|
|
(5 intermediate revisions by one other user not shown) |
Line 1: |
Line 1: |
| + | =Property= |
| + | Sensitivity: 100 fC/channel |
| + | |
| + | = Manual= |
| + | |
| + | [[Media:CAEN_V792_Manual.pdf]] |
| + | |
| =Module address= | | =Module address= |
| | | |
Line 112: |
Line 119: |
| =ROC library= | | =ROC library= |
| | | |
− | [[Media:caen775Lib.pdf]] | + | [[caen775Lib.c_Code]] |
− | /******************************************************************************
| |
− | *
| |
− | * caen775Lib.c - Driver library for readout of C.A.E.N. Model 775 TDC
| |
− | * using a VxWorks 5.2 or later based Single Board computer.
| |
− | *
| |
− | * Author: David Abbott
| |
− | * Jefferson Lab Data Acquisition Group
| |
− | * March 2002
| |
− | *
| |
− | * Revision 1.0 - Initial Revision
| |
− | * - Supports up to 20 CAEN Model 775s in a Crate
| |
− | * - Programmed I/O reads
| |
− | * - Interrupts from a Single 775
| |
− | *
| |
− | */
| |
− | | |
− | #include "vxWorks.h"
| |
− | #include "stdio.h"
| |
− | #include "string.h"
| |
− | #include "logLib.h"
| |
− | #include "taskLib.h"
| |
− | #include "intLib.h"
| |
− | #include "iv.h"
| |
− | #include "semLib.h"
| |
− | #include "vxLib.h"
| |
− | | |
− | /* Include TDC definitions */
| |
− | #include "c775Lib.h"
| |
− | | |
− | /* Include DMA Library definintions */
| |
− | #ifdef VXWORKSPPC
| |
− | #include "universeDma.h"
| |
− | #else
| |
− | #include "mvme_dma.c"
| |
− | #endif
| |
− | | |
− | /* Define external Functions */
| |
− | IMPORT STATUS sysBusToLocalAdrs(int, char *, char **);
| |
− | IMPORT STATUS intDisconnect(int);
| |
− | IMPORT STATUS sysIntEnable(int);
| |
− | IMPORT STATUS sysIntDisable(int);
| |
− | | |
− | /* Define Interrupts variables */
| |
− | BOOL c775IntRunning = FALSE; /* running flag */
| |
− | int c775IntID = -1; /* id number of TD
| |
− | C generating interrupts */
| |
− | LOCAL VOIDFUNCPTR c775IntRoutine = NULL; /* user interrupt
| |
− | service routine */
| |
− | LOCAL int c775IntArg = 0; /* arg to user rou
| |
− | tine */
| |
− | LOCAL int c775IntEvCount = 0; /* Number of Event
| |
− | s to generate Interrupt */
| |
− | LOCAL UINT32 c775IntLevel = C775_VME_INT_LEVEL; /* default VME int
| |
− | errupt level */
| |
− | LOCAL UINT32 c775IntVec = C775_INT_VEC; /* default interru
| |
− | pt Vector */
| |
− | | |
− | | |
− | /* Define global variables */
| |
− | int Nc775 = 0; /* Number of TDCs in Crate */
| |
− | volatile struct c775_struct *c775p[20]; /* pointers to TDC memory map */
| |
− | volatile struct c775_struct *c775pl[20]; /* Support for 68K second memory m
| |
− | ap A24/D32 */
| |
− | int c775IntCount = 0; /* Count of interrupts from TDC */
| |
− | int c775EventCount[20]; /* Count of Events taken by TDC (E
| |
− | vent Count Register value) */
| |
− | int c775EvtReadCnt[20]; /* Count of events read from speci
| |
− | fied TDC */
| |
− | SEM_ID c775Sem; /* Semephore for Task syncronizati
| |
− | on */
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775Init - Initialize c775 Library.
| |
− | *
| |
− | *
| |
− | * RETURNS: OK, or ERROR if the address is invalid or board is not present.
| |
− | */
| |
− | | |
− | STATUS
| |
− | c775Init (UINT32 addr, UINT32 addr_inc, int nadc, UINT16 crateID)
| |
− | {
| |
− | int ii, res, rdata, errFlag = 0;
| |
− | int boardID = 0;
| |
− | unsigned long laddr, lladdr;
| |
− | volatile struct c775_ROM_struct *rp;
| |
− | | |
− |
| |
− | /* Check for valid address */
| |
− | if(addr==0) {
| |
− | printf("c775Init: 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)||(nadc==0))
| |
− | nadc = 1; /* assume only one TDC to initialize */
| |
− | | |
− | /* get the TDCs address */
| |
− | res = sysBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr);
| |
− | if (res != 0) {
| |
− | printf("c775Init: ERROR in sysBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr);
| |
− | return(ERROR);
| |
− | }
| |
− | }else{ /* A32 Addressing */
| |
− | | |
− | #ifdef VXWORKS68K51
| |
− | printf("c775Init: ERROR: 68K Based CPU cannot support A32 addressing (use A2
| |
− | 4)\n");
| |
− | return(ERROR);
| |
− | #endif
| |
− | | |
− | if((addr_inc==0)||(nadc==0))
| |
− | nadc = 1; /* assume only one TDC to initialize */
| |
− | | |
− | /* get the TDC address */
| |
− | res = sysBusToLocalAdrs(0x09,(char *)addr,(char **)&laddr);
| |
− | if (res != 0) {
| |
− | printf("c775Init: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",addr);
| |
− | return(ERROR);
| |
− | }
| |
− | }
| |
− | | |
− | /* Put in Hack for 68K seperate address spaces for A24/D16 and A24/D32 */
| |
− | /* for PowerPC they are one and the same */
| |
− | #ifdef VXWORKS68K51
| |
− | lladdr = C775_68K_A24D32_OFFSET + (laddr&0x00ffffff);
| |
− | #else
| |
− | lladdr = laddr;
| |
− | #endif
| |
− |
| |
− | | |
− | Nc775 = 0;
| |
− | for (ii=0;ii<nadc;ii++) {
| |
− | c775p[ii] = (struct c775_struct *)(laddr + ii*addr_inc);
| |
− | c775pl[ii] = (struct c775_struct *)(lladdr + ii*addr_inc);
| |
− | /* Check if Board exists at that address */
| |
− | res = vxMemProbe((char *) &(c775p[ii]->rev),0,2,(char *)&rdata);
| |
− | if(res < 0) {
| |
− | printf("c775Init: ERROR: No addressable board at addr=0x%x\n",(UINT32) c77
| |
− | 5p[ii]);
| |
− | c775p[ii] = NULL;
| |
− | errFlag = 1;
| |
− | break;
| |
− | } else {
| |
− | /* Check if this is a Model 775 */
| |
− | rp = (struct c775_ROM_struct *)((UINT32)c775p[ii] + C775_ROM_OFFSET);
| |
− | boardID = (((rp->ID_3)&(0xff))<<16) + (((rp->ID_2)&(0xff))<<8) + ((rp->ID_
| |
− | 1)&(0xff));
| |
− | if((boardID != C775_BOARD_ID)&&(boardID != C775_BOARD_ID)) {
| |
− | printf("c775Init: ERROR: Board ID does not match: %d \n",boardID);
| |
− | return(ERROR);
| |
− | }
| |
− | }
| |
− | Nc775++;
| |
− | printf("Initialized TDC ID %d at address 0x%08x \n",ii,(UINT32) c775p[ii]);
| |
− | }
| |
− | | |
− | /* Initialize/Create Semephore */
| |
− | if(c775Sem != 0) {
| |
− | semFlush(c775Sem);
| |
− | semDelete(c775Sem);
| |
− | }
| |
− | c775Sem = semBCreate(SEM_Q_PRIORITY,SEM_EMPTY);
| |
− | if(c775Sem <= 0) {
| |
− | printf("c775Init: ERROR: Unable to create Binary Semephore\n");
| |
− | return(ERROR);
| |
− | }
| |
− |
| |
− | /* Disable/Clear all TDCs */
| |
− | for(ii=0;ii<Nc775;ii++) {
| |
− | C775_EXEC_SOFT_RESET(ii);
| |
− | C775_EXEC_DATA_RESET(ii);
| |
− | c775p[ii]->intLevel = 0; /* Disable Interrupts */
| |
− | c775p[ii]->evTrigger = 0; /* Zero interrupt trigger count */
| |
− | c775p[ii]->crateSelect = crateID; /* Set Crate ID Register */
| |
− | c775p[ii]->bitClear2 = C775_INCR_ALL_TRIG; /* Increment event count only on
| |
− | accepted gates */
| |
− | | |
− | c775EventCount[ii] = 0; /* Initialize the Event Count */
| |
− | c775EvtReadCnt[ii] = -1; /* Initialize the Read Count */
| |
− | | |
− | c775SetFSR(ii,C775_MIN_FSR); /* Set Full Scale Range for TDC */
| |
− | | |
− | c775Sparse(ii,0,0); /* Disable Overflow/Underflow suppression */
| |
− | }
| |
− | /* Initialize Interrupt variables */
| |
− | c775IntID = -1;
| |
− | c775IntRunning = FALSE;
| |
− | c775IntLevel = 0;
| |
− | c775IntVec = 0;
| |
− | c775IntRoutine = NULL;
| |
− | c775IntArg = 0;
| |
− | c775IntEvCount = 0;
| |
− |
| |
− | | |
− | if(errFlag > 0) {
| |
− | printf("c775Init: ERROR: Unable to initialize all TDC Modules\n");
| |
− | if(Nc775 > 0)
| |
− | printf("c7752Init: %d TDC(s) successfully initialized\n",Nc775);
| |
− | return(ERROR);
| |
− | } else {
| |
− | return(OK);
| |
− | }
| |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775Status - Gives Status info on specified TDC
| |
− | *
| |
− | *
| |
− | * RETURNS: None
| |
− | */
| |
− | | |
− | void
| |
− | c775Status( int id, int reg, int sflag)
| |
− | {
| |
− | | |
− | int DRdy=0, BufFull=0;
| |
− | UINT16 stat1, stat2, bit1, bit2, cntl1;
| |
− | UINT16 iLvl, iVec, evTrig;
| |
− | UINT16 fsr;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | printf("c775Status: ERROR : TDC id %d not initialized \n",id);
| |
− | return;
| |
− | }
| |
− | | |
− | | |
− | /* read various registers */
| |
− | | |
− | stat1 = (c775p[id]->status1)&C775_STATUS1_MASK;
| |
− | stat2 = (c775p[id]->status2)&C775_STATUS2_MASK;
| |
− | bit1 = (c775p[id]->bitSet1)&C775_BITSET1_MASK;
| |
− | bit2 = (c775p[id]->bitSet2)&C775_BITSET2_MASK;
| |
− | cntl1 = (c775p[id]->control1)&C775_CONTROL1_MASK;
| |
− | fsr = 4*(290 - ((c775p[id]->iped)&C775_FSR_MASK));
| |
− | C775_EXEC_READ_EVENT_COUNT(id);
| |
− | if(stat1&C775_DATA_READY) DRdy = 1;
| |
− | if(stat2&C775_BUFFER_FULL) BufFull = 1;
| |
− |
| |
− | iLvl = (c775p[id]->intLevel)&C775_INTLEVEL_MASK;
| |
− | iVec = (c775p[id]->intVector)&C775_INTVECTOR_MASK;
| |
− | evTrig = (c775p[id]->evTrigger)&C775_EVTRIGGER_MASK;
| |
− | | |
− | /* print out status info */
| |
− | | |
− | printf("STATUS for TDC id %d at base address 0x%x \n",id,(UINT32) c775p[id]);
| |
− | printf("---------------------------------------------- \n");
| |
− | | |
− | if( (iLvl>0) && (evTrig>0)) {
| |
− | printf(" Interrupts Enabled - Every %d events\n",evTrig);
| |
− | printf(" VME Interrupt Level: %d Vector: 0x%x \n",iLvl,iVec);
| |
− | printf(" Interrupt Count : %d \n",c775IntCount);
| |
− | } else {
| |
− | printf(" Interrupts Disabled\n");
| |
− | printf(" Last Interrupt Count : %d \n",c775IntCount);
| |
− | }
| |
− | printf("\n");
| |
− | | |
− | printf(" --1-- --2--\n");
| |
− | if(BufFull && DRdy) {
| |
− | printf(" Status = 0x%04x 0x%04x (Buffer Full)\n",stat1,stat2);
| |
− | } else if(DRdy) {
| |
− | printf(" Status = 0x%04x 0x%04x (Data Ready)\n",stat1,stat2);
| |
− | }else{
| |
− | printf(" Status = 0x%04x 0x%04x\n",stat1,stat2);
| |
− | }
| |
− | printf(" BitSet = 0x%04x 0x%04x\n",bit1,bit2);
| |
− | printf(" Control = 0x%04x\n",cntl1);
| |
− | printf(" FSR = %d nsec\n",fsr);
| |
− | if(c775EventCount[id] == 0xffffff) {
| |
− | printf(" Event Count = (No Events Taken)\n");
| |
− | printf(" Last Event Read = (No Events Read)\n");
| |
− | }else{
| |
− | printf(" Event Count = %d\n",c775EventCount[id]);
| |
− | if(c775EvtReadCnt[id] == -1)
| |
− | printf(" Last Event Read = (No Events Read)\n");
| |
− | else
| |
− | printf(" Last Event Read = %d\n",c775EvtReadCnt[id]);
| |
− | }
| |
− | | |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775PrintEvent - Print event from TDC to standard out.
| |
− | *
| |
− | *
| |
− | * RETURNS: Number of Data words read from the TDC (including Header/Trailer).
| |
− | */
| |
− | | |
− | int
| |
− | c775PrintEvent(int id, int pflag)
| |
− | {
| |
− | | |
− | int ii, nWords, evID;
| |
− | UINT32 header, trailer, dCnt;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | printf("c775ClearThresh: ERROR : TDC id %d not initialized \n",id);
| |
− | return(-1);
| |
− | }
| |
− | | |
− | /* Check if there is a valid event */
| |
− | | |
− | if((c775p[id]->status2)&C775_BUFFER_EMPTY) {
| |
− | printf("c775PrintEvent: Data Buffer is EMPTY!\n");
| |
− | return(0);
| |
− | }
| |
− | if((c775p[id]->status1)&C775_DATA_READY) {
| |
− | dCnt = 0;
| |
− | /* Read Header - Get Word count */
| |
− | header = c775pl[id]->data[0];
| |
− | if((header&C775_DATA_ID_MASK) != C775_HEADER_DATA) {
| |
− | printf("c775PrintEvent: ERROR: Invalid Header Word 0x%08x\n",header);
| |
− | return(-1);
| |
− | }else{
| |
− | printf(" TDC DATA for Module %d\n",id);
| |
− | nWords = (header&C775_WORDCOUNT_MASK)>>8;
| |
− | dCnt++;
| |
− | printf(" Header: 0x%08x nWords = %d ",header,nWords);
| |
− | }
| |
− | for(ii=0;ii<nWords;ii++) {
| |
− | if ((ii % 5) == 0) printf("\n ");
| |
− | printf(" 0x%08x",(UINT32) c775pl[id]->data[ii+1]);
| |
− | }
| |
− | printf("\n");
| |
− | dCnt += ii;
| |
− | | |
− | trailer = c775pl[id]->data[dCnt];
| |
− | if((trailer&C775_DATA_ID_MASK) != C775_TRAILER_DATA) {
| |
− | printf("c775PrintEvent: ERROR: Invalid Trailer Word 0x%08x\n",trailer);
| |
− | return(-1);
| |
− | }else{
| |
− | evID = trailer&C775_EVENTCOUNT_MASK;
| |
− | dCnt++;
| |
− | printf(" Trailer: 0x%08x Event Count = %d \n",trailer,evID);
| |
− | }
| |
− | C775_EXEC_SET_EVTREADCNT(id,evID);
| |
− | return (dCnt);
| |
− | | |
− | }else{
| |
− | printf("c775PrintEvent: Data Not ready for readout!\n");
| |
− | return(0);
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775ReadEvent - Read event from TDC to specified address.
| |
− | *
| |
− | *
| |
− | *
| |
− | * RETURNS: Number of Data words read from the TDC (including Header/Trailer).
| |
− | */
| |
− | | |
− | int
| |
− | c775ReadEvent(int id, UINT32 *data)
| |
− | {
| |
− | | |
− | int ii, nWords, evID;
| |
− | UINT32 header, trailer, dCnt;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775ReadEvent: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return(-1);
| |
− | }
| |
− | | |
− | /* Check if there is a valid event */
| |
− | | |
− | if((c775p[id]->status2)&C775_BUFFER_EMPTY) {
| |
− | logMsg("c775ReadEvent: Data Buffer is EMPTY!\n",0,0,0,0,0,0);
| |
− | return(0);
| |
− | }
| |
− | if((c775p[id]->status1)&C775_DATA_READY) {
| |
− | dCnt = 0;
| |
− | /* Read Header - Get Word count */
| |
− | header = c775pl[id]->data[dCnt];
| |
− | if((header&C775_DATA_ID_MASK) != C775_HEADER_DATA) {
| |
− | logMsg("c775ReadEvent: ERROR: Invalid Header Word 0x%08x\n",header,0,0,0,0
| |
− | ,0);
| |
− | return(-1);
| |
− | }else{
| |
− | nWords = (header&C775_WORDCOUNT_MASK)>>8;
| |
− | data[dCnt] = header;
| |
− | dCnt++;
| |
− | }
| |
− | for(ii=0;ii<nWords;ii++) {
| |
− | data[ii+1] = c775pl[id]->data[ii+1];
| |
− | }
| |
− | dCnt += ii;
| |
− | | |
− | trailer = c775pl[id]->data[dCnt];
| |
− | if((trailer&C775_DATA_ID_MASK) != C775_TRAILER_DATA) {
| |
− | logMsg("c775ReadEvent: ERROR: Invalid Trailer Word 0x%08x\n",trailer,0,0,0
| |
− | ,0,0);
| |
− | return(-1);
| |
− | }else{
| |
− | evID = trailer&C775_EVENTCOUNT_MASK;
| |
− | data[dCnt] = trailer;
| |
− | dCnt++;
| |
− | }
| |
− | C775_EXEC_SET_EVTREADCNT(id,evID);
| |
− | return (dCnt);
| |
− | | |
− | }else{
| |
− | logMsg("c775ReadEvent: Data Not ready for readout!\n",0,0,0,0,0,0);
| |
− | return(0);
| |
− | }
| |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775FlushEvent - Flush event/data from TDC.
| |
− | *
| |
− | *
| |
− | * RETURNS: Number of Data words read from the TDC.
| |
− | */
| |
− | | |
− | int
| |
− | c775FlushEvent(int id, int fflag)
| |
− | {
| |
− | | |
− | int evID;
| |
− | int done = 0;
| |
− | UINT32 tmpData, dCnt;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775FlushEvent: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return(-1);
| |
− | }
| |
− | | |
− | /* Check if there is a valid event */
| |
− | | |
− | if((c775p[id]->status2)&C775_BUFFER_EMPTY) {
| |
− | if(fflag > 0) logMsg("c775FlushEvent: Data Buffer is EMPTY!\n",0,0,0,0,0,0);
| |
− | return(0);
| |
− | }
| |
− | | |
− | /* Check if Data Ready Flag is on */
| |
− | if((c775p[id]->status1)&C775_DATA_READY) {
| |
− | dCnt = 0;
| |
− |
| |
− | while (!done) {
| |
− | tmpData = c775pl[id]->data[dCnt];
| |
− | switch (tmpData&C775_DATA_ID_MASK) {
| |
− | case C775_HEADER_DATA:
| |
− | if(fflag > 0) logMsg("c775FlushEvent: Found Header 0x%08x\n",tmpData,0,0
| |
− | ,0,0,0);
| |
− | break;
| |
− | case C775_DATA:
| |
− | break;
| |
− | case C775_TRAILER_DATA:
| |
− | if(fflag > 0) logMsg(" c775FlushEvent: Found Trailer 0x%08x\n",tmpData,0
| |
− | ,0,0,0,0);
| |
− | evID = tmpData&C775_EVENTCOUNT_MASK;
| |
− | C775_EXEC_SET_EVTREADCNT(id,evID);
| |
− | done = 1;
| |
− | break;
| |
− | case C775_INVALID_DATA:
| |
− | if(fflag > 0) logMsg(" c775FlushEvent: Buffer Empty 0x%08x\n",tmpData,0,
| |
− | 0,0,0,0);
| |
− | done = 1;
| |
− | break;
| |
− | default:
| |
− | if(fflag > 0) logMsg(" c775FlushEvent: Invalid Data 0x%08x\n",tmpData,0,
| |
− | 0,0,0,0);
| |
− | }
| |
− | | |
− | /* Print out Data */
| |
− | if(fflag > 1) {
| |
− | if ((dCnt % 5) == 0) printf("\n ");
| |
− | printf(" 0x%08x ",tmpData);
| |
− | }
| |
− | dCnt++;
| |
− | }
| |
− | if(fflag > 1) printf("\n");
| |
− | | |
− | return (dCnt);
| |
− | | |
− | }else{
| |
− | if(fflag > 0) logMsg("c775FlushEvent: Data Not ready for readout!\n",0,0,0,0
| |
− | ,0,0);
| |
− | return(0);
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775ReadBlock - Read Block of events from TDC to specified address.
| |
− | *
| |
− | * INPUTS: id - module id of TDC to access
| |
− | * data - address of data destination
| |
− | * nwrds - number of data words to transfer
| |
− | *
| |
− | * RETURNS: OK or ERROR on success of transfer.
| |
− | *
| |
− | * Note: User must call c775IncrEventBlk after a successful
| |
− | * call to c775ReadBlock to increment the number of events Read.
| |
− | * (e.g. c775IncrEventBlk(0,15);
| |
− | */
| |
− | | |
− | int
| |
− | c775ReadBlock(int id, volatile UINT32 *data, int nwrds)
| |
− | {
| |
− | | |
− | int retVal, xferCount;
| |
− | UINT32 evID;
| |
− | UINT16 stat = 0;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775ReadBlock: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return(-1);
| |
− | }
| |
− | | |
− | | |
− | #ifdef VXWORKSPPC
| |
− | /* Don't bother checking if there is a valid event. Just blast data out of the
| |
− |
| |
− | FIFO Valid or Invalid
| |
− | Also assume that the Universe DMA programming is setup. */
| |
− | | |
− | retVal = sysVmeDmaSend((UINT32)data, (UINT32)(c775pl[id]->data), (nwrds<<2), 0
| |
− | );
| |
− | if(retVal < 0) {
| |
− | logMsg("c775ReadBlock: ERROR in DMA transfer Initialization 0x%x\n",retVal,0
| |
− | ,0,0,0,0);
| |
− | return(retVal);
| |
− | }
| |
− | /* Wait until Done or Error */
| |
− | retVal = sysVmeDmaDone(1000,1);
| |
− | | |
− | #else
| |
− |
| |
− | /* 68K Block 32 transfer from FIFO using VME2Chip */
| |
− | retVal = mvme_dma((long)data, 1, (long)(c775pl[id]->data), 0, nwrds, 1);
| |
− | | |
− | #endif
| |
− | | |
− | if(retVal != 0) {
| |
− | /* Check to see if error was generated by TDC */
| |
− | stat = (c775p[id]->bitSet1)&C775_VME_BUS_ERROR;
| |
− | if((retVal>0) && (stat)) {
| |
− | c775p[id]->bitClear1 = C775_VME_BUS_ERROR;
| |
− | logMsg("c775ReadBlock: INFO: DMA terminated by TDC(BUS Error) - Transfer O
| |
− | K\n",0,0,0,0,0,0);
| |
− | xferCount = (nwrds - (retVal>>2)); /* Number of Longwords transfered */
| |
− | if ((data[xferCount-1]&C775_DATA_ID_MASK) == C775_TRAILER_DATA) {
| |
− | evID = data[xferCount-1]&C775_EVENTCOUNT_MASK;
| |
− | C775_EXEC_SET_EVTREADCNT(id,evID);
| |
− | return(xferCount); /* Return number of data words transfered */
| |
− | } else {
| |
− | logMsg("c775ReadBlock: ERROR: Invalid Trailer data 0x%x\n",data[xferCoun
| |
− | t-1],0,0,0,0,0);
| |
− | return(xferCount);
| |
− | }
| |
− | } else {
| |
− | logMsg("c775ReadBlock: ERROR in DMA transfer 0x%x\n",retVal,0,0,0,0,0);
| |
− | return(retVal);
| |
− | }
| |
− | }
| |
− | | |
− | return(OK);
| |
− | | |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775Int - default interrupt handler
| |
− | *
| |
− | * This rountine handles the c775 TDC interrupt. A user routine is
| |
− | * called, if one was connected by c775IntConnect().
| |
− | *
| |
− | * RETURNS: N/A
| |
− | *
| |
− | */
| |
− | | |
− | LOCAL void
| |
− | c775Int (void)
| |
− | {
| |
− | int ii=0;
| |
− | UINT32 nevt=0;
| |
− |
| |
− | /* Disable interrupts */
| |
− | sysIntDisable(c775IntLevel);
| |
− | | |
− | c775IntCount++;
| |
− |
| |
− | if (c775IntRoutine != NULL) { /* call user routine */
| |
− | (*c775IntRoutine) (c775IntArg);
| |
− | }else{
| |
− | if((c775IntID<0) || (c775p[c775IntID] == NULL)) {
| |
− | logMsg("c775Int: ERROR : TDC id %d not initialized \n",c775IntID,0,0,0,0,0
| |
− | );
| |
− | return;
| |
− | }
| |
− | /* Default action is to increment the Read pointer by
| |
− | the number of events in the Event Trigger register
| |
− | or until the Data buffer is empty. The later case would
| |
− | indicate a possible error. In either case the data is
| |
− | effectively thrown away */
| |
− | nevt = (c775p[c775IntID]->evTrigger)&C775_EVTRIGGER_MASK;
| |
− | while ( (ii<nevt) && (c775Dready(c775IntID) > 0) ) {
| |
− | C775_EXEC_INCR_EVENT(c775IntID);
| |
− | ii++;
| |
− | }
| |
− | if(ii<nevt)
| |
− | logMsg("c775Int: WARN : TDC %d - Events dumped (%d) != Events Triggered (%
| |
− | d)\n",
| |
− | c775IntID,ii,nevt,0,0,0);
| |
− | logMsg("c775Int: Processed %d events\n",nevt,0,0,0,0,0);
| |
− | | |
− | }
| |
− | | |
− | /* Enable interrupts */
| |
− | sysIntEnable(c775IntLevel);
| |
− | | |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775IntConnect - connect a user routine to the c775 TDC interrupt
| |
− | *
| |
− | * This routine specifies the user interrupt routine to be called at each
| |
− | * interrupt.
| |
− | *
| |
− | * RETURNS: OK, or ERROR if Interrupts are enabled
| |
− | */
| |
− | | |
− | STATUS
| |
− | c775IntConnect (VOIDFUNCPTR routine, int arg, UINT16 level, UINT16 vector)
| |
− | {
| |
− | | |
− | if(c775IntRunning) {
| |
− | printf("c775IntConnect: ERROR : Interrupts already Initialized for TDC id %d
| |
− | \n",
| |
− | c775IntID);
| |
− | return(ERROR);
| |
− | }
| |
− |
| |
− | c775IntRoutine = routine;
| |
− | c775IntArg = arg;
| |
− | | |
− | /* Check for user defined VME interrupt level and vector */
| |
− | if(level == 0) {
| |
− | c775IntLevel = C775_VME_INT_LEVEL; /* use default */
| |
− | }else if (level > 7) {
| |
− | printf("c775IntConnect: ERROR: Invalid VME interrupt level (%d). Must be (1-
| |
− | 7)\n",level);
| |
− | return(ERROR);
| |
− | } else {
| |
− | c775IntLevel = level;
| |
− | }
| |
− | | |
− | if(vector == 0) {
| |
− | c775IntVec = C775_INT_VEC; /* use default */
| |
− | }else if ((vector < 32)||(vector>255)) {
| |
− | printf("c775IntConnect: ERROR: Invalid interrupt vector (%d). Must be (32<ve
| |
− | ctor<255)\n",vector);
| |
− | return(ERROR);
| |
− | }else{
| |
− | c775IntVec = vector;
| |
− | }
| |
− |
| |
− | /* Connect the ISR */
| |
− | #ifdef VXWORKSPPC
| |
− | if((intDisconnect((int)INUM_TO_IVEC(c775IntVec)) != 0)) {
| |
− | printf("c775IntConnect: ERROR disconnecting Interrupt\n");
| |
− | return(ERROR);
| |
− | }
| |
− | #endif
| |
− | if((intConnect(INUM_TO_IVEC(c775IntVec),c775Int,0)) != 0) {
| |
− | printf("c775IntConnect: ERROR in intConnect()\n");
| |
− | return(ERROR);
| |
− | }
| |
− | | |
− | return (OK);
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775IntEnable - Enable interrupts from specified TDC
| |
− | *
| |
− | * Enables interrupts for a specified TDC.
| |
− | *
| |
− | * RETURNS OK or ERROR if TDC is not available or parameter is out of range
| |
− | */
| |
− | | |
− | STATUS
| |
− | c775IntEnable (int id, UINT16 evCnt)
| |
− | {
| |
− | | |
− | if(c775IntRunning) {
| |
− | printf("c775IntEnable: ERROR : Interrupts already initialized for TDC id %d\
| |
− | n",
| |
− | c775IntID);
| |
− | return(ERROR);
| |
− | }
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | printf("c775IntEnable: ERROR : TDC id %d not initialized \n",id);
| |
− | return(ERROR);
| |
− | }else{
| |
− | c775IntID = id;
| |
− | }
| |
− |
| |
− | /* check for event count out of range */
| |
− | if((evCnt<=0) || (evCnt>31)) {
| |
− | printf("c775IntEnable: ERROR: Event count %d for Interrupt is out of range (
| |
− | 1-31)\n"
| |
− | ,evCnt);
| |
− | return(ERROR);
| |
− | }
| |
− |
| |
− | sysIntEnable(c775IntLevel); /* Enable VME interrupts */
| |
− |
| |
− | /* Zero Counter and set Running Flag */
| |
− | c775IntEvCount = evCnt;
| |
− | c775IntCount = 0;
| |
− | c775IntRunning = TRUE;
| |
− | /* Enable interrupts on TDC */
| |
− | c775p[c775IntID]->intVector = c775IntVec;
| |
− | c775p[c775IntID]->intLevel = c775IntLevel;
| |
− | c775p[c775IntID]->evTrigger = c775IntEvCount;
| |
− |
| |
− | return(OK);
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775IntDisable - disable the TDC interrupts
| |
− | *
| |
− | * RETURNS: OK, or ERROR if not initialized
| |
− | */
| |
− | | |
− | STATUS
| |
− | c775IntDisable (int iflag)
| |
− | {
| |
− | | |
− | if((c775IntID<0) || (c775p[c775IntID] == NULL)) {
| |
− | logMsg("c775IntDisable: ERROR : TDC id %d not initialized \n",c775IntID,0,0,
| |
− | 0,0,0);
| |
− | return(ERROR);
| |
− | }
| |
− | | |
− | sysIntDisable(c775IntLevel); /* Disable VME interrupts */
| |
− | c775p[c775IntID]->evTrigger = 0;
| |
− | | |
− | /* Tell tasks that Interrupts have been disabled */
| |
− | if(iflag > 0) {
| |
− | c775IntRunning = FALSE;
| |
− | c775p[c775IntID]->intLevel = 0;
| |
− | c775p[c775IntID]->intVector = 0;
| |
− | }else{
| |
− | semGive(c775Sem);
| |
− | }
| |
− |
| |
− | return (OK);
| |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775IntResume - Re-enable interrupts from previously
| |
− | * intitialized TDC
| |
− | *
| |
− | * RETURNS: OK, or ERROR if not initialized
| |
− | */
| |
− | | |
− | STATUS
| |
− | c775IntResume (void)
| |
− | {
| |
− | UINT16 evTrig = 0;
| |
− | | |
− | if((c775IntID<0) || (c775p[c775IntID] == NULL)) {
| |
− | logMsg("c775IntResume: ERROR : TDC id %d not initialized \n",c775IntID,0,0,0
| |
− | ,0,0);
| |
− | return(ERROR);
| |
− | }
| |
− | | |
− | if ((c775IntRunning)) {
| |
− | evTrig = (c775p[c775IntID]->evTrigger)&C775_EVTRIGGER_MASK;
| |
− | if (evTrig == 0) {
| |
− | sysIntEnable(c775IntLevel);
| |
− | c775p[c775IntID]->evTrigger = c775IntEvCount;
| |
− | } else {
| |
− | logMsg("c775IntResume: WARNING : Interrupts already enabled \n",0,0,0,0,0,
| |
− | 0);
| |
− | return(ERROR);
| |
− | }
| |
− | } else {
| |
− | logMsg("c775IntResume: ERROR : Interrupts are not Enabled \n",0,0,0,0,0,0)
| |
− | ;
| |
− | return(ERROR);
| |
− | }
| |
− |
| |
− | return (OK);
| |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775Sparse - Enable/Disable Overflow and Under threshold sparsification
| |
− | *
| |
− | *
| |
− | * RETURNS: Bit Set 2 Register value.
| |
− | */
| |
− | | |
− | UINT16
| |
− | c775Sparse(int id, int over, int under)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | printf("c775Sparse: ERROR : TDC id %d not initialized \n",id);
| |
− | return(0xffff);
| |
− | }
| |
− |
| |
− | if(!over) { /* Set Overflow suppression */
| |
− | c775p[id]->bitSet2 = C775_OVERFLOW_SUP;
| |
− | }else{
| |
− | c775p[id]->bitClear2 = C775_OVERFLOW_SUP;
| |
− | }
| |
− | | |
− | if(!under) { /* Set Underflow suppression */
| |
− | c775p[id]->bitSet2 = C775_UNDERFLOW_SUP;
| |
− | }else{
| |
− | c775p[id]->bitClear2 = C775_UNDERFLOW_SUP;
| |
− | }
| |
− | | |
− | return((c775p[id]->bitSet2)&C775_BITSET2_MASK);
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775Dready - Return status of Data Ready bit in TDC
| |
− | *
| |
− | *
| |
− | * RETURNS: 0(No Data) or # of events in FIFO (1-32) or ERROR.
| |
− | */
| |
− | | |
− | int
| |
− | c775Dready(int id)
| |
− | {
| |
− | | |
− | int nevts = 0;
| |
− | UINT16 stat=0;
| |
− | | |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Dready: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return (ERROR);
| |
− | }
| |
− |
| |
− | stat = (c775p[id]->status1)&C775_DATA_READY;
| |
− | if(stat) {
| |
− | C775_EXEC_READ_EVENT_COUNT(id);
| |
− | nevts = c775EventCount[id] - c775EvtReadCnt[id];
| |
− | if(nevts <= 0) {
| |
− | logMsg("c775Dready: ERROR : Bad Event Ready Count (nevts = %d)\n",
| |
− | nevts,0,0,0,0,0);
| |
− | return(ERROR);
| |
− | }
| |
− | }
| |
− | | |
− | return(nevts);
| |
− | }
| |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775SetFSR - Set and/or Return TDC full scale range programming
| |
− | *
| |
− | * Register value: 0xff (255) -> 35 ps/count ( 140ns FSR )
| |
− | * range between: 0x1e ( 30) -> 300 ps/count ( 1200ns FSR )
| |
− | *
| |
− | * FSR = 4*(290-reg)
| |
− | *
| |
− | * reg = 290 - FSR/4
| |
− | *
| |
− | * Note: Passing 0 for fsr will return the contents of the register
| |
− | * but not set it.
| |
− | *
| |
− | * RETURNS: Full scale range of the TDC in nanoseconds or ERROR.
| |
− | */
| |
− | | |
− | int
| |
− | c775SetFSR(int id, UINT16 fsr)
| |
− | {
| |
− | | |
− | int rfsr=0;
| |
− | UINT16 reg;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775SetFSR: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return (ERROR);
| |
− | }
| |
− | | |
− | if(fsr==0) {
| |
− | reg = (c775p[id]->iped)&C775_FSR_MASK;
| |
− | rfsr = (int)(290 - reg)*4;
| |
− | }else if((fsr<C775_MIN_FSR)||(fsr>C775_MAX_FSR)) {
| |
− | logMsg("c775SetFSR: ERROR: FSR (%d ns) out of range (140<=FSR<=1200)\n",fsr,
| |
− | 0,0,0,0,0);
| |
− | return(ERROR);
| |
− | }else{
| |
− | reg = (UINT16)(290 - (fsr>>2));
| |
− | c775p[id]->iped = reg;
| |
− | reg = (c775p[id]->iped)&C775_FSR_MASK;
| |
− | rfsr = (int)(290 - reg)*4;
| |
− | }
| |
− | | |
− | return(rfsr);
| |
− | | |
− | }
| |
− | | |
− | /******************************************************************************
| |
− | *
| |
− | *
| |
− | * c775BitSet2 - Program Bit Set 2 register
| |
− | * c775BitClear2 - Program Bit clear 2 register
| |
− | *
| |
− | */
| |
− | | |
− | INT16
| |
− | c775BitSet2(int id, UINT16 val)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775BitSet2: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return (ERROR);
| |
− | }
| |
− | | |
− | if(val)
| |
− | c775p[id]->bitSet2 = val;
| |
− | | |
− | return((c775p[id]->bitSet2)&C775_BITSET2_MASK);
| |
− | }
| |
− | INT16
| |
− | c775BitClear2(int id, UINT16 val)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775BitClear2: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return (ERROR);
| |
− | }
| |
− | | |
− | if(val)
| |
− | c775p[id]->bitClear2 = val;
| |
− | | |
− | return((c775p[id]->bitSet2)&C775_BITSET2_MASK);
| |
− | }
| |
− | | |
− | | |
− | /*******************************************************************************
| |
− | *
| |
− | * c775ClearThresh - Zero TDC thresholds for all channels
| |
− | * c775Gate - Issue Software Gate to TDC
| |
− | * c775IncrEventBlk - Increment Event counter for Block reads
| |
− | * c775IncrEvent - Increment Read pointer to next event in the Buffer
| |
− | * c775IncrWord - Increment Read pointer to next word in the event
| |
− | * c775Enable - Bring TDC Online (Enable Gates)
| |
− | * c775Disable - Bring TDC Offline (Disable Gates)
| |
− | * c775CommonStop - Program for Common Stop
| |
− | * c775CommonStart - Program for Common Start (Default)
| |
− | * c775Clear - Clear TDC
| |
− | * c775Reset - Clear/Reset TDC
| |
− | *
| |
− | *
| |
− | * RETURNS: None.
| |
− | */
| |
− | | |
− | void
| |
− | c775ClearThresh(int id)
| |
− | {
| |
− | int ii;
| |
− | | |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775ClearThresh: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0)
| |
− | ;
| |
− | return;
| |
− | }
| |
− | | |
− | for (ii=0;ii< C775_MAX_CHANNELS; ii++) {
| |
− | c775p[id]->threshold[ii] = 0;
| |
− | }
| |
− | }
| |
− | | |
− | void
| |
− | c775Gate(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Gate: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | C775_EXEC_GATE(id);
| |
− | }
| |
− | | |
− | void
| |
− | c775IncrEventBlk(int id, int count)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775IncrEventBlk: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0
| |
− | );
| |
− | return;
| |
− | }
| |
− | | |
− | if((count > 0) && (count <=32))
| |
− | c775EvtReadCnt[id] += count;
| |
− | }
| |
− | | |
− | void
| |
− | c775IncrEvent(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775IncrEvent: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | C775_EXEC_INCR_EVENT(id);
| |
− | }
| |
− | | |
− | void
| |
− | c775IncrWord(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775IncrWord: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | C775_EXEC_INCR_WORD(id);
| |
− | }
| |
− | void
| |
− | c775Enable(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Enable: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | c775p[id]->bitClear2 = C775_OFFLINE;
| |
− | }
| |
− | | |
− | void
| |
− | c775Disable(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Disable: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | c775p[id]->bitSet2 = C775_OFFLINE;
| |
− | }
| |
− | | |
− | void
| |
− | c775CommonStop(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775CommonStop: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | c775p[id]->bitSet2 = C775_COMMON_STOP;
| |
− | }
| |
− | | |
− | void
| |
− | c775CommonStart(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775CommonStart: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0)
| |
− | ;
| |
− | return;
| |
− | }
| |
− | c775p[id]->bitClear2 = C775_COMMON_STOP;
| |
− | }
| |
− | | |
− | | |
− | void
| |
− | c775Clear(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Clear: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | C775_EXEC_DATA_RESET(id);
| |
− | c775EvtReadCnt[id] = -1;
| |
− | c775EventCount[id] = 0;
| |
− | | |
− | }
| |
− | | |
− | void
| |
− | c775Reset(int id)
| |
− | {
| |
− | if((id<0) || (c775p[id] == NULL)) {
| |
− | logMsg("c775Reset: ERROR : TDC id %d not initialized \n",id,0,0,0,0,0);
| |
− | return;
| |
− | }
| |
− | C775_EXEC_DATA_RESET(id);
| |
− | C775_EXEC_SOFT_RESET(id);
| |
− | c775EvtReadCnt[id] = -1;
| |
− | c775EventCount[id] = 0;
| |
− | }
| |
| | | |
| | | |
Line 1,222: |
Line 132: |
| ==Control lines== | | ==Control lines== |
| [[Image:ECL-QDC_FSTCLR.jpg | 400 px]] | | [[Image:ECL-QDC_FSTCLR.jpg | 400 px]] |
| + | |
| + | [http://wiki.iac.isu.edu/index.php/VME_modules Go back] |
| + | [[VME_modules]] Go back |