• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

roclib/src_sp605/Message.cxx (r4864/r4189)

Go to the documentation of this file.
00001 #include "sp605/Message.h"
00002 
00003 #include <stdio.h>
00004 
00005 
00006 const char* sp605_msg_names[sp605::MSG_LASTID] =
00007   { "NOP", "HIT", "EPOCH", "OVERFLOW", "INFO" };
00008 
00009 const char* sp605_info_names[7] =
00010 { "DIS", "NGT", "NRT", "NBE", "MSB", "NOP", "SYN" };
00011 
00012 const char* sp605_info_descr[7] =
00013 { "channel disabled during readout",
00014   "corruption, next grant timeout in switch",
00015   "corruption, next request timeout in switch",
00016   "corruption, new grant but channel empty in switch",
00017   "corruption, unknown metadata type in message builder",
00018   "empty word (may appear within other messages)",
00019   "out of sync warning"
00020 };
00021 
00022 
00023 size_t sp605::Message::assign(void* buf, unsigned fullsz)
00024 {
00025    if ((buf==0) || (fullsz<2)) return 0;
00026    clear();
00027    //isReadyTracebuffer=false;
00028    // we keep this helper pointers locally to avoid large overhead in message data structure
00029    uint16_t* pSOM=0; // points to actual start of message word
00030    // uint16_t* pTSW=0; // points to actual timestamp word (hit and buffer overflow msgs)
00031    uint16_t* pRDA=0; // points to begin of raw data field (hit messages)
00032    uint16_t* pEOM=0; // points to end of message word (hit messages)
00033    // uint16_t* pBOM=0; // points to buffer overflow word (buffer overflow messages)
00034    // uint16_t* pEPM=0; // points to epoch marker (epoch messages)
00035 
00036    unsigned wordlen = fullsz / sizeof(uint16_t);
00037    unsigned wordcnt = 0;
00038    uint16_t* cursor = (uint16_t*) buf;
00039     // check preamble of start word, may be some or single info word
00040     
00041    bool israwdata(false);
00042 
00043 
00044    while (wordcnt++ < wordlen) {
00045 
00046       unsigned kind = (*cursor >>12) & 0xF;
00047       
00048       // this is raw data, process it later
00049       if (israwdata && ((kind & 8) == 0)) { cursor++; continue; }
00050 
00051       switch (kind) {
00052          case 0x8:       // start of message
00053             if (cursor!=buf) { fprintf(stderr,"SOM inside the message\n"); clear(); }
00054             pSOM = cursor;
00055             fGroup = evalGroup(pSOM);
00056             fChan = evalChNum(pSOM);
00057             DPRINT605("sp605::Message::assign: found Start Of Message: 0x%x\n",*cursor);
00058             break;
00059 
00060          case 0x9:
00061             // timestamp word
00062             fTimeStamp = evalTimeStamp(cursor);
00063             DPRINT605("sp605::Message::assign: found Time Stamp Word: 0x%x\n",*cursor);
00064             break;
00065 
00066          case 0xA:
00067             // begin of  raw data
00068             pRDA = cursor;
00069             israwdata = true;
00070             DPRINT605("sp605::Message::assign: found Begin of Raw DAta: 0x%x\n",*cursor);
00071             break;
00072 
00073          case 0xB:
00074             // end of message
00075             DPRINT605("sp605::Message::assign: found End Of Message: 0x%x\n",*cursor);
00076             pEOM = cursor;
00077             fMsgType = MSG_HIT;
00078             fHitType = evalHitType(pEOM);
00079             fInfoType = evalStopType(pEOM);
00080             fTraceSize = evalTraceSize(pEOM);
00081 
00082             InitTraceBuffer(pRDA);
00083 
00084             return wordcnt * sizeof(uint16_t);
00085 
00086          case 0xC:
00087             fMsgType = MSG_OVERFLOW;
00088             fEpoch = *cursor & 0xFF; // overflow hits
00089             DPRINT605("sp605::Message::assign: found Buffer Overflow Message: 0x%x\n",*cursor);
00090             return wordcnt * sizeof(uint16_t);
00091 
00092          case 0xD:
00093             // epoch counter
00094             fMsgType = MSG_EPOCH;
00095             DPRINT605("sp605::Message::assign: found EPoch Marker: 0x%x\n",*cursor);
00096             fEpoch = *cursor & 0xFFF;
00097             return wordcnt * sizeof(uint16_t);
00098 
00099         case 0xE:
00100             // extracted data
00101             //pRDA= cursor;
00102             fprintf(stderr,"sp605::Message::assign: data error - extracted data not yet supported!");
00103             break;
00104 
00105          case 0xF: // info message, single word
00106             fMsgType = MSG_INFO;
00107             fGroup = 0;
00108             fInfoType = (*cursor >>8) & 0xF;
00109             switch (fInfoType) {
00110                case INFO_DIS:
00111                case INFO_NGT:
00112                case INFO_NBE:
00113                case INFO_MSB:
00114                   fChan = (*cursor >>4 ) & 0xF;
00115                   break;
00116                case INFO_NRT:
00117                case INFO_NOP:
00118                   break;
00119                case INFO_SYN:
00120                   fEpoch = *cursor & 0xff;
00121                   break;
00122             }
00123 
00124             DPRINT605("sp605::Message::assign: found INFo Message: 0x%x\n",*cursor);
00125             return wordcnt * sizeof(uint16_t);
00126 
00127          default:
00128             fprintf(stderr,"sp605::Message::assign: data error - unknown message header 0x%x\n",*cursor);
00129             fMsgType = MSG_NOP;
00130             fGroup = 0;
00131             return 0;
00132       }
00133       cursor++;
00134 
00135    }
00136    // check next word: timestamp or epoch counter?
00137 
00138    // fprintf(stderr,"Cannot decode message completely - not enough bytes");
00139    
00140    // indicate that message is not complete and we need more bytes
00141    return wordlen + 2;
00142 }
00143 
00144 
00145 void sp605::Message::InitTraceBuffer(uint16_t* pRDA)
00146 {
00147    //isReadyTracebuffer=true;
00148    int16_t result(0), rest(0);
00149    uint16_t* cursor = pRDA;
00150    size_t len = getTraceSize();
00151    fTraces.clear();
00152    fTraces.resize(len, 0);
00153 
00154    // extract trace words at first call to buffer array
00155    // we first write down manually the procedure, then generalize it:
00156    // patter repeats every 3 words. There are 45 bit which are 5 samples
00157 
00158    unsigned bin = 0;
00159 
00160    while (bin<len) {
00161 
00162       result = ((*cursor & 0xFFF) >> 3);
00163       if(!SetTrace(bin++, result, len)) return;    //0
00164       rest = (*cursor & 0x7);
00165       cursor++; // cursor to continuation word
00166 
00167       result = ((*cursor & 0x7FFF) >> 9) | (rest << 6);
00168       if(!SetTrace(bin++, result, len)) return;    //1
00169       result = (*cursor & 0x1FF);
00170       if(!SetTrace(bin++, result, len)) return;   //2
00171       cursor++;
00172 
00173       result = ((*cursor & 0x7FFF) >> 6);
00174       if(!SetTrace(bin++, result, len)) return;  //3
00175       rest = (*cursor & 0x3F);
00176       cursor++;
00177 
00178       result = ((*cursor & 0x7FFF) >> 12) | (rest << 3);
00179       if(!SetTrace(bin++, result, len)) return;  //4
00180    }
00181 
00182 }
00183 
00184 
00185 // -------------------------------------------------------------
00186 
00187 uint32_t sp605::Message::getMsgFullTime(uint16_t epoch) const
00188 {
00189    switch (getMsgType()) {
00190       case MSG_HIT:
00191       case MSG_OVERFLOW:
00192          return FullTimeStamp(epoch, getTimeStamp());
00193       case MSG_EPOCH:
00194          return FullTimeStamp(getEpoch(), 0);
00195    }
00196    return FullTimeStamp(epoch, 0);
00197 }
00198 
00199 //----------------------------------------------------------------------------
00202 
00203 double sp605::Message::getMsgFullTimeD(uint16_t epoch) const
00204 {
00205    return getMsgFullTime(epoch);
00206 }
00207 
00208 
00209 void sp605::Message::printData()
00210 {
00211 
00212    printf("MSG:%u %s", (unsigned) getMsgType(), sp605_msg_names[getMsgType()]);
00213 
00214    if ((getGroup()!=0xff) || (getChNum()!=0xff))
00215       printf(" gr:%x ch:%02x", (unsigned) getGroup(), (unsigned) getChNum());
00216 
00217    switch (getMsgType()) {
00218       //case MSG_HIT: break;
00219       //case MSG_EPOCH: break;
00220       //case MSG_OVERFLOW: break;
00221       case MSG_INFO:
00222          printf(" kind:%u %s", getInfoType(), sp605_info_names[getInfoType()]);
00223 
00224          switch (getInfoType()) {
00225             case INFO_DIS:
00226             case INFO_NGT:
00227             case INFO_NBE:
00228             case INFO_MSB:
00229                printf (" c:%u", getInfoChannel());
00230                break;
00231             case INFO_NRT:
00232             case INFO_NOP:
00233                break;
00234             case INFO_SYN:
00235                printf (" e:%u", getInfoEpoch());
00236                break;
00237          }
00238 
00239          printf(" %s\n", sp605_info_descr[getInfoType()]);
00240          break;
00241 
00242       default:
00243          printf("timestamp:%u datasize:%u\n", (unsigned) getTimeStamp(), (unsigned) fTraces.size());
00244          break;
00245    }
00246 
00247    if (fTraces.size()>0) {
00248       printf("  [");
00249       for (unsigned n=0;n<fTraces.size();n++) {
00250          printf("%d", (int) fTraces[n]);
00251          if (n<fTraces.size()-1) printf(", ");
00252       }
00253       printf("]\n");
00254    }
00255 }

Generated on Tue Dec 10 2013 04:52:23 for ROCsoft by  doxygen 1.7.1