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