remove all dev/drv support

This commit is contained in:
Marty Kraimer
2001-07-31 19:49:19 +00:00
parent b85bdd318b
commit 452d4df4fb
48 changed files with 0 additions and 21801 deletions

View File

@@ -1,5 +0,0 @@
TOP=../../..
include $(TOP)/configure/CONFIG
DIRS = $(wildcard *Dev)
include $(TOP)/configure/RULES_DIRS

View File

@@ -1,14 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
INC += devApsEr.h
SRCS += devApsEg.c
SRCS += devApsEr.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,12 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
SRCS += devAt5Vxi.c
SRCS += devAt8Fp.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

View File

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

View File

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

View File

@@ -1,11 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
SRCS += devSmCompumotor1830.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

View File

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

View File

@@ -1,13 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
INC += devCommonGpib.h
SRCS += devCommonGpib.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,11 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
SRCS += devWfJoergerVtr1.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

View File

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

View File

@@ -1,21 +0,0 @@
TOP=../../..
include $(TOP)/configure/CONFIG
SRCS += devAnalytekGpib.c
SRCS+= devXxDg535Gpib.c
SRCS+= devGpibInteract.c
SRCS+= devXxSr620Gpib.c
SRCS+= devK486Gpib.c
SRCS+= devXxK196Gpib.c
SRCS+= devXxDc5009Gpib.c
SRCS+= devXxK263Gpib.c
SRCS+= devXxSkeletonGpib.c
OBJS_vxWorks += $(SRCS:%.c=%)
OBJLIB_vxWorks += devLibOpt
OBJLIB_SRCS = $(SRCS)
include $(TOP)/configure/RULES

View File

@@ -1,804 +0,0 @@
#define DSET_AI devAiAnalytekGpib
#define DSET_AO devAoAnalytekGpib
#define DSET_LI devLiAnalytekGpib
#define DSET_LO devLoAnalytekGpib
#define DSET_BI devBiAnalytekGpib
#define DSET_BO devBoAnalytekGpib
#define DSET_MBBO devMbboAnalytekGpib
#define DSET_MBBI devMbbiAnalytekGpib
#define DSET_SI devSiAnalytekGpib
#define DSET_SO devSoAnalytekGpib
#define DSET_WF devWfAnalytekGpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <waveformRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
#define STATIC static
long devGpibLib_initWf();
long devGpibLib_readWf();
int devGpibLib_wfGpibWork();
STATIC long init_dev_sup(), report();
STATIC struct devGpibParmBlock devSupParms;
STATIC int getamprange(); /* used to get signal amplitude range */
STATIC int getrange(); /* used to get signal range */
STATIC int getoffset(); /* used to get signal offset */
STATIC int convertWave(); /* parses waveform data from analytek digitizer */
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork,
(DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
gDset DSET_WF = {5, {NULL, NULL, devGpibLib_initWf, NULL,
devGpibLib_readWf, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_wfGpibWork, NULL}};
int AnalytekDebug = 0; /* debugging flags */
extern int ibSrqDebug;
static char *onoffList[] = { "Off","On" };
static unsigned long onoffVal[] = { 0,1 };
static struct devGpibNames onoff = { 2, onoffList, onoffVal, 4 };
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 6000 /* 1 second on a watchdog time */
static struct gpibCmd gpibCmds[] =
{
/* Param 0, (model) */
FILL,
/* Function Commands */
/* Param 1, Clear status command */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*CLS\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 2, Return Power-on-Status Clear state */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "*PSC?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 3, Set Power-on-Status Clear state */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*PSC %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 4, Recall device state */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*RCL %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 5, Reset */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "*RST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 6, Save device state */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*SAV %u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 7, Perform self-test */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "*TST?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 8, Signal info, at end of parameter list */
FILL,
/* Param 9, Request base average sample count */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "BASAVG?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 10, Set base average sample count */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BASAVG %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 11, Request state of base correction switch */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "BASCOR?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 12, Set state of base correction switch */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "BASCOR %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 13 Request current channel on board 1 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "BDSEL?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 14, Set current channel on board 1 */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "*BDSEL 1,%u\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 15, Request sampling board types */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "BRDTYPE?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 16, Request state of calibration trigger */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "CALTRIG?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 17, Set state of calibration trigger, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 18, Request frequency of base clock in Mhz */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "CLKFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 19, Set frequency of base clock in Mhz */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "CLKFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 20, Return state of display*/
{&DSET_BI, GPIBREAD, IB_Q_LOW, "DISPlay?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 21, Set state of display */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "DISPlay %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 22, Return state of local switch*/
{&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCAL?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 23, Set local switch on/off */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCAL %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 24, Return state of lockout switch */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "LOCKOUT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 25, Set lockout switch on/off */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LOCKOUT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 26, Request state of low pass filter */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "LPFILT?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 27, Set low pass filter */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFILT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 28, Request length of FIR for low pass filter */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFIR?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 29, Set FIR for low pass filter */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFIR %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 30, Request frequency of low pass filter */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "LPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 31, Set frequency of low pass filter */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "LPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 32, Request filter mode, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "LPMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 33, Set filter mode, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 34, Select single or multiple events */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "MEVENT %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 35, Request number of samples stored in cache memory */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "MIREP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 36, Set number of samples stored 8in cache memory */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "MIREP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 37, Restart program, similar to external reset button */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "PGMRST\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 38, Request instrument to acquire a data sample */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SAMPLE\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 39, Request state of signal averaging switch */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "SIGAVG?", "%u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 40, Set state of signal averaging switch */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGAVG %u\n", 0, 32, NULL, 0, 0, NULL, &onoff, -1},
/* Param 41, Request current average count */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGCNT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 42, Request count of cycles to average before display modulo */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGDSP?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 43, Set count of cycles to average before display modulo */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGDSP %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 44, Request maximum count of cycles to be averaged */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "SIGLMT?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 45, Set maximum count of cycles to be averaged */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SIGLMT %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 46, Signal info, */
FILL,
/* Param 47, Request sampling frequency */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "SMPFREQ?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 48, Set sampling frequency */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "SMPFREQ %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 49, Request sample offset for a channel, */
FILL,
/* Param 50, Set sample offset for a channel, */
FILL,
/* Param 51, Request sample size, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "SMPSIZE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 52, Set sample size, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 53, Halt current sampling operation */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "STOP\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 54, Returns trigger coupling, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGCOUPLE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 55, Set trigger coupling, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 56, Request trigger delay */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGDELAY?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 57, Set trigger delay */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGDELAY %4.0f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 58, Requests trigger mode, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGMODE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 59, Set trigger mode, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 60, Request trigger offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "TRGOFF?", "%lf\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 61, Set trigger offset */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TRGOFF %f\n", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 62, Request trigger slope setting, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGSLOPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 63, Set trigger slope, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Param 64, Request trigger type, */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "TRGTYPE?", "%s", 0, 32, NULL, 0, 0, NULL, NULL, -1},
/* Param 65, Set trigger type, */
{&DSET_SO, GPIBWRITE, IB_Q_HIGH, NULL, "%s", 0, 64, NULL, 0, 0, NULL, NULL, -1},
/* Channel 1 */
/* Param 66, Request amplitude range for signal on board 1 channel 1 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 67, Request range for signal on board 1 channel 1 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 68, Request offset for signal on board 1 channel 1 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,1", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 69, on board 1 channel 1 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,1", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 2 */
/* Param 70, Request amplitude range for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 71, Request range for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 72, Request offset for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,2", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 73, on board 1 channel 2 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,2", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 3 */
/* Param 74, Request amplitude range for signal on board 1 channel 3 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 67, Request range for signal on board 1 channel 3 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 68, Request offset for signal on board 1 channel 3 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,3", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 71, on board 1 channel 3 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,3", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 4 */
/* Param 72, Request amplitude range for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 73, Request range for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 74, Request offset for signal on board 1 channel 2 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,4", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 75, on board 1 channel 4 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,4", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 5 */
/* Param 76, Request amplitude range for signal on board 1 channel 5 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 77, Request range for signal on board 1 channel 5 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 78, Request offset for signal on board 1 channel 5 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,5", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 79, on board 1 channel 5 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,5", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 6 */
/* Param 80, Request amplitude range for signal on board 1 channel 6 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 81, Request range for signal on board 1 channel 6 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 82, Request offset for signal on board 1 channel 6 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,6", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 83, on board 1 channel 6 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,6", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 7 */
/* Param 84, Request amplitude range for signal on board 1 channel 7 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 85, Request range for signal on board 1 channel 7 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 86, Request offset for signal on board 1 channel 7 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,7", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 87, on board 1 channel 7 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,7", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 8 */
/* Param 88, Request amplitude range for signal on board 1 channel 8 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 89, Request range for signal on board 1 channel 8 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 90, Request offset for signal on board 1 channel 8 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,8", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 91, on board 1 channel 8 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,8", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 9 */
/* Param 92, Request amplitude range for signal on board 1 channel 9 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 93, Request range for signal on board 1 channel 9 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 94, Request offset for signal on board 1 channel 9 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,9", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 95, on board 1 channel 9 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,9", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 10 */
/* Param 96, Request amplitude range for signal on board 1 channel 10 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 97, Request range for signal on board 1 channel 10 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 98, Request offset for signal on board 1 channel 10 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,10", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 99, on board 1 channel 10 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,10", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 11 */
/* Param 100, Request amplitude range for signal on board 1 channel 11 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 101, Request range for signal on board 1 channel 11 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 102, Request offset for signal on board 1 channel 11 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,11", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 103, on board 1 channel 11 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,11", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 12 */
/* Param 104, Request amplitude range for signal on board 1 channel 12 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 105, Request range for signal on board 1 channel 12 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 106, Request offset for signal on board 1 channel 12 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,12", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 107, on board 1 channel 12 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,12", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 13 */
/* Param 108, Request amplitude range for signal on board 1 channel 13 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 109, Request range for signal on board 1 channel 13 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 110, Request offset for signal on board 1 channel 13 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,13", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 111, on board 1 channel 13 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,13", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 14 */
/* Param 112, Request amplitude range for signal on board 1 channel 14 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 113, Request range for signal on board 1 channel 14 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 114, Request offset for signal on board 1 channel 14 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,14", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 115, on board 1 channel 14 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,14", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
/* Channel 15 */
/* Param 116, Request amplitude range for signal on board 1 channel 15 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 117, Request range for signal on board 1 channel 15 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 118, Request offset for signal on board 1 channel 15 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,15", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 119, on board 1 channel 15 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,15", "%u", 0, 1100, convertWave , 0, 0, NULL, NULL, -1},
/* Channel 16 */
/* Param 120, Request amplitude range for signal on board 1 channel 16 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getamprange, 0, 0, NULL, NULL, -1},
/* Param 121, Request range for signal on board 1 channel 16 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getrange, 0, 0, NULL, NULL, -1},
/* Param 122, Request offset for signal on board 1 channel 16 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "AINFO? 1,16", NULL, 0, 32, getoffset, 0, 0, NULL, NULL, -1},
/* Param 123, on board 1 channel 16 */
{&DSET_WF, GPIBREAD, IB_Q_LOW, "READ? SEQ, 1,16", "%u", 0, 1100, convertWave, 0, 0, NULL, NULL, -1},
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
STATIC long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &AnalytekDebug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxAnalytekGpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
};
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
STATIC long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}
STATIC int getamprange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
int amprange;
int i;
int status;
struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord);
if(AnalytekDebug)
printf("getamprange AINFO? returned msg:%s\n",pdpvt->msg);
/* Change all commas in returned string to blank spaces to seperate fields */
i=0;
while(pdpvt->msg[i] != '\0')
{
if (pdpvt->msg[i] == ',')
pdpvt->msg[i] = 0x20; /* blank space */
i++;
}
if(AnalytekDebug)
printf("getamprange AINFO? new msg:%s\n",pdpvt->msg);
/* Scan response string for signal amplitude range */
status = sscanf(pdpvt->msg, "%*c%d", &amprange); /* This sscanf command is command specific */
/* In this case the leading quote is skipped */
/* and the next number is assigned to amprange */
/* and the rest of the string is skipped */
if(AnalytekDebug)
printf("getamprange AINFO? :sscan status = %d\n",status);
printf("amprange = %d\n",amprange);
/* if value was assigned, put value in data base */
if (status == 1) /* make sure message was received ok */
{ /* sscanf returns an integer which tells */
pai->val = amprange; /* how many assignments were made */
}
else
{
if (pai->nsev < INVALID_ALARM)
{
pai->nsev = INVALID_ALARM;
pai->nsta = READ_ALARM;
}
}
return(OK);
}
/* conversion routine */
STATIC int getrange(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
int range;
int i;
int status;
struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord);
if(AnalytekDebug)
printf("getrange AINFO? returned msg:%s\n",pdpvt->msg);
/* Change all commas in returned string to blank spaces to seperate fields */
i=0;
while(pdpvt->msg[i] != '\0')
{
if (pdpvt->msg[i] == ',')
pdpvt->msg[i] = 0x20;
i++;
}
if(AnalytekDebug)
printf("getrange AINFO? new msg:%s\n",pdpvt->msg);
/* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */
status = sscanf(pdpvt->msg, "%*c%*d%d", &range);
if(AnalytekDebug)
printf("getrange AINFO? :sscan status = %d\n",status);
if (status == 1) /* make sure message was received ok */
{
/*assign new value */
pai->val = range;
}
else
{
if (pai->nsev < INVALID_ALARM)
{
pai->nsev = INVALID_ALARM;
pai->nsta = READ_ALARM;
}
}
return(OK);
}
/* conversion routine */
STATIC int getoffset(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
float offset;
int i;
int status;
struct aiRecord *pai= (struct aiRecord *) (pdpvt->precord);
if(AnalytekDebug)
printf("getoffset AINFO? returned msg:%s\n",pdpvt->msg);
/* Change all commas in returned string to blank spaces to seperate fields */
i=0;
while(pdpvt->msg[i] != '\0')
{
if (pdpvt->msg[i] == ',')
pdpvt->msg[i] = 0x20;
i++;
}
if(AnalytekDebug)
printf("getoffset AINFO? new msg:%s\n",pdpvt->msg);
/* Scan response string for signal amplitude range (paiar), range (pair), and offset (paio) */
status = sscanf(pdpvt->msg, "%*c%*d%*d%f", &offset);
if(AnalytekDebug)
printf("getoffset AINFO? :sscan status = %d\n",status);
if (status == 1) /* make sure message was received ok */
{
/*assign new value */
pai->val = offset;
}
else
{
if (pai->nsev < INVALID_ALARM)
{
pai->nsev = INVALID_ALARM;
pai->nsta = READ_ALARM;
}
}
return(OK);
}
STATIC int convertWave(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
struct waveformRecord *pwf = (struct waveformRecord *) (pdpvt->precord);
short *raw;
char *craw;
short *clean;
unsigned long numElem;
char asciiLen[10];
int ix;
#define ANALTEK_BIAS 2048
if (AnalytekDebug)
printf("Analytek waveform conversion routine entered\n");
clean = (short *) pwf->bptr;
craw = pdpvt->msg;
if (*craw != '#')
{ /* don't have a valid analytek waveform */
devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM);
printf("Got an invalid waveform back!\n");
return(ERROR);
}
while (*craw == '#')
craw++;
ix = *craw - '0';
craw ++;
raw = (short *) (craw + ix);
asciiLen[ix] = '\0';
while(ix--)
asciiLen[ix] = craw[ix];
if (sscanf (asciiLen, "%d", &numElem) != 1)
{
devGpibLib_setPvSevr(pwf,READ_ALARM,INVALID_ALARM);
printf("Got an invalid waveform back!!\n");
return(ERROR);
}
numElem = numElem/2; /* 2 bytes per sample */
/* Fill in the pwf->nord field with number of elements read from analytek */
if (numElem > pwf->nelm)
numElem = pwf->nelm;
pwf->nord = numElem;
/* convert the raw data in pdpvt->msg to a usable data-stream in pwf->bptr */
while (numElem)
{
*clean = (short) (*raw - ANALTEK_BIAS);
clean++;
raw++;
numElem--;
}
return(OK);
}

View File

