Compare commits

...

19 Commits

Author SHA1 Message Date
Marty Kraimer
ef12c444d8 Added support for retrieving adapter and card status 1995-04-26 14:16:59 +00:00
Marty Kraimer
cded07df78 Allen Bradley: Add support for retrieving adapter/card status 1995-04-26 13:37:05 +00:00
Marty Kraimer
81fb796c8d Allow record names to start with a digit. 1995-04-26 13:34:33 +00:00
Jeff Hill
b3af9b389a moved ansi drivers 1995-04-26 03:20:39 +00:00
Jeff Hill
9b76f9d9c0 Fix alignment problem found by purify 1995-04-26 03:14:08 +00:00
Jeff Hill
302f4ef6c8 dont send exception msg to all serach requests when the server
runs out of memory (send exception resp only in reply to search
requests that find a match)
1995-04-26 03:12:53 +00:00
Jeff Hill
64b7a679a0 Use vxWorks sem for locks and free lists when fdmgr delete
(none of this is currently used under UNIX)
1995-04-26 03:11:02 +00:00
Jeff Hill
e9624769cb moved already ANSI drivers into the ANSI directory 1995-04-26 03:02:57 +00:00
Jeff Hill
5ccee17d09 ANSI C changes 1995-04-26 03:01:02 +00:00
Jeff Hill
5e67b97e89 reformatted statement and fixed doc 1995-04-26 02:53:11 +00:00
Jeff Hill
7cd16f8ad6 fixed comment 1995-04-26 02:51:02 +00:00
Jeff Hill
b5aa0e300c fixed bug where nill func ptr io block called for get cb at disconnect 1995-04-26 02:49:30 +00:00
Jim Kowalkowski
c27c38d531 New Pentek 4261 support added 1995-04-25 15:49:23 +00:00
Jim Kowalkowski
b46166314f New device support for the Pentek 4261 ADC. 1995-04-25 15:47:21 +00:00
John Winans
593df59742 Changed name of HiDEOS link configuration command/function. 1995-04-25 15:32:23 +00:00
Andrew Johnson
561e2e9fb9 Moved environment parameter defaults to config/CONFIG_ENV 1995-04-24 16:02:24 +00:00
Ned Arnold
18b173eeb6 If reassignable PV ends in .DESC, change to .VAL 1995-04-19 18:58:50 +00:00
John Winans
47b3da99a0 Added support for the HiDEOS system as a GPIB bus transport agent. 1995-04-12 19:31:41 +00:00
cvs2svn
dd0ce8918a This commit was manufactured by cvs2svn to create tag 'R3.12.0-beta12'. 1995-04-07 11:50:22 +00:00
51 changed files with 18161 additions and 447 deletions

View File

