00001 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
00002 #define EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
00003
00004 #include "boost/cstdint.hpp"
00005 #include <string>
00006 #include <vector>
00007 #include <memory>
00008 #include <ostream>
00009 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
00010 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
00011
00012 namespace sistrip {
00013
00014
00015
00016
00017
00018 class FEDBufferBase
00019 {
00020 public:
00021 FEDBufferBase(const uint8_t* fedBuffer, size_t fedBufferSize, bool allowUnrecognizedFormat = false);
00022 virtual ~FEDBufferBase();
00023
00024 void dump(std::ostream& os) const { printHex(orderedBuffer_,bufferSize_,os); }
00025
00026 void dumpOriginalBuffer(std::ostream& os) const { printHex(originalBuffer_,bufferSize_,os); }
00027 virtual void print(std::ostream& os) const;
00028
00029 uint16_t calcCRC() const;
00030
00031
00032 FEDDAQHeader daqHeader() const { return daqHeader_; }
00033 FEDDAQTrailer daqTrailer() const { return daqTrailer_; }
00034 size_t bufferSize() const { return bufferSize_; }
00035 TrackerSpecialHeader trackerSpecialHeader() const { return specialHeader_; }
00036
00037 FEDDAQEventType daqEventType() const { return daqHeader_.eventType(); }
00038 uint32_t daqLvl1ID() const { return daqHeader_.l1ID(); }
00039 uint16_t daqBXID() const { return daqHeader_.bxID(); }
00040 uint16_t daqSourceID() const { return daqHeader_.sourceID(); }
00041 uint16_t sourceID() const { return daqSourceID(); }
00042
00043 uint32_t daqEventLengthIn64bitWords() const { return daqTrailer_.eventLengthIn64BitWords(); }
00044 uint32_t daqEventLengthInBytes() const { return daqTrailer_.eventLengthInBytes(); }
00045 uint16_t daqCRC() const { return daqTrailer_.crc(); }
00046 FEDTTSBits daqTTSState() const { return daqTrailer_.ttsBits(); }
00047
00048 FEDBufferFormat bufferFormat() const { return specialHeader_.bufferFormat(); }
00049 FEDHeaderType headerType() const { return specialHeader_.headerType(); }
00050 FEDReadoutMode readoutMode() const { return specialHeader_.readoutMode(); }
00051 FEDDataType dataType() const { return specialHeader_.dataType(); }
00052 uint8_t apveAddress() const { return specialHeader_.apveAddress(); }
00053 bool majorityAddressErrorForFEUnit(uint8_t internalFEUnitNum) const { return specialHeader_.majorityAddressErrorForFEUnit(internalFEUnitNum); }
00054 bool feEnabled(uint8_t internalFEUnitNum) const { return specialHeader_.feEnabled(internalFEUnitNum); }
00055 uint8_t nFEUnitsEnabled() const;
00056 bool feOverflow(uint8_t internalFEUnitNum) const { return specialHeader_.feOverflow(internalFEUnitNum); }
00057 FEDStatusRegister fedStatusRegister() const { return specialHeader_.fedStatusRegister(); }
00058
00059
00060
00061 bool doTrackerSpecialHeaderChecks() const;
00062
00063 bool doDAQHeaderAndTrailerChecks() const;
00064
00065 virtual bool doChecks() const;
00066
00067 virtual std::string checkSummary() const;
00068
00069
00070 bool checkCRC() const { return ( checkNoSlinkCRCError() && (calcCRC()==daqCRC()) ); }
00071 bool checkMajorityAddresses() const;
00072
00073 bool checkBufferFormat() const { return (bufferFormat() != BUFFER_FORMAT_INVALID); }
00074 bool checkHeaderType() const { return (headerType() != HEADER_TYPE_INVALID); }
00075 bool checkReadoutMode() const { return (readoutMode() != READOUT_MODE_INVALID); }
00076 bool checkAPVEAddressValid() const { return (apveAddress() <= APV_MAX_ADDRESS); }
00077 bool checkNoFEOverflows() const { return !specialHeader_.feOverflowRegister(); }
00078
00079 bool checkNoSlinkCRCError() const { return !daqTrailer_.slinkCRCError(); }
00080 bool checkNoSLinkTransmissionError() const { return !daqTrailer_.slinkTransmissionError(); }
00081 bool checkSourceIDs() const;
00082 bool checkNoUnexpectedSourceID() const { return !daqTrailer_.badFEDID(); }
00083 bool checkNoExtraHeadersOrTrailers() const { return ( (daqHeader_.boeNibble() == 0x5) && (daqTrailer_.eoeNibble() == 0xA) ); }
00084 bool checkLengthFromTrailer() const { return (bufferSize() == daqEventLengthInBytes()); }
00085 protected:
00086 const uint8_t* getPointerToDataAfterTrackerSpecialHeader() const
00087 { return orderedBuffer_+16; }
00088 uint8_t* getPointerToDataAfterTrackerSpecialHeader();
00089 const uint8_t* getPointerToByteAfterEndOfPayload() const
00090 { return orderedBuffer_+bufferSize_-8; }
00091 uint8_t* getPointerToByteAfterEndOfPayload();
00092 private:
00093 const uint8_t* originalBuffer_;
00094 const uint8_t* orderedBuffer_;
00095 const size_t bufferSize_;
00096 FEDDAQHeader daqHeader_;
00097 FEDDAQTrailer daqTrailer_;
00098 TrackerSpecialHeader specialHeader_;
00099 };
00100
00101 class FEDZSChannelUnpacker;
00102 class FEDRawChannelUnpacker;
00103
00104 class FEDChannel
00105 {
00106 public:
00107 FEDChannel(const uint8_t* data, size_t offset);
00108 uint16_t length() const { return length_; }
00109 uint8_t packetCode() const { return data_[(offset_+2)^7]; }
00110 private:
00111 friend class FEDBuffer;
00112 friend class FEDZSChannelUnpacker;
00113 friend class FEDRawChannelUnpacker;
00114 const uint8_t* data() const { return data_; }
00115 size_t offset() const { return offset_; }
00116 const uint8_t* data_;
00117 uint16_t length_;
00118 size_t offset_;
00119 };
00120
00121 class FEDBuffer : public FEDBufferBase
00122 {
00123 public:
00124
00125
00126 FEDBuffer(const uint8_t* fedBuffer, size_t fedBufferSize, bool allowBadBuffer = false);
00127 virtual ~FEDBuffer();
00128 virtual void print(std::ostream& os) const;
00129 const FEDFEHeader* feHeader() const { return feHeader_.get(); }
00130
00131 bool feGood(uint8_t internalFEUnitNum) const { return ( !majorityAddressErrorForFEUnit(internalFEUnitNum) && !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) ); }
00132
00133 bool channelGood(uint8_t internalFEDChannelNum) const;
00134 bool channelGood(uint8_t internalFEUnitNum, uint8_t internalChannelNum) const
00135 { return channelGood(internalFEDChannelNum(internalFEUnitNum,internalChannelNum)); }
00136
00137 const FEDChannel& channel(uint8_t internalFEDChannelNum) const { return channels_[internalFEDChannelNum]; }
00138 const FEDChannel& channel(uint8_t internalFEUnitNum, uint8_t internalChannelNum) const
00139 { return channel(internalFEDChannelNum(internalFEUnitNum,internalChannelNum)); }
00140
00141
00142
00143 virtual bool doChecks() const;
00144
00145
00146
00147 bool checkChannelLengths() const;
00148
00149 bool checkChannelLengthsMatchBufferLength() const;
00150
00151 bool checkChannelPacketCodes() const;
00152
00153 bool checkFEUnitLengths() const;
00154
00155 bool checkFEUnitAPVAddresses() const;
00156
00157 virtual bool doCorruptBufferChecks() const;
00158
00159
00160
00161 bool checkStatusBits(uint8_t internalFEDChannelNum) const { return feHeader_->checkChannelStatusBits(internalFEDChannelNum); }
00162 bool checkStatusBits(uint8_t internalFEUnitNum, uint8_t internalChannelNum) const
00163 { return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalChannelNum)); }
00164
00165 bool checkAllChannelStatusBits() const;
00166
00167
00168 virtual std::string checkSummary() const;
00169 private:
00170 bool fePresent(uint8_t internalFEUnitNum) const { return fePresent_[internalFEUnitNum]; }
00171 uint8_t nFEUnitsPresent() const;
00172 void findChannels();
00173 uint8_t getCorrectPacketCode() const;
00174 uint16_t calculateFEUnitLength(uint8_t internalFEUnitNumber) const;
00175 std::vector<FEDChannel> channels_;
00176 std::auto_ptr<FEDFEHeader> feHeader_;
00177 uint8_t* payloadPointer_;
00178 uint16_t payloadLength_;
00179 uint8_t lastValidChannel_;
00180 bool fePresent_[FEUNITS_PER_FED];
00181 };
00182
00183 class FEDZSChannelUnpacker
00184 {
00185 public:
00186 static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel& channel);
00187 static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel& channel);
00188 FEDZSChannelUnpacker() : data_(NULL), valuesLeftInCluster_(0), valuesLeftAfterThisCluster_(0) { }
00189 uint8_t strip() const { return currentStrip_; }
00190 uint8_t adc() const { return data_[currentOffset_^7]; }
00191 bool hasData() const { return (valuesLeftAfterThisCluster_ || valuesLeftInCluster_); }
00192 FEDZSChannelUnpacker& operator ++ ();
00193 FEDZSChannelUnpacker& operator ++ (int) { ++(*this); return *this; }
00194 private:
00195
00196 FEDZSChannelUnpacker(const uint8_t* payload, size_t channelPayloadOffset,int16_t channelPayloadLength);
00197 void readNewClusterInfo();
00198 static void throwBadChannelLength(uint16_t length);
00199 void throwBadClusterLength();
00200 const uint8_t* data_;
00201 size_t currentOffset_;
00202 uint8_t currentStrip_;
00203 uint8_t valuesLeftInCluster_;
00204 int16_t valuesLeftAfterThisCluster_;
00205 };
00206
00207 class FEDRawChannelUnpacker
00208 {
00209 public:
00210 static FEDRawChannelUnpacker scopeModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00211 static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00212 static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00213 FEDRawChannelUnpacker(const FEDChannel& channel);
00214 uint8_t strip() const { return currentStrip_; }
00215 uint16_t adc() const { return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) ); }
00216 bool hasData() const { return valuesLeft_; }
00217 FEDRawChannelUnpacker& operator ++ ();
00218 FEDRawChannelUnpacker& operator ++ (int) { ++(*this); return *this; }
00219 private:
00220 static void throwBadChannelLength(uint16_t length);
00221 const uint8_t* data_;
00222 size_t currentOffset_;
00223 uint8_t currentStrip_;
00224 uint8_t valuesLeft_;
00225 };
00226
00227
00228
00229
00230
00231 inline std::ostream& operator << (std::ostream& os, const FEDBufferBase& obj) { obj.print(os); os << obj.checkSummary(); return os; }
00232
00233
00234
00235 inline bool FEDBuffer::channelGood(uint8_t internalFEDChannelNum) const
00236 {
00237 return ( (internalFEDChannelNum <= lastValidChannel_) &&
00238 feGood(internalFEDChannelNum/FEDCH_PER_FEUNIT) &&
00239 checkStatusBits(internalFEDChannelNum) );
00240 }
00241
00242
00243
00244 inline bool FEDBufferBase::doTrackerSpecialHeaderChecks() const
00245 {
00246 return ( checkBufferFormat() &&
00247 checkHeaderType() &&
00248 checkReadoutMode() &&
00249 checkAPVEAddressValid() &&
00250 checkNoFEOverflows() );
00251 }
00252
00253 inline bool FEDBufferBase::doDAQHeaderAndTrailerChecks() const
00254 {
00255 return ( checkNoSLinkTransmissionError() &&
00256 checkSourceIDs() &&
00257 checkNoUnexpectedSourceID() &&
00258 checkNoExtraHeadersOrTrailers() &&
00259 checkLengthFromTrailer() );
00260 }
00261
00262
00263 inline uint8_t* FEDBufferBase::getPointerToDataAfterTrackerSpecialHeader()
00264 {
00265 const FEDBufferBase* constThis = static_cast<const FEDBufferBase*>(this);
00266 const uint8_t* constPointer = constThis->getPointerToDataAfterTrackerSpecialHeader();
00267 return const_cast<uint8_t*>(constPointer);
00268 }
00269
00270 inline uint8_t* FEDBufferBase::getPointerToByteAfterEndOfPayload()
00271 {
00272 const FEDBufferBase* constThis = static_cast<const FEDBufferBase*>(this);
00273 const uint8_t* constPointer = constThis->getPointerToByteAfterEndOfPayload();
00274 return const_cast<uint8_t*>(constPointer);
00275 }
00276
00277
00278
00279 inline FEDChannel::FEDChannel(const uint8_t* data, size_t offset)
00280 : data_(data),
00281 offset_(offset)
00282 {
00283 length_ = ( data_[(offset_)^7] + (data_[(offset_+1)^7] << 8) );
00284 }
00285
00286
00287
00288 inline FEDRawChannelUnpacker::FEDRawChannelUnpacker(const FEDChannel& channel)
00289 : data_(channel.data()),
00290 currentOffset_(channel.offset()+3),
00291 currentStrip_(0),
00292 valuesLeft_((channel.length()-3)/2)
00293 {
00294 if ((channel.length()-3)%2) throwBadChannelLength(channel.length());
00295 }
00296
00297 inline FEDRawChannelUnpacker& FEDRawChannelUnpacker::operator ++ ()
00298 {
00299 currentOffset_ += 2;
00300 currentStrip_++;
00301 valuesLeft_--;
00302 return (*this);
00303 }
00304
00305
00306
00307 inline FEDZSChannelUnpacker::FEDZSChannelUnpacker(const uint8_t* payload, size_t channelPayloadOffset,int16_t channelPayloadLength)
00308 : data_(payload),
00309 currentOffset_(channelPayloadOffset),
00310 currentStrip_(0),
00311 valuesLeftInCluster_(0),
00312 valuesLeftAfterThisCluster_(channelPayloadLength)
00313 {
00314 readNewClusterInfo();
00315 }
00316
00317 inline void FEDZSChannelUnpacker::readNewClusterInfo()
00318 {
00319 if (valuesLeftAfterThisCluster_) {
00320 currentStrip_ = data_[(currentOffset_++)^7];
00321 valuesLeftInCluster_ = data_[(currentOffset_++)^7]-1;
00322 valuesLeftAfterThisCluster_ -= valuesLeftInCluster_+3;
00323 if (valuesLeftAfterThisCluster_ < 0) throwBadClusterLength();
00324 }
00325 }
00326
00327 inline FEDZSChannelUnpacker& FEDZSChannelUnpacker::operator ++ ()
00328 {
00329 if (valuesLeftInCluster_) {
00330 currentStrip_++;
00331 currentOffset_++;
00332 valuesLeftInCluster_--;
00333 } else {
00334 currentOffset_++;
00335 readNewClusterInfo();
00336 }
00337 return (*this);
00338 }
00339
00340 inline FEDZSChannelUnpacker FEDZSChannelUnpacker::zeroSuppressedModeUnpacker(const FEDChannel& channel)
00341 {
00342 uint16_t length = channel.length();
00343 if (length & 0xF000) throwBadChannelLength(length);
00344 FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7);
00345 return result;
00346 }
00347
00348 inline FEDZSChannelUnpacker FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(const FEDChannel& channel)
00349 {
00350 uint16_t length = channel.length();
00351 if (length & 0xF000) throwBadChannelLength(length);
00352 FEDZSChannelUnpacker result(channel.data(),channel.offset()+2,length-2);
00353 return result;
00354 }
00355
00356 }
00357
00358 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H