DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
WIB_FEMB.cpp
Go to the documentation of this file.
1#include "wibmod/WIB1/WIB.hh"
6#include <unistd.h>
7#include <sstream>
8#include <iostream>
9#include <iomanip>
10#include <bitset>
11
12#define sleep(x) usleep((useconds_t) x * 1e6)
13
37void WIB::ConfigFEMB(uint8_t iFEMB, std::vector<uint32_t> fe_config, std::vector<uint16_t> clk_phases,
38 uint8_t pls_mode, uint8_t pls_dac_val, uint8_t start_frame_mode_sel, uint8_t start_frame_swap){
39
40 if (iFEMB < 1 || iFEMB > 4)
41 {
42 BUException::WIB_BAD_ARGS e;
43 std::stringstream expstr;
44 expstr << "ConfigFEMB: iFEMB should be between 1 and 4: "
45 << int(iFEMB);
46 e.Append(expstr.str().c_str());
47 throw e;
48 }
49 if (pls_mode > 2)
50 {
51 BUException::WIB_BAD_ARGS e;
52 std::stringstream expstr;
53 expstr << "ConfigFEMB: pls_dac_mode is allowed to be 0 (off), 1 (FPGA), 2 (internal), but is: "
54 << int(pls_mode);
55 e.Append(expstr.str().c_str());
56 throw e;
57 }
58 if (start_frame_mode_sel > 1 || start_frame_swap > 1)
59 {
60 BUException::WIB_BAD_ARGS e;
61 std::stringstream expstr;
62 expstr << "ConfigFEMB: start_frame_mode_sel and start_frame_swap must be 0 or 1";
63 e.Append(expstr.str().c_str());
64 throw e;
65 }
66
67 if(fe_config.size() != 8){
68
69 BUException::WIB_BAD_ARGS e;
70 std::stringstream expstr;
71 expstr << "Error: Expecting 9 Front End configuration options:" << std::endl <<
72 "\t0: Gain" << std::endl <<
73 "\t1: Shaping Time" << std::endl <<
74 "\t2: High Baseline" << std::endl <<
75 "\t3: High Leakage" << std::endl <<
76 "\t4: Leakage x 10" << std::endl <<
77 "\t5: AC Coupling" << std::endl <<
78 "\t6: Buffer" << std::endl <<
79 "\t7: Use External Clock" << std::endl;
80 e.Append(expstr.str().c_str());
81 throw e;
82 }
83 else{
84 std::cout << "Front End configuration options:" << std::endl <<
85 "\t0:" << std::setw(22) << std::setfill(' ') << "Gain " << fe_config[0] << std::endl <<
86 "\t1:" << std::setw(22) << std::setfill(' ') << "Shaping Time " << fe_config[1] << std::endl <<
87 "\t2:" << std::setw(22) << std::setfill(' ') << "High Baseline " << fe_config[2] << std::endl <<
88 "\t3:" << std::setw(22) << std::setfill(' ') << "High Leakage " << fe_config[3] << std::endl <<
89 "\t4:" << std::setw(22) << std::setfill(' ') << "Leakage x 10 " << fe_config[4] << std::endl <<
90 "\t5:" << std::setw(22) << std::setfill(' ') << "AC Coupling " << fe_config[5] << std::endl <<
91 "\t6:" << std::setw(22) << std::setfill(' ') << "Buffer " << fe_config[6] << std::endl <<
92 "\t8:" << std::setw(22) << std::setfill(' ') << "Use External Clock " << fe_config[7] << std::endl;
93 }
94
95 std::cout << "Pulser Mode: " << int(pls_mode) << " and DAC Value: " << int(pls_dac_val) << std::endl;
96
97 // get this register so we can leave it in the state it started in
98 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
99 Write("SYSTEM.SLOW_CONTROL_DND",1);
100
101 if(ReadFEMB(iFEMB,"VERSION_ID") == ReadFEMB(iFEMB,"SYS_RESET")) { // can't read register if equal
103 std::cout << "Error: Can't read registers from FEMB " << int(iFEMB) << std::endl;
104 return;
105 }
106 BUException::FEMB_REG_READ_ERROR e;
107 std::stringstream expstr;
108 expstr << " for FEMB: " << int(iFEMB);
109 e.Append(expstr.str().c_str());
110 throw e;
111 }
112
113 WriteFEMB(iFEMB, "REG_RESET", 1);
114 sleep(1);
115
116 WriteFEMB(iFEMB, "START_FRAME_MODE_SELECT", start_frame_mode_sel);
117 sleep(1);
118 WriteFEMB(iFEMB, "START_FRAME_SWAP", start_frame_swap);
119
120 if(fe_config[7]){ // use external clock
121 SetupFEMBExtClock(iFEMB);
122 }
123 sleep(0.05);
124
125 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
126 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
127
128 // These are all Jack's WIB addresses, need to figure out Dan's addresses for functionality
130 //Write(1, 0);
131 //Write(1, 0);
132 //Write(1, 2);
133 //Write(1, 2);
134 //Write(1, 0);
135 //Write(1, 0);
136 //
138 //Write(18, 0x8000);
139 //Write(18, 0x8000);
140
141 //Reset SPI
142 //
143 sleep(0.005);
144 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 0x1);
145 sleep(0.005);
146 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 0x1);
147 sleep(0.005);
148 WriteFEMB(iFEMB, "FE_ASIC_RESET", 0x1);
149 sleep(0.005);
150 WriteFEMB(iFEMB, "FE_ASIC_RESET", 0x1);
151 sleep(0.005);
152
153 //Set ADC latch_loc
154 uint32_t REG_LATCHLOC1_4_data = 0x04040404;
155 uint32_t REG_LATCHLOC5_8_data = 0x04040404;
156
157 WriteFEMB(iFEMB, "ADC_LATCH_LOC_0TO3", REG_LATCHLOC1_4_data);
158 WriteFEMB(iFEMB, "ADC_LATCH_LOC_4TO7", REG_LATCHLOC5_8_data);
159
160 // Setup pulser
161 uint8_t internal_daq_value = 0;
162 if (pls_mode == 1) // internal, FE ASIC, 6 bits
163 {
164 if (pls_dac_val >= 63)
165 {
166 BUException::WIB_BAD_ARGS e;
167 std::stringstream expstr;
168 expstr << "ConfigFEMB: pls_dac_val is 6 bits for internal DAC, must be 0-63, but is: "
169 << int(pls_dac_val);
170 e.Append(expstr.str().c_str());
171 throw e;
172 }
173 internal_daq_value = pls_dac_val;
174 SetupInternalPulser(iFEMB);
175 }
176 else if (pls_mode == 2) // external, FPGA, 5 bits
177 {
178 if (pls_dac_val >= 32)
179 {
180 BUException::WIB_BAD_ARGS e;
181 std::stringstream expstr;
182 expstr << "ConfigFEMB: pls_dac_val is 5 bits for FPGA DAC, must be 0-31, but is: "
183 << int(pls_dac_val);
184 e.Append(expstr.str().c_str());
185 throw e;
186 }
187 SetupFPGAPulser(iFEMB,pls_dac_val);
188 }
189
190 // Setup ASICs
191 SetupFEMBASICs(iFEMB, fe_config[0], fe_config[1], fe_config[2], fe_config[3], fe_config[4], fe_config[5], fe_config[6], fe_config[7], pls_mode, internal_daq_value);
192 std::cout << "FEMB " << int(iFEMB) << " Successful SPI config" << std::endl;
193
194 // Try to sync ADCs
195 if (clk_phases.size() == 0)
196 {
197 clk_phases.push_back(0xFFFF);
198 }
199 if (!TryFEMBPhases(iFEMB,clk_phases)) {
201 std::cout << "Warning: FEMB " << int(iFEMB) << " ADC FIFO not synced from expected phases, trying to hunt for phases" << std::endl;
202 if (!HuntFEMBPhase(iFEMB,clk_phases.at(0))) {
204 std::cout << "Error: FEMB " << int(iFEMB) << " ADC FIFO could not be synced even after hunting" << std::endl;
205 }
206 else {
207 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
208 BUException::FEMB_ADC_SYNC_ERROR e;
209 std::stringstream expstr;
210 expstr << " after hunting. ";
211 expstr << " FEMB: " << int(iFEMB);
212 expstr << " sync: " << std::bitset<16>(adc_fifo_sync);
213 expstr << " phases: ";
214 expstr << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT");
215 expstr << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT_2");
216 e.Append(expstr.str().c_str());
217 throw e;
218 }
219 } // if ! HuntFEMBPhase
220 } // if ContinueIfListOfFEMBClockPhasesDontSync
221 else // ContinueIfListOfFEMBClockPhasesDontSync
222 {
223 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
224 BUException::FEMB_ADC_SYNC_ERROR e;
225 std::stringstream expstr;
226 expstr << " after trying all in list. ";
227 expstr << " FEMB: " << int(iFEMB);
228 expstr << " sync: " << std::bitset<16>(adc_fifo_sync);
229 expstr << " phases tried: " << std::endl;
230 for (size_t iclk_phase = 0;iclk_phase < clk_phases.size();iclk_phase++)
231 {
232 expstr << " "
233 << std::hex << std::setfill ('0') << std::setw(4) << clk_phases[iclk_phase] << std::endl;
234 }
235 e.Append(expstr.str().c_str());
236 throw e;
237 } // else ContinueIfListOfFEMBClockPhasesDontSync
238 } // if ! TryFEMBPhases
239 uint16_t adc_fifo_sync = ( ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
240 std::cout << "FEMB " << int(iFEMB) << " Final ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
241 std::cout << "FEMB " << int(iFEMB) << " Final Clock Phases: "
242 << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT")
243 << std::hex << std::setfill ('0') << std::setw(2) << ReadFEMB(iFEMB,"ADC_ASIC_CLK_PHASE_SELECT_2")
244 << std::endl;
245
246 //time stamp reset
247 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
248 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
249
250 // These are all Jack's WIB addresses, need to figure out Dan's addresses for functionality
252 //Write(1, 0);
253 //Write(1, 0);
254 //Write(1, 2);
255 //Write(1, 2);
256 //Write(1, 0);
257 //Write(1, 0);
258 //
260 //Write(18, 0x8000);
261 //Write(18, 0x8000);
262
263 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
264}
265
275void WIB::ConfigFEMBFakeData(uint8_t iFEMB, uint8_t fake_mode, uint32_t fake_word, uint8_t femb_number,
276 std::vector<uint32_t> fake_samples, uint8_t start_frame_mode_sel, uint8_t start_frame_swap){
277
278 if (iFEMB < 1 || iFEMB > 4)
279 {
280 BUException::WIB_BAD_ARGS e;
281 std::stringstream expstr;
282 expstr << "ConfigFEMBFakeData: iFEMB should be between 1 and 4: "
283 << int(iFEMB);
284 e.Append(expstr.str().c_str());
285 throw e;
286 }
287 if (start_frame_mode_sel > 1 || start_frame_swap > 1)
288 {
289 BUException::WIB_BAD_ARGS e;
290 std::stringstream expstr;
291 expstr << "ConfigFEMBFakeData: start_frame_mode_sel and start_frame_swap must be 0 or 1";
292 e.Append(expstr.str().c_str());
293 throw e;
294 }
295 if (fake_mode == 1 && fake_word > 0xFFF)
296 {
297 BUException::WIB_BAD_ARGS e;
298 std::stringstream expstr;
299 expstr << "ConfigFEMBFakeData: fake_word must be only 12 bits i.e. <= 4095, is: "
300 << fake_word;
301 e.Append(expstr.str().c_str());
302 throw e;
303 }
304 if (fake_mode == 2 && fake_samples.size() != 256)
305 {
306 BUException::WIB_BAD_ARGS e;
307 std::stringstream expstr;
308 expstr << "ConfigFEMBFakeData: femb_samples must be 255 long, is: "
309 << fake_samples.size();
310 e.Append(expstr.str().c_str());
311 throw e;
312 }
313 if (fake_mode == 3 && femb_number > 0xF)
314 {
315 BUException::WIB_BAD_ARGS e;
316 std::stringstream expstr;
317 expstr << "ConfigFEMBFakeData: femb_number must be only 4 bits i.e. <= 15, is: "
318 << int(femb_number);
319 e.Append(expstr.str().c_str());
320 throw e;
321 }
322
323 // get this register so we can leave it in the state it started in
324 uint32_t slow_control_dnd = Read("SYSTEM.SLOW_CONTROL_DND");
325 Write("SYSTEM.SLOW_CONTROL_DND",1);
326
327 WriteFEMB(iFEMB, "REG_RESET", 1);
328 sleep(1);
329
330 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0);
331 sleep(1);
332
333 WriteFEMB(iFEMB, "START_FRAME_MODE_SELECT", start_frame_mode_sel);
334 sleep(1);
335 WriteFEMB(iFEMB, "START_FRAME_SWAP", start_frame_swap);
336 sleep(0.05);
337
338 //time stamp reset
339 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
340 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
341
342 // Now do the Fake data mode setup
343 if (fake_mode == 1)
344 {
345 WriteFEMB(iFEMB, "DATA_TEST_PATTERN", fake_word);
346 }
347 if (fake_mode == 2)
348 {
349 // Put waveform in FEMB registers
350 for (size_t iSample=0; iSample < 256; iSample++)
351 {
352 WriteFEMB(iFEMB,0x300+iSample,fake_samples.at(iSample));
353 sleep(0.005);
354 }
355 }
356 if (fake_mode == 3)
357 {
358 WriteFEMB(iFEMB, "FEMB_NUMBER", femb_number);
359 }
360 WriteFEMB(iFEMB, "FEMB_TST_SEL", fake_mode);
361
362 //time stamp reset
363 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
364 WriteFEMB(iFEMB, "TIME_STAMP_RESET", 1);
365
366 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9);
367
368 Write("SYSTEM.SLOW_CONTROL_DND",slow_control_dnd);
369}
370
375void WIB::SetupFEMBExtClock(uint8_t iFEMB){
376
377 //EXTERNAL CLOCK VARIABLES
378 uint32_t clk_period = 5; //ns
379 uint32_t clk_dis = 0; //0 --> enable, 1 disable
380 uint32_t d14_rst_oft = 0 / clk_period;
381 uint32_t d14_rst_wdt = (45 / clk_period ) ;
382 uint32_t d14_rst_inv = 1;
383 uint32_t d14_read_oft = 480 / clk_period;
384 uint32_t d14_read_wdt = 20 / clk_period;
385 uint32_t d14_read_inv = 1;
386 uint32_t d14_idxm_oft = 230 / clk_period;
387 uint32_t d14_idxm_wdt = 270 / clk_period;
388 uint32_t d14_idxm_inv = 0;
389 uint32_t d14_idxl_oft = 480 / clk_period;
390 uint32_t d14_idxl_wdt = 20 / clk_period;
391 uint32_t d14_idxl_inv = 0;
392 uint32_t d14_idl0_oft = 50 / clk_period;
393 uint32_t d14_idl0_wdt = (190 / clk_period ) -1;
394 uint32_t d14_idl1_oft = 480 / clk_period;
395 uint32_t d14_idl1_wdt = 20 / clk_period;
396 uint32_t d14_idl_inv = 0;
397
398 uint32_t d58_rst_oft = 0 / clk_period;
399 uint32_t d58_rst_wdt = (45 / clk_period );
400 uint32_t d58_rst_inv = 1;
401 uint32_t d58_read_oft = 480 / clk_period;
402 uint32_t d58_read_wdt = 20 / clk_period;
403 uint32_t d58_read_inv = 1;
404 uint32_t d58_idxm_oft = 230 / clk_period;
405 uint32_t d58_idxm_wdt = 270 / clk_period;
406 uint32_t d58_idxm_inv = 0;
407 uint32_t d58_idxl_oft = 480 / clk_period;
408 uint32_t d58_idxl_wdt = 20 / clk_period;
409 uint32_t d58_idxl_inv = 0;
410 uint32_t d58_idl0_oft = 50 / clk_period;
411 uint32_t d58_idl0_wdt = (190 / clk_period ) -1;
412 uint32_t d58_idl1_oft = 480 / clk_period;
413 uint32_t d58_idl1_wdt = 20 / clk_period;
414 uint32_t d58_idl_inv = 0;
415
416 //external clock phase -- Version 320
417 /*uint32_t d14_read_step = 7;
418 uint32_t d14_read_ud = 0;
419 uint32_t d14_idxm_step = 3;
420 uint32_t d14_idxm_ud = 0;
421 uint32_t d14_idxl_step = 1;
422 uint32_t d14_idxl_ud = 1;
423 uint32_t d14_idl0_step = 5;
424 uint32_t d14_idl0_ud = 0;
425 uint32_t d14_idl1_step = 2;
426 uint32_t d14_idl1_ud = 0;
427 uint32_t d14_phase_en = 1;
428
429 uint32_t d58_read_step = 1;
430 uint32_t d58_read_ud = 1;
431 uint32_t d58_idxm_step = 0;
432 uint32_t d58_idxm_ud = 0;
433 uint32_t d58_idxl_step = 5;
434 uint32_t d58_idxl_ud = 1;
435 uint32_t d58_idl0_step = 6;
436 uint32_t d58_idl0_ud = 0;
437 uint32_t d58_idl1_step = 5;
438 uint32_t d58_idl1_ud = 0;
439 uint32_t d58_phase_en = 1;*/
440 //Version 323
441 uint32_t d14_read_step = 11;
442 uint32_t d14_read_ud = 0;
443 uint32_t d14_idxm_step = 9;
444 uint32_t d14_idxm_ud = 0;
445 uint32_t d14_idxl_step = 7;
446 uint32_t d14_idxl_ud = 0;
447 uint32_t d14_idl0_step = 12;
448 uint32_t d14_idl0_ud = 0;
449 uint32_t d14_idl1_step = 10;
450 uint32_t d14_idl1_ud = 0;
451 uint32_t d14_phase_en = 1;
452
453 uint32_t d58_read_step = 0;
454 uint32_t d58_read_ud = 0;
455 uint32_t d58_idxm_step = 5;
456 uint32_t d58_idxm_ud = 0;
457 uint32_t d58_idxl_step = 4;
458 uint32_t d58_idxl_ud = 1;
459 uint32_t d58_idl0_step = 3;
460 uint32_t d58_idl0_ud = 0;
461 uint32_t d58_idl1_step = 4;
462 uint32_t d58_idl1_ud = 0;
463 uint32_t d58_phase_en = 1;
464
465 //END EXTERNAL CLOCK VARIABLES
466
467 //config timing
468 uint32_t d14_inv = (d14_rst_inv<<0) + (d14_read_inv<<1)+ (d14_idxm_inv<<2)+ (d14_idxl_inv<<3)+ (d14_idl_inv<<4);
469 uint32_t d58_inv = (d58_rst_inv<<0) + (d58_read_inv<<1)+ (d58_idxm_inv<<2)+ (d58_idxl_inv<<3)+ (d58_idl_inv<<4);
470 uint32_t d_inv = d58_inv + ( d14_inv<<5);
471
472 uint32_t addr_data;
473
474 addr_data = clk_dis + (d_inv << 16);
475 WriteFEMB(iFEMB, 21, addr_data);
476
477 addr_data = d58_rst_oft + (d14_rst_oft << 16);
478 WriteFEMB(iFEMB, 22, addr_data);
479
480 addr_data = d58_rst_wdt + (d14_rst_wdt << 16);
481 WriteFEMB(iFEMB, 23, addr_data);
482
483 addr_data = d58_read_oft + (d14_read_oft << 16);
484 WriteFEMB(iFEMB, 24, addr_data);
485
486 addr_data = d58_read_wdt + (d14_read_wdt << 16);
487 WriteFEMB(iFEMB, 25, addr_data);
488
489 addr_data = d58_idxm_oft + (d14_idxm_oft << 16);
490 WriteFEMB(iFEMB, 26, addr_data);
491
492 addr_data = d58_idxm_wdt + (d14_idxm_wdt << 16);
493 WriteFEMB(iFEMB, 27, addr_data);
494
495 addr_data = d58_idxl_oft + (d14_idxl_oft << 16);
496 WriteFEMB(iFEMB, 28, addr_data);
497
498 addr_data = d58_idxl_wdt + (d14_idxl_wdt << 16);
499 WriteFEMB(iFEMB, 29, addr_data);
500
501 addr_data = d58_idl0_oft + (d14_idl0_oft << 16);
502 WriteFEMB(iFEMB, 30, addr_data);
503
504 addr_data = d58_idl0_wdt + (d14_idl0_wdt << 16);
505 WriteFEMB(iFEMB, 31, addr_data);
506
507 addr_data = d58_idl1_oft + (d14_idl1_oft << 16);
508 WriteFEMB(iFEMB, 32, addr_data);
509
510 addr_data = d58_idl1_wdt + (d14_idl1_wdt << 16);
511 WriteFEMB(iFEMB, 33, addr_data);
512
513 //config phase
514 for(size_t i=0; i<4; i++)
515 {
516 addr_data = d14_read_step + (d14_idxm_step <<16);
517 WriteFEMB(iFEMB, 35, addr_data);
518
519 addr_data = d14_idxl_step + (d14_idl0_step <<16);
520 WriteFEMB(iFEMB, 36, addr_data);
521
522 d14_phase_en = d14_phase_en ^ 1;
523 uint32_t d14_ud = d14_read_ud + (d14_idxm_ud<<1) + (d14_idxl_ud<<2)+ (d14_idl0_ud<<3)+ (d14_idl1_ud<<4) + (d14_phase_en <<15);
524 addr_data = d14_idl1_step + (d14_ud<<16);
525 WriteFEMB(iFEMB, 37, addr_data);
526
527 addr_data = d58_read_step + (d58_idxm_step <<16);
528 WriteFEMB(iFEMB, 38, addr_data);
529
530 addr_data = d58_idxl_step + (d58_idl0_step <<16);
531 WriteFEMB(iFEMB, 39, addr_data);
532
533 d58_phase_en = d58_phase_en ^ 1;
534 uint32_t d58_ud = d58_read_ud + (d58_idxm_ud<<1) + (d58_idxl_ud<<2)+ (d58_idl0_ud<<3)+ (d58_idl1_ud<<4) + (d58_phase_en <<15);
535 addr_data = d58_idl1_step + (d58_ud <<16);
536 WriteFEMB(iFEMB, 40, addr_data);
537 }
538 sleep(0.05);
539}
540
541
550uint16_t WIB::SetupFEMBASICs(uint8_t iFEMB, std::vector<uint32_t> registerList){
551
552 const size_t REG_SPI_BASE = 512;
553 const size_t NREGS = 71;
554
555 if (registerList.size() != NREGS)
556 {
557 BUException::FEMB_FIRMWARE_VERSION_MISMATCH e;
558 std::stringstream expstr;
559 expstr << "SetupFEMBASICs expects : "
560 << NREGS
561 << " argument is: "
562 << registerList.size();
563 e.Append(expstr.str().c_str());
564 throw e;
565 }
566
567 //turn off HS data before register writes
568 WriteFEMB(iFEMB, "STREAM_EN", 0 );
569 sleep(2);
570
571 for (size_t iReg=0; iReg < NREGS; iReg++)
572 {
573 WriteFEMB(iFEMB, REG_SPI_BASE + iReg, registerList[iReg]);
574 }
575
577 //run the SPI programming
579
580 WriteFEMB(iFEMB, "ADC_ASIC_RESET", 1);
581 sleep(0.01);
582 WriteFEMB(iFEMB, "FE_ASIC_RESET", 1);
583 sleep(0.01);
584 WriteFEMB(iFEMB, "WRITE_ADC_ASIC_SPI", 1);
585 sleep(0.01);
586 WriteFEMB(iFEMB, "WRITE_ADC_ASIC_SPI", 1);
587 sleep(0.01);
588 WriteFEMB(iFEMB, "WRITE_FE_ASIC_SPI", 1);
589 sleep(0.01);
590 WriteFEMB(iFEMB, "WRITE_FE_ASIC_SPI", 1);
591 sleep(0.01);
592
593 uint16_t adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
596
597 //turn HS link back on
598 sleep(2);
599 WriteFEMB(iFEMB, "STREAM_EN", 1 );
600
601 return adc_sync_status;
602}
603
621uint16_t WIB::SetupFEMBASICs(uint8_t iFEMB, uint8_t gain, uint8_t shape, uint8_t highBaseline,
622 bool highLeakage, bool leakagex10, bool acCoupling, bool buffer, bool useExtClock,
623 uint8_t internalDACControl, uint8_t internalDACValue){
624
625 (void) buffer; // to make compiler not complain about unused arguments
626
627 if (gain > 3)
628 {
629 BUException::WIB_BAD_ARGS e;
630 std::stringstream expstr;
631 expstr << "gain should be between 0 and 3, but is: "
632 << int(gain);
633 e.Append(expstr.str().c_str());
634 throw e;
635 }
636 if (shape > 3)
637 {
638 BUException::WIB_BAD_ARGS e;
639 std::stringstream expstr;
640 expstr << "shape should be between 0 and 3, but is: "
641 << int(shape);
642 e.Append(expstr.str().c_str());
643 throw e;
644 }
645
646 const size_t REG_SPI_BASE_WRITE = 0x200; // 512
647 const size_t REG_SPI_BASE_READ = 0x250; // 592
648 // 0x48 registers total, 72 in hex
649
650 bool bypassOutputBuffer=true; // if false might blow up protoDUNE
651 bool useOutputMonitor=false; // if true might blow up protoDUNE
652 bool useCh16HighPassFilter=false;
653 bool monitorBandgapNotTemp=false;
654 bool monitorTempBandgapNotSignal=false;
655 bool useTestCapacitance = (bool) internalDACControl;
656
657 // Flip bits of gain
658 if (gain == 0x1) gain = 0x2;
659 else if (gain== 0x2) gain = 0x1;
660
661 // Shape
662 if (shape == 0x0) shape = 0x2; // 0.5 us
663 else if (shape == 0x1) shape = 0x0; // 1 us
664 else if (shape == 0x2) shape = 0x3; // 2 us
665 else if (shape == 0x3) shape = 0x1; // 3 us
666
667 FE_ASIC_reg_mapping fe_map;
668 if (highBaseline > 1)
669 {
670 // Set them all to high baseline
671 fe_map.set_board(useTestCapacitance,0,gain,shape,
672 useOutputMonitor,!bypassOutputBuffer,!highLeakage,
673 monitorBandgapNotTemp,monitorTempBandgapNotSignal,useCh16HighPassFilter,
674 leakagex10,acCoupling,internalDACControl,internalDACValue
675 );
676 // Now just set collection channels to low baseline
677 fe_map.set_collection_baseline(1);
678 }
679 else
680 {
681 fe_map.set_board(useTestCapacitance,~highBaseline,gain,shape,
682 useOutputMonitor,!bypassOutputBuffer,!highLeakage,
683 monitorBandgapNotTemp,monitorTempBandgapNotSignal,useCh16HighPassFilter,
684 leakagex10,acCoupling,internalDACControl,internalDACValue
685 );
686 }
687 ADC_ASIC_reg_mapping adc_map;
688 uint8_t offsetCurrentValue=0;
689 bool pcsr=0;
690 bool pdsr=0;
691 bool adcSleep=0;
692 bool useADCTestInput=0;
693 bool f4=0;
694 bool f5=0;
695 bool lsbCurrentStearingPartialNotFull=0;
696 bool clk0=0;
697 if (useExtClock) clk0=1;
698 bool clk1=0;
699 bool freq=0;
700 bool enableOffsetCurrent=0;
701 bool f0=0;
702 bool f1=0;
703 bool f2=0;
704 bool f3=0;
705 adc_map.set_board(offsetCurrentValue, pcsr, pdsr,
706 adcSleep, useADCTestInput, f4, f5,
707 lsbCurrentStearingPartialNotFull,0,0,
708 0,0,0,
709 clk0,clk1,freq,
710 enableOffsetCurrent,f0,f1,
711 f2,f3);
713 map.set_board(fe_map,adc_map);
714 map.get_regs();
715 const std::vector<uint32_t> regs = map.get_regs();
716 const size_t nRegs = regs.size();
717
718 uint16_t adc_sync_status = 0xFFFF;
719
720 for(unsigned iSPIWrite=0; iSPIWrite < 2; iSPIWrite++)
721 {
722 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0 ); // Turn off STREAM_EN and ADC_DATA_EN
723 sleep(0.1);
724
725 std::cout << "ASIC SPI Write Registers..." << std::endl;
726 for (size_t iReg=0; iReg<nRegs; iReg++)
727 {
728 WriteFEMB(iFEMB,REG_SPI_BASE_WRITE+iReg,regs[iReg]);
729 sleep(0.01);
730 }
731
732
733 //run the SPI programming
734 sleep(0.1);
735 WriteFEMB(iFEMB, "WRITE_ASIC_SPI", 1);
736 sleep(0.1);
737
738 if (iSPIWrite == 1)
739 {
740 // Now check readback
741 bool spi_mismatch = false;
742 for (unsigned iSPIRead = 0; iSPIRead < 2; iSPIRead++)
743 {
744 std::cout << "ASIC SPI Readback..." << std::endl;
745 std::vector<uint32_t> regsReadback(nRegs);
746 for (size_t iReg=0; iReg<nRegs; iReg++)
747 {
748 uint32_t regReadback = ReadFEMB(iFEMB,REG_SPI_BASE_READ+iReg);
749 regsReadback[iReg] = regReadback;
750 sleep(0.01);
751 }
752
753 bool verbose = false;
754 if (verbose) std::cout << "ASIC SPI register number, write val, read val:" << std::endl;
755 spi_mismatch = false;
756 for (size_t iReg=0; iReg<nRegs; iReg++)
757 {
758 if (verbose)
759 {
760 std::cout << std::dec << std::setfill (' ') << std::setw(3) << iReg
761 << " "
762 << std::hex << std::setfill ('0') << std::setw(8) << regs[iReg]
763 << " "
764 << std::hex << std::setfill ('0') << std::setw(8) << regsReadback[iReg]
765 << std::endl;
766 } // if verbose
767 if (regs[iReg] != regsReadback[iReg])
768 {
769 spi_mismatch = true;
770 size_t asicFailNum = 0;
771 if (iReg > 0) asicFailNum = (iReg-1) / 9;
772 std::cout << "FE-ADC ASIC " << asicFailNum << " SPI faled" << std::endl;
773 } // if regs don't match
774 } // for iReg
775 if (!spi_mismatch) break;
776 } // for iSPIRead
777 if(spi_mismatch)
778 {
780 {
781 std::cout << "FEMB ASIC SPI readback mismatch--problems communicating with ASICs for FEMB: " << int(iFEMB) << std::endl;
782 }
783 else
784 {
785 BUException::FEMB_SPI_READBACK_MISMATCH e;
786 std::stringstream expstr;
787 expstr << " for FEMB: " << int(iFEMB);
788 e.Append(expstr.str().c_str());
789 throw e;
790 }
791 } // if spi_mismatch
792 } // if iSPIWrite == 1
793 sleep(0.1);
794
795 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
796 sleep(0.05);
797 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
798 sleep(0.1);
799
800 adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
801
802 // The real sync check can happen here in Shanshan's code
803
804 } // for iSPIWrite
805
806 return adc_sync_status;
807}
808
809uint16_t WIB::SetupASICPulserBits(uint8_t iFEMB){
810
811 const uint32_t REG_SPI_BASE_WRITE = 0x200; // 512
812 const uint32_t REG_SPI_BASE_READ = 0x250; // 592
813 uint16_t adc_sync_status = 0xFFFF;
814
815
816
817 size_t nASICs = 8;
818 unsigned nTries = 3;
819 for(unsigned iSPIWrite=0; iSPIWrite < nTries; iSPIWrite++)
820 {
821 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 0 ); // Turn off STREAM_EN and ADC_DATA_EN
822 sleep(0.1);
823
824 std::cout << "ASIC SPI Write Registers..." << std::endl;
825
826 uint8_t value = 0x2;
827 uint8_t mask = 0x3;
828 uint8_t pos = 24;
829 std::vector<uint32_t> vals(nASICs);
830 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
831 {
832 uint32_t address = (REG_SPI_BASE_WRITE + 9*iASIC + 8);
833 std::cout <<"Writing address " << std::hex << std::setfill ('0') << std::setw(8) << address << std::endl;
834 //WriteFEMBBits(iFEMB, address, pos, mask, value);
835
836 //Bit-wise calculation of register val
837 uint32_t shiftVal = value & mask;
838 uint32_t regMask = (mask << pos);
839 uint32_t initVal = ReadFEMB(iFEMB,address);
840 uint32_t newVal = ( (initVal & ~(regMask)) | (shiftVal << pos) );
841 vals[iASIC] = newVal;
842 WriteFEMB(iFEMB,address,newVal);
843
844 sleep(0.01);
845 }
846
847
848
849 //run the SPI programming
850 sleep(0.1);
851 WriteFEMB(iFEMB, "WRITE_ASIC_SPI", 1);
852 sleep(0.1);
853
854 if (iSPIWrite == nTries - 1)
855 {
856 // Now check readback
857 bool spi_mismatch = false;
858 for (unsigned iSPIRead = 0; iSPIRead < 2; iSPIRead++)
859 {
860 std::cout << "ASIC SPI Readback..." << std::endl;
861 std::vector<uint32_t> regsReadback(nASICs);
862 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
863 {
864 uint32_t regReadback = ReadFEMB(iFEMB, (REG_SPI_BASE_READ + 9*iASIC + 8));
865 regsReadback[iASIC] = regReadback;
866 sleep(0.01);
867 }
868
869 std::cout << "ASIC SPI register number, write val, read val:" << std::endl;
870 spi_mismatch = false;
871 for (size_t iASIC=0; iASIC<nASICs; iASIC++)
872 {
873 std::cout << std::dec << std::setfill (' ') << std::setw(3) << iASIC
874 << " "
875 << std::hex << std::setfill ('0') << std::setw(8) << vals[iASIC]
876 << " "
877 << std::hex << std::setfill ('0') << std::setw(8) << regsReadback[iASIC]
878 << std::endl;
879 if (vals[iASIC] != regsReadback[iASIC])
880 {
881 spi_mismatch = true;
882 size_t asicFailNum = 0;
883 if (iASIC > 0) asicFailNum = (iASIC-1);
884 std::cout << "FE-ADC ASIC " << asicFailNum << " SPI faled" << std::endl;
885 } // if regs don't match
886 } // for iReg
887 if (!spi_mismatch) break;
888 } // for iSPIRead
889 if(spi_mismatch)
890 {
891 BUException::WIB_ERROR e;
892 e.Append("SPI programming failure");
893 throw e;
894 } // if spi_mismatch
895 } // if iSPIWrite == 1
896 sleep(0.1);
897
898 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
899 sleep(0.05);
900 WriteFEMB(iFEMB, "STREAM_AND_ADC_DATA_EN", 9 ); // STREAM_EN and ADC_DATA_EN
901 sleep(0.1);
902
903 adc_sync_status = (uint16_t) ReadFEMB(iFEMB, "ADC_ASIC_SYNC_STATUS");
904
905 // The real sync check can happen here in Shanshan's code
906
907 } // for iSPIWrite
908
909 return adc_sync_status;
910}
911
912void WIB::SetupFPGAPulser(uint8_t iFEMB, uint8_t dac_val){
913 std::cout << "FEMB " << int(iFEMB) << " Configuring FPGA pulser with DAC value: " << int(dac_val) << std::endl;
914
915 WriteFEMB(iFEMB, "ASIC_TP_EN", 0 );
916 WriteFEMB(iFEMB, "FPGA_TP_EN", 1 );
917
918 WriteFEMB(iFEMB, "DAC_SELECT", 1 );
919 WriteFEMB(iFEMB, "TEST_PULSE_AMPLITUDE", dac_val );
920 WriteFEMB(iFEMB, "TEST_PULSE_DELAY", 219 );
921 WriteFEMB(iFEMB, "TEST_PULSE_PERIOD", 497 );
922
923 WriteFEMB(iFEMB, "INT_TP_EN", 0 );
924 WriteFEMB(iFEMB, "EXT_TP_EN", 1 );
925
926}
927
928void WIB::SetupInternalPulser(uint8_t iFEMB){
929 std::cout << "FEMB " << int(iFEMB) << " Configuring internal pulser" << std::endl;
930
931 WriteFEMB(iFEMB, "DAC_SELECT", 0 );
932 WriteFEMB(iFEMB, "TEST_PULSE_AMPLITUDE", 0 );
933 WriteFEMB(iFEMB, "TEST_PULSE_DELAY", 219 );
934 WriteFEMB(iFEMB, "TEST_PULSE_PERIOD", 497 );
935
936 WriteFEMB(iFEMB, "INT_TP_EN", 0 );
937 WriteFEMB(iFEMB, "EXT_TP_EN", 1 );
938
939 WriteFEMB(iFEMB, "FPGA_TP_EN", 0 );
940 WriteFEMB(iFEMB, "ASIC_TP_EN", 1 );
941}
942
943void WIB::WriteFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data){
944
945 uint32_t clk_phase_data0 = (clk_phase_data >> 8) & 0xFF;
946 uint32_t clk_phase_data1 = clk_phase_data & 0xFF;
947
948 uint32_t data;
949 uint32_t read_back;
950 int count = 0;
951 sleep(0.001);
952 for(int i = 0; i < 10; ++i){
953
954 data = (~(clk_phase_data0)) & 0xFF;
955 WriteFEMB(iFEMB, 6, data);
956 sleep(0.001);
957 read_back = ReadFEMB(iFEMB, 6);
958 sleep(0.001);
959 if ( (read_back & 0xFF) == ((~(clk_phase_data0)) & 0xFF) ){
960 break;
961 }
962 else{
963 count++;
964 }
965 }
966 if( count >= 10){
967 std::cout << "readback val for 0 is different from written data "<< std::endl;
968 //Put in system exit?
969 }
970 count = 0;
971 for(int i = 0; i < 10; ++i){
972
973 data = (~(clk_phase_data1)) & 0xFF;
974 WriteFEMB(iFEMB, 15, data);
975 sleep(0.001);
976 read_back = ReadFEMB(iFEMB, 15);
977 sleep(0.001);
978 if ( (read_back & 0xFF) == ((~(clk_phase_data1)) & 0xFF) ){
979 break;
980 }
981 else{
982 count++;
983 }
984 }
985 if( count >= 10){
986 std::cout << "readback val for 1 is different from written data "<< std::endl;
987 //Put in system exit?
988 }
989 count = 0;
990 for(int i = 0; i < 10; ++i){
991
992 data = clk_phase_data0;
993 WriteFEMB(iFEMB, 6, data);
994 sleep(0.001);
995
996 read_back = ReadFEMB(iFEMB,6);
997 sleep(0.001);
998 if( (read_back & 0xFF) == ((clk_phase_data0) & 0xFF) ){
999 break;
1000 }
1001 else{
1002 count++;
1003 }
1004 }
1005 if( count >= 10){
1006 std::cout << "readback val for 2 is different from written data "<< std::endl;
1007 //Put in system exit?
1008 }
1009 count = 0;
1010 for(int i = 0; i < 10; ++i){
1011
1012 data = clk_phase_data1;
1013 WriteFEMB(iFEMB, 15, data);
1014 sleep(0.001);
1015
1016 read_back = ReadFEMB(iFEMB,6);
1017 sleep(0.001);
1018 if( (read_back & 0xFF) == ((clk_phase_data1) & 0xFF) ){
1019 break;
1020 }
1021 else{
1022 count++;
1023 }
1024 }
1025 if( count >= 10){
1026 std::cout << "readback val for 3 is different from written data "<< std::endl;
1027 //Put in system exit?
1028 }
1029}
1030
1031bool WIB::TryFEMBPhases(uint8_t iFEMB, std::vector<uint16_t> phases){
1032
1033 size_t nPhases = phases.size();
1034 std::cout << "Searching " << nPhases << " sets of phases:" << std::endl;
1035 for(size_t ip = 0; ip < nPhases; ++ip){
1036 uint16_t phase = phases.at(ip);
1037 std::cout << "Set " << ip << std::endl;
1038 std::cout << "\t Phase: " << std::hex << std::setw(4) << phase << std::endl;
1039
1040 WriteFEMBPhase(iFEMB,phase);
1041 //If it made it this far, it found the correct readback val
1042 sleep(0.001);
1043 uint32_t adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1044 sleep(0.001);
1045 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1046 sleep(0.001);
1047
1048 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1049
1050 if (adc_fifo_sync == 0){
1051 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO synced" << std::endl;
1052 std::cout << " phase: " << std::hex << std::setw(4) << std::setfill('0') << (uint32_t) phase << std::endl;
1053 return true;
1054 }
1055 }
1056
1057 //std::cout << "Could not find successful phase" << std::endl;
1058 return false;
1059}
1060
1061bool WIB::HuntFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data_start){
1062 uint32_t clk_phase_data0 = (clk_phase_data_start >> 8) & 0xFF;
1063 uint32_t clk_phase_data1 = clk_phase_data_start & 0xFF;
1064 uint32_t adc_fifo_sync = 1;
1065
1066 uint32_t a_cs[8] = {
1067 0xc000, 0x3000, 0x0c00, 0x0300,
1068 0x00c0, 0x0030, 0x000c, 0x0003};
1069
1070 uint32_t a_mark[8] = {
1071 0x80, 0x40, 0x20, 0x10,
1072 0x08, 0x04, 0x02, 0x01};
1073
1074 uint32_t a_cnt[8] = {
1075 0,0,0,0,
1076 0,0,0,0};
1077
1078 while (adc_fifo_sync){
1079 sleep(0.001);
1080 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1081 sleep(0.001);
1082 adc_fifo_sync = (ReadFEMB(iFEMB, 6) & 0xFFFF0000) >> 16;
1083 sleep(0.001);
1084
1085 std::cout << "FEMB " << int(iFEMB) << " ADC FIFO sync: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1086
1087 if (adc_fifo_sync == 0){
1088 std::cout << "FEMB " << int(iFEMB) << " Successful SPI config and ADC FIFO synced" << std::endl;
1089 //std::cout << " ADC_ASIC_CLK_PHASE_SELECT: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data0 << std::endl;
1090 //std::cout << " ADC_ASIC_CLK_PHASE_SELECT_2: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data1 << std::endl;
1091 std::cout << " phase: " << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data0;
1092 std::cout << std::hex << std::setw(2) << std::setfill('0') << clk_phase_data1 << std::endl;
1093 return true;
1094 }
1095 else{
1096 std::cout << "ERROR: sync not zero: " << std::bitset<16>(adc_fifo_sync) << std::endl;
1097 for(int i = 0; i < 8; ++i){
1098 uint32_t a = adc_fifo_sync & a_cs[i];
1099 uint32_t a_mark_xor = 0;
1100 if (a != 0){
1101 a_cnt[i]++;
1102 a_mark_xor = a_mark[i] ^ 0xFF;
1103 if (a_cnt[i] == 1 || a_cnt[i] == 3){
1104 clk_phase_data0 = ((clk_phase_data0 & a_mark[i]) ^ a_mark[i]) + (clk_phase_data0 & a_mark_xor);
1105 }
1106 else if (a_cnt[i] == 2 || a_cnt[i] == 4){
1107 clk_phase_data1 = ((clk_phase_data1 & a_mark[i]) ^ a_mark[i]) + (clk_phase_data1 & a_mark_xor);
1108 }
1109 else if (a_cnt[i] >= 5){
1110 return false;
1111 }
1112 }
1113 else{
1114 continue;
1115 }
1116 }
1117 uint16_t clk_phase_to_write=0;
1118 clk_phase_to_write |= (clk_phase_data0 & 0xFF) << 8;
1119 clk_phase_to_write |= clk_phase_data1;
1120 WriteFEMBPhase(iFEMB,clk_phase_to_write);
1121 }
1122 }
1123 return false;
1124}
1125
1126void WIB::ConfigFEMBMode(uint8_t iFEMB, uint32_t pls_cs, uint32_t dac_sel, uint32_t fpga_dac, uint32_t asic_dac, uint32_t mon_cs = 0){
1127 uint32_t tp_sel;
1128 if (mon_cs == 0){
1129 tp_sel = ((asic_dac & 0x01) << 1) + (fpga_dac & 0x01) + ((dac_sel&0x1)<<8);
1130 }
1131 else{
1132 tp_sel = 0x402;
1133 }
1134 WriteFEMB(iFEMB, 16, tp_sel & 0x0000FFFF);
1135 WriteFEMB(iFEMB, 18, 0x11);
1136 uint32_t pls_cs_value = 0x00;
1137 if (pls_cs == 0) pls_cs_value = 0x11;//disable all
1138 else if (pls_cs == 1) pls_cs_value = 0x10;//internal pls
1139 else if (pls_cs == 2) pls_cs_value = 0x01;//external pls
1140
1141 WriteFEMB(iFEMB, 18, pls_cs_value);
1142}
1143
1147
1151
1155
#define sleep(x)
Definition WIB_FEMB.cpp:12
void set_board(uint8_t d=0, uint8_t pcsr=0, uint8_t pdsr=0, uint8_t slp=0, uint8_t tstin=0, uint8_t f4=0, uint8_t f5=0, uint8_t slsb=0, uint8_t res4=0, uint8_t res3=0, uint8_t res2=0, uint8_t res1=0, uint8_t res0=0, uint8_t clk0=0, uint8_t clk1=0, uint8_t frqc=0, uint8_t engr=0, uint8_t f0=0, uint8_t f1=0, uint8_t f2=0, uint8_t f3=0)
std::vector< uint32_t > get_regs() const
void set_board(const FE_ASIC_reg_mapping &fe_map, const ADC_ASIC_reg_mapping &adc_map)
void set_collection_baseline(uint8_t snc)
void set_board(uint8_t sts=0, uint8_t snc=0, uint8_t sg=0, uint8_t st=0, uint8_t smn=0, uint8_t sdf=0, uint8_t slk0=0, uint8_t stb1=0, uint8_t stb=0, uint8_t s16=0, uint8_t slk1=0, uint8_t sdc=0, uint8_t swdac=0, uint8_t dac=0)
void WriteFEMB(int iFEMB, uint16_t address, uint32_t value)
Definition WIBBase.cpp:174
uint32_t Read(uint16_t address)
Definition WIBBase.cpp:119
void Write(uint16_t address, uint32_t value)
Definition WIBBase.cpp:132
uint32_t ReadFEMB(int iFEMB, uint16_t address)
Definition WIBBase.cpp:155
bool TryFEMBPhases(uint8_t iFEMB, std::vector< uint16_t > phases)
bool ContinueOnFEMBRegReadError
Definition WIB.hh:237
void ConfigFEMB(uint8_t iFEMB, std::vector< uint32_t > fe_config, std::vector< uint16_t > clk_phases, uint8_t pls_mode=0, uint8_t pls_dac_val=0, uint8_t start_frame_mode_sel=1, uint8_t start_frame_swap=1)
Setup FEMB in real or pulser data mode.
Definition WIB_FEMB.cpp:37
void SetContinueOnFEMBSyncError(bool enable)
bool ContinueOnFEMBSyncError
Definition WIB.hh:239
void ConfigFEMBMode(uint8_t iFEMB, uint32_t pls_cs, uint32_t dac_sel, uint32_t fpga_dac, uint32_t asic_dac, uint32_t mon_cs)
void SetupFEMBExtClock(uint8_t iFEMB)
Setup FEMB External Clock.
Definition WIB_FEMB.cpp:375
void ConfigFEMBFakeData(uint8_t iFEMB, uint8_t fake_mode, uint32_t fake_word, uint8_t femb_number, std::vector< uint32_t > fake_samples, uint8_t start_frame_mode_sel=1, uint8_t start_frame_swap=1)
Setup FEMB in fake data mode.
Definition WIB_FEMB.cpp:275
bool ContinueOnFEMBSPIError
Definition WIB.hh:238
bool HuntFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data_start)
void SetContinueIfListOfFEMBClockPhasesDontSync(bool enable)
void SetupInternalPulser(uint8_t iFEMB)
Definition WIB_FEMB.cpp:928
uint16_t SetupASICPulserBits(uint8_t iFEMB)
Definition WIB_FEMB.cpp:809
bool ContinueIfListOfFEMBClockPhasesDontSync
Definition WIB.hh:240
void SetContinueOnFEMBSPIError(bool enable)
void SetContinueOnFEMBRegReadError(bool enable)
void SetupFPGAPulser(uint8_t iFEMB, uint8_t dac_val)
Definition WIB_FEMB.cpp:912
uint16_t SetupFEMBASICs(uint8_t iFEMB, uint8_t gain, uint8_t shape, uint8_t highBaseline, bool highLeakage, bool leakagex10, bool acCoupling, bool buffer, bool useExtClock, uint8_t internalDACControl, uint8_t internalDACValue)
Setup FEMB ASICs.
Definition WIB_FEMB.cpp:621
void WriteFEMBPhase(uint8_t iFEMB, uint16_t clk_phase_data)
Definition WIB_FEMB.cpp:943