mrfioc2  2.3.0
devObjAnalog.cpp
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2011 Brookhaven Science Associates, as Operator of
3 * Brookhaven National Laboratory.
4 * mrfioc2 is distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /*
8  * Author: Michael Davidsaver <mdavidsaver@gmail.com>
9  */
10 
11 #include <aiRecord.h>
12 #include <aoRecord.h>
13 
14 #include "devObj.h"
15 
16 using namespace mrf;
17 
18 /************** AI *************/
19 
20 // When converting between VAL and RVAL the following
21 // convention is used. (ROFF omitted when RVAL is double)
22 // VAL = ((RVAL+ROFF) * ASLO + AOFF) * ESLO + EOFF
23 // RVAL = ((VAL - EOFF)/ESLO - AOFF)/ASLO + ROFF
24 
25 template<typename T>
26 static long read_ai_from_real(aiRecord* prec)
27 {
28 if (!prec->dpvt) {(void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM); return -1; }
29 try {
30  addr<T> *priv=(addr<T>*)prec->dpvt;
31 
32  {
33  scopedLock<mrf::Object> g(*priv->O);
34  prec->val = priv->P->get();
35  }
36 
37  if(prec->aslo!=0)
38  prec->val*=prec->aslo;
39  prec->val+=prec->aoff;
40 
41  if(prec->linr==menuConvertLINEAR){
42  if(prec->eslo!=0)
43  prec->val*=prec->eslo;
44  prec->val+=prec->eoff;
45  }
46 
47  prec->udf = 0;
48  return 2;
49 }CATCH(S_dev_badArgument)
50 }
51 
52 // ai double
53 
54 OBJECT_DSET(AIFromDouble,
55  (&add_record_inp<aiRecord,double>),
56  &del_record_property,
57  &init_record_empty,
58  &read_ai_from_real<double>,
59  NULL);
60 
61 template<typename T>
62 static long read_ai_from_integer(aiRecord* prec)
63 {
64 if (!prec->dpvt) {(void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM); return -1; }
65 CurrentRecord cur(prec);
66 try {
67  addr<T> *priv=(addr<T>*)prec->dpvt;
68 
69  {
70  scopedLock<mrf::Object> g(*priv->O);
71  prec->rval = priv->P->get();
72  }
73 
74  return 0;
75 } catch(std::exception& e) {
76  epicsPrintf("%s: read error: %s\n", prec->name, e.what());
77  return S_db_noMemory;
78 }
79 }
80 
81 // ai uint32
82 
83 OBJECT_DSET(AIFromUINT32,
84  (&add_record_inp<aiRecord,epicsUInt32>),
85  &del_record_property,
86  &init_record_empty,
87  &read_ai_from_integer<epicsUInt32>,
88  NULL);
89 
90 // ai uint16
91 
92 OBJECT_DSET(AIFromUINT16,
93  (&add_record_inp<aiRecord,epicsUInt16>),
94  &del_record_property,
95  &init_record_empty,
96  &read_ai_from_integer<epicsUInt16>,
97  NULL);
98 
99 
100 
101 /************** AO *************/
102 
103 template<typename T>
104 static long write_ao_from_real(aoRecord* prec)
105 {
106 if (!prec->dpvt) {(void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM); return -1; }
107 CurrentRecord cur(prec);
108 try {
109  addr<T> *priv=(addr<T>*)prec->dpvt;
110 
111  double val=prec->val;
112 
113  if(prec->linr==menuConvertLINEAR){
114  val-=prec->eoff;
115  if(prec->eslo!=0)
116  val/=prec->eslo;
117  }
118 
119  val-=prec->aoff;
120  if(prec->aslo!=0)
121  val/=prec->aslo;
122 
123  {
124  scopedLock<mrf::Object> g(*priv->O);
125  priv->P->set(val);
126 
127  if (!priv->rbv)
128  return 0;
129 
130  prec->val = priv->P->get();
131  }
132 
133  if(prec->aslo!=0)
134  prec->val*=prec->aslo;
135  prec->val+=prec->aoff;
136 
137  if(prec->linr==menuConvertLINEAR){
138  if(prec->eslo!=0)
139  prec->val*=prec->eslo;
140  prec->val+=prec->eoff;
141  }
142 
143  return 0;
144 }CATCH(S_dev_badArgument)
145 }
146 
147 // ao double
148 
149 OBJECT_DSET(AOFromDouble,
150  (&add_record_out<aoRecord,double>),
151  &del_record_property,
152  &init_record_return2,
153  &write_ao_from_real<double>,
154  NULL);
155 
156 template<typename T>
157 static long write_ao_from_integer(aoRecord* prec)
158 {
159 if (!prec->dpvt) {(void)recGblSetSevr(prec, COMM_ALARM, INVALID_ALARM); return -1; }
160 CurrentRecord cur(prec);
161 try {
162  addr<T> *priv=(addr<T>*)prec->dpvt;
163 
164  {
165  scopedLock<mrf::Object> g(*priv->O);
166  priv->P->set(prec->rval);
167 
168  prec->rbv = priv->P->get();
169  }
170 
171  return 0;
172 }CATCH(S_dev_badArgument)
173 }
174 
175 // ao uint32
176 
177 OBJECT_DSET(AOFromUINT32,
178  (&add_record_out<aoRecord,epicsUInt32>),
179  &del_record_property,
180  &init_record_empty,
181  &write_ao_from_integer<epicsUInt32>,
182  NULL);
183 
184 // ao uint16
185 
186 OBJECT_DSET(AOFromUINT16,
187  (&add_record_out<aoRecord,epicsUInt16>),
188  &del_record_property,
189  &init_record_empty,
190  &write_ao_from_integer<epicsUInt16>,
191  NULL);
192 
193 
194 #include <epicsExport.h>
195 extern "C" {
196  OBJECT_DSET_EXPORT(AIFromDouble);
197  OBJECT_DSET_EXPORT(AIFromUINT32);
198  OBJECT_DSET_EXPORT(AIFromUINT16);
199  OBJECT_DSET_EXPORT(AOFromDouble);
200  OBJECT_DSET_EXPORT(AOFromUINT32);
201  OBJECT_DSET_EXPORT(AOFromUINT16);
202 }
OBJECT_DSET_EXPORT(AIFromDouble)
Definition: devObj.h:97
mrf::Object * O
Definition: devObj.h:90
OBJECT_DSET(AIFromDouble,(&add_record_inp< aiRecord, double >), &del_record_property, &init_record_empty, &read_ai_from_real< double >, NULL)
mrf::auto_ptr< mrf::property< T > > P
Definition: devObj.h:98
#define CATCH(RET)
Definition: devObj.h:31
Definition: flash.cpp:23
int rbv
Definition: devObj.h:89