/* --------------------------------------------------------------------------- * Soak test program for TIM using a TTCvi module * * Author : J.B.Lane UCL January 2001 timrun.c * --------------------------------------------------------------------------- */ #include "ask.h" #include "vme.h" #include "timlet.h" static int reset_level = 0 ; static int old_TTCrx = 0 ; /***static int timID ;*/ void timrun (void) ; int test_cmds (const int) ; int test_i2c (const int) ; int test_long (const int) ; int test_new (const int) ; int test_ser (const int) ; int test_cink (const int) ; int test_trig (const int) ; void ttcvi_init(const int) ; int timTTCrxAccess (const int mode, const int addr, int *data) ; int main (void) { unsigned int vme_base_addr ; int r ; r = ask ("Enter TTCvi VME base address", VME_BASE_TTC, &vme_base_addr) ; ttc_ptr = vme_get_window (0x0800, vme_base_addr, VME_MODE_A24) ; /*** memory_ptr = ask_vme (0x0800) ; */ (void) tim_vme (0x10000); ram_ptr = memory_ptr + TIM_RAM_SIZE ; /* offset is 16-bit words */ /*** vme_base_addr = 0x8000 + VME_BASE_A24 ; ram_ptr = vme_get_window (0x8000, vme_base_addr, VME_MODE_A24) ; */ /* above assumes VME_BASE_A24 and DIPSY_A24 for TIM RAM */ if (memory_ptr != NULL) timrun () ; else printf ("Error opening VME window\n") ; vme_end () ; return (0) ; } /* --------------------------------------------------------------------------- */ void timrun (void) { int errors = 0 ; int nloops, loop, i ; debug_level = 0 ; ttcviSetupPtr(); (void) ask_int("ALL test: Enter number of loops", 1, &nloops) ; (void) ask_int ("Enter debug level", debug_level, &debug_level) ; (void) ask_int ("Enter reset level", reset_level, &reset_level) ; timSetupPtr () ; /*** added this - not really useful... YET! */ profile_tim() ; timReset(Loud) ; /* reset including TTCrx before Setup */ ttcvi_init (Loud) ; /* first one */ (void) checkID (PresetNextL1ID, TTC_FIRST_L1ID) ; /* reset */ /* NB new TTCrx has 50us reset... * wait for TTCReady and I2C not BUSY */ wait_secs(1); /* TTCready == 0 and I2C not BUSY don't find old TTCrx */ timSetupRun(); /* ttcvi_init (Silent); */ errors += test_loop( "CMDS", test_cmds, 0x1000, reset_level, -1 ) ; /* ttcvi_init(Silent); */ errors += test_loop( "LONG", test_long, 0x3000, reset_level, -1 ) ; *ttc_0cmd = 1 << 7 ; /* B-Go 0 data for BCR */ *ttc_0mod = 0xD ; /* B-Go 0 mode */ /**ttc_Bgo0 = 0 ; *//* no data - send */ /* NB ECR above gives 0 not TIM_FIRST_L1ID ***/ /*(void) checkID (PresetNextL1ID, TTC_FIRST_L1ID) ; */ /* TTCrx starts on 0 not 1 */ /*** NB reset checkID done in test_loop with TIM_FIRST_L1ID ***/ reg[TIM_OUTPUT] = 0 ; /* clear */ wait_state_timeout(10, TIM_OUTPUT, BCR, BCR); reg[TIM_OUTPUT] = 0 ; /* clear */ wait_state_timeout(10, TIM_OUTPUT, BCR, BCR); for (i = 0 ; i < nloops ; i ++ ) { loop = i ; if (nloops == 1) loop = -1 ; if (reset_level > 0) timReset(Quiet) ; timSetupRun () ; /* ttcvi_init (Silent); */ errors += test_loop( "TRIG", test_trig, 0x1000, reset_level, loop ) ; /* NB sink has first trigger, registers have last... */ if (debug_level > 1) timDump (TIM_RAM_SIZE, 1) ; /* ttcvi_init (Silent); */ errors += test_loop( "SER", test_ser, 0, reset_level, loop ) ; /* ttcvi_init (Silent); */ errors += test_loop( "I2C", test_i2c, 0x1000, reset_level, loop ) ; } errors += test_loop( "NEW", test_new, 0, reset_level, loop ) ; printf("\n"); report_errors ("ALL", errors) ; timReset(Quiet) ; /* reset including TTCrx */ } /* --------------------------------------------------------------------------- */ int test_cink (const int mask) { int i, error = 0 ; if (debug_level > 2) printf("debug3: Entering test_cink...\n"); /* how do we tell if seq didn't run ***/ timSetupSeq(mask, TIM_RAM_SIZE); error += test_trig (999) ; error += checkSink (TIM_RAM_SIZE, NONE, &i) ; /* errors occur if there's too much printout before checkSink * if sink started by software due to system taking the CPU ! */ if (debug_level > 2) printf("debug3: Leaving test_cink...\n"); return error ; } /* --------------------------------------------------------------------------- * test async short-format commands * NB beware of TTCrx delays *** nextL1ID ??? *** */ int test_cmds (const int loop) { static const int Brcst[] = { BCR, ECR, FER, 0, 0, 0, CAL, 0 } ; static int nextL1ID = 0; int error = 0 ; int icmd, l1id, test, cmd; /* NB old TTCrx uses these cmds to INIT etc... set unused bit 0x20 */ for (icmd = 0 ; icmd < 8 ; icmd ++ ) { if (debug_level>1) printf("Loop: %d, icmd: %2x\n", loop, icmd ); reg[TTC_STATUS] = 0 ; /* reset */ reg[TIM_OUTPUT] = 0 ; /* reset */ cmd = (1 << icmd) | 0x20 ; *ttc_acmd = cmd ; /* send command */ /* (void) wait_state_timeout(100, 0, 0, 1); *//* wait a little bit */ if (Brcst[icmd] == 0) test = SPA ; /* think about 0 instead of SPA ***/ else test = Brcst[icmd] ; error += checkID (test, NONE) ; l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16) ; error += timCheck ("CMDs: ttc_l1id want", l1id, nextL1ID) ; error += timCheck ("CMDs: TIM_OUTPUT want", reg[TIM_OUTPUT], Brcst[icmd]) ; error += timCheck ("CMDs: TTC_STATUS want", reg[TTC_STATUS], cmd | 0x4600) ; /* Ready + BrcstStr1/2 */ if (debug_level > 1) printf ("TIM_OUTPUT %04X, TTC_STATUS %04X\n", reg[TIM_OUTPUT], reg[TTC_STATUS]) ; } return error ; } /* --------------------------------------------------------------------------- */ int test_i2c (const int loop) { int error_count = 0 ; int pattern = 0xAAAA ; int addr = 0 ; int data ; for (addr = 0 ; addr < 2 ; addr ++ ) { pattern = addr ; data = pattern ; error_count += timTTCrxAccess (I2C_WRITE, addr, &data) ; data = 0xFFFFFFFF ; error_count += timTTCrxAccess (I2C_READ , addr, &data) ; if (data != pattern) { error_count ++ ; printf ("I2C read %04X write %04X addr %04X\n", data, pattern, addr) ; } } /* for (addr = 0 ; addr < 9 ; addr ++ ) { pattern = addr ; data = 0xFFFFFFFF ; error_count += timTTCrxAccess (I2C_READ , addr, &data) ; if (data != pattern) { error_count ++ ; printf ("I2C read %04X write %04X addr %04X\n", data, pattern, addr) ; } } */ return error_count; } /* --------------------------------------------------------------------------- * test async long-format esp. trigger type */ int test_long (const int loop) { static int nextL1ID = 0 ; int error = 0 ; int l1id ; reg[TTC_STATUS] = 0 ; /* reset */ reg[TIM_OUTPUT] = 0 ; /* reset */ reg[TTC_SELECT] = 0 ; /* TTCrx DQ=0 trigger type */ error += timCheck ("TYPE: output want", reg[TIM_OUTPUT], 0) ; #define TYPE 0xDA *ttc_ladd = 0x8001 ; /* long-format broadcast to TTCrx external */ *ttc_long = TYPE ; /* send long-format data - 8-bit trigger type */ error += checkID (SPA, NONE) ; /* think about 0=presetID instead of SPA ***/ l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16) ; error += timCheck ("TYPE: TTC_DATA want", reg[TTC_DATA], TYPE) ; /* sub-address = 0 */ error += timCheck ("TYPE: TTID(&03FF) want", reg[TTID] & 0x3FF, TYPE) ; error += timCheck ("TYPE: ttc_l1id want", l1id, nextL1ID) ; error += timCheck ("TYPE: TIM_OUTPUT want", reg[TIM_OUTPUT], STT) ; error += timCheck ("TYPE: TTC_STATUS want", reg[TTC_STATUS], 0x4800) ; /* Ready + DoutStr */ if (debug_level > 1) { printf ("TTID(&3FF) %04X\n", reg[TTID] & 0x3FF) ; printf ("TIM_OUTPUT %04X, TTC_STATUS %04X\n", reg[TIM_OUTPUT], reg[TTC_STATUS]) ; } return error ; } /* --------------------------------------------------------------------------- */ int test_new (const int loop) { int error_count = 0 ; error_count += test_cink (bSinkGo) ; if (debug_level > 3) timDump (TIM_RAM_SIZE, 1) ; return error_count ; } /* --------------------------------------------------------------------------- */ int test_ser (const int loop) { int error_count = 0; int mask; if (timID >= TIMID_FPGA) { mask = bEnStartSink; if (debug_level > 2) printf("TIM3 - Using EnStartSink.\n"); } else { mask = bSinkGo; if (debug_level>2) printf("TIM3 - Using SinkGo.\n"); } error_count += test_cink(mask); if (debug_level>3) timDump (TIM_RAM_SIZE, 1) ; return error_count ; } /* --------------------------------------------------------------------------- */ int test_trig (const int loop) { int error = 0 ; int data ; int bcin ; int bcip ; int bcid ; int ttc_l1id ; int tim_l1id ; int type ; int offset ; int i; static int nextL1ID = TTC_FIRST_L1ID + 1 ; /*---------------------------------------------------------------- */ if (debug_level > 2) printf("debug3: Entering test_trig...\n"); data = loop & 0xFF ; if (old_TTCrx == 0) { error += timTTCrxAccess (I2C_READ , 0, &data) ; /* doesn't work yet */ } /* Stuff for 1st loop (init) */ if (nextL1ID == (TTC_FIRST_L1ID + 1)) { /* first loop */ *ttc_CSR1 = 0xC ; /* VME L1A + Orbit */ /**** Sent trigs to offset L1ID to test TIM recieved correct L1ID ***/ for (i=0; i<5; i++) { *ttc_trig = 0 ; /* no data */ nextL1ID ++; error += checkID (TRG, NONE) ; } } /*** send fine delay to TTCrx? why ?? */ data = loop & 0xFF ; *ttc_ladd = 0x8000 ; /* long-format broadcast to TTCrx internal */ *ttc_long = data ; /* send long-format data to sub-address 0 */ if (debug_level > 0) { ttc_l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16) ; tim_l1id = ((reg[L1IDL] + ((reg[L1IDH] & 0xFF) << 16))+1) & 0xFFFFFF ; printf("\nttc_l1id %06x, tim_l1id(+1) %06x, BCID %03x\n", ttc_l1id, tim_l1id, reg[BCID]) ; printf("TIM_OUTPUT %04x, TTC_STATUS %04x (both pre-clear)\n", reg[TIM_OUTPUT], reg[TTC_STATUS]) ; } type = reg[L1IDL]+7 & 0xFF ; if (debug_level > 1) printf("Note: TType set to L1ID + 7.\n"); if (loop == 0) { timSetupSeq (0x4000, TIM_RAM_SIZE) ; } /* NB these async TYPEs override sync BCRs... try duration (was 1) ***/ /* NB if this ladd is without a long it causes test_long errors! */ /*** removed below - now ttype is sent as part of trigger sequence */ /* *ttc_ladd = 0x8001 ;*/ /* long-format broadcast to TTCrx external */ /* *ttc_long = type ; */ /* send long-format data - 8-bit trigger type */ reg[TTC_STATUS] = 0 ; /* reset */ reg[TIM_OUTPUT] = 0 ; /* reset */ /* Sent Trig */ *ttc_trig = 0 ; /* no data */ /* wait after trig ? ***/ /*** why not! */ (void) wait_state_timeout (10, 0, 0, 0); error += checkID (TRG, NONE) ; ttc_l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16); tim_l1id = ((reg[L1IDL] + ((reg[L1IDH] & 0xFF) << 16))+1) & 0xFFFFFF; /* add 1 to TIM L1ID as tim=LAST-l1id, vi=NEXT-l1id */ /*** really???*/ error += timCheck ("L1ID: TTCvi next ", ttc_l1id, nextL1ID); error += timCheck ("L1ID: TTCvi TIM ", ttc_l1id, tim_l1id); nextL1ID = (nextL1ID + 1) & 0xFFFFFF ; /* 3565 exactly required for old TTCvi giving 0 - 3564 = 0xDEC + 1 is for old TTCrx only */ if (old_TTCrx == 1) offset = SCToffset + 1 ; else offset = SCToffset ; bcin = reg[TTC_BCID] & 0xFFF ; bcid = reg[BCID] & 0xFFF ; bcip = (bcid + offset) % 3565 ; error += timCheck ("TTC : TTC_BCID want", bcin, bcip) ; /*** jbl added for debug at roll-over */ if (debug_level > 1) { if (bcin < 6) printf("TTC_BCID(&fff) %03x, bcip %03x, BCID(&fff) %03x\n", bcin,bcip,bcid); if (bcin > 3563) printf("TTC_BCID(&fff) %03x, bcip %03x, BCID(&fff) %03x\n", bcin,bcip,bcid); } error += timCheck ("TTC : TIM_OUTPUT want", (reg[TIM_OUTPUT] & ~BCR), TRG) ; /* BCR maybe or not */ /* BCR maybe or not... 4F00 is strobes without BCR ! BCR now fixed ***/ error += timCheck ("TTC : TTC_STATUS want", (reg[TTC_STATUS] & ~0x0601), 0x4900) ; /* Ready + DoutStr + Trig */ /*** not sure if this is useful! *** if (error > 0) { printf("L1IDL %04X, L1IDH %04X, BCID %03X\n", reg[L1IDL], reg[L1IDH], reg[BCID]); } */ if (debug_level > 1) { printf ("ttc_l1id %06X\n", ttc_l1id) ; printf("L1IDH/L %04x%04x, BCID %03X\n", reg[L1IDH], reg[L1IDH], reg[BCID]); printf ("TIM_OUTPUT %04X, TTC_STATUS %04X\n", reg[TIM_OUTPUT], reg[TTC_STATUS]) ; } if (debug_level > 2) printf("debug3: Leaving test_trig...\n"); return error ; } /* --------------------------------------------------------------------------- */ void ttcvi_init (const int noise) { int error_count = 0 ; int data = 0xFFFFFFFF ; int val; int i; int ttcID = 0; if (noise > Silent) printf("\n"); printf("Initialising TTCvi...\n"); *ttc_reset = 0 ; /* no data TTCvi reset */ (void) wait_state_timeout(100, 0, 0, 1); /* wait a bit */ if (noise > Silent) { for (i = 0x32/2 ; i < 0x40/2 ; i += 2) ttcID = (ttcID<<8)+(ttc_ptr[i]&0xFF); printf ("TTCvi ID %08X\n", ttcID); ttcID = 0 ; for (i = 0x42/2 ; i < 0x50/2 ; i += 2) ttcID = (ttcID<<8)+(ttc_ptr[i]&0xFF); printf ("TTCvi Rev %08X\n", ttcID); } *ttc_IDrst = 0; /* reset ID counter, I hope*/ *ttc_CSR1 = 0x0040; /* Reset FIFO */ *ttc_CSR2 = 0xFF00; /* Reset B-Go FIFOs */ *ttc_CSR1 = 0x000F; /* Event Count, Internal Orbit, No trigs */ *ttc_CSR2 = 0x0E00; /* Repeat B-Go 0 */ *ttc_L1hi = 0; /* may be overkill, but so what */ *ttc_L1lo = 0; /* may be overkill, but so what */ /* MkII only: sets TTCrx broadcast address to 0 [to emulate mk.I set to 7] */ *ttc_trigword_lo = 0x0300; /* Size=1, Ext=1, Sub-add(7:0) = 0 */ *ttc_trigword_hi = 0x0000; /* TTCrx address = boroadcast */ if (noise > Silent) { printf ("TTCvi CSR1 %04x, CSR2 %04x\n", *ttc_CSR1, *ttc_CSR2) ; printf ("TTCvi L1ID %04x%04x\n", *ttc_L1hi, *ttc_L1lo) ; } /* set TTCrx control reg value: * E3 = reset state + enable parallel bus & serial output * NB old TTCrx only *** check *** * enable parallel bus: old TTCrx: long-format & eventID * new TTCrx: long-format only */ *ttc_ladd = 0x8000; /* long-format broadcast to TTCrx internal */ val = 0x0323; /* ttcrx sub address 3, en-Parbus, en-L1ID, en_BCID */ *ttc_long = val; /* send */ i = timTTCrxAccess (I2C_READ, 3, &data) ; /* read control reg */ if (i == 0) { if (noise > Silent) printf ("Set TTCrx sub-addr(3)=%02x, I2C reg(3)=%02x\n", val&0xff, data) ; } else { old_TTCrx = 1; if (noise > Silent) printf ("TTCrx is old ???3\n") ; /* this is unreliable - often no I2C timeout */ /*** check this */ } /* transmission of synchronous command starts * at end of Inhibit signal duration, * which should exceed long-format cycle (about 1.05 us = 42 clocks) * check 42... still lose BCRs... 142 maybe ok *** * expect L1As after BCR within deadtime... need another Inhibit? *** * seen both on same clock... nextBCID error: DE7 FFFFFFFA */ *ttc_0del = 0 ; /* Inhibit 0 delay */ *ttc_0dur = 142 ; /* Inhibit 0 duration */ for (i = 0 ; i < TIM_RAM_SIZE ; i ++) ram_ptr[i] = 0 ; ram_ptr[0] = 0x8000 ; ram_ptr[9] = 0x8000 ; reg[BCID] = SCToffset << 12 ; /* delay for TTCrx... * NB fine delay gives serialID bit errors if TIM delay switch is wrong */ }