@@ -1,775 +0,0 @@
/* devGpibInteract.c */
/* share/src/devOpt/ $Id$ */
/*
* Author: John Winans
* Origional Author: Ned D. Arnold
* Date: 9/23/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 06-19-91 nda initial coding & debugging
* .02 09-23-91 jrw added proper multi-link support
*
*/
/* gpibInteract.c - allows interactive GPIB message transmissions */
/*
* gpibInteract allows the user to interactively set up gpib messages,
* submit them to the gpibOwn Queue, and display the result. Five
* gpib messages can be defined at a time.
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <rngLib.h>
#include <semLib.h>
#include <tickLib.h>
#include <taskLib.h>
#include <limits.h>
#include <string.h>
#include <math.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <drvGpibInterface.h>
#define GPIBREAD 1
#define GPIBWRITE 2
#define GPIBCMD 3
#define MAX_MSG_LENGTH 80
int GITime = 60; /* shell-setable DMA timeout value */
extern struct drvGpibSet drvGpib; /* entry points to driver functions */
static int gpibWork();
struct gpibIntCmd {
struct dpvtGpibHead head;
char type; /* R, W, C for read, write, command */
char cmd[MAX_MSG_LENGTH]; /* string to send to instrument */
char resp[MAX_MSG_LENGTH+32];/* place for response if a GPIB read */
long count; /* used for counting */
char busy; /* used by timing routine */
int linkId; /* link number */
int linkType; /* GPIB_IO or BBGPIB_IO */
int bug; /* bug# if BBGPIB_IO linkType */
};
#define LIST_SIZE 10
static struct gpibIntCmd gpibIntCmds[LIST_SIZE];
/* declare other required variables used by more than one routine */
BOOL replyIsBack; /* reset by sender, set by replyReceived() */
extern int ibDebug;
int GIDebug = 0;
static int sendMsg();
static int gpibWork();
static int configMsg();
static int getInt();
static int getChar();
static int getString();
static int showGpibMsg();
static int timingStudy();
static void hexDump(unsigned char *string, int indent);
static int firstTime = 1;
static int hexmode = 1;
static SEM_ID msgReply;
int GI(void)
{
unsigned char ans;
int cnt;
if(firstTime)
{
firstTime = 0;
msgReply = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
for (cnt=0; cnt < LIST_SIZE; cnt++)
{ /* init the elements of the command table */
#if 0
gpibIntCmds[cnt].head.header.list.list1 = NULL;
gpibIntCmds[cnt].head.header.list.list2 = NULL;
#endif
gpibIntCmds[cnt].head.workStart = gpibWork;
gpibIntCmds[cnt].head.link = 0;
gpibIntCmds[cnt].head.device = 0;
gpibIntCmds[cnt].head.bitBusDpvt= NULL;
gpibIntCmds[cnt].type = 'R';
gpibIntCmds[cnt].cmd[0] = '\0';
gpibIntCmds[cnt].resp[0] = '\0';
gpibIntCmds[cnt].count = 0;
gpibIntCmds[cnt].busy = 0;
}
}
ans = 0; /* set loop not to exit */
logMsg("\n\n");
while ((ans != 'q') && (ans != 'Q'))
{
printf("\n\nInteractive GPIB Program\n");
printf("Select a function:\n"); /* main menu */
printf(" 'C' to configure send message content\n");
printf(" 'D' to display transmit & receive messages\n");
printf(" 'H' enable hex dump listings of message responses\n");
printf(" 'h' disable hex dump listings of message responses\n");
printf(" 'S' to send & receive a message one time\n");
printf(" 'T' to do timing on messages\n");
printf(" 'R' to turn on the GPIB debugging flag\n");
printf(" 'r' to turn off the GPIB debugging flag\n");
printf(" 'Q' to quit program\n");
printf(">");
ans = 0; /* clear previous selection */
getChar(&ans);
switch (ans) {
case 'c': /* configure message contents */
case 'C':
configMsg();
break;
case 'h': /* disable hex dumping */
hexmode = 0;
break;
case 'H': /* enable hex dumping */
hexmode = 1;
break;
case 's':
case 'S': /* one shot: send one message */
sendMsg();
break;
case 't':
case 'T': /* Timing analysis */
timingStudy();
break;
case 'd':
case 'D': /* Display message contents */
for (cnt = 1; cnt < LIST_SIZE; cnt++) /* for each message */
showGpibMsg(cnt);
printf("\nHit CR to return to Main Menu ...");
getChar(&ans); /* dummy input */
break;
case 'q':
case 'Q': /* quit */
break;
case 'r': /* turn off ibDebug */
ibDebug = 0;
break;
case 'R': /* turn on ibDebug */
ibDebug = 1;
break;
} /* end case */
} /* end of while ans== q or Q */
return(0);
} /* end of main */
static int timingStudy(void)
{
struct gpibIntCmd *pCmd[LIST_SIZE];
int inInt; /* input integer from operator */
int reps; /* number of times to send a message */
ULONG startTime;
ULONG endTime;
ULONG delta;
int Reps;
int i;
int j;
for (i=0; i<LIST_SIZE; i++)
{
printf("\nEnter Message# to Send (1 thru 5, <cr> to terminate list) > ");
if (getInt(&inInt))
{
if (inInt>0 && inInt<LIST_SIZE)
{
pCmd[i] = &gpibIntCmds[inInt]; /* assign pointer to desired entry */
pCmd[i]->busy = 0; /* mark message 'not in queue' */
pCmd[i]->count = 0;
#ifdef USE_162_STUFF
if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE)
{
#endif
(*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGENLINK, 0, NULL);
(*(drvGpib.ioctl))(pCmd[i]->linkType, pCmd[i]->linkId, pCmd[i]->bug, IBGETLINK, 0, &(pCmd[i]->head.pibLink));
#ifdef USE_162_STUFF
}
else
{
drv162IB_InitLink(pCmd[i]->linkId);
drv162IB_GetLink(pCmd[i]->linkId, &(pCmd[i]->head.pibLink));
}
#endif
}
else
{
pCmd[i] = NULL; /* terminate the list */
i = LIST_SIZE;
}
}
else
{
pCmd[i] = NULL; /* terminate the list */
i = LIST_SIZE;
}
}
printf("Enter the number of messages to send > ");
if (!getInt(&inInt))
return(0); /* if no entry, return to main menu */
if(inInt < 0)
return(0);
reps = inInt;
Reps = reps;
startTime = tickGet(); /* time the looping started */
while(reps)
{
for(i=0; i<LIST_SIZE && reps; i++)
{
if (pCmd[i] != NULL)
{
if (!(pCmd[i]->busy))
{
pCmd[i]->count++;
pCmd[i]->busy = 1; /* mark the xact as busy */
#ifdef USE_162_STUFF
if (pCmd[i]->linkId < MVME162_LINK_NUM_BASE)
#endif
(*(drvGpib.qGpibReq))(pCmd[i], IB_Q_LOW);
#ifdef USE_162_STUFF
else
drv162IB_QueueReq(pCmd[i], IB_Q_LOW);
#endif
reps--;
if (reps%10000 == 0)
{
printf("Timing study in progress with %d messages left, current status:\n", reps);
for (j=0; j<LIST_SIZE; j++)
{
if(pCmd[j] != NULL)
{
printf("Message %d transmissions: %ld\n", j, pCmd[j]->count);
}
else
j = LIST_SIZE;
}
}
}
}
else
i = LIST_SIZE; /* force an exit from the loop */
}
semTake(msgReply, WAIT_FOREVER);
}
endTime = tickGet();
delta = (endTime - startTime); /* measured time in ticks */
if (delta == 0)
delta = 1;
printf("Total transmit and receiving time = %ld/60 Sec\n", delta);
printf("Messages/second = %.2f\n", (float) (60*Reps)/(float)delta);
for (i=0; i<LIST_SIZE; i++)
{
if(pCmd[i] != NULL)
{
printf("Message %d transmissions: %ld\n", i, pCmd[i]->count);
}
else
i = LIST_SIZE;
}
return(0);
}
/* sendMsg() ***************************************************
*/
static int sendMsg(void)
{
struct gpibIntCmd *pCmd;
int inInt; /* input integer from operator */
int msgNum; /* index to array of messages */
int ticks; /* # of ticks since message was sent */
int maxTicks = 480; /* # of ticks to wait for reply (8 seconds) */
printf("\nEnter Message # to Send (1 thru 5) > ");
if (!getInt(&inInt))
return(-1); /* if no entry, return to main menu */
if((inInt >= LIST_SIZE) || (inInt < 0))
return(-1);
msgNum = inInt;
pCmd = &gpibIntCmds[msgNum]; /* assign pointer to desired entry */
replyIsBack = FALSE;
ticks = 0;
#ifdef USE_162_STUFF
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
{
#endif
(*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGENLINK, 0, NULL);
(*(drvGpib.ioctl))(pCmd->linkType, pCmd->linkId, pCmd->bug, IBGETLINK, 0, &(pCmd->head.pibLink));
(*(drvGpib.qGpibReq))(pCmd, IB_Q_LOW); /* queue the msg */
#ifdef USE_162_STUFF
}
else
{
drv162IB_InitLink(pCmd->linkId);
drv162IB_GetLink(pCmd->linkId, &(pCmd->head.pibLink));
drv162IB_QueueReq(pCmd, IB_Q_LOW);
}
#endif
while (!replyIsBack && (ticks < maxTicks)) /* wait for reply msg */
{
taskDelay(1);
ticks++;
}
if (replyIsBack)
{
if (ibDebug)
taskDelay(60); /* Allow debug printing to complete */
showGpibMsg(msgNum);
}
else
printf("No Reply Received ...\n");
return(0);
}
static int gpibWork(struct gpibIntCmd *pCmd)
{
int status;
if (GIDebug || ibDebug)
logMsg("GI's gpibWork() was called for command >%s<\n", pCmd->cmd);
switch (pCmd->type) {
case 'w':
case 'W': /* write the message to the GPIB listen adrs */
#ifdef USE_162_STUFF
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
#endif
status =(*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
#ifdef USE_162_STUFF
else
status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
#endif
if (status == ERROR)
strcpy(pCmd->resp, "GPIB TIMEOUT (while talking)");
else
pCmd->resp[0] = '\0';
break;
case 'r':
case 'R': /* write the command string */
#ifdef USE_162_STUFF
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
#endif
status = (*(drvGpib.writeIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
#ifdef USE_162_STUFF
else
status = drv162IB_write(pCmd->head.pibLink, pCmd->head.device, pCmd->cmd, strlen(pCmd->cmd), GITime);
#endif
if (status == ERROR)
{
strcpy(pCmd->resp, "GPIB TIMEOUT (while talking)");
break;
}
/* fall thru into the reading protion below */
case 'I':
case 'i':
/* read the instrument */
pCmd->resp[0] = 0; /* clear response string */
#ifdef USE_162_STUFF
if (pCmd->linkId < MVME162_LINK_NUM_BASE)
#endif
status = (*(drvGpib.readIb))(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime);
#ifdef USE_162_STUFF
else
status = drv162IB_read(pCmd->head.pibLink, pCmd->head.device, pCmd->resp, MAX_MSG_LENGTH, GITime);
#endif
if (status == ERROR)
{
strcat(pCmd->resp, "GPIB ERROR (while listening)");
break;
}
else if (status > (MAX_MSG_LENGTH - 1)) /* check length of resp */
{
logMsg("GPIB Response length equaled allocated space !!!\n");
pCmd->resp[(MAX_MSG_LENGTH)] = '\0'; /* place \0 at end */
}
else
{
pCmd->resp[status] = '\0'; /* terminate response with \0 */
}
break;
}
pCmd->busy = 0;
replyIsBack = TRUE;
semGive(msgReply);
return(IDLE);
}
/*--------------------------------------------------------------------
* configMsg()
*
* - Purpose
* Prompts the operator for the contents of a GPIB message
* Displays current value of the field as the default entry
*
*/
static int
configMsg()
{
struct gpibIntCmd *pCmd;
int msgNum; /* index to array of messages */
int inInt; /* input integer from operator */
unsigned char inChar; /* input char from operator */
char inString[MAX_MSG_LENGTH]; /* input string from operator */
printf("\nEnter Message # to Configure (1 thru 5) > ");
if (!getInt(&inInt))
return(0); /* if no entry, return to main menu */
if((inInt >= LIST_SIZE) || (inInt < 0))
return(0);
msgNum = inInt;
pCmd = &gpibIntCmds[msgNum]; /* assign pointer to desired entry */
printf("\n\n Configuring Send Message # %1.1d .... \n", msgNum);
/* Prompt the Operator with the current value of each parameter If
* only a <CR> is typed, keep current value, else replace value with
* entered value
*/
printf("Enter the Link Type (5 = GPIB, 13 = BBGPIB) [%d]: ", pCmd->linkType);
if (getInt(&inInt) == 1)
{
if(inInt == 5)
pCmd->linkType = GPIB_IO;
else if (inInt == 13)
pCmd->linkType = BBGPIB_IO;
else
{
printf("Invalid link Type %d specified\n", pCmd->linkType);
return(ERROR);
}
}
printf("\nenter Enter Link # [%2.2d] > ", (int) pCmd->linkId);
if (getInt(&inInt) == 1)
pCmd->linkId = inInt;
if (pCmd->linkType == BBGPIB_IO)
{
printf("Enter the bug number [%d]: ", pCmd->bug);
if (getInt(&inInt) == 1)
pCmd->bug = inInt;
}
printf("\nenter GPIB Node # [%2.2d] > ", pCmd->head.device);
if (getInt(&inInt) == 1)
{
pCmd->head.device = inInt;
}
printf("\nenter command type R, W, C, I [%c] > ", pCmd->type);
if (getChar(&inChar) == 1)
pCmd->type = inChar;
if ((pCmd->type != 'I') && (pCmd->type != 'i'))
{
if (hexmode)
{
printf("\nEnter string to send (no quotes)\n");
hexDump(pCmd->cmd, 0);
}
else
printf("\nenter string to send (no quotes) [%.80s] > ", pCmd->cmd);
if (getString(inString) == 1)
strcpy(pCmd->cmd, inString);
}
else
pCmd->cmd[0] = 0;
pCmd->resp[0]= 0; /* clear response string */
showGpibMsg(msgNum);
return(ERROR);
}
/*
* getInt(pInt) ****************************************************
*
* gets a line of input from STDIN (10 characters MAX !!!!) scans the line
* for an integer.
*
* Parm1 : pointer to an integer
*
* Returns (0) if a <CR> was hit, *pInt left unchanged. Returns (1) if a new
* value was written to *pvalue. Returns (2) if a entry was not a valid
* integer entry
*
*/
static int
getInt(pInt)
int *pInt;
{
char input[10];
int inval;
gets(input);
if (input[0] == 0) /* if only a <CR> */
return (0);
else
{
if (sscanf(input, "%d", &inval) == 1)
{ /* if a valid entry ... */
*pInt = inval;
return (1);
}
else /* if not a valid entry, return 2 */
return (2);
}
}
/*
* int getChar(pChar) **************************************************
*
* gets a line of input from STDIN (10 characters MAX !!!!) scans the line
* for a character entry
*
* Parm1 : pointer to an unsigned character variable
*
* Returns(0) if a <CR> was hit, *pChar left unchanged. Returns(1) if a new
* value was written to *pChar
*
*/
static int
getChar(pChar)
unsigned char *pChar;
{
char input[10];
unsigned char inval;
gets(input);
if (input[0] == 0)
return (0);
else
{
sscanf(input, "%c", &inval);
*pChar = inval;
return (1);
}
}
/*
* int getString(pString) ****************************************************
*
* gets a line of input from STDIN (100 characters MAX !!!!) .
* If length is greater than 0, copies string into pString
*
* Parm1 : pointer to an character string
*
* Returns : 0 if a <CR> was hit, *pvalue left unchanged Returns : 1 if a
* new value was written to *pvalue
*
*/
static int
getString(pString)
char *pString;
{
char input[100];
char *in;
gets(input);
if (input[0] == 0)
return (0);
else
{
in = input;
while(*in != '\0')
{
switch (*in) {
case '\\': /* meta-character parser */
++in;
switch (*in) {
case 'n': /* \n = linefeed */
case 'l': /* \l = lenefeed too */
*pString = '\n';
break;
case 'r': /* \r = cariage return */
*pString = '\r';
break;
case 't': /* \t = tab character */
*pString = '\t';
break;
default: /* anything else is just the character after the \ */
*pString = *in;
}
break;
default:
*pString = *in;
}
++in;
++pString;
}
*pString = '\0';
return (1);
}
}
/* utility fuinction to print a hex dump */
static void hexDump(unsigned char *string, int indent)
{
char ascBuf[17]; /* for the ascii xlation part of the dump */
int strLength;
unsigned int j, x;
if (!(strLength = strlen(string)))
{
printf("(null)\n");
return;
}
j = 0;
while (j < strLength)
{
if (j)
{
x = indent;
while(x--)
printf(" ");
}
printf("%2.2X: ", j); /* print relative address */
x = 0;
while ((x < 16) && (j < strLength))
{
printf("%2.2X ", string[j]);
ascBuf[x] = string[j];
if (!((ascBuf[x] >= 0x20) && (ascBuf[x] <= 0x7e)))
ascBuf[x] = '.';
++x;
++j;
}
ascBuf[x] = '\0';
while (x++ <= 16)
printf(" ");
printf(" *%s*\n", ascBuf);
}
return;
}
/*
* showGpibMsg(msgNum) ***********************************************
*
*
* Print the gpib message contents onto the screen.
* msgNum selects the message to be displayed
*
*/
static int
showGpibMsg(msgNum)
int msgNum;
{
struct gpibIntCmd *pCmd = &gpibIntCmds[msgNum];
printf("\nMessage #%1.1d : ", msgNum);
printf("LinkType=%d bug=%d Link=%d Adrs=%d Type=%c\n",
pCmd->linkType, pCmd->bug, pCmd->linkId, pCmd->head.device, pCmd->type);
if (hexmode)
{
printf("Cmd: ");
hexDump(pCmd->cmd, 5);
printf("Res: ");
hexDump(pCmd->resp, 5);
}
else
{
printf(" Command String : %.40s\n", pCmd->cmd);
printf(" Response String : %.40s\n", pCmd->resp);
}
return(0);
}

View File

@@ -1,310 +0,0 @@
/* devK486Gpib.c */
/* @(#)devK486Gpib.c 1.2 3/18/92 */
/*
* Author: Bill Brown
* Date: 03-18-93
*
* 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
*
* The Control Systems Group
* Systems Engineering Department
* Lawrence Berkeley 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 03-18-93 wlb Initial Release
*/
#define DSET_AI devAiK486Gpib
#define DSET_AO devAoK486Gpib
#define DSET_LI devLiK486Gpib
#define DSET_LO devLoK486Gpib
#define DSET_BI devBiK486Gpib
#define DSET_BO devBoK486Gpib
#define DSET_MBBO devMbboK486Gpib
#define DSET_MBBI devMbbiK486Gpib
#define DSET_SI devSiK486Gpib
#define DSET_SO devSoK486Gpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
static long init_dev_sup(), report();
static struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
int K486Debug = 0; /* debugging flags */
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*/
#define TIME_WINDOW 300 /* 10 seconds on a getTick call */
#define DMA_TIME 60 /* 1/2 second on a watchdog time */
/*
* Strings used by the init routines to fill in the znam, onam, ...
* fields in BI, BO, MBBI, and MBBO record types.
*/
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *singleShotList[] = { "SINGLE", "SHOT" };
static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
static char *tABCDList[] = { "T", "A", "B", "C", "D" };
static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 };
static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 };
static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" };
static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 };
static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList,
ttlNimEclVarVal, 2 };
static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL",
"SINGLE SHOT", "BURST MODE", "STOP" };
static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 };
static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList,
intExtSsBmStopVal, 2 };
static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList,
intExtSsBmStopVal, 3 };
/******************************************************************************
*
* String arrays for EFAST operations. Note that the last entry must be
* NULL.
*
* On input operations, only as many bytes as are found in the string array
* elements are compared. If there are more bytes than that in the input
* message, they are ignored. The first matching string found (starting
* from the 0'th element) will be used as a match.
*
* NOTE: For the input operations, the strings are compared literally! This
* can cause problems if the instrument is returning things like \r and \n
* characters. You must take care when defining input strings so you include
* them as well.
*
******************************************************************************/
static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL};
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
/* forward declarations of some custom convert routines */
int setDelay();
int rdDelay();
static struct gpibCmd gpibCmds[] =
{
/* Param 0, (model) */
FILL,
/* Param 1 initialization string */
{
&DSET_BO, GPIBCMD, IB_Q_HIGH, "L0 X B0 G1 R0 S1 C2 X C0 T5 X",
NULL, 0, 32, NULL, 0, 0, NULL, NULL, -1
},
/* Param 2 read current value */
{
&DSET_AI, /* <f1> record type {analog in} */
GPIBREAD, /* <f2> GPIB I/O operation type {read} */
IB_Q_HIGH, /* <f3> processing priority */
"X", /* <f4> command sent to device */
"%*4c%lf", /* <f5> string descriptor for sscanf() */
0, /* <f6> buffer pointer */
32, /* <f7> buffer length */
NULL, /* <f8> special I/O operation */
0, /* <f9> passed to func specified by <f9> */
0, /* <f10> ditto */
NULL, /* <f11> ditto */
NULL, /* <f12> name table pointer */
-1 /* <f13> reserved */
}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
init_dev_sup(parm)
int parm;
{
if(parm==0) {
devSupParms.debugFlag = &K486Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxK486Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
report()
{
return(devGpibLib_report(&DSET_AI));
}

View File

@@ -1,536 +0,0 @@
/* devXxBugRac.c */
/* Device Support Routines for BUF RAC commands */
/*
* Original Author: Ned Arnold (based on work by Jim Kowalkowski)
* Date: 02/01/93
*
* 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 02-01093 nda initialized
* .02 06-03-94 nda removed automatic retry on a TIMEOUT
* .03 06-03-94 nda removed drvBitBus.qReq at init time
* ...
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vme.h>
#include <math.h>
#include <iv.h>
#include <alarm.h>
#include <callback.h>
#include <dbRecType.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <dbCommon.h>
#include <fast_lock.h>
#include <recSup.h>
#include <devSup.h>
#include <drvSup.h>
#include <dbScan.h>
#include <special.h>
#include <module_types.h>
#include <eventRecord.h>
#include <drvBitBusInterface.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <choiceAo.h>
#include <biRecord.h>
#include <boRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <mbboRecord.h>
#include <mbbiRecord.h>
/* types */
#define AI 0x01
#define AO 0x02
#define BI 0x03
#define BO 0x04
#define LI 0x05
#define LO 0x06
#define MBBI 0x07
#define MBBO 0x08
/* Define forward references */
long report();
long init();
static long init_ai();
static long init_ao();
static long init_bo();
static long init_bi();
static long init_li();
long init_lo();
static long init_mbbi();
static long init_mbbo();
long get_ioint_info();
static long bug_rac();
/* Create the dsets for devXxBugRac */
typedef struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_write;
DEVSUPFUN special_linconv;
} IODSET;
/* DEFINE SUPPORTED RAC COMMANDS
#define RESET_STATION 0x00 /* BO record */
#define GET_FUNCTION_ID 0x03 /* LI record */
/* xxDSET devXxxx={ 5,report,init,init_rec,get_ioint_info,bug_rac}; */
IODSET devBoBugRac = { 5, NULL, NULL, init_bo, NULL, bug_rac };
IODSET devLiBugRac = { 5, NULL, NULL, init_li, NULL, bug_rac };
/* forward references */
static void get_data();
static void send_cntl_trans();
extern struct drvBitBusEt drvBitBus;
volatile int bugRacDebug=0;
#define OFF 0
#define ON 1
#ifdef NODEBUG
#define Debug(FMT,V) ;
#else
#define Debug(FMT,V) { if(bugRacDebug) \
{\
printf("%s(%d):",__FILE__,__LINE__); \
printf(FMT,V); \
} \
}
#endif
struct dprivate {
struct dpvtBitBusHead bitbus;
char type;
unsigned char cmd;
struct dbCommon *precord; /* at end for callback to get it */
};
static int io_callback(struct dprivate *pcallback)
{
struct dbCommon *precord;
struct rset *prset;
precord=pcallback->precord;
prset=(struct rset *)(precord->rset);
dbScanLock(precord);
(*prset->process)(precord);
dbScanUnlock(precord);
}
static struct dprivate * set_bitbus(int prio,unsigned char cmd,struct bitbusio *pbitbusio)
{
struct dprivate *my_dpvt;
my_dpvt=(struct dprivate *)(malloc(sizeof(struct dprivate)));
my_dpvt->bitbus.finishProc=io_callback;
my_dpvt->bitbus.psyncSem=(SEM_ID *)NULL;
my_dpvt->bitbus.priority=prio;
my_dpvt->bitbus.link=pbitbusio->link;
my_dpvt->bitbus.rxMaxLen=9;
my_dpvt->bitbus.ageLimit=240;
my_dpvt->bitbus.txMsg.length=9;
my_dpvt->bitbus.txMsg.route=0x40;
my_dpvt->bitbus.txMsg.node=pbitbusio->node;
my_dpvt->bitbus.txMsg.tasks=0;
my_dpvt->bitbus.txMsg.cmd=cmd;
my_dpvt->bitbus.txMsg.data=(unsigned char *)malloc(2);
my_dpvt->bitbus.rxMsg.data=(unsigned char *)malloc(BB_MAX_DAT_LEN);
my_dpvt->bitbus.txMsg.data[0]='\0';
my_dpvt->bitbus.txMsg.data[1]='\0';
Debug("command sent:(%02.2x)\n", my_dpvt->bitbus.txMsg.cmd);
return(my_dpvt);
}
static long init_ai(struct aiRecord *ai)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&ai->inp.value);
struct dprivate *my_dpvt;
int ret;
Debug("init ai invoked\n",0);
/* type must be an BITBUS_IO */
if(ai->inp.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)ai,
"devXxBugRac (init_record) Illegal IN Bus Type");
return(S_dev_badBus);
}
my_dpvt=set_bitbus(ai->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)ai;
my_dpvt->type = AI;
ai->dpvt=(void *)my_dpvt;
return(0);
}
static long init_ao(struct aoRecord *ao)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&ao->out.value);
struct dprivate *my_dpvt;
Debug("init ao invoked\n",0);
/* out must be an BITBUS_IO */
if(ao->out.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)ao,
"devXxBugRac (init_record) Illegal OUT Bus Type");
return(S_dev_badBus);
}
my_dpvt=set_bitbus(ao->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)ao;
my_dpvt->type = AO;
ao->dpvt=(void *)my_dpvt;
return(0);
}
static long init_bi(struct biRecord *bi)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&bi->inp.value);
struct dprivate *my_dpvt;
unsigned char cmd = 0;
Debug("init bi invoked\n",0);
/* out must be an BITBUS_IO */
if(bi->inp.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)bi,
"devXxBugRac (init_record) Illegal IN Bus Type");
return(S_dev_badBus);
}
my_dpvt=set_bitbus(bi->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)bi;
my_dpvt->type = BI;
my_dpvt->cmd = cmd;
bi->dpvt=(void *)my_dpvt;
return(0);
}
static long init_bo(struct boRecord *bo)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&bo->out.value);
struct dprivate *my_dpvt;
Debug("init bo invoked\n",0);
/* out must be an BITBUS_IO */
if(bo->out.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)bo,
"devXxBugRac (init_record) Illegal IN Bus Type");
return(S_dev_badBus);
}
switch(pbitbusio->signal)
{
default:
recGblRecordError(S_dev_badBus,(void *)bo,
"devXxBugRac (init_record) Illegal IN signal number");
return(S_dev_badBus);
case 0: /* signal 0 is a bo record */
break;
}
my_dpvt=set_bitbus(bo->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)bo;
my_dpvt->type = BO;
my_dpvt->cmd = pbitbusio->signal;
bo->dpvt=(void *)my_dpvt;
return(0);
}
static long init_li(struct longinRecord *li)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&li->inp.value);
struct dprivate *my_dpvt;
unsigned char cmd = 0;
Debug("init li invoked\n",0);
/* out must be an BITBUS_IO */
if(li->inp.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)li,
"devXxBugRac (init_record) Illegal IN Bus Type");
return(S_dev_badBus);
}
switch(pbitbusio->signal)
{
default:
recGblRecordError(S_dev_badBus,(void *)li,
"devXxBugRac (init_record) Illegal IN signal number");
return(S_dev_badBus);
case 3: /* signal 3 is a li record */
break;
}
my_dpvt=set_bitbus(li->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)li;
my_dpvt->type = LI;
my_dpvt->cmd = pbitbusio->signal;
li->dpvt=(void *)my_dpvt;
return(0);
}
static long init_mbbi(struct mbbiRecord *mbbi)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&mbbi->inp.value);
struct dprivate *my_dpvt;
unsigned char cmd = 0;
Debug("init mbbi invoked\n",0);
/* out must be an BITBUS_IO */
if(mbbi->inp.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)mbbi,
"devXxBugRac (init_record) Illegal IN Bus Type");
return(S_dev_badBus);
}
my_dpvt=set_bitbus(mbbi->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)mbbi;
my_dpvt->type = MBBI;
my_dpvt->cmd = cmd;
mbbi->dpvt=(void *)my_dpvt;
return(0);
}
static long init_mbbo(struct mbboRecord *mbbo)
{
struct bitbusio *pbitbusio = (struct bitbusio *)(&mbbo->out.value);
struct dprivate *my_dpvt;
unsigned char cmd = 0;
Debug("init mbbo invoked\n",0);
/* out must be an BITBUS_IO */
if(mbbo->out.type!=BITBUS_IO)
{
recGblRecordError(S_dev_badBus,(void *)mbbo,
"devXxBugRac (init_record) Illegal OUT Bus Type");
return(S_dev_badBus);
}
if(pbitbusio->signal >= 8 )
{
recGblRecordError(S_dev_badBus,(void *)mbbo,
"devXxBugRac (init_record) Illegal OUT signal number");
return(S_dev_badBus);
}
my_dpvt=set_bitbus(mbbo->prio,pbitbusio->signal,pbitbusio);
my_dpvt->precord = (struct dbCommon *)mbbo;
my_dpvt->type = MBBO;
my_dpvt->cmd = cmd;
mbbo->dpvt=(void *)my_dpvt;
return(0);
}
static long bug_rac(struct dbCommon *io)
{
struct dprivate *my_dpvt=(struct dprivate *)io->dpvt;
struct dpvtBitBusHead *pbitbus;
if(!io->dpvt) return(S_dev_NoInit);
pbitbus=&(my_dpvt->bitbus);
if(io->pact==TRUE)
{
Debug("Bitbus message completed \n",0);
/* a transaction to bitbus has completed */
switch(pbitbus->status)
{
case BB_OK:
Debug("Getting data \n",0);
get_data(io);
return(0);
default:
recGblSetSevr(io,WRITE_ALARM,MAJOR_ALARM);
recGblRecordError(S_dev_badBus,(void *)io,
"devXxBugRac (iobug_rdwr) BitBus Error!");
return(S_dev_badBus);
}
}
else
{
/* data needs to be sent to bitbus */
Debug("Sending transaction \n",0);
send_cntl_trans(io);
}
io->pact=TRUE;
/* queue the command */
if((*drvBitBus.qReq)(pbitbus,BB_Q_LOW)<0)
{
recGblSetSevr(io,WRITE_ALARM,MAJOR_ALARM);
recGblRecordError(S_dev_badBus,(void *)io,
"devXxBugRac (init_record) Initial BitBus message failed");
return(S_dev_badBus);
}
Debug("Queued transaction \n",0);
return(0);
}
static void get_data(struct dbCommon *io)
{
struct dprivate *my_dpvt=(struct dprivate *)io->dpvt;
struct dpvtBitBusHead *pbitbus;
struct boRecord *bo;
struct biRecord *bi;
struct aoRecord *ao;
struct aiRecord *ai;
struct longoutRecord *lo;
struct longinRecord *li;
struct mbboRecord *mbbo;
struct mbbiRecord *mbbi;
long value;
unsigned long uvalue;
pbitbus=&(my_dpvt->bitbus);
Debug("Command return: 0x%04.4X\n",pbitbus->rxMsg.cmd);
Debug("byte 1 of return: 0x%04.4X\n",pbitbus->rxMsg.data[0]);
Debug("byte 2 of return: 0x%04.4X\n",pbitbus->rxMsg.data[1]);
switch(my_dpvt->type)
{
case LI:
li=(struct longinRecord *)io;
switch(my_dpvt->bitbus.txMsg.cmd)
{
case GET_FUNCTION_ID:
/* extract the second ID code (task 1) */
li->val = pbitbus->rxMsg.data[1];
li->udf = 0;
if ((pbitbus->rxMsg.cmd) != 0)
{
recGblSetSevr(li, READ_ALARM, INVALID_ALARM);
}
break;
default:
break;
}
default:
break;
}
return;
}
static void send_cntl_trans(struct dbCommon *io)
{
struct dprivate *my_dpvt=(struct dprivate *)io->dpvt;
struct dpvtBitBusHead *pbitbus;
struct boRecord *bo;
struct aoRecord *ao;
struct mbboRecord *mbbo;
short lsb,msb;
pbitbus=&(my_dpvt->bitbus);
pbitbus->finishProc=io_callback;
pbitbus->psyncSem=(SEM_ID *)NULL;
pbitbus->priority=io->prio;
pbitbus->txMsg.cmd=my_dpvt->cmd;
switch(my_dpvt->type)
{
case BO:
bo=(struct boRecord *)io;
break;
case MBBO:
mbbo=(struct mbboRecord *)io;
break;
case AO:
ao=(struct aoRecord *)io;
pbitbus->txMsg.data[0]=0;
pbitbus->txMsg.data[1]=0;
break;
default:
break;
}
my_dpvt->precord=(struct dbCommon *)io;
Debug("Command send: 0x%02.2X\n",pbitbus->txMsg.cmd);
Debug("byte 1 sent: 0x%02.2X\n",(unsigned char)pbitbus->txMsg.data[0]);
Debug("byte 2 sent: 0x%02.2X\n",(unsigned char)pbitbus->txMsg.data[1]);
return;
}

