#include #include #include #include #include #include #include "VISION.h" /* #include "crate_globals.h" #include "FinderboardVme_S.h" */ #define MAXBOARDS 22 #define MAXCABLES 160 #define MAXSTRLEN 132 #define ERR_FATAL 1 #define ERR_ERROR1 2 #define ERR_WARN1 3 #define ERR_INFO1 4 #define ERR_ERROR2 5 #define ERR_WARN2 6 #define ERR_INFO2 7 /* hard-wire the test for the UIUC test setup with only one finder and one TDC */ #define TRACERSLOT 2 #define TESTCLOCKSLOT 4 #define FINDERSLOT 11 #define TDCSLOT 13 /**************************************************************************** * finderboard_capture server side code Jay R. Dittmann 13-DEC-2000 * * Purpose: This is _very_ specialized code to run an TDC->Finder * input capture test in one crate. It is optimized for * speed. Up to 8 core input chips are used. * ****************************************************************************/ /* Prototypes */ void errout(char *str, int level); /* Global vars */ static const unsigned int EMPTY = 0; static const unsigned int FINDER13 = 1; static const unsigned int FINDER24 = 2; static const unsigned int FINDER = 3; static const unsigned int TDC = 4; static const unsigned int TESTCLOCK = 5; static const unsigned int TRACER = 6; static const unsigned int CRATECPU = 7; static const char *boardType[] = {"(empty)","Finder 1/3","Finder 2/4", "Finder","TDC","Testclock","TRACER", "Crate CPU"}; static int isRunning = 0; static int forceStop = 0; static unsigned int numCables; static unsigned int CableMap[MAXCABLES]; static unsigned int clockSlot; /* After init, should be 0-21 */ static unsigned int tracerSlot; /* After init, should be 1-21 */ static unsigned int maxEvents; static unsigned int maxIters; static unsigned int testMode; static unsigned long numLoops[MAXCABLES]; static unsigned long numErrors[MAXCABLES]; static unsigned long totalLoops; static unsigned long totalErrors; VISION_SLAVE boardHandle[MAXBOARDS]; static int debugLevel = ERR_INFO2; void task3(void); /******************/ /* START FUNCTION */ /******************/ /* cable map for now: cable 1: TDC in slot TDCSLOT, Finder in slot FINDERSLOT, finder is a SL2-4 finder. TDC TM header A -- 0 Finder TM header E -- 4 cable 2: TDC TM header B -- 1 Finder TM header D -- 3 try all finder cable possibilities as a test */ void run(void) { unsigned int num_cables=2; unsigned int cable_map[16]; unsigned int clock_slot=TESTCLOCKSLOT; unsigned int tracer_slot=TRACERSLOT; unsigned int max_events=1; unsigned int max_iters=1; unsigned int mode=1; int assignXTCConstants(int reset); unsigned int i; char tstr[MAXSTRLEN]; /* first cable -- TDC in slot 13, TDC conn A=0, no tdcdebug, finder slot 11, finder conn E=4, finder type =L24 */ /* second cable -- TDC in slot 13, TDC conn B=1, no tdcdebug, finder slot 11, finder conn D=3, finder type =L24 */ /* cable_map[0] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (0<<13) + (1<<16); cable_map[1] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (1<<13) + (1<<16); cable_map[2] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (2<<13) + (1<<16); cable_map[3] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (3<<13) + (1<<16); cable_map[4] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (4<<13) + (1<<16); cable_map[5] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (5<<13) + (1<<16); cable_map[6] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (6<<13) + (1<<16); cable_map[7] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (7<<13) + (1<<16); cable_map[8] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (0<<13) + (1<<16); cable_map[9] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (1<<13) + (1<<16); cable_map[10] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (2<<13) + (1<<16); cable_map[11] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (3<<13) + (1<<16); cable_map[12] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (4<<13) + (1<<16); cable_map[13] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (5<<13) + (1<<16); cable_map[14] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (6<<13) + (1<<16); cable_map[15] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (7<<13) + (1<<16); */ cable_map[0] = TDCSLOT + (0<<5) + (3<<6) + (FINDERSLOT<<8) + (4<<13) + (1<<16); cable_map[1] = TDCSLOT + (1<<5) + (3<<6) + (FINDERSLOT<<8) + (3<<13) + (1<<16); /*** If the test is already running, return ***/ if (isRunning) { sprintf(tstr,"TDC->Finder Capture test already running. Exiting...\n"); errout(tstr,ERR_FATAL); return; } /*** Check for valid Testclock slot (0 = None) */ if (clock_slot < 0 || clock_slot > 21) { sprintf(tstr,"A Testclock must be in a valid slot. Exiting...\n"); errout(tstr,ERR_FATAL); return; } /*** Check for valid TRACER slot (a TRACER must be present) */ if (tracer_slot < 1 || tracer_slot > 21) { sprintf(tstr,"A TRACER is required for the TDC->Finder Capture test. Exiting...\n"); errout(tstr,ERR_FATAL); return; } /*** Make sure there's at least one cable, but less than MAXCABLES */ if (num_cables < 1 || num_cables > MAXCABLES) { sprintf(tstr,"The number of cables is out of range. Exiting...\n"); errout(tstr,ERR_FATAL); return; } /*** Make sure the number of loops is at least one */ if (max_events < 1 || max_iters < 1) { sprintf(tstr,"At least 1 loop is required for the TDC->Finder Capture test. Exiting...\n"); errout(tstr,ERR_FATAL); return; } /*** Get ready to start a new test ***/ isRunning = 1; forceStop = 0; /*** Copy info from arguments into global variables ***/ numCables = num_cables; /* Number of cable connections */ for (i=0; iFinder capture test engaged.\n"); errout(tstr,ERR_INFO2); /*** Begin allocating boards to slots ***/ for (sl=0; sl 0) && (slotUsage[clockSlot] == EMPTY)) slotUsage[clockSlot] = TESTCLOCK; if (slotUsage[tracerSlot] == EMPTY) slotUsage[tracerSlot] = TRACER; /*** Loop over cable list: unpack slots and connectors ***/ for (nc=0; nc> 5) & 0x01; /* stored in 0 0000 0000 00x0 0000 */ tdcDebug[nc] = (packed_word >> 6) & 0x03; /* stored in 0 0000 0000 xx00 0000 */ finderSlots[nc] = (packed_word >> 8) & 0x1F; /* stored in 0 000x xxxx 0000 0000 */ finderConns[nc] = (packed_word >> 13) & 0x07; /* stored in 0 xxx0 0000 0000 0000 */ finderType[nc] = (packed_word >> 16) & 0x01; /* stored in x 0000 0000 0000 0000 */ if (tdcSlots[nc] < 1 || tdcSlots[nc] > 21) slotOutOfRangeError(tdcSlots[nc],TDC); if (finderSlots[nc] < 1 || finderSlots[nc] > 21) slotOutOfRangeError(finderSlots[nc],FINDER); if (slotUsage[tdcSlots[nc]] == EMPTY) slotUsage[tdcSlots[nc]] = TDC; ftype = finderType[nc] ? FINDER24 : FINDER13; if (slotUsage[finderSlots[nc]] == EMPTY) slotUsage[finderSlots[nc]] = ftype; } /*** Now make sure there are no board conflicts ***/ if (clockSlot > 0 && slotUsage[clockSlot] != TESTCLOCK) { slotConflictError(clockSlot,TESTCLOCK,slotUsage[clockSlot]); } if (slotUsage[tracerSlot] != TRACER) { slotConflictError(tracerSlot,TRACER,slotUsage[tracerSlot]); } for (i=0; i 0) { sprintf(access,"geo32:slot=%d",clockSlot); error = VISIONopen(&boardHandle[clockSlot], access, ""); dataw = 0; dataw |= 0x80000000; /* fifo_a_reset */ dataw |= 0x20000000; /* tsie_reset */ dataw |= 0x04000000; /* front_clk_en */ error = VISIONwrite(boardHandle[clockSlot], 0x4, sizeof(dataw), &bytes, &dataw); dataw = 0x000 << 16; error = VISIONwrite(boardHandle[clockSlot], 0x600000, sizeof(dataw), &bytes, &dataw); dataw = 0x200 << 16; error = VISIONwrite(boardHandle[clockSlot], 0x600000, sizeof(dataw), &bytes, &dataw); dataw = 0x000 << 16; error = VISIONwrite(boardHandle[clockSlot], 0x600000, sizeof(dataw), &bytes, &dataw); dataw = 0x001 << 16; error = VISIONwrite(boardHandle[clockSlot], 0x600000, sizeof(dataw), &bytes, &dataw); dataw = 0x000 << 16; error = VISIONwrite(boardHandle[clockSlot], 0x600000, sizeof(dataw), &bytes, &dataw); dataw = 0; dataw |= 0x00060000; /* set bunch0_wait, loop_enable */ error = VISIONwrite(boardHandle[clockSlot], 0x10, sizeof(dataw), &bytes, &dataw); dataw = 0; dataw |= 0x10000000; /* tsie_enable */ dataw |= 0x04000000; /* front_clk_en */ error = VISIONwrite(boardHandle[clockSlot], 0x4, sizeof(dataw), &bytes, &dataw); } /*********************/ /* Initialize TRACER */ /*********************/ sprintf(access,"geo32:slot=%d",tracerSlot); error = VISIONopen(&boardHandle[tracerSlot], access, ""); error = VISIONread(boardHandle[tracerSlot], 0x04, sizeof(dataw), &bytes, &dataw); dataw |= 0x02000000; /* set TRACER_BACK_EN */ dataw &= ~0x04000000; /* clr TRACER_TSI_EN */ error = VISIONwrite(boardHandle[tracerSlot], 0x04, sizeof(dataw), &bytes, &dataw); dataw = 0x7 << 29; /* set bits in TRACER_TDC_CAL_P_EN */ error = VISIONwrite(boardHandle[tracerSlot], 0x28, sizeof(dataw), &bytes, &dataw); dataw = 0x000000FF; /* set bits in TRACER_TDC_CAL_COR */ error = VISIONwrite(boardHandle[tracerSlot], 0x2C, sizeof(dataw), &bytes, &dataw); dataw = 0x00000000; /* set bits in TRACER_TDC_CAL_FINE */ error = VISIONwrite(boardHandle[tracerSlot], 0x30, sizeof(dataw), &bytes, &dataw); dataw = 0x0000FFFF; /* set bits in TRACER_TDC_CAL_WID */ error = VISIONwrite(boardHandle[tracerSlot], 0x34, sizeof(dataw), &bytes, &dataw); /**************************/ /* Open the Finder boards */ /**************************/ for (i=0; i> 24; printf("Kitchen Sink FPGA Firmware Version: %d\n", ks_version); /***********************/ /*** Start Main Loop ***/ /***********************/ w0_errors = 0; b0_errors = 0; readback_errors = 0; for (test_num = 0; test_num < 4; test_num++) { printf("\n\n***********************************************************\n"); printf("Test #%d\n", test_num); /***********************/ /* Set Register Values */ /***********************/ slot = tdcSlots[0]; /* Register 0x00: 0x00 = short B0, 0xFF = long B0 */ switch (test_num) { case 0: case 1: dataw = 0x00 << 24; printf(" Short B0\n"); break; default : dataw = 0xFF << 24; printf(" Long B0\n"); break; } error = VISIONwrite(boardHandle[slot], 0x02041C00, sizeof(dataw), &bytes, &dataw); /* Register 0x04: 0x00 = WRD0 every 6 clks, 0xFF = WRD0 every 18 clks */ switch (test_num) { case 0: case 2: dataw = 0x00 << 24; printf(" WRD0 every 6 clks\n"); break; default : dataw = 0xFF << 24; printf(" WRD0 every 18 clks\n"); break; } error = VISIONwrite(boardHandle[slot], 0x02041C04, sizeof(dataw), &bytes, &dataw); printf("***********************************************************\n"); /************************/ /* Generate RAM pattern */ /************************/ for (wc = 0; wc < 54; wc++) { data_in[wc] = (((4*wc)+3) << 24) | (((4*wc)+2) << 16) | (((4*wc)+1) << 8) | (4*wc); } /****************************/ /* Write pattern to buffers */ /****************************/ slot = tdcSlots[0]; for (i = 0; i < 54; i++) { for (j = 0; j < 4; j++) { xtc_addr = (i * 4) + j; /* Write the high 4 address bits to register 0x18 */ dataw = (xtc_addr & 0x00000F00) << 16; error = VISIONwrite(boardHandle[slot], 0x02041C18, sizeof(dataw), &bytes, &dataw); /* Write the low 8 address bits to register 0x14 */ dataw = (xtc_addr & 0x000000FF) << 24; error = VISIONwrite(boardHandle[slot], 0x02041C14, sizeof(dataw), &bytes, &dataw); /* Write the data byte to register 0x20 */ switch (j) { case 0: dataw = (data_in[i] & 0x000000FF) << 24; break; case 1: dataw = (data_in[i] & 0x0000FF00) << 16; break; case 2: dataw = (data_in[i] & 0x00FF0000) << 8; break; default: dataw = (data_in[i] & 0xFF000000); break; } written_data = dataw; error = VISIONwrite(boardHandle[slot], 0x02041C20, sizeof(dataw), &bytes, &dataw); /* Verify that the data was written correctly */ error = VISIONread(boardHandle[slot], 0x2041C1C, sizeof(dataw), &bytes, &dataw); dataw = dataw >> 24; written_data = written_data >> 24; if (dataw != written_data) { printf("READBACK ERROR: Addr=0x%03X Written Data=0x%08X Read Data=0x%08X\n", xtc_addr, written_data, dataw); } } } /* Wait a moment */ taskDelay(10); /*******************************/ /* Begin loops of this pattern */ /*******************************/ /* Check for force stop */ if (forceStop) { sprintf(tstr,"Capture test terminated by user.\n"); errout(tstr,ERR_WARN1); sprintf(tstr,"Test results:\n"); errout(tstr,ERR_INFO1); for (nc=0; nc> 16; } switch (test_num) { case 0: if ((i+1)<6) tdc_out |= 0x20000; /* Set Beam0 */ if ((i+1)%6 == 0) tdc_out |= 0x10000; /* Set Word0 */ break; case 1: if ((i+1)<6) tdc_out |= 0x20000; /* Set Beam0 */ if ((i+1)%18 == 0) tdc_out |= 0x10000; /* Set Word0 */ break; case 2: if ((i+1)<18) tdc_out |= 0x20000; /* Set Beam0 */ if ((i+1)%6 == 0) tdc_out |= 0x10000; /* Set Word0 */ break; default: if ((i+1)<18) tdc_out |= 0x20000; /* Set Beam0 */ if ((i+1)%18 == 0) tdc_out |= 0x10000; /* Set Word0 */ break; } switch (test_num) { case 0: if ((i+1)<6) { if ((finderRam[i] & 0x00020000) == 0) { b0_errors++; } } else { if ((finderRam[i] & 0x00020000) != 0) { b0_errors++; } } if (((i+1)%6) == 0) { if ((finderRam[i] & 0x00010000) == 0) { w0_errors++; } } else { if ((finderRam[i] & 0x00010000) != 0) { w0_errors++; } } break; case 1: if ((i+1)<6) { if ((finderRam[i] & 0x00020000) == 0) { b0_errors++; } } else { if ((finderRam[i] & 0x00020000) != 0) { b0_errors++; } } if (((i+1)%18) == 0) { if ((finderRam[i] & 0x00010000) == 0) { w0_errors++; } } else { if ((finderRam[i] & 0x00010000) != 0) { w0_errors++; } } break; case 2: if ((i+1)<18) { if ((finderRam[i] & 0x00020000) == 0) { b0_errors++; } } else { if ((finderRam[i] & 0x00020000) != 0) { b0_errors++; } } if (((i+1)%6) == 0) { if ((finderRam[i] & 0x00010000) == 0) { w0_errors++; } } else { if ((finderRam[i] & 0x00010000) != 0) { w0_errors++; } } break; default: if ((i+1)<18) { if ((finderRam[i] & 0x00020000) == 0) { b0_errors++; } } else { if ((finderRam[i] & 0x00020000) != 0) { b0_errors++; } } if (((i+1)%18) == 0) { if ((finderRam[i] & 0x00010000) == 0) { w0_errors++; } } else { if ((finderRam[i] & 0x00010000) != 0) { w0_errors++; } } break; } sprintf(tstr,"[M] Test Number=%3d T:%02d/%d F:%02d/%d Word=%2d:%02d w=%5X r=%5X x=%5X\n", test_num,tdcSlots[nc],tdcConns[nc],slot,conn,i,((i+1)%18),tdc_out,find_in,tdc_out^find_in); errout(tstr,ERR_ERROR2); if ((tdc_out & 0x0000FFFF) != (find_in & 0x0000FFFF)) { readback_errors++; } } } } printf("Test results:\n"); printf("\nB0 Errors: %d\n", b0_errors); printf("W0 Errors: %d\n", w0_errors); printf("Readback Byte Errors: %d\n\n", readback_errors); sprintf(tstr,"TDC->Finder capture test completed.\n"); errout(tstr,ERR_INFO2); closeAndExit(); } void errout(char *str, int level) { if (level <= debugLevel) printf("%s",str); } void slotConflictError(unsigned int slot, unsigned int board1, unsigned int board2) { char tstr[MAXSTRLEN]; sprintf(tstr,"Error: In slot %d, a %s and %s cannot coexist.\n",slot,boardType[board1],boardType[board2]); errout(tstr,ERR_FATAL); isRunning = 0; exit(0); } void slotOutOfRangeError(unsigned int slot, unsigned int board) { char tstr[MAXSTRLEN]; sprintf(tstr,"Error: Slot %d is out of range for a %s board.\n",slot,boardType[board]); errout(tstr,ERR_FATAL); isRunning = 0; exit(0); } void closeAndExit() { unsigned int sl; for (sl=0; sl