Line data Source code
1 : #include "wibmod/WIB1/WIB.hh"
2 : #include "wibmod/WIB1/BNL_UDP_Exception.hh"
3 : #include "wibmod/WIB1/WIBException.hh"
4 : #include <iostream>
5 : #include <stdio.h> //snprintf
6 :
7 0 : WIB::WIB(std::string const& address,
8 : std::string const& WIBAddressTable,
9 : std::string const& FEMBAddressTable,
10 0 : bool fullStart)
11 : : WIBBase(address, WIBAddressTable, FEMBAddressTable)
12 0 : , DAQMode(UNKNOWN)
13 0 : , FEMBStreamCount(4)
14 0 : , FEMBCDACount(2)
15 0 : , ContinueOnFEMBRegReadError(false)
16 0 : , ContinueOnFEMBSPIError(false)
17 0 : , ContinueOnFEMBSyncError(true)
18 0 : , ContinueIfListOfFEMBClockPhasesDontSync(true)
19 : {
20 :
21 0 : if (fullStart) {
22 : // Figure out what kind of WIB firmware we are dealing with
23 0 : FEMBCount = Read("SYSTEM.FEMB_COUNT");
24 0 : DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
25 : // Hardcoded lookup for RCE and FELIX
26 0 : if ((FEMBCount == 4) && (DAQLinkCount == 4)) {
27 0 : DAQMode = RCE;
28 0 : } else if ((FEMBCount == 4) && (DAQLinkCount == 2)) {
29 0 : DAQMode = FELIX;
30 : }
31 : // TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
32 : // TODO create those registers
33 0 : Write("POWER.ENABLE.MASTER_BIAS", 1);
34 0 : started = true;
35 : }
36 0 : }
37 :
38 0 : WIB::~WIB() {}
39 :
40 : void
41 0 : WIB::FullStart()
42 : {
43 : // Figure out what kind of WIB firmware we are dealing with
44 0 : FEMBCount = Read("SYSTEM.FEMB_COUNT");
45 0 : DAQLinkCount = Read("SYSTEM.DAQ_LINK_COUNT");
46 : // Hardcoded lookup for RCE and FELIX
47 0 : if ((FEMBCount == 4) && (DAQLinkCount == 4)) {
48 0 : DAQMode = RCE;
49 0 : } else if ((FEMBCount == 4) && (DAQLinkCount == 2)) {
50 0 : DAQMode = FELIX;
51 : }
52 : // TODO check FEMBStreamCount and FEMCDACount from registers on the WIB
53 : // TODO create those registers
54 0 : Write("POWER.ENABLE.MASTER_BIAS", 1);
55 0 : started = true;
56 0 : }
57 :
58 : void
59 0 : WIB::EnableDAQLink(uint8_t iDAQLink)
60 : {
61 : // CHeck if we know how to dael with this firmware
62 0 : if (!((DAQMode == RCE) || (DAQMode == FELIX))) {
63 : // Not RCE or FELIX firmware, return
64 0 : BUException::WIB_FEATURE_NOT_SUPPORTED e;
65 0 : e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
66 0 : throw e;
67 0 : }
68 :
69 : // Build the base string for this DAQLINK
70 0 : std::string base("DAQ_LINK_");
71 0 : base.push_back(GetDAQLinkChar(iDAQLink));
72 0 : base.append(".CONTROL.");
73 0 : printf("%s\n", base.c_str());
74 :
75 : // set the CD stream enable mask from that
76 : uint32_t enable_mask = 0;
77 0 : for (size_t iStream = 0; iStream < (4 * FEMBCount / DAQLinkCount); iStream++) {
78 : enable_mask <<= 0x1;
79 : }
80 :
81 0 : Write(base + "ENABLE_CDA_STREAM", enable_mask);
82 :
83 0 : Write(base + "ENABLE", 0x1);
84 0 : }
85 :
86 : void
87 0 : WIB::EnableDAQLink_Lite(uint8_t iDAQLink, uint8_t enable)
88 : {
89 : // CHeck if we know how to dael with this firmware
90 0 : if (!((DAQMode == RCE) || (DAQMode == FELIX))) {
91 : // Not RCE or FELIX firmware, return
92 0 : BUException::WIB_FEATURE_NOT_SUPPORTED e;
93 0 : e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
94 0 : throw e;
95 0 : }
96 :
97 : // Build the base string for this DAQLINK
98 0 : std::string base("DAQ_LINK_");
99 0 : base.push_back(GetDAQLinkChar(iDAQLink));
100 0 : base.append(".CONTROL.");
101 :
102 0 : uint8_t stream = 0;
103 0 : if (enable) {
104 0 : if (DAQMode == RCE)
105 : stream = 0xF;
106 : else
107 0 : stream = 0xFF;
108 : }
109 :
110 0 : Write(base + "ENABLE_CDA_STREAM", stream);
111 0 : Write(base + "ENABLE", enable);
112 0 : }
113 :
114 : /*void WIB::DisableDAQLink_Lite(uint8_t iDAQLink, uint8_t enable){
115 : //CHeck if we know how to dael with this firmware
116 : if(!((DAQMode == RCE)||(DAQMode == FELIX))){
117 : //Not RCE or FELIX firmware, return
118 : BUException::WIB_FEATURE_NOT_SUPPORTED e;
119 : e.Append("Automatic DAQLink configuration not supported with this firmware.\n");
120 : throw e;
121 : }
122 :
123 : //Build the base string for this DAQLINK
124 : std::string base("DAQ_LINK_");
125 : base.push_back(GetDAQLinkChar(iDAQLink));
126 : base.append(".CONTROL.");
127 :
128 : uint8_t stream = 0;
129 : if(DAQMode == RCE) stream = 0xF;
130 : else stream = 0xFF;
131 :
132 : if(enable){
133 : Write(base+"ENABLE_CDA_STREAM",stream);
134 :
135 : Write(base+"ENABLE",enable);
136 : }
137 : else{
138 : Write(base+"ENABLE_CDA_STREAM",0);
139 : Write(base+"ENABLE",0);
140 : }
141 : }*/
142 :
143 : void
144 0 : WIB::InitializeWIB()
145 : {
146 : // run resets
147 0 : Write("SYSTEM.RESET", 0xFF);
148 : // Set clock settings
149 0 : Write("POWER.ENABLE.MASTER_BIAS", 0x1); // Turn on DC/DC converter
150 0 : }
151 :
152 : // void WIB::ResetWIB(bool cntrlRegister=true, bool global=false, bool daq_path=false, bool udp=false){
153 : void
154 0 : WIB::ResetWIB(bool reset_udp)
155 : {
156 :
157 0 : if (reset_udp) {
158 : // Resetting the UDP will stop the reply packet which will cause an error.
159 0 : try {
160 0 : Write("SYSTEM.RESET.UDP_RESET", 1);
161 0 : } catch (BUException::BAD_REPLY& e) {
162 : // do nothing
163 0 : }
164 : // Since we don't know this happened since we lack a udp response, do it again.
165 : // This could be extended to read register REG
166 0 : usleep(10000);
167 0 : try {
168 0 : Write("SYSTEM.RESET.UDP_RESET", 1);
169 0 : } catch (BUException::BAD_REPLY& e) {
170 : // do nothing
171 0 : }
172 0 : usleep(10000);
173 : }
174 :
175 : // Reset the control register
176 0 : WriteWithRetry("SYSTEM.RESET.CONTROL_REGISTER_RESET", 1);
177 0 : usleep(1000);
178 :
179 : // If this is felix, make sure we configure the SI5342
180 0 : if (DAQMode == FELIX) {
181 0 : Write("DAQ.SI5342.RESET", 1);
182 : usleep(10000);
183 0 : Write("DAQ.SI5342.RESET", 0);
184 0 : usleep(10000);
185 0 : printf("Configuring SI5342 for FELIX\n");
186 0 : LoadConfigDAQ_SI5342("default"); // use the default config file for the SI5342
187 0 : usleep(10000); // Wait for
188 0 : SelectSI5342(1, // Set input to be local oscillator for FELIX clock
189 : 1); // enable the output of the SI5342
190 : }
191 :
192 : // Reset the Eventbuilder PLL
193 0 : Write("SYSTEM.RESET.EB_PLL_RESET", 1);
194 0 : usleep(10000);
195 :
196 : // Reset the DAQ path
197 0 : Write("SYSTEM.RESET.DAQ_PATH_RESET", 1);
198 :
199 0 : usleep(10000);
200 :
201 : // Set clock settings
202 0 : Write("DTS.CMD_COUNT_RESET", 0xFFFFFFFF);
203 0 : Write("DTS.CMD_COUNT_RESET", 0);
204 :
205 : // Halt signals
206 0 : Write("DTS.CONVERT_CONTROL.HALT", 1);
207 0 : Write("DTS.CONVERT_CONTROL.ENABLE", 0);
208 :
209 : // Make sure DC/DC is on
210 0 : Write("POWER.ENABLE.MASTER_BIAS", 1);
211 0 : }
212 :
213 : void
214 0 : WIB::ResetWIBAndCfgDTS(uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource, uint32_t PDTSAlignment_timeout)
215 : {
216 0 : if (DAQMode == UNKNOWN) {
217 0 : BUException::WIB_DAQMODE_UNKNOWN e;
218 0 : throw e;
219 0 : }
220 0 : if (localClock > 1) {
221 0 : BUException::WIB_BAD_ARGS e;
222 0 : e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
223 0 : throw e;
224 0 : }
225 0 : if (PDTSsource > 1) {
226 0 : BUException::WIB_BAD_ARGS e;
227 0 : e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
228 0 : throw e;
229 0 : }
230 0 : if (16 <= PDTS_TGRP) {
231 0 : BUException::WIB_BAD_ARGS e;
232 0 : e.Append("PDTS TGRP > 15; must be 0 to 15\n");
233 0 : throw e;
234 0 : }
235 :
236 : // get this register so we can leave it in the state it started in
237 0 : uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
238 :
239 0 : ResetWIB();
240 0 : Write("SYSTEM.SLOW_CONTROL_DND", 1);
241 0 : sleep(1);
242 :
243 0 : for (size_t iFEMB = 1; iFEMB <= 4; iFEMB++) {
244 0 : FEMBPower(iFEMB, 0);
245 : }
246 :
247 : // make sure everything DTS is off
248 0 : Write("DTS.CONVERT_CONTROL.HALT", 1);
249 0 : Write("DTS.CONVERT_CONTROL.ENABLE", 0);
250 0 : Write("DTS.CONVERT_CONTROL.START_SYNC", 0);
251 0 : sleep(1);
252 :
253 0 : if (localClock > 0) {
254 0 : printf("Configuring local clock\n");
255 : // Configure the SI5344 to use the local oscillator instead of the PDTS
256 0 : LoadConfigDTS_SI5344("default");
257 0 : sleep(1);
258 0 : SelectSI5344(1, 1);
259 0 : sleep(1);
260 0 : Write("DTS.CONVERT_CONTROL.EN_FAKE", 1);
261 0 : Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP", 1);
262 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
263 : // Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
264 0 : sleep(1);
265 : } else {
266 : // Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
267 0 : printf("Configuring DTS\n");
268 0 : Write("DTS.PDTS_TGRP", PDTS_TGRP);
269 0 : printf("Using timing group 0x%X\n", PDTS_TGRP);
270 0 : InitializeDTS(PDTSsource, 0, PDTSAlignment_timeout);
271 0 : sleep(1);
272 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
273 0 : sleep(1);
274 : // We are ready for the PDTS, start searching
275 0 : Write("DTS.PDTS_ENABLE", 1);
276 0 : sleep(1);
277 : }
278 :
279 : // Now we have the 128MHz clock
280 0 : Write("FEMB1.DAQ.ENABLE", 0);
281 0 : Write("FEMB2.DAQ.ENABLE", 0);
282 0 : Write("FEMB3.DAQ.ENABLE", 0);
283 0 : Write("FEMB4.DAQ.ENABLE", 0);
284 :
285 0 : Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
286 0 : }
287 :
288 : void
289 0 : WIB::CheckedResetWIBAndCfgDTS(uint8_t localClock, uint8_t PDTS_TGRP, uint8_t PDTSsource, uint32_t PDTSAlignment_timeout)
290 : {
291 0 : if (DAQMode == UNKNOWN) {
292 0 : BUException::WIB_DAQMODE_UNKNOWN e;
293 0 : throw e;
294 0 : }
295 0 : if (localClock > 1) {
296 0 : BUException::WIB_BAD_ARGS e;
297 0 : e.Append("localClock > 1; must be 0 (for DTS) or 1 (for local clock)\n");
298 0 : throw e;
299 0 : }
300 0 : if (PDTSsource > 1) {
301 0 : BUException::WIB_BAD_ARGS e;
302 0 : e.Append("PDTSsource > 1; must be 0 (for backplane) or 1 (for front panel)\n");
303 0 : throw e;
304 0 : }
305 0 : if (16 <= PDTS_TGRP) {
306 0 : BUException::WIB_BAD_ARGS e;
307 0 : e.Append("PDTS TGRP > 15; must be 0 to 15\n");
308 0 : throw e;
309 0 : }
310 :
311 0 : bool reset_check = false;
312 : // Check if we are already in a good state
313 0 : if (localClock > 0) {
314 0 : printf("Checking if locked on local clock\n");
315 0 : reset_check = ((Read("DTS.CONVERT_CONTROL.EN_FAKE") != 1) || (Read("DTS.CCONVERT_CONTROL.LOCAL_TIMESTAMP") != 1) ||
316 0 : (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1)
317 : // || (Read("FEMB_CNC.ENABLE_DTS_CMDS") != 1)
318 0 : || (Read("DTS.SI5344.INPUT_SELECT") != 1) || (Read("DTS.SI5344.ENABLE") != 1));
319 0 : if (!reset_check) {
320 0 : printf("Already in a good state\n");
321 : } else {
322 0 : printf("Need to reset for local clocking\n");
323 : }
324 : } else {
325 0 : printf("Checking if locked on PDTS\n");
326 0 : reset_check = ((Read("DTS.PDTS_TGRP") != PDTS_TGRP) || (Read("FEMB_CNC.CNC_CLOCK_SELECT") != 1) ||
327 0 : (Read("DTS.PDTS_ENABLE") != 1) || (Read("DTS.CDS.LOL") != 0) || (Read("DTS.CDS.LOS") != 0) ||
328 0 : (ReadWithRetry("DTS.SI5344.INPUT_SELECT") != 0) || (ReadWithRetry("DTS.SI5344.LOS") != 0) ||
329 0 : (ReadWithRetry("DTS.SI5344.LOL") != 0) || (ReadWithRetry("DTS.SI5344.ENABLE") != 1) ||
330 0 : (ReadWithRetry("DTS.PDTS_STATE") != 0x8));
331 0 : if (!reset_check) {
332 0 : printf("Already in a good state\n");
333 : } else {
334 0 : printf("Need to reset for PDTS\n");
335 : }
336 : }
337 :
338 : // Check the SI5342 if we're attached to FELIX
339 0 : if (DAQMode == FELIX) {
340 :
341 0 : if ((Read("DAQ.SI5342.ENABLE") == 0) || (Read("DAQ.SI5342.INPUT_SELECT") != 1) || (Read("DAQ.SI5342.LOL") == 1) ||
342 0 : (Read("DAQ.SI5342.LOS_XAXB") == 1) || (Read("DAQ.SI5342.LOS_2") == 1)) {
343 0 : printf("Need to reset for SI5342\n");
344 0 : reset_check = true;
345 : } else {
346 0 : printf("SI5342 in good state\n");
347 : }
348 : }
349 :
350 0 : if (reset_check) {
351 : // get this register so we can leave it in the state it started in
352 0 : uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
353 :
354 0 : ResetWIB();
355 0 : Write("SYSTEM.SLOW_CONTROL_DND", 1);
356 :
357 0 : for (size_t iFEMB = 1; iFEMB <= 4; iFEMB++) {
358 0 : FEMBPower(iFEMB, 0);
359 : }
360 :
361 : // make sure everything DTS is off
362 0 : Write("DTS.CONVERT_CONTROL.HALT", 1);
363 0 : Write("DTS.CONVERT_CONTROL.ENABLE", 0);
364 0 : Write("DTS.CONVERT_CONTROL.START_SYNC", 0);
365 0 : sleep(1);
366 :
367 0 : if (localClock > 0) {
368 0 : printf("Configuring local clock\n");
369 : // Configure the SI5344 to use the local oscillator instead of the PDTS
370 0 : LoadConfigDTS_SI5344("default");
371 0 : sleep(1);
372 0 : SelectSI5344(1, 1);
373 0 : sleep(1);
374 0 : Write("DTS.CONVERT_CONTROL.EN_FAKE", 1);
375 0 : Write("DTS.CONVERT_CONTROL.LOCAL_TIMESTAMP", 1);
376 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
377 : // Write("FEMB_CNC.ENABLE_DTS_CMDS",1);
378 0 : sleep(1);
379 : } else {
380 : // Configure the clocking for the PDTS (assumes the PDTS is sending idle or something)
381 0 : printf("Configuring DTS\n");
382 0 : Write("DTS.PDTS_TGRP", PDTS_TGRP);
383 0 : printf("Using timing group 0x%X\n", PDTS_TGRP);
384 0 : InitializeDTS(PDTSsource, 0, PDTSAlignment_timeout);
385 0 : sleep(1);
386 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
387 0 : sleep(1);
388 : // We are ready for the PDTS, start searching
389 0 : Write("DTS.PDTS_ENABLE", 1);
390 0 : sleep(1);
391 : }
392 :
393 0 : Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
394 : }
395 : // Now we have the 128MHz clock
396 0 : std::cout << "Resetting DAQ Links" << std::endl;
397 0 : size_t nLinks = 4;
398 0 : if (DAQMode == FELIX) {
399 0 : nLinks = 2;
400 : }
401 0 : for (size_t iLink = 1; iLink <= nLinks; ++iLink) {
402 0 : std::cout << iLink << std::endl;
403 0 : EnableDAQLink_Lite(iLink, 0);
404 : }
405 :
406 0 : Write("FEMB1.DAQ.ENABLE", 0);
407 0 : Write("FEMB2.DAQ.ENABLE", 0);
408 0 : Write("FEMB3.DAQ.ENABLE", 0);
409 0 : Write("FEMB4.DAQ.ENABLE", 0);
410 0 : }
411 :
412 : void
413 0 : WIB::StartStreamToDAQ(bool link1_enabled, bool link2_enabled, bool link3_enabled, bool link4_enabled)
414 : {
415 0 : if (DAQMode == UNKNOWN) {
416 0 : BUException::WIB_DAQMODE_UNKNOWN e;
417 0 : throw e;
418 0 : }
419 0 : WriteWithRetry("DTS.CONVERT_CONTROL.HALT", 1);
420 0 : WriteWithRetry("DTS.CONVERT_CONTROL.ENABLE", 0);
421 :
422 : // get this register so we can leave it in the state it started in
423 0 : uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
424 0 : Write("SYSTEM.SLOW_CONTROL_DND", 1);
425 :
426 0 : sleep(1);
427 0 : Write("FEMB_CNC.FEMB_STOP", 1);
428 0 : sleep(1);
429 0 : Write("SYSTEM.RESET.DAQ_PATH_RESET", 1);
430 0 : sleep(1);
431 :
432 : // Enable DAQ links
433 0 : if (DAQMode == FELIX) {
434 0 : if (link1_enabled)
435 0 : EnableDAQLink_Lite(1, 1);
436 0 : if (link2_enabled)
437 0 : EnableDAQLink_Lite(2, 1);
438 : } else {
439 0 : if (link3_enabled)
440 0 : EnableDAQLink_Lite(3, 1);
441 0 : if (link4_enabled)
442 0 : EnableDAQLink_Lite(4, 1);
443 : }
444 :
445 : // Enable the FEMB to align to idle and wait for convert
446 0 : Write("FEMB1.DAQ.ENABLE", 0xF);
447 0 : Write("FEMB2.DAQ.ENABLE", 0xF);
448 0 : Write("FEMB3.DAQ.ENABLE", 0xF);
449 0 : Write("FEMB4.DAQ.ENABLE", 0xF);
450 :
451 : // Start sending characters from the FEMB
452 0 : Write("FEMB_CNC.ENABLE_DTS_CMDS", 1);
453 0 : StartSyncDTS();
454 : // Write("FEMB_CNC.TIMESTAMP_RESET",1);
455 : // Write("FEMB_CNC.FEMB_START",1);
456 : // Write("SYSTEM.RESET.FEMB_COUNTER_RESET",1);
457 :
458 0 : Write("SYSTEM.SLOW_CONTROL_DND", slow_control_dnd);
459 0 : }
460 :
461 : void
462 0 : WIB::FEMBPower(uint8_t iFEMB, bool turnOn)
463 : {
464 0 : std::string reg = "POWER.ENABLE.FEMB";
465 0 : reg.push_back(GetFEMBChar(iFEMB));
466 0 : if (turnOn) {
467 0 : Write(reg, 0x1F);
468 : } else {
469 0 : Write(reg, 0x0);
470 : }
471 0 : }
472 :
473 : // void WIB::PowerOnFEMB(uint8_t iFEMB){
474 : // //Turn on power
475 : // std::string reg = "POWER.ENABLE.FEMB";
476 : // reg.push_back(GetFEMBChar(iFEMB));
477 : //
478 : //
479 : // const int REG_COUNT = 6;
480 : // uint8_t mon_reg_val = 0x1+REG_COUNT*(iFEMB-1); // starts at 0x1 and there are 6 per FEMB
481 : //
482 : // for(uint8_t iReg=0;iReg < REG_COUNT;iReg++){
483 : // //Go measure the reg value
484 : // // int iTries = 0;
485 : // // const int NUM_TRIES = 100;
486 : // //Set the value to be read
487 : // Write("POWER.MON_CONTROL.ADDRESS",mon_reg_val+iReg);
488 : // //Wait till the output is valid
489 : //// for(;iTries < NUM_TRIES;iTries++){
490 : //// sleep(1);
491 : //// if(0x1 == Read("POWER.MON_CONTROL.VALID")){
492 : //// break;
493 : //// }
494 : //// }
495 : //// if (NUM_TRIES == iTries){
496 : //// printf("Timeout on reading FEMB: %d power reg %d\n",iFEMB,iReg);
497 : //// }else{
498 : // uint32_t reg_val = Read("POWER.MON_VALUE.MEASUREMENT");
499 : // printf("Reg %u 0x%04X 0x%04X\n",iReg,reg_val >> 16,reg_val&0xFFFF);
500 : // // }
501 : // }
502 : //
503 : //}
504 : //
505 : void
506 0 : WIB::EnableFEMBCNC()
507 : {
508 : // Enable the clock and control stream to the FEMBs
509 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 1);
510 0 : Write("FEMB_CNC.CNC_COMMAND_SELECT", 1);
511 0 : }
512 : void
513 0 : WIB::DisableFEMBCNC()
514 : {
515 : // Enable the clock and control stream to the FEMBs
516 0 : Write("FEMB_CNC.CNC_CLOCK_SELECT", 0);
517 0 : Write("FEMB_CNC.CNC_COMMAND_SELECT", 0);
518 0 : }
519 :
520 : bool
521 0 : WIB::CheckDAQLinkInRange(uint8_t iDAQLink)
522 : {
523 0 : if (!((iDAQLink > 0) && (iDAQLink <= DAQLinkCount))) {
524 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
525 0 : e.Append("DAQ Link\n");
526 0 : throw e;
527 0 : }
528 0 : return true;
529 : }
530 :
531 : char
532 0 : WIB::GetDAQLinkChar(uint8_t iDAQLink)
533 : {
534 0 : char c = '0';
535 : // Check if the link is in range given DAQLinkCount (throws)
536 0 : CheckDAQLinkInRange(iDAQLink);
537 : // Convert the numeric daq link number to a char
538 0 : switch (iDAQLink) {
539 : case 1:
540 : c = '1';
541 : break;
542 : case 2:
543 : c = '2';
544 : break;
545 : case 3:
546 : c = '3';
547 : break;
548 : case 4:
549 : c = '4';
550 : break;
551 0 : default:
552 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
553 0 : e.Append("DAQ Link\n");
554 0 : char estr[] = "0";
555 0 : estr[0] = c;
556 0 : e.Append(estr);
557 0 : throw e;
558 : }
559 0 : return c;
560 : }
561 :
562 : bool
563 0 : WIB::CheckFEMBInRange(uint8_t iFEMB)
564 : {
565 0 : if (!((iFEMB > 0) && (iFEMB <= FEMBCount))) {
566 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
567 0 : e.Append("FEMB\n");
568 0 : throw e;
569 0 : }
570 0 : return true;
571 : }
572 :
573 : char
574 0 : WIB::GetFEMBChar(uint8_t iFEMB)
575 : {
576 0 : char c = '0';
577 : // Check if the link is in range given FEMBCount (throws)
578 0 : CheckFEMBInRange(iFEMB);
579 : // Convert the numeric daq link number to a char
580 0 : switch (iFEMB) {
581 : case 1:
582 : c = '1';
583 : break;
584 : case 2:
585 : c = '2';
586 : break;
587 : case 3:
588 : c = '3';
589 : break;
590 : case 4:
591 : c = '4';
592 : break;
593 0 : default:
594 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
595 0 : e.Append("FEMB\n");
596 0 : char estr[] = "0";
597 0 : estr[0] = c;
598 0 : e.Append(estr);
599 0 : throw e;
600 : }
601 0 : return c;
602 : }
603 :
604 : bool
605 0 : WIB::CheckFEMBStreamInRange(uint8_t iStream)
606 : {
607 0 : if (!((iStream > 0) && (iStream <= FEMBStreamCount))) {
608 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
609 0 : e.Append("FEMB Stream");
610 0 : throw e;
611 0 : }
612 0 : return true;
613 : }
614 :
615 : bool
616 0 : WIB::CheckFEMBCDInRange(uint8_t iCDA)
617 : {
618 0 : if (!((iCDA > 0) && (iCDA <= FEMBCDACount))) {
619 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
620 0 : e.Append("FEMB CDA");
621 0 : throw e;
622 0 : }
623 0 : return true;
624 : }
625 :
626 : char
627 0 : WIB::GetFEMBCDChar(uint8_t iCD)
628 : {
629 0 : char c = '0';
630 : // Check if the link is in range given FEMBCount (throws)
631 0 : CheckFEMBCDInRange(iCD);
632 : // Convert the numeric daq link number to a char
633 0 : switch (iCD) {
634 : case 1:
635 : c = '1';
636 : break;
637 0 : case 2:
638 0 : c = '2';
639 0 : break;
640 0 : default:
641 0 : BUException::WIB_INDEX_OUT_OF_RANGE e;
642 0 : e.Append("FEMB CDA\n");
643 0 : char estr[] = "0";
644 0 : estr[0] = c;
645 0 : e.Append(estr);
646 0 : throw e;
647 : }
648 0 : return c;
649 : }
650 :
651 : void
652 0 : WIB::SourceFEMB(uint64_t iFEMB, uint64_t real)
653 : {
654 0 : if (iFEMB < 1) {
655 0 : printf("FEMB index out of range < 1\n");
656 0 : return;
657 : }
658 :
659 : /* if(DAQMode == RCE && iFEMB > 4){
660 : printf("FEMB index out of range > 4 (RCE) \n");
661 : return;}
662 : if(DAQMode == FELIX && iFEMB > 2){
663 : printf("FEMB index out of range > 2 (FELIX) \n");
664 : return;}
665 : */
666 0 : std::string address("FEMB");
667 0 : address.push_back(GetFEMBChar(iFEMB));
668 0 : address.append(".DAQ.FAKE_CD.FAKE_SOURCE");
669 0 : Write(address, real);
670 0 : }
|