AlcapDAQ  1
Data Structures | Macros | Functions
epics_ca_ori.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include "cadef.h"
#include "midas.h"

Go to the source code of this file.

Data Structures

struct  CA_INFO
 

Macros

#define MIDEBUG
 
#define CHN_NAME_LENGTH   32 /* length of channel names */
 

Functions

void epics_ca_callback (struct event_handler_args args)
 
INT epics_ca_init (HNDLE hKey, void **pinfo, INT channels)
 
INT epics_ca_exit (CA_INFO *info)
 
INT epics_ca_set (CA_INFO *info, INT channel, float value)
 
INT epics_ca_set_all (CA_INFO *info, INT channels, float value)
 
INT epics_ca_set_label (CA_INFO *info, INT channels, char *label)
 
INT epics_ca_get (CA_INFO *info, INT channel, float *pvalue)
 
INT epics_ca_get_all (CA_INFO *info, INT channels, float *pvalue)
 
INT epics_ca (INT cmd,...)
 

Macro Definition Documentation

#define CHN_NAME_LENGTH   32 /* length of channel names */
#define MIDEBUG

Definition at line 24 of file epics_ca_ori.c.

Function Documentation

INT epics_ca ( INT  cmd,
  ... 
)

Definition at line 291 of file epics_ca_ori.c.

References channel, CA_INFO::cmd_disabled, epics_ca_exit(), epics_ca_get(), epics_ca_get_all(), epics_ca_get_default_name(), epics_ca_get_default_threshold(), epics_ca_get_demand(), epics_ca_init(), epics_ca_set(), epics_ca_set_all(), epics_ca_set_label(), FALSE, CA_INFO::flags, hKey, status, TRUE, and value.

292 {
293  va_list argptr;
294  HNDLE hKey;
295  INT channel, status;
296  DWORD flags;
297  float value, *pvalue;
298  CA_INFO *info;
299  char *label;
300 
301  va_start(argptr, cmd);
302  status = FE_SUCCESS;
303 
304 #ifdef MIDEBUG
305  cm_msg(MLOG,"","++epics_ca(CMD=%d)",cmd);
306 #endif
307  if (cmd == CMD_INIT) {
308  void *pinfo;
309 
310  hKey = va_arg(argptr, HNDLE);
311  pinfo = va_arg(argptr, void *);
312  channel = va_arg(argptr, INT);
313  flags = va_arg(argptr, DWORD);
314  status = epics_ca_init(hKey, pinfo, channel);
315  info = *(CA_INFO **) pinfo;
316  info->flags = flags;
317  } else {
318  info = va_arg(argptr, void *);
319 
320  /* only execute command if enabled */
321  if (cmd & info->cmd_disabled)
322  status = FE_ERR_DISABLED;
323  else
324  switch (cmd) {
325  case CMD_INIT:
326  break;
327 
328  case CMD_EXIT:
329  status = epics_ca_exit(info);
330  break;
331 
332  case CMD_SET:
333  channel = va_arg(argptr, INT);
334  value = (float) va_arg(argptr, double);
335  status = epics_ca_set(info, channel, value);
336  break;
337 
338  case CMD_SET_ALL:
339  channel = va_arg(argptr, INT);
340  value = (float) va_arg(argptr, double);
341  status = epics_ca_set_all(info, channel, value);
342  break;
343 
344  case CMD_SET_LABEL:
345  channel = va_arg(argptr, INT);
346  label = va_arg(argptr, char *);
347  status = epics_ca_set_label(info, channel, label);
348  break;
349 
350  case CMD_GET:
351  channel = va_arg(argptr, INT);
352  pvalue = va_arg(argptr, float *);
353  status = epics_ca_get(info, channel, pvalue);
354  break;
355 
356  case CMD_GET_ALL:
357  channel = va_arg(argptr, INT);
358  pvalue = va_arg(argptr, float *);
359  status = epics_ca_get_all(info, channel, pvalue);
360  break;
361 
362  default:
363  break;
364  }
365  }
366 
367  va_end(argptr);
368 
369 #ifdef MIDEBUG
370  cm_msg(MLOG,"","--epics_ca()");
371 #endif
372  return status;
373 }
void epics_ca_callback ( struct event_handler_args  args)

Definition at line 40 of file epics_ca_ori.c.

References CA_INFO::array, for(), i, CA_INFO::num_channels, and CA_INFO::pv_handles.

