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