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