Rev 197 | Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
195 | f9daq | 1 | /******************************************************************** |
2 | DRS.h, S.Ritt, M. Schneebeli - PSI |
||
3 | |||
4 | $Id: DRS.h 21309 2014-04-11 14:51:29Z ritt $ |
||
5 | |||
6 | ********************************************************************/ |
||
7 | #ifndef DRS_H |
||
8 | #define DRS_H |
||
9 | #include <stdio.h> |
||
10 | #include <string.h> |
||
11 | #include "averager.h" |
||
12 | |||
13 | #ifdef HAVE_LIBUSB |
||
14 | # ifndef HAVE_USB |
||
15 | # define HAVE_USB |
||
16 | # endif |
||
17 | #endif |
||
18 | |||
19 | #ifdef HAVE_USB |
||
20 | # include "musbstd.h" |
||
21 | #endif // HAVE_USB |
||
22 | |||
23 | #ifdef HAVE_VME |
||
24 | # include <mvmestd.h> |
||
25 | #endif // HAVE_VME |
||
26 | |||
27 | /* disable "deprecated" warning */ |
||
28 | #ifdef _MSC_VER |
||
29 | #pragma warning(disable: 4996) |
||
30 | #endif |
||
31 | |||
32 | #ifndef NULL |
||
33 | #define NULL 0 |
||
34 | #endif |
||
35 | |||
36 | int drs_kbhit(); |
||
37 | unsigned int millitime(); |
||
38 | |||
39 | /* transport mode */ |
||
40 | #define TR_VME 1 |
||
41 | #define TR_USB 2 |
||
42 | #define TR_USB2 3 |
||
43 | |||
44 | /* address types */ |
||
45 | #ifndef T_CTRL |
||
46 | #define T_CTRL 1 |
||
47 | #define T_STATUS 2 |
||
48 | #define T_RAM 3 |
||
49 | #define T_FIFO 4 |
||
50 | #endif |
||
51 | |||
52 | /*---- Register addresses ------------------------------------------*/ |
||
53 | |||
54 | #define REG_CTRL 0x00000 /* 32 bit control reg */ |
||
55 | #define REG_DAC_OFS 0x00004 |
||
56 | #define REG_DAC0 0x00004 |
||
57 | #define REG_DAC1 0x00006 |
||
58 | #define REG_DAC2 0x00008 |
||
59 | #define REG_DAC3 0x0000A |
||
60 | #define REG_DAC4 0x0000C |
||
61 | #define REG_DAC5 0x0000E |
||
62 | #define REG_DAC6 0x00010 |
||
63 | #define REG_DAC7 0x00012 |
||
64 | #define REG_CHANNEL_CONFIG 0x00014 // low byte |
||
65 | #define REG_CONFIG 0x00014 // high byte |
||
66 | #define REG_CHANNEL_MODE 0x00016 |
||
67 | #define REG_ADCCLK_PHASE 0x00016 |
||
68 | #define REG_FREQ_SET_HI 0x00018 // DRS2 |
||
69 | #define REG_FREQ_SET_LO 0x0001A // DRS2 |
||
70 | #define REG_TRG_DELAY 0x00018 // DRS4 |
||
71 | #define REG_FREQ_SET 0x0001A // DRS4 |
||
72 | #define REG_TRIG_DELAY 0x0001C |
||
73 | #define REG_LMK_MSB 0x0001C // DRS4 Mezz |
||
74 | #define REG_CALIB_TIMING 0x0001E // DRS2 |
||
75 | #define REG_EEPROM_PAGE_EVAL 0x0001E // DRS4 Eval |
||
76 | #define REG_EEPROM_PAGE_MEZZ 0x0001A // DRS4 Mezz |
||
77 | #define REG_TRG_CONFIG 0x0001C // DRS4 Eval4 |
||
78 | #define REG_LMK_LSB 0x0001E // DRS4 Mezz |
||
79 | #define REG_WARMUP 0x00020 // DRS4 Mezz |
||
80 | #define REG_COOLDOWN 0x00022 // DRS4 Mezz |
||
81 | #define REG_READ_POINTER 0x00026 // DRS4 Mezz |
||
82 | |||
83 | #define REG_MAGIC 0x00000 |
||
84 | #define REG_BOARD_TYPE 0x00002 |
||
85 | #define REG_STATUS 0x00004 |
||
86 | #define REG_RDAC_OFS 0x0000E |
||
87 | #define REG_RDAC0 0x00008 |
||
88 | #define REG_STOP_CELL0 0x00008 |
||
89 | #define REG_RDAC1 0x0000A |
||
90 | #define REG_STOP_CELL1 0x0000A |
||
91 | #define REG_RDAC2 0x0000C |
||
92 | #define REG_STOP_CELL2 0x0000C |
||
93 | #define REG_RDAC3 0x0000E |
||
94 | #define REG_STOP_CELL3 0x0000E |
||
95 | #define REG_RDAC4 0x00000 |
||
96 | #define REG_RDAC5 0x00002 |
||
97 | #define REG_STOP_WSR0 0x00010 |
||
98 | #define REG_STOP_WSR1 0x00011 |
||
99 | #define REG_STOP_WSR2 0x00012 |
||
100 | #define REG_STOP_WSR3 0x00013 |
||
101 | #define REG_RDAC6 0x00014 |
||
102 | #define REG_RDAC7 0x00016 |
||
103 | #define REG_EVENTS_IN_FIFO 0x00018 |
||
104 | #define REG_EVENT_COUNT 0x0001A |
||
105 | #define REG_FREQ1 0x0001C |
||
106 | #define REG_FREQ2 0x0001E |
||
107 | #define REG_WRITE_POINTER 0x0001E |
||
108 | #define REG_TEMPERATURE 0x00020 |
||
109 | #define REG_TRIGGER_BUS 0x00022 |
||
110 | #define REG_SERIAL_BOARD 0x00024 |
||
111 | #define REG_VERSION_FW 0x00026 |
||
112 | #define REG_SCALER0 0x00028 |
||
113 | #define REG_SCALER1 0x0002C |
||
114 | #define REG_SCALER2 0x00030 |
||
115 | #define REG_SCALER3 0x00034 |
||
116 | #define REG_SCALER4 0x00038 |
||
117 | #define REG_SCALER5 0x0003C |
||
118 | |||
119 | /*---- Control register bit definitions ----------------------------*/ |
||
120 | |||
121 | #define BIT_START_TRIG (1<<0) // write a "1" to start domino wave |
||
122 | #define BIT_REINIT_TRIG (1<<1) // write a "1" to stop & reset DRS |
||
123 | #define BIT_SOFT_TRIG (1<<2) // write a "1" to stop and read data to RAM |
||
124 | #define BIT_EEPROM_WRITE_TRIG (1<<3) // write a "1" to write into serial EEPROM |
||
125 | #define BIT_EEPROM_READ_TRIG (1<<4) // write a "1" to read from serial EEPROM |
||
126 | #define BIT_MULTI_BUFFER (1<<16) // Use multi buffering when "1" |
||
127 | #define BIT_DMODE (1<<17) // (*DRS2*) 0: single shot, 1: circular |
||
128 | #define BIT_ADC_ACTIVE (1<<17) // (*DRS4*) 0: stop ADC when running, 1: ADC always clocked |
||
129 | #define BIT_LED (1<<18) // 1=on, 0=blink during readout |
||
130 | #define BIT_TCAL_EN (1<<19) // switch on (1) / off (0) for 33 MHz calib signal |
||
131 | #define BIT_TCAL_SOURCE (1<<20) |
||
132 | #define BIT_REFCLK_SOURCE (1<<20) |
||
133 | #define BIT_FREQ_AUTO_ADJ (1<<21) // DRS2/3 |
||
134 | #define BIT_TRANSP_MODE (1<<21) // DRS4 |
||
135 | #define BIT_ENABLE_TRIGGER1 (1<<22) // External LEMO/FP/TRBUS trigger |
||
136 | #define BIT_LONG_START_PULSE (1<<23) // (*DRS2*) 0:short start pulse (>0.8GHz), 1:long start pulse (<0.8GHz) |
||
137 | #define BIT_READOUT_MODE (1<<23) // (*DRS3*,*DRS4*) 0:start from first bin, 1:start from domino stop |
||
138 | #define BIT_DELAYED_START (1<<24) // DRS2: start domino wave 400ns after soft trigger, used for waveform |
||
139 | // generator startup |
||
140 | #define BIT_NEG_TRIGGER (1<<24) // DRS4: use high-to-low trigger if set |
||
141 | #define BIT_ACAL_EN (1<<25) // connect DRS to inputs (0) or to DAC6 (1) |
||
142 | #define BIT_TRIGGER_DELAYED (1<<26) // select delayed trigger from trigger bus |
||
143 | #define BIT_ADCCLK_INVERT (1<<26) // invert ADC clock |
||
144 | #define BIT_REFCLK_EXT (1<<26) // use external MMCX CLKIN refclk |
||
145 | #define BIT_DACTIVE (1<<27) // keep domino wave running during readout |
||
146 | #define BIT_STANDBY_MODE (1<<28) // put chip in standby mode |
||
147 | #define BIT_TR_SOURCE1 (1<<29) // trigger source selection bits |
||
148 | #define BIT_DECIMATION (1<<29) // drop all odd samples (DRS4 mezz.) |
||
149 | #define BIT_TR_SOURCE2 (1<<30) // trigger source selection bits |
||
150 | #define BIT_ENABLE_TRIGGER2 (1<<31) // analog threshold (internal) trigger |
||
151 | |||
152 | /* DRS4 configuration register bit definitions */ |
||
153 | #define BIT_CONFIG_DMODE (1<<8) // 0: single shot, 1: circular |
||
154 | #define BIT_CONFIG_PLLEN (1<<9) // write a "1" to enable the internal PLL |
||
155 | #define BIT_CONFIG_WSRLOOP (1<<10) // write a "1" to connect WSROUT to WSRIN internally |
||
156 | |||
157 | /*---- Status register bit definitions -----------------------------*/ |
||
158 | |||
159 | #define BIT_RUNNING (1<<0) // one if domino wave running or readout in progress |
||
160 | #define BIT_NEW_FREQ1 (1<<1) // one if new frequency measurement available |
||
161 | #define BIT_NEW_FREQ2 (1<<2) |
||
162 | #define BIT_PLL_LOCKED0 (1<<1) // 1 if PLL has locked (DRS4 evaluation board only) |
||
163 | #define BIT_PLL_LOCKED1 (1<<2) // 1 if PLL DRS4 B has locked (DRS4 mezzanine board only) |
||
164 | #define BIT_PLL_LOCKED2 (1<<3) // 1 if PLL DRS4 C has locked (DRS4 mezzanine board only) |
||
165 | #define BIT_PLL_LOCKED3 (1<<4) // 1 if PLL DRS4 D has locked (DRS4 mezzanine board only) |
||
166 | #define BIT_SERIAL_BUSY (1<<5) // 1 if EEPROM operation in progress |
||
167 | #define BIT_LMK_LOCKED (1<<6) // 1 if PLL of LMK chip has locked (DRS4 mezzanine board only) |
||
168 | #define BIT_2048_MODE (1<<7) // 1 if 2048-bin mode has been soldered |
||
169 | |||
170 | enum DRSBoardConstants { |
||
171 | kNumberOfChannelsMax = 10, |
||
172 | kNumberOfCalibChannelsV3 = 10, |
||
173 | kNumberOfCalibChannelsV4 = 8, |
||
174 | kNumberOfBins = 1024, |
||
175 | kNumberOfChipsMax = 4, |
||
176 | kFrequencyCacheSize = 10, |
||
177 | kBSplineOrder = 4, |
||
178 | kPreCaliculatedBSplines = 1000, |
||
179 | kPreCaliculatedBSplineGroups = 5, |
||
180 | kNumberOfADCBins = 4096, |
||
181 | kBSplineXMinOffset = 20, |
||
182 | kMaxNumberOfClockCycles = 100, |
||
183 | }; |
||
184 | |||
185 | enum DRSErrorCodes { |
||
186 | kSuccess = 0, |
||
187 | kInvalidTriggerSignal = -1, |
||
188 | kWrongChannelOrChip = -2, |
||
189 | kInvalidTransport = -3, |
||
190 | kZeroSuppression = -4, |
||
191 | kWaveNotAvailable = -5 |
||
192 | }; |
||
193 | |||
194 | /*---- callback class ----*/ |
||
195 | |||
196 | class DRSCallback |
||
197 | { |
||
198 | public: |
||
199 | virtual void Progress(int value) = 0; |
||
200 | virtual ~DRSCallback() {}; |
||
201 | }; |
||
202 | |||
203 | /*------------------------*/ |
||
204 | |||
205 | class DRSBoard; |
||
206 | |||
207 | class ResponseCalibration { |
||
208 | protected: |
||
209 | |||
210 | class CalibrationData { |
||
211 | public: |
||
212 | class CalibrationDataChannel { |
||
213 | public: |
||
214 | unsigned char fLimitGroup[kNumberOfBins]; //! |
||
215 | float fMin[kNumberOfBins]; //! |
||
216 | float fRange[kNumberOfBins]; //! |
||
217 | short fOffset[kNumberOfBins]; //! |
||
218 | short fGain[kNumberOfBins]; //! |
||
219 | unsigned short fOffsetADC[kNumberOfBins]; //! |
||
220 | short *fData[kNumberOfBins]; //! |
||
221 | unsigned char *fLookUp[kNumberOfBins]; //! |
||
222 | unsigned short fLookUpOffset[kNumberOfBins]; //! |
||
223 | unsigned char fNumberOfLookUpPoints[kNumberOfBins]; //! |
||
224 | float *fTempData; //! |
||
225 | |||
226 | private: |
||
227 | CalibrationDataChannel(const CalibrationDataChannel &c); // not implemented |
||
228 | CalibrationDataChannel &operator=(const CalibrationDataChannel &rhs); // not implemented |
||
229 | |||
230 | public: |
||
231 | CalibrationDataChannel(int numberOfGridPoints) |
||
232 | :fTempData(new float[numberOfGridPoints]) { |
||
233 | int i; |
||
234 | for (i = 0; i < kNumberOfBins; i++) { |
||
235 | fData[i] = new short[numberOfGridPoints]; |
||
236 | } |
||
237 | memset(fLimitGroup, 0, sizeof(fLimitGroup)); |
||
238 | memset(fMin, 0, sizeof(fMin)); |
||
239 | memset(fRange, 0, sizeof(fRange)); |
||
240 | memset(fOffset, 0, sizeof(fOffset)); |
||
241 | memset(fGain, 0, sizeof(fGain)); |
||
242 | memset(fOffsetADC, 0, sizeof(fOffsetADC)); |
||
243 | memset(fLookUp, 0, sizeof(fLookUp)); |
||
244 | memset(fLookUpOffset, 0, sizeof(fLookUpOffset)); |
||
245 | memset(fNumberOfLookUpPoints, 0, sizeof(fNumberOfLookUpPoints)); |
||
246 | } |
||
247 | ~CalibrationDataChannel() { |
||
248 | int i; |
||
249 | delete fTempData; |
||
250 | for (i = 0; i < kNumberOfBins; i++) { |
||
251 | delete fData[i]; |
||
252 | delete fLookUp[i]; |
||
253 | } |
||
254 | } |
||
255 | }; |
||
256 | |||
257 | bool fRead; //! |
||
258 | CalibrationDataChannel *fChannel[10]; //! |
||
259 | unsigned char fNumberOfGridPoints; //! |
||
260 | int fHasOffsetCalibration; //! |
||
261 | float fStartTemperature; //! |
||
262 | float fEndTemperature; //! |
||
263 | int *fBSplineOffsetLookUp[kNumberOfADCBins]; //! |
||
264 | float **fBSplineLookUp[kNumberOfADCBins]; //! |
||
265 | float fMin; //! |
||
266 | float fMax; //! |
||
267 | unsigned char fNumberOfLimitGroups; //! |
||
268 | static float fIntRevers[2 * kBSplineOrder - 2]; |
||
269 | |||
270 | private: |
||
271 | CalibrationData(const CalibrationData &c); // not implemented |
||
272 | CalibrationData &operator=(const CalibrationData &rhs); // not implemented |
||
273 | |||
274 | public: |
||
275 | CalibrationData(int numberOfGridPoints); |
||
276 | ~CalibrationData(); |
||
277 | static int CalculateBSpline(int nGrid, float value, float *bsplines); |
||
278 | void PreCalculateBSpline(); |
||
279 | void DeletePreCalculatedBSpline(); |
||
280 | }; |
||
281 | |||
282 | // General Fields |
||
283 | DRSBoard *fBoard; |
||
284 | |||
285 | double fPrecision; |
||
286 | |||
287 | // Fields for creating the Calibration |
||
288 | bool fInitialized; |
||
289 | bool fRecorded; |
||
290 | bool fFitted; |
||
291 | bool fOffset; |
||
292 | bool fCalibrationValid[2]; |
||
293 | |||
294 | int fNumberOfPointsLowVolt; |
||
295 | int fNumberOfPoints; |
||
296 | int fNumberOfMode2Bins; |
||
297 | int fNumberOfSamples; |
||
298 | int fNumberOfGridPoints; |
||
299 | int fNumberOfXConstPoints; |
||
300 | int fNumberOfXConstGridPoints; |
||
301 | double fTriggerFrequency; |
||
302 | int fShowStatistics; |
||
303 | FILE *fCalibFile; |
||
304 | |||
305 | int fCurrentLowVoltPoint; |
||
306 | int fCurrentPoint; |
||
307 | int fCurrentSample; |
||
308 | int fCurrentFitChannel; |
||
309 | int fCurrentFitBin; |
||
310 | |||
311 | float *fResponseX[10][kNumberOfBins]; |
||
312 | float *fResponseY; |
||
313 | unsigned short **fWaveFormMode3[10]; |
||
314 | unsigned short **fWaveFormMode2[10]; |
||
315 | short **fWaveFormOffset[10]; |
||
316 | unsigned short **fWaveFormOffsetADC[10]; |
||
317 | unsigned short *fSamples; |
||
318 | int *fSampleUsed; |
||
319 | |||
320 | float *fPntX[2]; |
||
321 | float *fPntY[2]; |
||
322 | float *fUValues[2]; |
||
323 | float *fRes[kNumberOfBins]; |
||
324 | float *fResX[kNumberOfBins]; |
||
325 | |||
326 | double *fXXFit; |
||
327 | double *fYYFit; |
||
328 | double *fWWFit; |
||
329 | double *fYYFitRes; |
||
330 | double *fYYSave; |
||
331 | double *fXXSave; |
||
332 | double fGainMin; |
||
333 | double fGainMax; |
||
334 | |||
335 | float **fStatisticsApprox; |
||
336 | float **fStatisticsApproxExt; |
||
337 | |||
338 | // Fields for applying the Calibration |
||
339 | CalibrationData *fCalibrationData[kNumberOfChipsMax]; |
||
340 | |||
341 | private: |
||
342 | ResponseCalibration(const ResponseCalibration &c); // not implemented |
||
343 | ResponseCalibration &operator=(const ResponseCalibration &rhs); // not implemented |
||
344 | |||
345 | public: |
||
346 | ResponseCalibration(DRSBoard* board); |
||
347 | ~ResponseCalibration(); |
||
348 | |||
349 | void SetCalibrationParameters(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, |
||
350 | int numberOfSamples, int numberOfGridPoints, int numberOfXConstPoints, |
||
351 | int numberOfXConstGridPoints, double triggerFrequency, int showStatistics = 0); |
||
352 | void ResetCalibration(); |
||
353 | bool RecordCalibrationPoints(int chipNumber); |
||
354 | bool RecordCalibrationPointsV3(int chipNumber); |
||
355 | bool RecordCalibrationPointsV4(int chipNumber); |
||
356 | bool FitCalibrationPoints(int chipNumber); |
||
357 | bool FitCalibrationPointsV3(int chipNumber); |
||
358 | bool FitCalibrationPointsV4(int chipNumber); |
||
359 | bool OffsetCalibration(int chipNumber); |
||
360 | bool OffsetCalibrationV3(int chipNumber); |
||
361 | bool OffsetCalibrationV4(int chipNumber); |
||
362 | double GetTemperature(unsigned int chipIndex); |
||
363 | |||
364 | bool WriteCalibration(unsigned int chipIndex); |
||
365 | bool WriteCalibrationV3(unsigned int chipIndex); |
||
366 | bool WriteCalibrationV4(unsigned int chipIndex); |
||
367 | bool ReadCalibration(unsigned int chipIndex); |
||
368 | bool ReadCalibrationV3(unsigned int chipIndex); |
||
369 | bool ReadCalibrationV4(unsigned int chipIndex); |
||
370 | bool Calibrate(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, short *uWaveform, |
||
371 | int triggerCell, float threshold, bool offsetCalib); |
||
372 | bool SubtractADCOffset(unsigned int chipIndex, unsigned int channel, unsigned short *adcWaveform, |
||
373 | unsigned short *adcCalibratedWaveform, unsigned short newBaseLevel); |
||
374 | bool IsRead(int chipIndex) const { return fCalibrationValid[chipIndex]; } |
||
375 | double GetPrecision() const { return fPrecision; }; |
||
376 | |||
377 | double GetOffsetAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fOffset[bin]; }; |
||
378 | double GetGainAt(int chip,int chn,int bin) const { return fCalibrationData[chip]->fChannel[chn]->fGain[bin]; }; |
||
379 | double GetMeasPointXAt(int ip) const { return fXXSave[ip]; }; |
||
380 | double GetMeasPointYAt(int ip) const { return fYYSave[ip]; }; |
||
381 | |||
382 | protected: |
||
383 | void InitFields(int numberOfPointsLowVolt, int numberOfPoints, int numberOfMode2Bins, int numberOfSamples, |
||
384 | int numberOfGridPoints, int numberOfXConstPoints, int numberOfXConstGridPoints, |
||
385 | double triggerFrequency, int showStatistics); |
||
386 | void DeleteFields(); |
||
387 | void CalibrationTrigger(int mode, double voltage); |
||
388 | void CalibrationStart(double voltage); |
||
389 | |||
390 | static float GetValue(float *coefficients, float u, int n); |
||
391 | static int Approx(float *p, float *uu, int np, int nu, float *coef); |
||
392 | static void LeastSquaresAccumulation(float **matrix, int nb, int *ip, int *ir, int mt, int jt); |
||
393 | static int LeastSquaresSolving(float **matrix, int nb, int ip, int ir, float *x, int n); |
||
394 | static void Housholder(int lpivot, int l1, int m, float **u, int iU1, int iU2, float *up, float **c, int iC1, |
||
395 | int iC2, int ice, int ncv); |
||
396 | |||
397 | static int MakeDir(const char *path); |
||
398 | static void Average(int method,float *samples,int numberOfSamples,float &mean,float &error,float sigmaBoundary); |
||
399 | }; |
||
400 | |||
401 | |||
402 | class DRSBoard { |
||
403 | protected: |
||
404 | class TimeData { |
||
405 | public: |
||
406 | class FrequencyData { |
||
407 | public: |
||
408 | int fFrequency; |
||
409 | double fBin[kNumberOfBins]; |
||
410 | }; |
||
411 | |||
412 | enum { |
||
413 | kMaxNumberOfFrequencies = 4000 |
||
414 | }; |
||
415 | int fChip; |
||
416 | int fNumberOfFrequencies; |
||
417 | FrequencyData *fFrequency[kMaxNumberOfFrequencies]; |
||
418 | |||
419 | private: |
||
420 | TimeData(const TimeData &c); // not implemented |
||
421 | TimeData &operator=(const TimeData &rhs); // not implemented |
||
422 | |||
423 | public: |
||
424 | TimeData() |
||
425 | :fChip(0) |
||
426 | ,fNumberOfFrequencies(0) { |
||
427 | } |
||
428 | ~TimeData() { |
||
429 | int i; |
||
430 | for (i = 0; i < fNumberOfFrequencies; i++) { |
||
431 | delete fFrequency[i]; |
||
432 | } |
||
433 | } |
||
434 | }; |
||
435 | |||
436 | public: |
||
437 | // DAC channels (CMC Version 1 : DAC_COFSA,DAC_COFSB,DAC_DRA,DAC_DSA,DAC_TLEVEL,DAC_ACALIB,DAC_DSB,DAC_DRB) |
||
438 | unsigned int fDAC_COFSA; |
||
439 | unsigned int fDAC_COFSB; |
||
440 | unsigned int fDAC_DRA; |
||
441 | unsigned int fDAC_DSA; |
||
442 | unsigned int fDAC_TLEVEL; |
||
443 | unsigned int fDAC_ACALIB; |
||
444 | unsigned int fDAC_DSB; |
||
445 | unsigned int fDAC_DRB; |
||
446 | // DAC channels (CMC Version 2+3 : DAC_COFS,DAC_DSA,DAC_DSB,DAC_TLEVEL,DAC_ADCOFS,DAC_CLKOFS,DAC_ACALIB) |
||
447 | unsigned int fDAC_COFS; |
||
448 | unsigned int fDAC_ADCOFS; |
||
449 | unsigned int fDAC_CLKOFS; |
||
450 | // DAC channels (CMC Version 4 : DAC_ROFS_1,DAC_DSA,DAC_DSB,DAC_ROFS_2,DAC_ADCOFS,DAC_ACALIB,DAC_INOFS,DAC_BIAS) |
||
451 | unsigned int fDAC_ROFS_1; |
||
452 | unsigned int fDAC_ROFS_2; |
||
453 | unsigned int fDAC_INOFS; |
||
454 | unsigned int fDAC_BIAS; |
||
455 | // DAC channels (USB EVAL1 (fBoardType 5) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS) |
||
456 | // DAC channels (USB EVAL3 (fBoardType 7) : DAC_ROFS_1,DAC_CMOFS,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL,DAC_ONOFS) |
||
457 | unsigned int fDAC_CMOFS; |
||
458 | unsigned int fDAC_CALN; |
||
459 | unsigned int fDAC_CALP; |
||
460 | unsigned int fDAC_ONOFS; |
||
461 | // DAC channels (DRS4 MEZZ1 (fBoardType 6) : DAC_ONOFS,DAC_CMOFSP,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_CMOFSN,DAC_ROFS_1) |
||
462 | unsigned int fDAC_CMOFSP; |
||
463 | unsigned int fDAC_CMOFSN; |
||
464 | // DAC channels (DRS4 EVAL4 (fBoardType 8) : DAC_ONOFS,DAC_TLEVEL4,DAC_CALN,DAC_CALP,DAC_BIAS,DAC_TLEVEL1,DAC_TLEVEL2,DAC_TLEVEL3) |
||
465 | unsigned int fDAC_TLEVEL1; |
||
466 | unsigned int fDAC_TLEVEL2; |
||
467 | unsigned int fDAC_TLEVEL3; |
||
468 | unsigned int fDAC_TLEVEL4; |
||
469 | |||
470 | protected: |
||
471 | // Fields for DRS |
||
472 | int fDRSType; |
||
473 | int fBoardType; |
||
474 | int fNumberOfChips; |
||
475 | int fNumberOfChannels; |
||
476 | int fRequiredFirmwareVersion; |
||
477 | int fFirmwareVersion; |
||
478 | int fBoardSerialNumber; |
||
479 | int fHasMultiBuffer; |
||
480 | unsigned int fTransport; |
||
481 | unsigned int fCtrlBits; |
||
482 | int fNumberOfReadoutChannels; |
||
483 | int fReadoutChannelConfig; |
||
484 | int fADCClkPhase; |
||
485 | bool fADCClkInvert; |
||
486 | double fExternalClockFrequency; |
||
487 | #ifdef HAVE_USB |
||
488 | MUSB_INTERFACE *fUsbInterface; |
||
489 | #endif |
||
490 | #ifdef HAVE_VME |
||
491 | MVME_INTERFACE *fVmeInterface; |
||
492 | mvme_addr_t fBaseAddress; |
||
493 | #endif |
||
494 | int fSlotNumber; |
||
495 | double fNominalFrequency; |
||
496 | double fTrueFrequency; |
||
497 | double fTCALFrequency; |
||
498 | double fRefClock; |
||
499 | int fMultiBuffer; |
||
500 | int fDominoMode; |
||
501 | int fDominoActive; |
||
502 | int fADCActive; |
||
503 | int fChannelConfig; |
||
504 | int fChannelCascading; |
||
505 | int fChannelDepth; |
||
506 | int fWSRLoop; |
||
507 | int fReadoutMode; |
||
508 | unsigned short fReadPointer; |
||
509 | int fNMultiBuffer; |
||
510 | int fTriggerEnable1; |
||
511 | int fTriggerEnable2; |
||
512 | int fTriggerSource; |
||
513 | int fTriggerDelay; |
||
514 | double fTriggerDelayNs; |
||
515 | int fSyncDelay; |
||
516 | int fDelayedStart; |
||
517 | int fTranspMode; |
||
518 | int fDecimation; |
||
519 | unsigned short fStopCell[4]; |
||
520 | unsigned char fStopWSR[4]; |
||
521 | unsigned short fTriggerBus; |
||
522 | double fROFS; |
||
523 | double fRange; |
||
524 | double fCommonMode; |
||
525 | int fAcalMode; |
||
526 | int fbkAcalMode; |
||
527 | double fAcalVolt; |
||
528 | double fbkAcalVolt; |
||
529 | int fTcalFreq; |
||
530 | int fbkTcalFreq; |
||
531 | int fTcalLevel; |
||
532 | int fbkTcalLevel; |
||
533 | int fTcalPhase; |
||
534 | int fTcalSource; |
||
535 | int fRefclk; |
||
536 | |||
537 | unsigned char fWaveforms[kNumberOfChipsMax * kNumberOfChannelsMax * 2 * kNumberOfBins]; |
||
538 | |||
539 | // Fields for Calibration |
||
540 | int fMaxChips; |
||
541 | char fCalibDirectory[1000]; |
||
542 | |||
543 | // Fields for Response Calibration old method |
||
544 | ResponseCalibration *fResponseCalibration; |
||
545 | |||
546 | // Fields for Calibration new method |
||
547 | bool fVoltageCalibrationValid; |
||
548 | double fCellCalibratedRange; |
||
549 | double fCellCalibratedTemperature; |
||
550 | unsigned short fCellOffset[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
551 | unsigned short fCellOffset2[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
552 | double fCellGain[kNumberOfChipsMax * kNumberOfChannelsMax][kNumberOfBins]; |
||
553 | |||
554 | double fTimingCalibratedFrequency; |
||
555 | double fCellDT[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins]; |
||
556 | |||
557 | // Fields for Time Calibration |
||
558 | TimeData **fTimeData; |
||
559 | int fNumberOfTimeData; |
||
560 | |||
561 | // General debugging flag |
||
562 | int fDebug; |
||
563 | |||
564 | // Fields for wave transfer |
||
565 | bool fWaveTransferred[kNumberOfChipsMax * kNumberOfChannelsMax]; |
||
566 | |||
567 | // Waveform Rotation |
||
568 | int fTriggerStartBin; // Start Bin of the trigger |
||
569 | |||
570 | private: |
||
571 | DRSBoard(const DRSBoard &c); // not implemented |
||
572 | DRSBoard &operator=(const DRSBoard &rhs); // not implemented |
||
573 | |||
574 | public: |
||
575 | // Public Methods |
||
576 | #ifdef HAVE_USB |
||
577 | DRSBoard(MUSB_INTERFACE * musb_interface, int usb_slot); |
||
578 | #endif |
||
579 | #ifdef HAVE_VME |
||
580 | DRSBoard(MVME_INTERFACE * mvme_interface, mvme_addr_t base_address, int slot_number); |
||
581 | |||
582 | MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; |
||
583 | #endif |
||
584 | ~DRSBoard(); |
||
585 | |||
586 | int SetBoardSerialNumber(unsigned short serialNumber); |
||
587 | int GetBoardSerialNumber() const { return fBoardSerialNumber; } |
||
588 | int HasMultiBuffer() const { return fHasMultiBuffer; } |
||
589 | int GetFirmwareVersion() const { return fFirmwareVersion; } |
||
590 | int GetRequiredFirmwareVersion() const { return fRequiredFirmwareVersion; } |
||
591 | int GetDRSType() const { return fDRSType; } |
||
592 | int GetBoardType() const { return fBoardType; } |
||
593 | int GetNumberOfChips() const { return fNumberOfChips; } |
||
594 | // channel : Flash ADC index |
||
595 | // readout channel : VME readout index |
||
596 | // input : Input on board |
||
597 | int GetNumberOfChannels() const { return fNumberOfChannels; } |
||
598 | int GetChannelDepth() const { return fChannelDepth; } |
||
599 | int GetChannelCascading() const { return fChannelCascading; } |
||
600 | inline int GetNumberOfReadoutChannels() const; |
||
601 | inline int GetWaveformBufferSize() const; |
||
602 | inline int GetNumberOfInputs() const; |
||
603 | inline int GetNumberOfCalibInputs() const; |
||
604 | inline int GetClockChannel() const; |
||
605 | inline int GetTriggerChannel() const; |
||
606 | inline int GetClockInput() const { return Channel2Input(GetClockChannel()); } |
||
607 | inline int GetTriggerInput() const { return fDRSType < 4 ? Channel2Input(GetTriggerChannel()) : -1; } |
||
608 | inline int Channel2Input(int channel) const; |
||
609 | inline int Channel2ReadoutChannel(int channel) const; |
||
610 | inline int Input2Channel(int input, int ind = 0) const; |
||
611 | inline int Input2ReadoutChannel(int input, int ind = 0) const; |
||
612 | inline int ReadoutChannel2Channel(int readout) const; |
||
613 | inline int ReadoutChannel2Input(int readout) const; |
||
614 | |||
615 | inline bool IsCalibChannel(int ch) const; |
||
616 | inline bool IsCalibInput(int input) const; |
||
617 | int GetSlotNumber() const { return fSlotNumber; } |
||
618 | int InitFPGA(void); |
||
619 | int Write(int type, unsigned int addr, void *data, int size); |
||
620 | int Read(int type, void *data, unsigned int addr, int size); |
||
621 | int GetTransport() const { return fTransport; } |
||
622 | void RegisterTest(void); |
||
623 | int RAMTest(int flag); |
||
624 | int ChipTest(); |
||
625 | unsigned int GetCtrlReg(void); |
||
626 | unsigned short GetConfigReg(void); |
||
627 | unsigned int GetStatusReg(void); |
||
628 | void SetLED(int state); |
||
629 | int SetChannelConfig(int firstChannel, int lastChannel, int nConfigChannels); |
||
630 | void SetADCClkPhase(int phase, bool invert); |
||
631 | void SetWarmup(unsigned int ticks); |
||
632 | void SetCooldown(unsigned int ticks); |
||
633 | int GetReadoutChannelConfig() { return fReadoutChannelConfig; } |
||
634 | void SetNumberOfChannels(int nChannels); |
||
635 | int EnableTrigger(int flag1, int flag2); |
||
636 | int GetTriggerEnable(int i) { return i?fTriggerEnable2:fTriggerEnable1; } |
||
637 | int SetDelayedTrigger(int flag); |
||
638 | int SetTriggerDelayPercent(int delay); |
||
639 | int SetTriggerDelayNs(int delay); |
||
640 | int GetTriggerDelay() { return fTriggerDelay; } |
||
641 | double GetTriggerDelayNs() { return fTriggerDelayNs; } |
||
642 | int SetSyncDelay(int ticks); |
||
643 | int SetTriggerLevel(double value); |
||
644 | int SetIndividualTriggerLevel(int channel, double voltage); |
||
645 | int SetTriggerPolarity(bool negative); |
||
646 | int SetTriggerSource(int source); |
||
647 | int GetTriggerSource() { return fTriggerSource; } |
||
648 | int SetDelayedStart(int flag); |
||
649 | int SetTranspMode(int flag); |
||
650 | int SetStandbyMode(int flag); |
||
651 | int SetDecimation(int flag); |
||
652 | int GetDecimation() { return fDecimation; } |
||
653 | int IsBusy(void); |
||
654 | int IsEventAvailable(void); |
||
655 | int IsPLLLocked(void); |
||
656 | int IsLMKLocked(void); |
||
657 | int IsNewFreq(unsigned char chipIndex); |
||
658 | int SetDAC(unsigned char channel, double value); |
||
659 | int ReadDAC(unsigned char channel, double *value); |
||
660 | int GetRegulationDAC(double *value); |
||
661 | int StartDomino(); |
||
662 | int StartClearCycle(); |
||
663 | int FinishClearCycle(); |
||
664 | int Reinit(); |
||
665 | int Init(); |
||
666 | void SetDebug(int debug) { fDebug = debug; } |
||
667 | int Debug() { return fDebug; } |
||
668 | int SetDominoMode(unsigned char mode); |
||
669 | int SetDominoActive(unsigned char mode); |
||
670 | int SetReadoutMode(unsigned char mode); |
||
671 | int SoftTrigger(void); |
||
672 | int ReadFrequency(unsigned char chipIndex, double *f); |
||
673 | int SetFrequency(double freq, bool wait); |
||
674 | double VoltToFreq(double volt); |
||
675 | double FreqToVolt(double freq); |
||
676 | double GetNominalFrequency() const { return fNominalFrequency; } |
||
677 | double GetTrueFrequency(); |
||
678 | int RegulateFrequency(double freq); |
||
679 | int SetExternalClockFrequency(double frequencyMHz); |
||
680 | double GetExternalClockFrequency(); |
||
681 | int SetMultiBuffer(int flag); |
||
682 | int IsMultiBuffer() { return fMultiBuffer; } |
||
683 | void ResetMultiBuffer(void); |
||
684 | int GetMultiBufferRP(void); |
||
685 | int SetMultiBufferRP(unsigned short rp); |
||
686 | int GetMultiBufferWP(void); |
||
687 | void IncrementMultiBufferRP(void); |
||
688 | void SetVoltageOffset(double offset1, double offset2); |
||
689 | int SetInputRange(double center); |
||
690 | double GetInputRange(void) { return fRange; } |
||
691 | double GetCalibratedInputRange(void) { return fCellCalibratedRange; } |
||
692 | double GetCalibratedTemperature(void) { return fCellCalibratedTemperature; } |
||
693 | double GetCalibratedFrequency(void) { return fTimingCalibratedFrequency; } |
||
694 | int TransferWaves(int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); |
||
695 | int TransferWaves(unsigned char *p, int numberOfChannels = kNumberOfChipsMax * kNumberOfChannelsMax); |
||
696 | int TransferWaves(int firstChannel, int lastChannel); |
||
697 | int TransferWaves(unsigned char *p, int firstChannel, int lastChannel); |
||
698 | int DecodeWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, |
||
699 | unsigned short *waveform); |
||
700 | int DecodeWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform); |
||
701 | int GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, short *waveform, |
||
702 | bool responseCalib = false, int triggerCell = -1, int wsr = -1, bool adjustToClock = false, |
||
703 | float threshold = 0, bool offsetCalib = true); |
||
704 | int GetWave(unsigned char *waveforms, unsigned int chipIndex, unsigned char channel, float *waveform, |
||
705 | bool responseCalib = false, int triggerCell = -1, int wsr = -1, bool adjustToClock = false, |
||
706 | float threshold = 0, bool offsetCalib = true); |
||
707 | int GetWave(unsigned int chipIndex, unsigned char channel, short *waveform, bool responseCalib = false, |
||
708 | int triggerCell = -1, int wsr = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); |
||
709 | int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform, bool responseCalib, |
||
710 | int triggerCell = -1, int wsr = -1, bool adjustToClock = false, float threshold = 0, bool offsetCalib = true); |
||
711 | int GetWave(unsigned int chipIndex, unsigned char channel, float *waveform); |
||
712 | int GetRawWave(unsigned int chipIndex, unsigned char channel, unsigned short *waveform, bool adjustToClock = false); |
||
713 | int GetRawWave(unsigned char *waveforms,unsigned int chipIndex, unsigned char channel, |
||
714 | unsigned short *waveform, bool adjustToClock = false); |
||
715 | bool IsTimingCalibrationValid(void); |
||
716 | bool IsVoltageCalibrationValid(void) { return fVoltageCalibrationValid; } |
||
717 | int GetTime(unsigned int chipIndex, int channelIndex, double freq, int tc, float *time, bool tcalibrated=true, bool rotated=true); |
||
718 | int GetTime(unsigned int chipIndex, int channelIndex, int tc, float *time, bool tcalibrated=true, bool rotated=true); |
||
719 | int GetTimeCalibration(unsigned int chipIndex, int channelIndex, int mode, float *time, bool force=false); |
||
720 | int GetTriggerCell(unsigned int chipIndex); |
||
721 | int GetStopCell(unsigned int chipIndex); |
||
722 | unsigned char GetStopWSR(unsigned int chipIndex); |
||
723 | int GetTriggerCell(unsigned char *waveforms,unsigned int chipIndex); |
||
724 | void TestDAC(int channel); |
||
725 | void MeasureSpeed(); |
||
726 | void InteractSpeed(); |
||
727 | void MonitorFrequency(); |
||
728 | int TestShift(int n); |
||
729 | int EnableAcal(int mode, double voltage); |
||
730 | int GetAcalMode() { return fAcalMode; } |
||
731 | double GetAcalVolt() { return fAcalVolt; } |
||
732 | int EnableTcal(int freq, int level=0, int phase=0); |
||
733 | int SelectClockSource(int source); |
||
734 | int SetRefclk(int source); |
||
735 | int GetRefclk() { return fRefclk; } |
||
736 | int GetTcalFreq() { return fTcalFreq; } |
||
737 | int GetTcalLevel() { return fTcalLevel; } |
||
738 | int GetTcalPhase() { return fTcalPhase; } |
||
739 | int GetTcalSource() { return fTcalSource; } |
||
740 | int SetCalibVoltage(double value); |
||
741 | int SetCalibTiming(int t1, int t2); |
||
742 | double GetTemperature(); |
||
743 | int Is2048ModeCapable(); |
||
744 | int GetTriggerBus(); |
||
745 | unsigned int GetScaler(int channel); |
||
746 | int ReadEEPROM(unsigned short page, void *buffer, int size); |
||
747 | int WriteEEPROM(unsigned short page, void *buffer, int size); |
||
748 | bool HasCorrectFirmware(); |
||
749 | int ConfigureLMK(double sampFreq, bool freqChange, int calFreq, int calPhase); |
||
750 | |||
751 | bool InitTimeCalibration(unsigned int chipIndex); |
||
752 | void SetCalibrationDirectory(const char *calibrationDirectoryPath); |
||
753 | void GetCalibrationDirectory(char *calibrationDirectoryPath); |
||
754 | |||
755 | ResponseCalibration *GetResponseCalibration() const { return fResponseCalibration; } |
||
756 | |||
757 | double GetPrecision() const { return fResponseCalibration ? fResponseCalibration->GetPrecision() : 0.1; } |
||
758 | int CalibrateWaveform(unsigned int chipIndex, unsigned char channel, unsigned short *adcWaveform, |
||
759 | short *waveform, bool responseCalib, int triggerCell, bool adjustToClock, |
||
760 | float threshold, bool offsetCalib); |
||
761 | |||
762 | static void LinearRegression(double *x, double *y, int n, double *a, double *b); |
||
763 | |||
764 | void ReadSingleWaveform(int nChips, int nChan, |
||
765 | unsigned short wfu[kNumberOfChipsMax][kNumberOfChannelsMax][kNumberOfBins], bool rotated); |
||
766 | int AverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); |
||
767 | int RobustAverageWaveforms(DRSCallback *pcb, int chipIndex, int nChan, int prog1, int prog2, unsigned short *awf, int n, bool rotated); |
||
768 | int CalibrateVolt(DRSCallback *pcb); |
||
769 | int AnalyzePeriod(Averager *ave, int iIter, int nIter, int channel, float wf[kNumberOfBins], int tCell, double cellDV[kNumberOfBins], double cellDT[kNumberOfBins]); |
||
770 | int AnalyzeSlope(Averager *ave, int iIter, int nIter, int channel, float wf[kNumberOfBins], int tCell, double cellDV[kNumberOfBins], double cellDT[kNumberOfBins]); |
||
771 | int CalibrateTiming(DRSCallback *pcb); |
||
772 | static void RemoveSymmetricSpikes(short **wf, int nwf, |
||
773 | short diffThreshold, int spikeWidth, |
||
774 | short maxPeakToPeak, short spikeVoltage, |
||
775 | int nTimeRegionThreshold); |
||
776 | protected: |
||
777 | // Protected Methods |
||
778 | void ConstructBoard(); |
||
779 | void ReadSerialNumber(); |
||
780 | void ReadCalibration(void); |
||
781 | |||
782 | TimeData *GetTimeCalibration(unsigned int chipIndex, bool reinit = false); |
||
783 | |||
784 | int GetStretchedTime(float *time, float *measurement, int numberOfMeasurements, float period); |
||
785 | }; |
||
786 | |||
787 | int DRSBoard::GetNumberOfReadoutChannels() const |
||
788 | { |
||
789 | return (fDRSType == 4 && fReadoutChannelConfig == 4) ? 5 : fNumberOfChannels; |
||
790 | } |
||
791 | |||
792 | int DRSBoard::GetWaveformBufferSize() const |
||
793 | { |
||
794 | int nbin=0; |
||
795 | if (fDRSType < 4) { |
||
796 | nbin = fNumberOfChips * fNumberOfChannels * kNumberOfBins; |
||
797 | } else { |
||
798 | if (fBoardType == 6) { |
||
799 | if (fDecimation) { |
||
800 | nbin = fNumberOfChips * (4 * kNumberOfBins + kNumberOfBins / 2); |
||
801 | } else { |
||
802 | nbin = fNumberOfChips * 5 * kNumberOfBins; |
||
803 | } |
||
804 | } else if (fBoardType == 7 || fBoardType == 8 || fBoardType == 9) |
||
805 | nbin = fNumberOfChips * fNumberOfChannels * kNumberOfBins; |
||
806 | } |
||
807 | return nbin * static_cast<int>(sizeof(short int)); |
||
808 | } |
||
809 | |||
810 | int DRSBoard::GetNumberOfInputs() const |
||
811 | { |
||
812 | // return number of input channels excluding clock and trigger channels. |
||
813 | if (fDRSType < 4) { |
||
814 | return fNumberOfChannels - 2; |
||
815 | } else { |
||
816 | return fNumberOfChannels / 2; |
||
817 | } |
||
818 | } |
||
819 | int DRSBoard::GetNumberOfCalibInputs() const |
||
820 | { |
||
821 | return (fDRSType < 4) ? 2 : 1; |
||
822 | } |
||
823 | int DRSBoard::GetClockChannel() const |
||
824 | { |
||
825 | return fDRSType < 4 ? 9 : 8; |
||
826 | } |
||
827 | int DRSBoard::GetTriggerChannel() const |
||
828 | { |
||
829 | return fDRSType < 4 ? 8 : -1; |
||
830 | } |
||
831 | |||
832 | int DRSBoard::Channel2Input(int channel) const |
||
833 | { |
||
834 | return (fDRSType < 4) ? channel : channel / 2; |
||
835 | } |
||
836 | int DRSBoard::Channel2ReadoutChannel(int channel) const |
||
837 | { |
||
838 | if (fDRSType < 4) { |
||
839 | return channel; |
||
840 | } else { |
||
841 | if (fReadoutChannelConfig == 4) { |
||
842 | return channel / 2; |
||
843 | } else { |
||
844 | return channel; |
||
845 | } |
||
846 | } |
||
847 | } |
||
848 | int DRSBoard::Input2Channel(int input, int ind) const |
||
849 | { |
||
850 | if (fChannelCascading == 1) { |
||
851 | return (fDRSType < 4) ? input : (input * 2 + ind); |
||
852 | } else { |
||
853 | if (input == 4) { // clock |
||
854 | return 8; |
||
855 | } else { |
||
856 | return input; |
||
857 | } |
||
858 | } |
||
859 | } |
||
860 | int DRSBoard::Input2ReadoutChannel(int input, int ind) const |
||
861 | { |
||
862 | if (fDRSType < 4) { |
||
863 | return input; |
||
864 | } else { |
||
865 | if (fReadoutChannelConfig == 4) { |
||
866 | return input; |
||
867 | } else { |
||
868 | return (input * 2 + ind); |
||
869 | } |
||
870 | } |
||
871 | } |
||
872 | int DRSBoard::ReadoutChannel2Channel(int readout) const |
||
873 | { |
||
874 | if (fDRSType < 4) { |
||
875 | return readout; |
||
876 | } else { |
||
877 | if (fReadoutChannelConfig == 4) { |
||
878 | return readout * 2; |
||
879 | } else { |
||
880 | return readout; |
||
881 | } |
||
882 | } |
||
883 | } |
||
884 | int DRSBoard::ReadoutChannel2Input(int readout) const |
||
885 | { |
||
886 | if (fDRSType < 4) { |
||
887 | return readout; |
||
888 | } else { |
||
889 | if (fReadoutChannelConfig == 4) { |
||
890 | return readout; |
||
891 | } else { |
||
892 | return readout / 2; |
||
893 | } |
||
894 | } |
||
895 | } |
||
896 | bool DRSBoard::IsCalibChannel(int ch) const |
||
897 | { |
||
898 | // return if it is clock or trigger channel |
||
899 | if (fDRSType < 4) |
||
900 | return ch == GetClockChannel() || ch == GetTriggerChannel(); |
||
901 | else |
||
902 | return ch == GetClockChannel(); |
||
903 | } |
||
904 | bool DRSBoard::IsCalibInput(int input) const |
||
905 | { |
||
906 | // return if it is clock or trigger channel |
||
907 | int ch = Input2Channel(input); |
||
908 | if (fDRSType < 4) |
||
909 | return ch == GetClockChannel() || ch == GetTriggerChannel(); |
||
910 | else |
||
911 | return ch == GetClockChannel(); |
||
912 | } |
||
913 | |||
914 | class DRS { |
||
915 | protected: |
||
916 | // constants |
||
917 | enum { |
||
918 | kMaxNumberOfBoards = 40 |
||
919 | }; |
||
920 | |||
921 | protected: |
||
922 | DRSBoard *fBoard[kMaxNumberOfBoards]; |
||
923 | int fNumberOfBoards; |
||
924 | char fError[256]; |
||
925 | #ifdef HAVE_VME |
||
926 | MVME_INTERFACE *fVmeInterface; |
||
927 | #endif |
||
928 | |||
929 | private: |
||
930 | DRS(const DRS &c); // not implemented |
||
931 | DRS &operator=(const DRS &rhs); // not implemented |
||
932 | |||
933 | public: |
||
934 | // Public Methods |
||
935 | DRS(); |
||
936 | ~DRS(); |
||
937 | |||
938 | DRSBoard *GetBoard(int i) { return fBoard[i]; } |
||
939 | void SetBoard(int i, DRSBoard *b); |
||
940 | DRSBoard **GetBoards() { return fBoard; } |
||
941 | int GetNumberOfBoards() const { return fNumberOfBoards; } |
||
942 | bool GetError(char *str, int size); |
||
943 | void SortBoards(); |
||
944 | |||
945 | #ifdef HAVE_VME |
||
946 | MVME_INTERFACE *GetVMEInterface() const { return fVmeInterface; }; |
||
947 | #endif |
||
948 | }; |
||
949 | |||
950 | #endif // DRS_H |