Compare commits
19 Commits
R3.12.0-be
...
R3.12.0-be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef12c444d8 | ||
|
|
cded07df78 | ||
|
|
81fb796c8d | ||
|
|
b3af9b389a | ||
|
|
9b76f9d9c0 | ||
|
|
302f4ef6c8 | ||
|
|
64b7a679a0 | ||
|
|
e9624769cb | ||
|
|
5ccee17d09 | ||
|
|
5e67b97e89 | ||
|
|
7cd16f8ad6 | ||
|
|
b5aa0e300c | ||
|
|
c27c38d531 | ||
|
|
b46166314f | ||
|
|
593df59742 | ||
|
|
561e2e9fb9 | ||
|
|
18b173eeb6 | ||
|
|
47b3da99a0 | ||
|
|
dd0ce8918a |
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
114
src/dev/devABStatus.c
Normal 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);
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
758
src/dev/devWfPentek4261.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
30
src/drv/ansi/VXI_SETUP_README
Normal file
30
src/drv/ansi/VXI_SETUP_README
Normal 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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
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
94
src/drv/ansi/drvAt5Vxi.h
Normal 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
808
src/drv/ansi/drvCaenV265.c
Normal 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
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
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
408
src/drv/ansi/drvHp1404a.c
Normal 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
74
src/drv/ansi/drvHp1404a.h
Normal 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
359
src/drv/ansi/drvHpe1368a.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/* drvHpe1368a.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.c
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 071792 joh Added model name registration
|
||||
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
|
||||
* .03 082692 mrk Added support for new I/O event scanning and DRVET
|
||||
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <types.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <task_params.h>
|
||||
#include <fast_lock.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <devLib.h>
|
||||
|
||||
#include <drvHpe1368a.h>
|
||||
|
||||
|
||||
#define HPE1368A_PCONFIG(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
|
||||
|
||||
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
|
||||
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
|
||||
|
||||
#define ALL_SWITCHES_OPEN 0
|
||||
|
||||
struct hpe1368a_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
unsigned short pending; /* switch position pending int */
|
||||
unsigned short shadow; /* shadow of actual switch pos */
|
||||
int busy; /* relays active */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
#define HPE1368A_INT_LEVEL 1
|
||||
|
||||
LOCAL int hpe1368aDriverId;
|
||||
|
||||
LOCAL void hpe1368a_int_service(unsigned la);
|
||||
LOCAL void hpe1368a_init_card(unsigned la);
|
||||
LOCAL void hpe1368a_stat(unsigned la, int level);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvHpe1368a={
|
||||
2,
|
||||
NULL, /*VXI io report takes care of this */
|
||||
hpe1368a_init};
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_init
|
||||
*
|
||||
* initialize all hpe1368a cards
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_init(void)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
|
||||
/*
|
||||
* do nothing on crates without VXI
|
||||
*/
|
||||
if(!epvxiResourceMangerOK){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
hpe1368aDriverId = epvxiUniqueDriverID();
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_MODEL_HPE1368A;
|
||||
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_INIT_CARD
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_init_card(unsigned la)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
int model;
|
||||
|
||||
r0 = epvxiOpen(
|
||||
la,
|
||||
hpe1368aDriverId,
|
||||
(unsigned long) sizeof(*pc),
|
||||
hpe1368a_stat);
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
r0 = HPE1368A_PCONFIG(la, pc);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
/*
|
||||
* we must reset the device to a known state since
|
||||
* we cant read back the current state
|
||||
*/
|
||||
pc->pending = ALL_SWITCHES_OPEN;
|
||||
pc->shadow = ALL_SWITCHES_OPEN;
|
||||
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
|
||||
|
||||
FASTLOCKINIT(&pc->lock);
|
||||
scanIoInit(&pc->ioscanpvt);
|
||||
|
||||
r0 = intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpe1368a_int_service,
|
||||
la);
|
||||
if(r0 == ERROR){
|
||||
errMessage(S_dev_vxWorksVecInstlFail, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
sysIntEnable(HPE1368A_INT_LEVEL);
|
||||
|
||||
model = VXIMODEL(pcsr);
|
||||
r0 = epvxiRegisterModelName(
|
||||
VXIMAKE(pcsr),
|
||||
model,
|
||||
"E 1368A Microwave Switch\n");
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
}
|
||||
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpe1368a_int_service()
|
||||
*
|
||||
*
|
||||
* This device interrupts once the
|
||||
* switches have settled
|
||||
*
|
||||
*/
|
||||
LOCAL void
|
||||
hpe1368a_int_service(unsigned la)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la,pc);
|
||||
if(s){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* operation completed so we can update
|
||||
* the shadow value
|
||||
*/
|
||||
pc->shadow = pc->pending;
|
||||
pc->busy = FALSE;
|
||||
|
||||
/*
|
||||
* tell them that the switches have settled
|
||||
*/
|
||||
scanIoRequest(pc->ioscanpvt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_STAT
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s,NULL);
|
||||
return;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
if(level>0){
|
||||
printf("\tSwitch states %x\n", pc->shadow);
|
||||
printf("\tModule status %x\n", pcsr->dir.r.status);
|
||||
if(pc->busy){
|
||||
printf("\tModule is busy.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_getioscanpvt()
|
||||
*/
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
*scanpvt = pc->ioscanpvt;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_BO_DRIVER
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned int work;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
work = pc->pending;
|
||||
|
||||
/* alter specified bits */
|
||||
work = (work & ~mask) | (val & mask);
|
||||
|
||||
pc->pending = work;
|
||||
|
||||
ChannelEnable(pcsr) = work;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* HPE1368A_BI_DRIVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
*pval = pc->shadow & mask;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
60
src/drv/ansi/drvHpe1368a.h
Normal file
60
src/drv/ansi/drvHpe1368a.h
Normal 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
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
484
src/drv/ansi/drvKscV215.c
Normal 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
56
src/drv/ansi/drvKscV215.h
Normal 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
627
src/drv/ansi/drvMz8310.c
Normal 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
74
src/drv/ansi/drvMz8310.h
Normal 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
290
src/drv/ansi/drvStc.c
Normal 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
107
src/drv/ansi/drvStc.h
Normal 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
250
src/drv/ansi/drvTime.c
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
52
src/libCom/env/envSubr.c
vendored
52
src/libCom/env/envSubr.c
vendored
@@ -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++));
|
||||
}
|
||||
|
||||
|
||||
@@ -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++));
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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){
|
||||
|
||||
1410
src/vxWorks/drv/ansi/drvAt5Vxi.c
Normal file
1410
src/vxWorks/drv/ansi/drvAt5Vxi.c
Normal file
File diff suppressed because it is too large
Load Diff
94
src/vxWorks/drv/ansi/drvAt5Vxi.h
Normal file
94
src/vxWorks/drv/ansi/drvAt5Vxi.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
*
|
||||
* driver for at5 designed VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 11-89
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <dbScan.h>
|
||||
|
||||
typedef long at5VxiStatus;
|
||||
|
||||
at5VxiStatus at5vxi_one_shot(
|
||||
unsigned preset, /* TRUE or COMPLEMENT logic */
|
||||
double edge0_delay, /* sec */
|
||||
double edge1_delay, /* set */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned int_source, /* (FALSE)External/(TRUE)Internal source */
|
||||
void (*event_rtn)(void *pParam), /* subroutine to run on events */
|
||||
void *event_rtn_param/* parameter to pass to above routine */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_one_shot_read(
|
||||
unsigned *preset, /* TRUE or COMPLEMENT logic */
|
||||
double *edge0_delay, /* sec */
|
||||
double *edge1_delay, /* sec */
|
||||
unsigned card, /* 0 through ... */
|
||||
unsigned channel, /* 0 through channels on a card */
|
||||
unsigned *int_source /* (FALSE)External/(TRUE)Internal src */
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ai_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_driver(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *prval,
|
||||
unsigned short *prbval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_ao_read(
|
||||
unsigned card,
|
||||
unsigned chan,
|
||||
unsigned short *pval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bi_driver(
|
||||
unsigned card,
|
||||
unsigned long mask,
|
||||
unsigned long *prval
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_bo_driver(
|
||||
unsigned card,
|
||||
unsigned long val,
|
||||
unsigned long mask
|
||||
);
|
||||
|
||||
at5VxiStatus at5vxi_getioscanpvt(
|
||||
unsigned card,
|
||||
IOSCANPVT *scanpvt
|
||||
);
|
||||
|
||||
408
src/vxWorks/drv/ansi/drvHp1404a.c
Normal file
408
src/vxWorks/drv/ansi/drvHp1404a.c
Normal 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/vxWorks/drv/ansi/drvHp1404a.h
Normal file
74
src/vxWorks/drv/ansi/drvHp1404a.h
Normal 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/vxWorks/drv/ansi/drvHpe1368a.c
Normal file
359
src/vxWorks/drv/ansi/drvHpe1368a.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/* drvHpe1368a.c*/
|
||||
/* base/src/drv $Id$ */
|
||||
|
||||
/*
|
||||
* hpe1368a_driver.c
|
||||
*
|
||||
* driver for hpe1368a and hpe1369a microwave switch VXI modules
|
||||
*
|
||||
* Author: Jeff Hill
|
||||
* Date: 052192
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 071792 joh Added model name registration
|
||||
* .02 081992 joh vxiUniqueDriverID -> epvxiUniqueDriverID
|
||||
* .03 082692 mrk Added support for new I/O event scanning and DRVET
|
||||
* .04 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
|
||||
*
|
||||
*/
|
||||
|
||||
static char *sccsId = "@(#)drvHpe1368a.c 1.14\t9/9/93";
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <iv.h>
|
||||
#include <types.h>
|
||||
#include <intLib.h>
|
||||
#include <sysLib.h>
|
||||
#include <stdioLib.h>
|
||||
#include <vxLib.h>
|
||||
|
||||
#include <module_types.h>
|
||||
#include <task_params.h>
|
||||
#include <fast_lock.h>
|
||||
#include <drvEpvxi.h>
|
||||
#include <dbDefs.h>
|
||||
#include <drvSup.h>
|
||||
#include <dbScan.h>
|
||||
#include <devLib.h>
|
||||
|
||||
#include <drvHpe1368a.h>
|
||||
|
||||
|
||||
#define HPE1368A_PCONFIG(LA, PC) \
|
||||
epvxiFetchPConfig((LA), hpe1368aDriverId, (PC))
|
||||
|
||||
#define ChannelEnable(PCSR) ((PCSR)->dir.w.dd.reg.ddx08)
|
||||
#define ModuleStatus(PCSR) ((PCSR)->dir.r.status)
|
||||
|
||||
#define ALL_SWITCHES_OPEN 0
|
||||
|
||||
struct hpe1368a_config{
|
||||
FAST_LOCK lock; /* mutual exclusion */
|
||||
unsigned short pending; /* switch position pending int */
|
||||
unsigned short shadow; /* shadow of actual switch pos */
|
||||
int busy; /* relays active */
|
||||
IOSCANPVT ioscanpvt;
|
||||
};
|
||||
|
||||
#define HPE1368A_INT_LEVEL 1
|
||||
|
||||
LOCAL int hpe1368aDriverId;
|
||||
|
||||
LOCAL void hpe1368a_int_service(unsigned la);
|
||||
LOCAL void hpe1368a_init_card(unsigned la);
|
||||
LOCAL void hpe1368a_stat(unsigned la, int level);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DRVSUPFUN report;
|
||||
DRVSUPFUN init;
|
||||
} drvHpe1368a={
|
||||
2,
|
||||
NULL, /*VXI io report takes care of this */
|
||||
hpe1368a_init};
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_init
|
||||
*
|
||||
* initialize all hpe1368a cards
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_init(void)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
|
||||
/*
|
||||
* do nothing on crates without VXI
|
||||
*/
|
||||
if(!epvxiResourceMangerOK){
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
hpe1368aDriverId = epvxiUniqueDriverID();
|
||||
|
||||
{
|
||||
epvxiDeviceSearchPattern dsp;
|
||||
|
||||
dsp.flags = VXI_DSP_make | VXI_DSP_model;
|
||||
dsp.make = VXI_MAKE_HP;
|
||||
dsp.model = VXI_MODEL_HPE1368A;
|
||||
r0 = epvxiLookupLA(&dsp, hpe1368a_init_card, (void *)NULL);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return r0;
|
||||
}
|
||||
}
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_INIT_CARD
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_init_card(unsigned la)
|
||||
{
|
||||
hpe1368aStat r0;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
int model;
|
||||
|
||||
r0 = epvxiOpen(
|
||||
la,
|
||||
hpe1368aDriverId,
|
||||
(unsigned long) sizeof(*pc),
|
||||
hpe1368a_stat);
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
r0 = HPE1368A_PCONFIG(la, pc);
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
/*
|
||||
* we must reset the device to a known state since
|
||||
* we cant read back the current state
|
||||
*/
|
||||
pc->pending = ALL_SWITCHES_OPEN;
|
||||
pc->shadow = ALL_SWITCHES_OPEN;
|
||||
ChannelEnable(pcsr) = ALL_SWITCHES_OPEN;
|
||||
|
||||
FASTLOCKINIT(&pc->lock);
|
||||
scanIoInit(&pc->ioscanpvt);
|
||||
|
||||
r0 = intConnect(
|
||||
INUM_TO_IVEC(la),
|
||||
hpe1368a_int_service,
|
||||
la);
|
||||
if(r0 == ERROR){
|
||||
errMessage(S_dev_vxWorksVecInstlFail, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
sysIntEnable(HPE1368A_INT_LEVEL);
|
||||
|
||||
model = VXIMODEL(pcsr);
|
||||
r0 = epvxiRegisterModelName(
|
||||
VXIMAKE(pcsr),
|
||||
model,
|
||||
"E 1368A Microwave Switch\n");
|
||||
if(r0){
|
||||
errMessage(r0, NULL);
|
||||
}
|
||||
r0 = epvxiRegisterMakeName(VXIMAKE(pcsr), "Hewlett-Packard");
|
||||
if(r0){
|
||||
errMessage(r0,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hpe1368a_int_service()
|
||||
*
|
||||
*
|
||||
* This device interrupts once the
|
||||
* switches have settled
|
||||
*
|
||||
*/
|
||||
LOCAL void
|
||||
hpe1368a_int_service(unsigned la)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la,pc);
|
||||
if(s){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* operation completed so we can update
|
||||
* the shadow value
|
||||
*/
|
||||
pc->shadow = pc->pending;
|
||||
pc->busy = FALSE;
|
||||
|
||||
/*
|
||||
* tell them that the switches have settled
|
||||
*/
|
||||
scanIoRequest(pc->ioscanpvt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_STAT
|
||||
*
|
||||
* initialize single at5vxi card
|
||||
*
|
||||
*/
|
||||
LOCAL void hpe1368a_stat(
|
||||
unsigned la,
|
||||
int level
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s,NULL);
|
||||
return;
|
||||
}
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
if(level>0){
|
||||
printf("\tSwitch states %x\n", pc->shadow);
|
||||
printf("\tModule status %x\n", pcsr->dir.r.status);
|
||||
if(pc->busy){
|
||||
printf("\tModule is busy.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hpe1368a_getioscanpvt()
|
||||
*/
|
||||
hpe1368aStat hpe1368a_getioscanpvt(
|
||||
unsigned la,
|
||||
IOSCANPVT *scanpvt
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
*scanpvt = pc->ioscanpvt;
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HPE1368A_BO_DRIVER
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bo_driver(
|
||||
unsigned la,
|
||||
unsigned val,
|
||||
unsigned mask
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
struct vxi_csr *pcsr;
|
||||
unsigned int work;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
pcsr = VXIBASE(la);
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
work = pc->pending;
|
||||
|
||||
/* alter specified bits */
|
||||
work = (work & ~mask) | (val & mask);
|
||||
|
||||
pc->pending = work;
|
||||
|
||||
ChannelEnable(pcsr) = work;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* HPE1368A_BI_DRIVER
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
hpe1368aStat hpe1368a_bi_driver(
|
||||
unsigned la,
|
||||
unsigned mask,
|
||||
unsigned *pval
|
||||
)
|
||||
{
|
||||
hpe1368aStat s;
|
||||
struct hpe1368a_config *pc;
|
||||
|
||||
s = HPE1368A_PCONFIG(la, pc);
|
||||
if(s){
|
||||
errMessage(s, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
FASTLOCK(&pc->lock);
|
||||
|
||||
*pval = pc->shadow & mask;
|
||||
|
||||
FASTUNLOCK(&pc->lock);
|
||||
|
||||
return VXI_SUCCESS;
|
||||
}
|
||||
60
src/vxWorks/drv/ansi/drvHpe1368a.h
Normal file
60
src/vxWorks/drv/ansi/drvHpe1368a.h
Normal 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/vxWorks/drv/ansi/drvHpe1445a.c
Normal file
1185
src/vxWorks/drv/ansi/drvHpe1445a.c
Normal file
File diff suppressed because it is too large
Load Diff
290
src/vxWorks/drv/ansi/drvStc.c
Normal file
290
src/vxWorks/drv/ansi/drvStc.c
Normal 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/vxWorks/drv/ansi/drvStc.h
Normal file
107
src/vxWorks/drv/ansi/drvStc.h
Normal 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
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user