11 #include <TPX/tpx_altro_to_pad.h>
12 #include <DAQ1000/ddl_struct.h>
13 #include <TPC/fee_readout.h>
17 #include "tpx_fee_position.h"
25 u_int expected_usercode[5] = {
39 static inline u_int get10(u_int *l, u_int p) ;
40 static u_int *data_test(u_int *h,
struct tpx_altro_struct *a,
int log, u_int *first) ;
48 } tpx_pad_to_altro[46][183] ;
62 void tpx_to_altro(
int row,
int pad,
int &rdo,
int &a,
int &ch)
70 for(
int r=0;r<6;r++) {
71 for(
int a=0;a<256;a++) {
72 for(
int ch=0;ch<16;ch++) {
73 tpx_from_altro(r,a,ch,ro,pa) ;
74 if(ro > 45) continue ;
76 tpx_pad_to_altro[ro][pa].altro = a ;
77 tpx_pad_to_altro[ro][pa].ch = ch ;
78 tpx_pad_to_altro[ro][pa].rdo = r+1 ;
87 rdo = tpx_pad_to_altro[row][pad].rdo ;
88 a = tpx_pad_to_altro[row][pad].altro ;
89 ch = tpx_pad_to_altro[row][pad].ch ;
93 int *tpx_altro_to_row_override = 0 ;
94 int tpx_rdo_override = 0 ;
95 int tpx_fy16_map = 0 ;
101 void tpx_from_altro(
int rdo,
int a,
int ch,
int &row,
int &pad)
105 LOG(ERR,
"RDO should count from 0") ;
140 row = tpx_altro_to_pad[0][a][ch].row ;
141 pad = tpx_altro_to_pad[0][a][ch].pad ;
153 row = tpx_altro_to_pad[rdo][a][ch].row ;
154 pad = tpx_altro_to_pad[rdo][a][ch].pad ;
156 if(tpx_altro_to_row_override) {
157 if(tpx_rdo_override != (rdo+1)) {
163 row = tpx_altro_to_row_override[a&0xFE] ;
165 if(a&1) pad = 1 + 16 + ch ;
181 #ifdef ESB_TEST_ETTIE
186 if((a==252) || (a==253)) {
199 if((a>=50) && (a<=55)) {
204 if((a>=250) && (a<=255)) {
207 row = tpx_altro_to_pad[rdo][a][ch].row ;
208 pad = tpx_altro_to_pad[rdo][a][ch].pad ;
218 int tpx_altro_to_fee(
int rdo,
int a)
226 for(
int i=0;i<36;i++) {
230 fee = tpx_fee_position[rdo][i] ;
233 fee = fee_position[rdo][i] ;
236 if(fee == 255) continue ;
238 altro = (fee << 1) & 0xFF ;
240 if(altro == a)
return fee ;
247 u_char tpx_rdo_fees(
int rdo,
int cou)
251 if(cou >= 36)
return 255 ;
253 if(tpx_fy16_map)
return tpx_fee_position[rdo-1][cou] ;
254 else return fee_position[rdo-1][cou] ;
258 #ifdef WHO_USUES_THIS
259 u_char tpx_altro_ch_to_fee(
int a,
int ch)
263 for(
int i=0;i<32;i++) {
264 if(tpx_old_to_new_ch[i] == ch)
return i ;
279 int tpx_get_start(
char *buff, u_int words,
struct tpx_rdo_event *rdo,
int do_log)
292 rdo->token = -ENOTSUP ;
300 LOG(ERR,
"Event oddly small -- words %d",words) ;
307 rdo->type = hdr->type & 0xF ; ;
308 rdo->subtype = (hdr->type >> 4) & 0xF ;
309 rdo->sector = (hdr->type >> 12) & 0x7F ;
310 rdo->rdo = (hdr->type >> 8) & 0xF ;
315 rdo->data_start = (u_int *)(buff +
sizeof(
struct ddl_header)) ;
324 if((hdr->type != 0xFEED0301) && (hdr->type & 0x00100000)) {
325 trl->type |= 0x00100000 ;
341 if(trl->type != hdr->type) {
342 if(hdr->type == 0xFEED0301) {
343 if(do_log) LOG(WARN,
"RDO %d: Old factory log?",rdo->rdo) ;
344 rdo->data_start = (u_int *)(buff + 12) ;
345 rdo->type = DDL_TYPE_LOG ;
349 LOG(ERR,
"RDO %d:%d: Header type 0x%08X and trailer type 0x%08X mismatch",rdo->sector,rdo->rdo,hdr->type,trl->type) ;
351 u_int *d32 = (u_int *)(buff + 4*words) ;
354 for(
int i=0;i<10;i++) {
355 LOG(WARN,
"%d: 0x%08X",i,d32[i]) ;
358 rdo->token = -EBADF ;
365 switch(trl->fl_wc >> 28) {
371 if(do_log) rdo->data_err = 1 ;
385 LOG(WARN,
"Hm,I haven't coded this type %d", rdo->type) ;
386 u_int *val = rdo->data_start ;
387 for(
int i=0;i<10;i++) {
388 LOG(WARN,
"\t%2d: 0x%08X [%u dec]",i,val[i],val[i]) ;
391 rdo->token = -ENOTSUP ;
399 l = (u_int *) trl - 1 ;
403 if(rdo->trg_cou > 124) {
404 if(do_log) LOG(ERR,
"Bad trg count %d>124, token %d",rdo->trg_cou, rdo->token) ;
411 l -= rdo->trg_cou * (
sizeof(
struct trg_data)/4) ;
413 if(l < rdo->data_start) {
414 if(do_log) LOG(ERR,
"Bad trigger data!") ;
416 rdo->token = -EBADF ;
424 u_int rh_prompt = 0 ;
427 for(u_int i=0;i<rdo->trg_cou;i++) {
431 switch(rdo->trg[i].csr & 0xFF000000) {
434 rh = rdo->trg[i].rhic_counter ;
436 rh_delta = rh - rh_prompt ;
439 rh_delta = (rh -
tpx_rdo_dbg[rdo->sector-1][rdo->rdo-1].old_rhic) ;
444 rh_prompt = rdo->trg[i].rhic_counter ;
445 rh_delta = rh_prompt -
tpx_rdo_dbg[rdo->sector-1][rdo->rdo-1].old_rhic ;
446 rdo->token = rdo->trg[i].data & 0xFFF ;
453 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,
454 rdo->trg[i].rhic_counter,
457 rdo->trg[i].data&0xFFF,
467 tpx_rdo_dbg[rdo->sector-1][rdo->rdo-1].delta = rh_prompt -
tpx_rdo_dbg[rdo->sector-1][rdo->rdo-1].old_rhic ;
468 tpx_rdo_dbg[rdo->sector-1][rdo->rdo-1].old_rhic = rh_prompt ;
478 if(do_log) LOG(DBG,
"Event %d: sector %2d, rdo %d, type %d, subtype %d, token %d",
479 hdr->ev_cou,rdo->sector,rdo->rdo,rdo->type,rdo->subtype,rdo->token) ;
486 if(do_log && (rdo->rdo==6)) {
487 LOG(NOTE,
"\t evt %d: %u %u",hdr->ev_cou,l[0],l[1]) ;
496 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)) ;
498 if(do_log) LOG(DBG,
"RDO %d: real data...",rdo->rdo) ;
504 if((rdo->data_end - rdo->data_start) <= 0) {
505 if(rdo->token != 4097) {
506 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) ;
507 rdo->token = -EBADF ;
533 u_int *tpx_scan_to_next(u_int *now, u_int *first,
struct tpx_altro_struct *a_struct)
542 log_yes = was_log_yes = a_struct->log_err ;
550 next_altro = data_test(now,a_struct,log_yes,first) ;
554 LOG(DBG,
"Error in the bank at iter %d",iter) ;
565 if(was_log_yes && !log_yes) {
566 LOG(NOTE,
" ...but found A%03d:%02d %d words earlier",a_struct->id,a_struct->ch,store-now) ;
570 if(((next_altro-first)<-1) || ((next_altro-first)>1000000)) {
572 LOG(ERR,
"next_altro-first %d",next_altro-first) ;
585 }
while((now-first)>=1) ;
588 LOG(ERR,
"At end %d: now 0x%08X, next_altro 0x%08X, now-first 0x%08X, next-first 0x%08X",iter,
589 now,next_altro,now-first,next_altro-first) ;
595 int tpx_use_rdo(
char *rdobuff,
int bytes,
int (userfunc)(
struct tpx_altro_struct *a,
void *arg),
void *arg)
605 t = tpx_get_start(rdobuff, bytes/4, &rdo, 0) ;
607 LOG(NOTE,
"token %d, rdo %d: not an altro event",t,rdo.rdo) ;
612 LOG(ERR,
"token %d, rdo %d: altro data error!",t,rdo.rdo) ;
616 a.what = TPX_ALTRO_DO_ADC ;
618 a.sector = rdo.sector ;
622 LOG(DBG,
"token %d, rdo %d: running through %d bytes...",t,rdo.rdo,bytes) ;
624 data_end = rdo.data_end ;
627 data_end = tpx_scan_to_next(data_end, rdo.data_start, &a) ;
629 ret |= userfunc(&a, arg) ;
630 }
while((data_end > rdo.data_start) && data_end) ;
643 static u_int *data_test(u_int *h,
struct tpx_altro_struct *a,
int log, u_int *first)
669 if((lo & 0xCFF00000) || (hi & 0xCFF00000)) {
676 if((hi & 0xFFFC0) != 0xAAA80) {
682 if((lo & 0x0F000) != 0x0A000) {
688 wc = ((hi&0x3F)<<4) | ((lo&0xF0000)>>16) ;
692 a->id = (lo & 0xFF0)>>4 ;
696 if((wc > 529) || (wc<0)) {
708 if(log) LOG(WARN,
"RDO %d: T %d: A %d:%d(?) hdr[%d]",a->rdo+1,a->t,a->id,a->ch,ret) ;
719 goto real_tpx_skipped ;
723 for(
int i=0;i<tpx_fee_override_cou;i++) {
725 if(a->sector == tpx_fee_override[i].sector) {
726 if(a->rdo == (tpx_fee_override[i].rdo-1)) {
727 int fee = a->id & 0xFE ;
728 if(fee == tpx_fee_override[i].curr_altro) {
729 int should = tpx_fee_override[i].orig_altro ;
732 should = tpx_fee_override[i].orig_altro | 1 ;
735 should = tpx_fee_override[i].orig_altro ;
753 tpx_from_altro(a->rdo, a->id, a->ch, rrow, ppad) ;
759 if((a->row > 45) || (a->pad > 182)) {
760 if(log) LOG(ERR,
"row:pad %d:%d illegal for altro %d:%d",a->row,a->pad,a->id,a->ch) ;
762 if(tpx_rdo_override==0)
return 0 ;
768 if(wc == 0)
return h ;
772 while(l10 % 4) l10++ ;
777 delta = (h - l10/2) - first ;
779 if(log) LOG(ERR,
"AID %d:%d: Bad offset %d, wrong wc %d", a->id, a->ch, delta, wc) ;
792 if(get10(h,p10) != 0x2AA) {
798 if(get10(h,p10) != 0x2AA) {
804 if(get10(h,p10) != 0x2AA) {
813 if(get10(h,p10) != 0x2AA) {
819 if(get10(h,p10) != 0x2AA) {
828 if(get10(h,p10) != 0x2AA) {
843 #ifdef VEERY_PARANOID
845 for(
int i=0;i<l10/4;i++) {
846 if(h[-i] & 0xCFF00000) {
848 if(log) LOG(ERR,
" Bad form 0x%08X at %d",h[-i],i) ;
856 if(log) LOG(WARN,
"RDO %d: T %d: A %d:%d(?) hdr[%d]",a->rdo+1,a->t,a->id,a->ch,ret) ;
866 u_short *p_adc = a->adc ;
867 u_short *p_tb = a->tb ;
871 int tb_cou = get10(h,p10++) ;
872 int tb_last = get10(h,p10++) ;
873 int tb_prev_last = tb_prev ;
892 if((tb_cou > wc) || (tb_cou <= 0) || (tb_cou > 512)) {
897 if((tb_last < 0) || (tb_last >= tb_prev)) {
911 tb_prev = tb_last - tb_cou ;
919 if(log) LOG(WARN,
"RDO %d: T %d: A %d:%d(?) dta[%d]: pprev %d, prev %d, last %d, cou %d",a->rdo+1,a->t,a->id,a->ch,ret,
920 tb_prev_last,tb_prev,tb_last,tb_cou) ;
925 if(a->what & TPX_ALTRO_DO_ADC) {
926 for(;tb_last > tb_prev; tb_last--) {
927 *p_adc++ = get10(h, p10++) ;
944 if(log) LOG(ERR,
"RDO %d: token %d: Altro %03d:%02d (?) data [2]",a->rdo+1,a->t,a->id,a->ch) ;
948 a->count = p_adc - a->adc ;
965 static int check_emul(u_int *a)
972 for(i=0;i<200000;i++) {
975 should = ((i&0xFFFF)<<16)|(i&0xFFFF) ;
979 LOG(ERR,
"Mismatch %d: at %d: should 0x%08X, is 0x%08X",errors,i,should,dta) ;
980 if(errors > 3) break ;
988 LOG(NOTE,
"Emul evt checks OK...") ;
994 static inline u_int get10(u_int *l, u_int p)
1002 ret = (l[-1] & 0xFFC00) >> 10 ;
1005 ret = (l[-1] & 0x3FF) ;
1008 ret = (l[0] & 0xFFC00) >> 10 ;
1012 ret = l[0] & 0x3FF ;
1022 void tpx_analyze_log(
int sector,
int rdo,
char *buff)
1028 LOG(WARN,
"tpx_analyze_log: deprecated!") ;
1030 len = strlen(buff) ;
1036 for(i=0;i<len;i++) {
1037 if(start_ptr[i] ==
'\n') {
1039 if(strlen(start_ptr)) {
1041 LOG(INFO,
"[Sec_%02d:RDO_%d] %s",sector,rdo,start_ptr) ;
1043 start_ptr = start_ptr + i + 1 ;
1044 len = strlen(start_ptr) ;
1054 int tpx_show_status(
int sector,
int rb_mask,
int *altro_list)
1063 for(rb=0;rb<6;rb++) {
1065 if((1<<rb) & rb_mask) ;
1068 rdo = &(
tpx_rdo[sector-1][rb]) ;
1070 if(rdo->sector != sector || (rb+1) != rdo->rdo) {
1071 LOG(WARN,
"msc: config for RDO %d: sector %d, rdo %d claims error",rb+1,rdo->sector & 0x7F,rdo->rdo) ;
1075 LOG(NOTE,
"msc: config for RDO %d: sector %d, rdo %d",rb+1,rdo->sector,rdo->rdo) ;
1078 LOG(NOTE,
"msc: Remote %d, temp rdo %d, temp stratix %d",rdo->remote,rdo->temp_rdo,rdo->temp_stratix) ;
1079 LOG(NOTE,
"msc: Compiled on %s",rdo->compilation_date) ;
1081 LOG(NOTE,
"\t FPGAs: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X",
1082 rdo->fpga_usercode[0],
1083 rdo->fpga_usercode[1],
1084 rdo->fpga_usercode[2],
1085 rdo->fpga_usercode[3],
1086 rdo->fpga_usercode[4]
1089 for(
int i=0;i<5;i++) {
1090 if((expected_usercode[i] != rdo->fpga_usercode[i]) && (rdo->fpga_usercode[i] != (u_int)(i+1))) {
1091 LOG(WARN,
"msc: RDO %d: FPGA %d usercode is 0x%08X, expect 0x%08X!?",rdo->rdo,i,rdo->fpga_usercode[i],expected_usercode[i]) ;
1095 if(rdo->status_xilinx) {
1096 LOG(ERR,
"msc: RDO %d: xilinx status: 0x%02X",rdo->rdo,rdo->status_xilinx) ;
1100 LOG(NOTE,
"RDO %d: xilinx status: 0x%02X",rdo->rdo,rdo->status_xilinx) ;
1102 if(rdo->status_cpld) {
1103 LOG(ERR,
"msc: RDO %d: CPLD status: 0x%02X",rdo->rdo,rdo->status_cpld) ;
1107 LOG(NOTE,
"RDO %d: CPLD status: 0x%02X",rdo->rdo,rdo->status_cpld) ;
1111 memset(altro,0,
sizeof(altro)) ;
1114 for(
int a=0;a<256;a++) {
1115 altro[a] = altro_list[a] ;
1119 for(
int a=0;a<256;a++) {
1120 for(
int c=0;c<16;c++) {
1123 tpx_from_altro(rb,a,c,row,pad) ;
1133 for(
int i=0;i<tpx_odd_fee_count;i++) {
1134 if((tpx_odd_fee[i].sector != sector) || (tpx_odd_fee[i].rdo != (rb+1))) continue ;
1135 for(
int j=0;j<2;j++) {
1136 for(
int a=0;a<256;a++) {
1137 if(!altro[a]) continue ;
1139 if((tpx_odd_fee[i].altro_id_padplane + j) == a) {
1141 LOG(WARN,
"Marking ALTRO %3d (FEE %03d) as unneeded because it is marked bad in the gain file...",
1142 a,tpx_odd_fee[i].tpc_fee_padplane) ;
1150 LOG(NOTE,
"Checking override map [%d]",tpx_fee_override_cou) ;
1152 int in_fee[32], should_be[32] ;
1154 for(
int i=0;i<tpx_fee_override_cou;i++) {
1155 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,
1156 tpx_fee_override[i].orig_altro,tpx_fee_override[i].curr_altro) ;
1158 if(sector == tpx_fee_override[i].sector) {
1159 if((rb+1) == tpx_fee_override[i].rdo) {
1160 in_fee[over] = tpx_fee_override[i].curr_altro ;
1161 should_be[over] = tpx_fee_override[i].orig_altro ;
1163 LOG(WARN,
"Expect to override wrong altro %3d with correct altro %3d!",tpx_fee_override[i].curr_altro,tpx_fee_override[i].orig_altro) ;
1175 for(
int b=0;b<3;b++) {
1176 for(
int c=0;c<12;c++) {
1177 int altro = rdo->fee[b][c].id ;
1183 for(u_int i=0;i<
sizeof(tpx_fee_override)/
sizeof(tpx_fee_override[0]);i++) {
1184 int r = tpx_fee_override[i].rdo ;
1185 int s = tpx_fee_override[i].sector ;
1187 if(r==rdo->rdo && s==rdo->sector) ;
1190 if(altro==tpx_fee_override[i].curr_altro) {
1191 altro = tpx_fee_override[i].orig_altro ;
1197 if(rdo->sector==6 && rdo->rdo==3) {
1198 if(altro==200 || altro==214) {
1205 int fee_expect = tpx_rdo_fees(rdo->rdo, fcou) ;
1206 int altro_expect = -1 ;
1208 if(fee_expect != 255) {
1209 altro_expect = (fee_expect << 1) & 0xFF ;
1212 if(rdo->fee[b][c].fee_status) {
1213 if(altro_expect != altro) {
1214 LOG(WARN,
"RDO %d: at %d:%d: expect %d, got %d",rdo->rdo,b,c,altro_expect,altro) ;
1219 if(altro_expect != -1) {
1220 LOG(WARN,
"RDO %d: at %d:%d: expect %d, got %d",rdo->rdo,b,c,altro_expect,altro) ;
1231 for(
int b=0;b<3;b++) {
1232 for(
int c=0;c<12;c++) {
1233 int ix = rdo->fee[b][c].id ;
1235 if((altro[ix] & 2)) {
1236 LOG(ERR,
"Duplicate ALTRO %d status 0x%X at %d:%d",ix,altro[ix],b,c) ;
1239 if(rdo->fee[b][c].fee_status) {
1242 altro[ix+1] |= 0x2 ;
1244 if(rdo->fee[b][c].jumpers != 3) {
1249 if(rdo->fee[b][c].fee_status == 1) {
1254 altro[ix+1] |= 0x8 ;
1258 if(altro[ix] != 3) {
1263 for(
int i=0;i<over;i++) {
1264 if((in_fee[i] == ix) || ((in_fee[i]+1)==ix)) {
1265 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,
1266 rdo->fee[b][c].pad_id,
1268 rdo->fee[b][c].jumpers,
1270 rdo->fee[b][c].x_s>>4,
1271 rdo->fee[b][c].x_s&1,
1272 rdo->fee[b][c].fee_status,
1282 for(
int i=0;i<tpx_odd_fee_count;i++) {
1283 if((tpx_odd_fee[i].altro_id_padplane == ix) || ((tpx_odd_fee[i].altro_id_padplane+1) == ix)) {
1285 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,
1286 rdo->fee[b][c].pad_id,
1288 rdo->fee[b][c].jumpers,
1290 rdo->fee[b][c].x_s>>4,
1291 rdo->fee[b][c].x_s&1,
1292 rdo->fee[b][c].fee_status,
1303 LOG(ERR,
"msc: Sector %2d, RDO %d: %2d: FEE %3d (A%3d,%d) [port %d:%d:%d] = 0x%X, 0x%X",
1304 sector,rdo->rdo,fcou,
1305 rdo->fee[b][c].pad_id,
1307 rdo->fee[b][c].jumpers,
1309 rdo->fee[b][c].x_s>>4,
1310 rdo->fee[b][c].x_s&1,
1311 rdo->fee[b][c].fee_status,
1325 for(
int a=0;a<256;a++) {
1326 if(altro[a] == 0) continue ;
1327 if(altro[a] == 3) continue ;
1330 int fee = tpx_altro_to_fee(rb+1,a) ;
1335 for(
int i=0;i<over;i++) {
1336 if((a == should_be[i]) || (a == (should_be[i]+1))) {
1337 LOG(WARN,
"Sector %2d, RDO %d: ALTRO %3d missing but was overriden: status 0x%X",sector,rb+1,a,altro[a]) ;
1343 if(overriden) continue ;
1346 LOG(ERR,
"msc: Sector %2d, RDO %d: ALTRO %3d [FEE %3d] missing: status 0x%X",sector,rb+1,a,fee,altro[a]) ;
1351 LOG(WARN,
"msc: Sector %2d, RDO %d: ALTRO %3d [FEE %3d] odd status: status 0x%X",sector,rb+1,a,fee,altro[a]) ;
1352 if((altro[a] & 0xB)==0xB) {
1372 int tpx_analyze_msc(
int sector,
int rb,
char *buff,
int *altro_list)
1380 LOG(NOTE,
"RDO %d: msc event, should be %d bytes",rb+1,
sizeof(
struct tpx_rdo)) ;
1382 return tpx_show_status(sector,1<<rb,altro_list) ;