@@ -1372,7 +1372,7 @@ int status)
caIOBlockFree (monix);
if (cbRequired) {
if (cbRequired && monix->usr_func) {
(*monix->usr_func) (args);
}
}
@@ -2306,7 +2306,7 @@ void *pfl
* Call user's callback
*/
LOCKEVENTS;
{
if (monix->usr_func) {
struct event_handler_args args;
args.usr = monix->usr_arg;

View File

@@ -134,7 +134,8 @@ typedef float ca_float32_t;
* fields aligned on natural boundaries.
*
* NOTE: all structures declared in this file must have a
* byte count which is evenly divisible by 8 for the SPARC.
* byte count which is evenly divisible by 8 matching
* the largest atomic data type in db_access.h.
*/
#define CA_MESSAGE_ALIGN(A) (OCT_ROUND(A)<<3)

View File

@@ -119,8 +119,8 @@ unsigned long blockSize
if(piiu->curMsgBytes < sizeof(piiu->curMsg)){
char *pHdr;
size = sizeof(piiu->curMsg) - piiu->curMsgBytes;
size = min(size, blockSize);
size = sizeof (piiu->curMsg) - piiu->curMsgBytes;
size = min (size, blockSize);
pHdr = (char *) &piiu->curMsg;
memcpy( pHdr + piiu->curMsgBytes,
@@ -129,7 +129,7 @@ unsigned long blockSize
piiu->curMsgBytes += size;
if(piiu->curMsgBytes < sizeof(piiu->curMsg)){
#if 0
#if 0
printf ("waiting for %d msg hdr bytes\n",
sizeof(piiu->curMsg)-piiu->curMsgBytes);
#endif
@@ -174,7 +174,7 @@ unsigned long blockSize
/*
* make sure we have a large enough message body cache
*/
if(piiu->curMsg.m_postsize>piiu->curDataMax){
if (piiu->curMsg.m_postsize>piiu->curDataMax) {
if(piiu->pCurData){
free(piiu->pCurData);
}
@@ -192,6 +192,8 @@ unsigned long blockSize
/*
* Fetch a complete message body
* (allows for arrays larger than than the
* ring buffer size)
*/
if(piiu->curMsg.m_postsize>piiu->curDataBytes){
char *pBdy;

View File

@@ -1608,6 +1608,7 @@ char *pstring;
DBLINK *plink=(DBLINK *)pfield;
char string[80];
char *pstr=&string[0];
int ind;
if(strlen(pstring)>=sizeof(string)) {
status = S_dbLib_badField;
@@ -1617,6 +1618,11 @@ char *pstring;
strcpy(pstr,pstring);
/*strip off leading blanks and tabs*/
while(*pstr && (*pstr==' ' || *pstr=='\t')) pstr++;
/*strip off trailing blanks and tabs*/
if(pstr) for(ind = strlen(pstr)-1; ind>=0; ind--) {
if(pstr[ind]!=' ' && pstr[ind]!='\t') break;
pstr[ind] = '\0';
}
if(!pstr || strlen(pstr)<=0 ) {
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
if(plink->type!=CONSTANT) return(S_dbLib_badField);
@@ -1628,14 +1634,15 @@ char *pstring;
int pp=0;
int ms=0;
char *end;
char chr;
double tempval;
/* Check first to see if string is a constant*/
chr = pstr[0];
if(isdigit(chr) || chr=='.' || chr=='-' || chr=='+') {
/*It is a double if strtod eats entire string*/
/*Note that leading and trailing blanks have already been stripped*/
tempval = strtod(pstr,&end);
if(*end == 0) {
if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry);
plink->value.value = strtod(pstr,&end);
if(*end!=0) return(S_dbLib_badField);
plink->value.value = tempval;
return(0);
}
if(plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry);

View File

@@ -94,6 +94,7 @@ SRCS.c += ../devWfJoergerVtr1.c
SRCS.c += ../devWfSoft.c
SRCS.c += ../devWfTestAsyn.c
SRCS.c += ../devWfXy566Sc.c
SRCS.c += ../devWfPentek4261.c
SRCS.c += ../devXy240.c
SRCS.c += ../devAB1771IFE.c
@@ -102,6 +103,7 @@ SRCS.c += ../devAB1771IR.c
SRCS.c += ../devAB1771IXE.c
SRCS.c += ../devAB1771OFE.c
SRCS.c += ../devABBINARY.c
SRCS.c += ../devABStatus.c
SRCS.c += ../devMpc.c
# OBJS += devAaiCamac.o
@@ -194,6 +196,7 @@ OBJS += devWfJoergerVtr1.o
OBJS += devWfSoft.o
OBJS += devWfTestAsyn.o
OBJS += devWfXy566Sc.o
OBJS += devWfPentek4261.o
OBJS += devXy240.o
OBJS += devAB1771IFE.o
OBJS += devAB1771IL.o
@@ -201,6 +204,7 @@ OBJS += devAB1771IR.o
OBJS += devAB1771IXE.o
OBJS += devAB1771OFE.o
OBJS += devABBINARY.o
OBJS += devABStatus.o
OBJS += devMpc.o
PROD = devSup

114
src/dev/devABStatus.c Normal file
View File

@@ -0,0 +1,114 @@
/* devABStatus.c */
/*
* Original Authors: Marty Kraimer (nagging by Ned Arnold,Bob dalesio)
* Date: 3/6/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 04-20-95 mrk Initial version
* ...
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dbDefs.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <link.h>
#include <drvAb.h>
#include <mbbiRecord.h>
typedef struct {
void *drvPvt;
IOSCANPVT ioscanpvt;
}devPvt;
/* Create the dsets*/
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_bi;} ABBIDSET;
LOCAL long init_common(struct mbbiRecord *prec);
LOCAL long read_adapter_status(struct mbbiRecord *prec);
LOCAL long read_card_status(struct mbbiRecord *prec);
ABBIDSET devMbbiAbAdapterStat= { 5, 0, 0, init_common, 0, read_adapter_status};
ABBIDSET devMbbiAbCardStat= { 5, 0, 0, init_common, 0, read_card_status};
LOCAL long init_common(struct mbbiRecord *prec)
{
unsigned long *pstate_values;
char *pstate_string;
unsigned short *palarm_sevr;
short i;
if(abFailure>=16) {
epicsPrintf("devMbbiAbLinkStat. > 16 error status values\n");
taskSuspend(0);
return(0);
}
pstate_values = &(prec->zrvl);
pstate_string = prec->zrst;
palarm_sevr = &prec->zrsv;
/*Following code assumes that abFailure is last status value*/
for(i=0; i<=abFailure; i++ ,pstate_string += sizeof(prec->zrst)){
pstate_values[i] = 1<<i;
if(pstate_string[0]=='\0')
strncpy(pstate_string,abStatusMessage[i],sizeof(prec->zrst)-1);
if(i>0) palarm_sevr[i] = MAJOR_ALARM;
}
return(0);
}
LOCAL long read_adapter_status(struct mbbiRecord *prec)
{
abStatus status;
struct abio *pabio;
pabio = (struct abio *)&(prec->inp.value);
status = (*pabDrv->adapterStatus)(pabio->link,pabio->adapter);
prec->rval = 1 << status;;
return(0);
}
LOCAL long read_card_status(struct mbbiRecord *prec)
{
abStatus status;
struct abio *pabio;
pabio = (struct abio *)&(prec->inp.value);
status = (*pabDrv->cardStatus)(pabio->link,pabio->adapter,pabio->card);
prec->rval = 1 << status;;
return(0);
}

View File

@@ -127,12 +127,14 @@ AT5VXIDSET_TM devTmAt5Vxi={6, NULL, NULL, NULL, NULL, read_timer, write_timer};
* Values are converted to seconds.
*/
static double constants[] = {1e3,1e6,1e9,1e12};
static void localPostEvent (void *pParam);
static long read_timer(struct timerRecord *ptimer)
{
struct vmeio *pvmeio;
int source;
int ptst;
unsigned source;
unsigned ptst;
double time_pulse[2]; /* delay and width */
double constant;
@@ -164,22 +166,40 @@ static long read_timer(struct timerRecord *ptimer)
static long write_timer(struct timerRecord *ptimer)
{
struct vmeio *pvmeio;
struct vmeio *pvmeio;
void (*pCB)(void *);
pvmeio = (struct vmeio *)(&ptimer->out.value);
if (ptimer->tevt) {
pCB = localPostEvent;
}
else {
pCB = NULL;
}
/* put the value to the ao driver */
return at5vxi_one_shot(
(int)ptimer->ptst, /* pre-trigger state */
ptimer->t1dl, /* pulse offset */
ptimer->t1wd, /* pulse width */
(int)pvmeio->card, /* card number */
(int)pvmeio->signal, /* signal number */
(int)ptimer->tsrc, /* trigger source */
((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */
(int)ptimer->tevt); /* event to post on trigger */
ptimer->ptst, /* pre-trigger state */
ptimer->t1dl, /* pulse offset */
ptimer->t1wd, /* pulse width */
pvmeio->card, /* card number */
pvmeio->signal, /* signal number */
ptimer->tsrc, /* trigger source */
pCB, /* addr of event post routine */
ptimer); /* event to post on trigger */
}
static void localPostEvent (void *pParam)
{
struct timerRecord *ptimer = pParam;
if (ptimer->tevt) {
post_event(ptimer->tevt);
}
}
static long init_ai( struct aiRecord *pai)
{
@@ -342,7 +362,7 @@ static long read_bi(struct biRecord *pbi)
{
struct vmeio *pvmeio;
long status;
long value;
unsigned long value;
pvmeio = (struct vmeio *)&(pbi->inp.value);
@@ -357,9 +377,9 @@ static long read_bi(struct biRecord *pbi)
static long init_bo(struct boRecord *pbo)
{
unsigned int value;
long status=0;
struct vmeio *pvmeio;
unsigned long value;
long status=0;
struct vmeio *pvmeio;
/* bo.out must be an VME_IO */
switch (pbo->out.type) {

View File

@@ -115,9 +115,9 @@ static long bi_ioinfo(
static long read_bi(struct biRecord *pbi)
{
struct vmeio *pvmeio;
struct vmeio *pvmeio;
long status;
long value;
unsigned value;
pvmeio = (struct vmeio *)&(pbi->inp.value);
@@ -198,7 +198,7 @@ static long read_mbbi(struct mbbiRecord *pmbbi)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
unsigned value;
pvmeio = (struct vmeio *)&(pmbbi->inp.value);
@@ -213,9 +213,9 @@ static long read_mbbi(struct mbbiRecord *pmbbi)
static long init_mbbo(struct mbboRecord *pmbbo)
{
unsigned long value;
struct vmeio *pvmeio;
long status = 0;
unsigned value;
struct vmeio *pvmeio;
long status = 0;
/* mbbo.out must be an VME_IO */
switch (pmbbo->out.type) {
@@ -238,9 +238,9 @@ static long init_mbbo(struct mbboRecord *pmbbo)
static long write_mbbo(struct mbboRecord *pmbbo)
{
struct vmeio *pvmeio;
struct vmeio *pvmeio;
long status;
unsigned long value;
unsigned value;
pvmeio = &(pmbbo->out.value.vmeio);

View File

@@ -74,6 +74,8 @@
#include <choicePulseDelay.h>
#include <pulseTrainRecord.h>
#include <choicePulseTrain.h>
#include <epicsPrint.h>
/* Create the dsets for devMz8310 */
static long report();
static long init();
@@ -303,7 +305,7 @@ static long init(after)
if(after)return(0);
if(sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO, 0, (void *)&shortaddr)) {
logMsg("devMz8310: sysBusToLocalAdrs failed\n",0);
epicsPrintf ("devMz8310: sysBusToLocalAdrs failed\n",0);
exit(1);
}
memset((char *)&mz8310_info[0],0,MAXCARDS*sizeof(struct mz8310_info));
@@ -344,7 +346,7 @@ static long init(after)
}
if(rebootHookAdd(Mz8310_shutdown)<0)
logMsg("Mz8310_shutdown: reboot hook add failed\n");
epicsPrintf ("Mz8310_shutdown: reboot hook add failed\n");
return(0);
}

View File

@@ -63,6 +63,8 @@
static long read_timer();
static long write_timer();
static void localPostEvent (void *pParam);
struct tmdset {
long number;
DEVSUPFUN dev_report;
@@ -83,22 +85,22 @@ static double constants[] = {1e3,1e6,1e9,1e12};
static long read_timer(struct timerRecord *ptimer)
{
struct vmeio *pvmeio;
int source;
int ptst;
double time_pulse[2]; /* delay and width */
double constant;
struct vmeio *pvmeio;
unsigned source;
unsigned ptst;
double time_pulse[2]; /* delay and width */
double constant;
/* only supports a one channel VME timer module !!!! */
pvmeio = (struct vmeio *)(&ptimer->out.value);
if (mz8310_one_shot_read(
&ptst, /* pre-trigger state */
&(time_pulse[0]), /* offset of pulse */
&(time_pulse[1]), /* width of pulse */
(int)pvmeio->card, /* card number */
(int)pvmeio->signal, /* signal number */
&source) != 0) { /* trigger source */
&ptst, /* pre-trigger state */
&(time_pulse[0]), /* offset of pulse */
&(time_pulse[1]), /* width of pulse */
pvmeio->card, /* card number */
pvmeio->signal, /* signal number */
&source) != 0) { /* trigger source */
return 1;
}
@@ -117,19 +119,36 @@ static long read_timer(struct timerRecord *ptimer)
static long write_timer(struct timerRecord *ptimer)
{
struct vmeio *pvmeio;
void (*pCB)(void *);
/* put the value to the ao driver */
pvmeio = (struct vmeio *)(&ptimer->out.value);
if (ptimer->tevt) {
pCB = localPostEvent;
}
else {
pCB = NULL;
}
/* put the value to the ao driver */
return mz8310_one_shot(
(int)ptimer->ptst, /* pre-trigger state */
ptimer->t1dl, /* pulse offset */
ptimer->t1wd, /* pulse width */
(int)pvmeio->card, /* card number */
(int)pvmeio->signal, /* signal number */
(int)ptimer->tsrc, /* trigger source */
((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */
(int)ptimer->tevt); /* event to post on trigger */
ptimer->ptst, /* pre-trigger state */
ptimer->t1dl, /* pulse offset */
ptimer->t1wd, /* pulse width */
pvmeio->card, /* card number */
pvmeio->signal, /* signal number */
ptimer->tsrc, /* trigger source */
pCB, /* addr of event post routine */
ptimer); /* event to post on trigger */
}
static void localPostEvent (void *pParam)
{
struct timerRecord *ptimer = pParam;
if (ptimer->tevt) {
post_event (ptimer->tevt);
}
}

758
src/dev/devWfPentek4261.c Normal file
View File

@@ -0,0 +1,758 @@
/*
*****************************************************************
COPYRIGHT NOTIFICATION
*****************************************************************
THE FOLLOWING IS A NOTICE OF COPYRIGHT, AVAILABILITY OF THE CODE,
AND DISCLAIMER WHICH MUST BE INCLUDED IN THE PROLOGUE OF THE CODE
AND IN ALL SOURCE LISTINGS OF THE CODE.
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
Argonne National Laboratory (ANL), with facilities in the States of
Illinois and Idaho, is owned by the United States Government, and
operated by the University of Chicago under provision of a contract
with the Department of Energy.
Portions of this material resulted from work developed under a U.S.
Government contract and are subject to the following license: For
a period of five years from March 30, 1993, the Government is
granted for itself and others acting on its behalf a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, and perform
publicly and display publicly. With the approval of DOE, this
period may be renewed for two additional five year periods.
Following the expiration of this period or periods, the Government
is granted for itself and others acting on its behalf, a paid-up,
nonexclusive, irrevocable worldwide license in this computer
software to reproduce, prepare derivative works, distribute copies
to the public, perform publicly and display publicly, and to permit
others to do so.
*****************************************************************
DISCLAIMER
*****************************************************************
NEITHER THE UNITED STATES GOVERNMENT NOR ANY AGENCY THEREOF, NOR
THE UNIVERSITY OF CHICAGO, NOR ANY OF THEIR EMPLOYEES OR OFFICERS,
MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS
DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
OWNED RIGHTS.
*****************************************************************
LICENSING INQUIRIES MAY BE DIRECTED TO THE INDUSTRIAL TECHNOLOGY
DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000).
*/
#include <vxWorks.h>
#include <vme.h>
#include <iv.h>
#include <vxLib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <intLib.h>
#include <sysLib.h>
#include <module_types.h>
#include <alarm.h>
#include <dbDefs.h>
#include <recSup.h>
#include <devSup.h>
#include <dbScan.h>
#include <callback.h>
#include <waveformRecord.h>
/*
This is waveform record support for the Pentek 4261A 10MHz 12 bit ADC.
All scan types are supported, including I/O interrupt scan. The ADC
currently supports the edge trigger mode for starting the sampling
operation. The ADC is programmed to record an array of samples the
same size as the waveform record. The internal or an external clock
may be used as the sampling clock. The sampling can be triggered by
an external signal, or automatically by record support.
Using I/O interrupt scanning, the record is processed and the waveform
record array is updated each time an external trigger signal is present.
With the other scan types, the waveform array is updated each time the
record is processed.
I could not get the continuous bank swapping feature to work with the
trigger, I got a glitch in the data approximately 1 us into the sampling.
After each round of sampling is done, the buffers are reset.
The function ConfigurePentekADC() must be run in the
vxWorks startup.cmd file for every ADC board present. This function
makes it easy to configure jumpers on the ADC and inform EPICS of them.
parameters:
ConfigurePentekADC(
int card, - the ADC card number in the crate (0=first)
unsigned long a16_base, - where the card exists in A16
unsigned long a32_base, - where the card exists in A32 (not used)
int irq_vector, - interrupt request vector number
int irq_level, - interrupt request level number
int word_clock, - the ADC word clock (see 4261 documentation)
unsigned long clock_freq - clock frequency (see notes below)
)
Good values to use for configuring the module:
A16 base address = 0x0200
A32 base address = 0xc0200000 (A32 not used in the support)
IRQ vector = 121
IRQ level = 3
word clock = 32
The number of samples programed (size of waveform record) must be
divisible by the word clock.
The operating mode the ADC is selected using the input field parm area.
The user must supply two option, the clock type and the trigger type,
in that order. Here are all the valid parm field entry and what they
represent (all are entered as strings without the quotes):
"x_clock,x_trigger" = external clock and external trigger inputs.
"i_clock,x_trigger" = internal clock and external trigger input.
"x_clock,i_trigger" = external clock and internal trigger input.
"i_clock,i_trigger" = internal clock and internal trigger input.
If external trigger is selected and scan type is not I/O interrupt scan,
then sampling will start on the next external trigger input after device
support completes.
If internal trigger is selected, the sampling will be started by software
at the end of device support. Internal trigger only applied to scan
types that are not I/O interrupt scanned.
Configuration function clock frequency note:
The clock frequency specified in the configuration function is only
applicable to the internal clock. When the external clock is used,
the clock frequency parameter is meaningless, the sampling clock
will be the external clock frequency. When the internal clock is
used (10MHz), the clock frequency parameter will be the sampling
frequency. The 10Mhz internal clock must be divisible by the clock
frequency value.
-----------------------------------------------------------------------
Modify devSup.ascii and do a makesdr. Add devPentekADC
device support to the waveform record.
Running ReportPentekADC() will print a report of configuration for
the ADC.
Waveform data types of long, short, unsigned short, double, and float are
supported.
*/
long devWfPentek4261Debug=0;
#define CMD_ADDED 0
#define CMD_DELETED 1
#define A16_SIZE 256
#define A32_SIZE 256
#define MAX_CARDS 4
#define MAX_FILES_ALLOWED 20
/*-----------------------------------------------------------------*/
/* IMPORTANT, LOOK HERE: test areas - good ones to use for jumpers */
/* They are good setting for the jumpers for the first ADC card,
none of these defines are actually used, are they parameters come
from the ConfigurePentekADC().
*/
#define A16_BASE 0xffff0200
#define A32_BASE 0xc0200000 /* not really used currently */
#define IRQ_VECTOR ((unsigned char)121)
#define IRQ_LEVEL 3
#define WORD_CLOCK 32 /* my default */
/*-----------------------------------------------------------------*/
#define INTERNAL_CLOCK 10000000 /* 10MHz */
#define SAMPLE_CLOCK_SELECT 0x08
#define EXT_TRIGGER_ENABLE 0x04
#define RESET_RUN_FF 0x02
#define SET_RUN_FF 0x01
#define START_MODE 0x20
#define EXTERNAL 0
#define INTERNAL 1
struct card {
int in_use;
unsigned long a16_base;
unsigned long a32_base;
int irq_vector;
int irq_level;
int word_clock;
unsigned long clock_freq;
int soc;
};
typedef struct card CARD;
/* careful here: horrid looking structure -offset and access (rw=read/write) */
struct adc {
unsigned short ctc0_bs_a; /* 0x00 rw */
unsigned short ctc1_bs_b; /* 0x02 rw */
unsigned short ctc2_clock_div; /* 0x04 rw */
unsigned short ctc_control; /*c0x06 rw */ /*char a;*/ short junk1[0x04];
unsigned short int_id_status; /*c0x10 rw */ /*char b;*/
unsigned short int_mask; /*c0x12 rw */ /*char c;*/
unsigned short command; /*c0x14 rw */ /*char d;*/
unsigned short trigger; /*c0x16 rw */ /*char e;*/
unsigned short reserved; /* 0x18 -- */
unsigned short tag_cmd; /*c0x1a rw */ /*char f;*/
unsigned short tag_data; /* 0x1c rw */
unsigned short int_status; /*c0x1e r- */ /*char g;*/ char junk2[0x10];
unsigned short vme_fifo; /* 0x30 rw */
};
typedef struct adc ADC;
struct pvt_area {
CALLBACK callback;
int clock_mode;
int trigger_mode;
int last_int_status;
int last_status;
volatile ADC* adc_regs;
unsigned short div;
int card;
int file_count;
unsigned long total_count;
};
typedef struct pvt_area PVT_AREA;
static long dev_report(int level);
static long dev_init(int after);
static long dev_init_rec(struct waveformRecord* pr);
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt);
static long dev_read(struct waveformRecord* pr);
static long dev_complete_read(struct waveformRecord* pr);
static long dev_other_read(struct waveformRecord* pr);
static void irq_func(void*);
static int full_reset(PVT_AREA* pvt);
static int buffer_reset(PVT_AREA* pvt);
static long setup(PVT_AREA* pvt);
void ConfigurePentekADC(int,unsigned long,unsigned long,int,int,int,unsigned long);
/* generic structure for device support */
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_write;
DEVSUPFUN conv;
} ADC_DSET;
ADC_DSET devWfPentek4261=
{6,dev_report,dev_init,dev_init_rec,dev_ioint_info,dev_read,NULL};
static IOSCANPVT ioscanpvt;
static CARD** cards=0;
static void callback(CALLBACK* cback)
{
struct dbCommon* pc;
struct rset *prset;
callbackGetUser(pc,cback);
prset=(struct rset *)(pc->rset);
/* process the record */
dbScanLock(pc);
(*prset->process)(pc);
dbScanUnlock(pc);
}
static long dev_report(int level)
{
int i;
volatile ADC* adc_regs;
if(cards==0)
printf("No Pentek ADC cards configured in system\n");
else
{
for(i=0;i<MAX_CARDS;i++)
{
if(cards[i]!=0)
{
adc_regs=(ADC*)(i*A16_SIZE+cards[i]->a16_base);
printf("Pentek 4261A ADC card %d information:\n",i);
printf(" a16 base=%8.8x",cards[i]->a16_base);
printf(" a32 base=%8.8x\n",cards[i]->a32_base);
printf(" irq vector=%d",cards[i]->irq_vector);
printf(" irq level=%d\n",cards[i]->irq_level);
printf(" word clock=%d",cards[i]->word_clock);
printf(" clock frequency=%ld\n",cards[i]->clock_freq);
printf(" status=%4.4x\n", adc_regs->int_id_status);
printf(" int mask=%4.4x\n", adc_regs->int_mask);
printf(" command=%4.4x\n", adc_regs->command);
printf(" trigger=%4.4x\n", adc_regs->trigger);
printf(" int status=%4.4x\n", adc_regs->int_status);
}
else
printf("Pentek 4261A ADC card %d not installed\n",i);
}
}
return 0;
}
static long dev_init(int after)
{
if(after) return(0);
scanIoInit(&ioscanpvt);
return 0;
}
static long dev_init_rec(struct waveformRecord* pr)
{
volatile ADC* adc_regs;
PVT_AREA* pvt;
struct vmeio *pvmeio = (struct vmeio *)&(pr->inp.value);
char *clock_type,*trigger_type;
char parm[40];
char** save_area=NULL;
if(pr->inp.type != VME_IO)
{
recGblRecordError(S_db_badField,(void *)pr,
"devPentekADC (init_record) Illegal INP field");
return(S_db_badField);
}
if(cards[pvmeio->card]==0)
{
recGblRecordError(S_dev_badCard,(void *)pr,
"devPentekADC (init_record) Card not Configured!");
return(S_dev_badCard);
}
if(cards[pvmeio->card]->in_use==1)
{
recGblRecordError(S_dev_badCard,(void *)pr,
"devPentekADC (init_record) Card already in use");
return(S_dev_badCard);
}
if(pr->nelm%cards[pvmeio->card]->word_clock!=0)
{
recGblRecordError(S_db_badField, (void *)pr,
"devPentekADC (init_record) num of elements must be divisible by the word clock");
return(S_db_badField);
}
pvt=(PVT_AREA*)malloc(sizeof(PVT_AREA));
cards[pvmeio->card]->in_use=1;
strcpy(parm,pvmeio->parm);
if((clock_type=strtok_r(parm,",",save_area))==NULL)
{
printf("Clock type parameter missing from parm field\n");
printf(" Defaulting to i_clock,i_trigger (internal clock/trigger)\n");
clock_type="i_clock";
trigger_type="i_trigger";
}
else if((trigger_type=strtok_r(NULL,",",save_area))==NULL)
{
printf("Triggert type parameter missing from parm field\n");
printf(" Defaulting to i_trigger (internal trigger)\n");
trigger_type="i_trigger";
}
if( strcmp(clock_type,"i_clock")==0 )
pvt->clock_mode=INTERNAL;
else if( strcmp(clock_type,"x_clock")==0 )
pvt->clock_mode=EXTERNAL;
else
{
printf("Invalid parm for clock type, must be i_clock or x_clock\n");
pvt->clock_mode=INTERNAL;
}
if( strcmp(trigger_type,"i_trigger")==0 )
pvt->trigger_mode=INTERNAL;
else if( strcmp(trigger_type,"x_trigger")==0 )
pvt->trigger_mode=EXTERNAL;
else
{
printf("Invalid parm for clock type, must be i_trigger or x_trigger\n");
pvt->trigger_mode=INTERNAL;
}
adc_regs=(ADC*)(pvmeio->card*A16_SIZE+cards[pvmeio->card]->a16_base);
callbackSetCallback(callback,&pvt->callback);
callbackSetPriority(pr->prio,&pvt->callback);
callbackSetUser(pr,&pvt->callback);
pvt->adc_regs=adc_regs;
pvt->card=pvmeio->card;
pvt->file_count=0;
pr->dpvt=(void*)pvt;
/* program number of samples and sample clock */
pvt->div=pr->nelm/cards[pvmeio->card]->word_clock;
/* install the interrupt handler */
if(intConnect(INUM_TO_IVEC(cards[pvmeio->card]->irq_vector),
(VOIDFUNCPTR)irq_func, (int)pr)!=OK)
{ printf("intConnect failed\n"); return -1; }
sysIntEnable(cards[pvmeio->card]->irq_level);
full_reset(pvt);
return 0;
}
static int buffer_reset(PVT_AREA* pvt)
{
pvt->adc_regs->command=0x00; /* reset the card */
pvt->adc_regs->command=0x90; /* vme enable, no reset mode */
return 0;
}
static int full_reset(PVT_AREA* pvt)
{
unsigned long clock_div,clock_freq,sample_freq;
unsigned short clock_div_short;
unsigned char trig;
buffer_reset(pvt);
/* auto arm mode not enabled */
trig=0x20; /* positive going edge */
if(pvt->clock_mode==EXTERNAL) trig|=0x08; /* ext clock */
pvt->adc_regs->trigger=trig; /* set the trigger reg */
pvt->adc_regs->int_id_status=cards[pvt->card]->irq_vector;
/* program counter for bank A */
pvt->adc_regs->ctc_control=0x00|0x30|0x04; /* CTC-0,LSB-MSB,mode */
pvt->adc_regs->ctc0_bs_a=(unsigned short)(pvt->div&0x00ff);
pvt->adc_regs->ctc0_bs_a=(unsigned short)(pvt->div>>8);
/* program counter for bank B */
pvt->adc_regs->ctc_control=0x40|0x30|0x04; /* CTC-1,LSB-MSB,mode */
pvt->adc_regs->ctc1_bs_b=(unsigned short)(pvt->div&0x00ff);
pvt->adc_regs->ctc1_bs_b=(unsigned short)(pvt->div>>8);
/* printf("bank div=%4.4x\n",pvt->div); */
/* -------------------------------------------------------------- */
/*
careful here, if changing code to use internal clock, use the
code below to program the sample clock divisor, remember that if
sample clock divisor is one, then the else portion of the code must
be used.
SampleClock = InputClock / N
where:
N is programmed divisor and 1<=N<=65535
InputClock is 10MHz for internal clock or the external clock
SampleClock if the effective sampling clock
We are given SampleClock, and need N, so
N = InputClock / SampleClock
*/
/* internal clock type uses clock_freq from config as sample clock,
external clock does not use clock divisor */
if(pvt->clock_mode==INTERNAL) /* internal clock */
{
clock_freq=INTERNAL_CLOCK;
sample_freq=cards[pvt->card]->clock_freq;
}
else
{
clock_freq = cards[pvt->card]->clock_freq;
sample_freq = clock_freq;
}
if(clock_freq==sample_freq)
{
/* if clock divisor of one is to be used (10MHz) */
pvt->adc_regs->ctc_control=0x80|0x10; /* CTC-2, LSB, mode 0 */
}
else
{
clock_div=clock_freq/sample_freq;
/* printf("clock div=%8.8x\n",clock_div); */
if(clock_div>=1 && clock_div<=65535)
{
clock_div_short = clock_div;
/* if clock divisor used, sample rate */
pvt->adc_regs->ctc_control=0x80|0x30|0x04; /* CTC-2,LSB-MSB,mode */
pvt->adc_regs->ctc2_clock_div=(clock_div_short&0x00ff);
pvt->adc_regs->ctc2_clock_div=(clock_div_short>>8);
}
else
{
pvt->adc_regs->ctc_control=0x80|0x10; /* CTC-2, LSB, mode 0 */
printf("Invalid clock/sample frequency: %ld/%ld\n",
clock_freq,sample_freq);
}
}
/* -------------------------------------------------------------- */
/* start mode = off at this point */
return 0;
}
static long dev_ioint_info(int cmd,struct waveformRecord* pr,IOSCANPVT* iopvt)
{
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
pr->pact=0;
if(cmd==CMD_ADDED)
setup(pvt);
else /* CMD_DELETED */
buffer_reset(pvt); /* ensure that we are in a good state */
*iopvt=ioscanpvt;
return 0;
}
static long dev_read(struct waveformRecord* pr)
{
long rc;
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
if(pr->scan==SCAN_IO_EVENT)
{
pvt->adc_regs->command|=0x20; /* start mode */
rc=dev_complete_read(pr);
setup(pvt);
}
else
rc=dev_other_read(pr);
return rc;
}
static long setup(PVT_AREA* pvt)
{
unsigned char trig;
volatile unsigned char istat;
buffer_reset(pvt);
trig=pvt->adc_regs->trigger&0xf8; /* clear run FF,trigger */
trig|=0x44; /* external trigger on, auto arm mode */
istat=pvt->adc_regs->int_status; /* read int status */
pvt->adc_regs->int_mask=0x10; /* bank swap interrupt */
pvt->adc_regs->trigger=trig|0x02; /* trigger mode + reset run FF */
pvt->adc_regs->command|=0x20; /* start mode */
pvt->adc_regs->trigger=trig; /* trigger mode */
return 0;
}
static long dev_other_read(struct waveformRecord* pr)
{
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
long rc=0;
if(pr->pact==TRUE)
{
/* i/o complete */
/* interrupt handler shut down everything already */
pvt->adc_regs->command|=0x20; /* start mode on */
rc=dev_complete_read(pr); /* process data in buffer */
pvt->adc_regs->command&=~0x20; /* start mode off */
}
else
{
/* start the i/o */
/* this sucks, with internal mode trigger, the board glitch
every so often, I cannot get it to work correctly, so do full reset */
if(pvt->trigger_mode==INTERNAL) full_reset(pvt);
callbackSetPriority(pr->prio,&pvt->callback);
setup(pvt);
pr->pact=TRUE;
if(pvt->trigger_mode==INTERNAL)
pvt->adc_regs->trigger|=0x01; /* set run FF */
}
return rc;
}
static long dev_complete_read(struct waveformRecord* pr)
{
int i;
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
volatile unsigned short* source;
volatile unsigned short samples;
source=&(pvt->adc_regs->vme_fifo);
i=0;
switch(pr->ftvl)
{
case DBF_FLOAT:
{
float* f_thing = (float*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
f_thing[i]=(float)(((short)samples)>>4);
}
pr->nord=i;
break;
}
case DBF_DOUBLE:
{
double* d_thing = (double*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
d_thing[i]=(double)(((short)samples)>>4);
}
pr->nord=i;
break;
}
case DBF_ULONG:
{
unsigned long* ul_thing = (unsigned long*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
ul_thing[i]=(unsigned long)((samples>>4)&0x0fff);
}
pr->nord=i;
break;
}
case DBF_LONG:
{
long* l_thing = (long*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
l_thing[i]=(long)(((long)samples)>>4);
}
pr->nord=i;
break;
}
case DBF_USHORT:
{
unsigned short* s_thing = (unsigned short*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
s_thing[i]=(unsigned short)((samples>>4)&0x0fff);
}
pr->nord=i;
break;
}
default:
printf("devPentek4261: Invalid data type\n");
case DBF_SHORT:
{
short* ss_thing = (unsigned short*)pr->bptr;
for(i=0;i<pr->nelm;i++)
{
samples=pvt->adc_regs->vme_fifo;
ss_thing[i]=(short)(((short)(samples))>>4);
}
pr->nord=i;
break;
}
}
/* clear remaining samples if any */
while(pvt->adc_regs->int_id_status&0x80)
samples=pvt->adc_regs->vme_fifo;
/* pr->nelm, pr->bptr, &(pr->nord) */ /* three important fields */
pr->udf=0;
return 0;
}
/* IRQ under vxWorks */
static void irq_func(void* v)
{
struct waveformRecord* pr = (struct waveformRecord*)v;
PVT_AREA* pvt = (PVT_AREA*)pr->dpvt;
CALLBACK* cb = (CALLBACK*)pvt;
unsigned char trig;
pvt->last_int_status=pvt->adc_regs->int_status; /* read status */
/* logMsg("in irq_func\n"); */
/* if(pvt->last_int_status&0x02) logMsg("Overrun error\n"); */
pvt->adc_regs->command&=~0x20; /* start mode off - freeze all */
pvt->adc_regs->int_mask=0x00; /* interrupts off */
trig=pvt->adc_regs->trigger&0xfc; /* clear run FF bits */
pvt->adc_regs->trigger=trig; /* clear run FF bits */
pvt->adc_regs->trigger=trig|0x02; /* force reset run FF */
if(pr->scan==SCAN_IO_EVENT)
scanIoRequest(ioscanpvt); /* scan EPICS record */
else
callbackRequest(cb);
}
void ReportPentekADC() { dev_report(0); }
void ConfigurePentekADC( int card,
unsigned long a16_base, unsigned long a32_base,
int irq_vector, int irq_level,
int word_clock, unsigned long clock_freq)
{
unsigned short dummy;
if(cards==0)
{
cards=(CARD**)malloc(sizeof(CARD*)*MAX_CARDS);
memset((char*)cards,0,sizeof(CARD*)*MAX_CARDS);
}
if(cards[card]!=0) printf("Overriding previous configuration\n");
else cards[card]=(CARD*)malloc(sizeof(CARD));
cards[card]->in_use=0;
if( sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,(char*)a16_base,(char**)&(cards[card]->a16_base))!=OK)
{
printf(" a16 base could not be converted\n");
}
if( sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,(char*)a32_base,(char**)&(cards[card]->a32_base))!=OK)
{
printf(" a32 base could not be converted\n");
}
cards[card]->irq_vector=irq_vector;
cards[card]->irq_level=irq_level;
cards[card]->word_clock=word_clock;
cards[card]->clock_freq=clock_freq;
if(vxMemProbe((char*)cards[card]->a16_base,READ,
sizeof(unsigned short),(char*)&dummy)!=OK)
{
/* card not really present */
cards[card]->in_use=1;
}
}

View File

@@ -11,8 +11,30 @@ USR_CFLAGS = -ansi
VX_WARN_YES = -Wall -pedantic
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 += ../drvTime.c
# SRCS.c += ../drvCaenV265.c
TARGETS += drvAb.o
TARGETS += drvAt5Vxi.o
TARGETS += drvEpvxi.o
TARGETS += drvEpvxiMsg.o
TARGETS += drvHp1404a.o
TARGETS += drvHpe1368a.o
TARGETS += drvHpe1445a.o
TARGETS += drvKscV215.o
TARGETS += drvMz8310.o
TARGETS += drvStc.o
TARGETS += drvTime.o
# TARGETS += drvCaenV265.o
include $(EPICS)/config/RULES.Vx

View File

@@ -0,0 +1,30 @@
The CPU030 may need to have the nivxi path set correctly:
From the vxWorks shell type "vxitedit"
take option 2
take option 3
type list
type modify 0
type in the correct path when promped
(the path should end in nivxi
and should traverse the niCpu030
directories shipped with the 030
ie somethin of the form "???/config/niCPU030/nivxi"
type save
type exit
.
.
.
You may may need to setup front panel to backplane trigger
routing:
To take a TTL input and map it to VXI backplane ECL trigger 0
type in (to the vxWorks shell):
epvxiRouteTriggerECL(<logical address>, 1, 0)
where <logical address> specifies the card with the
front panel trigger connection.

View File

@@ -324,7 +324,7 @@ unsigned int ab_debug=0;
LOCAL char *statusMessage[] = {
"Success","New Card","Card Conflict","No Card",
"Card not initialized","block transfer queued",
"Card Busy","Timeout","Link Down","Failure"};
"Card Busy","Timeout","Adapter Down","Failure"};
char **abStatusMessage = statusMessage;
LOCAL char *numBitsMessage[] = {
@@ -616,7 +616,7 @@ LOCAL abStatus bt_queue(unsigned short command,ab_card *pcard,
unsigned short *pmb_msg = &pmb->msg[0];
int status;
if(!padapter->adapter_online) return(abLinkDown);
if(!padapter->adapter_online) return(abAdapterDown);
pbtInfo->cmd = command;
pbtInfo->pmsg = pmsg;
pbtInfo->msg_len = msg_len;
@@ -1482,26 +1482,30 @@ LOCAL abStatus registerCard(
if(link>=max_ab_6008s) {
printf("abDrv(registerCard) bad link %hu\n",link);
return(abFailure);
if(ab_debug>0)
printf("abDrv(registerCard) bad link %hu\n",link);
return(abNoCard);
}
if(adapter>=MAX_AB_ADAPTERS) {
printf("abDrv(registerCard) bad adapter %hu\n",adapter);
return(abFailure);
if(ab_debug>0)
printf("abDrv(registerCard) bad adapter %hu\n",adapter);
return(abNoCard);
}
if(card>=MAX_CARDS_PER_ADAPTER) {
printf("abDrv(registerCard) bad card %hu\n",card);
return(abFailure);
if(ab_debug>0)
printf("abDrv(registerCard) bad card %hu\n",card);
return(abNoCard);
}
plink = pab_links[link];
if(!plink || !plink->initialized) {
printf("abDrv(registerCard) link %hu not initialized\n",link);
return(abFailure);
if(ab_debug>0)
printf("abDrv(registerCard) link %hu not initialized\n",link);
return(abNoCard);
}
padapter = plink->papadapter[adapter];
if(padapter) pcard = padapter->papcard[card];
if(pcard) {
if(strcmp(pcard->card_name,card_name)!=0) return(abFailure);
if(strcmp(pcard->card_name,card_name)!=0) return(abCardConflict);
if(pcard->type==type) {
*ppcard = pcard;
return(abSuccess);
@@ -1518,7 +1522,7 @@ LOCAL abStatus registerCard(
return(abSuccess);
}
}
return(abFailure);
return(abCardConflict);
}
/*New Card*/
pcard = abCalloc(1,sizeof(ab_card));
@@ -1598,7 +1602,7 @@ LOCAL abStatus getStatus(void *drvPvt)
unsigned short adapter = pcard->adapter;
ab_adapter *padapter = pab_links[link]->papadapter[adapter];
if(!padapter->adapter_online) return(abLinkDown);
if(!padapter->adapter_online) return(abAdapterDown);
return(pcard->status);
}
@@ -1687,9 +1691,43 @@ LOCAL abStatus btWrite(void *drvPvt,unsigned short *pwrite_msg, unsigned short w
return(btStatus);
}
LOCAL abStatus adapterStatus(unsigned short link,unsigned short adapter)
{
ab_adapter *padapter;
ab_link *plink;
if(link>=max_ab_6008s) return(abFailure);
if(adapter>=MAX_AB_ADAPTERS) return(abFailure);
plink = pab_links[link];
if(!plink || !plink->initialized) return(abFailure);
padapter = plink->papadapter[adapter];
if(!padapter->adapter_online) return(abAdapterDown);
return(abSuccess);
}
LOCAL abStatus cardStatus(
unsigned short link,unsigned short adapter,unsigned short card)
{
ab_adapter *padapter;
ab_link *plink;
ab_card *pcard;
if(link>=max_ab_6008s) return(abFailure);
if(adapter>=MAX_AB_ADAPTERS) return(abFailure);
if(card>=MAX_CARDS_PER_ADAPTER) return(abFailure);
plink = pab_links[link];
if(!plink || !plink->initialized) return(abFailure);
padapter = plink->papadapter[adapter];
pcard = padapter->papcard[card];
if(!pcard) return(abNoCard);
if(!padapter->adapter_online) return(abAdapterDown);
return(pcard->status);
}
LOCAL abDrv abDrvTable= {
registerCard,getLocation,setNbits,setUserPvt,getUserPvt,
getStatus,startScan,updateAo,updateBo,readBo,readBi,btRead,btWrite
getStatus,startScan,updateAo,updateBo,readBo,readBi,btRead,btWrite,
adapterStatus,cardStatus
};
abDrv *pabDrv = &abDrvTable;

View File

@@ -41,7 +41,7 @@ typedef enum {typeNotAssigned,typeBi,typeBo,typeBiBo,typeAi,typeAo,typeBt}
cardType;
/* status values*/
typedef enum{abSuccess,abNewCard,abCardConflict,abNoCard,abNotInitialized,
abBtqueued,abBusy,abTimeout,abLinkDown,abFailure} abStatus;
abBtqueued,abBusy,abTimeout,abAdapterDown,abFailure} abStatus;
extern char **abStatusMessage;
typedef enum{abBitNotdefined,abBit8,abBit16,abBit32} abNumBits;
@@ -73,6 +73,10 @@ typedef struct {
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;

1410
src/drv/ansi/drvAt5Vxi.c Normal file

File diff suppressed because it is too large Load Diff

94
src/drv/ansi/drvAt5Vxi.h Normal file
View File

@@ -0,0 +1,94 @@
/* base/src/drv $Id$ */
/*
*
* driver for at5 designed VXI modules
*
* Author: Jeff Hill
* Date: 11-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#include <dbScan.h>
typedef long at5VxiStatus;
at5VxiStatus at5vxi_one_shot(
unsigned preset, /* TRUE or COMPLEMENT logic */
double edge0_delay, /* sec */
double edge1_delay, /* set */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
void (*event_rtn)(void *pParam), /* subroutine to run on events */
void *event_rtn_param/* parameter to pass to above routine */
);
at5VxiStatus at5vxi_one_shot_read(
unsigned *preset, /* TRUE or COMPLEMENT logic */
double *edge0_delay, /* sec */
double *edge1_delay, /* sec */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
);
at5VxiStatus at5vxi_ai_driver(
unsigned card,
unsigned chan,
unsigned short *prval
);
at5VxiStatus at5vxi_ao_driver(
unsigned card,
unsigned chan,
unsigned short *prval,
unsigned short *prbval
);
at5VxiStatus at5vxi_ao_read(
unsigned card,
unsigned chan,
unsigned short *pval
);
at5VxiStatus at5vxi_bi_driver(
unsigned card,
unsigned long mask,
unsigned long *prval
);
at5VxiStatus at5vxi_bo_driver(
unsigned card,
unsigned long val,
unsigned long mask
);
at5VxiStatus at5vxi_getioscanpvt(
unsigned card,
IOSCANPVT *scanpvt
);

808
src/drv/ansi/drvCaenV265.c Normal file
View File

@@ -0,0 +1,808 @@
/* share/src/drv @(#)drvCaenV265.c 1.1 9/2/94 */
/* drvCaenV265.c - Driver/Device Support Routines for CAEN V265
*
* Author: Jeff Hill (johill@lanl.gov)
* Date: 8-11-94
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* MIT Bates Lab
*
* Modification Log:
* -----------------
*/
/*
* ANSI C Includes
*/
#include <stdio.h>
#include <stddef.h>
#include <types.h>
#include <assert.h>
/*
* vxWorks includes
*/
#include <vme.h>
#include <iv.h>
#include <sysLib.h>
#include <intLib.h>
#include <logLib.h>
#include <vxLib.h>
#include <rebootLib.h>
#include <taskLib.h>
#include <tickLib.h>
#include <wdLib.h>
/*
* EPICS include
*/
#include <dbDefs.h>
#include <dbScan.h>
#include <drvSup.h>
#include <devSup.h>
#include <recSup.h>
#include <devLib.h>
#include <aiRecord.h>
#include <errMdef.h>
#include <epicsPrint.h>
/*
* base address, base interrupt vector,
* number of cards, & interrupt level
*/
#define CAIN_V265_A24_BASE (0x000000)
#define CAIN_V265_INTVEC_BASE (0xA0)
#define CAIN_V265_MAX_CARD_COUNT (8)
#define CAIN_V265_INT_LEVEL (6)
/*
* all device registers declared
* ANSI C volatile so we dont need to
* use the -fvolatile flag (and dont
* limit the optimizer)
*/
typedef volatile int16_t devReg;
struct caenV265 {
devReg csr;
devReg clear;
devReg DAC;
devReg gate;
const devReg data;
const devReg pad1[(0xf8-0x8)/2];
const devReg fixed;
const devReg identifier;
const devReg version;
};
#define CAENV265ID 0x0812
/*
* Insert or extract a bit field using the standard
* masks and shifts defined below
*/
#ifdef __STDC__
#define INSERT(FIELD,VALUE)\
(((VALUE)&(FD_ ## FIELD ## _M))<<(FD_ ## FIELD ## _S))
#define EXTRACT(FIELD,VALUE)\
( ((VALUE)>>(FD_ ## FIELD ## _S)) &(FD_ ## FIELD ## _M))
#else /*__STDC__*/
#define INSERT(FIELD,VALUE)\
(((VALUE)&(FD_/* */FIELD/* */_M))<<(FD_/* */FIELD/* */_S))
#define EXTRACT(FIELD,VALUE)\
( ((VALUE)>>(FD_/* */FIELD/* */_S)) &(FD_/* */FIELD/* */_M))
#endif /*__STDC__*/
/*
* in the constants below _M is a right justified mask
* and _S is a shift required to right justify the field
*/
/*
* csr register
*/
#define FD_FULL_M (0x1)
#define FD_FULL_S (14)
#define FD_READY_M (0x1)
#define FD_READY_S (15)
#define FD_BUSY_FULL_M (0x3)
#define FD_BUSY_FULL_S (14)
#define FD_IVEC_M (0xff)
#define FD_IVEC_S (0)
#define FD_ILEVEL_M (0x7)
#define FD_ILEVEL_S (8)
/*
* series/version register
*/
#define FD_SERIES_M (0xfff)
#define FD_SERIES_S (0)
#define FD_VERSION_M (0xf)
#define FD_VERSION_S (12)
/*
* data register
*/
#define FD_CHANNEL_M (0x7)
#define FD_CHANNEL_S (13)
#define FD_RANGE_M (1)
#define FD_RANGE_S (12)
#define FD_DATA_M (0xfff)
#define FD_DATA_S (0)
struct channel{
int16_t signal;
char newData;
};
enum adc_range {adc_12, adc_15, NUMBER_OF_ADC_RANGES};
#define NUMBER_OF_SIGNALS 8
#define NUMBER_OF_FIFO_ENTRIES (16*NUMBER_OF_SIGNALS*NUMBER_OF_ADC_RANGES)
LOCAL struct caenV265Config{
struct caenV265 *pCaenV265; /* pointer to the card */
struct channel chan[NUMBER_OF_SIGNALS][NUMBER_OF_ADC_RANGES];
IOSCANPVT scanpvt;
WDOG_ID wdid;
}caenV265Info[CAIN_V265_MAX_CARD_COUNT];
#ifdef __STDC__
#define SHOW_OFFSET(STRUCT,FIELD) \
printf( "%s.%s is at 0x%X\n", \
#STRUCT, \
#FIELD, \
offsetof(struct STRUCT, FIELD))
#endif
LOCAL void caenV265ISR(unsigned card);
LOCAL int caenV265Shutdown(void);
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265);
int caenV265Test(unsigned card);
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config);
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal);
LOCAL int caenV265IntEnable(unsigned card);
/*
* device support entry table
*/
LOCAL long caenV265InitRecord(struct aiRecord *pai);
LOCAL long caenV265AiRead(struct aiRecord *pai);
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after);
LOCAL long caenV265GetIoIntInfo(int cmd, struct aiRecord *pai, IOSCANPVT *ppvt);
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_ai;
DEVSUPFUN special_linconv;
} devCaenV265 ={
6,
NULL,
NULL,
caenV265InitRecord,
caenV265GetIoIntInfo,
caenV265AiRead,
caenV265SpecialLinconv};
/*
* driver support entry table
*/
LOCAL long caenV265Init(void);
LOCAL long caenV265IOReport(int level);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvCaenV265 ={
2,
caenV265IOReport,
caenV265Init};
/*
* verify that register
* offsets match the doc.
*/
#ifdef DEBUG
void offsettest()
{
SHOW_OFFSET(caenV265, version);
SHOW_OFFSET(caenV265, identifier);
SHOW_OFFSET(caenV265, fixed);
SHOW_OFFSET(caenV265, data);
SHOW_OFFSET(caenV265, gate);
SHOW_OFFSET(caenV265, DAC);
SHOW_OFFSET(caenV265, clear);
SHOW_OFFSET(caenV265, csr);
return;
}
#endif
/*
* caenV265InitRecord()
*/
LOCAL long caenV265InitRecord(struct aiRecord *pai)
{
struct vmeio *pvmeio;
/* ai.inp must be an VME_IO */
switch (pai->inp.type) {
case (VME_IO):
break;
default :
recGblRecordError(S_db_badField,(void *)pai,
"devAiXy566Se (init_record) Illegal INP field");
return(S_db_badField);
}
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad signal or card number
*/
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 bad card or signal number");
return -1;
}
if(!caenV265Info[pvmeio->card].pCaenV265){
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 card does not exist");
return -1;
}
/* set linear conversion slope*/
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
return(0);
}
/*
* caenV265AiRead()
*/
LOCAL long caenV265AiRead(struct aiRecord *pai)
{
int16_t value;
struct vmeio *pvmeio;
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad signal or card number
*/
if ( pvmeio->signal >= NUMBER_OF_SIGNALS ||
pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
return -1;
}
/*
* uninitialized data?
*/
if (!caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].newData) {
recGblSetSevr(pai, READ_ALARM, INVALID_ALARM);
return -1;
}
value = caenV265Info[pvmeio->card].chan[pvmeio->signal][adc_12].signal;
pai->rval = value;
return 0;
}
/*
* caenV265SpecialLinconv()
*/
LOCAL long caenV265SpecialLinconv(struct aiRecord *pai, int after)
{
if(!after) {
return 0;
}
/* set linear conversion slope*/
pai->eslo = (pai->eguf-pai->egul)/FD_DATA_M;
return 0;
}
/*
* caenV265GetIoIntInfo()
*/
LOCAL long caenV265GetIoIntInfo(
int cmd,
struct aiRecord *pai,
IOSCANPVT *ppvt)
{
struct vmeio *pvmeio;
pvmeio = (struct vmeio *)&(pai->inp.value);
/*
* check for bad card number
*/
if ( pvmeio->card >= CAIN_V265_MAX_CARD_COUNT ) {
epicsPrintf (
"%s.%d:devCaenV265 bad card number %d %s\n",
(int)__FILE__,
__LINE__,
pvmeio->card,
(int)pai->name);
recGblRecordError(
S_db_badField,
(void *)pai,
"devCaenV265 bad card number");
return -1;
}
*ppvt = &caenV265Info[pvmeio->card].scanpvt;
return 0;
}
/*
* caenV265Init()
*/
LOCAL long caenV265Init(void)
{
unsigned card;
struct caenV265 *pCaenV265;
int status;
status = rebootHookAdd(caenV265Shutdown);
if(status){
errMessage(S_dev_internal,"reboot hook add failed");
return ERROR;
}
status = sysBusToLocalAdrs(
VME_AM_STD_SUP_DATA,
CAIN_V265_A24_BASE,
(char **)&pCaenV265);
if(status!=OK){
errPrintf(
S_dev_badA24,
__FILE__,
__LINE__,
"caenV265Init");
return ERROR;
}
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++, pCaenV265++){
unsigned vec;
if(!caenV265IdTest(pCaenV265)){
continue;
}
caenV265Info[card].wdid = wdCreate();
if(!caenV265Info[card].wdid){
continue;
}
/*
* flag that we have found a caen V265
*/
caenV265Info[card].pCaenV265 = pCaenV265;
/*
* init the EPICS db int event scan block
*/
scanIoInit(&caenV265Info[card].scanpvt);
/*
* reset the device
*/
pCaenV265->clear = 0; /* any rw op resets the device */
pCaenV265->DAC = 0; /* set test-signal "offset" to zero */
/*
* attach ISR
*/
vec = CAIN_V265_INTVEC_BASE+card;
status = intConnect(
INUM_TO_IVEC(vec),
caenV265ISR,
card);
assert(status>=0);
/*
* Enable interrupts
*/
caenV265IntEnable(card);
}
status = sysIntEnable(CAIN_V265_INT_LEVEL);
assert(status>=0);
return OK;
}
/*
* caenV265ISR()
*/
LOCAL void caenV265ISR(unsigned card)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned signal;
int16_t csr;
static unsigned ticks;
unsigned newTicks;
/*
* If its full then its more efficient
* to read it out without checking
* in between each read
*/
csr = pCaenV265->csr;
if (EXTRACT(FULL,csr)) {
for( signal=0;
signal<NUMBER_OF_FIFO_ENTRIES;
signal++){
caenV265ReadData(pCaenV256Config);
}
return;
}
/*
* Not full so check to see if its ready before
* reading
*/
while (EXTRACT(READY, csr)) {
caenV265ReadData(pCaenV256Config);
csr = pCaenV265->csr;
}
/*
* limit the EPICS scan rate
*/
newTicks = tickGet();
if(newTicks == ticks){
/*
* Disable Interrupts
*/
pCaenV265->csr = 0;
/*
* start a watch dog after one tick
* so that we limit the int rate to
* the system tick rate.
*/
wdStart(pCaenV256Config->wdid,
1,
caenV265IntEnable,
card);
return;
}
else{
ticks = newTicks;
}
/*
* tell EPICS to scan on int
*/
scanIoRequest(&caenV265Info[card].scanpvt);
return;
}
/*
* caenV265IntEnable
*/
LOCAL int caenV265IntEnable(unsigned card)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned vec;
int16_t newcsr;
vec = CAIN_V265_INTVEC_BASE+card;
newcsr = INSERT(IVEC, vec) | INSERT(ILEVEL, CAIN_V265_INT_LEVEL);
pCaenV265->csr = newcsr;
return OK;
}
/*
* caenV265ReadData()
*/
LOCAL void caenV265ReadData(struct caenV265Config *pCaenV256Config)
{
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
int16_t val = pCaenV265->data;
int16_t data = EXTRACT(DATA, val);
unsigned range = EXTRACT(RANGE, val);
unsigned signal = EXTRACT(CHANNEL, val);
if(range>=NUMBER_OF_ADC_RANGES){
epicsPrintf ("caenV265ReadData: bad range number\n");
return;
}
if(signal>=NUMBER_OF_SIGNALS){
epicsPrintf ("caenV265ReadData: bad signal number\n");
return;
}
pCaenV256Config->chan[signal][range].signal=data;
pCaenV256Config->chan[signal][range].newData=TRUE;
return;
}
/*
* caenV265IdTest()
*/
LOCAL int caenV265IdTest(struct caenV265 *pCaenV265)
{
int status;
int16_t id;
/*
* Is a card present
*/
status = vxMemProbe(
(char *)&pCaenV265->identifier,
READ,
sizeof(id),
(char *)&id);
if(status!=OK){
return FALSE;
}
/*
* Is the correct type of card present
*/
if(id!=CAENV265ID){
errPrintf(
S_dev_wrongDevice,
__FILE__,
__LINE__,
"caenV265IdTest");
return FALSE;
}
return TRUE;
}
/*
* caenV265Shutdown()
* turns off interrupts so that dont foul up the boot
*/
LOCAL int caenV265Shutdown(void)
{
struct caenV265 *pCaenV265;
unsigned card;
for(card=0; card<CAIN_V265_MAX_CARD_COUNT; card++){
pCaenV265 = caenV265Info[card].pCaenV265;
if(!pCaenV265){
continue;
}
if(caenV265IdTest(pCaenV265)){
/*
* disable interrupts
*/
pCaenV265->csr=0;
}
}
return OK;
}
/*
* caenV265Test()
*/
int caenV265Test(unsigned card)
{
unsigned dacVal;
struct caenV265Config cofigCpy;
unsigned range;
unsigned signal;
dacVal=0;
caenV265TestVal(card, dacVal);
while(dacVal<FD_DATA_M){
cofigCpy = caenV265Info[card];
dacVal = dacVal+32;
caenV265TestVal(card, dacVal);
for( range=0;
range<NUMBER_OF_ADC_RANGES;
range++){
char *pRangeName[] = { "12 bit signal",
"15 bit signal"};
printf( "\t%s with DAC = 0x%X\n",
pRangeName[range],
dacVal);
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
unsigned newdata;
unsigned olddata;
olddata = cofigCpy.chan[signal][range].signal;
newdata = caenV265Info[card].
chan[signal][range].signal;
printf( "\t\tchan=0x%1X diff = 0x%03X\n",
signal,
newdata-olddata);
}
}
}
return OK;
}
/*
* caenV265TestVal()
*/
LOCAL int caenV265TestVal(unsigned card, unsigned dacVal)
{
struct caenV265Config *pCaenV256Config = &caenV265Info[card];
struct caenV265 *pCaenV265 = pCaenV256Config->pCaenV265;
unsigned signal;
if(!pCaenV265){
return ERROR;
}
if(!caenV265IdTest(pCaenV265)){
return ERROR;
}
/*
* clear the module
*/
pCaenV265->clear=0;
/*
* generate a test signal
*/
pCaenV265->DAC=dacVal;
/*
* generate a test gate
*/
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
caenV265Info[card].chan[signal][adc_12].newData=FALSE;
caenV265Info[card].chan[signal][adc_15].newData=FALSE;
while(!caenV265Info[card].chan[signal][adc_15].newData){
pCaenV265->gate=0;
taskDelay(1);
}
while(!caenV265Info[card].chan[signal][adc_12].newData){
pCaenV265->gate=0;
taskDelay(1);
}
}
/*
* turn off test signal
*/
pCaenV265->clear=0;
pCaenV265->DAC=0;
return OK;
}
/*
* caenV265IOReport()
*/
LOCAL long caenV265IOReport(int level)
{
struct caenV265 *pCaenV265;
unsigned card;
unsigned signal;
unsigned range;
char *pVersion[] = {"NIM","ECL"};
char *pState[] = {
"FIFO empty",
"FIFO full",
"FIFO partially filled",
"FIFO full"};
for (card=0; card<CAIN_V265_MAX_CARD_COUNT; card++) {
pCaenV265 = caenV265Info[card].pCaenV265;
if (!pCaenV265) {
continue;
}
if (!caenV265IdTest(pCaenV265)) {
continue;
}
printf("AI: caen V265:\tcard %d\n", card);
if (level == 0) {
continue;
}
printf("\tversion = %s\n",
pVersion[EXTRACT(VERSION, pCaenV265->version)]);
printf("\tseries = %d\n",
EXTRACT(SERIES, pCaenV265->version));
printf("\tstate = %s\n",
pState[EXTRACT(BUSY_FULL,pCaenV265->csr)]);
printf("\tint level = %d\n",
EXTRACT(ILEVEL,pCaenV265->csr));
printf("\tint vec = 0x%02X\n",
EXTRACT(IVEC,pCaenV265->csr));
printf( "\tbase addr= 0x%X on the %s\n",
(unsigned)caenV265Info[card].pCaenV265,
sysModel());
for( range=0;
range<NUMBER_OF_ADC_RANGES;
range++){
char *pRangeName[] = { "12 bit signal",
"15 bit signal"};
printf("\t%s\n", pRangeName[range]);
for( signal=0;
signal<NUMBER_OF_SIGNALS;
signal++){
int16_t data;
data = caenV265Info[card].
chan[signal][range].signal;
if(caenV265Info[card].chan[signal][range].newData){
printf( "\t\tchan=0x%1X val = 0x%03X\n",
signal,
data);
}
else{
printf( "\t\tchan=0x%1X <NO GATE>\n",
signal);
}
}
}
}
return OK;
}

4620
src/drv/ansi/drvEpvxi.c Normal file

File diff suppressed because it is too large Load Diff

1537
src/drv/ansi/drvEpvxiMsg.c Normal file

File diff suppressed because it is too large Load Diff

408
src/drv/ansi/drvHp1404a.c Normal file
View File

@@ -0,0 +1,408 @@
/* base/src/drv $Id$ */
/*
*
* HP E1404A VXI bus slot zero translator
* device dependent routines
*
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
*
* Author Jeffrey O. Hill
* Date 030692
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 joh 073092 Added msg device support & interrupt shutdown for
* soft reboots
* .02 joh 082792 converted to ANSI C
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*
*
*
*/
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
#include <vxWorks.h>
#include <iv.h>
#include <intLib.h>
#include <rebootLib.h>
#include <devLib.h>
#include <drvEpvxi.h>
#include <drvHp1404a.h>
LOCAL unsigned long hpE1404DriverID;
struct hpE1404_config{
void (*pSignalCallback)(int16_t signal);
};
#define TLTRIG(N) (1<<(N))
#define ECLTRIG(N) (1<<((N)+8))
/*
* enable int when signal register is written
*/
#define HP1404A_INT_ENABLE 0x0008
#define HP1404A_INT_DISABLE 0x0000
/*
*
* tag the device dependent registers
*/
#define IRQ_enable dir.w.dd.reg.ddx1a
#define MSG_status dir.w.dd.reg.ddx1e
#define fp_trig_drive dir.w.dd.reg.ddx2a
#define bp_trig_drive dir.w.dd.reg.ddx22
#define signal_read dir.r.dd.reg.ddx10
#define hpE1404PConfig(LA, PC) \
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
LOCAL void hpE1404InitLA(
unsigned la
);
LOCAL int hpE1404ShutDown(
void
);
LOCAL void hpE1404ShutDownLA(
unsigned la
);
LOCAL void hpE1404IOReport(
unsigned la,
unsigned level
);
LOCAL void hpE1404Int(
unsigned la
);
/*
*
* hpE1404Init
*
*/
hpE1404Stat hpE1404Init(void)
{
hpE1404Stat status;
status = rebootHookAdd(hpE1404ShutDown);
if(status<0){
status = S_dev_internal;
errMessage(status, "rebootHookAdd() failed");
return status;
}
hpE1404DriverID = epvxiUniqueDriverID();
status = epvxiRegisterMakeName(
VXI_MAKE_HP,
"Hewlett-Packard");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_REG_SLOT0,
"Slot Zero Translator (reg)");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_REG,
"Translator (reg)");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_MSG,
"Translator (msg)");
if(status){
errMessage(status, NULL);
}
{
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return status;
}
dsp.model = VXI_HP_MODEL_E1404_REG;
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return status;
}
}
return VXI_SUCCESS;
}
/*
*
* hpE1404ShutDown()
*
*
*/
LOCAL int hpE1404ShutDown(void)
{
hpE1404Stat status;
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return ERROR;
}
dsp.model = VXI_HP_MODEL_E1404_REG;
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return ERROR;
}
return OK;
}
/*
*
* hpE1404ShutDownLA()
*
*
*/
LOCAL
void hpE1404ShutDownLA(
unsigned la
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
}
/*
*
* hpE1404InitLA()
*
*/
LOCAL
void hpE1404InitLA(
unsigned la
)
{
struct hpE1404_config *pc;
struct vxi_csr *pcsr;
hpE1404Stat status;
status = epvxiOpen(
la,
hpE1404DriverID,
sizeof(*pc),
hpE1404IOReport);
if(status){
errMessage(status, NULL);
return;
}
pcsr = VXIBASE(la);
status = hpE1404PConfig(la, pc);
if(status){
errMessage(status, NULL);
epvxiClose(la, hpE1404DriverID);
return;
}
/*
* set the self test status to passed for
* the message based device
*/
pcsr->MSG_status = VXIPASS<<2;
intConnect(
INUM_TO_IVEC(la),
hpE1404Int,
la);
/*
* enable int when signal register is written
*/
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
return;
}
/*
*
* hpE1404SignalConnect()
*
*/
hpE1404Stat hpE1404SignalConnect(
unsigned la,
void (*pSignalCallback)(int16_t signal)
)
{
hpE1404Stat s;
struct hpE1404_config *pc;
s = hpE1404PConfig(la, pc);
if(s){
return s;
}
pc->pSignalCallback = pSignalCallback;
return VXI_SUCCESS;
}
/*
*
* hpE1404Int()
*
*/
LOCAL
void hpE1404Int(
unsigned la
)
{
hpE1404Stat s;
struct vxi_csr *pcsr;
unsigned short signal;
struct hpE1404_config *pc;
s = hpE1404PConfig(la, pc);
if(s){
errMessage(s, NULL);
return;
}
/*
* vector is only D8 so we cant check the cause of the int
* (signal cause is assumed since that was all that was enabled)
*/
pcsr = VXIBASE(la);
signal = pcsr->signal_read;
if(pc->pSignalCallback){
(*pc->pSignalCallback)(signal);
}
}
/*
*
* hpE1404RouteTriggerECL
*
*/
hpE1404Stat hpE1404RouteTriggerECL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
return VXI_SUCCESS;
}
/*
*
*
* hpE1404RouteTriggerTTL
*
*
*/
hpE1404Stat hpE1404RouteTriggerTTL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->fp_trig_drive = io_map&enable_map;
pcsr->bp_trig_drive = (~io_map)&enable_map;
return VXI_SUCCESS;
}
/*
*
* hpE1404IOReport()
*
*
*/
LOCAL
void hpE1404IOReport(
unsigned la,
unsigned level
)
{
}

74
src/drv/ansi/drvHp1404a.h Normal file
View File

@@ -0,0 +1,74 @@
/* base/src/drv $Id$ */
/*
* drvHp1404a.h
*
* HP E1404A VXI bus slot zero translator
* device dependent routines header file
*
* share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93
*
* Author Jeffrey O. Hill
* Date 030692
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
*
*
*/
typedef long hpE1404Stat;
hpE1404Stat hpE1404Init(void);
hpE1404Stat hpE1404SignalConnect(
unsigned la,
void (*pSignalCallback)(int16_t signal)
);
hpE1404Stat hpE1404RouteTriggerECL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
);
hpE1404Stat hpE1404RouteTriggerTTL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
);
#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10
#define VXI_HP_MODEL_E1404_REG 0x110
#define VXI_HP_MODEL_E1404_MSG 0x111

