4 #include "otsdaq-demo/FEInterfaces/FEOtsEthernetProgramInterface.h"
5 #include "otsdaq/Macros/CoutMacros.h"
6 #include "otsdaq/Macros/InterfacePluginMacros.h"
7 #include "otsdaq/MessageFacility/MessageFacility.h"
12 #define __MF_SUBJECT__ "FE-FEOtsEthernetProgramInterface"
14 #define PROGRAM_FILE_PATH std::string(__ENV__("OTS_FIRMWARE_PROGRAM_FILE_PATH")) + "/"
20 #define UDP_CORE_BLOCK_ADDRESS ((uint64_t)(0x2) << 32)
21 #define FLASH_COMMAND_BASE 0
26 #define FLASH_WRITE_DATA 4
27 #define FLASH_WRITE_STATUS 9
33 FEOtsEthernetProgramInterface::FEOtsEthernetProgramInterface(
34 const std::string& interfaceUID,
35 const ConfigurationTree& theXDAQContextConfigTree,
36 const std::string& interfaceConfigurationPath)
37 : Socket(theXDAQContextConfigTree.getNode(interfaceConfigurationPath)
38 .getNode(
"HostIPAddress")
39 .getValue<std::string>(),
40 theXDAQContextConfigTree.getNode(interfaceConfigurationPath)
42 .getValue<unsigned int>())
43 , FEOtsUDPTemplateInterface(
44 interfaceUID, theXDAQContextConfigTree, interfaceConfigurationPath)
47 registerFEMacroFunction(
48 "getListOfProgramFiles" ,
49 static_cast<FEVInterface::frontEndMacroFunction_t>(
50 &FEOtsEthernetProgramInterface::getListOfProgramFiles) ,
51 std::vector<std::string>{} ,
52 std::vector<std::string>{
"listOfProgramFiles"} ,
56 std::vector<frontEndMacroArg_t> argsIn;
61 __COUT__ << std::endl;
62 __COUT__ << std::endl;
63 __COUT__ << __COUT_HDR_P__ <<
"# of args = " << argsIn.size() << std::endl;
64 for(
auto& argIn : argsIn)
65 __COUT__ << argIn.first <<
": " << argIn.second << std::endl;
67 std::vector<std::string> returnStrings;
68 std::vector<frontEndMacroArg_t> argsOut;
70 std::string outputArgs =
"listOfProgramFiles";
72 std::istringstream inputStream(outputArgs);
74 while(getline(inputStream, argName,
','))
76 __COUT__ <<
"argName " << argName << std::endl;
78 returnStrings.push_back(std::string(
"test"));
79 argsOut.push_back(FEVInterface::frontEndMacroArg_t(
80 argName, returnStrings[returnStrings.size() - 1]));
87 auto mapOfFEMacroIt = mapOfFEMacroFunctions_.find(
"getListOfProgramFiles");
88 if(mapOfFEMacroIt != mapOfFEMacroFunctions_.end())
90 (this->*(mapOfFEMacroIt->second.macroFunction_))(
91 mapOfFEMacroIt->second, argsIn, argsOut);
92 __COUT__ <<
"Made it " << std::endl;
93 for(
auto& arg : argsOut)
94 __COUT__ << arg.first <<
": " << arg.second << std::endl;
99 FEOtsEthernetProgramInterface::~FEOtsEthernetProgramInterface(
void) {}
102 void FEOtsEthernetProgramInterface::configure(
void)
104 FEOtsUDPTemplateInterface::configure();
148 __COUT__ <<
"Done with configuring." << std::endl;
257 void FEOtsEthernetProgramInterface::getListOfProgramFiles(__ARGS__)
259 std::string dirpath = PROGRAM_FILE_PATH;
261 struct dirent* entry;
263 std::set<std::string> listOfProgramFiles;
265 if((pDIR = opendir(dirpath.c_str())))
270 while((entry = readdir(pDIR)))
273 if(entry->d_name[0] !=
'.' &&
274 (entry->d_type == 0 ||
275 entry->d_type == 4 || entry->d_type == 8))
277 __COUT__ << int(entry->d_type) <<
" " << entry->d_name <<
" "
278 << std::string(entry->d_name).find(
".bin") <<
" "
279 << strlen(entry->d_name) - 4 <<
"\n"
284 if(entry->d_type == 0)
287 DIR* pTmpDIR = opendir((dirpath + entry->d_name).c_str());
295 else if(entry->d_type == 4)
299 std::string(entry->d_name).find(
".bin") == strlen(entry->d_name) - 4)
300 listOfProgramFiles.insert(entry->d_name);
308 __COUT__ <<
"Failed to access directory contents!" << std::endl;
311 auto& returnString = getFEMacroArgument(argsOut,
"listOfProgramFiles");
313 for(
const auto& name : listOfProgramFiles)
315 if(returnString.size())
317 __COUT__ <<
"name " << name << std::endl;
318 returnString += name;
328 void FEOtsEthernetProgramInterface::loadProgramFile(__ARGS__)
334 std::string file =
"";
337 bool prevWasDot =
false;
338 std::string sourceStr = getFEMacroConstArgument(argsIn,
"programFile");
339 for(
const auto& c : sourceStr)
345 file[file.size() - 1] !=
352 else if((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') ||
353 (c >=
'0' && c <=
'9') || c ==
'_' || c ==
'-')
358 std::string path = PROGRAM_FILE_PATH + file;
360 __COUT__ <<
"Programmable file path: " << path << std::endl;
362 FILE* bitstream = fopen(path.c_str(),
"rb");
365 __SS__ <<
"Failed to read bitsream";
366 __COUT_ERR__ <<
"\n" << ss.str();
400 fseek(bitstream, 0, SEEK_END);
401 uint64_t bSize = ftell(bitstream) / 8;
404 __COUT__ <<
"Programmable file size [quad-words]: " << bSize << std::endl;
406 std::string sendBuffer;
407 std::string recvBuffer;
408 uint64_t recvQuadWord;
411 OtsUDPFirmwareCore::softEthernetReset(sendBuffer);
412 OtsUDPHardware::write(sendBuffer);
413 OtsUDPFirmwareCore::clearEthernetReset(sendBuffer);
414 OtsUDPHardware::write(sendBuffer);
421 std::vector<uint64_t> dataVec = {
429 sendBuffer.resize(0);
430 OtsUDPFirmwareCore::writeAdvanced(
432 UDP_CORE_BLOCK_ADDRESS | FLASH_COMMAND_BASE ,
434 OtsUDPHardware::write(sendBuffer);
438 const size_t page_size = 512;
441 char page_data[page_size];
455 sprintf(str,
"Place: %lX Page: %d", ftell(bitstream), page);
458 __COUT__ << str << std::endl;
465 result = fread(page_data, 1, page_size, bitstream);
466 if(result != page_size)
470 __COUT__ <<
"Done" << std::endl;
475 for(
unsigned int i = result; i < page_size; i++)
489 sendBuffer.resize(0);
490 OtsUDPFirmwareCore::read(
492 UDP_CORE_BLOCK_ADDRESS | FLASH_WRITE_STATUS );
496 OtsUDPHardware::read(sendBuffer, recvQuadWord);
501 std::fclose(bitstream);
505 if(recvQuadWord != 0x01)
508 if(recvQuadWord == 3)
509 __COUT_ERR__ <<
"No active command" << std::endl;
511 __COUT_ERR__ <<
"Error in writing multiple pages" << std::endl;
531 sendBuffer.resize(0);
532 OtsUDPFirmwareCore::writeAdvanced(
534 UDP_CORE_BLOCK_ADDRESS | FLASH_WRITE_DATA ,
537 OtsUDPFirmwareCore::FIFO_ADDRESS_CMD_TYPE );
538 OtsUDPHardware::write(sendBuffer);
556 sendBuffer.resize(0);
557 OtsUDPFirmwareCore::writeAdvanced(
559 UDP_CORE_BLOCK_ADDRESS | FLASH_COMMAND_BASE ,
561 OtsUDPHardware::write(sendBuffer);
563 __COUT__ <<
"Sending \"GO\" command..." << std::endl;
570 std::fclose(bitstream);