View File

@@ -1,387 +0,0 @@
/* devXxDc5009Gpib.c */
/* share/src/devOpt $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 05-30-91 jrw Initial Release
*/
/******************************************************************************
*
* The following define statements are used to declare the names to be used
* for the dset tables.
*
* NOTE: The dsets are referenced by the entries in the command table.
*
******************************************************************************/
#define DSET_AI devAiDc5009Gpib
#define DSET_AO devAoDc5009Gpib
#define DSET_LI devLiDc5009Gpib
#define DSET_LO devLoDc5009Gpib
#define DSET_BI devBiDc5009Gpib
#define DSET_BO devBoDc5009Gpib
#define DSET_MBBO devMbboDc5009Gpib
#define DSET_MBBI devMbbiDc5009Gpib
#define DSET_SI devSiDc5009Gpib
#define DSET_SO devSoDc5009Gpib
#define STATIC static
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
STATIC long init_dev_sup(), report();
STATIC int srqHandler();
STATIC struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
/******************************************************************************
*
* Debugging flags that can be accessed from the shell.
*
******************************************************************************/
int Dc5009Debug = 0;
extern int ibSrqDebug; /* declared in the GPIB driver */
/******************************************************************************
*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*
* These are to be declared in 60ths of a second.
*
******************************************************************************/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 60 /* 1 second on a watchdog time */
/******************************************************************************
*
* Strings used by the init routines to fill in the znam, onam, ...
* fields in BI, BO, MBBI, and MBBO record types.
******************************************************************************/
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *offOffList[] = { "Off", "Off" };
static struct devGpibNames offOff = { 2, offOffList, NULL, 1 };
static char *onOnList[] = { "On", "On" };
static struct devGpibNames onOn = { 2, onOnList, NULL, 1 };
static char *initNamesList[] = { "Init", "Init" };
static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
/******************************************************************************
*
* String arrays for EFAST operations. Note that the last entry must be
* NULL.
*
* On input operations, only as many bytes as are found in the string array
* elements are compared. If there are more bytes than that in the input
* message, they are ignored. The first matching string found (starting
* from the 0'th element) will be used as a match.
*
* NOTE: For the input operations, the strings are compared literally! This
* can cause problems if the instrument is returning things like \r and \n
* characters. You must take care when defining input strings so you include
* them as well.
*
******************************************************************************/
static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL};
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0, init the device */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "init", NULL, 0, 32,
NULL, 0, 0, NULL, &initNames, -1},
/* Param 1, set ability to generate SRQs by pressing the ID button */
{&DSET_BO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 32,
NULL, 0, 0, userOffOn, &offOn, -1},
/* Param 2, dissallow user-gen'd SRQs */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "user off", NULL, 0, 32,
NULL, 0, 0, NULL, &offOff, -1},
/* Param3, create an error */
{&DSET_BO, GPIBCMD, IB_Q_LOW, "XyZzY", NULL, 0, 32,
NULL, 0, 0, NULL, &onOn, -1},
/* Param4, read the error status */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "err?", "ERR %lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 5 read the user button status */
{&DSET_BI, GPIBEFASTI, IB_Q_HIGH, "user?", NULL, 0, 32,
NULL, 0, 0, userOffOn, &offOn, -1},
/* Param 6 send a reading from the display */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "DISP?", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
******************************************************************************/
STATIC long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &Dc5009Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = 4;
devSupParms.name = "devXxDc5009Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = srqHandler;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm,&DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
******************************************************************************/
STATIC long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}
/******************************************************************************
*
* This is invoked by the linkTask when an SRQ is detected from a device
* operated by this module.
*
* It calls the work routine associated with the type of record expecting
* the SRQ response.
*
* No semaphore locks are needed around the references to anything in the
* hwpvt structure, because it is static unless modified by the linkTask and
* the linkTask is what will execute this function.
*
* THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF...
* - the MAGIC_SRQ_PARM command is a GPIBREADW command.
* - the device generates unsolicited SRQs while processing GPIBREADW commands.
*
* In general, this function will have to be modified for each device
* type that SRQs are to be supported. This is because the serial poll byte
* format varies from device to device.
*
******************************************************************************/
#define DC5009_GOODBITS 0xef /* I only care about these bits */
#define DC5009_PON 65 /* power just turned on */
#define DC5009_OPC 66 /* operation just completed */
#define DC5009_USER 67 /* user requested SRQ */
STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
{
int status = IDLE; /* assume device will be idle when finished */
if (Dc5009Debug || ibSrqDebug)
printf("dc5009 srqHandler(%p, 0x%2.2X): called\n", phwpvt, srqStatus);
switch (srqStatus & DC5009_GOODBITS) {
case DC5009_OPC:
/* Invoke the command-type specific SRQ handler */
if (phwpvt->srqCallback != NULL)
status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus));
else
printf("dc5009 srqHandler: Unsolicited operation complete from DC5009 device support!\n");
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
case DC5009_USER:
/* user requested srq event is specific to the Dc5009 */
printf("dc5009 srqHandler: Dc5009 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device);
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
case DC5009_PON:
printf("dc5009 srqHandler: Power cycled on DC5009\n");
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
default:
if (phwpvt->unsolicitedDpvt != NULL)
{
if(Dc5009Debug || ibSrqDebug)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%2.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else
{
printf("dc5009 srqHandler: Unsolicited SRQ ignored from link %d, device %d, status = 0x%2.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
}
}
return(status);
}

View File

@@ -1,883 +0,0 @@
/* devXxDg535Gpib.c */
/* share/src/devOpt $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 05-30-91 jrw Initial Release
* .02 01-06-92 nda dg535 support under EPICS 3.3
*/
#define DSET_AI devAiDg535Gpib
#define DSET_AO devAoDg535Gpib
#define DSET_LI devLiDg535Gpib
#define DSET_LO devLoDg535Gpib
#define DSET_BI devBiDg535Gpib
#define DSET_BO devBoDg535Gpib
#define DSET_MBBO devMbboDg535Gpib
#define DSET_MBBI devMbbiDg535Gpib
#define DSET_SI devSiDg535Gpib
#define DSET_SO devSoDg535Gpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
#define STATIC static
STATIC long init_dev_sup(), report();
STATIC struct devGpibParmBlock devSupParms;
/* forward declarations of some custom convert routines */
STATIC int setDelay();
STATIC int rdDelay();
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
int Dg535Debug = 0; /* debugging flags */
extern int ibSrqDebug;
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 20 /* 1/3 second on a watchdog time */
/*
* Strings used by the init routines to fill in the znam, onam, ...
* fields in BI, BO, MBBI, and MBBO record types.
*/
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *singleShotList[] = { "SINGLE", "SHOT" };
static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
static char *tABCDList[] = { "T", "A", "B", "C", "D" };
static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 };
static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 };
static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" };
static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 };
static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList,
ttlNimEclVarVal, 2 };
static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL",
"SINGLE SHOT", "BURST MODE", "STOP" };
static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 };
static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList,
intExtSsBmStopVal, 2 };
static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList,
intExtSsBmStopVal, 3 };
/* Channel Names, used to derive string representation of programmed delay */
char *pchanName[8] = {" ", "T + ", "A + ", "B + ", " ", "C + ", "D + ", " "};
/******************************************************************************
*
* String arrays for EFAST operations. Note that the last entry must be
* NULL.
*
* On input operations, only as many bytes as are found in the string array
* elements are compared. If there are more bytes than that in the input
* message, they are ignored. The first matching string found (starting
* from the 0'th element) will be used as a match.
*
* NOTE: For the input operations, the strings are compared literally! This
* can cause problems if the instrument is returning things like \r and \n
* characters. You must take care when defining input strings so you include
* them as well.
*
******************************************************************************/
static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL};
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0, (model) */
FILL,
/* Channel A Delay and Output */
/* Param 1, write A delay */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,?,%.12lf\n", 0, 32,
setDelay, 0, 0, NULL, NULL, -1},
/* Param 2, currently undefined */
FILL,
/* Param 3, read A Delay */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1 },
/* Param 4, read A delay reference channel and delay as string */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1 },
/* Param 5, set A delay reference channel */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 2\n", "DT 2,%u,", 0, 32,
setDelay, 0, 0, NULL, &tABCD, -1},
/* Param 6, read A delay reference */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 2\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, &tABCD, -1},
/* Param 7, set A output mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 2,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 8, read A output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 2\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 9, set A output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 2,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 10, read A output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 2\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 11, set A output offset */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 2,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 12, read A output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 2\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 13, set A output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 2,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 14, read A output Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 2\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 15, set A output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 2,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 16, read A output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 2\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Channel B Delay and Output */
/* Param 17, write B delay */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,?,%.12lf\n", 0, 32,
setDelay, 0, 0, NULL, NULL, -1},
/* Param 18, currently undefined */
FILL,
/* Param 19, read B Delay */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1},
/* Param 20, read B delay reference channel and delay as string */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1 },
/* Param 21, set B delay reference channel */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 3\n", "DT 3,%u,", 0, 32,
setDelay, 0, 0, NULL, &tABCD, -1},
/* Param 22, read B delay reference */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 3\n", NULL, 0, 32,
rdDelay, 0 ,0, NULL, &tABCD, -1},
/* Param 23, set B output mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 3,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 24, read B output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 3\n", "%lu", 0 ,32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 25, set B output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 3,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 26, read B output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 3\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 27, set B output offset */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 3,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 28, read B output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 3\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 29, set B output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 3,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 30, read B output Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 3\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 31, set B output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 3,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 32, read B output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 3\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Channel AB Outputs */
/* Param 33, set AB output mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 4,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 34, read AB output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 4\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 35, set AB output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 4,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 36, read AB output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 4\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 37, set AB output offset */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 4,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 38, read AB output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 4\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 39, set AB output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 4,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 40, read AB output Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 4\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 41, set AB output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 4,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 42, read AB output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 4\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Channel C Delay and Output */
/* Param 43, write C delay */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,?,%.12lf\n", 0, 32,
setDelay, 0, 0, NULL, NULL, -1},
/* Param 44, currently undefined */
FILL,
/* Param 45, read C Delay */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1},
/* Param 46, read C delay reference channel and delay as string */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1 },
/* Param 47, set C delay reference channel */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 5\n", "DT 5,%u,", 0, 32,
setDelay, 0, 0, NULL, &tABCD, -1},
/* Param 48, read C delay reference */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 5\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, &tABCD, -1},
/* Param 49, set C output mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 5,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 50, read C output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 5\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 51, set C output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 5,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 52, read C output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 5\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 53, set C output offset */
{&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 5,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 54, read C output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 5\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 55, set C output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 5,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 56, read C utput Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 5\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 57, set C output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 5,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 58, read C output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 5\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Channel D Delay and Output */
/* Param 59, write D delay */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,?,%.12lf\n", 0, 32,
setDelay, 0, 0, NULL, NULL, -1},
/* Param 60, currently undefined */
FILL,
/* Param 61, read D Delay */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1},
/* Param 62, read D delay reference channel and delay as string */
{&DSET_SI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32,
rdDelay, 0, 0, NULL, NULL, -1 },
/* Param 63, set D delay reference channel */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, "DT 6\n", "DT 6,%u,", 0, 32,
setDelay, 0, 0, NULL, &tABCD, -1},
/* Param 64, read D delay reference */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "DT 6\n", NULL, 0, 32,
rdDelay, 0 ,0, NULL, &tABCD, -1},
/* Param 65, set D output mode */
{&DSET_MBBI, GPIBWRITE, IB_Q_HIGH, NULL, "OM 6,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 66, read D output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 6\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 67, set D output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 6,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 68, read D output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 6\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 69, set D output offset */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OO 6,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 70, read D output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 6\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 71, set D output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 6,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 72, read D output Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 6\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 73, set D output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 6,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 74, read D output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 6\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Channel CD Outputs */
/* Param 75, set CD output mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "OM 7,%u\n", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 76, read CD output mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "OM 7\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &ttlNimEclVar, -1},
/* Param 77, set CD output amplitude */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "OA 7,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 78, read CD output amplitude */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OA 7\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 79, set CD output offset */
{&DSET_AI, GPIBWRITE, IB_Q_HIGH, NULL, "OO 7,%.1f\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 80, read CD output offset */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "OO 7\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 81, set CD output Termination */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 7,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 82, read CD output Termination */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 7\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 83, set CD output Polarity */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "OP 7,%u\n", 0, 32,
NULL, 0, 0, NULL, &invertNorm, -1},
/* Param 84, read CD output Polarity */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "OP 7\n", "%lu", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Trigger Settings */
/* Param 85, set Trig Mode */
{&DSET_MBBO, GPIBWRITE, IB_Q_HIGH, NULL, "TM %u\n", 0, 32,
NULL, 0, 0, NULL, &intExtSsBmStop, -1},
/* Param 86, read Trig Mode */
{&DSET_MBBI, GPIBREAD, IB_Q_LOW, "TM \n", "%lu", 0, 32,
NULL, 0, 0, NULL, &intExtSsBm, -1},
/* Param 87, set Trig Rate */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 0,%.3lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 88, read Trig Rate */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 0\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 89, set Burst Rate */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TR 1,%.3lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 90, read Burst Rate */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "TR 1\n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 91, set Burst Count */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BC %01.0lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 92, read Burst Count */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "BC \n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 93, set Burst Period */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "BP %01.0lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 94, read Burst Period */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "BP \n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 95, set Trig Input Z */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TZ 0,%u\n", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 96, read Trig Input Z */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TZ 0\n", "%lu", 0, 32,
NULL, 0, 0, NULL, &lozHiz, -1},
/* Param 97, set Trig Input slope */
{&DSET_BO, GPIBWRITE, IB_Q_HIGH, NULL, "TS %u\n", 0, 32,
NULL, 0, 0, NULL, &fallingRising, -1},
/* Param 98, read Trig Input slope */
{&DSET_BI, GPIBREAD, IB_Q_LOW, "TS \n", "%lu", 0, 32,
NULL, 0, 0, NULL, &fallingRising, -1},
/* Param 99, set Trig Input level */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "TL %.2lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 100, read Trig Input Level */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "TL \n", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 101, generate Single Trig */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "SS \n", NULL, 0, 32,
NULL, 0, 0, NULL, &singleShot, -1},
/* Param 102, Store Setting # */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "ST %01.0lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 103, Recall Setting # */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "RC %01.0lf\n", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 104, Recall Setting # */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "CL \n", NULL, 0, 32,
NULL, 0, 0, NULL, &clear, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
******************************************************************************/
STATIC long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &Dg535Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxDg535Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
******************************************************************************/
STATIC long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}
/****************************************************************************
*
*
* Custom convert routines for DG535
*
*
***************************************************************************/
/******************************************************************************
*
* Unique message interpretaion for reading Channel Delays :
* The command to read the delay setting returns a string with two arguments,
* (eg 1, 4.300000000000)
* This routine extracts both arguments and assigns them appropriately. If the
* parameter corresponds to a "READ DELAY INTO STRING RECORD",
* a string is generated with the format CHAN + xxx.xxxxxxxxxxxx and stored
* in the val field of the SI record. (ex: T + .000000500000)
*****************************************************************************/
STATIC int rdDelay(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
int status;
double delay;
unsigned long chan;
union delayRec {
struct aiRecord ai;
struct mbbiRecord mbbi;
struct stringinRecord si;
} *prec = (union delayRec *) (pdpvt->precord);
if(Dg535Debug)
printf("rdDelay : returned msg :%s\n",pdpvt->msg);
/* Change the "," in returned string to a " " to separate fields */
pdpvt->msg[1] = 0x20;
/* scan response string for chan reference & delay value */
status = sscanf(pdpvt->msg, "%ld%lf", &chan, &delay);
if(Dg535Debug)
{
printf("Dg535 rdDelay(): pdpvt=%p prec=%p status=%ld msg=%s\n",
pdpvt, prec, status, pdpvt->msg);
}
switch (pdpvt->parm)
{
case 4: /* A Delay monitor, must be an si record */
case 20: /* B Delay monitor, must be an si record */
case 46: /* C Delay monitor, must be an si record */
case 62: /* D Delay monitor, must be an si record */
if (status == 2) /* make sure both parameters were assigned */
{
/* create a string in the value field*/
strcpy(prec->si.val, pchanName[chan]);
strcat(prec->si.val, &((pdpvt->msg)[3]));
}
else
{
if (prec->si.nsev < INVALID_ALARM)
{
prec->si.nsev = INVALID_ALARM;
prec->si.nsta = READ_ALARM;
}
}
break;
case 3: /* A Delay monitor, must be an ai record */
case 19: /* B Delay monitor, must be an ai record */
case 45: /* C Delay monitor, must be an ai record */
case 61: /* D Delay monitor, must be an ai record */
if (status == 2) /* make sure both parameters were assigned */
{
/* assign new delay to value field*/
prec->ai.val = delay;
}
else
{
if (prec->ai.nsev < INVALID_ALARM)
{
prec->ai.nsev = INVALID_ALARM;
prec->ai.nsta = READ_ALARM;
}
}
break;
case 6: /* A Delay Reference monitor, must be an mbbi record */
case 22: /* B Delay Reference monitor, must be an mbbi record */
case 48: /* C Delay Reference monitor, must be an mbbi record */
case 64: /* D Delay Reference monitor, must be an mbbi record */
if (status == 2) /* make sure both parameters were assigned */
{
prec->mbbi.rval = chan;
}
else
{
if (prec->mbbi.nsev < INVALID_ALARM)
{
prec->mbbi.nsev = INVALID_ALARM;
prec->mbbi.nsta = READ_ALARM;
}
}
break;
}
return(OK);
}
/******************************************************************************
*
* Unique message generation for writing channel Delays :
* The command to set the channel delay requires two parameters: The channel
* # to reference from and the time delay. Since changing either of these
* parameters requires the entire command to be sent, the current state of
* other parameter must be determined. This is done by reading the delay (which
* returns both parameters), changing one of the paramaters, and sending
* the command back.
*
*************************************************************************/
STATIC int setDelay(struct gpibDpvt *pdpvt, int p1, int p2, char **p3)
{
char curChan;
char tempMsg[32];
union delayRec {
struct aoRecord ao;
struct mbboRecord mbbo;
} *prec = (union delayRec *) (pdpvt->precord);
/* go read the current delay & channel reference setting */
/* this is done by specifying a GPIBREAD even though the gpibCmd is
defined as a GPIBWRITE. The cmd string in the gpibCmd is initialized
to make this work */
if(devGpibLib_xxGpibWork(pdpvt, GPIBREAD, -1) == ERROR)
{ /* abort operation if read failed */
return(ERROR); /* return, signalling an error */
}
/* Due to a fluke in the DG535, read again to insure accurate data */
if(devGpibLib_xxGpibWork(pdpvt, GPIBREAD, -1) == ERROR)
{ /* abort operation if read failed */
return(ERROR); /* return, signalling an error */
}
/* change one of the two parameters ... */
switch(pdpvt->parm)
{
case 1: /* changing time delay */
case 17:
case 43:
case 59:
curChan = pdpvt->msg[0]; /* save current chan reference */
/* generate new delay string (correct rounding error) */
sprintf(pdpvt->msg,gpibCmds[pdpvt->parm].format, (prec->ao.val + 1.0e-13));
pdpvt->msg[5] = curChan; /* replace "?" with current chan */
break;
case 5: /* changing reference channel */
case 21:
case 47:
case 63:
strcpy(tempMsg, &((pdpvt->msg)[3])); /* save current delay setting */
/* generate new channel reference */
sprintf(pdpvt->msg, gpibCmds[pdpvt->parm].format, (unsigned int)prec->mbbo.rval);
strcat(pdpvt->msg, tempMsg); /* append current delay setting */
break;
}
if(Dg535Debug)
printf("setDelay : returned msg :%s\n",pdpvt->msg);
return(OK); /* aoGpibWork or mbboGpibWork will call xxGpibWork */
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,284 +0,0 @@
/* devXxK196Gpib.c */
/* share/src/devOpt $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:
* -----------------
*/
#define DSET_AI devAiK196Gpib
#define DSET_AO devAoK196Gpib
#define DSET_LI devLiK196Gpib
#define DSET_LO devLoK196Gpib
#define DSET_BI devBiK196Gpib
#define DSET_BO devBoK196Gpib
#define DSET_MBBO devMbboK196Gpib
#define DSET_MBBI devMbbiK196Gpib
#define DSET_SI devSiK196Gpib
#define DSET_SO devSoK196Gpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
static long init_dev_sup(), report();
static struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
int K196Debug = 0; /* debugging flags */
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 30 /* 1/2 second on a watchdog time */
/*
* Strings used by the init routines to fill in the znam, onam, ...
* fields in BI, BO, MBBI, and MBBO record types.
*/
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *singleShotList[] = { "SINGLE", "SHOT" };
static struct devGpibNames singleShot = { 2, singleShotList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
static char *tABCDList[] = { "T", "A", "B", "C", "D" };
static unsigned long tABCDVal[] = { 1, 2, 3, 5, 6 };
static struct devGpibNames tABCD = { 5, tABCDList, tABCDVal, 3 };
static char *ttlNimEclVarList[] = { "TTL", "NIM", "ECL", "VAR" };
static unsigned long ttlNimEclVarVal[] = { 0, 1, 2, 3 };
static struct devGpibNames ttlNimEclVar = { 4, ttlNimEclVarList,
ttlNimEclVarVal, 2 };
static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL",
"SINGLE SHOT", "BURST MODE", "STOP" };
static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 };
static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList,
intExtSsBmStopVal, 2 };
static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList,
intExtSsBmStopVal, 3 };
/******************************************************************************
*
* String arrays for EFAST operations. Note that the last entry must be
* NULL.
*
* On input operations, only as many bytes as are found in the string array
* elements are compared. If there are more bytes than that in the input
* message, they are ignored. The first matching string found (starting
* from the 0'th element) will be used as a match.
*
* NOTE: For the input operations, the strings are compared literally! This
* can cause problems if the instrument is returning things like \r and \n
* characters. You must take care when defining input strings so you include
* them as well.
*
******************************************************************************/
static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL};
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0, (model) */
FILL,
/* Param 1 initialization string */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "L0XR3X", NULL, 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 2 read current voltage value */
{&DSET_AI, GPIBREAD, IB_Q_HIGH, "U7", "%*4c%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &K196Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxK196Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}

View File

@@ -1,220 +0,0 @@
/* devXxK263Gpib.c */
/* share/src/devOpt $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 05-30-91 jrw Initial Release
* .02 01-06-92 nda dg535 support under EPICS 3.3
*/
#define DSET_AI devAiK263Gpib
#define DSET_AO devAoK263Gpib
#define DSET_LI devLiK263Gpib
#define DSET_LO devLoK263Gpib
#define DSET_BI devBiK263Gpib
#define DSET_BO devBoK263Gpib
#define DSET_MBBO devMbboK263Gpib
#define DSET_MBBI devMbbiK263Gpib
#define DSET_SI devSiK263Gpib
#define DSET_SO devSoK263Gpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
static long init_dev_sup(), report();
static struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
int K263Debug = 0; /* debugging flags */
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 30 /* 1/2 second on a watchdog time */
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0, (model) */
FILL,
/* Param 1 initialization string */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "F2XR004XZ0XC0XW0XG1XO1XM00XK0XY4X", NULL, 0, 0,
NULL, 0, 0, NULL, NULL, -1},
/* Param 2 set voltage reference */
{&DSET_AO, GPIBWRITE, IB_Q_HIGH, NULL, "V%lfX", 32, 32,
NULL, 0, 0, NULL, NULL, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &K263Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxK263Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
static long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}

View File

