unbundled or moved to /home/phoebus/MRK/epics/base/src/vxWorks/drv/ansi

This commit is contained in:
Marty Kraimer
1999-09-13 18:51:50 +00:00
parent 9a1a37fce2
commit 3c2e5070ef
36 changed files with 0 additions and 19822 deletions

View File

@@ -1,7 +0,0 @@
TOP=../../..
include $(TOP)/config/CONFIG_BASE
include $(TOP)/config/RULES_ARCHS

View File

@@ -1,48 +0,0 @@
#
# $Id$
#
TOP = ../../../..
include $(TOP)/config/CONFIG_BASE
INC += canBus.h
INC += drvAb.h
INC += drvAt5Vxi.h
INC += drvEpvxi.h
INC += drvHp1404a.h
INC += drvHpe1368a.h
INC += drvIpac.h
INC += drvKscV215.h
INC += drvMz8310.h
INC += drvStc.h
INC += drvTip810.h
INC += epvxi.h
INC += ipModules.h
INC += ipic.h
INC += pca82c200.h
SRCS.c += ../drvAb.c
SRCS.c += ../drvAt5Vxi.c
SRCS.c += ../drvEpvxi.c
SRCS.c += ../drvEpvxiMsg.c
SRCS.c += ../drvHp1404a.c
SRCS.c += ../drvHpe1368a.c
SRCS.c += ../drvHpe1445a.c
SRCS.c += ../drvKscV215.c
SRCS.c += ../drvMz8310.c
SRCS.c += ../drvStc.c
#SRCS.c += ../drvCaenV265.c
SRCS.c += ../drvVipc310.c
SRCS.c += ../drvVipc610.c
SRCS.c += ../drvIpMv162.c
SRCS.c += ../drvIpac.c
SRCS.c += ../drvTip810.c
#SRCS.c += ../drvVmic2534.c
PROD = $(SRCS.c:../%.c=%.o)
MAN3 = drvEpvxi.3
include $(TOP)/config/RULES.Vx

View File

@@ -1,30 +0,0 @@
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 something 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.

View File

@@ -1,73 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
canBus.h
Description:
CANBUS specific constants
Author:
Andrew Johnson
Created:
25 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef INCcanBusH
#define INCcanBusH
#define CAN_IDENTIFIERS 2048
#define CAN_DATA_SIZE 8
#define CAN_BUS_OK 0
#define CAN_BUS_ERROR 1
#define CAN_BUS_OFF 2
#ifndef M_can
#define M_can (811<<16)
#endif
#define S_can_badMessage (M_can| 1) /*illegal CAN message contents*/
#define S_can_badAddress (M_can| 2) /*CAN address syntax error*/
#define S_can_noDevice (M_can| 3) /*CAN bus name does not exist*/
typedef struct {
ushort_t identifier; /* 0 .. 2047 with holes! */
enum {
SEND = 0, RTR = 1
} rtr; /* Remote Transmission Request */
uchar_t length; /* 0 .. 8 */
uchar_t data[CAN_DATA_SIZE];
} canMessage_t;
typedef struct {
char *busName;
int timeout;
ushort_t identifier;
ushort_t offset;
signed int parameter;
void *canBusID;
} canIo_t;
typedef void canMsgCallback_t(void *pprivate, canMessage_t *pmessage);
typedef void canSigCallback_t(void *pprivate, int status);
extern int canOpen(char *busName, void **pcanBusID);
extern int canRead(void *canBusID, canMessage_t *pmessage, int timeout);
extern int canWrite(void *canBusID, canMessage_t *pmessage, int timeout);
extern int canMessage(void *canBusID, ushort_t identifier,
canMsgCallback_t callback, void *pprivate);
extern int canSignal(void *canBusID, canSigCallback_t callback, void *pprivate);
extern int canIoParse(char *canString, canIo_t *pcanIo);
#endif /* INCcanBusH */

File diff suppressed because it is too large Load Diff

View File

@@ -1,93 +0,0 @@
/* drvAb.h */
/* header file for the Allen-Bradley Remote Serial IO
* This defines interface between driver and device support
*
* Author: Marty Kraimer
* Date: 03-06-95
*
* 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 03-06-95 mrk Moved all driver specific code to drvAb.c
*/
#ifndef INCdrvAbh
#define INCdrvAbh 1
#include "dbScan.h"
/* interface types */
typedef enum {typeNotAssigned,typeBi,typeBo,typeBiBo,typeAi,typeAo,typeBt}
cardType;
/* status values*/
typedef enum{abSuccess,abNewCard,abCardConflict,abNoCard,abNotInitialized,
abBtqueued,abBusy,abTimeout,abAdapterDown,abFailure} abStatus;
extern char **abStatusMessage;
typedef enum{abBitNotdefined,abBit8,abBit16,abBit32} abNumBits;
extern char **abNumBitsMessage;
/*entry table for dev to drv routines*/
typedef struct {
abStatus (*registerCard)
(unsigned short link,unsigned short adapter, unsigned short card,
cardType type, const char *card_name,
void (*callback)(void *drvPvt),
void **drvPvt);
void (*getLocation)
(void *drvPvt,
unsigned short *link, unsigned short *adapter,unsigned short *card);
abStatus (*setNbits)(void *drvPvt, abNumBits nbits);
void (*setUserPvt)(void *drvPvt, void *userPvt);
void *(*getUserPvt)(void *drvPvt);
abStatus (*getStatus)(void *drvPvt);
abStatus(*startScan)
(void *drvPvt, unsigned short update_rate,
unsigned short *pwrite_msg, unsigned short write_msg_len,
unsigned short *pread_msg, unsigned short read_msg_len);
abStatus(*updateAo)(void *drvPvt);
abStatus(*updateBo) (void *drvPvt,unsigned long value,unsigned long mask);
abStatus(*readBo) (void *drvPvt,unsigned long *value,unsigned long mask);
abStatus(*readBi) (void *drvPvt,unsigned long *value,unsigned long mask);
abStatus(*btRead)(void *drvPvt,unsigned short *pread_msg,
unsigned short read_msg_len);
abStatus(*btWrite)(void *drvPvt,unsigned short *pwrite_msg,
unsigned short write_msg_len);
abStatus (*adapterStatus)
(unsigned short link,unsigned short adapter);
abStatus (*cardStatus)
(unsigned short link,unsigned short adapter, unsigned short card);
}abDrv;
extern abDrv *pabDrv;
int ab_reset(void);
int ab_reset_link(int link);
int abConfigNlinks(int nlinks);
int abConfigVme(int link, int base, int vector, int level);
int abConfigBaud(int link, int baud);
int abConfigScanList(int link, int scan_list_len, char *scan_list);
int abConfigScanListAscii(int link, char *filename,int setRackSize);
int abConfigAuto(int link);
#endif /*INCdrvAbh*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,94 +0,0 @@
/* 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
);

View File

@@ -1,808 +0,0 @@
/* 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;
}

View File

@@ -1,766 +0,0 @@
.TH epvxiMsgLib 1 "" "EPICS Reference Manual"
.ad b
.SH VERSION @(#)drvEpvxi.nr 1.9 8/13/93
.SH NAME
epvxiMsgLib.c - the VXI message based device interface library
.SH SYNOPSIS
.nf
epvxiCmd - deliver a command to a message based device
epvxiQuery - fetch a response from a message based device
epvxiCmdQuery - send a command and fetch a response
epvxiRead - read a string of bytes from a device
epvxiWrite - write a string of bytes to a device
epvxiSetTimeout - change the message based transfer timeout
epvxiSetTraceEnable - turn trace mode on or off
int epvxiCmd (la, command)
int epvxiQuery (la, presponse)
int epvxiCmdQuery (la, command, presponse)
int epvxiRead (la, pbuffer, count, pactual_count, option)
int epvxiWrite (la, pbuffer, pcount, pactual_count, option)
int epvxiSetTimeout (la, timeout)
int epvxiSetTraceEnable(la, enable)
.fi
.SH DESCRIPTION
This library provides a vendor independent interface to VXI message
based devices. Device drivers which use this library may optionally
open devices accessed by this library using epvxiOpen() prior to use.
Opening a device prevents other drivers from using it.
.SH RETURNS
.nf
less than zero- operation failed
greater than zero- operation successful
#define VXI_SUCCESS 0 /* successful completion */
#define VXI_NO_DEVICE (-1) /* device does not exist */
#define VXI_NOT_SLOT0 (-2) /* not a slot zero device */
#define VXI_UKN_DEVICE (-3) /* device not supported */
#define VXI_BAD_TRIGGER (-4) /* no such trigger */
#define VXI_BAD_TRIG_IO (-5) /* no such trigger io */
#define VXI_DEVICE_OPEN (-6) /* device already open */
#define VXI_NOT_OWNER (-7) /* dev in use by another drv */
#define VXI_NO_MEMORY (-8) /* failed to allocate memory */
#define VXI_NOT_OPEN (-9) /* device not open */
#define VXI_NOT_MSG_DEVICE (-10) /* must be a message based dev */
#define VXI_MSG_DEVICE_TMO (-11) /* message based dev timed out */
#define VXI_MSG_DEVICE_FAILURE (-12) /* message based dev failed */
#define VXI_BAD_LA (-13) /* logical addr out of range */
#define VXI_MULTIPLE_QUERIES (-14) /* serial protocol error */
#define VXI_UNSUPPORTED_CMD (-15) /* serial protocol error */
#define VXI_DIR_VIOLATION (-16) /* serial protocol error */
#define VXI_DOR_VIOLATION (-17) /* serial protocol error */
#define VXI_RR_VIOLATION (-18) /* serial protocol error */
#define VXI_WR_VIOLATION (-19) /* serial protocol error */
#define VXI_ERR_FETCH_FAIL (-20) /* ukn serial protocol error */
#define VXI_SELF_TEST_FAILED (-21) /* self test failed */
.SH INCLUDES
epvxiLib.h
.fi
.TH epvxiCmd 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiCmd - deliver a command to a message based device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiCmd (la, command)
unsigned la; /* logical address */
unsigned long command; /* command */
.fi
.CE
.SH DESCRIPTION
Delivers a command to a message based device.
.SH RETURNS
See epvxiMsgLib(1) for a description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiQuery 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiQuery - fetch a response from a message based device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiQuery (la, presponse)
unsigned la; /* logical address */
unsigned long *presponse; /* response pointer */
.fi
.CE
.SH DESCRIPTION
Fetch a response from a message based device.
.SH RETURNS
See epvxiMsgLib(1) for a description of the returns from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiCmdQuery 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiCmdQuery - send a command and fetch a response from a message based device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiCmdQuery (la, command, presponse)
unsigned la; /* logical address */
unsigned long command; /* command */
unsigned long *presponse; /* response pointer */
.fi
.CE
.SH DESCRIPTION
Send a command and fetch a response from a message based device.
.SH RETURNS
See epvxiMsgLib(1) for a description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiRead 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiRead - read a string of bytes from a device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiRead (
unsigned la, /* logical address */
char *pbuffer, /* pointer to supplied buffer */
unsigned long count, /* number of bytes to read */
unsigned long *pactual_count, /* number of bytes read */
unsigned long option /* read options */
)
.fi
.CE
.SH DESCRIPTION
Read a string of bytes from a message based device using the
byte transfer protocol. Copy bytes into the supplied buffer
until the end of string terminator is received from the device
or the end of the buffer is reached as determined by the supplied
count. Returns the number of bytes read in *pactual_count.
The options argument is a mask with each bit potentially
representing a different option. If you need to specify more
than one option then you must bit or together the option
constants which apply. Currently, no read options are supported.
The option argument should be set to epvxiReadOptNone.
.nf
Option Bit Mask Purpose
--------------- -------
epvxiReadOptNon no options
.fi
.SH RETURNS
See epvxiMsgLib(1) for a description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiWrite 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiWrite - write a string of bytes to a device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiWrite (
unsigned la, /* logical address */
char *pbuffer, /* pointer to supplied buffer */
unsigned long count, /* number of bytes to write */
unsigned long *pactual_count, /* number of bytes written */
unsigned long option /* write options */
)
.fi
.CE
.SH DESCRIPTION
Write a string of bytes to a message based device using the
byte transfer protocol. Copy count bytes from the supplied buffer
to the device. Returns the number of bytes written in *pactual_count.
The options argument is a mask with each bit potentially
representing a different option. If you need to specify more
than one option then you must bit or together the option
constants which apply. Or in the constant epvxiWriteOptPartialMsg
if the string sent is part of a larger message and it is
not the last segment of the larger message.
.nf
Option Bit Mask Purpose
--------------- -------
epvxiWriteOptNone no options
epvxiWriteOptPartialMsg message continues after this transfer
.fi
.SH RETURNS
See epvxiMsgLib(1) for an description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiSetTimeout 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiSetTimeout - change the message based transfer timeout
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiSetTimeout (la, timeout)
unsigned la; /* logical address */
unsigned long timeout; /* milli-seconds prior to timeout */
.fi
.CE
.SH DESCRIPTION
Set the delay prior to timeout for each portion of a message based
VXI transfer. The default timeout is 10 seconds.
.SH RETURNS
See epvxiMsgLib(1) for a description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiSetTraceEnable 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiSetTraceEnable - set trace mode on or off
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiSetTraceEnable(la, enable)
unsigned la; /* logical address */
int enable; /* T=trace on, F=trace off */
.fi
.CE
.SH DESCRIPTION
Set trace mode on or off. If "enable" is true then trace mode is enabled.
If "enable" is false then trace mode is turned off. Trace mode is enable
for each VXI message based device independently.
.SH RETURNS
See epvxiMsgLib(1) for a description of the return codes from this library.
.SH SEE ALSO
epvxiMsgLib(1), epvxiLib(1)
.TH epvxiLib 1 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiLib.c - the VXI driver support library
.SH SYNOPSIS
.nf
epvxiLookupLA - find all devices matching a pattern
epvxiUniqueDriverID - return a non zero unique identification for a VXI driver
epvxiOpen - open a VXI device
epvxiClose - close a VXI device
epvxiPConfig - MACRO which returns a pointer to the drivers private structure
epvxiFetchPConfig - similar to epvxiPConfig but with status
epvxiRouteTriggerECL - route an ECL trigger to/from the front panel
epvxiRouteTriggerTTL - route an TTL trigger to/from the front panel
epvxiResman - perform VXI resource management and setup the MXI bus
epvxiDeviceList - list which drivers own which devices
epvxiCrateList - list all slot zero devices
epvxiExtenderList - list all extender devices and there windows
epvxiIOReport - list all VXI hardware in the system
int epvxiLookupLA(pmatch_structure, pcallback, pargument)
int epvxiUniqueDriverID()
int epvxiOpen(la, driverID, structure_size, pioReportFunction)
int epvxiClose(la, driverID)
(<structure declaration> *) epvxiPConfig(la, driverID, <structure declaration>)
int epvxiFetchPConfig(la, driverID, pConfig)
int epvxiRouteTriggerECL (la, trigger, io)
int epvxiRouteTriggerTTL(la, trigger, io)
int epvxiResman()
int epvxiDeviceList()
int epvxiCrateList()
int epvxiExtenderList()
int epvxiIOReport(level)
.fi
This is the structure used to specify search patterns for epvxiLookupLA().
Set a bit in the flags member for each item that is to be a
constraint on the search. All other items are ignored during
the search. The call back routine will be called for all devices
which exactly match all items specified in the flags field
.nf
#define VXI_DSP_make (1<<0)
#define VXI_DSP_model (1<<1)
#define VXI_DSP_class (1<<2)
#define VXI_DSP_slot (1<<3)
#define VXI_DSP_slot_zero_la (1<<4)
#define VXI_DSP_commander_la (1<<5)
#define VXI_DSP_extender_la (1<<6) /* id crates that have one */
typedef struct {
long flags; /* one bit enabling each field */
unsigned short make; /* manufacture identification */
unsigned short model; /* model code for the device */
unsigned short class; /* VXI device class */
unsigned char slot; /* slot where the device resides */
unsigned char slot_zero_la; /* logical address of slot 0 device */
unsigned char commander_la /* logical address of commander */
unsigned char extender_la /* logical address of bus repeater */
}epvxiDeviceSearchPattern;
.fi
.SH DESCRIPTION
.nf
Low level support needed if you are writing a VXI driver:
* Determine the logical address of all devices in a particular slot
* Determine the logical address of all devices of a particular make or model
* Prevent two drivers from accessing the same card
* Prevent a driver from accessing a nonexistent card
* Return a pointer to the driver's private variables given a logical address
* Device independent front panel trigger routing on the slot zero device
.fi
The message based device interface library epvxiMsgLib(1) is
an example of a VXI driver which utilizes this core VXI driver support.
.SH INCLUDES
epvxiLib.h
.SH RETURNS
.nf
less than zero- operation failed
greater than zero- operation successful
#define VXI_SUCCESS 0 /* successful completion */
#define VXI_NO_DEVICE (-1) /* device does not exist */
#define VXI_NOT_SLOT0 (-2) /* not a slot zero device */
#define VXI_UKN_DEVICE (-3) /* device not supported */
#define VXI_BAD_TRIGGER (-4) /* no such trigger */
#define VXI_BAD_TRIG_IO (-5) /* no such trigger io */
#define VXI_DEVICE_OPEN (-6) /* device already open */
#define VXI_NOT_OWNER (-7) /* dev in use by another drv */
#define VXI_NO_MEMORY (-8) /* failed to allocate memory */
#define VXI_NOT_OPEN (-9) /* device not open */
#define VXI_NOT_MSG_DEVICE (-10) /* must be a message based dev */
#define VXI_MSG_DEVICE_TMO (-11) /* message based dev timed out */
#define VXI_MSG_DEVICE_FAILURE (-12) /* message based dev failed */
#define VXI_BAD_LA (-13) /* logical addr out of range */
#define VXI_MULTIPLE_QUERIES (-14) /* serial protocol error */
#define VXI_UNSUPPORTED_CMD (-15) /* serial protocol error */
#define VXI_DIR_VIOLATION (-16) /* serial protocol error */
#define VXI_DOR_VIOLATION (-17) /* serial protocol error */
#define VXI_RR_VIOLATION (-18) /* serial protocol error */
#define VXI_WR_VIOLATION (-19) /* serial protocol error */
#define VXI_ERR_FETCH_FAIL (-20) /* ukn serial protocol error */
#define VXI_SELF_TEST_FAILED (-21) /* self test failed */
#define VXI_TIMEOUT_TO_LARGE (-22) /* supplied timeout to long */
#define VXI_PROTOCOL_ERROR (-23) /* protocol error */
.fi
.SH SEE ALSO
epvxiMsgLib(1)
.TH epvxiLookupLA 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiLookupLA - find all of the devices matching a search pattern
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiLookupLA(pmatch_structure, pcallback, pargument)
epvxiDeviceSearchPattern *pmatch_structure;
void (*pcallback)();
void *pargument;
/*
* your call back
*/
void callback(la, pargument)
unsigned la;
void *pargument;
{
}
.fi
.CE
.SH DESCRIPTION
Find all devices in the system matching the search pattern and call
the specified call back for each of them. The search pattern is specified
by filling fields in the structure epvxiDeviceSearchPattern and
setting the flags field of the same structure to match. For example:
.nf
epvxiDeviceSearchPattern dsp;
dsp.make = VXI_MAKE_HP;
dsp.model = 0xffc;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
epvxiLookupLA(&dsp, pcallback, pargument);
.fi
A list of these constants can be found in epvxiLib.h and
device make codes can be found in epvxi.h
This is the structure used to specify search patterns for epvxiLookupLA().
Set a bit in the flags member for each item that is to be a
constraint on the search. All other items are ignored during
the search. The call back routine will be called for all devices
which exactly match all items specified in the flags field
.nf
#define VXI_DSP_make (1<<0)
#define VXI_DSP_model (1<<1)
#define VXI_DSP_class (1<<2)
#define VXI_DSP_slot (1<<3)
#define VXI_DSP_slot_zero_la (1<<4)
#define VXI_DSP_commander_la (1<<5)
typedef struct {
long flags; /* one bit enabling each field */
unsigned short make; /* manufacture identification */
unsigned short model; /* model code for the device */
unsigned short class; /* VXI device class */
unsigned char slot; /* slot where the device resides */
unsigned char slot_zero_la; /* logical address of slot 0 device */
unsigned char commander_la /* logical address of commander */
}epvxiDeviceSearchPattern;
.fi
.SH RETURNS
Returns a non zero unique constant to be used as a driver identification.
.SH SEE ALSO
epvxiLib(1),
.TH epvxiUniqueDriverID 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiUniqueDriverID - return a non zero unique identification for a VXI driver
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiUniqueDriverID ()
.fi
.CE
.SH DESCRIPTION
Should be called once only
by each type of VXI driver to uniquely identify itself. The routines
in epvxiDrvLib.c use this constant to prevent a VXI device from being
accessed by the wrong driver.
.SH RETURNS
.SH SEE ALSO
epvxiLib(1),
.TH epvxiOpen 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiOpen - open a VXI device for a VXI driver
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiOpen (la, epvxiDriverID, structureSize, pio_report_func)
unsigned la;
int epvxiDriverID;
unsigned long structureSize;
void (*pio_report_func)();
void pio_report_func(la, level)
unsigned la;
int level;
{
}
.fi
.CE
.SH DESCRIPTION
Records this driver as the owner of the device at the specified logical
address la and verifies that the device has passed it's self test.
Allocates memory of size structureSize and saves a
pointer to this memory with the logical address for future use by the
driver with identification epvxiDriverID for its private configuration.
Installs call back routine pio_report_func as an io report function to
be called each time the user requests the status
of VXI devices. This routine is called with the logical address
and an integer specifying the detail level of the report
as the first and second arguments respectively.
The macro epvxiFetchPConfig returns a pointer to this block if the
specified device has been opened by the specified driver.
.SH RETURNS
.SH SEE ALSO
epvxiUniqueDriverID()
epvxiFetchPConfig()
epvxiLib(1),
.TH epvxiClose 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiClose - close a VXI device for a VXI driver
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiClose (la, vxiDriverID)
unsigned la;
int vxiDriverID;
.fi
.CE
.SH DESCRIPTION
Releases driver ownership of the device at the specified logical
address la. Deallocates memory in use for the driver's private
configuration.
.SH RETURNS
.SH SEE ALSO
epvxiLib(1),
.TH epvxiFetchPConfig 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiFetchPConfig - macro which loads a pointer to the drivers private structure
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int evxiFetchPConfig (la, vxiDriverID, pConfig)
unsigned la;
int vxiDriverID;
stuct XXXXXX *pConfig;
.fi
.CE
.SH DESCRIPTION
epvxiFetchPConfig() is a MACRO which loads a pointer to the devices
private configuration block (ie pConfig above). This macro
replaces the macro epvxiPConfig() which didnt return status.
This routine performs two functions:
.nf
1) Loads a pointer to the device's configuration block.
2) Informs your driver if the specified device does not exist or has
been opened by another driver.
.fi
.SH RETURNS
.SH SEE ALSO
epvxiLib(1),
.TH epvxiRouteTriggerECL 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiRouteTriggerECL - route an ECL trigger to/from the front panel
of a supported VXI device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiRouteTriggerECL (la, trigger, io)
unsigned la; /* 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 */
.fi
.CE
.SH DESCRIPTION
Route a VXI backplane trigger to or from the front panel of a slot zero
device.
The bits in argument enable_map correspond to an enable for triggers
0-5 (1 enables the trigger and 0 disables the trigger). The bits
in argument io_map set the direction for triggers 0-5 (1 sources
the front panel and 0 sources the backplane).
Most VXI slot zero devices have one trigger output and one trigger input
connector. The trigger input connector can drive multiple VXI backplane
triggers. The trigger output connector should be driven by only one of
the backplane triggers at a time.
.SH RETURNS
.SH SEE ALSO
epvxiLib(1),
.TH epvxiRouteTriggerTTL 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiRouteTriggerTTL - route an TTL trigger to/from the front panel
of a supported VXI device
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiRouteTriggerTTL (la, trigger, io)
unsigned la; /* 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 */
.fi
.CE
.SH DESCRIPTION
Route a VXI backplane trigger to or from the front panel of a slot zero
device.
The bits in argument enable_map correspond to an enable for triggers
0-5 (1 enables the trigger and 0 disables the trigger). The bits
in argument io_map set the direction for triggers 0-5 (1 sources
the front panel and 0 sources the backplane).
Most VXI slot zero devices have one trigger output and one trigger input
connector. The trigger input connector can drive multiple VXI backplane
triggers. The trigger output connector should be driven by only one of
the backplane triggers at a time.
.SH RETURNS
.SH SEE ALSO
epvxiLib(1),
.TH epvxiResman 2 "" "EPICS Reference Manual"
.ad b
.SH NAME
epvxiResman - perform VXI resource management and MXI bus setup
.SH SYNOPSIS
.CS
.nf
#include <epvxiLib.h>
int epvxiResman ()
.fi
.CE
.nf
MXI bus background information
o A MXI bus extender facilitates bus communication between
a VME bus master and a VME bus slave that are installed
in different crates. MXI bus extenders can be joined
together in a hierarchy interconnected by the MXI bus.
o A MXI bus extender's LA window determines the VXI LA range
over which local VME bus master initiated requests are
extended onto the MXI bus.
o A MXI bus extender's LA window also determines the MXI
LA range over which MXI extended bus master requests
are allowed to be further extended into the local VXI bus.
o MXI bus extenders are always SC devices. A MXI bus
extenders are always accessible from the MXI bus
invariant of the location of its LA window.
Conclusion: the LA of a MXI does not constrain the
location of its LA window.
o Each MXI's LA window must be large enough to contain all
of the MXI bus extender LA windows beneath it in the
hierarchy. A MXI's LA window may not overlap the windows of
any other MXI'at the same level in the hierarchy.
o SC devices within one crate must be within a block
which does not overlap the LA windows of other
MXI bus extenders at the same level in the
hierarchy. Likewise SC devices within one crate
must not overlap the LA windows of MXI bus
extenders at a lower level in the hierarchy.
EPICS VXI resource manager background information
o The EPICS VXI resource manager will always successfully
allocate all DC devices in a DC MXI bus system if
the available LA address range is large enough and
if all devices other than the resource manager and
the MXIs are DC.
o Otherwise if some of the devices in the system
(other than the MXIs and the resource manager) are
SC then the burden is placed on the project
engineer to guarantee that SC devices are located
such that nonoverlapping MXI LA windows can
be allocated by the resource manager. Additionally
the project engineer must locate the SC devices
so that there is sufficient space to allocate the LAs
of DC devices into nonoverlapping MXI LA windows.
If the project engineer locates SC devices
correctly the resource manager will always find the
corresponding window hierarchy that provides
access to all devices. If the project engineer
improperly locates SC devices the resource manager
will detect it and print a message.
o The CPU running the EPICS VXI resource manager is at the
root of the MXI hierarchy.
o The resource manager will never allocate a DC device
at a LA overlapping an interrupt vector already
allocated to another device (use "veclist()" to
determine what vectors are in use).
Resource manager DC device allocation rules
o When DC devices are allocated they will be placed between
existing SC devices (in the same extender) first.
Next they will be placed after existing DC devices
(in the same extender). If there isn't room above existing
DC devices then the resource manager will attempt to
allocate DC device beneath the existing SC devices.
If devices in other extenders (the limits of other windows)
bracket the upper and lower limits of an extender's
window there may not be enough space to allocate
all of the DC devices present in a crate.
If so, a warning message will be printed and the DC
device will not be allocated a valid LA.
o If the only SC device in a crate is the MXI granting access
to the crate then the resource manager will be free to place
any DC devices found in a contiguous block where there is room.
The resource manager requires block allocation because the MXI
address window must contain only the DC device LA assignments
for the current crate. This contiguous block will be placed
at the highest open LA block available. If a contiguous block
of sufficient size is not found then none of the DC devices will
be allocated (assigned) valid LAs and a warning message
will be printed. This block will not be anchored in any way
to the SC LA of the extender that provides access to the
DC devices in the crate.
.fi

