diff --git a/cfoInterfaceLib/CFO_Registers.cpp b/cfoInterfaceLib/CFO_Registers.cpp index a11ca41..612dbdb 100644 --- a/cfoInterfaceLib/CFO_Registers.cpp +++ b/cfoInterfaceLib/CFO_Registers.cpp @@ -1842,39 +1842,79 @@ DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDMAReadByteCount() return form; } -void CFOLib::CFO_Registers::SetDDRBeamOnBaseAddress(const uint32_t& address) +void CFOLib::CFO_Registers::SetRunPlanBeamOnBaseAddress(const uint32_t& address) { - WriteRegister_(address, CFO_Register_DDRBeamOnBaseAddress); + WriteRegister_(address, CFO_Register_RunPlanBeamOnBaseAddress); } -uint32_t CFOLib::CFO_Registers::ReadDDRBeamOnBaseAddress(std::optional val) { return val.has_value()?*val:ReadRegister_(CFO_Register_DDRBeamOnBaseAddress); } +uint32_t CFOLib::CFO_Registers::ReadRunPlanBeamOnBaseAddress(std::optional val) { return val.has_value()?*val:ReadRegister_(CFO_Register_RunPlanBeamOnBaseAddress); } -DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDDRBeamOnBaseAddress() +DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanBeamOnBaseAddress() { - auto form = CreateFormatter(CFO_Register_DDRBeamOnBaseAddress); + auto form = CreateFormatter(CFO_Register_RunPlanBeamOnBaseAddress); form.description = "DDR Memory Beam On Base Address"; - form.vals.push_back(std::to_string(ReadDDRBeamOnBaseAddress(form.value))); + form.vals.push_back(std::to_string(ReadRunPlanBeamOnBaseAddress(form.value))); return form; } -void CFOLib::CFO_Registers::SetDDRBeamOffBaseAddress(const uint32_t& address) +void CFOLib::CFO_Registers::SetRunPlanBeamOffBaseAddress(const uint32_t& address) { - WriteRegister_(address, CFO_Register_DDRBeamOffBaseAddress); + WriteRegister_(address, CFO_Register_RunPlanBeamOffBaseAddress); } -uint32_t CFOLib::CFO_Registers::ReadDDRBeamOffBaseAddress(std::optional val) +uint32_t CFOLib::CFO_Registers::ReadRunPlanBeamOffBaseAddress(std::optional val) { - return val.has_value()?*val:ReadRegister_(CFO_Register_DDRBeamOffBaseAddress); + return val.has_value()?*val:ReadRegister_(CFO_Register_RunPlanBeamOffBaseAddress); } -DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDDRBeamOffBaseAddress() +DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanBeamOffBaseAddress() { - auto form = CreateFormatter(CFO_Register_DDRBeamOffBaseAddress); + auto form = CreateFormatter(CFO_Register_RunPlanBeamOffBaseAddress); form.description = "DDR Memory Beam Off Base Address"; - form.vals.push_back(std::to_string(ReadDDRBeamOffBaseAddress())); + form.vals.push_back(std::to_string(ReadRunPlanBeamOffBaseAddress())); return form; } +void CFOLib::CFO_Registers::SetRunPlanData(const std::string& inputData, const uint32_t& runPlanBaseAddress) +{ + __COUTTV__(inputData.size()); + __COUTT__ << "Writing run plan of size " << inputData.size() << " to base address 0x" << + std::hex << std::setw(8) << std::setfill('0') << runPlanBaseAddress << __E__; + + auto dataPtr = reinterpret_cast(&inputData[0]); + + //primary run plan write loop + WriteRegister_(runPlanBaseAddress, CFO_Register_RunPlan_Address); //resets run plan BRAM write address + for(uint32_t l = 0; l < inputData.size(); l+=4) + { + // CFO_Register_RunPlan_Address = 0x9314, + // CFO_Register_RunPlan_Data = 0x9318, + WriteRegister_(*((uint32_t *)(&(dataPtr[l]))), CFO_Register_RunPlan_Data); //write data then increment BRAM address + __COUTT__ << std::hex << std::setw(8) << std::setfill('0') << "addr 0x" << (runPlanBaseAddress + l/4) << + " data 0x" << *((uint32_t *)(&(dataPtr[l]))) << __E__; + } //end primary run plan write loop + + //now verify run plan w/readback + WriteRegister_(runPlanBaseAddress, CFO_Register_RunPlan_Address); //resets run plan BRAM write address + uint32_t val; + for(uint32_t l = 0; l < inputData.size(); l+=4) + { + val = ReadRegister_(CFO_Register_RunPlan_Data); + + __COUTT__ << std::hex << std::setw(8) << std::setfill('0') << "addr 0x" << (runPlanBaseAddress + l/4) << + " data 0x" << *((uint32_t *)(&(dataPtr[l]))) << " =? rdata 0x" << val << __E__; + if(val != *((uint32_t *)(&(dataPtr[l])))) + { + __SS__ << "Run plan write validation failed at " << std::hex << std::setw(8) << std::setfill('0') << + "addr 0x" << (runPlanBaseAddress + l/4) << + " data 0x" << *((uint32_t *)(&(dataPtr[l]))) << " != rdata 0x" << val << __E__; + // __COUT_ERR__ << "\n" << ss.str(); + __SS_THROW__; + } + } //end run plan validation + +} //end SetRunPlanData() + // Firefly CSR Register bool CFOLib::CFO_Registers::ReadFireflyTXRXPresent(std::optional val) { @@ -3046,6 +3086,18 @@ void CFOLib::CFO_Registers::DisableAllOutputs() // Private Functions +bool CFOLib::CFO_Registers::NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) +{ + switch(address) + { + //list all registers that do no need to be verified + case CFO_Register_RunPlan_Data: + return false; + default:; + } + return true; +} //end NeedToVerifyRegisterWrite_() + void CFOLib::CFO_Registers::VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) { //verify register readback diff --git a/cfoInterfaceLib/CFO_Registers.h b/cfoInterfaceLib/CFO_Registers.h index 4ae468a..8bd64e4 100644 --- a/cfoInterfaceLib/CFO_Registers.h +++ b/cfoInterfaceLib/CFO_Registers.h @@ -68,8 +68,12 @@ enum CFO_Register : uint16_t CFO_Register_DDRMemoryDMAWriteStartAddress = 0x9300, CFO_Register_DDRMemoryDMAReadStartAddress = 0x9304, CFO_Register_DDRMemoryDMAReadByteCount = 0x9308, - CFO_Register_DDRBeamOnBaseAddress = 0x930C, - CFO_Register_DDRBeamOffBaseAddress = 0x9310, + CFO_Register_RunPlanBeamOnBaseAddress = 0x930C, + CFO_Register_RunPlanBeamOffBaseAddress = 0x9310, + + CFO_Register_RunPlan_Address = 0x9314, + CFO_Register_RunPlan_Data = 0x9318, + CFO_Register_FireflyCSRRegister = 0x9320, CFO_Register_SERDESPRBSControlLink0 = 0x9330, CFO_Register_SERDESPRBSControlLink1 = 0x9334, @@ -1013,34 +1017,35 @@ class CFO_Registers : public DTCLib::CFOandDTC_Registers /// Set the Beam On Base Address in the DDR memory /// /// Base address - void SetDDRBeamOnBaseAddress(const uint32_t& address); + void SetRunPlanBeamOnBaseAddress(const uint32_t& address); /// /// Read the Beam On Base Address for DMAs into the DDR memory /// /// Base Address - uint32_t ReadDDRBeamOnBaseAddress(std::optional val = std::nullopt); + uint32_t ReadRunPlanBeamOnBaseAddress(std::optional val = std::nullopt); /// /// Formats the register's current value for register dumps /// /// RegisterFormatter object containing register information - RegisterFormatter FormatDDRBeamOnBaseAddress(); + RegisterFormatter FormatRunPlanBeamOnBaseAddress(); // DDR3 Beam Off Base Address Register /// /// Set the Beam Off Base Address in the DDR memory /// /// Base address - void SetDDRBeamOffBaseAddress(const uint32_t& address); + void SetRunPlanBeamOffBaseAddress(const uint32_t& address); /// /// Read the Beam Off Base Address for DMAs into the DDR memory /// /// Base Address - uint32_t ReadDDRBeamOffBaseAddress(std::optional val = std::nullopt); + uint32_t ReadRunPlanBeamOffBaseAddress(std::optional val = std::nullopt); /// /// Formats the register's current value for register dumps /// /// RegisterFormatter object containing register information - RegisterFormatter FormatDDRBeamOffBaseAddress(); + RegisterFormatter FormatRunPlanBeamOffBaseAddress(); + void SetRunPlanData(const std::string& inputData, const uint32_t& address); // Firefly CSR Register /// @@ -1422,6 +1427,7 @@ class CFO_Registers : public DTCLib::CFOandDTC_Registers void DisableAllOutputs(); private: + bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) override; void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) override; int DecodeHighSpeedDivider_(int input); @@ -1493,8 +1499,8 @@ class CFO_Registers : public DTCLib::CFOandDTC_Registers [this]() { return this->FormatDMAWriteStartAddress(); }, [this]() { return this->FormatDMAReadStartAddress(); }, [this]() { return this->FormatDMAReadByteCount(); }, - [this]() { return this->FormatDDRBeamOnBaseAddress(); }, - [this]() { return this->FormatDDRBeamOffBaseAddress(); }, + [this]() { return this->FormatRunPlanBeamOnBaseAddress(); }, + [this]() { return this->FormatRunPlanBeamOffBaseAddress(); }, [this]() { return this->FormatFireflyCSR(); }, [this]() { return this->FormatSERDESPRBSControlLink0(); }, [this]() { return this->FormatSERDESPRBSControlLink1(); }, diff --git a/dtcInterfaceLib/CFOandDTC_Registers.cpp b/dtcInterfaceLib/CFOandDTC_Registers.cpp index bdb4090..ae39574 100644 --- a/dtcInterfaceLib/CFOandDTC_Registers.cpp +++ b/dtcInterfaceLib/CFOandDTC_Registers.cpp @@ -137,7 +137,9 @@ std::string DTCLib::CFOandDTC_Registers::ReadDesignDate(std::optional ((readData>>12)&0xF) << ((readData>>8)&0xF) << "/20" << // ((readData>>28)&0xF) << 20 + ((readData>>24)&0xF) << " " << //year 2020 + hex nibble at bit-24 - ((readData>>4)&0xF) << ((readData>>0)&0xF) << ":00 raw-data: 0x" << std::hex << readData; + ((readData>>4)&0x7) << ((readData>>0)&0xF) << ":00 " << + (((readData>>7)&0x1)?"6-ROC":"3-ROC") << + " raw-data: 0x" << std::hex << readData; return o.str(); } @@ -603,10 +605,15 @@ uint32_t DTCLib::CFOandDTC_Registers::WriteRegister_(uint32_t dataToWrite, const { auto retry = 3; int errorCode; - uint32_t readbackValue; + bool needToVerify = NeedToVerifyRegisterWrite_(address); + uint32_t readbackValue = needToVerify?-1:dataToWrite; do { - errorCode = device_.write_register_checked(address, 100, dataToWrite, &readbackValue); + if(needToVerify) + errorCode = device_.write_register_checked(address, 100, dataToWrite, &readbackValue); + else + errorCode = device_.write_register(address, 100, dataToWrite); + --retry; } while (retry > 0 && errorCode != 0); if (errorCode != 0) @@ -626,13 +633,15 @@ uint32_t DTCLib::CFOandDTC_Registers::WriteRegister_(uint32_t dataToWrite, const } //verify register readback - if(1) + if(needToVerify) { - uint32_t readbackValue = ReadRegister_(address); - if(!CFOandDTCVerifyRegisterWrite_(address,readbackValue,dataToWrite)) //first check if it is a core register, i.e. CFOandDTC* + // readbackValue = ReadRegister_(address); //already read above by write_register_checked! + if(!CFOandDTCVerifyRegisterWrite_(address,readbackValue,dataToWrite)) //first check if it is a core register, i.e. CFOandDTC* VerifyRegisterWrite_(address,readbackValue,dataToWrite); //virtual function call return readbackValue; } //end verify register readback + + return readbackValue; } //end WriteRegister_() //return false if not a core register, i.e. CFOandDTC* diff --git a/dtcInterfaceLib/CFOandDTC_Registers.h b/dtcInterfaceLib/CFOandDTC_Registers.h index b90b16e..2efa861 100644 --- a/dtcInterfaceLib/CFOandDTC_Registers.h +++ b/dtcInterfaceLib/CFOandDTC_Registers.h @@ -302,6 +302,7 @@ class CFOandDTC_Registers protected: uint32_t WriteRegister_(uint32_t data, const CFOandDTC_Register& address); uint32_t ReadRegister_(const CFOandDTC_Register& address); + virtual bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) = 0; virtual void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) = 0; bool CFOandDTCVerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite); diff --git a/dtcInterfaceLib/DTC_Registers.h b/dtcInterfaceLib/DTC_Registers.h index 9554a40..eb984bf 100644 --- a/dtcInterfaceLib/DTC_Registers.h +++ b/dtcInterfaceLib/DTC_Registers.h @@ -1252,6 +1252,7 @@ class DTC_Registers : public CFOandDTC_Registers void WriteCurrentProgram(uint64_t program, DTC_OscillatorType oscillator); private: + bool NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address) override { return true; } void VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite) override; int DecodeHighSpeedDivider_(int input); diff --git a/dtcInterfaceLib/otsStyleCoutMacros.h b/dtcInterfaceLib/otsStyleCoutMacros.h index bc9dd2d..49820e9 100644 --- a/dtcInterfaceLib/otsStyleCoutMacros.h +++ b/dtcInterfaceLib/otsStyleCoutMacros.h @@ -32,6 +32,7 @@ #define Q(X) #X #define QUOTE(X) Q(X) #define __COUTV__(X) __COUT__ << QUOTE(X) << " = " << X << __E__ +#define __COUTTV__(X) __COUTT__ << QUOTE(X) << " = " << X << __E__ #define __COUTVS__(LVL,X) TLOG(TLVL_DEBUG + LVL) << __COUT_HDR__ << QUOTE(X) << " = " << X << __E__ std::string otsStyleStackTrace (void);