Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:02

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