CMS 3D CMS Logo

SiStripFEDBufferComponents.cc
Go to the documentation of this file.
1 #include <iomanip>
2 #include <ostream>
3 #include <sstream>
4 #include <cstring>
7 
8 namespace sistrip {
9 
10  void printHexValue(const uint8_t value, std::ostream& os)
11  {
12  const std::ios_base::fmtflags originalFormatFlags = os.flags();
13  os << std::hex << std::setfill('0') << std::setw(2);
14  os << uint16_t(value);
15  os.flags(originalFormatFlags);
16  }
17 
18  void printHexWord(const uint8_t* pointer, const size_t lengthInBytes, std::ostream& os)
19  {
20  size_t i = lengthInBytes-1;
21  do{
22  printHexValue(pointer[i],os);
23  if (i != 0) os << " ";
24  } while (i-- != 0);
25  }
26 
27  void printHex(const void* pointer, const size_t lengthInBytes, std::ostream& os)
28  {
29  const uint8_t* bytePointer = reinterpret_cast<const uint8_t*>(pointer);
30  //if there is one 64 bit word or less, print it out
31  if (lengthInBytes <= 8) {
32  printHexWord(bytePointer,lengthInBytes,os);
33  }
34  //otherwise, print word numbers etc
35  else {
36  //header
37  os << "word\tbyte\t \t\tbyte" << std::endl;;
38  const size_t words = lengthInBytes/8;
39  const size_t extraBytes = lengthInBytes - 8*words;
40  //print full words
41  for (size_t w = 0; w < words; w++) {
42  const size_t startByte = w*8;
43  os << w << '\t' << startByte+8 << '\t';
44  printHexWord(bytePointer+startByte,8,os);
45  os << "\t\t" << startByte << std::endl;
46  }
47  //print part word, if any
48  if (extraBytes) {
49  const size_t startByte = words*8;
50  os << words << '\t' << startByte+8 << '\t';
51  //padding
52  size_t p = 8;
53  while (p-- > extraBytes) {
54  os << "00 ";
55  }
56  printHexWord(bytePointer+startByte,extraBytes,os);
57  os << "\t\t" << startByte << std::endl;
58  }
59  os << std::endl;
60  }
61  }
62 
63 
64  uint16_t calculateFEDBufferCRC(const uint8_t* buffer, const size_t lengthInBytes)
65  {
66  uint16_t crc = 0xFFFF;
67  for (size_t i = 0; i < lengthInBytes-8; i++) {
68  crc = evf::compute_crc_8bit(crc,buffer[i^7]);
69  }
70  for (size_t i=lengthInBytes-8; i<lengthInBytes; i++) {
71  uint8_t byte;
72  //set CRC bytes to zero since these were not set when CRC was calculated
73  if (i==lengthInBytes-4 || i==lengthInBytes-3)
74  byte = 0x00;
75  else
76  byte = buffer[i^7];
77  crc = evf::compute_crc_8bit(crc,byte);
78  }
79  return crc;
80  }
81 
82 
83  std::ostream& operator<<(std::ostream& os, const FEDBufferFormat& value)
84  {
85  switch (value) {
87  os << "Old VME";
88  break;
90  os << "Old S-Link";
91  break;
92  case BUFFER_FORMAT_NEW:
93  os << "New";
94  break;
96  os << "Invalid";
97  break;
98  default:
99  os << "Unrecognized";
100  os << " (";
101  printHexValue(value,os);
102  os << ")";
103  break;
104  }
105  return os;
106  }
107 
108  std::ostream& operator<<(std::ostream& os, const FEDHeaderType& value)
109  {
110  switch (value) {
112  os << "Full debug";
113  break;
115  os << "APV error";
116  break;
117  case HEADER_TYPE_NONE:
118  os << "None";
119  break;
120  case HEADER_TYPE_INVALID:
121  os << "Invalid";
122  break;
123  default:
124  os << "Unrecognized";
125  os << " (";
126  printHexValue(value,os);
127  os << ")";
128  break;
129  }
130  return os;
131  }
132 
133  std::ostream& operator<<(std::ostream& os, const FEDLegacyReadoutMode& value)
134  {
135  switch (value) {
136  case READOUT_MODE_LEGACY_SCOPE: os << "(L) Scope mode"; break;
137  case READOUT_MODE_LEGACY_VIRGIN_RAW_REAL: os << "(L) Virgin raw (real)"; break;
138  case READOUT_MODE_LEGACY_VIRGIN_RAW_FAKE: os << "(L) Virgin raw (fake)"; break;
139  case READOUT_MODE_LEGACY_PROC_RAW_REAL: os << "(L) Processed raw (real)"; break;
140  case READOUT_MODE_LEGACY_PROC_RAW_FAKE: os << "(L) Processed raw (fake)"; break;
141  case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_REAL: os << "(L) Zero suppressed (real)"; break;
142  case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_FAKE: os << "(L) Zero suppressed (fake)"; break;
143  case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_REAL: os << "(L) Zero suppressed lite (real)"; break;
144  case READOUT_MODE_LEGACY_ZERO_SUPPRESSED_LITE_FAKE: os << "(L) Zero suppressed lite (fake)"; break;
145  case READOUT_MODE_LEGACY_SPY: os << "(L) Spy channel"; break;
146  case READOUT_MODE_LEGACY_PREMIX_RAW: os << "(L) PreMix raw"; break;
147  case READOUT_MODE_LEGACY_INVALID: os << "(L) Invalid"; break;
148  default:
149  os << "(L) Unrecognized";
150  os << " (";
151  printHexValue(value,os);
152  os << ")";
153  break;
154  }
155  return os;
156  }
157 
158  std::ostream& operator<<(std::ostream& os, const FEDReadoutMode& value)
159  {
160  switch (value) {
161  case READOUT_MODE_SCOPE:
162  os << "Scope mode";
163  break;
165  os << "Virgin raw";
166  break;
168  os << "Processed raw";
169  break;
171  os << "Zero suppressed";
172  break;
174  os << "Zero suppressed (fake)";
175  break;
177  os << "Zero suppressed lite";
178  break;
179  case READOUT_MODE_SPY:
180  os << "Spy channel";
181  break;
182  /*case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
183  os << "Zero suppressed CM Override";
184  break;*/
186  os << "Zero suppressed lite CM Override";
187  break;
189  os << "Zero suppressed lite (8 bit, top-stripped)";
190  break;
192  os << "Zero suppressed lite CM Override (8 bit, top-stripped)";
193  break;
195  os << "Zero suppressed lite (8 bit, bottom-stripped)";
196  break;
198  os << "Zero suppressed lite CM Override (8 bit, bottom-stripped)";
199  break;
201  os << "Zero suppressed lite (8 bit, top/bottom-stripped)";
202  break;
204  os << "Zero suppressed lite CM Override (8 bit, top/bottom-stripped)";
205  break;
207  os << "PreMix raw";
208  break;
210  os << "Invalid";
211  break;
212  default:
213  os << "Unrecognized";
214  os << " (";
215  printHexValue(value,os);
216  os << ")";
217  break;
218  }
219  return os;
220  }
221 
222  std::ostream& operator<<(std::ostream& os, const FEDDAQEventType& value)
223  {
224  switch (value) {
226  os << "Physics trigger";
227  break;
229  os << "Calibration trigger";
230  break;
231  case DAQ_EVENT_TYPE_TEST:
232  os << "Test trigger";
233  break;
235  os << "Technical trigger";
236  break;
238  os << "Simulated event";
239  break;
241  os << "Traced event";
242  break;
244  os << "Error";
245  break;
247  os << "Unknown";
248  break;
249  default:
250  os << "Unrecognized";
251  os << " (";
252  printHexValue(value,os);
253  os << ")";
254  break;
255  }
256  return os;
257  }
258 
259  std::ostream& operator<<(std::ostream& os, const FEDTTSBits& value)
260  {
261  switch (value) {
262  case TTS_DISCONNECTED0:
263  os << "Disconected 0";
264  break;
265  case TTS_WARN_OVERFLOW:
266  os << "Warning overflow";
267  break;
268  case TTS_OUT_OF_SYNC:
269  os << "Out of sync";
270  break;
271  case TTS_BUSY:
272  os << "Busy";
273  break;
274  case TTS_READY:
275  os << "Ready";
276  break;
277  case TTS_ERROR:
278  os << "Error";
279  break;
280  case TTS_INVALID:
281  os << "Invalid";
282  break;
283  case TTS_DISCONNECTED1:
284  os << "Disconected 1";
285  break;
286  default:
287  os << "Unrecognized";
288  os << " (";
289  printHexValue(value,os);
290  os << ")";
291  break;
292  }
293  return os;
294  }
295 
296  std::ostream& operator<<(std::ostream& os, const FEDBufferState& value)
297  {
298  switch (value) {
299  case BUFFER_STATE_UNSET:
300  os << "Unset";
301  break;
302  case BUFFER_STATE_EMPTY:
303  os << "Empty";
304  break;
306  os << "Partial Full";
307  break;
308  case BUFFER_STATE_FULL:
309  os << "Full";
310  break;
311  default:
312  os << "Unrecognized";
313  os << " (";
314  printHexValue(value,os);
315  os << ")";
316  break;
317  }
318  return os;
319  }
320 
321  std::ostream& operator<<(std::ostream& os, const FEDChannelStatus& value)
322  {
323  if (!(value&CHANNEL_STATUS_LOCKED)) os << "Unlocked ";
324  if (!(value&CHANNEL_STATUS_IN_SYNC)) os << "Out-of-sync ";
325  if (!(value&CHANNEL_STATUS_APV1_ADDRESS_GOOD)) os << "APV 1 bad address ";
326  if (!(value&CHANNEL_STATUS_APV1_NO_ERROR_BIT)) os << "APV 1 error ";
327  if (!(value&CHANNEL_STATUS_APV0_ADDRESS_GOOD)) os << "APV 0 bad address ";
328  if (!(value&CHANNEL_STATUS_APV0_NO_ERROR_BIT)) os << "APV 0 error ";
329  if (value == CHANNEL_STATUS_NO_PROBLEMS) os << "No errors";
330  return os;
331  }
332 
334  {
335  if ( (bufferFormatString == "OLD_VME") ||
336  (bufferFormatString == "BUFFER_FORMAT_OLD_VME") ||
337  (bufferFormatString == "Old VME") ) {
338  return BUFFER_FORMAT_OLD_VME;
339  }
340  if ( (bufferFormatString == "OLD_SLINK") ||
341  (bufferFormatString == "BUFFER_FORMAT_OLD_SLINK") ||
342  (bufferFormatString == "Old S-Link") ) {
344  }
345  if ( (bufferFormatString == "NEW") ||
346  (bufferFormatString == "BUFFER_FORMAT_NEW") ||
347  (bufferFormatString == "New") ) {
348  return BUFFER_FORMAT_NEW;
349  }
350  //if it was none of the above then return invalid
351  return BUFFER_FORMAT_INVALID;
352  }
353 
355  {
356  if ( (headerTypeString == "FULL_DEBUG") ||
357  (headerTypeString == "HEADER_TYPE_FULL_DEBUG") ||
358  (headerTypeString == "Full debug") ) {
359  return HEADER_TYPE_FULL_DEBUG;
360  }
361  if ( (headerTypeString == "APV_ERROR") ||
362  (headerTypeString == "HEADER_TYPE_APV_ERROR") ||
363  (headerTypeString == "APV error") ) {
364  return HEADER_TYPE_APV_ERROR;
365  }
366  if ( (headerTypeString == "None") ||
367  (headerTypeString == "none") ) {
368  return HEADER_TYPE_NONE;
369  }
370  //if it was none of the above then return invalid
371  return HEADER_TYPE_INVALID;
372  }
373 
375  {
376  if ( (readoutModeString == "READOUT_MODE_SCOPE") ||
377  (readoutModeString == "SCOPE") ||
378  (readoutModeString == "SCOPE_MODE") ||
379  (readoutModeString == "Scope mode") ) {
380  return READOUT_MODE_SCOPE;
381  }
382  if ( (readoutModeString == "READOUT_MODE_VIRGIN_RAW") ||
383  (readoutModeString == "VIRGIN_RAW") ||
384  (readoutModeString == "Virgin raw") ) {
386  }
387  if ( (readoutModeString == "READOUT_MODE_PROC_RAW") ||
388  (readoutModeString == "PROC_RAW") ||
389  (readoutModeString == "PROCESSED_RAW") ||
390  (readoutModeString == "Processed raw") ) {
391  return READOUT_MODE_PROC_RAW;
392  }
393  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED") ||
394  (readoutModeString == "ZERO_SUPPRESSED") ||
395  (readoutModeString == "Zero suppressed") ) {
397  }
398  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE") ||
399  (readoutModeString == "ZERO_SUPPRESSED_LITE") ||
400  (readoutModeString == "Zero suppressed lite") ) {
402  }
403  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE") ||
404  (readoutModeString == "ZERO_SUPPRESSED_CMOVERRIDE") ||
405  (readoutModeString == "ZERO_SUPPRESSED_CMO") ||
406  (readoutModeString == "Zero suppressed CM Override") ) {
408  }
409  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE_CMOVERRIDE") ||
410  (readoutModeString == "ZERO_SUPPRESSED_LITE_CMO") ||
411  (readoutModeString == "ZERO_SUPPRESSED_LITE_CMOVERRIDE") ||
412  (readoutModeString == "Zero suppressed lite CM Override") ) {
414  }
415  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT") ||
416  (readoutModeString == "ZERO_SUPPRESSED_LITE8_TOPBOT") ||
417  (readoutModeString == "Zero suppressed lite8 TobBot") ){
419  }
420  if ( (readoutModeString == "READOUT_MODE_PREMIX_RAW") ||
421  (readoutModeString == "PREMIX_RAW") ||
422  (readoutModeString == "PreMix Raw") ) {
424  }
425  if ( (readoutModeString == "READOUT_MODE_SPY") ||
426  (readoutModeString == "SPY") ||
427  (readoutModeString == "Spy channel") ) {
428  return READOUT_MODE_SPY;
429  }
430  //if it was none of the above then return invalid
431  return READOUT_MODE_INVALID;
432  }
433 
435  {
436  if ( (daqEventTypeString == "PHYSICS") ||
437  (daqEventTypeString == "DAQ_EVENT_TYPE_PHYSICS") ||
438  (daqEventTypeString == "Physics trigger") ) {
439  return DAQ_EVENT_TYPE_PHYSICS;
440  }
441  if ( (daqEventTypeString == "CALIBRATION") ||
442  (daqEventTypeString == "DAQ_EVENT_TYPE_CALIBRATION") ||
443  (daqEventTypeString == "Calibration trigger") ) {
445  }
446  if ( (daqEventTypeString == "TEST") ||
447  (daqEventTypeString == "DAQ_EVENT_TYPE_TEST") ||
448  (daqEventTypeString == "Test trigger") ) {
449  return DAQ_EVENT_TYPE_TEST;
450  }
451  if ( (daqEventTypeString == "TECHNICAL") ||
452  (daqEventTypeString == "DAQ_EVENT_TYPE_TECHNICAL") ||
453  (daqEventTypeString == "Technical trigger") ) {
455  }
456  if ( (daqEventTypeString == "SIMULATED") ||
457  (daqEventTypeString == "DAQ_EVENT_TYPE_SIMULATED") ||
458  (daqEventTypeString == "Simulated trigger") ) {
460  }
461  if ( (daqEventTypeString == "TRACED") ||
462  (daqEventTypeString == "DAQ_EVENT_TYPE_TRACED") ||
463  (daqEventTypeString == "Traced event") ) {
464  return DAQ_EVENT_TYPE_TRACED;
465  }
466  if ( (daqEventTypeString == "ERROR") ||
467  (daqEventTypeString == "DAQ_EVENT_TYPE_ERROR") ||
468  (daqEventTypeString == "Error") ) {
469  return DAQ_EVENT_TYPE_ERROR;
470  }
471  //if it was none of the above then return invalid
472  return DAQ_EVENT_TYPE_INVALID;
473  }
474 
475 
476 
477 
478  void FEDStatusRegister::printFlags(std::ostream& os) const
479  {
480  if (slinkFullFlag()) os << "SLINK_FULL ";
481  if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
482  if (qdrMemoryFullFlag()) os << "QDR_FULL ";
483  if (qdrMemoryPartialFullFlag()) os << "QDR_PARTIAL_FULL ";
484  if (qdrMemoryEmptyFlag()) os << "QDR_EMPTY ";
485  if (l1aBxFIFOFullFlag()) os << "L1A_FULL ";
486  if (l1aBxFIFOPartialFullFlag()) os << "L1A_PARTIAL_FULL ";
487  if (l1aBxFIFOEmptyFlag()) os << "L1A_EMPTY ";
488  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
489  if (feDataMissingFlag(iFE)) os << "FEUNIT" << uint16_t(iFE) << "MISSING ";
490  }
491  }
492 
494  {
495  uint8_t result(0x00);
496  if (qdrMemoryFullFlag()) result |= BUFFER_STATE_FULL;
498  if (qdrMemoryEmptyFlag()) result |= BUFFER_STATE_EMPTY;
499  return FEDBufferState(result);
500  }
501 
503  {
504  uint8_t result(0x00);
505  if (l1aBxFIFOFullFlag()) result |= BUFFER_STATE_FULL;
507  if (l1aBxFIFOEmptyFlag()) result |= BUFFER_STATE_EMPTY;
508  return FEDBufferState(result);
509  }
510 
511  void FEDStatusRegister::setBit(const uint8_t num, const bool bitSet)
512  {
513  const uint16_t mask = (0x0001 << num);
514  if (bitSet) data_ |= mask;
515  else data_ &= (~mask);
516  }
517 
519  {
520  switch (state) {
521  case BUFFER_STATE_FULL:
523  case BUFFER_STATE_EMPTY:
524  case BUFFER_STATE_UNSET:
525  break;
526  default:
527  std::ostringstream ss;
528  ss << "Invalid buffer state: ";
529  printHex(&state,1,ss);
530  throw cms::Exception("FEDBuffer") << ss.str();
531  }
535  return *this;
536  }
537 
539  {
540  switch (state) {
541  case BUFFER_STATE_FULL:
543  case BUFFER_STATE_EMPTY:
544  case BUFFER_STATE_UNSET:
545  break;
546  default:
547  std::ostringstream ss;
548  ss << "Invalid buffer state: ";
549  printHex(&state,1,ss);
550  throw cms::Exception("FEDBuffer") << ss.str();
551  }
555  return *this;
556  }
557 
558 
559 
560 
561  void FEDBackendStatusRegister::printFlags(std::ostream& os) const
562  {
563  if (internalFreezeFlag()) os << "INTERNAL_FREEZE ";
564  if (slinkDownFlag()) os << "SLINK_DOWN ";
565  if (slinkFullFlag()) os << "SLINK_FULL ";
566  if (backpressureFlag()) os << "BACKPRESSURE ";
567  if (ttcReadyFlag()) os << "TTC_READY ";
568  if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
569  printFlagsForBuffer(qdrMemoryState(),"QDR",os);
570  printFlagsForBuffer(frameAddressFIFOState(),"FRAME_ADDRESS",os);
571  printFlagsForBuffer(totalLengthFIFOState(),"TOTAL_LENGTH",os);
572  printFlagsForBuffer(trackerHeaderFIFOState(),"TRACKER_HEADER",os);
573  printFlagsForBuffer(l1aBxFIFOState(),"L1ABX",os);
574  printFlagsForBuffer(feEventLengthFIFOState(),"FE_LENGTH",os);
575  printFlagsForBuffer(feFPGABufferState(),"FE",os);
576  }
577 
578  void FEDBackendStatusRegister::printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream& os) const
579  {
580  if (bufferState&BUFFER_STATE_EMPTY) os << name << "_EMPTY ";
581  if (bufferState&BUFFER_STATE_PARTIAL_FULL) os << name << "_PARTIAL_FULL ";
582  if (bufferState&BUFFER_STATE_FULL) os << name << "_FULL ";
583  if (bufferState == BUFFER_STATE_UNSET) os << name << "_UNSET ";
584  }
585 
586  FEDBufferState FEDBackendStatusRegister::getBufferState(const uint8_t bufferPosition) const
587  {
588  uint8_t result = 0x00;
589  if (getBit(bufferPosition+STATE_OFFSET_EMPTY)) result |= BUFFER_STATE_EMPTY;
590  if (getBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL)) result |= BUFFER_STATE_PARTIAL_FULL;
591  if (getBit(bufferPosition+STATE_OFFSET_FULL)) result |= BUFFER_STATE_FULL;
592  return FEDBufferState(result);
593  }
594 
595  void FEDBackendStatusRegister::setBufferSate(const uint8_t bufferPosition, const FEDBufferState state)
596  {
597  switch (state) {
598  case BUFFER_STATE_FULL:
600  case BUFFER_STATE_EMPTY:
601  case BUFFER_STATE_UNSET:
602  break;
603  default:
604  std::ostringstream ss;
605  ss << "Invalid buffer state: ";
606  printHex(&state,1,ss);
607  throw cms::Exception("FEDBuffer") << ss.str();
608  }
609  setBit(bufferPosition+STATE_OFFSET_EMPTY, state&BUFFER_STATE_EMPTY);
610  setBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL, state&BUFFER_STATE_PARTIAL_FULL);
611  setBit(bufferPosition+STATE_OFFSET_FULL, state&BUFFER_STATE_FULL);
612  }
613 
614  void FEDBackendStatusRegister::setBit(const uint8_t num, const bool bitSet)
615  {
616  const uint32_t mask = (0x00000001 << num);
617  if (bitSet) data_ |= mask;
618  else data_ &= (~mask);
619  }
620 
622  const FEDBufferState frameAddressFIFOBufferState,
623  const FEDBufferState totalLengthFIFOBufferState,
624  const FEDBufferState trackerHeaderFIFOBufferState,
625  const FEDBufferState l1aBxFIFOBufferState,
626  const FEDBufferState feEventLengthFIFOBufferState,
627  const FEDBufferState feFPGABufferState,
628  const bool backpressure, const bool slinkFull,
629  const bool slinkDown, const bool internalFreeze,
630  const bool trackerHeaderMonitorDataReady, const bool ttcReady)
631  : data_(0)
632  {
633  setInternalFreezeFlag(internalFreeze);
634  setSLinkDownFlag(slinkDown);
635  setSLinkFullFlag(slinkFull);
636  setBackpressureFlag(backpressure);
637  setTTCReadyFlag(ttcReady);
638  setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReady);
639  setQDRMemoryState(qdrMemoryBufferState);
640  setFrameAddressFIFOState(frameAddressFIFOBufferState);
641  setTotalLengthFIFOState(totalLengthFIFOBufferState);
642  setTrackerHeaderFIFOState(trackerHeaderFIFOBufferState);
643  setL1ABXFIFOState(l1aBxFIFOBufferState);
644  setFEEventLengthFIFOState(feEventLengthFIFOBufferState);
645  setFEFPGABufferState(feFPGABufferState);
646  }
647 
648 
649 
650 
651  TrackerSpecialHeader::TrackerSpecialHeader(const uint8_t* headerPointer)
652  {
653  //the buffer format byte is one of the valid values if we assume the buffer is not swapped
654  const bool validFormatByteWhenNotWordSwapped = ( (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_NEW) ||
655  (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_OLD) );
656  //the buffer format byte is the old value if we assume the buffer is swapped
657  const bool validFormatByteWhenWordSwapped = (headerPointer[BUFFERFORMAT^4] == BUFFER_FORMAT_CODE_OLD);
658  //if the buffer format byte is valid if the buffer is not swapped or it is never valid
659  if (validFormatByteWhenNotWordSwapped || (!validFormatByteWhenNotWordSwapped && !validFormatByteWhenWordSwapped) ) {
660  memcpy(specialHeader_,headerPointer,8);
661  wordSwapped_ = false;
662  } else {
663  memcpy(specialHeader_,headerPointer+4,4);
664  memcpy(specialHeader_+4,headerPointer,4);
665  wordSwapped_ = true;
666  }
667  }
668 
670  {
671  if (bufferFormatByte() == BUFFER_FORMAT_CODE_NEW) return BUFFER_FORMAT_NEW;
672  else if (bufferFormatByte() == BUFFER_FORMAT_CODE_OLD) {
673  if (wordSwapped_) return BUFFER_FORMAT_OLD_VME;
674  else return BUFFER_FORMAT_OLD_SLINK;
675  }
676  else return BUFFER_FORMAT_INVALID;
677  }
678 
680  {
681  if ( (headerTypeNibble() == HEADER_TYPE_FULL_DEBUG) ||
682  (headerTypeNibble() == HEADER_TYPE_APV_ERROR) ||
683  (headerTypeNibble() == HEADER_TYPE_NONE) )
684  return FEDHeaderType(headerTypeNibble());
685  else return HEADER_TYPE_INVALID;
686  }
687 
689  {
690  const uint8_t eventTypeNibble = trackerEventTypeNibble();
691  const uint8_t mode = (eventTypeNibble & 0xF);
692  switch(mode) {
701  return FEDLegacyReadoutMode(mode);
702  default:
704  }
705  }
706 
708  {
709  const uint8_t eventTypeNibble = trackerEventTypeNibble();
710  //if it is scope mode then return as is (it cannot be fake data)
711  if (eventTypeNibble == READOUT_MODE_SCOPE) return FEDReadoutMode(eventTypeNibble);
712  //if it is premix then return as is: stripping last bit would make it spy data !
713  if (eventTypeNibble == READOUT_MODE_PREMIX_RAW) return FEDReadoutMode(eventTypeNibble);
714  //if not then ignore the last bit which indicates if it is real or fake
715  else {
716  const uint8_t mode = (eventTypeNibble & 0xF);
717  switch(mode) {
723  //case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
731  case READOUT_MODE_SPY:
732  return FEDReadoutMode(mode);
733  default:
734  return READOUT_MODE_INVALID;
735  }
736  }
737  }
738 
740  {
741  //check if order in buffer is different
742  if ( ( (bufferFormat()==BUFFER_FORMAT_OLD_VME) && (newBufferFormat!=BUFFER_FORMAT_OLD_VME) ) ||
743  ( (bufferFormat()!=BUFFER_FORMAT_OLD_VME) && (newBufferFormat==BUFFER_FORMAT_OLD_VME) ) ) {
744  wordSwapped_ = !wordSwapped_;
745  }
746  //set appropriate code
747  setBufferFormatByte(newBufferFormat);
748  return *this;
749  }
750 
752  {
753  switch (newBufferFormat) {
756  specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_OLD;
757  break;
758  case BUFFER_FORMAT_NEW:
759  specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_NEW;
760  break;
761  default:
762  std::ostringstream ss;
763  ss << "Invalid buffer format: ";
764  printHex(&newBufferFormat,1,ss);
765  throw cms::Exception("FEDBuffer") << ss.str();
766  }
767  }
768 
770  {
771  switch(headerType) {
774  case HEADER_TYPE_NONE:
775  setHeaderTypeNibble(headerType);
776  return *this;
777  default:
778  std::ostringstream ss;
779  ss << "Invalid header type: ";
780  printHex(&headerType,1,ss);
781  throw cms::Exception("FEDBuffer") << ss.str();
782  }
783  }
784 
786  {
787  switch(readoutMode) {
788  case READOUT_MODE_SCOPE:
789  //scope mode is always real
790  setReadoutModeBits(readoutMode);
793  case READOUT_MODE_SPY:
804  setReadoutModeBits(readoutMode);
805  break;
807  //special mode for simulation
808  setReadoutModeBits(readoutMode);
809  break;
810  default:
811  std::ostringstream ss;
812  ss << "Invalid readout mode: ";
813  printHex(&readoutMode,1,ss);
814  throw cms::Exception("FEDBuffer") << ss.str();
815  }
816  return *this;
817  }
818 
820  {
821  const uint8_t mask = 0x1 << internalFEUnitNum;
822  const uint8_t result = ( (apvAddressErrorRegister() & (~mask)) | (error?mask:0x00) );
823  setAPVEAddressErrorRegister(result);
824  return *this;
825  }
826 
827  TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
828  {
829  const uint8_t mask = 0x1 << internalFEUnitNum;
830  const uint8_t result = ( (feEnableRegister() & (~mask)) | (enabled?mask:0x00) );
831  setFEEnableRegister(result);
832  return *this;
833  }
834 
835  TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow)
836  {
837  const uint8_t mask = 0x1 << internalFEUnitNum;
838  const uint8_t result = ( (feOverflowRegister() & (~mask)) | (overflow?mask:0x00) );
839  setFEEnableRegister(result);
840  return *this;
841  }
842 
844  const FEDHeaderType headerType,
845  const uint8_t address, const uint8_t addressErrorRegister,
846  const uint8_t feEnableRegister, const uint8_t feOverflowRegister,
847  const FEDStatusRegister fedStatusRegister)
848  {
849  memset(specialHeader_,0x00,8);
850  //determine if order is swapped in real buffer
851  wordSwapped_ = (bufferFormat == BUFFER_FORMAT_OLD_VME);
852  //set fields
853  setBufferFormatByte(bufferFormat);
854  setReadoutMode(readoutMode);
855  setHeaderType(headerType);
856  setAPVEAddress(address);
857  setAPVEAddressErrorRegister(addressErrorRegister);
858  setFEEnableRegister(feEnableRegister);
859  setFEOverflowRegister(feOverflowRegister);
860  setFEDStatusRegister(fedStatusRegister);
861  }
862 
863 
864 
865 
867  {
868  switch(eventTypeNibble()) {
871  case DAQ_EVENT_TYPE_TEST:
876  return FEDDAQEventType(eventTypeNibble());
877  default:
878  return DAQ_EVENT_TYPE_INVALID;
879  }
880  }
881 
883  {
884  header_[7] = ((header_[7] & 0xF0) | evtType);
885  return *this;
886  }
887 
888  FEDDAQHeader& FEDDAQHeader::setL1ID(const uint32_t l1ID)
889  {
890  header_[4] = (l1ID & 0x000000FF);
891  header_[5] = ( (l1ID & 0x0000FF00) >> 8);
892  header_[6] = ( (l1ID & 0x00FF0000) >> 16);
893  return *this;
894  }
895 
896  FEDDAQHeader& FEDDAQHeader::setBXID(const uint16_t bxID)
897  {
898  header_[3] = ( (bxID & 0x0FF0) >> 4);
899  header_[2] = ( (header_[2] & 0x0F) | ( (bxID & 0x000F) << 4) );
900  return *this;
901  }
902 
903  FEDDAQHeader& FEDDAQHeader::setSourceID(const uint16_t sourceID)
904  {
905  header_[2] = ( (header_[2] & 0xF0) | ( (sourceID & 0x0F00) >> 8) );
906  header_[1] = (sourceID & 0x00FF);
907  return *this;
908  }
909 
910  FEDDAQHeader::FEDDAQHeader(const uint32_t l1ID, const uint16_t bxID, const uint16_t sourceID, const FEDDAQEventType evtType)
911  {
912  //clear everything (FOV,H,x,$ all set to 0)
913  memset(header_,0x0,8);
914  //set the BoE nibble to indicate this is the last fragment
915  header_[7] = 0x50;
916  //set variable fields vith values supplied
917  setEventType(evtType);
918  setL1ID(l1ID);
919  setBXID(bxID);
920  setSourceID(sourceID);
921  }
922 
923 
924 
925 
927  {
928  switch(ttsNibble()) {
929  case TTS_DISCONNECTED0:
930  case TTS_WARN_OVERFLOW:
931  case TTS_OUT_OF_SYNC:
932  case TTS_BUSY:
933  case TTS_READY:
934  case TTS_ERROR:
935  case TTS_DISCONNECTED1:
936  return FEDTTSBits(ttsNibble());
937  default:
938  return TTS_INVALID;
939  }
940  }
941 
942  FEDDAQTrailer::FEDDAQTrailer(const uint32_t eventLengthIn64BitWords, const uint16_t crc, const FEDTTSBits ttsBits,
943  const bool slinkTransmissionError, const bool badFEDID, const bool slinkCRCError,
944  const uint8_t eventStatusNibble)
945  {
946  //clear everything (T,x,$ all set to 0)
947  memset(trailer_,0x0,8);
948  //set the EoE nibble to indicate this is the last fragment
949  trailer_[7] = 0xA0;
950  //set variable fields vith values supplied
951  setEventLengthIn64BitWords(eventLengthIn64BitWords);
952  setEventStatusNibble(eventStatusNibble);
953  setTTSBits(ttsBits);
954  setCRC(crc);
955  setSLinkTransmissionErrorBit(slinkTransmissionError);
956  setBadSourceIDBit(badFEDID);
957  setSLinkCRCErrorBit(slinkCRCError);
958  }
959 
960  FEDDAQTrailer& FEDDAQTrailer::setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
961  {
962  trailer_[4] = (eventLengthIn64BitWords & 0x000000FF);
963  trailer_[5] = ( (eventLengthIn64BitWords & 0x0000FF00) >> 8);
964  trailer_[6] = ( (eventLengthIn64BitWords & 0x00FF0000) >> 16);
965  return *this;
966  }
967 
969  {
970  trailer_[2] = (crc & 0x00FF);
971  trailer_[3] = ( (crc >> 8) & 0x00FF );
972  return *this;
973  }
974 
976  {
977  if (bitSet) trailer_[1] |= 0x80;
978  else trailer_[1] &= (~0x80);
979  return *this;
980  }
981 
983  {
984  if (bitSet) trailer_[1] |= 0x40;
985  else trailer_[1] &= (~0x40);
986  return *this;
987  }
988 
990  {
991  if (bitSet) trailer_[0] |= 0x04;
992  else trailer_[0] &= (~0x40);
993  return *this;
994  }
995 
996  FEDDAQTrailer& FEDDAQTrailer::setEventStatusNibble(const uint8_t eventStatusNibble)
997  {
998  trailer_[1] = ( (trailer_[1] & 0xF0) | (eventStatusNibble & 0x0F) );
999  return *this;
1000  }
1001 
1003  {
1004  trailer_[0] = ( (trailer_[0] & 0x0F) | (ttsBits & 0xF0) );
1005  return *this;
1006  }
1007 
1008 
1009 
1010 
1012  {
1013  }
1014 
1016  {
1017  return APV_ERROR_HEADER_SIZE_IN_BYTES;
1018  }
1019 
1020  void FEDAPVErrorHeader::print(std::ostream& os) const
1021  {
1022  printHex(header_,APV_ERROR_HEADER_SIZE_IN_BYTES,os);
1023  }
1024 
1026  {
1027  return new FEDAPVErrorHeader(*this);
1028  }
1029 
1030  bool FEDAPVErrorHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1031  {
1032  //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1033  const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FEUNIT)*24 + (FEDCH_PER_FEUNIT-1-(internalFEDChannelNum%FEDCH_PER_FEUNIT))*2 + apvNum;
1034  //bit high means no error
1035  return (header_[bitNumber/8] & (0x01<<(bitNumber%8)) );
1036  }
1037 
1039  {
1040  return (checkStatusBits(internalFEDChannelNum,0) && checkStatusBits(internalFEDChannelNum,1));
1041  }
1042 
1043  const uint8_t* FEDAPVErrorHeader::data() const
1044  {
1045  return header_;
1046  }
1047 
1048  FEDAPVErrorHeader::FEDAPVErrorHeader(const std::vector<bool>& apvsGood)
1049  {
1050  memset(header_,0x00,APV_ERROR_HEADER_SIZE_IN_BYTES);
1051  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1052  setAPVStatusBit(iCh,0,apvsGood[iCh*2]);
1053  setAPVStatusBit(iCh,1,apvsGood[iCh*2+1]);
1054  }
1055  }
1056 
1057  FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood)
1058  {
1059  //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1060  const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FED)*24 + (FEDCH_PER_FED-1-(internalFEDChannelNum%FEDCH_PER_FED))*2+apvNum;
1061  const uint8_t byteNumber = bitNumber/8;
1062  const uint8_t bitInByte = bitNumber%8;
1063  const uint8_t mask = (0x01 << bitInByte);
1064  header_[byteNumber] = ( (header_[byteNumber] & (~mask)) | (apvGood?mask:0x00) );
1065  return *this;
1066  }
1067 
1069  {
1070  //if channel is unlocked then set both APV bits bad
1071  if ( (!(status & CHANNEL_STATUS_LOCKED)) || (!(status & CHANNEL_STATUS_IN_SYNC)) ) {
1072  setAPVStatusBit(internalFEDChannelNum,0,false);
1073  setAPVStatusBit(internalFEDChannelNum,1,false);
1074  return;
1075  } else {
1076  if ( (status & CHANNEL_STATUS_APV0_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV0_NO_ERROR_BIT) ) {
1077  setAPVStatusBit(internalFEDChannelNum,0,true);
1078  } else {
1079  setAPVStatusBit(internalFEDChannelNum,0,false);
1080  }
1081  if ( (status & CHANNEL_STATUS_APV1_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV1_NO_ERROR_BIT) ) {
1082  setAPVStatusBit(internalFEDChannelNum,1,true);
1083  } else {
1084  setAPVStatusBit(internalFEDChannelNum,1,false);
1085  }
1086  }
1087  }
1088 
1089  //These methods do nothing as the values in question are in present in the APV Error header.
1090  //The methods exist so that users of the base class can set the values without caring which type of header they have and so if they are needed.
1091  void FEDAPVErrorHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
1092  {
1093  return;
1094  }
1096  {
1097  return;
1098  }
1099  void FEDAPVErrorHeader::setDAQRegister(const uint32_t daqRegister)
1100  {
1101  return;
1102  }
1103  void FEDAPVErrorHeader::setDAQRegister2(const uint32_t daqRegister2)
1104  {
1105  return;
1106  }
1107  void FEDAPVErrorHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister)
1108  {
1109  return;
1110  }
1111  void FEDAPVErrorHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
1112  {
1113  return;
1114  }
1115 
1116 
1118  {
1119  }
1120 
1122  {
1123  return FULL_DEBUG_HEADER_SIZE_IN_BYTES;
1124  }
1125 
1126  void FEDFullDebugHeader::print(std::ostream& os) const
1127  {
1128  printHex(header_,FULL_DEBUG_HEADER_SIZE_IN_BYTES,os);
1129  }
1130 
1132  {
1133  return new FEDFullDebugHeader(*this);
1134  }
1135 
1136  bool FEDFullDebugHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1137  {
1138  return ( !unlockedFromBit(internalFEDChannelNum) &&
1139  !outOfSyncFromBit(internalFEDChannelNum) &&
1140  !apvError(internalFEDChannelNum,apvNum) &&
1141  !apvAddressError(internalFEDChannelNum,apvNum) );
1142  }
1143 
1145  {
1146  //return ( !unlockedFromBit(internalFEDChannelNum) &&
1147  // !outOfSyncFromBit(internalFEDChannelNum) &&
1148  // !apvErrorFromBit(internalFEDChannelNum,0) &&
1149  // !apvAddressErrorFromBit(internalFEDChannelNum,0) &&
1150  // !apvErrorFromBit(internalFEDChannelNum,1) &&
1151  // !apvAddressErrorFromBit(internalFEDChannelNum,1) );
1152  return (getChannelStatus(internalFEDChannelNum) == CHANNEL_STATUS_NO_PROBLEMS);
1153  }
1154 
1156  {
1157  const uint8_t* pFEWord = feWord(internalFEDChannelNum/FEDCH_PER_FEUNIT);
1158  const uint8_t feUnitChanNum = internalFEDChannelNum % FEDCH_PER_FEUNIT;
1159  const uint8_t startByteInFEWord = (FEDCH_PER_FEUNIT-1 - feUnitChanNum) * 6 / 8;
1160  switch ( (FEDCH_PER_FEUNIT-1-feUnitChanNum) % 4 ) {
1161  case 0:
1162  return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
1163  case 1:
1164  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
1165  case 2:
1166  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
1167  case 3:
1168  return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
1169  //stop compiler warning
1170  default:
1171  return FEDChannelStatus(0);
1172  }
1173  /*const uint8_t feUnitChanNum = internalFEDChannelNum / FEDCH_PER_FEUNIT;
1174  const uint8_t* pFEWord = feWord(feUnitChanNum);
1175  const uint8_t startByteInFEWord = feUnitChanNum * 3 / 4;
1176  //const uint8_t shift = ( 6 - ((feUnitChanNum-1)%4) );
1177  //const uint16_t mask = ( 0x003F << shift );
1178  //uint8_t result = ( (pFEWord[startByteInFEWord] & (mask&0x00FF)) >> shift );
1179  //result |= ( (pFEWord[startByteInFEWord+1] & (mask>>8)) << (8-shift) );
1180  switch (feUnitChanNum % 4) {
1181  case 0:
1182  return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
1183  case 1:
1184  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
1185  case 2:
1186  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
1187  case 3:
1188  return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
1189  //stop compiler warning
1190  default:
1191  return FEDChannelStatus(0);
1192  }*/
1193  }
1194 
1195  const uint8_t* FEDFullDebugHeader::data() const
1196  {
1197  return header_;
1198  }
1199 
1200  FEDFullDebugHeader::FEDFullDebugHeader(const std::vector<uint16_t>& feUnitLengths, const std::vector<uint8_t>& feMajorityAddresses,
1201  const std::vector<FEDChannelStatus>& channelStatus, const FEDBackendStatusRegister beStatusRegister,
1202  const uint32_t daqRegister, const uint32_t daqRegister2)
1203  {
1204  memset(header_,0x00,FULL_DEBUG_HEADER_SIZE_IN_BYTES);
1205  setBEStatusRegister(beStatusRegister);
1206  setDAQRegister(daqRegister);
1207  setDAQRegister2(daqRegister2);
1208  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1209  setFEUnitLength(iFE,feUnitLengths[iFE]);
1210  setFEUnitMajorityAddress(iFE,feMajorityAddresses[iFE]);
1211  }
1212  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1213  setChannelStatus(iCh,channelStatus[iCh]);
1214  }
1215  }
1216 
1218  {
1219  setUnlocked(internalFEDChannelNum, !(status&CHANNEL_STATUS_LOCKED) );
1220  setOutOfSync(internalFEDChannelNum, !(status&CHANNEL_STATUS_IN_SYNC) );
1221  setAPVAddressError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_ADDRESS_GOOD) );
1222  setAPVAddressError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_ADDRESS_GOOD) );
1223  setAPVError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_NO_ERROR_BIT) );
1224  setAPVError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_NO_ERROR_BIT) );
1225  }
1226 
1227  void FEDFullDebugHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
1228  {
1229  feWord(internalFEUnitNum)[9] = address;
1230  }
1231 
1233  {
1234  set32BitWordAt(feWord(0)+10,beStatusRegister);
1235  }
1236 
1237  void FEDFullDebugHeader::setDAQRegister(const uint32_t daqRegister)
1238  {
1239  set32BitWordAt(feWord(7)+10,daqRegister);
1240  }
1241 
1242  void FEDFullDebugHeader::setDAQRegister2(const uint32_t daqRegister2)
1243  {
1244  set32BitWordAt(feWord(6)+10,daqRegister2);
1245  }
1246 
1247  //used by DigiToRaw to copy reserved registers in internalFEUnit buffers 1 through 5
1248  void FEDFullDebugHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister)
1249  {
1250  set32BitWordAt(feWord(internalFEUnitNum)+10,reservedRegister);
1251  }
1252 
1253  void FEDFullDebugHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
1254  {
1255  feWord(internalFEUnitNum)[15] = ( (length & 0xFF00) >> 8);
1256  feWord(internalFEUnitNum)[14] = (length & 0x00FF);
1257  }
1258 
1259  void FEDFullDebugHeader::setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value)
1260  {
1261  const uint8_t bitInFeWord = (FEDCH_PER_FEUNIT-1 - (internalFEDChannelNum%FEDCH_PER_FEUNIT)) * 6 + bit;
1262  uint8_t& byte = *(feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT)+(bitInFeWord/8));
1263  const uint8_t mask = (0x1 << bitInFeWord%8);
1264  byte = ( (byte & (~mask)) | (value?mask:0x0) );
1265  }
1266 
1268  {
1269  }
1270 
1271 
1272 
1273 
1274  FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
1275  : channels_(FEDCH_PER_FED,FEDChannel(nullptr,0,0)),
1276  originalBuffer_(fedBuffer),
1277  bufferSize_(fedBufferSize)
1278  {
1279  init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
1280  }
1281 
1282  FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat, const bool fillChannelVector)
1283  : originalBuffer_(fedBuffer),
1284  bufferSize_(fedBufferSize)
1285  {
1286  init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
1287  if (fillChannelVector) channels_.assign(FEDCH_PER_FED,FEDChannel(nullptr,0,0));
1288  }
1289 
1290  void FEDBufferBase::init(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
1291  {
1292  //min buffer length. DAQ header, DAQ trailer, tracker special header.
1293  static const size_t MIN_BUFFER_SIZE = 8+8+8;
1294  //check size is non zero and data pointer is not NULL
1295  if (!originalBuffer_) throw cms::Exception("FEDBuffer") << "Buffer pointer is NULL.";
1296  if (bufferSize_ < MIN_BUFFER_SIZE) {
1297  std::ostringstream ss;
1298  ss << "Buffer is too small. "
1299  << "Min size is " << MIN_BUFFER_SIZE << ". "
1300  << "Buffer size is " << bufferSize_ << ". ";
1301  throw cms::Exception("FEDBuffer") << ss.str();
1302  }
1303 
1304  //construct tracker special header using second 64 bit word
1306 
1307  //check the buffer format
1309  if (bufferFormat == BUFFER_FORMAT_INVALID && !allowUnrecognizedFormat) {
1310  std::ostringstream ss;
1311  ss << "Buffer format not recognized. "
1312  << "Tracker special header: " << specialHeader_;
1313  throw cms::Exception("FEDBuffer") << ss.str();
1314  }
1315  //swap the buffer words so that the whole buffer is in slink ordering
1316  if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) ) {
1317  uint8_t* newBuffer = new uint8_t[bufferSize_];
1318  const uint32_t* originalU32 = reinterpret_cast<const uint32_t*>(originalBuffer_);
1319  const size_t sizeU32 = bufferSize_/4;
1320  uint32_t* newU32 = reinterpret_cast<uint32_t*>(newBuffer);
1321  if (bufferFormat == BUFFER_FORMAT_OLD_VME) {
1322  //swap whole buffer
1323  for (size_t i = 0; i < sizeU32; i+=2) {
1324  newU32[i] = originalU32[i+1];
1325  newU32[i+1] = originalU32[i];
1326  }
1327  }
1328  if (bufferFormat == BUFFER_FORMAT_NEW) {
1329  //copy DAQ header
1330  memcpy(newU32,originalU32,8);
1331  //copy DAQ trailer
1332  memcpy(newU32+sizeU32-2,originalU32+sizeU32-2,8);
1333  //swap the payload
1334  for (size_t i = 2; i < sizeU32-2; i+=2) {
1335  newU32[i] = originalU32[i+1];
1336  newU32[i+1] = originalU32[i];
1337  }
1338  }
1339  orderedBuffer_ = newBuffer;
1340  } //if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) )
1341  else {
1343  }
1344 
1345  //construct header object at begining of buffer
1347  //construct trailer object using last 64 bit word of buffer
1349  }
1350 
1352  {
1353  //if the buffer was coppied and swapped then delete the copy
1355  }
1356 
1357  void FEDBufferBase::print(std::ostream& os) const
1358  {
1359  os << "buffer format: " << bufferFormat() << std::endl;
1360  os << "Buffer size: " << bufferSize() << " bytes" << std::endl;
1361  os << "Event length from DAQ trailer: " << daqEventLengthInBytes() << " bytes" << std::endl;
1362  os << "Source ID: " << daqSourceID() << std::endl;
1363  os << "Header type: " << headerType() << std::endl;
1364  os << "Readout mode: " << readoutMode() << std::endl;
1365  os << "DAQ event type: " << daqEventType() << std::endl;
1366  os << "TTS state: " << daqTTSState() << std::endl;
1367  os << "L1 ID: " << daqLvl1ID() << std::endl;
1368  os << "BX ID: " << daqBXID() << std::endl;
1369  os << "FED status register flags: "; fedStatusRegister().printFlags(os); os << std::endl;
1370  os << "APVe Address: " << uint16_t(apveAddress()) << std::endl;
1371  os << "Enabled FE units: " << uint16_t(nFEUnitsEnabled()) << std::endl;
1372  }
1373 
1375  {
1376  uint8_t result = 0;
1377  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1378  if (feEnabled(iFE)) result++;
1379  }
1380  return result;
1381  }
1382 
1384  {
1385  return ( (daqSourceID() >= FED_ID_MIN) &&
1386  (daqSourceID() <= FED_ID_MAX) );
1387  }
1388 
1390  {
1391  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1392  if (!feEnabled(iFE)) continue;
1393  if (majorityAddressErrorForFEUnit(iFE)) return false;
1394  }
1395  return true;
1396  }
1397 
1399  {
1400  const uint8_t feUnit = internalFEDChannelNum/FEDCH_PER_FEUNIT;
1401  return ( !majorityAddressErrorForFEUnit(feUnit) && feEnabled(feUnit) && !feOverflow(feUnit) );
1402  }
1403 
1405  {
1407  }
1408 
1410  {
1411  std::ostringstream summary;
1412  summary << "Check buffer type valid: " << ( checkBufferFormat() ? "passed" : "FAILED" ) << std::endl;
1413  summary << "Check header format valid: " << ( checkHeaderType() ? "passed" : "FAILED" ) << std::endl;
1414  summary << "Check readout mode valid: " << ( checkReadoutMode() ? "passed" : "FAILED" ) << std::endl;
1415  //summary << "Check APVe address valid: " << ( checkAPVEAddressValid() ? "passed" : "FAILED" ) << std::endl;
1416  summary << "Check FE unit majority addresses: " << ( checkMajorityAddresses() ? "passed" : "FAILED" ) << std::endl;
1417  if (!checkMajorityAddresses()) {
1418  summary << "FEs with majority address error: ";
1419  unsigned int badFEs = 0;
1420  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1421  if (!feEnabled(iFE)) continue;
1422  if (majorityAddressErrorForFEUnit(iFE)) {
1423  summary << uint16_t(iFE) << " ";
1424  badFEs++;
1425  }
1426  }
1427  summary << std::endl;
1428  summary << "Number of FE Units with bad addresses: " << badFEs << std::endl;
1429  }
1430  summary << "Check for FE unit buffer overflows: " << ( checkNoFEOverflows() ? "passed" : "FAILED" ) << std::endl;
1431  if (!checkNoFEOverflows()) {
1432  summary << "FEs which overflowed: ";
1433  unsigned int badFEs = 0;
1434  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1435  if (feOverflow(iFE)) {
1436  summary << uint16_t(iFE) << " ";
1437  badFEs++;
1438  }
1439  }
1440  summary << std::endl;
1441  summary << "Number of FE Units which overflowed: " << badFEs << std::endl;
1442  }
1443  summary << "Check for S-Link CRC errors: " << ( checkNoSlinkCRCError() ? "passed" : "FAILED" ) << std::endl;
1444  summary << "Check for S-Link transmission error: " << ( checkNoSLinkTransmissionError() ? "passed" : "FAILED" ) << std::endl;
1445  summary << "Check CRC: " << ( checkCRC() ? "passed" : "FAILED" ) << std::endl;
1446  summary << "Check source ID is FED ID: " << ( checkSourceIDs() ? "passed" : "FAILED" ) << std::endl;
1447  summary << "Check for unexpected source ID at FRL: " << ( checkNoUnexpectedSourceID() ? "passed" : "FAILED" ) << std::endl;
1448  summary << "Check there are no extra headers or trailers: " << ( checkNoExtraHeadersOrTrailers() ? "passed" : "FAILED" ) << std::endl;
1449  summary << "Check length from trailer: " << ( checkLengthFromTrailer() ? "passed" : "FAILED" ) << std::endl;
1450  return summary.str();
1451  }
1452 
1453 
1454 
1455 
1456  uint16_t FEDChannel::cmMedian(const uint8_t apvIndex) const
1457  {
1459  std::ostringstream ss;
1460  ss << "Request for CM median from channel with non-ZS packet code. "
1461  << "Packet code is " << uint16_t(packetCode()) << "."
1462  << std::endl;
1463  throw cms::Exception("FEDBuffer") << ss.str();
1464  }
1465  if (apvIndex > 1) {
1466  std::ostringstream ss;
1467  ss << "Channel APV index out of range when requesting CM median for APV. "
1468  << "Channel APV index is " << uint16_t(apvIndex) << "."
1469  << std::endl;
1470  throw cms::Exception("FEDBuffer") << ss.str();
1471  }
1472  uint16_t result = 0;
1473  //CM median is 10 bits with lowest order byte first. First APV CM median starts in 4th byte of channel data
1474  result |= data_[(offset_+3+2*apvIndex)^7];
1475  result |= ( ((data_[(offset_+4+2*apvIndex)^7]) << 8) & 0x300 );
1476  return result;
1477  }
1478 
1479 }
FEDBackendStatusRegister & setFEFPGABufferState(const FEDBufferState state)
FEDBackendStatusRegister & setQDRMemoryState(const FEDBufferState state)
FEDBackendStatusRegister & setL1ABXFIFOState(const FEDBufferState state)
bool feDataMissingFlag(const uint8_t internalFEUnitNum) const
void setDAQRegister2(const uint32_t daqRegister2) override
void printHexValue(const uint8_t value, std::ostream &os)
void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) override
void printFlags(std::ostream &os) const
void setBit(const uint8_t num, const bool bitSet)
static const uint16_t FED_ID_MIN
bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const override
bool getBit(const uint8_t num) const
void setQDRMemoryEmptyFlag(const bool bitSet)
bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const override
const double w
Definition: UKUtility.cc:23
void setDAQRegister2(const uint32_t daqRegister2) override
void set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister) override
virtual std::string checkSummary() const
FEDBackendStatusRegister & setFrameAddressFIFOState(const FEDBufferState state)
FEDBackendStatusRegister & setTrackerHeaderFIFOState(const FEDBufferState state)
FEDFullDebugHeader(const uint8_t *headerBuffer)
const uint8_t * data() const override
FEDDAQTrailer & setSLinkCRCErrorBit(const bool bitSet)
FEDDAQTrailer & setTTSBits(const FEDTTSBits ttsBits)
FEDReadoutMode readoutMode() const
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
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)
void setDAQRegister(const uint32_t daqRegister) override
void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) override
#define nullptr
std::ostream & operator<<(std::ostream &os, const FEDBufferFormat &value)
FEDAPVErrorHeader(const uint8_t *headerBuffer)
FEDBufferFormat fedBufferFormatFromString(const std::string &bufferFormatString)
void setBit(const uint8_t num, const bool bitSet)
sistrip classes
FEDDAQEventType daqEventType() const
TrackerSpecialHeader & setHeaderType(const FEDHeaderType headerType)
bool checkChannelStatusBits(const uint8_t internalFEDChannelNum) const override
FEDReadoutMode fedReadoutModeFromString(const std::string &readoutModeString)
FEDBackendStatusRegister(const uint32_t backendStatusRegister)
uint16_t cmMedian(const uint8_t apvIndex) const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
FEDBackendStatusRegister & setTotalLengthFIFOState(const FEDBufferState state)
TrackerSpecialHeader & setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
FEDDAQTrailer & setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
FEDLegacyReadoutMode legacyReadoutMode() const
FEDDAQTrailer & setEventStatusNibble(const uint8_t eventStatusNibble)
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
FEDBackendStatusRegister & setTTCReadyFlag(const bool bitSet)
FEDDAQTrailer & setCRC(const uint16_t crc)
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)
void setDAQRegister(const uint32_t daqRegister) override
static const uint16_t FEUNITS_PER_FED
FEDBufferState qdrMemoryState() const
void setQDRMemoryFullFlag(const bool bitSet)
bool feEnabled(const uint8_t internalFEUnitNum) 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
void print(std::ostream &os) const override
void printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream &os) const
uint8_t packetCode(bool legacy=false, const uint8_t internalFEDChannelNum=0) const
Definition: value.py:1
void setL1ABXFIFOPartialFullFlag(const bool bitSet)
FEDBufferState l1aBxFIFOState() const
void setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address) override
void set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister) override
FEDDAQEventType fedDAQEventTypeFromString(const std::string &daqEventTypeString)
std::vector< FEDChannel > channels_
void setBufferFormatByte(const FEDBufferFormat newBufferFormat)
FEDBufferState getBufferState(const uint8_t bufferPosition) const
FEDDAQTrailer & setBadSourceIDBit(const bool bitSet)
const uint8_t * data() const override
void printHex(const void *pointer, const size_t length, std::ostream &os)
void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) override
static const uint16_t FEDCH_PER_FEUNIT
void setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister) override
FEDBackendStatusRegister & setTrackerHeaderMonitorDataReadyFlag(const bool bitSet)
FEDDAQHeader & setEventType(const FEDDAQEventType evtType)
FEDDAQHeader & setL1ID(const uint32_t l1ID)
bool checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const override
unsigned short compute_crc_8bit(unsigned short crc, unsigned char data)
Definition: CRC16.h:79
void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) override
FEDBackendStatusRegister & setSLinkFullFlag(const bool bitSet)
FEDDAQHeader & setSourceID(const uint16_t sourceID)
void setBufferSate(const uint8_t bufferPosition, const FEDBufferState state)
void init(const uint8_t *fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
TrackerSpecialHeader specialHeader_
FEDChannelStatus getChannelStatus(const uint8_t internalFEDChannelNum) const
virtual void print(std::ostream &os) const
void print(std::ostream &os) const override
static const uint16_t FEDCH_PER_FED
TrackerSpecialHeader & setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow)
virtual bool channelGood(const uint8_t internalFEDChannelNum) const
FEDFullDebugHeader * clone() const override
FEDAPVErrorHeader * clone() const override
FEDBackendStatusRegister & setFEEventLengthFIFOState(const FEDBufferState state)
void printHexWord(const uint8_t *pointer, const size_t lengthInBytes, std::ostream &os)
static const uint16_t FED_ID_MAX
FEDDAQHeader & setBXID(const uint16_t bxID)
static const uint8_t BUFFER_FORMAT_CODE_OLD
void setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value)
FEDStatusRegister & setQDRMemoryBufferState(const FEDBufferState state)
FEDDAQEventType eventType() const
FEDBackendStatusRegister & setInternalFreezeFlag(const bool bitSet)
void setL1ABXFIFOEmptyFlag(const bool bitSet)
FEDBackendStatusRegister & setBackpressureFlag(const bool bitSet)
TrackerSpecialHeader & setReadoutMode(const FEDReadoutMode readoutMode)
bool feOverflow(const uint8_t internalFEUnitNum) const
void setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status) override
FEDStatusRegister fedStatusRegister() const
void setQDRMemoryPartialFullFlag(const bool bitSet)
FEDBackendStatusRegister & setSLinkDownFlag(const bool bitSet)
FEDBufferFormat bufferFormat() const
void setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length) override