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

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