From 3d8b4c72836d1705dcb6de5e02bff8f2aa176741 Mon Sep 17 00:00:00 2001 From: RYAN RIVERA Date: Wed, 8 Jul 2026 14:20:12 -0500 Subject: [PATCH 1/4] RTF sync status and control (in DTC) improvements --- .../CFOandDTCCore/CFOandDTCCoreVInterface.h | 2 +- .../FEInterfaces/DTCFrontEndInterface.h | 8 +- .../FEInterfaces/DTCFrontEndInterfaceImpl.cc | 138 +++++++++++++++++- 3 files changed, 140 insertions(+), 8 deletions(-) diff --git a/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h b/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h index ec50c251..4f171dd2 100644 --- a/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h +++ b/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h @@ -88,7 +88,7 @@ class CFOandDTCCoreVInterface : public FEVInterface FPGAClock_; //period of FPGA clock in ns (as of Feb 2026, was 25ns) public: - void SoftReset(__ARGS__); + virtual void SoftReset(__ARGS__); void HardReset(__ARGS__); void GetFirmwareVersion(__ARGS__); diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterface.h b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterface.h index 3573ceb9..8468dbf1 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterface.h +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterface.h @@ -220,10 +220,13 @@ class DTCFrontEndInterface : public CFOandDTCCoreVInterface void configureHardwareDevMode(__ARGS__); void ConfigureForTimingChain(__ARGS__); + std::string getCFORTFSettingsStatusAndErrors(); + void DTCCounters(__ARGS__); void readRxDiagFIFO(__ARGS__); void readTxDiagFIFO(__ARGS__); void GetLinkErrors(__ARGS__); + void GetRTFInterfaceStatus(__ARGS__); void ROCResetLink(__ARGS__); void HeaderFormatTest(__ARGS__); @@ -231,6 +234,8 @@ class DTCFrontEndInterface : public CFOandDTCCoreVInterface void ResetDTCLinks(__ARGS__); void EnableDTCLink(__ARGS__); + void SoftReset(__ARGS__) override; + void ResetPCIe(__ARGS__); void ResetCFOLinkRx(__ARGS__); void ResetCFOLinkTx(__ARGS__); @@ -250,7 +255,8 @@ class DTCFrontEndInterface : public CFOandDTCCoreVInterface bool alsoSetupJA, bool cfoRxTxEnable, bool enableAutogenDRP, - int permanentOffset = 0); + int permanentOffset = 0, + int idelayTapValue = -1); void SetCFOEmulatorOnOffSpillEmulation(__ARGS__); std::string SetCFOEmulatorOnOffSpillEmulation(bool enable, bool useDetachedBufferTest, diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc index de7297f6..41674282 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc @@ -588,6 +588,18 @@ void DTCFrontEndInterface::registerFEMacros(void) "Jitter Attenuator lost the RX Recovered clock and " "lost the RX External clock since last reset."); + registerFEMacroFunction( + "Get RTF Interface Status", + static_cast( + &DTCFrontEndInterface::GetRTFInterfaceStatus), + std::vector{}, + std::vector{"RTF Interface Status"}, + 1, // requiredUserPermissions + "*", + "Displays CFO interface status/errors, RTF timing settings, " + "and the RTF_HIST_IDELAY register (histogram bins, IDELAY tap " + "readback, saturation info)."); + std::stringstream feMacroTooltip; feMacroTooltip << "There are " << CONFIG_DTC_TIMING_CHAIN_STEPS << " steps. So choose 1 step at a time, 0-" @@ -776,6 +788,7 @@ void DTCFrontEndInterface::registerFEMacros(void) "Force External CFO Sample Clock Edge (0 for rising-edge, 1 for " "falling-edge, 2 for auto-find, Default := 0)", "Permanent Offset (-2 to 2, Default := 0)", + "IDELAY Tap Value (0-31, Default := -1 do nothing)", }, // namesOfInputArgs std::vector{"Result"}, 1, // requiredUserPermissions @@ -4766,6 +4779,59 @@ void DTCFrontEndInterface::configureHardwareDevMode(__ARGS__) configureHardwareDevMode(); } // end configureHardwareDevMode() +//======================================================================== +std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() +{ + auto dtc = getDTC(); + std::ostringstream o; + + auto jaSelect = dtc->ReadJitterAttenuatorSelect().to_ulong(); + std::string jaSource = jaSelect == 0 ? "Internal CFO" : (jaSelect == 1 ? "RJ45" : "Timing Card"); + int edgeMode = dtc->ReadExternalCFOSampleEdgeMode(std::nullopt); + bool cfoEmMode = dtc->ReadCFOEmulationMode(); + bool cfoCDRLock = dtc->ReadSERDESRXCDRLock(DTCLib::DTC_Link_CFO); + + uint32_t cfoErr; + getDevice()->read_register(0x9398, 100, &cfoErr); + int measuredPos = (cfoErr >> 16) & 7; + int impliedPos = 2 - measuredPos; + + uint32_t cdcDiag = dtc->ReadCFOCDCDiag(); + uint32_t parityMismatch = (cdcDiag >> 16) & 0xFFFF; + uint32_t batchSlip = cdcDiag & 0xFFFF; + + o << "=== CFO/RTF Settings & Status ===" << "\n"; + o << " CFO Emulation Mode: " << (cfoEmMode ? "ON" : "OFF") + << " JA Source: " << jaSource << "\n"; + o << " CFO-RTF Edge Select: " << ((edgeMode & 1) ? "posedge" : "negedge") + << " CFO CDR Lock: " << (cfoCDRLock ? "LOCKED" : "UNLOCKED") << "\n"; + o << " CFO Marker Pos: " << measuredPos << " ==> " << impliedPos + << " Perm Offset: " << dtc->ReadCFOSamplePermanentOffset(cfoErr) << "\n"; + o << " CFO Rx Clock Markers: " << dtc->ReadCFOTXClockMarkerCountLink6() << "\n"; + + o << "\n=== CFO Interface Errors ===" << "\n"; + o << " ErrFlag RTFPhase RTFMarker TxMarkers Rx-to-Tx | CDR JA JA-Rec JA-Ext\n"; + o << " Sticky: " + << "[" << (((cfoErr >> 11) & 1) ? "x" : " ") << "] " + << "[" << (((cfoErr >> 12) & 1) ? "x" : " ") << "] " + << "[" << (((cfoErr >> 9) & 1) ? "x" : " ") << ":" << (((cfoErr >> 10) & 1) ? "x" : " ") << "] " + << "[" << (((cfoErr >> 13) & 1) ? "x" : " ") << "] "; + o << "| " + << dtc->ReadRXCDRUnlockCount(DTCLib::DTC_Link_CFO) << " " + << dtc->ReadJitterAttenuatorUnlockCount() << " " + << dtc->ReadJitterAttenuatorRecoveredClockLOSCount() << " " + << dtc->ReadJitterAttenuatorExternalClockLOSCount() << "\n"; + + o << " EvtStart 40MHz Parity BatchSlip\n"; + o << " Count: " + << dtc->ReadRXCFOLinkEventStartCharacterErrorCount() << " " + << dtc->ReadRXCFOLink40MHzCharacterErrorCount() << " " + << parityMismatch << " " + << batchSlip << "\n"; + + return o.str(); +} //end getCFORTFSettingsStatusAndErrors() + //======================================================================== void DTCFrontEndInterface::DTCCounters(__ARGS__) { @@ -4775,10 +4841,9 @@ void DTCFrontEndInterface::DTCCounters(__ARGS__) protocol << getDTC()->FormattedRegDump( 130, - {[dtc] { return dtc->FormatCFOTXClockMarkerCountLink6(); }, - [dtc] { return dtc->FormatTXEventWindowMarkerCountLink(DTCLib::DTC_Link_CFO); }, - [dtc] { return dtc->FormatTXHeartbeatPacketCountLink(DTCLib::DTC_Link_CFO); }, - [dtc] { return dtc->FormatCFOLinkError(); }}); + {[dtc] { return dtc->FormatTXEventWindowMarkerCountLink(DTCLib::DTC_Link_CFO); }, + [dtc] { return dtc->FormatTXHeartbeatPacketCountLink(DTCLib::DTC_Link_CFO); }}); + protocol << "\n" << getCFORTFSettingsStatusAndErrors(); auto csvLinkCounts = [dtc](const std::string& label, std::function readFn) { @@ -4854,6 +4919,34 @@ void DTCFrontEndInterface::GetLinkErrors(__ARGS__) getDTC()->FormattedRegDump(0, getDTC()->formattedSERDESErrorFunctions_)); } //end GetLinkErrors() +//======================================================================== +void DTCFrontEndInterface::GetRTFInterfaceStatus(__ARGS__) +{ + std::ostringstream outss; + + outss << getCFORTFSettingsStatusAndErrors(); + + uint32_t rtfHist = getDTC()->ReadRTFHistIdelay(); + uint32_t idelayTap = (rtfHist >> 27) & 0x1F; + bool idelayRdy = (rtfHist >> 26) & 1; + bool saturated = (rtfHist >> 10) & 1; + uint32_t satBin = (rtfHist >> 7) & 0x7; + + outss << "\n=== RTF Histogram & IDELAY ===" << "\n"; + outss << " IDELAY Tap: " << idelayTap + << " Ready: " << (idelayRdy ? "YES" : "NO") + << " Saturated: " << (saturated ? "YES (bin " + std::to_string(satBin) + ")" : "NO") << "\n"; + outss << " Bins [0-4]: "; + for(int bin = 0; bin < 5; ++bin) + { + if(bin) outss << ", "; + outss << ((rtfHist >> (11 + bin * 3)) & 0x7); + } + outss << "\n"; + + __SET_ARG_OUT__("RTF Interface Status", "\n" + outss.str()); +} //end GetRTFInterfaceStatus() + // //======================================================================== // void DTCFrontEndInterface::ROCDestroy(__ARGS__) // { @@ -5066,6 +5159,17 @@ void DTCFrontEndInterface::ConfigureForTimingChain(__ARGS__) } //end ConfigureForTimingChain() +//======================================================================== +void DTCFrontEndInterface::SoftReset(__ARGS__) +{ + CFOandDTCCoreVInterface::SoftReset(feMacroStruct, argsIn, argsOut); + + getDTC()->ClearRXCDRUnlockCount(DTCLib::DTC_Link_CFO); + getDTC()->ClearJitterAttenuatorUnlockCount(); + getDTC()->ClearJitterAttenuatorRecoveredClockLOSCount(); + getDTC()->ClearJitterAttenuatorExternalClockLOSCount(); +} //end SoftReset() + //======================================================================== void DTCFrontEndInterface::ResetCFOLinkRx(__ARGS__) { @@ -5168,7 +5272,8 @@ void DTCFrontEndInterface::SetupCFOInterface(__ARGS__) "Enable Auto-generation of Data Request Packets (Default := false)", bool, false), - __GET_ARG_IN__("Permanent Offset (-2 to 2, Default := 0)", int, 0))); + __GET_ARG_IN__("Permanent Offset (-2 to 2, Default := 0)", int, 0), + __GET_ARG_IN__("IDELAY Tap Value (0-31, Default := -1 do nothing)", int, -1))); } //end SetupCFOInterface() //======================================================================== @@ -5177,7 +5282,8 @@ std::string DTCFrontEndInterface::SetupCFOInterface(int forceCFOedge, bool alsoSetupJA, bool cfoRxTxEnable, bool enableAutogenDRP, - int permanentOffset /* = 0 */) + int permanentOffset /* = 0 */, + int idelayTapValue /* = -1 */) { std::stringstream outSs; __FE_COUTV__(forceCFOedge); @@ -5252,6 +5358,26 @@ std::string DTCFrontEndInterface::SetupCFOInterface(int forceCFOedge, __FE_COUTV__(permanentOffset); getDTC()->SetCFOSamplePermanentOffset(permanentOffset); + __FE_COUTV__(idelayTapValue); + if(idelayTapValue >= 0) + { + if(idelayTapValue > 31) + { + __SS__ << "IDELAY Tap Value must be 0-31, received " << idelayTapValue; + __SS_THROW__; + } + uint32_t cfoErrReg; + getDevice()->read_register(0x9398, 100, &cfoErrReg); + cfoErrReg = (cfoErrReg & ~(0x1FF << 3)) | ((idelayTapValue & 0x1F) << 3); + getDevice()->write_register(0x9398, 100, cfoErrReg); + cfoErrReg |= (1 << 8); + getDevice()->write_register(0x9398, 100, cfoErrReg); + usleep(1000); + cfoErrReg &= ~(1 << 8); + getDevice()->write_register(0x9398, 100, cfoErrReg); + outSs << "Set IDELAY Tap Value = " << idelayTapValue << " and loaded\n"; + } + outSs << getDTC()->FormatDTCControl() << __E__ << getDTC()->FormatCFOLinkError() << __E__; __FE_COUT_INFO__ << outSs.str(); From 66eff0e6947209dd85b90a1539b27e97e7463161 Mon Sep 17 00:00:00 2001 From: RYAN RIVERA Date: Wed, 8 Jul 2026 14:20:31 -0500 Subject: [PATCH 2/4] Format fix --- .../CFOandDTCCore/CFOandDTCCoreVInterface.h | 2 +- .../FEInterfaces/DTCFrontEndInterfaceImpl.cc | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h b/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h index 4f171dd2..19352bdc 100644 --- a/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h +++ b/otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h @@ -89,7 +89,7 @@ class CFOandDTCCoreVInterface : public FEVInterface public: virtual void SoftReset(__ARGS__); - void HardReset(__ARGS__); + void HardReset(__ARGS__); void GetFirmwareVersion(__ARGS__); void ResetPCIe(__ARGS__); diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc index 41674282..f45a00f6 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc @@ -4782,13 +4782,14 @@ void DTCFrontEndInterface::configureHardwareDevMode(__ARGS__) //======================================================================== std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() { - auto dtc = getDTC(); + auto dtc = getDTC(); std::ostringstream o; - auto jaSelect = dtc->ReadJitterAttenuatorSelect().to_ulong(); - std::string jaSource = jaSelect == 0 ? "Internal CFO" : (jaSelect == 1 ? "RJ45" : "Timing Card"); - int edgeMode = dtc->ReadExternalCFOSampleEdgeMode(std::nullopt); - bool cfoEmMode = dtc->ReadCFOEmulationMode(); + auto jaSelect = dtc->ReadJitterAttenuatorSelect().to_ulong(); + std::string jaSource = + jaSelect == 0 ? "Internal CFO" : (jaSelect == 1 ? "RJ45" : "Timing Card"); + int edgeMode = dtc->ReadExternalCFOSampleEdgeMode(std::nullopt); + bool cfoEmMode = dtc->ReadCFOEmulationMode(); bool cfoCDRLock = dtc->ReadSERDESRXCDRLock(DTCLib::DTC_Link_CFO); uint32_t cfoErr; @@ -4796,11 +4797,12 @@ std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() int measuredPos = (cfoErr >> 16) & 7; int impliedPos = 2 - measuredPos; - uint32_t cdcDiag = dtc->ReadCFOCDCDiag(); + uint32_t cdcDiag = dtc->ReadCFOCDCDiag(); uint32_t parityMismatch = (cdcDiag >> 16) & 0xFFFF; uint32_t batchSlip = cdcDiag & 0xFFFF; - o << "=== CFO/RTF Settings & Status ===" << "\n"; + o << "=== CFO/RTF Settings & Status ===" + << "\n"; o << " CFO Emulation Mode: " << (cfoEmMode ? "ON" : "OFF") << " JA Source: " << jaSource << "\n"; o << " CFO-RTF Edge Select: " << ((edgeMode & 1) ? "posedge" : "negedge") @@ -4809,25 +4811,25 @@ std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() << " Perm Offset: " << dtc->ReadCFOSamplePermanentOffset(cfoErr) << "\n"; o << " CFO Rx Clock Markers: " << dtc->ReadCFOTXClockMarkerCountLink6() << "\n"; - o << "\n=== CFO Interface Errors ===" << "\n"; - o << " ErrFlag RTFPhase RTFMarker TxMarkers Rx-to-Tx | CDR JA JA-Rec JA-Ext\n"; + o << "\n=== CFO Interface Errors ===" + << "\n"; + o << " ErrFlag RTFPhase RTFMarker TxMarkers Rx-to-Tx | CDR JA JA-Rec " + "JA-Ext\n"; o << " Sticky: " << "[" << (((cfoErr >> 11) & 1) ? "x" : " ") << "] " << "[" << (((cfoErr >> 12) & 1) ? "x" : " ") << "] " - << "[" << (((cfoErr >> 9) & 1) ? "x" : " ") << ":" << (((cfoErr >> 10) & 1) ? "x" : " ") << "] " + << "[" << (((cfoErr >> 9) & 1) ? "x" : " ") << ":" + << (((cfoErr >> 10) & 1) ? "x" : " ") << "] " << "[" << (((cfoErr >> 13) & 1) ? "x" : " ") << "] "; - o << "| " - << dtc->ReadRXCDRUnlockCount(DTCLib::DTC_Link_CFO) << " " + o << "| " << dtc->ReadRXCDRUnlockCount(DTCLib::DTC_Link_CFO) << " " << dtc->ReadJitterAttenuatorUnlockCount() << " " << dtc->ReadJitterAttenuatorRecoveredClockLOSCount() << " " << dtc->ReadJitterAttenuatorExternalClockLOSCount() << "\n"; o << " EvtStart 40MHz Parity BatchSlip\n"; - o << " Count: " - << dtc->ReadRXCFOLinkEventStartCharacterErrorCount() << " " - << dtc->ReadRXCFOLink40MHzCharacterErrorCount() << " " - << parityMismatch << " " - << batchSlip << "\n"; + o << " Count: " << dtc->ReadRXCFOLinkEventStartCharacterErrorCount() << " " + << dtc->ReadRXCFOLink40MHzCharacterErrorCount() << " " << parityMismatch + << " " << batchSlip << "\n"; return o.str(); } //end getCFORTFSettingsStatusAndErrors() @@ -4926,20 +4928,22 @@ void DTCFrontEndInterface::GetRTFInterfaceStatus(__ARGS__) outss << getCFORTFSettingsStatusAndErrors(); - uint32_t rtfHist = getDTC()->ReadRTFHistIdelay(); + uint32_t rtfHist = getDTC()->ReadRTFHistIdelay(); uint32_t idelayTap = (rtfHist >> 27) & 0x1F; bool idelayRdy = (rtfHist >> 26) & 1; bool saturated = (rtfHist >> 10) & 1; uint32_t satBin = (rtfHist >> 7) & 0x7; - outss << "\n=== RTF Histogram & IDELAY ===" << "\n"; - outss << " IDELAY Tap: " << idelayTap - << " Ready: " << (idelayRdy ? "YES" : "NO") - << " Saturated: " << (saturated ? "YES (bin " + std::to_string(satBin) + ")" : "NO") << "\n"; + outss << "\n=== RTF Histogram & IDELAY ===" + << "\n"; + outss << " IDELAY Tap: " << idelayTap << " Ready: " << (idelayRdy ? "YES" : "NO") + << " Saturated: " + << (saturated ? "YES (bin " + std::to_string(satBin) + ")" : "NO") << "\n"; outss << " Bins [0-4]: "; for(int bin = 0; bin < 5; ++bin) { - if(bin) outss << ", "; + if(bin) + outss << ", "; outss << ((rtfHist >> (11 + bin * 3)) & 0x7); } outss << "\n"; @@ -5273,7 +5277,8 @@ void DTCFrontEndInterface::SetupCFOInterface(__ARGS__) bool, false), __GET_ARG_IN__("Permanent Offset (-2 to 2, Default := 0)", int, 0), - __GET_ARG_IN__("IDELAY Tap Value (0-31, Default := -1 do nothing)", int, -1))); + __GET_ARG_IN__( + "IDELAY Tap Value (0-31, Default := -1 do nothing)", int, -1))); } //end SetupCFOInterface() //======================================================================== @@ -5283,7 +5288,7 @@ std::string DTCFrontEndInterface::SetupCFOInterface(int forceCFOedge, bool cfoRxTxEnable, bool enableAutogenDRP, int permanentOffset /* = 0 */, - int idelayTapValue /* = -1 */) + int idelayTapValue /* = -1 */) { std::stringstream outSs; __FE_COUTV__(forceCFOedge); From c48d4ede125d110f60fd31aac4f12831392b24b3 Mon Sep 17 00:00:00 2001 From: rrivera747 <107584474+rrivera747@users.noreply.github.com> Date: Sat, 11 Jul 2026 15:48:12 -0500 Subject: [PATCH 3/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc index f45a00f6..22e32122 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc @@ -4804,8 +4804,11 @@ std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() o << "=== CFO/RTF Settings & Status ===" << "\n"; o << " CFO Emulation Mode: " << (cfoEmMode ? "ON" : "OFF") - << " JA Source: " << jaSource << "\n"; - o << " CFO-RTF Edge Select: " << ((edgeMode & 1) ? "posedge" : "negedge") + std::string edgeModeStr = (edgeMode == 0 ? "posedge" + : edgeMode == 1 ? "negedge" + : edgeMode == 2 ? "auto" + : ("unknown(" + std::to_string(edgeMode) + ")")); + o << " CFO-RTF Edge Select: " << edgeModeStr << " CFO CDR Lock: " << (cfoCDRLock ? "LOCKED" : "UNLOCKED") << "\n"; o << " CFO Marker Pos: " << measuredPos << " ==> " << impliedPos << " Perm Offset: " << dtc->ReadCFOSamplePermanentOffset(cfoErr) << "\n"; From a91a1fccd02a5ca1c6ec34ce53571ea286ab56fe Mon Sep 17 00:00:00 2001 From: rrivera747 <107584474+rrivera747@users.noreply.github.com> Date: Sat, 11 Jul 2026 15:49:17 -0500 Subject: [PATCH 4/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc index 22e32122..6157b721 100644 --- a/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc +++ b/otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc @@ -4792,9 +4792,13 @@ std::string DTCFrontEndInterface::getCFORTFSettingsStatusAndErrors() bool cfoEmMode = dtc->ReadCFOEmulationMode(); bool cfoCDRLock = dtc->ReadSERDESRXCDRLock(DTCLib::DTC_Link_CFO); - uint32_t cfoErr; - getDevice()->read_register(0x9398, 100, &cfoErr); - int measuredPos = (cfoErr >> 16) & 7; + uint32_t cfoErr = 0; + int errorCode = getDevice()->read_register(0x9398, 100, &cfoErr); + if(errorCode != 0) + { + __SS__ << "Error reading register 0x9398. Error code = " << errorCode; + __SS_THROW__; + } int impliedPos = 2 - measuredPos; uint32_t cdcDiag = dtc->ReadCFOCDCDiag();