$treeview $search $mathjax $extrastylesheet
otsdaq_components
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include <iostream> 00002 #include <set> 00003 #include "otsdaq-components/FEInterfaces/FEOtsUDPTemplateInterface.h" 00004 #include "otsdaq-core/Macros/CoutMacros.h" 00005 #include "otsdaq-core/Macros/InterfacePluginMacros.h" 00006 #include "otsdaq-core/MessageFacility/MessageFacility.h" 00007 00008 using namespace ots; 00009 00010 //======================================================================================================================== 00011 FEOtsUDPTemplateInterface::FEOtsUDPTemplateInterface( 00012 const std::string& interfaceUID, 00013 const ConfigurationTree& theXDAQContextConfigTree, 00014 const std::string& interfaceConfigurationPath) 00015 : Socket(theXDAQContextConfigTree.getNode(interfaceConfigurationPath) 00016 .getNode("HostIPAddress") 00017 .getValue<std::string>(), 00018 theXDAQContextConfigTree.getNode(interfaceConfigurationPath) 00019 .getNode("HostPort") 00020 .getValue<unsigned int>()) 00021 , FEVInterface(interfaceUID, theXDAQContextConfigTree, interfaceConfigurationPath) 00022 , OtsUDPHardware(theXDAQContextConfigTree.getNode(interfaceConfigurationPath) 00023 .getNode("InterfaceIPAddress") 00024 .getValue<std::string>(), 00025 theXDAQContextConfigTree.getNode(interfaceConfigurationPath) 00026 .getNode("InterfacePort") 00027 .getValue<unsigned int>()) 00028 , OtsUDPFirmwareDataGen(theXDAQContextConfigTree.getNode(interfaceConfigurationPath) 00029 .getNode("FirmwareVersion") 00030 .getValue<unsigned int>()) 00031 { 00032 universalAddressSize_ = 8; 00033 universalDataSize_ = 8; 00034 00035 // example self-call of feMacro 00036 if(1) 00037 { 00038 // registration of FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' 00039 // using MacroMaker. 00040 FEVInterface::registerFEMacroFunction( 00041 "varTest2", // feMacroName 00042 static_cast<FEVInterface::frontEndMacroFunction_t>( 00043 &FEOtsUDPTemplateInterface::varTest2), // feMacroFunction 00044 std::vector<std::string>{"myOtherArg"}, // namesOfInputArgs 00045 std::vector<std::string>{"myArg", "outArg1"}, // namesOfOutputArgs 00046 1); // requiredUserPermissions 00047 00048 // registration of FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' 00049 // using MacroMaker. 00050 FEVInterface::registerFEMacroFunction( 00051 "varTest", // feMacroName 00052 static_cast<FEVInterface::frontEndMacroFunction_t>( 00053 &FEOtsUDPTemplateInterface::varTest), // feMacroFunction 00054 std::vector<std::string>{"myOtherArg"}, // namesOfInputArgs 00055 std::vector<std::string>{"myArg", "outArg1"}, // namesOfOutputArgs 00056 1); // requiredUserPermissions 00057 00058 std::vector<frontEndMacroArg_t> argsIn; 00059 __SET_ARG_IN__("myOtherArg", (unsigned int)5); 00060 00061 std::vector<frontEndMacroArg_t> argsOut; 00062 00063 __FE_COUTV__(StringMacros::vectorToString(argsIn)); 00064 00065 runSelfFrontEndMacro("varTest2", argsIn, argsOut); 00066 00067 __FE_COUTV__(StringMacros::vectorToString(argsOut)); 00068 __FE_COUTV__(FEVInterface::getFEMacroArgument(argsOut, "outArg1")); 00069 00070 { 00071 std::string a = FEVInterface::getFEMacroArgument(argsOut, "myArg"); 00072 double b = getFEMacroArgumentValue<double>(argsOut, "outArg1"); 00073 unsigned short c = 00074 getFEMacroArgumentValue<unsigned short>(argsOut, "outArg1"); 00075 __FE_COUTV__(a); 00076 __FE_COUTV__(b); 00077 __FE_COUTV__(c); 00078 } 00079 } 00080 00081 } // end constructor 00082 00083 //======================================================================================================================== 00084 FEOtsUDPTemplateInterface::~FEOtsUDPTemplateInterface(void) {} 00085 00086 //======================================================================================================================== 00087 void FEOtsUDPTemplateInterface::configure(void) 00088 { 00089 // unsigned int i = VStateMachine::getIterationIndex(); 00090 // unsigned int j = VStateMachine::getSubIterationIndex(); 00091 // if(i == 0 && j < 5) 00092 // VStateMachine::indicateSubIterationWork(); 00093 // else if(i < 10) 00094 // VStateMachine::indicateIterationWork(); 00095 // 00096 // __FE_COUTV__(VStateMachine::getSubIterationIndex()); 00097 // __FE_COUTV__(VStateMachine::getSubIterationWork()); 00098 // __FE_COUTV__(VStateMachine::getIterationIndex()); 00099 // __FE_COUTV__(VStateMachine::getIterationWork()); 00100 // 00101 // __FE_COUTV__(i); 00102 // __FE_COUTV__(getInterfaceUID()); 00103 // switch(i) 00104 // { 00105 // case 1: 00106 // if(getInterfaceUID() == "ExampleInterface0") 00107 // { 00108 // FEVInterface::sendToFrontEnd("ExampleInterface1","Hello1"); 00109 // FEVInterface::sendToFrontEnd("ExampleInterface1",4.3f); 00110 // FEVInterface::sendToFrontEnd("ExampleInterface1",4); 00111 // FEVInterface::sendToFrontEnd("ExampleInterface2","Hello2"); 00112 // FEVInterface::sendToFrontEnd("ExampleInterface2",4.6f); 00113 // FEVInterface::sendToFrontEnd("ExampleInterface2",6); 00114 // } 00115 // break; 00116 // case 2: 00117 // if(getInterfaceUID() != "ExampleInterface0") 00118 // { 00119 // std::string a = FEVInterface::receiveFromFrontEnd("ExampleInterface0"); 00120 // double b = FEVInterface::receiveFromFrontEnd<double>("ExampleInterface0"); 00121 // unsigned short c = 00122 // FEVInterface::receiveFromFrontEnd<unsigned 00123 // short>("ExampleInterface0"); 00124 // __FE_COUTV__(a); 00125 // __FE_COUTV__(b); 00126 // __FE_COUTV__(c); 00127 // } 00128 // break; 00129 // case 3: 00130 // if(getInterfaceUID() == "ExampleInterface0") 00131 // { 00132 // std::vector<frontEndMacroArg_t> argsIn; 00133 // __SET_ARG_IN__("myOtherArg",(unsigned int)5); 00134 // 00135 // std::vector<frontEndMacroArg_t> argsOut; 00136 // 00137 // __FE_COUTV__(StringMacros::vectorToString(argsIn)); 00138 // 00139 // FEVInterface::runFrontEndMacro("ExampleInterface2","varTest2", 00140 // argsIn,argsOut); 00141 // 00142 // __FE_COUTV__(StringMacros::vectorToString(argsOut)); 00143 // __FE_COUTV__(FEVInterface::getFEMacroArgument( 00144 // argsOut,"outArg1")); 00145 // 00146 // { 00147 // std::string a = FEVInterface::getFEMacroArgument( 00148 // argsOut,"myArg"); 00149 // double b = getFEMacroArgumentValue<double>( 00150 // argsOut,"outArg1"); 00151 // unsigned short c = getFEMacroArgumentValue<unsigned short>( 00152 // argsOut,"outArg1"); 00153 // __FE_COUTV__(a); 00154 // __FE_COUTV__(b); 00155 // __FE_COUTV__(c); 00156 // } 00157 // 00158 // 00159 // 00160 // FEVInterface::runFrontEndMacro("ExampleInterface1","varTest", 00161 // argsIn,argsOut); 00162 // __FE_COUTV__(StringMacros::vectorToString(argsOut)); 00163 // 00164 // { 00165 // std::string a = __GET_ARG_OUT__("myArg",std::string); 00166 // double b = __GET_ARG_OUT__("outArg1",double); 00167 // unsigned short c = __GET_ARG_OUT__("outArg1",unsigned short); 00168 // __FE_COUTV__(a); 00169 // __FE_COUTV__(b); 00170 // __FE_COUTV__(c); 00171 // } 00172 // } 00173 // 00174 // break; 00175 // default:; 00176 // } 00177 // 00178 // 00179 // return; 00180 00181 __FE_COUT__ << "configure" << __E__; 00182 __FE_COUT__ << "Clearing receive socket buffer: " << OtsUDPHardware::clearReadSocket() 00183 << " packets cleared." << __E__; 00184 00185 std::string sendBuffer; 00186 std::string recvBuffer; 00187 uint64_t readQuadWord; 00188 00189 __FE_COUT__ 00190 << "Configuration Path Table: " 00191 << theXDAQContextConfigTree_.getNode(theConfigurationPath_).getTableName() << "-v" 00192 << theXDAQContextConfigTree_.getNode(theConfigurationPath_).getTableVersion() 00193 << __E__; 00194 00195 __FE_COUT__ << "Interface name: " 00196 << theXDAQContextConfigTree_.getNode(theConfigurationPath_) << __E__; 00197 00198 __FE_COUT__ << "Configured Firmware Version: " 00199 << theXDAQContextConfigTree_.getNode(theConfigurationPath_) 00200 .getNode("FirmwareVersion") 00201 .getValue<unsigned int>() 00202 << __E__; 00203 00204 __FE_COUT__ << "Setting Destination IP: " 00205 << theXDAQContextConfigTree_.getNode(theConfigurationPath_) 00206 .getNode("StreamToIPAddress") 00207 .getValue<std::string>() 00208 << __E__; 00209 __FE_COUT__ << "And Destination Port: " 00210 << theXDAQContextConfigTree_.getNode(theConfigurationPath_) 00211 .getNode("StreamToPort") 00212 .getValue<unsigned int>() 00213 << __E__; 00214 00215 OtsUDPFirmwareCore::setDataDestination( 00216 sendBuffer, 00217 theXDAQContextConfigTree_.getNode(theConfigurationPath_) 00218 .getNode("StreamToIPAddress") 00219 .getValue<std::string>(), 00220 theXDAQContextConfigTree_.getNode(theConfigurationPath_) 00221 .getNode("StreamToPort") 00222 .getValue<uint64_t>()); 00223 OtsUDPHardware::write(sendBuffer); 00224 00225 __FE_COUT__ << "Reading back burst dest MAC/IP/Port: " << __E__; 00226 00227 OtsUDPFirmwareCore::readDataDestinationMAC(sendBuffer); 00228 OtsUDPHardware::read(sendBuffer, readQuadWord); 00229 00230 OtsUDPFirmwareCore::readDataDestinationIP(sendBuffer); 00231 OtsUDPHardware::read(sendBuffer, readQuadWord); 00232 00233 OtsUDPFirmwareCore::readDataDestinationPort(sendBuffer); 00234 OtsUDPHardware::read(sendBuffer, readQuadWord); 00235 00236 OtsUDPFirmwareCore::readControlDestinationPort(sendBuffer); 00237 OtsUDPHardware::read(sendBuffer, readQuadWord); 00238 00239 // Run Configure Sequence Commands 00240 FEVInterface::runSequenceOfCommands("LinkToConfigureSequence"); 00241 00242 __FE_COUT__ << "Done with ots Template configuring." << __E__; 00243 } 00244 00245 //======================================================================================================================== 00246 // void FEOtsUDPTemplateInterface::configureDetector(const DACStream& theDACStream) 00247 //{ 00248 // __FE_COUT__ << "\tconfigureDetector" << __E__; 00249 //} 00250 00251 //======================================================================================================================== 00252 void FEOtsUDPTemplateInterface::halt(void) 00253 { 00254 __FE_COUT__ << "\tHalt" << __E__; 00255 stop(); 00256 } 00257 00258 //======================================================================================================================== 00259 void FEOtsUDPTemplateInterface::pause(void) 00260 { 00261 __FE_COUT__ << "\tPause" << __E__; 00262 stop(); 00263 } 00264 00265 //======================================================================================================================== 00266 void FEOtsUDPTemplateInterface::resume(void) 00267 { 00268 __FE_COUT__ << "\tResume" << __E__; 00269 start(""); 00270 } 00271 00272 //======================================================================================================================== 00273 void FEOtsUDPTemplateInterface::start(std::string) // runNumber) 00274 { 00275 __FE_COUT__ << "\tStart" << __E__; 00276 00277 // unsigned int i = VStateMachine::getIterationIndex(); 00278 // unsigned int j = VStateMachine::getSubIterationIndex(); 00279 // if(i == 0 && j < 5) 00280 // VStateMachine::indicateSubIterationWork(); 00281 // else if(i < 10) 00282 // VStateMachine::indicateIterationWork(); 00283 // 00284 // 00285 // __FE_COUTV__(VStateMachine::getSubIterationIndex()); 00286 // __FE_COUTV__(VStateMachine::getSubIterationWork()); 00287 // __FE_COUTV__(VStateMachine::getIterationIndex()); 00288 // __FE_COUTV__(VStateMachine::getIterationWork()); 00289 // 00290 // 00291 // return; 00292 00293 // Run Start Sequence Commands 00294 FEVInterface::runSequenceOfCommands("LinkToStartSequence"); 00295 00296 std::string sendBuffer; 00297 OtsUDPFirmwareCore::startBurst(sendBuffer); 00298 OtsUDPHardware::write(sendBuffer); 00299 } 00300 00301 //======================================================================================================================== 00302 void FEOtsUDPTemplateInterface::stop(void) 00303 { 00304 __FE_COUT__ << "\tStop" << __E__; 00305 00306 // Run Stop Sequence Commands 00307 00308 FEVInterface::runSequenceOfCommands("LinkToStopSequence"); 00309 00310 std::string sendBuffer; 00311 OtsUDPFirmwareCore::stopBurst(sendBuffer); 00312 OtsUDPHardware::write(sendBuffer); 00313 } 00314 00315 //======================================================================================================================== 00316 bool FEOtsUDPTemplateInterface::running(void) 00317 { 00318 __FE_COUT__ << "\tRunning" << __E__; 00319 00320 //__SS__ << "?" << __E__; //test exceptions during running 00321 //__SS_THROW__; 00322 00323 int state = -1; 00324 while(WorkLoop::continueWorkLoop_) 00325 { 00326 // while running 00327 // play with the LEDs at address 0x1003 00328 00329 ++state; 00330 if(state < 8) 00331 sleep(1); 00332 else 00333 { 00334 // if(1 || getInterfaceUID() == "ExampleInterface1") 00335 // { 00336 // throw __OTS_SOFT_EXCEPTION__("Soft error here"); 00337 // } 00338 // else 00339 break; 00340 } 00341 } 00342 00343 // //example! 00344 // //play with array of 8 LEDs at address 0x1003 00345 00346 // 00347 // bool flashLEDsWhileRunning = false; 00348 // if(flashLEDsWhileRunning) 00349 // { 00350 // std::string writeBuffer; 00351 // int state = -1; 00352 // while(WorkLoop::continueWorkLoop_) 00353 // { 00354 // //while running 00355 // //play with the LEDs at address 0x1003 00356 // 00357 // ++state; 00358 // if(state < 8) 00359 // { 00360 // writeBuffer.resize(0); 00361 // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,1<<state); 00362 // OtsUDPHardware::write(writeBuffer); 00363 // } 00364 // else if(state%2 == 1 && state < 11) 00365 // { 00366 // writeBuffer.resize(0); 00367 // OtsUDPFirmwareCore::write(writeBuffer, 0x1003, 0xFF); 00368 // OtsUDPHardware::write(writeBuffer); 00369 // } 00370 // else if(state%2 == 0 && state < 11) 00371 // { 00372 // writeBuffer.resize(0); 00373 // OtsUDPFirmwareCore::write(writeBuffer, 0x1003,0); 00374 // OtsUDPHardware::write(writeBuffer); 00375 // } 00376 // else 00377 // state = -1; 00378 // 00379 // sleep(1); 00380 // } 00381 // } 00382 00383 return false; 00384 } 00385 00386 //======================================================================================================================== 00387 // NOTE: buffer for address must be at least size universalAddressSize_ 00388 // NOTE: buffer for returnValue must be max UDP size to handle return possibility 00389 void ots::FEOtsUDPTemplateInterface::universalRead(char* address, char* returnValue) 00390 { 00391 __FE_COUT__ << "address size " << universalAddressSize_ << __E__; 00392 00393 __FE_COUT__ << "Universal Read Address: 0x"; 00394 for(unsigned int i = 0; i < universalAddressSize_; ++i) 00395 printf("%2.2X", (unsigned char)address[universalAddressSize_-1-i]); 00396 std::cout << __E__; 00397 00398 std::string readBuffer, sendBuffer; 00399 OtsUDPFirmwareCore::readAdvanced(sendBuffer, address, 1 /*size*/); 00400 00401 OtsUDPHardware::read(sendBuffer, readBuffer); // data reply 00402 00403 __FE_COUT__ << "Result SIZE: " << readBuffer.size() << __E__; 00404 std::memcpy(returnValue, readBuffer.substr(2).c_str(), universalDataSize_); 00405 00406 __FE_COUT__ << "Universal Read Data: 0x"; 00407 for(unsigned int i = 0; i < universalDataSize_; ++i) 00408 printf("%2.2X", (unsigned char)returnValue[universalDataSize_-1-i]); 00409 std::cout << __E__; 00410 00411 } // end universalRead() 00412 00413 //======================================================================================================================== 00414 // NOTE: buffer for address must be at least size universalAddressSize_ 00415 // NOTE: buffer for writeValue must be at least size universalDataSize_ 00416 void ots::FEOtsUDPTemplateInterface::universalWrite(char* address, char* writeValue) 00417 { 00418 __FE_COUT__ << "address size " << universalAddressSize_ << __E__; 00419 __FE_COUT__ << "data size " << universalDataSize_ << __E__; 00420 __FE_COUT__ << "Universal Write Address: 0x"; 00421 for(unsigned int i = 0; i < universalAddressSize_; ++i) 00422 printf("%2.2X", (unsigned char)address[universalAddressSize_-1-i]); 00423 std::cout << __E__; 00424 __FE_COUT__ << "Universal Write Data: 0x"; 00425 for(unsigned int i = 0; i < universalDataSize_; ++i) 00426 printf("%2.2X", (unsigned char)writeValue[universalDataSize_-1-i]); 00427 std::cout << __E__; 00428 00429 std::string sendBuffer; 00430 OtsUDPFirmwareCore::writeAdvanced(sendBuffer, address, writeValue, 1 /*size*/); 00431 OtsUDPHardware::write(sendBuffer); // data request 00432 } // end universalWrite() 00433 00434 //======================================================================================================================== 00435 // varTest 00436 // FEMacro 'varTest' generated, Oct-11-2018 11:36:28, by 'admin' using MacroMaker. 00437 // Macro Notes: This is a great test! 00438 void FEOtsUDPTemplateInterface::varTest(__ARGS__) 00439 { 00440 __FE_COUT__ << "# of input args = " << argsIn.size() << __E__; 00441 __FE_COUT__ << "# of output args = " << argsOut.size() << __E__; 00442 for(auto& argIn : argsIn) 00443 __FE_COUT__ << argIn.first << ": " << argIn.second << __E__; 00444 00445 // macro commands section 00446 { 00447 char* address = new char[universalAddressSize_]{ 00448 0}; //create address buffer of interface size and init to all 0 00449 char* data = new char[universalDataSize_]{ 00450 0}; //create data buffer of interface size and init to all 0 00451 uint64_t macroAddress; // create macro address buffer (size 8 bytes) 00452 uint64_t macroData; // create macro address buffer (size 8 bytes) 00453 std::map<std::string /*arg name*/, uint64_t /*arg val*/> 00454 macroArgs; // create map from arg name to 64-bit number 00455 00456 // command-#0: Read(0x1002 /*address*/,myArg /*data*/); 00457 macroAddress = 0x1002; 00458 memcpy(address, ¯oAddress, 8); // copy macro address to buffer 00459 universalRead(address, data); 00460 memcpy(¯oArgs["myArg"], data, 8); // copy buffer to argument map 00461 __SET_ARG_OUT__("myArg", macroArgs["myArg"]); // update output argument result 00462 00463 // command-#1: Read(0x1001 /*address*/,data); 00464 macroAddress = 0x1001; 00465 memcpy(address, ¯oAddress, 8); // copy macro address to buffer 00466 universalRead(address, data); 00467 memcpy(¯oArgs["outArg1"], data, 8); // copy buffer to argument map 00468 __SET_ARG_OUT__("outArg1", macroArgs["outArg1"]); // update output argument 00469 // result 00470 00471 // command-#2: Write(0x1002 /*address*/,myOtherArg /*data*/); 00472 macroAddress = 0x1002; 00473 memcpy(address, ¯oAddress, 8); // copy macro address to buffer 00474 macroArgs["myOtherArg"] = __GET_ARG_IN__( 00475 "myOtherArg", 00476 uint64_t); // initialize from input arguments //get macro data argument 00477 memcpy(data, ¯oArgs["myOtherArg"], 8); // copy macro data argument to buffer 00478 universalWrite(address, data); 00479 00480 // command-#3: Write(0x1001 /*address*/,myArg /*data*/); 00481 macroAddress = 0x1001; 00482 memcpy(address, 00483 ¯oAddress, 00484 8); // copy macro address to buffer //get macro data argument 00485 memcpy(data, ¯oArgs["myArg"], 8); // copy macro data argument to buffer 00486 universalWrite(address, data); 00487 00488 // command-#4: delay(4); 00489 __FE_COUT__ << "Sleeping for... " << 4 << " milliseconds " << __E__; 00490 usleep(4 * 1000 /* microseconds */); 00491 00492 delete[] address; // free the memory 00493 delete[] data; // free the memory 00494 } 00495 00496 for(auto& argOut : argsOut) 00497 __FE_COUT__ << argOut.first << ": " << argOut.second << __E__; 00498 00499 } // end varTest() 00500 00501 //======================================================================================================================== 00502 // varTest2 00503 // FEMacro 'varTest2' generated, Oct-11-2018 02:28:57, by 'admin' using MacroMaker. 00504 // Macro Notes: [Modified 14:28 10/11/2018] This is a great test! 00505 void FEOtsUDPTemplateInterface::varTest2(__ARGS__) 00506 { 00507 __FE_COUT__ << "# of input args = " << argsIn.size() << __E__; 00508 __FE_COUT__ << "# of output args = " << argsOut.size() << __E__; 00509 for(auto& argIn : argsIn) 00510 __FE_COUT__ << argIn.first << ": " << argIn.second << __E__; 00511 00512 __SET_ARG_OUT__("myArg", "hello2"); // update output argument result 00513 uint64_t macroData = __GET_ARG_IN__("myOtherArg", uint64_t); 00514 macroData *= 3; 00515 __SET_ARG_OUT__("outArg1", macroData); // update output argument result 00516 00517 for(auto& argOut : argsOut) 00518 __FE_COUT__ << argOut.first << ": " << argOut.second << __E__; 00519 00520 } // end varTest2() 00521 00522 DEFINE_OTS_INTERFACE(FEOtsUDPTemplateInterface)