/* --------------------------------------------------------------------------- * Soak test program for TIM using a TTCvi module * * Author : J.B.Lane UCL January 2001 timrun.c * --------------------------------------------------------------------------- */ #include "ask.h" #include "timlet.h" #define VME_BASE_TTC 0xBAD000 /* Gordon used FF1000 */ #define TTC_FIRST_L1ID 0 #define I2C_GO 0xC000 #define I2C_BUSY 0x8000 #define I2C_ENABLE 0x4000 #define I2C_READ 0x2000 #define I2C_WRITE 0x0000 static int reset_level = 0 ; static int old_TTCrx = 0 ; static int timID ; unsigned short *ttc_ptr ; volatile unsigned short *ttc_CSR1 ; volatile unsigned short *ttc_CSR2 ; volatile unsigned short *ttc_reset ; volatile unsigned short *ttc_trig ; volatile unsigned short *ttc_L1hi ; volatile unsigned short *ttc_L1lo ; volatile unsigned short *ttc_0mod ; volatile unsigned short *ttc_0del ; volatile unsigned short *ttc_0dur ; volatile unsigned short *ttc_Bgo0 ; volatile unsigned short *ttc_0cmd ; volatile unsigned short *ttc_ladd ; volatile unsigned short *ttc_long ; volatile unsigned short *ttc_acmd ; /* volatile UINT32 *ttc_Bda0 ; ***/ 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 test_ttc (void) ; int timTTCrxAccess (const int mode, const int addr, int *data) ; int main (void) { unsigned int vme_base_addr ; int r ; r = ask ("Enter VME base address", VME_BASE_TTC, &vme_base_addr) ; ttc_ptr = vme_get_window (0x0800, vme_base_addr, DIPSY_A24) ; memory_ptr = ask_vme (0x0800) ; vme_base_addr = 0x8000 + VME_BASE_A24 ; ram_ptr = vme_get_window (0x8000, vme_base_addr, DIPSY_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 ; int ttcID ; debug_level = 0 ; ttc_CSR1 = ttc_ptr + 0x80 / 2 ; ttc_CSR2 = ttc_ptr + 0x82 / 2 ; ttc_reset = ttc_ptr + 0x84 / 2 ; ttc_trig = ttc_ptr + 0x86 / 2 ; ttc_L1hi = ttc_ptr + 0x88 / 2 ; ttc_L1lo = ttc_ptr + 0x8A / 2 ; ttc_0mod = ttc_ptr + 0x90 / 2 ; ttc_0del = ttc_ptr + 0x92 / 2 ; ttc_0dur = ttc_ptr + 0x94 / 2 ; ttc_Bgo0 = ttc_ptr + 0x96 / 2 ; ttc_0cmd = ttc_ptr + 0xB2 / 2 ; ttc_ladd = ttc_ptr + 0xC0 / 2 ; ttc_long = ttc_ptr + 0xC2 / 2 ; ttc_acmd = ttc_ptr + 0xC4 / 2 ; /*ttc_Bda0 = (volatile UINT32 *) ttc_0cmd ; ***/ ttcID = 0 ; 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) ; (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 () ; timID = timGetTIMid() & 0xFF ; timReset(Loud) ; /* reset including TTCrx before Setup */ (void) checkID (PresetNextL1ID, TTC_FIRST_L1ID) ; /* reset */ /* NB new TTCrx has 50us reset... * wait for TTCReady and I2C not BUSY */ i = wait_state_timeout (reg_TTCrx , 0x8000, 0x0000) ; /* TTCready == 0 and I2C not BUSY don't find old TTCrx */ timSetupRun () ; test_ttc () ; errors += test_loop( "CMDS", test_cmds, 3, reset_level, -1 ) ; errors += test_loop( "LONG", test_long, 3, 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_output = 0 ; /* reset */ wait_state_timeout (reg_output, BCR, BCR) ; *reg_output = 0 ; /* reset */ wait_state_timeout (reg_output, BCR, BCR) ; for (i = 0 ; i < nloops ; i ++ ) { loop = i ; if (nloops == 1) loop = -1 ; if (reset_level > 0) timReset(Quiet) ; timSetupRun () ; errors += test_loop( "TRIG", test_trig, 3, reset_level, loop ) ; /* NB sink has first trigger, registers have last... */ if (debug_level > 1) timDump (TIM_RAM_SIZE, 1) ; errors += test_loop( "SER", test_ser, 3, reset_level, loop ) ; errors += test_loop( "I2C", test_i2c, 0, reset_level, loop ) ; } errors += test_loop( "NEW", test_new, 3, reset_level, loop ) ; report_errors ("ALL", errors) ; timReset(Quiet) ; /* reset including TTCrx */ } /* --------------------------------------------------------------------------- */ int test_cink (const int mask) { int i, error = 0 ; /* 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 ! */ 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 ; int l1id ; int test ; int cmd ; /* NB old TTCrx uses these cmds to INIT etc... set unused bit 0x20 */ for (icmd = 0 ; icmd < 8 ; icmd ++ ) { *reg_TTCcmd = 0 ; /* reset */ *reg_output = 0 ; /* reset */ cmd = (1 << icmd) | 0x20 ; *ttc_acmd = cmd ; /* send command */ 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: l1id want", l1id, nextL1ID) ; error += timCheck ("CMDs: output want", *reg_output, Brcst[icmd]) ; error += timCheck ("CMDs: TTCcmd want", *reg_TTCcmd, cmd | 0x4600) ; /* Ready + BrcstStr1/2 */ if (debug_level > 1) { printf ("reg_output %04X reg_TTCcmd %04X\n", *reg_output, *reg_TTCcmd) ; } } 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 < 2 ; 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_TTCcmd = 0 ; /* reset */ *reg_output = 0 ; /* reset */ *reg_TTCsel = 0 ; /* TTCrx DQ=0 trigger type */ error += timCheck ("TYPE: output want", *reg_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: ttcdat want", *reg_TTCdata, TYPE) ; /* sub-address = 0 */ error += timCheck ("TYPE: ttid want", *reg_TTid & 0x3FF, TYPE) ; error += timCheck ("TYPE: l1id want", l1id, nextL1ID) ; error += timCheck ("TYPE: output want", *reg_output, STT) ; error += timCheck ("TYPE: TTCcmd want", *reg_TTCcmd, 0x4800) ; /* Ready + DoutStr */ if (debug_level > 1) { printf ("TTid %04X\n", *reg_TTid & 0x3FF) ; printf ("reg_output %04X reg_TTCcmd %04X\n", *reg_output, *reg_TTCcmd) ; } return error ; } /* --------------------------------------------------------------------------- */ int test_new (const int loop) { int error_count = 0 ; error_count += test_cink (0x4000) ; 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 = 0x8000 ; else mask = 0x4000 ; error_count += test_cink (mask) ; if (debug_level > 3) timDump (TIM_RAM_SIZE, 1) ; return error_count ; } /* --------------------------------------------------------------------------- */ int test_trig (const int loop) { static int nextL1ID = TTC_FIRST_L1ID + 1 ; int error = 0 ; int data ; int bcin ; int bcip ; int bcid ; int l1id ; int type ; int offset ; data = loop & 0xFF ; if (old_TTCrx == 0) { error += timTTCrxAccess (I2C_READ , 0, &data) ; /* doesn't work yet */ } data = loop & 0xFF ; *ttc_ladd = 0x8000 ; /* long-format broadcast to TTCrx internal */ *ttc_long = data ; /* send long-format data to sub-address 0 */ *reg_TTCcmd = 0 ; /* reset */ *reg_output = 0 ; /* reset */ if (debug_level > 1) { l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16) ; printf ("\nTTC L1id %06X\n", l1id) ; printf("L1lo %04X L1hi %04X BCid %03X\n", *reg_L1lo, *reg_L1hi, *reg_BCid); printf ("reg_output %04X reg_TTCcmd %04X\n", *reg_output, *reg_TTCcmd) ; } type = *reg_L1lo & 0xFF ; 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! */ *ttc_ladd = 0x8001 ; /* long-format broadcast to TTCrx external */ *ttc_long = type ; /* send long-format data - 8-bit trigger type */ *ttc_trig = 0 ; /* no data */ /* wait after trig ? ***/ error += checkID (TRG, NONE) ; l1id = *ttc_L1lo + ((*ttc_L1hi & 0xFF) << 16) ; error += timCheck ("TTC : l1id want", l1id, nextL1ID) ; nextL1ID = (l1id + 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_BCin & 0xFFF ; bcid = *reg_BCid & 0xFFF ; bcip = (bcid + offset) % 3565 ; error += timCheck ("TTC : bcin want", bcin, bcip) ; if (bcin < 6) printf("BCin %03X, BCip %03X, BCid %03X\n", bcin,bcip,bcid); if (bcin > 3563) printf("BCin %03X, BCip %03X, BCid %03X\n", bcin,bcip,bcid); error += timCheck ("TTC : output want", (*reg_output & ~BCR), TRG) ; /* BCR maybe or not */ /* BCR maybe or not... 4F00 is strobes without BCR ! BCR now fixed ***/ error += timCheck ("TTC : TTCcmd want", (*reg_TTCcmd & ~0x0601), 0x4900) ; /* Ready + DoutStr + Trig */ if (error > 0) { printf("L1lo %04X L1hi %04X BCid %03X\n", *reg_L1lo, *reg_L1hi, *reg_BCid); } if (debug_level > 1) { printf ("TTC L1id %06X\n", l1id) ; printf("L1lo %04X L1hi %04X BCid %03X\n", *reg_L1lo, *reg_L1hi, *reg_BCid); printf ("reg_output %04X reg_TTCcmd %04X\n", *reg_output, *reg_TTCcmd) ; } return error ; } /* --------------------------------------------------------------------------- */ void test_ttc (void) { int error_count = 0 ; int data = 0xFFFFFFFF ; int i ; printf ("TTC CSR1 %04X CSR2 %04X\n", *ttc_CSR1, *ttc_CSR2) ; *ttc_reset = 0 ; /* no data TTCvi reset */ *ttc_CSR1 = 0xC ; /* VME L1A + Orbit */ *ttc_CSR2 = 0xFE00 ; /* reset + repeat 0 */ printf ("TTC CSR1 %04X CSR2 %04X\n", *ttc_CSR1, *ttc_CSR2) ; i = timTTCrxAccess (I2C_READ, 3, &data) ; /* read control reg */ printf ("I2C read %04X\n", data) ; if (i != 0) { old_TTCrx = 1 ; printf ("TTCrx is old ???3\n") ; /* this is unreliable - often no I2C timeout */ } /* 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 ; error_count += check_TTCclk () ; *reg_BCid = SCToffset << 12 ; /* delay for TTCrx... * NB fine delay gives serialID bit errors if TIM delay switch is wrong */ /* 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 */ *ttc_long = 0x03E3 ; /* send long-format data to sub-address 3 */ } /* --------------------------------------------------------------------------- */ int timTTCrxAccess (const int mode, const int addr, int *data) { int timeout = 0xFFFF ; int error = 0 ; int i ; *reg_TTCrx = I2C_ENABLE ; *reg_TTCrx = I2C_ENABLE | I2C_GO | mode | (addr << 8) | (*data & 0xFF) ; for (i = 0 ; ((int)*reg_TTCrx & I2C_BUSY) != 0 && i < timeout ; i ++) ; *data = *reg_TTCrx & 0xFF ; /* 36 loops printf ("wait loops %X\n", i) ; */ if (i >= timeout) { error = 1 ; printf ("TIMEOUT: TTCrx %04X i %d\n", *reg_TTCrx, i) ; } return error ; }