source: branches/fscctrl_safety_limits/src/HeadersFTM.h@ 19365

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