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

Last change on this file since 10520 was 10520, checked in by tbretz, 9 years ago
File size: 19.0 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
524    struct FtuResponse
525    {
526        uint16_t fPingAddr;
527        uint64_t fDNA;
528        uint16_t fErrorCounter;
529
530        void reverse() { Reverse(&fDNA); }
531
532        void print(std::ostream &out) const;
533
534    } __attribute__((__packed__));
535
536
537    struct FtuList
538    {
539        uint16_t fNumBoards;         /// Total number of boards responded
540        uint16_t fNumBoardsCrate[4]; /// Num of board responded in crate 0-3
541        uint16_t fActiveFTU[4];      /// List of active FTU boards in crate 0-3
542
543        FtuResponse fFTU[4][10];
544                         
545        FtuList() { init(*this); }
546
547        std::vector<uint16_t> HtoN() const
548        {
549            FtuList d(*this);
550
551            for (int c=0; c<4; c++)
552                for (int b=0; b<10; b++)
553                    d.fFTU[c][b].reverse();
554
555            return htoncpy(d);
556        }
557
558        void operator=(const std::vector<uint16_t> &vec)
559        {
560            ntohcpy(vec, *this);
561
562            for (int c=0; c<4; c++)
563                for (int b=0; b<10; b++)
564                    fFTU[c][b].reverse();
565        }
566
567        void clear() { reset(*this); }
568        void print(std::ostream &out) const;
569
570        FtuResponse &operator[](int i) { return fFTU[i/10][i%10]; }
571        const FtuResponse &operator[](int i) const { return fFTU[i/10][i%10]; }
572
573    } __attribute__((__packed__));
574
575    struct DimFtuList
576    {
577        uint64_t fTimeStamp;
578        uint64_t fActiveFTU;
579
580        uint16_t fNumBoards;          /// Number of boards answered in total
581        uint8_t  fNumBoardsCrate[4];  /// Number of boards answered per crate
582
583        uint64_t fDNA[40];            /// DNA of FTU board
584        uint8_t  fAddr[40];           /// Address of FTU board
585        uint8_t  fPing[40];           /// Number of pings until response
586
587        DimFtuList(const Header &h, const FtuList &d) :
588            fTimeStamp(h.fTimeStamp),
589            fActiveFTU(d.fActiveFTU[0] | (d.fActiveFTU[1]<<10) | (d.fActiveFTU[2]<<20) | (d.fActiveFTU[3]<<30))
590        {
591            for (int i=0; i<40; i++)
592            {
593                fDNA[i]  =  d[i].fDNA;
594                fAddr[i] =  d[i].fPingAddr&0x3f;
595                fPing[i] = (d[i].fPingAddr>>8)&0x3;
596            }
597        }
598
599        bool IsActive(int i) const { return fActiveFTU&(1<<i); }
600
601    } __attribute__((__packed__));
602
603
604    struct Error
605    {
606        uint16_t fNumCalls;    // Number or unsuccessfull calls
607        uint16_t fData[28];
608
609        Error() { init(*this); }
610
611        std::vector<uint16_t> HtoN() const
612        {
613            return htoncpy(*this);
614        }
615
616        void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
617
618        void clear() { reset(*this); }
619
620        uint16_t &operator[](int idx) { return fData[idx]; }
621        const uint16_t &operator[](int idx) const { return fData[idx]; }
622
623        void print(std::ostream &out) const;
624
625    } __attribute__((__packed__));
626
627    struct DimError
628    {
629        uint64_t fTimeStamp;
630        Error    fError;
631
632        DimError(const Header &h, const Error &e) :
633            fTimeStamp(h.fTimeStamp),
634            fError(e)
635        {
636        }
637    }  __attribute__((__packed__));
638
639    /*
640    struct Command
641    {
642        uint16_t fStartDelimiter;
643        uint16_t fCommand;
644        uint16_t fParam[3];
645
646        Command() { init(*this); }
647
648        void HtoN() { hton(*this); }
649        void NtoH() { ntoh(*this); }
650
651        void operator=(const std::vector<uint16_t> &vec) { ntohcpy(vec, *this); }
652
653        void clear() { reset(*this); }
654
655
656     } __attribute__((__packed__));
657    */
658
659    // --------------------------------------------------------------------
660
661    inline std::ostream &operator<<(std::ostream &out, const FtuResponse &h)
662    {
663        h.print(out);
664        return out;
665    }
666
667    inline std::ostream &operator<<(std::ostream &out, const Header &h)
668    {
669        h.print(out);
670        return out;
671    }
672
673
674    inline std::ostream &operator<<(std::ostream &out, const FtuList &h)
675    {
676        h.print(out);
677        return out;
678    }
679
680    inline std::ostream &operator<<(std::ostream &out, const DynamicDataBoard &h)
681    {
682        h.print(out);
683        return out;
684    }
685
686    inline std::ostream &operator<<(std::ostream &out, const DynamicData &h)
687    {
688        h.print(out);
689        return out;
690    }
691
692    inline std::ostream &operator<<(std::ostream &out, const StaticDataBoard &h)
693    {
694        h.print(out);
695        return out;
696    }
697
698    inline std::ostream &operator<<(std::ostream &out, const StaticData &h)
699    {
700        h.print(out);
701        return out;
702    }
703
704    inline std::ostream &operator<<(std::ostream &out, const Error &h)
705    {
706        h.print(out);
707        return out;
708    }
709};
Note: See TracBrowser for help on using the repository browser.