void DumpPmtVerbose(int n, uint32_t *pmt_buf, char* msg_buf) { int i,j; char msg[10000]; memset(msg,'\0',10000); for (i=0;i<n*3;i+=3) { if (!(i%32)){ sprintf(msg+strlen(msg),"No\tCh\tCell\t\tGT\tQlx\tQhs\tQhl\tTAC\tES\tMC\tLGI\tNC/CC\tCr\tBd\n"); sprintf(msg+strlen(msg),"--------------------------------------------------------------------------------------\n"); } sprintf(msg+strlen(msg),"% 4d\t%2u\t%2u\t%8u\t%4u\t%4u\t%4u\t%4u\t%u%u%u\t%1u\t%1u\t%1u\t%2u\t%2u\n", i/3, (uint32_t) UNPK_CHANNEL_ID(pmt_buf+i), (uint32_t) UNPK_CELL_ID(pmt_buf+i), (uint32_t) UNPK_FEC_GT_ID(pmt_buf+i), (uint32_t) UNPK_QLX(pmt_buf+i), (uint32_t) UNPK_QHS(pmt_buf+i), (uint32_t) UNPK_QHL(pmt_buf+i), (uint32_t) UNPK_TAC(pmt_buf+i), (uint32_t) UNPK_CMOS_ES_16(pmt_buf+i), (uint32_t) UNPK_CGT_ES_16(pmt_buf+i), (uint32_t) UNPK_CGT_ES_24(pmt_buf+i), (uint32_t) UNPK_MISSED_COUNT(pmt_buf+i), (uint32_t) UNPK_LGI_SELECT(pmt_buf+i), (uint32_t) UNPK_NC_CC(pmt_buf+i), (uint32_t) UNPK_CRATE_ID(pmt_buf+i), (uint32_t) UNPK_BOARD_ID(pmt_buf+i)); } sprintf(msg_buf+strlen(msg_buf),"%s",msg); lprintf("%s",msg); }
void *pt_read_bundle(void *args) { read_bundle_t arg = *(read_bundle_t *) args; free(args); fd_set thread_fdset; FD_ZERO(&thread_fdset); FD_SET(rw_xl3_fd[arg.crate_num],&thread_fdset); int errors = 0; uint32_t crate,slot,chan,gt8,gt16,cmos_es16,cgt_es16,cgt_es8,nc_cc; int cell; double qlx,qhs,qhl,tac; uint32_t pmtword[3]; errors += xl3_rw(READ_MEM+arg.slot_num*FEC_SEL,0x0,pmtword,arg.crate_num,&thread_fdset); errors += xl3_rw(READ_MEM+arg.slot_num*FEC_SEL,0x0,pmtword+1,arg.crate_num,&thread_fdset); errors += xl3_rw(READ_MEM+arg.slot_num*FEC_SEL,0x0,pmtword+2,arg.crate_num,&thread_fdset); if (errors != 0){ pt_printsend("There were %d errors reading out the bundles.\n",errors); unthread_and_unlock(0,(0x1<<arg.crate_num),arg.thread_num); return; } pt_printsend("%08x %08x %08x\n",pmtword[0],pmtword[1],pmtword[2]); if (arg.quiet == 0){ crate = (uint32_t) UNPK_CRATE_ID(pmtword); slot = (uint32_t) UNPK_BOARD_ID(pmtword); chan = (uint32_t) UNPK_CHANNEL_ID(pmtword); cell = (int) UNPK_CELL_ID(pmtword); gt8 = (uint32_t) UNPK_FEC_GT8_ID(pmtword); gt16 = (uint32_t) UNPK_FEC_GT16_ID(pmtword); cmos_es16 = (uint32_t) UNPK_CMOS_ES_16(pmtword); cgt_es16 = (uint32_t) UNPK_CGT_ES_16(pmtword); cgt_es8 = (uint32_t) UNPK_CGT_ES_24(pmtword); nc_cc = (uint32_t) UNPK_NC_CC(pmtword); qlx = (double) MY_UNPK_QLX(pmtword); qhs = (double) UNPK_QHS(pmtword); qhl = (double) UNPK_QHL(pmtword); tac = (double) UNPK_TAC(pmtword); pt_printsend("crate %d, slot %d, chan %d, cell %d, gt8 %08x, gt16 %08x, cmos_es16 %08x," " cgt_es16 %08x, cgt_es8 %08x, nc_cc %08x, qlx %6.1f, qhs %6.1f, qhl %6.1f, tac %6.1f\n", (int)crate,(int)slot,(int)chan,cell,gt8, gt16,cmos_es16,cgt_es16,cgt_es8,nc_cc,qlx,qhs,qhl,tac); } unthread_and_unlock(0,(0x1<<arg.crate_num),arg.thread_num); }
int CGTTest(int crateNum, uint32_t slotMask, uint32_t channelMask, int updateDB, int finalTest, int ecal) { lprintf("*** Starting CGT Test ******************\n"); uint32_t result; uint32_t bundles[3]; int crate_id,slot_id,chan_id,nc_id,gt16_id,gt8_id,es16; int missing_bundles[16],chan_errors[16][32]; char error_history[16][5000]; char cur_msg[1000]; int max_errors[16]; uint32_t badchanmask; int num_chans; // zero some stuff memset(cur_msg,'\0',1000); num_chans = 0; for (int i=0;i<32;i++) if ((0x1<<i) & channelMask) num_chans++; for (int i=0;i<16;i++){ for (int j=0;j<32;j++) chan_errors[i][j] = 0; missing_bundles[i] = 0; max_errors[i] = 0; memset(error_history[i],'\0',5000); } try{ // set up mtc mtc->ResetMemory(); //if (setup_pedestals(0,25,150,0,(0x1<<arg.crate_num)+MSK_TUB,(0x1<<arg.crate_num)+MSK_TUB)) if (mtc->SetupPedestals(0,DEFAULT_PED_WIDTH,DEFAULT_GT_DELAY,DEFAULT_GT_FINE_DELAY, (0x1<<crateNum)+MSK_TUB,(0x1<<crateNum)+MSK_TUB)){ lprintf("Error setting up mtc. Exiting\n"); return -1; } mtc->SetGTCounter(0); // set up crate for (int i=0;i<16;i++){ uint32_t select_reg = FEC_SEL*i; uint32_t crate_val = crateNum << FEC_CSR_CRATE_OFFSET; xl3s[crateNum]->RW(PED_ENABLE_R + select_reg + WRITE_REG,0x0,&result); xl3s[crateNum]->RW(CMOS_CHIP_DISABLE_R + select_reg + WRITE_REG,0xFFFFFFFF,&result); xl3s[crateNum]->RW(GENERAL_CSR_R + select_reg + WRITE_REG,crate_val | 0x6,&result); xl3s[crateNum]->RW(GENERAL_CSR_R + select_reg + WRITE_REG,crate_val,&result); xl3s[crateNum]->RW(CMOS_CHIP_DISABLE_R + select_reg + WRITE_REG,0x0,&result); } xl3s[crateNum]->DeselectFECs(); lprintf("Crate number: %d\n" "Slot and Channel mask: %08x %08x\n",crateNum,slotMask,channelMask); // select desired fecs if (xl3s[crateNum]->SetCratePedestals(slotMask,channelMask)){ lprintf("Error setting up crate for pedestals. Exiting\n"); return -1; } xl3s[crateNum]->DeselectFECs(); uint32_t num_peds = 0xFFFF + 10000; lprintf("Going to fire pulser %u times.\n",num_peds); XL3Packet packet; int total_pulses = 0; int numgt = 0; // we now send out gts in bunches, checking periodically // that we are getting the right count at the fecs for (int j=0;j<16;j++){ // we skip 4999 gtids then check each 5000th one if (j != 13) numgt = 4999; else numgt = 534; mtc->MultiSoftGT(numgt); // now loop over slots and make sure we got all the gts for (int i=0;i<16;i++){ if (((0x1<<i) & slotMask) && (max_errors[i] == 0)){ xl3s[crateNum]->RW(FIFO_DIFF_PTR_R + FEC_SEL*i + READ_REG,0x0,&result); if ((result & 0x000FFFFF) != numgt*3*num_chans){ sprintf(cur_msg,"Not enough bundles slot %d: expected %d, found %u\n", i,numgt*3*num_chans,result & 0x000FFFFF); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; missing_bundles[i] = 1; } } // end if in slot mask and not max errors } // end loop over slots // reset the fifo packet.header.packetType = RESET_FIFOS_ID; ResetFifosArgs *args = (ResetFifosArgs *) packet.payload; args->slotMask = slotMask; SwapLongBlock(args,sizeof(ResetFifosArgs)/sizeof(uint32_t)); xl3s[crateNum]->SendCommand(&packet); for (int i=0;i<16;i++) if ((0x1<<i) & slotMask && (max_errors[i] == 0)) xl3s[crateNum]->RW(GENERAL_CSR_R + FEC_SEL*i + WRITE_REG, (crateNum << FEC_CSR_CRATE_OFFSET),&result); // now send a single soft gt and make sure it looks good mtc->SoftGT(); total_pulses += numgt+1; if (j == 13) total_pulses++; // rollover bug for (int i=0;i<16;i++){ if (((0x1<<i) & slotMask) && (max_errors[i] == 0)){ uint32_t select_reg = FEC_SEL*i; xl3s[crateNum]->RW(FIFO_DIFF_PTR_R + select_reg + READ_REG,0x0,&result); if ((result & 0x000FFFFF) != 3*num_chans){ sprintf(cur_msg,"Not enough bundles slot %d: expected %d, found %u\n", i,3*num_chans,result & 0x000FFFFF); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; missing_bundles[i] = 1; } // read out one bundle for each channel badchanmask = channelMask; for (int k=0;k<((result&0x000FFFFF)/3);k++){ xl3s[crateNum]->RW(READ_MEM + select_reg,0x0,&bundles[0]); xl3s[crateNum]->RW(READ_MEM + select_reg,0x0,&bundles[1]); xl3s[crateNum]->RW(READ_MEM + select_reg,0x0,&bundles[2]); crate_id = (int) UNPK_CRATE_ID(bundles); slot_id = (int) UNPK_BOARD_ID(bundles); chan_id = (int) UNPK_CHANNEL_ID(bundles); nc_id = (int) UNPK_NC_CC(bundles); gt16_id = (int) UNPK_FEC_GT16_ID(bundles); gt8_id = (int) UNPK_FEC_GT8_ID(bundles); es16 = (int) UNPK_CGT_ES_16(bundles); badchanmask &= ~(0x1<<chan_id); if (crate_id != crateNum){ sprintf(cur_msg,"Crate wrong for slot %d, chan %u: expected %d, read %u\n", i,chan_id,crateNum,crate_id); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; chan_errors[i][chan_id] = 1; } if (slot_id != i){ sprintf(cur_msg,"Slot wrong for slot %d chan %u: expected %d, read %u\n", i,chan_id,i,slot_id); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; chan_errors[i][chan_id] = 1; } if (nc_id != 0x0){ sprintf(cur_msg,"NC_CC wrong for slot %d chan %u: expected %d, read %u\n", i,chan_id,0,nc_id); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; chan_errors[i][chan_id] = 1; } if ((gt16_id + (65536*gt8_id)) != total_pulses){ if (gt16_id == total_pulses%65536){ sprintf(cur_msg,"Bad upper 8 Gtid bits for slot %d chan %u: expected %d, read %u\n" "%08x %08x %08x\n", i,chan_id,total_pulses-total_pulses%65536,(65536*gt8_id),bundles[0], bundles[1],bundles[2]); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; }else if (gt8_id == total_pulses/65536){ sprintf(cur_msg,"Bad lower 16 gtid bits for slot %d chan %u: expected %d, read %u\n" "%08x %08x %08x\n", i,chan_id,total_pulses%65536,gt16_id,bundles[0], bundles[1],bundles[2]); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; }else{ sprintf(cur_msg,"Bad gtid for slot %d chan %u: expected %d, read %u\n" "%08x %08x %08x\n", i,chan_id,total_pulses,gt16_id+(65536*gt8_id),bundles[0], bundles[1],bundles[2]); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; } chan_errors[i][chan_id] = 1; } if (es16 != 0x0 && j >= 13){ sprintf(cur_msg,"Synclear error for slot %d chan %u.\n", i,chan_id); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; chan_errors[i][chan_id] = 1; } } // end loop over bundles being read out for (int k=0;k<32;k++){ if ((0x1<<k) & badchanmask){ sprintf(cur_msg,"No bundle found for slot %d chan %d\n",i,k); lprintf("%s",cur_msg); if ((strlen(error_history[i]) + strlen(cur_msg)) < sizeof(error_history[i])) sprintf(error_history[i]+strlen(error_history[i]),"%s",cur_msg); else max_errors[i] = 2; chan_errors[i][k] = 1; } } } // end if in slot mask and not max errors } // end loop over slots // check if we should stop any slot // because there are too many errors for (int i=0;i<16;i++){ if (((strlen(error_history[i]) > 5000) && (max_errors[i] == 0)) || (max_errors[i] == 2)){ lprintf("Too many errors slot %d. Skipping that slot\n",i); max_errors[i] = 1; } } lprintf("%d pulses\n",total_pulses); for (int i=0;i<16;i++) sprintf(error_history[i]+strlen(error_history[i]),"%d pulses\n",total_pulses); } // end loop over gt bunches if (updateDB){ lprintf("updating the database\n"); int passflag; for (int slot=0;slot<16;slot++){ if ((0x1<<slot) & slotMask){ lprintf("updating slot %d\n",slot); passflag = 1; JsonNode *newdoc = json_mkobject(); json_append_member(newdoc,"type",json_mkstring("cgt_test")); json_append_member(newdoc,"missing_bundles",json_mkbool(missing_bundles[slot])); if (missing_bundles[slot] > 0) passflag = 0; JsonNode *chan_errs = json_mkarray(); for (int i=0;i<32;i++){ json_append_element(chan_errs,json_mkbool(chan_errors[slot][i])); if (chan_errors[slot][i] > 0) passflag = 0; } json_append_member(newdoc,"errors",chan_errs); json_append_member(newdoc,"printout",json_mkstring(error_history[slot])); json_append_member(newdoc,"pass",json_mkbool(passflag)); if (finalTest) json_append_member(newdoc,"final_test_id",json_mkstring(finalTestIDs[crateNum][slot])); if (ecal) json_append_member(newdoc,"ecal_id",json_mkstring(ecalID)); PostDebugDoc(crateNum,slot,newdoc); json_delete(newdoc); // only delete the head node } } } } catch(const char* s){ lprintf("CGTTest: %s\n",s); } lprintf("Ending cgt test\n"); lprintf("****************************************\n"); return 0; }