00001 #include <stdio.h>
00002 #include <math.h>
00003 #include <string.h>
00004 #include <errno.h>
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <fcntl.h>
00008
00009 #include <rtsLog.h>
00010
00011 #include <TPX/tpx_altro_to_pad.h>
00012 #include <DAQ1000/ddl_struct.h>
00013 #include <TPC/fee_readout.h>
00014
00015
00016
00017 #include "tpxCore.h"
00018
00019
00020 struct tpx_rdo tpx_rdo[6] ;
00021 struct tpx_rdo_dbg tpx_rdo_dbg[6] ;
00022 int tpx_fee_check ;
00023
00024
00025 u_int expected_usercode[5] = {
00026
00027 0x0c500000,
00028 0x0283c6b3,
00029 0x02b9ab26,
00030 0x18a9352d,
00031
00032
00033
00034
00035
00036 0x00AD9D1D
00037 } ;
00038
00039 static inline u_int get10(u_int *l, u_int p) ;
00040 static u_int *data_test(u_int *h, struct tpx_altro_struct *a, int log, u_int *first) ;
00041
00042
00043
00044 static struct {
00045 u_char altro ;
00046 u_char ch ;
00047 u_char rdo ;
00048 } tpx_pad_to_altro[46][183] ;
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 void tpx_to_altro(int row, int pad, int &rdo, int &a, int &ch)
00063 {
00064 static int first ;
00065 int ro, pa ;
00066
00067
00068
00069 if(first == 0) {
00070 for(int r=0;r<6;r++) {
00071 for(int a=0;a<256;a++) {
00072 for(int ch=0;ch<16;ch++) {
00073 tpx_from_altro(r,a,ch,ro,pa) ;
00074 if(ro > 45) continue ;
00075
00076 tpx_pad_to_altro[ro][pa].altro = a ;
00077 tpx_pad_to_altro[ro][pa].ch = ch ;
00078 tpx_pad_to_altro[ro][pa].rdo = r+1 ;
00079 }
00080 }
00081 }
00082 first = 1 ;
00083 }
00084
00085
00086
00087 rdo = tpx_pad_to_altro[row][pad].rdo ;
00088 a = tpx_pad_to_altro[row][pad].altro ;
00089 ch = tpx_pad_to_altro[row][pad].ch ;
00090
00091 }
00092
00093
00094
00095
00096 void tpx_from_altro(int rdo, int a, int ch, int &row, int &pad)
00097 {
00098 row = tpx_altro_to_pad[rdo][a][ch].row ;
00099 pad = tpx_altro_to_pad[rdo][a][ch].pad ;
00100
00101 #ifdef TEST_RDO
00102 if(rdo==5) {
00103 if((a>=50) && (a<=55)) {
00104 row = 255 ;
00105 pad = 255 ;
00106 return ;
00107 }
00108 if((a>=250) && (a<=255)) {
00109 a -= 200 ;
00110
00111 row = tpx_altro_to_pad[rdo][a][ch].row ;
00112 pad = tpx_altro_to_pad[rdo][a][ch].pad ;
00113 return ;
00114 }
00115 }
00116 #endif
00117
00118 return ;
00119 }
00120
00121 int tpx_altro_to_fee(int rdo, int a)
00122 {
00123
00124 rdo-- ;
00125
00126 for(int i=0;i<36;i++) {
00127 int fee, altro ;
00128
00129 fee = fee_position[rdo][i] ;
00130 if(fee == 255) continue ;
00131
00132 altro = (fee << 1) & 0xFF ;
00133
00134 if(altro == a) return fee ;
00135 }
00136
00137 return -1 ;
00138 }
00139
00140 u_char tpx_rdo_fees(int rdo, int cou)
00141 {
00142 if(cou >= 36) return 255 ;
00143
00144 return fee_position[rdo-1][cou] ;
00145 }
00146
00147
00148 #ifdef WHO_USUES_THIS
00149 u_char tpx_altro_ch_to_fee(int a, int ch)
00150 {
00151 if(a & 1) ch += 16 ;
00152
00153 for(int i=0;i<32;i++) {
00154 if(tpx_old_to_new_ch[i] == ch) return i ;
00155 }
00156
00157 return 255 ;
00158
00159 }
00160 #endif
00161
00162
00163
00164
00165
00166
00167
00168
00169 int tpx_get_start(char *buff, u_int words, struct tpx_rdo_event *rdo, int do_log)
00170 {
00171 struct ddl_header *hdr ;
00172 struct ddl_trailer *trl ;
00173
00174 u_int *l ;
00175
00176
00177
00178 hdr = (struct ddl_header *) buff ;
00179
00180 rdo->data_err = 0 ;
00181 rdo->token = -ENOTSUP ;
00182 rdo->trg_cou = 0 ;
00183 rdo->rdo = 6 ;
00184 rdo->sector = 24 ;
00185
00186
00187 if(words < (2*sizeof(struct ddl_header))/4) {
00188 if(do_log) {
00189 LOG(ERR,"Event oddly small -- words %d",words) ;
00190 }
00191 return rdo->token ;
00192 }
00193
00194
00195 rdo->type = hdr->type & 0xF ; ;
00196 rdo->subtype = (hdr->type >> 4) & 0xF ;
00197 rdo->sector = (hdr->type >> 12) & 0x7F ;
00198 rdo->rdo = (hdr->type >> 8) & 0xF ;
00199
00200 rdo->data_end = 0 ;
00201 rdo->data_start = (u_int *)(buff + sizeof(struct ddl_header)) ;
00202
00203 rdo->l2_cmd = 0 ;
00204
00205
00206 trl = (struct ddl_trailer *) (buff + 4*words - sizeof(struct ddl_trailer)) ;
00207
00208 LOG(DBG,"Header 0x%08X 0x%08X",hdr->type,hdr->ev_cou) ;
00209
00210
00211
00212
00213
00214
00215
00216 if(trl->type != hdr->type) {
00217 if(hdr->type == 0xFEED0301) {
00218 if(do_log) LOG(WARN,"RDO %d: Old factory log?",rdo->rdo) ;
00219 rdo->data_start = (u_int *)(buff + 12) ;
00220 rdo->type = DDL_TYPE_LOG ;
00221 }
00222 else {
00223 if(do_log) LOG(ERR,"RDO %d:%d: Header type 0x%08X and trailer type 0x%08X mismatch",rdo->sector,rdo->rdo,hdr->type,trl->type) ;
00224 rdo->token = -EBADF ;
00225 return rdo->token ;
00226 }
00227 }
00228
00229
00230
00231 switch(trl->fl_wc >> 28) {
00232 case 0 :
00233 rdo->data_err = 0 ;
00234 break ;
00235 default :
00236
00237 if(do_log) rdo->data_err = 1 ;
00238 break ;
00239 }
00240
00241
00242 switch(rdo->type) {
00243 case DDL_TYPE_LOG :
00244 case DDL_TYPE_MSC :
00245 rdo->token = 4096 ;
00246 return rdo->token ;
00247 case DDL_TYPE_DTA :
00248 break ;
00249 default :
00250 if(do_log) {
00251 LOG(WARN,"Hm,I haven't coded this type %d", rdo->type) ;
00252 u_int *val = rdo->data_start ;
00253 for(int i=0;i<10;i++) {
00254 LOG(WARN,"\t%2d: 0x%08X [%u dec]",i,val[i],val[i]) ;
00255 }
00256 }
00257 rdo->token = -ENOTSUP ;
00258 return rdo->token ;
00259
00260 break ;
00261 }
00262
00263
00264
00265 l = (u_int *) trl - 1 ;
00266
00267 rdo->trg_cou = *l ;
00268
00269 if(rdo->trg_cou > 124) {
00270 if(do_log) LOG(ERR,"Bad trg count %d>124, token %d",rdo->trg_cou, rdo->token) ;
00271
00272
00273
00274 }
00275
00276
00277 l -= rdo->trg_cou * (sizeof(struct trg_data)/4) ;
00278
00279 if(l < rdo->data_start) {
00280 if(do_log) LOG(ERR,"Bad trigger data!") ;
00281 rdo->data_err = 1 ;
00282 rdo->token = -EBADF ;
00283 return rdo->token ;
00284 }
00285
00286 rdo->trg = (struct trg_data *) l ;
00287
00288
00289 u_int rh ;
00290 u_int rh_prompt = 0 ;
00291 rdo->token = 4097 ;
00292
00293 for(u_int i=0;i<rdo->trg_cou;i++) {
00294 int rh_delta ;
00295
00296
00297 switch(rdo->trg[i].csr & 0xFF000000) {
00298 case 0xFF000000 :
00299 case 0xDD000000 :
00300 rh = rdo->trg[i].rhic_counter ;
00301 if(rh_prompt) {
00302 rh_delta = rh - rh_prompt ;
00303 }
00304 else {
00305 rh_delta = (rh - tpx_rdo_dbg[rdo->rdo-1].old_rhic) ;
00306 }
00307 break ;
00308 case 0xEE000000 :
00309 default :
00310 rh_prompt = rdo->trg[i].rhic_counter ;
00311 rh_delta = rh_prompt - tpx_rdo_dbg[rdo->rdo-1].old_rhic ;
00312 rdo->token = rdo->trg[i].data & 0xFFF ;
00313 break ;
00314
00315 }
00316
00317 if(do_log) {
00318 if(rdo->rdo == 1) {
00319 LOG(NOTE,"\tRDO %d: evt %d: trg %d: RHIC %u, CSR 0x%08X, data 0x%08X [t %d], bytes %u, delta %d",rdo->rdo,hdr->ev_cou,i,
00320 rdo->trg[i].rhic_counter,
00321 rdo->trg[i].csr,
00322 rdo->trg[i].data,
00323 rdo->trg[i].data&0xFFF,
00324 words*4,
00325 rh_delta) ;
00326 }
00327 }
00328
00329 }
00330
00331 if(do_log) {
00332 if(rh_prompt) {
00333 tpx_rdo_dbg[rdo->rdo-1].delta = rh_prompt - tpx_rdo_dbg[rdo->rdo-1].old_rhic ;
00334 tpx_rdo_dbg[rdo->rdo-1].old_rhic = rh_prompt ;
00335 }
00336 else {
00337 tpx_rdo_dbg[rdo->rdo-1].delta = 0 ;
00338
00339
00340 }
00341
00342 }
00343
00344 if(do_log) LOG(DBG,"Event %d: sector %2d, rdo %d, type %d, subtype %d, token %d",
00345 hdr->ev_cou,rdo->sector,rdo->rdo,rdo->type,rdo->subtype,rdo->token) ;
00346
00347 l -= 2 ;
00348
00349
00350
00351
00352 if(do_log && (rdo->rdo==6)) {
00353 LOG(NOTE,"\t evt %d: %u %u",hdr->ev_cou,l[0],l[1]) ;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 if(rdo->data_err) LOG(ERR,"RDO %d: token %d, event %10u marked as in error [0x%X]",rdo->rdo,rdo->token,hdr->ev_cou,(trl->fl_wc >> 28)) ;
00363
00364 if(do_log) LOG(DBG,"RDO %d: real data...",rdo->rdo) ;
00365
00366 l-- ;
00367
00368 rdo->data_end = l ;
00369
00370 if((rdo->data_end - rdo->data_start) <= 0) {
00371 if(rdo->token != 4097) {
00372 if(do_log) LOG(ERR,"Bad RDO data: start 0x%X, end 0x%X, delta %d, tokenn %d!",rdo->data_start,rdo->data_end,rdo->data_end-rdo->data_start,rdo->token) ;
00373 rdo->token = -EBADF ;
00374 }
00375 }
00376
00377 return rdo->token ;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 u_int *tpx_scan_to_next(u_int *now, u_int *first, struct tpx_altro_struct *a_struct)
00400 {
00401 u_int *next_altro ;
00402 u_int *store = now ;
00403 int log_yes ;
00404 int was_log_yes ;
00405
00406
00407 log_yes = was_log_yes = a_struct->log_err ;
00408
00409 a_struct->err = 0 ;
00410
00411
00412
00413 do {
00414 next_altro = data_test(now,a_struct,log_yes,first) ;
00415
00416
00417 if(next_altro==0) {
00418 a_struct->err = 1 ;
00419
00420 log_yes = 0 ;
00421
00422 now-- ;
00423
00424 }
00425 else {
00426
00427 if(was_log_yes && !log_yes) {
00428 LOG(NOTE," ...but found A%03d:%02d %d words earlier",a_struct->id,a_struct->ch,store-now) ;
00429
00430 }
00431
00432 if(((next_altro-first)<-1) || ((next_altro-first)>1000000)) {
00433
00434 LOG(ERR,"next_altro-first %d",next_altro-first) ;
00435 }
00436
00437
00438
00439
00440
00441
00442 return next_altro ;
00443
00444 }
00445
00446
00447 } while((now-first)>=1) ;
00448
00449
00450 LOG(ERR,"At end: now 0x%08X, next_altro 0x%08X, now-first 0x%08X, next-first 0x%08X",
00451 now,next_altro,now-first,next_altro-first) ;
00452
00453 return 0 ;
00454
00455 }
00456
00457 int tpx_use_rdo(char *rdobuff, int bytes, int (userfunc)(struct tpx_altro_struct *a, void *arg), void *arg)
00458 {
00459 int t ;
00460 u_int *data_end ;
00461 tpx_rdo_event rdo ;
00462 tpx_altro_struct a ;
00463 int ret ;
00464
00465 ret = 0 ;
00466
00467 t = tpx_get_start(rdobuff, bytes/4, &rdo, 0) ;
00468 if(t<=0) {
00469 LOG(NOTE,"token %d, rdo %d: not an altro event",t,rdo.rdo) ;
00470 return ret ;
00471 }
00472
00473 if(rdo.data_err) {
00474 LOG(ERR,"token %d, rdo %d: altro data error!",t,rdo.rdo) ;
00475 return -1 ;
00476 }
00477
00478 a.what = TPX_ALTRO_DO_ADC ;
00479 a.rdo = rdo.rdo - 1;
00480 a.sector = rdo.sector ;
00481 a.t = t ;
00482 a.log_err = 0 ;
00483
00484 LOG(DBG,"token %d, rdo %d: running through %d bytes...",t,rdo.rdo,bytes) ;
00485
00486 data_end = rdo.data_end ;
00487 do {
00488
00489 data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
00490
00491 ret |= userfunc(&a, arg) ;
00492 } while((data_end > rdo.data_start) && data_end) ;
00493
00494 return ret ;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 static u_int *data_test(u_int *h, struct tpx_altro_struct *a, int log, u_int *first)
00506 {
00507 u_int hi, lo ;
00508 int wc ;
00509 int ret ;
00510 int delta ;
00511
00512
00513 ret = 0 ;
00514
00515
00516 a->count = 0 ;
00517 a->row = 0 ;
00518 a->pad = 0 ;
00519
00520 delta = h - first ;
00521 if(delta < 1) {
00522 if(log) LOG(ERR,"Startup offset bad %d",delta) ;
00523 return 0 ;
00524 }
00525
00526 lo = *h-- ;
00527 hi = *h-- ;
00528
00529
00530 if((lo & 0xCFF00000) || (hi & 0xCFF00000)) {
00531
00532 ret = -1 ;
00533 }
00534
00535
00536
00537 if((hi & 0xFFFC0) != 0xAAA80) {
00538
00539 ret = -2 ;
00540
00541 }
00542
00543 if((lo & 0x0F000) != 0x0A000) {
00544
00545 ret = -3 ;
00546 }
00547
00548
00549 wc = ((hi&0x3F)<<4) | ((lo&0xF0000)>>16) ;
00550
00551
00552
00553 a->id = (lo & 0xFF0)>>4 ;
00554 a->ch = lo & 0xF ;
00555
00556
00557 if((wc > 529) || (wc<0)) {
00558
00559 ret = -4 ;
00560 }
00561
00562
00563 if(ret) {
00564 if(log) LOG(WARN,"RDO %d: token %d: Altro %03d:%02d (?) header [1] %d",a->rdo+1,a->t,a->id,a->ch,ret) ;
00565 return 0 ;
00566 }
00567
00568
00569
00570
00571
00572 for(int i=0;i<tpx_fee_override_cou;i++) {
00573
00574 if(a->sector == tpx_fee_override[i].sector) {
00575 if(a->rdo == (tpx_fee_override[i].rdo-1)) {
00576 int fee = a->id & 0xFE ;
00577 if(fee == tpx_fee_override[i].curr_altro) {
00578 int should = tpx_fee_override[i].orig_altro ;
00579
00580 if(a->id & 1) {
00581 should = tpx_fee_override[i].orig_altro | 1 ;
00582 }
00583 else {
00584 should = tpx_fee_override[i].orig_altro ;
00585 }
00586
00587 if(log) {
00588
00589 }
00590
00591
00592 a->id = should ;
00593 }
00594 }
00595 }
00596 }
00597
00598
00599
00600 int rrow, ppad ;
00601
00602 tpx_from_altro(a->rdo, a->id, a->ch, rrow, ppad) ;
00603
00604 a->row = rrow ;
00605 a->pad = ppad ;
00606
00607
00608 if((a->row > 45) || (a->pad > 182)) {
00609 if(log) LOG(ERR,"row:pad %d:%d illegal for altro %d:%d",a->row,a->pad,a->id,a->ch) ;
00610 return 0 ;
00611 }
00612
00613 if(wc == 0) return h ;
00614
00615 int l10 = wc ;
00616
00617 while(l10 % 4) l10++ ;
00618
00619
00620
00621
00622 delta = (h - l10/2) - first ;
00623 if(delta < -1) {
00624 if(log) LOG(ERR,"AID %d:%d: Bad offset %d, wrong wc %d", a->id, a->ch, delta, wc) ;
00625 return 0 ;
00626 }
00627
00628
00629 int p10 = 0 ;
00630
00631
00632 switch(wc&3) {
00633 case 0 :
00634 break ;
00635
00636 case 1 :
00637 if(get10(h,p10) != 0x2AA) {
00638
00639 ret = -1 ;
00640 }
00641 p10++ ;
00642
00643 if(get10(h,p10) != 0x2AA) {
00644
00645 ret = -2 ;
00646 }
00647 p10++ ;
00648
00649 if(get10(h,p10) != 0x2AA) {
00650
00651 ret = -3 ;
00652 }
00653 p10++ ;
00654
00655 break ;
00656
00657 case 2 :
00658 if(get10(h,p10) != 0x2AA) {
00659
00660 ret = -4 ;
00661 }
00662 p10++ ;
00663
00664 if(get10(h,p10) != 0x2AA) {
00665
00666 ret = -5 ;
00667 }
00668 p10++ ;
00669
00670 break ;
00671
00672 case 3 :
00673 if(get10(h,p10) != 0x2AA) {
00674
00675 ret = -6 ;
00676 }
00677 p10++ ;
00678
00679 break ;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688 #ifdef VEERY_PARANOID
00689
00690 for(int i=0;i<l10/4;i++) {
00691 if(h[-i] & 0xCFF00000) {
00692
00693 if(log) LOG(ERR," Bad form 0x%08X at %d",h[-i],i) ;
00694 ret = -1 ;
00695 break ;
00696 }
00697 }
00698 #endif
00699
00700 if(ret) {
00701 if(log) LOG(WARN,"RDO %d: token %d: Altro %03d:%02d (?) header [2] %d",a->rdo+1,a->t,a->id,a->ch,ret) ;
00702
00703
00704
00705
00706
00707 return 0 ;
00708 }
00709
00710
00711
00712
00713
00714 int tb_prev = 512 ;
00715
00716 u_short *p_adc = a->adc ;
00717 u_short *p_tb = a->tb ;
00718 int tb_all = 0 ;
00719
00720 while(p10 < l10) {
00721 int tb_cou = get10(h,p10++) ;
00722 int tb_last = get10(h,p10++) ;
00723
00724
00725 tb_cou -= 2 ;
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742 if((tb_cou > wc) || (tb_cou <= 0) || (tb_cou > 512)) {
00743
00744 ret = -1 ;
00745 }
00746
00747 if((tb_last < 0) || (tb_last >= tb_prev)) {
00748
00749 ret = -2 ;
00750 }
00751
00752 if(ret) {
00753 if(log) LOG(WARN,"RDO %d: token %d: Altro %03d:%02d (?) data [1] %d",a->rdo+1,a->t,a->id,a->ch,ret) ;
00754 return 0 ;
00755 }
00756
00757
00758
00759
00760 tb_all += tb_cou ;
00761 if(tb_all >= 512) {
00762 if(log) LOG(WARN,"RDO %d: token %d: Altro %03d:%02d (?) tb_all [1] %d",a->rdo+1,a->t,a->id,a->ch,tb_all) ;
00763 return 0 ;
00764 }
00765
00766
00767 tb_prev = tb_last - tb_cou ;
00768
00769 if(a->what & TPX_ALTRO_DO_ADC) {
00770 for(;tb_last > tb_prev; tb_last--) {
00771 *p_adc++ = get10(h, p10++) ;
00772 *p_tb++ = tb_last ;
00773 }
00774 }
00775 else {
00776 p10 += tb_cou ;
00777 }
00778
00779
00780
00781 }
00782
00783
00784
00785
00786
00787 if(ret) {
00788 if(log) LOG(ERR,"RDO %d: token %d: Altro %03d:%02d (?) data [2]",a->rdo+1,a->t,a->id,a->ch) ;
00789 return 0 ;
00790 }
00791 else {
00792 a->count = p_adc - a->adc ;
00793 }
00794
00795 l10 /= 2 ;
00796
00797 h -= l10 ;
00798
00799
00800
00801
00802
00803 return h ;
00804 }
00805
00806
00807
00808 #if 0
00809 static int check_emul(u_int *a)
00810 {
00811 int i ;
00812 u_int dta, should ;
00813 u_int errors ;
00814
00815 errors = 0 ;
00816 for(i=0;i<200000;i++) {
00817 dta = *a++ ;
00818
00819 should = ((i&0xFFFF)<<16)|(i&0xFFFF) ;
00820
00821 if(dta != should) {
00822 errors++ ;
00823 LOG(ERR,"Mismatch %d: at %d: should 0x%08X, is 0x%08X",errors,i,should,dta) ;
00824 if(errors > 3) break ;
00825 }
00826 }
00827
00828 if(errors) {
00829 return -1 ;
00830 }
00831
00832 LOG(NOTE,"Emul evt checks OK...") ;
00833 return 0 ;
00834
00835 }
00836 #endif
00837
00838 static inline u_int get10(u_int *l, u_int p)
00839 {
00840 u_int ret ;
00841
00842 l -= 2*(p/4) ;
00843
00844 switch(p&3) {
00845 case 0 :
00846 ret = (l[-1] & 0xFFC00) >> 10 ;
00847 break ;
00848 case 1 :
00849 ret = (l[-1] & 0x3FF) ;
00850 break ;
00851 case 2 :
00852 ret = (l[0] & 0xFFC00) >> 10 ;
00853 break ;
00854 case 3 :
00855 default:
00856 ret = l[0] & 0x3FF ;
00857 break ;
00858 }
00859
00860
00861
00862 return ret ;
00863 }
00864
00865
00866 void tpx_analyze_log(int sector,int rdo, char *buff)
00867 {
00868 int i ;
00869 char *start_ptr ;
00870 int len ;
00871
00872 LOG(WARN,"tpx_analyze_log: deprecated!") ;
00873
00874 len = strlen(buff) ;
00875 start_ptr = buff ;
00876
00877
00878
00879 while(len) {
00880 for(i=0;i<len;i++) {
00881 if(start_ptr[i] == '\n') {
00882 start_ptr[i] = 0 ;
00883 if(strlen(start_ptr)) {
00884
00885 LOG(INFO,"[Sec_%02d:RDO_%d] %s",sector,rdo,start_ptr) ;
00886 }
00887 start_ptr = start_ptr + i + 1 ;
00888 len = strlen(start_ptr) ;
00889 break ;
00890 }
00891 }
00892 }
00893
00894 return ;
00895
00896 }
00897
00898 int tpx_show_status(int sector, int rb_mask, int *altro_list)
00899 {
00900 struct tpx_rdo *rdo ;
00901 u_char altro[256] ;
00902 int err ;
00903 int rb ;
00904
00905 err = 0 ;
00906
00907 for(rb=0;rb<6;rb++) {
00908
00909 if((1<<rb) & rb_mask) ;
00910 else continue ;
00911
00912 rdo = &(tpx_rdo[rb]) ;
00913
00914 if(rdo->sector != sector || (rb+1) != rdo->rdo) {
00915 LOG(WARN,"msc: config for RDO %d: sector %d, rdo %d claims error",rb+1,rdo->sector & 0x7F,rdo->rdo) ;
00916
00917 }
00918 else {
00919 LOG(NOTE,"msc: config for RDO %d: sector %d, rdo %d",rb+1,rdo->sector,rdo->rdo) ;
00920 }
00921
00922 LOG(NOTE,"msc: Remote %d, temp rdo %d, temp stratix %d",rdo->remote,rdo->temp_rdo,rdo->temp_stratix) ;
00923 LOG(NOTE,"msc: Compiled on %s",rdo->compilation_date) ;
00924
00925 LOG(NOTE,"\t FPGAs: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
00926 rdo->fpga_usercode[0],
00927 rdo->fpga_usercode[1],
00928 rdo->fpga_usercode[2],
00929 rdo->fpga_usercode[3],
00930 rdo->fpga_usercode[4]
00931 ) ;
00932
00933 for(int i=0;i<5;i++) {
00934 if(expected_usercode[i] != rdo->fpga_usercode[i]) {
00935 LOG(WARN,"msc: RDO %d: FPGA %d usercode is 0x%08X, expect 0x%08X!?",rdo->rdo,i,rdo->fpga_usercode[i],expected_usercode[i]) ;
00936 }
00937 }
00938
00939 if(rdo->status_xilinx) {
00940 LOG(ERR,"msc: RDO %d: xilinx status: 0x%02X",rdo->rdo,rdo->status_xilinx) ;
00941 err |= 1 ;
00942 }
00943 else {
00944 LOG(NOTE,"RDO %d: xilinx status: 0x%02X",rdo->rdo,rdo->status_xilinx) ;
00945 }
00946 if(rdo->status_cpld) {
00947 LOG(ERR,"msc: RDO %d: CPLD status: 0x%02X",rdo->rdo,rdo->status_cpld) ;
00948 err |= 1 ;
00949 }
00950 else {
00951 LOG(NOTE,"RDO %d: CPLD status: 0x%02X",rdo->rdo,rdo->status_cpld) ;
00952 }
00953
00954
00955 memset(altro,0,sizeof(altro)) ;
00956
00957 if(altro_list) {
00958 for(int a=0;a<256;a++) {
00959 altro[a] = altro_list[a] ;
00960 }
00961 }
00962 else {
00963 for(int a=0;a<256;a++) {
00964 for(int c=0;c<16;c++) {
00965 int row, pad ;
00966
00967 tpx_from_altro(rb,a,c,row,pad) ;
00968
00969 if(row <= 45) {
00970 altro[a] |= 0x1 ;
00971 }
00972 }
00973 }
00974 }
00975
00976
00977 for(int i=0;i<tpx_odd_fee_count;i++) {
00978 if((tpx_odd_fee[i].sector != sector) || (tpx_odd_fee[i].rdo != (rb+1))) continue ;
00979 for(int j=0;j<2;j++) {
00980 for(int a=0;a<256;a++) {
00981 if(!altro[a]) continue ;
00982
00983 if((tpx_odd_fee[i].altro_id_padplane + j) == a) {
00984 altro[a] = 0 ;
00985 LOG(WARN,"Marking ALTRO %3d (FEE %03d) as unneeded because it is marked bad in the gain file...",
00986 a,tpx_odd_fee[i].tpc_fee_padplane) ;
00987 }
00988 }
00989 }
00990
00991 }
00992
00993
00994 LOG(NOTE,"Checking override map [%d]",tpx_fee_override_cou) ;
00995 int over = 0 ;
00996 int in_fee[32], should_be[32] ;
00997
00998 for(int i=0;i<tpx_fee_override_cou;i++) {
00999 LOG(NOTE,"Checking sector %d:%d, rdo %d:%d, id %d:%d",sector,tpx_fee_override[i].sector,rb+1,tpx_fee_override[i].rdo,
01000 tpx_fee_override[i].orig_altro,tpx_fee_override[i].curr_altro) ;
01001
01002 if(sector == tpx_fee_override[i].sector) {
01003 if((rb+1) == tpx_fee_override[i].rdo) {
01004 in_fee[over] = tpx_fee_override[i].curr_altro ;
01005 should_be[over] = tpx_fee_override[i].orig_altro ;
01006 over++ ;
01007 LOG(WARN,"Expect to override wrong altro %3d with correct altro %3d!",tpx_fee_override[i].curr_altro,tpx_fee_override[i].orig_altro) ;
01008
01009
01010 }
01011 }
01012
01013 }
01014
01015
01016 int fcou = 1 ;
01017 for(int b=0;b<3;b++) {
01018 for(int c=0;c<12;c++) {
01019 int ix = rdo->fee[b][c].id ;
01020
01021 if(rdo->fee[b][c].fee_status) {
01022
01023 altro[ix] |= 0x2 ;
01024 altro[ix+1] |= 0x2 ;
01025
01026 if(rdo->fee[b][c].jumpers != 3) {
01027 altro[ix] |= 4 ;
01028 altro[ix+1] |= 4 ;
01029 }
01030
01031 if(rdo->fee[b][c].fee_status == 1) {
01032
01033 }
01034 else {
01035 altro[ix] |= 0x8 ;
01036 altro[ix+1] |= 0x8 ;
01037
01038 }
01039
01040 if(altro[ix] != 3) {
01041
01042
01043
01044 int overriden = 0 ;
01045 for(int i=0;i<over;i++) {
01046 if((in_fee[i] == ix) || ((in_fee[i]+1)==ix)) {
01047 LOG(WARN,"Sector %2d, RDO %d: %2d: FEE %3d (A%3d,%d) [port %d:%d:%d] = 0x%X, 0x%X -- overriden, should be A%3d",sector,rdo->rdo,fcou,
01048 rdo->fee[b][c].pad_id,
01049 rdo->fee[b][c].id,
01050 rdo->fee[b][c].jumpers,
01051 b,
01052 rdo->fee[b][c].x_s>>4,
01053 rdo->fee[b][c].x_s&1,
01054 rdo->fee[b][c].fee_status,
01055 altro[ix],
01056 should_be[i]
01057 ) ;
01058 overriden = 1 ;
01059 break ;
01060 }
01061 }
01062
01063
01064 for(int i=0;i<tpx_odd_fee_count;i++) {
01065 if((tpx_odd_fee[i].altro_id_padplane == ix) || ((tpx_odd_fee[i].altro_id_padplane+1) == ix)) {
01066
01067 LOG(WARN,"msc: Sector %2d, RDO %d: %2d: FEE %3d (A%3d,%d) [port %d:%d:%d] = 0x%X, 0x%X -- marked bad in gain file",sector,rdo->rdo,fcou,
01068 rdo->fee[b][c].pad_id,
01069 rdo->fee[b][c].id,
01070 rdo->fee[b][c].jumpers,
01071 b,
01072 rdo->fee[b][c].x_s>>4,
01073 rdo->fee[b][c].x_s&1,
01074 rdo->fee[b][c].fee_status,
01075 altro[ix]
01076 ) ;
01077
01078 overriden = 1 ;
01079 break ;
01080 }
01081 }
01082
01083 if(overriden) ;
01084 else {
01085 LOG(ERR,"msc: Sector %2d, RDO %d: %2d: FEE %3d (A%3d,%d) [port %d:%d:%d] = 0x%X, 0x%X",sector,rdo->rdo,fcou,
01086 rdo->fee[b][c].pad_id,
01087 rdo->fee[b][c].id,
01088 rdo->fee[b][c].jumpers,
01089 b,
01090 rdo->fee[b][c].x_s>>4,
01091 rdo->fee[b][c].x_s&1,
01092 rdo->fee[b][c].fee_status,
01093 altro[ix]
01094 ) ;
01095 }
01096 }
01097
01098
01099 fcou++ ;
01100 }
01101 }
01102 }
01103
01104
01105
01106 for(int a=0;a<256;a++) {
01107 if(altro[a] == 0) continue ;
01108 if(altro[a] == 3) continue ;
01109
01110 if(altro[a] == 1) {
01111 int overriden = 0 ;
01112
01113 for(int i=0;i<over;i++) {
01114 if((a == should_be[i]) || (a == (should_be[i]+1))) {
01115 LOG(WARN,"Sector %2d, RDO %d: ALTRO %3d missing but was overriden: status 0x%X",sector,rb+1,a,altro[a]) ;
01116 overriden = 1 ;
01117 break ;
01118 }
01119 }
01120
01121 if(overriden) continue ;
01122
01123 LOG(ERR,"msc: Sector %2d, RDO %d: ALTRO %3d missing: status 0x%X",sector,rb+1,a,altro[a]) ;
01124
01125 err |= 2 ;
01126 }
01127 else {
01128 LOG(WARN,"msc: Sector %2d, RDO %d: ALTRO %3d odd status: status 0x%X",sector,rb+1,a,altro[a]) ;
01129 if((altro[a] & 0xB)==0xB) {
01130 err |= 2 ;
01131 }
01132 }
01133 }
01134
01135
01136 }
01137
01138
01139
01140
01141
01142
01143
01144 return err ;
01145 }
01146
01147
01148 int tpx_analyze_msc(int sector,int rb, char *buff, int *altro_list)
01149 {
01150 struct tpx_rdo *rdo ;
01151
01152 rdo = (struct tpx_rdo *) buff ;
01153
01154
01155 memcpy(&(tpx_rdo[rb]),buff,sizeof(struct tpx_rdo)) ;
01156
01157
01158 LOG(NOTE,"RDO %d: msc event, should be %d bytes",rb+1,sizeof(struct tpx_rdo)) ;
01159
01160 return tpx_show_status(sector,1<<rb,altro_list) ;
01161 }