#ifndef BASE_MESSAGE_H #define BASE_MESSAGE_H #include #include #include "base/defines.h" namespace base { /** ROC message format */ enum MessageFormat { formatEth1 = 0, ///< original message format with big-endian coding, 6-byte formatOptic1 = 1, ///< original message format with big-endian coding, add 2 byte send/recv info, 8-byte formatEth2 = 2, ///< new message format with little-endian coding, 6-byte formatOptic2 = 3, ///< new message format with little-endian coding, add 2 byte send/recv info, 8-byte formatNormal = 4 ///< new message format with little-endian coding, 16-bit roc number (default) }; /** ROC message types */ enum MessageTypes { MSG_NOP = 0, ///< nop MSG_HIT = 1, ///< hit MSG_EPOCH = 2, ///< epoch MSG_SYNC = 3, ///< sync MSG_AUX = 4, ///< aux MSG_EPOCH2 = 5, ///< epoch2 MSG_GET4 = 6, ///< get4 MSG_SYS = 7 ///< sys }; /** ROC sys message types */ enum SysMessageTypes { SYSMSG_DAQ_START = 1, ///< indicates start daq in data stream SYSMSG_DAQ_FINISH = 2, ///< stop daq SYSMSG_NX_PARITY = 3, ///< nx_parity error SYSMSG_SYNC_PARITY = 4, ///< sync parity error SYSMSG_DAQ_RESUME = 5, ///< daq resume due to low/high water marker, only in udp case SYSMSG_FIFO_RESET = 6, ///< FPGA fifo reset SYSMSG_USER = 7, ///< user define message, generated by writing into ROC_ADDSYSMSG register SYSMSG_PCTIME = 8, ///< contains value of time() function, indicates when message was created on PC SYSMSG_ADC = 9, ///< contains feb1d (1 bit), channel id (7 bit) and adc value (24 bit), measured on PC SYSMSG_PACKETLOST = 10, ///< inserted by udp transport when packet was lost at this place SYSMSG_GET4_EVENT = 11, ///< GET4 event SYSMSG_CLOSYSYNC_ERROR = 12, ///< added to data stream when the closy-sync-strobe does not match the rocs 156MHz timestamp counter SYSMSG_TS156_SYNC = 13 ///< added when 156MHz timestamp counter is reset by a DLM }; /** ROC user message types */ enum SysMessageUserTypes { SYSMSG_USER_CALIBR_ON = 7, ///< calibr on SYSMSG_USER_CALIBR_OFF = 8, ///< calibr off SYSMSG_USER_RECONFIGURE = 9 ///< reconfigure }; /** Message print mask */ enum MessagePrintMask { msg_print_Prefix = 1, ///< prefix msg_print_Data = 2, ///< data msg_print_Hex = 4, ///< hex msg_print_Human = 8 ///< human }; /** ROC Message */ class Message { protected: uint64_t data; ///< main and only storage field for the message public: /** constructor */ Message() : data(0) {} /** constructor */ Message(const Message& src) : data(src.data) {} /** assign */ void assign(const Message& src) { data = src.data; } /** assign operator */ Message& operator=(const Message& src) { assign(src); return *this; } /** reset */ inline void reset() { data = 0; } /** get field */ inline uint32_t getField(uint32_t shift, uint32_t len) const { return (data >> shift) & ((((uint32_t)1) << len) - 1); } /** set field */ inline void setField(uint32_t shift, uint32_t len, uint32_t value) { data = (data & ~(((((uint64_t) 1) << len) - 1) << shift)) | (((uint64_t) value) << shift); } /** get bit */ inline uint8_t getBit(uint32_t shift) const { return (data >> shift) & 1; } /** set bit */ inline void setBit(uint32_t shift, uint8_t value) { data = value ? (data | (((uint64_t) 1) << shift)) : (data & ~(((uint64_t) 1) << shift)) ; } // --------------------------- common fields --------------------------------- /// Returns the message type. Valid for all message types. 4 bit inline uint8_t getMessageType() const { return getField(0, 4); } /// Returns the number of the sending ROC. Valid for all message types. /// /// The field has full 16 bits and allows to aggregate data of up to 64K ROC's /// in one message stream. inline uint16_t getRocNumber() const { return getField(48, 16); } /// Sets the message type field in the current message inline void setMessageType(uint8_t v) { setField(0, 4, v); } /// Sets the ROC number field in the current message inline void setRocNumber(uint16_t v) { setField(48, 16, v); } // ---------- Epoch marker access methods ------------ // 2 bit unused /// For Epoch data: Returns current epoch number (32 bit field) /// inline uint32_t getEpochNumber() const { return getField(8, 32); } /// on some machines 32-bit field is not working inline uint32_t getEpochNumber() const { return data >> 8; } /// For Epoch data: Returns number of missed hits (8 bit field) inline uint8_t getEpochMissed() const { return getField(40, 8); } /// For Epoch data: Sets epoch number (32 bit field) inline void setEpochNumber(uint32_t v) { setField(8, 32, v); } /// For Epoch data: Sets missed hits count (8 bit field) inline void setEpochMissed(uint8_t v) { setField(40, 8, v); } // ---------- Sync marker access methods ------------- /// For Sync data: Returns sync channel number (2 bit field) inline uint8_t getSyncChNum() const { return getField(6, 2); } /// For Sync data: Returns sync time stamp (13 bit field, 2 ns bins) inline uint16_t getSyncTs() const { return getField(8, 13) << 1; } /// For Sync data: Returns LSB of true epoch (1 bit field) inline uint8_t getSyncEpochLSB() const { return getBit(21); } /// For Sync data: Returns sync message data (24 bit field) inline uint32_t getSyncData() const { return getField(22, 24); } /// For Sync data: Returns sync status flags (2 bit field) inline uint8_t getSyncStFlag() const { return getField(46, 2); } /// For Sync data: Set sync channel number (2 bit field) inline void setSyncChNum(uint8_t v) { setField(6, 2, v); } /// For Sync data: Set sync time stamp (13 bit field, 2 ns bins ) inline void setSyncTs(uint16_t v) { setField(8, 13, v >> 1); } /// For Sync data: Set LSB of true epoch (1 bit field) inline void setSyncEpochLSB(uint8_t v) { setBit(21, v); } /// For Sync data: Set sync message data (24 bit field) inline void setSyncData(uint32_t v) { setField(22, 24, v); } /// For Sync data: Set sync status flags (2 bit field) inline void setSyncStFlag(uint8_t v) { setField(46, 2, v); } // ---------- AUX marker access methods -------------- /// For Aux data: Returns aux channel number (7 bit field) inline uint8_t getAuxChNum() const { return getField(6, 7); } /// For Aux data: Returns aux time stamp (13 bit field, 2 ns bins) inline uint16_t getAuxTs() const { return getField(13, 13) << 1; } /// For Aux data: Returns LSB of true epoch (1 bit field) inline uint8_t getAuxEpochLSB() const { return getBit(26); } /// For Aux data: Returns falling edge flag (1 bit flag) inline uint8_t getAuxFalling() const { return getBit(27); } /// For Aux data: Returns overflow flag (1 bit field) inline uint8_t getAuxOverflow() const { return getBit(28); } /// For Aux data: Set aux channel number (7 bit field) inline void setAuxChNum(uint8_t v) { setField(6, 7, v); } /// For Aux data: Set aux time stamp (13 bit field) inline void setAuxTs(uint16_t v) { setField(13, 13, v >> 1); } /// For Aux data: Set LSB of true epoch (1 bit field) inline void setAuxEpochLSB(uint8_t v) { setBit(26, v); } /// For Aux data: Set falling edge flag (1 bit flag) inline void setAuxFalling(uint8_t v) { setBit(27, v); } /// For Aux data: Set overflow flag (1 bit field) inline void setAuxOverflow(uint8_t v) { setBit(28, v); } // ---------- System message access methods ---------- // 2 bit unused /// For SysMes data: Returns system message subtype (8 bit field) inline uint8_t getSysMesType() const { return getField(8, 8); } /// For SysMes data: Returns system message data (32 bit field) // inline uint32_t getSysMesData() const { return getField(16, 32); } // on some machine 32-bit field not working inline uint32_t getSysMesData() const { return data >> 16; } /// For SysMes data: Set system message type (8 bit field) inline void setSysMesType(uint8_t v) { setField(8, 8, v); } /// For SysMes data: Set system message data (32 bit field) inline void setSysMesData(uint32_t v) { setField(16, 32, v); } // ---------- Common functions ----------------------- /// Returns \a true is message type is MSG_NOP (filler message) inline bool isNopMsg() const { return getMessageType() == MSG_NOP; } /// Returns \a true is message type is MSG_EPOCH (epoch marker) inline bool isEpochMsg() const { return getMessageType() == MSG_EPOCH;} /// Returns \a true is message type is MSG_SYNC inline bool isSyncMsg() const { return getMessageType() == MSG_SYNC; } /// Returns \a true is message type is MSG_AUX inline bool isAuxMsg() const { return getMessageType() == MSG_AUX; } /// Returns \a true is message type is MSG_SYS (system message) inline bool isSysMsg() const { return getMessageType() == MSG_SYS; } /// Returns \a true if system message and subtype ROC_SYSMSG_DAQ_START inline bool isStartDaqMsg() const { return isSysMsg() && (getSysMesType() == SYSMSG_DAQ_START); } /// Returns \a true if system message and subtype ROC_SYSMSG_DAQ_FINISH inline bool isStopDaqMsg() const { return isSysMsg() && (getSysMesType() == SYSMSG_DAQ_FINISH); } // -------------------- methods for working with different formats static uint32_t RawSize(int fmt); }; } #endif