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