Referenced by epics_ca_init().

41 {
42  CA_INFO *info;
43  int i;
44 #ifdef MIDEBUG
45  cm_msg(MLOG,"","++epics_ca_callback()");
46 #endif
47  info = (CA_INFO *) args.usr;
48 
49  /* search channel index */
50  for (i = 0; i < info->num_channels; i++)
51  if (info->pv_handles[i] == args.chid) {
52 #ifdef MIDEBUG
53  cm_msg(MLOG,"","callback for channel %d", i);
54 #endif
55  break;
56  }
57 
58  if (i < info->num_channels)
59  info->array[i] = *((float *) args.dbr);
60 
61 #ifdef MIDEBUG
62  cm_msg(MLOG,"","--epics_ca_callback()");
63 #endif
64 }
INT epics_ca_exit ( CA_INFO info)

Definition at line 160 of file epics_ca_ori.c.

References CA_INFO::array, CA_INFO::array_m, CA_INFO::channel_names, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CA_INFO::demand, CA_INFO::down, CA_INFO::firstread, CA_INFO::found, CA_INFO::gchan, i, CA_INFO::intol, CA_INFO::iscmd, CA_INFO::lastget, CA_INFO::lastset, CA_SETTINGS::maxval, CA_SETTINGS::minval, CA_INFO::nerr, CA_INFO::nmsg, CA_INFO::num_channels, CA_INFO::pchid, CA_INFO::pv_handles, CA_SETTINGS::readonly, CA_INFO::settings, status, CA_INFO::status, CA_INFO::subscribed, CA_INFO::threshold, CA_INFO::tolchan, CA_SETTINGS::tolerance, and CA_SETTINGS::used.

161 {
162  int i;
163 
164 #ifdef MIDEBUG
165  cm_msg(MLOG,"","++epics_ca_exit()");
166 #endif
167 
168  ca_task_exit();
169 
170  if (info->pv_handles) {
171  for (i = 0; i < info->num_channels; i++)
172  if (info->pv_handles[i]) {
173  free(info->pv_handles[i]);
174  info->pv_handles[i] = NULL;
175  }
176  free(info->pv_handles);
177  }
178 
179  if (info->array)
180  free(info->array);
181  if (info->channel_names)
182  free(info->channel_names);
183 
184  free(info);
185 
186 #ifdef MIDEBUG
187  cm_msg(MLOG,"","--epics_ca_exit()");
188 #endif
189  return FE_SUCCESS;
190 }
INT epics_ca_get ( CA_INFO info,
INT  channel,
float *  pvalue 
)

Definition at line 254 of file epics_ca_ori.c.

References CA_SETTINGS::AlarmWhenNOTConnected, CA_SETTINGS::AlarmWhenNOTinTolerance, CA_INFO::array, CA_INFO::array_m, channel, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, CA_INFO::demand, CA_INFO::down, epics_ca_get_demand(), epics_ca_set(), FALSE, CA_INFO::found, CA_INFO::gchan, hDB, CA_INFO::hkeyDemand, CA_INFO::hkeySNC, CA_INFO::hkeySNT, i, CA_INFO::intol, CA_INFO::iscmd, CA_INFO::lastset, CA_INFO::lastSNC, CA_INFO::lastSNT, CA_INFO::nmsg, CA_INFO::num_channels, CA_INFO::pchid, CA_INFO::pending, CA_INFO::settings, size, status, CA_SETTINGS::Sum_NOT_Connected, CA_SETTINGS::Sum_NOT_in_Tolerance, CA_INFO::tolchan, CA_SETTINGS::tolerance, TRUE, and CA_SETTINGS::used.

255 {
256 #ifdef MIDEBUG
257  cm_msg(MLOG,"","++epics_ca_get(channel %d)",channel);
258 #endif
259  ca_pend_event(0.0001);
260  if (pvalue) *pvalue = info->array[channel];
261 
262 #ifdef MIDEBUG
263  if (pvalue)
264  cm_msg(MLOG,"","--epics_ca_get(value = %f)",*pvalue);
265  else
266  cm_msg(MLOG,"","--epics_ca_get(NULL pointer to return)");
267 #endif
268  return FE_SUCCESS;
269 }
INT epics_ca_get_all ( CA_INFO info,
INT  channels,
float *  pvalue 
)

Definition at line 273 of file epics_ca_ori.c.

