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
00028
00029 uint16_t* pSOM=0;
00030
00031 uint16_t* pRDA=0;
00032 uint16_t* pEOM=0;
00033
00034
00035
00036 unsigned wordlen = fullsz / sizeof(uint16_t);
00037 unsigned wordcnt = 0;
00038 uint16_t* cursor = (uint16_t*) buf;
00039
00040
00041 bool israwdata(false);
00042
00043
00044 while (wordcnt++ < wordlen) {
00045
00046 unsigned kind = (*cursor >>12) & 0xF;
00047
00048
00049 if (israwdata && ((kind & 8) == 0)) { cursor++; continue; }
00050
00051 switch (kind) {
00052 case 0x8:
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
00062 fTimeStamp = evalTimeStamp(cursor);
00063 DPRINT605("sp605::Message::assign: found Time Stamp Word: 0x%x\n",*cursor);
00064 break;
00065
00066 case 0xA:
00067
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
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;
00089 DPRINT605("sp605::Message::assign: found Buffer Overflow Message: 0x%x\n",*cursor);
00090 return wordcnt * sizeof(uint16_t);
00091
00092 case 0xD:
00093
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
00101
00102 fprintf(stderr,"sp605::Message::assign: data error - extracted data not yet supported!");
00103 break;
00104
00105 case 0xF:
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
00137
00138
00139
00140
00141 return wordlen + 2;
00142 }
00143
00144
00145 void sp605::Message::InitTraceBuffer(uint16_t* pRDA)
00146 {
00147
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
00155
00156
00157
00158 unsigned bin = 0;
00159
00160 while (bin<len) {
00161
00162 result = ((*cursor & 0xFFF) >> 3);
00163 if(!SetTrace(bin++, result, len)) return;
00164 rest = (*cursor & 0x7);
00165 cursor++;
00166
00167 result = ((*cursor & 0x7FFF) >> 9) | (rest << 6);
00168 if(!SetTrace(bin++, result, len)) return;
00169 result = (*cursor & 0x1FF);
00170 if(!SetTrace(bin++, result, len)) return;
00171 cursor++;
00172
00173 result = ((*cursor & 0x7FFF) >> 6);
00174 if(!SetTrace(bin++, result, len)) return;
00175 rest = (*cursor & 0x3F);
00176 cursor++;
00177
00178 result = ((*cursor & 0x7FFF) >> 12) | (rest << 3);
00179 if(!SetTrace(bin++, result, len)) return;
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
00219
00220
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 }