/*FGROUP busy Operation: - read busy configuraion - read busy timers - sleep 100ms - read busy timers - calculate difference between 2 measurements and compare with busy_timer rc: busy pattern: [0..23] bits set to 1 correspond to Dead busy inputs */ w32 findDeadBusysRuns(int time){ int cix; w32 mem1[BYTIMERSCOUNTN]; // place for 24 byin* timers[0..23] +bytime counter w32 mem2[BYTIMERSCOUNTN]; int cls[7]; float dtfrac[NDET],dtperev[NDET],rate[NDET]; w32 clsbs; char ltus[200]; int rc,i,j; w32 ms100, busys=0; for(i=0;i<NDET;i++){ dtfrac[i]=0.;dtperev[i]=0.; } time=time*1000; rc= getBUSYtimerscounters(mem1); usleep(time); rc= getBUSYtimerscounters(mem2); ms100= dodif32(mem1[NCOUNTERS_BUSY_BYTIME], mem2[NCOUNTERS_BUSY_BYTIME]); // busy_timer // input dead time per event and deat time for(cix=0; cix<NDET; cix++) { // 24 byin* timers, busy_time w32 bt,btr; bt= dodif32(mem1[cix], mem2[cix]); btr= dodif32(mem1[55+cix], mem2[55+cix]); dtfrac[cix]=bt*1./ms100; rate[cix]=btr/0.4/ms100*1.e6; if(btr) dtperev[cix]=bt*0.4/btr; // in usecs //printf("findDeadBusys: bt%d:%d\n", cix, bt); if( bt<(ms100-10) ) continue; // not DEAD if at least 4 micsecs (10*0.4)in READY busys= busys | (1<<cix); }; // busy fractions for(i=1; i<7; i++){ cls[i]= vmer32(BUSY_CLUSTER+4*i); if(cls[i]){ printf("CLUSTER %d: measured time: %f milisecs\n",i,ms100*0.4/1000.); printf("Fraction DeadTime[us] Rate[Hz] Det\n"); for(j=0;j<NDET;j++){ if((1<<j) & cls[i]){ findLTUNAMESby(1<<j, 0xffffff, ltus); printf(" %2.3f %7.1f %4.1f %s\n",dtfrac[j],dtperev[j],rate[j],ltus); } } } } printf("\n"); // Plot dead busys in run for(i=1; i<7; i++){ cls[i]= vmer32(BUSY_CLUSTER+4*i); clsbs=cls[i]&busys; if(clsbs){ findLTUNAMESby(clsbs, 0xffffff, ltus); printf("CLUSTER %d busy dets:%s\n", i,ltus); } } return(0); }
void dumpFO(int board,FILE *f) { w32 offset,word; if(notInCrate(board)) return; offset=BSP*ctpboards[board].dial; fprintf(f,"FO%i==================================================== \n",board-4); word=vmer32(offset+FO_CLUSTER); fprintf(f,"CLUSTER: 0x%x\n",word); word=vmer32(offset+FO_TESTCLUSTER); fprintf(f,"FO_TESTCLUSTER/TEST_CLUSTER: 0x%x\n",word); word=vmer32(offset+FO_DELAY_L1CLST); fprintf(f,"DELAY_L1CLST: 0x%x\n",word); fprintf(f,"\n"); }
/*FGROUP SSM Stop recording. Should be issued only if recording was started in BEFORE mode. */ void SSMstoprec() { w32 status; status=vmer32(SSMstatus); if( (status & 0x4)==0) { printf("Warnining: recording not active. SSMstatus:%x going to VME/read mode\n",status); }; vmew32(SSMstop,DUMMYVAL); status=vmer32(SSMstatus); if( status & 0x4) { printf("ERROR: Cannot stop recording. SSMstatus:%x, no action\n",status); } else { SSMsetom(0); /* go to default mode: VME/read */ }; }
/*FGROUP SSM Dump SSM to file WORK/SSM.dump RC: 1->OK, 0->dump not successful */ int SSMdump() { /* in After mode: recording starts from address 1 and finishes at the address 0 which is correct, SSMaddress is set to 0 by itself after After recording. Overflow flag is not set for After mode. in Before mode: OK -SSMaddress is set by itself to right position (if overflow flag is ON. If not, we start from beginning of the memory, as in mode After Reading out memory after being initialised by SSMclear() and then filled from another LTU: Before calling SSMdump(), the SSMaddress has to be set to -1 */ w32 d,ssma; int i,words=Mega; FILE *dump; if(SSMsetom(0)) { /* VME access, read */ printf("dump not successful\n"); return(0); } else { ssma= vmer32(SSMaddress); /* printf("SSMaddress:%x\n",ssma); */ if( ((ssma & 0x80000)==0) && (SSMSCHEDULER==3)) { /* recording was done in Before mode, we should read only part of the SSM */ printf("Before mode data without Overflow flag, %d words\n",ssma); words= ssma; }; dump= fopen("WORK/SSM.dump","w"); if(dump==NULL) { printf("cannot open file WORK/SSM.dump\n"); return(0); }; d= vmer32(SSMdata); d= vmer32(SSMdata); for(i=0; i<words; i++) { /* *buf= vmer32(SSMdata); buf++; */ d= vmer32(SSMdata)&0x3ffff; /* 18 bits wide */ fwrite(&d, sizeof(w32), 1, dump); }; ssma= vmer32(SSMaddress); /* printf("SSMaddress end:%x\n",ssma); */ fclose(dump); printf("WORK/SSM.dump created in VMEWORKDIR\n"); return(1); }; }
/*-------------------------------------------------------*/ void getclocknow() { w32 bcm,om; if(micratepresent()) { bcm= vmer32(BCmain_MAN_SELECT); om= vmer32(ORBmain_MAN_SELECT); } else { bcm=bcmvme; om=omvme; //printf("novme vmer: bcm:%x om:%x\n", bcm, om); } if((bcm==3) && (om==0)) { strcpy(clocknow,"BEAM1"); clocktag=1; } else if((bcm==2) && (om==1)) { strcpy(clocknow,"BEAM2"); clocktag=2; } else if((bcm==1) && (om==2)) {strcpy(clocknow,"REF"); clocktag=3; } else if((bcm==0) && (om==2)) {strcpy(clocknow,"LOCAL"); clocktag=4; } else { strcpy(clocknow,"unknown"); clocktag=0; }; }
/*FGROUP busy 0- CTP BUSY 1-24 : detectors 25-30 : clusters 31 test cluster */ void busyprobe(char *det){ int detector; float min,max; detector=findLTUdetnum(det); if(detector == -1){ printf("Cannot find detector %s \n",det); return; } vmew32(MINIMAX_SELECT,detector); //vmew32(MINIMAX_CLEAR,0xff); sleep(1); max=0.4*vmer32(BUSYMAX_DATA); min=0.4*vmer32(BUSYMINI_DATA); printf("%i %s MIN:%f MAX:%f \n",detector,det,min,max); }
/*-------------------------------------------------------- all the boards */ int ReadTemp(int ix) { /* ix: the board (pointer to ctpboards[]) */ int i; w32 status, temp2; vmew32(TEMP_START+BSP*ctpboards[ix].dial, DUMMYVAL); for(i=0; i<3; i++) { usleep(1000); status=vmer32(TEMP_STATUS+BSP*ctpboards[ix].dial); if( (status & 0x1) == 0) goto TEMPOK; }; temp2=1000; return(temp2); TEMPOK: temp2=vmer32(TEMP_READ+BSP*ctpboards[ix].dial)&0xff; return(temp2); }
/* read BC masks from HW and print out 3564 4 (or 12)bits words */ void getBCmasks() { int ix, hchars; w32 m4_12; char m4[3*ORBITLENGTH+1]; //int bcmoffset=ORBITLENGTH-BCM_SHIFT; int bcm_shift=ORBITLENGTH-vmer32(LM_L0_TIME)-3; int bcmoffset=ORBITLENGTH-bcm_shift; vmew32(getMASK_MODE(),1); /* vme mode */ vmew32(MASK_CLEARADD,DUMMYVAL); if(l0AB()==0) { //firmAC m4_12= 0xfff; hchars= 3*ORBITLENGTH; } else { m4_12= 0xf; hchars= ORBITLENGTH; }; if(l0AB()==0) { //firmAC for(ix=0; ix<ORBITLENGTH; ix++) { if(bcmoffset>=ORBITLENGTH) bcmoffset=0; w32 c12,c; //c12=vmer32(MASK_DATA)&m4_12; c12= ~vmer32(MASK_DATA)&m4_12; // inverted in hw fro 19.5.2015 c= (c12 & 0xf00)>>8; // bcmoffset instead of ix from LM: c605 if(c>=10) m4[3*bcmoffset+0]= c-10+'a'; else m4[3*bcmoffset+0]= c+'0'; c= (c12 & 0x0f0)>>4; if(c>=10) m4[3*bcmoffset+1]= c-10+'a'; else m4[3*bcmoffset+1]= c+'0'; c= (c12 & 0x00f); if(c>=10) m4[3*bcmoffset+2]= c-10+'a'; else m4[3*bcmoffset+2]= c+'0'; bcmoffset++; //printf("ix=%i 0x%03x",ix,c12); //if(((ix+1)%66)==0)printf("\n"); }; } else { for(ix=0; ix<ORBITLENGTH; ix++) {
/* ret: 1 if timeout 0: not busy */ /*--------------------------------------------------*/ int i2cwait(int phase) { w32 itcr; int busytime=0; while(1) { itcr= vmer32(I2C_SET); if((itcr & 0x2000) == 0) break; usleep(MICSEC1); busytime= busytime+MICSEC1; if(busytime>3000) { char msg[300]; sprintf(msg, "i2cwait: timeout (%d > 3000 micsecs) phase:%d", busytime, phase); errifallowed(msg); return(1); }; }; if((itcr & 0x1000)==0x1000) { char msg[300]; sprintf(msg, "Err bit on found in i2cwait(%d)",phase); errifallowed(msg); return 2; }; //printf("i2cwait:%d micsecs in phase:%d\n",busytime,phase); return(0); }
/*---------------------- rc: 0:ok 1: at least on of the boards was not busy 10: >80mics between 1. and last stop */ int stop_ssm(int *boards) { w32 ssmstatus, seconds1,micseconds1, seconds2,micseconds2,diff; int nbs,ix,rc=0; ix=1; nbs= boards[2]; GetMicSec(&seconds1, &micseconds1); while(1) { int board; w32 boardoffset, busybit; if(ix>=nbs) ix=0; board= boards[ix]; boardoffset=BSP*ctpboards[board].dial; busybit=0x100; ssmstatus= vmer32(SSMstatus+boardoffset); if( (ssmstatus&busybit)==0 ) { printf("stopSSM: %d board not busy(SSMstatus:%x), no action\n", board, ssmstatus); rc=1; }; vmew32(SSMstop+boardoffset, DUMMYVAL); if(ix==0) break; ix++; }; GetMicSec(&seconds2, &micseconds2); if((diff=DiffSecUsec(seconds2, micseconds2, seconds1, micseconds1))>80) { rc=10; printf("startSSM: diff[usecs]=%d last SSMstatus before stop:%x\n", diff, ssmstatus); }; //printf("stop_ssm: diff:%dus\n", diff); return(rc); }
/*FGROUP SimpleTests send L1h word ower B channel. data: 12bits data words: numbe of words to be send as quickly as possible MAXW: number of words to be send in one batch (after batch is sent, the loop testing TTC_STATUS for empty fifo is started) FIFO capacity is 128 words. */ void sendB(w32 data, int words, int MAXW) { //#define MAXW 120 int ix, wordssent=0; // L1h:1 L1data:2 L2ah:3 L2adata:4 L2r:5 RoIh:6 RoIdata:7 FEEreset:8 w32 Command=1; w32 fn=0, mics1,mics2,secs1,secs2,udif; float rate; GetMicSec(&secs1, &mics1); for(ix=0; ix<words; ix++) { w32 dawo; if((ix%MAXW)==0) { int ix2; // wait for empty fifo: for(ix2=0; ix2<1000; ix2++) { dawo= vmer32(TTC_STATUS); //if(dawo&2) { // TTC FIFO full if(dawo&1) { // TTC FIFO empty fn++; goto FEMPTY; }; }; printf("Timeout when waiting for empty fifo\n"); goto STOP; }; FEMPTY: dawo= 0x80010000 | data | ((Command&0xf)<<12); vmew32(TTC_DATA, dawo); wordssent++; }; STOP: GetMicSec(&secs2, &mics2); udif= DiffSecUsec(secs2,mics2,secs1,mics1); rate= 1.*wordssent/udif; //printf("TTCfifo full: %d times\n", fn); printf("loops when waiting for empty FIFO: %d times\n", fn); printf("wordssent:%d udif:%d rate[/usec]:%f\n", wordssent, udif, rate); }
/*FGROUP INT read voltages from 1 board. Cabling in the lab: ------------------- channel: 0-7. 0-5: for LTU crates, 6:BUSY/1 L0/2 L1/6 L2/4 7:FO/0-6 (according to FO dial), INT/7 branch: 0-7 -see above (BUSY/1 -> BUSY board is channel6, branch 1 Cabling in the pit: ------------------- channel: 0: F1-FO6 + INT 1: BUSY, L0, L1, L2 2-7: branches: 0,1,2 [3] 2: crate1 alidcsvme006 sdd muon_trk muon_trg daq 3: crate2 alidcsvme007 spd tof v0 4: crate3 alidcsvme004 trd zdc emc 5: crate4 alidcsvme005 tpc pmd acorde 6: crate5 alidcsvme002 ssd fmd t0 7: crate6 alidcsvme003 hmpid phos cpv ad return: 4 channels packed in 1 32bit word */ /*------------------------------------*/ w32 i2cread(int channel, int branch) { w32 cb, i2crd; char msg[300]; //i2csetrd; int i; cb= 0x80 | (channel<<4) | branch; //printf("i2cread: cb=0x%x \n",cb); //if(i2cwait(1)) goto RET; because I2C_SET remembers last error vmew32(I2C_SET, cb); //if(i2cwait(2)) goto RET; because I2C_SET remembers last error vmew32(I2C_MUXWR, DUMMYVAL); if(i2cwait(3)) goto RET; vmew32(I2C_MUXRD, DUMMYVAL); if(i2cwait(4)) goto RET; //i2csetrd= vmer32(I2C_SET); if(i2cwait(5)) goto RET; //only for test //printf(" I2C_SET reading:%x\n", i2csetrd); vmew32(I2C_ADCWR, DUMMYVAL); if(i2cwait(6)) goto RET; //for(i=0; i<100000; i++) { vmew32(I2C_ADCRD, DUMMYVAL); if(i2cwait(7)) goto RET; //}; i2crd= vmer32(I2C_DATA); if(i2cwait(8)) goto RET; //printf("channel:%d branch:%d reading:%x: ", channel, branch,i2crd); //vme2volt(i2crd); return(i2crd); RET: sprintf(msg, "i2cread:channel:%d branch:%d device not responding.", channel, branch); errifallowed(msg); return(i2crd); }
/* returns temperature on the board in centigrades */ int ReadTemperature() { /* should work with A4 version too */ w32 temp2,status; int i,rett; vmew32(TEMP_START, DUMMYVAL); for(i=0; i<3; i++) { usleep(300); status=vmer32(TEMP_STATUS); if( (status & 0x1) == 0) goto TEMPOK; }; printf("ReadTemperature, TEMP_STATUS.BUSY timeout:\n"); return(-100); TEMPOK: temp2=vmer32(TEMP_READ)&0xff; /*printf("ReadTemperature TEMP_READ:%x\n",temp2); */ /* do the conversion from binary 2's complement */ return(temp2); }
w32 getl0ackn(){ return (vmer32(L0_TCSTATUS)&0x8)/0x8; /*w32 rc; if(l0C0()) { rc= vmer32(L0_TCSTATUSr2)&0x8)/0x8; } else { rc= vmer32(L0_TCSTATUS)&0x8)/0x8; }; return(rc); */ }
/* board:0:busy (the CLK edge for input ORBIT signal) 1..3:L0/1/2 input: busy: no sense, L0,L1:1..24 L2:1-12 edge: 0:Positive 1:Negative */ void setEdge(int board,w32 input,w32 edge){ w32 word; if(edge>1){ printf("Too big edge %i /n",edge); return; } if(board == 0){ word=vmer32(BUSY_ORBIT_SELECT); word=word&0xffffefff; if(edge) word=word | 0x1000; vmew32(BUSY_ORBIT_SELECT,word); }else{ word=vmer32(BSP*ctpboards[board].dial+SYNCH_ADD+4*(input-1)); word=word&0xfffffeff; if(edge)word=word+0x100; vmew32(BSP*ctpboards[board].dial+SYNCH_ADD+4*(input-1),word); } }
w32 getL0rqst(){ return (vmer32(L0_TCSTATUS)&0x4)/0x4; /* w32 rc; if(l0C0()) { rc= vmer32(L0_TCSTATUSr2)&0x4)/0x4; } else { rc= vmer32(L0_TCSTATUS)&0x4)/0x4; }; return(rc); */ }
/*FGROUP ConfiguratioH Print 1 line string xxxx where x is the status (0/1) of software LED word */ void getSWLEDS() { int ix; char sl[5]="0000"; slbin= vmer32(SOFT_LED); // slbin=slbin+1; for(ix=0; ix<4; ix++) { if(slbin &(1<<ix)) sl[ix]='1'; }; printf("%s\n", sl); }
int main(int argn, char **argv) { int ix, rc; w32 curdif=0; signal(SIGBUS, gotsignal); siginterrupt(SIGBUS, 0); rc= vmeopen(MINBASETX, BASEDIF16); printf("BASE vmever ltuver serial\n"); for(ix=0; ix<16; ix++) { /* max. 16 ltus in crate */ w32 code, vmever, ltuver, serial; code= 0xff&vmer32(CODE_ADD+curdif); if (code= 0x56) { vmever= 0xff&vmer32(VERSION_ADD+curdif); ltuver= 0xff&vmer32(LTUVERSION_ADD+curdif); serial= 0xff&vmer32(SERIAL_NUMBER+curdif); printf("0x%x %2x %2x %2x\n", MINBASE+curdif,vmever, ltuver, serial); }; curdif= curdif + BASEDIFF; }; rc=vmeclose(); }
/*----------------------*/ void HW_getmask(char *base, Tstatusmsg *msg) { w32 ed=0xdeadbeaf; w32 busy=0xbeaf; int rc; #ifdef SIMHW rc=0; ed= sim.xBUSY_MASK; busy= ~sim.xBUSY_MASK; //busy= sim.READ_INPUTS; printf("HW_getmask: %s ed:0x%x busy:0x%x\n", base, ed, busy); msg->ed=ed; msg->busy=busy; #else rc= vmeopen(base, "0x200"); if(rc!=0) { printf("vmeopen rc:%d base:%s\n", rc, base); return; }; ed= vmer32(BUSY_MASK); busy= vmer32(READ_INPUTS); //printf("HW_getmask: %s ed:0x%x busy:0x%x\n", base, ed, busy); msg->ed=ed; msg->busy=busy; rc= vmeclose(); #endif if(rc!=0) { printf("vmeclose rc:%d base:%s\n", rc, base); }; }
w32 vmbr32(int vsp, w32 reladr) { /* vsp: 0: -> ctp board >0: -> ltu board reladr: vme address relative to the LTUbase or CTP_BOARDbase */ if(vsp!=0) { /* ltu */ return(vmxr32(vsp,reladr)); } else { /* ctp */ return(vmer32(reladr)); }; }
/*FGROUP SSM Set operation & mode. If SSM is BUSY, an attempt is made to stop the recording. opmo values: 0x0 -VME access, read 0x1 -VME access, write 0x2 or 0x12 -RECORDING, After (cca 26 milsec) 0x3 or 0x13 -RECORDING, Before (should be stopped by SSMstoprec) if 0x10 bit set, record 7 fron panel input signals regardless of the global/standalone LTU mode RC: 0->ok, mode set 1->mode not set, possible errors (printed to stdout): BC signal not connected Cannot stop recording operation */ int SSMsetom(w32 opmo) { w32 status,opmo2; opmo2= opmo&0x3; if((opmo2==SSMomreca || opmo2==SSMomrecb)&&((vmer32(BC_STATUS)&0x3)!=0x2)) { printf("ERROR: BC signal not connected\n");/* BC not necessary for vme R/W*/ return(1); }; status=vmer32(SSMstatus); if( status & 0x4) { printf("SSM busy, stopping recording before setting new/op. mode...\n"); vmew32(SSMstop,DUMMYVAL); status=vmer32(SSMstatus); if( status & 0x4) { printf("ERROR: Cannot stop recording, operation/mode\n"); printf(" not set!\n"); return(1); }; }; vmew32(SSMcommand, opmo); return(0); }
/*FGROUP TOP FANOUT scan. Input: Common fanout input is connected to L0 source. Operation: measure number of L0 triggers for 4 phases 1st measurement: scan() phase: 0 L0s: 176075 phase: 1 L0s: 176111 phase: 2 L0s: 176111 phase: 3 L0s: 176111 scan() phase: 0 L0s: 176068 phase: 1 L0s: 176111 phase: 2 L0s: 176117 phase: 3 L0s: 176105 clock delayed by 3 ns: phase: 0 L0s: 139155 phase: 1 L0s: 176111 phase: 2 L0s: 177135 phase: 3 L0s: 176111 scan() phase: 0 L0s: 171364 phase: 1 L0s: 176147 phase: 2 L0s: 176075 phase: 3 L0s: 176111 */ void scan() { int ix; for(ix=0; ix<4; ix++) { // for 4 clock phases w32 l0s, phase; phase=ix; vmew32(CONTROL_REG, (phase | 0x4) ); vmew32(VME_RESET, DUMMY ); usleep(1000000); l0s= vmer32(L0_COUNTER); printf("phase: %d L0s: %d\n", phase, l0s); }; }
void dumpL2(FILE *f) { int i; w32 word,offset=0xb000; fprintf(f,"L2 BOARD====================================================\n"); word=vmer32(offset+ADC_SELECT); fprintf(f,"ADC_SELECT: 0x%x\n",word); word=vmer32(L2_TCSET); fprintf(f,"L2_TCSET/TC_SET: 0x%x\n",word); word=vmer32(L2_TCSTATUS); fprintf(f,"L2_TCSTATUS/TC_STATUS: 0x%x\n",word); // rate mode // fprintf(f,"CLASSES:\n"); for(i=0; i<NCLASS; i++) { w32 definition; definition=vmer32(L1_DEFINITION+4*(i+1)); fprintf(f,"%2i:0x%x",i+1,definition); fprintf(f,"\n"); } fprintf(f,"TIMING:\n"); word=vmer32(L2_DELAY_L1); fprintf(f,"DELAY_L1: 0x%x\n",word); fprintf(f,"SYNCAL (inputs delay and edge selector)\n"); for(i=0; i<11; i++) { word=vmer32(offset+4*0x141+4*i); fprintf(f,"0x%x ",word); } fprintf(f,"\n"); // pf TO BE ADDED }
/*FGROUP TOP Input: channel: number 0-23 or 24: set the dealy for all the channels delay: delay in ns, value for delay register willl be calculated: value= delay/12.5 Operation: - set Bit [2] of CONTROL_REG (ClockPhaseEnabled) to 1 ! - set channel(s) */ void setdelay(int channel, int delay) { w32 del,cr; del= delay/12.5; cr= vmer32(CONTROL_REG) | 0x2; vmew32(CONTROL_REG, cr); if(channel==24) { int channex; for(channex=0; channex<24; channex++) { vmew32(DELAY0+(channex<<4), del); }; printf("All channels set to %d ns = %x\n", delay, del); } else { vmew32(DELAY0+(channel<<4), del); printf("Channel %d is set to %d ns = 0x%x\n", channel, delay, del); }; }
/*FGROUP SimpleTests loops =0 : infinite loop Generates a lot of vme activity. */ int vmeWR(int board,int loops){ w32 data[]={0x0,0x55555555,0xaaaaaaaa,0xffffffff}; int i=0; int flag=0; int address; address=BSP*ctpboards[board].dial+ SSMdata; if(loops==0) flag=1; while((i<loops) || flag){ w32 word=data[i%4]; //printf("0x%x \n",word); vmew32(address,word); vmer32(address); i++; } return 0; }
//-------------------------------------------------------------------------- // startssm normal order, only CTP boards //------------------------------------------------------------------------- int startSSMnor(int n,int *boards){ int i,board,rc=0; w32 boardoffset, seconds1,micseconds1, seconds2,micseconds2,diff; w32 status; GetMicSec(&seconds1, &micseconds1); for(i=0;i<n;i++){ board= boards[i]; boardoffset=BSP*ctpboards[board].dial; vmew32(SSMaddress+boardoffset,0); /* micwait(30); */ status= vmer32(SSMstatus+boardoffset); vmew32(SSMstart+boardoffset, DUMMYVAL); }; GetMicSec(&seconds2, &micseconds2); if((diff=DiffSecUsec(seconds2, micseconds2, seconds1, micseconds1))>80) { rc=10; printf("startSSM: diff[usecs]=%d SSMstatus before start:%x\n",diff, status); }; return(rc); }
/*FGROUP address: rel. adress (4, 8, 12,... for 32 bits words readings) loops: 0: endless loop value: 0: read + print 1: read only >1: write, no print mics: mics between vme reads/writes. 0: do not wait between vme r/w */ void vmeloop(w32 address, int loops, w32 value, int mics) { int todoloops= loops; while(1) { if(loops>0) { if(todoloops>0) { todoloops--; } else { break; }; }; if(value<=1) { w32 val; val= vmer32(address); if(value==1) { printf("read:0x%x %u\n", val, val); fflush(stdout); //nebavi }; } else { vmew32(address, value); }; if(mics>0) micwait(mics); }; }
/*FGROUP Write/read random value into array of registers fromaddr: first address to be tested Nregs: number of consecutive addresses to be tested bitmask: e.g. 0xff -> test only bits 7..0 loops: number of loops over the array of registers */ void rndtest(w32 fromaddr, int Nregs, w32 bitmask, int loops) { int nn=0, nerrors=0; setseeds(7,3); while(1) { int ixreg; w32 address, val, val2; for(ixreg=0; ixreg<Nregs; ixreg++) { val= rounddown(bitmask * rnlx()); val= bitmask&val; address= fromaddr+(ixreg*4); vmew32(address, val); val2= vmer32(address)&bitmask; if((val!= val2) || (loops==(nn+1))) { // print last loop printf("Addr:0x%x Written:0x%x Read:0x%x\n", address, val, val2); if(val!=val2) nerrors++; }; if(nerrors>10) goto STOPTEST; }; nn++; if(nn>=loops) break; }; STOPTEST: printf("Loops:%d errors:%d\n", nn, nerrors); return; }
/*FGROUP SimpleTests Used for measuring stop ssm time by scope. */ int testStop(int board){ int i,n; int boards[6]; n=6; boards[0]=16; for(i=0;i<4;i++)boards[i+1]=i; boards[5]=5; for(i=0;i<n;i++)printf("%i board %i \n",i,boards[i]); vmew32(MINIMAX_SELECT,0x0); for(i=1;i<n;i++){ w32 busy; int boardoffset=BSP*ctpboards[boards[i]].dial; vmew32(SSMstop+boardoffset,DUMMYVAL); busy = vmer32(SSMstatus+boardoffset) & 0x001; if(busy){ printf("HW error board %i\n",boards[i]); return 1; } } //startBoardsN(6,boards,0,0); vmew32(MINIMAX_SELECT,0x0); return 0; }
/*FGROUP busy Print last busy for detectors in clusters. I get always zero - bug pedja or me. */ void printLastDetectors(w32 cluster){ w32 i,j; w32 cls,mask,timedif; float timeint; char dets[256]; w32 lastbusy[NDET+1]; for(i=0;i<NDET+1;i++)lastbusy[i]=0; vmew32(BUSYLAST_SELECT,cluster); if(memlok==0){ getBUSYtimerscounters(mem1);sleep(1);memlok=1; } getBUSYtimerscounters(mem2); timedif=dodif32(mem1[NCOUNTERS_BUSY_BYTIME],mem2[NCOUNTERS_BUSY_BYTIME]); timeint=timedif*0.4/1000.; // in milisecs mask=0; cls= vmer32(BUSY_CLUSTER+4*cluster); for(j=0;j<NDET;j++){ if((1<<j) & cls){ lastbusy[j]=dodif32(mem1[LASTBUSY1+j],mem2[LASTBUSY1+j]); mask=mask | (1<<j); } } printf("mask=%i\n",mask); if(mask){ printf("Number of LAST BUSYS per detector:\n"); printf("Time interval: %f milisec\n",timeint); for(i=0;i<NDET;i++)if(mask & (1<<i)){ findLTUNAMESby(1<<i,0xffffff,dets); printf("%20d %s\n",lastbusy[i],dets); } printf("\n"); }else{ printf("No loaded detectors in cluster %d \n",cluster); } for(i=0;i<NDET+1;i++)mem1[i]=mem2[i]; }