359
src/drv/ansi/drvHpe1368a.c Normal file
View File

@@ -0,0 +1,359 @@
/* drvHpe1368a.c*/
/* base/src/drv $Id$ */
/*
* hpe1368a_driver.c
*
* driver for hpe1368a and hpe1369a microwave switch VXI modules
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 071792 joh Added model name registration
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
* .03 082692 mrk Added support for new I/O event scanning and DRVET
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
*
*/
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
#include <vxWorks.h>
#include <iv.h>
#include <types.h>
#include <intLib.h>
#include <sysLib.h>
#include <stdioLib.h>
#include <vxLib.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <drvEpvxi.h>
#include <dbDefs.h>
#include <drvSup.h>
#include <dbScan.h>
#include <devLib.h>
#include <drvHpe1368a.h>
#define HPE1368A_PCONFIG(LA, PC) \
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
#define ALL_SWITCHES_OPEN 0
struct hpe1368a_config{
FAST_LOCK lock; /* mutual exclusion */
unsigned short pending; /* switch position pending int */
unsigned short shadow; /* shadow of actual switch pos */
int busy; /* relays active */
IOSCANPVT ioscanpvt;
};
#define HPE1368A_INT_LEVEL 1
LOCAL int hpe1368aDriverId;
LOCAL void hpe1368a_int_service(unsigned la);
LOCAL void hpe1368a_init_card(unsigned la);
LOCAL void hpe1368a_stat(unsigned la, int level);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvHpe1368a={
2,
NULL, /*VXI io report takes care of this */
hpe1368a_init};
/*
* hpe1368a_init
*
* initialize all hpe1368a cards
*
*/
hpe1368aStat hpe1368a_init(void)
{
hpe1368aStat r0;
/*
* do nothing on crates without VXI
*/
if(!epvxiResourceMangerOK){
return VXI_SUCCESS;
}
hpe1368aDriverId = epvxiUniqueDriverID();
{
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_MODEL_HPE1368A;
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
if(r0){
errMessage(r0, NULL);
return r0;
}
}
return VXI_SUCCESS;
}
/*
* HPE1368A_INIT_CARD
*
* initialize single at5vxi card
*
*/
LOCAL void hpe1368a_init_card(unsigned la)
{
hpe1368aStat r0;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
int model;
r0 = epvxiOpen(
la,
hpe1368aDriverId,
(unsigned long) sizeof(*pc),
hpe1368a_stat);
if(r0){
errMessage(r0,NULL);
return;
}
r0 = HPE1368A_PCONFIG(la, pc);
if(r0){
errMessage(r0, NULL);
return;
}
pcsr = VXIBASE(la);
/*
* we must reset the device to a known state since
* we cant read back the current state
*/
pc->pending = ALL_SWITCHES_OPEN;
pc->shadow = ALL_SWITCHES_OPEN;
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
FASTLOCKINIT(&pc->lock);
scanIoInit(&pc->ioscanpvt);
r0 = intConnect(
INUM_TO_IVEC(la),
hpe1368a_int_service,
la);
if(r0 == ERROR){
errMessage(S_dev_vxWorksVecInstlFail, NULL);
return;
}
sysIntEnable(HPE1368A_INT_LEVEL);
model = VXIMODEL(pcsr);
r0 = epvxiRegisterModelName(
VXIMAKE(pcsr),
model,
"E 1368A Microwave Switch\n");
if(r0){
errMessage(r0, NULL);
}
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
if(r0){
errMessage(r0,NULL);
}
}
/*
*
* hpe1368a_int_service()
*
*
* This device interrupts once the
* switches have settled
*
*/
LOCAL void
hpe1368a_int_service(unsigned la)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la,pc);
if(s){
return;
}
/*
* operation completed so we can update
* the shadow value
*/
pc->shadow = pc->pending;
pc->busy = FALSE;
/*
* tell them that the switches have settled
*/
scanIoRequest(pc->ioscanpvt);
}
/*
* HPE1368A_STAT
*
* initialize single at5vxi card
*
*/
LOCAL void hpe1368a_stat(
unsigned la,
int level
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s,NULL);
return;
}
pcsr = VXIBASE(la);
if(level>0){
printf("\tSwitch states %x\n", pc->shadow);
printf("\tModule status %x\n", pcsr->dir.r.status);
if(pc->busy){
printf("\tModule is busy.\n");
}
}
}
/*
* hpe1368a_getioscanpvt()
*/
hpe1368aStat hpe1368a_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
*scanpvt = pc->ioscanpvt;
return VXI_SUCCESS;
}
/*
* HPE1368A_BO_DRIVER
*/
hpe1368aStat hpe1368a_bo_driver(
unsigned la,
unsigned val,
unsigned mask
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
unsigned int work;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
pcsr = VXIBASE(la);
FASTLOCK(&pc->lock);
work = pc->pending;
/* alter specified bits */
work = (work & ~mask) | (val & mask);
pc->pending = work;
ChannelEnable(pcsr) = work;
FASTUNLOCK(&pc->lock);
return VXI_SUCCESS;
}
/*
*
* HPE1368A_BI_DRIVER
*
*
*
*/
hpe1368aStat hpe1368a_bi_driver(
unsigned la,
unsigned mask,
unsigned *pval
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
FASTLOCK(&pc->lock);
*pval = pc->shadow & mask;
FASTUNLOCK(&pc->lock);
return VXI_SUCCESS;
}

