Low-Energy Muon (LEM) Experiment  0.5.1
xtc.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: xtc.c
4 
5  Created by: Andreas Suter 2001/09/04
6  based on Stefan Ritt's multi device driver
7 
8  Contents: device driver for the XTC thin film thickness and rate monitor.
9 
10  RS232: 9600 baud, 8 data bits, 1 stop bit, no parity bit,
11  protocol: none, termination: 0x06 (ACK)
12 
13  driver: the first channel is the thickness, the second one the rate.
14 
15 \********************************************************************/
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include "midas.h"
22 
23 #include "ets_logout.h"
24 
25 /*---- globals -----------------------------------------------------*/
26 
28 #define XTC_ETS_LOGOUT_SLEEP 10000
29 
31 #define XTC_MAX_READBACK_FAILURE 5
32 
34 #define XTC_INIT_ERROR -2
35 #define XTC_READ_ERROR -1
37 
39 #define XTC_CHANNELS 2
40 
42 typedef struct {
44  INT ets_in_use;
45  char name[XTC_CHANNELS][32];
46 } XTC_SETTINGS;
47 
49 #define XTC_SETTINGS_STR "\
50 Detailed Messages = INT : 0\n\
51 ETS_IN_USE = INT : 1\n\
52 Name_1 = STRING : [32] XTC_Thickness\n\
53 Name_2 = STRING : [32] XTC_Rate\n\
54 "
55 
57 typedef struct {
60  INT (*bd)(INT cmd, ...);
61  void *bd_info;
62  HNDLE hkey;
63  INT errorcount;
65  DWORD lasterrtime;
69  float last_value;
71 } XTC_INFO;
72 
74 #define TIME_OUT_XTC 2000
75 
76 /* --------- to handle error messages ------------------------------*/
77 #define MAX_ERROR 4
78 #define DELTA_TIME_ERROR 3600
79 #define ACK 0x06
80 #define DEBUG FALSE
81 
82 /*---- device driver routines --------------------------------------*/
83 
97 INT xtc_init(HNDLE hKey, void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
98 {
99  INT status;
100  char cmd[8], ack[2], str[32];
101  HNDLE hDB, hkeydd;
102  XTC_INFO *info;
103 
104  cm_get_experiment_database(&hDB, NULL);
105 
106  // allocate info structure
107  info = calloc(1, sizeof(XTC_INFO));
108  *pinfo = info;
109 
110  // create XTC settings record
111  status = db_create_record(hDB, hKey, "DD", XTC_SETTINGS_STR);
112  if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
113  cm_msg(MERROR, "xtc_init", "xtc_init: Error creating DD record in ODB, status=%d", status);
114  cm_yield(0);
115  return FE_ERR_ODB;
116  }
117 
118  // Hot-link onto the device driver ODB entry (private stuff of the device driver)
119  db_find_key(hDB, hKey, "DD", &hkeydd);
120  db_open_record(hDB, hkeydd, &info->xtc_settings, sizeof(info->xtc_settings), MODE_READ, NULL, NULL);
121 
122  // initialize driver
123  info->num_channels = channels;
124  info->bd = bd;
125  info->hkey = hKey;
126  info->errorcount = 0;
127  info->startup_error = 0;
128  info->lasterrtime = ss_time();
129  info->bd_connected = 0;
130  info->readback_failure = 0;
131  info->last_reconnect = ss_time();
132  info->reconnection_failures = 0;
133 
134  if ( info->num_channels > XTC_CHANNELS ) {
135  cm_msg(MERROR,"xtc_init", "Error, number of XTC channels %d exceeds maximum of allowed channels", info->num_channels);
136  cm_yield(0);
137  info->startup_error = 1;
138  return FE_SUCCESS;
139  }
140 
141  if (!bd)
142  return FE_ERR_ODB;
143 
144  // initialize bus driver
145  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
146  if (status != SUCCESS) {
147  info->startup_error = 1;
148  return status;
149  }
150  info->bd_connected = 1; // bus driver successfully connected
151 
152  sprintf(ack, "%c", ACK); // terminater
153  sprintf(cmd, "D%s", ack); // command
154 
155  if ( info->bd_connected ) {
156  BD_PUTS(cmd);
157  status = BD_GETS(str, sizeof(str), ack, TIME_OUT_XTC);
158  }
159 
160  if ( status != 26) {
161  info->startup_error = 1;
162  cm_msg(MINFO, "xtc_init", "XTC startup error.");
163  cm_yield(0);
164  } else {
165  cm_msg(MINFO, "xtc_init", "XTC driver initialized.");
166  cm_yield(0);
167  }
168 
169  return FE_SUCCESS;
170 }
171 
172 /*----------------------------------------------------------------------------*/
173 
183 {
184  // call EXIT function of bus driver, usually closes device
185  info->bd(CMD_EXIT, info->bd_info);
186 
187  free(info);
188 
189  return FE_SUCCESS;
190 }
191 
192 /*----------------------------------------------------------------------------*/
193 
204 INT xtc_set(XTC_INFO *info, INT channel, float value)
205 {
206  return FE_SUCCESS;
207 }
208 
209 /*----------------------------------------------------------------------------*/
210 
220 INT xtc_get(XTC_INFO *info, INT channel, float *pvalue)
221 {
222 char str[128], substr[128], ack[2], cmd[128];
223 INT status = 0;
224 DWORD nowtime, difftime;
225 
226  nowtime = ss_time();
227  difftime = nowtime - info->lasterrtime;
228  if ( difftime > DELTA_TIME_ERROR ) {
229  info->errorcount = 0;
230  info->lasterrtime = nowtime;
231  }
232 
233  if ( info->startup_error == 1 ) { // error during CMD_INIT, return -2
234  *pvalue = (float) XTC_INIT_ERROR;
235  ss_sleep(10); // to keep CPU load low when Run active
236  return FE_SUCCESS;
237  }
238 
239  if (info->reconnection_failures > 5) {
240  *pvalue = (float) XTC_READ_ERROR;
241  if (info->reconnection_failures == 6) {
242  cm_msg(MERROR, "xtc_get", "too many reconnection failures, bailing out :-(");
243  info->reconnection_failures++;
244  }
245  return FE_SUCCESS;
246  }
247 
248  sprintf(ack, "%c", ACK); // terminater
249  sprintf(cmd, "D%s", ack); // command
250 
251  if ( info->bd_connected ) {
252  BD_PUTS(cmd);
253  status = BD_GETS(str, sizeof(str), ack, TIME_OUT_XTC);
254  }
255 
256  if ( status != 26) {
257  *pvalue = (float) info->last_value;
258  if (info->errorcount < MAX_ERROR) {
259  if (info->xtc_settings.detailed_msg)
260  cm_msg(MERROR, "xtc_get", "XTC: command error.");
261  info->errorcount++;
262  }
263 
264  info->readback_failure++;
265 
267  info->readback_failure = 0;
268  // try to disconnect and reconnect the bus driver
269  if ((ss_time()-info->last_reconnect > 10) && info->bd_connected) { // disconnect bus driver
270  info->bd(CMD_EXIT, info->bd_info);
271  if (info->xtc_settings.detailed_msg)
272  cm_msg(MINFO, "xtc_get", "xtc: try to disconnect and reconnect the bus driver");
273  info->last_reconnect = ss_time();
274  info->bd_connected = 0;
275  if (info->xtc_settings.ets_in_use)
277  }
278  }
279 
280  // try to reconnect after a timeout of 10 sec
281  if ((ss_time()-info->last_reconnect > 10) && !info->bd_connected) {
282  if (info->xtc_settings.detailed_msg)
283  cm_msg(MINFO, "xtc_get", "xtc: reconnection trial ...");
284  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
285  if (status != FE_SUCCESS) {
286  if (info->xtc_settings.detailed_msg)
287  cm_msg(MINFO, "xtc_get", "xtc: reconnection attempted failed");
288  info->reconnection_failures++;
289  return FE_ERR_HW;
290  } else {
291  info->bd_connected = 1; // bus driver is connected again
292  info->reconnection_failures = 0;
293  info->last_reconnect = ss_time();
294  if (info->xtc_settings.detailed_msg)
295  cm_msg(MINFO, "xtc_get", "xtc: successfully reconnected");
296  }
297  }
298  return FE_SUCCESS;
299  }
300 
301  switch(channel) {
302  case 0:
303  sscanf(str, "%s %f", substr, pvalue); // thickness in A
304  break;
305  case 1:
306  sscanf(str, "%f ", pvalue);
307  *pvalue /= 10.f;
308  break;
309  default:
310  *pvalue = (float) XTC_READ_ERROR;
311  break;
312  }
313 
314  info->last_value = *pvalue; // keep the last valid value
315  info->readback_failure = 0; // reset readback failure counter
316 
317  return FE_SUCCESS;
318 }
319 
320 /*----------------------------------------------------------------------------*/
321 
332 INT xtc_get_label(XTC_INFO *info, INT channel, char *name)
333 {
334  strcpy(name, info->xtc_settings.name[channel]);
335 
336  return FE_SUCCESS;
337 }
338 
339 
340 /*---- device driver entry point -----------------------------------*/
341 
342 INT xtc(INT cmd, ...)
343 {
344 va_list argptr;
345 HNDLE hKey;
346 INT channel, status;
347 DWORD flags;
348 void *info, *bd;
349 float value, *pvalue;
350 char *name;
351 
352  va_start(argptr, cmd);
353  status = FE_SUCCESS;
354 
355  switch (cmd) {
356  case CMD_INIT:
357  hKey = va_arg(argptr, HNDLE);
358  info = va_arg(argptr, void *);
359  channel = va_arg(argptr, INT);
360  flags = va_arg(argptr, DWORD);
361  bd = va_arg(argptr, void *);
362  status = xtc_init(hKey, info, channel, bd);
363  break;
364 
365  case CMD_EXIT:
366  info = va_arg(argptr, void *);
367  status = xtc_exit(info);
368  break;
369 
370  case CMD_SET:
371  info = va_arg(argptr, void *);
372  channel = va_arg(argptr, INT);
373  value = (float) va_arg(argptr, double);
374  status = xtc_set(info, channel, value);
375  break;
376 
377  case CMD_GET:
378  info = va_arg(argptr, void *);
379  channel = va_arg(argptr, INT);
380  pvalue = va_arg(argptr, float *);
381  status = xtc_get(info, channel, pvalue);
382  break;
383 
384  case CMD_GET_LABEL:
385  info = va_arg(argptr, void *);
386  channel = va_arg(argptr, INT);
387  name = va_arg(argptr, char*);
388  status = xtc_get_label(info, channel, name);
389  break;
390 
391  default:
392  break;
393  }
394  va_end(argptr);
395  return status;
396 }
397 /*------------------------------------------------------------------*/
INT startup_error
startup error flag
Definition: xtc.c:64
#define XTC_CHANNELS
number of channels of the xtc
Definition: xtc.c:39
INFO info
Definition: vme_fe.c:206
#define TIME_OUT_XTC
time out in msecs for bus driver -&gt; device communication
Definition: xtc.c:74
#define DELTA_TIME_ERROR
reset error counter after DELTA_TIME_ERROR seconds
Definition: xtc.c:78
void * bd_info
private info of bus driver
Definition: xtc.c:61
HNDLE hkey
ODB key for bus driver info.
Definition: xtc.c:62
#define MAX_ERROR
maximum number of error messages
Definition: xtc.c:77
XTC_SETTINGS xtc_settings
private settings of the XTC device driver
Definition: xtc.c:58
int bd_connected
flag showing if bus driver is connected
Definition: xtc.c:66
int ets_logout(void *info, int wait, int detailed_msg)
Definition: ets_logout.c:113
This structure contains private variables for the device driver.
Definition: xtc.c:57
HNDLE hKey
Definition: write_summary.c:97
INT xtc(INT cmd,...)
Definition: xtc.c:342
#define XTC_MAX_READBACK_FAILURE
maximum number of readback failures before a reconnect will take place
Definition: xtc.c:31
INT errorcount
number of error encountered
Definition: xtc.c:63
#define XTC_READ_ERROR
error tag if there was communication problem
Definition: xtc.c:36
Stores all the parameters the device driver needs.
Definition: xtc.c:42
#define ACK
acknowledgment tag for device communication
Definition: xtc.c:79
HNDLE hDB
Definition: write_summary.c:97
DWORD lasterrtime
last error time stamp
Definition: xtc.c:65
INT num_channels
number of channels of the XTC
Definition: xtc.c:59
INT xtc_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
Definition: xtc.c:97
float last_value
stores the last valid value
Definition: xtc.c:69
char name[XTC_CHANNELS][32]
string array holding the default names for the different channels
Definition: xtc.c:45
int reconnection_failures
how often reconnection failed
Definition: xtc.c:70
INT readback_failure
counts the number of readback failures
Definition: xtc.c:67
DWORD last_reconnect
timer for bus driver reconnect error handling
Definition: xtc.c:68
INT ets_in_use
flag indicating if the rs232 terminal server is in use
Definition: xtc.c:44
INT xtc_get_label(XTC_INFO *info, INT channel, char *name)
Definition: xtc.c:332
#define XTC_ETS_LOGOUT_SLEEP
sleep time (us) between the telnet commands of the ets_logout
Definition: xtc.c:28
INT xtc_set(XTC_INFO *info, INT channel, float value)
Definition: xtc.c:204
#define XTC_INIT_ERROR
error tag if there was an error during initializing the DD
Definition: xtc.c:34
INT(* bd)(INT cmd,...)
bus driver entry function
Definition: xtc.c:60
INT xtc_get(XTC_INFO *info, INT channel, float *pvalue)
Definition: xtc.c:220
INT detailed_msg
flag indicating if detailed status/error messages are wanted
Definition: xtc.c:43
INT xtc_exit(XTC_INFO *info)
Definition: xtc.c:182
#define XTC_SETTINGS_STR
Initializing string for the struct XTC_SETTINGS_STR.
Definition: xtc.c:49