source: trunk/FACT++/src/HeadersFTM.h@ 16581

Last change on this file since 16581 was 15106, checked in by tbretz, 12 years ago
The operator comparing the static data now does not compare the threesholds anymore. Thus the ratecontrol can start already even before the the end of the configuration procedure ans the ftmctrl will stay in Configured.
File size: 26.7 KB
Line 
1#ifndef FACT_HeadersFTM
2#define FACT_HeadersFTM
3
4#include <ostream>
5
6// For debugging
7#include <iostream>
8
9#include "ByteOrder.h"
10
11// ====================================================================
12
13
14namespace FTM
15{
16 enum States
17 {
18 kFtmUndefined = 0,
19
20 // FTM internal states
21 kFtmIdle = 1, ///< Trigger output disabled, configuration possible
22 kFtmConfig = 2, ///< FTM and FTUs are being reconfigured
23 kFtmRunning = 3, ///< Trigger output enabled, configuration ignored
24 kFtmCalib = 4,
25
26 kFtmStates = 0x0ff,
27 kFtmLocked = 0x100,
28
29 };
30
31 // idle: not locked: 0x2711
32 // running: not locked: 0x2713
33
34 namespace State
35 {
36 enum StateMachine
37 {
38 kDisconnected = 1, //= ConnectionFTM::kDisconnected,
39 kConnected, //= ConnectionFTM::kConnected,
40 kIdle, //= ConnectionFTM::kIdle,
41 kTriggerOn, //= ConnectionFTM::kTriggerOn,
42 kConfiguring1,
43 kConfiguring2,
44 kConfigured,
45
46 kConfigError1 = 0x101,
47 kConfigError2 = 0x102,
48 //kConfigError3 = 0x103,
49 };
50 }
51
52 /// Command codes for FTM communication
53 enum Commands
54 {
55 // First word
56 kCmdRead = 0x0001, ///< Request data
57 kCmdWrite = 0x0002, ///< Send data
58 kCmdStartRun = 0x0004, ///< Enable the trigger output
59 kCmdStopRun = 0x0008, ///< Disable the trigger output
60 kCmdPing = 0x0010, ///< Ping all FTUs (get FTU list)
61 kCmdCrateReset = 0x0020, ///< Reboot (no power cycle) all FTUs and FADs of one crate
62 kCmdDisableReports = 0x0040, ///< Disable transmission of rate-reports (dynamic data)
63 kCmdConfigFTU = 0x0080, ///< Configure single FTU board
64 kCmdToggleLed = 0xc000,
65
66 // second word for read and write
67 kCmdStaticData = 0x0001, ///< Specifies that static (configuration) data is read/written
68 kCmdDynamicData = 0x0002, ///< Specifies that dynamic data is read/written
69 kCmdRegister = 0x0004, ///< Specifies that a register is read/written
70
71 // second word for StartRun
72 kStartRun = 0x0001, ///< ...until kCmdStopRun
73 kTakeNevents = 0x0002, ///< ...fixed number of events
74
75 // second word for kCmdCrateReset
76 kResetCrate0 = 0x0001,
77 kResetCrate1 = 0x0002,
78 kResetCrate2 = 0x0004,
79 kResetCrate3 = 0x0008,
80 };
81
82
83 /// Types sent in the header of the following data
84 enum Types
85 {
86 kHeader = 0, ///< Local extension to identify a header in fCounter
87 kStaticData = 1, ///< Static (configuration) data
88 kDynamicData = 2, ///< Dynamic data (rates)
89 kFtuList = 3, ///< FTU list (answer of ping)
90 kErrorList = 4, ///< Error list (error when FTU communication failed)
91 kRegister = 5, ///< A requested register value
92 };
93
94 // --------------------------------------------------------------------
95
96 enum Delimiter
97 {
98 kDelimiterStart = 0xfb01, ///< Start delimiter send before each header
99 kDelimiterEnd = 0x04fe ///< End delimiter send after each data block
100 };
101
102 struct Header
103 {
104 uint16_t fDelimiter; ///< Start delimiter
105 uint16_t fType; ///< Type of the data to be received after the header
106 uint16_t fDataSize; ///< Size in words to be received after the header (incl end delim.)
107 uint16_t fState; ///< State of the FTM central state machine
108 uint64_t fBoardId; ///< FPGA device DNA (unique chip id)
109 uint16_t fFirmwareId; ///< Version number
110 uint32_t fTriggerCounter; ///< FTM internal counter of all trigger decision independant of trigger-line enable/disable (reset: start/stop run)
111 uint64_t fTimeStamp; ///< Internal counter (micro-seconds, reset: start/stop run)
112
113 Header() { init(*this); }
114
115 std::vector<uint16_t> HtoN() const
116 {
117 Header h(*this);
118
119 Reverse(&h.fBoardId);
120 Reverse(&h.fTriggerCounter);
121 Reverse(&h.fTimeStamp);
122
123 return htoncpy(h);
124 }
125 void operator=(const std::vector<uint16_t> &vec)
126 {
127 ntohcpy(vec, *this);
128
129 Reverse(&fBoardId);
130 Reverse(&fTriggerCounter);
131 Reverse(&fTimeStamp);
132 }
133
134 void clear() { reset(*this); }
135 void print(std::ostream &out) const;
136
137 } __attribute__((__packed__));
138
139 struct DimPassport
140 {
141 uint64_t fBoardId;
142 uint16_t fFirmwareId;
143
144 DimPassport(const Header &h) :
145 fBoardId(h.fBoardId),
146 fFirmwareId(h.fFirmwareId)
147 {
148 }
149 } __attribute__((__packed__));
150
151 /*
152 struct DimTriggerCounter
153 {
154 uint64_t fTimeStamp;
155 uint32_t fTriggerCounter;
156
157 DimTriggerCounter(const Header &h) :
158 fTimeStamp(h.fTimeStamp),
159 fTriggerCounter(h.fTriggerCounter)
160 {
161 }
162 } __attribute__((__packed__));
163 */
164
165 struct StaticDataBoard
166 {
167 uint16_t fEnable[4]; /// enable of 4x9 pixels coded as 4x9bits
168 uint16_t fDAC[5]; /// 0-3 (A-D) Threshold of patches, 4 (H) Threshold for N out of 4 (12 bit each)
169 uint16_t fPrescaling; /// Internal readout time of FTUs for trigger counter
170
171 StaticDataBoard() { init(*this); }
172
173 void print(std::ostream &out) const;
174
175 } __attribute__((__packed__));
176
177 struct StaticData
178 {
179 enum Limits
180 {
181 kMaxMultiplicity = 40, ///< Minimum required trigger multiplicity
182 kMaxWindow = 0xf, ///< (4ns * x + 8ns) At least N (multiplicity) rising edges (trigger signal) within this window
183 kMaxDeadTime = 0xffff, ///< (4ns * x + 8ns)
184 kMaxDelayTimeMarker = 0x3ff, ///< (4ns * x + 8ns)
185 kMaxDelayTrigger = 0x3ff, ///< (4ns * x + 8ns)
186 kMaxTriggerInterval = 0x3ff, ///<
187 kMaxIntensity = 0x7f,
188 kMaxSequence = 0x1f,
189 kMaxDAC = 0xfff,
190 kMaxAddr = 0xfff,
191 kMaxPatchIdx = 159,
192 kMaxPixelIdx = 1439,
193 kMaskSettings = 0xf,
194 kMaskLEDs = 0xf,
195 };
196
197 enum GeneralSettings
198 {
199 kTrigger = 0x80, ///< Physics trigger decision (PhysicTrigger)
200 kPedestal = 0x40, ///< Pedestal trigger (artifical)
201 kLPint = 0x20, ///< Enable artificial trigger after light pulse (LP2)
202 kLPext = 0x10, ///< Enable trigger decision after light pulse (CalibrationTrigger, LP1)
203 kExt2 = 0x08, ///< External trigger signal 2
204 kExt1 = 0x04, ///< External trigger signal 1
205 kVeto = 0x02, ///< Veto trigger decision / artifical triggers
206 kClockConditioner = 0x01, ///< Select clock conditioner frequency (1) / time marker (0) as output
207 };
208
209 enum LightPulserEnable
210 {
211 kGroup1 = 0x40,
212 kGroup2 = 0x80,
213 };
214
215 uint16_t fGeneralSettings; /// Enable for different trigger types / select for TIM/ClockConditioner output (only 8 bit used)
216 uint16_t fStatusLEDs; /// only 8 bit used
217 uint16_t fTriggerInterval; /// [ms] Interval between two artificial triggers (no matter which type) minimum 1ms, 10 bit
218 uint16_t fTriggerSequence; /// Ratio between trigger types send as artificial trigger (in this order) 3x5bit
219 uint8_t fIntensityLPext; /// Intensity of LEDs (0-127)
220 uint8_t fEnableLPext; /// Enable for LED group 1/2 (LightPulserEnable)
221 uint8_t fIntensityLPint; /// Intensity of LEDs (0-127)
222 uint8_t fEnableLPint; /// Enable for LED group 1/2 (LightPulserEnable)
223 uint32_t fDummy0;
224 uint16_t fMultiplicityPhysics; /// Required trigger multiplicity for physcis triggers (0-40)
225 uint16_t fMultiplicityCalib; /// Required trigger multiplicity calibration (LPext) triggers (0-40)
226 uint16_t fDelayTrigger; /// (4ns * x + 8ns) FTM internal programmable delay between trigger decision and output
227 uint16_t fDelayTimeMarker; /// (4ns * x + 8ns) FTM internal programmable delay between trigger descision and time marker output
228 uint16_t fDeadTime; /// (4ns * x + 8ns) FTM internal programmable dead time after trigger decision
229 uint32_t fClockConditioner[8]; /// R0, R1, R8, R9, R11, R13, R14, R15
230 uint16_t fWindowPhysics; /// (4ns * x + 8ns) At least N (multiplicity) rising edges (trigger signal) within this window
231 uint16_t fWindowCalib; /// (4ns * x + 8ns) At least N (multiplicity) rising edges (trigger signal) within this window
232 uint16_t fDummy1;
233
234 StaticDataBoard fBoard[4][10]; // 4 crates * 10 boards (Crate0/FTU0 == readout time of FTUs)
235
236 uint16_t fActiveFTU[4]; // 4 crates * 10 bits (FTU enable)
237
238 StaticData() { init(*this); }
239 StaticData(const std::vector<uint16_t> &vec)
240 {
241 ntohcpy(vec, *this);
242
243 for (int i=0; i<8; i++)
244 Reverse(fClockConditioner+i);
245 }
246
247 std::vector<uint16_t> HtoN() const
248 {
249 StaticData d(*this);
250 for (int i=0; i<8; i++)
251 Reverse(d.fClockConditioner+i);
252
253 return htoncpy(d);
254 }
255
256 bool operator==(StaticData d) const
257 {
258 for (int i=0; i<4; i++)
259 for (int j=0; j<10; j++)
260 memcpy(d.fBoard[i][j].fDAC, fBoard[i][j].fDAC, sizeof(uint16_t)*5);
261 return memcmp(this, &d, sizeof(StaticData))==0;
262 }
263
264 void clear() { reset(*this); }
265 void print(std::ostream &out) const;
266
267 StaticDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
268 const StaticDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
269
270 void EnableFTU(int i) { fActiveFTU[i/10] |= (1<<(i%10)); }
271 void DisableFTU(int i) { fActiveFTU[i/10] &= ~(1<<(i%10)); }
272
273 void EnableAllFTU() { for (int i=0; i<4; i++) fActiveFTU[i] = 0x3ff; }
274 void DisableAllFTU() { for (int i=0; i<4; i++) fActiveFTU[i] = 0; }
275
276 void EnableLPint(LightPulserEnable group, bool enable)
277 {
278 if (enable)
279 fEnableLPint |= group;
280 else
281 fEnableLPint &= ~group;
282 }
283
284 void EnableLPext(LightPulserEnable group, bool enable)
285 {
286 if (enable)
287 fEnableLPext |= group;
288 else
289 fEnableLPext &= ~group;
290 }
291
292 void ToggleFTU(int i) { fActiveFTU[i/10] ^= (1<<(i%10)); }
293
294 void Enable(GeneralSettings type, bool enable)
295 {
296 if (enable)
297 fGeneralSettings |= uint16_t(type);
298 else
299 fGeneralSettings &= ~uint16_t(type);
300 }
301
302 bool IsEnabled(GeneralSettings type) const { return fGeneralSettings&uint16_t(type); }
303
304 uint16_t *EnablePixel(int idx, bool enable)
305 {
306 const int pixel = idx%9;
307 const int patch = (idx/9)%4;
308 const int board = (idx/9)/4;
309
310 uint16_t &pix = fBoard[board/10][board%10].fEnable[patch];
311
312 if (enable)
313 pix |= (1<<pixel);
314 else
315 pix &= ~(1<<pixel);
316
317 return &pix;
318 }
319
320 void EnablePatch(int idx, bool enable)
321 {
322 const int patch = idx%4;
323 const int board = idx/4;
324
325 fBoard[board/10][board%10].fEnable[patch] = enable ? 0x1ff : 0;
326 }
327
328 void EnableAllPixel()
329 {
330 for (int c=0; c<4; c++)
331 for (int b=0; b<10; b++)
332 for (int p=0; p<4; p++)
333 fBoard[c][b].fEnable[p] = 0x1ff;
334 }
335
336 bool Enabled(uint16_t idx) const
337 {
338 const int pixel = idx%9;
339 const int patch = (idx/9)%4;
340 const int board = (idx/9)/4;
341
342 return (fBoard[board/10][board%10].fEnable[patch]>>pixel)&1;
343 }
344
345 uint8_t GetSequencePed() const { return (fTriggerSequence>>10)&0x1f; }
346 uint8_t GetSequenceLPint() const { return (fTriggerSequence>> 5)&0x1f; }
347 uint8_t GetSequenceLPext() const { return (fTriggerSequence) &0x1f; }
348
349 void SetSequence(uint8_t ped, uint8_t lpint, uint8_t lpext)
350 {
351 fTriggerSequence = ((ped&0x1f)<<10)|((lpint&0x1f)<<5)|(lpext&0x1f);
352
353 Enable(kPedestal, ped >0);
354 Enable(kLPext, lpext>0);
355 Enable(kLPint, lpint>0);
356 }
357
358 void SetClockRegister(const uint64_t reg[])
359 {
360 for (int i=0; i<8; i++)
361 fClockConditioner[i] = reg[i];
362 }
363
364 void SetPrescaling(uint16_t val)
365 {
366 for (int c=0; c<4; c++)
367 for (int b=0; b<10; b++)
368 fBoard[c][b].fPrescaling = val;
369 }
370
371 } __attribute__((__packed__));
372
373 // DimStructures must be a multiple of two... I don't know why
374 struct DimStaticData
375 {
376 uint64_t fTimeStamp;
377 //8
378 uint16_t fGeneralSettings; // only 8 bit used
379 uint16_t fStatusLEDs; // only 8 bit used
380 uint64_t fActiveFTU; // 40 bits in row
381 //20
382 uint16_t fTriggerInterval; // only 10 bit used
383 //22
384 uint16_t fTriggerSeqLPint; // only 5bits used
385 uint16_t fTriggerSeqLPext; // only 5bits used
386 uint16_t fTriggerSeqPed; // only 5bits used
387 // 28
388 uint8_t fEnableLPint; /// Enable for LED group 1/2 (LightPulserEnable)
389 uint8_t fEnableLPext; /// Enable for LED group 1/2 (LightPulserEnable)
390 uint8_t fIntensityLPint; /// Intensity of LEDs (0-127)
391 uint8_t fIntensityLPext; /// Intensity of LEDs (0-127)
392 //32
393 uint16_t fMultiplicityPhysics; // 0-40
394 uint16_t fMultiplicityCalib; // 0-40
395 //36
396 uint16_t fWindowPhysics;
397 uint16_t fWindowCalib;
398 //40
399 uint16_t fDelayTrigger;
400 uint16_t fDelayTimeMarker;
401 uint32_t fDeadTime;
402 //48
403 uint32_t fClockConditioner[8];
404 //64
405 uint16_t fEnable[90]; // 160*9bit = 180byte
406 uint16_t fThreshold[160];
407 uint16_t fMultiplicity[40]; // N out of 4
408 uint16_t fPrescaling[40];
409 // 640+64 = 704
410
411 bool HasTrigger() const { return fGeneralSettings & StaticData::kTrigger; }
412 bool HasPedestal() const { return fGeneralSettings & StaticData::kPedestal; }
413 bool HasLPext() const { return fGeneralSettings & StaticData::kLPext; }
414 bool HasLPint() const { return fGeneralSettings & StaticData::kLPint; }
415 bool HasExt2() const { return fGeneralSettings & StaticData::kExt2; }
416 bool HasExt1() const { return fGeneralSettings & StaticData::kExt1; }
417 bool HasVeto() const { return fGeneralSettings & StaticData::kVeto; }
418 bool HasClockConditioner() const { return fGeneralSettings & StaticData::kClockConditioner; }
419
420 bool HasLPextG1() const { return fEnableLPext&StaticData::kGroup1; }
421 bool HasLPextG2() const { return fEnableLPext&StaticData::kGroup2; }
422 bool HasLPintG1() const { return fEnableLPint&StaticData::kGroup1; }
423 bool HasLPintG2() const { return fEnableLPint&StaticData::kGroup2; }
424
425 bool IsActive(int i) const { return fActiveFTU&(uint64_t(1)<<i); }
426 bool IsEnabled(int i) const { return fEnable[i/16]&(1<<(i%16)); }
427
428 DimStaticData() { memset(this, 0, sizeof(DimStaticData)); }
429
430 DimStaticData(const Header &h, const StaticData &d) :
431 fTimeStamp(h.fTimeStamp),
432 fGeneralSettings(d.fGeneralSettings),
433 fStatusLEDs(d.fStatusLEDs),
434 fActiveFTU( uint64_t(d.fActiveFTU[0]) |
435 (uint64_t(d.fActiveFTU[1])<<10) |
436 (uint64_t(d.fActiveFTU[2])<<20) |
437 (uint64_t(d.fActiveFTU[3])<<30)),
438 fTriggerInterval(d.fTriggerInterval),
439 fTriggerSeqLPint((d.fTriggerSequence>>5)&0x1f),
440 fTriggerSeqLPext((d.fTriggerSequence)&0x1f),
441 fTriggerSeqPed((d.fTriggerSequence>>10)&0x1f),
442 fEnableLPint(d.fEnableLPint),
443 fEnableLPext(d.fEnableLPext),
444 fIntensityLPint(d.fIntensityLPint),
445 fIntensityLPext(d.fIntensityLPext),
446 fMultiplicityPhysics(d.fMultiplicityPhysics),
447 fMultiplicityCalib(d.fMultiplicityCalib),
448 fWindowPhysics(d.fWindowPhysics*4+8),
449 fWindowCalib(d.fWindowCalib*4+8),
450 fDelayTrigger(d.fDelayTrigger*4+8),
451 fDelayTimeMarker(d.fDelayTimeMarker*4+8),
452 fDeadTime(uint32_t(d.fDeadTime)*4+8)
453 {
454 memcpy(fClockConditioner, d.fClockConditioner, sizeof(uint32_t)*8);
455
456 uint16_t src[160];
457 for (int i=0; i<40; i++)
458 {
459 for (int j=0; j<4; j++)
460 {
461 src[i*4+j] = d[i].fEnable[j];
462 fThreshold[i*4+j] = d[i].fDAC[j];
463 }
464
465 fMultiplicity[i] = d[i].fDAC[4];
466 fPrescaling[i] = d[i].fPrescaling+1;
467 }
468 bitcpy(fEnable, 90, src, 160, 9);
469 }
470
471 } __attribute__((__packed__));
472
473
474 struct DynamicDataBoard
475 {
476 uint32_t fRatePatch[4]; // Patch 0,1,2,3
477 uint32_t fRateTotal; // Sum
478
479 uint16_t fOverflow; // Patches: bits 0-3, total 4
480 uint16_t fCrcError;
481
482 void print(std::ostream &out) const;
483
484 void reverse()
485 {
486 for (int i=0; i<4; i++)
487 Reverse(fRatePatch+i);
488
489 Reverse(&fRateTotal);
490 }
491
492 uint32_t &operator[](int i) { return fRatePatch[i]; }
493
494 } __attribute__((__packed__));
495
496
497 struct DynamicData
498 {
499 uint64_t fOnTimeCounter;
500 uint16_t fTempSensor[4]; // U45, U46, U48, U49
501
502 DynamicDataBoard fBoard[4][10]; // 4 crates * 10 boards
503
504 DynamicData() { init(*this); }
505
506 std::vector<uint16_t> HtoN() const
507 {
508 DynamicData d(*this);
509
510 Reverse(&d.fOnTimeCounter);
511
512 for (int c=0; c<4; c++)
513 for (int b=0; b<10; b++)
514 d.fBoard[c][b].reverse();
515
516 return htoncpy(d);
517 }
518
519 void operator=(const std::vector<uint16_t> &vec)
520 {
521 ntohcpy(vec, *this);
522
523 Reverse(&fOnTimeCounter);
524
525 for (int c=0; c<4; c++)
526 for (int b=0; b<10; b++)
527 fBoard[c][b].reverse();
528 }
529
530 void clear() { reset(*this); }
531 void print(std::ostream &out) const;
532
533 DynamicDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
534 const DynamicDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
535
536 } __attribute__((__packed__));
537
538
539 struct DimDynamicData
540 {
541 uint64_t fTimeStamp;
542
543 uint64_t fOnTimeCounter;
544 float fTempSensor[4];
545
546 uint32_t fRatePatch[160];
547
548 uint32_t fRateBoard[40];
549 uint16_t fRateOverflow[40];
550
551 uint16_t fPrescaling[40];
552
553 uint16_t fCrcError[40];
554
555 uint16_t fState;
556
557 DimDynamicData(const Header &h, const DynamicData &d, const StaticData &s) :
558 fTimeStamp(h.fTimeStamp),
559 fOnTimeCounter(d.fOnTimeCounter),
560 fState(h.fState)
561 {
562 for (int i=0; i<4; i++)
563 fTempSensor[i] = d.fTempSensor[i];
564
565 for (int i=0; i<40; i++)
566 {
567 fRateBoard[i] = d[i].fRateTotal;
568 fRateOverflow[i] = d[i].fOverflow;
569 fCrcError[i] = d[i].fCrcError;
570 for (int j=0; j<4; j++)
571 fRatePatch[i*4+j] = d[i].fRatePatch[j];
572
573 fPrescaling[i] = s[i].fPrescaling+1;
574 }
575 }
576
577 } __attribute__((__packed__));
578
579 struct DimTriggerRates
580 {
581 uint64_t fTimeStamp;
582 uint64_t fOnTimeCounter;
583 uint32_t fTriggerCounter;
584 float fTriggerRate;
585 float fBoardRate[40];
586 float fPatchRate[160];
587
588 float fElapsedTime;
589 float fOnTime;
590
591 DimTriggerRates() { memset(this, 0, sizeof(DimTriggerRates)); }
592
593 DimTriggerRates(const Header &h, const DynamicData &d, const StaticData &s, float rate, float et, float ot) :
594 fTimeStamp(h.fTimeStamp), fOnTimeCounter(d.fOnTimeCounter),
595 fTriggerCounter(h.fTriggerCounter), fTriggerRate(rate),
596 fElapsedTime(et), fOnTime(ot)
597 {
598 for (int i=0; i<40; i++)
599 {
600 if ((d[i].fOverflow>>4)&1)
601 fBoardRate[i] = float(UINT32_MAX+1)*2/(s[i].fPrescaling+1);
602 else
603 fBoardRate[i] = float(d[i].fRateTotal)*2/(s[i].fPrescaling+1);
604
605 // FIXME: Include fCrcError in calculation
606 //fRateOverflow[i] = d[i].fOverflow;
607 for (int j=0; j<4; j++)
608 if ((d[i].fOverflow>>j)&1)
609 fPatchRate[i*4+j] = float(UINT32_MAX+1)*2/(s[i].fPrescaling+1);
610 else
611 fPatchRate[i*4+j] = float(d[i].fRatePatch[j])*2/(s[i].fPrescaling+1);
612 }
613 }
614
615 } __attribute__((__packed__));
616
617
618 struct FtuResponse
619 {
620 uint16_t fPingAddr; // Number of Pings and addr (pings= see error)
621 uint64_t fDNA;
622 uint16_t fErrorCounter; //
623
624 void reverse() { Reverse(&fDNA); }
625
626 void print(std::ostream &out) const;
627
628 } __attribute__((__packed__));
629
630 struct FtuList
631 {
632 uint16_t fNumBoards; /// Total number of boards responded
633 uint16_t fNumBoardsCrate[4]; /// Num of board responded in crate 0-3
634 uint16_t fActiveFTU[4]; /// List of active FTU boards in crate 0-3
635
636 FtuResponse fFTU[4][10];
637
638 FtuList() { init(*this); }
639
640 std::vector<uint16_t> HtoN() const
641 {
642 FtuList d(*this);
643
644 for (int c=0; c<4; c++)
645 for (int b=0; b<10; b++)
646 d.fFTU[c][b].reverse();
647
648 return htoncpy(d);
649 }
650
651 void operator=(const std::vector<uint16_t> &vec)
652 {
653 ntohcpy(vec, *this);
654
655 for (int c=0; c<4; c++)
656 for (int b=0; b<10; b++)
657 fFTU[c][b].reverse();
658 }
659
660 void clear() { reset(*this); }
661 void print(std::ostream &out) const;
662
663 FtuResponse &operator[](int i) { return fFTU[i/10][i%10]; }
664 const FtuResponse &operator[](int i) const { return fFTU[i/10][i%10]; }
665
666 } __attribute__((__packed__));
667
668 struct DimFtuList
669 {
670 uint64_t fTimeStamp;
671 uint64_t fActiveFTU;
672
673 uint16_t fNumBoards; /// Number of boards answered in total
674 uint8_t fNumBoardsCrate[4]; /// Number of boards answered per crate
675
676 uint64_t fDNA[40]; /// DNA of FTU board
677 uint8_t fAddr[40]; /// Address of FTU board
678 uint8_t fPing[40]; /// Number of pings until response (same as in Error)
679
680 DimFtuList(const Header &h, const FtuList &d) :
681 fTimeStamp(h.fTimeStamp),
682 fActiveFTU( uint64_t(d.fActiveFTU[0]) |
683 (uint64_t(d.fActiveFTU[1])<<10) |
684 (uint64_t(d.fActiveFTU[2])<<20) |
685 (uint64_t(d.fActiveFTU[3])<<30)),
686 fNumBoards(d.fNumBoards)
687 {
688 for (int i=0; i<4; i++)
689 fNumBoardsCrate[i] = d.fNumBoardsCrate[i];
690
691 for (int i=0; i<40; i++)
692 {
693 fDNA[i] = d[i].fDNA;
694 fAddr[i] = d[i].fPingAddr&0x3f;
695 fPing[i] = (d[i].fPingAddr>>8)&0x3;
696 }
697 }
698
699 bool IsActive(int i) const { return fActiveFTU&(uint64_t(1)<<i); }
700
701 } __attribute__((__packed__));
702
703
704 struct Error
705 {
706 uint16_t fNumCalls; // 0=error, >1 needed repetition but successfull
707
708 uint16_t fDelimiter;
709 uint16_t fDestAddress;
710 uint16_t fSrcAddress;
711 uint16_t fFirmwareId;
712 uint16_t fCommand;
713 uint16_t fData[21];
714 uint16_t fCrcErrorCounter;
715 uint16_t fCrcCheckSum;
716
717 Error() { init(*this); }
718
719 std::vector<uint16_t> HtoN() const
720 {
721 return htoncpy(*this);
722 }
723
724 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
725
726 void clear() { reset(*this); }
727
728 uint16_t &operator[](int idx) { return fData[idx]; }
729 const uint16_t &operator[](int idx) const { return fData[idx]; }
730
731 void print(std::ostream &out) const;
732
733 } __attribute__((__packed__));
734
735 struct DimError
736 {
737 uint64_t fTimeStamp;
738 Error fError;
739
740 DimError(const Header &h, const Error &e) :
741 fTimeStamp(h.fTimeStamp),
742 fError(e)
743 {
744 fError.fDestAddress = (e.fDestAddress&0x3)*10 + ((e.fDestAddress>>2)&0xf);
745 fError.fSrcAddress = (e.fSrcAddress &0x3)*10 + ((e.fSrcAddress >>2)&0xf);
746 }
747
748 } __attribute__((__packed__));
749
750 /*
751 struct Command
752 {
753 uint16_t fStartDelimiter;
754 uint16_t fCommand;
755 uint16_t fParam[3];
756
757 Command() { init(*this); }
758
759 void HtoN() { hton(*this); }
760 void NtoH() { ntoh(*this); }
761
762 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
763
764 void clear() { reset(*this); }
765
766
767 } __attribute__((__packed__));
768 */
769
770 // --------------------------------------------------------------------
771
772 inline std::ostream &operator<<(std::ostream &out, const FtuResponse &h)
773 {
774 h.print(out);
775 return out;
776 }
777
778 inline std::ostream &operator<<(std::ostream &out, const Header &h)
779 {
780 h.print(out);
781 return out;
782 }
783
784
785 inline std::ostream &operator<<(std::ostream &out, const FtuList &h)
786 {
787 h.print(out);
788 return out;
789 }
790
791 inline std::ostream &operator<<(std::ostream &out, const DynamicDataBoard &h)
792 {
793 h.print(out);
794 return out;
795 }
796
797 inline std::ostream &operator<<(std::ostream &out, const DynamicData &h)
798 {
799 h.print(out);
800 return out;
801 }
802
803 inline std::ostream &operator<<(std::ostream &out, const StaticDataBoard &h)
804 {
805 h.print(out);
806 return out;
807 }
808
809 inline std::ostream &operator<<(std::ostream &out, const StaticData &h)
810 {
811 h.print(out);
812 return out;
813 }
814
815 inline std::ostream &operator<<(std::ostream &out, const Error &h)
816 {
817 h.print(out);
818 return out;
819 }
820};
821
822#endif
Note: See TracBrowser for help on using the repository browser.