LCOV - code coverage report
Current view: top level - mu2e-pcie-utils/cfoInterfaceLib - CFO_Registers.h (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 71 0
Test Date: 2026-10-29 01:38:59 Functions: 0.0 % 71 0

            Line data    Source code
       1              : #ifndef CFO_REGISTERS_H
       2              : #define CFO_REGISTERS_H
       3              : 
       4              : #include <ctime>       // time_t
       5              : #include <functional>  // std::bind, std::function, std::reference_wrapper
       6              : #include <optional>    // std::optional
       7              : #include <vector>      // std::vector
       8              : 
       9              : #include "dtcInterfaceLib/CFOandDTC_Registers.h"
      10              : 
      11              : using namespace DTCLib;
      12              : 
      13              : namespace CFOLib
      14              : {
      15              : 
      16              : /// <summary>
      17              : /// Register address map
      18              : /// </summary>
      19              : enum CFO_Register : uint16_t
      20              : {
      21              :         DTCLIB_COMMON_REGISTERS,  // Moved here all registers in common with DTC
      22              : 
      23              :         CFO_Register_SFPSERDESStatus   = 0x9140,
      24              :         CFO_Register_BeamOnTimerPreset = 0x9144,
      25              :         CFO_Register_EnableBeamOnMode  = 0x9148,
      26              :         CFO_Register_EnableBeamOffMode = 0x914C,
      27              :         // LEGACY (register 0x9154 repurposed as RunPlanSubrunEvtLimit):
      28              :         // CFO_Register_ClockMarkerIntervalCount  = 0x9154,
      29              :         CFO_Register_RunPlanSubrunEvtLimit     = 0x9154,
      30              :         CFO_Register_RunPlanSubrunPredOffset   = 0x9158,
      31              :         CFO_Register_SERDESOscillatorFrequency = 0x9160,
      32              :         CFO_Register_SERDESClock_IICBusControl = 0x9164,
      33              :         CFO_Register_TimestampPreset0          = 0x9180,
      34              :         CFO_Register_TimestampPreset1          = 0x9184,
      35              :         CFO_Register_LinuxTimestamp            = 0x9188,
      36              :         // 0x918C: deprecated NUMDTCs register, no longer used by firmware
      37              :         CFO_Register_FIFOFullErrorFlag0 = 0x9190,
      38              :         CFO_Register_ReceivePacketError = 0x919C,
      39              :         // CFO_Register_EventWindowEmulatorIntervalTime = 0x91A0, //register deleted in Firmware version: Nov/09/2023 11:00   raw-data: 0x23110911
      40              :         CFO_Register_EventWindowHoldoffTime         = 0x91A4,
      41              :         CFO_Register_EventWindowTimeoutError        = 0x91A8,
      42              :         CFO_Register_EventWindowTimeoutValue        = 0x91AC,
      43              :         CFO_Register_ReceiveRF0MarkerCount          = 0x9200,
      44              :         CFO_Register_TransmitHeartbeatPacketCount   = 0x9240,
      45              :         CFO_Register_TransmitEventWindowMarkerCount = 0x9260,
      46              :         // CFO_Register_ReceiveByteCountDataLink0     = 0x9200,
      47              :         // CFO_Register_ReceiveByteCountDataLink1     = 0x9204,
      48              :         // CFO_Register_ReceiveByteCountDataLink2     = 0x9208,
      49              :         // CFO_Register_ReceiveByteCountDataLink3     = 0x920C,
      50              :         // CFO_Register_ReceiveByteCountDataLink4     = 0x9210,
      51              :         // CFO_Register_ReceiveByteCountDataLink5     = 0x9214,
      52              :         // CFO_Register_ReceiveByteCountDataLink6     = 0x9218,
      53              :         // CFO_Register_ReceiveByteCountDataLink7     = 0x921C,
      54              :         // CFO_Register_ReceivePacketCountDataLink0   = 0x9220,
      55              :         // CFO_Register_ReceivePacketCountDataLink1   = 0x9224,
      56              :         // CFO_Register_ReceivePacketCountDataLink2   = 0x9228,
      57              :         // CFO_Register_ReceivePacketCountDataLink3   = 0x922C,
      58              :         // CFO_Register_ReceivePacketCountDataLink4   = 0x9230,
      59              :         // CFO_Register_ReceivePacketCountDataLink5   = 0x9234,
      60              :         // CFO_Register_ReceivePacketCountDataLink6   = 0x9238,
      61              :         // CFO_Register_ReceivePacketCountDataLink7   = 0x923C,
      62              :         // CFO_Register_TransmitByteCountDataLink0    = 0x9240,
      63              :         // CFO_Register_TransmitByteCountDataLink1    = 0x9244,
      64              :         // CFO_Register_TransmitByteCountDataLink2    = 0x9248,
      65              :         // CFO_Register_TransmitByteCountDataLink3    = 0x924C,
      66              :         // CFO_Register_TransmitByteCountDataLink4    = 0x9250,
      67              :         // CFO_Register_TransmitByteCountDataLink5    = 0x9254,
      68              :         // CFO_Register_TransmitByteCountDataLink6    = 0x9258,
      69              :         // CFO_Register_TransmitByteCountDataLink7    = 0x925C,
      70              :         // CFO_Register_TransmitPacketCountDataLink0  = 0x9260,
      71              :         // CFO_Register_TransmitPacketCountDataLink1  = 0x9264,
      72              :         // CFO_Register_TransmitPacketCountDataLink2  = 0x9268,
      73              :         // CFO_Register_TransmitPacketCountDataLink3  = 0x926C,
      74              :         // CFO_Register_TransmitPacketCountDataLink4  = 0x9270,
      75              :         // CFO_Register_TransmitPacketCountDataLink5  = 0x9274,
      76              :         // CFO_Register_TransmitPacketCountDataLink6  = 0x9278,
      77              :         // CFO_Register_TransmitPacketCountDataLink7  = 0x927C,
      78              :         CFO_Register_DDRMemoryDMAWriteStartAddress = 0x9300,
      79              :         CFO_Register_DDRMemoryDMAReadStartAddress  = 0x9304,
      80              :         CFO_Register_DDRMemoryDMAReadByteCount     = 0x9308,
      81              :         CFO_Register_RunPlanBeamOnBaseAddress      = 0x930C,
      82              :         CFO_Register_RunPlanBeamOffBaseAddress     = 0x9310,
      83              : 
      84              :         CFO_Register_RunPlan_Address    = 0x9314,
      85              :         CFO_Register_RunPlan_Data       = 0x9318,
      86              :         CFO_Register_RunPlan_EventMode0 = 0x931C,
      87              :         CFO_Register_RunPlan_EventMode1 = 0x9320,
      88              :         CFO_Register_RunPlan_EventTag0  = 0x9324,
      89              :         CFO_Register_RunPlan_EventTag1  = 0x9328,
      90              : 
      91              :         CFO_Register_SERDESPRBSControlLink0 = 0x9330,
      92              :         CFO_Register_SERDESPRBSControlLink1 = 0x9334,
      93              :         CFO_Register_SERDESPRBSControlLink2 = 0x9338,
      94              :         CFO_Register_SERDESPRBSControlLink3 = 0x933C,
      95              :         CFO_Register_SERDESPRBSControlLink4 = 0x9340,
      96              :         CFO_Register_SERDESPRBSControlLink5 = 0x9344,
      97              :         CFO_Register_SERDESPRBSControlLink6 = 0x9348,
      98              :         CFO_Register_SERDESPRBSControlLink7 = 0x934C,
      99              : 
     100              :         CFO_Register_CableDelayValue_offset = 0x9360,
     101              :         // CFO_Register_CableDelayValueROC1_offset = 0x9460,
     102              :         // CFO_Register_CableDelayValueROC2_offset = 0x9560,
     103              :         // CFO_Register_CableDelayValueROC3_offset = 0x9660,
     104              :         // CFO_Register_CableDelayValueROC4_offset = 0x9760,
     105              :         // CFO_Register_CableDelayValueROC5_offset = 0x9860,
     106              :         // CFO_Register_CableDelayValueLink0 = 0x9360,
     107              :         // CFO_Register_CableDelayValueLink1 = 0x9364,
     108              :         // CFO_Register_CableDelayValueLink2 = 0x9368,
     109              :         // CFO_Register_CableDelayValueLink3 = 0x936C,
     110              :         // CFO_Register_CableDelayValueLink4 = 0x9370,
     111              :         // CFO_Register_CableDelayValueLink5 = 0x9374,
     112              :         // CFO_Register_CableDelayValueLink6 = 0x9378,
     113              :         // CFO_Register_CableDelayValueLink7 = 0x937C,
     114              : 
     115              :         CFO_Register_CableDelayControlStatus = 0x9380,
     116              : 
     117              :         CFO_Register_FireflyCSRRegister = 0x93A0,
     118              : 
     119              :         CFO_Register_FPGAProgramData       = 0x9400,
     120              :         CFO_Register_FPGAPROMProgramStatus = 0x9404,
     121              :         CFO_Register_FPGACoreAccess        = 0x9408,
     122              :         CFO_Register_JitterAttenuatorCSR   = 0x9500,
     123              :         CFO_Register_Invalid,
     124              :         // };
     125              : };  // end CFO_Register enum
     126              : 
     127              : /// <summary>
     128              : /// The links of the CFO
     129              : /// </summary>
     130              : enum CFO_Link_ID : uint8_t
     131              : {
     132              :         CFO_Link_0 = 0,
     133              :         CFO_Link_1 = 1,
     134              :         CFO_Link_2 = 2,
     135              :         CFO_Link_3 = 3,
     136              :         CFO_Link_4 = 4,
     137              :         CFO_Link_5 = 5,
     138              :         CFO_Link_6 = 6,
     139              :         CFO_Link_7 = 7,
     140              :         CFO_Link_Unused,
     141              :         CFO_Link_ALL = 255
     142              : };
     143              : 
     144              : /// <summary>
     145              : /// Vector of the links, for iterating
     146              : /// </summary>
     147              : static const std::vector<CFO_Link_ID> CFO_Links{CFO_Link_0, CFO_Link_1, CFO_Link_2, CFO_Link_3, CFO_Link_4, CFO_Link_5, CFO_Link_6, CFO_Link_7};
     148              : 
     149              : /// <summary>
     150              : /// The CFO_Registers class represents the CFO Register space, and all the methods necessary to read and write those
     151              : /// registers. Each register has, at the very least, a read method, a write method, and a RegisterFormatter method
     152              : /// which formats the register value in a human-readable way.
     153              : /// </summary>
     154              : class CFO_Registers : public DTCLib::CFOandDTC_Registers
     155              : {
     156              :   public:
     157              :         /// <summary>
     158              :         /// Construct an instance of the CFO register map
     159              :         /// </summary>
     160              :         /// <param name="mode">Default: CFO_SimMode_Disabled; The simulation mode of the CFO</param>
     161              :         /// <param name="CFO">CFO/DTC card instance to use</param>
     162              :         /// <param name="skipInit">Default: false; Whether to skip initializing the CFO using the SimMode.
     163              :         /// Used to read state.</param> <param name="expectedDesignVersion">Expected CFO Firmware Design Version. If set, will
     164              :         /// throw an exception if the CFO firmware does not match (Default: "")</param>
     165              :         explicit CFO_Registers(DTC_SimMode mode, int cfo, std::string expectedDesignVersion = "", bool skipInit = false, const std::string& uid = "");
     166              :         /// <summary>
     167              :         /// CFO_Registers destructor
     168              :         /// </summary>
     169              :         virtual ~CFO_Registers();
     170              : 
     171              :         //
     172              :         // CFO Sim Mode Virtual Register
     173              :         //
     174              :         /// <summary>
     175              :         /// Get the current CFO_SimMode of this CFO_Registers object
     176              :         /// </summary>
     177              :         /// <returns></returns>
     178            0 :         DTC_SimMode GetSimMode() const { return simMode_; }
     179              : 
     180              :         /// <summary>
     181              :         /// Initialize the CFO in the given SimMode.
     182              :         /// </summary>
     183              :         /// <param name="expectedDesignVersion">Expected CFO Firmware Design Version. If set, will throw an exception if the
     184              :         /// CFO firmware does not match</param> <param name="mode">Mode to set</param> <param name="CFO">CFO/DTC card instance
     185              :         /// to use</param> <param name="skipInit">Whether to skip initializing the CFO using the SimMode. Used to read
     186              :         /// state.</param> <returns></returns>
     187              :         DTC_SimMode SetSimMode(std::string expectedDesignVersion, DTC_SimMode mode, int CFO, bool skipInit = false, const std::string& uid = "");
     188              : 
     189            0 :         virtual void ResetPCIe() override { throw std::runtime_error("CFO-TODO!"); };
     190            0 :         virtual void FlashLEDs() override { throw std::runtime_error("CFO-TODO!"); };
     191              : 
     192              :         // Design Status Register
     193              :         /// <summary>
     194              :         /// Determine if the DDR FIFO is empty
     195              :         /// </summary>
     196              :         /// <returns>True if the DDR FIFO Empty bit is set</returns>
     197              :         bool ReadDDRFIFOEmpty(std::optional<uint32_t> val = std::nullopt);
     198              :         /// <summary>
     199              :         /// Read the DDR Clock Calibration Done bit
     200              :         /// </summary>
     201              :         /// <returns>True if the DDR Clock Calibration Done bit is set</returns>
     202              :         bool ReadDDRClockCalibrationDone(std::optional<uint32_t> val = std::nullopt);
     203              :         /// <summary>
     204              :         /// Formats the register's current value for register dumps
     205              :         /// </summary>
     206              :         /// <returns>RegisterFormatter object containing register information</returns>
     207              :         RegisterFormatter FormatDesignStatus();
     208              : 
     209              :         // CFO Control Register
     210              :         // void ResetCFORunPlan();
     211              :         // bool ReadResetCFORunPlan(std::optional<uint32_t> val = std::nullopt);
     212              :         void              EnableLED7();
     213              :         void              DisableReadLED7();
     214              :         bool              ReadLED7State(std::optional<uint32_t> val = std::nullopt);
     215              :         void              EnableAcceleratorRF0();
     216              :         void              DisableAcceleratorRF0();
     217              :         bool              ReadAcceleratorRF0Enable(std::optional<uint32_t> val = std::nullopt);
     218              :         void              EnableEmbeddedClockMarker();
     219              :         void              DisableEmbeddedClockMarker();
     220              :         bool              ReadEmbeddedClockMarkerEnable(std::optional<uint32_t> val = std::nullopt);
     221              :         RegisterFormatter FormatCFOControl();
     222              : 
     223              :         // DMA Transfer Length Register
     224              :         /// <summary>
     225              :         /// Set the DMA buffer size which will automatically trigger a DMA
     226              :         /// </summary>
     227              :         /// <param name="length">Size, in bytes of buffer that will trigger a DMA</param>
     228              :         void SetTriggerDMATransferLength(uint16_t length);
     229              :         /// <summary>
     230              :         /// Read the DMA buffer size which will automatically trigger a DMA
     231              :         /// </summary>
     232              :         /// <returns>The DMA buffer size which will automatically trigger a DMA, in bytes</returns>
     233              :         uint16_t ReadTriggerDMATransferLength(std::optional<uint32_t> val = std::nullopt);
     234              :         /// <summary>
     235              :         /// Set the minimum DMA transfer size. Absolute minimum is 64 bytes.
     236              :         /// Buffers smaller than this size will be padded to the minimum.
     237              :         /// </summary>
     238              :         /// <param name="length">Size, in bytes, of the minimum DMA transfer buffer</param>
     239              :         void SetMinDMATransferLength(uint16_t length);
     240              :         /// <summary>
     241              :         /// Read the minimum DMA transfer size.
     242              :         /// </summary>
     243              :         /// <returns>The minimum DMA size, in bytes</returns>
     244              :         uint16_t ReadMinDMATransferLength(std::optional<uint32_t> val = std::nullopt);
     245              :         /// <summary>
     246              :         /// Formats the register's current value for register dumps
     247              :         /// </summary>
     248              :         /// <returns>RegisterFormatter object containing register information</returns>
     249              :         RegisterFormatter FormatDMATransferLength();
     250              : 
     251              :         // SERDES Loopback Enable Register
     252              :         /// <summary>
     253              :         /// Set the SERDES Loopback mode for the given Link
     254              :         /// </summary>
     255              :         /// <param name="link">Link to set for</param>
     256              :         /// <param name="mode">CFO_SERDESLoopbackMode to set</param>
     257              :         void SetSERDESLoopbackMode(const CFO_Link_ID& link, const DTC_SERDESLoopbackMode& mode);
     258              :         /// <summary>
     259              :         /// Read the SERDES Loopback mode for the given Link
     260              :         /// </summary>
     261              :         /// <param name="link">Link to read</param>
     262              :         /// <returns>CFO_SERDESLoopbackMode of the Link</returns>
     263              :         DTC_SERDESLoopbackMode ReadSERDESLoopback(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     264              :         /// <summary>
     265              :         /// Formats the register's current value for register dumps
     266              :         /// </summary>
     267              :         /// <returns>RegisterFormatter object containing register information</returns>
     268              :         RegisterFormatter FormatSERDESLoopbackEnable();
     269              : 
     270              :         // Clock Status Register
     271              :         /// <summary>
     272              :         /// Read the SERDES Oscillator IIC Error Bit
     273              :         /// </summary>
     274              :         /// <returns>True if the SERDES Oscillator IIC Error is set</returns>
     275              :         bool ReadSERDESOscillatorIICError(std::optional<uint32_t> val = std::nullopt);
     276              :         /// <summary>
     277              :         /// Read the SERDES Oscillator Initalization Complete flag
     278              :         /// </summary>
     279              :         /// <returns>Whether the SERDES Oscillator has completed initialization</returns>
     280              :         bool ReadSERDESOscillatorInitializationComplete(std::optional<uint32_t> val = std::nullopt);
     281              :         /// <summary>
     282              :         /// Wait for the SERDES Oscillator to initialize, up to max_wait seconds
     283              :         /// </summary>
     284              :         /// <param name="max_wait">Seconds to wait</param>
     285              :         /// <returns>Whether the SERDES OScillator Completed initialization in the timeout</returns>
     286              :         bool WaitForSERDESOscillatorInitializationComplete(double max_wait = 1.0);
     287              :         /// <summary>
     288              :         /// Read the Timing Clock PLL Locked bit
     289              :         /// </summary>
     290              :         /// <returns>The current value of the Timing Clock PLL Locked bit</returns>
     291              :         bool ReadTimingClockPLLLocked(std::optional<uint32_t> val = std::nullopt);
     292              :         /// <summary>
     293              :         /// Formats the register's current value for register dumps
     294              :         /// </summary>
     295              :         /// <returns>RegisterFormatter object containing register information</returns>
     296              :         RegisterFormatter FormatClockOscillatorStatus();
     297              : 
     298              :         // Link Enable Register
     299              :         /// <summary>
     300              :         /// Enable a SERDES Link
     301              :         /// </summary>
     302              :         /// <param name="link">Link to enable</param>
     303              :         /// <param name="mode">Link enable bits to set (Default: All)</param>
     304              :         void EnableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode = DTC_LinkEnableMode());
     305              : 
     306              :         /// <summary>
     307              :         /// Disable a SERDES Link
     308              :         /// The given mode bits will be UNSET
     309              :         /// </summary>
     310              :         /// <param name="link">Link to disable</param>
     311              :         /// <param name="mode">Link enable bits to unset (Default: All)</param>
     312              :         void DisableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode = DTC_LinkEnableMode());
     313              :         /// <summary>
     314              :         /// Read the Link Enable bits for a given SERDES Link
     315              :         /// </summary>
     316              :         /// <param name="link">Link to read</param>
     317              :         /// <returns>DTC_LinkEnableMode containing TX, RX, and CFO bits</returns>
     318              :         DTC_LinkEnableMode ReadLinkEnabled(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     319              :         /// <summary>
     320              :         /// Formats the register's current value for register dumps
     321              :         /// </summary>
     322              :         /// <returns>RegisterFormatter object containing register information</returns>
     323              :         RegisterFormatter FormatLinkEnable();
     324              : 
     325              :         // SERDES Reset Register
     326              :         /// <summary>
     327              :         /// Reset the SERDES
     328              :         /// Will poll the Reset SERDES Done flag until the SERDES reset is complete
     329              :         /// </summary>
     330              :         /// <param name="link">Link to reset</param>
     331              :         /// <param name="interval">Pollint interval, in microseconds</param>
     332              :         void ResetSERDES(const CFO_Link_ID& link, int interval = 100000);
     333              :         /// <summary>
     334              :         /// Reset all SERDES PLLs
     335              :         /// </summary>
     336              :         void ResetAllSERDESPlls();
     337              :         /// <summary>
     338              :         /// Reset all SERDES Tx
     339              :         /// </summary>
     340              :         void ResetAllSERDESTx();
     341              :         /// <summary>
     342              :         /// Read if a SERDES reset is currently in progress
     343              :         /// </summary>
     344              :         /// <param name="link">Link to read</param>
     345              :         /// <returns>True if a SERDES reset is in progress</returns>
     346              :         bool ReadResetSERDES(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     347              :         /// <summary>
     348              :         /// Formats the register's current value for register dumps
     349              :         /// </summary>
     350              :         /// <returns>RegisterFormatter object containing register information</returns>
     351              :         RegisterFormatter FormatSERDESReset();
     352              : 
     353              :         // SERDES RX Disparity Error Register
     354              :         /// <summary>
     355              :         /// Read the SERDES RX Dispatity Error bits
     356              :         /// </summary>
     357              :         /// <param name="link">Link to read</param>
     358              :         /// <returns>CFO_SERDESRXDisparityError object with error bits</returns>
     359              :         DTC_SERDESRXDisparityError ReadSERDESRXDisparityError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     360              :         /// <summary>
     361              :         /// Formats the register's current value for register dumps
     362              :         /// </summary>
     363              :         /// <returns>RegisterFormatter object containing register information</returns>
     364              :         RegisterFormatter FormatSERDESRXDisparityError();
     365              : 
     366              :         // SERDES Character Not In Table Error Register
     367              :         /// <summary>
     368              :         /// Read the SERDES Character Not In Table Error bits
     369              :         /// </summary>
     370              :         /// <param name="link">Link to read</param>
     371              :         /// <returns>CFO_CharacterNotInTableError object with error bits</returns>
     372              :         DTC_CharacterNotInTableError ReadSERDESRXCharacterNotInTableError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     373              :         /// <summary>
     374              :         /// Formats the register's current value for register dumps
     375              :         /// </summary>
     376              :         /// <returns>RegisterFormatter object containing register information</returns>
     377              :         RegisterFormatter FormatSERDESRXCharacterNotInTableError();
     378              : 
     379              :         // SERDES Unlock Error Register
     380              :         /// <summary>
     381              :         /// Read whether the SERDES Unlock Error bit is set
     382              :         /// </summary>
     383              :         /// <param name="link">Link to check</param>
     384              :         /// <returns>True if the SERDES Unlock Error bit is set on the given Link</returns>
     385              :         bool ReadSERDESUnlockError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     386              :         /// <summary>
     387              :         /// Formats the register's current value for register dumps
     388              :         /// </summary>
     389              :         /// <returns>RegisterFormatter object containing register information</returns>
     390              :         RegisterFormatter FormatSERDESUnlockError();
     391              : 
     392              :         // SERDES PLL Locked Register
     393              :         /// <summary>
     394              :         /// Read if the SERDES PLL is locked for the given SERDES Link
     395              :         /// </summary>
     396              :         /// <param name="link">Link to read</param>
     397              :         /// <returns>True if the PLL is locked, false otherwise</returns>
     398              :         bool ReadSERDESPLLLocked(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     399              :         /// <summary>
     400              :         /// Formats the register's current value for register dumps
     401              :         /// </summary>
     402              :         /// <returns>RegisterFormatter object containing register information</returns>
     403              :         RegisterFormatter FormatSERDESPLLLocked();
     404              : 
     405              :         // SERDES RX Status Register
     406              :         /// <summary>
     407              :         /// Read the SERDES RX Status for the given SERDES Link
     408              :         /// </summary>
     409              :         /// <param name="link">Link to read</param>
     410              :         /// <returns>CFO_RXStatus object</returns>
     411              :         DTC_RXStatus ReadSERDESRXStatus(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     412              :         /// <summary>
     413              :         /// Formats the register's current value for register dumps
     414              :         /// </summary>
     415              :         /// <returns>RegisterFormatter object containing register information</returns>
     416              :         RegisterFormatter FormatSERDESRXStatus();
     417              : 
     418              :         // SERDES Reset Done Register
     419              :         /// <summary>
     420              :         /// Read if the SERDES reset is complete on the given SERDES Link
     421              :         /// </summary>
     422              :         /// <param name="link">Link to read</param>
     423              :         /// <returns>True if the SERDES Reset is done, false otherwise</returns>
     424              :         bool ReadResetSERDESDone(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     425              :         /// <summary>
     426              :         /// Formats the register's current value for register dumps
     427              :         /// </summary>
     428              :         /// <returns>RegisterFormatter object containing register information</returns>
     429              :         RegisterFormatter FormatSERDESResetDone();
     430              : 
     431              :         // SERDES RX CDR Lock Register
     432              :         /// <summary>
     433              :         /// Read the SERDES CDR Lock bit for the given SERDES Link
     434              :         /// </summary>
     435              :         /// <param name="link">Link to read</param>
     436              :         /// <returns>True if the SERDES CDR Lock bit is set</returns>
     437              :         bool ReadSERDESRXCDRLock(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     438              :         /// <summary>
     439              :         /// Formats the register's current value for register dumps
     440              :         /// </summary>
     441              :         /// <returns>RegisterFormatter object containing register information</returns>
     442              :         RegisterFormatter FormatSERDESRXCDRLock();
     443              : 
     444              :         // Beam On Timer Preset Regsiter
     445              :         /// <summary>
     446              :         /// Set the maximum time a DMA buffer may be active before it is sent, in 4ns ticks.
     447              :         /// The default value is 0x800
     448              :         /// </summary>
     449              :         /// <param name="preset">Maximum active time for DMA buffers</param>
     450              :         void SetBeamOnTimerPreset(uint32_t preset);
     451              :         /// <summary>
     452              :         /// Read the maximum time a DMA buffer may be active before it is sent, in 4ns ticks.
     453              :         /// The default value is 0x800
     454              :         /// </summary>
     455              :         /// <returns>Maximum active time for DMA buffers</returns>
     456              :         uint32_t ReadBeamOnTimerPreset(std::optional<uint32_t> val = std::nullopt);
     457              :         /// <summary>
     458              :         /// Formats the register's current value for register dumps
     459              :         /// </summary>
     460              :         /// <returns>RegisterFormatter object containing register information</returns>
     461              :         RegisterFormatter FormatBeamOnTimerPreset();
     462              : 
     463              :         // Enable Beam On Mode Register
     464              :         /// <summary>
     465              :         /// Set the Beam On Mode Enable bit for the given link
     466              :         /// </summary>
     467              :         /// <param name="link">Link to enable</param>
     468              :         void EnableBeamOnMode(const CFO_Link_ID& link);
     469              :         /// <summary>
     470              :         /// Clear the Beam On Mode Enable bit for the given link
     471              :         /// </summary>
     472              :         /// <param name="link">Link to disable</param>
     473              :         void DisableBeamOnMode(const CFO_Link_ID& link);
     474              :         /// <summary>
     475              :         /// Read the global Beam On Mode Enable bit
     476              :         /// </summary>
     477              :         /// <param name="val">Optional register value to use instead of reading from hardware</param>
     478              :         /// <returns>Value of the Beam On Mode Enable bit</returns>
     479              :         bool ReadBeamOnMode(std::optional<uint32_t> val = std::nullopt);
     480              :         /// <summary>
     481              :         /// Formats the register's current value for register dumps
     482              :         /// </summary>
     483              :         /// <returns>RegisterFormatter object containing register information</returns>
     484              :         RegisterFormatter FormatBeamOnMode();
     485              : 
     486              :         // Enable Beam Off Mode Register
     487              :         /// <summary>
     488              :         /// Set the Beam Off Mode Enable bit for the given link
     489              :         /// </summary>
     490              :         /// <param name="link">Link to enable</param>
     491              :         void EnableBeamOffMode(const CFO_Link_ID& link);
     492              :         /// <summary>
     493              :         /// Clear the Beam Off Mode Enable bit for the given link
     494              :         /// </summary>
     495              :         /// <param name="link">Link to disable</param>
     496              :         void DisableBeamOffMode(const CFO_Link_ID& link);
     497              :         /// <summary>
     498              :         /// Read the global Beam Off Mode Enable bit
     499              :         /// </summary>
     500              :         /// <returns>Value of the global Beam Off Mode Enable bit</returns>
     501              :         bool ReadBeamOffMode(std::optional<uint32_t> val = std::nullopt);
     502              :         /// <summary>
     503              :         /// Formats the register's current value for register dumps
     504              :         /// </summary>
     505              :         /// <returns>RegisterFormatter object containing register information</returns>
     506              :         RegisterFormatter FormatBeamOffMode();
     507              : 
     508              :         // LEGACY: 40 MHz Clock Marker Interval Count Register (register 0x9154 repurposed as RunPlanSubrunEvtLimit)
     509              :         // /// <summary>
     510              :         // /// Set the Clock Marker Interval Count for synchronizing the 240 MHz and 40 MHz clocks
     511              :         // /// </summary>
     512              :         // /// <param name="data">Interval to set</param>
     513              :         // void SetClockMarkerIntervalCount(uint32_t data);
     514              :         // /// <summary>
     515              :         // /// Read the Clock Marker Interval Count used for synchronizing the 240 MHz and 40 MHz clocks
     516              :         // /// </summary>
     517              :         // /// <returns>The Clock Marker Interval Count used for synchronizing the 240 MHz and 40 MHz clocks</returns>
     518              :         // uint32_t ReadClockMarkerIntervalCount(std::optional<uint32_t> val = std::nullopt);
     519              :         // /// <summary>
     520              :         // /// Formats the register's current value for register dumps
     521              :         // /// </summary>
     522              :         // /// <returns>RegisterFormatter object containing register information</returns>
     523              :         // RegisterFormatter FormatClockMarkerIntervalCount();
     524              : 
     525              :         // SERDES Oscillator Registers
     526              :         /// <summary>
     527              :         /// Read the current SERDES Oscillator frequency, in Hz
     528              :         /// </summary>
     529              :         /// <returns>Current SERDES Oscillator frequency, in Hz</returns>
     530              :         uint32_t ReadSERDESOscillatorFrequency(std::optional<uint32_t> val = std::nullopt);
     531              :         /// <summary>
     532              :         /// Set the SERDES Oscillator frequency
     533              :         /// </summary>
     534              :         /// <param name="freq">New frequency, in Hz</param>
     535              :         void SetSERDESOscillatorFrequency(uint32_t freq);
     536              :         /// <summary>
     537              :         /// Read the Reset bit of the SERDES IIC Bus
     538              :         /// </summary>
     539              :         /// <returns>Reset bit value</returns>
     540              :         bool ReadSERDESOscillatorIICInterfaceReset(std::optional<uint32_t> val = std::nullopt);
     541              :         /// <summary>
     542              :         /// Reset the SERDES IIC Bus
     543              :         /// </summary>
     544              :         void ResetSERDESOscillatorIICInterface();
     545              : 
     546              :         // Jitter Attenuator CSR Register
     547              :         virtual std::bitset<2>    ReadJitterAttenuatorSelect(std::optional<uint32_t> val = std::nullopt) override;
     548              :         virtual void              SetJitterAttenuatorSelect(std::bitset<2> data, bool alsoResetJA = false) override;
     549              :         virtual bool              ReadJitterAttenuatorReset(std::optional<uint32_t> val = std::nullopt) override;
     550              :         virtual bool              ReadJitterAttenuatorLocked(std::optional<uint32_t> val = std::nullopt) override;
     551              :         virtual void              ResetJitterAttenuator() override;
     552              :         virtual RegisterFormatter FormatJitterAttenuatorCSR() override;
     553              : 
     554              :         /// <summary>
     555              :         /// Read the current Oscillator program for the SERDES Oscillator
     556              :         /// </summary>
     557              :         /// <returns>SERDES Oscillator Program</returns>
     558              :         uint64_t ReadSERDESOscillatorParameters(std::optional<uint32_t> val = std::nullopt);
     559              :         /// <summary>
     560              :         /// Set the SERDES Oscillator program
     561              :         /// </summary>
     562              :         /// <param name="program">New program for the SERDES Oscillator</param>
     563              :         void SetSERDESOscillatorParameters(uint64_t program);
     564              :         /// <summary>
     565              :         /// Read the current SERDES Oscillator clock speed
     566              :         /// </summary>
     567              :         /// <returns>Current SERDES clock speed</returns>
     568              :         DTC_SerdesClockSpeed ReadSERDESOscillatorClock(std::optional<uint32_t> val = std::nullopt);
     569              :         /// <summary>
     570              :         /// Set the SERDES Oscillator clock speed for the given SERDES transfer rate
     571              :         /// </summary>
     572              :         /// <param name="speed">Clock speed to set</param>
     573              :         void SetSERDESOscillatorClock(DTC_SerdesClockSpeed speed);
     574              :         /// <summary>
     575              :         /// Formats the register's current value for register dumps
     576              :         /// </summary>
     577              :         /// <returns>RegisterFormatter object containing register information</returns>
     578              :         RegisterFormatter FormatSERDESOscillatorFrequency();
     579              :         /// <summary>
     580              :         /// Formats the register's current value for register dumps
     581              :         /// </summary>
     582              :         /// <returns>RegisterFormatter object containing register information</returns>
     583              :         RegisterFormatter FormatSERDESOscillatorControl();
     584              : 
     585              :         // Timestamp Preset Registers
     586              :         /// <summary>
     587              :         /// Set the Timestamp preset for Timing system emulation mode
     588              :         /// </summary>
     589              :         /// <param name="preset">Timestamp for Timing emulation</param>
     590              :         void SetEventWindowTagPreset(const DTC_EventWindowTag& preset);
     591              :         /// <summary>
     592              :         /// Read the Timestamp preset for Timing system emulation mode
     593              :         /// </summary>
     594              :         /// <returns>Timestamp preset</returns>
     595              :         DTC_EventWindowTag ReadTimestampPreset(std::optional<uint32_t> val = std::nullopt);
     596              :         /// <summary>
     597              :         /// Formats the register's current value for register dumps
     598              :         /// </summary>
     599              :         /// <returns>RegisterFormatter object containing register information</returns>
     600              :         RegisterFormatter FormatTimestampPreset0();
     601              :         /// <summary>
     602              :         /// Formats the register's current value for register dumps
     603              :         /// </summary>
     604              :         /// <returns>RegisterFormatter object containing register information</returns>
     605              :         RegisterFormatter FormatTimestampPreset1();
     606              : 
     607              :         /// <summary>
     608              :         /// Writes the current Linux time (seconds since the Unix epoch) to the LinuxTimestamp register.
     609              :         /// </summary>
     610              :         void SetLinuxTimestampPreset();
     611              :         /// <summary>
     612              :         /// Reads the LinuxTimestamp register.
     613              :         /// </summary>
     614              :         /// <returns>The timestamp value stored in the register, in seconds since the Unix epoch</returns>
     615              :         time_t ReadLinuxTimestamp();
     616              : 
     617              :         // FIFO Full Error Flags Registers
     618              :         /// <summary>
     619              :         /// Clear all FIFO Full Error Flags for the given Link
     620              :         /// </summary>
     621              :         /// <param name="link">Link to clear</param>
     622              :         void ClearFIFOFullErrorFlags(const CFO_Link_ID& link);
     623              :         /// <summary>
     624              :         /// Read the FIFO Full Error/Status Flags for the given Link
     625              :         /// </summary>
     626              :         /// <param name="link">Link to read</param>
     627              :         /// <returns>CFO_FIFOFullErrorFlags object</returns>
     628              :         DTC_FIFOFullErrorFlags ReadFIFOFullErrorFlags(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     629              :         /// <summary>
     630              :         /// Formats the register's current value for register dumps
     631              :         /// </summary>
     632              :         /// <returns>RegisterFormatter object containing register information</returns>
     633              :         RegisterFormatter FormatFIFOFullErrorFlag0();
     634              : 
     635              :         // Receive Packet Error Register
     636              :         /// <summary>
     637              :         /// Clear the RX Elastic Buffer Underrun Error Flag for the given Link
     638              :         /// </summary>
     639              :         /// <param name="link">Link to clear</param>
     640              :         void ClearRXElasticBufferUnderrun(const CFO_Link_ID& link);
     641              :         /// <summary>
     642              :         /// Read the RX Elastic Buffer Underrun Error Flag for the given Link
     643              :         /// </summary>
     644              :         /// <param name="link">Link to read</param>
     645              :         /// <returns>True if the RX Elastic Buffer Underrun Error Flag is set</returns>
     646              :         bool ReadRXElasticBufferUnderrun(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     647              :         /// <summary>
     648              :         /// Clear the RX Elastic Buffer Overrun Error Flag for the given Link
     649              :         /// </summary>
     650              :         /// <param name="link">Link to clear</param>
     651              :         void ClearRXElasticBufferOverrun(const CFO_Link_ID& link);
     652              :         /// <summary>
     653              :         /// Read the RX Elastic Buffer Overrun Error Flag for the given Link
     654              :         /// </summary>
     655              :         /// <param name="link">Link to read</param>
     656              :         /// <returns>True if the RX Elastic Buffer Overrun Error Flag is set</returns>
     657              :         bool ReadRXElasticBufferOverrun(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     658              :         /// <summary>
     659              :         /// Clear the Packet Error Flag for the given Link
     660              :         /// </summary>
     661              :         /// <param name="link">Link to clear</param>
     662              :         void ClearPacketError(const CFO_Link_ID& link);
     663              :         /// <summary>
     664              :         /// Read the Packet Error Flag for the given Link
     665              :         /// </summary>
     666              :         /// <param name="link">Link to read</param>
     667              :         /// <returns>True if the Packet Error Flag is set</returns>
     668              :         bool ReadPacketError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     669              :         /// <summary>
     670              :         /// Clear the Packet CRC Error Flag for the given Link
     671              :         /// </summary>
     672              :         /// <param name="link">Link to clear</param>
     673              :         void ClearPacketCRCError(const CFO_Link_ID& link);
     674              :         /// <summary>
     675              :         /// Read the Packet CRC Error Flag for the given Link
     676              :         /// </summary>
     677              :         /// <param name="link">Link to read</param>
     678              :         /// <returns>True if the Packet CRC Error Flag is set</returns>
     679              :         bool ReadPacketCRCError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     680              :         /// <summary>
     681              :         /// Formats the register's current value for register dumps
     682              :         /// </summary>
     683              :         /// <returns>RegisterFormatter object containing register information</returns>
     684              :         RegisterFormatter FormatReceivePacketError();
     685              : 
     686              :         // Event Window Emulator (Beam Off) Interval Time Register
     687              :         /// <summary>
     688              :         /// Set the Event Window Emulator (Beam Off) Interval
     689              :         /// </summary>
     690              :         /// <param name="data">Interval to set</param>
     691              :         void SetEventWindowEmulatorInterval(const uint32_t& data);
     692              :         /// <summary>
     693              :         /// Read the Event Window Emulator (Beam Off) Interval
     694              :         /// </summary>
     695              :         /// <returns>The Event Window Emulator (Beam Off) Interval</returns>
     696              :         uint32_t ReadEventWindowEmulatorInterval(std::optional<uint32_t> val = std::nullopt);
     697              :         /// <summary>
     698              :         /// Formats the register's current value for register dumps
     699              :         /// </summary>
     700              :         /// <returns>RegisterFormatter object containing register information</returns>
     701              :         RegisterFormatter FormatEventWindowEmulatorIntervalTime();
     702              : 
     703              :         // Event Window Holdoff Time Register
     704              :         /// <summary>
     705              :         /// Set the holdoff time (minimum dead time before Beam On)
     706              :         /// </summary>
     707              :         /// <param name="data">New value of the holdoff time parameter</param>
     708              :         void SetEventWindowHoldoffTime(const uint32_t& data);
     709              :         /// <summary>
     710              :         /// Read the current Event Window Holdoff time (minimum dead time before Beam On)
     711              :         /// </summary>
     712              :         /// <returns>The current Event Window Holdoff time (minimum dead time before Beam On)</returns>
     713              :         uint32_t ReadEventWindowHoldoffTime(std::optional<uint32_t> val = std::nullopt);
     714              :         /// <summary>
     715              :         /// Formats the register's current value for register dumps
     716              :         /// </summary>
     717              :         /// <returns>RegisterFormatter object containing register information</returns>
     718              :         RegisterFormatter FormatEventWindowHoldoffTime();
     719              : 
     720              :         // Event Window Timeout Error Register
     721              :         /// <summary>
     722              :         /// Read the Event Window Timeout Error bit for the given link
     723              :         /// </summary>
     724              :         /// <param name="link">Link to read</param>
     725              :         /// <returns>Value of the Event Window Timeout Error bit for the given link</returns>
     726              :         bool ReadEventWindowTimeoutError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     727              :         /// <summary>
     728              :         /// Clear the Event Window Timeout Error bit for the given link
     729              :         /// </summary>
     730              :         /// <param name="link">Link to clear</param>
     731              :         void ClearEventWindowTimeoutError(const CFO_Link_ID& link);
     732              :         /// <summary>
     733              :         /// Formats the register's current value for register dumps
     734              :         /// </summary>
     735              :         /// <returns>RegisterFormatter object containing register information</returns>
     736              :         RegisterFormatter FormatEventWindowTimeoutError();
     737              : 
     738              :         // Event Window Timeout Interval Register
     739              :         /// <summary>
     740              :         /// Set the Event Window Timeout Interval
     741              :         /// </summary>
     742              :         /// <param name="data">New Event Window Timeout Interval</param>
     743              :         void SetEventWindowTimeoutInterval(const uint32_t& data);
     744              :         /// <summary>
     745              :         /// Read the Event Window Timeout Interval
     746              :         /// </summary>
     747              :         /// <returns>The Event Window Timeout Interval</returns>
     748              :         uint32_t ReadEventWindowTimeoutInterval(std::optional<uint32_t> val = std::nullopt);
     749              :         /// <summary>
     750              :         /// Formats the register's current value for register dumps
     751              :         /// </summary>
     752              :         /// <returns>RegisterFormatter object containing register information</returns>
     753              :         RegisterFormatter FormatEventWindowTimeoutInterval();
     754              : 
     755              :         uint32_t          ReadReceiveRF0MarkerCount(std::optional<uint32_t> val = std::nullopt);
     756              :         uint32_t          ReadTransmitHeartbeatPacketCount(std::optional<uint32_t> val = std::nullopt);
     757              :         uint32_t          ReadTransmitEventWindowMarkerCount(std::optional<uint32_t> val = std::nullopt);
     758              :         RegisterFormatter FormatReceiveRF0MarkerCount();
     759              :         RegisterFormatter FormatTransmitHeartbeatPacketCount();
     760              :         RegisterFormatter FormatTransmitEventWindowMarkerCount();
     761              : 
     762              :         /// <summary>
     763              :         /// Clear the value of the Receive byte counter
     764              :         /// </summary>
     765              :         /// <param name="link">Link to clear counter for</param>
     766              :         //2026-08-17 PM void ClearReceiveByteCount(const CFO_Link_ID& link);
     767              :         /// <summary>
     768              :         /// Read the value of the Receive byte counter
     769              :         /// </summary>
     770              :         /// <param name="link">Link to read counter for</param>
     771              :         /// <returns>Current value of the Receive byte counter on the given Link</returns>
     772              :         //2026-08-17 PM         uint32_t ReadReceiveByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     773              :         /// <summary>
     774              :         /// Clear the value of the Receive Packet counter
     775              :         /// </summary>
     776              :         /// <param name="link">Link to clear counter for</param>
     777              :         //2026-08-17 PM         void ClearReceivePacketCount(const CFO_Link_ID& link);
     778              :         /// <summary>
     779              :         /// Read the value of the Receive Packet counter
     780              :         /// </summary>
     781              :         /// <param name="link">Link to read counter for</param>
     782              :         /// <returns>Current value of the Receive Packet counter on the given Link</returns>
     783              :         //2026-08-17 PM         uint32_t ReadReceivePacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     784              :         /// <summary>
     785              :         /// Clear the value of the Transmit byte counter
     786              :         /// </summary>
     787              :         /// <param name="link">Link to clear counter for</param>
     788              :         //2026-08-17 PM         void ClearTransmitByteCount(const CFO_Link_ID& link);
     789              :         /// <summary>
     790              :         /// Read the value of the Transmit byye counter
     791              :         /// </summary>
     792              :         /// <param name="link">Link to read counter for</param>
     793              :         /// <returns>Current value of the Transmit byte counter on the given Link</returns>
     794              :         //2026-08-17 PM         uint32_t ReadTransmitByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     795              :         /// <summary>
     796              :         /// Clear the value of the Transmit Packet counter
     797              :         /// </summary>
     798              :         /// <param name="link">Link to clear counter for</param>
     799              :         //2026-08-17 PM         void ClearTransmitPacketCount(const CFO_Link_ID& link);
     800              :         /// <summary>
     801              :         /// Read the value of the Transmit Packet counter
     802              :         /// </summary>
     803              :         /// <param name="link">Link to read counter for</param>
     804              :         /// <returns>Current value of the Transmit Packet counter on the given Link</returns>
     805              :         //2026-08-17 PM         uint32_t ReadTransmitPacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     806              :         /// <summary>
     807              :         /// Formats the register's current value for register dumps
     808              :         /// </summary>
     809              :         /// <returns>RegisterFormatter object containing register information</returns>
     810              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink0();
     811              :         /// <summary>
     812              :         /// Formats the register's current value for register dumps
     813              :         /// </summary>
     814              :         /// <returns>RegisterFormatter object containing register information</returns>
     815              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink1();
     816              :         /// <summary>
     817              :         /// Formats the register's current value for register dumps
     818              :         /// </summary>
     819              :         /// <returns>RegisterFormatter object containing register information</returns>
     820              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink2();
     821              :         /// <summary>
     822              :         /// Formats the register's current value for register dumps
     823              :         /// </summary>
     824              :         /// <returns>RegisterFormatter object containing register information</returns>
     825              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink3();
     826              :         /// <summary>
     827              :         /// Formats the register's current value for register dumps
     828              :         /// </summary>
     829              :         /// <returns>RegisterFormatter object containing register information</returns>
     830              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink4();
     831              :         /// <summary>
     832              :         /// Formats the register's current value for register dumps
     833              :         /// </summary>
     834              :         /// <returns>RegisterFormatter object containing register information</returns>
     835              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink5();
     836              :         /// <summary>
     837              :         /// Formats the register's current value for register dumps
     838              :         /// </summary>
     839              :         /// <returns>RegisterFormatter object containing register information</returns>
     840              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink6();
     841              :         /// <summary>
     842              :         /// Formats the register's current value for register dumps
     843              :         /// </summary>
     844              :         /// <returns>RegisterFormatter object containing register information</returns>
     845              :         //2026-08-17 PM         RegisterFormatter FormatReceiveByteCountLink7();
     846              :         /// <summary>
     847              :         /// Formats the register's current value for register dumps
     848              :         /// </summary>
     849              :         /// <returns>RegisterFormatter object containing register information</returns>
     850              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink0();
     851              :         /// <summary>
     852              :         /// Formats the register's current value for register dumps
     853              :         /// </summary>
     854              :         /// <returns>RegisterFormatter object containing register information</returns>
     855              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink1();
     856              :         /// <summary>
     857              :         /// Formats the register's current value for register dumps
     858              :         /// </summary>
     859              :         /// <returns>RegisterFormatter object containing register information</returns>
     860              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink2();
     861              :         /// <summary>
     862              :         /// Formats the register's current value for register dumps
     863              :         /// </summary>
     864              :         /// <returns>RegisterFormatter object containing register information</returns>
     865              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink3();
     866              :         /// <summary>
     867              :         /// Formats the register's current value for register dumps
     868              :         /// </summary>
     869              :         /// <returns>RegisterFormatter object containing register information</returns>
     870              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink4();
     871              :         /// <summary>
     872              :         /// Formats the register's current value for register dumps
     873              :         /// </summary>
     874              :         /// <returns>RegisterFormatter object containing register information</returns>
     875              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink5();
     876              :         /// <summary>
     877              :         /// Formats the register's current value for register dumps
     878              :         /// </summary>
     879              :         /// <returns>RegisterFormatter object containing register information</returns>
     880              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink6();
     881              :         /// <summary>
     882              :         /// Formats the register's current value for register dumps
     883              :         /// </summary>
     884              :         /// <returns>RegisterFormatter object containing register information</returns>
     885              :         //2026-08-17 PM         RegisterFormatter FormatReceivePacketCountLink7();
     886              :         /// <summary>
     887              :         /// Formats the register's current value for register dumps
     888              :         /// </summary>
     889              :         /// <returns>RegisterFormatter object containing register information</returns>
     890              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink0();
     891              :         /// <summary>
     892              :         /// Formats the register's current value for register dumps
     893              :         /// </summary>
     894              :         /// <returns>RegisterFormatter object containing register information</returns>
     895              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink1();
     896              :         /// <summary>
     897              :         /// Formats the register's current value for register dumps
     898              :         /// </summary>
     899              :         /// <returns>RegisterFormatter object containing register information</returns>
     900              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink2();
     901              :         /// <summary>
     902              :         /// Formats the register's current value for register dumps
     903              :         /// </summary>
     904              :         /// <returns>RegisterFormatter object containing register information</returns>
     905              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink3();
     906              :         /// <summary>
     907              :         /// Formats the register's current value for register dumps
     908              :         /// </summary>
     909              :         /// <returns>RegisterFormatter object containing register information</returns>
     910              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink4();
     911              :         /// <summary>
     912              :         /// Formats the register's current value for register dumps
     913              :         /// </summary>
     914              :         /// <returns>RegisterFormatter object containing register information</returns>
     915              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink5();
     916              :         /// <summary>
     917              :         /// Formats the register's current value for register dumps
     918              :         /// </summary>
     919              :         /// <returns>RegisterFormatter object containing register information</returns>
     920              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink6();
     921              :         /// <summary>
     922              :         /// Formats the register's current value for register dumps
     923              :         /// </summary>
     924              :         /// <returns>RegisterFormatter object containing register information</returns>
     925              :         //2026-08-17 PM         RegisterFormatter FormatTramsitByteCountLink7();
     926              :         /// <summary>
     927              :         /// Formats the register's current value for register dumps
     928              :         /// </summary>
     929              :         /// <returns>RegisterFormatter object containing register information</returns>
     930              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink0();
     931              :         /// <summary>
     932              :         /// Formats the register's current value for register dumps
     933              :         /// </summary>
     934              :         /// <returns>RegisterFormatter object containing register information</returns>
     935              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink1();
     936              :         /// <summary>
     937              :         /// Formats the register's current value for register dumps
     938              :         /// </summary>
     939              :         /// <returns>RegisterFormatter object containing register information</returns>
     940              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink2();
     941              :         /// <summary>
     942              :         /// Formats the register's current value for register dumps
     943              :         /// </summary>
     944              :         /// <returns>RegisterFormatter object containing register information</returns>
     945              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink3();
     946              :         /// <summary>
     947              :         /// Formats the register's current value for register dumps
     948              :         /// </summary>
     949              :         /// <returns>RegisterFormatter object containing register information</returns>
     950              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink4();
     951              :         /// <summary>
     952              :         /// Formats the register's current value for register dumps
     953              :         /// </summary>
     954              :         /// <returns>RegisterFormatter object containing register information</returns>
     955              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink5();
     956              :         /// <summary>
     957              :         /// Formats the register's current value for register dumps
     958              :         /// </summary>
     959              :         /// <returns>RegisterFormatter object containing register information</returns>
     960              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink6();
     961              :         /// <summary>
     962              :         /// Formats the register's current value for register dumps
     963              :         /// </summary>
     964              :         /// <returns>RegisterFormatter object containing register information</returns>
     965              :         //2026-08-17 PM         RegisterFormatter FormatTransmitPacketCountLink7();
     966              : 
     967              :         // DDR3 Memory DMA Write Start Address Register
     968              :         /// <summary>
     969              :         /// Set the Write Start Address for DMAs into the DDR memory
     970              :         /// </summary>
     971              :         /// <param name="address">Start address</param>
     972              :         void SetDMAWriteStartAddress(const uint32_t& address);
     973              :         /// <summary>
     974              :         /// Read the Write Start Address for DMAs into the DDR memory
     975              :         /// </summary>
     976              :         /// <returns>Start Address</returns>
     977              :         uint32_t ReadDMAWriteStartAddress(std::optional<uint32_t> val = std::nullopt);
     978              :         /// <summary>
     979              :         /// Formats the register's current value for register dumps
     980              :         /// </summary>
     981              :         /// <returns>RegisterFormatter object containing register information</returns>
     982              :         RegisterFormatter FormatDMAWriteStartAddress();
     983              : 
     984              :         // DDR3 Memory DMA Read Start Address Register
     985              :         /// <summary>
     986              :         /// Set the Read Start Address for DMAs into the DDR memory
     987              :         /// </summary>
     988              :         /// <param name="address">Start address</param>
     989              :         void SetDMAReadStartAddress(const uint32_t& address);
     990              :         /// <summary>
     991              :         /// Read the Read Start Address for DMAs into the DDR memory
     992              :         /// </summary>
     993              :         /// <returns>Start Address</returns>
     994              :         uint32_t ReadDMAReadStartAddress(std::optional<uint32_t> val = std::nullopt);
     995              :         /// <summary>
     996              :         /// Formats the register's current value for register dumps
     997              :         /// </summary>
     998              :         /// <returns>RegisterFormatter object containing register information</returns>
     999              :         RegisterFormatter FormatDMAReadStartAddress();
    1000              : 
    1001              :         // DDR3 Memory DMA Read Byte Count / Start Read DMA Register
    1002              :         /// <summary>
    1003              :         /// Set the number of bytes to read for a DMA. Setting this register also initiates the DMA
    1004              :         /// </summary>
    1005              :         /// <param name="bytes">Bytes to read</param>
    1006              :         void SetDMAReadByteCount(const uint32_t& bytes);
    1007              :         /// <summary>
    1008              :         /// Read the current value of the DMA Read Byte Count
    1009              :         /// </summary>
    1010              :         /// <returns>Bytes to read</returns>
    1011              :         uint32_t ReadDMAReadByteCount(std::optional<uint32_t> val = std::nullopt);
    1012              :         /// <summary>
    1013              :         /// Start a DMA read using the byte count already present in the register
    1014              :         /// </summary>
    1015              :         void StartDMARead() { SetDMAReadByteCount(ReadDMAReadByteCount()); }
    1016              :         /// <summary>
    1017              :         /// Formats the register's current value for register dumps
    1018              :         /// </summary>
    1019              :         /// <returns>RegisterFormatter object containing register information</returns>
    1020              :         RegisterFormatter FormatDMAReadByteCount();
    1021              : 
    1022              :         // DDR3 Beam On Base Address Register
    1023              :         /// <summary>
    1024              :         /// Set the Beam On Base Address in the DDR memory
    1025              :         /// </summary>
    1026              :         /// <param name="address">Base address</param>
    1027              :         void SetRunPlanBeamOnBaseAddress(const uint32_t& address);
    1028              :         /// <summary>
    1029              :         /// Read the Beam On Base Address for DMAs into the DDR memory
    1030              :         /// </summary>
    1031              :         /// <returns>Base Address</returns>
    1032              :         uint32_t ReadRunPlanBeamOnBaseAddress(std::optional<uint32_t> val = std::nullopt);
    1033              :         /// <summary>
    1034              :         /// Formats the register's current value for register dumps
    1035              :         /// </summary>
    1036              :         /// <returns>RegisterFormatter object containing register information</returns>
    1037              :         RegisterFormatter FormatRunPlanBeamOnBaseAddress();
    1038              : 
    1039              :         // DDR3 Beam Off Base Address Register
    1040              :         /// <summary>
    1041              :         /// Set the Beam Off Base Address in the DDR memory
    1042              :         /// </summary>
    1043              :         /// <param name="address">Base address</param>
    1044              :         void SetRunPlanBeamOffBaseAddress(const uint32_t& address);
    1045              :         /// <summary>
    1046              :         /// Read the Beam Off Base Address for DMAs into the DDR memory
    1047              :         /// </summary>
    1048              :         /// <returns>Base Address</returns>
    1049              :         uint32_t ReadRunPlanBeamOffBaseAddress(std::optional<uint32_t> val = std::nullopt);
    1050              :         /// <summary>
    1051              :         /// Formats the register's current value for register dumps
    1052              :         /// </summary>
    1053              :         /// <returns>RegisterFormatter object containing register information</returns>
    1054              :         RegisterFormatter FormatRunPlanBeamOffBaseAddress();
    1055              :         /// <summary>
    1056              :         /// Write run plan data to the specified DDR memory address.
    1057              :         /// </summary>
    1058              :         /// <param name="inputData">Serialized run plan data to be written.</param>
    1059              :         /// <param name="address">DDR memory address where the run plan data should be stored.</param>
    1060              :         void SetRunPlanData(const std::string& inputData, const uint32_t& address);
    1061              :         /// <summary>
    1062              :         /// Compare the provided run plan data with the data stored at the specified DDR memory address.
    1063              :         /// </summary>
    1064              :         /// <param name="inputData">Serialized run plan data expected at the given address.</param>
    1065              :         /// <param name="address">DDR memory address from which the current run plan data is read.</param>
    1066              :         /// <param name="mismatches">
    1067              :         /// Optional pointer to a map that will be populated with any mismatching words,
    1068              :         /// keyed by address and containing expected/actual value pairs.
    1069              :         /// </param>
    1070              :         void CompareRunPlanData(const std::string& inputData, const uint32_t& address, std::optional<std::reference_wrapper<std::map<uint32_t /* address */, std::pair<uint32_t /* expected */, uint32_t /* actual */>>>> mismatches = std::nullopt, std::optional<std::reference_wrapper<std::vector<uint64_t>>> andMasks = std::nullopt, std::optional<std::reference_wrapper<std::vector<uint64_t>>> orMasks = std::nullopt);
    1071              :         /// <summary>
    1072              :         /// Read the current run plan mode as reported by the firmware.
    1073              :         /// </summary>
    1074              :         /// <returns>The current run plan mode value.</returns>
    1075              :         uint64_t ReadRunPlanCurrentMode();
    1076              :         /// <summary>
    1077              :         /// Format the current run plan mode value for inclusion in register dumps.
    1078              :         /// </summary>
    1079              :         /// <returns>RegisterFormatter object containing the current mode information.</returns>
    1080              :         RegisterFormatter FormatRunPlanCurrentMode();
    1081              :         /// <summary>
    1082              :         /// Read the current run plan tag as reported by the firmware.
    1083              :         /// </summary>
    1084              :         /// <returns>The current run plan tag value.</returns>
    1085              :         uint64_t ReadRunPlanCurrentTag();
    1086              :         /// <summary>
    1087              :         /// Format the current run plan tag value for inclusion in register dumps.
    1088              :         /// </summary>
    1089              :         /// <returns>RegisterFormatter object containing the current tag information.</returns>
    1090              :         RegisterFormatter FormatRunPlanCurrentTag();
    1091              : 
    1092              :         // Run Plan Subrun Event Limit Register
    1093              :         /// <summary>
    1094              :         /// Set the Run Plan Subrun Event Limit
    1095              :         /// </summary>
    1096              :         /// <param name="limit">Subrun event limit value</param>
    1097              :         void SetRunPlanSubrunEvtLimit(uint32_t limit);
    1098              :         /// <summary>
    1099              :         /// Read the Run Plan Subrun Event Limit
    1100              :         /// </summary>
    1101              :         /// <returns>Current subrun event limit value</returns>
    1102              :         uint32_t ReadRunPlanSubrunEvtLimit(std::optional<uint32_t> val = std::nullopt);
    1103              :         /// <summary>
    1104              :         /// Formats the register's current value for register dumps
    1105              :         /// </summary>
    1106              :         /// <returns>RegisterFormatter object containing register information</returns>
    1107              :         RegisterFormatter FormatRunPlanSubrunEvtLimit();
    1108              : 
    1109              :         // Run Plan Subrun Prediction Offset Register
    1110              :         /// <summary>
    1111              :         /// Set the Run Plan Subrun Prediction Offset
    1112              :         /// </summary>
    1113              :         /// <param name="offset">Subrun prediction offset value</param>
    1114              :         void SetRunPlanSubrunPredOffset(uint32_t offset);
    1115              :         /// <summary>
    1116              :         /// Read the Run Plan Subrun Prediction Offset
    1117              :         /// </summary>
    1118              :         /// <returns>Current subrun prediction offset value</returns>
    1119              :         uint32_t ReadRunPlanSubrunPredOffset(std::optional<uint32_t> val = std::nullopt);
    1120              :         /// <summary>
    1121              :         /// Formats the register's current value for register dumps
    1122              :         /// </summary>
    1123              :         /// <returns>RegisterFormatter object containing register information</returns>
    1124              :         RegisterFormatter FormatRunPlanSubrunPredOffset();
    1125              : 
    1126              :         // Firefly CSR Register
    1127              :         /// <summary>
    1128              :         /// Read the present bit for the TX/RX Firefly
    1129              :         /// </summary>
    1130              :         /// <returns>Whether the Firefly is present</returns>
    1131              :         bool ReadFireflyTXRXPresent(std::optional<uint32_t> val = std::nullopt);
    1132              :         /// <summary>
    1133              :         /// Read the present bit for the RX Firefly
    1134              :         /// </summary>
    1135              :         /// <returns>Whether the Firefly is present</returns>
    1136              :         bool ReadFireflyRXPresent(std::optional<uint32_t> val = std::nullopt);
    1137              :         /// <summary>
    1138              :         /// Read the present bit for the TX Firefly
    1139              :         /// </summary>
    1140              :         /// <returns>Whether the Firefly is present</returns>
    1141              :         bool ReadFireflyTXPresent(std::optional<uint32_t> val = std::nullopt);
    1142              :         /// <summary>
    1143              :         /// Read the interrupt bit for the TX/RX Firefly
    1144              :         /// </summary>
    1145              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1146              :         bool ReadFireflyTXRXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1147              :         /// <summary>
    1148              :         /// Read the interrupt bit for the RX Firefly
    1149              :         /// </summary>
    1150              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1151              :         bool ReadFireflyRXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1152              :         /// <summary>
    1153              :         /// Read the interrupt bit for the TX Firefly
    1154              :         /// </summary>
    1155              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1156              :         bool ReadFireflyTXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1157              :         /// <summary>
    1158              :         /// Set the Select bit of the TX/RX Firefly
    1159              :         /// </summary>
    1160              :         /// <param name="select">Value to set</param>
    1161              :         void SetFireflyTXRXSelect(bool select);
    1162              :         /// <summary>
    1163              :         /// Set the Select bit of the RX Firefly
    1164              :         /// </summary>
    1165              :         /// <param name="select">Value to set</param>
    1166              :         void SetFireflyRXSelect(bool select);
    1167              :         /// <summary>
    1168              :         /// Set the Select bit of the TX Firefly
    1169              :         /// </summary>
    1170              :         /// <param name="select">Value to set</param>
    1171              :         void SetFireflyTXSelect(bool select);
    1172              :         /// <summary>
    1173              :         /// Read the select bit for the TX/RX Firefly
    1174              :         /// </summary>
    1175              :         /// <returns>Whether the Firefly is selected</returns>
    1176              :         bool ReadFireflyTXRXSelect(std::optional<uint32_t> val = std::nullopt);
    1177              :         /// <summary>
    1178              :         /// Read the select bit for the RX Firefly
    1179              :         /// </summary>
    1180              :         /// <returns>Whether the Firefly is selected</returns>
    1181              :         bool ReadFireflyRXSelect(std::optional<uint32_t> val = std::nullopt);
    1182              :         /// <summary>
    1183              :         /// Read the select bit for the TX Firefly
    1184              :         /// </summary>
    1185              :         /// <returns>Whether the Firefly is selected</returns>
    1186              :         bool ReadFireflyTXSelect(std::optional<uint32_t> val = std::nullopt);
    1187              :         /// <summary>
    1188              :         /// Set the Reset bit of the TX/RX Firefly
    1189              :         /// </summary>
    1190              :         /// <param name="reset">Value to set</param>
    1191              :         void SetFireflyTXRXReset(bool reset);
    1192              :         /// <summary>
    1193              :         /// Set the Reset bit of the RX Firefly
    1194              :         /// </summary>
    1195              :         /// <param name="reset">Value to set</param>
    1196              :         void SetFireflyRXReset(bool reset);
    1197              :         /// <summary>
    1198              :         /// Set the Reset bit of the TX Firefly
    1199              :         /// </summary>
    1200              :         /// <param name="reset">Value to set</param>
    1201              :         void SetFireflyTXReset(bool reset);
    1202              :         /// <summary>
    1203              :         /// Read the reset bit for the TX/RX Firefly
    1204              :         /// </summary>
    1205              :         /// <returns>Whether the Firefly is in reset state</returns>
    1206              :         bool ReadFireflyTXRXReset(std::optional<uint32_t> val = std::nullopt);
    1207              :         /// <summary>
    1208              :         /// Read the reset bit for the RX Firefly
    1209              :         /// </summary>
    1210              :         /// <returns>Whether the Firefly is in reset state</returns>
    1211              :         bool ReadFireflyRXReset(std::optional<uint32_t> val = std::nullopt);
    1212              :         /// <summary>
    1213              :         /// Read the reset bit for the TX Firefly
    1214              :         /// </summary>
    1215              :         /// <returns>Whether the Firefly is in reset state</returns>
    1216              :         bool ReadFireflyTXReset(std::optional<uint32_t> val = std::nullopt);
    1217              :         /// <summary>
    1218              :         /// Formats the register's current value for register dumps
    1219              :         /// </summary>
    1220              :         /// <returns>RegisterFormatter object containing register information</returns>
    1221              :         RegisterFormatter FormatFireflyCSR();
    1222              : 
    1223              :         // SERDES PRBS Control Registers
    1224              :         /// <summary>
    1225              :         /// Read the SERDES PRBS Error flag for the given link
    1226              :         /// </summary>
    1227              :         /// <param name="link">Link to read</param>
    1228              :         /// <returns>Value of the flag</returns>
    1229              :         bool ReadSERDESPRBSErrorFlag(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1230              :         /// <summary>
    1231              :         /// Read the TX PRBS SEL byte for the given link
    1232              :         /// </summary>
    1233              :         /// <param name="link">Link to read</param>
    1234              :         /// <returns>Value of the byte</returns>
    1235              :         uint8_t ReadSERDESTXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1236              :         /// <summary>
    1237              :         /// Set the TX PRBS SEL byte for the given link to the given value
    1238              :         /// </summary>
    1239              :         /// <param name="link">Link to set</param>
    1240              :         /// <param name="byte">Value of the byte</param>
    1241              :         void SetSERDESTXPRBSSEL(const CFO_Link_ID& link, uint8_t byte);
    1242              :         /// <summary>
    1243              :         /// Read the RX PRBS SEL byte for the given link
    1244              :         /// </summary>
    1245              :         /// <param name="link">Link to read</param>
    1246              :         /// <returns>Value of the byte</returns>
    1247              :         uint8_t ReadSERDESRXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1248              :         /// <summary>
    1249              :         /// Set the RX PRBS SEL byte for the given link to the given value
    1250              :         /// </summary>
    1251              :         /// <param name="link">Link to set</param>
    1252              :         /// <param name="byte">Value of the byte</param>
    1253              :         void SetSERDESRXPRBSSEL(const CFO_Link_ID& link, uint8_t byte);
    1254              :         /// <summary>
    1255              :         /// Read the SERDES TX PRBS Force Error bit for the given link
    1256              :         /// </summary>
    1257              :         /// <param name="link">Link to read</param>
    1258              :         /// <returns>Value of the bit</returns>
    1259              :         bool ReadSERDESTXPRBSForceError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1260              :         /// <summary>
    1261              :         /// Set the SERDES TX PRBS Force Error bit for the given link to the given value
    1262              :         /// </summary>
    1263              :         /// <param name="link">Link to set</param>
    1264              :         /// <param name="flag">Value to set</param>
    1265              :         void SetSERDESTXPRBSForceError(const CFO_Link_ID& link, bool flag);
    1266              :         /// <summary>
    1267              :         /// Toggle the SERDES TX PRBS Force Error bit for the given link
    1268              :         /// </summary>
    1269              :         /// <param name="link">Link to toggle</param>
    1270              :         void ToggleSERDESTXPRBSForceError(const CFO_Link_ID& link);
    1271              :         /// <summary>
    1272              :         /// Read the SERDES RX PRBS Count Reset bit for the given link
    1273              :         /// </summary>
    1274              :         /// <param name="link">Link to read</param>
    1275              :         /// <returns>Value of the bit</returns>
    1276              :         bool ReadSERDESRXPRBSCountReset(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1277              :         /// <summary>
    1278              :         /// Set the SERDES RX PRBS Count Reset bit for the given link to the given value
    1279              :         /// </summary>
    1280              :         /// <param name="link">Link to set</param>
    1281              :         /// <param name="flag">Value to set</param>
    1282              :         void SetSERDESRXPRBSCountReset(const CFO_Link_ID& link, bool flag);
    1283              :         /// <summary>
    1284              :         /// Toggle the SERDES RX PRBS Count Reset bit for the given link
    1285              :         /// </summary>
    1286              :         /// <param name="link">Link to toggle</param>
    1287              :         void ToggleSERDESRXPRBSCountReset(const CFO_Link_ID& link);
    1288              :         /// <summary>
    1289              :         /// Formats the register's current value for register dumps
    1290              :         /// </summary>
    1291              :         /// <returns>RegisterFormatter object containing register information</returns>
    1292              :         RegisterFormatter FormatSERDESPRBSControlLink0();
    1293              :         /// <summary>
    1294              :         /// Formats the register's current value for register dumps
    1295              :         /// </summary>
    1296              :         /// <returns>RegisterFormatter object containing register information</returns>
    1297              :         RegisterFormatter FormatSERDESPRBSControlLink1();
    1298              :         /// <summary>
    1299              :         /// Formats the register's current value for register dumps
    1300              :         /// </summary>
    1301              :         /// <returns>RegisterFormatter object containing register information</returns>
    1302              :         RegisterFormatter FormatSERDESPRBSControlLink2();
    1303              :         /// <summary>
    1304              :         /// Formats the register's current value for register dumps
    1305              :         /// </summary>
    1306              :         /// <returns>RegisterFormatter object containing register information</returns>
    1307              :         RegisterFormatter FormatSERDESPRBSControlLink3();
    1308              :         /// <summary>
    1309              :         /// Formats the register's current value for register dumps
    1310              :         /// </summary>
    1311              :         /// <returns>RegisterFormatter object containing register information</returns>
    1312              :         RegisterFormatter FormatSERDESPRBSControlLink4();
    1313              :         /// <summary>
    1314              :         /// Formats the register's current value for register dumps
    1315              :         /// </summary>
    1316              :         /// <returns>RegisterFormatter object containing register information</returns>
    1317              :         RegisterFormatter FormatSERDESPRBSControlLink5();
    1318              :         /// <summary>
    1319              :         /// Formats the register's current value for register dumps
    1320              :         /// </summary>
    1321              :         /// <returns>RegisterFormatter object containing register information</returns>
    1322              :         RegisterFormatter FormatSERDESPRBSControlLink6();
    1323              :         /// <summary>
    1324              :         /// Formats the register's current value for register dumps
    1325              :         /// </summary>
    1326              :         /// <returns>RegisterFormatter object containing register information</returns>
    1327              :         RegisterFormatter FormatSERDESPRBSControlLink7();
    1328              : 
    1329              :         // Cable Delays
    1330              :         uint32_t ReadCableDelayMeasureExponentialCount(std::optional<uint32_t> val = std::nullopt);
    1331              :         void     SetCableDelayMeasureExponentialCount(const uint32_t exponent);
    1332              :         uint32_t ReadCableDelayMeasurement(const CFO_Link_ID link, const uint8_t roc, bool& done);
    1333              : 
    1334              :         // /// <summary>
    1335              :         // /// Set the cable delay value for the given link
    1336              :         // /// </summary>
    1337              :         // /// <param name="link">Link to set</param>
    1338              :         // /// <param name="delay">Delay value to set</param>
    1339              :         // void SetCableDelayValue(const CFO_Link_ID& link, const uint32_t delay);
    1340              :         // /// <summary>
    1341              :         // /// Read the configured delay value for the given link
    1342              :         // /// </summary>
    1343              :         // /// <param name="link">Link to read</param>
    1344              :         // /// <returns>Configured delay value for the given link</returns>
    1345              :         // uint32_t ReadCableDelayValue(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1346              :         // /// <summary>
    1347              :         // /// Formats the register's current value for register dumps
    1348              :         // /// </summary>
    1349              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1350              :         // RegisterFormatter FormatCableDelayValueLink0();
    1351              :         // /// <summary>
    1352              :         // /// Formats the register's current value for register dumps
    1353              :         // /// </summary>
    1354              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1355              :         // RegisterFormatter FormatCableDelayValueLink1();
    1356              :         // /// <summary>
    1357              :         // /// Formats the register's current value for register dumps
    1358              :         // /// </summary>
    1359              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1360              :         // RegisterFormatter FormatCableDelayValueLink2();
    1361              :         // /// <summary>
    1362              :         // /// Formats the register's current value for register dumps
    1363              :         // /// </summary>
    1364              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1365              :         // RegisterFormatter FormatCableDelayValueLink3();
    1366              :         // /// <summary>
    1367              :         // /// Formats the register's current value for register dumps
    1368              :         // /// </summary>
    1369              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1370              :         // RegisterFormatter FormatCableDelayValueLink4();
    1371              :         // /// <summary>
    1372              :         // /// Formats the register's current value for register dumps
    1373              :         // /// </summary>
    1374              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1375              :         // RegisterFormatter FormatCableDelayValueLink5();
    1376              :         // /// <summary>
    1377              :         // /// Formats the register's current value for register dumps
    1378              :         // /// </summary>
    1379              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1380              :         // RegisterFormatter FormatCableDelayValueLink6();
    1381              :         // /// <summary>
    1382              :         // /// Formats the register's current value for register dumps
    1383              :         // /// </summary>
    1384              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1385              :         // RegisterFormatter FormatCableDelayValueLink7();
    1386              : 
    1387              :         // // Cable Delay Control And Status Register
    1388              :         // /// <summary>
    1389              :         // /// reset all the bits of the register
    1390              :         // /// </summary>
    1391              :         // void ResetDelayRegister();
    1392              : 
    1393              :         // /// <summary>
    1394              :         // /// Read the Measure Error bit for the given link
    1395              :         // /// </summary>
    1396              :         // /// <param name="link">Link to read</param>
    1397              :         // /// <returns>Value of the bit</returns>
    1398              :         // bool ReadDelayMeasureError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1399              :         // /// <summary>
    1400              :         // /// Read the Cable Delay External Loopback Enable bit
    1401              :         // /// </summary>
    1402              :         // /// <returns>Value of the bit</returns>
    1403              :         // bool ReadDelayExternalLoopbackEnable(std::optional<uint32_t> val = std::nullopt);
    1404              :         // /// <summary>
    1405              :         // /// Set the Cable Delay External Loopback Enable bit
    1406              :         // /// </summary>
    1407              :         // /// <param name="value">Value to set</param>
    1408              :         // void SetDelayExternalLoopbackEnable(bool value);
    1409              :         // /// <summary>
    1410              :         // /// Enable the Delay Measure Mode on the given link
    1411              :         // /// </summary>
    1412              :         // /// <param name="link">Link to enable</param>
    1413              :         // void EnableDelayMeasureMode(const CFO_Link_ID& link);
    1414              :         // /// <summary>
    1415              :         // /// Disable the Delay Measure Mode on the given link
    1416              :         // /// </summary>
    1417              :         // /// <param name="link">Link to disable</param>
    1418              :         // void DisableDelayMeasureMode(const CFO_Link_ID& link);
    1419              :         // /// <summary>
    1420              :         // /// Read the Measure Mode Enable bit for the given link
    1421              :         // /// </summary>
    1422              :         // /// <param name="link">Link to read</param>
    1423              :         // /// <returns>Value of the bit</returns>
    1424              :         // bool ReadDelayMeasureMode(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1425              :         // /// <summary>
    1426              :         // /// Set the Delay Measure Now bit on the given link
    1427              :         // /// </summary>
    1428              :         // /// <param name="link">Link to enable</param>
    1429              :         // void EnableDelayMeasureNow(const CFO_Link_ID& link);
    1430              :         // /// <summary>
    1431              :         // /// Clear the Delay Measure Now bit on the given link
    1432              :         // /// </summary>
    1433              :         // /// <param name="link">Link to disable</param>
    1434              :         // void DisableDelayMeasureNow(const CFO_Link_ID& link);
    1435              :         // /// <summary>
    1436              :         // /// Read the Measure Now bit for the given link
    1437              :         // /// </summary>
    1438              :         // /// <param name="link">Link to read</param>
    1439              :         // /// <returns>Value of the bit</returns>
    1440              :         // bool ReadDelayMeasureNow(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1441              :         // /// <summary>
    1442              :         // /// Formats the register's current value for register dumps
    1443              :         // /// </summary>
    1444              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1445              :         // RegisterFormatter FormatCableDelayControl();
    1446              : 
    1447              :         // FPGA PROM Program Data Register
    1448              : 
    1449              :         // FPGA PROM Program Status Register
    1450              :         /// <summary>
    1451              :         /// Read the full bit on the FPGA PROM FIFO
    1452              :         /// </summary>
    1453              :         /// <returns>the full bit on the FPGA PROM FIFO</returns>
    1454              :         bool ReadFPGAPROMProgramFIFOFull(std::optional<uint32_t> val = std::nullopt);
    1455              :         /// <summary>
    1456              :         /// Read whether the FPGA PROM is ready for data
    1457              :         /// </summary>
    1458              :         /// <returns>whether the FPGA PROM is ready for data</returns>
    1459              :         bool ReadFPGAPROMReady(std::optional<uint32_t> val = std::nullopt);
    1460              :         /// <summary>
    1461              :         /// Formats the register's current value for register dumps
    1462              :         /// </summary>
    1463              :         /// <returns>RegisterFormatter object containing register information</returns>
    1464              :         RegisterFormatter FormatFPGAPROMProgramStatus();
    1465              : 
    1466              :         // FPGA Core Access Register
    1467              :         /// <summary>
    1468              :         /// Performs the chants necessary to reload the CFO firmware
    1469              :         /// </summary>
    1470              :         void ReloadFPGAFirmware();
    1471              :         /// <summary>
    1472              :         /// Read the FPGA Core Access FIFO Full bit
    1473              :         /// </summary>
    1474              :         /// <returns>Whether the FPGA Core Access FIFO is full</returns>
    1475              :         bool ReadFPGACoreAccessFIFOFull(std::optional<uint32_t> val = std::nullopt);
    1476              :         /// <summary>
    1477              :         /// Read the FPGA Core Access FIFO Empty bit
    1478              :         /// </summary>
    1479              :         /// <returns>Whether the FPGA Core Access FIFO is empty</returns>
    1480              :         bool ReadFPGACoreAccessFIFOEmpty(std::optional<uint32_t> val = std::nullopt);
    1481              :         /// <summary>
    1482              :         /// Formats the register's current value for register dumps
    1483              :         /// </summary>
    1484              :         /// <returns>RegisterFormatter object containing register information</returns>
    1485              :         RegisterFormatter FormatFPGACoreAccess();
    1486              : 
    1487              :         // Oscillator Programming (DDR and SERDES)
    1488              :         /// <summary>
    1489              :         /// Set the given oscillator to the given frequency, calculating a new program in the process.
    1490              :         /// </summary>
    1491              :         /// <param name="targetFrequency">New frequency to program, in Hz</param>
    1492              :         /// <returns>Whether the oscillator frequency was changed</returns>
    1493              :         bool SetNewOscillatorFrequency(double targetFrequency);
    1494              : 
    1495              :         /// <summary>
    1496              :         /// Disable all CFO links
    1497              :         /// </summary>
    1498              :         void DisableLinks();
    1499              : 
    1500              :         /// <summary>
    1501              :         /// Disable all CFO outputs
    1502              :         /// </summary>
    1503              :         void DisableAllOutputs();
    1504              : 
    1505              :   private:
    1506              :         bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) override;
    1507              :         void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) override;
    1508              : 
    1509              :         int      DecodeHighSpeedDivider_(int input);
    1510            0 :         int      DecodeOutputDivider_(int input) { return input + 1; }
    1511            0 :         double   DecodeRFREQ_(uint64_t input) { return input / 268435456.0; }
    1512              :         int      EncodeHighSpeedDivider_(int input);
    1513              :         int      EncodeOutputDivider_(int input);
    1514            0 :         uint64_t EncodeRFREQ_(double input) { return static_cast<uint64_t>(input * 268435456) & 0x3FFFFFFFFF; }
    1515              :         uint64_t CalculateFrequencyForProgramming_(double targetFrequency, double currentFrequency, uint64_t currentProgram);
    1516              : 
    1517              :   protected:
    1518              :         DTC_SimMode simMode_;                ///< Simulation mode
    1519              :         bool        usingDetectorEmulator_;  ///< Whether Detector Emulation mode is enabled
    1520              :         uint16_t    dmaSize_;                ///< Size of DMAs, in bytes (default 32k)
    1521              : 
    1522              :   public:
    1523            0 :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedDumpFunctions() override { return formattedDumpFunctions_; };
    1524            0 :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedSimpleDumpFunctions() override { return formattedSimpleDumpFunctions_; };
    1525              : 
    1526              :         const std::vector<std::function<RegisterFormatter()>> formattedSimpleDumpFunctions_{
    1527            0 :             [this] { return this->FormatDeviceHash(); },  // mu2e_host_hash
    1528            0 :             [this] { return this->FormatDeviceTimeAlive(); },
    1529            0 :             [this] { return this->FormatCFOControl(); },
    1530            0 :             [this] { return this->FormatBeamOffMode(); },
    1531            0 :             [this] { return this->FormatBeamOnMode(); },
    1532            0 :             [this] { return this->FormatJitterAttenuatorCSR(); },
    1533            0 :             [this] { return this->FormatSERDESPLLLocked(); },
    1534            0 :             [this] { return this->FormatLinkEnable(); },
    1535            0 :             [this] { return this->FormatSERDESRXCDRLock(); },
    1536            0 :             [this] { return this->FormatSERDESResetDone(); },
    1537            0 :             [this] { return this->FormatSERDESReset(); },
    1538              :         };
    1539              : 
    1540              :         const std::vector<std::function<RegisterFormatter()>> formattedDumpFunctions_{
    1541            0 :             [this] { return this->FormatDesignVersion(); },
    1542            0 :             [this] { return this->FormatDesignDate(); },
    1543            0 :             [this] { return this->FormatDesignStatus(); },
    1544            0 :             [this] { return this->FormatVivadoVersion(); },
    1545            0 :             [this] { return this->FormatCFOControl(); },
    1546            0 :             [this] { return this->FormatDMATransferLength(); },
    1547            0 :             [this] { return this->FormatSERDESLoopbackEnable(); },
    1548            0 :             [this] { return this->FormatClockOscillatorStatus(); },
    1549            0 :             [this] { return this->FormatLinkEnable(); },
    1550            0 :             [this] { return this->FormatSERDESReset(); },
    1551            0 :             [this] { return this->FormatSERDESRXDisparityError(); },
    1552            0 :             [this] { return this->FormatSERDESRXCharacterNotInTableError(); },
    1553            0 :             [this] { return this->FormatSERDESUnlockError(); },
    1554            0 :             [this] { return this->FormatSERDESPLLLocked(); },
    1555            0 :             [this] { return this->FormatSERDESRXStatus(); },
    1556            0 :             [this] { return this->FormatSERDESResetDone(); },
    1557            0 :             [this] { return this->FormatSERDESRXCDRLock(); },
    1558            0 :             [this] { return this->FormatBeamOnTimerPreset(); },
    1559            0 :             [this] { return this->FormatBeamOnMode(); },
    1560            0 :             [this] { return this->FormatBeamOffMode(); },
    1561              :             // LEGACY: [this] { return this->FormatClockMarkerIntervalCount(); },  // register 0x9154 repurposed as RunPlanSubrunEvtLimit
    1562            0 :             [this] { return this->FormatSERDESOscillatorFrequency(); },
    1563            0 :             [this] { return this->FormatSERDESOscillatorControl(); },
    1564            0 :             [this] { return this->FormatSERDESOscillatorParameterLow(); },
    1565            0 :             [this] { return this->FormatSERDESOscillatorParameterHigh(); },
    1566            0 :             [this] { return this->FormatTimestampPreset0(); },
    1567            0 :             [this] { return this->FormatTimestampPreset1(); },
    1568            0 :             [this] { return this->FormatFIFOFullErrorFlag0(); },
    1569            0 :             [this] { return this->FormatReceivePacketError(); },
    1570              :             // [this] { return this->FormatEventWindowEmulatorIntervalTime(); },
    1571            0 :             [this] { return this->FormatEventWindowHoldoffTime(); },
    1572            0 :             [this] { return this->FormatEventWindowTimeoutError(); },
    1573            0 :             [this] { return this->FormatEventWindowTimeoutInterval(); },
    1574            0 :             [this] { return this->FormatDMAWriteStartAddress(); },
    1575            0 :             [this] { return this->FormatDMAReadStartAddress(); },
    1576            0 :             [this] { return this->FormatDMAReadByteCount(); },
    1577            0 :             [this] { return this->FormatRunPlanBeamOnBaseAddress(); },
    1578            0 :             [this] { return this->FormatRunPlanBeamOffBaseAddress(); },
    1579            0 :             [this] { return this->FormatRunPlanSubrunEvtLimit(); },
    1580            0 :             [this] { return this->FormatRunPlanSubrunPredOffset(); },
    1581            0 :             [this] { return this->FormatFireflyCSR(); },
    1582            0 :             [this] { return this->FormatSERDESPRBSControlLink0(); },
    1583            0 :             [this] { return this->FormatSERDESPRBSControlLink1(); },
    1584            0 :             [this] { return this->FormatSERDESPRBSControlLink2(); },
    1585            0 :             [this] { return this->FormatSERDESPRBSControlLink3(); },
    1586            0 :             [this] { return this->FormatSERDESPRBSControlLink4(); },
    1587            0 :             [this] { return this->FormatSERDESPRBSControlLink5(); },
    1588            0 :             [this] { return this->FormatSERDESPRBSControlLink6(); },
    1589            0 :             [this] { return this->FormatSERDESPRBSControlLink7(); },
    1590              :             // [this] { return this->FormatCableDelayValueLink0(); },
    1591              :             // [this] { return this->FormatCableDelayValueLink1(); },
    1592              :             // [this] { return this->FormatCableDelayValueLink2(); },
    1593              :             // [this] { return this->FormatCableDelayValueLink3(); },
    1594              :             // [this] { return this->FormatCableDelayValueLink4(); },
    1595              :             // [this] { return this->FormatCableDelayValueLink5(); },
    1596              :             // [this] { return this->FormatCableDelayValueLink6(); },
    1597              :             // [this] { return this->FormatCableDelayValueLink7(); },
    1598              :             // [this] { return this->FormatCableDelayControl(); },
    1599            0 :             [this] { return this->FormatFPGAPROMProgramStatus(); },
    1600            0 :             [this] { return this->FormatFPGACoreAccess(); }};
    1601              : 
    1602              :         /// <summary>
    1603              :         /// Dump Byte/Packet Counter Registers
    1604              :         /// </summary>
    1605              :         const std::vector<std::function<RegisterFormatter()>> formattedCounterFunctions_{
    1606            0 :             [this] { return this->FormatTransmitHeartbeatPacketCount(); },
    1607            0 :             [this] { return this->FormatTransmitEventWindowMarkerCount(); },
    1608            0 :             [this] { return this->FormatReceiveRF0MarkerCount(); }
    1609              :             // [this] { return this->FormatReceiveByteCountLink0(); },
    1610              :             // [this] { return this->FormatReceiveByteCountLink1(); },
    1611              :             // [this] { return this->FormatReceiveByteCountLink2(); },
    1612              :             // [this] { return this->FormatReceiveByteCountLink3(); },
    1613              :             // [this] { return this->FormatReceiveByteCountLink4(); },
    1614              :             // [this] { return this->FormatReceiveByteCountLink5(); },
    1615              :             // [this] { return this->FormatReceiveByteCountLink6(); },
    1616              :             // [this] { return this->FormatReceiveByteCountLink7(); },
    1617              :             // [this] { return this->FormatReceivePacketCountLink0(); },
    1618              :             // [this] { return this->FormatReceivePacketCountLink1(); },
    1619              :             // [this] { return this->FormatReceivePacketCountLink2(); },
    1620              :             // [this] { return this->FormatReceivePacketCountLink3(); },
    1621              :             // [this] { return this->FormatReceivePacketCountLink4(); },
    1622              :             // [this] { return this->FormatReceivePacketCountLink5(); },
    1623              :             // [this] { return this->FormatReceivePacketCountLink6(); },
    1624              :             // [this] { return this->FormatReceivePacketCountLink7(); },
    1625              :             // [this] { return this->FormatTramsitByteCountLink0(); },
    1626              :             // [this] { return this->FormatTramsitByteCountLink1(); },
    1627              :             // [this] { return this->FormatTramsitByteCountLink2(); },
    1628              :             // [this] { return this->FormatTramsitByteCountLink3(); },
    1629              :             // [this] { return this->FormatTramsitByteCountLink4(); },
    1630              :             // [this] { return this->FormatTramsitByteCountLink5(); },
    1631              :             // [this] { return this->FormatTramsitByteCountLink6(); },
    1632              :             // [this] { return this->FormatTramsitByteCountLink7(); },
    1633              :             // [this] { return this->FormatTransmitPacketCountLink0(); },
    1634              :             // [this] { return this->FormatTransmitPacketCountLink1(); },
    1635              :             // [this] { return this->FormatTransmitPacketCountLink2(); },
    1636              :             // [this] { return this->FormatTransmitPacketCountLink3(); },
    1637              :             // [this] { return this->FormatTransmitPacketCountLink4(); },
    1638              :             // [this] { return this->FormatTransmitPacketCountLink5(); },
    1639              :             // [this] { return this->FormatTransmitPacketCountLink6(); },
    1640              :             // [this] { return this->FormatTransmitPacketCountLink7(); }
    1641              :         };
    1642              : };
    1643              : }  // namespace CFOLib
    1644              : 
    1645              : #endif  // CFO_REGISTERS_H
        

Generated by: LCOV version 2.0-1