View File

@@ -0,0 +1,60 @@
/* drvHpe1368a.h*/
/* base/src/drv $Id$ */
/*
* hpe1368a_driver.h
*
* driver for hpe1368a and hpe1369a microwave switch VXI modules
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
*/
#define VXI_MODEL_HPE1368A (0xf28)
typedef long hpe1368aStat;
hpe1368aStat hpe1368a_init(void);
hpe1368aStat hpe1368a_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
);
hpe1368aStat hpe1368a_bo_driver(
unsigned la,
unsigned val,
unsigned mask
);
hpe1368aStat hpe1368a_bi_driver(
unsigned la,
unsigned mask,
unsigned *pval
);

1185
src/drv/ansi/drvHpe1445a.c Normal file

File diff suppressed because it is too large Load Diff

484
src/drv/ansi/drvKscV215.c Normal file
View File

@@ -0,0 +1,484 @@
/* drvKscV215.c*/
/* base/src/drv $Id$ */
/*
* KscV215_driver.c
*
* driver for KscV215 VXI module
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 071792 joh Added model name registration
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
* .03 082692 mrk Added support for new I/O event scanning and DRVET
* .04 012893 joh include file name change
* .05 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
*
*/
#include <vxWorks.h>
#include <dbDefs.h>
#include <iv.h>
#include <types.h>
#include <stdioLib.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <drvEpvxi.h>
#include <drvSup.h>
#include <dbScan.h>
#include <devLib.h>
#include <drvKscV215.h>
#define MAXTRIES 100
#define KSCV215_PCONFIG(LA, PC) \
epvxiFetchPConfig((LA), KscV215DriverId, PC)
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
#define ALL_SWITCHES_OPEN 0
struct KscV215_config{
FAST_LOCK lock; /* mutual exclusion */
IOSCANPVT ioscanpvt;
};
#define KSCV215_INT_LEVEL 1
#define KscV215Handshake (0x0040)
#define KscV215csrInit (0x9000)
LOCAL int KscV215DriverId;
struct KscV215_A24{
volatile uint16_t diag;
volatile uint16_t isr;
volatile uint16_t pad1[7];
volatile uint16_t channels[64]; /* odd access causes a bus error ? */
volatile uint16_t controlMemoryAddr;
volatile uint16_t pad2;
volatile uint16_t controlMemoryDataWrite;
volatile uint16_t pad3;
volatile uint16_t controlMemoryDataRead;
volatile uint16_t pad4;
volatile uint16_t lastChannel;
volatile uint16_t pad5;
volatile uint16_t singleScan;
volatile uint16_t pad6;
volatile uint16_t stopScan;
volatile uint16_t pad7;
volatile uint16_t clearControlMemoryAddr;
volatile uint16_t pad8;
volatile uint16_t enableContinuousScanning;
volatile uint16_t pad9;
volatile uint16_t disableContinuousScanning;
volatile uint16_t pad10;
volatile uint16_t enableDoneInt;
volatile uint16_t pad11;
volatile uint16_t disbaleDoneInt;
volatile uint16_t pad12;
volatile uint16_t clearDoneInt;
volatile uint16_t pad13;
volatile uint16_t testDoneInt;
volatile uint16_t pad14;
};
#ifdef INTERRUPTS
LOCAL void KscV215_int_service(unsigned la);
#endif
LOCAL void KscV215_init_card(unsigned la);
LOCAL void KscV215_stat(
unsigned la,
int level
);
LOCAL kscV215Stat KscV215WriteSync(
struct KscV215_A24 *pA24,
volatile uint16_t *preg,
uint16_t val
);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvKscV215={
2,
NULL, /* VXI report takes care of this */
KscV215Init};
/*
* KscV215_init
*
* initialize all KscV215 cards
*
*/
kscV215Stat KscV215Init(void)
{
kscV215Stat r0;
/*
* do nothing on crates without VXI
*/
if(!epvxiResourceMangerOK){
return VXI_SUCCESS;
}
KscV215DriverId = epvxiUniqueDriverID();
{
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_KSC;
dsp.model = VXI_MODEL_KSCV215;
r0 = epvxiLookupLA(&dsp, KscV215_init_card, (void *)NULL);
if(r0){
return r0;
}
}
return VXI_SUCCESS;
}
/*
* KSCV215_INIT_CARD
*
* initialize single at5vxi card
*
*/
LOCAL void KscV215_init_card(unsigned la)
{
kscV215Stat status;
int i;
struct KscV215_config *pc;
struct KscV215_A24 *pA24;
struct vxi_csr *pcsr;
int model;
status = epvxiOpen(
la,
KscV215DriverId,
(unsigned long) sizeof(*pc),
KscV215_stat);
if(status){
errPrintf(
status,
__FILE__,
__LINE__,
"AT5VXI: device open failed %d\n",
la);
return;
}
status = KSCV215_PCONFIG(la, pc);
if(status){
errMessage(status,NULL);
epvxiClose(la, KscV215DriverId);
return;
}
pA24 = epvxiA24Base(la);
pcsr = VXIBASE(la);
pcsr->dir.w.control = KscV215csrInit;
status = KscV215WriteSync(pA24, &pA24->controlMemoryAddr, 0U);
if(status){
epvxiClose(la, KscV215DriverId);
errMessage(status, "KscV215 init failed\n");
return;
}
for(i=0; i<(NELEMENTS(pA24->channels)/2); i++){
status = KscV215WriteSync(
pA24,
&pA24->controlMemoryDataWrite,
0U);
if(status){
epvxiClose(la, KscV215DriverId);
errMessage(status, "KscV215 init failed\n");
return;
}
}
/*
* turn on continuous scan mode
*/
status = KscV215WriteSync(
pA24,
&pA24->enableContinuousScanning,
0U);
if(status){
epvxiClose(la, KscV215DriverId);
errMessage(status, "KscV215 init failed- device left open\n");
return;
}
FASTLOCKINIT(&pc->lock);
scanIoInit(&pc->ioscanpvt);
#ifdef INTERRUPTS
status = intConnect(
(unsigned char) INUM_TO_IVEC(la),
KscV215_int_service,
(void *) la);
if(status == ERROR){
epvxiClose(la, KscV215DriverId);
errMessage(S_dev_vxWorksVecInstlFail,
"KscV215 init failed- device left open");
return;
}
sysIntEnable(KSCV215_INT_LEVEL);
#endif
status = epvxiRegisterMakeName(VXI_MAKE_KSC, "Kinetic Systems");
if(status){
errMessage(status, NULL);
}
model = VXIMODEL(pcsr);
status = epvxiRegisterModelName(
VXIMAKE(pcsr),
model,
"V215 16 bit 32 channel ADC\n");
if(status){
errMessage(status, NULL);
}
}
/*
*
* KscV215WriteSync
*
*
*/
LOCAL kscV215Stat KscV215WriteSync(
struct KscV215_A24 *pA24,
volatile uint16_t *preg,
uint16_t val
)
{
kscV215Stat status;
int i;
for(i=0; i<MAXTRIES; i++){
*preg = val;
if(pA24->diag & KscV215Handshake){
return VXI_SUCCESS;
}
taskDelay(1);
}
status = S_dev_deviceTMO;
errMessage(status, NULL);
return status;
}
/*
*
* KscV215_int_service()
*
*
* This device interrupts once the
* switches have settled
*
*/
#ifdef INTERRUPTS
LOCAL void KscV215_int_service(unsigned la)
{
kscV215Stat s;
struct KscV215_config *pc;
s = KSCV215_PCONFIG(la, pc);
if(s){
logMsg( "Int to ukn device %s line=%d\n",
__FILE__,
__LINE__,
NULL,
NULL,
NULL,
NULL);
return;
}
/*
* tell them that the switches have settled
*/
scanIoRequest(pc->ioscanpvt);
}
#endif
/*
* KSCV215_STAT
*
* initialize single at5vxi card
*
*/
LOCAL void KscV215_stat(
unsigned la,
int level
)
{
kscV215Stat s;
struct KscV215_config *pc;
struct vxi_csr *pcsr;
struct KscV215_A24 *pA24;
int i;
s = KSCV215_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return;
}
pcsr = VXIBASE(la);
pA24 = (struct KscV215_A24 *) epvxiA24Base(la);
if(level>0){
printf ("KSC V215 32 CHANNEL 16 BIT ADC.\n");
}
if (level > 1) {
for (i = 0; i < 32; i++)
printf ("Channel %d Value %d\n",
i,
pA24->channels[i*2]);
}
if (level > 2) {
printf ("\nGain Setting (Control Memory Data Register\n");
pA24->controlMemoryAddr = 0;
for (i = 0; i < 32; i++) {
switch (pA24->controlMemoryAddr) {
case 0:
printf ("+- 10V");
break;
case 1:
printf ("+- 5V");
break;
case 3:
printf ("+- 2.5V");
break;
case 5:
printf ("+- 1.25V");
break;
case 6:
printf ("+- 625mV");
break;
default:
printf ("Unknown Gain Setting.");
}
}
printf ("\n");
}
}
/*
*
*
* AT5VXI_AI_DRIVER
*
* analog input driver
*/
kscV215Stat KscV215_ai_driver(
unsigned la,
unsigned chan,
unsigned short *prval
)
{
struct KscV215_config *pc;
struct vxi_csr *pcsr;
struct KscV215_A24 *pA24;
long tmp;
int i;
kscV215Stat s;
s = KSCV215_PCONFIG(la, pc);
if(s){
return s;
}
pcsr = VXIBASE(la);
pA24 = epvxiA24Base(la);
if(chan >= NELEMENTS(pA24->channels)/2){
return S_dev_badSignalNumber;
}
for(i=0; i<MAXTRIES; i++){
tmp = pA24->channels[chan<<1];
if(pA24->diag & KscV215Handshake){
tmp = tmp + 0xffff;
tmp = tmp >> 4;
tmp &= 0xfff;
*prval = tmp;
return VXI_SUCCESS;
}
taskDelay(1);
}
s = S_dev_deviceTMO;
return s;
}
/*
* KscV215_getioscanpvt()
*/
kscV215Stat KscV215_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
)
{
kscV215Stat s;
struct KscV215_config *pc;
s = KSCV215_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
*scanpvt = pc->ioscanpvt;
return VXI_SUCCESS;
}

56
src/drv/ansi/drvKscV215.h Normal file
View File

@@ -0,0 +1,56 @@
/* drvKscV215.c*/
/* base/src/drv $Id$ */
/*
* KscV215_driver.c
*
* driver for KscV215 VXI module
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
*/
#define VXI_MODEL_KSCV215 (0x215)
typedef long kscV215Stat;
kscV215Stat KscV215Init(void);
kscV215Stat KscV215_ai_driver(
unsigned la,
unsigned chan,
unsigned short *prval
);
kscV215Stat KscV215_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
);

627
src/drv/ansi/drvMz8310.c Normal file
View File

@@ -0,0 +1,627 @@
/* drvMz8310.c */
/* base/src/drv $Id$ */
/*
* Routines specific to the MZ8310. Low level routines for the AMD STC in
* stc_driver.c
* Author: Jeff Hill
* Date: Feb 1989
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification History
* joh 02-20-89 Init Release
* joh 04-28-89 Added read back
* joh 11-17-89 added readback to io report
* joh 12-10-89 DB defaults the internal/external clock
* parameter to 0 or external clock. This was the opposite
* of what this driver expected. Fix was made here.
* joh 07-06-90 print channel number with channel value in IO report
* joh 02-25-91 made ext/int clk IO report more readable
* joh 09-05-91 converted to v5 vxWorks
* bg 09-15-91 added sysBustoLocalAdrs() for addressing
* bg 03-10-92 added the argument, level, to mz310_io_report().
* bg 04-27-92 added rebootHookAdd and mz8310_reset so ioc will
* not hang on ctl X reboot.
* joh 04-28-92 added arguments to MACROS which had hidden
* parameters
* bg 06-25-92 combined drvMz8310.c and mz8310_driver.c
* bg 06-26-92 Added level to mz8310_io_report.
* joh 08-05-92 callable interface now conforms with epics standard
* mgb 08-04-93 Removed V5/V4 and EPICS_V2 conditionals
* joh 08-24-93 Include drvStc.h and ANSI C upgrade
* joh 09-29-93 removed superfluous error message
*/
/* drvMz8310.c - Driver Support Routines for Mz8310 */
#include <vxWorks.h>
#include <stdioLib.h>
#include <sysLib.h>
#include <stdlib.h>
#include <intLib.h>
#include <rebootLib.h>
#include <vxLib.h>
#include <vme.h>
#include <iv.h>
#include <dbDefs.h>
#include <drvSup.h>
#include <module_types.h>
#include <fast_lock.h>
#include <devLib.h>
#include <drvStc.h>
#include <drvMz8310.h>
#define MZ8310CHIPSIZE 0x20
#define MZ8310SIZE 0x00000100
#define MZ8310BASE(CARD) (shortaddr+tm_addrs[MZ8310]+(CARD)*MZ8310SIZE)
#define MZ8310DATA 0
#define MZ8310CMD 3
#define MZ8310CHANONCHIP 5
#define MZ8310CHIPCOUNT 2
#define MZ8310CHANCNT (MZ8310CHANONCHIP*MZ8310CHIPCOUNT)
/*
NOTE: The mizar draftsman has labeled the chip at the
highest address as one and the chip at the lowest address
2 so I am reversing the chip number below.
*/
#define CHIP_REVERSE(CHIP) (MZ8310CHIPCOUNT-1-(CHIP))
#define CHIP_ADDR(CARD,CHIP) (MZ8310BASE(CARD)+\
(CHIP_REVERSE(CHIP)*MZ8310CHIPSIZE))
#define MZ8310_CMD_ADDR(CARD,CHIP)\
((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + MZ8310CMD)
#define MZ8310_DATA_ADDR(CARD,CHIP)\
((volatile uint16_t *) CHIP_ADDR(CARD,CHIP) + MZ8310DATA)
#if 0
#define MZ8310VECBASE(CARD,CHIP)\
((volatile uint8_t *) CHIP_ADDR(CARD,CHIP) + 0x41)
#endif
#define MZ8310VECSIZE (0x20)
#define MZ8310INTCNT 4
#define MZ8310FIRSTINTCHAN 0
#define MZ8310INTVEC(CARD,CHAN)\
(MZ8310_INT_VEC_BASE + (CARD*MZ8310INTCNT) + mz8310_strap[CHAN].vec_num)
#define MZ8310_INTERUPTABLE(CHAN) (mz8310_strap[CHAN].vec_addr)
# define INT_TICKS 4.0e06 /* speed of F1 in Hz */
# define EXT_TICKS 5.0e06 /* GTA std speed of SRC1 in Hz */
struct mz8310_int_conf{
void (*user_service)(void *user_param);
void *user_param;
unsigned int cnt;
};
struct mz8310_conf{
char init;
FAST_LOCK lock;
struct mz8310_int_conf icf[MZ8310CHANCNT];
};
struct mz8310_strap_info{
unsigned char irq; /* the level at which the chan gen ints */
unsigned char vec_num; /* really a vec offset-see MZ8310INTVEC */
unsigned char vec_addr;/* offset from card base address */
};
static volatile char *shortaddr;
LOCAL struct mz8310_conf *mzconf;
LOCAL unsigned int mz8310_card_count;
/*
only 4 unique interrupts per card but any channel can potentially
generate an interrupt depending on board strapping.
NOTE: existence of vec addr tells the driver that that channel is
strapped for interrupts since the card can't be polled for this info.
In the MIZAR 8310 Documentation:
Designation vector reg offset
IRQA 0x41
IRQB 0x61
IRQC 0x81
IRQD 0xa1
*/
LOCAL struct mz8310_strap_info mz8310_strap[MZ8310CHANCNT] =
{
{ NULL, NULL, NULL }, /* channel 0 */
{ NULL, NULL, NULL }, /* channel 1 */
{ NULL, NULL, NULL }, /* channel 2 */
{ NULL, NULL, NULL }, /* channel 3 */
{ NULL, NULL, NULL }, /* channel 4 */
{ NULL, NULL, NULL }, /* channel 5 */
{ 1, 0, 0x41 }, /* channel 6 */
{ 3, 1, 0x61 }, /* channel 7 */
{ 5, 2, 0x81 }, /* channel 8 */
{ 6, 3, 0xa1 } /* channel 9 */
};
/* forward reference. */
LOCAL int mz8310_reset(void);
LOCAL mz8310Stat mz8310_io_report_card(unsigned card, unsigned level);
LOCAL mz8310Stat mz8310_init_card(unsigned card);
LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel);
LOCAL mz8310Stat mz8310_io_report(unsigned level);
LOCAL mz8310Stat mz8310_init(void);
LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel);
LOCAL void mz8310_int_service(struct mz8310_int_conf *icf);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvMz8310={
2,
mz8310_io_report,
mz8310_init};
/*
* mz8310_io_report()
*/
LOCAL mz8310Stat mz8310_io_report(unsigned level)
{
unsigned card;
for(card=0; card<tm_num_cards[MZ8310]; card++)
mz8310_io_report_card(card, level);
return MZ8310_SUCCESS;
}
/*
* mz8310_io_report_card()
*/
LOCAL mz8310Stat mz8310_io_report_card(unsigned card, unsigned level)
{
unsigned channel;
unsigned chip;
mz8310Stat status;
for(chip=0; chip<MZ8310CHIPCOUNT; chip++){
status = stc_io_report(
MZ8310_CMD_ADDR(card,chip),
MZ8310_DATA_ADDR(card,chip));
if(status){
return status;
}
}
printf("TM: MZ8310:\tcard %d\n", card);
if (mzconf && card<mz8310_card_count && level){
for(channel=0;channel<MZ8310CHANCNT;channel++){
status = mz8310_read_test(card, channel);
if(status){
return status;
}
}
}
return MZ8310_SUCCESS;
}
/*
* mz8310_init()
*/
LOCAL mz8310Stat mz8310_init(void)
{
unsigned card;
mz8310Stat status;
struct mz8310_conf *temp_mzconf;
unsigned card_count = tm_num_cards[MZ8310];
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
0,
(char **)&shortaddr);
if (status != OK){
status = S_dev_badA16;
errMessage(status, "A16 Address map error mz8310 driver");
return status;
}
temp_mzconf = (struct mz8310_conf *) malloc(sizeof(*mzconf)*card_count);
if(!temp_mzconf)
return S_dev_noMemory;
for(card=0; card<card_count; card++){
FASTLOCKINIT(&temp_mzconf[card].lock);
}
if(mzconf){
for(card=0; card<card_count; card++){
if(FASTLOCKFREE(&mzconf[card].lock)<0){
status = S_dev_internal;
errMessage(status, "error freeing sem");
}
}
free(mzconf);
}
mzconf = temp_mzconf;
for(card=0; card<card_count; card++){
status = mz8310_init_card(card);
if(status){
break;
}
}
mz8310_card_count = card;
rebootHookAdd(mz8310_reset);
return MZ8310_SUCCESS;
}
/*
*
* mz8310_init_card()
*
* Locking for this provided by mz8310_init()
*/
LOCAL mz8310Stat mz8310_init_card(unsigned card)
{
unsigned chip;
unsigned chan;
mz8310Stat error;
/*
* binary division
* data ptr seq enbl
* 16 bit bus
* FOUT on
* FOUT divide by one
* FOUT source (F1)
* Time of day disabled
*/
unsigned short master_mode = 0x2100;
for(chip=0; chip< MZ8310CHIPCOUNT; chip++){
error = stc_init(
MZ8310_CMD_ADDR(card,chip),
MZ8310_DATA_ADDR(card,chip),
master_mode);
if(error){
return error;
}
}
for(chan=0; chan<MZ8310CHANCNT; chan++)
mz8310_setup_int(card,chan);
mzconf[card].init = TRUE;
return MZ8310_SUCCESS;
}
/*
* mz8310_setup_int()
*
* (locked by calling routines)
*/
LOCAL mz8310Stat mz8310_setup_int(unsigned card, unsigned channel)
{
unsigned char vector;
mz8310Stat status;
mzconf[card].icf[channel].user_service = NULL;
mzconf[card].icf[channel].user_param = NULL;
mzconf[card].icf[channel].cnt = 0;
/*
* Is this channel strapped for interrupts
*/
if(!MZ8310_INTERUPTABLE(channel))
return MZ8310_SUCCESS;
vector = MZ8310INTVEC(card,channel);
status = vxMemProbe(
(char *)MZ8310BASE(card) + mz8310_strap[channel].vec_addr,
WRITE,
sizeof(vector),
(char *)&vector);
if(status != OK){
status = S_dev_noDevice;
errMessage(status, NULL);
return S_dev_noDevice;
}
status = intConnect( INUM_TO_IVEC(vector),
mz8310_int_service,
(int)&mzconf[card].icf[channel]);
if(status != OK)
return S_dev_vxWorksVecInstlFail;
sysIntEnable(mz8310_strap[channel].irq);
return MZ8310_SUCCESS;
}
/*
* mz8310_one_shot_read()
*/
mz8310Stat mz8310_one_shot_read(
unsigned *preset, /* TRUE or COMPLEMENT logic */
double *edge0_delay, /* sec */
double *edge1_delay, /* sec */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
)
{
int chip = channel/MZ8310CHANONCHIP;
double ticks;
unsigned short iedge0;
unsigned short iedge1;
mz8310Stat status;
if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT)
return S_dev_badSignalNumber;
if(card>=mz8310_card_count)
return S_dev_badA16;
if(!mzconf)
return S_dev_noDevice;
FASTLOCK(&mzconf[card].lock);
status =
stc_one_shot_read(
preset,
&iedge0,
&iedge1,
MZ8310_CMD_ADDR(card,chip),
MZ8310_DATA_ADDR(card,chip),
channel % MZ8310CHANONCHIP,
int_source);
if(status==STC_SUCCESS){
ticks = *int_source ? INT_TICKS : EXT_TICKS;
*edge0_delay = iedge0 / ticks;
*edge1_delay = iedge1 / ticks;
}
FASTUNLOCK(&mzconf[card].lock);
return status;
}
/*
* mz8310_read_test()
*/
LOCAL mz8310Stat mz8310_read_test(unsigned card, unsigned channel)
{
unsigned preset;
double edge0_delay;
double edge1_delay;
unsigned int_source;
mz8310Stat status;
static char *pclktype[] = {"external-clk", "internal-clk"};
static char *ppresettype[] = {"preset-FALSE", "preset-TRUE "};
status =
mz8310_one_shot_read(
&preset,
&edge0_delay,
&edge1_delay,
card,
channel,
&int_source);
if(status==MZ8310_SUCCESS){
printf( "\tChannel %u %s delay=%f width=%f %s\n",
channel,
ppresettype[preset&1],
edge0_delay,
edge1_delay,
pclktype[int_source&1]);
if(mzconf[card].icf[channel].cnt)
printf("\tChannel %u Interrupt count=%u\n",
channel,
mzconf[card].icf[channel].cnt);
}
return status;
}
/*
* mz8310_one_shot()
*/
mz8310Stat mz8310_one_shot(
unsigned preset, /* TRUE or COMPLEMENT logic */
double edge0_delay, /* sec */
double edge1_delay, /* set */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */
void (*event_rtn)(void *pParam), /* subroutine to run on events */
void *event_rtn_param /* parameter to pass to above routine */
)
{
int chip = channel/MZ8310CHANONCHIP;
double ticks = int_source?INT_TICKS:EXT_TICKS;
mz8310Stat status;
if(channel >= MZ8310CHANONCHIP * MZ8310CHIPCOUNT)
return S_dev_badSignalNumber;
if(card>=mz8310_card_count)
return S_dev_badA16;
if(!mzconf)
return S_dev_noDevice;
/* dont overflow unsigned short in STC */
if(edge0_delay >= 0xffff/ticks)
return S_dev_highValue;
if(edge1_delay >= 0xffff/ticks)
return S_dev_highValue;
if(edge0_delay < 0.0)
return S_dev_lowValue;
if(edge1_delay < 0.0)
return S_dev_lowValue;
FASTLOCK(&mzconf[card].lock);
/* Enable calling of user routine */
if(MZ8310_INTERUPTABLE(channel)){
mzconf[card].icf[channel].user_service = event_rtn;
mzconf[card].icf[channel].user_param = event_rtn_param;
}
status =
stc_one_shot(
preset,
(unsigned short) (edge0_delay * ticks),
(unsigned short) (edge1_delay * ticks),
MZ8310_CMD_ADDR(card,chip),
MZ8310_DATA_ADDR(card,chip),
channel % MZ8310CHANONCHIP,
int_source);
FASTUNLOCK(&mzconf[card].lock);
return status;
}
/*
* mz8310_int_service()
*/
LOCAL void mz8310_int_service(struct mz8310_int_conf *icf)
{
icf->cnt++;
if(icf->user_service)
(*icf->user_service)(icf->user_param);
return;
}
/*
* The following are provided for mz8310 access from the shell
*/
/*
* mz8310_cmd()
*/
int mz8310_cmd(
unsigned value,
unsigned card,
unsigned chip
)
{
volatile unsigned char *cmd = MZ8310_CMD_ADDR(card,chip);
*cmd = value;
return *cmd;
}
/*
* mz8310_rdata()
*/
int mz8310_rdata(int card, int chip)
{
volatile unsigned short *data = MZ8310_DATA_ADDR(card,chip);
return *data;
}
/*
* mz8310_wdata()
*/
int mz8310_wdata(
unsigned value,
unsigned card,
unsigned chip
)
{
volatile uint16_t *data = MZ8310_DATA_ADDR(card,chip);
*data = value;
return value;
}
/*
* mz8310_reset
*/
LOCAL int mz8310_reset(void)
{
short card,channel,chip;
for (card = 0; card < mz8310_card_count; card++){
FASTLOCK(&mzconf[card].lock);
for ( channel = 0; channel < tm_num_channels[MZ8310]; channel++){
if (mzconf[card].icf[channel].cnt){
chip = channel/MZ8310CHANONCHIP;
stc_one_shot(
0,
10,
0,
MZ8310_CMD_ADDR(card,chip),
MZ8310_DATA_ADDR(card,chip),
channel % MZ8310CHANONCHIP,
0);
}
}
FASTUNLOCK(&mzconf[card].lock);
}
return OK;
}

