This is Unofficial EPICS BASE Doxygen Site
biRecord.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 
10 /* recBi.c - Record Support Routines for Binary Input records */
11 /*
12  * Original Author: Bob Dalesio
13  * Date: 7-14-89
14  *
15  */
16 
17 #include <stddef.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "dbDefs.h"
24 #include "epicsPrint.h"
25 #include "alarm.h"
26 #include "callback.h"
27 #include "dbAccess.h"
28 #include "dbFldTypes.h"
29 #include "dbEvent.h"
30 #include "devSup.h"
31 #include "errMdef.h"
32 #include "menuSimm.h"
33 #include "recSup.h"
34 #include "recGbl.h"
35 #include "special.h"
36 
37 #define GEN_SIZE_OFFSET
38 #include "biRecord.h"
39 #undef GEN_SIZE_OFFSET
40 #include "epicsExport.h"
41 
42 /* Create RSET - Record Support Entry Table*/
43 #define report NULL
44 #define initialize NULL
45 static long init_record(struct dbCommon *, int);
46 static long process(struct dbCommon *);
47 static long special(DBADDR *, int);
48 #define get_value NULL
49 #define cvt_dbaddr NULL
50 #define get_array_info NULL
51 #define put_array_info NULL
52 #define get_units NULL
53 #define get_precision NULL
54 static long get_enum_str(const DBADDR *, char *);
55 static long get_enum_strs(const DBADDR *, struct dbr_enumStrs *);
56 static long put_enum_str(const DBADDR *, const char *);
57 #define get_graphic_double NULL
58 #define get_control_double NULL
59 #define get_alarm_double NULL
61  RSETNUMBER,
62  report,
63  initialize,
65  process,
66  special,
67  get_value,
68  cvt_dbaddr,
71  get_units,
79 };
80 epicsExportAddress(rset,biRSET);
81 
82 static void checkAlarms(biRecord *);
83 static void monitor(biRecord *);
84 static long readValue(biRecord *);
85 
86 static long init_record(struct dbCommon *pcommon, int pass)
87 {
88  struct biRecord *prec = (struct biRecord *)pcommon;
89  bidset *pdset;
90  long status;
91 
92  if (pass == 0) return 0;
93 
94  recGblInitSimm(pcommon, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
95  recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval);
96 
97  if(!(pdset = (bidset *)(prec->dset))) {
98  recGblRecordError(S_dev_noDSET,(void *)prec,"bi: init_record");
99  return(S_dev_noDSET);
100  }
101  /* must have read_bi function defined */
102  if( (pdset->common.number < 5) || (pdset->read_bi == NULL) ) {
103  recGblRecordError(S_dev_missingSup,(void *)prec,"bi: init_record");
104  return(S_dev_missingSup);
105  }
106  if( pdset->common.init_record ) {
107  if((status=(*pdset->common.init_record)(pcommon))) return(status);
108  }
109  prec->mlst = prec->val;
110  prec->lalm = prec->val;
111  prec->oraw = prec->rval;
112  return(0);
113 }
114 
115 static long process(struct dbCommon *pcommon)
116 {
117  struct biRecord *prec = (struct biRecord *)pcommon;
118  bidset *pdset = (bidset *)(prec->dset);
119  long status;
120  unsigned char pact=prec->pact;
121 
122  if( (pdset==NULL) || (pdset->read_bi==NULL) ) {
123  prec->pact=TRUE;
124  recGblRecordError(S_dev_missingSup,(void *)prec,"read_bi");
125  return(S_dev_missingSup);
126  }
127 
128  status=readValue(prec); /* read the new value */
129  /* check if device support set pact */
130  if ( !pact && prec->pact ) return(0);
131  prec->pact = TRUE;
132 
133  recGblGetTimeStampSimm(prec, prec->simm, &prec->siol);
134 
135  if(status==0) { /* convert rval to val */
136  if(prec->rval==0) prec->val =0;
137  else prec->val = 1;
138  prec->udf = FALSE;
139  }
140  else if(status==2) status=0;
141  /* check for alarms */
142  checkAlarms(prec);
143  /* check event list */
144  monitor(prec);
145  /* process the forward scan link record */
146  recGblFwdLink(prec);
147 
148  prec->pact=FALSE;
149  return(status);
150 }
151 
152 static long special(DBADDR *paddr, int after)
153 {
154  biRecord *prec = (biRecord *)(paddr->precord);
155  int special_type = paddr->special;
156 
157  switch(special_type) {
158  case(SPC_MOD):
159  if (dbGetFieldIndex(paddr) == biRecordSIMM) {
160  if (!after)
161  recGblSaveSimm(prec->sscn, &prec->oldsimm, prec->simm);
162  else
163  recGblCheckSimm((dbCommon *)prec, &prec->sscn, prec->oldsimm, prec->simm);
164  return(0);
165  }
166  default:
167  recGblDbaddrError(S_db_badChoice, paddr, "bi: special");
168  return(S_db_badChoice);
169  }
170 }
171 
172 static long get_enum_str(const DBADDR *paddr, char *pstring)
173 {
174  biRecord *prec=(biRecord *)paddr->precord;
175  int index;
176  unsigned short *pfield = (unsigned short *)paddr->pfield;
177 
178 
179  index = dbGetFieldIndex(paddr);
180  if(index!=biRecordVAL) {
181  strcpy(pstring,"Illegal_Value");
182  } else if(*pfield==0) {
183  strncpy(pstring,prec->znam,sizeof(prec->znam));
184  pstring[sizeof(prec->znam)] = 0;
185  } else if(*pfield==1) {
186  strncpy(pstring,prec->onam,sizeof(prec->onam));
187  pstring[sizeof(prec->onam)] = 0;
188  } else {
189  strcpy(pstring,"Illegal_Value");
190  }
191  return(0);
192 }
193 
194 static long get_enum_strs(const DBADDR *paddr,struct dbr_enumStrs *pes)
195 {
196  biRecord *prec=(biRecord *)paddr->precord;
197 
198  pes->no_str = 2;
199  memset(pes->strs,'\0',sizeof(pes->strs));
200  strncpy(pes->strs[0],prec->znam,sizeof(prec->znam));
201  if(*prec->znam!=0) pes->no_str=1;
202  strncpy(pes->strs[1],prec->onam,sizeof(prec->onam));
203  if(*prec->onam!=0) pes->no_str=2;
204  return(0);
205 }
206 
207 static long put_enum_str(const DBADDR *paddr, const char *pstring)
208 {
209  biRecord *prec=(biRecord *)paddr->precord;
210 
211  if(strncmp(pstring,prec->znam,sizeof(prec->znam))==0) prec->val = 0;
212  else if(strncmp(pstring,prec->onam,sizeof(prec->onam))==0) prec->val = 1;
213  else return(S_db_badChoice);
214  prec->udf=FALSE;
215  return(0);
216 }
217 
218 
219 static void checkAlarms(biRecord *prec)
220 {
221  unsigned short val = prec->val;
222 
223 
224  if(prec->udf == TRUE){
225  recGblSetSevr(prec,UDF_ALARM,prec->udfs);
226  return;
227  }
228 
229  if(val>1)return;
230  /* check for state alarm */
231  if (val == 0){
232  recGblSetSevr(prec,STATE_ALARM,prec->zsv);
233  }else{
234  recGblSetSevr(prec,STATE_ALARM,prec->osv);
235  }
236 
237  /* check for cos alarm */
238  if(val == prec->lalm) return;
239  recGblSetSevr(prec,COS_ALARM,prec->cosv);
240  prec->lalm = val;
241  return;
242 }
243 
244 static void monitor(biRecord *prec)
245 {
246  unsigned short monitor_mask;
247 
248  monitor_mask = recGblResetAlarms(prec);
249  /* check for value change */
250  if (prec->mlst != prec->val){
251  /* post events for value change and archive change */
252  monitor_mask |= (DBE_VALUE | DBE_LOG);
253  /* update last value monitored */
254  prec->mlst = prec->val;
255  }
256 
257  /* send out monitors connected to the value field */
258  if (monitor_mask){
259  db_post_events(prec,&prec->val,monitor_mask);
260  }
261  if(prec->oraw!=prec->rval) {
262  db_post_events(prec,&prec->rval,
263  monitor_mask|DBE_VALUE|DBE_LOG);
264  prec->oraw = prec->rval;
265  }
266  return;
267 }
268 
269 static long readValue(biRecord *prec)
270 {
271  bidset *pdset = (bidset *)prec->dset;
272  long status = 0;
273 
274  if (!prec->pact) {
275  status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
276  if (status) return status;
277  }
278 
279  switch (prec->simm) {
280  case menuSimmNO:
281  status = pdset->read_bi(prec);
282  break;
283 
284  case menuSimmYES:
285  case menuSimmRAW: {
286  recGblSetSevr(prec, SIMM_ALARM, prec->sims);
287  if (prec->pact || (prec->sdly < 0.)) {
288  status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0);
289  if (status == 0) {
290  if (prec->simm == menuSimmYES) {
291  prec->val = prec->sval;
292  status = 2; /* Don't convert */
293  } else {
294  prec->rval = (unsigned short) prec->sval;
295  }
296  prec->udf = FALSE;
297  }
298  prec->pact = FALSE;
299  } else { /* !prec->pact && delay >= 0. */
300  epicsCallback *pvt = prec->simpvt;
301  if (!pvt) {
302  pvt = calloc(1, sizeof(epicsCallback)); /* very lazy allocation of callback structure */
303  prec->simpvt = pvt;
304  }
305  if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
306  prec->pact = TRUE;
307  }
308  break;
309  }
310 
311  default:
312  recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
313  status = -1;
314  }
315 
316  return status;
317 }
#define RSETNUMBER
Definition: recSup.h:92
#define report
Definition: biRecord.c:43
#define FALSE
Definition: dbDefs.h:32
pvd::Status status
#define initialize
Definition: biRecord.c:44
#define get_enum_strs
Definition: aaiRecord.c:65
#define init_record
#define S_dev_missingSup
Definition: devSup.h:170
rset biRSET
Definition: biRecord.c:60
#define SOFT_ALARM
Definition: alarm.h:106
#define NULL
Definition: catime.c:38
Miscellaneous macro definitions.
epicsExportAddress(rset, biRSET)
#define get_control_double
Definition: biRecord.c:58
#define COS_ALARM
Definition: alarm.h:99
#define DBE_VALUE
Definition: caeventmask.h:38
#define get_array_info
Definition: biRecord.c:50
Device support routines.
#define DBE_LOG
Definition: caeventmask.h:40
#define get_units
Definition: biRecord.c:52
#define SIMM_ALARM
Definition: alarm.h:110
#define get_value
Definition: biRecord.c:48
#define put_enum_str
Definition: aaiRecord.c:66
#define get_precision
Definition: biRecord.c:53
#define put_array_info
Definition: biRecord.c:51
#define TRUE
Definition: dbDefs.h:27
if(yy_init)
Definition: scan.c:972
Definition: recSup.h:67
#define SPC_MOD
Definition: special.h:33
#define STATE_ALARM
Definition: alarm.h:98
int prec
Definition: reader.c:29
#define INVALID_ALARM
Definition: alarm.h:53
#define get_graphic_double
Definition: biRecord.c:57
#define DBR_ULONG
Definition: dbFldTypes.h:82
#define special
Definition: dfanoutRecord.c:50
#define get_enum_str
Definition: aaiRecord.c:64
#define cvt_dbaddr
Definition: biRecord.c:49
#define get_alarm_double
Definition: biRecord.c:59
#define S_dev_noDSET
Definition: devSup.h:169
#define UDF_ALARM
Definition: alarm.h:108
Exporting IOC objects.