Low-Energy Muon (LEM) Experiment  0.5.1
hvr400.c
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------
2 
3  Name: hvr400.c
4  Created by: Andreas Suter 2005/06/27
5 
6  Contents: MIDAS device driver declaration for the MSCB high voltage
7  dividers hvr_400.
8 
9 ----------------------------------------------------------------------------*/
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14 #include <string.h>
15 #include <math.h>
16 #include "midas.h"
17 #include "msystem.h"
18 #include "mscb.h"
19 
20 #include "hvr400.h"
21 
22 #include "lemSCWatchdog.h"
23 
24 // --------- to handle error messages ------------------------------
25 
26 #define HVR400_INIT_ERROR -2
27 
28 #define HVR400_MAX_ERROR 5
29 #define HVR400_DELTA_TIME_ERROR 600
30 
31 // ----------- HVR400 related infos ---------------------------------
33 #define MSCB_DEBUG FALSE
34 
35 // HVR400 offsets ---------------------------------------------------
36 #define HVR400_CONTROL 0
37 #define HVR400_VDEMAND 1
38 #define HVR400_VMEAS 2
39 #define HVR400_IMEAS 3
40 #define HVR400_STATUS 4
41 #define HVR400_TRIPCNT 5
42 #define HVR400_RAMPUP 6
43 #define HVR400_RAMPDOWN 7
44 #define HVR400_VLIMIT 8
45 #define HVR400_ILIMIT 9
46 #define HVR400_RILIMIT 10
47 #define HVR400_TRIPMAX 11
48 #define HVR400_TRIPTIME 12
49 
50 // HVR400 Control Bits ----------------------------------------------
51 #define HVR400_CTRL_HV_ON 0x01
52 #define HVR400_CTRL_REGULATION 0x02
53 #define HVR400_CTRL_IDLE 0x04
54 
58 typedef struct {
59  BOOL enabled;
60  BOOL scw_in_use;
62  char port[NAME_LENGTH];
63  char pwd[NAME_LENGTH];
64  INT group_addr;
65  INT node_addr;
66  char name[NAME_LENGTH];
67  INT odb_offset;
69 
71 #define HVR400_SETTINGS_STR "\
72 Enabled = BOOL : 0\n\
73 SCW_IN_USE = BOOL : 0\n\
74 Detailed Messages = INT : 0\n\
75 MSCB Port = STRING : [32] usb1\n\
76 MSCB Pwd = STRING : [32]\n\
77 Group Addr = INT : 400\n\
78 Node Addr = INT : 1\n\
79 HVR400 Name = STRING : [32] HVR400_1\n\
80 HV ODB Offset = INT : 0\n\
81 "
82 
83 //------------------------------------------------------------------
102 typedef struct {
103  unsigned char control;
104  float u_demand;
105  float u_meas;
106  float i_meas;
107  unsigned char status;
108  unsigned char trip_cnt;
109 
110  float ramp_up;
111  float ramp_down;
112  float u_limit;
113  float i_limit;
114  float ri_limit;
115  unsigned char trip_max;
116  unsigned char trip_time;
117 
118  unsigned char cached;
120 
121 
123 #define HVR400_SCW_STR "\
124 Proc Name = STRING : [32]\n\
125 PID = INT : -1\n\
126 Log Name = STRING : [64]\n\
127 DD Name = STRING : [32] \n\
128 Last Updated = DWORD : 0\n\
129 Timeout = DWORD : 180\n\
130 "
131 
133 typedef struct {
136  LEM_SC_WATCHDOG scw;
137  INT fd;
138  INT errcount;
140  DWORD lasterrtime;
141 } HVR400_INFO;
142 
143 
144 // device driver support routines -------------------------------------------------
151 INT hvr400_read_all(HVR400_INFO* info, int channel)
152 {
153  int size, status;
154  unsigned char buffer[256], *pbuf;
155 
156  size = sizeof(buffer);
157  status = mscb_read_range(info->fd, info->settings.node_addr+channel, 0, 12, buffer, &size);
158  if (status != MSCB_SUCCESS) {
159  cm_msg(MERROR, "hr400_read_all",
160  "Cannot access MSCB HVR400 address \"%d\". Check power and connection.",
161  info->settings.node_addr);
162  return FE_ERR_HW;
163  }
164 
165  /* decode variables from buffer */
166  pbuf = buffer;
167  info->node_vars[channel].control = *((unsigned char *)pbuf);
168  pbuf += sizeof(char);
169  DWORD_SWAP(pbuf);
170  info->node_vars[channel].u_demand = *((float *)pbuf);
171  pbuf += sizeof(float);
172  DWORD_SWAP(pbuf);
173  info->node_vars[channel].u_meas = *((float *)pbuf);
174  pbuf += sizeof(float);
175  DWORD_SWAP(pbuf);
176  info->node_vars[channel].i_meas = *((float *)pbuf);
177  pbuf += sizeof(float);
178  info->node_vars[channel].status = *((unsigned char *)pbuf);
179  pbuf += sizeof(char);
180  info->node_vars[channel].trip_cnt = *((unsigned char *)pbuf);
181  pbuf += sizeof(char);
182  DWORD_SWAP(pbuf);
183  info->node_vars[channel].ramp_up = *((float *)pbuf);
184  pbuf += sizeof(float);
185  DWORD_SWAP(pbuf);
186  info->node_vars[channel].ramp_down = *((float *)pbuf);
187  pbuf += sizeof(float);
188  DWORD_SWAP(pbuf);
189  info->node_vars[channel].u_limit = *((float *)pbuf);
190  pbuf += sizeof(float);
191  DWORD_SWAP(pbuf);
192  info->node_vars[channel].i_limit = *((float *)pbuf);
193  pbuf += sizeof(float);
194  DWORD_SWAP(pbuf);
195  info->node_vars[channel].ri_limit = *((float *)pbuf);
196  pbuf += sizeof(float);
197  info->node_vars[channel].trip_max = *((unsigned char *)pbuf);
198  pbuf += sizeof(char);
199  info->node_vars[channel].trip_time = *((unsigned char *)pbuf);
200 
201  /* mark voltage/current as valid in cache */
202  info->node_vars[channel].cached = 1;
203 
204  return FE_SUCCESS;
205 }
206 
207 //---- device driver routines --------------------------------------
222 INT hvr400_init(HNDLE hKey, void **pinfo, INT channels)
223 {
224 INT status, size;
225 INT i;
226 HNDLE hDB, hkeydd;
227 MSCB_INFO node_info;
229 
230  // allocate info structure
231  info = (HVR400_INFO *) calloc(1, sizeof(HVR400_INFO));
232  info->node_vars = (HVR400_NODE_VARS *) calloc(channels, sizeof(HVR400_NODE_VARS));
233  *pinfo = info;
234 
235  cm_get_experiment_database(&hDB, NULL);
236 
237  // create HVR400 settings record
238  status = db_create_record(hDB, hKey, "DD/HVR400", HVR400_SETTINGS_STR);
239  if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
240  cm_msg(MERROR, "hvr400_init", "hvr400_init: Error creating DD/HVR400 record in ODB, status=%d", status);
241  cm_yield(0);
242  return FE_ERR_ODB;
243  }
244 
245  db_find_key(hDB, hKey, "DD/HVR400", &hkeydd);
246  size = sizeof(info->settings);
247  db_get_record(hDB, hkeydd, &info->settings, &size, 0);
248 
249  // create HVR400 slowcontrol watchdog DD settings
250  status = db_create_record(hDB, hKey, "DD/SCW", HVR400_SCW_STR);
251  if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
252  cm_msg(MERROR, "hvr400_init", "hvr400_init: Error creating DD/SCW record in ODB, status=%d", status);
253  cm_yield(0);
254  return FE_ERR_ODB;
255  }
256 
257  // initialize driver
258  info->errcount = 0;
259  info->startup_error = 0;
260  info->lasterrtime = ss_time();
261 
262  if (!info->settings.enabled) {
263  cm_msg(MINFO, "hvr400_init", "hvr400_init: %s not enabled", info->settings.name);
264  cm_yield(0);
265  info->startup_error = 1;
266  return FE_SUCCESS;
267  }
268 
269  // initialize MSCB
270  info->fd = mscb_init(info->settings.port, sizeof(info->settings.port), info->settings.pwd, MSCB_DEBUG);
271  if (info->fd < 0) {
272  cm_msg(MINFO, "hvr400_init", "hvr400_init: Couldn't initialize MSCB port %s, Error no: %d",
273  info->settings.port, info->fd);
274  cm_yield(0);
275  info->startup_error = 1;
276  return FE_SUCCESS;
277  }
278 
279  // check first node
280  status = mscb_info(info->fd, info->settings.node_addr, &node_info);
281  if (status != MSCB_SUCCESS) {
282  cm_msg(MINFO, "hvr400_init", "Cannot access HVR node at address \"%d\". Please check cabling and power.",
283  info->settings.node_addr);
284  cm_yield(0);
285  info->startup_error = 1;
286  return FE_SUCCESS;
287  }
288 
289  // check if it is a HVR400
290  if (strcmp(node_info.node_name, "HVR-400") != 0) {
291  cm_msg(MINFO, "hvr400_init",
292  "Found unexpected node \"%s\" at address \"%d\".",
293  node_info.node_name, info->settings.node_addr);
294  cm_yield(0);
295  info->startup_error = 1;
296  return FE_SUCCESS;
297  }
298 
299  // read all values from the HVR400 devices
300  for (i=0; i<channels; i++) {
301  status = hvr400_read_all(info, i);
302  if (status != FE_SUCCESS) {
303  info->startup_error = 1;
304  return FE_SUCCESS;
305  }
306  }
307 
308  cm_msg(MINFO, "hvr400_init", "hvr400_init: %s initialized", info->settings.name);
309  cm_yield(0);
310 
311  if (info->settings.scw_in_use) { // slowcontrol watchdog shall be used
312  // register with the slowcontrol watchdog -------------------------------------
313  // find scw record in DD
314  db_find_key(hDB, hKey, "DD/SCW", &hkeydd);
315  // get record
316  size = sizeof(info->scw);
317  db_get_record(hDB, hkeydd, &info->scw, &size, 0);
318  // fill watchdog structure
319  info->scw.pid = ss_getpid();
320  info->scw.last_updated = ss_time();
321  strncpy(info->scw.name, info->settings.name, sizeof(info->scw.name));
322  // write info back into ODB
323  db_set_record(hDB, hkeydd, &info->scw, sizeof(info->scw), 0);
324 
325  // register with slowcontrol watchdog
326  status = lem_scw_init(&info->scw);
327  if (status != LEM_SCW_SUCCESS) {
328  cm_msg(MINFO, "hvr400_init", "Couldn't register with lem watchdog");
329  cm_yield(0);
330  }
331  }
332 
333  return FE_SUCCESS;
334 }
335 
336 /*----------------------------------------------------------------------------*/
345 {
346  // call EXIT function of MSCB driver, usually closes device
347  if (!info->startup_error)
348  mscb_exit(info->fd);
349 
350  if (info->settings.scw_in_use && !info->startup_error) { // slowcontrol watchdog in use
351  // deregister from the slowcontrol watchdog
352  lem_scw_exit(&info->scw);
353  }
354 
355  free(info->node_vars);
356  free(info);
357 
358  return FE_SUCCESS;
359 }
360 
361 /*----------------------------------------------------------------------------*/
371 INT hvr400_set(HVR400_INFO *info, INT channel, float value)
372 {
373  INT status;
374  unsigned char hv_on_off;
375  float mscb_value;
376 
377  if ( info->startup_error ) {
378  ss_sleep(10);
379  return FE_SUCCESS;
380  }
381 
382  // set HV value
383  mscb_value = fabs(value*1000.f); // kV -> V
384  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
385  (unsigned char) HVR400_VDEMAND, &mscb_value, 4);
386 
387  // check if it is necessay to switch HV on/off
388  if (value == 0.0) { // demand HV==0 -> switch HV off
389  if ((info->node_vars[channel].control & HVR400_CTRL_HV_ON) != 0) { // HV still on, hence switch it off
390  hv_on_off = HVR400_CTRL_REGULATION;
391  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
392  (unsigned char) HVR400_CONTROL, &hv_on_off, 1);
393  }
394  } else {
395  if ((info->node_vars[channel].control & HVR400_CTRL_HV_ON) == 0) { // HV has been off so far, hence switch it on
396  hv_on_off = HVR400_CTRL_HV_ON | HVR400_CTRL_REGULATION;
397  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
398  (unsigned char) HVR400_CONTROL, &hv_on_off, 1);
399  }
400  }
401 
402  return FE_SUCCESS;
403 }
404 
405 /*-----------------------------------------------------------------------------*/
415 INT hvr400_get(HVR400_INFO *info, INT channel, float *pvalue)
416 {
417 INT status, size;
418 DWORD nowtime, difftime;
419 unsigned char buffer[256], *pbuf;
420 
421  // error timeout facility
422  nowtime = ss_time();
423  difftime = nowtime - info->lasterrtime;
424  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
425  info->errcount = 0;
426  info->lasterrtime = ss_time();
427  }
428 
429  // check if there was a startup error
430  if ( info->startup_error ) {
431  *pvalue = (float) HVR400_INIT_ERROR;
432  ss_sleep(10); // to keep CPU load low when Run active
433  return FE_SUCCESS;
434  }
435 
436  // check if the value was previously read by hvr400_read_all
437  if (info->node_vars[channel].cached) {
438  *pvalue = info->node_vars[channel].u_meas / 1000.f;
439  info->node_vars[channel].cached = 0;
440  return FE_SUCCESS;
441  }
442 
443  // read voltage and current at the same time
444  size = sizeof(buffer);
445  status = mscb_read_range(info->fd, info->settings.node_addr+channel, HVR400_CONTROL, HVR400_IMEAS, buffer, &size);
446  if (status != MSCB_SUCCESS) {
447  info->errcount++;
448  if (info->errcount < HVR400_MAX_ERROR) {
449  cm_msg(MINFO, "hvr400_get",
450  "Cannot access MSCB HVR address \"%d\". Check power and connection.",
451  info->settings.node_addr+channel);
452  return FE_SUCCESS;
453  }
454  }
455 
456  // decode variables from buffer
457  pbuf = buffer;
458  info->node_vars[channel].control = *((unsigned char *)pbuf); // 0
459  pbuf += sizeof(char);
460  DWORD_SWAP(pbuf);
461  info->node_vars[channel].u_demand = *((float *)pbuf); // 1
462  pbuf += sizeof(float);
463  DWORD_SWAP(pbuf);
464  info->node_vars[channel].u_meas = *((float *)pbuf); // 2
465  pbuf += sizeof(float);
466  DWORD_SWAP(pbuf);
467  info->node_vars[channel].i_meas = *((float *)pbuf); // 3
468 
469  *pvalue = info->node_vars[channel].u_meas / 1000.f;
470 
471  if (info->settings.scw_in_use) { // slowcontrol watchdog in use
472  // feed slowcontrol watchdog
473  info->scw.last_updated = ss_time();
474  lem_scw_update(&info->scw);
475  }
476 
477  return FE_SUCCESS;
478 }
479 
480 //----------------------------------------------------------------------------
490 INT hvr400_set_current_limit(HVR400_INFO *info, INT channel, float limit)
491 {
492  INT status;
493  DWORD nowtime, difftime;
494  float mscb_value;
495 
496  if ( info->startup_error ) {
497  ss_sleep(10);
498  return FE_SUCCESS;
499  }
500 
501  // error timeout facility
502  nowtime = ss_time();
503  difftime = nowtime - info->lasterrtime;
504  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
505  info->errcount = 0;
506  info->lasterrtime = ss_time();
507  }
508 
509  // set current limit value
510  mscb_value = limit*1000.f; // mA -> uA
511  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
512  (unsigned char) HVR400_ILIMIT, &mscb_value, 4);
513 
514  return FE_SUCCESS;
515 }
516 
517 //----------------------------------------------------------------------------
527 INT hvr400_set_voltage_limit(HVR400_INFO *info, INT channel, float limit)
528 {
529  INT status;
530  DWORD nowtime, difftime;
531  float mscb_value;
532 
533  if ( info->startup_error ) {
534  ss_sleep(10);
535  return FE_SUCCESS;
536  }
537 
538  // error timeout facility
539  nowtime = ss_time();
540  difftime = nowtime - info->lasterrtime;
541  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
542  info->errcount = 0;
543  info->lasterrtime = ss_time();
544  }
545 
546  // set voltage limit value
547  mscb_value = limit*1000.f; // kV -> V
548  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
549  (unsigned char) HVR400_VLIMIT, &mscb_value, 4);
550 
551  return FE_SUCCESS;
552 }
553 
554 //----------------------------------------------------------------------------
565 INT hvr400_set_rampup(HVR400_INFO *info, INT channel, float ramp)
566 {
567  INT status;
568  DWORD nowtime, difftime;
569  float mscb_value;
570 
571  if ( info->startup_error ) {
572  ss_sleep(10);
573  return FE_SUCCESS;
574  }
575 
576  // error timeout facility
577  nowtime = ss_time();
578  difftime = nowtime - info->lasterrtime;
579  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
580  info->errcount = 0;
581  info->lasterrtime = ss_time();
582  }
583 
584  // set ramp up value
585  mscb_value = ramp * 1000.f; // kV/s -> V/s
586  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
587  (unsigned char) HVR400_RAMPUP, &mscb_value, 4);
588 
589  return FE_SUCCESS;
590 }
591 
592 //----------------------------------------------------------------------------
603 INT hvr400_set_rampdown(HVR400_INFO *info, INT channel, float ramp)
604 {
605  INT status;
606  DWORD nowtime, difftime;
607  float mscb_value;
608 
609  if ( info->startup_error ) {
610  ss_sleep(10);
611  return FE_SUCCESS;
612  }
613 
614  // error timeout facility
615  nowtime = ss_time();
616  difftime = nowtime - info->lasterrtime;
617  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
618  info->errcount = 0;
619  info->lasterrtime = ss_time();
620  }
621 
622  // set ramp down value
623  mscb_value = ramp * 1000.f; // kV/s -> V/s
624  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
625  (unsigned char) HVR400_RAMPDOWN, &mscb_value, 4);
626 
627  return FE_SUCCESS;
628 }
629 
630 //----------------------------------------------------------------------------
640 INT hvr400_set_triptime(HVR400_INFO *info, INT channel, float trip_time)
641 {
642  INT status;
643  DWORD nowtime, difftime;
644  unsigned char mscb_value;
645 
646  if ( info->startup_error ) {
647  ss_sleep(10);
648  return FE_SUCCESS;
649  }
650 
651  // error timeout facility
652  nowtime = ss_time();
653  difftime = nowtime - info->lasterrtime;
654  if ( difftime > HVR400_DELTA_TIME_ERROR ) {
655  info->errcount = 0;
656  info->lasterrtime = ss_time();
657  }
658 
659  // set trip time value
660  mscb_value = (unsigned char) trip_time;
661  status=mscb_write(info->fd, (unsigned short) (info->settings.node_addr+channel),
662  (unsigned char) HVR400_TRIPTIME, &mscb_value, 1);
663 
664  return FE_SUCCESS;
665 }
666 
667 //----------------------------------------------------------------------------
668 //---- device driver entry point ---------------------------------------------
669 //----------------------------------------------------------------------------
670 INT hvr400(INT cmd, ...)
671 {
672 va_list argptr;
673 HNDLE hKey;
674 INT channel, status;
675 float value, *pvalue;
677 
678  va_start(argptr, cmd);
679  status = FE_SUCCESS;
680 
681  switch (cmd) {
682  case CMD_INIT:
683  hKey = va_arg(argptr, HNDLE);
684  info = va_arg(argptr, void *);
685  channel = va_arg(argptr, INT);
686  status = hvr400_init(hKey, (void **)info, channel);
687  break;
688 
689  case CMD_EXIT:
690  info = va_arg(argptr, void *);
691  status = hvr400_exit(info);
692  break;
693 
694  case CMD_SET:
695  info = va_arg(argptr, void *);
696  channel = va_arg(argptr, INT);
697  value = (float) va_arg(argptr, double);
698  status = hvr400_set(info, channel, value);
699  break;
700 
701  case CMD_GET:
702  info = va_arg(argptr, void *);
703  channel = va_arg(argptr, INT);
704  pvalue = va_arg(argptr, float*);
705  status = hvr400_get(info, channel, pvalue);
706  break;
707 
708  case CMD_GET_DEMAND:
709  info = va_arg(argptr, void *);
710  channel = va_arg(argptr, INT);
711  pvalue = va_arg(argptr, float*);
712  *pvalue = info->node_vars[channel].u_demand / 1000.f; // V -> kV
713  break;
714 
715  case CMD_GET_CURRENT:
716  info = va_arg(argptr, void *);
717  channel = va_arg(argptr, INT);
718  pvalue = va_arg(argptr, float*);
719  *pvalue = info->node_vars[channel].i_meas / 1000.f; // uA -> mA
720  break;
721 
722  case CMD_GET_LABEL:
723  break;
724 
725  case CMD_SET_LABEL:
726  break;
727 
728  case CMD_SET_CURRENT_LIMIT:
729  info = va_arg(argptr, void *);
730  channel = va_arg(argptr, INT);
731  value = (float) va_arg(argptr, double);
732  status = hvr400_set_current_limit(info, channel, value);
733  break;
734 
735  case CMD_SET_VOLTAGE_LIMIT:
736  info = va_arg(argptr, void *);
737  channel = va_arg(argptr, INT);
738  value = (float) va_arg(argptr, double);
739  status = hvr400_set_voltage_limit(info, channel, value);
740  break;
741 
742  case CMD_GET_VOLTAGE_LIMIT:
743  info = va_arg(argptr, void *);
744  channel = va_arg(argptr, INT);
745  pvalue = va_arg(argptr, float *);
746  *pvalue = info->node_vars[channel].u_limit / 1000.f; // V -> kV
747  break;
748 
749  case CMD_GET_THRESHOLD:
750  info = va_arg(argptr, void *);
751  channel = va_arg(argptr, INT);
752  pvalue = va_arg(argptr, float*);
753  *pvalue = 0.1f;
754  break;
755 
756  case CMD_GET_THRESHOLD_CURRENT:
757  info = va_arg(argptr, void *);
758  channel = va_arg(argptr, INT);
759  pvalue = va_arg(argptr, float*);
760  *pvalue = 0.001f;
761  break;
762 
763  case CMD_GET_THRESHOLD_ZERO:
764  info = va_arg(argptr, void *);
765  channel = va_arg(argptr, INT);
766  pvalue = va_arg(argptr, float*);
767  *pvalue = 0.02f;
768  break;
769 
770  case CMD_GET_CURRENT_LIMIT:
771  info = va_arg(argptr, void *);
772  channel = va_arg(argptr, INT);
773  pvalue = va_arg(argptr, float*);
774  *pvalue = info->node_vars[channel].i_limit / 1000.f; // uA -> mA
775  break;
776 
777  case CMD_SET_RAMPUP:
778  info = va_arg(argptr, void *);
779  channel = va_arg(argptr, INT);
780  value = (float) va_arg(argptr, double);
781  hvr400_set_rampup(info, channel, value);
782  break;
783 
784  case CMD_SET_RAMPDOWN:
785  info = va_arg(argptr, void *);
786  channel = va_arg(argptr, INT);
787  value = (float) va_arg(argptr, double);
788  hvr400_set_rampdown(info, channel, value);
789  break;
790 
791  case CMD_GET_RAMPUP:
792  info = va_arg(argptr, void *);
793  channel = va_arg(argptr, INT);
794  pvalue = va_arg(argptr, float*);
795  *pvalue = info->node_vars[channel].ramp_up;
796  break;
797 
798  case CMD_GET_RAMPDOWN:
799  info = va_arg(argptr, void *);
800  channel = va_arg(argptr, INT);
801  pvalue = va_arg(argptr, float*);
802  *pvalue = info->node_vars[channel].ramp_down;
803  break;
804 
805  case CMD_SET_TRIP_TIME:
806  info = va_arg(argptr, void *);
807  channel = va_arg(argptr, INT);
808  value = (float) va_arg(argptr, double);
809  hvr400_set_triptime(info, channel, value);
810  break;
811 
812  case CMD_GET_TRIP_TIME:
813  info = va_arg(argptr, void *);
814  channel = va_arg(argptr, INT);
815  pvalue = va_arg(argptr, float*);
816  *pvalue = info->node_vars[channel].trip_time;
817  break;
818 
819  case CMD_STOP:
820  status = FE_SUCCESS;
821  break;
822 
823  default:
824  cm_msg(MERROR, "hvr400 device driver", "Received unkown command %d", cmd);
825  status = FE_ERR_DRIVER;
826  break;
827  }
828 
829  va_end(argptr);
830 
831  return status;
832 }
833 
834 //----------------------------------------------------------------------------
835 // end -----------------------------------------------------------------------
836 //----------------------------------------------------------------------------
INT hvr400_exit(HVR400_INFO *info)
Definition: hvr400.c:344
#define HVR400_RAMPUP
Definition: hvr400.c:42
INT startup_error
initializer error tag, if set, hvr400_get and hvr400_set won&#39;t do anything
Definition: hvr400.c:139
INT hvr400_set_triptime(HVR400_INFO *info, INT channel, float trip_time)
Definition: hvr400.c:640
unsigned char trip_max
maximal allowed number of HV trips
Definition: hvr400.c:115
DWORD lasterrtime
last error time stamp
Definition: hvr400.c:140
INFO info
Definition: vme_fe.c:206
INT hvr400_read_all(HVR400_INFO *info, int channel)
Definition: hvr400.c:151
#define HVR400_SETTINGS_STR
Initializing string for the struct HVR400_SETTINGS.
Definition: hvr400.c:71
INT hvr400_set_rampup(HVR400_INFO *info, INT channel, float ramp)
Definition: hvr400.c:565
#define HVR400_CTRL_REGULATION
Definition: hvr400.c:52
INT hvr400_set(HVR400_INFO *info, INT channel, float value)
Definition: hvr400.c:371
float ramp_up
ramp up speed in (V/s)
Definition: hvr400.c:110
BOOL enabled
flag indicating if the device is enabled or disabled
Definition: hvr400.c:59
BOOL scw_in_use
flag indicating if the slowcontrol watchdog shall be used
Definition: hvr400.c:60
INT hvr400_set_current_limit(HVR400_INFO *info, INT channel, float limit)
Definition: hvr400.c:490
unsigned char cached
cache flag
Definition: hvr400.c:118
float ri_limit
??
Definition: hvr400.c:114
HVR400_NODE_VARS * node_vars
stores the variables of all HVR400 node
Definition: hvr400.c:135
char pwd[NAME_LENGTH]
MSCB password for MSCB ethernet modules.
Definition: hvr400.c:63
unsigned char trip_time
??
Definition: hvr400.c:116
#define HVR400_RAMPDOWN
Definition: hvr400.c:43
float u_limit
voltage limit in (V)
Definition: hvr400.c:112
#define HVR400_MAX_ERROR
maximum number of error messages
Definition: hvr400.c:28
#define HVR400_TRIPTIME
Definition: hvr400.c:48
#define HVR400_VDEMAND
Definition: hvr400.c:37
HNDLE hKey
Definition: write_summary.c:97
#define HVR400_SCW_STR
defines the slowcontrol default watchdog info structure
Definition: hvr400.c:123
INT hvr400_init(HNDLE hKey, void **pinfo, INT channels)
Definition: hvr400.c:222
This structure contains private variables for the device driver.
Definition: hvr400.c:133
INT odb_offset
HV channel offset within ODB.
Definition: hvr400.c:67
INT node_addr
node address of the first HV channel within the MSCB
Definition: hvr400.c:65
#define HVR400_CONTROL
Definition: hvr400.c:36
HNDLE hDB
Definition: write_summary.c:97
unsigned char status
status tag
Definition: hvr400.c:107
INT group_addr
group address within the MSCB
Definition: hvr400.c:64
LEM_SC_WATCHDOG scw
slowcontrol watchdog info structure
Definition: hvr400.c:136
float ramp_down
ramp down speed in (V/s)
Definition: hvr400.c:111
INT hvr400_set_voltage_limit(HVR400_INFO *info, INT channel, float limit)
Definition: hvr400.c:527
float u_meas
measured HV in (V)
Definition: hvr400.c:105
#define HVR400_ILIMIT
Definition: hvr400.c:45
char port[NAME_LENGTH]
MSCB port, e.g. /dev/parport0 or usb1.
Definition: hvr400.c:62
unsigned char control
control tag
Definition: hvr400.c:103
INT detailed_msg
flag indicating if detailed status/error messages are wanted
Definition: hvr400.c:61
INT hvr400_get(HVR400_INFO *info, INT channel, float *pvalue)
Definition: hvr400.c:415
float i_meas
measured current in (uA)
Definition: hvr400.c:106
HVR400_SETTINGS settings
stores the internal DD settings
Definition: hvr400.c:134
unsigned char trip_cnt
trip counter
Definition: hvr400.c:108
char name[NAME_LENGTH]
name of the hvr_400 card
Definition: hvr400.c:66
float u_demand
demand HV in (V)
Definition: hvr400.c:104
float i_limit
current limit in (uA)
Definition: hvr400.c:113
#define HVR400_IMEAS
Definition: hvr400.c:39
INT hvr400(INT cmd,...)
Definition: hvr400.c:670
INT errcount
error counter in order not to flood the message queue
Definition: hvr400.c:138
INT fd
MSCB file desciptor.
Definition: hvr400.c:137
#define HVR400_INIT_ERROR
tag: initializing error
Definition: hvr400.c:26
#define HVR400_CTRL_HV_ON
Definition: hvr400.c:51
INT hvr400_set_rampdown(HVR400_INFO *info, INT channel, float ramp)
Definition: hvr400.c:603
#define HVR400_DELTA_TIME_ERROR
reset error counter after DELTA_TIME_ERROR seconds
Definition: hvr400.c:29
#define MSCB_DEBUG
MSCB debug flag.
Definition: hvr400.c:33
#define HVR400_VLIMIT
Definition: hvr400.c:44