Line data Source code
1 : #include "cfoInterfaceLib/CFO_Registers.h"
2 :
3 : #include <assert.h>
4 : #include <unistd.h>
5 : #include <chrono>
6 : #include <cmath>
7 : #include <iomanip> // std::setw, std::setfill
8 : #include <sstream> // Convert uint to hex stLink
9 :
10 : #include "artdaq-core/Utilities/ExceptionHandler.hh" /*for artdaq::ExceptionHandler*/
11 : #include "artdaq-core/Utilities/ExceptionStackTrace.hh" /*for artdaq::ExceptionStackTrace*/
12 : #include "cfoInterfaceLib/CFO_Compiler.hh"
13 :
14 : #include "TRACE/tracemf.h"
15 : #define TLVL_ResetCFO TLVL_DEBUG + 5
16 : #define TLVL_AutogenDRP TLVL_DEBUG + 6
17 : #define TLVL_SERDESReset TLVL_DEBUG + 7
18 : #define TLVL_CalculateFreq TLVL_DEBUG + 8
19 :
20 : #include "dtcInterfaceLib/otsStyleCoutMacros.h"
21 :
22 : #undef __COUT_HDR__
23 : #define __COUT_HDR__ "CFO " << this->getDeviceUID() << ": "
24 :
25 0 : CFOLib::CFO_Registers::CFO_Registers(DTC_SimMode mode, int cfo, std::string expectedDesignVersion,
26 0 : bool skipInit, const std::string& uid)
27 0 : : simMode_(mode), usingDetectorEmulator_(false), dmaSize_(16)
28 : {
29 0 : TLOG(TLVL_INFO) << "CONSTRUCTOR";
30 :
31 0 : auto sim = getenv("CFOLIB_SIM_ENABLE");
32 0 : if (sim == nullptr)
33 : {
34 : // Give priority to CFOLIB_SIM_ENABLE, but go ahead and check DTCLIB_SIM_ENABLE, too
35 0 : sim = getenv("DTCLIB_SIM_ENABLE");
36 : }
37 0 : if (sim != nullptr)
38 : {
39 0 : switch (sim[0])
40 : {
41 0 : case '1':
42 : case 'e':
43 : case 'E':
44 0 : simMode_ = DTC_SimMode_Tracker; // sim enabled
45 0 : break;
46 0 : case '2':
47 : case 'l':
48 : case 'L':
49 0 : simMode_ = DTC_SimMode_Loopback;
50 0 : break;
51 0 : case '0':
52 : default:
53 0 : simMode_ = DTC_SimMode_Disabled;
54 0 : break;
55 : }
56 : }
57 :
58 0 : if (cfo == -1)
59 : {
60 0 : auto CFOE = getenv("CFOLIB_CFO");
61 0 : if (CFOE != nullptr)
62 : {
63 0 : cfo = atoi(CFOE);
64 : }
65 : else
66 : {
67 0 : CFOE = getenv("DTCLIB_DTC"); // Check both environment variables for CFO
68 0 : if (CFOE != nullptr)
69 : {
70 0 : cfo = atoi(CFOE);
71 : }
72 : else
73 : {
74 0 : cfo = 0;
75 : }
76 : }
77 : }
78 :
79 0 : SetSimMode(expectedDesignVersion, simMode_, cfo, skipInit, (uid == "" ? ("CFO" + std::to_string(cfo)) : uid));
80 0 : } // end costructor()
81 :
82 0 : CFOLib::CFO_Registers::~CFO_Registers()
83 : {
84 0 : TLOG(TLVL_INFO) << "DESTRUCTOR";
85 0 : } // end destructor()
86 :
87 0 : DTCLib::DTC_SimMode CFOLib::CFO_Registers::SetSimMode(std::string expectedDesignVersion, DTC_SimMode mode, int cfo,
88 : bool skipInit, const std::string& uid)
89 : {
90 0 : simMode_ = mode;
91 :
92 0 : TLOG(TLVL_INFO) << "Initializing CFO device, sim mode is " << DTC_SimModeConverter(simMode_).toString() << " for uid = " << uid << ", deviceIndex = " << cfo;
93 :
94 0 : device_.init(simMode_, cfo, /* simMemoryFile */ "", uid);
95 0 : if (expectedDesignVersion != "")
96 : {
97 0 : uint32_t parsedExpectedVersion = 0;
98 0 : std::string parsedDesignDate = "";
99 : try
100 : {
101 0 : parsedExpectedVersion = static_cast<uint32_t>(std::stoul(expectedDesignVersion, nullptr, 16));
102 0 : parsedDesignDate = ReadDesignDate(parsedExpectedVersion);
103 : }
104 0 : catch (...) // illegal/non-hex expectedDesignVersion
105 : {
106 0 : __SS__;
107 0 : ss << "Version mismatch (is Expected Firmware Version string legal?)! Expected CFO (device index #" << cfo << ") version is '" << expectedDesignVersion << "' while the readback version was '" << ReadDesignVersion() << ".'" << __E__;
108 0 : __SS_THROW__;
109 0 : }
110 :
111 0 : if (parsedExpectedVersion != ReadRegister_(CFOandDTC_Register_DesignDate))
112 : {
113 0 : __SS__;
114 0 : ss << "Version mismatch! Expected CFO (device index #" << cfo << ") version is '" << parsedDesignDate << "' (0x" << std::hex << parsedExpectedVersion << " != 0x" << ReadRegister_(CFOandDTC_Register_DesignDate) << ") while the readback version was '" << ReadDesignVersion() << ".'" << __E__;
115 0 : __SS_THROW__;
116 : // throw new DTC_WrongVersionException(expectedDesignVersion, ReadDesignVersion());
117 0 : }
118 0 : }
119 :
120 0 : if (skipInit)
121 : {
122 0 : __COUT_INFO__ << "SKIPPING Initializing device";
123 0 : return simMode_;
124 : }
125 :
126 0 : __COUT__ << "Initialize requested, setting device registers acccording to sim mode " << DTC_SimModeConverter(simMode_).toString();
127 : // Keep whatever links the hardware already has enabled; only normalize them to Tx+Rx
128 : // and make sure disabled links are out of loopback.
129 0 : for (auto link : CFO_Links)
130 : {
131 0 : DTC_LinkEnableMode current = ReadLinkEnabled(link);
132 0 : bool LinkEnabled = current.TransmitEnable || current.ReceiveEnable;
133 0 : if (!LinkEnabled)
134 : {
135 0 : DisableLink(link);
136 0 : SetSERDESLoopbackMode(link, DTC_SERDESLoopbackMode_Disabled);
137 : }
138 : else
139 : {
140 0 : EnableLink(link, DTC_LinkEnableMode(true, true));
141 : }
142 : }
143 :
144 0 : if (simMode_ != DTC_SimMode_Disabled)
145 : {
146 : // Set up hardware simulation mode: Link 0 Tx/Rx Enabled, Loopback Enabled, ROC Emulator Enabled. All other Links
147 : // disabled.
148 0 : for (auto link : CFO_Links)
149 : {
150 0 : if (simMode_ == DTC_SimMode_Loopback)
151 : {
152 0 : SetSERDESLoopbackMode(link, DTC_SERDESLoopbackMode_NearPCS);
153 : // SetMaxROCNumber(CFO_Link_0, CFO_ROC_0);
154 : }
155 : }
156 : // SetInternalSystemClock(); //RAR does not select clock to JA
157 0 : DisableEmbeddedClockMarker();
158 : }
159 0 : ReadMinDMATransferLength();
160 :
161 0 : __COUT__ << "Done setting device registers";
162 0 : return simMode_;
163 : }
164 :
165 0 : bool CFOLib::CFO_Registers::ReadDDRFIFOEmpty(std::optional<uint32_t> val)
166 : {
167 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_DesignStatus);
168 0 : return data[2];
169 : }
170 :
171 0 : bool CFOLib::CFO_Registers::ReadDDRClockCalibrationDone(std::optional<uint32_t> val)
172 : {
173 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_DesignStatus);
174 0 : return data[0];
175 : }
176 :
177 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDesignStatus()
178 : {
179 0 : auto form = CreateFormatter(CFOandDTC_Register_DesignStatus);
180 0 : form.description = "Design Status Register";
181 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
182 0 : form.vals.push_back(std::string("DDR FIFO Empty: [") + (ReadDDRFIFOEmpty(form.value) ? "x" : " ") + "]");
183 0 : form.vals.push_back(std::string("DDR Clock Calibration Done: [") + (ReadDDRClockCalibrationDone(form.value) ? "x" : " ") + "]");
184 0 : return form;
185 0 : }
186 :
187 : // RAR: Now just Soft Reset resets run plan
188 : // void CFOLib::CFO_Registers::ResetCFORunPlan()
189 : // {
190 : // TLOG(TLVL_ResetCFO) << __COUT_HDR__ << "SoftReset Run Plan start";
191 : // std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
192 : // data[27] = 1; // CFO Run Plan Reset bit
193 : // WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
194 : // data[27] = 0; // Restore CFO Run Plan Reset bit
195 : // WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
196 : // }
197 :
198 : // bool CFOLib::CFO_Registers::ReadResetCFORunPlan(std::optional<uint32_t> val)
199 : // {
200 : // std::bitset<32> dataSet = val.has_value()?*val:ReadRegister_(CFOandDTC_Register_Control);
201 : // return dataSet[27];
202 : // }
203 :
204 0 : void CFOLib::CFO_Registers::EnableLED7()
205 : {
206 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
207 0 : data[23] = 1;
208 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
209 0 : }
210 :
211 0 : void CFOLib::CFO_Registers::DisableReadLED7()
212 : {
213 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
214 0 : data[23] = 0;
215 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
216 0 : }
217 :
218 0 : bool CFOLib::CFO_Registers::ReadLED7State(std::optional<uint32_t> val)
219 : {
220 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_Control);
221 0 : return data[23];
222 : }
223 :
224 0 : void CFOLib::CFO_Registers::EnableAcceleratorRF0()
225 : {
226 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
227 0 : data[2] = 1;
228 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
229 0 : }
230 :
231 0 : void CFOLib::CFO_Registers::DisableAcceleratorRF0()
232 : {
233 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
234 0 : data[2] = 0;
235 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
236 0 : }
237 :
238 0 : bool CFOLib::CFO_Registers::ReadAcceleratorRF0Enable(std::optional<uint32_t> val)
239 : {
240 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_Control);
241 0 : return data[2];
242 : }
243 :
244 0 : void CFOLib::CFO_Registers::EnableEmbeddedClockMarker()
245 : {
246 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
247 0 : data[1] = 1;
248 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
249 0 : }
250 :
251 0 : void CFOLib::CFO_Registers::DisableEmbeddedClockMarker()
252 : {
253 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_Control);
254 0 : data[1] = 0;
255 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_Control);
256 0 : }
257 :
258 0 : bool CFOLib::CFO_Registers::ReadEmbeddedClockMarkerEnable(std::optional<uint32_t> val)
259 : {
260 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_Control);
261 0 : return data[1];
262 : }
263 :
264 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCFOControl()
265 : {
266 0 : auto form = CreateFormatter(CFOandDTC_Register_Control);
267 0 : form.description = "CFO Control";
268 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
269 : // ~~~ CFO Control Register (0x9100) ~~~
270 : // Bit Position Mode Default Value Description
271 : // 31 RW 0b0 CFO Soft Reset (Self-clearing)
272 : // 30-28 RO 0x0 Reserved
273 : // 27 RW 0b0 DDR Write Reset
274 : // 26-24 RO 0x0 Reserved
275 : // 23 RW 0b0 Reserved (Formerly DRP Auto Generate Enable)
276 : // 22-17 RO 0x00 Reserved
277 : // 16 RW 0b0 Led 7
278 : // 15-10 RO 0x0000 Reserved
279 : // 9 RW 0b0 Punched Clock Enable
280 : // 8 RW 0b0 SERDES Global Reset
281 : // 7-4 RO 0x0000 Reserved
282 : // 3 RW 0b0 CFO Loopback Test Launch Control
283 : // 2 RW 0x0 Accelerator RF-0 Event Window Input Enable
284 : // 1 RW 0b0 Embedded Clock Marker Enable
285 : // 0 RO 0b0 CFO Hard Reset (Self-clearing)
286 :
287 0 : form.vals.push_back(std::string("Bit-31 CFO Soft Reset (Self-clearing): [") + (ReadSoftReset(form.value) ? "x" : " ") + "]");
288 : // RAR: not just Soft Reset for resetting run plan
289 : // form.vals.push_back(std::string("Bit-27 CFO Run Plan Reset: [") + (ReadResetCFORunPlan(form.value) ? "x" : " ") + "]");
290 0 : form.vals.push_back(std::string("Bit-16 LED 7: [") + (ReadLED7State(form.value) ? "x" : " ") + "]");
291 0 : form.vals.push_back(std::string("Bit-09 Punched Clock Enable: [") + (CFOandDTC_Registers::ReadPunchEnable(form.value) ? "x" : " ") + "]");
292 0 : form.vals.push_back(std::string("Bit-08 SERDES Global Reset: [") + (CFOandDTC_Registers::ReadResetSERDES(form.value) ? "x" : " ") + "]");
293 0 : form.vals.push_back(std::string("Bit-02 Accelerator RF-0 Input Enable: [") + (ReadAcceleratorRF0Enable(form.value) ? "x" : " ") + "]");
294 0 : form.vals.push_back(std::string("Bit-01 Embedded Clock Marker Enable: [") + (ReadEmbeddedClockMarkerEnable(form.value) ? "x" : " ") + "]");
295 0 : form.vals.push_back(std::string("Bit-00 CFO Hard Reset (Self-clearing): [") + (ReadHardReset(form.value) ? "x" : " ") + "]");
296 0 : return form;
297 0 : }
298 :
299 : // DMA Transfer Length Register
300 0 : void CFOLib::CFO_Registers::SetTriggerDMATransferLength(uint16_t length)
301 : {
302 0 : auto data = ReadRegister_(CFOandDTC_Register_DMATransferLength);
303 0 : data = (data & 0x0000FFFF) + (length << 16);
304 0 : WriteRegister_(data, CFOandDTC_Register_DMATransferLength);
305 0 : }
306 :
307 0 : uint16_t CFOLib::CFO_Registers::ReadTriggerDMATransferLength(std::optional<uint32_t> val)
308 : {
309 0 : auto data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_DMATransferLength);
310 0 : data >>= 16;
311 0 : return static_cast<uint16_t>(data);
312 : }
313 :
314 0 : void CFOLib::CFO_Registers::SetMinDMATransferLength(uint16_t length)
315 : {
316 0 : auto data = ReadRegister_(CFOandDTC_Register_DMATransferLength);
317 0 : data = (data & 0xFFFF0000) + length;
318 0 : WriteRegister_(data, CFOandDTC_Register_DMATransferLength);
319 0 : }
320 :
321 0 : uint16_t CFOLib::CFO_Registers::ReadMinDMATransferLength(std::optional<uint32_t> val)
322 : {
323 0 : auto data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_DMATransferLength);
324 0 : data = data & 0x0000FFFF;
325 0 : dmaSize_ = static_cast<uint16_t>(data);
326 0 : return dmaSize_;
327 : }
328 :
329 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDMATransferLength()
330 : {
331 0 : auto form = CreateFormatter(CFOandDTC_Register_DMATransferLength);
332 0 : form.description = "DMA Transfer Length";
333 0 : form.vals.push_back(""); // translation
334 0 : std::stringstream o;
335 0 : o << "Trigger Length: 0x" << std::hex << ReadTriggerDMATransferLength(form.value);
336 0 : form.vals.push_back(o.str());
337 0 : std::stringstream p;
338 0 : p << "Minimum Length: 0x" << std::hex << ReadMinDMATransferLength(form.value);
339 0 : form.vals.push_back(p.str());
340 0 : return form;
341 0 : }
342 :
343 : // SERDES Loopback Enable Register
344 0 : void CFOLib::CFO_Registers::SetSERDESLoopbackMode(const CFO_Link_ID& link, const DTC_SERDESLoopbackMode& mode)
345 : {
346 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_SERDES_LoopbackEnable);
347 0 : std::bitset<3> modeSet = mode;
348 0 : data[3 * link] = modeSet[0];
349 0 : data[3 * link + 1] = modeSet[1];
350 0 : data[3 * link + 2] = modeSet[2];
351 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_SERDES_LoopbackEnable);
352 0 : }
353 :
354 0 : DTCLib::DTC_SERDESLoopbackMode CFOLib::CFO_Registers::ReadSERDESLoopback(const CFO_Link_ID& link, std::optional<uint32_t> val)
355 : {
356 0 : std::bitset<3> dataSet = (val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_LoopbackEnable)) >> (3 * link);
357 0 : return static_cast<DTC_SERDESLoopbackMode>(dataSet.to_ulong());
358 : }
359 :
360 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESLoopbackEnable()
361 : {
362 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_LoopbackEnable);
363 0 : form.description = "SERDES Loopback Enable";
364 0 : form.vals.push_back(""); // translation
365 0 : for (auto r : CFO_Links)
366 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": " +
367 0 : DTC_SERDESLoopbackModeConverter(ReadSERDESLoopback(r, form.value)).toString());
368 0 : return form;
369 0 : }
370 :
371 : // Clock Status Register
372 0 : bool CFOLib::CFO_Registers::ReadSERDESOscillatorIICError(std::optional<uint32_t> val)
373 : {
374 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_ClockOscillatorStatus);
375 0 : return dataSet[2];
376 : }
377 :
378 0 : bool CFOLib::CFO_Registers::ReadSERDESOscillatorInitializationComplete(std::optional<uint32_t> val)
379 : {
380 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_ClockOscillatorStatus);
381 0 : return dataSet[1];
382 : }
383 :
384 0 : bool CFOLib::CFO_Registers::WaitForSERDESOscillatorInitializationComplete(double max_wait)
385 : {
386 0 : auto start_time = std::chrono::steady_clock::now();
387 0 : while (
388 0 : !ReadSERDESOscillatorInitializationComplete() &&
389 0 : std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - start_time).count() <
390 : max_wait)
391 : {
392 0 : usleep(1000);
393 : }
394 0 : return ReadSERDESOscillatorInitializationComplete();
395 : }
396 :
397 0 : bool CFOLib::CFO_Registers::ReadTimingClockPLLLocked(std::optional<uint32_t> val)
398 : {
399 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_ClockOscillatorStatus);
400 0 : return dataSet[0];
401 : }
402 :
403 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatClockOscillatorStatus()
404 : {
405 0 : auto form = CreateFormatter(CFOandDTC_Register_ClockOscillatorStatus);
406 0 : form.description = "Clock Oscillator Status";
407 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
408 0 : form.vals.push_back(std::string("SERDES IIC Error: [") + (ReadSERDESOscillatorIICError(form.value) ? "x" : " ") + "]");
409 0 : form.vals.push_back(std::string("SERDES Init.Complete: [") +
410 0 : (ReadSERDESOscillatorInitializationComplete(form.value) ? "x" : " ") + "]");
411 0 : form.vals.push_back(std::string("Timing Clock PLL Lock: [") + (ReadTimingClockPLLLocked(form.value) ? "x" : " ") + "]");
412 0 : return form;
413 0 : }
414 :
415 : // Link Enable Register
416 0 : void CFOLib::CFO_Registers::EnableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode)
417 : {
418 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_LinkEnable);
419 0 : if (link == CFO_Link_ALL)
420 : {
421 0 : for (uint8_t i = 0; i < 8; ++i)
422 : {
423 0 : data[i] = mode.TransmitEnable;
424 0 : data[i + 8] = mode.ReceiveEnable;
425 : }
426 : }
427 : else
428 : {
429 0 : data[link] = mode.TransmitEnable;
430 0 : data[link + 8] = mode.ReceiveEnable;
431 : }
432 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_LinkEnable);
433 0 : }
434 :
435 0 : void CFOLib::CFO_Registers::DisableLink(const CFO_Link_ID& link, const DTC_LinkEnableMode& mode)
436 : {
437 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_LinkEnable);
438 0 : data[link] = data[link] && !mode.TransmitEnable;
439 0 : data[link + 8] = data[link + 8] && !mode.ReceiveEnable;
440 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_LinkEnable);
441 0 : }
442 :
443 0 : DTCLib::DTC_LinkEnableMode CFOLib::CFO_Registers::ReadLinkEnabled(const CFO_Link_ID& link, std::optional<uint32_t> val)
444 : {
445 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_LinkEnable);
446 0 : return DTC_LinkEnableMode(dataSet[link], dataSet[link + 8]);
447 : }
448 :
449 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatLinkEnable()
450 : {
451 0 : auto form = CreateFormatter(CFOandDTC_Register_LinkEnable);
452 0 : form.description = "Link Enable";
453 0 : form.vals.push_back(" ([TX, RX, Timing])");
454 0 : for (auto r : CFO_Links)
455 : {
456 0 : auto re = ReadLinkEnabled(r);
457 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" + (re.TransmitEnable ? "x" : " ") + "," +
458 0 : (re.ReceiveEnable ? "x" : " ") + "]");
459 : }
460 0 : return form;
461 0 : }
462 :
463 : // SERDES Reset Register
464 0 : void CFOLib::CFO_Registers::ResetSERDES(const CFO_Link_ID& link, int interval)
465 : {
466 0 : TLOG(TLVL_SERDESReset) << __COUT_HDR__ << "Entering SERDES Reset Loop for Link " << link;
467 0 : std::bitset<32> data = ReadRegister_(CFOandDTC_Register_SERDES_Reset);
468 0 : if (link == CFO_Link_ALL)
469 : {
470 0 : for (uint8_t i = 0; i < 8; ++i)
471 0 : data[i] = 1;
472 : }
473 : else
474 0 : data[link] = 1;
475 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_SERDES_Reset);
476 :
477 : // usleep(interval);
478 :
479 0 : data = ReadRegister_(CFOandDTC_Register_SERDES_Reset);
480 0 : if (link == CFO_Link_ALL)
481 : {
482 0 : for (uint8_t i = 0; i < 8; ++i)
483 0 : data[i] = 0;
484 : }
485 : else
486 0 : data[link] = 0;
487 0 : WriteRegister_(data.to_ulong(), CFOandDTC_Register_SERDES_Reset);
488 :
489 0 : auto resetDone = false;
490 0 : uint32_t loops = 0;
491 0 : while (!resetDone && ++loops < 100)
492 : {
493 0 : usleep(interval);
494 :
495 0 : if (link == CFO_Link_ALL)
496 : {
497 0 : uint32_t readData = ReadRegister_(CFOandDTC_Register_SERDES_ResetDone);
498 0 : resetDone = ((readData & 0xFF) == 0xFF);
499 : }
500 : else
501 0 : resetDone = ReadResetSERDESDone(link);
502 0 : TLOG(TLVL_SERDESReset) << __COUT_HDR__ << "End of SERDES Reset loop=" << loops << ", done=" << std::boolalpha << resetDone;
503 : }
504 0 : if (loops >= 100)
505 : {
506 0 : uint32_t resetDoneReg = ReadRegister_(CFOandDTC_Register_SERDES_ResetDone);
507 0 : uint32_t linkEnableReg = ReadRegister_(CFOandDTC_Register_LinkEnable);
508 : // __SS__
509 0 : __COUT_WARN__ << "Timeout waiting for SERDES Reset loop=" << loops
510 0 : << ". SERDES Reset Done mask=0x" << std::hex << (resetDoneReg & 0xFF)
511 0 : << ", Link Enable mask=0x" << (linkEnableReg & 0xFF) << std::dec
512 0 : << ". This may not be an issue if not all CFO 8 links are active.";
513 : // __SS_THROW__;
514 : }
515 0 : }
516 :
517 0 : void CFOLib::CFO_Registers::ResetAllSERDESPlls()
518 : {
519 0 : WriteRegister_(0x0000ff00, CFOandDTC_Register_SERDES_Reset);
520 0 : WriteRegister_(0x0, CFOandDTC_Register_SERDES_Reset);
521 0 : sleep(3);
522 0 : }
523 0 : void CFOLib::CFO_Registers::ResetAllSERDESTx()
524 : {
525 0 : WriteRegister_(0x00ff0000, CFOandDTC_Register_SERDES_Reset);
526 0 : WriteRegister_(0x0, CFOandDTC_Register_SERDES_Reset);
527 0 : sleep(3);
528 0 : }
529 :
530 0 : bool CFOLib::CFO_Registers::ReadResetSERDES(const CFO_Link_ID& link, std::optional<uint32_t> val)
531 : {
532 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_Reset);
533 0 : return dataSet[link];
534 : }
535 :
536 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESReset()
537 : {
538 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_Reset);
539 0 : form.description = "SERDES Reset";
540 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
541 0 : for (auto r : CFO_Links)
542 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
543 0 : (ReadResetSERDES(r, form.value) ? "x" : " ") + "]");
544 :
545 0 : return form;
546 0 : }
547 :
548 : // SERDES RX Disparity Error Register
549 0 : DTCLib::DTC_SERDESRXDisparityError CFOLib::CFO_Registers::ReadSERDESRXDisparityError(const CFO_Link_ID& link, std::optional<uint32_t> val)
550 : {
551 0 : return DTC_SERDESRXDisparityError(val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_RXDisparityError), static_cast<DTC_Link_ID>(link));
552 : }
553 :
554 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESRXDisparityError()
555 : {
556 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_RXDisparityError);
557 0 : form.description = "SERDES RX Disparity Error";
558 0 : form.vals.push_back(" ([H,L])");
559 0 : for (auto r : CFO_Links)
560 : {
561 0 : auto re = ReadSERDESRXDisparityError(r, form.value);
562 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" + std::to_string(re.GetData()[1]) + "," +
563 0 : std::to_string(re.GetData()[0]) + "]");
564 : }
565 0 : return form;
566 0 : }
567 :
568 : // SERDES RX Character Not In Table Error Register
569 0 : DTCLib::DTC_CharacterNotInTableError CFOLib::CFO_Registers::ReadSERDESRXCharacterNotInTableError(const CFO_Link_ID& link, std::optional<uint32_t> val)
570 : {
571 0 : return DTC_CharacterNotInTableError(val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_RXCharacterNotInTableError),
572 0 : static_cast<DTC_Link_ID>(link));
573 : }
574 :
575 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESRXCharacterNotInTableError()
576 : {
577 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_RXCharacterNotInTableError);
578 0 : form.description = "SERDES RX CNIT Error";
579 0 : form.vals.push_back(" ([H,L])");
580 0 : for (auto r : CFO_Links)
581 : {
582 0 : auto re = ReadSERDESRXCharacterNotInTableError(r, form.value);
583 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" + std::to_string(re.GetData()[1]) + "," +
584 0 : std::to_string(re.GetData()[0]) + "]");
585 : }
586 0 : return form;
587 0 : }
588 :
589 : // SERDES Unlock Error Register
590 0 : bool CFOLib::CFO_Registers::ReadSERDESUnlockError(const CFO_Link_ID& link, std::optional<uint32_t> val)
591 : {
592 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_UnlockError);
593 0 : return dataSet[link];
594 : }
595 :
596 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESUnlockError()
597 : {
598 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_UnlockError);
599 0 : form.description = "SERDES Unlock Error";
600 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
601 0 : for (auto r : CFO_Links)
602 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
603 0 : (ReadSERDESUnlockError(r, form.value) ? "x" : " ") +
604 : "]");
605 0 : return form;
606 0 : }
607 :
608 : // SERDES PLL Locked Register
609 0 : bool CFOLib::CFO_Registers::ReadSERDESPLLLocked(const CFO_Link_ID& link, std::optional<uint32_t> val)
610 : {
611 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_PLLLocked);
612 0 : return dataSet[link];
613 : }
614 :
615 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPLLLocked()
616 : {
617 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_PLLLocked);
618 0 : form.description = "SERDES PLL Locked";
619 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
620 0 : for (auto r : CFO_Links)
621 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" + (ReadSERDESPLLLocked(r, form.value) ? "x" : " ") + "]");
622 0 : form.vals.push_back(std::string("Clock to JA: [") + ((((form.value) >> 8) & 1) ? "x" : " ") + "]");
623 0 : form.vals.push_back(std::string("Clock from JA: [") + ((((form.value) >> 9) & 1) ? "x" : " ") + "]");
624 0 : return form;
625 0 : }
626 :
627 : // SERDES RX Status Register
628 0 : DTCLib::DTC_RXStatus CFOLib::CFO_Registers::ReadSERDESRXStatus(const CFO_Link_ID& link, std::optional<uint32_t> val)
629 : {
630 0 : auto data = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_RXStatus);
631 0 : data = (data >> (3 * link)) & 0x7;
632 0 : return static_cast<DTC_RXStatus>(data);
633 : }
634 :
635 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESRXStatus()
636 : {
637 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_RXStatus);
638 0 : form.description = "SERDES RX Status";
639 0 : form.vals.push_back(""); // translation
640 0 : for (auto r : CFO_Links)
641 : {
642 0 : auto re = ReadSERDESRXStatus(r, form.value);
643 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": " + DTC_RXStatusConverter(re).toString());
644 : }
645 :
646 0 : return form;
647 0 : }
648 :
649 : // SERDES Reset Done Register
650 0 : bool CFOLib::CFO_Registers::ReadResetSERDESDone(const CFO_Link_ID& link, std::optional<uint32_t> val)
651 : {
652 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFOandDTC_Register_SERDES_ResetDone);
653 0 : return dataSet[link];
654 : }
655 :
656 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESResetDone()
657 : {
658 0 : auto form = CreateFormatter(CFOandDTC_Register_SERDES_ResetDone);
659 0 : form.description = "SERDES Reset Done";
660 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
661 0 : for (auto r : CFO_Links)
662 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
663 0 : (ReadResetSERDESDone(r, form.value) ? "x" : " ") + "]");
664 0 : return form;
665 0 : }
666 :
667 : // SFP / SERDES Status Register
668 :
669 0 : bool CFOLib::CFO_Registers::ReadSERDESRXCDRLock(const CFO_Link_ID& link, std::optional<uint32_t> val)
670 : {
671 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_SFPSERDESStatus);
672 0 : return dataSet[link];
673 : }
674 :
675 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESRXCDRLock()
676 : {
677 0 : auto form = CreateFormatter(CFO_Register_SFPSERDESStatus);
678 0 : form.description = "SERDES CDR Lock";
679 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
680 0 : for (auto r : CFO_Links)
681 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
682 0 : (ReadSERDESRXCDRLock(r, form.value) ? "x" : " ") + "]");
683 0 : return form;
684 0 : }
685 :
686 0 : void CFOLib::CFO_Registers::SetBeamOnTimerPreset(uint32_t preset)
687 : {
688 0 : WriteRegister_(preset, CFO_Register_BeamOnTimerPreset);
689 0 : }
690 :
691 0 : uint32_t CFOLib::CFO_Registers::ReadBeamOnTimerPreset(std::optional<uint32_t> val) { return val.has_value() ? *val : ReadRegister_(CFO_Register_BeamOnTimerPreset); }
692 :
693 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatBeamOnTimerPreset()
694 : {
695 0 : auto form = CreateFormatter(CFO_Register_BeamOnTimerPreset);
696 0 : form.description = "Beam On Timer Preset Register";
697 0 : form.vals.push_back(std::to_string(ReadBeamOnTimerPreset(form.value)));
698 0 : return form;
699 0 : }
700 :
701 0 : void CFOLib::CFO_Registers::EnableBeamOnMode(const CFO_Link_ID& link)
702 : {
703 0 : SetLinuxTimestampPreset();
704 0 : std::bitset<32> data = ReadRegister_(CFO_Register_EnableBeamOnMode);
705 0 : data[0] = 1; // Enable beam on processing a single global flag as of December 2023
706 0 : WriteRegister_(data.to_ulong(), CFO_Register_EnableBeamOnMode);
707 0 : }
708 :
709 0 : void CFOLib::CFO_Registers::DisableBeamOnMode(const CFO_Link_ID& link)
710 : {
711 0 : std::bitset<32> data = ReadRegister_(CFO_Register_EnableBeamOnMode);
712 0 : data[0] = 0; // Enable beam on processing a single global flag as of December 2023
713 0 : WriteRegister_(data.to_ulong(), CFO_Register_EnableBeamOnMode);
714 0 : }
715 :
716 0 : bool CFOLib::CFO_Registers::ReadBeamOnMode(std::optional<uint32_t> val)
717 : {
718 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_EnableBeamOnMode);
719 0 : return data[0]; // Enable beam on processing a single global flag as of December 2023
720 : }
721 :
722 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatBeamOnMode()
723 : {
724 0 : auto form = CreateFormatter(CFO_Register_EnableBeamOnMode);
725 0 : form.description = "Enable Beam On Mode Register";
726 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
727 : // Enable beam on processing a single global flag as of December 2023
728 0 : form.vals.push_back(std::string("Beam On Processing ") + ": [" + (ReadBeamOnMode(form.value) ? "x" : " ") + "]");
729 0 : return form;
730 0 : }
731 :
732 0 : void CFOLib::CFO_Registers::EnableBeamOffMode(const CFO_Link_ID& link)
733 : {
734 0 : SetLinuxTimestampPreset();
735 0 : std::bitset<32> data = ReadRegister_(CFO_Register_EnableBeamOffMode);
736 0 : data[0] = 1; // Enable beam off processing a single global flag as of December 2023
737 0 : WriteRegister_(data.to_ulong(), CFO_Register_EnableBeamOffMode);
738 0 : }
739 :
740 0 : void CFOLib::CFO_Registers::DisableBeamOffMode(const CFO_Link_ID& link)
741 : {
742 0 : std::bitset<32> data = ReadRegister_(CFO_Register_EnableBeamOffMode);
743 0 : data[0] = 0; // Enable off processing a single global flag as of December 2023
744 0 : WriteRegister_(data.to_ulong(), CFO_Register_EnableBeamOffMode);
745 0 : }
746 :
747 0 : bool CFOLib::CFO_Registers::ReadBeamOffMode(std::optional<uint32_t> val)
748 : {
749 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_EnableBeamOffMode);
750 0 : return data[0]; // Enable beam on processing a single global flag as of December 2023
751 : }
752 :
753 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatBeamOffMode()
754 : {
755 0 : auto form = CreateFormatter(CFO_Register_EnableBeamOffMode);
756 0 : form.description = "Enable Beam Off Mode Register";
757 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
758 : // Enable off processing a single global flag as of December 2023
759 0 : form.vals.push_back(std::string("Beam Off Processing ") + ": [" + (ReadBeamOffMode(form.value) ? "x" : " ") + "]");
760 0 : return form;
761 0 : }
762 :
763 : // LEGACY: register 0x9154 repurposed as RunPlanSubrunEvtLimit; these functions are no longer valid
764 : // void CFOLib::CFO_Registers::SetClockMarkerIntervalCount(uint32_t data)
765 : // {
766 : // WriteRegister_(data, CFO_Register_ClockMarkerIntervalCount);
767 : // }
768 :
769 : // LEGACY: register 0x9154 repurposed as RunPlanSubrunEvtLimit; these functions are no longer valid
770 : // uint32_t CFOLib::CFO_Registers::ReadClockMarkerIntervalCount(std::optional<uint32_t> val)
771 : // {
772 : // return val.has_value() ? *val : ReadRegister_(CFO_Register_ClockMarkerIntervalCount);
773 : // }
774 :
775 : // LEGACY: register 0x9154 repurposed as RunPlanSubrunEvtLimit; these functions are no longer valid
776 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatClockMarkerIntervalCount()
777 : // {
778 : // auto form = CreateFormatter(CFO_Register_ClockMarkerIntervalCount);
779 : // form.description = "40 MHz Clock Marker Interval Count Register";
780 : // form.vals.push_back(std::to_string(ReadClockMarkerIntervalCount()));
781 : // return form;
782 : // }
783 :
784 : // SEREDES Oscillator Registers
785 0 : uint32_t CFOLib::CFO_Registers::ReadSERDESOscillatorFrequency(std::optional<uint32_t> val)
786 : {
787 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_SERDESOscillatorFrequency);
788 : }
789 0 : void CFOLib::CFO_Registers::SetSERDESOscillatorFrequency(uint32_t freq)
790 : {
791 0 : WriteRegister_(freq, CFO_Register_SERDESOscillatorFrequency);
792 0 : }
793 0 : bool CFOLib::CFO_Registers::ReadSERDESOscillatorIICInterfaceReset(std::optional<uint32_t> val)
794 : {
795 0 : auto dataSet = std::bitset<32>(val.has_value() ? *val : ReadRegister_(CFO_Register_SERDESClock_IICBusControl));
796 0 : return dataSet[31];
797 : }
798 :
799 0 : void CFOLib::CFO_Registers::ResetSERDESOscillatorIICInterface()
800 : {
801 0 : auto bs = std::bitset<32>();
802 0 : bs[31] = 1;
803 0 : WriteRegister_(bs.to_ulong(), CFO_Register_SERDESClock_IICBusControl);
804 0 : while (ReadSERDESOscillatorIICInterfaceReset())
805 : {
806 0 : usleep(1000);
807 : }
808 0 : }
809 :
810 : // Jitter Attenuator CSR Register
811 : /// <summary>
812 : /// Read the value of the Jitter Attenuator Select
813 : /// </summary>
814 : /// <returns>Jitter Attenuator Select value</returns>
815 0 : std::bitset<2> CFOLib::CFO_Registers::ReadJitterAttenuatorSelect(std::optional<uint32_t> val) { return CFOandDTC_Registers::ReadJitterAttenuatorSelect(CFO_Register_JitterAttenuatorCSR, val); }
816 :
817 : /// <summary>
818 : /// Set the Jitter Attenuator Select bits
819 : /// </summary>
820 : /// <param name="data">Value to set</param>
821 0 : void CFOLib::CFO_Registers::SetJitterAttenuatorSelect(std::bitset<2> data, bool alsoResetJA /* = false */) { CFOandDTC_Registers::SetJitterAttenuatorSelect(CFO_Register_JitterAttenuatorCSR, data, alsoResetJA); }
822 :
823 : /// <summary>
824 : /// Read the Jitter Attenuator Reset bit
825 : /// </summary>
826 : /// <returns>Value of the Jitter Attenuator Reset bit</returns>
827 0 : bool CFOLib::CFO_Registers::ReadJitterAttenuatorReset(std::optional<uint32_t> val) { return CFOandDTC_Registers::ReadJitterAttenuatorReset(CFO_Register_JitterAttenuatorCSR, val); }
828 0 : bool CFOLib::CFO_Registers::ReadJitterAttenuatorLocked(std::optional<uint32_t> val) { return CFOandDTC_Registers::ReadJitterAttenuatorLocked(CFO_Register_JitterAttenuatorCSR, val); }
829 :
830 : /// <summary>
831 : /// Reset the Jitter Attenuator
832 : /// </summary>
833 0 : void CFOLib::CFO_Registers::ResetJitterAttenuator() { CFOandDTC_Registers::ResetJitterAttenuator(CFO_Register_JitterAttenuatorCSR); }
834 :
835 : /// <summary>
836 : /// Formats the register's current value for register dumps
837 : /// </summary>
838 : /// <returns>RegisterFormatter object containing register information</returns>
839 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatJitterAttenuatorCSR() { return CFOandDTC_Registers::FormatJitterAttenuatorCSR(CFO_Register_JitterAttenuatorCSR); }
840 :
841 0 : uint64_t CFOLib::CFO_Registers::ReadSERDESOscillatorParameters(std::optional<uint32_t> val)
842 : {
843 0 : uint64_t data = (static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 7)) << 40) +
844 0 : (static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 8)) << 32) +
845 0 : (static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 9)) << 24) +
846 0 : (static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 10)) << 16) +
847 0 : (static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 11)) << 8) +
848 0 : static_cast<uint64_t>(ReadSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 12));
849 0 : return data;
850 : }
851 0 : void CFOLib::CFO_Registers::SetSERDESOscillatorParameters(uint64_t program)
852 : {
853 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 0x89, 0x10);
854 :
855 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 7, static_cast<uint8_t>(program >> 40));
856 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 8, static_cast<uint8_t>(program >> 32));
857 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 9, static_cast<uint8_t>(program >> 24));
858 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 10, static_cast<uint8_t>(program >> 16));
859 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 11, static_cast<uint8_t>(program >> 8));
860 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 12, static_cast<uint8_t>(program));
861 :
862 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 0x89, 0);
863 0 : WriteSERDESIICInterface(DTC_IICSERDESBusAddress_EVB, 0x87, 0x40);
864 0 : }
865 :
866 0 : DTCLib::DTC_SerdesClockSpeed CFOLib::CFO_Registers::ReadSERDESOscillatorClock(std::optional<uint32_t> val)
867 : {
868 0 : auto freq = ReadSERDESOscillatorFrequency(val);
869 :
870 : // Clocks should be accurate to 30 ppm
871 0 : if (freq > 156250000 - 4687.5 && freq < 156250000 + 4687.5) return DTC_SerdesClockSpeed_3125Gbps;
872 0 : if (freq > 125000000 - 3750 && freq < 125000000 + 3750) return DTC_SerdesClockSpeed_25Gbps;
873 0 : return DTC_SerdesClockSpeed_Unknown;
874 : }
875 0 : void CFOLib::CFO_Registers::SetSERDESOscillatorClock(DTC_SerdesClockSpeed speed)
876 : {
877 : double targetFreq;
878 0 : switch (speed)
879 : {
880 0 : case DTC_SerdesClockSpeed_25Gbps:
881 0 : targetFreq = 125000000.0;
882 0 : break;
883 0 : case DTC_SerdesClockSpeed_3125Gbps:
884 0 : targetFreq = 156250000.0;
885 0 : break;
886 0 : case DTC_SerdesClockSpeed_48Gbps:
887 0 : targetFreq = 240000000.0;
888 0 : break;
889 0 : default:
890 0 : targetFreq = 0.0;
891 0 : break;
892 : }
893 0 : if (SetNewOscillatorFrequency(targetFreq))
894 : {
895 0 : for (auto& Link : CFO_Links)
896 : {
897 0 : ResetSERDES(Link, 1000);
898 : }
899 : }
900 0 : }
901 :
902 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESOscillatorFrequency()
903 : {
904 0 : auto form = CreateFormatter(CFO_Register_SERDESOscillatorFrequency);
905 0 : form.description = "SERDES Oscillator Frequency";
906 0 : std::stringstream o;
907 0 : o << std::dec << ReadSERDESOscillatorFrequency(form.value);
908 0 : form.vals.push_back(o.str());
909 0 : return form;
910 0 : }
911 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESOscillatorControl()
912 : {
913 0 : auto form = CreateFormatter(CFO_Register_SERDESClock_IICBusControl);
914 0 : form.description = "SERDES Oscillator IIC Bus Control";
915 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
916 0 : form.vals.push_back(std::string("Reset: [") + (ReadSERDESOscillatorIICInterfaceReset() ? "x" : " ") + "]");
917 0 : return form;
918 0 : }
919 :
920 : /// Timestamp Preset Registers
921 0 : void CFOLib::CFO_Registers::SetEventWindowTagPreset(const DTC_EventWindowTag& preset)
922 : {
923 0 : auto timestamp = preset.GetEventWindowTag();
924 0 : auto timestampLow = static_cast<uint32_t>(timestamp.to_ulong());
925 0 : timestamp >>= 32;
926 0 : auto timestampHigh = static_cast<uint16_t>(timestamp.to_ulong());
927 :
928 0 : WriteRegister_(timestampLow, CFO_Register_TimestampPreset0);
929 0 : WriteRegister_(timestampHigh, CFO_Register_TimestampPreset1);
930 0 : }
931 :
932 0 : DTCLib::DTC_EventWindowTag CFOLib::CFO_Registers::ReadTimestampPreset(std::optional<uint32_t> val)
933 : {
934 0 : auto timestampLow = val.has_value() ? *val : ReadRegister_(CFO_Register_TimestampPreset0);
935 0 : DTC_EventWindowTag output;
936 0 : output.SetEventWindowTag(timestampLow, static_cast<uint16_t>(ReadRegister_(CFO_Register_TimestampPreset1)));
937 0 : return output;
938 0 : }
939 :
940 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTimestampPreset0()
941 : {
942 0 : auto form = CreateFormatter(CFO_Register_TimestampPreset0);
943 0 : form.description = "Timestamp Preset 0";
944 0 : std::stringstream o;
945 0 : o << "0x" << std::hex << ReadRegister_(CFO_Register_TimestampPreset0);
946 0 : form.vals.push_back(o.str());
947 0 : return form;
948 0 : }
949 :
950 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTimestampPreset1()
951 : {
952 0 : auto form = CreateFormatter(CFO_Register_TimestampPreset1);
953 0 : form.description = "Timestamp Preset 1";
954 0 : std::stringstream o;
955 0 : o << "0x" << std::hex << ReadRegister_(CFO_Register_TimestampPreset1);
956 0 : form.vals.push_back(o.str());
957 0 : return form;
958 0 : }
959 :
960 : /// Linux Timestamp Register
961 0 : void CFOLib::CFO_Registers::SetLinuxTimestampPreset()
962 : {
963 0 : WriteRegister_(time(0), CFO_Register_LinuxTimestamp);
964 0 : }
965 :
966 0 : time_t CFOLib::CFO_Registers::ReadLinuxTimestamp()
967 : {
968 0 : auto val = ReadRegister_(CFO_Register_LinuxTimestamp);
969 0 : return val;
970 : }
971 :
972 : // FIFO Full Error Flags Registers
973 0 : void CFOLib::CFO_Registers::ClearFIFOFullErrorFlags(const CFO_Link_ID& link)
974 : {
975 0 : auto flags = ReadFIFOFullErrorFlags(link);
976 0 : std::bitset<32> data0 = 0;
977 :
978 0 : data0[link] = flags.CFOLinkInput;
979 :
980 0 : WriteRegister_(data0.to_ulong(), CFO_Register_FIFOFullErrorFlag0);
981 0 : }
982 :
983 0 : DTCLib::DTC_FIFOFullErrorFlags CFOLib::CFO_Registers::ReadFIFOFullErrorFlags(const CFO_Link_ID& link, std::optional<uint32_t> val)
984 : {
985 0 : std::bitset<32> data0 = val.has_value() ? *val : ReadRegister_(CFO_Register_FIFOFullErrorFlag0);
986 0 : DTC_FIFOFullErrorFlags flags;
987 :
988 0 : flags.CFOLinkInput = data0[link];
989 :
990 0 : return flags;
991 : }
992 :
993 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatFIFOFullErrorFlag0()
994 : {
995 0 : auto form = CreateFormatter(CFO_Register_FIFOFullErrorFlag0);
996 0 : form.description = "FIFO Full Error Flags 0";
997 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
998 0 : for (auto r : CFO_Links)
999 : {
1000 0 : auto re = ReadFIFOFullErrorFlags(r, form.value);
1001 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" + (re.CFOLinkInput ? "x" : " ") + "]");
1002 : }
1003 0 : return form;
1004 0 : }
1005 :
1006 : // Receive Packet Error Register
1007 0 : void CFOLib::CFO_Registers::ClearRXElasticBufferUnderrun(const CFO_Link_ID& link)
1008 : {
1009 0 : std::bitset<32> data = ReadRegister_(CFO_Register_ReceivePacketError);
1010 0 : data[static_cast<int>(link) + 24] = 0;
1011 0 : WriteRegister_(data.to_ulong(), CFO_Register_ReceivePacketError);
1012 0 : }
1013 :
1014 0 : bool CFOLib::CFO_Registers::ReadRXElasticBufferUnderrun(const CFO_Link_ID& link, std::optional<uint32_t> val)
1015 : {
1016 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_ReceivePacketError);
1017 0 : return data[static_cast<int>(link) + 24];
1018 : }
1019 :
1020 0 : void CFOLib::CFO_Registers::ClearRXElasticBufferOverrun(const CFO_Link_ID& link)
1021 : {
1022 0 : std::bitset<32> data = ReadRegister_(CFO_Register_ReceivePacketError);
1023 0 : data[static_cast<int>(link) + 16] = 0;
1024 0 : WriteRegister_(data.to_ulong(), CFO_Register_ReceivePacketError);
1025 0 : }
1026 :
1027 0 : bool CFOLib::CFO_Registers::ReadRXElasticBufferOverrun(const CFO_Link_ID& link, std::optional<uint32_t> val)
1028 : {
1029 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_ReceivePacketError);
1030 0 : return data[static_cast<int>(link) + 16];
1031 : }
1032 :
1033 0 : void CFOLib::CFO_Registers::ClearPacketError(const CFO_Link_ID& link)
1034 : {
1035 0 : std::bitset<32> data = ReadRegister_(CFO_Register_ReceivePacketError);
1036 0 : data[static_cast<int>(link) + 8] = 0;
1037 0 : WriteRegister_(data.to_ulong(), CFO_Register_ReceivePacketError);
1038 0 : }
1039 :
1040 0 : bool CFOLib::CFO_Registers::ReadPacketError(const CFO_Link_ID& link, std::optional<uint32_t> val)
1041 : {
1042 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_ReceivePacketError);
1043 0 : return data[static_cast<int>(link) + 8];
1044 : }
1045 :
1046 0 : void CFOLib::CFO_Registers::ClearPacketCRCError(const CFO_Link_ID& link)
1047 : {
1048 0 : std::bitset<32> data = ReadRegister_(CFO_Register_ReceivePacketError);
1049 0 : data[static_cast<int>(link)] = 0;
1050 0 : WriteRegister_(data.to_ulong(), CFO_Register_ReceivePacketError);
1051 0 : }
1052 :
1053 0 : bool CFOLib::CFO_Registers::ReadPacketCRCError(const CFO_Link_ID& link, std::optional<uint32_t> val)
1054 : {
1055 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_ReceivePacketError);
1056 0 : return data[static_cast<int>(link)];
1057 : }
1058 :
1059 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketError()
1060 : {
1061 0 : auto form = CreateFormatter(CFO_Register_ReceivePacketError);
1062 0 : form.description = "Receive Packet Error";
1063 0 : form.vals.push_back(" ([CRC, PacketError, RX Overrun, RX Underrun])");
1064 0 : for (auto r : CFO_Links)
1065 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
1066 0 : (ReadPacketCRCError(r, form.value) ? "x" : " ") + "," +
1067 0 : (ReadPacketError(r, form.value) ? "x" : " ") + "," +
1068 0 : (ReadRXElasticBufferOverrun(r, form.value) ? "x" : " ") + "," +
1069 0 : (ReadRXElasticBufferUnderrun(r, form.value) ? "x" : " ") + "]");
1070 0 : return form;
1071 0 : }
1072 :
1073 0 : void CFOLib::CFO_Registers::SetEventWindowEmulatorInterval(const uint32_t& data)
1074 : {
1075 0 : __SS__ << "Access attempt of CFO_Register_EventWindowEmulatorIntervalTime = 0x91A0,.."
1076 : "this register was deleted in Firmware version: Nov/09/2023 11:00 raw-data: 0x23110911; "
1077 0 : "please update the software to use the CFO Run Plan to control the Event Window duration."
1078 0 : << __E__;
1079 0 : __SS_THROW__;
1080 : // WriteRegister_(data, CFO_Register_EventWindowEmulatorIntervalTime);
1081 0 : }
1082 :
1083 0 : uint32_t CFOLib::CFO_Registers::ReadEventWindowEmulatorInterval(std::optional<uint32_t> val)
1084 : {
1085 0 : __SS__ << "Access attempt of CFO_Register_EventWindowEmulatorIntervalTime = 0x91A0,.."
1086 : "this register was deleted in Firmware version: Nov/09/2023 11:00 raw-data: 0x23110911; "
1087 0 : "please update the software to use the CFO Run Plan to control the Event Window duration."
1088 0 : << __E__;
1089 0 : __SS_THROW__;
1090 : // return val.has_value()?*val:ReadRegister_(CFO_Register_EventWindowEmulatorIntervalTime);
1091 0 : }
1092 :
1093 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatEventWindowEmulatorIntervalTime()
1094 : {
1095 0 : __SS__ << "Access attempt of CFO_Register_EventWindowEmulatorIntervalTime = 0x91A0,.."
1096 : "this register was deleted in Firmware version: Nov/09/2023 11:00 raw-data: 0x23110911; "
1097 0 : "please update the software to use the CFO Run Plan to control the Event Window duration."
1098 0 : << __E__;
1099 0 : __SS_THROW__;
1100 : // auto form = CreateFormatter(CFO_Register_EventWindowEmulatorIntervalTime);
1101 : // form.description = "Event Window Emulator Interval Time";
1102 : // form.vals.push_back(std::to_string(ReadEventWindowEmulatorInterval()));
1103 : // return form;
1104 0 : }
1105 :
1106 0 : void CFOLib::CFO_Registers::SetEventWindowHoldoffTime(const uint32_t& data)
1107 : {
1108 0 : WriteRegister_(data, CFO_Register_EventWindowHoldoffTime);
1109 0 : }
1110 :
1111 0 : uint32_t CFOLib::CFO_Registers::ReadEventWindowHoldoffTime(std::optional<uint32_t> val)
1112 : {
1113 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_EventWindowHoldoffTime);
1114 : }
1115 :
1116 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatEventWindowHoldoffTime()
1117 : {
1118 0 : auto form = CreateFormatter(CFO_Register_EventWindowHoldoffTime);
1119 0 : form.description = "Event Window Holdoff Time";
1120 0 : form.vals.push_back(std::to_string(ReadEventWindowHoldoffTime(form.value)));
1121 0 : return form;
1122 0 : }
1123 :
1124 0 : bool CFOLib::CFO_Registers::ReadEventWindowTimeoutError(const CFO_Link_ID& link, std::optional<uint32_t> val)
1125 : {
1126 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_EventWindowTimeoutError);
1127 0 : return dataSet[link];
1128 : }
1129 :
1130 0 : void CFOLib::CFO_Registers::ClearEventWindowTimeoutError(const CFO_Link_ID& link)
1131 : {
1132 0 : std::bitset<32> data = ReadRegister_(CFO_Register_EventWindowTimeoutError);
1133 0 : data[link] = 1;
1134 0 : WriteRegister_(data.to_ulong(), CFO_Register_EventWindowTimeoutError);
1135 0 : }
1136 :
1137 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatEventWindowTimeoutError()
1138 : {
1139 0 : auto form = CreateFormatter(CFO_Register_EventWindowTimeoutError);
1140 0 : form.description = "Event Window Timeout Error";
1141 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
1142 0 : for (auto r : CFO_Links)
1143 0 : form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
1144 0 : (ReadEventWindowTimeoutError(r, form.value) ? "x" : " ") + "]");
1145 0 : return form;
1146 0 : }
1147 :
1148 0 : void CFOLib::CFO_Registers::SetEventWindowTimeoutInterval(const uint32_t& data)
1149 : {
1150 0 : WriteRegister_(data, CFO_Register_EventWindowTimeoutValue);
1151 0 : }
1152 :
1153 0 : uint32_t CFOLib::CFO_Registers::ReadEventWindowTimeoutInterval(std::optional<uint32_t> val)
1154 : {
1155 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_EventWindowTimeoutValue);
1156 : }
1157 :
1158 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatEventWindowTimeoutInterval()
1159 : {
1160 0 : auto form = CreateFormatter(CFO_Register_EventWindowTimeoutValue);
1161 0 : form.description = "Event Window Timeout Value";
1162 0 : form.vals.push_back(std::to_string(ReadEventWindowTimeoutInterval()));
1163 0 : return form;
1164 0 : }
1165 :
1166 : // // SERDES Counter Registers
1167 : // void CFOLib::CFO_Registers::ClearReceiveByteCount(const CFO_Link_ID& link)
1168 : // {
1169 : // CFO_Register reg;
1170 : // switch (link)
1171 : // {
1172 : // case CFO_Link_0:
1173 : // reg = CFO_Register_ReceiveByteCountDataLink0;
1174 : // break;
1175 : // case CFO_Link_1:
1176 : // reg = CFO_Register_ReceiveByteCountDataLink1;
1177 : // break;
1178 : // case CFO_Link_2:
1179 : // reg = CFO_Register_ReceiveByteCountDataLink2;
1180 : // break;
1181 : // case CFO_Link_3:
1182 : // reg = CFO_Register_ReceiveByteCountDataLink3;
1183 : // break;
1184 : // case CFO_Link_4:
1185 : // reg = CFO_Register_ReceiveByteCountDataLink4;
1186 : // break;
1187 : // case CFO_Link_5:
1188 : // reg = CFO_Register_ReceiveByteCountDataLink5;
1189 : // break;
1190 : // case CFO_Link_6:
1191 : // reg = CFO_Register_ReceiveByteCountDataLink6;
1192 : // break;
1193 : // case CFO_Link_7:
1194 : // reg = CFO_Register_ReceiveByteCountDataLink7;
1195 : // break;
1196 : // default: {
1197 : // __SS__ << "Illegal link index provided: " << link << __E__;
1198 : // __SS_THROW__;
1199 : // }
1200 : // }
1201 : // WriteRegister_(0, reg);
1202 : // }
1203 :
1204 : // uint32_t CFOLib::CFO_Registers::ReadReceiveByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val)
1205 : // {
1206 : // CFO_Register reg;
1207 : // switch (link)
1208 : // {
1209 : // case CFO_Link_0:
1210 : // reg = CFO_Register_ReceiveByteCountDataLink0;
1211 : // break;
1212 : // case CFO_Link_1:
1213 : // reg = CFO_Register_ReceiveByteCountDataLink1;
1214 : // break;
1215 : // case CFO_Link_2:
1216 : // reg = CFO_Register_ReceiveByteCountDataLink2;
1217 : // break;
1218 : // case CFO_Link_3:
1219 : // reg = CFO_Register_ReceiveByteCountDataLink3;
1220 : // break;
1221 : // case CFO_Link_4:
1222 : // reg = CFO_Register_ReceiveByteCountDataLink4;
1223 : // break;
1224 : // case CFO_Link_5:
1225 : // reg = CFO_Register_ReceiveByteCountDataLink5;
1226 : // break;
1227 : // case CFO_Link_6:
1228 : // reg = CFO_Register_ReceiveByteCountDataLink6;
1229 : // break;
1230 : // case CFO_Link_7:
1231 : // reg = CFO_Register_ReceiveByteCountDataLink7;
1232 : // break;
1233 : // default: {
1234 : // __SS__ << "Illegal link index provided: " << link << __E__;
1235 : // __SS_THROW__;
1236 : // }
1237 : // }
1238 : // return val.has_value() ? *val : ReadRegister_(reg);
1239 : // }
1240 :
1241 : // void CFOLib::CFO_Registers::ClearReceivePacketCount(const CFO_Link_ID& link)
1242 : // {
1243 : // CFO_Register reg;
1244 : // switch (link)
1245 : // {
1246 : // case CFO_Link_0:
1247 : // reg = CFO_Register_ReceivePacketCountDataLink0;
1248 : // break;
1249 : // case CFO_Link_1:
1250 : // reg = CFO_Register_ReceivePacketCountDataLink1;
1251 : // break;
1252 : // case CFO_Link_2:
1253 : // reg = CFO_Register_ReceivePacketCountDataLink2;
1254 : // break;
1255 : // case CFO_Link_3:
1256 : // reg = CFO_Register_ReceivePacketCountDataLink3;
1257 : // break;
1258 : // case CFO_Link_4:
1259 : // reg = CFO_Register_ReceivePacketCountDataLink4;
1260 : // break;
1261 : // case CFO_Link_5:
1262 : // reg = CFO_Register_ReceivePacketCountDataLink5;
1263 : // break;
1264 : // case CFO_Link_6:
1265 : // reg = CFO_Register_ReceivePacketCountDataLink6;
1266 : // break;
1267 : // case CFO_Link_7:
1268 : // reg = CFO_Register_ReceivePacketCountDataLink7;
1269 : // break;
1270 : // default: {
1271 : // __SS__ << "Illegal link index provided: " << link << __E__;
1272 : // __SS_THROW__;
1273 : // }
1274 : // }
1275 : // WriteRegister_(0, reg);
1276 : // }
1277 :
1278 : // uint32_t CFOLib::CFO_Registers::ReadReceivePacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val)
1279 : // {
1280 : // CFO_Register reg;
1281 : // switch (link)
1282 : // {
1283 : // case CFO_Link_0:
1284 : // reg = CFO_Register_ReceivePacketCountDataLink0;
1285 : // break;
1286 : // case CFO_Link_1:
1287 : // reg = CFO_Register_ReceivePacketCountDataLink1;
1288 : // break;
1289 : // case CFO_Link_2:
1290 : // reg = CFO_Register_ReceivePacketCountDataLink2;
1291 : // break;
1292 : // case CFO_Link_3:
1293 : // reg = CFO_Register_ReceivePacketCountDataLink3;
1294 : // break;
1295 : // case CFO_Link_4:
1296 : // reg = CFO_Register_ReceivePacketCountDataLink4;
1297 : // break;
1298 : // case CFO_Link_5:
1299 : // reg = CFO_Register_ReceivePacketCountDataLink5;
1300 : // break;
1301 : // case CFO_Link_6:
1302 : // reg = CFO_Register_ReceivePacketCountDataLink6;
1303 : // break;
1304 : // case CFO_Link_7:
1305 : // reg = CFO_Register_ReceivePacketCountDataLink7;
1306 : // break;
1307 : // default: {
1308 : // __SS__ << "Illegal link index provided: " << link << __E__;
1309 : // __SS_THROW__;
1310 : // }
1311 : // }
1312 : // return val.has_value() ? *val : ReadRegister_(reg);
1313 : // }
1314 :
1315 : // void CFOLib::CFO_Registers::ClearTransmitByteCount(const CFO_Link_ID& link)
1316 : // {
1317 : // CFO_Register reg;
1318 : // switch (link)
1319 : // {
1320 : // case CFO_Link_0:
1321 : // reg = CFO_Register_TransmitByteCountDataLink0;
1322 : // break;
1323 : // case CFO_Link_1:
1324 : // reg = CFO_Register_TransmitByteCountDataLink1;
1325 : // break;
1326 : // case CFO_Link_2:
1327 : // reg = CFO_Register_TransmitByteCountDataLink2;
1328 : // break;
1329 : // case CFO_Link_3:
1330 : // reg = CFO_Register_TransmitByteCountDataLink3;
1331 : // break;
1332 : // case CFO_Link_4:
1333 : // reg = CFO_Register_TransmitByteCountDataLink4;
1334 : // break;
1335 : // case CFO_Link_5:
1336 : // reg = CFO_Register_TransmitByteCountDataLink5;
1337 : // break;
1338 : // case CFO_Link_6:
1339 : // reg = CFO_Register_TransmitByteCountDataLink6;
1340 : // break;
1341 : // case CFO_Link_7:
1342 : // reg = CFO_Register_TransmitByteCountDataLink7;
1343 : // break;
1344 : // default: {
1345 : // __SS__ << "Illegal link index provided: " << link << __E__;
1346 : // __SS_THROW__;
1347 : // }
1348 : // }
1349 : // WriteRegister_(0, reg);
1350 : // }
1351 :
1352 : // uint32_t CFOLib::CFO_Registers::ReadTransmitByteCount(const CFO_Link_ID& link, std::optional<uint32_t> val)
1353 : // {
1354 : // CFO_Register reg;
1355 : // switch (link)
1356 : // {
1357 : // case CFO_Link_0:
1358 : // reg = CFO_Register_TransmitByteCountDataLink0;
1359 : // break;
1360 : // case CFO_Link_1:
1361 : // reg = CFO_Register_TransmitByteCountDataLink1;
1362 : // break;
1363 : // case CFO_Link_2:
1364 : // reg = CFO_Register_TransmitByteCountDataLink2;
1365 : // break;
1366 : // case CFO_Link_3:
1367 : // reg = CFO_Register_TransmitByteCountDataLink3;
1368 : // break;
1369 : // case CFO_Link_4:
1370 : // reg = CFO_Register_TransmitByteCountDataLink4;
1371 : // break;
1372 : // case CFO_Link_5:
1373 : // reg = CFO_Register_TransmitByteCountDataLink5;
1374 : // break;
1375 : // case CFO_Link_6:
1376 : // reg = CFO_Register_TransmitByteCountDataLink6;
1377 : // break;
1378 : // case CFO_Link_7:
1379 : // reg = CFO_Register_TransmitByteCountDataLink7;
1380 : // break;
1381 : // default: {
1382 : // __SS__ << "Illegal link index provided: " << link << __E__;
1383 : // __SS_THROW__;
1384 : // }
1385 : // }
1386 : // return val.has_value() ? *val : ReadRegister_(reg);
1387 : // }
1388 :
1389 : // void CFOLib::CFO_Registers::ClearTransmitPacketCount(const CFO_Link_ID& link)
1390 : // {
1391 : // CFO_Register reg;
1392 : // switch (link)
1393 : // {
1394 : // case CFO_Link_0:
1395 : // reg = CFO_Register_TransmitPacketCountDataLink0;
1396 : // break;
1397 : // case CFO_Link_1:
1398 : // reg = CFO_Register_TransmitPacketCountDataLink1;
1399 : // break;
1400 : // case CFO_Link_2:
1401 : // reg = CFO_Register_TransmitPacketCountDataLink2;
1402 : // break;
1403 : // case CFO_Link_3:
1404 : // reg = CFO_Register_TransmitPacketCountDataLink3;
1405 : // break;
1406 : // case CFO_Link_4:
1407 : // reg = CFO_Register_TransmitPacketCountDataLink4;
1408 : // break;
1409 : // case CFO_Link_5:
1410 : // reg = CFO_Register_TransmitPacketCountDataLink5;
1411 : // break;
1412 : // case CFO_Link_6:
1413 : // reg = CFO_Register_TransmitPacketCountDataLink6;
1414 : // break;
1415 : // case CFO_Link_7:
1416 : // reg = CFO_Register_TransmitPacketCountDataLink7;
1417 : // break;
1418 : // default: {
1419 : // __SS__ << "Illegal link index provided: " << link << __E__;
1420 : // __SS_THROW__;
1421 : // }
1422 : // }
1423 : // WriteRegister_(0, reg);
1424 : // }
1425 :
1426 : // uint32_t CFOLib::CFO_Registers::ReadTransmitPacketCount(const CFO_Link_ID& link, std::optional<uint32_t> val)
1427 : // {
1428 : // CFO_Register reg;
1429 : // switch (link)
1430 : // {
1431 : // case CFO_Link_0:
1432 : // reg = CFO_Register_TransmitPacketCountDataLink0;
1433 : // break;
1434 : // case CFO_Link_1:
1435 : // reg = CFO_Register_TransmitPacketCountDataLink1;
1436 : // break;
1437 : // case CFO_Link_2:
1438 : // reg = CFO_Register_TransmitPacketCountDataLink2;
1439 : // break;
1440 : // case CFO_Link_3:
1441 : // reg = CFO_Register_TransmitPacketCountDataLink3;
1442 : // break;
1443 : // case CFO_Link_4:
1444 : // reg = CFO_Register_TransmitPacketCountDataLink4;
1445 : // break;
1446 : // case CFO_Link_5:
1447 : // reg = CFO_Register_TransmitPacketCountDataLink5;
1448 : // break;
1449 : // case CFO_Link_6:
1450 : // reg = CFO_Register_TransmitPacketCountDataLink6;
1451 : // break;
1452 : // case CFO_Link_7:
1453 : // reg = CFO_Register_TransmitPacketCountDataLink7;
1454 : // break;
1455 : // default: {
1456 : // __SS__ << "Illegal link index provided: " << link << __E__;
1457 : // __SS_THROW__;
1458 : // }
1459 : // }
1460 : // return val.has_value() ? *val : ReadRegister_(reg);
1461 : // }
1462 :
1463 0 : uint32_t CFOLib::CFO_Registers::ReadReceiveRF0MarkerCount(std::optional<uint32_t> val)
1464 : {
1465 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_ReceiveRF0MarkerCount);
1466 0 : return static_cast<uint32_t>(data.to_ulong());
1467 : }
1468 0 : uint32_t CFOLib::CFO_Registers::ReadTransmitHeartbeatPacketCount(std::optional<uint32_t> val)
1469 : {
1470 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_TransmitHeartbeatPacketCount);
1471 0 : return static_cast<uint32_t>(data.to_ulong());
1472 : }
1473 0 : uint32_t CFOLib::CFO_Registers::ReadTransmitEventWindowMarkerCount(std::optional<uint32_t> val)
1474 : {
1475 0 : std::bitset<32> data = val.has_value() ? *val : ReadRegister_(CFO_Register_TransmitEventWindowMarkerCount);
1476 0 : return static_cast<uint32_t>(data.to_ulong());
1477 : }
1478 :
1479 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveRF0MarkerCount()
1480 : {
1481 0 : auto form = CreateFormatter(CFO_Register_ReceiveRF0MarkerCount);
1482 0 : form.description = "Receive RF0 Marker Count";
1483 0 : std::stringstream o;
1484 0 : o << "0x" << std::hex << ReadReceiveRF0MarkerCount(form.value);
1485 0 : form.vals.push_back(o.str());
1486 0 : return form;
1487 0 : }
1488 :
1489 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitHeartbeatPacketCount()
1490 : {
1491 0 : auto form = CreateFormatter(CFO_Register_TransmitHeartbeatPacketCount);
1492 0 : form.description = "Transmit Heartbeat Packet Count";
1493 0 : std::stringstream o;
1494 0 : o << "0x" << std::hex << ReadTransmitHeartbeatPacketCount(form.value);
1495 0 : form.vals.push_back(o.str());
1496 0 : return form;
1497 0 : }
1498 :
1499 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitEventWindowMarkerCount()
1500 : {
1501 0 : auto form = CreateFormatter(CFO_Register_TransmitEventWindowMarkerCount);
1502 0 : form.description = "Transmit Event Window Marker Count";
1503 0 : std::stringstream o;
1504 0 : o << "0x" << std::hex << ReadTransmitEventWindowMarkerCount(form.value);
1505 0 : form.vals.push_back(o.str());
1506 0 : return form;
1507 0 : }
1508 :
1509 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink0()
1510 : // {
1511 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink0);
1512 : // form.description = "Receive Byte Count: Link 0";
1513 : // std::stringstream o;
1514 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_0, form.value);
1515 : // form.vals.push_back(o.str());
1516 : // return form;
1517 : // }
1518 :
1519 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink1()
1520 : // {
1521 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink1);
1522 : // form.description = "Receive Byte Count: Link 1";
1523 : // std::stringstream o;
1524 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_1, form.value);
1525 : // form.vals.push_back(o.str());
1526 : // return form;
1527 : // }
1528 :
1529 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink2()
1530 : // {
1531 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink2);
1532 : // form.description = "Receive Byte Count: Link 2";
1533 : // std::stringstream o;
1534 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_2, form.value);
1535 : // form.vals.push_back(o.str());
1536 : // return form;
1537 : // }
1538 :
1539 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink3()
1540 : // {
1541 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink3);
1542 : // form.description = "Receive Byte Count: Link 3";
1543 : // std::stringstream o;
1544 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_3, form.value);
1545 : // form.vals.push_back(o.str());
1546 : // return form;
1547 : // }
1548 :
1549 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink4()
1550 : // {
1551 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink4);
1552 : // form.description = "Receive Byte Count: Link 4";
1553 : // std::stringstream o;
1554 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_4, form.value);
1555 : // form.vals.push_back(o.str());
1556 : // return form;
1557 : // }
1558 :
1559 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink5()
1560 : // {
1561 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink5);
1562 : // form.description = "Receive Byte Count: Link 5";
1563 : // std::stringstream o;
1564 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_5, form.value);
1565 : // form.vals.push_back(o.str());
1566 : // return form;
1567 : // }
1568 :
1569 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink6()
1570 : // {
1571 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink6);
1572 : // form.description = "Receive Byte Count: Link 6";
1573 : // std::stringstream o;
1574 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_6, form.value);
1575 : // form.vals.push_back(o.str());
1576 : // return form;
1577 : // }
1578 :
1579 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceiveByteCountLink7()
1580 : // {
1581 : // auto form = CreateFormatter(CFO_Register_ReceiveByteCountDataLink7);
1582 : // form.description = "Receive Byte Count: Link 7";
1583 : // std::stringstream o;
1584 : // o << "0x" << std::hex << ReadReceiveByteCount(CFO_Link_7, form.value);
1585 : // form.vals.push_back(o.str());
1586 : // return form;
1587 : // }
1588 :
1589 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink0()
1590 : // {
1591 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink0);
1592 : // form.description = "Receive Packet Count: Link 0";
1593 : // std::stringstream o;
1594 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_0);
1595 : // form.vals.push_back(o.str());
1596 : // return form;
1597 : // }
1598 :
1599 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink1()
1600 : // {
1601 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink1);
1602 : // form.description = "Receive Packet Count: Link 1";
1603 : // std::stringstream o;
1604 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_1);
1605 : // form.vals.push_back(o.str());
1606 : // return form;
1607 : // }
1608 :
1609 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink2()
1610 : // {
1611 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink2);
1612 : // form.description = "Receive Packet Count: Link 2";
1613 : // std::stringstream o;
1614 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_2);
1615 : // form.vals.push_back(o.str());
1616 : // return form;
1617 : // }
1618 :
1619 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink3()
1620 : // {
1621 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink3);
1622 : // form.description = "Receive Packet Count: Link 3";
1623 : // std::stringstream o;
1624 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_3);
1625 : // form.vals.push_back(o.str());
1626 : // return form;
1627 : // }
1628 :
1629 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink4()
1630 : // {
1631 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink4);
1632 : // form.description = "Receive Packet Count: Link 4";
1633 : // std::stringstream o;
1634 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_4);
1635 : // form.vals.push_back(o.str());
1636 : // return form;
1637 : // }
1638 :
1639 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink5()
1640 : // {
1641 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink5);
1642 : // form.description = "Receive Packet Count: Link 5";
1643 : // std::stringstream o;
1644 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_5);
1645 : // form.vals.push_back(o.str());
1646 : // return form;
1647 : // }
1648 :
1649 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink6()
1650 : // {
1651 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink6);
1652 : // form.description = "Receive Packet Count: Link 6";
1653 : // std::stringstream o;
1654 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_6);
1655 : // form.vals.push_back(o.str());
1656 : // return form;
1657 : // }
1658 :
1659 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatReceivePacketCountLink7()
1660 : // {
1661 : // auto form = CreateFormatter(CFO_Register_ReceivePacketCountDataLink7);
1662 : // form.description = "Receive Packet Count: Link 7";
1663 : // std::stringstream o;
1664 : // o << "0x" << std::hex << ReadReceivePacketCount(CFO_Link_7);
1665 : // form.vals.push_back(o.str());
1666 : // return form;
1667 : // }
1668 :
1669 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink0()
1670 : // {
1671 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink0);
1672 : // form.description = "Transmit Byte Count: Link 0";
1673 : // std::stringstream o;
1674 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_0);
1675 : // form.vals.push_back(o.str());
1676 : // return form;
1677 : // }
1678 :
1679 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink1()
1680 : // {
1681 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink1);
1682 : // form.description = "Transmit Byte Count: Link 1";
1683 : // std::stringstream o;
1684 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_1);
1685 : // form.vals.push_back(o.str());
1686 : // return form;
1687 : // }
1688 :
1689 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink2()
1690 : // {
1691 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink2);
1692 : // form.description = "Transmit Byte Count: Link 2";
1693 : // std::stringstream o;
1694 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_2);
1695 : // form.vals.push_back(o.str());
1696 : // return form;
1697 : // }
1698 :
1699 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink3()
1700 : // {
1701 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink3);
1702 : // form.description = "Transmit Byte Count: Link 3";
1703 : // std::stringstream o;
1704 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_3);
1705 : // form.vals.push_back(o.str());
1706 : // return form;
1707 : // }
1708 :
1709 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink4()
1710 : // {
1711 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink4);
1712 : // form.description = "Transmit Byte Count: Link 4";
1713 : // std::stringstream o;
1714 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_4);
1715 : // form.vals.push_back(o.str());
1716 : // return form;
1717 : // }
1718 :
1719 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink5()
1720 : // {
1721 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink5);
1722 : // form.description = "Transmit Byte Count: Link 5";
1723 : // std::stringstream o;
1724 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_5);
1725 : // form.vals.push_back(o.str());
1726 : // return form;
1727 : // }
1728 :
1729 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink6()
1730 : // {
1731 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink6);
1732 : // form.description = "Transmit Byte Count: Link 6";
1733 : // std::stringstream o;
1734 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_6);
1735 : // form.vals.push_back(o.str());
1736 : // return form;
1737 : // }
1738 :
1739 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTramsitByteCountLink7()
1740 : // {
1741 : // auto form = CreateFormatter(CFO_Register_TransmitByteCountDataLink7);
1742 : // form.description = "Transmit Byte Count: Link 7";
1743 : // std::stringstream o;
1744 : // o << "0x" << std::hex << ReadTransmitByteCount(CFO_Link_7);
1745 : // form.vals.push_back(o.str());
1746 : // return form;
1747 : // }
1748 :
1749 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink0()
1750 : // {
1751 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink0);
1752 : // form.description = "Transmit Packet Count: Link 0";
1753 : // std::stringstream o;
1754 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_0);
1755 : // form.vals.push_back(o.str());
1756 : // return form;
1757 : // }
1758 :
1759 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink1()
1760 : // {
1761 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink1);
1762 : // form.description = "Transmit Packet Count: Link 1";
1763 : // std::stringstream o;
1764 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_1);
1765 : // form.vals.push_back(o.str());
1766 : // return form;
1767 : // }
1768 :
1769 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink2()
1770 : // {
1771 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink2);
1772 : // form.description = "Transmit Packet Count: Link 2";
1773 : // std::stringstream o;
1774 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_2);
1775 : // form.vals.push_back(o.str());
1776 : // return form;
1777 : // }
1778 :
1779 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink3()
1780 : // {
1781 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink3);
1782 : // form.description = "Transmit Packet Count: Link 3";
1783 : // std::stringstream o;
1784 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_3);
1785 : // form.vals.push_back(o.str());
1786 : // return form;
1787 : // }
1788 :
1789 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink4()
1790 : // {
1791 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink4);
1792 : // form.description = "Transmit Packet Count: Link 4";
1793 : // std::stringstream o;
1794 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_4);
1795 : // form.vals.push_back(o.str());
1796 : // return form;
1797 : // }
1798 :
1799 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink5()
1800 : // {
1801 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink5);
1802 : // form.description = "Transmit Packet Count: Link 5";
1803 : // std::stringstream o;
1804 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_5);
1805 : // form.vals.push_back(o.str());
1806 : // return form;
1807 : // }
1808 :
1809 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink6()
1810 : // {
1811 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink6);
1812 : // form.description = "Transmit Packet Count: Link 6";
1813 : // std::stringstream o;
1814 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_6);
1815 : // form.vals.push_back(o.str());
1816 : // return form;
1817 : // }
1818 :
1819 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatTransmitPacketCountLink7()
1820 : // {
1821 : // auto form = CreateFormatter(CFO_Register_TransmitPacketCountDataLink7);
1822 : // form.description = "Transmit Packet Count: Link 7";
1823 : // std::stringstream o;
1824 : // o << "0x" << std::hex << ReadTransmitPacketCount(CFO_Link_7);
1825 : // form.vals.push_back(o.str());
1826 : // return form;
1827 : // }
1828 :
1829 : // DMA Address Registers
1830 0 : void CFOLib::CFO_Registers::SetDMAWriteStartAddress(const uint32_t& address)
1831 : {
1832 0 : WriteRegister_(address, CFO_Register_DDRMemoryDMAWriteStartAddress);
1833 0 : }
1834 :
1835 0 : uint32_t CFOLib::CFO_Registers::ReadDMAWriteStartAddress(std::optional<uint32_t> val)
1836 : {
1837 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_DDRMemoryDMAWriteStartAddress);
1838 : }
1839 :
1840 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDMAWriteStartAddress()
1841 : {
1842 0 : auto form = CreateFormatter(CFO_Register_DDRMemoryDMAWriteStartAddress);
1843 0 : form.description = "DDR Memory DMA Write Start Address";
1844 0 : form.vals.push_back(std::to_string(ReadDMAWriteStartAddress(form.value)));
1845 0 : return form;
1846 0 : }
1847 :
1848 0 : void CFOLib::CFO_Registers::SetDMAReadStartAddress(const uint32_t& address)
1849 : {
1850 0 : WriteRegister_(address, CFO_Register_DDRMemoryDMAReadStartAddress);
1851 0 : }
1852 :
1853 0 : uint32_t CFOLib::CFO_Registers::ReadDMAReadStartAddress(std::optional<uint32_t> val)
1854 : {
1855 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_DDRMemoryDMAReadStartAddress);
1856 : }
1857 :
1858 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDMAReadStartAddress()
1859 : {
1860 0 : auto form = CreateFormatter(CFO_Register_DDRMemoryDMAWriteStartAddress);
1861 0 : form.description = "DDR Memory DMA Read Start Address";
1862 0 : form.vals.push_back(std::to_string(ReadDMAReadStartAddress(form.value)));
1863 0 : return form;
1864 0 : }
1865 :
1866 0 : void CFOLib::CFO_Registers::SetDMAReadByteCount(const uint32_t& bytes)
1867 : {
1868 0 : WriteRegister_(bytes, CFO_Register_DDRMemoryDMAReadByteCount);
1869 0 : }
1870 :
1871 0 : uint32_t CFOLib::CFO_Registers::ReadDMAReadByteCount(std::optional<uint32_t> val) { return val.has_value() ? *val : ReadRegister_(CFO_Register_DDRMemoryDMAReadByteCount); }
1872 :
1873 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatDMAReadByteCount()
1874 : {
1875 0 : auto form = CreateFormatter(CFO_Register_DDRMemoryDMAWriteStartAddress);
1876 0 : form.description = "DDR Memory DMA Read Byte Count/Enable";
1877 0 : form.vals.push_back(std::to_string(ReadDMAReadByteCount(form.value)));
1878 0 : return form;
1879 0 : }
1880 :
1881 0 : void CFOLib::CFO_Registers::SetRunPlanBeamOnBaseAddress(const uint32_t& address)
1882 : {
1883 0 : WriteRegister_(address, CFO_Register_RunPlanBeamOnBaseAddress);
1884 0 : }
1885 :
1886 0 : uint32_t CFOLib::CFO_Registers::ReadRunPlanBeamOnBaseAddress(std::optional<uint32_t> val) { return val.has_value() ? *val : ReadRegister_(CFO_Register_RunPlanBeamOnBaseAddress); }
1887 :
1888 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanBeamOnBaseAddress()
1889 : {
1890 0 : auto form = CreateFormatter(CFO_Register_RunPlanBeamOnBaseAddress);
1891 0 : form.description = "DDR Memory Beam On Base Address";
1892 0 : form.vals.push_back(std::to_string(ReadRunPlanBeamOnBaseAddress(form.value)));
1893 0 : return form;
1894 0 : }
1895 :
1896 0 : void CFOLib::CFO_Registers::SetRunPlanBeamOffBaseAddress(const uint32_t& address)
1897 : {
1898 0 : WriteRegister_(address, CFO_Register_RunPlanBeamOffBaseAddress);
1899 0 : }
1900 :
1901 0 : uint32_t CFOLib::CFO_Registers::ReadRunPlanBeamOffBaseAddress(std::optional<uint32_t> val)
1902 : {
1903 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_RunPlanBeamOffBaseAddress);
1904 : }
1905 :
1906 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanBeamOffBaseAddress()
1907 : {
1908 0 : auto form = CreateFormatter(CFO_Register_RunPlanBeamOffBaseAddress);
1909 0 : form.description = "DDR Memory Beam Off Base Address";
1910 0 : form.vals.push_back(std::to_string(ReadRunPlanBeamOffBaseAddress()));
1911 0 : return form;
1912 0 : }
1913 :
1914 0 : void CFOLib::CFO_Registers::SetRunPlanData(const std::string& inputData, const uint32_t& runPlanBaseAddress)
1915 : {
1916 0 : __COUTTV__(inputData.size());
1917 0 : __COUT__ << "Writing run plan of size " << inputData.size() << " to base address 0x" << std::hex << std::setw(8) << std::setfill('0') << runPlanBaseAddress << __E__;
1918 :
1919 0 : auto dataPtr = reinterpret_cast<const uint8_t*>(&inputData[0]);
1920 :
1921 : // primary run plan write loop
1922 0 : WriteRegister_(runPlanBaseAddress, CFO_Register_RunPlan_Address); // resets run plan BRAM write address
1923 0 : for (uint32_t l = 0; l < inputData.size(); l += 4)
1924 : {
1925 : // CFO_Register_RunPlan_Address = 0x9314,
1926 : // CFO_Register_RunPlan_Data = 0x9318,
1927 0 : WriteRegister_(*((uint32_t*)(&(dataPtr[l]))), CFO_Register_RunPlan_Data); // write data then increment BRAM address
1928 0 : __COUTT__ << std::hex << std::setw(8) << std::setfill('0') << "addr 0x" << (runPlanBaseAddress + l / 4) << " data 0x" << *((uint32_t*)(&(dataPtr[l]))) << __E__;
1929 : } // end primary run plan write loop
1930 :
1931 0 : __COUT__ << "Verifying run plan of size " << inputData.size() << " to base address 0x" << std::hex << std::setw(8) << std::setfill('0') << runPlanBaseAddress << __E__;
1932 : // now verify run plan w/readback (throws exception on mismatch)
1933 0 : CompareRunPlanData(inputData, runPlanBaseAddress);
1934 :
1935 0 : } // end SetRunPlanData()
1936 :
1937 : /// @brief Read back run plan data from BRAM and compare to input data for validation.
1938 : /// Note that the run plan BRAM read address auto-increments with each read, so we just need to set it once at the beginning of the function.
1939 : /// If mismatches has a value, it will be filled with a map of mismatches instead of throwing an exception on the first mismatch.
1940 : /// Otherwise (std::nullopt), an exception will be thrown on the first mismatch with details of the failure.
1941 : /// @param inputData The binary run plan data to compare against the readback.
1942 : /// @param runPlanBaseAddress The base BRAM address at which the run plan was written.
1943 : /// @param mismatches Optional reference to a map that will be filled with any mismatches found, where the key is the
1944 : /// address of the mismatch and the value is a pair of (expected, actual) data values.
1945 : /// Pass std::nullopt (default) to throw an exception on the first mismatch instead of collecting them.
1946 : /// @param andMasks Optional reference to a vector that will be filled with the 48-bit mask values found in
1947 : /// AND_MODE_BITS instructions during the readback scan. Pass std::nullopt (default) to skip collection.
1948 : /// @param orMasks Optional reference to a vector that will be filled with the 48-bit mask values found in
1949 : /// OR_MODE_BITS instructions during the readback scan. Pass std::nullopt (default) to skip collection.
1950 0 : void CFOLib::CFO_Registers::CompareRunPlanData(const std::string& inputData, const uint32_t& runPlanBaseAddress,
1951 : std::optional<std::reference_wrapper<std::map<uint32_t /* address */,
1952 : std::pair<uint32_t /* expected */,
1953 : uint32_t /* actual */>>>>
1954 : mismatches,
1955 : std::optional<std::reference_wrapper<std::vector<uint64_t>>> andMasks /* = std::nullopt */,
1956 : std::optional<std::reference_wrapper<std::vector<uint64_t>>> orMasks /* = std::nullopt */)
1957 : {
1958 0 : auto dataPtr = reinterpret_cast<const uint8_t*>(&inputData[0]);
1959 :
1960 0 : WriteRegister_(runPlanBaseAddress, CFO_Register_RunPlan_Address); // resets run plan BRAM write address
1961 0 : uint32_t val, lastVal = 0;
1962 0 : for (uint32_t l = 0; l < inputData.size(); l += 4)
1963 : {
1964 0 : val = ReadRegister_(CFO_Register_RunPlan_Data);
1965 :
1966 0 : __COUTT__ << std::hex << std::setw(8) << std::setfill('0') << "addr 0x" << (runPlanBaseAddress + l / 4) << " data 0x" << *((uint32_t*)(&(dataPtr[l]))) << " =? rdata 0x" << val << __E__;
1967 :
1968 0 : if ((andMasks || orMasks) && l % 8 == 4) // check opcodes
1969 : {
1970 0 : uint8_t opCode = ((*((uint32_t*)(&(dataPtr[l])))) >> 24) & 0xFF;
1971 0 : if (andMasks && opCode == (uint8_t)CFOLib::CFO_Compiler::CFO_INSTR::AND_MODE_BITS)
1972 : {
1973 0 : andMasks->get().push_back((uint64_t)lastVal | ((uint64_t)(val & 0xFFFF) << 32));
1974 0 : __COUTT__ << "Found AND line = " << l / 8 << " --> 0x" << std::hex << andMasks->get().back() << __E__;
1975 : }
1976 0 : if (orMasks && opCode == (uint8_t)CFOLib::CFO_Compiler::CFO_INSTR::OR_MODE_BITS)
1977 : {
1978 0 : orMasks->get().push_back((uint64_t)lastVal | ((uint64_t)(val & 0xFFFF) << 32));
1979 0 : __COUTT__ << "Found OR line = " << l / 8 << " --> 0x" << std::hex << orMasks->get().back() << __E__;
1980 : }
1981 : }
1982 :
1983 0 : if (val != *((uint32_t*)(&(dataPtr[l]))))
1984 : {
1985 0 : uint8_t opCode = -1;
1986 0 : if (l % 8 == 4)
1987 0 : opCode = ((*((uint32_t*)(&(dataPtr[l])))) >> 24) & 0xFF;
1988 0 : else if (l + 4 < inputData.size())
1989 0 : opCode = ((*((uint32_t*)(&(dataPtr[l + 4])))) >> 24) & 0xFF;
1990 0 : if (opCode == (uint8_t)CFOLib::CFO_Compiler::CFO_INSTR::OR_SINGLESHOT_MODE_BITS)
1991 : {
1992 0 : if (l % 8 == 4 && opCode == (val >> 24)) // if opcode matches, ignore mismatch since single-shot mode bit instructions fire once and then clear 48-bit value
1993 : {
1994 0 : __COUTT__ << "Ignoring mismatch at line #" << l / 8 << " for OR_SINGLESHOT_MODE_BITS instruction since opcode matches and data auto-clears after firing." << __E__;
1995 0 : continue;
1996 0 : }
1997 0 : if (l % 8 == 0)
1998 : {
1999 0 : __COUTT__ << "Ignoring mismatch at line #" << l / 8 << " for OR_SINGLESHOT_MODE_BITS instruction since opcode matches for this data and data auto-clears after firing." << __E__;
2000 0 : continue;
2001 0 : }
2002 : }
2003 :
2004 0 : __SS__ << "Run plan validation failed at line #" << l / 8 << " "
2005 0 : << "addr 0x" << std::hex << std::setw(8) << std::setfill('0') << (runPlanBaseAddress + l / 4)
2006 0 : << " expected data 0x" << std::hex << std::setw(8) << std::setfill('0') << *((uint32_t*)(&(dataPtr[l])))
2007 0 : << " != readback data 0x" << std::hex << std::setw(8) << std::setfill('0') << val << __E__;
2008 0 : if (!mismatches)
2009 0 : __SS_THROW__;
2010 :
2011 0 : __COUTT__ << ss.str() << __E__;
2012 0 : mismatches->get()[runPlanBaseAddress + l / 4] = std::make_pair(*((uint32_t*)(&(dataPtr[l]))), val);
2013 0 : }
2014 :
2015 0 : lastVal = val;
2016 : } // end run plan validation
2017 :
2018 0 : } // end CompareRunPlanData()
2019 :
2020 : /// Read current tag bits from two registers and concatenate the full 48-bit value
2021 0 : uint64_t CFOLib::CFO_Registers::ReadRunPlanCurrentTag()
2022 : {
2023 0 : uint64_t val = ReadRegister_(CFO_Register_RunPlan_EventTag0);
2024 0 : val |= (uint64_t(ReadRegister_(CFO_Register_RunPlan_EventTag1))) << 32;
2025 0 : return val;
2026 : } // end ReadRunPlanCurrentTag()
2027 :
2028 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanCurrentTag()
2029 : {
2030 0 : uint64_t currentTag = ReadRunPlanCurrentTag();
2031 0 : auto form = CreateFormatter(CFO_Register_RunPlan_EventTag1, false /* getValue */);
2032 0 : form.value = uint32_t(currentTag >> 32); // show high 32-bits of tag in hex value field
2033 0 : form.description = "Run Plan Current Tag";
2034 : {
2035 0 : std::stringstream oss;
2036 0 : oss << "0x" << std::hex << std::setw(8) << std::setfill('0') << uint32_t(currentTag); // show hex format low 32-bits of tag
2037 0 : form.vals.push_back(oss.str());
2038 0 : }
2039 : { // show full 64-bit number
2040 0 : std::stringstream oss;
2041 0 : oss << std::dec << currentTag << " " << std::scientific << static_cast<double>(currentTag) << " (0x" << std::hex << currentTag << ")";
2042 0 : form.vals.push_back(oss.str());
2043 0 : }
2044 0 : return form;
2045 0 : } // end FormatRunPlanCurrentTag()
2046 :
2047 : /// Read current mode bits from two registers and concatenate the full 48-bit value
2048 0 : uint64_t CFOLib::CFO_Registers::ReadRunPlanCurrentMode()
2049 : {
2050 0 : uint64_t val = ReadRegister_(CFO_Register_RunPlan_EventMode0);
2051 0 : val |= (uint64_t(ReadRegister_(CFO_Register_RunPlan_EventMode1))) << 32;
2052 0 : return val;
2053 : } // end ReadRunPlanCurrentMode()
2054 :
2055 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanCurrentMode()
2056 : {
2057 0 : auto form = CreateFormatter(CFO_Register_RunPlan_EventMode0, false /* getValue */);
2058 0 : form.description = "Run Plan Current Mode";
2059 :
2060 0 : uint64_t mode = ReadRunPlanCurrentMode();
2061 :
2062 : // -- parse for each subsystem according docdb 4914 --
2063 : // Mode Packet Definition:
2064 : // Event Mode Byte 1 (Resrv’d Trk) Event Mode Byte 0 [7:3] Pattern Mode [2:1] Injection Data Source [0]
2065 : // Event Mode Byte 3 (Resrv’d CRV) Event Mode Byte 2 (Resrv’d Calo) [7:1] Calo Laser Injection [0]
2066 : // Delivery Ring RF-0 Marker TDC [15:8] Resrv’d (TEM) [7:6] (STM) [5:4] Subrun Handling [3:1] On-spill Flag [0]
2067 : //
2068 : // The high Event Mode bit, for example bit index 7 of a subsystem’s mode byte (or bit 1 of a subsystem’s 2-bit mode,
2069 : // is considered the active bit. If set, the corresponding subsystem is expected to record data for that Event Window.
2070 :
2071 0 : std::map<std::string, uint16_t> subsystemModeMap;
2072 0 : subsystemModeMap["Tracker"] = (mode >> 8) & 0xFF; // bits [7:0] of Event Mode Byte-1
2073 0 : subsystemModeMap["Calo"] = (mode >> 16) & 0xFF; // bits [7:0] of Event Mode Byte-2
2074 0 : subsystemModeMap["CRV"] = (mode >> 32) & 0xFF; // bits [7:0] of Event Mode Byte-3
2075 0 : subsystemModeMap["STM"] = (mode >> 36) & 0x3; // bits [1:0] of Event Mode Byte-4 upper nibble
2076 0 : subsystemModeMap["ExtMon"] = (mode >> 38) & 0x3; // bits [3:2] of Event Mode Byte-4 upper nibble
2077 :
2078 0 : subsystemModeMap["Tracker active"] = (subsystemModeMap["Tracker"] >> 7) & 1; // high Event Mode bit is active bit
2079 0 : subsystemModeMap["Calo active"] = (subsystemModeMap["Calo"] >> 7) & 1; // high Event Mode bit is active bit
2080 0 : subsystemModeMap["CRV active"] = (subsystemModeMap["CRV"] >> 7) & 1; // high Event Mode bit is active bit
2081 0 : subsystemModeMap["STM active"] = (subsystemModeMap["STM"] >> 1) & 1; // high Event Mode bit is active bit
2082 0 : subsystemModeMap["ExtMon active"] = (subsystemModeMap["ExtMon"] >> 1) & 1; // high Event Mode bit is active bit
2083 :
2084 0 : std::stringstream oss;
2085 0 : oss << "0x" << std::hex << std::setw(8) << std::setfill('0') << ReadRegister_(CFO_Register_RunPlan_EventMode0);
2086 0 : form.vals.push_back(oss.str()); // show hex format low 32-bits of mode
2087 0 : form.vals.push_back(std::to_string(mode)); // show decimal value
2088 0 : form.vals.push_back(""); // spacer for readability
2089 0 : for (auto pair : subsystemModeMap)
2090 : {
2091 0 : if (pair.first.find("active") != std::string::npos) continue;
2092 :
2093 0 : std::stringstream o;
2094 0 : if (pair.first.find("STM") != std::string::npos || pair.first.find("ExtMon") != std::string::npos)
2095 0 : o << pair.first + ": " << std::string(12 - pair.first.size(), ' ') << // pad for alignment
2096 0 : "b" << std::bitset<2>(pair.second) << std::string(6, ' ') << " (0x" << std::hex << pair.second << ")" << (subsystemModeMap[pair.first + " active"] ? " in" : " out");
2097 : else
2098 0 : o << pair.first + ": " << std::string(12 - pair.first.size(), ' ') << // pad for alignment
2099 0 : "b" << std::bitset<8>(pair.second) << " (0x" << std::hex << pair.second << ")" << (subsystemModeMap[pair.first + " active"] ? " in" : " out");
2100 0 : form.vals.push_back(o.str());
2101 0 : }
2102 0 : return form;
2103 0 : } // end FormatRunPlanCurrentMode()
2104 :
2105 : // Run Plan Subrun Event Limit Register
2106 0 : void CFOLib::CFO_Registers::SetRunPlanSubrunEvtLimit(uint32_t limit)
2107 : {
2108 0 : WriteRegister_(limit, CFO_Register_RunPlanSubrunEvtLimit);
2109 0 : }
2110 :
2111 0 : uint32_t CFOLib::CFO_Registers::ReadRunPlanSubrunEvtLimit(std::optional<uint32_t> val)
2112 : {
2113 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_RunPlanSubrunEvtLimit);
2114 : }
2115 :
2116 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanSubrunEvtLimit()
2117 : {
2118 0 : auto form = CreateFormatter(CFO_Register_RunPlanSubrunEvtLimit);
2119 0 : form.description = "Run Plan Subrun Event Limit";
2120 0 : form.vals.push_back(std::to_string(ReadRunPlanSubrunEvtLimit(form.value)));
2121 0 : return form;
2122 0 : }
2123 :
2124 : // Run Plan Subrun Prediction Offset Register
2125 0 : void CFOLib::CFO_Registers::SetRunPlanSubrunPredOffset(uint32_t offset)
2126 : {
2127 0 : WriteRegister_(offset, CFO_Register_RunPlanSubrunPredOffset);
2128 0 : }
2129 :
2130 0 : uint32_t CFOLib::CFO_Registers::ReadRunPlanSubrunPredOffset(std::optional<uint32_t> val)
2131 : {
2132 0 : return val.has_value() ? *val : ReadRegister_(CFO_Register_RunPlanSubrunPredOffset);
2133 : }
2134 :
2135 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatRunPlanSubrunPredOffset()
2136 : {
2137 0 : auto form = CreateFormatter(CFO_Register_RunPlanSubrunPredOffset);
2138 0 : form.description = "Run Plan Subrun Prediction Offset";
2139 0 : form.vals.push_back(std::to_string(ReadRunPlanSubrunPredOffset(form.value)));
2140 0 : return form;
2141 0 : }
2142 :
2143 : // Firefly CSR Register
2144 0 : bool CFOLib::CFO_Registers::ReadFireflyTXRXPresent(std::optional<uint32_t> val)
2145 : {
2146 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2147 0 : return dataSet[26];
2148 : }
2149 :
2150 0 : bool CFOLib::CFO_Registers::ReadFireflyRXPresent(std::optional<uint32_t> val)
2151 : {
2152 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2153 0 : return dataSet[25];
2154 : }
2155 :
2156 0 : bool CFOLib::CFO_Registers::ReadFireflyTXPresent(std::optional<uint32_t> val)
2157 : {
2158 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2159 0 : return dataSet[24];
2160 : }
2161 :
2162 0 : bool CFOLib::CFO_Registers::ReadFireflyTXRXInterrupt(std::optional<uint32_t> val)
2163 : {
2164 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2165 0 : return dataSet[18];
2166 : }
2167 :
2168 0 : bool CFOLib::CFO_Registers::ReadFireflyRXInterrupt(std::optional<uint32_t> val)
2169 : {
2170 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2171 0 : return dataSet[17];
2172 : }
2173 :
2174 0 : bool CFOLib::CFO_Registers::ReadFireflyTXInterrupt(std::optional<uint32_t> val)
2175 : {
2176 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2177 0 : return dataSet[16];
2178 : }
2179 :
2180 0 : void CFOLib::CFO_Registers::SetFireflyTXRXSelect(bool select)
2181 : {
2182 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2183 0 : dataSet[10] = select;
2184 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2185 0 : }
2186 :
2187 0 : void CFOLib::CFO_Registers::SetFireflyRXSelect(bool select)
2188 : {
2189 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2190 0 : dataSet[9] = select;
2191 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2192 0 : }
2193 :
2194 0 : void CFOLib::CFO_Registers::SetFireflyTXSelect(bool select)
2195 : {
2196 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2197 0 : dataSet[8] = select;
2198 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2199 0 : }
2200 :
2201 0 : bool CFOLib::CFO_Registers::ReadFireflyTXRXSelect(std::optional<uint32_t> val)
2202 : {
2203 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2204 0 : return dataSet[10];
2205 : }
2206 :
2207 0 : bool CFOLib::CFO_Registers::ReadFireflyRXSelect(std::optional<uint32_t> val)
2208 : {
2209 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2210 0 : return dataSet[9];
2211 : }
2212 :
2213 0 : bool CFOLib::CFO_Registers::ReadFireflyTXSelect(std::optional<uint32_t> val)
2214 : {
2215 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2216 0 : return dataSet[8];
2217 : }
2218 :
2219 0 : void CFOLib::CFO_Registers::SetFireflyTXRXReset(bool reset)
2220 : {
2221 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2222 0 : dataSet[2] = reset;
2223 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2224 0 : }
2225 :
2226 0 : void CFOLib::CFO_Registers::SetFireflyRXReset(bool reset)
2227 : {
2228 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2229 0 : dataSet[1] = reset;
2230 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2231 0 : }
2232 :
2233 0 : void CFOLib::CFO_Registers::SetFireflyTXReset(bool reset)
2234 : {
2235 0 : std::bitset<32> dataSet = ReadRegister_(CFO_Register_FireflyCSRRegister);
2236 0 : dataSet[0] = reset;
2237 0 : WriteRegister_(dataSet.to_ulong(), CFO_Register_FireflyCSRRegister);
2238 0 : }
2239 :
2240 0 : bool CFOLib::CFO_Registers::ReadFireflyTXRXReset(std::optional<uint32_t> val)
2241 : {
2242 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2243 0 : return dataSet[2];
2244 : }
2245 :
2246 0 : bool CFOLib::CFO_Registers::ReadFireflyRXReset(std::optional<uint32_t> val)
2247 : {
2248 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2249 0 : return dataSet[1];
2250 : }
2251 :
2252 0 : bool CFOLib::CFO_Registers::ReadFireflyTXReset(std::optional<uint32_t> val)
2253 : {
2254 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FireflyCSRRegister);
2255 0 : return dataSet[0];
2256 : }
2257 :
2258 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatFireflyCSR()
2259 : {
2260 0 : auto form = CreateFormatter(CFO_Register_FireflyCSRRegister);
2261 0 : form.description = "Firefly CSR Register";
2262 0 : form.vals.push_back(" ([Present, Interrupt, Select, Reset])");
2263 0 : form.vals.push_back(std::string("TX/RX: [") +
2264 0 : (ReadFireflyTXRXPresent(form.value) ? "x" : " ") +
2265 0 : (ReadFireflyTXRXInterrupt(form.value) ? "x" : " ") +
2266 0 : (ReadFireflyTXRXSelect(form.value) ? "x" : " ") +
2267 0 : (ReadFireflyTXRXReset(form.value) ? "x" : " ") + "]");
2268 0 : form.vals.push_back(std::string("RX: [") +
2269 0 : (ReadFireflyRXPresent(form.value) ? "x" : " ") +
2270 0 : (ReadFireflyRXInterrupt(form.value) ? "x" : " ") +
2271 0 : (ReadFireflyRXSelect(form.value) ? "x" : " ") +
2272 0 : (ReadFireflyRXReset(form.value) ? "x" : " ") + "]");
2273 0 : form.vals.push_back(std::string("TX: [") +
2274 0 : (ReadFireflyTXPresent(form.value) ? "x" : " ") +
2275 0 : (ReadFireflyTXInterrupt(form.value) ? "x" : " ") +
2276 0 : (ReadFireflyTXSelect(form.value) ? "x" : " ") +
2277 0 : (ReadFireflyTXReset(form.value) ? "x" : " ") + "]");
2278 :
2279 0 : return form;
2280 0 : }
2281 :
2282 : // SERDES PRBS Control Registers
2283 0 : bool CFOLib::CFO_Registers::ReadSERDESPRBSErrorFlag(const CFO_Link_ID& link, std::optional<uint32_t> val)
2284 : {
2285 : CFO_Register reg;
2286 0 : switch (link)
2287 : {
2288 0 : case CFO_Link_0:
2289 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2290 0 : break;
2291 0 : case CFO_Link_1:
2292 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2293 0 : break;
2294 0 : case CFO_Link_2:
2295 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2296 0 : break;
2297 0 : case CFO_Link_3:
2298 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2299 0 : break;
2300 0 : case CFO_Link_4:
2301 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2302 0 : break;
2303 0 : case CFO_Link_5:
2304 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2305 0 : break;
2306 0 : case CFO_Link_6:
2307 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2308 0 : break;
2309 0 : case CFO_Link_7:
2310 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2311 0 : break;
2312 0 : default: {
2313 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2314 0 : __SS_THROW__;
2315 0 : }
2316 : }
2317 :
2318 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(reg);
2319 0 : return dataSet[31];
2320 : }
2321 :
2322 0 : uint8_t CFOLib::CFO_Registers::ReadSERDESTXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val)
2323 : {
2324 : CFO_Register reg;
2325 0 : switch (link)
2326 : {
2327 0 : case CFO_Link_0:
2328 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2329 0 : break;
2330 0 : case CFO_Link_1:
2331 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2332 0 : break;
2333 0 : case CFO_Link_2:
2334 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2335 0 : break;
2336 0 : case CFO_Link_3:
2337 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2338 0 : break;
2339 0 : case CFO_Link_4:
2340 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2341 0 : break;
2342 0 : case CFO_Link_5:
2343 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2344 0 : break;
2345 0 : case CFO_Link_6:
2346 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2347 0 : break;
2348 0 : case CFO_Link_7:
2349 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2350 0 : break;
2351 0 : default: {
2352 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2353 0 : __SS_THROW__;
2354 0 : }
2355 : }
2356 0 : auto data = val.has_value() ? *val : ReadRegister_(reg);
2357 0 : return (data >> 12) & 0xF;
2358 : }
2359 :
2360 0 : void CFOLib::CFO_Registers::SetSERDESTXPRBSSEL(const CFO_Link_ID& link, uint8_t byte)
2361 : {
2362 : CFO_Register reg;
2363 0 : switch (link)
2364 : {
2365 0 : case CFO_Link_0:
2366 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2367 0 : break;
2368 0 : case CFO_Link_1:
2369 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2370 0 : break;
2371 0 : case CFO_Link_2:
2372 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2373 0 : break;
2374 0 : case CFO_Link_3:
2375 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2376 0 : break;
2377 0 : case CFO_Link_4:
2378 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2379 0 : break;
2380 0 : case CFO_Link_5:
2381 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2382 0 : break;
2383 0 : case CFO_Link_6:
2384 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2385 0 : break;
2386 0 : case CFO_Link_7:
2387 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2388 0 : break;
2389 0 : default: {
2390 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2391 0 : __SS_THROW__;
2392 0 : }
2393 : }
2394 0 : WriteRegister_(byte, reg);
2395 0 : }
2396 :
2397 0 : uint8_t CFOLib::CFO_Registers::ReadSERDESRXPRBSSEL(const CFO_Link_ID& link, std::optional<uint32_t> val)
2398 : {
2399 : CFO_Register reg;
2400 0 : switch (link)
2401 : {
2402 0 : case CFO_Link_0:
2403 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2404 0 : break;
2405 0 : case CFO_Link_1:
2406 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2407 0 : break;
2408 0 : case CFO_Link_2:
2409 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2410 0 : break;
2411 0 : case CFO_Link_3:
2412 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2413 0 : break;
2414 0 : case CFO_Link_4:
2415 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2416 0 : break;
2417 0 : case CFO_Link_5:
2418 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2419 0 : break;
2420 0 : case CFO_Link_6:
2421 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2422 0 : break;
2423 0 : case CFO_Link_7:
2424 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2425 0 : break;
2426 0 : default: {
2427 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2428 0 : __SS_THROW__;
2429 0 : }
2430 : }
2431 0 : auto data = val.has_value() ? *val : ReadRegister_(reg);
2432 0 : return (data >> 8) & 0xF;
2433 : }
2434 :
2435 0 : void CFOLib::CFO_Registers::SetSERDESRXPRBSSEL(const CFO_Link_ID& link, uint8_t byte)
2436 : {
2437 : CFO_Register reg;
2438 0 : switch (link)
2439 : {
2440 0 : case CFO_Link_0:
2441 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2442 0 : break;
2443 0 : case CFO_Link_1:
2444 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2445 0 : break;
2446 0 : case CFO_Link_2:
2447 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2448 0 : break;
2449 0 : case CFO_Link_3:
2450 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2451 0 : break;
2452 0 : case CFO_Link_4:
2453 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2454 0 : break;
2455 0 : case CFO_Link_5:
2456 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2457 0 : break;
2458 0 : case CFO_Link_6:
2459 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2460 0 : break;
2461 0 : case CFO_Link_7:
2462 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2463 0 : break;
2464 0 : default: {
2465 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2466 0 : __SS_THROW__;
2467 0 : }
2468 : }
2469 0 : WriteRegister_(byte, reg);
2470 0 : }
2471 :
2472 0 : bool CFOLib::CFO_Registers::ReadSERDESTXPRBSForceError(const CFO_Link_ID& link, std::optional<uint32_t> val)
2473 : {
2474 : CFO_Register reg;
2475 0 : switch (link)
2476 : {
2477 0 : case CFO_Link_0:
2478 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2479 0 : break;
2480 0 : case CFO_Link_1:
2481 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2482 0 : break;
2483 0 : case CFO_Link_2:
2484 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2485 0 : break;
2486 0 : case CFO_Link_3:
2487 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2488 0 : break;
2489 0 : case CFO_Link_4:
2490 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2491 0 : break;
2492 0 : case CFO_Link_5:
2493 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2494 0 : break;
2495 0 : case CFO_Link_6:
2496 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2497 0 : break;
2498 0 : case CFO_Link_7:
2499 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2500 0 : break;
2501 0 : default: {
2502 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2503 0 : __SS_THROW__;
2504 0 : }
2505 : }
2506 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(reg);
2507 0 : return dataSet[1];
2508 : }
2509 :
2510 0 : void CFOLib::CFO_Registers::SetSERDESTXPRBSForceError(const CFO_Link_ID& link, bool flag)
2511 : {
2512 : CFO_Register reg;
2513 0 : switch (link)
2514 : {
2515 0 : case CFO_Link_0:
2516 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2517 0 : break;
2518 0 : case CFO_Link_1:
2519 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2520 0 : break;
2521 0 : case CFO_Link_2:
2522 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2523 0 : break;
2524 0 : case CFO_Link_3:
2525 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2526 0 : break;
2527 0 : case CFO_Link_4:
2528 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2529 0 : break;
2530 0 : case CFO_Link_5:
2531 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2532 0 : break;
2533 0 : case CFO_Link_6:
2534 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2535 0 : break;
2536 0 : case CFO_Link_7:
2537 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2538 0 : break;
2539 0 : default: {
2540 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2541 0 : __SS_THROW__;
2542 0 : }
2543 : }
2544 0 : std::bitset<32> dataSet = ReadRegister_(reg);
2545 0 : dataSet[1] = flag;
2546 0 : WriteRegister_(dataSet.to_ulong(), reg);
2547 0 : }
2548 :
2549 0 : void CFOLib::CFO_Registers::ToggleSERDESTXPRBSForceError(const CFO_Link_ID& link)
2550 : {
2551 : CFO_Register reg;
2552 0 : switch (link)
2553 : {
2554 0 : case CFO_Link_0:
2555 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2556 0 : break;
2557 0 : case CFO_Link_1:
2558 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2559 0 : break;
2560 0 : case CFO_Link_2:
2561 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2562 0 : break;
2563 0 : case CFO_Link_3:
2564 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2565 0 : break;
2566 0 : case CFO_Link_4:
2567 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2568 0 : break;
2569 0 : case CFO_Link_5:
2570 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2571 0 : break;
2572 0 : case CFO_Link_6:
2573 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2574 0 : break;
2575 0 : case CFO_Link_7:
2576 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2577 0 : break;
2578 0 : default: {
2579 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2580 0 : __SS_THROW__;
2581 0 : }
2582 : }
2583 0 : std::bitset<32> dataSet = ReadRegister_(reg);
2584 0 : dataSet[1] = !dataSet[1];
2585 0 : WriteRegister_(dataSet.to_ulong(), reg);
2586 0 : }
2587 :
2588 0 : bool CFOLib::CFO_Registers::ReadSERDESRXPRBSCountReset(const CFO_Link_ID& link, std::optional<uint32_t> val)
2589 : {
2590 : CFO_Register reg;
2591 0 : switch (link)
2592 : {
2593 0 : case CFO_Link_0:
2594 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2595 0 : break;
2596 0 : case CFO_Link_1:
2597 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2598 0 : break;
2599 0 : case CFO_Link_2:
2600 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2601 0 : break;
2602 0 : case CFO_Link_3:
2603 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2604 0 : break;
2605 0 : case CFO_Link_4:
2606 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2607 0 : break;
2608 0 : case CFO_Link_5:
2609 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2610 0 : break;
2611 0 : case CFO_Link_6:
2612 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2613 0 : break;
2614 0 : case CFO_Link_7:
2615 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2616 0 : break;
2617 0 : default: {
2618 0 : __SS__ << "Illegal link index provided: " << link << __E__;
2619 0 : __SS_THROW__;
2620 0 : }
2621 : }
2622 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(reg);
2623 0 : return dataSet[0];
2624 : }
2625 :
2626 0 : void CFOLib::CFO_Registers::SetSERDESRXPRBSCountReset(const CFO_Link_ID& link, bool flag)
2627 : {
2628 : CFO_Register reg;
2629 0 : switch (link)
2630 : {
2631 0 : case CFO_Link_0:
2632 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2633 0 : break;
2634 0 : case CFO_Link_1:
2635 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2636 0 : break;
2637 0 : case CFO_Link_2:
2638 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2639 0 : break;
2640 0 : case CFO_Link_3:
2641 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2642 0 : break;
2643 0 : case CFO_Link_4:
2644 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2645 0 : break;
2646 0 : case CFO_Link_5:
2647 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2648 0 : break;
2649 0 : case CFO_Link_6:
2650 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2651 0 : break;
2652 0 : case CFO_Link_7:
2653 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2654 0 : break;
2655 0 : default:
2656 0 : return;
2657 : }
2658 0 : std::bitset<32> dataSet = ReadRegister_(reg);
2659 0 : dataSet[0] = flag;
2660 0 : WriteRegister_(dataSet.to_ulong(), reg);
2661 : }
2662 :
2663 0 : void CFOLib::CFO_Registers::ToggleSERDESRXPRBSCountReset(const CFO_Link_ID& link)
2664 : {
2665 : CFO_Register reg;
2666 0 : switch (link)
2667 : {
2668 0 : case CFO_Link_0:
2669 0 : reg = CFO_Register_SERDESPRBSControlLink0;
2670 0 : break;
2671 0 : case CFO_Link_1:
2672 0 : reg = CFO_Register_SERDESPRBSControlLink1;
2673 0 : break;
2674 0 : case CFO_Link_2:
2675 0 : reg = CFO_Register_SERDESPRBSControlLink2;
2676 0 : break;
2677 0 : case CFO_Link_3:
2678 0 : reg = CFO_Register_SERDESPRBSControlLink3;
2679 0 : break;
2680 0 : case CFO_Link_4:
2681 0 : reg = CFO_Register_SERDESPRBSControlLink4;
2682 0 : break;
2683 0 : case CFO_Link_5:
2684 0 : reg = CFO_Register_SERDESPRBSControlLink5;
2685 0 : break;
2686 0 : case CFO_Link_6:
2687 0 : reg = CFO_Register_SERDESPRBSControlLink6;
2688 0 : break;
2689 0 : case CFO_Link_7:
2690 0 : reg = CFO_Register_SERDESPRBSControlLink7;
2691 0 : break;
2692 0 : default:
2693 0 : return;
2694 : }
2695 0 : std::bitset<32> dataSet = ReadRegister_(reg);
2696 0 : dataSet[0] = !dataSet[0];
2697 0 : WriteRegister_(dataSet.to_ulong(), reg);
2698 : }
2699 :
2700 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink0()
2701 : {
2702 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink0);
2703 0 : form.description = "SERDES PRBS Control Link 0";
2704 0 : form.vals.push_back(""); // translation
2705 0 : std::ostringstream o;
2706 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_0, form.value);
2707 0 : form.vals.push_back(o.str());
2708 0 : o.flush();
2709 0 : o.str("");
2710 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_0, form.value));
2711 0 : form.vals.push_back(o.str());
2712 0 : o.flush();
2713 0 : o.str("");
2714 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_0, form.value));
2715 0 : form.vals.push_back(o.str());
2716 0 : o.flush();
2717 0 : o.str("");
2718 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_0, form.value);
2719 0 : form.vals.push_back(o.str());
2720 0 : o.flush();
2721 0 : o.str("");
2722 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_0, form.value);
2723 0 : form.vals.push_back(o.str());
2724 0 : o.flush();
2725 :
2726 0 : return form;
2727 0 : }
2728 :
2729 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink1()
2730 : {
2731 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink1);
2732 0 : form.description = "SERDES PRBS Control Link 1";
2733 0 : form.vals.push_back(""); // translation
2734 0 : std::ostringstream o;
2735 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_1, form.value);
2736 0 : form.vals.push_back(o.str());
2737 0 : o.flush();
2738 0 : o.str("");
2739 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_1, form.value));
2740 0 : form.vals.push_back(o.str());
2741 0 : o.flush();
2742 0 : o.str("");
2743 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_1, form.value));
2744 0 : form.vals.push_back(o.str());
2745 0 : o.flush();
2746 0 : o.str("");
2747 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_1, form.value);
2748 0 : form.vals.push_back(o.str());
2749 0 : o.flush();
2750 0 : o.str("");
2751 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_1, form.value);
2752 0 : form.vals.push_back(o.str());
2753 0 : o.flush();
2754 :
2755 0 : return form;
2756 0 : }
2757 :
2758 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink2()
2759 : {
2760 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink2);
2761 0 : form.description = "SERDES PRBS Control Link 2";
2762 0 : form.vals.push_back(""); // translation
2763 0 : std::ostringstream o;
2764 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_2, form.value);
2765 0 : form.vals.push_back(o.str());
2766 0 : o.flush();
2767 0 : o.str("");
2768 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_2, form.value));
2769 0 : form.vals.push_back(o.str());
2770 0 : o.flush();
2771 0 : o.str("");
2772 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_2, form.value));
2773 0 : form.vals.push_back(o.str());
2774 0 : o.flush();
2775 0 : o.str("");
2776 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_2, form.value);
2777 0 : form.vals.push_back(o.str());
2778 0 : o.flush();
2779 0 : o.str("");
2780 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_2, form.value);
2781 0 : form.vals.push_back(o.str());
2782 0 : o.flush();
2783 :
2784 0 : return form;
2785 0 : }
2786 :
2787 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink3()
2788 : {
2789 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink3);
2790 0 : form.description = "SERDES PRBS Control Link 3";
2791 0 : form.vals.push_back(""); // translation
2792 0 : std::ostringstream o;
2793 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_3, form.value);
2794 0 : form.vals.push_back(o.str());
2795 0 : o.flush();
2796 0 : o.str("");
2797 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_3, form.value));
2798 0 : form.vals.push_back(o.str());
2799 0 : o.flush();
2800 0 : o.str("");
2801 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_3, form.value));
2802 0 : form.vals.push_back(o.str());
2803 0 : o.flush();
2804 0 : o.str("");
2805 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_3, form.value);
2806 0 : form.vals.push_back(o.str());
2807 0 : o.flush();
2808 0 : o.str("");
2809 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_3, form.value);
2810 0 : form.vals.push_back(o.str());
2811 0 : o.flush();
2812 :
2813 0 : return form;
2814 0 : }
2815 :
2816 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink4()
2817 : {
2818 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink4);
2819 0 : form.description = "SERDES PRBS Control Link 4";
2820 0 : form.vals.push_back(""); // translation
2821 0 : std::ostringstream o;
2822 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_4, form.value);
2823 0 : form.vals.push_back(o.str());
2824 0 : o.flush();
2825 0 : o.str("");
2826 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_4, form.value));
2827 0 : form.vals.push_back(o.str());
2828 0 : o.flush();
2829 0 : o.str("");
2830 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_4, form.value));
2831 0 : form.vals.push_back(o.str());
2832 0 : o.flush();
2833 0 : o.str("");
2834 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_4, form.value);
2835 0 : form.vals.push_back(o.str());
2836 0 : o.flush();
2837 0 : o.str("");
2838 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_4, form.value);
2839 0 : form.vals.push_back(o.str());
2840 0 : o.flush();
2841 :
2842 0 : return form;
2843 0 : }
2844 :
2845 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink5()
2846 : {
2847 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink5);
2848 0 : form.description = "SERDES PRBS Control Link 5";
2849 0 : form.vals.push_back(""); // translation
2850 0 : std::ostringstream o;
2851 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_5, form.value);
2852 0 : form.vals.push_back(o.str());
2853 0 : o.flush();
2854 0 : o.str("");
2855 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_5, form.value));
2856 0 : form.vals.push_back(o.str());
2857 0 : o.flush();
2858 0 : o.str("");
2859 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_5, form.value));
2860 0 : form.vals.push_back(o.str());
2861 0 : o.flush();
2862 0 : o.str("");
2863 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_5, form.value);
2864 0 : form.vals.push_back(o.str());
2865 0 : o.flush();
2866 0 : o.str("");
2867 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_5, form.value);
2868 0 : form.vals.push_back(o.str());
2869 0 : o.flush();
2870 :
2871 0 : return form;
2872 0 : }
2873 :
2874 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink6()
2875 : {
2876 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink6);
2877 0 : form.description = "SERDES PRBS Control Link 6";
2878 0 : form.vals.push_back(""); // translation
2879 0 : std::ostringstream o;
2880 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_6, form.value);
2881 0 : form.vals.push_back(o.str());
2882 0 : o.flush();
2883 0 : o.str("");
2884 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_6, form.value));
2885 0 : form.vals.push_back(o.str());
2886 0 : o.flush();
2887 0 : o.str("");
2888 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_6, form.value));
2889 0 : form.vals.push_back(o.str());
2890 0 : o.flush();
2891 0 : o.str("");
2892 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_6, form.value);
2893 0 : form.vals.push_back(o.str());
2894 0 : o.flush();
2895 0 : o.str("");
2896 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_6, form.value);
2897 0 : form.vals.push_back(o.str());
2898 0 : o.flush();
2899 :
2900 0 : return form;
2901 0 : }
2902 :
2903 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatSERDESPRBSControlLink7()
2904 : {
2905 0 : auto form = CreateFormatter(CFO_Register_SERDESPRBSControlLink7);
2906 0 : form.description = "SERDES PRBS Control Link 7";
2907 0 : form.vals.push_back(""); // translation
2908 0 : std::ostringstream o;
2909 0 : o << "RX PRBS Error: " << std::boolalpha << ReadSERDESPRBSErrorFlag(CFO_Link_7, form.value);
2910 0 : form.vals.push_back(o.str());
2911 0 : o.flush();
2912 0 : o.str("");
2913 0 : o << "TX PRBS Select: " << std::to_string(ReadSERDESTXPRBSSEL(CFO_Link_7, form.value));
2914 0 : form.vals.push_back(o.str());
2915 0 : o.flush();
2916 0 : o.str("");
2917 0 : o << "RX PRBS Select: " << std::to_string(ReadSERDESRXPRBSSEL(CFO_Link_7, form.value));
2918 0 : form.vals.push_back(o.str());
2919 0 : o.flush();
2920 0 : o.str("");
2921 0 : o << "TX PRBS Enable Force Error: " << std::boolalpha << ReadSERDESTXPRBSForceError(CFO_Link_7, form.value);
2922 0 : form.vals.push_back(o.str());
2923 0 : o.flush();
2924 0 : o.str("");
2925 0 : o << "RX PRBS Count Reset: " << std::boolalpha << ReadSERDESRXPRBSCountReset(CFO_Link_7, form.value);
2926 0 : form.vals.push_back(o.str());
2927 0 : o.flush();
2928 :
2929 0 : return form;
2930 0 : }
2931 :
2932 0 : uint32_t CFOLib::CFO_Registers::ReadCableDelayMeasureExponentialCount(std::optional<uint32_t> val)
2933 : {
2934 0 : uint32_t readVal = val.has_value() ? *val : ReadRegister_(CFO_Register_CableDelayControlStatus);
2935 0 : return (readVal >> 16) & 0xF; // return 4-bit nibble at bit-16
2936 : } // end ReadCableDelayMeasureExponentialCount()
2937 :
2938 0 : void CFOLib::CFO_Registers::SetCableDelayMeasureExponentialCount(const uint32_t exponent)
2939 : {
2940 0 : uint32_t val = ReadRegister_(CFO_Register_CableDelayControlStatus);
2941 0 : val &= ~(0x0F << 16); // mask off
2942 0 : val |= (exponent & 0xF) << 16; // insert 4-bit nibble at bit-16
2943 0 : WriteRegister_(val, CFO_Register_CableDelayControlStatus);
2944 0 : } // end SetCableDelayMeasureExponentialCount()
2945 :
2946 0 : uint32_t CFOLib::CFO_Registers::ReadCableDelayMeasurement(const CFO_Link_ID link, const uint8_t roc, bool& done)
2947 : {
2948 0 : CFOandDTC_Register calcReg = CFO_Register_CableDelayValue_offset;
2949 0 : calcReg += 0x100 * roc;
2950 0 : calcReg += 0x4 * link;
2951 0 : __COUTT__ << "Delay Register 0x" << std::hex << calcReg << __E__;
2952 0 : uint32_t readVal = ReadRegister_(calcReg);
2953 0 : done = (readVal >> 31) & 1;
2954 0 : return readVal & (~(1 << 31)); // return 4-bit nibble at bit-16
2955 : } // end ReadCableDelayMeasureExponentialCount()
2956 :
2957 : // void CFOLib::CFO_Registers::SetCableDelayValue(const CFO_Link_ID& link, const uint32_t delay)
2958 : // {
2959 : // CFO_Register reg;
2960 : // switch (link)
2961 : // {
2962 : // case CFO_Link_0:
2963 : // reg = CFO_Register_CableDelayValueLink0;
2964 : // break;
2965 : // case CFO_Link_1:
2966 : // reg = CFO_Register_CableDelayValueLink1;
2967 : // break;
2968 : // case CFO_Link_2:
2969 : // reg = CFO_Register_CableDelayValueLink2;
2970 : // break;
2971 : // case CFO_Link_3:
2972 : // reg = CFO_Register_CableDelayValueLink3;
2973 : // break;
2974 : // case CFO_Link_4:
2975 : // reg = CFO_Register_CableDelayValueLink4;
2976 : // break;
2977 : // case CFO_Link_5:
2978 : // reg = CFO_Register_CableDelayValueLink5;
2979 : // break;
2980 : // case CFO_Link_6:
2981 : // reg = CFO_Register_CableDelayValueLink6;
2982 : // break;
2983 : // case CFO_Link_7:
2984 : // reg = CFO_Register_CableDelayValueLink7;
2985 : // break;
2986 : // default:
2987 : // return;
2988 : // }
2989 : // WriteRegister_(delay, reg);
2990 : // }
2991 :
2992 : // uint32_t CFOLib::CFO_Registers::ReadCableDelayValue(const CFO_Link_ID& link, std::optional<uint32_t> val)
2993 : // {
2994 : // switch (link)
2995 : // {
2996 : // case CFO_Link_0:
2997 : // return val.has_value()?*val:ReadRegister_(CFO_Register_CableDelayValueLink0);
2998 : // case CFO_Link_1:
2999 : // return ReadRegister_(CFO_Register_CableDelayValueLink1);
3000 : // case CFO_Link_2:
3001 : // return ReadRegister_(CFO_Register_CableDelayValueLink2);
3002 : // case CFO_Link_3:
3003 : // return ReadRegister_(CFO_Register_CableDelayValueLink3);
3004 : // case CFO_Link_4:
3005 : // return ReadRegister_(CFO_Register_CableDelayValueLink4);
3006 : // case CFO_Link_5:
3007 : // return ReadRegister_(CFO_Register_CableDelayValueLink5);
3008 : // case CFO_Link_6:
3009 : // return ReadRegister_(CFO_Register_CableDelayValueLink6);
3010 : // case CFO_Link_7:
3011 : // return ReadRegister_(CFO_Register_CableDelayValueLink7);
3012 : // default:
3013 : // return -1;
3014 : // }
3015 : // }
3016 :
3017 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink0()
3018 : // {
3019 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink0);
3020 : // form.description = "Cable Delay Value Link 0";
3021 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_0)));
3022 : // return form;
3023 : // }
3024 :
3025 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink1()
3026 : // {
3027 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink1);
3028 : // form.description = "Cable Delay Value Link 1";
3029 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_1)));
3030 : // return form;
3031 : // }
3032 :
3033 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink2()
3034 : // {
3035 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink2);
3036 : // form.description = "Cable Delay Value Link 2";
3037 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_2)));
3038 : // return form;
3039 : // }
3040 :
3041 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink3()
3042 : // {
3043 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink3);
3044 : // form.description = "Cable Delay Value Link 3";
3045 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_3)));
3046 : // return form;
3047 : // }
3048 :
3049 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink4()
3050 : // {
3051 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink4);
3052 : // form.description = "Cable Delay Value Link 4";
3053 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_4)));
3054 : // return form;
3055 : // }
3056 :
3057 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink5()
3058 : // {
3059 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink5);
3060 : // form.description = "Cable Delay Value Link 5";
3061 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_5)));
3062 : // return form;
3063 : // }
3064 :
3065 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink6()
3066 : // {
3067 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink6);
3068 : // form.description = "Cable Delay Value Link 6";
3069 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_6)));
3070 : // return form;
3071 : // }
3072 :
3073 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayValueLink7()
3074 : // {
3075 : // auto form = CreateFormatter(CFO_Register_CableDelayValueLink7);
3076 : // form.description = "Cable Delay Value Link 7";
3077 : // form.vals.push_back(std::to_string(ReadCableDelayValue(CFO_Link_7)));
3078 : // return form;
3079 : // }
3080 :
3081 : // void CFOLib::CFO_Registers::ResetDelayRegister()
3082 : // {
3083 : // WriteRegister_(0, CFO_Register_CableDelayControlStatus);
3084 : // }
3085 :
3086 : // bool CFOLib::CFO_Registers::ReadDelayMeasureError(const CFO_Link_ID& link, std::optional<uint32_t> val)
3087 : // {
3088 : // std::bitset<32> dataSet = val.has_value()?*val:ReadRegister_(CFO_Register_CableDelayControlStatus);
3089 : // return dataSet[24 + link];
3090 : // }
3091 :
3092 : // bool CFOLib::CFO_Registers::ReadDelayExternalLoopbackEnable(std::optional<uint32_t> val)
3093 : // {
3094 : // std::bitset<32> dataSet = val.has_value()?*val:ReadRegister_(CFO_Register_CableDelayControlStatus);
3095 : // return dataSet[16];
3096 : // }
3097 :
3098 : // void CFOLib::CFO_Registers::SetDelayExternalLoopbackEnable(bool value)
3099 : // {
3100 : // std::bitset<32> dataSet = ReadRegister_(CFO_Register_CableDelayControlStatus);
3101 : // dataSet[16] = value;
3102 : // WriteRegister_(dataSet.to_ulong(), CFO_Register_CableDelayControlStatus);
3103 : // }
3104 :
3105 : // void CFOLib::CFO_Registers::EnableDelayMeasureMode(const CFO_Link_ID& link)
3106 : // {
3107 : // std::bitset<32> dataSet = ReadRegister_(CFO_Register_CableDelayControlStatus);
3108 : // dataSet[8 + link] = 1;
3109 : // WriteRegister_(dataSet.to_ulong(), CFO_Register_CableDelayControlStatus);
3110 : // }
3111 :
3112 : // void CFOLib::CFO_Registers::DisableDelayMeasureMode(const CFO_Link_ID& link)
3113 : // {
3114 : // std::bitset<32> dataSet = ReadRegister_(CFO_Register_CableDelayControlStatus);
3115 : // dataSet[8 + link] = 0;
3116 : // WriteRegister_(dataSet.to_ulong(), CFO_Register_CableDelayControlStatus);
3117 : // }
3118 :
3119 : // bool CFOLib::CFO_Registers::ReadDelayMeasureMode(const CFO_Link_ID& link, std::optional<uint32_t> val)
3120 : // {
3121 : // std::bitset<32> dataSet = val.has_value()?*val:ReadRegister_(CFO_Register_CableDelayControlStatus);
3122 : // return dataSet[8 + link];
3123 : // }
3124 :
3125 : // void CFOLib::CFO_Registers::EnableDelayMeasureNow(const CFO_Link_ID& link)
3126 : // {
3127 : // std::bitset<32> dataSet = ReadRegister_(CFO_Register_CableDelayControlStatus);
3128 : // dataSet[link] = 1;
3129 : // WriteRegister_(dataSet.to_ulong(), CFO_Register_CableDelayControlStatus);
3130 : // }
3131 :
3132 : // void CFOLib::CFO_Registers::DisableDelayMeasureNow(const CFO_Link_ID& link)
3133 : // {
3134 : // std::bitset<32> dataSet = ReadRegister_(CFO_Register_CableDelayControlStatus);
3135 : // dataSet[link] = 0;
3136 : // WriteRegister_(dataSet.to_ulong(), CFO_Register_CableDelayControlStatus);
3137 : // }
3138 :
3139 : // bool CFOLib::CFO_Registers::ReadDelayMeasureNow(const CFO_Link_ID& link, std::optional<uint32_t> val)
3140 : // {
3141 : // std::bitset<32> dataSet = val.has_value()?*val:ReadRegister_(CFO_Register_CableDelayControlStatus);
3142 : // return dataSet[link];
3143 : // }
3144 :
3145 : // DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatCableDelayControl()
3146 : // {
3147 : // auto form = CreateFormatter(CFO_Register_CableDelayControlStatus);
3148 : // form.description = "Cabel Delay Control and Status";
3149 : // form.vals.push_back("[ x = 1 (hi) ]"); //translation
3150 : // form.vals.push_back(std::string("Delay External Loopback Enable: [") +
3151 : // (ReadDelayExternalLoopbackEnable(form.value) ? "x" : " ") + std::string("]"));
3152 : // form.vals.push_back(std::string("Delay Measure Flags: ([Error, Enabled, Now])"));
3153 : // for (auto r : CFO_Links)
3154 : // form.vals.push_back(std::string("Link ") + std::to_string(r) + ": [" +
3155 : // (ReadDelayMeasureError(r, form.value) ? "x" : " ") + "," +
3156 : // (ReadDelayMeasureMode(r, form.value) ? "x" : " ") + "," +
3157 : // (ReadDelayMeasureNow(r, form.value) ? "x" : " ") + "]");
3158 : // return form;
3159 : // }
3160 :
3161 : // FPGA PROM Program Status Register
3162 0 : bool CFOLib::CFO_Registers::ReadFPGAPROMProgramFIFOFull(std::optional<uint32_t> val)
3163 : {
3164 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FPGAPROMProgramStatus);
3165 0 : return dataSet[1];
3166 : }
3167 :
3168 0 : bool CFOLib::CFO_Registers::ReadFPGAPROMReady(std::optional<uint32_t> val)
3169 : {
3170 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FPGAPROMProgramStatus);
3171 0 : return dataSet[0];
3172 : }
3173 :
3174 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatFPGAPROMProgramStatus()
3175 : {
3176 0 : auto form = CreateFormatter(CFO_Register_FPGAPROMProgramStatus);
3177 0 : form.description = "FPGA PROM Program Status";
3178 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
3179 0 : form.vals.push_back(std::string("FPGA PROM Program FIFO Full: [") + (ReadFPGAPROMProgramFIFOFull(form.value) ? "x" : " ") +
3180 : "]");
3181 0 : form.vals.push_back(std::string("FPGA PROM Ready: [") + (ReadFPGAPROMReady(form.value) ? "x" : " ") + "]");
3182 0 : return form;
3183 0 : }
3184 :
3185 : // FPGA Core Access Register
3186 0 : void CFOLib::CFO_Registers::ReloadFPGAFirmware()
3187 : {
3188 0 : WriteRegister_(0xFFFFFFFF, CFO_Register_FPGACoreAccess);
3189 0 : while (ReadFPGACoreAccessFIFOFull())
3190 : {
3191 0 : usleep(10);
3192 : }
3193 0 : WriteRegister_(0xAA995566, CFO_Register_FPGACoreAccess);
3194 0 : while (ReadFPGACoreAccessFIFOFull())
3195 : {
3196 0 : usleep(10);
3197 : }
3198 0 : WriteRegister_(0x20000000, CFO_Register_FPGACoreAccess);
3199 0 : while (ReadFPGACoreAccessFIFOFull())
3200 : {
3201 0 : usleep(10);
3202 : }
3203 0 : WriteRegister_(0x30020001, CFO_Register_FPGACoreAccess);
3204 0 : while (ReadFPGACoreAccessFIFOFull())
3205 : {
3206 0 : usleep(10);
3207 : }
3208 0 : WriteRegister_(0x00000000, CFO_Register_FPGACoreAccess);
3209 0 : while (ReadFPGACoreAccessFIFOFull())
3210 : {
3211 0 : usleep(10);
3212 : }
3213 0 : WriteRegister_(0x30008001, CFO_Register_FPGACoreAccess);
3214 0 : while (ReadFPGACoreAccessFIFOFull())
3215 : {
3216 0 : usleep(10);
3217 : }
3218 0 : WriteRegister_(0x0000000F, CFO_Register_FPGACoreAccess);
3219 0 : while (ReadFPGACoreAccessFIFOFull())
3220 : {
3221 0 : usleep(10);
3222 : }
3223 0 : WriteRegister_(0x20000000, CFO_Register_FPGACoreAccess);
3224 0 : }
3225 :
3226 0 : bool CFOLib::CFO_Registers::ReadFPGACoreAccessFIFOFull(std::optional<uint32_t> val)
3227 : {
3228 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FPGACoreAccess);
3229 0 : return dataSet[1];
3230 : }
3231 :
3232 0 : bool CFOLib::CFO_Registers::ReadFPGACoreAccessFIFOEmpty(std::optional<uint32_t> val)
3233 : {
3234 0 : std::bitset<32> dataSet = val.has_value() ? *val : ReadRegister_(CFO_Register_FPGACoreAccess);
3235 0 : return dataSet[0];
3236 : }
3237 :
3238 0 : DTCLib::RegisterFormatter CFOLib::CFO_Registers::FormatFPGACoreAccess()
3239 : {
3240 0 : auto form = CreateFormatter(CFO_Register_FPGACoreAccess);
3241 0 : form.description = "FPGA Core Access";
3242 0 : form.vals.push_back("[ x = 1 (hi) ]"); // translation
3243 0 : form.vals.push_back(std::string("FPGA Core Access FIFO Full: [") + (ReadFPGACoreAccessFIFOFull(form.value) ? "x" : " ") + "]");
3244 0 : form.vals.push_back(std::string("FPGA Core Access FIFO Empty: [") + (ReadFPGACoreAccessFIFOEmpty(form.value) ? "x" : " ") +
3245 : "]");
3246 :
3247 0 : return form;
3248 0 : }
3249 :
3250 : // Oscillator Programming (DDR and SERDES)
3251 0 : bool CFOLib::CFO_Registers::SetNewOscillatorFrequency(double targetFrequency)
3252 : {
3253 0 : auto currentFrequency = ReadSERDESOscillatorFrequency();
3254 0 : auto currentProgram = ReadSERDESOscillatorParameters();
3255 0 : __COUT__ << "Target Frequency: " << targetFrequency << ", Current Frequency: " << currentFrequency
3256 0 : << ", Current Program: " << std::showbase << std::hex << currentProgram;
3257 :
3258 : // Check if targetFrequency is essentially the same as the current frequency...
3259 0 : if (fabs(currentFrequency - targetFrequency) < targetFrequency * 30 / 1000000)
3260 : {
3261 0 : __COUT_INFO__ << "New frequency and old frequency are within 30 ppm of each other, not reprogramming!";
3262 0 : return false;
3263 : }
3264 :
3265 0 : auto newParameters = CalculateFrequencyForProgramming_(targetFrequency, currentFrequency, currentProgram);
3266 0 : if (newParameters == 0)
3267 : {
3268 0 : __COUT_WARN__ << "New program calculated as 0! Check parameters!";
3269 0 : return false;
3270 : }
3271 0 : SetSERDESOscillatorParameters(newParameters);
3272 0 : SetSERDESOscillatorFrequency(targetFrequency);
3273 0 : return true;
3274 : }
3275 :
3276 0 : void CFOLib::CFO_Registers::DisableLinks()
3277 : {
3278 0 : __COUT_INFO__ << "CFO disable serdes transmit and receive";
3279 0 : WriteRegister_(0, CFOandDTC_Register_LinkEnable);
3280 0 : }
3281 :
3282 0 : void CFOLib::CFO_Registers::DisableAllOutputs()
3283 : {
3284 0 : __COUT_INFO__ << "CFO disable Event Start character output";
3285 0 : WriteRegister_(0, CFOandDTC_Register_Control);
3286 :
3287 0 : __COUT_INFO__ << "CFO disable serdes transmit and receive";
3288 0 : WriteRegister_(0, CFOandDTC_Register_LinkEnable);
3289 :
3290 0 : __COUT_INFO__ << "CFO turn off Event Windows";
3291 : // WriteRegister_(0,CFO_Register_EventWindowEmulatorIntervalTime);
3292 0 : DisableBeamOnMode(CFOLib::CFO_Link_ID::CFO_Link_ALL);
3293 0 : DisableBeamOffMode(CFOLib::CFO_Link_ID::CFO_Link_ALL);
3294 :
3295 : // LEGACY: register 0x9154 repurposed as RunPlanSubrunEvtLimit; no longer writing ClockMarkerIntervalCount
3296 : // __COUT_INFO__ << "CFO turn off 40MHz marker interval";
3297 : // WriteRegister_(0, CFO_Register_ClockMarkerIntervalCount);
3298 0 : }
3299 :
3300 : // Private Functions
3301 0 : bool CFOLib::CFO_Registers::NeedToVerifyRegisterWrite_(const CFOandDTC_Register& address)
3302 : {
3303 0 : switch (address)
3304 : {
3305 : // list all registers that do no need to be verified
3306 0 : case CFO_Register_RunPlan_Data:
3307 0 : return false;
3308 0 : default:;
3309 : }
3310 0 : return true;
3311 : } // end NeedToVerifyRegisterWrite_()
3312 :
3313 0 : void CFOLib::CFO_Registers::VerifyRegisterWrite_(const CFOandDTC_Register& address, uint32_t readbackValue, uint32_t dataToWrite)
3314 : {
3315 : // verify register readback
3316 : if (1)
3317 : {
3318 0 : switch (address) // handle special register checks by masking of DONT-CARE bits, or else check full 32 bits
3319 : {
3320 : //---------- CFO only registers
3321 0 : case CFO_Register_JitterAttenuatorCSR: // 0x9500 bit-0 is reset, input select bit-5:4, bit-8 is LOL, bit-11:9
3322 : // (input LOS).. only check input select bits
3323 0 : dataToWrite &= (3 << 4);
3324 0 : readbackValue &= (3 << 4);
3325 0 : break;
3326 :
3327 0 : default:; // do direct comparison of each bit
3328 : } // end readback verification address case handling
3329 :
3330 0 : if (readbackValue != dataToWrite)
3331 : {
3332 : try
3333 : {
3334 0 : __SS__ << "Write check mismatch - "
3335 0 : << "write value 0x" << std::setw(8) << std::setfill('0') << std::setprecision(8) << std::hex << static_cast<uint32_t>(dataToWrite)
3336 0 : << " to register 0x" << std::setw(4) << std::setfill('0') << std::setprecision(4) << std::hex << static_cast<uint32_t>(address) << "... read back 0x" << std::setw(8) << std::setfill('0') << std::setprecision(8) << std::hex << static_cast<uint32_t>(readbackValue) << std::endl
3337 0 : << std::endl
3338 0 : << "If you do not understand this error, try checking the CFO firmware version: " << ReadDesignDate() << std::endl;
3339 0 : __SS_ONLY_THROW__;
3340 0 : }
3341 0 : catch (const std::runtime_error& e)
3342 : {
3343 0 : std::stringstream ss;
3344 0 : ss << e.what();
3345 : ss << "\n\nThe stack trace is as follows:\n"
3346 0 : << otsStyleStackTrace() << __E__; // artdaq::debug::getStackTraceCollector().print_stacktrace() << __E__;
3347 0 : __SS_THROW__;
3348 0 : }
3349 :
3350 : // __COUT_ERR__ << ss.str();
3351 : // throw DTC_IOErrorException(ss.str());
3352 : // __FE_COUT_ERR__ << ss.str();
3353 : }
3354 :
3355 : } // end verify register readback
3356 0 : }
3357 :
3358 0 : int CFOLib::CFO_Registers::DecodeHighSpeedDivider_(int input)
3359 : {
3360 0 : switch (input)
3361 : {
3362 0 : case 0:
3363 0 : return 4;
3364 0 : case 1:
3365 0 : return 5;
3366 0 : case 2:
3367 0 : return 6;
3368 0 : case 3:
3369 0 : return 7;
3370 0 : case 5:
3371 0 : return 9;
3372 0 : case 7:
3373 0 : return 11;
3374 0 : default:
3375 0 : return -1;
3376 : }
3377 : }
3378 :
3379 0 : int CFOLib::CFO_Registers::EncodeHighSpeedDivider_(int input)
3380 : {
3381 0 : switch (input)
3382 : {
3383 0 : case 4:
3384 0 : return 0;
3385 0 : case 5:
3386 0 : return 1;
3387 0 : case 6:
3388 0 : return 2;
3389 0 : case 7:
3390 0 : return 3;
3391 0 : case 9:
3392 0 : return 5;
3393 0 : case 11:
3394 0 : return 7;
3395 0 : default:
3396 0 : return -1;
3397 : }
3398 : }
3399 :
3400 0 : int CFOLib::CFO_Registers::EncodeOutputDivider_(int input)
3401 : {
3402 0 : if (input == 1) return 0;
3403 0 : int temp = input / 2;
3404 0 : return (temp * 2) - 1;
3405 : }
3406 :
3407 0 : uint64_t CFOLib::CFO_Registers::CalculateFrequencyForProgramming_(double targetFrequency, double currentFrequency,
3408 : uint64_t currentProgram)
3409 : {
3410 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: targetFrequency=" << targetFrequency << ", currentFrequency=" << currentFrequency
3411 0 : << ", currentProgram=" << std::showbase << std::hex << static_cast<unsigned long long>(currentProgram);
3412 0 : auto currentHighSpeedDivider = DecodeHighSpeedDivider_((currentProgram >> 45) & 0x7);
3413 0 : auto currentOutputDivider = DecodeOutputDivider_((currentProgram >> 38) & 0x7F);
3414 0 : auto currentRFREQ = DecodeRFREQ_(currentProgram & 0x3FFFFFFFFF);
3415 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: Current HSDIV=" << currentHighSpeedDivider << ", N1=" << currentOutputDivider << ", RFREQ=" << currentRFREQ;
3416 0 : const auto minFreq = 4850000000; // Hz
3417 0 : const auto maxFreq = 5670000000; // Hz
3418 :
3419 0 : auto fXTAL = currentFrequency * currentHighSpeedDivider * currentOutputDivider / currentRFREQ;
3420 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: fXTAL=" << fXTAL;
3421 :
3422 0 : std::vector<int> hsdiv_values = {11, 9, 7, 6, 5, 4};
3423 0 : std::vector<std::pair<int, double>> parameter_values;
3424 0 : for (auto hsdiv : hsdiv_values)
3425 : {
3426 0 : auto minN = minFreq / (targetFrequency * hsdiv);
3427 0 : if (minN > 128) break;
3428 :
3429 0 : auto thisN = 2;
3430 0 : if (minN < 1) thisN = 1;
3431 0 : while (thisN < minN)
3432 : {
3433 0 : thisN += 2;
3434 : }
3435 0 : auto fdco_new = hsdiv * thisN * targetFrequency;
3436 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: Adding solution: HSDIV=" << hsdiv << ", N1=" << thisN << ", fdco_new=" << fdco_new;
3437 0 : parameter_values.push_back(std::make_pair(thisN, fdco_new));
3438 : }
3439 :
3440 0 : auto counter = -1;
3441 0 : auto newHighSpeedDivider = 0;
3442 0 : auto newOutputDivider = 0;
3443 0 : auto newRFREQ = 0.0;
3444 :
3445 0 : for (auto values : parameter_values)
3446 : {
3447 0 : ++counter;
3448 0 : if (values.second > maxFreq) continue;
3449 :
3450 0 : newHighSpeedDivider = hsdiv_values[counter];
3451 0 : newOutputDivider = values.first;
3452 0 : newRFREQ = values.second / fXTAL;
3453 0 : break;
3454 : }
3455 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: New Program: HSDIV=" << newHighSpeedDivider << ", N1=" << newOutputDivider << ", RFREQ=" << newRFREQ;
3456 :
3457 0 : if (EncodeHighSpeedDivider_(newHighSpeedDivider) == -1)
3458 : {
3459 0 : __COUT_ERR__ << "ERROR: CalculateFrequencyForProgramming: Invalid HSDIV " << newHighSpeedDivider << "!";
3460 0 : return 0;
3461 : }
3462 0 : if (newOutputDivider > 128 || newOutputDivider < 0)
3463 : {
3464 0 : __COUT_ERR__ << "ERROR: CalculateFrequencyForProgramming: Invalid N1 " << newOutputDivider << "!";
3465 0 : return 0;
3466 : }
3467 0 : if (newRFREQ <= 0)
3468 : {
3469 0 : __COUT_ERR__ << "ERROR: CalculateFrequencyForProgramming: Invalid RFREQ " << newRFREQ << "!";
3470 0 : return 0;
3471 : }
3472 :
3473 0 : auto output = (static_cast<uint64_t>(EncodeHighSpeedDivider_(newHighSpeedDivider)) << 45) +
3474 0 : (static_cast<uint64_t>(EncodeOutputDivider_(newOutputDivider)) << 38) + EncodeRFREQ_(newRFREQ);
3475 0 : TLOG(TLVL_CalculateFreq) << __COUT_HDR__ << "CalculateFrequencyForProgramming: New Program: " << std::showbase << std::hex << static_cast<unsigned long long>(output);
3476 0 : return output;
3477 0 : }
|