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

Last change on this file since 10525 was 10525, checked in by tbretz, 14 years ago
Added Number of responding boards and boards in crate to DimFtuList
File size: 19.2 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 std::cout << "-----><-----" << std::endl;
322 return htoncpy(*this);
323 }
324
325 void operator=(const std::vector<uint16_t> &vec)
326 {
327 std::cout << "-----<>-----" << std::endl;
328
329 ntohcpy(vec, *this);
330 }
331
332 void clear() { reset(*this); }
333 void print(std::ostream &out) const;
334
335 StaticDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
336 const StaticDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
337
338 } __attribute__((__packed__));
339
340 // DimStructures must be a multiple of two... I don't know why
341 struct DimStaticData
342 {
343 uint64_t fTimeStamp;
344 //8
345 uint16_t fGeneralSettings; // only 8 bit used
346 uint16_t fStatusLEDs; // only 8 bit used
347 uint64_t fActiveFTU; // 40 bits in row
348 //20
349 uint16_t fTriggerInterval; // only 10 bit used
350 //22
351 uint16_t fTriggerSeqLP1; // only 5bits used
352 uint16_t fTriggerSeqLP2; // only 5bits used
353 uint16_t fTriggerSeqPed; // only 5bits used
354 //28
355 uint16_t fCoincidencePhysics; // 0-40
356 uint16_t fCoincidenceCalib; // 0-40
357 //32
358 uint16_t fWindowPhysics;
359 uint16_t fWindowCalib;
360 //36
361 uint16_t fDelayTrigger;
362 uint16_t fDelayTimeMarker;
363 uint32_t fDeadTime;
364 //44
365 uint16_t fClockConditioner[8];
366 //60
367 uint16_t fEnable[80]; // 160*9bit = 180byte
368 uint16_t fThreshold[160];
369 uint16_t fMultiplicity[40]; // N out of 4
370 uint16_t fPrescaling[40];
371 // 640+60 = 700
372
373 bool HasTrigger() const { return fGeneralSettings & StaticData::kTrigger; }
374 bool HasPedestal() const { return fGeneralSettings & StaticData::kPedestal; }
375 bool HasLP2() const { return fGeneralSettings & StaticData::kLP2; }
376 bool HasLP1() const { return fGeneralSettings & StaticData::kLP1; }
377 bool HasExt2() const { return fGeneralSettings & StaticData::kExt2; }
378 bool HasExt1() const { return fGeneralSettings & StaticData::kExt1; }
379 bool HasVeto() const { return fGeneralSettings & StaticData::kVeto; }
380 bool HasTimeMarker() const { return fGeneralSettings & StaticData::kTimeMarker; }
381
382 bool IsActive(int i) const { return fActiveFTU&(1<<i); }
383 bool IsEnabled(int i) const { return fEnable[i/16]&(1<<(i%16)); }
384
385 DimStaticData() { memset(this, 0, sizeof(DimStaticData)); }
386
387 DimStaticData(const Header &h, const StaticData &d) :
388 fTimeStamp(h.fTimeStamp),
389 fGeneralSettings(d.fGeneralSettings),
390 fStatusLEDs(d.fStatusLEDs),
391 fActiveFTU(d.fActiveFTU[0] | (d.fActiveFTU[1]<<10) | (d.fActiveFTU[2]<<20) | (d.fActiveFTU[3]<<30)),
392 fTriggerInterval(d.fTriggerInterval*4+8),
393 fTriggerSeqLP1((d.fTriggerSequence)&0x1f),
394 fTriggerSeqLP2((d.fTriggerSequence>>5)&0x1f),
395 fTriggerSeqPed((d.fTriggerSequence>>10)&0x1f),
396 fCoincidencePhysics(d.fCoincidencePhysics),
397 fCoincidenceCalib(d.fCoincidenceCalib),
398 fWindowPhysics(d.fWindowPhysics*4+8),
399 fWindowCalib(d.fWindowCalib*4+8),
400 fDelayTrigger(d.fDelayTrigger*4+8),
401 fDelayTimeMarker(d.fDelayTimeMarker*4+8),
402 fDeadTime(uint32_t(d.fDeadTime)*4+8)
403 {
404 memcpy(fClockConditioner, d.fClockConditioner, sizeof(uint16_t)*8);
405
406 uint16_t src[160];
407 for (int i=0; i<40; i++)
408 {
409 for (int j=0; j<4; j++)
410 {
411 src[i*4+j] = d[i].fEnable[j];
412 fThreshold[i*4+j] = d[i].fDAC[j];
413 }
414
415 fMultiplicity[i] = d[i].fDAC[4];
416 fPrescaling[i] = d[i].fPrescaling;
417 }
418 bitcpy(fEnable, 80, src, 160, 9);
419 }
420
421 } __attribute__((__packed__));
422
423
424 struct DynamicDataBoard
425 {
426 uint32_t fRatePatch[4]; // Patch 0,1,2,3
427 uint32_t fRateTotal; // Sum
428
429 uint16_t fOverflow; // Patches: bits 0-3, total 4
430 uint16_t fCrcError;
431
432 void print(std::ostream &out) const;
433
434 void reverse()
435 {
436 for (int i=0; i<4; i++)
437 Reverse(fRatePatch+i);
438
439 Reverse(&fRateTotal);
440 }
441
442 uint32_t &operator[](int i) { return fRatePatch[i]; }
443
444 } __attribute__((__packed__));
445
446
447 struct DynamicData
448 {
449 uint64_t fOnTimeCounter;
450 uint16_t fTempSensor[4]; // U45, U46, U48, U49
451
452 DynamicDataBoard fBoard[4][10]; // 4 crates * 10 boards
453
454 DynamicData() { init(*this); }
455
456 std::vector<uint16_t> HtoN() const
457 {
458 DynamicData d(*this);
459
460 Reverse(&d.fOnTimeCounter);
461
462 for (int c=0; c<4; c++)
463 for (int b=0; b<10; b++)
464 d.fBoard[c][b].reverse();
465
466 return htoncpy(d);
467 }
468
469 void operator=(const std::vector<uint16_t> &vec)
470 {
471 ntohcpy(vec, *this);
472
473 Reverse(&fOnTimeCounter);
474
475 for (int c=0; c<4; c++)
476 for (int b=0; b<10; b++)
477 fBoard[c][b].reverse();
478 }
479
480 void clear() { reset(*this); }
481 void print(std::ostream &out) const;
482
483 DynamicDataBoard &operator[](int i) { return fBoard[i/10][i%10]; }
484 const DynamicDataBoard &operator[](int i) const { return fBoard[i/10][i%10]; }
485
486 } __attribute__((__packed__));
487
488
489 struct DimDynamicData
490 {
491 uint64_t fTimeStamp;
492
493 uint64_t fOnTimeCounter;
494 float fTempSensor[4];
495
496 uint32_t fRatePatch[160];
497
498 uint32_t fRateBoard[40];
499 uint16_t fRateOverflow[40];
500
501 uint16_t fCrcError[40];
502
503 DimDynamicData(const Header &h, const DynamicData &d) :
504 fTimeStamp(h.fTimeStamp),
505 fOnTimeCounter(d.fOnTimeCounter)
506 {
507 for (int i=0; i<4; i++)
508 fTempSensor[i] = d.fTempSensor[i];
509
510 for (int i=0; i<40; i++)
511 {
512 fRateBoard[i] = d[i].fRateTotal;
513 fRateOverflow[i] = d[i].fOverflow;
514 fCrcError[i] = d[i].fCrcError;
515 for (int j=0; j<4; j++)
516 fRatePatch[i*4+j] = d[i].fRatePatch[j];
517 }
518 }
519
520 } __attribute__((__packed__));
521
522
523 struct FtuResponse
524 {
525 uint16_t fPingAddr; // Number of Pings and addr (pings= see error)
526 uint64_t fDNA;
527 uint16_t fErrorCounter; //
528
529 void reverse() { Reverse(&fDNA); }
530
531 void print(std::ostream &out) const;
532
533 } __attribute__((__packed__));
534
535 struct FtuList
536 {
537 uint16_t fNumBoards; /// Total number of boards responded
538 uint16_t fNumBoardsCrate[4]; /// Num of board responded in crate 0-3
539 uint16_t fActiveFTU[4]; /// List of active FTU boards in crate 0-3
540
541 FtuResponse fFTU[4][10];
542
543 FtuList() { init(*this); }
544
545 std::vector<uint16_t> HtoN() const
546 {
547 FtuList d(*this);
548
549 for (int c=0; c<4; c++)
550 for (int b=0; b<10; b++)
551 d.fFTU[c][b].reverse();
552
553 return htoncpy(d);
554 }
555
556 void operator=(const std::vector<uint16_t> &vec)
557 {
558 ntohcpy(vec, *this);
559
560 for (int c=0; c<4; c++)
561 for (int b=0; b<10; b++)
562 fFTU[c][b].reverse();
563 }
564
565 void clear() { reset(*this); }
566 void print(std::ostream &out) const;
567
568 FtuResponse &operator[](int i) { return fFTU[i/10][i%10]; }
569 const FtuResponse &operator[](int i) const { return fFTU[i/10][i%10]; }
570
571 } __attribute__((__packed__));
572
573 struct DimFtuList
574 {
575 uint64_t fTimeStamp;
576 uint64_t fActiveFTU;
577
578 uint16_t fNumBoards; /// Number of boards answered in total
579 uint8_t fNumBoardsCrate[4]; /// Number of boards answered per crate
580
581 uint64_t fDNA[40]; /// DNA of FTU board
582 uint8_t fAddr[40]; /// Address of FTU board
583 uint8_t fPing[40]; /// Number of pings until response (same as in Error)
584
585 DimFtuList(const Header &h, const FtuList &d) :
586 fTimeStamp(h.fTimeStamp),
587 fActiveFTU(d.fActiveFTU[0] | (d.fActiveFTU[1]<<10) | (d.fActiveFTU[2]<<20) | (d.fActiveFTU[3]<<30)),
588 fNumBoards(d.fNumBoards)
589 {
590 for (int i=0; i<4; i++)
591 fNumBoardsCrate[i] = d.fNumBoardsCrate[i];
592
593 for (int i=0; i<40; i++)
594 {
595 fDNA[i] = d[i].fDNA;
596 fAddr[i] = d[i].fPingAddr&0x3f;
597 fPing[i] = (d[i].fPingAddr>>8)&0x3;
598 }
599 }
600
601 bool IsActive(int i) const { return fActiveFTU&(1<<i); }
602
603 } __attribute__((__packed__));
604
605
606 struct Error
607 {
608 // (same as FtuList)
609 uint16_t fNumCalls; // 0=error, >1 needed repetition but successfull
610 uint16_t fData[28];
611
612 Error() { init(*this); }
613
614 std::vector<uint16_t> HtoN() const
615 {
616 return htoncpy(*this);
617 }
618
619 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
620
621 void clear() { reset(*this); }
622
623 uint16_t &operator[](int idx) { return fData[idx]; }
624 const uint16_t &operator[](int idx) const { return fData[idx]; }
625
626 void print(std::ostream &out) const;
627
628 } __attribute__((__packed__));
629
630 struct DimError
631 {
632 uint64_t fTimeStamp;
633 Error fError;
634
635 DimError(const Header &h, const Error &e) :
636 fTimeStamp(h.fTimeStamp),
637 fError(e)
638 {
639 }
640 } __attribute__((__packed__));
641
642 /*
643 struct Command
644 {
645 uint16_t fStartDelimiter;
646 uint16_t fCommand;
647 uint16_t fParam[3];
648
649 Command() { init(*this); }
650
651 void HtoN() { hton(*this); }
652 void NtoH() { ntoh(*this); }
653
654 void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
655
656 void clear() { reset(*this); }
657
658
659 } __attribute__((__packed__));
660 */
661
662 // --------------------------------------------------------------------
663
664 inline std::ostream &operator<<(std::ostream &out, const FtuResponse &h)
665 {
666 h.print(out);
667 return out;
668 }
669
670 inline std::ostream &operator<<(std::ostream &out, const Header &h)
671 {
672 h.print(out);
673 return out;
674 }
675
676
677 inline std::ostream &operator<<(std::ostream &out, const FtuList &h)
678 {
679 h.print(out);
680 return out;
681 }
682
683 inline std::ostream &operator<<(std::ostream &out, const DynamicDataBoard &h)
684 {
685 h.print(out);
686 return out;
687 }
688
689 inline std::ostream &operator<<(std::ostream &out, const DynamicData &h)
690 {
691 h.print(out);
692 return out;
693 }
694
695 inline std::ostream &operator<<(std::ostream &out, const StaticDataBoard &h)
696 {
697 h.print(out);
698 return out;
699 }
700
701 inline std::ostream &operator<<(std::ostream &out, const StaticData &h)
702 {
703 h.print(out);
704 return out;
705 }
706
707 inline std::ostream &operator<<(std::ostream &out, const Error &h)
708 {
709 h.print(out);
710 return out;
711 }
712};
Note: See TracBrowser for help on using the repository browser.