CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/EventFilter/SiStripRawToDigi/src/SiStripFEDBufferComponents.cc

Go to the documentation of this file.
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     //if there is one 64 bit word or less, print it out
00031     if (lengthInBytes <= 8) {
00032       printHexWord(bytePointer,lengthInBytes,os);
00033     }
00034     //otherwise, print word numbers etc
00035     else {
00036       //header
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       //print full words
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       //print part word, if any
00048       if (extraBytes) {
00049         const size_t startByte = words*8;
00050         os << words << '\t' << startByte+8 << '\t';
00051         //padding
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       //set CRC bytes to zero since these were not set when CRC was calculated
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     //if it was none of the above then return invalid
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     //if it was none of the above then return invalid
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     //if it was none of the above then return invalid
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     //if it was none of the above then throw an exception (there is no invalid value for the data type since it is represented as a single bit in the buffer)
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     //if it was none of the above then return invalid
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     //the buffer format byte is one of the valid values if we assume the buffer is not swapped
00614     const bool validFormatByteWhenNotWordSwapped = ( (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_NEW) ||
00615                                                      (headerPointer[BUFFERFORMAT] == BUFFER_FORMAT_CODE_OLD) );
00616     //the buffer format byte is the old value if we assume the buffer is swapped
00617     const bool validFormatByteWhenWordSwapped = (headerPointer[BUFFERFORMAT^4] == BUFFER_FORMAT_CODE_OLD);
00618     //if the buffer format byte is valid if the buffer is not swapped or it is never valid
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     //if it is scope mode then return as is (it cannot be fake data)
00652     if (eventTypeNibble == READOUT_MODE_SCOPE) return FEDReadoutMode(eventTypeNibble);
00653     //if not then ignore the last bit which indicates if it is real or fake
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     //if it is scope mode then it is always real
00673     if (eventTypeNibble == READOUT_MODE_SCOPE) return DATA_TYPE_REAL;
00674     //in other modes it is the lowest order bit of event type nibble
00675     else return FEDDataType(eventTypeNibble & 0x1);
00676   }
00677   
00678   TrackerSpecialHeader& TrackerSpecialHeader::setBufferFormat(const FEDBufferFormat newBufferFormat)
00679   {
00680     //check if order in buffer is different
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     //set appropriate code
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       //scope mode is always real
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     //if mode is scope then this bit can't be changed
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     //determine if order is swapped in real buffer
00796     wordSwapped_ = (bufferFormat == BUFFER_FORMAT_OLD_VME);
00797     //set fields
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     //clear everything (FOV,H,x,$ all set to 0)
00859     memset(header_,0x0,8);
00860     //set the BoE nibble to indicate this is the last fragment
00861     header_[7] = 0x50;
00862     //set variable fields vith values supplied
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     //clear everything (T,x,$ all set to 0)
00893     memset(trailer_,0x0,8);
00894     //set the EoE nibble to indicate this is the last fragment
00895     trailer_[7] = 0xA0;
00896     //set variable fields vith values supplied
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     //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
00979     const uint16_t bitNumber = (internalFEDChannelNum/FEDCH_PER_FEUNIT)*24 + (FEDCH_PER_FEUNIT-1-(internalFEDChannelNum%FEDCH_PER_FEUNIT))*2 + apvNum;
00980     //bit high means no error
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     //3 bytes per FE unit, channel order is reversed in FE unit data, 2 bits per channel
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     //if channel is unlocked then set both APV bits bad
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   //These methods do nothing as the values in question are in present in the APV Error header.
01036   //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.
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     //return ( !unlockedFromBit(internalFEDChannelNum) &&
01081     //         !outOfSyncFromBit(internalFEDChannelNum) &&
01082     //         !apvErrorFromBit(internalFEDChannelNum,0) &&
01083     //         !apvAddressErrorFromBit(internalFEDChannelNum,0) &&
01084     //         !apvErrorFromBit(internalFEDChannelNum,1) &&
01085     //         !apvAddressErrorFromBit(internalFEDChannelNum,1) );
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     //stop compiler warning
01104     default:
01105       return FEDChannelStatus(0);
01106     }
01107     /*const uint8_t feUnitChanNum = internalFEDChannelNum / FEDCH_PER_FEUNIT;
01108     const uint8_t* pFEWord = feWord(feUnitChanNum);
01109     const uint8_t startByteInFEWord = feUnitChanNum * 3 / 4;
01110     //const uint8_t shift = ( 6 - ((feUnitChanNum-1)%4) );
01111     //const uint16_t mask = ( 0x003F << shift );
01112     //uint8_t result = ( (pFEWord[startByteInFEWord] & (mask&0x00FF)) >> shift );
01113     //result |= ( (pFEWord[startByteInFEWord+1] & (mask>>8)) << (8-shift) );
01114     switch (feUnitChanNum % 4) {
01115     case 0:
01116       return FEDChannelStatus( pFEWord[startByteInFEWord] & 0x3F );
01117     case 1:
01118       return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xC0) >> 6) | ((pFEWord[startByteInFEWord+1] & 0x0F) << 2) );
01119     case 2:
01120       return FEDChannelStatus( ((pFEWord[startByteInFEWord] & 0xF0) >> 4) | ((pFEWord[startByteInFEWord+1] & 0x03) << 4) );
01121     case 3:
01122       return FEDChannelStatus( (pFEWord[startByteInFEWord] & 0xFC) >> 2 );
01123     //stop compiler warning
01124     default:
01125       return FEDChannelStatus(0);
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     //min buffer length. DAQ header, DAQ trailer, tracker special header. 
01221     static const size_t MIN_BUFFER_SIZE = 8+8+8;
01222     //check size is non zero and data pointer is not NULL
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     //construct tracker special header using second 64 bit word
01233     specialHeader_ = TrackerSpecialHeader(originalBuffer_+8);
01234   
01235     //check the buffer format
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     //swap the buffer words so that the whole buffer is in slink ordering
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         //swap whole buffer
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         //copy DAQ header
01258         memcpy(newU32,originalU32,8);
01259         //copy DAQ trailer
01260         memcpy(newU32+sizeU32-2,originalU32+sizeU32-2,8);
01261         //swap the payload
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     } //if ( (bufferFormat == BUFFER_FORMAT_OLD_VME) || (bufferFormat == BUFFER_FORMAT_NEW) )
01269     else {
01270       orderedBuffer_ = originalBuffer_;
01271     }
01272   
01273     //construct header object at begining of buffer
01274     daqHeader_ = FEDDAQHeader(orderedBuffer_);
01275     //construct trailer object using last 64 bit word of buffer
01276     daqTrailer_ = FEDDAQTrailer(orderedBuffer_+bufferSize_-8);
01277   }
01278 
01279   FEDBufferBase::~FEDBufferBase()
01280   {
01281     //if the buffer was coppied and swapped then delete the copy
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     //summary << "Check APVe address valid: " << ( checkAPVEAddressValid() ? "passed" : "FAILED" ) << std::endl;
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     //CM median is 10 bits with lowest order byte first. First APV CM median starts in 4th byte of channel data
01403     result |= data_[(offset_+3+2*apvIndex)^7];
01404     result |= ( ((data_[(offset_+4+2*apvIndex)^7]) << 8) & 0x300 );
01405     return result;
01406   }
01407   
01408 }