References epics_ca_get(), i, MIN, and CA_INFO::num_channels.

274 {
275  int i;
276 
277 #ifdef MIDEBUG
278  cm_msg(MLOG,"","++epics_ca_get_all(%d channels)", channels);
279 #endif
280  for (i = 0; i < MIN(info->num_channels, channels); i++)
281  epics_ca_get(info, i, pvalue + i);
282 
283 #ifdef MIDEBUG
284  cm_msg(MLOG,"","--epics_ca_get_all()");
285 #endif
286  return FE_SUCCESS;
287 }
INT epics_ca_init ( HNDLE  hKey,
void **  pinfo,
INT  channels 
)

Definition at line 68 of file epics_ca_ori.c.

References CA_SETTINGS::AlarmWhenNOTConnected, CA_SETTINGS::AlarmWhenNOTinTolerance, CA_INFO::array, CA_INFO::array_m, castatestr(), CA_INFO::channel_names, CA_SETTINGS::channel_names, channels, CHN_NAME_LENGTH, CA_SETTINGS::chnflags, CHNFLAGS_LENGTH, CA_INFO::cmd_disabled, CA_INFO::demand, CA_INFO::down, epics_ca_callback(), epics_ca_connection_handler(), epics_ca_event_handler(), epics_ca_exception_handler(), epics_ca_get_demand(), FALSE, CA_INFO::firstread, found, CA_INFO::found, CA_INFO::gchan, GFA_SPECIFIC, hDB, CA_INFO::hkeyDemand, CA_INFO::hkeySNC, CA_INFO::hkeySNT, i, CA_INFO::intol, CA_INFO::iscmd, CA_INFO::lastget, CA_INFO::lastset, CA_SETTINGS::loadfile, CA_SETTINGS::maxval, CA_SETTINGS::minval, msg, N_GFA_TYPES, CA_INFO::name, _GFA_type::nc, CA_INFO::nerr, CA_INFO::nmsg, CA_INFO::num_channels, CA_INFO::pchid, CA_INFO::pv_handles, CA_SETTINGS::readonly, CA_INFO::settings, smsg, sprintf(), status, CA_INFO::status, CA_INFO::subscribe_disabled, CA_INFO::subscribed, CA_SETTINGS::Sum_NOT_Connected, CA_SETTINGS::Sum_NOT_in_Tolerance, _GFA_type::tc, CA_INFO::threshold, CA_INFO::tolchan, CA_SETTINGS::tolerance, TRUE, _GFA_type::type, CA_SETTINGS::used, and value.

