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

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