CAEN V792 ADC

From New IAC Wiki
Revision as of 18:16, 16 January 2009 by Oborn (talk | contribs) (→‎ROC library)
Jump to navigation Jump to search

Module address

CAEN V792 QDC Address.jpg

Rotary dials

The rotary dials for the address were set by the factory to be 32 bit addressing with "e" and "e" on the last dials.

We would like to use 24 bit addressing so lets set the first two dials to "ee". The last two dials should also be set to something non-zero in order to permit 32 bit addressing. The MVME-6100 board only has a small amount of 32 bit VME addressing space mapped to the MVME's address space.

               VME                             CPU
    A24   0x000000-0xffffff           0x90000000-0x90ffffff
    A32   0x08000000-0x11ffffff       0x80000000-0x89ffffff


If you set the last two dials to 0 8 then the addressing will look like

    c792Init 0xee0000     (for A24 addressing)

or

    c792Init 0x08ee0000   (for A32 addressing)

Data banks

The ADC module library will send the entire block over unless you set the ADC for specification.

Below is shown the data structure for Multi-Event Buffer. The data is organized in events[1]. The header, which contains the crate number and the number of converted channels(the second row in the table), the data words - the number of the channel, the Under-Threshold (UN) bit, the Overflow (OV) bit and the 12-bit converted value(ADC COUNTS) and event counter is in The End of Block.

The Header

The bits[26..24] - shows the word type(010 - header);
The bits[23..16] - the crate number;
The bits[13...8] - the memorized channel number.

The data words

The bits[26..24] - the type of word (000 - datum);
The bits[21..16] - the data output channel number;
The bit[13] - the underthreshold;
The bit[12] - the overflow;
The bits[11...0] - the 12 bit converted data.

The End of Block(EOB)

The bits[26..24] - identification of the word type(100 - EOB);
The bits[23..0] - the event counter value.


26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 0 CRATE NUMBER 0 0 MEM. CHANNELS(2)
0 0 0 CHANNEL(2) UN OV ADC COUNTS
0 0 0 CHANNEL(5) UN OV ADC COUNTS
1 0 0 EVENT COUNTER(m)
0 1 0 CRATE NUMBER 0 0 MEM. CHANNELS(3)
0 0 0 CHANNEL(0) UN OV ADC COUNTS
0 0 0 CHANNEL(17) UN OV ADC COUNTS
0 0 0 CHANNEL(3) UN OV ADC COUNTS
1 0 0 EVENT COUNTER(m+3)

Assuming we read all 32 channels then the data block will look like

ADC1:
Crate #=0
Ch       data    Hex
0       3896    f8005f38
16      3896    f8105f38
1       3896    f8015f38
17      3896    f8115f38
2       3896    f8025f38
18      3896    f8125f38
3       3896    f8035f38
19      3896    f8135f38
4       3896    f8045f38
20      3896    f8145f38
5       3896    f8055f38
21      3896    f8155f38
6       3896    f8065f38
22      3896    f8165f38
7       3896    f8075f38
23      3896    f8175f38
8       3896    f8085f38
24      3896    f8185f38
9       3896    f8095f38
25      3896    f8195f38
10      3896    f80a5f38
26      3896    f81a5f38
11      3896    f80b5f38
27      3896    f81b5f38
12      3896    f80c5f38
28      3896    f81c5f38
13      3896    f80d5f38
29      3896    f81d5f38
14      3896    f80e5f38
30      3896    f81e5f38
15      3896    f80f5f38
31      3896    f81f5f38
Event Counter=46=0xfc00002e


ROC library

/******************************************************************************

  • 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
  • /
  1. include "vxWorks.h"
  2. include "stdio.h"
  3. include "string.h"
  4. include "logLib.h"
  5. include "taskLib.h"
  6. include "intLib.h"
  7. include "iv.h"
  8. include "semLib.h"
  9. include "vxLib.h"

/* Include TDC definitions */

  1. include "c775Lib.h"

/* Include DMA Library definintions */

  1. ifdef VXWORKSPPC
  2. include "universeDma.h"
  3. else
  4. include "mvme_dma.c"
  5. 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 */
  1. ifdef VXWORKS68K51
   printf("c775Init: ERROR: 68K Based CPU cannot support A32 addressing (use A2

4)\n");

   return(ERROR);
  1. 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 */
  1. ifdef VXWORKS68K51
 lladdr = C775_68K_A24D32_OFFSET + (laddr&0x00ffffff);
  1. else
 lladdr = laddr;
  1. 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);
 }


  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);
  1. else
 /* 68K Block 32 transfer from FIFO using VME2Chip */
 retVal = mvme_dma((long)data, 1, (long)(c775pl[id]->data), 0, nwrds, 1);
  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 */
  1. ifdef VXWORKSPPC
 if((intDisconnect((int)INUM_TO_IVEC(c775IntVec)) != 0)) {
   printf("c775IntConnect: ERROR disconnecting Interrupt\n");
   return(ERROR);
 }
  1. 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;

}


The command below will compile the above library.


v792 >ccppc -fno-builtin -fno-for-scope -fstrength-reduce -mlongcall -mcpu=604 -DCPU=PPC604 -DVXWORKS -D_GNU_TOOL 
-DVXWORKSPPC  -I/usr/local/coda/2.5/common/include -I../h   -c -o v792Lib.o caen792Lib.c

ECL input polarity

Control lines

ECL-QDC FSTCLR.jpg