CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_8_patch3/src/EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h

Go to the documentation of this file.
00001 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBufferComponents_H
00002 #define EventFilter_SiStripRawToDigi_SiStripFEDBufferComponents_H
00003 
00004 #include "boost/cstdint.hpp"
00005 #include <ostream>
00006 #include <memory>
00007 #include <cstring>
00008 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 
00011 namespace sistrip {
00012   
00013   //
00014   // Constants
00015   //
00016   
00017   static const uint8_t INVALID=0xFF;
00018 
00019   static const uint8_t APV_MAX_ADDRESS=192;
00020   
00021   static const uint16_t SCOPE_MODE_MAX_SCOPE_LENGTH=1022;
00022 
00023   enum FEDBufferFormat { BUFFER_FORMAT_INVALID=INVALID,
00024                          BUFFER_FORMAT_OLD_VME,
00025                          BUFFER_FORMAT_OLD_SLINK,
00026                          BUFFER_FORMAT_NEW
00027                        };
00028   //these are the values which appear in the buffer.
00029   static const uint8_t BUFFER_FORMAT_CODE_OLD = 0xED;
00030   static const uint8_t BUFFER_FORMAT_CODE_NEW = 0xC5;
00031 
00032   //enum values are values which appear in buffer. DO NOT CHANGE!
00033   enum FEDHeaderType { HEADER_TYPE_INVALID=INVALID,
00034                        HEADER_TYPE_FULL_DEBUG=1,
00035                        HEADER_TYPE_APV_ERROR=2,
00036                        HEADER_TYPE_NONE=4 //spy channel
00037                      };
00038 
00039   //enum values are values which appear in buffer. DO NOT CHANGE!
00040   enum FEDReadoutMode { READOUT_MODE_INVALID=INVALID,
00041                         READOUT_MODE_SCOPE=0x1,
00042                         READOUT_MODE_VIRGIN_RAW=0x2,
00043                         READOUT_MODE_PROC_RAW=0x6,
00044                         READOUT_MODE_ZERO_SUPPRESSED=0xA,
00045                         READOUT_MODE_ZERO_SUPPRESSED_LITE=0xC,
00046                         READOUT_MODE_SPY=0xE
00047                       };
00048 
00049   static const uint8_t PACKET_CODE_SCOPE = 0xE5;
00050   static const uint8_t PACKET_CODE_VIRGIN_RAW = 0xE6;
00051   static const uint8_t PACKET_CODE_PROC_RAW = 0xF2;
00052   static const uint8_t PACKET_CODE_ZERO_SUPPRESSED = 0xEA;
00053 
00054   //enum values are values which appear in buffer. DO NOT CHANGE!
00055   enum FEDDataType { DATA_TYPE_REAL=0,
00056                      DATA_TYPE_FAKE=1
00057                    };
00058 
00059   //enum values are values which appear in buffer. DO NOT CHANGE!
00060   //see https://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
00061   enum FEDDAQEventType { DAQ_EVENT_TYPE_PHYSICS=0x1,
00062                          DAQ_EVENT_TYPE_CALIBRATION=0x2,
00063                          DAQ_EVENT_TYPE_TEST=0x3,
00064                          DAQ_EVENT_TYPE_TECHNICAL=0x4,
00065                          DAQ_EVENT_TYPE_SIMULATED=0x5,
00066                          DAQ_EVENT_TYPE_TRACED=0x6,
00067                          DAQ_EVENT_TYPE_ERROR=0xF,
00068                          DAQ_EVENT_TYPE_INVALID=INVALID
00069                        };
00070 
00071   //enum values are values which appear in buffer. DO NOT CHANGE!
00072   //see https://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
00073   enum FEDTTSBits { TTS_DISCONNECTED0=0x0,
00074                     TTS_WARN_OVERFLOW=0x1,
00075                     TTS_OUT_OF_SYNC=0x2,
00076                     TTS_BUSY=0x4,
00077                     TTS_READY=0x8,
00078                     TTS_ERROR=0x12,
00079                     TTS_DISCONNECTED1=0xF,
00080                     TTS_INVALID=INVALID };
00081   
00082   //enum values are values which appear in buffer. DO NOT CHANGE!
00083   enum FEDBufferState { BUFFER_STATE_UNSET=0x0,
00084                         BUFFER_STATE_EMPTY=0x1,
00085                         BUFFER_STATE_PARTIAL_FULL=0x4,
00086                         BUFFER_STATE_FULL=0x8
00087                       };
00088   
00089   //enum values are values which appear in buffer. DO NOT CHANGE!
00090   enum FEDChannelStatus { CHANNEL_STATUS_LOCKED=0x20,
00091                           CHANNEL_STATUS_IN_SYNC=0x10,
00092                           CHANNEL_STATUS_APV1_ADDRESS_GOOD=0x08,
00093                           CHANNEL_STATUS_APV0_NO_ERROR_BIT=0x04,
00094                           CHANNEL_STATUS_APV0_ADDRESS_GOOD=0x02,
00095                           CHANNEL_STATUS_APV1_NO_ERROR_BIT=0x01,
00096                           CHANNEL_STATUS_NO_PROBLEMS=CHANNEL_STATUS_LOCKED|
00097                                                      CHANNEL_STATUS_IN_SYNC|
00098                                                      CHANNEL_STATUS_APV1_ADDRESS_GOOD|
00099                                                      CHANNEL_STATUS_APV0_NO_ERROR_BIT|
00100                                                      CHANNEL_STATUS_APV0_ADDRESS_GOOD|
00101                                                      CHANNEL_STATUS_APV1_NO_ERROR_BIT
00102                         };
00103 
00104   //
00105   // Global function declarations
00106   //
00107 
00108   //used by these classes
00109   uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum);
00110   void printHex(const void* pointer, const size_t length, std::ostream& os);
00111   //calculate the CRC for a FED buffer
00112   uint16_t calculateFEDBufferCRC(const uint8_t* buffer, const size_t lengthInBytes);
00113   //to make enums printable
00114   std::ostream& operator<<(std::ostream& os, const FEDBufferFormat& value);
00115   std::ostream& operator<<(std::ostream& os, const FEDHeaderType& value);
00116   std::ostream& operator<<(std::ostream& os, const FEDReadoutMode& value);
00117   std::ostream& operator<<(std::ostream& os, const FEDDataType& value);
00118   std::ostream& operator<<(std::ostream& os, const FEDDAQEventType& value);
00119   std::ostream& operator<<(std::ostream& os, const FEDTTSBits& value);
00120   std::ostream& operator<<(std::ostream& os, const FEDBufferState& value);
00121   std::ostream& operator<<(std::ostream& os, const FEDChannelStatus& value);
00122   //convert name of an element of enum to enum value (useful for getting values from config)
00123   FEDBufferFormat fedBufferFormatFromString(const std::string& bufferFormatString);
00124   FEDHeaderType fedHeaderTypeFromString(const std::string& headerTypeString);
00125   FEDReadoutMode fedReadoutModeFromString(const std::string& readoutModeString);
00126   FEDDataType fedDataTypeFromString(const std::string& dataTypeString);
00127   FEDDAQEventType fedDAQEventTypeFromString(const std::string& daqEventTypeString);
00128 
00129   //
00130   // Class definitions
00131   //
00132   
00133   //handles conversion between order of data in buffer in VR/PR modes (readout order) and strip order (physical order)
00134   class FEDStripOrdering
00135     {
00136     public:
00137       //convert strip/sample index in channel (ie 0-255) between physical and readout order
00138       static uint8_t physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel);
00139       static uint8_t readoutOrderForStripInChannel(const uint8_t physicalOrderStripIndexInChannel);
00140       //convert strip/sample index in APV (ie 0-127) between physical and readout order
00141       static uint8_t physicalOrderForStripInAPV(const uint8_t readoutOrderStripIndexInAPV);
00142       static uint8_t readoutOrderForStripInAPV(const uint8_t physicalOrderStripIndexInAPV);
00143     };
00144 
00145   //see https://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
00146   class FEDDAQHeader
00147     {
00148     public:
00149       FEDDAQHeader() { }
00150       explicit FEDDAQHeader(const uint8_t* header);
00151       //0x5 in first fragment
00152       uint8_t boeNibble() const;
00153       uint8_t eventTypeNibble() const;
00154       FEDDAQEventType eventType() const;
00155       uint32_t l1ID() const;
00156       uint16_t bxID() const;
00157       uint16_t sourceID() const;
00158       uint8_t version() const;
00159       //0 if current header word is last, 1 otherwise
00160       bool hBit() const;
00161       bool lastHeader() const;
00162       void print(std::ostream& os) const;
00163       //used by digi2Raw
00164       const uint8_t* data() const;
00165       FEDDAQHeader& setEventType(const FEDDAQEventType evtType);
00166       FEDDAQHeader& setL1ID(const uint32_t l1ID);
00167       FEDDAQHeader& setBXID(const uint16_t bxID);
00168       FEDDAQHeader& setSourceID(const uint16_t sourceID);
00169       FEDDAQHeader(const uint32_t l1ID, const uint16_t bxID, const uint16_t sourceID, 
00170                    const FEDDAQEventType evtType = DAQ_EVENT_TYPE_PHYSICS);
00171     private:
00172       uint8_t header_[8];
00173     };
00174 
00175   //see https://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
00176   class FEDDAQTrailer
00177     {
00178     public:
00179       FEDDAQTrailer() { }
00180       explicit FEDDAQTrailer(const uint8_t* trailer);
00181       //0xA in first fragment
00182       uint8_t eoeNibble() const;
00183       uint32_t eventLengthIn64BitWords() const;
00184       uint32_t eventLengthInBytes() const;
00185       uint16_t crc() const;
00186       //set to 1 if FRL detects a transmission error over S-link
00187       bool cBit() const;
00188       bool slinkTransmissionError() const { return cBit(); }
00189       //set to 1 if the FED ID is not the one expected by the FRL
00190       bool fBit() const;
00191       bool badSourceID() const { return fBit(); }
00192       uint8_t eventStatusNibble() const;
00193       uint8_t ttsNibble() const;
00194       FEDTTSBits ttsBits() const;
00195       //0 if the current trailer is the last, 1 otherwise
00196       bool tBit() const;
00197       bool lastTrailer() const { return !tBit(); }
00198       //set to 1 if the S-link sender card detects a CRC error (the CRC it computes is put in the CRC field)
00199       bool rBit() const;
00200       bool slinkCRCError() const { return rBit(); }
00201       void print(std::ostream& os) const;
00202       //used by digi2Raw
00203       const uint8_t* data() const;
00204       FEDDAQTrailer& setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords);
00205       FEDDAQTrailer& setCRC(const uint16_t crc);
00206       FEDDAQTrailer& setSLinkTransmissionErrorBit(const bool bitSet);
00207       FEDDAQTrailer& setBadSourceIDBit(const bool bitSet);
00208       FEDDAQTrailer& setSLinkCRCErrorBit(const bool bitSet);
00209       FEDDAQTrailer& setEventStatusNibble(const uint8_t eventStatusNibble);
00210       FEDDAQTrailer& setTTSBits(const FEDTTSBits ttsBits);
00211       FEDDAQTrailer(const uint32_t eventLengthIn64BitWords, const uint16_t crc = 0, const FEDTTSBits ttsBits = TTS_READY,
00212                     const bool slinkTransmissionError = false, const bool badFEDID = false, const bool slinkCRCError = false,
00213                     const uint8_t eventStatusNibble = 0);
00214     private:
00215       uint8_t trailer_[8];
00216     };
00217 
00218   class FEDStatusRegister
00219     {
00220     public:
00221       FEDStatusRegister(const uint16_t fedStatusRegister);
00222       bool slinkFullFlag() const;
00223       bool trackerHeaderMonitorDataReadyFlag() const;
00224       bool qdrMemoryFullFlag() const;
00225       bool qdrMemoryPartialFullFlag() const;
00226       bool qdrMemoryEmptyFlag() const;
00227       bool l1aBxFIFOFullFlag() const;
00228       bool l1aBxFIFOPartialFullFlag() const;
00229       bool l1aBxFIFOEmptyFlag() const;
00230       FEDBufferState qdrMemoryState() const;
00231       FEDBufferState l1aBxFIFOState() const;
00232       bool feDataMissingFlag(const uint8_t internalFEUnitNum) const;
00233       void print(std::ostream& os) const;
00234       void printFlags(std::ostream& os) const;
00235       operator uint16_t () const;
00236       //used by digi2Raw
00237       FEDStatusRegister& setSLinkFullFlag(const bool bitSet);
00238       FEDStatusRegister& setTrackerHeaderMonitorDataReadyFlag(const bool bitSet);
00239       FEDStatusRegister& setQDRMemoryBufferState(const FEDBufferState state);
00240       FEDStatusRegister& setL1ABXFIFOBufferState(const FEDBufferState state);
00241       FEDStatusRegister(const FEDBufferState qdrMemoryBufferState = BUFFER_STATE_UNSET,
00242                         const FEDBufferState l1aBxFIFOBufferState = BUFFER_STATE_UNSET,
00243                         const bool trackerHeaderMonitorDataReadyFlagSet = false,
00244                         const bool slinkFullFlagSet = false);
00245     private:
00246       bool getBit(const uint8_t num) const;
00247       void setBit(const uint8_t num, const bool bitSet);
00248       void setQDRMemoryFullFlag(const bool bitSet);
00249       void setQDRMemoryPartialFullFlag(const bool bitSet);
00250       void setQDRMemoryEmptyFlag(const bool bitSet);
00251       void setL1ABXFIFOFullFlag(const bool bitSet);
00252       void setL1ABXFIFOPartialFullFlag(const bool bitSet);
00253       void setL1ABXFIFOEmptyFlag(const bool bitSet);
00254       uint16_t data_;
00255     };
00256 
00257   class TrackerSpecialHeader
00258     {
00259     public:
00260       TrackerSpecialHeader();
00261       //construct with a pointer to the data. The data will be coppied and swapped if necessary. 
00262       explicit TrackerSpecialHeader(const uint8_t* headerPointer);
00263       uint8_t bufferFormatByte() const;
00264       FEDBufferFormat bufferFormat() const;
00265       uint8_t headerTypeNibble() const;
00266       FEDHeaderType headerType() const;
00267       uint8_t trackerEventTypeNibble() const;
00268       FEDReadoutMode readoutMode() const;
00269       FEDDataType dataType() const;
00270       uint8_t apveAddress() const;
00271       uint8_t apvAddressErrorRegister() const;
00272       bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const;
00273       uint8_t feEnableRegister() const;
00274       bool feEnabled(const uint8_t internalFEUnitNum) const;
00275       uint8_t feOverflowRegister() const;
00276       bool feOverflow(const uint8_t internalFEUnitNum) const;
00277       uint16_t fedStatusRegisterWord() const;
00278       FEDStatusRegister fedStatusRegister() const;
00279       void print(std::ostream& os) const;
00280       //used by digi2Raw
00281       //returns ordered buffer (ie this may need to be swapped to get original order)
00282       const uint8_t* data() const;
00283       bool wasSwapped() const;
00284       TrackerSpecialHeader& setBufferFormat(const FEDBufferFormat newBufferFormat);
00285       TrackerSpecialHeader& setHeaderType(const FEDHeaderType headerType);
00286       TrackerSpecialHeader& setReadoutMode(const FEDReadoutMode readoutMode);
00287       TrackerSpecialHeader& setDataType(const FEDDataType dataType);
00288       TrackerSpecialHeader& setAPVEAddress(const uint8_t address);
00289       TrackerSpecialHeader& setAPVEAddressErrorRegister(const uint8_t addressErrorRegister);
00290       TrackerSpecialHeader& setAPVAddressErrorForFEUnit(const uint8_t internalFEUnitNum, const bool error);
00291       TrackerSpecialHeader& setFEEnableRegister(const uint8_t feEnableRegister);
00292       TrackerSpecialHeader& setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled);
00293       TrackerSpecialHeader& setFEOverflowRegister(const uint8_t feOverflowRegister);
00294       TrackerSpecialHeader& setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow);
00295       TrackerSpecialHeader& setFEDStatusRegister(const FEDStatusRegister fedStatusRegister);
00296       TrackerSpecialHeader(const FEDBufferFormat bufferFormat, const FEDReadoutMode readoutMode,
00297                            const FEDHeaderType headerType, const FEDDataType dataType,
00298                            const uint8_t address = 0x00, const uint8_t addressErrorRegister = 0x00,
00299                            const uint8_t feEnableRegister = 0xFF, const uint8_t feOverflowRegister = 0x00,
00300                            const FEDStatusRegister fedStatusRegister = FEDStatusRegister());
00301     private:
00302       void setBufferFormatByte(const FEDBufferFormat newBufferFormat);
00303       void setHeaderTypeNibble(const uint8_t value);
00304       void setReadoutModeBits(const uint8_t value);
00305       void setDataTypeBit(const bool value);
00306       enum byteIndicies { FEDSTATUS=0, FEOVERFLOW=2, FEENABLE=3, ADDRESSERROR=4, APVEADDRESS=5, BUFFERTYPE=6, BUFFERFORMAT=7 };
00307       //copy of header, 32 bit word swapped if needed
00308       uint8_t specialHeader_[8];
00309       //was the header word swapped wrt order in buffer?
00310       bool wordSwapped_;
00311     };
00312 
00313   class FEDBackendStatusRegister
00314     {
00315     public:
00316       FEDBackendStatusRegister(const uint32_t backendStatusRegister);
00317       bool internalFreezeFlag() const;
00318       bool slinkDownFlag() const;
00319       bool slinkFullFlag() const;
00320       bool backpressureFlag() const;
00321       bool ttcReadyFlag() const;
00322       bool trackerHeaderMonitorDataReadyFlag() const;
00323       FEDBufferState qdrMemoryState() const;
00324       FEDBufferState frameAddressFIFOState() const;
00325       FEDBufferState totalLengthFIFOState() const;
00326       FEDBufferState trackerHeaderFIFOState() const;
00327       FEDBufferState l1aBxFIFOState() const;
00328       FEDBufferState feEventLengthFIFOState() const;
00329       FEDBufferState feFPGABufferState() const;
00330       void print(std::ostream& os) const;
00331       void printFlags(std::ostream& os) const;
00332       operator uint32_t () const;
00333       //used by digi2Raw
00334       FEDBackendStatusRegister& setInternalFreezeFlag(const bool bitSet);
00335       FEDBackendStatusRegister& setSLinkDownFlag(const bool bitSet);
00336       FEDBackendStatusRegister& setSLinkFullFlag(const bool bitSet);
00337       FEDBackendStatusRegister& setBackpressureFlag(const bool bitSet);
00338       FEDBackendStatusRegister& setTTCReadyFlag(const bool bitSet);
00339       FEDBackendStatusRegister& setTrackerHeaderMonitorDataReadyFlag(const bool bitSet);
00340       FEDBackendStatusRegister& setQDRMemoryState(const FEDBufferState state);
00341       FEDBackendStatusRegister& setFrameAddressFIFOState(const FEDBufferState state);
00342       FEDBackendStatusRegister& setTotalLengthFIFOState(const FEDBufferState state);
00343       FEDBackendStatusRegister& setTrackerHeaderFIFOState(const FEDBufferState state);
00344       FEDBackendStatusRegister& setL1ABXFIFOState(const FEDBufferState state);
00345       FEDBackendStatusRegister& setFEEventLengthFIFOState(const FEDBufferState state);
00346       FEDBackendStatusRegister& setFEFPGABufferState(const FEDBufferState state);
00347       FEDBackendStatusRegister(const FEDBufferState qdrMemoryBufferState = BUFFER_STATE_UNSET,
00348                                const FEDBufferState frameAddressFIFOBufferState = BUFFER_STATE_UNSET,
00349                                const FEDBufferState totalLengthFIFOBufferState = BUFFER_STATE_UNSET,
00350                                const FEDBufferState trackerHeaderFIFOBufferState = BUFFER_STATE_UNSET,
00351                                const FEDBufferState l1aBxFIFOBufferState = BUFFER_STATE_UNSET,
00352                                const FEDBufferState feEventLengthFIFOBufferState = BUFFER_STATE_UNSET,
00353                                const FEDBufferState feFPGABufferState = BUFFER_STATE_UNSET,
00354                                const bool backpressure = false, const bool slinkFull = false,
00355                                const bool slinkDown = false, const bool internalFreeze = false,
00356                                const bool trackerHeaderMonitorDataReady = false, const bool ttcReady = true);                               
00357     private:
00358       bool getBit(const uint8_t num) const;
00359       void setBit(const uint8_t num, const bool bitSet);
00360       //get the state of the buffer in position 'bufferPosition'
00361       FEDBufferState getBufferState(const uint8_t bufferPosition) const;
00362       //set the state of the buffer in position 'bufferPosition' to state 'state'
00363       void setBufferSate(const uint8_t bufferPosition, const FEDBufferState state);
00364       void printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream& os) const;
00365       //constants marking order of flags in buffer
00366       //eg. bit offset for L1A/BX FIFO Partial full flag is STATE_OFFSET_PARTIAL_FULL+BUFFER_POSITION_L1ABX_FIFO
00367       //    bit offset for total length FIFO empty flag is STATE_OFFSET_EMPTY+BUFFER_POSITION_TOTAL_LENGTH_FIFO
00368       //see BE FPGA technical description
00369       enum bufferPositions { BUFFER_POSITION_QDR_MEMORY=0,
00370                              BUFFER_POSITION_FRAME_ADDRESS_FIFO=1,
00371                              BUFFER_POSITION_TOTAL_LENGTH_FIFO=2,
00372                              BUFFER_POSITION_TRACKER_HEADER_FIFO=3,
00373                              BUFFER_POSITION_L1ABX_FIFO=4,
00374                              BUFFER_POSITION_FE_EVENT_LENGTH_FIFO=5,
00375                              BUFFER_POSITION_FE_FPGA_BUFFER=6 };
00376       enum stateOffsets { STATE_OFFSET_FULL=8,
00377                           STATE_OFFSET_PARTIAL_FULL=16,
00378                           STATE_OFFSET_EMPTY=24 };
00379       uint32_t data_;
00380     };
00381 
00382   class FEDFEHeader
00383     {
00384     public:
00385       //factory function: allocates new FEDFEHeader derrivative of appropriate type
00386       static std::auto_ptr<FEDFEHeader> newFEHeader(const FEDHeaderType headerType, const uint8_t* headerBuffer);
00387       //used by digi2Raw
00388       static std::auto_ptr<FEDFEHeader> newFEHeader(const FEDHeaderType headerType);
00389       //create a buffer to use with digi2Raw
00390       static std::auto_ptr<FEDFEHeader> newFEFakeHeader(const FEDHeaderType headerType);
00391       virtual ~FEDFEHeader();
00392       //the length of the header
00393       virtual size_t lengthInBytes() const = 0;
00394       //check that there are no errors indicated in which ever error bits are available in the header
00395       //check bits for both APVs on a channel
00396       bool checkChannelStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
00397       virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const = 0;
00398       //check bits for one APV
00399       bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
00400       virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const = 0;
00401       virtual void print(std::ostream& os) const = 0;
00402       virtual FEDFEHeader* clone() const = 0;
00403       //used by digi2Raw
00404       virtual const uint8_t* data() const = 0;
00405       virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) = 0;
00406       virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) = 0;
00407       virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) = 0;
00408       virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) = 0;
00409       void setChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const FEDChannelStatus status);
00410     };
00411 
00412   class FEDAPVErrorHeader : public FEDFEHeader
00413     {
00414     public:
00415       explicit FEDAPVErrorHeader(const uint8_t* headerBuffer);
00416       virtual ~FEDAPVErrorHeader();
00417       virtual size_t lengthInBytes() const;
00418       virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const;
00419       virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00420       virtual void print(std::ostream& os) const;
00421       virtual FEDAPVErrorHeader* clone() const;
00422       //used by digi2Raw
00423       virtual const uint8_t* data() const;
00424       FEDAPVErrorHeader& setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood);
00425       FEDAPVErrorHeader& setAPVStatusBit(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum, const bool apvGood);
00426       FEDAPVErrorHeader(const std::vector<bool> apvsGood = std::vector<bool>(APVS_PER_FED,true));
00427       //Information which is not present in APVError mode is allowed to be set here so that the methods can be called on the base class without caring
00428       //if the values need to be set.
00429       virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status);
00430       virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address);
00431       virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister);
00432       virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length);
00433     private:
00434       static const size_t APV_ERROR_HEADER_SIZE_IN_64BIT_WORDS = 3;
00435       static const size_t APV_ERROR_HEADER_SIZE_IN_BYTES = APV_ERROR_HEADER_SIZE_IN_64BIT_WORDS*8;
00436       uint8_t header_[APV_ERROR_HEADER_SIZE_IN_BYTES];
00437     };
00438 
00439   class FEDFullDebugHeader : public FEDFEHeader
00440     {
00441     public:
00442       explicit FEDFullDebugHeader(const uint8_t* headerBuffer);
00443       virtual ~FEDFullDebugHeader();
00444       virtual size_t lengthInBytes() const;
00445       virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const;
00446       virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00447       virtual void print(std::ostream& os) const;
00448       virtual FEDFullDebugHeader* clone() const;
00449       
00450       uint8_t feUnitMajorityAddress(const uint8_t internalFEUnitNum) const;
00451       FEDBackendStatusRegister beStatusRegister() const;
00452       uint32_t daqRegister() const;
00453       uint32_t daqRegister2() const;
00454       uint16_t feUnitLength(const uint8_t internalFEUnitNum) const;
00455       bool fePresent(const uint8_t internalFEUnitNum) const;
00456       
00457       FEDChannelStatus getChannelStatus(const uint8_t internalFEDChannelNum) const;
00458       FEDChannelStatus getChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
00459       
00460       //These methods return true if there was an error of the appropriate type (ie if the error bit is 0).
00461       //They return false if the error could not occur due to a more general error.
00462       //was channel unlocked
00463       bool unlocked(const uint8_t internalFEDChannelNum) const;
00464       bool unlocked(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
00465       //was channel out of sync if it was unlocked
00466       bool outOfSync(const uint8_t internalFEDChannelNum) const;
00467       bool outOfSync(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
00468       //was there an internal APV error if it was in sync
00469       bool apvError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00470       bool apvError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
00471       //was the APV address wrong if it was in sync (does not depend on APV internal error bit)
00472       bool apvAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00473       bool apvAddressError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
00474       
00475       //used by digi2Raw
00476       virtual const uint8_t* data() const;
00477       virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status);
00478       virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address);
00479       virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister);
00480       virtual void setDAQRegister(const uint32_t daqRegister);
00481       virtual void setDAQRegister2(const uint32_t daqRegister2);
00482       virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length);
00483       FEDFullDebugHeader(const std::vector<uint16_t> feUnitLengths = std::vector<uint16_t>(FEUNITS_PER_FED,0),
00484                          const std::vector<uint8_t> feMajorityAddresses = std::vector<uint8_t>(FEUNITS_PER_FED,0),
00485                          const std::vector<FEDChannelStatus> channelStatus = std::vector<FEDChannelStatus>(FEDCH_PER_FED,CHANNEL_STATUS_NO_PROBLEMS),
00486                          const FEDBackendStatusRegister beStatusRegister = FEDBackendStatusRegister(),
00487                          const uint32_t daqRegister = 0, const uint32_t daqRegister2 = 0);
00488     private:
00489       bool getBit(const uint8_t internalFEDChannelNum, const uint8_t bit) const;
00490       static uint32_t get32BitWordFrom(const uint8_t* startOfWord);
00491       static void set32BitWordAt(uint8_t* startOfWord, const uint32_t value);
00492       const uint8_t* feWord(const uint8_t internalFEUnitNum) const;
00493       uint8_t* feWord(const uint8_t internalFEUnitNum);
00494       void setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value);
00495       
00496       //These methods return true if there was an error of the appropriate type (ie if the error bit is 0).
00497       //They ignore any previous errors which make the status bits meaningless and return the value of the bit anyway.
00498       //In general, the methods above which only return an error for the likely cause are more useful.
00499       bool unlockedFromBit(const uint8_t internalFEDChannelNum) const;
00500       bool outOfSyncFromBit(const uint8_t internalFEDChannelNum) const;
00501       bool apvErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00502       bool apvAddressErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
00503       
00504       //following methods set the bits to 1 (no error) if value is false
00505       void setUnlocked(const uint8_t internalFEDChannelNum, const bool value);
00506       void setOutOfSync(const uint8_t internalFEDChannelNum, const bool value);
00507       void setAPVAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value);
00508       void setAPVError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value);
00509       static const size_t FULL_DEBUG_HEADER_SIZE_IN_64BIT_WORDS = FEUNITS_PER_FED*2;
00510       static const size_t FULL_DEBUG_HEADER_SIZE_IN_BYTES = FULL_DEBUG_HEADER_SIZE_IN_64BIT_WORDS*8;
00511       uint8_t header_[FULL_DEBUG_HEADER_SIZE_IN_BYTES];
00512     };
00513 
00514   //holds information about position of a channel in the buffer for use by unpacker
00515   class FEDChannel
00516     {
00517     public:
00518       FEDChannel(const uint8_t*const data, const size_t offset, const uint16_t length);
00519       //gets length from first 2 bytes (assuming normal FED channel)
00520       FEDChannel(const uint8_t*const data, const size_t offset);
00521       uint16_t length() const;
00522       const uint8_t* data() const;
00523       size_t offset() const;
00524       uint16_t cmMedian(const uint8_t apvIndex) const;
00525     private:
00526       friend class FEDBuffer;
00527       //third byte of channel data for normal FED channels
00528       uint8_t packetCode() const;
00529       const uint8_t* data_;
00530       size_t offset_;
00531       uint16_t length_;
00532     };
00533 
00534   //base class for sistrip FED buffers which have a DAQ header/trailer and tracker special header
00535   class FEDBufferBase
00536     {
00537     public:
00538       FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat = false);
00539       virtual ~FEDBufferBase();
00540       //dump buffer to stream
00541       void dump(std::ostream& os) const;
00542       //dump original buffer before word swapping
00543       void dumpOriginalBuffer(std::ostream& os) const;
00544       virtual void print(std::ostream& os) const;
00545       //calculate the CRC from the buffer
00546       uint16_t calcCRC() const;
00547   
00548       //methods to get parts of the buffer
00549       FEDDAQHeader daqHeader() const;
00550       FEDDAQTrailer daqTrailer() const;
00551       size_t bufferSize() const;
00552       TrackerSpecialHeader trackerSpecialHeader() const;
00553       //methods to get info from DAQ header
00554       FEDDAQEventType daqEventType() const;
00555       uint32_t daqLvl1ID() const;
00556       uint16_t daqBXID() const;
00557       uint16_t daqSourceID() const;
00558       uint16_t sourceID() const;
00559       //methods to get info from DAQ trailer
00560       uint32_t daqEventLengthIn64bitWords() const;
00561       uint32_t daqEventLengthInBytes() const;
00562       uint16_t daqCRC() const;
00563       FEDTTSBits daqTTSState() const;
00564       //methods to get info from the tracker special header
00565       FEDBufferFormat bufferFormat() const;
00566       FEDHeaderType headerType() const;
00567       FEDReadoutMode readoutMode() const;
00568       FEDDataType dataType() const;
00569       uint8_t apveAddress() const;
00570       bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const;
00571       bool feEnabled(const uint8_t internalFEUnitNum) const;
00572       uint8_t nFEUnitsEnabled() const;
00573       bool feOverflow(const uint8_t internalFEUnitNum) const;
00574       FEDStatusRegister fedStatusRegister() const;
00575       
00576       //check that channel has no errors
00577       virtual bool channelGood(const uint8_t internalFEDChannelNum) const;
00578       bool channelGood(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
00579       //return channel object for channel
00580       const FEDChannel& channel(const uint8_t internalFEDChannelNum) const;
00581       const FEDChannel& channel(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
00582   
00583       //summary checks
00584       //check that tracker special header is valid (does not check for FE unit errors indicated in special header)
00585       bool doTrackerSpecialHeaderChecks() const;
00586       //check for errors in DAQ heaqder and trailer (not including bad CRC)
00587       bool doDAQHeaderAndTrailerChecks() const;
00588       //do both
00589       virtual bool doChecks() const;
00590       //print the result of all detailed checks
00591       virtual std::string checkSummary() const;
00592   
00593       //detailed checks
00594       bool checkCRC() const;
00595       bool checkMajorityAddresses() const;
00596       //methods to check tracker special header
00597       bool checkBufferFormat() const;
00598       bool checkHeaderType() const;
00599       bool checkReadoutMode() const;
00600       bool checkAPVEAddressValid() const;
00601       bool checkNoFEOverflows() const;
00602       //methods to check daq header and trailer
00603       bool checkNoSlinkCRCError() const;
00604       bool checkNoSLinkTransmissionError() const;
00605       bool checkSourceIDs() const;
00606       bool checkNoUnexpectedSourceID() const;
00607       bool checkNoExtraHeadersOrTrailers() const;
00608       bool checkLengthFromTrailer() const;
00609     protected:
00610       const uint8_t* getPointerToDataAfterTrackerSpecialHeader() const;
00611       const uint8_t* getPointerToByteAfterEndOfPayload() const;
00612       FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat, const bool fillChannelVector);
00613       std::vector<FEDChannel> channels_;
00614     private:
00615       void init(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat);
00616       const uint8_t* originalBuffer_;
00617       const uint8_t* orderedBuffer_;
00618       const size_t bufferSize_;
00619       FEDDAQHeader daqHeader_;
00620       FEDDAQTrailer daqTrailer_;
00621       TrackerSpecialHeader specialHeader_;
00622     };
00623 
00624   //
00625   // Inline function definitions
00626   //
00627   
00628   inline std::ostream& operator << (std::ostream& os, const FEDBufferBase& obj) { obj.print(os); os << obj.checkSummary(); return os; }
00629 
00630   inline uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
00631     {
00632       return (internalFEUnitNum*FEDCH_PER_FEUNIT + internalFEUnitChannelNum);
00633     }
00634 
00635   inline std::ostream& operator << (std::ostream& os, const FEDDAQHeader& obj) { obj.print(os); return os; }
00636   inline std::ostream& operator << (std::ostream& os, const FEDDAQTrailer& obj) { obj.print(os); return os; }
00637   inline std::ostream& operator << (std::ostream& os, const TrackerSpecialHeader& obj) { obj.print(os); return os; }
00638   inline std::ostream& operator << (std::ostream& os, const FEDStatusRegister& obj) { obj.print(os); return os; }
00639   inline std::ostream& operator << (std::ostream& os, const FEDFEHeader& obj) { obj.print(os); return os; }
00640 
00641   //FEDStripOrdering
00642 
00643   inline uint8_t FEDStripOrdering::physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel)
00644     {
00645       return physicalOrderForStripInAPV(readoutOrderStripIndexInChannel/2) + (readoutOrderStripIndexInChannel%2)*STRIPS_PER_APV;
00646     }
00647   
00648   inline uint8_t FEDStripOrdering::readoutOrderForStripInChannel(const uint8_t physicalOrderStripIndexInChannel)
00649     {
00650       return ( readoutOrderForStripInAPV(physicalOrderStripIndexInChannel%128)*2 + (physicalOrderStripIndexInChannel/128) );
00651     }
00652   
00653   inline uint8_t FEDStripOrdering::physicalOrderForStripInAPV(const uint8_t readout_order)
00654     {
00655       return ( (32 * (readout_order%4)) +
00656                (8 * static_cast<uint16_t>(static_cast<float>(readout_order)/4.0)) -
00657                (31 * static_cast<uint16_t>(static_cast<float>(readout_order)/16.0))
00658              );
00659     }
00660   
00661   inline uint8_t FEDStripOrdering::readoutOrderForStripInAPV(const uint8_t physical_order)
00662     {
00663       return ( 4*((static_cast<uint16_t>((static_cast<float>(physical_order)/8.0)))%4) +
00664                static_cast<uint16_t>(static_cast<float>(physical_order)/32.0) +
00665                16*(physical_order%8)
00666              );
00667     }
00668 
00669   //TrackerSpecialHeader
00670 
00671   inline TrackerSpecialHeader::TrackerSpecialHeader()
00672     : wordSwapped_(false)
00673     {
00674     }
00675   
00676   inline uint8_t TrackerSpecialHeader::bufferFormatByte() const
00677     { return specialHeader_[BUFFERFORMAT]; }
00678   
00679   inline uint8_t TrackerSpecialHeader::headerTypeNibble() const
00680     { return ( (specialHeader_[BUFFERTYPE] & 0xF0) >> 4 ); }
00681   
00682   inline uint8_t TrackerSpecialHeader::trackerEventTypeNibble() const
00683     { return (specialHeader_[BUFFERTYPE] & 0x0F); }
00684   
00685   inline uint8_t TrackerSpecialHeader::apveAddress() const
00686     { return specialHeader_[APVEADDRESS]; }
00687   
00688   inline uint8_t TrackerSpecialHeader::apvAddressErrorRegister() const
00689     { return specialHeader_[ADDRESSERROR]; }
00690   
00691   inline bool TrackerSpecialHeader::majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
00692     {
00693       return ( !(readoutMode() == READOUT_MODE_SCOPE) && !( (0x1<<internalFEUnitNum) & apvAddressErrorRegister() ) );
00694     }
00695   
00696   inline uint8_t TrackerSpecialHeader::feEnableRegister() const
00697     { return specialHeader_[FEENABLE]; }
00698   
00699   inline bool TrackerSpecialHeader::feEnabled(const uint8_t internalFEUnitNum) const
00700     {
00701       return ( (0x1<<internalFEUnitNum) & feEnableRegister() );
00702     }
00703   
00704   inline uint8_t TrackerSpecialHeader::feOverflowRegister() const
00705     { return specialHeader_[FEOVERFLOW]; }
00706   
00707   inline bool TrackerSpecialHeader::feOverflow(const uint8_t internalFEUnitNum) const
00708     {
00709       return ( (0x1<<internalFEUnitNum) & feOverflowRegister() );
00710     }
00711   
00712   inline uint16_t TrackerSpecialHeader::fedStatusRegisterWord() const
00713     {
00714       //get 16 bits
00715       uint16_t statusRegister = ( (specialHeader_[(FEDSTATUS+1)]<<8) | specialHeader_[FEDSTATUS]);
00716       return statusRegister;
00717     }
00718   
00719   inline FEDStatusRegister TrackerSpecialHeader::fedStatusRegister() const
00720     { return FEDStatusRegister(fedStatusRegisterWord()); }
00721   
00722   inline void TrackerSpecialHeader::print(std::ostream& os) const
00723     { printHex(specialHeader_,8,os); }
00724   
00725   inline const uint8_t* TrackerSpecialHeader::data() const
00726     {
00727       return specialHeader_;
00728     }
00729   
00730   inline bool TrackerSpecialHeader::wasSwapped() const
00731     {
00732       return wordSwapped_;
00733     }
00734   
00735   inline void TrackerSpecialHeader::setHeaderTypeNibble(const uint8_t value)
00736     {
00737       specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & 0x0F) | ((value<<4) & 0xF0) );
00738     }
00739   
00740   inline void TrackerSpecialHeader::setReadoutModeBits(const uint8_t value)
00741     {
00742       specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & (~0x0E)) | (value & 0x0E) );
00743     }
00744       
00745   inline void TrackerSpecialHeader::setDataTypeBit(const bool value)
00746     {
00747       specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & (~0x01)) | (value ? 0x01 : 0x00) );
00748     }
00749   
00750   inline TrackerSpecialHeader& TrackerSpecialHeader::setAPVEAddress(const uint8_t address)
00751     {
00752       specialHeader_[APVEADDRESS] = address;
00753       return *this;
00754     }
00755   
00756   inline TrackerSpecialHeader& TrackerSpecialHeader::setAPVEAddressErrorRegister(const uint8_t addressErrorRegister)
00757     {
00758       specialHeader_[ADDRESSERROR] = addressErrorRegister;
00759       return *this;
00760     }
00761   
00762   inline TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableRegister(const uint8_t feEnableRegister)
00763     {
00764       specialHeader_[FEENABLE] = feEnableRegister;
00765       return *this;
00766     }
00767   
00768   inline TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowRegister(const uint8_t feOverflowRegister)
00769     {
00770       specialHeader_[FEOVERFLOW] = feOverflowRegister;
00771       return *this;
00772     }
00773   
00774   inline TrackerSpecialHeader& TrackerSpecialHeader::setFEDStatusRegister(const FEDStatusRegister fedStatusRegister)
00775     {
00776       specialHeader_[FEDSTATUS] = (static_cast<uint16_t>(fedStatusRegister) & 0x00FF);
00777       specialHeader_[FEDSTATUS+1] = ( (static_cast<uint16_t>(fedStatusRegister) & 0xFF00) >> 8);
00778       return *this;
00779     }
00780 
00781   //FEDStatusRegister
00782 
00783   inline FEDStatusRegister::FEDStatusRegister(const uint16_t fedStatusRegister)
00784     : data_(fedStatusRegister) { }
00785   
00786   inline FEDStatusRegister::operator uint16_t () const
00787     { return data_; }
00788   
00789   inline bool FEDStatusRegister::getBit(const uint8_t num) const
00790     { return ( (0x1<<num) & (data_) ); }
00791   
00792   inline bool FEDStatusRegister::slinkFullFlag() const
00793     { return getBit(0); }
00794   
00795   inline bool FEDStatusRegister::trackerHeaderMonitorDataReadyFlag() const
00796     { return getBit(1); }
00797   
00798   inline bool FEDStatusRegister::qdrMemoryFullFlag() const
00799     { return getBit(2); }
00800   
00801   inline bool FEDStatusRegister::qdrMemoryPartialFullFlag() const
00802     { return getBit(3); }
00803   
00804   inline bool FEDStatusRegister::qdrMemoryEmptyFlag() const
00805     { return getBit(4); }
00806   
00807   inline bool FEDStatusRegister::l1aBxFIFOFullFlag() const
00808     { return getBit(5); }
00809   
00810   inline bool FEDStatusRegister::l1aBxFIFOPartialFullFlag() const
00811     { return getBit(6); }
00812   
00813   inline bool FEDStatusRegister::l1aBxFIFOEmptyFlag() const
00814     { return getBit(7); }
00815   
00816   inline bool FEDStatusRegister::feDataMissingFlag(const uint8_t internalFEUnitNum) const
00817     {
00818       return getBit(8+internalFEUnitNum);
00819     }
00820   
00821   inline void FEDStatusRegister::print(std::ostream& os) const
00822     { printHex(&data_,2,os); }
00823   
00824   inline FEDStatusRegister& FEDStatusRegister::setSLinkFullFlag(const bool bitSet)
00825     { setBit(0,bitSet); return *this; }
00826   
00827   inline FEDStatusRegister& FEDStatusRegister::setTrackerHeaderMonitorDataReadyFlag(const bool bitSet)
00828     { setBit(1,bitSet); return *this; }
00829   
00830   inline void FEDStatusRegister::setQDRMemoryFullFlag(const bool bitSet)
00831     { setBit(2,bitSet); }
00832   
00833   inline void FEDStatusRegister::setQDRMemoryPartialFullFlag(const bool bitSet)
00834     { setBit(3,bitSet); }
00835   
00836   inline void FEDStatusRegister::setQDRMemoryEmptyFlag(const bool bitSet)
00837     { setBit(4,bitSet); }
00838   
00839   inline void FEDStatusRegister::setL1ABXFIFOFullFlag(const bool bitSet)
00840     { setBit(5,bitSet); }
00841   
00842   inline void FEDStatusRegister::setL1ABXFIFOPartialFullFlag(const bool bitSet)
00843     { setBit(6,bitSet); }
00844   
00845   inline void FEDStatusRegister::setL1ABXFIFOEmptyFlag(const bool bitSet)
00846     { setBit(7,bitSet); }
00847   
00848   inline FEDStatusRegister::FEDStatusRegister(const FEDBufferState qdrMemoryBufferState, const FEDBufferState l1aBxFIFOBufferState,
00849                                               const bool trackerHeaderMonitorDataReadyFlagSet, const bool slinkFullFlagSet)
00850     : data_(0x0000)
00851     {
00852       setSLinkFullFlag(slinkFullFlagSet);
00853       setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReadyFlagSet);
00854       setQDRMemoryBufferState(qdrMemoryBufferState);
00855       setL1ABXFIFOBufferState(l1aBxFIFOBufferState);
00856     }
00857 
00858   //FEDBackendStatusRegister
00859 
00860   inline FEDBackendStatusRegister::FEDBackendStatusRegister(const uint32_t backendStatusRegister)
00861     : data_(backendStatusRegister) { }
00862   
00863   inline FEDBackendStatusRegister::operator uint32_t () const
00864     { return data_; }
00865   
00866   inline void FEDBackendStatusRegister::print(std::ostream& os) const
00867     { printHex(&data_,4,os); }
00868   
00869   inline bool FEDBackendStatusRegister::getBit(const uint8_t num) const
00870     { return ( (0x1<<num) & (data_) ); }  
00871   
00872   inline bool FEDBackendStatusRegister::internalFreezeFlag() const
00873     { return getBit(1); }
00874   
00875   inline bool FEDBackendStatusRegister::slinkDownFlag() const
00876     { return getBit(2); }
00877   
00878   inline bool FEDBackendStatusRegister::slinkFullFlag() const
00879     { return getBit(3); }
00880   
00881   inline bool FEDBackendStatusRegister::backpressureFlag() const
00882     { return getBit(4); }
00883   
00884   inline bool FEDBackendStatusRegister::ttcReadyFlag() const
00885     { return getBit(6); }
00886   
00887   inline bool FEDBackendStatusRegister::trackerHeaderMonitorDataReadyFlag() const
00888     { return getBit(7); }
00889   
00890   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setInternalFreezeFlag(const bool bitSet)
00891     { setBit(1,bitSet); return *this; }
00892   
00893   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setSLinkDownFlag(const bool bitSet)
00894     { setBit(2,bitSet); return *this; }
00895   
00896   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setSLinkFullFlag(const bool bitSet)
00897     { setBit(3,bitSet); return *this; }
00898   
00899   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setBackpressureFlag(const bool bitSet)
00900     { setBit(4,bitSet); return *this; }
00901   
00902   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setTTCReadyFlag(const bool bitSet)
00903     { setBit(6,bitSet); return *this; }
00904   
00905   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setTrackerHeaderMonitorDataReadyFlag(const bool bitSet)
00906     { setBit(7,bitSet); return *this; }
00907   
00908   inline FEDBufferState FEDBackendStatusRegister::qdrMemoryState() const
00909     {
00910       return getBufferState(BUFFER_POSITION_QDR_MEMORY);
00911     }
00912   
00913   inline FEDBufferState FEDBackendStatusRegister::frameAddressFIFOState() const
00914     {
00915       return getBufferState(BUFFER_POSITION_FRAME_ADDRESS_FIFO);
00916     }
00917   
00918   inline FEDBufferState FEDBackendStatusRegister::totalLengthFIFOState() const
00919     {
00920       return getBufferState(BUFFER_POSITION_TOTAL_LENGTH_FIFO);
00921     }
00922   
00923   inline FEDBufferState FEDBackendStatusRegister::trackerHeaderFIFOState() const
00924     {
00925       return getBufferState(BUFFER_POSITION_TRACKER_HEADER_FIFO);
00926     }
00927   
00928   inline FEDBufferState FEDBackendStatusRegister::l1aBxFIFOState() const
00929     {
00930       return getBufferState(BUFFER_POSITION_L1ABX_FIFO);
00931     }
00932   
00933   inline FEDBufferState FEDBackendStatusRegister::feEventLengthFIFOState() const
00934     {
00935       return getBufferState(BUFFER_POSITION_FE_EVENT_LENGTH_FIFO);
00936     }
00937   
00938   inline FEDBufferState FEDBackendStatusRegister::feFPGABufferState() const
00939     {
00940       return getBufferState(BUFFER_POSITION_FE_FPGA_BUFFER);
00941     }
00942   
00943   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setQDRMemoryState(const FEDBufferState state)
00944     {
00945       setBufferSate(BUFFER_POSITION_QDR_MEMORY,state);
00946       return *this;
00947     }
00948   
00949   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setFrameAddressFIFOState(const FEDBufferState state)
00950     {
00951       setBufferSate(BUFFER_POSITION_FRAME_ADDRESS_FIFO,state);
00952       return *this;
00953     }
00954   
00955   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setTotalLengthFIFOState(const FEDBufferState state)
00956     {
00957       setBufferSate(BUFFER_POSITION_TOTAL_LENGTH_FIFO,state);
00958       return *this;
00959     }
00960   
00961   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setTrackerHeaderFIFOState(const FEDBufferState state)
00962     {
00963       setBufferSate(BUFFER_POSITION_TRACKER_HEADER_FIFO,state);
00964       return *this;
00965     }
00966   
00967   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setL1ABXFIFOState(const FEDBufferState state)
00968     {
00969       setBufferSate(BUFFER_POSITION_L1ABX_FIFO,state);
00970       return *this;
00971     }
00972   
00973   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setFEEventLengthFIFOState(const FEDBufferState state)
00974     {
00975       setBufferSate(BUFFER_POSITION_FE_EVENT_LENGTH_FIFO,state);
00976       return *this;
00977     }
00978   
00979   inline FEDBackendStatusRegister& FEDBackendStatusRegister::setFEFPGABufferState(const FEDBufferState state)
00980     {
00981       setBufferSate(BUFFER_POSITION_FE_FPGA_BUFFER,state);
00982       return *this;
00983     }
00984 
00985   //FEDFEHeader
00986 
00987   inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEHeader(const FEDHeaderType headerType, const uint8_t* headerBuffer)
00988     {
00989       switch (headerType) {
00990       case HEADER_TYPE_FULL_DEBUG:
00991         return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader(headerBuffer));
00992       case HEADER_TYPE_APV_ERROR:
00993         return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader(headerBuffer));
00994       default:
00995         return std::auto_ptr<FEDFEHeader>();
00996       }
00997     }
00998   
00999   inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEHeader(const FEDHeaderType headerType)
01000     {
01001       switch (headerType) {
01002       case HEADER_TYPE_FULL_DEBUG:
01003         return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader());
01004       case HEADER_TYPE_APV_ERROR:
01005         return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader());
01006       default:
01007         return std::auto_ptr<FEDFEHeader>();
01008       }
01009     }
01010   
01011   inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEFakeHeader(const FEDHeaderType headerType)
01012     {
01013       switch (headerType) {
01014       case HEADER_TYPE_FULL_DEBUG:
01015         return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader);
01016       case HEADER_TYPE_APV_ERROR:
01017         return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader);
01018       default:
01019         return std::auto_ptr<FEDFEHeader>();
01020       }
01021     }
01022   
01023   inline bool FEDFEHeader::checkChannelStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
01024     {
01025       return checkChannelStatusBits(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
01026     }
01027   
01028   inline bool FEDFEHeader::checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
01029     {
01030       return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
01031     }
01032   
01033   inline void FEDFEHeader::setChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const FEDChannelStatus status)
01034     {
01035       this->setChannelStatus(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),status);
01036     }
01037   
01038   inline FEDAPVErrorHeader::FEDAPVErrorHeader(const uint8_t* headerBuffer)
01039     {
01040       memcpy(header_,headerBuffer,APV_ERROR_HEADER_SIZE_IN_BYTES);
01041     }
01042   
01043   inline FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum,
01044                                                                const uint8_t apvNum, const bool apvGood)
01045     {
01046       return setAPVStatusBit(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum,apvGood);
01047     }
01048   
01049   inline FEDFullDebugHeader::FEDFullDebugHeader(const uint8_t* headerBuffer)
01050     {
01051       memcpy(header_,headerBuffer,FULL_DEBUG_HEADER_SIZE_IN_BYTES);
01052     }
01053   
01054   inline uint8_t FEDFullDebugHeader::feUnitMajorityAddress(const uint8_t internalFEUnitNum) const
01055     {
01056       return feWord(internalFEUnitNum)[9];
01057     }
01058   
01059   inline FEDBackendStatusRegister FEDFullDebugHeader::beStatusRegister() const
01060     {
01061       return FEDBackendStatusRegister(get32BitWordFrom(feWord(0)+10));
01062     }
01063   
01064   inline uint32_t FEDFullDebugHeader::daqRegister() const
01065     {
01066       return get32BitWordFrom(feWord(7)+10);
01067     }
01068   
01069   inline uint32_t FEDFullDebugHeader::daqRegister2() const
01070     {
01071       return get32BitWordFrom(feWord(6)+10);
01072     }
01073   
01074   inline uint16_t FEDFullDebugHeader::feUnitLength(const uint8_t internalFEUnitNum) const
01075     {
01076       return ( (feWord(internalFEUnitNum)[15]<<8) | (feWord(internalFEUnitNum)[14]) );
01077     }
01078   
01079   inline bool FEDFullDebugHeader::fePresent(const uint8_t internalFEUnitNum) const
01080     {
01081       return (feUnitLength(internalFEUnitNum) != 0);
01082     }
01083   
01084   inline bool FEDFullDebugHeader::unlocked(const uint8_t internalFEDChannelNum) const
01085     {
01086       return unlockedFromBit(internalFEDChannelNum);
01087     }
01088   
01089   inline bool FEDFullDebugHeader::unlocked(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
01090     {
01091       return unlocked(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
01092     }
01093   
01094   inline bool FEDFullDebugHeader::outOfSync(const uint8_t internalFEDChannelNum) const
01095     {
01096       return ( !unlocked(internalFEDChannelNum) && outOfSyncFromBit(internalFEDChannelNum) );
01097     }
01098   
01099   inline bool FEDFullDebugHeader::outOfSync(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
01100     {
01101       return outOfSync(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
01102     }
01103   
01104   inline bool FEDFullDebugHeader::apvError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
01105     {
01106       return ( !unlockedFromBit(internalFEDChannelNum) &&
01107                !outOfSyncFromBit(internalFEDChannelNum) &&
01108                apvErrorFromBit(internalFEDChannelNum,apvNum) );
01109     }
01110   
01111   inline bool FEDFullDebugHeader::apvError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
01112     {
01113       return apvError(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
01114     }
01115   
01116   inline bool FEDFullDebugHeader::apvAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
01117     {
01118       return ( !unlockedFromBit(internalFEDChannelNum) &&
01119                !outOfSyncFromBit(internalFEDChannelNum) &&
01120                apvAddressErrorFromBit(internalFEDChannelNum,apvNum) );
01121     }
01122   
01123   inline bool FEDFullDebugHeader::apvAddressError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
01124     {
01125       return apvAddressError(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
01126     }
01127   
01128   inline FEDChannelStatus FEDFullDebugHeader::getChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
01129     {
01130       return getChannelStatus(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
01131     }
01132   
01133   inline bool FEDFullDebugHeader::unlockedFromBit(const uint8_t internalFEDChannelNum) const
01134     {
01135       return !getBit(internalFEDChannelNum,5);
01136     }
01137   
01138   inline bool FEDFullDebugHeader::outOfSyncFromBit(const uint8_t internalFEDChannelNum) const
01139     {
01140       return !getBit(internalFEDChannelNum,4);
01141     }
01142   
01143   inline bool FEDFullDebugHeader::apvErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
01144     {
01145       //Discovered March 2012: two bits inverted in firmware. Decided
01146       //to update documentation but keep firmware identical for
01147       //backward compatibility. So status bit order is actually:
01148       //apvErr1 - apvAddrErr0 - apvErr0 - apvAddrErr1 - OOS - unlocked.
01149       //Before, it was: return !getBit(internalFEDChannelNum,0+2*apvNum);
01150 
01151       return !getBit(internalFEDChannelNum,0+2*(1-apvNum));
01152     }
01153   
01154   inline bool FEDFullDebugHeader::apvAddressErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
01155     {
01156       return !getBit(internalFEDChannelNum,1+2*apvNum);
01157     }
01158   
01159   inline bool FEDFullDebugHeader::getBit(const uint8_t internalFEDChannelNum, const uint8_t bit) const
01160     {
01161       const uint8_t* pFEWord = feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT);
01162       const uint8_t bitInFeWord = ((FEDCH_PER_FEUNIT-1) - (internalFEDChannelNum%FEDCH_PER_FEUNIT)) * 6 + bit;
01163       return ( pFEWord[bitInFeWord/8] & (0x1 << (bitInFeWord%8)) );
01164     }
01165   
01166   inline uint32_t FEDFullDebugHeader::get32BitWordFrom(const uint8_t* startOfWord)
01167     {
01168       return ( startOfWord[0] | (startOfWord[1]<<8) | (startOfWord[2]<<16) | (startOfWord[3]<<24) );
01169     }
01170   
01171   inline void FEDFullDebugHeader::set32BitWordAt(uint8_t* startOfWord, const uint32_t value)
01172     {
01173       memcpy(startOfWord,&value,4);
01174     }
01175   
01176   inline const uint8_t* FEDFullDebugHeader::feWord(const uint8_t internalFEUnitNum) const
01177     {
01178       return header_+internalFEUnitNum*2*8;
01179     }
01180   
01181   //re-use const method
01182   inline uint8_t* FEDFullDebugHeader::feWord(const uint8_t internalFEUnitNum)
01183     {
01184       return const_cast<uint8_t*>(static_cast<const FEDFullDebugHeader*>(this)->feWord(internalFEUnitNum));
01185     }
01186   
01187   inline void FEDFullDebugHeader::setUnlocked(const uint8_t internalFEDChannelNum, const bool value)
01188     {
01189       setBit(internalFEDChannelNum,5,!value);
01190     }
01191   
01192   inline void FEDFullDebugHeader::setOutOfSync(const uint8_t internalFEDChannelNum, const bool value)
01193     {
01194       setBit(internalFEDChannelNum,4,!value);
01195     }
01196   
01197   inline void FEDFullDebugHeader::setAPVAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
01198     {
01199       setBit(internalFEDChannelNum,1+2*apvNum,!value);
01200     }
01201   
01202   inline void FEDFullDebugHeader::setAPVError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
01203     {
01204       //Discovered March 2012: two bits inverted in firmware. Decided
01205       //to update documentation but keep firmware identical for
01206       //backward compatibility. So status bit order is actually:
01207       //apvErr1 - apvAddrErr0 - apvErr0 - apvAddrErr1 - OOS - unlocked.
01208       //Before, it was: return !getBit(internalFEDChannelNum,0+2*apvNum);
01209 
01210       setBit(internalFEDChannelNum,0+2*(1-apvNum),!value);
01211     }
01212 
01213   //FEDDAQHeader
01214 
01215   inline FEDDAQHeader::FEDDAQHeader(const uint8_t* header)
01216     {
01217       memcpy(header_,header,8);
01218     }
01219   
01220   inline uint8_t FEDDAQHeader::boeNibble() const
01221     {
01222       return ( (header_[7] & 0xF0) >> 4 );
01223     }
01224   
01225   inline uint8_t FEDDAQHeader::eventTypeNibble() const
01226     {
01227       return (header_[7] & 0x0F);
01228     }
01229   
01230   inline uint32_t FEDDAQHeader::l1ID() const
01231     {
01232       return ( header_[4] | (header_[5]<<8) | (header_[6]<<16) );
01233     }
01234   
01235   inline uint16_t FEDDAQHeader::bxID() const
01236     {
01237       return ( (header_[3]<<4) | ((header_[2]&0xF0)>>4) );
01238     }
01239   
01240   inline uint16_t FEDDAQHeader::sourceID() const
01241     {
01242       return ( ((header_[2]&0x0F)<<8) | header_[1] );
01243     }
01244   
01245   inline uint8_t FEDDAQHeader::version() const
01246     {
01247       return ( (header_[0] & 0xF0) >> 4 );
01248     }
01249   
01250   inline bool FEDDAQHeader::hBit() const
01251     {
01252       return (header_[0] & 0x8);
01253     }
01254   
01255   inline bool FEDDAQHeader::lastHeader() const
01256     {
01257       return !hBit();
01258     }
01259   
01260   inline const uint8_t* FEDDAQHeader::data() const
01261     {
01262       return header_;
01263     }
01264   
01265   inline void FEDDAQHeader::print(std::ostream& os) const
01266     {
01267       printHex(header_,8,os);
01268     }
01269 
01270   //FEDDAQTrailer
01271 
01272   inline FEDDAQTrailer::FEDDAQTrailer(const uint8_t* trailer)
01273     {
01274       memcpy(trailer_,trailer,8);
01275     }
01276   
01277   inline uint8_t FEDDAQTrailer::eoeNibble() const
01278     {
01279       return ( (trailer_[7] & 0xF0) >> 4 );
01280     }
01281   
01282   inline uint32_t FEDDAQTrailer::eventLengthIn64BitWords() const
01283     {
01284       return ( trailer_[4] | (trailer_[5]<<8) | (trailer_[6]<<16) );
01285     }
01286   
01287   inline uint32_t FEDDAQTrailer::eventLengthInBytes() const
01288     {
01289       return eventLengthIn64BitWords()*8;
01290     }
01291   
01292   inline uint16_t FEDDAQTrailer::crc() const
01293     {
01294       return ( trailer_[2] | (trailer_[3]<<8) );
01295     }
01296   
01297   inline bool FEDDAQTrailer::cBit() const
01298     {
01299       return (trailer_[1] & 0x80);
01300     }
01301   
01302   inline bool FEDDAQTrailer::fBit() const
01303     {
01304       return (trailer_[1] & 0x40);
01305     }
01306   
01307   inline uint8_t FEDDAQTrailer::eventStatusNibble() const
01308     {
01309       return (trailer_[1] & 0x0F);
01310     }
01311   
01312   inline uint8_t FEDDAQTrailer::ttsNibble() const
01313     {
01314       return ( (trailer_[0] & 0xF0) >> 4);
01315     }
01316   
01317   inline bool FEDDAQTrailer::tBit() const
01318     {
01319       return (trailer_[0] & 0x08);
01320     }
01321   
01322   inline bool FEDDAQTrailer::rBit() const
01323     {
01324       return (trailer_[0] & 0x04);
01325     }
01326   
01327   inline void FEDDAQTrailer::print(std::ostream& os) const
01328     {
01329       printHex(trailer_,8,os);
01330     }
01331   
01332   inline const uint8_t* FEDDAQTrailer::data() const
01333     {
01334       return trailer_;
01335     }
01336 
01337   //FEDBufferBase
01338 
01339   inline void FEDBufferBase::dump(std::ostream& os) const
01340     {
01341       printHex(orderedBuffer_,bufferSize_,os);
01342     }
01343   
01344   inline void FEDBufferBase::dumpOriginalBuffer(std::ostream& os) const
01345     {
01346       printHex(originalBuffer_,bufferSize_,os);
01347     }
01348   
01349   inline uint16_t FEDBufferBase::calcCRC() const
01350     {
01351       return calculateFEDBufferCRC(orderedBuffer_,bufferSize_);
01352     }
01353   
01354   inline FEDDAQHeader FEDBufferBase::daqHeader() const
01355     {
01356       return daqHeader_;
01357     }
01358   
01359   inline FEDDAQTrailer FEDBufferBase::daqTrailer() const
01360     {
01361       return daqTrailer_;
01362     }
01363   
01364   inline size_t FEDBufferBase::bufferSize() const
01365     { 
01366       return bufferSize_;
01367     }
01368   
01369   inline TrackerSpecialHeader FEDBufferBase::trackerSpecialHeader() const
01370     { 
01371       return specialHeader_;
01372     }
01373   
01374   inline FEDDAQEventType FEDBufferBase::daqEventType() const
01375     {
01376       return daqHeader_.eventType();
01377     }
01378   
01379   inline uint32_t FEDBufferBase::daqLvl1ID() const
01380     {
01381       return daqHeader_.l1ID();
01382     }
01383   
01384   inline uint16_t FEDBufferBase::daqBXID() const
01385     {
01386       return daqHeader_.bxID();
01387     }
01388   
01389   inline uint16_t FEDBufferBase::daqSourceID() const
01390     {
01391       return daqHeader_.sourceID();
01392     }
01393   
01394   inline uint32_t FEDBufferBase::daqEventLengthIn64bitWords() const
01395     {
01396       return daqTrailer_.eventLengthIn64BitWords();
01397     }
01398   
01399   inline uint32_t FEDBufferBase::daqEventLengthInBytes() const
01400     {
01401       return daqTrailer_.eventLengthInBytes();
01402     }
01403   
01404   inline uint16_t FEDBufferBase::daqCRC() const
01405     {
01406       return daqTrailer_.crc();
01407     }
01408   
01409   inline FEDTTSBits FEDBufferBase::daqTTSState() const
01410     {
01411       return daqTrailer_.ttsBits();
01412     }
01413   
01414   inline FEDBufferFormat FEDBufferBase::bufferFormat() const
01415     {
01416       return specialHeader_.bufferFormat();
01417     }
01418   
01419   inline FEDHeaderType FEDBufferBase::headerType() const
01420     {
01421       return specialHeader_.headerType();
01422     }
01423   
01424   inline FEDReadoutMode FEDBufferBase::readoutMode() const
01425     {
01426       return specialHeader_.readoutMode();
01427     }
01428   
01429   inline FEDDataType FEDBufferBase::dataType() const
01430     {
01431       return specialHeader_.dataType();
01432     }
01433   
01434   inline uint8_t FEDBufferBase::apveAddress() const
01435     {
01436       return specialHeader_.apveAddress();
01437     }
01438   
01439   inline bool FEDBufferBase::majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
01440     {
01441       return (specialHeader_.majorityAddressErrorForFEUnit(internalFEUnitNum) && (specialHeader_.apveAddress() != 0x00));
01442     }
01443   
01444   inline bool FEDBufferBase::feEnabled(const uint8_t internalFEUnitNum) const
01445     {
01446       return specialHeader_.feEnabled(internalFEUnitNum);
01447     }
01448   
01449   inline bool FEDBufferBase::feOverflow(const uint8_t internalFEUnitNum) const
01450     {
01451       return specialHeader_.feOverflow(internalFEUnitNum);
01452     }
01453   
01454   inline FEDStatusRegister FEDBufferBase::fedStatusRegister() const
01455     {
01456       return specialHeader_.fedStatusRegister();
01457     }
01458   
01459   inline bool FEDBufferBase::channelGood(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
01460     {
01461       return channelGood(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
01462     }
01463   
01464   inline const FEDChannel& FEDBufferBase::channel(const uint8_t internalFEDChannelNum) const
01465     {
01466       return channels_[internalFEDChannelNum];
01467     }
01468   
01469   inline const FEDChannel& FEDBufferBase::channel(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
01470     {
01471       return channel(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
01472     }
01473   
01474   inline bool FEDBufferBase::doTrackerSpecialHeaderChecks() const
01475     {
01476       return ( checkBufferFormat() &&
01477                checkHeaderType() &&
01478                checkReadoutMode() &&
01479                //checkAPVEAddressValid() &&
01480                checkNoFEOverflows() ); 
01481     }
01482   
01483   inline bool FEDBufferBase::doDAQHeaderAndTrailerChecks() const
01484     {
01485       return ( checkNoSLinkTransmissionError() &&
01486                checkSourceIDs() &&
01487                checkNoUnexpectedSourceID() &&
01488                checkNoExtraHeadersOrTrailers() &&
01489                checkLengthFromTrailer() );
01490     }
01491   
01492   inline bool FEDBufferBase::checkCRC() const
01493     {
01494       return ( checkNoSlinkCRCError() && (calcCRC()==daqCRC()) );
01495     }
01496   
01497   inline bool FEDBufferBase::checkBufferFormat() const
01498     {
01499       return (bufferFormat() != BUFFER_FORMAT_INVALID);
01500     }
01501   
01502   inline bool FEDBufferBase::checkHeaderType() const
01503     {
01504       return (headerType() != HEADER_TYPE_INVALID);
01505     }
01506   
01507   inline bool FEDBufferBase::checkReadoutMode() const
01508     {
01509       return (readoutMode() != READOUT_MODE_INVALID);
01510     }
01511   
01512   inline bool FEDBufferBase::checkAPVEAddressValid() const
01513     {
01514       return (apveAddress() <= APV_MAX_ADDRESS);
01515     }
01516   
01517   inline bool FEDBufferBase::checkNoFEOverflows() const
01518     {
01519       return !specialHeader_.feOverflowRegister();
01520     }
01521   
01522   inline bool FEDBufferBase::checkNoSlinkCRCError() const
01523     {
01524       return !daqTrailer_.slinkCRCError();
01525     }
01526   
01527   inline bool FEDBufferBase::checkNoSLinkTransmissionError() const
01528     {
01529       return !daqTrailer_.slinkTransmissionError();
01530     }
01531   
01532   inline bool FEDBufferBase::checkNoUnexpectedSourceID() const
01533     {
01534       return !daqTrailer_.badSourceID();
01535     }
01536   
01537   inline bool FEDBufferBase::checkNoExtraHeadersOrTrailers() const
01538     {
01539       return ( (daqHeader_.boeNibble() == 0x5) && (daqTrailer_.eoeNibble() == 0xA) );
01540     }
01541   
01542   inline bool FEDBufferBase::checkLengthFromTrailer() const
01543     {
01544       return (bufferSize() == daqEventLengthInBytes());
01545     }
01546   
01547   inline const uint8_t* FEDBufferBase::getPointerToDataAfterTrackerSpecialHeader() const
01548     {
01549       return orderedBuffer_+16;
01550     }
01551   
01552   inline const uint8_t* FEDBufferBase::getPointerToByteAfterEndOfPayload() const
01553     {
01554       return orderedBuffer_+bufferSize_-8;
01555     }
01556 
01557   //FEDChannel
01558 
01559   inline FEDChannel::FEDChannel(const uint8_t*const data, const size_t offset)
01560     : data_(data),
01561       offset_(offset)
01562     {
01563       length_ = ( data_[(offset_)^7] + (data_[(offset_+1)^7] << 8) );
01564     }
01565   
01566   inline FEDChannel::FEDChannel(const uint8_t*const data, const size_t offset, const uint16_t length)
01567     : data_(data),
01568       offset_(offset),
01569       length_(length)
01570     {
01571     }
01572   
01573   inline uint16_t FEDChannel::length() const
01574     {
01575       return length_;
01576     }
01577   
01578   inline uint8_t FEDChannel::packetCode() const
01579     {
01580       return data_[(offset_+2)^7];
01581     }
01582   
01583   inline const uint8_t* FEDChannel::data() const
01584     {
01585       return data_;
01586     }
01587   
01588   inline size_t FEDChannel::offset() const
01589     {
01590       return offset_;
01591     }
01592 
01593 }
01594 
01595 #endif //ndef EventFilter_SiStripRawToDigi_FEDBufferComponents_H