#endif
/* Include ADC definitions */
#include "fadcLib.h"
#ifdef VXWORKS
#define FALOCK
#define FAUNLOCK
#define FASDCLOCK
#define FASDCUNLOCK
#else
/* Mutex to guard flexio read/writes */
pthread_mutex_t faMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t fasdcMutex = PTHREAD_MUTEX_INITIALIZER;
#define FALOCK if(pthread_mutex_lock(&faMutex)<0) perror("pthread_mutex_lock");
#define FAUNLOCK if(pthread_mutex_unlock(&faMutex)<0) perror("pthread_mutex_unlock");
#define FASDCLOCK if(pthread_mutex_lock(&fasdcMutex)<0) perror("pthread_mutex_lock");
#define FASDCUNLOCK if(pthread_mutex_unlock(&fasdcMutex)<0) perror("pthread_mutex_unlock");
#endif
/* Define external Functions */
#ifdef VXWORKS
IMPORT STATUS sysBusToLocalAdrs(int, char *, char **);
IMPORT STATUS intDisconnect(int);
IMPORT STATUS sysIntEnable(int);
IMPORT STATUS sysIntDisable(int);
IMPORT STATUS sysVmeDmaDone(int, int);
IMPORT STATUS sysVmeDmaSend(UINT32, UINT32, int, BOOL);
#define EIEIO __asm__ volatile ("eieio")
#define SYNC __asm__ volatile ("sync")
#endif
/* Define Interrupts variables */
BOOL fadcIntRunning = FALSE; /* running flag */
int fadcIntID = -1; /* id number of ADC generating interrupts */
LOCAL VOIDFUNCPTR fadcIntRoutine = NULL; /* user interrupt service routine */
LOCAL int fadcIntArg = 0; /* arg to user routine */
LOCAL UINT32 fadcIntLevel = FA_VME_INT_LEVEL; /* default VME interrupt level */
LOCAL UINT32 fadcIntVec = FA_VME_INT_VEC; /* default interrupt Vector */
/* Define global variables */
int nfadc = 0; /* Number of FADCs in Crate */
unsigned int fadcA32Base = 0x08000000; /* Minimum VME A32 Address for use by FADCs */
unsigned long fadcA32Offset = 0x08000000; /* Difference in CPU A32 Base - VME A32 Base */
unsigned long fadcA24Offset = 0x0; /* Difference in CPU A24 Base - VME A24 Base */
unsigned long fadcA16Offset = 0x0; /* Difference in CPU A16 Base - VME A16 Base */
volatile struct fadc_struct *FAp[(FA_MAX_BOARDS+1)]; /* pointers to FADC memory map */
volatile struct fadc_sdc_struct *FASDCp; /* pointer to FADC Signal distribution card */
volatile unsigned int *FApd[(FA_MAX_BOARDS+1)]; /* pointers to FADC FIFO memory */
volatile unsigned int *FApmb; /* pointer to Multblock window */
int fadcID[FA_MAX_BOARDS]; /* array of slot numbers for FADCs */
unsigned int fadcAddrList[FA_MAX_BOARDS]; /* array of a24 addresses for FADCs */
int fadcRev[(FA_MAX_BOARDS+1)]; /* Board Revision Info for each module */
int fadcProcRev[(FA_MAX_BOARDS+1)]; /* Processing FPGA Revision Info for each module */
unsigned short fadcChanDisable[(FA_MAX_BOARDS+1)]; /* Disabled Channel Mask for each Module*/
int fadcInited=0; /* >0 if Library has been Initialized before */
int fadcMaxSlot=0; /* Highest Slot hold an FADC */
int fadcMinSlot=0; /* Lowest Slot holding an FADC */
int fadcSource=0; /* Signal source for FADC system control*/
int fadcBlockLevel=0; /* Block Level for ADCs */
int fadcIntCount = 0; /* Count of interrupts from FADC */
int fadcUseSDC=0; /* If > 0 then Use Signal Distribution board */
struct fadc_data_struct fadc_data;
int fadcBlockError=FA_BLOCKERROR_NO_ERROR; /* Whether (>0) or not (0) Block Transfer had an error */
int fadcAlignmentDebug=0; /* Flag to send alignment sequence to CTP */
/* Internal triggering tools */
#include "faItrig.c"
/* Include Firmware Tools */
#include "fadcFirmwareTools.c"
/**
* @defgroup Config Initialization/Configuration
* @defgroup SDCConfig SDC Initialization/Configuration
* @ingroup Config
* @defgroup Status Status
* @defgroup SDCStatus SDC Status
* @ingroup Status
* @defgroup Readout Data Readout
* @defgroup IntPoll Interrupt/Polling
* @defgroup Deprec Deprecated - To be removed
*/
/**
* @ingroup Config
* @brief Initialize JLAB FADC Library.
*
* @param addr
* - A24 VME Address of the fADC250
* @param addr_inc
* - Amount to increment addr to find the next fADC250
* @param nadc
* - Number of times to increment
*
* @param iFlag 18 bit integer
*
* Low 6 bits - Specifies the default Signal distribution (clock,trigger)
* sources for the board (Internal, FrontPanel, VXS, VME(Soft))
* bit 0: defines Sync Reset source
* 0 VME (Software Sync-Reset)
* 1 Front Panel/VXS/P2 (Depends on Clk/Trig source selection)
* bits 3-1: defines Trigger source
* 0 0 0 VME (Software Triggers)
* 0 0 1 Front Panel Input
* 0 1 0 VXS (P0)
* 1 0 0 Internal Trigger Logic (HITSUM FPGA)
* (all others Undefined - default to VME/Software)
* bits 5-4: defines Clock Source
* 0 0 Internal 250MHz Clock
* 0 1 Front Panel
* 1 0 VXS (P0)
* 1 1 P2 Connector (Backplane)
*
*
*
* Common Modes of Operation:
* Value = 0 CLK (Int) TRIG (Soft) SYNC (Soft) (Debug/Test Mode)
* 2 CLK (Int) TRIG (FP) SYNC (Soft) (Single Board
* 3 CLK (Int) TRIG (FP) SYNC (FP) Modes)
* 0x10 CLK (FP) TRIG (Soft) SYNC (Soft)
* 0x13 CLK (FP) TRIG (FP) SYNC (FP) (VME SDC Mode)
* 0x20 CLK (VXS) TRIG (Soft) SYNC (Soft)
* 0x25 CLK (VXS) TRIG (VXS) SYNC (VXS) (VXS SD Mode)
*
*
* High 10bits - A16 Base address of FADC Signal Distribution Module
* This board can control up to 7 FADC Boards.
* Clock Source must be set to Front Panel (bit4 = 1)
*
* bit 16: Exit before board initialization
* 0 Initialize FADC (default behavior)
* 1 Skip initialization (just setup register map pointers)
*
* bit 17: Use fadcAddrList instead of addr and addr_inc
* for VME addresses.
* 0 Initialize with addr and addr_inc
* 1 Use fadcAddrList
*
* bit 18: Skip firmware check. Useful for firmware updating.
* 0 Perform firmware check
* 1 Skip firmware check
*
*
*
* @return OK, or ERROR if the address is invalid or a board is not present.
*/
STATUS
faInit(UINT32 addr, UINT32 addr_inc, int nadc, int iFlag)
{
int ii, res, errFlag = 0;
int boardID = 0;
int maxSlot = 1;
int minSlot = 21;
int trigSrc=0, clkSrc=0, srSrc=0;
unsigned int rdata, a32addr, a16addr=0;
unsigned long laddr=0, laddr_inc=0;
volatile struct fadc_struct *fa;
unsigned short sdata;
int noBoardInit=0;
int useList=0;
int noFirmwareCheck=0;
unsigned short supported_proc[FA_SUPPORTED_PROC_FIRMWARE_NUMBER]
= {FA_SUPPORTED_PROC_FIRMWARE};
unsigned short proc_version=0;
int icheck=0, proc_supported=0;
// Alex
/* Check if we have already Initialized boards before */
if((fadcInited>0) && (fadcID[0] != 0))
{
FALOCK;
/* Hard Reset of all FADC boards in the Crate */
for(ii=0;iicsr),FA_CSR_HARD_RESET);
printf(" Hard Reset Executed on FADC %d \n",FAp[fadcID[ii]]);
}
taskDelay(5);
FAUNLOCK;
}
/* Check if we are to exit when pointers are setup */
noBoardInit=(iFlag&FA_INIT_SKIP)>>16;
/* Check if we're initializing using a list */
useList=(iFlag&FA_INIT_USE_ADDRLIST)>>17;
/* Are we skipping the firmware check? */
noFirmwareCheck=(iFlag&FA_INIT_SKIP_FIRMWARE_CHECK)>>18;
/* Check for valid address */
if(addr==0)
{
printf("faInit: ERROR: Must specify a Bus (VME-based A24) address for FADC 0\n");
return(ERROR);
}
else if(addr > 0x00ffffff)
{ /* A24 Addressing */
printf("faInit: ERROR: A32 Addressing not allowed for FADC configuration space\n");
return(ERROR);
}
else
{ /* A24 Addressing */
if( ((addr_inc==0)||(nadc==0)) && (useList==0) )
nadc = 1; /* assume only one FADC to initialize */
/* get the FADC address */
#ifdef VXWORKS
res = sysBusToLocalAdrs(0x39,(char *)addr,(char **)&laddr);
#else
res = vmeBusToLocalAdrs(0x39,(char *)(unsigned long)addr,(char **)&laddr);
#endif
if (res != 0)
{
#ifdef VXWORKS
printf("faInit: ERROR in sysBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr);
#else
printf("faInit: ERROR in vmeBusToLocalAdrs(0x39,0x%x,&laddr) \n",addr);
#endif
return(ERROR);
}
fadcA24Offset = laddr - addr;
}
/* Init Some Global variables */
fadcSource = iFlag&FA_SOURCE_MASK;
fadcInited = nfadc = 0;
fadcUseSDC = 0;
bzero((char *)fadcChanDisable,sizeof(fadcChanDisable));
bzero((char *)fadcID,sizeof(fadcID));
for (ii=0;iiversion),VX_READ,4,(char *)&rdata);
#else
res = vmeMemProbe((char *) &(fa->version),4,(char *)&rdata);
#endif
if(res < 0)
{
#ifdef VXWORKS
printf("faInit: WARN: No addressable board at addr=0x%x\n",(UINT32) fa);
#else
printf("faInit: WARN: No addressable board at VME (Local) addr=0x%x (0x%lx)\n",
(UINT32)(laddr_inc-fadcA24Offset), (unsigned long) fa);
#endif
errFlag = 1;
continue;
}
else
{
/* Check that it is an FA board */
if((rdata&FA_BOARD_MASK) != FA_BOARD_ID)
{
printf("%s: WARN: For board at 0x%x, Invalid Board ID: 0x%x\n",
__FUNCTION__,
(UINT32)(laddr_inc-fadcA24Offset), rdata);
continue;
}
else
{
/* Check if this is board has a valid slot number */
boardID = ((vmeRead32(&(fa->intr)))&FA_SLOT_ID_MASK)>>16;
if((boardID <= 0)||(boardID >21))
{
printf("%s: ERROR: For Board at 0x%x, Slot number is not in range: %d\n",
__FUNCTION__,(UINT32)(laddr_inc-fadcA24Offset), boardID);
continue;
}
if(!noFirmwareCheck)
{
/* Check Control FPGA firmware version */
if( (rdata&FA_VERSION_MASK) < FA_SUPPORTED_CTRL_FIRMWARE )
{
printf("%s: ERROR: Slot %2d: Control FPGA Firmware (0x%02x) not supported by this driver.\n",
__FUNCTION__,boardID, rdata & FA_VERSION_MASK);
printf("\tUpdate to 0x%02x to use this driver.\n",FA_SUPPORTED_CTRL_FIRMWARE);
continue;
}
/* Check Processing FPGA firmware version */
proc_version =
(unsigned short)(vmeRead32(&fa->adc_status[0]) & FA_ADC_VERSION_MASK);
for(icheck=0; icheckadc_status[0]) & FA_ADC_VERSION_MASK);
for(icheck=0; icheck= maxSlot) maxSlot = boardID;
if(boardID <= minSlot) minSlot = boardID;
printf("Initialized FADC %2d Slot #%2d at VME (Local) address 0x%06x (0x%lx) \n",
nfadc,fadcID[nfadc],
(UINT32) (((unsigned long)FAp[(fadcID[nfadc])])-fadcA24Offset),
(unsigned long) FAp[(fadcID[nfadc])]);
}
nfadc++;
}
}
// Alex
// for(ii = 3;ii < 11;ii++){
// vmeWrite32(&(FAp[ii]->csr),FA_CSR_HARD_RESET);
// printf(" Hard Reset Executed on FADC %d \n",FAp[ii]);
// }
// for(ii = 13;ii < 16;ii++){
// vmeWrite32(&(FAp[ii]->csr),FA_CSR_HARD_RESET);
// printf(" Hard Reset Executed on FADC %d \n",FAp[ii]);
// }
/* Check if we are using a JLAB FADC Signal Distribution Card (SDC)
NOTE the SDC board only supports 7 FADCs - so if there are
more than 7 FADCs in the crate they can only be controlled by daisychaining
multiple SDCs together - or by using a VXS Crate with SD switch card
*/
a16addr = iFlag&FA_SDC_ADR_MASK;
if(a16addr)
{
#ifdef VXWORKS
res = sysBusToLocalAdrs(0x29,(char *)a16addr,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in sysBusToLocalAdrs(0x29,0x%x,&laddr) \n",a16addr);
return(ERROR);
}
res = vxMemProbe((char *) laddr,VX_READ,2,(char *)&sdata);
#else
res = vmeBusToLocalAdrs(0x29,(char *)(unsigned long)a16addr,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in vmeBusToLocalAdrs(0x29,0x%x,&laddr) \n",a16addr);
return(ERROR);
}
res = vmeMemProbe((char *) laddr,2,(char *)&sdata);
#endif
if(res < 0)
{
printf("faInit: ERROR: No addressable SDC board at addr=0x%x\n",(UINT32) laddr);
}
else
{
fadcA16Offset = laddr-a16addr;
FASDCp = (struct fadc_sdc_struct *) laddr;
if(!noBoardInit)
vmeWrite16(&(FASDCp->ctrl),FASDC_CSR_INIT); /* Reset the Module */
if(nfadc>7)
{
printf("WARN: A Single JLAB FADC Signal Distribution Module only supports 7 FADCs\n");
printf("WARN: You must use multiple SDCs to support more FADCs - this must be configured in hardware\n");
}
#ifdef VXWORKS
printf("Using JLAB FADC Signal Distribution Module at address 0x%x\n",
(UINT32) FASDCp);
#else
printf("Using JLAB FADC Signal Distribution Module at VME (Local) address 0x%x (0x%lx)\n",
(UINT32)a16addr, (unsigned long) FASDCp);
#endif
fadcUseSDC=1;
}
if(fadcSource == FA_SOURCE_SDC)
{ /* Check if SDC will be used */
fadcUseSDC = 1;
printf("faInit: JLAB FADC Signal Distribution Card is Assumed in Use\n");
printf("faInit: Front Panel Inputs will be enabled. \n");
}
else
{
fadcUseSDC = 0;
printf("faInit: JLAB FADC Signal Distribution Card will not be Used\n");
}
}
/* Hard Reset of all FADC boards in the Crate */
if(!noBoardInit)
{
for(ii=0;iireset),FA_RESET_ALL);
}
taskDelay(60);
}
/* Initialize Interrupt variables */
fadcIntID = -1;
fadcIntRunning = FALSE;
fadcIntLevel = FA_VME_INT_LEVEL;
fadcIntVec = FA_VME_INT_VEC;
fadcIntRoutine = NULL;
fadcIntArg = 0;
/* Calculate the A32 Offset for use in Block Transfers */
#ifdef VXWORKS
res = sysBusToLocalAdrs(0x09,(char *)fadcA32Base,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",fadcA32Base);
return(ERROR);
}
else
{
fadcA32Offset = laddr - fadcA32Base;
}
#else
res = vmeBusToLocalAdrs(0x09,(char *)(unsigned long)fadcA32Base,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in vmeBusToLocalAdrs(0x09,0x%x,&laddr) \n",fadcA32Base);
return(ERROR);
}
else
{
fadcA32Offset = laddr - fadcA32Base;
}
#endif
if(!noBoardInit)
{
/* what are the Trigger Sync Reset and Clock sources */
if (fadcSource == FA_SOURCE_VXS)
{
printf("faInit: Enabling FADC for VXS Clock ");
clkSrc = FA_REF_CLK_P0;
switch (iFlag&0xf)
{
case 0: case 1:
printf("and Software Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_VME | FA_ENABLE_SOFT_TRIG;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 2:
printf("and Front Panel Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 3:
printf("and Front Panel Triggers (FP Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_FP_ISYNC;
break;
case 4: case 6:
printf("and VXS Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_P0_ISYNC;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 5: case 7:
printf("and VXS Triggers (VXS Sync Reset)\n");
trigSrc = FA_TRIG_P0_ISYNC;
srSrc = FA_SRESET_P0_ISYNC;
break;
case 8: case 10: case 12: case 14:
printf("and Internal Trigger Logic (Soft Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 9: case 11: case 13: case 15:
printf("and Internal Trigger Logic (VXS Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_FP_ISYNC;
break;
}
}
else if (fadcSource == FA_SOURCE_SDC)
{
printf("faInit: Enabling FADC for SDC Clock (Front Panel) ");
clkSrc = FA_REF_CLK_FP;
switch (iFlag&0xf)
{
case 0: case 1:
printf("and Software Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_VME | FA_ENABLE_SOFT_TRIG;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 2: case 4: case 6:
printf("and Front Panel Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 3: case 5: case 7:
printf("and Front Panel Triggers (FP Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_FP_ISYNC;
break;
case 8: case 10: case 12: case 14:
printf("and Internal Trigger Logic (Soft Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 9: case 11: case 13: case 15:
printf("and Internal Trigger Logic (Front Panel Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_FP_ISYNC;
break;
}
faSDC_Config(0,0);
}
else
{ /* Use internal Clk */
printf("faInit: Enabling FADC Internal Clock, ");
clkSrc = FA_REF_CLK_INTERNAL;
switch (iFlag&0xf)
{
case 0: case 1:
printf("and Software Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_VME | FA_ENABLE_SOFT_TRIG;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET ;
break;
case 2:
printf("and Front Panel Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 3:
printf("and Front Panel Triggers (FP Sync Reset)\n");
trigSrc = FA_TRIG_FP_ISYNC;
srSrc = FA_SRESET_FP_ISYNC;
break;
case 4: case 6:
printf("and VXS Triggers (Soft Sync Reset)\n");
trigSrc = FA_TRIG_P0_ISYNC;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 5: case 7:
printf("and VXS Triggers (VXS Sync Reset)\n");
trigSrc = FA_TRIG_P0_ISYNC;
srSrc = FA_SRESET_P0_ISYNC;
break;
case 8: case 10: case 12: case 14:
printf("and Internal Trigger Logic (Soft Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_VME | FA_ENABLE_SOFT_SRESET;
break;
case 9: case 11: case 13: case 15:
printf("and Internal Trigger Logic (Front Panel Sync Reset)\n");
trigSrc = FA_TRIG_INTERNAL;
srSrc = FA_SRESET_FP_ISYNC;
break;
}
}
}
/* Enable Clock source - Internal Clk enabled by default */
if(!noBoardInit)
{
for(ii=0;iictrl1),(clkSrc | FA_ENABLE_INTERNAL_CLK)) ;
}
taskDelay(20);
/* Hard Reset FPGAs and FIFOs */
for(ii=0;iireset),
(FA_RESET_ADC_FPGA1 | FA_RESET_ADC_FIFO1 |
FA_RESET_DAC | FA_RESET_EXT_RAM_PT));
/* Release reset on MGTs */
vmeWrite32(&(FAp[fadcID[ii]]->mgt_ctrl),FA_RELEASE_MGT_RESET);
vmeWrite32(&(FAp[fadcID[ii]]->mgt_ctrl),FA_MGT_RESET);
vmeWrite32(&(FAp[fadcID[ii]]->mgt_ctrl),FA_RELEASE_MGT_RESET);
}
taskDelay(5);
}
/* Write configuration registers with default/defined Sources */
for(ii=0;iiadr32),(a32addr>>16) + 1); /* Write the register and enable */
/* Set Default Block Level to 1 */
vmeWrite32(&(FAp[fadcID[ii]]->blk_level),1);
}
fadcBlockLevel=1;
/* Setup Trigger and Sync Reset sources */
if(!noBoardInit)
{
vmeWrite32(&(FAp[fadcID[ii]]->ctrl1),
vmeRead32(&(FAp[fadcID[ii]]->ctrl1)) |
(srSrc | trigSrc) );
}
/* Set default stop and busy conditions (modified in faSetProcMode(..)) */
faSetTriggerStopCondition(fadcID[ii], 9);
faSetTriggerBusyCondition(fadcID[ii], 9);
}
/* If there are more than 1 FADC in the crate then setup the Muliblock Address
window. This must be the same on each board in the crate */
if(nfadc > 1)
{
a32addr = fadcA32Base + (nfadc+1)*FA_MAX_A32_MEM; /* set MB base above individual board base */
#ifdef VXWORKS
res = sysBusToLocalAdrs(0x09,(char *)a32addr,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in sysBusToLocalAdrs(0x09,0x%x,&laddr) \n",a32addr);
return(ERROR);
}
#else
res = vmeBusToLocalAdrs(0x09,(char *)(unsigned long)a32addr,(char **)&laddr);
if (res != 0)
{
printf("faInit: ERROR in vmeBusToLocalAdrs(0x09,0x%x,&laddr) \n",a32addr);
return(ERROR);
}
#endif
FApmb = (unsigned int *)(laddr); /* Set a pointer to the FIFO */
if(!noBoardInit)
{
for (ii=0;iiadr_mb),
(a32addr+FA_MAX_A32MB_SIZE) + (a32addr>>16) + FA_A32_ENABLE);
}
}
/* Set First Board and Last Board */
fadcMaxSlot = maxSlot;
fadcMinSlot = minSlot;
if(!noBoardInit)
{
vmeWrite32(&(FAp[minSlot]->ctrl1),
vmeRead32(&(FAp[minSlot]->ctrl1)) | FA_FIRST_BOARD);
vmeWrite32(&(FAp[maxSlot]->ctrl1),
vmeRead32(&(FAp[maxSlot]->ctrl1)) | FA_LAST_BOARD);
}
}
if(!noBoardInit)
fadcInited = nfadc;
if(errFlag > 0)
{
printf("faInit: WARN: Unable to initialize all requested FADC Modules (%d)\n",
nadc);
if(nfadc > 0)
printf("faInit: %d FADC(s) successfully initialized\n",nfadc );
return(ERROR);
}
else
{
return(OK);
}
}
int
faCheckAddresses(int id)
{
unsigned long offset=0, expected=0, base=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
printf("%s:\n\t ---------- Checking fADC250 address space ---------- \n",__FUNCTION__);
base = (unsigned long) &FAp[id]->version;
offset = ((unsigned long) &FAp[id]->system_monitor) - base;
expected = 0xFC;
if(offset != expected)
printf("%s: ERROR FAp[id]->system_monitor not at offset = 0x%lx (@ 0x%lx)\n",
__FUNCTION__,expected,offset);
offset = ((unsigned long) &FAp[id]->adc_status[0]) - base;
expected = 0x100;
if(offset != expected)
printf("%s: ERROR FAp[id]->adc_status[0] not at offset = 0x%lx (@ 0x%lx)\n",
__FUNCTION__,expected,offset);
offset = ((unsigned long) &FAp[id]->config7) - base;
expected = 0x150;
if(offset != expected)
printf("%s: ERROR FAp[id]->config7 not at offset = 0x%lx (@ 0x%lx)\n",
__FUNCTION__,expected,offset);
offset = ((unsigned long) &FAp[id]->adc_pedestal[0]) - base;
expected = 0x158;
if(offset != expected)
printf("%s: ERROR FAp[id]->adc_pedestal[0] not at offset = 0x%lx (@ 0x%lx)\n",
__FUNCTION__,expected,offset);
offset = ((unsigned long) &FAp[id]->scaler[0]) - base;
expected = 0x300;
if(offset != expected)
printf("%s: ERROR FAp[id]->scaler[0] not at offset = 0x%lx (@ 0x%lx)\n",
__FUNCTION__,expected,offset);
return OK;
}
/**
* @ingroup Config
* @brief Convert an index into a slot number, where the index is
* the element of an array of FADCs in the order in which they were
* initialized.
*
* @param i Initialization number
* @return Slot number if Successfull, otherwise ERROR.
*
*/
int
faSlot(unsigned int i)
{
if(i>=nfadc)
{
printf("%s: ERROR: Index (%d) >= FADCs initialized (%d).\n",
__FUNCTION__,i,nfadc);
return ERROR;
}
return fadcID[i];
}
/**
* @ingroup Config
* @brief Set the clock source
*
* This routine should be used in the case that the source clock
* is NOT set in faInit (and defaults to Internal). Such is the case
* when clocks are synchronized in a many crate system. The clock source
* of the FADC should ONLY be set AFTER those clocks have been set and
* synchronized.
*
* @param id Slot Number
* @param clkSrc 2 bit integer
*
* bits 1-0: defines Clock Source
* 0 0 Internal 250MHz Clock
* 0 1 Front Panel
* 1 0 VXS (P0)
* 1 1 VXS (P0)
*
*
* @return OK if successful, otherwise ERROR.
*/
int
faSetClockSource(int id, int clkSrc)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
if(clkSrc>0x3)
{
printf("%s: ERROR: Invalid Clock Source specified (0x%x)\n",
__FUNCTION__,clkSrc);
return ERROR;
}
/* Enable Clock source - Internal Clk enabled by default */
vmeWrite32(&(FAp[id]->ctrl1),
(vmeRead32(&FAp[id]->ctrl1) & ~(FA_REF_CLK_MASK)) |
(clkSrc | FA_ENABLE_INTERNAL_CLK)) ;
taskDelay(20);
switch(clkSrc)
{
case FA_REF_CLK_INTERNAL:
printf("%s: FADC id %d clock source set to INTERNAL\n",
__FUNCTION__,id);
break;
case FA_REF_CLK_FP:
printf("%s: FADC id %d clock source set to FRONT PANEL\n",
__FUNCTION__,id);
break;
case FA_REF_CLK_P0:
printf("%s: FADC id %d clock source set to VXS (P0)\n",
__FUNCTION__,id);
break;
case FA_REF_CLK_MASK:
printf("%s: FADC id %d clock source set to VXS (P0)\n",
__FUNCTION__,id);
break;
}
return OK;
}
/**
* @ingroup Status
* @brief Print Status of fADC250 to standard out
* @param id Slot Number
* @param sflag Not yet used.
*
*/
void
faStatus(int id, int sflag)
{
int ii;
unsigned int a32Base, ambMin, ambMax, vers, bid, brev;
unsigned int csr, ctrl1, ctrl2, count, bcount, blevel, intr, addr32, addrMB;
unsigned int adcStat[3], adcConf[3],
PTW, PL, NSB, NSA, NSA_tp, NP, adcChanDisabled, playbackMode;
unsigned int nsb_reg, nsa_reg;
unsigned int adc_enabled, adc_version, adc_option;
unsigned int trigCnt, trig2Cnt, srCnt, itrigCnt, ramWords;
unsigned int mgtStatus;
unsigned int berr_count=0;
unsigned int scaler_interval=0;
unsigned int threshold_tp;
unsigned int trigger_control=0;
unsigned int lost_trig_scal=0;
float ctrl_temp=0., proc_temp=0.;
float core_volt=0., aux_volt=0.;
unsigned int NPED, MAXPED, NSAT;
unsigned int MNPED, MMAXPED;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return;
}
FALOCK;
vers = vmeRead32(&FAp[id]->version);
bid = ((vers)&FA_BOARD_MASK)>>16;
brev = (vers)&FA_VERSION_MASK;
csr = (vmeRead32(&(FAp[id]->csr)))&FA_CSR_MASK;
ctrl1 = (vmeRead32(&(FAp[id]->ctrl1)))&FA_CONTROL_MASK;
ctrl2 = (vmeRead32(&(FAp[id]->ctrl2)))&FA_CONTROL2_MASK;
count = (vmeRead32(&(FAp[id]->ev_count)))&FA_EVENT_COUNT_MASK;
bcount = (vmeRead32(&(FAp[id]->blk_count)))&FA_BLOCK_COUNT_MASK;
blevel = (vmeRead32(&(FAp[id]->blk_level)))&FA_BLOCK_LEVEL_MASK;
ramWords = (vmeRead32(&(FAp[id]->ram_word_count)))&FA_RAM_DATA_MASK;
itrigCnt = vmeRead32(&FAp[id]->internal_trig_scal);
trigCnt = vmeRead32(&(FAp[id]->trig_scal));
trig2Cnt = vmeRead32(&FAp[id]->trig2_scal);
srCnt = vmeRead32(&FAp[id]->syncreset_scal);
intr = vmeRead32(&(FAp[id]->intr));
addr32 = vmeRead32(&(FAp[id]->adr32));
a32Base = (addr32&FA_A32_ADDR_MASK)<<16;
addrMB = vmeRead32(&(FAp[id]->adr_mb));
ambMin = (addrMB&FA_AMB_MIN_MASK)<<16;
ambMax = (addrMB&FA_AMB_MAX_MASK);
berr_count = vmeRead32(&(FAp[id]->berr_module_scal));
for(ii=0;ii<3;ii++)
{
adcStat[ii] = (vmeRead32(&(FAp[id]->adc_status[ii]))&0xFFFF);
adcConf[ii] = (vmeRead32(&(FAp[id]->adc_config[ii]))&0xFFFF);
}
PTW = ((vmeRead32(&(FAp[id]->adc_ptw))&0xFFFF + 1))*FA_ADC_NS_PER_CLK;
PL = (vmeRead32(&(FAp[id]->adc_pl))&0xFFFF)*FA_ADC_NS_PER_CLK;
nsb_reg = (vmeRead32(&(FAp[id]->adc_nsb))&0xFFFF);
nsa_reg = (vmeRead32(&(FAp[id]->adc_nsa))&0xFFFF);
NSB = (nsb_reg&FA_ADC_NSB_READBACK_MASK)*FA_ADC_NS_PER_CLK;
NSA = (nsa_reg&FA_ADC_NSA_READBACK_MASK)*FA_ADC_NS_PER_CLK;
NSA_tp = ((nsa_reg&FA_ADC_TNSA_MASK)>>9)*FA_ADC_NS_PER_CLK;
adc_version = adcStat[0]&FA_ADC_VERSION_MASK;
// Alex
// adc_option = (adcConf[0]&FA_ADC_PROC_MASK) + 1;
adc_option = (adcConf[0] & FA_ADC_PROC_MASK)>>8 ? 10 :9;
NP = ( ((adcConf[0]&FA_ADC_PEAK_MASK)>>4) + 1);
adc_enabled = (adcConf[0]&FA_ADC_PROC_ENABLE);
playbackMode = (adcConf[0]&FA_ADC_PLAYBACK_MODE)>>7;
adcChanDisabled = (adcConf[1]&FA_ADC_CHAN_MASK);
threshold_tp = vmeRead32(&FAp[id]->config3)&FA_ADC_TPT_MASK;
NPED = (vmeRead32(&FAp[id]->config7) & FA_ADC_CONFIG7_NPED_MASK)>>10;
MAXPED = vmeRead32(&FAp[id]->config7) & FA_ADC_CONFIG7_MAXPED_MASK;
NSAT = ( ((adcConf[0] & FA_ADC_CONFIG1_NSAT_MASK)>>10) + 1);
mgtStatus = vmeRead32(&(FAp[id]->mgt_status));
scaler_interval = vmeRead32(&FAp[id]->scaler_interval) & FA_SCALER_INTERVAL_MASK;
trigger_control = vmeRead32(&FAp[id]->trigger_control);
lost_trig_scal = vmeRead32(&FAp[id]->lost_trig_scal);
MNPED = ( ((vmeRead32(&FAp[id]->config6) & 0x3C00)>>10) + 1);
MMAXPED = (vmeRead32(&FAp[id]->config6) & 0x3FF);
FAUNLOCK;
ctrl_temp = faGetCtrlFPGATemp(id,0);
proc_temp = faGetProcFPGATemp(id,0);
core_volt = faGetCtrlFPGAVoltage(id,0,0);
aux_volt = faGetCtrlFPGAVoltage(id,1,0);
#ifdef VXWORKS
printf("\nSTATUS for FADC in slot %d at base address 0x%x \n",
id, (UINT32) FAp[id]);
#else
printf("\nSTATUS for FADC in slot %d at VME (Local) base address 0x%x (0x%lx)\n",
id, (UINT32)(unsigned long)(FAp[id] - fadcA24Offset), (unsigned long) FAp[id]);
#endif
printf("---------------------------------------------------------------------- \n");
printf(" Board Firmware Rev/ID = 0x%04x : ADC Processing Rev = 0x%04x\n",
(vers)&0xffff, adc_version);
if(addrMB&FA_AMB_ENABLE)
{
printf(" Alternate VME Addressing: Multiblock Enabled\n");
if(addr32&FA_A32_ENABLE)
printf(" A32 Enabled at VME (Local) base 0x%08x (0x%lx)\n",a32Base,(unsigned long) FApd[id]);
else
printf(" A32 Disabled\n");
printf(" Multiblock VME Address Range 0x%08x - 0x%08x\n",ambMin,ambMax);
}
else
{
printf(" Alternate VME Addressing: Multiblock Disabled\n");
if(addr32&FA_A32_ENABLE)
printf(" A32 Enabled at VME (Local) base 0x%08x (0x%lx)\n",a32Base,(unsigned long) FApd[id]);
else
printf(" A32 Disabled\n");
}
if(ctrl1&FA_INT_ENABLE_MASK)
{
printf("\n Interrupts ENABLED: ");
if(ctrl1&FA_ENABLE_BLKLVL_INT) printf(" on Block Level(%d)",blevel);
printf("\n");
printf(" Interrupt Reg: 0x%08x\n",intr);
printf(" VME INT Vector = 0x%x Level = %d\n",(intr&FA_INT_VEC_MASK),((intr&FA_INT_LEVEL_MASK)>>8));
}
printf("\n Signal Sources: \n");
if((ctrl1&FA_REF_CLK_MASK)==FA_REF_CLK_INTERNAL)
{
printf(" Ref Clock : Internal\n");
}
else if((ctrl1&FA_REF_CLK_MASK)==FA_REF_CLK_P0)
{
printf(" Ref Clock : VXS\n");
}
else if((ctrl1&FA_REF_CLK_MASK)==FA_REF_CLK_FP)
{
printf(" Ref Clock : Front Panel\n");
}
else
{
printf(" Ref Clock : %d (Undefined)\n",(ctrl1&FA_REF_CLK_MASK));
}
switch(ctrl1&FA_TRIG_MASK)
{
case FA_TRIG_INTERNAL:
printf(" Trig Src : Internal\n");
break;
case FA_TRIG_VME:
printf(" Trig Src : VME (Software)\n");
break;
case FA_TRIG_P0_ISYNC:
printf(" Trig Src : VXS (Async)\n");
break;
case FA_TRIG_P0:
printf(" Trig Src : VXS (Sync)\n");
break;
case FA_TRIG_FP_ISYNC:
printf(" Trig Src : Front Panel (Async)\n");
break;
case FA_TRIG_FP:
printf(" Trig Src : Front Panel (Sync)\n");
}
switch(ctrl1&FA_SRESET_MASK)
{
case FA_SRESET_VME:
printf(" Sync Reset: VME (Software)\n");
break;
case FA_SRESET_P0_ISYNC:
printf(" Sync Reset: VXS (Async)\n");
break;
case FA_SRESET_P0:
printf(" Sync Reset: VXS (Sync)\n");
break;
case FA_SRESET_FP_ISYNC:
printf(" Sync Reset: Front Panel (Async)\n");
break;
case FA_SRESET_FP:
printf(" Sync Reset: Front Panel (Sync)\n");
}
if(fadcUseSDC)
{
printf(" SDC : In Use\n");
}
printf("\n Configuration: \n");
if(ctrl1&FA_ENABLE_INTERNAL_CLK)
printf(" Internal Clock ON\n");
else
printf(" Internal Clock OFF\n");
if(ctrl1&FA_ENABLE_BERR)
printf(" Bus Error ENABLED\n");
else
printf(" Bus Error DISABLED\n");
if(ctrl1&FA_ENABLE_MULTIBLOCK)
{
int tP0, tP2;
tP0 = ctrl1&FA_MB_TOKEN_VIA_P0;
tP2 = ctrl1&FA_MB_TOKEN_VIA_P2;
if(tP0)
{
if(ctrl1&FA_FIRST_BOARD)
printf(" MultiBlock transfer ENABLED (First Board - token via VXS)\n");
else if(ctrl1&FA_LAST_BOARD)
printf(" MultiBlock transfer ENABLED (Last Board - token via VXS)\n");
else
printf(" MultiBlock transfer ENABLED (Token via VXS)\n");
}
else if(tP2)
{
if(ctrl1&FA_FIRST_BOARD)
printf(" MultiBlock transfer ENABLED (First Board - token via P2)\n");
else if(ctrl1&FA_LAST_BOARD)
printf(" MultiBlock transfer ENABLED (Last Board - token via P2)\n");
else
printf(" MultiBlock transfer ENABLED (Token via P2)\n");
}
else
{
printf(" MultiBlock transfer ENABLED (**NO Tokens enabled**)\n");
}
}
else
{
printf(" MultiBlock transfer DISABLED\n");
}
if(ctrl1&FA_ENABLE_SOFT_TRIG)
printf(" Software Triggers ENABLED\n");
if(ctrl1&FA_ENABLE_SOFT_SRESET)
printf(" Software Sync Reset ENABLED\n");
printf("\n ADC Processing Configuration: \n");
printf(" Channel Disable Mask = 0x%04x\n",adcChanDisabled);
printf(" Mode = %d (%s) - %s \n",
adc_option,
fa_mode_names[adc_option],
(adc_enabled)?"ENABLED":"Disabled");
printf(" Lookback (PL) = %d ns Time Window (PTW) = %d ns\n",PL, PTW );
printf(" Time Before Peak (NSB) = %d ns Time After Peak (NSA) = %d ns\n",NSB,NSA);
printf(" Max Peak Count (MNoP) = %d \n",NP);
printf(" Samples in Pulse Pedestal Sum (NPED) = %d\n",
NPED + 1);
printf(" Max Pedestal for readback pedestal sum (MAXPED) = %d\n",
MAXPED);
printf(" Number of Samples over TET required (NSAT) = %d\n",
NSAT);
printf("\n");
printf(" Playback Mode = %s \n",
(playbackMode)?"Enabled":"Disabled");
printf("\n");
printf(" Trigger Path Parameters:\n");
printf(" Time After Peak (TNSA) = %d ns\n", NSA_tp);
printf(" Threshold (TPT) = %d \n", threshold_tp);
printf(" Samples over TPT (TNSAT) = %d \n",
((adcConf[0] & FA_ADC_CONFIG1_TNSAT_MASK)>>12) + 1);
printf(" Monitoring (MNPED) = %d \n", MNPED);
printf(" Monitoring (MMAXPED) = %d \n", MMAXPED);
printf("\n");
printf(" Unacknowleged Trigger Stop: %s (%d)\n",
(trigger_control&FA_TRIGCTL_TRIGSTOP_EN) ? " ENABLED" : "DISABLED",
(trigger_control&FA_TRIGCTL_MAX2_MASK)>>16);
printf(" Unacknowleged Trigger Busy: %s (%d)\n",
(trigger_control&FA_TRIGCTL_BUSY_EN) ? " ENABLED" : "DISABLED",
trigger_control&FA_TRIGCTL_MAX1_MASK);
printf("\n");
if(csr&FA_CSR_ERROR_MASK)
{
printf(" CSR Register = 0x%08x - **Error Condition**\n",csr);
}
else
{
printf(" CSR Register = 0x%08x\n",csr);
}
printf(" Control 1 Register = 0x%08x \n",ctrl1);
if((ctrl2&FA_CTRL_ENABLE_MASK)==FA_CTRL_ENABLED)
{
printf(" Control 2 Register = 0x%08x - Enabled for triggers\n",ctrl2);
}
else
{
printf(" Control 2 Register = 0x%08x - Disabled\n",ctrl2);
}
printf(" Internal Triggers (Live) = %d\n",itrigCnt);
printf(" Trigger Scaler = %d\n",trigCnt);
printf(" Trigger 2 Scaler = %d\n",trig2Cnt);
printf(" SyncReset Scaler = %d\n",srCnt);
if(trigger_control & (FA_TRIGCTL_TRIGSTOP_EN | FA_TRIGCTL_BUSY_EN))
{
printf(" Lost Trigger Scaler = %d\n",lost_trig_scal);
}
if(scaler_interval)
{
printf(" Block interval for scaler events = %d\n",scaler_interval);
}
if(csr&FA_CSR_BLOCK_READY)
{
printf(" Blocks in FIFO = %d (Block level = %d) - Block Available\n",bcount,blevel);
printf(" RAM Level (Bytes) = %d \n",(ramWords*8));
}
else if (csr&FA_CSR_EVENT_AVAILABLE)
{
printf(" Events in FIFO = %d (Block level = %d) - Data Available\n",count,blevel);
printf(" RAM Level (Bytes) = %d \n",(ramWords*8));
}
else
{
printf(" Events in FIFO = %d (Block level = %d)\n",count,blevel);
}
printf(" MGT Status Register = 0x%08x ",mgtStatus);
if(mgtStatus & (FA_MGT_GTX1_HARD_ERROR | FA_MGT_GTX1_SOFT_ERROR |
FA_MGT_GTX2_HARD_ERROR | FA_MGT_GTX2_SOFT_ERROR))
printf(" - **Error Condition**\n");
else
printf("\n");
printf(" BERR count (from module) = %d\n",berr_count);
printf(" CTRL Temp = %3.2f [C] PROC Temp = %3.2f [C]\n",ctrl_temp,proc_temp);
printf(" CTRL Core = %3.2f [V] CTRL AUX = %3.2f [V]\n",core_volt,aux_volt);
}
/**
* @ingroup Status
* @brief Print a summary of all initialized fADC250s
* @param sflag Not yet used
*/
void
faGStatus(int sflag)
{
int ifa, id, ii;
struct fadc_struct st[FA_MAX_BOARDS+1];
unsigned int a24addr[FA_MAX_BOARDS+1];
float temp[FA_MAX_BOARDS+1][2];
float volt[FA_MAX_BOARDS+1][2];
FALOCK;
for (ifa=0;ifaversion);
st[id].adr32 = vmeRead32(&FAp[id]->adr32);
st[id].adr_mb = vmeRead32(&FAp[id]->adr_mb);
st[id].ctrl1 = vmeRead32(&FAp[id]->ctrl1);
st[id].ctrl2 = vmeRead32(&FAp[id]->ctrl2);
st[id].csr = vmeRead32(&FAp[id]->csr);
st[id].config6 = vmeRead32(&FAp[id]->config6);
st[id].config7 = vmeRead32(&FAp[id]->config7);
for(ii=0;ii<3;ii++)
{
st[id].adc_status[ii] = vmeRead32(&FAp[id]->adc_status[ii])&0xFFFF;
st[id].adc_config[ii] = vmeRead32(&FAp[id]->adc_config[ii])&0xFFFF;
}
st[id].adc_ptw = vmeRead32(&FAp[id]->adc_ptw);
st[id].adc_pl = vmeRead32(&FAp[id]->adc_pl);
st[id].adc_nsb = vmeRead32(&FAp[id]->adc_nsb);
st[id].adc_nsa = vmeRead32(&FAp[id]->adc_nsa);
st[id].config3 = vmeRead32(&FAp[id]->config3);
st[id].blk_count = vmeRead32(&FAp[id]->blk_count);
st[id].blk_level = vmeRead32(&FAp[id]->blk_level);
st[id].ram_word_count = vmeRead32(&FAp[id]->ram_word_count)&FA_RAM_DATA_MASK;
st[id].trig_scal = vmeRead32(&(FAp[id]->trig_scal));
st[id].trig2_scal = vmeRead32(&FAp[id]->trig2_scal);
st[id].syncreset_scal = vmeRead32(&FAp[id]->syncreset_scal);
st[id].berr_module_scal = vmeRead32(&FAp[id]->berr_module_scal);
st[id].lost_trig_scal = vmeRead32(&FAp[id]->lost_trig_scal);
st[id].mgt_status = vmeRead32(&FAp[id]->mgt_status);
for(ii = 0;ii < FA_MAX_ADC_CHANNELS;ii++){
st[id].adc_pedestal[ii] = vmeRead32(&FAp[id]->adc_pedestal[ii]) & FA_ADC_PEDESTAL_MASK;
}
}
FAUNLOCK;
for (ifa=0;ifa>8 ? 10 : 9);
printf("%4d ", (st[id].adc_pl & 0xFFFF)*FA_ADC_NS_PER_CLK);
printf("%4d ", ((st[id].adc_ptw & 0xFFFF) + 1)*FA_ADC_NS_PER_CLK);
printf("%3d ", (st[id].adc_nsb & FA_ADC_NSB_READBACK_MASK)*FA_ADC_NS_PER_CLK);
printf("%3d ", (st[id].adc_nsa & FA_ADC_NSB_READBACK_MASK)*FA_ADC_NS_PER_CLK);
printf("%1d ", ((st[id].adc_config[0] & FA_ADC_PEAK_MASK)>>4) + 1);
printf("%2d ", (((st[id].config7 & FA_ADC_CONFIG7_NPED_MASK)>>10) + 1)*FA_ADC_NS_PER_CLK);
printf("%4d ", st[id].config7 & FA_ADC_CONFIG7_MAXPED_MASK);
printf("%d ", ((st[id].adc_config[0] & FA_ADC_CONFIG1_NSAT_MASK)>>10) + 1);
printf("%s ",
(st[id].adc_config[0] &FA_ADC_PLAYBACK_MODE)>>7 ?" Enabled":"Disabled");
printf("\n");
}
printf("--------------------------------------------------------------------------------\n");
printf("\n");
printf(" fADC250 Trigger Path Processing Config\n\n");
printf(" [ns] \n");
printf("Slot TNSA TPT TNSAT MNPED MMAXPED \n");
printf("--------------------------------------------------------------------------------\n");
for(ifa=0; ifa>9)*FA_ADC_NS_PER_CLK);
printf("%4d ", st[id].config3 & FA_ADC_TPT_MASK);
printf("%d ", (((st[id].adc_config[0] &FA_ADC_CONFIG1_TNSAT_MASK)>>12) + 1));
printf("%4d ", (( (st[id].config6 & 0x3C00 )>>10) + 1));
printf("%4d ", ( st[id].config6 & 0x3FF ));
printf("\n");
}
printf("--------------------------------------------------------------------------------\n");
printf("\n");
printf(" fADC250 Signal Scalers\n\n");
printf("Slot Trig1 Trig2 SyncReset BERR Lost Triggers\n");
printf("--------------------------------------------------------------------------------\n");
for(ifa=0; ifa21) || (FAp[id] == NULL))
{
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return(ERROR);
}
FALOCK;
/* Control FPGA firmware version */
cntl = vmeRead32(&FAp[id]->version) & 0xFFFF;
/* Processing FPGA firmware version */
proc = vmeRead32(&(FAp[id]->adc_status[0]))&FA_ADC_VERSION_MASK;
FAUNLOCK;
rval = (cntl) | (proc<<16);
if(pflag)
{
printf("%s: Board Firmware Rev/ID = 0x%04x : ADC Processing Rev = 0x%04x\n",
__FUNCTION__,
cntl, proc);
}
return rval;
}
/**
* @ingroup Config
* @brief Configure the processing type/mode
*
* @param id Slot number
* @param pmode Processing Mode
* - 1 - Raw Window
* - 2 - Pulse Raw Window
* - 3 - Pulse Integral
* - 4 - High-resolution time
* - 7 - Mode 3 + Mode 4
* - 8 - Mode 1 + Mode 4
* @param PL Window Latency
* @param PTW Window Width
* @param NSB Number of samples before pulse over threshold
* @param NSA Number of samples after pulse over threshold
* @param NP Number of pulses processed per window
* @param bank Ignored
*
* Note:
* - PL must be greater than PTW
* - NSA+NSB must be an odd number
*
* @return OK if successful, otherwise ERROR.
*/
int
faSetProcMode(int id, int pmode, unsigned int PL, unsigned int PTW,
unsigned int NSB, unsigned int NSA, unsigned int NP,
unsigned int NPED, unsigned int MAXPED, unsigned int NSAT)
{
int err=0;
int imode=0, supported_modes[FA_SUPPORTED_NMODES] = {FA_SUPPORTED_MODES};
int mode_supported=0;
int mode_bit=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetProcMode: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
for(imode=0; imode FA_ADC_MAX_PL))
{
printf("%s: WARN: PL (%d) out of bounds. ",__FUNCTION__,PL);
PL = (PL < FA_ADC_MIN_PL) ? FA_ADC_MIN_PL : FA_ADC_MAX_PL;
printf("Setting to %d.\n",PL);
}
if((PTW < FA_ADC_MIN_PTW) || (PTW > FA_ADC_MAX_PTW))
{
printf("%s: WARN: PTW (%d) out of bounds. ",__FUNCTION__,PTW);
PTW = (PTW < FA_ADC_MIN_PTW) ? FA_ADC_MIN_PTW : FA_ADC_MAX_PTW;
printf("Setting to %d.\n",PTW);
}
if((NSB < FA_ADC_MIN_NSB) || (NSB > FA_ADC_MAX_NSB))
{
printf("%s: WARN: NSB (%d) out of bounds. ",__FUNCTION__,NSB);
NSB = (NSB < FA_ADC_MIN_NSB) ? FA_ADC_MIN_NSB : FA_ADC_MAX_NSB;
printf("Setting to %d.\n",NSB);
}
// Alex
// if((NSA < FA_ADC_MIN_NSA) || (NSA > FA_ADC_MAX_NSA))
// {
// printf("%s: WARN: NSA (%d) out of bounds. ",__FUNCTION__,NSA);
// NSA = (NSA < FA_ADC_MIN_NSA) ? FA_ADC_MIN_NSA : FA_ADC_MAX_NSA;
// if(((NSB + NSA) % 2)==0) /* Make sure NSA+NSB is an odd number */
// NSA = (NSA==FA_ADC_MIN_NSA) ? NSA + 1 : NSA - 1;
// printf("Setting to %d.\n",NSA);
// }
// if( (NSB & 0x8) && (NSA <= NSB) )
// {
// printf("%s: WARN: ", __FUNCTION__);
// }
if((NP < FA_ADC_MIN_NP) || (NP > FA_ADC_MAX_NP))
{
printf("%s: WARN: NP (%d) out of bounds. ",__FUNCTION__,NP);
NP = (NP < FA_ADC_MIN_NP) ? FA_ADC_MIN_NP : FA_ADC_MAX_NP;
printf("Setting to %d.\n",NP);
}
if((NPED < FA_ADC_MIN_NPED) || (NPED > FA_ADC_MAX_NPED))
{
printf("%s: WARN: NPED (%d) out of bounds. ",__FUNCTION__,NPED);
NPED = (NPED < FA_ADC_MIN_NPED) ? FA_ADC_MIN_NPED : FA_ADC_MAX_NPED;
printf("Setting to %d.\n",NPED);
}
if(NPED >= PTW)
{
printf("%s: WARN: NPED (%d) >= PTW (%d) ",__FUNCTION__, NPED, PTW);
NPED = PTW - 1;
printf("Setting to %d.\n",NPED);
}
if((MAXPED < FA_ADC_MIN_MAXPED) || (MAXPED > FA_ADC_MAX_MAXPED))
{
printf("%s: WARN: MAXPED (%d) out of bounds. ",__FUNCTION__,MAXPED);
MAXPED = (MAXPED < FA_ADC_MIN_MAXPED) ? FA_ADC_MIN_MAXPED : FA_ADC_MAX_MAXPED;
printf("Setting to %d.\n",MAXPED);
}
if((NSAT < FA_ADC_MIN_NSAT) || (NSAT > FA_ADC_MAX_NSAT))
{
printf("%s: WARN: NSAT (%d) out of bounds. ",__FUNCTION__,NSAT);
NSAT = (NSAT < FA_ADC_MIN_NSAT) ? FA_ADC_MIN_NSAT : FA_ADC_MAX_NSAT;
printf("Setting to %d.\n",NSAT);
}
/* Consistancy check */
// Alex
// if(((NSB + NSA) % 2)==0)
// {
// err++;
// printf("%s: ERROR: NSB+NSA must be an odd number\n",__FUNCTION__);
// }
// faSetNormalMode(id,0);
// faSetNormalMode(id,0);
FALOCK;
/* Disable ADC processing while writing window info */
if(pmode == FA_ADC_PROC_MODE_PULSE_PARAM)
mode_bit = 0;
else if(pmode == FA_ADC_PROC_MODE_RAW_PULSE_PARAM)
mode_bit = 1;
else
{
printf("%s: ERROR: Unsupported mode (%d)\n",
__FUNCTION__, pmode);
return ERROR;
}
/* Configure the mode (mode_bit), # of pulses (NP), # samples above TET (NSAT)
keep TNSAT, if it's already been configured */
vmeWrite32(&FAp[id]->adc_config[0],
(vmeRead32(&FAp[id]->adc_config[0]) & FA_ADC_CONFIG1_TNSAT_MASK) |
(mode_bit << 8) | ((NP-1) << 4) | ((NSAT-1) << 10) );
/* Disable user-requested channels */
vmeWrite32(&FAp[id]->adc_config[1], fadcChanDisable[id]);
/* Set window parameters */
vmeWrite32(&FAp[id]->adc_pl, PL);
vmeWrite32(&FAp[id]->adc_ptw, PTW - 1);
/* Set Readback NSB, NSA
NSA */
vmeWrite32(&FAp[id]->adc_nsb, NSB);
vmeWrite32(&FAp[id]->adc_nsa,
(vmeRead32(&FAp[id]->adc_nsa) & FA_ADC_TNSA_MASK) |
NSA );
/* Set Pedestal parameters */
vmeWrite32(&FAp[id]->config7, (NPED-1)<<10 | (MAXPED));
/* Set default value of trigger path threshold (TPT) */
vmeWrite32(&FAp[id]->config3, FA_ADC_DEFAULT_TPT);
/* Enable ADC processing */
vmeWrite32(&FAp[id]->adc_config[0],
vmeRead32(&FAp[id]->adc_config[0]) | FA_ADC_PROC_ENABLE );
FAUNLOCK;
// faSetTriggerStopCondition(id, faCalcMaxUnAckTriggers(pmode,PTW,NSA,NSB,NP));
// faSetTriggerBusyCondition(id, faCalcMaxUnAckTriggers(pmode,PTW,NSA,NSB,NP));
return(OK);
}
/**
* @ingroup Config
* @brief Configure the processing type/mode for all initialized fADC250s
*
* @param pmode Processing Mode
* - 1 - Raw Window
* - 2 - Pulse Raw Window
* - 3 - Pulse Integral
* - 4 - High-resolution time
* - 7 - Mode 3 + Mode 4
* - 8 - Mode 1 + Mode 4
* @param PL Window Latency
* @param PTW Window Width
* @param NSB Number of samples before pulse over threshold
* @param NSA Number of samples after pulse over threshold
* @param NP Number of pulses processed per window
* @param bank Ignored
*
* @sa faSetProcMode
*/
void
faGSetProcMode(int pmode, unsigned int PL, unsigned int PTW,
unsigned int NSB, unsigned int NSA, unsigned int NP,
unsigned int NPED, unsigned int MAXPED, unsigned int NSAT)
{
int ii, res;
for (ii=0;ii21) || (FAp[id] == NULL))
{
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(trigger_max>0xFF)
{
printf("%s: ERROR: Invalid trigger_max (%d)\n",
__FUNCTION__,trigger_max);
return ERROR;
}
FALOCK;
if(trigger_max>0)
{
vmeWrite32(&FAp[id]->trigger_control,
(vmeRead32(&FAp[id]->trigger_control) &
~(FA_TRIGCTL_TRIGSTOP_EN | FA_TRIGCTL_MAX2_MASK)) |
(FA_TRIGCTL_TRIGSTOP_EN | (trigger_max<<16)));
}
else
{
vmeWrite32(&FAp[id]->trigger_control,
(vmeRead32(&FAp[id]->trigger_control) &
~(FA_TRIGCTL_TRIGSTOP_EN | FA_TRIGCTL_MAX2_MASK)));
}
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the maximum number of unacknowledged triggers before module
* asserts BUSY.
* @param id Slot number
* @param trigger_max Limit for maximum number of unacknowledged triggers
* If 0, disables the condition
* @return OK if successful, otherwise ERROR.
*/
int
faSetTriggerBusyCondition(int id, int trigger_max)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(trigger_max>0xFF)
{
printf("%s: ERROR: Invalid trigger_max (%d)\n",
__FUNCTION__,trigger_max);
return ERROR;
}
FALOCK;
if(trigger_max>0)
{
vmeWrite32(&FAp[id]->trigger_control,
(vmeRead32(&FAp[id]->trigger_control) &
~(FA_TRIGCTL_BUSY_EN | FA_TRIGCTL_MAX1_MASK)) |
(FA_TRIGCTL_BUSY_EN | (trigger_max)));
}
else
{
vmeWrite32(&FAp[id]->trigger_control,
(vmeRead32(&FAp[id]->trigger_control) &
~(FA_TRIGCTL_BUSY_EN | FA_TRIGCTL_MAX1_MASK)));
}
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the number of samples that are included before and after
* threshold crossing that are sent through the trigger path
* @param id Slot number
* @param NSB Number of samples before threshold crossing
* @param NSA Number of samples after threshold crossing
* @return OK if successful, otherwise ERROR.
*/
int
faSetTriggerPathSamples(int id, unsigned int TNSA, unsigned int TNSAT)
{
unsigned int readback_nsa=0, readback_config1=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(fadcProcRev[id]<0x90B)
{
printf("%s: ERROR: Processing Firmware does not support this function\n",
__FUNCTION__);
printf(" Requires 0x90B and above\n");
return ERROR;
}
if((TNSA < FA_ADC_MIN_TNSA) || (TNSA > FA_ADC_MAX_TNSA))
{
printf("%s: WARN: TNSA (%d) out of range. Setting to %d\n",
__FUNCTION__,
TNSA, FA_ADC_DEFAULT_TNSA);
TNSA = FA_ADC_DEFAULT_TNSA;
}
if((TNSAT < FA_ADC_MIN_TNSAT) || (TNSAT > FA_ADC_MAX_TNSAT))
{
printf("%s: WARN: TNSAT (%d) out of range. Setting to %d\n",
__FUNCTION__,
TNSAT, FA_ADC_DEFAULT_TNSAT);
TNSAT = FA_ADC_DEFAULT_TNSAT;
}
FALOCK;
readback_nsa = vmeRead32(&FAp[id]->adc_nsa) & FA_ADC_NSA_READBACK_MASK;
readback_config1 = vmeRead32(&FAp[id]->adc_config[0]) & ~FA_ADC_CONFIG1_TNSAT_MASK;
vmeWrite32(&FAp[id]->adc_nsa, (TNSA << 9) | readback_nsa);
vmeWrite32(&FAp[id]->adc_config[0], ((TNSAT-1) << 12) | readback_config1);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the number of samples that are included before and after
* threshold crossing that are sent through the trigger path for
* all initialized fADC250s
* @param NSB Number of samples before threshold crossing
* @param NSA Number of samples after threshold crossing
* @sa faSetTriggerPathSamples
*/
void
faGSetTriggerPathSamples(unsigned int TNSA, unsigned int TNSAT)
{
int ii, res;
for (ii=0;ii21) || (FAp[id] == NULL)) {
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(fadcProcRev[id]<0x90B)
{
printf("%s: ERROR: Processing Firmware does not support this function\n",
__FUNCTION__);
printf(" Requires 0x90B and above\n");
return ERROR;
}
if(TPT>FA_ADC_MAX_TPT)
{
printf("%s: WARN: TPT (%d) greater than MAX. Setting to %d\n",
__FUNCTION__, TPT, FA_ADC_MAX_TPT);
TPT = FA_ADC_MAX_TPT;
}
FALOCK;
vmeWrite32(&FAp[id]->config3,
(vmeRead32(&FAp[id]->config3) & ~FA_ADC_CONFIG3_TPT_MASK) |
TPT);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the threshold used to determine what samples are sent through the
* trigger path for all initialized fADC250s
* @param threshold Trigger Path Threshold
* @sa faSetTriggerPathThreshold
*/
void
faGSetTriggerPathThreshold(unsigned int TPT)
{
int ii, res;
for (ii=0;ii21) || (FAp[id] == NULL)) {
printf("%s: ERROR : FADC in slot %d is not initialized \n",__FUNCTION__,id);
return;
}
while((iwait<100) && (vmeRead32(&FAp[id]->adc_status[0])&0x8000)==0)
{
iwait++;
}
// printf(" Board %d iwait %d \n", id, iwait);
if(iwait==100)
printf("%s: ERROR: Wait timeout.\n",__FUNCTION__);
}
/**
* @ingroup Config
* @brief Configure the ADC Processing in "Normal Mode"
*
* This routine is called in faSetProcMode
*
* @param id Slot number
* @param opt Not Used
*
*/
void
faSetNormalMode(int id, int opt)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL)) {
logMsg("faSetNormalMode: ERROR : FADC in slot %d qis not initialized \n",id,0,0,0,0,0);
return;
}
unsigned int read_status = 0;
FALOCK;
taskDelay(1);
vmeWrite32(&FAp[id]->adc_config[2], 0);
taskDelay(1);
vmeWrite32(&FAp[id]->adc_config[2], 0x10);
taskDelay(1);
vmeWrite32(&FAp[id]->adc_config[2], 0);
taskDelay(1);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0x0F02);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0xC0);
// Read back
// taskDelay(1);
// vmeWrite32(&FAp[id]->adc_config[2], 0x20);
// vmeWrite32(&FAp[id]->adc_config[2], 0xA0);
// taskDelay(2);
// read_status = vmeRead32(&FAp[id]->status4);
// printf(" Read back F02 from chip 1 0x%x \n", read_status);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0x179F);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0xC0);
/* 01dec2011 This portion commented out... would change the input gain */
/* faWaitForAdcReady(id); */
/* vmeWrite32(&FAp[id]->adc_config[3], 0x1811); */
/* faWaitForAdcReady(id); */
/* vmeWrite32(&FAp[id]->adc_config[2], 0x40); */
/* faWaitForAdcReady(id); */
/* vmeWrite32(&FAp[id]->adc_config[2], 0xC0); */
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0xFF01); /* transfer register values */
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0xC0);
printf("%s: ---- FADC %2d ADC chips initialized ----\n",
__FUNCTION__,id);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0x0D00);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0xC0);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0xFF01); /* transfer register values */
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0xC0);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Configure the ADC Processing in "Inverted (positive polarity) Mode"
*
* Call this routine to invert the digital output of the ADC chips for each channel.
* This routine MUST be called after faSetProcMode.
*
* @sa faSetProcMode
* @param id Slot number
*
*/
void
faSetInvertedMode(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL)) {
logMsg("faSetInvertedMode: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0x1404);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40 | 0x80);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[3], 0xFF01);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40 | 0x80);
faWaitForAdcReady(id);
vmeWrite32(&FAp[id]->adc_config[2], 0x40);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Setup FADC Progammable Pulse Generator
*
* @param id Slot number
* @param pmode Not used
* @param sdata Array of sample data to be programmed
* @param nsamples Number of samples contained in sdata
*
* @sa faPPGEnable faPPGDisable
* @return OK if successful, otherwise ERROR.
*/
int
faSetPPG(int id, int pmode, unsigned short *sdata, int nsamples)
{
int ii, diff;
unsigned short rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetPPG: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(sdata == NULL)
{
printf("faSetPPG: ERROR: Invalid Pointer to sample data\n");
return(ERROR);
}
/*Defaults */
if((nsamples <= 0)||(nsamples>FA_PPG_MAX_SAMPLES)) nsamples = FA_PPG_MAX_SAMPLES;
diff = FA_PPG_MAX_SAMPLES - nsamples;
FALOCK;
for(ii=0;ii<(nsamples-2);ii++)
{
vmeWrite32(&FAp[id]->adc_test_data, (sdata[ii]|FA_PPG_WRITE_VALUE));
rval = vmeRead32(&FAp[id]->adc_test_data);
if( (rval&FA_PPG_SAMPLE_MASK) != sdata[ii])
printf("faSetPPG: ERROR: Write error %x != %x (ii=%d)\n",rval, sdata[ii],ii);
}
vmeWrite32(&FAp[id]->adc_test_data, (sdata[(nsamples-2)]&FA_PPG_SAMPLE_MASK));
rval = vmeRead32(&FAp[id]->adc_test_data);
if(rval != sdata[(nsamples-2)])
printf("faSetPPG: ERROR: Write error %x != %x\n",
rval, sdata[nsamples-2]);
vmeWrite32(&FAp[id]->adc_test_data, (sdata[(nsamples-1)]&FA_PPG_SAMPLE_MASK));
rval = vmeRead32(&FAp[id]->adc_test_data);
if(rval != sdata[(nsamples-1)])
printf("faSetPPG: ERROR: Write error %x != %x\n",
rval, sdata[nsamples-1]);
/* vmeWrite32(&FAp[id]->adc_test_data, (sdata[(nsamples-2)]&FA_PPG_SAMPLE_MASK)); */
/* vmeWrite32(&FAp[id]->adc_test_data, (sdata[(nsamples-1)]&FA_PPG_SAMPLE_MASK)); */
FAUNLOCK;
return(OK);
}
/**
* @ingroup Config
* @brief Enable the programmable pulse generator
* @param id Slot number
* @sa faSetPPG faPPGDisable
*/
void
faPPGEnable(int id)
{
unsigned short val1;
if(id==0) id=fadcID[0];
FALOCK;
val1 = (vmeRead32(&FAp[id]->adc_config[0])&0xFFFF);
// val1 |= (FA_PPG_ENABLE | 0xff00);
// Alex
val1 |= FA_PPG_ENABLE;
vmeWrite32(&FAp[id]->adc_config[0], val1);
FAUNLOCK;
printf(" PPGEnable adc_config[0] 0x%x \n", val1);
}
/**
* @ingroup Config
* @brief Disable the programmable pulse generator
* @param id Slot number
* @sa faSetPPG faPPGEnable
*/
void
faPPGDisable(int id)
{
unsigned short val1;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faPPGDisable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
val1 = (vmeRead32(&FAp[id]->adc_config[0])&0xFFFF);
val1 &= ~FA_PPG_ENABLE;
// Alex
// val1 &= ~(0xff00);
vmeWrite32(&FAp[id]->adc_config[0], val1);
FAUNLOCK;
}
/**
* @ingroup Readout
* @brief General Data readout routine
*
* @param id Slot number of module to read
* @param data local memory address to place data
* @param nwrds Max number of words to transfer
* @param rflag Readout Flag
*
* 0 - programmed I/O from the specified board
* 1 - DMA transfer using Universe/Tempe DMA Engine
* (DMA VME transfer Mode must be setup prior)
* 2 - Multiblock DMA transfer (Multiblock must be enabled
* and daisychain in place or SD being used)
*
* @return Number of words inserted into data if successful. Otherwise ERROR.
*/
int
faReadBlock(int id, volatile UINT32 *data, int nwrds, int rflag)
{
int ii, blknum, evnum1;
int stat, retVal, xferCount, rmode, async;
int dCnt, berr=0;
int dummy=0;
volatile unsigned int *laddr;
unsigned int bhead, ehead, val;
unsigned int vmeAdr, csr;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadBlock: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(data==NULL)
{
logMsg("faReadBlock: ERROR: Invalid Destination address\n",0,0,0,0,0,0);
return(ERROR);
}
fadcBlockError=FA_BLOCKERROR_NO_ERROR;
if(nwrds <= 0) nwrds= (FA_MAX_ADC_CHANNELS*FA_MAX_DATA_PER_CHANNEL) + 8;
rmode = rflag&0x0f;
async = rflag&0x80;
if(rmode >= 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 = FA_DUMMY_DATA;
#else
*data = LSWAP(FA_DUMMY_DATA);
#endif
dummy = 1;
laddr = (data + 1);
}
else
{
dummy = 0;
laddr = data;
}
FALOCK;
if(rmode == 2)
{ /* Multiblock Mode */
if((vmeRead32(&(FAp[id]->ctrl1))&FA_FIRST_BOARD)==0)
{
logMsg("faReadBlock: ERROR: FADC in slot %d is not First Board\n",id,0,0,0,0,0);
FAUNLOCK;
return(ERROR);
}
vmeAdr = (unsigned int)((unsigned long)(FApmb) - fadcA32Offset);
}
else
{
vmeAdr = (unsigned int)((unsigned long)(FApd[id]) - fadcA32Offset);
}
#ifdef VXWORKS
retVal = sysVmeDmaSend((UINT32)laddr, vmeAdr, (nwrds<<2), 0);
#else
retVal = vmeDmaSend((unsigned long)laddr, vmeAdr, (nwrds<<2));
#endif
if(retVal != 0)
{
logMsg("faReadBlock: ERROR in DMA transfer Initialization 0x%x\n",retVal,0,0,0,0,0);
FAUNLOCK;
return(retVal);
}
if(async)
{ /* Asynchonous mode - return immediately - don't wait for done!! */
FAUNLOCK;
return(OK);
}
else
{
/* Wait until Done or Error */
#ifdef VXWORKS
retVal = sysVmeDmaDone(10000,1);
#else
retVal = vmeDmaDone();
#endif
}
if(retVal > 0)
{
/* Check to see that Bus error was generated by FADC */
if(rmode == 2)
{
csr = vmeRead32(&(FAp[fadcMaxSlot]->csr)); /* from Last FADC */
stat = (csr)&FA_CSR_BERR_STATUS; /* from Last FADC */
}
else
{
csr = vmeRead32(&(FAp[id]->csr)); /* from Last FADC */
stat = (csr)&FA_CSR_BERR_STATUS; /* from Last FADC */
}
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
FAUNLOCK;
return(xferCount); /* Return number of data words transfered */
}
else
{
#ifdef VXWORKS
xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */
logMsg("faReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x xferCount=%d id=%d)\n",
csr,xferCount,id,0,0,0);
fadcBlockError=FA_BLOCKERROR_UNKNOWN_BUS_ERROR;
#else
xferCount = ((retVal>>2) + dummy); /* Number of Longwords transfered */
if((retVal>>2)==nwrds)
{
logMsg("faReadBlock: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0);
fadcBlockError=FA_BLOCKERROR_TERM_ON_WORDCOUNT;
}
else
{
logMsg("faReadBlock: DMA transfer terminated by unknown BUS Error (csr=0x%x xferCount=%d id=%d)\n",
csr,xferCount,id,0,0,0);
fadcBlockError=FA_BLOCKERROR_UNKNOWN_BUS_ERROR;
}
#endif
FAUNLOCK;
return(xferCount);
/* return(ERROR); */
}
}
else if (retVal == 0)
{ /* Block Error finished without Bus Error */
#ifdef VXWORKS
logMsg("faReadBlock: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0);
#else
logMsg("faReadBlock: WARN: DMA transfer returned zero word count 0x%x\n",nwrds,0,0,0,0,0);
#endif
fadcBlockError=FA_BLOCKERROR_ZERO_WORD_COUNT;
FAUNLOCK;
return(nwrds);
}
else
{ /* Error in DMA */
#ifdef VXWORKS
logMsg("faReadBlock: ERROR: sysVmeDmaDone returned an Error\n",0,0,0,0,0,0);
#else
logMsg("faReadBlock: ERROR: vmeDmaDone returned an Error\n",0,0,0,0,0,0);
#endif
fadcBlockError=FA_BLOCKERROR_DMADONE_ERROR;
FAUNLOCK;
return(retVal>>2);
}
}
else
{ /*Programmed IO */
/* Check if Bus Errors are enabled. If so then disable for Prog I/O reading */
FALOCK;
berr = vmeRead32(&(FAp[id]->ctrl1))&FA_ENABLE_BERR;
if(berr)
vmeWrite32(&(FAp[id]->ctrl1),vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_BERR);
dCnt = 0;
/* Read Block Header - should be first word */
bhead = (unsigned int) *FApd[id];
#ifndef VXWORKS
bhead = LSWAP(bhead);
#endif
if((bhead&FA_DATA_TYPE_DEFINE)&&((bhead&FA_DATA_TYPE_MASK) == FA_DATA_BLOCK_HEADER)) {
blknum = bhead&FA_DATA_BLKNUM_MASK;
ehead = (unsigned int) *FApd[id];
#ifndef VXWORKS
ehead = LSWAP(ehead);
#endif
evnum1 = ehead&FA_DATA_TRIGNUM_MASK;
#ifdef VXWORKS
data[dCnt] = bhead;
#else
data[dCnt] = LSWAP(bhead); /* Swap back to little-endian */
#endif
dCnt++;
#ifdef VXWORKS
data[dCnt] = ehead;
#else
data[dCnt] = LSWAP(ehead); /* Swap back to little-endian */
#endif
dCnt++;
}
else
{
/* We got bad data - Check if there is any data at all */
if( (vmeRead32(&(FAp[id]->ev_count)) & FA_EVENT_COUNT_MASK) == 0)
{
logMsg("faReadBlock: FIFO Empty (0x%08x)\n",bhead,0,0,0,0,0);
FAUNLOCK;
return(0);
}
else
{
logMsg("faReadBlock: ERROR: Invalid Header Word 0x%08x\n",bhead,0,0,0,0,0);
FAUNLOCK;
return(ERROR);
}
}
ii=0;
while(iictrl1),
vmeRead32(&(FAp[id]->ctrl1)) | FA_ENABLE_BERR);
FAUNLOCK;
return(dCnt);
}
FAUNLOCK;
return(OK);
}
/**
* @ingroup Status
* @brief Return the type of error that occurred while attempting a
* block read from faReadBlock.
* @param pflag
* - >0: Print error message to standard out
* @sa faReadBlock
* @return OK if successful, otherwise ERROR.
*/
int
faGetBlockError(int pflag)
{
int rval=0;
const char *block_error_names[FA_BLOCKERROR_NTYPES] =
{
"NO ERROR",
"DMA Terminated on Word Count",
"Unknown Bus Error",
"Zero Word Count",
"DmaDone Error"
};
rval = fadcBlockError;
if(pflag)
{
if(rval!=FA_BLOCKERROR_NO_ERROR)
{
logMsg("faGetBlockError: Block Transfer Error: %s\n",
block_error_names[rval],2,3,4,5,6);
}
}
return rval;
}
/**
* @ingroup Readout
* @brief For asychronous calls to faReadBlock, this routine completes the block transfer
* @param id Slot number of module to read
* @param data local memory address to place data
* @param nwrds Max number of words to transfer
* @param rflag Readout Flag
*
* 0 - programmed I/O from the specified board
* 1 - DMA transfer using Universe/Tempe DMA Engine
* (DMA VME transfer Mode must be setup prior)
* 2 - Multiblock DMA transfer (Multiblock must be enabled
* and daisychain in place or SD being used)
*
* @return Number of words read if successful, otherwise ERROR.
*/
int
faReadBlockStatus(int id, volatile UINT32 *data, int nwrds, int rflag)
{
int stat, retVal, xferCount, rmode, async;
int dummy=0;
unsigned int csr=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadBlockStatus: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(nwrds <= 0) nwrds= (FA_MAX_ADC_CHANNELS*FA_MAX_DATA_PER_CHANNEL) + 8;
rmode = rflag&0x0f;
async = rflag&0x80;
/* Check for 8 byte boundary for address - insert dummy word (Slot 0 FADC Dummy DATA)*/
if((unsigned long) (data)&0x7)
{
dummy = 1;
}
else
{
dummy = 0;
}
#ifdef VXWORKS
retVal = sysVmeDmaDone(10000,1);
#else
retVal = vmeDmaDone();
#endif
FALOCK;
if(retVal > 0)
{
/* Check to see that Bus error was generated by FADC */
if(rmode == 2)
{
csr = vmeRead32(&(FAp[fadcMaxSlot]->csr)); /* from Last FADC */
stat = (csr)&FA_CSR_BERR_STATUS; /* from Last FADC */
}
else
{
stat = vmeRead32(&(FAp[id]->csr))&FA_CSR_BERR_STATUS; /* from FADC id */
}
if((retVal>0) && (stat))
{
xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */
FAUNLOCK;
return(xferCount); /* Return number of data words transfered */
}
else
{
xferCount = (nwrds - (retVal>>2) + dummy); /* Number of Longwords transfered */
logMsg("faReadBlockStatus: DMA transfer terminated by unknown BUS Error (csr=0x%x nwrds=%d)\n",csr,xferCount,0,0,0,0);
FAUNLOCK;
return(ERROR);
}
}
else if (retVal == 0)
{ /* Block Error finished without Bus Error */
logMsg("faReadBlockStatus: WARN: DMA transfer terminated by word count 0x%x\n",nwrds,0,0,0,0,0);
FAUNLOCK;
return(nwrds);
}
else
{ /* Error in DMA */
logMsg("faReadBlockStatus: ERROR: sysVmeDmaDone returned an Error\n",0,0,0,0,0,0);
FAUNLOCK;
return(retVal);
}
}
/**
* @ingroup Readout
* @brief Print the current available block to standard out
* @param id Slot number
* @param rflag Not used
* @return Number of words read if successful, otherwise ERROR.
*/
int
faPrintBlock(int id, int rflag)
{
int ii, blknum, evnum1;
int nwrds=32768, dCnt, berr=0;
unsigned int data, bhead, ehead;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("faPrintEvent: ERROR : FADC in slot %d is not initialized \n",id);
return(ERROR);
}
/* Check if data available */
FALOCK;
if((vmeRead32(&(FAp[id]->ev_count))&FA_EVENT_COUNT_MASK)==0)
{
printf("faPrintEvent: ERROR: FIFO Empty\n");
FAUNLOCK;
return(0);
}
/* Check if Bus Errors are enabled. If so then disable for reading */
berr = vmeRead32(&(FAp[id]->ctrl1))&FA_ENABLE_BERR;
if(berr)
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_BERR);
dCnt = 0;
/* Read Block Header - should be first word */
bhead = (unsigned int) *FApd[id];
#ifndef VXWORKS
bhead = LSWAP(bhead);
#endif
if( (bhead&FA_DATA_TYPE_DEFINE)&&((bhead&FA_DATA_TYPE_MASK) == FA_DATA_BLOCK_HEADER))
{
blknum = bhead&FA_DATA_BLKNUM_MASK;
ehead = (unsigned int) *FApd[id];
#ifndef VXWORKS
ehead = LSWAP(ehead);
#endif
evnum1 = ehead&FA_DATA_TRIGNUM_MASK;
printf("%4d: ",dCnt+1);
faDataDecode(bhead);
dCnt++;
printf("%4d: ",dCnt+1);
faDataDecode(ehead);
dCnt++;
}
else
{
/* We got bad data - Check if there is any data at all */
if((vmeRead32(&(FAp[id]->ev_count))&FA_EVENT_COUNT_MASK)==0)
{
logMsg("faPrintBlock: FIFO Empty (0x%08x)\n",bhead,0,0,0,0,0);
FAUNLOCK;
return(0);
}
else
{
logMsg("faPrintBlock: ERROR: Invalid Header Word 0x%08x\n",bhead,0,0,0,0,0);
FAUNLOCK;
return(ERROR);
}
}
ii=0;
while(iictrl1),
vmeRead32( &(FAp[id]->ctrl1)) | FA_ENABLE_BERR );
FAUNLOCK;
return(dCnt);
}
/**
* @ingroup Status
* @brief Get the value of the Control/Status Register
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
unsigned int
faReadCSR(int id)
{
unsigned int rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadCSR: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(0);
}
FALOCK;
rval = vmeRead32(&(FAp[id]->csr));
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Perform a soft reset.
* @param id Slot number
*/
void
faClear(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faClear: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->csr),FA_CSR_SOFT_RESET);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Perform a soft reset of all initialized fADC250s
*/
void
faGClear()
{
int ii, id;
FALOCK;
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faGClear: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
}
else
{
vmeWrite32(&(FAp[id]->csr),FA_CSR_SOFT_RESET);
}
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Clear latched errors
* @param id Slot number
*/
void
faClearError(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faClearErr: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->csr),FA_CSR_ERROR_CLEAR);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Clear latched errors of all initialized fADC250s
*/
void
faGClearError()
{
int ii, id;
FALOCK;
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faGClearErr: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
}
else
{
vmeWrite32(&(FAp[id]->csr),FA_CSR_ERROR_CLEAR);
}
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Perform a hard reset
* @param id Slot number
* @param iFlag Decision to restore A32 readout after reset.
* - 0: Restore A32 readout after reset.
* - !0: Do not restore A32 readout after reset. (Useful for configuration changes)
*/
void
faReset(int id, int iFlag)
{
unsigned int a32addr, addrMB;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReset: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
if(iFlag==0)
{
a32addr = vmeRead32(&(FAp[id]->adr32));
addrMB = vmeRead32(&(FAp[id]->adr_mb));
}
vmeWrite32(&(FAp[id]->csr),FA_CSR_HARD_RESET);
taskDelay(10);
if(iFlag==0)
{
vmeWrite32(&(FAp[id]->adr32),a32addr);
vmeWrite32(&(FAp[id]->adr_mb),addrMB);
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Perform a hard reset on all initialized fADC250s
* @param iFlag Decision to restore A32 readout after reset.
* - 0: Restore A32 readout after reset.
* - !0: Do not restore A32 readout after reset. (Useful for configuration changes)
*/
void
faGReset(int iFlag)
{
unsigned int a32addr[(FA_MAX_BOARDS+1)], addrMB[(FA_MAX_BOARDS+1)];
int ifa=0, id=0;
FALOCK;
if(iFlag==0)
{
for(ifa=0; ifaadr32));
addrMB[id] = vmeRead32(&(FAp[id]->adr_mb));
}
}
for(ifa=0; ifacsr),FA_CSR_HARD_RESET);
}
taskDelay(10);
if(iFlag==0)
{
for(ifa=0; ifaadr32),a32addr[id]);
vmeWrite32(&(FAp[id]->adr_mb),addrMB[id]);
}
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Perform either a soft clear or soft reset
* @param id Slot number
* @param cflag
* - 0: Soft Clear
* - >0: Soft Reset
*/
void
faSoftReset(int id, int cflag)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReset: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
if(cflag) /* perform soft clear */
vmeWrite32(&(FAp[id]->csr),FA_CSR_SOFT_CLEAR);
else /* normal soft reset */
vmeWrite32(&(FAp[id]->csr),FA_CSR_SOFT_RESET);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Reset the token
*
* A call to this routine will cause the module to have the token if it
* has been configured to the the FIRST module in the MultiBlock chain.
* This routine has no effect on any other module in the chain.
*
* @param id Slot number
*/
void
faResetToken(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faResetToken: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->reset),FA_RESET_TOKEN);
FAUNLOCK;
}
/**
* @ingroup Status
* @brief Return the status of the token
* @param id Slot number
* @return 1 if module has the token, 0 if not, otherwise ERROR.
*/
int
faTokenStatus(int id)
{
int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faResetToken: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
FALOCK;
rval = (vmeRead32(&FAp[id]->csr) & FA_CSR_TOKEN_STATUS)>>4;
FAUNLOCK;
return rval;
}
/**
* @ingroup Status
* @brief Return the slotmask of those modules that have the token.
* @return Token Slotmask
*/
int
faGTokenStatus()
{
int ifa=0, bit=0, rval=0;
for(ifa = 0; ifa21) || (FAp[id] == NULL))
{
logMsg("faSetCalib: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->delay),(sdelay<<16) | tdelay);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Disable the specified channel
* @param id Slot number
* @param channel Channel Number to Disable
* @return OK if successful, otherwise ERROR.
*/
int
faSetChannelDisable(int id, int channel)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetChannelDisable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
if((channel<0) || (channel>=FA_MAX_ADC_CHANNELS))
{
logMsg("faSetChannelDisable: ERROR: Invalid channel (%d). Must be 0-%d\n",
channel, FA_MAX_ADC_CHANNELS-1,3,4,5,6);
return ERROR;
}
fadcChanDisable[id] = fadcChanDisable[id] | (1<adc_config[1]), fadcChanDisable[id]);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Disable all channels in the specified mask
* @param id Slot number
* @param cmask Channel mask of channels to disable
*/
void
faChanDisable(int id, unsigned short cmask)
{
faSetChannelDisableMask(id,cmask);
}
/**
* @ingroup Config
* @brief Disable all channels in the specified mask
* @param id Slot number
* @param cmask Channel mask of channels to disable
* @return OK if successful, otherwise ERROR.
*/
int
faSetChannelDisableMask(int id, unsigned short cmask)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faChanDisable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
fadcChanDisable[id] = cmask; /* Set Global Variable */
FALOCK;
/* Write New Disable Mask */
vmeWrite32(&(FAp[id]->adc_config[1]), fadcChanDisable[id]);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Enable the specified channel
* @param id Slot number
* @param channel Channel Number to Enable
* @return OK if successful, otherwise ERROR.
*/
int
faSetChannelEnable(int id, int channel)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetChannelEnable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
if((channel<0) || (channel>=FA_MAX_ADC_CHANNELS))
{
logMsg("faSetChannelEnable: ERROR: Invalid channel (%d). Must be 0-%d\n",
channel, FA_MAX_ADC_CHANNELS-1,3,4,5,6);
return ERROR;
}
fadcChanDisable[id] = fadcChanDisable[id] & (~(1<adc_config[1]), fadcChanDisable[id]);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Enable all channels in the specified mask
* @param id Slot number
* @param cmask Channel mask of channels to Enable
* @return OK if successful, otherwise ERROR.
*/
int
faSetChannelEnableMask(int id, unsigned short enMask)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetChannelEnableMask: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
fadcChanDisable[id] = ~(enMask) & FA_ADC_CHAN_MASK;
FALOCK;
/* Write New Disable Mask */
vmeWrite32(&FAp[id]->adc_config[1], fadcChanDisable[id]);
FAUNLOCK;
return OK;
}
/**
* @ingroup Status
* @brief Get the Enabled/Disabled Channel Mask
* @param id Slot number
* @param type
* - 0: Return the disabled Mask
* - !0: Return the enabled Mask
* @return Specified mask if successful, otherwise ERROR.
*/
int
faGetChannelMask(int id, int type)
{
int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faGetChannelMask: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return ERROR;
}
FALOCK;
fadcChanDisable[id] = vmeRead32(&FAp[id]->adc_config[1]) & FA_ADC_CHAN_MASK;
FAUNLOCK;
if(type!=0)
rval = (~fadcChanDisable[id]) & FA_ADC_CHAN_MASK;
else
rval = fadcChanDisable[id];
return rval;
}
/**
* @ingroup Config
* @brief Enabled the SyncReset source
* @param id Slot number
*/
void
faEnableSyncSrc(int id)
{
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableSyncSrc: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl2), FA_CTRL_GO | FA_CTRL_ENABLE_SRESET);
/* Keep this bit set, if it is */
reg = vmeRead32(&FAp[id]->mgt_ctrl) & FA_MGT_HITBITS_TO_CTP;
if(fadcAlignmentDebug)
{
/* Disable front end channel data */
vmeWrite32(&FAp[id]->adc_config[1],0xffff);
printf("%s: Enabling alignment debugging sequence\n",__FUNCTION__);
/* Enable data alignment debugging sequence */
vmeWrite32(&FAp[id]->mgt_ctrl,FA_MGT_RESET | reg);
vmeWrite32(&FAp[id]->mgt_ctrl,FA_RELEASE_MGT_RESET | reg);
vmeWrite32(&FAp[id]->mgt_ctrl,FA_MGT_ENABLE_DATA_ALIGNMENT | reg);
printf(" mgt_ctrl = 0x%08x\n",vmeRead32(&FAp[id]->mgt_ctrl));
}
else
{
//Alex
vmeWrite32(&FAp[id]->mgt_ctrl,FA_MGT_RESET | reg);
vmeWrite32(&FAp[id]->mgt_ctrl,FA_RELEASE_MGT_RESET | reg);
vmeWrite32(&FAp[id]->mgt_ctrl, FA_MGT_FRONT_END_TO_CTP | FA_MGT_ENABLE_DATA_ALIGNMENT | reg);
}
FAUNLOCK;
/* Allow time for the fADC250 to CTP lanes to come back up */
taskDelay(1);
}
/**
* @ingroup Config
* @brief Enable the SyncReset Source of all initialized fADC250s
*/
void
faGEnableSyncSrc()
{
int id=0;
for(id=0;id21) || (FAp[id] == NULL))
{
logMsg("faEnable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
#if 0
/* Wait until PROC has finished processing buffered triggers */
stat = vmeRead32(&FAp[id]->adc_status[1]) & FA_ADC_STATUS1_TRIG_RCV_DONE;
while( (stat == 0) && (itimeout < timeout) )
{
taskDelay(1);
stat = vmeRead32(&FAp[id]->adc_status[1]) & FA_ADC_STATUS1_TRIG_RCV_DONE;
itimeout++;
}
if(stat==0)
{
logMsg("faEnable: ERROR: ADC in slot %d NOT READY to Enable.\n",id,0,0,0,0,0);
FAUNLOCK;
return;
}
#endif
/* Keep this bit set, if it is */
reg = vmeRead32(&FAp[id]->mgt_ctrl) & FA_MGT_HITBITS_TO_CTP;
if(fadcAlignmentDebug)
{
/* Disable data alignment debugging sequence */
vmeWrite32(&FAp[id]->mgt_ctrl, FA_MGT_FRONT_END_TO_CTP | FA_MGT_ENABLE_DATA_ALIGNMENT | reg);
/* Re-enable front end channel data */
vmeWrite32(&FAp[id]->adc_config[1], fadcChanDisable[id]);
}
if(eflag)
{ /* Enable Internal Trigger logic as well*/
vmeWrite32(&(FAp[id]->ctrl2),
FA_CTRL_GO | FA_CTRL_ENABLE_TRIG | FA_CTRL_ENABLE_SRESET |
FA_CTRL_ENABLE_INT_TRIG);
}
else
{
vmeWrite32(&(FAp[id]->ctrl2),
FA_CTRL_GO | FA_CTRL_ENABLE_TRIG | FA_CTRL_ENABLE_SRESET);
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable data acquisition, trigger, and SyncReset on all initialized fADC250s
*
* Also enables the SDC if it is initalized and used.
*
* @param eflag Enable Internal Trigger Logic, as well
* @param bank Not used
*/
void
faGEnable(int eflag, int bank)
{
int ii;
for(ii=0;ii0: Turn off FIFO transfer as well.
*/
void
faDisable(int id, int eflag)
{
unsigned int stat=0;
int itimeout=0, timeout=10;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDisable: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
/* Wait until PROC has finished processing buffered triggers */
stat = vmeRead32(&FAp[id]->adc_status[1]) & FA_ADC_STATUS1_TRIG_RCV_DONE;
while( (stat == 0) && (itimeout < timeout) )
{
taskDelay(1);
stat = vmeRead32(&FAp[id]->adc_status[1]) & FA_ADC_STATUS1_TRIG_RCV_DONE;
itimeout++;
}
if(stat==0)
{
logMsg("faDisable: ERROR: ADC in slot %d NOT READY to Disable.\n",id,0,0,0,0,0);
FAUNLOCK;
return;
}
if(eflag)
vmeWrite32(&(FAp[id]->ctrl2),0); /* Turn FIFO Transfer off as well */
else
vmeWrite32(&(FAp[id]->ctrl2),FA_CTRL_GO);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Disable data acquisition, triggers, and SyncReset on all initialized fADC250s
* @param eflag
* - >0: Turn off FIFO transfer as well.
*/
void
faGDisable(int eflag)
{
int ii;
if(fadcUseSDC)
faSDC_Disable();
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faTrig: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
if( vmeRead32(&(FAp[id]->ctrl1)) & (FA_ENABLE_SOFT_TRIG) )
vmeWrite32(&(FAp[id]->csr), FA_CSR_TRIGGER);
else
logMsg("faTrig: ERROR: Software Triggers not enabled",0,0,0,0,0,0);
FAUNLOCK;
}
/**
* @ingroup Readout
* @brief Pulse a software trigger to all initialized fADC250s
*/
void
faGTrig()
{
int ii;
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faTrig2: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
if( vmeRead32(&(FAp[id]->ctrl1)) & (FA_ENABLE_SOFT_TRIG) )
vmeWrite32(&(FAp[id]->csr), FA_CSR_SOFT_PULSE_TRIG2);
else
logMsg("faTrig2: ERROR: Software Triggers not enabled",0,0,0,0,0,0);
FAUNLOCK;
}
/**
* @ingroup Readout
* @brief Pulse a software playback trigger to all initialized fADC250s
*/
void
faGTrig2()
{
int ii;
for(ii=0;ii21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(delay>FA_TRIG21_DELAY_MASK)
{
printf("%s: ERROR: Invalid value for delay (%d).\n",
__FUNCTION__,delay);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->trig21_delay, delay);
FAUNLOCK;
return OK;
}
/**
* @ingroup Status
* @brief Return the value of the delay between the software playback trigger and trigger
* @param id Slot number
* @return Trigger delay, otherwise ERROR.
*/
int
faGetTrig21Delay(int id)
{
int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->trig21_delay) & FA_TRIG21_DELAY_MASK;
FAUNLOCK;
return rval;
}
/**
* @ingroup Config
* @brief Enable the software playback trigger and trigger
* @param id Slot number
* @sa faSetTrig21Delay
* @return OK if successful, otherwise ERROR.
*/
int
faEnableInternalPlaybackTrigger(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->ctrl1,
(vmeRead32(&FAp[id]->ctrl1) & ~FA_TRIG_MASK) | FA_TRIG_VME_PLAYBACK);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Pulse a software SyncReset
* @param id Slot number
*/
void
faSync(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSync: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
if(vmeRead32(&(FAp[id]->ctrl1))&(FA_ENABLE_SOFT_SRESET))
vmeWrite32(&(FAp[id]->csr), FA_CSR_SYNC);
else
logMsg("faSync: ERROR: Software Sync Resets not enabled\n",0,0,0,0,0,0);
FAUNLOCK;
}
/**
* @ingroup Readout
* @brief Return Event/Block count
* @param id Slot number
* @param dflag
* - 0: Event Count
* - >0: Block count
* @return OK if successful, otherwise ERROR.
*/
int
faDready(int id, int dflag)
{
unsigned int dcnt=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDready: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
if(dflag)
dcnt = vmeRead32(&(FAp[id]->blk_count))&FA_BLOCK_COUNT_MASK;
else
dcnt = vmeRead32(&(FAp[id]->ev_count))&FA_EVENT_COUNT_MASK;
FAUNLOCK;
return(dcnt);
}
/**
* @ingroup Readout
* @brief Return a Block Ready status
* @param id Slot number
* @return 1 if block is ready for readout, 0 if not, otherwise ERROR.
*/
int
faBready(int id)
{
int stat=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faBready: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
stat = (vmeRead32(&(FAp[id]->csr))) &FA_CSR_BLOCK_READY;
FAUNLOCK;
if(stat)
return(1);
else
return(0);
}
/**
* @ingroup Readout
* @brief Return a Block Ready status mask for all initialized fADC250s
* @return block ready mask, otherwise ERROR.
*/
unsigned int
faGBready()
{
int ii, id, stat=0;
unsigned int dmask=0;
FALOCK;
for(ii=0;iicsr))&FA_CSR_BLOCK_READY;
if(stat)
dmask |= (1<0: set the busy level to val
* - 0: read back busy level
* @param bflag i
* - >0: force the module Busy
*
* @return OK if successful, otherwise ERROR.
*/
int
faBusyLevel(int id, unsigned int val, int bflag)
{
unsigned int blreg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faBusyLevel: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(val>FA_BUSY_LEVEL_MASK)
return(ERROR);
/* if Val > 0 then set the Level else leave it alone*/
FALOCK;
if(val)
{
if(bflag)
vmeWrite32(&(FAp[id]->busy_level),(val | FA_FORCE_BUSY));
else
vmeWrite32(&(FAp[id]->busy_level),val);
}
else
{
blreg = vmeRead32(&(FAp[id]->busy_level));
if(bflag)
vmeWrite32(&(FAp[id]->busy_level),(blreg | FA_FORCE_BUSY));
}
FAUNLOCK;
return((blreg&FA_BUSY_LEVEL_MASK));
}
/**
* @ingroup Status
* @brief Get the busy status
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faBusy(int id)
{
unsigned int blreg=0;
unsigned int dreg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faBusy: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
blreg = vmeRead32(&(FAp[id]->busy_level))&FA_BUSY_LEVEL_MASK;
dreg = vmeRead32(&(FAp[id]->ram_word_count))&FA_RAM_DATA_MASK;
FAUNLOCK;
if(dreg>=blreg)
return(1);
else
return(0);
}
/**
* @ingroup Config
* @brief Enable software triggers
* @param id Slot number
*/
void
faEnableSoftTrig(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableSoftTrig: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
/* Clear the source */
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_TRIG_MASK );
/* Set Source and Enable*/
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | (FA_TRIG_VME | FA_ENABLE_SOFT_TRIG) );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable Software Triggers for all initialized fADC250s
*/
void
faGEnableSoftTrig()
{
int ii, id;
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faDisableSoftTrig: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_SOFT_TRIG );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable Software SyncReset
* @param id Slot number
*/
void
faEnableSoftSync(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableSoftSync: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
/* Clear the source */
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_SRESET_MASK);
/* Set Source and Enable*/
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | (FA_SRESET_VME | FA_ENABLE_SOFT_SRESET));
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Disable Software SyncReset
* @param id Slot number
*/
void
faDisableSoftSync(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDisableSoftSync: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_SOFT_SRESET);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable the internal clock
* @param id Slot number
*/
void
faEnableClk(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableClk: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | (FA_REF_CLK_INTERNAL|FA_ENABLE_INTERNAL_CLK) );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Disable the internal clock
* @param id Slot number
*/
void
faDisableClk(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDisableClk: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_INTERNAL_CLK );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable trigger out for front panel or p0
* @param id Slot number
* @param output
* - 0: FP trigger out
* - 1: P0 trigger out
* - 2: FP and P0 trigger out
*/
void
faEnableTriggerOut(int id, int output)
{
int bitset=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableBusError: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
if(output>2)
{
logMsg("faEnableTriggerOut: ERROR: output (%d) out of range. Must be less than 3",
output,2,3,4,5,6);
return;
}
switch(output)
{
case 0:
bitset = FA_ENABLE_TRIG_OUT_FP;
break;
case 1:
bitset = FA_ENABLE_TRIG_OUT_P0;
break;
case 2:
bitset = FA_ENABLE_TRIG_OUT_FP | FA_ENABLE_TRIG_OUT_P0;
break;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | bitset );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable bus errors to terminate a block transfer
* @param id Slot number
*/
void
faEnableBusError(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableBusError: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | FA_ENABLE_BERR );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable bus errors to terminate a block transfer for all initialized fADC250s
*/
void
faGEnableBusError()
{
int ii;
FALOCK;
for(ii=0;iictrl1),
vmeRead32(&(FAp[fadcID[ii]]->ctrl1)) | FA_ENABLE_BERR );
}
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Disable bus errors
* @param id Slot number
*/
void
faDisableBusError(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDisableBusError: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_ENABLE_BERR );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Enable and setup multiblock transfers for all initialized fADC250s
* @param tflag Token Flag
* - >0: Token via P0/VXS
* - 0: Token via P2
*/
void
faEnableMultiBlock(int tflag)
{
int ii, id;
unsigned int mode;
if((nfadc <= 1) || (FAp[fadcID[0]] == NULL))
{
logMsg("faEnableMultiBlock: ERROR : Cannot Enable MultiBlock mode \n",0,0,0,0,0,0);
return;
}
/* if token = 0 then send via P2 else via VXS */
if(tflag)
mode = (FA_ENABLE_MULTIBLOCK | FA_MB_TOKEN_VIA_P0);
else
mode = (FA_ENABLE_MULTIBLOCK | FA_MB_TOKEN_VIA_P2);
for(ii=0;iictrl1),
vmeRead32(&(FAp[id]->ctrl1)) | mode );
FAUNLOCK;
faDisableBusError(id);
if(id == fadcMinSlot)
{
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | FA_FIRST_BOARD );
FAUNLOCK;
}
if(id == fadcMaxSlot)
{
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | FA_LAST_BOARD );
FAUNLOCK;
faEnableBusError(id); /* Enable Bus Error only on Last Board */
}
}
}
/**
* @ingroup Config
* @brief Disable multiblock transfer for all initialized fADC250s
*/
void
faDisableMultiBlock()
{
int ii;
if((nfadc <= 1) || (FAp[fadcID[0]] == NULL))
{
logMsg("faDisableMultiBlock: ERROR : Cannot Disable MultiBlock Mode\n",0,0,0,0,0,0);
return;
}
FALOCK;
for(ii=0;iictrl1),
vmeRead32(&(FAp[fadcID[ii]]->ctrl1)) & ~FA_ENABLE_MULTIBLOCK );
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set the block level for the module
* @param id Slot number
* @param level block level
* @return OK if successful, otherwise ERROR.
*/
int
faSetBlockLevel(int id, int level)
{
int rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetBlockLevel: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(level<=0) level = 1;
FALOCK;
vmeWrite32(&(FAp[id]->blk_level), level);
fadcBlockLevel = level;
rval = vmeRead32(&(FAp[id]->blk_level)) & FA_BLOCK_LEVEL_MASK;
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Set the block level for all initialized fADC250s
* @param level block level
*/
void
faGSetBlockLevel(int level)
{
int ii;
if(level<=0) level = 1;
FALOCK;
for(ii=0;iiblk_level), level);
FAUNLOCK;
fadcBlockLevel = level;
}
/**
* @ingroup Config
* @brief Set the Clock Source for the module
* @param id Slot number
* @param source Clock Source
* - 0: internal
* - 1: front panel
* - 2: P0/VXS
* @return OK if successful, otherwise ERROR.
*/
int
faSetClkSource(int id, int source)
{
int rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetClkSource: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_REF_CLK_SEL_MASK );
if((source<0)||(source>7)) source = FA_REF_CLK_INTERNAL;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | source );
rval = vmeRead32(&(FAp[id]->ctrl1)) & FA_REF_CLK_SEL_MASK;
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Set the trigger source for the module
* @param id Slot number
* @param source Trigger Source
* - 0: Front Panel
* - 1: Front Panel (Synchronized)
* - 2: P0/VXS
* - 3: P0/VXS (Synchronized)
* - 4: Not used
* - 5: Software (with playback)
* - 6: Software
* @return OK if successful, otherwise ERROR.
*/
int
faSetTrigSource(int id, int source)
{
int rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetTrigSource: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if((source<0)||(source>6))
{
logMsg("faSetTrigSource: ERROR: Invalid source (%d)\n",source,2,3,4,5,6);
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_TRIG_SEL_MASK );
if((source<0)||(source>7)) source = FA_TRIG_FP_ISYNC;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | source );
rval = vmeRead32(&(FAp[id]->ctrl1)) & FA_TRIG_SEL_MASK;
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Set the SyncReset source for the module
* @param id Slot number
* @param source
* - 0: FP
* - 1: FP (synchronized)
* - 2: P0/VXS
* - 3: P0/VXS (synchronized)
* - 4: Not used
* - 5: Not used
* - 6: Software
* - 7: No Source
* @return OK if successful, otherwise ERROR.
*/
int
faSetSyncSource(int id, int source)
{
int rval;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetSyncSource: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) & ~FA_SRESET_SEL_MASK );
if((source<0)||(source>7)) source = FA_SRESET_FP_ISYNC;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | source );
rval = vmeRead32(&(FAp[id]->ctrl1)) & FA_SRESET_SEL_MASK;
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Enable Front Panel Inputs
*
* Also disables software triggers/syncs but leaves the clock source alone
*
* @param id Slot number
*/
void
faEnableFP(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableFP: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) &
~(FA_TRIG_SEL_MASK | FA_SRESET_SEL_MASK | FA_ENABLE_SOFT_SRESET | FA_ENABLE_SOFT_TRIG));
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&(FAp[id]->ctrl1)) | (FA_TRIG_FP_ISYNC | FA_SRESET_FP_ISYNC));
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set trigger output options
* @param id Slot number
* @param trigout bits:
*
* 0 1 0 Enable Front Panel Trigger Output
* 1 0 0 Enable VXS Trigger Output
*
*
* @return OK if successful, otherwise ERROR.
*/
int
faSetTrigOut(int id, int trigout)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("faSetTrigOut: ERROR : ADC in slot %d is not initialized \n",id);
return ERROR;
}
if((trigout & ~(0x6))!=0)
{
printf("faSetTrigOut: ERROR : Invalid trigout value (%d) \n",trigout);
return ERROR;
}
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
(vmeRead32(&(FAp[id]->ctrl1)) & ~FA_TRIGOUT_MASK) |
trigout<<12);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Reset the trigger count for the module
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faResetTriggerCount(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faResetTriggerCount: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
vmeWrite32(&FAp[id]->trig_scal,FA_TRIG_SCAL_RESET);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the readout threshold value for specified channel mask
* @param id Slot number
* @param tvalue Threshold value
* @param chmask Mask of channels to set
* @return OK if successful, otherwise ERROR.
*/
int
faSetThreshold(int id, unsigned short tvalue, unsigned short chmask)
{
int ii, doWrite=0;
unsigned int lovalue=0, hivalue=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetThreshold: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chmask==0) chmask = 0xffff; /* Set All channels the same */
FALOCK;
for(ii=0;iiadc_thres[ii]));
hivalue = (vmeRead16(&FAp[id]->adc_thres[ii+1]));
if((1<adc_thres[ii]),
lovalue<<16 | hivalue);
lovalue = 0;
hivalue = 0;
doWrite=0;
}
}
FAUNLOCK;
return(OK);
}
/**
* @ingroup Status
* @brief Print the thresholds of all channels to standard out
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faPrintThreshold(int id)
{
int ii;
unsigned short tval[FA_MAX_ADC_CHANNELS];
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faPrintThreshold: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
for(ii=0;iiadc_thres[ii]));
}
FAUNLOCK;
printf(" Threshold Settings for FADC in slot %d:",id);
for(ii=0;ii21) || (FAp[id] == NULL))
{
logMsg("faProcPedConfig: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if((nsamples < FA_ADC_MIN_NPED) || (nsamples > FA_ADC_MAX_NPED))
{
printf("%s: ERROR: Invalid nsamples (%d)\n",
__FUNCTION__, nsamples);
return ERROR;
}
if((maxvalue < 0) || (maxvalue > 0x3ff))
{
printf("%s: ERROR: Invalid maxvalue (%d)\n",
__FUNCTION__, maxvalue);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->config7,
(nsamples - 1)<<10 | maxvalue);
FAUNLOCK;
return OK;
}
/**
* @ingroup Readout
* @brief Configure pedestal parameters to be used by processing algorythm
* for all initialized modules.
* @param nsamples Number of samples to contribute to sum
* @param maxvalue Maximum sample value to be included in the sum
* @return OK if successful, otherwise ERROR.
*/
int
faGProcPedConfig(int nsamples, int maxvalue)
{
int ifa=0, rval=OK;
for(ifa = 0; ifa < nfadc; ifa++)
rval |= faProcPedConfig(faSlot(ifa), nsamples, maxvalue);
return rval;
}
/**
* @ingroup Readout
* @brief Configure output of sample data from @faReadChannelSample and @faReadAllChannelSamples
* @param id Slot number
* @param nsamples Number of samples to contribute to sum
* @param maxvalue Maximum sample value to be included in the sum
* @return OK if successful, otherwise ERROR.
*/
int
faSampleConfig(int id, int nsamples, int maxvalue)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSampleConfig: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if((nsamples < FA_ADC_MIN_MNPED) || (nsamples > FA_ADC_MAX_MNPED))
{
printf("%s: ERROR: Invalid nsamples (%d)\n",
__FUNCTION__, nsamples);
return ERROR;
}
if((maxvalue < 0) || (maxvalue > 0x3ff))
{
printf("%s: ERROR: Invalid maxvalue (%d)\n",
__FUNCTION__, maxvalue);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->config6,
(nsamples - 1)<<10 | maxvalue);
FAUNLOCK;
return OK;
}
/**
* @ingroup Readout
* @brief Configure output of sample data from @faReadChannelSample and @faReadAllChannelSamples
* for all initialized modules.
* @param nsamples Number of samples to contribute to sum
* @param maxvalue Maximum sample value to be included in the sum
* @return OK if successful, otherwise ERROR.
*/
int
faGSampleConfig(int nsamples, int maxvalue)
{
int ifa=0, rval=OK;
for(ifa = 0; ifa < nfadc; ifa++)
rval |= faSampleConfig(faSlot(ifa), nsamples, maxvalue);
return rval;
}
/**
* @ingroup Readout
* @brief Read the current sample data from the specified channel and module.
* @param id Slot number
* @param chan Channel Number
* @return Sample data if successful, otherwise ERROR.
*/
int
faReadChannelSample(int id, int chan)
{
int rval=0;
unsigned int write=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadChannelSample: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chan>=FA_MAX_ADC_CHANNELS)
{
logMsg("faReadChannelSample: ERROR: Invalid channel (%d)\n",chan,2,3,4,5,6);
return ERROR;
}
FALOCK;
write = vmeRead32(&FAp[id]->adc_config[0]) & 0xFF;
// Alex
// vmeWrite32(&FAp[id]->adc_config[0], write |
// ((chan<<8) | FA_ADC_CONFIG0_CHAN_READ_ENABLE) );
vmeWrite32(&FAp[id]->adc_config[0], (write | FA_ADC_CONFIG0_CHAN_READ_ENABLE) );
rval = vmeRead32(&FAp[id]->adc_status[2]) & FA_ADC_STATUS2_CHAN_DATA_MASK;
FAUNLOCK;
return rval;
}
/**
* @ingroup Readout
* @brief Read the current sample data from the specified channel and module.
* @param id Slot number
* @param data local memory address to place data
* * Least significant 16bits contain lesser channel number data
* @return Number of words stored in data if successful, otherwise ERROR.
*/
int
faReadAllChannelSamples(int id, volatile unsigned int *data)
{
int ichan=0;
unsigned int write=0, read=0, set_readout = 0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadAllChannelSamples: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
write = vmeRead32(&FAp[id]->adc_config[0]) & 0xFFFF;
// Enable processing
vmeWrite32(&FAp[id]->adc_config[0], (write | FA_ADC_CONFIG0_CHAN_READ_ENABLE) );
// Disable processing
vmeWrite32(&FAp[id]->adc_config[0], (write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
for(ichan = 0; ichan < FA_MAX_ADC_CHANNELS; ichan++)
{
read = vmeRead32(&FAp[id]->adc_status[2]) & FA_ADC_STATUS2_CHAN_DATA_MASK;
// printf("Channel = %2d 0%x \n", ichan, read & 0xFFFF);
if( (ichan % 2)==0 )
{
data[ichan/2] = (data[ichan/2] & 0xFFFF0000) | read;
}
else
{
data[ichan/2] = (data[ichan/2] & 0xFFFF) | (read<<16);
}
}
// printf("faReadAllChannelSamples End readout : adc_config[0] 0x%x \n",(write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
FAUNLOCK;
return (FA_MAX_ADC_CHANNELS/2);
}
/**
* @ingroup Config
* @brief Set the DAC value of the specified channel mask
* @param id Slot number
* @param dvalue DAC Value
* @param chmask Mask of channels to set
* @return OK if successful, otherwise ERROR.
*/
int
faSetDAC(int id, unsigned short dvalue, unsigned short chmask)
{
int ii, doWrite=0, rval=OK;
unsigned int lovalue=0, hivalue=0;
unsigned int lovalue_rb=0, hivalue_rb=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetDAC: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chmask==0) chmask = 0xffff; /* Set All channels the same */
if(dvalue>0xfff)
{
logMsg("faSetDAC: ERROR : DAC value (%d) out of range (0-255) \n",
dvalue,0,0,0,0,0);
return(ERROR);
}
FALOCK;
for(ii=0;iidac[ii]));
hivalue = (vmeRead16(&FAp[id]->dac[ii+1]));
if((1<dac[ii]),
lovalue<<16 | hivalue);
// Alex
// taskDelay(1);
/* Readback to check values, and write timeout error */
lovalue_rb = (vmeRead16(&FAp[id]->dac[ii]));
// taskDelay(1);
hivalue_rb = (vmeRead16(&FAp[id]->dac[ii+1]));
// printf(" lovalue_rb %d %d %d \n", lovalue_rb, lovalue, ii);
// printf(" hivalue_rb %d %d %d \n", hivalue_rb, hivalue, ii);
if((lovalue_rb != lovalue) || (hivalue_rb != hivalue_rb))
{
printf("%s: ERROR: Readback of DAC Channels (%d, %d) != Write value\n",
__FUNCTION__,ii, ii+1);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii, lovalue_rb & FA_DAC_VALUE_MASK,
(lovalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
lovalue);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii+1, hivalue_rb & FA_DAC_VALUE_MASK,
(hivalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
hivalue);
rval=ERROR;
}
}
lovalue = 0;
hivalue = 0;
doWrite=0;
}
}
FAUNLOCK;
return(rval);
}
/**
* @ingroup Config
* @brief Set the DAC value of the specified channel mask and readback and check that it
* was written properly
* @param id Slot number
* @param dvalue DAC Value
* @param chmask Mask of channels to set
* @return OK if successful, otherwise ERROR.
*/
int
faSetDACandCheck(int id, unsigned short dvalue, unsigned short chmask)
{
int ichan, rval=OK;
unsigned short dacRB[FA_MAX_ADC_CHANNELS];
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetDACandCheck: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(faSetDAC(id, dvalue, chmask)!=OK)
return ERROR;
if(faGetDAC(id,(unsigned short *)&dacRB)!=OK)
return ERROR;
for(ichan=0; ichan21) || (FAp[id] == NULL))
{
logMsg("faPrintDAC: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
for(ii=0;iidac[ii])) & FA_DAC_VALUE_MASK;
FAUNLOCK;
printf(" DAC Settings for FADC in slot %d:",id);
for(ii=0;ii21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if(indata==NULL)
{
printf("%s: ERROR: Invalid destintation address\n",
__FUNCTION__);
return ERROR;
}
FALOCK;
for(idac=0;idacdac[idac])) & FA_DAC_VALUE_MASK;
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Readback the DAC for a specific channel by the module in the specified slot.
*
* @param id Slot number
* @param channel Channel number (0-15)
* @return DAC Value if successful, otherwise ERROR.
*/
int
faGetChannelDAC(int id, int channel)
{
int dac;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,id);
return ERROR;
}
if((channel<0)||(channel>15))
{
printf("%s: ERROR: Invalid channel (%d)\n",
__FUNCTION__, channel);
return ERROR;
}
FALOCK;
dac = vmeRead16(&(FAp[id]->dac[channel])) & FA_DAC_VALUE_MASK;
FAUNLOCK;
return dac;
}
/**
* @ingroup Config
* @brief Set the pedestal value of specified channel
*
* The pedestal is the value that will be subtracted from specified channel
* for each sample before it is sent through the trigger path
*
* @param id Slot number
* @param chan Channel Number
* @param ped Pedestal value
* @return OK if successful, otherwise ERROR.
*/
int
faSetChannelPedestal(int id, unsigned int chan, unsigned int ped)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetChannelPedestal: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chan>16)
{
logMsg("faSetChannelPedestal: ERROR : Channel (%d) out of range (0-15) \n",
chan,0,0,0,0,0);
return(ERROR);
}
if(ped>0xffff)
{
logMsg("faSetChannelPedestal: ERROR : PED value (%d) out of range (0-65535) \n",
ped,0,0,0,0,0);
return(ERROR);
}
FALOCK;
vmeWrite32(&FAp[id]->adc_pedestal[chan], ped);
FAUNLOCK;
return(OK);
}
/**
* @ingroup Status
* @brief Get the pedestal value of specified channel
* @param id Slot number
* @param chan Channel Number
* @return OK if successful, otherwise ERROR.
*/
int
faGetChannelPedestal(int id, unsigned int chan)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetChannelPedestal: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chan>16)
{
logMsg("faSetChannelPedestal: ERROR : Channel (%d) out of range (0-15) \n",
chan,0,0,0,0,0);
return(ERROR);
}
FALOCK;
rval = vmeRead32(&FAp[id]->adc_pedestal[chan]) & FA_ADC_PEDESTAL_MASK;
FAUNLOCK;
return(rval);
}
/**
* @ingroup Deprec
* @brief Set the fa250 operation when Sync Reset is received
*
* This routine is deprecated. Use faSetAlignmentDebugMode
*
* @param id Slot number
* @param mode
* - 0: Send a calibration sequence to the CTP for alignment purposes
* - 1: Normal operation
* @sa faSetAlignmentDebugMode
* @return OK if successful, otherwise ERROR.
*/
int
faSetMGTTestMode(int id, unsigned int mode)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return(ERROR);
}
if(mode==0)
printf("%s: This routine is deprecated. Replace with faEnableSyncSrc(int id)\n",
__FUNCTION__);
else
printf("%s: This routine is deprecated. Remove it if after SyncReset\n",
__FUNCTION__);
#ifdef OLDMGTCTRL
FALOCK;
if(mode)
{ /* After Sync Reset (Normal mode) */
vmeWrite32(&FAp[id]->mgt_ctrl, FA_RELEASE_MGT_RESET);
vmeWrite32(&FAp[id]->mgt_ctrl, FA_MGT_FRONT_END_TO_CTP);
}
else
{ /* Before Sync Reset (Calibration Mode) */
vmeWrite32(&FAp[id]->mgt_ctrl,FA_MGT_RESET);
vmeWrite32(&FAp[id]->mgt_ctrl,FA_RELEASE_MGT_RESET);
vmeWrite32(&FAp[id]->mgt_ctrl,FA_MGT_ENABLE_DATA_ALIGNMENT);
}
FAUNLOCK;
#else
if(mode==0) /* Before sync reset */
{
faEnableSyncSrc(id);
}
/* Nothing needs to be done after Sync Reset... now taken care of in faEnable(..) */
#endif /* OLDMGTCTRL */
return(OK);
}
/**
* @ingroup Config
* @brief Enable/Disable the alignment sequence that is sent to the CTP for debugging.
* @param enable
* - 0: Disable
* - >0: Enable
* @return 1 if enabled, 0 if disabled
*/
int
faSetAlignmentDebugMode(int enable)
{
fadcAlignmentDebug = (enable)?1:0;
return fadcAlignmentDebug;
}
/**
* @ingroup Status
* @brief Return whether or not the module will send the alignment sequence to the CTP
* @return 1 if enabled, 0 if disabled
*/
int
faGetAlignmentDebugMode()
{
return fadcAlignmentDebug;
}
/**
* @ingroup Config
* @brief Enable/Disable Hitbits mode on the module
* @param id Slot number
* @param enable
* - 0: Disable
* - >0: Enable
* @return OK if successful, otherwise ERROR.
*/
int
faSetHitbitsMode(int id, int enable)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return(ERROR);
}
FALOCK;
if(enable)
{
vmeWrite32(&FAp[id]->mgt_ctrl,
vmeRead32(&FAp[id]->mgt_ctrl) | FA_MGT_HITBITS_TO_CTP);
}
else
{ /* Before Sync Reset (Calibration Mode) */
vmeWrite32(&FAp[id]->mgt_ctrl,
vmeRead32(&FAp[id]->mgt_ctrl) & ~FA_MGT_HITBITS_TO_CTP);
}
FAUNLOCK;
return(OK);
}
/**
* @ingroup Config
* @brief Enable/Disable Hitbits mode for all initialized fADC250s
* @param enable
* - 0: Disable
* - >0: Enable
*/
void
faGSetHitbitsMode(int enable)
{
int ifadc;
for(ifadc=0;ifadc21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return(ERROR);
}
FALOCK;
rval = (vmeRead32(&FAp[id]->mgt_ctrl)&FA_MGT_HITBITS_TO_CTP)>>3;
FAUNLOCK;
return rval;
}
/**
* @ingroup Readout
* @brief Scaler Data readout routine
*
* Readout the desired scalers (indicated by the channel mask), as well
* as the timer counter. The timer counter will be the last word
* in the "data" array.
*
* @param id Slot number
* @param data - local memory address to place data
* @param chmask - Channel Mask (indicating which channels to read)
* @param rflag - Readout Flag
* - bit 0: Latch Scalers before read
* - bit 1: Clear Scalers after read
* @return OK if successful, otherwise ERROR.
*/
int
faReadScalers(int id, volatile unsigned int *data, unsigned int chmask, int rflag)
{
int doLatch=0, doClear=0, ichan=0;
int dCnt=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
if(rflag & ~(FA_SCALER_CTRL_MASK))
{
logMsg("faReadScalers: WARN : rflag (0x%x) has undefined bits \n",
rflag,0,0,0,0,0);
}
doLatch = rflag&(1<<0);
doClear = rflag&(1<<1);
FALOCK;
if(doLatch)
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_LATCH);
for(ichan=0; ichan<16; ichan++)
{
if( (1<scaler[ichan]);
dCnt++;
}
}
data[dCnt] = vmeRead32(&FAp[id]->time_count);
dCnt++;
if(doClear)
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_RESET);
FAUNLOCK;
return dCnt;
}
/**
* @ingroup Readout
* @brief Scaler Print Out routine
*
* Print out the scalers as well as the timer counter.
*
* @param id Slot number
* @param rflag - Printout Flag
* - bit 0: Latch Scalers before read
* - bit 1: Clear Scalers after read
* @return OK if successful, otherwise ERROR.
*/
int
faPrintScalers(int id, int rflag)
{
int doLatch=0, doClear=0, ichan=0;
unsigned int data[16], time_count;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faPrintScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
if(rflag & ~(FA_SCALER_CTRL_MASK))
{
logMsg("faPrintScalers: WARN : rflag (0x%x) has undefined bits \n",
rflag,0,0,0,0,0);
}
doLatch = rflag&(1<<0);
doClear = rflag&(1<<1);
FALOCK;
if(doLatch)
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_LATCH);
for(ichan=0; ichan<16; ichan++)
{
data[ichan] = vmeRead32(&FAp[id]->scaler[ichan]);
}
time_count = vmeRead32(&FAp[id]->time_count);
if(doClear)
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_RESET);
FAUNLOCK;
printf("%s: Scaler Counts\n",__FUNCTION__);
for(ichan=0; ichan<16; ichan++)
{
if( (ichan%4) == 0 )
printf("\n");
printf("%2d: %10d ",ichan,data[ichan]);
}
printf("\n timer: %10d\n",time_count);
return OK;
}
/**
* @ingroup Config
* @brief Clear the scalers (and enable, if disabled)
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faClearScalers(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faClearScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_RESET);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Latch the current scaler count
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faLatchScalers(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faLatchScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->scaler_ctrl,
FA_SCALER_CTRL_ENABLE | FA_SCALER_CTRL_LATCH);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Enable the scalers to count
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faEnableScalers(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faEnableScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->scaler_ctrl,FA_SCALER_CTRL_ENABLE);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Disable counting in the scalers
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faDisableScalers(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faDisableScalers: ERROR : ADC in slot %d is not initialized \n",
id,0,0,0,0,0);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->scaler_ctrl,~FA_SCALER_CTRL_ENABLE);
FAUNLOCK;
return OK;
}
/**
* @ingroup Status
* @brief Get the minimum address used for multiblock
* @param id Slot number
* @return multiblock min address if successful, otherwise ERROR.
*/
unsigned int
faGetMinA32MB(int id)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = (vmeRead32(&FAp[id]->adr_mb) & FA_AMB_MIN_MASK)<<16;
FAUNLOCK;
return rval;
}
/**
* @ingroup Status
* @brief Get the maximum address used for multiblock
* @param id Slot number
* @return multiblock max address if successful, otherwise ERROR.
*/
unsigned int
faGetMaxA32MB(int id)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->adr_mb) & FA_AMB_MAX_MASK;
FAUNLOCK;
return rval;
}
/**
* @ingroup Config
* @brief Insert ADC parameter word into datastream.
* The data word appears as a block header continuation word.
* @param id Slot number
* @param enable Enable flag
* - 0: Disable
* - !0: Enable
* @return OK if successful, otherwise ERROR.
*/
int
faDataInsertAdcParameters(int id, int enable)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
if(enable)
vmeWrite32(&FAp[id]->ctrl1,
vmeRead32(&FAp[id]->ctrl1) | FA_ENABLE_ADC_PARAMETERS_DATA);
else
vmeWrite32(&FAp[id]->ctrl1,
vmeRead32(&FAp[id]->ctrl1) & ~FA_ENABLE_ADC_PARAMETERS_DATA);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Enable/Disable suppression of one or both of the trigger time words
* in the data stream.
* @param id Slot number
* @param suppress Suppression Flag
* - 0: Trigger time words are enabled in datastream
* - 1: Suppress BOTH trigger time words
* - 2: Suppress trigger time word 2 (that with most significant bytes)
* @return OK if successful, otherwise ERROR.
*/
int
faDataSuppressTriggerTime(int id, int suppress)
{
unsigned int suppress_bits=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
switch(suppress)
{
case 0: /* Enable trigger time words */
suppress_bits = FA_SUPPRESS_TRIGGER_TIME_DATA;
break;
case 1: /* Suppress both trigger time words */
suppress_bits = FA_SUPPRESS_TRIGGER_TIME_DATA;
break;
case 2: /* Suppress trigger time word 2 */
suppress_bits = FA_SUPPRESS_TRIGGER_TIME_WORD2_DATA;
break;
default:
printf("%s(%d): ERROR: Invalid suppress (%d)\n",
__FUNCTION__,id,suppress);
return ERROR;
}
FALOCK;
if(suppress)
vmeWrite32(&FAp[id]->ctrl1,
vmeRead32(&FAp[id]->ctrl1) | suppress_bits);
else
vmeWrite32(&FAp[id]->ctrl1,
vmeRead32(&FAp[id]->ctrl1) & ~suppress_bits);
FAUNLOCK;
return OK;
}
/**
* @ingroup Status
* @brief Return raw register data from the Control FPGA containing the temperature,
* core voltage, and auxiliary voltage.
* @param id Slot number
* @return Register value if successful, otherwise ERROR.
*/
unsigned int
faGetCtrlFPGAData(int id)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->system_monitor);
FAUNLOCK;
return rval;
}
/**
* @ingroup Status
* @brief Return raw register data from the Processing FPGA containing the temperature.
* @param id Slot number
* @return Register value if successful, otherwise ERROR.
*/
unsigned int
faGetProcFPGAData(int id)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->status3) & 0xFFFF;
FAUNLOCK;
return rval;
}
/**
* @ingroup Status
* @brief Return the value of the Control FPGA temperature (in degrees Celsius)
* @param id Slot number
* @param pflag Print Flag
* - !0: Print temperature to standard out
* @return Temperature if successful, otherwise ERROR.
*/
float
faGetCtrlFPGATemp(int id, int pflag)
{
float rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval =
((float)(vmeRead32(&FAp[id]->system_monitor) & FA_SYSMON_CTRL_TEMP_MASK) *
(503.975/1024.0) - 273.15);
FAUNLOCK;
if(pflag)
{
printf("%s: CTRL FPGA Temperature = %.1f [deg C]\n",
__FUNCTION__,rval);
}
return rval;
}
/**
* @ingroup Status
* @brief Return the value of specified Control FPGA voltage.
* @param id Slot number
* @param vtype Voltage type
* - 0: Core Voltage
* - 1: Auxiliary Voltage
* @param pflag Print flag
* - !0: Print voltage to standard out.
* @return Specified voltage if successful, otherwise ERROR.
*/
float
faGetCtrlFPGAVoltage(int id, int vtype, int pflag)
{
float rval=0;
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
if((pflag>2) || (pflag<0))
{
printf("%s: ERROR: Invalid vtype (%d)\n",
__FUNCTION__,vtype);
return ERROR;
}
FALOCK;
reg = vmeRead32(&FAp[id]->system_monitor);
if(vtype==0)
{
reg = (reg & FA_SYSMON_FPGA_CORE_V_MASK)>>11;
}
else
{
reg = (reg & FA_SYSMON_FPGA_AUX_V_MASK)>>22;
}
rval = ((float)(reg))*3.0/1024.0;
FAUNLOCK;
if(pflag)
{
printf("%s: CTRL FPGA %s Voltage = %.1f [V]\n",
__FUNCTION__,
(vtype==0)?
"Core":
"Auxiliary",
rval);
}
return rval;
}
/**
* @ingroup Status
* @brief Return the value of the Processing FPGA temperature (in degrees Celsius)
* @param id Slot number
* @param pflag Print Flag
* - !0: Print temperature to standard out
* @return Temperature if successful, otherwise ERROR.
*/
float
faGetProcFPGATemp(int id, int pflag)
{
float rval=0;
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
reg = (vmeRead32(&FAp[id]->status3) & FA_STATUS3_PROC_TEMP_MASK);
rval = ((float)reg * (503.975/1024.0) - 273.15);
FAUNLOCK;
if(pflag)
{
printf("%s: PROC FPGA Temperature = %.1f [deg C]\n",
__FUNCTION__,rval);
}
return rval;
}
/* -------------------------------------------------------------------------------------
Utility routines
*/
/**
* @ingroup Status
* @brief Print to standard out some auxillary scalers
*
* Prints out
* - Total number of words generated
* - Total number of headers generated
* - Total number of trailers generated
* - Total number of lost triggers
*
* @param id Slot number
*/
void
faPrintAuxScal(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faPrintAuxScal: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
printf("Auxillary Scalers:\n");
printf(" Word Count: %d\n",
vmeRead32(&FAp[id]->proc_words_scal));
printf(" Headers : %d\n",
vmeRead32(&FAp[id]->header_scal));
printf(" Trailers : %d\n",
vmeRead32(&FAp[id]->trailer_scal));
printf(" Lost Triggers : %d\n",
vmeRead32(&FAp[id]->lost_trig_scal));
FAUNLOCK;
return;
}
/**
* @ingroup Status
* @brief Print the status of the FIFO to standard out
* @param id Slot number
*/
void
faPrintFifoStatus(int id)
{
unsigned int ibuf, bbuf, obuf, dflow;
unsigned int wc[2],mt[2],full[2];
unsigned int rdy[2];
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faPrintFifoStatus: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
dflow = vmeRead32(&(FAp[id]->dataflow_status));
ibuf = vmeRead32(&(FAp[id]->status[0]))&0xdfffdfff;
bbuf = vmeRead32(&(FAp[id]->status[1]))&0x1fff1fff;
obuf = vmeRead32(&(FAp[id]->status[2]))&0x3fff3fff;
FAUNLOCK;
printf("%s: Fifo Buffers Status (DataFlow Status = 0x%08x\n",
__FUNCTION__,dflow);
mt[1] = full[1] = 0;
wc[1] = (ibuf&0x7ff0000)>>16;
rdy[1] = (ibuf&0x80000000)>>31;
if(ibuf&0x8000000) full[1]=1;
if(ibuf&0x10000000) mt[1]=1;
printf(" Input Buffer : 0x%08x \n",ibuf);
printf(" FPGA : wc=%d Empty=%d Full=%d Ready=%d\n",wc[1],mt[1],full[1],rdy[1]);
mt[0]=full[0]=0;
wc[0] = bbuf&0x7ff;
if(bbuf&0x800) full[0]=1;
if(bbuf&0x1000) mt[0]=1;
mt[1]=full[1]=0;
wc[1] = (bbuf&0x7ff0000)>>16;
if(bbuf&0x8000000) full[1]=1;
if(bbuf&0x10000000) mt[1]=1;
printf(" Build Buffer : 0x%08x \n",bbuf);
printf(" BUF_A: wc=%d Empty=%d Full=%d \n",wc[1],mt[1],full[1]);
printf(" BUF_B: wc=%d Empty=%d Full=%d \n",wc[0],mt[0],full[0]);
mt[0]=full[0]=0;
wc[0] = obuf&0xfff;
if(obuf&0x1000) full[0]=1;
if(obuf&0x2000) mt[0]=1;
mt[1]=full[1]=0;
wc[1] = (obuf&0xfff0000)>>16;
if(obuf&0x10000000) full[1]=1;
if(obuf&0x20000000) mt[1]=1;
printf(" Output Buffer: 0x%08x \n",obuf);
printf(" BUF_A: wc=%d Empty=%d Full=%d \n",wc[1],mt[1],full[1]);
printf(" BUF_B: wc=%d Empty=%d Full=%d \n",wc[0],mt[0],full[0]);
return;
}
/**
* @ingroup Status
* @brief Decode a data word from an fADC250 and print to standard out.
* @param data 32bit fADC250 data word
*/
void
faDataDecode(unsigned int data)
{
int i_print = 1;
static unsigned int type_last = 15; /* initialize to type FILLER WORD */
static unsigned int time_last = 0;
int idata=0;
if( data & 0x80000000 ) /* data type defining word */
{
fadc_data.new_type = 1;
fadc_data.type = (data & 0x78000000) >> 27;
}
else
{
fadc_data.new_type = 0;
fadc_data.type = type_last;
}
switch( fadc_data.type )
{
case 0: /* BLOCK HEADER */
if( fadc_data.new_type )
{
fadc_data.slot_id_hd = ((data) & 0x7C00000) >> 22;
fadc_data.modID = (data & 0x3C0000)>>18;
fadc_data.blk_num = (data & 0x3FF00) >> 8;
fadc_data.n_evts = (data & 0xFF);
if( i_print )
printf("%8X - BLOCK HEADER - slot = %d modID = %d n_evts = %d n_blk = %d\n",
data, fadc_data.slot_id_hd,
fadc_data.modID, fadc_data.n_evts, fadc_data.blk_num);
}
else
{
fadc_data.PL = (data & 0x1FFC0000) >> 18;
fadc_data.NSB = (data & 0x0003FE00) >> 9;
fadc_data.NSA = (data & 0x000001FF) >> 0;
printf("%8X - BLOCK HEADER 2 - PL = %d NSB = %d NSA = %d\n",
data,
fadc_data.PL,
fadc_data.NSB,
fadc_data.NSA);
}
break;
case 1: /* BLOCK TRAILER */
fadc_data.slot_id_tr = (data & 0x7C00000) >> 22;
fadc_data.n_words = (data & 0x3FFFFF);
if( i_print )
printf("%8X - BLOCK TRAILER - slot = %d n_words = %d\n",
data, fadc_data.slot_id_tr, fadc_data.n_words);
break;
case 2: /* EVENT HEADER */
fadc_data.time_low_10 = (data & 0x003FF000) >> 12;
fadc_data.evt_num_1 = (data & 0x3FFFFF);
if( i_print )
printf("%8X - EVENT HEADER 1 - trig time = %d trig num = %d\n", data,
fadc_data.time_low_10, fadc_data.evt_num_1);
break;
case 3: /* TRIGGER TIME */
if( fadc_data.new_type )
{
fadc_data.time_1 = (data & 0x07FFFFFF);
if( i_print )
printf("%8X - TRIGGER TIME 1 - time = %08x\n", data, fadc_data.time_1);
fadc_data.time_now = 1;
time_last = 1;
}
else
{
if( time_last == 1 )
{
fadc_data.time_2 = (data & 0xFFFFFF);
if( i_print )
printf("%8X - TRIGGER TIME 2 - time = %08x\n", data, fadc_data.time_2);
fadc_data.time_now = 2;
}
else if( time_last == 2 )
{
fadc_data.time_3 = (data & 0xFFFFFF);
if( i_print )
printf("%8X - TRIGGER TIME 3 - time = %08x\n", data, fadc_data.time_3);
fadc_data.time_now = 3;
}
else if( time_last == 3 )
{
fadc_data.time_4 = (data & 0xFFFFFF);
if( i_print )
printf("%8X - TRIGGER TIME 4 - time = %08x\n", data, fadc_data.time_4);
fadc_data.time_now = 4;
}
else
if( i_print )
printf("%8X - TRIGGER TIME - (ERROR)\n", data);
time_last = fadc_data.time_now;
}
break;
case 4: /* WINDOW RAW DATA */
if( fadc_data.new_type )
{
fadc_data.chan = (data & 0x7800000) >> 23;
fadc_data.width = (data & 0xFFF);
if( i_print )
printf("%8X - WINDOW RAW DATA - chan = %d nsamples = %d\n",
data, fadc_data.chan, fadc_data.width);
}
else
{
fadc_data.valid_1 = 1;
fadc_data.valid_2 = 1;
fadc_data.adc_1 = (data & 0x1FFF0000) >> 16;
if( data & 0x20000000 )
fadc_data.valid_1 = 0;
fadc_data.adc_2 = (data & 0x1FFF);
if( data & 0x2000 )
fadc_data.valid_2 = 0;
if( i_print )
printf("%8X - RAW SAMPLES - valid = %d adc = %4d valid = %d adc = %4d\n",
data, fadc_data.valid_1, fadc_data.adc_1,
fadc_data.valid_2, fadc_data.adc_2);
}
break;
case 5: /* UNDEFINED TYPE */
if( i_print )
printf("%8X - UNDEFINED TYPE = %d\n", data, fadc_data.type);
break;
case 6: /* PULSE RAW DATA */
if( fadc_data.new_type )
{
fadc_data.chan = (data & 0x7800000) >> 23;
fadc_data.pulse_num = (data & 0x600000) >> 21;
fadc_data.thres_bin = (data & 0x3FF);
if( i_print )
printf("%8X - PULSE RAW DATA - chan = %d pulse # = %d threshold bin = %d\n",
data, fadc_data.chan, fadc_data.pulse_num, fadc_data.thres_bin);
}
else
{
fadc_data.valid_1 = 1;
fadc_data.valid_2 = 1;
fadc_data.adc_1 = (data & 0x1FFF0000) >> 16;
if( data & 0x20000000 )
fadc_data.valid_1 = 0;
fadc_data.adc_2 = (data & 0x1FFF);
if( data & 0x2000 )
fadc_data.valid_2 = 0;
if( i_print )
printf("%8X - PULSE RAW SAMPLES - valid = %d adc = %d valid = %d adc = %d\n",
data, fadc_data.valid_1, fadc_data.adc_1,
fadc_data.valid_2, fadc_data.adc_2);
}
break;
case 7: /* PULSE INTEGRAL */
fadc_data.chan = (data & 0x7800000) >> 23;
fadc_data.pulse_num = (data & 0x600000) >> 21;
fadc_data.quality = (data & 0x180000) >> 19;
fadc_data.integral = (data & 0x7FFFF);
if( i_print )
printf("%8X - PULSE INTEGRAL - chan = %d pulse # = %d quality = %d integral = %d\n",
data, fadc_data.chan, fadc_data.pulse_num,
fadc_data.quality, fadc_data.integral);
break;
case 8: /* PULSE TIME */
fadc_data.chan = (data & 0x7800000) >> 23;
fadc_data.pulse_num = (data & 0x600000) >> 21;
fadc_data.quality = (data & 0x180000) >> 19;
fadc_data.time = (data & 0xFFFF);
if( i_print )
printf("%8X - PULSE TIME - chan = %d pulse # = %d quality = %d time = %d\n",
data, fadc_data.chan, fadc_data.pulse_num,
fadc_data.quality, fadc_data.time);
break;
case 9: /* PULSE PARAMETERS */
if( fadc_data.new_type )
{ /* Channel ID and Pedestal Info */
fadc_data.pulse_num = 0; /* Initialize */
fadc_data.evt_of_blk = (data & 0x07f80000)>>19;
fadc_data.chan = (data & 0x00078000)>>15;
fadc_data.quality = (data & (1<<14))>>14;
fadc_data.ped_sum = (data & 0x00003fff);
printf("%8X - PULSEPARAM 1 - evt = %d chan = %d quality = %d pedsum = %d\n",
data,
fadc_data.evt_of_blk,
fadc_data.chan,
fadc_data.quality,
fadc_data.ped_sum);
}
else
{
if(data & (1<<30))
{ /* Word 1: Integral of n-th pulse in window */
fadc_data.pulse_num++;
fadc_data.adc_sum = (data & 0x3ffff000)>>12;
fadc_data.nsa_ext = (data & (1<<11))>>11;
fadc_data.over = (data & (1<<10))>>10;
fadc_data.under = (data & (1<<9))>>9;
fadc_data.samp_ov_thres = (data & 0x000001ff);
printf("%8X - PULSEPARAM 2 - P# = %d Sum = %d NSA+ = %d Ov/Un = %d/%d #OT = %d\n",
data,
fadc_data.pulse_num,
fadc_data.adc_sum,
fadc_data.nsa_ext,
fadc_data.over,
fadc_data.under,
fadc_data.samp_ov_thres);
}
else
{ /* Word 2: Time of n-th pulse in window */
fadc_data.time_coarse = (data & 0x3fe00000)>>21;
fadc_data.time_fine = (data & 0x001f8000)>>15;
fadc_data.vpeak = (data & 0x00007ff8)>>3;
fadc_data.quality = (data & 0x2)>>1;
fadc_data.quality2 = (data & 0x1);
printf("%8X - PULSEPARAM 3 - CTime = %d FTime = %d Peak = %d NoVp = %d Q = %d\n",
data,
fadc_data.time_coarse,
fadc_data.time_fine,
fadc_data.vpeak,
fadc_data.quality,
fadc_data.quality2);
}
}
break;
case 10: /* UNDEFINED TYPE */
if( i_print )
printf("%8X - UNDEFINED TYPE = %d\n", data, fadc_data.type);
break;
case 11: /* UNDEFINED TYPE */
if( i_print )
printf("%8X - UNDEFINED TYPE = %d\n", data, fadc_data.type);
break;
case 12: /* SCALER HEADER */
if( fadc_data.new_type )
{
fadc_data.scaler_data_words = (data & 0x3F);
if( i_print )
printf("%8X - SCALER HEADER - data words = %d\n", data, fadc_data.scaler_data_words);
}
else
{
for(idata=0; idata0: Enable Test Mode
*/
void
faTestSetSystemTestMode(int id, int mode)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
if(mode>=1)
reg=FA_CTRL1_SYSTEM_TEST_MODE;
else
reg=0;
FALOCK;
vmeWrite32(&(FAp[id]->ctrl1),
vmeRead32(&FAp[id]->ctrl1) | reg);
/* printf(" ctrl1 = 0x%08x\n",vmeRead32(&FAp[id]->ctrl1)); */
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set the level of Trig Out to the SD
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @param mode
* - 0: Not asserted
* - >0: Asserted
*/
void
faTestSetTrigOut(int id, int mode)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
if(mode>=1)
reg=FA_TESTBIT_TRIGOUT;
else
reg=0;
FALOCK;
vmeWrite32(&(FAp[id]->testBit),reg);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set the level of Busy Out to the SD
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @param mode
* - 0: Not asserted
* - >0: Asserted
*/
void
faTestSetBusyOut(int id, int mode)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
if(mode>=1)
reg=FA_TESTBIT_BUSYOUT;
else
reg=0;
FALOCK;
vmeWrite32(&(FAp[id]->testBit),reg);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set the level of the SD Link
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @param mode
* - 0: Not asserted
* - >0: Asserted
*/
void
faTestSetSdLink(int id, int mode)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
if(mode>=1)
reg=FA_TESTBIT_SDLINKOUT;
else
reg=0;
FALOCK;
vmeWrite32(&(FAp[id]->testBit),reg);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Set the level of Token Out to the SD
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @param mode
* - 0: Not asserted
* - >0: Asserted
*/
void
faTestSetTokenOut(int id, int mode)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
if(mode>=1)
reg=FA_TESTBIT_TOKENOUT;
else
reg=0;
FALOCK;
vmeWrite32(&(FAp[id]->testBit),reg);
FAUNLOCK;
}
/**
* @ingroup Status
* @brief Get the level of the StatBitB to the SD
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return 1 if asserted, 0 if not, otherwise ERROR.
*/
int
faTestGetStatBitB(int id)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = (vmeRead32(&FAp[id]->testBit) & FA_TESTBIT_STATBITB)>>8;
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Get the level of the Token In from the SD
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return 1 if asserted, 0 if not, otherwise ERROR.
*/
int
faTestGetTokenIn(int id)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = (vmeRead32(&FAp[id]->testBit) & FA_TESTBIT_TOKENIN)>>9;
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Return the status of the 250Mhz Clock Counter
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return 1 if counting, 0 if not counting, otherwise ERROR.
*/
int
faTestGetClock250CounterStatus(int id)
{
int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = (vmeRead32(&FAp[id]->testBit) & FA_TESTBIT_CLOCK250_STATUS)>>15;
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Return the value of the 250Mhz Clock scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return 250Mhz Clock scaler counter if successful, otherwise ERROR.
*/
unsigned int
faTestGetClock250Counter(int id)
{
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = vmeRead32(&FAp[id]->clock250count);
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Return the value of the SyncReset scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return SyncReset scaler counter if successful, otherwise ERROR.
*/
unsigned int
faTestGetSyncCounter(int id)
{
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = vmeRead32(&FAp[id]->syncp0count);
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Return the value of the trig1 scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return trig1 scaler counter if successful, otherwise ERROR.
*/
unsigned int
faTestGetTrig1Counter(int id)
{
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = vmeRead32(&FAp[id]->trig1p0count);
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Return the value of the trig2 scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return trig2 scaler counter if successful, otherwise ERROR.
*/
unsigned int
faTestGetTrig2Counter(int id)
{
unsigned int reg=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
reg = vmeRead32(&FAp[id]->trig2p0count);
FAUNLOCK;
return reg;
}
/**
* @ingroup Status
* @brief Reset the counter of the 250MHz Clock scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
*/
void
faTestResetClock250Counter(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
FALOCK;
vmeWrite32(&FAp[id]->clock250count,FA_CLOCK250COUNT_RESET);
vmeWrite32(&FAp[id]->clock250count,FA_CLOCK250COUNT_START);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Reset the counter of the SyncReset scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
*/
void
faTestResetSyncCounter(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
FALOCK;
vmeWrite32(&FAp[id]->syncp0count,FA_SYNCP0COUNT_RESET);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Reset the counter of the trig1 scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
*/
void
faTestResetTrig1Counter(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
FALOCK;
vmeWrite32(&FAp[id]->trig1p0count,FA_TRIG1P0COUNT_RESET);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Reset the counter of the trig2 scaler
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
*/
void
faTestResetTrig2Counter(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return;
}
FALOCK;
vmeWrite32(&FAp[id]->trig2p0count,FA_TRIG2P0COUNT_RESET);
FAUNLOCK;
}
/**
* @ingroup Status
* @brief Return the current value of the testBit register
*
* Available only in System Test Mode
*
* @sa faTestSetSystemTestMode
* @param id Slot number
* @return testBit register value if successful, otherwise ERROR.
*/
unsigned int
faTestGetTestBitReg(int id)
{
unsigned int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return 0;
}
FALOCK;
rval = vmeRead32(&FAp[id]->testBit);
FAUNLOCK;
return rval;
}
/**
* @ingroup Status
* @brief Fills 'rval' with a character array containing the fa250 serial number.
* @param id Slot number
* @param rval Where to return Serial number string
* @param snfix
*
* If snfix >= 1, will attempt to format the serial number to maintain
* consistency between serials made by the same vendor.
* e.g. Advanced Assembly:
* snfix=0: B21595-02R B2159515R1
* snfix=1: B21595-02R B21595-15R1
* e.g. ACDI
* snfix=0: ACDI002
* snfix=1: ACDI-002
*
* @return length of character array 'rval' if successful, otherwise ERROR
*/
int
faGetSerialNumber(int id, char **rval, int snfix)
{
unsigned int sn[3];
int i=0, ivme=0, ibyte=0;
unsigned int byte, prev_byte;
unsigned int shift=0, mask=0;
unsigned int boardID;
char boardID_c[4];
char byte_c[2];
char adv_str[12], acdi_str[12];
char ret[12];
int ret_len;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
for(i=0; i<3; i++)
sn[i] = vmeRead32(&FAp[id]->serial_number[i]);
FAUNLOCK;
if(sn[0]==FA_SERIAL_NUMBER_ACDI)
{ /* ACDI */
strcpy(acdi_str,"");
for(ibyte=3; ibyte>=0; ibyte--)
{
shift = (ibyte*8);
mask = (0xFF)<>shift;
sprintf(byte_c,"%c",byte);
strcat(acdi_str,byte_c);
}
boardID = (sn[1] & FA_SERIAL_NUMBER_ACDI_BOARDID_MASK);
if(boardID>999)
{
printf("%s: WARN: Invalid Board ACDI Board ID (%d)\n",
__FUNCTION__,boardID);
}
if(snfix>0) /* If needed, Add '-' after the ACDI */
sprintf(boardID_c,"-%03d",boardID);
else
sprintf(boardID_c,"%03d",boardID);
strcat(acdi_str,boardID_c);
#ifdef DEBUGSN
printf("acdi_str = %s\n",acdi_str);
#endif
strcpy(ret,acdi_str);
}
else if((sn[0] & FA_SERIAL_NUMBER_ADV_ASSEM_MASK)==FA_SERIAL_NUMBER_ADV_ASSEM)
{ /* ADV ASSEM */
/* Make sure manufacture's ID is correct */
if((sn[0] == FA_SERIAL_NUMBER_ADV_MNFID1) &&
((sn[1] & FA_SERIAL_NUMBER_ADV_MNFID2_MASK) == FA_SERIAL_NUMBER_ADV_MNFID2) )
{
strcpy(adv_str,"");
for(ivme=0; ivme<3; ivme++)
{
for(ibyte=3; ibyte>=0; ibyte--)
{
shift = (ibyte*8);
mask = (0xFF)<>shift;
if(byte==0xFF)
{
break;
}
if(snfix>0)
{ /* If needed, Add '-' after the B21595 */
if(ivme==1 && ibyte==1)
{
if(byte!=0x2D) /* 2D = - */
{
strcat(adv_str,"-");
}
}
}
sprintf(byte_c,"%c",byte);
strcat(adv_str,byte_c);
prev_byte = byte;
}
}
#ifdef DEBUGSN
printf("adv_str = %s\n",adv_str);
#endif
strcpy(ret,adv_str);
}
else
{
printf("%s: ERROR: Unable to determine manufacture's ID. SN regs:\n",
__FUNCTION__);
for(i=0; i<3; i++)
printf("\t%d: 0x%08x\n",i,sn[i]);
return -1;
}
}
else
{
printf("%s: ERROR: Unable to determine manufacture's ID. SN regs:\n",
__FUNCTION__);
for(i=0; i<3; i++)
printf("\t%d: 0x%08x\n",i,sn[i]);
return -1;
}
#ifdef DEBUGSN
printf("ret = %s\n",ret);
#endif
strcpy((char *)rval,ret);
ret_len = (int)strlen(ret);
return(ret_len);
}
/**
* @ingroup Config
* @brief Set the block interval of scaler data insertion
*
* Data from scalers may be inserted into the readout data stream at
* regular event count intervals. The interval is specified in
* multiples of blocks.
* Note: Scalers are NOT reset after their values are captured.
*
* @param id Slot number
* @param nblock
* - 0: No insertion of scaler data into the data stream
* - >=1: The current scaler values are appended to the last event of the appropriate n'th block of events.
* @return OK if successful, otherwise ERROR.
*/
int
faSetScalerBlockInterval(int id, unsigned int nblock)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
if(nblock > FA_SCALER_INTERVAL_MASK)
{
printf("%s: ERROR: Invalid value of nblock (%d).\n",
__FUNCTION__,nblock);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->scaler_interval,nblock);
FAUNLOCK;
return OK;
}
/**
* @ingroup Status
* @brief
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faGetScalerBlockInterval(int id)
{
int rval=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",__FUNCTION__,
id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->scaler_interval) & FA_SCALER_INTERVAL_MASK;
FAUNLOCK;
return rval;
}
/**
* @ingroup Config
* @brief Allows for the insertion of a block trailer into the data stream.
*
* Allows for the insertion of a block trailer into the data stream. This is
* useful for the efficient extraction of a partial block of events
* from the FADC (e.g. for an end of run event, or the resynchonize with
* other modules).
* Event count within block is reset, after successful execution.
*
* @param id Slot number
* @param scalers If set to > 0, scalers will also be inserted with the End of Block
* @return OK if successful, otherwise ERROR.
*/
int
faForceEndOfBlock(int id, int scalers)
{
int rval=OK, icheck=0, timeout=1000, csr=0;
int proc_config=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faForceEndOfBlock: ERROR : ADC in slot %d is not initialized \n",
id,2,3,4,5,6);
return ERROR;
}
FALOCK;
/* Disable triggers to Processing FPGA (if enabled) */
proc_config = vmeRead32(&FAp[id]->adc_config[0]);
vmeWrite32(&FAp[id]->adc_config[0],
proc_config & ~(FA_ADC_PROC_ENABLE));
csr = FA_CSR_FORCE_EOB_INSERT;
if(scalers>0)
csr |= FA_CSR_DATA_STREAM_SCALERS;
vmeWrite32(&FAp[id]->csr, csr);
for(icheck=0; icheckcsr);
if(csr & FA_CSR_FORCE_EOB_SUCCESS)
{
logMsg("faForceEndOfBlock: Block trailer insertion successful\n",
1,2,3,4,5,6);
rval = ERROR;
break;
}
if(csr & FA_CSR_FORCE_EOB_FAILED)
{
logMsg("faForceEndOfBlock: Block trailer insertion FAILED\n",
1,2,3,4,5,6);
rval = ERROR;
break;
}
}
if(icheck==timeout)
{
logMsg("faForceEndOfBlock: Block trailer insertion FAILED on timeout\n",
1,2,3,4,5,6);
rval = ERROR;
}
/* Restore the original state of the Processing FPGA */
vmeWrite32(&FAp[id]->adc_config[0], proc_config);
FAUNLOCK;
return rval;
}
/**
* @ingroup Config
* @brief Allows for the insertion of a block trailer into the data stream for all
* initialized fADC250s
*
* Allows for the insertion of a block trailer into the data stream. This is
* useful for the efficient extraction of a partial block of events
* from the FADC (e.g. for an end of run event, or the resynchonize with
* other modules).
* Event count within block is reset, after successful execution.
*
* @param scalers If set to > 0, scalers will also be inserted with the End of Block
*/
void
faGForceEndOfBlock(int scalers)
{
int ii, res;
for (ii=0;ii21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
if(thres>FA_SUM_THRESHOLD_MASK)
{
printf("%s: ERROR: Invalid value for threshold (%d)\n",
__FUNCTION__,thres);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->sum_threshold,thres);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the threshold to trigger for the history buffer to be saved for readout
* for all initialized fADC250s
* @param thres History Buffer Threshold
*/
void
faGSetHistoryBufferThreshold(int thres)
{
int ifa=0;
for (ifa=0;ifa21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
FALOCK;
rval = vmeRead32(&FAp[id]->sum_threshold) & FA_SUM_THRESHOLD_MASK;
FAUNLOCK;
return rval;
}
/**
* @ingroup Config
* @brief Enable the history buffer for data acquisition for the module
* @param id Slot number
* @return OK if successful, otherwise ERROR.
*/
int
faArmHistoryBuffer(int id)
{
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faArmHistoryBuffer: ERROR : ADC in slot %d is not initialized \n",
id,2,3,4,5,6);
return ERROR;
}
FALOCK;
vmeWrite32(&FAp[id]->sum_data, FA_SUM_DATA_ARM_HISTORY_BUFFER);
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Enable the history buffer for data acquisition for all initialized fADC250s
*/
void
faGArmHistoryBuffer()
{
int ifa=0;
for (ifa=0;ifa21) || (FAp[id] == NULL))
{
logMsg("faHistoryBufferDReady: ERROR : ADC in slot %d is not initialized \n",
id,2,3,4,5,6);
return ERROR;
}
FALOCK;
rval = (vmeRead32(&FAp[id]->sum_threshold) & FA_SUM_THRESHOLD_DREADY)>>31;
FAUNLOCK;
return rval;
}
/**
* @ingroup Readout
* @brief Read out history buffer from the module
* @param id Slot number
* @param data local memory address to place data
* @param nwrds Max number of words to transfer
* @return Number of words read if successful, otherwise ERROR.
*/
int
faReadHistoryBuffer(int id, volatile unsigned int *data, int nwrds)
{
int idata=0, dCnt=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faHistoryBufferDReady: ERROR : ADC in slot %d is not initialized \n",
id,2,3,4,5,6);
return ERROR;
}
FALOCK;
while(idatasum_data) & FA_SUM_DATA_SAMPLE_MASK;
#ifndef VXWORKS
data[idata] = LSWAP(data[idata]);
#endif
idata++;
}
idata++;
/* Use this to clear the data ready bit (dont set back to zero) */
vmeWrite32(&FAp[id]->sum_data,FA_SUM_DATA_ARM_HISTORY_BUFFER);
FAUNLOCK;
dCnt += idata;
return dCnt;
}
const char *fa_mode_names[FA_MAX_PROC_MODE+1] =
{
"NOT DEFINED", // 0
"NOT DEFINED",
"NOT DEFINED",
"NOT DEFINED",
"NOT DEFINED",
"NOT DEFINED", // 5
"NOT DEFINED",
"NOT DEFINED",
"NOT DEFINED",
"PULSE PARAMETER", // 9
"RAW + PULSE PARAMETER" // 10
};
/***************************************************************************************
JLAB FADC Signal Distribution Card (SDC) Routines
***************************************************************************************/
/**
* @ingroup SDCConfig
* @brief Configure the Signal Distribution Card (SDC)
* @param id Slot number
* @param cFlag controls the configuation of the SDC
* - 0: Default Mode Internal CLK, Sync External Trigger and Sync Reset
* - >0: Pass through mode
* @param bMask: mask of Busy enables for the SDC - Do not Enable busy if there is no FADC
* @return OK if successful, otherwise ERROR.
*/
int
faSDC_Config(unsigned short cFlag, unsigned short bMask)
{
if(FASDCp == NULL)
{
logMsg("faSDC_Config: ERROR : Cannot Configure FADC Signal Board \n",0,0,0,0,0,0);
return(ERROR);
}
/* Reset the Board */
FASDCLOCK;
vmeWrite16(&(FASDCp->csr),FASDC_CSR_INIT);
if(cFlag == 0)
{
/* Default - Enable Internal Clock, Sync Trigger and Sync-Reset*/
vmeWrite16(&(FASDCp->ctrl),(FASDC_CTRL_ENABLE_SOFT_TRIG | FASDC_CTRL_ENABLE_SOFT_SRESET));
}
else if(cFlag==1)
{
/* Pass Through - */
vmeWrite16(&(FASDCp->ctrl),(FASDC_CTRL_NOSYNC_TRIG | FASDC_CTRL_NOSYNC_SRESET |
FASDC_CTRL_ENABLE_SOFT_TRIG | FASDC_CTRL_ENABLE_SOFT_SRESET));
}
else
{
/* Level Translator */
vmeWrite16(&(FASDCp->ctrl),(FASDC_CTRL_NOSYNC_TRIG | FASDC_CTRL_NOSYNC_SRESET));
}
vmeWrite16(&(FASDCp->busy_enable),bMask);
FASDCUNLOCK;
return(OK);
}
/**
* @ingroup SDCStatus
* @brief Print status of SDC to standard out
* @param sFlag Not used
*/
void
faSDC_Status(int sFlag)
{
unsigned short sdc[4];
if(FASDCp == NULL)
{
printf("faSDC_Status: ERROR : No FADC SDC available \n");
return;
}
FASDCLOCK;
sdc[0] = vmeRead16(&(FASDCp->csr));
sdc[1] = vmeRead16(&(FASDCp->ctrl))&FASDC_CTRL_MASK;
sdc[2] = vmeRead16(&(FASDCp->busy_enable))&FASDC_BUSY_MASK;
sdc[3] = vmeRead16(&(FASDCp->busy_status));
FASDCUNLOCK;
#ifdef VXWORKS
printf("\nSTATUS for FADC Signal Distribution Card at base address 0x%x \n",(UINT32) FASDCp);
#else
printf("\nSTATUS for FADC Signal Distribution Card at VME (Local) base address 0x%x (0x%lx)\n",
(UINT32)((unsigned long)FASDCp - fadcA16Offset), (unsigned long) FASDCp);
#endif
printf("---------------------------------------------------------------- \n");
printf(" Board Firmware Rev/ID = 0x%02x\n",((sdc[0]&0xff00)>>8));
printf(" Registers: \n");
printf(" CSR = 0x%04x Control = 0x%04x\n",sdc[0],sdc[1]);
printf(" Busy Enable = 0x%04x Busy Status = 0x%04x\n",sdc[2],sdc[3]);
printf("\n");
if((sdc[1]&FASDC_CTRL_CLK_EXT))
printf(" Ref Clock : External\n");
else
printf(" Ref Clock : Internal\n");
if((sdc[1]&FASDC_CTRL_ENABLE_SOFT_TRIG))
{
printf(" Software Triggers\n");
}
else
{
if((sdc[1]&FASDC_CTRL_NOSYNC_TRIG))
printf(" External Triggers (Pass through)\n");
else
printf(" External Triggers (Sync with clock)\n");
}
if((sdc[1]&FASDC_CTRL_ENABLE_SOFT_SRESET))
{
printf(" Software Sync Reset\n");
}
else
{
if((sdc[1]&FASDC_CTRL_NOSYNC_SRESET))
printf(" External Sync Reset (Pass through)\n");
else
printf(" External Sync Reset (Sync with clock)\n");
}
}
/**
* @ingroup SDCConfig
* @brief Enable Triggers and/or SyncReset on the SDC
* @param nsync
* - 0: Front panel triggers and syncreset
* - !0: Front panel triggers only
*/
void
faSDC_Enable(int nsync)
{
if(FASDCp == NULL)
{
logMsg("faSDC_Enable: ERROR : No FADC SDC available \n",0,0,0,0,0,0);
return;
}
FASDCLOCK;
if(nsync != 0) /* FP triggers only */
vmeWrite16(&(FASDCp->ctrl),FASDC_CTRL_ENABLE_SOFT_SRESET);
else /* both FP triggers and sync reset */
vmeWrite16(&(FASDCp->ctrl),0);
FASDCUNLOCK;
}
/**
* @ingroup SDCConfig
* @brief Disable Triggers and SyncReset on the SDC
*/
void
faSDC_Disable()
{
if(FASDCp == NULL)
{
logMsg("faSDC_Disable: ERROR : No FADC SDC available \n",0,0,0,0,0,0);
return;
}
FASDCLOCK;
vmeWrite16(&(FASDCp->ctrl),(FASDC_CTRL_ENABLE_SOFT_TRIG | FASDC_CTRL_ENABLE_SOFT_SRESET));
FASDCUNLOCK;
}
/**
* @ingroup SDCConfig
* @brief Perform a SyncReset from the SDC
*/
void
faSDC_Sync()
{
if(FASDCp == NULL)
{
logMsg("faSDC_Sync: ERROR : No FADC SDC available \n",0,0,0,0,0,0);
return;
}
FASDCLOCK;
vmeWrite16(&(FASDCp->csr),FASDC_CSR_SRESET);
FASDCUNLOCK;
}
/**
* @ingroup SDCConfig
* @brief Perform a trigger pulse from the SDC
*/
void
faSDC_Trig()
{
if(FASDCp == NULL)
{
logMsg("faSDC_Trig: ERROR : No FADC SDC available \n",0,0,0,0,0,0);
return;
}
FASDCLOCK;
vmeWrite16(&(FASDCp->csr),FASDC_CSR_TRIG);
FASDCUNLOCK;
}
/**
* @ingroup SDCStatus
* @brief Return Busy status of the SDC
* @return 1 if busy, 0 if not, otherwise ERROR.
*/
int
faSDC_Busy()
{
int busy=0;
if(FASDCp == NULL)
{
logMsg("faSDC_Busy: ERROR : No FADC SDC available \n",0,0,0,0,0,0);
return -1;
}
FASDCLOCK;
busy = vmeRead16(&(FASDCp->csr))&FASDC_CSR_BUSY;
FASDCUNLOCK;
return(busy);
}
/**
* @ingroup Config
* @brief Set the readout data form which allows for suppression of
* repetitious data words
* @param id Slot number
* @param format Data Format
* - 0: Standard Format - No data words suppressed
* - 1: Intermediate compression - Event headers suppressed if no data
* - 2: Full compression - Only first event header in the block.
* @return OK if successful, otherwise ERROR.
*/
int
faSetDataFormat(int id, int format)
{
unsigned int orig = 0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
printf("%s: ERROR : ADC in slot %d is not initialized \n",
__FUNCTION__,id);
return ERROR;
}
if((format < 0) || (format > 2))
{
printf("%s: ERROR: Invalid format (%d) \n",
__FUNCTION__, format);
return ERROR;
}
FALOCK;
orig = (vmeRead32(&FAp[id]->ctrl1) & (~FA_CTRL1_DATAFORMAT_MASK));
vmeWrite32(&FAp[id]->ctrl1, (orig | (format << 26)) );
printf("Write Format 0x%x \n", (orig | (format << 26)));
FAUNLOCK;
return OK;
}
/**
* @ingroup Config
* @brief Set the readout data form for all initialized modules.
* @param format Data Format
* - 0: Standard Format - No data words suppressed
* - 1: Intermediate compression - Event headers suppressed if no data
* - 2: Full compression - Only first event header in the block.
*/
void
faGSetDataFormat(int format)
{
int ifadc;
for(ifadc=0;ifadc21) || (FAp[id] == NULL))
{
logMsg("faDACReset: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return;
}
FALOCK;
vmeWrite32(&FAp[id]->reset, FA_RESET_DAC);
FAUNLOCK;
}
/**
* @ingroup Config
* @brief Perform a reset of the DAC chip for all initialized modules.
*/
void
faGDACReset()
{
int ifa;
FALOCK;
for(ifa=0; ifareset, FA_RESET_DAC);
}
FAUNLOCK;
}
int faReSetDAC(int id) {
int ii, rval = 0;
unsigned short dacRead[FA_MAX_ADC_CHANNELS];
int doWrite = 0;
unsigned int lovalue=0, hivalue=0;
unsigned int lovalue_rb=0, hivalue_rb=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetDAC: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
printf("Read DAC for FADC250 in slot %d \n", id);
for(ii = 0; ii < FA_MAX_ADC_CHANNELS; ii++){
dacRead[ii] = vmeRead16(&(FAp[id]->dac[ii])) & FA_DAC_VALUE_MASK;
printf(" %d ", dacRead[ii]);
}
printf("\n");
printf("Reset DAC \n");
vmeWrite32(&FAp[id]->reset, FA_RESET_DAC);
printf("Load DAC \n");
for(ii = 0; ii < FA_MAX_ADC_CHANNELS; ii++) {
if(ii%2 == 0) {
lovalue = (dacRead[ii] & FA_DAC_VALUE_MASK);
hivalue = (dacRead[ii+1] & FA_DAC_VALUE_MASK);
vmeWrite32((unsigned int *)&(FAp[id]->dac[ii]),
lovalue<<16 | hivalue);
// Alex
taskDelay(100);
/* Readback to check values, and write timeout error */
lovalue_rb = (vmeRead16(&FAp[id]->dac[ii]));
hivalue_rb = (vmeRead16(&FAp[id]->dac[ii+1]));
if((lovalue_rb != lovalue) || (hivalue_rb != hivalue_rb))
{
printf("%s: ERROR: Readback of DAC Channels (%d, %d) != Write value\n",
__FUNCTION__,ii, ii+1);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii, lovalue_rb & FA_DAC_VALUE_MASK,
(lovalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
lovalue);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii+1, hivalue_rb & FA_DAC_VALUE_MASK,
(hivalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
hivalue);
rval=ERROR;
}
}
lovalue = 0;
hivalue = 0;
}
FAUNLOCK;
return 0;
}
void faPrintBaseline(int id)
{
int ichan = 0;
unsigned int write = 0, read = 0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faReadAllChannelSamples: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
FALOCK;
write = vmeRead32(&FAp[id]->adc_config[0]) & 0xFFFF;
// Enable processing
vmeWrite32(&FAp[id]->adc_config[0], (write | FA_ADC_CONFIG0_CHAN_READ_ENABLE) );
// Disable processing
vmeWrite32(&FAp[id]->adc_config[0], (write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
for(ichan = 0; ichan < FA_MAX_ADC_CHANNELS; ichan++) {
read = vmeRead32(&FAp[id]->adc_status[2]) & FA_ADC_STATUS2_CHAN_DATA_MASK;
printf("Channel = %2d %5d Valid = %d Quality = %d 0x%x \n", ichan, (read & 0x3FFF), (read >> 15) & 0x1, (read >> 14) & 0x1, read );
}
// printf("faReadAllChannelSamples End readout : adc_config[0] 0x%x \n",(write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
FAUNLOCK;
}
int faSetDACCheck(int id, unsigned short dvalue, unsigned short chmask)
{
int ii, doWrite=0, rval=OK;
unsigned int lovalue=0, hivalue=0;
unsigned int lovalue_rb=0, hivalue_rb=0;
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetDAC: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
if(chmask==0) chmask = 0xffff; /* Set All channels the same */
if(dvalue>0xfff)
{
logMsg("faSetDAC: ERROR : DAC value (%d) out of range (0-255) \n",
dvalue,0,0,0,0,0);
return(ERROR);
}
FALOCK;
for(ii=0;iidac[ii]));
hivalue = (vmeRead16(&FAp[id]->dac[ii+1]));
if((1<dac[ii]),
lovalue<<16 | hivalue);
/* Readback to check values, and write timeout error */
lovalue_rb = (vmeRead16(&FAp[id]->dac[ii]));
hivalue_rb = (vmeRead16(&FAp[id]->dac[ii+1]));
printf(" Read Back DAC 1 = 0x%x \n", lovalue_rb);
printf(" Read Back DAC 2 = 0x%x \n", hivalue_rb);
if((lovalue_rb != lovalue) || (hivalue_rb != hivalue_rb))
{
printf("%s: ERROR: Readback of DAC Channels (%d, %d) != Write value\n",
__FUNCTION__,ii, ii+1);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii, lovalue_rb & FA_DAC_VALUE_MASK,
(lovalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
lovalue);
printf(" %2d: Read: 0x%04x %s Write: 0x%04x\n",
ii+1, hivalue_rb & FA_DAC_VALUE_MASK,
(hivalue_rb & FA_DAC_WRITE_TIMEOUT_ERROR)?
"-Write Timeout ERROR-":
" ",
hivalue);
rval=ERROR;
}
}
lovalue = 0;
hivalue = 0;
doWrite=0;
}
}
FAUNLOCK;
return(rval);
}
void faPrintPedestal(int id){
unsigned int rval = 0;
unsigned int ii;
if(id == 0) id = fadcID[0];
if((id <= 0) || (id > 21) || (FAp[id] == NULL)) {
logMsg("faSetChannelPedestal: ERROR : ADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
printf(" Pedestal Settings for FADC in slot %d:",id);
FALOCK;
for(ii = 0;ii < FA_MAX_ADC_CHANNELS;ii++){
rval = vmeRead32(&FAp[id]->adc_pedestal[ii]) & FA_ADC_PEDESTAL_MASK;
if((ii % 4)==0) printf("\n");
printf("Chan %2d: %5d ",(ii+1), rval );
}
FAUNLOCK;
}
void faPrintBaselineAll()
{
int ifa, id;
int ichan = 0;
unsigned int write = 0, read = 0;
FALOCK;
for (ifa=0;ifaadc_config[0]) & 0xFFFF;
// Enable processing
vmeWrite32(&FAp[id]->adc_config[0], (write | FA_ADC_CONFIG0_CHAN_READ_ENABLE) );
// Disable processing
vmeWrite32(&FAp[id]->adc_config[0], (write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
for(ichan = 0; ichan < FA_MAX_ADC_CHANNELS; ichan++) {
read = vmeRead32(&FAp[id]->adc_status[2]) & FA_ADC_STATUS2_CHAN_DATA_MASK;
printf("Channel = %2d %5d Valid = %d Quality = %d 0x%x \n", ichan, (read & 0x3FFF), (read >> 15) & 0x1, (read >> 14) & 0x1, read );
}
// printf("faReadAllChannelSamples End readout : adc_config[0] 0x%x \n",(write & (~FA_ADC_CONFIG0_CHAN_READ_ENABLE)) );
}
FAUNLOCK;
}
int
faSetProcModeDef(int id)
{
int pmode = 10;
unsigned int PL = 900;
unsigned int PTW = 50;
unsigned int NSB = 3;
unsigned int NSA = 15;
unsigned int NP = 1;
unsigned int NPED = 5;
unsigned int MAXPED = 600;
unsigned int NSAT = 2;
int err=0;
int imode=0, supported_modes[FA_SUPPORTED_NMODES] = {FA_SUPPORTED_MODES};
int mode_supported=0;
int mode_bit=0;
printf(" NSAT = %d \n", NSAT);
printf(" MAXPED = %d \n", MAXPED);
printf(" NPED = %d \n", NPED);
if(id==0) id=fadcID[0];
if((id<=0) || (id>21) || (FAp[id] == NULL))
{
logMsg("faSetProcMode: ERROR : FADC in slot %d is not initialized \n",id,0,0,0,0,0);
return(ERROR);
}
for(imode=0; imode FA_ADC_MAX_PL))
{
printf("%s: WARN: PL (%d) out of bounds. ",__FUNCTION__,PL);
PL = (PL < FA_ADC_MIN_PL) ? FA_ADC_MIN_PL : FA_ADC_MAX_PL;
printf("Setting to %d.\n",PL);
}
if((PTW < FA_ADC_MIN_PTW) || (PTW > FA_ADC_MAX_PTW))
{
printf("%s: WARN: PTW (%d) out of bounds. ",__FUNCTION__,PTW);
PTW = (PTW < FA_ADC_MIN_PTW) ? FA_ADC_MIN_PTW : FA_ADC_MAX_PTW;
printf("Setting to %d.\n",PTW);
}
if((NSB < FA_ADC_MIN_NSB) || (NSB > FA_ADC_MAX_NSB))
{
printf("%s: WARN: NSB (%d) out of bounds. ",__FUNCTION__,NSB);
NSB = (NSB < FA_ADC_MIN_NSB) ? FA_ADC_MIN_NSB : FA_ADC_MAX_NSB;
printf("Setting to %d.\n",NSB);
}
// Alex
// if((NSA < FA_ADC_MIN_NSA) || (NSA > FA_ADC_MAX_NSA))
// {
// printf("%s: WARN: NSA (%d) out of bounds. ",__FUNCTION__,NSA);
// NSA = (NSA < FA_ADC_MIN_NSA) ? FA_ADC_MIN_NSA : FA_ADC_MAX_NSA;
// if(((NSB + NSA) % 2)==0) /* Make sure NSA+NSB is an odd number */
// NSA = (NSA==FA_ADC_MIN_NSA) ? NSA + 1 : NSA - 1;
// printf("Setting to %d.\n",NSA);
// }
// if( (NSB & 0x8) && (NSA <= NSB) )
// {
// printf("%s: WARN: ", __FUNCTION__);
// }
if((NP < FA_ADC_MIN_NP) || (NP > FA_ADC_MAX_NP))
{
printf("%s: WARN: NP (%d) out of bounds. ",__FUNCTION__,NP);
NP = (NP < FA_ADC_MIN_NP) ? FA_ADC_MIN_NP : FA_ADC_MAX_NP;
printf("Setting to %d.\n",NP);
}
if((NPED < FA_ADC_MIN_NPED) || (NPED > FA_ADC_MAX_NPED))
{
printf("%s: WARN: NPED (%d) out of bounds. ",__FUNCTION__,NPED);
NPED = (NPED < FA_ADC_MIN_NPED) ? FA_ADC_MIN_NPED : FA_ADC_MAX_NPED;
printf("Setting to %d.\n",NPED);
}
if(NPED >= PTW)
{
printf("%s: WARN: NPED (%d) >= PTW (%d) ",__FUNCTION__, NPED, PTW);
NPED = PTW - 1;
printf("Setting to %d.\n",NPED);
}
if((MAXPED < FA_ADC_MIN_MAXPED) || (MAXPED > FA_ADC_MAX_MAXPED))
{
printf("%s: WARN: MAXPED (%d) out of bounds. ",__FUNCTION__,MAXPED);
MAXPED = (MAXPED < FA_ADC_MIN_MAXPED) ? FA_ADC_MIN_MAXPED : FA_ADC_MAX_MAXPED;
printf("Setting to %d.\n",MAXPED);
}
if((NSAT < FA_ADC_MIN_NSAT) || (NSAT > FA_ADC_MAX_NSAT))
{
printf("%s: WARN: NSAT (%d) out of bounds. ",__FUNCTION__,NSAT);
NSAT = (NSAT < FA_ADC_MIN_NSAT) ? FA_ADC_MIN_NSAT : FA_ADC_MAX_NSAT;
printf("Setting to %d.\n",NSAT);
}
/* Consistancy check */
// Alex
// if(((NSB + NSA) % 2)==0)
// {
// err++;
// printf("%s: ERROR: NSB+NSA must be an odd number\n",__FUNCTION__);
// }
// faSetNormalMode(id,0);
// faSetNormalMode(id,0);
FALOCK;
/* Disable ADC processing while writing window info */
if(pmode == FA_ADC_PROC_MODE_PULSE_PARAM)
mode_bit = 0;
else if(pmode == FA_ADC_PROC_MODE_RAW_PULSE_PARAM)
mode_bit = 1;
else
{
printf("%s: ERROR: Unsupported mode (%d)\n",
__FUNCTION__, pmode);
return ERROR;
}
/* Configure the mode (mode_bit), # of pulses (NP), # samples above TET (NSAT)
keep TNSAT, if it's already been configured */
vmeWrite32(&FAp[id]->adc_config[0],
(vmeRead32(&FAp[id]->adc_config[0]) & FA_ADC_CONFIG1_TNSAT_MASK) |
(mode_bit << 8) | ((NP-1) << 4) | ((NSAT-1) << 10) );
/* Disable user-requested channels */
vmeWrite32(&FAp[id]->adc_config[1], fadcChanDisable[id]);
/* Set window parameters */
vmeWrite32(&FAp[id]->adc_pl, PL);
vmeWrite32(&FAp[id]->adc_ptw, PTW - 1);
/* Set Readback NSB, NSA
NSA */
vmeWrite32(&FAp[id]->adc_nsb, NSB);
vmeWrite32(&FAp[id]->adc_nsa,
(vmeRead32(&FAp[id]->adc_nsa) & FA_ADC_TNSA_MASK) |
NSA );
/* Set Pedestal parameters */
vmeWrite32(&FAp[id]->config7, (NPED-1)<<10 | (MAXPED));
/* Enable ADC processing */
vmeWrite32(&FAp[id]->adc_config[0],
vmeRead32(&FAp[id]->adc_config[0]) | FA_ADC_PROC_ENABLE );
/* Set default value of trigger path threshold (TPT) */
vmeWrite32(&FAp[id]->config3, FA_ADC_DEFAULT_TPT);
FAUNLOCK;
// faSetTriggerStopCondition(id, faCalcMaxUnAckTriggers(pmode,PTW,NSA,NSB,NP));
// faSetTriggerBusyCondition(id, faCalcMaxUnAckTriggers(pmode,PTW,NSA,NSB,NP));
return(OK);
}
void faResetADC(int id) {
printf(" Reset ADC chip for FADC in slot %d \n", id);
FALOCK;
vmeWrite32(&FAp[id]->adc_config[2], 0x10);
taskDelay(1);
vmeWrite32(&FAp[id]->adc_config[2], 0);
taskDelay(1);
FAUNLOCK;
}
void faWriteConfig(int id, int config, unsigned int value) {
FALOCK;
printf(" FAp address 0x%x \n", &FAp[id]);
if(config == 2){
vmeWrite32(&FAp[id]->adc_config[2], value);
taskDelay(1);
printf(" Write 0x%x to config 2 \n", value);
}
if(config == 3) {
vmeWrite32(&FAp[id]->adc_config[3], value);
taskDelay(1);
printf(" Write 0x%x to config 3 \n", value);
}
FAUNLOCK;
}
void faMGTReset(int id, int reset){
printf(" Reset MGT in slot %id reset %d\n",id, reset);
FALOCK;
if(reset)
vmeWrite32(&FAp[id]->mgt_ctrl, FA_MGT_RESET);
else
vmeWrite32(&FAp[id]->mgt_ctrl,FA_RELEASE_MGT_RESET);
FAUNLOCK;
}