00001 #include <sys/types.h>
00002 #include <errno.h>
00003 #include <assert.h>
00004
00005 #include <rtsLog.h>
00006 #include <rtsSystems.h>
00007
00008 #include <SFS/sfs_index.h>
00009 #include <DAQ_READER/daq_dta.h>
00010 #include <DAQ_READER/daqReader.h>
00011
00012 #include "daq_pp2pp.h"
00013
00014
00015
00016 class daq_det_pp2pp_factory : public daq_det_factory
00017 {
00018 public:
00019 daq_det_pp2pp_factory() {
00020 daq_det_factory::det_factories[PP_ID] = this ;
00021 }
00022
00023 daq_det *create() {
00024 return new daq_pp2pp ;
00025 }
00026 } ;
00027
00028 static daq_det_pp2pp_factory pp2pp_factory ;
00029
00030
00031
00032 const char *daq_pp2pp::help_string = "\
00033 \n\
00034 PP2PP Help: \n\
00035 Supported Banks: \n\
00036 raw returns=ptr of start of DDL data; c1=pp[1..2]; \n\
00037 adc returns=ptr of ADC data; c1=pp[1..2]; \n\
00038 \n\
00039 \n\
00040 " ;
00041
00042
00043
00044 daq_pp2pp::daq_pp2pp(daqReader *rts_caller)
00045 {
00046 rts_id = PP_ID ;
00047 name = rts2name(rts_id) ;
00048 sfs_name = "pp2pp" ;
00049 caller = rts_caller ;
00050 #ifndef PP_MVME
00051 if(caller) caller->insert(this, rts_id) ;
00052 #endif
00053
00054 raw = new daq_dta ;
00055 adc = new daq_dta ;
00056
00057
00058 LOG(DBG,"%s: constructor: caller %p, endianess %d",name,rts_caller,endianess) ;
00059 return ;
00060 }
00061
00062 daq_pp2pp::~daq_pp2pp()
00063 {
00064 LOG(DBG,"%s: Destructor",name) ;
00065 if(raw) delete raw ;
00066 if(adc) delete adc ;
00067
00068 return ;
00069 }
00070
00071
00072
00073 daq_dta *daq_pp2pp::get(const char *bank, int sec, int row, int pad, void *p1, void *p2)
00074 {
00075 Make() ;
00076 if(!present) return 0 ;
00077
00078
00079 LOG(DBG,"%s: looking for bank %s",name,bank) ;
00080
00081 if(strcasecmp(bank,"raw")==0) {
00082 return handle_raw(sec,row) ;
00083 }
00084 else if(strcasecmp(bank,"adc")==0) {
00085 return handle_adc(sec, row) ;
00086 }
00087 else {
00088 LOG(ERR,"%s: unknown bank type \"%s\"",name,bank) ;
00089 }
00090
00091 return 0 ;
00092 }
00093
00094 daq_dta *daq_pp2pp::handle_adc(int sec, int rdo)
00095 {
00096 int min_sec, max_sec ;
00097 int found_some = 0 ;
00098
00099
00100 if(sec==-1) {
00101 min_sec = 1 ;
00102 max_sec = MAX_SEC ;
00103 }
00104 else if((sec<0) || (sec>MAX_SEC)) return 0 ;
00105 else {
00106 min_sec = max_sec = sec ;
00107 }
00108
00109 adc->create(1,"pp2pp_t",rts_id,DAQ_DTA_STRUCT(pp2pp_t)) ;
00110
00111 for(int i=min_sec;i<=max_sec;i++) {
00112 daq_dta *sec_dta ;
00113
00114 sec_dta = handle_raw(i, -1) ;
00115 if(sec_dta == 0) continue ;
00116
00117 int ret = sec_dta->iterate() ;
00118 if(ret == 0) continue ;
00119
00120
00121 found_some = 1 ;
00122 LOG(NOTE,"pp2pp adc: sector %d, words %d",i,sec_dta->ncontent) ;
00123
00124
00125 ret = decode(i,(char *)sec_dta->Void, sec_dta->ncontent) ;
00126 if(ret < 0) {
00127 LOG(ERR,"pp2pp_decode failed for sector %d",i) ;
00128 continue ;
00129 }
00130 }
00131
00132 adc->rewind() ;
00133
00134 if(found_some) return adc ;
00135 else return 0 ;
00136 }
00137
00138
00139 daq_dta *daq_pp2pp::handle_raw(int sec, int rdo)
00140 {
00141 char str[128] ;
00142 char *full_name ;
00143 int found_some = 0 ;
00144
00145 int tot_bytes ;
00146 int min_rdo, max_rdo ;
00147 int min_sec, max_sec ;
00148 struct {
00149 int sec ;
00150 int rb ;
00151 u_int bytes ;
00152 } obj[MAX_SEC*(MAX_RDO+1)] ;
00153
00154
00155 if(sec==-1) {
00156 min_sec = 1 ;
00157 max_sec = MAX_SEC ;
00158 }
00159 else if((sec<0) || (sec>MAX_SEC)) return 0 ;
00160 else {
00161 min_sec = max_sec = sec ;
00162 }
00163
00164 if(rdo==-1) {
00165 min_rdo = 0 ;
00166 max_rdo = 0 ;
00167 }
00168 else if((rdo<0) || (rdo>MAX_RDO)) return 0 ;
00169 else {
00170 min_rdo = max_rdo = rdo ;
00171 }
00172
00173 #ifdef PP_MVME
00174 return 0 ;
00175 #else
00176
00177 assert(caller) ;
00178
00179
00180 tot_bytes = 0 ;
00181 int o_cou = 0 ;
00182 for(int s=min_sec;s<=max_sec;s++) {
00183 for(int r=min_rdo;r<=max_rdo;r++) {
00184
00185 sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, s, r) ;
00186 full_name = caller->get_sfs_name(str) ;
00187 if(!full_name) continue ;
00188
00189 LOG(DBG,"%s: trying sfs on \"%s\"",name,str) ;
00190
00191 int size = caller->sfs->fileSize(str) ;
00192
00193 LOG(DBG,"Got %d",size) ;
00194
00195 if(size <= 0) {
00196 LOG(NOTE,"%s: %s: not found in this event",name,str) ;
00197 continue ;
00198 }
00199 else {
00200 obj[o_cou].sec = s ;
00201 obj[o_cou].rb = r ;
00202 obj[o_cou].bytes = size ;
00203
00204 o_cou++ ;
00205
00206 tot_bytes += size ;
00207 found_some = 1 ;
00208 LOG(NOTE,"%s: %s: reading in \"%s\": bytes %d",name,str,"raw", size) ;
00209 }
00210 }
00211 }
00212
00213 if(o_cou == 0) return 0 ;
00214
00215 raw->create(tot_bytes,"pp2pp_raw",rts_id,DAQ_DTA_STRUCT(u_char)) ;
00216
00217 for(int i=0;i<o_cou;i++) {
00218
00219 sprintf(str,"%s/sec%02d/rb%02d/raw",sfs_name, obj[i].sec, obj[i].rb) ;
00220 full_name = caller->get_sfs_name(str) ;
00221 if(!full_name) continue ;
00222
00223 char *mem = (char *)raw->request(obj[i].bytes) ;
00224
00225 int ret = caller->sfs->read(full_name, mem, obj[i].bytes) ;
00226
00227 if(ret != (int)obj[i].bytes) {
00228 LOG(ERR,"%s: %s: read failed, expect %d, got %d [%s]",name,str,
00229 obj[i].bytes,ret,strerror(errno)) ;
00230 }
00231 else {
00232 LOG(NOTE,"%s: %s read %d bytes",name,str,ret) ;
00233
00234 }
00235
00236 raw->finalize(obj[i].bytes, obj[i].sec, obj[i].rb, 0) ;
00237
00238 }
00239
00240
00241 raw->rewind() ;
00242
00243 if(found_some) return raw ;
00244 else return 0 ;
00245 #endif
00246 }
00247
00248 int daq_pp2pp::get_token(char *addr, int words)
00249 {
00250 int cou ;
00251 struct daq_trg_word trg[8] ;
00252
00253 cou = get_l2(addr,words,trg,1) ;
00254
00255 if(cou==0) return -1000 ;
00256 if(trg[0].t==0) return -ENOSYS ;
00257
00258 return trg[0].t ;
00259 }
00260
00261
00262 int daq_pp2pp::get_l2(char *addr, int words, struct daq_trg_word *trgs, int prompt)
00263 {
00264 u_int *d = (u_int *)addr ;
00265 int t_cou = 0 ;
00266 u_int datum ;
00267 int trg_cou ;
00268 u_int *trg_dta ;
00269
00270
00271 if(prompt) {
00272 LOG(DBG,"words %d: dta 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",words,d[0],d[1],d[2],d[3],d[4]) ;
00273
00274 }
00275
00276 trg_cou = d[words-1] ;
00277
00278 trg_dta = &(d[words-1-trg_cou]) ;
00279
00280 for(int i=0;i<trg_cou;i++) {
00281 datum = trg_dta[i] ;
00282
00283 if((datum & 0xFF000000) == 0xEE000000) {
00284
00285 trgs[t_cou].t = (datum&0xF00) | ((datum & 0xF000)>>8) | ((datum & 0xF0000)>>16);
00286 trgs[t_cou].daq = (datum>>4) & 0xF ;
00287 trgs[t_cou].trg = datum & 0xF ;
00288 trgs[t_cou].rhic = 0 ;
00289 trgs[t_cou].rhic_delta = 0 ;
00290
00291 if(prompt) {
00292 LOG(NOTE,"T %4d (prompt): daq %d, trg %d",trgs[t_cou].t,trgs[t_cou].daq,trgs[t_cou].trg) ;
00293 }
00294
00295 t_cou++ ;
00296 break ;
00297 }
00298
00299 }
00300
00301 if(t_cou == 0) {
00302
00303 trgs[t_cou].t = 4097 ;
00304 trgs[t_cou].daq = 0 ;
00305 trgs[t_cou].trg = 5 ;
00306 trgs[t_cou].rhic = 0 ;
00307 trgs[t_cou].rhic_delta = 0 ;
00308
00309 if(prompt) {
00310 LOG(NOTE,"T %4d (no data): daq %d, trg %d",trgs[t_cou].t,trgs[t_cou].daq,trgs[t_cou].trg) ;
00311 }
00312
00313 t_cou++ ;
00314
00315
00316 }
00317
00318 for(int i=0;i<trg_cou;i++) {
00319 datum = trg_dta[i] ;
00320
00321 if((datum & 0xFF000000) != 0xEE000000) {
00322
00323 trgs[t_cou].t = (datum&0xF00) | ((datum & 0xF000)>>8) | ((datum & 0xF0000)>>16);
00324 trgs[t_cou].daq = (datum>>4) & 0xF ;
00325 trgs[t_cou].trg = datum & 0xF ;
00326 trgs[t_cou].rhic = 1 ;
00327 trgs[t_cou].rhic_delta = 1 ;
00328
00329 if(prompt) {
00330 LOG(NOTE,"T %4d (FIFO): daq %d, trg %d",trgs[t_cou].t,trgs[t_cou].daq,trgs[t_cou].trg) ;
00331 }
00332
00333
00334
00335 switch(trgs[t_cou].trg) {
00336 case 13 :
00337 case 15 :
00338 break ;
00339 default :
00340 continue ;
00341 }
00342
00343 if(trgs[t_cou].t == 0) {
00344 LOG(ERR,"T %4d (FIFO): daq %d, trg %d -- token 0, skipping",trgs[t_cou].t,trgs[t_cou].daq,trgs[t_cou].trg) ;
00345 }
00346 else {
00347 t_cou++ ;
00348 }
00349 }
00350
00351 }
00352
00353
00354
00355 return t_cou ;
00356 }
00357
00358
00359
00360
00361 int daq_pp2pp::decode(int sec_id, char *raw, int bytes)
00362 {
00363 u_int *d32 ;
00364 u_short *d16 ;
00365 u_short seq[2], trg[2] ;
00366 u_char *d8 ;
00367 int ret = 0 ;
00368
00369 int seq_id, chain_id, svx_id ;
00370
00371 int words = bytes/4 ;
00372
00373
00374 d32 = (u_int *) raw ;
00375 d16 = (u_short *) raw ;
00376
00377 for(int i=0;i<bytes/4;i++) {
00378 LOG(DBG,"pp2pp data: %2d: 0x%08X",i,b2h32(d32[i])) ;
00379 }
00380
00381 int trg_cou = b2h32(d32[words-1]) ;
00382 int trg_ix = words - 1 - trg_cou ;
00383
00384 for(int i=0;i<trg_cou;i++) {
00385 LOG(NOTE,"pp2pp: trg %d/%d: 0x%08X",i+1,trg_cou,b2h32(d32[trg_ix+i])) ;
00386 }
00387
00388
00389 int w16 = 2 * (words - trg_cou - 1) ;
00390
00391 LOG(DBG,"16bit words left: %d",w16) ;
00392
00393 int cur_ix = 0 ;
00394 int next_good_ix = 0 ;
00395
00396 int bunch_xing = -1 ;
00397 u_int trigger = 0xFFFFFFFF ;
00398
00399 int not_sparse = 0 ;
00400
00401 while(cur_ix < w16) {
00402 struct pp2pp_t *d = 0 ;
00403 int requested = 0 ;
00404
00405 int i ;
00406
00407
00408 seq[0] = b2h16(d16[cur_ix]) ;
00409 cur_ix++ ;
00410 seq[1] = b2h16(d16[cur_ix]) ;
00411 cur_ix++ ;
00412
00413
00414 trg[0] = b2h16(d16[cur_ix]) ;
00415 cur_ix++ ;
00416 trg[1] = b2h16(d16[cur_ix]) ;
00417 cur_ix++ ;
00418
00419 seq_id = (seq[0] >> 8) >> 2 ;
00420 chain_id = (seq[0] >> 8) & 3 ;
00421
00422
00423 if(trigger == 0xFFFFFFFF) {
00424 trigger = (trg[1] << 16) | trg[0] ;
00425 }
00426 else {
00427 u_int tmp = (trg[1] << 16) | trg[0] ;
00428
00429 if(tmp != trigger) {
00430 ret |= 1 ;
00431 LOG(ERR,"pp2pp: seq %d:%d: expect trigger 0x%08X, read 0x%08X",seq_id,chain_id,trigger,tmp) ;
00432 return ret ;
00433 }
00434 else {
00435 LOG(DBG,"pp2pp: seq %d:%d: expect trigger 0x%08X, read 0x%08X",seq_id,chain_id,trigger,tmp) ;
00436 }
00437 }
00438
00439 if(bunch_xing < 0) {
00440 bunch_xing = seq[0] & 0x7F ;
00441 not_sparse = (seq[0] & 0x80)?1:0 ;
00442 }
00443 else {
00444 int tmp = seq[0] & 0x7F ;
00445
00446 if(tmp != bunch_xing) {
00447 ret |= 2 ;
00448 LOG(ERR,"pp2pp: seq %d:%d: expect xing 0x%02X, read 0x%02X",seq_id,chain_id,bunch_xing,tmp) ;
00449 return ret ;
00450 }
00451 else {
00452 LOG(DBG,"pp2pp: seq %d:%d: expect xing 0x%02X, read 0x%02X",seq_id,chain_id,bunch_xing,tmp) ;
00453 }
00454
00455
00456 tmp = (seq[0] & 0x80)?1:0 ;
00457
00458 if(tmp != not_sparse) {
00459 ret |= 2 ;
00460 LOG(ERR,"pp2pp: seq %d:%d: expect not_sparse 0x%02X, read 0x%02X",seq_id,chain_id,not_sparse,tmp) ;
00461 return ret ;
00462 }
00463 else {
00464 LOG(DBG,"pp2pp: seq %d:%d: expect not_sparse 0x%02X, read 0x%02X",seq_id,chain_id,not_sparse,tmp) ;
00465 }
00466
00467
00468
00469
00470 }
00471
00472
00473
00474
00475
00476 int fifo_w16 = (seq[1] >>8) | ((seq[1] & 0xF)<<8) ;
00477
00478 LOG(DBG,"seq 0x%04X, 0x%04X; trg 0x%04X, 0x%04X; len %d",seq[0],seq[1],trg[0],trg[1],fifo_w16) ;
00479 LOG(NOTE,"pp2pp: seq_id %d:%d; words %d",seq_id,chain_id,fifo_w16) ;
00480
00481
00482 fifo_w16 -= 2 ;
00483
00484 d8 = (u_char *) &(d16[cur_ix]) ;
00485
00486 next_good_ix = cur_ix + fifo_w16 ;
00487 if(fifo_w16 & 1) {
00488 next_good_ix++ ;
00489 }
00490
00491 for(i=0;i<fifo_w16;i++) {
00492 int ch, c_adc ;
00493
00494 ch = *d8++ ;
00495 c_adc = *d8++ ;
00496
00497 LOG(DBG,"Word %d/%d: ch %d, c_adc %d",i,fifo_w16,ch,c_adc) ;
00498
00499 if(ch & 0x80) {
00500 if(c_adc != 0) {
00501 ret |= 4 ;
00502 LOG(ERR,"Bad channel in seq %d:%d: %d %d",seq_id,chain_id,ch,c_adc) ;
00503 break ;
00504 }
00505 else {
00506 LOG(NOTE,"SVX break: seq %d:%d: SVX 0x%02X",seq_id, chain_id,ch) ;
00507 }
00508
00509 if(requested) {
00510 adc->finalize(1, sec_id, d->seq_id, d->chain_id) ;
00511 requested = 0 ;
00512 }
00513
00514 svx_id = ch & 0x7F ;
00515 d = (struct pp2pp_t *) adc->request(1) ;
00516
00517 requested = 1 ;
00518
00519 d->seq_id = seq_id ;
00520 d->chain_id = chain_id ;
00521 d->svx_id = svx_id ;
00522 d->bunch_xing = bunch_xing ;
00523 d->not_sparse = not_sparse ;
00524
00525 d->error = ret ;
00526
00527 memset(d->adc,0,sizeof(d->adc)) ;
00528 memset(d->trace,0,sizeof(d->trace)) ;
00529 }
00530 else {
00531 if(!requested) {
00532 LOG(ERR,"Bad data -- SVX ID was not found in sequencer %d, chain %d (0x%X 0x%X)",seq_id, chain_id, ch,c_adc) ;
00533 ret |=4 ;
00534 break ;
00535 }
00536 else {
00537 LOG(DBG,"datum %d/%d: %3d = 0x%02X",i,fifo_w16,ch,c_adc) ;
00538
00539 if(d->trace[ch]) {
00540 LOG(WARN,"duplicate channel %d: ADC now %d, was %d!",ch,c_adc,d->adc[ch]) ;
00541 ret |= 4;
00542 d->trace[ch] = 2 ;
00543 }
00544 else d->trace[ch] = 1 ;
00545
00546 d->adc[ch] = c_adc ;
00547 }
00548 }
00549
00550 cur_ix++ ;
00551 }
00552
00553
00554
00555 if(fifo_w16 & 1) {
00556 int ch, c_adc ;
00557
00558 ch = *d8++ ;
00559 c_adc = *d8++ ;
00560
00561 LOG(DBG,"Padding %d/%d: %3d = 0x%02X",i,fifo_w16,ch,c_adc) ;
00562
00563 cur_ix++ ;
00564 }
00565
00566 if(requested) {
00567 adc->finalize(1, sec_id, d->seq_id, d->chain_id) ;
00568 requested = 0 ;
00569 }
00570
00571 cur_ix = next_good_ix ;
00572
00573 }
00574
00575 return ret ;
00576 }