/*----------------------------------------------------------------------------*/ /** * @mainpage *
 *
 *  f1tdcLib.c  -  Driver library for JLAB config and readout of JLAB F1
 *                 TDC v2/v3 using a VxWorks 5.4 or later, or Linux
 *                 based Single Board computer.
 *
 *  Authors: David Abbott 
 *           Jefferson Lab Data Acquisition Group
 *           August 2003
 *
 *           Bryan Moffit
 *           Jefferson Lab Data Acquisition Group
 *           July 2013
 *
 *  Revision  2.0 - Initial Revision for v2/v3
 *                    - Supports up to 20 F1 boards in a Crate
 *                    - Programmed I/O and Block reads
 *
 * 
*----------------------------------------------------------------------------*/ #include #include #include #ifdef VXWORKS #include #include #include #include #include #include #include #else #include "jvme.h" #include #endif /* Include TDC definitions */ #include "f1tdcLib.h" /* Mutex to guard flexio read/writes */ pthread_mutex_t f1Mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t f1sdcMutex = PTHREAD_MUTEX_INITIALIZER; #define F1LOCK if(pthread_mutex_lock(&f1Mutex)<0) perror("pthread_mutex_lock"); #define F1UNLOCK if(pthread_mutex_unlock(&f1Mutex)<0) perror("pthread_mutex_unlock"); /* Define external Functions */ #ifdef VXWORKS IMPORT STATUS sysBusToLocalAdrs(int, char *, char **); IMPORT STATUS intDisconnect(int); IMPORT STATUS sysIntEnable(int); IMPORT STATUS sysIntDisable(int); IMPORT STATUS sysVmeDmaDone(int, int); IMPORT STATUS sysVmeDmaSend(UINT32, UINT32, int, BOOL); #define EIEIO __asm__ volatile ("eieio") #define SYNC __asm__ volatile ("sync") #endif /* Define Interrupts variables */ BOOL f1tdcIntRunning = FALSE; /* running flag */ int f1tdcIntID = -1; /* id number of ADC generating interrupts */ LOCAL VOIDFUNCPTR f1tdcIntRoutine = NULL; /* user interrupt service routine */ LOCAL int f1tdcIntArg = 0; /* arg to user routine */ LOCAL UINT32 f1tdcIntLevel = F1_VME_INT_LEVEL; /* default VME interrupt level */ LOCAL UINT32 f1tdcIntVec = F1_VME_INT_VEC; /* default interrupt Vector */ /* Define static default config data 0: V2 Hi Rez - 32 MHz Clock (Internal Clock) 1: V2 Hi Rez - 31.25 MHz Clock (SD Clock) 2: V3 Normal Rez - 32 MHz Clock (Internal Clock) 3: V3 Normal Rez - 31.25 MHz Clock (SD Clock) 4: Not Initialized - Read data from a file */ LOCAL int f1ConfigData[5][16] = { { 0x0180, 0x8000, 0x407F, 0x407F, 0x407F, 0x407F, 0x003F, 0x9CC0, 0x22E2, 0x68A6, 0x1FEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C}, { 0x0180, 0x8000, 0x407F, 0x407F, 0x407F, 0x407F, 0x003F, 0x9C00, 0x22EF, 0x68CE, 0x1FF1, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C}, { 0x0180, 0x0000, 0x4040, 0x4040, 0x4040, 0x4040, 0x003F, 0xBA00, 0x63A4, 0xCDEC, 0x1FEB, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C}, { 0x0180, 0x0000, 0x4040, 0x4040, 0x4040, 0x4040, 0x003F, 0xB880, 0x61D1, 0xCE1E, 0x1FF1, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C}, { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000} }; /* Define global variables */ int nf1tdc = 0; /* Number of TDCs in Crate */ int f1tdcA32Base = 0x08000000; /* Minimum VME A32 Address for use by TDCs */ int f1tdcA32Offset = 0x08000000; /* Difference in CPU A32 Base - VME A32 Base */ int f1tdcA24Offset = 0x0; /* Difference in CPU A24 Base - VME A24 Base */ int f1tdcA16Offset = 0x0; /* Difference in CPU A16 Base - VME A16 Base */ volatile struct f1tdc_struct *f1p[(F1_MAX_BOARDS+1)]; /* pointers to TDC memory map */ volatile unsigned int *f1pd[(F1_MAX_BOARDS+1)]; /* pointers to TDC FIFO memory */ volatile unsigned int *f1pmb; /* pointer to Multblock window */ int f1ID[F1_MAX_BOARDS]; /* array of slot numbers for TDCs */ unsigned int f1AddrList[F1_MAX_BOARDS]; /* array of a24 addresses for TDCs */ int f1Rev[(F1_MAX_BOARDS+1)]; /* Board Revision Info for each module */ int f1Nchips[(F1_MAX_BOARDS+1)]; /* Number of f1 chips on each module */ int f1MaxSlot=0; /* Highest Slot hold an F1 */ int f1MinSlot=0; /* Lowest Slot holding an F1 */ int f1tdcIntCount = 0; /* Count of interrupts from TDC */ unsigned int f1LetraMode = 0; /* Mask of Letra Enabled TDCs. Rising edge only default */ unsigned long long int f1ChannelDisable[(F1_MAX_BOARDS+1)]; /* Mask of channels to disable for each module */ int f1ClockSource=0; /* Common clock source: 0=Internal, 1=External */ int f1BlockError=F1_BLOCKERROR_NO_ERROR; /* Whether (>0) or not (0) Block Transfer had an error */ /* Include Firmware Tools */ #include "f1FirmwareTools.c" /* Some static function prototypes */ static int f1WriteChip(int id, int chip, int reg, unsigned short data); static int f1WriteAllChips(int id, int reg, unsigned short data); static unsigned short f1ReadChip(int id, int chip, int reg); /** * @defgroup Config Initialization/Configuration * @defgroup PulserConfig Pulser Configuration (V3 only) * @ingroup Config * @defgroup Status Status * @defgroup Readout Data Readout * @defgroup IntPoll Interrupt/Polling * @defgroup DebugSW Routines to test lines to Switch Slot Modules * @defgroup Deprec Deprecated - To be removed */ /** * @ingroup Config * @brief Initialize JLAB F1 TDC Library. * * @param addr * - A24 VME Address of the f1TDC * @param addr_inc * - Amount to increment addr to find the next f1TDC * @param ntdc * - Number of times to increment * * @param iFlag * - 18 bit integer for initialization flags * *
 *       Low 6 bits - Specifies the default Signal distribution (clock,trigger) 
 *                    sources for the board (Internal, FrontPanel, VXS, VME(Soft))
 *
 *       bit    0:  defines Sync Reset source
 *                     0  VME (Software Sync-Reset)
 *                     1  Front Panel/VXS/P2 (Depends on Clk/Trig source selection)
 *       bits 2-1:  defines Trigger source
 *                   0 0  VME (Software Triggers)
 *                   0 1  Front Panel Input
 *                   1 0  VXS (P0) 
 *                        (all others Undefined - default to Internal)
 *       bits 5-4:  defines Clock Source
 *                   0 0  32 MHz Clock
 *                   0 1  Front Panel 
 *                   1 0  VXS (P0)
 *
 *       bit 16:  Exit before board initialization
 *                     0  Initialize FADC (default behavior)
 *                     1  Skip initialization (just setup register map pointers)
 *
 *       bit 17:  Use f1AddrList instead of addr and addr_inc
 *                for VME addresses.
 *                     0  Initialize with addr and addr_inc
 *                     1  Use f1AddrList 
 *
 *       bit 18:  Skip firmware check.  Useful for firmware updating.
 *                     0  Perform firmware check
 *                     1  Skip firmware check
 * 
