Merge branch '7.0' release 7.4.0.1 into PSI-7.0
Conflicts: .gitmodules modules/database/src/ioc/db/Makefile modules/libcom/test/epicsAtomicTest.cpp modules/pvAccess modules/pvData modules/pvDatabase modules/pva2pva
This commit is contained in:
@@ -11,9 +11,13 @@ TOP = ../../../..
|
||||
|
||||
include $(TOP)/configure/CONFIG
|
||||
|
||||
USR_CPPFLAGS += -DUSE_TYPED_RSET
|
||||
USR_CPPFLAGS += -DUSE_TYPED_RSET -DUSE_TYPED_DSET
|
||||
|
||||
SHRLIB_VERSION = 3.17.0
|
||||
# Shared library ABI version.
|
||||
SHRLIB_VERSION = $(EPICS_DATABASE_MAJOR_VERSION).$(EPICS_DATABASE_MINOR_VERSION).$(EPICS_DATABASE_MAINTENANCE_VERSION)
|
||||
|
||||
API_HEADER = dbRecStdAPI.h
|
||||
dbRecStd_API = dbRecStd
|
||||
|
||||
LIBRARY_IOC += dbRecStd
|
||||
dbRecStd_LIBS = dbCore ca Com
|
||||
|
||||
@@ -47,7 +47,6 @@ dbRecStd_SRCS += devSASoft.c
|
||||
dbRecStd_SRCS += devSiSoft.c
|
||||
dbRecStd_SRCS += devSoSoft.c
|
||||
dbRecStd_SRCS += devWfSoft.c
|
||||
dbRecStd_SRCS += devGeneralTime.c
|
||||
|
||||
dbRecStd_SRCS += devAiSoftCallback.c
|
||||
dbRecStd_SRCS += devBiSoftCallback.c
|
||||
@@ -68,6 +67,7 @@ dbRecStd_SRCS += devMbboDirectSoftCallback.c
|
||||
dbRecStd_SRCS += devPrintfSoftCallback.c
|
||||
dbRecStd_SRCS += devSoSoftCallback.c
|
||||
|
||||
dbRecStd_SRCS += devGeneralTime.c
|
||||
dbRecStd_SRCS += devTimestamp.c
|
||||
dbRecStd_SRCS += devStdio.c
|
||||
dbRecStd_SRCS += devEnviron.c
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* asSubRecordFunctions.c */
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
|
||||
static void myCallback(epicsCallback *pcallback)
|
||||
{
|
||||
ASDBCALLBACK *pasdbcallback = (ASDBCALLBACK *)pcallback;
|
||||
subRecord *precord;
|
||||
rset *prset;
|
||||
ASDBCALLBACK *pasdbcallback = (ASDBCALLBACK *)pcallback;
|
||||
subRecord *precord;
|
||||
rset *prset;
|
||||
|
||||
callbackGetUser(precord,pcallback);
|
||||
prset=(rset *)(precord->rset);
|
||||
precord->val = 0.0;
|
||||
if(pasdbcallback->status) {
|
||||
recGblSetSevr(precord,READ_ALARM,precord->brsv);
|
||||
recGblRecordError(pasdbcallback->status,precord,"asInit Failed");
|
||||
recGblSetSevr(precord,READ_ALARM,precord->brsv);
|
||||
recGblRecordError(pasdbcallback->status,precord,"asInit Failed");
|
||||
}
|
||||
dbScanLock((dbCommon *)precord);
|
||||
(*prset->process)((dbCommon *)precord);
|
||||
@@ -69,11 +69,11 @@ long asSubProcess(subRecord *precord)
|
||||
ASDBCALLBACK *pcallback = (ASDBCALLBACK *)precord->dpvt;
|
||||
|
||||
if(!precord->pact && precord->val==1.0) {
|
||||
db_post_events(precord,&precord->val,DBE_VALUE);
|
||||
callbackSetPriority(precord->prio,&pcallback->callback);
|
||||
asInitAsyn(pcallback);
|
||||
precord->pact=TRUE;
|
||||
return(1);
|
||||
db_post_events(precord,&precord->val,DBE_VALUE);
|
||||
callbackSetPriority(precord->prio,&pcallback->callback);
|
||||
asInitAsyn(pcallback);
|
||||
precord->pact=TRUE;
|
||||
return(1);
|
||||
}
|
||||
db_post_events(precord,&precord->val,DBE_VALUE);
|
||||
return(0);
|
||||
|
||||
@@ -32,28 +32,18 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devAaiSoft */
|
||||
static long init_record();
|
||||
static long read_aai();
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_aai(aaiRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_aai;
|
||||
} devAaiSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
aaidset devAaiSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_aai
|
||||
};
|
||||
epicsExportAddress(dset,devAaiSoft);
|
||||
epicsExportAddress(dset, devAaiSoft);
|
||||
|
||||
static long init_record(aaiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
|
||||
/* This is pass 0, link hasn't been initialized yet */
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* devAaoSoft.c - Device Support Routines for soft Waveform Records
|
||||
*
|
||||
*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Dirk Zimoch
|
||||
* Date: 27-MAY-2010
|
||||
@@ -30,28 +30,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devAaoSoft */
|
||||
static long init_record();
|
||||
static long write_aao();
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_aao(aaoRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_aao;
|
||||
} devAaoSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
aaodset devAaoSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_aao
|
||||
};
|
||||
epicsExportAddress(dset,devAaoSoft);
|
||||
epicsExportAddress(dset, devAaoSoft);
|
||||
|
||||
static long init_record(aaoRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)pcommon;
|
||||
|
||||
if (dbLinkIsConstant(&prec->out)) {
|
||||
prec->nord = 0;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -26,30 +26,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devAiSoft */
|
||||
static long init_record(aiRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_ai(aiRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiSoft = {
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_ai,
|
||||
NULL
|
||||
aidset devAiSoft = {
|
||||
{6, NULL, NULL, init_record, NULL},
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoft);
|
||||
|
||||
static long init_record(aiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -153,8 +153,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(aiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -213,14 +215,8 @@ static long read_ai(aiRecord *prec)
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Create the dset for devAiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiSoftCallback = {
|
||||
aidset devAiSoftCallback = {
|
||||
{6, NULL, init, init_record, NULL},
|
||||
read_ai,
|
||||
NULL
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoftCallback);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,30 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devAiSoftRaw */
|
||||
static long init_record(aiRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_ai(aiRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiSoftRaw = {
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_ai,
|
||||
NULL
|
||||
aidset devAiSoftRaw = {
|
||||
{6, NULL, NULL, init_record, NULL},
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoftRaw);
|
||||
|
||||
static long init_record(aiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
|
||||
recGblInitConstantLink(&prec->inp, DBF_LONG, &prec->rval);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devAoSoft.c */
|
||||
|
||||
@@ -31,31 +31,17 @@
|
||||
#include "aoRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* added for Channel Access Links */
|
||||
static long init_record(aoRecord *prec);
|
||||
|
||||
/* Create the dset for devAoSoft */
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_ao(aoRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_ao;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devAoSoft={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_ao,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devAoSoft);
|
||||
|
||||
|
||||
static long init_record(aoRecord *prec)
|
||||
aodset devAoSoft = {
|
||||
{6, NULL, NULL, init_record, NULL},
|
||||
write_ao, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAoSoft);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
|
||||
long status=0;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devAoSoftCallbackCallback.c */
|
||||
/*
|
||||
@@ -31,23 +31,12 @@
|
||||
|
||||
/* Create the dset for devAoSoftCallback */
|
||||
static long write_ao(aoRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_ao;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devAoSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_ao,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devAoSoftCallback);
|
||||
|
||||
aodset devAoSoftCallback = {
|
||||
{6, NULL, NULL, NULL, NULL},
|
||||
write_ao, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAoSoftCallback);
|
||||
|
||||
static long write_ao(aoRecord *prec)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devAoSoftRaw.c */
|
||||
|
||||
@@ -33,25 +33,13 @@
|
||||
|
||||
/* Create the dset for devAoSoftRaw */
|
||||
static long write_ao(aoRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_ao;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devAoSoftRaw={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_ao,
|
||||
NULL
|
||||
|
||||
aodset devAoSoftRaw = {
|
||||
{6, NULL, NULL, NULL, NULL},
|
||||
write_ao, NULL
|
||||
};
|
||||
epicsExportAddress(dset,devAoSoftRaw);
|
||||
|
||||
epicsExportAddress(dset, devAoSoftRaw);
|
||||
|
||||
static long write_ao(aoRecord *prec)
|
||||
{
|
||||
long status;
|
||||
|
||||
@@ -69,20 +69,9 @@ static long read_bi(biRecord *prec)
|
||||
return 2;
|
||||
}
|
||||
|
||||
static struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;
|
||||
} devBiDbState = {
|
||||
5,
|
||||
NULL,
|
||||
init,
|
||||
NULL,
|
||||
NULL,
|
||||
read_bi
|
||||
/* Create the dset for devBiDbState */
|
||||
bidset devBiDbState = {
|
||||
{5, NULL, init, NULL, NULL},
|
||||
read_bi
|
||||
};
|
||||
|
||||
epicsExportAddress(dset, devBiDbState);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devBiSoft */
|
||||
static long init_record(biRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_bi(biRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;
|
||||
} devBiSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
bidset devBiSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_bi
|
||||
};
|
||||
epicsExportAddress(dset, devBiSoft);
|
||||
|
||||
static long init_record(biRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
biRecord *prec = (biRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
return 0;
|
||||
|
||||
@@ -151,8 +151,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(biRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
biRecord *prec = (biRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -204,10 +206,7 @@ static long read_bi(biRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devBiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_bi;
|
||||
} devBiSoftCallback = {
|
||||
bidset devBiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_bi
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devBiSoftRaw */
|
||||
static long init_record(biRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_bi(biRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;
|
||||
} devBiSoftRaw = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
bidset devBiSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_bi
|
||||
};
|
||||
epicsExportAddress(dset, devBiSoftRaw);
|
||||
|
||||
static long init_record(biRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
biRecord *prec = (biRecord *)pcommon;
|
||||
|
||||
recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -67,20 +67,9 @@ static long write_bo(boRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;
|
||||
} devBoDbState = {
|
||||
5,
|
||||
NULL,
|
||||
init,
|
||||
NULL,
|
||||
NULL,
|
||||
write_bo
|
||||
/* Create the dset for devBoDbState */
|
||||
bodset devBoDbState = {
|
||||
{5, NULL, init, NULL, NULL},
|
||||
write_bo
|
||||
};
|
||||
|
||||
epicsExportAddress(dset, devBoDbState);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* devBoSoft.c - Device Support Routines for Soft Binary Output*/
|
||||
@@ -29,37 +29,24 @@
|
||||
#include "boRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long init_record(boRecord *prec);
|
||||
|
||||
/* Create the dset for devBoSoft */
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_bo(boRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;
|
||||
}devBoSoft={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_bo
|
||||
bodset devBoSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_bo
|
||||
};
|
||||
epicsExportAddress(dset,devBoSoft);
|
||||
|
||||
static long init_record(boRecord *prec)
|
||||
epicsExportAddress(dset, devBoSoft);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
|
||||
long status=0;
|
||||
|
||||
|
||||
/* dont convert */
|
||||
status=2;
|
||||
return status;
|
||||
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
static long write_bo(boRecord *prec)
|
||||
|
||||
@@ -31,22 +31,11 @@
|
||||
/* Create the dset for devBoCallbackSoft */
|
||||
static long write_bo(boRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;
|
||||
}devBoSoftCallback={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_bo
|
||||
bodset devBoSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_bo
|
||||
};
|
||||
epicsExportAddress(dset,devBoSoftCallback);
|
||||
epicsExportAddress(dset, devBoSoftCallback);
|
||||
|
||||
static long write_bo(boRecord *prec)
|
||||
{
|
||||
@@ -64,4 +53,3 @@ static long write_bo(boRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* devBoSoftRaw.c - Device Support Routines for SoftRaw Binary Output*/
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 3-28-92
|
||||
* Author: Janet Anderson
|
||||
* Date: 3-28-92
|
||||
*/
|
||||
|
||||
|
||||
@@ -28,37 +28,24 @@
|
||||
#include "boRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* added for Channel Access Links */
|
||||
static long init_record(boRecord *prec);
|
||||
|
||||
/* Create the dset for devBoSoftRaw */
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_bo(boRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;
|
||||
}devBoSoftRaw={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_bo
|
||||
bodset devBoSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_bo
|
||||
};
|
||||
epicsExportAddress(dset,devBoSoftRaw);
|
||||
|
||||
static long init_record(boRecord *prec)
|
||||
epicsExportAddress(dset, devBoSoftRaw);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
long status;
|
||||
|
||||
|
||||
/*Don't convert*/
|
||||
status = 2;
|
||||
return status;
|
||||
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
static long write_bo(boRecord *prec)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devCalcoutSoft.c */
|
||||
|
||||
@@ -31,15 +31,9 @@
|
||||
|
||||
static long write_calcout(calcoutRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write;
|
||||
} devCalcoutSoft = {
|
||||
5, NULL, NULL, NULL, NULL, write_calcout
|
||||
calcoutdset devCalcoutSoft = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_calcout
|
||||
};
|
||||
epicsExportAddress(dset, devCalcoutSoft);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devCalcoutSoftCallback.c */
|
||||
|
||||
@@ -31,15 +31,9 @@
|
||||
|
||||
static long write_calcout(calcoutRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write;
|
||||
} devCalcoutSoftCallback = {
|
||||
5, NULL, NULL, NULL, NULL, write_calcout
|
||||
calcoutdset devCalcoutSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_calcout
|
||||
};
|
||||
epicsExportAddress(dset, devCalcoutSoftCallback);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* devEnviron.c */
|
||||
@@ -69,7 +69,7 @@ static long read_lsi(lsiRecord *prec)
|
||||
}
|
||||
|
||||
lsidset devLsiEnviron = {
|
||||
5, NULL, init_lsi, NULL, NULL, read_lsi
|
||||
{5, NULL, init_lsi, NULL, NULL }, read_lsi
|
||||
};
|
||||
epicsExportAddress(dset, devLsiEnviron);
|
||||
|
||||
@@ -119,10 +119,8 @@ static long read_stringin(stringinRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
dset common;
|
||||
DEVSUPFUN read;
|
||||
} devSiEnviron = {
|
||||
{5, NULL, init_stringin, NULL, NULL}, read_stringin
|
||||
stringindset devSiEnviron = {
|
||||
{5, NULL, init_stringin, NULL, NULL},
|
||||
read_stringin
|
||||
};
|
||||
epicsExportAddress(dset, devSiEnviron);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devEventSoft */
|
||||
static long init_record(eventRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_event(eventRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_event;
|
||||
} devEventSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
eventdset devEventSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_event
|
||||
};
|
||||
epicsExportAddress(dset, devEventSoft);
|
||||
|
||||
static long init_record(eventRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
eventRecord *prec = (eventRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_STRING, prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Original Author: Sheng Peng, ORNL / SNS Project
|
||||
* Date: 07/2004
|
||||
* Original Author: Sheng Peng, ORNL / SNS Project
|
||||
* Date: 07/2004
|
||||
*
|
||||
* EPICS device support for general timestamp support
|
||||
*
|
||||
@@ -50,8 +50,9 @@ static struct ai_channel {
|
||||
{"TIME", getCurrentTime},
|
||||
};
|
||||
|
||||
static long init_ai(aiRecord *prec)
|
||||
static long init_ai(dbCommon *pcommon)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
@@ -91,12 +92,9 @@ static long read_ai(aiRecord *prec)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiGeneralTime = {
|
||||
{6, NULL, NULL, init_ai, NULL}, read_ai, NULL
|
||||
aidset devAiGeneralTime = {
|
||||
{6, NULL, NULL, init_ai, NULL},
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiGeneralTime);
|
||||
|
||||
@@ -114,8 +112,9 @@ static struct bo_channel {
|
||||
{"RSTERRCNT", resetErrors},
|
||||
};
|
||||
|
||||
static long init_bo(boRecord *prec)
|
||||
static long init_bo(dbCommon *pcommon)
|
||||
{
|
||||
boRecord *prec = (boRecord *)pcommon;
|
||||
int i;
|
||||
|
||||
if (prec->out.type != INST_IO) {
|
||||
@@ -151,15 +150,14 @@ static long write_bo(boRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devBoGeneralTime = {
|
||||
{5, NULL, NULL, init_bo, NULL}, write_bo
|
||||
bodset devBoGeneralTime = {
|
||||
{5, NULL, NULL, init_bo, NULL},
|
||||
write_bo
|
||||
};
|
||||
epicsExportAddress(dset, devBoGeneralTime);
|
||||
|
||||
|
||||
|
||||
/******* longin record *************/
|
||||
static int errorCount(void)
|
||||
{
|
||||
@@ -173,8 +171,9 @@ static struct li_channel {
|
||||
{"GETERRCNT", errorCount},
|
||||
};
|
||||
|
||||
static long init_li(longinRecord *prec)
|
||||
static long init_li(dbCommon *pcommon)
|
||||
{
|
||||
longinRecord *prec = (longinRecord *)pcommon;
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
@@ -209,11 +208,9 @@ static long read_li(longinRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devLiGeneralTime = {
|
||||
{5, NULL, NULL, init_li, NULL}, read_li
|
||||
longindset devLiGeneralTime = {
|
||||
{5, NULL, NULL, init_li, NULL},
|
||||
read_li
|
||||
};
|
||||
epicsExportAddress(dset, devLiGeneralTime);
|
||||
|
||||
@@ -243,8 +240,9 @@ static struct si_channel {
|
||||
{"BESTTEP", eventProvider},
|
||||
};
|
||||
|
||||
static long init_si(stringinRecord *prec)
|
||||
static long init_si(dbCommon *pcommon)
|
||||
{
|
||||
stringinRecord *prec = (stringinRecord *)pcommon;
|
||||
int i;
|
||||
|
||||
if (prec->inp.type != INST_IO) {
|
||||
@@ -288,10 +286,8 @@ static long read_si(stringinRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
} devSiGeneralTime = {
|
||||
{5, NULL, NULL, init_si, NULL}, read_si
|
||||
stringindset devSiGeneralTime = {
|
||||
{5, NULL, NULL, init_si, NULL},
|
||||
read_si
|
||||
};
|
||||
epicsExportAddress(dset, devSiGeneralTime);
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devHistogramSoft.c */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 07/02/91
|
||||
* Author: Janet Anderson
|
||||
* Date: 07/02/91
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -28,29 +28,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devHistogramSoft */
|
||||
static long init_record(histogramRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_histogram(histogramRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_histogram;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devHistogramSoft={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_histogram,
|
||||
NULL
|
||||
|
||||
histogramdset devHistogramSoft = {
|
||||
{6, NULL, NULL, init_record, NULL},
|
||||
read_histogram, NULL
|
||||
};
|
||||
epicsExportAddress(dset,devHistogramSoft);
|
||||
|
||||
static long init_record(histogramRecord *prec)
|
||||
epicsExportAddress(dset, devHistogramSoft);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
histogramRecord *prec = (histogramRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->svl,DBF_DOUBLE,&prec->sgnl))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -24,29 +24,9 @@
|
||||
#include "int64inRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devI64inSoft */
|
||||
static long init_record(int64inRecord *prec);
|
||||
static long read_int64in(int64inRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_int64in;
|
||||
} devI64inSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_int64in
|
||||
};
|
||||
epicsExportAddress(dset, devI64inSoft);
|
||||
|
||||
static long init_record(int64inRecord *prec)
|
||||
static long init_record(dbCommon *common)
|
||||
{
|
||||
int64inRecord *prec = (int64inRecord *)common;
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_INT64, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -76,3 +56,11 @@ static long read_int64in(int64inRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Create the dset for devI64inSoft */
|
||||
|
||||
int64indset devI64inSoft = {
|
||||
{ 5, NULL, NULL, init_record, NULL }, read_int64in
|
||||
};
|
||||
epicsExportAddress(dset, devI64inSoft);
|
||||
|
||||
|
||||
@@ -151,8 +151,9 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(int64inRecord *prec)
|
||||
static long init_record(dbCommon *common)
|
||||
{
|
||||
int64inRecord *prec = (int64inRecord *)common;
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_INT64, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -204,11 +205,7 @@ static long read_int64in(int64inRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devI64inSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_int64in;
|
||||
} devI64inSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_int64in
|
||||
int64indset devI64inSoftCallback = {
|
||||
{ 5, NULL, init, init_record, NULL }, read_int64in
|
||||
};
|
||||
epicsExportAddress(dset, devI64inSoftCallback);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/*
|
||||
* Original Author: Janet Anderson
|
||||
* Date: 09-23-91
|
||||
* Date: 09-23-91
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -25,27 +25,7 @@
|
||||
#include "int64outRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devI64outSoft */
|
||||
static long init_record(int64outRecord *prec);
|
||||
static long write_int64out(int64outRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_int64out;
|
||||
} devI64outSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_int64out
|
||||
};
|
||||
epicsExportAddress(dset, devI64outSoft);
|
||||
|
||||
static long init_record(int64outRecord *prec)
|
||||
static long init_record(dbCommon *common)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -55,3 +35,10 @@ static long write_int64out(int64outRecord *prec)
|
||||
dbPutLink(&prec->out, DBR_INT64, &prec->val,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devI64outSoft */
|
||||
int64outdset devI64outSoft = {
|
||||
{ 5, NULL, NULL, init_record, NULL }, write_int64out
|
||||
};
|
||||
epicsExportAddress(dset, devI64outSoft);
|
||||
|
||||
|
||||
@@ -25,25 +25,6 @@
|
||||
#include "int64outRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devI64outSoftCallback */
|
||||
static long write_int64out(int64outRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_int64out;
|
||||
} devI64outSoftCallback = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_int64out
|
||||
};
|
||||
epicsExportAddress(dset, devI64outSoftCallback);
|
||||
|
||||
static long write_int64out(int64outRecord *prec)
|
||||
{
|
||||
struct link *plink = &prec->out;
|
||||
@@ -60,3 +41,9 @@ static long write_int64out(int64outRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Create the dset for devI64outSoftCallback */
|
||||
int64outdset devI64outSoftCallback = {
|
||||
{ 5, NULL, NULL, NULL, NULL }, write_int64out
|
||||
};
|
||||
epicsExportAddress(dset, devI64outSoftCallback);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devLiSoft */
|
||||
static long init_record(longinRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_longin(longinRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_longin;
|
||||
} devLiSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
longindset devLiSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_longin
|
||||
};
|
||||
epicsExportAddress(dset, devLiSoft);
|
||||
|
||||
static long init_record(longinRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
longinRecord *prec = (longinRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_LONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -151,8 +151,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(longinRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
longinRecord *prec = (longinRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_LONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -204,10 +206,7 @@ static long read_li(longinRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devLiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_li;
|
||||
} devLiSoftCallback = {
|
||||
longindset devLiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_li
|
||||
};
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devLoSoft.c */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 09-23-91
|
||||
* Author: Janet Anderson
|
||||
* Date: 09-23-91
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -26,31 +26,21 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devLoSoft */
|
||||
static long init_record(longoutRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_longout(longoutRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_longout;
|
||||
}devLoSoft={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_longout
|
||||
|
||||
longoutdset devLoSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_longout
|
||||
};
|
||||
epicsExportAddress(dset,devLoSoft);
|
||||
|
||||
static long init_record(longoutRecord *prec)
|
||||
epicsExportAddress(dset, devLoSoft);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
return 0;
|
||||
} /* end init_record() */
|
||||
|
||||
static long write_longout(longoutRecord *prec)
|
||||
static long write_longout(longoutRecord *prec)
|
||||
{
|
||||
dbPutLink(&prec->out,DBR_LONG, &prec->val,1);
|
||||
return 0;
|
||||
|
||||
@@ -29,24 +29,14 @@
|
||||
|
||||
/* Create the dset for devLoSoftCallback */
|
||||
static long write_longout(longoutRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_longout;
|
||||
}devLoSoftCallback={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_longout
|
||||
};
|
||||
epicsExportAddress(dset,devLoSoftCallback);
|
||||
|
||||
static long write_longout(longoutRecord *prec)
|
||||
longoutdset devLoSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_longout
|
||||
};
|
||||
epicsExportAddress(dset, devLoSoftCallback);
|
||||
|
||||
static long write_longout(longoutRecord *prec)
|
||||
{
|
||||
struct link *plink = &prec->out;
|
||||
long status;
|
||||
@@ -62,4 +52,3 @@ static long write_longout(longoutRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
#include "lsiRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long init_record(lsiRecord *prec)
|
||||
static long init_record(dbCommon *common)
|
||||
{
|
||||
lsiRecord *prec = (lsiRecord *)common;
|
||||
dbLoadLinkLS(&prec->inp, prec->val, prec->sizv, &prec->len);
|
||||
|
||||
return 0;
|
||||
@@ -49,6 +50,6 @@ static long read_string(lsiRecord *prec)
|
||||
}
|
||||
|
||||
lsidset devLsiSoft = {
|
||||
5, NULL, NULL, init_record, NULL, read_string
|
||||
{ 5, NULL, NULL, init_record, NULL }, read_string
|
||||
};
|
||||
epicsExportAddress(dset, devLsiSoft);
|
||||
|
||||
@@ -21,6 +21,6 @@ static long write_string(lsoRecord *prec)
|
||||
}
|
||||
|
||||
lsodset devLsoSoft = {
|
||||
5, NULL, NULL, NULL, NULL, write_string
|
||||
{ 5, NULL, NULL, NULL, NULL }, write_string
|
||||
};
|
||||
epicsExportAddress(dset, devLsoSoft);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Andrew Johnson
|
||||
@@ -40,7 +40,7 @@ static long write_string(lsoRecord *prec)
|
||||
}
|
||||
|
||||
lsodset devLsoSoftCallback = {
|
||||
5, NULL, NULL, NULL, NULL, write_string
|
||||
{ 5, NULL, NULL, NULL, NULL }, write_string
|
||||
};
|
||||
epicsExportAddress(dset, devLsoSoftCallback);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiDirectSoft */
|
||||
static long init_record(mbbiDirectRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_mbbi(mbbiDirectRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiDirectSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
mbbidirectdset devMbbiDirectSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset, devMbbiDirectSoft);
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ULONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -151,8 +151,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ULONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -204,10 +206,7 @@ static long read_mbbiDirect(mbbiDirectRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devMbbiDirectSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_mbbiDirect;
|
||||
} devMbbiDirectSoftCallback = {
|
||||
mbbidirectdset devMbbiDirectSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_mbbiDirect
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiDirectSoftRaw */
|
||||
static long init_record(mbbiDirectRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_mbbi(mbbiDirectRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiDirectSoftRaw = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
mbbidirectdset devMbbiDirectSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset, devMbbiDirectSoftRaw);
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon;
|
||||
|
||||
recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval);
|
||||
|
||||
/* Preserve old functionality */
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiSoft */
|
||||
static long init_record(mbbiRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_mbbi(mbbiRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
mbbidset devMbbiSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset, devMbbiSoft);
|
||||
|
||||
static long init_record(mbbiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiRecord *prec = (mbbiRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ static long add_record(dbCommon *pcommon)
|
||||
|
||||
pdevPvt = calloc(1, sizeof(*pdevPvt));
|
||||
if (!pdevPvt) {
|
||||
long status = S_db_noMemory;
|
||||
long status = S_db_noMemory;
|
||||
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devMbbiSoftCallback (add_record) out of memory, calloc() failed");
|
||||
@@ -151,8 +151,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(mbbiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiRecord *prec = (mbbiRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -204,11 +206,8 @@ static long read_mbbi(mbbiRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devMbbiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiSoftCallback = {
|
||||
mbbidset devMbbiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset,devMbbiSoftCallback);
|
||||
epicsExportAddress(dset, devMbbiSoftCallback);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -25,28 +25,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiSoftRaw */
|
||||
static long init_record(mbbiRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_mbbi(mbbiRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiSoftRaw = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
mbbidset devMbbiSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset, devMbbiSoftRaw);
|
||||
|
||||
static long init_record(mbbiRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiRecord *prec = (mbbiRecord *)pcommon;
|
||||
|
||||
recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval);
|
||||
|
||||
/* Preserve old functionality*/
|
||||
|
||||
@@ -19,17 +19,14 @@
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
dbPutLink(&prec->out, DBR_ULONG, &prec->val, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboDirectSoft */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoft = {
|
||||
mbbodirectdset devMbboDirectSoft = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
|
||||
@@ -38,11 +38,8 @@ static long write_mbbo(mbboDirectRecord *prec)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboSoft */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoftCallback = {
|
||||
/* Create the dset for devMbboDirectSoftCallback */
|
||||
mbbodirectdset devMbboDirectSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long init_record(mbboDirectRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbboDirectRecord *prec = (mbboDirectRecord *)pcommon;
|
||||
|
||||
if (prec->nobt == 0)
|
||||
prec->mask = 0xffffffff;
|
||||
|
||||
@@ -30,7 +32,7 @@ static long init_record(mbboDirectRecord *prec)
|
||||
return 2; /* Don't convert */
|
||||
}
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
epicsUInt32 data;
|
||||
|
||||
@@ -40,10 +42,7 @@ static long write_mbbo(mbboDirectRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboDirectSoftRaw */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoftRaw = {
|
||||
mbbodirectdset devMbboDirectSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devMbboSoft.c */
|
||||
/*
|
||||
@@ -27,30 +27,20 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbboSoft */
|
||||
static long init_record(mbboRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long write_mbbo(mbboRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboSoft={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_mbbo
|
||||
|
||||
mbbodset devMbboSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboSoft);
|
||||
|
||||
static long init_record(mbboRecord *prec)
|
||||
epicsExportAddress(dset, devMbboSoft);
|
||||
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
/*dont convert*/
|
||||
return 2;
|
||||
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
static long write_mbbo(mbboRecord *prec)
|
||||
|
||||
@@ -28,22 +28,12 @@
|
||||
|
||||
/* Create the dset for devMbboSoftCallback */
|
||||
static long write_mbbo(mbboRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboSoftCallback={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_mbbo
|
||||
|
||||
mbbodset devMbboSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboSoftCallback);
|
||||
epicsExportAddress(dset, devMbboSoftCallback);
|
||||
|
||||
static long write_mbbo(mbboRecord *prec)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
#include "mbboRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
static long init_record(mbboRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
mbboRecord *prec = (mbboRecord *)pcommon;
|
||||
|
||||
if (prec->nobt == 0)
|
||||
prec->mask = 0xffffffff;
|
||||
|
||||
@@ -40,10 +42,7 @@ static long write_mbbo(mbboRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboSoftRaw */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboSoftRaw = {
|
||||
mbbodset devMbboSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Andrew Johnson
|
||||
@@ -19,7 +19,7 @@ static long write_string(printfRecord *prec)
|
||||
}
|
||||
|
||||
printfdset devPrintfSoft = {
|
||||
5, NULL, NULL, NULL, NULL, write_string
|
||||
{ 5, NULL, NULL, NULL, NULL }, write_string
|
||||
};
|
||||
epicsExportAddress(dset, devPrintfSoft);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Andrew Johnson
|
||||
@@ -40,6 +40,6 @@ static long write_string(printfRecord *prec)
|
||||
}
|
||||
|
||||
printfdset devPrintfSoftCallback = {
|
||||
5, NULL, NULL, NULL, NULL, write_string
|
||||
{ 5, NULL, NULL, NULL, NULL }, write_string
|
||||
};
|
||||
epicsExportAddress(dset, devPrintfSoftCallback);
|
||||
|
||||
@@ -26,22 +26,11 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devSASoft */
|
||||
static long init_record(subArrayRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_sa(subArrayRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_sa;
|
||||
} devSASoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
sadset devSASoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_sa
|
||||
};
|
||||
epicsExportAddress(dset, devSASoft);
|
||||
@@ -65,8 +54,9 @@ static void subset(subArrayRecord *prec, long nRequest)
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
|
||||
static long init_record(subArrayRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
subArrayRecord *prec = (subArrayRecord *)pcommon;
|
||||
long nRequest = prec->indx + prec->nelm;
|
||||
long status;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -27,28 +27,19 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devSiSoft */
|
||||
static long init_record(stringinRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_stringin(stringinRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_stringin;
|
||||
} devSiSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
stringindset devSiSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_stringin
|
||||
};
|
||||
epicsExportAddress(dset, devSiSoft);
|
||||
|
||||
static long init_record(stringinRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
stringinRecord *prec = (stringinRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_STRING, prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
|
||||
@@ -153,8 +153,10 @@ static long init(int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(stringinRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
stringinRecord *prec = (stringinRecord *)pcommon;
|
||||
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_STRING, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
@@ -207,11 +209,8 @@ static long read_si(stringinRecord *prec)
|
||||
}
|
||||
|
||||
/* Create the dset for devSiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_li;
|
||||
} devSiSoftCallback = {
|
||||
stringindset devSiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_si
|
||||
};
|
||||
epicsExportAddress(dset,devSiSoftCallback);
|
||||
epicsExportAddress(dset, devSiSoftCallback);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
@@ -27,19 +27,9 @@
|
||||
|
||||
/* Create the dset for devSoSoft */
|
||||
static long write_stringout(stringoutRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_stringout;
|
||||
} devSoSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
stringoutdset devSoSoft = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_stringout
|
||||
};
|
||||
epicsExportAddress(dset, devSoSoft);
|
||||
|
||||
@@ -27,19 +27,9 @@
|
||||
|
||||
/* Create the dset for devSoSoftCallback */
|
||||
static long write_stringout(stringoutRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_stringout;
|
||||
} devSoSoftCallback = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
stringoutdset devSoSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_stringout
|
||||
};
|
||||
epicsExportAddress(dset, devSoSoftCallback);
|
||||
@@ -60,4 +50,3 @@ static long write_stringout(stringoutRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -103,7 +103,7 @@ static long write_lso(lsoRecord *prec)
|
||||
}
|
||||
|
||||
lsodset devLsoStdio = {
|
||||
5, NULL, init_lso, NULL, NULL, write_lso
|
||||
{ 5, NULL, init_lso, NULL, NULL }, write_lso
|
||||
};
|
||||
epicsExportAddress(dset, devLsoStdio);
|
||||
|
||||
@@ -153,7 +153,7 @@ static long write_printf(printfRecord *prec)
|
||||
}
|
||||
|
||||
printfdset devPrintfStdio = {
|
||||
5, NULL, init_printf, NULL, NULL, write_printf
|
||||
{5, NULL, init_printf, NULL, NULL }, write_printf
|
||||
};
|
||||
epicsExportAddress(dset, devPrintfStdio);
|
||||
|
||||
@@ -202,10 +202,8 @@ static long write_stringout(stringoutRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devSoStdio = {
|
||||
{5, NULL, init_stringout, NULL, NULL}, write_stringout
|
||||
stringoutdset devSoStdio = {
|
||||
{5, NULL, init_stringout, NULL, NULL},
|
||||
write_stringout
|
||||
};
|
||||
epicsExportAddress(dset, devSoStdio);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/*
|
||||
* Device support for EPICS time stamps
|
||||
*
|
||||
* Original Author: Eric Norum
|
||||
* Original Author: Eric Norum
|
||||
*/
|
||||
|
||||
#include "dbDefs.h"
|
||||
@@ -40,12 +40,9 @@ static long read_ai(aiRecord *prec)
|
||||
return 2;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_write;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devTimestampAI = {
|
||||
{6, NULL, initAllow, NULL, NULL}, read_ai, NULL
|
||||
aidset devTimestampAI = {
|
||||
{6, NULL, initAllow, NULL, NULL},
|
||||
read_ai, NULL
|
||||
};
|
||||
epicsExportAddress(dset, devTimestampAI);
|
||||
|
||||
@@ -68,10 +65,8 @@ static long read_stringin (stringinRecord *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_stringin;
|
||||
} devTimestampSI = {
|
||||
{5, NULL, initAllow, NULL, NULL}, read_stringin
|
||||
stringindset devTimestampSI = {
|
||||
{5, NULL, initAllow, NULL, NULL},
|
||||
read_stringin
|
||||
};
|
||||
epicsExportAddress(dset, devTimestampSI);
|
||||
|
||||
@@ -26,28 +26,18 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devWfSoft */
|
||||
static long init_record(waveformRecord *prec);
|
||||
static long init_record(dbCommon *pcommon);
|
||||
static long read_wf(waveformRecord *prec);
|
||||
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_wf;
|
||||
} devWfSoft = {
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
wfdset devWfSoft = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
read_wf
|
||||
};
|
||||
epicsExportAddress(dset, devWfSoft);
|
||||
|
||||
static long init_record(waveformRecord *prec)
|
||||
static long init_record(dbCommon *pcommon)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *)pcommon;
|
||||
long nelm = prec->nelm;
|
||||
long status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nelm);
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl)
|
||||
long end = my->end;
|
||||
long nTarget = 0;
|
||||
long offset = 0;
|
||||
long nSource = chan->addr.no_elements;
|
||||
long nSource = dbChannelElements(chan);
|
||||
long capacity = nSource;
|
||||
void *pdst;
|
||||
|
||||
@@ -110,12 +110,12 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl)
|
||||
|
||||
case dbfl_type_rec:
|
||||
/* Extract from record */
|
||||
if (chan->addr.special == SPC_DBADDR &&
|
||||
if (dbChannelSpecial(chan) == SPC_DBADDR &&
|
||||
nSource > 1 &&
|
||||
(prset = dbGetRset(&chan->addr)) &&
|
||||
prset->get_array_info)
|
||||
{
|
||||
void *pfieldsave = chan->addr.pfield;
|
||||
void *pfieldsave = dbChannelField(chan);
|
||||
prec = dbChannelRecord(chan);
|
||||
dbScanLock(prec);
|
||||
prset->get_array_info(&chan->addr, &nSource, &offset);
|
||||
@@ -124,22 +124,22 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl)
|
||||
pfl->stat = prec->stat;
|
||||
pfl->sevr = prec->sevr;
|
||||
pfl->time = prec->time;
|
||||
pfl->field_type = chan->addr.field_type;
|
||||
pfl->field_size = chan->addr.field_size;
|
||||
pfl->field_type = dbChannelFieldType(chan);
|
||||
pfl->field_size = dbChannelFieldSize(chan);
|
||||
pfl->no_elements = nTarget;
|
||||
if (nTarget) {
|
||||
pdst = freeListCalloc(my->arrayFreeList);
|
||||
if (pdst) {
|
||||
pfl->u.r.dtor = freeArray;
|
||||
pfl->u.r.pvt = my->arrayFreeList;
|
||||
offset = (offset + start) % chan->addr.no_elements;
|
||||
offset = (offset + start) % dbChannelElements(chan);
|
||||
dbExtractArrayFromRec(&chan->addr, pdst, nTarget, capacity,
|
||||
offset, my->incr);
|
||||
pfl->u.r.field = pdst;
|
||||
}
|
||||
}
|
||||
dbScanUnlock(prec);
|
||||
chan->addr.pfield = pfieldsave;
|
||||
dbChannelField(chan) = pfieldsave;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ result should be displayed. Equivalent to the C<PREC> field of a record.
|
||||
=item time
|
||||
|
||||
An optional string containing a single upper or lower-case letter C<A> ... C<L>
|
||||
which must correspond to an input provided in the c<args> parameter. When the
|
||||
which must correspond to an input provided in the C<args> parameter. When the
|
||||
record containing such a link has C<TSEL> set to -2 (epicsTimeEventDeviceTime)
|
||||
the record's timestamp field C<TIME> will be read from the indicated input link
|
||||
atomically with the value of the input argument.
|
||||
@@ -161,7 +161,7 @@ atomically with the value of the input argument.
|
||||
|
||||
=head4 Example
|
||||
|
||||
{calc: {expr:"A*B", args:[{db:"record.VAL"}, 1.5], prec:3}}
|
||||
{calc: {expr:"A*B", args:[{pva:"record"}, 1.5], prec:3}}
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -127,8 +127,8 @@ static jlif_result lnkCalc_integer(jlink *pjlink, long long num)
|
||||
}
|
||||
|
||||
if (clink->pstate != ps_args) {
|
||||
return jlif_stop;
|
||||
errlogPrintf("lnkCalc: Unexpected integer %lld\n", num);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
if (clink->nArgs == CALCPERFORM_NARGS) {
|
||||
@@ -147,8 +147,8 @@ static jlif_result lnkCalc_double(jlink *pjlink, double num)
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
if (clink->pstate != ps_args) {
|
||||
return jlif_stop;
|
||||
errlogPrintf("lnkCalc: Unexpected double %g\n", num);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
if (clink->nArgs == CALCPERFORM_NARGS) {
|
||||
@@ -198,6 +198,7 @@ static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len)
|
||||
inbuf = malloc(len+1);
|
||||
if(!inbuf) {
|
||||
errlogPrintf("lnkCalc: Out of memory\n");
|
||||
free(postbuf);
|
||||
return jlif_stop;
|
||||
}
|
||||
memcpy(inbuf, val, len);
|
||||
|
||||
@@ -348,7 +348,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
aSubRecord *prec = (aSubRecord *)paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
int linkNumber;
|
||||
|
||||
|
||||
linkNumber = get_inlinkNumber(fieldIndex);
|
||||
if (linkNumber >= 0) {
|
||||
dbGetGraphicLimits(&prec->inpa + linkNumber,
|
||||
|
||||
@@ -4,37 +4,53 @@
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Array Subroutine Record (aSub)
|
||||
|
||||
...
|
||||
The aSub record is an advanced variant of the 'sub' (subroutine) record which
|
||||
has a number of additional features:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
It provides 20 different input and output fields which can hold array or
|
||||
scalar values.
|
||||
The types and array capacities of these are user configurable, and they all
|
||||
have an associated input or output link.
|
||||
|
||||
=item *
|
||||
|
||||
The name of the C or C++ subroutine to be called when the record processes
|
||||
can be changed dynamically while the IOC is running.
|
||||
The name can either be fetched from another record using an input link, or
|
||||
written directly into the SNAM field.
|
||||
|
||||
=item *
|
||||
|
||||
The user can choose whether monitor events should be posted for the output
|
||||
fields.
|
||||
|
||||
=item *
|
||||
|
||||
The VAL field is set to the return value from the user subroutine, which is
|
||||
treated as a status value and controls whether the output links will be used
|
||||
or not. The record can also raise an alarm with a chosen severity if the status
|
||||
value is non-zero.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Record-specific Menus
|
||||
|
||||
=head3 Menu aSubLFLG
|
||||
|
||||
The LFLG field uses this menu to ...
|
||||
The LFLG menu field controls whether the SUBL link will be read to update
|
||||
the name of the subroutine to be called when the record processes.
|
||||
|
||||
=menu aSubLFLG
|
||||
|
||||
=head3 Menu aSubEFLG
|
||||
|
||||
The EFLG field uses this menu to ...
|
||||
|
||||
=menu aSubEFLG
|
||||
|
||||
...
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype aSub
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
menu(aSubLFLG) {
|
||||
@@ -42,14 +58,69 @@ menu(aSubLFLG) {
|
||||
choice(aSubLFLG_READ,"READ")
|
||||
}
|
||||
|
||||
=head3 Menu aSubEFLG
|
||||
|
||||
The EFLG menu field indicates whether monitor events should be posted for the
|
||||
VALA..VALU output value fields.
|
||||
|
||||
=menu aSubEFLG
|
||||
|
||||
=cut
|
||||
|
||||
menu(aSubEFLG) {
|
||||
choice(aSubEFLG_NEVER,"NEVER")
|
||||
choice(aSubEFLG_ON_CHANGE,"ON CHANGE")
|
||||
choice(aSubEFLG_ALWAYS,"ALWAYS")
|
||||
}
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype aSub
|
||||
|
||||
=cut
|
||||
|
||||
recordtype(aSub) {
|
||||
include "dbCommon.dbd"
|
||||
|
||||
=head3 Subroutine Fields
|
||||
|
||||
The VAL field is set to the value returned by the user subroutine.
|
||||
The value is treated as an error status value where zero mean success.
|
||||
The output links OUTA ... OUTU will only be used to forward the associated
|
||||
output value fields when the subroutine has returned a zero status.
|
||||
If the return status was non-zero, the record will be put into C<SOFT_ALARM>
|
||||
state with severity given by the BRSV field.
|
||||
|
||||
The INAM field may be used to name a subroutine that will be called once at
|
||||
IOC initialization time.
|
||||
|
||||
LFLG tells the record whether to read or ignore the SUBL link.
|
||||
If the value is C<READ>, then the name of the subroutine to be called at
|
||||
process time is read from SUBL.
|
||||
If the value is C<IGNORE>, the name of the subroutine is that currently held
|
||||
in SNAM.
|
||||
|
||||
A string is read from the SUBL link to fetch the name of the subroutine to
|
||||
be run during record processing.
|
||||
|
||||
SNAM holds the name of the subroutine to be called when the record processes.
|
||||
The value in this field can be overwritten by the SUBL link if LFLG is set
|
||||
to C<READ>.
|
||||
|
||||
The SADR field is only accessible from C code; it points to the subroutine
|
||||
to be called.
|
||||
|
||||
The CADR field may be set by the user subroutine to point to another function
|
||||
that will be called immediately before setting the SADR field to some other
|
||||
routine. This allows the main user subroutine to allocate resources when it is
|
||||
first called and be able to release them again when they are no longer needed.
|
||||
|
||||
=fields VAL, OVAL, INAM, LFLG, SUBL, SNAM, ONAM, SADR, CADR, BRSV
|
||||
|
||||
=cut
|
||||
|
||||
field(VAL,DBF_LONG) {
|
||||
prompt("Subr. return value")
|
||||
asl(ASL0)
|
||||
@@ -112,12 +183,34 @@ recordtype(aSub) {
|
||||
interest(1)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
The PREC field specifies the number of decimal places with which to display
|
||||
the values of the value fields A ... U and VALA ... VALU.
|
||||
Except when it doesn't.
|
||||
|
||||
=cut
|
||||
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
|
||||
=head3 Output Event Flag
|
||||
|
||||
This field tells the record when to post change events on the output fields
|
||||
VALA ... VALU. If the value is C<NEVER>, events are never posted. If the value
|
||||
is C<ALWAYS>, events are posted every time the record processes. If the value
|
||||
is C<ON CHANGE>, events are posted when any element of an array changes value.
|
||||
This flag controls value, log (archive) and alarm change events.
|
||||
|
||||
=fields EFLG
|
||||
|
||||
=cut
|
||||
|
||||
field(EFLG,DBF_MENU) {
|
||||
prompt("Output Event Flag")
|
||||
promptgroup("50 - Output")
|
||||
@@ -125,6 +218,16 @@ recordtype(aSub) {
|
||||
menu(aSubEFLG)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=head3 Input Link Fields
|
||||
|
||||
The input links from where the values of A,...,U are fetched
|
||||
during record processing.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL, INPM, INPN, INPO, INPP, INPQ, INPR, INPS, INPT, INPU
|
||||
|
||||
=cut
|
||||
|
||||
field(INPA,DBF_INLINK) {
|
||||
prompt("Input Link A")
|
||||
promptgroup("41 - Input A-G")
|
||||
@@ -231,9 +334,10 @@ recordtype(aSub) {
|
||||
interest(1)
|
||||
}
|
||||
|
||||
=head3 Input Fields
|
||||
=head3 Input Value Fields
|
||||
|
||||
...
|
||||
Thse fields hold the scalar or array values fetched through the input links
|
||||
INPA,...,INPU.
|
||||
|
||||
=fields A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U
|
||||
|
||||
@@ -449,6 +553,16 @@ recordtype(aSub) {
|
||||
#=write Yes
|
||||
#=type Set by FTU
|
||||
}
|
||||
|
||||
=head3 Input Value Data Types
|
||||
|
||||
Field types of the input value fields.
|
||||
The choices can be found by following the link to the menuFtype definition.
|
||||
|
||||
=fields FTA, FTB, FTC, FTD, FTE, FTF, FTG, FTH, FTI, FTJ, FTK, FTL, FTM, FTN, FTO, FTP, FTQ, FTR, FTS, FTT, FTU
|
||||
|
||||
=cut
|
||||
|
||||
field(FTA,DBF_MENU) {
|
||||
prompt("Type of A")
|
||||
promptgroup("41 - Input A-G")
|
||||
@@ -617,6 +731,15 @@ recordtype(aSub) {
|
||||
initial("DOUBLE")
|
||||
menu(menuFtype)
|
||||
}
|
||||
|
||||
=head3 Input Value Array Capacity
|
||||
|
||||
These fields specify how many array elements the input value fields may hold.
|
||||
|
||||
=fields NOA, NOB, NOC, NOD, NOE, NOF, NOG, NOH, NOI, NOJ, NOK, NOL, NOM, NON, NOO, NOP, NOQ, NOR, NOS, NOT, NOU
|
||||
|
||||
=cut
|
||||
|
||||
field(NOA,DBF_ULONG) {
|
||||
prompt("Max. elements in A")
|
||||
promptgroup("41 - Input A-G")
|
||||
@@ -764,6 +887,16 @@ recordtype(aSub) {
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=head3 Input Value Array Size
|
||||
|
||||
These fields specify how many array elements the input value fields currently
|
||||
contain.
|
||||
|
||||
=fields NEA, NEB, NEC, NED, NEE, NEF, NEG, NEH, NEI, NEJ, NEK, NEL, NEM, NEN, NEO, NEP, NEQ, NER, NES, NET, NEU
|
||||
|
||||
=cut
|
||||
|
||||
field(NEA,DBF_ULONG) {
|
||||
prompt("Num. elements in A")
|
||||
special(SPC_NOMOD)
|
||||
@@ -890,6 +1023,15 @@ recordtype(aSub) {
|
||||
interest(3)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=head3 Output Link Fields
|
||||
|
||||
The output links through which the VALA ... VALU field values are sent
|
||||
during record processing, provided the subroutine returned 0.
|
||||
|
||||
=fields OUTA, OUTB, OUTC, OUTD, OUTE, OUTF, OUTG, OUTH, OUTI, OUTJ, OUTK, OUTL, OUTM, OUTN, OUTO, OUTP, OUTQ, OUTR, OUTS, OUTT, OUTU
|
||||
|
||||
=cut
|
||||
field(OUTA,DBF_OUTLINK) {
|
||||
prompt("Output Link A")
|
||||
promptgroup("51 - Output A-G")
|
||||
@@ -996,9 +1138,10 @@ recordtype(aSub) {
|
||||
interest(1)
|
||||
}
|
||||
|
||||
=head3 Value Fields
|
||||
=head3 Output Value Fields
|
||||
|
||||
...
|
||||
These fields hold scalar or array data generated by the subroutine which will
|
||||
be sent through the OUTA ... OUTU links during record processing.
|
||||
|
||||
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
|
||||
|
||||
@@ -1214,6 +1357,16 @@ recordtype(aSub) {
|
||||
#=write Yes
|
||||
#=type Set by FTVU
|
||||
}
|
||||
|
||||
=head3 Old Value Fields
|
||||
|
||||
The previous values of the output fields.
|
||||
These are used to determine when to post events if EFLG is set to C<ON CHANGE>.
|
||||
|
||||
=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU
|
||||
|
||||
=cut
|
||||
|
||||
field(OVLA,DBF_NOACCESS) {
|
||||
prompt("Old Output A")
|
||||
asl(ASL0)
|
||||
@@ -1361,6 +1514,16 @@ recordtype(aSub) {
|
||||
interest(4)
|
||||
extra("void *ovlu")
|
||||
}
|
||||
|
||||
=head3 Output Value Data Types
|
||||
|
||||
Field types of the output value fields.
|
||||
The choices can be found by following a link to the menuFtype definition.
|
||||
|
||||
=fields FTVA, FTVB, FTVC, FTVD, FTVE, FTVF, FTVG, FTVH, FTVI, FTVJ, FTVK, FTVL, FTVM, FTVN, FTVO, FTVP, FTVQ, FTVR, FTVS, FTVT, FTVU
|
||||
|
||||
=cut
|
||||
|
||||
field(FTVA,DBF_MENU) {
|
||||
prompt("Type of VALA")
|
||||
promptgroup("51 - Output A-G")
|
||||
@@ -1529,6 +1692,15 @@ recordtype(aSub) {
|
||||
initial("DOUBLE")
|
||||
menu(menuFtype)
|
||||
}
|
||||
|
||||
=head3 Output Value Array Capacity
|
||||
|
||||
These fields specify how many array elements the output value fields may hold.
|
||||
|
||||
=fields NOVA, NOVB, NOVC, NOVD, NOVE, NOVF, NOVG, NOVH, NOVI, NOVJ, NOVK, NOVL, NOVM, NOVN, NOVO, NOVP, NOVQ, NOVR, NOVS, NOVT, NOVU
|
||||
|
||||
=cut
|
||||
|
||||
field(NOVA,DBF_ULONG) {
|
||||
prompt("Max. elements in VALA")
|
||||
promptgroup("51 - Output A-G")
|
||||
@@ -1676,6 +1848,16 @@ recordtype(aSub) {
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=head3 Output Value Array Size
|
||||
|
||||
These fields specify how many array elements the output value fields currently
|
||||
contain.
|
||||
|
||||
=fields NEVA, NEVB, NEVC, NEVD, NEVE, NEVF, NEVG, NEVH, NEVI, NEVJ, NEVK, NEVL, NEVM, NEVN, NEVO, NEVP, NEVQ, NEVR, NEVS, NEVT, NEVU
|
||||
|
||||
=cut
|
||||
|
||||
field(NEVA,DBF_ULONG) {
|
||||
prompt("Num. elements in VALA")
|
||||
special(SPC_NOMOD)
|
||||
@@ -1802,6 +1984,16 @@ recordtype(aSub) {
|
||||
interest(3)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=head3 Old Value Array Size
|
||||
|
||||
These fields specify how many array elements the old value fields currently
|
||||
contain.
|
||||
|
||||
=fields ONVA, ONVB, ONVC, ONVD, ONVE, ONVF, ONVG, ONVH, ONVI, ONVJ, ONVK, ONVL, ONVM, ONVN, ONVO, ONVP, ONVQ, ONVR, ONVS, ONVT, ONVU
|
||||
|
||||
=cut
|
||||
|
||||
field(ONVA,DBF_ULONG) {
|
||||
prompt("Num. elements in OVLA")
|
||||
special(SPC_NOMOD)
|
||||
@@ -1928,4 +2120,305 @@ recordtype(aSub) {
|
||||
interest(4)
|
||||
initial("1")
|
||||
}
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=head2 Record Support Routines
|
||||
|
||||
=head3 init_record
|
||||
|
||||
long (*init_record)(struct dbCommon *precord, int pass)
|
||||
|
||||
This routine is called twice at iocInit. On the first call it does the
|
||||
following:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Calloc sufficient space to hold the number of input scalars and/or arrays
|
||||
defined by the settings of the fields FTA-FTU and NOA-NOU. Initialize fields
|
||||
NE* to the values of the associated NO* field values.
|
||||
|
||||
=item *
|
||||
|
||||
Calloc sufficient space to hold the number of output scalars and/or arrays
|
||||
defined by the settings of the fields FTVA-FTVU and NOVA-NOVU. For the output
|
||||
fields, also calloc space to hold the previous value of a field. This is
|
||||
required when the decision is made on whether or not to post events.
|
||||
|
||||
=back
|
||||
|
||||
On the second call, it does the following:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Initializes SUBL if it is a constant link.
|
||||
|
||||
=item *
|
||||
|
||||
Initializes each constant input link.
|
||||
|
||||
=item *
|
||||
|
||||
If the field INAM is set, look-up the address of the routine and call it.
|
||||
|
||||
=item *
|
||||
|
||||
If the field LFLG is set to IGNORE and SNAM is defined, look up the address of
|
||||
the process routine.
|
||||
|
||||
=back
|
||||
|
||||
=head3 process
|
||||
|
||||
long (*process)(struct dbCommon *precord)
|
||||
|
||||
This routine implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
If PACT is FALSE, perform normal processing
|
||||
|
||||
=item *
|
||||
|
||||
If PACT is TRUE, perform asynchronous-completion processing
|
||||
|
||||
=back
|
||||
|
||||
Normal processing:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to TRUE.
|
||||
|
||||
=item *
|
||||
|
||||
If the field LFLG is set to READ, get the subroutine name from the SUBL link.
|
||||
If the name is not NULL and it is not the same as the previous subroutine name,
|
||||
look up the subroutine address. Set the old subroutine name, ONAM, equal to the
|
||||
current name, SNAM.
|
||||
|
||||
=item *
|
||||
|
||||
Fetch the values from the input links.
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to FALSE
|
||||
|
||||
=item *
|
||||
|
||||
If all input-link fetches succeeded, call the routine specified by SNAM.
|
||||
|
||||
=item *
|
||||
|
||||
Set VAL equal to the return value from the routine specified by SNAM.
|
||||
|
||||
=item *
|
||||
|
||||
If the SNAM routine set PACT to TRUE, then return. In this case, we presume
|
||||
the routine has arranged that process will be called at some later time for
|
||||
asynchronous completion.
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to TRUE.
|
||||
|
||||
=item *
|
||||
|
||||
If VAL is zero, write the output values using the output links.
|
||||
|
||||
=item *
|
||||
|
||||
Get the time of processing and put it into the timestamp field.
|
||||
|
||||
=item *
|
||||
|
||||
If VAL has changed, post a change-of value and log event for this field.
|
||||
If EFLG is set to ALWAYS, post change-of-value and log events for every output
|
||||
field. If EFLG is set to ON CHANGE, post change-of-value and log events for
|
||||
every output field which has changed. In the case of an array, an event will be
|
||||
posted if any single element of the array has changed. If EFLG is set to NEVER,
|
||||
no change-of-value or log events are posted for the output fields.
|
||||
|
||||
=item *
|
||||
|
||||
Process the record on the end of the forward link, if one exists.
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to FALSE.
|
||||
|
||||
=back
|
||||
|
||||
Asynchronous-completion processing:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Call the routine specified by SNAM (again).
|
||||
|
||||
=item *
|
||||
|
||||
Set VAL equal to the return value from the routine specified by SNAM.
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to TRUE.
|
||||
|
||||
=item *
|
||||
|
||||
If VAL is zero, write the output values using the output links.
|
||||
|
||||
=item *
|
||||
|
||||
Get the time of processing and put it into the timestamp field.
|
||||
|
||||
=item *
|
||||
|
||||
If VAL has changed, post a change-of value and log event for this field. If
|
||||
EFLG is set to ALWAYS, post change-of-value and log events for every output
|
||||
field. If EFLG is set to ON CHANGE, post change-of-value and log events for
|
||||
every output field which has changed. In the case of an array, an event will
|
||||
be posted if any single element of the array has changed. If EFLG is set to
|
||||
NEVER, no change-of-value or log events are posted for the output fields.
|
||||
|
||||
=item *
|
||||
|
||||
Process the record on the end of the forward link, if one exists.
|
||||
|
||||
=item *
|
||||
|
||||
Set PACT to FALSE.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=head2 Use of the aSub Record
|
||||
|
||||
The aSub record has input-value fields (A-U) and output-value fields
|
||||
(VALA-VALU), which are completely independent. The input-value fields have
|
||||
associated input links (INPA-INPU), and the output-value fields have associated
|
||||
output links (OUTA-OUTU). Both inputs and outputs have type fields (FTA-FTU,
|
||||
FTVA-FTVU, which default to 'DOUBLE') and number-of-element fields (NOA-NOU,
|
||||
NOVA-NOVU, which default to '1'). The output links OUTA-OUTU will only be
|
||||
processed if the subroutine returns a zero (OK) status value.
|
||||
|
||||
=head3 Example database fragment
|
||||
|
||||
To use the A field to read an array from some other record, then, you would
|
||||
need a database fragment that might look something like this:
|
||||
|
||||
record(aSub,"my_asub_record") {
|
||||
field(SNAM,"my_asub_routine")
|
||||
...
|
||||
field(FTA, "LONG")
|
||||
field(NOA, "100")
|
||||
field(INPA, "myWaveform_1 NPP NMS")
|
||||
...
|
||||
}
|
||||
|
||||
If you wanted some other record to be able to write to the A field, then you
|
||||
would delete the input link above. If you wanted the A field to hold a scalar
|
||||
value, you would either delete the NOA specification, or specify it as "1".
|
||||
|
||||
=head3 Example subroutine fragment
|
||||
|
||||
The associated subroutine code that uses the A field might look like this:
|
||||
|
||||
static long my_asub_routine(aSubRecord *prec) {
|
||||
long i, *a;
|
||||
double sum=0;
|
||||
...
|
||||
a = (long *)prec->a;
|
||||
for (i=0; i<prec->noa; i++) {
|
||||
sum += a[i];
|
||||
}
|
||||
...
|
||||
return 0; /* process output links */
|
||||
}
|
||||
|
||||
Note that the subroutine code must always handle the value fields (A-U,
|
||||
VALA-VALU) as arrays, even if they contain only a single element.
|
||||
|
||||
=head3 Required export code
|
||||
|
||||
Aside from your own code, you must export and register your subroutines so the
|
||||
record can locate them. The simplest way is as follows:
|
||||
|
||||
#include <registryFunction.h>
|
||||
#include <epicsExport.h>
|
||||
|
||||
static long my_asub_routine(aSubRecord *prec) {
|
||||
...
|
||||
}
|
||||
epicsRegisterFunction(my_asub_routine);
|
||||
|
||||
=head3 Required database-definition code
|
||||
|
||||
The .dbd file loaded by the ioc must then contain the following line, which
|
||||
tells the linker to include your object file in the IOC binary:
|
||||
|
||||
function(my_asub_routine)
|
||||
|
||||
=head3 Device support, writing to hardware
|
||||
|
||||
The aSub record does not call any device support routines. If you want to write
|
||||
to hardware, you might use your output fields and links to write to some other
|
||||
record that can write to hardware.
|
||||
|
||||
=head3 Dynamically Changing the User Routine called during Record Processing
|
||||
|
||||
The aSub record allows the user to dynamically change which routine is called
|
||||
when the record processes. This can be done in two ways:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
The LFLG field can be set to READ so that the name of the routine is read from
|
||||
the SUBL link. Thus, whatever is feeding this link can change the name of the
|
||||
routine before the aSub record is processed. In this case, the record looks in
|
||||
the symbol table for the symbol name whenever the name of routine fetched from
|
||||
the link changes.
|
||||
|
||||
=item *
|
||||
|
||||
The LFLG field can be set to IGNORE. In this case, the routine called during
|
||||
record processing is that specified in the SNAM field. Under these conditions,
|
||||
the SNAM field can be changed by a Channel Access write to that field. During
|
||||
development when trying several versions of the routine, it is not necessary
|
||||
to reboot the IOC and reload the database. A new routine can be loaded with
|
||||
the vxWorks ld command, and Channel Access or the dbpf command used to put the
|
||||
name of the routine into the record's SNAM field. The record will look up the
|
||||
symbol name in the symbol table whenever the SNAM field gets modified. The
|
||||
same routine name can even be used as the vxWorks symbol lookup returns the
|
||||
latest version of the code to have been loaded.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
}
|
||||
|
||||
@@ -90,22 +90,13 @@ rset aaiRSET={
|
||||
};
|
||||
epicsExportAddress(rset,aaiRSET);
|
||||
|
||||
struct aaidset { /* aai dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_aai; /*returns: (-1,0)=>(failure,success)*/
|
||||
};
|
||||
|
||||
static void monitor(aaiRecord *);
|
||||
static long readValue(aaiRecord *);
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct aaiRecord *prec = (struct aaiRecord *)pcommon;
|
||||
struct aaidset *pdset = (struct aaidset *)(prec->dset);
|
||||
aaidset *pdset = (aaidset *)(prec->dset);
|
||||
|
||||
/* must have dset defined */
|
||||
if (!pdset) {
|
||||
@@ -125,8 +116,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
not change after links are established before pass 1
|
||||
*/
|
||||
|
||||
if (pdset->init_record) {
|
||||
long status = pdset->init_record(prec);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
/* init_record may set the bptr to point to the data */
|
||||
if (status)
|
||||
@@ -143,7 +134,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have read_aai function defined */
|
||||
if (pdset->number < 5 || pdset->read_aai == NULL) {
|
||||
if (pdset->common.number < 5 || pdset->read_aai == NULL) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "aai: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
@@ -153,7 +144,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct aaiRecord *prec = (struct aaiRecord *)pcommon;
|
||||
struct aaidset *pdset = (struct aaidset *)(prec->dset);
|
||||
aaidset *pdset = (aaidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact = prec->pact;
|
||||
|
||||
@@ -339,7 +330,7 @@ static void monitor(aaiRecord *prec)
|
||||
|
||||
static long readValue(aaiRecord *prec)
|
||||
{
|
||||
struct aaidset *pdset = (struct aaidset *) prec->dset;
|
||||
aaidset *pdset = (aaidset *) prec->dset;
|
||||
long status;
|
||||
|
||||
/* NB: Device support must post updates to NORD */
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
menu(aaiPOST) {
|
||||
choice(aaiPOST_Always,"Always")
|
||||
choice(aaiPOST_OnChange,"On Change")
|
||||
}
|
||||
recordtype(aai) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup("40 - Input")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
menu(menuFtype)
|
||||
}
|
||||
field(NORD,DBF_ULONG) {
|
||||
prompt("Number elements read")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaiPOST)
|
||||
}
|
||||
field(APST,DBF_MENU) {
|
||||
prompt("Post Archive Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaiPOST)
|
||||
}
|
||||
field(HASH,DBF_ULONG) {
|
||||
prompt("Hash of OnChange data.")
|
||||
interest(3)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Array Analog Input (aai)
|
||||
|
||||
The array analog input record type is used to read array data. The array data can
|
||||
contain any of the supported data types. The record is in many ways similar to the
|
||||
waveform record. It allows, however, the device support to allocate the array
|
||||
storage.
|
||||
|
||||
=recordtype aai
|
||||
|
||||
=cut
|
||||
|
||||
menu(aaiPOST) {
|
||||
choice(aaiPOST_Always,"Always")
|
||||
choice(aaiPOST_OnChange,"On Change")
|
||||
}
|
||||
|
||||
recordtype(aai) {
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=head3 Scan Parameters
|
||||
|
||||
The array analog input record has the standard fields for specifying under what
|
||||
circumstances the record will be processed.
|
||||
These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
These fields are configurable by the user to specify how and from where the record
|
||||
reads its data. The INP field determines from where the array analog input gets
|
||||
its input. It can be a hardware address, a channel access or database link, or a
|
||||
constant. Only in records that use soft device support can the INP field be a
|
||||
channel access link, a database link, or a constant. Otherwise, the INP field must
|
||||
be a hardware address.
|
||||
|
||||
=head4 Fields related to waveform reading
|
||||
|
||||
The DTYP field must contain the name of the appropriate device support module.
|
||||
The values retrieved from the input link are placed in an array referenced by
|
||||
VAL. (If the INP link is a constant, elements can be placed in the array via
|
||||
dbPuts.) NELM specifies the number of elements that the array will hold, while
|
||||
FTVL specifies the data type of the elements (follow the link in the table below
|
||||
for a list of the available choices).
|
||||
|
||||
=fields DTYP, INP, NELM, FTVL
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator. They
|
||||
display the value and other parameters of the waveform either textually or
|
||||
graphically.
|
||||
|
||||
=head4 Fields related to I<Operator Display>
|
||||
|
||||
EGU is a string of up to 16 characters describing the units that the array data
|
||||
measures. It is retrieved by the C<<< get_units() >>> record support routine.
|
||||
|
||||
The HOPR and LOPR fields set the upper and lower display limits for array
|
||||
elements referenced by the VAL field. Both the C<<< get_graphic_double() >>> and
|
||||
C<<< get_control_double() >>> record support routines retrieve these fields.
|
||||
|
||||
The PREC field determines the floating point precision with which to display the
|
||||
array values. It is used whenever the C<<< get_precision() >>> record support
|
||||
routine is called.
|
||||
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
|
||||
=fields EGU, HOPR, LOPR, PREC, NAME, DESC
|
||||
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The array analog input record has the alarm parameters common to all record types.
|
||||
|
||||
=head3 Monitor Parameters
|
||||
|
||||
These parameters are used to determine when to send monitors placed on the VAL
|
||||
field. The APST and MPST fields are a menu with choices C<Always> and C<On
|
||||
Change>. The default is C<Always>, thus monitors will normally be sent every time
|
||||
the record processes. Selecting C<On Change> causes a 32-bit hash of the VAL
|
||||
field buffer to be calculated and compared with the previous hash value every
|
||||
time the record processes; the monitor will only be sent if the hash is
|
||||
different, indicating that the buffer has changed. Note that there is a small
|
||||
chance that two different value buffers might result in the same hash value, so
|
||||
for critical systems C<Always> may be a better choice, even though it re-sends
|
||||
duplicate data.
|
||||
|
||||
=fields APST, MPST, HASH
|
||||
|
||||
=head4 Menu aaiPOST
|
||||
|
||||
These are the possible choices for the C<APST> and C<MPST> fields:
|
||||
|
||||
=menu aaiPOST
|
||||
|
||||
=head3 Run-time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the array analog
|
||||
input record. They are not configured using a configuration tool. Only the VAL
|
||||
field is modifiable at run-time.
|
||||
|
||||
VAL references the array where the array analog input record stores its data. The
|
||||
BPTR field holds the address of the array.
|
||||
|
||||
The NORD field holds a counter of the number of elements that have been read
|
||||
into the array.
|
||||
|
||||
=fields VAL, BPTR, NORD
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is fetched through SIOL.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Input Simulation Fields|dbCommonInput/Input Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
=head3 Record Support Routines
|
||||
|
||||
=head4 init_record
|
||||
|
||||
static long init_record(aaiRecord *prec, int pass)
|
||||
|
||||
If device support includes C<init_record()>, it is called.
|
||||
|
||||
Checks if device support allocated array space. If not, space for the array is
|
||||
allocated using NELM and FTVL. The array address is stored in the record.
|
||||
|
||||
This routine initializes SIMM with the value of SIML if SIML type is CONSTANT
|
||||
link or creates a channel access link if SIML type is PV_LINK. VAL is likewise
|
||||
initialized if SIOL is CONSTANT or PV_LINK.
|
||||
|
||||
This routine next checks to see that device support is available and a device
|
||||
support read routine is defined. If either does not exist, an error message is
|
||||
issued and processing is terminated
|
||||
|
||||
=head4 process
|
||||
|
||||
static long process(aaiRecord *prec)
|
||||
|
||||
See L</"Record Processing"> section below.
|
||||
|
||||
=head4 cvt_dbaddr
|
||||
|
||||
static long cvt_dbaddr(DBADDR *paddr)
|
||||
|
||||
This is called by dbNameToAddr. It makes the dbAddr structure refer to the
|
||||
actual buffer holding the result.
|
||||
|
||||
=head4 get_array_info
|
||||
|
||||
static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
|
||||
Obtains values from the array referenced by VAL.
|
||||
|
||||
=head4 put_array_info
|
||||
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
|
||||
Writes values into the array referenced by VAL.
|
||||
|
||||
=head4 get_units
|
||||
|
||||
static long get_units(DBADDR *paddr, char *units)
|
||||
|
||||
Retrieves EGU.
|
||||
|
||||
=head4 get_prec
|
||||
|
||||
static long get_precision(DBADDR *paddr, long *precision)
|
||||
|
||||
Retrieves PREC if field is VAL field. Otherwise, calls C<<< recGblGetPrec() >>>.
|
||||
|
||||
=head4 get_graphic_double
|
||||
|
||||
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
|
||||
Sets the upper display and lower display limits for a field. If the field is VAL
|
||||
the limits are set to HOPR and LOPR, else if the field has upper and lower
|
||||
limits defined they will be used, else the upper and lower maximum values for
|
||||
the field type will be used.
|
||||
|
||||
Sets the following values:
|
||||
|
||||
upper_disp_limit = HOPR
|
||||
lower_disp_limit = LOPR
|
||||
|
||||
=head4 get_control_double
|
||||
|
||||
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
|
||||
Sets the upper control and the lower control limits for a field. If the field is
|
||||
VAL the limits are set to HOPR and LOPR, else if the field has upper and lower
|
||||
limits defined they will be used, else the upper and lower maximum values for
|
||||
the field type will be used.
|
||||
|
||||
Sets the following values
|
||||
|
||||
upper_ctrl_limit = HOPR
|
||||
lower_ctrl_limit = LOPR
|
||||
|
||||
=head3 Record Processing
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module exists. If it doesn't,
|
||||
an error message is issued and processing is terminated with the PACT field
|
||||
still set to TRUE. This ensures that processes will no longer be called for this
|
||||
record. Thus error storms will not occur.
|
||||
|
||||
=item 2.
|
||||
|
||||
Call device support read routine C<read_aai()>.
|
||||
|
||||
=item 3.
|
||||
|
||||
If PACT has been changed to TRUE, the device support read routine has started
|
||||
but has not completed writing the new value. In this case, the processing
|
||||
routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Alarm monitors are invoked if the alarm status or severity has changed.
|
||||
|
||||
=item *
|
||||
|
||||
Archive and value change monitors are invoked if APST or MPST are Always or if
|
||||
the result of the hash calculation is different.
|
||||
|
||||
=item *
|
||||
|
||||
NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=item 5.
|
||||
|
||||
Scan forward link if necessary, set PACT FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct aaiRecord;
|
||||
%typedef struct aaidset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*read_aai)(struct aaiRecord *prec); /*returns: (-1,0)=>(failure,success)*/
|
||||
%} aaidset;
|
||||
%#define HAS_aaidset
|
||||
%
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[NELM]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup("40 - Input")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
menu(menuFtype)
|
||||
}
|
||||
field(NORD,DBF_ULONG) {
|
||||
prompt("Number elements read")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaiPOST)
|
||||
}
|
||||
field(APST,DBF_MENU) {
|
||||
prompt("Post Archive Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaiPOST)
|
||||
}
|
||||
field(HASH,DBF_ULONG) {
|
||||
prompt("Hash of OnChange data.")
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head2 Device Support
|
||||
|
||||
=head3 Fields Of Interest To Device Support
|
||||
|
||||
Each array analog input record record must have an associated set of device
|
||||
support routines. The primary responsibility of the device support routines is to
|
||||
obtain a new array value whenever C<read_aai()> is called. The device support
|
||||
routines are primarily interested in the following fields:
|
||||
|
||||
=fields PACT, DPVT, NSEV, NSTA, INP, NELM, FTVL, BPTR, NORD
|
||||
|
||||
=head3 Device Support Routines
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=head4 report
|
||||
|
||||
long report(int level)
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=head4 init
|
||||
|
||||
long init(int after)
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=head4 init_record
|
||||
|
||||
long init_record(dbCommon *precord)
|
||||
|
||||
This routine is optional. If provided, it is called by the record support
|
||||
C<init_record()> routine.
|
||||
|
||||
=head4 get_ioint_info
|
||||
|
||||
long get_ioint_info(int cmd, dbCommon *precord, IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the
|
||||
record is being (added to, deleted from) an I/O event list. It must be
|
||||
provided for any device type that can use the ioEvent scanner.
|
||||
|
||||
=head4 read_aai
|
||||
|
||||
long read_aai(dbCommon *precord)
|
||||
|
||||
This routine must provide a new input value. It returns the following values:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
0: Success.
|
||||
|
||||
=item *
|
||||
|
||||
Other: Error.
|
||||
|
||||
=back
|
||||
|
||||
=head3 Device Support For Soft Records
|
||||
|
||||
The C<<< Soft Channel >>> device support module is provided to read values from
|
||||
other records and store them in arrays. If INP is a constant link, then read_aai
|
||||
does nothing. In this case, the record can be used to hold arrays written via
|
||||
dbPuts. If INP is a database or channel access link, the new array value is read
|
||||
from the link. NORD is set.
|
||||
|
||||
This module places a value directly in VAL and NORD is set to the number of items
|
||||
in the array.
|
||||
|
||||
If the INP link type is constant, then NORD is set to zero.
|
||||
|
||||
=cut
|
||||
}
|
||||
@@ -90,22 +90,13 @@ rset aaoRSET={
|
||||
};
|
||||
epicsExportAddress(rset,aaoRSET);
|
||||
|
||||
struct aaodset { /* aao dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_aao; /*returns: (-1,0)=>(failure,success)*/
|
||||
};
|
||||
|
||||
static void monitor(aaoRecord *);
|
||||
static long writeValue(aaoRecord *);
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct aaoRecord *prec = (struct aaoRecord *)pcommon;
|
||||
struct aaodset *pdset = (struct aaodset *)(prec->dset);
|
||||
aaodset *pdset = (aaodset *)(prec->dset);
|
||||
long status;
|
||||
|
||||
/* must have dset defined */
|
||||
@@ -130,9 +121,9 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
not change after links are established before pass 1
|
||||
*/
|
||||
|
||||
if (pdset->init_record) {
|
||||
if (pdset->common.init_record) {
|
||||
/* init_record may set the bptr to point to the data */
|
||||
if ((status = pdset->init_record(prec)))
|
||||
if ((status = pdset->common.init_record(pcommon)))
|
||||
return status;
|
||||
}
|
||||
if (!prec->bptr) {
|
||||
@@ -146,7 +137,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
/* must have write_aao function defined */
|
||||
if (pdset->number < 5 || pdset->write_aao == NULL) {
|
||||
if (pdset->common.number < 5 || pdset->write_aao == NULL) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "aao: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
@@ -156,7 +147,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct aaoRecord *prec = (struct aaoRecord *)pcommon;
|
||||
struct aaodset *pdset = (struct aaodset *)(prec->dset);
|
||||
aaodset *pdset = (aaodset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact = prec->pact;
|
||||
|
||||
@@ -339,7 +330,7 @@ static void monitor(aaoRecord *prec)
|
||||
|
||||
static long writeValue(aaoRecord *prec)
|
||||
{
|
||||
struct aaodset *pdset = (struct aaodset *) prec->dset;
|
||||
aaodset *pdset = (aaodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
menu(aaoPOST) {
|
||||
choice(aaoPOST_Always,"Always")
|
||||
choice(aaoPOST_OnChange,"On Change")
|
||||
}
|
||||
recordtype(aao) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(OUT,DBF_OUTLINK) {
|
||||
prompt("Output Specification")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
menu(menuFtype)
|
||||
}
|
||||
field(NORD,DBF_ULONG) {
|
||||
prompt("Number elements read")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaoPOST)
|
||||
}
|
||||
field(APST,DBF_MENU) {
|
||||
prompt("Post Archive Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaoPOST)
|
||||
}
|
||||
field(HASH,DBF_ULONG) {
|
||||
prompt("Hash of OnChange data.")
|
||||
interest(3)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,519 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Array Analog Output (aao)
|
||||
|
||||
The array analog output record type is used to write array data. The array data
|
||||
can contain any of the supported data types. The record is in many ways similar to
|
||||
the waveform record but outputs arrays instead of reading them. It also allows the
|
||||
device support to allocate the array storage.
|
||||
|
||||
=recordtype aao
|
||||
|
||||
=cut
|
||||
|
||||
menu(aaoPOST) {
|
||||
choice(aaoPOST_Always,"Always")
|
||||
choice(aaoPOST_OnChange,"On Change")
|
||||
}
|
||||
|
||||
recordtype(aao) {
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=head3 Scan Parameters
|
||||
|
||||
The array analog output record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. These fields are listed in L<Scan
|
||||
Fields>. In addition, L<Scanning Specification> explains how these fields are
|
||||
used. I/O event scanning is only available when supported by device support.
|
||||
|
||||
=head3 Write Parameters
|
||||
|
||||
These fields are configurable by the user to specify how and where to the record
|
||||
writes its data. The OUT field determines where the array analog output writes its
|
||||
output. It can be a hardware address, a channel access or database link, or a
|
||||
constant. Only in records that use soft device support can the OUT field be a
|
||||
channel access link, a database link, or a constant. Otherwise, the OUT field must
|
||||
be a hardware address. See L<Address Specification> for information on the format
|
||||
of hardware addresses and database links.
|
||||
|
||||
=head4 Fields related to array writing
|
||||
|
||||
The DTYP field must contain the name of the appropriate device support module. The
|
||||
values in the array referenced by are written to the location specified in the OUT
|
||||
field. (If the OUT link is a constant, no data are written.) NELM specifies the
|
||||
maximum number of elements that the array can hold, while FTVL specifies the data
|
||||
type of the elements (follow the link in the table below for a list of the
|
||||
available choices).
|
||||
|
||||
=fields DTYP, OUT, NELM, FTVL
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator. They
|
||||
display the value and other parameters of the waveform either textually or
|
||||
graphically.
|
||||
|
||||
=head4 Fields related to I<Operator Display>
|
||||
|
||||
EGU is a string of up to 16 characters describing the units that the array data
|
||||
measures. It is retrieved by the C<<< get_units >>> record support routine.
|
||||
|
||||
The HOPR and LOPR fields set the upper and lower display limits for array
|
||||
elements referenced by the VAL field. Both the C<<< get_graphic_double >>> and
|
||||
C<<< get_control_double >>> record support routines retrieve these fields.
|
||||
|
||||
The PREC field determines the floating point precision with which to display the
|
||||
array values. It is used whenever the C<<< get_precision >>> record support
|
||||
routine is called.
|
||||
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
|
||||
=fields EGU, HOPR, LOPR, PREC, NAME, DESC
|
||||
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The array analog output record has the alarm parameters common to all record
|
||||
types.
|
||||
|
||||
=head3 Monitor Parameters
|
||||
|
||||
These parameters are used to determine when to send monitors placed on the VAL
|
||||
field. The APST and MPST fields are a menu with choices "Always" and "On
|
||||
Change". The default is "Always", thus monitors will normally be sent every time
|
||||
the record processes. Selecting "On Change" causes a 32-bit hash of the VAL
|
||||
field buffer to be calculated and compared with the previous hash value every
|
||||
time the record processes; the monitor will only be sent if the hash is
|
||||
different, indicating that the buffer has changed. Note that there is a small
|
||||
chance that two different value buffers might result in the same hash value, so
|
||||
for critical systems "Always" may be a better choice, even though it re-sends
|
||||
duplicate data.
|
||||
|
||||
=head4 Record fields related to I<Monitor Parameters>
|
||||
|
||||
=fields APST, MPST, HASH
|
||||
|
||||
=head4 Menu aaoPOST
|
||||
|
||||
These are the choices available for the C<APST> and C<MPST> fields
|
||||
|
||||
=menu aaoPOST
|
||||
|
||||
=head3 Run-time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the array analog
|
||||
output record. They are not configured using a configuration tool. Only the VAL
|
||||
field is modifiable at run-time.
|
||||
|
||||
VAL references the array where the array analog output record stores its data. The
|
||||
BPTR field holds the address of the array.
|
||||
|
||||
The NORD field holds a counter of the number of elements that have been written to
|
||||
the output,
|
||||
|
||||
=fields VAL, BPTR, NORD
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is written through SIOL.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Output Simulation Fields|dbCommonOutput/Output Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
=head3 Record Support Routines
|
||||
|
||||
=head4 init_record
|
||||
|
||||
static long init_record(aaoRecord *prec, int pass)
|
||||
|
||||
If device support includes C<init_record()>, it is called.
|
||||
|
||||
Checks if device support allocated array space. If not, space for the array is
|
||||
allocated using NELM and FTVL. The array address is stored in the record.
|
||||
|
||||
This routine initializes SIMM with the value of SIML if SIML type is CONSTANT
|
||||
link or creates a channel access link if SIML type is PV_LINK. VAL is likewise
|
||||
initialized if SIOL is CONSTANT or PV_LINK.
|
||||
|
||||
This routine next checks to see that device support is available and a device
|
||||
support write routine is defined. If either does not exist, an error message is
|
||||
issued and processing is terminated
|
||||
|
||||
=head4 process
|
||||
|
||||
static long process(aaoRecord *prec)
|
||||
|
||||
See L</"Record Processing"> section below.
|
||||
|
||||
=head4 cvt_dbaddr
|
||||
|
||||
static long cvt_dbaddr(DBADDR *paddr)
|
||||
|
||||
This is called by dbNameToAddr. It makes the dbAddr structure refer to the
|
||||
actual buffer holding the result.
|
||||
|
||||
=head4 get_array_info
|
||||
|
||||
static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
|
||||
Obtains values from the array referenced by VAL.
|
||||
|
||||
=head4 put_array_info
|
||||
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
|
||||
Writes values into the array referenced by VAL.
|
||||
|
||||
=head4 get_units
|
||||
|
||||
static long get_units(DBADDR *paddr, char *units)
|
||||
|
||||
Retrieves EGU.
|
||||
|
||||
=head4 get_prec
|
||||
|
||||
static long get_precision(DBADDR *paddr, long *precision)
|
||||
|
||||
Retrieves PREC if field is VAL field. Otherwise, calls C<<< recGblGetPrec() >>>.
|
||||
|
||||
=head4 get_graphic_double
|
||||
|
||||
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
|
||||
Sets the upper display and lower display limits for a field. If the field is VAL
|
||||
the limits are set to HOPR and LOPR, else if the field has upper and lower
|
||||
limits defined they will be used, else the upper and lower maximum values for
|
||||
the field type will be used.
|
||||
|
||||
Sets the following values:
|
||||
|
||||
upper_disp_limit = HOPR
|
||||
lower_disp_limit = LOPR
|
||||
|
||||
=head4 get_control_double
|
||||
|
||||
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
|
||||
Sets the upper control and the lower control limits for a field. If the field is
|
||||
VAL the limits are set to HOPR and LOPR, else if the field has upper and lower
|
||||
limits defined they will be used, else the upper and lower maximum values for
|
||||
the field type will be used.
|
||||
|
||||
Sets the following values
|
||||
|
||||
upper_ctrl_limit = HOPR
|
||||
lower_ctrl_limit = LOPR
|
||||
|
||||
=head3 Record Processing
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module exists. If it doesn't,
|
||||
an error message is issued and processing is terminated with the PACT field
|
||||
still set to TRUE. This ensures that processes will no longer be called for this
|
||||
record. Thus error storms will not occur.
|
||||
|
||||
=item 2.
|
||||
|
||||
Call device support write routine C<write_aao>.
|
||||
|
||||
=item 3.
|
||||
|
||||
If PACT has been changed to TRUE, the device support read routine has started
|
||||
but has not completed writing the new value. In this case, the processing
|
||||
routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check to see if monitors should be invoked.
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Alarm monitors are invoked if the alarm status or severity has changed.
|
||||
|
||||
=item *
|
||||
|
||||
Archive and value change monitors are invoked if APST or MPST are Always or if
|
||||
the result of the hash calculation is different.
|
||||
|
||||
=item *
|
||||
|
||||
NSEV and NSTA are reset to 0.
|
||||
|
||||
=back
|
||||
|
||||
=item 5.
|
||||
|
||||
Scan forward link if necessary, set PACT FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
=begin html
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
=end html
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct aaoRecord;
|
||||
%typedef struct aaodset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*write_aao)(struct aaoRecord *prec); /*returns: (-1,0)=>(failure,success)*/
|
||||
%} aaodset;
|
||||
%#define HAS_aaodset
|
||||
%
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
pp(TRUE)
|
||||
extra("void * val")
|
||||
#=type DOUBLE[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(OUT,DBF_OUTLINK) {
|
||||
prompt("Output Specification")
|
||||
promptgroup("50 - Output")
|
||||
interest(1)
|
||||
}
|
||||
field(EGU,DBF_STRING) {
|
||||
prompt("Engineering Units")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
size(16)
|
||||
prop(YES)
|
||||
}
|
||||
field(HOPR,DBF_DOUBLE) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_DOUBLE) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(NELM,DBF_ULONG) {
|
||||
prompt("Number of Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(FTVL,DBF_MENU) {
|
||||
prompt("Field Type of Value")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
menu(menuFtype)
|
||||
}
|
||||
field(NORD,DBF_ULONG) {
|
||||
prompt("Number elements read")
|
||||
special(SPC_NOMOD)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * bptr")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Simulation Output Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(MPST,DBF_MENU) {
|
||||
prompt("Post Value Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaoPOST)
|
||||
}
|
||||
field(APST,DBF_MENU) {
|
||||
prompt("Post Archive Monitors")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
menu(aaoPOST)
|
||||
}
|
||||
field(HASH,DBF_ULONG) {
|
||||
prompt("Hash of OnChange data.")
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head2 Device Support
|
||||
|
||||
=head3 Fields Of Interest To Device Support
|
||||
|
||||
Each array analog output record record must have an associated set of device
|
||||
support routines. The primary responsibility of the device support routines is to
|
||||
write the array data value whenever C<write_aao()> is called. The device support
|
||||
routines are primarily interested in the following fields:
|
||||
|
||||
=fields PACT, DPVT, NSEV, NSTA, OUT, NELM, FTVL, BPTR, NORD
|
||||
|
||||
=head3 Device Support Routines
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=head4 report
|
||||
|
||||
long report(int level)
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=head4 init
|
||||
|
||||
long init(int after)
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=head4 init_record
|
||||
|
||||
long init_record(dbCommon *precord)
|
||||
|
||||
This routine is optional. If provided, it is called by the record support
|
||||
C<init_record()> routine.
|
||||
|
||||
=head4 get_ioint_info
|
||||
|
||||
long get_ioint_info(int cmd, dbCommon *precord, IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the
|
||||
record is being (added to, deleted from) an I/O event list. It must be
|
||||
provided for any device type that can use the ioEvent scanner.
|
||||
|
||||
=head4 write_aao
|
||||
|
||||
long write_aao(dbCommon *precord)
|
||||
|
||||
This routine must write the array data to output. It returns the following values:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
0: Success.
|
||||
|
||||
=item *
|
||||
|
||||
Other: Error.
|
||||
|
||||
=back
|
||||
|
||||
=head3 Device Support For Soft Records
|
||||
|
||||
The C<<< Soft Channel >>> device support module is provided to write values to
|
||||
other records and store them in arrays. If OUT is a constant link, then
|
||||
C<write_aao()> does nothing. In this case, the record can be used to hold arrays
|
||||
written via dbPuts. If OUT is a database or channel access link, the array value
|
||||
is written to the link. NORD is set to the number of items in the array.
|
||||
|
||||
|
||||
If the OUT link type is constant, then NORD is set to zero.
|
||||
|
||||
=cut
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* aiRecord.c - Record Support Routines for Analog Input records */
|
||||
@@ -63,40 +63,29 @@ static long get_precision(const DBADDR *, long *);
|
||||
static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
|
||||
static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
|
||||
rset aiRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,aiRSET);
|
||||
|
||||
typedef struct aidset { /* analog input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;/*(0,2)=> success and convert,don't convert)*/
|
||||
/* if convert then raw value stored in rval */
|
||||
DEVSUPFUN special_linconv;
|
||||
}aidset;
|
||||
|
||||
static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime);
|
||||
static void convert(aiRecord *prec);
|
||||
static void monitor(aiRecord *prec);
|
||||
@@ -105,8 +94,8 @@ static long readValue(aiRecord *prec);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)pcommon;
|
||||
aidset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
aidset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
|
||||
@@ -114,27 +103,27 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitConstantLink(&prec->siol, DBF_DOUBLE, &prec->sval);
|
||||
|
||||
if(!(pdset = (aidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ai: init_record");
|
||||
return(S_dev_noDSET);
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ai: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have read_ai function defined */
|
||||
if( (pdset->number < 6) || (pdset->read_ai == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"ai: init_record");
|
||||
return(S_dev_missingSup);
|
||||
if ((pdset->common.number < 6) || (pdset->read_ai == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"ai: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
prec->init = TRUE;
|
||||
/*The following is for old device support that doesnt know about eoff*/
|
||||
if ((prec->eslo==1.0) && (prec->eoff==0.0)) {
|
||||
prec->eoff = prec->egul;
|
||||
prec->eoff = prec->egul;
|
||||
}
|
||||
|
||||
if( pdset->init_record ) {
|
||||
long status=(*pdset->init_record)(prec);
|
||||
if (prec->linr == menuConvertSLOPE) {
|
||||
prec->eoff = eoff;
|
||||
prec->eslo = eslo;
|
||||
}
|
||||
return (status);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
if (prec->linr == menuConvertSLOPE) {
|
||||
prec->eoff = eoff;
|
||||
prec->eslo = eslo;
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
prec->alst = prec->val;
|
||||
@@ -146,51 +135,51 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)pcommon;
|
||||
aidset *pdset = (aidset *)(prec->dset);
|
||||
long status;
|
||||
aidset *pdset = (aidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
epicsTimeStamp timeLast;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_ai==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_ai");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
if( (pdset==NULL) || (pdset->read_ai==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_ai");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) convert(prec);
|
||||
else if (status==2) status=0;
|
||||
if (status==0) convert(prec);
|
||||
else if (status==2) status=0;
|
||||
|
||||
if (status == 0) prec->udf = isnan(prec->val);
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec,&timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
/* check for alarms */
|
||||
checkAlarms(prec,&timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->init=FALSE;
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->init=FALSE;
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr,int after)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)(paddr->precord);
|
||||
aidset *pdset = (aidset *) (prec->dset);
|
||||
aiRecord *prec = (aiRecord *)(paddr->precord);
|
||||
aidset *pdset = (aidset *) (prec->dset);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_LINCONV):
|
||||
if(pdset->number<6) {
|
||||
if (pdset->common.number < 6) {
|
||||
recGblDbaddrError(S_db_noMod,paddr,"ai: special");
|
||||
return(S_db_noMod);
|
||||
}
|
||||
@@ -226,7 +215,7 @@ static long special(DBADDR *paddr,int after)
|
||||
|
||||
static long get_units(DBADDR *paddr, char *units)
|
||||
{
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
|
||||
if(paddr->pfldDes->field_type == DBF_DOUBLE) {
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
@@ -243,7 +232,7 @@ static long get_units(DBADDR *paddr, char *units)
|
||||
|
||||
static long get_precision(const DBADDR *paddr, long *precision)
|
||||
{
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
|
||||
*precision = prec->prec;
|
||||
if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0);
|
||||
@@ -253,7 +242,7 @@ static long get_precision(const DBADDR *paddr, long *precision)
|
||||
|
||||
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
@@ -276,7 +265,7 @@ static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
|
||||
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
@@ -288,8 +277,8 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
case indexof(ALST):
|
||||
case indexof(MLST):
|
||||
case indexof(SVAL):
|
||||
pcd->upper_ctrl_limit = prec->hopr;
|
||||
pcd->lower_ctrl_limit = prec->lopr;
|
||||
pcd->upper_ctrl_limit = prec->hopr;
|
||||
pcd->lower_ctrl_limit = prec->lopr;
|
||||
break;
|
||||
default:
|
||||
recGblGetControlDouble(paddr,pcd);
|
||||
@@ -299,7 +288,7 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
|
||||
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
|
||||
{
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
aiRecord *prec=(aiRecord *)paddr->precord;
|
||||
|
||||
if (dbGetFieldIndex(paddr) == indexof(VAL)) {
|
||||
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
|
||||
@@ -380,7 +369,7 @@ static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime)
|
||||
* level, otherwise to a higher.
|
||||
*/
|
||||
afvl = alpha * afvl +
|
||||
((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
|
||||
((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
|
||||
if (afvl - floor(afvl) > THRESHOLD)
|
||||
afvl = -afvl; /* reverse rounding */
|
||||
|
||||
@@ -422,38 +411,38 @@ static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime)
|
||||
|
||||
static void convert(aiRecord *prec)
|
||||
{
|
||||
double val;
|
||||
double val;
|
||||
|
||||
|
||||
val = (double)prec->rval + (double)prec->roff;
|
||||
/* adjust slope and offset */
|
||||
if(prec->aslo!=0.0) val*=prec->aslo;
|
||||
val+=prec->aoff;
|
||||
val = (double)prec->rval + (double)prec->roff;
|
||||
/* adjust slope and offset */
|
||||
if(prec->aslo!=0.0) val*=prec->aslo;
|
||||
val+=prec->aoff;
|
||||
|
||||
/* convert raw to engineering units and signal units */
|
||||
switch (prec->linr) {
|
||||
case menuConvertNO_CONVERSION:
|
||||
break; /* do nothing*/
|
||||
|
||||
case menuConvertLINEAR:
|
||||
case menuConvertSLOPE:
|
||||
val = (val * prec->eslo) + prec->eoff;
|
||||
break;
|
||||
|
||||
default: /* must use breakpoint table */
|
||||
if (cvtRawToEngBpt(&val,prec->linr,prec->init,(void *)&prec->pbrk,&prec->lbrk)!=0) {
|
||||
recGblSetSevr(prec,SOFT_ALARM,MAJOR_ALARM);
|
||||
}
|
||||
}
|
||||
/* convert raw to engineering units and signal units */
|
||||
switch (prec->linr) {
|
||||
case menuConvertNO_CONVERSION:
|
||||
break; /* do nothing*/
|
||||
|
||||
/* apply smoothing algorithm */
|
||||
case menuConvertLINEAR:
|
||||
case menuConvertSLOPE:
|
||||
val = (val * prec->eslo) + prec->eoff;
|
||||
break;
|
||||
|
||||
default: /* must use breakpoint table */
|
||||
if (cvtRawToEngBpt(&val,prec->linr,prec->init,(void *)&prec->pbrk,&prec->lbrk)!=0) {
|
||||
recGblSetSevr(prec,SOFT_ALARM,MAJOR_ALARM);
|
||||
}
|
||||
}
|
||||
|
||||
/* apply smoothing algorithm */
|
||||
if (prec->smoo != 0.0 && finite(prec->val)){
|
||||
if (prec->init) prec->val = val; /* initial condition */
|
||||
prec->val = val * (1.00 - prec->smoo) + (prec->val * prec->smoo);
|
||||
}else{
|
||||
prec->val = val;
|
||||
}
|
||||
return;
|
||||
if (prec->init) prec->val = val; /* initial condition */
|
||||
prec->val = val * (1.00 - prec->smoo) + (prec->val * prec->smoo);
|
||||
}else{
|
||||
prec->val = val;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void monitor(aiRecord *prec)
|
||||
@@ -466,15 +455,15 @@ static void monitor(aiRecord *prec)
|
||||
/* check for archive change */
|
||||
recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE);
|
||||
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
if(prec->oraw != prec->rval) {
|
||||
db_post_events(prec,&prec->rval,monitor_mask);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
}
|
||||
return;
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
if(prec->oraw != prec->rval) {
|
||||
db_post_events(prec,&prec->rval,monitor_mask);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static long readValue(aiRecord *prec)
|
||||
@@ -488,40 +477,40 @@ static long readValue(aiRecord *prec)
|
||||
}
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
status = pdset->read_ai(prec);
|
||||
break;
|
||||
case menuSimmNO:
|
||||
status = pdset->read_ai(prec);
|
||||
break;
|
||||
|
||||
case menuSimmYES:
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_DOUBLE, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* don't convert */
|
||||
} else {
|
||||
prec->rval = (long)floor(prec->sval);
|
||||
status = 0; /* convert RVAL */
|
||||
case menuSimmYES:
|
||||
case menuSimmRAW: {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, DBR_DOUBLE, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
if (prec->simm == menuSimmYES) {
|
||||
prec->val = prec->sval;
|
||||
status = 2; /* don't convert */
|
||||
} else {
|
||||
prec->rval = (long)floor(prec->sval);
|
||||
status = 0; /* convert RVAL */
|
||||
}
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
epicsCallback *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(epicsCallback)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
epicsCallback *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(epicsCallback)); /* very lazy allocation of callback structure */
|
||||
prec->simpvt = pvt;
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -190,7 +190,13 @@ noise.
|
||||
The AFTC field sets the time constant on a low-pass filter that delays the
|
||||
reporting of limit alarms until the signal has been within the alarm range for
|
||||
that number of seconds (the default AFTC value of zero retains the previous
|
||||
behavior).
|
||||
behavior). The record must be scanned often enough for the filtering action to
|
||||
work effectively and the alarm severity can only change when the record is
|
||||
processed, but that processing does not have to be regular; the filter uses the
|
||||
time since the record last processed in its calculation. Setting AFTC to a
|
||||
positive number of seconds will delay the record going into or out of a minor
|
||||
alarm severity or from minor to major severity until the input signal has been
|
||||
in the alarm range for that number of seconds.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, AFTC, LALM
|
||||
|
||||
@@ -215,6 +221,16 @@ monitoring functionality.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct aiRecord;
|
||||
%typedef struct aidset {
|
||||
% dset common;
|
||||
% long (*read_ai)(struct aiRecord *prec);
|
||||
% long (*special_linconv)(struct aiRecord *prec, int after);
|
||||
%} aidset;
|
||||
%#define HAS_aidset
|
||||
%
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Current EGU Value")
|
||||
promptgroup("40 - Input")
|
||||
@@ -435,35 +451,22 @@ monitoring functionality.
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The record provides several fields to support simulation of absent hardware.
|
||||
If the SIML field is set it is used to read a value into the SIMM field, which
|
||||
controls whether simulation is used or not:
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
=over
|
||||
If SIMM (fetched through SIML) is YES or RAW, the record is put in SIMS
|
||||
severity and the value is fetched through SIOL (buffered in SVAL).
|
||||
If SIMM is YES, SVAL is written to VAL without conversion,
|
||||
if SIMM is RAW, SVAL is trancated to RVAL and converted.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
=item *
|
||||
SIMM must be zero (C<NO>) for the record to request a value from the device
|
||||
support.
|
||||
See L<Input Simulation Fields|dbCommonInput/Input Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=item *
|
||||
If SIMM is C<YES> and the SIOL link field is set, a simlated value in
|
||||
engineering units is read using the link into the SVAL field, from where it will
|
||||
subsequently be copied into the VAL field.
|
||||
|
||||
=item *
|
||||
If SIMM is C<RAW> the SIOL link is still read into SVAL, but is then truncated
|
||||
and copied into the RVAL field.
|
||||
The L</Units Conversion> process described above is then followed to transform
|
||||
the simulated raw value into engineering units.
|
||||
|
||||
=back
|
||||
|
||||
The SIMS field can be set to give the record an alarm severity while it is in
|
||||
simulation mode.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* aoRecord.c - Record Support Routines for Analog Output records */
|
||||
@@ -64,37 +64,27 @@ static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
rset aoRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double };
|
||||
|
||||
struct aodset { /* analog input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (0,2)=>(success,success no convert)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_ao;/*(0)=>(success ) */
|
||||
DEVSUPFUN special_linconv;
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,aoRSET);
|
||||
|
||||
|
||||
static void checkAlarms(aoRecord *);
|
||||
static long fetch_value(aoRecord *, double *);
|
||||
static void convert(aoRecord *, double);
|
||||
@@ -104,62 +94,62 @@ static long writeValue(aoRecord *);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct aoRecord *prec = (struct aoRecord *)pcommon;
|
||||
struct aodset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
double value;
|
||||
long status = 0;
|
||||
aodset *pdset;
|
||||
double eoff = prec->eoff, eslo = prec->eslo;
|
||||
double value;
|
||||
long status = 0;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if(!(pdset = (struct aodset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ao: init_record");
|
||||
return(S_dev_noDSET);
|
||||
if(!(pdset = (aodset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"ao: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* get the initial value if dol is a constant*/
|
||||
if (recGblInitConstantLink(&prec->dol,DBF_DOUBLE,&prec->val))
|
||||
prec->udf = isnan(prec->val);
|
||||
|
||||
/* must have write_ao function defined */
|
||||
if ((pdset->number < 6) || (pdset->write_ao ==NULL)) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"ao: init_record");
|
||||
return(S_dev_missingSup);
|
||||
if ((pdset->common.number < 6) || (pdset->write_ao ==NULL)) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"ao: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
prec->init = TRUE;
|
||||
/*The following is for old device support that doesnt know about eoff*/
|
||||
if ((prec->eslo==1.0) && (prec->eoff==0.0)) {
|
||||
prec->eoff = prec->egul;
|
||||
prec->eoff = prec->egul;
|
||||
}
|
||||
|
||||
if (pdset->init_record) {
|
||||
status = (*pdset->init_record)(prec);
|
||||
if (prec->linr == menuConvertSLOPE) {
|
||||
prec->eoff = eoff;
|
||||
prec->eslo = eslo;
|
||||
}
|
||||
if (pdset->common.init_record) {
|
||||
status = pdset->common.init_record(pcommon);
|
||||
if (prec->linr == menuConvertSLOPE) {
|
||||
prec->eoff = eoff;
|
||||
prec->eslo = eslo;
|
||||
}
|
||||
switch(status){
|
||||
case(0): /* convert */
|
||||
value = (double)prec->rval + (double)prec->roff;
|
||||
if(prec->aslo!=0.0) value *= prec->aslo;
|
||||
value += prec->aoff;
|
||||
value = (double)prec->rval + (double)prec->roff;
|
||||
if(prec->aslo!=0.0) value *= prec->aslo;
|
||||
value += prec->aoff;
|
||||
if (prec->linr == menuConvertNO_CONVERSION){
|
||||
; /*do nothing*/
|
||||
; /*do nothing*/
|
||||
} else if ((prec->linr == menuConvertLINEAR) ||
|
||||
(prec->linr == menuConvertSLOPE)) {
|
||||
(prec->linr == menuConvertSLOPE)) {
|
||||
value = value*prec->eslo + prec->eoff;
|
||||
}else{
|
||||
if(cvtRawToEngBpt(&value,prec->linr,prec->init,
|
||||
(void *)&prec->pbrk,&prec->lbrk)!=0) break;
|
||||
(void *)&prec->pbrk,&prec->lbrk)!=0) break;
|
||||
}
|
||||
prec->val = value;
|
||||
prec->udf = isnan(value);
|
||||
prec->val = value;
|
||||
prec->udf = isnan(value);
|
||||
break;
|
||||
case(2): /* no convert */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_dev_badInitRet,(void *)prec,"ao: init_record");
|
||||
return(S_dev_badInitRet);
|
||||
recGblRecordError(S_dev_badInitRet,(void *)prec,"ao: init_record");
|
||||
return(S_dev_badInitRet);
|
||||
}
|
||||
}
|
||||
prec->oval = prec->pval = prec->val;
|
||||
@@ -174,19 +164,19 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct aoRecord *prec = (struct aoRecord *)pcommon;
|
||||
struct aodset *pdset = (struct aodset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
double value;
|
||||
aodset *pdset = (aodset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
double value;
|
||||
|
||||
if ((pdset==NULL) || (pdset->write_ao==NULL)) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_ao");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if ((pdset==NULL) || (pdset->write_ao==NULL)) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_ao");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
|
||||
/* fetch value and convert*/
|
||||
if (prec->pact == FALSE) {
|
||||
/* fetch value and convert*/
|
||||
if (prec->pact == FALSE) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
status = fetch_value(prec, &value);
|
||||
@@ -194,80 +184,80 @@ static long process(struct dbCommon *pcommon)
|
||||
else {
|
||||
value = prec->val;
|
||||
}
|
||||
if(!status) convert(prec, value);
|
||||
prec->udf = isnan(prec->val);
|
||||
}
|
||||
if(!status) convert(prec, value);
|
||||
prec->udf = isnan(prec->val);
|
||||
}
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
value=prec->ivov;
|
||||
convert(prec,value);
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"ao:process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
value=prec->ivov;
|
||||
convert(prec,value);
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"ao:process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
|
||||
/* process the forward scan link record */
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->init=FALSE;
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->init=FALSE;
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
aoRecord *prec = (aoRecord *)(paddr->precord);
|
||||
struct aodset *pdset = (struct aodset *) (prec->dset);
|
||||
aodset *pdset = (aodset *) (prec->dset);
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_LINCONV):
|
||||
if(pdset->number<6 ) {
|
||||
if(pdset->common.number<6 ) {
|
||||
recGblDbaddrError(S_db_noMod,paddr,"ao: special");
|
||||
return(S_db_noMod);
|
||||
}
|
||||
prec->init=TRUE;
|
||||
prec->init=TRUE;
|
||||
if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) {
|
||||
double eoff = prec->eoff;
|
||||
double eslo = prec->eslo;
|
||||
long status;
|
||||
prec->eoff = prec->egul;
|
||||
status = (*pdset->special_linconv)(prec,after);
|
||||
if (eoff != prec->eoff)
|
||||
db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG);
|
||||
double eoff = prec->eoff;
|
||||
double eslo = prec->eslo;
|
||||
long status;
|
||||
prec->eoff = prec->egul;
|
||||
status = (*pdset->special_linconv)(prec,after);
|
||||
if (eoff != prec->eoff)
|
||||
db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG);
|
||||
if (eslo != prec->eslo)
|
||||
db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG);
|
||||
return (status);
|
||||
}
|
||||
return (0);
|
||||
db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG);
|
||||
return (status);
|
||||
}
|
||||
return (0);
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == aoRecordSIMM) {
|
||||
if (!after)
|
||||
@@ -286,7 +276,7 @@ static long special(DBADDR *paddr, int after)
|
||||
|
||||
static long get_units(DBADDR * paddr,char *units)
|
||||
{
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
|
||||
if(paddr->pfldDes->field_type == DBF_DOUBLE) {
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
@@ -302,7 +292,7 @@ static long get_units(DBADDR * paddr,char *units)
|
||||
|
||||
static long get_precision(const DBADDR *paddr,long *precision)
|
||||
{
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
|
||||
*precision = prec->prec;
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
@@ -318,7 +308,7 @@ static long get_precision(const DBADDR *paddr,long *precision)
|
||||
|
||||
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
@@ -343,7 +333,7 @@ static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
|
||||
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
@@ -366,7 +356,7 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
}
|
||||
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
{
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
aoRecord *prec=(aoRecord *)paddr->precord;
|
||||
|
||||
if(dbGetFieldIndex(paddr) == indexof(VAL)){
|
||||
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
|
||||
@@ -435,27 +425,27 @@ static void checkAlarms(aoRecord *prec)
|
||||
|
||||
static long fetch_value(aoRecord *prec,double *pvalue)
|
||||
{
|
||||
short save_pact;
|
||||
long status;
|
||||
short save_pact;
|
||||
long status;
|
||||
|
||||
save_pact = prec->pact;
|
||||
prec->pact = TRUE;
|
||||
save_pact = prec->pact;
|
||||
prec->pact = TRUE;
|
||||
|
||||
/* don't allow dbputs to val field */
|
||||
prec->val=prec->pval;
|
||||
/* don't allow dbputs to val field */
|
||||
prec->val=prec->pval;
|
||||
|
||||
status = dbGetLink(&prec->dol,DBR_DOUBLE,pvalue,0,0);
|
||||
prec->pact = save_pact;
|
||||
status = dbGetLink(&prec->dol,DBR_DOUBLE,pvalue,0,0);
|
||||
prec->pact = save_pact;
|
||||
|
||||
if (status) {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
if (status) {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
|
||||
if (prec->oif == aoOIF_Incremental)
|
||||
*pvalue += prec->val;
|
||||
if (prec->oif == aoOIF_Incremental)
|
||||
*pvalue += prec->val;
|
||||
|
||||
return(0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void convert(aoRecord *prec, double value)
|
||||
@@ -487,19 +477,19 @@ static void convert(aoRecord *prec, double value)
|
||||
|
||||
/* convert */
|
||||
switch (prec->linr) {
|
||||
case menuConvertNO_CONVERSION:
|
||||
break; /* do nothing*/
|
||||
case menuConvertLINEAR:
|
||||
case menuConvertSLOPE:
|
||||
if (prec->eslo == 0.0) value = 0;
|
||||
else value = (value - prec->eoff) / prec->eslo;
|
||||
break;
|
||||
default:
|
||||
if (cvtEngToRawBpt(&value, prec->linr, prec->init,
|
||||
(void *)&prec->pbrk, &prec->lbrk) != 0) {
|
||||
recGblSetSevr(prec, SOFT_ALARM, MAJOR_ALARM);
|
||||
return;
|
||||
}
|
||||
case menuConvertNO_CONVERSION:
|
||||
break; /* do nothing*/
|
||||
case menuConvertLINEAR:
|
||||
case menuConvertSLOPE:
|
||||
if (prec->eslo == 0.0) value = 0;
|
||||
else value = (value - prec->eoff) / prec->eslo;
|
||||
break;
|
||||
default:
|
||||
if (cvtEngToRawBpt(&value, prec->linr, prec->init,
|
||||
(void *)&prec->pbrk, &prec->lbrk) != 0) {
|
||||
recGblSetSevr(prec, SOFT_ALARM, MAJOR_ALARM);
|
||||
return;
|
||||
}
|
||||
}
|
||||
value -= prec->aoff;
|
||||
if (prec->aslo != 0) value /= prec->aslo;
|
||||
@@ -535,27 +525,27 @@ static void monitor(aoRecord *prec)
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
}
|
||||
|
||||
if(prec->omod) monitor_mask |= (DBE_VALUE|DBE_LOG);
|
||||
if(monitor_mask) {
|
||||
prec->omod = FALSE;
|
||||
db_post_events(prec,&prec->oval,monitor_mask);
|
||||
if(prec->oraw != prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
if(prec->orbv != prec->rbv) {
|
||||
db_post_events(prec,&prec->rbv,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->orbv = prec->rbv;
|
||||
}
|
||||
}
|
||||
return;
|
||||
if(prec->omod) monitor_mask |= (DBE_VALUE|DBE_LOG);
|
||||
if(monitor_mask) {
|
||||
prec->omod = FALSE;
|
||||
db_post_events(prec,&prec->oval,monitor_mask);
|
||||
if(prec->oraw != prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
if(prec->orbv != prec->rbv) {
|
||||
db_post_events(prec,&prec->rbv,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->orbv = prec->rbv;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static long writeValue(aoRecord *prec)
|
||||
{
|
||||
struct aodset *pdset = (struct aodset *) prec->dset;
|
||||
aodset *pdset = (aodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Analog Output Record (ao)
|
||||
@@ -104,33 +104,32 @@ The LINR field can specify C<LINEAR> or C<SLOPE> for linear conversions,
|
||||
C<NO CONVERSION> for no conversions at all, or the name of a breakpoint table
|
||||
such as C<typeKdegC> for breakpoint conversions.
|
||||
|
||||
Note that the ESLO, EOFF, EGUF, and EGUL fields are only used for linear
|
||||
conversions.
|
||||
Also note that none of these fields have any significance for records that use
|
||||
the Soft Channel device support module.
|
||||
The EGUF and EGUL fields should be set for C<LINEAR> conversions, and the ESLO
|
||||
and EOFF fields for C<SLOPE> conversion. Note that none of these fields have any
|
||||
significance for records that use the Soft Channel device support module.
|
||||
|
||||
=over
|
||||
|
||||
=item EGUF, EGUF
|
||||
|
||||
The user must calculate these fields when configuring the database for records
|
||||
The user must set these fields when configuring the database for records
|
||||
that use C<LINEAR> conversions.
|
||||
They are used to calculate the values for ESLO and EOFF.
|
||||
See Conversion Specification for more information on how to calculate these
|
||||
fields.
|
||||
|
||||
=item ESLO, EOFF
|
||||
|
||||
Computed by device support from EGUF and EGUL when LINR specifies C<LINEAR>.
|
||||
These values must be supplied by the user when LINR specifies C<SLOPE>.
|
||||
Used only when LINR is C<LINEAR> or C<SLOPE>.
|
||||
|
||||
=item AOFF, ASLO
|
||||
|
||||
These fields are adjustment parameters for the raw output values.
|
||||
They are applied to the raw output value after conversion from engineering
|
||||
units.
|
||||
|
||||
=item ESLO, EOFF
|
||||
|
||||
Computed by device support using EGUF and EGUL when LINR specifies C<LINEAR>.
|
||||
These values must be supplied by the user when LINR specifies C<SLOPE>.
|
||||
Used only when LINR is C<LINEAR> or C<SLOPE>.
|
||||
|
||||
=item ROFF
|
||||
|
||||
This field can be used to offset the raw value generated by the conversion
|
||||
@@ -168,8 +167,7 @@ addresses.
|
||||
|
||||
For soft records the output link can be a database link, a channel
|
||||
access link, or a constant value. If the link is a constant, no output
|
||||
is sent. See Address Specification for information on the format of
|
||||
database and channel access addresses.
|
||||
is sent.
|
||||
|
||||
=fields DTYP, OUT
|
||||
|
||||
@@ -193,8 +191,8 @@ The PREC field determines the floating point precision with which to
|
||||
display VAL, OVAL and PVAL. It is used whenever the get_precision
|
||||
record support routine is called.
|
||||
|
||||
See Fields Common to All Record Types for more on the record name
|
||||
(NAME) and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, HOPR, LOPR, PREC, NAME, DESC
|
||||
|
||||
@@ -209,9 +207,10 @@ and LOW fields, which must be floating-point values. For each of these
|
||||
fields, there is a corresponding severity field which can be either
|
||||
NO_ALARM, MINOR, or MAJOR.
|
||||
|
||||
See Alarm Specification for a complete explanation of alarms and these
|
||||
fields. See Invalid Alarm Output Action for more information on the
|
||||
IVOA and IVOV fields. Alarm Fields lists other fields related to a
|
||||
See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for more information on the IVOA and IVOV fields.
|
||||
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related to a
|
||||
alarms that are common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, IVOA, IVOV
|
||||
@@ -229,7 +228,7 @@ a complete explanation of monitors.
|
||||
|
||||
=fields ADEL, MDEL
|
||||
|
||||
=head3 Run-time and Simulation Mode Parameters
|
||||
=head3 Run-time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the
|
||||
analog output. They are not configurable. They represent the current
|
||||
@@ -260,15 +259,34 @@ processing.
|
||||
|
||||
=fields ORAW, RBV, ORBV, LALM, ALST, MLST, INIT, PBRK, LBRK, PVAL, OMOD
|
||||
|
||||
The following fields are used to operate the analog output in the
|
||||
simulation mode. See Fields Common to Many Record Types for more
|
||||
information on these fields.
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
=fields SIOL, SIML, SIMM, SIMS
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is written through SIOL, without conversion.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Output Simulation Fields|dbCommonOutput/Output Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct aoRecord;
|
||||
%typedef struct aodset {
|
||||
% dset common; /*init_record returns: (0,2)=>(success,success no convert)*/
|
||||
% long (*write_ao)(struct aoRecord *prec); /*(0)=>(success ) */
|
||||
% long (*special_linconv)(struct aoRecord *prec, int after);
|
||||
%} aodset;
|
||||
%#define HAS_aodset
|
||||
%
|
||||
field(VAL,DBF_DOUBLE) {
|
||||
prompt("Desired Output")
|
||||
promptgroup("50 - Output")
|
||||
@@ -602,6 +620,8 @@ get_precision, get_graphic_double, and get_control_double routines.
|
||||
|
||||
=item init_record
|
||||
|
||||
C<long init_record(aoRecord *prec, int pass);>
|
||||
|
||||
This routine initializes SIMM if SIML is a constant or creates a
|
||||
channel access link if SIML is PV_LINK. If SIOL is PV_LINK a channel
|
||||
access link is created.
|
||||
@@ -633,10 +653,14 @@ then set to FALSE. PVAL is set to VAL.
|
||||
|
||||
=item process
|
||||
|
||||
C<long process(aoRecord *prec);>
|
||||
|
||||
See next section.
|
||||
|
||||
=item special
|
||||
|
||||
C<long special(DBADDR *paddr, int after);>
|
||||
|
||||
The only special processing for analog output records is SPC_LINCONV
|
||||
which is invoked whenever either of the fields LINR, EGUF, EGUL or ROFF
|
||||
is changed If the device support routine special_linconv exists it is
|
||||
@@ -647,6 +671,8 @@ re-initialized.
|
||||
|
||||
=item get_alarm_double
|
||||
|
||||
C<long get_alarm_double(DBADDR *, struct dbr_alDouble *);>
|
||||
|
||||
Sets the following values:
|
||||
|
||||
upper_alarm_limit = HIHI
|
||||
@@ -796,7 +822,9 @@ Device support consists of the following routines:
|
||||
|
||||
=over
|
||||
|
||||
=item C<long report(int level)>
|
||||
=item report
|
||||
|
||||
C<long report(int level);>
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
@@ -806,7 +834,9 @@ information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=item C<long init(int after)>
|
||||
=item init
|
||||
|
||||
C<long init(int after);>
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
@@ -814,7 +844,9 @@ the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=item C<long init_record(aoRecord *prec)>
|
||||
=item init_record
|
||||
|
||||
C<long init_record(aoRecord *prec);>
|
||||
|
||||
This optional routine is called by the record initialization code for each ao
|
||||
record instance that has its DTYP field set to use this device support.
|
||||
@@ -836,7 +868,9 @@ should also fetch that value and put it into the record's RVAL or VAL field. The
|
||||
return value should be zero if the RVAL field has been set, or 2 if either the
|
||||
VAL field has been set or if the last output value cannot be retrieved.
|
||||
|
||||
=item C<long get_ioint_info(int cmd, aoRecord *prec, IOSCANPVT *piosl)>
|
||||
=item get_ioint_info
|
||||
|
||||
C<long get_ioint_info(int cmd, aoRecord *prec, IOSCANPVT *piosl);>
|
||||
|
||||
This optional routine is called whenever the record's SCAN field is being
|
||||
changed to or from the value C<I/O Intr> to find out which I/O Interrupt Scan
|
||||
@@ -864,7 +898,9 @@ thread.
|
||||
The C<scanIoRequest()> routine is safe to call from an interrupt service routine
|
||||
on embedded architectures (vxWorks and RTEMS).
|
||||
|
||||
=item C<long write_ao(aoRecord *prec)>
|
||||
=item write_ao
|
||||
|
||||
C<long write_ao(aoRecord *prec);>
|
||||
|
||||
This essential routine is called whenever the record has a new output value to
|
||||
send to the device. It is responsible for performing the write operation, using
|
||||
@@ -883,7 +919,9 @@ that happens the C<write_ao()> routine will be called again with PACT still set
|
||||
to TRUE; it should then set it to FALSE to indicate the write has completed, and
|
||||
return.
|
||||
|
||||
=item C<long special_linconv(aoRecord *prec, int after)>
|
||||
=item special_linconv
|
||||
|
||||
C<long special_linconv(aoRecord *prec, int after);>
|
||||
|
||||
This optional routine should be provided if the record type's unit conversion
|
||||
features are used by the device support's C<write_ao()> routine utilizing the
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recBi.c - Record Support Routines for Binary Input records */
|
||||
@@ -58,34 +58,27 @@ static long put_enum_str(const DBADDR *, const char *);
|
||||
#define get_control_double NULL
|
||||
#define get_alarm_double NULL
|
||||
rset biRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double };
|
||||
struct bidset { /* binary input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;/*(0,2)=> success and convert, don't convert)*/
|
||||
/* if convert then raw value stored in rval */
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,biRSET);
|
||||
|
||||
static void checkAlarms(biRecord *);
|
||||
static void monitor(biRecord *);
|
||||
static long readValue(biRecord *);
|
||||
@@ -93,7 +86,7 @@ static long readValue(biRecord *);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct biRecord *prec = (struct biRecord *)pcommon;
|
||||
struct bidset *pdset;
|
||||
bidset *pdset;
|
||||
long status;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
@@ -101,17 +94,17 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
|
||||
if(!(pdset = (struct bidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"bi: init_record");
|
||||
return(S_dev_noDSET);
|
||||
if(!(pdset = (bidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"bi: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have read_bi function defined */
|
||||
if( (pdset->number < 5) || (pdset->read_bi == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"bi: init_record");
|
||||
return(S_dev_missingSup);
|
||||
if( (pdset->common.number < 5) || (pdset->read_bi == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"bi: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if( pdset->init_record ) {
|
||||
if((status=(*pdset->init_record)(prec))) return(status);
|
||||
if( pdset->common.init_record ) {
|
||||
if((status=(*pdset->common.init_record)(pcommon))) return(status);
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
prec->lalm = prec->val;
|
||||
@@ -122,38 +115,38 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct biRecord *prec = (struct biRecord *)pcommon;
|
||||
struct bidset *pdset = (struct bidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
bidset *pdset = (bidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_bi==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_bi");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if( (pdset==NULL) || (pdset->read_bi==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_bi");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if(status==0) { /* convert rval to val */
|
||||
if(prec->rval==0) prec->val =0;
|
||||
else prec->val = 1;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
else if(status==2) status=0;
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
if(prec->rval==0) prec->val =0;
|
||||
else prec->val = 1;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
else if(status==2) status=0;
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -178,29 +171,29 @@ static long special(DBADDR *paddr, int after)
|
||||
|
||||
static long get_enum_str(const DBADDR *paddr, char *pstring)
|
||||
{
|
||||
biRecord *prec=(biRecord *)paddr->precord;
|
||||
int index;
|
||||
unsigned short *pfield = (unsigned short *)paddr->pfield;
|
||||
biRecord *prec=(biRecord *)paddr->precord;
|
||||
int index;
|
||||
unsigned short *pfield = (unsigned short *)paddr->pfield;
|
||||
|
||||
|
||||
index = dbGetFieldIndex(paddr);
|
||||
if(index!=biRecordVAL) {
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
} else if(*pfield==0) {
|
||||
strncpy(pstring,prec->znam,sizeof(prec->znam));
|
||||
pstring[sizeof(prec->znam)] = 0;
|
||||
strncpy(pstring,prec->znam,sizeof(prec->znam));
|
||||
pstring[sizeof(prec->znam)] = 0;
|
||||
} else if(*pfield==1) {
|
||||
strncpy(pstring,prec->onam,sizeof(prec->onam));
|
||||
pstring[sizeof(prec->onam)] = 0;
|
||||
strncpy(pstring,prec->onam,sizeof(prec->onam));
|
||||
pstring[sizeof(prec->onam)] = 0;
|
||||
} else {
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long get_enum_strs(const DBADDR *paddr,struct dbr_enumStrs *pes)
|
||||
{
|
||||
biRecord *prec=(biRecord *)paddr->precord;
|
||||
biRecord *prec=(biRecord *)paddr->precord;
|
||||
|
||||
pes->no_str = 2;
|
||||
memset(pes->strs,'\0',sizeof(pes->strs));
|
||||
@@ -225,57 +218,57 @@ static long put_enum_str(const DBADDR *paddr, const char *pstring)
|
||||
|
||||
static void checkAlarms(biRecord *prec)
|
||||
{
|
||||
unsigned short val = prec->val;
|
||||
unsigned short val = prec->val;
|
||||
|
||||
|
||||
if(prec->udf == TRUE){
|
||||
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
|
||||
return;
|
||||
}
|
||||
if(prec->udf == TRUE){
|
||||
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
|
||||
return;
|
||||
}
|
||||
|
||||
if(val>1)return;
|
||||
/* check for state alarm */
|
||||
if (val == 0){
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->zsv);
|
||||
}else{
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->osv);
|
||||
}
|
||||
if(val>1)return;
|
||||
/* check for state alarm */
|
||||
if (val == 0){
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->zsv);
|
||||
}else{
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->osv);
|
||||
}
|
||||
|
||||
/* check for cos alarm */
|
||||
if(val == prec->lalm) return;
|
||||
if(val == prec->lalm) return;
|
||||
recGblSetSevr(prec,COS_ALARM,prec->cosv);
|
||||
prec->lalm = val;
|
||||
return;
|
||||
prec->lalm = val;
|
||||
return;
|
||||
}
|
||||
|
||||
static void monitor(biRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask;
|
||||
unsigned short monitor_mask;
|
||||
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
/* check for value change */
|
||||
if (prec->mlst != prec->val){
|
||||
/* post events for value change and archive change */
|
||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||
/* update last value monitored */
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
/* check for value change */
|
||||
if (prec->mlst != prec->val){
|
||||
/* post events for value change and archive change */
|
||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||
/* update last value monitored */
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
}
|
||||
if(prec->oraw!=prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
return;
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
}
|
||||
if(prec->oraw!=prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static long readValue(biRecord *prec)
|
||||
{
|
||||
struct bidset *pdset = (struct bidset *)prec->dset;
|
||||
bidset *pdset = (bidset *)prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -23,26 +23,7 @@ value into RVAL just like normal hardware modules.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The binary input's fields fall into the following categories:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
scan Parameters
|
||||
|
||||
=item *
|
||||
read and convert parameters
|
||||
|
||||
=item *
|
||||
operator display parameters
|
||||
|
||||
=item *
|
||||
alarm parameters
|
||||
|
||||
=item *
|
||||
run-time parameters
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype bi
|
||||
|
||||
@@ -53,12 +34,8 @@ recordtype(bi) {
|
||||
=head3 Scan Parameters
|
||||
|
||||
The binary input record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. These fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
fields are used. Note that I/O event scanning is only supported for those
|
||||
card types that interrupt.
|
||||
|
||||
=fields SCAN
|
||||
circumstances the record will be processed.
|
||||
These fields are described in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read and Convert Parameters
|
||||
|
||||
@@ -106,8 +83,8 @@ corresponding to the VAL's state. If the value is 1, C<get_enum_str()> will
|
||||
return the string in the ONAM field; and if 0, C<get_enum_str()> will return
|
||||
the ZNAM string.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME)
|
||||
and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields ZNAM, ONAM, NAME, DESC
|
||||
|
||||
@@ -126,12 +103,12 @@ the one state. COSV causes an alarm whenever the state changes between
|
||||
0 and 1 and the severity is configured as MINOR or MAJOR.
|
||||
|
||||
See L<Alarm Specification> for a complete explanation of the discrete alarm
|
||||
states. L<Alarm Fields> lists other fields related to alarms that are
|
||||
states. L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related to alarms that are
|
||||
common to all record types.
|
||||
|
||||
=fields ZSV, OSV, COSV
|
||||
|
||||
=head3 Run-time Parameters and Simulation Mode Parameters
|
||||
=head3 Run-time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the binary
|
||||
input. They are not configured using a database configuration tool.
|
||||
@@ -153,16 +130,18 @@ is not equal to VAL.
|
||||
|
||||
=fields ORAW, MASK, LALM, MLST
|
||||
|
||||
The following fields are used to operate the binary input in simulation
|
||||
mode. See L<Fields Common to Many Record Types> for more information on
|
||||
these fields.
|
||||
|
||||
=fields SIOL, SVAL, SIML, SIMM, SIMS
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct biRecord;
|
||||
%typedef struct bidset {
|
||||
% dset common;
|
||||
% long (*read_bi)(struct biRecord *prec);
|
||||
%} bidset;
|
||||
%#define HAS_bidset
|
||||
%
|
||||
field(INP,DBF_INLINK) {
|
||||
prompt("Input Specification")
|
||||
promptgroup("40 - Input")
|
||||
@@ -235,6 +214,26 @@ these fields.
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES or RAW, the record is put in SIMS
|
||||
severity and the value is fetched through SIOL (buffered in SVAL).
|
||||
If SIMM is YES, SVAL is written to VAL without conversion,
|
||||
if SIMM is RAW, SVAL is trancated to RVAL and converted.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Input Simulation Fields|dbCommonInput/Input Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
@@ -305,7 +304,7 @@ If device support includes C<init_record()>, it is called.
|
||||
|
||||
long process(struct dbCommon *precord);
|
||||
|
||||
See L<Record Processing> below.
|
||||
See L</Record Processing> below.
|
||||
|
||||
long get_enum_str(const struct dbAddr *paddr, char *pbuffer);
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recBo.c - Record Support Routines for Binary Output records */
|
||||
@@ -60,24 +60,24 @@ static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
#define get_alarm_double NULL
|
||||
|
||||
rset boRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,boRSET);
|
||||
|
||||
@@ -86,16 +86,6 @@ epicsExportAddress(int, boHIGHprecision);
|
||||
double boHIGHlimit = 100000;
|
||||
epicsExportAddress(double, boHIGHlimit);
|
||||
|
||||
struct bodset { /* binary output dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns:(0,2)=>(success,success no convert*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_bo;/*returns: (-1,0)=>(failure,success)*/
|
||||
};
|
||||
|
||||
|
||||
/* control block for callback*/
|
||||
typedef struct myCallback {
|
||||
epicsCallback callback;
|
||||
@@ -115,15 +105,15 @@ static void myCallbackFunc(epicsCallback *arg)
|
||||
prec=(boRecord *)pcallback->precord;
|
||||
dbScanLock((struct dbCommon *)prec);
|
||||
if(prec->pact) {
|
||||
if((prec->val==1) && (prec->high>0)){
|
||||
myCallback *pcallback;
|
||||
pcallback = (myCallback *)(prec->rpvt);
|
||||
if((prec->val==1) && (prec->high>0)){
|
||||
myCallback *pcallback;
|
||||
pcallback = (myCallback *)(prec->rpvt);
|
||||
callbackSetPriority(prec->prio, &pcallback->callback);
|
||||
callbackRequestDelayed(&pcallback->callback,(double)prec->high);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
prec->val = 0;
|
||||
dbProcess((struct dbCommon *)prec);
|
||||
prec->val = 0;
|
||||
dbProcess((struct dbCommon *)prec);
|
||||
}
|
||||
dbScanUnlock((struct dbCommon *)prec);
|
||||
}
|
||||
@@ -131,7 +121,7 @@ static void myCallbackFunc(epicsCallback *arg)
|
||||
static long init_record(struct dbCommon *pcommon,int pass)
|
||||
{
|
||||
struct boRecord *prec = (struct boRecord *)pcommon;
|
||||
struct bodset *pdset = (struct bodset *) prec->dset;
|
||||
bodset *pdset = (bodset *) prec->dset;
|
||||
unsigned short ival = 0;
|
||||
long status = 0;
|
||||
myCallback *pcallback;
|
||||
@@ -146,7 +136,7 @@ static long init_record(struct dbCommon *pcommon,int pass)
|
||||
}
|
||||
|
||||
/* must have write_bo functions defined */
|
||||
if ((pdset->number < 5) || (pdset->write_bo == NULL)) {
|
||||
if ((pdset->common.number < 5) || (pdset->write_bo == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "bo: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
@@ -163,19 +153,19 @@ static long init_record(struct dbCommon *pcommon,int pass)
|
||||
callbackSetUser(pcallback, &pcallback->callback);
|
||||
pcallback->precord = (struct dbCommon *) prec;
|
||||
|
||||
if (pdset->init_record) {
|
||||
status=(*pdset->init_record)(prec);
|
||||
if(status==0) {
|
||||
if(prec->rval==0) prec->val = 0;
|
||||
else prec->val = 1;
|
||||
prec->udf = FALSE;
|
||||
} else if (status==2) status=0;
|
||||
if (pdset->common.init_record) {
|
||||
status=(*pdset->common.init_record)(pcommon);
|
||||
if(status==0) {
|
||||
if(prec->rval==0) prec->val = 0;
|
||||
else prec->val = 1;
|
||||
prec->udf = FALSE;
|
||||
} else if (status==2) status=0;
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
/* convert val to rval */
|
||||
if ( prec->mask != 0 ) {
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
} else prec->rval = (epicsUInt32)prec->val;
|
||||
|
||||
prec->mlst = prec->val;
|
||||
@@ -188,87 +178,87 @@ static long init_record(struct dbCommon *pcommon,int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct boRecord *prec = (struct boRecord *)pcommon;
|
||||
struct bodset *pdset = (struct bodset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
bodset *pdset = (bodset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->write_bo==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_bo");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
unsigned short val;
|
||||
if( (pdset==NULL) || (pdset->write_bo==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_bo");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
unsigned short val;
|
||||
|
||||
prec->pact = TRUE;
|
||||
status=dbGetLink(&prec->dol,DBR_USHORT, &val,0,0);
|
||||
prec->pact = FALSE;
|
||||
if(status==0){
|
||||
prec->val = val;
|
||||
prec->udf = FALSE;
|
||||
}else {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
}
|
||||
}
|
||||
|
||||
/* convert val to rval */
|
||||
if ( prec->mask != 0 ) {
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
} else prec->rval = (epicsUInt32)prec->val;
|
||||
}
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
/* convert val to rval */
|
||||
prec->val=prec->ivov;
|
||||
if ( prec->mask != 0 ) {
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
} else prec->rval = (epicsUInt32)prec->val;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"bo:process Illegal IVOA field");
|
||||
}
|
||||
prec->pact = TRUE;
|
||||
status=dbGetLink(&prec->dol,DBR_USHORT, &val,0,0);
|
||||
prec->pact = FALSE;
|
||||
if(status==0){
|
||||
prec->val = val;
|
||||
prec->udf = FALSE;
|
||||
}else {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
}
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
/* convert val to rval */
|
||||
if ( prec->mask != 0 ) {
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
} else prec->rval = (epicsUInt32)prec->val;
|
||||
}
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
/* convert val to rval */
|
||||
prec->val=prec->ivov;
|
||||
if ( prec->mask != 0 ) {
|
||||
if(prec->val==0) prec->rval = 0;
|
||||
else prec->rval = prec->mask;
|
||||
} else prec->rval = (epicsUInt32)prec->val;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"bo:process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
if((prec->val==1) && (prec->high>0)){
|
||||
myCallback *pcallback;
|
||||
pcallback = (myCallback *)(prec->rpvt);
|
||||
callbackSetPriority(prec->prio, &pcallback->callback);
|
||||
callbackRequestDelayed(&pcallback->callback,(double)prec->high);
|
||||
}
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
if((prec->val==1) && (prec->high>0)){
|
||||
myCallback *pcallback;
|
||||
pcallback = (myCallback *)(prec->rpvt);
|
||||
callbackSetPriority(prec->prio, &pcallback->callback);
|
||||
callbackRequestDelayed(&pcallback->callback,(double)prec->high);
|
||||
}
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -277,17 +267,17 @@ static long special(DBADDR *paddr, int after)
|
||||
int special_type = paddr->special;
|
||||
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == boRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "bo: special");
|
||||
return(S_db_badChoice);
|
||||
case(SPC_MOD):
|
||||
if (dbGetFieldIndex(paddr) == boRecordSIMM) {
|
||||
if (!after)
|
||||
recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
|
||||
else
|
||||
recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
|
||||
return(0);
|
||||
}
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "bo: special");
|
||||
return(S_db_badChoice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,29 +311,29 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
|
||||
static long get_enum_str(const DBADDR *paddr, char *pstring)
|
||||
{
|
||||
boRecord *prec=(boRecord *)paddr->precord;
|
||||
int index;
|
||||
unsigned short *pfield = (unsigned short *)paddr->pfield;
|
||||
boRecord *prec=(boRecord *)paddr->precord;
|
||||
int index;
|
||||
unsigned short *pfield = (unsigned short *)paddr->pfield;
|
||||
|
||||
|
||||
index = dbGetFieldIndex(paddr);
|
||||
if(index!=indexof(VAL)) {
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
} else if(*pfield==0) {
|
||||
strncpy(pstring,prec->znam,sizeof(prec->znam));
|
||||
pstring[sizeof(prec->znam)] = 0;
|
||||
strncpy(pstring,prec->znam,sizeof(prec->znam));
|
||||
pstring[sizeof(prec->znam)] = 0;
|
||||
} else if(*pfield==1) {
|
||||
strncpy(pstring,prec->onam,sizeof(prec->onam));
|
||||
pstring[sizeof(prec->onam)] = 0;
|
||||
strncpy(pstring,prec->onam,sizeof(prec->onam));
|
||||
pstring[sizeof(prec->onam)] = 0;
|
||||
} else {
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
strcpy(pstring,"Illegal_Value");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long get_enum_strs(const DBADDR *paddr,struct dbr_enumStrs *pes)
|
||||
{
|
||||
boRecord *prec=(boRecord *)paddr->precord;
|
||||
boRecord *prec=(boRecord *)paddr->precord;
|
||||
|
||||
/*SETTING no_str=0 breaks channel access clients*/
|
||||
pes->no_str = 2;
|
||||
@@ -367,60 +357,60 @@ static long put_enum_str(const DBADDR *paddr, const char *pstring)
|
||||
|
||||
static void checkAlarms(boRecord *prec)
|
||||
{
|
||||
unsigned short val = prec->val;
|
||||
unsigned short val = prec->val;
|
||||
|
||||
/* check for udf alarm */
|
||||
if(prec->udf == TRUE ){
|
||||
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
|
||||
}
|
||||
/* check for udf alarm */
|
||||
if(prec->udf == TRUE ){
|
||||
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
|
||||
}
|
||||
|
||||
/* check for state alarm */
|
||||
if (val == 0){
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->zsv);
|
||||
}else{
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->osv);
|
||||
}
|
||||
/* check for state alarm */
|
||||
if (val == 0){
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->zsv);
|
||||
}else{
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->osv);
|
||||
}
|
||||
|
||||
/* check for cos alarm */
|
||||
if(val == prec->lalm) return;
|
||||
recGblSetSevr(prec,COS_ALARM,prec->cosv);
|
||||
prec->lalm = val;
|
||||
return;
|
||||
if(val == prec->lalm) return;
|
||||
recGblSetSevr(prec,COS_ALARM,prec->cosv);
|
||||
prec->lalm = val;
|
||||
return;
|
||||
}
|
||||
|
||||
static void monitor(boRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask;
|
||||
unsigned short monitor_mask;
|
||||
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
/* check for value change */
|
||||
if (prec->mlst != prec->val){
|
||||
/* post events for value change and archive change */
|
||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||
/* update last value monitored */
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
/* check for value change */
|
||||
if (prec->mlst != prec->val){
|
||||
/* post events for value change and archive change */
|
||||
monitor_mask |= (DBE_VALUE | DBE_LOG);
|
||||
/* update last value monitored */
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
}
|
||||
if(prec->oraw!=prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
if(prec->orbv!=prec->rbv) {
|
||||
db_post_events(prec,&prec->rbv,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->orbv = prec->rbv;
|
||||
}
|
||||
return;
|
||||
/* send out monitors connected to the value field */
|
||||
if (monitor_mask){
|
||||
db_post_events(prec,&prec->val,monitor_mask);
|
||||
}
|
||||
if(prec->oraw!=prec->rval) {
|
||||
db_post_events(prec,&prec->rval,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
if(prec->orbv!=prec->rbv) {
|
||||
db_post_events(prec,&prec->rbv,
|
||||
monitor_mask|DBE_VALUE|DBE_LOG);
|
||||
prec->orbv = prec->rbv;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static long writeValue(boRecord *prec)
|
||||
{
|
||||
struct bodset *pdset = (struct bodset *) prec->dset;
|
||||
bodset *pdset = (bodset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -48,7 +48,8 @@ recordtype(bo) {
|
||||
|
||||
The binary output record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. The fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
|
||||
L<Scan Fields|dbCommonRecord/Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
fields are used. Note that I/O event scanning is only supported for those card
|
||||
types that interrupt.
|
||||
|
||||
@@ -147,8 +148,8 @@ corresponding to the VAL's state. So, if the value is 1, C<get_enum_str()>
|
||||
will return the string in the ONAM field: and if 0, C<get_enum_str()> will
|
||||
return the ZNAM string.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME)
|
||||
and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields ZNAM, ONAM, NAME, DESC
|
||||
|
||||
@@ -164,13 +165,13 @@ C<MAJOR>. The ZSV holds the severity for the zero state; OSV for the one
|
||||
state. COSV is used to cause an alarm whenever the state changes between
|
||||
states (0-1, 1-0) and its severity is configured as MINOR or MAJOR.
|
||||
|
||||
See L<Invalid Alarm Output Action> for more information on the IVOA and
|
||||
IVOV fields. L<Alarm Fields> lists other fields related to alarms that are
|
||||
See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields> for more information on the IVOA and
|
||||
IVOV fields. L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related to alarms that are
|
||||
common to all record types.
|
||||
|
||||
=fields ZSV, OSV, COSV, IVOA, IVOV
|
||||
|
||||
=head3 Run-Time and Simulation Mode Parameters
|
||||
=head3 Run-Time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processiong the binary
|
||||
output. They are not configurable using a configuration tool. They
|
||||
@@ -201,15 +202,33 @@ The WPDT field is a private field for honoring seconds to hold HIGH.
|
||||
|
||||
=fields ORAW, MASK, RBV, ORBV, LALM, MLST, RPVT, WDPT
|
||||
|
||||
The following fields are used to operate the binary output in the
|
||||
simulation mode. See L<Fields Common to Many Record Types> for more
|
||||
information on these fields.
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
=fields SIOL, SIML, SIMM, SIMS
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is written through SIOL.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Output Simulation Fields|dbCommonOutput/Output Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct boRecord;
|
||||
%typedef struct bodset {
|
||||
% dset common; /*init_record returns:(0,2)=>(success,success no convert*/
|
||||
% long (*write_bo)(struct boRecord *prec); /*returns: (-1,0)=>(failure,success)*/
|
||||
%} bodset;
|
||||
%#define HAS_bodset
|
||||
%
|
||||
field(VAL,DBF_ENUM) {
|
||||
prompt("Current Value")
|
||||
promptgroup("50 - Output")
|
||||
@@ -475,7 +494,7 @@ Check alarms: This routine checks to see if the new VAL causes the alarm
|
||||
status and severity to change. If so, NSEV, NSTA, and LALM are set.
|
||||
|
||||
=item 4.
|
||||
Check severity and write the new value. See L<Invalid Alarm Output Action>
|
||||
Check severity and write the new value. See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for more information on how INVALID alarms affect output.
|
||||
|
||||
=item 5.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* Record Support Routines for Calculation records */
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#define report NULL
|
||||
#define initialize NULL
|
||||
static long init_record(struct dbCommon *prec, int pass);
|
||||
static long init_record(struct dbCommon *pcommon, int pass);
|
||||
static long process(struct dbCommon *prec);
|
||||
static long special(DBADDR *paddr, int after);
|
||||
#define get_value NULL
|
||||
@@ -206,7 +206,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
calcRecord *prec = (calcRecord *)paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
int linkNumber;
|
||||
|
||||
|
||||
switch (fieldIndex) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -234,7 +234,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
calcRecord *prec = (calcRecord *)paddr->precord;
|
||||
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -281,24 +281,24 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
static void checkAlarms(calcRecord *prec, epicsTimeStamp *timeLast)
|
||||
{
|
||||
|
||||
enum {
|
||||
range_Lolo = 1,
|
||||
range_Low,
|
||||
range_Normal,
|
||||
range_High,
|
||||
range_Hihi
|
||||
} alarmRange;
|
||||
static const epicsEnum16 range_stat[] = {
|
||||
SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
|
||||
NO_ALARM, HIGH_ALARM, HIHI_ALARM
|
||||
};
|
||||
enum {
|
||||
range_Lolo = 1,
|
||||
range_Low,
|
||||
range_Normal,
|
||||
range_High,
|
||||
range_Hihi
|
||||
} alarmRange;
|
||||
static const epicsEnum16 range_stat[] = {
|
||||
SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
|
||||
NO_ALARM, HIGH_ALARM, HIHI_ALARM
|
||||
};
|
||||
|
||||
double val, hyst, lalm, alev, aftc, afvl;
|
||||
epicsEnum16 asev;
|
||||
|
||||
if (prec->udf) {
|
||||
recGblSetSevr(prec, UDF_ALARM, prec->udfs);
|
||||
prec->afvl = 0;
|
||||
prec->afvl = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,32 +16,7 @@ then be used.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The fields in the record fall into the following categories:
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
scan parameters
|
||||
|
||||
=item *
|
||||
read parameters
|
||||
|
||||
=item *
|
||||
expression parameters
|
||||
|
||||
=item *
|
||||
operator display parameters
|
||||
|
||||
=item *
|
||||
alarm parameters
|
||||
|
||||
=item *
|
||||
monitor parameters
|
||||
|
||||
=item *
|
||||
run-time parameters
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype calc
|
||||
|
||||
@@ -52,13 +27,8 @@ recordtype(calc) {
|
||||
=head3 Scan Parameters
|
||||
|
||||
The Calc record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. These fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
fields are used. Since the Calc record supports no direct interfaces to
|
||||
hardware, it cannot be scanned on I/O interrupt, so its SCAN field cannot
|
||||
be C<I/O Intr>.
|
||||
|
||||
=fields SCAN
|
||||
circumstances the record will be processed.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
|
||||
=head3 Read Parameters
|
||||
@@ -318,10 +288,13 @@ XOR : Bitwise Exclusive Or
|
||||
C<~> : One's Complement
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Left shift
|
||||
C<<< << >>> : Arithmetic Left Shift
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Right shift
|
||||
C<<< >> >>> : Arithmetic Right Shift
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical Right Shift
|
||||
|
||||
=back
|
||||
|
||||
@@ -463,8 +436,8 @@ solely for an operator's sake and does not have to be used.
|
||||
The HOPR and LOPR fields only refer to the limits of the VAL, HIHI, HIGH,
|
||||
LOW and LOLO fields. PREC controls the precision of the VAL field.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME)
|
||||
and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, PREC, HOPR, LOPR, NAME, DESC
|
||||
|
||||
@@ -481,7 +454,7 @@ limit alarms for the VAL field and the severity corresponding to those
|
||||
conditions.
|
||||
|
||||
The HYST field defines an alarm deadband for each limit. See L<Alarm Specification>
|
||||
for a complete explanation of alarms of these fields. L<Alarm Fields>
|
||||
for a complete explanation of alarms of these fields. L<Alarm Fields|dbCommonRecord/Alarm Fields>
|
||||
lists other fields related to alarms that are common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST
|
||||
|
||||
@@ -90,16 +90,6 @@ epicsExportAddress(int, calcoutODLYprecision);
|
||||
double calcoutODLYlimit = 100000;
|
||||
epicsExportAddress(double, calcoutODLYlimit);
|
||||
|
||||
typedef struct calcoutDSET {
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write;
|
||||
}calcoutDSET;
|
||||
|
||||
|
||||
/* To provide feedback to the user as to the connection status of the
|
||||
* links (.INxV and .OUTV), the following algorithm has been implemented ...
|
||||
*
|
||||
@@ -142,7 +132,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
double *pvalue;
|
||||
epicsEnum16 *plinkValid;
|
||||
short error_number;
|
||||
calcoutDSET *pcalcoutDSET;
|
||||
calcoutdset *pcalcoutDSET;
|
||||
rpvtStruct *prpvt;
|
||||
|
||||
if (pass == 0) {
|
||||
@@ -150,13 +140,13 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pcalcoutDSET = (calcoutDSET *)prec->dset)) {
|
||||
if (!(pcalcoutDSET = (calcoutdset *)prec->dset)) {
|
||||
recGblRecordError(S_dev_noDSET, (void *)prec, "calcout:init_record");
|
||||
return S_dev_noDSET;
|
||||
}
|
||||
|
||||
/* must have write defined */
|
||||
if ((pcalcoutDSET->number < 5) || (pcalcoutDSET->write ==NULL)) {
|
||||
if ((pcalcoutDSET->common.number < 5) || (pcalcoutDSET->write ==NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, (void *)prec, "calcout:init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
@@ -220,8 +210,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
prpvt->cbScheduled = 0;
|
||||
|
||||
prec->epvt = eventNameToHandle(prec->oevt);
|
||||
|
||||
if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec);
|
||||
|
||||
if (pcalcoutDSET->common.init_record) pcalcoutDSET->common.init_record(pcommon);
|
||||
prec->pval = prec->val;
|
||||
prec->mlst = prec->val;
|
||||
prec->alst = prec->val;
|
||||
@@ -271,7 +261,7 @@ static long process(struct dbCommon *pcommon)
|
||||
doOutput = (prec->val != 0.0);
|
||||
break;
|
||||
default:
|
||||
doOutput = 0;
|
||||
doOutput = 0;
|
||||
break;
|
||||
}
|
||||
prec->pval = prec->val;
|
||||
@@ -468,7 +458,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
int linkNumber;
|
||||
|
||||
|
||||
switch (fieldIndex) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -484,7 +474,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
case indexof(ODLY):
|
||||
recGblGetGraphicDouble(paddr,pgd);
|
||||
pgd->lower_disp_limit = 0.0;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
linkNumber = get_linkNumber(fieldIndex);
|
||||
if (linkNumber >= 0) {
|
||||
@@ -500,7 +490,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
|
||||
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
{
|
||||
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
|
||||
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -768,7 +758,7 @@ static void checkLinks(calcoutRecord *prec)
|
||||
|
||||
static long writeValue(calcoutRecord *prec)
|
||||
{
|
||||
calcoutDSET *pcalcoutDSET = (calcoutDSET *)prec->dset;
|
||||
calcoutdset *pcalcoutDSET = (calcoutdset *)prec->dset;
|
||||
|
||||
|
||||
if (!pcalcoutDSET || !pcalcoutDSET->write) {
|
||||
|
||||
@@ -22,35 +22,7 @@ Wait record.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The fields in this record fall into these categories:
|
||||
|
||||
=over 1
|
||||
|
||||
=item *
|
||||
scan parameters
|
||||
|
||||
=item *
|
||||
read parameters
|
||||
|
||||
=item *
|
||||
expression parameters
|
||||
|
||||
=item *
|
||||
output parameters
|
||||
|
||||
=item *
|
||||
operator display parameters
|
||||
|
||||
=item *
|
||||
alarm parameters
|
||||
|
||||
=item *
|
||||
monitor parameters
|
||||
|
||||
=item *
|
||||
run-time parameters
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype calcout
|
||||
|
||||
@@ -80,11 +52,8 @@ recordtype(calcout) {
|
||||
=head3 Scan Parameters
|
||||
|
||||
The Calcout record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. The fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
fields are used. Since the Calcout record supports no direct interfaces to
|
||||
hardware, it cannot be scanned on I/O interrupt, so its SCAN field cannot
|
||||
be C<I/O Intr>.
|
||||
circumstances the record will be processed.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
@@ -99,9 +68,6 @@ example, whether or not the specified PV was found and a link to it
|
||||
established. See L<Operator Display Parameters> for an explanation of these
|
||||
fields.
|
||||
|
||||
See L<Address Specification> for information on how to specify database
|
||||
links.
|
||||
|
||||
=fields INPA, INPB, INPC, INPD, INPE, INPF, INPG, INPH, INPI, INPJ, INPK, INPL
|
||||
|
||||
=head3 Expression
|
||||
@@ -350,10 +316,13 @@ XOR : Bitwise Exclusive Or
|
||||
C<~> : One's Complement
|
||||
|
||||
=item *
|
||||
C<<< << >>> : Left shift
|
||||
C<<< << >>> : Arithmetic Left Shift
|
||||
|
||||
=item *
|
||||
C<<< >> >>> : Right shift
|
||||
C<<< >> >>> : Arithmetic Right Shift
|
||||
|
||||
=item *
|
||||
C<<<< >>> >>>> : Logical Right Shift
|
||||
|
||||
=back
|
||||
|
||||
@@ -604,8 +573,8 @@ is set to one.
|
||||
|
||||
The DLYA field is set to one during the delay specified in ODLY.
|
||||
|
||||
See L<Fields Common to All Record Types> for more information on the record
|
||||
name (NAME) and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, PREC, HOPR, LOPR, INAV, INBV, INCV, INDV, INEV, INFV, INGV, INHV, INIV, INJV, INKV, INLV, OUTV, CLCV, OCLV, DLYA, NAME, DESC
|
||||
|
||||
@@ -659,6 +628,14 @@ manner for the VAL field.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct calcoutRecord;
|
||||
%typedef struct calcoutdset {
|
||||
% dset common;
|
||||
% long (*write)(struct calcoutRecord *prec);
|
||||
%} calcoutdset;
|
||||
%#define HAS_calcoutdset
|
||||
%
|
||||
field(RPVT,DBF_NOACCESS) {
|
||||
prompt("Record Private")
|
||||
special(SPC_NOMOD)
|
||||
|
||||
@@ -44,8 +44,6 @@ The record-specific fields are described below.
|
||||
|
||||
=recordtype compress
|
||||
|
||||
...
|
||||
|
||||
=cut
|
||||
|
||||
menu(compressALG) {
|
||||
@@ -70,7 +68,8 @@ The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
The compression record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. These fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification>
|
||||
|
||||
L<Scan Fields|dbCommonRecord/Scan Fields>. In addition, L<Scanning Specification>
|
||||
explains how these fields are used. Since the compression record supports no
|
||||
direct interfaces to hardware, its SCAN field cannot specify C<<< I/O Intr >>>.
|
||||
|
||||
@@ -197,14 +196,14 @@ PREC controls the floating-point precision whenever C<<< get_precision >>> is
|
||||
called, and the field being referenced is the VAL field (i.e., one of the values
|
||||
contained in the circular buffer).
|
||||
|
||||
See L<Fields Common to All Record Types>
|
||||
for more on the record name (NAME) and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The compression record has the alarm parameters common to all record types
|
||||
described in L<Alarm Fields>.
|
||||
described in L<Alarm Fields|dbCommonRecord/Alarm Fields>.
|
||||
|
||||
=head3 Run-time Parameters
|
||||
|
||||
@@ -234,7 +233,7 @@ appropriate fields in the record.
|
||||
|
||||
long process(struct dbCommon *precord)
|
||||
|
||||
See L<Record Processing> below.
|
||||
See L</"Record Processing"> below.
|
||||
|
||||
long special(struct dbAddr *paddr, int after)
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
* Copyright (c) 2002 Southeastern Universities Research Association, as
|
||||
* Operator of Thomas Jefferson National Accelerator Facility.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recDfanout.c - Record Support Routines for Dfanout records */
|
||||
/*
|
||||
* Original Author: Matt Bickley (Sometime in 1994)
|
||||
* Original Author: Matt Bickley (Sometime in 1994)
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 1994 mhb Started with longout record to make the data fanout
|
||||
* .02 May 10, 96 jt Bug Fix
|
||||
* .02 May 10, 96 jt Bug Fix
|
||||
* .03 11SEP2000 mrk LONG=>DOUBLE, add SELL,SELN,SELM
|
||||
*/
|
||||
|
||||
@@ -62,24 +62,24 @@ static long get_control_double(DBADDR *,struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *,struct dbr_alDouble *);
|
||||
|
||||
rset dfanoutRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,dfanoutRSET);
|
||||
|
||||
@@ -183,8 +183,8 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
case indexof(LALM):
|
||||
case indexof(ALST):
|
||||
case indexof(MLST):
|
||||
pcd->upper_ctrl_limit = prec->hopr;
|
||||
pcd->lower_ctrl_limit = prec->lopr;
|
||||
pcd->upper_ctrl_limit = prec->hopr;
|
||||
pcd->lower_ctrl_limit = prec->lopr;
|
||||
break;
|
||||
default:
|
||||
recGblGetControlDouble(paddr,pcd);
|
||||
@@ -194,7 +194,7 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
|
||||
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
|
||||
{
|
||||
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
|
||||
|
||||
|
||||
if(dbGetFieldIndex(paddr) == indexof(VAL)) {
|
||||
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
|
||||
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
|
||||
|
||||
@@ -16,32 +16,7 @@ device support.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The fields in this record can be classified into the following categories:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
scan parameters
|
||||
|
||||
=item *
|
||||
desired output parameters
|
||||
|
||||
=item *
|
||||
write parameters
|
||||
|
||||
=item *
|
||||
operator display parameters
|
||||
|
||||
=item *
|
||||
alarm parameters
|
||||
|
||||
=item *
|
||||
monitor parameters
|
||||
|
||||
=item *
|
||||
run-time and simulation mode parameters
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype dfanout
|
||||
|
||||
@@ -58,11 +33,8 @@ recordtype(dfanout) {
|
||||
=head3 Scan Parameters
|
||||
|
||||
The data fanout record has the standard fields for specifying under what
|
||||
circumstances it will be processed. These fields are listed in
|
||||
L<Scan Fields>. In addition, L<Scanning Specification> explains how these
|
||||
fields are used. Since the data fanout record supports no direct interfaces
|
||||
to hardware, it cannot be scanned on I/O interrupt, so its SCAN field
|
||||
cannot be C<I/O Intr>.
|
||||
circumstances it will be processed.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Desired Output Parameters
|
||||
|
||||
@@ -131,8 +103,8 @@ displays. They apply to the VAL, HIHI, HIGH, LOW, and LOLO fields. The
|
||||
record support routines C<get_graphic_double()> and C<get_control_double()>
|
||||
retrieve HOPR and LOPR.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME)
|
||||
and description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, HOPR, LOPR, NAME, DESC
|
||||
|
||||
@@ -148,7 +120,7 @@ NO_ALARM, MINOR, or MAJOR. In the hysteresis field (HYST) can be entered a
|
||||
number which serves as the deadband on the limit alarms.
|
||||
|
||||
See L<Alarm Specification> for a complete explanation of alarms and these
|
||||
fields. L<Alarm Fields> lists other fields related to alarms that are
|
||||
fields. L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related to alarms that are
|
||||
common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recEvent.c - Record Support Routines for Event records */
|
||||
@@ -59,35 +59,27 @@ static long special(DBADDR *, int);
|
||||
#define get_alarm_double NULL
|
||||
|
||||
rset eventRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,eventRSET);
|
||||
|
||||
struct eventdset { /* event input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_event;/*(0)=> success */
|
||||
};
|
||||
static void monitor(eventRecord *);
|
||||
static long readValue(eventRecord *);
|
||||
|
||||
@@ -95,7 +87,7 @@ static long readValue(eventRecord *);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct eventRecord *prec = (struct eventRecord *)pcommon;
|
||||
struct eventdset *pdset;
|
||||
eventdset *pdset;
|
||||
long status=0;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
@@ -103,8 +95,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_STRING, &prec->sval);
|
||||
|
||||
if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) )
|
||||
status=(*pdset->init_record)(prec);
|
||||
if( (pdset=(eventdset *)(prec->dset)) && (pdset->common.init_record) )
|
||||
status=(*pdset->common.init_record)(pcommon);
|
||||
|
||||
prec->epvt = eventNameToHandle(prec->val);
|
||||
|
||||
@@ -114,28 +106,28 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct eventRecord *prec = (struct eventRecord *)pcommon;
|
||||
struct eventdset *pdset = (struct eventdset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
eventdset *pdset = (eventdset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
|
||||
if((pdset!=NULL) && (pdset->number >= 5) && pdset->read_event )
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
postEvent(prec->epvt);
|
||||
if((pdset!=NULL) && (pdset->common.number >= 5) && pdset->read_event )
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
postEvent(prec->epvt);
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +165,7 @@ static void monitor(eventRecord *prec)
|
||||
|
||||
static long readValue(eventRecord *prec)
|
||||
{
|
||||
struct eventdset *pdset = (struct eventdset *) prec->dset;
|
||||
eventdset *pdset = (eventdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -15,27 +15,7 @@ handler routine for I/O Event-scanned records.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The records in this field fall into the following groups of parameters:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
scan parameters
|
||||
|
||||
=item *
|
||||
|
||||
read parameters
|
||||
|
||||
=item *
|
||||
|
||||
event number parameters
|
||||
|
||||
=item *
|
||||
|
||||
simulation mode parameters
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype event
|
||||
|
||||
@@ -44,14 +24,23 @@ simulation mode parameters
|
||||
recordtype(event) {
|
||||
include "dbCommon.dbd"
|
||||
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct eventRecord;
|
||||
%typedef struct eventdset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*read_event)(struct eventRecord *prec); /*(0)=> success */
|
||||
%} eventdset;
|
||||
%#define HAS_eventdset
|
||||
%
|
||||
|
||||
=head3 Scan Parameters
|
||||
|
||||
The event record has the standard fields for specifying under what circumstances
|
||||
it will be processed. If the SCAN field specifies C<I/O Intr>, then device
|
||||
support will provide an interrupt handler, posting an event number when an I/O
|
||||
interrupt occurs. These fields are listed in L<Scan Fields>. In addition,
|
||||
L<Scanning Specification> explains how the scanning fields work. Note that I/O
|
||||
event scanning is only supported for those card types that interrupt.
|
||||
interrupt occurs.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Event Number Parameters
|
||||
|
||||
@@ -102,8 +91,9 @@ access link. For soft records, the DTYP field should specify C<Soft Channel>.
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME) and
|
||||
description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
|
||||
=fields NAME, DESC
|
||||
|
||||
@@ -266,7 +256,7 @@ C<init_record()> routine.
|
||||
get_ioint_info(int cmd, struct dbCommon *precord, IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. cmd has the value (0,1) if the record is
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the record is
|
||||
being (added to, deleted from) an I/O event list. It must be provided for any
|
||||
device type that can use the ioEvent scanner.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
@@ -17,27 +17,11 @@ process. If more than sixteen are needed, one of the forward links in the fanout
|
||||
record (or its FLNK field) can point to another fanout record.
|
||||
|
||||
B<NOTE: Fanout records only propagate processing, not data.> The dfanout or
|
||||
data fanout record can, on the other hand, send data to other records.
|
||||
Data Fanout record can, on the other hand, send data to other records.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The fanout record's fields fall into the following categories:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
scan parameters
|
||||
|
||||
=item *
|
||||
|
||||
operator display parameters
|
||||
|
||||
=item *
|
||||
|
||||
run-time parameters.
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=recordtype fanout
|
||||
|
||||
@@ -113,9 +97,7 @@ retrieved from SELL each time the record is processed and can also be changed
|
||||
via dbPuts.
|
||||
|
||||
The Fanout record also has the standard scanning fields common to all records.
|
||||
These fields are listed in L<Scan Fields>. In addition,
|
||||
L<Scanning Specification> explains in more detail how forward links and the
|
||||
scanning algorithms work.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=fields SELM, SELN, SELL, OFFS, SHFT, LNK0, LNK1, LNK2, LNK3, LNK4, LNK5, LNK6, LNK7, LNK8, LNK9, LNKA, LNKB, LNKC, LNKD, LNKE, LNKF
|
||||
|
||||
@@ -238,15 +220,16 @@ scanning algorithms work.
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator. See
|
||||
L<Fields Common to All Record Types> for more on these fields.
|
||||
L<Fields Common to All Record Types|dbCommonRecord/Operator Display Parameters>
|
||||
for more on these fields.
|
||||
|
||||
=fields NAME, DESC
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The Fanout record has the alarm parameters common to all record types.
|
||||
L<Alarm Fields> lists other fields related to a alarms that are common to all
|
||||
record types.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists the fields related to
|
||||
alarms that are common to all record types.
|
||||
|
||||
=head3 Run-time Parameters
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* histogramRecord.c - Record Support Routines for Histogram records */
|
||||
@@ -87,17 +87,6 @@ epicsExportAddress(rset,histogramRSET);
|
||||
int histogramSDELprecision = 2;
|
||||
epicsExportAddress(int, histogramSDELprecision);
|
||||
|
||||
struct histogramdset { /* histogram input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_histogram;/*(0,2)=> success and add_count, don't add_count)*/
|
||||
/* if add_count then sgnl added to array */
|
||||
DEVSUPFUN special_linconv;
|
||||
};
|
||||
|
||||
/* control block for callback*/
|
||||
typedef struct myCallback {
|
||||
epicsCallback callback;
|
||||
@@ -133,39 +122,34 @@ static void wdogCallback(epicsCallback *arg)
|
||||
|
||||
return;
|
||||
}
|
||||
static long wdogInit(histogramRecord *prec)
|
||||
|
||||
static void wdogInit(histogramRecord *prec)
|
||||
{
|
||||
myCallback *pcallback;
|
||||
|
||||
if (!prec->wdog && prec->sdel > 0) {
|
||||
/* initialize a callback object */
|
||||
pcallback = calloc(1, sizeof(myCallback));
|
||||
pcallback->prec = prec;
|
||||
if (!pcallback)
|
||||
return -1;
|
||||
|
||||
callbackSetCallback(wdogCallback, &pcallback->callback);
|
||||
callbackSetUser(pcallback, &pcallback->callback);
|
||||
callbackSetPriority(priorityLow, &pcallback->callback);
|
||||
prec->wdog = pcallback;
|
||||
}
|
||||
|
||||
if (!prec->wdog)
|
||||
return -1;
|
||||
pcallback = prec->wdog;
|
||||
if (!pcallback)
|
||||
return -1;
|
||||
if (prec->sdel > 0) {
|
||||
myCallback *pcallback = prec->wdog;
|
||||
|
||||
if (!pcallback) {
|
||||
/* initialize a callback object */
|
||||
pcallback = calloc(1, sizeof(myCallback));
|
||||
if (!pcallback)
|
||||
return;
|
||||
|
||||
pcallback->prec = prec;
|
||||
callbackSetCallback(wdogCallback, &pcallback->callback);
|
||||
callbackSetUser(pcallback, &pcallback->callback);
|
||||
callbackSetPriority(priorityLow, &pcallback->callback);
|
||||
prec->wdog = pcallback;
|
||||
}
|
||||
|
||||
/* start new timer on monitor */
|
||||
callbackRequestDelayed(&pcallback->callback, prec->sdel);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct histogramRecord *prec = (struct histogramRecord *)pcommon;
|
||||
struct histogramdset *pdset;
|
||||
histogramdset *pdset;
|
||||
|
||||
if (pass == 0) {
|
||||
/* allocate space for histogram array */
|
||||
@@ -186,21 +170,21 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
recGblInitConstantLink(&prec->siol, DBF_DOUBLE, &prec->sval);
|
||||
|
||||
/* must have device support defined */
|
||||
pdset = (struct histogramdset *) prec->dset;
|
||||
pdset = (histogramdset *) prec->dset;
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "histogram: init_record");
|
||||
return S_dev_noDSET;
|
||||
}
|
||||
|
||||
/* must have read_histogram function defined */
|
||||
if (pdset->number < 6 || !pdset->read_histogram) {
|
||||
if (pdset->common.number < 6 || !pdset->read_histogram) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "histogram: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
/* call device support init_record */
|
||||
if (pdset->init_record) {
|
||||
long status = pdset->init_record(prec);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -211,7 +195,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct histogramRecord *prec = (struct histogramRecord *)pcommon;
|
||||
struct histogramdset *pdset = (struct histogramdset *) prec->dset;
|
||||
histogramdset *pdset = (histogramdset *) prec->dset;
|
||||
int pact = prec->pact;
|
||||
long status;
|
||||
|
||||
@@ -380,7 +364,7 @@ static long clear_histogram(histogramRecord *prec)
|
||||
|
||||
static long readValue(histogramRecord *prec)
|
||||
{
|
||||
struct histogramdset *pdset = (struct histogramdset *) prec->dset;
|
||||
histogramdset *pdset = (histogramdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
menu(histogramCMD) {
|
||||
choice(histogramCMD_Read,"Read")
|
||||
choice(histogramCMD_Clear,"Clear")
|
||||
choice(histogramCMD_Start,"Start")
|
||||
choice(histogramCMD_Stop,"Stop")
|
||||
}
|
||||
recordtype(histogram) {
|
||||
include "dbCommon.dbd"
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
extra("void * val")
|
||||
#=type ULONG[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(NELM,DBF_USHORT) {
|
||||
prompt("Num of Array Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(CSTA,DBF_SHORT) {
|
||||
prompt("Collection Status")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(CMD,DBF_MENU) {
|
||||
prompt("Collection Control")
|
||||
asl(ASL0)
|
||||
special(SPC_CALC)
|
||||
interest(1)
|
||||
menu(histogramCMD)
|
||||
}
|
||||
field(ULIM,DBF_DOUBLE) {
|
||||
prompt("Upper Signal Limit")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LLIM,DBF_DOUBLE) {
|
||||
prompt("Lower Signal Limit ")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(WDTH,DBF_DOUBLE) {
|
||||
prompt("Element Width")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SGNL,DBF_DOUBLE) {
|
||||
prompt("Signal Value")
|
||||
special(SPC_MOD)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(SVL,DBF_INLINK) {
|
||||
prompt("Signal Value Location")
|
||||
promptgroup("40 - Input")
|
||||
interest(1)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsUInt32 *bptr")
|
||||
}
|
||||
field(WDOG,DBF_NOACCESS) {
|
||||
prompt("Watchdog callback")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * wdog")
|
||||
}
|
||||
field(MDEL,DBF_SHORT) {
|
||||
prompt("Monitor Count Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(MCNT,DBF_SHORT) {
|
||||
prompt("Counts Since Monitor")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Seconds Dband")
|
||||
promptgroup("80 - Display")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_DOUBLE) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(HOPR,DBF_ULONG) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_ULONG) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
}
|
||||
|
||||
variable(histogramSDELprecision, int)
|
||||
@@ -0,0 +1,456 @@
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
# Copyright (c) 2002 The Regents of the University of California, as
|
||||
# Operator of Los Alamos National Laboratory.
|
||||
# EPICS BASE is distributed subject to a Software License Agreement found
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
=title Histogram Record (histogram)
|
||||
|
||||
The histogram record is used to store frequency counts of a signal into an array
|
||||
of arbitrary length. The user can configure the range of the signal value that
|
||||
the array will store. Anything outside this range will be ignored.
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The record-specific fields are described below.
|
||||
|
||||
=recordtype histogram
|
||||
|
||||
=cut
|
||||
|
||||
menu(histogramCMD) {
|
||||
choice(histogramCMD_Read,"Read")
|
||||
choice(histogramCMD_Clear,"Clear")
|
||||
choice(histogramCMD_Start,"Start")
|
||||
choice(histogramCMD_Stop,"Stop")
|
||||
}
|
||||
recordtype(histogram) {
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
The SVL is the input link where the record reads its value. It can be a
|
||||
constant, a database link, or a channel access link. If SVL is a database or
|
||||
channel access link, then SGNL is read from SVL. If SVL is a constant, then SGNL
|
||||
is initialized with the constant value but can be changed via dbPuts. The C<Soft
|
||||
Channel> device support module can be specified in the DTYP field.
|
||||
|
||||
The ULIM and LLIM fields determine the usable range of signal values. Any value
|
||||
of SGNL below LLIM or above ULIM is outside the range and will not be stored in
|
||||
the array. In the NELM field the user must specify the array size, e.g., the
|
||||
number of array elements. Each element in the NELM field holds the counts for an
|
||||
interval of the range of signal counts, the range specified by ULIM and LLIM.
|
||||
These intervals are determined by dividing the range by NELM:
|
||||
|
||||
(ULIM - LLIM) / NELM.
|
||||
|
||||
=fields SVL, SGNL, DTYP, NELM, ULIM, LLIM
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
These parameters are used to present meaningful data to the operator. These
|
||||
fields are used to display the value and other parameters of the histogram
|
||||
either textually or graphically. See
|
||||
L<Fields Common to All Record Types|dbCommonRecord/Operator Display Parameters>
|
||||
for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields NAME, DESC
|
||||
|
||||
=head3 Alarm Parameters
|
||||
|
||||
The Histogram record has the alarm parameters common to all record types.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists the fields related to
|
||||
alarms that are common to all record types.
|
||||
|
||||
=head3 Monitor Parameters
|
||||
|
||||
The MDEL field implements the monitor count deadband. Only when MCNT is greater
|
||||
than the value given to MDEL are monitors triggered, MCNT being the number of
|
||||
counts since the last time the record was processed. If MDEL is -1, everytime
|
||||
the record is processed, a monitor is triggered regardless.
|
||||
|
||||
If SDEL is greater than 0, it causes a callback routine to be called. The number
|
||||
specified in SDEL is the callback routines interval. The callback routine is
|
||||
called every SDEL seconds. The callback routine posts an event if MCNT is
|
||||
greater than 0.
|
||||
|
||||
=fields MDEL, SDEL
|
||||
|
||||
=head3 Run-time and Simulation Mode Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the histogram.
|
||||
They are not configurable by the user prior to run-time. They represent the
|
||||
current state of the record. Many of them are used to process the histogram more
|
||||
efficiently.
|
||||
|
||||
The BPTR field contains a pointer to the unsigned long array of frequency
|
||||
values. The VAL field references this array as well. However, the BPTR field is
|
||||
not accessible at run-time.
|
||||
|
||||
The MCNT field keeps counts the number of signal counts since the last monitor
|
||||
was invoked.
|
||||
|
||||
The collections controls field (CMD) is a menu field with five choices:
|
||||
|
||||
=menu histogramCMD
|
||||
|
||||
When CMD is C<Read>, the record retrieves its values and adds them to the signal
|
||||
array. This command will first clear the signal counts which have already been
|
||||
read when it is first invoked.
|
||||
|
||||
The C<Clear> command erases the signal counts, setting the elements in the array
|
||||
back to zero. Afterwards, the CMD field is set back to C<Read>.
|
||||
|
||||
The C<Start> command simply causes the record to read signal values into the
|
||||
array. Unlike C<Read>, it doesn't clear the array first.
|
||||
|
||||
The C<Stop> command disables the reading of signal values into the array.
|
||||
|
||||
The C<Setup> command waits until the C<start> or C<read> command has been issued
|
||||
to start counting.
|
||||
|
||||
The CSTA or collections status field implements the CMD field choices by
|
||||
enabling or disabling the reading of values into the histogram array. While
|
||||
FALSE, no signals are added to the array. While TRUE, signals are read and added
|
||||
to the array. The field is initialized to TRUE. The C<Stop> command is the only
|
||||
command that sets CSTA to FALSE. On the other hand, the C<Start> command is the
|
||||
only command that sets it to TRUE. Thus, C<Start> must be invoked after each
|
||||
C<Stop> command in order to enable counting; invoking C<Read> will not enable
|
||||
signal counting after C<Stop> has been invoked.
|
||||
|
||||
A typical use of these fields would be to initialize the CMD field to C<Read>
|
||||
(it is initialized to this command by default), to use the C<Stop> command to
|
||||
disable counting when necessary, after which the C<Start> command can be invoked
|
||||
to re-start the signal count.
|
||||
|
||||
The WDTH field is a private field that holds the signal width of the array
|
||||
elements. For instance, if the LLIM was configured to be 4.0 and ULIM was
|
||||
configured to be 12.0 and the NELM was set to 4, then the WDTH for each array
|
||||
would be 2. Thus, it is (ULIM - LLIM) / NELM.
|
||||
|
||||
=fields BPTR, VAL, MCNT, CMD, CSTA, WDTH
|
||||
|
||||
The following fields are used to operate the histogram record in simulation
|
||||
mode. See L<Fields Common to Many Record Types> for more information on the
|
||||
simulation mode fields.
|
||||
|
||||
=fields SIOL, SVAL, SIML, SIMM, SIMS
|
||||
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct histogramRecord;
|
||||
%typedef struct histogramdset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*read_histogram)(struct histogramRecord *prec); /*(0,2)=> success and add_count, don't add_count); if add_count then sgnl added to array*/
|
||||
% long (*special_linconv)(struct histogramRecord *prec, int after);
|
||||
%} histogramdset;
|
||||
%#define HAS_histogramdset
|
||||
%
|
||||
field(VAL,DBF_NOACCESS) {
|
||||
prompt("Value")
|
||||
asl(ASL0)
|
||||
special(SPC_DBADDR)
|
||||
extra("void * val")
|
||||
#=type ULONG[]
|
||||
#=read Yes
|
||||
#=write Yes
|
||||
}
|
||||
field(NELM,DBF_USHORT) {
|
||||
prompt("Num of Array Elements")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(CSTA,DBF_SHORT) {
|
||||
prompt("Collection Status")
|
||||
special(SPC_NOMOD)
|
||||
interest(1)
|
||||
initial("1")
|
||||
}
|
||||
field(CMD,DBF_MENU) {
|
||||
prompt("Collection Control")
|
||||
asl(ASL0)
|
||||
special(SPC_CALC)
|
||||
interest(1)
|
||||
menu(histogramCMD)
|
||||
}
|
||||
field(ULIM,DBF_DOUBLE) {
|
||||
prompt("Upper Signal Limit")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LLIM,DBF_DOUBLE) {
|
||||
prompt("Lower Signal Limit ")
|
||||
promptgroup("30 - Action")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(WDTH,DBF_DOUBLE) {
|
||||
prompt("Element Width")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SGNL,DBF_DOUBLE) {
|
||||
prompt("Signal Value")
|
||||
special(SPC_MOD)
|
||||
}
|
||||
field(PREC,DBF_SHORT) {
|
||||
prompt("Display Precision")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(SVL,DBF_INLINK) {
|
||||
prompt("Signal Value Location")
|
||||
promptgroup("40 - Input")
|
||||
interest(1)
|
||||
}
|
||||
field(BPTR,DBF_NOACCESS) {
|
||||
prompt("Buffer Pointer")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsUInt32 *bptr")
|
||||
}
|
||||
field(WDOG,DBF_NOACCESS) {
|
||||
prompt("Watchdog callback")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("void * wdog")
|
||||
}
|
||||
field(MDEL,DBF_SHORT) {
|
||||
prompt("Monitor Count Deadband")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
}
|
||||
field(MCNT,DBF_SHORT) {
|
||||
prompt("Counts Since Monitor")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(SDEL,DBF_DOUBLE) {
|
||||
prompt("Monitor Seconds Dband")
|
||||
promptgroup("80 - Display")
|
||||
special(SPC_RESET)
|
||||
interest(1)
|
||||
}
|
||||
field(SIOL,DBF_INLINK) {
|
||||
prompt("Simulation Input Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SVAL,DBF_DOUBLE) {
|
||||
prompt("Simulation Value")
|
||||
}
|
||||
field(SIML,DBF_INLINK) {
|
||||
prompt("Simulation Mode Link")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
}
|
||||
field(SIMM,DBF_MENU) {
|
||||
prompt("Simulation Mode")
|
||||
special(SPC_MOD)
|
||||
interest(1)
|
||||
menu(menuYesNo)
|
||||
}
|
||||
field(SIMS,DBF_MENU) {
|
||||
prompt("Simulation Mode Severity")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
menu(menuAlarmSevr)
|
||||
}
|
||||
field(OLDSIMM,DBF_MENU) {
|
||||
prompt("Prev. Simulation Mode")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
menu(menuSimm)
|
||||
}
|
||||
field(SSCN,DBF_MENU) {
|
||||
prompt("Sim. Mode Scan")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
menu(menuScan)
|
||||
initial("65535")
|
||||
}
|
||||
field(SDLY,DBF_DOUBLE) {
|
||||
prompt("Sim. Mode Async Delay")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(2)
|
||||
initial("-1.0")
|
||||
}
|
||||
%#include "callback.h"
|
||||
field(SIMPVT,DBF_NOACCESS) {
|
||||
prompt("Sim. Mode Private")
|
||||
special(SPC_NOMOD)
|
||||
interest(4)
|
||||
extra("epicsCallback *simpvt")
|
||||
}
|
||||
field(HOPR,DBF_ULONG) {
|
||||
prompt("High Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
field(LOPR,DBF_ULONG) {
|
||||
prompt("Low Operating Range")
|
||||
promptgroup("80 - Display")
|
||||
interest(1)
|
||||
prop(YES)
|
||||
}
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
=head3 Record Support Routines
|
||||
|
||||
=head4 init_record
|
||||
|
||||
Using NELM, space for the unsigned long array is allocated and the width WDTH of
|
||||
the array is calculated.
|
||||
|
||||
This routine initializes SIMM with the value of SIML if SIML type is CONSTANT
|
||||
link or creates a channel access link if SIML type is PV_LINK. SVAL is likewise
|
||||
initialized if SIOL is CONSTANT or PV_LINK.
|
||||
|
||||
This routine next checks to see that device support and a device support read
|
||||
routine are available. If device support includes C<init_record()>, it is
|
||||
called.
|
||||
|
||||
=head4 process
|
||||
|
||||
See next section.
|
||||
|
||||
=head4 special
|
||||
|
||||
Special is invoked whenever the fields CMD, SGNL, ULIM, or LLIM are changed.
|
||||
|
||||
If SGNL is changed, add_count is called.
|
||||
|
||||
If ULIM or LLIM are changed, WDTH is recalculated and clear_histogram is called.
|
||||
|
||||
If CMD is less or equal to 1, clear_histogram is called and CMD is reset to 0.
|
||||
If CMD is 2, CSTA is set to TRUE and CMD is reset to 0. If CMD is 3, CSTA is set
|
||||
to FALSE and CMD is reset to 0.
|
||||
|
||||
clear_histogram zeros out the histogram array. add_count increments the
|
||||
frequency in the histogram array.
|
||||
|
||||
=head4 cvt_dbaddr
|
||||
|
||||
This is called by dbNameToAddr. It makes the dbAddr structure refer to the
|
||||
actual buffer holding the array.
|
||||
|
||||
=head4 get_array_info
|
||||
|
||||
Obtains values from the array referenced by VAL.
|
||||
|
||||
=head4 put_array_info
|
||||
|
||||
Writes values into the array referenced by VAL.
|
||||
|
||||
=head3 Record Processing
|
||||
|
||||
Routine process implements the following algorithm:
|
||||
|
||||
=over
|
||||
|
||||
=item 1.
|
||||
|
||||
Check to see that the appropriate device support module exists. If it doesn't,
|
||||
an error message is issued and processing is terminated with the PACT field set
|
||||
to TRUE. This ensures that processes will no longer be called for this record.
|
||||
Thus error storms will not occur.
|
||||
|
||||
=item 2.
|
||||
|
||||
readValue is called. See L<Input Records> for more information
|
||||
|
||||
=item 3.
|
||||
|
||||
If PACT has been changed to TRUE, the device support read routine has started
|
||||
but has not completed writing the new value. In this case, the processing
|
||||
routine merely returns, leaving PACT TRUE.
|
||||
|
||||
=item 4.
|
||||
|
||||
Add count to histogram array.
|
||||
|
||||
=item 5.
|
||||
|
||||
Check to see if monitors should be invoked. Alarm monitors are invoked if the
|
||||
alarm status or severity has changed. Archive and value change monitors are
|
||||
invoked if MDEL conditions are met. NSEV and NSTA are reset to 0.
|
||||
|
||||
=item 6.
|
||||
|
||||
Scan forward link if necessary, set PACT and INIT to FALSE, and return.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Device Support
|
||||
|
||||
=head3 Fields Of Interest To Device Support
|
||||
|
||||
The device support routines are primarily interested in the following fields:
|
||||
|
||||
=fields PACT, DPVT, UDF, NSEV, NSTA, SVL, SGNL
|
||||
|
||||
=head3 Device Support Routines
|
||||
|
||||
Device support consists of the following routines:
|
||||
|
||||
=head4 long report(int level)
|
||||
|
||||
This optional routine is called by the IOC command C<dbior> and is passed the
|
||||
report level that was requested by the user.
|
||||
It should print a report on the state of the device support to stdout.
|
||||
The C<level> parameter may be used to output increasingly more detailed
|
||||
information at higher levels, or to select different types of information with
|
||||
different levels.
|
||||
Level zero should print no more than a small summary.
|
||||
|
||||
=head4 long init(int after)
|
||||
|
||||
This optional routine is called twice at IOC initialization time.
|
||||
The first call happens before any of the C<init_record()> calls are made, with
|
||||
the integer parameter C<after> set to 0.
|
||||
The second call happens after all of the C<init_record()> calls have been made,
|
||||
with C<after> set to 1.
|
||||
|
||||
=head4 init_record
|
||||
|
||||
init_record(precord)
|
||||
|
||||
This routine is called by the record support C<init_record()> routine. It makes
|
||||
sure that SGNL is a CONSTANT, PV_LINK, DB_LINK, or CA_LINK. It also retrieves a
|
||||
value for SVL from SGNL. If SGNL is none of the above, an error is generated.
|
||||
|
||||
=head4 read_histogram
|
||||
|
||||
read_histogram(*precord)
|
||||
|
||||
This routine is called by the record support routines. It retrieves a value for
|
||||
SVL from SGNL.
|
||||
|
||||
=head3 Device Support For Soft Records
|
||||
|
||||
Only the device support module C<Soft Channel> is currently provided, though
|
||||
other device support modules may be provided at the user's site.
|
||||
|
||||
=head4 Soft Channel
|
||||
|
||||
The C<Soft Channel> device support routine retrieves a value from SGNL. SGNL
|
||||
must be CONSTANT, PV_LINK, DB_LINK, or CA_LINK.
|
||||
|
||||
=cut
|
||||
|
||||
}
|
||||
|
||||
variable(histogramSDELprecision, int)
|
||||
@@ -4,13 +4,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* int64inRecord.c - Record Support Routines for int64in records */
|
||||
/*
|
||||
* Original Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -58,39 +58,31 @@ static long get_units(DBADDR *, char *);
|
||||
#define put_enum_str NULL
|
||||
static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
|
||||
static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
rset int64inRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,int64inRSET);
|
||||
|
||||
|
||||
struct int64indset { /* int64in input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_int64in; /*returns: (-1,0)=>(failure,success)*/
|
||||
};
|
||||
static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast);
|
||||
static void monitor(int64inRecord *prec);
|
||||
static long readValue(int64inRecord *prec);
|
||||
@@ -99,7 +91,7 @@ static long readValue(int64inRecord *prec);
|
||||
static long init_record(dbCommon *pcommon, int pass)
|
||||
{
|
||||
int64inRecord *prec = (int64inRecord*)pcommon;
|
||||
struct int64indset *pdset;
|
||||
int64indset *pdset;
|
||||
long status;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
@@ -108,17 +100,17 @@ static long init_record(dbCommon *pcommon, int pass)
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
recGblInitConstantLink(&prec->siol, DBF_INT64, &prec->sval);
|
||||
|
||||
if(!(pdset = (struct int64indset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64in: init_record");
|
||||
return(S_dev_noDSET);
|
||||
if(!(pdset = (int64indset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64in: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have read_int64in function defined */
|
||||
if( (pdset->number < 5) || (pdset->read_int64in == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"int64in: init_record");
|
||||
return(S_dev_missingSup);
|
||||
if ((pdset->common.number < 5) || (pdset->read_int64in == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"int64in: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if( pdset->init_record ) {
|
||||
if((status=(*pdset->init_record)(prec))) return(status);
|
||||
if (pdset->common.init_record) {
|
||||
if ((status = pdset->common.init_record(pcommon))) return status;
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
prec->alst = prec->val;
|
||||
@@ -129,36 +121,36 @@ static long init_record(dbCommon *pcommon, int pass)
|
||||
static long process(dbCommon *pcommon)
|
||||
{
|
||||
int64inRecord *prec = (int64inRecord*)pcommon;
|
||||
struct int64indset *pdset = (struct int64indset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
int64indset *pdset = (int64indset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_int64in==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_int64in");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
if( (pdset==NULL) || (pdset->read_int64in==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_int64in");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) prec->udf = FALSE;
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -239,7 +231,7 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
{
|
||||
int64inRecord *prec=(int64inRecord *)paddr->precord;
|
||||
|
||||
@@ -265,7 +257,7 @@ static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast)
|
||||
SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
|
||||
NO_ALARM, HIGH_ALARM, HIHI_ALARM
|
||||
};
|
||||
|
||||
|
||||
double aftc, afvl;
|
||||
epicsInt64 val, hyst, lalm;
|
||||
epicsInt64 alev;
|
||||
@@ -397,7 +389,7 @@ static void monitor(int64inRecord *prec)
|
||||
|
||||
static long readValue(int64inRecord *prec)
|
||||
{
|
||||
struct int64indset *pdset = (struct int64indset *) prec->dset;
|
||||
int64indset *pdset = (int64indset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -43,10 +43,7 @@ that comes with Base.
|
||||
The INP link field contains a database or channel access link or provides
|
||||
hardware address information that the device support uses to determine where the
|
||||
input data should come from.
|
||||
The format for the INP field value depends on the device support layer that is
|
||||
selected by the DTYP field.
|
||||
See L<Address Specification|...> for a description of the various hardware
|
||||
address formats supported.
|
||||
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
@@ -111,6 +108,15 @@ monitoring deadband functionality.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct int64inRecord;
|
||||
%typedef struct int64indset {
|
||||
% dset common;
|
||||
% long (*read_int64in)(struct int64inRecord *prec);
|
||||
%} int64indset;
|
||||
%#define HAS_int64indset
|
||||
%
|
||||
field(VAL,DBF_INT64) {
|
||||
prompt("Current value")
|
||||
promptgroup("40 - Input")
|
||||
@@ -238,29 +244,20 @@ monitoring deadband functionality.
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The record provides several fields to support simulation of absent hardware.
|
||||
If the SIML field is set it is used to read a value into the SIMM field, which
|
||||
controls whether simulation is used or not:
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
=over
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is fetched through SIOL (buffered in SVAL).
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
=item *
|
||||
SIMM must be zero (C<NO>) for the record to request a value from the device
|
||||
support.
|
||||
See L<Input Simulation Fields|dbCommonInput/Input Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=item *
|
||||
If SIMM is C<YES> and the SIOL link field is set, a simulated value in
|
||||
engineering units is read using the link into the SVAL field, from where it will
|
||||
subsequently be copied into the VAL field.
|
||||
|
||||
=back
|
||||
|
||||
The SIMS field can be set to give the record an alarm severity while it is in
|
||||
simulation mode.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
@@ -375,14 +372,30 @@ If PACT is FALSE, read the value, honoring simulation mode:
|
||||
=item * If SIMM is C<NO>,
|
||||
call the device support C<read_int64in> routine and return.
|
||||
|
||||
=item * If SIMM is C<YES>,
|
||||
read the simulated value into SVAL using the SIOL link,
|
||||
then copy the value into VAL and set UDF to 0 on success.
|
||||
=item * If SIMM is C<YES>, then
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
Set alarm status to SIMM_ALARM and severity to SIMS,
|
||||
if SIMS is greater than zero.
|
||||
|
||||
=item *
|
||||
|
||||
If the record simulation processing is synchronous (SDLY < 0) or the record is
|
||||
in the second phase of an asynchronous processing, call C<dbGetLink()>
|
||||
to read the input value from SIOL into SVAL.
|
||||
Set status to the return code from C<dbGetLink()>.
|
||||
If the call succeeded, write the value to VAL and set UDF to 0.
|
||||
|
||||
Otherwise (record is in first phase of an asynchronous processing), set up a
|
||||
callback processing with the delay specified in SDLY.
|
||||
|
||||
=back
|
||||
|
||||
=item * Raise an alarm for other values of SIMM.
|
||||
|
||||
=item * Set the record to the severity configured in SIMS.
|
||||
|
||||
=back
|
||||
|
||||
=item 3.
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/*
|
||||
* Original Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -58,36 +58,28 @@ static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
rset int64outRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,int64outRSET);
|
||||
|
||||
|
||||
struct int64outdset { /* int64out input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_int64out;/*(-1,0)=>(failure,success*/
|
||||
};
|
||||
static void checkAlarms(int64outRecord *prec);
|
||||
static void monitor(int64outRecord *prec);
|
||||
static long writeValue(int64outRecord *prec);
|
||||
@@ -97,28 +89,28 @@ static void convert(int64outRecord *prec, epicsInt64 value);
|
||||
static long init_record(dbCommon *pcommon, int pass)
|
||||
{
|
||||
int64outRecord *prec = (int64outRecord*)pcommon;
|
||||
struct int64outdset *pdset;
|
||||
int64outdset *pdset;
|
||||
long status=0;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
|
||||
recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
|
||||
if(!(pdset = (struct int64outdset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64out: init_record");
|
||||
return(S_dev_noDSET);
|
||||
if(!(pdset = (int64outdset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"int64out: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have write_int64out functions defined */
|
||||
if( (pdset->number < 5) || (pdset->write_int64out == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"int64out: init_record");
|
||||
return(S_dev_missingSup);
|
||||
if ((pdset->common.number < 5) || (pdset->write_int64out == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"int64out: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (prec->dol.type == CONSTANT) {
|
||||
if(recGblInitConstantLink(&prec->dol,DBF_INT64,&prec->val))
|
||||
prec->udf=FALSE;
|
||||
if(recGblInitConstantLink(&prec->dol,DBF_INT64,&prec->val))
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
if( pdset->init_record ) {
|
||||
if((status=(*pdset->init_record)(prec))) return(status);
|
||||
if (pdset->common.init_record) {
|
||||
if ((status = pdset->common.init_record(pcommon))) return status;
|
||||
}
|
||||
prec->mlst = prec->val;
|
||||
prec->alst = prec->val;
|
||||
@@ -129,69 +121,69 @@ static long init_record(dbCommon *pcommon, int pass)
|
||||
static long process(dbCommon *pcommon)
|
||||
{
|
||||
int64outRecord *prec = (int64outRecord*)pcommon;
|
||||
struct int64outdset *pdset = (struct int64outdset *)(prec->dset);
|
||||
long status=0;
|
||||
epicsInt64 value;
|
||||
unsigned char pact=prec->pact;
|
||||
int64outdset *pdset = (int64outdset *)(prec->dset);
|
||||
long status=0;
|
||||
epicsInt64 value;
|
||||
unsigned char pact=prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->write_int64out==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_int64out");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if((prec->dol.type != CONSTANT)
|
||||
if( (pdset==NULL) || (pdset->write_int64out==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_int64out");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if((prec->dol.type != CONSTANT)
|
||||
&& (prec->omsl == menuOmslclosed_loop)) {
|
||||
status = dbGetLink(&(prec->dol),DBR_INT64,
|
||||
&value,0,0);
|
||||
if (prec->dol.type!=CONSTANT && RTN_SUCCESS(status))
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
else {
|
||||
value = prec->val;
|
||||
}
|
||||
if (!status) convert(prec,value);
|
||||
}
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"int64out:process Illegal IVOA field");
|
||||
}
|
||||
status = dbGetLink(&(prec->dol),DBR_INT64,
|
||||
&value,0,0);
|
||||
if (prec->dol.type!=CONSTANT && RTN_SUCCESS(status))
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
else {
|
||||
value = prec->val;
|
||||
}
|
||||
if (!status) convert(prec,value);
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"int64out:process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -229,7 +221,7 @@ static long get_units(DBADDR *paddr,char *units)
|
||||
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
int64outRecord *prec=(int64outRecord *)paddr->precord;
|
||||
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -377,7 +369,7 @@ static void monitor(int64outRecord *prec)
|
||||
|
||||
static long writeValue(int64outRecord *prec)
|
||||
{
|
||||
struct int64outdset *pdset = (struct int64outdset *) prec->dset;
|
||||
int64outdset *pdset = (int64outdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
@@ -418,9 +410,9 @@ static long writeValue(int64outRecord *prec)
|
||||
static void convert(int64outRecord *prec, epicsInt64 value)
|
||||
{
|
||||
/* check drive limits */
|
||||
if(prec->drvh > prec->drvl) {
|
||||
if (value > prec->drvh) value = prec->drvh;
|
||||
else if (value < prec->drvl) value = prec->drvl;
|
||||
}
|
||||
prec->val = value;
|
||||
if(prec->drvh > prec->drvl) {
|
||||
if (value > prec->drvh) value = prec->drvh;
|
||||
else if (value < prec->drvl) value = prec->drvl;
|
||||
}
|
||||
prec->val = value;
|
||||
}
|
||||
|
||||
@@ -74,10 +74,6 @@ that comes with Base.
|
||||
The OUT link field contains a database or channel access link or provides
|
||||
hardware address information that the device support uses to determine where the
|
||||
output data should be sent to.
|
||||
The format for the OUT field value depends on the device support layer that is
|
||||
selected by the DTYP field.
|
||||
See L<Address Specification|...> for a description of the various hardware
|
||||
address formats supported.
|
||||
|
||||
=head3 Operator Display Parameters
|
||||
|
||||
@@ -137,6 +133,15 @@ monitoring deadband functionality.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct int64outRecord;
|
||||
%typedef struct int64outdset {
|
||||
% dset common;
|
||||
% long (*write_int64out)(struct int64outRecord *prec);
|
||||
%} int64outdset;
|
||||
%#define HAS_int64outdset
|
||||
%
|
||||
field(VAL,DBF_INT64) {
|
||||
prompt("Desired Output")
|
||||
promptgroup("50 - Output")
|
||||
@@ -279,28 +284,20 @@ monitoring deadband functionality.
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
The record provides several fields to support simulation of absent hardware.
|
||||
If the SIML field is set it is used to read a value into the SIMM field,
|
||||
which controls whether simulation is used or not:
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
=over
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is written through SIOL.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
=item *
|
||||
SIMM must be zero (C<NO>) for the record to write a value to the device
|
||||
support.
|
||||
See L<Output Simulation Fields|dbCommonOutput/Output Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=item *
|
||||
If SIMM is C<YES> and the SIOL link field is set, the value in engineering
|
||||
units is written using the link.
|
||||
|
||||
=back
|
||||
|
||||
The SIMS field can be set to give the record an alarm severity while it is in
|
||||
simulation mode.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
@@ -462,7 +459,7 @@ by at least HYST between level alarm status and severity changes.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check severity and write the new value. See L<Invalid Alarm Output Action>
|
||||
Check severity and write the new value. See L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields>
|
||||
for details on how invalid alarms affect output records.
|
||||
|
||||
=item 5.
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recLongin.c - Record Support Routines for Longin records */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
* Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -59,39 +59,30 @@ static long get_units(DBADDR *, char *);
|
||||
#define put_enum_str NULL
|
||||
static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
|
||||
static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
rset longinRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,longinRSET);
|
||||
|
||||
|
||||
struct longindset { /* longin input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_longin; /*returns: (-1,0)=>(failure,success)*/
|
||||
};
|
||||
static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast);
|
||||
static void monitor(longinRecord *prec);
|
||||
static long readValue(longinRecord *prec);
|
||||
@@ -100,7 +91,7 @@ static long readValue(longinRecord *prec);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct longinRecord *prec = (struct longinRecord *)pcommon;
|
||||
struct longindset *pdset = (struct longindset *) prec->dset;
|
||||
longindset *pdset = (longindset *) prec->dset;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
|
||||
@@ -113,13 +104,13 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
/* must have read_longin function defined */
|
||||
if ((pdset->number < 5) || (pdset->read_longin == NULL)) {
|
||||
if ((pdset->common.number < 5) || (pdset->read_longin == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "longin: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
if (pdset->init_record) {
|
||||
long status = pdset->init_record(prec);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -134,36 +125,36 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct longinRecord *prec = (struct longinRecord *)pcommon;
|
||||
struct longindset *pdset = (struct longindset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
longindset *pdset = (longindset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_longin==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_longin");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
if( (pdset==NULL) || (pdset->read_longin==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_longin");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
timeLast = prec->time;
|
||||
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
|
||||
|
||||
if (status==0) prec->udf = FALSE;
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
/* check for alarms */
|
||||
checkAlarms(prec, &timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -245,7 +236,7 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
{
|
||||
longinRecord *prec=(longinRecord *)paddr->precord;
|
||||
|
||||
@@ -262,7 +253,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
|
||||
|
||||
static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast)
|
||||
{
|
||||
enum {
|
||||
enum {
|
||||
range_Lolo = 1,
|
||||
range_Low,
|
||||
range_Normal,
|
||||
@@ -273,7 +264,7 @@ static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast)
|
||||
SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
|
||||
NO_ALARM, HIGH_ALARM, HIHI_ALARM
|
||||
};
|
||||
|
||||
|
||||
double aftc, afvl;
|
||||
epicsInt32 val, hyst, lalm;
|
||||
epicsInt32 alev;
|
||||
@@ -405,7 +396,7 @@ static void monitor(longinRecord *prec)
|
||||
|
||||
static long readValue(longinRecord *prec)
|
||||
{
|
||||
struct longindset *pdset = (struct longindset *) prec->dset;
|
||||
longindset *pdset = (longindset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
@@ -28,10 +28,8 @@ The record-specific fields are described below, grouped by functionality.
|
||||
=head3 Scan Parameters
|
||||
|
||||
The long input record has the standard fields for specifying under what
|
||||
circumstances the record will be processed. These fields are listed in L<Scan
|
||||
Fields>. In addition, L<Scanning Specification> explains how these fields are
|
||||
used. Note that I/O event scanning is only supported for those card types
|
||||
that interrupt.
|
||||
circumstances the record will be processed.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Read Parameters
|
||||
|
||||
@@ -43,9 +41,7 @@ I/O bus used.
|
||||
|
||||
For soft records, the INP can be a constant, a database link, or a channel
|
||||
access link. The value is read directly into VAL. The C<<< Soft Channel >>>
|
||||
device support module is available for longin records. See L<Address
|
||||
Specification> for information on the format of hardware addresses and a
|
||||
database links.
|
||||
device support module is available for longin records.
|
||||
|
||||
=fields VAL, INP, DTYP
|
||||
|
||||
@@ -62,8 +58,9 @@ The HOPR and LOPR fields set the upper and lower display limits for the VAL,
|
||||
HIHI, HIGH, LOW, and LOLO fields. Both the C<<< get_graphic_double >>> and C<<<
|
||||
get_control_double >>> record support routines retrieve these fields.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME) and
|
||||
description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
|
||||
=fields EGU, HOPR, LOPR, NAME, DESC
|
||||
|
||||
@@ -76,10 +73,9 @@ routines.
|
||||
The limit alarms are configured by the user in the HIHI, LOLO, HIGH, and LOW
|
||||
fields using numerical values. For each of these fields, there is a
|
||||
corresponding severity field which can be either NO_ALARM, MINOR, or MAJOR. The
|
||||
HYST field can be used to specify a deadband around each limit. See L<Alarm
|
||||
Specification> for a complete explanation of alarms and these fields. L<Alarm
|
||||
Fields> lists other fields related to a alarms that are common to all record
|
||||
types.
|
||||
HYST field can be used to specify a deadband around each limit.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists the fields related to
|
||||
alarms that are common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST
|
||||
|
||||
@@ -91,24 +87,34 @@ field (see the next section) by the appropriate deadband. If these fields have a
|
||||
value of zero, everytime the value changes, a monitor will be triggered; if they
|
||||
have a value of -1, everytime the record is scanned, monitors are triggered. The
|
||||
ADEL field is used by archive monitors and the MDEL field for all other types of
|
||||
monitors. See L<Monitor Specification> for a complete explanation of monitors.
|
||||
monitors.
|
||||
|
||||
=fields ADEL, MDEL
|
||||
|
||||
=head3 Run-time and Simulation Mode Parameters
|
||||
=head3 Run-time Parameters
|
||||
|
||||
The LALM, MLST, and ALST fields are used to implement the hysteresis factors for
|
||||
monitor callbacks. Only if the difference between these fields and the
|
||||
corresponding value field is greater than the appropriate delta (MDEL, ADEL,
|
||||
HYST)--only then are monitors triggered. For instance, only if the difference
|
||||
HYST) will monitors be triggered. For instance, only if the difference
|
||||
between VAL and MLST is greater than MDEL are the monitors triggered for VAL.
|
||||
|
||||
=fields LALM, ALST, MLST
|
||||
|
||||
The following fields are used to operate the long input in the simulation mode.
|
||||
See L<Fields Common to Many Record Types> for more information on these fields.
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
=fields SIOL, SVAL, SIML, SIMM, SIMS
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is fetched through SIOL (buffered in SVAL).
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Input Simulation Fields|dbCommonInput/Input Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SVAL, SIMS, SDLY, SSCN
|
||||
|
||||
=head2 Record Support
|
||||
|
||||
@@ -265,7 +271,7 @@ C<init_record()> routine.
|
||||
get_ioint_info(int cmd,struct dbCommon *precord,IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. cmd has the value (0,1) if the
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the
|
||||
record is being (added to, deleted from) an I/O event list. It must be
|
||||
provided for any device type that can use the ioEvent scanner.
|
||||
|
||||
@@ -305,6 +311,15 @@ sets UDF to FALSE. read_longin returns the status of C<recGblGetLinkValue>.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct longinRecord;
|
||||
%typedef struct longindset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*read_longin)(struct longinRecord *prec); /*returns: (-1,0)=>(failure,success)*/
|
||||
%} longindset;
|
||||
%#define HAS_longindset
|
||||
%
|
||||
field(VAL,DBF_LONG) {
|
||||
prompt("Current value")
|
||||
promptgroup("40 - Input")
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
* Author: Janet Anderson
|
||||
* Date: 9/23/91
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -59,36 +59,27 @@ static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
|
||||
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
rset longoutRSET={
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
RSETNUMBER,
|
||||
report,
|
||||
initialize,
|
||||
init_record,
|
||||
process,
|
||||
special,
|
||||
get_value,
|
||||
cvt_dbaddr,
|
||||
get_array_info,
|
||||
put_array_info,
|
||||
get_units,
|
||||
get_precision,
|
||||
get_enum_str,
|
||||
get_enum_strs,
|
||||
put_enum_str,
|
||||
get_graphic_double,
|
||||
get_control_double,
|
||||
get_alarm_double
|
||||
};
|
||||
epicsExportAddress(rset,longoutRSET);
|
||||
|
||||
|
||||
struct longoutdset { /* longout input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_longout;/*(-1,0)=>(failure,success*/
|
||||
};
|
||||
static void checkAlarms(longoutRecord *prec);
|
||||
static void monitor(longoutRecord *prec);
|
||||
static long writeValue(longoutRecord *prec);
|
||||
@@ -97,7 +88,7 @@ static void convert(longoutRecord *prec, epicsInt32 value);
|
||||
static long init_record(struct dbCommon *pcommon, int pass)
|
||||
{
|
||||
struct longoutRecord *prec = (struct longoutRecord *)pcommon;
|
||||
struct longoutdset *pdset = (struct longoutdset *) prec->dset;
|
||||
longoutdset *pdset = (longoutdset *) prec->dset;
|
||||
|
||||
if (pass == 0) return 0;
|
||||
|
||||
@@ -109,7 +100,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
/* must have write_longout functions defined */
|
||||
if ((pdset->number < 5) || (pdset->write_longout == NULL)) {
|
||||
if ((pdset->common.number < 5) || (pdset->write_longout == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "longout: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
@@ -117,8 +108,8 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_LONG, &prec->val))
|
||||
prec->udf=FALSE;
|
||||
|
||||
if (pdset->init_record) {
|
||||
long status = pdset->init_record(prec);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -133,68 +124,68 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
static long process(struct dbCommon *pcommon)
|
||||
{
|
||||
struct longoutRecord *prec = (struct longoutRecord *)pcommon;
|
||||
struct longoutdset *pdset = (struct longoutdset *)(prec->dset);
|
||||
long status=0;
|
||||
epicsInt32 value;
|
||||
unsigned char pact=prec->pact;
|
||||
longoutdset *pdset = (longoutdset *)(prec->dset);
|
||||
long status=0;
|
||||
epicsInt32 value;
|
||||
unsigned char pact=prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->write_longout==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_longout");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
status = dbGetLink(&prec->dol, DBR_LONG, &value, 0, 0);
|
||||
if (!dbLinkIsConstant(&prec->dol) && !status)
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
else {
|
||||
value = prec->val;
|
||||
}
|
||||
if (!status) convert(prec,value);
|
||||
}
|
||||
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"longout:process Illegal IVOA field");
|
||||
}
|
||||
if( (pdset==NULL) || (pdset->write_longout==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_longout");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (!prec->pact) {
|
||||
if (!dbLinkIsConstant(&prec->dol) &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
status = dbGetLink(&prec->dol, DBR_LONG, &value, 0, 0);
|
||||
if (!dbLinkIsConstant(&prec->dol) && !status)
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
else {
|
||||
value = prec->val;
|
||||
}
|
||||
if (!status) convert(prec,value);
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
|
||||
if (prec->nsev < INVALID_ALARM )
|
||||
status=writeValue(prec); /* write the new value */
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case (menuIvoaContinue_normally) :
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
case (menuIvoaDon_t_drive_outputs) :
|
||||
break;
|
||||
case (menuIvoaSet_output_to_IVOV) :
|
||||
if(prec->pact == FALSE){
|
||||
prec->val=prec->ivov;
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"longout:process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStampSimm(prec, prec->simm, NULL);
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
@@ -232,7 +223,7 @@ static long get_units(DBADDR *paddr,char *units)
|
||||
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
|
||||
{
|
||||
longoutRecord *prec=(longoutRecord *)paddr->precord;
|
||||
|
||||
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
case indexof(HIHI):
|
||||
@@ -382,7 +373,7 @@ static void monitor(longoutRecord *prec)
|
||||
|
||||
static long writeValue(longoutRecord *prec)
|
||||
{
|
||||
struct longoutdset *pdset = (struct longoutdset *) prec->dset;
|
||||
longoutdset *pdset = (longoutdset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
@@ -423,9 +414,9 @@ static long writeValue(longoutRecord *prec)
|
||||
static void convert(longoutRecord *prec, epicsInt32 value)
|
||||
{
|
||||
/* check drive limits */
|
||||
if(prec->drvh > prec->drvl) {
|
||||
if (value > prec->drvh) value = prec->drvh;
|
||||
else if (value < prec->drvl) value = prec->drvl;
|
||||
}
|
||||
prec->val = value;
|
||||
if(prec->drvh > prec->drvl) {
|
||||
if (value > prec->drvh) value = prec->drvh;
|
||||
else if (value < prec->drvl) value = prec->drvl;
|
||||
}
|
||||
prec->val = value;
|
||||
}
|
||||
|
||||
@@ -24,33 +24,13 @@ recordtype(longout) {
|
||||
|
||||
=head2 Parameter Fields
|
||||
|
||||
The fields in this record fall into the following categories:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<Scan Parameters>
|
||||
|
||||
=item * L<Desired Output Parameters>
|
||||
|
||||
=item * L<Write Parameters>
|
||||
|
||||
=item * L<Operator Display Parameters>
|
||||
|
||||
=item * L<Alarm Parameters>
|
||||
|
||||
=item * L<Monitor Parameters>
|
||||
|
||||
=item * L<Simulation Mode Parameters>
|
||||
|
||||
=back
|
||||
The record-specific fields are described below, grouped by functionality.
|
||||
|
||||
=head3 Scan Parameters
|
||||
|
||||
The longout record has the standard fields for specifying under what
|
||||
circumstances it will be processed. These fields are listed in L<Scan Fields>.
|
||||
In addition, L<Scanning Specification> explains how these fields are used. Note
|
||||
that I/O event scanning is only supported for those card types that
|
||||
interrupt.
|
||||
circumstances it will be processed.
|
||||
These fields are listed in L<Scan Fields|dbCommonRecord/Scan Fields>.
|
||||
|
||||
=head3 Desired Output Parameters
|
||||
|
||||
@@ -96,6 +76,15 @@ and database links.
|
||||
=cut
|
||||
|
||||
include "dbCommon.dbd"
|
||||
%
|
||||
%/* Declare Device Support Entry Table */
|
||||
%struct longoutRecord;
|
||||
%typedef struct longoutdset {
|
||||
% dset common; /*init_record returns: (-1,0)=>(failure,success)*/
|
||||
% long (*write_longout)(struct longoutRecord *prec); /*(-1,0)=>(failure,success*/
|
||||
%} longoutdset;
|
||||
%#define HAS_longoutdset
|
||||
%
|
||||
field(VAL,DBF_LONG) {
|
||||
prompt("Desired Output")
|
||||
promptgroup("50 - Output")
|
||||
@@ -132,8 +121,8 @@ The HOPR and LOPR fields set the upper and lower display limits for the VAL,
|
||||
HIHI, HIGH, LOW, and LOLO fields. Both the C<<< get_graphic_double >>> and C<<<
|
||||
get_control_double >>> record support routines retrieve these fields.
|
||||
|
||||
See L<Fields Common to All Record Types> for more on the record name (NAME) and
|
||||
description (DESC) fields.
|
||||
See L<Fields Common to All Record Types|dbCommonRecord/Operator Display
|
||||
Parameters> for more on the record name (NAME) and description (DESC) fields.
|
||||
|
||||
=fields EGU, HOPR, LOPR, NAME, DESC
|
||||
|
||||
@@ -186,10 +175,10 @@ fields using floating-point values. For each of these fields, there is a
|
||||
corresponding severity field which can be either NO_ALARM, MINOR, or MAJOR. The
|
||||
HYST field contains the alarm deadband around each limit alarm.
|
||||
|
||||
See the See L<Alarm Specification> for a complete explanation of alarms and
|
||||
See L<Alarm Specification> for a complete explanation of alarms and
|
||||
these fields. For an explanation of the IVOA and IVOV fields, see L<Output
|
||||
Records>. L<Alarm Fields> lists other fields related to a alarms that are common
|
||||
to all record types.
|
||||
Records>. L<Alarm Fields|dbCommonRecord/Alarm Fields> lists the fields related to
|
||||
alarms that are common to all record types.
|
||||
|
||||
=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, IVOA, IVOV
|
||||
|
||||
@@ -298,7 +287,7 @@ monitors.
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Run-time and Simulation Mode Parameters
|
||||
=head3 Run-time Parameters
|
||||
|
||||
The LALM, MLST, and ALST fields are used to implement the hysteresis factors for
|
||||
monitor callbacks. Only if the difference between these fields and the
|
||||
@@ -308,15 +297,24 @@ between VAL and MLST is greater than MDEL are the monitors triggered for VAL.
|
||||
|
||||
=fields LALM, ALST, MLST
|
||||
|
||||
The following fields are used to operate the long output in the simulation mode.
|
||||
See L<Fields Common to Many Record Types> for more information on the simulation
|
||||
mode fields
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
=fields SIOL, SIML, SIMM, SIMS
|
||||
The following fields are used to operate the record in simulation mode.
|
||||
|
||||
If SIMM (fetched through SIML) is YES, the record is put in SIMS
|
||||
severity and the value is written through SIOL.
|
||||
SSCN sets a different SCAN mechanism to use in simulation mode.
|
||||
SDLY sets a delay (in sec) that is used for asynchronous simulation
|
||||
processing.
|
||||
|
||||
See L<Output Simulation Fields|dbCommonOutput/Output Simulation Fields>
|
||||
for more information on simulation mode and its fields.
|
||||
|
||||
=fields SIML, SIMM, SIOL, SIMS, SDLY, SSCN
|
||||
|
||||
=cut
|
||||
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
field(SIOL,DBF_OUTLINK) {
|
||||
prompt("Sim Output Specifctn")
|
||||
promptgroup("90 - Simulate")
|
||||
interest(1)
|
||||
@@ -464,7 +462,8 @@ before the alarm status and severity is lowered.
|
||||
|
||||
=item 4.
|
||||
|
||||
Check severity and write the new value. See L<Invalid Alarm Output Action> for
|
||||
Check severity and write the new value. See
|
||||
L<Invalid Output Action Fields|dbCommonOutput/Invalid Output Action Fields> for
|
||||
information on how INVALID alarms affect output records.
|
||||
|
||||
=item 5.
|
||||
@@ -551,7 +550,7 @@ C<init_record()> routine.
|
||||
get_ioint_info(int cmd,struct dbCommon *precord,IOSCANPVT *ppvt)
|
||||
|
||||
This routine is called by the ioEventScan system each time the record is added
|
||||
or deleted from an I/O event scan list. cmd has the value (0,1) if the
|
||||
or deleted from an I/O event scan list. C<cmd> has the value (0,1) if the
|
||||
record is being (added to, deleted from) an I/O event list. It must be
|
||||
provided for any device type that can use the ioEvent scanner.
|
||||
|
||||
|
||||
@@ -66,13 +66,13 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
/* must have a read_string function */
|
||||
if (pdset->number < 5 || !pdset->read_string) {
|
||||
if (pdset->common.number < 5 || !pdset->read_string) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "lsi: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
if (pdset->init_record) {
|
||||
long status = pdset->init_record(prec);
|
||||
if (pdset->common.init_record) {
|
||||
long status = pdset->common.init_record(pcommon);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
@@ -221,7 +221,7 @@ static void monitor(lsiRecord *prec)
|
||||
|
||||
static long readValue(lsiRecord *prec)
|
||||
{
|
||||
struct lsidset *pdset = (struct lsidset *) prec->dset;
|
||||
lsidset *pdset = (lsidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user