Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions otsdaq-mu2e/CFOandDTCCore/CFOandDTCCoreVInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class CFOandDTCCoreVInterface : public FEVInterface
FPGAClock_; //period of FPGA clock in ns (as of Feb 2026, was 25ns)

public:
void SoftReset(__ARGS__);
void HardReset(__ARGS__);
virtual void SoftReset(__ARGS__);
void HardReset(__ARGS__);

void GetFirmwareVersion(__ARGS__);
void ResetPCIe(__ARGS__);
Expand Down
8 changes: 7 additions & 1 deletion otsdaq-mu2e/FEInterfaces/DTCFrontEndInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,22 @@ 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__);

void DTCInstantiate(__ARGS__);
void ResetDTCLinks(__ARGS__);
void EnableDTCLink(__ARGS__);

void SoftReset(__ARGS__) override;

void ResetPCIe(__ARGS__);
void ResetCFOLinkRx(__ARGS__);
void ResetCFOLinkTx(__ARGS__);
Expand All @@ -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,
Expand Down
150 changes: 144 additions & 6 deletions otsdaq-mu2e/FEInterfaces/DTCFrontEndInterfaceImpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<FEVInterface::frontEndMacroFunction_t>(
&DTCFrontEndInterface::GetRTFInterfaceStatus),
std::vector<std::string>{},
std::vector<std::string>{"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-"
Expand Down Expand Up @@ -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<std::string>{"Result"},
1, // requiredUserPermissions
Expand Down Expand Up @@ -4766,6 +4779,68 @@ 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 = 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();
uint32_t parityMismatch = (cdcDiag >> 16) & 0xFFFF;
uint32_t batchSlip = cdcDiag & 0xFFFF;

o << "=== CFO/RTF Settings & Status ==="
<< "\n";
o << " CFO Emulation Mode: " << (cfoEmMode ? "ON" : "OFF")
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";
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__)
{
Expand All @@ -4775,10 +4850,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<uint32_t(DTCLib::DTC_Link_ID)> readFn) {
Expand Down Expand Up @@ -4854,6 +4928,36 @@ 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__)
// {
Expand Down Expand Up @@ -5066,6 +5170,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__)
{
Expand Down Expand Up @@ -5168,7 +5283,9 @@ 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()

//========================================================================
Expand All @@ -5177,7 +5294,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);
Expand Down Expand Up @@ -5252,6 +5370,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);
Comment thread
rrivera747 marked this conversation as resolved.
outSs << "Set IDELAY Tap Value = " << idelayTapValue << " and loaded\n";
}

outSs << getDTC()->FormatDTCControl() << __E__ << getDTC()->FormatCFOLinkError()
<< __E__;
__FE_COUT_INFO__ << outSs.str();
Expand Down
Loading