mrfioc2  2.3.0
devEvrPulserMapping.cpp
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2010 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 <cstdlib>
12 #include <cstring>
13 
14 #include <epicsExport.h>
15 #include <dbDefs.h>
16 #include <dbAccess.h>
17 #include <devSup.h>
18 #include <recGbl.h>
19 #include <devLib.h> // For S_dev_*
20 #include <errlog.h>
21 
22 #include <longoutRecord.h>
23 #include <stringinRecord.h>
24 
25 #include "devObj.h"
26 #include "evr/pulser.h"
27 #include "linkoptions.h"
28 
29 #include <stdexcept>
30 #include <string>
31 
43 /***************** Mapping record ******************/
44 
45 struct map_priv {
46  char obj[30];
48  epicsUInt32 last_code;
50 };
51 
52 static const
53 linkOptionEnumType funcEnum[] = {
54  {"Trig", MapType::Trigger},
55  {"Set", MapType::Set},
56  {"Reset",MapType::Reset},
57  {NULL,0}
58 };
59 
60 static const
61 linkOptionDef eventdef[] =
62 {
63  linkString (map_priv, obj , "OBJ" , 1, 0),
64  linkEnum (map_priv, func, "Func" , 1, 0, funcEnum),
66 };
67 
68 static long add_lo(dbCommon* praw)
69 {
70  long ret=0;
71  longoutRecord *prec = (longoutRecord*)praw;
72 try {
73  assert(prec->out.type==INST_IO);
74 
75  mrf::auto_ptr<map_priv> priv(new map_priv);
76  priv->last_code=prec->val;
77 
78  if (linkOptionsStore(eventdef, priv.get(), prec->out.value.instio.string, 0))
79  throw std::runtime_error("Couldn't parse link string");
80 
81  mrf::Object *O=mrf::Object::getObject(priv->obj);
82  if(!O) {
83  errlogPrintf("%s: failed to find object '%s'\n", praw->name, priv->obj);
84  return S_db_errArg;
85  }
86  priv->pulser=dynamic_cast<Pulser*>(O);
87  if(!priv->pulser)
88  throw std::runtime_error("Failed to lookup device");
89 
90  if(priv->last_code>0 && priv->last_code<=255)
91  priv->pulser->sourceSetMap(priv->last_code,priv->func);
92 
93  prec->dpvt=(void*)priv.release();
94 
95  return 0;
96 
97 } catch(std::runtime_error& e) {
98  recGblRecordError(S_dev_noDevice, (void*)prec, e.what());
99  ret=S_dev_noDevice;
100 } catch(std::exception& e) {
101  recGblRecordError(S_db_noMemory, (void*)prec, e.what());
102  ret=S_db_noMemory;
103 }
104  return ret;
105 }
106 
107 static inline
108 long del_lo(dbCommon* praw)
109 {
110  if(!praw->dpvt)
111  return 0;
112  try {
113  mrf::auto_ptr<map_priv> priv(static_cast<map_priv*>(praw->dpvt));
114 
115  if(priv->last_code>0 && priv->last_code<=255)
116  priv->pulser->sourceSetMap(priv->last_code,MapType::None);
117 
118  return 0;
119  } catch(std::exception& e) {
120  recGblRecordError(S_db_noMemory, (void*)praw, e.what());
121  }
122  (void)recGblSetSevr(praw, WRITE_ALARM, INVALID_ALARM);
123  return S_db_noMemory;
124 }
125 
126 static long write_lo(longoutRecord* plo)
127 {
128  map_priv* priv=static_cast<map_priv*>(plo->dpvt);
129  try {
130 
131  if (!priv)
132  return -2;
133 
134  epicsUInt32 code=plo->val;
135 
136  if(code > 255) {
137  (void)recGblSetSevr((dbCommon *)plo, WRITE_ALARM, INVALID_ALARM);
138  return 0;
139  }
140 
141  if( code==priv->last_code )
142  return 0;
143 
144  //TODO: sanity check to catch overloaded mappings
145 
147 
148  if(code!=0)
149  priv->pulser->sourceSetMap(code,priv->func);
150 
151  priv->last_code=code;
152 
153  return 0;
154 
155  } catch(std::exception& e) {
156  plo->val=0;
157  priv->last_code=0;
158  (void)recGblSetSevr((dbCommon *)plo, WRITE_ALARM, INVALID_ALARM);
159  recGblRecordError(S_db_noMemory, (void*)plo, e.what());
160  return S_db_noMemory;
161  }
162 }
163 
164 /********************** DSETs ***********************/
165 
166 extern "C" {
167 
168 dsxt dxtLOEVRPulserMap={add_lo, &del_lo};
169 static
170 common_dset devLOEVRPulserMap = {
171  5,
172  NULL,
173  dset_cast(&init_dset<&dxtLOEVRPulserMap>),
174  (DEVSUPFUN) &init_record_empty,
175  NULL,
176  (DEVSUPFUN) &write_lo,
177  NULL
178 };
179 epicsExportAddress(dset,devLOEVRPulserMap);
180 
181 };
dsxt dxtLOEVRPulserMap
MapType::type func
virtual void sourceSetMap(epicsUInt32 src, MapType::type action)=0
Set mapping of source &#39;src&#39;.
#define linkOptionEnd
Definition: linkoptions.h:111
epicsUInt32 last_code
Base object inspection.
Definition: object.h:378
static Object * getObject(const std::string &name)
Definition: object.cpp:107
int epicsShareAPI linkOptionsStore(const linkOptionDef *opts, void *user, const char *str, int options)
Parse a string a store the result.
Definition: linkoptions.c:135
A programmable delay unit.
Definition: pulser.h:38
type
Definition: pulser.h:21
#define linkEnum(Struct, Member, Name, Req, Over, Enums)
Definition: linkoptions.h:108
Hardware link parsing and storage.
epicsExportAddress(dset, devLOEVRPulserMap)
#define linkString(Struct, Member, Name, Req, Over)
Definition: linkoptions.h:105
char obj[30]