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

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