150 auto rdhPrevious = rdh;
151 bool firstRdh =
true;
152 uint32_t totalDataInputSize = 0;
153 mTotalHBFPayLoad = 0;
154 if (o2::raw::RDHUtils::getStop(rdh)) {
155 if (mMaxErrsPrinted > 0) {
156 LOGP(error,
"First RDH for given HBF for FEE ID {:#04x} has stop bit set", o2::raw::RDHUtils::getFEEID(rdh));
163 while (!o2::raw::RDHUtils::getStop(rdh)) {
165 LOG(info) <<
"Current RDH is as follows:";
168 }
catch (std::runtime_error& e) {
169 LOG(error) << e.what();
171 LOGP(
debug,
"mDataBufferSize {}, mDataBufferPtr {}, mCurrRdhPtr {}, totalDataInputSize {}. Already read: {}. Current payload {}", mDataBufferSize, fmt::ptr(mDataBufferPtr), fmt::ptr(mCurrRdhPtr), totalDataInputSize, mCurrRdhPtr - mDataBufferPtr, o2::raw::RDHUtils::getMemorySize(rdh));
176 if (!firstRdh && !
compareRDH(rdhPrevious, rdh)) {
182 auto headerSize = o2::raw::RDHUtils::getHeaderSize(rdh);
183 auto memorySize = o2::raw::RDHUtils::getMemorySize(rdh);
184 auto offsetToNext = o2::raw::RDHUtils::getOffsetToNext(rdh);
185 auto rdhpayload = memorySize - headerSize;
186 mFEEID.
word = o2::raw::RDHUtils::getFEEID(rdh);
187 mCRUEndpoint = o2::raw::RDHUtils::getEndPointID(rdh);
188 mCRUID = o2::raw::RDHUtils::getCRUID(rdh);
189 mIR = o2::raw::RDHUtils::getTriggerIR(rdh);
191 if (totalDataInputSize + memorySize >= mDataBufferSize) {
193 if (mMaxErrsPrinted > 0) {
194 LOGP(error,
"RDH memory size of {} + already read data size {} = {} >= {} (total available buffer size) from CRU with FEE ID {:#04x}",
195 memorySize, totalDataInputSize, memorySize + totalDataInputSize, mDataBufferSize, mFEEID.
word);
203 std::memcpy((
char*)&mHBFPayload[0] + mTotalHBFPayLoad, ((
char*)rdh) + headerSize, rdhpayload);
205 mTotalHBFPayLoad += rdhpayload;
206 totalDataInputSize += offsetToNext;
208 mCurrRdhPtr += offsetToNext;
212 mCurrRdhPtr += o2::raw::RDHUtils::getOffsetToNext(rdh);
215 LOG(info) <<
"Current RDH is as follows (should have STOP bit set):";
218 }
catch (std::runtime_error& e) {
219 LOG(error) << e.what();
226 mPreviousHalfCRUHeaderSet =
false;
227 while (mHBFoffset32 < (mTotalHBFPayLoad / 4)) {
229 LOGP(info,
"Current half-CRU iteration {}, current offset in the HBF payload {}, total payload in number of 32-bit words {}", iteration, mHBFoffset32, mTotalHBFPayLoad / 4);
238 return totalDataInputSize;
245 mDigitHCHeader.
word = mHBFPayload[mHBFoffset32++];
251 if (mDigitHCHeader.
major == 0 && mDigitHCHeader.
minor == 0 && mDigitHCHeader.
numberHCW == 0) {
252 mDigitHCHeader.
major = mHalfChamberMajor;
253 mDigitHCHeader.
minor = 42;
254 mDigitHCHeader.
numberHCW = mHalfChamberWords;
255 if (mHalfChamberWords == 0 || mHalfChamberMajor == 0) {
256 if (mMaxWarnPrinted > 0) {
257 LOG(alarm) <<
"DigitHCHeader is corrupted and using a hack as workaround is not configured";
266 if (hcid != halfChamberIdHeader) {
268 if (mMaxWarnPrinted > 0) {
269 LOGF(warning,
"HCID mismatch in DigitHCHeader detected for ref HCID %i. DigitHCHeader says HCID is %i", hcid, halfChamberIdHeader);
275 int additionalHeaderWords = mDigitHCHeader.
numberHCW;
276 if (additionalHeaderWords >= 3) {
278 if (mMaxWarnPrinted > 0) {
279 LOGF(warn,
"Found too many additional words (%i) in DigitHCHeader 0x%08x", additionalHeaderWords, mDigitHCHeader.
word);
284 std::bitset<3> headersfound;
285 std::array<uint32_t, 3> headers{0};
287 for (
int headerwordcount = 0; headerwordcount < additionalHeaderWords; ++headerwordcount) {
288 headers[headerwordcount] = mHBFPayload[mHBFoffset32++];
292 if (headersfound.test(0)) {
295 LOGF(warn,
"We have more than one DigitHCHeader of type 1. Current word in hex %08x", headers[headerwordcount]);
302 header1.
word = headers[headerwordcount];
308 LOGF(warn,
"According to Digit HC Header 1 there are %i time bins configured", (
int)header1.
numtimebins);
318 if (headersfound.test(1)) {
321 LOGF(warn,
"We have more than one DigitHCHeader of type 2. Current word in hex %08x", headers[headerwordcount]);
335 if (headersfound.test(2)) {
338 LOG(info) <<
"We have a >1 Digit HC Header 2 : " << std::hex <<
" raw: 0x" << headers[headerwordcount];
345 header3.
word = headers[headerwordcount];
347 if (mHaveSeenDigitHCHeader3) {
348 if (header3.
svnver != mPreviousDigitHCHeadersvnver || header3.
svnrver != mPreviousDigitHCHeadersvnrver) {
350 LOG(warning) <<
"Conflicting SVN in DigitHCHeader3";
357 mPreviousDigitHCHeadersvnver = header3.
svnver;
358 mPreviousDigitHCHeadersvnrver = header3.
svnrver;
359 mHaveSeenDigitHCHeader3 =
true;
383 LOG(info) <<
"blank rdh payload data at " << mHBFoffset32 <<
": 0x" << std::hex << mHBFPayload[mHBFoffset32] <<
" and 0x" << mHBFPayload[mHBFoffset32 + 1];
386 while (mHBFPayload[mHBFoffset32] ==
CRUPADDING32 && loopcount < 8) {
394 auto crustart = std::chrono::high_resolution_clock::now();
396 memcpy(&mCurrentHalfCRUHeader, &(mHBFPayload[mHBFoffset32]),
sizeof(
HalfCRUHeader));
404 mWordsRejected += (mTotalHBFPayLoad / 4) - mHBFoffset32 +
sizeof(
HalfCRUHeader) / 4;
410 uint32_t totalHalfCRUDataLength256 = std::accumulate(mCurrentHalfCRULinkLengths.begin(),
411 mCurrentHalfCRULinkLengths.end(),
413 uint32_t totalHalfCRUDataLength32 = totalHalfCRUDataLength256 * 8;
417 mWordsRejected += totalHalfCRUDataLength32;
418 mHBFoffset32 += totalHalfCRUDataLength32;
421 if (mCRUEndpoint != mCurrentHalfCRUHeader.
EndPoint) {
422 if (mMaxWarnPrinted > 0) {
423 LOGF(warn,
"End point mismatch detected. HalfCRUHeader says %i, RDH says %i", mCurrentHalfCRUHeader.
EndPoint, mCRUEndpoint);
427 mHBFoffset32 += totalHalfCRUDataLength32;
428 mWordsRejected += totalHalfCRUDataLength32;
432 if (mPreviousHalfCRUHeaderSet) {
436 if (mMaxWarnPrinted > 0) {
437 LOGF(warn,
"For current half-CRU index %i we have end point %i, while the previous end point was %i", iteration, mCurrentHalfCRUHeader.
EndPoint, mPreviousHalfCRUHeader.
EndPoint);
441 mWordsRejected += totalHalfCRUDataLength32;
442 mHBFoffset32 += totalHalfCRUDataLength32;
445 if (mCurrentHalfCRUHeader.
StopBit != mPreviousHalfCRUHeader.
StopBit) {
446 if (mMaxWarnPrinted > 0) {
447 LOGF(warn,
"For current half-CRU index %i we have stop bit %i, while the previous stop bit was %i", iteration, mCurrentHalfCRUHeader.
StopBit, mPreviousHalfCRUHeader.
StopBit);
451 mWordsRejected += totalHalfCRUDataLength32;
452 mHBFoffset32 += totalHalfCRUDataLength32;
456 mPreviousHalfCRUHeader = mCurrentHalfCRUHeader;
457 mPreviousHalfCRUHeaderSet =
true;
460 if (totalHalfCRUDataLength32 > (mTotalHBFPayLoad / 4) - mHBFoffset32) {
461 if (mMaxWarnPrinted > 0) {
462 LOGP(warn,
"HalfCRU header says it contains more data ({} 32-bit words) than is remaining in the payload ({} 32-bit words)", totalHalfCRUDataLength32, ((mTotalHBFPayLoad / 4) - mHBFoffset32));
466 mWordsRejected += (mTotalHBFPayLoad / 4) - mHBFoffset32;
475 mHBFoffset32 += totalHalfCRUDataLength32;
476 mWordsRejected += totalHalfCRUDataLength32;
489 uint32_t linksizeAccum32 = 0;
490 auto hbfOffsetTmp = mHBFoffset32;
491 for (
int currentlinkindex = 0; currentlinkindex <
NLINKSPERHALFCRU; currentlinkindex++) {
494 int halfCruIdx = cruIdx * 2 + mFEEID.
endpoint;
496 int halfChamberId = mLinkMap->
getHCID(linkIdxGlobal);
499 mEventRecords.
incLinkErrorFlags(halfChamberId, mCurrentHalfCRULinkErrorFlags[currentlinkindex]);
500 mEventRecords.
incLinkWords(halfChamberId, mCurrentHalfCRULinkLengths[currentlinkindex]);
501 uint32_t currentlinksize32 = mCurrentHalfCRULinkLengths[currentlinkindex] * 8;
502 uint32_t endOfCurrentLink = mHBFoffset32 + currentlinksize32;
506 linksizeAccum32 += currentlinksize32;
507 if (currentlinksize32 == 0) {
511 if (currentlinksize32 > 0) {
512 LOGF(info,
"Half-CRU link %i raw dump before parsing starts:", currentlinkindex);
513 for (uint32_t dumpoffset = mHBFoffset32; dumpoffset < mHBFoffset32 + currentlinksize32; dumpoffset += 8) {
514 LOGF(info,
"0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", mHBFPayload[dumpoffset], mHBFPayload[dumpoffset + 1], mHBFPayload[dumpoffset + 2], mHBFPayload[dumpoffset + 3], mHBFPayload[dumpoffset + 4], mHBFPayload[dumpoffset + 5], mHBFPayload[dumpoffset + 6], mHBFPayload[dumpoffset + 7]);
517 LOGF(info,
"Half-CRU link %i has zero link size", currentlinkindex);
520 if (currentlinksize32 > 0) {
521 auto trackletparsingstart = std::chrono::high_resolution_clock::now();
523 LOGF(info,
"Tracklet parser starting at offset %u and processing up to %u words", mHBFoffset32, currentlinksize32);
525 int trackletWordsRejected = 0;
526 int trackletWordsReadOK = 0;
527 int numberOfTrackletsFound = 0;
528 int trackletWordsRead =
parseTrackletLinkData(currentlinksize32, halfChamberId, trackletWordsRejected, trackletWordsReadOK, numberOfTrackletsFound);
529 std::chrono::duration<float, std::micro> trackletparsingtime = std::chrono::high_resolution_clock::now() - trackletparsingstart;
531 LOGP(info,
"Could read {} 32-bit words w/o errors, found {} tracklets, rejected {} 32-bit words for {}. Parsing OK? {}", trackletWordsReadOK, numberOfTrackletsFound, trackletWordsRejected,
HelperMethods::getSectorStackLayerSide(halfChamberId), (trackletWordsRead != -1 && trackletWordsRejected == 0));
533 if (trackletWordsRead == -1) {
535 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
539 if (trackletWordsRejected > 0) {
542 mHBFoffset32 += trackletWordsRead;
544 endOfCurrentLink - mHBFoffset32 >= 8) {
545 if (mMaxWarnPrinted > 0) {
546 LOGF(warn,
"After successfully parsing the tracklet data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
554 LOGF(
debug,
"Read %i tracklet words and rejected %i words", trackletWordsRead, trackletWordsRejected);
556 mTrackletWordsRejected += trackletWordsRejected;
557 mTrackletWordsRead += trackletWordsRead;
565 if (mHBFoffset32 != endOfCurrentLink &&
570 uint32_t offsetBeforeDigitParsing = mHBFoffset32;
573 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
576 if (mHBFoffset32 - offsetBeforeDigitParsing != 1U + mDigitHCHeader.
numberHCW) {
577 if (mMaxErrsPrinted > 0) {
578 LOGF(error,
"Did not read as many digit headers (%i) as expected (%i)",
579 mHBFoffset32 - offsetBeforeDigitParsing, mDigitHCHeader.
numberHCW + 1);
582 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
588 if (mDigitHCHeader.
major == 0x47) {
591 mHBFoffset32 = hbfOffsetTmp + currentlinksize32;
592 mDigitWordsRejected += hbfOffsetTmp + currentlinksize32;
593 LOG(info) <<
"Configuration event ";
595 auto digitsparsingstart = std::chrono::high_resolution_clock::now();
596 int digitWordsRejected = 0;
597 int digitWordsRead =
parseDigitLinkData(endOfCurrentLink - mHBFoffset32, halfChamberId, digitWordsRejected);
598 std::chrono::duration<float, std::micro> digitsparsingtime = std::chrono::high_resolution_clock::now() - digitsparsingstart;
599 if (digitWordsRead == -1) {
601 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
604 mHBFoffset32 += digitWordsRead;
605 if (endOfCurrentLink - mHBFoffset32 >= 8) {
608 if (mMaxWarnPrinted > 0) {
609 LOGF(warn,
"After successfully parsing the digit data for link %i there are %u words remaining which did not get parsed", currentlinkindex, endOfCurrentLink - mHBFoffset32);
615 if (digitWordsRejected > 0) {
623 LOGF(info,
"Read %i digit words and rejected %i words", digitWordsRead, digitWordsRejected);
625 mDigitWordsRead += digitWordsRead;
626 mDigitWordsRejected += digitWordsRejected;
638 if (mHBFoffset32 != hbfOffsetTmp + linksizeAccum32) {
640 LOGF(
debug,
"After processing link %i the payload offset of %u is not the expected %u + %u", currentlinkindex, mHBFoffset32, hbfOffsetTmp, linksizeAccum32);
641 mHBFoffset32 = hbfOffsetTmp + linksizeAccum32;
644 if (mHBFoffset32 != hbfOffsetTmp + totalHalfCRUDataLength32) {
645 LOGF(
debug,
"After processing half-CRU data the offset (%u) is not pointing to the expected position (%u + %u = %u)", mHBFoffset32, hbfOffsetTmp, totalHalfCRUDataLength32, totalHalfCRUDataLength32 + hbfOffsetTmp);
646 mHBFoffset32 = hbfOffsetTmp + totalHalfCRUDataLength32;
653 std::chrono::duration<float, std::micro> cruparsingtime = std::chrono::high_resolution_clock::now() - crustart;