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