74
src/drv/ansi/drvMz8310.h Normal file
View File

@@ -0,0 +1,74 @@
/* drvMz8310.c */
/* base/src/drv $Id$ */
/*
* Routines specific to the MZ8310. Low level routines for the AMD STC in
* stc_driver.c
* Author: Jeff Hill
* Date: Feb 1989
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification History
*/
#define MZ8310_SUCCESS 0
typedef long mz8310Stat;
mz8310Stat mz8310_one_shot_read(
unsigned *preset, /* TRUE or COMPLEMENT logic */
double *edge0_delay, /* sec */
double *edge1_delay, /* sec */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
);
mz8310Stat mz8310_one_shot(
unsigned preset, /* TRUE or COMPLEMENT logic */
double edge0_delay, /* sec */
double edge1_delay, /* set */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned int_source, /* (FALSE)External/ (TRUE)Internal source */
void (*event_rtn)(void *pParam), /* subroutine to run on events */
void *event_rtn_param /* parameter to pass to above routine */
);
int mz8310_cmd(
unsigned value,
unsigned card,
unsigned chip
);
int mz8310_rdata(int card, int chip);
int mz8310_wdata(
unsigned value,
unsigned card,
unsigned chip
);

290
src/drv/ansi/drvStc.c Normal file
View File

@@ -0,0 +1,290 @@
/* drvStc.c */
/* base/src/drv $Id$ */
/*
* The following are specific driver routines for the AMD STC
*
* NOTE: if multiple threads use these routines at once you must provide locking
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
*
*
* Author: Jeff Hill
* Date: Feb 89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
* joh 022089 Init Release
* joh 042889 Added read back
* joh 111789 Fixed reset goes to byte mode bug
* joh 121090 Fixed confusion about the polarity of internal/external
* clock between DB and the drivers.
* joh 110791 Prevent the stc from generating tc prior to the trigger
* in delayed pulse mode by forcing edge 0 delays of zero to be
* a delay of one instead.
* joh 010491 force all edge 0 delays less than two to two
* joh 082493 ANSI C and EPICS return codes
*/
#include <vxWorks.h>
#include <stdioLib.h>
#include <vxLib.h>
#include <dbDefs.h>
#include <drvSup.h>
#include <module_types.h>
#include <drvStc.h>
#include <devLib.h>
/*
* stc_io_report()
*/
stcStat stc_io_report(
volatile uint8_t *pcmd,
volatile uint16_t *pdata
)
{
uint8_t cmd;
uint16_t data;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
/*
* addd AMD STC status here
*/
return STC_SUCCESS;
}
/*
* stc_init()
*/
stcStat stc_init(
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned master_mode
)
{
uint8_t cmd;
uint16_t data;
unsigned channel;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
/*
* go to 16 bit mode in order to test the master mode register
*/
STC_BUS16;
if(master_mode != STC_MASTER_MODE){
/*
* start in a known state
*/
STC_RESET;
/*
* required since the reset puts it in byte mode
*/
STC_BUS16;
STC_SET_MASTER_MODE(master_mode);
for(channel=0; channel<CHANONCHIP; channel++)
STC_LOAD;
}
return STC_SUCCESS;
}
/*
* stc_one_shot_read()
*/
stcStat stc_one_shot_read(
unsigned *preset,
unsigned short *edge0_count,
unsigned short *edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned *int_source
)
{
uint8_t cmd;
uint16_t data;
uint16_t mode;
uint16_t edge0;
uint16_t edge1;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
if(channel>=CHANONCHIP)
return S_dev_badSignalNumber;
STC_CTR_READ(mode, edge0, edge1);
/*
* Only return values if the counter is in the proper mode
* see stc_one_shot() for info on conversions and functions selected
* by these bit fields
*/
if(mode == 0xc16a){
*int_source = FALSE;
*preset = TRUE;
*edge0_count = ~edge0;
*edge1_count = ~edge1+1;
}
else if(mode == 0xc162){
*int_source = FALSE;
*preset = FALSE;
*edge0_count = edge0-1;
*edge1_count = edge1;
}
else if(mode == 0xcb6a){
*int_source = TRUE;
*preset = TRUE;
*edge0_count = ~edge0;
*edge1_count = ~edge1+1;
}
else if(mode == 0xcb62){
*int_source = TRUE;
*preset = FALSE;
*edge0_count = edge0-1;
*edge1_count = edge1;
}
else
return S_dev_internal;
return STC_SUCCESS;
}
/*
* stc_one_shot()
*/
stcStat stc_one_shot(
unsigned preset,
unsigned edge0_count,
unsigned edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned int_source
)
{
uint8_t cmd;
uint16_t data;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
if(channel>=CHANONCHIP)
return S_dev_badSignalNumber;
/*
* joh 110791
* Prevent the stc from generating tc prior to the trigger
* in delayed pulse mode by forcing edge 0 delays of zero to be
* a delay of one instead.
*
* 010492
* Strange extra edges occur when the delay is 0 or 1
* and the counter is reinitialized to a width of
* zero so I have disabled a delay of one also
*
* These extra edges occur when TC is set
*/
if(edge0_count < 2)
edge0_count = 2;
STC_DISARM;
/*
* active positive going edge (gate input)
* count on the rising edge of source
* ctr source: (F1- internal) (SRC1- external)
* mode L - Hardware triggered delayed pulse one-shot
* binary count
* count down (count up if preset is TRUE)
* TC toggled output
*
* see chapter 7 of the Am9513 STC tech man concerning count + 1
*
*/
/*
* NOTE: I must be able to read back the state of the preset later
* so I encode this information in the count down/up bit.
* count up on TRUE preset
* count down on FALSE preset
*
* see stc_one_shot_read() above
*/
if(int_source){
if(preset)
STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1)
else
STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count);
}else{
if(preset)
STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1)
else
STC_CTR_INIT(0xc162, edge0_count+1, edge1_count);
}
STC_LOAD;
/*
*see chapter 7 of the Am9513 STC tech man concerning this step
*/
STC_STEP;
STC_SET_TC(preset);
/*
* Only arm counter if the pulse has a finite duration
*/
if(edge1_count != 0){
STC_ARM;
}
return STC_SUCCESS;
}

107
src/drv/ansi/drvStc.h Normal file
View File

@@ -0,0 +1,107 @@
/* drvStc.h */
/* base/src/drv $Id$ */
/*
* The following are specific driver routines for the AMD STC
*
* NOTE: if multiple threads use these routines at once you must provide locking
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
*
*
* Author: Jeff Hill
* Date: Feb 89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
* joh 022089 Init Release
* joh 082493 ANSI C and EPICS return codes
*/
/*
* AMD STC constants
*/
#define CHANONCHIP 5U
#define CHIPCHAN (channel%CHANONCHIP)
#define CHIPNUM (channel/CHANONCHIP)
#define STC_RESET *pcmd = 0xffU
#define STC_BUS16 *pcmd = 0xefU
#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);}
#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata)
#define STC_CTR_INIT(MODE,LOAD,HOLD)\
{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);}
#define STC_CTR_READ(MODE,LOAD,HOLD)\
{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;}
#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U)
#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN)
#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U)
#define STC_ARM *pcmd = 0x20U | 1<<CHIPCHAN
#define STC_DISARM *pcmd = 0xc0U | 1<<CHIPCHAN
/*
* return type of the stc routines
*/
typedef long stcStat;
#define STC_SUCCESS 0
stcStat stc_io_report(
volatile uint8_t *pcmd,
volatile uint16_t *pdata
);
stcStat stc_init(
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned master_mode
);
stcStat stc_one_shot_read(
unsigned *preset,
uint16_t *edge0_count,
uint16_t *edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned *int_source
);
stcStat stc_one_shot(
unsigned preset,
unsigned edge0_count,
unsigned edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned int_source
);

250
src/drv/ansi/drvTime.c Normal file
View File

@@ -0,0 +1,250 @@
/* drvTime.c */
/* base/src/drv $Id$ */
/* Glue between timing_drivers and the GTA database
* Author: Jeff Hill
* Date: Feb 89
*
* Experimental Physics and Industrial Control System (EPICS)
*
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos Natjonal Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* joh 02-20-89 Init Release
* joh 11-16-89 added vxi timing
* bg 11-18-91 added time_io_report
* bg 02-24-91 added levels to time_io_report.
* bg 06-26-92 Combined time_driver.c and drvTime.c
* joh 08-05-92 removed report & init routines
*/
static char *sccsID = "@(#)drvTime.c 1.10\t9/9/93";
/* drvTime.c - Driver Support Routines for Time */
#include <vxWorks.h>
#include <logLib.h>
#include <module_types.h>
#include <epicsPrint.h>
#include <drvMz8310.h>
#include <drvAt5Vxi.h>
struct pulse{
double offset;
double width;
};
/*
*
* time_driver_read()
*
*
*/
int time_driver_read
(
card, /* 0 through ... */
channel, /* 0 through chans on card */
card_type, /* module type as stored in GTA DB */
int_source, /* (TRUE)External/ (FALSE)Internal source */
preset, /* TRUE or COMPLEMENT logic */
pulses, /* ptr to array of structure describing pulses */
npulses, /* N elements found */
npulmax /* N elements in the caller's array */
)
unsigned card;
unsigned channel;
unsigned card_type;
unsigned *int_source;
unsigned *preset;
struct pulse *pulses;
unsigned *npulses;
unsigned npulmax;
{
int status;
*npulses=0;
switch(card_type){
case MZ8310:
if(npulmax<1)
return ERROR;
status = mz8310_one_shot_read (
preset,
&pulses->offset,
&pulses->width,
card,
channel,
int_source
);
if(status==0)
*npulses=1;
return status;
case VXI_AT5_TIME:
if(npulmax<1)
return ERROR;
status = at5vxi_one_shot_read (
preset,
&pulses->offset,
&pulses->width,
card,
channel,
int_source
);
if(status==0)
*npulses=1;
return status;
case DG535:
break;
default:
break;
}
epicsPrintf("time_driver: No support for that type of timing card\n");
return ERROR;
}
int time_driver (
card, /* 0 through ... */
channel, /* 0 through chans on card */
card_type, /* module type as stored in GTA DB */
int_source, /* (TRUE)External/ (FALSE)Internal source */
preset, /* TRUE or COMPLEMENT logic */
pulses, /* ptr to array of structure describing pulses */
npulses, /* N elements in this array */
eventrtn, /* routine to run on events */
eventrtnarg /* argument to above rtn */
)
unsigned int card;
unsigned int channel;
unsigned int card_type;
unsigned int int_source;
int preset;
struct pulse *pulses;
unsigned int npulses;
void (*eventrtn)(void *pParam);
void *eventrtnarg;
{
switch(card_type){
case MZ8310:
if(npulses != 1)
return ERROR;
return mz8310_one_shot (
preset,
pulses->offset,
pulses->width,
card,
channel,
int_source,
eventrtn,
eventrtnarg
);
case VXI_AT5_TIME:
if(npulses != 1)
return ERROR;
return at5vxi_one_shot (
preset,
pulses->offset,
pulses->width,
card,
channel,
int_source,
eventrtn,
eventrtnarg
);
case DG535:
break;
default:
break;
}
epicsPrintf("time_driver: No support for that type of timing card\n");
return ERROR;
}
int time_test()
{
unsigned int card=0;
unsigned int channel=0;
unsigned int card_type=MZ8310;
unsigned int int_source=1;
int preset=1;
static struct
pulse pulses={.00001,.00001};
unsigned int npulses = 1;
unsigned int t_int_source;
int t_preset;
struct pulse t_pulses;
unsigned int t_npulses;
int status;
status =
time_driver (
card, /* 0 through ... */
channel, /* 0 through chans on card */
card_type, /* module type as stored in GTA DB */
int_source, /* (TRUE)External/ (FALSE)Internal source */
preset, /* TRUE or COMPLEMENT logic */
&pulses, /* ptr to array of structure describing pulses */
npulses, /* N elements in this array */
NULL, /* routine to run on events */
NULL /* argument to above rtn */
);
if(status==ERROR)
return ERROR;
status =
time_driver_read(
card, /* 0 through ... */
channel, /* 0 through chans on card */
card_type, /* module type as stored in GTA DB */
&t_int_source, /* (TRUE)External/ (FALSE)Internal source */
&t_preset, /* TRUE or COMPLEMENT logic */
&t_pulses, /* ptr to array of structure describing pulses */
&t_npulses, /* N elements found */
1 /* max N elements in this array */
);
if(status==ERROR)
return ERROR;
epicsPrintf( "wrote: preset %x internal-clk %x delay %f width %f \n",
preset,
int_source,
pulses.offset,
pulses.width);
epicsPrintf( "read: preset %x internal-clk %x delay %f width %f count %x\n",
t_preset,
t_int_source,
t_pulses.offset,
t_pulses.width,
t_npulses);
return OK;
}

View File

@@ -9,30 +9,19 @@ include $(EPICS)/config/CONFIG_BASE
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield -traditional
SRCS.c += ../module_types.c
SRCS.c += ../drvAt5Vxi.c
SRCS.c += ../drvBB232.c
SRCS.c += ../drvBb902.c
SRCS.c += ../drvBb910.c
SRCS.c += ../drvBitBus.c
# SRCS.c += ../drvCaenV265.c
SRCS.c += ../drvComet.c
SRCS.c += ../drvCompuSm.c
SRCS.c += ../drvDvx.c
SRCS.c += ../drvEpvxi.c
SRCS.c += ../drvEpvxiMsg.c
SRCS.c += ../drvFp.c
SRCS.c += ../drvFpm.c
SRCS.c += ../drvGpib.c
SRCS.c += ../drvHp1404a.c
SRCS.c += ../drvHpe1368a.c
SRCS.c += ../drvHpe1445a.c
SRCS.c += ../drvJgvtr1.c
SRCS.c += ../drvKscV215.c
SRCS.c += ../drvMsg.c
SRCS.c += ../drvMz8310.c
SRCS.c += ../drvOms.c
SRCS.c += ../drvStc.c
SRCS.c += ../drvTime.c
# SRCS.c += ../drvTranServ.c
SRCS.c += ../drvVmi4100.c
SRCS.c += ../drvXy010.c
@@ -42,30 +31,19 @@ SRCS.c += ../drvXy240.c
SRCS.c += ../drvXy566.c
TARGETS += module_types.o
TARGETS += drvAt5Vxi.o
TARGETS += drvBB232.o
TARGETS += drvBb902.o
TARGETS += drvBb910.o
TARGETS += drvBitBus.o
# TARGETS += drvCaenV265.o
TARGETS += drvComet.o
TARGETS += drvCompuSm.o
TARGETS += drvDvx.o
TARGETS += drvEpvxi.o
TARGETS += drvEpvxiMsg.o
TARGETS += drvFp.o
TARGETS += drvFpm.o
TARGETS += drvGpib.o
TARGETS += drvHp1404a.o
TARGETS += drvHpe1368a.o
TARGETS += drvHpe1445a.o
TARGETS += drvJgvtr1.o
TARGETS += drvKscV215.o
TARGETS += drvMsg.o
TARGETS += drvMz8310.o
TARGETS += drvOms.o
TARGETS += drvStc.o
TARGETS += drvTime.o
# TARGETS += drvTranServ.o
TARGETS += drvVmi4100.o
TARGETS += drvXy010.o

View File

