00001 #include "roc/Message.h"
00002
00003 #include <stdio.h>
00004 #include <string.h>
00005
00006 bool roc::Message::convertFromOld(void* src)
00007 {
00008 data = 0;
00009
00010 uint8_t* arr = (uint8_t*) src;
00011
00012 setMessageType((arr[0] >> 5) & 0x7);
00013 setRocNumber((arr[0] >> 2) & 0x7);
00014
00015 switch (getMessageType()) {
00016 case MSG_HIT:
00017 setNxNumber(arr[0] & 0x3);
00018 setNxLtsMsb((arr[1] >> 5) & 0x7);
00019 setNxTs(((arr[1] & 0x1f) << 9) | (arr[2] << 1) | (arr[3] >> 7));
00020 setNxChNum(arr[3] & 0x7f);
00021 setNxAdcValue(((arr[4] & 0x7f) << 5) | ((arr[5] & 0xf8) >> 3));
00022 setNxPileup((arr[5] >> 2) & 0x1);
00023 setNxOverflow((arr[5] >> 1) & 0x1);
00024 setNxLastEpoch(arr[5] & 0x1);
00025 break;
00026
00027 case MSG_EPOCH:
00028 setEpochNumber((arr[1] << 24) | (arr[2] << 16) | (arr[3] << 8) | arr[4]);
00029 setEpochMissed(arr[5]);
00030 break;
00031
00032 case MSG_SYNC:
00033 setSyncChNum(arr[0] & 0x3);
00034 setSyncEpochLSB(arr[1] >> 7);
00035 setSyncTs(((arr[1] & 0x7f) << 7) | ((arr[2] & 0xfc) >> 1));
00036 setSyncData(((arr[2] & 0x3) << 22) | (arr[3] << 14) | (arr[4] << 6) | (arr[5] >> 2));
00037 setSyncStFlag(arr[5] & 0x3);
00038 break;
00039
00040 case MSG_AUX:
00041 setAuxChNum(((arr[0] & 0x3) << 5) | ((arr[1] & 0xf8) >> 3));
00042 setAuxEpochLSB((arr[1] & 0x4) >> 2);
00043 setAuxTs(((arr[1] & 0x3) << 12) | (arr[2] << 4) | ((arr[3] & 0xe0) >> 4));
00044 setAuxFalling((arr[3] >> 4) & 1);
00045 setAuxOverflow((arr[3] >> 3) & 1);
00046 break;
00047
00048 case MSG_SYS:
00049 setSysMesType(arr[1]);
00050 setSysMesData((arr[2] << 24) | (arr[3] << 16) | (arr[4] << 8) | arr[5]);
00051 break;
00052
00053 default:
00054 return false;
00055 }
00056
00057 return true;
00058 }
00059
00060
00061 bool roc::Message::convertToOld(void* tgt)
00062 {
00063 uint8_t* data = (uint8_t*) tgt;
00064 for (int n=0;n<6;n++) data[n] = 0;
00065
00066 data[0] = ((getMessageType() & 0x7) << 5) | ((getRocNumber() & 0x7) << 2);
00067
00068 switch (getMessageType()) {
00069 case MSG_HIT:
00070 data[0] = data[0] | (getNxNumber() & 0x3);
00071 data[1] = ((getNxTs() >> 9) & 0x1f) | ((getNxLtsMsb() << 5) & 0xe0);
00072 data[2] = (getNxTs() >> 1);
00073 data[3] = ((getNxTs() << 7) & 0x80) | (getNxChNum() & 0x7f);
00074 data[4] = (getNxAdcValue() >> 5) & 0x7f;
00075 data[5] = ((getNxAdcValue() << 3) & 0xf8) |
00076 (getNxLastEpoch() & 0x1) |
00077 ((getNxOverflow() & 0x1) << 1) |
00078 ((getNxPileup() & 0x1) << 2);
00079 break;
00080
00081 case MSG_EPOCH:
00082 data[1] = (getEpochNumber() >> 24) & 0xff;
00083 data[2] = (getEpochNumber() >> 16) & 0xff;
00084 data[3] = (getEpochNumber() >> 8) & 0xff;
00085 data[4] = getEpochNumber() & 0xff;
00086 data[5] = getEpochMissed();
00087 break;
00088
00089 case MSG_SYNC:
00090 data[0] = data[0] | (getSyncChNum() & 0x3);
00091 data[1] = (getSyncEpochLSB() << 7) | ((getSyncTs() >> 7) & 0x7f);
00092 data[2] = ((getSyncTs() << 1) & 0xfc) | ((getSyncData() >> 22) & 0x3);
00093 data[3] = (getSyncData() >> 14) & 0xff;
00094 data[4] = (getSyncData() >> 6) & 0xff;
00095 data[5] = ((getSyncData() << 2) & 0xfc) | (getSyncStFlag() & 0x3);
00096 break;
00097
00098 case MSG_AUX:
00099 data[0] = data[0] | ((getAuxChNum() >> 5) & 0x3);
00100 data[1] = ((getAuxChNum() << 3) & 0xf8) |
00101 ((getAuxEpochLSB() << 2) & 0x4) |
00102 ((getAuxTs() >> 12) & 0x3);
00103 data[2] = (getAuxTs() >> 4) & 0xff;
00104 data[3] = ((getAuxTs() << 4) & 0xe0) |
00105 (getAuxFalling() << 4) |
00106 (getAuxOverflow() << 3);
00107 break;
00108
00109 case MSG_SYS:
00110 data[1] = getSysMesType();
00111 data[2] = (getSysMesData() >> 24) & 0xff;
00112 data[3] = (getSysMesData() >> 16) & 0xff;
00113 data[4] = (getSysMesData() >> 8) & 0xff;
00114 data[5] = getSysMesData() & 0xff;
00115 break;
00116
00117 default:
00118 return false;
00119 }
00120
00121 return true;
00122 }
00123
00124
00125
00131
00132 uint64_t roc::Message::getMsgFullTime(uint32_t epoch) const
00133 {
00134 switch (getMessageType()) {
00135 case MSG_HIT:
00136 return FullTimeStamp(getNxLastEpoch() ? epoch - 1 : epoch, getNxTs());
00137 case MSG_EPOCH:
00138 return FullTimeStamp(getEpochNumber(), 0);
00139 case MSG_SYNC:
00140 return FullTimeStamp((getSyncEpochLSB() == (epoch & 0x1)) ? epoch : epoch - 1, getSyncTs());
00141 case MSG_AUX:
00142 return FullTimeStamp((getAuxEpochLSB() == (epoch & 0x1)) ? epoch : epoch - 1, getAuxTs());
00143 case MSG_EPOCH2:
00144 return FullTimeStamp2(getEpoch2Number(), 0) / 20 + 512;
00145 case MSG_GET4:
00146 return FullTimeStamp2(epoch, getGet4Ts()) / 20 + 512;
00147 case MSG_SYS:
00148 return FullTimeStamp(epoch, 0);
00149
00150 }
00151 return 0;
00152 }
00153
00154
00157
00158 double roc::Message::getMsgFullTimeD(uint32_t epoch) const
00159 {
00160 switch (getMessageType()) {
00161 case MSG_EPOCH2:
00162 return FullTimeStamp2(getEpoch2Number(), 0) / 20. + 512.;
00163 case MSG_GET4:
00164 return FullTimeStamp2(epoch, getGet4Ts()) / 20. + 512.;
00165 }
00166 return getMsgFullTime(epoch);
00167 }
00168
00169
00170
00172
00173 uint64_t roc::Message::CalcDistance(uint64_t start, uint64_t stop)
00174 {
00175 if (start>stop) {
00176 stop += 0x3FFFFFFFFFFFLLU;
00177 if (start>stop) {
00178 printf("Epochs overflow error in CalcDistance\n");
00179 return 0;
00180 }
00181 }
00182
00183 return stop - start;
00184 }
00185
00186
00187
00189
00190 double roc::Message::CalcDistanceD(double start, double stop)
00191 {
00192 if (start>stop) {
00193 stop += 0x3FFFFFFFFFFFLLU;
00194 if (start>stop) {
00195 printf("Epochs overflow error in CalcDistanceD\n");
00196 return 0.;
00197 }
00198 }
00199
00200 return stop - start;
00201 }
00202
00203
00204
00205
00207
00213 void roc::Message::printData(unsigned kind, uint32_t epoch) const
00214 {
00215 printData(std::cout, kind, epoch);
00216 }
00217
00218
00220
00269 void roc::Message::printData(std::ostream& os, unsigned kind, uint32_t epoch) const
00270 {
00271 char buf[256];
00272
00273 if (kind & msg_print_Hex) {
00274 uint8_t* arr = (uint8_t*) &data;
00275 snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X ",
00276 arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
00277 os << buf;
00278 }
00279
00280 if (kind & msg_print_Human) {
00281 double timeInSec = getMsgFullTimeD(epoch)/1.e9;
00282 int fifoFill = 0;
00283
00284 switch (getMessageType()) {
00285 case MSG_HIT:
00286 fifoFill = getNxLtsMsb() - ((getNxTs()>>11)&0x7);
00287 if (getNxLastEpoch()) fifoFill += 8;
00288 snprintf(buf, sizeof(buf),
00289 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00290 os << buf;
00291 snprintf(buf, sizeof(buf),
00292 "HIT @%15.9f Nx:%d Chn:%3d Ts:%5d%s(%2d) Adc:%4d Pu:%d Of:%d",
00293 timeInSec, getNxNumber(), getNxChNum(), getNxTs(),
00294 (getNxLastEpoch() ? "-e" : " "),
00295 fifoFill, getNxAdcValue(), getNxPileup(), getNxOverflow());
00296 os << buf << std::endl;
00297 break;
00298 case MSG_EPOCH:
00299 snprintf(buf, sizeof(buf),
00300 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00301 os << buf;
00302 snprintf(buf, sizeof(buf),
00303 "EPO @%15.9f Epo:%10u 0x%08x Miss: %3d%c",
00304 timeInSec, getEpochNumber(), getEpochNumber(),
00305 getEpochMissed(), (getEpochMissed()==0xff) ? '+' : ' ');
00306 os << buf << std::endl;
00307 break;
00308 case MSG_SYNC:
00309 snprintf(buf, sizeof(buf),
00310 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00311 os << buf;
00312 snprintf(buf, sizeof(buf),
00313 "SYN @%15.9f Chn:%d Ts:%5d%s Data:%8d 0x%06x Flag:%d",
00314 timeInSec, getSyncChNum(), getSyncTs(),
00315 ((getSyncEpochLSB() != (epoch&0x1)) ? "-e" : " "),
00316 getSyncData(), getSyncData(), getSyncStFlag());
00317 os << buf << std::endl;
00318 break;
00319 case MSG_AUX:
00320 snprintf(buf, sizeof(buf),
00321 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00322 os << buf;
00323 snprintf(buf, sizeof(buf),
00324 "AUX @%15.9f Chn:%d Ts:%5d%s Falling:%d Overflow:%d",
00325 timeInSec, getAuxChNum(), getAuxTs(),
00326 ((getAuxEpochLSB() != (epoch&0x1)) ? "-e" : " "),
00327 getAuxFalling(), getAuxOverflow());
00328 os << buf << std::endl;
00329 break;
00330 case MSG_EPOCH2:
00331 snprintf(buf, sizeof(buf),
00332 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00333 os << buf;
00334 snprintf(buf, sizeof(buf),
00335 "EPO2 @%17.11f Get4:%2d Epoche2:%10u 0x%08x StampTime:%2d Sync:%x Dataloss:%x Epochloss:%x Epochmissmatch:%x",
00336 timeInSec, getEpoch2ChipNumber(), getEpoch2Number(), getEpoch2Number(),
00337 getEpoch2StampTime(), getEpoch2Sync(), getEpoch2DataLost(), getEpoch2EpochLost(), getEpoch2EpochMissmatch());
00338 os << buf << std::endl;
00339 break;
00340 case MSG_GET4:
00341 snprintf(buf, sizeof(buf),
00342 "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00343 os << buf;
00344 snprintf(buf, sizeof(buf),
00345 "Get4 @%17.11f Get4:%2d Chn:%3d Edge:%1d Ts:%7d CRC8:%3d",
00346 timeInSec, getGet4Number(), getGet4ChNum(), getGet4Edge(), getGet4Ts(), getGet4CRC() );
00347 os << buf << std::endl;
00348 break;
00349 default:
00350 kind = kind & ~msg_print_Human;
00351 if (kind==0) kind = msg_print_Prefix | msg_print_Data;
00352 }
00353
00354
00355 if (kind & msg_print_Human) return;
00356 }
00357
00358 if (kind & msg_print_Prefix) {
00359 snprintf(buf, sizeof(buf), "Msg:%u Roc:%u ", getMessageType(), getRocNumber());
00360 os << buf;
00361 }
00362
00363 if (kind & msg_print_Data) {
00364 uint8_t* arr = (uint8_t*) &data;
00365 switch (getMessageType()) {
00366 case MSG_NOP:
00367 snprintf(buf, sizeof(buf), "NOP (raw %02X:%02X:%02X:%02X:%02X:%02X)",
00368 arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]);
00369 break;
00370 case MSG_HIT:
00371 snprintf(buf, sizeof(buf), "Nx:%1x Chn:%02x Ts:%04x Last:%1x Msb:%1x Adc:%03x Pup:%1x Oflw:%1x",
00372 getNxNumber(), getNxChNum(), getNxTs(), getNxLastEpoch(),
00373 getNxLtsMsb(), getNxAdcValue(), getNxPileup(),
00374 getNxOverflow());
00375 break;
00376 case MSG_EPOCH:
00377 snprintf(buf, sizeof(buf), "Epoch:%08x Missed:%02x",
00378 getEpochNumber(), getEpochMissed());
00379 break;
00380 case MSG_SYNC:
00381 snprintf(buf, sizeof(buf), "SyncChn:%1x EpochLSB:%1x Ts:%04x Data:%06x Flag:%1x",
00382 getSyncChNum(), getSyncEpochLSB(), getSyncTs(),
00383 getSyncData(), getSyncStFlag());
00384 break;
00385 case MSG_AUX:
00386 snprintf(buf, sizeof(buf), "AuxChn:%02x EpochLSB:%1x Ts:%04x Falling:%1x Overflow:%1x",
00387 getAuxChNum(), getAuxEpochLSB(), getAuxTs(),
00388 getAuxFalling(), getAuxOverflow());
00389 break;
00390 case MSG_EPOCH2:
00391 snprintf(buf, sizeof(buf), "Get4:0x%02x Epoche2:0x%08x StampTime:0x%x Sync:%x Dataloss:%x Epochloss:%x Epochmissmatch:%x",
00392 getEpoch2ChipNumber(), getEpoch2Number(), getEpoch2StampTime(), getEpoch2Sync(), getEpoch2DataLost(), getEpoch2EpochLost(), getEpoch2EpochMissmatch());
00393 break;
00394 case MSG_GET4:
00395 snprintf(buf, sizeof(buf), "Get4:0x%02x Chn:%1x Edge:%1x Ts:0x%05x CRC8:0x%02x",
00396 getGet4Number(), getGet4ChNum(), getGet4Edge(), getGet4Ts(), getGet4CRC() );
00397 break;
00398 case MSG_SYS: {
00399 char sysbuf[256];
00400
00401 switch (getSysMesType()) {
00402 case SYSMSG_DAQ_START:
00403 snprintf(sysbuf, sizeof(sysbuf), "DAQ started");
00404 break;
00405 case SYSMSG_DAQ_FINISH:
00406 snprintf(sysbuf, sizeof(sysbuf), "DAQ finished");
00407 break;
00408 case SYSMSG_NX_PARITY: {
00409 uint32_t data = getSysMesData();
00410 uint32_t nxb3_flg = (data>>31) & 0x01;
00411 uint32_t nxb3_val = (data>>24) & 0x7f;
00412 uint32_t nxb2_flg = (data>>23) & 0x01;
00413 uint32_t nxb2_val = (data>>16) & 0x7f;
00414 uint32_t nxb1_flg = (data>>15) & 0x01;
00415 uint32_t nxb1_val = (data>>8 ) & 0x7f;
00416 uint32_t nxb0_flg = (data>>7 ) & 0x01;
00417 uint32_t nxb0_val = (data ) & 0x7f;
00418 snprintf(sysbuf, sizeof(sysbuf),"Nx:%1x %1d%1d%1d%1d:%02x:%02x:%02x:%02x nX parity error", getNxNumber(),
00419 nxb3_flg, nxb2_flg, nxb1_flg, nxb0_flg,
00420 nxb3_val, nxb2_val, nxb1_val, nxb0_val);
00421 }
00422 break;
00423 case SYSMSG_SYNC_PARITY:
00424 snprintf(sysbuf, sizeof(sysbuf), "SYNC parity error ");
00425 break;
00426 case SYSMSG_DAQ_RESUME:
00427 snprintf(sysbuf, sizeof(sysbuf), "DAQ resume after high/low water");
00428 break;
00429 case SYSMSG_FIFO_RESET:
00430 snprintf(sysbuf, sizeof(sysbuf), "FIFO reset");
00431 break;
00432 case SYSMSG_USER: {
00433 const char* subtyp = "";
00434 if (getSysMesData()==SYSMSG_USER_CALIBR_ON) subtyp = "Calibration ON"; else
00435 if (getSysMesData()==SYSMSG_USER_CALIBR_OFF) subtyp = "Calibration OFF"; else
00436 if (getSysMesData()==SYSMSG_USER_RECONFIGURE) subtyp = "Reconfigure";
00437 snprintf(sysbuf, sizeof(sysbuf), "User message 0x%08x %s", getSysMesData(), subtyp);
00438 break;
00439 }
00440 case SYSMSG_PACKETLOST:
00441 snprintf(sysbuf, sizeof(sysbuf), "Packet lost");
00442 break;
00443 case SYSMSG_GET4_EVENT: {
00444 uint32_t data = getSysMesData();
00445 uint32_t get4_pattern = getField(16, 6);
00446 uint32_t get4_eventType = getBit(22);
00447 uint32_t get4_TS = getField(23,12);
00448 uint32_t get4_chip = getField(40, 8);
00449 if(get4_eventType==1)
00450 snprintf(sysbuf, sizeof(sysbuf),
00451 "Get4:0x%02x TS:0x%03x Pattern:0x%02x - GET4 External Sync Event", get4_chip, get4_TS, get4_pattern);
00452 else
00453 snprintf(sysbuf, sizeof(sysbuf),
00454 "Get4:0x%02x TS:0x%03x ErrCode:0x%02x - GET4 Error Event", get4_chip, get4_TS, get4_pattern);
00455 break;
00456 }
00457 case SYSMSG_CLOSYSYNC_ERROR:
00458 snprintf(sysbuf, sizeof(sysbuf), "Closy synchronization error");
00459 break;
00460 case SYSMSG_TS156_SYNC:
00461 snprintf(sysbuf, sizeof(sysbuf), "156.25MHz timestamp reset");
00462 break;
00463 default:
00464 snprintf(sysbuf, sizeof(sysbuf), "unknown system message type ");
00465 }
00466
00467 snprintf(buf, sizeof(buf), "SysType:%2x Data:%8x : %s", getSysMesType(), getSysMesData(), sysbuf);
00468
00469 break;
00470 }
00471 default:
00472 snprintf(buf, sizeof(buf), "Error - unexpected MessageType: %1x", getMessageType());
00473 }
00474 }
00475
00476 os << buf << std::endl;
00477 }
00478
00479 uint32_t roc::Message::RawSize(int fmt)
00480 {
00481 switch (fmt) {
00482 case formatEth1: return 6;
00483 case formatOptic1: return 8;
00484 case formatEth2: return 6;
00485 case formatOptic2: return 8;
00486 case formatNormal: return 8;
00487 }
00488 return 8;
00489 }
00490
00491 bool roc::Message::assign(void* src, int fmt)
00492 {
00493 switch (fmt) {
00494 case formatEth1:
00495 convertFromOld(src);
00496 return true;
00497 case formatOptic1:
00498 convertFromOld((uint8_t*) src + 2);
00499 setRocNumber((*((uint8_t*) src) << 8) | *((uint8_t*) src + 1) );
00500 return true;
00501 case formatEth2:
00502 memcpy(&data, src, 6);
00503 return true;
00504 case formatOptic2:
00505 memcpy(&data, (uint8_t*) src + 2, 6);
00506 setRocNumber(*((uint16_t*) src));
00507 return true;
00508 case formatNormal:
00509 memcpy(&data, src, 8);
00510 return true;
00511 }
00512
00513 return false;
00514 }
00515
00516 bool roc::Message::copyto(void* tgt, int fmt)
00517 {
00518 switch (fmt) {
00519 case formatEth1:
00520 convertToOld(tgt);
00521 return true;
00522 case formatOptic1:
00523 convertToOld((uint8_t*) tgt + 2);
00524 *((uint16_t*) tgt) = getRocNumber();
00525 return true;
00526 case formatEth2:
00527 memcpy(tgt, &data, 6);
00528 return true;
00529 case formatOptic2:
00530 memcpy((uint8_t*) tgt + 2, &data, 6);
00531 *((uint16_t*) tgt) = getRocNumber();
00532 return true;
00533 case formatNormal:
00534 memcpy(tgt, &data, 8);
00535 return true;
00536 }
00537
00538 return false;
00539
00540 }