File diff suppressed because it is too large Load Diff

View File

@@ -1,473 +0,0 @@
/* drvEpvxi.h */
/* $Id$ */
/*
* parameter file supporting the VXI library
*
* Author: Jeff Hill
* Date: 8-91
*
* 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 070792 joh Added MACROS to return the A24 and A32 base addr
* .02 072992 joh Added sccs id
* .03 081992 joh ANSI C func proto
* .04 082592 joh added arg to epvxiRead() and epvxiWrite()
* .05 090392 joh Now runtime links to NI trigger routing
* .06 092392 joh New status from epvxiRead() - VXI_BUFFER_FULL
* .07 033193 joh error codes converted to EPICS standard format
* .08 071293 joh record task id when opening a device
* .09 082793 joh -Wall cleanup and added drvEpvxiFetchPConfig()
*
*
*/
#ifndef INCepvxiLibh
#define INCepvxiLibh
static char *epvxiLibhSccId = "$Id$";
#include <ellLib.h>
#include <epvxi.h>
#include <errMdef.h>
/*
* Structure used to specify search patterns for epvxiLookupLA()
*
* Set a bit in the flags member for each item that is to be a
* constraint on the search. All other items are ignored during
* the search. The callback routine will be called for all devices
* which exactly match all items specified in the flags field
*/
#define VXI_DSP_make (1<<0)
#define VXI_DSP_model (1<<1)
#define VXI_DSP_class (1<<2)
#define VXI_DSP_slot (1<<3)
#define VXI_DSP_slot_zero_la (1<<4)
#define VXI_DSP_commander_la (1<<5)
#define VXI_DSP_extender_la (1<<6) /* id crates that have one */
typedef struct {
long flags; /* one bit enabling each field */
unsigned short make; /* manufacture identification */
unsigned short model; /* model code for the device */
unsigned short class; /* vxi device class */
unsigned char slot; /* slot where the device resides */
unsigned char slot_zero_la; /* logical address of slot 0 dev */
unsigned char commander_la; /* logical address of commander */
unsigned char extender_la; /* logical address of bus repeater */
}epvxiDeviceSearchPattern;
typedef long EPVXISTAT;
/*
* functions from epvxiLib.c
*/
EPVXISTAT epvxiResman(
void
);
EPVXISTAT epvxiIOReport(
unsigned level
);
EPVXISTAT epvxiDeviceList(
void
);
EPVXISTAT epvxiCrateList(
void
);
EPVXISTAT epvxiExtenderList(
void
);
EPVXISTAT epvxiUniqueDriverID(
void
);
EPVXISTAT epvxiDeviceVerify(
unsigned la
);
EPVXISTAT epvxiOpen(
unsigned la,
int vxiDriverID,
unsigned long driverConfigSize,
void (*pio_report_func)()
);
EPVXISTAT epvxiClose(
unsigned la,
int vxiDriverID
);
EPVXISTAT epvxiLookupLA(
epvxiDeviceSearchPattern
*pdsp,
void (*pfunc)(unsigned, void *),
void *parg
);
EPVXISTAT epvxiRouteTriggerECL(
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 */
);
EPVXISTAT epvxiRouteTriggerTTL(
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 */
);
EPVXISTAT epvxiRegisterModelName(
unsigned int make,
unsigned int model,
char *pmodel_name
);
EPVXISTAT epvxiRegisterMakeName(
unsigned int make,
char *pmake_name
);
EPVXISTAT epuxiLookupModelName(
unsigned int make, /* VXI manuf. */
unsigned int model, /* VXI model code */
char *pbuffer, /* model name return */
unsigned int bufsize, /* size of supplied buf */
unsigned int *preadcount /* n bytes written */
);
EPVXISTAT epuxiLookupMakeName(
unsigned int make, /* VXI manuf. */
char *pbuffer, /* model name return */
unsigned int bufsize, /* size of supplied buf */
unsigned int *preadcount /* n bytes written */
);
EPVXISTAT vxi_init( /* compatibility */
void
);
EPVXISTAT vxi_io_report( /* compatibility */
unsigned level
);
/*
* functions from epvxiMsgLib.c
*/
EPVXISTAT epvxiCmd(
unsigned la,
unsigned long cmd
);
EPVXISTAT epvxiQuery(
unsigned la,
unsigned long *presp
);
EPVXISTAT epvxiCmdQuery(
unsigned la,
unsigned long cmd,
unsigned long *presp
);
EPVXISTAT epvxiRead(
unsigned la,
char *pbuf,
unsigned long count,
unsigned long *pread_count,
unsigned long option
);
#define epvxiReadOptNone 0
EPVXISTAT epvxiWrite(
unsigned la,
char *pbuf,
unsigned long count,
unsigned long *pwrite_count,
unsigned long option
);
#define epvxiWriteOptNone 0
#define epvxiWriteOptPartialMsg 1 /* message continues after this transfer */
EPVXISTAT epvxiSetTimeout(
unsigned la,
unsigned long timeout
);
/*
* epvxiLib return codes (also used by epvxiMsgLib)
*
* These codes changed to the EPICS standrd format on 033193
*/
#define VXI_SUCCESS 0 /* normal successful completion*/
#define S_epvxi_noDevice (M_epvxi|1) /*device does not exist*/
#define S_epvxi_notSlotZero (M_epvxi|2) /*not a slot zero devic*/
#define S_epvxi_uknDevice (M_epvxi|3) /*device not supported*/
#define S_epvxi_badTrigger (M_epvxi|4) /*specified trigger does not exist*/
#define S_epvxi_badTrigIO (M_epvxi|5) /*specified trigger io does not exist*/
#define S_epvxi_deviceOpen (M_epvxi|6) /*device already open*/
#define S_epvxi_notOwner (M_epvxi|7) /*device in use by a different driver*/
#define S_epvxi_noMemory (M_epvxi|8) /*memory allocation failed*/
#define S_epvxi_notOpen (M_epvxi|9) /*device not open*/
#define S_epvxi_notMsgDevice (M_epvxi|10) /*operation requires a message based device*/
#define S_epvxi_deviceTMO (M_epvxi|11) /*message based dev timed out*/
#define S_epvxi_msgDeviceFailure (M_epvxi|12) /*message based dev failed*/
#define S_epvxi_badLA (M_epvxi|13) /*logical addr out of range*/
#define S_epvxi_multipleQueries (M_epvxi|14) /*multiple queries serial protocol error*/
#define S_epvxi_unsupportedCmd (M_epvxi|15) /*unsupported cmd serial protocol error*/
#define S_epvxi_dirViolation (M_epvxi|16) /*DIR violation serial protocol error*/
#define S_epvxi_dorViolation (M_epvxi|17) /*DOR violation serial protocol error*/
#define S_epvxi_rrViolation (M_epvxi|18) /*RR violation serial protocol error*/
#define S_epvxi_wrViolation (M_epvxi|19) /*WR violation serial protocol error*/
#define S_epvxi_errFetchFailed (M_epvxi|20) /*unknown serial protocol error*/
#define S_epvxi_selfTestFailed (M_epvxi|21) /*self test failed*/
#define S_epvxi_timeoutToLarge (M_epvxi|22) /*specified timeout to long*/
#define S_epvxi_protocolError (M_epvxi|23) /*protocol error*/
#define S_epvxi_unreadData (M_epvxi|24) /*attempt to write when unread data from a previous command is present (RULE C.3.3)*/
#define S_epvxi_nameMismatch (M_epvxi|25) /*make or model name already registered does not matchi supplied name*/
#define S_epvxi_noMatch (M_epvxi|26) /*no name registered for the supplied make and or model*/
#define S_epvxi_bufferFull (M_epvxi|27) /*read terminated with unread data remaining because the end of the supplied buffer was reached*/
#define S_epvxi_noResman (M_epvxi|28) /*the VXI resource manager must run first*/
#define S_epvxi_internal (M_epvxi|29) /*VXI internal failure*/
#define S_epvxi_badConfig (M_epvxi|30) /*Incorrect system configuration*/
#define S_epvxi_noCmdr (M_epvxi|31) /*No commander hardware support for message based comm - continuing*/
#define S_epvxi_msgDeviceStatus (M_epvxi|32) /*VXI Message based device reporting error condition*/
#define S_epvxi_slotNotFound (M_epvxi|33) /*VXI device's slot not found- MODID failure?*/
#define S_epvxi_noMODID (M_epvxi|34) /*VXI device does not have MODID capability*/
enum ext_type { ext_local_cpu, /* bus master constrained by module_types.h */
ext_export_vxi_onto_mxi, /* VXI mapped into MXI addr space */
ext_import_mxi_into_vxi /* MXI mapped into VXI addr space */
/*
.
.
other bus extender types could be inserted here
.
.
*/
};
#ifndef SRCepvxiLib
extern
#endif
char *ext_type_name[]
#ifdef SRCepvxiLib
= {
"VXI hosted VME bus master",
"VXI mapped onto MXI addr space",
"MXI mapped into VXI addr space"
}
#endif
;
typedef struct extender_device{
ELLNODE node;
ELLLIST extenders; /* sub extenders */
struct extender_device *pParent;
struct slot_zero_device *pSZD;
enum ext_type type;
int la;
int la_low; /* inclusive */
int la_high; /* inclusive */
unsigned long A24_base;
unsigned long A24_size;
unsigned long A32_base;
unsigned long A32_size;
unsigned la_mapped:1; /* device present */
unsigned A24_mapped:1;
unsigned A32_mapped:1;
unsigned A24_ok:1;
unsigned A32_ok:1;
}VXIE;
/*
* bits for the device type and a pointer
* to its configuration registers if
* available
*/
typedef struct slot_zero_device{
ELLNODE node;
void (*set_modid)(struct slot_zero_device *pvxisz, unsigned slot);
void (*clear_modid)(struct slot_zero_device *pvxisz);
EPVXISTAT (*report)(unsigned la, unsigned level);
VXIE *pvxie;
struct vxi_csr *pcsr;
unsigned char la;
unsigned reg:1;
unsigned msg:1;
}VXISZ;
typedef struct epvxiLibDeviceConfig{
void (*pio_report_func)(); /* ptr to io report func */
void *pDriverConfig; /* ptr to driver config */
void *pMsgConfig; /* msg driver config area */
void *pFatAddrBase;
VXIE *pvxie; /* extender info */
VXIE *pvxieSelf; /* extender info for self */
VXISZ *pvxisz; /* ptr to slot zero info */
unsigned long driverID; /* unique driver id */
int taskID; /* opened by this id */
unsigned short make;
unsigned short model;
short slot;
short commander_la;
short extender_la; /* logical address of bus repeater */
unsigned char class;
unsigned st_passed:1; /* self test passed */
unsigned msg_dev_online:1;
unsigned A24_mapped:1;
unsigned A32_mapped:1;
}VXIDI;
/*
*
*
* functions used from the nivxi library
* (to support runtime linking)
*
*/
enum nivxi_func_index {
e_SetMODID,
e_VXIinLR,
e_InitVXIlibrary,
e_vxiinit,
e_MapTrigToTrig,
e_GetMyLA,
e_EnableSignalInt,
e_SetSignalHandler,
e_RouteSignal
};
#ifndef SRCepvxiLib
extern
#endif
char *nivxi_func_names[]
#ifdef SRCepvxiLib
= {
"_SetMODID",
"_VXIinLR",
"_InitVXIlibrary",
"_vxiinit", /* WARNING this is different than vxiInit */
"_MapTrigToTrig",
"_GetMyLA",
"_EnableSignalInt",
"_SetSignalHandler",
"_RouteSignal"
}
#endif
;
#ifdef SRCepvxiLib
int (*pnivxi_func[NELEMENTS(nivxi_func_names)])();
#else
extern
int (*pnivxi_func[])();
#endif
/*
*
* typical usage
*
* struct freds_driver_info pfdi;
*
* pfdi = epvxiPConfig(14, driverID, (struct freds_driver_info *))
*
* RETURNS ptr to device config area or NULL
*/
#define PVXIDI(LA) (epvxiLibDeviceList[LA])
#define epvxiPConfig(LA, ID, CAST) \
( \
PVXIDI(LA)? \
PVXIDI(LA)->driverID==(ID)? \
(CAST) PVXIDI(LA)->pDriverConfig \
: \
(CAST) NULL \
: \
(CAST) NULL \
)
/*
* epvxiFetchPConfig
* (improved version of the above returns status)
*/
#define epvxiFetchPConfig(LA, ID, PTR) \
( \
PVXIDI(LA)!=NULL? \
(PVXIDI(LA)->driverID==(ID)? \
(((PTR) = PVXIDI(LA)->pDriverConfig), VXI_SUCCESS) \
: \
S_epvxi_notOwner) \
: \
S_epvxi_noDevice \
)
/*
* A24 and A32 base addressing
*/
#define epvxiA24Base(LA) (PVXIDI(LA)->pFatAddrBase)
#define epvxiA32Base(LA) (PVXIDI(LA)->pFatAddrBase)
#ifndef SRCepvxiLib
extern
#endif
VXIDI *epvxiLibDeviceList[NVXIADDR];
#define NO_DRIVER_ATTACHED_ID (0)
#define UNINITIALIZED_DRIVER_ID (0xffff)
#ifndef SRCepvxiLib
extern
#endif
unsigned long epvxiNextDriverID
#ifdef SRCepvxiLib
= (NO_DRIVER_ATTACHED_ID+1)
#endif
;
/*
* set by the RM when it is done and VXI modules are present
*/
#ifndef SRCepvxiLib
extern
#endif
int epvxiResourceMangerOK;
#ifndef SRCepvxiLib
extern
#endif
volatile void *epvxi_local_base;
#define VXIBASE(LA) VXI_LA_TO_PA(LA, epvxi_local_base)
#endif /* INCepvxiLibh */

