LCOV - code coverage report
Current view: top level - mu2e-pcie-utils/dtcInterfaceLib - Mu2eUtil.cpp (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 602 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 68 0

            Line data    Source code
       1              : 
       2              : 
       3              : #include "dtcInterfaceLib/otsStyleCoutMacros.h"
       4              : 
       5              : #include "Mu2eUtil.h"
       6              : 
       7            0 : void DTCLib::Mu2eUtil::parse_arguments(int argc, char** argv)
       8              : {
       9            0 :         for (auto optind = 1; optind < argc; ++optind)
      10              :         {
      11            0 :                 if (argv[optind][0] == '-')
      12              :                 {
      13            0 :                         switch (argv[optind][1])
      14              :                         {
      15            0 :                                 case 'i':
      16            0 :                                         incrementTimestamp = false;
      17            0 :                                         break;
      18            0 :                                 case 'd':
      19            0 :                                         delay = DTCLib::Utilities::getOptionValue(&optind, &argv);
      20            0 :                                         break;
      21            0 :                                 case 'D':
      22            0 :                                         cfodelay = DTCLib::Utilities::getOptionValue(&optind, &argv);
      23            0 :                                         break;
      24            0 :                                 case 'S':
      25            0 :                                         syncRequests = true;
      26            0 :                                         break;
      27            0 :                                 case 'n':
      28            0 :                                         number = DTCLib::Utilities::getOptionValue(&optind, &argv);
      29            0 :                                         break;
      30            0 :                                 case 'o':
      31            0 :                                         timestampOffset = DTCLib::Utilities::getOptionValueLong(&optind, &argv) & 0x0000FFFFFFFFFFFF;  // Timestamps are 48 bits
      32            0 :                                         break;
      33            0 :                                 case 'c':
      34            0 :                                         packetCount = DTCLib::Utilities::getOptionValue(&optind, &argv);
      35            0 :                                         break;
      36            0 :                                 case 'N':
      37            0 :                                         forceNoDebug = true;
      38            0 :                                         break;
      39            0 :                                 case 'b':
      40            0 :                                         blockCount = DTCLib::Utilities::getOptionValue(&optind, &argv);
      41            0 :                                         break;
      42            0 :                                 case 'E':
      43            0 :                                         eventCount = DTCLib::Utilities::getOptionValue(&optind, &argv);
      44            0 :                                         break;
      45            0 :                                 case 'a':
      46            0 :                                         requestsAhead = DTCLib::Utilities::getOptionValue(&optind, &argv);
      47            0 :                                         break;
      48            0 :                                 case 'q':
      49            0 :                                         quiet = true;
      50            0 :                                         quietCount = DTCLib::Utilities::getOptionValue(&optind, &argv);
      51            0 :                                         break;
      52            0 :                                 case 'p':
      53            0 :                                         useSimFile = true;
      54            0 :                                         break;
      55            0 :                                 case 'P':
      56            0 :                                         useSimFile = true;
      57            0 :                                         simFile = DTCLib::Utilities::getOptionValue(&optind, &argv);
      58            0 :                                         break;
      59            0 :                                 case 'G':
      60            0 :                                         readGenerated = true;
      61            0 :                                         break;
      62            0 :                                 case 'Q':
      63            0 :                                         quiet = true;
      64            0 :                                         reallyQuiet = true;
      65            0 :                                         break;
      66            0 :                                 case 's':
      67            0 :                                         checkSERDES = true;
      68            0 :                                         break;
      69            0 :                                 case 'e':
      70            0 :                                         useCFOEmulator = false;
      71            0 :                                         break;
      72            0 :                                 case 'f':
      73            0 :                                         rawOutput = true;
      74            0 :                                         rawOutputFile = DTCLib::Utilities::getOptionString(&optind, &argv);
      75            0 :                                         break;
      76            0 :                                 case 'H':
      77            0 :                                         writeDMAHeadersToOutput = true;
      78            0 :                                         break;
      79            0 :                                 case 't':
      80            0 :                                         debugType = DTC_DebugType_ExternalSerialWithReset;
      81            0 :                                         stickyDebugType = false;
      82            0 :                                         break;
      83            0 :                                 case 'T':
      84            0 :                                         val = DTCLib::Utilities::getOptionValue(&optind, &argv);
      85            0 :                                         if (val < static_cast<int>(DTC_DebugType_Invalid))
      86              :                                         {
      87            0 :                                                 stickyDebugType = true;
      88            0 :                                                 debugType = static_cast<DTC_DebugType>(val);
      89            0 :                                                 break;
      90              :                                         }
      91            0 :                                         TLOG(TLVL_ERROR) << "Invalid Debug Type passed to -T!" << std::endl;
      92            0 :                                         printHelpMsg();
      93            0 :                                         break;
      94            0 :                                 case 'r':
      95            0 :                                         rocMask = DTCLib::Utilities::getOptionValue(&optind, &argv);
      96            0 :                                         break;
      97            0 :                                 case 'C':
      98            0 :                                         clockToProgram = DTCLib::Utilities::getOptionValue(&optind, &argv) % 3;
      99            0 :                                         break;
     100            0 :                                 case 'F':
     101            0 :                                         targetFrequency = DTCLib::Utilities::getOptionValue(&optind, &argv);
     102            0 :                                         break;
     103            0 :                                 case 'v':
     104            0 :                                         expectedDesignVersion = DTCLib::Utilities::getOptionString(&optind, &argv);
     105            0 :                                         break;
     106            0 :                                 case 'V':
     107            0 :                                         skipVerify = true;
     108            0 :                                         break;
     109            0 :                                 case '-':  // Long option
     110              :                                 {
     111            0 :                                         auto option = DTCLib::Utilities::getLongOptionOption(&optind, &argv);
     112            0 :                                         if (option == "--timestamp-list")
     113              :                                         {
     114            0 :                                                 timestampFile = DTCLib::Utilities::getLongOptionString(&optind, &argv);
     115              :                                         }
     116            0 :                                         else if (option == "--dtc")
     117              :                                         {
     118            0 :                                                 dtc = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
     119              :                                         }
     120            0 :                                         else if (option == "--cfoDRP")
     121              :                                         {
     122            0 :                                                 useCFODRP = true;
     123              :                                         }
     124            0 :                                         else if (option == "--heartbeats")
     125              :                                         {
     126            0 :                                                 heartbeatsAfter = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
     127              :                                         }
     128            0 :                                         else if (option == "--binary-file-mode")
     129              :                                         {
     130            0 :                                                 binaryFileOutput = true;
     131            0 :                                                 rawOutput = true;
     132            0 :                                                 rawOutputFile = DTCLib::Utilities::getLongOptionString(&optind, &argv);
     133              :                                         }
     134            0 :                                         else if (option == "--stop-verify")
     135              :                                         {
     136            0 :                                                 stopOnVerifyFailure = true;
     137              :                                         }
     138            0 :                                         else if (option == "--stop-on-timeout")
     139              :                                         {
     140            0 :                                                 stopOnTimeout = true;
     141              :                                         }
     142            0 :                                         else if (option == "--extra-reads")
     143              :                                         {
     144            0 :                                                 extraReads = DTCLib::Utilities::getLongOptionValue(&optind, &argv);
     145              :                                         }
     146            0 :                                         else if (option == "--help")
     147              :                                         {
     148            0 :                                                 printHelpMsg();
     149              :                                         }
     150            0 :                                         break;
     151            0 :                                 }
     152            0 :                                 default:
     153            0 :                                         TLOG(TLVL_ERROR) << "Unknown option: " << argv[optind] << std::endl;
     154            0 :                                         printHelpMsg();
     155            0 :                                         break;
     156            0 :                                 case 'h':
     157            0 :                                         printHelpMsg();
     158            0 :                                         break;
     159              :                         }
     160              :                 }
     161              :                 else
     162              :                 {
     163            0 :                         op = std::string(argv[optind]);
     164              :                 }
     165              :         }
     166              : 
     167            0 :         TLOG(TLVL_DEBUG) << "Options are: " << std::boolalpha
     168            0 :                                          << "Operation: " << std::string(op) << ", DTC: " << dtc << ", Num: " << number << ", Delay: " << delay
     169            0 :                                          << ", CFO Delay: " << cfodelay << ", TS Offset: " << timestampOffset << ", PacketCount: " << packetCount
     170            0 :                                          << ", Force NO Debug Flag: " << forceNoDebug << ", DataBlock Count: " << blockCount;
     171            0 :         TLOG(TLVL_DEBUG) << std::boolalpha << ", Event Count: " << eventCount << ", Requests Ahead of Reads: " << requestsAhead
     172            0 :                                          << ", Synchronous Request Mode: " << syncRequests << ", Use DTC CFO Emulator: " << useCFOEmulator << (useCFODRP ? " (CFO Emulator DRPs)" : " (DTC DRPs)")
     173            0 :                                          << ", Increment TS: " << incrementTimestamp << ", Quiet Mode: " << quiet << " (" << quietCount << ")"
     174            0 :                                          << ", Really Quiet Mode: " << reallyQuiet << ", Check SERDES Error Status: " << checkSERDES;
     175            0 :         TLOG(TLVL_DEBUG) << std::boolalpha << ", Read Data from DDR: " << readGenerated
     176            0 :                                          << ", Use Sim File: " << useSimFile << ", Skip Verify: " << skipVerify << ", ROC Mask: " << std::hex
     177            0 :                                          << rocMask << ", Debug Type: " << DTC_DebugTypeConverter(debugType).toString()
     178            0 :                                          << ", Target Frequency: " << std::dec << targetFrequency;
     179            0 :         TLOG(TLVL_DEBUG) << std::boolalpha << ", Clock To Program: " << (clockToProgram == 0 ? "SERDES" : (clockToProgram == 1 ? "DDR" : "Timing"))
     180            0 :                                          << ", Expected Design Version: " << expectedDesignVersion << ", Heartbeats: " << heartbeatsAfter;
     181            0 :         if (rawOutput)
     182              :         {
     183            0 :                 TLOG(TLVL_DEBUG) << ", Raw output file: " << rawOutputFile;
     184              :         }
     185            0 :         if (simFile.size() > 0)
     186              :         {
     187            0 :                 TLOG(TLVL_DEBUG) << ", Sim file: " << simFile;
     188              :         }
     189            0 : }
     190              : 
     191            0 : void DTCLib::Mu2eUtil::read_data()
     192              : {
     193            0 :         TLOG(TLVL_DEBUG) << "Operation \"read_data\"" << std::endl;
     194            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     195              : 
     196            0 :         auto device = thisDTC->GetDevice();
     197            0 :         if (readGenerated)
     198              :         {
     199            0 :                 thisDTC->EnableDetectorEmulatorMode();
     200            0 :                 thisDTC->SetDetectorEmulationDMACount(number);
     201            0 :                 thisDTC->EnableDetectorEmulator();
     202              :         }
     203            0 :         for (unsigned ii = 0; ii < number; ++ii)
     204              :         {
     205            0 :                 TLOG((reallyQuiet ? TLVL_DEBUG + 4 : TLVL_INFO)) << "Buffer Read " << ii << std::endl;
     206              :                 mu2e_databuff_t* buffer;
     207            0 :                 auto tmo_ms = 1500;
     208            0 :                 auto sts = device->read_data(DTC_DMA_Engine_DAQ, reinterpret_cast<void**>(&buffer), tmo_ms);
     209              : 
     210            0 :                 TLOG(TLVL_TRACE) << "util - read for DAQ - ii=" << ii << ", sts=" << sts << ", buffer=" << (void*)buffer;
     211            0 :                 if (sts > 0)
     212              :                 {
     213            0 :                         auto bufSize = static_cast<uint16_t>(*reinterpret_cast<uint64_t*>(&buffer[0]));
     214            0 :                         TLOG(TLVL_TRACE) << "util - bufSize is " << bufSize;
     215              : 
     216            0 :                         if (!reallyQuiet)
     217              :                         {
     218            0 :                                 DTCLib::Utilities::PrintBuffer(buffer, bufSize, quietCount);
     219              :                         }
     220              :                 }
     221            0 :                 device->read_release(DTC_DMA_Engine_DAQ, 1);
     222            0 :                 if (delay > 0) usleep(delay);
     223              :         }
     224            0 :         delete thisDTC;
     225            0 : }
     226              : 
     227            0 : void DTCLib::Mu2eUtil::toggle_serdes()
     228              : {
     229            0 :         TLOG(TLVL_DEBUG) << "Swapping SERDES Oscillator Clock" << std::endl;
     230            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     231            0 :         auto clock = thisDTC->ReadSERDESOscillatorClock();
     232            0 :         if (clock == DTC_SerdesClockSpeed_3125Gbps)
     233              :         {
     234            0 :                 TLOG(TLVL_INFO) << "Setting SERDES Oscillator Clock to 2.5 Gbps" << std::endl;
     235            0 :                 thisDTC->SetSERDESOscillatorClock(DTC_SerdesClockSpeed_25Gbps);
     236              :         }
     237            0 :         else if (clock == DTC_SerdesClockSpeed_25Gbps)
     238              :         {
     239            0 :                 TLOG(TLVL_INFO) << "Setting SERDES Oscillator Clock to 3.125 Gbps" << std::endl;
     240            0 :                 thisDTC->SetSERDESOscillatorClock(DTC_SerdesClockSpeed_3125Gbps);
     241              :         }
     242              :         else
     243              :         {
     244            0 :                 TLOG(TLVL_ERROR) << "Error: SERDES clock not recognized value!";
     245              :         }
     246            0 :         delete thisDTC;
     247            0 : }
     248              : 
     249            0 : void DTCLib::Mu2eUtil::reset_ddr()
     250              : {
     251            0 :         TLOG(TLVL_DEBUG) << "Resetting DDR Address" << std::endl;
     252            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     253              : 
     254            0 :         thisDTC->ResetDDRInterface();
     255            0 :         thisDTC->ResetDDRReadAddress();
     256            0 :         thisDTC->ResetDDRWriteAddress();
     257            0 :         thisDTC->ResetDDR();
     258            0 :         delete thisDTC;
     259            0 : }
     260              : 
     261            0 : void DTCLib::Mu2eUtil::reset_detector_emulator()
     262              : {
     263            0 :         TLOG(TLVL_DEBUG) << "Resetting Detector Emulator" << std::endl;
     264            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     265            0 :         thisDTC->ClearDetectorEmulatorInUse();
     266            0 :         thisDTC->ResetDDR();
     267            0 :         thisDTC->SoftReset();
     268            0 :         delete thisDTC;
     269            0 : }
     270              : 
     271            0 : void DTCLib::Mu2eUtil::verify_sim_file()
     272              : {
     273            0 :         TLOG(TLVL_DEBUG) << "Operation \"verify_simfile\"" << std::endl;
     274            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     275            0 :         auto device = thisDTC->GetDevice();
     276              : 
     277            0 :         device->ResetDeviceTime();
     278              : 
     279            0 :         if (useSimFile)
     280              :         {
     281            0 :                 thisDTC->DisableDetectorEmulator();
     282            0 :                 thisDTC->EnableDetectorEmulatorMode();
     283            0 :                 thisDTC->VerifySimFileInDTC(simFile, rawOutputFile);
     284              :         }
     285            0 : }
     286              : 
     287            0 : void DTCLib::Mu2eUtil::verify_stream()
     288              : {
     289            0 :         TLOG(TLVL_DEBUG) << "Operation \"verify_stream\"" << std::endl;
     290            0 :         auto startTime = std::chrono::steady_clock::now();
     291            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     292            0 :         auto device = thisDTC->GetDevice();
     293              : 
     294            0 :         auto initTime = device->GetDeviceTime();
     295            0 :         device->ResetDeviceTime();
     296            0 :         auto afterInit = std::chrono::steady_clock::now();
     297              : 
     298            0 :         DTCSoftwareCFO cfo(thisDTC, useCFOEmulator, packetCount, debugType, stickyDebugType, quiet, false, forceNoDebug, useCFODRP);
     299              : 
     300            0 :         if (useSimFile)
     301              :         {
     302            0 :                 auto overwrite = false;
     303            0 :                 if (simFile.size() > 0) overwrite = true;
     304            0 :                 thisDTC->WriteSimFileToDTC(simFile, false, overwrite, rawOutputFile, skipVerify);
     305            0 :                 if (readGenerated)
     306              :                 {
     307            0 :                         exit(0);
     308              :                 }
     309              :         }
     310            0 :         else if (readGenerated)
     311              :         {
     312            0 :                 thisDTC->DisableDetectorEmulator();
     313            0 :                 thisDTC->EnableDetectorEmulatorMode();
     314            0 :                 thisDTC->SetDetectorEmulationDMACount(number);
     315            0 :                 thisDTC->EnableDetectorEmulator();
     316              :         }
     317              : 
     318            0 :         if (thisDTC->GetSimMode() != DTC_SimMode_Loopback && timestampFile != "")
     319              :         {
     320            0 :                 syncRequests = false;
     321            0 :                 std::set<DTC_EventWindowTag> timestamps;
     322            0 :                 std::ifstream is(timestampFile);
     323              :                 uint64_t a;
     324            0 :                 while (is >> a)
     325              :                 {
     326            0 :                         timestamps.insert(DTC_EventWindowTag(a));
     327              :                 }
     328            0 :                 number = timestamps.size();
     329            0 :                 cfo.SendRequestsForList(timestamps, cfodelay, heartbeatsAfter);
     330            0 :         }
     331            0 :         else if (thisDTC->GetSimMode() != DTC_SimMode_Loopback && !syncRequests)
     332              :         {
     333            0 :                 cfo.SendRequestsForRange(number, DTC_EventWindowTag(timestampOffset), incrementTimestamp, cfodelay, requestsAhead, heartbeatsAfter);
     334              :         }
     335            0 :         else if (thisDTC->GetSimMode() == DTC_SimMode_Loopback)
     336              :         {
     337            0 :                 uint64_t ts = timestampOffset;
     338            0 :                 DTC_DataHeaderPacket header(DTC_Link_0, static_cast<uint16_t>(0), DTC_DataStatus_Valid, 0, DTC_Subsystem_Other, 0, DTC_EventWindowTag(ts));
     339            0 :                 TLOG(TLVL_INFO) << "Request: " << header.toJSON() << std::endl;
     340            0 :                 thisDTC->WriteDMAPacket(header);
     341            0 :         }
     342              : 
     343            0 :         auto readoutRequestTime = device->GetDeviceTime();
     344            0 :         device->ResetDeviceTime();
     345            0 :         auto afterRequests = std::chrono::steady_clock::now();
     346              : 
     347            0 :         DTC_Data_Verifier verifier;
     348              : 
     349            0 :         for (unsigned ii = 0; ii < number + extraReads; ++ii)
     350              :         {
     351            0 :                 if (syncRequests && ii < number)
     352              :                 {
     353            0 :                         auto startRequest = std::chrono::steady_clock::now();
     354            0 :                         cfo.SendRequestForTimestamp(DTC_EventWindowTag(timestampOffset + (incrementTimestamp ? ii : 0), heartbeatsAfter));
     355            0 :                         auto endRequest = std::chrono::steady_clock::now();
     356            0 :                         readoutRequestTime +=
     357            0 :                                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(endRequest - startRequest).count();
     358              :                 }
     359            0 :                 TLOG((reallyQuiet ? TLVL_DEBUG + 4 : TLVL_INFO)) << "Buffer Read " << std::dec << ii << std::endl;
     360              : 
     361            0 :                 bool readSuccess = false;
     362            0 :                 bool timeout = false;
     363            0 :                 bool verified = false;
     364            0 :                 size_t sts = 0;
     365            0 :                 unsigned buffers_read = 1;
     366            0 :                 mu2e_databuff_t* buffer = readDTCBuffer(device, readSuccess, timeout, sts, false);
     367              : 
     368            0 :                 if (!readSuccess && checkSERDES)
     369              :                         break;
     370            0 :                 else if (!readSuccess)
     371            0 :                         continue;
     372              : 
     373            0 :                 void* readPtr = &buffer[0];
     374            0 :                 uint16_t bufSize = static_cast<uint16_t>(*static_cast<uint64_t*>(readPtr));
     375            0 :                 readPtr = static_cast<uint8_t*>(readPtr) + 8;
     376              : 
     377            0 :                 if (timeout)
     378              :                 {
     379            0 :                         if (stopOnTimeout)
     380              :                         {
     381            0 :                                 TLOG(TLVL_ERROR) << "Timeout detected and stop-on-timeout mode enabled. Stopping after " << ii << " events!";
     382            0 :                                 break;
     383              :                         }
     384              : 
     385            0 :                         TLOG(TLVL_WARNING) << "Timeout detected, moving to next read";
     386            0 :                         continue;
     387            0 :                 }
     388              : 
     389            0 :                 DTC_Event evt(readPtr);
     390            0 :                 size_t eventByteCount = evt.GetEventByteCount();
     391            0 :                 size_t subEventCount = 0;
     392            0 :                 if (eventByteCount > bufSize - 8U)
     393              :                 {
     394            0 :                         DTC_Event newEvt(eventByteCount);
     395            0 :                         memcpy(const_cast<void*>(newEvt.GetRawBufferPointer()), evt.GetRawBufferPointer(), bufSize - 8);
     396            0 :                         size_t newEvtSize = bufSize - 8;
     397            0 :                         while (newEvtSize < eventByteCount)
     398              :                         {
     399            0 :                                 TLOG(TLVL_TRACE) << "Reading continued DMA, current size " << newEvtSize << " / " << eventByteCount;
     400            0 :                                 buffer = readDTCBuffer(device, readSuccess, timeout, sts, true);
     401            0 :                                 if (!readSuccess)
     402              :                                 {
     403            0 :                                         TLOG(TLVL_ERROR) << "Unable to receive continued DMA! Aborting!";
     404            0 :                                         break;
     405              :                                 }
     406            0 :                                 readPtr = &buffer[0];
     407            0 :                                 bufSize = static_cast<uint16_t>(*static_cast<uint64_t*>(readPtr));
     408            0 :                                 readPtr = static_cast<uint8_t*>(readPtr) + 8;
     409            0 :                                 buffers_read++;
     410              : 
     411            0 :                                 size_t bytes_to_read = bufSize - 8;
     412            0 :                                 if (newEvtSize + bufSize - 8 > eventByteCount) { bytes_to_read = eventByteCount - newEvtSize; }
     413              : 
     414            0 :                                 memcpy(const_cast<uint8_t*>(static_cast<const uint8_t*>(newEvt.GetRawBufferPointer()) + newEvtSize), readPtr, bytes_to_read);
     415            0 :                                 newEvtSize += bufSize - 8;
     416              :                         }
     417              : 
     418            0 :                         if (!readSuccess && checkSERDES)
     419              :                                 break;
     420            0 :                         else if (!readSuccess)
     421            0 :                                 continue;
     422              : 
     423            0 :                         newEvt.SetupEvent();
     424            0 :                         subEventCount = newEvt.GetSubEventCount();
     425              : 
     426            0 :                         if (thisDTC->GetSimMode() == DTC_SimMode_ROCEmulator ||
     427            0 :                                 thisDTC->GetSimMode() == DTC_SimMode_Performance)
     428              :                         {
     429            0 :                                 auto roc_mask_tmp = rocMask;
     430            0 :                                 size_t num_rocs = 0;
     431              : 
     432            0 :                                 while (roc_mask_tmp != 0)
     433              :                                 {
     434            0 :                                         if ((roc_mask_tmp & 0x1) == 1)
     435              :                                         {
     436            0 :                                                 num_rocs++;
     437              :                                         }
     438            0 :                                         roc_mask_tmp = roc_mask_tmp >> 4;
     439              :                                 }
     440              : 
     441            0 :                                 size_t expectedEventSize = sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader) + num_rocs * ((packetCount + 1) * 16);
     442            0 :                                 if (newEvt.GetEventByteCount() != expectedEventSize)
     443              :                                 {
     444            0 :                                         TLOG(TLVL_WARNING) << "DTC_Event size mismatch! Expected size was " << expectedEventSize << ", actual " << newEvt.GetEventByteCount();
     445              :                                 }
     446              :                         }
     447              : 
     448            0 :                         verified = verifier.VerifyEvent(newEvt);
     449            0 :                 }
     450              :                 else
     451              :                 {
     452            0 :                         evt.SetupEvent();
     453            0 :                         subEventCount = evt.GetSubEventCount();
     454            0 :                         if (thisDTC->GetSimMode() == DTC_SimMode_ROCEmulator ||
     455            0 :                                 thisDTC->GetSimMode() == DTC_SimMode_Performance)
     456              :                         {
     457            0 :                                 auto roc_mask_tmp = rocMask;
     458            0 :                                 size_t num_rocs = 0;
     459              : 
     460            0 :                                 while (roc_mask_tmp != 0)
     461              :                                 {
     462            0 :                                         if ((roc_mask_tmp & 0x1) == 1)
     463              :                                         {
     464            0 :                                                 num_rocs++;
     465              :                                         }
     466            0 :                                         roc_mask_tmp = roc_mask_tmp >> 4;
     467              :                                 }
     468              : 
     469            0 :                                 size_t expectedEventSize = sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader) + num_rocs * ((packetCount + 1) * 16);
     470            0 :                                 if (evt.GetEventByteCount() != expectedEventSize)
     471              :                                 {
     472            0 :                                         TLOG(TLVL_WARNING) << "DTC_Event size mismatch! Expected size was " << expectedEventSize << ", actual " << evt.GetEventByteCount();
     473              :                                 }
     474              :                         }
     475            0 :                         verified = verifier.VerifyEvent(evt);
     476              :                 }
     477            0 :                 if (!reallyQuiet)
     478              :                 {
     479            0 :                         if (verified)
     480              :                         {
     481            0 :                                 TLOG(TLVL_INFO) << "Event verified successfully, " << subEventCount << " sub-events";
     482              :                         }
     483              :                         else
     484              :                         {
     485            0 :                                 TLOG(TLVL_WARNING) << "Event verification failed!";
     486              :                         }
     487              :                 }
     488              : 
     489            0 :                 if (stopOnVerifyFailure && !verified)
     490              :                 {
     491            0 :                         TLOG(TLVL_ERROR) << "Event verification error encountered and stop-verify mode enabled. Stopping after " << ii << " events!";
     492            0 :                         break;
     493              :                 }
     494              : 
     495            0 :                 device->read_release(DTC_DMA_Engine_DAQ, buffers_read);
     496            0 :                 if (delay > 0) usleep(delay);
     497            0 :         }
     498            0 :         device->release_all(DTC_DMA_Engine_DAQ);
     499              : 
     500            0 :         auto readDevTime = device->GetDeviceTime();
     501            0 :         auto doneTime = std::chrono::steady_clock::now();
     502            0 :         auto totalBytesRead = device->GetReadSize();
     503            0 :         auto totalBytesWritten = device->GetWriteSize();
     504              :         auto totalTime =
     505            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(doneTime - startTime).count();
     506              :         auto totalInitTime =
     507            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(afterInit - startTime).count();
     508              :         auto totalRequestTime =
     509            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(afterRequests - afterInit).count();
     510              :         auto totalReadTime =
     511            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(doneTime - afterRequests).count();
     512              : 
     513            0 :         TLOG(TLVL_INFO) << "Total Elapsed Time: " << Utilities::FormatTimeString(totalTime) << "." << std::endl
     514            0 :                                         << "Total Init Time: " << Utilities::FormatTimeString(totalInitTime) << "." << std::endl
     515            0 :                                         << "Total Readout Request Time: " << Utilities::FormatTimeString(totalRequestTime) << "." << std::endl
     516            0 :                                         << "Total Read Time: " << Utilities::FormatTimeString(totalReadTime) << "." << std::endl;
     517            0 :         TLOG(TLVL_INFO) << "Device Init Time: " << Utilities::FormatTimeString(initTime) << "." << std::endl
     518            0 :                                         << "Device Request Time: " << Utilities::FormatTimeString(readoutRequestTime) << "." << std::endl
     519            0 :                                         << "Device Read Time: " << Utilities::FormatTimeString(readDevTime) << "." << std::endl;
     520            0 :         TLOG(TLVL_INFO) << "Total Bytes Written: " << Utilities::FormatByteString(static_cast<double>(totalBytesWritten), "")
     521            0 :                                         << "." << std::endl
     522            0 :                                         << "Total Bytes Read: " << Utilities::FormatByteString(static_cast<double>(totalBytesRead), "") << "."
     523            0 :                                         << std::endl;
     524            0 :         TLOG(TLVL_INFO) << "Total PCIe Rate: "
     525            0 :                                         << Utilities::FormatByteString((totalBytesWritten + totalBytesRead) / totalTime, "/s") << std::endl
     526            0 :                                         << "Read Rate: " << Utilities::FormatByteString(totalBytesRead / totalReadTime, "/s") << std::endl
     527            0 :                                         << "Device Read Rate: " << Utilities::FormatByteString(totalBytesRead / readDevTime, "/s") << std::endl;
     528            0 : }
     529              : 
     530            0 : void DTCLib::Mu2eUtil::buffer_test()
     531              : {
     532            0 :         TLOG(TLVL_DEBUG) << "Operation \"buffer_test\"" << std::endl;
     533            0 :         auto startTime = std::chrono::steady_clock::now();  // get the beggining of the test
     534            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion);
     535            0 :         auto device = thisDTC->GetDevice();
     536              : 
     537            0 :         auto initTime = device->GetDeviceTime();
     538            0 :         device->ResetDeviceTime();
     539            0 :         auto afterInit = std::chrono::steady_clock::now();
     540              : 
     541              :         // Emulated CFO
     542              :         DTCSoftwareCFO cfo(thisDTC,
     543            0 :                                            useCFOEmulator,
     544            0 :                                            packetCount,
     545              :                                            debugType,
     546            0 :                                            stickyDebugType,
     547            0 :                                            quiet,
     548              :                                            false,
     549            0 :                                            forceNoDebug,
     550            0 :                                            useCFODRP);
     551              : 
     552            0 :         if (useSimFile)
     553              :         {
     554            0 :                 auto overwrite = false;
     555            0 :                 if (simFile.size() > 0) overwrite = true;
     556            0 :                 thisDTC->WriteSimFileToDTC(simFile, false, overwrite, rawOutputFile, skipVerify);
     557            0 :                 if (readGenerated)
     558              :                 {
     559            0 :                         exit(0);
     560              :                 }
     561              :         }
     562            0 :         else if (readGenerated)
     563              :         {
     564            0 :                 thisDTC->DisableDetectorEmulator();
     565            0 :                 thisDTC->EnableDetectorEmulatorMode();
     566            0 :                 thisDTC->SetDetectorEmulationDMACount(number);
     567            0 :                 thisDTC->EnableDetectorEmulator();
     568              :         }
     569              : 
     570            0 :         if (thisDTC->GetSimMode() != DTC_SimMode_Loopback && timestampFile != "")
     571              :         {
     572            0 :                 syncRequests = false;
     573            0 :                 std::set<DTC_EventWindowTag> timestamps;
     574            0 :                 std::ifstream is(timestampFile);
     575              :                 uint64_t a;
     576            0 :                 while (is >> a)
     577              :                 {
     578            0 :                         timestamps.insert(DTC_EventWindowTag(a));
     579              :                 }
     580            0 :                 number = timestamps.size();
     581            0 :                 cfo.SendRequestsForList(timestamps, cfodelay, heartbeatsAfter);
     582            0 :         }
     583            0 :         else if (thisDTC->GetSimMode() != DTC_SimMode_Loopback && !syncRequests)
     584              :         {
     585            0 :                 cfo.SendRequestsForRange(number,
     586            0 :                                                                  DTC_EventWindowTag(timestampOffset),
     587            0 :                                                                  incrementTimestamp,
     588              :                                                                  cfodelay,
     589              :                                                                  requestsAhead,
     590              :                                                                  heartbeatsAfter);
     591              :         }
     592            0 :         else if (thisDTC->GetSimMode() == DTC_SimMode_Loopback)
     593              :         {
     594            0 :                 uint64_t ts = timestampOffset;
     595            0 :                 DTC_DataHeaderPacket header(DTC_Link_0, static_cast<uint16_t>(0), DTC_DataStatus_Valid, 0, DTC_Subsystem_Other, 0, DTC_EventWindowTag(ts));
     596            0 :                 TLOG(TLVL_INFO) << "Request: " << header.toJSON() << std::endl;
     597            0 :                 thisDTC->WriteDMAPacket(header);
     598            0 :         }
     599              : 
     600              :         // record the response time
     601            0 :         auto readoutRequestTime = device->GetDeviceTime();
     602            0 :         device->ResetDeviceTime();
     603            0 :         auto afterRequests = std::chrono::steady_clock::now();
     604              : 
     605            0 :         for (unsigned ii = 0; ii < number + extraReads; ++ii)
     606              :         {
     607            0 :                 if (syncRequests && ii < number)
     608              :                 {
     609            0 :                         auto startRequest = std::chrono::steady_clock::now();
     610            0 :                         cfo.SendRequestForTimestamp(DTC_EventWindowTag(timestampOffset + (incrementTimestamp ? ii : 0), heartbeatsAfter));
     611            0 :                         auto endRequest = std::chrono::steady_clock::now();
     612            0 :                         readoutRequestTime +=
     613            0 :                                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(endRequest - startRequest).count();
     614              :                 }
     615            0 :                 TLOG((reallyQuiet ? TLVL_DEBUG + 4 : TLVL_INFO)) << "Buffer Read " << std::dec << ii << std::endl;
     616              : 
     617            0 :                 bool readSuccess = false;
     618            0 :                 bool timeout = false;
     619            0 :                 size_t sts = 0;
     620            0 :                 mu2e_databuff_t* buffer = readDTCBuffer(device, readSuccess, timeout, sts, false);
     621              : 
     622              :                 // check if the read of the buffer is succesful
     623            0 :                 if (!readSuccess && checkSERDES)
     624              :                         break;
     625            0 :                 else if (!readSuccess)
     626            0 :                         continue;
     627              : 
     628            0 :                 if (stopOnTimeout && timeout)
     629              :                 {
     630            0 :                         TLOG(TLVL_ERROR) << "Timeout detected and stop-on-timeout mode enabled. Stopping after " << ii << " events!";
     631            0 :                         break;
     632              :                 }
     633              : 
     634            0 :                 if (!reallyQuiet)
     635              :                 {
     636            0 :                         DTCLib::Utilities::PrintBuffer(buffer, sts, quietCount);
     637              :                 }
     638              : 
     639            0 :                 device->read_release(DTC_DMA_Engine_DAQ, 1);
     640            0 :                 if (delay > 0) usleep(delay);
     641              :         }
     642            0 :         device->release_all(DTC_DMA_Engine_DAQ);
     643              : 
     644            0 :         auto readDevTime = device->GetDeviceTime();
     645            0 :         auto doneTime = std::chrono::steady_clock::now();
     646            0 :         auto totalBytesRead = device->GetReadSize();
     647            0 :         auto totalBytesWritten = device->GetWriteSize();
     648              :         auto totalTime =
     649            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(doneTime - startTime).count();
     650              :         auto totalInitTime =
     651            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(afterInit - startTime).count();
     652              :         auto totalRequestTime =
     653            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(afterRequests - afterInit).count();
     654              :         auto totalReadTime =
     655            0 :                 std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1>>>(doneTime - afterRequests).count();
     656              : 
     657            0 :         TLOG(TLVL_INFO) << "Total Elapsed Time: " << Utilities::FormatTimeString(totalTime) << "." << std::endl
     658            0 :                                         << "Total Init Time: " << Utilities::FormatTimeString(totalInitTime) << "." << std::endl
     659            0 :                                         << "Total Readout Request Time: " << Utilities::FormatTimeString(totalRequestTime) << "." << std::endl
     660            0 :                                         << "Total Read Time: " << Utilities::FormatTimeString(totalReadTime) << "." << std::endl;
     661            0 :         TLOG(TLVL_INFO) << "Device Init Time: " << Utilities::FormatTimeString(initTime) << "." << std::endl
     662            0 :                                         << "Device Request Time: " << Utilities::FormatTimeString(readoutRequestTime) << "." << std::endl
     663            0 :                                         << "Device Read Time: " << Utilities::FormatTimeString(readDevTime) << "." << std::endl;
     664            0 :         TLOG(TLVL_INFO) << "Total Bytes Written: " << Utilities::FormatByteString(static_cast<double>(totalBytesWritten), "")
     665            0 :                                         << "." << std::endl
     666            0 :                                         << "Total Bytes Read: " << Utilities::FormatByteString(static_cast<double>(totalBytesRead), "") << "."
     667            0 :                                         << std::endl;
     668            0 :         TLOG(TLVL_INFO) << "Total PCIe Rate: "
     669            0 :                                         << Utilities::FormatByteString((totalBytesWritten + totalBytesRead) / totalTime, "/s") << std::endl
     670            0 :                                         << "Read Rate: " << Utilities::FormatByteString(totalBytesRead / totalReadTime, "/s") << std::endl
     671            0 :                                         << "Device Read Rate: " << Utilities::FormatByteString(totalBytesRead / readDevTime, "/s") << std::endl;
     672            0 : }
     673              : 
     674            0 : void DTCLib::Mu2eUtil::read_release()
     675              : {
     676            0 :         TLOG(TLVL_DEBUG) << "Operation \"read_release\"";
     677            0 :         mu2edev device;
     678            0 :         device.init(DTCLib::DTC_SimMode_Disabled, dtc);
     679            0 :         for (unsigned ii = 0; ii < number; ++ii)
     680              :         {
     681              :                 void* buffer;
     682            0 :                 auto tmo_ms = 0;
     683            0 :                 auto stsRD = device.read_data(DTC_DMA_Engine_DAQ, &buffer, tmo_ms);
     684            0 :                 auto stsRL = device.read_release(DTC_DMA_Engine_DAQ, 1);
     685            0 :                 TLOG(TLVL_TRACE + 10) << "util - release/read for DAQ and DCS ii=" << ii << ", stsRD=" << stsRD << ", stsRL=" << stsRL << ", buffer=" << buffer;
     686            0 :                 if (delay > 0) usleep(delay);
     687              :         }
     688            0 : }
     689              : 
     690            0 : void DTCLib::Mu2eUtil::program_clock()
     691              : {
     692            0 :         TLOG(TLVL_DEBUG) << "Operation \"program_clock\"";
     693            0 :         auto thisDTC = new DTC(DTC_SimMode_NoCFO, dtc, rocMask, expectedDesignVersion, true);
     694            0 :         auto oscillator = clockToProgram == 0 ? DTC_OscillatorType_SERDES
     695            0 :                                                                                   : (clockToProgram == 1 ? DTC_OscillatorType_DDR : DTC_OscillatorType_Timing);
     696            0 :         thisDTC->SetNewOscillatorFrequency(oscillator, targetFrequency);
     697            0 :         delete thisDTC;
     698            0 : }
     699              : 
     700            0 : void DTCLib::Mu2eUtil::dma_info()
     701              : {
     702            0 :         TLOG(TLVL_DEBUG) << "Opearation \"dma_info\"";
     703            0 :         if (dtc == -1)
     704              :         {
     705            0 :                 auto dtcE = getenv("DTCLIB_DTC");
     706            0 :                 if (dtcE != nullptr)
     707              :                 {
     708            0 :                         dtc = atoi(dtcE);
     709              :                 }
     710              :                 else
     711            0 :                         dtc = 0;
     712              :         }
     713              : 
     714            0 :         mu2edev device;
     715            0 :         device.init(DTCLib::DTC_SimMode_Disabled, dtc);
     716            0 :         device.meta_dump();
     717            0 : }
     718              : 
     719            0 : void DTCLib::Mu2eUtil::run()
     720              : {
     721            0 :         if (rawOutput) outputStream.open(rawOutputFile, std::ios::out | std::ios::app | std::ios::binary);
     722              : 
     723            0 :         if (op == "read_data")
     724              :         {
     725            0 :                 read_data();
     726              :         }
     727            0 :         else if (op == "toggle_serdes")
     728              :         {
     729            0 :                 toggle_serdes();
     730              :         }
     731            0 :         else if (op == "reset_ddr")
     732              :         {
     733            0 :                 reset_ddr();
     734              :         }
     735            0 :         else if (op == "reset_detemu")
     736              :         {
     737            0 :                 reset_detector_emulator();
     738              :         }
     739            0 :         else if (op == "verify_simfile")
     740              :         {
     741            0 :                 verify_sim_file();
     742              :         }
     743            0 :         else if (op == "verify_stream")
     744              :         {
     745            0 :                 verify_stream();
     746              :         }
     747            0 :         else if (op == "buffer_test")
     748              :         {
     749            0 :                 buffer_test();
     750              :         }
     751            0 :         else if (op == "read_release")
     752              :         {
     753            0 :                 read_release();
     754              :         }
     755            0 :         else if (op == "program_clock")
     756              :         {
     757            0 :                 program_clock();
     758              :         }
     759            0 :         else if (op == "dma_info")
     760              :         {
     761            0 :                 dma_info();
     762              :         }
     763              :         else
     764              :         {
     765            0 :                 TLOG(TLVL_ERROR) << "Unrecognized operation: " << op << std::endl;
     766            0 :                 printHelpMsg();
     767              :         }
     768              : 
     769            0 :         if (rawOutput)
     770              :         {
     771            0 :                 outputStream.flush();
     772            0 :                 outputStream.close();
     773              :         }
     774            0 : }
     775              : 
     776            0 : void DTCLib::Mu2eUtil::printHelpMsg()
     777              : {
     778              :         std::cout << "Usage: mu2eUtil [options] "
     779            0 :                                  "[read_data,reset_ddrread,reset_detemu,toggle_serdes,loopback,verify_stream,buffer_test,read_release,program_clock,verify_simfile,dma_info]"
     780            0 :                           << std::endl;
     781              :         std::cout
     782            0 :                 << "Options are:" << std::endl
     783            0 :                 << "    -h, --help: This message." << std::endl
     784            0 :                 << "    -n: Number of times to repeat test. (Default: 1)" << std::endl
     785            0 :                 << "    -o: Starting Timestamp offest. (Default: 1)." << std::endl
     786            0 :                 << "    -i: Do not increment Timestamps." << std::endl
     787            0 :                 << "    -S: Synchronous Timestamp mode (1 RR & DR per Read operation)" << std::endl
     788            0 :                 << "    -d: Delay between tests, in us (Default: 0)." << std::endl
     789            0 :                 << "    -D: CFO Request delay interval (Default: 1000 (minimum)." << std::endl
     790            0 :                 << "    -c: Number of Debug Packets to request (Default: 0)." << std::endl
     791            0 :                 << "    -N: Do NOT set the Debug flag in generated Data Request packets" << std::endl
     792            0 :                 << "    -b: Number of Data Blocks to generate per Event (Default: 1)." << std::endl
     793            0 :                 << "    -E: Number of Events to generate per DMA block (Default: 1)." << std::endl
     794            0 :                 << "    -a: Number of Readout Request/Data Requests to send before starting to read data (Default: 0)."
     795            0 :                 << std::endl
     796              :                 << "    -q: Quiet mode (Don't print requests) Additionally, for buffer_test mode, limits to N (Default 1) "
     797            0 :                    "packets at the beginning and end of the buffer."
     798            0 :                 << std::endl
     799            0 :                 << "    -Q: Really Quiet mode (Try not to print anything)" << std::endl
     800            0 :                 << "    -s: Stop on SERDES Error." << std::endl
     801            0 :                 << "    -e: Use DTCLib's SoftwareCFO instead of the DTC CFO Emulator" << std::endl
     802            0 :                 << "    -t: Use DebugType flag (1st request gets ExternalDataWithFIFOReset, the rest get ExternalData)"
     803            0 :                 << std::endl
     804            0 :                 << "    -T: Set DebugType flag for ALL requests (0, 1, or 2)" << std::endl
     805            0 :                 << "    -f: RAW Output file path" << std::endl
     806            0 :                 << "    -H: Write DMA headers to raw output file (when -f is used with -g)" << std::endl
     807            0 :                 << "    -p: Send DTCLIB_SIM_FILE to DTC and enable Detector Emulator mode" << std::endl
     808            0 :                 << "    -P: Send <file> to DTC and enable Detector Emulator mode (Default: \"\")" << std::endl
     809            0 :                 << "    -G: Enable Detector Emulator Mode" << std::endl
     810              :                 << "    -r: # of rocs to enable. Hexadecimal, each digit corresponds to a link. ROC_0: 1, ROC_1: 3, ROC_2: 5, "
     811            0 :                    "ROC_3: 7, ROC_4: 9, ROC_5: B (Default 0x1, All possible: 0xBBBBBB)"
     812            0 :                 << std::endl
     813            0 :                 << "    -F: Frequency to program (in Hz, sorry...Default 166666667 Hz)" << std::endl
     814            0 :                 << "    -C: Clock to program (0: SERDES, 1: DDR, 2: Timing, Default 0)" << std::endl
     815            0 :                 << "    -v: Expected DTC Design version string (Default: \"\")" << std::endl
     816            0 :                 << "    -V: Do NOT attempt to verify that the sim file landed in DTC memory correctly" << std::endl
     817            0 :                 << "    --timestamp-list: Read <file> for timestamps to request (CFO will generate heartbeats for all timestamps in range spanned by file)" << std::endl
     818            0 :                 << "    --dtc: Use dtc <num> (Defaults to DTCLIB_DTC if set, 0 otherwise, see ls /dev/mu2e* for available DTCs)" << std::endl
     819            0 :                 << "    --cfoDRP: Send DRPs from the DTC CFO Emulator instead of from the DTC itself" << std::endl
     820            0 :                 << "    --heartbeats: Send <int> heartbeats after each DataRequestPacket" << std::endl
     821            0 :                 << "    --binary-file-mode: Write DMA sizes to <file> along with read data, to generate a new binary file for detector emulator mode (not compatible with -f)" << std::endl
     822            0 :                 << "    --stop-verify: If a verify_stream mode error occurs, stop processing" << std::endl
     823            0 :                 << "    --stop-on-timeout: Stop verify_stream or buffer_test mode if a timeout is detected (0xCAFE in first packet of buffer)" << std::endl
     824            0 :                 << "    --extra-reads: Number of extra DMA reads to attempt in verify_stream and buffer_test modes (Default: 1)" << std::endl;
     825              : 
     826            0 :         exit(0);
     827              : }
     828              : 
     829            0 : mu2e_databuff_t* DTCLib::Mu2eUtil::readDTCBuffer(mu2edev* device, bool& readSuccess, bool& timeout, size_t& sts, bool continuedMode)
     830              : {
     831              :         mu2e_databuff_t* buffer;
     832            0 :         auto tmo_ms = 1500;
     833            0 :         readSuccess = false;
     834            0 :         TLOG(TLVL_TRACE) << "util - before read for DAQ";
     835            0 :         sts = device->read_data(DTC_DMA_Engine_DAQ, reinterpret_cast<void**>(&buffer), tmo_ms);
     836            0 :         TLOG(TLVL_TRACE) << "util - after read for DAQ sts=" << sts << ", buffer=" << (void*)buffer;
     837              : 
     838            0 :         if (sts > 0)
     839              :         {
     840            0 :                 readSuccess = true;
     841            0 :                 void* readPtr = &buffer[0];
     842            0 :                 uint16_t bufSize = static_cast<uint16_t>(*static_cast<uint64_t*>(readPtr));
     843            0 :                 readPtr = static_cast<uint8_t*>(readPtr) + 8;
     844            0 :                 TLOG((reallyQuiet ? TLVL_DEBUG + 4 : TLVL_INFO)) << "Buffer reports DMA size of " << std::dec << bufSize << " bytes. Device driver reports read of "
     845            0 :                                                                                                                  << sts << " bytes," << std::endl;
     846              : 
     847            0 :                 TLOG(TLVL_TRACE) << "util - bufSize is " << bufSize;
     848            0 :                 if (binaryFileOutput)
     849              :                 {
     850            0 :                         uint64_t dmaWriteSize = sts + 8;
     851            0 :                         outputStream.write(reinterpret_cast<char*>(&dmaWriteSize), sizeof(dmaWriteSize));
     852            0 :                         outputStream.write(reinterpret_cast<char*>(&buffer[0]), sts);
     853              :                 }
     854            0 :                 else if (rawOutput)
     855              :                 {
     856            0 :                         outputStream.write(static_cast<char*>(readPtr), sts - 8);
     857              :                 }
     858              : 
     859            0 :                 timeout = false;
     860            0 :                 if (!continuedMode && sts > sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader) + 8)
     861              :                 {
     862              :                         // Check for dead or cafe in first packet
     863            0 :                         readPtr = static_cast<uint8_t*>(readPtr) + sizeof(DTC_EventHeader) + sizeof(DTC_SubEventHeader);
     864            0 :                         std::vector<size_t> wordsToCheck{1, 2, 3, 7, 8};
     865            0 :                         for (auto& word : wordsToCheck)
     866              :                         {
     867            0 :                                 auto wordPtr = static_cast<uint16_t*>(readPtr) + (word - 1);
     868            0 :                                 TLOG(TLVL_TRACE + 1) << word << (word == 1 ? "st" : word == 2 ? "nd"
     869            0 :                                                                                                                                 : word == 3   ? "rd"
     870            0 :                                                                                                                                                           : "th")
     871            0 :                                                                          << " word of buffer: " << *wordPtr;
     872            0 :                                 if (*wordPtr == 0xcafe || *wordPtr == 0xdead)
     873              :                                 {
     874            0 :                                         TLOG(TLVL_WARNING) << "Buffer Timeout detected! " << word << (word == 1 ? "st" : word == 2 ? "nd"
     875            0 :                                                                                                                                                                                                  : word == 3   ? "rd"
     876            0 :                                                                                                                                                                                                                            : "th")
     877            0 :                                                                            << " word of buffer is 0x" << std::hex << *wordPtr;
     878            0 :                                         DTCLib::Utilities::PrintBuffer(readPtr, 16, 0, TLVL_TRACE + 3);
     879            0 :                                         timeout = true;
     880            0 :                                         break;
     881              :                                 }
     882              :                         }
     883            0 :                 }
     884              :         }
     885            0 :         return buffer;
     886              : }
        

Generated by: LCOV version 2.0-1