@@ -1,414 +0,0 @@
/* devXxSkeletonGpib.c */
/* share/src/devOpt $Id$ */
/*
* Author: John Winans
* Date: 02-18-92
*
* 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 02-18-92 jrw Initial Release
*/
/******************************************************************************
*
* The following define statements are used to declare the names to be used
* for the dset tables.
*
* NOTE: The dsets are referenced by the entries in the command table.
*
******************************************************************************/
#define DSET_AI devAiSkeletonGpib
#define DSET_AO devAoSkeletonGpib
#define DSET_LI devLiSkeletonGpib
#define DSET_LO devLoSkeletonGpib
#define DSET_BI devBiSkeletonGpib
#define DSET_BO devBoSkeletonGpib
#define DSET_MBBO devMbboSkeletonGpib
#define DSET_MBBI devMbbiSkeletonGpib
#define DSET_SI devSiSkeletonGpib
#define DSET_SO devSoSkeletonGpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
#define STATIC static
STATIC long init_dev_sup(), report();
STATIC int srqHandler();
static struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
* The last 3 items in the DSET structure are used to point to the parm
* structure, the work functions used for each record type, and the srq
* handler for each record type.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
/******************************************************************************
*
* Debugging flags that can be accessed from the shell.
*
******************************************************************************/
int SkeletonDebug = 0;
extern int ibSrqDebug; /* declared in the GPIB driver */
/******************************************************************************
*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*
* Use the DMA_TIME to define how long you wish to wait for an I/O operation
* to complete once started.
*
* These are to be declared in 60ths of a second.
*
******************************************************************************/
#define TIME_WINDOW 600 /* 10 seconds */
#define DMA_TIME 60 /* 1 second */
/******************************************************************************
*
* Strings used by the init routines to fill in the znam, onam, ...
* fields in BI and BO record types.
*
******************************************************************************/
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *initNamesList[] = { "Init", "Init" };
static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
/******************************************************************************
*
* Structures used by the init routines to fill in the onst, twst,... and the
* onvl, twvl,... fields in MBBI and MBBO record types.
*
* Note that the intExtSsBm and intExtSsBmStop structures use the same
* intExtSsBmStopList and intExtSsBmStopVal lists but have a different number
* of elements in them that they use... The intExtSsBm structure only represents
* 4 elements, while the intExtSsBmStop structure represents 5.
*
******************************************************************************/
static char *intExtSsBmStopList[] = { "INTERNAL", "EXTERNAL",
"SINGLE SHOT", "BURST MODE", "STOP" };
static unsigned long intExtSsBmStopVal[] = { 0, 1, 2, 3, 2 };
static struct devGpibNames intExtSsBm = { 4, intExtSsBmStopList,
intExtSsBmStopVal, 2 };
static struct devGpibNames intExtSsBmStop = { 5, intExtSsBmStopList,
intExtSsBmStopVal, 3 };
/******************************************************************************
*
* String arrays for EFAST operations. Note that the last entry must be
* NULL.
*
* On input operations, only as many bytes as are found in the string array
* elements are compared. If there are more bytes than that in the input
* message, they are ignored. The first matching string found (starting
* from the 0'th element) will be used as a match.
*
* NOTE: For the input operations, the strings are compared literally! This
* can cause problems if the instrument is returning things like \r and \n
* characters. You must take care when defining input strings so you include
* them as well.
*
******************************************************************************/
static char *(userOffOn[]) = {"USER OFF;", "USER ON;", NULL};
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0 */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "init", NULL, 0, 32,
NULL, 0, 0, NULL, &initNames, -1},
/* Param 1 */
{&DSET_BO, GPIBEFASTO, IB_Q_HIGH, NULL, NULL, 0, 32,
NULL, 0, 0, userOffOn, &offOn, -1},
/* Param 2 */
{&DSET_BI, GPIBEFASTI, IB_Q_HIGH, "user?", NULL, 0, 32,
NULL, 0, 0, userOffOn, &offOn, -1},
/* Param 3 */
{&DSET_AI, GPIBREAD, IB_Q_LOW, "send", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
*****************************************************************************/
/******************************************************************************
* The magic SRQ parm is the parm number that, if specified on a passive
* record, will cause the record to be processed automatically when an
* unsolicited SRQ interrupt is detected from the device.
*
* If the parm is specified on a non-passive record, it will NOT be processed
* when an unsolicited SRQ is detected.
*
* In the future, the magic SRQ parm records will be processed as "I/O event
* scanned"... not passive.
*
*****************************************************************************/
STATIC long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &SkeletonDebug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxSkeletonGpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = 0;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm,&DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
* This function will no longer be required after epics 3.3 is released
*
******************************************************************************/
STATIC long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}
/******************************************************************************
*
* A sample SRQ handler. This one is taken from the DC5009 gpib device support
* module. Its primary function is to check the serial poll byte to determine
* why an SRQ was generated from the device. If the SRQ is an operation
* complete, and the GPIB library code was expecting one, it would have left
* a pointer to a function that can be used to finish processing the
* transaction that solicited the OPC SRQ. In other cases, an error or event
* of interest has occured and notice should be taken.
*
* This is invoked by the linkTask when an SRQ is detected from a device
* operated by this module.
*
* It calls the work routine associated with the type of record expecting
* the SRQ response.
*
* No semaphore locks are needed around the references to anything in the
* hwpvt structure, because it is static unless modified by the linkTask and
* the linkTask is what will execute this function.
*
* THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF...
* - the MAGIC_SRQ_PARM command is a GPIBREADW command.
* - the device generates unsolicited SRQs while processing GPIBREADW commands.
*
* In general, this function will have to be modified for each device
* type that SRQs are to be supported. This is because the serial poll byte
* format varies from device to device.
*
******************************************************************************/
#define DC5009_GOODBITS 0xef /* I only care about these bits */
#define DC5009_PON 65 /* power just turned on */
#define DC5009_OPC 66 /* operation just completed */
#define DC5009_USER 67 /* user requested SRQ */
STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
{
int status = IDLE; /* assume device will be idle when finished */
if (SkeletonDebug || ibSrqDebug)
printf("dc5009 srqHandler(%p, 0x%2.2X): called\n", phwpvt, srqStatus);
switch (srqStatus & DC5009_GOODBITS) {
case DC5009_OPC:
/* Invoke the command-type specific SRQ handler */
if (phwpvt->srqCallback != NULL)
status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus));
else
printf("dc5009 srqHandler: Unsolicited operation complete from DC5009 device support!\n");
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
case DC5009_USER:
/* user requested srq event is specific to the Dc5009 */
printf("dc5009 srqHandler: Dc5009 User requested srq event link %d, device %d\n", phwpvt->link, phwpvt->device);
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
case DC5009_PON:
printf("dc5009 srqHandler: Power cycled on DC5009\n");
break;
/* BUG - I have to clear out the error status by doing an err? read operation */
default:
if (phwpvt->unsolicitedDpvt != NULL)
{
if(SkeletonDebug || ibSrqDebug)
printf("dc5009 srqHandler: Unsolicited SRQ being handled from link %d, device %d, status = 0x%2.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else
{
printf("dc5009 srqHandler: Unsolicited SRQ ignored from link %d, device %d, status = 0x%2.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
}
}
return(status);
}

View File

@@ -1,254 +0,0 @@
/* share/src/devOpt $Id$ */
/*
* Author: John Winans
* Date: 04-13-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 09-30-91 jrw created
*
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iosLib.h>
#include <taskLib.h>
#include <memLib.h>
#include <semLib.h>
#include <wdLib.h>
#include <wdLib.h>
#include <tickLib.h>
#include <vme.h>
#include <task_params.h>
#include <module_types.h>
#include <drvSup.h>
#include <devSup.h>
#include <dbDefs.h>
#include <link.h>
#include <callback.h>
#include <fast_lock.h>
#include <drvMsg.h>
#include <drvRs232.h>
#include <drvTy232.h>
#include <drvBB232.h>
static long BBinit(), BBreport(), VXinit(), VXreport();
static msgParmBlock BBParmBlock, VXParmBlock;
/******************************************************************************
*
* DSET tables used for BITBUS -> RS-232 ports.
*
******************************************************************************/
msgDset devBBAiSoftMsg = { 6, { BBreport, BBinit, drvMsg_initAi, NULL,
drvMsg_procAi, NULL}, &BBParmBlock, &drvMsgAi};
msgDset devBBAoSoftMsg = { 6, { NULL, NULL, drvMsg_initAo, NULL,
drvMsg_procAo, NULL}, &BBParmBlock, &drvMsgAo};
msgDset devBBBiSoftMsg = { 6, { NULL, NULL, drvMsg_initBi, NULL,
drvMsg_procBi, NULL}, &BBParmBlock, &drvMsgBi};
msgDset devBBBoSoftMsg = { 6, { NULL, NULL, drvMsg_initBo, NULL,
drvMsg_procBo, NULL}, &BBParmBlock, &drvMsgBo};
msgDset devBBMiSoftMsg = { 6, { NULL, NULL, drvMsg_initMi, NULL,
drvMsg_procMi, NULL}, &BBParmBlock, &drvMsgMi};
msgDset devBBMoSoftMsg = { 6, { NULL, NULL, drvMsg_initMo, NULL,
drvMsg_procMo, NULL}, &BBParmBlock, &drvMsgMo};
msgDset devBBLiSoftMsg = { 6, { NULL, NULL, drvMsg_initLi, NULL,
drvMsg_procLi, NULL}, &BBParmBlock, &drvMsgLi};
msgDset devBBLoSoftMsg = { 6, { NULL, NULL, drvMsg_initLo, NULL,
drvMsg_procLo, NULL}, &BBParmBlock, &drvMsgLo};
msgDset devBBSiSoftMsg = { 6, { NULL, NULL, drvMsg_initSi, NULL,
drvMsg_procSi, NULL}, &BBParmBlock, &drvMsgSi};
msgDset devBBSoSoftMsg = { 6, { NULL, NULL, drvMsg_initSo, NULL,
drvMsg_procSo, NULL}, &BBParmBlock, &drvMsgSo};
msgDset devBBWfSoftMsg = { 6, { NULL, NULL, drvMsg_initWf, NULL,
drvMsg_procWf, NULL}, &BBParmBlock, &drvMsgWf};
/******************************************************************************
*
* DSET tables used for vxWorks tty ports.
*
******************************************************************************/
msgDset devVXAiSoftMsg = { 6, { VXreport, VXinit, drvMsg_initAi, NULL,
drvMsg_procAi, NULL}, &VXParmBlock, &drvMsgAi};
msgDset devVXAoSoftMsg = { 6, { NULL, NULL, drvMsg_initAo, NULL,
drvMsg_procAo, NULL}, &VXParmBlock, &drvMsgAo};
msgDset devVXBiSoftMsg = { 6, { NULL, NULL, drvMsg_initBi, NULL,
drvMsg_procBi, NULL}, &VXParmBlock, &drvMsgBi};
msgDset devVXBoSoftMsg = { 6, { NULL, NULL, drvMsg_initBo, NULL,
drvMsg_procBo, NULL}, &VXParmBlock, &drvMsgBo};
msgDset devVXMiSoftMsg = { 6, { NULL, NULL, drvMsg_initMi, NULL,
drvMsg_procMi, NULL}, &VXParmBlock, &drvMsgMi};
msgDset devVXMoSoftMsg = { 6, { NULL, NULL, drvMsg_initMo, NULL,
drvMsg_procMo, NULL}, &VXParmBlock, &drvMsgMo};
msgDset devVXLiSoftMsg = { 6, { NULL, NULL, drvMsg_initLi, NULL,
drvMsg_procLi, NULL}, &VXParmBlock, &drvMsgLi};
msgDset devVXLoSoftMsg = { 6, { NULL, NULL, drvMsg_initLo, NULL,
drvMsg_procLo, NULL}, &VXParmBlock, &drvMsgLo};
msgDset devVXSiSoftMsg = { 6, { NULL, NULL, drvMsg_initSi, NULL,
drvMsg_procSi, NULL}, &VXParmBlock, &drvMsgSi};
msgDset devVXSoSoftMsg = { 6, { NULL, NULL, drvMsg_initSo, NULL,
drvMsg_procSo, NULL}, &VXParmBlock, &drvMsgSo};
msgDset devVXWfSoftMsg = { 6, { NULL, NULL, drvMsg_initWf, NULL,
drvMsg_procWf, NULL}, &VXParmBlock, &drvMsgWf};
int softMsgDebug = 0;
static msgStrParm wrParms[] = {
{ "Parm 0 write string!\n\r", -1},
{ "wrParm-1 raw write string\n\r", -1 },
{ "123456789012", -1 },
{ "1234567890123", -1 },
{ "12345678901234", -1},
};
static msgFoParm foParms[] = {
{ "Parm 1 Value is: %lf\n\r" },
{ "pArM 2 VaLuE iS: %lf\n\r" },
{ "longout value is %ld\n\r" }
};
static msgFiParm fiParms[] = {
{ "%s %lf", 0, 50 },
{ "%lf", 0, 50 },
{ "%ld", 0, 50 },
};
static msgCmd cmds[] = {
{&drvMsgAi, READ_NDLY, {MSG_OP_WRITE, &wrParms[0]}, {MSG_OP_FAI, &fiParms[0]}, NULL, -1},
{&drvMsgAo, READ_NDLY, {MSG_OP_FAO, &foParms[0]}, {MSG_OP_NOP, NULL}, NULL, -1},
{&drvMsgAi, READ_NDLY, {MSG_OP_WRITE, &wrParms[1]}, {MSG_OP_FAI, &fiParms[1]}, NULL, -1},
{&drvMsgAo, READ_NDLY, {MSG_OP_FAO, &foParms[1]}, {MSG_OP_NOP, NULL}, NULL, -1},
{&drvMsgLi, READ_NDLY, {MSG_OP_WRITE, &wrParms[1]}, {MSG_OP_FLI, &fiParms[2]}, NULL, -1},
{&drvMsgLo, READ_NDLY, {MSG_OP_FLO, &foParms[2]}, {MSG_OP_NOP, NULL}, NULL, -1},
{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[2]}, {MSG_OP_NOP, NULL}, NULL, -1},
{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[3]}, {MSG_OP_NOP, NULL}, NULL, -1},
{&drvMsgBo, READ_NDLY, {MSG_OP_WRITE, &wrParms[4]}, {MSG_OP_NOP, NULL}, NULL, -1},
};
/******************************************************************************
*
* The devTy232ParmBlock contains vxWorks tty-driver specific extensions to
* the msgParmBlock structure.
*
******************************************************************************/
/* For vxWorks tty ports */
static devTy232ParmBlock parm232extension = {
0, /* Time window */
60, /* DMA time limit */
KILL_CRLF, /* loose the CRs and LFs */
0x0d, /* EOI character, always stop reading when I hit it */
9600, /* Baud rate to the machine at */
OPT_7_BIT /* 7-bit transfers */
};
/******************************************************************************
*
* The drvBB232ParmBlock contains the bitbus->RS232 specific extensions to the
* msgParmBlock structure.
*
******************************************************************************/
static drvBB232ParmBlock parmBB232extension = {
0,
9600
};
/******************************************************************************
*
* The parmBlock is used to define the relationship b/w the command table and
* the driverBlock.
*
******************************************************************************/
/* For records requesting Bitbus->232 */
static msgParmBlock BBParmBlock = {
&softMsgDebug,
NULL,
cmds,
sizeof(cmds) / sizeof(msgCmd),
"softMsg",
&drvBB232Block,
drvMsg_xactWork,
&parmBB232extension
};
/* For records requesting vxWorks tty */
static msgParmBlock VXParmBlock = {
&softMsgDebug,
NULL,
cmds,
sizeof(cmds) / sizeof(msgCmd),
"softMsg",
&drv232Block,
drvMsg_xactWork,
&parm232extension
};
/******************************************************************************
*
* These are used to add parameters to calls made to the init routines.
*
******************************************************************************/
/* For records requesting Bitbus->232 */
static long
BBinit(parm)
int parm;
{
return(drvMsg_initMsg(parm, &devBBAiSoftMsg));
}
static long
BBreport()
{
return(drvMsg_reportMsg(&devBBAiSoftMsg));
}
/* For records requesting vxWorks tty */
static long
VXinit(parm)
int parm;
{
return(drvMsg_initMsg(parm, &devVXAiSoftMsg));
}
static long
VXreport()
{
return(drvMsg_reportMsg(&devVXAiSoftMsg));
}

View File

