24 #include "epicsMath.h" 33 #define GEN_SIZE_OFFSET 34 #include "selRecord.h" 35 #undef GEN_SIZE_OFFSET 40 #define initialize NULL 42 static long process(
struct dbCommon *);
44 #define get_value NULL 45 #define cvt_dbaddr NULL 46 #define get_array_info NULL 47 #define put_array_info NULL 50 #define get_enum_str NULL 51 #define get_enum_strs NULL 52 #define put_enum_str NULL 81 static void checkAlarms(selRecord *);
82 static void do_sel(selRecord *);
83 static int fetch_values(selRecord *);
84 static void monitor(selRecord *);
87 static long init_record(
struct dbCommon *pcommon,
int pass)
89 struct selRecord *
prec = (
struct selRecord *)pcommon;
98 recGblInitConstantLink(&prec->nvl,
DBF_USHORT, &prec->seln);
102 for (i=0; i<
SEL_MAX; i++, plink++, pvalue++) {
104 recGblInitConstantLink(plink,
DBF_DOUBLE, pvalue);
109 static long process(
struct dbCommon *pcommon)
111 struct selRecord *prec = (
struct selRecord *)pcommon;
117 recGblGetTimeStamp(prec);
133 #define indexof(field) selRecord##field 135 static long get_units(DBADDR *paddr,
char *units)
137 selRecord *prec=(selRecord *)paddr->precord;
139 if(paddr->pfldDes->field_type ==
DBF_DOUBLE) {
140 strncpy(units,prec->egu,DB_UNITS_SIZE);
145 static long get_precision(
const DBADDR *paddr,
long *precision)
147 selRecord *prec=(selRecord *)paddr->precord;
148 double *pvalue,*plvalue;
151 *precision = prec->prec;
152 if(paddr->pfield==(
void *)&prec->val){
157 for(i=0; i<
SEL_MAX; i++, pvalue++, plvalue++) {
158 if(paddr->pfield==(
void *)&pvalue
159 || paddr->pfield==(
void *)&plvalue){
163 recGblGetPrec(paddr,precision);
170 selRecord *prec=(selRecord *)paddr->precord;
171 int index = dbGetFieldIndex(paddr);
194 recGblGetGraphicDouble(paddr,pgd);
197 pgd->upper_disp_limit = prec->hopr;
198 pgd->lower_disp_limit = prec->lopr;
204 selRecord *prec=(selRecord *)paddr->precord;
205 int index = dbGetFieldIndex(paddr);
228 recGblGetControlDouble(paddr,pcd);
231 pcd->upper_ctrl_limit = prec->hopr;
232 pcd->lower_ctrl_limit = prec->lopr;
238 selRecord *prec=(selRecord *)paddr->precord;
240 if(dbGetFieldIndex(paddr) ==
indexof(VAL)) {
241 pad->upper_alarm_limit = prec->hhsv ? prec->hihi :
epicsNAN;
242 pad->upper_warning_limit = prec->hsv ? prec->high :
epicsNAN;
243 pad->lower_warning_limit = prec->lsv ? prec->low :
epicsNAN;
244 pad->lower_alarm_limit = prec->llsv ? prec->lolo :
epicsNAN;
245 }
else recGblGetAlarmDouble(paddr,pad);
249 static void checkAlarms(selRecord *prec)
251 double val, hyst, lalm;
256 recGblSetSevr(prec,
UDF_ALARM, prec->udfs);
267 if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
276 if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
285 if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
294 if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
295 if (recGblSetSevr(prec,
LOW_ALARM, asev))
305 static void monitor(selRecord *prec)
307 unsigned monitor_mask;
312 monitor_mask = recGblResetAlarms(prec);
315 recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask,
DBE_VALUE);
318 recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask,
DBE_ARCHIVE);
322 db_post_events(prec, &prec->val, monitor_mask);
327 if (prec->nlst != prec->seln) {
328 prec->nlst = prec->seln;
329 db_post_events(prec, &prec->seln, monitor_mask);
333 for(i=0, pnew=&prec->a, pprev=&prec->la; i<
SEL_MAX; i++, pnew++, pprev++) {
334 if(*pnew != *pprev) {
335 db_post_events(prec, pnew, monitor_mask);
342 static void do_sel(selRecord *prec)
346 unsigned short count;
353 case (selSELM_Specified):
358 val = *(pvalue+prec->seln);
360 case (selSELM_High_Signal):
362 for (i = 0; i <
SEL_MAX; i++,pvalue++){
363 if (!
isnan(*pvalue) && val < *pvalue) {
369 case (selSELM_Low_Signal):
371 for (i = 0; i <
SEL_MAX; i++,pvalue++){
372 if (!
isnan(*pvalue) && val > *pvalue) {
378 case (selSELM_Median_Signal):
381 for (i = 0; i <
SEL_MAX; i++,pvalue++){
382 if (!
isnan(*pvalue)){
385 while ((j > 0) && (order[j-1] > *pvalue)){
386 order[j] = order[j-1];
394 val = order[count / 2];
401 prec->udf =
isnan(prec->val);
410 static int fetch_values(selRecord *prec)
420 if(prec->selm == selSELM_Specified) {
422 status=dbGetLink(&(prec->nvl),
DBR_USHORT,&(prec->seln),0,0);
427 pvalue += prec->seln;
429 status=dbGetLink(plink,
DBR_DOUBLE, pvalue,0,0);
433 for(i=0; i<
SEL_MAX; i++, plink++, pvalue++) {
434 status=dbGetLink(plink,
DBR_DOUBLE, pvalue,0,0);
#define RTN_SUCCESS(STATUS)
epicsExportAddress(rset, selRSET)
Miscellaneous macro definitions.
#define get_control_double
#define get_graphic_double