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

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