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

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