otsdaq_components  v2_02_00
FEOtsUDPTemplateInterface_interface.cc
1 #include "otsdaq-components/FEInterfaces/FEOtsUDPTemplateInterface.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/Macros/InterfacePluginMacros.h"
5 #include <iostream>
6 #include <set>
7 
8 using namespace ots;
9 
10 //========================================================================================================================
11 FEOtsUDPTemplateInterface::FEOtsUDPTemplateInterface(const std::string& interfaceUID, const ConfigurationTree& theXDAQContextConfigTree, const std::string& interfaceConfigurationPath)
12 : Socket (
13  theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("HostIPAddress").getValue<std::string>()
14  , theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("HostPort").getValue<unsigned int>())
15 , FEVInterface (interfaceUID, theXDAQContextConfigTree, interfaceConfigurationPath)
16 , OtsUDPHardware (theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("InterfaceIPAddress").getValue<std::string>()
17  , theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("InterfacePort").getValue<unsigned int>())
18 , OtsUDPFirmwareDataGen(theXDAQContextConfigTree.getNode(interfaceConfigurationPath).getNode("FirmwareVersion").getValue<unsigned int>())
19 {
20 
21 
22  universalAddressSize_ = 8;
23  universalDataSize_ = 8;
24 
25  //example self-call of feMacro
26  if(1)
27  {
28  //registration of FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' using MacroMaker.
29  FEVInterface::registerFEMacroFunction("varTest2",//feMacroName
30  static_cast<FEVInterface::frontEndMacroFunction_t>(&FEOtsUDPTemplateInterface::varTest2), //feMacroFunction
31  std::vector<std::string>{"myOtherArg"}, //namesOfInputArgs
32  std::vector<std::string>{"myArg","outArg1"}, //namesOfOutputArgs
33  1); //requiredUserPermissions
34 
35 
36  //registration of FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' using MacroMaker.
37  FEVInterface::registerFEMacroFunction("varTest",//feMacroName
38  static_cast<FEVInterface::frontEndMacroFunction_t>(&FEOtsUDPTemplateInterface::varTest), //feMacroFunction
39  std::vector<std::string>{"myOtherArg"}, //namesOfInputArgs
40  std::vector<std::string>{"myArg","outArg1"}, //namesOfOutputArgs
41  1); //requiredUserPermissions
42 
43  std::vector<frontEndMacroArg_t> argsIn;
44  __SET_ARG_IN__("myOtherArg",(unsigned int)5);
45 
46  std::vector<frontEndMacroArg_t> argsOut;
47 
48  __FE_COUTV__(StringMacros::vectorToString(argsIn));
49 
50  runSelfFrontEndMacro("varTest2",
51  argsIn,argsOut);
52 
53  __FE_COUTV__(StringMacros::vectorToString(argsOut));
54  __FE_COUTV__(FEVInterface::getFEMacroArgument(
55  argsOut,"outArg1"));
56 
57  {
58  std::string a = FEVInterface::getFEMacroArgument(
59  argsOut,"myArg");
60  double b = getFEMacroArgumentValue<double>(
61  argsOut,"outArg1");
62  unsigned short c = getFEMacroArgumentValue<unsigned short>(
63  argsOut,"outArg1");
64  __FE_COUTV__(a);
65  __FE_COUTV__(b);
66  __FE_COUTV__(c);
67  }
68  }
69 
70 } //end constructor
71 
72 //========================================================================================================================
73 FEOtsUDPTemplateInterface::~FEOtsUDPTemplateInterface(void)
74 {}
75 
76 //========================================================================================================================
77 void FEOtsUDPTemplateInterface::configure(void)
78 {
79 // unsigned int i = VStateMachine::getIterationIndex();
80 // unsigned int j = VStateMachine::getSubIterationIndex();
81 // if(i == 0 && j < 5)
82 // VStateMachine::indicateSubIterationWork();
83 // else if(i < 10)
84 // VStateMachine::indicateIterationWork();
85 //
86 // __FE_COUTV__(VStateMachine::getSubIterationIndex());
87 // __FE_COUTV__(VStateMachine::getSubIterationWork());
88 // __FE_COUTV__(VStateMachine::getIterationIndex());
89 // __FE_COUTV__(VStateMachine::getIterationWork());
90 //
91 // __FE_COUTV__(i);
92 // __FE_COUTV__(getInterfaceUID());
93 // switch(i)
94 // {
95 // case 1:
96 // if(getInterfaceUID() == "ExampleInterface0")
97 // {
98 // FEVInterface::sendToFrontEnd("ExampleInterface1","Hello1");
99 // FEVInterface::sendToFrontEnd("ExampleInterface1",4.3f);
100 // FEVInterface::sendToFrontEnd("ExampleInterface1",4);
101 // FEVInterface::sendToFrontEnd("ExampleInterface2","Hello2");
102 // FEVInterface::sendToFrontEnd("ExampleInterface2",4.6f);
103 // FEVInterface::sendToFrontEnd("ExampleInterface2",6);
104 // }
105 // break;
106 // case 2:
107 // if(getInterfaceUID() != "ExampleInterface0")
108 // {
109 // std::string a = FEVInterface::receiveFromFrontEnd("ExampleInterface0");
110 // double b = FEVInterface::receiveFromFrontEnd<double>("ExampleInterface0");
111 // unsigned short c =
112 // FEVInterface::receiveFromFrontEnd<unsigned short>("ExampleInterface0");
113 // __FE_COUTV__(a);
114 // __FE_COUTV__(b);
115 // __FE_COUTV__(c);
116 // }
117 // break;
118 // case 3:
119 // if(getInterfaceUID() == "ExampleInterface0")
120 // {
121 // std::vector<frontEndMacroArg_t> argsIn;
122 // __SET_ARG_IN__("myOtherArg",(unsigned int)5);
123 //
124 // std::vector<frontEndMacroArg_t> argsOut;
125 //
126 // __FE_COUTV__(StringMacros::vectorToString(argsIn));
127 //
128 // FEVInterface::runFrontEndMacro("ExampleInterface2","varTest2",
129 // argsIn,argsOut);
130 //
131 // __FE_COUTV__(StringMacros::vectorToString(argsOut));
132 // __FE_COUTV__(FEVInterface::getFEMacroArgument(
133 // argsOut,"outArg1"));
134 //
135 // {
136 // std::string a = FEVInterface::getFEMacroArgument(
137 // argsOut,"myArg");
138 // double b = getFEMacroArgumentValue<double>(
139 // argsOut,"outArg1");
140 // unsigned short c = getFEMacroArgumentValue<unsigned short>(
141 // argsOut,"outArg1");
142 // __FE_COUTV__(a);
143 // __FE_COUTV__(b);
144 // __FE_COUTV__(c);
145 // }
146 //
147 //
148 //
149 // FEVInterface::runFrontEndMacro("ExampleInterface1","varTest",
150 // argsIn,argsOut);
151 // __FE_COUTV__(StringMacros::vectorToString(argsOut));
152 //
153 // {
154 // std::string a = __GET_ARG_OUT__("myArg",std::string);
155 // double b = __GET_ARG_OUT__("outArg1",double);
156 // unsigned short c = __GET_ARG_OUT__("outArg1",unsigned short);
157 // __FE_COUTV__(a);
158 // __FE_COUTV__(b);
159 // __FE_COUTV__(c);
160 // }
161 // }
162 //
163 // break;
164 // default:;
165 // }
166 //
167 //
168 // return;
169 
170  __FE_COUT__ << "configure" << __E__;
171  __FE_COUT__ << "Clearing receive socket buffer: " << OtsUDPHardware::clearReadSocket() << " packets cleared." << __E__;
172 
173  std::string sendBuffer;
174  std::string recvBuffer;
175  uint64_t readQuadWord;
176 
177  __FE_COUT__ << "Configuration Path Table: " <<
178  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getConfigurationName() <<
179  "-v" <<
180  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getConfigurationVersion() <<
181  __E__;
182 
183  __FE_COUT__ << "Interface name: " <<
184  theXDAQContextConfigTree_.getNode(theConfigurationPath_) << __E__;
185 
186  __FE_COUT__ << "Configured Firmware Version: " <<
187  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("FirmwareVersion").getValue<unsigned int>()
188  << __E__;
189 
190  __FE_COUT__ << "Setting Destination IP: " <<
191  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToIPAddress").getValue<std::string>()
192  << __E__;
193  __FE_COUT__ << "And Destination Port: " <<
194  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToPort").getValue<unsigned int>()
195  << __E__;
196 
197  OtsUDPFirmwareCore::setDataDestination(sendBuffer,
198  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToIPAddress").getValue<std::string>(),
199  theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode("StreamToPort").getValue<uint64_t>()
200  );
201  OtsUDPHardware::write(sendBuffer);
202 
203  __FE_COUT__ << "Reading back burst dest MAC/IP/Port: " << __E__;
204 
205  OtsUDPFirmwareCore::readDataDestinationMAC(sendBuffer);
206  OtsUDPHardware::read(sendBuffer,readQuadWord);
207 
208  OtsUDPFirmwareCore::readDataDestinationIP(sendBuffer);
209  OtsUDPHardware::read(sendBuffer,readQuadWord);
210 
211  OtsUDPFirmwareCore::readDataDestinationPort(sendBuffer);
212  OtsUDPHardware::read(sendBuffer,readQuadWord);
213 
214 
215 
216  OtsUDPFirmwareCore::readControlDestinationPort(sendBuffer);
217  OtsUDPHardware::read(sendBuffer,readQuadWord);
218 
219  //Run Configure Sequence Commands
220  FEVInterface::runSequenceOfCommands("LinkToConfigureSequence");
221 
222  __FE_COUT__ << "Done with ots Template configuring." << __E__;
223 }
224 
225 //========================================================================================================================
226 //void FEOtsUDPTemplateInterface::configureDetector(const DACStream& theDACStream)
227 //{
228 // __FE_COUT__ << "\tconfigureDetector" << __E__;
229 //}
230 
231 //========================================================================================================================
232 void FEOtsUDPTemplateInterface::halt(void)
233 {
234  __FE_COUT__ << "\tHalt" << __E__;
235  stop();
236 }
237 
238 //========================================================================================================================
239 void FEOtsUDPTemplateInterface::pause(void)
240 {
241  __FE_COUT__ << "\tPause" << __E__;
242  stop();
243 }
244 
245 //========================================================================================================================
246 void FEOtsUDPTemplateInterface::resume(void)
247 {
248  __FE_COUT__ << "\tResume" << __E__;
249  start("");
250 }
251 
252 //========================================================================================================================
253 void FEOtsUDPTemplateInterface::start(std::string )//runNumber)
254 {
255  __FE_COUT__ << "\tStart" << __E__;
256 
257 
258 // unsigned int i = VStateMachine::getIterationIndex();
259 // unsigned int j = VStateMachine::getSubIterationIndex();
260 // if(i == 0 && j < 5)
261 // VStateMachine::indicateSubIterationWork();
262 // else if(i < 10)
263 // VStateMachine::indicateIterationWork();
264 //
265 //
266 // __FE_COUTV__(VStateMachine::getSubIterationIndex());
267 // __FE_COUTV__(VStateMachine::getSubIterationWork());
268 // __FE_COUTV__(VStateMachine::getIterationIndex());
269 // __FE_COUTV__(VStateMachine::getIterationWork());
270 //
271 //
272 // return;
273 
274 
275 
276  //Run Start Sequence Commands
277  FEVInterface::runSequenceOfCommands("LinkToStartSequence");
278 
279  std::string sendBuffer;
280  OtsUDPFirmwareCore::startBurst(sendBuffer);
281  OtsUDPHardware::write(sendBuffer);
282 }
283 
284 //========================================================================================================================
285 void FEOtsUDPTemplateInterface::stop(void)
286 {
287  __FE_COUT__ << "\tStop" << __E__;
288 
289  //Run Stop Sequence Commands
290 
291  FEVInterface::runSequenceOfCommands("LinkToStopSequence");
292 
293  std::string sendBuffer;
294  OtsUDPFirmwareCore::stopBurst(sendBuffer);
295  OtsUDPHardware::write(sendBuffer);
296 }
297 
298 //========================================================================================================================
299 bool FEOtsUDPTemplateInterface::running(void)
300 {
301  __FE_COUT__ << "\tRunning" << __E__;
302 
303  //__SS__ << "?" << __E__; //test exceptions during running
304  //__SS_THROW__;
305 
306 
307  int state = -1;
308  while(WorkLoop::continueWorkLoop_)
309  {
310  //while running
311  //play with the LEDs at address 0x1003
312 
313  ++state;
314  if(state < 8)
315  sleep(1);
316  else
317  {
318  // if(1 || getInterfaceUID() == "ExampleInterface1")
319  // {
320  // throw __OTS_SOFT_EXCEPTION__("Soft error here");
321  // }
322  // else
323  break;
324  }
325  }
326 
327  // //example!
328  // //play with array of 8 LEDs at address 0x1003
329 
330  //
331  // bool flashLEDsWhileRunning = false;
332  // if(flashLEDsWhileRunning)
333  // {
334  // std::string writeBuffer;
335  // int state = -1;
336  // while(WorkLoop::continueWorkLoop_)
337  // {
338  // //while running
339  // //play with the LEDs at address 0x1003
340  //
341  // ++state;
342  // if(state < 8)
343  // {
344  // writeBuffer.resize(0);
345  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,1<<state);
346  // OtsUDPHardware::write(writeBuffer);
347  // }
348  // else if(state%2 == 1 && state < 11)
349  // {
350  // writeBuffer.resize(0);
351  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003, 0xFF);
352  // OtsUDPHardware::write(writeBuffer);
353  // }
354  // else if(state%2 == 0 && state < 11)
355  // {
356  // writeBuffer.resize(0);
357  // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,0);
358  // OtsUDPHardware::write(writeBuffer);
359  // }
360  // else
361  // state = -1;
362  //
363  // sleep(1);
364  // }
365  // }
366 
367  return false;
368 }
369 
370 //========================================================================================================================
371 //NOTE: buffer for address must be at least size universalAddressSize_
372 //NOTE: buffer for returnValue must be max UDP size to handle return possibility
373 void ots::FEOtsUDPTemplateInterface::universalRead(char *address, char *returnValue)
374 {
375  __FE_COUT__ << "address size " << universalAddressSize_ << __E__;
376 
377  __FE_COUT__ << "Universal Read Address: ";
378  for(unsigned int i=0;i<universalAddressSize_;++i)
379  printf("%2.2X",(unsigned char)address[i]);
380  std::cout << __E__;
381 
382  std::string readBuffer, sendBuffer;
383  OtsUDPFirmwareCore::readAdvanced(sendBuffer,address,1 /*size*/);
384 
385  OtsUDPHardware::read(sendBuffer, readBuffer); // data reply
386 
387  __FE_COUT__ << "Result SIZE: " << readBuffer.size() << __E__;
388  std::memcpy(returnValue,readBuffer.substr(2).c_str(),universalDataSize_);
389 
390  __FE_COUT__ << "Universal Read Data: ";
391  for(unsigned int i=0;i<universalDataSize_;++i)
392  printf("%2.2X",(unsigned char)returnValue[i]);
393  std::cout << __E__;
394 
395 } //end universalRead()
396 
397 //========================================================================================================================
398 //NOTE: buffer for address must be at least size universalAddressSize_
399 //NOTE: buffer for writeValue must be at least size universalDataSize_
400 void ots::FEOtsUDPTemplateInterface::universalWrite(char* address, char* writeValue)
401 {
402  __FE_COUT__ << "address size " << universalAddressSize_ << __E__;
403  __FE_COUT__ << "data size " << universalDataSize_ << __E__;
404  __FE_COUT__ << "Universal Write Address: ";
405  for(unsigned int i=0;i<universalAddressSize_;++i)
406  printf("%2.2X",(unsigned char)address[i]);
407  std::cout << __E__;
408  __FE_COUT__ << "Universal Write Data: ";
409  for(unsigned int i=0;i<universalDataSize_;++i)
410  printf("%2.2X",(unsigned char)writeValue[i]);
411  std::cout << __E__;
412 
413  std::string sendBuffer;
414  OtsUDPFirmwareCore::writeAdvanced(sendBuffer,address,writeValue,1 /*size*/);
415  OtsUDPHardware::write(sendBuffer); // data request
416 } //end universalWrite()
417 
418 
419 
420 
421 //========================================================================================================================
422 //varTest
423 // FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' using MacroMaker.
424 // Macro Notes: This is a great test!
425 void FEOtsUDPTemplateInterface::varTest(__ARGS__)
426 {
427  __FE_COUT__ << "# of input args = " << argsIn.size() << __E__;
428  __FE_COUT__ << "# of output args = " << argsOut.size() << __E__;
429  for(auto &argIn:argsIn)
430  __FE_COUT__ << argIn.first << ": " << argIn.second << __E__;
431 
432  //macro commands section
433  {
434  char *address = new char[universalAddressSize_]{0}; //create address buffer of interface size and init to all 0
435  char *data = new char[universalDataSize_]{0}; //create data buffer of interface size and init to all 0
436  uint64_t macroAddress; //create macro address buffer (size 8 bytes)
437  uint64_t macroData; //create macro address buffer (size 8 bytes)
438  std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create map from arg name to 64-bit number
439 
440  // command-#0: Read(0x1002 /*address*/,myArg /*data*/);
441  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
442  universalRead(address,data); memcpy(&macroArgs["myArg"],data,8); //copy buffer to argument map
443  __SET_ARG_OUT__("myArg",macroArgs["myArg"]); //update output argument result
444 
445  // command-#1: Read(0x1001 /*address*/,data);
446  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer
447  universalRead(address,data); memcpy(&macroArgs["outArg1"],data,8); //copy buffer to argument map
448  __SET_ARG_OUT__("outArg1",macroArgs["outArg1"]); //update output argument result
449 
450  // command-#2: Write(0x1002 /*address*/,myOtherArg /*data*/);
451  macroAddress = 0x1002; memcpy(address,&macroAddress,8); //copy macro address to buffer
452  macroArgs["myOtherArg"] = __GET_ARG_IN__("myOtherArg", uint64_t); //initialize from input arguments //get macro data argument
453  memcpy(data,&macroArgs["myOtherArg"],8); //copy macro data argument to buffer
454  universalWrite(address,data);
455 
456  // command-#3: Write(0x1001 /*address*/,myArg /*data*/);
457  macroAddress = 0x1001; memcpy(address,&macroAddress,8); //copy macro address to buffer //get macro data argument
458  memcpy(data,&macroArgs["myArg"],8); //copy macro data argument to buffer
459  universalWrite(address,data);
460 
461  // command-#4: delay(4);
462  __FE_COUT__ << "Sleeping for... " << 4 << " milliseconds " << __E__;
463  usleep(4*1000 /* microseconds */);
464 
465 
466  delete[] address; //free the memory
467  delete[] data; //free the memory
468  }
469 
470  for(auto &argOut:argsOut)
471  __FE_COUT__ << argOut.first << ": " << argOut.second << __E__;
472 
473 } //end varTest()
474 
475 
476 //========================================================================================================================
477 //varTest2
478 // FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' using MacroMaker.
479 // Macro Notes: [Modified 14:28 10/11/2018] This is a great test!
480 void FEOtsUDPTemplateInterface::varTest2(__ARGS__)
481 {
482  __FE_COUT__ << "# of input args = " << argsIn.size() << __E__;
483  __FE_COUT__ << "# of output args = " << argsOut.size() << __E__;
484  for(auto &argIn:argsIn)
485  __FE_COUT__ << argIn.first << ": " << argIn.second << __E__;
486 
487  __SET_ARG_OUT__("myArg","hello2"); //update output argument result
488  uint64_t macroData = __GET_ARG_IN__("myOtherArg", uint64_t);
489  macroData *= 3;
490  __SET_ARG_OUT__("outArg1",macroData); //update output argument result
491 
492  for(auto &argOut:argsOut)
493  __FE_COUT__ << argOut.first << ": " << argOut.second << __E__;
494 
495 } //end varTest2()
496 
497 DEFINE_OTS_INTERFACE(FEOtsUDPTemplateInterface)