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

Last change on this file since 15075 was 15055, checked in by tbretz, 12 years ago
Removed the code dealing with the clock conditioner. There is now easy way to check that during configuration. This check has to be done continously somewhere else.
File size: 26.6 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==(const StaticData &d) const
257 {
258 return memcmp(this, &d, sizeof(StaticData))==0;
259 }
260
261 void clear() { reset(*this); }
262 void print(std::ostream &out) const;
263
264 StaticDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
265 const StaticDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
266
267 void EnableFTU(int i) { fActiveFTU[i/10] |= (1<<(i%10)); }
268 void DisableFTU(int i) { fActiveFTU[i/10] &= ~(1<<(i%10)); }
269
270 void EnableAllFTU() { for (int i=0; i<4; i++) fActiveFTU[i] = 0x3ff; }
271 void DisableAllFTU() { for (int i=0; i<4; i++) fActiveFTU[i] = 0; }
272
273 void EnableLPint(LightPulserEnable group, bool enable)
274 {
275 if (enable)
276 fEnableLPint |= group;
277 else
278 fEnableLPint &= ~group;
279 }
280
281 void EnableLPext(LightPulserEnable group, bool enable)
282 {
283 if (enable)
284 fEnableLPext |= group;
285 else
286 fEnableLPext &= ~group;
287 }
288
289 void ToggleFTU(int i) { fActiveFTU[i/10] ^= (1<<(i%10)); }
290
291 void Enable(GeneralSettings type, bool enable)
292 {
293 if (enable)
294 fGeneralSettings |= uint16_t(type);
295 else
296 fGeneralSettings &= ~uint16_t(type);
297 }
298
299 bool IsEnabled(GeneralSettings type) const { return fGeneralSettings&uint16_t(type); }
300
301 uint16_t *EnablePixel(int idx, bool enable)
302 {
303 const int pixel = idx%9;
304 const int patch = (idx/9)%4;
305 const int board = (idx/9)/4;
306
307 uint16_t &pix = fBoard[board/10][board%10].fEnable[patch];
308
309 if (enable)
310 pix |= (1<<pixel);
311 else
312 pix &= ~(1<<pixel);
313
314 return &pix;
315 }
316
317 void EnablePatch(int idx, bool enable)
318 {
319 const int patch = idx%4;
320 const int board = idx/4;
321
322 fBoard[board/10][board%10].fEnable[patch] = enable ? 0x1ff : 0;
323 }
324
325 void EnableAllPixel()
326 {
327 for (int c=0; c<4; c++)
328 for (int b=0; b<10; b++)
329 for (int p=0; p<4; p++)
330 fBoard[c][b].fEnable[p] = 0x1ff;
331 }
332
333 bool Enabled(uint16_t idx) const
334 {
335 const int pixel = idx%9;
336 const int patch = (idx/9)%4;
337 const int board = (idx/9)/4;
338
339 return (fBoard[board/10][board%10].fEnable[patch]>>pixel)&1;
340 }
341
342 uint8_t GetSequencePed() const { return (fTriggerSequence>>10)&0x1f; }
343 uint8_t GetSequenceLPint() const { return (fTriggerSequence>> 5)&0x1f; }
344 uint8_t GetSequenceLPext() const { return (fTriggerSequence) &0x1f; }
345
346 void SetSequence(uint8_t ped, uint8_t lpint, uint8_t lpext)
347 {
348 fTriggerSequence = ((ped&0x1f)<<10)|((lpint&0x1f)<<5)|(lpext&0x1f);
349
350 Enable(kPedestal, ped >0);
351 Enable(kLPext, lpext>0);
352 Enable(kLPint, lpint>0);
353 }
354
355 void SetClockRegister(const uint64_t reg[])
356 {
357 for (int i=0; i<8; i++)
358 fClockConditioner[i] = reg[i];
359 }
360
361 void SetPrescaling(uint16_t val)
362 {
363 for (int c=0; c<4; c++)
364 for (int b=0; b<10; b++)
365 fBoard[c][b].fPrescaling = val;
366 }
367
368 } __attribute__((__packed__));
369
370 // DimStructures must be a multiple of two... I don't know why
371 struct DimStaticData
372 {
373 uint64_t fTimeStamp;
374 //8
375 uint16_t fGeneralSettings; // only 8 bit used
376 uint16_t fStatusLEDs; // only 8 bit used
377 uint64_t fActiveFTU; // 40 bits in row
378 //20
379 uint16_t fTriggerInterval; // only 10 bit used
380 //22
381 uint16_t fTriggerSeqLPint; // only 5bits used
382 uint16_t fTriggerSeqLPext; // only 5bits used
383 uint16_t fTriggerSeqPed; // only 5bits used
384 // 28
385 uint8_t fEnableLPint; /// Enable for LED group 1/2 (LightPulserEnable)
386 uint8_t fEnableLPext; /// Enable for LED group 1/2 (LightPulserEnable)
387 uint8_t fIntensityLPint; /// Intensity of LEDs (0-127)
388 uint8_t fIntensityLPext; /// Intensity of LEDs (0-127)
389 //32
390 uint16_t fMultiplicityPhysics; // 0-40
391 uint16_t fMultiplicityCalib; // 0-40
392 //36
393 uint16_t fWindowPhysics;
394 uint16_t fWindowCalib;
395 //40
396 uint16_t fDelayTrigger;
397 uint16_t fDelayTimeMarker;
398 uint32_t fDeadTime;
399 //48
400 uint32_t fClockConditioner[8];
401 //64
402 uint16_t fEnable[90]; // 160*9bit = 180byte
403 uint16_t fThreshold[160];
404 uint16_t fMultiplicity[40]; // N out of 4
405 uint16_t fPrescaling[40];
406 // 640+64 = 704
407
408 bool HasTrigger() const { return fGeneralSettings & StaticData::kTrigger; }
409 bool HasPedestal() const { return fGeneralSettings & StaticData::kPedestal; }
410 bool HasLPext() const { return fGeneralSettings & StaticData::kLPext; }
411 bool HasLPint() const { return fGeneralSettings & StaticData::kLPint; }
412 bool HasExt2() const { return fGeneralSettings & StaticData::kExt2; }
413 bool HasExt1() const { return fGeneralSettings & StaticData::kExt1; }
414 bool HasVeto() const { return fGeneralSettings & StaticData::kVeto; }
415 bool HasClockConditioner() const { return fGeneralSettings & StaticData::kClockConditioner; }
416
417 bool HasLPextG1() const { return fEnableLPext&StaticData::kGroup1; }
418 bool HasLPextG2() const { return fEnableLPext&StaticData::kGroup2; }
419 bool HasLPintG1() const { return fEnableLPint&StaticData::kGroup1; }
420 bool HasLPintG2() const { return fEnableLPint&StaticData::kGroup2; }
421
422 bool IsActive(int i) const { return fActiveFTU&(uint64_t(1)<<i); }
423 bool IsEnabled(int i) const { return fEnable[i/16]&(1<<(i%16)); }
424
425 DimStaticData() { memset(this, 0, sizeof(DimStaticData)); }
426
427 DimStaticData(const Header &h, const StaticData &d) :
428 fTimeStamp(h.fTimeStamp),
429 fGeneralSettings(d.fGeneralSettings),
430 fStatusLEDs(d.fStatusLEDs),
431 fActiveFTU( uint64_t(d.fActiveFTU[0]) |
432 (uint64_t(d.fActiveFTU[1])<<10) |
433 (uint64_t(d.fActiveFTU[2])<<20) |
434 (uint64_t(d.fActiveFTU[3])<<30)),
435 fTriggerInterval(d.fTriggerInterval),
436 fTriggerSeqLPint((d.fTriggerSequence>>5)&0x1f),
437 fTriggerSeqLPext((d.fTriggerSequence)&0x1f),
438 fTriggerSeqPed((d.fTriggerSequence>>10)&0x1f),
439 fEnableLPint(d.fEnableLPint),
440 fEnableLPext(d.fEnableLPext),
441 fIntensityLPint(d.fIntensityLPint),
442 fIntensityLPext(d.fIntensityLPext),
443 fMultiplicityPhysics(d.fMultiplicityPhysics),
444 fMultiplicityCalib(d.fMultiplicityCalib),
445 fWindowPhysics(d.fWindowPhysics*4+8),
446 fWindowCalib(d.fWindowCalib*4+8),
447 fDelayTrigger(d.fDelayTrigger*4+8),
448 fDelayTimeMarker(d.fDelayTimeMarker*4+8),
449 fDeadTime(uint32_t(d.fDeadTime)*4+8)
450 {
451 memcpy(fClockConditioner, d.fClockConditioner, sizeof(uint32_t)*8);
452
453 uint16_t src[160];
454 for (int i=0; i<40; i++)
455 {
456 for (int j=0; j<4; j++)
457 {
458 src[i*4+j] = d[i].fEnable[j];
459 fThreshold[i*4+j] = d[i].fDAC[j];
460 }
461
462 fMultiplicity[i] = d[i].fDAC[4];
463 fPrescaling[i] = d[i].fPrescaling+1;
464 }
465 bitcpy(fEnable, 90, src, 160, 9);
466 }
467
468 } __attribute__((__packed__));
469
470
471 struct DynamicDataBoard
472 {
473 uint32_t fRatePatch[4]; // Patch 0,1,2,3
474 uint32_t fRateTotal; // Sum
475
476 uint16_t fOverflow; // Patches: bits 0-3, total 4
477 uint16_t fCrcError;
478
479 void print(std::ostream &out) const;
480
481 void reverse()
482 {
483 for (int i=0; i<4; i++)
484 Reverse(fRatePatch+i);
485
486 Reverse(&fRateTotal);
487 }
488
489 uint32_t &operator[](int i) { return fRatePatch[i]; }
490
491 } __attribute__((__packed__));
492
493
494 struct DynamicData
495 {
496 uint64_t fOnTimeCounter;
497 uint16_t fTempSensor[4]; // U45, U46, U48, U49
498
499 DynamicDataBoard fBoard[4][10]; // 4 crates * 10 boards
500
501 DynamicData() { init(*this); }
502
503 std::vector<uint16_t> HtoN() const
504 {
505 DynamicData d(*this);
506
507 Reverse(&d.fOnTimeCounter);
508
509 for (int c=0; c<4; c++)
510 for (int b=0; b<10; b++)
511 d.fBoard[c][b].reverse();
512
513 return htoncpy(d);
514 }
515
516 void operator=(const std::vector<uint16_t> &vec)
517 {
518 ntohcpy(vec, *this);
519
520 Reverse(&fOnTimeCounter);
521
522 for (int c=0; c<4; c++)
523 for (int b=0; b<10; b++)
524 fBoard[c][b].reverse();
525 }
526
527 void clear() { reset(*this); }
528 void print(std::ostream &out) const;
529
530 DynamicDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
531 const DynamicDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
532
533 } __attribute__((__packed__));
534
535
536 struct DimDynamicData
537 {
538 uint64_t fTimeStamp;
539
540 uint64_t fOnTimeCounter;
541 float fTempSensor[4];
542
543 uint32_t fRatePatch[160];
544
545 uint32_t fRateBoard[40];
546 uint16_t fRateOverflow[40];
547
548 uint16_t fPrescaling[40];
549
550 uint16_t fCrcError[40];
551
552 uint16_t fState;
553
554 DimDynamicData(const Header &h, const DynamicData &d, const StaticData &s) :
555 fTimeStamp(h.fTimeStamp),
556 fOnTimeCounter(d.fOnTimeCounter),
557 fState(h.fState)
558 {
559 for (int i=0; i<4; i++)
560 fTempSensor[i] = d.fTempSensor[i];
561
562 for (int i=0; i<40; i++)
563 {
564 fRateBoard[i] = d[i].fRateTotal;
565 fRateOverflow[i] = d[i].fOverflow;
566 fCrcError[i] = d[i].fCrcError;
567 for (int j=0; j<4; j++)
568 fRatePatch[i*4+j] = d[i].fRatePatch[j];
569
570 fPrescaling[i] = s[i].fPrescaling+1;
571 }
572 }
573
574 } __attribute__((__packed__));
575
576 struct DimTriggerRates
577 {
578 uint64_t fTimeStamp;
579 uint64_t fOnTimeCounter;
580 uint32_t fTriggerCounter;
581 float fTriggerRate;
582 float fBoardRate[40];
583 float fPatchRate[160];
584
585 float fElapsedTime;
586 float fOnTime;
587
588 DimTriggerRates() { memset(this, 0, sizeof(DimTriggerRates)); }
589
590 DimTriggerRates(const Header &h, const DynamicData &d, const StaticData &s, float rate, float et, float ot) :
591 fTimeStamp(h.fTimeStamp), fOnTimeCounter(d.fOnTimeCounter),
592 fTriggerCounter(h.fTriggerCounter), fTriggerRate(rate),
593 fElapsedTime(et), fOnTime(ot)
594 {
595 for (int i=0; i<40; i++)
596 {
597 if ((d[i].fOverflow>>4)&1)
598 fBoardRate[i] = float(UINT32_MAX+1)*2/(s[i].fPrescaling+1);
599 else
600 fBoardRate[i] = float(d[i].fRateTotal)*2/(s[i].fPrescaling+1);
601
602 // FIXME: Include fCrcError in calculation
603 //fRateOverflow[i] = d[i].fOverflow;
604 for (int j=0; j<4; j++)
605 if ((d[i].fOverflow>>j)&1)
606 fPatchRate[i*4+j] = float(UINT32_MAX+1)*2/(s[i].fPrescaling+1);
607 else
608 fPatchRate[i*4+j] = float(d[i].fRatePatch[j])*2/(s[i].fPrescaling+1);
609 }
610 }
611
612 } __attribute__((__packed__));
613
614
615 struct FtuResponse
616 {
617 uint16_t fPingAddr; // Number of Pings and addr (pings= see error)
618 uint64_t fDNA;
619 uint16_t fErrorCounter; //
620
621 void reverse() { Reverse(&fDNA); }
622
623 void print(std::ostream &out) const;
624
625 } __attribute__((__packed__));
626
627 struct FtuList
628 {
629 uint16_t fNumBoards; /// Total number of boards responded
630 uint16_t fNumBoardsCrate[4]; /// Num of board responded in crate 0-3
631 uint16_t fActiveFTU[4]; /// List of active FTU boards in crate 0-3
632
633 FtuResponse fFTU[4][10];
634
635 FtuList() { init(*this); }
636
637 std::vector<uint16_t> HtoN() const
638 {
639 FtuList d(*this);
640
641 for (int c=0; c<4; c++)
642 for (int b=0; b<10; b++)
643 d.fFTU[c][b].reverse();
644
645 return htoncpy(d);
646 }
647
648 void operator=(const std::vector<uint16_t> &vec)
649 {
650 ntohcpy(vec, *this);
651
652 for (int c=0; c<4; c++)
653 for (int b=0; b<10; b++)
654 fFTU[c][b].reverse();
655 }
656
657 void clear() { reset(*this); }
658 void print(std::ostream &out) const;
659
660 FtuResponse &operator[](int i) { return fFTU[i/10][i%10]; }
661 const FtuResponse &operator[](int i) const { return fFTU[i/10][i%10]; }
662
663 } __attribute__((__packed__));
664
665 struct DimFtuList
666 {
667 uint64_t fTimeStamp;
668 uint64_t fActiveFTU;
669
670 uint16_t fNumBoards; /// Number of boards answered in total
671 uint8_t fNumBoardsCrate[4]; /// Number of boards answered per crate
672
673 uint64_t fDNA[40]; /// DNA of FTU board
674 uint8_t fAddr[40]; /// Address of FTU board
675 uint8_t fPing[40]; /// Number of pings until response (same as in Error)
676
677 DimFtuList(const Header &h, const FtuList &d) :
678 fTimeStamp(h.fTimeStamp),
679 fActiveFTU( uint64_t(d.fActiveFTU[0]) |
680 (uint64_t(d.fActiveFTU[1])<<10) |
681 (uint64_t(d.fActiveFTU[2])<<20) |
682 (uint64_t(d.fActiveFTU[3])<<30)),
683 fNumBoards(d.fNumBoards)
684 {
685 for (int i=0; i<4; i++)
686 fNumBoardsCrate[i] = d.fNumBoardsCrate[i];
687
688 for (int i=0; i<40; i++)
689 {
690 fDNA[i] = d[i].fDNA;
691 fAddr[i] = d[i].fPingAddr&0x3f;
692 fPing[i] = (d[i].fPingAddr>>8)&0x3;
693 }
694 }
695
696 bool IsActive(int i) const { return fActiveFTU&(uint64_t(1)<<i); }
697
698 } __attribute__((__packed__));
699
700
701 struct Error
702 {
703 uint16_t fNumCalls; // 0=error, >1 needed repetition but successfull
704
705 uint16_t fDelimiter;
706 uint16_t fDestAddress;
707 uint16_t fSrcAddress;
708 uint16_t fFirmwareId;
709 uint16_t fCommand;
710 uint16_t fData[21];
711 uint16_t fCrcErrorCounter;
712 uint16_t fCrcCheckSum;
713
714 Error() { init(*this); }
715
716 std::vector<uint16_t> HtoN() const
717 {
718 return htoncpy(*this);
719 }
720
721 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
722
723 void clear() { reset(*this); }
724
725 uint16_t &operator[](int idx) { return fData[idx]; }
726 const uint16_t &operator[](int idx) const { return fData[idx]; }
727
728 void print(std::ostream &out) const;
729
730 } __attribute__((__packed__));
731
732 struct DimError
733 {
734 uint64_t fTimeStamp;
735 Error fError;
736
737 DimError(const Header &h, const Error &e) :
738 fTimeStamp(h.fTimeStamp),
739 fError(e)
740 {
741 fError.fDestAddress = (e.fDestAddress&0x3)*10 + ((e.fDestAddress>>2)&0xf);
742 fError.fSrcAddress = (e.fSrcAddress &0x3)*10 + ((e.fSrcAddress >>2)&0xf);
743 }
744
745 } __attribute__((__packed__));
746
747 /*
748 struct Command
749 {
750 uint16_t fStartDelimiter;
751 uint16_t fCommand;
752 uint16_t fParam[3];
753
754 Command() { init(*this); }
755
756 void HtoN() { hton(*this); }
757 void NtoH() { ntoh(*this); }
758
759 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
760
761 void clear() { reset(*this); }
762
763
764 } __attribute__((__packed__));
765 */
766
767 // --------------------------------------------------------------------
768
769 inline std::ostream &operator<<(std::ostream &out, const FtuResponse &h)
770 {
771 h.print(out);
772 return out;
773 }
774
775 inline std::ostream &operator<<(std::ostream &out, const Header &h)
776 {
777 h.print(out);
778 return out;
779 }
780
781
782 inline std::ostream &operator<<(std::ostream &out, const FtuList &h)
783 {
784 h.print(out);
785 return out;
786 }
787
788 inline std::ostream &operator<<(std::ostream &out, const DynamicDataBoard &h)
789 {
790 h.print(out);
791 return out;
792 }
793
794 inline std::ostream &operator<<(std::ostream &out, const DynamicData &h)
795 {
796 h.print(out);
797 return out;
798 }
799
800 inline std::ostream &operator<<(std::ostream &out, const StaticDataBoard &h)
801 {
802 h.print(out);
803 return out;
804 }
805
806 inline std::ostream &operator<<(std::ostream &out, const StaticData &h)
807 {
808 h.print(out);
809 return out;
810 }
811
812 inline std::ostream &operator<<(std::ostream &out, const Error &h)
813 {
814 h.print(out);
815 return out;
816 }
817};
818
819#endif
Note: See TracBrowser for help on using the repository browser.