@@ -1,6 +1,3 @@
/* drvGpib.c */
/* share/src/drv/drvGpib.c %W% %G% */
/******************************************************************************
*
* TODO:
@@ -62,6 +59,9 @@
*
*
* $Log$
* Revision 1.2 1995/04/12 19:31:41 winans
* Added support for the HiDEOS system as a GPIB bus transport agent.
*
* Revision 1.28 1995/02/14 22:33:01 winans
* Cleaned up some Hideos hacking and commented out the LANL debug code because
* APS has had some add behaviour from GPIB lately and it is one of few things
@@ -87,6 +87,7 @@
*
*/
#define INCLUDE_HIDEOS_INTERFACE
#include <vxWorks.h>
#include <types.h>
#include <iosLib.h>
@@ -98,19 +99,24 @@
#include <vme.h>
#include <wdLib.h>
#include <rngLib.h>
#include <symLib.h>
#include <sysSymTbl.h> /* idiots at WRS have undocumented stuff in here */
#include <devLib.h>
#include <ellLib.h>
#include <task_params.h>
#include <module_types.h>
#include <drvSup.h>
#include <dbDefs.h>
#include <link.h>
#include <fast_lock.h>
#include <taskwd.h>
#include "devLib.h"
#include "ellLib.h"
#include "task_params.h"
#include "module_types.h"
#include "drvSup.h"
#include "dbDefs.h"
#include "link.h"
#include "fast_lock.h"
#include "taskwd.h"
#include <drvGpibInterface.h>
#include <drvBitBusInterface.h>
#ifdef INCLUDE_HIDEOS_INTERFACE
#include "drvHiDEOSGpib.h"
#endif
#include "drvGpibInterface.h"
#include "drvBitBusInterface.h"
#include "drvGpib.h"
#define STATIC /* static */
@@ -155,9 +161,6 @@ STATIC int defaultTimeout; /* in 60ths, for GPIB timeouts */
static char init_called = 0; /* To insure that init is done first */
STATIC char *short_base; /* Base of short address space */
#ifdef USE_OLD_XLATION
STATIC char *ram_base; /* Base of the ram on the CPU board */
#endif
STATIC int timeoutSquelch = 0; /* Used to quiet timeout msgs during polling */
@@ -271,6 +274,31 @@ struct bbIbLink {
};
STATIC struct bbIbLink *rootBBLink = NULL; /* Head of bitbus structures */
#ifdef INCLUDE_HIDEOS_INTERFACE
/******************************************************************************
*
******************************************************************************/
typedef struct HideosIbLinkStruct
{
struct ibLink ibLink; /* Associated ibLink */
struct HideosIbLinkStruct *pNext; /* Next in struct list */
int BoardId; /* Hideos CPU board number */
char TaskName[100]; /* Hideos GPIB task name */
void *remote_td;
}HideosIbLinkStruct;
STATIC SEM_ID RootHideosIbLinklock;
STATIC HideosIbLinkStruct *RootHideosIbLink = NULL;
STATIC GPIB_HIDEOS_INIT_FUNC LHideosInit = NULL;
STATIC GPIB_HIDEOS_WRITE_FUNC LHideosWrite = NULL;
STATIC GPIB_HIDEOS_READ_FUNC LHideosRead = NULL;
STATIC GPIB_HIDEOS_WRITEREAD_FUNC LHideosWriteRead = NULL;
STATIC GPIB_HIDEOS_WRITECMD_FUNC LHideosWriteCmd = NULL;
#endif
/******************************************************************************
*
@@ -362,24 +390,20 @@ initGpib(void)
logMsg("initGpib() driver already initialized!\n");
return(OK);
}
#ifdef INCLUDE_HIDEOS_INTERFACE
RootHideosIbLinklock = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
#endif
defaultTimeout = sysClkRateGet();
/* figure out where the short address space is */
sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO , 0, &short_base);
#ifdef USE_OLD_XLATION
/* figure out where the CPU memory is (when viewed from the backplane) */
sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &ram_base, &ram_base);
ram_base = (char *)((ram_base - (char *)&ram_base) & 0x00FFFFFF);
#endif
if (ibDebug)
{
logMsg("Gpib NI1014 driver initializing\n");
logMsg("short_base 0x%08.8X\n", short_base);
#ifdef USE_OLD_XLATION
logMsg("ram_base 0x%08.8X\n", ram_base);
#endif
logMsg("NIGPIB_SHORT_OFF 0x%08.8X\n", NIGPIB_SHORT_OFF);
logMsg("NIGPIB_NUM_LINKS 0x%08.8X\n", NIGPIB_NUM_LINKS);
}
@@ -1047,28 +1071,19 @@ int time; /* time to wait on the DMA operation */
if(ibDebug > 5)
logMsg("PhysIO: readying to xlate cc pointers at %8.8X and %8.8X\n", &(pNiLink[link]->DmaStuff->cc_byte), &pNiLink[link]->A24BounceBuffer[cnt - 1]);
#ifdef USE_OLD_XLATION
pNiLink[link]->DmaStuff->cc_array.cc_ccb = &(pNiLink[link]->DmaStuff->cc_byte) + (long) ram_base;
pNiLink[link]->DmaStuff->cc_array.cc_n_1addr = &(pNiLink[link]->A24BounceBuffer[cnt - 1]) + (long)ram_base;
#else
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_byte), &(pNiLink[link]->DmaStuff->cc_array.cc_ccb)) == ERROR)
return(ERROR);
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->A24BounceBuffer[cnt - 1]), &(pNiLink[link]->DmaStuff->cc_array.cc_n_1addr)) == ERROR)
return(ERROR);
#endif
if(ibDebug > 5)
logMsg("PhysIO: &cc_byte=%8.8X, &pNiLink[link]->A24BounceBuffer[cnt-1]=%8.8X, ", pNiLink[link]->DmaStuff->cc_array.cc_ccb, pNiLink[link]->DmaStuff->cc_array.cc_n_1addr);
cnt--;
#ifdef USE_OLD_XLATION
temp_addr = (long) (&(pNiLink[link]->DmaStuff->cc_array)) + (long)ram_base;
#else
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, &(pNiLink[link]->DmaStuff->cc_array), &temp_addr) == ERROR)
return(ERROR);
#endif
if(ibDebug > 5)
logMsg("&cc_array=%8.8X, ", temp_addr);
@@ -1077,12 +1092,10 @@ int time; /* time to wait on the DMA operation */
/* setup channel 0 (main transfer) */
b->ch0.mtc = cnt ? cnt : 1;
#ifdef USE_OLD_XLATION
temp_addr = (long) (pNiLink[link]->A24BounceBuffer) + (long) ram_base;
#else
if (sysLocalToBusAdrs(VME_AM_STD_SUP_DATA, pNiLink[link]->A24BounceBuffer, &temp_addr) == ERROR)
return(ERROR);
#endif
if(ibDebug > 5)
logMsg("pNiLink[link]->A24BounceBuffer=%8.8X\n", temp_addr);
@@ -1399,45 +1412,50 @@ struct ibLink *plink;
*
******************************************************************************/
STATIC int
ibLinkStart(plink)
struct ibLink *plink;
ibLinkStart(struct ibLink *plink)
{
int j;
int taskId;
char tName[20];
int j;
int taskId;
char tName[20];
if (ibDebug || bbibDebug)
logMsg("ibLinkStart(%08.8X): entered for linkType %d, link %d\n", plink, plink->linkType, plink->linkId);
if (ibDebug || bbibDebug)
logMsg("ibLinkStart(%08.8X): entered for linkType %d, link %d\n", plink, plink->linkType, plink->linkId);
ioctlIb(plink->linkType, plink->linkId, plink->bug, IBIFC, -1, NULL);/* fire out an interface clear */
ioctlIb(plink->linkType, plink->linkId, plink->bug, IBREN, 1, NULL);/* turn on the REN line */
/* fire out an interface clear */
ioctlIb(plink->linkType, plink->linkId, plink->bug, IBIFC, -1, NULL);
/* turn on the REN line */
ioctlIb(plink->linkType, plink->linkId, plink->bug, IBREN, 1, NULL);
/* BUG -- why not just forget this & only poll registered devices? */
/* BUG -- the pollinhibit array stuff has to be fixed! */
if ((plink->linkType == GPIB_IO) && (ibSrqLock == 0))
{
/* poll all available adresses to see if will respond */
speIb(plink);
for (j=1; j<31; j++) /* poll 1 thru 31 (no 0 or 32) */
{
if (pollInhibit[plink->linkId][j] != 1);/* if user did not block it out */
{
if (pollIb(plink, j, 0, POLLTIME) == ERROR)
pollInhibit[plink->linkId][j] = 2; /* address is not pollable */
}
}
if ((plink->linkType == GPIB_IO) && (ibSrqLock == 0))
{
/* poll all available adresses to see if will respond */
speIb(plink);
for (j=1; j<31; j++) /* poll 1 thru 31 (no 0 or 32) */
{
if (pollInhibit[plink->linkId][j] != 1);/* User block it out ? */
{
if (pollIb(plink, j, 0, POLLTIME) == ERROR)
pollInhibit[plink->linkId][j] = 2; /* not pollable */
}
}
spdIb(plink);
}
spdIb(plink);
}
if (plink->linkType == GPIB_IO)
sprintf(tName, "ib-%2.2d", plink->linkId);
else if (plink->linkType == BBGPIB_IO)
sprintf(tName, "bbib-%2.2d.%2.2d", plink->linkId, plink->bug);
else
strcpy(tName, GPIBLINK_NAME);
if (plink->linkType == GPIB_IO)
{
if (plink->linkId > NIGPIB_NUM_LINKS)
sprintf(tName, "hib-%2.2d", plink->linkId);
else
sprintf(tName, "ib-%2.2d", plink->linkId);
}
else if (plink->linkType == BBGPIB_IO)
sprintf(tName, "bbib-%2.2d.%2.2d", plink->linkId, plink->bug);
else
strcpy(tName, GPIBLINK_NAME);
/* Start a task to manage the link */
if ((taskId = taskSpawn(tName, GPIBLINK_PRI, GPIBLINK_OPT, GPIBLINK_STACK, ibLinkTask, plink)) == ERROR)
@@ -1727,25 +1745,33 @@ struct ibLink *plink;
STATIC int
srqIntEnable(int linkType, int link, int bug)
{
if (linkType == GPIB_IO)
return(niSrqIntEnable(link));
if (linkType == GPIB_IO)
{
if (link > NIGPIB_NUM_LINKS)
return(OK);
else
return(niSrqIntEnable(link));
}
if (linkType == BBGPIB_IO)
return(OK); /* Bit Bus does not use interrupts for SRQ handeling */
if (linkType == BBGPIB_IO)
return(OK); /* Bit Bus does not use interrupts for SRQ handeling */
return(ERROR); /* Invalid link type specified on the call */
return(ERROR); /* Invalid link type specified on the call */
}
STATIC int
srqIntDisable(int linkType, int link, int bug)
{
if (linkType == GPIB_IO)
return(niSrqIntDisable(link));
if (linkType == GPIB_IO)
{
if (link > NIGPIB_NUM_LINKS)
return(0);
else
return(niSrqIntDisable(link));
}
if (linkType == BBGPIB_IO)
return(0); /* BitBus does not use interrupts for SRQs */
if (linkType == BBGPIB_IO)
return(0); /* Bit Bus does not use interrupts for SRQ handeling */
return(ERROR); /* Invlaid link type specified on the call */
return(ERROR); /* Invlaid link type specified on the call */
}
/******************************************************************************
@@ -1755,14 +1781,15 @@ srqIntDisable(int linkType, int link, int bug)
*
******************************************************************************/
STATIC int
checkLink(linkType, link, bug)
int linkType;
int link;
int bug;
checkLink(int linkType, int link, int bug)
{
if (linkType == GPIB_IO)
return(niCheckLink(link));
if (linkType == GPIB_IO)
{
if (link > NIGPIB_NUM_LINKS)
return(HiDEOSCheckLink(link));
else
return(niCheckLink(link));
}
if (linkType == BBGPIB_IO)
return(bbCheckLink(link, bug));
@@ -1788,31 +1815,33 @@ int bug;
*
* BUG --
* This could change if we decide to poll them during the second call to init()
* when epics 3.3 is available.
*
******************************************************************************/
/* STATIC */ int
srqPollInhibit(linkType, link, bug, gpibAddr)
int linkType; /* link type (defined in link.h) */
int link; /* the link number the handler is related to */
int bug; /* the bug node address if on a bitbus link */
int gpibAddr; /* the device address the handler is for */
int
srqPollInhibit(
int linkType, /* link type (defined in link.h) */
int link, /* the link number the handler is related to */
int bug, /* the bug node address if on a bitbus link */
int gpibAddr) /* the device address the handler is for */
{
if (ibDebug || ibSrqDebug)
logMsg("srqPollInhibit(%d, %d, %d, %d): called\n", linkType, link, bug, gpibAddr);
if (ibDebug || ibSrqDebug)
logMsg("srqPollInhibit(%d, %d, %d, %d): called\n", linkType, link, bug, gpibAddr);
if (linkType == GPIB_IO)
{
return(niSrqPollInhibit(link, gpibAddr));
}
if (linkType == GPIB_IO)
{
if (link > NIGPIB_NUM_LINKS)
return(HiDEOSSrqPollInhibit(link, gpibAddr));
else
return(niSrqPollInhibit(link, gpibAddr));
}
if (linkType == BBGPIB_IO)
{
return(bbSrqPollInhibit(link, bug, gpibAddr));
}
if (linkType == BBGPIB_IO)
{
return(bbSrqPollInhibit(link, bug, gpibAddr));
}
logMsg("drvGpib: srqPollInhibit(%d, %d, %d, %d): invalid link type specified\n", linkType, link, bug, gpibAddr);
return(ERROR);
logMsg("drvGpib: srqPollInhibit(%d, %d, %d, %d): invalid link type specified\n", linkType, link, bug, gpibAddr);
return(ERROR);
}
/******************************************************************************
@@ -1825,18 +1854,18 @@ int gpibAddr; /* the device address the handler is for */
*
******************************************************************************/
STATIC int
registerSrqCallback(pibLink, device, handler, parm)
struct ibLink *pibLink;
int device;
int (*handler)(); /* handler function to invoke upon SRQ detection */
caddr_t parm; /* so caller can have a parm passed back */
registerSrqCallback(
struct ibLink *pibLink,
int device,
int (*handler)(), /* Function invoked upon SRQ detection */
void *parm) /* So caller can have a parm passed back */
{
if(ibDebug || ibSrqDebug)
logMsg("registerSrqCallback(%08.8X, %d, 0x%08.8X, %08.8X)\n", pibLink, device, handler, parm);
if(ibDebug || ibSrqDebug)
logMsg("registerSrqCallback(%08.8X, %d, 0x%08.8X, %08.8X)\n", pibLink, device, handler, parm);
pibLink->srqHandler[device] = handler;
pibLink->srqParm[device] = parm;
return(OK);
pibLink->srqHandler[device] = handler;
pibLink->srqParm[device] = parm;
return(OK);
}
/******************************************************************************
@@ -1847,26 +1876,30 @@ caddr_t parm; /* so caller can have a parm passed back */
*
******************************************************************************/
STATIC int
ioctlIb(linkType, link, bug, cmd, v, p)
int linkType; /* link type (defined in link.h) */
int link; /* the link number to use */
int bug; /* node number if is a bitbus -> gpib link */
int cmd;
int v;
caddr_t p;
ioctlIb(
int linkType, /* link type (defined in link.h) */
int link, /* the link number to use */
int bug, /* node number if is a bitbus -> gpib link */
int cmd,
int v,
void *p)
{
int stat;
int stat;
if (linkType == GPIB_IO)
return(niGpibIoctl(link, cmd, v, p));/* link checked in niGpibIoctl */
if (linkType == BBGPIB_IO)
return(bbGpibIoctl(link, bug, cmd, v, p));/* link checked in bbGpibIoctl */
if (linkType == GPIB_IO)
{
if (link > NIGPIB_NUM_LINKS)
return(HiDEOSGpibIoctl(link, cmd, v, p));
else
return(niGpibIoctl(link, cmd, v, p));
}
if (linkType == BBGPIB_IO)
return(bbGpibIoctl(link, bug, cmd, v, p));
if (ibDebug || bbibDebug)
logMsg("ioctlIb(%d, %d, %d, %d, %08.8X, %08.8X): invalid link type\n", linkType, link, bug, cmd, v, p);
if (ibDebug || bbibDebug)
logMsg("ioctlIb(%d, %d, %d, %d, %08.8X, %08.8X): invalid link type\n", linkType, link, bug, cmd, v, p);
return(ERROR);
return(ERROR);
}
/******************************************************************************
@@ -1884,37 +1917,37 @@ caddr_t p;
*
******************************************************************************/
STATIC int
qGpibReq(pdpvt, prio)
struct dpvtGpibHead *pdpvt; /* pointer to the device private structure */
int prio;
qGpibReq(
struct dpvtGpibHead *pdpvt, /* pointer to the device private structure */
int prio)
{
if (pdpvt->pibLink == NULL)
{
logMsg("qGpibReq(%08.8X, %d): dpvt->pibLink == NULL!\n", pdpvt, prio);
return(ERROR);
}
if (pdpvt->pibLink == NULL)
{
logMsg("qGpibReq(%08.8X, %d): dpvt->pibLink == NULL!\n", pdpvt, prio);
return(ERROR);
}
switch (prio) {
case IB_Q_LOW: /* low priority transaction request */
semTake(pdpvt->pibLink->loPriSem, WAIT_FOREVER);
ellAdd(&(pdpvt->pibLink->loPriList), pdpvt);
semGive(pdpvt->pibLink->loPriSem);
semGive(pdpvt->pibLink->linkEventSem);
break;
case IB_Q_HIGH: /* high priority transaction request */
semTake(pdpvt->pibLink->hiPriSem, WAIT_FOREVER);
ellAdd(&(pdpvt->pibLink->hiPriList), pdpvt);
semGive(pdpvt->pibLink->hiPriSem);
semGive(pdpvt->pibLink->linkEventSem);
break;
default: /* invalid priority */
logMsg("invalid priority requested in call to qgpibreq(%08.8X, %d)\n", pdpvt, prio);
return(ERROR);
}
if (ibDebug)
logMsg("qgpibreq(0x%08.8X, %d): transaction queued\n", pdpvt, prio);
return(OK);
switch (prio) {
case IB_Q_LOW: /* low priority transaction request */
semTake(pdpvt->pibLink->loPriSem, WAIT_FOREVER);
ellAdd(&(pdpvt->pibLink->loPriList), pdpvt);
semGive(pdpvt->pibLink->loPriSem);
semGive(pdpvt->pibLink->linkEventSem);
break;
case IB_Q_HIGH: /* high priority transaction request */
semTake(pdpvt->pibLink->hiPriSem, WAIT_FOREVER);
ellAdd(&(pdpvt->pibLink->hiPriList), pdpvt);
semGive(pdpvt->pibLink->hiPriSem);
semGive(pdpvt->pibLink->linkEventSem);
break;
default: /* invalid priority */
logMsg("invalid priority requested in call to qgpibreq(%08.8X, %d)\n", pdpvt, prio);
return(ERROR);
}
if (ibDebug)
logMsg("qgpibreq(0x%08.8X, %d): transaction queued\n", pdpvt, prio);
return(OK);
}
/******************************************************************************
@@ -1931,43 +1964,44 @@ int prio;
*
******************************************************************************/
STATIC int
writeIb(pibLink, gpibAddr, data, length, time)
struct ibLink *pibLink;
int gpibAddr; /* the device number to write the data to */
char *data; /* the data buffer to write out */
int length; /* number of bytes to write out from the data buffer */
int time;
writeIb(
struct ibLink *pibLink,
int gpibAddr, /* The device number to write the data to */
char *data, /* The data buffer to write out */
int length, /* Number of bytes to write out */
int time)
{
char attnCmd[5];
int stat;
char attnCmd[5];
int stat;
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("writeIb(%08.8X, %d, 0x%08.8X, %d, %d)\n", pibLink, gpibAddr, data, length, time);
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("writeIb(%08.8X, %d, 0x%08.8X, %d, %d)\n", pibLink, gpibAddr, data, length, time);
if (pibLink->linkType == GPIB_IO)
{
attnCmd[0] = '?'; /* global unlisten */
attnCmd[1] = '_'; /* global untalk */
attnCmd[2] = gpibAddr+LADBASE; /* lad = gpibAddr */
attnCmd[3] = 0+TADBASE; /* mta = 0 */
attnCmd[4] = '\0'; /* in case debugging prints it */
if (writeIbCmd(pibLink, attnCmd, 4) != 4)
return(ERROR);
stat = niGpibWrite(pibLink->linkId, data, length, time);
if (writeIbCmd(pibLink, attnCmd, 2) != 2)
return(ERROR);
}
else if (pibLink->linkType == BBGPIB_IO)
{
stat = bbGpibWrite(pibLink, gpibAddr, data, length, time);
}
else
{
return(ERROR);
}
return(stat);
if (pibLink->linkType == GPIB_IO)
{
if (pibLink->linkId > NIGPIB_NUM_LINKS)
return(HiDEOSGpibWrite(pibLink, gpibAddr, data, length, time));
else
{
attnCmd[0] = '?'; /* global unlisten */
attnCmd[1] = '_'; /* global untalk */
attnCmd[2] = gpibAddr+LADBASE; /* lad = gpibAddr */
attnCmd[3] = 0+TADBASE; /* mta = 0 */
attnCmd[4] = '\0'; /* in case debugging prints it */
if (writeIbCmd(pibLink, attnCmd, 4) != 4)
return(ERROR);
stat = niGpibWrite(pibLink->linkId, data, length, time);
if (writeIbCmd(pibLink, attnCmd, 2) != 2)
return(ERROR);
}
}
else if (pibLink->linkType == BBGPIB_IO)
stat = bbGpibWrite(pibLink, gpibAddr, data, length, time);
else
return(ERROR);
return(stat);
}
/******************************************************************************
@@ -1979,44 +2013,49 @@ int time;
*
******************************************************************************/
STATIC int
readIb(pibLink, gpibAddr, data, length, time)
struct ibLink *pibLink;
int gpibAddr; /* the device number to read the data from */
char *data; /* the buffer to place the data into */
int length; /* max number of bytes to place into the buffer */
int time; /* max time to allow for read operation */
readIb(
struct ibLink *pibLink,
int gpibAddr, /* the device number to read the data from */
char *data, /* the buffer to place the data into */
int length, /* max number of bytes to place into the buffer */
int time) /* max time to allow for read operation */
{
char attnCmd[5];
int stat;
char attnCmd[5];
int stat;
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("readIb(%08.8X, %d, 0x%08.8X, %d)\n", pibLink, gpibAddr, data, length);
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("readIb(%08.8X, %d, 0x%08.8X, %d)\n", pibLink, gpibAddr, data, length);
if (pibLink->linkType == GPIB_IO)
{
attnCmd[0] = '_'; /* global untalk */
attnCmd[1] = '?'; /* global unlisten */
attnCmd[2] = gpibAddr+TADBASE; /* tad = gpibAddr */
attnCmd[3] = 0+LADBASE; /* mta = 0 */
attnCmd[4] = '\0';
if (writeIbCmd(pibLink, attnCmd, 4) != 4)
return(ERROR);
if (pibLink->linkType == GPIB_IO)
{
if (pibLink->linkId > NIGPIB_NUM_LINKS)
return(HiDEOSGpibRead(pibLink, gpibAddr, data, length, time));
else
{
attnCmd[0] = '_'; /* global untalk */
attnCmd[1] = '?'; /* global unlisten */
attnCmd[2] = gpibAddr+TADBASE; /* tad = gpibAddr */
attnCmd[3] = 0+LADBASE; /* mta = 0 */
attnCmd[4] = '\0';
stat = niGpibRead(pibLink->linkId, data, length, time);
if (writeIbCmd(pibLink, attnCmd, 4) != 4)
return(ERROR);
if (writeIbCmd(pibLink, attnCmd, 2) != 2)
return(ERROR);
}
else if (pibLink->linkType == BBGPIB_IO)
{
stat = bbGpibRead(pibLink, gpibAddr, data, length, time);
}
else
{ /* incorrect link type specified! */
return(ERROR);
}
return(stat);
stat = niGpibRead(pibLink->linkId, data, length, time);
if (writeIbCmd(pibLink, attnCmd, 2) != 2)
return(ERROR);
}
}
else if (pibLink->linkType == BBGPIB_IO)
{
stat = bbGpibRead(pibLink, gpibAddr, data, length, time);
}
else
{ /* incorrect link type specified! */
return(ERROR);
}
return(stat);
}
/******************************************************************************
@@ -2029,26 +2068,26 @@ int time; /* max time to allow for read operation */
*
******************************************************************************/
STATIC int
writeIbCmd(pibLink, data, length)
struct ibLink *pibLink;
char *data; /* the data buffer to write out */
int length; /* number of bytes to write out from the data buffer */
writeIbCmd(
struct ibLink *pibLink,
char *data, /* The data buffer to write out */
int length) /* Number of bytes to write out */
{
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("writeIbCmd(%08.8X, %08.8X, %d)\n", pibLink, data, length);
if(ibDebug || (bbibDebug & (pibLink->linkType == BBGPIB_IO)))
logMsg("writeIbCmd(%08.8X, %08.8X, %d)\n", pibLink, data, length);
if (pibLink->linkType == GPIB_IO)
{
/* raw-write the data */
return(niGpibCmd(pibLink->linkId, data, length));
}
if (pibLink->linkType == BBGPIB_IO)
{
/* raw-write the data */
return(bbGpibCmd(pibLink, data, length));
}
return(ERROR);
if (pibLink->linkType == GPIB_IO)
{
if (pibLink->linkId > NIGPIB_NUM_LINKS)
return(HiDEOSGpibCmd(pibLink, data, length));
else
return(niGpibCmd(pibLink->linkId, data, length));
}
if (pibLink->linkType == BBGPIB_IO)
return(bbGpibCmd(pibLink, data, length));
return(ERROR);
}
/******************************************************************************
@@ -2386,11 +2425,7 @@ bbGpibIoctl(int link, int bug, int cmd, int v, caddr_t p)
switch (cmd) {
case IBTMO: /* set timeout time for next transaction only */
/* find the ibLink structure for the requested link & bug */
#if 1
if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL)
#else
if ((pbbIbLink = findBBLink(link, bug)) != NULL)
#endif
{
/* build a TMO message to send to the bug */
bbDpvt.txMsg.length = 7;
@@ -2425,11 +2460,7 @@ bbGpibIoctl(int link, int bug, int cmd, int v, caddr_t p)
case IBIFC: /* send an Interface Clear pulse */
/* find the ibLink structure for the requested link & bug */
#if 1
if ((pbbIbLink = (struct bbIbLink *)&(findBBLink(link, bug)->ibLink)) != NULL)
#else
if ((pbbIbLink = findBBLink(link, bug)) != NULL)
#endif
{
/* build an IFC message to send to the bug */
bbDpvt.txMsg.length = 7;
@@ -2588,11 +2619,206 @@ IBHistDump(int type, int link, int bug)
}
#endif
#if 0
/* A way to stop the CPU when idle... run from shell at prio 250 */
cpuStopperThingy()
/******************************************************************************
*
* These are the HiDEOS architecture specific functions.
*
******************************************************************************/
/******************************************************************************
*
* Find a HiDEOS link structure given a link number.
*
******************************************************************************/
STATIC HideosIbLinkStruct *findHiDEOSIbLink(int link)
{
while (1)
asm(" stop #0x3000");
HideosIbLinkStruct *pHideosIbLink;
pHideosIbLink = RootHideosIbLink;
pHideosIbLink->pNext = RootHideosIbLink;
while (pHideosIbLink != NULL)
{
if (pHideosIbLink->ibLink.linkId == link)
break;
else
pHideosIbLink = pHideosIbLink->pNext;
}
if (ibDebug)
logMsg("findHiDEOSIbLink(%d): returning %08.8X\n", link, pHideosIbLink);
return(pHideosIbLink);
}
/******************************************************************************
*
* Read a GPIB message via the HiDEOS subsystem.
*
******************************************************************************/
STATIC int
HiDEOSGpibRead(
struct ibLink *pibLink,
int DevAddr,
char *Buf,
int BufLen,
int time)
{
int Actual;
HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink;
if (LHideosRead(pHLink->remote_td, Buf, BufLen, &Actual, DevAddr, time)==0)
return(Actual);
return(-1);
}
/******************************************************************************
*
* Write a GPIB message by way of the bitbus driver.
*
******************************************************************************/
STATIC int
HiDEOSGpibWrite(
struct ibLink *pibLink,
int DevAddr,
char *Buf,
int BufLen,
int time)
{
HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink;
return(LHideosWrite(pHLink->remote_td, Buf, BufLen, DevAddr, time));
}
/******************************************************************************/
STATIC int
HiDEOSGpibCmd(
struct ibLink *pibLink,
char *Buf,
int BufLen)
{
HideosIbLinkStruct *pHLink = (HideosIbLinkStruct*)pibLink;
return(LHideosWriteCmd(pHLink->remote_td, Buf, BufLen, 100));
}
/******************************************************************************/
STATIC int
HiDEOSCheckLink(int link)
{
if (findHiDEOSIbLink(link) != NULL)
return(OK);
else
return(ERROR);
}
/******************************************************************************/
STATIC int
HiDEOSSrqPollInhibit(int link, int gpibAddr)
{
logMsg("HiDEOSSrqPollInhibit for link %d, device %d\n", link, gpibAddr);
return(ERROR);
}
/******************************************************************************
*
* Initialize all required structures and start an ibLinkTask() for use with
* a GPIB_IO based link to a HiDEOS interface.
*
******************************************************************************/
int
HiDEOSGpibLinkConfig(int link, int BoardId, char *TaskName)
{
SYM_TYPE stype;
HideosIbLinkStruct *pHiDEOSIbLink;
if (ibDebug)
logMsg("HiDEOSGpibLinkConfig(%d): entered\n", link);
/* First check to see if there is already a link set up */
pHiDEOSIbLink = findHiDEOSIbLink(link);
if (pHiDEOSIbLink != NULL)
{ /* Already have initialized the link for this guy... */
if (ibDebug)
logMsg("HiDEOSGpibLinkConfig(%d): link already initialized\n", link);
return(OK);
}
if ((pHiDEOSIbLink = (HideosIbLinkStruct *) malloc(sizeof(HideosIbLinkStruct))) == NULL)
{
logMsg("HiDEOSGpibLinkConfig(%d): can't malloc memory for link structure\n", link);
return(ERROR);
}
if ((symFindByName(sysSymTbl,"_GpibHideosInit", (char**)&LHideosInit,&stype)==ERROR)
|| (symFindByName(sysSymTbl,"_GpibHideosWrite", (char**)&LHideosWrite,&stype)==ERROR)
|| (symFindByName(sysSymTbl,"_GpibHideosRead", (char**)&LHideosRead,&stype)==ERROR)
|| (symFindByName(sysSymTbl,"_GpibHideosWriteRead", (char**)&LHideosWriteRead,&stype)==ERROR)
|| (symFindByName(sysSymTbl,"_GpibHideosWriteCmd", (char**)&LHideosWriteCmd,&stype)==ERROR))
{
free (pHiDEOSIbLink);
logMsg("HiDEOSGpibLinkConfig: Can not locate Hideos GPIB services\n");
return(-1);
}
/* get a logical connection into HiDEOS-land */
if ((pHiDEOSIbLink->remote_td = LHideosInit(BoardId, TaskName)) == NULL)
{
free (pHiDEOSIbLink);
logMsg("HiDEOSGpibLinkConfig: Can not locate Hideos task %s\n", TaskName);
return(-1);
}
pHiDEOSIbLink->ibLink.linkType = GPIB_IO;
pHiDEOSIbLink->ibLink.linkId = link;
pHiDEOSIbLink->ibLink.bug = -1;
pHiDEOSIbLink->BoardId = BoardId;
strcpy(pHiDEOSIbLink->TaskName, TaskName);
ibLinkInit(&(pHiDEOSIbLink->ibLink));
semTake(RootHideosIbLinklock, WAIT_FOREVER);
pHiDEOSIbLink->pNext = RootHideosIbLink;
RootHideosIbLink = pHiDEOSIbLink;
semGive(RootHideosIbLinklock);
return(ibLinkStart(&(pHiDEOSIbLink->ibLink)));
}
/******************************************************************************
*
* IOCTL control function for BBGPIB_IO based links.
*
******************************************************************************/
STATIC int
HiDEOSGpibIoctl(int link, int cmd, int v, void *p)
{
int stat = ERROR;
if (ibDebug)
logMsg("HiDEOSGpibIoctl(%d, %d, %08.8X, %08.8X): called\n", link, cmd, v, p);
switch (cmd) {
case IBTMO: /* set timeout time for next transaction only */
/* Can't do this yet!!! */
stat = OK;
break;
case IBIFC: /* send an Interface Clear pulse */
/* Can't do this yet!!! */
stat = OK;
break;
case IBREN: /* turn the Remote Enable line on or off */
case IBGTS: /* go to standby (ATN off etc... ) */
case IBGTA: /* go to active (ATN on etc... ) */
stat = OK;
break;
case IBGENLINK: /* Done manually in startup.cmd */
stat = OK;
break;
case IBGETLINK: /* request the address of the ibLink structure */
*(struct ibLink **)p = &(findHiDEOSIbLink(link)->ibLink);
break;
default:
logMsg("HiDEOSGpibIoctl(%d, %d, %08.8X, %08.8X): invalid command requested\n", link, cmd, v, p);
}
return(stat);
}
#endif

View File

@@ -56,6 +56,10 @@ errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl;
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c
@@ -63,5 +67,5 @@ tsTest: tsSubr.o
$(LINK.c) -o $@ tsSubr.o -lCom -lDb -lCom -lm -s
clean::
@$(RM) errInc.c errSymTbl.c
@$(RM) errInc.c errSymTbl.c envData.h

View File

@@ -44,7 +44,7 @@ PROD = libCom
include $(EPICS)/config/RULES.Vx
clean::
@$(RM) errInc.c errSymTbl.c
@$(RM) errInc.c errSymTbl.c envData.h
build: errSymTbl.o errInc.o
@@ -52,6 +52,10 @@ errSymTbl.c errInc.o: errInc.c
@$(RM) errInc.o
@$(EPICS_BASE)/tools/blderrSymTbl
envSubr.o: envData.h
envData.h: $(EPICS_BASE)/include/envDefs.h $(EPICS)/config/CONFIG_ENV
$(EPICS_BASE)/tools/bldEnvData
pre_build:
@test -f errInc.c || ln -s ../errInc.c errInc.c

View File

@@ -30,6 +30,7 @@
* .03 08-07-91 joh added config get for struct in_addr type
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
* vars under vxWorks
* .05 04-20-95 anj changes to use CONFIG_ENV
*
* make options
* -DvxWorks makes a version for VxWorks
@@ -79,10 +80,9 @@
#include <errnoLib.h>
#endif
#define ENV_PRIVATE_DATA
#include <envDefs.h>
#include "envData.h"
#include <errMdef.h>
#include <epicsEnvParams.h>
/*+/subr**********************************************************************
@@ -423,34 +423,36 @@ char *value; /* I pointer to value string */
}
/*parameters meant to be modified in epicsEnvParams.h*/
/* epicsSetEnvParams not required any more - do not use */
int epicsSetEnvParams()
{
printf("setting EPICS environment parameters\n");
envSetConfigParam(&EPICS_TS_MIN_WEST, EPICS_TS_MIN_VALUE);
envSetConfigParam(&EPICS_AR_PORT, "7002");
envSetConfigParam(&EPICS_IOC_LOG_INET, EPICS_IOC_LOG_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_PORT, "7004");
envSetConfigParam(&EPICS_IOC_LOG_FILE_LIMIT, EPICS_IOC_FILE_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_FILE_NAME, EPICS_IOC_LOG_FILE_TXT);
return 0;
}
int epicsPrtEnvParams()
/*+/subr**********************************************************************
* NAME epicsPrtEnvParams - print value of all configuration parameters
*
* DESCRIPTION
* Prints all configuration parameters and their current value.
*
* RETURNS
* 0
*
* EXAMPLE
* 1. Print the value for all EPICS-defined environment parameters.
*
* #include <envDefs.h>
*
* epicsPrtEnvParams();
*
*-*/
long
epicsPrtEnvParams()
{
envPrtConfigParam(&EPICS_TS_MIN_WEST);
envPrtConfigParam(&EPICS_CMD_PROTO_PORT);
envPrtConfigParam(&EPICS_AR_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_INET);
envPrtConfigParam(&EPICS_IOC_LOG_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_LIMIT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_NAME);
envPrtConfigParam(&EPICS_CA_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_CONN_TMO);
envPrtConfigParam(&EPICS_CA_BEACON_PERIOD);
envPrtConfigParam(&EPICS_CA_AUTO_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_REPEATER_PORT);
envPrtConfigParam(&EPICS_CA_SERVER_PORT);
return 0;
ENV_PARAM **ppParam = env_param_list;
while (*ppParam != NULL)
envPrtConfigParam(*(ppParam++));
}

View File

@@ -30,6 +30,7 @@
* .03 08-07-91 joh added config get for struct in_addr type
* .04 01-11-95 joh use getenv()/putenv() to fetch/write env
* vars under vxWorks
* .05 04-20-95 anj changes to use CONFIG_ENV
*
* make options
* -DvxWorks makes a version for VxWorks
@@ -79,10 +80,9 @@
#include <errnoLib.h>
#endif
#define ENV_PRIVATE_DATA
#include <envDefs.h>
#include "envData.h"
#include <errMdef.h>
#include <epicsEnvParams.h>
/*+/subr**********************************************************************
@@ -423,34 +423,36 @@ char *value; /* I pointer to value string */
}
/*parameters meant to be modified in epicsEnvParams.h*/
/* epicsSetEnvParams not required any more - do not use */
int epicsSetEnvParams()
{
printf("setting EPICS environment parameters\n");
envSetConfigParam(&EPICS_TS_MIN_WEST, EPICS_TS_MIN_VALUE);
envSetConfigParam(&EPICS_AR_PORT, "7002");
envSetConfigParam(&EPICS_IOC_LOG_INET, EPICS_IOC_LOG_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_PORT, "7004");
envSetConfigParam(&EPICS_IOC_LOG_FILE_LIMIT, EPICS_IOC_FILE_VALUE);
envSetConfigParam(&EPICS_IOC_LOG_FILE_NAME, EPICS_IOC_LOG_FILE_TXT);
return 0;
}
int epicsPrtEnvParams()
/*+/subr**********************************************************************
* NAME epicsPrtEnvParams - print value of all configuration parameters
*
* DESCRIPTION
* Prints all configuration parameters and their current value.
*
* RETURNS
* 0
*
* EXAMPLE
* 1. Print the value for all EPICS-defined environment parameters.
*
* #include <envDefs.h>
*
* epicsPrtEnvParams();
*
*-*/
long
epicsPrtEnvParams()
{
envPrtConfigParam(&EPICS_TS_MIN_WEST);
envPrtConfigParam(&EPICS_CMD_PROTO_PORT);
envPrtConfigParam(&EPICS_AR_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_INET);
envPrtConfigParam(&EPICS_IOC_LOG_PORT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_LIMIT);
envPrtConfigParam(&EPICS_IOC_LOG_FILE_NAME);
envPrtConfigParam(&EPICS_CA_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_CONN_TMO);
envPrtConfigParam(&EPICS_CA_BEACON_PERIOD);
envPrtConfigParam(&EPICS_CA_AUTO_ADDR_LIST);
envPrtConfigParam(&EPICS_CA_REPEATER_PORT);
envPrtConfigParam(&EPICS_CA_SERVER_PORT);
return 0;
ENV_PARAM **ppParam = env_param_list;
while (*ppParam != NULL)
envPrtConfigParam(*(ppParam++));
}

