remove all dev/drv support
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
TOP=../../..
|
||||
include $(TOP)/configure/CONFIG
|
||||
DIRS = $(wildcard *Dev)
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -1,12 +0,0 @@
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
SRCS += devAt5Vxi.c
|
||||
SRCS += devAt8Fp.c
|
||||
|
||||
OBJS_vxWorks += $(SRCS:%.c=%)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
SRCS += devSmCompumotor1830.c
|
||||
|
||||
OBJS_vxWorks += $(SRCS:%.c=%)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -1,11 +0,0 @@
|
||||
TOP=../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
SRCS += devWfJoergerVtr1.c
|
||||
|
||||
OBJS_vxWorks += $(SRCS:%.c=%)
|
||||
|
||||
include $(TOP)/configure/RULES
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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", &range); /* 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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));
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
TOP=../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
DIRS = ansi old
|
||||
|
||||
include $(TOP)/configure/RULES_DIRS
|
||||
|
||||
@@ -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
@@ -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
|
||||
);
|
||||
|
||||
@@ -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
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user