moved ansi drivers

This commit is contained in:
Jeff Hill
1995-04-26 03:20:39 +00:00
parent 9b76f9d9c0
commit b3af9b389a
28 changed files with 16460 additions and 22 deletions
+30
View File
@@ -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
+94
View File
@@ -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
);
+808
View File
@@ -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
+408
View File
@@ -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
)
{
}
+74
View File
@@ -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
+359
View File
@@ -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;
}
+60
View File
@@ -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
+484
View File
@@ -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;
}
+56
View File
@@ -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
);
+627
View File
@@ -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;
}
+74
View File
@@ -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
);
+290
View File
@@ -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;
}
+107
View File
@@ -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
);
+250
View File
@@ -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;
}
-22
View File
@@ -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
+94
View File
@@ -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
);
+408
View File
@@ -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
)
{
}
+74
View File
@@ -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
+359
View File
@@ -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;
}
+60
View File
@@ -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
+290
View File
@@ -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;
}
+107
View File
@@ -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
);