View File

@@ -111,6 +111,7 @@ static char *pSccsId = "@(#) $Id$";
#include <tickLib.h>
#include <logLib.h>
#include <selectLib.h>
#include <semLib.h>
#endif
#include <epicsAssert.h>
@@ -151,19 +152,23 @@ typedef struct{
}fdentry;
#if defined(vxWorks)
# define LOCK(PFDCTX) FASTLOCK(&(PFDCTX)->lock)
# define UNLOCK(PFDCTX) FASTUNLOCK(&(PFDCTX)->lock)
# define LOCK(PFDCTX) assert(semTake((PFDCTX)->lock, WAIT_FOREVER)==OK);
# define UNLOCK(PFDCTX) assert(semGive((PFDCTX)->lock)==OK);
# define UNLOCK_FDMGR_PEND_EVENT(PFDCTX) \
FASTUNLOCK(&(PFDCTX)->fdmgr_pend_event_lock) \
(PFDCTX)->fdmgr_pend_event_tid = NULL;
{(PFDCTX)->fdmgr_pend_event_tid = NULL; \
assert(semGive((PFDCTX)->fdmgr_pend_event_lock)==OK);}
# define LOCK_EXPIRED(PFDCTX) \
FASTLOCK(&(PFDCTX)->expired_alarm_lock)
assert(semTake((PFDCTX)->expired_alarm_lock, WAIT_FOREVER)==OK);
# define UNLOCK_EXPIRED(PFDCTX) \
FASTUNLOCK(&(PFDCTX)->expired_alarm_lock)
assert(semGive((PFDCTX)->expired_alarm_lock)==OK);
# define LOCK_FD_HANDLER(PFDCTX) \
FASTLOCK(&(PFDCTX)->fd_handler_lock)
assert(semTake((PFDCTX)->fd_handler_lock, WAIT_FOREVER)==OK);
# define UNLOCK_FD_HANDLER(PFDCTX) \
FASTUNLOCK(&(PFDCTX)->fd_handler_lock)
assert(semGive((PFDCTX)->fd_handler_lock)==OK);
#elif defined(UNIX) || defined(VMS) || defined(_WIN32)
# define LOCK(PFDCTX)
# define UNLOCK(PFDCTX)
@@ -224,10 +229,22 @@ fdctx *fdmgr_init(void)
pfdctx = (fdctx *) calloc(1, sizeof(fdctx));
# if defined(vxWorks)
FASTLOCKINIT(&pfdctx->lock);
FASTLOCKINIT(&pfdctx->fdmgr_pend_event_lock);
FASTLOCKINIT(&pfdctx->expired_alarm_lock);
FASTLOCKINIT(&pfdctx->fd_handler_lock);
pfdctx->lock = semMCreate (SEM_DELETE_SAFE);
if (pfdctx->lock == NULL){
return NULL;
}
pfdctx->fdmgr_pend_event_lock = semMCreate (SEM_DELETE_SAFE);
if (pfdctx->fdmgr_pend_event_lock == NULL){
return NULL;
}
pfdctx->expired_alarm_lock = semMCreate (SEM_DELETE_SAFE);
if (pfdctx->expired_alarm_lock == NULL) {
return NULL;
}
pfdctx->fd_handler_lock = semMCreate (SEM_DELETE_SAFE);
if (pfdctx->fd_handler_lock == NULL) {
return NULL;
}
pfdctx->clk_rate = sysClkRateGet();
pfdctx->last_tick_count = tickGet();
# endif
@@ -239,7 +256,7 @@ fdctx *fdmgr_init(void)
ellInit(&pfdctx->free_alarm_list);
/*
* returns NULL if unsuccessfull
* returns NULL if unsuccessful
*/
return pfdctx;
}
@@ -252,17 +269,30 @@ fdctx *fdmgr_init(void)
*/
int fdmgr_delete(fdctx *pfdctx)
{
int status;
if(!pfdctx){
return ERROR;
}
# if defined(vxWorks)
FASTLOCKFREE(&pfdctx->lock);
FASTLOCKFREE(&pfdctx->fdmgr_pend_event_lock);
FASTLOCKFREE(&pfdctx->expired_alarm_lock);
FASTLOCKFREE(&pfdctx->fd_handler_lock);
status = semDelete (pfdctx->lock);
assert (status == OK);
status = semDelete (pfdctx->fdmgr_pend_event_lock);
assert (status == OK);
status = semDelete (pfdctx->expired_alarm_lock);
assert (status == OK);
status = semDelete (pfdctx->fd_handler_lock);
assert (status == OK);
# endif
ellFree(&pfdctx->fdentry_list);
ellFree(&pfdctx->fdentry_in_use_list);
ellFree(&pfdctx->fdentry_free_list);
ellFree(&pfdctx->alarm_list);
ellFree(&pfdctx->expired_alarm_list);
ellFree(&pfdctx->free_alarm_list);
return OK;
}
@@ -334,7 +364,7 @@ void *param
}
}
if(pa){
ellInsert(&pfdctx->alarm_list, pa->node.previous, &palarm->node);
ellInsert(&pfdctx->alarm_list, pa->node.previous, &palarm->node);
}
else{
ellAdd(&pfdctx->alarm_list, &palarm->node);
@@ -421,7 +451,7 @@ fdmgrAlarm *palarm
*
* fdmgr_add_fd()
*
* this rouitine is supplied solely for compatibility
* this routine is supplied solely for compatibility
* with earlier versions of this software
*/
int fdmgr_add_fd(
@@ -574,10 +604,14 @@ enum fdi_type fdi
/*
* wait for it to finish if it is in progress
* when running in a multithreaded environment
*
* Taking the lock here guarantees that if the
* event we are deleting is in progress then
* we will wait for it to complete prior to
* proceeding
*/
# ifdef vxWorks
if(delete_pending == TRUE){
@@@@ review all of this delete pending stuff
LOCK_FD_HANDLER(pfdctx);
UNLOCK_FD_HANDLER(pfdctx);
}
@@ -777,6 +811,9 @@ struct timeval *ptimeout
/*
* sync with clear
*
* This allows the clearing thread to wait
* until the event that it is clearing completes
*/
LOCK_FD_HANDLER(pfdctx);
@@ -859,12 +896,6 @@ struct timeval *poffset
* they are in an alarm handler (and potentially modifying
* the alarm queue).
*/
/*
* no need to lock here since this list is only touched
* by this routine, this routine is not exported
* and I am only allowing one thread in fdmgr_pend_event()
* at at time.
*/
/*
* I dont want the primary LOCK to be applied while in their
* alarm handler as this would prevent them from
@@ -878,7 +909,7 @@ struct timeval *poffset
LOCK_EXPIRED(pfdctx);
pa = (fdmgrAlarm*) pfdctx->expired_alarm_list.node.next;
while(pa){
void (*pfunc)();
void (*pfunc)(void *pParam);
/*
* check to see if it has been disabled
@@ -1019,7 +1050,7 @@ struct timeval *pt
LOCAL void lockFDMGRPendEvent (fdctx *pfdctx)
{
# if defined(vxWorks)
FASTLOCK(&pfdctx->fdmgr_pend_event_lock);
assert(semTake (pfdctx->fdmgr_pend_event_lock, WAIT_FOREVER)==OK);
pfdctx->fdmgr_pend_event_tid = taskIdCurrent;
# else
assert (pfdctx->fdmgr_pend_event_in_use==0);

View File

@@ -60,9 +60,10 @@
* .15 03-15-95 nda If no readback PV (RxPV) is specified, copy desired
* value (PxDV) to current value (RxCV). Now, plotting
* programs can always monitor RxCV.
* .16 04-03-95 nda If PV field = DESC, change to VAL
*/
#define VERSION 1.15
#define VERSION 1.16
@@ -945,6 +946,9 @@ static void lookupPVs(pscan)
{
struct recPvtStruct *precPvt = (struct recPvtStruct *)pscan->rpvt;
char *ppvn[PVN_SIZE];
char *pdesc = ".DESC";
char *pval = ".VAL";
char *pdot;
struct dbAddr **ppdbAddr; /* ptr to a ptr to dbAddr */
long *paddrValid;
long prevValid;
@@ -958,6 +962,15 @@ static void lookupPVs(pscan)
for(i=0;i<NUM_DYN_PVS; i++, *ppvn += PVN_SIZE, ppdbAddr++, paddrValid++) {
prevValid = *paddrValid;
/* If PV field name = DESC, change to VAL */
pdot = strrchr(*ppvn, '.');
if(pdot!=NULL) {
if(strncmp(pdot, pdesc, 5) == 0) {
strcpy(pdot, pval);
db_post_events(pscan, *ppvn, DBE_VALUE);
}
}
*paddrValid = dbNameToAddr(*ppvn, *ppdbAddr);
if(*paddrValid != prevValid) {
db_post_events(pscan, paddrValid, DBE_VALUE);

View File

@@ -1582,19 +1582,6 @@ struct client *client
unsigned long count;
int type;
/*
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
*/
if(casDontAllowSearchReplies){
SEND_LOCK(client);
send_err(mp,
ECA_ALLOCMEM,
client,
"Server memory exhausted");
SEND_UNLOCK(client);
return;
}
/* Exit quickly if channel not on this node */
status = db_name_to_addr(
mp + 1,
@@ -1613,6 +1600,19 @@ struct client *client
return;
}
/*
* set true if max memory block drops below MAX_BLOCK_THRESHOLD
*/
if(casDontAllowSearchReplies){
SEND_LOCK(client);
send_err(mp,
ECA_ALLOCMEM,
client,
"Server memory exhausted");
SEND_UNLOCK(client);
return;
}
/*
* starting with V4.4 the count field is used (abused)
* to store the minor version number of the client.

View File

@@ -175,7 +175,10 @@ unsigned extsize; /* extension size */
unsigned msgsize;
unsigned newstack;
extsize = CA_MESSAGE_ALIGN(extsize);
msgsize = extsize + sizeof(struct extmsg);
newstack = pclient->send.stk + msgsize;
if(newstack > pclient->send.maxstk){
if(pclient->disconnect){

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/* base/src/drv $Id$ */
/*
*
* driver for at5 designed VXI modules
*
* Author: Jeff Hill
* Date: 11-89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*/
#include <dbScan.h>
typedef long at5VxiStatus;
at5VxiStatus at5vxi_one_shot(
unsigned preset, /* TRUE or COMPLEMENT logic */
double edge0_delay, /* sec */
double edge1_delay, /* set */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
void (*event_rtn)(void *pParam), /* subroutine to run on events */
void *event_rtn_param/* parameter to pass to above routine */
);
at5VxiStatus at5vxi_one_shot_read(
unsigned *preset, /* TRUE or COMPLEMENT logic */
double *edge0_delay, /* sec */
double *edge1_delay, /* sec */
unsigned card, /* 0 through ... */
unsigned channel, /* 0 through channels on a card */
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
);
at5VxiStatus at5vxi_ai_driver(
unsigned card,
unsigned chan,
unsigned short *prval
);
at5VxiStatus at5vxi_ao_driver(
unsigned card,
unsigned chan,
unsigned short *prval,
unsigned short *prbval
);
at5VxiStatus at5vxi_ao_read(
unsigned card,
unsigned chan,
unsigned short *pval
);
at5VxiStatus at5vxi_bi_driver(
unsigned card,
unsigned long mask,
unsigned long *prval
);
at5VxiStatus at5vxi_bo_driver(
unsigned card,
unsigned long val,
unsigned long mask
);
at5VxiStatus at5vxi_getioscanpvt(
unsigned card,
IOSCANPVT *scanpvt
);

View File

@@ -0,0 +1,408 @@
/* base/src/drv $Id$ */
/*
*
* HP E1404A VXI bus slot zero translator
* device dependent routines
*
* share/src/drv/@(#)drvHp1404a.c 1.7 8/27/93
*
* Author Jeffrey O. Hill
* Date 030692
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 joh 073092 Added msg device support & interrupt shutdown for
* soft reboots
* .02 joh 082792 converted to ANSI C
* .03 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*
*
*
*/
static char *sccsId = "@(#)drvHp1404a.c 1.7\t8/27/93";
#include <vxWorks.h>
#include <iv.h>
#include <intLib.h>
#include <rebootLib.h>
#include <devLib.h>
#include <drvEpvxi.h>
#include <drvHp1404a.h>
LOCAL unsigned long hpE1404DriverID;
struct hpE1404_config{
void (*pSignalCallback)(int16_t signal);
};
#define TLTRIG(N) (1<<(N))
#define ECLTRIG(N) (1<<((N)+8))
/*
* enable int when signal register is written
*/
#define HP1404A_INT_ENABLE 0x0008
#define HP1404A_INT_DISABLE 0x0000
/*
*
* tag the device dependent registers
*/
#define IRQ_enable dir.w.dd.reg.ddx1a
#define MSG_status dir.w.dd.reg.ddx1e
#define fp_trig_drive dir.w.dd.reg.ddx2a
#define bp_trig_drive dir.w.dd.reg.ddx22
#define signal_read dir.r.dd.reg.ddx10
#define hpE1404PConfig(LA, PC) \
epvxiFetchPConfig((LA), hpE1404DriverID, (PC))
LOCAL void hpE1404InitLA(
unsigned la
);
LOCAL int hpE1404ShutDown(
void
);
LOCAL void hpE1404ShutDownLA(
unsigned la
);
LOCAL void hpE1404IOReport(
unsigned la,
unsigned level
);
LOCAL void hpE1404Int(
unsigned la
);
/*
*
* hpE1404Init
*
*/
hpE1404Stat hpE1404Init(void)
{
hpE1404Stat status;
status = rebootHookAdd(hpE1404ShutDown);
if(status<0){
status = S_dev_internal;
errMessage(status, "rebootHookAdd() failed");
return status;
}
hpE1404DriverID = epvxiUniqueDriverID();
status = epvxiRegisterMakeName(
VXI_MAKE_HP,
"Hewlett-Packard");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_REG_SLOT0,
"Slot Zero Translator (reg)");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_REG,
"Translator (reg)");
if(status){
errMessage(status, NULL);
}
status = epvxiRegisterModelName(
VXI_MAKE_HP,
VXI_HP_MODEL_E1404_MSG,
"Translator (msg)");
if(status){
errMessage(status, NULL);
}
{
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return status;
}
dsp.model = VXI_HP_MODEL_E1404_REG;
status = epvxiLookupLA(&dsp, hpE1404InitLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return status;
}
}
return VXI_SUCCESS;
}
/*
*
* hpE1404ShutDown()
*
*
*/
LOCAL int hpE1404ShutDown(void)
{
hpE1404Stat status;
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_HP_MODEL_E1404_REG_SLOT0;
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return ERROR;
}
dsp.model = VXI_HP_MODEL_E1404_REG;
status = epvxiLookupLA(&dsp, hpE1404ShutDownLA, (void *)NULL);
if(status){
errMessage(status, NULL);
return ERROR;
}
return OK;
}
/*
*
* hpE1404ShutDownLA()
*
*
*/
LOCAL
void hpE1404ShutDownLA(
unsigned la
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->IRQ_enable = HP1404A_INT_DISABLE;
}
/*
*
* hpE1404InitLA()
*
*/
LOCAL
void hpE1404InitLA(
unsigned la
)
{
struct hpE1404_config *pc;
struct vxi_csr *pcsr;
hpE1404Stat status;
status = epvxiOpen(
la,
hpE1404DriverID,
sizeof(*pc),
hpE1404IOReport);
if(status){
errMessage(status, NULL);
return;
}
pcsr = VXIBASE(la);
status = hpE1404PConfig(la, pc);
if(status){
errMessage(status, NULL);
epvxiClose(la, hpE1404DriverID);
return;
}
/*
* set the self test status to passed for
* the message based device
*/
pcsr->MSG_status = VXIPASS<<2;
intConnect(
INUM_TO_IVEC(la),
hpE1404Int,
la);
/*
* enable int when signal register is written
*/
pcsr->IRQ_enable = HP1404A_INT_ENABLE;
return;
}
/*
*
* hpE1404SignalConnect()
*
*/
hpE1404Stat hpE1404SignalConnect(
unsigned la,
void (*pSignalCallback)(int16_t signal)
)
{
hpE1404Stat s;
struct hpE1404_config *pc;
s = hpE1404PConfig(la, pc);
if(s){
return s;
}
pc->pSignalCallback = pSignalCallback;
return VXI_SUCCESS;
}
/*
*
* hpE1404Int()
*
*/
LOCAL
void hpE1404Int(
unsigned la
)
{
hpE1404Stat s;
struct vxi_csr *pcsr;
unsigned short signal;
struct hpE1404_config *pc;
s = hpE1404PConfig(la, pc);
if(s){
errMessage(s, NULL);
return;
}
/*
* vector is only D8 so we cant check the cause of the int
* (signal cause is assumed since that was all that was enabled)
*/
pcsr = VXIBASE(la);
signal = pcsr->signal_read;
if(pc->pSignalCallback){
(*pc->pSignalCallback)(signal);
}
}
/*
*
* hpE1404RouteTriggerECL
*
*/
hpE1404Stat hpE1404RouteTriggerECL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->fp_trig_drive = (io_map&enable_map)<<8;
pcsr->bp_trig_drive = ((~io_map)&enable_map)<<8;
return VXI_SUCCESS;
}
/*
*
*
* hpE1404RouteTriggerTTL
*
*
*/
hpE1404Stat hpE1404RouteTriggerTTL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
)
{
struct vxi_csr *pcsr;
pcsr = VXIBASE(la);
pcsr->fp_trig_drive = io_map&enable_map;
pcsr->bp_trig_drive = (~io_map)&enable_map;
return VXI_SUCCESS;
}
/*
*
* hpE1404IOReport()
*
*
*/
LOCAL
void hpE1404IOReport(
unsigned la,
unsigned level
)
{
}

View File

@@ -0,0 +1,74 @@
/* base/src/drv $Id$ */
/*
* drvHp1404a.h
*
* HP E1404A VXI bus slot zero translator
* device dependent routines header file
*
* share/src/drv/@(#)drvHp1404a.h 1.1 8/27/93
*
* Author Jeffrey O. Hill
* Date 030692
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
*
*
*/
typedef long hpE1404Stat;
hpE1404Stat hpE1404Init(void);
hpE1404Stat hpE1404SignalConnect(
unsigned la,
void (*pSignalCallback)(int16_t signal)
);
hpE1404Stat hpE1404RouteTriggerECL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
);
hpE1404Stat hpE1404RouteTriggerTTL(
unsigned la, /* slot zero device logical address */
unsigned enable_map, /* bits 0-5 correspond to trig 0-5 */
/* a 1 enables a trigger */
/* a 0 disables a trigger */
unsigned io_map /* bits 0-5 correspond to trig 0-5 */
/* a 1 sources the front panel */
/* a 0 sources the back plane */
);
#define VXI_HP_MODEL_E1404_REG_SLOT0 0x10
#define VXI_HP_MODEL_E1404_REG 0x110
#define VXI_HP_MODEL_E1404_MSG 0x111