File diff suppressed because it is too large Load Diff

View File

@@ -1,414 +0,0 @@
/* 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 "dbDefs.h"
#include "errlog.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,
void *pArg
);
LOCAL int hpE1404ShutDown(
void
);
LOCAL void hpE1404ShutDownLA(
unsigned la,
void *pArg
);
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,
void *pArg
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
}
/*
*
* hpE1404InitLA()
*
*/
LOCAL
void hpE1404InitLA(
unsigned la,
void *pArg
)
{
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
)
{
}

View File

@@ -1,74 +0,0 @@
/* 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

View File

@@ -1,361 +0,0 @@
/* 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 "dbDefs.h"
#include "errlog.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 */
uint16_t pending; /* switch position pending int */
uint16_t 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, void *pArg);
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, void *pArg)
{
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_vecInstlFail, 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;
}

View File

@@ -1,60 +0,0 @@
/* 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

View File

@@ -1,341 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvIpMv162.c
Description:
IPAC Carrier Driver for the IndustryPack carriers on the Motorola
MVME162 CPU board, provides the interface between IPAC driver and the
hardware.
Author:
Andrew Johnson
Created:
6 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <sysLib.h>
#include <vxLib.h>
#include "drvIpac.h"
#include "ipic.h"
/* Characteristics of the card */
#define SLOTS 4
#define IO_SPACES 2 /* Address spaces in A16 */
#define IPAC_IRQS 2 /* Interrupts per module */
#define IPIC_BASE 0xfffbc000
/* Base Addresses of IO and ID spaces */
#define REGS_A 0xfff58000
#define PROM_A 0xfff58080
#define REGS_B 0xfff58100
#define PROM_B 0xfff58180
#define REGS_C 0xfff58200
#define PROM_C 0xfff58280
#define REGS_D 0xfff58300
#define PROM_D 0xfff58380
#define REGS_AB 0xfff58400
#define REGS_CD 0xfff58500
/* IPIC chip */
ipic_t *ipic = (ipic_t *) IPIC_BASE;
/* IP Recovery Timers */
LOCAL const uchar_t recoveryTime[] = {
IPIC_GEN_RT_0,
IPIC_GEN_RT_2,
IPIC_GEN_RT_2,
IPIC_GEN_RT_4,
IPIC_GEN_RT_4,
IPIC_GEN_RT_8,
IPIC_GEN_RT_8,
IPIC_GEN_RT_8,
IPIC_GEN_RT_8
};
/* Carrier Base Address structure, only one instance can exist! */
LOCAL long mBase[IPAC_ADDR_SPACES][SLOTS] = {
PROM_A, PROM_B, PROM_C, PROM_D,
REGS_A, REGS_B, REGS_C, REGS_D,
REGS_AB, NULL, REGS_CD, NULL,
NULL, NULL, NULL, NULL
};
/*******************************************************************************
Routine:
initialise
Purpose:
Initialises the MVME162 IPIC chip with settings given in cardParams
Description:
Parameters:
Examples:
"A:m=0x80000000,1024 l=4;B:l=2,2;C:m=0x80100000,64"
Returns:
0 = OK,
S_IPAC_tooMany = Carrier already registered
S_IPAC_badDriver = IPIC chip not found
S_IPAC_badAddress = Parameter string error, or address not reachable
*/
LOCAL int initialise (
char *cardParams,
void **pprivate
) {
static int initialised = FALSE;
ushort_t slot;
int count, p1, p2, next;
char dummy, cmd;
if (initialised) {
return S_IPAC_tooMany;
}
if (vxMemProbe((void *)&ipic->chipId, READ, 1, &dummy) ||
ipic->chipId != IPIC_CHIP_ID) {
return S_IPAC_badDriver;
}
/* Initialise the IPIC chip */
for (slot = 0; slot < SLOTS; slot++) {
ipic->intCtrl[slot][0] = IPIC_INT_ICLR;
ipic->intCtrl[slot][1] = IPIC_INT_ICLR;
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 | IPIC_GEN_RT_0;
}
/* Parse the parameter string */
slot = 0;
while ((cmd = *cardParams++) != '\0') {
switch (cmd) {
case 'A':
case 'B':
case 'C':
case 'D':
slot = cmd - 'A';
break;
case 'm':
p1 = p2 = 0;
count = sscanf(cardParams, "=%p,%d%n",
(void **) &p1, &p2, &next);
if (count != 2 ||
p1 < (long) sysMemTop() ||
p1 & 0xffff != 0 ||
p2 < 64 || p2 > 16384 ||
p1 + (p2*1024) > 0xfff00000) {
return S_IPAC_badAddress;
}
ipic->memBase[slot] = p1 >> 16;
ipic->memSize[slot] = (p2 / 64) - 1;
ipic->genCtrl[slot] |= IPIC_GEN_MEN;
mBase[ipac_addrMem][slot] = p1;
cardParams += next;
break;
case 'l':
p1 = p2 = 0;
count = sscanf(cardParams, "=%d%n,%d%n", &p1, &next, &p2, &next);
if (count < 1 || count > 2 ||
p1 < 0 || p1 > 7 ||
p2 < 0 || p2 > 7) {
return S_IPAC_badAddress;
}
ipic->intCtrl[slot][0] = (p1 & IPIC_INT_LEVEL) |
(ipic->intCtrl[slot][0] & ~IPIC_INT_LEVEL);
ipic->intCtrl[slot][1] = (p2 & IPIC_INT_LEVEL) |
(ipic->intCtrl[slot][1] & ~IPIC_INT_LEVEL);
cardParams += next;
break;
case 'r':
p1 = 0;
count = sscanf(cardParams, "=%d%n", &p1, &next);
if (count != 1 ||
p1 < 0 || p1 > 8) {
return S_IPAC_badAddress;
}
ipic->genCtrl[slot] = (ipic->genCtrl[slot] & ~IPIC_GEN_RT) |
recoveryTime[p1];
cardParams += next;
break;
case 'w':
p1 = 0;
count = sscanf(cardParams, "=%d%n", &p1, &next);
if (count != 1) {
return S_IPAC_badAddress;
}
switch (p1) {
case 8:
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_8 |
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
break;
case 16:
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_16 |
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
break;
case 32:
if (slot & 1) {
/* Illegal for odd-numbered slots */
return S_IPAC_badAddress;
}
ipic->genCtrl[slot] = IPIC_GEN_WIDTH_32 |
(ipic->genCtrl[slot] & ~IPIC_GEN_WIDTH);
ipic->genCtrl[slot+1] &= ~(IPIC_GEN_WIDTH |
IPIC_GEN_MEN);
break;
default:
return S_IPAC_badAddress;
}
}
}
initialised = TRUE;
return OK;
}
/*******************************************************************************
Routine:
baseAddr
Purpose:
Returns the base address for the requested slot & address space
Description:
This routine only has to do a table lookup in the mBase array.
Note that no parameter checking is required - the IPAC driver which
calls this routine handles that.
Returns:
The requested address, or NULL if the slot has no memory in the
requested address space.
*/
LOCAL void *baseAddr (
void *private,
ushort_t slot,
ipac_addr_t space
) {
return (void *) mBase[space][slot];
}
/*******************************************************************************
Routine:
irqCmd
Purpose:
Handles interrupter commands and status requests
Description:
The IPIC chip allows a lot of control over the IP interrupters, thus
all commands perform the requested action.
Returns:
ipac_irqGetLevel returns the current interrupt level,
ipac_irqPoll returns >0 if interrupt line active else 0,
other calls return 0 = OK.
*/
LOCAL int irqCmd (
void *private,
ushort_t slot,
ushort_t irqNumber,
ipac_irqCmd_t cmd
) {
switch (cmd) {
case ipac_irqLevel0:
case ipac_irqLevel1:
case ipac_irqLevel2:
case ipac_irqLevel3:
case ipac_irqLevel4:
case ipac_irqLevel5:
case ipac_irqLevel6:
case ipac_irqLevel7:
ipic->intCtrl[slot][irqNumber] = (cmd & IPIC_INT_LEVEL) |
(ipic->intCtrl[slot][irqNumber] & ~IPIC_INT_LEVEL);
return OK;
case ipac_irqGetLevel:
return ipic->intCtrl[slot][irqNumber] & IPIC_INT_LEVEL;
case ipac_irqEnable:
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_IEN;
return OK;
case ipac_irqDisable:
ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_IEN;
return OK;
case ipac_irqPoll:
return ipic->intCtrl[slot][irqNumber] & IPIC_INT_INT;
case ipac_irqSetEdge:
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_EDGE;
return OK;
case ipac_irqSetLevel:
ipic->intCtrl[slot][irqNumber] &= ~IPIC_INT_EDGE;
return OK;
case ipac_irqClear:
ipic->intCtrl[slot][irqNumber] |= IPIC_INT_ICLR;
return OK;
default:
return S_IPAC_notImplemented;
}
}
/******************************************************************************/
/* IPAC Carrier Table */
ipac_carrier_t ipmv162 = {
"Motorola MVME162",
SLOTS,
initialise,
NULL,
baseAddr,
irqCmd
};