* * @return OK, or ERROR if the address is invalid or a board is not present. */ STATUS f1Init (UINT32 addr, UINT32 addr_inc, int ntdc, int iFlag) { int ii, res, rdata, errFlag = 0; int boardID = 0; int maxSlot = 1; int minSlot = 21; unsigned int laddr, laddr_inc, a32addr; int rev=0, config=0; volatile struct f1tdc_struct *f1; int trigSrc=0, clkSrc=0, srSrc=0; int noBoardInit=0, useList=0, noFirmwareCheck=0; /* Parse some iFlag arguments, rest done later */ /* Check if we are to exit when pointers are setup */ noBoardInit=(iFlag&F1_IFLAG_NOINIT)? 1:0; /* Check if we're initializing using a list */ useList=(iFlag&F1_IFLAG_USELIST)? 1:0; /* Skip the firmware check? */ noFirmwareCheck=(iFlag&F1_IFLAG_NOFWCHECK)? 1:0; /* Check for valid address */ if(addr==0) { printf("f1Init: ERROR: Must specify a Bus (VME-based A24) address for TDC 0\n"); return(ERROR); } else if(addr > 0x00ffffff) { /* A24 Addressing */ printf("f1Init: ERROR: A32 Addressing not allowed for the F1 TDC\n"); return(ERROR); } else { /* A24 Addressing */ if( ((addr_inc==0)||(ntdc==0)) && (useList==0) ) ntdc = 1; /* assume only one TDC to initialize */ /* get the TDC address */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("f1Init: ERROR in sysBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } #else res = vmeBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("f1Init: ERROR in vmeBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } #endif f1tdcA24Offset = laddr - addr; } /* Init Some Global variables */ nf1tdc = 0; memset((char *)f1ID, 0, sizeof(f1ID)); memset((char *)f1ChannelDisable, 0 , sizeof(f1ChannelDisable)); for (ii=0;iiversion),VX_READ,4,(char *)&rdata); #else res = vmeMemProbe((char *) &(f1->version),4,(char *)&rdata); #endif if(res < 0) { #ifdef VXWORKS printf("f1Init: ERROR: No addressable board at addr=0x%x\n",(UINT32) f1); #else printf("f1Init: ERROR: No addressable board at VME (Local) addr=0x%x (0x%x)\n", (UINT32) laddr_inc, (UINT32) f1); #endif errFlag = 1; continue; } else { /* Check that it is an F1 board */ if((rdata&F1_VERSION_BOARDTYPE_MASK) != F1_BOARD_ID) { printf(" ERROR: For board at 0x%x, Invalid Board ID: 0x%x\n", (UINT32) f1-f1tdcA24Offset,rdata); errFlag = 1; continue; } /* Check if this is board has a valid slot number */ boardID = ((vmeRead32(&(f1->intr)))&F1_SLOT_ID_MASK)>>16; if((boardID <= 0)||(boardID >21)) { printf(" ERROR: Board Slot ID is not in range: %d\n",boardID); errFlag = 1; continue; } rev = (rdata&F1_VERSION_BOARDREV_MASK)>>8; if((rev != 2) && (rev != 3)) { printf("%s: ERROR: Module revision (%d) not compatible with this driver\n", __FUNCTION__,rev); errFlag = 1; continue; } f1Rev[boardID] = rdata&(F1_VERSION_BOARDREV_MASK | F1_VERSION_FIRMWARE_MASK); if(!noFirmwareCheck) { if( (f1Rev[boardID] & F1_VERSION_FIRMWARE_MASK) < F1_SUPPORTED_FIRMWARE(rev)) { printf("%s: ERROR: FPGA Firmware (0x%02x) not supported by this driver.\n", __FUNCTION__,rdata & F1_VERSION_FIRMWARE_MASK); printf("\tUpdate to 0x%02x to use this driver.\n",F1_SUPPORTED_FIRMWARE(rev)); errFlag = 1; continue; } } if(rev == 2) f1Nchips[boardID] = 8; else f1Nchips[boardID] = 6; } f1ID[nf1tdc] = boardID; if(boardID >= maxSlot) maxSlot = boardID; if(boardID <= minSlot) minSlot = boardID; f1p[boardID] = (struct f1tdc_struct *)(laddr_inc); #ifdef VXWORKS printf("Initialized TDC %2d Slot #%2d at address 0x%08x \n", ii,f1ID[nf1tdc],(UINT32) f1p[(f1ID[nf1tdc])]); #else printf("Initialized TDC %2d Slot #%2d at VME (Local) address 0x%x (0x%x) \n", ii,f1ID[nf1tdc],(UINT32) f1p[(f1ID[nf1tdc])] - f1tdcA24Offset, (UINT32) f1p[(f1ID[nf1tdc])]); #endif nf1tdc++; } if(!noBoardInit) { /* Parse the rest of the iFlag arguments for Trigger, SyncReset, and Clock Sources */ if((iFlag & F1_CLKSRC_MASK) == F1_CLKSRC_VXS) { printf("%s: Enabling f1TDC for VXS Clock",__FUNCTION__); clkSrc = 0; f1ClockSource=1; if(rev==2) config=1; else config=3; switch (iFlag&(F1_TRIGSRC_MASK|F1_SRSRC_MASK)) { /* P0/VXS Clock Source */ case 0: case 1: printf(" and Software Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 2: printf(" and Front Panel Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 3: printf(" and Front Panel Triggers (FP Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_FP; break; case 4: case 6: printf(" and VXS Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_P0; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 5: case 7: printf(" and VXS Triggers (VXS Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_P0; srSrc = F1_SYNC_RESET_SRC_P0; break; } } else if ((iFlag & F1_CLKSRC_MASK) == F1_CLKSRC_FP) { /* Front Panel Clock Source */ printf("%s: Enabling f1TDC for Front Panel Clock",__FUNCTION__); clkSrc = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_SRC_FP; f1ClockSource=1; if(rev==2) config=1; else config=3; switch (iFlag&(F1_TRIGSRC_MASK|F1_SRSRC_MASK)) { case 0: case 1: printf(" and Software Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 2: case 4: case 6: printf(" and Front Panel Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 3: case 5: case 7: printf(" and Front Panel Triggers (FP Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_FP; break; } } else { /* Use internal clock */ printf("%s: Enabling f1TDC for Internal Clock",__FUNCTION__); clkSrc = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_INTERNAL_ENABLE; f1ClockSource=0; if(rev==2) config=0; else config=2; switch (iFlag&(F1_TRIGSRC_MASK|F1_SRSRC_MASK)) { case 0: case 1: printf(" and Software Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 2: printf(" and Front Panel Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 3: printf(" and Front Panel Triggers (FP Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_FP; srSrc = F1_SYNC_RESET_SRC_FP; break; case 4: case 6: printf(" and VXS Triggers (Software Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_P0; srSrc = F1_SYNC_RESET_SRC_SOFT | F1_ENABLE_SOFT_CONTROL; break; case 5: case 7: printf(" and VXS Triggers (VXS Sync Reset)\n"); trigSrc = F1_TRIGGER_SRC_P0; srSrc = F1_SYNC_RESET_SRC_P0; break; } } /* Reset all TDCs */ for(ii=0;iicsr),F1_CSR_HARD_RESET); } taskDelay(60); /* Initialize Interrupt variables */ f1tdcIntID = -1; f1tdcIntRunning = FALSE; f1tdcIntLevel = F1_VME_INT_LEVEL; f1tdcIntVec = F1_VME_INT_VEC; f1tdcIntRoutine = NULL; f1tdcIntArg = 0; /* Calculate the A32 Offset for use in Block Transfers */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x09,(char *)f1tdcA32Base,(char **)&laddr); #else res = vmeBusToLocalAdrs(0x09,(char *)f1tdcA32Base,(char **)&laddr); #endif if (res != 0) { #ifdef VXWORKS printf("f1Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",f1tdcA32Base); #else printf("f1Init: ERROR in vmeBusToLocalAdrs(0x09,0x%x,&laddr) \n",f1tdcA32Base); #endif return(ERROR); } else { f1tdcA32Offset = laddr - f1tdcA32Base; } for(ii=0;iiadr32),(a32addr>>16) + 1); /* Write the register and enable */ } /* default Block Level to 1 */ f1GSetBlockLevel(1); /* Use the user configuration, if it has been loaded. */ if(f1ConfigData[4][0] != 0) config=4; /* Write the configuration to the f1tdc chips */ printf("%s: Using configuration %d.\n", __FUNCTION__,config); f1GConfigWrite((int *) &f1ConfigData[config], F1_ALL_CHIPS); for(ii=0; iictrl, (vmeRead32(&f1p[f1ID[ii]]->ctrl) & ~F1_CTRL_SIGNALS_MASK) | clkSrc | srSrc | trigSrc); } // FIXME: Carry over code from v1... Wait for the Chips on each module to lock to SD Clock. for(ii=0;ii 1) { a32addr = f1tdcA32Base + (nf1tdc+1)*F1_MAX_A32_MEM; /* set MB base above individual board base */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x09,(char *)a32addr,(char **)&laddr); #else res = vmeBusToLocalAdrs(0x09,(char *)a32addr,(char **)&laddr); #endif if (res != 0) { #ifdef VXWORKS printf("f1Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",a32addr); #else printf("f1Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",a32addr); #endif return(ERROR); } f1pmb = (unsigned int *)(laddr); /* Set a pointer to the FIFO */ for (ii=0;iiadr_mb), (a32addr+F1_MAX_A32MB_SIZE) + (a32addr>>16) + 1); } /* Set First Board and Last Board */ f1MaxSlot = maxSlot; f1MinSlot = minSlot; vmeWrite32(&(f1p[minSlot]->ctrl), vmeRead32(&(f1p[minSlot]->ctrl)) | F1_FIRST_BOARD); vmeWrite32(&(f1p[maxSlot]->ctrl), vmeRead32(&(f1p[maxSlot]->ctrl)) | F1_LAST_BOARD); } } /* !noBoardInit */ if(errFlag > 0) { printf("f1Init: Unable to initialize all (%d) TDC Modules\n",ntdc); if(nf1tdc > 0) printf("f1Init: %d TDC(s) successfully initialized\n",nf1tdc ); return(ERROR); } else { if(nf1tdc > 0) printf("f1Init: %d TDC(s) successfully initialized\n",nf1tdc ); return(OK); } } /** * @ingroup Config * @brief Convert an index into a slot number, where the index is * the element of an array of F1TDCs in the order in which they were * initialized. * * @param i * - Initialization number * @return Slot number if Successfull, otherwise ERROR. * */ int f1Slot(unsigned int i) { if(i>=nf1tdc) { printf("%s: ERROR: Index (%d) >= f1TDCs initialized (%d).\n", __FUNCTION__,i,nf1tdc); return ERROR; } return f1ID[i]; } /** * @ingroup Config * @brief Write the specified configuration to provided chips of the module in slot id * indicated by the chipmask * * @param id * - Slot Number * @param config_data * - Array of configuration data to write to f1TDC chips. Each element * refers to a specific f1TDC chip register. * @param chipmask * - Mask of which chips to write to. * * @return OK if Successfull, otherwise ERROR. */ int f1ConfigWrite(int id, int *config_data, int chipMask) { int ichip,jj, reg, ctrl=0; int order[16] = { 15,10, 0,1,6, 8,9, 11,12,13,14, 7, 2,3,4,5 }; unsigned int data, rval; unsigned int allchips_mask=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return(ERROR); } if(chipMask == 0) { /* Assume all chips programmed the same */ chipMask = F1_ALL_CHIPS; } /* Disable FIFOs and Edges */ f1DisableData(id); F1LOCK; /* Save the current clock state */ ctrl = vmeRead32(&f1p[id]->ctrl); /* Disable the clock if it is enabled */ vmeWrite32(&f1p[id]->ctrl, (ctrl & ~F1_REFCLK_SRC_MASK) | F1_REFCLK_SRC_INTERNALFP); taskDelay(20); allchips_mask = ((1<<(f1Nchips[id]))-1); if((allchips_mask & chipMask) == allchips_mask) { /* Write the same configuration to all chips */ /* printf("%s: Write same to all chips\n",__FUNCTION__); */ for(jj=0; jj<16; jj++) /* write cfg data */ { reg = order[jj]; /* program registers in the correct order */ if((reg>=2) && (reg<=5)) /* Disable edges until "enable" */ data = config_data[reg] & F1_OFFSET_MASK; else data = config_data[reg] & 0xFFFF; f1WriteAllChips(id, reg, data); taskDelay(1); // FIXME: Put this back in, when f1 stores the config in memory /* rval = f1ReadChip(id, ichip, reg); */ /* if((rval & 0xFFFF) != data) */ /* { */ /* printf("%s(%d): ERROR writing to chip %d reg %2d..\n", */ /* __FUNCTION__,id, ichip, reg); */ /* printf("\t Write (0x%04x) != Readback (0x%04x)\n", */ /* data, rval%0xFFFF); */ /* } */ } } else { /* printf("%s: Just write to SOME chips\n",__FUNCTION__); */ /* Loop over each chip, neglect the ones that are not turned on in chipMask */ for(ichip=0; ichip=2) && (reg<=5)) /* Disable edges until "enable" */ data = config_data[reg] & F1_OFFSET_MASK; else data = config_data[reg] & 0xFFFF; f1WriteChip(id, ichip, reg, data); taskDelay(1); rval = f1ReadChip(id, ichip, reg); if((rval & 0xFFFF) != data) { printf("%s(%d): ERROR writing to chip %d reg %2d..\n", __FUNCTION__,id, ichip, reg); printf("\t Write (0x%04x) != Readback (0x%04x)\n", data, rval%0xFFFF); } } } } } /* Return the original clock setting */ vmeWrite32(&f1p[id]->ctrl, ctrl); taskDelay(20); for(ichip=0;ichipstat[ichip], F1_CHIP_CLEAR_STATUS); } } F1UNLOCK; return(OK); } /** * @ingroup Config * @brief Write the specified configuration to provided chips of all initialized f1TDCs * indicated by the chipmask * * @param config_data * - Array of configuration data to write to f1TDC chips. Each element * refers to a specific f1TDC chip register. * @param chipmask * - Mask of which chips to write to. * * @return OK if Successfull, otherwise ERROR. */ int f1GConfigWrite(int *config_data, int chipMask) { int if1=0, id=0; int ichip,jj, reg, ctrl=0; int order[16] = { 15,10, 0,1,6, 8,9, 11,12,13,14, 7, 2,3,4,5 }; unsigned int data, rval; unsigned int allchips_mask=0; if(chipMask == 0) { /* Assume all chips programmed the same */ chipMask = F1_ALL_CHIPS; } /* Disable FIFOs and Edges */ for(if1=0; if1ctrl); /* Disable the clock if it is enabled */ for(if1=0; if1ctrl, (ctrl & ~F1_REFCLK_SRC_MASK) | F1_REFCLK_SRC_INTERNALFP); taskDelay(30); for(if1=0; if1=2) && (reg<=5)) /* Disable edges until "enable" */ data = config_data[reg] & F1_OFFSET_MASK; else data = config_data[reg] & 0xFFFF; f1WriteAllChips(id, reg, data); taskDelay(1); // FIXME: Put this back in, when f1 stores the config in memory /* rval = f1ReadChip(id, ichip, reg); */ /* if((rval & 0xFFFF) != data) */ /* { */ /* printf("%s(%d): ERROR writing to chip %d reg %2d..\n", */ /* __FUNCTION__,id, ichip, reg); */ /* printf("\t Write (0x%04x) != Readback (0x%04x)\n", */ /* data, rval%0xFFFF); */ /* } */ } } else { /* printf("%s: Just write to SOME chips\n",__FUNCTION__); */ /* Loop over each chip, neglect the ones that are not turned on in chipMask */ for(ichip=0; ichip=2) && (reg<=5)) /* Disable edges until "enable" */ data = config_data[reg] & F1_OFFSET_MASK; else data = config_data[reg] & 0xFFFF; f1WriteChip(id, ichip, reg, data); taskDelay(2); rval = f1ReadChip(id, ichip, reg); if((rval & 0xFFFF) != data) { printf("%s(%d): ERROR writing to chip %d reg %2d..\n", __FUNCTION__,id, ichip, reg); printf("\t Write (0x%04x) != Readback (0x%04x)\n", data, rval%0xFFFF); } } } } } /* Return the original clock setting */ vmeWrite32(&f1p[id]->ctrl, ctrl); } taskDelay(40); for(if1=0; if1stat[ichip], F1_CHIP_CLEAR_STATUS); } } } F1UNLOCK; return(OK); } /** * @ingroup Config * @brief Set which preset/user configuration to use for specified slot id * for indicated chips in chipmask * * @param id * - Slot Number * @param iflag * - Set from four default configuations *
 *    0 V2: Hi Rez      - Internal Clock (32 MHz)
 *    1 V2: Hi Rez      - External Clock (31.25 MHz)
 *    2 V3: Normal Rez  - Internal Clock (32 MHz)
 *    3 V3: Normal Rez  - External Clock (31.25 MHz)
 *    4 User specified (from file)
 * 
* @param chipmask * - Mask of which chips to write to. * * @return OK if Successfull, otherwise ERROR. */ int f1SetConfig(int id, int iflag, int chipMask) { int rev; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return(ERROR); } if((iflag<0)||(iflag>4)) { printf("f1SetConfig: ERROR: Invalid config number. Choose from 0-4 where\n"); printf(" 0 -> V2: Hi Resolution (32 chan) - Internal Clock (32 MHz) \n"); printf(" 1 -> V2: Hi Resolution (32 chan) - External Clock (31.25 MHz) \n"); printf(" 2 -> V3: Normal Resolution (48 chan) - Internal Clock (32 MHz)\n"); printf(" 3 -> V3: Normal Resolution (48 chan) - External Clock (31.25 MHz)\n"); printf(" 4 -> User specified from a file (call f1ConfigReadFile() first)\n"); return (ERROR); } rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>16; if(rev==2) { if((iflag == 2) || (iflag == 3)) { printf("%s: ERROR: Invalid config number (%d) for this module revision (%d).\n", __FUNCTION__,iflag,rev); return ERROR; } } if(rev==3) { if((iflag == 0) || (iflag == 1)) { printf("%s: ERROR: Invalid config number (%d) for this module revision (%d).\n", __FUNCTION__,iflag,rev); return ERROR; } } if(iflag==4) { /* check if there is valid config data there */ if (f1ConfigData[4][0] == 0) { printf("%s: ERROR: Configuration not loaded from file.\n", __FUNCTION__); return(ERROR); } } f1ConfigWrite(id,(int *)&f1ConfigData[iflag], chipMask); return(OK); } /** * @ingroup Status * @brief Read the f1TDC Chip Registers into user specified config_data array * * @param id * - Slot Number * @param config_data * - local memory address to place register values * @param chipID * - Which f1TDC Chip to read from * * @return OK if successful, otherwise ERROR. */ int f1ConfigRead(int id, unsigned int *config_data, int chipID) { int jj;//, reg; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return(ERROR); } if((chipID<0)||(chipID>=f1Nchips[id])) { printf("f1ConfigRead: ERROR : Invalid Chip ID %d (range 0-%d)\n",chipID, f1Nchips[id]-1); return(ERROR); } F1LOCK; for(jj=0; jj<16; jj++) { /* READ cfg data */ config_data[jj] = f1ReadChip(id, chipID, jj); } F1UNLOCK; return(OK); } /** * @ingroup Config * @brief Read in user defined (4) f1TDC chip registers from specified file * * @param filename * - Name of file that contains f1TDC chip registers * * @return OK if successful, otherwise ERROR. */ int f1ConfigReadFile(char *filename) { FILE *fd_1; unsigned int value, config[16]; int ii, jj; if(filename == NULL) { printf("f1ConfigReadFile: ERROR: No Config file specified.\n"); return(ERROR); } fd_1 = fopen(filename,"r"); if(fd_1 > 0) { printf("Reading Data from file: %s\n",filename); jj = 4; /* location for file data */ for(ii = 0; ii < 16; ii++) { fscanf(fd_1,"%x",&value); f1ConfigData[jj][ii] = 0xFFFF & value; config[ii] = f1ConfigData[jj][ii]; printf("ALL Chips: Reg %2d = %04x\n",ii,config[ii]); } fclose(fd_1); return(OK); } else { printf("f1ConfigReadFile: ERROR opening file %s\n",filename); return(ERROR); } } static int f1ChipsHaveSameConfig(int id) { int ichip, ireg; unsigned short chipReg0; F1LOCK; for(ireg = 0; ireg < 16; ireg++) { chipReg0 = f1ReadChip(id, 0, ireg); for(ichip = 1; ichip < f1Nchips[id]; ichip++) { if(chipReg0 != f1ReadChip(id, ichip, ireg)) { return 0; F1UNLOCK; } } } F1UNLOCK; return 1; } typedef struct chipinfo_struct { int chip; int clk_period; int rez; float bin_size; float full_range; float window; float latency; unsigned int rollover_count; } chipInfo; static void f1ConfigDecode(int id, chipInfo *ci, int pflag) { int ireg, ii; unsigned short chipReg[16]; float factor, tframe; int sync; unsigned int refcnt, exponent, refclkdiv, hsdiv, trigwin, triglat; F1LOCK; for(ireg = 0; ireg < 16; ireg++) { chipReg[ireg] = f1ReadChip(id, ci->chip, ireg); } F1UNLOCK; if(pflag) { printf("\n ---------------- Chip %d ----------------",ci->chip); for(ireg = 0; ireg < 16; ireg++) { if((ireg%8)==0) printf("\n"); printf("0x%04x ",chipReg[ireg]); } printf("\n"); } if( chipReg[1] & 0x8000 ) { if(pflag) printf("High Resolution mode\n"); factor = 0.5; ci->rez = 1; } else { if(pflag) printf("Normal Resolution mode\n"); factor = 1.; ci->rez = 0; } if( chipReg[15] & 0x4 ) { sync=1; if(pflag) printf("Synchronous mode\n"); } else { sync=0; if(pflag) printf("Non-synchronous mode (Start required)\n"); } refcnt = ( chipReg[7] >> 6 ) & 0x1FF; tframe = (float)(ci->clk_period * (refcnt +2 )); if(pflag) printf("refcnt = %d tframe (ns) = %.1f\n",refcnt,tframe); exponent = ( chipReg[10] >> 8 ) & 0x7; refclkdiv = 1; for(ii = 0; ii < exponent; ii++) refclkdiv = 2 * refclkdiv; hsdiv = chipReg[10] & 0xFF; ci->bin_size = factor * (ci->clk_period/152.) * ( (float)refclkdiv )/( (float)hsdiv ); ci->full_range = 65536 * ci->bin_size; if(pflag) printf("refclkdiv = %d hsdiv = %d bin_size (ns) = %.4f full_range (ns) = %.1f\n", refclkdiv,hsdiv,ci->bin_size,ci->full_range); trigwin = chipReg[8]&0xffff; triglat = chipReg[9]&0xffff; ci->window = ((float)trigwin) * ci->bin_size/factor; ci->latency = ((float)triglat) * ci->bin_size/factor; if(pflag) printf("trigwin = %d triglat = %d window (ns) = %.1f latency (ns) = %.1f\n", trigwin,triglat,ci->window,ci->latency); if(sync) { ci->rollover_count = (unsigned int) (tframe/ci->bin_size); if(pflag) printf("Rollover count = %d\n",ci->rollover_count); } else { ci->rollover_count = 65536; if(pflag) printf("Rollover count = N/A (Full Range - 65536)\n"); } } /** * @ingroup Status * @brief Print to standard out the configuration of the f1TDC chips * specified by the chipmask and module in slot id * * @param id * - Slot Number * @param chipMask * - Mask of chips in module to show * */ void f1ConfigShow(int id, int chipMask) { int ii_chip; chipInfo ci; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("f1ConfigShow: ERROR : TDC in slot %d is not initialized \n",id); return; } if(chipMask == 0) /* Print out config info for all chips */ chipMask = F1_ALL_CHIPS; if(f1ClockSource==0) /* Internal */ ci.clk_period = 31.25; else /* External */ ci.clk_period = 32.; for(ii_chip = 0; ii_chip < f1Nchips[id]; ii_chip++) { if((chipMask)&(1<21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } // read serial number back from eeprom character by character // printf("\n read serial number back from eeprom character by character\n"); for(ii=0; iiserial_eprom, 0x3000 | ii); taskDelay(1); data_word = vmeRead32(&f1p[id]->serial_eprom); // printf("data_word = %X data_byte = %X\n", data_word, (data_word >>24)); read_char = (char)(data_word >> 24); // printf("eprom character = %c\n", read_char); serial_read[ii] = read_char; // build the serial number jj = ii; } serial_read[jj+1] = '\0'; // terminate string printf("\n--- Module serial number = %s ---\n\n", serial_read); if(rval!=NULL) strcpy((char *)rval, serial_read); ret_len = (int)strlen(serial_read); return ret_len; } /** * @ingroup Status * @brief Get the firmware version of the FPGA * * @param id * - Slot number * @param pflag Print to standard out flag * - 0: Print nothing to stdout * - !0: Print firmware versions to stdout * * RETURNS: FPGA Version if successful * or -1 if error */ int f1GetFirmwareVersion(int id, int pflag) { int rval=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } F1LOCK; rval = vmeRead32(&f1p[id]->version) & F1_VERSION_FIRMWARE_MASK; F1UNLOCK; if(pflag) { printf("%s: Board Firmware Rev = 0x%04x\n", __FUNCTION__, rval); } return rval; } /** * @ingroup Status * @brief Print Status of f1TDC to standard out * @param id * - Slot Number * @param sflag Status flag * - !1: Show control status of the module * - 1: Show minimal error status of the f1TDC chips * - 2: Show f1TDC chip configuration * */ void f1Status(int id, int sflag) { int jj; unsigned int a32Base, ambMin, ambMax; unsigned int version; unsigned int csr, ctrl, ctrl2, count, blevel, intr, addr32, addrMB; unsigned short chipstat[F1_MAX_TDC_CHIPS]; unsigned int cmask=0; unsigned int bcount=0, ramWords=0; unsigned int trig1Cnt=0, trig2Cnt=0, srCnt=0; // ALEX unsigned int scaler2 = 0; unsigned int status_my[15]; unsigned int test_config_my = 0; // unsigned int clock_config_my = 0; // unsigned int test_config_my = 0; // unsigned int test_config_my = 0; // unsigned int test_config_my = 0; memset(status_my,0,sizeof(status_my)); if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("f1Status: ERROR : TDC in slot %d is not initialized \n",id); return; } F1LOCK; version = vmeRead32(&f1p[id]->version)&0xFFFF; csr = vmeRead32(&f1p[id]->csr); ctrl = vmeRead32(&f1p[id]->ctrl); ctrl2 = vmeRead32(&f1p[id]->ctrl2); count = vmeRead32(&f1p[id]->ev_count)&F1_EVENT_COUNT_MASK; blevel = vmeRead32(&f1p[id]->blocklevel)&F1_BLOCKLEVEL_MASK; intr = vmeRead32(&f1p[id]->intr); addr32 = vmeRead32(&f1p[id]->adr32); a32Base = (addr32&F1_A32_ADDR_MASK)<<16; addrMB = vmeRead32(&f1p[id]->adr_mb); ambMin = (addrMB&F1_AMB_MIN_MASK)<<16; ambMax = (addrMB&F1_AMB_MAX_MASK); bcount = vmeRead32(&f1p[id]->block_count); ramWords = vmeRead32(&f1p[id]->block_word_count_fifo); trig1Cnt = vmeRead32(&f1p[id]->scaler1); trig2Cnt = vmeRead32(&f1p[id]->trig2_scaler); srCnt = vmeRead32(&f1p[id]->sync_scaler); // ALEX scaler2 = vmeRead32(&f1p[id]->scaler2); status_my[0] = vmeRead32(&f1p[id]->status[0]); status_my[1] = vmeRead32(&f1p[id]->status[1]); status_my[2] = vmeRead32(&f1p[id]->status[2]); status_my[3] = vmeRead32(&f1p[id]->status[3]); status_my[4] = vmeRead32(&f1p[id]->status[4]); status_my[5] = vmeRead32(&f1p[id]->status[5]); status_my[6] = vmeRead32(&f1p[id]->status[6]); status_my[7] = vmeRead32(&f1p[id]->status[7]); status_my[8] = vmeRead32(&f1p[id]->status[8]); status_my[9] = vmeRead32(&f1p[id]->status[9]); status_my[10] = vmeRead32(&f1p[id]->status[10]); status_my[11] = vmeRead32(&f1p[id]->status[11]); status_my[12] = vmeRead32(&f1p[id]->status[12]); status_my[13] = vmeRead32(&f1p[id]->status[13]); status_my[14] = vmeRead32(&f1p[id]->status[14]); F1UNLOCK; #ifdef VXWORKS printf("\nSTATUS for TDC in slot %d at base address 0x%x \n",id,(UINT32) f1p[id]); #else printf("\nSTATUS for TDC in slot %d at VME (Local) base address 0x%x (0x%x) \n", id,(UINT32) f1p[id] - f1tdcA24Offset, (UINT32) f1p[id]); #endif printf("---------------------------------------------------------------------- \n"); printf(" Module Version = 0x%02x : Firmware Version = 0x%02x\n", (version & F1_VERSION_BOARDREV_MASK)>>8, version & F1_VERSION_FIRMWARE_MASK); // ALEX printf(" --- SCALER 2 = 0x%x\n",scaler2); printf(" ------------- \n "); for(jj = 0; jj < 15; jj++){ printf("Status %d = 0x%x\n",jj, status_my[jj]); } printf(" ------------- \n "); if(sflag != 1) { if(addrMB&F1_AMB_ENABLE) { printf(" Alternate VME Addressing: Multiblock Enabled\n"); if(addr32&F1_A32_ENABLE) printf(" A32 Enabled at VME (Local) base 0x%08x (0x%08x)\n",a32Base,(UINT32) f1pd[id]); else printf(" A32 Disabled\n"); printf(" Muliblock VME Address Range 0x%08x - 0x%08x\n",ambMin,ambMax); } else { printf(" Alternate VME Addressing: Multiblock Disabled\n"); if(addr32&F1_A32_ENABLE) printf(" A32 Enabled at VME (Local) base 0x%08x (0x%08x)\n",a32Base,(UINT32) f1pd[id]); else printf(" A32 Disabled\n"); } if(ctrl&F1_INT_ENABLE) { printf("\n Interrupts ENABLED: "); /* if(ctrl&F1_EVENT_LEVEL_INT) printf("EventLevel(%d)",level); */ /* if(ctrl&F1_ERROR_INT) printf("Errors "); */ /* printf("\n"); */ printf(" VME INT Vector = 0x%x Level = %d\n",(intr&F1_INT_VEC_MASK),((intr&F1_INT_LEVEL_MASK)>>8)); } printf("\n Signal Sources: \n"); printf(" Ref Clock : "); if(ctrl&F1_REFCLK_SRC_INTERNALFP) { if(ctrl&F1_REFCLK_SRC_FP) printf("Front Panel\n"); else { printf("Internal\n"); } } else printf("VXS\n"); printf(" Trig Src : "); if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_P0) printf("VXS\n"); else if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf(" Sync Reset: "); if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_P0) printf("VXS\n"); else if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf(" Start : "); if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_P0) printf("VXS\n"); else if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf("\n Configuration: \n"); if(ctrl&F1_REFCLK_INTERNAL_ENABLE) printf(" Internal Clock ON\n"); else printf(" Internal Clock OFF\n"); if(ctrl&F1_ENABLE_BERR) printf(" Bus Error ENABLED\n"); else printf(" Bus Error DISABLED\n"); printf(" MultiBlock transfer "); if(ctrl&F1_ENABLE_MULTIBLOCK) { int tP0, tP2; tP0 = ctrl&F1_MB_TOKEN_P0; tP2 = ctrl&F1_MB_TOKEN_P2; printf("ENABLED "); if(ctrl&F1_FIRST_BOARD) printf("(First Board "); else if(ctrl&F1_LAST_BOARD) printf("(Last Board "); else printf("( "); if(tP0 || tP2) { printf("token via "); if(tP0) printf("VXS"); if(tP2) printf("P2"); } printf(")\n"); } else { printf("DISABLED\n"); } printf("\n"); if(csr&F1_CSR_ERROR_MASK) { printf(" CSR Register = 0x%08x - Error Condition\n",csr); } else { printf(" CSR Register = 0x%08x \n",csr); } printf(" Control 1 Register = 0x%08x \n",ctrl); if(ctrl2&F1_GO_DATA) { printf(" Control 2 Register = 0x%08x - Enabled for triggers\n",ctrl2); } else { printf(" Control 2 Register = 0x%08x - Disabled\n",ctrl2); } printf(" Trigger Scaler = %d\n",trig1Cnt); printf(" Trigger 2 Scaler = %d\n",trig2Cnt); printf(" SyncReset Scaler = %d\n",srCnt); printf("\n"); if(csr&F1_CSR_BLOCK_READY) { printf(" Blocks in FIFO = %d (Block level = %d) - Block Available\n",bcount,blevel); printf(" Events in FIFO = %d (Block level = %d)\n",count,blevel); printf(" RAM Level (Bytes) = %d \n",(ramWords*8)); } else if((csr&F1_CSR_MODULE_EMPTY)==F1_CSR_MODULE_EMPTY) { printf(" Blocks in FIFO = %d (Block level = %d) - Block Available\n",bcount,blevel); printf(" Events in FIFO = %d (Block level = %d)\n",count,blevel); printf(" RAM Level (Bytes) = %d \n",(ramWords*8)); } else { printf(" Blocks in FIFO = %d (Block level = %d) - Block Available\n",bcount,blevel); printf(" Events in FIFO = %d (Block level = %d) - Data Available\n",count,blevel); printf(" RAM Level (Bytes) = %d \n",(ramWords*8)); } /* Print out Chip Status */ f1ChipStatus(id, 0); } else { /* Print minimal Error status of Chips on the TDC */ F1LOCK; for(jj=0;jjstat[jj]); if(((chipstat[jj]&F1_CHIP_RES_LOCKED)==0)||(chipstat[jj]&F1_CHIP_ERROR_COND)) cmask |= (1<version); st[id].adr32 = vmeRead32(&f1p[id]->adr32); st[id].adr_mb = vmeRead32(&f1p[id]->adr_mb); st[id].ctrl = vmeRead32(&f1p[id]->ctrl); st[id].ctrl2 = vmeRead32(&f1p[id]->ctrl2); st[id].csr = vmeRead32(&f1p[id]->csr); st[id].scaler1 = vmeRead32(&f1p[id]->scaler1); st[id].trig2_scaler = vmeRead32(&f1p[id]->trig2_scaler); st[id].sync_scaler = vmeRead32(&f1p[id]->sync_scaler); st[id].block_count = vmeRead32(&f1p[id]->block_count); st[id].blocklevel = vmeRead32(&f1p[id]->blocklevel); } F1UNLOCK; for (itdc=0;itdc>16)==3) printf("0x%04X %08X",(unsigned short)(~(f1ChannelDisable[id]>>32)&0xFFFF), (unsigned int)(~f1ChannelDisable[id] & 0xFFFFFFFF)); else printf("0x%08X", (unsigned int)(~f1ChannelDisable[id] & 0xFFFFFFFF)); printf("\n"); } printf("--------------------------------------------------------------------------------\n"); printf("\n"); printf(" f1TDC Chip Configuration\n\n"); printf(" Bin Full Rollover\n"); printf("Slot Chip Rez PL PTW Size Range Count\n"); printf("--------------------------------------------------------------------------------\n"); for(itdc=0; itdc>16)==2) { errmask = F1_CSR_V3_ERROR_MASK; } printf("%s ", st[id].csr & errmask ? "ERROR" : " OK " ); if(st[id].csr & errmask) { int ibit=0; printf("("); for(ibit=0; ibit>8) & (1<21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return; } F1LOCK; for(ii=0;iistat[ii]); } F1UNLOCK; printf("\n CHIP Status: (slot %d)\n",id); for(ii=0; ii>8; if(!(reg&F1_CHIP_INITIALIZED)) { printf(" CHIP %d Reg = 0x%04x - NOT Initialized \n",ii,reg); } else { if(lock==0) { printf(" CHIP %d Reg = 0x%04x ** Resolution NOT Locked **\n",ii,reg); } else if(latch) { printf(" CHIP %d Reg = 0x%04x ** Check Latched Status **\n",ii,reg); if(pflag) { if(lock==1) printf(" Resolution locked\n"); if(latch&F1_CHIP_RES_LOCKED) printf(" Loss of Resolution Lock occurred\n"); if(latch&F1_CHIP_HITFIFO_OVERFLOW) printf(" Hit FIFO Overflow occurred\n"); if(latch&F1_CHIP_TRIGFIFO_OVERFLOW) printf(" Trigger FIFO Overflow occured\n"); if(latch&F1_CHIP_OUTFIFO_OVERFLOW) printf(" Output FIFO Overflow occured\n"); if(latch&F1_CHIP_EXTFIFO_FULL) printf(" External FIFO Full occured\n"); } } else { printf(" CHIP %d Reg = 0x%04x - OK\n",ii,reg); if(pflag) { if(stat&F1_CHIP_HITFIFO_OVERFLOW) printf(" Hit FIFO has Overflowed\n"); if(stat&F1_CHIP_TRIGFIFO_OVERFLOW) printf(" Trigger has FIFO Overflowed\n"); if(stat&F1_CHIP_OUTFIFO_OVERFLOW) printf(" Output has FIFO Overflowed\n"); if(stat&F1_CHIP_EXTFIFO_FULL) printf(" External FIFO is Full\n"); if(stat&F1_CHIP_EXTFIFO_ALMOST_FULL) printf(" External FIFO Almost Full (Busy Asserted)\n"); if((stat&F1_CHIP_EXTFIFO_EMPTY) == 0) printf(" External FIFO NOT Empty\n"); } } } } } /** * @ingroup Readout * @brief General Data readout routine * * @param id Slot number of module to read * @param data local memory address to place data * @param nwrds Max number of words to transfer * @param rflag Readout Flag *
 *              0 - programmed I/O from the specified board
 *              1 - DMA transfer using Universe/Tempe DMA Engine 
 *                    (DMA VME transfer Mode must be setup prior)
 *              2 - Multiblock DMA transfer (Multiblock must be enabled
 *                     and daisychain in place or SD being used)
 * 
* @return Number of words inserted into data if successful. Otherwise ERROR. */ int f1ReadBlock(int id, volatile UINT32 *data, int nwrds, int rflag) { int ii; int stat, retVal, xferCount; int dCnt, berr=0; int dummy=0; volatile unsigned int *laddr; unsigned int bhead, val; unsigned int vmeAdr, csr=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1ReadBlock: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } if(data==NULL) { logMsg("f1ReadBlock: ERROR: Invalid Destination address\n",0,0,0,0,0,0); return(ERROR); } f1BlockError=F1_BLOCKERROR_NO_ERROR; if(nwrds <= 0) nwrds=F1_MAX_TDC_CHANNELS*F1_MAX_HITS_PER_CHANNEL; if(rflag >= 1) { /* Block Transfers */ /*Assume that the DMA programming is already setup. */ /* Don't Bother checking if there is valid data - that should be done prior to calling the read routine */ /* Check for 8 byte boundary for address - insert dummy word (Slot 30 TDC DATA 0xffff)*/ if((unsigned long) (data)&0x7) { #ifdef VXWORKS *data = F1_DUMMY_DATA; #else *data = LSWAP(F1_DUMMY_DATA); #endif dummy = 1; laddr = (data + 1); } else { dummy = 0; laddr = data; } if(rflag == 2) { /* Multiblock Mode */ F1LOCK; if((vmeRead32(&f1p[id]->ctrl)&F1_FIRST_BOARD)==0) { logMsg("f1ReadBlock: ERROR: TDC in slot %d is not First Board\n",id,0,0,0,0,0); F1UNLOCK; return(ERROR); } F1UNLOCK; vmeAdr = (unsigned int)(f1pmb) - f1tdcA32Offset; } else { vmeAdr = (unsigned int)(f1pd[id]) - f1tdcA32Offset; } F1LOCK; #ifdef VXWORKS retVal = sysVmeDmaSend((UINT32)laddr, vmeAdr, (nwrds<<2), 0); #else retVal = vmeDmaSend((UINT32)laddr, vmeAdr, (nwrds<<2)); #endif if(retVal != 0) { logMsg("f1ReadBlock: ERROR in DMA transfer Initialization 0x%x\n",retVal,0,0,0,0,0); F1UNLOCK; return(retVal); } /* Wait until Done or Error */ #ifdef VXWORKS retVal = sysVmeDmaDone(10000,1); #else retVal = vmeDmaDone(); #endif F1UNLOCK; if(retVal > 0) { /* Check to see that Bus error was generated by TDC */ if(rflag == 2) { F1LOCK; csr = vmeRead32(&f1p[f1MaxSlot]->csr); /* from Last TDC */ F1UNLOCK; stat = (csr)&F1_CSR_BERR_STATUS; /* from Last TDC */ } else { F1LOCK; stat = vmeRead32(&f1p[id]->csr)&F1_CSR_BERR_STATUS; /* from TDC id */ F1UNLOCK; } if((retVal>0) && (stat)) { #ifdef VXWORKS xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */ #else xferCount = (retVal>>2) + dummy; /* Number of Longwords transfered */ #endif return(xferCount); /* Return number of data words transfered */ } else { #ifdef VXWORKS xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */ logMsg("f1ReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x nwrds=%d)\n",csr,xferCount,0,0,0,0); f1BlockError=F1_BLOCKERROR_UNKNOWN_BUS_ERROR; #else xferCount = (retVal>>2) + dummy; /* Number of Longwords transfered */ if((retVal>>2)==nwrds) { logMsg("f1ReadBlock: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0); f1BlockError=F1_BLOCKERROR_TERM_ON_WORDCOUNT; } else { logMsg("f1ReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x xferCount=%d id=%d)\n", csr,xferCount,id,0,0,0); f1BlockError=F1_BLOCKERROR_UNKNOWN_BUS_ERROR; } #endif logMsg(" csr of other = 0x%08x\n",vmeRead32(&f1p[id]->csr)); return(xferCount); } } else if (retVal == 0) { /* Block Error finished without Bus Error */ #ifdef VXWORKS logMsg("f1ReadBlock: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0); #else logMsg("f1ReadBlock: WARN: DMA transfer returned zero word count 0x%x\n",nwrds,0,0,0,0,0); #endif f1BlockError=F1_BLOCKERROR_ZERO_WORD_COUNT; return(nwrds); } else { /* Error in DMA */ #ifdef VXWORKS logMsg("f1ReadBlock: ERROR: sysVmeDmaDone returned an Error\n",0,0,0,0,0,0); #else logMsg("f1ReadBlock: ERROR: vmeDmaDone returned an Error\n",0,0,0,0,0,0); #endif f1BlockError=F1_BLOCKERROR_DMADONE_ERROR; return(retVal); } } else { /*Programmed IO */ /* Check if Bus Errors are enabled. If so then disable for Prog I/O reading */ F1LOCK; berr = vmeRead32(&f1p[id]->ctrl)&F1_ENABLE_BERR; if(berr) vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) & ~F1_ENABLE_BERR); dCnt = 0; /* Read Block Header - should be first word */ bhead = (unsigned int) *f1pd[id]; #ifndef VXWORKS bhead = LSWAP(bhead); #endif if((bhead&F1_DATA_TYPE_DEFINE)&&((bhead&F1_DATA_TYPE_MASK) == F1_DATA_BLOCK_HEADER)) { #ifdef VXWORKS data[dCnt] = bhead; #else data[dCnt] = LSWAP(bhead); /* Swap back to little-endian */ #endif dCnt++; } else { /* We got bad data - Check if there is any data at all */ if( (vmeRead32(&(f1p[id]->ev_count)) & F1_EVENT_COUNT_MASK) == 0) { logMsg("f1ReadBlock: FIFO Empty (0x%08x)\n",bhead,0,0,0,0,0); F1UNLOCK; return(0); } else { logMsg("f1ReadBlock: ERROR: Invalid Header Word 0x%08x\n",bhead,0,0,0,0,0); F1UNLOCK; return(ERROR); } } ii=0; while(iictrl, vmeRead32(&f1p[id]->ctrl) | F1_ENABLE_BERR); } F1UNLOCK; return(dCnt); } return(OK); } /** * @ingroup Status * @brief Return the type of error that occurred while attempting a * block read from f1ReadBlock. * @param pflag * - >0: Print error message to standard out * @sa f1ReadBlock * @return OK if successful, otherwise ERROR. */ int f1GetBlockError(int pflag) { int rval=0; const char *block_error_names[F1_BLOCKERROR_NTYPES] = { "NO ERROR", "DMA Terminated on Word Count", "Unknown Bus Error", "Zero Word Count", "DmaDone Error" }; rval = f1BlockError; if(pflag) { if(rval!=F1_BLOCKERROR_NO_ERROR) { logMsg("f1GetBlockError: Block Transfer Error: %s\n", block_error_names[rval],2,3,4,5,6); } } return rval; } /** * @ingroup Readout * @brief Readout and print event to standard out. * * @param id Slot number of module to read * @param rflag Not used * @return Number of words read if successful. Otherwise ERROR. */ int f1PrintEvent(int id, int rflag) { int ii, evnum, trigtime, MAXWORDS=64*8; int dCnt, berr=0; unsigned int head, tail=0, val, chip; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("f1PrintEvent: ERROR : TDC in slot %d is not initialized \n",id); return(ERROR); } /* Check if data available */ F1LOCK; if((vmeRead32(&f1p[id]->ev_count)&F1_EVENT_COUNT_MASK)==0) { printf("f1PrintEvent: ERROR: FIFO Empty\n"); F1UNLOCK; return(0); } F1UNLOCK; /* Check if Bus Errors are enabled. If so then disable for reading */ F1LOCK; berr = vmeRead32(&f1p[id]->ctrl)&F1_ENABLE_BERR; if(berr) vmeWrite32(&f1p[id]->ctrl,vmeRead32(&f1p[id]->ctrl) & ~F1_ENABLE_BERR); F1UNLOCK; dCnt = 0; /* Read Header - */ F1LOCK; head = (unsigned int) *f1pd[id]; F1UNLOCK; #ifndef VXWORKS head = LSWAP(head); #endif /* check if valid data */ if((head&F1_DATA_SLOT_MASK) == F1_DATA_INVALID) { printf("f1PrintEvent: ERROR: Invalid Data from FIFO 0x%08x\n",head); return(ERROR); } if((head&F1_HT_DATA_MASK) != F1_HEAD_DATA) { printf("f1PrintEvent: ERROR: Invalid Header Word 0x%08x\n",head); return(ERROR); } else { printf("TDC DATA for Module in Slot %d\n",id); evnum = (head&F1_HT_EVENT_MASK)>>16; trigtime = (head&F1_HT_TRIG_MASK)>>7; chip = (head&F1_HT_CHIP_MASK)>>3; dCnt++; printf(" Header = 0x%08x(chip %d) Event = %d Trigger Time = %d ",head,chip,evnum,trigtime); } ii=0; while(ii>3; printf(" 0x%08x(H%d T%d)",val,chip,(val&F1_HT_TRIG_MASK)>>7); ii++; } else { printf(" 0x%08x ",val); ii++; } } dCnt += ii; #ifdef VERSION1_KILL /* Check if this is an end of Block and there is a filler word. If so then it should be read out and discarded */ F1LOCK; status = vmeRead32(&f1p[id]->csr); F1UNLOCK; if((status&F1_CSR_NEXT_BUF_NO)&&(status&F1_CSR_FILLER_FLAG)) { F1LOCK; val = (unsigned int) *f1pd[id]; F1UNLOCK; #ifndef VXWORKS val = LSWAP(val); #endif if(val&F1_DATA_SLOT_MASK) printf("f1PrintData: ERROR: Invalid filler word 0x%08x\n",val); printf(" Trailer = 0x%08x Word Count = %d Filler = 0x%08x\n",tail,dCnt,val); } else #endif // VERSION1 { printf(" Trailer = 0x%08x Word Count = %d\n",tail,dCnt); } if(berr) { F1LOCK; vmeWrite32(&f1p[id]->ctrl,vmeRead32(&f1p[id]->ctrl) | F1_ENABLE_BERR); F1UNLOCK; } return(dCnt); } /** * @ingroup Readout * @brief Routine to flush a partial event from the FIFO. Read until a valid trailer is found * * @param id * - Slot Number * * @return OK if successful, otherwise ERROR. */ int f1FlushEvent(int id) { /* int ii, evnum, trigtime, MAXWORDS=64*8; */ int ii, MAXWORDS=64*8; int berr=0; unsigned int tail, val; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1FlushEvent: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } /* Check if data available - If not then just issue a Clear */ F1LOCK; if((vmeRead32(&f1p[id]->ev_count)&F1_EVENT_COUNT_MASK)==0) { F1UNLOCK; f1Clear(id); return(0); } F1UNLOCK; /* Check if Bus Errors are enabled. If so then disable for reading */ F1LOCK; berr = vmeRead32(&f1p[id]->ctrl)&F1_ENABLE_BERR; if(berr) vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) & ~F1_ENABLE_BERR); F1UNLOCK; ii=0; while(iicsr); F1UNLOCK; if((status&F1_CSR_NEXT_BUF_NO)&&(status&F1_CSR_FILLER_FLAG)) { F1LOCK; val = (unsigned int) *f1pd[id]; F1UNLOCK; #ifndef VXWORKS val = LSWAP(val); #endif ii++; if(val&F1_DATA_SLOT_MASK) logMsg("f1FlushEvent: ERROR: Invalid filler word 0x%08x\n",val,0,0,0,0,0); } #endif // VERSION1 if(berr) { F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) | F1_ENABLE_BERR); F1UNLOCK; } return(ii); } /** * @ingroup Readout * @brief Readout and print event from all initialized f1TDCs to standard out * * @param rflag Not used * @return Number of words read if successful. Otherwise ERROR. */ int f1GPrintEvent(int rflag) { int ii, id, count, total=0; int mask=0, scan=0; /*check for data in all TDCs*/ for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1Clear: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->csr,F1_CSR_SOFT_RESET); F1UNLOCK; } /** * @ingroup Config * @brief Perform a soft reset on all initialized f1TDC modules * */ void f1GClear() { int ii; F1LOCK; for(ii=0;iicsr), F1_CSR_SOFT_RESET); F1UNLOCK; } /** * @ingroup Config * @brief Clear the latched error status of specified f1TDC chips in the chipMask * * @param id * - Slot Number * @param chipMask * - Mask for f1TDC chips to clear latched error status * */ void f1ClearStatus(int id, unsigned int chipMask) { int ii; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1ClearStatus: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } /* Default clear all chips latched status bits */ if(chipMask<=0) chipMask=F1_ALL_CHIPS; F1LOCK; for(ii=0;iistat[ii], F1_CHIP_CLEAR_STATUS); } } F1UNLOCK; } /** * @ingroup Config * @brief Clear the latched error status of specified f1TDC chips in the chipMask in * all initialized f1TDCs * * @param chipMask * - Mask for f1TDC chips to clear latched error status * */ void f1GClearStatus(unsigned int chipMask) { int ii, id; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1ErrorStatus: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(0); } if(sflag==1) { /* Do full latch and persistance check of all chips */ F1LOCK; for(jj=0;jjstat[jj]); if(((chipstat[jj]&F1_CHIP_RES_LOCKED)==0)||(chipstat[jj]&F1_CHIP_ERROR_COND)) cmask |= (1<csr); F1UNLOCK; if(err&F1_CSR_ERROR_MASK) /* an Error condition exists */ return((err&F1_CSR_ERROR_MASK)>>8); else return(0); } } /** * @ingroup Status * @brief Return the Error status for all the f1TDC chips on all initialized modules * * @param sflag Status flag * - 0: Just read the status and return error info * - !0: Do full latch and persistance check of all chips * * @return Slot Mask of f1TDCs that report a latched error status */ unsigned int f1GErrorStatus(int sflag) { int ii, jj, id, count; unsigned short chipstat[F1_MAX_TDC_CHIPS]; unsigned int emask=0; if(sflag==1) { /* Do full latch and persistance check of all chips */ F1LOCK; for(ii=0;iistat[jj]); if(((chipstat[jj]&F1_CHIP_RES_LOCKED)==0)||(chipstat[jj]&F1_CHIP_ERROR_COND)) emask |= (1<csr)&F1_CSR_ERROR_MASK); if(count) emask |= (1<21) || (f1p[id] == NULL)) { logMsg("f1CheckLock: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } #ifdef VXWORKS /* Get Chip status Register data in longword chunks - faster than in 16bit mode*/ bcopyLongs((char *)&f1p[id]->stat[0],(char *)&chipstat[0],4); #else F1LOCK; for(jj=0;jj<8;jj++) { chipstat[jj] = vmeRead16(&f1p[id]->stat[jj]); } F1UNLOCK; #endif for(jj=0;jjcsr)&F1_CSR_ERROR_MASK); /* If there is an error check if it is Resolution NOT locked */ if(stat) { emask = f1CheckLock(id); if(emask) { mmask |= (1<21) || (f1p[id] == NULL)) { logMsg("f1Reset: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } if((iFlag<0)||(iFlag>3)) iFlag=2; /* Default to Normal Syncronous */ F1LOCK; a32addr = vmeRead32(&f1p[id]->adr32); addrMB = vmeRead32(&f1p[id]->adr_mb); vmeWrite32(&f1p[id]->csr, F1_CSR_HARD_RESET); taskDelay(30); F1UNLOCK; f1ConfigWrite(id, (int *) &f1ConfigData[iFlag], F1_ALL_CHIPS); #ifdef SKIPTHIS F1LOCK; vmeWrite32(&f1p[id]->adr32, a32addr); vmeWrite32(&f1p[id]->adr_mb, addrMB); F1UNLOCK; // FIXME: Change this, if using SD f1EnableClk(id,0); #endif f1ClearStatus(id,F1_ALL_CHIPS); } /** * @ingroup Config * @brief Perform a software Sync Reset on the module * * @param id * - Slot Number * */ void f1SyncReset(int id) { unsigned int ctrl=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SyncReset: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; ctrl = vmeRead32(&f1p[id]->ctrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_SYNC_RESET_SRC_MASK) == F1_SYNC_RESET_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_SYNC_RESET); else logMsg("f1SyncReset: ERROR: Software Sync Reset not enabled",0,0,0,0,0,0); } else { logMsg("f1SyncReset: ERROR: Software Control Signals not enabled",0,0,0,0,0,0); } F1UNLOCK; } /** * @ingroup Config * @brief Perform a software Sync Reset for all initialized modules * */ void f1GSyncReset() { unsigned int ctrl=0; int ii, id; F1LOCK; for(ii=0;iictrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_SYNC_RESET_SRC_MASK) == F1_SYNC_RESET_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_SYNC_RESET); else logMsg("f1GSyncReset: ERROR: Software Sync Reset not enabled for TDC in slot %d",id,0,0,0,0,0); } else { logMsg("f1GSyncReset: ERROR: Software Control Signals not enabled for TDC in slot %d", id,0,0,0,0,0); } } F1UNLOCK; } /** * @ingroup Config * @brief Issue a software trigger to the module * * @param id * - Slot Number * */ void f1Trig(int id) { unsigned int ctrl=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1Trig: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; ctrl = vmeRead32(&f1p[id]->ctrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_TRIGGER_SRC_MASK) == F1_TRIGGER_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_TRIGGER); else logMsg("f1Trig: ERROR: Software Triggers not enabled",0,0,0,0,0,0); } else { logMsg("f1Trig: ERROR: Software Control Signals not enabled",0,0,0,0,0,0); } F1UNLOCK; } /** * @ingroup Config * @brief Issue a software trigger to all initialized modules * * */ void f1GTrig() { unsigned int ctrl=0; int ii, id; F1LOCK; for(ii=0;iictrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_TRIGGER_SRC_MASK) == F1_TRIGGER_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_TRIGGER); else logMsg("f1GTrig: ERROR: Software Triggers not enabled for TDC in slot %d",id,0,0,0,0,0); } else { logMsg("f1GTrig: ERROR: Software Control Signals not enabled for TDC in slot %d", id,0,0,0,0,0); } } F1UNLOCK; } /** * @ingroup Deprec * @brief Issue a software Start signal to the module * * @param id * - Slot Number * */ void f1Start(int id) { unsigned int ctrl=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1Start: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; ctrl = vmeRead32(&f1p[id]->ctrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_START_SRC_MASK) == F1_START_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_START); else logMsg("f1Start: ERROR: Software Start not enabled",0,0,0,0,0,0); } else { logMsg("f1Start: ERROR: Software Control Signals not enabled",0,0,0,0,0,0); } F1UNLOCK; } /** * @ingroup Deprec * @brief Issue a software Start signal to all initialized modules * * */ void f1GStart() { unsigned int ctrl=0; int ii, id; F1LOCK; for(ii=0;iictrl); if(ctrl & F1_ENABLE_SOFT_CONTROL) { if((ctrl&F1_START_SRC_MASK) == F1_START_SRC_SOFT) vmeWrite32(&f1p[id]->csr, F1_CSR_START); else logMsg("f1GStart: ERROR: Software Start not enabled for TDC in slot %d",id,0,0,0,0,0); } else { logMsg("f1GStart: ERROR: Software Control Signals not enabled for TDC in slot %d", id,0,0,0,0,0); } } F1UNLOCK; } /** * @ingroup Readout * @brief Determine if an event is ready for readout on the module * * @param id * - Slot Number * @return Number of events ready for readout, otherwise ERROR */ /* Return Event count for TDC in slot id */ int f1Dready(int id) { int rval; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1Dready: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; rval = vmeRead32(&f1p[id]->ev_count)&F1_EVENT_COUNT_MASK; F1UNLOCK; return(rval); } /** * @ingroup Readout * @brief Return block available for readout status of the module * * @param id * - Slot Number * @return 1 if block available for readout, 0 if not, otherwise ERROR */ /* Return True if there is an event Block ready for readout */ int f1Bready(int id) { int stat; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1Bready: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; stat = (vmeRead32(&f1p[id]->csr)&F1_CSR_BLOCK_READY)>>4; F1UNLOCK; return(stat); } /** * @ingroup Readout * @brief Return the mask of all initialized modules with blocks available for readout * * @return mask of all initialized modules with blocks available for readout */ unsigned int f1GBready() { int ii, id, stat; unsigned int dmask=0; F1LOCK; for(ii=0;iicsr)&F1_CSR_BLOCK_READY; if(stat) dmask |= (1<0: Print event count of each module to standard out. * @return mask of all initialized modules with events available for readout */ /* Return Slot mask for modules with data avaialable */ int f1DataScan(int pflag) { int ii, count, id, dmask=0; F1LOCK; for(ii=0;iiev_count)&F1_EVENT_COUNT_MASK; if(count) dmask |= (1<21) || (f1p[id] == NULL)) { logMsg("f1GetRez: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1SetWindow: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } if(chipMask<=0) chipMask = F1_ALL_CHIPS; enMask = f1Enabled(id); if(f1ClockSource==0) /* Internal */ clk_period = 31.25; else /* External */ clk_period = 32.; for(ichip=0;ichip>6)&0x1ff) + 2); winMax = (tframe*(0.4)); latMax = (tframe*(0.9)); if((window>winMax)||(window<=0)) { logMsg("f1SetWindow: Trig Window for chip %d Out of range. Set to %d ns\n",ichip,winMax,0,0,0,0); window = winMax; } if(latencylatMax) { logMsg("f1SetWindow: Trig Latency for chip %d Out of range. Set to %d ns\n",ichip,latMax,0,0,0,0); latency = latMax; } exponent = ((config[10])>>8)&0x7; refclkdiv = 1; for(jj = 0; jj21) || (f1p[id] == NULL)) { logMsg("f1ReadCSR: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(0xffffffff); } F1LOCK; rval = vmeRead32(&f1p[id]->csr); F1UNLOCK; return(rval); } /** * @ingroup Config * @brief Write provided value to the CTRL register of the module * * @param id * - Slot Number * @param val * - Value to write to CTRL register * * @return Read value at CTRL register after the write, otherwise ERROR */ int f1WriteControl(int id, unsigned int val) { int rval; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1WriteControl: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; vmeWrite32(&f1p[id]->ctrl, val); rval = vmeRead32(&f1p[id]->ctrl)&F1_CONTROL_MASK; F1UNLOCK; return(rval); } /** * @ingroup Config * @brief Write provided value to the CTRL register to all initialized modules * * @param id * - Slot Number * @param val * - Value to write to CTRL register */ void f1GWriteControl(unsigned int val) { int id, ii; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1Enable: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; vmeWrite32(&f1p[id]->ctrl2, F1_GO_DATA); F1UNLOCK; return OK; } /** * @ingroup Config * @brief Enable f1TDC FPGA data fifo on all initialized modules * * @return OK */ int f1GEnable() { int id, ii; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1Disable: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; vmeWrite32(&f1p[id]->ctrl2, 0); F1UNLOCK; return OK; } /** * @ingroup Config * @brief Disable f1TDC FPGA data fifo on all initialized modules * * @return OK */ int f1GDisable() { int id, ii; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1Enabled: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } F1LOCK; res = (vmeRead32(&f1p[id]->ctrl)&0xff0000)>>16; F1UNLOCK; return(res); /* Return the output FIFO enable mask */ } /** * @ingroup Config * @brief Enable data on f1TDC chips specified in chipMask for the module * * @param id * - Slot Number * @param chipMask * - Mask of chips to enable * @return OK if successful, otherwise ERROR */ int f1EnableData(int id, int chipMask) { int ichip, jj, mask=0; unsigned int reg, rval; unsigned int allchips_mask=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1EnableData: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } if(chipMask<=0) chipMask = F1_ALL_CHIPS; /* Enable all Chips */ allchips_mask = ((1<<(f1Nchips[id]))-1); /* Mask only the chips on the module */ chipMask = chipMask & allchips_mask; /* Enable FIFOs for each chip */ mask = (chipMask&0xff)<<16; F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) | mask); /* Enable Edges for each chip */ if((allchips_mask & chipMask) == allchips_mask) { /* Write the same configuration to all chips */ ichip=0; for(jj=2; jj<6; jj++) /* write cfg data */ { reg = f1ReadChip(id, ichip, jj); reg = reg | F1_ENABLE_EDGES; f1WriteAllChips(id, jj, reg); taskDelay(1); // FIXME: Put this back in, when f1 stores the config in memory /* rval = f1ReadChip(id, ichip, reg); */ /* if((rval & 0xFFFF) != data) */ /* { */ /* printf("%s(%d): ERROR writing to chip %d reg %2d..\n", */ /* __FUNCTION__,id, ichip, reg); */ /* printf("\t Write (0x%04x) != Readback (0x%04x)\n", */ /* data, rval%0xFFFF); */ /* } */ } } else { for(ichip=0;ichip21) || (f1p[id] == NULL)) { logMsg("f1DisableData: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } /* Disable FIFOs for All chips */ mask = (0xff)<<16; F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) & ~mask); /* Disable Edges for All chips */ for(ichip=0;ichiprev == 2) /* V2 */ { ci->rez = 1; /* high resolution */ ci->maxchan = 31; } else /* V3 */ { ci->rez = 0; /* normal resolution */ ci->maxchan = 47; } input = ci->input; if(ci->rez==1) input = input*2; else input = input; ci->chip = (int)(input/8); ci->chan = ~((input%8)) & 0x7; /* In V2 and V3, Front Panel Channel number is inverted WRT the Chip Channel Number (e.g. 0->7, 1->6). This is fixed in firmware for the readout data, but must be fixed by the software driver for writing to the f1chip. */ ci->reg = (int)(((ci->chan)/2) + 2); /* Reg 2 - 6 */ ci->odd = ci->chan%2; /* Odd (1) or Even (0) Channel */ } static int f1SetChannel(int id, int input, int enable) { chipchanInfo c; unsigned int rval, check_rval; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SetChannel: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } c.rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>16; c.input = input; f1Input2ChipChannel(&c); /* Determine Chip number and Channel for the given input */ if((input<0)||(input>c.maxchan)) { logMsg("f1SetChannel: ERROR: Invalid channel number (%d)\n",input); return(ERROR); } /* Disable Edges for specified Channel */ F1LOCK; rval = f1ReadChip(id, c.chip, c.reg); if(c.rez) { if(enable>0) rval = rval | ~F1_DISABLE_EDGES; else rval = rval & F1_DISABLE_EDGES; } else { if(c.odd) { if(enable>0) rval = rval | ~F1_DISABLE_EDGES_ODD; else rval = rval & F1_DISABLE_EDGES_ODD; } else { if(enable>0) rval = rval | ~F1_DISABLE_EDGES_EVEN; else rval = rval & F1_DISABLE_EDGES_EVEN; } } f1WriteChip(id, c.chip, c.reg, rval); taskDelay(1); /* read it back and check */ check_rval = f1ReadChip(id, c.chip, c.reg); F1UNLOCK; if(rval != check_rval) { logMsg("f1SetChannel: Error writing Config (%x != %x) \n",rval,check_rval,0,0,0,0); } if(enable>0) f1ChannelDisable[id] &= ~(1<21) || (f1p[id] == NULL)) { logMsg("f1DisableChannelMask: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; c.rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>16; /* Grab the initial registers from each chip */ for(ichip=0; ichip0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES; } else { if(c.odd) { if(enable>0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES_ODD; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES_ODD; } else { if(enable>0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES_EVEN; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES_EVEN; } } } else { if(c.rez) { if(enable>0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES; } else { if(c.odd) { if(enable>0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES_ODD; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES_ODD; } else { if(enable>0) chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] & F1_DISABLE_EDGES_EVEN; else chipRegs[c.chip][c.reg] = chipRegs[c.chip][c.reg] | ~F1_DISABLE_EDGES_EVEN; } } } } /* Write the new registers for each chip */ for(ichip=0; ichip0) f1ChannelDisable[id] = ~mask; // FIXME: Add appropriate maxchan mask else f1ChannelDisable[id] = mask; F1UNLOCK; } /** * @ingroup Config * @brief Disable inputs indicated in channel mask for the module * * @param id * - Slot Number * @param mask * - Mask of input channels to DISABLE * */ void f1DisableChannelMask(int id, unsigned long long int mask) { f1SetChannelMask(id,mask,0); } /** * @ingroup Config * @brief Enable inputs indicated in channel mask for the module * * @param id * - Slot Number * @param mask * - Mask of input channels to Enable * */ void f1EnableChannelMask(int id, unsigned long long int mask) { f1SetChannelMask(id,mask,1); } /* F1 Chip Write and Read routines. These routines are static because they do not use mutex locks/unlocks. Be sure to implement those mutex's when calling these routines */ /* A temporary place to store chip registers, until the firmware allows for the module to store them */ static unsigned short f1ChipRegs[F1_MAX_BOARDS+1][8][16]; /* Write a 2 byte word to a single register on a f1tdc chip */ static int f1WriteChip(int id, int chip, int reg, unsigned short data) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } if((chip<0) || (chip>=f1Nchips[id])) { printf("%s: ERROR: Invalid chip (%d)\n", __FUNCTION__,chip); return ERROR; } if((reg<0) || (reg>=16)) { printf("%s: ERROR: Invalid register (%d)\n", __FUNCTION__,reg); return ERROR; } vmeWrite32(&f1p[id]->config, (chip<<21) | (reg<<16) | data); f1ChipRegs[id][chip][reg] = data; return OK; } /* Write a 2 byte word to a single register on all f1tdc chips in the module */ static int f1WriteAllChips(int id, int reg, unsigned short data) { int ichip=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } if((reg<0) || (reg>=16)) { printf("%s: ERROR: Invalid register (%d)\n", __FUNCTION__,reg); return ERROR; } vmeWrite32(&f1p[id]->config, F1_CONFIG_COMMON | (reg<<16) | data); for(ichip=0; ichip<8; ichip++) f1ChipRegs[id][ichip][reg] = data; return OK; } /* Read a 2 byte word from a single register on an f1tdc chip */ static unsigned short f1ReadChip(int id, int chip, int reg) { unsigned short rval; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } // FIXME: for now... register values stored in library. // Future firmware well have these available for readout on the module rval = f1ChipRegs[id][chip][reg]; return rval; } /** * @ingroup Config * @brief Enable the specified clock source on the module * * @param id * - Slot Number * @param cflag Clock Source Flag * - 0: P0/VXS * - 1: Internal * - 2: Front Panel */ void f1EnableClk(int id, int cflag) { unsigned int clkbits=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1EnableClk: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } if((cflag<0) || (cflag>2)) { printf("%s: ERROR: Invalid clock source (%d)\n",__FUNCTION__,cflag); return; } F1LOCK; switch(cflag) { case 1: clkbits = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_INTERNAL_ENABLE; break; case 2: clkbits = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_SRC_FP; break; case 0: default: clkbits = 0; } vmeWrite32(&f1p[id]->ctrl, (vmeRead32(&f1p[id]->ctrl) & ~F1_REFCLK_SRC_MASK) | clkbits); F1UNLOCK; } /** * @ingroup Config * @brief Disable the current clock source on the module * * @param id * - Slot Number * */ void f1DisableClk(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1DisableClk: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, (vmeRead32(&f1p[id]->ctrl) & ~F1_REFCLK_SRC_MASK) | F1_REFCLK_SRC_INTERNALFP); F1UNLOCK; } /** * @ingroup Config * @brief Enable lead and trailing edges for the f1TDC chips indicated by the chipMask for the module * * @param id * - Slot Number * @param chipMask * - Mask of chips to enable Lead and Trailing edges * * @return Mask of initialized slots with leading and trailing edges enabled. */ unsigned int f1EnableLetra(int id, int chipMask) { /* int ii; */ if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1EnableLetra: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(0); } if(chipMask<=0) chipMask = F1_ALL_CHIPS; /* Enable all Chips */ f1LetraMode |= (1<21) || (f1p[id] == NULL)) { logMsg("f1DisableLetra: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(0); } if(chipMask<=0) chipMask = F1_ALL_CHIPS; /* Disable all Chips */ f1LetraMode &= ~(1<21) || (f1p[id] == NULL)) { logMsg("f1EnableSoftTrig: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) | F1_ENABLE_SOFT_CONTROL); F1UNLOCK; } /** * @ingroup Config * @brief Enable software triggers for all initialized modules * * */ void f1GEnableSoftTrig() { int ii; F1LOCK; for(ii=0;iictrl), vmeRead32(&(f1p[f1ID[ii]]->ctrl)) | F1_ENABLE_SOFT_CONTROL); F1UNLOCK; } /** * @ingroup Config * @brief Disable software triggers on the module * * @param id * - Slot Number * */ void f1DisableSoftTrig(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1DisableSoftTrig: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) & ~F1_ENABLE_SOFT_CONTROL); F1UNLOCK; } /** * @ingroup Config * @brief Enable bus error block termination on the module * * @param id * - Slot Number * */ void f1EnableBusError(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1EnableBusError: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) | F1_ENABLE_BERR); F1UNLOCK; } /** * @ingroup Config * @brief Enable bus error block termination for all initialized modules * * */ void f1GEnableBusError() { int ii; F1LOCK; for(ii=0;iictrl), vmeRead32(&(f1p[f1ID[ii]]->ctrl)) | F1_ENABLE_BERR); F1UNLOCK; } /** * @ingroup Config * @brief Disable bus error block termination on the module * * @param id * - Slot Number * */ void f1DisableBusError(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1DisableBusError: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, vmeRead32(&f1p[id]->ctrl) & ~F1_ENABLE_BERR); F1UNLOCK; } /** * @ingroup Config * @brief Set the block level (number of events per block) on the module * * @param id * - Slot Number * @param level * - Number of events per block * * @return OK if successful, otherwise ERROR */ int f1SetBlockLevel(int id, int level) { int rval; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SetBlockLevel: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } if(level<=0) level = 1; F1LOCK; vmeWrite32(&f1p[id]->blocklevel, level); rval = vmeRead32(&f1p[id]->blocklevel)&F1_BLOCKLEVEL_MASK; F1UNLOCK; return(rval); } /** * @ingroup Config * @brief Set the block level (number of events per block) on all initialized modules * * @param id * - Slot Number * @param level * - Number of events per block */ void f1GSetBlockLevel(int level) { int ii; if(level<=0) level = 1; F1LOCK; for(ii=0;iiblocklevel), level); F1UNLOCK; } /** * @ingroup Config * @brief Enable multiblock readout for all initialized modules * * @param tflag Token Flag * - 0: Token passed through P2 * - >0: Token passed through P0/VXS */ void f1EnableMultiBlock(int tflag) { int ii, id; unsigned int mode=0; if((nf1tdc <= 1) || (f1p[f1ID[0]] == NULL)) { logMsg("f1EnableMultiBlock: ERROR : Cannot Enable MultiBlock mode \n",0,0,0,0,0,0); return; } for(ii=0;ii 0 then send via P0 else via P2 */ if(tflag) mode = F1_MB_TOKEN_P0 | F1_ENABLE_MULTIBLOCK; else mode = F1_MB_TOKEN_P2 | F1_ENABLE_MULTIBLOCK; id = f1ID[ii]; f1DisableBusError(id); if(id == f1MinSlot) { mode |= F1_FIRST_BOARD; } if(id == f1MaxSlot) { mode |= F1_LAST_BOARD; f1EnableBusError(id); } F1LOCK; vmeWrite32(&f1p[id]->ctrl, (vmeRead32(&f1p[id]->ctrl) & ~F1_MB_CONFIG_MASK) | mode); F1UNLOCK; } } /** * @ingroup Config * @brief Disable multiblock readout for all initialized modules */ void f1DisableMultiBlock() { int ii; if((nf1tdc <= 1) || (f1p[f1ID[0]] == NULL)) { logMsg("f1DisableMultiBlock: ERROR : Cannot Disable MultiBlock Mode\n",0,0,0,0,0,0); return; } F1LOCK; for(ii=0;iictrl), vmeRead32(&(f1p[f1ID[ii]]->ctrl)) & ~F1_ENABLE_MULTIBLOCK); F1UNLOCK; } /** * @ingroup Config * @brief Reset the token for the module * * This routine only has an effect for the module marked as "FIRST" in the * multiblock chain. * * @param id * - Slot Number * */ void f1ResetToken(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1ResetToken: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } F1LOCK; vmeWrite32(&f1p[id]->csr, F1_CSR_TOKEN_RETURN); F1UNLOCK; } /** * @ingroup Status * @brief Return the status of the token * @param id Slot number * @return 1 if module has the token, 0 if not, otherwise ERROR. */ int f1TokenStatus(int id) { int rval=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1TokenStatus: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return ERROR; } F1LOCK; rval = (vmeRead32(&f1p[id]->csr) & F1_CSR_TOKEN_STATUS)>>6; F1UNLOCK; return rval; } /** * @ingroup Status * @brief Return the slotmask of those modules that have the token. * @return Token Slotmask */ int f1GTokenStatus() { int ifa=0, bit=0, rval=0; for(ifa = 0; ifa0: Enable forcing of chip headers * * @return OK if successful, otherwise ERROR */ int f1SetForceChipHeaders(int id, int enable) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__,id); return ERROR; } F1LOCK; if(enable) { vmeWrite32(&f1p[id]->ctrl2, vmeRead32(&f1p[id]->ctrl2) | F1_FORCE_CHIP_HEADERS); } else { vmeWrite32(&f1p[id]->ctrl2, vmeRead32(&f1p[id]->ctrl2) & ~F1_FORCE_CHIP_HEADERS); } F1UNLOCK; return OK; } /** * @ingroup Config * @brief Force f1TDC Chip Headers into the data stream for all initialized modules * * @param enable * - 0: Disable forcing of chip headers * - >0: Enable forcing of chip headers */ void f1GSetForceChipHeaders(int enable) { int id, ii; for(ii=0;ii21) || (f1p[id] == NULL)) { logMsg("f1ResetPulser: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return ERROR; } rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>8; if(rev != 3) { logMsg("f1ResetPulser: ERROR: f1TDC Board Revision (%d) does not have pulser support", rev,2,3,4,5,6); return ERROR; } F1LOCK; vmeWrite32(&f1p[id]->pulser_dac, F1_PULSER_DAC_RESET); taskDelay(1); vmeWrite32(&f1p[id]->pulser_dac, F1_PULSER_DAC_INT_REF); taskDelay(1); F1UNLOCK; return OK; } /** * @ingroup PulserConfig * @brief Set the delay between the output pulse and f1TDC trigger * * @param id * - Slot Number * */ int f1SetPulserTriggerDelay(int id, int delay) { int rev=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SetPulserTriggerDelay: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return ERROR; } rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>8; if(rev != 3) { logMsg("f1SetPulserTriggerDelay: ERROR: f1TDC Board Revision (%d) does not have pulser support", rev,2,3,4,5,6); return ERROR; } if(delay>F1_PULSER_DELAY_MASK) { logMsg("f1SetPulserTriggerDelay: ERROR: delay (%d) out of range. Must be <= %d", delay,F1_PULSER_DELAY_MASK,3,4,5,6); return ERROR; } F1LOCK; vmeWrite32(&f1p[id]->pulser_delay, delay); F1UNLOCK; return OK; } /** * @ingroup PulserConfig * @brief Set the DAC level for the outgoing pulse * * @param id * - Slot Number * @param output * - 1: channels 0-23 * - 2: channels 24-37 * - 3: all channels * * @param dac * - 400 should be sufficient for the Hall D descriminator cards) * * @return OK if successful, otherwise ERROR. */ int f1SetPulserDAC(int id, int output, int dac) { int rev=0; unsigned int selection=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SetPulserDAC: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return ERROR; } rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>8; if(rev != 3) { logMsg("f1SetPulserDAC: ERROR: f1TDC Board Revision (%d) does not have pulser support", rev,2,3,4,5,6); return ERROR; } if(dac>(F1_PULSER_DAC_MASK>>4)) { logMsg("f1SetPulserDAC: ERROR: dac (%d) out of range. Must be <= %d", dac,F1_PULSER_DAC_MASK,3,4,5,6); return ERROR; } switch(output) { case 1: /* DAC A: lower cable - channels 0-23 */ selection = F1_PULSER_DAC_A_VALUE; break; case 2: /* DAC B: upper cable - channels 24-47 */ selection = F1_PULSER_DAC_B_VALUE; break; case 3: /* DAC A and B: both cables */ selection = F1_PULSER_DAC_BOTH_VALUE; break; default: logMsg("f1SetPulserDAC: ERROR: Invalid DAC output selection (%d)", output,2,3,4,5,6); return ERROR; } F1LOCK; vmeWrite32(&f1p[id]->pulser_dac, (dac<<4) | selection); F1UNLOCK; return OK; } /** * @ingroup PulserConfig * @brief Trigger the pulser * * @param id * - Slot Number * @param output * - 1: Pulse out only * - 2: f1TDC Trigger only * - 3: Both pulse and trigger * @return OK if successful, otherwise ERROR. */ int f1SoftPulser(int id, int output) { int rev=0; unsigned int selection=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SoftPulser: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return ERROR; } rev = (f1Rev[id] & F1_VERSION_BOARDREV_MASK)>>8; if(rev != 3) { logMsg("f1SoftPulser: ERROR: f1TDC Board Revision (%d) does not have pulser support", rev,2,3,4,5,6); return ERROR; } switch(output) { case 0: /* Just the pulse out */ selection = F1_PULSER_PULSE_OUT; break; case 1: /* Just the trigger out */ selection = F1_PULSER_TRIGGER_OUT; break; case 2: /* Pulse and trigger out */ selection = F1_PULSER_PULSE_OUT | F1_PULSER_TRIGGER_OUT; break; default: logMsg("f1SoftPulser: ERROR: Invalid output option (%d)", output,2,3,4,5,6); return ERROR; } F1LOCK; vmeWrite32(&f1p[id]->pulser_control, selection); F1UNLOCK; return OK; } /** * @ingroup DebugSW * @brief Enable/Disable System test mode * @param id * - Slot Number * @param mode * - 0: Disable Test Mode * - >0: Enable Test Mode */ void f1TestSetSystemTestMode(int id, int mode) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } F1LOCK; if(mode>=1) { vmeWrite32(&(f1p[id]->ctrl2), vmeRead32(&f1p[id]->ctrl2) | F1_SINGLE_BOARD_TEST_MODE); } else { vmeWrite32(&(f1p[id]->ctrl2), vmeRead32(&f1p[id]->ctrl2) & ~F1_SINGLE_BOARD_TEST_MODE); } printf(" ctrl2 = 0x%08x\n",vmeRead32(&f1p[id]->ctrl2)); F1UNLOCK; } /** * @ingroup DebugSW * @brief Set the level of Trig Out to the SD * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @param mode * - 0: Not asserted * - >0: Asserted */ void f1TestSetTrigOut(int id, int mode) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } if(mode>=1) reg=F1_TEST_TRIG_OUT; else reg=0; F1LOCK; vmeWrite32(&(f1p[id]->test_config),reg); F1UNLOCK; } /** * @ingroup DebugSW * @brief Set the level of Busy Out to the SD * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @param mode * - 0: Not asserted * - >0: Asserted * */ void f1TestSetBusyOut(int id, int mode) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } if(mode>=1) reg=F1_TEST_BUSY_OUT; else reg=0; F1LOCK; vmeWrite32(&(f1p[id]->test_config),reg); F1UNLOCK; } /** * @ingroup DebugSW * @brief Set the level of the SD Link * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @param mode * - 0: Not asserted * - >0: Asserted */ void f1TestSetSdLink(int id, int mode) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } if(mode>=1) reg=F1_TEST_SDLINK_OUT; else reg=0; F1LOCK; vmeWrite32(&(f1p[id]->test_config),reg); F1UNLOCK; } /** * @ingroup DebugSW * @brief Set the level of Token Out to the SD * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @param mode * - 0: Not asserted * - >0: Asserted * */ void f1TestSetTokenOut(int id, int mode) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } if(mode>=1) reg=F1_TEST_TOKEN_OUT; else reg=0; F1LOCK; vmeWrite32(&(f1p[id]->test_config),reg); F1UNLOCK; } /** * @ingroup DebugSW * @brief Get the level of the StatBitB to the SD * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return 1 if asserted, 0 if not, otherwise ERROR. * */ int f1TestGetStatBitB(int id) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = (vmeRead32(&f1p[id]->test_config) & F1_TEST_STATBITB_IN)>>8; F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Get the level of the Token In from the SD * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return 1 if asserted, 0 if not, otherwise ERROR. */ int f1TestGetTokenIn(int id) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = (vmeRead32(&f1p[id]->test_config) & F1_TEST_TOKEN_IN)>>9; F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Return the status of the 250Mhz Clock Counter * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return 1 if counting, 0 if not counting, otherwise ERROR. */ int f1TestGetClockCounterStatus(int id) { int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = (vmeRead32(&f1p[id]->test_config) & F1_TEST_CLOCK_COUNTER_STATUS)>>15; F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Return the value of the 250Mhz Clock scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return 250Mhz Clock scaler counter if successful, otherwise ERROR. */ unsigned int f1TestGetClockCounter(int id) { unsigned int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = vmeRead32(&f1p[id]->clock_scaler); F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Return the value of the SyncReset scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return SyncReset scaler counter if successful, otherwise ERROR. */ unsigned int f1TestGetSyncCounter(int id) { unsigned int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = vmeRead32(&f1p[id]->p0_sync_scaler); F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Return the value of the trig1 scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return trig1 scaler counter if successful, otherwise ERROR. */ unsigned int f1TestGetTrig1Counter(int id) { unsigned int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = vmeRead32(&f1p[id]->p0_trig1_scaler); F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Return the value of the trig2 scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number * @return trig2 scaler counter if successful, otherwise ERROR. */ unsigned int f1TestGetTrig2Counter(int id) { unsigned int reg=0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return ERROR; } F1LOCK; reg = vmeRead32(&f1p[id]->p0_trig2_scaler); F1UNLOCK; return reg; } /** * @ingroup DebugSW * @brief Reset the counter of the 250MHz Clock scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number */ void f1TestResetClockCounter(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } F1LOCK; vmeWrite32(&f1p[id]->clock_scaler,F1_CLOCK_SCALER_RESET); vmeWrite32(&f1p[id]->clock_scaler,F1_CLOCK_SCALER_START); F1UNLOCK; } /** * @ingroup DebugSW * @brief Reset the counter of the SyncReset scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number */ void f1TestResetSyncCounter(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } F1LOCK; vmeWrite32(&f1p[id]->p0_sync_scaler,F1_SYNC_SCALER_RESET); F1UNLOCK; } /** * @ingroup DebugSW * @brief Reset the counter of the trig1 scaler * * Available only in System Test Mode * * @sa f1TestSetSystemTestMode * @param id * - Slot Number */ void f1TestResetTrig1Counter(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } F1LOCK; vmeWrite32(&f1p[id]->p0_trig1_scaler,F1_TRIG1_SCALER_RESET); F1UNLOCK; } /** * @ingroup DebugSW * @brief Reset the counter of the trig2 scaler * * Available only in System Test Mode * * @param id * - Slot Number */ void f1TestResetTrig2Counter(int id) { if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n",__FUNCTION__, id); return; } F1LOCK; vmeWrite32(&f1p[id]->p0_trig2_scaler,F1_TRIG2_SCALER_RESET); F1UNLOCK; } /* Test routines */ /* Max words = 64 channels * 8 hits/chan + 8 headers + 1 trailer */ #define TEST_MAX_WORDS (64*8 + 9) int f1TestEventCount, f1TestClearCount, f1TestErrorCount; unsigned int f1TestData[TEST_MAX_WORDS]; void f1TestRead() { int ii, slot, retval, scanval; int maxwords=TEST_MAX_WORDS; int mask = 0; unsigned int errmask; unsigned int *data; maxwords = TEST_MAX_WORDS*nf1tdc; data = (unsigned int *) malloc((maxwords<<2)); bzero((char *)data,(maxwords<<2)); mask = f1ScanMask(); if(mask <=0) { printf("No TDCs available for Readout\n"); return; } else { printf("F1 TDC Mask = 0x%x\n",mask); printf("F1 DATA Buffer (%d bytes) at addr = 0x%x\n",(maxwords<<2), (int) data); } f1TestEventCount = 0; f1TestClearCount = 0; f1TestErrorCount = 0; f1GEnableSoftTrig(); while(1) { f1GTrig(); scanval = f1DataScan(0); if(scanval == mask) { f1TestEventCount++; retval = f1ReadBlock(f1MinSlot,data,maxwords,2); if(retval<=0) { printf("Error in reading data retval=%d\n address = 0x%x",retval,(int) data); return; } /* check Error Status */ errmask = f1GErrorStatus(1); if(errmask) { f1TestErrorCount++; for(ii=0;ii= maxwords) { /* Check who has the Token */ for(ii=0;ii>16; if(rev==2) mode = 1; factor = 2 - mode; if( data & 0x80000000 ) /* data type defining word */ { new_type = 1; data_type = (data & 0x78000000) >> 27; } else { new_type = 0; data_type = type_last; } switch( data_type ) { case 0: /* BLOCK HEADER */ slot_id_hd = (data & 0x7C00000) >> 22; blk_evts = (data & 0x3FF800) >> 11; blk_num = (data & 0x7FF); printf(" %08X - BLOCK HEADER - slot = %u blk_evts = %u n_blk = %u\n", data, slot_id_hd, blk_evts, blk_num); break; case 1: /* BLOCK TRAILER */ slot_id_tr = (data & 0x7C00000) >> 22; blk_words = (data & 0x3FFFFF); printf(" %08X - BLOCK TRAILER - slot = %u n_words = %u\n", data, slot_id_tr, blk_words); break; case 2: /* EVENT HEADER */ evt_num = (data & 0x7FFFFFF); printf(" %08X - EVENT HEADER - evt_num = %u\n", data, evt_num); break; case 3: /* TRIGGER TIME */ if( new_type ) { time_1 = (data & 0xFFFFFF); printf(" %08X - TRIGGER TIME 1 - time = %u\n", data, time_1); type_last = 3; } else { if( type_last == 3 ) { time_2 = (data & 0xFFFF); printf(" %08X - TRIGGER TIME 2 - time = %u\n", data, time_2); } else printf(" %08X - TRIGGER TIME - (ERROR)\n", data); } break; case 7: /* EVENT DATA */ printf("TDC = %08X ED ERR=%X chip=%u chan=%u t = %u (%u ps)\n", data, ((data >> 24) & 0x7), // ERR ((data >> 19) & 0x7), // chip ((data >> 16) & 0x7), // chan (data & 0xFFFF), // t ( (data & 0xFFFF) * 56 * factor )); break; case 8: /* CHIP HEADER */ /* need 2 prints - maximum # of variables is 7 in VxWorks printf (?) */ printf("TDC = %08X --CH-- (%X,%u) chip=%u chan=%u trig = %u t = %3u ", data, ((data >> 24) & 0x7), ((data >> 6) & 0x1), ((data >> 3) & 0x7), // chip (data & 0x7), //chan ((data >> 16) & 0x3F), // trig ((data >> 7) & 0x1FF)); // t printf("(%u ps) (P=%u)\n", ( ( (data >> 7) & 0x1FF) * 56 * factor * 128 ), ((data >> 6) & 0x1)); break; case 13: /* EVENT TRAILER */ /* need 2 prints - maximum # of variables is 7 in VxWorks printf (?) */ printf("TDC = %08X --ET-- (%08X,%u) chip=%u chan=%u trig = %u t = %3u ", data, ((data >> 24) & 0x7), ((data >> 6) & 0x1), ((data >> 3) & 0x7), (data & 0x7), ((data >> 16) & 0x3F), ((data >> 7) & 0x1FF)); printf("(%u ps) (P=%u)\n", ( ( (data >> 7) & 0x1FF) * 56 * factor * 128 ), ((data >> 6) & 0x1)); break; case 14: /* DATA NOT VALID (no data available) */ printf(" %08X - DATA NOT VALID = %u\n", data, data_type); break; case 15: /* FILLER WORD */ printf(" %08X - FILLER WORD = %u\n", data, data_type); break; case 4: /* UNDEFINED TYPE */ case 5: /* UNDEFINED TYPE */ case 6: /* UNDEFINED TYPE */ case 9: /* UNDEFINED TYPE */ case 10: /* UNDEFINED TYPE */ case 11: /* UNDEFINED TYPE */ case 12: /* UNDEFINED TYPE */ default: printf(" %08X - UNDEFINED TYPE = %u\n", data, data_type); break; } } /*****************************************************************************/ /*****************************************************************************/ /*S.P.start*/ int f1Id(unsigned int slot) { int id; for(id=0; id21) || (f1p[id] == NULL)) { printf("%s: ERROR : TDC in slot %d is not initialized \n", __FUNCTION__,id); return ERROR; } F1LOCK; rval = (vmeRead32(&f1p[id]->version) & F1_VERSION_BOARDREV_MASK)>>8; F1UNLOCK; if(pflag) printf("%s: Module Version = %d\n",__FUNCTION__,rval); return(rval); } void f1Mon(int slot, int sflag) { int jj; char bSN[10]; unsigned int a32Base, ambMin, ambMax; unsigned int version, b_rev, f_rev; unsigned int csr, ctrl, ctrl2, count, blevel, intr, addr32, addrMB; unsigned short chipstat[F1_MAX_TDC_CHIPS]; unsigned int cmask=0; unsigned int bcount=0, ramWords=0; unsigned int trig1Cnt=0, trig2Cnt=0, srCnt=0; unsigned long long int ch_mask; unsigned long long int ch_B_REV_MASK = 0xffffffff; if(slot==0) slot=f1ID[0]; if((slot<1) || (slot>21) || (f1p[slot] == NULL)) { printf("f1Status: ERROR : TDC in slot %d is not initialized \n",slot); return; } F1LOCK; version = vmeRead32(&f1p[slot]->version)&0xFFFF; csr = vmeRead32(&f1p[slot]->csr); ctrl = vmeRead32(&f1p[slot]->ctrl); ctrl2 = vmeRead32(&f1p[slot]->ctrl2); count = vmeRead32(&f1p[slot]->ev_count)&F1_EVENT_COUNT_MASK; blevel = vmeRead32(&f1p[slot]->blocklevel)&F1_BLOCKLEVEL_MASK; intr = vmeRead32(&f1p[slot]->intr); addr32 = vmeRead32(&f1p[slot]->adr32); a32Base = (addr32&F1_A32_ADDR_MASK)<<16; addrMB = vmeRead32(&f1p[slot]->adr_mb); ambMin = (addrMB&F1_AMB_MIN_MASK)<<16; ambMax = (addrMB&F1_AMB_MAX_MASK); bcount = vmeRead32(&f1p[slot]->block_count); ramWords = vmeRead32(&f1p[slot]->block_word_count_fifo); trig1Cnt = vmeRead32(&f1p[slot]->scaler1); trig2Cnt = vmeRead32(&f1p[slot]->trig2_scaler); srCnt = vmeRead32(&f1p[slot]->sync_scaler); F1UNLOCK; b_rev = (version & F1_VERSION_BOARDREV_MASK)>>8; f_rev = version & F1_VERSION_FIRMWARE_MASK; if(b_rev == 3) ch_B_REV_MASK = (unsigned long long)ch_B_REV_MASK<<16 | 0xffff; ch_mask = ~f1ChannelDisable[slot] & ch_B_REV_MASK; printf("\nf1TDC number %d in slot %d\n",f1Id(slot),slot); f1GetSerialNumber(slot, (char **)&bSN); printf(" Serial Number = %s\n", bSN); printf(" Module Version = %d\n", b_rev); printf(" Firmware Revision = 0x%02x\n", f_rev); printf(" Enable Channel Mask = 0x%llx\n", ch_mask); #ifdef VXWORKS printf(" Board at base address 0x%x \n",(UINT32) f1p[slot]); #else printf(" Board at VME (Local) base address 0x%x (0x%x) \n", (UINT32) f1p[slot] - f1tdcA24Offset, (UINT32) f1p[slot]); #endif if(sflag != 1) { if(addrMB&F1_AMB_ENABLE) { printf(" Alternate VME Addressing: Multiblock Enabled\n"); if(addr32&F1_A32_ENABLE) printf(" A32 Enabled at VME (Local) base 0x%08x (0x%08x)\n",a32Base,(UINT32) f1pd[slot]); else printf(" A32 Disabled\n"); printf(" Muliblock VME Address Range 0x%08x - 0x%08x\n",ambMin,ambMax); } else { printf(" Alternate VME Addressing: Multiblock Disabled\n"); if(addr32&F1_A32_ENABLE) printf(" A32 Enabled at VME (Local) base 0x%08x (0x%08x)\n",a32Base,(UINT32) f1pd[slot]); else printf(" A32 Disabled\n"); } if(ctrl&F1_INT_ENABLE) { printf("\n Interrupts ENABLED: "); printf(" VME INT Vector = 0x%x Level = %d\n",(intr&F1_INT_VEC_MASK),((intr&F1_INT_LEVEL_MASK)>>8)); } printf("\n Signal Sources: \n"); printf(" Ref Clock : "); if(ctrl&F1_REFCLK_SRC_INTERNALFP) { if(ctrl&F1_REFCLK_SRC_FP) printf("Front Panel\n"); else printf("Internal\n"); } else printf("VXS\n"); printf(" Trig Src : "); if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_P0) printf("VXS\n"); else if((ctrl&F1_TRIGGER_SRC_MASK)==F1_TRIGGER_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf(" Sync Reset: "); if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_P0) printf("VXS\n"); else if((ctrl&F1_SYNC_RESET_SRC_MASK)==F1_SYNC_RESET_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf(" Start : "); if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_FP) printf("Front Panel\n"); else if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_P0) printf("VXS\n"); else if((ctrl&F1_START_SRC_MASK)==F1_START_SRC_SOFT) printf("Software\n"); else printf("DISABLED\n"); printf("\n Configuration: \n"); if(ctrl&F1_REFCLK_INTERNAL_ENABLE) printf(" Internal Clock ON\n"); else printf(" Internal Clock OFF\n"); if(ctrl&F1_ENABLE_BERR) printf(" Bus Error ENABLED\n"); else printf(" Bus Error DISABLED\n"); printf(" MultiBlock transfer "); if(ctrl&F1_ENABLE_MULTIBLOCK) { int tP0, tP2; tP0 = ctrl&F1_MB_TOKEN_P0; tP2 = ctrl&F1_MB_TOKEN_P2; printf("ENABLED "); if(ctrl&F1_FIRST_BOARD) printf("(First Board "); else if(ctrl&F1_LAST_BOARD) printf("(Last Board "); else printf("( "); if(tP0 || tP2) { printf("token via "); if(tP0) printf("VXS"); if(tP2) printf("P2"); } printf(")\n"); } else { printf("DISABLED\n"); } printf("\n"); if(csr&F1_CSR_ERROR_MASK) { printf(" CSR Register = 0x%08x - Error Condition\n",csr); } else { printf(" CSR Register = 0x%08x \n",csr); } printf(" Control 1 Register = 0x%08x \n",ctrl); if(ctrl2&F1_GO_DATA) { printf(" Control 2 Register = 0x%08x - Enabled for triggers\n",ctrl2); } else { printf(" Control 2 Register = 0x%08x - Disabled\n",ctrl2); } printf(" Trigger Scaler = %d\n",trig1Cnt); printf(" Trigger 2 Scaler = %d\n",trig2Cnt); printf(" SyncReset Scaler = %d\n",srCnt); printf("\n"); if(csr&F1_CSR_BLOCK_READY) { printf(" Blocks in FIFO = %d (Block level = %d) - Block Available\n",bcount,blevel); printf(" RAM Level (Bytes) = %d \n",(ramWords*8)); } else if((csr&F1_CSR_MODULE_EMPTY)==F1_CSR_MODULE_EMPTY) printf(" Events in FIFO = %d (Block level = %d)\n",count,blevel); else { printf(" Events in FIFO = %d (Block level = %d) - Data Available\n",count,blevel); printf(" RAM Level (Bytes) = %d \n",(ramWords*8)); } /* Print out Chip Status */ f1ChipStatus(slot, 0); } else { /* Print minimal Error status of Chips on the TDC */ F1LOCK; for(jj=0;jjstat[jj]); if(((chipstat[jj]&F1_CHIP_RES_LOCKED)==0)||(chipstat[jj]&F1_CHIP_ERROR_COND)) cmask |= (1<21) || (f1p[id] == NULL)) { logMsg("f1ForceBlock: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return; } printf(" ---- FORCE BLOCK TRAILER INSERTION for F1TDC in SLOT %d ------- \n",id); F1LOCK; vmeWrite32(&f1p[id]->csr, F1_FORCE_TRAILER); csr = vmeRead32(&f1p[id]->csr); printf(" FORCE BLOCK TRAILER INSERTION Succesful %d \n",(csr>>22) & 0x3); printf(" CSR Register: 0x%x \n",csr); if(csr&F1_CSR_BLOCK_READY) printf(" Block Ready for Readout for board %d \n", id); else printf(" Block NOT Ready for Readout for board %d \n", id); F1UNLOCK; } // Swicth clock, added 8 Oct 2017 f1SetClkSource(int id, int source) { int clkSrc = 0; if(id==0) id=f1ID[0]; if((id<=0) || (id>21) || (f1p[id] == NULL)) { logMsg("f1SetClkSource: ERROR : TDC in slot %d is not initialized \n",id,0,0,0,0,0); return(ERROR); } switch(source) { case 0: /* Internal */ clkSrc = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_INTERNAL_ENABLE; break; case 1: /* Front Panel */ clkSrc = F1_REFCLK_SRC_INTERNALFP | F1_REFCLK_SRC_FP; break; case 2: /* VXS */ clkSrc = 0; break; default: printf("%s: Invalid Clock source (%d)\n", __FUNCTION__, source); return ERROR; } F1LOCK; vmeWrite32(&f1p[id]->ctrl, (vmeRead32(&f1p[id]->ctrl) & ~F1_REFCLK_SRC_MASK) | clkSrc); F1UNLOCK; return OK; }