diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c index 7388d6e29..2aeddf436 100644 --- a/src/ioc/db/recGbl.c +++ b/src/ioc/db/recGbl.c @@ -274,7 +274,31 @@ void recGblTSELwasModified(struct link *plink) ppv_link->pvlMask |= pvlOptTSELisTime; } } - + +void recGblCheckDeadband(epicsFloat64 *poldval, const epicsFloat64 newval, + const epicsFloat64 deadband, unsigned *monitor_mask, const unsigned add_mask) +{ + double delta = 0; + + if (isnan(newval) != isnan(*poldval) || isinf(newval) != isinf(*poldval)) { + /* one is NaN or +-inf, the other finite -> send update */ + delta = epicsINF; + } else if (!isinf(newval) && !isnan(newval)) { + /* both are finite -> compare delta with deadband */ + delta = *poldval - newval; + if (delta < 0.0) delta = -delta; + } else if (signbit(newval) != signbit(*poldval)) { + /* one is +inf, the other -inf -> send update */ + delta = epicsINF; + } + if (delta > deadband) { + /* add bits to monitor mask */ + *monitor_mask |= add_mask; + /* update last value monitored */ + *poldval = newval; + } +} + static void getMaxRangeValues(short field_type, double *pupper_limit, double *plower_limit) { diff --git a/src/ioc/db/recGbl.h b/src/ioc/db/recGbl.h index 64db229ed..04a0ee4d1 100644 --- a/src/ioc/db/recGbl.h +++ b/src/ioc/db/recGbl.h @@ -62,6 +62,8 @@ epicsShareFunc int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsShareFunc void recGblFwdLink(void *precord); epicsShareFunc void recGblGetTimeStamp(void *precord); epicsShareFunc void recGblTSELwasModified(struct link *plink); +epicsShareFunc void recGblCheckDeadband(epicsFloat64 *poldval, const epicsFloat64 newval, + const epicsFloat64 deadband, unsigned *monitor_mask, const unsigned add_mask); #ifdef __cplusplus }