View File

@@ -1,520 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvIpac.c
Description:
IPAC Driver, provides a standard interface between IPAC Module
drivers and the IPAC Carrier drivers.
Author:
Andrew Johnson
Created:
3 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef NO_EPICS
# include <drvSup.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vxLib.h>
#include "drvIpac.h"
#define IPAC_MAX_CARRIERS 21
/* Private carrier data structures */
struct carrierInfo {
ipac_carrier_t *driver;
void *cPrivate;
};
LOCAL struct {
ushort_t number;
struct carrierInfo *info[IPAC_MAX_CARRIERS];
} carriers = {
0
};
/* Null carrier stuff */
LOCAL ipac_carrier_t nullCarrier = {
"Null carrier (place holder)",
0, /* No slots */
NULL, NULL, NULL, NULL
};
LOCAL struct carrierInfo nullInfo = {
&nullCarrier,
NULL
};
#ifndef NO_EPICS
/* EPICS Driver Support Entry Table */
struct drvet drvIpac = {
3,
(DRVSUPFUN) ipacReport,
(DRVSUPFUN) ipacInitialise,
NULL
};
#endif
/*******************************************************************************
Routine:
ipacAddCarrier
Purpose:
Used to register a carrier board & carrier driver with the IPAC driver.
Description:
Usually called from the vxWorks (EPICS) startup script. Some types of
carrier may need additional initilisation before or after registering,
but the card parameter string should be sufficient for most carriers.
Note that only the carrier initialise routine is called at this stage.
The order in which carriers are registered with this routine specifies
the carrier number which they will be allocated, starting from zero.
Checks that the carrier descriptor table looks sensible, then calls the
initialise routine with the given card parameters, and saves the carrier
private pointer and carrier table address. The card number allows the
same descriptor to be used for all carriers of the same type.
It may be necessary to remove a carrier temporarily from a system in
some circumstances without wanting to have to change the carrier number
allocated to higher numbered carriers. To allow this, it is legal to
call this routine with a NULL (zero) carrier table address, which
switches in the null carrier table instead.
Returns:
0 = OK,
S_IPAC_tooMany = Carrier Info Table full,
S_IPAC_badTable = Carrier Table invalid.
Example:
ipacAddCarrier(&vipc310, "0x6000");
*/
int ipacAddCarrier (
ipac_carrier_t *pcarrierTable,
char *cardParams
) {
void *cPrivate;
int status;
if (carriers.number >= IPAC_MAX_CARRIERS) {
return S_IPAC_tooMany;
}
if (pcarrierTable == NULL) {
carriers.info[carriers.number] = &nullInfo;
carriers.number++;
return OK;
}
if (pcarrierTable->numberSlots == 0 ||
pcarrierTable->initialise == NULL ||
pcarrierTable->baseAddr == NULL ||
pcarrierTable->irqCmd == NULL) {
return S_IPAC_badTable;
}
status = pcarrierTable->initialise(cardParams, &cPrivate);
if (status) {
return status;
}
carriers.info[carriers.number] = malloc(sizeof (struct carrierInfo));
carriers.info[carriers.number]->driver = pcarrierTable;
carriers.info[carriers.number]->cPrivate = cPrivate;
carriers.number++;
return OK;
}
/*******************************************************************************
Routine:
ipmCheck
Function:
Check on presence of an IPAC module at the given carrier & slot number.
Description:
Does a quick check to make sure the carrier and slot numbers are legal,
probes the IDprom space to ensure an IPAC is installed, and checks that
the IDprom starts with the "IPAC" identifier.
Returns:
0 = OK,
S_IPAC_badAddress = Bad carrier or slot number,
S_IPAC_noModule = No module installed,
S_IPAC_noIpacId = "IPAC" identifier not found
*/
int ipmCheck (
ushort_t carrier,
ushort_t slot
) {
ipac_idProm_t *id;
char dummy;
if (carrier >= carriers.number ||
slot >= carriers.info[carrier]->driver->numberSlots) {
return S_IPAC_badAddress;
}
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
if (id == NULL) {
return S_IPAC_badDriver;
}
if (vxMemProbe((void *)&id->asciiI, READ, 1, &dummy)) {
return S_IPAC_noModule;
}
if (id->asciiI != 'I' ||
id->asciiP != 'P' ||
id->asciiA != 'A' ||
id->asciiC != 'C') {
return S_IPAC_noIpacId; /* Not an IPAC */
}
return OK;
}
/*******************************************************************************
Routine:
checkCRC
Function:
Calculate the CRC of the IDprom at the given address.
Description:
Generates an industry standard CRC of the ID Prom data as described
in the GreenSpring Industry Pack specification. The CRC byte in the
Prom (at address 0x17) is set to zero for the purpose of calculating
the CRC.
Returns:
The low 8 bits of the calculated CRC value.
*/
LOCAL int checkCRC (
uchar_t *data,
ushort_t length
) {
uint_t i, crc = 0xffff;
uchar_t mask;
for (i = 1; i < 2*length; i += 2) {
mask = 0x80;
while (mask) {
if ((data[i] & mask) && (i != 0x17)) {
crc ^= 0x8000;
}
crc += crc;
if (crc > 0xffff) {
crc = (crc & 0xffff) ^ 0x1021;
}
mask >>= 1;
}
}
return (~crc) & 0xff;
}
/*******************************************************************************
Routine:
ipmValidate
Function:
Validate a particular IPAC module type at the given carrier & slot number.
Description:
Uses ipmCheck to ensure the carrier and slot numbers are legal, probe the
IDprom and check that the IDprom looks like an IPAC module. Calculates
the CRC for the ID Prom, and compares the manufacturer and model ID values
in the Prom to the ones given.
Returns:
0 = OK,
S_IPAC_badAddress = Bad carrier or slot number,
S_IPAC_noModule = No module installed,
S_IPAC_noIpacId = "IPAC" identifier not found
S_IPAC_badCRC = CRC Check failed,
S_IPAC_badModule = Manufacturer or model IDs wrong
*/
int ipmValidate (
ushort_t carrier,
ushort_t slot,
uchar_t manufacturerId,
uchar_t modelId
) {
ipac_idProm_t *id;
int status;
status = ipmCheck(carrier, slot);
if (status) {
return status;
}
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
if (checkCRC((uchar_t *) id, id->bytesUsed) != id->CRC) {
return S_IPAC_badCRC;
}
if (id->manufacturerId != manufacturerId ||
id->modelId != modelId) {
return S_IPAC_badModule;
}
return OK;
}
/*******************************************************************************
Routine:
ipmReport
Function:
returns printable string giving status of module at given carrier/slot.
Description:
Generates a report string describing the given IPAC slot. If a module
is installed, it includes the manufacturer and model ID numbers. If
the report function is supported by the carrier driver this report
string is appended.
Returns:
Pointer to static, printable string.
Sample Output:
"C0 S1 : 0xB1/0x01 - M0 L4,5"
*/
char *ipmReport (
ushort_t carrier,
ushort_t slot
) {
static char report[80];
int status;
sprintf(report, "C%hd S%hd : ", carrier, slot);
status = ipmCheck(carrier, slot);
if (status == S_IPAC_badAddress) {
strcat(report, "No such carrier/slot");
return report;
}
if (status == S_IPAC_noModule) {
strcat(report, "No Module");
} else {
ipac_idProm_t *id;
char module[16];
id = (ipac_idProm_t *) ipmBaseAddr(carrier, slot, ipac_addrID);
sprintf(module, "0x%02hX/0x%02hX", (short) id->manufacturerId,
(short) id->modelId);
strcat(report, module);
}
if (carriers.info[carrier]->driver->report != NULL) {
strcat(report, " - ");
strcat(report, carriers.info[carrier]->driver->report(
carriers.info[carrier]->cPrivate, slot));
}
return report;
}
/*******************************************************************************
Routine:
ipmBaseAddr
Function:
Returns a pointer to the selected IP address space
Description:
Checks its input parameters, then calls the carrier driver. This will
return a pointer to the location of the address space indicated by the
space parameter. All IP modules must provide an ID prom to indicate
the module type (space = ipac_addrID). Most modules need register I/O
locations, which are in the I/O space (space = ipac_addrIO). Some
types of module also provide memory (space = ipac_addrMem), but if
this is not required the carrier may allow it to be disabled, in which
case the driver should return a NULL for this address space. Some
carriers provide a 32-bit wide I/O space for Dual-slot IP modules;
carriers which do not should return NULL for this space.
Returns:
Base CPU address of IP address space, or NULL pointer.
*/
void *ipmBaseAddr (
ushort_t carrier,
ushort_t slot,
ipac_addr_t space
) {
if (carrier >= carriers.number ||
slot >= carriers.info[carrier]->driver->numberSlots) {
return NULL;
}
return carriers.info[carrier]->driver->baseAddr(
carriers.info[carrier]->cPrivate, slot, space);
}
/*******************************************************************************
Routine:
ipmIrqCmd
Function:
Send command to slot interrupt controller.
Description:
Checks input parameters, then passes the interrupt command request to
the carrier driver routine. The driver is only required to support
the command ipac_irqEnable; for other commands it may return the status
code S_IPAC_notImplemented and do nothing.
Returns:
0 = OK,
S_IPAC_badAddress = illegal carrier, slot or irqNumber,
S_IPAC_notImplemented = Driver does not support that command,
other, depending on command.
*/
int ipmIrqCmd (
ushort_t carrier,
ushort_t slot,
ushort_t irqNumber,
ipac_irqCmd_t cmd
) {
if (irqNumber > 1 ||
carrier >= carriers.number ||
slot >= carriers.info[carrier]->driver->numberSlots) {
return S_IPAC_badAddress;
}
return carriers.info[carrier]->driver->irqCmd(
carriers.info[carrier]->cPrivate, slot, irqNumber, cmd);
}
/*******************************************************************************
Routine:
ipacReport
Function:
Report status of all known IPAC carriers
Description:
Prints information on each known carrier board and slot according to the
specified interest level. Level 0 lists carriers only, with the number
of slots it supports. Level 1 gives each slot, manufacturer & model ID
of the installed module (if any), and the carrier driver report for that
slot. Level 2 adds the address of each memory space for the slot.
Returns:
OK.
*/
int ipacReport (
int interest
) {
ushort_t carrier, slot;
for (carrier=0; carrier < carriers.number; carrier++) {
printf(" IP Carrier %2d: %s, %d slots\n", carrier,
carriers.info[carrier]->driver->carrierType,
carriers.info[carrier]->driver->numberSlots);
if (interest > 0) {
long memBase, io32Base;
for (slot=0; slot < carriers.info[carrier]->driver->numberSlots;
slot++) {
printf(" %s\n", ipmReport(carrier, slot));
if (interest > 1) {
printf(" ID = 0x%lx, I/O = 0x%lx",
(long) ipmBaseAddr(carrier, slot, ipac_addrID),
(long) ipmBaseAddr(carrier, slot, ipac_addrIO));
io32Base = (long) ipmBaseAddr(carrier, slot, ipac_addrIO32);
if (io32Base != NULL) {
printf(", I/O32 = 0x%lx", io32Base);
}
memBase = (long) ipmBaseAddr(carrier, slot, ipac_addrMem);
if (memBase != NULL) {
printf(", Mem = 0x%lx", memBase);
}
printf("\n");
}
}
}
}
return OK;
}
/*******************************************************************************
Routine:
ipacInitialise
Function:
Initialise the IPAC driver
Description:
Null routine.
Returns:
OK.
*/
int ipacInitialise (
int after
) {
return OK;
}

View File

@@ -1,176 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvIpac.h
Description:
IPAC Driver header file, defines the software interfaces:
1. Upwards to the IPAC Module driver
2. Downwards to the IPAC Carrier driver
Author:
Andrew Johnson
Created:
1 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef INCdrvIpacH
#define INCdrvIpacH
#include <types.h>
#include "ipModules.h"
#ifndef NO_EPICS
#include <errMdef.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Error numbers */
#ifndef OK
#define OK 0
#endif
#ifndef M_ipac
#define M_ipac (600 << 16)
#endif
#define S_IPAC_badTable (M_ipac| 1) /*IPAC Carrier Table invalid*/
#define S_IPAC_tooMany (M_ipac| 2) /*Too many IPAC carriers, table full*/
#define S_IPAC_badAddress (M_ipac| 3) /*Bad IPAC carrier or slot number*/
#define S_IPAC_badDriver (M_ipac| 4) /*Bad value from IPAC carrier driver*/
#define S_IPAC_noModule (M_ipac| 5) /*No IP module installed*/
#define S_IPAC_noIpacId (M_ipac| 6) /*IPAC identifier not found*/
#define S_IPAC_badCRC (M_ipac| 7) /*IPAC CRC Check failed*/
#define S_IPAC_badModule (M_ipac| 8) /*IPAC Manufacturer or model ID wrong*/
#define S_IPAC_notImplemented (M_ipac| 9) /*IPAC Driver command not available*/
/* Structure of the IPAC ID Prom, located in the pack ID space. */
typedef struct {
uchar_t pad00;
uchar_t asciiI;
uchar_t pad02;
uchar_t asciiP;
uchar_t pad04;
uchar_t asciiA;
uchar_t pad06;
uchar_t asciiC;
uchar_t pad08;
uchar_t manufacturerId;
uchar_t pad0a;
uchar_t modelId;
uchar_t pad0c;
uchar_t revision;
uchar_t pad0e;
uchar_t reserved;
uchar_t pad10;
uchar_t driverIdLow;
uchar_t pad12;
uchar_t driverIdHigh;
uchar_t pad14;
uchar_t bytesUsed;
uchar_t pad16;
uchar_t CRC;
uchar_t pad18;
uchar_t packSpecific[0x3f-0x18];
} ipac_idProm_t;
/* These are the types of address space implemented in the IP
specification. Some IP modules only use the ID and IO spaces. */
#define IPAC_ADDR_SPACES 4
typedef enum {
ipac_addrID = 0, /* ID Prom space */
ipac_addrIO = 1, /* Registers etc */
ipac_addrIO32 = 2, /* Registers for 32-bit dual-slot */
ipac_addrMem = 3 /* Memory space */
} ipac_addr_t;
/* The following are the possible commands to the carrier driver to
handle interrupts from the IP modules. Some carriers will only be
able to implement a subset of these commands. Note that irqEnable
should call the vxWorks sysBusEnable routine if this is needed to
pass the carrier interrupts through to the CPU. */
typedef enum {
ipac_irqLevel0 = 0, /* Disables interrupts */
ipac_irqLevel1 = 1, /* Lowest priority */
ipac_irqLevel2 = 2,
ipac_irqLevel3 = 3,
ipac_irqLevel4 = 4,
ipac_irqLevel5 = 5,
ipac_irqLevel6 = 6, /* Highest priority */
ipac_irqLevel7 = 7, /* Non-maskable, don't use */
ipac_irqGetLevel, /* Returns level set (or hard-coded) */
ipac_irqEnable, /* Required to use interrupts */
ipac_irqDisable, /* Not necessarily supported */
ipac_irqPoll, /* Returns interrupt state */
ipac_irqSetEdge, /* Sets edge-triggered interrupts */
ipac_irqSetLevel, /* Sets level-triggered (default) */
ipac_irqClear /* Only needed if using edge-triggered */
} ipac_irqCmd_t;
/* This is a table which each IPAC carrier driver provides to allow
it to be queried by the IPAC driver. One table is required for
each type of carrier. The cPrivate pointer is returned by the
carrier driver initialise routine, and passed to all of the other
routines as a means of identification of the carrier board. */
typedef struct {
char *carrierType;
/* String containing carrier board type */
ushort_t numberSlots;
/* Number of IPAC devices this carrier can hold */
int (*initialise)(char *cardParams, void **cPrivate);
/* Initialise carrier and return *cPrivate */
char *(*report)(void *cPrivate, ushort_t slot);
/* Return string with giving status of this slot */
void *(*baseAddr)(void *cPrivate, ushort_t slot, ipac_addr_t space);
/* Return base addresses for this slot */
int (*irqCmd)(void *cPrivate, ushort_t slot,
ushort_t irqNumber, ipac_irqCmd_t cmd);
/* interrupt manipulation */
} ipac_carrier_t;
/* Functions for startup and interactive use */
extern int ipacAddCarrier(ipac_carrier_t *pcarrier, char *cardParams);
extern int ipacReport(int interest);
extern int ipacInitialise(int after);
/* Functions for use in IPAC module drivers */
extern int ipmCheck(ushort_t carrier, ushort_t slot);
extern int ipmValidate(ushort_t carrier, ushort_t slot,
uchar_t manufacturerId, uchar_t modelId);
extern char *ipmReport(ushort_t carrier, ushort_t slot);
extern void *ipmBaseAddr(ushort_t carrier, ushort_t slot, ipac_addr_t space);
extern int ipmIrqCmd(ushort_t carrier, ushort_t slot,
ushort_t irqNumber, ipac_irqCmd_t cmd);
#ifdef __cplusplus
}
#endif
#endif /* INCipacH */