69 {
70  int status, i;
71  HNDLE hDB;
72  CA_INFO *info;
73 
74 #ifdef MIDEBUG
75  cm_msg(MLOG,"","++epics_ca_init(%d channels)",channels);
76 #endif
77  /* allocate info structure */
78  info = calloc(1, sizeof(CA_INFO));
79  *pinfo = info;
80 
81  /* disable all commands by default */
82  info->cmd_disabled = 1;
83 
84  cm_get_experiment_database(&hDB, NULL);
85 
86  /* get channel names */
87  info->channel_names = calloc(channels, CHN_NAME_LENGTH);
88  for (i = 0; i < channels; i++)
89  sprintf(info->channel_names + CHN_NAME_LENGTH * i, "Channel%d", i);
90  db_merge_data(hDB, hKey, "Channel name",
91  info->channel_names, CHN_NAME_LENGTH * channels, channels, TID_STRING);
92 
93  /* initialize driver */
94  status = ca_task_initialize();
95  if (!(status & ECA_NORMAL)) {
96  cm_msg(MERROR, "epics_ca_init", "Unable to initialize! ca_task_initialize() "
97  "returned 0X%x",status);
98  return FE_ERR_HW;
99  }
100 
101  /* allocate arrays */
102  info->array = calloc(channels, sizeof(float));
103  info->pv_handles = calloc(channels, sizeof(void *));
104  for (i = 0; i < channels; i++)
105  info->pv_handles[i] = calloc(1, sizeof(chid));
106 
107  /* search channels */
108  info->num_channels = channels;
109 
110  for (i = 0; i < channels; i++) {
111  status = ca_search(info->channel_names+CHN_NAME_LENGTH * i, &info->pv_handles[i]);
112  if (!(status & ECA_NORMAL))
113  cm_msg(MERROR, "epics_ca_init", "ERROR 0X%x returned by ca_search(%s)",
114  status, info->channel_names + CHN_NAME_LENGTH * i);
115  }
116 
117  if ((status=ca_pend_io(5.0)) == ECA_TIMEOUT) {
118  for (i = 0; i < channels; i++)
119  if (ca_state(info->pv_handles[i]) != cs_conn)
120  cm_msg(MERROR, "epics_ca_init", "Not connect to %s",
121  info->channel_names + CHN_NAME_LENGTH * i);
122  } else if (status != ECA_NORMAL) {
123  // NIY unknown status
124  }
125 
126  /* add change notifications */
127  for (i = 0; i < channels; i++) {
128  /* ignore unconnected channels */
129  if (ca_state(info->pv_handles[i]) != cs_conn) {
130  // NIY ignoring unconnected channel %s
131  continue;
132  }
133  status = ca_add_event(DBR_FLOAT, info->pv_handles[i], epics_ca_callback,
134  info, NULL);
135  if (!(status & ECA_NORMAL))
136  cm_msg(MERROR, "epics_ca_init", "channel %s ca_add_event() returned 0X%x",
137  info->channel_names + CHN_NAME_LENGTH * i, status);
138  }
139 
140  if ((status=ca_pend_io(5.0)) == ECA_TIMEOUT) {
141  for (i = 0; i < channels; i++)
142  if (ca_state(info->pv_handles[i]) != cs_conn)
143  cm_msg(MERROR, "epics_ca_init", "Not connect to %s",
144  info->channel_names + CHN_NAME_LENGTH * i);
145  } else if (status != ECA_NORMAL) {
146  // NIY unknown status
147  }
148 
149  /* enable all commands by default */
150  info->cmd_disabled = 0;
151 
152 #ifdef MIDEBUG
153  cm_msg(MLOG,"","--epics_ca_init()");
154 #endif
155  return FE_SUCCESS;
156 }
INT epics_ca_set ( CA_INFO info,
INT  channel,
float  value 
)

Definition at line 194 of file epics_ca_ori.c.

195 {
196 #ifdef MIDEBUG
197  cm_msg(MLOG,"","++epics_ca_set(channel %d, value %f)",channel,value);
198 #endif
199  //ca_put(DBR_FLOAT, info->pv_handles[channel], &value);
200 
201 #ifdef MIDEBUG
202  cm_msg(MLOG,"","--epics_ca_set()");
203 #endif
204  return FE_SUCCESS;
205 }
INT epics_ca_set_all ( CA_INFO info,
INT  channels,
float  value 
)

Definition at line 209 of file epics_ca_ori.c.

References epics_ca_set(), FALSE, i, MIN, CA_INFO::num_channels, CA_INFO::pv_handles, and status.

210 {
211  INT i;
212 
213 #ifdef MIDEBUG
214  cm_msg(MLOG,"","++epics_ca_set_all(%d channels)",channels);
215 #endif
216  for (i = 0; i < MIN(info->num_channels, channels); i++)
217  ca_put(DBR_FLOAT, info->pv_handles[i], &value);
218 
219 #ifdef MIDEBUG
220  cm_msg(MLOG,"","--epics_ca_set_all()");
221 #endif
222  return FE_SUCCESS;
223 }
INT epics_ca_set_label ( CA_INFO info,
INT  channels,
char *  label 
)

Definition at line 227 of file epics_ca_ori.c.

References CA_INFO::channel_names, CA_SETTINGS::channel_names, CHN_NAME_LENGTH, printf(), CA_INFO::settings, sprintf(), and status.

228 {
229  int status;
230  char str[256];
231  chid chan_id;
232 
233 #ifdef MIDEBUG
234  cm_msg(MLOG,"","++epics_ca_set_label(channel %d, label %s)", channels, label);
235 #endif
236  sprintf(str, "%s.DESC", info->channel_names + CHN_NAME_LENGTH * channels);
237  status = ca_search(str, &chan_id);
238 
239  status = ca_pend_io(2.0);
240  if (status != ECA_NORMAL)
241  printf("%s not found\n", str);
242 
243  status = ca_put(ca_field_type(chan_id), chan_id, label);
244  ca_pend_event(0.01);
245 
246 #ifdef MIDEBUG
247  cm_msg(MLOG,"","--epics_ca_set_label()");
248 #endif
249  return FE_SUCCESS;
250 }