View File

@@ -0,0 +1,359 @@
/* drvHpe1368a.c*/
/* base/src/drv $Id$ */
/*
* hpe1368a_driver.c
*
* driver for hpe1368a and hpe1369a microwave switch VXI modules
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
* .01 071792 joh Added model name registration
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
* .03 082692 mrk Added support for new I/O event scanning and DRVET
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
*
*/
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
#include <vxWorks.h>
#include <iv.h>
#include <types.h>
#include <intLib.h>
#include <sysLib.h>
#include <stdioLib.h>
#include <vxLib.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <drvEpvxi.h>
#include <dbDefs.h>
#include <drvSup.h>
#include <dbScan.h>
#include <devLib.h>
#include <drvHpe1368a.h>
#define HPE1368A_PCONFIG(LA, PC) \
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
#define ALL_SWITCHES_OPEN 0
struct hpe1368a_config{
FAST_LOCK lock; /* mutual exclusion */
unsigned short pending; /* switch position pending int */
unsigned short shadow; /* shadow of actual switch pos */
int busy; /* relays active */
IOSCANPVT ioscanpvt;
};
#define HPE1368A_INT_LEVEL 1
LOCAL int hpe1368aDriverId;
LOCAL void hpe1368a_int_service(unsigned la);
LOCAL void hpe1368a_init_card(unsigned la);
LOCAL void hpe1368a_stat(unsigned la, int level);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvHpe1368a={
2,
NULL, /*VXI io report takes care of this */
hpe1368a_init};
/*
* hpe1368a_init
*
* initialize all hpe1368a cards
*
*/
hpe1368aStat hpe1368a_init(void)
{
hpe1368aStat r0;
/*
* do nothing on crates without VXI
*/
if(!epvxiResourceMangerOK){
return VXI_SUCCESS;
}
hpe1368aDriverId = epvxiUniqueDriverID();
{
epvxiDeviceSearchPattern dsp;
dsp.flags = VXI_DSP_make | VXI_DSP_model;
dsp.make = VXI_MAKE_HP;
dsp.model = VXI_MODEL_HPE1368A;
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
if(r0){
errMessage(r0, NULL);
return r0;
}
}
return VXI_SUCCESS;
}
/*
* HPE1368A_INIT_CARD
*
* initialize single at5vxi card
*
*/
LOCAL void hpe1368a_init_card(unsigned la)
{
hpe1368aStat r0;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
int model;
r0 = epvxiOpen(
la,
hpe1368aDriverId,
(unsigned long) sizeof(*pc),
hpe1368a_stat);
if(r0){
errMessage(r0,NULL);
return;
}
r0 = HPE1368A_PCONFIG(la, pc);
if(r0){
errMessage(r0, NULL);
return;
}
pcsr = VXIBASE(la);
/*
* we must reset the device to a known state since
* we cant read back the current state
*/
pc->pending = ALL_SWITCHES_OPEN;
pc->shadow = ALL_SWITCHES_OPEN;
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
FASTLOCKINIT(&pc->lock);
scanIoInit(&pc->ioscanpvt);
r0 = intConnect(
INUM_TO_IVEC(la),
hpe1368a_int_service,
la);
if(r0 == ERROR){
errMessage(S_dev_vxWorksVecInstlFail, NULL);
return;
}
sysIntEnable(HPE1368A_INT_LEVEL);
model = VXIMODEL(pcsr);
r0 = epvxiRegisterModelName(
VXIMAKE(pcsr),
model,
"E 1368A Microwave Switch\n");
if(r0){
errMessage(r0, NULL);
}
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
if(r0){
errMessage(r0,NULL);
}
}
/*
*
* hpe1368a_int_service()
*
*
* This device interrupts once the
* switches have settled
*
*/
LOCAL void
hpe1368a_int_service(unsigned la)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la,pc);
if(s){
return;
}
/*
* operation completed so we can update
* the shadow value
*/
pc->shadow = pc->pending;
pc->busy = FALSE;
/*
* tell them that the switches have settled
*/
scanIoRequest(pc->ioscanpvt);
}
/*
* HPE1368A_STAT
*
* initialize single at5vxi card
*
*/
LOCAL void hpe1368a_stat(
unsigned la,
int level
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s,NULL);
return;
}
pcsr = VXIBASE(la);
if(level>0){
printf("\tSwitch states %x\n", pc->shadow);
printf("\tModule status %x\n", pcsr->dir.r.status);
if(pc->busy){
printf("\tModule is busy.\n");
}
}
}
/*
* hpe1368a_getioscanpvt()
*/
hpe1368aStat hpe1368a_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
*scanpvt = pc->ioscanpvt;
return VXI_SUCCESS;
}
/*
* HPE1368A_BO_DRIVER
*/
hpe1368aStat hpe1368a_bo_driver(
unsigned la,
unsigned val,
unsigned mask
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
struct vxi_csr *pcsr;
unsigned int work;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
pcsr = VXIBASE(la);
FASTLOCK(&pc->lock);
work = pc->pending;
/* alter specified bits */
work = (work & ~mask) | (val & mask);
pc->pending = work;
ChannelEnable(pcsr) = work;
FASTUNLOCK(&pc->lock);
return VXI_SUCCESS;
}
/*
*
* HPE1368A_BI_DRIVER
*
*
*
*/
hpe1368aStat hpe1368a_bi_driver(
unsigned la,
unsigned mask,
unsigned *pval
)
{
hpe1368aStat s;
struct hpe1368a_config *pc;
s = HPE1368A_PCONFIG(la, pc);
if(s){
errMessage(s, NULL);
return s;
}
FASTLOCK(&pc->lock);
*pval = pc->shadow & mask;
FASTUNLOCK(&pc->lock);
return VXI_SUCCESS;
}

View File

@@ -0,0 +1,60 @@
/* drvHpe1368a.h*/
/* base/src/drv $Id$ */
/*
* hpe1368a_driver.h
*
* driver for hpe1368a and hpe1369a microwave switch VXI modules
*
* Author: Jeff Hill
* Date: 052192
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
*/
#define VXI_MODEL_HPE1368A (0xf28)
typedef long hpe1368aStat;
hpe1368aStat hpe1368a_init(void);
hpe1368aStat hpe1368a_getioscanpvt(
unsigned la,
IOSCANPVT *scanpvt
);
hpe1368aStat hpe1368a_bo_driver(
unsigned la,
unsigned val,
unsigned mask
);
hpe1368aStat hpe1368a_bi_driver(
unsigned la,
unsigned mask,
unsigned *pval
);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,290 @@
/* drvStc.c */
/* base/src/drv $Id$ */
/*
* The following are specific driver routines for the AMD STC
*
* NOTE: if multiple threads use these routines at once you must provide locking
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
*
*
* Author: Jeff Hill
* Date: Feb 89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
* joh 022089 Init Release
* joh 042889 Added read back
* joh 111789 Fixed reset goes to byte mode bug
* joh 121090 Fixed confusion about the polarity of internal/external
* clock between DB and the drivers.
* joh 110791 Prevent the stc from generating tc prior to the trigger
* in delayed pulse mode by forcing edge 0 delays of zero to be
* a delay of one instead.
* joh 010491 force all edge 0 delays less than two to two
* joh 082493 ANSI C and EPICS return codes
*/
#include <vxWorks.h>
#include <stdioLib.h>
#include <vxLib.h>
#include <dbDefs.h>
#include <drvSup.h>
#include <module_types.h>
#include <drvStc.h>
#include <devLib.h>
/*
* stc_io_report()
*/
stcStat stc_io_report(
volatile uint8_t *pcmd,
volatile uint16_t *pdata
)
{
uint8_t cmd;
uint16_t data;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
/*
* addd AMD STC status here
*/
return STC_SUCCESS;
}
/*
* stc_init()
*/
stcStat stc_init(
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned master_mode
)
{
uint8_t cmd;
uint16_t data;
unsigned channel;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
/*
* go to 16 bit mode in order to test the master mode register
*/
STC_BUS16;
if(master_mode != STC_MASTER_MODE){
/*
* start in a known state
*/
STC_RESET;
/*
* required since the reset puts it in byte mode
*/
STC_BUS16;
STC_SET_MASTER_MODE(master_mode);
for(channel=0; channel<CHANONCHIP; channel++)
STC_LOAD;
}
return STC_SUCCESS;
}
/*
* stc_one_shot_read()
*/
stcStat stc_one_shot_read(
unsigned *preset,
unsigned short *edge0_count,
unsigned short *edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned *int_source
)
{
uint8_t cmd;
uint16_t data;
uint16_t mode;
uint16_t edge0;
uint16_t edge1;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
if(channel>=CHANONCHIP)
return S_dev_badSignalNumber;
STC_CTR_READ(mode, edge0, edge1);
/*
* Only return values if the counter is in the proper mode
* see stc_one_shot() for info on conversions and functions selected
* by these bit fields
*/
if(mode == 0xc16a){
*int_source = FALSE;
*preset = TRUE;
*edge0_count = ~edge0;
*edge1_count = ~edge1+1;
}
else if(mode == 0xc162){
*int_source = FALSE;
*preset = FALSE;
*edge0_count = edge0-1;
*edge1_count = edge1;
}
else if(mode == 0xcb6a){
*int_source = TRUE;
*preset = TRUE;
*edge0_count = ~edge0;
*edge1_count = ~edge1+1;
}
else if(mode == 0xcb62){
*int_source = TRUE;
*preset = FALSE;
*edge0_count = edge0-1;
*edge1_count = edge1;
}
else
return S_dev_internal;
return STC_SUCCESS;
}
/*
* stc_one_shot()
*/
stcStat stc_one_shot(
unsigned preset,
unsigned edge0_count,
unsigned edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned int_source
)
{
uint8_t cmd;
uint16_t data;
if(vxMemProbe((char *)pcmd, READ, sizeof(cmd), (char *)&cmd) != OK)
return S_dev_noDevice;
if(vxMemProbe((char *)pdata, READ, sizeof(data), (char *)&data) != OK)
return S_dev_noDevice;
if(channel>=CHANONCHIP)
return S_dev_badSignalNumber;
/*
* joh 110791
* Prevent the stc from generating tc prior to the trigger
* in delayed pulse mode by forcing edge 0 delays of zero to be
* a delay of one instead.
*
* 010492
* Strange extra edges occur when the delay is 0 or 1
* and the counter is reinitialized to a width of
* zero so I have disabled a delay of one also
*
* These extra edges occur when TC is set
*/
if(edge0_count < 2)
edge0_count = 2;
STC_DISARM;
/*
* active positive going edge (gate input)
* count on the rising edge of source
* ctr source: (F1- internal) (SRC1- external)
* mode L - Hardware triggered delayed pulse one-shot
* binary count
* count down (count up if preset is TRUE)
* TC toggled output
*
* see chapter 7 of the Am9513 STC tech man concerning count + 1
*
*/
/*
* NOTE: I must be able to read back the state of the preset later
* so I encode this information in the count down/up bit.
* count up on TRUE preset
* count down on FALSE preset
*
* see stc_one_shot_read() above
*/
if(int_source){
if(preset)
STC_CTR_INIT(0xcb6a, ~edge0_count, ~edge1_count+1)
else
STC_CTR_INIT(0xcb62, edge0_count+1, edge1_count);
}else{
if(preset)
STC_CTR_INIT(0xc16a, ~edge0_count, ~edge1_count+1)
else
STC_CTR_INIT(0xc162, edge0_count+1, edge1_count);
}
STC_LOAD;
/*
*see chapter 7 of the Am9513 STC tech man concerning this step
*/
STC_STEP;
STC_SET_TC(preset);
/*
* Only arm counter if the pulse has a finite duration
*/
if(edge1_count != 0){
STC_ARM;
}
return STC_SUCCESS;
}

View File

@@ -0,0 +1,107 @@
/* drvStc.h */
/* base/src/drv $Id$ */
/*
* The following are specific driver routines for the AMD STC
*
* NOTE: if multiple threads use these routines at once you must provide locking
* so command/data sequences are gauranteed. See mz8310_driver.c for examples.
*
*
* Author: Jeff Hill
* Date: Feb 89
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
* Modification Log:
* -----------------
*
* joh 022089 Init Release
* joh 082493 ANSI C and EPICS return codes
*/
/*
* AMD STC constants
*/
#define CHANONCHIP 5U
#define CHIPCHAN (channel%CHANONCHIP)
#define CHIPNUM (channel/CHANONCHIP)
#define STC_RESET *pcmd = 0xffU
#define STC_BUS16 *pcmd = 0xefU
#define STC_SET_MASTER_MODE(D) {*pcmd = 0x17U; *pdata=(D);}
#define STC_MASTER_MODE (*pcmd = 0x17U, *pdata)
#define STC_CTR_INIT(MODE,LOAD,HOLD)\
{*pcmd = CHIPCHAN+1; *pdata = (MODE); *pdata = (LOAD); *pdata= (HOLD);}
#define STC_CTR_READ(MODE,LOAD,HOLD)\
{*pcmd = CHIPCHAN+1; (MODE) = *pdata; (LOAD) = *pdata; (HOLD) = *pdata;}
#define STC_SET_TC(D) *pcmd = 0xe0U | ((D)?8:0)|(CHIPCHAN+1U)
#define STC_LOAD *pcmd = 0x40U | 1<<(CHIPCHAN)
#define STC_STEP *pcmd = 0xf0U | (CHIPCHAN+1U)
#define STC_ARM *pcmd = 0x20U | 1<<CHIPCHAN
#define STC_DISARM *pcmd = 0xc0U | 1<<CHIPCHAN
/*
* return type of the stc routines
*/
typedef long stcStat;
#define STC_SUCCESS 0
stcStat stc_io_report(
volatile uint8_t *pcmd,
volatile uint16_t *pdata
);
stcStat stc_init(
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned master_mode
);
stcStat stc_one_shot_read(
unsigned *preset,
uint16_t *edge0_count,
uint16_t *edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned *int_source
);
stcStat stc_one_shot(
unsigned preset,
unsigned edge0_count,
unsigned edge1_count,
volatile uint8_t *pcmd,
volatile uint16_t *pdata,
unsigned channel,
unsigned int_source
);