00001 #include <iomanip>
00002 #include <ostream>
00003 #include <sstream>
00004 #include <cstring>
00005 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
00006 #include "FWCore/Utilities/interface/CRC16.h"
00007
00008 namespace sistrip {
00009
00010 void printHexValue(const uint8_t value, std::ostream& os)
00011 {
00012 const std::ios_base::fmtflags originalFormatFlags = os.flags();
00013 os << std::hex << std::setfill('0') << std::setw(2);
00014 os << uint16_t(value);
00015 os.flags(originalFormatFlags);
00016 }
00017
00018 void printHexWord(const uint8_t* pointer, const size_t lengthInBytes, std::ostream& os)
00019 {
00020 size_t i = lengthInBytes-1;
00021 do{
00022 printHexValue(pointer[i],os);
00023 if (i != 0) os << " ";
00024 } while (i-- != 0);
00025 }
00026
00027 void printHex(const void* pointer, const size_t lengthInBytes, std::ostream& os)
00028 {
00029 const uint8_t* bytePointer = reinterpret_cast<const uint8_t*>(pointer);
00030
00031 if (lengthInBytes <= 8) {
00032 printHexWord(bytePointer,lengthInBytes,os);
00033 }
00034
00035 else {
00036
00037 os << "word\tbyte\t \t\tbyte" << std::endl;;
00038 const size_t words = lengthInBytes/8;
00039 const size_t extraBytes = lengthInBytes - 8*words;
00040
00041 for (size_t w = 0; w < words; w++) {
00042 const size_t startByte = w*8;
00043 os << w << '\t' << startByte+8 << '\t';
00044 printHexWord(bytePointer+startByte,8,os);
00045 os << "\t\t" << startByte << std::endl;
00046 }
00047
00048 if (extraBytes) {
00049 const size_t startByte = words*8;
00050 os << words << '\t' << startByte+8 << '\t';
00051
00052 size_t p = 8;
00053 while (p-- > extraBytes) {
00054 os << "00 ";
00055 }
00056 printHexWord(bytePointer+startByte,extraBytes,os);
00057 os << "\t\t" << startByte << std::endl;
00058 }
00059 os << std::endl;
00060 }
00061 }
00062
00063
00064 uint16_t calculateFEDBufferCRC(const uint8_t* buffer, const size_t lengthInBytes)
00065 {
00066 uint16_t crc = 0xFFFF;
00067 for (size_t i = 0; i < lengthInBytes-8; i++) {
00068 crc = evf::compute_crc_8bit(crc,buffer[i^7]);
00069 }
00070 for (size_t i=lengthInBytes-8; i<lengthInBytes; i++) {
00071 uint8_t byte;
00072
00073 if (i==lengthInBytes-4 || i==lengthInBytes-3)
00074 byte = 0x00;
00075 else
00076 byte = buffer[i^7];
00077 crc = evf::compute_crc_8bit(crc,byte);
00078 }
00079 return crc;
00080 }
00081
00082
00083 std::ostream& operator<<(std::ostream& os, const FEDBufferFormat& value)
00084 {
00085 switch (value) {
00086 case BUFFER_FORMAT_OLD_VME:
00087 os << "Old VME";
00088 break;
00089 case BUFFER_FORMAT_OLD_SLINK:
00090 os << "Old S-Link";
00091 break;
00092 case BUFFER_FORMAT_NEW:
00093 os << "New";
00094 break;
00095 case BUFFER_FORMAT_INVALID:
00096 os << "Invalid";
00097 break;
00098 default:
00099 os << "Unrecognized";
00100 os << " (";
00101 printHexValue(value,os);
00102 os << ")";
00103 break;
00104 }
00105 return os;
00106 }
00107
00108 std::ostream& operator<<(std::ostream& os, const FEDHeaderType& value)
00109 {
00110 switch (value) {
00111 case HEADER_TYPE_FULL_DEBUG:
00112 os << "Full debug";
00113 break;
00114 case HEADER_TYPE_APV_ERROR:
00115 os << "APV error";
00116 break;
00117 case HEADER_TYPE_NONE:
00118 os << "None";
00119 break;
00120 case HEADER_TYPE_INVALID:
00121 os << "Invalid";
00122 break;
00123 default:
00124 os << "Unrecognized";
00125 os << " (";
00126 printHexValue(value,os);
00127 os << ")";
00128 break;
00129 }
00130 return os;
00131 }
00132
00133 std::ostream& operator<<(std::ostream& os, const FEDReadoutMode& value)
00134 {
00135 switch (value) {
00136 case READOUT_MODE_SCOPE:
00137 os << "Scope mode";
00138 break;
00139 case READOUT_MODE_VIRGIN_RAW:
00140 os << "Virgin raw";
00141 break;
00142 case READOUT_MODE_PROC_RAW:
00143 os << "Processed raw";
00144 break;
00145 case READOUT_MODE_ZERO_SUPPRESSED:
00146 os << "Zero suppressed";
00147 break;
00148 case READOUT_MODE_ZERO_SUPPRESSED_LITE:
00149 os << "Zero suppressed lite";
00150 break;
00151 case READOUT_MODE_SPY:
00152 os << "Spy channel";
00153 break;
00154 case READOUT_MODE_INVALID:
00155 os << "Invalid";
00156 break;
00157 default:
00158 os << "Unrecognized";
00159 os << " (";
00160 printHexValue(value,os);
00161 os << ")";
00162 break;
00163 }
00164 return os;
00165 }
00166
00167 std::ostream& operator<<(std::ostream& os, const FEDDataType& value)
00168 {
00169 switch (value) {
00170 case DATA_TYPE_REAL:
00171 os << "Real data";
00172 break;
00173 case DATA_TYPE_FAKE:
00174 os << "Fake data";
00175 break;
00176 default:
00177 os << "Unrecognized";
00178 os << " (";
00179 printHexValue(value,os);
00180 os << ")";
00181 break;
00182 }
00183 return os;
00184 }
00185
00186 std::ostream& operator<<(std::ostream& os, const FEDDAQEventType& value)
00187 {
00188 switch (value) {
00189 case DAQ_EVENT_TYPE_PHYSICS:
00190 os << "Physics trigger";
00191 break;
00192 case DAQ_EVENT_TYPE_CALIBRATION:
00193 os << "Calibration trigger";
00194 break;
00195 case DAQ_EVENT_TYPE_TEST:
00196 os << "Test trigger";
00197 break;
00198 case DAQ_EVENT_TYPE_TECHNICAL:
00199 os << "Technical trigger";
00200 break;
00201 case DAQ_EVENT_TYPE_SIMULATED:
00202 os << "Simulated event";
00203 break;
00204 case DAQ_EVENT_TYPE_TRACED:
00205 os << "Traced event";
00206 break;
00207 case DAQ_EVENT_TYPE_ERROR:
00208 os << "Error";
00209 break;
00210 case DAQ_EVENT_TYPE_INVALID:
00211 os << "Unknown";
00212 break;
00213 default:
00214 os << "Unrecognized";
00215 os << " (";
00216 printHexValue(value,os);
00217 os << ")";
00218 break;
00219 }
00220 return os;
00221 }
00222
00223 std::ostream& operator<<(std::ostream& os, const FEDTTSBits& value)
00224 {
00225 switch (value) {
00226 case TTS_DISCONNECTED0:
00227 os << "Disconected 0";
00228 break;
00229 case TTS_WARN_OVERFLOW:
00230 os << "Warning overflow";
00231 break;
00232 case TTS_OUT_OF_SYNC:
00233 os << "Out of sync";
00234 break;
00235 case TTS_BUSY:
00236 os << "Busy";
00237 break;
00238 case TTS_READY:
00239 os << "Ready";
00240 break;
00241 case TTS_ERROR:
00242 os << "Error";
00243 break;
00244 case TTS_INVALID:
00245 os << "Invalid";
00246 break;
00247 case TTS_DISCONNECTED1:
00248 os << "Disconected 1";
00249 break;
00250 default:
00251 os << "Unrecognized";
00252 os << " (";
00253 printHexValue(value,os);
00254 os << ")";
00255 break;
00256 }
00257 return os;
00258 }
00259
00260 std::ostream& operator<<(std::ostream& os, const FEDBufferState& value)
00261 {
00262 switch (value) {
00263 case BUFFER_STATE_UNSET:
00264 os << "Unset";
00265 break;
00266 case BUFFER_STATE_EMPTY:
00267 os << "Empty";
00268 break;
00269 case BUFFER_STATE_PARTIAL_FULL:
00270 os << "Partial Full";
00271 break;
00272 case BUFFER_STATE_FULL:
00273 os << "Full";
00274 break;
00275 default:
00276 os << "Unrecognized";
00277 os << " (";
00278 printHexValue(value,os);
00279 os << ")";
00280 break;
00281 }
00282 return os;
00283 }
00284
00285 std::ostream& operator<<(std::ostream& os, const FEDChannelStatus& value)
00286 {
00287 if (!(value&CHANNEL_STATUS_LOCKED)) os << "Unlocked ";
00288 if (!(value&CHANNEL_STATUS_IN_SYNC)) os << "Out-of-sync ";
00289 if (!(value&CHANNEL_STATUS_APV1_ADDRESS_GOOD)) os << "APV 1 bad address ";
00290 if (!(value&CHANNEL_STATUS_APV1_NO_ERROR_BIT)) os << "APV 1 error ";
00291 if (!(value&CHANNEL_STATUS_APV0_ADDRESS_GOOD)) os << "APV 0 bad address ";
00292 if (!(value&CHANNEL_STATUS_APV0_NO_ERROR_BIT)) os << "APV 0 error ";
00293 if (value == CHANNEL_STATUS_NO_PROBLEMS) os << "No errors";
00294 return os;
00295 }
00296
00297 FEDBufferFormat fedBufferFormatFromString(const std::string& bufferFormatString)
00298 {
00299 if ( (bufferFormatString == "OLD_VME") ||
00300 (bufferFormatString == "BUFFER_FORMAT_OLD_VME") ||
00301 (bufferFormatString == "Old VME") ) {
00302 return BUFFER_FORMAT_OLD_VME;
00303 }
00304 if ( (bufferFormatString == "OLD_SLINK") ||
00305 (bufferFormatString == "BUFFER_FORMAT_OLD_SLINK") ||
00306 (bufferFormatString == "Old S-Link") ) {
00307 return BUFFER_FORMAT_OLD_SLINK;
00308 }
00309 if ( (bufferFormatString == "NEW") ||
00310 (bufferFormatString == "BUFFER_FORMAT_NEW") ||
00311 (bufferFormatString == "New") ) {
00312 return BUFFER_FORMAT_NEW;
00313 }
00314
00315 return BUFFER_FORMAT_INVALID;
00316 }
00317
00318 FEDHeaderType fedHeaderTypeFromString(const std::string& headerTypeString)
00319 {
00320 if ( (headerTypeString == "FULL_DEBUG") ||
00321 (headerTypeString == "HEADER_TYPE_FULL_DEBUG") ||
00322 (headerTypeString == "Full debug") ) {
00323 return HEADER_TYPE_FULL_DEBUG;
00324 }
00325 if ( (headerTypeString == "APV_ERROR") ||
00326 (headerTypeString == "HEADER_TYPE_APV_ERROR") ||
00327 (headerTypeString == "APV error") ) {
00328 return HEADER_TYPE_APV_ERROR;
00329 }
00330 if ( (headerTypeString == "None") ||
00331 (headerTypeString == "none") ) {
00332 return HEADER_TYPE_NONE;
00333 }
00334
00335 return HEADER_TYPE_INVALID;
00336 }
00337
00338 FEDReadoutMode fedReadoutModeFromString(const std::string& readoutModeString)
00339 {
00340 if ( (readoutModeString == "READOUT_MODE_SCOPE") ||
00341 (readoutModeString == "SCOPE") ||
00342 (readoutModeString == "SCOPE_MODE") ||
00343 (readoutModeString == "Scope mode") ) {
00344 return READOUT_MODE_SCOPE;
00345 }
00346 if ( (readoutModeString == "READOUT_MODE_VIRGIN_RAW") ||
00347 (readoutModeString == "VIRGIN_RAW") ||
00348 (readoutModeString == "Virgin raw") ) {
00349 return READOUT_MODE_VIRGIN_RAW;
00350 }
00351 if ( (readoutModeString == "READOUT_MODE_PROC_RAW") ||
00352 (readoutModeString == "PROC_RAW") ||
00353 (readoutModeString == "PROCESSED_RAW") ||
00354 (readoutModeString == "Processed raw") ) {
00355 return READOUT_MODE_PROC_RAW;
00356 }
00357 if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED") ||
00358 (readoutModeString == "ZERO_SUPPRESSED") ||
00359 (readoutModeString == "Zero suppressed") ) {
00360 return READOUT_MODE_ZERO_SUPPRESSED;
00361 }
00362 if ( (readoutModeString == "READOUT_MODE_ZERO_SUPPRESSED_LITE") ||
00363 (readoutModeString == "ZERO_SUPPRESSED_LITE") ||
00364 (readoutModeString == "Zero suppressed lite") ) {
00365 return READOUT_MODE_ZERO_SUPPRESSED_LITE;
00366 }
00367 if ( (readoutModeString == "READOUT_MODE_SPY") ||
00368 (readoutModeString == "SPY") ||
00369 (readoutModeString == "Spy channel") ) {
00370 return READOUT_MODE_SPY;
00371 }
00372
00373 return READOUT_MODE_INVALID;
00374 }
00375
00376 FEDDataType fedDataTypeFromString(const std::string& dataTypeString)
00377 {
00378 if ( (dataTypeString == "REAL") ||
00379 (dataTypeString == "DATA_TYPE_REAL") ||
00380 (dataTypeString == "Real data") ) {
00381 return DATA_TYPE_REAL;
00382 }
00383 if ( (dataTypeString == "FAKE") ||
00384 (dataTypeString == "DATA_TYPE_FAKE") ||
00385 (dataTypeString == "Fake data") ) {
00386 return DATA_TYPE_FAKE;
00387 }
00388
00389 std::ostringstream ss;
00390 ss << "Trying to convert to a FEDDataType from an invalid string: " << dataTypeString;
00391 throw cms::Exception("FEDDataType") << ss.str();
00392 }
00393
00394 FEDDAQEventType fedDAQEventTypeFromString(const std::string& daqEventTypeString)
00395 {
00396 if ( (daqEventTypeString == "PHYSICS") ||
00397 (daqEventTypeString == "DAQ_EVENT_TYPE_PHYSICS") ||
00398 (daqEventTypeString == "Physics trigger") ) {
00399 return DAQ_EVENT_TYPE_PHYSICS;
00400 }
00401 if ( (daqEventTypeString == "CALIBRATION") ||
00402 (daqEventTypeString == "DAQ_EVENT_TYPE_CALIBRATION") ||
00403 (daqEventTypeString == "Calibration trigger") ) {
00404 return DAQ_EVENT_TYPE_CALIBRATION;
00405 }
00406 if ( (daqEventTypeString == "TEST") ||
00407 (daqEventTypeString == "DAQ_EVENT_TYPE_TEST") ||
00408 (daqEventTypeString == "Test trigger") ) {
00409 return DAQ_EVENT_TYPE_TEST;
00410 }
00411 if ( (daqEventTypeString == "TECHNICAL") ||
00412 (daqEventTypeString == "DAQ_EVENT_TYPE_TECHNICAL") ||
00413 (daqEventTypeString == "Technical trigger") ) {
00414 return DAQ_EVENT_TYPE_TECHNICAL;
00415 }
00416 if ( (daqEventTypeString == "SIMULATED") ||
00417 (daqEventTypeString == "DAQ_EVENT_TYPE_SIMULATED") ||
00418 (daqEventTypeString == "Simulated trigger") ) {
00419 return DAQ_EVENT_TYPE_SIMULATED;
00420 }
00421 if ( (daqEventTypeString == "TRACED") ||
00422 (daqEventTypeString == "DAQ_EVENT_TYPE_TRACED") ||
00423 (daqEventTypeString == "Traced event") ) {
00424 return DAQ_EVENT_TYPE_TRACED;
00425 }
00426 if ( (daqEventTypeString == "ERROR") ||
00427 (daqEventTypeString == "DAQ_EVENT_TYPE_ERROR") ||
00428 (daqEventTypeString == "Error") ) {
00429 return DAQ_EVENT_TYPE_ERROR;
00430 }
00431
00432 return DAQ_EVENT_TYPE_INVALID;
00433 }
00434
00435
00436
00437
00438 void FEDStatusRegister::printFlags(std::ostream& os) const
00439 {
00440 if (slinkFullFlag()) os << "SLINK_FULL ";
00441 if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
00442 if (qdrMemoryFullFlag()) os << "QDR_FULL ";
00443 if (qdrMemoryPartialFullFlag()) os << "QDR_PARTIAL_FULL ";
00444 if (qdrMemoryEmptyFlag()) os << "QDR_EMPTY ";
00445 if (l1aBxFIFOFullFlag()) os << "L1A_FULL ";
00446 if (l1aBxFIFOPartialFullFlag()) os << "L1A_PARTIAL_FULL ";
00447 if (l1aBxFIFOEmptyFlag()) os << "L1A_EMPTY ";
00448 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
00449 if (feDataMissingFlag(iFE)) os << "FEUNIT" << uint16_t(iFE) << "MISSING ";
00450 }
00451 }
00452
00453 FEDBufferState FEDStatusRegister::qdrMemoryState() const
00454 {
00455 uint8_t result(0x00);
00456 if (qdrMemoryFullFlag()) result |= BUFFER_STATE_FULL;
00457 if (qdrMemoryPartialFullFlag()) result |= BUFFER_STATE_PARTIAL_FULL;
00458 if (qdrMemoryEmptyFlag()) result |= BUFFER_STATE_EMPTY;
00459 return FEDBufferState(result);
00460 }
00461
00462 FEDBufferState FEDStatusRegister::l1aBxFIFOState() const
00463 {
00464 uint8_t result(0x00);
00465 if (l1aBxFIFOFullFlag()) result |= BUFFER_STATE_FULL;
00466 if (l1aBxFIFOPartialFullFlag()) result |= BUFFER_STATE_PARTIAL_FULL;
00467 if (l1aBxFIFOEmptyFlag()) result |= BUFFER_STATE_EMPTY;
00468 return FEDBufferState(result);
00469 }
00470
00471 void FEDStatusRegister::setBit(const uint8_t num, const bool bitSet)
00472 {
00473 const uint16_t mask = (0x0001 << num);
00474 if (bitSet) data_ |= mask;
00475 else data_ &= (~mask);
00476 }
00477
00478 FEDStatusRegister& FEDStatusRegister::setQDRMemoryBufferState(const FEDBufferState state)
00479 {
00480 switch (state) {
00481 case BUFFER_STATE_FULL:
00482 case BUFFER_STATE_PARTIAL_FULL:
00483 case BUFFER_STATE_EMPTY:
00484 case BUFFER_STATE_UNSET:
00485 break;
00486 default:
00487 std::ostringstream ss;
00488 ss << "Invalid buffer state: ";
00489 printHex(&state,1,ss);
00490 throw cms::Exception("FEDBuffer") << ss.str();
00491 }
00492 setQDRMemoryFullFlag(state & BUFFER_STATE_FULL);
00493 setQDRMemoryPartialFullFlag(state & BUFFER_STATE_PARTIAL_FULL);
00494 setQDRMemoryEmptyFlag(state & BUFFER_STATE_EMPTY);
00495 return *this;
00496 }
00497
00498 FEDStatusRegister& FEDStatusRegister::setL1ABXFIFOBufferState(const FEDBufferState state)
00499 {
00500 switch (state) {
00501 case BUFFER_STATE_FULL:
00502 case BUFFER_STATE_PARTIAL_FULL:
00503 case BUFFER_STATE_EMPTY:
00504 case BUFFER_STATE_UNSET:
00505 break;
00506 default:
00507 std::ostringstream ss;
00508 ss << "Invalid buffer state: ";
00509 printHex(&state,1,ss);
00510 throw cms::Exception("FEDBuffer") << ss.str();
00511 }
00512 setL1ABXFIFOFullFlag(state & BUFFER_STATE_FULL);
00513 setL1ABXFIFOPartialFullFlag(state & BUFFER_STATE_PARTIAL_FULL);
00514 setL1ABXFIFOEmptyFlag(state & BUFFER_STATE_EMPTY);
00515 return *this;
00516 }
00517
00518
00519
00520
00521 void FEDBackendStatusRegister::printFlags(std::ostream& os) const
00522 {
00523 if (internalFreezeFlag()) os << "INTERNAL_FREEZE ";
00524 if (slinkDownFlag()) os << "SLINK_DOWN ";
00525 if (slinkFullFlag()) os << "SLINK_FULL ";
00526 if (backpressureFlag()) os << "BACKPRESSURE ";
00527 if (ttcReadyFlag()) os << "TTC_READY ";
00528 if (trackerHeaderMonitorDataReadyFlag()) os << "HEADER_MONITOR_READY ";
00529 printFlagsForBuffer(qdrMemoryState(),"QDR",os);
00530 printFlagsForBuffer(frameAddressFIFOState(),"FRAME_ADDRESS",os);
00531 printFlagsForBuffer(totalLengthFIFOState(),"TOTAL_LENGTH",os);
00532 printFlagsForBuffer(trackerHeaderFIFOState(),"TRACKER_HEADER",os);
00533 printFlagsForBuffer(l1aBxFIFOState(),"L1ABX",os);
00534 printFlagsForBuffer(feEventLengthFIFOState(),"FE_LENGTH",os);
00535 printFlagsForBuffer(feFPGABufferState(),"FE",os);
00536 }
00537
00538 void FEDBackendStatusRegister::printFlagsForBuffer(const FEDBufferState bufferState, const std::string name, std::ostream& os) const
00539 {
00540 if (bufferState&BUFFER_STATE_EMPTY) os << name << "_EMPTY ";
00541 if (bufferState&BUFFER_STATE_PARTIAL_FULL) os << name << "_PARTIAL_FULL ";
00542 if (bufferState&BUFFER_STATE_FULL) os << name << "_FULL ";
00543 if (bufferState == BUFFER_STATE_UNSET) os << name << "_UNSET ";
00544 }
00545
00546 FEDBufferState FEDBackendStatusRegister::getBufferState(const uint8_t bufferPosition) const
00547 {
00548 uint8_t result = 0x00;
00549 if (getBit(bufferPosition+STATE_OFFSET_EMPTY)) result |= BUFFER_STATE_EMPTY;
00550 if (getBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL)) result |= BUFFER_STATE_PARTIAL_FULL;
00551 if (getBit(bufferPosition+STATE_OFFSET_FULL)) result |= BUFFER_STATE_FULL;
00552 return FEDBufferState(result);
00553 }
00554
00555 void FEDBackendStatusRegister::setBufferSate(const uint8_t bufferPosition, const FEDBufferState state)
00556 {
00557 switch (state) {
00558 case BUFFER_STATE_FULL:
00559 case BUFFER_STATE_PARTIAL_FULL:
00560 case BUFFER_STATE_EMPTY:
00561 case BUFFER_STATE_UNSET:
00562 break;
00563 default:
00564 std::ostringstream ss;
00565 ss << "Invalid buffer state: ";
00566 printHex(&state,1,ss);
00567 throw cms::Exception("FEDBuffer") << ss.str();
00568 }
00569 setBit(bufferPosition+STATE_OFFSET_EMPTY, state&BUFFER_STATE_EMPTY);
00570 setBit(bufferPosition+STATE_OFFSET_PARTIAL_FULL, state&BUFFER_STATE_PARTIAL_FULL);
00571 setBit(bufferPosition+STATE_OFFSET_FULL, state&BUFFER_STATE_FULL);
00572 }
00573
00574 void FEDBackendStatusRegister::setBit(const uint8_t num, const bool bitSet)
00575 {
00576 const uint32_t mask = (0x00000001 << num);
00577 if (bitSet) data_ |= mask;
00578 else data_ &= (~mask);
00579 }
00580
00581 FEDBackendStatusRegister::FEDBackendStatusRegister(const FEDBufferState qdrMemoryBufferState,
00582 const FEDBufferState frameAddressFIFOBufferState,
00583 const FEDBufferState totalLengthFIFOBufferState,
00584 const FEDBufferState trackerHeaderFIFOBufferState,
00585 const FEDBufferState l1aBxFIFOBufferState,
00586 const FEDBufferState feEventLengthFIFOBufferState,
00587 const FEDBufferState feFPGABufferState,
00588 const bool backpressure, const bool slinkFull,
00589 const bool slinkDown, const bool internalFreeze,
00590 const bool trackerHeaderMonitorDataReady, const bool ttcReady)
00591 : data_(0)
00592 {
00593 setInternalFreezeFlag(internalFreeze);
00594 setSLinkDownFlag(slinkDown);
00595 setSLinkFullFlag(slinkFull);
00596 setBackpressureFlag(backpressure);
00597 setTTCReadyFlag(ttcReady);
00598 setTrackerHeaderMonitorDataReadyFlag(trackerHeaderMonitorDataReady);
00599 setQDRMemoryState(qdrMemoryBufferState);
00600 setFrameAddressFIFOState(frameAddressFIFOBufferState);
00601 setTotalLengthFIFOState(totalLengthFIFOBufferState);
00602 setTrackerHeaderFIFOState(trackerHeaderFIFOBufferState);
00603 setL1ABXFIFOState(l1aBxFIFOBufferState);
00604 setFEEventLengthFIFOState(feEventLengthFIFOBufferState);
00605 setFEFPGABufferState(feFPGABufferState);
00606 }
00607
00608
00609
00610
00611 TrackerSpecialHeader::TrackerSpecialHeader(const uint8_t* headerPointer)
00612 {
00613
00614 const bool validFormatByteWhenNotWordSwapped = ( (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_NEW) ||
00615 (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_OLD) );
00616
00617 const bool validFormatByteWhenWordSwapped = (headerPointer[BUFFERFORMAT^4] == BUFFER_FORMAT_CODE_OLD);
00618
00619 if (validFormatByteWhenNotWordSwapped || (!validFormatByteWhenNotWordSwapped && !validFormatByteWhenWordSwapped) ) {
00620 memcpy(specialHeader_,headerPointer,8);
00621 wordSwapped_ = false;
00622 } else {
00623 memcpy(specialHeader_,headerPointer+4,4);
00624 memcpy(specialHeader_+4,headerPointer,4);
00625 wordSwapped_ = true;
00626 }
00627 }
00628
00629 FEDBufferFormat TrackerSpecialHeader::bufferFormat() const
00630 {
00631 if (bufferFormatByte() == BUFFER_FORMAT_CODE_NEW) return BUFFER_FORMAT_NEW;
00632 else if (bufferFormatByte() == BUFFER_FORMAT_CODE_OLD) {
00633 if (wordSwapped_) return BUFFER_FORMAT_OLD_VME;
00634 else return BUFFER_FORMAT_OLD_SLINK;
00635 }
00636 else return BUFFER_FORMAT_INVALID;
00637 }
00638
00639 FEDHeaderType TrackerSpecialHeader::headerType() const
00640 {
00641 if ( (headerTypeNibble() == HEADER_TYPE_FULL_DEBUG) ||
00642 (headerTypeNibble() == HEADER_TYPE_APV_ERROR) ||
00643 (headerTypeNibble() == HEADER_TYPE_NONE) )
00644 return FEDHeaderType(headerTypeNibble());
00645 else return HEADER_TYPE_INVALID;
00646 }
00647
00648 FEDReadoutMode TrackerSpecialHeader::readoutMode() const
00649 {
00650 const uint8_t eventTypeNibble = trackerEventTypeNibble();
00651
00652 if (eventTypeNibble == READOUT_MODE_SCOPE) return FEDReadoutMode(eventTypeNibble);
00653
00654 else {
00655 const uint8_t mode = (eventTypeNibble & 0xE);
00656 switch(mode) {
00657 case READOUT_MODE_VIRGIN_RAW:
00658 case READOUT_MODE_PROC_RAW:
00659 case READOUT_MODE_ZERO_SUPPRESSED:
00660 case READOUT_MODE_ZERO_SUPPRESSED_LITE:
00661 case READOUT_MODE_SPY:
00662 return FEDReadoutMode(mode);
00663 default:
00664 return READOUT_MODE_INVALID;
00665 }
00666 }
00667 }
00668
00669 FEDDataType TrackerSpecialHeader::dataType() const
00670 {
00671 const uint8_t eventTypeNibble = trackerEventTypeNibble();
00672
00673 if (eventTypeNibble == READOUT_MODE_SCOPE) return DATA_TYPE_REAL;
00674
00675 else return FEDDataType(eventTypeNibble & 0x1);
00676 }
00677
00678 TrackerSpecialHeader& TrackerSpecialHeader::setBufferFormat(const FEDBufferFormat newBufferFormat)
00679 {
00680
00681 if ( ( (bufferFormat()==BUFFER_FORMAT_OLD_VME) && (newBufferFormat!=BUFFER_FORMAT_OLD_VME) ) ||
00682 ( (bufferFormat()!=BUFFER_FORMAT_OLD_VME) && (newBufferFormat==BUFFER_FORMAT_OLD_VME) ) ) {
00683 wordSwapped_ = !wordSwapped_;
00684 }
00685
00686 setBufferFormatByte(newBufferFormat);
00687 return *this;
00688 }
00689
00690 void TrackerSpecialHeader::setBufferFormatByte(const FEDBufferFormat newBufferFormat)
00691 {
00692 switch (newBufferFormat) {
00693 case BUFFER_FORMAT_OLD_VME:
00694 case BUFFER_FORMAT_OLD_SLINK:
00695 specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_OLD;
00696 break;
00697 case BUFFER_FORMAT_NEW:
00698 specialHeader_[BUFFERFORMAT] = BUFFER_FORMAT_CODE_NEW;
00699 break;
00700 default:
00701 std::ostringstream ss;
00702 ss << "Invalid buffer format: ";
00703 printHex(&newBufferFormat,1,ss);
00704 throw cms::Exception("FEDBuffer") << ss.str();
00705 }
00706 }
00707
00708 TrackerSpecialHeader& TrackerSpecialHeader::setHeaderType(const FEDHeaderType headerType)
00709 {
00710 switch(headerType) {
00711 case HEADER_TYPE_FULL_DEBUG:
00712 case HEADER_TYPE_APV_ERROR:
00713 case HEADER_TYPE_NONE:
00714 setHeaderTypeNibble(headerType);
00715 return *this;
00716 default:
00717 std::ostringstream ss;
00718 ss << "Invalid header type: ";
00719 printHex(&headerType,1,ss);
00720 throw cms::Exception("FEDBuffer") << ss.str();
00721 }
00722 }
00723
00724 TrackerSpecialHeader& TrackerSpecialHeader::setReadoutMode(const FEDReadoutMode readoutMode)
00725 {
00726 switch(readoutMode) {
00727 case READOUT_MODE_SCOPE:
00728
00729 setReadoutModeBits(readoutMode);
00730 setDataTypeBit(true);
00731 case READOUT_MODE_VIRGIN_RAW:
00732 case READOUT_MODE_PROC_RAW:
00733 case READOUT_MODE_ZERO_SUPPRESSED:
00734 case READOUT_MODE_ZERO_SUPPRESSED_LITE:
00735 case READOUT_MODE_SPY:
00736 setReadoutModeBits(readoutMode);
00737 break;
00738 default:
00739 std::ostringstream ss;
00740 ss << "Invalid readout mode: ";
00741 printHex(&readoutMode,1,ss);
00742 throw cms::Exception("FEDBuffer") << ss.str();
00743 }
00744 return *this;
00745 }
00746
00747 TrackerSpecialHeader& TrackerSpecialHeader::setDataType(const FEDDataType dataType)
00748 {
00749
00750 if (readoutMode() == READOUT_MODE_SCOPE) return *this;
00751 switch (dataType) {
00752 case DATA_TYPE_REAL:
00753 case DATA_TYPE_FAKE:
00754 setDataTypeBit(dataType);
00755 return *this;
00756 default:
00757 std::ostringstream ss;
00758 ss << "Invalid data type: ";
00759 printHex(&dataType,1,ss);
00760 throw cms::Exception("FEDBuffer") << ss.str();
00761 }
00762 }
00763
00764 TrackerSpecialHeader& TrackerSpecialHeader::setAPVAddressErrorForFEUnit(const uint8_t internalFEUnitNum, const bool error)
00765 {
00766 const uint8_t mask = 0x1 << internalFEUnitNum;
00767 const uint8_t result = ( (apvAddressErrorRegister() & (~mask)) | (error?mask:0x00) );
00768 setAPVEAddressErrorRegister(result);
00769 return *this;
00770 }
00771
00772 TrackerSpecialHeader& TrackerSpecialHeader::setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
00773 {
00774 const uint8_t mask = 0x1 << internalFEUnitNum;
00775 const uint8_t result = ( (feEnableRegister() & (~mask)) | (enabled?mask:0x00) );
00776 setFEEnableRegister(result);
00777 return *this;
00778 }
00779
00780 TrackerSpecialHeader& TrackerSpecialHeader::setFEOverflowForFEUnit(const uint8_t internalFEUnitNum, const bool overflow)
00781 {
00782 const uint8_t mask = 0x1 << internalFEUnitNum;
00783 const uint8_t result = ( (feOverflowRegister() & (~mask)) | (overflow?mask:0x00) );
00784 setFEEnableRegister(result);
00785 return *this;
00786 }
00787
00788 TrackerSpecialHeader::TrackerSpecialHeader(const FEDBufferFormat bufferFormat, const FEDReadoutMode readoutMode,
00789 const FEDHeaderType headerType, const FEDDataType dataType,
00790 const uint8_t address, const uint8_t addressErrorRegister,
00791 const uint8_t feEnableRegister, const uint8_t feOverflowRegister,
00792 const FEDStatusRegister fedStatusRegister)
00793 {
00794 memset(specialHeader_,0x00,8);
00795
00796 wordSwapped_ = (bufferFormat == BUFFER_FORMAT_OLD_VME);
00797
00798 setBufferFormatByte(bufferFormat);
00799 setReadoutMode(readoutMode);
00800 setHeaderType(headerType);
00801 setDataType(dataType);
00802 setAPVEAddress(address);
00803 setAPVEAddressErrorRegister(addressErrorRegister);
00804 setFEEnableRegister(feEnableRegister);
00805 setFEOverflowRegister(feOverflowRegister);
00806 setFEDStatusRegister(fedStatusRegister);
00807 }
00808
00809
00810
00811
00812 FEDDAQEventType FEDDAQHeader::eventType() const
00813 {
00814 switch(eventTypeNibble()) {
00815 case DAQ_EVENT_TYPE_PHYSICS:
00816 case DAQ_EVENT_TYPE_CALIBRATION:
00817 case DAQ_EVENT_TYPE_TEST:
00818 case DAQ_EVENT_TYPE_TECHNICAL:
00819 case DAQ_EVENT_TYPE_SIMULATED:
00820 case DAQ_EVENT_TYPE_TRACED:
00821 case DAQ_EVENT_TYPE_ERROR:
00822 return FEDDAQEventType(eventTypeNibble());
00823 default:
00824 return DAQ_EVENT_TYPE_INVALID;
00825 }
00826 }
00827
00828 FEDDAQHeader& FEDDAQHeader::setEventType(const FEDDAQEventType evtType)
00829 {
00830 header_[7] = ((header_[7] & 0xF0) | evtType);
00831 return *this;
00832 }
00833
00834 FEDDAQHeader& FEDDAQHeader::setL1ID(const uint32_t l1ID)
00835 {
00836 header_[4] = (l1ID & 0x000000FF);
00837 header_[5] = ( (l1ID & 0x0000FF00) >> 8);
00838 header_[6] = ( (l1ID & 0x00FF0000) >> 16);
00839 return *this;
00840 }
00841
00842 FEDDAQHeader& FEDDAQHeader::setBXID(const uint16_t bxID)
00843 {
00844 header_[3] = ( (bxID & 0x0FF0) >> 4);
00845 header_[2] = ( (header_[2] & 0x0F) | ( (bxID & 0x000F) << 4) );
00846 return *this;
00847 }
00848
00849 FEDDAQHeader& FEDDAQHeader::setSourceID(const uint16_t sourceID)
00850 {
00851 header_[2] = ( (header_[2] & 0xF0) | ( (sourceID & 0x0F00) >> 8) );
00852 header_[1] = (sourceID & 0x00FF);
00853 return *this;
00854 }
00855
00856 FEDDAQHeader::FEDDAQHeader(const uint32_t l1ID, const uint16_t bxID, const uint16_t sourceID, const FEDDAQEventType evtType)
00857 {
00858
00859 memset(header_,0x0,8);
00860
00861 header_[7] = 0x50;
00862
00863 setEventType(evtType);
00864 setL1ID(l1ID);
00865 setBXID(bxID);
00866 setSourceID(sourceID);
00867 }
00868
00869
00870
00871
00872 FEDTTSBits FEDDAQTrailer::ttsBits() const
00873 {
00874 switch(ttsNibble()) {
00875 case TTS_DISCONNECTED0:
00876 case TTS_WARN_OVERFLOW:
00877 case TTS_OUT_OF_SYNC:
00878 case TTS_BUSY:
00879 case TTS_READY:
00880 case TTS_ERROR:
00881 case TTS_DISCONNECTED1:
00882 return FEDTTSBits(ttsNibble());
00883 default:
00884 return TTS_INVALID;
00885 }
00886 }
00887
00888 FEDDAQTrailer::FEDDAQTrailer(const uint32_t eventLengthIn64BitWords, const uint16_t crc, const FEDTTSBits ttsBits,
00889 const bool slinkTransmissionError, const bool badFEDID, const bool slinkCRCError,
00890 const uint8_t eventStatusNibble)
00891 {
00892
00893 memset(trailer_,0x0,8);
00894
00895 trailer_[7] = 0xA0;
00896
00897 setEventLengthIn64BitWords(eventLengthIn64BitWords);
00898 setEventStatusNibble(eventStatusNibble);
00899 setTTSBits(ttsBits);
00900 setCRC(crc);
00901 setSLinkTransmissionErrorBit(slinkTransmissionError);
00902 setBadSourceIDBit(badFEDID);
00903 setSLinkCRCErrorBit(slinkCRCError);
00904 }
00905
00906 FEDDAQTrailer& FEDDAQTrailer::setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
00907 {
00908 trailer_[4] = (eventLengthIn64BitWords & 0x000000FF);
00909 trailer_[5] = ( (eventLengthIn64BitWords & 0x0000FF00) >> 8);
00910 trailer_[6] = ( (eventLengthIn64BitWords & 0x00FF0000) >> 16);
00911 return *this;
00912 }
00913
00914 FEDDAQTrailer& FEDDAQTrailer::setCRC(const uint16_t crc)
00915 {
00916 trailer_[2] = (crc & 0x00FF);
00917 trailer_[3] = ( (crc >> 8) & 0x00FF );
00918 return *this;
00919 }
00920
00921 FEDDAQTrailer& FEDDAQTrailer::setSLinkTransmissionErrorBit(const bool bitSet)
00922 {
00923 if (bitSet) trailer_[1] |= 0x80;
00924 else trailer_[1] &= (~0x80);
00925 return *this;
00926 }
00927
00928 FEDDAQTrailer& FEDDAQTrailer::setBadSourceIDBit(const bool bitSet)
00929 {
00930 if (bitSet) trailer_[1] |= 0x40;
00931 else trailer_[1] &= (~0x40);
00932 return *this;
00933 }
00934
00935 FEDDAQTrailer& FEDDAQTrailer::setSLinkCRCErrorBit(const bool bitSet)
00936 {
00937 if (bitSet) trailer_[0] |= 0x04;
00938 else trailer_[0] &= (~0x40);
00939 return *this;
00940 }
00941
00942 FEDDAQTrailer& FEDDAQTrailer::setEventStatusNibble(const uint8_t eventStatusNibble)
00943 {
00944 trailer_[1] = ( (trailer_[1] & 0xF0) | (eventStatusNibble & 0x0F) );
00945 return *this;
00946 }
00947
00948 FEDDAQTrailer& FEDDAQTrailer::setTTSBits(const FEDTTSBits ttsBits)
00949 {
00950 trailer_[0] = ( (trailer_[0] & 0x0F) | (ttsBits & 0xF0) );
00951 return *this;
00952 }
00953
00954
00955
00956
00957 FEDAPVErrorHeader::~FEDAPVErrorHeader()
00958 {
00959 }
00960
00961 size_t FEDAPVErrorHeader::lengthInBytes() const
00962 {
00963 return APV_ERROR_HEADER_SIZE_IN_BYTES;
00964 }
00965
00966 void FEDAPVErrorHeader::print(std::ostream& os) const
00967 {
00968 printHex(header_,APV_ERROR_HEADER_SIZE_IN_BYTES,os);
00969 }
00970
00971 FEDAPVErrorHeader* FEDAPVErrorHeader::clone() const
00972 {
00973 return new FEDAPVErrorHeader(*this);
00974 }
00975
00976 bool FEDAPVErrorHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
00977 {
00978
00979 const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FEUNIT)*24 + (FEDCH_PER_FEUNIT-1-(internalFEDChannelNum%FEDCH_PER_FEUNIT))*2 + apvNum;
00980
00981 return (header_[bitNumber/8] & (0x01<<(bitNumber%8)) );
00982 }
00983
00984 bool FEDAPVErrorHeader::checkChannelStatusBits(const uint8_t internalFEDChannelNum) const
00985 {
00986 return (checkStatusBits(internalFEDChannelNum,0) && checkStatusBits(internalFEDChannelNum,1));
00987 }
00988
00989 const uint8_t* FEDAPVErrorHeader::data() const
00990 {
00991 return header_;
00992 }
00993
00994 FEDAPVErrorHeader::FEDAPVErrorHeader(const std::vector<bool>& apvsGood)
00995 {
00996 memset(header_,0x00,APV_ERROR_HEADER_SIZE_IN_BYTES);
00997 for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
00998 setAPVStatusBit(iCh,0,apvsGood[iCh*2]);
00999 setAPVStatusBit(iCh,1,apvsGood[iCh*2+1]);
01000 }
01001 }
01002
01003 FEDAPVErrorHeader& FEDAPVErrorHeader::setAPVStatusBit(const uint8_t internalFEDChannelNum, const uint8_t apvNum, const bool apvGood)
01004 {
01005
01006 const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FED)*24 + (FEDCH_PER_FED-1-(internalFEDChannelNum%FEDCH_PER_FED))*2+apvNum;
01007 const uint8_t byteNumber = bitNumber/8;
01008 const uint8_t bitInByte = bitNumber%8;
01009 const uint8_t mask = (0x01 << bitInByte);
01010 header_[byteNumber] = ( (header_[byteNumber] & (~mask)) | (apvGood?mask:0x00) );
01011 return *this;
01012 }
01013
01014 void FEDAPVErrorHeader::setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status)
01015 {
01016
01017 if ( (!(status & CHANNEL_STATUS_LOCKED)) || (!(status & CHANNEL_STATUS_IN_SYNC)) ) {
01018 setAPVStatusBit(internalFEDChannelNum,0,false);
01019 setAPVStatusBit(internalFEDChannelNum,1,false);
01020 return;
01021 } else {
01022 if ( (status & CHANNEL_STATUS_APV0_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV0_NO_ERROR_BIT) ) {
01023 setAPVStatusBit(internalFEDChannelNum,0,true);
01024 } else {
01025 setAPVStatusBit(internalFEDChannelNum,0,false);
01026 }
01027 if ( (status & CHANNEL_STATUS_APV1_ADDRESS_GOOD) && (status & CHANNEL_STATUS_APV1_NO_ERROR_BIT) ) {
01028 setAPVStatusBit(internalFEDChannelNum,1,true);
01029 } else {
01030 setAPVStatusBit(internalFEDChannelNum,1,false);
01031 }
01032 }
01033 }
01034
01035
01036
01037 void FEDAPVErrorHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
01038 {
01039 return;
01040 }
01041 void FEDAPVErrorHeader::setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister)
01042 {
01043 return;
01044 }
01045 void FEDAPVErrorHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
01046 {
01047 return;
01048 }
01049
01050
01051 FEDFullDebugHeader::~FEDFullDebugHeader()
01052 {
01053 }
01054
01055 size_t FEDFullDebugHeader::lengthInBytes() const
01056 {
01057 return FULL_DEBUG_HEADER_SIZE_IN_BYTES;
01058 }
01059
01060 void FEDFullDebugHeader::print(std::ostream& os) const
01061 {
01062 printHex(header_,FULL_DEBUG_HEADER_SIZE_IN_BYTES,os);
01063 }
01064
01065 FEDFullDebugHeader* FEDFullDebugHeader::clone() const
01066 {
01067 return new FEDFullDebugHeader(*this);
01068 }
01069
01070 bool FEDFullDebugHeader::checkStatusBits(const uint8_t internalFEDChannelNum, const uint8_t apvNum) const
01071 {
01072 return ( !unlockedFromBit(internalFEDChannelNum) &&
01073 !outOfSyncFromBit(internalFEDChannelNum) &&
01074 !apvError(internalFEDChannelNum,apvNum) &&
01075 !apvAddressError(internalFEDChannelNum,apvNum) );
01076 }
01077
01078 bool FEDFullDebugHeader::checkChannelStatusBits(const uint8_t internalFEDChannelNum) const
01079 {
01080
01081
01082
01083
01084
01085
01086 return (getChannelStatus(internalFEDChannelNum) == CHANNEL_STATUS_NO_PROBLEMS);
01087 }
01088
01089 FEDChannelStatus FEDFullDebugHeader::getChannelStatus(const uint8_t internalFEDChannelNum) const
01090 {
01091 const uint8_t* pFEWord = feWord(internalFEDChannelNum/FEDCH_PER_FEUNIT);
01092 const uint8_t feUnitChanNum = internalFEDChannelNum % FEDCH_PER_FEUNIT;
01093 const uint8_t startByteInFEWord = (FEDCH_PER_FEUNIT-1 - feUnitChanNum) * 6 / 8;
01094 switch ( (FEDCH_PER_FEUNIT-1-feUnitChanNum) % 4 ) {
01095 case 0:
01096 return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
01097 case 1:
01098 return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
01099 case 2:
01100 return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
01101 case 3:
01102 return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
01103
01104 default:
01105 return FEDChannelStatus(0);
01106 }
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 }
01128
01129 const uint8_t* FEDFullDebugHeader::data() const
01130 {
01131 return header_;
01132 }
01133
01134 FEDFullDebugHeader::FEDFullDebugHeader(const std::vector<uint16_t>& feUnitLengths, const std::vector<uint8_t>& feMajorityAddresses,
01135 const std::vector<FEDChannelStatus>& channelStatus, const FEDBackendStatusRegister beStatusRegister,
01136 const uint32_t daqRegister, const uint32_t daqRegister2)
01137 {
01138 memset(header_,0x00,FULL_DEBUG_HEADER_SIZE_IN_BYTES);
01139 setBEStatusRegister(beStatusRegister);
01140 setDAQRegister(daqRegister);
01141 setDAQRegister2(daqRegister2);
01142 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
01143 setFEUnitLength(iFE,feUnitLengths[iFE]);
01144 setFEUnitMajorityAddress(iFE,feMajorityAddresses[iFE]);
01145 }
01146 for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
01147 setChannelStatus(iCh,channelStatus[iCh]);
01148 }
01149 }
01150
01151 void FEDFullDebugHeader::setChannelStatus(const uint8_t internalFEDChannelNum, const FEDChannelStatus status)
01152 {
01153 setUnlocked(internalFEDChannelNum, !(status&CHANNEL_STATUS_LOCKED) );
01154 setOutOfSync(internalFEDChannelNum, !(status&CHANNEL_STATUS_IN_SYNC) );
01155 setAPVAddressError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_ADDRESS_GOOD) );
01156 setAPVAddressError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_ADDRESS_GOOD) );
01157 setAPVError(internalFEDChannelNum,1, !(status&CHANNEL_STATUS_APV1_NO_ERROR_BIT) );
01158 setAPVError(internalFEDChannelNum,0, !(status&CHANNEL_STATUS_APV0_NO_ERROR_BIT) );
01159 }
01160
01161 void FEDFullDebugHeader::setFEUnitMajorityAddress(const uint8_t internalFEUnitNum, const uint8_t address)
01162 {
01163 feWord(internalFEUnitNum)[9] = address;
01164 }
01165
01166 void FEDFullDebugHeader::setBEStatusRegister(const FEDBackendStatusRegister beStatusRegister)
01167 {
01168 set32BitWordAt(feWord(0)+10,beStatusRegister);
01169 }
01170
01171 void FEDFullDebugHeader::setDAQRegister(const uint32_t daqRegister)
01172 {
01173 set32BitWordAt(feWord(7)+10,daqRegister);
01174 }
01175
01176 void FEDFullDebugHeader::setDAQRegister2(const uint32_t daqRegister2)
01177 {
01178 set32BitWordAt(feWord(6)+10,daqRegister2);
01179 }
01180
01181 void FEDFullDebugHeader::setFEUnitLength(const uint8_t internalFEUnitNum, const uint16_t length)
01182 {
01183 feWord(internalFEUnitNum)[15] = ( (length & 0xFF00) >> 8);
01184 feWord(internalFEUnitNum)[14] = (length & 0x00FF);
01185 }
01186
01187 void FEDFullDebugHeader::setBit(const uint8_t internalFEDChannelNum, const uint8_t bit, const bool value)
01188 {
01189 const uint8_t bitInFeWord = (FEDCH_PER_FEUNIT-1 - (internalFEDChannelNum%FEDCH_PER_FEUNIT)) * 6 + bit;
01190 uint8_t& byte = *(feWord(internalFEDChannelNum / FEDCH_PER_FEUNIT)+(bitInFeWord/8));
01191 const uint8_t mask = (0x1 << bitInFeWord%8);
01192 byte = ( (byte & (~mask)) | (value?mask:0x0) );
01193 }
01194
01195 FEDFEHeader::~FEDFEHeader()
01196 {
01197 }
01198
01199
01200
01201
01202 FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
01203 : channels_(FEDCH_PER_FED,FEDChannel(NULL,0,0)),
01204 originalBuffer_(fedBuffer),
01205 bufferSize_(fedBufferSize)
01206 {
01207 init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
01208 }
01209
01210 FEDBufferBase::FEDBufferBase(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat, const bool fillChannelVector)
01211 : originalBuffer_(fedBuffer),
01212 bufferSize_(fedBufferSize)
01213 {
01214 init(fedBuffer,fedBufferSize,allowUnrecognizedFormat);
01215 if (fillChannelVector) channels_.assign(FEDCH_PER_FED,FEDChannel(NULL,0,0));
01216 }
01217
01218 void FEDBufferBase::init(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowUnrecognizedFormat)
01219 {
01220
01221 static const size_t MIN_BUFFER_SIZE = 8+8+8;
01222
01223 if (!originalBuffer_) throw cms::Exception("FEDBuffer") << "Buffer pointer is NULL.";
01224 if (bufferSize_ < MIN_BUFFER_SIZE) {
01225 std::ostringstream ss;
01226 ss << "Buffer is too small. "
01227 << "Min size is " << MIN_BUFFER_SIZE << ". "
01228 << "Buffer size is " << bufferSize_ << ". ";
01229 throw cms::Exception("FEDBuffer") << ss.str();
01230 }
01231
01232
01233 specialHeader_ = TrackerSpecialHeader(originalBuffer_+8);
01234
01235
01236 const FEDBufferFormat bufferFormat = specialHeader_.bufferFormat();
01237 if (bufferFormat == BUFFER_FORMAT_INVALID && !allowUnrecognizedFormat) {
01238 std::ostringstream ss;
01239 ss << "Buffer format not recognized. "
01240 << "Tracker special header: " << specialHeader_;
01241 throw cms::Exception("FEDBuffer") << ss.str();
01242 }
01243
01244 if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) ) {
01245 uint8_t* newBuffer = new uint8_t[bufferSize_];
01246 const uint32_t* originalU32 = reinterpret_cast<const uint32_t*>(originalBuffer_);
01247 const size_t sizeU32 = bufferSize_/4;
01248 uint32_t* newU32 = reinterpret_cast<uint32_t*>(newBuffer);
01249 if (bufferFormat == BUFFER_FORMAT_OLD_VME) {
01250
01251 for (size_t i = 0; i < sizeU32; i+=2) {
01252 newU32[i] = originalU32[i+1];
01253 newU32[i+1] = originalU32[i];
01254 }
01255 }
01256 if (bufferFormat == BUFFER_FORMAT_NEW) {
01257
01258 memcpy(newU32,originalU32,8);
01259
01260 memcpy(newU32+sizeU32-2,originalU32+sizeU32-2,8);
01261
01262 for (size_t i = 2; i < sizeU32-2; i+=2) {
01263 newU32[i] = originalU32[i+1];
01264 newU32[i+1] = originalU32[i];
01265 }
01266 }
01267 orderedBuffer_ = newBuffer;
01268 }
01269 else {
01270 orderedBuffer_ = originalBuffer_;
01271 }
01272
01273
01274 daqHeader_ = FEDDAQHeader(orderedBuffer_);
01275
01276 daqTrailer_ = FEDDAQTrailer(orderedBuffer_+bufferSize_-8);
01277 }
01278
01279 FEDBufferBase::~FEDBufferBase()
01280 {
01281
01282 if (orderedBuffer_ != originalBuffer_) delete[] orderedBuffer_;
01283 }
01284
01285 void FEDBufferBase::print(std::ostream& os) const
01286 {
01287 os << "buffer format: " << bufferFormat() << std::endl;
01288 os << "Buffer size: " << bufferSize() << " bytes" << std::endl;
01289 os << "Event length from DAQ trailer: " << daqEventLengthInBytes() << " bytes" << std::endl;
01290 os << "Source ID: " << daqSourceID() << std::endl;
01291 os << "Header type: " << headerType() << std::endl;
01292 os << "Readout mode: " << readoutMode() << std::endl;
01293 os << "Data type: " << dataType() << std::endl;
01294 os << "DAQ event type: " << daqEventType() << std::endl;
01295 os << "TTS state: " << daqTTSState() << std::endl;
01296 os << "L1 ID: " << daqLvl1ID() << std::endl;
01297 os << "BX ID: " << daqBXID() << std::endl;
01298 os << "FED status register flags: "; fedStatusRegister().printFlags(os); os << std::endl;
01299 os << "APVe Address: " << uint16_t(apveAddress()) << std::endl;
01300 os << "Enabled FE units: " << uint16_t(nFEUnitsEnabled()) << std::endl;
01301 }
01302
01303 uint8_t FEDBufferBase::nFEUnitsEnabled() const
01304 {
01305 uint8_t result = 0;
01306 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
01307 if (feEnabled(iFE)) result++;
01308 }
01309 return result;
01310 }
01311
01312 bool FEDBufferBase::checkSourceIDs() const
01313 {
01314 return ( (daqSourceID() >= FED_ID_MIN) &&
01315 (daqSourceID() <= FED_ID_MAX) );
01316 }
01317
01318 bool FEDBufferBase::checkMajorityAddresses() const
01319 {
01320 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
01321 if (!feEnabled(iFE)) continue;
01322 if (majorityAddressErrorForFEUnit(iFE)) return false;
01323 }
01324 return true;
01325 }
01326
01327 bool FEDBufferBase::channelGood(const uint8_t internalFEDChannelNum) const
01328 {
01329 const uint8_t feUnit = internalFEDChannelNum/FEDCH_PER_FEUNIT;
01330 return ( !majorityAddressErrorForFEUnit(feUnit) && feEnabled(feUnit) && !feOverflow(feUnit) );
01331 }
01332
01333 bool FEDBufferBase::doChecks() const
01334 {
01335 return (doTrackerSpecialHeaderChecks() && doDAQHeaderAndTrailerChecks());
01336 }
01337
01338 std::string FEDBufferBase::checkSummary() const
01339 {
01340 std::ostringstream summary;
01341 summary << "Check buffer type valid: " << ( checkBufferFormat() ? "passed" : "FAILED" ) << std::endl;
01342 summary << "Check header format valid: " << ( checkHeaderType() ? "passed" : "FAILED" ) << std::endl;
01343 summary << "Check readout mode valid: " << ( checkReadoutMode() ? "passed" : "FAILED" ) << std::endl;
01344
01345 summary << "Check FE unit majority addresses: " << ( checkMajorityAddresses() ? "passed" : "FAILED" ) << std::endl;
01346 if (!checkMajorityAddresses()) {
01347 summary << "FEs with majority address error: ";
01348 unsigned int badFEs = 0;
01349 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
01350 if (!feEnabled(iFE)) continue;
01351 if (majorityAddressErrorForFEUnit(iFE)) {
01352 summary << uint16_t(iFE) << " ";
01353 badFEs++;
01354 }
01355 }
01356 summary << std::endl;
01357 summary << "Number of FE Units with bad addresses: " << badFEs << std::endl;
01358 }
01359 summary << "Check for FE unit buffer overflows: " << ( checkNoFEOverflows() ? "passed" : "FAILED" ) << std::endl;
01360 if (!checkNoFEOverflows()) {
01361 summary << "FEs which overflowed: ";
01362 unsigned int badFEs = 0;
01363 for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
01364 if (feOverflow(iFE)) {
01365 summary << uint16_t(iFE) << " ";
01366 badFEs++;
01367 }
01368 }
01369 summary << std::endl;
01370 summary << "Number of FE Units which overflowed: " << badFEs << std::endl;
01371 }
01372 summary << "Check for S-Link CRC errors: " << ( checkNoSlinkCRCError() ? "passed" : "FAILED" ) << std::endl;
01373 summary << "Check for S-Link transmission error: " << ( checkNoSLinkTransmissionError() ? "passed" : "FAILED" ) << std::endl;
01374 summary << "Check CRC: " << ( checkCRC() ? "passed" : "FAILED" ) << std::endl;
01375 summary << "Check source ID is FED ID: " << ( checkSourceIDs() ? "passed" : "FAILED" ) << std::endl;
01376 summary << "Check for unexpected source ID at FRL: " << ( checkNoUnexpectedSourceID() ? "passed" : "FAILED" ) << std::endl;
01377 summary << "Check there are no extra headers or trailers: " << ( checkNoExtraHeadersOrTrailers() ? "passed" : "FAILED" ) << std::endl;
01378 summary << "Check length from trailer: " << ( checkLengthFromTrailer() ? "passed" : "FAILED" ) << std::endl;
01379 return summary.str();
01380 }
01381
01382
01383
01384
01385 uint16_t FEDChannel::cmMedian(const uint8_t apvIndex) const
01386 {
01387 if (packetCode() != PACKET_CODE_ZERO_SUPPRESSED) {
01388 std::ostringstream ss;
01389 ss << "Request for CM median from channel with non-ZS packet code. "
01390 << "Packet code is " << uint16_t(packetCode()) << "."
01391 << std::endl;
01392 throw cms::Exception("FEDBuffer") << ss.str();
01393 }
01394 if (apvIndex > 1) {
01395 std::ostringstream ss;
01396 ss << "Channel APV index out of range when requesting CM median for APV. "
01397 << "Channel APV index is " << uint16_t(apvIndex) << "."
01398 << std::endl;
01399 throw cms::Exception("FEDBuffer") << ss.str();
01400 }
01401 uint16_t result = 0;
01402
01403 result |= data_[(offset_+3+2*apvIndex)^7];
01404 result |= ( ((data_[(offset_+4+2*apvIndex)^7]) << 8) & 0x300 );
01405 return result;
01406 }
01407
01408 }