Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:38

0001 #ifndef DTDigi_DTDDUWords_h
0002 #define DTDigi_DTDDUWords_h
0003 
0004 /** \file
0005  * MASKS and SHIFTS definition. Documentation at:
0006  *
0007  * https://uimon.cern.ch/twiki/bin/view/CMS/FEDDataFormats
0008  */
0009 
0010 #define WORDCONTROLMASK 0xE0000000
0011 #define WORDCONTROLSHIFT 29
0012 #define WORDTYPEMASK 0x1F000000
0013 #define WORDTYPESHIFT 24
0014 
0015 /// to distinguish between ROS and TDC error
0016 #define ERRORMASK 0x8000
0017 #define ERRORSHIFT 15
0018 
0019 #define DEBUG_TYPE_MASK 0xE00000
0020 #define DEBUG_TYPE_SHIFT 21
0021 #define DEBUG_MESSAGE_MASK 0x7FFF
0022 #define CEROS_ID_CEROS_STATUS_MASK 0x1F0000
0023 #define CEROS_ID_CEROS_STATUS_SHIFT 16
0024 #define EV_ID_CEROS_STATUS_MASK 0xFC0
0025 #define EV_ID_CEROS_STATUS_SHIFT 6
0026 #define DONTREAD_CEROS_STATUS_MASK 0x3F
0027 #define CEROS_ID_ROS_STATUS_MASK 0x1F
0028 
0029 #define TTC_EVENT_COUNTER_MASK 0xFFFFFF
0030 
0031 #define TFF_MASK 0x800000
0032 #define TFF_SHIFT 23
0033 #define TPX_MASK 0x400000
0034 #define TPX_SHIFT 22
0035 #define L1A_FIFO_OCC_MASK 0x3F0000
0036 #define L1A_FIFO_OCC_SHIFT 16
0037 #define EVENT_WORD_COUNT_MASK 0xFFFF
0038 
0039 #define ERROR_TYPE_MASK 0xE00000
0040 #define ERROR_TYPE_SHIFT 21
0041 #define ERROR_ROB_ID_MASK 0x1F0000
0042 #define ERROR_ROB_ID_SHIFT 16
0043 #define ERROR_CEROS_ID_MASK 0x3F
0044 
0045 #define ROB_ID_MASK 0x1F000000
0046 #define EVENT_ID_MASK 0xFFF000
0047 #define EVENT_ID_SHIFT 12
0048 #define BUNCH_ID_MASK 0xFFF
0049 #define WORD_COUNT_MASK 0xFFF
0050 
0051 #define PC_MASK 0x8000000
0052 #define PC_SHIFT 27
0053 #define PAF_MASK 0x4000000
0054 #define PAF_SHIFT 26
0055 #define TDC_ID_MASK 0x3000000
0056 #define TDC_ID_SHIFT 24
0057 
0058 #define TDC_CHANNEL_MASK 0xF80000
0059 #define TDC_CHANNEL_SHIFT 19
0060 #define TDC_TIME_MASK 0x7FFFC  // First two bits are excluded
0061 #define TDC_TIME_SHIFT 2
0062 
0063 #define TDC_ERROR_MASK 0x7FFF
0064 
0065 #define SCFO_MASK 0xFF
0066 
0067 #define TRIGGER_WORD_COUNT_MASK 0xFFFF
0068 
0069 #define TRIGGER_DATA_MASK 0xFFFF
0070 
0071 #define SC_LAT_SHIFT 8
0072 #define SC_LAT_MASK 0x7F
0073 
0074 #define SC_NW_MASK 0xFF
0075 
0076 #define SC_TRIGGERDLY_MASK 0x7
0077 #define SC_TRIGGERDLY_SHIFT 12
0078 #define SC_BXC_MASK 0xFFF
0079 
0080 #include <iostream>
0081 #include <cstdint>
0082 
0083 /** \class DTROSWordType
0084  *  Enumeration of DT Read Out Sector (ROS) word types.
0085  *
0086  * \author M. Zanetti - INFN Padova
0087  */
0088 class DTROSWordType {
0089 public:
0090   /// Constructor
0091   DTROSWordType(const uint32_t index) { word_ = index; }
0092 
0093   DTROSWordType(const DTROSWordType& obj) { *this = obj; }
0094 
0095   DTROSWordType() : word_(0){};
0096 
0097   /// Destructor
0098   virtual ~DTROSWordType(){};
0099 
0100   /// List of DT DDU Word Types
0101   enum wordTypes {
0102     ROSHeader = 1,
0103     ROSTrailer = 2,
0104     ROSError = 3,
0105     GroupHeader = 4,
0106     GroupTrailer = 5,
0107     TDCHeader = 6,
0108     TDCTrailer = 7,
0109     TDCMeasurement = 8,
0110     TDCError = 9,
0111     SCHeader = 10,
0112     SCTrailer = 11,
0113     SCData = 12,
0114     ROSDebug = 13,
0115     TDCDebug = 14,
0116     Control = 15
0117   };
0118 
0119   /// DDU word type getter
0120   enum wordTypes type() {
0121     enum wordTypes wordType = Control;
0122 
0123     // ROS/ROB/SC Headers
0124     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == headerControlWord) {
0125       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == rosTypeWord)
0126         wordType = ROSHeader;
0127       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == scTypeWord)
0128         wordType = SCHeader;
0129       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) < scTypeWord)
0130         wordType = GroupHeader;
0131     }
0132 
0133     // ROS/ROB/SC Trailers
0134     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == trailerControlWord) {
0135       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == rosTypeWord)
0136         wordType = ROSTrailer;
0137       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == scTypeWord)
0138         wordType = SCTrailer;
0139       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) < scTypeWord)
0140         wordType = GroupTrailer;
0141     }
0142 
0143     // TDC Header
0144     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == tdcHeaderControlWord)
0145       wordType = TDCHeader;
0146 
0147     // TDC Trailer
0148     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == tdcTrailerControlWord)
0149       wordType = TDCTrailer;
0150 
0151     // TDC/SC Data
0152     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == tdcDataControlWord) {
0153       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == scTypeWord)
0154         wordType = SCData;
0155       else
0156         wordType = TDCMeasurement;
0157     }
0158 
0159     // Errors
0160     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == errorControlWord) {
0161       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == rosTypeWord)
0162         wordType = ROSError;
0163       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) < scTypeWord)
0164         wordType = TDCError;
0165     }
0166 
0167     // ROS Debug
0168     if (((word_ & WORDCONTROLMASK) >> WORDCONTROLSHIFT) == debugControlWord) {
0169       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) == rosTypeWord)
0170         wordType = ROSDebug;
0171       if (((word_ & WORDTYPEMASK) >> WORDTYPESHIFT) < scTypeWord)
0172         wordType = TDCDebug;
0173     }
0174 
0175     return wordType;
0176   }
0177 
0178   /// Control bits definitions
0179   static const uint32_t headerControlWord = 0;
0180   static const uint32_t trailerControlWord = 1;
0181   static const uint32_t tdcHeaderControlWord = 2;
0182   static const uint32_t tdcTrailerControlWord = 3;
0183   static const uint32_t tdcDataControlWord = 4;
0184   static const uint32_t errorControlWord = 6;
0185   static const uint32_t debugControlWord = 7;
0186 
0187   /// Word Type bits definitions
0188   static const uint32_t rosTypeWord = 31;
0189   static const uint32_t scTypeWord = 25;
0190 
0191 private:
0192   uint32_t word_;
0193 };
0194 
0195 /** \class DTROSHeaderWord
0196  *  DT ROS Header interpreter. 
0197  *  It interprets the TTC Event counter (24 bits).
0198  *
0199  * \author M. Zanetti - INFN Padova
0200  */
0201 class DTROSHeaderWord {
0202 public:
0203   /// Constructor
0204   DTROSHeaderWord() {}
0205 
0206   DTROSHeaderWord(const DTROSHeaderWord& obj) { *this = obj; }
0207 
0208   DTROSHeaderWord(const uint32_t index) : word_(index) {}
0209 
0210   /// Destructor
0211   virtual ~DTROSHeaderWord() {}
0212 
0213   int TTCEventCounter() const { return word_ & TTC_EVENT_COUNTER_MASK; }
0214 
0215   static void set(uint32_t& word, int ttc_event_counter) {
0216     word = DTROSWordType::headerControlWord << WORDCONTROLSHIFT | DTROSWordType::rosTypeWord << WORDTYPESHIFT |
0217            ttc_event_counter;
0218   }
0219 
0220 private:
0221   uint32_t word_;
0222 };
0223 
0224 /** \class DTROSTrailerWord
0225  *  DT ROS Trailer interpreter. 
0226  *  Information interpreted: 
0227  *  - TFF: L1 FIFO is full (1 bit)
0228  *  - TPX: Transmitter parity (1 bit)
0229  *  - L1A FIFO occupancy  (6 bits)
0230  *  - Event Word count (16 bits)
0231  *
0232  * \author M. Zanetti - INFN Padova
0233  */
0234 class DTROSTrailerWord {
0235 public:
0236   /// Constructor
0237   DTROSTrailerWord() {}
0238 
0239   DTROSTrailerWord(const DTROSTrailerWord& obj) { *this = obj; }
0240 
0241   DTROSTrailerWord(const uint32_t index) : word_(index) {}
0242 
0243   /// Destructor
0244   virtual ~DTROSTrailerWord() {}
0245 
0246   int TFF() const { return (word_ & TFF_MASK) >> TFF_SHIFT; }
0247   int TPX() const { return (word_ & TPX_MASK) >> TPX_SHIFT; }
0248   int l1AFifoOccupancy() const { return (word_ & L1A_FIFO_OCC_MASK) >> L1A_FIFO_OCC_SHIFT; }
0249   int EventWordCount() const { return word_ & EVENT_WORD_COUNT_MASK; }
0250 
0251   static void set(uint32_t& word, int tff, int tpx, int l1a_fifo_occ, int event_word_count) {
0252     word = DTROSWordType::trailerControlWord << WORDCONTROLSHIFT | DTROSWordType::rosTypeWord << WORDTYPESHIFT |
0253            tff << TFF_SHIFT | tpx << TPX_SHIFT | l1a_fifo_occ << L1A_FIFO_OCC_SHIFT | event_word_count;
0254   }
0255 
0256 private:
0257   uint32_t word_;
0258 };
0259 
0260 /** \class DTROSErrorWord
0261  *  DT ROS Error interpreter. 
0262  *  It interprets the Error type, the ROB_ID (2 bits) and the CEROS ID (6 bits)
0263  *
0264  * \author M. Zanetti - INFN Padova
0265  */
0266 class DTROSErrorWord {
0267 public:
0268   /// Constructor
0269   DTROSErrorWord() {}
0270 
0271   DTROSErrorWord(const DTROSErrorWord& obj) { *this = obj; }
0272 
0273   DTROSErrorWord(const uint32_t index) : word_(index) {}
0274 
0275   /// Destructor
0276   virtual ~DTROSErrorWord() {}
0277 
0278   int errorType() const { return (word_ & ERROR_TYPE_MASK) >> ERROR_TYPE_SHIFT; }
0279   int robID() const { return (word_ & ERROR_ROB_ID_MASK) >> ERROR_ROB_ID_SHIFT; }
0280   int cerosID() const { return errorType() == 4 ? (word_ & ERROR_CEROS_ID_MASK) : 0; }
0281 
0282   static void set(uint32_t& word, int error_type, int rob_id) {
0283     word = DTROSWordType::errorControlWord << WORDCONTROLSHIFT | DTROSWordType::rosTypeWord << WORDTYPESHIFT |
0284            error_type << ERROR_TYPE_SHIFT | rob_id << ERROR_ROB_ID_SHIFT | 1 << ERRORSHIFT;
0285   }
0286 
0287 private:
0288   uint32_t word_;
0289 };
0290 
0291 /** \class DTROSDebugWord
0292  *  DT ROS Debug interpreter. 
0293  *  It interprets the Debug type (3 bits) and the debug message 
0294  *  (in the first 15 bits) 
0295  *
0296  * \author M. Zanetti - INFN Padova
0297  */
0298 class DTROSDebugWord {
0299 public:
0300   /// Constructor
0301   DTROSDebugWord() {}
0302 
0303   DTROSDebugWord(const DTROSDebugWord& obj) { *this = obj; }
0304 
0305   DTROSDebugWord(const uint32_t index) : word_(index) {}
0306 
0307   /// Destructor
0308   virtual ~DTROSDebugWord() {}
0309 
0310   int debugType() const { return (word_ & DEBUG_TYPE_MASK) >> DEBUG_TYPE_SHIFT; }
0311   int debugMessage() const { return (word_ & DEBUG_MESSAGE_MASK); }
0312   int cerosIdCerosStatus() const {
0313     return debugType() == 3 ? (word_ & CEROS_ID_CEROS_STATUS_MASK) >> CEROS_ID_CEROS_STATUS_SHIFT : 0;
0314   }
0315   int evIdMis() const { return debugType() == 3 ? (word_ & EV_ID_CEROS_STATUS_MASK) >> EV_ID_CEROS_STATUS_SHIFT : 0; }
0316   int dontRead() const { return debugType() == 3 ? (word_ & DONTREAD_CEROS_STATUS_MASK) : 0; }
0317   int cerosIdRosStatus() const { return debugType() == 4 ? (word_ & CEROS_ID_ROS_STATUS_MASK) : 0; }
0318 
0319   static void set(uint32_t& word,  //CB FIXME do we need setters for DEBUG Types 3 and 4?
0320                   int debug_type) {
0321     word = DTROSWordType::debugControlWord << WORDCONTROLSHIFT | DTROSWordType::rosTypeWord << WORDTYPESHIFT |
0322            debug_type << DEBUG_TYPE_SHIFT | 504 << 15;  // TEMPORARY
0323   }
0324 
0325   static void set(uint32_t& word, int debug_type, int ceros_id) {
0326     word = DTROSWordType::debugControlWord << WORDCONTROLSHIFT | DTROSWordType::rosTypeWord << WORDTYPESHIFT |
0327            debug_type << DEBUG_TYPE_SHIFT | ceros_id << CEROS_ID_CEROS_STATUS_SHIFT | 1 << 15;
0328   }
0329 
0330 private:
0331   uint32_t word_;
0332 };
0333 
0334 /** \class DTROBHeaderWord
0335  *  DT ROB Header interpreter. 
0336  *  It interprets the ROB_ID (5 bits), the Event ID (12 bits) 
0337  *  and the Bunch ID (12 bits).
0338  *
0339  * \author M. Zanetti - INFN Padova
0340  */
0341 class DTROBHeaderWord {
0342 public:
0343   /// Constructor
0344   DTROBHeaderWord() {}
0345 
0346   DTROBHeaderWord(const DTROBHeaderWord& obj) { *this = obj; }
0347 
0348   DTROBHeaderWord(const uint32_t index) : word_(index) {}
0349 
0350   /// Destructor
0351   virtual ~DTROBHeaderWord() {}
0352 
0353   int robID() const { return (word_ & ROB_ID_MASK) >> WORDTYPESHIFT; }
0354   int eventID() const { return (word_ & EVENT_ID_MASK) >> EVENT_ID_SHIFT; }
0355   int bunchID() const { return (word_ & BUNCH_ID_MASK); }
0356 
0357   static void set(uint32_t& word, int rob_id, int event_id, int bunch_id) {
0358     word = DTROSWordType::headerControlWord << WORDCONTROLSHIFT | rob_id << WORDTYPESHIFT | event_id << EVENT_ID_SHIFT |
0359            bunch_id;
0360   }
0361 
0362 private:
0363   uint32_t word_;
0364 };
0365 
0366 /** \class DTROBTrailerWord
0367  *  DT ROB Trailer interpreter. 
0368  *  It interprets the ROB_ID (5 bits), the Event ID (12 bits) 
0369  *  and the Word ID (12 bits).
0370  *
0371  * \author M. Zanetti - INFN Padova
0372  */
0373 class DTROBTrailerWord {
0374 public:
0375   /// Constructor
0376   DTROBTrailerWord() {}
0377 
0378   DTROBTrailerWord(const DTROBTrailerWord& obj) { *this = obj; }
0379 
0380   DTROBTrailerWord(const uint32_t index) : word_(index) {}
0381 
0382   /// Destructor
0383   virtual ~DTROBTrailerWord() {}
0384 
0385   int robID() const { return (word_ & ROB_ID_MASK) >> WORDTYPESHIFT; }
0386   int eventID() const { return (word_ & EVENT_ID_MASK) >> EVENT_ID_SHIFT; }
0387   int wordCount() const { return (word_ & WORD_COUNT_MASK); }
0388 
0389   static void set(uint32_t& word, int rob_id, int event_id, int word_count) {
0390     word = DTROSWordType::trailerControlWord << WORDCONTROLSHIFT | rob_id << WORDTYPESHIFT |
0391            event_id << EVENT_ID_SHIFT | word_count;
0392   }
0393 
0394 private:
0395   uint32_t word_;
0396 };
0397 
0398 /** \class DTTDCHeaderWord
0399  *  DT TDC Header interpreter. 
0400  *  It interprets the Parity Checks, FIFO occupancy, Lokeced channels (all 1 bit),
0401  *  the TDC_ID (2 bits), the Event ID (12 bits) and the Bunch ID (12 bits).
0402  *
0403  * \author M. Zanetti - INFN Padova
0404  */
0405 class DTTDCHeaderWord {
0406 public:
0407   /// Constructor
0408   DTTDCHeaderWord() {}
0409 
0410   DTTDCHeaderWord(const DTTDCHeaderWord& obj) { *this = obj; }
0411 
0412   DTTDCHeaderWord(const uint32_t index) : word_(index) {}
0413 
0414   /// Destructor
0415   virtual ~DTTDCHeaderWord() {}
0416 
0417   int PC() const { return (word_ & PC_MASK) >> PC_SHIFT; }
0418   int PAF() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }
0419   int HU() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }  /// <== OBSOLETE!!
0420   int tdcID() const { return (word_ & TDC_ID_MASK) >> TDC_ID_SHIFT; }
0421   int eventID() const { return (word_ & EVENT_ID_MASK) >> EVENT_ID_SHIFT; }
0422   int bunchID() const { return (word_ & BUNCH_ID_MASK); }
0423 
0424   static void set(uint32_t& word, int pc, int paf, int hu, int tdc_id, int event_id, int bunch_id) {
0425     word = DTROSWordType::tdcHeaderControlWord << WORDCONTROLSHIFT | pc << PC_SHIFT | paf << PAF_SHIFT |
0426            hu << PAF_SHIFT | tdc_id << TDC_ID_SHIFT | event_id << EVENT_ID_SHIFT | bunch_id;
0427   }
0428 
0429 private:
0430   uint32_t word_;
0431 };
0432 
0433 /** \class DTTDCTrailerWord
0434  *  DT TDC Trailer interpreter. 
0435  *  It interprets the Parity Checks, FIFO occupancy, Lokeced channels (all 1 bit),
0436  *  the TDC_ID (2 bits), the Event ID (12 bits) and the Word ID (12 bits).
0437  *
0438  * \author M. Zanetti - INFN Padova
0439  */
0440 class DTTDCTrailerWord {
0441 public:
0442   /// Constructor
0443   DTTDCTrailerWord() {}
0444 
0445   DTTDCTrailerWord(const DTTDCTrailerWord& obj) { *this = obj; }
0446 
0447   DTTDCTrailerWord(const uint32_t index) : word_(index) {}
0448 
0449   /// Destructor
0450   virtual ~DTTDCTrailerWord() {}
0451 
0452   int PC() const { return (word_ & PC_MASK) >> PC_SHIFT; }
0453   int PAF() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }
0454   int HU() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }  /// <== OBSOLETE!!
0455   int tdcID() const { return (word_ & TDC_ID_MASK) >> TDC_ID_SHIFT; }
0456   int eventID() const { return (word_ & EVENT_ID_MASK) >> EVENT_ID_SHIFT; }
0457   int wordCount() const { return (word_ & WORD_COUNT_MASK); }
0458 
0459   static void set(uint32_t& word, int pc, int paf, int hu, int tdc_id, int event_id, int word_count) {
0460     word = DTROSWordType::tdcTrailerControlWord << WORDCONTROLSHIFT | pc << PC_SHIFT | paf << PAF_SHIFT |
0461            hu << PAF_SHIFT | tdc_id << TDC_ID_SHIFT | event_id << EVENT_ID_SHIFT | word_count;
0462   }
0463 
0464 private:
0465   uint32_t word_;
0466 };
0467 
0468 /** \class DTTDCMeasurementWord
0469  *  DT TDC Measurement interpreter. 
0470  *  It interprets the Parity Checks, FIFO occupancy, Lokeced channels (all 1 bit),
0471  *  the TDC_ID (2 bits), the TDC channel (5 bits), and the TDC time (19 bits)
0472  *
0473  * \author M. Zanetti - INFN Padova
0474  */
0475 class DTTDCMeasurementWord {
0476 public:
0477   /// Constructor
0478   DTTDCMeasurementWord() {}
0479 
0480   DTTDCMeasurementWord(const DTTDCMeasurementWord& obj) { *this = obj; }
0481 
0482   DTTDCMeasurementWord(const uint32_t index) : word_(index) {}
0483 
0484   /// Destructor
0485   virtual ~DTTDCMeasurementWord() {}
0486 
0487   int PC() const { return (word_ & PC_MASK) >> PC_SHIFT; }
0488   int PAF() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }
0489   int HU() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }  /// <== OBSOLETE!!
0490   int tdcID() const { return (word_ & TDC_ID_MASK) >> TDC_ID_SHIFT; }
0491   int tdcChannel() const { return (word_ & TDC_CHANNEL_MASK) >> TDC_CHANNEL_SHIFT; }
0492   int tdcTime() const { return (word_ & TDC_TIME_MASK) >> TDC_TIME_SHIFT; }
0493 
0494   static void set(uint32_t& word, int pc, int paf, int hu, int tdc_id, int tdc_channel, int tdc_time) {
0495     word = DTROSWordType::tdcDataControlWord << WORDCONTROLSHIFT | pc << PC_SHIFT | paf << PAF_SHIFT | hu << PAF_SHIFT |
0496            tdc_id << TDC_ID_SHIFT | tdc_channel << TDC_CHANNEL_SHIFT | tdc_time;
0497   }
0498 
0499 private:
0500   uint32_t word_;
0501 };
0502 
0503 /** \class DTTDCErrorWord
0504  *  DT TDC Error interpreter. 
0505  *  It interprets the Parity Checks, FIFO occupancy, Lokeced channels (all 1 bit),
0506  *  the TDC_ID (2 bits) and the TDC error flag (15 bits)
0507  *
0508  * \author M. Zanetti - INFN Padova
0509  */
0510 class DTTDCErrorWord {
0511 public:
0512   /// Constructor
0513   DTTDCErrorWord() {}
0514 
0515   DTTDCErrorWord(const DTTDCErrorWord& obj) { *this = obj; }
0516 
0517   DTTDCErrorWord(const uint32_t index) : word_(index) {}
0518 
0519   /// Destructor
0520   virtual ~DTTDCErrorWord() {}
0521 
0522   int PC() const { return (word_ & PC_MASK) >> PC_SHIFT; }
0523   int PAF() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }
0524   int HU() const { return (word_ & PAF_MASK) >> PAF_SHIFT; }  /// <== OBSOLETE!!
0525   int tdcID() const { return (word_ & TDC_ID_MASK) >> TDC_ID_SHIFT; }
0526   int tdcError() const { return (word_ & TDC_ERROR_MASK); }
0527 
0528   static void set(uint32_t& word, int pc, int paf, int hu, int tdc_id, int tdc_error) {
0529     word = DTROSWordType::errorControlWord << WORDCONTROLSHIFT | pc << PC_SHIFT | paf << PAF_SHIFT | hu << PAF_SHIFT |
0530            tdc_id << TDC_ID_SHIFT | 0 << ERRORSHIFT | tdc_error;
0531   }
0532 
0533 private:
0534   uint32_t word_;
0535 };
0536 
0537 /** \class DTLocalTriggerHeaderWord
0538  *  DT Sector Collector header interpreter. 
0539  *  It interprets ROS event ID (12 bits) and the Sector Collector FIFO occupancy (8 bits)
0540  *
0541  * \author M. Zanetti - INFN Padova
0542  */
0543 class DTLocalTriggerHeaderWord {
0544 public:
0545   /// Constructor
0546   DTLocalTriggerHeaderWord() {}
0547 
0548   DTLocalTriggerHeaderWord(const DTLocalTriggerHeaderWord& obj) { *this = obj; }
0549 
0550   DTLocalTriggerHeaderWord(const uint32_t index) : word_(index) {}
0551 
0552   /// Destructor
0553   virtual ~DTLocalTriggerHeaderWord() {}
0554 
0555   int eventID() const { return (word_ & EVENT_ID_MASK) >> EVENT_ID_SHIFT; }
0556   int SCFO() const { return (word_ & SCFO_MASK); }
0557 
0558   static void set(uint32_t& word, int event_id, int scfo) {
0559     word = DTROSWordType::headerControlWord << WORDCONTROLSHIFT | DTROSWordType::scTypeWord << WORDTYPESHIFT |
0560            event_id << EVENT_ID_SHIFT | scfo;
0561   }
0562 
0563 private:
0564   uint32_t word_;
0565 };
0566 
0567 /** \class DTLocalTriggerTrailerWord
0568  *  DT Sector Collector trailer interpreter. 
0569  *  It interprets the word count (16 bits)
0570  *
0571  * \author M. Zanetti - INFN Padova
0572  */
0573 class DTLocalTriggerTrailerWord {
0574 public:
0575   /// Constructor
0576   DTLocalTriggerTrailerWord() {}
0577 
0578   DTLocalTriggerTrailerWord(const DTLocalTriggerTrailerWord& obj) { *this = obj; }
0579 
0580   DTLocalTriggerTrailerWord(const uint32_t index) : word_(index) {}
0581 
0582   /// Destructor
0583   virtual ~DTLocalTriggerTrailerWord() {}
0584 
0585   int wordCount() const { return (word_ & TRIGGER_WORD_COUNT_MASK); }
0586 
0587   static void set(uint32_t& word, int word_count) {
0588     word =
0589         DTROSWordType::trailerControlWord << WORDCONTROLSHIFT | DTROSWordType::scTypeWord << WORDTYPESHIFT | word_count;
0590   }
0591 
0592 private:
0593   uint32_t word_;
0594 };
0595 
0596 /** \class DTLocalTriggerDataWord
0597  *  DT Sector Collector data interpreter. 
0598  *  It interprets the Sector Collector data (16 bits)
0599  *
0600  * \author M. Zanetti - INFN Padova
0601  */
0602 class DTLocalTriggerDataWord {
0603 public:
0604   /// Constructor
0605   DTLocalTriggerDataWord() {}
0606 
0607   DTLocalTriggerDataWord(const DTLocalTriggerDataWord& obj) { *this = obj; }
0608 
0609   DTLocalTriggerDataWord(const uint32_t index) : word_(index) {}
0610 
0611   /// Destructor
0612   virtual ~DTLocalTriggerDataWord() {}
0613 
0614   int SCData() const { return (word_ & TRIGGER_DATA_MASK); }
0615 
0616   int getBits(int first) const {
0617     return first == 1 ? ((word_ & TRIGGER_DATA_MASK) >> 8) : ((word_ & TRIGGER_DATA_MASK) & 0xFF);
0618   }
0619 
0620   //int hasTrigger(int first) const { return (getBits(first) & 0x40) >> 6; }
0621   int hasTrigger(int first) const { return (trackQuality(first) != 7 ? 1 : 0); }
0622   int trackQuality(int first) const { return (getBits(first) & 0xE) >> 1; }
0623 
0624   static void set(uint32_t& word, int sc_data) {
0625     word = DTROSWordType::tdcDataControlWord << WORDCONTROLSHIFT | DTROSWordType::scTypeWord << WORDTYPESHIFT | sc_data;
0626   }
0627 
0628 private:
0629   uint32_t word_;
0630 };
0631 
0632 /** \class DTDDUFirstStatusWord
0633  *  DT DDU status 1 interpreter (8 bits word). 
0634  *  It interprets the error messages from each DDU channel
0635  *
0636  * \author M. Zanetti - INFN Padova
0637  */
0638 class DTDDUFirstStatusWord {
0639 public:
0640   /// Constructor
0641   DTDDUFirstStatusWord() {}
0642 
0643   DTDDUFirstStatusWord(const DTDDUFirstStatusWord& obj) { *this = obj; }
0644 
0645   DTDDUFirstStatusWord(const unsigned char index) : word_(index) {}
0646 
0647   /// Destructor
0648   virtual ~DTDDUFirstStatusWord() {}
0649 
0650   int channelEnabled() const { return (word_ & 0x1); }
0651   int timeout() const { return (word_ & 0x2) >> 1; }
0652   int eventTrailerLost() const { return (word_ & 0x4) >> 2; }
0653   int opticalFiberSignalLost() const { return (word_ & 0x8) >> 3; }
0654   int tlkPropagationError() const { return (word_ & 0x10) >> 4; }
0655   int tlkPatternError() const { return (word_ & 0x20) >> 5; }
0656   int tlkSignalLost() const { return (word_ & 0x40) >> 6; }
0657   int errorFromROS() const { return (word_ & 0x80) >> 7; }
0658 
0659 private:
0660   unsigned char word_;
0661 };
0662 
0663 /** \class DTDDUSecondStatusWord
0664  *  DT DDU status 2 interpreter. 
0665  *  It interprets the (16 bits)
0666  *  WARNING!! : It interprets the second part of a 64 bits word!
0667  *
0668  * \author M. Zanetti - INFN Padova
0669  */
0670 class DTDDUSecondStatusWord {
0671 public:
0672   /// Constructor
0673   DTDDUSecondStatusWord() {}
0674 
0675   DTDDUSecondStatusWord(const DTDDUSecondStatusWord& obj) { *this = obj; }
0676 
0677   DTDDUSecondStatusWord(const uint32_t index) : word_(index) {}
0678 
0679   /// Destructor
0680   virtual ~DTDDUSecondStatusWord() {}
0681 
0682   int l1AIDError() const { return (word_ & 0x1); }
0683   int bxIDError() const { return (word_ & 0x2) >> 1; }
0684   int fifoFull() const { return (word_ & 0x1C) >> 2; }
0685   int inputFifoFull() const { return (word_ & 0xE0) >> 5; }
0686   int fifoAlmostFull() const { return (word_ & 0x700) >> 8; }
0687   int inputFifoAlmostFull() const { return (word_ & 0x3800) >> 11; }
0688   int outputFifoFull() const { return (word_ & 0x4000) >> 14; }
0689   int outputFifoAlmostFull() const { return (word_ & 0x8000) >> 15; }
0690   int rosList() const { return (word_ & 0xFFF0000) >> 16; }
0691   int warningROSPAF() const { return (word_ & 0x10000000) >> 28; }
0692   int busyROSPAF() const { return (word_ & 0x20000000) >> 29; }
0693   int outOfSynchROSError() const { return (word_ & 0x40000000) >> 30; }
0694 
0695   //   int fifoAlmostEmpty() const { return (word_ & 0x1C000) >> 14; }
0696   //   int inputFifoAlmostEmpty() const { return (word_ & 0xE0000) >> 17; }
0697   //   int outputFifoFull() const { return (word_ & 0x100000) >> 20; }
0698   //   int outputFifoAlmostFull() const { return (word_ & 0x200000) >> 21; }
0699   //   int outputFifoAlmostEmpty() const { return (word_ & 0x400000) >> 22; }
0700 
0701 private:
0702   uint32_t word_;
0703 };
0704 
0705 /** \class DTLocalTriggerSectorCollectorHeaderWord
0706  *  DT Sector Collector private header interpreter. 
0707  *  It interprets Latency measured by SC-Latency Timer Unit (still testing!)
0708  *  and the number of 16-bit words following this header sent by the Sector Collector
0709  *
0710  * \author R. Travaglini - INFN Bologna
0711  */
0712 class DTLocalTriggerSectorCollectorHeaderWord {
0713 public:
0714   /// Constructor
0715   DTLocalTriggerSectorCollectorHeaderWord() {}
0716 
0717   DTLocalTriggerSectorCollectorHeaderWord(const DTLocalTriggerSectorCollectorHeaderWord& obj) { *this = obj; }
0718 
0719   DTLocalTriggerSectorCollectorHeaderWord(const uint32_t index) : word_(index) {}
0720 
0721   /// Destructor
0722   virtual ~DTLocalTriggerSectorCollectorHeaderWord() {}
0723 
0724   int Latency() const { return ((word_ >> SC_LAT_SHIFT) & SC_LAT_MASK); }
0725   int NumberOf16bitWords() const { return (word_ & SC_NW_MASK); }
0726 
0727   static void set(uint32_t& word, int lat, int nw) {
0728     word = DTROSWordType::headerControlWord << WORDCONTROLSHIFT | DTROSWordType::scTypeWord << WORDTYPESHIFT |
0729            (lat & SC_LAT_MASK) << SC_LAT_SHIFT | (nw & SC_NW_MASK);
0730   }
0731 
0732 private:
0733   uint32_t word_;
0734 };
0735 
0736 /** \class DTLocalTriggerSectorCollectorSubHeaderWord
0737  *  DT Sector Collector private SUB-header interpreter. 
0738  *  It interprets local SC bunch Counter and delay (3-bit) between trigger used to stop spying and
0739  *  effective bx stop
0740  *
0741  * \author R. Travaglini - INFN Bologna
0742  */
0743 class DTLocalTriggerSectorCollectorSubHeaderWord {
0744 public:
0745   /// Constructor
0746   DTLocalTriggerSectorCollectorSubHeaderWord() {}
0747 
0748   DTLocalTriggerSectorCollectorSubHeaderWord(const DTLocalTriggerSectorCollectorSubHeaderWord& obj) { *this = obj; }
0749 
0750   DTLocalTriggerSectorCollectorSubHeaderWord(const uint32_t index) : word_(index) {}
0751 
0752   /// Destructor
0753   virtual ~DTLocalTriggerSectorCollectorSubHeaderWord() {}
0754 
0755   int TriggerDelay() const { return ((word_ >> SC_TRIGGERDLY_SHIFT) & SC_TRIGGERDLY_MASK); }
0756   int LocalBunchCounter() const { return (word_ & SC_BXC_MASK); }
0757 
0758   static void set(uint32_t& word, int trigdly, int bxcount) {
0759     word = DTROSWordType::headerControlWord << WORDCONTROLSHIFT | DTROSWordType::scTypeWord << WORDTYPESHIFT |
0760            (trigdly & SC_TRIGGERDLY_MASK) << SC_TRIGGERDLY_SHIFT | (bxcount & SC_BXC_MASK);
0761   }
0762 
0763 private:
0764   uint32_t word_;
0765 };
0766 
0767 #endif