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 % 73 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 72 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              :         CFO_Register_NUMDTCs                   = 0x918C,
      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              :         /// <param name="dtcCount">Number of DTCs in the Link (Default: 0)</param>
     305            0 :         void EnableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode = DTC_LinkEnableMode(), const uint8_t& dtcCount = 0);
     306              : 
     307              :         /// <summary>
     308              :         /// Disable a SERDES Link
     309              :         /// The given mode bits will be UNSET
     310              :         /// </summary>
     311              :         /// <param name="link">Link to disable</param>
     312              :         /// <param name="mode">Link enable bits to unset (Default: All)</param>
     313              :         void DisableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode = DTC_LinkEnableMode());
     314              :         /// <summary>
     315              :         /// Read the Link Enable bits for a given SERDES Link
     316              :         /// </summary>
     317              :         /// <param name="link">Link to read</param>
     318              :         /// <returns>DTC_LinkEnableMode containing TX, RX, and CFO bits</returns>
     319              :         DTC_LinkEnableMode ReadLinkEnabled(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     320              :         /// <summary>
     321              :         /// Formats the register's current value for register dumps
     322              :         /// </summary>
     323              :         /// <returns>RegisterFormatter object containing register information</returns>
     324              :         RegisterFormatter FormatLinkEnable();
     325              : 
     326              :         // SERDES Reset Register
     327              :         /// <summary>
     328              :         /// Reset the SERDES
     329              :         /// Will poll the Reset SERDES Done flag until the SERDES reset is complete
     330              :         /// </summary>
     331              :         /// <param name="link">Link to reset</param>
     332              :         /// <param name="interval">Pollint interval, in microseconds</param>
     333              :         void ResetSERDES(const CFO_Link_ID& link, int interval = 100000);
     334              :         /// <summary>
     335              :         /// Reset all SERDES PLLs
     336              :         /// </summary>
     337              :         void ResetAllSERDESPlls();
     338              :         /// <summary>
     339              :         /// Reset all SERDES Tx
     340              :         /// </summary>
     341              :         void ResetAllSERDESTx();
     342              :         /// <summary>
     343              :         /// Read if a SERDES reset is currently in progress
     344              :         /// </summary>
     345              :         /// <param name="link">Link to read</param>
     346              :         /// <returns>True if a SERDES reset is in progress</returns>
     347              :         bool ReadResetSERDES(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     348              :         /// <summary>
     349              :         /// Formats the register's current value for register dumps
     350              :         /// </summary>
     351              :         /// <returns>RegisterFormatter object containing register information</returns>
     352              :         RegisterFormatter FormatSERDESReset();
     353              : 
     354              :         // SERDES RX Disparity Error Register
     355              :         /// <summary>
     356              :         /// Read the SERDES RX Dispatity Error bits
     357              :         /// </summary>
     358              :         /// <param name="link">Link to read</param>
     359              :         /// <returns>CFO_SERDESRXDisparityError object with error bits</returns>
     360              :         DTC_SERDESRXDisparityError ReadSERDESRXDisparityError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     361              :         /// <summary>
     362              :         /// Formats the register's current value for register dumps
     363              :         /// </summary>
     364              :         /// <returns>RegisterFormatter object containing register information</returns>
     365              :         RegisterFormatter FormatSERDESRXDisparityError();
     366              : 
     367              :         // SERDES Character Not In Table Error Register
     368              :         /// <summary>
     369              :         /// Read the SERDES Character Not In Table Error bits
     370              :         /// </summary>
     371              :         /// <param name="link">Link to read</param>
     372              :         /// <returns>CFO_CharacterNotInTableError object with error bits</returns>
     373              :         DTC_CharacterNotInTableError ReadSERDESRXCharacterNotInTableError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     374              :         /// <summary>
     375              :         /// Formats the register's current value for register dumps
     376              :         /// </summary>
     377              :         /// <returns>RegisterFormatter object containing register information</returns>
     378              :         RegisterFormatter FormatSERDESRXCharacterNotInTableError();
     379              : 
     380              :         // SERDES Unlock Error Register
     381              :         /// <summary>
     382              :         /// Read whether the SERDES Unlock Error bit is set
     383              :         /// </summary>
     384              :         /// <param name="link">Link to check</param>
     385              :         /// <returns>True if the SERDES Unlock Error bit is set on the given Link</returns>
     386              :         bool ReadSERDESUnlockError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     387              :         /// <summary>
     388              :         /// Formats the register's current value for register dumps
     389              :         /// </summary>
     390              :         /// <returns>RegisterFormatter object containing register information</returns>
     391              :         RegisterFormatter FormatSERDESUnlockError();
     392              : 
     393              :         // SERDES PLL Locked Register
     394              :         /// <summary>
     395              :         /// Read if the SERDES PLL is locked for the given SERDES Link
     396              :         /// </summary>
     397              :         /// <param name="link">Link to read</param>
     398              :         /// <returns>True if the PLL is locked, false otherwise</returns>
     399              :         bool ReadSERDESPLLLocked(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     400              :         /// <summary>
     401              :         /// Formats the register's current value for register dumps
     402              :         /// </summary>
     403              :         /// <returns>RegisterFormatter object containing register information</returns>
     404              :         RegisterFormatter FormatSERDESPLLLocked();
     405              : 
     406              :         // SERDES RX Status Register
     407              :         /// <summary>
     408              :         /// Read the SERDES RX Status for the given SERDES Link
     409              :         /// </summary>
     410              :         /// <param name="link">Link to read</param>
     411              :         /// <returns>CFO_RXStatus object</returns>
     412              :         DTC_RXStatus ReadSERDESRXStatus(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     413              :         /// <summary>
     414              :         /// Formats the register's current value for register dumps
     415              :         /// </summary>
     416              :         /// <returns>RegisterFormatter object containing register information</returns>
     417              :         RegisterFormatter FormatSERDESRXStatus();
     418              : 
     419              :         // SERDES Reset Done Register
     420              :         /// <summary>
     421              :         /// Read if the SERDES reset is complete on the given SERDES Link
     422              :         /// </summary>
     423              :         /// <param name="link">Link to read</param>
     424              :         /// <returns>True if the SERDES Reset is done, false otherwise</returns>
     425              :         bool ReadResetSERDESDone(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     426              :         /// <summary>
     427              :         /// Formats the register's current value for register dumps
     428              :         /// </summary>
     429              :         /// <returns>RegisterFormatter object containing register information</returns>
     430              :         RegisterFormatter FormatSERDESResetDone();
     431              : 
     432              :         // SERDES RX CDR Lock Register
     433              :         /// <summary>
     434              :         /// Read the SERDES CDR Lock bit for the given SERDES Link
     435              :         /// </summary>
     436              :         /// <param name="link">Link to read</param>
     437              :         /// <returns>True if the SERDES CDR Lock bit is set</returns>
     438              :         bool ReadSERDESRXCDRLock(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     439              :         /// <summary>
     440              :         /// Formats the register's current value for register dumps
     441              :         /// </summary>
     442              :         /// <returns>RegisterFormatter object containing register information</returns>
     443              :         RegisterFormatter FormatSERDESRXCDRLock();
     444              : 
     445              :         // Beam On Timer Preset Regsiter
     446              :         /// <summary>
     447              :         /// Set the maximum time a DMA buffer may be active before it is sent, in 4ns ticks.
     448              :         /// The default value is 0x800
     449              :         /// </summary>
     450              :         /// <param name="preset">Maximum active time for DMA buffers</param>
     451              :         void SetBeamOnTimerPreset(uint32_t preset);
     452              :         /// <summary>
     453              :         /// Read the maximum time a DMA buffer may be active before it is sent, in 4ns ticks.
     454              :         /// The default value is 0x800
     455              :         /// </summary>
     456              :         /// <returns>Maximum active time for DMA buffers</returns>
     457              :         uint32_t ReadBeamOnTimerPreset(std::optional<uint32_t> val = std::nullopt);
     458              :         /// <summary>
     459              :         /// Formats the register's current value for register dumps
     460              :         /// </summary>
     461              :         /// <returns>RegisterFormatter object containing register information</returns>
     462              :         RegisterFormatter FormatBeamOnTimerPreset();
     463              : 
     464              :         // Enable Beam On Mode Register
     465              :         /// <summary>
     466              :         /// Set the Beam On Mode Enable bit for the given link
     467              :         /// </summary>
     468              :         /// <param name="link">Link to enable</param>
     469              :         void EnableBeamOnMode(const CFO_Link_ID& link);
     470              :         /// <summary>
     471              :         /// Clear the Beam On Mode Enable bit for the given link
     472              :         /// </summary>
     473              :         /// <param name="link">Link to disable</param>
     474              :         void DisableBeamOnMode(const CFO_Link_ID& link);
     475              :         /// <summary>
     476              :         /// Read the global Beam On Mode Enable bit
     477              :         /// </summary>
     478              :         /// <param name="val">Optional register value to use instead of reading from hardware</param>
     479              :         /// <returns>Value of the Beam On Mode Enable bit</returns>
     480              :         bool ReadBeamOnMode(std::optional<uint32_t> val = std::nullopt);
     481              :         /// <summary>
     482              :         /// Formats the register's current value for register dumps
     483              :         /// </summary>
     484              :         /// <returns>RegisterFormatter object containing register information</returns>
     485              :         RegisterFormatter FormatBeamOnMode();
     486              : 
     487              :         // Enable Beam Off Mode Register
     488              :         /// <summary>
     489              :         /// Set the Beam Off Mode Enable bit for the given link
     490              :         /// </summary>
     491              :         /// <param name="link">Link to enable</param>
     492              :         void EnableBeamOffMode(const CFO_Link_ID& link);
     493              :         /// <summary>
     494              :         /// Clear the Beam Off Mode Enable bit for the given link
     495              :         /// </summary>
     496              :         /// <param name="link">Link to disable</param>
     497              :         void DisableBeamOffMode(const CFO_Link_ID& link);
     498              :         /// <summary>
     499              :         /// Read the global Beam Off Mode Enable bit
     500              :         /// </summary>
     501              :         /// <returns>Value of the global Beam Off Mode Enable bit</returns>
     502              :         bool ReadBeamOffMode(std::optional<uint32_t> val = std::nullopt);
     503              :         /// <summary>
     504              :         /// Formats the register's current value for register dumps
     505              :         /// </summary>
     506              :         /// <returns>RegisterFormatter object containing register information</returns>
     507              :         RegisterFormatter FormatBeamOffMode();
     508              : 
     509              :         // LEGACY: 40 MHz Clock Marker Interval Count Register (register 0x9154 repurposed as RunPlanSubrunEvtLimit)
     510              :         // /// <summary>
     511              :         // /// Set the Clock Marker Interval Count for synchronizing the 240 MHz and 40 MHz clocks
     512              :         // /// </summary>
     513              :         // /// <param name="data">Interval to set</param>
     514              :         // void SetClockMarkerIntervalCount(uint32_t data);
     515              :         // /// <summary>
     516              :         // /// Read the Clock Marker Interval Count used for synchronizing the 240 MHz and 40 MHz clocks
     517              :         // /// </summary>
     518              :         // /// <returns>The Clock Marker Interval Count used for synchronizing the 240 MHz and 40 MHz clocks</returns>
     519              :         // uint32_t ReadClockMarkerIntervalCount(std::optional<uint32_t> val = std::nullopt);
     520              :         // /// <summary>
     521              :         // /// Formats the register's current value for register dumps
     522              :         // /// </summary>
     523              :         // /// <returns>RegisterFormatter object containing register information</returns>
     524              :         // RegisterFormatter FormatClockMarkerIntervalCount();
     525              : 
     526              :         // SERDES Oscillator Registers
     527              :         /// <summary>
     528              :         /// Read the current SERDES Oscillator frequency, in Hz
     529              :         /// </summary>
     530              :         /// <returns>Current SERDES Oscillator frequency, in Hz</returns>
     531              :         uint32_t ReadSERDESOscillatorFrequency(std::optional<uint32_t> val = std::nullopt);
     532              :         /// <summary>
     533              :         /// Set the SERDES Oscillator frequency
     534              :         /// </summary>
     535              :         /// <param name="freq">New frequency, in Hz</param>
     536              :         void SetSERDESOscillatorFrequency(uint32_t freq);
     537              :         /// <summary>
     538              :         /// Read the Reset bit of the SERDES IIC Bus
     539              :         /// </summary>
     540              :         /// <returns>Reset bit value</returns>
     541              :         bool ReadSERDESOscillatorIICInterfaceReset(std::optional<uint32_t> val = std::nullopt);
     542              :         /// <summary>
     543              :         /// Reset the SERDES IIC Bus
     544              :         /// </summary>
     545              :         void ResetSERDESOscillatorIICInterface();
     546              : 
     547              :         // Jitter Attenuator CSR Register
     548              :         virtual std::bitset<2>    ReadJitterAttenuatorSelect(std::optional<uint32_t> val = std::nullopt) override;
     549              :         virtual void              SetJitterAttenuatorSelect(std::bitset<2> data, bool alsoResetJA = false) override;
     550              :         virtual bool              ReadJitterAttenuatorReset(std::optional<uint32_t> val = std::nullopt) override;
     551              :         virtual bool              ReadJitterAttenuatorLocked(std::optional<uint32_t> val = std::nullopt) override;
     552              :         virtual void              ResetJitterAttenuator() override;
     553              :         virtual RegisterFormatter FormatJitterAttenuatorCSR() override;
     554              : 
     555              :         /// <summary>
     556              :         /// Read the current Oscillator program for the SERDES Oscillator
     557              :         /// </summary>
     558              :         /// <returns>SERDES Oscillator Program</returns>
     559              :         uint64_t ReadSERDESOscillatorParameters(std::optional<uint32_t> val = std::nullopt);
     560              :         /// <summary>
     561              :         /// Set the SERDES Oscillator program
     562              :         /// </summary>
     563              :         /// <param name="program">New program for the SERDES Oscillator</param>
     564              :         void SetSERDESOscillatorParameters(uint64_t program);
     565              :         /// <summary>
     566              :         /// Read the current SERDES Oscillator clock speed
     567              :         /// </summary>
     568              :         /// <returns>Current SERDES clock speed</returns>
     569              :         DTC_SerdesClockSpeed ReadSERDESOscillatorClock(std::optional<uint32_t> val = std::nullopt);
     570              :         /// <summary>
     571              :         /// Set the SERDES Oscillator clock speed for the given SERDES transfer rate
     572              :         /// </summary>
     573              :         /// <param name="speed">Clock speed to set</param>
     574              :         void SetSERDESOscillatorClock(DTC_SerdesClockSpeed speed);
     575              :         /// <summary>
     576              :         /// Formats the register's current value for register dumps
     577              :         /// </summary>
     578              :         /// <returns>RegisterFormatter object containing register information</returns>
     579              :         RegisterFormatter FormatSERDESOscillatorFrequency();
     580              :         /// <summary>
     581              :         /// Formats the register's current value for register dumps
     582              :         /// </summary>
     583              :         /// <returns>RegisterFormatter object containing register information</returns>
     584              :         RegisterFormatter FormatSERDESOscillatorControl();
     585              : 
     586              :         // Timestamp Preset Registers
     587              :         /// <summary>
     588              :         /// Set the Timestamp preset for Timing system emulation mode
     589              :         /// </summary>
     590              :         /// <param name="preset">Timestamp for Timing emulation</param>
     591              :         void SetEventWindowTagPreset(const DTC_EventWindowTag& preset);
     592              :         /// <summary>
     593              :         /// Read the Timestamp preset for Timing system emulation mode
     594              :         /// </summary>
     595              :         /// <returns>Timestamp preset</returns>
     596              :         DTC_EventWindowTag ReadTimestampPreset(std::optional<uint32_t> val = std::nullopt);
     597              :         /// <summary>
     598              :         /// Formats the register's current value for register dumps
     599              :         /// </summary>
     600              :         /// <returns>RegisterFormatter object containing register information</returns>
     601              :         RegisterFormatter FormatTimestampPreset0();
     602              :         /// <summary>
     603              :         /// Formats the register's current value for register dumps
     604              :         /// </summary>
     605              :         /// <returns>RegisterFormatter object containing register information</returns>
     606              :         RegisterFormatter FormatTimestampPreset1();
     607              : 
     608              :         /// <summary>
     609              :         /// Writes the current Linux time (seconds since the Unix epoch) to the LinuxTimestamp register.
     610              :         /// </summary>
     611              :         void SetLinuxTimestampPreset();
     612              :         /// <summary>
     613              :         /// Reads the LinuxTimestamp register.
     614              :         /// </summary>
     615              :         /// <returns>The timestamp value stored in the register, in seconds since the Unix epoch</returns>
     616              :         time_t ReadLinuxTimestamp();
     617              : 
     618              :         // NUMDTCs Register
     619              :         /// <summary>
     620              :         /// Set the maximum ROC ID for the given Link
     621              :         /// </summary>
     622              :         /// <param name="link">Link to set</param>
     623              :         /// <param name="dtcCount">Number of DTCs on the link</param>
     624              :         void SetMaxDTCNumber(const CFO_Link_ID& link, const uint8_t& dtcCount);
     625              :         /// <summary>
     626              :         /// Read the number of ROCs configured on the given Link
     627              :         /// </summary>
     628              :         /// <param name="link">Link to read</param>
     629              :         /// <param name="local">Whether to use the NUMDTCs virtual register or perform a register access (Default: true, use
     630              :         /// virtual register)</param> <returns>Number of DTCs on the link</returns>
     631              :         uint8_t ReadLinkDTCCount(const CFO_Link_ID& link, bool local = true, std::optional<uint32_t> val = std::nullopt);
     632              :         /// <summary>
     633              :         /// Formats the register's current value for register dumps
     634              :         /// </summary>
     635              :         /// <returns>RegisterFormatter object containing register information</returns>
     636              :         RegisterFormatter FormatNUMDTCs();
     637              : 
     638              :         // FIFO Full Error Flags Registers
     639              :         /// <summary>
     640              :         /// Clear all FIFO Full Error Flags for the given Link
     641              :         /// </summary>
     642              :         /// <param name="link">Link to clear</param>
     643              :         void ClearFIFOFullErrorFlags(const CFO_Link_ID& link);
     644              :         /// <summary>
     645              :         /// Read the FIFO Full Error/Status Flags for the given Link
     646              :         /// </summary>
     647              :         /// <param name="link">Link to read</param>
     648              :         /// <returns>CFO_FIFOFullErrorFlags object</returns>
     649              :         DTC_FIFOFullErrorFlags ReadFIFOFullErrorFlags(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     650              :         /// <summary>
     651              :         /// Formats the register's current value for register dumps
     652              :         /// </summary>
     653              :         /// <returns>RegisterFormatter object containing register information</returns>
     654              :         RegisterFormatter FormatFIFOFullErrorFlag0();
     655              : 
     656              :         // Receive Packet Error Register
     657              :         /// <summary>
     658              :         /// Clear the RX Elastic Buffer Underrun Error Flag for the given Link
     659              :         /// </summary>
     660              :         /// <param name="link">Link to clear</param>
     661              :         void ClearRXElasticBufferUnderrun(const CFO_Link_ID& link);
     662              :         /// <summary>
     663              :         /// Read the RX Elastic Buffer Underrun Error Flag for the given Link
     664              :         /// </summary>
     665              :         /// <param name="link">Link to read</param>
     666              :         /// <returns>True if the RX Elastic Buffer Underrun Error Flag is set</returns>
     667              :         bool ReadRXElasticBufferUnderrun(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     668              :         /// <summary>
     669              :         /// Clear the RX Elastic Buffer Overrun Error Flag for the given Link
     670              :         /// </summary>
     671              :         /// <param name="link">Link to clear</param>
     672              :         void ClearRXElasticBufferOverrun(const CFO_Link_ID& link);
     673              :         /// <summary>
     674              :         /// Read the RX Elastic Buffer Overrun Error Flag for the given Link
     675              :         /// </summary>
     676              :         /// <param name="link">Link to read</param>
     677              :         /// <returns>True if the RX Elastic Buffer Overrun Error Flag is set</returns>
     678              :         bool ReadRXElasticBufferOverrun(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     679              :         /// <summary>
     680              :         /// Clear the Packet Error Flag for the given Link
     681              :         /// </summary>
     682              :         /// <param name="link">Link to clear</param>
     683              :         void ClearPacketError(const CFO_Link_ID& link);
     684              :         /// <summary>
     685              :         /// Read the Packet Error Flag for the given Link
     686              :         /// </summary>
     687              :         /// <param name="link">Link to read</param>
     688              :         /// <returns>True if the Packet Error Flag is set</returns>
     689              :         bool ReadPacketError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     690              :         /// <summary>
     691              :         /// Clear the Packet CRC Error Flag for the given Link
     692              :         /// </summary>
     693              :         /// <param name="link">Link to clear</param>
     694              :         void ClearPacketCRCError(const CFO_Link_ID& link);
     695              :         /// <summary>
     696              :         /// Read the Packet CRC Error Flag for the given Link
     697              :         /// </summary>
     698              :         /// <param name="link">Link to read</param>
     699              :         /// <returns>True if the Packet CRC Error Flag is set</returns>
     700              :         bool ReadPacketCRCError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     701              :         /// <summary>
     702              :         /// Formats the register's current value for register dumps
     703              :         /// </summary>
     704              :         /// <returns>RegisterFormatter object containing register information</returns>
     705              :         RegisterFormatter FormatReceivePacketError();
     706              : 
     707              :         // Event Window Emulator (Beam Off) Interval Time Register
     708              :         /// <summary>
     709              :         /// Set the Event Window Emulator (Beam Off) Interval
     710              :         /// </summary>
     711              :         /// <param name="data">Interval to set</param>
     712              :         void SetEventWindowEmulatorInterval(const uint32_t& data);
     713              :         /// <summary>
     714              :         /// Read the Event Window Emulator (Beam Off) Interval
     715              :         /// </summary>
     716              :         /// <returns>The Event Window Emulator (Beam Off) Interval</returns>
     717              :         uint32_t ReadEventWindowEmulatorInterval(std::optional<uint32_t> val = std::nullopt);
     718              :         /// <summary>
     719              :         /// Formats the register's current value for register dumps
     720              :         /// </summary>
     721              :         /// <returns>RegisterFormatter object containing register information</returns>
     722              :         RegisterFormatter FormatEventWindowEmulatorIntervalTime();
     723              : 
     724              :         // Event Window Holdoff Time Register
     725              :         /// <summary>
     726              :         /// Set the holdoff time (minimum dead time before Beam On)
     727              :         /// </summary>
     728              :         /// <param name="data">New value of the holdoff time parameter</param>
     729              :         void SetEventWindowHoldoffTime(const uint32_t& data);
     730              :         /// <summary>
     731              :         /// Read the current Event Window Holdoff time (minimum dead time before Beam On)
     732              :         /// </summary>
     733              :         /// <returns>The current Event Window Holdoff time (minimum dead time before Beam On)</returns>
     734              :         uint32_t ReadEventWindowHoldoffTime(std::optional<uint32_t> val = std::nullopt);
     735              :         /// <summary>
     736              :         /// Formats the register's current value for register dumps
     737              :         /// </summary>
     738              :         /// <returns>RegisterFormatter object containing register information</returns>
     739              :         RegisterFormatter FormatEventWindowHoldoffTime();
     740              : 
     741              :         // Event Window Timeout Error Register
     742              :         /// <summary>
     743              :         /// Read the Event Window Timeout Error bit for the given link
     744              :         /// </summary>
     745              :         /// <param name="link">Link to read</param>
     746              :         /// <returns>Value of the Event Window Timeout Error bit for the given link</returns>
     747              :         bool ReadEventWindowTimeoutError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     748              :         /// <summary>
     749              :         /// Clear the Event Window Timeout Error bit for the given link
     750              :         /// </summary>
     751              :         /// <param name="link">Link to clear</param>
     752              :         void ClearEventWindowTimeoutError(const CFO_Link_ID& link);
     753              :         /// <summary>
     754              :         /// Formats the register's current value for register dumps
     755              :         /// </summary>
     756              :         /// <returns>RegisterFormatter object containing register information</returns>
     757              :         RegisterFormatter FormatEventWindowTimeoutError();
     758              : 
     759              :         // Event Window Timeout Interval Register
     760              :         /// <summary>
     761              :         /// Set the Event Window Timeout Interval
     762              :         /// </summary>
     763              :         /// <param name="data">New Event Window Timeout Interval</param>
     764              :         void SetEventWindowTimeoutInterval(const uint32_t& data);
     765              :         /// <summary>
     766              :         /// Read the Event Window Timeout Interval
     767              :         /// </summary>
     768              :         /// <returns>The Event Window Timeout Interval</returns>
     769              :         uint32_t ReadEventWindowTimeoutInterval(std::optional<uint32_t> val = std::nullopt);
     770              :         /// <summary>
     771              :         /// Formats the register's current value for register dumps
     772              :         /// </summary>
     773              :         /// <returns>RegisterFormatter object containing register information</returns>
     774              :         RegisterFormatter FormatEventWindowTimeoutInterval();
     775              : 
     776              :         uint32_t          ReadReceiveRF0MarkerCount(std::optional<uint32_t> val = std::nullopt);
     777              :         uint32_t          ReadTransmitHeartbeatPacketCount(std::optional<uint32_t> val = std::nullopt);
     778              :         uint32_t          ReadTransmitEventWindowMarkerCount(std::optional<uint32_t> val = std::nullopt);
     779              :         RegisterFormatter FormatReceiveRF0MarkerCount();
     780              :         RegisterFormatter FormatTransmitHeartbeatPacketCount();
     781              :         RegisterFormatter FormatTransmitEventWindowMarkerCount();
     782              : 
     783              :         /// <summary>
     784              :         /// Clear the value of the Receive byte counter
     785              :         /// </summary>
     786              :         /// <param name="link">Link to clear counter for</param>
     787              :         void ClearReceiveByteCount(const CFO_Link_ID& link);
     788              :         /// <summary>
     789              :         /// Read the value of the Receive byte counter
     790              :         /// </summary>
     791              :         /// <param name="link">Link to read counter for</param>
     792              :         /// <returns>Current value of the Receive byte counter on the given Link</returns>
     793              :         uint32_t ReadReceiveByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     794              :         /// <summary>
     795              :         /// Clear the value of the Receive Packet counter
     796              :         /// </summary>
     797              :         /// <param name="link">Link to clear counter for</param>
     798              :         void ClearReceivePacketCount(const CFO_Link_ID& link);
     799              :         /// <summary>
     800              :         /// Read the value of the Receive Packet counter
     801              :         /// </summary>
     802              :         /// <param name="link">Link to read counter for</param>
     803              :         /// <returns>Current value of the Receive Packet counter on the given Link</returns>
     804              :         uint32_t ReadReceivePacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     805              :         /// <summary>
     806              :         /// Clear the value of the Transmit byte counter
     807              :         /// </summary>
     808              :         /// <param name="link">Link to clear counter for</param>
     809              :         void ClearTransmitByteCount(const CFO_Link_ID& link);
     810              :         /// <summary>
     811              :         /// Read the value of the Transmit byye counter
     812              :         /// </summary>
     813              :         /// <param name="link">Link to read counter for</param>
     814              :         /// <returns>Current value of the Transmit byte counter on the given Link</returns>
     815              :         uint32_t ReadTransmitByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     816              :         /// <summary>
     817              :         /// Clear the value of the Transmit Packet counter
     818              :         /// </summary>
     819              :         /// <param name="link">Link to clear counter for</param>
     820              :         void ClearTransmitPacketCount(const CFO_Link_ID& link);
     821              :         /// <summary>
     822              :         /// Read the value of the Transmit Packet counter
     823              :         /// </summary>
     824              :         /// <param name="link">Link to read counter for</param>
     825              :         /// <returns>Current value of the Transmit Packet counter on the given Link</returns>
     826              :         uint32_t ReadTransmitPacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
     827              :         /// <summary>
     828              :         /// Formats the register's current value for register dumps
     829              :         /// </summary>
     830              :         /// <returns>RegisterFormatter object containing register information</returns>
     831              :         RegisterFormatter FormatReceiveByteCountLink0();
     832              :         /// <summary>
     833              :         /// Formats the register's current value for register dumps
     834              :         /// </summary>
     835              :         /// <returns>RegisterFormatter object containing register information</returns>
     836              :         RegisterFormatter FormatReceiveByteCountLink1();
     837              :         /// <summary>
     838              :         /// Formats the register's current value for register dumps
     839              :         /// </summary>
     840              :         /// <returns>RegisterFormatter object containing register information</returns>
     841              :         RegisterFormatter FormatReceiveByteCountLink2();
     842              :         /// <summary>
     843              :         /// Formats the register's current value for register dumps
     844              :         /// </summary>
     845              :         /// <returns>RegisterFormatter object containing register information</returns>
     846              :         RegisterFormatter FormatReceiveByteCountLink3();
     847              :         /// <summary>
     848              :         /// Formats the register's current value for register dumps
     849              :         /// </summary>
     850              :         /// <returns>RegisterFormatter object containing register information</returns>
     851              :         RegisterFormatter FormatReceiveByteCountLink4();
     852              :         /// <summary>
     853              :         /// Formats the register's current value for register dumps
     854              :         /// </summary>
     855              :         /// <returns>RegisterFormatter object containing register information</returns>
     856              :         RegisterFormatter FormatReceiveByteCountLink5();
     857              :         /// <summary>
     858              :         /// Formats the register's current value for register dumps
     859              :         /// </summary>
     860              :         /// <returns>RegisterFormatter object containing register information</returns>
     861              :         RegisterFormatter FormatReceiveByteCountLink6();
     862              :         /// <summary>
     863              :         /// Formats the register's current value for register dumps
     864              :         /// </summary>
     865              :         /// <returns>RegisterFormatter object containing register information</returns>
     866              :         RegisterFormatter FormatReceiveByteCountLink7();
     867              :         /// <summary>
     868              :         /// Formats the register's current value for register dumps
     869              :         /// </summary>
     870              :         /// <returns>RegisterFormatter object containing register information</returns>
     871              :         RegisterFormatter FormatReceivePacketCountLink0();
     872              :         /// <summary>
     873              :         /// Formats the register's current value for register dumps
     874              :         /// </summary>
     875              :         /// <returns>RegisterFormatter object containing register information</returns>
     876              :         RegisterFormatter FormatReceivePacketCountLink1();
     877              :         /// <summary>
     878              :         /// Formats the register's current value for register dumps
     879              :         /// </summary>
     880              :         /// <returns>RegisterFormatter object containing register information</returns>
     881              :         RegisterFormatter FormatReceivePacketCountLink2();
     882              :         /// <summary>
     883              :         /// Formats the register's current value for register dumps
     884              :         /// </summary>
     885              :         /// <returns>RegisterFormatter object containing register information</returns>
     886              :         RegisterFormatter FormatReceivePacketCountLink3();
     887              :         /// <summary>
     888              :         /// Formats the register's current value for register dumps
     889              :         /// </summary>
     890              :         /// <returns>RegisterFormatter object containing register information</returns>
     891              :         RegisterFormatter FormatReceivePacketCountLink4();
     892              :         /// <summary>
     893              :         /// Formats the register's current value for register dumps
     894              :         /// </summary>
     895              :         /// <returns>RegisterFormatter object containing register information</returns>
     896              :         RegisterFormatter FormatReceivePacketCountLink5();
     897              :         /// <summary>
     898              :         /// Formats the register's current value for register dumps
     899              :         /// </summary>
     900              :         /// <returns>RegisterFormatter object containing register information</returns>
     901              :         RegisterFormatter FormatReceivePacketCountLink6();
     902              :         /// <summary>
     903              :         /// Formats the register's current value for register dumps
     904              :         /// </summary>
     905              :         /// <returns>RegisterFormatter object containing register information</returns>
     906              :         RegisterFormatter FormatReceivePacketCountLink7();
     907              :         /// <summary>
     908              :         /// Formats the register's current value for register dumps
     909              :         /// </summary>
     910              :         /// <returns>RegisterFormatter object containing register information</returns>
     911              :         RegisterFormatter FormatTramsitByteCountLink0();
     912              :         /// <summary>
     913              :         /// Formats the register's current value for register dumps
     914              :         /// </summary>
     915              :         /// <returns>RegisterFormatter object containing register information</returns>
     916              :         RegisterFormatter FormatTramsitByteCountLink1();
     917              :         /// <summary>
     918              :         /// Formats the register's current value for register dumps
     919              :         /// </summary>
     920              :         /// <returns>RegisterFormatter object containing register information</returns>
     921              :         RegisterFormatter FormatTramsitByteCountLink2();
     922              :         /// <summary>
     923              :         /// Formats the register's current value for register dumps
     924              :         /// </summary>
     925              :         /// <returns>RegisterFormatter object containing register information</returns>
     926              :         RegisterFormatter FormatTramsitByteCountLink3();
     927              :         /// <summary>
     928              :         /// Formats the register's current value for register dumps
     929              :         /// </summary>
     930              :         /// <returns>RegisterFormatter object containing register information</returns>
     931              :         RegisterFormatter FormatTramsitByteCountLink4();
     932              :         /// <summary>
     933              :         /// Formats the register's current value for register dumps
     934              :         /// </summary>
     935              :         /// <returns>RegisterFormatter object containing register information</returns>
     936              :         RegisterFormatter FormatTramsitByteCountLink5();
     937              :         /// <summary>
     938              :         /// Formats the register's current value for register dumps
     939              :         /// </summary>
     940              :         /// <returns>RegisterFormatter object containing register information</returns>
     941              :         RegisterFormatter FormatTramsitByteCountLink6();
     942              :         /// <summary>
     943              :         /// Formats the register's current value for register dumps
     944              :         /// </summary>
     945              :         /// <returns>RegisterFormatter object containing register information</returns>
     946              :         RegisterFormatter FormatTramsitByteCountLink7();
     947              :         /// <summary>
     948              :         /// Formats the register's current value for register dumps
     949              :         /// </summary>
     950              :         /// <returns>RegisterFormatter object containing register information</returns>
     951              :         RegisterFormatter FormatTransmitPacketCountLink0();
     952              :         /// <summary>
     953              :         /// Formats the register's current value for register dumps
     954              :         /// </summary>
     955              :         /// <returns>RegisterFormatter object containing register information</returns>
     956              :         RegisterFormatter FormatTransmitPacketCountLink1();
     957              :         /// <summary>
     958              :         /// Formats the register's current value for register dumps
     959              :         /// </summary>
     960              :         /// <returns>RegisterFormatter object containing register information</returns>
     961              :         RegisterFormatter FormatTransmitPacketCountLink2();
     962              :         /// <summary>
     963              :         /// Formats the register's current value for register dumps
     964              :         /// </summary>
     965              :         /// <returns>RegisterFormatter object containing register information</returns>
     966              :         RegisterFormatter FormatTransmitPacketCountLink3();
     967              :         /// <summary>
     968              :         /// Formats the register's current value for register dumps
     969              :         /// </summary>
     970              :         /// <returns>RegisterFormatter object containing register information</returns>
     971              :         RegisterFormatter FormatTransmitPacketCountLink4();
     972              :         /// <summary>
     973              :         /// Formats the register's current value for register dumps
     974              :         /// </summary>
     975              :         /// <returns>RegisterFormatter object containing register information</returns>
     976              :         RegisterFormatter FormatTransmitPacketCountLink5();
     977              :         /// <summary>
     978              :         /// Formats the register's current value for register dumps
     979              :         /// </summary>
     980              :         /// <returns>RegisterFormatter object containing register information</returns>
     981              :         RegisterFormatter FormatTransmitPacketCountLink6();
     982              :         /// <summary>
     983              :         /// Formats the register's current value for register dumps
     984              :         /// </summary>
     985              :         /// <returns>RegisterFormatter object containing register information</returns>
     986              :         RegisterFormatter FormatTransmitPacketCountLink7();
     987              : 
     988              :         // DDR3 Memory DMA Write Start Address Register
     989              :         /// <summary>
     990              :         /// Set the Write Start Address for DMAs into the DDR memory
     991              :         /// </summary>
     992              :         /// <param name="address">Start address</param>
     993              :         void SetDMAWriteStartAddress(const uint32_t& address);
     994              :         /// <summary>
     995              :         /// Read the Write Start Address for DMAs into the DDR memory
     996              :         /// </summary>
     997              :         /// <returns>Start Address</returns>
     998              :         uint32_t ReadDMAWriteStartAddress(std::optional<uint32_t> val = std::nullopt);
     999              :         /// <summary>
    1000              :         /// Formats the register's current value for register dumps
    1001              :         /// </summary>
    1002              :         /// <returns>RegisterFormatter object containing register information</returns>
    1003              :         RegisterFormatter FormatDMAWriteStartAddress();
    1004              : 
    1005              :         // DDR3 Memory DMA Read Start Address Register
    1006              :         /// <summary>
    1007              :         /// Set the Read Start Address for DMAs into the DDR memory
    1008              :         /// </summary>
    1009              :         /// <param name="address">Start address</param>
    1010              :         void SetDMAReadStartAddress(const uint32_t& address);
    1011              :         /// <summary>
    1012              :         /// Read the Read Start Address for DMAs into the DDR memory
    1013              :         /// </summary>
    1014              :         /// <returns>Start Address</returns>
    1015              :         uint32_t ReadDMAReadStartAddress(std::optional<uint32_t> val = std::nullopt);
    1016              :         /// <summary>
    1017              :         /// Formats the register's current value for register dumps
    1018              :         /// </summary>
    1019              :         /// <returns>RegisterFormatter object containing register information</returns>
    1020              :         RegisterFormatter FormatDMAReadStartAddress();
    1021              : 
    1022              :         // DDR3 Memory DMA Read Byte Count / Start Read DMA Register
    1023              :         /// <summary>
    1024              :         /// Set the number of bytes to read for a DMA. Setting this register also initiates the DMA
    1025              :         /// </summary>
    1026              :         /// <param name="bytes">Bytes to read</param>
    1027              :         void SetDMAReadByteCount(const uint32_t& bytes);
    1028              :         /// <summary>
    1029              :         /// Read the current value of the DMA Read Byte Count
    1030              :         /// </summary>
    1031              :         /// <returns>Bytes to read</returns>
    1032              :         uint32_t ReadDMAReadByteCount(std::optional<uint32_t> val = std::nullopt);
    1033              :         /// <summary>
    1034              :         /// Start a DMA read using the byte count already present in the register
    1035              :         /// </summary>
    1036              :         void StartDMARead() { SetDMAReadByteCount(ReadDMAReadByteCount()); }
    1037              :         /// <summary>
    1038              :         /// Formats the register's current value for register dumps
    1039              :         /// </summary>
    1040              :         /// <returns>RegisterFormatter object containing register information</returns>
    1041              :         RegisterFormatter FormatDMAReadByteCount();
    1042              : 
    1043              :         // DDR3 Beam On Base Address Register
    1044              :         /// <summary>
    1045              :         /// Set the Beam On Base Address in the DDR memory
    1046              :         /// </summary>
    1047              :         /// <param name="address">Base address</param>
    1048              :         void SetRunPlanBeamOnBaseAddress(const uint32_t& address);
    1049              :         /// <summary>
    1050              :         /// Read the Beam On Base Address for DMAs into the DDR memory
    1051              :         /// </summary>
    1052              :         /// <returns>Base Address</returns>
    1053              :         uint32_t ReadRunPlanBeamOnBaseAddress(std::optional<uint32_t> val = std::nullopt);
    1054              :         /// <summary>
    1055              :         /// Formats the register's current value for register dumps
    1056              :         /// </summary>
    1057              :         /// <returns>RegisterFormatter object containing register information</returns>
    1058              :         RegisterFormatter FormatRunPlanBeamOnBaseAddress();
    1059              : 
    1060              :         // DDR3 Beam Off Base Address Register
    1061              :         /// <summary>
    1062              :         /// Set the Beam Off Base Address in the DDR memory
    1063              :         /// </summary>
    1064              :         /// <param name="address">Base address</param>
    1065              :         void SetRunPlanBeamOffBaseAddress(const uint32_t& address);
    1066              :         /// <summary>
    1067              :         /// Read the Beam Off Base Address for DMAs into the DDR memory
    1068              :         /// </summary>
    1069              :         /// <returns>Base Address</returns>
    1070              :         uint32_t ReadRunPlanBeamOffBaseAddress(std::optional<uint32_t> val = std::nullopt);
    1071              :         /// <summary>
    1072              :         /// Formats the register's current value for register dumps
    1073              :         /// </summary>
    1074              :         /// <returns>RegisterFormatter object containing register information</returns>
    1075              :         RegisterFormatter FormatRunPlanBeamOffBaseAddress();
    1076              :         /// <summary>
    1077              :         /// Write run plan data to the specified DDR memory address.
    1078              :         /// </summary>
    1079              :         /// <param name="inputData">Serialized run plan data to be written.</param>
    1080              :         /// <param name="address">DDR memory address where the run plan data should be stored.</param>
    1081              :         void SetRunPlanData(const std::string& inputData, const uint32_t& address);
    1082              :         /// <summary>
    1083              :         /// Compare the provided run plan data with the data stored at the specified DDR memory address.
    1084              :         /// </summary>
    1085              :         /// <param name="inputData">Serialized run plan data expected at the given address.</param>
    1086              :         /// <param name="address">DDR memory address from which the current run plan data is read.</param>
    1087              :         /// <param name="mismatches">
    1088              :         /// Optional pointer to a map that will be populated with any mismatching words,
    1089              :         /// keyed by address and containing expected/actual value pairs.
    1090              :         /// </param>
    1091              :         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);
    1092              :         /// <summary>
    1093              :         /// Read the current run plan mode as reported by the firmware.
    1094              :         /// </summary>
    1095              :         /// <returns>The current run plan mode value.</returns>
    1096              :         uint64_t ReadRunPlanCurrentMode();
    1097              :         /// <summary>
    1098              :         /// Format the current run plan mode value for inclusion in register dumps.
    1099              :         /// </summary>
    1100              :         /// <returns>RegisterFormatter object containing the current mode information.</returns>
    1101              :         RegisterFormatter FormatRunPlanCurrentMode();
    1102              :         /// <summary>
    1103              :         /// Read the current run plan tag as reported by the firmware.
    1104              :         /// </summary>
    1105              :         /// <returns>The current run plan tag value.</returns>
    1106              :         uint64_t ReadRunPlanCurrentTag();
    1107              :         /// <summary>
    1108              :         /// Format the current run plan tag value for inclusion in register dumps.
    1109              :         /// </summary>
    1110              :         /// <returns>RegisterFormatter object containing the current tag information.</returns>
    1111              :         RegisterFormatter FormatRunPlanCurrentTag();
    1112              : 
    1113              :         // Run Plan Subrun Event Limit Register
    1114              :         /// <summary>
    1115              :         /// Set the Run Plan Subrun Event Limit
    1116              :         /// </summary>
    1117              :         /// <param name="limit">Subrun event limit value</param>
    1118              :         void SetRunPlanSubrunEvtLimit(uint32_t limit);
    1119              :         /// <summary>
    1120              :         /// Read the Run Plan Subrun Event Limit
    1121              :         /// </summary>
    1122              :         /// <returns>Current subrun event limit value</returns>
    1123              :         uint32_t ReadRunPlanSubrunEvtLimit(std::optional<uint32_t> val = std::nullopt);
    1124              :         /// <summary>
    1125              :         /// Formats the register's current value for register dumps
    1126              :         /// </summary>
    1127              :         /// <returns>RegisterFormatter object containing register information</returns>
    1128              :         RegisterFormatter FormatRunPlanSubrunEvtLimit();
    1129              : 
    1130              :         // Run Plan Subrun Prediction Offset Register
    1131              :         /// <summary>
    1132              :         /// Set the Run Plan Subrun Prediction Offset
    1133              :         /// </summary>
    1134              :         /// <param name="offset">Subrun prediction offset value</param>
    1135              :         void SetRunPlanSubrunPredOffset(uint32_t offset);
    1136              :         /// <summary>
    1137              :         /// Read the Run Plan Subrun Prediction Offset
    1138              :         /// </summary>
    1139              :         /// <returns>Current subrun prediction offset value</returns>
    1140              :         uint32_t ReadRunPlanSubrunPredOffset(std::optional<uint32_t> val = std::nullopt);
    1141              :         /// <summary>
    1142              :         /// Formats the register's current value for register dumps
    1143              :         /// </summary>
    1144              :         /// <returns>RegisterFormatter object containing register information</returns>
    1145              :         RegisterFormatter FormatRunPlanSubrunPredOffset();
    1146              : 
    1147              :         // Firefly CSR Register
    1148              :         /// <summary>
    1149              :         /// Read the present bit for the TX/RX Firefly
    1150              :         /// </summary>
    1151              :         /// <returns>Whether the Firefly is present</returns>
    1152              :         bool ReadFireflyTXRXPresent(std::optional<uint32_t> val = std::nullopt);
    1153              :         /// <summary>
    1154              :         /// Read the present bit for the RX Firefly
    1155              :         /// </summary>
    1156              :         /// <returns>Whether the Firefly is present</returns>
    1157              :         bool ReadFireflyRXPresent(std::optional<uint32_t> val = std::nullopt);
    1158              :         /// <summary>
    1159              :         /// Read the present bit for the TX Firefly
    1160              :         /// </summary>
    1161              :         /// <returns>Whether the Firefly is present</returns>
    1162              :         bool ReadFireflyTXPresent(std::optional<uint32_t> val = std::nullopt);
    1163              :         /// <summary>
    1164              :         /// Read the interrupt bit for the TX/RX Firefly
    1165              :         /// </summary>
    1166              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1167              :         bool ReadFireflyTXRXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1168              :         /// <summary>
    1169              :         /// Read the interrupt bit for the RX Firefly
    1170              :         /// </summary>
    1171              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1172              :         bool ReadFireflyRXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1173              :         /// <summary>
    1174              :         /// Read the interrupt bit for the TX Firefly
    1175              :         /// </summary>
    1176              :         /// <returns>Whether the Firefly is in interrupt state</returns>
    1177              :         bool ReadFireflyTXInterrupt(std::optional<uint32_t> val = std::nullopt);
    1178              :         /// <summary>
    1179              :         /// Set the Select bit of the TX/RX Firefly
    1180              :         /// </summary>
    1181              :         /// <param name="select">Value to set</param>
    1182              :         void SetFireflyTXRXSelect(bool select);
    1183              :         /// <summary>
    1184              :         /// Set the Select bit of the RX Firefly
    1185              :         /// </summary>
    1186              :         /// <param name="select">Value to set</param>
    1187              :         void SetFireflyRXSelect(bool select);
    1188              :         /// <summary>
    1189              :         /// Set the Select bit of the TX Firefly
    1190              :         /// </summary>
    1191              :         /// <param name="select">Value to set</param>
    1192              :         void SetFireflyTXSelect(bool select);
    1193              :         /// <summary>
    1194              :         /// Read the select bit for the TX/RX Firefly
    1195              :         /// </summary>
    1196              :         /// <returns>Whether the Firefly is selected</returns>
    1197              :         bool ReadFireflyTXRXSelect(std::optional<uint32_t> val = std::nullopt);
    1198              :         /// <summary>
    1199              :         /// Read the select bit for the RX Firefly
    1200              :         /// </summary>
    1201              :         /// <returns>Whether the Firefly is selected</returns>
    1202              :         bool ReadFireflyRXSelect(std::optional<uint32_t> val = std::nullopt);
    1203              :         /// <summary>
    1204              :         /// Read the select bit for the TX Firefly
    1205              :         /// </summary>
    1206              :         /// <returns>Whether the Firefly is selected</returns>
    1207              :         bool ReadFireflyTXSelect(std::optional<uint32_t> val = std::nullopt);
    1208              :         /// <summary>
    1209              :         /// Set the Reset bit of the TX/RX Firefly
    1210              :         /// </summary>
    1211              :         /// <param name="reset">Value to set</param>
    1212              :         void SetFireflyTXRXReset(bool reset);
    1213              :         /// <summary>
    1214              :         /// Set the Reset bit of the RX Firefly
    1215              :         /// </summary>
    1216              :         /// <param name="reset">Value to set</param>
    1217              :         void SetFireflyRXReset(bool reset);
    1218              :         /// <summary>
    1219              :         /// Set the Reset bit of the TX Firefly
    1220              :         /// </summary>
    1221              :         /// <param name="reset">Value to set</param>
    1222              :         void SetFireflyTXReset(bool reset);
    1223              :         /// <summary>
    1224              :         /// Read the reset bit for the TX/RX Firefly
    1225              :         /// </summary>
    1226              :         /// <returns>Whether the Firefly is in reset state</returns>
    1227              :         bool ReadFireflyTXRXReset(std::optional<uint32_t> val = std::nullopt);
    1228              :         /// <summary>
    1229              :         /// Read the reset bit for the RX Firefly
    1230              :         /// </summary>
    1231              :         /// <returns>Whether the Firefly is in reset state</returns>
    1232              :         bool ReadFireflyRXReset(std::optional<uint32_t> val = std::nullopt);
    1233              :         /// <summary>
    1234              :         /// Read the reset bit for the TX Firefly
    1235              :         /// </summary>
    1236              :         /// <returns>Whether the Firefly is in reset state</returns>
    1237              :         bool ReadFireflyTXReset(std::optional<uint32_t> val = std::nullopt);
    1238              :         /// <summary>
    1239              :         /// Formats the register's current value for register dumps
    1240              :         /// </summary>
    1241              :         /// <returns>RegisterFormatter object containing register information</returns>
    1242              :         RegisterFormatter FormatFireflyCSR();
    1243              : 
    1244              :         // SERDES PRBS Control Registers
    1245              :         /// <summary>
    1246              :         /// Read the SERDES PRBS Error flag for the given link
    1247              :         /// </summary>
    1248              :         /// <param name="link">Link to read</param>
    1249              :         /// <returns>Value of the flag</returns>
    1250              :         bool ReadSERDESPRBSErrorFlag(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1251              :         /// <summary>
    1252              :         /// Read the TX PRBS SEL byte for the given link
    1253              :         /// </summary>
    1254              :         /// <param name="link">Link to read</param>
    1255              :         /// <returns>Value of the byte</returns>
    1256              :         uint8_t ReadSERDESTXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1257              :         /// <summary>
    1258              :         /// Set the TX PRBS SEL byte for the given link to the given value
    1259              :         /// </summary>
    1260              :         /// <param name="link">Link to set</param>
    1261              :         /// <param name="byte">Value of the byte</param>
    1262              :         void SetSERDESTXPRBSSEL(const CFO_Link_ID& link, uint8_t byte);
    1263              :         /// <summary>
    1264              :         /// Read the RX PRBS SEL byte for the given link
    1265              :         /// </summary>
    1266              :         /// <param name="link">Link to read</param>
    1267              :         /// <returns>Value of the byte</returns>
    1268              :         uint8_t ReadSERDESRXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1269              :         /// <summary>
    1270              :         /// Set the RX PRBS SEL byte for the given link to the given value
    1271              :         /// </summary>
    1272              :         /// <param name="link">Link to set</param>
    1273              :         /// <param name="byte">Value of the byte</param>
    1274              :         void SetSERDESRXPRBSSEL(const CFO_Link_ID& link, uint8_t byte);
    1275              :         /// <summary>
    1276              :         /// Read the SERDES TX PRBS Force Error bit for the given link
    1277              :         /// </summary>
    1278              :         /// <param name="link">Link to read</param>
    1279              :         /// <returns>Value of the bit</returns>
    1280              :         bool ReadSERDESTXPRBSForceError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1281              :         /// <summary>
    1282              :         /// Set the SERDES TX PRBS Force Error bit for the given link to the given value
    1283              :         /// </summary>
    1284              :         /// <param name="link">Link to set</param>
    1285              :         /// <param name="flag">Value to set</param>
    1286              :         void SetSERDESTXPRBSForceError(const CFO_Link_ID& link, bool flag);
    1287              :         /// <summary>
    1288              :         /// Toggle the SERDES TX PRBS Force Error bit for the given link
    1289              :         /// </summary>
    1290              :         /// <param name="link">Link to toggle</param>
    1291              :         void ToggleSERDESTXPRBSForceError(const CFO_Link_ID& link);
    1292              :         /// <summary>
    1293              :         /// Read the SERDES RX PRBS Count Reset bit for the given link
    1294              :         /// </summary>
    1295              :         /// <param name="link">Link to read</param>
    1296              :         /// <returns>Value of the bit</returns>
    1297              :         bool ReadSERDESRXPRBSCountReset(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1298              :         /// <summary>
    1299              :         /// Set the SERDES RX PRBS Count Reset bit for the given link to the given value
    1300              :         /// </summary>
    1301              :         /// <param name="link">Link to set</param>
    1302              :         /// <param name="flag">Value to set</param>
    1303              :         void SetSERDESRXPRBSCountReset(const CFO_Link_ID& link, bool flag);
    1304              :         /// <summary>
    1305              :         /// Toggle the SERDES RX PRBS Count Reset bit for the given link
    1306              :         /// </summary>
    1307              :         /// <param name="link">Link to toggle</param>
    1308              :         void ToggleSERDESRXPRBSCountReset(const CFO_Link_ID& link);
    1309              :         /// <summary>
    1310              :         /// Formats the register's current value for register dumps
    1311              :         /// </summary>
    1312              :         /// <returns>RegisterFormatter object containing register information</returns>
    1313              :         RegisterFormatter FormatSERDESPRBSControlLink0();
    1314              :         /// <summary>
    1315              :         /// Formats the register's current value for register dumps
    1316              :         /// </summary>
    1317              :         /// <returns>RegisterFormatter object containing register information</returns>
    1318              :         RegisterFormatter FormatSERDESPRBSControlLink1();
    1319              :         /// <summary>
    1320              :         /// Formats the register's current value for register dumps
    1321              :         /// </summary>
    1322              :         /// <returns>RegisterFormatter object containing register information</returns>
    1323              :         RegisterFormatter FormatSERDESPRBSControlLink2();
    1324              :         /// <summary>
    1325              :         /// Formats the register's current value for register dumps
    1326              :         /// </summary>
    1327              :         /// <returns>RegisterFormatter object containing register information</returns>
    1328              :         RegisterFormatter FormatSERDESPRBSControlLink3();
    1329              :         /// <summary>
    1330              :         /// Formats the register's current value for register dumps
    1331              :         /// </summary>
    1332              :         /// <returns>RegisterFormatter object containing register information</returns>
    1333              :         RegisterFormatter FormatSERDESPRBSControlLink4();
    1334              :         /// <summary>
    1335              :         /// Formats the register's current value for register dumps
    1336              :         /// </summary>
    1337              :         /// <returns>RegisterFormatter object containing register information</returns>
    1338              :         RegisterFormatter FormatSERDESPRBSControlLink5();
    1339              :         /// <summary>
    1340              :         /// Formats the register's current value for register dumps
    1341              :         /// </summary>
    1342              :         /// <returns>RegisterFormatter object containing register information</returns>
    1343              :         RegisterFormatter FormatSERDESPRBSControlLink6();
    1344              :         /// <summary>
    1345              :         /// Formats the register's current value for register dumps
    1346              :         /// </summary>
    1347              :         /// <returns>RegisterFormatter object containing register information</returns>
    1348              :         RegisterFormatter FormatSERDESPRBSControlLink7();
    1349              : 
    1350              :         // Cable Delays
    1351              :         uint32_t ReadCableDelayMeasureExponentialCount(std::optional<uint32_t> val = std::nullopt);
    1352              :         void     SetCableDelayMeasureExponentialCount(const uint32_t exponent);
    1353              :         uint32_t ReadCableDelayMeasurement(const CFO_Link_ID link, const uint8_t roc, bool& done);
    1354              : 
    1355              :         // /// <summary>
    1356              :         // /// Set the cable delay value for the given link
    1357              :         // /// </summary>
    1358              :         // /// <param name="link">Link to set</param>
    1359              :         // /// <param name="delay">Delay value to set</param>
    1360              :         // void SetCableDelayValue(const CFO_Link_ID& link, const uint32_t delay);
    1361              :         // /// <summary>
    1362              :         // /// Read the configured delay value for the given link
    1363              :         // /// </summary>
    1364              :         // /// <param name="link">Link to read</param>
    1365              :         // /// <returns>Configured delay value for the given link</returns>
    1366              :         // uint32_t ReadCableDelayValue(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1367              :         // /// <summary>
    1368              :         // /// Formats the register's current value for register dumps
    1369              :         // /// </summary>
    1370              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1371              :         // RegisterFormatter FormatCableDelayValueLink0();
    1372              :         // /// <summary>
    1373              :         // /// Formats the register's current value for register dumps
    1374              :         // /// </summary>
    1375              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1376              :         // RegisterFormatter FormatCableDelayValueLink1();
    1377              :         // /// <summary>
    1378              :         // /// Formats the register's current value for register dumps
    1379              :         // /// </summary>
    1380              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1381              :         // RegisterFormatter FormatCableDelayValueLink2();
    1382              :         // /// <summary>
    1383              :         // /// Formats the register's current value for register dumps
    1384              :         // /// </summary>
    1385              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1386              :         // RegisterFormatter FormatCableDelayValueLink3();
    1387              :         // /// <summary>
    1388              :         // /// Formats the register's current value for register dumps
    1389              :         // /// </summary>
    1390              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1391              :         // RegisterFormatter FormatCableDelayValueLink4();
    1392              :         // /// <summary>
    1393              :         // /// Formats the register's current value for register dumps
    1394              :         // /// </summary>
    1395              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1396              :         // RegisterFormatter FormatCableDelayValueLink5();
    1397              :         // /// <summary>
    1398              :         // /// Formats the register's current value for register dumps
    1399              :         // /// </summary>
    1400              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1401              :         // RegisterFormatter FormatCableDelayValueLink6();
    1402              :         // /// <summary>
    1403              :         // /// Formats the register's current value for register dumps
    1404              :         // /// </summary>
    1405              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1406              :         // RegisterFormatter FormatCableDelayValueLink7();
    1407              : 
    1408              :         // // Cable Delay Control And Status Register
    1409              :         // /// <summary>
    1410              :         // /// reset all the bits of the register
    1411              :         // /// </summary>
    1412              :         // void ResetDelayRegister();
    1413              : 
    1414              :         // /// <summary>
    1415              :         // /// Read the Measure Error bit for the given link
    1416              :         // /// </summary>
    1417              :         // /// <param name="link">Link to read</param>
    1418              :         // /// <returns>Value of the bit</returns>
    1419              :         // bool ReadDelayMeasureError(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1420              :         // /// <summary>
    1421              :         // /// Read the Cable Delay External Loopback Enable bit
    1422              :         // /// </summary>
    1423              :         // /// <returns>Value of the bit</returns>
    1424              :         // bool ReadDelayExternalLoopbackEnable(std::optional<uint32_t> val = std::nullopt);
    1425              :         // /// <summary>
    1426              :         // /// Set the Cable Delay External Loopback Enable bit
    1427              :         // /// </summary>
    1428              :         // /// <param name="value">Value to set</param>
    1429              :         // void SetDelayExternalLoopbackEnable(bool value);
    1430              :         // /// <summary>
    1431              :         // /// Enable the Delay Measure Mode on the given link
    1432              :         // /// </summary>
    1433              :         // /// <param name="link">Link to enable</param>
    1434              :         // void EnableDelayMeasureMode(const CFO_Link_ID& link);
    1435              :         // /// <summary>
    1436              :         // /// Disable the Delay Measure Mode on the given link
    1437              :         // /// </summary>
    1438              :         // /// <param name="link">Link to disable</param>
    1439              :         // void DisableDelayMeasureMode(const CFO_Link_ID& link);
    1440              :         // /// <summary>
    1441              :         // /// Read the Measure Mode Enable bit for the given link
    1442              :         // /// </summary>
    1443              :         // /// <param name="link">Link to read</param>
    1444              :         // /// <returns>Value of the bit</returns>
    1445              :         // bool ReadDelayMeasureMode(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1446              :         // /// <summary>
    1447              :         // /// Set the Delay Measure Now bit on the given link
    1448              :         // /// </summary>
    1449              :         // /// <param name="link">Link to enable</param>
    1450              :         // void EnableDelayMeasureNow(const CFO_Link_ID& link);
    1451              :         // /// <summary>
    1452              :         // /// Clear the Delay Measure Now bit on the given link
    1453              :         // /// </summary>
    1454              :         // /// <param name="link">Link to disable</param>
    1455              :         // void DisableDelayMeasureNow(const CFO_Link_ID& link);
    1456              :         // /// <summary>
    1457              :         // /// Read the Measure Now bit for the given link
    1458              :         // /// </summary>
    1459              :         // /// <param name="link">Link to read</param>
    1460              :         // /// <returns>Value of the bit</returns>
    1461              :         // bool ReadDelayMeasureNow(const CFO_Link_ID& link, std::optional<uint32_t> val = std::nullopt);
    1462              :         // /// <summary>
    1463              :         // /// Formats the register's current value for register dumps
    1464              :         // /// </summary>
    1465              :         // /// <returns>RegisterFormatter object containing register information</returns>
    1466              :         // RegisterFormatter FormatCableDelayControl();
    1467              : 
    1468              :         // FPGA PROM Program Data Register
    1469              : 
    1470              :         // FPGA PROM Program Status Register
    1471              :         /// <summary>
    1472              :         /// Read the full bit on the FPGA PROM FIFO
    1473              :         /// </summary>
    1474              :         /// <returns>the full bit on the FPGA PROM FIFO</returns>
    1475              :         bool ReadFPGAPROMProgramFIFOFull(std::optional<uint32_t> val = std::nullopt);
    1476              :         /// <summary>
    1477              :         /// Read whether the FPGA PROM is ready for data
    1478              :         /// </summary>
    1479              :         /// <returns>whether the FPGA PROM is ready for data</returns>
    1480              :         bool ReadFPGAPROMReady(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 FormatFPGAPROMProgramStatus();
    1486              : 
    1487              :         // FPGA Core Access Register
    1488              :         /// <summary>
    1489              :         /// Performs the chants necessary to reload the CFO firmware
    1490              :         /// </summary>
    1491              :         void ReloadFPGAFirmware();
    1492              :         /// <summary>
    1493              :         /// Read the FPGA Core Access FIFO Full bit
    1494              :         /// </summary>
    1495              :         /// <returns>Whether the FPGA Core Access FIFO is full</returns>
    1496              :         bool ReadFPGACoreAccessFIFOFull(std::optional<uint32_t> val = std::nullopt);
    1497              :         /// <summary>
    1498              :         /// Read the FPGA Core Access FIFO Empty bit
    1499              :         /// </summary>
    1500              :         /// <returns>Whether the FPGA Core Access FIFO is empty</returns>
    1501              :         bool ReadFPGACoreAccessFIFOEmpty(std::optional<uint32_t> val = std::nullopt);
    1502              :         /// <summary>
    1503              :         /// Formats the register's current value for register dumps
    1504              :         /// </summary>
    1505              :         /// <returns>RegisterFormatter object containing register information</returns>
    1506              :         RegisterFormatter FormatFPGACoreAccess();
    1507              : 
    1508              :         // Oscillator Programming (DDR and SERDES)
    1509              :         /// <summary>
    1510              :         /// Set the given oscillator to the given frequency, calculating a new program in the process.
    1511              :         /// </summary>
    1512              :         /// <param name="targetFrequency">New frequency to program, in Hz</param>
    1513              :         /// <returns>Whether the oscillator frequency was changed</returns>
    1514              :         bool SetNewOscillatorFrequency(double targetFrequency);
    1515              : 
    1516              :         /// <summary>
    1517              :         /// Disable all CFO links
    1518              :         /// </summary>
    1519              :         void DisableLinks();
    1520              : 
    1521              :         /// <summary>
    1522              :         /// Disable all CFO outputs
    1523              :         /// </summary>
    1524              :         void DisableAllOutputs();
    1525              : 
    1526              :   private:
    1527              :         bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) override;
    1528              :         void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) override;
    1529              : 
    1530              :         int      DecodeHighSpeedDivider_(int input);
    1531            0 :         int      DecodeOutputDivider_(int input) { return input + 1; }
    1532            0 :         double   DecodeRFREQ_(uint64_t input) { return input / 268435456.0; }
    1533              :         int      EncodeHighSpeedDivider_(int input);
    1534              :         int      EncodeOutputDivider_(int input);
    1535            0 :         uint64_t EncodeRFREQ_(double input) { return static_cast<uint64_t>(input * 268435456) & 0x3FFFFFFFFF; }
    1536              :         uint64_t CalculateFrequencyForProgramming_(double targetFrequency, double currentFrequency, uint64_t currentProgram);
    1537              : 
    1538              :   protected:
    1539              :         DTC_SimMode simMode_;                ///< Simulation mode
    1540              :         uint32_t    maxDTCs_;                ///< Map of active DTCs
    1541              :         bool        usingDetectorEmulator_;  ///< Whether Detector Emulation mode is enabled
    1542              :         uint16_t    dmaSize_;                ///< Size of DMAs, in bytes (default 32k)
    1543              : 
    1544              :   public:
    1545            0 :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedDumpFunctions() override { return formattedDumpFunctions_; };
    1546            0 :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedSimpleDumpFunctions() override { return formattedSimpleDumpFunctions_; };
    1547              : 
    1548              :         const std::vector<std::function<RegisterFormatter()>> formattedSimpleDumpFunctions_{
    1549            0 :             [this] { return this->FormatDeviceHash(); },  // mu2e_host_hash
    1550            0 :             [this] { return this->FormatDeviceTimeAlive(); },
    1551            0 :             [this] { return this->FormatCFOControl(); },
    1552            0 :             [this] { return this->FormatBeamOffMode(); },
    1553            0 :             [this] { return this->FormatBeamOnMode(); },
    1554            0 :             [this] { return this->FormatJitterAttenuatorCSR(); },
    1555            0 :             [this] { return this->FormatSERDESPLLLocked(); },
    1556            0 :             [this] { return this->FormatLinkEnable(); },
    1557            0 :             [this] { return this->FormatSERDESRXCDRLock(); },
    1558            0 :             [this] { return this->FormatSERDESResetDone(); },
    1559            0 :             [this] { return this->FormatSERDESReset(); },
    1560              :         };
    1561              : 
    1562              :         const std::vector<std::function<RegisterFormatter()>> formattedDumpFunctions_{
    1563            0 :             [this] { return this->FormatDesignVersion(); },
    1564            0 :             [this] { return this->FormatDesignDate(); },
    1565            0 :             [this] { return this->FormatDesignStatus(); },
    1566            0 :             [this] { return this->FormatVivadoVersion(); },
    1567            0 :             [this] { return this->FormatCFOControl(); },
    1568            0 :             [this] { return this->FormatDMATransferLength(); },
    1569            0 :             [this] { return this->FormatSERDESLoopbackEnable(); },
    1570            0 :             [this] { return this->FormatClockOscillatorStatus(); },
    1571            0 :             [this] { return this->FormatLinkEnable(); },
    1572            0 :             [this] { return this->FormatSERDESReset(); },
    1573            0 :             [this] { return this->FormatSERDESRXDisparityError(); },
    1574            0 :             [this] { return this->FormatSERDESRXCharacterNotInTableError(); },
    1575            0 :             [this] { return this->FormatSERDESUnlockError(); },
    1576            0 :             [this] { return this->FormatSERDESPLLLocked(); },
    1577            0 :             [this] { return this->FormatSERDESRXStatus(); },
    1578            0 :             [this] { return this->FormatSERDESResetDone(); },
    1579            0 :             [this] { return this->FormatSERDESRXCDRLock(); },
    1580            0 :             [this] { return this->FormatBeamOnTimerPreset(); },
    1581            0 :             [this] { return this->FormatBeamOnMode(); },
    1582            0 :             [this] { return this->FormatBeamOffMode(); },
    1583              :             // LEGACY: [this] { return this->FormatClockMarkerIntervalCount(); },  // register 0x9154 repurposed as RunPlanSubrunEvtLimit
    1584            0 :             [this] { return this->FormatSERDESOscillatorFrequency(); },
    1585            0 :             [this] { return this->FormatSERDESOscillatorControl(); },
    1586            0 :             [this] { return this->FormatSERDESOscillatorParameterLow(); },
    1587            0 :             [this] { return this->FormatSERDESOscillatorParameterHigh(); },
    1588            0 :             [this] { return this->FormatTimestampPreset0(); },
    1589            0 :             [this] { return this->FormatTimestampPreset1(); },
    1590            0 :             [this] { return this->FormatNUMDTCs(); },
    1591            0 :             [this] { return this->FormatFIFOFullErrorFlag0(); },
    1592            0 :             [this] { return this->FormatReceivePacketError(); },
    1593              :             // [this] { return this->FormatEventWindowEmulatorIntervalTime(); },
    1594            0 :             [this] { return this->FormatEventWindowHoldoffTime(); },
    1595            0 :             [this] { return this->FormatEventWindowTimeoutError(); },
    1596            0 :             [this] { return this->FormatEventWindowTimeoutInterval(); },
    1597            0 :             [this] { return this->FormatDMAWriteStartAddress(); },
    1598            0 :             [this] { return this->FormatDMAReadStartAddress(); },
    1599            0 :             [this] { return this->FormatDMAReadByteCount(); },
    1600            0 :             [this] { return this->FormatRunPlanBeamOnBaseAddress(); },
    1601            0 :             [this] { return this->FormatRunPlanBeamOffBaseAddress(); },
    1602            0 :             [this] { return this->FormatRunPlanSubrunEvtLimit(); },
    1603            0 :             [this] { return this->FormatRunPlanSubrunPredOffset(); },
    1604            0 :             [this] { return this->FormatFireflyCSR(); },
    1605            0 :             [this] { return this->FormatSERDESPRBSControlLink0(); },
    1606            0 :             [this] { return this->FormatSERDESPRBSControlLink1(); },
    1607            0 :             [this] { return this->FormatSERDESPRBSControlLink2(); },
    1608            0 :             [this] { return this->FormatSERDESPRBSControlLink3(); },
    1609            0 :             [this] { return this->FormatSERDESPRBSControlLink4(); },
    1610            0 :             [this] { return this->FormatSERDESPRBSControlLink5(); },
    1611            0 :             [this] { return this->FormatSERDESPRBSControlLink6(); },
    1612            0 :             [this] { return this->FormatSERDESPRBSControlLink7(); },
    1613              :             // [this] { return this->FormatCableDelayValueLink0(); },
    1614              :             // [this] { return this->FormatCableDelayValueLink1(); },
    1615              :             // [this] { return this->FormatCableDelayValueLink2(); },
    1616              :             // [this] { return this->FormatCableDelayValueLink3(); },
    1617              :             // [this] { return this->FormatCableDelayValueLink4(); },
    1618              :             // [this] { return this->FormatCableDelayValueLink5(); },
    1619              :             // [this] { return this->FormatCableDelayValueLink6(); },
    1620              :             // [this] { return this->FormatCableDelayValueLink7(); },
    1621              :             // [this] { return this->FormatCableDelayControl(); },
    1622            0 :             [this] { return this->FormatFPGAPROMProgramStatus(); },
    1623            0 :             [this] { return this->FormatFPGACoreAccess(); }};
    1624              : 
    1625              :         /// <summary>
    1626              :         /// Dump Byte/Packet Counter Registers
    1627              :         /// </summary>
    1628              :         const std::vector<std::function<RegisterFormatter()>> formattedCounterFunctions_{
    1629            0 :             [this] { return this->FormatTransmitHeartbeatPacketCount(); },
    1630            0 :             [this] { return this->FormatTransmitEventWindowMarkerCount(); },
    1631            0 :             [this] { return this->FormatReceiveRF0MarkerCount(); }
    1632              :             // [this] { return this->FormatReceiveByteCountLink0(); },
    1633              :             // [this] { return this->FormatReceiveByteCountLink1(); },
    1634              :             // [this] { return this->FormatReceiveByteCountLink2(); },
    1635              :             // [this] { return this->FormatReceiveByteCountLink3(); },
    1636              :             // [this] { return this->FormatReceiveByteCountLink4(); },
    1637              :             // [this] { return this->FormatReceiveByteCountLink5(); },
    1638              :             // [this] { return this->FormatReceiveByteCountLink6(); },
    1639              :             // [this] { return this->FormatReceiveByteCountLink7(); },
    1640              :             // [this] { return this->FormatReceivePacketCountLink0(); },
    1641              :             // [this] { return this->FormatReceivePacketCountLink1(); },
    1642              :             // [this] { return this->FormatReceivePacketCountLink2(); },
    1643              :             // [this] { return this->FormatReceivePacketCountLink3(); },
    1644              :             // [this] { return this->FormatReceivePacketCountLink4(); },
    1645              :             // [this] { return this->FormatReceivePacketCountLink5(); },
    1646              :             // [this] { return this->FormatReceivePacketCountLink6(); },
    1647              :             // [this] { return this->FormatReceivePacketCountLink7(); },
    1648              :             // [this] { return this->FormatTramsitByteCountLink0(); },
    1649              :             // [this] { return this->FormatTramsitByteCountLink1(); },
    1650              :             // [this] { return this->FormatTramsitByteCountLink2(); },
    1651              :             // [this] { return this->FormatTramsitByteCountLink3(); },
    1652              :             // [this] { return this->FormatTramsitByteCountLink4(); },
    1653              :             // [this] { return this->FormatTramsitByteCountLink5(); },
    1654              :             // [this] { return this->FormatTramsitByteCountLink6(); },
    1655              :             // [this] { return this->FormatTramsitByteCountLink7(); },
    1656              :             // [this] { return this->FormatTransmitPacketCountLink0(); },
    1657              :             // [this] { return this->FormatTransmitPacketCountLink1(); },
    1658              :             // [this] { return this->FormatTransmitPacketCountLink2(); },
    1659              :             // [this] { return this->FormatTransmitPacketCountLink3(); },
    1660              :             // [this] { return this->FormatTransmitPacketCountLink4(); },
    1661              :             // [this] { return this->FormatTransmitPacketCountLink5(); },
    1662              :             // [this] { return this->FormatTransmitPacketCountLink6(); },
    1663              :             // [this] { return this->FormatTransmitPacketCountLink7(); }
    1664              :         };
    1665              : };
    1666              : }  // namespace CFOLib
    1667              : 
    1668              : #endif  // CFO_REGISTERS_H
        

Generated by: LCOV version 2.0-1