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

Last change on this file since 10546 was 10535, checked in by tbretz, 14 years ago
Added more details to Error.
File size: 19.4 KB
Line 
1#include <string.h>
2#include <algorithm>
3#include <arpa/inet.h>
4#include <stdexcept>
5#include <typeinfo>
6#include <vector>
7
8// For debugging
9#include <iostream>
10
11namespace Header
12{
13 template<typename S>
14 void hton(S &s)
15 {
16 std::transform(reinterpret_cast<uint16_t*>(&s),
17 reinterpret_cast<uint16_t*>(&s)+sizeof(S)/2,
18 reinterpret_cast<uint16_t*>(&s),
19 htons);
20 }
21
22 template<typename S>
23 void ntoh(S &s)
24 {
25 std::transform(reinterpret_cast<uint16_t*>(&s),
26 reinterpret_cast<uint16_t*>(&s)+sizeof(S)/2,
27 reinterpret_cast<uint16_t*>(&s),
28 ntohs);
29 }
30
31 template<typename S>
32 S NtoH(const S &s)
33 {
34 S ret(s);
35 ntoh(ret);
36 return ret;
37 }
38
39 template<typename S>
40 S HtoN(const S &s)
41 {
42 S ret(s);
43 hton(ret);
44 return ret;
45 }
46
47 template<typename S>
48 void reset(S &s)
49 {
50 memset(&s, 0, sizeof(S));
51 }
52
53 template<typename S>
54 void init(S &s)
55 {
56 if (sizeof(S)%2!=0)
57 throw std::logic_error("size of "+std::string(typeid(S).name())+" not a multiple of 2.");
58
59 reset(s);
60 }
61
62 template<typename S>
63 void ntohcpy(const std::vector<uint16_t> &vec, S &s)
64 {
65 if (sizeof(S)!=vec.size()*2)
66 throw std::logic_error("size of vector mismatch "+std::string(typeid(S).name()));
67
68 std::transform(vec.begin(), vec.end(),
69 reinterpret_cast<uint16_t*>(&s), ntohs);
70 }
71
72 template<typename S>
73 std::vector<uint16_t> htoncpy(const S &s)
74 {
75 if (sizeof(S)%2)
76 throw std::logic_error("size of "+std::string(typeid(S).name())+" not a multiple of 2");
77
78 std::vector<uint16_t> v(sizeof(S)/2);
79
80 std::transform(reinterpret_cast<const uint16_t*>(&s),
81 reinterpret_cast<const uint16_t*>(&s)+sizeof(S)/2,
82 v.begin(), htons);
83
84 return v;
85 }
86
87 template<typename T, typename S>
88 void bitcpy(T *target, size_t ntarget, const S *source, size_t nsource, size_t ss=0, size_t ts=0)
89 {
90 const size_t targetsize = ss==0 ? sizeof(T) : std::min(ss, sizeof(T));
91 const size_t sourcesize = ts==0 ? sizeof(S) : std::min(ts, sizeof(S));
92
93 const S *const ends = source + nsource;
94 const T *const endt = target + ntarget;
95
96 const S *s = source;
97 T *t = target;
98
99 memset(t, 0, sizeof(T)*ntarget);
100
101 size_t targetpos = 0;
102 size_t sourcepos = 0;
103
104 while (s<ends && t<endt)
105 {
106 // Start filling with "source size" - "position" bits
107 *t |= (*s>>sourcepos)<<targetpos;
108
109 // If not all bits fitted into targetsize the number
110 // of copied bits is the number of bits which fitted
111 const int n = std::min(sourcesize-sourcepos, targetsize-targetpos);
112
113 targetpos += n;
114 sourcepos += n;
115
116 if (sourcepos>=sourcesize)
117 s++;
118
119 if (targetpos>=targetsize)
120 t++;
121
122 sourcepos %= sourcesize;
123 targetpos %= targetsize;
124 }
125 }
126
127}
128
129// ====================================================================
130
131#include <ostream>
132
133namespace FTM
134{
135 using namespace Header;
136
137 enum States
138 {
139 kDisconnected = 1,
140 kConnected,
141 kIdle,
142 kTakingData,
143
144 // FTM internal states
145 kFtmIdle = 1,
146 kFtmConfig = 2,
147 kFtmRunning = 3,
148 kFtmCalib = 4,
149 };
150
151 enum Commands
152 {
153 kCmdRead = 0x0001,
154 kCmdWrite = 0x0002,
155 kCmdStartRun = 0x0004,
156 kCmdStopRun = 0x0008,
157 kCmdPing = 0x0010,
158 kCmdCrateReset = 0x0020,
159 kCmdDisableReports = 0x0040,
160 kCmdToggleLed = 0xc000,
161
162 kWriteStaticData = 0x0001,
163 kWriteRegister = 0x0004,
164
165 kReadStaticData = 0x0001,
166 kReadDynamicData = 0x0002,
167 kReadRegister = 0x0004,
168
169 kStartRun = 0x0001,
170 kTakeNevents = 0x0002,
171 };
172
173 enum Types
174 {
175 kHeader = 0, // Local extension to identify a header in fCounter
176 kStaticData = 1,
177 kDynamicData = 2,
178 kFtuList = 3,
179 kErrorList = 4,
180 kRegister = 5,
181 };
182
183 // --------------------------------------------------------------------
184
185 template<typename T>
186 void Reverse(T *t)
187 {
188 std::reverse((uint16_t*)t, ((uint16_t*)t)+sizeof(T)/2);
189 }
190
191 enum
192 {
193 kDelimiterStart = 0xfb01,
194 kDelimiterEnd = 0x04fe
195 };
196
197 struct Header
198 {
199 uint16_t fDelimiter; /// Start delimiter
200 uint16_t fType; /// Type of the data to be received after the header
201 uint16_t fDataSize; /// Size in words to be received after the header
202 uint16_t fState; /// State of the FTM state machine
203 uint64_t fBoardId;
204 uint16_t fFirmwareId;
205 uint32_t fTriggerCounter;
206 uint64_t fTimeStamp;
207
208 Header() { init(*this); }
209
210 std::vector<uint16_t> HtoN() const
211 {
212 Header h(*this);
213
214 Reverse(&h.fBoardId);
215 Reverse(&h.fTriggerCounter);
216 Reverse(&h.fTimeStamp);
217
218 return htoncpy(h);
219 }
220 void operator=(const std::vector<uint16_t> &vec)
221 {
222 ntohcpy(vec, *this);
223
224 Reverse(&fBoardId);
225 Reverse(&fTriggerCounter);
226 Reverse(&fTimeStamp);
227 }
228
229 void clear() { reset(*this); }
230 void print(std::ostream &out) const;
231
232 } __attribute__((__packed__));
233
234 struct DimPassport
235 {
236 uint64_t fBoardId;
237 uint16_t fFirmwareId;
238
239 DimPassport(const Header &h) :
240 fBoardId(h.fBoardId),
241 fFirmwareId(h.fFirmwareId)
242 {
243 }
244 } __attribute__((__packed__));
245
246 struct DimTriggerCounter
247 {
248 uint64_t fTimeStamp;
249 uint32_t fTriggerCounter;
250
251 DimTriggerCounter(const Header &h) :
252 fTimeStamp(h.fTimeStamp),
253 fTriggerCounter(h.fTriggerCounter)
254 {
255 }
256 } __attribute__((__packed__));
257
258
259 struct StaticDataBoard
260 {
261 uint16_t fEnable[4]; // 4x9bits
262 uint16_t fDAC[5]; // 4x12bit + 1xN/40
263 uint16_t fPrescaling;
264
265 StaticDataBoard() { init(*this); }
266
267 void print(std::ostream &out) const;
268
269 } __attribute__((__packed__));
270
271 struct StaticData
272 {
273 enum
274 {
275 kMaxCoincidence = 40,
276 kMaxWindow = 0xf,
277 kMaxDeadTime = 0xffff,
278 kMaxDelayTimeMarker = 0x3ff,
279 kMaxDelayTrigger = 0x3ff,
280 kMaxInterval = 0x3ff,
281 kMaskSequence = 0x7ff,
282 kMaskSettings = 0xf,
283 kMaskLEDs = 0xf,
284 };
285
286 enum GeneralSettings
287 {
288 kTrigger = 0x80,
289 kPedestal = 0x40,
290 kLP2 = 0x20,
291 kLP1 = 0x10,
292 kExt2 = 0x08,
293 kExt1 = 0x04,
294 kVeto = 0x02,
295 kTimeMarker = 0x01,
296 };
297
298 uint16_t fGeneralSettings; // only 8 bit used
299 uint16_t fStatusLEDs; // only 8 bit used
300 uint16_t fTriggerInterval; // only 10 bit used
301 uint16_t fTriggerSequence; // 3x5bit
302 uint64_t fDummy0;
303 uint16_t fCoincidencePhysics;
304 uint16_t fCoincidenceCalib;
305 uint16_t fDelayTrigger;
306 uint16_t fDelayTimeMarker;
307 uint16_t fDeadTime;
308 uint16_t fClockConditioner[8]; // R0, R1, R8, R9, R11, R13, R14, R15
309 uint16_t fWindowPhysics;
310 uint16_t fWindowCalib;
311 uint16_t fDummy1;
312
313 StaticDataBoard fBoard[4][10]; // 4 crates * 10 boards
314
315 uint16_t fActiveFTU[4];
316
317 StaticData() { init(*this); }
318
319 std::vector<uint16_t> HtoN() const
320 {
321 return htoncpy(*this);
322 }
323
324 void operator=(const std::vector<uint16_t> &vec)
325 {
326 ntohcpy(vec, *this);
327 }
328
329 void clear() { reset(*this); }
330 void print(std::ostream &out) const;
331
332 StaticDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
333 const StaticDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
334
335 } __attribute__((__packed__));
336
337 // DimStructures must be a multiple of two... I don't know why
338 struct DimStaticData
339 {
340 uint64_t fTimeStamp;
341 //8
342 uint16_t fGeneralSettings; // only 8 bit used
343 uint16_t fStatusLEDs; // only 8 bit used
344 uint64_t fActiveFTU; // 40 bits in row
345 //20
346 uint16_t fTriggerInterval; // only 10 bit used
347 //22
348 uint16_t fTriggerSeqLP1; // only 5bits used
349 uint16_t fTriggerSeqLP2; // only 5bits used
350 uint16_t fTriggerSeqPed; // only 5bits used
351 //28
352 uint16_t fCoincidencePhysics; // 0-40
353 uint16_t fCoincidenceCalib; // 0-40
354 //32
355 uint16_t fWindowPhysics;
356 uint16_t fWindowCalib;
357 //36
358 uint16_t fDelayTrigger;
359 uint16_t fDelayTimeMarker;
360 uint32_t fDeadTime;
361 //44
362 uint16_t fClockConditioner[8];
363 //60
364 uint16_t fEnable[80]; // 160*9bit = 180byte
365 uint16_t fThreshold[160];
366 uint16_t fMultiplicity[40]; // N out of 4
367 uint16_t fPrescaling[40];
368 // 640+60 = 700
369
370 bool HasTrigger() const { return fGeneralSettings & StaticData::kTrigger; }
371 bool HasPedestal() const { return fGeneralSettings & StaticData::kPedestal; }
372 bool HasLP2() const { return fGeneralSettings & StaticData::kLP2; }
373 bool HasLP1() const { return fGeneralSettings & StaticData::kLP1; }
374 bool HasExt2() const { return fGeneralSettings & StaticData::kExt2; }
375 bool HasExt1() const { return fGeneralSettings & StaticData::kExt1; }
376 bool HasVeto() const { return fGeneralSettings & StaticData::kVeto; }
377 bool HasTimeMarker() const { return fGeneralSettings & StaticData::kTimeMarker; }
378
379 bool IsActive(int i) const { return fActiveFTU&(1<<i); }
380 bool IsEnabled(int i) const { return fEnable[i/16]&(1<<(i%16)); }
381
382 DimStaticData() { memset(this, 0, sizeof(DimStaticData)); }
383
384 DimStaticData(const Header &h, const StaticData &d) :
385 fTimeStamp(h.fTimeStamp),
386 fGeneralSettings(d.fGeneralSettings),
387 fStatusLEDs(d.fStatusLEDs),
388 fActiveFTU(d.fActiveFTU[0] | (d.fActiveFTU[1]<<10) | (d.fActiveFTU[2]<<20) | (d.fActiveFTU[3]<<30)),
389 fTriggerInterval(d.fTriggerInterval*4+8),
390 fTriggerSeqLP1((d.fTriggerSequence)&0x1f),
391 fTriggerSeqLP2((d.fTriggerSequence>>5)&0x1f),
392 fTriggerSeqPed((d.fTriggerSequence>>10)&0x1f),
393 fCoincidencePhysics(d.fCoincidencePhysics),
394 fCoincidenceCalib(d.fCoincidenceCalib),
395 fWindowPhysics(d.fWindowPhysics*4+8),
396 fWindowCalib(d.fWindowCalib*4+8),
397 fDelayTrigger(d.fDelayTrigger*4+8),
398 fDelayTimeMarker(d.fDelayTimeMarker*4+8),
399 fDeadTime(uint32_t(d.fDeadTime)*4+8)
400 {
401 memcpy(fClockConditioner, d.fClockConditioner, sizeof(uint16_t)*8);
402
403 uint16_t src[160];
404 for (int i=0; i<40; i++)
405 {
406 for (int j=0; j<4; j++)
407 {
408 src[i*4+j] = d[i].fEnable[j];
409 fThreshold[i*4+j] = d[i].fDAC[j];
410 }
411
412 fMultiplicity[i] = d[i].fDAC[4];
413 fPrescaling[i] = d[i].fPrescaling;
414 }
415 bitcpy(fEnable, 80, src, 160, 9);
416 }
417
418 } __attribute__((__packed__));
419
420
421 struct DynamicDataBoard
422 {
423 uint32_t fRatePatch[4]; // Patch 0,1,2,3
424 uint32_t fRateTotal; // Sum
425
426 uint16_t fOverflow; // Patches: bits 0-3, total 4
427 uint16_t fCrcError;
428
429 void print(std::ostream &out) const;
430
431 void reverse()
432 {
433 for (int i=0; i<4; i++)
434 Reverse(fRatePatch+i);
435
436 Reverse(&fRateTotal);
437 }
438
439 uint32_t &operator[](int i) { return fRatePatch[i]; }
440
441 } __attribute__((__packed__));
442
443
444 struct DynamicData
445 {
446 uint64_t fOnTimeCounter;
447 uint16_t fTempSensor[4]; // U45, U46, U48, U49
448
449 DynamicDataBoard fBoard[4][10]; // 4 crates * 10 boards
450
451 DynamicData() { init(*this); }
452
453 std::vector<uint16_t> HtoN() const
454 {
455 DynamicData d(*this);
456
457 Reverse(&d.fOnTimeCounter);
458
459 for (int c=0; c<4; c++)
460 for (int b=0; b<10; b++)
461 d.fBoard[c][b].reverse();
462
463 return htoncpy(d);
464 }
465
466 void operator=(const std::vector<uint16_t> &vec)
467 {
468 ntohcpy(vec, *this);
469
470 Reverse(&fOnTimeCounter);
471
472 for (int c=0; c<4; c++)
473 for (int b=0; b<10; b++)
474 fBoard[c][b].reverse();
475 }
476
477 void clear() { reset(*this); }
478 void print(std::ostream &out) const;
479
480 DynamicDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
481 const DynamicDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
482
483 } __attribute__((__packed__));
484
485
486 struct DimDynamicData
487 {
488 uint64_t fTimeStamp;
489
490 uint64_t fOnTimeCounter;
491 float fTempSensor[4];
492
493 uint32_t fRatePatch[160];
494
495 uint32_t fRateBoard[40];
496 uint16_t fRateOverflow[40];
497
498 uint16_t fCrcError[40];
499
500 DimDynamicData(const Header &h, const DynamicData &d) :
501 fTimeStamp(h.fTimeStamp),
502 fOnTimeCounter(d.fOnTimeCounter)
503 {
504 for (int i=0; i<4; i++)
505 fTempSensor[i] = d.fTempSensor[i];
506
507 for (int i=0; i<40; i++)
508 {
509 fRateBoard[i] = d[i].fRateTotal;
510 fRateOverflow[i] = d[i].fOverflow;
511 fCrcError[i] = d[i].fCrcError;
512 for (int j=0; j<4; j++)
513 fRatePatch[i*4+j] = d[i].fRatePatch[j];
514 }
515 }
516
517 } __attribute__((__packed__));
518
519
520 struct FtuResponse
521 {
522 uint16_t fPingAddr; // Number of Pings and addr (pings= see error)
523 uint64_t fDNA;
524 uint16_t fErrorCounter; //
525
526 void reverse() { Reverse(&fDNA); }
527
528 void print(std::ostream &out) const;
529
530 } __attribute__((__packed__));
531
532 struct FtuList
533 {
534 uint16_t fNumBoards; /// Total number of boards responded
535 uint16_t fNumBoardsCrate[4]; /// Num of board responded in crate 0-3
536 uint16_t fActiveFTU[4]; /// List of active FTU boards in crate 0-3
537
538 FtuResponse fFTU[4][10];
539
540 FtuList() { init(*this); }
541
542 std::vector<uint16_t> HtoN() const
543 {
544 FtuList d(*this);
545
546 for (int c=0; c<4; c++)
547 for (int b=0; b<10; b++)
548 d.fFTU[c][b].reverse();
549
550 return htoncpy(d);
551 }
552
553 void operator=(const std::vector<uint16_t> &vec)
554 {
555 ntohcpy(vec, *this);
556
557 for (int c=0; c<4; c++)
558 for (int b=0; b<10; b++)
559 fFTU[c][b].reverse();
560 }
561
562 void clear() { reset(*this); }
563 void print(std::ostream &out) const;
564
565 FtuResponse &operator[](int i) { return fFTU[i/10][i%10]; }
566 const FtuResponse &operator[](int i) const { return fFTU[i/10][i%10]; }
567
568 } __attribute__((__packed__));
569
570 struct DimFtuList
571 {
572 uint64_t fTimeStamp;
573 uint64_t fActiveFTU;
574
575 uint16_t fNumBoards; /// Number of boards answered in total
576 uint8_t fNumBoardsCrate[4]; /// Number of boards answered per crate
577
578 uint64_t fDNA[40]; /// DNA of FTU board
579 uint8_t fAddr[40]; /// Address of FTU board
580 uint8_t fPing[40]; /// Number of pings until response (same as in Error)
581
582 DimFtuList(const Header &h, const FtuList &d) :
583 fTimeStamp(h.fTimeStamp),
584 fActiveFTU(d.fActiveFTU[0] | (d.fActiveFTU[1]<<10) | (d.fActiveFTU[2]<<20) | (d.fActiveFTU[3]<<30)),
585 fNumBoards(d.fNumBoards)
586 {
587 for (int i=0; i<4; i++)
588 fNumBoardsCrate[i] = d.fNumBoardsCrate[i];
589
590 for (int i=0; i<40; i++)
591 {
592 fDNA[i] = d[i].fDNA;
593 fAddr[i] = d[i].fPingAddr&0x3f;
594 fPing[i] = (d[i].fPingAddr>>8)&0x3;
595 }
596 }
597
598 bool IsActive(int i) const { return fActiveFTU&(1<<i); }
599
600 } __attribute__((__packed__));
601
602
603 struct Error
604 {
605 uint16_t fNumCalls; // 0=error, >1 needed repetition but successfull
606
607 uint16_t fDelimiter;
608 uint16_t fDestAddress;
609 uint16_t fSrcAddress;
610 uint16_t fFirmwareId;
611 uint16_t fCommand;
612 uint16_t fData[21];
613 uint16_t fCrcErrorCounter;
614 uint16_t fCrcCheckSum;
615
616 Error() { init(*this); }
617
618 std::vector<uint16_t> HtoN() const
619 {
620 return htoncpy(*this);
621 }
622
623 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
624
625 void clear() { reset(*this); }
626
627 uint16_t &operator[](int idx) { return fData[idx]; }
628 const uint16_t &operator[](int idx) const { return fData[idx]; }
629
630 void print(std::ostream &out) const;
631
632 } __attribute__((__packed__));
633
634 struct DimError
635 {
636 uint64_t fTimeStamp;
637 Error fError;
638
639 DimError(const Header &h, const Error &e) :
640 fTimeStamp(h.fTimeStamp),
641 fError(e)
642 {
643 fError.fDestAddress = (e.fDestAddress&0x3)*10 + ((e.fDestAddress>>2)&0xf);
644 fError.fSrcAddress = (e.fSrcAddress &0x3)*10 + ((e.fSrcAddress >>2)&0xf);
645 }
646
647 } __attribute__((__packed__));
648
649 /*
650 struct Command
651 {
652 uint16_t fStartDelimiter;
653 uint16_t fCommand;
654 uint16_t fParam[3];
655
656 Command() { init(*this); }
657
658 void HtoN() { hton(*this); }
659 void NtoH() { ntoh(*this); }
660
661 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
662
663 void clear() { reset(*this); }
664
665
666 } __attribute__((__packed__));
667 */
668
669 // --------------------------------------------------------------------
670
671 inline std::ostream &operator<<(std::ostream &out, const FtuResponse &h)
672 {
673 h.print(out);
674 return out;
675 }
676
677 inline std::ostream &operator<<(std::ostream &out, const Header &h)
678 {
679 h.print(out);
680 return out;
681 }
682
683
684 inline std::ostream &operator<<(std::ostream &out, const FtuList &h)
685 {
686 h.print(out);
687 return out;
688 }
689
690 inline std::ostream &operator<<(std::ostream &out, const DynamicDataBoard &h)
691 {
692 h.print(out);
693 return out;
694 }
695
696 inline std::ostream &operator<<(std::ostream &out, const DynamicData &h)
697 {
698 h.print(out);
699 return out;
700 }
701
702 inline std::ostream &operator<<(std::ostream &out, const StaticDataBoard &h)
703 {
704 h.print(out);
705 return out;
706 }
707
708 inline std::ostream &operator<<(std::ostream &out, const StaticData &h)
709 {
710 h.print(out);
711 return out;
712 }
713
714 inline std::ostream &operator<<(std::ostream &out, const Error &h)
715 {
716 h.print(out);
717 return out;
718 }
719};
Note: See TracBrowser for help on using the repository browser.