From 0af48f5a29f93c080d86591ddabffab0a7de95bb Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Wed, 6 Jan 2010 16:05:49 -0600
Subject: [PATCH 01/13] Alarm filter changes by Bernd Schoeneburg Algorithm by
Eric Norum. Developed at the 2009 EPICS Codeathon.
---
src/std/rec/aiRecord.c | 140 ++++++++++++++++++++++++++++-----------
src/std/rec/aiRecord.dbd | 10 +++
2 files changed, 110 insertions(+), 40 deletions(-)
diff --git a/src/std/rec/aiRecord.c b/src/std/rec/aiRecord.c
index 158456e88..7f2ce4bde 100644
--- a/src/std/rec/aiRecord.c
+++ b/src/std/rec/aiRecord.c
@@ -41,6 +41,9 @@
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
+/* Hysterisis for alarm filtering: 1-1/e */
+#define THRESHOLD 0.6321
+
/* Create RSET - Record Support Entry Table*/
#define report NULL
#define initialize NULL
@@ -99,7 +102,7 @@ typedef struct aidset { /* analog input dset */
extern unsigned int gts_trigger_counter;
*/
-static void checkAlarms(aiRecord *prec);
+static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime);
static void convert(aiRecord *prec);
static void monitor(aiRecord *prec);
static long readValue(aiRecord *prec);
@@ -158,12 +161,15 @@ static long process(void *precord)
aidset *pdset = (aidset *)(prec->dset);
long status;
unsigned char pact=prec->pact;
+ epicsTimeStamp timeLast;
if( (pdset==NULL) || (pdset->read_ai==NULL) ) {
prec->pact=TRUE;
recGblRecordError(S_dev_missingSup,(void *)prec,"read_ai");
return(S_dev_missingSup);
}
+ timeLast = prec->time;
+
status=readValue(prec); /* read the new value */
/* check if device support set pact */
if ( !pact && prec->pact ) return(0);
@@ -174,7 +180,7 @@ static long process(void *precord)
else if (status==2) status=0;
/* check for alarms */
- checkAlarms(prec);
+ checkAlarms(prec,&timeLast);
/* check event list */
monitor(prec);
/* process the forward scan link record */
@@ -305,60 +311,114 @@ static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
return(0);
}
-static void checkAlarms(aiRecord *prec)
+static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime)
{
- double val, hyst, lalm;
- double alev;
+ enum {
+ range_Lolo = 1,
+ range_Low,
+ range_Normal,
+ range_High,
+ range_Hihi
+ } alarmRange;
+ static const epicsEnum16 range_stat[] = {
+ SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
+ NO_ALARM, HIGH_ALARM, HIHI_ALARM
+ };
+ double val, hyst, lalm, alev, aftc, afvl;
epicsEnum16 asev;
if (prec->udf) {
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+ prec->afvl = 0;
return;
}
- val = prec->val;
+ val = prec->val;
hyst = prec->hyst;
lalm = prec->lalm;
- /* alarm condition hihi */
- asev = prec->hhsv;
- alev = prec->hihi;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIHI_ALARM, asev))
- prec->lalm = alev;
- return;
+ /* check VAL against alarm limits */
+ if ((asev = prec->hhsv) &&
+ (val >= (alev = prec->hihi) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_Hihi;
+ else
+ if ((asev = prec->llsv) &&
+ (val <= (alev = prec->lolo) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Lolo;
+ else
+ if ((asev = prec->hsv) &&
+ (val >= (alev = prec->high) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_High;
+ else
+ if ((asev = prec->lsv) &&
+ (val <= (alev = prec->low) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Low;
+ else {
+ alev = val;
+ asev = NO_ALARM;
+ alarmRange = range_Normal;
}
- /* alarm condition lolo */
- asev = prec->llsv;
- alev = prec->lolo;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOLO_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ aftc = prec->aftc;
+ afvl = 0;
- /* alarm condition high */
- asev = prec->hsv;
- alev = prec->high;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIGH_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ if (aftc > 0) {
+ /* Apply level filtering */
+ afvl = prec->afvl;
+ if (afvl == 0) {
+ afvl = (double)alarmRange;
+ } else {
+ double t = epicsTimeDiffInSeconds(&prec->time, lastTime);
+ double alpha = aftc / (t + aftc);
- /* alarm condition low */
- asev = prec->lsv;
- alev = prec->low;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOW_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ /* The sign of afvl indicates whether the result should be
+ * rounded up or down. This gives the filter hysteresis.
+ * If afvl > 0 the floor() function rounds to a lower alarm
+ * level, otherwise to a higher.
+ */
+ afvl = alpha * afvl +
+ ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
+ if (afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl; /* reverse rounding */
- /* we get here only if val is out of alarm by at least hyst */
- prec->lalm = val;
- return;
+ alarmRange = abs((int)floor(afvl));
+ switch (alarmRange) {
+ case range_Hihi:
+ asev = prec->hhsv;
+ alev = prec->hihi;
+ break;
+ case range_High:
+ asev = prec->hsv;
+ alev = prec->high;
+ break;
+ case range_Normal:
+ asev = NO_ALARM;
+ break;
+ case range_Low:
+ asev = prec->lsv;
+ alev = prec->low;
+ break;
+ case range_Lolo:
+ asev = prec->llsv;
+ alev = prec->lolo;
+ break;
+ }
+ }
+ }
+ prec->afvl = afvl;
+
+ if (asev) {
+ /* Report alarm condition, store LALM for future HYST calculations */
+ if (recGblSetSevr(prec, range_stat[alarmRange], asev))
+ prec->lalm = alev;
+ } else {
+ /* No alarm condition, reset LALM */
+ prec->lalm = val;
+ }
}
static void convert(aiRecord *prec)
diff --git a/src/std/rec/aiRecord.dbd b/src/std/rec/aiRecord.dbd
index a7518ab73..52fd4b05b 100644
--- a/src/std/rec/aiRecord.dbd
+++ b/src/std/rec/aiRecord.dbd
@@ -138,6 +138,11 @@ recordtype(ai) {
promptgroup(GUI_ALARMS)
interest(1)
}
+ field(AFTC,DBF_DOUBLE) {
+ prompt("Alarm Filter Time Constant")
+ promptgroup(GUI_ALARMS)
+ interest(1)
+ }
field(ADEL,DBF_DOUBLE) {
prompt("Archive Deadband")
promptgroup(GUI_DISPLAY)
@@ -153,6 +158,11 @@ recordtype(ai) {
special(SPC_NOMOD)
interest(3)
}
+ field(AFVL,DBF_DOUBLE) {
+ prompt("Alarm Filter Value")
+ special(SPC_NOMOD)
+ interest(3)
+ }
field(ALST,DBF_DOUBLE) {
prompt("Last Value Archived")
special(SPC_NOMOD)
From 8e701b7d4ff720955669e8b1ab1be06651595d9f Mon Sep 17 00:00:00 2001
From: Dirk Zimoch
Date: Wed, 26 May 2010 04:18:57 -0700
Subject: [PATCH 02/13] fixed get_units, get_precision, get_graphic_double, and
get_control_double to return meaningful values on non-VAL fields
---
src/rec/aaiRecord.c | 47 +++++++++---
src/rec/aaoRecord.c | 47 +++++++++---
src/rec/aiRecord.c | 70 +++++++++++-------
src/rec/aoRecord.c | 81 ++++++++++++++-------
src/rec/boRecord.c | 27 +++++--
src/rec/calcRecord.c | 134 ++++++++++++++++++++--------------
src/rec/calcoutRecord.c | 146 ++++++++++++++++++++++++--------------
src/rec/compressRecord.c | 41 +++++++----
src/rec/dfanoutRecord.c | 73 ++++++++++---------
src/rec/histogramRecord.c | 71 ++++++++++++------
src/rec/longinRecord.c | 56 ++++++++++-----
src/rec/longoutRecord.c | 73 +++++++++++--------
src/rec/selRecord.c | 104 +++++++++++++++------------
src/rec/seqRecord.c | 135 ++++++++++++++++++++++++++++-------
src/rec/subArrayRecord.c | 97 ++++++++++++++-----------
src/rec/subRecord.c | 127 ++++++++++++++++++++-------------
src/rec/waveformRecord.c | 59 ++++++++++-----
17 files changed, 904 insertions(+), 484 deletions(-)
diff --git a/src/rec/aaiRecord.c b/src/rec/aaiRecord.c
index 008a4f3d5..0d8f8ad6f 100644
--- a/src/rec/aaiRecord.c
+++ b/src/rec/aaiRecord.c
@@ -191,11 +191,20 @@ static long put_array_info(DBADDR *paddr, long nNew)
return 0;
}
+#define indexof(field) aaiRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
aaiRecord *prec = (aaiRecord *)paddr->precord;
- strncpy(units, prec->egu, DB_UNITS_SIZE);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+ break;
+ case indexof(HOPR):
+ case indexof(LOPR):
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return 0;
}
@@ -204,8 +213,8 @@ static long get_precision(DBADDR *paddr, long *precision)
aaiRecord *prec = (aaiRecord *)paddr->precord;
*precision = prec->prec;
- if (paddr->pfield == (void *)prec->bptr) return 0;
- recGblGetPrec(paddr, precision);
+ if (dbGetFieldIndex(paddr) != indexof(VAL))
+ recGblGetPrec(paddr, precision);
return 0;
}
@@ -213,10 +222,18 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
aaiRecord *prec = (aaiRecord *)paddr->precord;
- if (paddr->pfield == (void *)prec->bptr) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr, pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ case indexof(NORD):
+ pgd->upper_disp_limit = prec->nelm;
+ pgd->lower_disp_limit = 0;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr, pgd);
+ }
return 0;
}
@@ -224,10 +241,18 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
aaiRecord *prec = (aaiRecord *)paddr->precord;
- if (paddr->pfield == (void *)prec->bptr) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr, pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ case indexof(NORD):
+ pcd->upper_ctrl_limit = prec->nelm;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ default:
+ recGblGetControlDouble(paddr, pcd);
+ }
return 0;
}
diff --git a/src/rec/aaoRecord.c b/src/rec/aaoRecord.c
index 954df058f..f1dd23a5b 100644
--- a/src/rec/aaoRecord.c
+++ b/src/rec/aaoRecord.c
@@ -188,11 +188,20 @@ static long put_array_info(DBADDR *paddr, long nNew)
return 0;
}
+#define indexof(field) aaoRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
aaoRecord *prec = (aaoRecord *)paddr->precord;
- strncpy(units, prec->egu, DB_UNITS_SIZE);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+ break;
+ case indexof(HOPR):
+ case indexof(LOPR):
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return 0;
}
@@ -201,8 +210,8 @@ static long get_precision(DBADDR *paddr, long *precision)
aaoRecord *prec = (aaoRecord *)paddr->precord;
*precision = prec->prec;
- if (paddr->pfield == (void *)prec->bptr) return 0;
- recGblGetPrec(paddr, precision);
+ if (dbGetFieldIndex(paddr) != indexof(VAL))
+ recGblGetPrec(paddr, precision);
return 0;
}
@@ -210,10 +219,18 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
aaoRecord *prec = (aaoRecord *)paddr->precord;
- if (paddr->pfield == (void *)prec->bptr) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ case indexof(NORD):
+ pgd->upper_disp_limit = prec->nelm;
+ pgd->lower_disp_limit = 0;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr, pgd);
+ }
return 0;
}
@@ -221,10 +238,18 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
aaoRecord *prec = (aaoRecord *)paddr->precord;
- if(paddr->pfield==(void *)prec->bptr){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ case indexof(NORD):
+ pcd->upper_ctrl_limit = prec->nelm;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ default:
+ recGblGetControlDouble(paddr, pcd);
+ }
return 0;
}
diff --git a/src/rec/aiRecord.c b/src/rec/aiRecord.c
index 6cb440f8d..1f17d805e 100644
--- a/src/rec/aiRecord.c
+++ b/src/rec/aiRecord.c
@@ -217,11 +217,22 @@ static long special(DBADDR *paddr,int after)
}
}
+#define indexof(field) aiRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
aiRecord *prec=(aiRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(ASLO):
+ case indexof(AOFF):
+ case indexof(SMOO):
+ break;
+ default:
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ }
return(0);
}
@@ -230,7 +241,7 @@ static long get_precision(DBADDR *paddr, long *precision)
aiRecord *prec=(aiRecord *)paddr->precord;
*precision = prec->prec;
- if(paddr->pfield == (void *)&prec->val) return(0);
+ if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0);
recGblGetPrec(paddr,precision);
return(0);
}
@@ -238,43 +249,54 @@ static long get_precision(DBADDR *paddr, long *precision)
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
aiRecord *prec=(aiRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == aiRecordVAL
- || fieldIndex == aiRecordHIHI
- || fieldIndex == aiRecordHIGH
- || fieldIndex == aiRecordLOW
- || fieldIndex == aiRecordLOLO
- || fieldIndex == aiRecordHOPR
- || fieldIndex == aiRecordLOPR) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
aiRecord *prec=(aiRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == aiRecordVAL
- || fieldIndex == aiRecordHIHI
- || fieldIndex == aiRecordHIGH
- || fieldIndex == aiRecordLOW
- || fieldIndex == aiRecordLOLO) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
{
aiRecord *prec=(aiRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == aiRecordVAL) {
+ if (dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/aoRecord.c b/src/rec/aoRecord.c
index 33bfc4730..6fe832daf 100644
--- a/src/rec/aoRecord.c
+++ b/src/rec/aoRecord.c
@@ -276,11 +276,21 @@ static long special(DBADDR *paddr, int after)
}
}
+#define indexof(field) aoRecord##field
+
static long get_units(DBADDR * paddr,char *units)
{
aoRecord *prec=(aoRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(ASLO):
+ case indexof(AOFF):
+ break;
+ default:
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ }
return(0);
}
@@ -289,10 +299,14 @@ static long get_precision(DBADDR *paddr,long *precision)
aoRecord *prec=(aoRecord *)paddr->precord;
*precision = prec->prec;
- if(paddr->pfield == (void *)&prec->val
- || paddr->pfield == (void *)&prec->oval
- || paddr->pfield == (void *)&prec->pval) return(0);
- recGblGetPrec(paddr,precision);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(OVAL):
+ case indexof(PVAL):
+ break;
+ default:
+ recGblGetPrec(paddr,precision);
+ }
return(0);
}
@@ -300,16 +314,24 @@ static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
aoRecord *prec=(aoRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo
- || paddr->pfield==(void *)&prec->oval
- || paddr->pfield==(void *)&prec->pval){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(OVAL):
+ case indexof(PVAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(IVOV):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
@@ -317,23 +339,30 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
aoRecord *prec=(aoRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo
- || paddr->pfield==(void *)&prec->oval
- || paddr->pfield==(void *)&prec->pval){
- pcd->upper_ctrl_limit = prec->drvh;
- pcd->lower_ctrl_limit = prec->drvl;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(OVAL):
+ case indexof(PVAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ pcd->upper_ctrl_limit = prec->drvh;
+ pcd->lower_ctrl_limit = prec->drvl;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
aoRecord *prec=(aoRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val){
+ if(dbGetFieldIndex(paddr) == indexof(VAL)){
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/boRecord.c b/src/rec/boRecord.c
index b0c45daed..42d050b95 100644
--- a/src/rec/boRecord.c
+++ b/src/rec/boRecord.c
@@ -51,13 +51,13 @@ static long process(boRecord *);
#define cvt_dbaddr NULL
#define get_array_info NULL
#define put_array_info NULL
-#define get_units NULL
+static long get_units(DBADDR *, char *);
static long get_precision(DBADDR *, long *);
static long get_enum_str(DBADDR *, char *);
static long get_enum_strs(DBADDR *, struct dbr_enumStrs *);
static long put_enum_str(DBADDR *, char *);
#define get_graphic_double NULL
-#define get_control_double NULL
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
#define get_alarm_double NULL
rset boRSET={
@@ -268,15 +268,30 @@ static long process(boRecord *prec)
return(status);
}
+#define indexof(field) boRecord##field
+
+static long get_units(DBADDR *paddr, char *units)
+{
+ if(dbGetFieldIndex(paddr) == indexof(HIGH)) strcpy(units, "s");
+ return(0);
+}
+
static long get_precision(DBADDR *paddr, long *precision)
{
- boRecord *prec=(boRecord *)paddr->precord;
-
- if(paddr->pfield == (void *)&prec->high) *precision=2;
+ if(dbGetFieldIndex(paddr) == indexof(HIGH)) *precision = 2;
else recGblGetPrec(paddr,precision);
return(0);
}
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+ recGblGetControlDouble(paddr,pcd);
+ if(dbGetFieldIndex(paddr) == indexof(HIGH)) {
+ pcd->lower_ctrl_limit = 0.0;
+ }
+ return(0);
+}
+
static long get_enum_str(DBADDR *paddr, char *pstring)
{
boRecord *prec=(boRecord *)paddr->precord;
@@ -285,7 +300,7 @@ static long get_enum_str(DBADDR *paddr, char *pstring)
index = dbGetFieldIndex(paddr);
- if(index!=boRecordVAL) {
+ if(index!=indexof(VAL)) {
strcpy(pstring,"Illegal_Value");
} else if(*pfield==0) {
strncpy(pstring,prec->znam,sizeof(prec->znam));
diff --git a/src/rec/calcRecord.c b/src/rec/calcRecord.c
index aa2178054..75ae6ed00 100644
--- a/src/rec/calcRecord.c
+++ b/src/rec/calcRecord.c
@@ -54,7 +54,7 @@ static long get_precision(DBADDR *paddr, long *precision);
#define get_enum_strs NULL
#define put_enum_str NULL
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd);
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd);
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd);
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad);
rset calcRSET={
@@ -74,7 +74,7 @@ rset calcRSET={
get_enum_strs,
put_enum_str,
get_graphic_double,
- get_ctrl_double,
+ get_control_double,
get_alarm_double
};
epicsExportAddress(rset, calcRSET);
@@ -148,83 +148,107 @@ static long special(DBADDR *paddr, int after)
return S_db_badChoice;
}
+#define indexof(field) calcRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
calcRecord *prec = (calcRecord *)paddr->precord;
+ int index = dbGetFieldIndex(paddr);
- strncpy(units, prec->egu, DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get units for A-L */;
+ } else {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ }
return 0;
}
static long get_precision(DBADDR *paddr, long *pprecision)
{
calcRecord *prec = (calcRecord *)paddr->precord;
+ int index = dbGetFieldIndex(paddr);
- if (paddr->pfield == (void *)&prec->val) {
- *pprecision = prec->prec;
- } else {
- recGblGetPrec(paddr, pprecision);
+ *pprecision = prec->prec;
+ if (index == indexof(VAL)) {
+ return 0;
}
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get precision for A-L */;
+ *pprecision=15;
+ }
+ recGblGetPrec(paddr, pprecision);
return 0;
}
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
calcRecord *prec = (calcRecord *)paddr->precord;
-
- if (paddr->pfield == (void *)&prec->val ||
- paddr->pfield == (void *)&prec->hihi ||
- paddr->pfield == (void *)&prec->high ||
- paddr->pfield == (void *)&prec->low ||
- paddr->pfield == (void *)&prec->lolo) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetGraphicDouble(paddr,pgd);
+ return 0;
}
-
- if (paddr->pfield >= (void *)&prec->a &&
- paddr->pfield <= (void *)&prec->l) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
- }
- if (paddr->pfield >= (void *)&prec->la &&
- paddr->pfield <= (void *)&prec->ll) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
- }
- recGblGetGraphicDouble(paddr, pgd);
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
return 0;
}
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
calcRecord *prec = (calcRecord *)paddr->precord;
-
- if (paddr->pfield == (void *)&prec->val ||
- paddr->pfield == (void *)&prec->hihi ||
- paddr->pfield == (void *)&prec->high ||
- paddr->pfield == (void *)&prec->low ||
- paddr->pfield == (void *)&prec->lolo) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetControlDouble(paddr,pcd);
+ return 0;
}
-
- if (paddr->pfield >= (void *)&prec->a &&
- paddr->pfield <= (void *)&prec->l) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
- }
- if (paddr->pfield >= (void *)&prec->la &&
- paddr->pfield <= (void *)&prec->ll) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
- }
- recGblGetControlDouble(paddr, pcd);
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
@@ -232,7 +256,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
calcRecord *prec = (calcRecord *)paddr->precord;
- if (paddr->pfield == (void *)&prec->val) {
+ if (dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c
index f49c699d8..795f1db66 100644
--- a/src/rec/calcoutRecord.c
+++ b/src/rec/calcoutRecord.c
@@ -59,7 +59,7 @@ static long get_precision(DBADDR *, long *);
#define get_enum_strs NULL
#define put_enum_str NULL
static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
-static long get_ctrl_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
rset calcoutRSET = {
@@ -79,7 +79,7 @@ rset calcoutRSET = {
get_enum_strs,
put_enum_str,
get_graphic_double,
- get_ctrl_double,
+ get_control_double,
get_alarm_double
};
epicsExportAddress(rset, calcoutRSET);
@@ -363,23 +363,49 @@ static long special(DBADDR *paddr, int after)
}
}
+#define indexof(field) calcoutRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
+ int index = dbGetFieldIndex(paddr);
- strncpy(units, prec->egu, DB_UNITS_SIZE);
+ if(index == indexof(ODLY)) {
+ strcpy(units, "s");
+ return 0;
+ }
+
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get units for A-L */;
+ } else {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ }
return 0;
}
static long get_precision(DBADDR *paddr, long *pprecision)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
+ int index = dbGetFieldIndex(paddr);
- if (paddr->pfield == (void *)&prec->val) {
- *pprecision = prec->prec;
- } else {
- recGblGetPrec(paddr, pprecision);
+ if(index == indexof(ODLY)) {
+ *pprecision = 2;
+ return 0;
}
+
+ *pprecision = prec->prec;
+ if (index == indexof(VAL)) {
+ return 0;
+ }
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get precision for A-L */;
+ *pprecision=15;
+ }
+ recGblGetPrec(paddr, pprecision);
return 0;
}
@@ -387,59 +413,71 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
- if (paddr->pfield == (void *)&prec->val ||
- paddr->pfield == (void *)&prec->hihi ||
- paddr->pfield == (void *)&prec->high ||
- paddr->pfield == (void *)&prec->low ||
- paddr->pfield == (void *)&prec->lolo) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(ODLY):
+ return 0;
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetGraphicDouble(paddr,pgd);
+ return 0;
}
-
- if (paddr->pfield >= (void *)&prec->a &&
- paddr->pfield <= (void *)&prec->l) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
- }
- if (paddr->pfield >= (void *)&prec->la &&
- paddr->pfield <= (void *)&prec->ll) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return 0;
- }
- recGblGetGraphicDouble(paddr, pgd);
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
return 0;
}
-static long get_ctrl_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
-
- if (paddr->pfield == (void *)&prec->val ||
- paddr->pfield == (void *)&prec->hihi ||
- paddr->pfield == (void *)&prec->high ||
- paddr->pfield == (void *)&prec->low ||
- paddr->pfield == (void *)&prec->lolo) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetControlDouble(paddr,pcd);
+ if (index == indexof(ODLY)) pcd->lower_ctrl_limit = 0.0;
+ return 0;
}
-
- if (paddr->pfield >= (void *)&prec->a &&
- paddr->pfield <= (void *)&prec->l) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
- }
- if (paddr->pfield >= (void *)&prec->la &&
- paddr->pfield <= (void *)&prec->ll) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return 0;
- }
- recGblGetControlDouble(paddr, pcd);
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
@@ -447,7 +485,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
- if (paddr->pfield == (void *)&prec->val) {
+ if (dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/compressRecord.c b/src/rec/compressRecord.c
index 5d29f7ec0..7053f7c2b 100644
--- a/src/rec/compressRecord.c
+++ b/src/rec/compressRecord.c
@@ -398,11 +398,16 @@ static long put_array_info(DBADDR *paddr, long nNew)
return(0);
}
+#define indexof(field) compressRecord##field
+
static long get_units(DBADDR *paddr,char *units)
{
compressRecord *prec=(compressRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE
+ || dbGetFieldIndex(paddr) == indexof(VAL)) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return(0);
}
@@ -411,7 +416,7 @@ static long get_precision(DBADDR *paddr, long *precision)
compressRecord *prec=(compressRecord *)paddr->precord;
*precision = prec->prec;
- if(paddr->pfield == (void *)prec->bptr) return(0);
+ if(dbGetFieldIndex(paddr) == indexof(BPTR)) return(0);
recGblGetPrec(paddr,precision);
return(0);
}
@@ -420,12 +425,16 @@ static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
compressRecord *prec=(compressRecord *)paddr->precord;
- if(paddr->pfield==(void *)prec->bptr
- || paddr->pfield==(void *)&prec->ihil
- || paddr->pfield==(void *)&prec->ilil){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(BPTR):
+ case indexof(IHIL):
+ case indexof(ILIL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
@@ -433,11 +442,15 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
compressRecord *prec=(compressRecord *)paddr->precord;
- if(paddr->pfield==(void *)prec->bptr
- || paddr->pfield==(void *)&prec->ihil
- || paddr->pfield==(void *)&prec->ilil){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(BPTR):
+ case indexof(IHIL):
+ case indexof(ILIL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
diff --git a/src/rec/dfanoutRecord.c b/src/rec/dfanoutRecord.c
index 899fbf941..3c82812cd 100644
--- a/src/rec/dfanoutRecord.c
+++ b/src/rec/dfanoutRecord.c
@@ -126,73 +126,72 @@ static long process(dfanoutRecord *prec)
return(status);
}
+#define indexof(field) dfanoutRecord##field
+
static long get_units(DBADDR *paddr,char *units)
{
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return(0);
}
static long get_precision(DBADDR *paddr,long *precision)
{
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == dfanoutRecordVAL
- || fieldIndex == dfanoutRecordHIHI
- || fieldIndex == dfanoutRecordHIGH
- || fieldIndex == dfanoutRecordLOW
- || fieldIndex == dfanoutRecordLOLO
- || fieldIndex == dfanoutRecordHOPR
- || fieldIndex == dfanoutRecordLOPR) {
- *precision = prec->prec;
- } else {
- recGblGetPrec(paddr,precision);
- }
+ *precision = prec->prec;
+ if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0);
+ recGblGetPrec(paddr,precision);
return(0);
}
-static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
+static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == dfanoutRecordVAL
- || fieldIndex == dfanoutRecordHIHI
- || fieldIndex == dfanoutRecordHIGH
- || fieldIndex == dfanoutRecordLOW
- || fieldIndex == dfanoutRecordLOLO
- || fieldIndex == dfanoutRecordHOPR
- || fieldIndex == dfanoutRecordLOPR) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == dfanoutRecordVAL
- || fieldIndex == dfanoutRecordHIHI
- || fieldIndex == dfanoutRecordHIGH
- || fieldIndex == dfanoutRecordLOW
- || fieldIndex == dfanoutRecordLOLO) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
{
dfanoutRecord *prec=(dfanoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
-
- if(fieldIndex == dfanoutRecordVAL) {
+ if(dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/histogramRecord.c b/src/rec/histogramRecord.c
index 7753312a6..5c9802824 100644
--- a/src/rec/histogramRecord.c
+++ b/src/rec/histogramRecord.c
@@ -52,7 +52,7 @@ static long special(DBADDR *, int);
static long cvt_dbaddr(DBADDR *);
static long get_array_info(DBADDR *, long *, long *);
#define put_array_info NULL
-#define get_units NULL
+static long get_units(DBADDR *, char *);
static long get_precision(DBADDR *paddr,long *precision);
#define get_enum_str NULL
#define get_enum_strs NULL
@@ -386,42 +386,71 @@ static long readValue(histogramRecord *prec)
return(status);
}
+#define indexof(field) histogramRecord##field
+
+static long get_units(DBADDR *paddr, char *units)
+{
+ if (dbGetFieldIndex(paddr) == indexof(SDEL)) {
+ strcpy(units,"s");
+ }
+ /* We should have EGU for other DOUBLE values or probably get it from input link SVL */
+ return(0);
+}
+
static long get_precision(DBADDR *paddr,long *precision)
{
histogramRecord *prec=(histogramRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- *precision = prec->prec;
- if(fieldIndex == histogramRecordULIM
- || fieldIndex == histogramRecordLLIM
- || fieldIndex == histogramRecordSDEL
- || fieldIndex == histogramRecordSGNL
- || fieldIndex == histogramRecordSVAL
- || fieldIndex == histogramRecordWDTH) {
- *precision = prec->prec;
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(ULIM):
+ case indexof(LLIM):
+ case indexof(SGNL):
+ case indexof(SVAL):
+ case indexof(WDTH):
+ *precision = prec->prec;
+ break;
+ case indexof(SDEL):
+ *precision = 2;
+ break;
+ default:
+ recGblGetPrec(paddr,precision);
}
- recGblGetPrec(paddr,precision);
return(0);
}
+
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
histogramRecord *prec=(histogramRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == histogramRecordBPTR){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(BPTR):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ case indexof(WDTH):
+ pgd->upper_disp_limit = prec->ulim-prec->llim;
+ pgd->lower_disp_limit = 0.0;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
histogramRecord *prec=(histogramRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == histogramRecordBPTR){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(BPTR):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ case indexof(WDTH):
+ pcd->upper_ctrl_limit = prec->ulim-prec->llim;
+ pcd->lower_ctrl_limit = 0.0;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
diff --git a/src/rec/longinRecord.c b/src/rec/longinRecord.c
index 56904d1a5..34c21cb10 100644
--- a/src/rec/longinRecord.c
+++ b/src/rec/longinRecord.c
@@ -158,11 +158,15 @@ static long process(longinRecord *prec)
return(status);
}
+#define indexof(field) longinRecord##field
+
static long get_units(DBADDR *paddr,char *units)
{
longinRecord *prec=(longinRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_LONG) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return(0);
}
@@ -171,14 +175,22 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
longinRecord *prec=(longinRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
@@ -186,14 +198,22 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
longinRecord *prec=(longinRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
@@ -201,7 +221,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
longinRecord *prec=(longinRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val){
+ if(dbGetFieldIndex(paddr) == indexof(VAL)){
pad->upper_alarm_limit = prec->hihi;
pad->upper_warning_limit = prec->high;
pad->lower_warning_limit = prec->low;
diff --git a/src/rec/longoutRecord.c b/src/rec/longoutRecord.c
index 1de82e3ba..709286f5a 100644
--- a/src/rec/longoutRecord.c
+++ b/src/rec/longoutRecord.c
@@ -190,58 +190,73 @@ static long process(longoutRecord *prec)
return(status);
}
+#define indexof(field) longoutRecord##field
+
static long get_units(DBADDR *paddr,char *units)
{
longoutRecord *prec=(longoutRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_LONG) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return(0);
}
static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
{
longoutRecord *prec=(longoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
-
- if(fieldIndex == longoutRecordVAL
- || fieldIndex == longoutRecordHIHI
- || fieldIndex == longoutRecordHIGH
- || fieldIndex == longoutRecordLOW
- || fieldIndex == longoutRecordLOLO) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else recGblGetGraphicDouble(paddr,pgd);
+
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
return(0);
}
-
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
longoutRecord *prec=(longoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == longoutRecordVAL
- || fieldIndex == longoutRecordHIHI
- || fieldIndex == longoutRecordHIGH
- || fieldIndex == longoutRecordLOW
- || fieldIndex == longoutRecordLOLO) {
- /* do not change pre drvh/drvl behavior */
- if(prec->drvh > prec->drvl) {
- pcd->upper_ctrl_limit = prec->drvh;
- pcd->lower_ctrl_limit = prec->drvl;
- } else {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- }
- } else recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ /* do not change pre drvh/drvl behavior */
+ if(prec->drvh > prec->drvl) {
+ pcd->upper_ctrl_limit = prec->drvh;
+ pcd->lower_ctrl_limit = prec->drvl;
+ } else {
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ }
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
return(0);
}
+
static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
{
longoutRecord *prec=(longoutRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
- if(fieldIndex == longoutRecordVAL) {
+ if(dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hihi;
pad->upper_warning_limit = prec->high;
pad->lower_warning_limit = prec->low;
diff --git a/src/rec/selRecord.c b/src/rec/selRecord.c
index 4eef2d79a..884f85aba 100644
--- a/src/rec/selRecord.c
+++ b/src/rec/selRecord.c
@@ -132,11 +132,15 @@ static long process(selRecord *prec)
}
+#define indexof(field) selRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
selRecord *prec=(selRecord *)paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return(0);
}
@@ -166,56 +170,68 @@ static long get_precision(DBADDR *paddr, long *precision)
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
selRecord *prec=(selRecord *)paddr->precord;
-
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return(0);
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetGraphicDouble(paddr,pgd);
+ return(0);
}
-
- if(paddr->pfield>=(void *)&prec->a && paddr->pfield<=(void *)&prec->l){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return(0);
- }
- if(paddr->pfield>=(void *)&prec->la && paddr->pfield<=(void *)&prec->ll){
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- return(0);
- }
- recGblGetGraphicDouble(paddr,pgd);
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
return(0);
}
static long get_control_double(struct dbAddr *paddr, struct dbr_ctrlDouble *pcd)
{
selRecord *prec=(selRecord *)paddr->precord;
-
- if(paddr->pfield==(void *)&prec->val
- || paddr->pfield==(void *)&prec->hihi
- || paddr->pfield==(void *)&prec->high
- || paddr->pfield==(void *)&prec->low
- || paddr->pfield==(void *)&prec->lolo){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return(0);
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetControlDouble(paddr,pcd);
+ return(0);
}
-
- if(paddr->pfield>=(void *)&prec->a && paddr->pfield<=(void *)&prec->l){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return(0);
- }
- if(paddr->pfield>=(void *)&prec->la && paddr->pfield<=(void *)&prec->ll){
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- return(0);
- }
- recGblGetControlDouble(paddr,pcd);
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
return(0);
}
@@ -223,7 +239,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
selRecord *prec=(selRecord *)paddr->precord;
- if(paddr->pfield==(void *)&prec->val ){
+ if(dbGetFieldIndex(paddr) == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
diff --git a/src/rec/seqRecord.c b/src/rec/seqRecord.c
index 7c0d3dd42..5eff6d513 100644
--- a/src/rec/seqRecord.c
+++ b/src/rec/seqRecord.c
@@ -6,7 +6,7 @@
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
-
+
/*
* $Id$
*
@@ -39,34 +39,48 @@
int seqRecDebug = 0;
-/* Create RSET - Record Support Entry Table*/
-static long init_record(seqRecord *prec, int pass);
-static long process(seqRecord *prec);
static int processNextLink(seqRecord *prec);
static long asyncFinish(seqRecord *prec);
static void processCallback(CALLBACK *arg);
-static long get_precision(dbAddr *paddr, long *pprecision);
+
+/* Create RSET - Record Support Entry Table*/
+#define report NULL
+#define initialize NULL
+static long init_record(seqRecord *prec, int pass);
+static long process(seqRecord *prec);
+#define special NULL
+#define get_value NULL
+#define cvt_dbaddr NULL
+#define get_array_info NULL
+#define put_array_info NULL
+static long get_units(DBADDR *, char *);
+static long get_precision(dbAddr *paddr, long *);
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+#define get_graphic_double NULL
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+#define get_alarm_double NULL
rset seqRSET={
RSETNUMBER,
- NULL, /* report */
- NULL, /* initialize */
+ report, /* report */
+ initialize, /* initialize */
init_record, /* init_record */
process, /* process */
- NULL, /* special */
- NULL, /* get_value */
- NULL, /* cvt_dbaddr */
- NULL, /* get_array_info */
- NULL, /* put_array_info */
- NULL, /* get_units */
+ special, /* special */
+ get_value, /* get_value */
+ cvt_dbaddr, /* cvt_dbaddr */
+ get_array_info, /* get_array_info */
+ put_array_info, /* put_array_info */
+ get_units, /* get_units */
get_precision, /* get_precision */
- NULL, /* get_enum_str */
- NULL, /* get_enum_strs */
- NULL, /* put_enum_str */
- NULL, /* get_graphic_double */
- NULL, /* get_control_double */
- NULL /* get_alarm_double */
-
+ get_enum_str, /* get_enum_str */
+ get_enum_strs, /* get_enum_strs */
+ put_enum_str, /* put_enum_str */
+ get_graphic_double, /* get_graphic_double */
+ get_control_double, /* get_control_double */
+ get_alarm_double /* get_alarm_double */
};
epicsExportAddress(rset,seqRSET);
@@ -406,15 +420,84 @@ static void processCallback(CALLBACK *arg)
* Return the precision value from PREC
*
*****************************************************************************/
+#define indexof(field) seqRecord##field
+
+static long get_units(DBADDR *paddr, char *units)
+{
+ switch (dbGetFieldIndex(paddr)) {
+ /* we need something for DO1-DOA, either EGU1-EGUA or
+ read EGU from DOL1-DOLA if possible
+ */
+ case indexof(DLY1):
+ case indexof(DLY2):
+ case indexof(DLY3):
+ case indexof(DLY4):
+ case indexof(DLY5):
+ case indexof(DLY6):
+ case indexof(DLY7):
+ case indexof(DLY8):
+ case indexof(DLY9):
+ case indexof(DLYA):
+ strcpy(units, "s");
+ break;
+ case indexof(DO1):
+ case indexof(DO2):
+ case indexof(DO3):
+ case indexof(DO4):
+ case indexof(DO5):
+ case indexof(DO6):
+ case indexof(DO7):
+ case indexof(DO8):
+ case indexof(DO9):
+ case indexof(DOA):
+ /* we need something here, either EGU1-EGUA or
+ read EGU from DOL1-DOLA if possible
+ */
+ break;
+ }
+ return(0);
+}
+
static long get_precision(dbAddr *paddr, long *pprecision)
{
seqRecord *prec = (seqRecord *) paddr->precord;
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(DLY1):
+ case indexof(DLY2):
+ case indexof(DLY3):
+ case indexof(DLY4):
+ case indexof(DLY5):
+ case indexof(DLY6):
+ case indexof(DLY7):
+ case indexof(DLY8):
+ case indexof(DLY9):
+ case indexof(DLYA):
+ *pprecision = 2;
+ return(0);
+ /* maybe we need specific PRECs for DO1-DOA
+ */
+ }
*pprecision = prec->prec;
-
- if(paddr->pfield < (void *)&prec->val)
- return 0; /* Field is NOT in dbCommon */
-
- recGblGetPrec(paddr, pprecision); /* Field is in dbCommon */
- return 0;
+ recGblGetPrec(paddr, pprecision);
+ return(0);
+}
+
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+ recGblGetControlDouble(paddr,pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(DLY1):
+ case indexof(DLY2):
+ case indexof(DLY3):
+ case indexof(DLY4):
+ case indexof(DLY5):
+ case indexof(DLY6):
+ case indexof(DLY7):
+ case indexof(DLY8):
+ case indexof(DLY9):
+ case indexof(DLYA):
+ pcd->lower_ctrl_limit = 0.0;
+ }
+ return(0);
}
diff --git a/src/rec/subArrayRecord.c b/src/rec/subArrayRecord.c
index b6a167945..a8f06d077 100644
--- a/src/rec/subArrayRecord.c
+++ b/src/rec/subArrayRecord.c
@@ -201,25 +201,30 @@ static long put_array_info(DBADDR *paddr, long nNew)
return 0;
}
+#define indexof(field) subArrayRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
- strncpy(units, prec->egu, DB_UNITS_SIZE);
-
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+ break;
+ case indexof(HOPR):
+ case indexof(LOPR):
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return 0;
}
static long get_precision(DBADDR *paddr, long *precision)
{
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
*precision = prec->prec;
-
- if (fieldIndex != subArrayRecordVAL)
+ if (dbGetFieldIndex(paddr) != indexof(VAL))
recGblGetPrec(paddr, precision);
-
return 0;
}
@@ -228,25 +233,29 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
switch (dbGetFieldIndex(paddr)) {
- case subArrayRecordVAL:
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- break;
-
- case subArrayRecordINDX:
- pgd->upper_disp_limit = prec->malm - 1;
- pgd->lower_disp_limit = 0;
- break;
-
- case subArrayRecordNELM:
- pgd->upper_disp_limit = prec->malm;
- pgd->lower_disp_limit = 1;
- break;
-
- default:
- recGblGetGraphicDouble(paddr, pgd);
+ case indexof(VAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ case indexof(INDX):
+ pgd->upper_disp_limit = prec->malm - 1;
+ pgd->lower_disp_limit = 0;
+ break;
+ case indexof(NELM):
+ pgd->upper_disp_limit = prec->malm;
+ pgd->lower_disp_limit = 0;
+ break;
+ case indexof(NORD):
+ pgd->upper_disp_limit = prec->malm;
+ pgd->lower_disp_limit = 0;
+ break;
+ case indexof(BUSY):
+ pgd->upper_disp_limit = 1;
+ pgd->lower_disp_limit = 0;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr, pgd);
}
-
return 0;
}
@@ -255,25 +264,29 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
switch (dbGetFieldIndex(paddr)) {
- case subArrayRecordVAL:
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- break;
-
- case subArrayRecordINDX:
- pcd->upper_ctrl_limit = prec->malm - 1;
- pcd->lower_ctrl_limit = 0;
- break;
-
- case subArrayRecordNELM:
- pcd->upper_ctrl_limit = prec->malm;
- pcd->lower_ctrl_limit = 1;
- break;
-
- default:
- recGblGetControlDouble(paddr, pcd);
+ case indexof(VAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ case indexof(INDX):
+ pcd->upper_ctrl_limit = prec->malm - 1;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ case indexof(NELM):
+ pcd->upper_ctrl_limit = prec->malm;
+ pcd->lower_ctrl_limit = 1;
+ break;
+ case indexof(NORD):
+ pcd->upper_ctrl_limit = prec->malm;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ case indexof(BUSY):
+ pcd->upper_ctrl_limit = 1;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ default:
+ recGblGetControlDouble(paddr, pcd);
}
-
return 0;
}
diff --git a/src/rec/subRecord.c b/src/rec/subRecord.c
index 195097671..428e6d290 100644
--- a/src/rec/subRecord.c
+++ b/src/rec/subRecord.c
@@ -191,80 +191,107 @@ static long special(DBADDR *paddr, int after)
return S_db_BadSub;
}
+#define indexof(field) subRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
subRecord *prec = (subRecord *)paddr->precord;
+ int index = dbGetFieldIndex(paddr);
- strncpy(units, prec->egu, DB_UNITS_SIZE);
+ if(paddr->pfldDes->field_type == DBF_DOUBLE) {
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get units for A-L */;
+ } else {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ }
return 0;
}
-static long get_precision(DBADDR *paddr, long *precision)
+static long get_precision(DBADDR *paddr, long *pprecision)
{
subRecord *prec = (subRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
-
- *precision = prec->prec;
- if (fieldIndex != subRecordVAL)
- recGblGetPrec(paddr, precision);
+ int index = dbGetFieldIndex(paddr);
+ *pprecision = prec->prec;
+ if (index == indexof(VAL)) {
+ return 0;
+ }
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL))) {
+ /* We need a way to get precision for A-L */;
+ *pprecision=15;
+ }
+ recGblGetPrec(paddr, pprecision);
return 0;
}
-
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
subRecord *prec = (subRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
-
- switch (fieldIndex) {
- case subRecordVAL:
- case subRecordHIHI: case subRecordHIGH:
- case subRecordLOW: case subRecordLOLO:
- case subRecordA: case subRecordB:
- case subRecordC: case subRecordD:
- case subRecordE: case subRecordF:
- case subRecordG: case subRecordH:
- case subRecordI: case subRecordJ:
- case subRecordK: case subRecordL:
- case subRecordLA: case subRecordLB:
- case subRecordLC: case subRecordLD:
- case subRecordLE: case subRecordLF:
- case subRecordLG: case subRecordLH:
- case subRecordLI: case subRecordLJ:
- case subRecordLK: case subRecordLL:
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- break;
-
- default:
- recGblGetGraphicDouble(paddr, pgd);
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetGraphicDouble(paddr,pgd);
+ return 0;
}
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
return 0;
}
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
subRecord *prec = (subRecord *)paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
-
- switch (fieldIndex) {
- case subRecordVAL:
- case subRecordHIHI: case subRecordHIGH:
- case subRecordLOW: case subRecordLOLO:
- case subRecordA: case subRecordB:
- case subRecordC: case subRecordD:
- case subRecordE: case subRecordF:
- case subRecordG: case subRecordH:
- case subRecordI: case subRecordJ:
- case subRecordK: case subRecordL:
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- break;
-
- default:
- recGblGetControlDouble(paddr, pcd);
+ int index = dbGetFieldIndex(paddr);
+
+ switch (index) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+#ifdef __GNUC__
+ case indexof(A) ... indexof(L):
+ case indexof(LA) ... indexof(LL):
+ break;
+ default:
+#else
+ break;
+ default:
+ if((index >= indexof(A) && index <= indexof(L))
+ || (index >= indexof(LA) && index <= indexof(LL)))
+ break;
+#endif
+ recGblGetControlDouble(paddr,pcd);
+ return 0;
}
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
diff --git a/src/rec/waveformRecord.c b/src/rec/waveformRecord.c
index b36435fb6..967abad41 100644
--- a/src/rec/waveformRecord.c
+++ b/src/rec/waveformRecord.c
@@ -194,25 +194,30 @@ static long put_array_info(DBADDR *paddr, long nNew)
return 0;
}
+#define indexof(field) waveformRecord##field
+
static long get_units(DBADDR *paddr, char *units)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
- strncpy(units,prec->egu,DB_UNITS_SIZE);
-
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
+ break;
+ case indexof(HOPR):
+ case indexof(LOPR):
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
return 0;
}
static long get_precision(DBADDR *paddr, long *precision)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
- int fieldIndex = dbGetFieldIndex(paddr);
*precision = prec->prec;
-
- if (fieldIndex != waveformRecordVAL)
+ if (dbGetFieldIndex(paddr) != indexof(VAL))
recGblGetPrec(paddr, precision);
-
return 0;
}
@@ -220,11 +225,22 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
- if (dbGetFieldIndex(paddr) == waveformRecordVAL) {
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
- } else
- recGblGetGraphicDouble(paddr, pgd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ case indexof(BUSY):
+ pgd->upper_disp_limit = 1;
+ pgd->lower_disp_limit = 0;
+ break;
+ case indexof(NORD):
+ pgd->upper_disp_limit = prec->nelm;
+ pgd->lower_disp_limit = 0;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr, pgd);
+ }
return 0;
}
@@ -232,11 +248,22 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
- if (dbGetFieldIndex(paddr) == waveformRecordVAL) {
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
- } else
- recGblGetControlDouble(paddr, pcd);
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ case indexof(BUSY):
+ pcd->upper_ctrl_limit = 1;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ case indexof(NORD):
+ pcd->upper_ctrl_limit = prec->nelm;
+ pcd->lower_ctrl_limit = 0;
+ break;
+ default:
+ recGblGetControlDouble(paddr, pcd);
+ }
return 0;
}
From dc9e4ccc0420f29d8df03a69f9dc5cc901ec6290 Mon Sep 17 00:00:00 2001
From: Dirk Zimoch
Date: Wed, 26 May 2010 10:39:22 -0700
Subject: [PATCH 03/13] display limits for delays set to 0...10
---
src/rec/boRecord.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/rec/boRecord.c b/src/rec/boRecord.c
index 42d050b95..efc4b107f 100644
--- a/src/rec/boRecord.c
+++ b/src/rec/boRecord.c
@@ -272,23 +272,27 @@ static long process(boRecord *prec)
static long get_units(DBADDR *paddr, char *units)
{
- if(dbGetFieldIndex(paddr) == indexof(HIGH)) strcpy(units, "s");
+ if(dbGetFieldIndex(paddr) == indexof(HIGH))
+ strcpy(units, "s");
return(0);
}
static long get_precision(DBADDR *paddr, long *precision)
{
- if(dbGetFieldIndex(paddr) == indexof(HIGH)) *precision = 2;
- else recGblGetPrec(paddr,precision);
+ if(dbGetFieldIndex(paddr) == indexof(HIGH))
+ *precision = 2;
+ else
+ recGblGetPrec(paddr,precision);
return(0);
}
static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
- recGblGetControlDouble(paddr,pcd);
if(dbGetFieldIndex(paddr) == indexof(HIGH)) {
pcd->lower_ctrl_limit = 0.0;
- }
+ pcd->upper_ctrl_limit = 10.0;
+ } else
+ recGblGetControlDouble(paddr,pcd);
return(0);
}
From 27e80be2e54765000471144b7ff7067f565dd16e Mon Sep 17 00:00:00 2001
From: Dirk Zimoch
Date: Wed, 26 May 2010 10:42:16 -0700
Subject: [PATCH 04/13] read attributes of input fields from links
---
src/rec/calcRecord.c | 105 +++++++++++++++++----------------
src/rec/calcoutRecord.c | 117 +++++++++++++++++++-----------------
src/rec/seqRecord.c | 127 +++++++++++++++++++++-------------------
src/rec/subRecord.c | 96 +++++++++++++++---------------
4 files changed, 235 insertions(+), 210 deletions(-)
diff --git a/src/rec/calcRecord.c b/src/rec/calcRecord.c
index 75ae6ed00..ed82f9f91 100644
--- a/src/rec/calcRecord.c
+++ b/src/rec/calcRecord.c
@@ -150,18 +150,25 @@ static long special(DBADDR *paddr, int after)
#define indexof(field) calcRecord##field
+static long get_linkNumber(int fieldIndex) {
+ if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+ return fieldIndex - indexof(A);
+ if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+ return fieldIndex - indexof(LA);
+ return -1;
+}
+
static long get_units(DBADDR *paddr, char *units)
{
calcRecord *prec = (calcRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int linkNumber;
if(paddr->pfldDes->field_type == DBF_DOUBLE) {
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get units for A-L */;
- } else {
+ linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+ if (linkNumber >= 0)
+ dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+ else
strncpy(units,prec->egu,DB_UNITS_SIZE);
- }
}
return 0;
}
@@ -169,27 +176,32 @@ static long get_units(DBADDR *paddr, char *units)
static long get_precision(DBADDR *paddr, long *pprecision)
{
calcRecord *prec = (calcRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
*pprecision = prec->prec;
- if (index == indexof(VAL)) {
+ if (fieldIndex == indexof(VAL)) {
return 0;
}
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get precision for A-L */;
- *pprecision=15;
- }
- recGblGetPrec(paddr, pprecision);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ short precision;
+ if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+ *pprecision = precision;
+ else
+ *pprecision = 15;
+ } else
+ recGblGetPrec(paddr, pprecision);
return 0;
}
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
calcRecord *prec = (calcRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- switch (index) {
+ switch (fieldIndex) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -198,32 +210,26 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pgd->lower_disp_limit = prec->lopr;
+ pgd->upper_disp_limit = prec->hopr;
break;
default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
- recGblGetGraphicDouble(paddr,pgd);
- return 0;
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetGraphicLimits(&prec->inpa + linkNumber,
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ } else
+ recGblGetGraphicDouble(paddr,pgd);
}
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
return 0;
}
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
calcRecord *prec = (calcRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
- switch (index) {
+ switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -232,37 +238,36 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pcd->lower_ctrl_limit = prec->lopr;
+ pcd->upper_ctrl_limit = prec->hopr;
break;
default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
recGblGetControlDouble(paddr,pcd);
- return 0;
}
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
calcRecord *prec = (calcRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- if (dbGetFieldIndex(paddr) == indexof(VAL)) {
- pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
- pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
- pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
+ if (fieldIndex == indexof(VAL)) {
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
+ pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
+ pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
+ pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
} else {
- recGblGetAlarmDouble(paddr, pad);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetAlarmLimits(&prec->inpa + linkNumber,
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ } else
+ recGblGetAlarmDouble(paddr, pad);
}
return 0;
}
diff --git a/src/rec/calcoutRecord.c b/src/rec/calcoutRecord.c
index 795f1db66..750fdfd0a 100644
--- a/src/rec/calcoutRecord.c
+++ b/src/rec/calcoutRecord.c
@@ -365,23 +365,31 @@ static long special(DBADDR *paddr, int after)
#define indexof(field) calcoutRecord##field
+static long get_linkNumber(int fieldIndex) {
+ if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+ return fieldIndex - indexof(A);
+ if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+ return fieldIndex - indexof(LA);
+ return -1;
+}
+
static long get_units(DBADDR *paddr, char *units)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- if(index == indexof(ODLY)) {
+ if(fieldIndex == indexof(ODLY)) {
strcpy(units, "s");
return 0;
}
if(paddr->pfldDes->field_type == DBF_DOUBLE) {
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get units for A-L */;
- } else {
+ linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+ if (linkNumber >= 0)
+ dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+ else
strncpy(units,prec->egu,DB_UNITS_SIZE);
- }
}
return 0;
}
@@ -389,35 +397,36 @@ static long get_units(DBADDR *paddr, char *units)
static long get_precision(DBADDR *paddr, long *pprecision)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- if(index == indexof(ODLY)) {
+ if(fieldIndex == indexof(ODLY)) {
*pprecision = 2;
return 0;
}
-
*pprecision = prec->prec;
- if (index == indexof(VAL)) {
+ if (fieldIndex == indexof(VAL)) {
return 0;
}
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get precision for A-L */;
- *pprecision=15;
- }
- recGblGetPrec(paddr, pprecision);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ short precision;
+ if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+ *pprecision = precision;
+ else
+ *pprecision = 15;
+ } else
+ recGblGetPrec(paddr, pprecision);
return 0;
}
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
-
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- switch (index) {
- case indexof(ODLY):
- return 0;
+ switch (fieldIndex) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -426,32 +435,30 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pgd->lower_disp_limit = prec->lopr;
+ pgd->upper_disp_limit = prec->hopr;
break;
- default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
+ case indexof(ODLY):
recGblGetGraphicDouble(paddr,pgd);
- return 0;
+ pgd->lower_disp_limit = 0.0;
+ break;
+ default:
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetGraphicLimits(&prec->inpa + linkNumber,
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ } else
+ recGblGetGraphicDouble(paddr,pgd);
}
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
return 0;
}
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
- switch (index) {
+ switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -460,38 +467,40 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pcd->lower_ctrl_limit = prec->lopr;
+ pcd->upper_ctrl_limit = prec->hopr;
break;
+ case indexof(ODLY):
+ pcd->lower_ctrl_limit = 0.0;
+ pcd->upper_ctrl_limit = 10.0;
+ break;
default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
recGblGetControlDouble(paddr,pcd);
- if (index == indexof(ODLY)) pcd->lower_ctrl_limit = 0.0;
- return 0;
}
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
calcoutRecord *prec = (calcoutRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- if (dbGetFieldIndex(paddr) == indexof(VAL)) {
+ if (fieldIndex == indexof(VAL)) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN;
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
} else {
- recGblGetAlarmDouble(paddr, pad);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetAlarmLimits(&prec->inpa + linkNumber,
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ } else
+ recGblGetAlarmDouble(paddr, pad);
}
return 0;
}
diff --git a/src/rec/seqRecord.c b/src/rec/seqRecord.c
index 5eff6d513..1990aff0a 100644
--- a/src/rec/seqRecord.c
+++ b/src/rec/seqRecord.c
@@ -58,9 +58,9 @@ static long get_precision(dbAddr *paddr, long *);
#define get_enum_str NULL
#define get_enum_strs NULL
#define put_enum_str NULL
-#define get_graphic_double NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
-#define get_alarm_double NULL
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
rset seqRSET={
RSETNUMBER,
@@ -421,39 +421,21 @@ static void processCallback(CALLBACK *arg)
*
*****************************************************************************/
#define indexof(field) seqRecord##field
+#define get_dol(prec, fieldOffset) \
+ &((linkDesc*)&prec->dly1)[fieldOffset>>2].dol
static long get_units(DBADDR *paddr, char *units)
{
- switch (dbGetFieldIndex(paddr)) {
- /* we need something for DO1-DOA, either EGU1-EGUA or
- read EGU from DOL1-DOLA if possible
- */
- case indexof(DLY1):
- case indexof(DLY2):
- case indexof(DLY3):
- case indexof(DLY4):
- case indexof(DLY5):
- case indexof(DLY6):
- case indexof(DLY7):
- case indexof(DLY8):
- case indexof(DLY9):
- case indexof(DLYA):
+ seqRecord *prec = (seqRecord *) paddr->precord;
+ int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+ if (fieldOffset >= 0) switch (fieldOffset & 2) {
+ case 0: /* DLYn */
strcpy(units, "s");
break;
- case indexof(DO1):
- case indexof(DO2):
- case indexof(DO3):
- case indexof(DO4):
- case indexof(DO5):
- case indexof(DO6):
- case indexof(DO7):
- case indexof(DO8):
- case indexof(DO9):
- case indexof(DOA):
- /* we need something here, either EGU1-EGUA or
- read EGU from DOL1-DOLA if possible
- */
- break;
+ case 2: /* DOn */
+ dbGetUnits(get_dol(prec, fieldOffset),
+ units, DB_UNITS_SIZE);
}
return(0);
}
@@ -461,43 +443,68 @@ static long get_units(DBADDR *paddr, char *units)
static long get_precision(dbAddr *paddr, long *pprecision)
{
seqRecord *prec = (seqRecord *) paddr->precord;
+ int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+ short precision;
- switch (dbGetFieldIndex(paddr)) {
- case indexof(DLY1):
- case indexof(DLY2):
- case indexof(DLY3):
- case indexof(DLY4):
- case indexof(DLY5):
- case indexof(DLY6):
- case indexof(DLY7):
- case indexof(DLY8):
- case indexof(DLY9):
- case indexof(DLYA):
+ if (fieldOffset >= 0) switch (fieldOffset & 2) {
+ case 0: /* DLYn */
*pprecision = 2;
- return(0);
- /* maybe we need specific PRECs for DO1-DOA
- */
+ return 0;
+ case 2: /* DOn */
+ if (dbGetPrecision(get_dol(prec, fieldOffset),
+ &precision) == 0) {
+ *pprecision = precision;
+ return 0;
+ }
}
*pprecision = prec->prec;
recGblGetPrec(paddr, pprecision);
+ return 0;
+}
+
+static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
+{
+ seqRecord *prec = (seqRecord *) paddr->precord;
+ int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+ if (fieldOffset >= 0) switch (fieldOffset & 2) {
+ case 0: /* DLYn */
+ pgd->lower_disp_limit = 0.0;
+ pgd->lower_disp_limit = 10.0;
+ return 0;
+ case 2: /* DOn */
+ dbGetGraphicLimits(get_dol(prec, fieldOffset),
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ return 0;
+ }
+ recGblGetGraphicDouble(paddr,pgd);
+ return 0;
+}
+
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+ int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+ recGblGetControlDouble(paddr,pcd);
+ if (fieldOffset >= 0 && (fieldOffset & 2) == 0) /* DLYn */
+ pcd->lower_ctrl_limit = 0.0;
return(0);
}
-static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
- recGblGetControlDouble(paddr,pcd);
- switch (dbGetFieldIndex(paddr)) {
- case indexof(DLY1):
- case indexof(DLY2):
- case indexof(DLY3):
- case indexof(DLY4):
- case indexof(DLY5):
- case indexof(DLY6):
- case indexof(DLY7):
- case indexof(DLY8):
- case indexof(DLY9):
- case indexof(DLYA):
- pcd->lower_ctrl_limit = 0.0;
- }
- return(0);
+ seqRecord *prec = (seqRecord *) paddr->precord;
+ int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
+
+ if (fieldOffset >= 0 && (fieldOffset & 2) == 2) /* DOn */
+ dbGetAlarmLimits(get_dol(prec, fieldOffset),
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ else
+ recGblGetAlarmDouble(paddr, pad);
+ return 0;
}
+
diff --git a/src/rec/subRecord.c b/src/rec/subRecord.c
index 428e6d290..1d6a2a810 100644
--- a/src/rec/subRecord.c
+++ b/src/rec/subRecord.c
@@ -193,18 +193,25 @@ static long special(DBADDR *paddr, int after)
#define indexof(field) subRecord##field
+static long get_linkNumber(int fieldIndex) {
+ if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L))
+ return fieldIndex - indexof(A);
+ if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL))
+ return fieldIndex - indexof(LA);
+ return -1;
+}
+
static long get_units(DBADDR *paddr, char *units)
{
subRecord *prec = (subRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int linkNumber;
if(paddr->pfldDes->field_type == DBF_DOUBLE) {
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get units for A-L */;
- } else {
+ linkNumber = get_linkNumber(dbGetFieldIndex(paddr));
+ if (linkNumber >= 0)
+ dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+ else
strncpy(units,prec->egu,DB_UNITS_SIZE);
- }
}
return 0;
}
@@ -212,27 +219,32 @@ static long get_units(DBADDR *paddr, char *units)
static long get_precision(DBADDR *paddr, long *pprecision)
{
subRecord *prec = (subRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
*pprecision = prec->prec;
- if (index == indexof(VAL)) {
+ if (fieldIndex == indexof(VAL)) {
return 0;
}
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL))) {
- /* We need a way to get precision for A-L */;
- *pprecision=15;
- }
- recGblGetPrec(paddr, pprecision);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ short precision;
+ if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+ *pprecision = precision;
+ else
+ *pprecision = 15;
+ } else
+ recGblGetPrec(paddr, pprecision);
return 0;
}
static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
{
subRecord *prec = (subRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
- switch (index) {
+ switch (fieldIndex) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -241,32 +253,26 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pgd->lower_disp_limit = prec->lopr;
+ pgd->upper_disp_limit = prec->hopr;
break;
default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
- recGblGetGraphicDouble(paddr,pgd);
- return 0;
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetGraphicLimits(&prec->inpa + linkNumber,
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ } else
+ recGblGetGraphicDouble(paddr,pgd);
}
- pgd->upper_disp_limit = prec->hopr;
- pgd->lower_disp_limit = prec->lopr;
return 0;
}
static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
{
subRecord *prec = (subRecord *)paddr->precord;
- int index = dbGetFieldIndex(paddr);
- switch (index) {
+ switch (dbGetFieldIndex(paddr)) {
case indexof(VAL):
case indexof(HIHI):
case indexof(HIGH):
@@ -275,23 +281,12 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
case indexof(LALM):
case indexof(ALST):
case indexof(MLST):
-#ifdef __GNUC__
- case indexof(A) ... indexof(L):
- case indexof(LA) ... indexof(LL):
+ pcd->lower_ctrl_limit = prec->lopr;
+ pcd->upper_ctrl_limit = prec->hopr;
break;
default:
-#else
- break;
- default:
- if((index >= indexof(A) && index <= indexof(L))
- || (index >= indexof(LA) && index <= indexof(LL)))
- break;
-#endif
recGblGetControlDouble(paddr,pcd);
- return 0;
}
- pcd->upper_ctrl_limit = prec->hopr;
- pcd->lower_ctrl_limit = prec->lopr;
return 0;
}
@@ -299,6 +294,7 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
{
subRecord *prec = (subRecord *)paddr->precord;
int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
if (fieldIndex == subRecordVAL) {
pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN;
@@ -306,7 +302,15 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN;
pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN;
} else {
- recGblGetAlarmDouble(paddr, pad);
+ linkNumber = get_linkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetAlarmLimits(&prec->inpa + linkNumber,
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ } else
+ recGblGetAlarmDouble(paddr, pad);
}
return 0;
}
From e53753b76bd45594a8fc74f6751e9ae3537b835a Mon Sep 17 00:00:00 2001
From: Dirk Zimoch
Date: Wed, 26 May 2010 12:47:19 -0700
Subject: [PATCH 05/13] read attributes of input fields from links
---
src/rec/aSubRecord.c | 115 ++++++++++++++++++++++++++++++++++++++++---
1 file changed, 108 insertions(+), 7 deletions(-)
diff --git a/src/rec/aSubRecord.c b/src/rec/aSubRecord.c
index a4ecf4179..906748314 100644
--- a/src/rec/aSubRecord.c
+++ b/src/rec/aSubRecord.c
@@ -53,14 +53,14 @@ static long special(DBADDR *, int);
static long cvt_dbaddr(DBADDR *);
static long get_array_info(DBADDR *, long *, long *);
static long put_array_info(DBADDR *, long );
-#define get_units NULL
+static long get_units(DBADDR *, char *);
static long get_precision(DBADDR *, long *);
#define get_enum_str NULL
#define get_enum_strs NULL
#define put_enum_str NULL
-#define get_graphic_double NULL
-#define get_control_double NULL
-#define get_alarm_double NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
rset aSubRSET = {
RSETNUMBER,
@@ -330,15 +330,116 @@ static long fetch_values(aSubRecord *prec)
return 0;
}
-static long get_precision(DBADDR *paddr, long *precision)
+#define indexof(field) aSubRecord##field
+
+static long get_inlinkNumber(int fieldIndex) {
+ if (fieldIndex >= indexof(A) && fieldIndex <= indexof(U))
+ return fieldIndex - indexof(A);
+ return -1;
+}
+
+static long get_outlinkNumber(int fieldIndex) {
+ if (fieldIndex >= indexof(VALA) && fieldIndex <= indexof(VALU))
+ return fieldIndex - indexof(VALA);
+ return -1;
+}
+
+static long get_units(DBADDR *paddr, char *units)
{
aSubRecord *prec = (aSubRecord *)paddr->precord;
+ int linkNumber;
- *precision = prec->prec;
- recGblGetPrec(paddr, precision);
+ linkNumber = get_inlinkNumber(dbGetFieldIndex(paddr));
+ if (linkNumber >= 0) {
+ dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE);
+ return 0;
+ }
+ linkNumber = get_outlinkNumber(dbGetFieldIndex(paddr));
+ if (linkNumber >= 0) {
+ dbGetUnits(&prec->outa + linkNumber, units, DB_UNITS_SIZE);
+ }
return 0;
}
+static long get_precision(DBADDR *paddr, long *pprecision)
+{
+ aSubRecord *prec = (aSubRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
+ short precision;
+
+ *pprecision = prec->prec;
+ linkNumber = get_inlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0)
+ *pprecision = precision;
+ return 0;
+ }
+ linkNumber = get_outlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ if (dbGetPrecision(&prec->outa + linkNumber, &precision) == 0)
+ *pprecision = precision;
+ return 0;
+ }
+ recGblGetPrec(paddr, pprecision);
+ return 0;
+}
+
+static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
+{
+ aSubRecord *prec = (aSubRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
+
+ linkNumber = get_inlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetGraphicLimits(&prec->inpa + linkNumber,
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ return 0;
+ }
+ linkNumber = get_outlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetGraphicLimits(&prec->outa + linkNumber,
+ &pgd->lower_disp_limit,
+ &pgd->upper_disp_limit);
+ }
+ return 0;
+}
+
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+{
+ recGblGetControlDouble(paddr,pcd);
+ return 0;
+}
+
+static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
+{
+ aSubRecord *prec = (aSubRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+ int linkNumber;
+
+ linkNumber = get_inlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetAlarmLimits(&prec->inpa + linkNumber,
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ return 0;
+ }
+ linkNumber = get_outlinkNumber(fieldIndex);
+ if (linkNumber >= 0) {
+ dbGetAlarmLimits(&prec->outa + linkNumber,
+ &pad->lower_alarm_limit,
+ &pad->lower_warning_limit,
+ &pad->upper_warning_limit,
+ &pad->upper_alarm_limit);
+ return 0;
+ }
+ recGblGetAlarmDouble(paddr, pad);
+ return 0;
+}
static void monitor(aSubRecord *prec)
{
From 824d378117822298d803975bb4caec71de04d33c Mon Sep 17 00:00:00 2001
From: Kukhee Kim
Date: Fri, 28 May 2010 02:16:45 -0700
Subject: [PATCH 06/13] add the alarm filter for ai, calc, longin, mbbi type
records
---
src/std/rec/calcRecord.c | 142 +++++++++++++++++++++++++----------
src/std/rec/calcRecord.dbd | 10 +++
src/std/rec/longinRecord.c | 135 ++++++++++++++++++++++++---------
src/std/rec/longinRecord.dbd | 10 +++
src/std/rec/mbbiRecord.c | 46 +++++++++++-
src/std/rec/mbbiRecord.dbd | 10 +++
6 files changed, 274 insertions(+), 79 deletions(-)
diff --git a/src/std/rec/calcRecord.c b/src/std/rec/calcRecord.c
index 85e66f538..acbc85668 100644
--- a/src/std/rec/calcRecord.c
+++ b/src/std/rec/calcRecord.c
@@ -37,6 +37,9 @@
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
+/* Hysterisis for alarm filtering: 1-1/e */
+#define THRESHOLD 0.6321
+
/* Create RSET - Record Support Entry Table */
#define report NULL
@@ -79,7 +82,7 @@ rset calcRSET={
};
epicsExportAddress(rset, calcRSET);
-static void checkAlarms(calcRecord *prec);
+static void checkAlarms(calcRecord *prec, epicsTimeStamp *timeLast);
static void monitor(calcRecord *prec);
static int fetch_values(calcRecord *prec);
@@ -111,6 +114,8 @@ static long init_record(calcRecord *prec, int pass)
static long process(calcRecord *prec)
{
+ epicsTimeStamp timeLast;
+
prec->pact = TRUE;
if (fetch_values(prec) == 0) {
if (calcPerform(&prec->a, &prec->val, prec->rpcl)) {
@@ -118,9 +123,11 @@ static long process(calcRecord *prec)
} else
prec->udf = isnan(prec->val);
}
+
+ timeLast = prec->time;
recGblGetTimeStamp(prec);
/* check for alarms */
- checkAlarms(prec);
+ checkAlarms(prec, &timeLast);
/* check event list */
monitor(prec);
/* process the forward scan link record */
@@ -273,14 +280,27 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
return 0;
}
-static void checkAlarms(calcRecord *prec)
+static void checkAlarms(calcRecord *prec, epicsTimeStamp *timeLast)
{
- double val, hyst, lalm;
- double alev;
+
+ enum {
+ range_Lolo = 1,
+ range_Low,
+ range_Normal,
+ range_High,
+ range_Hihi
+ } alarmRange;
+ static const epicsEnum16 range_stat[] = {
+ SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
+ NO_ALARM, HIGH_ALARM, HIHI_ALARM
+ };
+
+ double val, hyst, lalm, alev, aftc, afvl;
epicsEnum16 asev;
if (prec->udf) {
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+ prec->afvl = 0;
return;
}
@@ -288,45 +308,89 @@ static void checkAlarms(calcRecord *prec)
hyst = prec->hyst;
lalm = prec->lalm;
- /* alarm condition hihi */
- asev = prec->hhsv;
- alev = prec->hihi;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIHI_ALARM, asev))
- prec->lalm = alev;
- return;
+ /* check VAL against alarm limits */
+ if ((asev = prec->hhsv) &&
+ (val >= (alev = prec->hihi) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_Hihi;
+ else
+ if ((asev = prec->llsv) &&
+ (val <= (alev = prec->lolo) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Lolo;
+ else
+ if ((asev = prec->hsv) &&
+ (val >= (alev = prec->high) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_High;
+ else
+ if ((asev = prec->lsv) &&
+ (val <= (alev = prec->low) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Low;
+ else {
+ alev = val;
+ asev = NO_ALARM;
+ alarmRange = range_Normal;
}
- /* alarm condition lolo */
- asev = prec->llsv;
- alev = prec->lolo;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOLO_ALARM, asev))
+ aftc = prec->aftc;
+ afvl = 0;
+
+ if (aftc > 0) {
+ /* Apply level filtering */
+ afvl = prec->afvl;
+ if (afvl == 0) {
+ afvl = (double)alarmRange;
+ } else {
+ double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
+ double alpha = aftc / (t + aftc);
+
+ /* The sign of afvl indicates whether the result should be
+ * rounded up or down. This gives the filter hysteresis.
+ * If afvl > 0 the floor() function rounds to a lower alarm
+ * level, otherwise to a higher.
+ */
+ afvl = alpha * afvl +
+ ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
+ if (afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl; /* reverse rounding */
+
+ alarmRange = abs((int)floor(afvl));
+ switch (alarmRange) {
+ case range_Hihi:
+ asev = prec->hhsv;
+ alev = prec->hihi;
+ break;
+ case range_High:
+ asev = prec->hsv;
+ alev = prec->high;
+ break;
+ case range_Normal:
+ asev = NO_ALARM;
+ break;
+ case range_Low:
+ asev = prec->lsv;
+ alev = prec->low;
+ break;
+ case range_Lolo:
+ asev = prec->llsv;
+ alev = prec->lolo;
+ break;
+ }
+ }
+ }
+ prec->afvl = afvl;
+
+ if (asev) {
+ /* Report alarm condition, store LALM for future HYST calculations */
+ if (recGblSetSevr(prec, range_stat[alarmRange], asev))
prec->lalm = alev;
- return;
+ } else {
+ /* No alarm condition, reset LALM */
+ prec->lalm = val;
}
- /* alarm condition high */
- asev = prec->hsv;
- alev = prec->high;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIGH_ALARM, asev))
- prec->lalm = alev;
- return;
- }
-
- /* alarm condition low */
- asev = prec->lsv;
- alev = prec->low;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOW_ALARM, asev))
- prec->lalm = alev;
- return;
- }
-
- /* we get here only if val is out of alarm by at least hyst */
- prec->lalm = val;
- return;
}
static void monitor(calcRecord *prec)
diff --git a/src/std/rec/calcRecord.dbd b/src/std/rec/calcRecord.dbd
index 0248f34cd..b4d4cc99b 100644
--- a/src/std/rec/calcRecord.dbd
+++ b/src/std/rec/calcRecord.dbd
@@ -153,6 +153,16 @@ recordtype(calc) {
interest(1)
menu(menuAlarmSevr)
}
+ field(AFTC, DBF_DOUBLE) {
+ prompt("Alarm Filter Time Constant")
+ promptgroup(GUI_ALARMS)
+ interest(1)
+ }
+ field(AFVL, DBF_DOUBLE) {
+ prompt("Alarm Filter Value")
+ special(SPC_NOMOD)
+ interest(3)
+ }
field(HYST,DBF_DOUBLE) {
prompt("Alarm Deadband")
promptgroup(GUI_ALARMS)
diff --git a/src/std/rec/longinRecord.c b/src/std/rec/longinRecord.c
index b41bbe506..a625b56e4 100644
--- a/src/std/rec/longinRecord.c
+++ b/src/std/rec/longinRecord.c
@@ -37,6 +37,8 @@
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
+/* Hysterisis for alarm filtering: 1-1/e */
+#define THRESHOLD 0.6321
/* Create RSET - Record Support Entry Table*/
#define report NULL
#define initialize NULL
@@ -87,7 +89,7 @@ struct longindset { /* longin input dset */
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_longin; /*returns: (-1,0)=>(failure,success)*/
};
-static void checkAlarms(longinRecord *prec);
+static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast);
static void monitor(longinRecord *prec);
static long readValue(longinRecord *prec);
@@ -132,12 +134,14 @@ static long process(longinRecord *prec)
struct longindset *pdset = (struct longindset *)(prec->dset);
long status;
unsigned char pact=prec->pact;
+ epicsTimeStamp timeLast;
if( (pdset==NULL) || (pdset->read_longin==NULL) ) {
prec->pact=TRUE;
recGblRecordError(S_dev_missingSup,(void *)prec,"read_longin");
return(S_dev_missingSup);
}
+ timeLast = prec->time;
status=readValue(prec); /* read the new value */
/* check if device support set pact */
@@ -148,7 +152,7 @@ static long process(longinRecord *prec)
if (status==0) prec->udf = FALSE;
/* check for alarms */
- checkAlarms(prec);
+ checkAlarms(prec, &timeLast);
/* check event list */
monitor(prec);
/* process the forward scan link record */
@@ -230,14 +234,28 @@ static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
return(0);
}
-static void checkAlarms(longinRecord *prec)
+static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast)
{
+ enum {
+ range_Lolo = 1,
+ range_Low,
+ range_Normal,
+ range_High,
+ range_Hihi
+ } alarmRange;
+ static const epicsEnum16 range_stat[] = {
+ SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
+ NO_ALARM, HIGH_ALARM, HIHI_ALARM
+ };
+
+ double aftc, afvl;
epicsInt32 val, hyst, lalm;
epicsInt32 alev;
epicsEnum16 asev;
if (prec->udf) {
recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+ prec->afvl = 0;
return;
}
@@ -245,45 +263,88 @@ static void checkAlarms(longinRecord *prec)
hyst = prec->hyst;
lalm = prec->lalm;
- /* alarm condition hihi */
- asev = prec->hhsv;
- alev = prec->hihi;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIHI_ALARM, asev))
- prec->lalm = alev;
- return;
+ /* check VAL against alarm limits */
+ if ((asev = prec->hhsv) &&
+ (val >= (alev = prec->hihi) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_Hihi;
+ else
+ if ((asev = prec->llsv) &&
+ (val <= (alev = prec->lolo) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Lolo;
+ else
+ if ((asev = prec->hsv) &&
+ (val >= (alev = prec->high) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_High;
+ else
+ if ((asev = prec->lsv) &&
+ (val <= (alev = prec->low) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Low;
+ else {
+ alev = val;
+ asev = NO_ALARM;
+ alarmRange = range_Normal;
}
- /* alarm condition lolo */
- asev = prec->llsv;
- alev = prec->lolo;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOLO_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ aftc = prec->aftc;
+ afvl = 0;
- /* alarm condition high */
- asev = prec->hsv;
- alev = prec->high;
- if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
- if (recGblSetSevr(prec, HIGH_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ if (aftc > 0) {
+ /* Apply level filtering */
+ afvl = prec->afvl;
+ if (afvl == 0) {
+ afvl = (double)alarmRange;
+ } else {
+ double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
+ double alpha = aftc / (t + aftc);
- /* alarm condition low */
- asev = prec->lsv;
- alev = prec->low;
- if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
- if (recGblSetSevr(prec, LOW_ALARM, asev))
- prec->lalm = alev;
- return;
- }
+ /* The sign of afvl indicates whether the result should be
+ * rounded up or down. This gives the filter hysteresis.
+ * If afvl > 0 the floor() function rounds to a lower alarm
+ * level, otherwise to a higher.
+ */
+ afvl = alpha * afvl +
+ ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
+ if (afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl; /* reverse rounding */
- /* we get here only if val is out of alarm by at least hyst */
- prec->lalm = val;
- return;
+ alarmRange = abs((int)floor(afvl));
+ switch (alarmRange) {
+ case range_Hihi:
+ asev = prec->hhsv;
+ alev = prec->hihi;
+ break;
+ case range_High:
+ asev = prec->hsv;
+ alev = prec->high;
+ break;
+ case range_Normal:
+ asev = NO_ALARM;
+ break;
+ case range_Low:
+ asev = prec->lsv;
+ alev = prec->low;
+ break;
+ case range_Lolo:
+ asev = prec->llsv;
+ alev = prec->lolo;
+ break;
+ }
+ }
+ }
+ prec->afvl = afvl;
+
+ if (asev) {
+ /* Report alarm condition, store LALM for future HYST calculations */
+ if (recGblSetSevr(prec, range_stat[alarmRange], asev))
+ prec->lalm = alev;
+ } else {
+ /* No alarm condition, reset LALM */
+ prec->lalm = val;
+ }
}
/* DELTA calculates the absolute difference between its arguments
diff --git a/src/std/rec/longinRecord.dbd b/src/std/rec/longinRecord.dbd
index 4bd734018..ef9506e3d 100644
--- a/src/std/rec/longinRecord.dbd
+++ b/src/std/rec/longinRecord.dbd
@@ -93,6 +93,16 @@ recordtype(longin) {
promptgroup(GUI_ALARMS)
interest(1)
}
+ field(AFTC, DBF_DOUBLE) {
+ prompt("Alarm Filter Time Constant")
+ promptgroup(GUI_ALARMS)
+ interest(1)
+ }
+ field(AFVL, DBF_DOUBLE) {
+ prompt("Alarm Filter Value")
+ special(SPC_NOMOD)
+ interest(3)
+ }
field(ADEL,DBF_LONG) {
prompt("Archive Deadband")
promptgroup(GUI_DISPLAY)
diff --git a/src/std/rec/mbbiRecord.c b/src/std/rec/mbbiRecord.c
index eddc188eb..fd8ebc98a 100644
--- a/src/std/rec/mbbiRecord.c
+++ b/src/std/rec/mbbiRecord.c
@@ -36,6 +36,9 @@
#include "mbbiRecord.h"
#undef GEN_SIZE_OFFSET
#include "epicsExport.h"
+
+/* Hysterisis for alarm filtering: 1-1/e */
+#define THRESHOLD 0.6321
/* Create RSET - Record Support Entry Table*/
#define report NULL
#define initialize NULL
@@ -84,7 +87,7 @@ struct mbbidset { /* multi bit binary input dset */
DEVSUPFUN get_ioint_info;
DEVSUPFUN read_mbbi;/*(0,2)=>(success, success no convert)*/
};
-static void checkAlarms(mbbiRecord *);
+static void checkAlarms(mbbiRecord *, epicsTimeStamp *);
static void monitor(mbbiRecord *);
static long readValue(mbbiRecord *);
@@ -146,6 +149,7 @@ static long process(mbbiRecord *prec)
struct mbbidset *pdset = (struct mbbidset *)(prec->dset);
long status;
unsigned char pact=prec->pact;
+ epicsTimeStamp timeLast;
if( (pdset==NULL) || (pdset->read_mbbi==NULL) ) {
prec->pact=TRUE;
@@ -153,6 +157,8 @@ static long process(mbbiRecord *prec)
return(S_dev_missingSup);
}
+ timeLast = prec->time;
+
status=readValue(prec); /* read the new value */
/* check if device support set pact */
if ( !pact && prec->pact ) return(0);
@@ -184,7 +190,7 @@ static long process(mbbiRecord *prec)
else if(status == 2) status = 0;
/* check for alarms */
- checkAlarms(prec);
+ checkAlarms(prec, &timeLast);
/* check event list */
monitor(prec);
@@ -279,14 +285,20 @@ static long put_enum_str(DBADDR *paddr, char *pstring)
return(S_db_badChoice);
}
-static void checkAlarms(mbbiRecord *prec)
+static void checkAlarms(mbbiRecord *prec, epicsTimeStamp *timeLast)
{
+
+ double aftc, afvl;
+
+ unsigned short alarm;
+ epicsEnum16 asev;
unsigned short *severities;
unsigned short val=prec->val;
/* check for udf alarm */
if(prec->udf == TRUE ){
recGblSetSevr(prec,UDF_ALARM,INVALID_ALARM);
+ prec->afvl = 0;
}
/* check for state alarm */
@@ -296,9 +308,37 @@ static void checkAlarms(mbbiRecord *prec)
} else {
/* in a state which is an error */
severities = (unsigned short *)&(prec->zrsv);
+ /*
recGblSetSevr(prec,STATE_ALARM,severities[prec->val]);
+ */
+ alarm = severities[prec->val];
+
}
+ aftc = prec->aftc;
+ afvl = 0.;
+
+ if(aftc > 0.) {
+ afvl = prec->afvl;
+ if(afvl == 0.) {
+ afvl = (double) alarm;
+ } else {
+ double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
+ double alpha = aftc / (t + aftc);
+
+ afvl = alpha * afvl +
+ ((afvl>0.)?(1.-alpha):(alpha-1.)) * alarm;
+ if(afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl;
+
+ alarm = abs((int)floor(afvl));
+ }
+ }
+
+
+ asev = alarm;
+ recGblSetSevr(prec, STATE_ALARM, asev);
+
/* check for cos alarm */
if(val == prec->lalm) return;
recGblSetSevr(prec,COS_ALARM,prec->cosv);
diff --git a/src/std/rec/mbbiRecord.dbd b/src/std/rec/mbbiRecord.dbd
index b0c33ad9e..bbb9fd17a 100644
--- a/src/std/rec/mbbiRecord.dbd
+++ b/src/std/rec/mbbiRecord.dbd
@@ -394,6 +394,16 @@ recordtype(mbbi) {
interest(1)
menu(menuAlarmSevr)
}
+ field(AFTC, DBF_DOUBLE) {
+ prompt("Alarm Filter Time Constant")
+ promptgroup(GUI_ALARMS)
+ interest(1)
+ }
+ field(AFVL, DBF_DOUBLE) {
+ prompt("Alarm Filter Value")
+ special(SPC_NOMOD)
+ interest(3)
+ }
field(UNSV,DBF_MENU) {
prompt("Unknown State Severity")
promptgroup(GUI_MBB)
From df9ec50b59c254e99585d0ec52871f76c4e9f9f3 Mon Sep 17 00:00:00 2001
From: Dirk Zimoch
Date: Fri, 28 May 2010 03:12:19 -0700
Subject: [PATCH 07/13] release notes updated
---
documentation/RELEASE_NOTES.html | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 9b3ce378e..fae4d5e75 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -12,6 +12,14 @@
Changes between 3.14.11 and 3.14.12
+Attributes of Non-VAL Fields
+
+Non-VAL fields now report meaningful information for precision, units,
+graphic limits, control limits, and alarm limits instead of simply using
+PREC, EGU, HOPR, LOPR, DRVL, DRVH, HIHI, HIGH, LOW, and LOLO. All delay
+fields have precision 2 and units "s". Input fields like A-L of the calc record
+read these information from the corresponding INPn link if possible.
+
Rewrite epicsThreadOnce()
Michael Davidsaver suggested a better implementation of epicsThreadOnce()
From ed18b6903e153e47777be4f9198f9f9d50a7e969 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Sat, 21 Jan 2012 15:31:39 -0600
Subject: [PATCH 08/13] Special processing events
When generating a DBE_PROPERTY event because of a modified
enum string, also post DBE_VALUE and DBE_LOG events if the
record is currently in that particular state.
---
src/std/rec/mbbiRecord.c | 33 +++++++++++++++++++--------------
src/std/rec/mbboRecord.c | 29 +++++++++++++++++------------
2 files changed, 36 insertions(+), 26 deletions(-)
diff --git a/src/std/rec/mbbiRecord.c b/src/std/rec/mbbiRecord.c
index 6a1ef943d..eddc188eb 100644
--- a/src/std/rec/mbbiRecord.c
+++ b/src/std/rec/mbbiRecord.c
@@ -1,6 +1,6 @@
/*************************************************************************\
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
-* 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.
@@ -197,22 +197,27 @@ static long process(mbbiRecord *prec)
}
-static long special(DBADDR *paddr,int after)
+static long special(DBADDR *paddr, int after)
{
- mbbiRecord *prec = (mbbiRecord *)(paddr->precord);
- int special_type = paddr->special;
- int fieldIndex = dbGetFieldIndex(paddr);
+ mbbiRecord *prec = (mbbiRecord *)(paddr->precord);
+ int special_type = paddr->special;
+ int fieldIndex = dbGetFieldIndex(paddr);
- if(!after) return(0);
- switch(special_type) {
- case(SPC_MOD):
- init_common(prec);
- if (fieldIndex >= mbbiRecordZRST && fieldIndex <= mbbiRecordFFST)
- db_post_events(prec,&prec->val,DBE_PROPERTY);
- return(0);
+ if (!after) return 0;
+ switch (special_type) {
+ case SPC_MOD:
+ init_common(prec);
+ if (fieldIndex >= mbbiRecordZRST && fieldIndex <= mbbiRecordFFST) {
+ int event = DBE_PROPERTY;
+
+ if (prec->val == fieldIndex - mbbiRecordZRST)
+ event |= DBE_VALUE | DBE_LOG;
+ db_post_events(prec, &prec->val, event);
+ }
+ return 0;
default:
- recGblDbaddrError(S_db_badChoice,paddr,"mbbi: special");
- return(S_db_badChoice);
+ recGblDbaddrError(S_db_badChoice, paddr, "mbbi: special");
+ return S_db_badChoice;
}
}
diff --git a/src/std/rec/mbboRecord.c b/src/std/rec/mbboRecord.c
index 5df97ff07..60ffaa34c 100644
--- a/src/std/rec/mbboRecord.c
+++ b/src/std/rec/mbboRecord.c
@@ -1,6 +1,6 @@
/*************************************************************************\
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
-* 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.
@@ -267,20 +267,25 @@ CONTINUE:
static long special(DBADDR *paddr, int after)
{
- mbboRecord *prec = (mbboRecord *)(paddr->precord);
- int special_type = paddr->special;
- int fieldIndex = dbGetFieldIndex(paddr);
+ mbboRecord *prec = (mbboRecord *)(paddr->precord);
+ int special_type = paddr->special;
+ int fieldIndex = dbGetFieldIndex(paddr);
- if(!after) return(0);
- switch(special_type) {
- case(SPC_MOD):
+ if (!after) return 0;
+ switch (special_type) {
+ case SPC_MOD:
init_common(prec);
- if (fieldIndex >= mbboRecordZRST && fieldIndex <= mbboRecordFFST)
- db_post_events(prec,&prec->val,DBE_PROPERTY);
- return(0);
+ if (fieldIndex >= mbboRecordZRST && fieldIndex <= mbboRecordFFST) {
+ int event = DBE_PROPERTY;
+
+ if (prec->val == fieldIndex - mbboRecordZRST)
+ event |= DBE_VALUE | DBE_LOG;
+ db_post_events(prec, &prec->val, event);
+ }
+ return 0;
default:
- recGblDbaddrError(S_db_badChoice,paddr,"mbbo: special");
- return(S_db_badChoice);
+ recGblDbaddrError(S_db_badChoice, paddr, "mbbo: special");
+ return S_db_badChoice;
}
}
From 0abfcc9445b9a20e437f4abb7ba71e23a90f47c2 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Sat, 21 Jan 2012 16:35:40 -0600
Subject: [PATCH 09/13] Replace fixed limits with global variables
Replaced Dirk's fixed precision=2 and limit=10 seconds with
global variables which can be set for each IOC. Also changed
the upper control limit for delay fields from 10 to 100,000.
---
documentation/RELEASE_NOTES.html | 7 +++++--
src/std/rec/boRecord.c | 9 +++++++--
src/std/rec/boRecord.dbd | 3 +++
src/std/rec/calcoutRecord.c | 13 +++++++++----
src/std/rec/calcoutRecord.dbd | 3 +++
src/std/rec/histogramRecord.c | 5 ++++-
src/std/rec/histogramRecord.dbd | 2 ++
src/std/rec/seqRecord.c | 13 ++++++++++---
src/std/rec/seqRecord.dbd | 3 +++
9 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 4ec06ada0..12d2fd709 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -20,8 +20,11 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Non-VAL fields now report meaningful information for precision, units,
graphic limits, control limits, and alarm limits instead of simply using
PREC, EGU, HOPR, LOPR, DRVL, DRVH, HIHI, HIGH, LOW, and LOLO. All delay
-fields have precision 2 and units "s". Input fields like A-L of the calc record
-read these information from the corresponding INPn link if possible.
+fields have a default precision of 2 digits, units "s" and control limits
+of 0 to 100,000 seconds (these precision and limit values can be changed
+for each record type as a whole at runtime by updating a registered global
+variable). Input fields like A-L of the calc record read their metadata
+from the corresponding INPn link if possible.
Changes to epicsVersion.h
diff --git a/src/std/rec/boRecord.c b/src/std/rec/boRecord.c
index e0e361c6f..ed6364734 100644
--- a/src/std/rec/boRecord.c
+++ b/src/std/rec/boRecord.c
@@ -82,6 +82,11 @@ rset boRSET={
};
epicsExportAddress(rset,boRSET);
+int boHIGHprecision = 2;
+epicsExportAddress(int, boHIGHprecision);
+double boHIGHlimit = 100000;
+epicsExportAddress(double, boHIGHlimit);
+
struct bodset { /* binary output dset */
long number;
DEVSUPFUN dev_report;
@@ -280,7 +285,7 @@ static long get_units(DBADDR *paddr, char *units)
static long get_precision(DBADDR *paddr, long *precision)
{
if(dbGetFieldIndex(paddr) == indexof(HIGH))
- *precision = 2;
+ *precision = boHIGHprecision;
else
recGblGetPrec(paddr,precision);
return(0);
@@ -290,7 +295,7 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
if(dbGetFieldIndex(paddr) == indexof(HIGH)) {
pcd->lower_ctrl_limit = 0.0;
- pcd->upper_ctrl_limit = 10.0;
+ pcd->upper_ctrl_limit = boHIGHlimit;
} else
recGblGetControlDouble(paddr,pcd);
return(0);
diff --git a/src/std/rec/boRecord.dbd b/src/std/rec/boRecord.dbd
index adc6704ad..4bc44c2fd 100644
--- a/src/std/rec/boRecord.dbd
+++ b/src/std/rec/boRecord.dbd
@@ -149,3 +149,6 @@ recordtype(bo) {
interest(2)
}
}
+
+variable(boHIGHprecision, int)
+variable(boHIGHlimit, double)
diff --git a/src/std/rec/calcoutRecord.c b/src/std/rec/calcoutRecord.c
index 1e7432465..88341eba9 100644
--- a/src/std/rec/calcoutRecord.c
+++ b/src/std/rec/calcoutRecord.c
@@ -83,7 +83,12 @@ rset calcoutRSET = {
get_alarm_double
};
epicsExportAddress(rset, calcoutRSET);
-
+
+int calcoutODLYprecision = 2;
+epicsExportAddress(int, calcoutODLYprecision);
+double calcoutODLYlimit = 100000;
+epicsExportAddress(double, calcoutODLYlimit);
+
typedef struct calcoutDSET {
long number;
DEVSUPFUN dev_report;
@@ -401,7 +406,7 @@ static long get_precision(DBADDR *paddr, long *pprecision)
int linkNumber;
if(fieldIndex == indexof(ODLY)) {
- *pprecision = 2;
+ *pprecision = calcoutODLYprecision;
return 0;
}
*pprecision = prec->prec;
@@ -472,8 +477,8 @@ static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
break;
case indexof(ODLY):
pcd->lower_ctrl_limit = 0.0;
- pcd->upper_ctrl_limit = 10.0;
- break;
+ pcd->upper_ctrl_limit = calcoutODLYlimit;
+ break;
default:
recGblGetControlDouble(paddr,pcd);
}
diff --git a/src/std/rec/calcoutRecord.dbd b/src/std/rec/calcoutRecord.dbd
index fc393a782..fd93fe0c4 100644
--- a/src/std/rec/calcoutRecord.dbd
+++ b/src/std/rec/calcoutRecord.dbd
@@ -504,3 +504,6 @@ recordtype(calcout) {
extra("char orpc[INFIX_TO_POSTFIX_SIZE(80)]")
}
}
+
+variable(calcoutODLYprecision, int)
+variable(calcoutODLYlimit, double)
diff --git a/src/std/rec/histogramRecord.c b/src/std/rec/histogramRecord.c
index a01dfb2ab..cb086d523 100644
--- a/src/std/rec/histogramRecord.c
+++ b/src/std/rec/histogramRecord.c
@@ -83,6 +83,9 @@ rset histogramRSET={
};
epicsExportAddress(rset,histogramRSET);
+int histogramSDELprecision = 2;
+epicsExportAddress(int, histogramSDELprecision);
+
struct histogramdset { /* histogram input dset */
long number;
DEVSUPFUN dev_report;
@@ -410,7 +413,7 @@ static long get_precision(DBADDR *paddr,long *precision)
*precision = prec->prec;
break;
case indexof(SDEL):
- *precision = 2;
+ *precision = histogramSDELprecision;
break;
default:
recGblGetPrec(paddr,precision);
diff --git a/src/std/rec/histogramRecord.dbd b/src/std/rec/histogramRecord.dbd
index 6def0f41a..dc0d2df31 100644
--- a/src/std/rec/histogramRecord.dbd
+++ b/src/std/rec/histogramRecord.dbd
@@ -135,3 +135,5 @@ recordtype(histogram) {
interest(1)
}
}
+
+variable(histogramSDELprecision, int)
diff --git a/src/std/rec/seqRecord.c b/src/std/rec/seqRecord.c
index 0394497f7..0537ebe52 100644
--- a/src/std/rec/seqRecord.c
+++ b/src/std/rec/seqRecord.c
@@ -84,6 +84,11 @@ rset seqRSET={
};
epicsExportAddress(rset,seqRSET);
+int seqDLYprecision = 2;
+epicsExportAddress(int, seqDLYprecision);
+double seqDLYlimit = 100000;
+epicsExportAddress(double, seqDLYlimit);
+
/* Total number of link-groups in a sequence record */
#define NUM_LINKS 10
#define SELN_BIT_MASK ~(0xffff << NUM_LINKS)
@@ -448,7 +453,7 @@ static long get_precision(dbAddr *paddr, long *pprecision)
if (fieldOffset >= 0) switch (fieldOffset & 2) {
case 0: /* DLYn */
- *pprecision = 2;
+ *pprecision = seqDLYprecision;
return 0;
case 2: /* DOn */
if (dbGetPrecision(get_dol(prec, fieldOffset),
@@ -486,9 +491,11 @@ static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
{
int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1);
- recGblGetControlDouble(paddr,pcd);
- if (fieldOffset >= 0 && (fieldOffset & 2) == 0) /* DLYn */
+ if (fieldOffset >= 0 && (fieldOffset & 2) == 0) { /* DLYn */
pcd->lower_ctrl_limit = 0.0;
+ pcd->upper_ctrl_limit = seqDLYlimit;
+ } else
+ recGblGetControlDouble(paddr,pcd);
return(0);
}
diff --git a/src/std/rec/seqRecord.dbd b/src/std/rec/seqRecord.dbd
index 518310220..ae183d2db 100644
--- a/src/std/rec/seqRecord.dbd
+++ b/src/std/rec/seqRecord.dbd
@@ -231,3 +231,6 @@ recordtype(seq) {
interest(1)
}
}
+
+variable(seqDLYprecision, int)
+variable(seqDLYlimit, double)
From 037e5f6a9def88cc5e1422788999fe3299c24c31 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Fri, 17 Feb 2012 17:32:25 -0600
Subject: [PATCH 10/13] Post events on waveform.NORD field changes
Set "Rec Proc Monitor" column in the Record Reference Manual to Yes.
---
documentation/RELEASE_NOTES.html | 7 +++++++
src/std/dev/devWfSoft.c | 2 ++
src/std/rec/waveformRecord.c | 4 +++-
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 12d2fd709..100cf023c 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -15,6 +15,13 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Changes between 3.14.x and 3.15.0.x
+Post events on Waveform record's NORD field
+
+When the record type or soft device support modify the NORD field of a
+waveform record they now also post a DBE_VALUE and DBE_LOG event, signalling the
+array length change to any clients monitoring the NORD field. Input device
+support routines should be modified to do this as well.
+
Attributes of Non-VAL Fields
Non-VAL fields now report meaningful information for precision, units,
diff --git a/src/std/dev/devWfSoft.c b/src/std/dev/devWfSoft.c
index 92bb3c566..ea9280051 100644
--- a/src/std/dev/devWfSoft.c
+++ b/src/std/dev/devWfSoft.c
@@ -20,6 +20,7 @@
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
+#include "dbEvent.h"
#include "recGbl.h"
#include "devSup.h"
#include "waveformRecord.h"
@@ -75,6 +76,7 @@ static long read_wf(waveformRecord *prec)
if (prec->tsel.type == CONSTANT &&
prec->tse == epicsTimeEventDeviceTime)
dbGetTimeStamp(&prec->inp, &prec->time);
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
}
return 0;
diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c
index 95219a70a..006de248d 100644
--- a/src/std/rec/waveformRecord.c
+++ b/src/std/rec/waveformRecord.c
@@ -177,7 +177,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
{
waveformRecord *prec = (waveformRecord *) paddr->precord;
- *no_elements = prec->nord;
+ *no_elements = prec->nord;
*offset = 0;
return 0;
@@ -191,6 +191,7 @@ static long put_array_info(DBADDR *paddr, long nNew)
if (prec->nord > prec->nelm)
prec->nord = prec->nelm;
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
return 0;
}
@@ -327,6 +328,7 @@ static long readValue(waveformRecord *prec)
/* nord set only for db links: needed for old db_access */
if (prec->siol.type != CONSTANT) {
prec->nord = nRequest;
+ db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
if (status == 0)
prec->udf=FALSE;
}
From d9e066ac29a2b30809a3544a99f5e624aef419e0 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Fri, 9 Mar 2012 12:22:45 -0600
Subject: [PATCH 11/13] Documentation on alarm filtering (AFTC field)
---
documentation/RELEASE_NOTES.html | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index 100cf023c..1d9fd1f75 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -15,6 +15,23 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Changes between 3.14.x and 3.15.0.x
+Alarm filtering added to input record types
+
+The record types ai, calc, longin and mbbi have a new alarm filter added to
+them. This provides a low-pass filter that can be used to delay the reporting of
+alarms caused by the input level passing the HIGH, HIHI, LOW or LOLO values. The
+filter is controlled with a new AFTC field that sets the filter's time constant.
+The default value for this field is zero, which keeps the record's original
+alarm behaviour.
+
+The record must be scanned often enough for the filtering action to work
+effectively and the alarm severity can only change when the record is processed,
+but that processing does not have to be regular; the filter uses the time since
+the record last processed in its calculation. Setting AFTC to a positive number
+of seconds will delay the record going into or out of a minor alarm severity or
+from minor to major severity until the input signal has been in that range for
+that number of seconds.
+
Post events on Waveform record's NORD field
When the record type or soft device support modify the NORD field of a
From 4c98463b0110e24d74452cecc245e7aacbe8e9aa Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Mon, 12 Mar 2012 11:24:47 -0500
Subject: [PATCH 12/13] rec/ai: Delete ancient, unused, commented-out function
prototype.
---
src/std/rec/aiRecord.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/std/rec/aiRecord.c b/src/std/rec/aiRecord.c
index 7f2ce4bde..94f665af7 100644
--- a/src/std/rec/aiRecord.c
+++ b/src/std/rec/aiRecord.c
@@ -97,11 +97,6 @@ typedef struct aidset { /* analog input dset */
}aidset;
-/*Following from timing system */
-/*
-extern unsigned int gts_trigger_counter;
-*/
-
static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime);
static void convert(aiRecord *prec);
static void monitor(aiRecord *prec);
From bd53941ac4bdd5934b872d9b0f94adc04c238f79 Mon Sep 17 00:00:00 2001
From: Andrew Johnson
Date: Mon, 18 Jun 2012 12:13:14 -0500
Subject: [PATCH 13/13] Cleanup of mbbi, mbbo record code.
Mostly just layout changes, removing unnecessary casts, and
replacing 'unsigned short' with epicsEnum16 types.
The only significant code change is in the alarm filtering
code of the mbbi record, which wasn't handling UDF alarms
or unknown state alarms quite right.
---
src/std/rec/mbbiRecord.c | 494 +++++++++++++++++++------------------
src/std/rec/mbboRecord.c | 513 ++++++++++++++++++++-------------------
2 files changed, 513 insertions(+), 494 deletions(-)
diff --git a/src/std/rec/mbbiRecord.c b/src/std/rec/mbbiRecord.c
index fd8ebc98a..3bdffe12e 100644
--- a/src/std/rec/mbbiRecord.c
+++ b/src/std/rec/mbbiRecord.c
@@ -27,6 +27,7 @@
#include "dbEvent.h"
#include "dbFldTypes.h"
#include "devSup.h"
+#include "epicsMath.h"
#include "errMdef.h"
#include "menuSimm.h"
#include "recSup.h"
@@ -39,6 +40,7 @@
/* Hysterisis for alarm filtering: 1-1/e */
#define THRESHOLD 0.6321
+
/* Create RSET - Record Support Entry Table*/
#define report NULL
#define initialize NULL
@@ -57,56 +59,56 @@ static long put_enum_str(DBADDR *, char *);
#define get_graphic_double NULL
#define get_control_double NULL
#define get_alarm_double NULL
-rset mbbiRSET={
- 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 mbbiRSET = {
+ 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,mbbiRSET);
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;/* (0, 2) => (success, success no convert)*/
};
+
static void checkAlarms(mbbiRecord *, epicsTimeStamp *);
static void monitor(mbbiRecord *);
static long readValue(mbbiRecord *);
static void init_common(mbbiRecord *prec)
{
- epicsUInt32 *pstate_values;
- char *pstate_string;
- short i;
+ epicsUInt32 *pstate_values = &prec->zrvl;
+ char *pstate_string = prec->zrst;
+ int i;
- /* determine if any states are defined */
- pstate_values = &(prec->zrvl); pstate_string = prec->zrst;
- prec->sdef = FALSE;
- for (i=0; i<16; i++, pstate_string += sizeof(prec->zrst)) {
- if((*(pstate_values+i) != 0) || (*pstate_string !='\0')) {
- prec->sdef = TRUE;
- return;
- }
- }
- return;
+ /* Check if any states are defined */
+ for (i = 0; i < 16; i++, pstate_string += sizeof(prec->zrst)) {
+ if ((pstate_values[i] != 0) || (*pstate_string != '\0')) {
+ prec->sdef = TRUE;
+ return;
+ }
+ }
+ prec->sdef = FALSE;
}
static long init_record(mbbiRecord *prec, int pass)
@@ -114,98 +116,113 @@ static long init_record(mbbiRecord *prec, int pass)
struct mbbidset *pdset;
long status;
- if (pass==0) return(0);
+ if (pass == 0)
+ return 0;
if (prec->siml.type == CONSTANT) {
- recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
+ recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
}
if (prec->siol.type == CONSTANT) {
- recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval);
+ recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
}
- if(!(pdset = (struct mbbidset *)(prec->dset))) {
- recGblRecordError(S_dev_noDSET,(void *)prec,"mbbi: init_record");
- return(S_dev_noDSET);
+
+ pdset = (struct mbbidset *) prec->dset;
+ if (!pdset) {
+ recGblRecordError(S_dev_noDSET, prec, "mbbi: 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,"mbbi: init_record");
- return(S_dev_missingSup);
+ if ((pdset->number < 5) || (pdset->read_mbbi == NULL)) {
+ recGblRecordError(S_dev_missingSup, prec, "mbbi: init_record");
+ return S_dev_missingSup;
}
- /* initialize mask*/
- prec->mask = (1 << prec->nobt) - 1;
- if( pdset->init_record ) {
- if((status=(*pdset->init_record)(prec))) return(status);
+ /* 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);
}
+ else
+ status = 0;
+
init_common(prec);
prec->mlst = prec->val;
prec->lalm = prec->val;
prec->oraw = prec->rval;
- return(0);
+ return status;
}
static long process(mbbiRecord *prec)
{
- struct mbbidset *pdset = (struct mbbidset *)(prec->dset);
- long status;
- unsigned char pact=prec->pact;
- epicsTimeStamp timeLast;
+ struct mbbidset *pdset = (struct mbbidset *) prec->dset;
+ long status;
+ int pact = prec->pact;
+ epicsTimeStamp timeLast;
- 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;
+ }
- timeLast = prec->time;
+ timeLast = prec->time;
- status=readValue(prec); /* read the new value */
- /* check if device support set pact */
- if ( !pact && prec->pact ) return(0);
- prec->pact = TRUE;
+ status = readValue(prec); /* read the new value */
+ /* check if device support set pact */
+ if (!pact && prec->pact)
+ return 0;
+ prec->pact = TRUE;
- recGblGetTimeStamp(prec);
- if(status==0) { /* convert the value */
- epicsUInt32 *pstate_values;
- short i;
- epicsUInt32 rval = prec->rval;
+ recGblGetTimeStamp(prec);
+ if (status == 0) { /* convert the value */
+ epicsUInt32 *pstate_values;
+ short i;
+ epicsUInt32 rval = prec->rval;
- prec->udf = FALSE;
- if(prec->shft>0) rval >>= prec->shft;
- if (prec->sdef){
- pstate_values = &(prec->zrvl);
- prec->val = 65535; /* initalize to unknown state*/
- for (i = 0; i < 16; i++){
- if (*pstate_values == rval){
- prec->val = i;
- break;
- }
- pstate_values++;
- }
- }else{
- /* the raw value is the desired value */
- prec->val = (unsigned short)rval;
- }
- }
- else if(status == 2) status = 0;
+ prec->udf = FALSE;
+ if (prec->shft > 0)
+ rval >>= prec->shft;
+ if (prec->sdef) {
+ pstate_values = &(prec->zrvl);
+ prec->val = 65535; /* initalize to unknown state*/
+ for (i = 0; i < 16; i++) {
+ if (*pstate_values == rval) {
+ prec->val = i;
+ break;
+ }
+ pstate_values++;
+ }
+ }
+ else {
+ /* the raw value is the desired value */
+ prec->val = rval;
+ }
+ }
+ else {
+ if (status == 2) {
+ status = 0;
+ }
+ }
- /* check for alarms */
- checkAlarms(prec, &timeLast);
+ /* check for alarms */
+ checkAlarms(prec, &timeLast);
- /* check event list */
- monitor(prec);
+ /* check event list */
+ monitor(prec);
- /* process the forward scan link record */
- recGblFwdLink(prec);
+ /* process the forward scan link record */
+ recGblFwdLink(prec);
- prec->pact=FALSE;
- return(status);
+ prec->pact=FALSE;
+ return status;
}
static long special(DBADDR *paddr, int after)
{
- mbbiRecord *prec = (mbbiRecord *)(paddr->precord);
+ mbbiRecord *prec = (mbbiRecord *) paddr->precord;
int special_type = paddr->special;
int fieldIndex = dbGetFieldIndex(paddr);
@@ -227,187 +244,184 @@ static long special(DBADDR *paddr, int after)
}
}
-static long get_enum_str(DBADDR *paddr,char* pstring)
+static long get_enum_str(DBADDR *paddr, char *pstring)
{
- mbbiRecord *prec=(mbbiRecord *)paddr->precord;
- char *psource;
- int index;
- unsigned short *pfield = (unsigned short *)paddr->pfield;
- unsigned short val=*pfield;
+ mbbiRecord *prec = (mbbiRecord *) paddr->precord;
+ int index;
+ unsigned short *pfield = paddr->pfield;
+ epicsEnum16 val = *pfield;
index = dbGetFieldIndex(paddr);
- if(index!=mbbiRecordVAL) {
- strcpy(pstring,"Illegal_Value");
- } else if(val<= 15) {
- psource = (prec->zrst);
- psource += (val * sizeof(prec->zrst));
- strncpy(pstring,psource,sizeof(prec->zrst));
- } else {
- strcpy(pstring,"Illegal Value");
+ if (index != mbbiRecordVAL) {
+ strcpy(pstring, "Illegal_Value");
}
- return(0);
+ else if (val <= 15) {
+ char *pstate = prec->zrst + val * sizeof(prec->zrst);
+
+ strncpy(pstring, pstate, sizeof(prec->zrst));
+ }
+ else {
+ strcpy(pstring, "Illegal Value");
+ }
+ return 0;
}
static long get_enum_strs(DBADDR *paddr, struct dbr_enumStrs *pes)
{
- mbbiRecord *prec=(mbbiRecord *)paddr->precord;
- char *psource;
- int i;
- short no_str;
+ mbbiRecord *prec = (mbbiRecord *) paddr->precord;
+ char *pstate = prec->zrst;
+ int i;
+ short states = 0;
- no_str = 0;
- memset(pes->strs,'\0',sizeof(pes->strs));
- for(i=0,psource=(prec->zrst); i<16; i++, psource += sizeof(prec->zrst) ) {
- strncpy(pes->strs[i],psource,sizeof(prec->zrst));
- if(*psource!=0) no_str=i+1;
+ memset(pes->strs, '\0', sizeof(pes->strs));
+ for (i = 0; i < 16; i++, pstate += sizeof(prec->zrst) ) {
+ strncpy(pes->strs[i], pstate, sizeof(prec->zrst));
+ if (*pstate!=0) states = i+1;
}
- pes->no_str=no_str;
- return(0);
+ pes->no_str = states;
+ return 0;
}
static long put_enum_str(DBADDR *paddr, char *pstring)
{
- mbbiRecord *prec=(mbbiRecord *)paddr->precord;
- char *pstate_name;
- short i;
+ mbbiRecord *prec = (mbbiRecord *) paddr->precord;
+ char *pstate;
+ short i;
- if (prec->sdef){
- pstate_name = prec->zrst;
- for (i = 0; i < 16; i++){
- if(strncmp(pstate_name,pstring,sizeof(prec->zrst))==0){
- prec->val = i;
- prec->udf = FALSE;
- return(0);
- }
- pstate_name += sizeof(prec->zrst);
- }
+ if (prec->sdef) {
+ pstate = prec->zrst;
+ for (i = 0; i < 16; i++) {
+ if (strncmp(pstate, pstring, sizeof(prec->zrst)) == 0) {
+ prec->val = i;
+ prec->udf = FALSE;
+ return 0;
+ }
+ pstate += sizeof(prec->zrst);
}
- return(S_db_badChoice);
+ }
+ return S_db_badChoice;
}
static void checkAlarms(mbbiRecord *prec, epicsTimeStamp *timeLast)
{
-
double aftc, afvl;
-
- unsigned short alarm;
- epicsEnum16 asev;
- unsigned short *severities;
- unsigned short val=prec->val;
+ unsigned short alarm;
+ epicsEnum16 asev;
+ epicsEnum16 val = prec->val;
- /* check for udf alarm */
- if(prec->udf == TRUE ){
- recGblSetSevr(prec,UDF_ALARM,INVALID_ALARM);
- prec->afvl = 0;
+ /* check for udf alarm */
+ if (prec->udf) {
+ recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+ prec->afvl = 0;
+ return;
+ }
+
+ /* check for state alarm */
+ if (val > 15) {
+ /* Unknown state */
+ alarm = prec->unsv;
+ }
+ else {
+ /* State has a severity field */
+ epicsEnum16 *severities = &prec->zrsv;
+
+ alarm = severities[prec->val];
+ }
+
+ aftc = prec->aftc;
+ afvl = 0;
+
+ if (aftc > 0) {
+ afvl = prec->afvl;
+ if (afvl == 0) {
+ afvl = (double) alarm;
}
+ else {
+ double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
+ double alpha = aftc / (t + aftc);
- /* check for state alarm */
- /* unknown state */
- if (val > 15){
- recGblSetSevr(prec,STATE_ALARM,prec->unsv);
- } else {
- /* in a state which is an error */
- severities = (unsigned short *)&(prec->zrsv);
- /*
- recGblSetSevr(prec,STATE_ALARM,severities[prec->val]);
- */
- alarm = severities[prec->val];
+ afvl = alpha * afvl +
+ ((afvl > 0) ? (1.0 - alpha) : (alpha - 1.0)) * alarm;
+ if (afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl;
- }
+ alarm = abs((int)floor(afvl));
+ }
+ }
- aftc = prec->aftc;
- afvl = 0.;
+ asev = alarm;
+ recGblSetSevr(prec, STATE_ALARM, asev);
- if(aftc > 0.) {
- afvl = prec->afvl;
- if(afvl == 0.) {
- afvl = (double) alarm;
- } else {
- double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
- double alpha = aftc / (t + aftc);
+ /* check for cos alarm */
+ if (val == prec->lalm)
+ return;
- afvl = alpha * afvl +
- ((afvl>0.)?(1.-alpha):(alpha-1.)) * alarm;
- if(afvl - floor(afvl) > THRESHOLD)
- afvl = -afvl;
-
- alarm = abs((int)floor(afvl));
- }
- }
-
-
- asev = alarm;
- recGblSetSevr(prec, STATE_ALARM, asev);
-
- /* check for cos alarm */
- if(val == prec->lalm) return;
- recGblSetSevr(prec,COS_ALARM,prec->cosv);
- prec->lalm = val;
- return;
+ recGblSetSevr(prec, COS_ALARM, prec->cosv);
+ prec->lalm = val;
}
static void monitor(mbbiRecord *prec)
{
- unsigned short monitor_mask;
+ unsigned short monitor_mask;
- monitor_mask = recGblResetAlarms(prec);
- /* check for value change */
- if (prec->mlst != prec->val){
- /* post events for value change and archive change */
- monitor_mask |= (DBE_VALUE | DBE_LOG);
- /* update last value monitored */
- prec->mlst = prec->val;
- }
- /* 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);
- prec->oraw = prec->rval;
- }
- return;
+ monitor_mask = recGblResetAlarms(prec);
+ /* check for value change */
+ if (prec->mlst != prec->val) {
+ /* post events for value change and archive change */
+ monitor_mask |= (DBE_VALUE | DBE_LOG);
+ /* update last value monitored */
+ prec->mlst = prec->val;
+ }
+ /* send out monitors connected to the value field */
+ if (monitor_mask) {
+ db_post_events(prec, &prec->val, monitor_mask);
+ }
+ if (prec->oraw != prec->rval) {
+ db_post_events(prec, &prec->rval, monitor_mask | DBE_VALUE);
+ prec->oraw = prec->rval;
+ }
}
static long readValue(mbbiRecord *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) {
+ status = pdset->read_mbbi(prec);
+ return status;
+ }
- status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
- if (status)
- return(status);
+ status = dbGetLink(&prec->siml, DBR_USHORT, &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; /* dont 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);
+ 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 = prec->sval;
+ prec->udf = FALSE;
+ }
+ status = 2; /* dont 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);
- return(status);
+ return status;
}
diff --git a/src/std/rec/mbboRecord.c b/src/std/rec/mbboRecord.c
index 60ffaa34c..c2fc5e84c 100644
--- a/src/std/rec/mbboRecord.c
+++ b/src/std/rec/mbboRecord.c
@@ -60,35 +60,35 @@ static long put_enum_str(DBADDR *, char *);
#define get_control_double NULL
#define get_alarm_double NULL
-rset mbboRSET={
- 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 mbboRSET = {
+ 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,mbboRSET);
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)*/
};
@@ -100,178 +100,183 @@ static long writeValue(mbboRecord *);
static void init_common(mbboRecord *prec)
{
- epicsUInt32 *pstate_values;
- char *pstate_string;
- short i;
+ epicsUInt32 *pstate_values = &prec->zrvl;
+ char *pstate_string = prec->zrst;
+ int i;
- /* determine if any states are defined */
- pstate_values = &(prec->zrvl); pstate_string = prec->zrst;
- prec->sdef = FALSE;
- for (i=0; i<16; i++, pstate_string += sizeof(prec->zrst)) {
- if((*(pstate_values+i)!= 0) || (*pstate_string !='\0')) {
- prec->sdef = TRUE;
- return;
- }
+ /* Check if any states are defined */
+ for (i = 0; i < 16; i++, pstate_string += sizeof(prec->zrst)) {
+ if ((pstate_values[i] != 0) || (*pstate_string != '\0')) {
+ prec->sdef = TRUE;
+ return;
}
- return;
+ }
+ prec->sdef = FALSE;
}
static long init_record(mbboRecord *prec, int pass)
{
struct mbbodset *pdset;
long status;
- int i;
- if (pass==0) {
+ if (pass == 0) {
init_common(prec);
- return(0);
+ return 0;
}
- /* mbbo.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);
+ recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
}
- if(!(pdset = (struct mbbodset *)(prec->dset))) {
- recGblRecordError(S_dev_noDSET,(void *)prec,"mbbo: init_record");
- return(S_dev_noDSET);
+ pdset = (struct mbbodset *) prec->dset;
+ if (!pdset) {
+ recGblRecordError(S_dev_noDSET, prec, "mbbo: init_record");
+ return S_dev_noDSET;
}
/* must have write_mbbo function defined */
- if( (pdset->number < 5) || (pdset->write_mbbo == NULL) ) {
- recGblRecordError(S_dev_missingSup,(void *)prec,"mbbo: init_record");
- return(S_dev_missingSup);
+ if ((pdset->number < 5) || (pdset->write_mbbo == NULL)) {
+ recGblRecordError(S_dev_missingSup, prec, "mbbo: init_record");
+ return S_dev_missingSup;
}
- if (prec->dol.type == CONSTANT){
- if(recGblInitConstantLink(&prec->dol,DBF_USHORT,&prec->val))
- prec->udf = FALSE;
+ if (prec->dol.type == CONSTANT) {
+ if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val))
+ prec->udf = FALSE;
}
- /* initialize mask*/
- prec->mask = 0;
- for (i=0; inobt; i++) {
- prec->mask <<= 1; /* shift left 1 bit*/
- prec->mask |= 1; /* set low order bit*/
- }
- if( pdset->init_record ) {
- epicsUInt32 rval;
+ /* initialize mask if the user didn't */
+ if (prec->mask == 0)
+ prec->mask = (1 << prec->nobt) - 1;
- status=(*pdset->init_record)(prec);
- /* init_record might set status */
- init_common(prec);
- if(status==0){
- rval = prec->rval;
- if(prec->shft>0) rval >>= prec->shft;
- if (prec->sdef){
- epicsUInt32 *pstate_values;
- short i;
+ if (pdset->init_record) {
+ status = pdset->init_record(prec);
+ init_common(prec);
+ if (status == 0) {
+ /* convert initial read-back */
+ epicsUInt32 rval = prec->rval;
- pstate_values = &(prec->zrvl);
- prec->val = 65535; /* initalize to unknown state*/
- for (i = 0; i < 16; i++){
- if (*pstate_values == rval){
- prec->val = i;
- break;
- }
- pstate_values++;
- }
- }else{
- /* the raw is the desired val */
- prec->val = (unsigned short)rval;
- }
- prec->udf = FALSE;
- } else if (status==2) status=0;
+ if (prec->shft > 0)
+ rval >>= prec->shft;
+
+ if (prec->sdef) {
+ epicsUInt32 *pstate_values = &prec->zrvl;
+ int i;
+
+ prec->val = 65535; /* initalize to unknown state */
+ for (i = 0; i < 16; i++) {
+ if (*pstate_values == rval) {
+ prec->val = i;
+ break;
+ }
+ pstate_values++;
+ }
+ }
+ else {
+ /* No defined states, punt */
+ prec->val = rval;
+ }
+ prec->udf = FALSE;
+ }
+ else if (status == 2)
+ status = 0;
+ }
+ else {
+ init_common(prec);
+ status = 0;
}
- init_common(prec);
/* convert val to rval */
convert(prec);
prec->mlst = prec->val;
prec->lalm = prec->val;
prec->oraw = prec->rval;
prec->orbv = prec->rbv;
- return(0);
+ return status;
}
static long process(mbboRecord *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) {
+ long status;
+ unsigned short 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==TRUE) {
- recGblSetSevr(prec,UDF_ALARM,INVALID_ALARM);
- goto CONTINUE;
- }
- /* convert val to rval */
- convert(prec);
+ 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==TRUE) {
+ recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+ goto CONTINUE;
+ }
+ /* convert val to rval */
+ convert(prec);
}
CONTINUE:
/* check for alarms */
checkAlarms(prec);
- if (prec->nsev < INVALID_ALARM )
- status=writeValue(prec); /* write the new value */
+ 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,
- "mbbo:process Illegal IVOA field");
+ 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); /* write the new value */
+ break;
+ case menuIvoaDon_t_drive_outputs:
+ break;
+ default :
+ status = -1;
+ recGblRecordError(S_db_badField, prec,
+ "mbbo::process Illegal IVOA field");
+ }
}
/* check if device support set pact */
- if ( !pact && prec->pact ) return(0);
+ if (!pact && prec->pact)
+ return 0;
prec->pact = TRUE;
recGblGetTimeStamp(prec);
+
/* check event list */
monitor(prec);
+
/* process the forward scan link record */
recGblFwdLink(prec);
- prec->pact=FALSE;
- return(status);
+ prec->pact = FALSE;
+ return status;
}
static long special(DBADDR *paddr, int after)
{
- mbboRecord *prec = (mbboRecord *)(paddr->precord);
+ mbboRecord *prec = (mbboRecord *) paddr->precord;
int special_type = paddr->special;
int fieldIndex = dbGetFieldIndex(paddr);
- if (!after) return 0;
+ if (!after)
+ return 0;
+
switch (special_type) {
case SPC_MOD:
init_common(prec);
@@ -291,174 +296,174 @@ static long special(DBADDR *paddr, int after)
static long cvt_dbaddr(DBADDR *paddr)
{
- mbboRecord *prec=(mbboRecord *)paddr->precord;
- int index;
+ mbboRecord *prec = (mbboRecord *) paddr->precord;
- index = dbGetFieldIndex(paddr);
- if(index!=mbboRecordVAL) {
- recGblDbaddrError(S_db_badField,paddr,"mbbo: cvt_dbaddr");
- return(0);
+ if (dbGetFieldIndex(paddr) != mbboRecordVAL) {
+ recGblDbaddrError(S_db_badField, paddr, "mbbo: cvt_dbaddr");
+ return 0;
}
- if(!prec->sdef) {
+ if (!prec->sdef) {
paddr->field_type = DBF_USHORT;
paddr->dbr_field_type = DBF_USHORT;
}
- return(0);
+ return 0;
}
static long get_enum_str(DBADDR *paddr, char *pstring)
{
- mbboRecord *prec=(mbboRecord *)paddr->precord;
- char *psource;
- int index;
- unsigned short *pfield = (unsigned short *)paddr->pfield;
- unsigned short val=*pfield;
+ mbboRecord *prec = (mbboRecord *) paddr->precord;
+ unsigned short *pfield = paddr->pfield;
+ int val = *pfield;
- index = dbGetFieldIndex(paddr);
- if(index!=mbboRecordVAL) {
- strcpy(pstring,"Illegal_Value");
- } else if(val<= 15) {
- psource = (prec->zrst);
- psource += (val * sizeof(prec->zrst));
- strncpy(pstring,psource,sizeof(prec->zrst));
- } else {
- strcpy(pstring,"Illegal Value");
+ if (dbGetFieldIndex(paddr) != mbboRecordVAL) {
+ strcpy(pstring, "Bad Field");
}
- return(0);
+ else if (val <= 15) {
+ const char *pstate = prec->zrst + val * sizeof(prec->zrst);
+
+ strncpy(pstring, pstate, sizeof(prec->zrst));
+ }
+ else {
+ strcpy(pstring, "Illegal Value");
+ }
+ return 0;
}
static long get_enum_strs(DBADDR *paddr, struct dbr_enumStrs *pes)
{
- mbboRecord *prec=(mbboRecord *)paddr->precord;
- char *psource;
- int i;
- short no_str;
+ mbboRecord *prec = (mbboRecord *) paddr->precord;
+ const char *pstate;
+ int i, states = 0;
- no_str=0;
- memset(pes->strs,'\0',sizeof(pes->strs));
- for(i=0,psource=(prec->zrst); i<16; i++, psource += sizeof(prec->zrst) ) {
- strncpy(pes->strs[i],psource,sizeof(prec->zrst));
- if(*psource!=0)no_str=i+1;
+ memset(pes->strs, '\0', sizeof(pes->strs));
+ pstate = prec->zrst;
+ for (i = 0; i < 16; i++) {
+ strncpy(pes->strs[i], pstate, sizeof(prec->zrst));
+ if (*pstate) states = i + 1;
+ pstate += sizeof(prec->zrst);
}
- pes->no_str = no_str;
+ pes->no_str = states;
- return(0);
+ return 0;
}
static long put_enum_str(DBADDR *paddr,char *pstring)
{
- mbboRecord *prec=(mbboRecord *)paddr->precord;
- char *pstate_name;
- short i;
+ mbboRecord *prec = (mbboRecord *) paddr->precord;
+ const char *pstate;
+ short i;
- if (prec->sdef){
- pstate_name = prec->zrst;
- for (i = 0; i < 16; i++){
- if(strncmp(pstate_name,pstring,sizeof(prec->zrst))==0){
- prec->val = i;
- return(0);
- }
- pstate_name += sizeof(prec->zrst);
- }
+ if (prec->sdef) {
+ pstate = prec->zrst;
+ for (i = 0; i < 16; i++) {
+ if (strncmp(pstate, pstring, sizeof(prec->zrst)) == 0) {
+ prec->val = i;
+ return 0;
+ }
+ pstate += sizeof(prec->zrst);
}
- return(S_db_badChoice);
+ }
+ return S_db_badChoice;
}
static void checkAlarms(mbboRecord *prec)
{
- unsigned short *severities;
- unsigned short val=prec->val;
+ epicsEnum16 val = prec->val;
+ /* check for state alarm */
+ if (val > 15) {
+ /* Unknown state */
+ recGblSetSevr(prec, STATE_ALARM, prec->unsv);
+ }
+ else {
+ /* State has a severity field */
+ epicsEnum16 *severities = &prec->zrsv;
+ recGblSetSevr(prec, STATE_ALARM, severities[prec->val]);
+ }
- /* check for state alarm */
- /* unknown state */
- if (val > 15){
- recGblSetSevr(prec,STATE_ALARM,prec->unsv);
- } else {
- /* in a state which is an error */
- severities = (unsigned short *)&(prec->zrsv);
- recGblSetSevr(prec,STATE_ALARM,severities[prec->val]);
- }
-
- /* check for cos alarm */
- if(val == prec->lalm) return;
- if(recGblSetSevr(prec,COS_ALARM,prec->cosv)) return;
- prec->lalm = val;
- return;
+ /* check for cos alarm */
+ if (val == prec->lalm) return;
+ if (recGblSetSevr(prec,COS_ALARM,prec->cosv)) return;
+ prec->lalm = val;
+ return;
}
static void monitor(mbboRecord *prec)
{
- unsigned short monitor_mask;
+ unsigned short monitor_mask;
- monitor_mask = recGblResetAlarms(prec);
- /* check for value change */
- if (prec->mlst != prec->val){
- /* post events for value change and archive change */
- monitor_mask |= (DBE_VALUE | DBE_LOG);
- /* update last value monitored */
- prec->mlst = prec->val;
- }
- /* 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);
- prec->oraw = prec->rval;
- }
- if(prec->orbv!=prec->rbv) {
- db_post_events(prec,&prec->rbv,monitor_mask|DBE_VALUE);
- prec->orbv = prec->rbv;
- }
- return;
+ monitor_mask = recGblResetAlarms(prec);
+ /* check for value change */
+ if (prec->mlst != prec->val) {
+ /* post events for value change and archive change */
+ monitor_mask |= (DBE_VALUE | DBE_LOG);
+ /* update last value monitored */
+ prec->mlst = prec->val;
+ }
+ /* send out monitors connected to the value field */
+ if (monitor_mask) {
+ db_post_events(prec, &prec->val, monitor_mask);
+ }
+ if (prec->oraw != prec->rval) {
+ db_post_events(prec, &prec->rval, monitor_mask | DBE_VALUE);
+ prec->oraw = prec->rval;
+ }
+ if (prec->orbv != prec->rbv) {
+ db_post_events(prec, &prec->rbv, monitor_mask | DBE_VALUE);
+ prec->orbv = prec->rbv;
+ }
+ return;
}
static void convert(mbboRecord *prec)
{
- epicsUInt32 *pvalues = &(prec->zrvl);
+ epicsUInt32 *pvalues = &prec->zrvl;
- /* convert val to rval */
- if(prec->sdef) {
+ /* convert val to rval */
+ if (prec->sdef) {
+ if (prec->val > 15) {
+ recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
+ return;
+ }
+ prec->rval = pvalues[prec->val];
+ }
+ else
+ prec->rval = prec->val;
- if(prec->val>15) {
- recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
- return;
- }
- prec->rval = pvalues[prec->val];
- } else prec->rval = (epicsUInt32)(prec->val);
- if(prec->shft>0) prec->rval <<= prec->shft;
+ if (prec->shft > 0)
+ prec->rval <<= prec->shft;
- return;
+ return;
}
static long writeValue(mbboRecord *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) {
+ status = pdset->write_mbbo(prec);
+ return status;
+ }
- status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
- if (status)
- return(status);
+ status = dbGetLink(&prec->siml, DBR_USHORT, &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);
+ 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);
- return(status);
+ return status;
}