00001 #include <sys/types.h>
00002 #include <errno.h>
00003 #include <assert.h>
00004 #include <stdlib.h>
00005
00006 #include <rtsLog.h>
00007 #include <rtsSystems.h>
00008
00009
00010
00011 #include <SFS/sfs_index.h>
00012 #include <DAQ_READER/daqReader.h>
00013 #include <DAQ_READER/daq_dta.h>
00014
00015
00016 #include "daq_fgt.h"
00017
00018
00019 const char *daq_fgt::help_string = "FGT\n\
00020 adc returns fgt_t;\n\
00021 raw returns raw data\n" ;
00022
00023 class daq_det_fgt_factory : public daq_det_factory
00024 {
00025 public:
00026 daq_det_fgt_factory() {
00027 daq_det_factory::det_factories[FGT_ID] = this ;
00028 }
00029
00030 daq_det *create() {
00031 return new daq_fgt ;
00032 }
00033 } ;
00034
00035 static daq_det_fgt_factory fgt_factory ;
00036
00037
00038 daq_fgt::daq_fgt(daqReader *rts_caller)
00039 {
00040 rts_id = FGT_ID ;
00041 name = rts2name(rts_id) ;
00042 sfs_name = "fgt" ;
00043 caller = rts_caller ;
00044
00045 if(caller) caller->insert(this, rts_id) ;
00046
00047 raw = new daq_dta ;
00048 adc = new daq_dta ;
00049 phys = new daq_dta ;
00050 ped = new daq_dta ;
00051
00052 #if 0
00053
00054 memset(adc_to_phys,0xff,sizeof(adc_to_phys)) ;
00055 memset(phys_to_adc,0xff,sizeof(phys_to_adc)) ;
00056
00057
00058 #endif
00059
00060 LOG(DBG,"%s: constructor: caller %p",name,rts_caller) ;
00061 return ;
00062 }
00063
00064 daq_fgt::~daq_fgt()
00065 {
00066 LOG(DBG,"%s: DEstructor",name) ;
00067
00068 delete raw ;
00069 delete adc ;
00070 delete phys ;
00071 delete ped ;
00072
00073 return ;
00074 }
00075
00076
00077
00078 daq_dta *daq_fgt::get(const char *bank, int sec, int rdo, int pad, void *p1, void *p2)
00079 {
00080 Make() ;
00081
00082 if(present == 0) return 0 ;
00083
00084
00085 if(strcasecmp(bank,"raw")==0) {
00086 return handle_raw(rdo) ;
00087 }
00088 else if(strcasecmp(bank,"adc")==0) {
00089 return handle_adc(rdo,0) ;
00090 }
00091 else if(strcasecmp(bank,"phys")==0) {
00092 return handle_phys(sec,rdo,pad) ;
00093 }
00094 else if(strcasecmp(bank,"pedrms")==0) {
00095 return handle_ped(rdo) ;
00096 }
00097
00098
00099 LOG(ERR,"%s: unknown bank type \"%s\"",name,bank) ;
00100 return 0 ;
00101 }
00102
00103
00104
00105 daq_dta *daq_fgt::handle_raw(int rdo)
00106 {
00107 char *st ;
00108 int r_start, r_stop ;
00109 int bytes ;
00110
00111 assert(caller) ;
00112
00113 if(!present) {
00114 return 0 ;
00115 }
00116 else {
00117 LOG(DBG,"%s: present %d",name,present) ;
00118 }
00119
00120 char str[256] ;
00121 char *full_name ;
00122
00123
00124 if(rdo<=0) {
00125 r_start = 1 ;
00126 r_stop = 2 ;
00127 }
00128 else {
00129 r_start = r_stop = rdo ;
00130 }
00131
00132
00133 raw->create(8*1024,"fgt_raw",rts_id,DAQ_DTA_STRUCT(char)) ;
00134
00135 for(int r=r_start;r<=r_stop;r++) {
00136 sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, 1, r) ;
00137 full_name = caller->get_sfs_name(str) ;
00138
00139 if(!full_name) continue ;
00140 bytes = caller->sfs->fileSize(full_name) ;
00141
00142
00143 st = (char *) raw->request(bytes) ;
00144
00145 int ret = caller->sfs->read(str, st, bytes) ;
00146 if(ret != bytes) {
00147 LOG(ERR,"ret is %d") ;
00148 }
00149
00150
00151 raw->finalize(bytes,0,r,0) ;
00152 }
00153
00154 raw->rewind() ;
00155
00156 return raw ;
00157
00158 }
00159
00160
00161
00162 daq_dta *daq_fgt::handle_adc(int rdo, char *rdobuff)
00163 {
00164 int r_start, r_stop ;
00165
00166
00167 adc->create(1000,"fgt_adc",rts_id,DAQ_DTA_STRUCT(fgt_adc_t)) ;
00168
00169 LOG(NOTE,"FGT: doing ADC") ;
00170
00171 if((rdo <= 0) || (rdo > FGT_RDO_COU)){
00172 r_start = 1 ;
00173 r_stop = FGT_RDO_COU ;
00174 }
00175 else {
00176 r_start = r_stop = rdo ;
00177 }
00178
00179
00180
00181 for(int r=r_start;r<=r_stop;r++) {
00182 u_int *d ;
00183
00184 if(rdobuff == 0) {
00185 daq_dta *dd = handle_raw(r) ;
00186 if(dd == 0) continue ;
00187
00188 if(dd->iterate() == 0) continue ;
00189
00190 d = (u_int *) dd->Void ;
00191 int words = dd->ncontent/4 ;
00192
00193 if(words <= 0) continue ;
00194
00195 }
00196 else {
00197 d = (u_int *) rdobuff ;
00198 }
00199
00200
00201
00202 int format_code = (d[2] >> 8) & 0xFF ;
00203
00204
00205
00206
00207 int arm_mask = (d[3] >> 8) & 0x3F ;
00208 LOG(NOTE,"[evt %d]: RDO %d: ARC Header: format %d, ARM mask 0x%02x",get_global_event_num(),r,format_code,arm_mask);
00209
00210 u_int *dta = d + 6 ;
00211
00212 for(int arm=0;arm<6;arm++) {
00213 if(arm_mask & (1<<arm)) ;
00214 else continue ;
00215
00216 LOG(NOTE,"[evt %d]: RDO %d: Handling ARM %d",get_global_event_num(),r) ;
00217
00218
00219 int arm_id = *dta & 0x7 ;
00220 int arm_seq = (*dta >> 20) & 0xfff;
00221 int arm_err = (*dta >>16) & 0xf;
00222 dta++ ;
00223
00224 u_int apv_mask = *dta & 0x00FFFFFF ;
00225 dta++ ;
00226
00227 dta++ ;
00228
00229 LOG(NOTE,"[evt %d]: ARM_ID %d SEQ %d ERR %1x APV_MASK %06x",get_global_event_num(),
00230 arm_id,arm_seq,arm_err,apv_mask);
00231
00232 if(arm_id != arm) {
00233 LOG(ERR,"[evt %d]: RDO %d ARM %d: Bad ARM ID is %d",get_global_event_num(),r,arm,arm_id) ;
00234 goto unrecoverable_error ;
00235 }
00236
00237 if(arm_err != 0) {
00238 LOG(ERR,"[evt %d]: RDO %d ARM %d: Error code 0x%x",get_global_event_num(),r,arm,arm_err) ;
00239 continue ;
00240 }
00241
00242
00243 for(int apv=0;apv<24;apv++) {
00244 if(apv_mask & (1<<apv)) ;
00245 else continue ;
00246
00247 LOG(NOTE,"[evt %d]: Handling APV %d",get_global_event_num(),apv) ;
00248
00249 int apv_id = *dta & 0x1F ;
00250 int length = (*dta >> 5) & 0x3FF ;
00251 int fmt = (*dta >> 16) & 0xf ;
00252 int seq = (*dta >> 20) & 0xfff;
00253
00254 dta++ ;
00255
00256 LOG(NOTE," ID %d, length %d, fmt %d",apv_id,length,fmt) ;
00257
00258 int capid = *dta & 0xFF ;
00259 int nhits = (*dta >> 8) & 0x7F ;
00260 int is_error = (*dta >> 15) & 1 ;
00261 int refadc = (*dta >> 16) & 0xFFF ;
00262 int ntim = (*dta >> 28) & 0x7 ;
00263 int is_0 = *dta & 0x80000000 ;
00264
00265 dta++ ;
00266
00267 nhits = ( ntim>0 ? nhits+1 : 0 );
00268
00269 LOG(NOTE," capid %d, nhits %d, is_error 0x%X, refadc %d, ntim %d, is_0 0x%X",
00270 capid, nhits, is_error, refadc, ntim, is_0) ;
00271
00272
00273
00274 if(apv != apv_id) {
00275 LOG(ERR,"[evt %d]: RDO %d ARM %d APV %d: Bad APV ID, got %d",get_global_event_num(),r,arm,apv,apv_id) ;
00276 goto unrecoverable_error ;
00277 }
00278
00279 if(seq != arm_seq) {
00280
00281 #if 0
00282 LOG(WARN,"[evt %d]: RDO %d ARM %d APV %d: Sequence number mismatch, expect %d have %d",get_global_event_num(),r,arm,apv,arm_seq,seq);
00283 #else
00284 LOG(ERR,"[evt %d]: RDO %d ARM %d APV %d: Sequence number mismatch, expect %d have %d",get_global_event_num(),r,arm,apv,arm_seq,seq);
00285 goto unrecoverable_error ;
00286 #endif
00287 }
00288
00289 if((ntim <= 0) || (ntim > 7)) {
00290 LOG(ERR,"Ntim %d ?!",ntim) ;
00291 continue ;
00292 }
00293 if(fmt != 1) {
00294 LOG(ERR,"FMT %d != 1 (evt %d)",fmt,get_global_event_num()) ;
00295 continue ;
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305 if (length==2)
00306 continue;
00307 if (apv==23) {
00308 dta += 3;
00309 continue;
00310 }
00311 u_long expect0 = *(dta-2);
00312 expect0 = (expect0 & 0xffffffe0)|((expect0+1) & 0x0000001f);
00313 u_long expect1 = *(dta-1);
00314
00315
00316 if((*(dta+3)==expect0) && (*(dta+4)==expect1)) {
00317 dta += 3 ;
00318 continue ;
00319 }
00320
00321
00322
00323 fgt_adc_t *fgt_d = (fgt_adc_t *) adc->request(FGT_TB_COU*FGT_CH_COU) ;
00324 int cou = 0 ;
00325
00326
00327
00328
00329 u_short *d16 = (u_short *) dta ;
00330 u_short wfm[2720] ;
00331 int i = 0 ;
00332
00333
00334 for(int j=0;j<((length-2)/3)*2;j++) {
00335 u_short wtmp ;
00336
00337 wfm[4*j] = 0x0fff & d16[i] ;
00338
00339 wtmp = 0x000f & (d16[i++] >> 12) ;
00340
00341 wfm[4*j + 1] = (0x0ff0 & (d16[i]<<4)) | wtmp ;
00342
00343 wtmp = 0x00ff & (d16[i++] >> 8) ;
00344
00345 wfm[4*j+2] = (0x0f00 & (d16[i]<<8)) | wtmp ;
00346 wfm[4*j+3] = 0x0fff & (d16[i++]>>4) ;
00347 }
00348
00349 dta += (length - 2) ;
00350
00351
00352
00353
00354
00355
00356
00357
00358 if ( 27+127+(ntim-1)*140 >= ((length-2)/3)*8 ) {
00359 LOG(ERR,"[evt %d]: RDO %d ARM %d APV %d: Trouble in APV block content, it's shorter than required to unpack %d timebins",
00360 get_global_event_num(),r,arm,apv,ntim);
00361 continue;
00362 }
00363 for(int ch=0;ch<128;ch++) {
00364 int rch = 32*(ch%4) + 8*(ch/4) - 31*(ch/16) ;
00365 for(int tb=0;tb<ntim;tb++) {
00366
00367 int adc = wfm[27+ch+tb*140] ;
00368 fgt_d[cou].ch = rch ;
00369 fgt_d[cou].tb = tb ;
00370 fgt_d[cou].adc = adc ;
00371 cou++ ;
00372 }
00373 }
00374
00375
00376 adc->finalize(cou, arm, r, apv) ;
00377
00378 }
00379
00380 }
00381 continue;
00382 unrecoverable_error:
00383 LOG(WARN,"[evt %d]: RDO %d: Cannot reliably recover pointer to next item, dropping the rest of this event on this rdo");
00384 }
00385
00386 adc->rewind() ;
00387
00388 return adc ;
00389
00390 }
00391
00392 daq_dta *daq_fgt::handle_ped(int rdo)
00393 {
00394
00395 int r_start, r_stop ;
00396
00397
00398 LOG(NOTE,"FGT PED is not yet supported") ;
00399 return 0 ;
00400
00401 ped->create(1000,"fgt_pedrms",rts_id,DAQ_DTA_STRUCT(fgt_pedrms_t)) ;
00402
00403
00404
00405 if((rdo <= 0) || (rdo > FGT_RDO_COU)){
00406 r_start = 1 ;
00407 r_stop = FGT_RDO_COU ;
00408 }
00409 else {
00410 r_start = r_stop = rdo ;
00411 }
00412
00413
00414
00415 for(int r=r_start;r<=r_stop;r++) {
00416 for(int arm=0;arm<FGT_ARM_COU;arm++) {
00417 for(int apv=0;apv<FGT_APV_COU;apv++) {
00418
00419 fgt_pedrms_t *d = (fgt_pedrms_t *) ped->request(FGT_TB_COU*FGT_CH_COU) ;
00420
00421 int cou = 0 ;
00422
00423 for(int tb=0;tb<FGT_TB_COU;tb++) {
00424 for(int ch=0;ch<FGT_CH_COU;ch++) {
00425
00426 d[cou].ch = ch ;
00427 d[cou].tb = tb ;
00428 d[cou].ped = drand48() * 1024.0 ;
00429 d[cou].rms = 1.0/((double)(ch+1)) ;
00430 cou++ ;
00431
00432 }
00433 }
00434
00435 ped->finalize(cou,r,arm,apv) ;
00436
00437 }
00438 }
00439 }
00440
00441 ped->rewind() ;
00442
00443 return ped ;
00444
00445
00446
00447 }
00448
00449
00450 daq_dta *daq_fgt::handle_phys(int disk, int quadrant, int strip_type)
00451 {
00452
00453 return 0 ;
00454
00455 LOG(WARN,"FGT PHYS not yet supported....") ;
00456 return 0 ;
00457 }
00458
00459
00460
00461 int daq_fgt::get_l2(char *buff, int words, struct daq_trg_word *trg, int rdo)
00462 {
00463 const int FGT_BYTES_MIN = ((6)*4) ;
00464 const int FGT_BYTES_MAX = (32768*4) ;
00465 const u_int FGT_VERSION = 0x0034 ;
00466 const u_int FGT_SIGNATURE = 0x46475420 ;
00467
00468 int t_cou = 0 ;
00469 int bad = 0 ;
00470 u_int *d32 = (u_int *)buff ;
00471 int id_check_failed = 0 ;
00472
00473
00474 int buff_bytes = 4 * words ;
00475
00476 if((buff_bytes < FGT_BYTES_MIN) || (buff_bytes > FGT_BYTES_MAX)) {
00477 LOG(ERR,"RDO %d: expect %d bytes, received %d",rdo,FGT_BYTES_MIN,buff_bytes) ;
00478 bad |= 1 ;
00479 }
00480
00481
00482
00483
00484
00485 if(d32[1] != FGT_SIGNATURE) {
00486 LOG(ERR,"RDO %d: bad header sig 0x%08X, expect 0x%08X",rdo,d32[1], FGT_SIGNATURE) ;
00487 bad |= 1 ;
00488 }
00489
00490 if(d32[5] != 0xFEEDBEEF) {
00491 LOG(ERR,"RDO %d: bad deadface 0x%08X",rdo,d32[9]) ;
00492 bad |= 1 ;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 if((d32[3] & 0xFFFF0000)) {
00505 LOG(ERR,"RDO %d: error flags 0x%04X",rdo,d32[3]>>16) ;
00506 bad |= 2 ;
00507 }
00508
00509
00510
00511
00512
00513 int rdo_in_dta = d32[3] & 0xFF ;
00514 if(rdo_id[rdo] != 0xFF) {
00515 if(rdo_id[rdo] != rdo_in_dta) {
00516 id_check_failed++ ;
00517 }
00518 }
00519
00520
00521
00522 LOG(DBG,"RDO %d: in data %d",rdo,rdo_in_dta) ;
00523
00524
00525 int format_code = (d32[2] >> 8) & 0xFF ;
00526 if(format_code == 0x02) {
00527 LOG(WARN,"RDO %d: format code 0x%X? (null event)",rdo,format_code) ;
00528
00529
00530
00531
00532
00533
00534
00535
00536 }
00537
00538 #if 0
00539 #define G_CONST 0x04C11DB7
00540 int last_ix = words - 1 ;
00541 u_int crc_in_data = d32[last_ix] ;
00542 register u_int crc = 0xFFFFFFFF ;
00543 if(crc_in_data) {
00544 for(int i=0;i<last_ix;i++) {
00545 u_int datum ;
00546
00547 datum = d32[i] ;
00548 register u_int data_j ;
00549 register u_int crc_31 ;
00550
00551 for(register int j=31;j>=0;j--) {
00552 data_j = (datum >> j) & 1 ;
00553 crc_31 = (crc & 0x80000000) ? 1 : 0 ;
00554
00555 if(crc_31 == data_j) {
00556 crc = (crc<<1) ^ G_CONST ;
00557 }
00558 else {
00559 crc = (crc<<1) ;
00560 }
00561 }
00562 }
00563
00564 if(crc != crc_in_data) {
00565 LOG(ERR,"RDO %d: CRC in data 0x%08X, CRC calculated 0x%08X",rdo,crc_in_data,crc) ;
00566 bad |= 1 ;
00567 }
00568 }
00569
00570 LOG(DBG,"RDO %d: CRC in data 0x%08X, CRC calculated 0x%08X",rdo,crc_in_data,crc) ;
00571 #endif
00572
00573
00574
00575 t_cou = 0 ;
00576 trg[t_cou].t = d32[0] & 0xFFF ;
00577 trg[t_cou].daq = d32[2] & 0xF ;
00578 trg[t_cou].trg = (d32[2] >> 4) & 0xF ;
00579 trg[t_cou].rhic = d32[4] ;
00580 t_cou++ ;
00581
00582
00583 LOG(NOTE,"RDO %d: words %d: token %d, trg %d, daq %d: rhic %u: rdo_in_data %d, format_code 0x%X",rdo,words,
00584 trg[0].t, trg[0].trg, trg[0].daq, trg[0].rhic,
00585 rdo_in_dta,format_code) ;
00586
00587
00588
00589 if(trg[0].t == 0) {
00590 LOG(ERR,"RDO %d: token 0?",rdo) ;
00591 trg[0].t = 4097 ;
00592 bad |= 2 ;
00593 }
00594
00595 switch(trg[0].trg) {
00596 case 4 :
00597 break ;
00598 default :
00599 LOG(ERR,"RDO %d: bad trg_cmd %d",rdo, trg[0].trg) ;
00600
00601 trg[0].t = 4097 ;
00602 bad |= 2 ;
00603 break ;
00604 }
00605
00606 #if 0 // skip for the temporary 0x8129 V
00607
00608
00609 int mesg_length = d32[last_ix-1] & 0xFFF ;
00610 if(mesg_length > 30) {
00611 LOG(ERR,"RDO %d: bad trigger length %d",rdo,mesg_length) ;
00612
00613 mesg_length = 0 ;
00614 bad |= 2 ;
00615 }
00616
00617 for(int i=0;i<mesg_length;i++) {
00618 u_int trg_data = d32[last_ix - 2 - i] ;
00619
00620
00621
00622 trg[t_cou].t = (trg_data >> 8) & 0xFFF ;
00623 trg[t_cou].trg = (trg_data >> 4) & 0xF ;
00624 trg[t_cou].daq = trg_data & 0xF ;
00625 trg[t_cou].rhic = (trg_data >> 20) & 0x7FF ;
00626
00627
00628
00629 if(trg_data & 0x80000000) {
00630 LOG(ERR,"RDO %d: FIFO limit 0x%08X",rdo,trg_data) ;
00631 bad |= 2 ;
00632 }
00633
00634
00635
00636 if(t_cou >= 120) {
00637 LOG(ERR,"RDO %d: too many triggers %d",rdo,t_cou) ;
00638 bad |= 2 ;
00639 break ;
00640 }
00641
00642 t_cou++ ;
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 #endif
00654
00655
00656
00657 if(bad) {
00658 LOG(WARN,"RDO %d: words %d: bad %d:",rdo,words,bad) ;
00659
00660 for(int i=0;i<10;i++) {
00661 LOG(WARN,"\tRDO %d: %4d: 0x%08X",rdo,i,d32[i]) ;
00662 }
00663
00664 for(int i=(words-4);i<words;i++) {
00665 LOG(WARN,"\tRDO %d: %4d: 0x%08X",rdo,i,d32[i]) ;
00666 }
00667
00668 }
00669 else if(trg[0].trg==11) {
00670 int bad_cou = 0;
00671 int shutup = 0 ;
00672 for(int i=10;i<2410;i++) {
00673 u_int should ;
00674 u_int b31, b21, b1, b0 ;
00675
00676 b31 = (t_data >> 31) & 1 ;
00677 b21 = (t_data >> 21) & 1 ;
00678 b1 = (t_data >> 1) & 1 ;
00679 b0 = (t_data >> 0) & 1 ;
00680
00681 should = !(b31 ^ b21 ^ b1 ^b0) ;
00682 should = (t_data << 1) | should ;
00683
00684 if(d32[i] != t_data) {
00685 if(!shutup) LOG(WARN,"word %4d: should 0x%08X, is 0x%08X",i,t_data,d32[i]) ;
00686 bad_cou++ ;
00687 }
00688
00689 if(bad_cou > 2) shutup = 1 ;
00690
00691 should = !(b31 ^ b21 ^ b1 ^b0) ;
00692 should = (t_data << 1) | should ;
00693
00694 t_data = should ;
00695
00696 }
00697
00698 if(bad_cou) LOG(ERR,"RDO %d: bad locations %d",rdo,bad_cou) ;
00699 }
00700
00701 if(bad & 1) {
00702 return 0 ;
00703 }
00704 else {
00705
00706 if(id_check_failed) {
00707 rdo_warns[rdo]++ ;
00708 if(rdo_warns[rdo] < 5) {
00709 LOG(CAUTION,"RDO %d: rdo check failed: expect 0x%02X, found 0x%02X",
00710 rdo,rdo_id[rdo],rdo_in_dta) ;
00711 }
00712 }
00713
00714
00715 rdo_warns[rdo]++ ;
00716 if(rdo_warns[rdo]<2) {
00717 LOG(NOTE,"RDO %d: rdo check: expect 0x%02X, found 0x%02X",
00718 rdo,rdo_id[rdo],rdo_in_dta) ;
00719 }
00720
00721
00722 return t_cou ;
00723 }
00724 }
00725
00726