Line data Source code
1 : #include "ers/ers.hpp"
2 : #include "wibmod/Issues.hpp"
3 : #include "wibmod/WIB1/WIB.hh"
4 : #include "wibmod/WIB1/WIBException.hh"
5 :
6 : #include <unistd.h>
7 :
8 : #include <chrono>
9 : #include <stdio.h>
10 :
11 : void
12 0 : WIB::InitializeDTS(uint8_t PDTSsource, uint8_t clockSource, uint32_t PDTSAlignment_timeout)
13 : {
14 : // Disable the PDTS
15 0 : WriteWithRetry("DTS.PDTS_ENABLE", 0x0);
16 :
17 : // Disable SI5344 outputs (fixed by SI5344 config)
18 0 : WriteWithRetry("DTS.SI5344.ENABLE", 0);
19 : // Disable SI5344 (fixed by SI5344 config)
20 0 : WriteWithRetry("DTS.SI5344.RESET", 1);
21 :
22 : // Reset the I2C firmware
23 0 : WriteWithRetry("DTS.CDS.I2C.RESET", 1);
24 :
25 0 : if (0 == clockSource) {
26 0 : printf("Using PDTS for DUNE timing.\n\nConfiguring clock and data separator\n");
27 : // Bring up the CDS
28 0 : float frequency = 0;
29 0 : try {
30 0 : frequency = ConfigureDTSCDS(PDTSsource);
31 0 : } catch (BUException::exBase& e) {
32 0 : frequency = 0;
33 0 : e.Append("Failed to communicate with the DTS CDS via I2C\n");
34 0 : throw;
35 0 : }
36 0 : uint32_t LOL = Read("DTS.CDS.LOL");
37 0 : uint32_t LOS = Read("DTS.CDS.LOS");
38 0 : printf("CDS frequency %f\n", frequency);
39 0 : printf("CDS LOL=%d LOS=%d\n", LOL, LOS);
40 :
41 : // Check for the correct frequency, not in LOS, and not in LOL
42 : // if( (2.4136e+08 == frequency) &&
43 0 : if (LOL || LOS) {
44 0 : BUException::WIB_DTS_ERROR e;
45 0 : e.Append("Failed to configure CDS chip\n");
46 0 : throw e;
47 0 : }
48 : } else {
49 0 : printf("Using local OSC for DUNE timing\n");
50 : }
51 : // CDS is up
52 :
53 0 : printf("\nConfiguring SI5344.\n");
54 :
55 : // Set the SI5344 source
56 0 : WriteWithRetry("DTS.SI5344.INPUT_SELECT", clockSource);
57 : // Configure Si5344 with default config file
58 : // Do the I2C configuration
59 0 : try {
60 0 : LoadConfigDTS_SI5344("");
61 0 : } catch (BUException::exBase& e) {
62 : // Disable SI5344 outputs
63 0 : WriteWithRetry("DTS.SI5344.ENABLE", 0);
64 : // Disable SI5344
65 0 : WriteWithRetry("DTS.SI5344.RESET", 1);
66 :
67 0 : e.Append("Error in LoadConfigDTS_SI5344\n");
68 0 : throw;
69 0 : }
70 :
71 0 : usleep(100000);
72 :
73 : // Check that SI5344 is locked on
74 0 : if (ReadWithRetry("DTS.SI5344.LOS") || ReadWithRetry("DTS.SI5344.LOL")) {
75 : // Disable SI5344 outputs
76 0 : WriteWithRetry("DTS.SI5344.ENABLE", 0);
77 : // Disable SI5344
78 0 : WriteWithRetry("DTS.SI5344.RESET", 1);
79 :
80 : // Throw
81 0 : BUException::WIB_DTS_ERROR e;
82 0 : e.Append("Failed to configure the SI5344 chip correctly\n");
83 0 : throw e;
84 0 : }
85 :
86 : // Enable the clock for FPGA
87 0 : WriteWithRetry("DTS.SI5344.ENABLE", 1);
88 0 : usleep(100000);
89 :
90 0 : char const* const PDTSStates[] = { "W_RST", "W_LINK", "W_FREQ", "W_ADJUST", "W_ALIGN", "W_LOCK", "W_PHASE", "W_RDY",
91 : "RUN", "0x9", "0xA", "0xB", "ERR_R", "ERR_T", "ERR_P", "0xF" };
92 :
93 0 : if (0 == clockSource) {
94 0 : printf("\nSetup PDTS.\n");
95 0 : bool timeout_exists = true;
96 0 : if (PDTSAlignment_timeout == 0)
97 0 : timeout_exists = false;
98 :
99 0 : auto start_time = std::chrono::high_resolution_clock::now();
100 0 : bool timed_out = false;
101 :
102 0 : while ((timeout_exists == false) || timed_out == false) {
103 : // Using PDTS, set that up.
104 0 : usleep(500000);
105 0 : WriteWithRetry("DTS.PDTS_ENABLE", 1);
106 0 : usleep(500000); // needed in new PDTS system to get to a good state before giving up and trying a new phase.
107 :
108 : // See if we've locked
109 0 : uint32_t pdts_state = ReadWithRetry("DTS.PDTS_STATE");
110 0 : printf("PDTS state: %s (0x%01X)\n", PDTSStates[pdts_state & 0xF], pdts_state);
111 0 : if ((pdts_state < 0x6) || (pdts_state > 0x8)) {
112 0 : WriteWithRetry("DTS.PDTS_ENABLE", 0);
113 : // dynamic post-amble
114 0 : Write("DTS.SI5344.I2C.RESET", 1);
115 0 : SetDTS_SI5344Page(0x0);
116 0 : Write("DTS.SI5344.I2C.RESET", 1);
117 0 : WriteDTS_SI5344(0x1C, 0x1, 1);
118 0 : } else if (0x6 == pdts_state) {
119 0 : ers::info(dunedaq::wibmod::WaitingForAlignment(ERS_HERE));
120 0 : } else if (0x7 == pdts_state) {
121 0 : ers::info(dunedaq::wibmod::WaitingForTimestamp(ERS_HERE));
122 : } else {
123 0 : return; // 0x8 == pdts_state
124 : }
125 0 : auto now = std::chrono::high_resolution_clock::now();
126 0 : auto duration = now - start_time;
127 0 : if (duration.count() > PDTSAlignment_timeout)
128 0 : timed_out = true;
129 : }
130 : // If we get here something went wrong
131 0 : Write("DTS.SI5344.I2C.RESET", 1);
132 0 : SetDTS_SI5344Page(0x0);
133 0 : Write("DTS.SI5344.I2C.RESET", 1);
134 0 : WriteDTS_SI5344(0x1C, 0x1, 1);
135 :
136 0 : BUException::WIB_DTS_ERROR e;
137 0 : e.Append("Failed to configure the PDTS correctly within timeout\n");
138 0 : throw e;
139 0 : }
140 : }
141 :
142 : void
143 0 : WIB::StartSyncDTS()
144 : {
145 0 : WriteWithRetry("DTS.CONVERT_CONTROL.HALT", 0);
146 0 : WriteWithRetry("DTS.CONVERT_CONTROL.ENABLE", 1);
147 0 : WriteWithRetry("DTS.CONVERT_CONTROL.START_SYNC", 1);
148 0 : }
149 :
150 : void
151 0 : WIB::PDTSInRunningState()
152 : {
153 0 : if (Read("DTS.PDTS_STATE") != 0x8) {
154 0 : BUException::WIB_DTS_ERROR e;
155 0 : e.Append("WIB is not in PDTS state RUN(0x8)\n");
156 0 : throw e;
157 0 : }
158 0 : }
|