@@ -1,308 +0,0 @@
/* devXxSr620Gpib.c */
/* share/src/devOpt $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 05-30-91 jrw Initial Release
*/
#define DSET_AI devAiSr620Gpib
#define DSET_AO devAoSr620Gpib
#define DSET_LI devLiSr620Gpib
#define DSET_LO devLoSr620Gpib
#define DSET_BI devBiSr620Gpib
#define DSET_BO devBoSr620Gpib
#define DSET_MBBO devMbboSr620Gpib
#define DSET_MBBI devMbbiSr620Gpib
#define DSET_SI devSiSr620Gpib
#define DSET_SO devSoSr620Gpib
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <taskLib.h>
#include <rngLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbDefs.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recSup.h>
#include <drvSup.h>
#include <link.h>
#include <module_types.h>
#include <dbCommon.h>
#include <aiRecord.h>
#include <aoRecord.h>
#include <biRecord.h>
#include <boRecord.h>
#include <mbbiRecord.h>
#include <mbboRecord.h>
#include <stringinRecord.h>
#include <stringoutRecord.h>
#include <longinRecord.h>
#include <longoutRecord.h>
#include <drvGpibInterface.h>
#include <devCommonGpib.h>
#define STATIC static
STATIC long init_dev_sup(), report();
STATIC int srqHandler();
static struct devGpibParmBlock devSupParms;
/******************************************************************************
*
* Define all the dset's.
*
* Note that the dset names are provided via the #define lines at the top of
* this file.
*
* Other than for the debugging flag(s), these DSETs are the only items that
* will appear in the global name space within the IOC.
*
******************************************************************************/
gDset DSET_AI = {6, {report, init_dev_sup, devGpibLib_initAi, NULL,
devGpibLib_readAi, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aiGpibWork, (DRVSUPFUN)devGpibLib_aiGpibSrq}};
gDset DSET_AO = {6, {NULL, NULL, devGpibLib_initAo, NULL,
devGpibLib_writeAo, NULL, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_aoGpibWork, NULL}};
gDset DSET_BI = {5, {NULL, NULL, devGpibLib_initBi, NULL,
devGpibLib_readBi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_biGpibWork, (DRVSUPFUN)devGpibLib_biGpibSrq}};
gDset DSET_BO = {5, {NULL, NULL, devGpibLib_initBo, NULL,
devGpibLib_writeBo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_boGpibWork, NULL}};
gDset DSET_MBBI = {5, {NULL, NULL, devGpibLib_initMbbi, NULL,
devGpibLib_readMbbi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbbiGpibWork, (DRVSUPFUN)devGpibLib_mbbiGpibSrq}};
gDset DSET_MBBO = {5, {NULL, NULL, devGpibLib_initMbbo, NULL,
devGpibLib_writeMbbo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_mbboGpibWork, NULL}};
gDset DSET_SI = {5, {NULL, NULL, devGpibLib_initSi, NULL,
devGpibLib_readSi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)&devGpibLib_stringinGpibWork, (DRVSUPFUN)devGpibLib_stringinGpibSrq}};
gDset DSET_SO = {5, {NULL, NULL, devGpibLib_initSo, NULL,
devGpibLib_writeSo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_stringoutGpibWork, NULL}};
gDset DSET_LI = {5, {NULL, NULL, devGpibLib_initLi, NULL,
devGpibLib_readLi, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_liGpibWork, (DRVSUPFUN)devGpibLib_liGpibSrq}};
gDset DSET_LO = {5, {NULL, NULL, devGpibLib_initLo, NULL,
devGpibLib_writeLo, (DRVSUPFUN)&devSupParms,
(DRVSUPFUN)devGpibLib_loGpibWork, NULL}};
int sr620Debug = 0; /* debugging flags */
extern int ibSrqDebug;
/*
* Use the TIME_WINDOW defn to indicate how long commands should be ignored
* for a given device after it times out. The ignored commands will be
* returned as errors to device support.
*/
#define TIME_WINDOW 600 /* 10 seconds on a getTick call */
#define DMA_TIME 60
static char *offOnList[] = { "Off", "On" };
static struct devGpibNames offOn = { 2, offOnList, NULL, 1 };
static char *offOffList[] = { "Off", "Off" };
static struct devGpibNames offOff = { 2, offOffList, NULL, 1 };
static char *onOnList[] = { "On", "On" };
static struct devGpibNames onOn = { 2, onOnList, NULL, 1 };
static char *initNamesList[] = { "Init", "Init" };
static struct devGpibNames initNames = { 2, initNamesList, NULL, 1 };
static char *disableEnableList[] = { "Disable", "Enable" };
static struct devGpibNames disableEnable = { 2, disableEnableList, NULL, 1 };
static char *resetList[] = { "Reset", "Reset" };
static struct devGpibNames reset = { 2, resetList, NULL, 1 };
static char *lozHizList[] = { "50 OHM", "IB_Q_HIGH Z" };
static struct devGpibNames lozHiz = {2, lozHizList, NULL, 1};
static char *invertNormList[] = { "INVERT", "NORM" };
static struct devGpibNames invertNorm = { 2, invertNormList, NULL, 1 };
static char *fallingRisingList[] = { "FALLING", "RISING" };
static struct devGpibNames fallingRising = { 2, fallingRisingList, NULL, 1 };
static char *clearList[] = { "CLEAR", "CLEAR" };
static struct devGpibNames clear = { 2, clearList, NULL, 1 };
/******************************************************************************
*
* Array of structures that define all GPIB messages
* supported for this type of instrument.
*
******************************************************************************/
static struct gpibCmd gpibCmds[] =
{
/* Param 0, init the instrument */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "*RST;*WAI;*CLS;*ESE 1", NULL, 0, 32,
NULL, 0, 0, NULL, &reset, -1},
/* Param1 */
{&DSET_LO, GPIBWRITE, IB_Q_HIGH, NULL, "mode %ld", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param2 */
{&DSET_LO, GPIBWRITE, IB_Q_HIGH, NULL, "ARMM %ld", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 3 */
{&DSET_BO, GPIBCMD, IB_Q_HIGH, "*OPC %d", NULL, 0, 32,
NULL, 0, 0, NULL, &offOn, -1},
/* Param 4 send an mean?0 and generate an SRQ when finished */
{&DSET_AI, GPIBREADW, IB_Q_HIGH, "*SRE 16;meas?0;*wai;*SRE 0", "%lf", 0, 32,
NULL, 0, 0, NULL, NULL, -1},
/* Param 5 */
{&DSET_AI, GPIBREAD, IB_Q_HIGH, "XALL?", NULL, 0, 32,
NULL, 0, 0, NULL, NULL, -1}
};
/* The following is the number of elements in the command array above. */
#define NUMPARAMS sizeof(gpibCmds)/sizeof(struct gpibCmd)
/******************************************************************************
*
* This is invoked by the linkTask when an SRQ is detected from a device
* operated by this module.
*
* It calls the work routine associated with the type of record expecting
* the SRQ response.
*
* No semaphore locks are needed around the references to anything in the
* hwpvt structure, because it is static unless modified by the linkTask and
* the linkTask is what will execute this function.
*
* THIS ROUTINE WILL GENERATE UNPREDICTABLE RESULTS IF...
* - the MAGIC_SRQ_PARM command is a GPIBREADW command.
* - the device generates unsolicited SRQs while processing GPIBREADW commands.
*
* In general, this function will have to be heavily modified for each device
* type that SRQs are to be supported. This is because the serial poll byte
* format varies from device to device.
*
******************************************************************************/
#define SR620_ERROR 0x04 /* bit masks for status indicators */
#define SR620_TIC 0x08
#define SR620_MAV 0x10
#define SR630_ESB 0x20
STATIC int srqHandler(struct hwpvt *phwpvt, int srqStatus)
{
int status = IDLE; /* assume device will be idle when finished */
if (sr620Debug || ibSrqDebug)
logMsg("srqHandler(0x%08.8X, 0x%02.2X): called\n", phwpvt, srqStatus);
if (srqStatus & SR620_MAV) /* is data available to be read? */
{
/* Invoke the command-type specific SRQ handler */
if (phwpvt->srqCallback != NULL)
status = ((*(phwpvt->srqCallback))(phwpvt->parm, srqStatus));
else if (sr620Debug || ibSrqDebug)
logMsg("Unsolicited operation complete from SR620 device support!\n");
}
else
{
if (phwpvt->unsolicitedDpvt != NULL)
{
if (sr620Debug || ibSrqDebug)
logMsg("Unsolicited SRQ being handled from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
((struct gpibDpvt*)(phwpvt->unsolicitedDpvt))->head.callback.callback = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->process;
((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->head.callback.priority = ((struct gpibDpvt *)(phwpvt->unsolicitedDpvt))->processPri;
callbackRequest((CALLBACK*)phwpvt->unsolicitedDpvt);
}
else
{
if (sr620Debug || ibSrqDebug)
logMsg("Unsolicited SRQ ignored from link %d, device %d, status = 0x%02.2X\n",
phwpvt->link, phwpvt->device, srqStatus);
}
}
return(status);
}
/******************************************************************************
*
* Initialization for device support
* This is called one time before any records are initialized with a parm
* value of 0. And then again AFTER all record-level init is complete
* with a param value of 1.
*
******************************************************************************/
STATIC long
init_dev_sup(int parm)
{
if(parm==0) {
devSupParms.debugFlag = &sr620Debug;
devSupParms.respond2Writes = -1;
devSupParms.timeWindow = TIME_WINDOW;
devSupParms.hwpvtHead = 0;
devSupParms.gpibCmds = gpibCmds;
devSupParms.numparams = NUMPARAMS;
devSupParms.magicSrq = -1;
devSupParms.name = "devXxSr620Gpib";
devSupParms.dmaTimeout = DMA_TIME;
devSupParms.srqHandler = srqHandler;
devSupParms.wrConversion = 0;
}
return(devGpibLib_initDevSup(parm, &DSET_AI));
}
/******************************************************************************
*
* Print a report of operating statistics for all devices supported by this
* module.
*
******************************************************************************/
STATIC long
report(void)
{
return(devGpibLib_report(&DSET_AI));
}

View File

@@ -1,9 +0,0 @@
TOP=../../..
include $(TOP)/configure/CONFIG
DIRS = ansi old
include $(TOP)/configure/RULES_DIRS

View File

@@ -1,26 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
INC += drvAt5Vxi.h
INC += drvHp1404a.h
INC += drvHpe1368a.h
INC += drvKscV215.h
INC += drvMz8310.h
INC += drvStc.h
SRCS += drvAt5Vxi.c
SRCS += drvHp1404a.c
SRCS += drvHpe1368a.c
SRCS += drvHpe1445a.c
SRCS += drvKscV215.c
SRCS += drvMz8310.c
SRCS += drvStc.c
#SRCS += drvCaenV265.c
#SRCS += drvVmic2534.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -1,49 +0,0 @@
TOP=../../../..
include $(TOP)/configure/CONFIG
CMPLR = TRAD
VX_WARN_YES = -Wall -pedantic
# Only the 68k cross-compiler has no "nobitfield" option -kuk-
ifeq ($(ARCH_CLASS),68k)
USR_CFLAGS = -fshared-data -fvolatile -mnobitfield
else
USR_CFLAGS = -fshared-data -fvolatile
endif
#Following only to make Gpib stuff build
INC += drvBitBusErr.h
INC += drvBitBusInterface.h
INC += drvGpib.h
INC += drvGpibErr.h
INC += drvGpibInterface.h
INC += drvHiDEOSGpib.h
INC += drvJgvtr1.h
INC += drvOms.h
INC += steppermotor.h
SRCS += module_types.c
SRCS += drvBb902.c
SRCS += drvBb910.c
SRCS += drvComet.c
SRCS += drvCompuSm.c
SRCS += drvDvx.c
SRCS += drvFp.c
SRCS += drvFpm.c
SRCS += drvGpib.c
SRCS += drvJgvtr1.c
SRCS += drvOms.c
SRCS += drvVmi4100.c
SRCS += drvXy010.c
SRCS += drvXy210.c
SRCS += drvXy220.c
SRCS += drvXy240.c
SRCS += drvXy566.c
OBJS_vxWorks += $(SRCS:%.c=%)
include $(TOP)/configure/RULES

View File

@@ -1,22 +0,0 @@
The following are unbundled
drvBB232.c
drvBB232.h
drvBitBus.c
drvBitBus.h
drvBitBusErr.h
drvBitBusInterface.h
drvMsg.h
drvMsg.c
drvRs232.h
The following should not be used
drvTy232.h
drvRs232.c
The following is a BIG PROBLEM because drvGpib.c include and uses it.
For now it is both here are in the unbundled version
drvBitBusInterface.h

View File

@@ -1,637 +0,0 @@
/* comet_driver.c */
/* base/src/drv $Id$ */
/*
* Author: Leo R. Dalesio
* Date: 5-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 joh 071092 added argument to calloc()
* .02 joh 071092 stripped the hkv2f specific portion off the comet
* std addr base specification and left it at base
* addr zero which is most likely wrong.
* .03 joh 071492 use extended (A32) address space
* instead of standard (A24) address space
* for the base address of the waveform memory
* (changed arg to sysBusToLocalAdrs()
* .04 joh 071592 fixed to use correct size when incrementing
* to the waveform memory of the second card
* .05 joh 071592 modified A16 & A32 base addr to match AT8
* address standard
* .06 bg 071792 moved addresses to module_types.h
* .07 joh 080592 added io report routines
* .08 ms 080692 added comet_mode routine, modified comet_driver
* and cometDoneTask to allow an external routine
* to control hardware scan mode. Added variable
* scan_control to flag operating mode.
* .09 mrk 082692 added DSET
* .10 joh 082792 fixed uninitialized csr pointer in comet_driver()
* function
* .11 lrd 091692 add signal support
* .12 joh 092992 card number validation now based on module_types.h.
* signal number checking now based on the array element
* count.
* .13 mrk 080293 Added call to taskwdInsert
* .14 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*/
static char *sccsID = "@(#)drvComet.c 1.11\t9/16/92";
/*
* Code Portions
*
* comet_init()
* comet_driver(card, pcbroutine, parg)
* cometDoneTask()
* comet_io_report()
* comet_mode(card,mode,arg,val)
*
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <iv.h>
#include <vme.h>
#include "module_types.h"
#include "task_params.h"
#include "fast_lock.h"
#include "drvSup.h"
#include "dbDefs.h"
#include "dbScan.h"
#include "taskwd.h"
#define COMET_NCHAN 4
#define COMET_CHANNEL_MEM_SIZE 0x20000 /* bytes */
#define COMET_DATA_MEM_SIZE (COMET_CHANNEL_MEM_SIZE*COMET_NCHAN)
static short scan_control; /* scan type/rate (if >0 normal, <=0 external control) */
/* comet conrtol register map */
struct comet_cr{
unsigned char csrh; /* control and status register - high byte */
unsigned char csrl; /* control and status register - low byte */
unsigned char lcrh; /* location status register - high byte */
unsigned char lcrl; /* location status register - low byte */
unsigned char gdcrh; /* gate duration status register - high byte*/
unsigned char gdcrl; /* gate duration status register - low byte */
unsigned char cdr; /* channel delay register */
unsigned char acr; /* auxiliary control register */
char pad[0x100-8];
};
/* defines for the control status register - high byte */
#define DIGITIZER_ACTIVE 0x80 /* 1- Active */
#define ARM_DIGITIZER 0x40 /* 1- Arm the digitizer */
#define CIRC_BUFFER_ENABLED 0x20 /* 0- Stop when memory is full */
#define WRAP_MODE_ENABLED 0x10 /* 0- Disable wrap around */
#define AUTO_RESET_LOC_CNT 0x08 /* 1- Reset addr to 0 on trigger */
#define EXTERNAL_TRIG_ENABLED 0x04 /* 1- use external clk to trigger */
#define EXTERNAL_GATE_ENABLED 0x02 /* 0- use pulse start conversion */
#define EXTERNAL_CLK_ENABLED 0x01 /* 0- uses the internal clock */
/* commands for the COMET digitizer */
#define COMET_INIT_CSRH
#define COMET_INIT_READ
/* mode commands for the COMET digitizer */
#define READREG 0
#define WRITEREG 1
#define SCANCONTROL 2
#define SCANSENSE 3
#define SCANDONE 4
/* register selects */
#define COMET_CSR 0
#define COMET_LCR 1
#define COMET_GDCR 2
#define COMET_CDACR 3
/* defines for the control status register - low byte */
#define SOFTWARE_TRIGGER 0x80 /* 1- generates a software trigger */
#define UNUSED 0x60
#define CHAN_DELAY_ENABLE 0x10 /* 0- digitize on trigger */
#define DIG_RATE_SELECT 0x0f
/* digitizer rates - not defined but available for 250KHz to 122Hz */
#define COMET_5MHZ 0x0000
#define COMET_2MHZ 0x0001
#define COMET_1MHZ 0x0002
#define COMET_500KHZ 0x0003
/* defines for the auxiliary control register */
#define ONE_SHOT 0x10
#define ALL_CHANNEL_MODE 0x80
/* comet configuration data */
struct comet_config{
struct comet_cr *pcomet_csr; /* pointer to the control/status register */
unsigned short *pdata; /* pointer to data area for this COMET card */
void (*psub)(); /* subroutine to call on end of conversion */
void *parg[4]; /* argument to return to the arming routine */
FAST_LOCK lock; /* mutual exclusion lock */
IOSCANPVT ioscanpvt;
unsigned long nelements; /* number of elements to digitize/read */
};
/* task ID for the comet done task */
int cometDoneTaskId;
struct comet_config *pcomet_config;
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvComet={
2,
report,
init};
/*
* cometDoneTask
*
* wait for comet waveform record cycle complete
* and call back to the database with the waveform size and address
*
*/
void
cometDoneTask()
{
register unsigned card;
register struct comet_config *pconfig;
while(TRUE)
{
if (scan_control <= 0)
taskDelay(2);
else
{
taskDelay(scan_control);
/* printf("DoneTask: entering for loop...\n"); */
/* check each card for end of conversion */
for(card=0, pconfig = pcomet_config; card < 2;card++, pconfig++)
{
/* is the card present */
if (!pconfig->pcomet_csr)
{
if (card == 0)
{
/*
printf("DoneTask: checking card present?...\n");
printf("DoneTask: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr);
*/
}
continue;
}
/* is the card armed */
if (!pconfig->psub)
{
if (card == 0)
{
/* printf("DoneTask: checking card armed?...\n"); */
}
continue;
}
/* is the digitizer finished conversion */
/* printf("pconfig->pdata: %x \n", pconfig->pdata); */
if (*(pconfig->pdata+pconfig->nelements) == 0xffff)
{
if (card == 0)
{
/* printf("DoneTask: finished conversion?...\n"); */
}
continue;
}
/* printf("DoneTask: pcomet_config->pcomet_csr %x...\n",pcomet_config->pcomet_csr); */
/* printf("DoneTask: DONE\n"); */
#if 0
/* reset each of the control registers */
pconfig->pcomet_csr->csrh = pconfig->pcomet_csr->csrl = 0;
pconfig->pcomet_csr->lcrh = pconfig->pcomet_csr->lcrl = 0;
pconfig->pcomet_csr->gdcrh = pconfig->pcomet_csr->gdcrl = 0;
pconfig->pcomet_csr->acr = 0;
#endif
/* clear the pointer to the subroutine to allow rearming */
/* pconfig->psub = NULL; */
/* post the event */
/* - is there a bus error for long references to this card?? copy into VME mem? */
if(pconfig->parg[0])
{
(*pconfig->psub)(pconfig->parg[0],pconfig->pdata);
}
if(pconfig->parg[1])
{
(*pconfig->psub)(pconfig->parg[1],(((char*)pconfig->pdata)+0x20000));
}
if(pconfig->parg[2])
{
(*pconfig->psub)(pconfig->parg[2],(((char*)pconfig->pdata)+0x40000));
}
if(pconfig->parg[3])
{
(*pconfig->psub)(pconfig->parg[3],(((char*)pconfig->pdata)+0x60000));
}
}
}
}
}
/*
* COMET_INIT
*
* intialize the driver for the COMET digitizer from omnibyte
*
*/
int comet_init()
{
register struct comet_config *pconfig;
short readback,got_one,card;
int status;
struct comet_cr *pcomet_cr;
unsigned char *extaddr;
/* free memory and delete tasks from previous initialization */
if (cometDoneTaskId)
{
taskwdRemove(cometDoneTaskId);
if ((status = taskDelete(cometDoneTaskId)) < 0)
logMsg("\nCOMET: Failed to delete cometDoneTask: %d",status);
}
else
{
pcomet_config = (struct comet_config *)calloc(wf_num_cards[COMET],sizeof(struct comet_config));
if (pcomet_config == 0)
{
logMsg("\nCOMET: Couldn't allocate memory for the configuration data");
return(0);
}
}
/* get the standard and short address locations */
if ((status = sysBusToLocalAdrs(VME_AM_SUP_SHORT_IO,wf_addrs[COMET],&pcomet_cr)) != OK){
logMsg("\nCOMET: failed to map VME A16 base address\n");
return(0);
}
if ((status = sysBusToLocalAdrs(VME_AM_EXT_SUP_DATA,wf_memaddrs[COMET],&extaddr)) != OK){
logMsg("\nCOMET: failed to map VME A32 base address\n");
return(0);
}
/* determine which cards are present */
got_one = FALSE;
pconfig = pcomet_config;
for ( card = 0;
card < 2;
card++, pconfig++, pcomet_cr++, extaddr+= COMET_DATA_MEM_SIZE){
/* is the card present */
if (vxMemProbe(pcomet_cr,READ,sizeof(readback),&readback) != OK)
{
continue;
}
if (vxMemProbe(extaddr,READ,sizeof(readback),&readback) != OK)
{
logMsg("\nCOMET: Found CSR but not data RAM %x\n",extaddr);
continue;
}
/* initialize the configuration data */
pconfig->pcomet_csr = pcomet_cr;
pconfig->pdata = (unsigned short *) extaddr;
got_one = TRUE;
FASTLOCKINIT(&pcomet_config[card].lock);
/* initialize the card */
pcomet_cr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT;
pcomet_cr->csrl = COMET_1MHZ;
pcomet_cr->lcrh = pcomet_cr->lcrl = 0;
pcomet_cr->gdcrh = 0;
pcomet_cr->gdcrl = 1;
pcomet_cr->cdr = 0;
/* run it once */
pcomet_cr->csrl |= SOFTWARE_TRIGGER;
taskDelay(1);
/* reset */
pcomet_cr->csrl = COMET_5MHZ;
pcomet_cr->acr = ONE_SHOT | ALL_CHANNEL_MODE;
scanIoInit(&pconfig->ioscanpvt);
} /*end of for loop*/
/* initialization for processing comet digitizers */
if(got_one)
{
/* start the waveform readback task */
scan_control = 2; /* scan rate in vxWorks clock ticks */
cometDoneTaskId = taskSpawn("cometWFTask",WFDONE_PRI,WFDONE_OPT,WFDONE_STACK,(FUNCPTR) cometDoneTask);
taskwdInsert(cometDoneTaskId,NULL,NULL);
}
return(0);
}
static long report(level)
int level;
{
comet_io_report(level);
return(0);
}
static long init()
{
comet_init();
return(0);
}
/*
* COMET_DRIVER
*
* initiate waveform read
*
*/
int comet_driver(card, signal, pcbroutine, parg, nelements)
register short card;
register unsigned short signal;
unsigned int *pcbroutine;
unsigned int *parg; /* pointer to the waveform record */
unsigned long nelements;
{
register struct comet_cr *pcomet_csr;
register struct comet_config *pconfig;
/* printf("comet_driver: BEGIN...\n"); */
/* printf("comet_driver: nelements: %d ...\n",nelements); */
/* check for valid card number */
if(card >= wf_num_cards[COMET])
return ERROR;
pconfig = (pcomet_config+card);
if(signal >= NELEMENTS(pconfig->parg))
return ERROR;
pconfig->nelements = nelements * 2;
/* printf("comet_driver: check for card present...\n"); */
/* check for card present */
if(!pconfig->pcomet_csr) return ERROR;
/* mutual exclusion area */
FASTLOCK(&pconfig->lock);
/* printf("comet_driver: mark the card as armed...\n"); */
/* mark the card as armed */
/* if (pconfig->parg[signal] != 0) */
pconfig->parg[signal] = parg;
/* if (pconfig->psub) return; */
pconfig->psub = (void (*)()) pcbroutine;
/* exit mutual exclusion area */
FASTUNLOCK(&pconfig->lock);
pcomet_csr = pconfig->pcomet_csr;
/* reset each of the control registers */
pcomet_csr->csrh = pcomet_csr->csrl = 0;
pcomet_csr->lcrh = pcomet_csr->lcrl = 0;
pcomet_csr->gdcrh = pcomet_csr->gdcrl = 0;
pcomet_csr->acr = 0;
/* arm the card */
*(pconfig->pdata+pconfig->nelements) = 0xffff;
/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */
if (scan_control > 0)
{
#if 0 /* for debugging purposes */
pcomet_csr->gdcrh = 0x03; /* # samples per channel */
pcomet_csr->gdcrl = 0xe8; /* # samples per channel */
#endif
pcomet_csr->gdcrh = (pconfig->nelements >> 8) & 0xff; /* # samples per channel */
pcomet_csr->gdcrl = pconfig->nelements & 0xff; /* # samples per channel */
pcomet_csr->acr = ONE_SHOT | ALL_CHANNEL_MODE; /* disarm after the trigger */
pcomet_csr->csrl = COMET_5MHZ; /* sample at 5MhZ */
/* arm, reset location counter to 0 on trigger, use external trigger */
pcomet_csr->csrh = ARM_DIGITIZER | AUTO_RESET_LOC_CNT | EXTERNAL_TRIG_ENABLED;
/* printf("comet_driver: gdcrh: %x gdcrl: %x nelements: %x\n ",pcomet_csr->gdcrh,pcomet_csr->gdcrl, pconfig->nelements); */
}
else
pcomet_csr->csrh |= ARM_DIGITIZER;
/* printf("comet_driver: pconfig->pcomet_csr %x...\n",pconfig->pcomet_csr); */
/* printf("comet_driver: END...\n"); */
return OK;
}
/*
* COMET_IO_REPORT
*
* print status for all cards in the specified COMET address range
*/
int comet_io_report(level)
short int level;
{
struct comet_config *pconfig;
unsigned card;
unsigned nelements;
int status;
pconfig = pcomet_config;
for(card=0; card < wf_num_cards[COMET]; card++){
if(!pconfig->pcomet_csr)
continue;
printf( "WF: COMET:\tcard=%d\n", card);
if (level >= 2){
printf("enter the number of elements to dump:");
status = scanf("%d",&nelements);
if(status == 1){
comet_dump(card, nelements);
}
}
pconfig++;
}
return OK;
}
/*
* comet_dump
*
*/
int comet_dump(card, n)
unsigned card;
unsigned n;
{
unsigned short *pdata;
unsigned short *psave;
unsigned short *pbegin;
unsigned short *pend;
if (card >= wf_num_cards[COMET])
return ERROR;
pdata = pcomet_config[card].pdata;
psave = (unsigned short *) malloc(n * sizeof(*psave));
if(!psave){
return ERROR;
}
pbegin = psave;
pend = &psave[n];
for( pdata = pcomet_config[card].pdata;
psave<pend;
pdata++,psave++){
*psave = *pdata;
}
psave = pbegin;
for( ;
psave<pend;
psave++){
if((psave-pbegin)%8 == 0){
printf("\n\t");
}
printf("%04X ", *psave);
}
printf("\n");
free(pbegin);
return OK;
}
/*
* comet_mode
*
* controls and reports operating mode
*
*/
int comet_mode(card,mode,arg,val)
short card;
unsigned short mode, arg, val;
{
unsigned char *cptr;
if (card >= wf_num_cards[COMET])
return ERROR;
if (!pcomet_config[card].pcomet_csr)
return ERROR;
switch (mode)
{
case READREG:
/*cptr = (unsigned char *)pcomet_config[card].pcomet_csr;
for (i = 0; i < 6; i++, cptr++)
printf("%x %x\n",cptr,*cptr);*/
cptr = (unsigned char *)pcomet_config[card].pcomet_csr; /* point to offset 0 */
cptr += arg<<1; /* build new offset */
val = (*cptr++)<<8; /* read value and return */
val |= *cptr;
return val;
break;
case WRITEREG:
cptr = (unsigned char *)pcomet_config[card].pcomet_csr;
cptr += arg<<1;
*cptr++ = val>>8;
*cptr = val;
break;
case SCANCONTROL:
scan_control = val;
break;
case SCANSENSE:
return scan_control;
break;
case SCANDONE:
if (!pcomet_config[card].psub)
return ERROR;
/*pcomet_config[card].psub = NULL;*/ /* clear the pointer to subroutine to allow rearming */
(*pcomet_config[card].psub)(pcomet_config[card].parg,0xffff,pcomet_config[card].pdata);
break;
default:
return ERROR;
}
return OK;
}
/*********************************************/
int cometGetioscanpvt(card,scanpvt)
short card;
IOSCANPVT *scanpvt;
{
register struct comet_config *pconfig;
pconfig=pcomet_config;
pconfig+=card;
if ((card >= wf_num_cards[COMET]) || (card < 0)) /* make sure hardware exists */
return(0);
/*
This is present in the mix driver...I don't know if I really need it.
if (!pconfig->present)
return(0);
*/
*scanpvt = pconfig->ioscanpvt;
return(0);
}

View File

@@ -1,868 +0,0 @@
/* drvCompuSm.c */
/* base/src/drv $Id$ */
/*
* subroutines and tasks that are used to interface to the Compumotor 1830
* stepper motor drivers
*
* Author: Bob Dalesio
* Date: 01-03-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 02-07-90 lrd add command to read the motor status
* .02 04-11-90 lrd made velocity mode motor go active
* .03 04-12-90 lrd only allow one connection to a motor
* .04 04-13-90 lrd add externally initiated motor motion monitoring
* .05 09-05-91 joh updated for v5 vxWorks
* .06 10-09-91 lrd monitor for external motion once every 2 seconds
* not at 30 Hz (.04 was not implemented correctly)
* .06 11-31-91 bg added compu_sm_io_report. Added sysBusToLocalAdrs()
* for addressing.
* .07 03-02-92 bg added level and ability to print raw values to
* compu_sm_io_report for level > 0.
* .08 05-04-92 bg added compu_sm_reset and rebootHookAdd so ioc can be
* rebooted with control X.
* .09 06-25-92 bg Combined drvCompuSm.c and compu_sm_driver.c
* .10 06-26-92 bg Added level to compu_sm_io_report in drvCompuSm
* structure
* .11 06-29-92 joh took file ptr arg out of io report
* .12 08-06-92 joh merged compu sm include file
* .13 08-27-92 joh silenced ANSI C function proto warning
* .14 08-27-92 joh fixed no epics init
* .15 08-02-93 mrk Added call to taskwdInsert
* .16 10-29-93 jba Fixed max number of cards to use module_types.c
* Fixed error in calculating card addresses
* .17 04-09-96 ric Added SM_FIND_LIMIT, SM_FIND_HOME
*/
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <semLib.h> /* library for semaphore support */
#include <intLib.h> /* library for semaphore support */
#include <vxLib.h> /* library for semaphore support */
#include <rebootLib.h> /* library for semaphore support */
#include <wdLib.h>
#include <rngLib.h> /* library for ring buffer support */
/* drvCompuSm.c - Driver Support Routines for CompuSm */
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvSup.h>
#include <module_types.h>
#include <steppermotor.h>
#include <task_params.h>
#include <taskwd.h>
long compu_sm_io_report();
long compu_driver_init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvCompuSm={
2,
compu_sm_io_report,
compu_driver_init};
/* compumotor vme interface information */
#define MAX_COMPU_MOTORS 8
#define RESP_SZ 16 /* card returns 16 chars - cmd & resp */
#define RESPBUF_SZ (RESP_SZ+1) /* intr routine also passes motor no. */
/* Control Byte bit definitions for the Compumotor 1830 */
/* bits 0 and 1 are not used */
#define CBEND 0x04 /* end of command string */
#define CBLMR 0x08 /* last message byte read */
#define CBCR 0x10 /* command ready in cm_idb */
#define CBMA 0x20 /* message accepted from odb */
#define CBEI 0x40 /* enable interrupts */
#define CBBR 0x80 /* board reset */
#define SND_MORE CBCR | CBEI /* more chars to send */
#define SND_LAST CBEND | SND_MORE /* last char being sent */
#define RD_MORE CBMA | CBEI /* more chars to read */
#define RD_LAST CBLMR | RD_MORE /* last byte we need to read */
/* Status Byte bit definitions */
#define SBIRDY 0x10 /* idb is ready */
/* Structure used for communication with a Compumotor 1830
** Motor Controller. The data buffer is repeated 64 times
** on even word addresses (0xXXXXXX1,0xXXXXX5...) and the
** control location is repeated 64 times on odd word
** addresses (0xXXXXX3, 0xXXXXX7...). The registers must
** be read and written as bytes.
*/
struct compumotor {
char cm_d1; /* not accessable */
char cm_idb; /* input data buffer */
char cm_d2; /* not accessable */
char cm_cb; /* control byte */
char cm_d3[0x100-4]; /* fill to next standard address */
};
/* This file includes defines for all compumotor 1830 controller
** commands. */
#define SM_NULL 0x0 /* Null command */
#define SM_INT 0x1 /* Interrupt X */
#define SM_WRT_STAT 0x8 /* Write X to the user defined status bits */
#define SM_SET_STAT 0x9 /* Set user defined status bit number X */
#define SM_CLR_STAT 0xa /* Clear user defined status bit number X */
#define SM_SET_PROG 0xb /* Set programmable output bit X */
#define SM_CLR_PROG 0xc /* Clear programmable output bit X */
#define SM_WRT_PROG 0xd /* Write X to the programmable output bits */
#define SM_DEF_X_TO_Y 0xf /* Define bit X to indicate state Y */
#define SM_TOG_JOG 0x10 /* Disable/enable the JOG inputs */
#define SM_DEF_JOG 0x11 /* Define JOG input functions */
#define SM_TOG_REM_PWR 0x12 /* Turn off/on remote power shutdown */
#define SM_TOG_REM_SHUT 0x13 /* Disable/enable the "remote shutdown" bit */
#define SM_SET_CW_MOTN 0x14 /* Set CW motion equal to +- */
#define SM_TOG_POS_MTN 0x18 /* Turn off/on post-move position maintenance */
#define SM_TOG_STOP_STL 0x19 /* Turn off/on termination on stall detect */
#define SM_REP_X_Y 0x20 /* Repeat the following X commands Y times */
#define SM_REP_TIL_CONT 0x21 /* Repeat the following X commands
until a CONTINUE is received */
#define SM_WAIT_CONT 0x28 /* Wait for a CONTINUE */
#define SM_WAIT_MILLI 0x29 /* Wait X milliseconds */
#define SM_WAIT_SECOND 0x2a /* Wait X seconds */
#define SM_WAIT_MINUTE 0x2b /* Wait X minutes */
#define SM_WAIT_TRIGGER 0x2c /* Wait for trigger X to go active */
#define SM_DEF_A_OP_POS 0x2e /* Define the abs open-loop position as X */
#define SM_DEF_A_CL_POS 0x2f /* Define absolute closed-loop position */
#define SM_DEF_ABS_ZERO 0x30 /* Define the present position as the
absolute zero position */
#define SM_DEF_VEL_ACC 0x31 /* Define default velocity and acceleration */
#define SM_MOV_DEFAULT 0x32 /* Perform the default move (trapezoidal
continuous) */
#define SM_MOV_REL_POS 0x33 /* Go to relative position X at default
velocity and acceleration */
#define SM_MOV_ABS_POS 0x34 /* Go to absolute position X at default
velocity and acceleration */
#define SM_MOV_REL_ENC 0x35 /* Go to relative encoder position X */
#define SM_MOV_ABS_ENC 0x36 /* Go to absolute encoder position X */
#define SM_DEF_OP_HOME 0x38 /* Define HOME location (open loop */
#define SM_DEF_CL_HOME 0x38 /* Define HOME location (closed loop) */
#define SM_MOV_HOME_POS 0x39 /* Go HOME at the default velocity and
acceleration */
#define SM_MOV_HOME_ENC 0x3a /* Go to encoder HOME at the default
velocity and acceleration */
#define SM_DO_MOV_X 0x40 /* Perform move number X */
#define SM_DO_SEQ_X 0x41 /* Perform sequence buffer X */
#define SM_DO_VEL_STR 0x42 /* Perform the velocity streaming buffer */
#define SM_CONT 0x48 /* CONTINUE (perform next command) */
#define SM_OP_LOOP_MODE 0x50 /* Enter open loop indexer mode */
#define SM_VEL_DIS_MODE 0x51 /* Enter velocity-distance streaming mode */
#define SM_VEL_TIM_MODE 0x52 /* Enter velocity-time streaming mode */
#define SM_STOP 0x70 /* STOP motion */
#define SM_DSC_SEQ 0x71 /* Discontinue the sequence buffer */
#define SM_SSP_SEQ 0x72 /* Suspend the sequence buffer;
wait for a CONTINUE to resume */
#define SM_DSC_SNGL 0x73 /* Discontinue any singular command
currently being performed */
#define SM_STOP_ON_TRG 0x74 /* STOP motion when trigger X goes active */
#define SM_DSC_SEQ_TRG 0x75 /* Discontinue the sequence buffer when
trigger X goes active */
#define SM_SSP_SEQ_TRG 0x76 /* Suspend sequence buffer when trigger
X goes active */
#define SM_DSC_SNGL_TRG 0x77 /* Discontinue any singular command when
trigger X goes active */
#define SM_KILL 0x78 /* Kill motion */
#define SM_KILL_SEQ 0x79 /* Kill the sequence buffer */
#define SM_KILL_SEQ_SNGL 0x7a /* Kill current sequence singular command;
wait for CONTINUE */
#define SM_KILL_VEL_STR 0x7b /* Kill the velocity streaming buffer */
#define SM_KILL_ON_TRG 0x7c /* Kill motion when trigger X goes active */
#define SM_KILL_SEQ_TRG 0x7d /* Kill the sequence buffer when trigger
X goes active */
#define SM_KL_SQSNG_TRG 0x7e /* Kill current sequence singular command
when trigger X goes active; wait for
a continue */
#define SM_KL_VLSTR_TRG 0x7f /* Kill the velocity streaming buffer
when trigger X goes active */
#define SM_GET_B_REL_POS 0x80 /* Request position relative to the
beginning of the current move */
#define SM_GET_E_REL_POS 0x81 /* Request position relative to the
end of the current move */
#define SM_GET_H_REL_POS 0x82 /* Request position relative to the home
limit switch */
#define SM_GET_Z_REL_POS 0x83 /* Request position relative to the
absolute zero position */
#define SM_GET_CUR_DIR 0x84 /* Request current direction */
#define SM_GET_VEL 0x85 /* Request current velocity */
#define SM_GET_ACC 0x86 /* Request current acceleration */
#define SM_GET_MOV_STAT 0x88 /* Request current move status */
#define SM_GET_LIM_STAT 0x89 /* Request state of the limit switches */
#define SM_GET_HOME_STAT 0x8a /* Request state of the HOME switch */
#define SM_GET_TRV_DIR 0x8b /* Request direction of travel */
#define SM_GET_MOT_MOV 0x8c /* Request whether motor is moving or not */
#define SM_GET_MOT_CONST 0x8d /* Request whether motor is at constant,
nonzero velocity or not */
#define SM_GET_MOT_ACC 0x8e /* Request whether motor is or is not
accelerating */
#define SM_GET_MOT_DEC 0x8f /* Request whether motor is or is not
decelerating */
#define SM_GET_MODE 0x90 /* Request present mode */
#define SM_GET_MV_PARM 0x91 /* Request move parameters for move number X */
#define SM_GET_SEQ_CMMD 0x92 /* request commands stored in the
sequence buffer */
#define SM_GET_MVDEF_STAT 0x93 /* Request state of the move definitions */
#define SM_GET_TRG_STAT 0x94 /* Request state of trigger inputs */
#define SM_GET_JOG_STAT 0x95 /* Request state of JOG inputs */
#define SM_GET_Z_STAT 0x96 /* Request state of the Channel Z home input */
#define SM_GET_OUT_STAT 0x97 /* Request the state of the programmable
output bits */
#define SM_GET_REL_ENC 0x98 /* Request relative encoder count */
#define SM_GET_REL_ERR 0x99 /* Request relative error from desired
closed loop position */
#define SM_GET_ABS_ENC 0x9a /* Request absolute encoder count */
#define SM_GET_SLIP_STAT 0x9b /* Request slip detect status */
#define SM_GET_RATIO 0x9c /* Request motor pulse to encoder pulse ratio */
#define SM_GET_RESOLTN 0x9d /* Request motor resolution */
#define SM_GET_BACK_SIG 0x9e /* Request backlash sigma (motor steps)*/
#define SM_GET_ALG 0x9f /* Request position maintenance alg.
const, and max velocity */
#define SM_INT_NXT_MOV 0xa0 /* Interrupt at start of next move */
#define SM_INT_ALL_MOV 0xa1 /* Interrupt at the start of every move */
#define SM_INT_NXT_NZ 0xa2 /* Interrupt at constant nonzero velocity
of next move */
#define SM_INT_ALL_NZ 0xa3 /* Interrupt at constant nonzero velocity
of every move */
#define SM_INT_NXT_END 0xa4 /* Interrupt at next end of motion */
#define SM_INT_ALL_END 0xa5 /* Interrupt at every end of motion */
#define SM_INT_NXT_STL 0xa6 /* Interrupt on next stall detect */
#define SM_INT_ALL_STL 0xa7 /* Interrupt on every stall detect */
#define SM_INT_NXT_PLIM 0xa8 /* Interrupt the next time the motor
hits the positive limit */
#define SM_INT_ALL_PLIM 0xa9 /* Interrupt on every positive limit */
#define SM_INT_NXT_NLIM 0xaa /* Interrupt the next time the motor
hits the negative limit */
#define SM_INT_ALL_NLIM 0xab /* Interrupt on every negative limit */
#define SM_INT_TRG 0xac /* Interrupt on trigger X active */
#define SM_INT_INHBT 0xaf /* Inhibit all interrupts */
#define SM_DEF_RATIO 0xb0 /* Define motor pulse to encoder pulse ratio */
#define SM_DEF_RESOLTN 0xb1 /* Define motor resolution */
#define SM_DEF_BACK_SIG 0xb2 /* Define backlash sigma (motor steps)*/
#define SM_DEF_ALG 0xb3 /* Define position maintenance algorithm
const, and max velocity */
#define SM_DEF_TEETH 0xb4 /* Define the number of rotor teeth */
#define SM_DEF_DEADBAND 0xb5 /* Def the deadband region in encoder pulses */
#define SM_DEF_REL_TRP 0xc8 /* Define move X as a relative,
trapezoidal move */
#define SM_DEF_ABS_TRP 0xcb /* Define move X as an absolute
trapezoidal move */
#define SM_DEF_CONT 0xce /* Define move X as a continuous move */
#define SM_DEF_REL_CL 0xd4 /* Define move X, define it as relative,
closed-loop move */
#define SM_DEF_ABS_CL 0xd5 /* Def move X as an abs, closed- loop move */
#define SM_DEF_STSTP_VEL 0xd6 /* Define the start/stop velocity */
#define SM_DEL_MOV_X 0xd7 /* Delete move X */
#define SM_END_SEQ_DEF 0xd8 /* End definition of sequence buffer */
#define SM_BEG_SEQ_DEF 0xd9 /* Begin definition of sequence buffer */
#define SM_DEL_SEQ_X 0xda /* Delete sequence buffer X */
#define SM_LD_VD_DATA 0xe0 /* Place data into the velocity-distance buffer */
#define SM_LD_VT_DATA 0xe1 /* Place data into the velocity-time buffer */
#define SM_GET_FREE_BYT 0xe2 /* Request number of free bytes in vel-
streaming/sequence buffer */
#define SM_DEF_VS_CMMD 0xee /* Define command to be executed during
the velocity streaming buffer */
#define SM_GET_NUM_REV 0xfd /* Request software part number and revision */
#define SM_TEST_SWITCH 0xff /* Perform the test switch function */
#define VELOCITY_MODE 0
#define MAX_COMMANDS 256
#define COMPU_INT_LEVEL 5
/* array of pointers to stepper motor driver cards present in system */
struct compumotor *pcompu_motors[MAX_COMPU_MOTORS];
LOCAL SEM_ID compu_wakeup; /* compumotor data request task semaphore */
/* response variables */
LOCAL SEM_ID smRespSem; /* task semaphore */
LOCAL RING_ID smRespQ; /* ring buffer */
int smRespId; /* task id */
#define RESP_Q_SZ (RESPBUF_SZ * 50) /* response ring buffer size */
/* interrupt buffers */
unsigned char sm_responses[MAX_COMPU_MOTORS][RESPBUF_SZ];
unsigned short counts[MAX_COMPU_MOTORS];
/* counts for debugging */
long dbicounts; /* counts number of times through interrupt routine */
long dbrcounts; /* counts number of times through response routine */
long dbscounts; /* counts number of times through send routine */
/* VME memory Short Address Space is set up in gta_init */
static int *compu_addr;
/* motor information */
struct compu_motor{
short active; /* flag to tell the oms_task if the motor is moving */
int callback; /* routine in database library to call with status */
int callback_arg; /* argument to callback routine */
short update_count;
short mode;
short motor_resolution;
};
struct compu_motor compu_motor_array[MAX_COMPU_MOTORS];
/* Forward reference. */
VOID compu_sm_reset();
VOID compu_sm_stat();
/* motor status - returned to the database library routines */
struct motor_data compu_motor_data_array[MAX_COMPU_MOTORS];
/* moving status bit descriptions */
#define CW_LIMIT 0x01 /* clockwise???? limit */
#define CCW_LIMIT 0x02 /* counter-clockwise???? limit */
#define DIRECTION 0x08 /* direction bit */
#define MOVING 0x10 /* moving status bit */
#define CONSTANT_VEL 0x20 /* constant velocity */
/* directions in driver card-ese */
#define CLKW 0 /* clockwise direction */
#define CCLKW 1 /* counter clockwise direction */
/*
* Code Portions:
*
* smCmdTask Task which writes commands to the hardware
* smRespTask Task which places reponses from the hardware into resp buffers
* sm_intr Interrupt Handler - collects response data from the hardware
* sm_drv_init Initializes all motors, semaphores, ring buffers and interrupts
* sm_driver Subroutine for outside world to issue commands to motors
* motor_select Subroutine to setting callback arg and verifying no other user
* motor_deselect Subroutine to free the motor for other users
*
* Interaction Chart:
* -------------- -------------------
* / \ / \
* | smRespTask | | smCmdTask |
* \ / \ /
* --------------- -------------------
* ^ ^ |
* TAKES | | GETS |
* | | |
* -------------- --------------- |
* Resp Semaphore Response Queue |
* -------------- --------------- |
* ^ ^ |
* GIVES | | PUTS |
* | | |
* --------------- |
* / \ |
* | sm_intr | |
* \ / |
* --------------- |
* ^ reads responses writes commands |
* | from hardware to hardware V
*/
/*
* COMPU_RESP_TASK
*
* converts readback from the compumotor 1830 cards into a structure that
* is returned to the database library layer every .1 second while a motor
* is moving
*/
int compu_resp_task()
{
unsigned char resp[RESPBUF_SZ];
register struct motor_data *pmotor_data;
FOREVER {
/* wait for somebody to wake us up */
semTake (smRespSem, WAIT_FOREVER);
(dbrcounts < 0xFFFF ? dbrcounts++: 0);
/* the response buffer contains: */
/* 0 - motor number */
/* 1 - the command which solicited this response */
/* 2 - the first byte of the response */
/* process requests in the command ring buffer */
while (rngBufGet(smRespQ,(char *)resp,RESPBUF_SZ) == RESPBUF_SZ){
pmotor_data = &compu_motor_data_array[resp[0]];
/* convert argument */
switch(resp[1]){
case (SM_GET_VEL):
{
register long *pvelocity = (long *)(&resp[3]);
pmotor_data->velocity = *pvelocity;
break;
}
case (SM_GET_MOV_STAT):
{
register struct compu_motor *pcompu_motor;
register int (*psmcb_routine)();
pcompu_motor = &compu_motor_array[resp[0]];
pmotor_data->moving = (resp[2] & MOVING)?1:0;
pmotor_data->constant_velocity = (resp[2] & CONSTANT_VEL)?1:0;
pmotor_data->cw_limit = (resp[2] & CW_LIMIT)?1:0;
pmotor_data->ccw_limit = (resp[2] & CCW_LIMIT)?1:0;
pmotor_data->direction = (resp[2] & DIRECTION)?1:0;
/* post every .1 second or not moving */
if ((pcompu_motor->update_count-- <= 0)
|| (pmotor_data->moving == 0)){
if (pcompu_motor->callback != 0){
(int)psmcb_routine = pcompu_motor->callback;
(*psmcb_routine)(pmotor_data,pcompu_motor->callback_arg);
}
if (pmotor_data->moving){
/* motors are reported at 10 Hz */
pcompu_motor->update_count = 3;
}else{
pcompu_motor->active = FALSE;
pcompu_motor->update_count = 0;
}
}
break;
}
case (SM_GET_ABS_ENC):
{
register long *pencoder = (long *)(&resp[2]);
pmotor_data->encoder_position = *pencoder;
break;
}
case (SM_GET_Z_REL_POS):
{
register long *pmotor = (long *)(&resp[4]);
pmotor_data->motor_position = *pmotor;
break;
}
case (SM_GET_CUR_DIR):
pmotor_data->direction = (resp[2] == 0xff)?CLKW:CCLKW;
break;
}
}
}
}
/* Data request commands for the positional and velocity mode motors */
char compu_velo_reqs[] = { SM_GET_VEL, SM_GET_MOV_STAT };
#define NUM_VEL_REQS 2
char compu_pos_reqs[] = { SM_GET_ABS_ENC, SM_GET_Z_REL_POS, SM_GET_MOV_STAT };
#define NUM_POS_REQS 3
/*
* COMPU_TASK
*
* task to solicit currnet status from the compumotor 1830 cards while they
* are active
*/
int compu_task()
{
register short inactive_count;
register short card;
register short i;
register struct compumotor *pmotor;
register char *preqs;
/* inactive motors get monitored once every 2 seconds in case they are */
/* being moved manually */
inactive_count = 60;
while(1){
/* This task is run 30 times a second */
taskDelay(2);
for (card = 0; card < sm_num_cards[CM57_83E]; card++){
pmotor = pcompu_motors[card];
if (pmotor == 0) continue;
if ((compu_motor_array[card].active)
|| (inactive_count <=0)){
if (compu_motor_array[card].mode == VELOCITY_MODE){
preqs = &compu_velo_reqs[0];
/* request status data */
for (i = 0; i < NUM_VEL_REQS; i++,preqs++)
compu_send_msg(pmotor,preqs,1);
}else{
preqs = &compu_pos_reqs[0];
/* request status data */
for (i = 0; i < NUM_POS_REQS; i++,preqs++)
compu_send_msg(pmotor,preqs,1);
}
}
}
if (--inactive_count < 0) inactive_count = 60;
}
}
/*
* COMPU_INTR
*
* interrupt vector for the compumotor 1830 card
*/
int compu_intr(mdnum)
register int mdnum;
{
register struct compumotor *pmtr; /* memory port to motor card */
register int key;
key = intLock();
/* pointer to the compumotor card interface */
pmtr = pcompu_motors[mdnum];
if (pmtr == 0)
{
intUnlock(key);
return(0);
};
(dbicounts < 0xFFFF ? dbicounts++: 0);
/* place the response byte into the appropriate response buffer */
sm_responses[mdnum][counts[mdnum]] = pmtr->cm_idb;
counts[mdnum]++;
/* when the buffer is full pass it onto the repsonse task */
if (counts[mdnum] == RESPBUF_SZ){
if (rngBufPut(smRespQ,(char *)sm_responses[mdnum],RESPBUF_SZ) != RESPBUF_SZ)
logMsg("smRespQ %d - Full\n",mdnum);
else
semGive (smRespSem);
/* the zero-th byte is the motor number */
counts[mdnum] = 1; /* start with command */
/* inform the hardware that the response is complete */
pmtr->cm_cb = RD_LAST;
}else{
/* inform the hardware there is more to send */
pmtr->cm_cb = RD_MORE;
}
intUnlock(key);
return(0);
}
/*
* COMPU_DRIVER_INIT
*
* initialization for the compumotor 1830 card
*/
long
compu_driver_init(){
register short i;
int status;
struct compumotor *pmtr; /* memory port to motor card */
int cok = CBBR; /*to reset board */
short none_found; /* flags a steppermotor is present */
int taskId;
struct compumotor *pmtrb;
/* intialize each driver which is present */
none_found = TRUE;
rebootHookAdd((FUNCPTR)compu_sm_reset);
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
sm_addrs[CM57_83E],
(int **)&compu_addr);
if (status != OK){
printf("%s: failed to map A16 base\n", __FILE__);
return ERROR;
}
pmtrb = (struct compumotor *)compu_addr;
for (i = 0; i < sm_num_cards[CM57_83E]; i++) {
pmtr = (struct compumotor *)((int)pmtrb + (i<<8));
/* initialize when card is present */
if (vxMemProbe(&pmtr->cm_cb,WRITE,1,&cok) != ERROR){
none_found = FALSE;
pcompu_motors[i] = pmtr; /* ptr to interface */
intConnect((MD_INT_BASE+i)*4,compu_intr,i); /* interrupt enable */
sysIntEnable(COMPU_INT_LEVEL);
/* init interrupt receive buffers */
sm_responses[i][0] = i; /* motor number */
counts[i] = 1; /* buffer index */
}else{
pcompu_motors[i] = 0; /* flags no board is present */
}
}
if (none_found) return(0);
/* initialize the response task ring buffer */
if ((smRespQ = rngCreate(RESP_Q_SZ)) == (RING_ID)NULL)
panic ("sm_init: cmRespQ\n");
/* intialize the semaphores which awakens the sleeping *
* stepper motor command task and the stepper motor response task */
if(!(smRespSem=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in compu_driver_init");
if(!(compu_wakeup=semBCreate(SEM_Q_FIFO,SEM_EMPTY)))
errMessage(0,"semBcreate failed in compu_driver_init");
/* spawn the sleeping motor driver command and response tasks */
smRespId =
taskSpawn("compu_resp_task",SMRESP_PRI,SMRESP_OPT,SMRESP_STACK,compu_resp_task);
taskwdInsert(smRespId,NULL,NULL);
taskId = taskSpawn("compu_task",SMRESP_PRI,SMRESP_OPT,2000,compu_task);
taskwdInsert(taskId,NULL,NULL);
return(0);
}
short trigger = 0;
/*
* COMPU_DRIVER
*
* driver interface to the database library layer
*/
int compu_driver(card, channel, value_flag,arg1,arg2)
register short card;
short channel;
short value_flag;
register int arg1;
register int arg2;
{
register int *pint;
register short *pshort;
short i;
char compu_msg[20];
i = 0;
/* verify the stepper motor driver card is present */
if ((card < 0) || (card > sm_num_cards[CM57_83E]) || (!pcompu_motors[card]))
return (-1);
switch (value_flag){
case (SM_MODE):
/* set the motor mode */
compu_motor_array[card].mode = arg1;
break;
case (SM_VELOCITY):
compu_motor_data_array[card].velocity = arg1;
compu_motor_data_array[card].accel = arg2;
/* set the velocity */
compu_msg[0] = SM_DEF_VEL_ACC;
compu_msg[1] = 0; /* time is in seconds */
compu_msg[2] = 0;
pint = (int *)&compu_msg[3]; /* velocity */
*pint = arg1;
pint++; /* acceleration */
*pint = arg2;
compu_send_msg(pcompu_motors[card],compu_msg,11);
break;
case (SM_FIND_HOME): /* Move to a home switch */
break; /* Not supported by this device */
case (SM_FIND_LIMIT): /* Move to a limit switch */
arg1 = arg1 >= 0 ? 0x000fffff : -0x000fffff;
/* break purposely left out to continue with SM_MOVE */
case (SM_MOVE):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(0);
/* move the motor */
i = 0;
compu_msg[i++] = SM_MOV_REL_POS;
pint = (int *)&compu_msg[i];
*pint = arg1;
i += 4;
compu_send_msg(pcompu_motors[card],compu_msg,i);
/* set the motor to active */
compu_motor_array[card].active = TRUE;
/* wakeup the compu task */
semGive(compu_wakeup);
break;
case (SM_MOTION):
if (arg1 == 0){
compu_msg[0] = SM_STOP;
compu_send_msg(pcompu_motors[card],compu_msg,1);
}else if (compu_motor_array[card].mode == VELOCITY_MODE){
compu_msg[0] = SM_MOV_DEFAULT;
compu_msg[1] = arg2; /* direction */
compu_send_msg(pcompu_motors[card],compu_msg,2);
compu_motor_array[card].active = TRUE;
}
/* wakeup the compu task */
semGive(compu_wakeup);
break;
case (SM_CALLBACK):
/* put the callback routine and argument into the data array */
i = 0;
if (compu_motor_array[card].callback != 0) return(-1);
compu_motor_array[card].callback = arg1;
compu_motor_array[card].callback_arg = arg2;
break;
case (SM_SET_HOME):
if (compu_motor_array[card].mode == VELOCITY_MODE)
return(OK);
/* set the motor and encoder position to zero */
compu_msg[0] = SM_DEF_ABS_ZERO;
compu_send_msg(pcompu_motors[card],compu_msg,1);
break;
case (SM_ENCODER_RATIO):
compu_motor_array[card].motor_resolution = arg1;
/* set the encoder ratio */
compu_msg[0] = SM_DEF_RATIO;
pshort = (short *)&compu_msg[1];
*pshort = arg1; /* motor resolution */
pshort++;
*pshort = arg2; /* encoder resolution */
compu_send_msg(pcompu_motors[card],compu_msg,5);
/* set the motor resolution */
compu_msg[0] = SM_DEF_RESOLTN;
pshort = (short *)&compu_msg[1];
*pshort = 0;
pshort++;
*pshort = arg1; /* motor resolution */
compu_send_msg(pcompu_motors[card],compu_msg,5);
break;
case (SM_READ):
/* set the motor to active */
compu_motor_array[card].active = TRUE;
/* wakeup the compu task */
semGive(compu_wakeup);
break;
}
return (OK);
}
/*
* COMPU_SEND_MSG
*
* send a message to the compumotor 1830
*/
int wait_count;
int compu_send_msg(pmotor,pmsg,count)
register struct compumotor *pmotor;
register char *pmsg;
register short count;
{
(dbscounts < 0xFFFF ? dbscounts++: 0);
/* write out this command one byte at a time */
while (count){
/* wait for the driver to be ready */
while ((pmotor->cm_cb & SBIRDY) == 0){
taskDelay(0);
wait_count++;
}
/* next byte in the input data buffer of compumotor */
pmotor->cm_idb = *pmsg;
pmsg++;
count--;
/* tell compumotor more or complete */
if (count == 0){
pmotor->cm_cb = SND_LAST;
}else{
pmotor->cm_cb = SND_MORE;
}
}
return(0);
}
/*
* COMPU_SM_IO_REPORT
*
* send a message to the compumotor 1830
*/
long compu_sm_io_report(level)
short int level;
{
register int i;
for (i = 0; i < sm_num_cards[CM57_83E]; i++){
if (pcompu_motors[i]){
printf("SM: CM1830: card %d\n",i);
if (level > 0)
compu_sm_stat(i);
}
}
return OK;
}
VOID compu_sm_stat(compu_num)
short int compu_num;
{
printf("\tCW limit = %d\t,CCW limit = %d\tMoving = %d\tDirection = %d\n",
compu_motor_data_array[compu_num].cw_limit,
compu_motor_data_array[compu_num].ccw_limit,
compu_motor_data_array[compu_num].moving,
compu_motor_data_array[compu_num].direction);
printf("\tConstant Velocity = %d\t, Velocity = %d\t \n",
compu_motor_data_array[compu_num].constant_velocity,
compu_motor_data_array[compu_num].velocity);
printf("\tAcceleration = %d\tEncoder Position = %d\tMotor Position = %d\n",
compu_motor_data_array[compu_num].accel,
compu_motor_data_array[compu_num].encoder_position,
compu_motor_data_array[compu_num].motor_position);
}
/*
*
* Subroutine to be called during a CTL X reboot. Inhibits interrupts.
*
*/
VOID compu_sm_reset()
{
short int i;
char compu_msg[20];
for (i = 0; i < sm_num_cards[CM57_83E]; i++){
if (pcompu_motors[i]){
compu_msg[0] = SM_INT_INHBT;
compu_send_msg(pcompu_motors[i],compu_msg,1);
}
}
}

View File

@@ -1,532 +0,0 @@
/* drvFp.c */
/* base/src/drv $Id$
* routines which are used to test and interface with the
* FP10S fast protect module
*
* Author: Matthew Stettler
* Date: 6-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 joh 070992 integrated into GTACS & added std header
* .02 joh 070992 merged in include file fp.h
* .03 joh 070992 converted some symbols to LOCAL so they stay out
* of the vxWorks global symbol table
* .04 joh 070992 took out sysSetBCL() and substituted
* sysIntEnable() so this will not be hkv2f
* specific.
* .05 joh 070992 added INUM_TO_IVEC so this will be less
* 68k dependence (added include of iv.h)
* .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the
* interrupt level can be easily changed
* .07 joh 070992 changed some printf() calls to logMsg()
* so that driver diagnostics will show up in
* the log
* .08 joh 071092 now fetches base addr from module_types.h
* .09 joh 071092 added io_report routine
* .10 joh 071092 added scan task wakeup from ISR
* .11 joh 071092 moved ivec allocation to module_types.h
* .12 joh 072792 added soft reboot int disable
* .13 joh 082792 converted to V5 vxorks
* .14 mrk 090192 support epics I/O event scan, and added DRVET
* .15 mrk 080293 Add call to taskwdInsert
* .16 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*/
/*
*
* Routines:
*
* fp_init Finds and initializes fast protect cards
* fp_driver System interface to FP10S modules
* fp_int Interrupt service routine
* fp_en Enables/disables interrupts (toggles)
* fp_mode Sets interrupt reporting mode
* fp_reboot Clean up for soft reboots
*
* Diagnostic Routines:
*
* fp_srd Reads current local inputs and enables
* fp_frd Reads last failure register
* fp_csrd Reads control/status register
* fp_read Command line interface to fp_driver
* fp_dump Prints all fast protect status to console
* fp_monitor Monitor all cards and print failure data to
* console
*
* Routines Return:
*
* -1 No card present
* -2 Interrupt connection error
* -3 Semaphore creation error
* -4 addressing error
* -5 no memory
* 0-8 successfull completion, or # of cards found
*
*/
static char *sccsId = "@(#)drvFp.c 1.12\t6/4/93";
#include "vxWorks.h"
#include "stdlib.h"
#include "stdio.h"
#include "intLib.h"
#include "rebootLib.h"
#include "vme.h"
#include "taskLib.h"
#include <iv.h> /* in h/68k if this is compiling for a 68xxx */
#include "module_types.h"
#include <dbDefs.h>
#include <drvSup.h>
#include <taskwd.h>
#include <dbScan.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvFp={
2,
report,
init};
static long report()
{
fp_io_report();
return(0);
}
static long init()
{
fp_init(0);
return(0);
}
/* general constants */
#define FP_INTLEV 5 /* interrupt level */
#define FP_BUFSIZ 8 /* input buffer size */
/* csr bit definitions */
#define CSR_RST 0x1 /* reset status */
#define CSR_CMD1 0x2 /* force local fail */
#define CSR_IEN 0x4 /* interrupt enable */
#define CSR_UDEF0 0x8 /* undefined */
#define CSR_I0 0x10 /* interrupt level bit #1 */
#define CSR_I1 0x20 /* interrupt level bit #2 */
#define CSR_I2 0x40 /* interrupt level bit #3 */
#define CSR_UDEF1 0x80 /* undefined */
#define CSR_CARM0_L 0x100 /* latched carrier monitor #0 (one shot) */
#define CSR_CARM1_L 0x200 /* latched carrier monitor #1 (freq mon) */
#define CSR_OPTIC 0x400 /* optical carrier input enabled */
#define CSR_CARM 0x800 /* carrier OK */
#define CSR_LFAIL0 0x1000 /* local fail #0 (pal monitor) */
#define CSR_LFAIL1 0x2000 /* local fail #1 (fpga monitor) */
#define CSR_CMON 0x4000 /* clock fail (one shot) */
#define CSR_CHNG 0x8000 /* enable switch configuration change */
/* csr mask definitions */
#define CSR_STM 0xff00 /* status mask */
#define CSR_IM 0x70 /* interrupt level mask */
/* driver status */
#define DRV_MOM 0x010000 /* momentary fault */
#define DRV_LOC 0x020000 /* local fault */
#define DRV_REM 0x040000 /* remote fault */
#define DRV_CLR 0x080000 /* fault cleared */
#define DRV_HWF 0x800000 /* hardware fault */
/* operating modes */
#define FP_NMSG 0 /* no messages to console */
#define FP_TMSG 1 /* terse messages to console */
#define FP_FMSG 2 /* full messages to console */
#define FP_RUN 3 /* normal operating mode */
/* register address map for FP10s */
struct fp1
{
unsigned short csr; /* control and status register */
unsigned short srd; /* current status */
unsigned short frd; /* latched status */
unsigned short ivec; /* interrupt vector */
char end_pad[0xff-0x8]; /* pad to 256 byte boundary */
};
/* fast protect control structure */
struct fp_rec
{
struct fp1 *fptr; /* pointer to device registers */
unsigned int drvstat; /* fast protect physical inputs */
unsigned short lastswitch; /* previous enable switch data */
short type; /* device type */
short num; /* device number */
short fp_vector; /* interrupt vector */
short mode; /* operating mode */
unsigned int int_num; /* interrupt number */
IOSCANPVT ioscanpvt;
};
static struct fp_rec *fp; /* fast protect control structure */
static int fp_num; /* # of fast protect cards found -1 */
static SEM_ID fp_semid; /* semaphore for monitor task */
static void fp_reboot();
/*
* fp_int
*
* interrupt service routine
*
*/
int fp_int(card)
unsigned card;
{
register struct fp_rec *ptr = &fp[card];
register struct fp1 *regptr;
unsigned short temp0, temp1, temp2;
regptr = ptr->fptr;
temp0 = regptr->csr;
temp1 = regptr->frd;
temp2 = regptr->srd;
switch (ptr->mode)
{
case FP_TMSG:
logMsg("fast protect interrupt!\n");
logMsg("csr status = %x\n",temp0);
break;
case FP_FMSG:
logMsg("fast protect #%d fault! fault input = %x enable switches = %x\n",
ptr->num,temp1 & 0xff,temp2>>8);
logMsg("csr status = %x\n",temp0);
break;
case FP_RUN:
ptr->drvstat = temp2; /* save last switch data */
ptr->drvstat |= temp1<<16; /* save fault data */
ptr->drvstat |= (temp0 & 0xff00)<<16; /* csr status bits */
if ((temp1 ^ (temp2>>8)) || (temp0 & CSR_CHNG)) /* fault or enable change */
semGive(fp_semid); /* wake up monitor */
/*
* wakeup the interrupt driven scanner
*/
scanIoRequest(fp[card].ioscanpvt);
break;
}
ptr->int_num++; /* log interrupt */
regptr->csr |= CSR_RST; /* clear status and rearm */
regptr->csr ^= CSR_RST;
return(0);
}
/*
* fp_init
*
* initialization routine for FP10s fast protect modules
*
*
*/
int fp_init(addr)
unsigned int addr;
{
int i;
short junk;
short intvec = AT8FP_IVEC_BASE;
struct fp1 *ptr;
int status;
fp = (struct fp_rec *) calloc(bi_num_cards[AT8_FP10S_BI], sizeof(*fp));
if(!fp){
return -5;
}
if(!addr){
addr = bi_addrs[AT8_FP10S_BI];
}
status = sysBusToLocalAdrs( VME_AM_SUP_SHORT_IO, addr, &ptr);
if(status<0){
logMsg("VME shrt IO addr err in the slave fast protect driver\n");
return(-4);
}
status = rebootHookAdd(fp_reboot);
if(status<0){
logMsg("%s: reboot hook add failed\n", __FILE__);
}
for (i = 0;
(i < bi_num_cards[AT8_FP10S_BI]) && (vxMemProbe(ptr,READ,2,&junk) == OK);
i++,ptr++) {
/* register initialization */
ptr->csr = 0x0000; /* disable interface */
fp[i].fptr = ptr; /* hardware location */
fp[i].fp_vector = intvec++; /* interrupt vector */
ptr->ivec = fp[i].fp_vector; /* load vector */
fp[i].mode = FP_NMSG; /* set default mode (no messages) */
fp[i].int_num = 0; /* initialize interrupt number */
fp[i].type = 10; /* board type */
fp[i].num = i; /* board number */
/* initialize input buffer */
fp[i].drvstat = ptr->srd; /* initialize enable switch data */
fp[i].drvstat |= ptr->frd<<16; /* initialize fault data */
fp[i].drvstat |= (ptr->csr & 0xff00)<<16; /* csr status bits */
/* set up interrupt handler */
ptr->csr |= FP_INTLEV<<4; /* level 5 interrupt */
if (intConnect(INUM_TO_IVEC(fp[i].fp_vector),fp_int,i) != OK)
return(-2); /* abort if can't connect */
sysIntEnable(FP_INTLEV);
ptr->csr |= 0x0001;
ptr->csr ^= 0x0001; /* clear status bits */
if (ptr->csr & CSR_OPTIC)
logMsg("fast protect #%d optically coupled\n",i);
else
logMsg("fast protect #%d elecrically coupled\n",i);
/* start up module */
fp[i].fptr->csr |= CSR_IEN; /* enable interrupts */
fp[i].mode = FP_RUN; /* normal run mode */
scanIoInit(&fp[i].ioscanpvt);
}
fp_num = i - 1; /* record max card # */
/* create the semaphore */
fp_semid = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if ((int)fp_semid == 0) /* abort if can't create semaphore */
return(-3);
return(i); /* return # found */
}
/*
*
* fp_reboot()
*
* turn off interrupts to avoid ctrl X reboot problems
*/
LOCAL
void fp_reboot()
{
int i;
if(!fp){
return;
}
for (i = 0; i < bi_num_cards[AT8_FP10S_BI]; i++){
if(!fp[i].fptr){
continue;
}
fp[i].fptr->csr &= ~CSR_IEN;
}
}
/*
* fp_en
*
* interrupt enable/disable
* (toggles the interrupt enable - joh)
*
*/
int fp_en(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
fp[card].fptr->csr = fp[card].fptr->csr ^ CSR_IEN;
if (fp[card].fptr->csr & CSR_IEN)
printf("fast protect interrupts enabled\n");
else
printf("fast protect interrupts disabled\n");
return 0;
}
/*
* fp_mode
*
* set interrupt reporting mode
*
*/
int fp_mode(card,mode)
short card, mode;
{
if (card < 0 || (card > fp_num))
return -1;
fp[card].mode = mode;
return 0;
}
/*
* fp_srd
*
* read current local inputs and enable switches
*
*/
int fp_srd(card,option)
short card;
short option;
{
if (card > fp_num) return -1;
if (!option)
printf("local inputs = %x enable switches = %x\n",fp[card].fptr->srd & 0xff,
fp[card].fptr->srd>>8);
return fp[card].fptr->srd;
}
/*
* fp_frd
*
* read latched local inputs
*
*/
int fp_frd(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
return fp[card].fptr->frd & 0xff;
}
/*
* fp_csrd
*
* read csr contents
*
*/
int fp_csrd(card)
short card;
{
if (card < 0 || (card > fp_num))
return -1;
return fp[card].fptr->csr & 0xff77;
}
/*
* fp_driver
*
* epics interface to fast protect
*
*/
int fp_driver(card,mask,prval)
register unsigned short card;
unsigned int mask;
register unsigned int *prval;
{
register unsigned int temp;
if (card > fp_num) return -1;
temp = fp[card].drvstat & 0xffff0000; /* latched status info */
temp |= fp[card].fptr->srd; /* current switches & inputs */
*prval = temp & mask;
return 0;
}
/*
* fp_read
*
* command line interface to fp_driver
*
*/
int fp_read(card)
short card;
{
unsigned int fpval,ret;
if ((ret = fp_driver(card,0xffffffff,&fpval)) != 0)
return ret;
printf("Card #%d enable switches = %x inputs = %x\n",card,(fpval & 0x0000ff00)>>8,
fpval & 0x000000ff);
printf("csr status = %x last fault = %x\n",fpval>>24,(fpval & 0x00ff0000)>>16);
printf("raw readback = %x\n",fpval);
return 0;
}
/*
* fp_dump
*
* dump fast protect status to console
*
*/
int fp_dump()
{
int i;
printf("Fast protect status (fault and CSR are latched):\n");
printf("Card#\tenables\tinputs\tfault\tCSR status\n");
for(i = 0; i < (fp_num + 1); i++)
printf("%d\t%x\t%x\t%x\t%x\n",i,fp[i].fptr->srd>>8,fp[i].fptr->srd & 0xff,
(fp[i].drvstat & 0x00ff0000)>>16,fp[i].drvstat>>24);
return i;
}
/*
* fp_monitor
*
* monitor fast protect cards and report failures to console
*
*/
void fp_mon()
{
for(semTake(fp_semid,WAIT_FOREVER);fp_dump() != 0;semTake(fp_semid,WAIT_FOREVER));
}
int fp_monitor()
{
static char *name = "fpmon";
int tid;
if ((tid = taskNameToId(name)) != ERROR) {
taskwdRemove(tid);
taskDelete(tid);
}
if((tid = taskSpawn(name,25,VX_SUPERVISOR_MODE|VX_STDIO,
1000,fp_mon)) == ERROR) return -1;
taskwdInsert(tid,NULL,NULL);
return 0;
}
int fp_io_report(level)
int level;
{
int i;
for(i=0; i<=fp_num; i++){
printf("BI: AT8-FP-S: card %d\n", i);
}
return(0);
}
int fp_getioscanpvt(card,scanpvt)
short card;
IOSCANPVT *scanpvt;
{
if ((card >= bi_num_cards[AT8_FP10S_BI])) return(0);
*scanpvt = fp[card].ioscanpvt;
return(0);
}

View File

@@ -1,440 +0,0 @@
/* drvFpm.c */
/* base/src/drv $Id$ */
/*
* control routines for use with the FP10M fast protect master modules
*
* routines which are used to test and interface with the
* FP10S fast protect module
*
* Author: Matthew Stettler
* Date: 6-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 joh 070992 integrated into GTACS & added std header
* .02 joh 070992 merged in include file fpm.h
* .03 joh 070992 converted some symbols to LOCAL so they stay out
* of the vxWorks global symbol table
* .04 joh 070992 took out sysSetBCL() and substituted
* sysIntEnable() so this will not be hkv2f
* specific.
* .05 joh 070992 added INUM_TO_IVEC so this will be less
* 68k dependence (added include of iv.h)
* .06 joh 070992 FP_ILEV passed to call sysIntEnable() so that the
* interrupt level can be easily changed
* .07 joh 071092 now fetches base addr from module_types.h
* .08 joh 071092 added io report routine
* .09 joh 071092 allocate config structure at run time so that
* the users can adjust the number of cards without
* recompilation
* .10 joh 071092 moved ivec allocation to module_types.h
* .11 joh 072792 added soft reboot int disable
* .12 mrk 090292 added DRVET
* .13 mgb 080493 Removed V5/V4 and EPICS_V2 conditionals
*
*
* Routines:
*
* fpm_init Finds and initializes FP10M cards
* fpm_driver System interface to FP10M modules
* fpm_read Carrier control readback
* fpm_reboot clean up before soft reboots
*
* Daignostic Routines
* fpm_en Enables/disables interrupts (diagnostic enable)
* fpm_mode Sets interrupt reporting mode (logs mode
* changes to console)
* fpm_cdis Disables carrier from console
* fpm_fail Sets carrier failure mode
* fpm_srd Reads current carrier status
* fpm_write Command line interface to fpm_driver
*
* Routines return:
*
* -1 Nonexistent card
* -2 Interrupt connection error
* -3 no memory
* -4 VME short IO bus nonexistent
* 0-2 Successfull completion, or # cards found
*
*/
static char *sccsId = "@(#)drvFpm.c 1.12\t8/4/93";
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <rebootLib.h>
#include <intLib.h>
#include <vxLib.h>
#include <vme.h>
#include <iv.h> /* in h/68k if this is compiling for a 68xxx */
#include "module_types.h"
#include <dbDefs.h>
#include <drvSup.h>
static long report();
static long init();
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvFpm={
2,
report,
init};
static long report()
{
fpm_io_report();
return(0);
}
static long init()
{
fpm_init(0);
return(0);
}
/* general constants */
#define FPM_INTLEV 5 /* interrupt level */
/* control register bit definitions */
#define CR_CDIS 0x1 /* software carrier disable */
#define CR_FS0 0x2 /* fail select 0 */
#define CR_FS1 0x4 /* fail select 1 */
#define CR_FS2 0x8 /* fail select 2 */
#define CR_I0 0x10 /* interrupt level bit 0 */
#define CR_I1 0x20 /* interrupt level bit 1 */
#define CR_I2 0x40 /* interrupt level bit 2 */
#define CR_IEN 0x80 /* interrupt enable */
/* control register mask definitions */
#define CR_IM 0x70 /* interrupt level mask */
/* status register bit definitions */
#define SR_S0 0x1 /* error sequencer state bit 0 */
#define SR_S1 0x2 /* error sequencer state bit 1 */
#define SR_S2 0x3 /* error sequencer state bit 2 */
/* status register mask definitions */
#define SR_EM 0x7 /* error state mask */
/* operating modes */
#define FPM_NMSG 0 /* no messages to console */
#define FPM_TMSG 1 /* terse messages to console */
#define FPM_FMSG 2 /* full messages to console */
/* register address map for FP10M */
struct fp10m
{
unsigned short cr; /* control register */
unsigned short sr; /* status register */
unsigned short ivec; /* interrupt vector */
char end_pad[0xff-0x6]; /* pad to 256 byte boundary */
};
/* control structure */
struct fpm_rec
{
struct fp10m *fmptr; /* pointer to device registers */
short type; /* device type */
short num; /* board number */
short vector; /* interrupt vector */
short mode; /* operating mode */
unsigned int int_num; /* interrupt number */
};
static struct fpm_rec *fpm; /* fast protect control structure */
static int fpm_num; /* # cards found - 1 */
static void fpm_reboot();
/*
* fpm_int
*
* interrupt service routine
*
*/
int fpm_int(ptr)
register struct fpm_rec *ptr;
{
register struct fp10m *regptr;
regptr = ptr->fmptr;
switch (ptr->mode)
{
case FPM_TMSG:
logMsg("fast protect master interrupt!\n");
break;
case FPM_FMSG:
logMsg("fast protect master interrupt!\n");
logMsg("cr = %x sr = %x\n",regptr->cr,regptr->sr & 0x7);
break;
}
ptr->int_num++;
return(0);
}
/*
* fpm_init
*
* initialization for fp10m fast protect master modules
*
*/
int fpm_init(addr)
unsigned int addr;
{
int i;
short junk;
short intvec = AT8FPM_IVEC_BASE;
struct fp10m *ptr;
int status;
fpm = (struct fpm_rec *) calloc(
bo_num_cards[AT8_FP10M_BO],
sizeof(*fpm));
if(!fpm){
return -3;
}
if(!addr){
addr = bo_addrs[AT8_FP10M_BO];
}
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
addr,
&ptr);
if(status<0){
logMsg("VME shrt IO addr err in the master fast protect driver\n");
return -4;
}
status = rebootHookAdd(fpm_reboot);
if(status<0){
logMsg("%s: reboot hook add failed\n", __FILE__);
}
for (i = 0; (i < bo_num_cards[AT8_FP10M_BO]) && (vxMemProbe(ptr,READ,2,&junk) == OK);
i++,ptr++)
{
/*
register initialization
*/
ptr->cr = 0x00; /* disable interface */
fpm[i].fmptr = ptr; /* hardware location */
fpm[i].vector = intvec++; /* interrupt vector */
ptr->ivec = fpm[i].vector; /* load vector */
fpm[i].mode = FPM_NMSG; /* set default mode (no messages) */
fpm[i].int_num = 0; /* initialize interrupt number */
fpm[i].type = 2; /* board type */
fpm[i].num = i; /* board number */
/*
set up interrupt handler
*/
ptr->cr |= FPM_INTLEV<<4; /* set up board for level 5 interrupt */
if (intConnect(INUM_TO_IVEC(fpm[i].vector),fpm_int,&fpm[i]) != OK)
return -2; /* abort if can't connect */
sysIntEnable(FPM_INTLEV);
}
fpm_num = i - 1; /* record last card # */
return i; /* return # cards found */
}
/*
*
* fpm_reboot()
*
* turn off interrupts to avoid ctrl X reboot problems
*/
LOCAL
void fpm_reboot()
{
int i;
if(!fpm){
return;
}
for (i = 0; i < bo_num_cards[AT8_FP10M_BO]; i++){
if(!fpm[i].fmptr){
continue;
}
fpm[i].fmptr->cr &= ~CR_IEN;
}
}
/*
* fpm_en
*
* interrupt enable/disable
* (toggles the int enable state - joh)
*
*/
int fpm_en(card)
short card;
{
if (card < 0 || (card > fpm_num))
return -1;
fpm[card].fmptr->cr ^= CR_IEN;
if (fpm[card].fmptr->cr & CR_IEN)
printf("fast protect master interrupts enabled\n");
else
printf("fast protect master interrupts disabled\n");
return 0;
}
/*
* fpm_mode
*
* set interrupt reporting mode
*
*/
int fpm_mode(card,mode)
short card, mode;
{
if (card < 0 || (card > fpm_num))
return -1;
fpm[card].mode = mode;
return 0;
}
/*
* fpm_cdis
*
* carrier disable (1), enable (0)
*
*/
int fpm_cdis(card,disable)
short card, disable;
{
unsigned short temp;
if (card < 0 || (card > fpm_num))
return -1;
temp = fpm[card].fmptr->cr;
temp &= 0xfe;
temp |= (disable & 0x01);
fpm[card].fmptr->cr = temp;
return 0;
}
/*
* fpm_fail
*
* set failure mode
*
*/
int fpm_fail(card,mode)
short card, mode;
{
unsigned short temp;
if (card < 0 || (card > fpm_num))
return -1;
temp = fpm[card].fmptr->cr;
temp &= 0xf1;
temp |= (mode & 0x7)<<1;
fpm[card].fmptr->cr = temp;
return 0;
}
/*
* fpm_srd
*
* read status bits
*
*/
int fpm_srd(card)
short card;
{
if (card < 0 || ( card > fpm_num))
return -1;
return fpm[card].fmptr->sr & 0x7;
}
/*
* fpm_driver
*
* epics interface to fast protect master
*
*/
int fpm_driver(card,mask,prval)
register unsigned short card;
unsigned int mask;
register unsigned int prval;
{
register unsigned int temp;
if (card > fpm_num)
return -1;
temp = fpm[card].fmptr->cr;
fpm[card].fmptr->cr = (temp & (~mask | 0xf0)) | ((prval & mask) & 0xf);
return 0;
}
/*
* fpm_write
*
* command line interface to fpm_driver
*
*/
int fpm_write(card,val)
short card;
unsigned int val;
{
return fpm_driver(card,0xffffffff,val);
}
/*
* fpm_read
*
* read the current control register contents (readback)
*
*/
int fpm_read(card,mask,pval)
register unsigned short card;
unsigned int mask;
register unsigned int *pval;
{
if (card > fpm_num)
return -1;
*pval = fpm[card].fmptr->cr & 0x000f;
return 0;
}
/*
* fpm_io_report()
*
*/
int fpm_io_report(level)
int level;
{
int i;
for(i=0; i<=fpm_num; i++){
printf("BO: AT8-FP-M: card %d\n", i);
}
return(0);
}

View File

@@ -1,640 +0,0 @@
/* drvJgvtr1.c */
/* base/src/drv $Id$ */
/*
* Author: Jeff Hill
* Date: 5-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:
* -----------------
* 110689 joh print mem not full message only once
* 120789 joh temporary removal of memory full check
* 050190 joh clear ptr to callback prior to calling
* it so they can rearm from inside the callback
* 071190 joh check STD address after cycle complete detected
* to avoid erroneous card misaddressed messages
* 071190 joh internal sample rate status is bit reversed on the
* card- I added a lookup table to untwist it.
* 020491 ges Change taskDelay from 20 to 2 in "jgvtr1DoneTask".
* To allow rearm and data reads from succesive
* waveform scans up thru 10Hz rates.
* 031491 lrd move data into a local memory area for each card
* 090591 joh converted to V5 vxWorks
* 110591 lrd initialization of cards other than 0 not
* allocating data buffer correctly
* 013092 bg added sysBusToLocalAdrs. Added levels to io_report
* and the ability to read out the Joerger's raw values
* in io_report if level is > 1.
* 031992 joh Took the vxMemProbe out of each arm and checked
* the card present bit instead.
* 062592 bg Combined drvJgvtr1.c and jgvtr_driver.c
* 062992 joh removed file pointer argument added to io
* report by bg
* 082792 joh added ANSI C function prototypes
* 080293 mrk added call to taskwdInsert
* 080493 mgb Removed V5/V4 and EPICS_V2 conditionals
*/
static char *sccsID = "@(#)drvJgvtr1.c 1.17\t9/9/93";
/*
* Code Portions
*
* jgvtr1_init()
* jgvtr1_driver(card, pcbroutine, parg)
* jgvtr1_int_service()
* jgvtr1DoneTask()
* jgvtr1_io_report()
* jgvtr1_stat(card)
*
*/
/* drvJgvtr1.c - Driver Support Routines for Jgvtr1 */
#include <vxWorks.h>
#include <stdlib.h>
#include <stdio.h>
#include <vme.h>
#include <iv.h>
#include <dbDefs.h>
#include <epicsPrint.h>
#include <drvSup.h>
#include <module_types.h>
#include <task_params.h>
#include <fast_lock.h>
#include <taskwd.h>
#include <devLib.h>
#include <drvJgvtr1.h>
LOCAL jgvtr1Stat jgvtr1_io_report(
unsigned level
);
LOCAL jgvtr1Stat jgvtr1_init(
void
);
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL void jgvtr1_int_service(
void
);
#endif
LOCAL void jgvtr1DoneTask(
void
);
LOCAL jgvtr1Stat jgvtr1_dump(
unsigned card,
unsigned n
);
LOCAL jgvtr1Stat jgvtr1_stat(
unsigned card,
int level
);
struct {
long number;
DRVSUPFUN report;
DRVSUPFUN init;
} drvJgvtr1={
2,
jgvtr1_io_report,
jgvtr1_init};
static volatile char *stdaddr;
static volatile char *shortaddr;
#define JGVTR1MAXFREQ 25.0e6
/* NBBY - the number of bits per byte */
#define JGVTR1SHORTSIZE (1<<(NBBY*sizeof(uint8_t)))
#define JGVTR1STDSIZE (1<<(NBBY*sizeof(uint16_t)))
#define JGVTR1_INT_LEVEL 5
#define JGVTR1BASE(CARD)\
(shortaddr+wf_addrs[JGVTR1]+(CARD)*JGVTR1SHORTSIZE)
#define JGVTR1DATA(CARD)\
(stdaddr+wf_memaddrs[JGVTR1]+(CARD)*JGVTR1STDSIZE)
/*
Joerger fixed hardware bug by switching to an inverting tristate buffer
where these commands are read from the VME bus. As a result these commands
are complemented.
*/
#define JGVTR1ARM (~1)
#define JGVTR1START (~2)
#define JGVTR1STOP (~4)
/*
!! our compiler allocates bit fields starting from the ms bit !!
*/
struct jgvtr1_status{
volatile unsigned pad:8;
volatile unsigned internal_frequency:3;
volatile unsigned internal_clock:1;
volatile unsigned cycle_complete:1;
volatile unsigned interrupt:1;
volatile unsigned active:1;
volatile unsigned memory_full:1;
};
struct jgvtr1_config{
char present; /* card present */
char std_ok; /* std addr ok on first read */
void (*psub) /* call back routine */
(void *pprm, unsigned nbytes, uint16_t *pData);
void *pprm; /* call back parameter */
FAST_LOCK lock; /* mutual exclusion */
uint16_t *pdata; /* pointer to the data buffer */
};
/* amount of data to make available from the waveform */
#define JRG_MEM_SIZE 2048
LOCAL
struct jgvtr1_config *pjgvtr1_config;
LOCAL
int jgvtr1_max_card_count;
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL
SEM_ID jgvtr1_interrupt; /* interrupt event */
#endif
/*
* JGVTR1_INIT
*
* intialize the driver for the joerger vtr1
*
*/
jgvtr1Stat jgvtr1_init(void)
{
unsigned card;
unsigned card_count = 0;
struct jgvtr1_config *pconfig;
uint16_t readback;
jgvtr1Stat status;
status = sysBusToLocalAdrs(
VME_AM_SUP_SHORT_IO,
0,
(char **)&shortaddr);
if (status != OK){
status = S_dev_badA16;
errMessage(status,NULL);
return status;
}
status = sysBusToLocalAdrs(
VME_AM_STD_SUP_DATA,
0,
(char **)&stdaddr);
if (status != OK){
status = S_dev_badA24;
errMessage(status,NULL);
return status;
}
jgvtr1_max_card_count = wf_num_cards[JGVTR1];
if(pjgvtr1_config){
FASTLOCKFREE(&pjgvtr1_config->lock);
free(pjgvtr1_config);
}
pjgvtr1_config =
(struct jgvtr1_config *)
calloc(wf_num_cards[JGVTR1], sizeof(*pjgvtr1_config));
if(!pjgvtr1_config){
status = S_dev_noMemory;
errMessage(status,NULL);
return status;
}
for( card=0, pconfig=pjgvtr1_config;
card < wf_num_cards[JGVTR1];
pconfig++, card++){
FASTLOCKINIT(&pconfig->lock);
status = vxMemProbe( (char *)JGVTR1BASE(card),
READ,
sizeof(readback),
(char *)&readback);
if(status==ERROR)
continue;
pconfig->pdata =
(uint16_t *)malloc(JRG_MEM_SIZE);
/*
not easy to test for correct addressing in
standard address space since the module does
not respond if it has not clocked in data
- so I check this the first time data is ready
*/
pconfig->std_ok = FALSE; /* presumed guilty before tested */
pconfig->present = TRUE;
card_count++;
}
if(!card_count)
return OK;
# ifdef INTERRUPT_HARDWARE_FIXED
jgvtr1_interrupt = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if(!jgvtr1_interrupt)
return ERROR;
# endif
/* start the waveform readback task */
status = taskSpawn( WFDONE_NAME,
WFDONE_PRI,
WFDONE_OPT,
WFDONE_STACK,
(FUNCPTR) jgvtr1DoneTask,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if(status < 0){
status = S_dev_internal;
errMessage(status, "vxWorks taskSpawn failed");
return status;
}
taskwdInsert(status, NULL, NULL);
# ifdef INTERRUPT_HARDWARE_FIXED
status = intConnect( INUM_TO_IVEC(JGVTR1_INT_VEC),
jgvtr1_int_service,
NULL);
if(status != OK)
return S_dev_internal;
sysIntEnable(JGVTR_INT_LEVEL);
# endif
return JGVTR1_SUCCESS;
}
/*
* JGVTR1_DRIVER
*
* initiate waveform read
*
*/
jgvtr1Stat jgvtr1_driver(
unsigned card,
void (*pcbroutine)(void *, unsigned, uint16_t *),
void *parg
)
{
if(card >= jgvtr1_max_card_count)
return S_dev_badSignalNumber;
if(!pjgvtr1_config[card].present)
return S_dev_noDevice;
if(pjgvtr1_config[card].psub)
return S_dev_badRequest;
FASTLOCK(&pjgvtr1_config[card].lock);
*(volatile uint16_t *)JGVTR1BASE(card) = JGVTR1ARM;
pjgvtr1_config[card].pprm = parg;
pjgvtr1_config[card].psub = pcbroutine;
FASTUNLOCK(&pjgvtr1_config[card].lock);
return JGVTR1_SUCCESS;
}
/*
* JGVTR1_INT_SERVICE
*
* signal via the RTK that an interrupt occured from the joerger vtr1
*
*/
#ifdef INTERRUPT_HARDWARE_FIXED
LOCAL void jgvtr1_int_service(void)
{
semGive(jgvtr1_interrupt);
}
#endif
/*
* JGVTR1DONETASK
*
* wait for joerger vtr1 waveform record cycle complete
* and call back to the database with the waveform size and address
*
*/
LOCAL void jgvtr1DoneTask(void)
{
unsigned card;
struct jgvtr1_config *pconfig;
struct jgvtr1_status stat;
static char started = FALSE;
volatile uint16_t *pdata;
volatile uint16_t *pjgdata;
long i;
/* dont allow two of this task */
if(started)
exit(0);
started = TRUE;
while(TRUE){
# ifdef INTERRUPT_HARDWARE_FIXED
semTake(jgvtr1_interrupt, WAIT_FOREVER);
# else
/* ges: changed from 20 ticks to 2 ticks 2/4/91 */
taskDelay(2);
# endif
for( card=0, pconfig = pjgvtr1_config;
card < jgvtr1_max_card_count;
card++, pconfig++){
if(!pconfig->present)
continue;
if(!pconfig->psub)
continue;
stat = *(struct jgvtr1_status *) JGVTR1BASE(card);
/*
* Wait for the module to finish filling its memory
* or a stop trigger
*/
if(!stat.cycle_complete)
continue;
/*
clear ptr to function here so they
can rearm in the callback
*/
pconfig->psub = NULL;
/*
check the first time for module
correctly addressed
card does not respond at STD address
until it has data
*/
if(!pconfig->std_ok){
uint16_t readback;
int status;
status = vxMemProbe(
(char *)JGVTR1DATA(card),
READ,
sizeof(readback),
(char *)&readback);
if(status==ERROR){
errPrintf(
S_dev_badA24,
__FILE__,
__LINE__,
"jgvtr1 card %d incorrectly addressed- use std addr 0X%X",
card,
JGVTR1DATA(card));
pconfig->present = FALSE;
continue;
}
pconfig->std_ok = TRUE;
}
/*
Test for full memory
( card designer does not give a sample count register )
( instead a bus error returned when on the last sample
to test every location is a lot of overhead so a test
for memory full is used for now )
*/
if(!stat.memory_full){
errMessage(S_dev_internal,
"jgvtr1 driver: proceeding with partial mem");
errMessage(S_dev_internal,
"jgvtr1 driver: beware of bus errors");
}
/* copy the data into a local memory buffer */
/* this is to avoid any bus errors */
for(i = 0,
pdata = pconfig->pdata,
pjgdata = (volatile uint16_t *)JGVTR1DATA(card);
i < JRG_MEM_SIZE/sizeof(uint16_t);
i++, pdata++, pjgdata++){
*pdata = *pjgdata;
}
/*
Post waveform to the database
perhaps the size must be the size below+1 ?
(Joerger's documentation is not clear here)
*/
(*pconfig->psub)(pconfig->pprm,JRG_MEM_SIZE,pconfig->pdata);
}
}
}
/*
*
* JGVTR1_IO_REPORT
*
* print status for all cards in the specified joerger
* vtr1 address range
*
*
*/
LOCAL jgvtr1Stat jgvtr1_io_report(unsigned level)
{
unsigned card;
unsigned nelements;
jgvtr1Stat status;
for(card=0; card < wf_num_cards[JGVTR1]; card++){
status = jgvtr1_stat(card,level);
if(status){
continue;
}
if (level >= 2){
printf("enter the number of elements to dump:");
status = scanf("%d",&nelements);
if(status == 1){
jgvtr1_dump(card, nelements);
}
}
}
return JGVTR1_SUCCESS;
}
/*
*
* JGVTR1_STAT
*
* print status for a single card in the joerger vtr1 address range
*
*
*/
jgvtr1Stat jgvtr1_stat(
unsigned card,
int level
)
{
struct jgvtr1_status stat;
jgvtr1Stat status;
/*
internal freq status is bit reversed so I
use a lookup table
*/
static float sample_rate[8] = {
JGVTR1MAXFREQ/(1<<7),
JGVTR1MAXFREQ/(1<<3),
JGVTR1MAXFREQ/(1<<5),
JGVTR1MAXFREQ/(1<<1),
JGVTR1MAXFREQ/(1<<6),
JGVTR1MAXFREQ/(1<<2),
JGVTR1MAXFREQ/(1<<4),
JGVTR1MAXFREQ/(1<<0)};
static char *clock_status[] =
{"ext-clock", "internal-clk"};
static char *cycle_status[] =
{"cycling", "done"};
static char *interrupt_status[] =
{"", "int-pending"};
static char *activity_status[] =
{"", "active"};
static char *memory_status[] =
{"", "mem-full"};
status = vxMemProbe( (char *)JGVTR1BASE(card),
READ,
sizeof(stat),
(char *)&stat);
if(status != OK)
return ERROR;
if (level == 0)
printf("WF: JGVTR1:\tcard=%d \n",card);
else if (level > 0)
printf( "WF: JGVTR1:\tcard=%d Sample rate=%g %s %s %s %s %s \n",
card,
sample_rate[stat.internal_frequency],
clock_status[ stat.internal_clock ],
cycle_status[ stat.cycle_complete ],
interrupt_status[ stat.interrupt ],
activity_status[ stat.active ],
memory_status[ stat.memory_full ]);
return JGVTR1_SUCCESS;
}
/*
* jgvtr1_dump
*
*/
LOCAL jgvtr1Stat jgvtr1_dump(
unsigned card,
unsigned n
)
{
volatile uint16_t *pjgdata;
uint16_t *pread;
uint16_t *pdata;
unsigned nread;
jgvtr1Stat status;
/* Print out the data if user requests it. */
n = min(JRG_MEM_SIZE,n);
pdata = (uint16_t *)malloc(n * (sizeof(*pdata)));
if(!pdata){
return S_dev_noMemory;
}
pread = pdata;
nread = 0;
pjgdata = (volatile uint16_t *)JGVTR1DATA(card);
while(nread <= (n>>1)){
status = vxMemProbe(
(char *)pjgdata,
READ,
sizeof(*pread),
(char *)pread);
if(status<0){
break;
}
nread++;
pread++;
pjgdata++;
}
for(pread=pdata; pread<&pdata[nread]; pread++){
if ((pread-pdata)%8 == 0){
printf("\n\t");
}
printf( "%02X %02X ",
(unsigned char) ((*pread)>>8),
(unsigned char) *pread);
}
printf("\n");
free(pdata);
return JGVTR1_SUCCESS;
}

View File

@@ -1,43 +0,0 @@
/* drvJgvtr1.h */
/* base/src/drv $Id$ */
/*
* Author: Jeff Hill
* Date: 5-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:
* -----------------
*/
typedef long jgvtr1Stat;
#define JGVTR1_SUCCESS 0
jgvtr1Stat jgvtr1_driver(
unsigned card,
void (*pcbroutine)(void *, unsigned, uint16_t *),
void *parg
);

View File

@@ -1,241 +0,0 @@
/* module_types.c */
/* base/src/drv $Id$ */
/*
* Author: Marty Kraimer
* Date: 08-23-93
*
* 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-23-93 mrk Initial Version
*/
#include <module_types.h>
int module_types()
{
ai_num_cards[AB1771IL] = 12;
ai_num_cards[AB1771IFE] = 12;
ai_num_cards[AB1771IXE] = 12;
ai_num_cards[XY566SE] = 2;
ai_num_cards[XY566DI] = 2;
ai_num_cards[XY566DIL] = 2;
ai_num_cards[VXI_AT5_AI] = 32;
ai_num_cards[AB1771IFE_SE] = 12;
ai_num_cards[AB1771IFE_4to20MA] = 12;
ai_num_cards[DVX2502] = 1;
ai_num_cards[AB1771IFE_0to5V] = 12;
ai_num_cards[KSCV215] = 32;
ai_num_channels[AB1771IL] = 8;
ai_num_channels[AB1771IFE] = 8;
ai_num_channels[AB1771IXE] = 8;
ai_num_channels[XY566SE] = 32;
ai_num_channels[XY566DI] = 16;
ai_num_channels[XY566DIL] = 16;
ai_num_channels[VXI_AT5_AI] = 8;
ai_num_channels[AB1771IFE_SE] = 16;
ai_num_channels[AB1771IFE_4to20MA] = 8;
ai_num_channels[DVX2502] = 127;
ai_num_channels[AB1771IFE_0to5V] = 8;
ai_num_channels[KSCV215] = 32;
ai_addrs[AB1771IL] = 0;
ai_addrs[AB1771IFE] = 0;
ai_addrs[AB1771IXE] = 0;
ai_addrs[XY566SE] = 0x6000;
ai_addrs[XY566DI] = 0x7000;
ai_addrs[XY566DIL] = 0x7800;
ai_addrs[VXI_AT5_AI] = 0xc014;
ai_addrs[AB1771IFE_SE] = 0;
ai_addrs[AB1771IFE_4to20MA] = 0;
ai_addrs[DVX2502] = 0xff00;
ai_addrs[AB1771IFE_0to5V] = 0;
ai_addrs[KSCV215] = 0;
ai_memaddrs[AB1771IL] = 0;
ai_memaddrs[AB1771IFE] = 0;
ai_memaddrs[AB1771IXE] = 0;
ai_memaddrs[XY566SE] = 0x000000;
ai_memaddrs[XY566DI] = 0x040000;
ai_memaddrs[XY566DIL] = 0x0c0000;
ai_memaddrs[VXI_AT5_AI] = 0;
ai_memaddrs[AB1771IFE_SE] = 0;
ai_memaddrs[AB1771IFE_4to20MA] = 0;
ai_memaddrs[DVX2502] = 0x100000;
ai_memaddrs[AB1771IFE_0to5V] = 0;
ai_memaddrs[KSCV215] = 0;
ao_num_cards[AB1771OFE] = 12;
ao_num_cards[VMI4100] = 4;
ao_num_cards[ZIO085] = 1;
ao_num_cards[VXI_AT5_AO] = 32;
ao_num_channels[AB1771OFE] = 4;
ao_num_channels[VMI4100] = 16;
ao_num_channels[ZIO085] = 32;
ao_num_channels[VXI_AT5_AO] = 16;
ao_addrs[AB1771OFE] = 0;
ao_addrs[VMI4100] = 0x4100;
ao_addrs[ZIO085] = 0x0800;
ao_addrs[VXI_AT5_AO] = 0xc000;
bi_num_cards[ABBI_08_BIT] = 12;
bi_num_cards[ABBI_16_BIT] = 12;
bi_num_cards[BB910] = 4;
bi_num_cards[XY210] = 2;
bi_num_cards[VXI_AT5_BI] = 32;
bi_num_cards[HPE1368A_BI] = 32;
bi_num_cards[AT8_FP10S_BI] = 8;
bi_num_cards[XY240_BI] = 2;
bi_num_channels[ABBI_08_BIT] = 8;
bi_num_channels[ABBI_16_BIT] = 16;
bi_num_channels[BB910] = 32;
bi_num_channels[XY210] = 32;
bi_num_channels[VXI_AT5_BI] = 32;
bi_num_channels[HPE1368A_BI] = 16;
bi_num_channels[AT8_FP10S_BI] = 32;
bi_num_channels[XY240_BI] = 32;
bi_addrs[ABBI_08_BIT] = 0;
bi_addrs[ABBI_16_BIT] = 0;
bi_addrs[BB910] = 0xb800;
bi_addrs[XY210] = 0xa000;
bi_addrs[VXI_AT5_BI] = 0xc000;
bi_addrs[HPE1368A_BI] = 0xc000;
bi_addrs[AT8_FP10S_BI] = 0x0e00;
bi_addrs[XY240_BI] = 0x3000;
bo_num_cards[ABBO_08_BIT] = 12;
bo_num_cards[ABBO_16_BIT] = 12;
bo_num_cards[BB902] = 4;
bo_num_cards[XY220] = 1;
bo_num_cards[VXI_AT5_BO] = 32;
bo_num_cards[HPE1368A_BO] = 32;
bo_num_cards[AT8_FP10M_BO] = 2;
bo_num_cards[XY240_BO] = 2;
bo_num_channels[ABBO_08_BIT] = 8;
bo_num_channels[ABBO_16_BIT] = 16;
bo_num_channels[BB902] = 32;
bo_num_channels[XY220] = 32;
bo_num_channels[VXI_AT5_BO] = 32;
bo_num_channels[HPE1368A_BO] = 16;
bo_num_channels[AT8_FP10M_BO] = 32;
bo_num_channels[XY240_BO] = 32;
bo_addrs[ABBO_08_BIT] = 0;
bo_addrs[ABBO_16_BIT] = 0;
bo_addrs[BB902] = 0x0400;
bo_addrs[XY220] = 0xa800;
bo_addrs[VXI_AT5_BO] = 0xc000;
bo_addrs[HPE1368A_BO] = 0xc000;
bo_addrs[AT8_FP10M_BO] = 0xc000;
bo_addrs[XY240_BO] = 0x3000;
sm_num_cards[CM57_83E] = 4;
sm_num_cards[OMS_6AXIS] = 4;
sm_num_channels[CM57_83E] = 1;
sm_num_channels[OMS_6AXIS] = 6;
sm_addrs[CM57_83E] = 0x8000;
sm_addrs[OMS_6AXIS] = 0x4000;
wf_num_cards[XY566WF] = 2;
wf_num_cards[CAMAC_THING] = 4;
wf_num_cards[JGVTR1] = 4;
wf_num_cards[COMET] = 4;
wf_num_channels[XY566WF] = 1;
wf_num_channels[CAMAC_THING] = 1;
wf_num_channels[JGVTR1] = 1;
wf_num_channels[COMET] = 4;
wf_addrs[XY566WF] = 0x9000;
wf_addrs[CAMAC_THING] = 0;
wf_addrs[JGVTR1] = 0xB000;
wf_addrs[COMET] = 0xbc00;
wf_armaddrs[XY566WF] = 0x5400;
wf_armaddrs[CAMAC_THING]= 0;
wf_armaddrs[JGVTR1] = 0;
wf_armaddrs[COMET] = 0;
wf_memaddrs[XY566WF] = 0x080000;
wf_memaddrs[CAMAC_THING]= 0;
wf_memaddrs[JGVTR1] = 0xb80000;
wf_memaddrs[COMET] = 0xe0000000;
tm_num_cards[MZ8310] = 4;
tm_num_cards[DG535] = 1;
tm_num_cards[VXI_AT5_TIME] = 32;
tm_num_channels[MZ8310] = 10;
tm_num_channels[DG535] = 1;
tm_num_channels[VXI_AT5_TIME] = 10;
tm_addrs[MZ8310] = 0x1000;
tm_addrs[DG535] = 0;
tm_addrs[VXI_AT5_TIME] = 0xc000;
AT830X_1_addrs = 0x0400;
AT830X_1_num_cards = 2;
AT830X_addrs = 0xaa0000;
AT830X_num_cards = 2;
xy010ScA16Base = 0x0000;
EPICS_VXI_LA_COUNT = 32;
EPICS_VXI_A24_BASE = (char *) 0x900000;
EPICS_VXI_A24_SIZE = 0x100000;
EPICS_VXI_A32_BASE = (char *) 0x90000000;
EPICS_VXI_A32_SIZE = 0x10000000;
AI566_VNUM = 0xf8;
DVX_IVEC0 = 0xd0;
MD_INT_BASE = 0xf0;
MZ8310_INT_VEC_BASE = 0xe8;
AB_VEC_BASE = 0x60;
JGVTR1_INT_VEC = 0xe0;
AT830X_1_IVEC0 = 0xd4;
AT830X_IVEC0 = 0xd6;
AT8FP_IVEC_BASE = 0xa2;
AT8FPM_IVEC_BASE= 0xaa;
BB_SHORT_OFF = 0x1800;
BB_IVEC_BASE = 0xa0;
BB_IRQ_LEVEL = 5;
PEP_BB_SHORT_OFF= 0x1c00;
PEP_BB_IVEC_BASE= 0xe8;
NIGPIB_SHORT_OFF = 0x5000;
NIGPIB_IVEC_BASE = 100;
NIGPIB_IRQ_LEVEL = 5;
return(0);
}