mrfioc2  2.3.0
devEvrMapping.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/evr.h"
27 #include "linkoptions.h"
28 
29 #include <stdexcept>
30 #include <string>
31 
46 /***************** Mapping record ******************/
47 
48 struct map_priv {
50  epicsUInt32 last_code;
51  char obj[30];
52  int func;
53 };
54 
55 static const
56 linkOptionEnumType funcEnum[] = {
57  {"FIFO", 127},
58  //{"Latch TS", 126}, // Not supported
59  {"Blink", 125},
60  {"Forward", 124},
61  {"Stop Log", 123},
62  {"Log", 122},
63  {"Heartbeat",101},
64  {"Reset PS", 100},
65  {"TS reset", 99},
66  {"TS tick", 98},
67  {"Shift 1", 97},
68  {"Shift 0", 96},
69  {NULL,0}
70 };
71 
72 static const
73 linkOptionDef eventdef[] =
74 {
75  linkString (map_priv, obj , "OBJ" , 1, 0),
76  linkEnum (map_priv, func, "Func" , 1, 0, funcEnum),
78 };
79 
80 static long add_lo(dbCommon* praw)
81 {
82  longoutRecord *prec=(longoutRecord*)praw;
83  try {
84  assert(prec->out.type==INST_IO);
85 
86  mrf::auto_ptr<map_priv> priv(new map_priv);
87 
88  if (linkOptionsStore(eventdef, priv.get(), prec->out.value.instio.string, 0))
89  throw std::runtime_error("Couldn't parse link string");
90 
91  priv->last_code=prec->val;
92 
93  mrf::Object *O=mrf::Object::getObject(priv->obj);
94  if(!O) {
95  errlogPrintf("%s: failed to find object '%s'\n", praw->name, priv->obj);
96  return S_db_errArg;
97  }
98  priv->card=dynamic_cast<EVR*>(O);
99  if(!priv->card) {
100  errlogPrintf("%s: object '%s' is not an EVR\n", praw->name, priv->obj);
101  return S_db_errArg;
102  }
103 
104  if(priv->last_code>0 && priv->last_code<=255)
105  priv->card->specialSetMap(priv->last_code,priv->func,true);
106 
107  praw->dpvt = (void*)priv.release();
108 
109  return 0;
110 
111  } catch(std::exception& e) {
112  recGblRecordError(S_db_noMemory, (void*)prec, e.what());
113  (void)recGblSetSevr(praw, WRITE_ALARM, INVALID_ALARM);
114  return S_db_noMemory;
115  }
116 }
117 
118 static inline
119 long del_lo(dbCommon* praw)
120 {
121  try {
122  mrf::auto_ptr<map_priv> priv(static_cast<map_priv*>(praw->dpvt));
123 
124  if (!priv.get())
125  return -2;
126 
127  if(priv->last_code>0 && priv->last_code<=255)
128  priv->card->specialSetMap(priv->last_code,priv->func,false);
129 
130  return 0;
131  } catch(std::exception& e) {
132  recGblRecordError(S_db_noMemory, (void*)praw, e.what());
133  }
134  (void)recGblSetSevr(praw, WRITE_ALARM, INVALID_ALARM);
135  return S_db_noMemory;
136 }
137 
138 static long write_lo(longoutRecord* prec)
139 {
140  try {
141  map_priv* priv=static_cast<map_priv*>(prec->dpvt);
142 
143  if (!priv)
144  return -2;
145 
146  epicsUInt32 func=priv->func;
147 
148  epicsUInt32 code=prec->val;
149 
150  if(code > 255) {
151  (void)recGblSetSevr((dbCommon *)prec, WRITE_ALARM, INVALID_ALARM);
152  return 0;
153  }
154 
155  if( code==priv->last_code )
156  return 0;
157 
158  if(priv->last_code>0 && priv->last_code<=255)
159  priv->card->specialSetMap(priv->last_code,func,false);
160 
161  priv->card->specialSetMap(code,func,true);
162 
163 
164  priv->last_code=code;
165 
166  return 0;
167 
168  } catch(std::exception& e) {
169  prec->val=0;
170  recGblRecordError(S_db_noMemory, (void*)prec, e.what());
171  (void)recGblSetSevr((dbCommon *)prec, WRITE_ALARM, INVALID_ALARM);
172  return S_db_noMemory;
173  }
174 }
175 
176 /********************** DSETs ***********************/
177 
178 extern "C" {
179 
180 dsxt dxtLOEVRMap={&add_lo,&del_lo};
181 static
182 common_dset devLOEVRMap = {
183  5,
184  NULL,
185  dset_cast(&init_dset<&dxtLOEVRMap>),
186  (DEVSUPFUN) init_record_empty,
187  NULL,
188  (DEVSUPFUN) write_lo,
189  NULL
190 };
191 epicsExportAddress(dset,devLOEVRMap);
192 
193 };
dsxt dxtLOEVRMap
#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
virtual void specialSetMap(epicsUInt32 code, epicsUInt32 func, bool set)=0
epicsExportAddress(dset, devLOEVRMap)
#define linkEnum(Struct, Member, Name, Req, Over, Enums)
Definition: linkoptions.h:108
Base interface for EVRs.
Definition: evr.h:45
Hardware link parsing and storage.
#define linkString(Struct, Member, Name, Req, Over)
Definition: linkoptions.h:105
char obj[30]