otsdaq_components  v2_02_00
PurdueFirmwareCore.cc
1 #include "otsdaq-components/DAQHardware/PurdueFirmwareCore.h"
2 #include "otsdaq-core/BitManipulator/BitManipulator.h"
3 #include "otsdaq-components/DAQHardware/FirmwareBaseDefinitions.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 #include "otsdaq-core/Macros/CoutMacros.h"
6 #include <sys/socket.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <iostream>
10 #include <cstdlib>
11 
12 using namespace ots;
13 
14 //========================================================================================================================
15 PurdueFirmwareCore::PurdueFirmwareCore(unsigned int version):
16  FrontEndFirmwareBase(version)
17 {
18 }
19 
20 //========================================================================================================================
21 PurdueFirmwareCore::~PurdueFirmwareCore(void)
22 {}
23 
24 //========================================================================================================================
25 void PurdueFirmwareCore::init(void)
26 {}
27 
28 //========================================================================================================================
29 void PurdueFirmwareCore::setDataDestination(std::string& buffer,
30  const std::string& ipAddress, const uint16_t port,bool clearBuffer)
31 {
32  //do nothing
33 
34  if(clearBuffer)
35  buffer.resize(0);
36 }
37 
38 //========================================================================================================================
39 std::string PurdueFirmwareCore::read(char* address)
40 {
41  std::string buffer;
42  read(buffer, *(uint32_t*)address);
43  return buffer;
44 }
45 
46 //========================================================================================================================
47 std::string PurdueFirmwareCore::write(char* address, char* data)
48 {
49  std::string buffer;
50  write(buffer, *(uint32_t*)address, *(uint32_t*)data);
51  return buffer;
52 }
53 
54 //========================================================================================================================
55 void PurdueFirmwareCore::write(std::string& buffer, uint32_t address, uint32_t data,bool clearBuffer)
56 {
57  if(clearBuffer)
58  buffer.resize(0);
59 
60  //std::cout << __COUT_HDR_FL__ << "Making buffer" << std::endl;
61  unsigned int begin = buffer.length();
62  unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
63  buffer.resize(buffer.length() + 12, '\0');
64  if (begin != 0)
65  begin -= 1;
66  buffer[begin + 0] = numberOfBufferedCommands + 1;
67  buffer[begin + 1] = WRITE;
68  buffer[begin + 2] = 0;
69  buffer[begin + 3] = 8;
70  buffer[begin + 4] = (address >> 24) & 0xff;
71  buffer[begin + 5] = (address >> 16) & 0xff;
72  buffer[begin + 6] = (address >> 8) & 0xff;
73  buffer[begin + 7] = address & 0xff;
74  buffer[begin + 8] = (data >> 24) & 0xff;
75  buffer[begin + 9] = (data >> 16) & 0xff;
76  buffer[begin + 10] = (data >> 8) & 0xff;
77  buffer[begin + 11] = data & 0xff;
78  if (begin == 0)
79  buffer += '\0';
80  //return (unsigned int) buffer[begin] + 1;
81 }
82 
83 //========================================================================================================================
84 void PurdueFirmwareCore::waitSet(std::string& buffer, uint32_t address, uint32_t data, uint32_t timeout,bool clearBuffer)
85 {
86  if(clearBuffer)
87  buffer.resize(0);
88 
89  unsigned int begin = buffer.length();
90  unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
91  buffer.resize(buffer.length() + 16, '\0');
92  if (begin != 0)
93  begin -= 1;
94  buffer[begin + 0] = numberOfBufferedCommands + 1;
95  buffer[begin + 1] = WAITSET;
96  buffer[begin + 2] = 0;
97  buffer[begin + 3] = 12;
98  buffer[begin + 4] = (address >> 24) & 0xff;
99  buffer[begin + 5] = (address >> 16) & 0xff;
100  buffer[begin + 6] = (address >> 8) & 0xff;
101  buffer[begin + 7] = address & 0xff;
102  buffer[begin + 8] = (data >> 24) & 0xff;
103  buffer[begin + 9] = (data >> 16) & 0xff;
104  buffer[begin + 10] = (data >> 8) & 0xff;
105  buffer[begin + 11] = data & 0xff;
106  buffer[begin + 12] = (timeout >> 24) & 0xff;
107  buffer[begin + 13] = (timeout >> 16) & 0xff;
108  buffer[begin + 14] = (timeout >> 8) & 0xff;
109  buffer[begin + 15] = timeout & 0xff;
110  if (begin == 0)
111  buffer += '\0';
112  //return (unsigned int) buffer[begin] + 1;
113 }
114 
115 //========================================================================================================================
116 void PurdueFirmwareCore::waitClear(std::string& buffer, uint32_t address, uint32_t data, uint32_t timeout,bool clearBuffer)
117 {
118  if(clearBuffer)
119  buffer.resize(0);
120 
121  unsigned int begin = buffer.length();
122  unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
123  buffer.resize(buffer.length() + 16, '\0');
124  if (begin != 0)
125  begin -= 1;
126  buffer[begin + 0] = numberOfBufferedCommands + 1;
127  buffer[begin + 1] = WAITCLR;
128  buffer[begin + 2] = 0;
129  buffer[begin + 3] = 12;
130  buffer[begin + 4] = (address >> 24) & 0xff;
131  buffer[begin + 5] = (address >> 16) & 0xff;
132  buffer[begin + 6] = (address >> 8) & 0xff;
133  buffer[begin + 7] = address & 0xff;
134  buffer[begin + 8] = (data >> 24) & 0xff;
135  buffer[begin + 9] = (data >> 16) & 0xff;
136  buffer[begin + 10] = (data >> 8) & 0xff;
137  buffer[begin + 11] = data & 0xff;
138  buffer[begin + 12] = (timeout >> 24) & 0xff;
139  buffer[begin + 13] = (timeout >> 16) & 0xff;
140  buffer[begin + 14] = (timeout >> 8) & 0xff;
141  buffer[begin + 15] = timeout & 0xff;
142  if (begin == 0)
143  buffer += '\0';
144  //return (unsigned int) buffer[begin] + 1;
145 }
146 
147 //========================================================================================================================
148 void PurdueFirmwareCore::read(std::string& buffer, uint32_t address,bool clearBuffer)
149 {
150  if(clearBuffer)
151  buffer.resize(0);
152 
153  unsigned int begin = buffer.length();
154  unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
155  buffer.resize(buffer.length() + 8, '\0');
156  if (begin != 0)
157  begin -= 1;
158  buffer[begin + 0] = numberOfBufferedCommands + 1;
159  buffer[begin + 1] = READ;
160  buffer[begin + 2] = 0;
161  buffer[begin + 3] = 4;
162  buffer[begin + 4] = (address >> 24) & 0xff;
163  buffer[begin + 5] = (address >> 16) & 0xff;
164  buffer[begin + 6] = (address >> 8) & 0xff;
165  buffer[begin + 7] = address & 0xff;
166  if (begin == 0)
167  buffer += '\0';
168  //return (unsigned int) buffer[begin] + 1;
169 }
170 
171 //========================================================================================================================
172 unsigned int PurdueFirmwareCore::getNumberOfBufferedCommands(std::string& buffer)
173 {
174  if (buffer.length() == 0)
175  return 0;
176  unsigned int bufferPosition = 0;
177  unsigned int commandNumber = 0;
178  while (bufferPosition < buffer.length() - 1)
179  {
180  bufferPosition += (unsigned int) buffer[bufferPosition + 3] + 4;
181  ++commandNumber;
182  }
183  return commandNumber;
184 }
185 
186 //========================================================================================================================
187 std::string PurdueFirmwareCore::compareSendAndReceive(const std::string& sentBuffer, std::string& acknowledgment)
188 {
189  std::string reSendBuffer;
190  unsigned int skipBuffer = 0;
191  unsigned int skipAcknow = 0;
192  unsigned int remainBufferCommands;
193  unsigned int remainAcknowCommands;
194 
195  std::cout << __COUT_HDR_FL__ << "Comparing sent buffer and received acknowledgment!!!" << std::endl;
196 
197  std::cout << __COUT_HDR_FL__ << "Buffer size (send): " << sentBuffer.size() << std::endl;
198  std::cout << __COUT_HDR_FL__ << "Acknowledgment size (receive): " << acknowledgment.size() << std::endl;
199 
200  while(skipBuffer < sentBuffer.size())
201  {
202 
203  for (int position = 0; position < 4; position++)
204  {
205  if (position + skipBuffer >= sentBuffer.size()) //make sure the number NEVER goes above the limit
206  {
207  reSendBuffer.clear();
208  std::cout << __COUT_HDR_FL__ << "Done... Works!!!" << std::endl;
209  return reSendBuffer;
210  }
211 
212  if (position == 0)
213  {
214  if (sentBuffer[position + skipBuffer] != acknowledgment[position + skipAcknow])
215  {
216  std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
217  << " different from Received " << position + skipAcknow << "th:"
218  << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec;
219  std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
220  reSendBuffer.clear();
221  for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
222  {
223  reSendBuffer+= sentBuffer[i];
224  }
225  return reSendBuffer;
226  }
227  }
228 
229  if (position == 1)
230  {
231  if ( (sentBuffer[position + skipBuffer]) != (acknowledgment[position + skipAcknow] & 0xf) )
232  {
233  std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
234  << " different from Received " << position + skipAcknow << "th:"
235  << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec;
236  std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
237  reSendBuffer.clear();
238  for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
239  {
240  reSendBuffer+= sentBuffer[i];
241  }
242  return reSendBuffer;
243  }
244  }
245 
246  if (position == 2)
247  {
248  if ( (sentBuffer[position + skipBuffer] != 0) || (acknowledgment[position + skipAcknow] != 0) )
249  {
250  std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
251  << " different from Received " << position + skipAcknow << "th:"
252  << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec << std::endl;
253  std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
254  reSendBuffer.clear();
255  for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
256  {
257  reSendBuffer+= sentBuffer[i];
258  }
259  return reSendBuffer;
260  }
261  }
262 
263  if ( position == 3)
264  {
265  remainBufferCommands = sentBuffer[position + skipBuffer]; //4th bit tells us how many bits are left
266  remainAcknowCommands = acknowledgment[position + skipAcknow];
267 
268  if ( ((remainBufferCommands == 12) && (remainAcknowCommands == 4)) || ((remainBufferCommands == 8) && (remainAcknowCommands == 0)) )
269  {
270  skipBuffer += (4 + remainBufferCommands); //go to the beginning of next buffer
271  skipAcknow += (4 + remainAcknowCommands);
272  }
273  else
274  {
275  std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
276  << " not compatible with Received " << position + skipAcknow << "th:"
277  << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec << std::endl;
278  std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
279  reSendBuffer.clear();
280  for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
281  {
282  reSendBuffer+= sentBuffer[i];
283  }
284  return reSendBuffer;
285  }
286  }
287  }
288  }
289 
290  reSendBuffer.clear();
291  std::cout << __COUT_HDR_FL__ << "Done... Works!!!" << std::endl;
292  return reSendBuffer;
293 }
294 
295 //========================================================================================================================
296 uint32_t PurdueFirmwareCore::createRegisterFromValue(std::string& readBuffer, std::string& receivedValue)
297 {
298  for (int position = 0; position < 8; position++)
299  {
300  if (position == 0 || position == 4 || position == 5 || position == 6 || position == 7)
301  {
302  if (readBuffer[position] != receivedValue[position])
303  {
304  std::cout << __COUT_HDR_FL__
305  << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
306  << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
307  << std::endl;
308  return 0;
309  }
310  }
311 
312  if (position == 1)
313  {
314  if ( (readBuffer[position] != (receivedValue[position] & 0xf)) )
315  {
316  std::cout << __COUT_HDR_FL__
317  << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
318  << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
319  << std::endl;
320  return 0;
321  }
322  }
323 
324  if (position == 2)
325  {
326  if ( (readBuffer[position] != 0) || (receivedValue[position] != 0) )
327  {
328  std::cout << __COUT_HDR_FL__
329  << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
330  << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
331  << std::endl;
332  return 0;
333  }
334  }
335 
336  if ( position == 3)
337  {
338  if ( (readBuffer[position] != 4) || (receivedValue[position] != 8) )
339  {
340  std::cout << __COUT_HDR_FL__
341  << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
342  << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
343  << std::endl;
344  return 0;
345  }
346  }
347  }
348 
349  uint32_t registerValue;
350 
351  registerValue = ((unsigned int)receivedValue[8] << 24)
352  + ((unsigned int)receivedValue[9] << 16)
353  + ((unsigned int)receivedValue[10] << 8)
354  + (unsigned int)receivedValue[11];
355 
356  std::cout << __COUT_HDR_FL__ << "No problem encountered! Register value created!!! " << std::endl;
357 
358  return registerValue;
359 }
360