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