moved ansi drivers
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
|
||||
The CPU030 may need to have the nivxi path set correctly:
|
||||
From the vxWorks shell type "vxitedit"
|
||||
take option 2
|
||||
take option 3
|
||||
type list
|
||||
type modify 0
|
||||
type in the correct path when promped
|
||||
(the path should end in nivxi
|
||||
and should traverse the niCpu030
|
||||
directories shipped with the 030
|
||||
ie somethin of the form "???/config/niCPU030/nivxi"
|
||||
type save
|
||||
type exit
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
|
||||
You may may need to setup front panel to backplane trigger
|
||||
routing:
|
||||
|
||||
To take a TTL input and map it to VXI backplane ECL trigger 0
|
||||
type in (to the vxWorks shell):
|
||||
|
||||
epvxiRouteTriggerECL(<logical address>, 1, 0)
|
||||
|
||||
where <logical address> specifies the card with the
|
||||
front panel trigger connection.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
*
|
||||
* driver for at5 designed VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 11-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <dbScan.h>
|
||||
|
||||
typedef long at5VxiStatus;
|
||||
|
||||
at5VxiStatus at5vxi_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param/* parameter to pass to above routine */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ai_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval,
|
||||
unsigned short *prbval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_read(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *pval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bi_driver(
|
||||
unsigned card,
|
||||
unsigned long mask,
|
||||
unsigned long *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bo_driver(
|
||||
unsigned card,
|
||||
unsigned long val,
|
||||
unsigned long mask
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_getioscanpvt(
|
||||
unsigned card,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
@@ -0,0 +1,808 @@
|
||||
/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */
|
||||
/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265
|
||||
*
|
||||
* Author: Jeff Hill (johill@lanl.gov)
|
||||
* Date: 8-11-94
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* MIT Bates Lab
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* ANSI C Includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <types.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* vxWorks includes
|
||||
*/
|
||||
#include <vme.h>
|
||||
#include <iv.h>
|
||||
#include <sysLib.h>
|
||||
#include <intLib.h>
|
||||
#include <logLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <rebootLib.h>
|
||||
#include <taskLib.h>
|
||||
#include <tickLib.h>
|
||||
#include <wdLib.h>
|
||||
|
||||
/*
|
||||
* EPICS include
|
||||
*/
|
||||
#include <dbDefs.h>
|
||||
#include <dbScan.h>
|
||||
#include <drvSup.h>
|
||||
#include <devSup.h>
|
||||
#include <recSup.h>
|
||||
#include <devLib.h>
|
||||
#include <aiRecord.h>
|
||||
#include <errMdef.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
|
||||
/*
|
||||
* base address, base interrupt vector,
|
||||
* number of cards, & interrupt level
|
||||
*/
|
||||
#define CAIN_V265_A24_BASE (0x000000)
|
||||
#define CAIN_V265_INTVEC_BASE (0xA0)
|
||||
#define CAIN_V265_MAX_CARD_COUNT (8)
|
||||
#define CAIN_V265_INT_LEVEL (6)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* all device registers declared
|
||||
* ANSI C volatile so we dont need to
|
||||
* use the -fvolatile flag (and dont
|
||||
* limit the optimizer)
|
||||
*/
|
||||
typedef volatile int16_t devReg;
|
||||
|
||||
struct caenV265 {
|
||||
devReg csr;
|
||||
devReg clear;
|
||||
devReg DAC;
|
||||
devReg gate;
|
||||
const devReg data;
|
||||
const devReg pad1[(0xf8-0x8)/2];
|
||||
const devReg fixed;
|
||||
const devReg identifier;
|
||||
const devReg version;
|
||||
};
|
||||
#define CAENV265ID 0x0812
|
||||
|
||||
/*
|
||||
* Insert or extract a bit field using the standard
|
||||
* masks and shifts defined below
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
#define INSERT(FIELD,VALUE)\
|
||||
(((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S))
|
||||
#define EXTRACT(FIELD,VALUE)\
|
||||
( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M))
|
||||
#else /*__STDC__*/
|
||||
#define INSERT(FIELD,VALUE)\
|
||||
(((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S))
|
||||
#define EXTRACT(FIELD,VALUE)\
|
||||
( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M))
|
||||
#endif /*__STDC__*/
|
||||
|
||||
/*
|
||||
* in the constants below _M is a right justified mask
|
||||
* and _S is a shift required to right justify the field
|
||||
*/
|
||||
|
||||
/*
|
||||
* csr register
|
||||
*/
|
||||
#define FD_FULL_M (0x1)
|
||||
#define FD_FULL_S (14)
|
||||
#define FD_READY_M (0x1)
|
||||
#define FD_READY_S (15)
|
||||
#define FD_BUSY_FULL_M (0x3)
|
||||
#define FD_BUSY_FULL_S (14)
|
||||
#define FD_IVEC_M (0xff)
|
||||
#define FD_IVEC_S (0)
|
||||
#define FD_ILEVEL_M (0x7)
|
||||
#define FD_ILEVEL_S (8)
|
||||
|
||||
/*
|
||||
* series/version register
|
||||
*/
|
||||
#define FD_SERIES_M (0xfff)
|
||||
#define FD_SERIES_S (0)
|
||||
#define FD_VERSION_M (0xf)
|
||||
#define FD_VERSION_S (12)
|
||||
|
||||
/*
|
||||
* data register
|
||||
*/
|
||||
#define FD_CHANNEL_M (0x7)
|
||||
#define FD_CHANNEL_S (13)
|
||||
#define FD_RANGE_M (1)
|
||||
#define FD_RANGE_S (12)
|
||||
#define FD_DATA_M (0xfff)
|
||||
#define FD_DATA_S (0)
|
||||
|
||||
struct channel{
|
||||
int16_t signal;
|
||||
char newData;
|
||||
};
|
||||
|
||||
enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES};
|
||||
#define NUMBER_OF_SIGNALS 8
|
||||
#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES)
|
||||
LOCAL struct caenV265Config{
|
||||
struct caenV265 *pCaenV265; /* pointer to the card */
|
||||
struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES];
|
||||
IOSCANPVT scanpvt;
|
||||
WDOG_ID wdid;
|
||||
}caenV265Info[CAIN_V265_MAX_CARD_COUNT];
|
||||
|
||||
#ifdef __STDC__
|
||||
#define SHOW_OFFSET(STRUCT,FIELD) \
|
||||
printf( "%s.%s is at 0x%X\n", \
|
||||
#STRUCT, \
|
||||
#FIELD, \
|
||||
offsetof(struct STRUCT, FIELD))
|
||||
#endif
|
||||
|
||||
LOCAL void caenV265ISR(unsigned card);
|
||||
LOCAL int caenV265Shutdown(void);
|
||||
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265);
|
||||
int caenV265Test(unsigned card);
|
||||
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config);
|
||||
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal);
|
||||
LOCAL int caenV265IntEnable(unsigned card);
|
||||
|
||||
/*
|
||||
* device support entry table
|
||||
*/
|
||||
LOCAL long caenV265InitRecord(struct aiRecord *pai);
|
||||
LOCAL long caenV265AiRead(struct aiRecord *pai);
|
||||
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after);
|
||||
LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devCaenV265 ={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
caenV265InitRecord,
|
||||
caenV265GetIoIntInfo,
|
||||
caenV265AiRead,
|
||||
caenV265SpecialLinconv};
|
||||
|
||||
/*
|
||||
* driver support entry table
|
||||
*/
|
||||
LOCAL long caenV265Init(void);
|
||||
LOCAL long caenV265IOReport(int level);
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvCaenV265 ={
|
||||
2,
|
||||
caenV265IOReport,
|
||||
caenV265Init};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* verify that register
|
||||
* offsets match the doc.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
void offsettest()
|
||||
{
|
||||
SHOW_OFFSET(caenV265, version);
|
||||
SHOW_OFFSET(caenV265, identifier);
|
||||
SHOW_OFFSET(caenV265, fixed);
|
||||
SHOW_OFFSET(caenV265, data);
|
||||
SHOW_OFFSET(caenV265, gate);
|
||||
SHOW_OFFSET(caenV265, DAC);
|
||||
SHOW_OFFSET(caenV265, clear);
|
||||
SHOW_OFFSET(caenV265, csr);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* caenV265InitRecord()
|
||||
*/
|
||||
LOCAL long caenV265InitRecord(struct aiRecord *pai)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
/* ai.inp must be an VME_IO */
|
||||
switch (pai->inp.type) {
|
||||
case (VME_IO):
|
||||
break;
|
||||
default :
|
||||
recGblRecordError(S_db_badField,(void *)pai,
|
||||
"devAiXy566Se (init_record) Illegal INP field");
|
||||
return(S_db_badField);
|
||||
}
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad signal or card number
|
||||
*/
|
||||
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
|
||||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 bad card or signal number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!caenV265Info[pvmeio->card].pCaenV265){
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 card does not exist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set linear conversion slope*/
|
||||
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265AiRead()
|
||||
*/
|
||||
LOCAL long caenV265AiRead(struct aiRecord *pai)
|
||||
{
|
||||
int16_t value;
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad signal or card number
|
||||
*/
|
||||
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
|
||||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
|
||||
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* uninitialized data?
|
||||
*/
|
||||
if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) {
|
||||
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal;
|
||||
pai->rval = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265SpecialLinconv()
|
||||
*/
|
||||
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after)
|
||||
{
|
||||
if(!after) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set linear conversion slope*/
|
||||
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265GetIoIntInfo()
|
||||
*/
|
||||
LOCAL long caenV265GetIoIntInfo(
|
||||
int cmd,
|
||||
struct aiRecord *pai,
|
||||
IOSCANPVT *ppvt)
|
||||
{
|
||||
struct vmeio *pvmeio;
|
||||
|
||||
pvmeio = (struct vmeio *)&(pai->inp.value);
|
||||
|
||||
/*
|
||||
* check for bad card number
|
||||
*/
|
||||
if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
|
||||
epicsPrintf (
|
||||
"%s.%d:devCaenV265 bad card number %d %s\n",
|
||||
(int)__FILE__,
|
||||
__LINE__,
|
||||
pvmeio->card,
|
||||
(int)pai->name);
|
||||
recGblRecordError(
|
||||
S_db_badField,
|
||||
(void *)pai,
|
||||
"devCaenV265 bad card number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppvt = &caenV265Info[pvmeio->card].scanpvt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Init()
|
||||
*/
|
||||
LOCAL long caenV265Init(void)
|
||||
{
|
||||
unsigned card;
|
||||
struct caenV265 *pCaenV265;
|
||||
int status;
|
||||
|
||||
status = rebootHookAdd(caenV265Shutdown);
|
||||
if(status){
|
||||
errMessage(S_dev_internal,"reboot hook add failed");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
status = sysBusToLocalAdrs(
|
||||
VME_AM_STD_SUP_DATA,
|
||||
CAIN_V265_A24_BASE,
|
||||
(char **)&pCaenV265);
|
||||
if(status!=OK){
|
||||
errPrintf(
|
||||
S_dev_badA24,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"caenV265Init");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++, pCaenV265++){
|
||||
unsigned vec;
|
||||
|
||||
if(!caenV265IdTest(pCaenV265)){
|
||||
continue;
|
||||
}
|
||||
|
||||
caenV265Info[card].wdid = wdCreate();
|
||||
if(!caenV265Info[card].wdid){
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* flag that we have found a caen V265
|
||||
*/
|
||||
caenV265Info[card].pCaenV265 = pCaenV265;
|
||||
|
||||
/*
|
||||
* init the EPICS db int event scan block
|
||||
*/
|
||||
scanIoInit(&caenV265Info[card].scanpvt);
|
||||
|
||||
/*
|
||||
* reset the device
|
||||
*/
|
||||
pCaenV265->clear = 0; /* any rw op resets the device */
|
||||
pCaenV265->DAC = 0; /* set test-signal "offset" to zero */
|
||||
|
||||
/*
|
||||
* attach ISR
|
||||
*/
|
||||
vec = CAIN_V265_INTVEC_BASE+card;
|
||||
status = intConnect(
|
||||
INUM_TO_IVEC(vec),
|
||||
caenV265ISR,
|
||||
card);
|
||||
assert(status>=0);
|
||||
|
||||
/*
|
||||
* Enable interrupts
|
||||
*/
|
||||
caenV265IntEnable(card);
|
||||
}
|
||||
status = sysIntEnable(CAIN_V265_INT_LEVEL);
|
||||
assert(status>=0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265ISR()
|
||||
*/
|
||||
LOCAL void caenV265ISR(unsigned card)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned signal;
|
||||
int16_t csr;
|
||||
static unsigned ticks;
|
||||
unsigned newTicks;
|
||||
|
||||
/*
|
||||
* If its full then its more efficient
|
||||
* to read it out without checking
|
||||
* in between each read
|
||||
*/
|
||||
csr = pCaenV265->csr;
|
||||
if (EXTRACT(FULL,csr)) {
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_FIFO_ENTRIES;
|
||||
signal++){
|
||||
|
||||
caenV265ReadData(pCaenV256Config);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not full so check to see if its ready before
|
||||
* reading
|
||||
*/
|
||||
while (EXTRACT(READY, csr)) {
|
||||
caenV265ReadData(pCaenV256Config);
|
||||
csr = pCaenV265->csr;
|
||||
}
|
||||
|
||||
/*
|
||||
* limit the EPICS scan rate
|
||||
*/
|
||||
newTicks = tickGet();
|
||||
if(newTicks == ticks){
|
||||
/*
|
||||
* Disable Interrupts
|
||||
*/
|
||||
pCaenV265->csr = 0;
|
||||
|
||||
/*
|
||||
* start a watch dog after one tick
|
||||
* so that we limit the int rate to
|
||||
* the system tick rate.
|
||||
*/
|
||||
wdStart(pCaenV256Config->wdid,
|
||||
1,
|
||||
caenV265IntEnable,
|
||||
card);
|
||||
|
||||
return;
|
||||
}
|
||||
else{
|
||||
ticks = newTicks;
|
||||
}
|
||||
|
||||
/*
|
||||
* tell EPICS to scan on int
|
||||
*/
|
||||
scanIoRequest(&caenV265Info[card].scanpvt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IntEnable
|
||||
*/
|
||||
LOCAL int caenV265IntEnable(unsigned card)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned vec;
|
||||
int16_t newcsr;
|
||||
|
||||
|
||||
vec = CAIN_V265_INTVEC_BASE+card;
|
||||
newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL);
|
||||
pCaenV265->csr = newcsr;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265ReadData()
|
||||
*/
|
||||
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config)
|
||||
{
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
int16_t val = pCaenV265->data;
|
||||
int16_t data = EXTRACT(DATA, val);
|
||||
unsigned range = EXTRACT(RANGE, val);
|
||||
unsigned signal = EXTRACT(CHANNEL, val);
|
||||
|
||||
if(range>=NUMBER_OF_ADC_RANGES){
|
||||
epicsPrintf ("caenV265ReadData: bad range number\n");
|
||||
return;
|
||||
}
|
||||
if(signal>=NUMBER_OF_SIGNALS){
|
||||
epicsPrintf ("caenV265ReadData: bad signal number\n");
|
||||
return;
|
||||
}
|
||||
pCaenV256Config->chan[signal][range].signal=data;
|
||||
pCaenV256Config->chan[signal][range].newData=TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IdTest()
|
||||
*/
|
||||
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265)
|
||||
{
|
||||
int status;
|
||||
int16_t id;
|
||||
|
||||
/*
|
||||
* Is a card present
|
||||
*/
|
||||
status = vxMemProbe(
|
||||
(char *)&pCaenV265->identifier,
|
||||
READ,
|
||||
sizeof(id),
|
||||
(char *)&id);
|
||||
if(status!=OK){
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the correct type of card present
|
||||
*/
|
||||
if(id!=CAENV265ID){
|
||||
errPrintf(
|
||||
S_dev_wrongDevice,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"caenV265IdTest");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Shutdown()
|
||||
* turns off interrupts so that dont foul up the boot
|
||||
*/
|
||||
LOCAL int caenV265Shutdown(void)
|
||||
{
|
||||
struct caenV265 *pCaenV265;
|
||||
unsigned card;
|
||||
|
||||
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++){
|
||||
pCaenV265 = caenV265Info[card].pCaenV265;
|
||||
if(!pCaenV265){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(caenV265IdTest(pCaenV265)){
|
||||
/*
|
||||
* disable interrupts
|
||||
*/
|
||||
pCaenV265->csr=0;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265Test()
|
||||
*/
|
||||
int caenV265Test(unsigned card)
|
||||
{
|
||||
unsigned dacVal;
|
||||
struct caenV265Config cofigCpy;
|
||||
unsigned range;
|
||||
unsigned signal;
|
||||
|
||||
|
||||
dacVal=0;
|
||||
caenV265TestVal(card, dacVal);
|
||||
while(dacVal<FD_DATA_M){
|
||||
|
||||
cofigCpy = caenV265Info[card];
|
||||
dacVal = dacVal+32;
|
||||
caenV265TestVal(card, dacVal);
|
||||
|
||||
for( range=0;
|
||||
range<NUMBER_OF_ADC_RANGES;
|
||||
range++){
|
||||
char *pRangeName[] = { "12 bit signal",
|
||||
"15 bit signal"};
|
||||
|
||||
printf( "\t%s with DAC = 0x%X\n",
|
||||
pRangeName[range],
|
||||
dacVal);
|
||||
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
unsigned newdata;
|
||||
unsigned olddata;
|
||||
|
||||
olddata = cofigCpy.chan[signal][range].signal;
|
||||
newdata = caenV265Info[card].
|
||||
chan[signal][range].signal;
|
||||
|
||||
printf( "\t\tchan=0x%1X diff = 0x%03X\n",
|
||||
signal,
|
||||
newdata-olddata);
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265TestVal()
|
||||
*/
|
||||
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal)
|
||||
{
|
||||
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
|
||||
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
|
||||
unsigned signal;
|
||||
|
||||
if(!pCaenV265){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if(!caenV265IdTest(pCaenV265)){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the module
|
||||
*/
|
||||
pCaenV265->clear=0;
|
||||
|
||||
/*
|
||||
* generate a test signal
|
||||
*/
|
||||
pCaenV265->DAC=dacVal;
|
||||
|
||||
/*
|
||||
* generate a test gate
|
||||
*/
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
caenV265Info[card].chan[signal][adc_12].newData=FALSE;
|
||||
caenV265Info[card].chan[signal][adc_15].newData=FALSE;
|
||||
while(!caenV265Info[card].chan[signal][adc_15].newData){
|
||||
pCaenV265->gate=0;
|
||||
taskDelay(1);
|
||||
}
|
||||
while(!caenV265Info[card].chan[signal][adc_12].newData){
|
||||
pCaenV265->gate=0;
|
||||
taskDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* turn off test signal
|
||||
*/
|
||||
pCaenV265->clear=0;
|
||||
pCaenV265->DAC=0;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* caenV265IOReport()
|
||||
*/
|
||||
LOCAL long caenV265IOReport(int level)
|
||||
{
|
||||
struct caenV265 *pCaenV265;
|
||||
unsigned card;
|
||||
unsigned signal;
|
||||
unsigned range;
|
||||
char *pVersion[] = {"NIM","ECL"};
|
||||
char *pState[] = {
|
||||
"FIFO empty",
|
||||
"FIFO full",
|
||||
"FIFO partially filled",
|
||||
"FIFO full"};
|
||||
|
||||
for (card=0; card<CAIN_V265_MAX_CARD_COUNT; card++) {
|
||||
pCaenV265 = caenV265Info[card].pCaenV265;
|
||||
if (!pCaenV265) {
|
||||
continue;
|
||||
}
|
||||
if (!caenV265IdTest(pCaenV265)) {
|
||||
continue;
|
||||
}
|
||||
printf("AI: caen V265:\tcard %d\n", card);
|
||||
if (level == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\tversion = %s\n",
|
||||
pVersion[EXTRACT(VERSION, pCaenV265->version)]);
|
||||
printf("\tseries = %d\n",
|
||||
EXTRACT(SERIES, pCaenV265->version));
|
||||
printf("\tstate = %s\n",
|
||||
pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]);
|
||||
printf("\tint level = %d\n",
|
||||
EXTRACT(ILEVEL,pCaenV265->csr));
|
||||
printf("\tint vec = 0x%02X\n",
|
||||
EXTRACT(IVEC,pCaenV265->csr));
|
||||
printf( "\tbase addr= 0x%X on the %s\n",
|
||||
(unsigned)caenV265Info[card].pCaenV265,
|
||||
sysModel());
|
||||
|
||||
for( range=0;
|
||||
range<NUMBER_OF_ADC_RANGES;
|
||||
range++){
|
||||
char *pRangeName[] = { "12 bit signal",
|
||||
"15 bit signal"};
|
||||
|
||||
printf("\t%s\n", pRangeName[range]);
|
||||
|
||||
for( signal=0;
|
||||
signal<NUMBER_OF_SIGNALS;
|
||||
signal++){
|
||||
int16_t data;
|
||||
|
||||
data = caenV265Info[card].
|
||||
chan[signal][range].signal;
|
||||
|
||||
if(caenV265Info[card].chan[signal][range].newData){
|
||||
printf( "\t\tchan=0x%1X val = 0x%03X\n",
|
||||
signal,
|
||||
data);
|
||||
}
|
||||
else{
|
||||
printf( "\t\tchan=0x%1X <NO GATE>\n",
|
||||
signal);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,408 @@
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
*
|
||||
* HP E1404A VXI bus slot zero translator
|
||||
* device dependent routines
|
||||
*
|
||||
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* Date 030692
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 joh 073092 Added msg device support & interrupt shutdown for
|
||||
* soft reboots
|
||||
* .02 joh 082792 converted to ANSI C
|
||||
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <intLib.h>
|
||||
#include <rebootLib.h>
|
||||
|
||||
#include <devLib.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <drvHp1404a.h>
|
||||
|
||||
LOCAL unsigned long hpE1404DriverID;
|
||||
|
||||
struct hpE1404_config{
|
||||
void (*pSignalCallback)(int16_t signal);
|
||||
};
|
||||
|
||||
#define TLTRIG(N) (1<<(N))
|
||||
#define ECLTRIG(N) (1<<((N)+8))
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
#define HP1404A_INT_ENABLE 0x0008
|
||||
#define HP1404A_INT_DISABLE 0x0000
|
||||
|
||||
/*
|
||||
*
|
||||
* tag the device dependent registers
|
||||
*/
|
||||
#define IRQ_enable dir.w.dd.reg.ddx1a
|
||||
#define MSG_status dir.w.dd.reg.ddx1e
|
||||
#define fp_trig_drive dir.w.dd.reg.ddx2a
|
||||
#define bp_trig_drive dir.w.dd.reg.ddx22
|
||||
#define signal_read dir.r.dd.reg.ddx10
|
||||
|
||||
#define hpE1404PConfig(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
|
||||
|
||||
LOCAL void hpE1404InitLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL int hpE1404ShutDown(
|
||||
void
|
||||
);
|
||||
|
||||
LOCAL void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
);
|
||||
|
||||
LOCAL void hpE1404Int(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Init
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404Init(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
|
||||
status = rebootHookAdd(hpE1404ShutDown);
|
||||
if(status<0){
|
||||
status = S_dev_internal;
|
||||
errMessage(status, "rebootHookAdd() failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
hpE1404DriverID = epvxiUniqueDriverID();
|
||||
|
||||
status = epvxiRegisterMakeName(
|
||||
VXI_MAKE_HP,
|
||||
"Hewlett-Packard");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG_SLOT0,
|
||||
"Slot Zero Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG,
|
||||
"Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_MSG,
|
||||
"Translator (msg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDown()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL int hpE1404ShutDown(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDownLA()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404InitLA()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404InitLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct hpE1404_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
hpE1404Stat status;
|
||||
|
||||
status = epvxiOpen(
|
||||
la,
|
||||
hpE1404DriverID,
|
||||
sizeof(*pc),
|
||||
hpE1404IOReport);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
status = hpE1404PConfig(la, pc);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
epvxiClose(la, hpE1404DriverID);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the self test status to passed for
|
||||
* the message based device
|
||||
*/
|
||||
pcsr->MSG_status = VXIPASS<<2;
|
||||
|
||||
intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpE1404Int,
|
||||
la);
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404SignalConnect()
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404SignalConnect(
|
||||
unsigned la,
|
||||
void (*pSignalCallback)(int16_t signal)
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
return s;
|
||||
}
|
||||
|
||||
pc->pSignalCallback = pSignalCallback;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Int()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404Int(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned short signal;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* vector is only D8 so we cant check the cause of the int
|
||||
* (signal cause is assumed since that was all that was enabled)
|
||||
*/
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
signal = pcsr->signal_read;
|
||||
|
||||
if(pc->pSignalCallback){
|
||||
(*pc->pSignalCallback)(signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404RouteTriggerECL
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerECL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
|
||||
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* hpE1404RouteTriggerTTL
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = io_map&enable_map;
|
||||
pcsr->bp_trig_drive = (~io_map)&enable_map;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404IOReport()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* drvHp1404a.h
|
||||
*
|
||||
* HP E1404A VXI bus slot zero translator
|
||||
* device dependent routines header file
|
||||
*
|
||||
* share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* Date 030692
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef long hpE1404Stat;
|
||||
|
||||
hpE1404Stat hpE1404Init(void);
|
||||
|
||||
hpE1404Stat hpE1404SignalConnect(
|
||||
unsigned la,
|
||||
void (*pSignalCallback)(int16_t signal)
|
||||
);
|
||||
|
||||
hpE1404Stat hpE1404RouteTriggerECL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
);
|
||||
|
||||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
);
|
||||
|
||||
#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10
|
||||
#define VXI_HP_MODEL_E1404_REG 0x110
|
||||
#define VXI_HP_MODEL_E1404_MSG 0x111
|
||||
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
/* drvHpe1368a.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.c
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 071792 joh Added model name registration
|
||||
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
|
||||
* .03 082692 mrk Added support for new I/O event scanning and DRVET
|
||||
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <types.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <task_params.h>
|
||||
#include <fast_lock.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <devLib.h>
|
||||
|
||||
#include <drvHpe1368a.h>
|
||||
|
||||
|
||||
#define HPE1368A_PCONFIG(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
|
||||
|
||||
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
|
||||
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
|
||||
|
||||
#define ALL_SWITCHES_OPEN 0
|
||||
|
||||
struct hpe1368a_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
unsigned short pending; /* switch position pending int */
|
||||
unsigned short shadow; /* shadow of actual switch pos */
|
||||
int busy; /* relays active */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
#define HPE1368A_INT_LEVEL 1
|
||||
|
||||
LOCAL int hpe1368aDriverId;
|
||||
|
||||
LOCAL void hpe1368a_int_service(unsigned la);
|
||||
LOCAL void hpe1368a_init_card(unsigned la);
|
||||
LOCAL void hpe1368a_stat(unsigned la, int level);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvHpe1368a={
|
||||
2,
|
||||
NULL, /*VXI io report takes care of this */
|
||||
hpe1368a_init};
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_init
|
||||
*
|
||||
* initialize all hpe1368a cards
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_init(void)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
|
||||
/*
|
||||
* do nothing on crates without VXI
|
||||
*/
|
||||
if(!epvxiResourceMangerOK){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
hpe1368aDriverId = epvxiUniqueDriverID();
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_MODEL_HPE1368A;
|
||||
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_INIT_CARD
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_init_card(unsigned la)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
int model;
|
||||
|
||||
r0 = epvxiOpen(
|
||||
la,
|
||||
hpe1368aDriverId,
|
||||
(unsigned long) sizeof(*pc),
|
||||
hpe1368a_stat);
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
r0 = HPE1368A_PCONFIG(la, pc);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
/*
|
||||
* we must reset the device to a known state since
|
||||
* we cant read back the current state
|
||||
*/
|
||||
pc->pending = ALL_SWITCHES_OPEN;
|
||||
pc->shadow = ALL_SWITCHES_OPEN;
|
||||
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
|
||||
|
||||
FASTLOCKINIT(&pc->lock);
|
||||
scanIoInit(&pc->ioscanpvt);
|
||||
|
||||
r0 = intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpe1368a_int_service,
|
||||
la);
|
||||
if(r0 == ERROR){
|
||||
errMessage(S_dev_vxWorksVecInstlFail, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
sysIntEnable(HPE1368A_INT_LEVEL);
|
||||
|
||||
model = VXIMODEL(pcsr);
|
||||
r0 = epvxiRegisterModelName(
|
||||
VXIMAKE(pcsr),
|
||||
model,
|
||||
"E 1368A Microwave Switch\n");
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
}
|
||||
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpe1368a_int_service()
|
||||
*
|
||||
*
|
||||
* This device interrupts once the
|
||||
* switches have settled
|
||||
*
|
||||
*/
|
||||
LOCAL void
|
||||
hpe1368a_int_service(unsigned la)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la,pc);
|
||||
if(s){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* operation completed so we can update
|
||||
* the shadow value
|
||||
*/
|
||||
pc->shadow = pc->pending;
|
||||
pc->busy = FALSE;
|
||||
|
||||
/*
|
||||
* tell them that the switches have settled
|
||||
*/
|
||||
scanIoRequest(pc->ioscanpvt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_STAT
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s,NULL);
|
||||
return;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
if(level>0){
|
||||
printf("\tSwitch states %x\n", pc->shadow);
|
||||
printf("\tModule status %x\n", pcsr->dir.r.status);
|
||||
if(pc->busy){
|
||||
printf("\tModule is busy.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_getioscanpvt()
|
||||
*/
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
*scanpvt = pc->ioscanpvt;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_BO_DRIVER
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned int work;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
work = pc->pending;
|
||||
|
||||
/* alter specified bits */
|
||||
work = (work & ~mask) | (val & mask);
|
||||
|
||||
pc->pending = work;
|
||||
|
||||
ChannelEnable(pcsr) = work;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* HPE1368A_BI_DRIVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
*pval = pc->shadow & mask;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* drvHpe1368a.h*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.h
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
*/
|
||||
|
||||
#define VXI_MODEL_HPE1368A (0xf28)
|
||||
|
||||
typedef long hpe1368aStat;
|
||||
|
||||
hpe1368aStat hpe1368a_init(void);
|
||||
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
);
|
||||
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,484 @@
|
||||
/* drvKscV215.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* KscV215_driver.c
|
||||
*
|
||||
* driver for KscV215 VXI module
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 071792 joh Added model name registration
|
||||
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
|
||||
* .03 082692 mrk Added support for new I/O event scanning and DRVET
|
||||
* .04 012893 joh include file name change
|
||||
* .05 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <dbDefs.h>
|
||||
#include <iv.h>
|
||||
#include <types.h>
|
||||
#include <stdioLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <task_params.h>
|
||||
#include <fast_lock.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <drvSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <devLib.h>
|
||||
|
||||
#include <drvKscV215.h>
|
||||
|
||||
|
||||
#define MAXTRIES 100
|
||||
|
||||
#define KSCV215_PCONFIG(LA, PC) \
|
||||
epvxiFetchPConfig((LA), KscV215DriverId, PC)
|
||||
|
||||
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
|
||||
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
|
||||
|
||||
#define ALL_SWITCHES_OPEN 0
|
||||
|
||||
struct KscV215_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
#define KSCV215_INT_LEVEL 1
|
||||
#define KscV215Handshake (0x0040)
|
||||
#define KscV215csrInit (0x9000)
|
||||
|
||||
LOCAL int KscV215DriverId;
|
||||
|
||||
|
||||
struct KscV215_A24{
|
||||
volatile uint16_t diag;
|
||||
volatile uint16_t isr;
|
||||
volatile uint16_t pad1[7];
|
||||
volatile uint16_t channels[64]; /* odd access causes a bus error ? */
|
||||
volatile uint16_t controlMemoryAddr;
|
||||
volatile uint16_t pad2;
|
||||
volatile uint16_t controlMemoryDataWrite;
|
||||
volatile uint16_t pad3;
|
||||
volatile uint16_t controlMemoryDataRead;
|
||||
volatile uint16_t pad4;
|
||||
volatile uint16_t lastChannel;
|
||||
volatile uint16_t pad5;
|
||||
volatile uint16_t singleScan;
|
||||
volatile uint16_t pad6;
|
||||
volatile uint16_t stopScan;
|
||||
volatile uint16_t pad7;
|
||||
volatile uint16_t clearControlMemoryAddr;
|
||||
volatile uint16_t pad8;
|
||||
volatile uint16_t enableContinuousScanning;
|
||||
volatile uint16_t pad9;
|
||||
volatile uint16_t disableContinuousScanning;
|
||||
volatile uint16_t pad10;
|
||||
volatile uint16_t enableDoneInt;
|
||||
volatile uint16_t pad11;
|
||||
volatile uint16_t disbaleDoneInt;
|
||||
volatile uint16_t pad12;
|
||||
volatile uint16_t clearDoneInt;
|
||||
volatile uint16_t pad13;
|
||||
volatile uint16_t testDoneInt;
|
||||
volatile uint16_t pad14;
|
||||
};
|
||||
|
||||
#ifdef INTERRUPTS
|
||||
LOCAL void KscV215_int_service(unsigned la);
|
||||
#endif
|
||||
LOCAL void KscV215_init_card(unsigned la);
|
||||
|
||||
LOCAL void KscV215_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
);
|
||||
|
||||
LOCAL kscV215Stat KscV215WriteSync(
|
||||
struct KscV215_A24 *pA24,
|
||||
volatile uint16_t *preg,
|
||||
uint16_t val
|
||||
);
|
||||
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvKscV215={
|
||||
2,
|
||||
NULL, /* VXI report takes care of this */
|
||||
KscV215Init};
|
||||
|
||||
/*
|
||||
* KscV215_init
|
||||
*
|
||||
* initialize all KscV215 cards
|
||||
*
|
||||
*/
|
||||
kscV215Stat KscV215Init(void)
|
||||
{
|
||||
kscV215Stat r0;
|
||||
|
||||
/*
|
||||
* do nothing on crates without VXI
|
||||
*/
|
||||
if(!epvxiResourceMangerOK){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
KscV215DriverId = epvxiUniqueDriverID();
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_KSC;
|
||||
dsp.model = VXI_MODEL_KSCV215;
|
||||
r0 = epvxiLookupLA(&dsp, KscV215_init_card, (void *)NULL);
|
||||
if(r0){
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* KSCV215_INIT_CARD
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void KscV215_init_card(unsigned la)
|
||||
{
|
||||
kscV215Stat status;
|
||||
int i;
|
||||
struct KscV215_config *pc;
|
||||
struct KscV215_A24 *pA24;
|
||||
struct vxi_csr *pcsr;
|
||||
int model;
|
||||
|
||||
status = epvxiOpen(
|
||||
la,
|
||||
KscV215DriverId,
|
||||
(unsigned long) sizeof(*pc),
|
||||
KscV215_stat);
|
||||
if(status){
|
||||
errPrintf(
|
||||
status,
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
"AT5VXI: device open failed %d\n",
|
||||
la);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
status = KSCV215_PCONFIG(la, pc);
|
||||
if(status){
|
||||
errMessage(status,NULL);
|
||||
epvxiClose(la, KscV215DriverId);
|
||||
return;
|
||||
}
|
||||
|
||||
pA24 = epvxiA24Base(la);
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->dir.w.control = KscV215csrInit;
|
||||
|
||||
status = KscV215WriteSync(pA24, &pA24->controlMemoryAddr, 0U);
|
||||
if(status){
|
||||
epvxiClose(la, KscV215DriverId);
|
||||
errMessage(status, "KscV215 init failed\n");
|
||||
return;
|
||||
}
|
||||
for(i=0; i<(NELEMENTS(pA24->channels)/2); i++){
|
||||
status = KscV215WriteSync(
|
||||
pA24,
|
||||
&pA24->controlMemoryDataWrite,
|
||||
0U);
|
||||
if(status){
|
||||
epvxiClose(la, KscV215DriverId);
|
||||
errMessage(status, "KscV215 init failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* turn on continuous scan mode
|
||||
*/
|
||||
status = KscV215WriteSync(
|
||||
pA24,
|
||||
&pA24->enableContinuousScanning,
|
||||
0U);
|
||||
if(status){
|
||||
epvxiClose(la, KscV215DriverId);
|
||||
errMessage(status, "KscV215 init failed- device left open\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FASTLOCKINIT(&pc->lock);
|
||||
scanIoInit(&pc->ioscanpvt);
|
||||
|
||||
#ifdef INTERRUPTS
|
||||
status = intConnect(
|
||||
(unsigned char) INUM_TO_IVEC(la),
|
||||
KscV215_int_service,
|
||||
(void *) la);
|
||||
if(status == ERROR){
|
||||
epvxiClose(la, KscV215DriverId);
|
||||
errMessage(S_dev_vxWorksVecInstlFail,
|
||||
"KscV215 init failed- device left open");
|
||||
return;
|
||||
}
|
||||
sysIntEnable(KSCV215_INT_LEVEL);
|
||||
#endif
|
||||
|
||||
status = epvxiRegisterMakeName(VXI_MAKE_KSC, "Kinetic Systems");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
|
||||
model = VXIMODEL(pcsr);
|
||||
status = epvxiRegisterModelName(
|
||||
VXIMAKE(pcsr),
|
||||
model,
|
||||
"V215 16 bit 32 channel ADC\n");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* KscV215WriteSync
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL kscV215Stat KscV215WriteSync(
|
||||
struct KscV215_A24 *pA24,
|
||||
volatile uint16_t *preg,
|
||||
uint16_t val
|
||||
)
|
||||
{
|
||||
kscV215Stat status;
|
||||
int i;
|
||||
|
||||
for(i=0; i<MAXTRIES; i++){
|
||||
*preg = val;
|
||||
if(pA24->diag & KscV215Handshake){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
taskDelay(1);
|
||||
}
|
||||
|
||||
status = S_dev_deviceTMO;
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* KscV215_int_service()
|
||||
*
|
||||
*
|
||||
* This device interrupts once the
|
||||
* switches have settled
|
||||
*
|
||||
*/
|
||||
#ifdef INTERRUPTS
|
||||
LOCAL void KscV215_int_service(unsigned la)
|
||||
{
|
||||
kscV215Stat s;
|
||||
struct KscV215_config *pc;
|
||||
|
||||
s = KSCV215_PCONFIG(la, pc);
|
||||
if(s){
|
||||
logMsg( "Int to ukn device %s line=%d\n",
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* tell them that the switches have settled
|
||||
*/
|
||||
scanIoRequest(pc->ioscanpvt);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* KSCV215_STAT
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void KscV215_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
)
|
||||
{
|
||||
kscV215Stat s;
|
||||
struct KscV215_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
struct KscV215_A24 *pA24;
|
||||
int i;
|
||||
|
||||
s = KSCV215_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pA24 = (struct KscV215_A24 *) epvxiA24Base(la);
|
||||
|
||||
if(level>0){
|
||||
printf ("KSC V215 32 CHANNEL 16 BIT ADC.\n");
|
||||
}
|
||||
if (level > 1) {
|
||||
for (i = 0; i < 32; i++)
|
||||
printf ("Channel %d Value %d\n",
|
||||
i,
|
||||
pA24->channels[i*2]);
|
||||
}
|
||||
if (level > 2) {
|
||||
printf ("\nGain Setting (Control Memory Data Register\n");
|
||||
pA24->controlMemoryAddr = 0;
|
||||
for (i = 0; i < 32; i++) {
|
||||
switch (pA24->controlMemoryAddr) {
|
||||
case 0:
|
||||
printf ("+- 10V");
|
||||
break;
|
||||
case 1:
|
||||
printf ("+- 5V");
|
||||
break;
|
||||
case 3:
|
||||
printf ("+- 2.5V");
|
||||
break;
|
||||
case 5:
|
||||
printf ("+- 1.25V");
|
||||
break;
|
||||
case 6:
|
||||
printf ("+- 625mV");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown Gain Setting.");
|
||||
}
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* AT5VXI_AI_DRIVER
|
||||
*
|
||||
* analog input driver
|
||||
*/
|
||||
kscV215Stat KscV215_ai_driver(
|
||||
unsigned la,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
)
|
||||
{
|
||||
struct KscV215_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
struct KscV215_A24 *pA24;
|
||||
long tmp;
|
||||
int i;
|
||||
kscV215Stat s;
|
||||
|
||||
s = KSCV215_PCONFIG(la, pc);
|
||||
if(s){
|
||||
return s;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pA24 = epvxiA24Base(la);
|
||||
|
||||
if(chan >= NELEMENTS(pA24->channels)/2){
|
||||
return S_dev_badSignalNumber;
|
||||
}
|
||||
|
||||
for(i=0; i<MAXTRIES; i++){
|
||||
tmp = pA24->channels[chan<<1];
|
||||
if(pA24->diag & KscV215Handshake){
|
||||
tmp = tmp + 0xffff;
|
||||
tmp = tmp >> 4;
|
||||
tmp &= 0xfff;
|
||||
*prval = tmp;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
taskDelay(1);
|
||||
}
|
||||
|
||||
s = S_dev_deviceTMO;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* KscV215_getioscanpvt()
|
||||
*/
|
||||
kscV215Stat KscV215_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
)
|
||||
{
|
||||
kscV215Stat s;
|
||||
struct KscV215_config *pc;
|
||||
|
||||
s = KSCV215_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
*scanpvt = pc->ioscanpvt;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* drvKscV215.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* KscV215_driver.c
|
||||
*
|
||||
* driver for KscV215 VXI module
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
*/
|
||||
|
||||
#define VXI_MODEL_KSCV215 (0x215)
|
||||
|
||||
typedef long kscV215Stat;
|
||||
|
||||
kscV215Stat KscV215Init(void);
|
||||
|
||||
kscV215Stat KscV215_ai_driver(
|
||||
unsigned la,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
);
|
||||
|
||||
kscV215Stat KscV215_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,627 @@
|
||||
|
||||
/* drvMz8310.c */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* Routines specific to the MZ8310. Low level routines for the AMD STC in
|
||||
* stc_driver.c
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 1989
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification History
|
||||
* joh 02-20-89 Init Release
|
||||
* joh 04-28-89 Added read back
|
||||
* joh 11-17-89 added readback to io report
|
||||
* joh 12-10-89 DB defaults the internal/external clock
|
||||
* parameter to 0 or external clock. This was the opposite
|
||||
* of what this driver expected. Fix was made here.
|
||||
* joh 07-06-90 print channel number with channel value in IO report
|
||||
* joh 02-25-91 made ext/int clk IO report more readable
|
||||
* joh 09-05-91 converted to v5 vxWorks
|
||||
* bg 09-15-91 added sysBustoLocalAdrs() for addressing
|
||||
* bg 03-10-92 added the argument, level, to mz310_io_report().
|
||||
* bg 04-27-92 added rebootHookAdd and mz8310_reset so ioc will
|
||||
* not hang on ctl X reboot.
|
||||
* joh 04-28-92 added arguments to MACROS which had hidden
|
||||
* parameters
|
||||
* bg 06-25-92 combined drvMz8310.c and mz8310_driver.c
|
||||
* bg 06-26-92 Added level to mz8310_io_report.
|
||||
* joh 08-05-92 callable interface now conforms with epics standard
|
||||
* mgb 08-04-93 Removed V5/V4 and EPICS_V2 conditionals
|
||||
* joh 08-24-93 Include drvStc.h and ANSI C upgrade
|
||||
* joh 09-29-93 removed superfluous error message
|
||||
*/
|
||||
|
||||
/* drvMz8310.c - Driver Support Routines for Mz8310 */
|
||||
#include <vxWorks.h>
|
||||
#include <stdioLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <stdlib.h>
|
||||
#include <intLib.h>
|
||||
#include <rebootLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <vme.h>
|
||||
#include <iv.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <module_types.h>
|
||||
#include <fast_lock.h>
|
||||
#include <devLib.h>
|
||||
#include <drvStc.h>
|
||||
|
||||
#include <drvMz8310.h>
|
||||
|
||||
#define MZ8310CHIPSIZE 0x20
|
||||
#define MZ8310SIZE 0x00000100
|
||||
#define MZ8310BASE(CARD) (shortaddr+tm_addrs[MZ8310]+(CARD)*MZ8310SIZE)
|
||||
|
||||
#define MZ8310DATA 0
|
||||
#define MZ8310CMD 3
|
||||
#define MZ8310CHANONCHIP 5
|
||||
#define MZ8310CHIPCOUNT 2
|
||||
#define MZ8310CHANCNT (MZ8310CHANONCHIP*MZ8310CHIPCOUNT)
|
||||
|
||||
/*
|
||||
NOTE: The mizar draftsman has labeled the chip at the
|
||||
highest address as one and the chip at the lowest address
|
||||
2 so I am reversing the chip number below.
|
||||
*/
|
||||
#define CHIP_REVERSE(CHIP) (MZ8310CHIPCOUNT-1-(CHIP))
|
||||
#define CHIP_ADDR(CARD,CHIP) (MZ8310BASE(CARD)+\
|
||||
(CHIP_REVERSE(CHIP)*MZ8310CHIPSIZE))
|
||||
|
||||
#define MZ8310_CMD_ADDR(CARD,CHIP)\
|
||||
((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + MZ8310CMD)
|
||||
#define MZ8310_DATA_ADDR(CARD,CHIP)\
|
||||
((volatile uint16_t *) CHIP_ADDR(CARD,CHIP) + MZ8310DATA)
|
||||
#if 0
|
||||
#define MZ8310VECBASE(CARD,CHIP)\
|
||||
((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + 0x41)
|
||||
#endif
|
||||
|
||||
#define MZ8310VECSIZE (0x20)
|
||||
#define MZ8310INTCNT 4
|
||||
#define MZ8310FIRSTINTCHAN 0
|
||||
#define MZ8310INTVEC(CARD,CHAN)\
|
||||
(MZ8310_INT_VEC_BASE + (CARD*MZ8310INTCNT) + mz8310_strap[CHAN].vec_num)
|
||||
|
||||
#define MZ8310_INTERUPTABLE(CHAN) (mz8310_strap[CHAN].vec_addr)
|
||||
|
||||
# define INT_TICKS 4.0e06 /* speed of F1 in Hz */
|
||||
# define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */
|
||||
|
||||
|
||||
struct mz8310_int_conf{
|
||||
void (*user_service)(void *user_param);
|
||||
void *user_param;
|
||||
unsigned int cnt;
|
||||
};
|
||||
|
||||
struct mz8310_conf{
|
||||
char init;
|
||||
FAST_LOCK lock;
|
||||
struct mz8310_int_conf icf[MZ8310CHANCNT];
|
||||
};
|
||||
|
||||
struct mz8310_strap_info{
|
||||
unsigned char irq; /* the level at which the chan gen ints */
|
||||
unsigned char vec_num; /* really a vec offset-see MZ8310INTVEC */
|
||||
unsigned char vec_addr;/* offset from card base address */
|
||||
};
|
||||
|
||||
static volatile char *shortaddr;
|
||||
|
||||
LOCAL struct mz8310_conf *mzconf;
|
||||
LOCAL unsigned int mz8310_card_count;
|
||||
|
||||
/*
|
||||
only 4 unique interrupts per card but any channel can potentially
|
||||
generate an interrupt depending on board strapping.
|
||||
|
||||
NOTE: existence of vec addr tells the driver that that channel is
|
||||
strapped for interrupts since the card can't be polled for this info.
|
||||
|
||||
In the MIZAR 8310 Documentation:
|
||||
|
||||
Designation vector reg offset
|
||||
IRQA 0x41
|
||||
IRQB 0x61
|
||||
IRQC 0x81
|
||||
IRQD 0xa1
|
||||
*/
|
||||
|
||||
LOCAL struct mz8310_strap_info mz8310_strap[MZ8310CHANCNT] =
|
||||
{
|
||||
{ NULL, NULL, NULL }, /* channel 0 */
|
||||
{ NULL, NULL, NULL }, /* channel 1 */
|
||||
{ NULL, NULL, NULL }, /* channel 2 */
|
||||
{ NULL, NULL, NULL }, /* channel 3 */
|
||||
{ NULL, NULL, NULL }, /* channel 4 */
|
||||
{ NULL, NULL, NULL }, /* channel 5 */
|
||||
{ 1, 0, 0x41 }, /* channel 6 */
|
||||
{ 3, 1, 0x61 }, /* channel 7 */
|
||||
{ 5, 2, 0x81 }, /* channel 8 */
|
||||
{ 6, 3, 0xa1 } /* channel 9 */
|
||||
};
|
||||
|
||||
/* forward reference. */
|
||||
LOCAL int mz8310_reset(void);
|
||||
LOCAL mz8310Stat mz8310_io_report_card(unsigned card, unsigned level);
|
||||
LOCAL mz8310Stat mz8310_init_card(unsigned card);
|
||||
LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel);
|
||||
LOCAL mz8310Stat mz8310_io_report(unsigned level);
|
||||
LOCAL mz8310Stat mz8310_init(void);
|
||||
LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel);
|
||||
LOCAL void mz8310_int_service(struct mz8310_int_conf *icf);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvMz8310={
|
||||
2,
|
||||
mz8310_io_report,
|
||||
mz8310_init};
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_io_report()
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_io_report(unsigned level)
|
||||
{
|
||||
unsigned card;
|
||||
|
||||
for(card=0; card<tm_num_cards[MZ8310]; card++)
|
||||
mz8310_io_report_card(card, level);
|
||||
|
||||
return MZ8310_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_io_report_card()
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_io_report_card(unsigned card, unsigned level)
|
||||
{
|
||||
unsigned channel;
|
||||
unsigned chip;
|
||||
mz8310Stat status;
|
||||
|
||||
for(chip=0; chip<MZ8310CHIPCOUNT; chip++){
|
||||
status = stc_io_report(
|
||||
MZ8310_CMD_ADDR(card,chip),
|
||||
MZ8310_DATA_ADDR(card,chip));
|
||||
if(status){
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
printf("TM: MZ8310:\tcard %d\n", card);
|
||||
|
||||
|
||||
if (mzconf && card<mz8310_card_count && level){
|
||||
for(channel=0;channel<MZ8310CHANCNT;channel++){
|
||||
status = mz8310_read_test(card, channel);
|
||||
if(status){
|
||||
return status;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return MZ8310_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_init()
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_init(void)
|
||||
{
|
||||
unsigned card;
|
||||
mz8310Stat status;
|
||||
struct mz8310_conf *temp_mzconf;
|
||||
unsigned card_count = tm_num_cards[MZ8310];
|
||||
|
||||
status = sysBusToLocalAdrs(
|
||||
VME_AM_SUP_SHORT_IO,
|
||||
0,
|
||||
(char **)&shortaddr);
|
||||
if (status != OK){
|
||||
status = S_dev_badA16;
|
||||
errMessage(status, "A16 Address map error mz8310 driver");
|
||||
return status;
|
||||
}
|
||||
|
||||
temp_mzconf = (struct mz8310_conf *) malloc(sizeof(*mzconf)*card_count);
|
||||
if(!temp_mzconf)
|
||||
return S_dev_noMemory;
|
||||
|
||||
for(card=0; card<card_count; card++){
|
||||
FASTLOCKINIT(&temp_mzconf[card].lock);
|
||||
}
|
||||
|
||||
if(mzconf){
|
||||
for(card=0; card<card_count; card++){
|
||||
if(FASTLOCKFREE(&mzconf[card].lock)<0){
|
||||
status = S_dev_internal;
|
||||
errMessage(status, "error freeing sem");
|
||||
}
|
||||
}
|
||||
free(mzconf);
|
||||
}
|
||||
|
||||
mzconf = temp_mzconf;
|
||||
|
||||
for(card=0; card<card_count; card++){
|
||||
status = mz8310_init_card(card);
|
||||
if(status){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mz8310_card_count = card;
|
||||
|
||||
rebootHookAdd(mz8310_reset);
|
||||
|
||||
return MZ8310_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* mz8310_init_card()
|
||||
*
|
||||
* Locking for this provided by mz8310_init()
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_init_card(unsigned card)
|
||||
{
|
||||
unsigned chip;
|
||||
unsigned chan;
|
||||
mz8310Stat error;
|
||||
/*
|
||||
* binary division
|
||||
* data ptr seq enbl
|
||||
* 16 bit bus
|
||||
* FOUT on
|
||||
* FOUT divide by one
|
||||
* FOUT source (F1)
|
||||
* Time of day disabled
|
||||
*/
|
||||
unsigned short master_mode = 0x2100;
|
||||
|
||||
for(chip=0; chip< MZ8310CHIPCOUNT; chip++){
|
||||
error = stc_init(
|
||||
MZ8310_CMD_ADDR(card,chip),
|
||||
MZ8310_DATA_ADDR(card,chip),
|
||||
master_mode);
|
||||
if(error){
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
for(chan=0; chan<MZ8310CHANCNT; chan++)
|
||||
mz8310_setup_int(card,chan);
|
||||
|
||||
mzconf[card].init = TRUE;
|
||||
|
||||
return MZ8310_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_setup_int()
|
||||
*
|
||||
* (locked by calling routines)
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel)
|
||||
{
|
||||
unsigned char vector;
|
||||
mz8310Stat status;
|
||||
|
||||
mzconf[card].icf[channel].user_service = NULL;
|
||||
mzconf[card].icf[channel].user_param = NULL;
|
||||
mzconf[card].icf[channel].cnt = 0;
|
||||
|
||||
/*
|
||||
* Is this channel strapped for interrupts
|
||||
*/
|
||||
if(!MZ8310_INTERUPTABLE(channel))
|
||||
return MZ8310_SUCCESS;
|
||||
|
||||
vector = MZ8310INTVEC(card,channel);
|
||||
status = vxMemProbe(
|
||||
(char *)MZ8310BASE(card) + mz8310_strap[channel].vec_addr,
|
||||
WRITE,
|
||||
sizeof(vector),
|
||||
(char *)&vector);
|
||||
if(status != OK){
|
||||
status = S_dev_noDevice;
|
||||
errMessage(status, NULL);
|
||||
return S_dev_noDevice;
|
||||
}
|
||||
|
||||
status = intConnect( INUM_TO_IVEC(vector),
|
||||
mz8310_int_service,
|
||||
(int)&mzconf[card].icf[channel]);
|
||||
if(status != OK)
|
||||
return S_dev_vxWorksVecInstlFail;
|
||||
|
||||
sysIntEnable(mz8310_strap[channel].irq);
|
||||
|
||||
return MZ8310_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_one_shot_read()
|
||||
*/
|
||||
mz8310Stat mz8310_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
)
|
||||
{
|
||||
int chip = channel/MZ8310CHANONCHIP;
|
||||
double ticks;
|
||||
unsigned short iedge0;
|
||||
unsigned short iedge1;
|
||||
mz8310Stat status;
|
||||
|
||||
if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
if(card>=mz8310_card_count)
|
||||
return S_dev_badA16;
|
||||
|
||||
if(!mzconf)
|
||||
return S_dev_noDevice;
|
||||
|
||||
FASTLOCK(&mzconf[card].lock);
|
||||
|
||||
status =
|
||||
stc_one_shot_read(
|
||||
preset,
|
||||
&iedge0,
|
||||
&iedge1,
|
||||
MZ8310_CMD_ADDR(card,chip),
|
||||
MZ8310_DATA_ADDR(card,chip),
|
||||
channel % MZ8310CHANONCHIP,
|
||||
int_source);
|
||||
if(status==STC_SUCCESS){
|
||||
ticks = *int_source ? INT_TICKS : EXT_TICKS;
|
||||
*edge0_delay = iedge0 / ticks;
|
||||
*edge1_delay = iedge1 / ticks;
|
||||
}
|
||||
|
||||
FASTUNLOCK(&mzconf[card].lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_read_test()
|
||||
*/
|
||||
LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel)
|
||||
{
|
||||
unsigned preset;
|
||||
double edge0_delay;
|
||||
double edge1_delay;
|
||||
unsigned int_source;
|
||||
mz8310Stat status;
|
||||
static char *pclktype[] = {"external-clk", "internal-clk"};
|
||||
static char *ppresettype[] = {"preset-FALSE", "preset-TRUE "};
|
||||
|
||||
status =
|
||||
mz8310_one_shot_read(
|
||||
&preset,
|
||||
&edge0_delay,
|
||||
&edge1_delay,
|
||||
card,
|
||||
channel,
|
||||
&int_source);
|
||||
if(status==MZ8310_SUCCESS){
|
||||
printf( "\tChannel %u %s delay=%f width=%f %s\n",
|
||||
channel,
|
||||
ppresettype[preset&1],
|
||||
edge0_delay,
|
||||
edge1_delay,
|
||||
pclktype[int_source&1]);
|
||||
if(mzconf[card].icf[channel].cnt)
|
||||
printf("\tChannel %u Interrupt count=%u\n",
|
||||
channel,
|
||||
mzconf[card].icf[channel].cnt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_one_shot()
|
||||
*/
|
||||
mz8310Stat mz8310_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param /* parameter to pass to above routine */
|
||||
)
|
||||
{
|
||||
int chip = channel/MZ8310CHANONCHIP;
|
||||
double ticks = int_source?INT_TICKS:EXT_TICKS;
|
||||
mz8310Stat status;
|
||||
|
||||
if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
if(card>=mz8310_card_count)
|
||||
return S_dev_badA16;
|
||||
|
||||
if(!mzconf)
|
||||
return S_dev_noDevice;
|
||||
|
||||
/* dont overflow unsigned short in STC */
|
||||
if(edge0_delay >= 0xffff/ticks)
|
||||
return S_dev_highValue;
|
||||
if(edge1_delay >= 0xffff/ticks)
|
||||
return S_dev_highValue;
|
||||
if(edge0_delay < 0.0)
|
||||
return S_dev_lowValue;
|
||||
if(edge1_delay < 0.0)
|
||||
return S_dev_lowValue;
|
||||
|
||||
FASTLOCK(&mzconf[card].lock);
|
||||
|
||||
/* Enable calling of user routine */
|
||||
if(MZ8310_INTERUPTABLE(channel)){
|
||||
mzconf[card].icf[channel].user_service = event_rtn;
|
||||
mzconf[card].icf[channel].user_param = event_rtn_param;
|
||||
}
|
||||
|
||||
status =
|
||||
stc_one_shot(
|
||||
preset,
|
||||
(unsigned short) (edge0_delay * ticks),
|
||||
(unsigned short) (edge1_delay * ticks),
|
||||
MZ8310_CMD_ADDR(card,chip),
|
||||
MZ8310_DATA_ADDR(card,chip),
|
||||
channel % MZ8310CHANONCHIP,
|
||||
int_source);
|
||||
|
||||
FASTUNLOCK(&mzconf[card].lock);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_int_service()
|
||||
*/
|
||||
LOCAL void mz8310_int_service(struct mz8310_int_conf *icf)
|
||||
{
|
||||
icf->cnt++;
|
||||
|
||||
if(icf->user_service)
|
||||
(*icf->user_service)(icf->user_param);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are provided for mz8310 access from the shell
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_cmd()
|
||||
*/
|
||||
int mz8310_cmd(
|
||||
unsigned value,
|
||||
unsigned card,
|
||||
unsigned chip
|
||||
)
|
||||
{
|
||||
volatile unsigned char *cmd = MZ8310_CMD_ADDR(card,chip);
|
||||
|
||||
*cmd = value;
|
||||
|
||||
return *cmd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_rdata()
|
||||
*/
|
||||
int mz8310_rdata(int card, int chip)
|
||||
{
|
||||
volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip);
|
||||
|
||||
return *data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_wdata()
|
||||
*/
|
||||
int mz8310_wdata(
|
||||
unsigned value,
|
||||
unsigned card,
|
||||
unsigned chip
|
||||
)
|
||||
{
|
||||
volatile uint16_t *data = MZ8310_DATA_ADDR(card,chip);
|
||||
|
||||
*data = value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* mz8310_reset
|
||||
*/
|
||||
LOCAL int mz8310_reset(void)
|
||||
{
|
||||
short card,channel,chip;
|
||||
|
||||
for (card = 0; card < mz8310_card_count; card++){
|
||||
FASTLOCK(&mzconf[card].lock);
|
||||
for ( channel = 0; channel < tm_num_channels[MZ8310]; channel++){
|
||||
if (mzconf[card].icf[channel].cnt){
|
||||
chip = channel/MZ8310CHANONCHIP;
|
||||
|
||||
stc_one_shot(
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
MZ8310_CMD_ADDR(card,chip),
|
||||
MZ8310_DATA_ADDR(card,chip),
|
||||
channel % MZ8310CHANONCHIP,
|
||||
0);
|
||||
}
|
||||
}
|
||||
FASTUNLOCK(&mzconf[card].lock);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/* drvMz8310.c */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* Routines specific to the MZ8310. Low level routines for the AMD STC in
|
||||
* stc_driver.c
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 1989
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification History
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#define MZ8310_SUCCESS 0
|
||||
|
||||
typedef long mz8310Stat;
|
||||
|
||||
mz8310Stat mz8310_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
);
|
||||
|
||||
mz8310Stat mz8310_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param /* parameter to pass to above routine */
|
||||
);
|
||||
|
||||
int mz8310_cmd(
|
||||
unsigned value,
|
||||
unsigned card,
|
||||
unsigned chip
|
||||
);
|
||||
|
||||
int mz8310_rdata(int card, int chip);
|
||||
|
||||
int mz8310_wdata(
|
||||
unsigned value,
|
||||
unsigned card,
|
||||
unsigned chip
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
/* drvStc.c */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* The following are specific driver routines for the AMD STC
|
||||
*
|
||||
* NOTE: if multiple threads use these routines at once you must provide locking
|
||||
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
|
||||
*
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
* joh 022089 Init Release
|
||||
* joh 042889 Added read back
|
||||
* joh 111789 Fixed reset goes to byte mode bug
|
||||
* joh 121090 Fixed confusion about the polarity of internal/external
|
||||
* clock between DB and the drivers.
|
||||
* joh 110791 Prevent the stc from generating tc prior to the trigger
|
||||
* in delayed pulse mode by forcing edge 0 delays of zero to be
|
||||
* a delay of one instead.
|
||||
* joh 010491 force all edge 0 delays less than two to two
|
||||
* joh 082493 ANSI C and EPICS return codes
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <module_types.h>
|
||||
#include <drvStc.h>
|
||||
#include <devLib.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_io_report()
|
||||
*/
|
||||
stcStat stc_io_report(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
/*
|
||||
* addd AMD STC status here
|
||||
*/
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_init()
|
||||
*/
|
||||
stcStat stc_init(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned master_mode
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
unsigned channel;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
/*
|
||||
* go to 16 bit mode in order to test the master mode register
|
||||
*/
|
||||
STC_BUS16;
|
||||
if(master_mode != STC_MASTER_MODE){
|
||||
|
||||
/*
|
||||
* start in a known state
|
||||
*/
|
||||
STC_RESET;
|
||||
|
||||
/*
|
||||
* required since the reset puts it in byte mode
|
||||
*/
|
||||
STC_BUS16;
|
||||
STC_SET_MASTER_MODE(master_mode);
|
||||
for(channel=0; channel<CHANONCHIP; channel++)
|
||||
STC_LOAD;
|
||||
}
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_one_shot_read()
|
||||
*/
|
||||
stcStat stc_one_shot_read(
|
||||
unsigned *preset,
|
||||
unsigned short *edge0_count,
|
||||
unsigned short *edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned *int_source
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
uint16_t mode;
|
||||
uint16_t edge0;
|
||||
uint16_t edge1;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
if(channel>=CHANONCHIP)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
STC_CTR_READ(mode, edge0, edge1);
|
||||
|
||||
/*
|
||||
* Only return values if the counter is in the proper mode
|
||||
* see stc_one_shot() for info on conversions and functions selected
|
||||
* by these bit fields
|
||||
*/
|
||||
if(mode == 0xc16a){
|
||||
*int_source = FALSE;
|
||||
*preset = TRUE;
|
||||
*edge0_count = ~edge0;
|
||||
*edge1_count = ~edge1+1;
|
||||
}
|
||||
else if(mode == 0xc162){
|
||||
*int_source = FALSE;
|
||||
*preset = FALSE;
|
||||
*edge0_count = edge0-1;
|
||||
*edge1_count = edge1;
|
||||
}
|
||||
else if(mode == 0xcb6a){
|
||||
*int_source = TRUE;
|
||||
*preset = TRUE;
|
||||
*edge0_count = ~edge0;
|
||||
*edge1_count = ~edge1+1;
|
||||
}
|
||||
else if(mode == 0xcb62){
|
||||
*int_source = TRUE;
|
||||
*preset = FALSE;
|
||||
*edge0_count = edge0-1;
|
||||
*edge1_count = edge1;
|
||||
}
|
||||
else
|
||||
return S_dev_internal;
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_one_shot()
|
||||
*/
|
||||
stcStat stc_one_shot(
|
||||
unsigned preset,
|
||||
unsigned edge0_count,
|
||||
unsigned edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned int_source
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(channel>=CHANONCHIP)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
/*
|
||||
* joh 110791
|
||||
* Prevent the stc from generating tc prior to the trigger
|
||||
* in delayed pulse mode by forcing edge 0 delays of zero to be
|
||||
* a delay of one instead.
|
||||
*
|
||||
* 010492
|
||||
* Strange extra edges occur when the delay is 0 or 1
|
||||
* and the counter is reinitialized to a width of
|
||||
* zero so I have disabled a delay of one also
|
||||
*
|
||||
* These extra edges occur when TC is set
|
||||
*/
|
||||
|
||||
if(edge0_count < 2)
|
||||
edge0_count = 2;
|
||||
|
||||
STC_DISARM;
|
||||
|
||||
/*
|
||||
* active positive going edge (gate input)
|
||||
* count on the rising edge of source
|
||||
* ctr source: (F1- internal) (SRC1- external)
|
||||
* mode L - Hardware triggered delayed pulse one-shot
|
||||
* binary count
|
||||
* count down (count up if preset is TRUE)
|
||||
* TC toggled output
|
||||
*
|
||||
* see chapter 7 of the Am9513 STC tech man concerning count + 1
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: I must be able to read back the state of the preset later
|
||||
* so I encode this information in the count down/up bit.
|
||||
* count up on TRUE preset
|
||||
* count down on FALSE preset
|
||||
*
|
||||
* see stc_one_shot_read() above
|
||||
*/
|
||||
if(int_source){
|
||||
if(preset)
|
||||
STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1)
|
||||
else
|
||||
STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count);
|
||||
}else{
|
||||
if(preset)
|
||||
STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1)
|
||||
else
|
||||
STC_CTR_INIT(0xc162, edge0_count+1, edge1_count);
|
||||
}
|
||||
|
||||
STC_LOAD;
|
||||
/*
|
||||
*see chapter 7 of the Am9513 STC tech man concerning this step
|
||||
*/
|
||||
|
||||
STC_STEP;
|
||||
|
||||
STC_SET_TC(preset);
|
||||
|
||||
/*
|
||||
* Only arm counter if the pulse has a finite duration
|
||||
*/
|
||||
if(edge1_count != 0){
|
||||
STC_ARM;
|
||||
}
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/* drvStc.h */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* The following are specific driver routines for the AMD STC
|
||||
*
|
||||
* NOTE: if multiple threads use these routines at once you must provide locking
|
||||
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
|
||||
*
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
* joh 022089 Init Release
|
||||
* joh 082493 ANSI C and EPICS return codes
|
||||
*/
|
||||
|
||||
/*
|
||||
* AMD STC constants
|
||||
*/
|
||||
#define CHANONCHIP 5U
|
||||
#define CHIPCHAN (channel%CHANONCHIP)
|
||||
#define CHIPNUM (channel/CHANONCHIP)
|
||||
|
||||
#define STC_RESET *pcmd = 0xffU
|
||||
#define STC_BUS16 *pcmd = 0xefU
|
||||
#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);}
|
||||
#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata)
|
||||
|
||||
#define STC_CTR_INIT(MODE,LOAD,HOLD)\
|
||||
{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);}
|
||||
|
||||
#define STC_CTR_READ(MODE,LOAD,HOLD)\
|
||||
{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;}
|
||||
|
||||
#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U)
|
||||
|
||||
#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN)
|
||||
#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U)
|
||||
#define STC_ARM *pcmd = 0x20U | 1<<CHIPCHAN
|
||||
#define STC_DISARM *pcmd = 0xc0U | 1<<CHIPCHAN
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* return type of the stc routines
|
||||
*/
|
||||
typedef long stcStat;
|
||||
#define STC_SUCCESS 0
|
||||
|
||||
|
||||
stcStat stc_io_report(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata
|
||||
);
|
||||
|
||||
|
||||
stcStat stc_init(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned master_mode
|
||||
);
|
||||
|
||||
stcStat stc_one_shot_read(
|
||||
unsigned *preset,
|
||||
uint16_t *edge0_count,
|
||||
uint16_t *edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned *int_source
|
||||
);
|
||||
|
||||
stcStat stc_one_shot(
|
||||
unsigned preset,
|
||||
unsigned edge0_count,
|
||||
unsigned edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned int_source
|
||||
);
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
/* drvTime.c */
|
||||
/* base/src/drv $Id$ */
|
||||
/* Glue between timing_drivers and the GTA database
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos Natjonal Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* joh 02-20-89 Init Release
|
||||
* joh 11-16-89 added vxi timing
|
||||
* bg 11-18-91 added time_io_report
|
||||
* bg 02-24-91 added levels to time_io_report.
|
||||
* bg 06-26-92 Combined time_driver.c and drvTime.c
|
||||
* joh 08-05-92 removed report & init routines
|
||||
*/
|
||||
|
||||
static char *sccsID = "@(#)drvTime.c 1.10\t9/9/93";
|
||||
|
||||
/* drvTime.c - Driver Support Routines for Time */
|
||||
#include <vxWorks.h>
|
||||
#include <logLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <epicsPrint.h>
|
||||
|
||||
#include <drvMz8310.h>
|
||||
#include <drvAt5Vxi.h>
|
||||
|
||||
struct pulse{
|
||||
double offset;
|
||||
double width;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* time_driver_read()
|
||||
*
|
||||
*
|
||||
*/
|
||||
int time_driver_read
|
||||
(
|
||||
card, /* 0 through ... */
|
||||
channel, /* 0 through chans on card */
|
||||
card_type, /* module type as stored in GTA DB */
|
||||
int_source, /* (TRUE)External/ (FALSE)Internal source */
|
||||
preset, /* TRUE or COMPLEMENT logic */
|
||||
pulses, /* ptr to array of structure describing pulses */
|
||||
npulses, /* N elements found */
|
||||
npulmax /* N elements in the caller's array */
|
||||
)
|
||||
unsigned card;
|
||||
unsigned channel;
|
||||
unsigned card_type;
|
||||
unsigned *int_source;
|
||||
unsigned *preset;
|
||||
struct pulse *pulses;
|
||||
unsigned *npulses;
|
||||
unsigned npulmax;
|
||||
{
|
||||
int status;
|
||||
|
||||
*npulses=0;
|
||||
|
||||
switch(card_type){
|
||||
case MZ8310:
|
||||
if(npulmax<1)
|
||||
return ERROR;
|
||||
status = mz8310_one_shot_read (
|
||||
preset,
|
||||
&pulses->offset,
|
||||
&pulses->width,
|
||||
card,
|
||||
channel,
|
||||
int_source
|
||||
);
|
||||
if(status==0)
|
||||
*npulses=1;
|
||||
|
||||
return status;
|
||||
case VXI_AT5_TIME:
|
||||
if(npulmax<1)
|
||||
return ERROR;
|
||||
status = at5vxi_one_shot_read (
|
||||
preset,
|
||||
&pulses->offset,
|
||||
&pulses->width,
|
||||
card,
|
||||
channel,
|
||||
int_source
|
||||
);
|
||||
if(status==0)
|
||||
*npulses=1;
|
||||
|
||||
return status;
|
||||
case DG535:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
epicsPrintf("time_driver: No support for that type of timing card\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
int time_driver (
|
||||
card, /* 0 through ... */
|
||||
channel, /* 0 through chans on card */
|
||||
card_type, /* module type as stored in GTA DB */
|
||||
int_source, /* (TRUE)External/ (FALSE)Internal source */
|
||||
preset, /* TRUE or COMPLEMENT logic */
|
||||
pulses, /* ptr to array of structure describing pulses */
|
||||
npulses, /* N elements in this array */
|
||||
eventrtn, /* routine to run on events */
|
||||
eventrtnarg /* argument to above rtn */
|
||||
)
|
||||
unsigned int card;
|
||||
unsigned int channel;
|
||||
unsigned int card_type;
|
||||
unsigned int int_source;
|
||||
int preset;
|
||||
struct pulse *pulses;
|
||||
unsigned int npulses;
|
||||
void (*eventrtn)(void *pParam);
|
||||
void *eventrtnarg;
|
||||
{
|
||||
|
||||
switch(card_type){
|
||||
case MZ8310:
|
||||
if(npulses != 1)
|
||||
return ERROR;
|
||||
return mz8310_one_shot (
|
||||
preset,
|
||||
pulses->offset,
|
||||
pulses->width,
|
||||
card,
|
||||
channel,
|
||||
int_source,
|
||||
eventrtn,
|
||||
eventrtnarg
|
||||
);
|
||||
case VXI_AT5_TIME:
|
||||
if(npulses != 1)
|
||||
return ERROR;
|
||||
return at5vxi_one_shot (
|
||||
preset,
|
||||
pulses->offset,
|
||||
pulses->width,
|
||||
card,
|
||||
channel,
|
||||
int_source,
|
||||
eventrtn,
|
||||
eventrtnarg
|
||||
);
|
||||
case DG535:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
epicsPrintf("time_driver: No support for that type of timing card\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int time_test()
|
||||
{
|
||||
unsigned int card=0;
|
||||
unsigned int channel=0;
|
||||
unsigned int card_type=MZ8310;
|
||||
unsigned int int_source=1;
|
||||
int preset=1;
|
||||
static struct
|
||||
pulse pulses={.00001,.00001};
|
||||
unsigned int npulses = 1;
|
||||
|
||||
unsigned int t_int_source;
|
||||
int t_preset;
|
||||
struct pulse t_pulses;
|
||||
unsigned int t_npulses;
|
||||
|
||||
int status;
|
||||
|
||||
status =
|
||||
time_driver (
|
||||
card, /* 0 through ... */
|
||||
channel, /* 0 through chans on card */
|
||||
card_type, /* module type as stored in GTA DB */
|
||||
int_source, /* (TRUE)External/ (FALSE)Internal source */
|
||||
preset, /* TRUE or COMPLEMENT logic */
|
||||
&pulses, /* ptr to array of structure describing pulses */
|
||||
npulses, /* N elements in this array */
|
||||
NULL, /* routine to run on events */
|
||||
NULL /* argument to above rtn */
|
||||
);
|
||||
if(status==ERROR)
|
||||
return ERROR;
|
||||
|
||||
|
||||
status =
|
||||
time_driver_read(
|
||||
card, /* 0 through ... */
|
||||
channel, /* 0 through chans on card */
|
||||
card_type, /* module type as stored in GTA DB */
|
||||
&t_int_source, /* (TRUE)External/ (FALSE)Internal source */
|
||||
&t_preset, /* TRUE or COMPLEMENT logic */
|
||||
&t_pulses, /* ptr to array of structure describing pulses */
|
||||
&t_npulses, /* N elements found */
|
||||
1 /* max N elements in this array */
|
||||
);
|
||||
if(status==ERROR)
|
||||
return ERROR;
|
||||
|
||||
|
||||
epicsPrintf( "wrote: preset %x internal-clk %x delay %f width %f \n",
|
||||
preset,
|
||||
int_source,
|
||||
pulses.offset,
|
||||
pulses.width);
|
||||
epicsPrintf( "read: preset %x internal-clk %x delay %f width %f count %x\n",
|
||||
t_preset,
|
||||
t_int_source,
|
||||
t_pulses.offset,
|
||||
t_pulses.width,
|
||||
t_npulses);
|
||||
return OK;
|
||||
}
|
||||
@@ -9,30 +9,19 @@ include $(EPICS)/config/CONFIG_BASE
|
||||
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield -traditional
|
||||
|
||||
SRCS.c += ../module_types.c
|
||||
SRCS.c += ../drvAt5Vxi.c
|
||||
SRCS.c += ../drvBB232.c
|
||||
SRCS.c += ../drvBb902.c
|
||||
SRCS.c += ../drvBb910.c
|
||||
SRCS.c += ../drvBitBus.c
|
||||
# SRCS.c += ../drvCaenV265.c
|
||||
SRCS.c += ../drvComet.c
|
||||
SRCS.c += ../drvCompuSm.c
|
||||
SRCS.c += ../drvDvx.c
|
||||
SRCS.c += ../drvEpvxi.c
|
||||
SRCS.c += ../drvEpvxiMsg.c
|
||||
SRCS.c += ../drvFp.c
|
||||
SRCS.c += ../drvFpm.c
|
||||
SRCS.c += ../drvGpib.c
|
||||
SRCS.c += ../drvHp1404a.c
|
||||
SRCS.c += ../drvHpe1368a.c
|
||||
SRCS.c += ../drvHpe1445a.c
|
||||
SRCS.c += ../drvJgvtr1.c
|
||||
SRCS.c += ../drvKscV215.c
|
||||
SRCS.c += ../drvMsg.c
|
||||
SRCS.c += ../drvMz8310.c
|
||||
SRCS.c += ../drvOms.c
|
||||
SRCS.c += ../drvStc.c
|
||||
SRCS.c += ../drvTime.c
|
||||
# SRCS.c += ../drvTranServ.c
|
||||
SRCS.c += ../drvVmi4100.c
|
||||
SRCS.c += ../drvXy010.c
|
||||
@@ -42,30 +31,19 @@ SRCS.c += ../drvXy240.c
|
||||
SRCS.c += ../drvXy566.c
|
||||
|
||||
TARGETS += module_types.o
|
||||
TARGETS += drvAt5Vxi.o
|
||||
TARGETS += drvBB232.o
|
||||
TARGETS += drvBb902.o
|
||||
TARGETS += drvBb910.o
|
||||
TARGETS += drvBitBus.o
|
||||
# TARGETS += drvCaenV265.o
|
||||
TARGETS += drvComet.o
|
||||
TARGETS += drvCompuSm.o
|
||||
TARGETS += drvDvx.o
|
||||
TARGETS += drvEpvxi.o
|
||||
TARGETS += drvEpvxiMsg.o
|
||||
TARGETS += drvFp.o
|
||||
TARGETS += drvFpm.o
|
||||
TARGETS += drvGpib.o
|
||||
TARGETS += drvHp1404a.o
|
||||
TARGETS += drvHpe1368a.o
|
||||
TARGETS += drvHpe1445a.o
|
||||
TARGETS += drvJgvtr1.o
|
||||
TARGETS += drvKscV215.o
|
||||
TARGETS += drvMsg.o
|
||||
TARGETS += drvMz8310.o
|
||||
TARGETS += drvOms.o
|
||||
TARGETS += drvStc.o
|
||||
TARGETS += drvTime.o
|
||||
# TARGETS += drvTranServ.o
|
||||
TARGETS += drvVmi4100.o
|
||||
TARGETS += drvXy010.o
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
*
|
||||
* driver for at5 designed VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 11-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <dbScan.h>
|
||||
|
||||
typedef long at5VxiStatus;
|
||||
|
||||
at5VxiStatus at5vxi_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param/* parameter to pass to above routine */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ai_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval,
|
||||
unsigned short *prbval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_read(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *pval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bi_driver(
|
||||
unsigned card,
|
||||
unsigned long mask,
|
||||
unsigned long *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bo_driver(
|
||||
unsigned card,
|
||||
unsigned long val,
|
||||
unsigned long mask
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_getioscanpvt(
|
||||
unsigned card,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
@@ -0,0 +1,408 @@
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
*
|
||||
* HP E1404A VXI bus slot zero translator
|
||||
* device dependent routines
|
||||
*
|
||||
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* Date 030692
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 joh 073092 Added msg device support & interrupt shutdown for
|
||||
* soft reboots
|
||||
* .02 joh 082792 converted to ANSI C
|
||||
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <intLib.h>
|
||||
#include <rebootLib.h>
|
||||
|
||||
#include <devLib.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <drvHp1404a.h>
|
||||
|
||||
LOCAL unsigned long hpE1404DriverID;
|
||||
|
||||
struct hpE1404_config{
|
||||
void (*pSignalCallback)(int16_t signal);
|
||||
};
|
||||
|
||||
#define TLTRIG(N) (1<<(N))
|
||||
#define ECLTRIG(N) (1<<((N)+8))
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
#define HP1404A_INT_ENABLE 0x0008
|
||||
#define HP1404A_INT_DISABLE 0x0000
|
||||
|
||||
/*
|
||||
*
|
||||
* tag the device dependent registers
|
||||
*/
|
||||
#define IRQ_enable dir.w.dd.reg.ddx1a
|
||||
#define MSG_status dir.w.dd.reg.ddx1e
|
||||
#define fp_trig_drive dir.w.dd.reg.ddx2a
|
||||
#define bp_trig_drive dir.w.dd.reg.ddx22
|
||||
#define signal_read dir.r.dd.reg.ddx10
|
||||
|
||||
#define hpE1404PConfig(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
|
||||
|
||||
LOCAL void hpE1404InitLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL int hpE1404ShutDown(
|
||||
void
|
||||
);
|
||||
|
||||
LOCAL void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
LOCAL void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
);
|
||||
|
||||
LOCAL void hpE1404Int(
|
||||
unsigned la
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Init
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404Init(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
|
||||
status = rebootHookAdd(hpE1404ShutDown);
|
||||
if(status<0){
|
||||
status = S_dev_internal;
|
||||
errMessage(status, "rebootHookAdd() failed");
|
||||
return status;
|
||||
}
|
||||
|
||||
hpE1404DriverID = epvxiUniqueDriverID();
|
||||
|
||||
status = epvxiRegisterMakeName(
|
||||
VXI_MAKE_HP,
|
||||
"Hewlett-Packard");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG_SLOT0,
|
||||
"Slot Zero Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_REG,
|
||||
"Translator (reg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
status = epvxiRegisterModelName(
|
||||
VXI_MAKE_HP,
|
||||
VXI_HP_MODEL_E1404_MSG,
|
||||
"Translator (msg)");
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDown()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL int hpE1404ShutDown(void)
|
||||
{
|
||||
hpE1404Stat status;
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
dsp.model = VXI_HP_MODEL_E1404_REG;
|
||||
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return ERROR;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404ShutDownLA()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404ShutDownLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404InitLA()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404InitLA(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
struct hpE1404_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
hpE1404Stat status;
|
||||
|
||||
status = epvxiOpen(
|
||||
la,
|
||||
hpE1404DriverID,
|
||||
sizeof(*pc),
|
||||
hpE1404IOReport);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
status = hpE1404PConfig(la, pc);
|
||||
if(status){
|
||||
errMessage(status, NULL);
|
||||
epvxiClose(la, hpE1404DriverID);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the self test status to passed for
|
||||
* the message based device
|
||||
*/
|
||||
pcsr->MSG_status = VXIPASS<<2;
|
||||
|
||||
intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpE1404Int,
|
||||
la);
|
||||
|
||||
/*
|
||||
* enable int when signal register is written
|
||||
*/
|
||||
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404SignalConnect()
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404SignalConnect(
|
||||
unsigned la,
|
||||
void (*pSignalCallback)(int16_t signal)
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
return s;
|
||||
}
|
||||
|
||||
pc->pSignalCallback = pSignalCallback;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404Int()
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404Int(
|
||||
unsigned la
|
||||
)
|
||||
{
|
||||
hpE1404Stat s;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned short signal;
|
||||
struct hpE1404_config *pc;
|
||||
|
||||
s = hpE1404PConfig(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* vector is only D8 so we cant check the cause of the int
|
||||
* (signal cause is assumed since that was all that was enabled)
|
||||
*/
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
signal = pcsr->signal_read;
|
||||
|
||||
if(pc->pSignalCallback){
|
||||
(*pc->pSignalCallback)(signal);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404RouteTriggerECL
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerECL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
|
||||
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* hpE1404RouteTriggerTTL
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
)
|
||||
{
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
pcsr->fp_trig_drive = io_map&enable_map;
|
||||
pcsr->bp_trig_drive = (~io_map)&enable_map;
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpE1404IOReport()
|
||||
*
|
||||
*
|
||||
*/
|
||||
LOCAL
|
||||
void hpE1404IOReport(
|
||||
unsigned la,
|
||||
unsigned level
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* drvHp1404a.h
|
||||
*
|
||||
* HP E1404A VXI bus slot zero translator
|
||||
* device dependent routines header file
|
||||
*
|
||||
* share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93
|
||||
*
|
||||
* Author Jeffrey O. Hill
|
||||
* Date 030692
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef long hpE1404Stat;
|
||||
|
||||
hpE1404Stat hpE1404Init(void);
|
||||
|
||||
hpE1404Stat hpE1404SignalConnect(
|
||||
unsigned la,
|
||||
void (*pSignalCallback)(int16_t signal)
|
||||
);
|
||||
|
||||
hpE1404Stat hpE1404RouteTriggerECL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
);
|
||||
|
||||
hpE1404Stat hpE1404RouteTriggerTTL(
|
||||
unsigned la, /* slot zero device logical address */
|
||||
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 enables a trigger */
|
||||
/* a 0 disables a trigger */
|
||||
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
|
||||
/* a 1 sources the front panel */
|
||||
/* a 0 sources the back plane */
|
||||
);
|
||||
|
||||
#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10
|
||||
#define VXI_HP_MODEL_E1404_REG 0x110
|
||||
#define VXI_HP_MODEL_E1404_MSG 0x111
|
||||
|
||||
|
||||
@@ -0,0 +1,359 @@
|
||||
/* drvHpe1368a.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.c
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 071792 joh Added model name registration
|
||||
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
|
||||
* .03 082692 mrk Added support for new I/O event scanning and DRVET
|
||||
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <types.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <task_params.h>
|
||||
#include <fast_lock.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <devLib.h>
|
||||
|
||||
#include <drvHpe1368a.h>
|
||||
|
||||
|
||||
#define HPE1368A_PCONFIG(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
|
||||
|
||||
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
|
||||
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
|
||||
|
||||
#define ALL_SWITCHES_OPEN 0
|
||||
|
||||
struct hpe1368a_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
unsigned short pending; /* switch position pending int */
|
||||
unsigned short shadow; /* shadow of actual switch pos */
|
||||
int busy; /* relays active */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
#define HPE1368A_INT_LEVEL 1
|
||||
|
||||
LOCAL int hpe1368aDriverId;
|
||||
|
||||
LOCAL void hpe1368a_int_service(unsigned la);
|
||||
LOCAL void hpe1368a_init_card(unsigned la);
|
||||
LOCAL void hpe1368a_stat(unsigned la, int level);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvHpe1368a={
|
||||
2,
|
||||
NULL, /*VXI io report takes care of this */
|
||||
hpe1368a_init};
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_init
|
||||
*
|
||||
* initialize all hpe1368a cards
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_init(void)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
|
||||
/*
|
||||
* do nothing on crates without VXI
|
||||
*/
|
||||
if(!epvxiResourceMangerOK){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
hpe1368aDriverId = epvxiUniqueDriverID();
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_MODEL_HPE1368A;
|
||||
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_INIT_CARD
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_init_card(unsigned la)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
int model;
|
||||
|
||||
r0 = epvxiOpen(
|
||||
la,
|
||||
hpe1368aDriverId,
|
||||
(unsigned long) sizeof(*pc),
|
||||
hpe1368a_stat);
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
r0 = HPE1368A_PCONFIG(la, pc);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
/*
|
||||
* we must reset the device to a known state since
|
||||
* we cant read back the current state
|
||||
*/
|
||||
pc->pending = ALL_SWITCHES_OPEN;
|
||||
pc->shadow = ALL_SWITCHES_OPEN;
|
||||
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
|
||||
|
||||
FASTLOCKINIT(&pc->lock);
|
||||
scanIoInit(&pc->ioscanpvt);
|
||||
|
||||
r0 = intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpe1368a_int_service,
|
||||
la);
|
||||
if(r0 == ERROR){
|
||||
errMessage(S_dev_vxWorksVecInstlFail, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
sysIntEnable(HPE1368A_INT_LEVEL);
|
||||
|
||||
model = VXIMODEL(pcsr);
|
||||
r0 = epvxiRegisterModelName(
|
||||
VXIMAKE(pcsr),
|
||||
model,
|
||||
"E 1368A Microwave Switch\n");
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
}
|
||||
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpe1368a_int_service()
|
||||
*
|
||||
*
|
||||
* This device interrupts once the
|
||||
* switches have settled
|
||||
*
|
||||
*/
|
||||
LOCAL void
|
||||
hpe1368a_int_service(unsigned la)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la,pc);
|
||||
if(s){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* operation completed so we can update
|
||||
* the shadow value
|
||||
*/
|
||||
pc->shadow = pc->pending;
|
||||
pc->busy = FALSE;
|
||||
|
||||
/*
|
||||
* tell them that the switches have settled
|
||||
*/
|
||||
scanIoRequest(pc->ioscanpvt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_STAT
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s,NULL);
|
||||
return;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
if(level>0){
|
||||
printf("\tSwitch states %x\n", pc->shadow);
|
||||
printf("\tModule status %x\n", pcsr->dir.r.status);
|
||||
if(pc->busy){
|
||||
printf("\tModule is busy.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_getioscanpvt()
|
||||
*/
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
*scanpvt = pc->ioscanpvt;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_BO_DRIVER
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned int work;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
work = pc->pending;
|
||||
|
||||
/* alter specified bits */
|
||||
work = (work & ~mask) | (val & mask);
|
||||
|
||||
pc->pending = work;
|
||||
|
||||
ChannelEnable(pcsr) = work;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* HPE1368A_BI_DRIVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
*pval = pc->shadow & mask;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* drvHpe1368a.h*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.h
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
*/
|
||||
|
||||
#define VXI_MODEL_HPE1368A (0xf28)
|
||||
|
||||
typedef long hpe1368aStat;
|
||||
|
||||
hpe1368aStat hpe1368a_init(void);
|
||||
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
);
|
||||
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,290 @@
|
||||
/* drvStc.c */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* The following are specific driver routines for the AMD STC
|
||||
*
|
||||
* NOTE: if multiple threads use these routines at once you must provide locking
|
||||
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
|
||||
*
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
* joh 022089 Init Release
|
||||
* joh 042889 Added read back
|
||||
* joh 111789 Fixed reset goes to byte mode bug
|
||||
* joh 121090 Fixed confusion about the polarity of internal/external
|
||||
* clock between DB and the drivers.
|
||||
* joh 110791 Prevent the stc from generating tc prior to the trigger
|
||||
* in delayed pulse mode by forcing edge 0 delays of zero to be
|
||||
* a delay of one instead.
|
||||
* joh 010491 force all edge 0 delays less than two to two
|
||||
* joh 082493 ANSI C and EPICS return codes
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <module_types.h>
|
||||
#include <drvStc.h>
|
||||
#include <devLib.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_io_report()
|
||||
*/
|
||||
stcStat stc_io_report(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
/*
|
||||
* addd AMD STC status here
|
||||
*/
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_init()
|
||||
*/
|
||||
stcStat stc_init(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned master_mode
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
unsigned channel;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
/*
|
||||
* go to 16 bit mode in order to test the master mode register
|
||||
*/
|
||||
STC_BUS16;
|
||||
if(master_mode != STC_MASTER_MODE){
|
||||
|
||||
/*
|
||||
* start in a known state
|
||||
*/
|
||||
STC_RESET;
|
||||
|
||||
/*
|
||||
* required since the reset puts it in byte mode
|
||||
*/
|
||||
STC_BUS16;
|
||||
STC_SET_MASTER_MODE(master_mode);
|
||||
for(channel=0; channel<CHANONCHIP; channel++)
|
||||
STC_LOAD;
|
||||
}
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_one_shot_read()
|
||||
*/
|
||||
stcStat stc_one_shot_read(
|
||||
unsigned *preset,
|
||||
unsigned short *edge0_count,
|
||||
unsigned short *edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned *int_source
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
uint16_t mode;
|
||||
uint16_t edge0;
|
||||
uint16_t edge1;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
|
||||
if(channel>=CHANONCHIP)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
STC_CTR_READ(mode, edge0, edge1);
|
||||
|
||||
/*
|
||||
* Only return values if the counter is in the proper mode
|
||||
* see stc_one_shot() for info on conversions and functions selected
|
||||
* by these bit fields
|
||||
*/
|
||||
if(mode == 0xc16a){
|
||||
*int_source = FALSE;
|
||||
*preset = TRUE;
|
||||
*edge0_count = ~edge0;
|
||||
*edge1_count = ~edge1+1;
|
||||
}
|
||||
else if(mode == 0xc162){
|
||||
*int_source = FALSE;
|
||||
*preset = FALSE;
|
||||
*edge0_count = edge0-1;
|
||||
*edge1_count = edge1;
|
||||
}
|
||||
else if(mode == 0xcb6a){
|
||||
*int_source = TRUE;
|
||||
*preset = TRUE;
|
||||
*edge0_count = ~edge0;
|
||||
*edge1_count = ~edge1+1;
|
||||
}
|
||||
else if(mode == 0xcb62){
|
||||
*int_source = TRUE;
|
||||
*preset = FALSE;
|
||||
*edge0_count = edge0-1;
|
||||
*edge1_count = edge1;
|
||||
}
|
||||
else
|
||||
return S_dev_internal;
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* stc_one_shot()
|
||||
*/
|
||||
stcStat stc_one_shot(
|
||||
unsigned preset,
|
||||
unsigned edge0_count,
|
||||
unsigned edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned int_source
|
||||
)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint16_t data;
|
||||
|
||||
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
|
||||
return S_dev_noDevice;
|
||||
if(channel>=CHANONCHIP)
|
||||
return S_dev_badSignalNumber;
|
||||
|
||||
/*
|
||||
* joh 110791
|
||||
* Prevent the stc from generating tc prior to the trigger
|
||||
* in delayed pulse mode by forcing edge 0 delays of zero to be
|
||||
* a delay of one instead.
|
||||
*
|
||||
* 010492
|
||||
* Strange extra edges occur when the delay is 0 or 1
|
||||
* and the counter is reinitialized to a width of
|
||||
* zero so I have disabled a delay of one also
|
||||
*
|
||||
* These extra edges occur when TC is set
|
||||
*/
|
||||
|
||||
if(edge0_count < 2)
|
||||
edge0_count = 2;
|
||||
|
||||
STC_DISARM;
|
||||
|
||||
/*
|
||||
* active positive going edge (gate input)
|
||||
* count on the rising edge of source
|
||||
* ctr source: (F1- internal) (SRC1- external)
|
||||
* mode L - Hardware triggered delayed pulse one-shot
|
||||
* binary count
|
||||
* count down (count up if preset is TRUE)
|
||||
* TC toggled output
|
||||
*
|
||||
* see chapter 7 of the Am9513 STC tech man concerning count + 1
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE: I must be able to read back the state of the preset later
|
||||
* so I encode this information in the count down/up bit.
|
||||
* count up on TRUE preset
|
||||
* count down on FALSE preset
|
||||
*
|
||||
* see stc_one_shot_read() above
|
||||
*/
|
||||
if(int_source){
|
||||
if(preset)
|
||||
STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1)
|
||||
else
|
||||
STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count);
|
||||
}else{
|
||||
if(preset)
|
||||
STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1)
|
||||
else
|
||||
STC_CTR_INIT(0xc162, edge0_count+1, edge1_count);
|
||||
}
|
||||
|
||||
STC_LOAD;
|
||||
/*
|
||||
*see chapter 7 of the Am9513 STC tech man concerning this step
|
||||
*/
|
||||
|
||||
STC_STEP;
|
||||
|
||||
STC_SET_TC(preset);
|
||||
|
||||
/*
|
||||
* Only arm counter if the pulse has a finite duration
|
||||
*/
|
||||
if(edge1_count != 0){
|
||||
STC_ARM;
|
||||
}
|
||||
|
||||
return STC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/* drvStc.h */
|
||||
/* base/src/drv $Id$ */
|
||||
/*
|
||||
* The following are specific driver routines for the AMD STC
|
||||
*
|
||||
* NOTE: if multiple threads use these routines at once you must provide locking
|
||||
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
|
||||
*
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: Feb 89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
* joh 022089 Init Release
|
||||
* joh 082493 ANSI C and EPICS return codes
|
||||
*/
|
||||
|
||||
/*
|
||||
* AMD STC constants
|
||||
*/
|
||||
#define CHANONCHIP 5U
|
||||
#define CHIPCHAN (channel%CHANONCHIP)
|
||||
#define CHIPNUM (channel/CHANONCHIP)
|
||||
|
||||
#define STC_RESET *pcmd = 0xffU
|
||||
#define STC_BUS16 *pcmd = 0xefU
|
||||
#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);}
|
||||
#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata)
|
||||
|
||||
#define STC_CTR_INIT(MODE,LOAD,HOLD)\
|
||||
{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);}
|
||||
|
||||
#define STC_CTR_READ(MODE,LOAD,HOLD)\
|
||||
{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;}
|
||||
|
||||
#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U)
|
||||
|
||||
#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN)
|
||||
#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U)
|
||||
#define STC_ARM *pcmd = 0x20U | 1<<CHIPCHAN
|
||||
#define STC_DISARM *pcmd = 0xc0U | 1<<CHIPCHAN
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* return type of the stc routines
|
||||
*/
|
||||
typedef long stcStat;
|
||||
#define STC_SUCCESS 0
|
||||
|
||||
|
||||
stcStat stc_io_report(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata
|
||||
);
|
||||
|
||||
|
||||
stcStat stc_init(
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned master_mode
|
||||
);
|
||||
|
||||
stcStat stc_one_shot_read(
|
||||
unsigned *preset,
|
||||
uint16_t *edge0_count,
|
||||
uint16_t *edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned *int_source
|
||||
);
|
||||
|
||||
stcStat stc_one_shot(
|
||||
unsigned preset,
|
||||
unsigned edge0_count,
|
||||
unsigned edge1_count,
|
||||
volatile uint8_t *pcmd,
|
||||
volatile uint16_t *pdata,
|
||||
unsigned channel,
|
||||
unsigned int_source
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user