#include #include #include #include /* sleep function */ #include /* Usual interrupt handler stuff */ #include /* JRG, 1/15/03 **** CRC_CALC **** OLD, not needed after 4/5/03: Link datafile to "file.dat" before running CRC polynomial: X^22 + X + 1 (10000000000000000000011) calculate CRC-22 for 16-bit parallel data (ALCT & TMB) JRG, 4/05/03: NO FILE.DAT ANYMORE! Instead crc_calc now asks for "Run Name" before processing; it will then look for the file "run{RunName}.dat" but RunName must be a string less than 80 characters. JRG, 4/03/03: improved Empty Event handling count empty events, CFEB events, ALCT event, TMB events count board errors for multiple CSCs: use ierr_xxx for dmb, tmb count number of single- and multi-CSC events (DMB HDRs found) add call to ddu_status(evt_stat) JRG, 3/20/03: improved & added additional error checking added CFEB crc15 check uncomment ALCT l1a and bxn check To Do: add voting for DDU Special bits add detection of 16-bit offset in FIFO stream, also correction? */ // CFEB CRC15: crc15c=(buf[l]&0x1fff)^((buf[l]&0x1fff)<<1)^(((crc15c&0x7ffc)>>2)|((0x0003&crc15c)<<13))^((crc15c&0x7ffc)>>1); /* For DDU 32-bit Error/Status Decode */ void ddu_status_decode(int long code) { // JRG, some problem here: need 32-bit int for code, LONG INT? // printf("\nReceived code=%08X\n",code); // if((code&0x008FFFFF)>0){ /*Non-triggered^^^^^ status bits: bit[31:28] = Private gigabit Ethernet status bit[27:24] = details related to a triggered error bit[23:21] = less important status/warning bits */ // JRG, low-order 16-bit status (most serious errors): if((code&0x0000F000)>0){ if((0x00008000&code)>0)printf(" DDU Critical Error, ** needs reset **\n"); if((0x00004000&code)>0)printf(" DDU Single Error, bad event"); if((0x00002000&code)>0)printf(" DDU Single Warning"); if((0x00001000&code)>0)printf(" DDU Near Full Warning"); printf("\n"); } if((code&0x00000F00)>0){ if((0x00000800&code)>0)printf(" DDU RX Error"); if((0x00000400&code)>0)printf(" DDU Control DLL Error occured"); if((0x00000200&code)>0)printf(" DDU DMB Error occurred"); if((0x00000100&code)>0)printf(" DDU Lost In Event Error"); printf("\n"); } if((code&0x000000F0)>0){ if((0x00000080&code)>0)printf(" DDU Lost In Data Error occurred"); if((0x00000040&code)>0)printf(" DDU Timeout Error"); // Multiple-bit vote failures (or Rx Errors) in one 64-bit word: if((0x00000020&code)>0)printf(" DDU Critical Data Error"); // Multiple single-bit vote failures (or Rx Errors) over time from one DMB: if((0x00000010&code)>0)printf(" DDU Multiple Transmit Errors"); printf("\n"); } if((code&0x0000000F)>0){ if((0x00000008&code)>0)printf(" DDU FIFO Full Error"); if((0x00000004&code)>0)printf(" DDU Fiber Error"); if((0x00000002&code)>0)printf(" DDU L1A Match Error"); if((0x00000001&code)>0)printf(" DDU CRC Error"); printf("\n"); } if((code&0xF0000000)>0){ // JRG, high-order 16-bit status (not-so-serious errors): /*Pre-ver51 encoding: if((0x80000000&code)>0)printf(" DDU G-Bit FIFO Not Empty"); if((0x40000000&code)>0)printf(" DDU G-Bit FIFO Near Full Warning"); if((0x20000000&code)>0)printf(" DDU G-Bit FIFO Full Warning"); */ if((0x80000000&code)>0)printf(" DDU Output Limited Buffer Overflow"); if((0x40000000&code)>0)printf(" DDU G-Bit FIFO Full Warning"); if((0x20000000&code)>0)printf(" DDU G-Bit FIFO Near Full Warning"); if((0x10000000&code)>0)printf(" DDU G-Bit Fiber Error"); printf("\n"); } if((code&0x0F000000)>0){ if((0x08000000&code)>0)printf(" DDU FirstDat Error"); if((0x04000000&code)>0)printf(" DDU BadFirstWord Error"); //Pre-ver53: if((0x02000000&code)>0)printf(" DDU BadCtrlWord Error"); if((0x02000000&code)>0)printf(" DDU Data Stuck in FIFO"); if((0x01000000&code)>0)printf(" DDU NoLiveFibers Error"); printf("\n"); } if((code&0x00F00000)>0){ if((0x00800000&code)>0)printf(" DDU Spwd single-bit Warning"); if((0x00400000&code)>0)printf(" DDU Ethernet DLL Error"); if((0x00200000&code)>0)printf(" DDU S-Link Full Bit set"); if((0x00100000&code)>0)printf(" DDU S-Link Not Ready"); if((0x00300000&code)==0x00200000)printf("\n DDU S-Link Stopped (backpressure)"); printf("\n"); } if((code&0x000F0000)>0){ if((0x00080000&code)>0)printf(" DDU TMB Error"); /*Pre-ver57: if((0x00040000&code)>0)printf(" DDU FIFO-PAF Warning"); if((0x00020000&code)>0)printf(" DDU L1A-FIFO Near Full Warning"); */ if((0x00040000&code)>0)printf(" DDU Trigger Readout CRC Error"); if((0x00020000&code)>0)printf(" DDU Trigger Readout Wordcount Error"); if((0x00010000&code)>0)printf(" DDU L1A-FIFO Full Error"); printf("\n"); } } void ddu_ostatus_decode(int long code) { // JRG 4/6/03, labelled "historical" check results //printf("\nReceived code=%08X\n",code); // JRG, 16-bit DDU output path status: if((code&0x0000F000)>0){ if((0x00008000&code)>0)printf(" DDU Output Limited Buffer Overflow Error occurred\n"); if((0x00004000&code)>0)printf(" DDU SLink Wait occurred"); if((0x00002000&code)>0)printf(" DDU SLink Full occurred"); //JRG, before ver52: if((0x00001000&code)>0)printf(" DDU SLink Ready occurred"); if((0x00001000&code)>0)printf(" DDU SLink Never Ready"); printf("\n"); } if((code&0x00000F00)>0){ if((0x00000800&code)>0)printf(" DDU Gigabit Ethernet Overflow occurred"); if((0x00000400&code)>0)printf(" DDU Gigabit Ethernet FIFO Almost Full occurred"); //JRG, before ver52: if((0x00000200&code)>0)printf(" DDU Gigabit Ethernet FIFO Not Empty occurred"); if((0x00000200&code)>0)printf(" DDU Gigabit Ethernet FIFO Always Empty"); if((0x00000100&code)>0)printf(" DDU Gigabit Ethernet Fiber Error occurred"); printf("\n"); } if((code&0x000000F0)>0){ if((0x00000080&code)>0)printf(" DDU SLink Limited Overflow occurred"); if((0x00000040&code)>0)printf(" DDU SLink Wait"); if((0x00000020&code)>0)printf(" DDU SLink Full"); //JRG, before ver52: if((0x00000010&code)>0)printf(" DDU SLink Ready"); if((0x00000010&code)>0)printf(" DDU SLink Not Ready"); printf("\n"); } if((code&0x0000000F)>0){ if((0x00000008&code)>0)printf(" DDU Gigabit Ethernet FIFO Full"); if((0x00000004&code)>0)printf(" DDU Gigabit Ethernet FIFO PAF flag"); if((0x00000002&code)>0)printf(" DDU Gigabit Ethernet FIFO Not Empty"); if((0x00000001&code)>0)printf(" DDU Gigabit Ethernet Fiber Error"); printf("\n"); } } void ddu_era_decode(int long code) { //printf("\nReceived code=%08X\n",code); // JRG, 16-bit DDU Error Bus A: if((code&0x0000F000)>0){ if((0x00008000&code)>0)printf(" DDU Critical Error, ** needs reset **\n"); if((0x00004000&code)>0)printf(" DDU DMB Error occurred"); if((0x00002000&code)>0)printf(" DDU L1A-FIFO Near Full Warning"); if((0x00001000&code)>0)printf(" DDU Gigabit Ethernet FIFO PAF flag"); printf("\n"); } if((code&0x00000F00)>0){ if((0x00000800&code)>0)printf(" DDU Input-FIFO Near Full Warning"); if((0x00000400&code)>0)printf(" DDU Near Full Warning"); if((0x00000200&code)>0)printf(" DDU CFEB-CRC not OK"); if((0x00000100&code)>0)printf(" DDU CFEB-CRC End Error"); printf("\n"); } if((code&0x000000F0)>0){ if((0x00000080&code)>0)printf(" DDU CFEB-CRC Count Error"); if((0x00000040&code)>0)printf(" DDU CFEB-CRC Error occurred"); if((0x00000020&code)>0)printf(" DDU Latched Trigger Trail"); if((0x00000010&code)>0)printf(" DDU Trigger Trail_Done"); printf("\n"); } if((code&0x0000000F)>0){ if((0x00000008&code)>0)printf(" DDU Trigger Readout Error"); if((0x00000004&code)>0)printf(" DDU End Timeout"); if((0x00000002&code)>0)printf(" DDU Start Timeout"); if((0x00000001&code)>0)printf(" DDU Timeout Error occurred"); printf("\n"); } } void ddu_erb_decode(int long code) { //printf("\nReceived code=%08X\n",code); // JRG, 16-bit DDU Error Bus B: if((code&0x0000F000)>0){ if((0x00008000&code)>0)printf(" DDU Lost In Event Error"); if((0x00004000&code)>0)printf(" DDU DMB Error occurred"); if((0x00002000&code)>0)printf(" DDU Control DLL Error occured"); if((0x00001000&code)>0)printf(" DDU 2nd Header First flag"); printf("\n"); } if((code&0x00000F00)>0){ if((0x00000800&code)>0)printf(" DDU Early 2nd Trailer flag"); if((0x00000400&code)>0)printf(" DDU Extra 1st Trailer flag"); if((0x00000200&code)>0)printf(" DDU Extra Trigger Trailer flag"); if((0x00000100&code)>0)printf(" DDU Extra 2nd Header flag"); printf("\n"); } if((code&0x000000F0)>0){ if((0x00000080&code)>0)printf(" DDU CFEB-DMB Error flag"); if((0x00000040&code)>0)printf(" DDU First Header flag"); if((0x00000020&code)>0)printf(" DDU Lone Word Event flag"); if((0x00000010&code)>0)printf(" DDU Bad Control Word Error occurred"); printf("\n"); } if((code&0x0000000F)>0){ if((0x00000008&code)>0)printf(" DDU Missed Trigger Trailer Error occurred"); if((0x00000004&code)>0)printf(" DDU First Dat Error"); if((0x00000002&code)>0)printf(" DDU Bad First Word"); if((0x00000001&code)>0)printf(" DDU Lost In Data occured"); printf("\n"); } } void ddu_erc_decode(int long code) { //printf("\nReceived code=%08X\n",code); // JRG, 16-bit DDU Error Bus C: if((code&0x0000F000)>0){ if((0x00008000&code)>0)printf(" DDU Trigger Readout Error"); if((0x00004000&code)>0)printf(" DDU ALCT Trailer Done"); if((0x00002000&code)>0)printf(" DDU ALCT DAV Vote True occurred"); if((0x00001000&code)>0)printf(" DDU do_ALCT flag"); printf("\n"); } if((code&0x00000F00)>0){ if((0x00000800&code)>0)printf(" DDU ALCT CRC Error"); if((0x00000400&code)>0)printf(" DDU ALCT Wordcount Error"); if((0x00000200&code)>0)printf(" DDU Missed ALCT Trailer"); if((0x00000100&code)>0)printf(" DDU ALCT Error"); printf("\n"); } if((code&0x000000F0)>0){ if((0x00000080&code)>0)printf(" DDU Compare Trigger CRC flag"); if((0x00000040&code)>0)printf(" DDU TMB Trailer Done"); if((0x00000020&code)>0)printf(" DDU TMB DAV Vote True occurred"); if((0x00000010&code)>0)printf(" DDU do_TMB flag"); printf("\n"); } if((code&0x0000000F)>0){ if((0x00000008&code)>0)printf(" DDU TMB CRC Error"); if((0x00000004&code)>0)printf(" DDU TMB Word Count Error"); if((0x00000002&code)>0)printf(" DDU Missed TMB Trailer"); if((0x00000001&code)>0)printf(" DDU TMB Error"); printf("\n"); } } main(){ int ierr,i,j,k,l,m,n,num,ev=0,buf[4],l1offset=0,prev_offset,bx_offset=0,trg_bx_offset=0,ev_empty=0,ev_cfeb=0,ev_alct=0,ev_tmb=0,ev_one_csc=0,ev_mult_csc=0,ev_mult_full_csc=0; unsigned int bytes,acrc_r,tcrc_r,crc22,crc_r,crc15; unsigned int l1num=0,trg_wc,trg_mark,n_cfeb_samples=16; unsigned int idmb=0,ialct=0,itmb=0,icfeb=0,ndmb=0,nalct=0,ntmb=0,ncfeb=0,dmb_cfeb=0,prev_dmb=0,ndmb_w_cfeb=0; unsigned int evt_stat=0,evt_wc=0,istart=0,iend=99999999,trg_rd,run_stat=0; unsigned int ierr_ddu=0,ierr_dmb=0,ierr_tmb=0,ierr_alct=0,ierr_cfeb=0,ierr_rd=0,evt_error=0; int idmb_err,icfeb_err,ialct_err,itmb_err,iread_err; int bxn,dmb_bxn,tmb_bxn,alct_bxn; unsigned int dmb_l1a,tmb_l1a,tmb_nfeb,tmb_nts,tmb_active,tmb_dump,tmb_mode; unsigned int alct_l1a,alct_nts,alct_active,alct_dump,alct_mode; unsigned int ibx_err=0,NoDMBhdr=0,dmbdav,ddu_in[16],cscerr[16],dmb_id; int orbit=3564,iGAP; //Note that lowest 7-bits of 3564=0xDEC is 0x6C=108 int p_dmbdduoffset=4,n_dmbdduoffset=-124; int p_dmbtmboffset=1,n_dmbtmboffset=-1; // -1 <= range <= 1 int p_dmbalctoffset=4,n_dmbalctoffset=3; int p_ddutmboffset=-3,n_ddutmboffset=-5; // -5 <= range <= -3 int p_ddualctoffset=128,n_ddualctoffset=127; //why so big? cable? below... FILE *fp,*fpout; char Filename[90]; char RunName[80]; // extern void ddu_status_decode; // ALCT BX offset: p_ddualctoffset=124; n_ddualctoffset=-3440; //why so big? cable ~75ns=3BX //iGAP=(bxn+p_dmbdduoffset-orbit>0); //GAPfix: p_dmbdduoffset=p_dmbdduoffset-108; n_dmbdduoffset=n_dmbdduoffset+108; crc15=0; crc_r=0; crc22=0; acrc_r=0; tcrc_r=0; printf("Input Run Name: "); scanf("%s",RunName); sprintf(Filename,"run%s.dat",RunName); fp=fopen(Filename,"r"); //fp=fopen("file.dat","r"); printf("\n BEGIN Processing Run file run%s.dat \n",RunName); ierr=1; while(ierr>0){ ierr=fscanf(fp,"%d %04x %04x %04x %04x\n",&num,&buf[3],&buf[2],&buf[1],&buf[0]); if(ierr<=0)printf(" ierr=%d, END OF FILE\n",ierr); // printf("Read in word %d: %04x %04x %04x %04x\n",num,buf[3],buf[2],buf[1],buf[0]); // check for DDU HDR3: DMB_CNT, DMB_DAV if((num==3)&&(num==istart+2)){ istart=0; ndmb=(buf[0]&0x000f); dmbdav=buf[1]&0x00007FFF; if(ndmb>15)ndmb=16; j=0x00000001; k=-1; for(i=0;i=15)ddu_in[i]=-1; } ddu_in[i]=k; } } // Begin new event on num==1: if(num==1){ iend=99999999; // check for DDU Event Header if((buf[3]&0xf000)!=0x5000){ printf(" *** New event, DDU readout: Missing DDU Event Header!\n"); if(iread_err==0)ierr_rd++; iread_err=1; } } // check for 1st DMB Header2 (must occur immediately after DDU header!) if(num==4&&((buf[3]&0xf000)!=0xa000)&&((buf[2]&0xf000)!=0xa000)&&((buf[1]&0xf000)!=0xa000)&&((buf[0]&0xf000)!=0xa000)){ NoDMBhdr=1; ev_empty++; // printf(" *** Missing 1st DMB Header2!\n"); } // check for DDU special bit if((buf[3]&0x8000)>0){ // ALCT trail found: if((buf[2]&0xffff)==0xde0d){ // Compare ALCT CRC results: ialct++; if(ialct>nalct)printf(" *** too many ALCTs: read %d, expected %d\n",ialct,nalct); acrc_r=(((buf[1]&0x07ff)<<11)|(buf[0]&0x07ff)); trg_wc=(buf[3]&0x03ff); trg_rd=((num-trg_mark)*4); if(trg_wc!=trg_rd){ printf(" *** ALCT wordcount error: read %d (0x%x), expected %d (0x%x)\n",trg_rd,trg_rd,trg_wc,trg_wc); ialct_err++; } if(crc22!=acrc_r){ printf(" *** ALCT crc calculated=%06x, received=%06x: ",crc22&0x03fffff,acrc_r&0x03fffff); printf("ALCT CRC failed! \n"); ialct_err++; } /* else{ printf("ALCT CRC passed! \n"); } */ acrc_r=0; // dmb_l1a,dmb_bxn,alct_bxn,alct_l1a,alct_nts,alct_active,alct_dump, // alct_mode: 0=NoDump/1=FullDump/2=LocalDump if((l1num&0x0000000f)!=alct_l1a){ printf(" *** L1A mismatch DDU-ALCT: DDU=0x%1x, ALCT=0x%1x\n",l1num&0x000f,alct_l1a); ialct_err++; } if(ialct_err>0){ ierr_alct++; ialct_err=-999999; } // Compare DMB BXN with ALCT BXN (7-bits)....NO! // Compare DDU BXN with ALCT BXN (12-bits): trg_bx_offset=dmb_bxn-(alct_bxn&0x0000007f); trg_bx_offset=(bxn&0x00000fff)-(alct_bxn&0x00000fff); trg_bx_offset=bxn-alct_bxn; //if (1){ if((trg_bx_offset!=n_ddualctoffset) && (trg_bx_offset!=p_ddualctoffset) && ((3564+trg_bx_offset)!=n_ddualctoffset) && ((3564+trg_bx_offset)!=p_ddualctoffset)){ //if((trg_bx_offset!=n_dmbalctoffset) && (trg_bx_offset!=p_dmbalctoffset)){ //printf(" ** BXN mismatch DMB-ALCT: DMB=0x%02x, ALCT=0x%03x (dec%d), offset=%d\n",dmb_bxn,alct_bxn&0x0fff,alct_bxn&0x0fff,trg_bx_offset); printf(" ** BXN mismatch DDU-ALCT: DDU=0x%03x, ALCT=0x%03x (dec%d), offset=%d\n",bxn&0x0fff,alct_bxn&0x0fff,alct_bxn&0x0fff,trg_bx_offset); printf(" * ALCT: mode=%1d, nTimeBins=%d, active=0x%x, dumped=0x%x\n",alct_mode,alct_nts,alct_active,alct_dump); } } // TMB trail found: else if((buf[2]&0xffff)==0xde0f){ // Compare TMB CRC results: itmb++; if(itmb>ntmb)printf(" *** too many TMBs: read %d, expected %d\n",itmb,ntmb); tcrc_r=(((buf[1]&0x07ff)<<11)|(buf[0]&0x07ff)); trg_wc=(buf[3]&0x03ff); trg_rd=((num-trg_mark)*4); if(trg_wc!=trg_rd){ printf(" *** TMB wordcount error: read %d (0x%x), expected %d (0x%x)\n",trg_rd,trg_rd,trg_wc,trg_wc); itmb_err++; } if(crc22!=tcrc_r){ printf(" *** TMB crc calculated=%06x, received=%06x: ",crc22&0x03fffff,tcrc_r&0x03fffff); printf("TMB CRC failed! \n"); itmb_err++; } /* else{ printf("TMB CRC passed! \n"); } */ tcrc_r=0; // dmb_l1a,dmb_bxn,tmb_bxn,tmb_l1a,tmb_nfeb,tmb_nts,tmb_active,tmb_dump, // tmb_mode: // 0=NoDump/1=FullDump/2=LocalDump/3=NoDumpShortHdr/4=NoDumpNoHdr if((l1num&0x0000000f)!=tmb_l1a){ printf(" *** L1A mismatch DDU-TMB: DDU=0x%1x, TMB=0x%1x\n",l1num&0x000f,tmb_l1a); itmb_err++; } if(itmb_err>0){ ierr_tmb++; itmb_err=-999999; } // Compare DMB BXN with TMB BXN (one 7-bits, one 12-bits)....NO! /* trg_bx_offset=dmb_bxn-(tmb_bxn&0x0000007f); if((trg_bx_offsetp_dmbtmboffset)){ printf(" ** BXN mismatch DMB-TMB: DMB=0x%02x, TMB=0x%03x (dec%d), offset=%d\n",dmb_bxn,tmb_bxn&0x0fff,tmb_bxn&0x0fff,trg_bx_offset); ibx_err++; } */ // Compare DDU BXN with TMB BXN (12-bits): trg_bx_offset=bxn-tmb_bxn; // if (1){ if((trg_bx_offsetp_ddutmboffset)){ printf(" ** BXN mismatch DDU-TMB: DDU=0x%03x, TMB=0x%03x, offset=%d\n",bxn,tmb_bxn,trg_bx_offset); ibx_err++; } if(ibx_err>0)printf(" * TMB: mode=%1d, nTimeBins=%d, nfeb=%d, active=0x%x, dumped=0x%x\n",tmb_mode,tmb_nts,tmb_nfeb,tmb_active,tmb_dump); } // DMB header found: else if(((buf[3]&0xf000)==0xa000)&&((buf[2]&0xf000)==0xa000)&&((buf[1]&0xf000)==0xa000)&&((buf[0]&0xf000)==0xa000)) { // check for DMB header // // for MPC: if next word has (buf[0]&0x0fff)=0x0b0c then it is TMB data! // TMB data continues through the "marker word" with 4-consecutive hex "Dxxx" codes, // the 3rd of which is "DEOF" and the 4th is TMB wordcount (lowest 11-bits) // idmb++; dmb_l1a=(buf[3]&0x000000ff); dmb_bxn=(buf[2]&0x0000007f); dmb_id=(buf[1]&0x0000000f); printf(" Begin CSC #%d of %d (DDU Input #%d, DMB ID=0x%X): ",idmb,ndmb,ddu_in[idmb-1],dmb_id); if((buf[0]&0x0800)>0)ntmb++; if((buf[0]&0x0400)>0)nalct++; // Count CFEB DAVs on the DMB: dmb_cfeb=0; for(i=0;i<5;i++){ if( (buf[0]&(0x0001<0) dmb_cfeb++; // printf("i=%d, ncfeb=%d\n",i,dmb_cfeb); } printf("nCFEB=%d, nALCT=%d, nTMB=%d\n",dmb_cfeb,(buf[0]&0x0400)>>10,(buf[0]&0x0800)>>11); ncfeb=ncfeb+dmb_cfeb; // Compare DDU and DMB L1A (8-bits): if((l1num&0x000000ff)!=dmb_l1a){ printf(" *** L1A mismatch DMB-DDU: DMB=0x%x, DDU=0x%x\n",dmb_l1a,l1num); if(idmb_err==0)ierr_dmb++; idmb_err=1; } // Compare DDU and DMB BXN (7-bits): bx_offset=dmb_bxn-(bxn&0x0000007f); iGAP=(bxn+p_dmbdduoffset-orbit>0); // if (1){ if((bx_offset!=(n_dmbdduoffset+108*iGAP)) && (bx_offset!=(p_dmbdduoffset-108*iGAP))){ printf(" *** BXN mismatch DMB-DDU: DMB=0x%02x, DDU=0x%03x (dec%d), offset=%d\n",dmb_bxn,bxn&0x0fff,bxn&0x0fff,bx_offset); } } // Check for event end marker (actually "DDU Trail-2"): else if(((buf[3]&0xffff)==0x8000)&&((buf[2]&0xffff)==0xffff)&&((buf[1]&0xffff)==0x8000)&&((buf[0]&0xffff)==0x8000)) { iend=num; if(icfeb>0)ev_cfeb++; if(ialct>0)ev_alct++; if(itmb>0)ev_tmb++; if(idmb==1)ev_one_csc++; if(idmb>1)ev_mult_csc++; if(idmb!=ndmb){ printf(" *** DMB count mismatch! read %d, expected %d.\n",idmb,ndmb); evt_error++; } if(ialct0)||(ierr_dmb>0)||(ierr_alct>0)||(ierr_ddu>0)||(ierr_cfeb>0)||(ierr_rd>0))evt_error++; printf(" Event Summary (ev %d=0x%x): ",l1num,l1num); if((idmb>1)&&(ialct>1)&&(itmb>1)&&(ndmb_w_cfeb>1)){ // &&(evt_error==0) ev_mult_full_csc++; printf("Excellent Event! %d fully occupied CSCs!",ndmb_w_cfeb); } printf("\n * %d CFEBs, %d DMB, %d ALCT, %d TMB, %d DDU words read (ev %d=0x%x)\n",icfeb/n_cfeb_samples,idmb,ialct,itmb,num+2,l1num,l1num); ndmb=0; ndmb_w_cfeb=0; nalct=0; ntmb=0; ncfeb=0; idmb=0; ialct=0; itmb=0; icfeb=0; } // Check for event end (actually "DDU Trail" because iend=num at Trail-2): else if(num==iend+2){ // check for event wordcount evt_wc=((buf[3]&0x00ff)<<16)|(buf[2]&0xffff); if(num!=evt_wc){ printf(" *** Event wordcount error! DDU readout %d (0x%x), expected %d (0x%x)\n",num,num,evt_wc,evt_wc); if(iread_err==0)ierr_rd++; iread_err=1; } iend=88888888; // istart=0; } // Check for ethernet "filler" junk passed by gigabit driver; should only // happen for empty events at end of small event packet with 48 bytes! else if(((buf[3]&0xffff)==0xffff)&&((buf[2]&0xffff)==0xffff)&&((buf[1]&0xffff)==0xffff)&&((buf[0]&0xff00)==0xff00)) { bytes=(buf[0]&0x000000ff); if(iend==99999990){ // Event end should be previous word (num==6) so now check num==7 if(num!=7)printf(" ** Empty event detected with filler, but wordcount!=6: %d\n",num-1); if(bytes!=48)printf(" ** Empty event detected with filler, but data bytes!=48: %d\n",bytes); iend=99999994; } // Notify if filler junk happens in any other case: error!? else if(iend!=99999994){ if(NoDMBhdr>0)printf(" *** Missing 1st DMB Header2!\n"); printf(" *** Ethernet Filler junk detected"); if(iend!=88888888)printf(" mid-event"); if(bytes==255){ printf("! \n"); } else{ printf("! %d data bytes present\n",bytes); } iend=99999994; } } // Notify if normal empty event was detected (regardless of "filler" at end): if((iend==88888888)&&(NoDMBhdr>0)){ if(num==6){ printf(" * Empty event detected. \n"); } else{ printf(" ** Empty event detected, but wordcount!=6: %d\n",num); } iend=99999990; } // Notify if No DMB Header detected but event is Not Empty: if((iend<99999990)&&(num>6)&&(NoDMBhdr>0)){ printf(" *** Missing 1st DMB Header2 in a big event!\n"); } crc15=0; // Zero CRC22 accumulator for any non-"B" DDU special word (after CRC check) if( ((buf[3]&0xf000)==0xb000)&&((buf[0]&0xf000)==0xb000)){ printf(" *** DMB Error Code detected! \n"); if(icfeb_err==0)ierr_cfeb++; icfeb_err=1; } else{ crc22=0; trg_mark=num; } } // if no DDU special bit, check if first word of event, header info: else if((num==1) && (buf[3]&0xf000)==0x5000){ ev++; istart=num; ntmb=0; nalct=0; itmb=0; ialct=0; ncfeb=0; icfeb=0; ndmb=0; ndmb_w_cfeb=0; idmb=0; idmb_err=0; icfeb_err=0; ialct_err=0; itmb_err=0; iread_err=0; evt_error=0; NoDMBhdr=0; l1num=((buf[3]&0x00ff)<<16)|(buf[2]&0xffff); bxn=((buf[1]&0x0000fff0)>>4); ibx_err=0; printf("ev#%d: LEVEL 1 Event Number = %d (0x%x)\n",ev,l1num,l1num); if(l1num!=ev+l1offset){ prev_offset=l1offset; l1offset=l1num-ev; printf(" ** L1A number jump: %d event numbers skipped\n",l1offset-prev_offset); } } // Check for CFEB timesample end, check CFEB CRC and error code? else if(((buf[3]&0xffff)==0x7fff)&&((buf[2]&0xf000)==0x7000)&&((buf[1]&0xf000)==0x7000)){ icfeb++; if(idmb!=prev_dmb){ ndmb_w_cfeb++; prev_dmb=idmb; } crc_r=(buf[0]&0x7fff); if(crc15!=crc_r){ printf(" *** CFEB CRC failed! calculated=%04x, received=%04x: ",crc15&0x07fff,crc_r&0x7fff); printf("cfeb timesample #%d\n",icfeb); if(icfeb_err==0)ierr_cfeb++; icfeb_err=1; } /* else{ printf("CFEB CRC passed! cfeb timesample #%d\n",icfeb); } */ crc15=0; } else if(num==iend+1){ // check for event status evt_stat=((buf[3]&0xffff)<<16)|(buf[2]&0xffff); run_stat=run_stat|evt_stat; if(evt_stat!=0){ printf(" ** Non-zero DDU event status: %04X/%04X\n",((evt_stat&0xffff0000)>>16),(evt_stat&0x0000ffff)); ddu_status_decode(evt_stat); ierr_ddu++; } } // for normal data, Accumulate CRC15 and Trigger CRC22: else { for(l=0;l<4;l++)crc15=(buf[l]&0x1fff)^((buf[l]&0x1fff)<<1)^(((crc15&0x7ffc)>>2)|((0x0003&crc15)<<13))^((crc15&0x7ffc)>>1); for(l=0;l<4;l++)crc22=(buf[l]&0xffff)^ ((buf[l]&0xffff)<<1)^ (((crc22&0x3fffc0)>>6)|((0x00003f&crc22)<<16))^ ((crc22&0x3fffc0)>>5); if((num>istart+2)&&((num-trg_mark)==1)){ // get trigger event info available in 1st word of dump: // tmb_bxn,tmb_l1a,tmb_nfeb,tmb_nts; tmb_bxn=(buf[3]&0x00000fff); tmb_l1a=(buf[2]&0x0000000f); /* old TMB: tmb_nfeb=(buf[1]&0x00001c00)>>10; tmb_nts=(buf[1]&0x000003e0)>>5; */ /* E-series TMB: */ tmb_mode=(buf[1]&0x00007000)>>12; tmb_dump=(buf[1]&0x00000fe0)>>5; tmb_nts=(buf[1]&0x0000001f); alct_dump=(buf[3]&0x00003f80)>>7; alct_active=(buf[3]&0x0000007f); alct_bxn=(buf[2]&0x00000fff); alct_nts=(buf[1]&0x0000007c)>>2; alct_mode=(buf[1]&0x00000003); // alct_l1a=(buf[0]&0x0000000f); //Madorsky starts with evt #0... alct_l1a=(buf[0]+1)&0x0000000f; } else if((num-trg_mark)==2){ // get trigger event info available in 2nd word of dump: // tmb_active,tmb_dump,tmb_mode; /* old TMB: tmb_active=(buf[1]&0x0000001f); tmb_dump=(buf[0]&0x00000f80)>>7; tmb_mode=(buf[0]&0x00000003); */ /* E-series TMB: */ tmb_nfeb=(buf[0]&0x000000e0)>>5; tmb_active=(buf[2]&0x0000001f); } } } fclose(fp); printf("\nProcessed %d events: %d empty, %d single-CSC, %d multi-CSC\n",ev,ev_empty,ev_one_csc,ev_mult_csc); printf(" %d events w/CFEB, %d events w/ALCT, %d events w/TMB\n",ev_cfeb,ev_alct,ev_tmb); if(ev_mult_full_csc>0)printf(" There were %d Excellent events (full data for multiple CSCs)\n",ev_mult_full_csc); if((run_stat!=0)||(ierr_cfeb!=0)||(ierr_alct!=0)||(ierr_tmb!=0)||(ierr_dmb!=0)||(ierr_rd!=0)){ printf(" %d ev w/CFEB err, %d ev w/DMB err, %d ev w/ALCT err, %d ev w/TMB err\n",ierr_cfeb,ierr_dmb,ierr_alct,ierr_tmb); printf(" *** %d events had a DDU readout error\n",ierr_rd); if(run_stat!=0){ printf(" *** %d events ended with a DDU detected error state\n",ierr_ddu); printf(" *** run summary of Non-zero DDU status: %04X/%04X\n",((run_stat&0xffff0000)>>16),(run_stat&0x0000ffff)); ddu_status_decode(run_stat); } } }