Convert INST_IO links to regular PV_LINK types, for VDCT support.
Added new PN_LINK type in link.h, make dbStaticLib display it. Made all device support extended so links can be changed at runtime. Modified startup so add_record() always called before regular link processing. Incomplete, stilll need to add MS/MSS/MSI support, currently disabled.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,17 +8,20 @@
|
||||
\*************************************************************************/
|
||||
/* devAiSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
/* TODO:
|
||||
* Support MS/MSS/MSI link flags
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +32,35 @@
|
||||
#include "aiRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devAiSoftCallback */
|
||||
static long init_record();
|
||||
static long read_ai();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devAiSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_ai,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devAiSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
double value;
|
||||
int status;
|
||||
}notifyInfo;
|
||||
int status;
|
||||
int smooth;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt;
|
||||
aiRecord *prec = (aiRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if(ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status == notifyCanceled) {
|
||||
printf("devAiSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
switch(type) {
|
||||
|
||||
switch (type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_DOUBLE,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr, DBR_DOUBLE, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +68,152 @@ static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct aiRecord *prec = (struct aiRecord *)ppn->usrPvt;
|
||||
aiRecord *prec = (aiRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct aiRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if(plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devAiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
return(S_db_badField);
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devAiSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devAiSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
if(status) {
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devAiSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
return(status);
|
||||
"devAiSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devAiSoftCallback (add_record) link target not found");
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devAiSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devAiSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devAiSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devAiSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devAiSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devAiSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
aiRecord *prec = (aiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(aiRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devAiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_ai(aiRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if(prec->pact) {
|
||||
if(pnotifyInfo->status) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
return(2);
|
||||
if (!prec->dpvt)
|
||||
return 2;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
pnotifyInfo->smooth = FALSE;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Apply smoothing algorithm */
|
||||
if (prec->smoo != 0.0 && pnotifyInfo->smooth)
|
||||
prec->val = pnotifyInfo->value * (1.0 - prec->smoo) + prec->val * prec->smoo;
|
||||
else
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
pnotifyInfo->smooth = TRUE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Create the dset for devAiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_ai;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devAiSoftCallback = {
|
||||
{6, NULL, init, init_record, NULL},
|
||||
read_ai,
|
||||
NULL
|
||||
};
|
||||
epicsExportAddress(dset, devAiSoftCallback);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,17 +8,16 @@
|
||||
\*************************************************************************/
|
||||
/* devBiSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +28,34 @@
|
||||
#include "biRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devBiSoftCallback */
|
||||
static long init_record();
|
||||
static long read_bi();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_bi;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devBiSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_bi,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devBiSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
unsigned short value;
|
||||
int status;
|
||||
}notifyInfo;
|
||||
epicsEnum16 value;
|
||||
int status;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
{
|
||||
struct biRecord *prec = (struct biRecord *)ppn->usrPvt;
|
||||
biRecord *prec = (biRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if(ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status == notifyCanceled) {
|
||||
printf("devBiSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
switch(type) {
|
||||
|
||||
switch (type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct biRecord *prec = (struct biRecord *)ppn->usrPvt;
|
||||
biRecord *prec = (biRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct biRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
biRecord *prec = (biRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if(plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devBiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
return(S_db_badField);
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devBiSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devBiSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
if(status) {
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devBiSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
return(status);
|
||||
"devBiSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devBiSoftCallback (add_record) link target not found");
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devBiSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devBiSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devBiSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devBiSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devBiSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devBiSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
biRecord *prec = (biRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(biRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devBiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_bi(biRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if(prec->pact) {
|
||||
if(pnotifyInfo->status) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
return(2);
|
||||
if (!prec->dpvt)
|
||||
return 2;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return 2;
|
||||
}
|
||||
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Create the dset for devBiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_bi;
|
||||
} devBiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_bi
|
||||
};
|
||||
epicsExportAddress(dset, devBiSoftCallback);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,17 +8,16 @@
|
||||
\*************************************************************************/
|
||||
/* devLiSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +28,34 @@
|
||||
#include "longinRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devLiSoftCallback */
|
||||
static long init_record();
|
||||
static long read_li();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_li;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devLiSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_li,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devLiSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
long value;
|
||||
int status;
|
||||
}notifyInfo;
|
||||
epicsInt32 value;
|
||||
int status;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt;
|
||||
longinRecord *prec = (longinRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if(ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status == notifyCanceled) {
|
||||
printf("devLiSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
switch(type) {
|
||||
|
||||
switch (type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_LONG,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_LONG, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_LONG,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr, DBR_LONG, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct longinRecord *prec = (struct longinRecord *)ppn->usrPvt;
|
||||
longinRecord *prec = (longinRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct longinRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
longinRecord *prec = (longinRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if(plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devLiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
return(S_db_badField);
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devLiSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devLiSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
if(status) {
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devLiSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devLiSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devLiSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devLiSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devLiSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devLiSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devLiSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devLiSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
longinRecord *prec = (longinRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(longinRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_LONG, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devLiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_li(longinRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if(prec->pact) {
|
||||
if(pnotifyInfo->status) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(pnotifyInfo->status);
|
||||
}
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
return(0);
|
||||
if (!prec->dpvt)
|
||||
return 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return pnotifyInfo->status;
|
||||
}
|
||||
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devLiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_li;
|
||||
} devLiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_li
|
||||
};
|
||||
epicsExportAddress(dset, devLiSoftCallback);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,17 +8,16 @@
|
||||
\*************************************************************************/
|
||||
/* devMbbiDirectSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +28,34 @@
|
||||
#include "mbbiDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiDirectSoftCallback */
|
||||
static long init_record();
|
||||
static long read_mbbiDirect();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbiDirect;
|
||||
DEVSUPFUN special_linconv;
|
||||
} devMbbiDirectSoftCallback = {
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_mbbiDirect,
|
||||
NULL};
|
||||
epicsExportAddress(dset, devMbbiDirectSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
unsigned short value;
|
||||
int status;
|
||||
epicsUInt16 value;
|
||||
int status;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt;
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if (ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status == notifyCanceled) {
|
||||
printf("devMbbiDirectSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_USHORT, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr, DBR_USHORT, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt;
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct mbbiDirectRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
long status;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if (plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devMbbiDirectSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devMbbiDirectSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devMbbiDirectSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
"devMbbiDirectSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devMbbiDirectSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
"devMbbiDirectSoftCallback (add_record) linked record not found");
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devMbbiDirectSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devMbbiDirectSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devMbbiDirectSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devMbbiDirectSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devMbbiDirectSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devMbbiDirectSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devMbbiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_mbbiDirect(mbbiDirectRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (prec->pact) {
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return 2;
|
||||
}
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
if (!prec->dpvt)
|
||||
return 2;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return 2;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbbiDirectSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_mbbiDirect;
|
||||
} devMbbiDirectSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_mbbiDirect
|
||||
};
|
||||
epicsExportAddress(dset, devMbbiDirectSoftCallback);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,17 +8,16 @@
|
||||
\*************************************************************************/
|
||||
/* devMbbiSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +28,34 @@
|
||||
#include "mbbiRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbbiSoftCallback */
|
||||
static long init_record();
|
||||
static long read_mbbi();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devMbbiSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_mbbi,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devMbbiSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
unsigned short value;
|
||||
int status;
|
||||
}notifyInfo;
|
||||
epicsEnum16 value;
|
||||
int status;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt;
|
||||
mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if(ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status == notifyCanceled) {
|
||||
printf("devMbbiSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
switch(type) {
|
||||
|
||||
switch (type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_ENUM, &pnotifyInfo->value,
|
||||
&options, &no_elements,0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_USHORT,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr,DBR_ENUM, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +63,144 @@ static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct mbbiRecord *prec = (struct mbbiRecord *)ppn->usrPvt;
|
||||
mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct mbbiRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
mbbiRecord *prec = (mbbiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
long status;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if(plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devMbbiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
return(S_db_badField);
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devMbbiSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devMbbiSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
if(status) {
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devMbbiSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
return(status);
|
||||
"devMbbiSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devMbbiSoftCallback (add_record) linked record not found");
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devMbbiSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devMbbiSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devMbbiSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devMbbiSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devMbbiSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devMbbiSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
mbbiRecord *prec = (mbbiRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(mbbiRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devMbbiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_mbbi(mbbiRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if(prec->pact) {
|
||||
if(pnotifyInfo->status) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(2);
|
||||
}
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
return(2);
|
||||
if (!prec->dpvt)
|
||||
return 2;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return 2;
|
||||
}
|
||||
|
||||
prec->val = pnotifyInfo->value;
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbbiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_mbbi;
|
||||
} devMbbiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_mbbi
|
||||
};
|
||||
epicsExportAddress(dset,devMbbiSoftCallback);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
@@ -8,8 +8,7 @@
|
||||
\*************************************************************************/
|
||||
/* devSiSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 23APR2008
|
||||
* Authors: Marty Kraimer & Andrew Johnson
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -19,6 +18,7 @@
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "cantProceed.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbNotify.h"
|
||||
@@ -29,54 +29,34 @@
|
||||
#include "stringinRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devSiSoftCallback */
|
||||
static long init_record();
|
||||
static long read_stringin();
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_stringin;
|
||||
DEVSUPFUN special_linconv;
|
||||
}devSiSoftCallback={
|
||||
6,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
read_stringin,
|
||||
NULL};
|
||||
epicsExportAddress(dset,devSiSoftCallback);
|
||||
|
||||
typedef struct notifyInfo {
|
||||
processNotify *ppn;
|
||||
CALLBACK *pcallback;
|
||||
char value[40];
|
||||
int status;
|
||||
}notifyInfo;
|
||||
char value[MAX_STRING_SIZE];
|
||||
int status;
|
||||
} notifyInfo;
|
||||
|
||||
static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
static void getCallback(processNotify *ppn, notifyGetType type)
|
||||
{
|
||||
struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt;
|
||||
stringinRecord *prec = (stringinRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
int status = 0;
|
||||
long no_elements = 1;
|
||||
long options = 0;
|
||||
|
||||
if(ppn->status==notifyCanceled) {
|
||||
printf("dbtpn:getCallback notifyCanceled\n");
|
||||
if (ppn->status==notifyCanceled) {
|
||||
printf("devSiSoftCallback::getCallback notifyCanceled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case getFieldType:
|
||||
status = dbGetField(ppn->paddr,DBR_STRING,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGetField(ppn->paddr, DBR_STRING, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
case getType:
|
||||
status = dbGet(ppn->paddr,DBR_STRING,&pnotifyInfo->value,
|
||||
&options,&no_elements,0);
|
||||
status = dbGet(ppn->paddr, DBR_STRING, &pnotifyInfo->value,
|
||||
&options, &no_elements, 0);
|
||||
break;
|
||||
}
|
||||
pnotifyInfo->status = status;
|
||||
@@ -84,72 +64,144 @@ static void getCallback(processNotify *ppn,notifyGetType type)
|
||||
|
||||
static void doneCallback(processNotify *ppn)
|
||||
{
|
||||
struct stringinRecord *prec = (struct stringinRecord *)ppn->usrPvt;
|
||||
stringinRecord *prec = (stringinRecord *)ppn->usrPvt;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec);
|
||||
callbackRequestProcessCallback(pnotifyInfo->pcallback, prec->prio, prec);
|
||||
}
|
||||
|
||||
|
||||
static long init_record(struct stringinRecord *prec)
|
||||
static long add_record(dbCommon *pcommon)
|
||||
{
|
||||
stringinRecord *prec = (stringinRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
struct instio *pinstio;
|
||||
char *pvname;
|
||||
DBADDR *pdbaddr=NULL;
|
||||
DBADDR *pdbaddr;
|
||||
long status;
|
||||
notifyInfo *pnotifyInfo;
|
||||
CALLBACK *pcallback;
|
||||
processNotify *ppn=NULL;
|
||||
processNotify *ppn;
|
||||
|
||||
if(plink->type!=INST_IO) {
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"devSiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact=TRUE;
|
||||
return(S_db_badField);
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
|
||||
if (plink->type != PV_LINK) {
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devSiSoftCallback (add_record) Illegal INP field");
|
||||
return S_db_badField;
|
||||
}
|
||||
pinstio=(struct instio*)&(plink->value);
|
||||
pvname = pinstio->string;
|
||||
|
||||
pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr),
|
||||
"devSiSoftCallback::init_record");
|
||||
status = dbNameToAddr(pvname,pdbaddr);
|
||||
if(status) {
|
||||
recGblRecordError(status,(void *)prec,
|
||||
"devSiSoftCallback (init_record) linked record not found");
|
||||
prec->pact=TRUE;
|
||||
return(status);
|
||||
"devSiSoftCallback::add_record");
|
||||
status = dbNameToAddr(plink->value.pv_link.pvname, pdbaddr);
|
||||
if (status) {
|
||||
free(pdbaddr);
|
||||
recGblRecordError(status, (void *)prec,
|
||||
"devSiSoftCallback (add_record) linked record not found");
|
||||
return status;
|
||||
}
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devSiSoftCallback::init_record");
|
||||
pcallback = callocMustSucceed(1, sizeof(*pcallback),
|
||||
"devSiSoftCallback::init_record");
|
||||
|
||||
plink->type = PN_LINK;
|
||||
plink->value.pv_link.precord = pcommon;
|
||||
plink->value.pv_link.pvt = pdbaddr;
|
||||
plink->value.pv_link.pvlMask = 0;
|
||||
|
||||
ppn = callocMustSucceed(1, sizeof(*ppn),
|
||||
"devSiSoftCallback::init_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
pnotifyInfo->pcallback = pcallback;
|
||||
"devSiSoftCallback::add_record");
|
||||
ppn->usrPvt = prec;
|
||||
ppn->paddr = pdbaddr;
|
||||
ppn->getCallback = getCallback;
|
||||
ppn->doneCallback = doneCallback;
|
||||
ppn->requestType = processGetRequest;
|
||||
|
||||
pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo),
|
||||
"devSiSoftCallback::add_record");
|
||||
pnotifyInfo->pcallback = callocMustSucceed(1, sizeof(CALLBACK),
|
||||
"devSiSoftCallback::add_record");
|
||||
pnotifyInfo->ppn = ppn;
|
||||
|
||||
prec->dpvt = pnotifyInfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_stringin(stringinRecord *prec)
|
||||
static long del_record(dbCommon *pcommon) {
|
||||
stringinRecord *prec = (stringinRecord *)pcommon;
|
||||
DBLINK *plink = &prec->inp;
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if (plink->type == CONSTANT) return 0;
|
||||
assert (plink->type == PN_LINK);
|
||||
|
||||
dbNotifyCancel(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->ppn);
|
||||
free(pnotifyInfo->pcallback);
|
||||
free(pnotifyInfo);
|
||||
free(plink->value.pv_link.pvt);
|
||||
|
||||
plink->type = PV_LINK;
|
||||
plink->value.pv_link.pvt = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dsxt dsxtSoftCallback = {
|
||||
add_record, del_record
|
||||
};
|
||||
|
||||
static long init(int pass)
|
||||
{
|
||||
if (pass == 0) devExtend(&dsxtSoftCallback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long init_record(stringinRecord *prec)
|
||||
{
|
||||
/* INP must be CONSTANT or PN_LINK */
|
||||
switch (prec->inp.type) {
|
||||
case CONSTANT:
|
||||
if (recGblInitConstantLink(&prec->inp, DBR_STRING, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
case PN_LINK:
|
||||
/* Handled by add_record */
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_db_badField, (void *)prec,
|
||||
"devSiSoftCallback (init_record) Illegal INP field");
|
||||
prec->pact = TRUE;
|
||||
return S_db_badField;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long read_si(stringinRecord *prec)
|
||||
{
|
||||
notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt;
|
||||
|
||||
if(prec->pact) {
|
||||
if(pnotifyInfo->status) {
|
||||
recGblSetSevr(prec,READ_ALARM,INVALID_ALARM);
|
||||
return(pnotifyInfo->status);
|
||||
}
|
||||
strcpy(prec->val,pnotifyInfo->value);
|
||||
prec->udf = FALSE;
|
||||
return(0);
|
||||
if (!prec->dpvt)
|
||||
return 0;
|
||||
|
||||
if (!prec->pact) {
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
dbProcessNotify(pnotifyInfo->ppn);
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
|
||||
if (pnotifyInfo->status) {
|
||||
recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
|
||||
return pnotifyInfo->status;
|
||||
}
|
||||
strncpy(prec->val, pnotifyInfo->value, MAX_STRING_SIZE);
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (prec->tsel.type == CONSTANT &&
|
||||
prec->tse == epicsTimeEventDeviceTime)
|
||||
prec->time = prec->inp.value.pv_link.precord->time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devSiSoftCallback */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN read_li;
|
||||
} devSiSoftCallback = {
|
||||
{5, NULL, init, init_record, NULL},
|
||||
read_si
|
||||
};
|
||||
epicsExportAddress(dset,devSiSoftCallback);
|
||||
|
||||
@@ -27,19 +27,18 @@ device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel")
|
||||
device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel")
|
||||
|
||||
device(ai,INST_IO,devAiSoftCallback,"Async Soft Channel")
|
||||
device(bi,INST_IO,devBiSoftCallback,"Async Soft Channel")
|
||||
device(mbbi,INST_IO,devMbbiSoftCallback,"Async Soft Channel")
|
||||
device(mbbiDirect,INST_IO,devMbbiDirectSoftCallback,"Async Soft Channel")
|
||||
device(longin,INST_IO,devLiSoftCallback,"Async Soft Channel")
|
||||
device(stringin,INST_IO,devSiSoftCallback,"Async Soft Channel")
|
||||
|
||||
device(ai,CONSTANT,devAiSoftCallback,"Async Soft Channel")
|
||||
device(ao,CONSTANT,devAoSoftCallback,"Async Soft Channel")
|
||||
device(bi,CONSTANT,devBiSoftCallback,"Async Soft Channel")
|
||||
device(bo,CONSTANT,devBoSoftCallback,"Async Soft Channel")
|
||||
device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel")
|
||||
device(longin,CONSTANT,devLiSoftCallback,"Async Soft Channel")
|
||||
device(longout,CONSTANT,devLoSoftCallback,"Async Soft Channel")
|
||||
device(mbbi,CONSTANT,devMbbiSoftCallback,"Async Soft Channel")
|
||||
device(mbbiDirect,CONSTANT,devMbbiDirectSoftCallback,"Async Soft Channel")
|
||||
device(mbbo,CONSTANT,devMbboSoftCallback,"Async Soft Channel")
|
||||
device(mbboDirect,CONSTANT,devMbboDirectSoftCallback,"Async Soft Channel")
|
||||
device(stringin,CONSTANT,devSiSoftCallback,"Async Soft Channel")
|
||||
device(stringout,CONSTANT,devSoSoftCallback,"Async Soft Channel")
|
||||
|
||||
device(ai, INST_IO,devTimestampAI,"Soft Timestamp")
|
||||
|
||||
Reference in New Issue
Block a user