View File

@@ -1,486 +0,0 @@
/* 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 "dbDefs.h"
#include "errlog.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, void *pArg);
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, void *pArg)
{
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_vecInstlFail,
"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;
}

View File

@@ -1,56 +0,0 @@
/* 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
);

View File

@@ -1,628 +0,0 @@
/* 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 "errlog.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_vecInstlFail;
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, /* sec */
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;
}

View File

@@ -1,74 +0,0 @@
/* 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
);

View File

@@ -1,316 +0,0 @@
/* 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 <taskLib.h>
#include "dbDefs.h"
#include "errlog.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;
}
/*
* stcWriteData()
*/
void stcWriteData(volatile uint16_t *pdata, uint16_t data)
{
*pdata = data;
}
/*
* stcReadData()
*/
uint16_t stcReadData(volatile uint16_t *pdata)
{
uint16_t data;
data = *pdata;
return data;
}
/*
* stcWriteCmd()
*/
void stcWriteCmd(volatile uint8_t *pcmd, uint8_t cmd)
{
*pcmd = cmd;
}

View File

@@ -1,116 +0,0 @@
/* 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 stcWriteCmd(pcmd,0xffU);
#define STC_BUS16 stcWriteCmd(pcmd,0xefU);
#define STC_BUS16 stcWriteCmd(pcmd,0xefU);
#define STC_SET_MASTER_MODE(D) {stcWriteCmd(pcmd,0x17U); \
stcWriteData(pdata,(D));}
#define STC_MASTER_MODE (stcWriteCmd(pcmd,0x17U), stcReadData(pdata))
#define STC_CTR_INIT(MODE,LOAD,HOLD)\
{stcWriteCmd(pcmd,CHIPCHAN+1); stcWriteData(pdata,(MODE)); \
stcWriteData(pdata,(LOAD)); stcWriteData(pdata,(HOLD));}
#define STC_CTR_READ(MODE,LOAD,HOLD)\
{stcWriteCmd(pcmd,CHIPCHAN+1); (MODE) = stcReadData(pdata); \
(LOAD) = stcReadData(pdata); (HOLD) = stcReadData(pdata);}
#define STC_SET_TC(D) stcWriteCmd(pcmd, \
0xe0U | ((D)?8:0)|(CHIPCHAN+1U) )
#define STC_LOAD stcWriteCmd(pcmd, 0x40U | 1<<(CHIPCHAN))
#define STC_STEP stcWriteCmd(pcmd, 0xf0U | (CHIPCHAN+1U))
#define STC_ARM stcWriteCmd(pcmd, 0x20U | 1<<CHIPCHAN)
#define STC_DISARM stcWriteCmd(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
);
void stcWriteData(volatile uint16_t *pdata, uint16_t data);
uint16_t stcReadData(volatile uint16_t *pdata);
void stcWriteCmd(volatile uint8_t *pcmd, uint8_t cmd);

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvTip810.h
Description:
Header file for TEWS TIP810 CAN Bus driver.
Author:
Andrew Johnson
Created:
20 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef INCdrvTip810H
#define INCdrvTip810H
#include <types.h>
#include "canBus.h"
/* Error Numbers */
#ifndef M_t810
#define M_t810 (810<<16)
#endif
#define S_t810_duplicateDevice (M_t810| 1) /*duplicate t810 device definition*/
#define S_t810_badBusRate (M_t810| 2) /*CANbus bit rate not supported*/
#define S_t810_badDevice (M_t810| 3) /*device pointer is not for t810*/
#define S_t810_transmitterBusy (M_t810| 4) /*transmit buffer unexpectedly busy*/
extern int t810Report(int page);
extern int t810Create(char *busName, ushort_t card, ushort_t slot,
uint_t busRate);
extern int t810Shutdown(int starttype);
extern int t810Initialise(void);
#endif /* INCdrvTip810H */

View File

@@ -1,262 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvVipc310.c
Description:
IPAC Carrier Driver for the GreenSpring VIPC310 Dual IndustryPack
Carrier VME board, provides the interface between IPAC driver and the
hardware. This carrier is 3U high, and thus cannot support 32-bit
accesses to dual-slot IP modules.
Author:
Andrew Johnson
Created:
5 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <sysLib.h>
#include "drvIpac.h"
/* Characteristics of the card */
#define SLOTS 2
#define IO_SPACES 2 /* Address spaces in A16 */
#define IPAC_IRQS 2 /* Interrupts per module */
/* Offsets from base address in VME A16 */
#define REGS_A 0x0000
#define PROM_A 0x0080
#define REGS_B 0x0100
#define PROM_B 0x0180
/* VME Interrupt levels */
#define IRQ_A0 4
#define IRQ_A1 5
#define IRQ_B0 2
#define IRQ_B1 1
/* Carrier Private structure type, one instance per board */
typedef void* private_t[IPAC_ADDR_SPACES][SLOTS];
/*******************************************************************************
Routine:
initialise
Purpose:
Creates new private table for VIPC310 at addresses given by cardParams
Description:
Checks the parameter string for the address of the card I/O space and
optional size of the memory space for the modules. If both the I/O and
memory base addresses can be reached from the CPU, a private table is
created for this board. The private table is a 2-D array of pointers
to the base addresses of the various accessible parts of the IP module.
Parameters:
The parameter string should comprise a hex number (the 0x or 0X at the
start is optional) optionally followed by a comma and a decimal integer.
The first number is the I/O base address of the card in the VME A16
address space (the factory default is 0x6000). If present the second
number gives the memory space in Kbytes allocated to each IP module.
The memory base address of the VIPC310 card is set using the same jumpers
as the I/O base address and is always 256 times the I/O base address,
but in the VME A24 address space. The factory default fot the memory
base address is thus 0x600000. If the memory size parameter is omitted
or set to zero then neither IP module provides any memory space. Legal
memory size values are 0, 64, 128, 256, 512, 1024 or 2048. The memory
size interacts with the memory base address such that it is possible to
set the existance of memory in either slot independently with suitable
adjustment of the base address.
Examples:
"0x6000"
This indicates that the carrier has its I/O base set to 0x6000, and
neither slot uses any memory space.
"1000,512"
Here the I/O base is set to 0x1000, and there is 512 Kbytes of
memory on each module, with the IP module A memory at 0x100000
and module B at 0x180000.
"0xfe00, 128"
The I/O base is at 0xfe00, and hence the carrier memory base is
0xfe0000. However because the memory size is set to give each module
128 Kbytes of memory space, module A cannot be selected (128 K =
0x020000, so the module is decoded at 0xfc0000 but can't be accessed
because this is below the memory base).
Returns:
0 = OK,
S_IPAC_badAddress = Parameter string error, or address not reachable
*/
LOCAL int initialise (
char *cardParams,
void **pprivate
) {
int params, status1 = OK, status2 = OK, mSize = 0;
long ioBase, mOrig, mBase;
ushort_t space, slot;
private_t *private;
static const int offset[IO_SPACES][SLOTS] = {
PROM_A, PROM_B,
REGS_A, REGS_B
};
if (cardParams == NULL ||
strlen(cardParams) == 0) {
ioBase = 0x6000;
} else {
params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize);
if (params < 1 || params > 2 ||
ioBase > 0xfe00 || ioBase & 0x01ff ||
mSize < 0 || mSize > 2048 || mSize & 63) {
return S_IPAC_badAddress;
}
}
mBase = ioBase << 8; /* Fixed by VIPC310 card */
status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,
(char *) ioBase, (char **) &ioBase);
if (mSize > 0) {
status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,
(char *) mBase, (char **) &mBase);
}
if (status1 || status2) {
return S_IPAC_badAddress;
}
mSize = mSize << 10; /* Convert size from K to Bytes */
mOrig = mBase & ~(mSize * SLOTS - 1);
private = malloc(sizeof (private_t));
for (space = 0; space < IO_SPACES; space++) {
for (slot = 0; slot < SLOTS; slot++) {
(*private)[space][slot] = (void *) (ioBase + offset[space][slot]);
}
}
(*private)[ipac_addrIO32][0] = NULL;
(*private)[ipac_addrIO32][1] = NULL;
if (mOrig == mBase) {
(*private)[ipac_addrMem][0] = (void *) mBase;
(*private)[ipac_addrMem][1] = (void *) (mBase + mSize);
} else {
(*private)[ipac_addrMem][0] = NULL;
(*private)[ipac_addrMem][1] = (void *) mBase;
}
*pprivate = private;
return OK;
}
/*******************************************************************************
Routine:
baseAddr
Purpose:
Returns the base address for the requested slot & address space
Description:
Because we did all that hard work in the initialise routine, this
routine only has to do a table lookup in the private array.
Note that no parameter checking is required - the IPAC driver which
calls this routine handles that.
Returns:
The requested address, or NULL if the module has no memory.
*/
LOCAL void *baseAddr (
void *private,
ushort_t slot,
ipac_addr_t space
) {
return (*(private_t *) private)[space][slot];
}
/*******************************************************************************
Routine:
irqCmd
Purpose:
Handles interrupter commands and status requests
Description:
The GreenSpring board is limited to fixed interrupt levels, and has
no control over interrupts. The only commands thus supported are
a request of the interrupt level associated with a particular slot
and interrupt number, or to enable interrupts by making sure the
VMEbus interrupter is listening on the necessary level.
Returns:
ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5),
ipac_irqEnable returns 0 = OK,
other calls return S_IPAC_notImplemented.
*/
LOCAL int irqCmd (
void *private,
ushort_t slot,
ushort_t irqNumber,
ipac_irqCmd_t cmd
) {
static const int irqLevel[SLOTS][IPAC_IRQS] = {
IRQ_A0, IRQ_A1,
IRQ_B0, IRQ_B1
};
switch (cmd) {
case ipac_irqGetLevel:
return irqLevel[slot][irqNumber];
case ipac_irqEnable:
sysIntEnable(irqLevel[slot][irqNumber]);
return OK;
default:
return S_IPAC_notImplemented;
}
}
/******************************************************************************/
/* IPAC Carrier Table */
ipac_carrier_t vipc310 = {
"GreenSpring VIPC310",
SLOTS,
initialise,
NULL,
baseAddr,
irqCmd
};

View File

@@ -1,275 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
drvVipc610.c
Description:
IPAC Carrier Driver for the GreenSpring VIPC610-01 Quad IndustryPack
Carrier VME board, provides the interface between IPAC driver and the
hardware. This carrier is 6U high, but cannot support 32-bit accesses
to dual-slot IP modules. Note the -01 option fixes the IRQ levels to
be equivalent to two VIPC310 carriers.
Author:
Andrew Johnson
Created:
19 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <sysLib.h>
#include "drvIpac.h"
/* Characteristics of the card */
#define SLOTS 4
#define IO_SPACES 2 /* Address spaces in A16 */
#define IPAC_IRQS 2 /* Interrupts per module */
/* Offsets from base address in VME A16 */
#define REGS_A 0x0000
#define PROM_A 0x0080
#define REGS_B 0x0100
#define PROM_B 0x0180
#define REGS_C 0x0200
#define PROM_C 0x0280
#define REGS_D 0x0300
#define PROM_D 0x0380
/* VME Interrupt levels for -01 option */
#define IRQ_A0 4
#define IRQ_A1 5
#define IRQ_B0 2
#define IRQ_B1 1
#define IRQ_C0 4
#define IRQ_C1 5
#define IRQ_D0 2
#define IRQ_D1 1
/* Carrier Private structure type, one instance per board */
typedef void* private_t[IPAC_ADDR_SPACES][SLOTS];
/*******************************************************************************
Routine:
initialise
Purpose:
Creates new private table for VIPC610 at addresses given by cardParams
Description:
Checks the parameter string for the address of the card I/O space and
optional size of the memory space for the modules. If both the I/O and
memory base addresses can be reached from the CPU, a private table is
created for this board. The private table is a 2-D array of pointers
to the base addresses of the various accessible parts of the IP module.
Parameters:
The parameter string should comprise a hex number (the 0x or 0X at the
start is optional) optionally followed by a comma and a decimal integer.
The first number is the I/O base address of the card in the VME A16
address space (the factory default is 0x6000). If present the second
number gives the memory space in Kbytes allocated to each IP module.
The memory base address of the VIPC610 card is set using the same jumpers
as the I/O base address and is always 256 times the I/O base address,
but in the VME A24 address space. The factory default for the memory
base address is thus 0x600000. If the memory size parameter is omitted
or set to zero then none of the IP modules on the carrier provide any
memory space. Legal memory size values are 0, 64?, 128, 256, 512, 1024
or 2048. The memory size interacts with the memory base address such
that it is possible to exclude memory from the lower slots while still
providing access to memory in the later slots by adjusting the base
address suitably.
Examples:
"0x6000"
This indicates that the carrier board has its I/O base set to
0x6000, and none of the slots provide memory space.
"1000,128"
Here the I/O base is set to 0x1000, and there is 128Kbytes of
memory on each module, with the IP module A memory at 0x100000,
module B at 0x120000, module C at 0x140000 and D at 0x160000.
"7000,1024"
The I/O base is at 0x7000, and hence the carrier memory base is
0x700000. However because the memory size is set to 1024 Kbytes,
modules A, B and C cannot be selected (1024 K = 0x100000, so they
are decoded at 0x400000, 0x500000 and 0x600000 but can't be accessed
because these are below the base address).
Returns:
0 = OK,
S_IPAC_badAddress = Parameter string error, or address not reachable
*/
LOCAL int initialise (
char *cardParams,
void **pprivate
) {
int params, status1 = OK, status2 = OK, mSize = 0;
ulong_t ioBase, mOrig, mBase, addr;
ushort_t space, slot;
private_t *private;
static const int offset[IO_SPACES][SLOTS] = {
PROM_A, PROM_B, PROM_C, PROM_D,
REGS_A, REGS_B, REGS_C, REGS_D
};
if (cardParams == NULL ||
strlen(cardParams) == 0) {
ioBase = 0x6000;
} else {
params = sscanf(cardParams, "%p,%i", (void **) &ioBase, &mSize);
if (params < 1 || params > 2 ||
ioBase > 0xfc00 || ioBase & 0x01ff ||
mSize < 0 || mSize > 2048 || mSize & 63) {
return S_IPAC_badAddress;
}
}
mBase = ioBase << 8; /* Fixed by the VIPC610 card */
ioBase = ioBase & 0xfc00; /* Clear A09 */
status1 = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,
(char *) ioBase, (char **) &ioBase);
if (mSize > 0) {
status2 = sysBusToLocalAdrs(VME_AM_STD_SUP_DATA,
(char *) mBase, (char **) &mBase);
}
if (status1 || status2) {
return S_IPAC_badAddress;
}
mSize = mSize << 10; /* Convert size from K to Bytes */
mOrig = mBase & ~(mSize * SLOTS - 1);
private = malloc(sizeof (private_t));
for (space = 0; space < IO_SPACES; space++) {
for (slot = 0; slot < SLOTS; slot++) {
(*private)[space][slot] = (void *) (ioBase + offset[space][slot]);
}
}
for (slot = 0; slot < SLOTS; slot++) {
(*private)[ipac_addrIO32][slot] = NULL;
addr = mOrig + (mSize * slot);
if (addr < mBase) {
(*private)[ipac_addrMem][slot] = NULL;
} else {
(*private)[ipac_addrMem][slot] = (void *) addr;
}
}
*pprivate = private;
return OK;
}
/*******************************************************************************
Routine:
baseAddr
Purpose:
Returns the base address for the requested slot & address space
Description:
Because we did all that hard work in the initialise routine, this
routine only has to do a table lookup in the private array.
Note that no parameter checking is required - the IPAC driver which
calls this routine handles that.
Returns:
The requested address, or NULL if the module has no memory.
*/
LOCAL void *baseAddr (
void *private,
ushort_t slot,
ipac_addr_t space
) {
return (*(private_t *) private)[space][slot];
}
/*******************************************************************************
Routine:
irqCmd
Purpose:
Handles interrupter commands and status requests
Description:
The GreenSpring board is limited to fixed interrupt levels, and has
no control over interrupts. The only commands thus supported are
a request of the interrupt level associated with a particular slot
and interrupt number, or to enable interrupts by making sure the
VMEbus interrupter is listening on the necessary level.
Returns:
ipac_irqGetLevel returns the interrupt level (1, 2, 4 or 5),
ipac_irqEnable returns 0 = OK,
other calls return S_IPAC_notImplemented.
*/
LOCAL int irqCmd (
void *private,
ushort_t slot,
ushort_t irqNumber,
ipac_irqCmd_t cmd
) {
static const int irqLevel[SLOTS][IPAC_IRQS] = {
IRQ_A0, IRQ_A1,
IRQ_B0, IRQ_B1,
IRQ_C0, IRQ_C1,
IRQ_D0, IRQ_D1
};
switch (cmd) {
case ipac_irqGetLevel:
return irqLevel[slot][irqNumber];
case ipac_irqEnable:
sysIntEnable(irqLevel[slot][irqNumber]);
return OK;
default:
return S_IPAC_notImplemented;
}
}
/******************************************************************************/
/* IPAC Carrier Table */
ipac_carrier_t vipc610 = {
"GreenSpring VIPC610-01",
SLOTS,
initialise,
NULL,
baseAddr,
irqCmd
};

