/***************************************************************************** * * caen1190Lib.c - Driver library for readout of C.A.E.N. Model 1190 * TDC using a VxWorks 5.2 or later based Single Board computer. * * Author: David Abbott * Jefferson Lab Data Acquisition Group * August 2002 * * Revision 1.0 - Initial Revision * - Supports up to 20 CAEN Model 1190s in a Crate * - Programmed I/O reads * - Interrupts from a Single 1190 * * adjusted for CLAS by Sergey Boyarinov - May 2003-present * * Ported to Linux by Bryan Moffit - Jan 2010 * * - Linked List DMA supported * vxworks: requires modified tsi148 DMA library * */ #include #include #include #ifdef VXWORKS #include #include #include #include #include #include #else #include "jvme.h" #endif #include "c1190Lib.h" /* Prototype of Common Initialization of Modules */ STATUS tdc1190CommonInit(int itdc, UINT32 laddr); /* Macro to check id and c1190p */ #define CHECKID(id) { \ if((id<0) || (c1190p[id] == NULL)) { \ logMsg("%s: ERROR : TDC id %d not initialized \n", \ (int)__FUNCTION__,id,3,4,5,6); \ return ERROR; \ } \ if(use1190[id]==0) \ { \ logMsg("%s: TDC id %d flagged to NOT be used.\n", \ (int)__FUNCTION__,id,3,4,5,6); \ return ERROR; \ } \ } #ifdef VXWORKS /* Define external Functions */ IMPORT STATUS sysBusToLocalAdrs(int, char *, char **); IMPORT STATUS intDisconnect(int); IMPORT STATUS sysIntEnable(int); IMPORT STATUS sysIntDisable(int); #endif #ifdef VXWORKS #define EIEIO __asm__ volatile ("eieio") #define SynC __asm__ volatile ("sync") #else #define EIEIO #define SynC #endif /* Mutex to hold of reads and writes from competing threads */ pthread_mutex_t c1190_mutex = PTHREAD_MUTEX_INITIALIZER; #define LOCK_1190 { \ if(pthread_mutex_lock(&c1190_mutex)<0) \ perror("pthread_mutex_lock"); \ } #define UNLOCK_1190 { \ if(pthread_mutex_unlock(&c1190_mutex)<0) \ perror("pthread_mutex_unlock"); \ } /* Define global variables */ unsigned int tdcAddrOffset = 0; /* Difference in CPU (USERSPACE) Base */ int Nc1190 = 0; /* Number of TDCs in crate */ volatile struct v1190_struct *c1190p[V1190_MAX_MODULES]; /* pointers to TDC memory map */ int use1190[V1190_MAX_MODULES] = { /* Switch to turn on (1) or off (0) specific TDCs */ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0}; int vers1190[V1190_MAX_MODULES] = { /* The version of 1190/1290 (A=0 or N=2) */ 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0}; volatile struct v1190_struct *c1190MCSTp=NULL; /* pointer to TDC MCST memory map */ int tdcMaxSlot=-1; /* Highest element in use1190 hold an TDC */ int tdcMinSlot=-1; /* Lowest element in use1190 holding an TDC */ /* Define Interrupts variables */ BOOL c1190IntRunning = FALSE; /* running flag */ int c1190IntID = -1; /* id number of TDC generating interrupts */ LOCAL VOIDFUNCPTR c1190IntRoutine = NULL; /* user interrupt service routine */ LOCAL int c1190IntArg = 0; /* arg to user routine */ LOCAL int c1190IntEvCount = 0; /* Number of Events to generate Interrupt */ LOCAL UINT32 c1190IntLevel = V1190_VME_INT_LEVEL; /* default VME interrupt level */ LOCAL UINT32 c1190IntVec = V1190_INT_VEC; /* default interrupt Vector */ int c1190IntCount = 0; /* Count of interrupts from TDC */ /******************************************************************************* * * tdc1190Init - Initialize tdc1190 Library. * * * RETURNS: OK, or ERROR if the address is invalid or board is not present. */ STATUS tdc1190Init(UINT32 addr, UINT32 addr_inc, int ntdc, int iFlag) { int ii, res; unsigned int laddr; /* Check for valid address */ if(addr==0) { printf("tdc1190Init: ERROR: Must specify a Bus (VME-based A32/A24) address for TDC 0\n"); return(ERROR); } else if(addr < 0x00ffffff) { /* A24 Addressing */ if((addr_inc==0)||(ntdc==0)) ntdc = 1; /* assume only one TDC to initialize */ /* get the TDCs address */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190Init: ERROR in sysBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #else res = vmeBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190Init: ERROR in vmeBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #endif } /* A24 Addressing */ else { /* A32 Addressing */ if((addr_inc==0)||(ntdc==0)) ntdc = 1; /* assume only one TDC to initialize */ /* get the TDC address */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x09,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #else res = vmeBusToLocalAdrs(0x09,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190Init: ERROR in vmeBusToLocalAdrs(0x09,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #endif } /* A32 Addressing */ Nc1190 = 0; for (ii=0;iimoduleReset),1); vmeWrite16(&(c1190p[ii]->clear),1); } return OK; } /******************************************************************************* * * tdc1190InitList - Initialize tdc1190 Library for a "list" of modules * All modules must follow the same addressing scheme * (A24 or A32). The first module, in the list, must * be valid (addressable). * * RETURNS: OK, or ERROR if the address is invalid or board is not present. */ STATUS tdc1190InitList(UINT32 *addr_list, int ntdc, int iFlag) { int ii, res=0; UINT32 addr; unsigned int laddr; if(addr_list == NULL) { printf("tdc1190InitList: ERROR: Invalid addr_list\n"); return(ERROR); } if(ntdc<1 || ntdc>V1190_MAX_MODULES) { printf("tdc1190InitList: ERROR: Invalid ntdc specified %d\n",ntdc); return(ERROR); } /* Start with the first address in the list, determine A24/A32 */ addr = addr_list[0]; /* Check for valid address */ if(addr==0) { printf("tdc1190InitList: ERROR: Must specify a Bus (VME-based A32/A24) address for TDC 0\n"); return(ERROR); } else if(addr < 0x00ffffff) { /* A24 Addressing */ /* get the TDCs address */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190InitList: ERROR in sysBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #else res = vmeBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190InitList: ERROR in vmeBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #endif } /* A24 Addressing */ else { /* A32 Addressing */ /* get the TDC address */ #ifdef VXWORKS res = sysBusToLocalAdrs(0x09,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190InitList: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #else res = vmeBusToLocalAdrs(0x09,(char *)addr,(char **)&laddr); if (res != 0) { printf("tdc1190InitList: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",addr); return(ERROR); } tdcAddrOffset = (unsigned int)laddr-(unsigned int)addr; #endif } /* A32 Addressing */ Nc1190 = 0; /* Loop through the provided list checking for valid addresses */ for (ii=0;iimoduleReset),1); /* 'error' light here !!! */ vmeWrite16(&(c1190p[ii]->clear),1); } return OK; } /******************************************************************************* * * tdc1190CommonInit - Called by tdc1190Init or tdc1190InitList. * Initialization of individual modules, checking * for a valid VME address and BOARD_ID and * Firmware Version. * * RETURNS: OK, or ERROR if the address is invalid or board is not present. */ STATUS tdc1190CommonInit(int itdc, UINT32 laddr) { int res=0, errFlag = 0; unsigned short rdata=0; int boardID = 0; volatile struct v1190_ROM_struct *rp; c1190p[itdc] = (struct v1190_struct *)(laddr); /* Check if Board exists at that address */ #ifdef VXWORKS res = vxMemProbe((char *) &(c1190p[itdc]->firmwareRev),0,2,(char *)&rdata); #else res = vmeMemProbe((char *) &(c1190p[itdc]->firmwareRev),2,(char *)&rdata); #endif if(res < 0 ) /* if(res < 0 || rdata==0xffff) */ { printf("tdc1190CommonInit: ERROR: No addressable board at VME (Local) addr=0x%x (0x%x)\n", (UINT32) c1190p[itdc] - tdcAddrOffset, (UINT32) c1190p[itdc]); c1190p[itdc] = NULL; use1190[itdc] = 0; errFlag = 1; return ERROR; } else { /* Check if this is a Model 1190/1290 */ rp = (struct v1190_ROM_struct *)((UINT32)c1190p[itdc] + V1190_ROM_OFFSET); boardID = ((vmeRead16(&(rp->board2))&(0xff))<<16) + ((vmeRead16(&(rp->board1))&(0xff))<<8) + (vmeRead16(&(rp->board0))&(0xff)); if((boardID != V1190_BOARD_ID) && ((boardID & 0xffff) != V1290_BOARD_ID)) { printf("tdc1190CommonInit: ERROR: Board ID does not match: 0x%x \n",boardID); use1190[itdc] = 0; return ERROR; } /* Check if this is the firmware we expect > = V1190_FIRMWARE_REV */ if(rdata < V1190_FIRMWARE_REV) { printf("ERROR: Firmware not supported: 0x%08x (minimum required 0x%08x)\n", rdata,V1190_FIRMWARE_REV); use1190[itdc] = 0; return ERROR; } /* Keep track of the 1190/1290 type (A or N) */ vers1190[itdc] = vmeRead16(&rp->vers) & 0xFF; } use1190[itdc] = 1; Nc1190++; printf("Initialized TDC ID %2d (vers=0x%02x) at VME (Local) address 0x%08x (0x%08x)\n",itdc, vers1190[itdc], (UINT32) c1190p[itdc]-tdcAddrOffset,(UINT32) c1190p[itdc]); return OK; } UINT32 tdc1190ScanMask() { int itdc=0; UINT32 rval=0; for(itdc=0; itdcstatus))&V1190_STATUS_MASK; cntlReg = vmeRead16(&(c1190p[id]->control))&V1190_CONTROL_MASK; afullLevel = vmeRead16(&(c1190p[id]->almostFullLevel)); bltEvents = vmeRead16(&(c1190p[id]->bltEventNumber))&V1190_BLTEVNUM_MASK; iLvl = vmeRead16(&(c1190p[id]->intLevel))&V1190_INTLEVEL_MASK; iVec = vmeRead16(&(c1190p[id]->intVector))&V1190_INTVECTOR_MASK; evCount = vmeRead32(&(c1190p[id]->evCount))&V1190_EVCOUNT_MASK; evStored = vmeRead16(&(c1190p[id]->evStored)); mcstBaseAddr = vmeRead16(&c1190p[id]->mcstBaseAddr); mcstCtrl = vmeRead16(&c1190p[id]->mcstCtrl); UNLOCK_1190; drdy = statReg&V1190_STATUS_DATA_READY; afull = statReg&V1190_STATUS_ALMOST_FULL; bfull = statReg&V1190_STATUS_FULL; trigMatch = statReg&V1190_STATUS_TRIG_MATCH; headers = statReg&V1190_STATUS_HEADER_ENABLE; tdcerror[0] = (statReg&V1190_STATUS_ERROR_0)>>6; tdcerror[1] = (statReg&V1190_STATUS_ERROR_1)>>7; tdcerror[2] = (statReg&V1190_STATUS_ERROR_2)>>8; tdcerror[3] = (statReg&V1190_STATUS_ERROR_3)>>9; berr = cntlReg&V1190_BUSERROR_ENABLE; testmode = cntlReg&V1190_TESTMODE; /* print out status info */ printf("STATUS for v1x90 TDC at VME (Local) base address 0x%x (0x%x)\n", (UINT32)c1190p[id] - tdcAddrOffset, (UINT32)c1190p[id]); printf("---------------------------------------------- \n"); if(iLvl>0) { printf(" Interrupts Enabled - Request level = %d words\n",afullLevel); printf(" VME Interrupt Level: %d Vector: 0x%x \n",iLvl,iVec); } else { printf(" Interrupts Disabled\n"); } printf("\n"); printf(" Data Status \n"); printf(" Events to transfer via BLT = 0x%04x\n",bltEvents); if(bfull) { printf(" Status = 0x%04x (Buffer Full)\n",statReg); } else if(afull) { printf(" Status = 0x%04x (Almost Full)\n",statReg); }else if(drdy) { printf(" Status = 0x%04x (Data Ready )\n",statReg); }else { printf(" Status = 0x%04x (No Data)\n",statReg); } printf(" Events Stored = %d\n",evStored); if(evCount == 0xffff) printf(" Total Events = (No Events taken)\n"); else printf(" Total Events = %d\n",evCount); printf(" Almost Full = %d\n",afullLevel); printf("\n"); printf(" TDC Mode/Status \n"); res = tdc1190GetEdgeResolution(id); printf(" Resolution : %d ps\n",res); if(testmode) printf(" Test Mode : On\n"); if(trigMatch) printf(" Trigger Matching: On\n"); else printf(" Trigger Matching: Off\n"); if(headers) printf(" TDC Headers/EOB : On\n"); else printf(" TDC Headers/EOB : Off\n"); if(berr) printf(" Bus Errors : On\n"); else printf(" Bus Errors : Off\n"); printf(" TDC Errors : 0:%d 1:%d 2:%d 3:%d\n", tdcerror[0],tdcerror[1],tdcerror[2],tdcerror[3]); printf(" MCST/CBLT Base Address 0x%08x\n",mcstBaseAddr<<24); printf(" MCST/CBLT Control Reg 0x%08x\n",mcstCtrl); printf("\n"); return OK; } STATUS tdc1190GStatus(int mcFlag) { int itdc; TDC1190 st[V1190_MAX_MODULES+1]; unsigned int addr[V1190_MAX_MODULES+1]; /* 02xx */ UINT16 acq_mode[V1190_MAX_MODULES+1]; /* 16xx */ UINT16 trig_config[V1190_MAX_MODULES+1][5]; /* 23xx */ UINT16 edge_detection[V1190_MAX_MODULES+1]; /* 26xx */ UINT16 resolution[V1190_MAX_MODULES+1]; /* 29xx */ UINT16 doublehit_resolution[V1190_MAX_MODULES+1]; /* 32xx */ UINT16 tdc_headtrail_status[V1190_MAX_MODULES+1]; /* 34xx */ UINT16 maxhits[V1190_MAX_MODULES+1]; /* 3axx */ UINT16 errtype_enable[V1190_MAX_MODULES+1]; /* 3cxx */ UINT16 fifo_size[V1190_MAX_MODULES+1]; /* 45xx */ UINT32 chanenable_mask[V1190_MAX_MODULES+1]; LOCK_1190; for(itdc=0; itdccontrol); st[itdc].status = vmeRead16(&c1190p[itdc]->status); st[itdc].geoAddr = vmeRead16(&c1190p[itdc]->geoAddr); st[itdc].mcstBaseAddr = vmeRead16(&c1190p[itdc]->mcstBaseAddr); st[itdc].mcstCtrl = vmeRead16(&c1190p[itdc]->mcstCtrl); st[itdc].evCount = vmeRead32(&c1190p[itdc]->evCount); st[itdc].evStored = vmeRead16(&c1190p[itdc]->evStored); st[itdc].almostFullLevel = vmeRead16(&c1190p[itdc]->almostFullLevel); st[itdc].bltEventNumber = vmeRead16(&c1190p[itdc]->bltEventNumber); st[itdc].firmwareRev = vmeRead16(&c1190p[itdc]->firmwareRev); st[itdc].fifo_stored = vmeRead16(&c1190p[itdc]->fifo_stored); st[itdc].fifo_status = vmeRead16(&c1190p[itdc]->fifo_status); } UNLOCK_1190; if(mcFlag) { tdc1190GReadAcquisitionMode(acq_mode); tdc1190GReadTriggerConfiguration((UINT16 *)trig_config); tdc1190GReadEdgeDetectionConfig(edge_detection); tdc1190GGetEdgeResolution(resolution); tdc1190GGetDoubleHitResolution(doublehit_resolution); tdc1190GGetTDCHeaderAndTrailer(tdc_headtrail_status); tdc1190GGetMaxNumberOfHitsPerEvent(maxhits); tdc1190GGetTDCErrorType(errtype_enable); tdc1190GGetEffectiveSizeOfReadoutFIFO(fifo_size); tdc1190GGetChannels(chanenable_mask); } printf("\n"); /* Parameters from Registers */ printf(" CAEN1x90 TDC Module Configuration Summary\n\n"); printf(" Firmware TDC Error Status\n"); printf(" # GEO Revision Address CBLT/MCST Address 0 1 2 3\n"); printf("--------------------------------------------------------------------------------\n"); for(itdc=0; itdc>12)==0?800: ((st[itdc].status & 0x3000)>>12)==1?200: ((st[itdc].status & 0x3000)>>12)==2?100: ((st[itdc].status & 0x3000)>>12)==3?25:0); printf("%s ", (st[itdc].control & V1190_ALIGN64)?"ENABLED ":"disabled"); printf("%s ", (st[itdc].control & V1190_BUSERROR_ENABLE)?"ENABLED ":"disabled"); printf("%s ", (st[itdc].control & V1190_EVENT_FIFO_ENABLE)?"ENABLED ":"disabled"); printf("%s ", (st[itdc].control & V1190_EXT_TRIG_TIME_TAG_ENABLE)?"ENABLED ":"disabled"); printf("%s", (st[itdc].status & (1<<4))?"ENABLED ":"disabled"); printf("\n"); } printf("--------------------------------------------------------------------------------\n"); printf("\n"); printf(" Data Status\n\n"); printf(" Output Events -----Event FIFO---- Event\n"); printf(" # Buffer Stored Status Count Counter \n"); printf("--------------------------------------------------------------------------------\n"); for(itdc=0; itdc>2)==1?"FULL ": ((st[itdc].status & 0x2)>>1)==0?"Not Full ": ((st[itdc].status & 0x2)>>1)==1?"AlmostFull": ""); printf("%5d ",st[itdc].evStored); printf("%s ", ((st[itdc].fifo_status & 0x2)>>1)==1?"FULL ": ((st[itdc].fifo_status & 0x1)>>0)==1?"Data Ready": "Empty "); printf("%4d ",st[itdc].fifo_stored & 0x7ff); printf("%10d",st[itdc].evCount); printf("\n"); } printf("--------------------------------------------------------------------------------\n"); printf("\n"); if(mcFlag) { /* Parameters from MicroController */ printf("--------------------------------------------------------------------------------\n"); printf(" MicroController Parameters\n\n"); printf(" TriggerTime Edge Channel TDC Headers+\n"); printf(" # Mode Subtraction Detection Resolution Deadtime Trailers\n"); printf("--------------------------------------------------------------------------------\n"); for(itdc=0; itdcmicroHandshake)) & V1190_MICRO_READOK; if(kk > 10) { printf("-> ReadMicro: mstatus=%d (0x%x)\n",mstatus, vmeRead16(&(c1190p[id]->microHandshake))); } if(mstatus) { for(ii=0; iimicroHandshake)) & V1190_MICRO_READOK)) { jj++; if(jj>20) { logMsg("tdc1190ReadMicro: ERROR1: Read Status not OK (read %d)\n", ii,0,0,0,0,0); UNLOCK_1190; return(ERROR); } } data[ii] = vmeRead16(&(c1190p[id]->microReg)); } } else { kk++; if(kk>=20) { logMsg("tdc1190ReadMicro: ERROR2: Read Status not OK\n",0,0,0,0,0,0); UNLOCK_1190; return(ERROR); } else { taskDelay(10); goto retry; } } if(kk > 10) printf("-> ReadMicro: kk=%d\n",kk); UNLOCK_1190; return(OK); } STATUS tdc1190GReadMicro(UINT16 *data, int nwords_per_module) { int id=0, ntries=0, iword=0; volatile UINT32 mstatus=0; UINT32 scanmask=0; LOCK_1190; scanmask = tdc1190ScanMask(); while((mstatus!=scanmask) && (ntries<20)) { for(id=0; idmicroHandshake) & V1190_MICRO_READOK) mstatus |= 1<microHandshake)) & V1190_MICRO_READOK)) { ntries++; if(ntries>20) { logMsg("tdc1190GReadMicro: ERROR: Read Status from id=%d not OK (read %d)\n", id, iword,0,0,0,0); UNLOCK_1190; return(ERROR); } } data[iword+id*nwords_per_module] = vmeRead16(&(c1190p[id]->microReg)); } } } else { logMsg("tdc1190GReadMicro: ERROR2: Read Status not OK (0x%x != 0x%x)\n",mstatus,scanmask,0,0,0,0); UNLOCK_1190; return(ERROR); } if(ntries > 10) logMsg("tdc1190GReadMicro: ntries=%d\n",ntries,2,3,4,5,6); UNLOCK_1190; return(OK); } /******************************************************************************* * * tdc1190WriteMicro - Write to Microcontroller Register * * returns OK or ERROR */ STATUS tdc1190WriteMicro(int id, UINT16 data) { int kk=0; volatile UINT16 mstatus; CHECKID(id); LOCK_1190; retry: mstatus = vmeRead16(&(c1190p[id]->microHandshake)) & V1190_MICRO_WRITEOK; if(mstatus) { vmeWrite16(&(c1190p[id]->microReg),data); } else { kk++; mstatus=0; if(kk>=20) { logMsg("tdc1190WriteMicro: ERROR: Write Status not OK\n",0,0,0,0,0,0); UNLOCK_1190; return(ERROR); } else { taskDelay(10); goto retry; } } UNLOCK_1190; if(kk > 10) printf("-> WriteMicro: kk=%d\n",kk); return(OK); } STATUS tdc1190GWriteMicro(UINT16 data) { int id=0, ntries=0;; volatile UINT32 mstatus=0; UINT32 scanmask=0; LOCK_1190; scanmask = tdc1190ScanMask(); while((mstatus!=scanmask) || (ntries>=20)) { for(id=0; idmicroHandshake)) & V1190_MICRO_WRITEOK)?1:0)<microReg),data); } } else { logMsg("tdc1190GWriteMicro: ERROR: Write Status not OK (0x%x != 0x%x)\n",mstatus,scanmask,0,0,0,0); UNLOCK_1190; return(ERROR); } UNLOCK_1190; if(ntries > 10) logMsg("tdc1190GWriteMicro: ntries=%d\n",ntries); return(OK); } /******************************************************************************* * * tdc1190PrintEvent - Print an event from TDC to standard out. * * * RETURNS: Number of Data words read from the TDC (including Header/Trailer). */ int tdc1190PrintEvent(int id, int pflag) { int ii, jj, nWords, evID, bunchID, evCount, headFlag, trigMatch; UINT32 gheader, gtrailer, theader, ttrailer, tmpData, dCnt; int tdcID, chanID, dataVal, tEdge; int ntdc=4; /* Number of TDC chips. 'A' version = 4, 'N' version = 2 */ CHECKID(id); if(vers1190[id]==V1190_VERS_N) ntdc=2; LOCK_1190; /* Check if there is a valid event */ if(vmeRead16(&(c1190p[id]->status))&V1190_STATUS_DATA_READY) { dCnt = 0; headFlag = vmeRead16(&(c1190p[id]->status))&V1190_STATUS_HEADER_ENABLE; trigMatch = vmeRead16(&(c1190p[id]->status))&V1190_STATUS_TRIG_MATCH; if(trigMatch) { /* If trigger match mode then print individual event */ /* Read Global Header - Get event count */ gheader = vmeRead32(&(c1190p[id]->data[0])); if((gheader&V1190_DATA_TYPE_MASK) != V1190_GLOBAL_HEADER_DATA) { logMsg("tdc1190PrintEvent: ERROR: Invalid Global Header Word 0x%08x\n", gheader,2,3,4,5,6); UNLOCK_1190; return(ERROR); } else { logMsg(" TDC DATA for Module at address 0x%08x\n", (UINT32)c1190p[id]-tdcAddrOffset,2,3,4,5,6); evCount = (gheader&V1190_GHEAD_EVCOUNT_MASK)>>5; dCnt++; logMsg(" Global Header: 0x%08x Event Count = %d \n", gheader,evCount,3,4,5,6); } /* Loop over TDC chips and get data for each */ for(ii=0; iidata[0])); if((theader&V1190_DATA_TYPE_MASK) != V1190_TDC_HEADER_DATA) { logMsg("ERROR: Invalid TDC Header Word 0x%08x for TDC %d\n", theader,ii,3,4,5,6); UNLOCK_1190; return(ERROR); } else { evID = (theader&V1190_TDCHEAD_EVID_MASK)>>12; bunchID = (theader&V1190_TDCHEAD_BUNCHID_MASK); dCnt++; logMsg(" TDC %d Header: 0x%08x EventID = %d Bunch ID = %d ", ii,theader,evID,bunchID,5,6); } jj=0; tmpData = vmeRead32(&(c1190p[id]->data[0])); dCnt++; while((tmpData&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA) { /* if((jj % 5) == 0) printf("\n "); */ logMsg("ch %d: 0x%08x (0x%08x)\n", (tmpData&0x3e00000)>>21,(tmpData&0x1ffff), (tmpData),4,5,6); jj++; tmpData = vmeRead32(&(c1190p[id]->data[jj])); } /* reached EOB for TDC */ logMsg("\n",1,2,3,4,5,6); ttrailer = tmpData; if((ttrailer&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA) { logMsg("ERROR: Invalid TDC EOB Word 0x%08x for TDC %d\n", ttrailer,ii,3,4,5,6); UNLOCK_1190; return(ERROR); } else { nWords = (ttrailer&V1190_TDCEOB_WORDCOUNT_MASK); dCnt++; logMsg(" TDC %d EOB : 0x%08x Word Count = %d \n", ii,ttrailer,nWords,4,5,6); } } /* next data word should be Global EOB */ gtrailer = vmeRead32(&(c1190p[id]->data[dCnt])); if((gtrailer&V1190_DATA_TYPE_MASK) != V1190_GLOBAL_EOB_DATA) { logMsg("tdc1190PrintEvent: ERROR: Invalid Global EOB Word 0x%08x\n", gtrailer,2,3,4,5,6); UNLOCK_1190; return(ERROR); } else { nWords = (gtrailer&V1190_GEOB_WORDCOUNT_MASK)>>5; dCnt++; logMsg(" Global EOB : 0x%08x Total Word Count = %d \n", gtrailer,nWords,3,4,5,6); } } else /* Continuous Storage mode */ { tmpData = vmeRead32(&(c1190p[id]->data[dCnt])); logMsg(" TDC Continuous Storage DATA\n",1,2,3,4,5,6); while((tmpData&V1190_DATA_TYPE_MASK) != V1190_FILLER_DATA) { tdcID = (tmpData&V1190_TDC_MASK)>>24; chanID = (tmpData&V1190_CHANNEL_MASK)>>19; tEdge = (tmpData&V1190_EDGE_MASK)>>19; dataVal = (tmpData&V1190_DATA_MASK); logMsg(" %d %d %d %d\n",tdcID, chanID, tEdge, dataVal,5,6); dCnt++; tmpData = vmeRead32(&(c1190p[id]->data[dCnt])); } printf("\n"); } UNLOCK_1190; return(dCnt); } else { logMsg("tdc1190PrintEvent: No data available for readout!\n",1,2,3,4,5,6); UNLOCK_1190; return(0); } UNLOCK_1190; } /******************************************************************************* * * tdc1190StatusFull - Return the status of the Output Buffer Full register * * RETURNS: 1 if Full, 0 if Not Full, -1 if TDC is disabled * */ int tdc1190StatusFull(int id) { int res; CHECKID(id); if(use1190[id]==0) return -1; LOCK_1190; res = vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_FULL; UNLOCK_1190; return(res); } /******************************************************************************* * * tdc1190StatusAlmostFull - Return the status of the Output Buffer * Almost Full register * * RETURNS: 1 if Almost Full level is met, 0 if not, -1 if TDC is disabled * */ int tdc1190StatusAlmostFull(int id) { int res; CHECKID(id); if(use1190[id]==0) return -1; LOCK_1190; res = vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_ALMOST_FULL; UNLOCK_1190; return(res); } /****************************************************************************** * * tdc1190Dready - data readyness * * * RETURNS: 0(No Data) or the number of events */ int tdc1190Dready(int id) { UINT16 stat=0, nevents; CHECKID(id); if(use1190[id]==0) return ERROR; LOCK_1190; stat = vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_DATA_READY; if(stat) { nevents = vmeRead16(&(c1190p[id]->evStored)); UNLOCK_1190; return(nevents); } else { UNLOCK_1190; return(0); } } UINT32 tdc1190GDready(int blocklevel) { UINT32 rval=0; int id; LOCK_1190; for(id=0; idevStored))>=blocklevel) rval |= 1<1) { printf("tdc1190EventFifo: ERROR: Invalid flag = %d",flag); return ERROR; } LOCK_1190; if(flag == 1) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_EVENT_FIFO_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_EVENT_FIFO_ENABLE); UNLOCK_1190; return(0); } int tdc1190GEventFifo(UINT32 flag) { int itdc=0; if(flag>1) { printf("tdc1190GEventFifo: ERROR: Invalid flag = %d",flag); return ERROR; } LOCK_1190; for(itdc=0; itdccontrol), vmeRead16(&(c1190p[itdc]->control)) | V1190_EVENT_FIFO_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[itdc]->control), vmeRead16(&(c1190p[itdc]->control)) & ~V1190_EVENT_FIFO_ENABLE); } UNLOCK_1190; return(0); } /****************************************************************************** * * tdc1190ResetMSCT - Reset the MSCT/CBLT register * This effectively disables MSCT/CBLT * * * RETURNS: 0 if successful, ERROR otherwise. */ int tdc1190ResetMCST(int id) { CHECKID(id); if(use1190[id]==0) return ERROR; LOCK_1190; vmeWrite16(&(c1190p[id]->mcstCtrl),0); c1190MCSTp=NULL; UNLOCK_1190; return(0); } /****************************************************************************** * * tdc1190BusError - Enable/Disable Bus Errors (to finish a block transfer, * or on an empty buffer read) * flag = 0 : Disable * 1 : Enable * * RETURNS: 0 if successful, ERROR otherwise. */ int tdc1190BusError(int id, UINT32 flag) { CHECKID(id); if(use1190[id]==0) return ERROR; if(flag>1) { printf("%s: ERROR: Invalid flag = %d",__FUNCTION__,flag); return ERROR; } LOCK_1190; if(flag == 1) { printf("set BUSerror\n"); vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_BUSERROR_ENABLE); } else if(flag == 0) { printf("reset BUSerror\n"); vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_BUSERROR_ENABLE); } UNLOCK_1190; return(0); } int tdc1190GBusError(UINT32 flag) { int itdc=0; if(flag>1) { printf("tdc1190GEventFifo: ERROR: Invalid flag = %d",flag); return ERROR; } LOCK_1190; for(itdc=0; itdccontrol), vmeRead16(&(c1190p[itdc]->control)) | V1190_BUSERROR_ENABLE); } else if(flag == 0) { vmeWrite16(&(c1190p[itdc]->control), vmeRead16(&(c1190p[itdc]->control)) & ~V1190_BUSERROR_ENABLE); } } UNLOCK_1190; return(0); } /****************************************************************************** * * tdc1190Align64 - Enable/Disable 64 bit alignment for block transfers * flag = 0 : Disable * 1 : Enable * * RETURNS: 0 if successful, ERROR otherwise. */ int tdc1190Align64(int id, UINT32 flag) { CHECKID(id); if(use1190[id]==0) return ERROR; if(flag>1) { printf("%s: ERROR: Invalid flag = %d",__FUNCTION__,flag); return ERROR; } LOCK_1190; printf("tdc1190Align64 before: 0x%04x\n", vmeRead16(&(c1190p[id]->control))); if(flag == 1) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_ALIGN64); else if(flag == 0) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_ALIGN64); else printf("tdc1190Align64: unknown flag=%d\n",flag); printf("tdc1190Align64 after: 0x%04x\n", vmeRead16(&(c1190p[id]->control))); UNLOCK_1190; return(0); } int tdc1190GAlign64(UINT32 flag) { int itdc=0; if(flag>1) { printf("%s: ERROR: Invalid flag = %d",__FUNCTION__,flag); return ERROR; } LOCK_1190; for(itdc=0; itdccontrol), vmeRead16(&(c1190p[itdc]->control)) | V1190_ALIGN64); } else if(flag == 0) { vmeWrite16(&(c1190p[itdc]->control), vmeRead16(&(c1190p[itdc]->control)) & ~V1190_ALIGN64); } } UNLOCK_1190; return(0); } int tdc1190ConfigureGReadout(int choice) { switch(choice) { case 0: /* CBLT */ tdc1190GEventFifo(0); tdc1190GBusError(1); tdc1190GAlign64(1); break; case 1: /* LL-DMA */ default: tdc1190GEventFifo(1); tdc1190GBusError(0); tdc1190GAlign64(1); break; } return choice; } int tdc1190CBLTReadBlock(int id, volatile UINT32 *data, int nwrds, int rflag) { int stat, retVal, xferCount; int dummy=0; volatile unsigned int *laddr; unsigned int vmeAdr, csr; int nwrds_leftover=0; CHECKID(id); if(nwrds <= 0) nwrds= (V1190_MAX_WORDS_PER_BOARD*V1190_MAX_MODULES) + 10; if(c1190MCSTp==NULL) { logMsg("tdc1190CBLTReadBlock: ERROR: MCST/CBLT Address not initialized!\n", 1,2,3,4,5,6); return ERROR; } /* #define DEBUGCBLT */ LOCK_1190; /*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 0 FADC Dummy DATA)*/ if((unsigned long) (data)&0x7) { #ifdef VXWORKS *data = V1190_FILLER_DATA; #else *data = LSWAP(V1190_FILLER_DATA); #endif dummy = 1; laddr = (data + 1); xferCount = 1; } else { dummy = 0; laddr = data; xferCount = 0; } vmeAdr = (unsigned int)(c1190MCSTp) - (unsigned int)(tdcAddrOffset); int dmas=0; DMASTART: /* Here's our Start of the CBLT, in case it needs to be repeated */ dmas++; if(nwrds>(0x1000>>2)) { /* Limit the DMA Transfer to less than the readout space */ nwrds_leftover = nwrds-(0x1000>>2); nwrds = (0x1000>>2); #ifdef DEBUGCBLT printf("%s: May need retries. nwrds = %d nwrds_leftover = %d\n", __FUNCTION__, nwrds, nwrds_leftover); #endif } #ifdef DEBUGCBLT printf("%s: DMAs = %d\n",__FUNCTION__,dmas); #endif #ifdef VXWORKS retVal = sysVmeDmaSend((UINT32)laddr, vmeAdr, (nwrds<<2), 0); #else retVal = vmeDmaSend((UINT32)laddr, vmeAdr, (nwrds<<2)); #endif if(retVal != 0) { logMsg("tdc1190CBLTReadBlock: ERROR in DMA transfer Initialization 0x%x\n",retVal,0,0,0,0,0); UNLOCK_1190; return(retVal); } /* Wait until Done or Error */ #ifdef VXWORKS retVal = sysVmeDmaDone(10000,1); #else retVal = vmeDmaDone(); #endif /* Check to see that Bus error was generated by TDC */ csr = vmeRead16(&(c1190p[tdcMaxSlot]->status)); /* from Last TDC */ stat = (csr&V1190_STATUS_BERR_FLAG)>>10; /* from Last TDC */ if (retVal == 0) { /* Block Error finished without Bus Error */ #ifdef VXWORKS logMsg("tdc1190CBLTReadBlock: WARN: DMA transfer terminated by word count 0x%x stat=%d\n",nwrds,stat,0,0,0,0); UNLOCK_1190; return(nwrds); #else if((xferCount - dummy)==0) logMsg("tdc1190CBLTReadBlock: WARN: DMA transfer returned zero word count 0x%x stat=%d\n",nwrds,stat,0,0,0,0); UNLOCK_1190; return(xferCount); #endif } else if(retVal < 0) { /* Error in DMA */ #ifdef VXWORKS logMsg("tdc1190CBLTReadBlock: ERROR: sysVmeDmaDone returned an Error\n",0,0,0,0,0,0); #else logMsg("tdc1190CBLTReadBlock: ERROR: vmeDmaDone returned an Error\n",0,0,0,0,0,0); #endif UNLOCK_1190; return(retVal); } if(stat) { #ifdef VXWORKS xferCount += nwrds - (retVal>>2); /* Number of Longwords transfered */ #else xferCount += (retVal>>2); /* Number of Longwords transfered */ #endif UNLOCK_1190; #ifdef DEBUGCBLT printf("%s: Done. xferCount = %d nwrds = %d nwrds_leftover = %d\n", __FUNCTION__, xferCount, nwrds, nwrds_leftover); #endif return(xferCount); /* Return number of data words transfered */ } else { if(nwrds_leftover > 0) { /* Do it again to get the data left in the modules */ xferCount += nwrds; laddr += nwrds; nwrds = nwrds_leftover; #ifdef DEBUGCBLT printf("%s: Retry... nwrds = %d nwrds_leftover = %d\n", __FUNCTION__, nwrds, nwrds_leftover); #endif goto DMASTART; } #ifdef VXWORKS xferCount += nwrds - (retVal>>2); /* Number of Longwords transfered */ #else xferCount += (retVal>>2); /* Number of Longwords transfered */ #endif logMsg("tdc1190CBLTReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x xferCount=%d)\n",csr,xferCount,0,0,0,0); UNLOCK_1190; return(xferCount); } UNLOCK_1190; return(OK); } /************************************************************************************** * * tdc1190ReadBlock - General Data readout routine * * id - Slot number of module to read * data - local memory address to place data * nwrds - Max number of words to transfer * 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 - Linked-List DMA transfer (Linux: Linked-List system memory * must be setup prior) * - Must be compiled with WITHLL */ int tdc1190ReadBlock(int id, volatile UINT32 *data, int nwrds, int rflag) { int ii, jj; int stat, retVal, xferCount; int dCnt; int dummy=0; volatile unsigned int *laddr; unsigned int vmeAdr, csr; unsigned int vmeAdrLL[V1190_MAX_MODULES],dmaSizeLL[V1190_MAX_MODULES], destAdrLL[V1190_MAX_MODULES], numLL; unsigned int itdcbuf=0; unsigned int fifowords=0; unsigned int blocklevel=0, ievent=0; CHECKID(id); if(nwrds <= 0) nwrds= (V1190_MAX_WORDS_PER_BOARD*V1190_MAX_MODULES) + 10; blocklevel = (rflag&0xff00)>>8; rflag = rflag&0xf; LOCK_1190; 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 0 FADC Dummy DATA)*/ if((unsigned long) (data)&0x7) { #ifdef VXWORKS *data = V1190_FILLER_DATA; #else *data = LSWAP(V1190_FILLER_DATA); #endif dummy = 1; laddr = (data + 1); } else { dummy = 0; laddr = data; } if(rflag == 2) /* Linked-list Mode DMA */ { #ifdef WITHLL /* Setup the LL arrays */ jj=0; for(ii=0; iififo))&0xffff); } /* 128 bit alignment for 2eVME/2eSST */ if(fifowords%4) dmaSizeLL[jj] = (fifowords+(4-(fifowords%4)))<<2; else dmaSizeLL[jj] = fifowords<<2; destAdrLL[jj] = (unsigned int)&laddr[itdcbuf]; itdcbuf += dmaSizeLL[jj]; jj++; } } #ifdef DEBUGLL for(ii=0;ii 0) { /* Check to see that Bus error was generated by TDC */ if(rflag == 2) { csr = vmeRead16(&(c1190p[tdcMaxSlot]->status)); /* from Last TDC */ stat = (csr)&V1190_STATUS_BERR_FLAG; /* from Last TDC */ stat = 1; // No Bus Error for linked list mode. } else if (rflag == 1) { csr = vmeRead16(&(c1190p[id]->status)); stat = (csr)&V1190_STATUS_BERR_FLAG; } if((retVal>0) && (stat)) { #ifdef VXWORKS xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */ #else xferCount = (retVal>>2) + dummy; /* Number of Longwords transfered */ /* xferCount = (retVal + dummy); /\* Number of Longwords transfered *\/ */ #endif UNLOCK_1190; return(xferCount); /* Return number of data words transfered */ } else { #ifdef VXWORKS xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */ #else xferCount = (retVal>>2) + dummy; /* Number of Longwords transfered */ #endif logMsg("tdc1190ReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x xferCount=%d)\n",csr,xferCount,0,0,0,0); UNLOCK_1190; return(xferCount); /* return(ERROR); */ } } else if (retVal == 0) { /* Block Error finished without Bus Error */ #ifdef VXWORKS logMsg("tdc1190ReadBlock: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0); #else logMsg("tdc1190ReadBlock: WARN: DMA transfer returned zero word count 0x%x\n",nwrds,0,0,0,0,0); #endif UNLOCK_1190; return(nwrds); } else { /* Error in DMA */ #ifdef VXWORKS logMsg("tdc1190ReadBlock: ERROR: sysVmeDmaDone returned an Error\n",0,0,0,0,0,0); #else logMsg("tdc1190ReadBlock: ERROR: vmeDmaDone returned an Error\n",0,0,0,0,0,0); #endif UNLOCK_1190; return(retVal); } } else { /*Programmed IO */ /* Check if Bus Errors are enabled. If so then disable for Prog I/O reading */ // FIXME: Get rid of this? #ifdef BERR berr = vmeRead16(&(c1190p[id]->control))&V1190_BUSERROR_ENABLE; if(berr) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_BUSERROR_ENABLE); #endif UNLOCK_1190; /* will be locked again within tdc1190ReadData */ dCnt = tdc1190ReadData(id,(UINT32 *)data,nwrds); LOCK_1190; // FIXME: Get rid of this? #ifdef BERR if(berr) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_BUSERROR_ENABLE); #endif UNLOCK_1190; return(dCnt); } UNLOCK_1190; return(OK); } /******************************************************************************* * * tdc1190ReadEvent - Read event from TDC to specified address. * * // FIXME: May just remove this routine.. * * RETURNS: Number of Data words read from the TDC (including Header/Trailer). */ // FIXME: Make sure endian-ness is correct int tdc1190ReadEvent(int id, UINT32 *tdata) { /* int ii, nWords, evID; */ UINT32 header, trailer, dCnt, tmpData; UINT16 contReg, statReg; int fifodata; CHECKID(id); LOCK_1190; /* Check if there is a valid event */ if(vmeRead16(&(c1190p[id]->evStored))==0) { logMsg("tdc1190ReadEvent: Data Buffer is EMPTY!\n",0,0,0,0,0,0); UNLOCK_1190; return(0); } statReg = vmeRead16(&(c1190p[id]->status)); contReg = vmeRead16(&(c1190p[id]->control)); if(statReg & V1190_STATUS_DATA_READY) { dCnt = 0; /* Check to see if the Event FIFO is enabled, If so, read its register */ if(contReg & V1190_EVENT_FIFO_ENABLE) fifodata = vmeRead32(&(c1190p[id]->fifo)); /* Read Header */ header = vmeRead32(&(c1190p[id]->data[dCnt])); if((header&V1190_DATA_TYPE_MASK) != V1190_TDC_HEADER_DATA) { logMsg("tdc1190ReadEvent: ERROR: Invalid Header Word 0x%08x\n",header,0,0,0,0,0); UNLOCK_1190; return(-1); } else { tdata[dCnt] = header; dCnt++; tmpData = vmeRead32(&(c1190p[id]->data[0])); while((tmpData&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA ) { tdata[dCnt] = tmpData; dCnt++; tmpData = vmeRead32(&(c1190p[id]->data[0])); } } /* reached EOB for TDC */ trailer = tmpData; if((trailer&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA) { logMsg("tdc1190ReadEvent: ERROR: Invalid Trailer Word 0x%08x\n",trailer,0,0,0,0,0); UNLOCK_1190; return(-1); }else{ tdata[dCnt] = trailer; dCnt++; } UNLOCK_1190; return (dCnt); }else{ logMsg("tdc1190ReadEvent: Data Not ready for readout!\n",0,0,0,0,0,0); UNLOCK_1190; return(0); } } /****************************************************************************** * * tdc1190ReadData - available data into a buffer. * * * RETURNS: Number of Data words read from the TDC (including Header/Trailer). */ // FIXME: Make sure endian-ness is correct int tdc1190ReadData(int id, UINT32 *tdata, int maxWords) { int ii, jj, nWords, evID, bunchID, evCount, headFlag, trigMatch; UINT32 gheader, gtrailer, theader, ttrailer, tmpData, dCnt; int ntdc=4; /* Number of TDC chips. 'A' version = 4, 'N' version = 2 */ int gotMaxWords=0; CHECKID(id); if(vers1190[id]==V1190_VERS_N) ntdc=2; if(maxWords==0) maxWords = 1024; /* Check if there is a valid event */ LOCK_1190; if(vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_DATA_READY) { dCnt = 0; headFlag = vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_HEADER_ENABLE; trigMatch = vmeRead16(&(c1190p[id]->status)) & V1190_STATUS_TRIG_MATCH; if(trigMatch) /* If trigger match mode then read individual event */ { /* Read Global Header - Get event count */ gheader = vmeRead32(&(c1190p[id]->data[0])); if((gheader & V1190_DATA_TYPE_MASK) != V1190_GLOBAL_HEADER_DATA) { logMsg("tdc1190ReadData: ERROR: Invalid Global Header Word 0x%08x\n", gheader,2,3,4,5,6); UNLOCK_1190; return(ERROR); } else { #ifdef VXWORKS tdata[dCnt] = gheader; #else tdata[dCnt] = LSWAP(gheader); #endif evCount = (gheader & V1190_GHEAD_EVCOUNT_MASK) >> 5; dCnt++; } /* Loop over TDC chips and get data for each */ for(ii=0; iidata[0])); if((theader&V1190_DATA_TYPE_MASK) != V1190_TDC_HEADER_DATA) { logMsg("ERROR: Invalid TDC Header Word 0x%08x for TDC %d\n", theader,ii,3,4,5,6); UNLOCK_1190; return(ERROR); } else { #ifdef VXWORKS tdata[dCnt] = theader; #else tdata[dCnt] = LSWAP(theader); #endif evID = (theader&V1190_TDCHEAD_EVID_MASK)>>12; bunchID = (theader&V1190_TDCHEAD_BUNCHID_MASK); dCnt++; } jj=0; tmpData = vmeRead32(&(c1190p[id]->data[0])); while((tmpData&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA) { if(!gotMaxWords) { #ifdef VXWORKS tdata[dCnt] = tmpData; #else tdata[dCnt] = LSWAP(tmpData); #endif dCnt++; } jj++; tmpData = vmeRead32(&(c1190p[id]->data[jj])); /* Check for maxwords.. leave room for EOBs. Put out an error (only the first time) */ if( (dCnt-2 >= maxWords) && gotMaxWords==0) { gotMaxWords=1; logMsg("ERROR: More Data in module than specified maxWords (%d). Data potentially lost!\n", maxWords,2,3,4,5,6); } } /* reached EOB for TDC */ ttrailer = tmpData; if((ttrailer&V1190_DATA_TYPE_MASK) != V1190_TDC_EOB_DATA) { logMsg("ERROR: Invalid TDC EOB Word 0x%08x for TDC %d\n", ttrailer,ii,3,4,5,6); UNLOCK_1190; return(ERROR); } else { #ifdef VXWORKS tdata[dCnt] = ttrailer; #else tdata[dCnt] = LSWAP(ttrailer); #endif nWords = (ttrailer&V1190_TDCEOB_WORDCOUNT_MASK); dCnt++; } } /* next data word should be Global EOB */ gtrailer = vmeRead32(&(c1190p[id]->data[dCnt])); if((gtrailer&V1190_DATA_TYPE_MASK) != V1190_GLOBAL_EOB_DATA) { logMsg("tdc1190ReadData: ERROR: Invalid Global EOB Word 0x%08x\n", gtrailer,2,3,4,5,6); UNLOCK_1190; return(ERROR); } else { #ifdef VXWORKS tdata[dCnt] = gtrailer; #else tdata[dCnt] = LSWAP(gtrailer); #endif nWords = (gtrailer&V1190_GEOB_WORDCOUNT_MASK)>>5; dCnt++; } } else /* Continuous Storage mode */ { tmpData = vmeRead32(&(c1190p[id]->data[dCnt])); while(((tmpData&V1190_DATA_TYPE_MASK) != V1190_FILLER_DATA) && (dCntdata[dCnt])); } } UNLOCK_1190; return(dCnt); } else { logMsg("tdc1190ReadData: No data available for readout!\n",1,2,3,4,5,6); UNLOCK_1190; return(0); } } /****************************************************************************** * ACQUISITION MODE OPCODES Routines * * All routines return OK or ERROR, * unless otherwise specified. * * tdc1190SetTriggerMatchingMode * tdc1190SetContinuousStorageMode * tdc1190ReadAcquisitionMode - Returns 0: Continuous storage mode * 1: Trigger matching mode * tdc1190SetKeepToken * tdc1190ClearKeepToken * tdc1190LoadDefaultConfiguration * tdc1190SaveUserConfiguration * tdc1190LoadUserConfiguration * tdc1190SetAutoLoadUserConfiguration * tdc1190SetAutoLoadDefaultConfiguration * */ STATUS tdc1190SetTriggerMatchingMode(int id) { STATUS status; CHECKID(id); status = tdc1190WriteMicro(id,0x0000); tdc1190Clear(id); return status; } STATUS tdc1190GSetTriggerMatchingMode() { STATUS status; int itdc; status = tdc1190GWriteMicro(0x0000); for(itdc=0; itdc -800000ns * tdc1190SetExtraSearchMargin - Set window extra search margin [0,1250ns] * tdc1190SetRejectMargin - Set reject margin [0,1250ns] * tdc1190EnableTriggerTimeSubtraction * tdc1190DisableTriggerTimeSubtraction * tdc1190ReadTriggerConfiguration * */ STATUS tdc1190SetWindowWidth(int id, UINT32 window_width) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x1000); if(window_width < 25) tdata = 1; else if (window_width > 51175) tdata = 0x7FF; else tdata = window_width/25; printf("%s(%d): Set Window Width to %d ns\n",__FUNCTION__,id,tdata*25); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetWindowWidth(UINT32 window_width) { UINT16 tdata; tdc1190GWriteMicro(0x1000); if(window_width < 25) tdata = 1; else if (window_width > 51175) tdata = 0x7FF; else tdata = window_width/25; printf("%s: Set Window Width to %d ns\n",__FUNCTION__,tdata*25); return tdc1190GWriteMicro(tdata); } STATUS tdc1190SetWindowOffset(int id, INT32 window_offset) { INT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x1100); if(window_offset < -800000) tdata = -32000; else tdata = window_offset/25; printf("%s(%d): Set Window Offset to %d ns\n",__FUNCTION__,id,tdata*25); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetWindowOffset(INT32 window_offset) { INT16 tdata; tdc1190GWriteMicro(0x1100); if(window_offset < -800000) tdata = -32000; else tdata = window_offset/25; printf("%s: Set Window Offset to %d ns\n",__FUNCTION__,tdata*25); return tdc1190GWriteMicro(tdata); } STATUS tdc1190SetExtraSearchMargin(int id, UINT32 window_extra) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x1200); if(window_extra < 0) tdata = 0; else if (window_extra > 1250) tdata = 50; else tdata = window_extra/25; printf("%s(%d): Set Extra Search Margin to %d ns\n",__FUNCTION__,id,tdata*25); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetExtraSearchMargin(UINT32 window_extra) { UINT16 tdata; tdc1190GWriteMicro(0x1200); if(window_extra < 0) tdata = 0; else if (window_extra > 1250) tdata = 50; else tdata = window_extra/25; printf("%s: Set Extra Search Margin to %d ns\n",__FUNCTION__,tdata*25); return tdc1190GWriteMicro(tdata); } STATUS tdc1190SetRejectMargin(int id, UINT32 window_reject) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x1300); if(window_reject < 0) tdata = 0; else if (window_reject > 1250) tdata = 50; else tdata = window_reject/25; printf("%s(%d): Set Reject Margin to %d ns\n",__FUNCTION__,id,tdata*25); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetRejectMargin(UINT32 window_reject) { UINT16 tdata; tdc1190GWriteMicro(0x1300); if(window_reject < 0) tdata = 0; else if (window_reject > 1250) tdata = 50; else tdata = window_reject/25; printf("%s: Set Reject Margin to %d ns\n",__FUNCTION__,tdata*25); return tdc1190GWriteMicro(tdata); } STATUS tdc1190EnableTriggerTimeSubtraction(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x1400); } STATUS tdc1190GEnableTriggerTimeSubtraction() { return tdc1190GWriteMicro(0x1400); } STATUS tdc1190DisableTriggerTimeSubtraction(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x1500); } STATUS tdc1190GDisableTriggerTimeSubtraction() { return tdc1190GWriteMicro(0x1500); } STATUS tdc1190ReadTriggerConfiguration(int id) { UINT16 tmp[5] = {0,0,0,0,0}; CHECKID(id); EIEIO; SynC; tdc1190WriteMicro(id,0x1600); EIEIO; SynC; /* tdc1190ReadMicro(id,tmp,5); */ tdc1190ReadMicro(id,&tmp[0],1); tdc1190ReadMicro(id,&tmp[1],1); tdc1190ReadMicro(id,&tmp[2],1); tdc1190ReadMicro(id,&tmp[3],1); tdc1190ReadMicro(id,&tmp[4],1); EIEIO; SynC; printf("%s(%d):\n",__FUNCTION__,id); printf(" Window Width = %6d ns\n",tmp[0]*25); printf(" Window Offset = %6d ns\n",tmp[1]*25); printf(" Extra Seach Margin = %6d ns\n",tmp[2]*25); printf(" Reject Margin = %6d ns\n",tmp[3]*25); printf(" Trigger Time Subtraction = %6d\n",tmp[4]); return(OK); } STATUS tdc1190GReadTriggerConfiguration(UINT16 *trigcfg) { STATUS status; tdc1190GWriteMicro(0x1600); status = tdc1190GReadMicro(trigcfg,5); return(status); } /****************************************************************************** * EDGE DETECTION AND RESOLUTION OPCODES Routines * * All routines return OK or ERROR, * unless otherwise specified. * * tdc1190SetEdgeDetectionConfig * tdc1190ReadEdgeDetectionConfig - Returns: * 0 : Pair mode * 1 : Trailing Edge * 2 : Leading Edge * 3 : Both leading and trailing edge * tdc1190SetEdgeResolution * tdc1190GetEdgeResolution - Returns edge resolution (ns) * tdc1190SetPairResolution * tdc1190GetPairResolution - Returns 2nd and 3rd argument (ns) * tdc1190SetDoubleHitResolution * tdc1190GetDoubleHitResolution - Returns double hit resolution (ns) * */ STATUS tdc1190SetEdgeDetectionConfig(int id, UINT16 setedge) { UINT16 tdata=0; CHECKID(id); printf("%s(%d): ",__FUNCTION__,id); if(setedge==0) { tdata=0x0; printf("set pair mode\n"); } else if(setedge==1) { tdata=0x1; printf("set trailing edge only\n"); } else if(setedge==2) { tdata=0x2; printf("set leading edge only\n"); } else { printf("set both leading and trailing edges\n"); tdata=0x3; } tdc1190WriteMicro(id,0x2200); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetEdgeDetectionConfig(UINT16 setedge) { UINT16 tdata=0; printf("%s: ",__FUNCTION__); if(setedge==0) { tdata=0x0; printf("set pair mode\n"); } else if(setedge==1) { tdata=0x1; printf("set trailing edge only\n"); } else if(setedge==2) { tdata=0x2; printf("set leading edge only\n"); } else { printf("set both leading and trailing edges\n"); tdata=0x3; } tdc1190GWriteMicro(0x2200); return tdc1190GWriteMicro(tdata); } int tdc1190ReadEdgeDetectionConfig(int id) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x2300); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x3; if(tdata<3) { printf("%s(%d): Mode =",__FUNCTION__,id); if(tdata==0) printf(" pair mode\n"); else if(tdata==1) printf(" trailing edge\n"); else if(tdata==2) printf(" leading edge\n"); else if(tdata==3) printf(" both leading and trailing\n"); } else { printf("%s(%d) ERROR: tdata=%d (0x%x)\n",__FUNCTION__,id,tdata,tdata); return(ERROR); } return(tdata); } STATUS tdc1190GReadEdgeDetectionConfig(UINT16 *edgedetect) { STATUS status; tdc1190GWriteMicro(0x2300); status = tdc1190GReadMicro(edgedetect,1); return status; } STATUS tdc1190SetEdgeResolution(int id, UINT16 edge_res) { UINT16 tdata; CHECKID(id); if(edge_res==800) tdata = 0; else if(edge_res==200) tdata = 1; else if(edge_res==100) tdata = 2; else if(edge_res==25) tdata = 3; else { printf("%s(%d): ERROR: Invalid edge_res=%d, must be 25, 100, 200 or 800 ps\n", __FUNCTION__,id,edge_res); return(ERROR); } tdc1190WriteMicro(id,0x2400); tdc1190WriteMicro(id,tdata); printf("%s(%d): Set Edge Resolution to %d ps\n",__FUNCTION__,id,edge_res); return(OK); } STATUS tdc1190GSetEdgeResolution(UINT16 edge_res) { UINT16 tdata; if(edge_res==800) tdata = 0; else if(edge_res==200) tdata = 1; else if(edge_res==100) tdata = 2; else if(edge_res==25) tdata = 3; else { printf("%s: ERROR: Invalid edge_res=%d, must be 25, 100, 200 or 800 ps\n", __FUNCTION__,edge_res); return(ERROR); } tdc1190GWriteMicro(0x2400); printf("%s: Set Edge Resolution to %d ps\n",__FUNCTION__,edge_res); tdc1190GWriteMicro(tdata); return(OK); } int tdc1190GetEdgeResolution(int id) { UINT16 tdata=0; int rval; CHECKID(id); tdc1190WriteMicro(id,0x2600); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x3; if(tdata==0) rval = 800; else if(tdata==1) rval = 200; else if(tdata==2) rval = 100; else { printf("%s(%d): ERROR: tdata=%d (0x%x)\n",__FUNCTION__,id,tdata,tdata); return(ERROR); } return(rval); } STATUS tdc1190GGetEdgeResolution(UINT16 *res) { STATUS status; tdc1190GWriteMicro(0x2600); status = tdc1190GReadMicro(res,1); return status; } STATUS tdc1190SetPairResolution(int id, UINT32 leading_res, UINT32 pulse_width_res) { UINT16 tdata; CHECKID(id); if(leading_res==100) tdata = 0x0; else if(leading_res==200) tdata = 0x1; else if(leading_res==400) tdata = 0x2; else if(leading_res==800) tdata = 0x3; else if(leading_res==1600) tdata = 0x4; else if(leading_res==3120) tdata = 0x5; else if(leading_res==6250) tdata = 0x6; else if(leading_res==12500) tdata = 0x7; else { printf("%s(%d): ERROR: Invalid leading_res=%d\n",__FUNCTION__,id, leading_res); return(ERROR); } if(pulse_width_res==100) tdata += 0x0; else if(pulse_width_res==200) tdata += 0x100; else if(pulse_width_res==400) tdata += 0x200; else if(pulse_width_res==800) tdata += 0x300; else if(pulse_width_res==1600) tdata += 0x400; else if(pulse_width_res==3200) tdata += 0x500; else if(pulse_width_res==6250) tdata += 0x600; else if(pulse_width_res==12500) tdata += 0x700; else if(pulse_width_res==25000) tdata += 0x800; else if(pulse_width_res==50000) tdata += 0x900; else if(pulse_width_res==100000) tdata += 0xA00; else if(pulse_width_res==200000) tdata += 0xB00; else if(pulse_width_res==400000) tdata += 0xC00; else if(pulse_width_res==800000) tdata += 0xD00; else { printf("%s(%d): ERROR: Invalid pulse_width_res=%d\n",__FUNCTION__,id, pulse_width_res); return(ERROR); } tdc1190WriteMicro(id,0x2500); tdc1190WriteMicro(id,tdata); printf("%s(%d): Set Pair Resolution to %d(leading time), %d(width) ps\n", __FUNCTION__,id,leading_res,pulse_width_res); return(OK); } STATUS tdc1190GSetPairResolution(UINT32 leading_res, UINT32 pulse_width_res) { UINT16 tdata; if(leading_res==100) tdata = 0x0; else if(leading_res==200) tdata = 0x1; else if(leading_res==400) tdata = 0x2; else if(leading_res==800) tdata = 0x3; else if(leading_res==1600) tdata = 0x4; else if(leading_res==3120) tdata = 0x5; else if(leading_res==6250) tdata = 0x6; else if(leading_res==12500) tdata = 0x7; else { printf("%s: ERROR: Invalid leading_res=%d\n",__FUNCTION__, leading_res); return(ERROR); } if(pulse_width_res==100) tdata += 0x0; else if(pulse_width_res==200) tdata += 0x100; else if(pulse_width_res==400) tdata += 0x200; else if(pulse_width_res==800) tdata += 0x300; else if(pulse_width_res==1600) tdata += 0x400; else if(pulse_width_res==3200) tdata += 0x500; else if(pulse_width_res==6250) tdata += 0x600; else if(pulse_width_res==12500) tdata += 0x700; else if(pulse_width_res==25000) tdata += 0x800; else if(pulse_width_res==50000) tdata += 0x900; else if(pulse_width_res==100000) tdata += 0xA00; else if(pulse_width_res==200000) tdata += 0xB00; else if(pulse_width_res==400000) tdata += 0xC00; else if(pulse_width_res==800000) tdata += 0xD00; else { printf("%s: ERROR: Invalid pulse_width_res=%d\n",__FUNCTION__, pulse_width_res); return(ERROR); } tdc1190GWriteMicro(0x2500); printf("%s: Set Pair Resolution to %d(leading time), %d(width) ps\n", __FUNCTION__,leading_res,pulse_width_res); tdc1190GWriteMicro(tdata); return(OK); } STATUS tdc1190GetPairResolution(int id, UINT32 *leading_res, UINT32 *pulse_width_res) { UINT16 tdata, tdata1, tdata2; CHECKID(id); tdc1190WriteMicro(id,0x2600); tdc1190ReadMicro(id,&tdata,1); tdata1 = tdata & 0x7; if(tdata1 == 0x0) *leading_res = 100; else if(tdata1 == 0x1) *leading_res = 200; else if(tdata1 == 0x2) *leading_res = 400; else if(tdata1 == 0x3) *leading_res = 800; else if(tdata1 == 0x4) *leading_res = 1600; else if(tdata1 == 0x5) *leading_res = 3120; else if(tdata1 == 0x6) *leading_res = 6250; else if(tdata1 == 0x7) *leading_res = 12500; else { printf("ERROR: GetPairResolution: tdata1=%d\n",tdata1); return(ERROR); } tdata2 = tdata & 0xF00; if(tdata2 == 0x0) *pulse_width_res = 100; else if(tdata2 == 0x100) *pulse_width_res = 200; else if(tdata2 == 0x200) *pulse_width_res = 400; else if(tdata2 == 0x300) *pulse_width_res = 800; else if(tdata2 == 0x400) *pulse_width_res = 1600; else if(tdata2 == 0x500) *pulse_width_res = 3200; else if(tdata2 == 0x600) *pulse_width_res = 6250; else if(tdata2 == 0x700) *pulse_width_res = 12500; else if(tdata2 == 0x800) *pulse_width_res = 25000; else if(tdata2 == 0x900) *pulse_width_res = 50000; else if(tdata2 == 0xA00) *pulse_width_res = 100000; else if(tdata2 == 0xB00) *pulse_width_res = 200000; else if(tdata2 == 0xC00) *pulse_width_res = 400000; else if(tdata2 == 0xD00) *pulse_width_res = 800000; else { printf("ERROR: GetPairResolution: tdata2=%d\n",tdata2); return(ERROR); } printf("Pair Resolution is %d(leading time), %d(width) ps\n",*leading_res,*pulse_width_res); return(OK); } STATUS tdc1190GGetPairResolution(UINT16 *pair_res) { STATUS status; tdc1190GWriteMicro(0x2600); status = tdc1190GReadMicro(pair_res,1); return status; } STATUS tdc1190SetDoubleHitResolution(int id, UINT16 doublehit_res) { UINT16 tdata; CHECKID(id); if(doublehit_res==5) tdata = 0; else if(doublehit_res==10) tdata = 1; else if(doublehit_res==30) tdata = 2; else if(doublehit_res==100) tdata = 3; else { printf("%s(%d): ERROR: Invalid doublehit_res=%d, must be 5, 10, 30 or 100 ns\n", __FUNCTION__,id,doublehit_res); return(ERROR); } tdc1190WriteMicro(id,0x2800); tdc1190WriteMicro(id,tdata); printf("%s(%d): Set Double Hit Resolution to %d ns\n",__FUNCTION__,id,doublehit_res); return(OK); } STATUS tdc1190GSetDoubleHitResolution(UINT16 doublehit_res) { UINT16 tdata; if(doublehit_res==5) tdata = 0; else if(doublehit_res==10) tdata = 1; else if(doublehit_res==30) tdata = 2; else if(doublehit_res==100) tdata = 3; else { printf("%s: ERROR: Invalid doublehit_res=%d, must be 5, 10, 30 or 100 ns\n", __FUNCTION__,doublehit_res); return(ERROR); } tdc1190GWriteMicro(0x2800); printf("%s: Set Double Hit Resolution to %d ns\n",__FUNCTION__,doublehit_res); tdc1190GWriteMicro(tdata); return(OK); } int tdc1190GetDoubleHitResolution(int id) { UINT16 tdata; int rval; CHECKID(id); tdc1190WriteMicro(id,0x2900); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x3; if(tdata==0) rval = 5; else if(tdata==1) rval = 10; else if(tdata==2) rval = 30; else if(tdata==3) rval = 100; else { printf("%s(%d): ERROR: tdata=%d (0x%x)\n",__FUNCTION__,id,tdata,tdata); return(ERROR); } printf("w%s(%d): Double Hit Resolution is %d ns\n",__FUNCTION__,id,rval); return(rval); } STATUS tdc1190GGetDoubleHitResolution(UINT16 *double_res) { STATUS status; tdc1190GWriteMicro(0x2900); status = tdc1190GReadMicro(double_res,1); return status; } /****************************************************************************** * TDC READOUT OPCODES Routines * * All routines return OK or ERROR, * unless otherwise specified. * * tdc1190EnableTDCHeaderAndTrailer * tdc1190DisableTDCHeaderAndTrailer * tdc1190GetTDCHeaderAndTrailer - Returns * 0 : header/trailer disabled * 1 : header/trailer enabled * tdc1190SetMaxNumberOfHitsPerEvent * tdc1190GetMaxNumberOfHitsPerEvent - Returns maximum number of hits/event * tdc1190EnableTDCErrorMark * tdc1190DisableTDCErrorMark * tdc1190EnableTDCErrorBypass * tdc1190DisableTDCErrorBypass * tdc1190SetTDCErrorType * tdc1190GetTDCErrorType - Returns mask of enabled error types * tdc1190SetEffectiveSizeOfReadoutFIFO * tdc1190GetEffectiveSizeOfReadoutFIFO - Returns number of words in readout FIFO * */ STATUS tdc1190EnableTDCHeaderAndTrailer(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3000); } STATUS tdc1190GEnableTDCHeaderAndTrailer() { return tdc1190GWriteMicro(0x3000); } STATUS tdc1190DisableTDCHeaderAndTrailer(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3100); } STATUS tdc1190GDisableTDCHeaderAndTrailer() { return tdc1190GWriteMicro(0x3100); } int tdc1190GetTDCHeaderAndTrailer(int id) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x3200); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x1; if(tdata==0) printf("%s(%d): TDC Header/Trailer disabled\n",__FUNCTION__,id); else if(tdata==1) printf("%s(%d): TDC Header/Trailer enabled\n",__FUNCTION__,id); return(tdata); } STATUS tdc1190GGetTDCHeaderAndTrailer(UINT16 *headtrl) { STATUS status; tdc1190GWriteMicro(0x3200); status = tdc1190GReadMicro(headtrl,1); return status; } STATUS tdc1190SetMaxNumberOfHitsPerEvent(int id, UINT32 nhits) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x3300); if(nhits==0) tdata = 0; else if(nhits==1) tdata = 1; else if(nhits==2) tdata = 2; else if(nhits==4) tdata = 3; else if(nhits==8) tdata = 4; else if(nhits==16) tdata = 5; else if(nhits==32) tdata = 6; else if(nhits==64) tdata = 7; else if(nhits==128) tdata = 8; else tdata = 9; if(tdata==9) printf("%s(%d): Set Unlimited Number Of Hits Per Event\n",__FUNCTION__,id); else printf("%s(%d): Set Maximum Number Of Hits Per Event to %d\n",__FUNCTION__,id,nhits); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetMaxNumberOfHitsPerEvent(UINT32 nhits) { UINT16 tdata; tdc1190GWriteMicro(0x3300); if(nhits==0) tdata = 0; else if(nhits==1) tdata = 1; else if(nhits==2) tdata = 2; else if(nhits==4) tdata = 3; else if(nhits==8) tdata = 4; else if(nhits==16) tdata = 5; else if(nhits==32) tdata = 6; else if(nhits==64) tdata = 7; else if(nhits==128) tdata = 8; else tdata = 9; if(tdata==9) printf("%s: Set Unlimited Number Of Hits Per Event\n",__FUNCTION__); else printf("%s: Set Maximum Number Of Hits Per Event to %d\n",__FUNCTION__,nhits); return tdc1190GWriteMicro(tdata); } int tdc1190GetMaxNumberOfHitsPerEvent(int id) { UINT16 tdata; int rval; CHECKID(id); tdc1190WriteMicro(id,0x3400); tdc1190ReadMicro(id,&tdata,1); tdata &= 0xF; if(tdata==0) rval = 0; else if(tdata==1) rval = 1; else if(tdata==2) rval = 2; else if(tdata==3) rval = 4; else if(tdata==4) rval = 8; else if(tdata==5) rval = 16; else if(tdata==6) rval = 32; else if(tdata==7) rval = 64; else if(tdata==8) rval = 128; else if(tdata==9) rval = 9999; else { printf("%s(%d): ERROR: tdata=%d (0x%x)\n",__FUNCTION__,id,tdata,tdata); return(ERROR); } return(rval); } STATUS tdc1190GGetMaxNumberOfHitsPerEvent(UINT16 *maxhits) { STATUS status; tdc1190GWriteMicro(0x3400); status = tdc1190GReadMicro(maxhits,1); return status; } STATUS tdc1190EnableTDCErrorMark(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3500); } STATUS tdc1190GEnableTDCErrorMark() { return tdc1190GWriteMicro(0x3500); } STATUS tdc1190DisableTDCErrorMark(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3600); } STATUS tdc1190GDisableTDCErrorMark() { return tdc1190GWriteMicro(0x3600); } STATUS tdc1190EnableTDCErrorBypass(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3700); } STATUS tdc1190GEnableTDCErrorBypass() { return tdc1190GWriteMicro(0x3700); } STATUS tdc1190DisableTDCErrorBypass(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x3800); } STATUS tdc1190GDisableTDCErrorBypass() { return tdc1190GWriteMicro(0x3800); } STATUS tdc1190SetTDCErrorType(int id, UINT32 mask) { UINT16 tdata; CHECKID(id); tdata = mask & 0x7FF; tdc1190WriteMicro(id,0x3900); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetTDCErrorType(UINT32 mask) { UINT16 tdata; tdata = mask & 0x7FF; tdc1190GWriteMicro(0x3900); return tdc1190GWriteMicro(tdata); } int tdc1190GetTDCErrorType(int id) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x3A00); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x7FF; if(tdata & 0x1) printf("%s(%d): Vernier error\n",__FUNCTION__,id); else if(tdata & 0x2) printf("%s(%d): Coarse error\n",__FUNCTION__,id); else if(tdata & 0x4) printf("%s(%d): Channel select error\n",__FUNCTION__,id); else if(tdata & 0x8) printf("%s(%d): L1 buffer parity error\n",__FUNCTION__,id); else if(tdata & 0x10) printf("%s(%d): Trigger fifo parity error\n",__FUNCTION__,id); else if(tdata & 0x20) printf("%s(%d): Trigger matching error\n",__FUNCTION__,id); else if(tdata & 0x40) printf("%s(%d): Readout fifo parity error\n",__FUNCTION__,id); else if(tdata & 0x80) printf("%s(%d): Readout state error\n",__FUNCTION__,id); else if(tdata & 0x100) printf("%s(%d): Set up parity error\n",__FUNCTION__,id); else if(tdata & 0x200) printf("%s(%d): Control parity error\n",__FUNCTION__,id); else if(tdata & 0x400) printf("%s(%d): Jtag instruction parity error\n",__FUNCTION__,id); return(tdata); } STATUS tdc1190GGetTDCErrorType(UINT16 *errortype) { STATUS status; tdc1190GWriteMicro(0x3A00); status = tdc1190GReadMicro(errortype,1); return status; } STATUS tdc1190SetEffectiveSizeOfReadoutFIFO(int id, UINT32 nwords) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x3B00); if(nwords==2) tdata = 0; else if(nwords==4) tdata = 1; else if(nwords==8) tdata = 2; else if(nwords==16) tdata = 3; else if(nwords==32) tdata = 4; else if(nwords==64) tdata = 5; else if(nwords==128) tdata = 6; else if(nwords==256) tdata = 7; else tdata = 7; printf("%s(%d): Set Effective Size Of Readout FIFO to %d\n",__FUNCTION__,id,nwords); return tdc1190WriteMicro(id,tdata); } STATUS tdc1190GSetEffectiveSizeOfReadoutFIFO(UINT32 nwords) { UINT16 tdata; tdc1190GWriteMicro(0x3B00); if(nwords==2) tdata = 0; else if(nwords==4) tdata = 1; else if(nwords==8) tdata = 2; else if(nwords==16) tdata = 3; else if(nwords==32) tdata = 4; else if(nwords==64) tdata = 5; else if(nwords==128) tdata = 6; else if(nwords==256) tdata = 7; else tdata = 7; printf("%s: Set Effective Size Of Readout FIFO to %d\n",__FUNCTION__,nwords); return tdc1190GWriteMicro(tdata); } int tdc1190GetEffectiveSizeOfReadoutFIFO(int id) { UINT16 tdata; CHECKID(id); tdc1190WriteMicro(id,0x3C00); tdc1190ReadMicro(id,&tdata,1); tdata &= 0x7; if(tdata==0) printf("%s(%d): 2 words\n",__FUNCTION__,id); else if(tdata==1) printf("%s(%d): 4 words\n",__FUNCTION__,id); else if(tdata==2) printf("%s(%d): 8 words\n",__FUNCTION__,id); else if(tdata==3) printf("%s(%d): 16 words\n",__FUNCTION__,id); else if(tdata==4) printf("%s(%d): 32 words\n",__FUNCTION__,id); else if(tdata==5) printf("%s(%d): 64 words\n",__FUNCTION__,id); else if(tdata==6) printf("%s(%d): 128 words\n",__FUNCTION__,id); else if(tdata==7) printf("%s(%d): 256 words\n",__FUNCTION__,id); return(tdata); } STATUS tdc1190GGetEffectiveSizeOfReadoutFIFO(UINT16 *fifosize) { STATUS status; tdc1190GWriteMicro(0x3C00); status = tdc1190GReadMicro(fifosize,1); return status; } /****************************************************************************** * CHANNEL ENABLE OPCODES Routines * * All routines return OK or ERROR, * unless otherwise specified. * * tdc1190EnableChannel * tdc1190DisableChannel * tdc1190EnableAllChannels * tdc1190DisableAllChannels * tdc1190EnableChannels * tdc1190GetChannels - Returns mask of enabled channels * */ STATUS tdc1190EnableChannel(int id, UINT16 channel) { int opcode = 0x4000 + (channel & 0x7F); CHECKID(id); return tdc1190WriteMicro(id,opcode); } STATUS tdc1190DisableChannel(int id, UINT16 channel) { int opcode = 0x4100 + (channel & 0x7F); CHECKID(id); return tdc1190WriteMicro(id,opcode); } STATUS tdc1190EnableAllChannels(int id) { CHECKID(id); return tdc1190WriteMicro(id,0x4200); } STATUS tdc1190GEnableAllChannels() { return tdc1190GWriteMicro(0x4200); } STATUS tdc1190DisableAllChannels(int id) { CHECKID(id); tdc1190WriteMicro(id,0x4300); return(OK); } STATUS tdc1190GDisableAllChannels() { return tdc1190GWriteMicro(0x4300); } STATUS tdc1190EnableChannels(int id, UINT32 channel_mask) { CHECKID(id); tdc1190WriteMicro(id,0x4400); tdc1190WriteMicro(id,channel_mask&0xffff); tdc1190WriteMicro(id,(channel_mask&0xffff0000)>>16); return(OK); } STATUS tdc1190GEnableChannels(UINT32 channel_mask) { tdc1190GWriteMicro(0x4400); tdc1190GWriteMicro(channel_mask&0xffff); tdc1190GWriteMicro((channel_mask&0xffff0000)>>16); return(OK); } int tdc1190GetChannels(int id) { int rval; UINT16 read1, read2; CHECKID(id); tdc1190WriteMicro(id,0x4500); tdc1190ReadMicro(id,&read1,1); tdc1190ReadMicro(id,&read2,1); rval = (read1) | (read2<<16); return(rval); } STATUS tdc1190GGetChannels(UINT32 *chanenable_mask) { STATUS status; UINT16 read[V1190_MAX_MODULES+1][2]; int itdc; tdc1190GWriteMicro(0x4500); status = tdc1190GReadMicro((UINT16 *)read,2); for(itdc=0; itdc>24) & 0xFF; #ifdef VXWORKS res = sysBusToLocalAdrs(0x09,(char *)(baseadrs<<24),(char **)&laddr); if (res != 0) { printf("%s: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n", __FUNCTION__,(baseadrs<<24)); return(ERROR); } #else res = vmeBusToLocalAdrs(0x09,(char *)(baseadrs<<24),(char **)&laddr); if (res != 0) { printf("%s: ERROR in vmeBusToLocalAdrs(0x09,0x%x,&laddr) \n", __FUNCTION__,(baseadrs<<24)); return(ERROR); } #endif c1190MCSTp = (struct v1190_struct *)(laddr); printf("tdc1190InitMCST: MCST VME (Local) base address 0x%x (0x%x):\n", (UINT32)c1190MCSTp - tdcAddrOffset, (UINT32)c1190MCSTp); /* Loop through use1190/c1190p array to set mcstBaseAddr and set First/intermediate/Last boards */ for(ii=0; iimcstBaseAddr),(baseadrs & V1190_MCSTBASEADDR_MASK)); if(ii==tdcMinSlot) { vmeWrite16(&(c1190p[ii]->mcstCtrl),2); /* active first */ printf("\tFirst board at 0x%08x\n",(UINT32)c1190p[ii] - tdcAddrOffset); } else if(ii==tdcMaxSlot) { vmeWrite16(&(c1190p[ii]->mcstCtrl),1); /* active last */ printf("\tLast board at 0x%08x\n",(UINT32)c1190p[ii] - tdcAddrOffset); } else { vmeWrite16(&(c1190p[ii]->mcstCtrl),3); /* active intermediate */ printf("\tMiddle board at 0x%08x\n",(UINT32)c1190p[ii] - tdcAddrOffset); } } for(ii=0; iimoduleReset,1); } return(OK); } /****************************************************************************** * * tdc1190Trig - Issue Software trigger to TDC * tdc1190Clear - Clear TDC * tdc1190Reset - Clear/Reset TDC * tdc1190GetEventCounter - Return number of triggers since last clear/reset. * tdc1190GetEventStored - Return number of events currently stored in * output buffer * tdc1190SetAlmostFullLevel - Set value of number of words in output buffer * when an IRQ is generated (if enabled) and * correspond bit in Status reg is set. * tdc1190SetOutProg - Set the function for the output on the control connector * 0 : Data Ready * 1 : Full * 2 : Almost Full * 3 : Error * tdc1190GetOutProg - Get value set for the output on the control connector. * tdc1190TestMode - Enable (off=0) or disable (off=1) Test mode * tdc1190Test - Set a value (tval) into the Testreg register * tdc1190SetGeoAddress - Set the GEO Address (contained in header/trailer words) * tdc1190GetGeoAddress - Get the GEO Address (contained in header/trailer words) * */ STATUS tdc1190Trig(int id) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->trigger),1); UNLOCK_1190; return OK; } STATUS tdc1190GTrig() { int id; LOCK_1190; for(id=0; idtrigger),1); UNLOCK_1190; return OK; } STATUS tdc1190Clear(int id) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->clear),1); UNLOCK_1190; return OK; } STATUS tdc1190GClear() { int id; LOCK_1190; for(id=0; idclear),1); UNLOCK_1190; return OK; } STATUS tdc1190Reset(int id) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->moduleReset),1); UNLOCK_1190; return OK; } STATUS tdc1190GReset() { int id; LOCK_1190; for(id=0; idmoduleReset),1); UNLOCK_1190; return OK; } int tdc1190GetEventCounter(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead32(&(c1190p[id]->evCount)); UNLOCK_1190; return rval; } int tdc1190GetEventStored(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead16(&(c1190p[id]->evStored)); UNLOCK_1190; return rval; } STATUS tdc1190SetAlmostFullLevel(int id, UINT16 nwords) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->almostFullLevel),(nwords & 0x7FFF)); UNLOCK_1190; return OK; } STATUS tdc1190GSetAlmostFullLevel(UINT16 nwords) { int id; LOCK_1190; for(id=0; idalmostFullLevel),(nwords & 0x7FFF)); UNLOCK_1190; return OK; } int tdc1190GetAlmostFullLevel(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead16(&(c1190p[id]->almostFullLevel)); UNLOCK_1190; return rval; } STATUS tdc1190SetOutProg(int id, UINT16 code) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->outProgControl),code & 0x3); UNLOCK_1190; return OK; } STATUS tdc1190GSetOutProg(UINT16 code) { int id; LOCK_1190; for(id=0; idoutProgControl),code & 0x3); UNLOCK_1190; return OK; } int tdc1190GetOutProg(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead16(&(c1190p[id]->outProgControl)); UNLOCK_1190; return rval; } STATUS tdc1190TestMode(int id, int off) { UINT16 loword=0x3456, hiword=0x12; CHECKID(id); if(off) { tdc1190WriteMicro(id,0xC600); /* Disable test mode */ } else { tdc1190WriteMicro(id,0xC500); /* Enable test mode */ tdc1190WriteMicro(id,loword); tdc1190WriteMicro(id,hiword); } #ifdef OLDSTUFF /* FIXME: Test mode enabled/disabled through OPCODE */ if(off) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & (~V1190_TESTMODE&0xf)); else vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | (V1190_TESTMODE)); #endif return OK; } STATUS tdc1190Test(int id, UINT16 tval) { /* FIXME: Test mode enabled/disabled through OPCODE */ UINT16 testMode=0; CHECKID(id); testMode = vmeRead16(&(c1190p[id]->control))&V1190_TESTMODE; if(testMode) { if(tval==0) vmeWrite32(&(c1190p[id]->testReg),0x11223344); else vmeWrite32(&(c1190p[id]->testReg),tval); /* FIXME: Maybe the below is better than above... I dont know... fix it later */ /* (UINT16 *)(c1190p[id]->testReg) = tval; */ } else { printf("tdc1190Test: ERROR: TestMode not enabled.\n"); } return OK; } STATUS tdc1190SetGeoAddress(int id, UINT16 geoaddr) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->geoAddr),geoaddr & 0x1F); UNLOCK_1190; return OK; } int tdc1190GetGeoAddress(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead16(&(c1190p[id]->geoAddr)) & 0x1F; UNLOCK_1190; return rval; } STATUS tdc1190SetBLTEventNumber(int id, UINT16 nevents) { CHECKID(id); LOCK_1190; vmeWrite16(&(c1190p[id]->bltEventNumber), nevents & 0xFF); UNLOCK_1190; return OK; } STATUS tdc1190GSetBLTEventNumber(UINT16 nevents) { int itdc=0; LOCK_1190; for(itdc=0; itdcbltEventNumber), nevents & 0xFF); UNLOCK_1190; return OK; } int tdc1190GetBLTEventNumber(int id) { int rval; CHECKID(id); LOCK_1190; rval = vmeRead16(&(c1190p[id]->bltEventNumber)); UNLOCK_1190; return rval; } STATUS tdc1190SetRCadjust(int id, int tdc, int adjust) { CHECKID(id); if((tdc<0) || (tdc>3)) { printf("%s: ERROR: Invalid tdc (%d)\n", __FUNCTION__,tdc); return ERROR; } if((adjust<0) || (adjust>0xFFF)) { printf("%s: ERROR: Invalid adjust (0x%x)\n", __FUNCTION__,adjust); return ERROR; } tdc1190WriteMicro(id, 0x5400 + tdc); tdc1190WriteMicro(id, adjust); return OK; } STATUS tdc1190GSetRCadjust(int tdc, int adjust) { if((tdc<0) || (tdc>3)) { printf("%s: ERROR: Invalid tdc (%d)\n", __FUNCTION__,tdc); return ERROR; } if((adjust<0) || (adjust>0xFFF)) { printf("%s: ERROR: Invalid adjust (0x%x)\n", __FUNCTION__,adjust); return ERROR; } tdc1190GWriteMicro(0x5400 + tdc); tdc1190GWriteMicro(adjust); return OK; } int tdc1190GetRCadjust(int id, int tdc) { int rval=0; unsigned short tmp = 0; CHECKID(id); if((tdc<0) || (tdc>3)) { printf("%s: ERROR: Invalid tdc (%d)\n", __FUNCTION__,tdc); return ERROR; } tdc1190WriteMicro(id, 0x5500 + tdc); tdc1190ReadMicro(id, &tmp, 1); rval = (int) ( tmp & 0xFFF ); return rval; } /***********************/ /* INTERRUPT FUNCTIONS */ /***********************/ /******************************************************************************* * * tdc1190Int - default interrupt handler * * This rountine handles the v1190 TDC interrupt. A user routine is * called, if one was connected by tdc1190IntConnect(). * * RETURNS: N/A * */ LOCAL void tdc1190Int (void) { UINT32 nevt=0; /* Disable interrupts */ #ifdef VXWORKS sysIntDisable(c1190IntLevel); #else vmeBusLock(); #endif c1190IntCount++; if (c1190IntRoutine != NULL) { /* call user routine */ (*c1190IntRoutine) (c1190IntArg); }else{ if((c1190IntID<0) || (c1190p[c1190IntID] == NULL)) { logMsg("c1190Int: ERROR : TDC id %d not initialized \n",c1190IntID,0,0,0,0,0); return; } logMsg("c1190Int: Processed %d events\n",nevt,0,0,0,0,0); } /* Enable interrupts */ #ifdef VXWORKS sysIntEnable(c1190IntLevel); #else vmeBusUnlock(); #endif } /******************************************************************************* * * c1190IntConnect - connect a user routine to the v1190 TDC interrupt * * This routine specifies the user interrupt routine to be called at each * interrupt. * * RETURNS: OK, or ERROR if Interrupts are enabled */ STATUS tdc1190IntConnect (VOIDFUNCPTR routine, int arg, UINT16 level, UINT16 vector) { if(c1190IntRunning) { printf("c1190IntConnect: ERROR : Interrupts already Initialized for TDC id %d\n", c1190IntID); return(ERROR); } c1190IntRoutine = routine; c1190IntArg = arg; /* Check for user defined VME interrupt level and vector */ if(level == 0) { c1190IntLevel = V1190_VME_INT_LEVEL; /* use default */ } else if (level > 7) { printf("c1190IntConnect: ERROR: Invalid VME interrupt level (%d). Must be (1-7)\n",level); return(ERROR); } else { c1190IntLevel = level; } if(vector == 0) { c1190IntVec = V1190_INT_VEC; /* use default */ } else if ((vector < 32)||(vector>255)) { printf("c1190IntConnect: ERROR: Invalid interrupt vector (%d). Must be (32 0) { c1190IntRunning = FALSE; } return (OK); } void tdc1190DataDecode(UINT32 data) { static int tdc = 0; UINT32 datatype = 0; int evCount=0, geo=0; /* Global Header */ int eventID=0, bunchID=0; /* TDC Header */ int isTrailing=0, chan=0, measurement=0; /* TDC Measurement */ int wordCount=0; /* TDC Trailer */ int errorFlags=0; /* TDC Error */ int triggerTime=0; /* Global Trigger Time Tag */ int status=0, trigLost=0, outBufferOverflow=0, tdcError=0; /* Global Trailer */ static UINT32 call_count=0; call_count++; printf("%5d: ",call_count); datatype = (data & 0xF8000000)>>27; switch(datatype) { case 0: /* TDC Measurement */ isTrailing = (data & (1<<28))>>28; chan = (data & 0x03f80000)>>19; measurement = (data & 0x0007ffff); printf("%8X - TDC MEASUREMENT - %s tdc=%d chan=%2d time=0x%08x\n", data, isTrailing?"T":"L", tdc, chan, measurement); break; case 1: /* TDC Header */ tdc = (data & 0x03000000)>>24; eventID = (data & 0x00fff000)>>12; bunchID = (data & 0x00000fff); printf("%8X - TDC HEADER - tdc=%d eventID=%d bunchID=%d\n", data, tdc, eventID, bunchID); break; case 3: /* TDC Trailer */ tdc = (data & 0x03000000)>>24; eventID = (data & 0x00fff000)>>12; wordCount = (data & 0x00000fff); printf("%8X - TDC TRAILER - tdc=%d eventID=%d wordCount=%d\n", data, tdc, eventID, wordCount); break; case 4: /* TDC Error */ tdc = (data & 0x03000000)>>24; errorFlags = (data & 0x00007fff); printf("%8X - TDC ERROR - 0x%05x\n", data, errorFlags); break; case 8: /* Global Header */ evCount = (data & 0x07ffffe0)>>5; geo = (data & 0x0000001f); printf("%8X - GLOBAL HEADER - geo = %d evCount = %d\n", data, geo, evCount); break; case 16: /* Global Trailer */ status = (data & 0x07000000)>>24; wordCount = (data & 0x001fffe0)>>5; geo = (data & 0x0000001f); trigLost = status & 0x1; outBufferOverflow = status & 0x2; tdcError = status & 0x4; printf("%8X - GLOBAL TRAILER - geo = %d status = %d %s%s%s wordCount = %d\n", data, geo, status, trigLost?"T":"", outBufferOverflow?"O":"", tdcError?"E":"", wordCount); break; case 17: /* Global Trigger Time Tag */ triggerTime = (data & 0x07ffffff); printf("%8X - GLOBAL TRIGGER TIME TAG - time = %08x\n", data, triggerTime); break; case 24: /* Filler */ printf("%8X - FILLER\n", data); break; default: printf("%8X: UNKNOWN DATA TYPE %d (0x%x)\n", data, datatype, datatype); } } // SOME MODIFIED FUNCTIONS void tdc1190RCStatus(){ int itdc, caen_slot, chip; int adjust = 0; int tap1, tap2, tap3, tap4; printf("\n"); printf(" SLOT CHIP TAP1 TAP2 TAP3 TAP4\n"); for(itdc = 0; itdc < Nc1190; itdc++){ caen_slot = tdc1190GetGeoAddress(itdc); for(chip = 0; chip < 4; chip++){ adjust = tdc1190GetRCadjust(itdc, chip); tap1 = adjust & 0x7; tap2 = (adjust >> 3) & 0x7; tap3 = (adjust >> 6) & 0x7; tap4 = (adjust >> 9) & 0x7; printf(" %2d %2d %2d %2d %2d %2d\n", caen_slot, chip, tap1, tap2, tap3, tap4); } printf("\n"); } } // 11/16/2016 /****************************************************************************** * * tdc1190Compensation - Set the status of the compensation of the INL * flag = 1 : enable compensation * 0 : disable compensation * * * RETURNS: 0 if successful, ERROR otherwise. */ int tdc1190Compensation(int id, UINT32 flag) { CHECKID(id); if(use1190[id]==0) return ERROR; if(flag>1) { printf("%s: ERROR: Invalid flag = %d", __FUNCTION__, flag); return ERROR; } LOCK_1190; if(flag == 1) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_COMPENSATION_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_COMPENSATION_ENABLE); UNLOCK_1190; return(0); } int tdc1190GCompensation(UINT32 flag) { int itdc=0; if(flag>1) { printf("%s: ERROR: Invalid flag = %d", __FUNCTION__, flag); return ERROR; } LOCK_1190; for(itdc=0; itdccontrol), vmeRead16(&(c1190p[itdc]->control)) | V1190_COMPENSATION_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[itdc]->control), vmeRead16(&(c1190p[itdc]->control)) & ~V1190_COMPENSATION_ENABLE); } UNLOCK_1190; return(0); } /****************************************************************************** * * tdc1190ReadCompensation - Set the readback of the compensation of the INL * flag = 1 : enable compensation readback * 0 : disable compensation readback * * * RETURNS: 0 if successful, ERROR otherwise. */ int tdc1190ReadCompensation(int id, UINT32 flag) { CHECKID(id); if(use1190[id]==0) return ERROR; if(flag>1) { printf("%s: ERROR: Invalid flag = %d", __FUNCTION__, flag); return ERROR; } LOCK_1190; if(flag == 1) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) | V1190_READ_COMP_SRAM_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[id]->control), vmeRead16(&(c1190p[id]->control)) & ~V1190_READ_COMP_SRAM_ENABLE); UNLOCK_1190; return(0); } int tdc1190GReadCompensation(UINT32 flag) { int itdc=0; if(flag>1) { printf("%s: ERROR: Invalid flag = %d", __FUNCTION__, flag); return ERROR; } LOCK_1190; for(itdc=0; itdccontrol), vmeRead16(&(c1190p[itdc]->control)) | V1190_READ_COMP_SRAM_ENABLE); else if(flag == 0) vmeWrite16(&(c1190p[itdc]->control), vmeRead16(&(c1190p[itdc]->control)) & ~V1190_READ_COMP_SRAM_ENABLE); } UNLOCK_1190; return(0); }