/* --------------------------------------------------------------------------- * Test functions for Timlet and Timrun * * Author : J.B.Lane UCL December 2000 timcode.c * --------------------------------------------------------------------------- */ #include "ask.h" #include "timlet.h" #include #include /* rand */ #include /* strcat strcpy */ #include /* ctime */ /***int TIM_FIRST_L1ID ;*/ int timOrbit; int timVersion ; int getOrbit (void) { return timOrbit; } int getVersion (void) { return timVersion; } void setOrbit (const int orbit) { timOrbit = orbit; } void setVersion (const int version) { timVersion = version; } /* --------------------------------------------------------------------------- */ int check_clk (void) { int error = 0 ; int status ; int status3 ; if (debug_level > 2) printf("debug3: Entering check_clk...\n"); status = reg[STATUS]; /**** store status value to ensure printout matches decision */ status3 = reg[STATUS3]; if (isTIM3) { /*** TIM3 */ if ((status3 & (bTtcClkEnOK | bExtClkEnOK | bIntClkEnOK)) == 0) { printf("check_clk: ERROR - No clock OK! Status3 %04x\n", status3); error = 1 ; } } else { /*** TIM2 */ if ((status & TIM_OK) == 0) { printf ("check_clk: TIM_OK FAILURE: bit OFF, status %04x, delays %04x\n", status, reg[DELAYS]) ; error = 1 ; } if ((status & SAclkON) == 0) { printf ("check_clk: CLOCK FAILURE: Stand-alone clock OFF, status %04x, delays %04x\n", status, reg[DELAYS]) ; error = 1 ; } } if (debug_level > 2) printf("debug3: Leaving check_clk...\n"); return error ; } /* --------------------------------------------------------------------------- */ int check_TTCclk (void) { int error = 0 ; int status; int status3; int ttc_status; if (debug_level > 2) printf("debug3: Entering check_TTCclk...\n"); status = reg[STATUS]; /**** store status value to ensure printout matches decision */ status3 = reg[STATUS3]; ttc_status = reg[TTC_STATUS]; /***/ if (isTIM3) { /* -------------- new TIM3 version ---------------- */ if (status3 & bTTCReady3) { if (debug_level>0) printf("debug: check_TTCclk: TTCrx Ready"); if (status3 & bTtcClkOK3) { if (debug_level>0) printf(", TTC Clock Detected, "); if (reg[RUN_ENABLE] & bEnTTCClk) { if (debug_level>0) printf("and Enabled\n"); if ((status3 & bTtcClkEnOK) == 0) { printf("check_TTCclk: FAILURE: TTCClkEn, but no TTC-Clock-Enabled-OK!\n"); error = 1; } } else if (debug_level>0) printf("but not enabled\n"); printf("check_TTCclk: TTC clock present, but not enabled\n"); } if (ttcRQ_present) { if (debug_level>0) printf ("check_TTCclk: QPLL present, "); if (status3 & bQpllLocked) { if (debug_level>0) printf("and locked.\n"); } else { if (debug_level>0) printf("and not locked\n"); printf("check_TTCclk: WARNING: QPLL present, but not locked.\n"); error = 1 ; } } } else { if (debug_level>0) printf("check_TTCclk: TTCrx not Ready"); if (TTCrx_ready) { error = 1; printf ("check_TTCclk: FAILURE: TTCready lost!\n"); } } /* check for errors vs. profile_tim */ if (ttcRQ_present) { if ((status3 & bQpllPresent) == 0) printf ("check_TTCclk: ERROR! Lost QPLL!\n"); if (QPLL_lockable) if ((status3 & bQpllLocked) == 0) printf ("check_TTCclk: WARNING: QPLL not locked.\n"); } } else { /*** -------------- original TIM2 version ---------------- */ if ((status & TIM_OK) == 0) { printf ("TIM_OK FAILURE: bit OFF, status %04x, delays %04x\n", status, reg[DELAYS]) ; error = 1 ; } if (status3 & bTTCReady3) { printf("TTCrx Ready"); if (status & TTCclkON) { printf(", TTC Clock Detected, "); if (reg[RUN_ENABLE] & EnTTCClk) printf("and Enabled"); else printf("but not Enabled"); } printf(".\n"); } else { printf("check_TTCclk: Warning: TTCrx Not Ready. status %04x, enRun %04x, TTCcmd %04x.\n", status, reg[RUN_ENABLE], ttc_status); if ((reg[RUN_ENABLE] & EnTTCClk) == 1) printf("check_TTCclk: CLOCK FAILURE: TTC Clock Enabled, but OFF!\n"); error = 1; } } if (debug_level > 2) printf("debug3: Leaving check_TTCclk...\n"); return error ; } /* --------------------------------------------------------------------------- */ int checkBCID (const int outmask, const int next) { static int lastBCID = NONE ; int error = 0 ; int bcid ; if (debug_level > 2) printf("debug3: Entering checkBCID...\n"); bcid = *reg_BCid & 0xFFF ; if (lastBCID == NONE) lastBCID = 0 ; /* bcid ; ***/ if (outmask == 0) ; /***/ else if (outmask & L1A) { if (next != NONE) error += timCheck ("checkBCID: post L1A: (bcid, want)", bcid, next) ; else if (next == NONE && bcid == lastBCID) /* actually it's allowed */ { error = 0 ; printf ("Info: checkBCID: post L1A, BCIDs equal: bcid %04x\n", bcid) ; } } else error += timCheck ("checkBCID: post (bcid, want)", bcid, lastBCID) ; if (outmask != PresetNextL1ID) lastBCID = bcid ; if (debug_level > 2) printf("debug3: Leaving checkBCID...\n"); return error ; } /* --------------------------------------------------------------------------- */ int checkID (const int outmask, const int next) { int error = 0 ; if (debug_level > 2) printf("debug3: Entering checkID...\n"); error += checkL1ID (outmask, next) ; error += checkBCID (outmask, next) ; if (debug_level > 2) printf("debug3: Leaving checkID...\n"); return error ; } /* --------------------------------------------------------------------------- */ int checkL1ID (const int outmask, const int next) { static int lastL1ID = NONE ; static int nextL1ID = NONE ; /* value depends on when last reset */ int error = 0 ; int l1id ; if (debug_level > 2) printf("debug3: Entering checkL1ID...\n"); l1id = timGetL1ID( *reg_L1lo, *reg_L1hi ) ; if (lastL1ID == NONE) /* Setup at first time called */ lastL1ID = l1id ; if (outmask == PresetNextL1ID) nextL1ID = next ; /* test if ECR resets L1ID */ else if (outmask & ECR) { /* from v9 still last trig, reset next trig... *** test this and ECR counter *** */ if (timVersion < 9) error += timCheck ("checkID: post ECR, L1ID non-zero: l1id=", l1id, 0) ; else error += timCheck ("checkID: post ECR, LIID value unexpected: (l1id, want)=", l1id, lastL1ID) ; nextL1ID = TIM_FIRST_L1ID ; } /* test if L1A increments L1ID */ else if (outmask & L1A) { error += timCheck ("checkID:postL1A LIID! l1id want", l1id, nextL1ID) ; nextL1ID = (l1id + 1) & 0xFFFFFF ; } else { error += timCheck ("checkID:post non-ECR/L1A, L1ID change: l1id want", l1id, lastL1ID) ; } lastL1ID = l1id ; if (debug_level > 2) printf("debug3: Leaving checkL1ID...\n"); return error ; } /* --------------------------------------------------------------------------- */ int convHz2Clk (const double hertz) { double clock40_periods = (1/hertz)*40000000 ; /*printf("Hz2Clk: Converted %d Hz, to %d Clks\n", (int)hertz, (int)clock40_periods);*/ return (int)clock40_periods; } /* --------------------------------------------------------------------------- */ double convClk2Hz (const double clock40_periods) { double hertz = 40000000/clock40_periods; /*printf("Clk2Hz: Converted %d Clks, to %d Hz\n", (int)clock40_periods, (int)hertz);*/ return hertz; } /* --------------------------------------------------------------------------- */ double convClk2Sec (const int clock40_periods) { double seconds = (((double)clock40_periods)*0.000000025); /*printf("Clk2Sec: Converted %d Clks, to %d secs\n", (int)clock40_periods, (int)seconds);*/ return seconds; } /* --------------------------------------------------------------------------- */ void dump16 (char *string, volatile const unsigned short *array, const int words) { int i, n ; printf ("%s\n", string) ; n = words ; if (n > 16) n = 16 ; for (i = 0 ; i < n ; i++) printf ("%4X ", array[i]) ; printf ("\n") ; } /* --------------------------------------------------------------------------- */ void profile_tim (void) { /*int qpll_lock_chk = bQpllLocked; int i, stat3, prev_stat3 = 0;*/ int timetaken, errors=0, data16, data17; TTCrx_ready = false; ttcRQ_present = false; QPLL_lockable = false; Disable_FFTV = false; printf("\nprofile_tim: Checking TIM specifics...\n"); timReset(Silent); /*** was Quick, but that is not working too well */ timID = timGetTIMid() & 0xFF; /* get IDs, and sets 'isTIM3' */ if (reg[STATUS3] & bQpllPresent) { ttcRQ_present = true; printf("TTCrq(QPLL) present, "); errors = timTTCrxAccess (I2C_READ , 16, &data16) ; errors += timTTCrxAccess (I2C_READ , 17, &data17) ; if (errors == 0) printf("ID %02x%02x\n", (data17 & 0x3F), data16 ); else printf("but I2C communication FAILED!\n"); } timetaken = wait_state_timeout(50, TTC_STATUS, TTCready, TTCready); /* 50 ms timeout */ if (timetaken == 0) { printf("Timeout on TTCReady (assuming not functional - no more reports)\n"); } else { TTCrx_ready = true; if (!ttcRQ_present) /* Assume if not rq, and ttc is ready = TTCrm */ printf("TTCrm present\n"); printf("TTCrx ready\n"); if (isTIM3) { if (debug_level > 1) printf("debug2: profile_tim: I think I'm a TIM3\n"); if (ttcRQ_present) { /* check Qpll lots to ensure not a flash */ /* may be better to do this with a wait for 1, then wait for zero type thing */ /* pulses 6-7 secs apart, lasting 3ms */ timetaken = wait_state_timeout(500, STATUS3, bQpllLocked, bQpllLocked); /* 500 ms timeout */ timetaken = wait_state_timeout(50, STATUS3, bQpllLocked, 0); /* just in case it was spurion*/ if (timetaken == 0) { /* timeout = stable lock, so good here */ QPLL_lockable = true; printf("QPLL locked\n"); } else { printf("QPLL not locked. Assuming not functional (no more reports)\n"); } } } } if (isTIM3) { if (reg[STATUS3] & bFFTVLinkStat) printf("Found FFTV-disable link. This is also software-disabled after reset\n"); } timReset(Quiet); /* First full reset - will ***NOT report on tim setup (ttcrx present etc) */ check_clk(); check_TTCclk(); /* Should do rst_val setups here. but don't work - I've moved back to timlet.c for now */ if (debug_level > 2) printf("debug3: Leaving profile_tim...\n"); } /* --------------------------------------------------------------------------- */ void report_errors (char *name, int error_count) { printf ("-%s test: ", name) ; if (error_count != 0) printf ("Fail -- 0x%0x (%d) errors\n------------------------------------!\n", error_count, error_count) ; else printf ("Pass\n") ; } /* --------------------------------------------------------------------------- * Test a block of memory */ int test_block (volatile unsigned short *memory_ptr, unsigned int buffer[], const int nwords, const int loop, const int nmasks, const unsigned short masks[]) { static unsigned int seed = 12345678; /* 12345678 = no seed */ unsigned int pattern ; unsigned int word_read ; int iword ; int imask ; int error_count = 0 ; int i ; if (debug_level > 2) printf("debug3: Entering test_block...\n"); if (seed==12345678) { seed = 0; printf("No preset random seed.\n"); } else if (seed!=0) { srand(seed); } /* Fill memory block with random pattern */ for (i = 0 ; i < nwords ; i++) { if (loop == 0) iword = i ; else iword = rand () % nwords ; imask = iword % nmasks ; pattern = rand () ; buffer [iword] = pattern ; memory_ptr[iword] = pattern & masks[imask] ; word_read = (int)memory_ptr[iword] & masks[imask] ; if (debug_level > 8) printf("debug9: test_block wr->rd: wrote %04x, read %04x, byte %x loop %d mask %04x\n", pattern, word_read, 2*iword, loop, masks[imask]) ; if (word_read != (pattern & masks[imask])) { error_count++ ; printf ("Error: test_block wr->rd: wrote %04x, read %04x, byte %x loop %d mask %04x\n", pattern, word_read, 2*iword, loop, masks[imask]) ; } } /* Regenerate same pattern and compare */ for (iword = 0 ; iword < nwords ; iword++) { imask = iword % nmasks ; pattern = buffer[iword] ; word_read = (int)memory_ptr[iword] & masks[imask] ; if (word_read != (pattern & masks[imask])) { error_count++ ; printf ("Error: test_block wr-all->rd-all: wrote %04x, read %04x, byte %x loop %d\n", pattern, word_read, 2*iword, loop) ; } } seed = pattern ; if (debug_level > 2) printf("debug3: Leaving test_block...\n"); return (error_count) ; } /* --------------------------------------------------------------------------- */ int test_loop ( char* name, int (*test_func) (const int), int loops, int reset_level, int soak_loop ) { int error_count = 0 ; int jloop = loops * soak_loop ; int nloops = loops ; int r ; int i ; char string[99] ; if (debug_level > 2) printf("debug3: Entering test_loop...\n"); if (loops > 0) { if (reset_level > 1) timReset(Quiet); if (soak_loop < 0) { (void) strcpy(string, name) ; (void) strcat(string," test: Enter number of loops"); printf("\n"); r = ask_int(string, nloops, &nloops) ; printf("\n"); jloop = 0 ; } for (i = 0 ; i < nloops ; i ++ ) error_count += (*test_func) (i + jloop) ; if (soak_loop < 0) report_errors (name, error_count) ; } else { printf("\n%s test\n-%s test SKIPPED!\n", name, name); } if (debug_level > 2) printf("debug3: Leaving test_loop...\n"); return error_count ; } /* --------------------------------------------------------------------------- */ int test_sink (unsigned int buffer[], const int RamWords, const int SeqWords) /* assumes buffer and RAM are ready */ { unsigned int output ; unsigned int pattern ; unsigned int word_read ; int i ; int error_count = 0 ; if (debug_level > 2) printf("debug3: Entering test_sink...\n"); /* cmd LEDs flash during VME access if output enabled */ /* initial junk data could be set to 0 but it's not in RAM */ /* printf ("RamWords %04x SeqEnd %04x\n", RamWords, *reg_seq_end) ; dump16 ("RAM contents:", ram_ptr+0x3F00/2, 16) ; ram_ptr[SeqWords] = 0 ; buffer [SeqWords] = 0 ; printf ("RAM word %04x\n", ram_ptr[8]) ; */ output = 0 ; *reg_output = 0 ; /* reset */ timRunSeq (SeqWords) ; error_count += check_clk () ; timWait_seqBusys () ; /* wait for busy bits to clear */ for (i = 0 ; i < SeqWords ; i ++ ) { pattern = buffer[i] & 0xFF ; /* source */ buffer[i] = pattern + (pattern << 8) ; /* sink */ output = output | pattern ; } for (i = 0 ; i < RamWords ; i ++ ) { pattern = buffer[i] ; word_read = ram_ptr[i] ; if (word_read != (pattern & 0xffff)) { error_count++ ; printf ("test_sink: expect-sink/wrote %04x, read %04x, byte %x\n", pattern, word_read, 2*i) ; } } if (output != *reg_output) /* no &FF */ { error_count++ ; printf ("test_sink: reg_output %04x, want %04x, SeqWords %04x\n", *reg_output, output, SeqWords) ; } if (debug_level > 2) printf("debug3: Leaving test_sink.\n"); return error_count ; } /* --------------------------------------------------------------------------- */ int timCheck (const char *string, const int word1, const int word2) { int error = 0 ; int diff; if (debug_level > 2) printf("debug3: Entering timCheck...\n"); if (word1 != word2) { diff = abs(word1 - word2); printf("ERROR: %s diff_d bit (%6x %6x %6d %6x)\n", string, word1, word2, diff, diff) ; error = 1 ; } if (debug_level > 2) printf("debug3: Leaving timCheck...\n"); return error ; } /* --------------------------------------------------------------------------- */ int timGetL1ID(const int lo, const int hi) { int l1id ; if (timVersion < 9) l1id = (lo & 0xFFF) + ((hi & 0xFFF) << 12) ; else l1id = (lo & 0xFFFF) + ((hi & 0xFF) << 16) ; return l1id ; } /* --------------------------------------------------------------------------- */ int timGetTIMid(void) { int timID, timSer, lo, hi, vme ; time_t tp ; timID = reg[TIM_ID]; timSer = timID & 0xFF ; timVersion = timID >> 8 ; if ((timSer==0)||(timSer==0xFF)) { printf("\n*********************************************\n"); printf("WARNING! Can't read reasonable TIM serial No.\n"); printf("Assuming TIM-3E: Setting Ser.No. to 0x100!\n"); printf("*********************************************\n\n"); timSer = 0x100; } if (timSer >= TIMID_FPGA) { /* FPGA synthesis timestamps */ timVersion += 0x300 ; /*** why? */ isTIM3 = true; register_words = TIM3_REG_WORDS; /***/ if (debug_level > 0) printf("debug: timGetTIMid: I think I'm a TIM3!\n"); printf ("TIM Hardware Serial No. %02X\n", timSer) ; printf ("FPGA2 (TIM) Firmware Version %2X. ", (timVersion & 0xFF)) ; lo = reg[TSTAMPL] ; /* TIM (F2) timestamp lo */ hi = reg[TSTAMPH] ; /* TIM (F2) timestamp hi */ tp = (lo & 0xFFFF) + ((hi & 0xFFFF) << 16) ; printf ("Timestamp %s", ctime(&tp)) ; if (debug_level > 0) printf("\ndebug: timGetTIMid: FPGA2 timestamp hi,lo = %04x, %04x\n", hi, lo); vme = reg[TIM_ID1] ; /* FPGA1(VME) version */ printf ("FPGA1 (VME) Firmware Version %02X. ", (vme >> 8)) ; lo = reg[TSTAMP1L] ; /* F1(VME) timestamp lo */ hi = reg[TSTAMP1H] ; /* F1(VME) timestamp hi */ tp = (lo & 0xFFFF) + ((hi & 0xFFFF) << 16) ; printf ("Timestamp %s", ctime(&tp)) ; if (debug_level > 0) printf("\ndebug: timGetTIMid: FPGA1 timestamp hi,lo = %04x, %04x\n", hi, lo); } else { register_words = TIM2_REG_WORDS; /***/ printf ("\nTIM Hardware Serial No. %2X. Firmware Version %2X\n", timSer, timVersion) ; } printf ("\n") ; if (timVersion < 9) TIM_FIRST_L1ID = 1 ; else TIM_FIRST_L1ID = 0 ; return timID ; } /* --------------------------------------------------------------------------- */ void timReset (const int noise) { /* Reset needs to wait longer ... * The TTCrx takes 50ms? to reset! */ static int checkTTCrx = 1; /* set to one to ensure these are checked once */ static int checkQPLL = 1; static int checkFFTV = 1; static int checkCSB = 1; int timetaken = 0; if (debug_level > 2) printf("debug3: Entering timReset...\n"); if (debug_level == 1) printf("debug: timReset\n"); if (noise == Loud) printf("\ntimReset: Performing TIM vReset\n\n"); if (noise == Quiet) printf("\ntimReset: vReset\n\n"); if (noise == Quick) printf("timReset: Quick vReset (no checks) DOES NOTHING\n"); reg[COMMAND] = 0x8000; /* vReset*/ timetaken = wait_state_timeout(10, COMMAND, VMEreset, 0); if (timetaken == 0) printf("timReset: TIMEOUT on VMEreset bit clear\n"); if (isTIM3) reg[DEBUG_CTL] |= bCSBdisable; /* Disable long Clock-Switch-Busy ASAP */ if (TTCrx_ready) { timetaken = wait_state_timeout(50, TTC_STATUS, TTCready, TTCready); /* 50 ms timeout */ if (timetaken == 0) printf("timReset: ERROR! timeout on TTCready\n"); else if (debug_level > 1) printf("debug2: timReset: TTCrx is ready\n"); } if (ttcRQ_present) { if (QPLL_lockable) { timetaken = wait_state_timeout(500, STATUS3, bQpllLocked, bQpllLocked); /* 500 ms timeout */ if (timetaken == 0) printf("timReset: ERROR! Timeout on QPLL-lock\n"); else if (debug_level > 0) printf("debug: timReset: QPLL locked\n"); } } if (isTIM3) { reg[DEBUG_CTL] |= bFVdisable; /* No FFTV */ timetaken = wait_state_timeout(10, STATUS3, bIntClkEnOK, bIntClkEnOK); /* 1 ms timeout*/ if (timetaken == 0) printf("ERROR: timReset: Timeout on Internal-Clock-Enable-OK (IntClkEnOK)\n"); timetaken = wait_state_timeout(120, STATUS3, bPllStable, bPllStable); /* 120 ms timeout*/ if (timetaken == 0) printf("ERROR: timReset: Timeout on pll-stable signal\n"); /* just in case we miss the CSBdisable window *** must fix this in FW*/ timetaken = wait_state_timeout(900, BUSY_STAT3, bClkSwitchBusy, 0); /* 120 ms timeout*/ if (timetaken == 0) printf("ERROR: timReset: Timeout on clk-switch-busy clear\n"); } (void) checkID (PresetNextL1ID, TIM_FIRST_L1ID); if (debug_level > 2) printf("debug3: Leaving timReset...\n"); } /* --------------------------------------------------------------------------- */ void timRunSeq (const int Size) { if (debug_level > 2) printf("debug3: Entering timRunSeq...\n"); reg[ENABLES] &= bEnExtClk; /* ensure no other signals enabled, leave clk alone*/ reg[COMMAND] = 0; /* VME mode */ reg[RUN_ENABLE] &= bEnTTCClk; /* VME mode, but selected clock */ timSetupSeq (0x40FF, Size) ; /* Sink/SeqGO + all outputs enabled */ if (debug_level > 2) printf("debug3: Leaving timRunSeq...\n"); } /* --------------------------------------------------------------------------- */ void timSetupPtr (void) { /* pointer offsets are 16-bit words */ reg_srcAddr = memory_ptr + SRC_ADDR; reg_snkAddr = memory_ptr + SINK_ADDR; reg_enables = memory_ptr + 0 ; reg_command = memory_ptr + 1 ; reg_burst = memory_ptr + 2 ; reg_freqncy = memory_ptr + 3 ; reg_window = memory_ptr + 4 ; reg_delays = memory_ptr + 5 ; reg_status = memory_ptr + 6 ; reg_FIFO = memory_ptr + 7 ; reg_L1lo = memory_ptr + 8 ; reg_L1hi = memory_ptr + 9 ; reg_BCid = memory_ptr + 10 ; reg_TTid = memory_ptr + 11 ; reg_EnRun = memory_ptr + 12 ; reg_sequenc = memory_ptr + 13 ; reg_seq_end = memory_ptr + 14 ; reg_RODmask = memory_ptr + 15 ; reg_RODbusy = memory_ptr + 16 ; reg_RODheld = memory_ptr + 17 ; reg_RODmoni = memory_ptr + 18 ; reg_TTCdata = memory_ptr + 19 ; reg_TTCsel = memory_ptr + 20 ; reg_BCin = memory_ptr + 21 ; reg_TTCrx = memory_ptr + 22 ; reg_TTCcmd = memory_ptr + 23 ; reg_output = memory_ptr + 24 ; reg_TIMid = memory_ptr + 25 ; } /* --------------------------------------------------------------------------- */ void timSetupRun (void) { reg[ENABLES] = 0 ; /* ensure no other signals en */ reg[COMMAND] = RunMode ; reg[RUN_ENABLE] = 0x06FE ; /* enable TTC signals and eventID strobes, excl. TTC-clk*/ timSwitchClk(TTC); } /* --------------------------------------------------------------------------- */ void timSetupSeq (const int Mask, const int Size) { if (debug_level > 2) printf("debug3: Entering timSetupSeq...\n"); reg[SEQ_END] = Size - 1 ; reg[SEQ_CTL] = (bSeqReset | bSinkReset); /* seq reset. NEEDED. cures "write" errors? needed for new data errors! */ reg[SEQ_CTL] = 0 ; /* is this needed? */ reg[SEQ_CTL] = Mask ; if (debug_level > 2) printf("debug3: Leaving timSetupSeq...\n"); } /* --------------------------------------------------------------------------- */ void timSetupVME (void) { reg[ENABLES] = 0 ; /* ensure no other signals en */ reg[COMMAND] = 0 ; reg[RUN_ENABLE] = (EnID | EnTType) ; /* enable eventID/TType strobes */ } /* --------------------------------------------------------------------------- */ int timSwitchClk (const int dest_clk) { int error = 0; int timetaken = 0; int check_bit = 99; int enables = reg[ENABLES]; int run_enable = reg[RUN_ENABLE]; char bitname[32]; if (dest_clk == TTC) { reg[RUN_ENABLE] |= bEnTTCClk; check_bit = bTtcClkEnOK; strcpy(bitname,"bTtcClkEnOK"); } if (dest_clk == External) { reg[RUN_ENABLE] &= ~bEnTTCClk; reg[ENABLES] |= bEnExtClk; check_bit = bExtClkEnOK; strcpy(bitname, "bExtClkEnOK"); } if (dest_clk == Internal) { reg[RUN_ENABLE] &= ~bEnTTCClk; reg[ENABLES] &= ~bEnExtClk; check_bit = bIntClkEnOK; strcpy(bitname, "bIntClkEnOK"); } if (dest_clk == Standalone) { reg[RUN_ENABLE] &= ~bEnTTCClk; if (reg[ENABLES] & bEnExtClk) { check_bit = bExtClkEnOK; strcpy(bitname,"selected SA clk (bExtClkEnOK)"); } else { check_bit = bIntClkEnOK; strcpy(bitname,"selected SA clk(bIntClkEnOK)"); } } timetaken = wait_state_timeout(10, STATUS3, check_bit, check_bit); if (debug_level > 1) printf("debug2: timSwitchClk: Time taken switching clk: %d ms\n", timetaken); if (timetaken == 0) { printf("ERROR: timSwitchClk: Timeout on %s, reverting to original\n",bitname); reg[ENABLES] = enables; reg[RUN_ENABLE] = run_enable; error = 1; } else { timetaken = wait_state_timeout(120, STATUS3, bPllStable, bPllStable); if (timetaken == 0) { printf("ERROR: timSwitchClk: Timeout on bPllStable\n"); error = 1; } } return error; } /* --------------------------------------------------------------------------- */ int timTTCrxAccess (const int mode, const int addr, int *data) { int timeout = 0xFFFF ; int error = 0 ; int i = 0, busy = 1; int reg_val; reg[TTCRX_CTL] = I2C_ENABLE; /* needed on T2, clears any abort on T3 */ reg[TTCRX_CTL] = I2C_GO | I2C_ENABLE | mode | (addr << 8) | (*data & 0xFF); while ((i> 15; /* if (busy==0) printf("reg_val %04x, busy %d, loop %d.\n", reg_val, busy, i); */ } *data = reg[TTCRX_CTL] & 0xFF ; /* printf("I2C busy time %d loops.\n", i); */ if (i >= timeout) { error = 1 ; printf ("TIMEOUT: TTCrx %04X i %d\n", reg[TTCRX_CTL], i) ; } return error ; } /* --------------------------------------------------------------------------- */ void timWait_seqBusys (void) { int i ; for (i = 0 ; ((int)*reg_status & (SeqBUSY | SinkBUSY)) != 0 && i < 999 ; i ++) ; if (i >= 999) printf ("timWait_seqBusys: status %04x i %d\n", *reg_status, i) ; } /* --------------------------------------------------------------------------- */ void ttcviSetupPtr (void) { 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_IDrst = ttc_ptr + 0x8C / 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_trigword_lo = ttc_ptr + 0xCA / 2 ; ttc_trigword_hi = ttc_ptr + 0xC8 / 2 ; } /* --------------------------------------------------------------------------- */ void wait (void) { printf ("Press RETURN to continue :") ; (void) getchar() ; printf ("\n") ; } /* --------------------------------------------------------------------------- */ void wait_secs( const int timeout) { int timestart; timestart = time(0); while ((time(0)-timestart) < timeout); return; } /* --------------------------------------------------------------------------- */ int wait_state_timeout ( const int timeout, const int r, const int mask1, const int mask2) { int timetaken = 0; int time_remaining = timeout; int state; int reg_was = 0; int reg_now; int n; /*struct timespec ts; ts.tv_sec = 0; ts.tv_nsec = 1000000;*/ /* 1 milli-second steps */ state = reg[r] & mask1; while ((time_remaining > 0) && (state != mask2)) { /* this will have to wait - no nanosleep in MSVC! nanosleep (&ts, NULL); /* 1 milli-second sleep */ for(n=0; n<100000; n++) {} /* delay of 1ms set on PC25 running NT! */ reg_now = reg[r]; state = reg_now & mask1; if (debug_level > 8) { if (reg_now != reg_was) printf("debug9: wait_state_timeout: reg change: was %04x, now %04x, after %d ms.\n", (timeout - time_remaining), reg_was, reg_now); reg_was = reg_now; } time_remaining--; } timetaken = (timeout - time_remaining) + 1; /* ensure not zero */ if (time_remaining == 0) { timetaken = 0; /* Error print out generated by caller... */ if (debug_level > 1) printf ("debug1: TIMEOUT: wait_state_timeout: reg_id %d, reg %04x, timeout %d ms\n", r, reg[r], timeout); } else if (debug_level > 1) printf("debug2: wait_state_timeout: True after <%d ms, reg %04x\n", timetaken, reg[r]); return timetaken; } /* --------------------------------------------------------------------------- */