View File

@@ -1,690 +0,0 @@
/* drvVmi2534.c */
/* share/src/drv @(#)drvVmic2534.c 1.1 003/22/94 */
#ifndef lint
static char rcsid[] =
"@(#) /babar/CVSROOT/epics/base/src/drv/old/drvVmi2534.c,v 1.1 1996/01/09 19:54:35 lewis Exp(LBL)";
#endif
/*
* routines used to test and interface with V.M.I.C. VMIVME-2534
* digital i/o module
*
* Author: Bill Brown
* Date: 03/22/94
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1994, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (DE-AC03-76SF00) at Lawrence Berkeley Laboratory.
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* Control System Group
* Advanced Light Source
* Lawrence Berkeley Laboratory
*
* Co-developed with
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* NOTES:
* This code is/was cloned from "drvXy240.c" of EPICS R3.11
*
* Data direction is dynamically assigned at ioInit() time.
* The definition of the first bit(s) in a given byte will
* determine the data direction of all bits within that byte.
*
* Modification Log:
*
*
@(#) drvVmi2534.c,v
@(#) Revision 1.1 1996/01/09 19:54:35 lewis
@(#) Add PAL record. Remove APS eg/er records.
@(#) Add 4 STAR drivers, LBL 2534, and preliminaries for LBL/SLAC 9210/9325 drivers.
@(#)
* Revision 1.1.1.1 1995/07/25 21:49:57 lewis
* Baseline import R3.12 w/LBL drivers and mods.
*
* Revision 1.5 1994/09/28 09:05:51 wbrown
* at beginning of init function, ctrl reg is set to match
* SYS_RESET* condition.
*
* Revision 1.4 94/09/27 09:44:31 wbrown
* changed order of "writes to '2534 hardware during initialization
* to prevent undesired output transistions when calculating
* "output correction factor."
*
* Revision 1.3 94/08/19 15:16:14 wbrown
* added debug #ifdef, printf statements
* fixed initialization of record definition structure
*
* Revision 1.2 94/07/20 09:25:26 wbrown
* modified to dynamically assign data direction at
* record init time.
*
* Revision 1.1 94/05/27 09:57:51 wbrown
* Initial revision
*
*
*/
#include <vxWorks.h>
#include <taskLib.h>
#include <types.h>
#include <vme.h>
#include "dbDefs.h"
#include "errlog.h"
#include "errlog.h"
#include "module_types.h"
#include "task_params.h"
#include "drvSup.h"
#include "dbDefs.h"
#include "dbScan.h"
#include "taskwd.h"
#define VMIC_2534_ADDR0 (bi_addrs[VMIC_2534_BI])
#define VMIC_2534_MAX_CARDS (bi_num_cards[VMIC_2534_BI])
#define VMIC_2534_MAX_CHANS (bi_num_channels[VMIC_2534_BI])
/* control-status register
bit definiitions */
#define BYTE_0_OUT_ENA 1<<0
#define BYTE_1_OUT_ENA 1<<1
#define BYTE_2_OUT_ENA 1<<2
#define BYTE_3_OUT_ENA 1<<3
#define FAIL_LED_OFF 1<<5
#define TM1_ENABLE 1<<7
#define TM2_ENABLE 1<<6
/* Refer to VMIVME-2534 manual for hardware options */
/* These boards are available in two configurations; */
/* "POSITIVE-TRUE Option" - writing a "1" to the output register */
/* "TURNS ON the output driver, ie pulls the output LOW */
/* "NEGATIVE-TRUE Option" - writing a "1" to the output register */
/* "TURNS OFF" the output driver, allowing the load to pull */
/* the output HIGH. */
/* The initialization routine recognizes which type of board is */
/* installed and generates a mask which is used by the device- */
/* driver to cause BOTH board types to appear to have the */
/* POSITIVE-TRUE Option installed. */
#define FAIL_FLAG 1<<5
/* Test Mode */
#define TM2 1<<6 /* TM2 - "1" = disable test buffers */
#define TM1 1<<7 /* TM1 - "1" = enable output drivers */
#define masks( K ) ((1<<K))
/* VMIVME-2534 memory structure */
/* Data direction is dynamically assigned at ioInit() time. */
/* The definition of the first bit(s) in a given byte will */
/* determine the data direction of all bits within that byte. */
typedef struct
{
u_long pioData;
u_char brdIdReg;
u_char ctlStatReg;
u_char endPad[2];
} VMIC_2534 ;
/* VMIVME-2534 control structure record */
typedef struct
{
VMIC_2534 *vmicDevice; /* pointer to the hardware */
short deviceNr; /* device number */
u_long savedInputs; /* previous input value */
u_long outputCorrector; /* polarity correction factor */
u_long inputMask; /* and-mask for input bytes */
u_long outputMask; /* and-mask for output bytes */
IOSCANPVT ioscanpvt;
} VMIC_2534_REC ;
VMIC_2534_REC *vmic2534Rec; /* points to control structures */
static long report( );
static long init( );
struct
{
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvVmi2534 =
{
2,
report,
init
} ;
static
long report( int level)
{
vmic2534_io_report( level );
return( 0 );
}
void vmic2534BiReport( int card );
void vmic2534BoReport( int card );
static long init( )
{
vmic2534Init( );
return( 0 );
}
/*
*
* This hardware does not support interrupts
*
* NO interrupt service routine is applicable
*/
/*
*
* vmic2534IOScan
*
* task to check of a change of state
* (used to simulate "change-of-state" interrupts)
*
*/
vmic2534IOScan( )
{
int i;
int firstScan = TRUE;
long temp;
for ( ; ; )
{
if ( interruptAccept ) break;
taskDelay( vxTicksPerSecond/30 );
}
for ( ; ; )
{
for ( i = 0; i < VMIC_2534_MAX_CARDS; i++ )
{
if ( vmic2534Rec[ i ].vmicDevice )
{
temp = ( vmic2534Rec[ i ].vmicDevice->pioData )
& ( vmic2534Rec[ i ].inputMask );
if ( (temp ^ vmic2534Rec[ i ].savedInputs) || firstScan )
{
scanIoRequest( vmic2534Rec[ i ].ioscanpvt );
vmic2534Rec[ i ].savedInputs = temp;
}
}
}
if ( firstScan )
firstScan = FALSE;
taskDelay( vxTicksPerSecond/30 );
}
}
/*
* DIO DRIVER INIT
*
*/
vmic2534Init( )
{
u_long dummy;
register short i;
VMIC_2534 *theHardware;
int tid;
int status;
int atLeastOnePresent = FALSE;
/*
* allow for runtime reconfiguration of the addr map
*/
vmic2534Rec = (VMIC_2534_REC *)calloc(
VMIC_2534_MAX_CARDS, sizeof( VMIC_2534_REC ) );
if ( !vmic2534Rec )
{
logMsg("Attempt to calloc \"VMIC_2534_REC\" failed\n");
return( ERROR );
}
status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, (VMIC_2534_ADDR0),
&theHardware );
if ( status != OK )
{
logMsg("%s: Unable to map VMIC_2534 base addr\n", __FILE__);
return( ERROR );
}
for ( i = 0; i < VMIC_2534_MAX_CARDS; i++, theHardware++ )
{
if ( (vxMemProbe( theHardware, READ, 2 ,&dummy )) != OK )
{
vmic2534Rec[i].vmicDevice = NULL;
continue;
}
else
/* initialize hardware */
{
/* Outputs/Inputs are undetermined at this time */
/* Disable output drivers in case of no SYS_RESET* */
theHardware->ctlStatReg = 0;
/* determine "sense" of output and save correction factor */
theHardware->pioData = 0;
vmic2534Rec[i].outputCorrector = theHardware->pioData;
/* clear input & output masks, (malloc'ed mem may != 0) */
vmic2534Rec[i].inputMask = 0;
vmic2534Rec[i].outputMask = 0;
/* insure that outputs are initially "OFF", i.e. HIGH */
theHardware->pioData = vmic2534Rec[i].outputCorrector;
theHardware->ctlStatReg = TM1 | TM2 | FAIL_LED_OFF;
/*
* record structure initalization
*/
vmic2534Rec[ i ].vmicDevice = theHardware;
atLeastOnePresent = TRUE;
scanIoInit( &(vmic2534Rec[ i ].ioscanpvt) );
}
}
if ( atLeastOnePresent)
{
if ( (tid = taskNameToId( VMIC_2534_NAME )) != ERROR )
{
taskwdRemove( tid );
taskDelete( tid );
}
if ( (status = taskSpawn(
VMIC_2534_NAME, VMIC_2534_PRI, VMIC_2534_OPT,
VMIC_2534_STACK, vmic2534IOScan )) == ERROR )
logMsg("Unable to spawn \"vmic2534IOScan( )\" task\n");
else
taskwdInsert( status, NULL, NULL );
}
return( OK );
}
/*
* Set data direction control for specified data bits
* Note:
* Data direction is controlled on a "per-byte" basis.
* The first bit defined within a byte sets the direction for the entire
* byte. Any attempt to define conflicting bits after the direction
* for a byte is set will return an error (-1) response.)
* Permmissable values for "direction" are:
* direction == 0 indicates input
* direction != 0 indicates output
*
*/
vmic2534_setIOBitDirection( short card, u_int mask, u_int direction )
{
int status = 0;
u_long work, j;
static u_long maskTbl[ ] =
{ 0x000000ff,
0x0000ff00,
0x00ff0000,
0xff000000
};
if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) )
status = -1 ;
else
{
if ( direction == 0)
{
/* INPUT */
#ifdef DEBUG_2534
printf("Mask = %08x, outPutMask =%08x\n",
mask, vmic2534Rec[ card ].outputMask);
#endif DEBUG_2534
if ( ((u_long)mask & vmic2534Rec[ card ].outputMask) == 0 )
{
for ( j = 0; j < 4; j++ )
{
if ( ( (u_long)mask & maskTbl[ j ] ) != 0 )
{
vmic2534Rec[ card ].inputMask |= maskTbl[ j ];
#ifdef DEBUG_2534
printf("inputMask = %08x\n",
vmic2534Rec[ card ].inputMask);
#endif DEBUG_2534
vmic2534Rec[ card ].vmicDevice->ctlStatReg
&= (u_char) ~(1 << j);
}
}
}
else
{
status = -1;
}
}
else
{
/* OUTPUT */
#ifdef DEBUG_2534
printf("Mask = %08x, inputMask =%08x\n",
mask, vmic2534Rec[ card ].inputMask);
#endif DEBUG_2534
if ( ((u_long)mask & vmic2534Rec[ card ].inputMask) == 0 )
{
for ( j = 0; j < 4; j++ )
{
if ( ( (u_long)mask & maskTbl[ j ] ) != 0 )
{
vmic2534Rec[ card ].outputMask |= maskTbl[ j ];
#ifdef DEBUG_2534
printf("outputMask = %08x\n",
vmic2534Rec[ card ].outputMask);
#endif DEBUG_2534
vmic2534Rec[ card ].vmicDevice->ctlStatReg
|= (u_char)(1 << j);
}
}
}
else
{
status = -1;
}
}
}
return( status );
}
vmic2534_getioscanpvt( short card, IOSCANPVT *scanpvt )
{
if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) )
return( -1 );
*scanpvt = vmic2534Rec[ card ].ioscanpvt;
return( 0 );
}
/*
* VMEVMIC_BI_DRIVER
*
* interface binary inputs
*/
vmic2534_bi_driver( register short card,
u_int mask,
register u_int * prval )
{
if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) )
return( -1 );
*prval = (u_int)( (vmic2534Rec[ card ].vmicDevice->pioData)
& (vmic2534Rec[ card ].inputMask) )
& mask;
return( 0 );
}
/*
* vmic2534_bo_read
*
* (read) interface to binary outputs
*
*/
vmic2534_bo_read( register short card,
u_int mask,
register u_int * prval )
{
if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) )
return( -1 );
*prval = (u_int)(~( ( (vmic2534Rec[ card ].vmicDevice->pioData)
& (vmic2534Rec[ card ].outputMask) )
^ vmic2534Rec[card].outputCorrector) ) & mask;
return( 0 );
}
/*
* vmic2534_bo_driver
*
* (write) interface to binary outputs
*/
vmic2534_bo_driver( register short card,
register u_int val,
u_int mask )
{
u_long work;
if ( (card >= VMIC_2534_MAX_CARDS) || !(vmic2534Rec[ card ].vmicDevice) )
return( ERROR );
#ifndef DEBUGTHIS
vmic2534Rec[ card ].vmicDevice->pioData =
( ( ( ~(vmic2534Rec[ card ].vmicDevice->pioData) & (u_long)~mask)
| (u_long)(val & mask) ) ^ vmic2534Rec[card].outputCorrector )
& vmic2534Rec[ card ].outputMask;
#else
printf("Data = 0x%x, mask = 0x%x, corrector = 0x%x\n",
val, mask, vmic2534Rec[card].outputCorrector);
work = vmic2534Rec[ card ].vmicDevice->pioData;
printf("Current raw i/o data = 0x%x, output mask = 0x%x\n",
work, vmic2534Rec[ card ].outputMask);
work = ~work;
printf("Corrected output data = 0x%x\n", work);
work &= ( (u_long)~mask );
printf("Masked data = 0x%x\n", work);
work |= ( (u_long)(val & mask) );
printf("New output data = 0x%x\n", work);
work ^= vmic2534Rec[card].outputCorrector;
printf("Polarity-corrected output data = 0x%x\n", work);
work &= vmic2534Rec[ card ].outputMask;
printf("Output data masked to output bits only = 0x%x\n", work);
vmic2534Rec[ card ].vmicDevice->pioData = work;
printf("*\n");
#undef DEBUGTHIS
#endif DEBUGTHIS
return( OK );
}
/*
* vmiv2534Out
*
* test routine for vm1c2534 output
*/
vmiv2534Out( short card,
u_long val )
{
/* check for valid card nr */
if ( card >= VMIC_2534_MAX_CARDS )
{
logMsg("card # out of range/n");
return( -1 );
}
/* check for card actually installed */
if ( !(vmic2534Rec[ card ].vmicDevice) )
{
logMsg("card #%d not found\n", card);
return( -2 );
}
/* set the physical output */
vmic2534Rec[ card ].vmicDevice->pioData
= vmic2534Rec[ card ].outputCorrector ^ val;
return( OK );
}
/*
* vmic2534Write
*
* command line interface to test bo driver
*/
vmic2534Write( short card,
u_int val )
{
return( vmic2534_bo_driver( card, val, 0xffff ) );
}
long
vmic2534_io_report( short level )
{
int card;
for ( card = 0; card < VMIC_2534_MAX_CARDS; card++ )
{
if ( vmic2534Rec[ card ].vmicDevice )
{
printf("B*: vmic2534:\tcard%d\n", card);
if( level >= 1 )
{
vmic2534_bi_io_report( card );
vmic2534_bo_io_report( card );
}
}
}
}
void
vmic2534_bi_io_report( int card )
{
short int num_chans,j,k,l,m,status;
int ival,jval,kval,lval,mval;
unsigned int *prval;
num_chans = VMIC_2534_MAX_CHANS;
if( !vmic2534Rec[card].vmicDevice )
return;
printf("\tVMEVMI-2534 BINARY IN CHANNELS:\n");
for( j=0, k=1, l=2, m=3;
j < num_chans, k < num_chans, l< num_chans, m < num_chans;
j+=IOR_MAX_COLS, k+= IOR_MAX_COLS, l+= IOR_MAX_COLS,
m += IOR_MAX_COLS )
{
if( j < num_chans )
{
vmic2534_bi_driver( card, masks( j ), &jval );
if ( jval != 0 )
jval = 1;
printf("\tChan %d = %x\t ", j, jval);
}
if( k < num_chans )
{
vmic2534_bi_driver( card, masks( k ), &kval );
if ( kval != 0)
kval = 1;
printf("Chan %d = %x\t ", k, kval);
}
if( l < num_chans )
{
vmic2534_bi_driver( card, masks( l ), &lval );
if ( lval != 0 )
lval = 1;
printf("Chan %d = %x \t", l, lval);
}
if( m < num_chans)
{
vmic2534_bi_driver( card, masks( m ), &mval );
if ( mval != 0 )
mval = 1;
printf("Chan %d = %x \n", m, mval);
}
}
}
void
vmic2534_bo_io_report( int card )
{
short int num_chans,j,k,l,m,status;
int ival,jval,kval,lval,mval;
unsigned int *prval;
num_chans = VMIC_2534_MAX_CHANS;
if( !vmic2534Rec[card].vmicDevice )
return;
printf("\tVMEVMI-2534 BINARY OUT CHANNELS:\n");
for( j=0, k=1, l=2, m=3;
j < num_chans, k < num_chans, l< num_chans, m < num_chans;
j+=IOR_MAX_COLS, k+= IOR_MAX_COLS, l+= IOR_MAX_COLS,
m += IOR_MAX_COLS )
{
if( j < num_chans )
{
vmic2534_bo_read( card, masks( j ), &jval );
if ( jval != 0 )
jval = 1;
printf("\tChan %d = %x\t ", j, jval);
}
if( k < num_chans )
{
vmic2534_bo_read( card, masks( k ), &kval );
if ( kval != 0)
kval = 1;
printf("Chan %d = %x\t ", k, kval);
}
if( l < num_chans )
{
vmic2534_bo_read( card, masks( l ), &lval );
if ( lval != 0 )
lval = 1;
printf("Chan %d = %x \t", l, lval);
}
if( m < num_chans)
{
vmic2534_bo_read( card, masks( m ), &mval );
if ( mval != 0 )
mval = 1;
printf("Chan %d = %x \n", m, mval);
}
}
}

