CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SiStripFEDBufferComponents.h
Go to the documentation of this file.
1 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBufferComponents_H
2 #define EventFilter_SiStripRawToDigi_SiStripFEDBufferComponents_H
3 
4 #include "boost/cstdint.hpp"
5 #include <ostream>
6 #include <memory>
7 #include <cstring>
10 
11 namespace sistrip {
12 
13  //
14  // Constants
15  //
16 
17  static const uint8_t INVALID=0xFF;
18 
19  static const uint8_t APV_MAX_ADDRESS=192;
20 
21  static const uint16_t SCOPE_MODE_MAX_SCOPE_LENGTH=1022;
22 
27  };
28  //these are the values which appear in the buffer.
29  static const uint8_t BUFFER_FORMAT_CODE_OLD = 0xED;
30  static const uint8_t BUFFER_FORMAT_CODE_NEW = 0xC5;
31 
32  //enum values are values which appear in buffer. DO NOT CHANGE!
36  HEADER_TYPE_NONE=4 //spy channel
37  };
38 
39  //enum values are values which appear in buffer. DO NOT CHANGE!
48  };
49 
50  static const uint8_t PACKET_CODE_SCOPE = 0xE5;
51  static const uint8_t PACKET_CODE_VIRGIN_RAW = 0xE6;
52  static const uint8_t PACKET_CODE_PROC_RAW = 0xF2;
53  static const uint8_t PACKET_CODE_ZERO_SUPPRESSED = 0xEA;
54 
55  //enum values are values which appear in buffer. DO NOT CHANGE!
58  };
59 
60  //enum values are values which appear in buffer. DO NOT CHANGE!
61  //see http://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
70  };
71 
72  //enum values are values which appear in buffer. DO NOT CHANGE!
73  //see http://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
77  TTS_BUSY=0x4,
78  TTS_READY=0x8,
79  TTS_ERROR=0x12,
82 
83  //enum values are values which appear in buffer. DO NOT CHANGE!
88  };
89 
90  //enum values are values which appear in buffer. DO NOT CHANGE!
103  };
104 
105  //
106  // Global function declarations
107  //
108 
109  //used by these classes
110  uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum);
111  void printHex(const void* pointer, const size_t length, std::ostream& os);
112  //calculate the CRC for a FED buffer
113  uint16_t calculateFEDBufferCRC(const uint8_t* buffer, const size_t lengthInBytes);
114  //to make enums printable
115  std::ostream& operator<<(std::ostream& os, const FEDBufferFormat& value);
116  std::ostream& operator<<(std::ostream& os, const FEDHeaderType& value);
117  std::ostream& operator<<(std::ostream& os, const FEDReadoutMode& value);
118  std::ostream& operator<<(std::ostream& os, const FEDDataType& value);
119  std::ostream& operator<<(std::ostream& os, const FEDDAQEventType& value);
120  std::ostream& operator<<(std::ostream& os, const FEDTTSBits& value);
121  std::ostream& operator<<(std::ostream& os, const FEDBufferState& value);
122  std::ostream& operator<<(std::ostream& os, const FEDChannelStatus& value);
123  //convert name of an element of enum to enum value (useful for getting values from config)
124  FEDBufferFormat fedBufferFormatFromString(const std::string& bufferFormatString);
125  FEDHeaderType fedHeaderTypeFromString(const std::string& headerTypeString);
126  FEDReadoutMode fedReadoutModeFromString(const std::string& readoutModeString);
127  FEDDataType fedDataTypeFromString(const std::string& dataTypeString);
128  FEDDAQEventType fedDAQEventTypeFromString(const std::string& daqEventTypeString);
129 
130  //
131  // Class definitions
132  //
133 
134  //handles conversion between order of data in buffer in VR/PR modes (readout order) and strip order (physical order)
136  {
137  public:
138  //convert strip/sample index in channel (ie 0-255) between physical and readout order
139  static uint8_t physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel);
140  static uint8_t readoutOrderForStripInChannel(const uint8_t physicalOrderStripIndexInChannel);
141  //convert strip/sample index in APV (ie 0-127) between physical and readout order
142  static uint8_t physicalOrderForStripInAPV(const uint8_t readoutOrderStripIndexInAPV);
143  static uint8_t readoutOrderForStripInAPV(const uint8_t physicalOrderStripIndexInAPV);
144  };
145 
146  //see http://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
148  {
149  public:
151  explicit FEDDAQHeader(const uint8_t* header);
152  //0x5 in first fragment
153  uint8_t boeNibble() const;
154  uint8_t eventTypeNibble() const;
155  FEDDAQEventType eventType() const;
156  uint32_t l1ID() const;
157  uint16_t bxID() const;
158  uint16_t sourceID() const;
159  uint8_t version() const;
160  //0 if current header word is last, 1 otherwise
161  bool hBit() const;
162  bool lastHeader() const;
163  void print(std::ostream& os) const;
164  //used by digi2Raw
165  const uint8_t* data() const;
166  FEDDAQHeader& setEventType(const FEDDAQEventType evtType);
167  FEDDAQHeader& setL1ID(const uint32_t l1ID);
168  FEDDAQHeader& setBXID(const uint16_t bxID);
169  FEDDAQHeader& setSourceID(const uint16_t sourceID);
170  FEDDAQHeader(const uint32_t l1ID, const uint16_t bxID, const uint16_t sourceID,
171  const FEDDAQEventType evtType = DAQ_EVENT_TYPE_PHYSICS);
172  private:
173  uint8_t header_[8];
174  };
175 
176  //see http://cmsdoc.cern.ch/cms/TRIDAS/horizontal/RUWG/DAQ_IF_guide/DAQ_IF_guide.html
178  {
179  public:
181  explicit FEDDAQTrailer(const uint8_t* trailer);
182  //0xA in first fragment
183  uint8_t eoeNibble() const;
184  uint32_t eventLengthIn64BitWords() const;
185  uint32_t eventLengthInBytes() const;
186  uint16_t crc() const;
187  //set to 1 if FRL detects a transmission error over S-link
188  bool cBit() const;
189  bool slinkTransmissionError() const { return cBit(); }
190  //set to 1 if the FED ID is not the one expected by the FRL
191  bool fBit() const;
192  bool badSourceID() const { return fBit(); }
193  uint8_t eventStatusNibble() const;
194  uint8_t ttsNibble() const;
195  FEDTTSBits ttsBits() const;
196  //0 if the current trailer is the last, 1 otherwise
197  bool tBit() const;
198  bool lastTrailer() const { return !tBit(); }
199  //set to 1 if the S-link sender card detects a CRC error (the CRC it computes is put in the CRC field)
200  bool rBit() const;
201  bool slinkCRCError() const { return rBit(); }
202  void print(std::ostream& os) const;
203  //used by digi2Raw
204  const uint8_t* data() const;
206  FEDDAQTrailer& setCRC(const uint16_t crc);
207  FEDDAQTrailer& setSLinkTransmissionErrorBit(const bool bitSet);
208  FEDDAQTrailer& setBadSourceIDBit(const bool bitSet);
209  FEDDAQTrailer& setSLinkCRCErrorBit(const bool bitSet);
212  FEDDAQTrailer(const uint32_t eventLengthIn64BitWords, const uint16_t crc = 0, const FEDTTSBits ttsBits = TTS_READY,
213  const bool slinkTransmissionError = false, const bool badFEDID = false, const bool slinkCRCError = false,
214  const uint8_t eventStatusNibble = 0);
215  private:
216  uint8_t trailer_[8];
217  };
218 
220  {
221  public:
222  FEDStatusRegister(const uint16_t fedStatusRegister);
223  bool slinkFullFlag() const;
225  bool qdrMemoryFullFlag() const;
226  bool qdrMemoryPartialFullFlag() const;
227  bool qdrMemoryEmptyFlag() const;
228  bool l1aBxFIFOFullFlag() const;
229  bool l1aBxFIFOPartialFullFlag() const;
230  bool l1aBxFIFOEmptyFlag() const;
233  bool feDataMissingFlag(const uint8_t internalFEUnitNum) const;
234  void print(std::ostream& os) const;
235  void printFlags(std::ostream& os) const;
236  operator uint16_t () const;
237  //used by digi2Raw
238  FEDStatusRegister& setSLinkFullFlag(const bool bitSet);
242  FEDStatusRegister(const FEDBufferState qdrMemoryBufferState = BUFFER_STATE_UNSET,
243  const FEDBufferState l1aBxFIFOBufferState = BUFFER_STATE_UNSET,
244  const bool trackerHeaderMonitorDataReadyFlagSet = false,
245  const bool slinkFullFlagSet = false);
246  private:
247  bool getBit(const uint8_t num) const;
248  void setBit(const uint8_t num, const bool bitSet);
249  void setQDRMemoryFullFlag(const bool bitSet);
250  void setQDRMemoryPartialFullFlag(const bool bitSet);
251  void setQDRMemoryEmptyFlag(const bool bitSet);
252  void setL1ABXFIFOFullFlag(const bool bitSet);
253  void setL1ABXFIFOPartialFullFlag(const bool bitSet);
254  void setL1ABXFIFOEmptyFlag(const bool bitSet);
255  uint16_t data_;
256  };
257 
259  {
260  public:
262  //construct with a pointer to the data. The data will be coppied and swapped if necessary.
263  explicit TrackerSpecialHeader(const uint8_t* headerPointer);
264  uint8_t bufferFormatByte() const;
266  uint8_t headerTypeNibble() const;
267  FEDHeaderType headerType() const;
268  uint8_t trackerEventTypeNibble() const;
269  FEDReadoutMode readoutMode() const;
270  FEDDataType dataType() const;
271  uint8_t apveAddress() const;
272  uint8_t apvAddressErrorRegister() const;
273  bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const;
274  uint8_t feEnableRegister() const;
275  bool feEnabled(const uint8_t internalFEUnitNum) const;
276  uint8_t feOverflowRegister() const;
277  bool feOverflow(const uint8_t internalFEUnitNum) const;
278  uint16_t fedStatusRegisterWord() const;
280  void print(std::ostream& os) const;
281  //used by digi2Raw
282  //returns ordered buffer (ie this may need to be swapped to get original order)
283  const uint8_t* data() const;
284  bool wasSwapped() const;
285  TrackerSpecialHeader& setBufferFormat(const FEDBufferFormat newBufferFormat);
289  TrackerSpecialHeader& setAPVEAddress(const uint8_t address);
290  TrackerSpecialHeader& setAPVEAddressErrorRegister(const uint8_t addressErrorRegister);
291  TrackerSpecialHeader& setAPVAddressErrorForFEUnit(const uint8_t internalFEUnitNum, const bool error);
292  TrackerSpecialHeader& setFEEnableRegister(const uint8_t feEnableRegister);
293  TrackerSpecialHeader& setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled);
294  TrackerSpecialHeader& setFEOverflowRegister(const uint8_t feOverflowRegister);
295  TrackerSpecialHeader& setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow);
297  TrackerSpecialHeader(const FEDBufferFormat bufferFormat, const FEDReadoutMode readoutMode,
298  const FEDHeaderType headerType, const FEDDataType dataType,
299  const uint8_t address = 0x00, const uint8_t addressErrorRegister = 0x00,
300  const uint8_t feEnableRegister = 0xFF, const uint8_t feOverflowRegister = 0x00,
301  const FEDStatusRegister fedStatusRegister = FEDStatusRegister());
302  private:
303  void setBufferFormatByte(const FEDBufferFormat newBufferFormat);
304  void setHeaderTypeNibble(const uint8_t value);
305  void setReadoutModeBits(const uint8_t value);
306  void setDataTypeBit(const bool value);
308  //copy of header, 32 bit word swapped if needed
309  uint8_t specialHeader_[8];
310  //was the header word swapped wrt order in buffer?
312  };
313 
315  {
316  public:
317  FEDBackendStatusRegister(const uint32_t backendStatusRegister);
318  bool internalFreezeFlag() const;
319  bool slinkDownFlag() const;
320  bool slinkFullFlag() const;
321  bool backpressureFlag() const;
322  bool ttcReadyFlag() const;
331  void print(std::ostream& os) const;
332  void printFlags(std::ostream& os) const;
333  operator uint32_t () const;
334  //used by digi2Raw
336  FEDBackendStatusRegister& setSLinkDownFlag(const bool bitSet);
337  FEDBackendStatusRegister& setSLinkFullFlag(const bool bitSet);
338  FEDBackendStatusRegister& setBackpressureFlag(const bool bitSet);
339  FEDBackendStatusRegister& setTTCReadyFlag(const bool bitSet);
348  FEDBackendStatusRegister(const FEDBufferState qdrMemoryBufferState = BUFFER_STATE_UNSET,
349  const FEDBufferState frameAddressFIFOBufferState = BUFFER_STATE_UNSET,
350  const FEDBufferState totalLengthFIFOBufferState = BUFFER_STATE_UNSET,
351  const FEDBufferState trackerHeaderFIFOBufferState = BUFFER_STATE_UNSET,
352  const FEDBufferState l1aBxFIFOBufferState = BUFFER_STATE_UNSET,
353  const FEDBufferState feEventLengthFIFOBufferState = BUFFER_STATE_UNSET,
354  const FEDBufferState feFPGABufferState = BUFFER_STATE_UNSET,
355  const bool backpressure = false, const bool slinkFull = false,
356  const bool slinkDown = false, const bool internalFreeze = false,
357  const bool trackerHeaderMonitorDataReady = false, const bool ttcReady = true);
358  private:
359  bool getBit(const uint8_t num) const;
360  void setBit(const uint8_t num, const bool bitSet);
361  //get the state of the buffer in position 'bufferPosition'
362  FEDBufferState getBufferState(const uint8_t bufferPosition) const;
363  //set the state of the buffer in position 'bufferPosition' to state 'state'
364  void setBufferSate(const uint8_t bufferPosition, const FEDBufferState state);
365  void printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream& os) const;
366  //constants marking order of flags in buffer
367  //eg. bit offset for L1A/BX FIFO Partial full flag is STATE_OFFSET_PARTIAL_FULL+BUFFER_POSITION_L1ABX_FIFO
368  // bit offset for total length FIFO empty flag is STATE_OFFSET_EMPTY+BUFFER_POSITION_TOTAL_LENGTH_FIFO
369  //see BE FPGA technical description
380  uint32_t data_;
381  };
382 
384  {
385  public:
386  //factory function: allocates new FEDFEHeader derrivative of appropriate type
387  static std::auto_ptr<FEDFEHeader> newFEHeader(const FEDHeaderType headerType, const uint8_t* headerBuffer);
388  //used by digi2Raw
389  static std::auto_ptr<FEDFEHeader> newFEHeader(const FEDHeaderType headerType);
390  //create a buffer to use with digi2Raw
391  static std::auto_ptr<FEDFEHeader> newFEFakeHeader(const FEDHeaderType headerType);
392  virtual ~FEDFEHeader();
393  //the length of the header
394  virtual size_t lengthInBytes() const = 0;
395  //check that there are no errors indicated in which ever error bits are available in the header
396  //check bits for both APVs on a channel
397  bool checkChannelStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
398  virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const = 0;
399  //check bits for one APV
400  bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
401  virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const = 0;
402  virtual void print(std::ostream& os) const = 0;
403  virtual FEDFEHeader* clone() const = 0;
404  //used by digi2Raw
405  virtual const uint8_t* data() const = 0;
406  virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) = 0;
407  virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) = 0;
408  virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) = 0;
409  virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) = 0;
410  void setChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const FEDChannelStatus status);
411  };
412 
413  class FEDAPVErrorHeader final : public FEDFEHeader
414  {
415  public:
416  explicit FEDAPVErrorHeader(const uint8_t* headerBuffer);
417  virtual ~FEDAPVErrorHeader();
418  virtual size_t lengthInBytes() const;
419  virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const;
420  virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
421  virtual void print(std::ostream& os) const;
422  virtual FEDAPVErrorHeader* clone() const;
423  //used by digi2Raw
424  virtual const uint8_t* data() const;
425  FEDAPVErrorHeader& setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood);
426  FEDAPVErrorHeader& setAPVStatusBit(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum, const bool apvGood);
427  FEDAPVErrorHeader(const std::vector<bool>& apvsGood = std::vector<bool>(APVS_PER_FED,true));
428  //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
429  //if the values need to be set.
430  virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status);
431  virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address);
432  virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister);
433  virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length);
434  private:
435  static const size_t APV_ERROR_HEADER_SIZE_IN_64BIT_WORDS = 3;
438  };
439 
440  class FEDFullDebugHeader final : public FEDFEHeader
441  {
442  public:
443  explicit FEDFullDebugHeader(const uint8_t* headerBuffer);
444  virtual ~FEDFullDebugHeader();
445  virtual size_t lengthInBytes() const;
446  virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const;
447  virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
448  virtual void print(std::ostream& os) const;
449  virtual FEDFullDebugHeader* clone() const;
450 
451  uint8_t feUnitMajorityAddress(const uint8_t internalFEUnitNum) const;
453  uint32_t daqRegister() const;
454  uint32_t daqRegister2() const;
455  uint16_t feUnitLength(const uint8_t internalFEUnitNum) const;
456  bool fePresent(const uint8_t internalFEUnitNum) const;
457 
458  FEDChannelStatus getChannelStatus(const uint8_t internalFEDChannelNum) const;
459  FEDChannelStatus getChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
460 
461  //These methods return true if there was an error of the appropriate type (ie if the error bit is 0).
462  //They return false if the error could not occur due to a more general error.
463  //was channel unlocked
464  bool unlocked(const uint8_t internalFEDChannelNum) const;
465  bool unlocked(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
466  //was channel out of sync if it was unlocked
467  bool outOfSync(const uint8_t internalFEDChannelNum) const;
468  bool outOfSync(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const;
469  //was there an internal APV error if it was in sync
470  bool apvError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
471  bool apvError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
472  //was the APV address wrong if it was in sync (does not depend on APV internal error bit)
473  bool apvAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
474  bool apvAddressError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const;
475 
476  //used by digi2Raw
477  virtual const uint8_t* data() const;
478  virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status);
479  virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address);
480  virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister);
481  virtual void setDAQRegister(const uint32_t daqRegister);
482  virtual void setDAQRegister2(const uint32_t daqRegister2);
483  virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length);
484  FEDFullDebugHeader(const std::vector<uint16_t>& feUnitLengths = std::vector<uint16_t>(FEUNITS_PER_FED,0),
485  const std::vector<uint8_t>& feMajorityAddresses = std::vector<uint8_t>(FEUNITS_PER_FED,0),
486  const std::vector<FEDChannelStatus>& channelStatus = std::vector<FEDChannelStatus>(FEDCH_PER_FED,CHANNEL_STATUS_NO_PROBLEMS),
487  const FEDBackendStatusRegister beStatusRegister = FEDBackendStatusRegister(),
488  const uint32_t daqRegister = 0, const uint32_t daqRegister2 = 0);
489  private:
490  bool getBit(const uint8_t internalFEDChannelNum, const uint8_t bit) const;
491  static uint32_t get32BitWordFrom(const uint8_t* startOfWord);
492  static void set32BitWordAt(uint8_t* startOfWord, const uint32_t value);
493  const uint8_t* feWord(const uint8_t internalFEUnitNum) const;
494  uint8_t* feWord(const uint8_t internalFEUnitNum);
495  void setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value);
496 
497  //These methods return true if there was an error of the appropriate type (ie if the error bit is 0).
498  //They ignore any previous errors which make the status bits meaningless and return the value of the bit anyway.
499  //In general, the methods above which only return an error for the likely cause are more useful.
500  bool unlockedFromBit(const uint8_t internalFEDChannelNum) const;
501  bool outOfSyncFromBit(const uint8_t internalFEDChannelNum) const;
502  bool apvErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
503  bool apvAddressErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const;
504 
505  //following methods set the bits to 1 (no error) if value is false
506  void setUnlocked(const uint8_t internalFEDChannelNum, const bool value);
507  void setOutOfSync(const uint8_t internalFEDChannelNum, const bool value);
508  void setAPVAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value);
509  void setAPVError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value);
513  };
514 
515  //holds information about position of a channel in the buffer for use by unpacker
517  {
518  public:
519  FEDChannel(const uint8_t*const data, const size_t offset, const uint16_t length);
520  //gets length from first 2 bytes (assuming normal FED channel)
521  FEDChannel(const uint8_t*const data, const size_t offset);
522  uint16_t length() const;
523  const uint8_t* data() const;
524  size_t offset() const;
525  uint16_t cmMedian(const uint8_t apvIndex) const;
526  private:
527  friend class FEDBuffer;
528  //third byte of channel data for normal FED channels
529  uint8_t packetCode() const;
530  const uint8_t* data_;
531  size_t offset_;
532  uint16_t length_;
533  };
534 
535  //base class for sistrip FED buffers which have a DAQ header/trailer and tracker special header
537  {
538  public:
539  FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat = false);
540  virtual ~FEDBufferBase();
541  //dump buffer to stream
542  void dump(std::ostream& os) const;
543  //dump original buffer before word swapping
544  void dumpOriginalBuffer(std::ostream& os) const;
545  virtual void print(std::ostream& os) const;
546  //calculate the CRC from the buffer
547  uint16_t calcCRC() const;
548 
549  //methods to get parts of the buffer
550  FEDDAQHeader daqHeader() const;
551  FEDDAQTrailer daqTrailer() const;
552  size_t bufferSize() const;
554  //methods to get info from DAQ header
556  uint32_t daqLvl1ID() const;
557  uint16_t daqBXID() const;
558  uint16_t daqSourceID() const;
559  uint16_t sourceID() const;
560  //methods to get info from DAQ trailer
561  uint32_t daqEventLengthIn64bitWords() const;
562  uint32_t daqEventLengthInBytes() const;
563  uint16_t daqCRC() const;
564  FEDTTSBits daqTTSState() const;
565  //methods to get info from the tracker special header
567  FEDHeaderType headerType() const;
568  FEDReadoutMode readoutMode() const;
569  FEDDataType dataType() const;
570  uint8_t apveAddress() const;
571  bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const;
572  bool feEnabled(const uint8_t internalFEUnitNum) const;
573  uint8_t nFEUnitsEnabled() const;
574  bool feOverflow(const uint8_t internalFEUnitNum) const;
576 
577  //check that channel has no errors
578  virtual bool channelGood(const uint8_t internalFEDChannelNum) const;
579  bool channelGood(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
580  //return channel object for channel
581  const FEDChannel& channel(const uint8_t internalFEDChannelNum) const;
582  const FEDChannel& channel(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
583 
584  //summary checks
585  //check that tracker special header is valid (does not check for FE unit errors indicated in special header)
586  bool doTrackerSpecialHeaderChecks() const;
587  //check for errors in DAQ heaqder and trailer (not including bad CRC)
588  bool doDAQHeaderAndTrailerChecks() const;
589  //do both
590  virtual bool doChecks() const;
591  //print the result of all detailed checks
592  virtual std::string checkSummary() const;
593 
594  //detailed checks
595  bool checkCRC() const;
596  bool checkMajorityAddresses() const;
597  //methods to check tracker special header
598  bool checkBufferFormat() const;
599  bool checkHeaderType() const;
600  bool checkReadoutMode() const;
601  bool checkAPVEAddressValid() const;
602  bool checkNoFEOverflows() const;
603  //methods to check daq header and trailer
604  bool checkNoSlinkCRCError() const;
605  bool checkNoSLinkTransmissionError() const;
606  bool checkSourceIDs() const;
607  bool checkNoUnexpectedSourceID() const;
608  bool checkNoExtraHeadersOrTrailers() const;
609  bool checkLengthFromTrailer() const;
610  protected:
611  const uint8_t* getPointerToDataAfterTrackerSpecialHeader() const;
612  const uint8_t* getPointerToByteAfterEndOfPayload() const;
613  FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat, const bool fillChannelVector);
614  std::vector<FEDChannel> channels_;
615  private:
616  void init(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat);
617  const uint8_t* originalBuffer_;
618  const uint8_t* orderedBuffer_;
619  const size_t bufferSize_;
623  };
624 
625  //
626  // Inline function definitions
627  //
628 
629  inline std::ostream& operator << (std::ostream& os, const FEDBufferBase& obj) { obj.print(os); os << obj.checkSummary(); return os; }
630 
631  inline uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
632  {
633  return (internalFEUnitNum*FEDCH_PER_FEUNIT + internalFEUnitChannelNum);
634  }
635 
636  inline std::ostream& operator << (std::ostream& os, const FEDDAQHeader& obj) { obj.print(os); return os; }
637  inline std::ostream& operator << (std::ostream& os, const FEDDAQTrailer& obj) { obj.print(os); return os; }
638  inline std::ostream& operator << (std::ostream& os, const TrackerSpecialHeader& obj) { obj.print(os); return os; }
639  inline std::ostream& operator << (std::ostream& os, const FEDStatusRegister& obj) { obj.print(os); return os; }
640  inline std::ostream& operator << (std::ostream& os, const FEDFEHeader& obj) { obj.print(os); return os; }
641 
642  //FEDStripOrdering
643 
644  inline uint8_t FEDStripOrdering::physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel)
645  {
646  return physicalOrderForStripInAPV(readoutOrderStripIndexInChannel/2) + (readoutOrderStripIndexInChannel%2)*STRIPS_PER_APV;
647  }
648 
649  inline uint8_t FEDStripOrdering::readoutOrderForStripInChannel(const uint8_t physicalOrderStripIndexInChannel)
650  {
651  return ( readoutOrderForStripInAPV(physicalOrderStripIndexInChannel%128)*2 + (physicalOrderStripIndexInChannel/128) );
652  }
653 
654  inline uint8_t FEDStripOrdering::physicalOrderForStripInAPV(const uint8_t readout_order)
655  {
656  return ( (32 * (readout_order%4)) +
657  (8 * static_cast<uint16_t>(static_cast<float>(readout_order)/4.0)) -
658  (31 * static_cast<uint16_t>(static_cast<float>(readout_order)/16.0))
659  );
660  }
661 
662  inline uint8_t FEDStripOrdering::readoutOrderForStripInAPV(const uint8_t physical_order)
663  {
664  return ( 4*((static_cast<uint16_t>((static_cast<float>(physical_order)/8.0)))%4) +
665  static_cast<uint16_t>(static_cast<float>(physical_order)/32.0) +
666  16*(physical_order%8)
667  );
668  }
669 
670  //TrackerSpecialHeader
671 
673  : wordSwapped_(false)
674  {
675  }
676 
678  { return specialHeader_[BUFFERFORMAT]; }
679 
681  { return ( (specialHeader_[BUFFERTYPE] & 0xF0) >> 4 ); }
682 
684  { return (specialHeader_[BUFFERTYPE] & 0x0F); }
685 
686  inline uint8_t TrackerSpecialHeader::apveAddress() const
687  { return specialHeader_[APVEADDRESS]; }
688 
690  { return specialHeader_[ADDRESSERROR]; }
691 
692  inline bool TrackerSpecialHeader::majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
693  {
694  return ( !(readoutMode() == READOUT_MODE_SCOPE) && !( (0x1<<internalFEUnitNum) & apvAddressErrorRegister() ) );
695  }
696 
698  { return specialHeader_[FEENABLE]; }
699 
700  inline bool TrackerSpecialHeader::feEnabled(const uint8_t internalFEUnitNum) const
701  {
702  return ( (0x1<<internalFEUnitNum) & feEnableRegister() );
703  }
704 
706  { return specialHeader_[FEOVERFLOW]; }
707 
708  inline bool TrackerSpecialHeader::feOverflow(const uint8_t internalFEUnitNum) const
709  {
710  return ( (0x1<<internalFEUnitNum) & feOverflowRegister() );
711  }
712 
714  {
715  //get 16 bits
716  uint16_t statusRegister = ( (specialHeader_[(FEDSTATUS+1)]<<8) | specialHeader_[FEDSTATUS]);
717  return statusRegister;
718  }
719 
722 
723  inline void TrackerSpecialHeader::print(std::ostream& os) const
724  { printHex(specialHeader_,8,os); }
725 
726  inline const uint8_t* TrackerSpecialHeader::data() const
727  {
728  return specialHeader_;
729  }
730 
732  {
733  return wordSwapped_;
734  }
735 
737  {
738  specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & 0x0F) | ((value<<4) & 0xF0) );
739  }
740 
742  {
743  specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & (~0x0E)) | (value & 0x0E) );
744  }
745 
747  {
748  specialHeader_[BUFFERTYPE] = ( (specialHeader_[BUFFERTYPE] & (~0x01)) | (value ? 0x01 : 0x00) );
749  }
750 
752  {
753  specialHeader_[APVEADDRESS] = address;
754  return *this;
755  }
756 
758  {
759  specialHeader_[ADDRESSERROR] = addressErrorRegister;
760  return *this;
761  }
762 
763  inline TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableRegister(const uint8_t feEnableRegister)
764  {
766  return *this;
767  }
768 
769  inline TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowRegister(const uint8_t feOverflowRegister)
770  {
772  return *this;
773  }
774 
776  {
777  specialHeader_[FEDSTATUS] = (static_cast<uint16_t>(fedStatusRegister) & 0x00FF);
778  specialHeader_[FEDSTATUS+1] = ( (static_cast<uint16_t>(fedStatusRegister) & 0xFF00) >> 8);
779  return *this;
780  }
781 
782  //FEDStatusRegister
783 
784  inline FEDStatusRegister::FEDStatusRegister(const uint16_t fedStatusRegister)
785  : data_(fedStatusRegister) { }
786 
787  inline FEDStatusRegister::operator uint16_t () const
788  { return data_; }
789 
790  inline bool FEDStatusRegister::getBit(const uint8_t num) const
791  { return ( (0x1<<num) & (data_) ); }
792 
794  { return getBit(0); }
795 
797  { return getBit(1); }
798 
800  { return getBit(2); }
801 
803  { return getBit(3); }
804 
806  { return getBit(4); }
807 
809  { return getBit(5); }
810 
812  { return getBit(6); }
813 
815  { return getBit(7); }
816 
817  inline bool FEDStatusRegister::feDataMissingFlag(const uint8_t internalFEUnitNum) const
818  {
819  return getBit(8+internalFEUnitNum);
820  }
821 
822  inline void FEDStatusRegister::print(std::ostream& os) const
823  { printHex(&data_,2,os); }
824 
826  { setBit(0,bitSet); return *this; }
827 
829  { setBit(1,bitSet); return *this; }
830 
831  inline void FEDStatusRegister::setQDRMemoryFullFlag(const bool bitSet)
832  { setBit(2,bitSet); }
833 
834  inline void FEDStatusRegister::setQDRMemoryPartialFullFlag(const bool bitSet)
835  { setBit(3,bitSet); }
836 
837  inline void FEDStatusRegister::setQDRMemoryEmptyFlag(const bool bitSet)
838  { setBit(4,bitSet); }
839 
840  inline void FEDStatusRegister::setL1ABXFIFOFullFlag(const bool bitSet)
841  { setBit(5,bitSet); }
842 
843  inline void FEDStatusRegister::setL1ABXFIFOPartialFullFlag(const bool bitSet)
844  { setBit(6,bitSet); }
845 
846  inline void FEDStatusRegister::setL1ABXFIFOEmptyFlag(const bool bitSet)
847  { setBit(7,bitSet); }
848 
849  inline FEDStatusRegister::FEDStatusRegister(const FEDBufferState qdrMemoryBufferState, const FEDBufferState l1aBxFIFOBufferState,
850  const bool trackerHeaderMonitorDataReadyFlagSet, const bool slinkFullFlagSet)
851  : data_(0x0000)
852  {
853  setSLinkFullFlag(slinkFullFlagSet);
854  setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReadyFlagSet);
855  setQDRMemoryBufferState(qdrMemoryBufferState);
856  setL1ABXFIFOBufferState(l1aBxFIFOBufferState);
857  }
858 
859  //FEDBackendStatusRegister
860 
861  inline FEDBackendStatusRegister::FEDBackendStatusRegister(const uint32_t backendStatusRegister)
862  : data_(backendStatusRegister) { }
863 
864  inline FEDBackendStatusRegister::operator uint32_t () const
865  { return data_; }
866 
867  inline void FEDBackendStatusRegister::print(std::ostream& os) const
868  { printHex(&data_,4,os); }
869 
870  inline bool FEDBackendStatusRegister::getBit(const uint8_t num) const
871  { return ( (0x1<<num) & (data_) ); }
872 
874  { return getBit(1); }
875 
877  { return getBit(2); }
878 
880  { return getBit(3); }
881 
883  { return getBit(4); }
884 
886  { return getBit(6); }
887 
889  { return getBit(7); }
890 
892  { setBit(1,bitSet); return *this; }
893 
895  { setBit(2,bitSet); return *this; }
896 
898  { setBit(3,bitSet); return *this; }
899 
901  { setBit(4,bitSet); return *this; }
902 
904  { setBit(6,bitSet); return *this; }
905 
907  { setBit(7,bitSet); return *this; }
908 
910  {
912  }
913 
915  {
917  }
918 
920  {
922  }
923 
925  {
927  }
928 
930  {
932  }
933 
935  {
937  }
938 
940  {
942  }
943 
945  {
947  return *this;
948  }
949 
951  {
953  return *this;
954  }
955 
957  {
959  return *this;
960  }
961 
963  {
965  return *this;
966  }
967 
969  {
971  return *this;
972  }
973 
975  {
977  return *this;
978  }
979 
981  {
983  return *this;
984  }
985 
986  //FEDFEHeader
987 
988  inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEHeader(const FEDHeaderType headerType, const uint8_t* headerBuffer)
989  {
990  switch (headerType) {
992  return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader(headerBuffer));
994  return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader(headerBuffer));
995  default:
996  return std::auto_ptr<FEDFEHeader>();
997  }
998  }
999 
1000  inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEHeader(const FEDHeaderType headerType)
1001  {
1002  switch (headerType) {
1004  return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader());
1005  case HEADER_TYPE_APV_ERROR:
1006  return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader());
1007  default:
1008  return std::auto_ptr<FEDFEHeader>();
1009  }
1010  }
1011 
1012  inline std::auto_ptr<FEDFEHeader> FEDFEHeader::newFEFakeHeader(const FEDHeaderType headerType)
1013  {
1014  switch (headerType) {
1016  return std::auto_ptr<FEDFEHeader>(new FEDFullDebugHeader);
1017  case HEADER_TYPE_APV_ERROR:
1018  return std::auto_ptr<FEDFEHeader>(new FEDAPVErrorHeader);
1019  default:
1020  return std::auto_ptr<FEDFEHeader>();
1021  }
1022  }
1023 
1024  inline bool FEDFEHeader::checkChannelStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
1025  {
1026  return checkChannelStatusBits(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
1027  }
1028 
1029  inline bool FEDFEHeader::checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
1030  {
1031  return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
1032  }
1033 
1034  inline void FEDFEHeader::setChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const FEDChannelStatus status)
1035  {
1036  this->setChannelStatus(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),status);
1037  }
1038 
1039  inline FEDAPVErrorHeader::FEDAPVErrorHeader(const uint8_t* headerBuffer)
1040  {
1041  memcpy(header_,headerBuffer,APV_ERROR_HEADER_SIZE_IN_BYTES);
1042  }
1043 
1044  inline FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum,
1045  const uint8_t apvNum, const bool apvGood)
1046  {
1047  return setAPVStatusBit(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum,apvGood);
1048  }
1049 
1050  inline FEDFullDebugHeader::FEDFullDebugHeader(const uint8_t* headerBuffer)
1051  {
1052  memcpy(header_,headerBuffer,FULL_DEBUG_HEADER_SIZE_IN_BYTES);
1053  }
1054 
1055  inline uint8_t FEDFullDebugHeader::feUnitMajorityAddress(const uint8_t internalFEUnitNum) const
1056  {
1057  return feWord(internalFEUnitNum)[9];
1058  }
1059 
1061  {
1063  }
1064 
1065  inline uint32_t FEDFullDebugHeader::daqRegister() const
1066  {
1067  return get32BitWordFrom(feWord(7)+10);
1068  }
1069 
1070  inline uint32_t FEDFullDebugHeader::daqRegister2() const
1071  {
1072  return get32BitWordFrom(feWord(6)+10);
1073  }
1074 
1075  inline uint16_t FEDFullDebugHeader::feUnitLength(const uint8_t internalFEUnitNum) const
1076  {
1077  return ( (feWord(internalFEUnitNum)[15]<<8) | (feWord(internalFEUnitNum)[14]) );
1078  }
1079 
1080  inline bool FEDFullDebugHeader::fePresent(const uint8_t internalFEUnitNum) const
1081  {
1082  return (feUnitLength(internalFEUnitNum) != 0);
1083  }
1084 
1085  inline bool FEDFullDebugHeader::unlocked(const uint8_t internalFEDChannelNum) const
1086  {
1087  return unlockedFromBit(internalFEDChannelNum);
1088  }
1089 
1090  inline bool FEDFullDebugHeader::unlocked(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
1091  {
1092  return unlocked(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
1093  }
1094 
1095  inline bool FEDFullDebugHeader::outOfSync(const uint8_t internalFEDChannelNum) const
1096  {
1097  return ( !unlocked(internalFEDChannelNum) && outOfSyncFromBit(internalFEDChannelNum) );
1098  }
1099 
1100  inline bool FEDFullDebugHeader::outOfSync(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
1101  {
1102  return outOfSync(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
1103  }
1104 
1105  inline bool FEDFullDebugHeader::apvError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1106  {
1107  return ( !unlockedFromBit(internalFEDChannelNum) &&
1108  !outOfSyncFromBit(internalFEDChannelNum) &&
1109  apvErrorFromBit(internalFEDChannelNum,apvNum) );
1110  }
1111 
1112  inline bool FEDFullDebugHeader::apvError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
1113  {
1114  return apvError(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
1115  }
1116 
1117  inline bool FEDFullDebugHeader::apvAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1118  {
1119  return ( !unlockedFromBit(internalFEDChannelNum) &&
1120  !outOfSyncFromBit(internalFEDChannelNum) &&
1121  apvAddressErrorFromBit(internalFEDChannelNum,apvNum) );
1122  }
1123 
1124  inline bool FEDFullDebugHeader::apvAddressError(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
1125  {
1126  return apvAddressError(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum),apvNum);
1127  }
1128 
1129  inline FEDChannelStatus FEDFullDebugHeader::getChannelStatus(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
1130  {
1131  return getChannelStatus(internalFEDChannelNum(internalFEUnitNum,internalFEUnitChannelNum));
1132  }
1133 
1135  {
1136  return !getBit(internalFEDChannelNum,5);
1137  }
1138 
1140  {
1141  return !getBit(internalFEDChannelNum,4);
1142  }
1143 
1144  inline bool FEDFullDebugHeader::apvErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1145  {
1146  //Discovered March 2012: two bits inverted in firmware. Decided
1147  //to update documentation but keep firmware identical for
1148  //backward compatibility. So status bit order is actually:
1149  //apvErr1 - apvAddrErr0 - apvErr0 - apvAddrErr1 - OOS - unlocked.
1150  //Before, it was: return !getBit(internalFEDChannelNum,0+2*apvNum);
1151 
1152  return !getBit(internalFEDChannelNum,0+2*(1-apvNum));
1153  }
1154 
1155  inline bool FEDFullDebugHeader::apvAddressErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1156  {
1157  return !getBit(internalFEDChannelNum,1+2*apvNum);
1158  }
1159 
1160  inline bool FEDFullDebugHeader::getBit(const uint8_t internalFEDChannelNum, const uint8_t bit) const
1161  {
1162  const uint8_t* pFEWord = feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT);
1163  const uint8_t bitInFeWord = ((FEDCH_PER_FEUNIT-1) - (internalFEDChannelNum%FEDCH_PER_FEUNIT)) * 6 + bit;
1164  return ( pFEWord[bitInFeWord/8] & (0x1 << (bitInFeWord%8)) );
1165  }
1166 
1167  inline uint32_t FEDFullDebugHeader::get32BitWordFrom(const uint8_t* startOfWord)
1168  {
1169  return ( startOfWord[0] | (startOfWord[1]<<8) | (startOfWord[2]<<16) | (startOfWord[3]<<24) );
1170  }
1171 
1172  inline void FEDFullDebugHeader::set32BitWordAt(uint8_t* startOfWord, const uint32_t value)
1173  {
1174  memcpy(startOfWord,&value,4);
1175  }
1176 
1177  inline const uint8_t* FEDFullDebugHeader::feWord(const uint8_t internalFEUnitNum) const
1178  {
1179  return header_+internalFEUnitNum*2*8;
1180  }
1181 
1182  //re-use const method
1183  inline uint8_t* FEDFullDebugHeader::feWord(const uint8_t internalFEUnitNum)
1184  {
1185  return const_cast<uint8_t*>(static_cast<const FEDFullDebugHeader*>(this)->feWord(internalFEUnitNum));
1186  }
1187 
1188  inline void FEDFullDebugHeader::setUnlocked(const uint8_t internalFEDChannelNum, const bool value)
1189  {
1190  setBit(internalFEDChannelNum,5,!value);
1191  }
1192 
1193  inline void FEDFullDebugHeader::setOutOfSync(const uint8_t internalFEDChannelNum, const bool value)
1194  {
1195  setBit(internalFEDChannelNum,4,!value);
1196  }
1197 
1198  inline void FEDFullDebugHeader::setAPVAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
1199  {
1200  setBit(internalFEDChannelNum,1+2*apvNum,!value);
1201  }
1202 
1203  inline void FEDFullDebugHeader::setAPVError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
1204  {
1205  //Discovered March 2012: two bits inverted in firmware. Decided
1206  //to update documentation but keep firmware identical for
1207  //backward compatibility. So status bit order is actually:
1208  //apvErr1 - apvAddrErr0 - apvErr0 - apvAddrErr1 - OOS - unlocked.
1209  //Before, it was: return !getBit(internalFEDChannelNum,0+2*apvNum);
1210 
1211  setBit(internalFEDChannelNum,0+2*(1-apvNum),!value);
1212  }
1213 
1214  //FEDDAQHeader
1215 
1216  inline FEDDAQHeader::FEDDAQHeader(const uint8_t* header)
1217  {
1218  memcpy(header_,header,8);
1219  }
1220 
1221  inline uint8_t FEDDAQHeader::boeNibble() const
1222  {
1223  return ( (header_[7] & 0xF0) >> 4 );
1224  }
1225 
1226  inline uint8_t FEDDAQHeader::eventTypeNibble() const
1227  {
1228  return (header_[7] & 0x0F);
1229  }
1230 
1231  inline uint32_t FEDDAQHeader::l1ID() const
1232  {
1233  return ( header_[4] | (header_[5]<<8) | (header_[6]<<16) );
1234  }
1235 
1236  inline uint16_t FEDDAQHeader::bxID() const
1237  {
1238  return ( (header_[3]<<4) | ((header_[2]&0xF0)>>4) );
1239  }
1240 
1241  inline uint16_t FEDDAQHeader::sourceID() const
1242  {
1243  return ( ((header_[2]&0x0F)<<8) | header_[1] );
1244  }
1245 
1246  inline uint8_t FEDDAQHeader::version() const
1247  {
1248  return ( (header_[0] & 0xF0) >> 4 );
1249  }
1250 
1251  inline bool FEDDAQHeader::hBit() const
1252  {
1253  return (header_[0] & 0x8);
1254  }
1255 
1256  inline bool FEDDAQHeader::lastHeader() const
1257  {
1258  return !hBit();
1259  }
1260 
1261  inline const uint8_t* FEDDAQHeader::data() const
1262  {
1263  return header_;
1264  }
1265 
1266  inline void FEDDAQHeader::print(std::ostream& os) const
1267  {
1268  printHex(header_,8,os);
1269  }
1270 
1271  //FEDDAQTrailer
1272 
1273  inline FEDDAQTrailer::FEDDAQTrailer(const uint8_t* trailer)
1274  {
1275  memcpy(trailer_,trailer,8);
1276  }
1277 
1278  inline uint8_t FEDDAQTrailer::eoeNibble() const
1279  {
1280  return ( (trailer_[7] & 0xF0) >> 4 );
1281  }
1282 
1284  {
1285  return ( trailer_[4] | (trailer_[5]<<8) | (trailer_[6]<<16) );
1286  }
1287 
1288  inline uint32_t FEDDAQTrailer::eventLengthInBytes() const
1289  {
1290  return eventLengthIn64BitWords()*8;
1291  }
1292 
1293  inline uint16_t FEDDAQTrailer::crc() const
1294  {
1295  return ( trailer_[2] | (trailer_[3]<<8) );
1296  }
1297 
1298  inline bool FEDDAQTrailer::cBit() const
1299  {
1300  return (trailer_[1] & 0x80);
1301  }
1302 
1303  inline bool FEDDAQTrailer::fBit() const
1304  {
1305  return (trailer_[1] & 0x40);
1306  }
1307 
1308  inline uint8_t FEDDAQTrailer::eventStatusNibble() const
1309  {
1310  return (trailer_[1] & 0x0F);
1311  }
1312 
1313  inline uint8_t FEDDAQTrailer::ttsNibble() const
1314  {
1315  return ( (trailer_[0] & 0xF0) >> 4);
1316  }
1317 
1318  inline bool FEDDAQTrailer::tBit() const
1319  {
1320  return (trailer_[0] & 0x08);
1321  }
1322 
1323  inline bool FEDDAQTrailer::rBit() const
1324  {
1325  return (trailer_[0] & 0x04);
1326  }
1327 
1328  inline void FEDDAQTrailer::print(std::ostream& os) const
1329  {
1330  printHex(trailer_,8,os);
1331  }
1332 
1333  inline const uint8_t* FEDDAQTrailer::data() const
1334  {
1335  return trailer_;
1336  }
1337 
1338  //FEDBufferBase
1339 
1340  inline void FEDBufferBase::dump(std::ostream& os) const
1341  {
1343  }
1344 
1345  inline void FEDBufferBase::dumpOriginalBuffer(std::ostream& os) const
1346  {
1348  }
1349 
1350  inline uint16_t FEDBufferBase::calcCRC() const
1351  {
1353  }
1354 
1356  {
1357  return daqHeader_;
1358  }
1359 
1361  {
1362  return daqTrailer_;
1363  }
1364 
1365  inline size_t FEDBufferBase::bufferSize() const
1366  {
1367  return bufferSize_;
1368  }
1369 
1371  {
1372  return specialHeader_;
1373  }
1374 
1376  {
1377  return daqHeader_.eventType();
1378  }
1379 
1380  inline uint32_t FEDBufferBase::daqLvl1ID() const
1381  {
1382  return daqHeader_.l1ID();
1383  }
1384 
1385  inline uint16_t FEDBufferBase::daqBXID() const
1386  {
1387  return daqHeader_.bxID();
1388  }
1389 
1390  inline uint16_t FEDBufferBase::daqSourceID() const
1391  {
1392  return daqHeader_.sourceID();
1393  }
1394 
1396  {
1398  }
1399 
1401  {
1403  }
1404 
1405  inline uint16_t FEDBufferBase::daqCRC() const
1406  {
1407  return daqTrailer_.crc();
1408  }
1409 
1411  {
1412  return daqTrailer_.ttsBits();
1413  }
1414 
1416  {
1417  return specialHeader_.bufferFormat();
1418  }
1419 
1421  {
1422  return specialHeader_.headerType();
1423  }
1424 
1426  {
1427  return specialHeader_.readoutMode();
1428  }
1429 
1431  {
1432  return specialHeader_.dataType();
1433  }
1434 
1435  inline uint8_t FEDBufferBase::apveAddress() const
1436  {
1437  return specialHeader_.apveAddress();
1438  }
1439 
1440  inline bool FEDBufferBase::majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
1441  {
1442  return (specialHeader_.majorityAddressErrorForFEUnit(internalFEUnitNum) && (specialHeader_.apveAddress() != 0x00));
1443  }
1444 
1445  inline bool FEDBufferBase::feEnabled(const uint8_t internalFEUnitNum) const
1446  {
1447  return specialHeader_.feEnabled(internalFEUnitNum);
1448  }
1449 
1450  inline bool FEDBufferBase::feOverflow(const uint8_t internalFEUnitNum) const
1451  {
1452  return specialHeader_.feOverflow(internalFEUnitNum);
1453  }
1454 
1456  {
1458  }
1459 
1460  inline bool FEDBufferBase::channelGood(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
1461  {
1462  return channelGood(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
1463  }
1464 
1465  inline const FEDChannel& FEDBufferBase::channel(const uint8_t internalFEDChannelNum) const
1466  {
1468  }
1469 
1470  inline const FEDChannel& FEDBufferBase::channel(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
1471  {
1472  return channel(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
1473  }
1474 
1476  {
1477  return ( checkBufferFormat() &&
1478  checkHeaderType() &&
1479  checkReadoutMode() &&
1480  //checkAPVEAddressValid() &&
1481  checkNoFEOverflows() );
1482  }
1483 
1485  {
1486  return ( checkNoSLinkTransmissionError() &&
1487  checkSourceIDs() &&
1491  }
1492 
1493  inline bool FEDBufferBase::checkCRC() const
1494  {
1495  return ( checkNoSlinkCRCError() && (calcCRC()==daqCRC()) );
1496  }
1497 
1499  {
1500  return (bufferFormat() != BUFFER_FORMAT_INVALID);
1501  }
1502 
1504  {
1505  return (headerType() != HEADER_TYPE_INVALID);
1506  }
1507 
1509  {
1510  return (readoutMode() != READOUT_MODE_INVALID);
1511  }
1512 
1514  {
1515  return (apveAddress() <= APV_MAX_ADDRESS);
1516  }
1517 
1519  {
1521  }
1522 
1524  {
1525  return !daqTrailer_.slinkCRCError();
1526  }
1527 
1529  {
1531  }
1532 
1534  {
1535  return !daqTrailer_.badSourceID();
1536  }
1537 
1539  {
1540  return ( (daqHeader_.boeNibble() == 0x5) && (daqTrailer_.eoeNibble() == 0xA) );
1541  }
1542 
1544  {
1545  return (bufferSize() == daqEventLengthInBytes());
1546  }
1547 
1549  {
1550  return orderedBuffer_+16;
1551  }
1552 
1554  {
1555  return orderedBuffer_+bufferSize_-8;
1556  }
1557 
1558  //FEDChannel
1559 
1560  inline FEDChannel::FEDChannel(const uint8_t*const data, const size_t offset)
1561  : data_(data),
1562  offset_(offset)
1563  {
1564  length_ = ( data_[(offset_)^7] + (data_[(offset_+1)^7] << 8) );
1565  }
1566 
1567  inline FEDChannel::FEDChannel(const uint8_t*const data, const size_t offset, const uint16_t length)
1568  : data_(data),
1569  offset_(offset),
1570  length_(length)
1571  {
1572  }
1573 
1574  inline uint16_t FEDChannel::length() const
1575  {
1576  return length_;
1577  }
1578 
1579  inline uint8_t FEDChannel::packetCode() const
1580  {
1581  return data_[(offset_+2)^7];
1582  }
1583 
1584  inline const uint8_t* FEDChannel::data() const
1585  {
1586  return data_;
1587  }
1588 
1589  inline size_t FEDChannel::offset() const
1590  {
1591  return offset_;
1592  }
1593 
1594 }
1595 
1596 #endif //ndef EventFilter_SiStripRawToDigi_FEDBufferComponents_H
static uint8_t physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel)
FEDBackendStatusRegister & setFEFPGABufferState(const FEDBufferState state)
FEDBackendStatusRegister & setQDRMemoryState(const FEDBufferState state)
FEDBackendStatusRegister & setL1ABXFIFOState(const FEDBufferState state)
bool getBit(const uint8_t internalFEDChannelNum, const uint8_t bit) const
uint16_t sourceID() const
virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister)=0
bool feDataMissingFlag(const uint8_t internalFEUnitNum) const
virtual size_t lengthInBytes() const =0
virtual void setDAQRegister(const uint32_t daqRegister)
virtual void print(std::ostream &os) const
TrackerSpecialHeader & setDataType(const FEDDataType dataType)
static const size_t APV_ERROR_HEADER_SIZE_IN_BYTES
void printFlags(std::ostream &os) const
void setBit(const uint8_t num, const bool bitSet)
bool fePresent(const uint8_t internalFEUnitNum) const
void setOutOfSync(const uint8_t internalFEDChannelNum, const bool value)
virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
bool getBit(const uint8_t num) const
void setQDRMemoryEmptyFlag(const bool bitSet)
uint32_t daqEventLengthIn64bitWords() const
bool feEnabled(const uint8_t internalFEUnitNum) const
virtual std::string checkSummary() const
FEDStatusRegister & setTrackerHeaderMonitorDataReadyFlag(const bool bitSet)
FEDBackendStatusRegister & setFrameAddressFIFOState(const FEDBufferState state)
TrackerSpecialHeader & setFEOverflowRegister(const uint8_t feOverflowRegister)
bool unlockedFromBit(const uint8_t internalFEDChannelNum) const
virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
const uint8_t * getPointerToByteAfterEndOfPayload() const
FEDDAQTrailer daqTrailer() const
static const uint8_t PACKET_CODE_SCOPE
bool unlocked(const uint8_t internalFEDChannelNum) const
FEDBackendStatusRegister & setTrackerHeaderFIFOState(const FEDBufferState state)
FEDFullDebugHeader(const uint8_t *headerBuffer)
virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const
void print(std::ostream &os) const
FEDDAQTrailer & setSLinkCRCErrorBit(const bool bitSet)
FEDDAQTrailer & setTTSBits(const FEDTTSBits ttsBits)
const uint8_t * feWord(const uint8_t internalFEUnitNum) const
virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister)
FEDBackendStatusRegister beStatusRegister() const
FEDReadoutMode readoutMode() const
FEDDataType fedDataTypeFromString(const std::string &dataTypeString)
bool getBit(const uint8_t num) const
FEDStatusRegister(const uint16_t fedStatusRegister)
static uint32_t get32BitWordFrom(const uint8_t *startOfWord)
void setAPVError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
FEDStatusRegister & setSLinkFullFlag(const bool bitSet)
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
FEDStatusRegister fedStatusRegister() const
void print(std::ostream &os) const
TrackerSpecialHeader & setAPVEAddress(const uint8_t address)
const uint8_t * getPointerToDataAfterTrackerSpecialHeader() const
FEDDAQTrailer & setSLinkTransmissionErrorBit(const bool bitSet)
FEDHeaderType fedHeaderTypeFromString(const std::string &headerTypeString)
void printFlags(std::ostream &os) const
TrackerSpecialHeader & setBufferFormat(const FEDBufferFormat newBufferFormat)
uint16_t calculateFEDBufferCRC(const uint8_t *buffer, const size_t lengthInBytes)
FEDChannel(const uint8_t *const data, const size_t offset, const uint16_t length)
std::ostream & operator<<(std::ostream &os, const FEDBufferFormat &value)
virtual bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
bool apvError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
FEDAPVErrorHeader(const uint8_t *headerBuffer)
const uint8_t * data() const
FEDBufferFormat fedBufferFormatFromString(const std::string &bufferFormatString)
void setBit(const uint8_t num, const bool bitSet)
FEDDAQEventType daqEventType() const
TrackerSpecialHeader & setHeaderType(const FEDHeaderType headerType)
static std::auto_ptr< FEDFEHeader > newFEFakeHeader(const FEDHeaderType headerType)
void dumpOriginalBuffer(std::ostream &os) const
FEDReadoutMode fedReadoutModeFromString(const std::string &readoutModeString)
bool feOverflow(const uint8_t internalFEUnitNum) const
static uint8_t readoutOrderForStripInChannel(const uint8_t physicalOrderStripIndexInChannel)
FEDBackendStatusRegister(const uint32_t backendStatusRegister)
uint16_t cmMedian(const uint8_t apvIndex) const
virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
virtual void print(std::ostream &os) const
bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum, const uint8_t apvNum) const
const uint8_t * data() const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
virtual FEDFullDebugHeader * clone() const
virtual void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister)
FEDBackendStatusRegister & setTotalLengthFIFOState(const FEDBufferState state)
TrackerSpecialHeader & setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
FEDDAQTrailer & setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
FEDDAQTrailer & setEventStatusNibble(const uint8_t eventStatusNibble)
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
void setUnlocked(const uint8_t internalFEDChannelNum, const bool value)
FEDBackendStatusRegister & setTTCReadyFlag(const bool bitSet)
FEDDAQTrailer & setCRC(const uint16_t crc)
TrackerSpecialHeader & setAPVEAddressErrorRegister(const uint8_t addressErrorRegister)
TrackerSpecialHeader & setFEDStatusRegister(const FEDStatusRegister fedStatusRegister)
bool apvErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
TrackerSpecialHeader & setAPVAddressErrorForFEUnit(const uint8_t internalFEUnitNum, const bool error)
FEDStatusRegister & setL1ABXFIFOBufferState(const FEDBufferState state)
FEDAPVErrorHeader & setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood)
static const uint16_t FEUNITS_PER_FED
FEDBufferState qdrMemoryState() const
void setQDRMemoryFullFlag(const bool bitSet)
bool feEnabled(const uint8_t internalFEUnitNum) const
virtual void setDAQRegister2(const uint32_t daqRegister2)
virtual void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)=0
virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status)=0
void dump(std::ostream &os) const
void setL1ABXFIFOFullFlag(const bool bitSet)
static const uint8_t BUFFER_FORMAT_CODE_NEW
FEDBufferBase(const uint8_t *fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat=false)
FEDHeaderType headerType() const
virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)=0
void setAPVAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool value)
void printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream &os) const
static const size_t APV_ERROR_HEADER_SIZE_IN_64BIT_WORDS
static const uint8_t APV_MAX_ADDRESS
virtual void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
void setL1ABXFIFOPartialFullFlag(const bool bitSet)
FEDBufferState l1aBxFIFOState() const
void setHeaderTypeNibble(const uint8_t value)
unsigned int offset(bool)
static const uint8_t INVALID
const FEDChannel & channel(const uint8_t internalFEDChannelNum) const
FEDDAQEventType fedDAQEventTypeFromString(const std::string &daqEventTypeString)
bool outOfSync(const uint8_t internalFEDChannelNum) const
std::vector< FEDChannel > channels_
void setBufferFormatByte(const FEDBufferFormat newBufferFormat)
FEDBufferState getBufferState(const uint8_t bufferPosition) const
bool checkChannelStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum) const
FEDDAQTrailer & setBadSourceIDBit(const bool bitSet)
void print(std::ostream &os) const
static const size_t FULL_DEBUG_HEADER_SIZE_IN_BYTES
static const uint8_t PACKET_CODE_PROC_RAW
static const uint16_t APVS_PER_FED
virtual void print(std::ostream &os) const =0
void printHex(const void *pointer, const size_t length, std::ostream &os)
static uint8_t physicalOrderForStripInAPV(const uint8_t readoutOrderStripIndexInAPV)
static const uint16_t FEDCH_PER_FEUNIT
Constants and enumerated types for FED/FEC systems.
FEDBackendStatusRegister & setTrackerHeaderMonitorDataReadyFlag(const bool bitSet)
void setReadoutModeBits(const uint8_t value)
bool apvAddressError(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status)
FEDDAQHeader & setEventType(const FEDDAQEventType evtType)
const uint8_t * data() const
TrackerSpecialHeader trackerSpecialHeader() const
FEDDAQHeader & setL1ID(const uint32_t l1ID)
FEDBackendStatusRegister & setSLinkFullFlag(const bool bitSet)
void print(std::ostream &os) const
FEDDAQHeader & setSourceID(const uint16_t sourceID)
uint16_t feUnitLength(const uint8_t internalFEUnitNum) const
void setBufferSate(const uint8_t bufferPosition, const FEDBufferState state)
virtual void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status)
void init(const uint8_t *fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
virtual const uint8_t * data() const =0
uint8_t header_[FULL_DEBUG_HEADER_SIZE_IN_BYTES]
uint8_t feUnitMajorityAddress(const uint8_t internalFEUnitNum) const
TrackerSpecialHeader specialHeader_
virtual const uint8_t * data() const
FEDChannelStatus getChannelStatus(const uint8_t internalFEDChannelNum) const
virtual void print(std::ostream &os) const
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
static const uint16_t FEDCH_PER_FED
static const uint16_t STRIPS_PER_APV
TrackerSpecialHeader & setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow)
virtual bool channelGood(const uint8_t internalFEDChannelNum) const
static const size_t FULL_DEBUG_HEADER_SIZE_IN_64BIT_WORDS
virtual FEDFEHeader * clone() const =0
FEDBackendStatusRegister & setFEEventLengthFIFOState(const FEDBufferState state)
virtual const uint8_t * data() const
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
static std::auto_ptr< FEDFEHeader > newFEHeader(const FEDHeaderType headerType, const uint8_t *headerBuffer)
FEDDAQHeader & setBXID(const uint16_t bxID)
bool apvAddressErrorFromBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
static const uint8_t BUFFER_FORMAT_CODE_OLD
volatile std::atomic< bool > shutdown_flag false
void setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value)
static const uint16_t SCOPE_MODE_MAX_SCOPE_LENGTH
tuple status
Definition: ntuplemaker.py:245
static uint8_t readoutOrderForStripInAPV(const uint8_t physicalOrderStripIndexInAPV)
FEDStatusRegister & setQDRMemoryBufferState(const FEDBufferState state)
virtual FEDAPVErrorHeader * clone() const
FEDDAQEventType eventType() const
static void set32BitWordAt(uint8_t *startOfWord, const uint32_t value)
uint8_t header_[APV_ERROR_HEADER_SIZE_IN_BYTES]
FEDBackendStatusRegister & setInternalFreezeFlag(const bool bitSet)
void setL1ABXFIFOEmptyFlag(const bool bitSet)
virtual bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const
FEDBackendStatusRegister & setBackpressureFlag(const bool bitSet)
static const uint8_t PACKET_CODE_VIRGIN_RAW
TrackerSpecialHeader & setReadoutMode(const FEDReadoutMode readoutMode)
bool outOfSyncFromBit(const uint8_t internalFEDChannelNum) const
bool feOverflow(const uint8_t internalFEUnitNum) const
FEDStatusRegister fedStatusRegister() const
void setQDRMemoryPartialFullFlag(const bool bitSet)
FEDBackendStatusRegister & setSLinkDownFlag(const bool bitSet)
FEDBufferFormat bufferFormat() const
TrackerSpecialHeader & setFEEnableRegister(const uint8_t feEnableRegister)