LCOV - code coverage report
Current view: top level - mu2e-pcie-utils/dtcInterfaceLib - CFOandDTC_Registers.h (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 51 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 7 0

            Line data    Source code
       1              : #ifndef CFO_AND_DTC_REGISTERS_H
       2              : #define CFO_AND_DTC_REGISTERS_H
       3              : 
       4              : // #include <bitset> // std::bitset
       5              : // #include <cstdint> // uint8_t, uint16_t
       6              : #include <functional>  // std::bind, std::function
       7              : #include <optional>
       8              : #include <vector>  // std::vector
       9              : 
      10              : #include "mu2edev.h"
      11              : 
      12              : #define DTCLIB_COMMON_REGISTERS                                                         \
      13              :         CFOandDTC_Register_DesignVersion                     = 0x9000,                      \
      14              :         CFOandDTC_Register_DesignDate                        = 0x9004,                      \
      15              :         CFOandDTC_Register_DesignStatus                      = 0x9008,                      \
      16              :         CFOandDTC_Register_VivadoVersion                     = 0x900C,                      \
      17              :         CFOandDTC_Register_FPGA_Temperature                  = 0x9010,                      \
      18              :         CFOandDTC_Register_FPGA_VCCINT                       = 0x9014,                      \
      19              :         CFOandDTC_Register_FPGA_VCCAUX                       = 0x9018,                      \
      20              :         CFOandDTC_Register_FPGA_VCCBRAM                      = 0x901C,                      \
      21              :         CFOandDTC_Register_FPGA_MonitorAlarm                 = 0x9020,                      \
      22              :         CFOandDTC_Register_TimeAlive                         = 0x9024,                      \
      23              :         CFOandDTC_Register_Scratch                           = 0x9030,                      \
      24              :         CFOandDTC_Register_Control                           = 0x9100,                      \
      25              :         CFOandDTC_Register_DMATransferLength                 = 0x9104,                      \
      26              :         CFOandDTC_Register_SERDES_LoopbackEnable             = 0x9108,                      \
      27              :         CFOandDTC_Register_ClockOscillatorStatus             = 0x910C,                      \
      28              :         CFOandDTC_Register_LinkEnable                        = 0x9114,                      \
      29              :         CFOandDTC_Register_SERDES_Reset                      = 0x9118,                      \
      30              :         CFOandDTC_Register_SERDES_RXDisparityError           = 0x911C,                      \
      31              :         CFOandDTC_Register_SERDES_RXCharacterNotInTableError = 0x9120,                      \
      32              :         CFOandDTC_Register_SERDES_UnlockError                = 0x9124,                      \
      33              :         CFOandDTC_Register_SERDES_PLLLocked                  = 0x9128, /* not in CFO (?) */ \
      34              :             CFOandDTC_Register_SERDES_PLLPowerDown           = 0x912C, /* not in CFO (?) */ \
      35              :             CFOandDTC_Register_SERDES_CDRLockCommaCount      = 0x9130,                      \
      36              :         CFOandDTC_Register_SERDES_RXStatus                   = 0x9134,                      \
      37              :         CFOandDTC_Register_SERDES_ResetDone                  = 0x9138,                      \
      38              :         CFOandDTC_Register_SERDESClock_IICBusLow             = 0x9168,                      \
      39              :         CFOandDTC_Register_SERDESClock_IICBusHigh            = 0x916C,                      \
      40              :         CFOandDTC_Register_FireflyTX_IICBusControl           = 0x9284,                      \
      41              :         CFOandDTC_Register_FireflyTX_IICBusConfigLow         = 0x9288,                      \
      42              :         CFOandDTC_Register_FireflyTX_IICBusConfigHigh        = 0x928C,                      \
      43              :         CFOandDTC_Register_FireflyRX_IICBusControl           = 0x9294,                      \
      44              :         CFOandDTC_Register_FireflyRX_IICBusConfigLow         = 0x9298,                      \
      45              :         CFOandDTC_Register_FireflyRX_IICBusConfigHigh        = 0x929C,                      \
      46              :         CFOandDTC_Register_FireflyTXRX_IICBusControl         = 0x92A4,                      \
      47              :         CFOandDTC_Register_FireflyTXRX_IICBusConfigLow       = 0x92A8,                      \
      48              :         CFOandDTC_Register_FireflyTXRX_IICBusConfigHigh      = 0x92AC,                      \
      49              :         CFOandDTC_Register_FireFlyControlStatus              = 0x93A0
      50              : 
      51              : namespace DTCLib
      52              : {
      53              : 
      54              : typedef uint16_t CFOandDTC_Register;  // defined enum in CFOandDTC_Registers.cpp
      55              : 
      56              : /// <summary>
      57              : /// The RegisterFormatter class is used to print a DTC register in a human-readable format
      58              : /// </summary>
      59              : struct RegisterFormatter
      60              : {
      61              :         /// <summary>
      62              :         /// Default Constructor with zero values
      63              :         /// </summary>
      64            0 :         RegisterFormatter()
      65            0 :             : address(0)
      66            0 :             , value(0)
      67            0 :             , descWidth(28)
      68            0 :             , description("")
      69            0 :             , vals() {}
      70              : 
      71              :         /// <summary>
      72              :         /// Default Copy Consturctor
      73              :         /// </summary>
      74              :         /// <param name="r">RegisterFormatter to copy</param>
      75              :         RegisterFormatter(const RegisterFormatter& r) = default;
      76              :         /// <summary>
      77              :         /// Default Move Constructor
      78              :         /// </summary>
      79              :         /// <param name="r">RegisterFormatter rvalue</param>
      80              :         RegisterFormatter(RegisterFormatter&& r) = default;
      81              :         uint16_t                 address;      ///< Address of the register
      82              :         uint32_t                 value;        ///< Value of the register
      83              :         int                      descWidth;    ///< Display width of description field
      84              :         std::string              description;  ///< Description of the register (name)
      85              :         std::vector<std::string> vals;         ///< Human-readable descriptions of register values (bits, etc)
      86              : 
      87              :         /// <summary>
      88              :         /// Default Copy Assignment Operator
      89              :         /// </summary>
      90              :         /// <param name="r">RHS</param>
      91              :         /// <returns>RegisterFormatter regerence</returns>
      92              :         RegisterFormatter& operator=(const RegisterFormatter& r) = default;
      93              : 
      94              :         /// <summary>
      95              :         /// Write out the RegisterFormatter to the given stream. This function uses setw to make sure that fields for
      96              :         /// different registers still line up.
      97              :         /// Format is: "    0xADDR  | 0xVALUEXXX | DESCRIPTION: Variable size, minimum of 28 chars | Value 1
      98              :         ///                                                                                        | Value 2 ..."
      99              :         /// </summary>
     100              :         /// <param name="stream">Stream to write register data to</param>
     101              :         /// <param name="reg">RegisterFormatter to write</param>
     102              :         /// <returns>Stream reference for continued streaming</returns>
     103            0 :         friend std::ostream& operator<<(std::ostream& stream, const RegisterFormatter& reg)
     104              :         {
     105            0 :                 stream << std::hex << std::setfill('0');
     106              :                 {  // move address to right-align with values
     107            0 :                         std::string placeholder = "";
     108            0 :                         placeholder.resize(reg.descWidth - 6, ' ');
     109            0 :                         stream << placeholder;
     110            0 :                 }
     111            0 :                 stream << "0x" << std::setw(4) << static_cast<int>(reg.address) << " | 0x" << std::setw(8)
     112            0 :                        << static_cast<int>(reg.value) << " | ";
     113            0 :                 auto tmp = reg.description;
     114            0 :                 tmp.resize(reg.descWidth, ' ');
     115              :                 stream << '\n'
     116            0 :                        << tmp << " | ";
     117              : 
     118            0 :                 if(!reg.vals.empty())
     119              :                 {
     120            0 :                         auto first = true;
     121            0 :                         for(auto i : reg.vals)
     122              :                         {
     123            0 :                                 if(!first)
     124              :                                 {
     125            0 :                                         std::string placeholder = "";
     126            0 :                                         placeholder.resize(reg.descWidth, ' ');
     127              :                                         stream <<  //"                           " <<
     128            0 :                                             placeholder << " | ";
     129            0 :                                 }
     130            0 :                                 stream << i << std::endl;
     131            0 :                                 first = false;
     132            0 :                         }
     133              :                 }
     134              :                 else
     135              :                 {
     136            0 :                         stream << std::endl;
     137              :                 }
     138              : 
     139            0 :                 return stream;
     140            0 :         }  // end << operator
     141              : 
     142              :         // Overloaded operator+ for RegisterFormatter + std::string
     143            0 :         std::string operator+(const std::string& rhs) const
     144              :         {
     145            0 :                 std::stringstream ss;
     146            0 :                 ss << *this;
     147            0 :                 return ss.str() + rhs;
     148            0 :         }
     149              : 
     150              :         // Friend function operator+  for std::string + RegisterFormatter
     151            0 :         friend std::string operator+(const std::string& lhs, const RegisterFormatter& reg)
     152              :         {
     153            0 :                 std::stringstream ss;
     154            0 :                 ss << reg;
     155            0 :                 return lhs + ss.str();
     156            0 :         }
     157              : };  // end RegisterFormatter class
     158              : 
     159              : /// <summary>
     160              : /// The CFOandDTC_Registers class represents the common CFO-and-DTC Register space, and all the methods necessary to read and write those
     161              : /// registers. Each register has, at the very least, a read method, a write method, and a RegisterFormatter method
     162              : /// which formats the register value in a human-readable way.
     163              : /// </summary>
     164              : class CFOandDTC_Registers
     165              : {
     166              :   public:
     167              :         explicit CFOandDTC_Registers();
     168              : 
     169              :         virtual ~CFOandDTC_Registers();
     170              : 
     171              :         /// <summary>
     172              :         /// Get a pointer to the device handle
     173              :         /// </summary>
     174              :         /// <returns>mu2edev* pointer</returns>
     175            0 :         mu2edev* GetDevice() { return &device_; }
     176              : 
     177              :         /// <summary>
     178              :         /// Get the current DTC UID for this instance
     179              :         /// </summary>
     180              :         /// <returns>The current DTC UID for this instance</returns>
     181            0 :         std::string getDeviceUID() { return GetDevice()->getDeviceUID(); }
     182              : 
     183              :         std::string                                                    FormattedRegDump(int width, const std::vector<std::function<RegisterFormatter()>>& regVec);
     184              :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedDumpFunctions()       = 0;  // pure virtual
     185              :         virtual const std::vector<std::function<RegisterFormatter()>>& getFormattedSimpleDumpFunctions() = 0;  // pure virtual
     186              : 
     187              :         //
     188              :         // Register IO Functions ----------------
     189              :         //
     190              : 
     191              :         virtual void ResetPCIe() = 0;  // pure virtual
     192              :         virtual void FlashLEDs() = 0;  // pure virtual
     193              : 
     194              :         // Desgin Version/Date Registers
     195              :         std::string       ReadDesignVersion();
     196              :         RegisterFormatter FormatDesignVersion();
     197              :         std::string       ReadDesignDate(std::optional<uint32_t> val = std::nullopt);
     198              :         bool              isCRVDTCDesignFlavour(std::optional<uint32_t> val = std::nullopt);
     199              :         bool              isNonCRVDTCDesignFlavour(std::optional<uint32_t> val = std::nullopt);
     200              :         bool              isCFODesignFlavour(std::optional<uint32_t> val = std::nullopt);
     201              :         RegisterFormatter FormatDesignDate();
     202              :         std::string       ReadDesignVersionNumber(std::optional<uint32_t> val = std::nullopt);
     203              :         std::string       ReadDesignLinkSpeed(std::optional<uint32_t> val = std::nullopt);
     204              :         std::string       ReadDesignType(std::optional<uint32_t> val = std::nullopt);
     205              : 
     206              :         // Vivado Version Register
     207              :         virtual std::string       ReadVivadoVersionNumber(std::optional<uint32_t> val = std::nullopt);
     208              :         virtual RegisterFormatter FormatVivadoVersion();
     209              : 
     210              :         // FPGA Temperature Register
     211              :         double            ReadFPGATemperature(std::optional<uint32_t> val = std::nullopt);
     212              :         RegisterFormatter FormatFPGATemperature();
     213              : 
     214              :         // FPGA VCCINT Voltage Register
     215              :         double            ReadFPGAVCCINTVoltage(std::optional<uint32_t> val = std::nullopt);
     216              :         RegisterFormatter FormatFPGAVCCINT();
     217              : 
     218              :         // FPGA VCCAUX Voltage Register
     219              :         double            ReadFPGAVCCAUXVoltage(std::optional<uint32_t> val = std::nullopt);
     220              :         RegisterFormatter FormatFPGAVCCAUX();
     221              : 
     222              :         // FPGA VCCBRAM Voltage Register
     223              :         double            ReadFPGAVCCBRAMVoltage(std::optional<uint32_t> val = std::nullopt);
     224              :         RegisterFormatter FormatFPGAVCCBRAM();
     225              : 
     226              :         // FPGA Monitor Alarm Register
     227              :         bool              ReadFPGADieTemperatureAlarm(std::optional<uint32_t> val = std::nullopt);
     228              :         void              ResetFPGADieTemperatureAlarm(std::optional<uint32_t> val = std::nullopt);
     229              :         bool              ReadFPGAAlarms(std::optional<uint32_t> val = std::nullopt);
     230              :         void              ResetFPGAAlarms(std::optional<uint32_t> val = std::nullopt);
     231              :         bool              ReadVCCBRAMAlarm(std::optional<uint32_t> val = std::nullopt);
     232              :         void              ResetVCCBRAMAlarm(std::optional<uint32_t> val = std::nullopt);
     233              :         bool              ReadVCCAUXAlarm(std::optional<uint32_t> val = std::nullopt);
     234              :         void              ResetVCCAUXAlarm(std::optional<uint32_t> val = std::nullopt);
     235              :         bool              ReadVCCINTAlarm(std::optional<uint32_t> val = std::nullopt);
     236              :         void              ResetVCCINTAlarm(std::optional<uint32_t> val = std::nullopt);
     237              :         bool              ReadFPGAUserTemperatureAlarm(std::optional<uint32_t> val = std::nullopt);
     238              :         void              ResetFPGAUserTemperatureAlarm(std::optional<uint32_t> val = std::nullopt);
     239              :         RegisterFormatter FormatFPGAAlarms();
     240              : 
     241              :         // Time Alive Register
     242              :         RegisterFormatter FormatDeviceTimeAlive();
     243              : 
     244              :         // Scratch Register (Device Hash)
     245              :         RegisterFormatter FormatDeviceHash();
     246              : 
     247              :         // CFO and DTC Control Register B31 is Soft Reset
     248              :         void SoftReset();                                                  // B31
     249              :         bool ReadSoftReset(std::optional<uint32_t> val = std::nullopt);    // B31
     250              :         void SetPunchEnable();                                             // B9
     251              :         void ClearPunchEnable();                                           // B9
     252              :         bool ReadPunchEnable(std::optional<uint32_t> val = std::nullopt);  // B9
     253              :         void ResetSERDES();                                                // B8
     254              :         bool ReadResetSERDES(std::optional<uint32_t> val = std::nullopt);  // B8
     255              :         void RunCableDelayLoopbackTest();                                  // B3
     256              :         void HardReset();                                                  // B0
     257              :         bool ReadHardReset(std::optional<uint32_t> val = std::nullopt);    // B0
     258              :         void ClearControlRegister();                                       // 32-bit clear
     259              : 
     260              :         // Jitter Attenuator CSR Register
     261              :         virtual std::bitset<2>    ReadJitterAttenuatorSelect(std::optional<uint32_t> val = std::nullopt)   = 0;  // pure virtual
     262              :         virtual void              SetJitterAttenuatorSelect(std::bitset<2> data, bool alsoResetJA = false) = 0;  // pure virtual
     263              :         virtual bool              ReadJitterAttenuatorReset(std::optional<uint32_t> val = std::nullopt)    = 0;  // pure virtual
     264              :         virtual bool              ReadJitterAttenuatorLocked(std::optional<uint32_t> val = std::nullopt)   = 0;  // pure virtual
     265              :         virtual void              ResetJitterAttenuator()                                                  = 0;  // pure virtual
     266              :         virtual RegisterFormatter FormatJitterAttenuatorCSR()                                              = 0;  // pure virtual
     267              : 
     268              :         std::bitset<2>    ReadJitterAttenuatorSelect(CFOandDTC_Register JAreg, std::optional<uint32_t> val = std::nullopt);
     269              :         void              SetJitterAttenuatorSelect(CFOandDTC_Register JAreg, std::bitset<2> data, bool alsoResetJA);
     270              :         bool              ReadJitterAttenuatorReset(CFOandDTC_Register JAreg, std::optional<uint32_t> val = std::nullopt);
     271              :         bool              ReadJitterAttenuatorLocked(CFOandDTC_Register JAreg, std::optional<uint32_t> val = std::nullopt);
     272              :         void              ResetJitterAttenuator(CFOandDTC_Register JAreg, std::optional<uint32_t> val = std::nullopt);
     273              :         RegisterFormatter FormatJitterAttenuatorCSR(CFOandDTC_Register JAreg);
     274              :         // virtual void ConfigureJitterAttenuator() = 0; //pure virtual
     275              :         void ConfigureJitterAttenuator();
     276              : 
     277              :         void              WriteSERDESIICInterface(DTC_IICSERDESBusAddress device, uint8_t address, uint8_t data);
     278              :         uint8_t           ReadSERDESIICInterface(DTC_IICSERDESBusAddress device, uint8_t address);
     279              :         RegisterFormatter FormatSERDESOscillatorParameterLow();
     280              :         RegisterFormatter FormatSERDESOscillatorParameterHigh();
     281              : 
     282              :         // Firefly TX IIC Registers
     283              :         bool              ReadFireflyTXIICInterfaceReset(std::optional<uint32_t> val = std::nullopt);
     284              :         void              ResetFireflyTXIICInterface();
     285              :         void              WriteFireflyTXIICInterface(uint8_t device, uint8_t address, uint8_t data);
     286              :         uint8_t           ReadFireflyTXIICInterface(uint8_t device, uint8_t address);
     287              :         RegisterFormatter FormatFireflyTXIICControl();
     288              :         RegisterFormatter FormatFireflyTXIICParameterLow();
     289              :         RegisterFormatter FormatFireflyTXIICParameterHigh();
     290              : 
     291              :         // Firefly RX IIC Registers
     292              :         bool              ReadFireflyRXIICInterfaceReset(std::optional<uint32_t> val = std::nullopt);
     293              :         void              ResetFireflyRXIICInterface();
     294              :         void              WriteFireflyRXIICInterface(uint8_t device, uint8_t address, uint8_t data);
     295              :         uint8_t           ReadFireflyRXIICInterface(uint8_t device, uint8_t address);
     296              :         RegisterFormatter FormatFireflyRXIICControl();
     297              :         RegisterFormatter FormatFireflyRXIICParameterLow();
     298              :         RegisterFormatter FormatFireflyRXIICParameterHigh();
     299              : 
     300              :         // Firefly TXRX IIC Registers
     301              :         bool              ReadFireflyTXRXIICInterfaceReset(std::optional<uint32_t> val = std::nullopt);
     302              :         void              ResetFireflyTXRXIICInterface();
     303              :         void              WriteFireflyTXRXIICInterface(uint8_t device, uint8_t address, uint8_t data);
     304              :         uint8_t           ReadFireflyTXRXIICInterface(uint8_t device, uint8_t address);
     305              :         RegisterFormatter FormatFireflyTXRXIICControl();
     306              :         RegisterFormatter FormatFireflyTXRXIICParameterLow();
     307              :         RegisterFormatter FormatFireflyTXRXIICParameterHigh();
     308              : 
     309              :         // Firefly CSR Register
     310              :         bool              ReadTXRXFireflyPresent(std::optional<uint32_t> val = std::nullopt);
     311              :         bool              ReadRXFireflyPresent(std::optional<uint32_t> val = std::nullopt);
     312              :         bool              ReadTXFireflyPresent(std::optional<uint32_t> val = std::nullopt);
     313              :         bool              ReadTXRXFireflyInterrupt(std::optional<uint32_t> val = std::nullopt);
     314              :         bool              ReadRXFireflyInterrupt(std::optional<uint32_t> val = std::nullopt);
     315              :         bool              ReadTXFireflyInterrupt(std::optional<uint32_t> val = std::nullopt);
     316              :         bool              ReadTXRXFireflySelect(std::optional<uint32_t> val = std::nullopt);
     317              :         void              SetTXRXFireflySelect(bool select);
     318              :         bool              ReadTXFireflySelect(std::optional<uint32_t> val = std::nullopt);
     319              :         void              SetTXFireflySelect(bool select);
     320              :         bool              ReadRXFireflySelect(std::optional<uint32_t> val = std::nullopt);
     321              :         void              SetRXFireflySelect(bool select);
     322              :         bool              ReadResetTXRXFirefly(std::optional<uint32_t> val = std::nullopt);
     323              :         void              ResetTXRXFirefly();
     324              :         bool              ReadResetTXFirefly(std::optional<uint32_t> val = std::nullopt);
     325              :         void              ResetTXFirefly();
     326              :         bool              ReadResetRXFirefly(std::optional<uint32_t> val = std::nullopt);
     327              :         void              ResetRXFirefly();
     328              :         RegisterFormatter FormatFireflyCSR();
     329              : 
     330              :         uint32_t WriteRegister_(uint32_t data, const CFOandDTC_Register& address);
     331              : 
     332              :   protected:
     333              :         uint32_t     ReadRegister_(const CFOandDTC_Register& address);
     334              :         virtual bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address)                                         = 0;
     335              :         virtual void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) = 0;
     336              :         bool         CFOandDTCVerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite);
     337              : 
     338              :         /// <summary>
     339              :         /// Initializes a RegisterFormatter for the given CFOandDTC_Register
     340              :         /// </summary>
     341              :         /// <param name="address">Address of register to format</param>
     342              :         /// <returns>RegisterFormatter with address and raw value set</returns>
     343            0 :         RegisterFormatter CreateFormatter(const CFOandDTC_Register& address, bool getValue = true)
     344              :         {
     345            0 :                 RegisterFormatter form;
     346            0 :                 form.descWidth = formatterWidth_;
     347            0 :                 form.address   = address;
     348            0 :                 if(getValue)
     349            0 :                         form.value = ReadRegister_(address);
     350            0 :                 return form;
     351            0 :         }
     352              : 
     353              :         bool GetBit_(const CFOandDTC_Register& address, size_t bit);
     354              :         void SetBit_(const CFOandDTC_Register& address, size_t bit, bool value);
     355              :         bool ToggleBit_(const CFOandDTC_Register& address, size_t bit)
     356              :         {
     357              :                 auto val = GetBit_(address, bit);
     358              :                 SetBit_(address, bit, !val);
     359              :                 return !val;
     360              :         }
     361              : 
     362              :         mu2edev device_;               ///< Device handle
     363              :         int     formatterWidth_ = 28;  ///< Description field width, in characters (must be initialized or RegisterFormatter can resize to crazy large values!)
     364              : 
     365              : };  // end CFOandDTC_Registers class
     366              : }  // namespace DTCLib
     367              : 
     368              : #endif  // CFO_AND_DTC_REGISTERS_H
        

Generated by: LCOV version 2.0-1