View File

@@ -1,532 +0,0 @@
/* $Id$
*
* VXI standard defines
*
* 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:
* -----------------
* .01 joh 021490 changed NVXIADDR to 32 before formal release
* .02 joh 120591 reorganized to support nivxi
* .03 joh 010892 added message based device registers and
* commands
* .04 joh 013091 moved some of the slot 0 stuff here
* .05 joh 070692 added KSC manufacturer id
* .06 joh 070692 added address space defines
* .07 joh 081992 added csr typedef
* .08 joh 071593 typedef for device registers
* .09 joh 051995 fixed incorrect MBC_TOP_LEVEL_CMDR def
*
*/
#ifndef INCepvxih
#define INCepvxih
#include <sys/types.h>
/*
* offset from the bottom of VME short addr of
* VXI logical address space
*/
#define VXIBASEADDR 0xc000
typedef volatile uint16_t vxi16_t;
typedef volatile uint8_t vxi8_t;
/*
* set NVXIADDR to less than 0x100 since other VME modules
* currently live in VXI address space
*/
#define NVXIADDR (0x100)
#define NVXISLOTS 13
#define VXIDYNAMICADDR (0xff)
#define NVXIADDRBITS 8
#define VXIADDRMASK ((1<<NVXIADDRBITS)-1)
#define VXI_RESMAN_LA 0
#define VXI_NBBY 8
#define VXIDEVBITS 6
#define VXIDEVSIZE (1<<VXIDEVBITS)
#define VXI_LA_TO_PA(LA, VXIBASEADDR) \
( (VXICSR *) (((char *)VXIBASEADDR)+(((unsigned)LA)<<VXIDEVBITS)) )
#define VXI_PA_TO_LA(PA) ( (((unsigned)PA)>>VXIDEVBITS)&VXIADDRMASK )
struct vxi_msg_dev_w{
vxi16_t signal;
vxi16_t dextended;
vxi16_t dhigh;
vxi16_t dlow;
};
struct vxi_mxi_dev_w{
vxi16_t modid;
vxi16_t la_window;
vxi8_t a16_window_high;
vxi8_t a16_window_low;
vxi8_t a24_window_high;
vxi8_t a24_window_low;
vxi8_t a32_window_high;
vxi8_t a32_window_low;
vxi16_t INTX_interrupt;
vxi16_t INTX_trigger;
vxi16_t dd7;
vxi16_t INTX_utility;
vxi16_t dd9;
vxi16_t dd10;
vxi16_t subclass;
vxi16_t control;
vxi16_t lock;
vxi16_t irq;
vxi16_t trigger_drive;
vxi16_t trigger_mode;
vxi16_t interrupt;
vxi16_t status_id;
vxi16_t trigger_config;
vxi16_t trigger_sync_ack;
vxi16_t trigger_async_ack;
vxi16_t irq_ack;
};
struct vxi_reg_dev_w{
vxi16_t ddx08;
vxi16_t ddxoa;
vxi16_t ddx0c;
vxi16_t ddx0e;
vxi16_t ddx10;
vxi16_t ddx12;
vxi16_t ddx14;
vxi16_t ddx16;
vxi16_t ddx18;
vxi16_t ddx1a;
vxi16_t ddx1c;
vxi16_t ddx1e;
vxi16_t ddx20;
vxi16_t ddx22;
vxi16_t ddx24;
vxi16_t ddx26;
vxi16_t ddx28;
vxi16_t ddx2a;
vxi16_t ddx2c;
vxi16_t ddx2e;
};
struct vxi_reg_slot0_dev_w{
vxi16_t modid;
vxi16_t ddxoa;
vxi16_t ddx0c;
vxi16_t ddx0e;
vxi16_t ddx10;
vxi16_t ddx12;
vxi16_t ddx14;
vxi16_t ddx16;
vxi16_t ddx18;
vxi16_t ddx1a;
vxi16_t ddx1c;
vxi16_t ddx1e;
vxi16_t ddx20;
vxi16_t ddx22;
vxi16_t ddx24;
vxi16_t ddx26;
vxi16_t ddx28;
vxi16_t ddx2a;
vxi16_t ddx2c;
vxi16_t ddx2e;
};
struct vxi_csr_w{
vxi16_t addr;
vxi16_t pad0;
vxi16_t control;
vxi16_t offset;
union {
struct vxi_msg_dev_w msg;
struct vxi_mxi_dev_w mxi;
struct vxi_reg_dev_w reg;
struct vxi_reg_slot0_dev_w reg_s0;
}dd;
};
struct vxi_msg_dev_r{
vxi16_t protocol;
vxi16_t response;
vxi16_t dhigh;
vxi16_t dlow;
};
struct vxi_mxi_dev_r{
vxi16_t modid;
vxi16_t la_window;
vxi16_t a16_window;
vxi16_t a24_window;
vxi16_t a32_window;
vxi16_t dd5;
vxi16_t dd6;
vxi16_t dd7;
vxi16_t dd8;
vxi16_t dd9;
vxi16_t dd10;
vxi16_t subclass;
vxi16_t status;
vxi16_t lock;
vxi16_t irq;
vxi16_t read_la;
vxi16_t trigger_mode;
vxi16_t interrupt;
vxi16_t status_id;
vxi16_t trigger_config;
vxi16_t trigger_sync_ack;
vxi16_t trigger_async_ack;
vxi16_t irq_ack;
};
struct vxi_reg_dev_r{
vxi16_t ddx08;
vxi16_t ddxoa;
vxi16_t ddx0c;
vxi16_t ddx0e;
vxi16_t ddx10;
vxi16_t ddx12;
vxi16_t ddx14;
vxi16_t ddx16;
vxi16_t ddx18;
vxi16_t ddx1a;
vxi16_t ddx1c;
vxi16_t ddx1e;
vxi16_t ddx20;
vxi16_t ddx22;
vxi16_t ddx24;
vxi16_t ddx26;
vxi16_t ddx28;
vxi16_t ddx2a;
vxi16_t ddx2c;
vxi16_t ddx2e;
};
struct vxi_reg_slot0_dev_r{
vxi16_t modid;
vxi16_t ddxoa;
vxi16_t ddx0c;
vxi16_t ddx0e;
vxi16_t ddx10;
vxi16_t ddx12;
vxi16_t ddx14;
vxi16_t ddx16;
vxi16_t ddx18;
vxi16_t ddx1a;
vxi16_t ddx1c;
vxi16_t ddx1e;
vxi16_t ddx20;
vxi16_t ddx22;
vxi16_t ddx24;
vxi16_t ddx26;
vxi16_t ddx28;
vxi16_t ddx2a;
vxi16_t ddx2c;
vxi16_t ddx2e;
};
struct vxi_csr_r{
vxi16_t make;
vxi16_t model;
vxi16_t status;
vxi16_t offset;
union {
struct vxi_msg_dev_r msg;
struct vxi_mxi_dev_r mxi;
struct vxi_reg_dev_r reg;
struct vxi_reg_slot0_dev_r reg_s0;
}dd;
};
struct vxi_csr{
union {
struct vxi_csr_w w;
struct vxi_csr_r r;
}dir;
};
typedef struct vxi_csr VXICSR;
#define CSRRMEM(PSR,MEMBER) ( ((VXICSR *)(PSR))->MEMBER )
/*
* Reserved device types
*/
#define VXIMODELMASK(WD) ( (WD)&0xfff )
#define VXIMODEL(PSR) ( (unsigned) VXIMODELMASK(CSRRMEM(PSR,dir.r.model)) )
#define VXIMAKE(PSR) ( (unsigned) 0xfff&CSRRMEM(PSR,dir.r.make) )
#define VXISLOT0MODELTEST(WD) ((WD)<0x100)
#define VXISLOT0MODEL(PCSR) (VXISLOT0MODELTEST(VXIMODEL(PCSR)))
/*
* vxi device classes
*/
#define VXI_MEMORY_DEVICE 0
#define VXI_EXTENDED_DEVICE 1
#define VXI_MESSAGE_DEVICE 2
#define VXI_REGISTER_DEVICE 3
#define VXICLASS(PSR) ((unsigned)(0xc000&CSRRMEM(PSR,dir.r.make))>>14)
#define VXISUBCLASS(PSR) ((unsigned)CSRRMEM(PSR,dir.r.dd.mxi.subclass) )
#define VXIMXI(PSR)\
(VXICLASS(PSR)==VXI_EXTENDED_DEVICE ? VXISUBCLASS(PSR)==VXI_MXI_DEVICE : 0)
#define VXI_MXI_DEVICE 0xfffc
#define MXI_BASE_DEVICE 0xf
#define MXI_INTX_DEVICE 0xe
#define MXI_EXTENDED_TYPE(PSR) ((((unsigned)CSRRMEM(PSR,dir.r.status))>>10)&0xf)
#define MXIINTX(PSR) (MXI_EXTENDED_TYPE(PSR) == MXI_INTX_DEVICE)
#ifndef SRCepvxiLib
extern
#endif
char *vxi_device_class_names[]
#ifdef SRCepvxiLib
= {
"memory",
"extended",
"message",
"register"}
#endif
;
/*
* A32/A24 address space
*/
#define VXIADDRSPACE(PSR) ( (unsigned long) 3&(CSRRMEM(PSR,dir.r.make)>>12) )
#define VXIREQMEM(PSR) ( (unsigned long) 0xf&(CSRRMEM(PSR,dir.r.model)>>12) )
#define VXIA24MEMSIZE(M) ( (long) 1<<(23-(M)) )
#define VXIA32MEMSIZE(M) ( (long) 1<<(31-(M)) )
#define VXI_ADDR_EXT_A24 0
#define VXI_ADDR_EXT_A32 1
#define VXI_ADDR_EXT_NONE 3
/*
*
* VXI vendor codes
*
*/
#define VXI_MAKE_HP 0xfff /* Hewlett Packard */
#define VXI_MAKE_RD 0xffb /* Racal Dana */
#define VXI_MAKE_NI 0xff6 /* National Instruments */
#define VXI_MAKE_LANSCE5 0xfa0 /* Los Alamos Natl Lab LANSCE-5 */
#define VXI_MAKE_KSC 0xf29 /* Kinetic Systems */
struct vxi_vendor_info{
uint16_t make;
char *pvendor_name;
};
/*
* In decreasing order of vendor id
*/
#ifndef SRCepvxiLib
extern
#endif
struct vxi_vendor_info vxi_vi[]
#ifdef SRCepvxiLib
= {
{VXI_MAKE_HP, "Hewlett-Packard"},
{VXI_MAKE_RD, "Racal-Dana"},
{VXI_MAKE_NI, "National Instruments"},
{VXI_MAKE_LANSCE5, "LANL LANSCE-5"},
{VXI_MAKE_KSC, "Kinetic Systems"},
}
#endif
;
/*
* MXI commands
* (for the MXI control register)
*/
#define MXI_UPPER_LOWER_BOUNDS 0x4000
#define MXI_LA_WINDOW_SIZE_MASK 0x3
#define MXIA24MASK (0xffff)
#define MXIA24MASKSIZE 16
#define MXIA32MASK (0xffffff)
#define MXIA32MASKSIZE 24
#define MXIA24ALIGN(A) (((unsigned long)(A)+MXIA24MASK)&~MXIA24MASK)
#define MXIA32ALIGN(A) (((unsigned long)(A)+MXIA32MASK)&~MXIA32MASK)
/*
* applies to all vxi devices
*/
#define VXIMEMENBLMASK (0x8000)
#define VXIMEMENBL(PSR) (VXIMEMENBLMASK&CSRRMEM(PSR,dir.r.status))
#define VXINDCDEVICESMASK (0xff)
#define VXINDCDEVICES(PSR) (VXINDCDEVICESMASK&CSRRMEM(PSR,dir.r.offset))
/*
* Register based slot zero
*/
#define VXIMODIDSTATUS(WD) ((WD)&0x4000?FALSE:TRUE)
#define VXIPASS 3
#define VXIPASSEDSTATUS(WD) (((WD)>>2)&VXIPASS)
/*
* RULE C.4.4
*
* The resource manager shall write all ones to the
* device dependent bits when writing to the control register
*
*/
#define VXISAFECONTROL 0x7fff /* sys fail inhibit, reset, no mem enbl */
#define VXIMEMENBLCONTROL 0xfffc /* mem enbl, no sys fail inhibit, no reset */
#define VXI_SET_REG_MODID(PCSR, SLOT) \
( ((VXICSR *)(PCSR))->dir.w.dd.reg_s0.modid = \
0x2000|1<<(SLOT) )
#define VXI_CLR_ALL_REG_MODID(PCSR) \
( ((VXICSR *)(PCSR))->dir.w.dd.reg_s0.modid = 0 )
/*
* vxi msg based functions
*/
#define VXIWRITEREADYMASK (0x0200)
#define VXIREADREADYMASK (0x0400)
#define VXIDIRMASK (0x1000)
#define VXIDORMASK (0x2000)
#define VXIFHSMMASK (0x0100)
#define VXIERRNOTMASK (0x0800)
#define VXICMDRMASK (0x8000)
#define VXICMDR(PSR) (!(VXICMDRMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)))
#define VXIFHSMASK (0x0800)
#define VXIFHS(PSR) (!(VXIFHSMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)))
#define VXISHMMASK (0x0400)
#define VXISHM(PSR) (!(VXISHMMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)))
#define VXIMBINTMASK (0x1000)
#define VXIMBINT(PSR) (VXIMBINTMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol))
#define VXIVMEBMMASK (0x2000)
#define VXIVMEBM(PSR) (!(VXIVMEBMMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)))
#define VXISIGREGMASK (0x4000)
#define VXISIGREG(PSR) (!(VXISIGREGMASK&CSRRMEM(PSR,dir.r.dd.msg.protocol)))
/*
* serial protocol errors
*/
#define MBE_NO_ERROR (0xff)
#define MBE_MULTIPLE_QUERIES (0xfd)
#define MBE_UNSUPPORTED_CMD (0xfc)
#define MBE_DIR_VIOLATION (0xfb)
#define MBE_DOR_VIOLATION (0xfa)
#define MBE_RR_VIOLATION (0xf9)
#define MBE_WR_VIOLATION (0xf8)
/*
* vxi message based commands
*/
#define MBC_BEGIN_NORMAL_OPERATION 0xfcff
#define MBC_TOP_LEVEL_CMDR 0x0100
#define MBC_READ_SERVANT_AREA 0xceff
#define MBC_BA 0xbc00
#define MBC_BR 0xdeff
#define MBC_END 0x0100
#define MBC_READ_PROTOCOL 0xdfff
#define MBC_ASSIGN_INTERRUPTER_LINE 0xaa00
#define MBC_READ_INTERRUPTERS 0xcaff
#define MBC_READ_PROTOCOL_ERROR 0xcdff
#define MBC_GRANT_DEVICE 0xbf00
#define MBC_IDENTIFY_COMMANDER 0xbe00
#define MBC_CLEAR 0xffff
/*
* async mode control commands
*/
#define MBC_ASYNC_MODE_CONTROL 0xa800
#define MBC_AMC_RESP_ENABLE 0x0000
#define MBC_AMC_RESP_DISABLE 0x0008
#define MBC_AMC_EVENT_ENABLE 0x0000
#define MBC_AMC_EVENT_DISABLE 0x0004
#define MBC_AMC_RESP_INT_ENABLE 0x0000
#define MBC_AMC_RESP_SIGNAL_ENABLE 0x0002
#define MBC_AMC_EVENT_INT_ENABLE 0x0000
#define MBC_AMC_EVENT_SIGNAL_ENABLE 0x0001
/*
* control resp command
* (enable all)
*/
#define MBC_CONTROL_RESPONSE 0x8fc0
/*
* msg based responses
*/
#define MBR_STATUS(RESP) (((RESP)>>12) & 0xf)
#define MBR_STATUS_SUCCESS 0xf
#define MBR_READ_SERVANT_AREA_MASK 0x00ff
#define MBR_CR_CONFIRM_MASK 0x007f
/*
* read interrupters response
*/
#define MBR_READ_INTERRUPTERS_MASK 0x7
/*
* async mode control resp
*/
#define MBR_AMC_CONFIRM_MASK 0xf
/*
* begin normal operation message based responses
*/
#define MBR_BNO_STATE(RESP) (((RESP)>>8) & 0xf)
#define MBR_BNO_STATE_NO 0xf
/*
* read protocol message based responses
*/
#define MBR_RP_LW(RESP) (!((RESP)&0x1))
#define MBR_RP_ELW(RESP) (!((RESP)&0x2))
#define MBR_RP_I(RESP) (!((RESP)&0x4))
#define MBR_RP_I4(RESP) (!((RESP)&0x8))
#define MBR_RP_TRG(RESP) (!((RESP)&0x10))
#define MBR_RP_PH(RESP) (!((RESP)&0x20))
#define MBR_RP_PI(RESP) (!((RESP)&0x40))
#define MBR_RP_EG(RESP) (!((RESP)&0x100))
#define MBR_RP_RG(RESP) (!((RESP)&0x200))
#define MBR_REV_12(RESP) (!((RESP)&0x8000))
/*
* protocol events
* vxi spec E.4
*/
#define MBE_EVENT_TEST(EVENT) ((EVENT)&0x1000)
/*
* vxi trigger constants
*/
#define VXI_N_TTL_TRIGGERS 8
#define VXI_N_ECL_TRIGGERS 6
#define MXI_ECL0_ENABLE 0x0800
#define MXI_ECL0_FP_TO_BP 0x0400
#define MXI_ECL0_BP_TO_FP 0
#define MXI_ECL1_ENABLE 0x2000
#define MXI_ECL1_FP_TO_BP 0x1000
#define MXI_ECL1_BP_TO_FP 0
#endif /* INCvxih */

