rec: mbbiDirect and mbboDirect refactoring
This includes changes to functionality, documented.
This commit is contained in:
@@ -15,6 +15,38 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.</p>
|
||||
<h2 align="center">Changes between 3.15.0.1 and 3.15.0.2</h2>
|
||||
<!-- Insert new items immediately below here ... -->
|
||||
|
||||
<h3>mbboDirect and mbbiDirect records</h3>
|
||||
|
||||
<p>These record types have undergone some significant rework, and will behave
|
||||
slightly differently than they did in their 3.14 versions. The externally
|
||||
visible changes are as follows:</p>
|
||||
|
||||
<h5>mbbiDirect</h5>
|
||||
|
||||
<ul>
|
||||
<li>If the MASK field is set in a database file, it will not be over-written
|
||||
when the record is initialized. This allows non-contiguous masks to be set,
|
||||
although only the device support actually uses the MASK field.</li>
|
||||
<li>If process() finds the UDF field to be set, the record will raise a
|
||||
UDF/INVALID alarm.</li>
|
||||
</ul>
|
||||
|
||||
<h5>mbboDirect</h5>
|
||||
|
||||
<ul>
|
||||
<li>If the MASK field is set in a database file, it will not be over-written
|
||||
when the record is initialized. This allows non-contiguous masks to be set,
|
||||
although only the device support actually uses the MASK field.</li>
|
||||
<li>After the device support's init_record() routine returns during record
|
||||
initialization, if OMSL is <q>supervisory</q> and UDF is clear the fields
|
||||
B0-BF will be set from the current VAL field.</li>
|
||||
<li>When a put to the OMSL field sets it to <q>supervisory</q>, the fields
|
||||
B0-BF will be set from the current VAL field. This did not used to happen,
|
||||
the individual bit fields were previously never modified by the record.
|
||||
Note that this change may require some databases to be modified, if they
|
||||
were designed to take advantage of the previous behavior.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Redirection of the errlog console stream</h3>
|
||||
|
||||
<p>A new routine has been added to the errlog facility which allows the console
|
||||
|
||||
@@ -1,64 +1,36 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2012 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 Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devMbboDirectSoft.c */
|
||||
/* base/src/dev $Revision-Id$ */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Current Author: Matthew Needes
|
||||
* Date: 10-08-93
|
||||
* Original Author: Bob Dalesio
|
||||
* Date: 10-08-93
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "devSup.h"
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbboSoft */
|
||||
static long init_record(mbboDirectRecord *prec);
|
||||
static long write_mbbo(mbboDirectRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboDirectSoft={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboDirectSoft);
|
||||
|
||||
static long init_record(mbboDirectRecord *prec)
|
||||
{
|
||||
long status = 0;
|
||||
|
||||
/* dont convert */
|
||||
status = 2;
|
||||
return status;
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
dbPutLink(&prec->out,DBR_USHORT,&prec->val,1);
|
||||
dbPutLink(&prec->out, DBR_USHORT, &prec->val, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboDirectSoft */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoft = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset, devMbboDirectSoft);
|
||||
|
||||
@@ -1,66 +1,56 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2012 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 Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devMbboDirectSoftCallback.c */
|
||||
/*
|
||||
* Author: Marty Kraimer
|
||||
* Date: 04NOV2003
|
||||
* Original Author: Marty Kraimer
|
||||
* Date: 04NOV2003
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "devSup.h"
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbboSoft */
|
||||
static long write_mbbo(mbboDirectRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboDirectSoftCallback={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboDirectSoftCallback);
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
struct link *plink = &prec->out;
|
||||
long status;
|
||||
|
||||
if(prec->pact) return(0);
|
||||
if(plink->type!=CA_LINK) {
|
||||
status = dbPutLink(plink,DBR_USHORT,&prec->val,1);
|
||||
return(status);
|
||||
if (prec->pact)
|
||||
return 0;
|
||||
|
||||
if (plink->type != CA_LINK) {
|
||||
status = dbPutLink(plink, DBR_USHORT, &prec->val, 1);
|
||||
return status;
|
||||
}
|
||||
status = dbCaPutLinkCallback(plink,DBR_USHORT,&prec->val,1,
|
||||
dbCaCallbackProcess,plink);
|
||||
if(status) {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
|
||||
status = dbCaPutLinkCallback(plink, DBR_USHORT, &prec->val, 1,
|
||||
dbCaCallbackProcess, plink);
|
||||
if (status) {
|
||||
recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
|
||||
return status;
|
||||
}
|
||||
|
||||
prec->pact = TRUE;
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboSoft */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoftCallback = {
|
||||
{5, NULL, NULL, NULL, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset, devMbboDirectSoftCallback);
|
||||
|
||||
@@ -1,70 +1,50 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2012 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 Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devMbboDirectSoftRaw.c */
|
||||
/* base/src/dev $Revision-Id$ */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Current Author: Matthew Needes
|
||||
* Date: 10-08-93
|
||||
* Original Author: Janet Anderson
|
||||
* Date: 10-08-93
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "epicsTypes.h"
|
||||
#include "devSup.h"
|
||||
#include "mbboDirectRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
|
||||
/* Create the dset for devMbboDirectSoftRaw */
|
||||
static long init_record(mbboDirectRecord *prec);
|
||||
static long write_mbbo(mbboDirectRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboDirectSoftRaw={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboDirectSoftRaw);
|
||||
|
||||
static long init_record(mbboDirectRecord *prec)
|
||||
{
|
||||
long status = 0;
|
||||
|
||||
if (prec->out.type != PV_LINK)
|
||||
status = 2;
|
||||
/*to preserve old functionality*/
|
||||
if(prec->nobt == 0) prec->mask = 0xffffffff;
|
||||
if (prec->nobt == 0)
|
||||
prec->mask = 0xffffffff;
|
||||
|
||||
prec->mask <<= prec->shft;
|
||||
return status;
|
||||
} /* end init_record() */
|
||||
|
||||
return 2; /* Don't convert */
|
||||
}
|
||||
|
||||
static long write_mbbo(mbboDirectRecord *prec)
|
||||
{
|
||||
unsigned long data;
|
||||
epicsUInt32 data;
|
||||
|
||||
data = prec->rval & prec->mask;
|
||||
dbPutLink(&prec->out,DBR_LONG, &data,1);
|
||||
dbPutLink(&prec->out, DBR_ULONG, &data, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboDirectSoftRaw */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboDirectSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset, devMbboDirectSoftRaw);
|
||||
|
||||
@@ -1,66 +1,50 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
|
||||
* Copyright (c) 2012 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 Versions 3.13.7
|
||||
* and higher are distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* devMbboSoftRaw.c */
|
||||
/* base/src/dev $Revision-Id$ */
|
||||
/*
|
||||
* Author: Janet Anderson
|
||||
* Date: 3-28-92
|
||||
* Original Author: Janet Anderson
|
||||
* Date: 3-28-92
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dbAccess.h"
|
||||
#include "recGbl.h"
|
||||
#include "recSup.h"
|
||||
#include "epicsTypes.h"
|
||||
#include "devSup.h"
|
||||
#include "mbboRecord.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Create the dset for devMbboSoftRaw */
|
||||
static long init_record(mbboRecord *prec);
|
||||
static long write_mbbo(mbboRecord *prec);
|
||||
struct {
|
||||
long number;
|
||||
DEVSUPFUN report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record;
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo;
|
||||
}devMbboSoftRaw={
|
||||
5,
|
||||
NULL,
|
||||
NULL,
|
||||
init_record,
|
||||
NULL,
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset,devMbboSoftRaw);
|
||||
|
||||
static long init_record(mbboRecord *prec)
|
||||
{
|
||||
/*to preserve old functionality*/
|
||||
if (prec->nobt == 0) prec->mask = 0xffffffff;
|
||||
if (prec->nobt == 0)
|
||||
prec->mask = 0xffffffff;
|
||||
|
||||
prec->mask <<= prec->shft;
|
||||
/*dont convert*/
|
||||
return 2;
|
||||
|
||||
} /* end init_record() */
|
||||
|
||||
return 2; /* Don't convert */
|
||||
}
|
||||
|
||||
static long write_mbbo(mbboRecord *prec)
|
||||
{
|
||||
unsigned long data;
|
||||
epicsUInt32 data;
|
||||
|
||||
data = prec->rval & prec->mask;
|
||||
dbPutLink(&prec->out,DBR_LONG, &data,1);
|
||||
dbPutLink(&prec->out, DBR_ULONG, &data, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create the dset for devMbboSoftRaw */
|
||||
struct {
|
||||
dset common;
|
||||
DEVSUPFUN write;
|
||||
} devMbboSoftRaw = {
|
||||
{5, NULL, NULL, init_record, NULL},
|
||||
write_mbbo
|
||||
};
|
||||
epicsExportAddress(dset, devMbboSoftRaw);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2012 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.
|
||||
@@ -11,9 +11,10 @@
|
||||
|
||||
/* $Revision-Id$ */
|
||||
|
||||
/* recMbbiDirect.c - Record Support routines for mbboDirect records */
|
||||
/* mbbiDirectRecord.c - Record Support routines for mbboDirect records */
|
||||
/*
|
||||
* Original Author: Bob Dalesio and Matthew Needes 10-07-93
|
||||
* Original Authors: Bob Dalesio and Matthew Needes
|
||||
* Date: 10-07-93
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -23,7 +24,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -59,219 +60,203 @@ static long process(mbbiDirectRecord *);
|
||||
#define get_alarm_double NULL
|
||||
|
||||
rset mbbiDirectRSET={
|
||||
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,mbbiDirectRSET);
|
||||
|
||||
struct mbbidset { /* multi bit binary input dset */
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi;/*(0,2)=>(success, success no convert)*/
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (-1,0)=>(failure, success)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN read_mbbi; /*returns: (0,2)=>(success, success no convert)*/
|
||||
};
|
||||
|
||||
static void refresh_bits(mbbiDirectRecord *, unsigned short);
|
||||
static void monitor(mbbiDirectRecord *);
|
||||
static long readValue(mbbiDirectRecord *);
|
||||
|
||||
#define NUM_BITS 16
|
||||
|
||||
/* refreshes all the bit fields based on a hardware value
|
||||
and sends monitors if the bit's value or the record's
|
||||
severity/status have changed */
|
||||
static void refresh_bits(mbbiDirectRecord *prec,
|
||||
unsigned short monitor_mask)
|
||||
{
|
||||
unsigned short i;
|
||||
unsigned short mask = 1;
|
||||
unsigned short momask;
|
||||
unsigned char *bit;
|
||||
|
||||
bit = &(prec->b0);
|
||||
for (i=0; i<NUM_BITS; i++, mask = mask << 1, bit++) {
|
||||
momask = monitor_mask;
|
||||
if (prec->val & mask) {
|
||||
if (*bit == 0) {
|
||||
*bit = 1;
|
||||
momask |= DBE_VALUE | DBE_LOG;
|
||||
}
|
||||
} else {
|
||||
if (*bit != 0) {
|
||||
*bit = 0;
|
||||
momask |= DBE_VALUE | DBE_LOG;
|
||||
}
|
||||
}
|
||||
if (momask)
|
||||
db_post_events(prec,bit,momask);
|
||||
}
|
||||
}
|
||||
#define NUM_BITS 16
|
||||
|
||||
static long init_record(mbbiDirectRecord *prec, int pass)
|
||||
{
|
||||
struct mbbidset *pdset;
|
||||
long status;
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status = 0;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0)
|
||||
return status;
|
||||
|
||||
/* siml must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/
|
||||
if (prec->siml.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "mbbiDirect: init_record");
|
||||
return S_dev_noDSET;
|
||||
}
|
||||
|
||||
/* siol must be a CONSTANT or a PV_LINK or a DB_LINK */
|
||||
if (prec->siol.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval);
|
||||
if ((pdset->number < 5) || (pdset->read_mbbi == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "mbbiDirect: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
if(!(pdset = (struct mbbidset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"mbbiDirect: init_record");
|
||||
return(S_dev_noDSET);
|
||||
}
|
||||
/* must have read_mbbi function defined */
|
||||
if( (pdset->number < 5) || (pdset->read_mbbi == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"mbbiDirect: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
/* initialize mask*/
|
||||
prec->mask = (1 << prec->nobt) - 1;
|
||||
if (prec->siml.type == CONSTANT)
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
|
||||
if( pdset->init_record ) {
|
||||
if((status=(*pdset->init_record)(prec))) return(status);
|
||||
refresh_bits(prec, 0);
|
||||
if (prec->siol.type == CONSTANT)
|
||||
recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
|
||||
|
||||
/* Initialize MASK if the user didn't */
|
||||
if (prec->mask == 0)
|
||||
prec->mask = (1 << prec->nobt) - 1;
|
||||
|
||||
if (pdset->init_record) {
|
||||
status = pdset->init_record(prec);
|
||||
if (status == 0) {
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
/* Initialize B0 - BF from VAL */
|
||||
for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1)
|
||||
*pBn = !! (val & 1);
|
||||
}
|
||||
}
|
||||
|
||||
prec->mlst = prec->val;
|
||||
prec->oraw = prec->rval;
|
||||
return(0);
|
||||
return status;
|
||||
}
|
||||
|
||||
static long process(mbbiDirectRecord *prec)
|
||||
{
|
||||
struct mbbidset *pdset = (struct mbbidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status;
|
||||
int pact = prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_mbbi==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"read_mbbi");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if ((pdset == NULL) || (pdset->read_mbbi == NULL)) {
|
||||
prec->pact = TRUE;
|
||||
recGblRecordError(S_dev_missingSup, prec, "read_mbbi");
|
||||
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);
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
/* Done if device support set PACT */
|
||||
if (!pact && prec->pact)
|
||||
return 0;
|
||||
|
||||
if(status==0) { /* convert the value */
|
||||
epicsUInt32 rval = prec->rval;
|
||||
prec->pact = TRUE;
|
||||
recGblGetTimeStamp(prec);
|
||||
|
||||
if(prec->shft>0) rval >>= prec->shft;
|
||||
prec->val = (unsigned short)rval;
|
||||
prec->udf=FALSE;
|
||||
if (status == 0) {
|
||||
/* Convert RVAL to VAL */
|
||||
epicsUInt32 rval = prec->rval;
|
||||
|
||||
}
|
||||
else if(status == 2) status = 0;
|
||||
if (prec->shft > 0)
|
||||
rval >>= prec->shft;
|
||||
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
prec->val = rval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
else if (status == 2)
|
||||
status = 0;
|
||||
|
||||
/* process the forward scan link record */
|
||||
recGblFwdLink(prec);
|
||||
if (prec->udf)
|
||||
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
|
||||
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
monitor(prec);
|
||||
|
||||
/* Wrap up */
|
||||
recGblFwdLink(prec);
|
||||
prec->pact = FALSE;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void monitor(mbbiDirectRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask;
|
||||
epicsUInt16 events = recGblResetAlarms(prec);
|
||||
epicsUInt16 vl_events = events | DBE_VALUE | DBE_LOG;
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
/* Update B0 - BF from VAL and post monitors */
|
||||
for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1) {
|
||||
epicsUInt8 oBn = *pBn;
|
||||
|
||||
/* send out bit field monitors (value change and sevr change) */
|
||||
refresh_bits(prec, monitor_mask);
|
||||
*pBn = !! (val & 1);
|
||||
if (oBn != *pBn)
|
||||
db_post_events(prec, pBn, vl_events);
|
||||
else if (events)
|
||||
db_post_events(prec, pBn, events);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
if (prec->mlst != prec->val) {
|
||||
events = vl_events;
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
if (events)
|
||||
db_post_events(prec, &prec->val, events);
|
||||
|
||||
if (prec->oraw != prec->rval) {
|
||||
db_post_events(prec, &prec->rval, vl_events);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static long readValue(mbbiDirectRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct mbbidset *pdset = (struct mbbidset *) (prec->dset);
|
||||
struct mbbidset *pdset = (struct mbbidset *) prec->dset;
|
||||
long status;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->read_mbbi)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->pact)
|
||||
return pdset->read_mbbi(prec);
|
||||
|
||||
status=dbGetLink(&(prec->siml),DBR_ENUM,
|
||||
&(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (prec->simm == menuSimmNO){
|
||||
status=(*pdset->read_mbbi)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuSimmYES){
|
||||
status=dbGetLink(&(prec->siol),
|
||||
DBR_ULONG,&(prec->sval),0,0);
|
||||
if (status==0){
|
||||
prec->val=(unsigned short)prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
status=2; /* don't convert */
|
||||
}
|
||||
else if (prec->simm == menuSimmRAW){
|
||||
status=dbGetLink(&(prec->siol),
|
||||
DBR_ULONG,&(prec->sval),0,0);
|
||||
if (status==0){
|
||||
prec->rval=prec->sval;
|
||||
prec->udf=FALSE;
|
||||
}
|
||||
status=0; /* convert since we've written RVAL */
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
switch (prec->simm) {
|
||||
case menuSimmNO:
|
||||
return pdset->read_mbbi(prec);
|
||||
|
||||
return(status);
|
||||
case menuSimmYES:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->val = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
status = 2; /* Don't convert */
|
||||
break;
|
||||
|
||||
case menuSimmRAW:
|
||||
status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
|
||||
if (status == 0) {
|
||||
prec->rval = prec->sval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
status = 0; /* Convert RVAL */
|
||||
break;
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
|
||||
* Copyright (c) 2012 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* $Revision-Id$ */
|
||||
|
||||
/* recMbboDirect.c - Record Support for mbboDirect records */
|
||||
/* mbboDirectRecord.c - Record Support for mbboDirect records */
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Date: 10-06-93
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "errlog.h"
|
||||
#include "alarm.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
@@ -59,35 +59,35 @@ static long special(DBADDR *, int);
|
||||
#define get_control_double NULL
|
||||
#define get_alarm_double NULL
|
||||
|
||||
rset mbboDirectRSET={
|
||||
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
|
||||
rset mbboDirectRSET = {
|
||||
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,mbboDirectRSET);
|
||||
epicsExportAddress(rset, mbboDirectRSET);
|
||||
|
||||
struct mbbodset { /* multi bit 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_mbbo; /*returns: (0,2)=>(success,success no convert)*/
|
||||
long number;
|
||||
DEVSUPFUN dev_report;
|
||||
DEVSUPFUN init;
|
||||
DEVSUPFUN init_record; /*returns: (0, 2)=>(success, success no convert)*/
|
||||
DEVSUPFUN get_ioint_info;
|
||||
DEVSUPFUN write_mbbo; /*returns: (0, 2)=>(success, success no convert)*/
|
||||
};
|
||||
|
||||
|
||||
@@ -95,264 +95,268 @@ static void convert(mbboDirectRecord *);
|
||||
static void monitor(mbboDirectRecord *);
|
||||
static long writeValue(mbboDirectRecord *);
|
||||
|
||||
#define NUM_BITS 16
|
||||
#define NUM_BITS 16
|
||||
|
||||
static long init_record(mbboDirectRecord *prec, int pass)
|
||||
{
|
||||
struct mbbodset *pdset;
|
||||
struct mbbodset *pdset = (struct mbbodset *) prec->dset;
|
||||
long status = 0;
|
||||
int i;
|
||||
|
||||
if (pass==0) return(0);
|
||||
if (pass == 0)
|
||||
return 0;
|
||||
|
||||
/* mbboDirect.siml must be a CONSTANT or a PV_LINK or a DB_LINK */
|
||||
if (prec->siml.type == CONSTANT) {
|
||||
recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
|
||||
if (!pdset) {
|
||||
recGblRecordError(S_dev_noDSET, prec, "mbboDirect: init_record");
|
||||
return S_dev_noDSET;
|
||||
}
|
||||
|
||||
if(!(pdset = (struct mbbodset *)(prec->dset))) {
|
||||
recGblRecordError(S_dev_noDSET,(void *)prec,"mbboDirect: init_record");
|
||||
return(S_dev_noDSET);
|
||||
if ((pdset->number < 5) || (pdset->write_mbbo == NULL)) {
|
||||
recGblRecordError(S_dev_missingSup, prec, "mbboDirect: init_record");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
/* must have write_mbbo function defined */
|
||||
if( (pdset->number < 5) || (pdset->write_mbbo == NULL) ) {
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"mbboDirect: init_record");
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
if (prec->dol.type == CONSTANT){
|
||||
if(recGblInitConstantLink(&prec->dol,DBF_USHORT,&prec->val))
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
/* initialize mask*/
|
||||
prec->mask = 0;
|
||||
for (i=0; i<prec->nobt; i++) {
|
||||
prec->mask <<= 1; /* shift left 1 bit*/
|
||||
prec->mask |= 1; /* set low order bit*/
|
||||
}
|
||||
if(pdset->init_record) {
|
||||
epicsUInt32 rval;
|
||||
|
||||
status=(*pdset->init_record)(prec);
|
||||
/* init_record might set status */
|
||||
if(status==0){
|
||||
rval = prec->rval;
|
||||
if(prec->shft>0) rval >>= prec->shft;
|
||||
prec->val = (unsigned short)rval;
|
||||
prec->udf = FALSE;
|
||||
} else if (status == 2) status = 0;
|
||||
if (prec->siml.type == CONSTANT)
|
||||
recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
|
||||
|
||||
if (prec->dol.type == CONSTANT)
|
||||
if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val))
|
||||
prec->udf = FALSE;
|
||||
|
||||
/* Initialize MASK if the user didn't */
|
||||
if (prec->mask == 0)
|
||||
prec->mask = (1 << prec->nobt) - 1;
|
||||
|
||||
if (pdset->init_record) {
|
||||
status = pdset->init_record(prec);
|
||||
if (status == 0) {
|
||||
/* Convert initial read-back */
|
||||
epicsUInt32 rval = prec->rval;
|
||||
|
||||
if (prec->shft > 0)
|
||||
rval >>= prec->shft;
|
||||
|
||||
prec->val = rval;
|
||||
prec->udf = FALSE;
|
||||
}
|
||||
else if (status == 2)
|
||||
status = 0;
|
||||
}
|
||||
|
||||
if (!prec->udf &&
|
||||
prec->omsl == menuOmslsupervisory) {
|
||||
/* Set initial B0 - BF from VAL */
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_BITS; i++) {
|
||||
*pBn++ = !! (val & 1);
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
prec->mlst = prec->val;
|
||||
prec->oraw = prec->rval;
|
||||
prec->orbv = prec->rbv;
|
||||
return(status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static long process(mbboDirectRecord *prec)
|
||||
{
|
||||
struct mbbodset *pdset = (struct mbbodset *)(prec->dset);
|
||||
long status=0;
|
||||
unsigned char pact=prec->pact;
|
||||
struct mbbodset *pdset = (struct mbbodset *)(prec->dset);
|
||||
long status = 0;
|
||||
int pact = prec->pact;
|
||||
|
||||
if( (pdset==NULL) || (pdset->write_mbbo==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
recGblRecordError(S_dev_missingSup,(void *)prec,"write_mbbo");
|
||||
return(S_dev_missingSup);
|
||||
if ((pdset == NULL) || (pdset->write_mbbo == NULL)) {
|
||||
prec->pact = TRUE;
|
||||
recGblRecordError(S_dev_missingSup, prec, "write_mbbo");
|
||||
return S_dev_missingSup;
|
||||
}
|
||||
|
||||
if (!prec->pact) {
|
||||
if(prec->dol.type!=CONSTANT && prec->omsl==menuOmslclosed_loop){
|
||||
long status;
|
||||
unsigned short val;
|
||||
if (!pact) {
|
||||
if (prec->dol.type != CONSTANT &&
|
||||
prec->omsl == menuOmslclosed_loop) {
|
||||
epicsUInt16 val;
|
||||
|
||||
status = dbGetLink(&prec->dol,DBR_USHORT,&val,0,0);
|
||||
if(status==0) {
|
||||
prec->val= val;
|
||||
prec->udf= FALSE;
|
||||
}
|
||||
else {
|
||||
recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM);
|
||||
goto CONTINUE;
|
||||
}
|
||||
}
|
||||
if(prec->udf) {
|
||||
recGblSetSevr(prec,UDF_ALARM,INVALID_ALARM);
|
||||
goto CONTINUE;
|
||||
}
|
||||
if(prec->nsev < INVALID_ALARM
|
||||
&& prec->sevr == INVALID_ALARM
|
||||
&& prec->omsl == menuOmslsupervisory) {
|
||||
/* reload value field with B0 - B15 */
|
||||
int offset = 1, i;
|
||||
unsigned char *bit = &(prec->b0);
|
||||
for (i=0; i<NUM_BITS; i++, offset = offset << 1, bit++) {
|
||||
if (*bit)
|
||||
prec->val |= offset;
|
||||
else
|
||||
prec->val &= ~offset;
|
||||
}
|
||||
}
|
||||
/* convert val to rval */
|
||||
convert(prec);
|
||||
if (dbGetLink(&prec->dol, DBR_USHORT, &val, 0, 0)) {
|
||||
recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
|
||||
goto CONTINUE;
|
||||
}
|
||||
prec->val = val;
|
||||
}
|
||||
else if (prec->omsl == menuOmslsupervisory) {
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
epicsUInt16 val = 0;
|
||||
epicsUInt16 bit = 1;
|
||||
int i;
|
||||
|
||||
/* Construct VAL from B0 - BF */
|
||||
for (i = 0; i < NUM_BITS; i++, bit <<= 1)
|
||||
if (*pBn++)
|
||||
val |= bit;
|
||||
prec->val = val;
|
||||
}
|
||||
else if (prec->udf) {
|
||||
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
|
||||
goto CONTINUE;
|
||||
}
|
||||
|
||||
prec->udf = FALSE;
|
||||
/* Convert VAL to RVAL */
|
||||
convert(prec);
|
||||
}
|
||||
|
||||
CONTINUE:
|
||||
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;
|
||||
convert(prec);
|
||||
}
|
||||
status=writeValue(prec); /* write the new value */
|
||||
break;
|
||||
default :
|
||||
status=-1;
|
||||
recGblRecordError(S_db_badField,(void *)prec,
|
||||
"mbboDirect: process Illegal IVOA field");
|
||||
}
|
||||
if (prec->nsev < INVALID_ALARM)
|
||||
status = writeValue(prec);
|
||||
else {
|
||||
switch (prec->ivoa) {
|
||||
case menuIvoaSet_output_to_IVOV:
|
||||
if (!prec->pact) {
|
||||
prec->val = prec->ivov;
|
||||
convert(prec);
|
||||
}
|
||||
/* No break, fall through... */
|
||||
case menuIvoaContinue_normally:
|
||||
status = writeValue(prec);
|
||||
break;
|
||||
case menuIvoaDon_t_drive_outputs:
|
||||
break;
|
||||
default:
|
||||
status = -1;
|
||||
recGblRecordError(S_db_badField, prec,
|
||||
"mbboDirect: process Illegal IVOA field");
|
||||
}
|
||||
}
|
||||
|
||||
/* Done if device support set PACT */
|
||||
if (!pact && prec->pact)
|
||||
return 0;
|
||||
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
prec->pact = TRUE;
|
||||
|
||||
recGblGetTimeStamp(prec);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
|
||||
/* Wrap up */
|
||||
recGblFwdLink(prec);
|
||||
prec->pact=FALSE;
|
||||
return(status);
|
||||
prec->pact = FALSE;
|
||||
return status;
|
||||
}
|
||||
|
||||
static long special(DBADDR *paddr, int after)
|
||||
{
|
||||
mbboDirectRecord *prec = (mbboDirectRecord *)(paddr->precord);
|
||||
int special_type = paddr->special, offset = 1, i;
|
||||
unsigned char *bit;
|
||||
mbboDirectRecord *prec = (mbboDirectRecord *) paddr->precord;
|
||||
|
||||
if(!after) return(0);
|
||||
switch(special_type) {
|
||||
case(SPC_MOD):
|
||||
/*
|
||||
* Set a bit in VAL corresponding to the bit changed
|
||||
* offset equals the offset in bit array. Only do
|
||||
* this if in supervisory mode.
|
||||
*/
|
||||
if (prec->omsl == menuOmslclosed_loop)
|
||||
return(0);
|
||||
if (!after)
|
||||
return 0;
|
||||
|
||||
offset = 1 << (((unsigned char *)paddr->pfield) - &(prec->b0));
|
||||
|
||||
if (*((char *)paddr->pfield)) {
|
||||
/* set field */
|
||||
prec->val |= offset;
|
||||
}
|
||||
else {
|
||||
/* zero field */
|
||||
prec->val &= ~offset;
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
|
||||
convert(prec);
|
||||
return(0);
|
||||
case(SPC_RESET):
|
||||
/*
|
||||
* If OMSL changes from closed_loop to supervisory,
|
||||
* reload value field with B0 - B15
|
||||
*/
|
||||
bit = &(prec->b0);
|
||||
switch (paddr->special) {
|
||||
case SPC_MOD: /* Bn field modified */
|
||||
if (prec->omsl == menuOmslsupervisory) {
|
||||
for (i=0; i<NUM_BITS; i++, offset = offset << 1, bit++) {
|
||||
if (*bit)
|
||||
prec->val |= offset;
|
||||
else
|
||||
prec->val &= ~offset;
|
||||
/* Adjust VAL corresponding to the bit changed */
|
||||
epicsUInt8 *pBn = (epicsUInt8 *) paddr->pfield;
|
||||
int bit = 1 << (pBn - &prec->b0);
|
||||
|
||||
if (*pBn)
|
||||
prec->val |= bit;
|
||||
else
|
||||
prec->val &= ~bit;
|
||||
|
||||
prec->udf = FALSE;
|
||||
convert(prec);
|
||||
}
|
||||
break;
|
||||
|
||||
case SPC_RESET: /* OMSL field modified */
|
||||
if (prec->omsl == menuOmslclosed_loop) {
|
||||
/* Construct VAL from B0 - BF */
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
epicsUInt16 val = 0, bit = 1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_BITS; i++, bit <<= 1)
|
||||
if (*pBn++)
|
||||
val |= bit;
|
||||
prec->val = val;
|
||||
}
|
||||
else if (prec->omsl == menuOmslsupervisory) {
|
||||
/* Set B0 - BF from VAL and post monitors */
|
||||
epicsUInt16 val = prec->val;
|
||||
epicsUInt8 *pBn = &prec->b0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1) {
|
||||
epicsUInt8 oBn = *pBn;
|
||||
|
||||
*pBn = !! (val & 1);
|
||||
if (oBn != *pBn)
|
||||
db_post_events(prec, pBn, DBE_VALUE | DBE_LOG);
|
||||
}
|
||||
}
|
||||
prec->udf = FALSE;
|
||||
break;
|
||||
|
||||
return(0);
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"mbboDirect: special");
|
||||
return(S_db_badChoice);
|
||||
default:
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "mbboDirect: special");
|
||||
return S_db_badChoice;
|
||||
}
|
||||
|
||||
prec->udf = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void monitor(mbboDirectRecord *prec)
|
||||
{
|
||||
unsigned short monitor_mask;
|
||||
epicsUInt16 events = recGblResetAlarms(prec);
|
||||
|
||||
monitor_mask = recGblResetAlarms(prec);
|
||||
if (prec->mlst != prec->val) {
|
||||
events |= DBE_VALUE | DBE_LOG;
|
||||
prec->mlst = prec->val;
|
||||
}
|
||||
if (events)
|
||||
db_post_events(prec, &prec->val, events);
|
||||
|
||||
/* 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;
|
||||
events |= DBE_VALUE | DBE_LOG;
|
||||
if (prec->oraw != prec->rval) {
|
||||
db_post_events(prec, &prec->rval, events);
|
||||
prec->oraw = prec->rval;
|
||||
}
|
||||
if (prec->orbv != prec->rbv) {
|
||||
db_post_events(prec, &prec->rbv, events);
|
||||
prec->orbv = prec->rbv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void convert(mbboDirectRecord *prec)
|
||||
{
|
||||
/* convert val to rval */
|
||||
prec->rval = (epicsUInt32)(prec->val);
|
||||
if(prec->shft>0)
|
||||
prec->rval <<= prec->shft;
|
||||
/* Convert VAL to RVAL */
|
||||
prec->rval = prec->val;
|
||||
|
||||
return;
|
||||
if (prec->shft > 0)
|
||||
prec->rval <<= prec->shft;
|
||||
}
|
||||
|
||||
static long writeValue(mbboDirectRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct mbbodset *pdset = (struct mbbodset *) (prec->dset);
|
||||
long status;
|
||||
struct mbbodset *pdset = (struct mbbodset *) prec->dset;
|
||||
|
||||
if (prec->pact == TRUE){
|
||||
status=(*pdset->write_mbbo)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->pact)
|
||||
return pdset->write_mbbo(prec);
|
||||
|
||||
status=dbGetLink(&(prec->siml),
|
||||
DBR_ENUM,&(prec->simm),0,0);
|
||||
if (status)
|
||||
return(status);
|
||||
status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (prec->simm == menuYesNoNO){
|
||||
status=(*pdset->write_mbbo)(prec);
|
||||
return(status);
|
||||
}
|
||||
if (prec->simm == menuYesNoYES){
|
||||
status=dbPutLink(&prec->siol,DBR_USHORT,
|
||||
&prec->val,1);
|
||||
} else {
|
||||
status=-1;
|
||||
recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
|
||||
return(status);
|
||||
}
|
||||
recGblSetSevr(prec,SIMM_ALARM,prec->sims);
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
return pdset->write_mbbo(prec);
|
||||
|
||||
return(status);
|
||||
case menuYesNoYES:
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
return dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1);
|
||||
|
||||
default:
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user