Low-Energy Muon (LEM) Experiment  0.5.1
twickenham.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: twickenham.c
4  Created by: Andreas Suter 2001/09/13
5 
6  Contents: device driver for the twickenham depth indicator.
7 
8  RS232: 9600 baud, 8 data bits, 1 stop bit, no parity bit
9  protocol: Xon/Xoff (Software), termination: "\r\n"
10 
11 \********************************************************************/
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include <string.h>
17 #include "midas.h"
18 #include "twickenham.h"
19 
20 #include "ets_logout.h"
21 
22 /*---- globals -----------------------------------------------------*/
23 
25 #define TWICKENHAM_ETS_LOGOUT_SLEEP 10000
26 
27 // --------- to handle error messages ------------------------------
28 
29 #define TWICKENHAM_READ_ERROR -1
30 
31 #define TWICKENHAM_DEBUG FALSE
32 
34 #define TIME_OUT_TWICKENHAM 2000
36 
38 #define TWICKENHAM_MAX_READBACK_FAILURE 5
39 
41 typedef struct {
43  INT ets_in_use;
44  char name[NAME_LENGTH];
46 
48 #define TWICKENHAM_SETTINGS_STR "\
49 Detailed Messages = INT : 0\n\
50 ETS_IN_USE = INT : 1\n\
51 Name = STRING : [32] HDI_Level\n\
52 "
53 
55 typedef struct {
58  INT (*bd)(INT cmd, ...);
59  void *bd_info;
60  HNDLE hkey;
61  INT errorcount;
62  DWORD lasterrtime;
66  float last_value;
69 
70 
71 /*---- device driver routines --------------------------------------*/
72 
86 INT twickenham_init(HNDLE hKey, void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
87 {
88  int status;
89  char str[256];
90  HNDLE hDB, hkeydd;
92 
93  cm_get_experiment_database(&hDB, NULL);
94 
95  // allocate info structure
96  info = calloc(1, sizeof(TWICKENHAM_INFO));
97  *pinfo = info;
98 
99  // create Twickenham settings record
100  status = db_create_record(hDB, hKey, "DD", TWICKENHAM_SETTINGS_STR);
101  if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
102  cm_msg(MERROR, "twickenham_init", "twickenham_init: Error creating DD record in ODB, status=%d", status);
103  cm_yield(0);
104  return FE_ERR_ODB;
105  }
106 
107  // Hot-link onto the device driver ODB entry (private stuff of the device driver)
108  db_find_key(hDB, hKey, "DD", &hkeydd);
109  db_open_record(hDB, hkeydd, &info->twickenham_settings, sizeof(info->twickenham_settings), MODE_READ, NULL, NULL);
110 
111  // initialize driver
112  info->num_channels = channels;
113  info->bd = bd;
114  info->hkey = hKey;
115  info->errorcount = 0;
116  info->lasterrtime = ss_time();
117  info->bd_connected = 0;
118  info->readback_failure = 0;
119  info->last_reconnect = ss_time();
120  info->reconnection_failures = 0;
121 
122  if (!bd)
123  return FE_ERR_ODB;
124 
125  // initialize bus driver
126  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
127  if (status != SUCCESS)
128  return status;
129  info->bd_connected = 1;
130 
131  // initialize Twickenham, check sensor status
132  printf("\n initialize Twickenham.");
133  BD_PUTS("S\r\n");
134  status = BD_GETS(str, sizeof(str), "\r\n", TIME_OUT_TWICKENHAM);
135  if (TWICKENHAM_DEBUG) {
136  cm_msg(MINFO,"twicken_init", "status = %d, str = %s, device = %s",
137  status, str, info->twickenham_settings.name+0);
138  cm_yield(0);
139  }
140  if ( !status ) { // error occurred
141  cm_msg(MERROR,"twickenham_init",
142  "Error getting device status from Twickenham, %s",
143  info->twickenham_settings.name+0);
144  cm_yield(0);
145  return FE_SUCCESS; //FE_ERR_HW;
146  }
147  cm_msg(MINFO,"twickenham_init", "Device status of Twickenham %s = %s", info->twickenham_settings.name+0,str);
148  cm_yield(0);
149 
150  return FE_SUCCESS;
151 }
152 
153 /*----------------------------------------------------------------------------*/
163 {
164  // call EXIT function of bus driver, usually closes device
165  info->bd(CMD_EXIT, info->bd_info);
166 
167  free(info);
168 
169  return FE_SUCCESS;
170 }
171 
172 /*----------------------------------------------------------------------------*/
182 INT twickenham_get(TWICKENHAM_INFO *info, INT channel, float *pvalue)
183 {
184 char str[128];
185 INT status=0;
186 
187  if (info->bd_connected) {
188  // read sensor level
189  BD_PUTS("G\r\n");
190  status = BD_GETS(str, sizeof(str), "\r\n", TIME_OUT_TWICKENHAM);
191  }
192 
193  if (status != 0) {
194  str[strlen(str)-2] = '\0'; // truncate mm ?
195  if ( strstr(str, "-") ) // not a level message
196  *pvalue = (float) TWICKENHAM_READ_ERROR;
197  else { // standard level message
198  sscanf(str+strlen(str)-6, "%f", pvalue); // to skip over the first characters
199  info->last_value = *pvalue;
200  info->readback_failure = 0;
201  }
202  }
203  else {
204  *pvalue = info->last_value;
205 
206  if (info->reconnection_failures > 5) {
207  if (info->reconnection_failures == 6) {
208  cm_msg(MERROR, "twickenham_get", "too many reconnection failures, bailing out :-(");
209  info->reconnection_failures++;
210  }
211  return FE_SUCCESS;
212  }
213 
214  // try to disconnect and reconnect the bus driver
215  if ((ss_time()-info->last_reconnect > 10) && info->bd_connected) { // disconnect bus driver
216  info->bd(CMD_EXIT, info->bd_info);
218  cm_msg(MINFO, "twickenham_get", "twickenham: try to disconnect and reconnect the bus driver");
219  info->last_reconnect = ss_time();
220  info->bd_connected = 0;
223  }
224 
225  info->readback_failure++;
226 
228  info->readback_failure = 0;
229  // try to reconnect after a timeout of 10 sec
230  if ((ss_time()-info->last_reconnect > 10) && !info->bd_connected) {
232  cm_msg(MINFO, "twickenham_get", "twickenham: reconnection trial ...");
233  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
234  if (status != FE_SUCCESS) {
236  cm_msg(MINFO, "twickenham_get", "twickenham: reconnection attempted failed");
237  info->reconnection_failures++;
238  return FE_ERR_HW;
239  } else {
240  info->bd_connected = 1; // bus driver is connected again
241  info->reconnection_failures = 0;
242  info->last_reconnect = ss_time();
244  cm_msg(MINFO, "twickenham_get", "twickenham: successfully reconnected");
245  }
246  }
247  }
248  }
249  ss_sleep(10);
250  if (TWICKENHAM_DEBUG)
251  cm_msg(MINFO,"tw_get","status = %d, str = %s, %f", status, str, *pvalue);
252  return FE_SUCCESS;
253 }
254 
255 /*----------------------------------------------------------------------------*/
266 INT twickenham_get_label(TWICKENHAM_INFO *info, INT channel, char *name)
267 {
268  strcpy(name, info->twickenham_settings.name);
269 
270  return FE_SUCCESS;
271 }
272 
273 
274 /*---- device driver entry point -----------------------------------*/
275 INT twickenham(INT cmd, ...)
276 {
277 va_list argptr;
278 HNDLE hKey;
279 INT channel, status;
280 void *info, *bd;
281 float *pvalue;
282 DWORD flags;
283 char *name;
284 
285  va_start(argptr, cmd);
286  status = FE_SUCCESS;
287 
288  switch (cmd)
289  {
290  case CMD_INIT:
291  hKey = va_arg(argptr, HNDLE);
292  info = va_arg(argptr, void *);
293  channel = va_arg(argptr, INT);
294  flags = va_arg(argptr, DWORD);
295  bd = va_arg(argptr, void *);
296  status = twickenham_init(hKey, info, channel, bd);
297  break;
298 
299  case CMD_EXIT:
300  info = va_arg(argptr, void *);
301  status = twickenham_exit(info);
302  break;
303 
304  case CMD_SET:
305  break;
306 
307  case CMD_GET:
308  info = va_arg(argptr, void *);
309  channel = va_arg(argptr, INT);
310  pvalue = va_arg(argptr, float*);
311  status = twickenham_get(info, channel, pvalue);
312  break;
313 
314  case CMD_GET_LABEL:
315  info = va_arg(argptr, void *);
316  channel = va_arg(argptr, INT);
317  name = va_arg(argptr, char*);
318  status = twickenham_get_label(info, channel, name);
319  break;
320 
321 
322  default:
323  break;
324  }
325 
326  va_end(argptr);
327  return status;
328 }
329 /*------------------------------------------------------------------*/
void * bd_info
private info of bus driver
Definition: twickenham.c:59
int bd_connected
flag showing if bus driver is connected
Definition: twickenham.c:63
TWICKENHAM_SETTINGS twickenham_settings
ODB hot-link data for the DD.
Definition: twickenham.c:56
This structure contains private variables for the device driver.
Definition: twickenham.c:55
INFO info
Definition: vme_fe.c:206
stores internal informations within the DD.
Definition: twickenham.c:41
DWORD last_reconnect
timer for bus driver reconnect error handling
Definition: twickenham.c:65
INT twickenham_get(TWICKENHAM_INFO *info, INT channel, float *pvalue)
Definition: twickenham.c:182
int reconnection_failures
how often reconnection failed
Definition: twickenham.c:67
#define TIME_OUT_TWICKENHAM
be displayed at execution time
Definition: twickenham.c:35
INT twickenham_exit(TWICKENHAM_INFO *info)
Definition: twickenham.c:162
INT twickenham_get_label(TWICKENHAM_INFO *info, INT channel, char *name)
Definition: twickenham.c:266
int ets_logout(void *info, int wait, int detailed_msg)
Definition: ets_logout.c:113
float last_value
stores the last valid value
Definition: twickenham.c:66
#define TWICKENHAM_READ_ERROR
read error tag
Definition: twickenham.c:29
HNDLE hKey
Definition: write_summary.c:97
#define TWICKENHAM_SETTINGS_STR
initializing string for TWICKENHAM_SETTINGS
Definition: twickenham.c:48
#define TWICKENHAM_MAX_READBACK_FAILURE
maximum number of readback failures before a reconnect will take place
Definition: twickenham.c:38
HNDLE hDB
Definition: write_summary.c:97
HNDLE hkey
ODB key for bus driver info.
Definition: twickenham.c:60
#define TWICKENHAM_DEBUG
Definition: twickenham.c:31
INT errorcount
error counter; for reducing number of error messages
Definition: twickenham.c:61
INT readback_failure
counts the number of readback failures
Definition: twickenham.c:64
INT twickenham(INT cmd,...)
Definition: twickenham.c:275
INT detailed_msg
flag indicating if detailed status/error messages are wanted
Definition: twickenham.c:42
INT ets_in_use
flag indicating if the rs232 terminal server is in use
Definition: twickenham.c:43
char name[NAME_LENGTH]
name of the device used for system messages
Definition: twickenham.c:44
DWORD lasterrtime
timer error handling; for reducing number of error messages
Definition: twickenham.c:62
#define TWICKENHAM_ETS_LOGOUT_SLEEP
sleep time (us) between the telnet commands of the ets_logout
Definition: twickenham.c:25
INT(* bd)(INT cmd,...)
bus driver entry function
Definition: twickenham.c:58
INT num_channels
number of channels of the DD
Definition: twickenham.c:57
INT twickenham_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
Definition: twickenham.c:86