From 02b90344570c0bd1926080e3b68a61955f15bc6b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 30 Dec 2009 00:06:19 -0600 Subject: [PATCH] Added async soft channel support for mbbiDirect records --- src/std/dev/Makefile | 1 + src/std/dev/devMbbiDirectSoftCallback.c | 155 ++++++++++++++++++++++++ src/std/dev/devSoft.dbd | 1 + 3 files changed, 157 insertions(+) create mode 100644 src/std/dev/devMbbiDirectSoftCallback.c diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile index 0e3fac9e2..3d291e05a 100644 --- a/src/std/dev/Makefile +++ b/src/std/dev/Makefile @@ -45,6 +45,7 @@ dbRecStd_SRCS += devGeneralTime.c dbRecStd_SRCS += devAiSoftCallback.c dbRecStd_SRCS += devBiSoftCallback.c dbRecStd_SRCS += devLiSoftCallback.c +dbRecStd_SRCS += devMbbiDirectSoftCallback.c dbRecStd_SRCS += devMbbiSoftCallback.c dbRecStd_SRCS += devSiSoftCallback.c diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c new file mode 100644 index 000000000..e56ef6e16 --- /dev/null +++ b/src/std/dev/devMbbiDirectSoftCallback.c @@ -0,0 +1,155 @@ +/*************************************************************************\ +* Copyright (c) 2009 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. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* devMbbiDirectSoftCallback.c */ +/* + * Author: Marty Kraimer + * Date: 23APR2008 + */ + +#include +#include +#include + +#include "alarm.h" +#include "callback.h" +#include "cantProceed.h" +#include "dbDefs.h" +#include "dbAccess.h" +#include "dbNotify.h" +#include "recGbl.h" +#include "recSup.h" +#include "devSup.h" +#include "link.h" +#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; +} notifyInfo; + +static void getCallback(processNotify *ppn, notifyGetType type) +{ + struct mbbiDirectRecord *prec = (struct 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"); + return; + } + switch (type) { + case getFieldType: + 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); + break; + } + pnotifyInfo->status = status; +} + +static void doneCallback(processNotify *ppn) +{ + struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)ppn->usrPvt; + notifyInfo *pnotifyInfo = (notifyInfo *)prec->dpvt; + + callbackRequestProcessCallback(pnotifyInfo->pcallback,prec->prio,prec); +} + + +static long init_record(struct mbbiDirectRecord *prec) +{ + DBLINK *plink = &prec->inp; + struct instio *pinstio; + char *pvname; + DBADDR *pdbaddr=NULL; + long status; + notifyInfo *pnotifyInfo; + CALLBACK *pcallback; + processNotify *ppn=NULL; + + if (plink->type!=INST_IO) { + recGblRecordError(S_db_badField,(void *)prec, + "devMbbiDirectSoftCallback (init_record) Illegal INP field"); + prec->pact=TRUE; + return S_db_badField; + } + pinstio=(struct instio*)&(plink->value); + pvname = pinstio->string; + pdbaddr = callocMustSucceed(1, sizeof(*pdbaddr), + "devMbbiDirectSoftCallback::init_record"); + status = dbNameToAddr(pvname,pdbaddr); + if (status) { + recGblRecordError(status,(void *)prec, + "devMbbiDirectSoftCallback (init_record) linked record not found"); + prec->pact=TRUE; + return status; + } + pnotifyInfo = callocMustSucceed(1, sizeof(*pnotifyInfo), + "devMbbiDirectSoftCallback::init_record"); + pcallback = callocMustSucceed(1, sizeof(*pcallback), + "devMbbiDirectSoftCallback::init_record"); + ppn = callocMustSucceed(1, sizeof(*ppn), + "devMbbiDirectSoftCallback::init_record"); + pnotifyInfo->ppn = ppn; + pnotifyInfo->pcallback = pcallback; + ppn->usrPvt = prec; + ppn->paddr = pdbaddr; + ppn->getCallback = getCallback; + ppn->doneCallback = doneCallback; + ppn->requestType = processGetRequest; + prec->dpvt = pnotifyInfo; + 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; + return 2; + } + dbProcessNotify(pnotifyInfo->ppn); + prec->pact = TRUE; + return 0; +} diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd index 860a0a500..f6a93241d 100644 --- a/src/std/dev/devSoft.dbd +++ b/src/std/dev/devSoft.dbd @@ -30,6 +30,7 @@ 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")