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_LITE8") ||
399  (readoutModeString == "ZERO_SUPPRESSED_LITE8") ||
400  (readoutModeString == "Zero suppressed lite8") ){
402  }
403  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8_TOPBOT") ||
404  (readoutModeString == "ZERO_SUPPRESSED_LITE8_TOPBOT") ||
405  (readoutModeString == "Zero suppressed lite8 TopBot") ){
407  }
408  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE8_BOTBOT") ||
409  (readoutModeString == "ZERO_SUPPRESSED_LITE8_BOTBOT") ||
410  (readoutModeString == "Zero suppressed lite8 BotBot") ){
412  }
413  if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE10") ||
414  (readoutModeString == "ZERO_SUPPRESSED_LITE10") ||
415  (readoutModeString == "Zero suppressed lite10") ) {
417  }
418  if ( (readoutModeString == "READOUT_MODE_PREMIX_RAW") ||
419  (readoutModeString == "PREMIX_RAW") ||
420  (readoutModeString == "PreMix Raw") ) {
422  }
423  if ( (readoutModeString == "READOUT_MODE_SPY") ||
424  (readoutModeString == "SPY") ||
425  (readoutModeString == "Spy channel") ) {
426  return READOUT_MODE_SPY;
427  }
428  //if it was none of the above then return invalid
429  return READOUT_MODE_INVALID;
430  }
432  {
433  if ( mode == READOUT_MODE_ZERO_SUPPRESSED ) {
434  if ( packetCode == "ZERO_SUPPRESSED" || packetCode == "Zero suppressed" ) {
436  } else if ( packetCode == "ZERO_SUPPRESSED10" || packetCode == "Zero suppressed 10" ) {
438  } else if ( packetCode == "ZERO_SUPPRESSED8_BOTBOT" || packetCode == "Zero suppressed 8 BOTBOT" ) {
440  } else if ( packetCode == "ZERO_SUPPRESSED8_TOPBOT" || packetCode == "Zero suppressed 8 TOPBOT" ) {
442  } else {
443  throw cms::Exception("FEDBuffer") << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode ZERO_SUPPRESSED";
444 
445  }
446  } else if ( mode == READOUT_MODE_VIRGIN_RAW ) {
447  if ( packetCode == "VIRGIN_RAW" || packetCode == "Virgin raw" ) {
448  return PACKET_CODE_VIRGIN_RAW;
449  } else if ( packetCode == "VIRGIN_RAW10" || packetCode == "Virgin raw 10" ) {
451  } else if ( packetCode == "VIRGIN_RAW8_BOTBOT" || packetCode == "Virgin raw 8 BOTBOT" ) {
453  } else if ( packetCode == "VIRGIN_RAW8_TOPBOT" || packetCode == "Virgin raw 8 TOPBOT" ) {
455  } else {
456  throw cms::Exception("FEDBuffer") << "'" << packetCode << "' cannot be converted into a valid packet code for FEDReadoutMode VIRGIN_RAW";
457  }
458  } else if ( mode == READOUT_MODE_PROC_RAW ) {
459  if ( packetCode == "PROC_RAW" || packetCode == "Processed raw" ) {
460  return PACKET_CODE_PROC_RAW;
461  } else if ( packetCode == "PROC_RAW10" || packetCode == "Processed raw 10" ) {
462  return PACKET_CODE_PROC_RAW10;
463  } else if ( packetCode == "PROC_RAW8_BOTBOT" || packetCode == "Processed raw 8 BOTBOT" ) {
465  } else if ( packetCode == "PROC_RAW8_TOPBOT" || packetCode == "Processed raw 8 TOPBOT" ) {
467  } else {
468  throw cms::Exception("FEDBuffer") << "'" << 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"
472  || packetCode.empty() ) { // default
473  return PACKET_CODE_SCOPE;
474  } else {
475  throw cms::Exception("FEDBuffer") << "'" << 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, processed raw and spy data. FEDReadoutMode=" << mode << " and packetCode='" << packetCode << "'";
480  }
481  return 0;
482  }
483  }
484 
486  {
487  if ( (daqEventTypeString == "PHYSICS") ||
488  (daqEventTypeString == "DAQ_EVENT_TYPE_PHYSICS") ||
489  (daqEventTypeString == "Physics trigger") ) {
490  return DAQ_EVENT_TYPE_PHYSICS;
491  }
492  if ( (daqEventTypeString == "CALIBRATION") ||
493  (daqEventTypeString == "DAQ_EVENT_TYPE_CALIBRATION") ||
494  (daqEventTypeString == "Calibration trigger") ) {
496  }
497  if ( (daqEventTypeString == "TEST") ||
498  (daqEventTypeString == "DAQ_EVENT_TYPE_TEST") ||
499  (daqEventTypeString == "Test trigger") ) {
500  return DAQ_EVENT_TYPE_TEST;
501  }
502  if ( (daqEventTypeString == "TECHNICAL") ||
503  (daqEventTypeString == "DAQ_EVENT_TYPE_TECHNICAL") ||
504  (daqEventTypeString == "Technical trigger") ) {
506  }
507  if ( (daqEventTypeString == "SIMULATED") ||
508  (daqEventTypeString == "DAQ_EVENT_TYPE_SIMULATED") ||
509  (daqEventTypeString == "Simulated trigger") ) {
511  }
512  if ( (daqEventTypeString == "TRACED") ||
513  (daqEventTypeString == "DAQ_EVENT_TYPE_TRACED") ||
514  (daqEventTypeString == "Traced event") ) {
515  return DAQ_EVENT_TYPE_TRACED;
516  }
517  if ( (daqEventTypeString == "ERROR") ||
518  (daqEventTypeString == "DAQ_EVENT_TYPE_ERROR") ||
519  (daqEventTypeString == "Error") ) {
520  return DAQ_EVENT_TYPE_ERROR;
521  }
522  //if it was none of the above then return invalid
523  return DAQ_EVENT_TYPE_INVALID;
524  }
525 
526 
527 
528 
529  void FEDStatusRegister::printFlags(std::ostream& os) const
530  {
531  if (slinkFullFlag()) os << "SLINK_FULL ";
532  if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
533  if (qdrMemoryFullFlag()) os << "QDR_FULL ";
534  if (qdrMemoryPartialFullFlag()) os << "QDR_PARTIAL_FULL ";
535  if (qdrMemoryEmptyFlag()) os << "QDR_EMPTY ";
536  if (l1aBxFIFOFullFlag()) os << "L1A_FULL ";
537  if (l1aBxFIFOPartialFullFlag()) os << "L1A_PARTIAL_FULL ";
538  if (l1aBxFIFOEmptyFlag()) os << "L1A_EMPTY ";
539  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
540  if (feDataMissingFlag(iFE)) os << "FEUNIT" << uint16_t(iFE) << "MISSING ";
541  }
542  }
543 
545  {
546  uint8_t result(0x00);
547  if (qdrMemoryFullFlag()) result |= BUFFER_STATE_FULL;
549  if (qdrMemoryEmptyFlag()) result |= BUFFER_STATE_EMPTY;
550  return FEDBufferState(result);
551  }
552 
554  {
555  uint8_t result(0x00);
556  if (l1aBxFIFOFullFlag()) result |= BUFFER_STATE_FULL;
558  if (l1aBxFIFOEmptyFlag()) result |= BUFFER_STATE_EMPTY;
559  return FEDBufferState(result);
560  }
561 
562  void FEDStatusRegister::setBit(const uint8_t num, const bool bitSet)
563  {
564  const uint16_t mask = (0x0001 << num);
565  if (bitSet) data_ |= mask;
566  else data_ &= (~mask);
567  }
568 
570  {
571  switch (state) {
572  case BUFFER_STATE_FULL:
574  case BUFFER_STATE_EMPTY:
575  case BUFFER_STATE_UNSET:
576  break;
577  default:
578  std::ostringstream ss;
579  ss << "Invalid buffer state: ";
580  printHex(&state,1,ss);
581  throw cms::Exception("FEDBuffer") << ss.str();
582  }
586  return *this;
587  }
588 
590  {
591  switch (state) {
592  case BUFFER_STATE_FULL:
594  case BUFFER_STATE_EMPTY:
595  case BUFFER_STATE_UNSET:
596  break;
597  default:
598  std::ostringstream ss;
599  ss << "Invalid buffer state: ";
600  printHex(&state,1,ss);
601  throw cms::Exception("FEDBuffer") << ss.str();
602  }
606  return *this;
607  }
608 
609 
610 
611 
612  void FEDBackendStatusRegister::printFlags(std::ostream& os) const
613  {
614  if (internalFreezeFlag()) os << "INTERNAL_FREEZE ";
615  if (slinkDownFlag()) os << "SLINK_DOWN ";
616  if (slinkFullFlag()) os << "SLINK_FULL ";
617  if (backpressureFlag()) os << "BACKPRESSURE ";
618  if (ttcReadyFlag()) os << "TTC_READY ";
619  if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
620  printFlagsForBuffer(qdrMemoryState(),"QDR",os);
621  printFlagsForBuffer(frameAddressFIFOState(),"FRAME_ADDRESS",os);
622  printFlagsForBuffer(totalLengthFIFOState(),"TOTAL_LENGTH",os);
623  printFlagsForBuffer(trackerHeaderFIFOState(),"TRACKER_HEADER",os);
624  printFlagsForBuffer(l1aBxFIFOState(),"L1ABX",os);
625  printFlagsForBuffer(feEventLengthFIFOState(),"FE_LENGTH",os);
626  printFlagsForBuffer(feFPGABufferState(),"FE",os);
627  }
628 
629  void FEDBackendStatusRegister::printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream& os) const
630  {
631  if (bufferState&BUFFER_STATE_EMPTY) os << name << "_EMPTY ";
632  if (bufferState&BUFFER_STATE_PARTIAL_FULL) os << name << "_PARTIAL_FULL ";
633  if (bufferState&BUFFER_STATE_FULL) os << name << "_FULL ";
634  if (bufferState == BUFFER_STATE_UNSET) os << name << "_UNSET ";
635  }
636 
637  FEDBufferState FEDBackendStatusRegister::getBufferState(const uint8_t bufferPosition) const
638  {
639  uint8_t result = 0x00;
640  if (getBit(bufferPosition+STATE_OFFSET_EMPTY)) result |= BUFFER_STATE_EMPTY;
641  if (getBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL)) result |= BUFFER_STATE_PARTIAL_FULL;
642  if (getBit(bufferPosition+STATE_OFFSET_FULL)) result |= BUFFER_STATE_FULL;
643  return FEDBufferState(result);
644  }
645 
646  void FEDBackendStatusRegister::setBufferSate(const uint8_t bufferPosition, const FEDBufferState state)
647  {
648  switch (state) {
649  case BUFFER_STATE_FULL:
651  case BUFFER_STATE_EMPTY:
652  case BUFFER_STATE_UNSET:
653  break;
654  default:
655  std::ostringstream ss;
656  ss << "Invalid buffer state: ";
657  printHex(&state,1,ss);
658  throw cms::Exception("FEDBuffer") << ss.str();
659  }
660  setBit(bufferPosition+STATE_OFFSET_EMPTY, state&BUFFER_STATE_EMPTY);
661  setBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL, state&BUFFER_STATE_PARTIAL_FULL);
662  setBit(bufferPosition+STATE_OFFSET_FULL, state&BUFFER_STATE_FULL);
663  }
664 
665  void FEDBackendStatusRegister::setBit(const uint8_t num, const bool bitSet)
666  {
667  const uint32_t mask = (0x00000001 << num);
668  if (bitSet) data_ |= mask;
669  else data_ &= (~mask);
670  }
671 
673  const FEDBufferState frameAddressFIFOBufferState,
674  const FEDBufferState totalLengthFIFOBufferState,
675  const FEDBufferState trackerHeaderFIFOBufferState,
676  const FEDBufferState l1aBxFIFOBufferState,
677  const FEDBufferState feEventLengthFIFOBufferState,
678  const FEDBufferState feFPGABufferState,
679  const bool backpressure, const bool slinkFull,
680  const bool slinkDown, const bool internalFreeze,
681  const bool trackerHeaderMonitorDataReady, const bool ttcReady)
682  : data_(0)
683  {
684  setInternalFreezeFlag(internalFreeze);
685  setSLinkDownFlag(slinkDown);
686  setSLinkFullFlag(slinkFull);
687  setBackpressureFlag(backpressure);
688  setTTCReadyFlag(ttcReady);
689  setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReady);
690  setQDRMemoryState(qdrMemoryBufferState);
691  setFrameAddressFIFOState(frameAddressFIFOBufferState);
692  setTotalLengthFIFOState(totalLengthFIFOBufferState);
693  setTrackerHeaderFIFOState(trackerHeaderFIFOBufferState);
694  setL1ABXFIFOState(l1aBxFIFOBufferState);
695  setFEEventLengthFIFOState(feEventLengthFIFOBufferState);
696  setFEFPGABufferState(feFPGABufferState);
697  }
698 
699 
700 
701 
702  TrackerSpecialHeader::TrackerSpecialHeader(const uint8_t* headerPointer)
703  {
704  //the buffer format byte is one of the valid values if we assume the buffer is not swapped
705  const bool validFormatByteWhenNotWordSwapped = ( (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_NEW) ||
706  (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_OLD) );
707  //the buffer format byte is the old value if we assume the buffer is swapped
708  const bool validFormatByteWhenWordSwapped = (headerPointer[BUFFERFORMAT^4] == BUFFER_FORMAT_CODE_OLD);
709  //if the buffer format byte is valid if the buffer is not swapped or it is never valid
710  if (validFormatByteWhenNotWordSwapped || (!validFormatByteWhenNotWordSwapped && !validFormatByteWhenWordSwapped) ) {
711  memcpy(specialHeader_,headerPointer,8);
712  wordSwapped_ = false;
713  } else {
714  memcpy(specialHeader_,headerPointer+4,4);
715  memcpy(specialHeader_+4,headerPointer,4);
716  wordSwapped_ = true;
717  }
718  }
719 
721  {
722  if (bufferFormatByte() == BUFFER_FORMAT_CODE_NEW) return BUFFER_FORMAT_NEW;
723  else if (bufferFormatByte() == BUFFER_FORMAT_CODE_OLD) {
724  if (wordSwapped_) return BUFFER_FORMAT_OLD_VME;
725  else return BUFFER_FORMAT_OLD_SLINK;
726  }
727  else return BUFFER_FORMAT_INVALID;
728  }
729 
731  {
732  if ( (headerTypeNibble() == HEADER_TYPE_FULL_DEBUG) ||
733  (headerTypeNibble() == HEADER_TYPE_APV_ERROR) ||
734  (headerTypeNibble() == HEADER_TYPE_NONE) )
735  return FEDHeaderType(headerTypeNibble());
736  else return HEADER_TYPE_INVALID;
737  }
738 
740  {
741  const uint8_t eventTypeNibble = trackerEventTypeNibble();
742  const uint8_t mode = (eventTypeNibble & 0xF);
743  switch(mode) {
752  return FEDLegacyReadoutMode(mode);
753  default:
755  }
756  }
757 
759  {
760  const uint8_t eventTypeNibble = trackerEventTypeNibble();
761  //if it is scope mode then return as is (it cannot be fake data)
762  if (eventTypeNibble == READOUT_MODE_SCOPE) return FEDReadoutMode(eventTypeNibble);
763  //if it is premix then return as is: stripping last bit would make it spy data !
764  if (eventTypeNibble == READOUT_MODE_PREMIX_RAW) return FEDReadoutMode(eventTypeNibble);
765  //if not then ignore the last bit which indicates if it is real or fake
766  else {
767  const uint8_t mode = (eventTypeNibble & 0xF);
768  switch(mode) {
774  //case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
782  case READOUT_MODE_SPY:
783  return FEDReadoutMode(mode);
784  default:
785  return READOUT_MODE_INVALID;
786  }
787  }
788  }
789 
791  {
792  //check if order in buffer is different
793  if ( ( (bufferFormat()==BUFFER_FORMAT_OLD_VME) && (newBufferFormat!=BUFFER_FORMAT_OLD_VME) ) ||
794  ( (bufferFormat()!=BUFFER_FORMAT_OLD_VME) && (newBufferFormat==BUFFER_FORMAT_OLD_VME) ) ) {
795  wordSwapped_ = !wordSwapped_;
796  }
797  //set appropriate code
798  setBufferFormatByte(newBufferFormat);
799  return *this;
800  }
801 
803  {
804  switch (newBufferFormat) {
807  specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_OLD;
808  break;
809  case BUFFER_FORMAT_NEW:
810  specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_NEW;
811  break;
812  default:
813  std::ostringstream ss;
814  ss << "Invalid buffer format: ";
815  printHex(&newBufferFormat,1,ss);
816  throw cms::Exception("FEDBuffer") << ss.str();
817  }
818  }
819 
821  {
822  switch(headerType) {
825  case HEADER_TYPE_NONE:
826  setHeaderTypeNibble(headerType);
827  return *this;
828  default:
829  std::ostringstream ss;
830  ss << "Invalid header type: ";
831  printHex(&headerType,1,ss);
832  throw cms::Exception("FEDBuffer") << ss.str();
833  }
834  }
835 
837  {
838  switch(readoutMode) {
839  case READOUT_MODE_SCOPE:
840  //scope mode is always real
841  setReadoutModeBits(readoutMode);
844  case READOUT_MODE_SPY:
855  setReadoutModeBits(readoutMode);
856  break;
858  //special mode for simulation
859  setReadoutModeBits(readoutMode);
860  break;
861  default:
862  std::ostringstream ss;
863  ss << "Invalid readout mode: ";
864  printHex(&readoutMode,1,ss);
865  throw cms::Exception("FEDBuffer") << ss.str();
866  }
867  return *this;
868  }
869 
871  {
872  const uint8_t mask = 0x1 << internalFEUnitNum;
873  const uint8_t result = ( (apvAddressErrorRegister() & (~mask)) | (error?mask:0x00) );
874  setAPVEAddressErrorRegister(result);
875  return *this;
876  }
877 
878  TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
879  {
880  const uint8_t mask = 0x1 << internalFEUnitNum;
881  const uint8_t result = ( (feEnableRegister() & (~mask)) | (enabled?mask:0x00) );
882  setFEEnableRegister(result);
883  return *this;
884  }
885 
886  TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow)
887  {
888  const uint8_t mask = 0x1 << internalFEUnitNum;
889  const uint8_t result = ( (feOverflowRegister() & (~mask)) | (overflow?mask:0x00) );
890  setFEEnableRegister(result);
891  return *this;
892  }
893 
895  const FEDHeaderType headerType,
896  const uint8_t address, const uint8_t addressErrorRegister,
897  const uint8_t feEnableRegister, const uint8_t feOverflowRegister,
898  const FEDStatusRegister fedStatusRegister)
899  {
900  memset(specialHeader_,0x00,8);
901  //determine if order is swapped in real buffer
902  wordSwapped_ = (bufferFormat == BUFFER_FORMAT_OLD_VME);
903  //set fields
904  setBufferFormatByte(bufferFormat);
905  setReadoutMode(readoutMode);
906  setHeaderType(headerType);
907  setAPVEAddress(address);
908  setAPVEAddressErrorRegister(addressErrorRegister);
909  setFEEnableRegister(feEnableRegister);
910  setFEOverflowRegister(feOverflowRegister);
911  setFEDStatusRegister(fedStatusRegister);
912  }
913 
914 
915 
916 
918  {
919  switch(eventTypeNibble()) {
922  case DAQ_EVENT_TYPE_TEST:
927  return FEDDAQEventType(eventTypeNibble());
928  default:
929  return DAQ_EVENT_TYPE_INVALID;
930  }
931  }
932 
934  {
935  header_[7] = ((header_[7] & 0xF0) | evtType);
936  return *this;
937  }
938 
939  FEDDAQHeader& FEDDAQHeader::setL1ID(const uint32_t l1ID)
940  {
941  header_[4] = (l1ID & 0x000000FF);
942  header_[5] = ( (l1ID & 0x0000FF00) >> 8);
943  header_[6] = ( (l1ID & 0x00FF0000) >> 16);
944  return *this;
945  }
946 
947  FEDDAQHeader& FEDDAQHeader::setBXID(const uint16_t bxID)
948  {
949  header_[3] = ( (bxID & 0x0FF0) >> 4);
950  header_[2] = ( (header_[2] & 0x0F) | ( (bxID & 0x000F) << 4) );
951  return *this;
952  }
953 
954  FEDDAQHeader& FEDDAQHeader::setSourceID(const uint16_t sourceID)
955  {
956  header_[2] = ( (header_[2] & 0xF0) | ( (sourceID & 0x0F00) >> 8) );
957  header_[1] = (sourceID & 0x00FF);
958  return *this;
959  }
960 
961  FEDDAQHeader::FEDDAQHeader(const uint32_t l1ID, const uint16_t bxID, const uint16_t sourceID, const FEDDAQEventType evtType)
962  {
963  //clear everything (FOV,H,x,$ all set to 0)
964  memset(header_,0x0,8);
965  //set the BoE nibble to indicate this is the last fragment
966  header_[7] = 0x50;
967  //set variable fields vith values supplied
968  setEventType(evtType);
969  setL1ID(l1ID);
970  setBXID(bxID);
971  setSourceID(sourceID);
972  }
973 
974 
975 
976 
978  {
979  switch(ttsNibble()) {
980  case TTS_DISCONNECTED0:
981  case TTS_WARN_OVERFLOW:
982  case TTS_OUT_OF_SYNC:
983  case TTS_BUSY:
984  case TTS_READY:
985  case TTS_ERROR:
986  case TTS_DISCONNECTED1:
987  return FEDTTSBits(ttsNibble());
988  default:
989  return TTS_INVALID;
990  }
991  }
992 
993  FEDDAQTrailer::FEDDAQTrailer(const uint32_t eventLengthIn64BitWords, const uint16_t crc, const FEDTTSBits ttsBits,
994  const bool slinkTransmissionError, const bool badFEDID, const bool slinkCRCError,
995  const uint8_t eventStatusNibble)
996  {
997  //clear everything (T,x,$ all set to 0)
998  memset(trailer_,0x0,8);
999  //set the EoE nibble to indicate this is the last fragment
1000  trailer_[7] = 0xA0;
1001  //set variable fields vith values supplied
1002  setEventLengthIn64BitWords(eventLengthIn64BitWords);
1003  setEventStatusNibble(eventStatusNibble);
1004  setTTSBits(ttsBits);
1005  setCRC(crc);
1006  setSLinkTransmissionErrorBit(slinkTransmissionError);
1007  setBadSourceIDBit(badFEDID);
1008  setSLinkCRCErrorBit(slinkCRCError);
1009  }
1010 
1011  FEDDAQTrailer& FEDDAQTrailer::setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
1012  {
1013  trailer_[4] = (eventLengthIn64BitWords & 0x000000FF);
1014  trailer_[5] = ( (eventLengthIn64BitWords & 0x0000FF00) >> 8);
1015  trailer_[6] = ( (eventLengthIn64BitWords & 0x00FF0000) >> 16);
1016  return *this;
1017  }
1018 
1020  {
1021  trailer_[2] = (crc & 0x00FF);
1022  trailer_[3] = ( (crc >> 8) & 0x00FF );
1023  return *this;
1024  }
1025 
1027  {
1028  if (bitSet) trailer_[1] |= 0x80;
1029  else trailer_[1] &= (~0x80);
1030  return *this;
1031  }
1032 
1034  {
1035  if (bitSet) trailer_[1] |= 0x40;
1036  else trailer_[1] &= (~0x40);
1037  return *this;
1038  }
1039 
1041  {
1042  if (bitSet) trailer_[0] |= 0x04;
1043  else trailer_[0] &= (~0x40);
1044  return *this;
1045  }
1046 
1047  FEDDAQTrailer& FEDDAQTrailer::setEventStatusNibble(const uint8_t eventStatusNibble)
1048  {
1049  trailer_[1] = ( (trailer_[1] & 0xF0) | (eventStatusNibble & 0x0F) );
1050  return *this;
1051  }
1052 
1054  {
1055  trailer_[0] = ( (trailer_[0] & 0x0F) | (ttsBits & 0xF0) );
1056  return *this;
1057  }
1058 
1059 
1060 
1061 
1063  {
1064  }
1065 
1067  {
1068  return APV_ERROR_HEADER_SIZE_IN_BYTES;
1069  }
1070 
1071  void FEDAPVErrorHeader::print(std::ostream& os) const
1072  {
1073  printHex(header_,APV_ERROR_HEADER_SIZE_IN_BYTES,os);
1074  }
1075 
1077  {
1078  return new FEDAPVErrorHeader(*this);
1079  }
1080 
1081  bool FEDAPVErrorHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1082  {
1083  //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1084  const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FEUNIT)*24 + (FEDCH_PER_FEUNIT-1-(internalFEDChannelNum%FEDCH_PER_FEUNIT))*2 + apvNum;
1085  //bit high means no error
1086  return (header_[bitNumber/8] & (0x01<<(bitNumber%8)) );
1087  }
1088 
1090  {
1091  return (checkStatusBits(internalFEDChannelNum,0) && checkStatusBits(internalFEDChannelNum,1));
1092  }
1093 
1094  const uint8_t* FEDAPVErrorHeader::data() const
1095  {
1096  return header_;
1097  }
1098 
1099  FEDAPVErrorHeader::FEDAPVErrorHeader(const std::vector<bool>& apvsGood)
1100  {
1101  memset(header_,0x00,APV_ERROR_HEADER_SIZE_IN_BYTES);
1102  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1103  setAPVStatusBit(iCh,0,apvsGood[iCh*2]);
1104  setAPVStatusBit(iCh,1,apvsGood[iCh*2+1]);
1105  }
1106  }
1107 
1108  FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood)
1109  {
1110  //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
1111  const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FED)*24 + (FEDCH_PER_FED-1-(internalFEDChannelNum%FEDCH_PER_FED))*2+apvNum;
1112  const uint8_t byteNumber = bitNumber/8;
1113  const uint8_t bitInByte = bitNumber%8;
1114  const uint8_t mask = (0x01 << bitInByte);
1115  header_[byteNumber] = ( (header_[byteNumber] & (~mask)) | (apvGood?mask:0x00) );
1116  return *this;
1117  }
1118 
1120  {
1121  //if channel is unlocked then set both APV bits bad
1122  if ( (!(status & CHANNEL_STATUS_LOCKED)) || (!(status & CHANNEL_STATUS_IN_SYNC)) ) {
1123  setAPVStatusBit(internalFEDChannelNum,0,false);
1124  setAPVStatusBit(internalFEDChannelNum,1,false);
1125  return;
1126  } else {
1127  if ( (status & CHANNEL_STATUS_APV0_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV0_NO_ERROR_BIT) ) {
1128  setAPVStatusBit(internalFEDChannelNum,0,true);
1129  } else {
1130  setAPVStatusBit(internalFEDChannelNum,0,false);
1131  }
1132  if ( (status & CHANNEL_STATUS_APV1_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV1_NO_ERROR_BIT) ) {
1133  setAPVStatusBit(internalFEDChannelNum,1,true);
1134  } else {
1135  setAPVStatusBit(internalFEDChannelNum,1,false);
1136  }
1137  }
1138  }
1139 
1140  //These methods do nothing as the values in question are in present in the APV Error header.
1141  //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.
1142  void FEDAPVErrorHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
1143  {
1144  return;
1145  }
1147  {
1148  return;
1149  }
1150  void FEDAPVErrorHeader::setDAQRegister(const uint32_t daqRegister)
1151  {
1152  return;
1153  }
1154  void FEDAPVErrorHeader::setDAQRegister2(const uint32_t daqRegister2)
1155  {
1156  return;
1157  }
1158  void FEDAPVErrorHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister)
1159  {
1160  return;
1161  }
1162  void FEDAPVErrorHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
1163  {
1164  return;
1165  }
1166 
1167 
1169  {
1170  }
1171 
1173  {
1174  return FULL_DEBUG_HEADER_SIZE_IN_BYTES;
1175  }
1176 
1177  void FEDFullDebugHeader::print(std::ostream& os) const
1178  {
1179  printHex(header_,FULL_DEBUG_HEADER_SIZE_IN_BYTES,os);
1180  }
1181 
1183  {
1184  return new FEDFullDebugHeader(*this);
1185  }
1186 
1187  bool FEDFullDebugHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
1188  {
1189  return ( !unlockedFromBit(internalFEDChannelNum) &&
1190  !outOfSyncFromBit(internalFEDChannelNum) &&
1191  !apvError(internalFEDChannelNum,apvNum) &&
1192  !apvAddressError(internalFEDChannelNum,apvNum) );
1193  }
1194 
1196  {
1197  //return ( !unlockedFromBit(internalFEDChannelNum) &&
1198  // !outOfSyncFromBit(internalFEDChannelNum) &&
1199  // !apvErrorFromBit(internalFEDChannelNum,0) &&
1200  // !apvAddressErrorFromBit(internalFEDChannelNum,0) &&
1201  // !apvErrorFromBit(internalFEDChannelNum,1) &&
1202  // !apvAddressErrorFromBit(internalFEDChannelNum,1) );
1203  return (getChannelStatus(internalFEDChannelNum) == CHANNEL_STATUS_NO_PROBLEMS);
1204  }
1205 
1207  {
1208  const uint8_t* pFEWord = feWord(internalFEDChannelNum/FEDCH_PER_FEUNIT);
1209  const uint8_t feUnitChanNum = internalFEDChannelNum % FEDCH_PER_FEUNIT;
1210  const uint8_t startByteInFEWord = (FEDCH_PER_FEUNIT-1 - feUnitChanNum) * 6 / 8;
1211  switch ( (FEDCH_PER_FEUNIT-1-feUnitChanNum) % 4 ) {
1212  case 0:
1213  return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
1214  case 1:
1215  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
1216  case 2:
1217  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
1218  case 3:
1219  return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
1220  //stop compiler warning
1221  default:
1222  return FEDChannelStatus(0);
1223  }
1224  /*const uint8_t feUnitChanNum = internalFEDChannelNum / FEDCH_PER_FEUNIT;
1225  const uint8_t* pFEWord = feWord(feUnitChanNum);
1226  const uint8_t startByteInFEWord = feUnitChanNum * 3 / 4;
1227  //const uint8_t shift = ( 6 - ((feUnitChanNum-1)%4) );
1228  //const uint16_t mask = ( 0x003F << shift );
1229  //uint8_t result = ( (pFEWord[startByteInFEWord] & (mask&0x00FF)) >> shift );
1230  //result |= ( (pFEWord[startByteInFEWord+1] & (mask>>8)) << (8-shift) );
1231  switch (feUnitChanNum % 4) {
1232  case 0:
1233  return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
1234  case 1:
1235  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
1236  case 2:
1237  return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
1238  case 3:
1239  return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
1240  //stop compiler warning
1241  default:
1242  return FEDChannelStatus(0);
1243  }*/
1244  }
1245 
1246  const uint8_t* FEDFullDebugHeader::data() const
1247  {
1248  return header_;
1249  }
1250 
1251  FEDFullDebugHeader::FEDFullDebugHeader(const std::vector<uint16_t>& feUnitLengths, const std::vector<uint8_t>& feMajorityAddresses,
1252  const std::vector<FEDChannelStatus>& channelStatus, const FEDBackendStatusRegister beStatusRegister,
1253  const uint32_t daqRegister, const uint32_t daqRegister2)
1254  {
1255  memset(header_,0x00,FULL_DEBUG_HEADER_SIZE_IN_BYTES);
1256  setBEStatusRegister(beStatusRegister);
1257  setDAQRegister(daqRegister);
1258  setDAQRegister2(daqRegister2);
1259  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1260  setFEUnitLength(iFE,feUnitLengths[iFE]);
1261  setFEUnitMajorityAddress(iFE,feMajorityAddresses[iFE]);
1262  }
1263  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
1264  setChannelStatus(iCh,channelStatus[iCh]);
1265  }
1266  }
1267 
1269  {
1270  setUnlocked(internalFEDChannelNum, !(status&CHANNEL_STATUS_LOCKED) );
1271  setOutOfSync(internalFEDChannelNum, !(status&CHANNEL_STATUS_IN_SYNC) );
1272  setAPVAddressError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_ADDRESS_GOOD) );
1273  setAPVAddressError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_ADDRESS_GOOD) );
1274  setAPVError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_NO_ERROR_BIT) );
1275  setAPVError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_NO_ERROR_BIT) );
1276  }
1277 
1278  void FEDFullDebugHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
1279  {
1280  feWord(internalFEUnitNum)[9] = address;
1281  }
1282 
1284  {
1285  set32BitWordAt(feWord(0)+10,beStatusRegister);
1286  }
1287 
1288  void FEDFullDebugHeader::setDAQRegister(const uint32_t daqRegister)
1289  {
1290  set32BitWordAt(feWord(7)+10,daqRegister);
1291  }
1292 
1293  void FEDFullDebugHeader::setDAQRegister2(const uint32_t daqRegister2)
1294  {
1295  set32BitWordAt(feWord(6)+10,daqRegister2);
1296  }
1297 
1298  //used by DigiToRaw to copy reserved registers in internalFEUnit buffers 1 through 5
1299  void FEDFullDebugHeader::set32BitReservedRegister(const uint8_t internalFEUnitNum, const uint32_t reservedRegister)
1300  {
1301  set32BitWordAt(feWord(internalFEUnitNum)+10,reservedRegister);
1302  }
1303 
1304  void FEDFullDebugHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
1305  {
1306  feWord(internalFEUnitNum)[15] = ( (length & 0xFF00) >> 8);
1307  feWord(internalFEUnitNum)[14] = (length & 0x00FF);
1308  }
1309 
1310  void FEDFullDebugHeader::setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value)
1311  {
1312  const uint8_t bitInFeWord = (FEDCH_PER_FEUNIT-1 - (internalFEDChannelNum%FEDCH_PER_FEUNIT)) * 6 + bit;
1313  uint8_t& byte = *(feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT)+(bitInFeWord/8));
1314  const uint8_t mask = (0x1 << bitInFeWord%8);
1315  byte = ( (byte & (~mask)) | (value?mask:0x0) );
1316  }
1317 
1319  {
1320  }
1321 
1322 
1323 
1324 
1325  FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
1326  : channels_(FEDCH_PER_FED,FEDChannel(nullptr,0,0)),
1327  originalBuffer_(fedBuffer),
1328  bufferSize_(fedBufferSize)
1329  {
1330  init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
1331  }
1332 
1333  FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat, const bool fillChannelVector)
1334  : originalBuffer_(fedBuffer),
1335  bufferSize_(fedBufferSize)
1336  {
1337  init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
1338  if (fillChannelVector) channels_.assign(FEDCH_PER_FED,FEDChannel(nullptr,0,0));
1339  }
1340 
1341  void FEDBufferBase::init(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
1342  {
1343  //min buffer length. DAQ header, DAQ trailer, tracker special header.
1344  static const size_t MIN_BUFFER_SIZE = 8+8+8;
1345  //check size is non zero and data pointer is not NULL
1346  if (!originalBuffer_) throw cms::Exception("FEDBuffer") << "Buffer pointer is NULL.";
1347  if (bufferSize_ < MIN_BUFFER_SIZE) {
1348  std::ostringstream ss;
1349  ss << "Buffer is too small. "
1350  << "Min size is " << MIN_BUFFER_SIZE << ". "
1351  << "Buffer size is " << bufferSize_ << ". ";
1352  throw cms::Exception("FEDBuffer") << ss.str();
1353  }
1354 
1355  //construct tracker special header using second 64 bit word
1357 
1358  //check the buffer format
1360  if (bufferFormat == BUFFER_FORMAT_INVALID && !allowUnrecognizedFormat) {
1361  std::ostringstream ss;
1362  ss << "Buffer format not recognized. "
1363  << "Tracker special header: " << specialHeader_;
1364  throw cms::Exception("FEDBuffer") << ss.str();
1365  }
1366  //swap the buffer words so that the whole buffer is in slink ordering
1367  if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) ) {
1368  uint8_t* newBuffer = new uint8_t[bufferSize_];
1369  const uint32_t* originalU32 = reinterpret_cast<const uint32_t*>(originalBuffer_);
1370  const size_t sizeU32 = bufferSize_/4;
1371  uint32_t* newU32 = reinterpret_cast<uint32_t*>(newBuffer);
1372  if (bufferFormat == BUFFER_FORMAT_OLD_VME) {
1373  //swap whole buffer
1374  for (size_t i = 0; i < sizeU32; i+=2) {
1375  newU32[i] = originalU32[i+1];
1376  newU32[i+1] = originalU32[i];
1377  }
1378  }
1379  if (bufferFormat == BUFFER_FORMAT_NEW) {
1380  //copy DAQ header
1381  memcpy(newU32,originalU32,8);
1382  //copy DAQ trailer
1383  memcpy(newU32+sizeU32-2,originalU32+sizeU32-2,8);
1384  //swap the payload
1385  for (size_t i = 2; i < sizeU32-2; i+=2) {
1386  newU32[i] = originalU32[i+1];
1387  newU32[i+1] = originalU32[i];
1388  }
1389  }
1390  orderedBuffer_ = newBuffer;
1391  } //if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) )
1392  else {
1394  }
1395 
1396  //construct header object at begining of buffer
1398  //construct trailer object using last 64 bit word of buffer
1400  }
1401 
1403  {
1404  //if the buffer was coppied and swapped then delete the copy
1406  }
1407 
1408  void FEDBufferBase::print(std::ostream& os) const
1409  {
1410  os << "buffer format: " << bufferFormat() << std::endl;
1411  os << "Buffer size: " << bufferSize() << " bytes" << std::endl;
1412  os << "Event length from DAQ trailer: " << daqEventLengthInBytes() << " bytes" << std::endl;
1413  os << "Source ID: " << daqSourceID() << std::endl;
1414  os << "Header type: " << headerType() << std::endl;
1415  os << "Readout mode: " << readoutMode() << std::endl;
1416  os << "DAQ event type: " << daqEventType() << std::endl;
1417  os << "TTS state: " << daqTTSState() << std::endl;
1418  os << "L1 ID: " << daqLvl1ID() << std::endl;
1419  os << "BX ID: " << daqBXID() << std::endl;
1420  os << "FED status register flags: "; fedStatusRegister().printFlags(os); os << std::endl;
1421  os << "APVe Address: " << uint16_t(apveAddress()) << std::endl;
1422  os << "Enabled FE units: " << uint16_t(nFEUnitsEnabled()) << std::endl;
1423  }
1424 
1426  {
1427  uint8_t result = 0;
1428  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1429  if (feEnabled(iFE)) result++;
1430  }
1431  return result;
1432  }
1433 
1435  {
1436  return ( (daqSourceID() >= FED_ID_MIN) &&
1437  (daqSourceID() <= FED_ID_MAX) );
1438  }
1439 
1441  {
1442  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1443  if (!feEnabled(iFE)) continue;
1444  if (majorityAddressErrorForFEUnit(iFE)) return false;
1445  }
1446  return true;
1447  }
1448 
1450  {
1451  const uint8_t feUnit = internalFEDChannelNum/FEDCH_PER_FEUNIT;
1452  return ( !majorityAddressErrorForFEUnit(feUnit) && feEnabled(feUnit) && !feOverflow(feUnit) );
1453  }
1454 
1456  {
1458  }
1459 
1461  {
1462  std::ostringstream summary;
1463  summary << "Check buffer type valid: " << ( checkBufferFormat() ? "passed" : "FAILED" ) << std::endl;
1464  summary << "Check header format valid: " << ( checkHeaderType() ? "passed" : "FAILED" ) << std::endl;
1465  summary << "Check readout mode valid: " << ( checkReadoutMode() ? "passed" : "FAILED" ) << std::endl;
1466  //summary << "Check APVe address valid: " << ( checkAPVEAddressValid() ? "passed" : "FAILED" ) << std::endl;
1467  summary << "Check FE unit majority addresses: " << ( checkMajorityAddresses() ? "passed" : "FAILED" ) << std::endl;
1468  if (!checkMajorityAddresses()) {
1469  summary << "FEs with majority address error: ";
1470  unsigned int badFEs = 0;
1471  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1472  if (!feEnabled(iFE)) continue;
1473  if (majorityAddressErrorForFEUnit(iFE)) {
1474  summary << uint16_t(iFE) << " ";
1475  badFEs++;
1476  }
1477  }
1478  summary << std::endl;
1479  summary << "Number of FE Units with bad addresses: " << badFEs << std::endl;
1480  }
1481  summary << "Check for FE unit buffer overflows: " << ( checkNoFEOverflows() ? "passed" : "FAILED" ) << std::endl;
1482  if (!checkNoFEOverflows()) {
1483  summary << "FEs which overflowed: ";
1484  unsigned int badFEs = 0;
1485  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
1486  if (feOverflow(iFE)) {
1487  summary << uint16_t(iFE) << " ";
1488  badFEs++;
1489  }
1490  }
1491  summary << std::endl;
1492  summary << "Number of FE Units which overflowed: " << badFEs << std::endl;
1493  }
1494  summary << "Check for S-Link CRC errors: " << ( checkNoSlinkCRCError() ? "passed" : "FAILED" ) << std::endl;
1495  summary << "Check for S-Link transmission error: " << ( checkNoSLinkTransmissionError() ? "passed" : "FAILED" ) << std::endl;
1496  summary << "Check CRC: " << ( checkCRC() ? "passed" : "FAILED" ) << std::endl;
1497  summary << "Check source ID is FED ID: " << ( checkSourceIDs() ? "passed" : "FAILED" ) << std::endl;
1498  summary << "Check for unexpected source ID at FRL: " << ( checkNoUnexpectedSourceID() ? "passed" : "FAILED" ) << std::endl;
1499  summary << "Check there are no extra headers or trailers: " << ( checkNoExtraHeadersOrTrailers() ? "passed" : "FAILED" ) << std::endl;
1500  summary << "Check length from trailer: " << ( checkLengthFromTrailer() ? "passed" : "FAILED" ) << std::endl;
1501  return summary.str();
1502  }
1503 
1504 
1505 
1506 
1507  uint16_t FEDChannel::cmMedian(const uint8_t apvIndex) const
1508  {
1509  const auto pCode = packetCode();
1510  if ( ( pCode != PACKET_CODE_ZERO_SUPPRESSED ) && ( pCode != PACKET_CODE_ZERO_SUPPRESSED10 )
1512  {
1513  std::ostringstream ss;
1514  ss << "Request for CM median from channel with non-ZS packet code. "
1515  << "Packet code is " << uint16_t(packetCode()) << "."
1516  << std::endl;
1517  throw cms::Exception("FEDBuffer") << ss.str();
1518  }
1519  if (apvIndex > 1) {
1520  std::ostringstream ss;
1521  ss << "Channel APV index out of range when requesting CM median for APV. "
1522  << "Channel APV index is " << uint16_t(apvIndex) << "."
1523  << std::endl;
1524  throw cms::Exception("FEDBuffer") << ss.str();
1525  }
1526  uint16_t result = 0;
1527  //CM median is 10 bits with lowest order byte first. First APV CM median starts in 4th byte of channel data
1528  result |= data_[(offset_+3+2*apvIndex)^7];
1529  result |= ( ((data_[(offset_+4+2*apvIndex)^7]) << 8) & 0x300 );
1530  return result;
1531  }
1532 
1533 }
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
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)
#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)
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: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)
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