restructure; new Symb support

This commit is contained in:
Marty Kraimer
1998-01-21 20:48:12 +00:00
parent fe2d8d5564
commit f3eb906bf3
179 changed files with 11918 additions and 6667 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+74
View File
@@ -0,0 +1,74 @@
/*
* *****************************************************************
* 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).
*/
#ifndef EPICS_DEVAPSER_H
#define EPICS_DEVAPSER_H
/* Error numbers passed to ERROR_FUNC routines */
#define ERROR_TAXI 1 /* Taxi violation */
#define ERROR_HEART 2 /* Lost the system heart beat */
#define ERROR_LOST 3 /* Events were lost */
/* Globally reserved event numbers */
#define ER_EVENT_NULL 0x00 /* NULL event */
#define ER_EVENT_END 0x7f /* Event sequence end */
#define ER_EVENT_FREEZE 0x7e /* Freeze the event sequence */
#define ER_EVENT_RESET_TICK 0x7d /* Reset the tick counter */
#define ER_EVENT_TICK 0x7c /* Add 1 to the tick counter */
#define ER_EVENT_RESET_PRESCALERS 0x7b
#define ER_EVENT_HEARTBEAT 0x7a
typedef void (*EVENT_FUNC)(int Card, int EventNum, unsigned long Ticks);
typedef void (*ERROR_FUNC)(int Card, int ErrorNum);
long ErRegisterEventHandler(int Card, EVENT_FUNC func);
long ErRegisterErrorHandler(int Card, ERROR_FUNC func);
long ErGetTicks(int Card, unsigned long *Ticks);
long ErHaveReceiver(int Card);
#endif
+584
View File
@@ -0,0 +1,584 @@
/* devAt5Vxi.c */
/* base/src/dev $Id$ */
/* devAt5Vxi.c - Device Support Routines */
/*
* Original Author: Bob Dalesio
* Current Author: Marty Kraimer
* Date: 6-1-90
*
* 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 08-21-92 mrk Replaces individual At5Vxi modules
* .02 05-27-93 joh changed linear conversion
* .03 09-01-93 joh expects EPICS status from driver
* .04 09-02-93 mcn added AT5VXI Timer support
* .05 10-08-93 mcn added support for Direct mbbo and mbbi
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <dbScan.h>
#include <link.h>
#include <module_types.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbbiDirectRecord.h>
#include <mbboRecord.h>
#include <mbboDirectRecord.h>
#include <timerRecord.h>
#include <drvAt5Vxi.h>
/* The following must match the definition in choiceGbl.ascii */
#define LINEAR 1
static long init_ai();
static long init_ao();
static long init_bi();
static long init_bo();
static long init_mbbi();
static long init_mbbiDirect();
static long init_mbbo();
static long init_mbboDirect();
static long ai_ioinfo();
static long bi_ioinfo();
static long mbbi_ioinfo();
static long mbbiDirect_ioinfo();
static long read_timer();
static long read_ai();
static long write_ao();
static long read_bi();
static long write_timer();
static long write_bo();
static long read_mbbi();
static long read_mbbiDirect();
static long write_mbbo();
static long write_mbboDirect();
static long ai_lincvt();
static long ao_lincvt();
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_write;
DEVSUPFUN special_linconv;} AT5VXIDSET;
AT5VXIDSET devAiAt5Vxi= {6, NULL, NULL, init_ai, ai_ioinfo, read_ai, ai_lincvt};
AT5VXIDSET devAoAt5Vxi= {6, NULL, NULL, init_ao, NULL, write_ao, ao_lincvt};
AT5VXIDSET devBiAt5Vxi= {6, NULL, NULL, init_bi, bi_ioinfo, read_bi, NULL};
AT5VXIDSET devBoAt5Vxi= {6, NULL, NULL, init_bo, NULL, write_bo, NULL};
AT5VXIDSET devMbbiAt5Vxi= {6, NULL, NULL, init_mbbi, mbbi_ioinfo, read_mbbi, NULL};
AT5VXIDSET devMbbiDirectAt5Vxi= {6, NULL, NULL, init_mbbiDirect, mbbiDirect_ioinfo, read_mbbiDirect, NULL};
AT5VXIDSET devMbboAt5Vxi= {6, NULL, NULL, init_mbbo, NULL, write_mbbo, NULL};
AT5VXIDSET devMbboDirectAt5Vxi= {6, NULL, NULL, init_mbboDirect, NULL, write_mbboDirect, NULL};
/* DSET structure for timer records */
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read;
DEVSUPFUN write;} AT5VXIDSET_TM;
AT5VXIDSET_TM devTmAt5Vxi={6, NULL, NULL, NULL, NULL, read_timer, write_timer};
/*
* These constants are indexed by the time units field in the timer record.
* 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;
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);
/* put the value to the ao driver */
if (at5vxi_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 */
return 1;
}
/* convert according to time units */
constant = constants[ptimer->timu];
/* timing pulse 1 is currently active */
/* put its parameters into the database so that it will not change */
/* when the timer record is written */
ptimer->rdt1 = time_pulse[0] * constant; /* delay to trigger */
ptimer->rpw1 = time_pulse[1] * constant; /* pulse width */
return 0;
}
static long write_timer(struct timerRecord *ptimer)
{
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(
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)
{
unsigned short value;
struct vmeio *pvmeio;
long status;
/* ai.inp must be an VME_IO */
switch (pai->inp.type) {
case (VME_IO) :
break;
default :
recGblRecordError(S_db_badField,(void *)pai,
"devAiAt5Vxi (init_record) Illegal INP field");
return(S_db_badField);
}
/* set linear conversion slope*/
pai->eslo = (pai->eguf -pai->egul)/0xffff;
/* call driver so that it configures card */
pvmeio = (struct vmeio *)&(pai->inp.value);
if(status=at5vxi_ai_driver(pvmeio->card,pvmeio->signal,&value)) {
recGblRecordError(status,(void *)pai,
"devAiAt5Vxi (init_record) at5vxi_ai_driver error");
return(status);
}
return(0);
}
static long ai_ioinfo(
int cmd,
struct aiRecord *pai,
IOSCANPVT *ppvt)
{
return at5vxi_getioscanpvt(pai->inp.value.vmeio.card,ppvt);
}
static long read_ai(struct aiRecord *pai)
{
struct vmeio *pvmeio;
long status;
unsigned short value;
pvmeio = (struct vmeio *)&(pai->inp.value);
status = at5vxi_ai_driver(pvmeio->card,pvmeio->signal,&value);
if(status==0){
pai->rval = value;
}
else{
recGblSetSevr(pai,READ_ALARM,INVALID_ALARM);
}
return(status);
}
static long ai_lincvt(struct aiRecord *pai, int after)
{
if(!after) return(0);
/* set linear conversion slope*/
pai->eslo = (pai->eguf -pai->egul)/0xffff;
return(0);
}
static long read_ao(); /* forward reference*/
static long init_ao(struct aoRecord *pao)
{
/* ao.out must be an VME_IO */
switch (pao->out.type) {
case (VME_IO) :
break;
default :
recGblRecordError(S_db_badField,(void *)pao,
"devAoAt5Vxi (init_record) Illegal OUT field");
return(S_db_badField);
}
/* set linear conversion slope*/
pao->eslo = (pao->eguf -pao->egul)/0xffff;
/* call driver so that it configures card */
return read_ao(pao);
}
static long write_ao(struct aoRecord *pao)
{
struct vmeio *pvmeio;
long status;
unsigned short value,rbvalue;
pvmeio = (struct vmeio *)&(pao->out.value);
value = pao->rval;
status = at5vxi_ao_driver(pvmeio->card,pvmeio->signal,&value,&rbvalue);
if(status == 0){
pao->rbv = rbvalue;
}
else{
recGblSetSevr(pao,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
static long ao_lincvt( struct aoRecord *pao, int after)
{
if(!after) return(0);
/* set linear conversion slope*/
pao->eslo = (pao->eguf -pao->egul)/0xffff;
return(0);
}
static long read_ao(pao)
struct aoRecord *pao;
{
long status;
unsigned short value;
struct vmeio *pvmeio = &pao->out.value.vmeio;
/* get the value from the ao driver */
status = at5vxi_ao_read(pvmeio->card,pvmeio->signal,&value);
if(status == 0){
pao->rbv = pao->rval = value;
}
return status;
}
static long init_bi( struct biRecord *pbi)
{
struct vmeio *pvmeio;
/* bi.inp must be an VME_IO */
switch (pbi->inp.type) {
case (VME_IO) :
pvmeio = (struct vmeio *)&(pbi->inp.value);
pbi->mask=1;
pbi->mask <<= pvmeio->signal;
break;
default :
recGblRecordError(S_db_badField,(void *)pbi,
"devBiAt5Vxi (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long bi_ioinfo(
int cmd,
struct biRecord *pbi,
IOSCANPVT *ppvt)
{
return at5vxi_getioscanpvt(pbi->inp.value.vmeio.card,ppvt);
}
static long read_bi(struct biRecord *pbi)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
pvmeio = (struct vmeio *)&(pbi->inp.value);
status = at5vxi_bi_driver(pvmeio->card,pbi->mask,&value);
if(status==0) {
pbi->rval = value;
} else {
recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM);
}
return status;
}
static long init_bo(struct boRecord *pbo)
{
unsigned long value;
long status=0;
struct vmeio *pvmeio;
/* bo.out must be an VME_IO */
switch (pbo->out.type) {
case (VME_IO) :
pvmeio = (struct vmeio *)&(pbo->out.value);
pbo->mask = 1;
pbo->mask <<= pvmeio->signal;
status = at5vxi_bi_driver(pvmeio->card,pbo->mask,&value);
if(status == 0){
pbo->rbv = pbo->rval = value;
}
break;
default :
status = S_db_badField;
recGblRecordError(status,(void *)pbo,
"devBoAt5Vxi (init_record) Illegal OUT field");
}
return(status);
}
static long write_bo(struct boRecord *pbo)
{
struct vmeio *pvmeio;
long status;
pvmeio = (struct vmeio *)&(pbo->out.value);
status = at5vxi_bo_driver(pvmeio->card,pbo->rval,pbo->mask);
if(status!=0) {
recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
static long init_mbbi(struct mbbiRecord *pmbbi)
{
/* mbbi.inp must be an VME_IO */
switch (pmbbi->inp.type) {
case (VME_IO) :
pmbbi->shft = pmbbi->inp.value.vmeio.signal;
pmbbi->mask <<= pmbbi->shft;
break;
default :
recGblRecordError(S_db_badField,(void *)pmbbi,
"devMbbiAt5Vxi (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long init_mbbiDirect(struct mbbiDirectRecord *pmbbi)
{
/* mbbi.inp must be an VME_IO */
switch (pmbbi->inp.type) {
case (VME_IO) :
pmbbi->shft = pmbbi->inp.value.vmeio.signal;
pmbbi->mask <<= pmbbi->shft;
break;
default :
recGblRecordError(S_db_badField,(void *)pmbbi,
"devMbbiDirectAt5Vxi (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long mbbi_ioinfo(
int cmd,
struct mbbiRecord *pmbbi,
IOSCANPVT *ppvt)
{
return at5vxi_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt);
}
static long mbbiDirect_ioinfo(
int cmd,
struct mbbiDirectRecord *pmbbi,
IOSCANPVT *ppvt)
{
return at5vxi_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt);
}
static long read_mbbi(struct mbbiRecord *pmbbi)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
pvmeio = (struct vmeio *)&(pmbbi->inp.value);
status = at5vxi_bi_driver(pvmeio->card,pmbbi->mask,&value);
if(status==0) {
pmbbi->rval = value;
} else {
recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM);
}
return(status);
}
static long read_mbbiDirect(struct mbbiDirectRecord *pmbbi)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
pvmeio = (struct vmeio *)&(pmbbi->inp.value);
status = at5vxi_bi_driver(pvmeio->card,pmbbi->mask,&value);
if(status==0) {
pmbbi->rval = value;
} else {
recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM);
}
return(status);
}
static long init_mbbo(struct mbboRecord *pmbbo)
{
unsigned long value;
struct vmeio *pvmeio;
long status = 0;
/* mbbo.out must be an VME_IO */
switch (pmbbo->out.type) {
case (VME_IO) :
pvmeio = &(pmbbo->out.value.vmeio);
pmbbo->shft = pvmeio->signal;
pmbbo->mask <<= pmbbo->shft;
status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = pmbbo->rval = value;
break;
default :
status = S_db_badField;
recGblRecordError(status,(void *)pmbbo,
"devMbboAt5Vxi (init_record) Illegal OUT field");
}
return(status);
}
static long init_mbboDirect(struct mbboDirectRecord *pmbbo)
{
unsigned long value;
struct vmeio *pvmeio;
long status = 0;
/* mbbo.out must be an VME_IO */
switch (pmbbo->out.type) {
case (VME_IO) :
pvmeio = &(pmbbo->out.value.vmeio);
pmbbo->shft = pvmeio->signal;
pmbbo->mask <<= pmbbo->shft;
status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = pmbbo->rval = value;
break;
default :
status = S_db_badField;
recGblRecordError(status,(void *)pmbbo,
"devMbboDirectAt5Vxi (init_record) Illegal OUT field");
}
return(status);
}
static long write_mbbo(struct mbboRecord *pmbbo)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
pvmeio = &(pmbbo->out.value.vmeio);
status = at5vxi_bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask);
if(status==0) {
status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = value;
else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM);
} else {
recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
static long write_mbboDirect(struct mbboDirectRecord *pmbbo)
{
struct vmeio *pvmeio;
long status;
unsigned long value;
pvmeio = &(pmbbo->out.value.vmeio);
status = at5vxi_bo_driver(pvmeio->card,pmbbo->rval,pmbbo->mask);
if(status==0) {
status = at5vxi_bi_driver(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = value;
else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM);
} else {
recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
+251
View File
@@ -0,0 +1,251 @@
/* devAt8At8Fp.c */
/* base/src/dev $Id$ */
/*
* Original Author: Bob Dalesio
* Current Author: Marty Kraimer
* Date: 09-02-92
*
* 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 08-02-92 mrk Original version
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <dbScan.h>
#include <link.h>
#include <module_types.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
static long init_bi();
static long init_bo();
static long init_mbbi();
static long init_mbbo();
static long bi_ioinfo();
static long mbbi_ioinfo();
static long read_bi();
static long write_bo();
static long read_mbbi();
static long write_mbbo();
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_write;
} BINARYDSET;
BINARYDSET devBiAt8Fp= {6,NULL,NULL,init_bi, bi_ioinfo, read_bi};
BINARYDSET devBoAt8Fp= {6,NULL,NULL,init_bo, NULL, write_bo};
BINARYDSET devMbbiAt8Fp={6,NULL,NULL,init_mbbi,mbbi_ioinfo,read_mbbi};
BINARYDSET devMbboAt8Fp={6,NULL,NULL,init_mbbo, NULL,write_mbbo};
static long init_bi( struct biRecord *pbi)
{
struct vmeio *pvmeio;
/* bi.inp must be an VME_IO */
switch (pbi->inp.type) {
case (VME_IO) :
pvmeio = (struct vmeio *)&(pbi->inp.value);
pbi->mask=1;
pbi->mask <<= pvmeio->signal;
break;
default :
recGblRecordError(S_db_badField,(void *)pbi,
"devBiAt8Fp (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long bi_ioinfo(
int cmd,
struct biRecord *pbi,
IOSCANPVT *ppvt)
{
fp_getioscanpvt(pbi->inp.value.vmeio.card,ppvt);
return(0);
}
static long read_bi(struct biRecord *pbi)
{
struct vmeio *pvmeio;
int status;
long value;
pvmeio = (struct vmeio *)&(pbi->inp.value);
status = fp_read(pvmeio->card,pbi->mask,&value);
if(status==0) {
pbi->rval = value;
return(0);
} else {
recGblSetSevr(pbi,READ_ALARM,INVALID_ALARM);
return(2);
}
}
static long init_bo(struct boRecord *pbo)
{
unsigned int value;
int status=0;
struct vmeio *pvmeio;
/* bo.out must be an VME_IO */
switch (pbo->out.type) {
case (VME_IO) :
pvmeio = (struct vmeio *)&(pbo->out.value);
pbo->mask = 1;
pbo->mask <<= pvmeio->signal;
status = fp_read(pvmeio->card,pbo->mask,&value);
if(status == 0) pbo->rbv = pbo->rval = value;
else status = 2;
break;
default :
status = S_db_badField;
recGblRecordError(status,(void *)pbo,
"devBoAt8Fp (init_record) Illegal OUT field");
}
return(status);
}
static long write_bo(struct boRecord *pbo)
{
struct vmeio *pvmeio;
int status;
pvmeio = (struct vmeio *)&(pbo->out.value);
status = fp_driver(pvmeio->card,pbo->rval,pbo->mask);
if(status!=0) {
recGblSetSevr(pbo,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
static long init_mbbi(struct mbbiRecord *pmbbi)
{
/* mbbi.inp must be an VME_IO */
switch (pmbbi->inp.type) {
case (VME_IO) :
pmbbi->shft = pmbbi->inp.value.vmeio.signal;
pmbbi->mask <<= pmbbi->shft;
break;
default :
recGblRecordError(S_db_badField,(void *)pmbbi,
"devMbbiAt8Fp (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long mbbi_ioinfo(
int cmd,
struct mbbiRecord *pmbbi,
IOSCANPVT *ppvt)
{
fp_getioscanpvt(pmbbi->inp.value.vmeio.card,ppvt);
return(0);
}
static long read_mbbi(struct mbbiRecord *pmbbi)
{
struct vmeio *pvmeio;
int status;
unsigned long value;
pvmeio = (struct vmeio *)&(pmbbi->inp.value);
status = fp_read(pvmeio->card,pmbbi->mask,&value);
if(status==0) {
pmbbi->rval = value;
} else {
recGblSetSevr(pmbbi,READ_ALARM,INVALID_ALARM);
}
return(status);
}
static long init_mbbo(struct mbboRecord *pmbbo)
{
unsigned long value;
struct vmeio *pvmeio;
int status = 0;
/* mbbo.out must be an VME_IO */
switch (pmbbo->out.type) {
case (VME_IO) :
pvmeio = &(pmbbo->out.value.vmeio);
pmbbo->shft = pvmeio->signal;
pmbbo->mask <<= pmbbo->shft;
status = fp_read(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = pmbbo->rval = value;
else status = 2;
break;
default :
status = S_db_badField;
recGblRecordError(status,(void *)pmbbo,
"devMbboAt8Fp (init_record) Illegal OUT field");
}
return(status);
}
static long write_mbbo(struct mbboRecord *pmbbo)
{
struct vmeio *pvmeio;
int status;
unsigned long value;
pvmeio = &(pmbbo->out.value.vmeio);
status = fp_driver(pvmeio->card,pmbbo->rval,pmbbo->mask);
if(status==0) {
status = fp_read(pvmeio->card,pmbbo->mask,&value);
if(status==0) pmbbo->rbv = value;
else recGblSetSevr(pmbbo,READ_ALARM,INVALID_ALARM);
} else {
recGblSetSevr(pmbbo,WRITE_ALARM,INVALID_ALARM);
}
return(status);
}
@@ -0,0 +1,82 @@
/* devSmCompumotor1830.c */
/* base/src/dev $Id$ */
/* devSmCompumotor1830.c - Device Support Routines */
/*
* Original Author: Bob Dalesio
* Current Author: Marty Kraimer
* 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-08092 mrk Moved from record support
*/
#include <vxWorks.h>
#include <types.h>
#include <stdioLib.h>
#include <string.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <recSup.h>
#include <devSup.h>
#include <link.h>
#include <module_types.h>
#include <steppermotorRecord.h>
#include <steppermotor.h>
/* Create the dset for */
static long sm_command();
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN sm_command;
}devSmCompumotor1830={
6,
NULL,
NULL,
NULL,
NULL,
sm_command};
static long sm_command(psm,command,arg1,arg2)
struct steppermotorRecord *psm;
short command;
int arg1;
int arg2;
{
short card,channel;
card = psm->out.value.vmeio.card;
channel = psm->out.value.vmeio.signal;
compu_driver(card,channel,command,arg1,arg2);
return(0);
}
File diff suppressed because it is too large Load Diff
+348
View File
@@ -0,0 +1,348 @@
/* devCommonGpib.h */
/* share/epicsH/devCommonGpib.h $Id$ */
/*
* Author: John Winans
* Date: 11-19-91
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1988, 1989, 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
*
* All rights reserved. No part of this publication may be reproduced,
* stored in a retrieval system, transmitted, in any form or by any
* means, electronic, mechanical, photocopying, recording, or otherwise
* without prior written permission of Los Alamos National Laboratory
* and Argonne National Laboratory.
*
* Modification Log:
* -----------------
* .01 11-19-91 jrw Initial release
* .02 02-26-92 jrw removed declaration of callbackRequest()
* .03 05-11-92 jrw Added waveform record support
*/
#ifndef DEVCOMMONGPIB_H
#define DEVCOMMONGPIB_H
long devGpibLib_report();
long devGpibLib_initDevSup();
long devGpibLib_initAi();
long devGpibLib_initAo();
long devGpibLib_initLi();
long devGpibLib_initLo();
long devGpibLib_initBi();
long devGpibLib_initBo();
long devGpibLib_initMbbo();
long devGpibLib_initMbbi();
long devGpibLib_initSi();
long devGpibLib_initSo();
long devGpibLib_initXx();
long devGpibLib_readAi();
long devGpibLib_writeAo();
long devGpibLib_readLi();
long devGpibLib_writeLo();
long devGpibLib_readBi();
long devGpibLib_writeBo();
long devGpibLib_readMbbi();
long devGpibLib_writeMbbo();
long devGpibLib_readSi();
long devGpibLib_writeSo();
int devGpibLib_aiGpibWork();
int devGpibLib_aiGpibSrq();
int devGpibLib_aiGpibFinish();
int devGpibLib_aoGpibWork();
int devGpibLib_liGpibWork();
int devGpibLib_liGpibSrq();
int devGpibLib_liGpibFinish();
int devGpibLib_loGpibWork();
int devGpibLib_biGpibWork();
int devGpibLib_biGpibSrq();
int devGpibLib_biGpibFinish();
int devGpibLib_boGpibWork();
int devGpibLib_mbbiGpibWork();
int devGpibLib_mbbiGpibSrq();
int devGpibLib_mbbiGpibFinish();
int devGpibLib_mbboGpibWork();
int devGpibLib_stringinGpibWork();
int devGpibLib_stringinGpibSrq();
int devGpibLib_stringinGpibFinish();
int devGpibLib_stringoutGpibWork();
int devGpibLib_xxGpibWork();
int devGpibLib_wfGpibFinish();
int devGpibLib_wfGpibSrq();
int devGpibLib_wfGpibWork();
long devGpibLib_readWf();
long devGpibLib_initWf();
void devGpibLib_processCallback();
long devGpibLib_setPvSevr();
typedef struct {
long number;
DEVSUPFUN funPtr[20];
} gDset;
/******************************************************************************
*
* This structure holds device-related data on a per-device basis and is
* referenced by the gpibDpvt structures. They are built using a linked
* list entered from hwpvtHead. This linked list is only for this specific
* device type (other gpib devices may have their own lists.)
*
* The srqCallback() and parm fields are used for GPIBREADW type calls. They
* should place the address of the appropriate function (aiGpibSrq if an AI
* record is being processed) into the srqCallback() field and the pdpvt
* field for the device into the parm field. This allows the SrqHandler()
* function to locate the proper function and work areas to complete the
* GPIBREADW operation.
*
* The unsolicitedDpvt field is used if the user specifies a record with
* the parm number associated with handleing unsolicited SRQ interrupts.
* What is done, is that the record will be processed when an SRQ is
* detected for reasons other than GPIBREADW-related reasons. There may
* be at most, 1 single record in hte database that can specify the 'magic'
* parm number. If you need more, forward link it to a fanout record.
*
******************************************************************************/
struct hwpvt {
struct hwpvt *next; /* to next structure for same type device */
int linkType; /* is a GPIB_IO, BBGPIB_IO... from link.h */
int link; /* link number */
int bug; /* used only on BBGPIB_IO links */
int device; /* gpib device number */
unsigned long tmoVal; /* time last timeout occurred */
unsigned long tmoCount; /* total number of timeouts since boot time */
/* No semaphore guards here because can inly be mod'd by the linkTask */
int (*srqCallback)(); /* filled by cmds expecting SRQ callbacks */
caddr_t parm; /* filled in by cmds expecting SRQ callbacks */
struct gpibDpvt *unsolicitedDpvt; /* filled in if database calls for it */
caddr_t pupvt; /* user defined pointer */
};
/******************************************************************************
*
* This structure will be attached to each pv (via psub->dpvt) to store the
* appropriate head.workStart pointer, callback address to record support,
* gpib link #, device address, and command information.
*
******************************************************************************/
struct gpibDpvt {
struct dpvtGpibHead head; /* fields used by the GPIB driver */
short parm; /* parameter index into gpib commands */
char *rsp; /* for read/write message error Responses*/
char *msg; /* for read/write messages */
struct dbCommon *precord; /* record this dpvt is part of */
void (*process)(); /* callback to perform forward db processing */
int processPri; /* process callback's priority */
long linkType; /* GPIB_IO, BBGPIB_IO... */
struct hwpvt *phwpvt; /* pointer to per-device private area */
caddr_t pupvt; /* user defined pointer */
};
#define GET_GPIB_HW_PVT(pGpibDpvt) (((struct gpibDpvt*)(pGpibDpvt))->phwpvt->pupvt)
#define SET_GPIB_HW_PVT(pGpibDpvt, value) (((struct gpibDpvt*)(pGpibDpvt))->phwpvt->pupvt = value)
/******************************************************************************
*
* This is used to define the strings that are used for button labels.
* These strings are put into the record's znam & onam foelds if the
* record is a BI or BO type and into the zrst, onst... fields of an
* MBBI or MBBO record.
*
* Before these strings are placed into the record, the record is
* check to see if there is already a string defined (could be user-entered
* with DCT.) If there is already a string present, it will be preserved.
*
* There MUST ALWAYS be 2 and only 2 entries in the names.item list
* for BI and BO records if a name list is being specified for them here.
* The names.count field is ignored for BI and BO record types, but
* should be properly specified as 2 for future compatibility.
*
* NOTE:
* If a name string is filled in an an MBBI/MBBO record, it's corresponding
* value will be filled in as well. For this reason, there MUST be
* a value array and a valid nobt value for every MBBI/MBBO record that
* contains an item array!
*
******************************************************************************/
struct devGpibNames {
int count; /* CURRENTLY only used for MBBI and MBBO */
char **item;
unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */
short nobt; /* CURRENTLY only used for MBBI and MBBO */
};
/******************************************************************************
*
* Enumeration of gpib command types supported.
*
* Each transaction type is described below :
*
* GPIBREAD : (1) The cmd string is sent to the instrument
* (2) Data is read from the inst into a buffer (gpibDpvt.msg)
* (3) The important data is extracted from the buffer using the
* format string.
*
* GPIBWRITE: (1) An ascii string is generated using the format string and
* contents of the gpibDpvt->dbAddr->precord->val
* (2) The ascii string is sent to the instrument
*
* GPIBCMD : (1) The cmd string is sent to the instrument
*
* GPIBCNTL : (1) The control string is sent to the instrument (ATN active)
*
* GPIBSOFT : (1) No GPIB activity involved - normally retrieves internal data
*
* GPIBREADW : (1) The cmd string is sent to the instrument
* (2) Wait for SRQ
* (3) Data is read from the inst into a buffer (gpibDpvt.msg)
* (4) The important data is extracted from the buffer using the
* format string.
*
* GPIBRAWREAD: Used internally with GPIBREADW. Not useful from cmd table.
*
*
* The following is only supported on mbbo and bo record types.
*
* GPIBEFASTO: (1) Sends out the string pointed to by p3[VAL] w/o formating
*
* The following are only supported on mbbi and bi record types.
*
* GPIBEFASTI: (1) Send out the cmd string
* (2) Data is read from the inst into a buffer (gpibDpvt.msg)
* (3) Check the response against P3[0..?]
* (4) Set the value field to index when response = P3[index]
*
* GPIBEFASTIW: (1) Send out the cmd string
* (2) Wait for SRQ
* (3) Data is read from the inst into a buffer (gpibDpvt.msg)
* (4) Check the response against P3[0..?]
* (5) Set the value field to index when response = P3[index]
*
* If a particular GPIB message does not fit one of these formats, a custom
* routine may be provided. Store a pointer to this routine in the
* gpibCmd.convert field to use it rather than the above approaches.
*
******************************************************************************/
#define GPIBREAD 1
#define GPIBWRITE 2
#define GPIBCMD 3
#define GPIBCNTL 4
#define GPIBSOFT 5
#define GPIBREADW 6
#define GPIBRAWREAD 7
#define GPIBEFASTO 8
#define GPIBEFASTI 9
#define GPIBEFASTIW 10
struct gpibCmd {
gDset *rec_typ; /* used to indicate record type supported */
int type; /* enum - GPIBREAD, GPIBWRITE, GPIBCMND */
short pri; /* request priority--IB_Q_HIGH or IB_Q_LOW*/
char *cmd; /* CONSTANT STRING to send to instrument */
char *format; /* string used to generate or interpret msg*/
long rspLen; /* room for response error message*/
long msgLen; /* room for return data message length*/
int (*convert)(); /* custom routine for conversions */
int P1; /* user defined parameter used in convert() */
int P2; /* user defined parameter used in convert() */
char **P3; /* user defined parameter used in convert() */
struct devGpibNames *namelist; /* pointer to name strings */
int companion; /* companion command (used at init time) */
};
#define FILL {0,0,0,NULL,NULL,0,0,NULL,0,0,NULL,NULL,-1}
#define FILL10 FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL,FILL
/******************************************************************************
*
* debugFlag:
* Must point to a flag used to request debugging traces for the device
* while executing library code.
*
* respond2Writes:
* Set to TRUE if the device responds to write operations. This causes
* a read operation to follow each write operation. (See also wrConversion)
*
* timeWindow:
* Set to the number of system ticks that should be skipped after a timeout
* is detected on a device. All commands issued within this time window
* will be aborted and returned as errors.
*
* hwpvtHead:
* This is the root pointer for the per-hardware device private structure
* list. It should ALWAYS be initialized to NULL.
*
* gpibCmds:
* Pointer to the gpibCmds array.
*
* numparams:
* The number of parameters described in the gpibCmds array.
*
* magicSrq:
* Set to the parameter number that should be processed if an unsolicited
* SRQ is detected.
*
* name:
* Must point to a string containing the device name (used for
* debug messages.)
*
* srqHandler:
* Must point to the SRQ handler for the device support module if SRQs are
* supported or NULL if not.
*
* wrConversion:
* If not set to NULL and respond2Writes is true and a GPIBWRITE or GPIBCMD
* operation has completed it's read portion, this secondary conversion
* routine is called.
*
******************************************************************************/
typedef struct devGpibParmBlock {
int *debugFlag; /* pointer to debug flag */
int respond2Writes; /* set to true if a device responds to writes */
int timeWindow; /* clock ticks to skip after a timeout */
struct hwpvt *hwpvtHead; /* pointer to the hwpvt list for device type */
struct gpibCmd *gpibCmds; /* pointer to gpib command list */
int numparams; /* number of elements in the command list */
int magicSrq; /* magic parm to handle unsolicited SRQs */
char *name; /* pointer to a string containing device type */
int dmaTimeout; /* clock ticks to wait for DMA to complete */
int (*srqHandler)(); /* user SRQ handler or NULL if not supported */
int (*wrConversion)(); /* secondary conversion routine */
} devGpibParmBlockStruct;
#endif
@@ -0,0 +1,167 @@
/* devWfJoergerVtr1.c */
/* base/src/dev $Id$ */
/* devWfJoergerVtr1.c - Device Support Routines */
/*
* Original Author: Bob Dalesio
* Current Author: Marty Kraimer
* Date: 6-1-90
*
* 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 11-11-91 jba Moved set of alarm stat and sevr to macros
* .02 12-02-91 jba Added cmd control to io-interrupt processing
* .03 12-12-91 jba Set cmd to zero in io-interrupt processing
* .04 02-05-92 jba Changed function arguments from paddr to precord
* .05 02-28-92 jba Changed callback handling, ANSI C changes
* .06 03-13-92 jba ANSI C changes
* .07 04-10-92 jba pact now used to test for asyn processing, not return value
* .08 04-18-92 jba removed process from init_record parms
* .09 09-01-93 joh expects EPICS standard status
* ...
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <alarm.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <dbAccess.h>
#include <recSup.h>
#include <devSup.h>
#include <dbScan.h>
#include <link.h>
#include <module_types.h>
#include <waveformRecord.h>
#include <drvJgvtr1.h>
static long init_record();
static long read_wf();
static long arm_wf();
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_wf;
} devWfJoergerVtr1={
5,
NULL,
NULL,
init_record,
NULL,
read_wf};
static void myCallback(pwf,no_read,pdata)
struct waveformRecord *pwf;
int no_read;
unsigned short *pdata;
{
struct rset *prset=(struct rset *)(pwf->rset);
short ftvl = pwf->ftvl;
long i;
if(!pwf->busy) return;
dbScanLock((struct dbCommon *)pwf);
pwf->busy = FALSE;
if(no_read>pwf->nelm)no_read = pwf->nelm;
if(ftvl==DBF_CHAR || ftvl==DBF_UCHAR) {
unsigned char *pdest=(unsigned char *)pwf->bptr;
for(i=0; i<no_read; i++) {
*pdest++ = *pdata++;
}
pwf->nord = no_read; /* number of values read */
} else if(ftvl==DBF_SHORT || ftvl==DBF_USHORT) {
unsigned short *pdest=(unsigned short *)pwf->bptr;
for(i=0; i<no_read; i++) {
*pdest++ = *pdata++;
}
pwf->nord = no_read; /* number of values read */
} else {
recGblRecordError(S_db_badField,(void *)pwf,
"read_wf - illegal ftvl");
recGblSetSevr(pwf,READ_ALARM,INVALID_ALARM);
}
(*prset->process)(pwf);
dbScanUnlock((struct dbCommon *)pwf);
}
static long init_record(pwf)
struct waveformRecord *pwf;
{
/* wf.inp must be an VME_IO */
switch (pwf->inp.type) {
case (VME_IO) :
break;
default :
recGblRecordError(S_db_badField,(void *)pwf,
"devWfJoergerVtr1 (init_record) Illegal INP field");
return(S_db_badField);
}
return(0);
}
static long read_wf(pwf)
struct waveformRecord *pwf;
{
/* determine if wave form is to be rearmed*/
/* If not active then request rearm */
if(!pwf->pact) arm_wf(pwf);
/* if already active then call is from myCallback. check rarm*/
else if(pwf->rarm) {
(void)arm_wf(pwf);
}
return(0);
}
static long arm_wf(pwf)
struct waveformRecord *pwf;
{
long status;
struct vmeio *pvmeio = (struct vmeio *)&(pwf->inp.value);
pwf->busy = TRUE;
status = jgvtr1_driver(pvmeio->card,myCallback,pwf);
if(status!=0){
errMessage(status, NULL);
recGblSetSevr(pwf,READ_ALARM,INVALID_ALARM);
pwf->busy = FALSE;
return(0);
}
pwf->pact=TRUE;
return(0);
}