View File

@@ -1,33 +0,0 @@
#ifndef INCipModulesH
#define INCipModulesH
#define IP_MANUFACTURER_GREENSPRING 0xf0
#define IP_MODEL_GS_PRECISION_ADC 0x15
#define IP_MODEL_GS_PRECISION_ADC_N "ADC"
#define IP_MODEL_GS_QUAD_SERIAL 0x37
#define IP_MODEL_GS_QUAD_SERIAL_N "Quad_Serial"
#define IP_MODEL_GS_OCTAL_SERIAL 0x22
#define IP_MODEL_GS_OCTAL_SERIAL_N "Octal_Serial"
#define IP_MODEL_GS_SERIAL 0x10
#define IP_MODEL_GS_SERIAL_N "Serial"
#define IP_MODEL_GS_QUADRATURE 0x41
#define IP_MODEL_GS_QUADRATURE_N "Quadrature"
#define IP_MODEL_GS_488 0x14
#define IP_MODEL_GS_488_N "ip488"
#define IP_MANUFACTURER_TEWS 0xb3
#define IP_MODEL_TEWS_TIP810 0x01
#endif /* INCipModulesH */

View File

@@ -1,89 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
ipic.h
Description:
IndustryPack Interface Controller ASIC header file, giving the register
layout and programming model for the IPIC chip used on the MVME162.
Author:
Andrew Johnson
Created:
6 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef INCipicH
#define INCipicH
#include <types.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Chip Registers */
#define IPIC_CHIP_ID 0x23
#define IPIC_CHIP_REVISION 0x00
/* Interrupt Control Register bits */
#define IPIC_INT_LEVEL 0x07
#define IPIC_INT_ICLR 0x08
#define IPIC_INT_IEN 0x10
#define IPIC_INT_INT 0x20
#define IPIC_INT_EDGE 0x40
#define IPIC_INT_PLTY 0x80
/* General Control Registers bits */
#define IPIC_GEN_MEN 0x01
#define IPIC_GEN_WIDTH 0x0c
#define IPIC_GEN_WIDTH_8 0x04
#define IPIC_GEN_WIDTH_16 0x08
#define IPIC_GEN_WIDTH_32 0x00
#define IPIC_GEN_RT 0x30
#define IPIC_GEN_RT_0 0x00
#define IPIC_GEN_RT_2 0x10
#define IPIC_GEN_RT_4 0x20
#define IPIC_GEN_RT_8 0x30
#define IPIC_GEN_ERR 0x80
/* IP Reset register bits */
#define IPIC_IP_RESET 0x01
/* Chip Structure */
typedef struct {
uchar_t chipId;
uchar_t chipRevision;
uchar_t reserved1[2];
ushort_t memBase[4];
uchar_t memSize[4];
uchar_t intCtrl[4][2];
uchar_t genCtrl[4];
uchar_t reserved2[3];
uchar_t ipReset;
} ipic_t;
#ifdef __cplusplus
}
#endif
#endif /* INCipicH */

View File

@@ -1,188 +0,0 @@
/*******************************************************************************
Project:
Gemini/UKIRT CAN Bus Driver for EPICS
File:
pca82c200.h
Description:
Philips Stand-alone CAN-controller chip header file, giving the register
layout and programming model for the chip used on the TIP810 IP module.
Author:
Andrew Johnson
Created:
19 July 1995
(c) 1995 Royal Greenwich Observatory
*******************************************************************************/
#ifndef INCpca82c200H
#define INCpca82c200H
#include <types.h>
#ifdef __cplusplus
extern "C" {
#endif
/***** Control Segment Bit Patterns *****/
/* Control Register */
#define PCA_CR_TM 0x80 /* Test Mode */
#define PCA_CR_S 0x40 /* Synch */
#define PCA_CR_OIE 0x10 /* Overrun Interrupt Enable */
#define PCA_CR_EIE 0x08 /* Error Interrupt Enable */
#define PCA_CR_TIE 0x04 /* Transmit Interrupt Enable */
#define PCA_CR_RIE 0x02 /* Receive Interrupt Enable */
#define PCA_CR_RR 0x01 /* Reset Request */
/* Command Register */
#define PCA_CMR_GTS 0x10 /* Goto Sleep */
#define PCA_CMR_COS 0x08 /* Clear Overrun Status */
#define PCA_CMR_RRB 0x04 /* Release Receive Buffer */
#define PCA_CMR_AT 0x02 /* Abort Transmission */
#define PCA_CMR_TR 0x01 /* Transmission Request */
/* Status Register */
#define PCA_SR_BS 0x80 /* Bus Status */
#define PCA_SR_ES 0x40 /* Error Status */
#define PCA_SR_TS 0x20 /* Transmit Status */
#define PCA_SR_RS 0x10 /* Receive Status */
#define PCA_SR_TCS 0x08 /* Transmission Complete Status */
#define PCA_SR_TBS 0x04 /* Transmit Buffer Status */
#define PCA_SR_DO 0x02 /* Data Overrun */
#define PCA_SR_RBS 0x01 /* Receive Buffer Status */
/* Interrupt Register */
#define PCA_IR_WUI 0x10 /* Wake-Up Interrupt */
#define PCA_IR_OI 0x08 /* Overrun Interrupt */
#define PCA_IR_EI 0x04 /* Error Interrupt */
#define PCA_IR_TI 0x02 /* Transmit Interrupt */
#define PCA_IR_RI 0x01 /* Receive Interrupt */
/* Bus Timing Register 0 */
#define PCA_BTR0_1M6 0x00 /* 1.6 Mbits/sec, 20 m */
#define PCA_BTR0_1M0 0x00 /* 1.0 Mbits/sec, 40 m */
#define PCA_BTR0_500K 0x00 /* 500 Kbits/sec, 130 m */
#define PCA_BTR0_250K 0x01 /* 250 Kbits/sec, 270 m */
#define PCA_BTR0_125K 0x03 /* 125 Kbits/sec, 530 m */
#define PCA_BTR0_100K 0x43 /* 100 Kbits/sec, 620 m */
#define PCA_BTR0_50K 0x47 /* 50 Kbits/sec, 1.3 km */
#define PCA_BTR0_20K 0x53 /* 20 Kbits/sec, 3.3 km */
#define PCA_BTR0_10K 0x67 /* 10 Kbits/sec, 6.7 km */
#define PCA_BTR0_5K 0x7f /* 5 Kbits/sec, 10 km */
#define PCA_KVASER_1M0 0x00 /* 1.0 Mbits/sec, 40 m -- Kvaser standard */
#define PCA_KVASER_500K 0x01 /* 500 Kbits/sec, 130 m -- Kvaser standard */
#define PCA_KVASER_250K 0x03 /* 250 Kbits/sec, 270 m -- Kvaser standard */
#define PCA_KVASER_125K 0x07 /* 125 Kbits/sec, 530 m -- Kvaser standard */
/* Bus Timing Register 1 */
#define PCA_BTR1_1M6 0x11 /* 1.6 Mbits/sec, 20 m */
#define PCA_BTR1_1M0 0x14 /* 1.0 Mbits/sec, 40 m */
#define PCA_BTR1_500K 0x1c /* 500 Kbits/sec, 130 m */
#define PCA_BTR1_250K 0x1c /* 250 Kbits/sec, 270 m */
#define PCA_BTR1_125K 0x1c /* 125 Kbits/sec, 530 m */
#define PCA_BTR1_100K 0x2f /* 100 Kbits/sec, 620 m */
#define PCA_BTR1_50K 0x2f /* 50 Kbits/sec, 1.3 km */
#define PCA_BTR1_20K 0x2f /* 20 Kbits/sec, 3.3 km */
#define PCA_BTR1_10K 0x2f /* 10 Kbits/sec, 6.7 km */
#define PCA_BTR1_5K 0x7f /* 5 Kbits/sec, 10 km */
#define PCA_BTR1_KVASER 0x23 /* All speeds -- Kvaser standard */
/* Output Control Register */
#define PCA_OCR_OCM_NORMAL 0x02
#define PCA_OCR_OCM_CLOCK 0x03
#define PCA_OCR_OCM_BIPHASE 0x00
#define PCA_OCR_OCM_TEST 0x01
#define PCA_OCR_OCT1_FLOAT 0x00
#define PCA_OCR_OCT1_PULLDOWN 0x40
#define PCA_OCR_OCT1_PULLUP 0x80
#define PCA_OCR_OCT1_PUSHPULL 0xc0
#define PCA_OCR_OCT0_FLOAT 0x00
#define PCA_OCR_OCT0_PULLDOWN 0x08
#define PCA_OCR_OCT0_PULLUP 0x10
#define PCA_OCR_OCT0_PUSHPULL 0x18
#define PCA_OCR_OCP1_INVERT 0x20
#define PCA_OCR_OCP0_INVERT 0x04
/* Message Buffers */
#define PCA_MSG_ID0_RSHIFT 3
#define PCA_MSG_ID1_LSHIFT 5
#define PCA_MSG_ID1_MASK 0xe0
#define PCA_MSG_RTR 0x10
#define PCA_MSG_DLC_MASK 0x0f
/***** Chip Structure *****/
/* Message Buffers */
typedef struct {
uchar_t pad0;
uchar_t descriptor0;
uchar_t pad1;
uchar_t descriptor1;
ushort_t data[8];
} msgBuffer_t;
/* Chip Registers */
typedef volatile struct {
uchar_t pad00;
uchar_t control;
uchar_t pad01;
uchar_t command;
uchar_t pad02;
uchar_t status;
uchar_t pad03;
uchar_t interrupt;
uchar_t pad04;
uchar_t acceptanceCode;
uchar_t pad05;
uchar_t acceptanceMask;
uchar_t pad06;
uchar_t busTiming0;
uchar_t pad07;
uchar_t busTiming1;
uchar_t pad08;
uchar_t outputControl;
uchar_t pad09;
uchar_t test;
msgBuffer_t txBuffer;
msgBuffer_t rxBuffer;
uchar_t pad31;
uchar_t clockDivider;
} pca82c200_t;
#ifdef __cplusplus
}
#endif
#endif /* INCpca82c200H */