29 #include "lemSCWatchdog.h" 
   34 #define BH_TIME_OUT 2000 
   37 #define BH_RECONNECTION_TIMEOUT 5 
   38 #define BH_MAX_READBACK_FAILURE 5 
   40 #define BH_MAX_RECONNECTION_FAILURE 5 
   44 #define BH_MAX_ERROR        10      
   45 #define BH_DELTA_TIME_ERROR 3600    
   49 #define BH_CMD_ERROR  -3            
   50 #define BH_INIT_ERROR -2            
   51 #define BH_READ_ERROR -1            
   53 #define BH_ETS_LOGOUT_SLEEP 10000 
   66 #ifndef DOXYGEN_SHOULD_SKIP_THIS 
   68 #define BH_CMD_UNKNOWN  2 
   70 #define BH_STATUS_ERR   4 
   71 #define BH_DECODE_ERR   5 
   75 #define BH_IDENTSTRNG   1 
   78 #define BH_SETSLOPE    10 
   79 #define BH_CNTRLMODE   12 
   80 #define BH_POLYCNSTA   13 
   81 #define BH_POLYCNSTB   14 
   82 #define BH_POLYCNSTC   15 
   83 #define BH_POLYCNSTD   16 
   84 #define BH_POLYCNSTE   17 
   85 #define BH_POLYCNSTF   18 
   86 #define BH_POLYCNSTG   19 
   87 #define BH_POLYCNSTH   20 
   88 #define BH_CAPACITY    21 
   89 #define BH_SENSORTYPE  22 
   92 #define BH_FLUIDNAME   25 
   93 #define BH_ALARMINFO   28 
   94 #define BH_ALARMMSGTA  33 
   95 #define BH_ALARMMSGNR  34 
   96 #define BH_VALVEOUT    55 
   97 #define BH_IOSTATUS    86 
   98 #define BH_DEVICETYPE  90 
   99 #define BH_MODELNUM    91 
  100 #define BH_SERIALNUM   92 
  101 #define BH_VERSION    105 
  102 #define BH_TEMPERATUR 142 
  103 #define BH_FLUIDTEMP  181 
  107 #define BH_STATUSMSG 0 
  108 #define BH_SETPARAM  1 
  109 #define BH_GETPARAM  4 
  112 #define BH_INTEGER  0x20 
  114 #define BH_FLOAT    0x40 
  115 #define BH_STRING   0x60 
  118 #define BH_NOERROR          0x00 
  119 #define BH_PROCESS_CLAIMED  0x01 
  120 #define BH_CMD_ERR          0x02 
  121 #define BH_PROC_ERR         0x03 
  128 #define BH_UNCHAINED 0x00 
  129 #define BH_CHAINED   0x80 
  132 #define BH_MAX_NEEDLE_VALVE 16777215 
  134 #define BH_IN_CHANNELS  2   
  135 #define BH_OUT_CHANNELS 2   
  137 #endif // DOXYGEN_SHOULD_SKIP_THIS 
  147   char  name[BH_IN_CHANNELS][32]; 
 
  155  char  name[BH_OUT_CHANNELS][32]; 
 
  159 #define BH_IN_SETTINGS_STR "\ 
  160 Detailed Messages = INT : 0\n\ 
  161 ETS_IN_USE = INT : 1\n\ 
  162 SCW_IN_USE = INT : 0\n\ 
  163 Input = STRING[2]:\n\ 
  164 [32] BH Flow measured\n\ 
  165 [32] BH ValvePos Get\n\ 
  169 #define BH_OUT_SETTINGS_STR "\ 
  170 Output = STRING[2] :\n\ 
  171 [32] BH Flow setpoint\n\ 
  172 [32] BH ValvePos Set\n\ 
  176 #define BH_SCW_STR "\ 
  177 Proc Name = STRING : [32]\n\ 
  179 Log Name = STRING : [64]\n\ 
  180 DD Name = STRING : [32] bronkhorst\n\ 
  181 Last Updated = DWORD : 0\n\ 
  182 Timeout = DWORD : 180\n\ 
  195   INT (*bd)(INT cmd, ...);         
 
  203   float last_valid_value[2];       
 
  228   strcpy(error_msg, 
""); 
 
  230   if (strstr(str, 
":01")) { 
 
  231     sscanf(str, 
":01%02d", &error);
 
  234         strcpy(error_msg, 
"BH ERROR: no ':' at the start of the message.");
 
  237         strcpy(error_msg, 
"BH ERROR: error in 1st byte.");
 
  240         strcpy(error_msg, 
"BH ERROR: error in 2nd byte or number of bytes is 0 or message to long.");
 
  243         strcpy(error_msg, 
"BH ERROR: error in recieved message (reciever overrun, framing error, etc.).");
 
  246         strcpy(error_msg, 
"BH ERROR: flowbus communication BH ERROR: timeout or message rejected by reciver.");
 
  249         strcpy(error_msg, 
"BH ERROR: timeout during sending.");
 
  252         strcpy(error_msg, 
"BH ERROR: no answer recieved within timeout.");
 
  255         strcpy(error_msg, 
"BH ERROR: unknown error, obscure.");
 
  260   if (strstr(str, 
":04")) { 
 
  261     sscanf(str, 
":048000%02d%02d", &error, &error_byte);
 
  266         sprintf(error_msg, 
"BH ERROR: process claimed. claimed process = %x\n", error_byte);
 
  269         sprintf(error_msg, 
"BH ERROR: command error. error_byte = %d\n", error_byte);
 
  272         sprintf(error_msg, 
"BH ERROR: process error. error_byte = %d\n", error_byte);
 
  275         sprintf(error_msg, 
"BH ERROR: parameter error. error_byte = %d\n", error_byte);
 
  278         sprintf(error_msg, 
"BH ERROR: parameter type error. error_byte = %d\n", error_byte);
 
  281         sprintf(error_msg, 
"BH ERROR: parameter value error. error_byte = %d\n", error_byte);
 
  284         sprintf(error_msg, 
"BH ERROR: network not active. error_byte = %d\n", error_byte);
 
  287         sprintf(error_msg, 
"BH ERROR: timeout start character. error_byte = %d\n", error_byte);
 
  290         sprintf(error_msg, 
"BH ERROR: timeout serial line. error_byte = %d\n", error_byte);
 
  293         sprintf(error_msg, 
"BH ERROR: hardware memory error. error_byte = %d\n", error_byte);
 
  296         sprintf(error_msg, 
"BH ERROR: node number error. error_byte = %d\n", error_byte);
 
  299         sprintf(error_msg, 
"BH ERROR: general communication error. error_byte = %d\n", error_byte);
 
  302         sprintf(error_msg, 
"BH ERROR: read only parameter. error_byte = %d\n", error_byte);
 
  305         sprintf(error_msg, 
"BH ERROR: error pc-communication. error_byte = %d\n", error_byte);
 
  308         sprintf(error_msg, 
"BH ERROR: no rs232 connection. error_byte = %d\n", error_byte);
 
  311         sprintf(error_msg, 
"BH ERROR: pc out of memory. error_byte = %d\n", error_byte);
 
  314         sprintf(error_msg, 
"BH ERROR: write only parameter. error_byte = %d\n", error_byte);
 
  317         sprintf(error_msg, 
"BH ERROR: system configuration unknown. error_byte = %d\n", error_byte);
 
  320         sprintf(error_msg, 
"BH ERROR: no free node address. error_byte = %d\n", error_byte);
 
  323         sprintf(error_msg, 
"BH ERROR: wrong interface type. error_byte = %d\n", error_byte);
 
  326         sprintf(error_msg, 
"BH ERROR: error serial port connection. error_byte = %d\n", error_byte);
 
  329         sprintf(error_msg, 
"BH ERROR: error opening communication. error_byte = %d\n", error_byte);
 
  332         sprintf(error_msg, 
"BH ERROR: communication error. error_byte = %d\n", error_byte);
 
  335         sprintf(error_msg, 
"BH ERROR: error interface bus master. error_byte = %d\n", error_byte);
 
  338         sprintf(error_msg, 
"BH ERROR: timeout answer. error_byte = %d\n", error_byte);
 
  341         sprintf(error_msg, 
"BH ERROR: no start character. error_byte = %d\n", error_byte);
 
  344         sprintf(error_msg, 
"BH ERROR: error first digit. error_byte = %d\n", error_byte);
 
  347         sprintf(error_msg, 
"BH ERROR: buffer overflow in host. error_byte = %d\n", error_byte);
 
  350         sprintf(error_msg, 
"BH ERROR: buffer overflow. error_byte = %d\n", error_byte);
 
  353         sprintf(error_msg, 
"BH ERROR: no answer found. error_byte = %d\n", error_byte);
 
  356         sprintf(error_msg, 
"BH ERROR: error closing communication. error_byte = %d\n", error_byte);
 
  359         sprintf(error_msg, 
"BH ERROR: synchronization error. error_byte = %d\n", error_byte);
 
  362         sprintf(error_msg, 
"BH ERROR: send error. error_byte = %d\n", error_byte);
 
  365         sprintf(error_msg, 
"BH ERROR: protocol error. error_byte = %d\n", error_byte);
 
  368         sprintf(error_msg, 
"BH ERROR: buffer overflow in module. error_byte = %d\n", error_byte);
 
  371         sprintf(error_msg, 
"BH ERROR: unknown error, obscure. error_byte = %d\n", error_byte);
 
  376   if (strlen(error_msg)>0)
 
  377     return BH_STATUS_ERR;
 
  396   for (i=0; i<len; i++) {
 
  397     strncpy(hexchar, str+2*i, 2);
 
  399     sscanf(hexchar, 
"%x", &j);
 
  400     strcat(result, (
const char *)&j);
 
  428   totlen = strlen(rply);
 
  430     strcpy(err_msg, 
"BH ERROR: no string to decode ...");
 
  431     return BH_DECODE_ERR;
 
  434   switch (decode_tag) {
 
  437       sscanf(rply, 
":%02x%s", &len, str);
 
  438       if (totlen != 2*len+5) {
 
  439         strcpy(err_msg, 
"BH ERROR: wrong string length ...");
 
  440         return BH_DECODE_ERR;
 
  442       sscanf(rply, 
":%10x%x", &len, &ivalue);
 
  443       *result = (float)ivalue;
 
  446       sscanf(rply, 
":%02x%s", &len, str);
 
  447       if (totlen != 2*len+5) {
 
  448         strcpy(err_msg, 
"BH ERROR: wrong string length ...");
 
  449         return BH_DECODE_ERR;
 
  451       sscanf(rply, 
":%10x%x", &len, &(hexfloat.ival));
 
  452       *result = hexfloat.fval;
 
  478   totlen = strlen(rply);
 
  480     strcpy(err_msg, 
"BH ERROR: no string to decode ...");
 
  481     return BH_DECODE_ERR;
 
  484   sscanf(rply, 
":%02x%s", &len, str);
 
  485   if (totlen != 2*len+5) {
 
  486     strcpy(err_msg, 
"BH ERROR: wrong string length ...");
 
  487     return BH_DECODE_ERR;
 
  489   sscanf(rply, 
":%10x%02x%s", &ivalue, &len, str);
 
  507   char str[128], err_msg[128];
 
  509   int  cmd_length, process, parameter, decode_tag;
 
  517       decode_tag = BH_STRING;
 
  518       sprintf(str, 
":%02X%02X%02X%02X%02X%02X%02X%02X\r\n",
 
  519                    cmd_length, BH_NODE, BH_GETPARAM, BH_UNCHAINED|process,
 
  520                    BH_UNCHAINED|BH_STRING, process, BH_STRING|parameter, 12);
 
  526       decode_tag = BH_INTEGER;
 
  527       sprintf(str, 
":%02X%02X%02X%02X%02X%02X%02X\r\n",
 
  528                    cmd_length, BH_NODE, BH_GETPARAM, BH_UNCHAINED|process,
 
  529                    BH_UNCHAINED|BH_INTEGER, process, BH_INTEGER|parameter);
 
  535       decode_tag = BH_INTEGER;
 
  536       sprintf(str, 
":%02X%02X%02X%02X%02X%02X%02X\r\n",
 
  537                    cmd_length, BH_NODE, BH_GETPARAM, BH_UNCHAINED|process,
 
  538                    BH_UNCHAINED|BH_LONG, process, BH_LONG|parameter);
 
  544       decode_tag = BH_INTEGER;
 
  545       sprintf(str, 
":%02X%02X%02X%02X%02X%02X%02X\r\n",
 
  546                    cmd_length, BH_NODE, BH_GETPARAM, BH_UNCHAINED|process,
 
  547                    BH_UNCHAINED|BH_LONG, process, BH_LONG|parameter);
 
  550       return BH_CMD_UNKNOWN;
 
  557   status = BD_GETS(str, 
sizeof(str), 
"\r\n", 
BH_TIME_OUT);
 
  563         cm_msg(MERROR, 
"bh_get_send_rcv", 
"Communication error with bronkhorst flowcontroller.");
 
  573         cm_msg(MERROR, 
"bh_get_send_rcv", 
"%s", err_msg);
 
  595   char str[128], err_msg[128];
 
  597   int  cmd_length, process, parameter, decode_tag;
 
  605       decode_tag = BH_INTEGER;
 
  606       sprintf(str, 
":%02X%02X%02X%02X%02X%04X\r\n",
 
  607                    cmd_length, BH_NODE, BH_SETPARAM, BH_UNCHAINED|process,
 
  608                    BH_UNCHAINED|BH_INTEGER|parameter, (
int)value);
 
  615         decode_tag = BH_INTEGER;
 
  616         sprintf(str, 
":%02X%02X%02X%02X%02X%08X\r\n",
 
  617                      cmd_length, BH_NODE, BH_SETPARAM, BH_UNCHAINED|process,
 
  618                      BH_UNCHAINED|BH_LONG|parameter, value*BH_MAX_NEEDLE_VALVE);
 
  624       return BH_CMD_UNKNOWN;
 
  631   status = BD_GETS(str, 
sizeof(str), 
"\r\n", 
BH_TIME_OUT);
 
  636         cm_msg(MERROR, 
"bh_set_send_rcv", 
"Communication error with bronkhorst flowcontroller.");
 
  646         cm_msg(MERROR, 
"bh_set_send_rcv", 
"%s", err_msg);
 
  667   if (strstr(str,
"measured")) {
 
  669     *decode_tag = BH_INTEGER;
 
  671   if (strstr(str,
"setpoint")) {
 
  673     *decode_tag = BH_INTEGER;
 
  675   if (strstr(str,
"fluidtemp")) {
 
  677     *decode_tag = BH_INTEGER;
 
  679   if (strstr(str, 
"ValvePos")) {
 
  681     *decode_tag = BH_INTEGER;
 
  702   INT     status, size, chno;
 
  705   char    bh_id[128], result[128], err_msg[128];
 
  707   cm_get_experiment_database(&hDB, NULL);
 
  710   info = calloc(1, 
sizeof(
BH_INFO));
 
  715   if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
 
  716     cm_msg(MERROR, 
"bh_in_init", 
"bh_in_init: Couldn't create DD/BH in ODB: status=%d", status); 
 
  722   status = db_create_record(hDB, hKey, 
"DD/SCW", 
BH_SCW_STR);
 
  723   if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
 
  724     cm_msg(MERROR, 
"bh_in_init", 
"bh_in_init: Couldn't create DD/SCW in ODB: status=%d", status); 
 
  730   db_find_key(hDB, hKey, 
"DD/BH", &hkeydd);
 
  747     chno = BH_IN_CHANNELS;
 
  748     cm_msg(MERROR,
"BH_in_init", 
"Error, max. number of BH input channels is %d, not %d.", chno, info->
num_channels_in);
 
  758   status = info->
bd(CMD_INIT, hKey, &info->
bd_info);
 
  759   if (status != FE_SUCCESS) {
 
  771     cm_msg(MERROR,
"BH_in_init", 
"Error getting device query from BH, %s",info->
bh_in_settings.
name[0]);
 
  778     cm_msg(MERROR,
"BH_in_init", 
"%s", err_msg);
 
  784   cm_msg(MINFO,
"BH_in_init", 
"Device query of BH yields %s", bh_id);
 
  790     db_find_key(hDB, hKey, 
"DD/SCW", &hkeydd);
 
  792     size = 
sizeof(info->
scw);
 
  793     db_get_record(hDB, hkeydd, &info->
scw, &size, 0);
 
  795     info->
scw.pid = ss_getpid();
 
  796     info->
scw.last_updated = ss_time();
 
  798     db_set_record(hDB, hkeydd, &info->
scw, 
sizeof(info->
scw), 0);
 
  801     status = lem_scw_init(&info->
scw);
 
  802     if (status != LEM_SCW_SUCCESS) {
 
  803       cm_msg(MINFO, 
"bh_in_init", 
"Couldn't register with lem watchdog");
 
  824 INT 
bh_out_init(HNDLE hKey, 
void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
 
  829   cm_get_experiment_database(&hDB, NULL);
 
  835   if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
 
  836     cm_msg(MERROR, 
"bh_out_init", 
"Couldn't create DD: status=%d", status); 
 
  841   db_find_key(hDB, hKey, 
"DD", &hkeydd);
 
  848     chno = BH_OUT_CHANNELS;
 
  849     cm_msg(MERROR,
"bh_out_init", 
"Error, allowed number of BH output channels is %d, not %d.", chno, info->
num_channels_out);
 
  871     lem_scw_exit(&info->
scw);
 
  889   int cmd, status, decode_tag;
 
  897       cm_msg(MINFO, 
"BH_set",
 
  898             "BH_set: set values not possible at the moment, since the bus driver is not available!");
 
  919         cm_msg(MERROR, 
"BH_set", 
"BH communication or command error.");
 
  937   int   cmd, status, decode_tag;
 
  938   char  str[128], err_msg[128];
 
  939   DWORD nowtime, difftime;
 
  960       cm_msg(MERROR, 
"BH_get", 
"too many reconnection failures, bailing out :-(");
 
  968     info->
scw.last_updated = ss_time();
 
  969     lem_scw_update(&info->
scw);
 
  976         cm_msg(MINFO, 
"BH_get", 
"Bronkhorst: reconnection trial ...");
 
  978       if (status != FE_SUCCESS) {
 
  982           cm_msg(MINFO, 
"BH_get", 
"Bronkhorst: reconnection attempted failed");
 
  990           cm_msg(MINFO, 
"BH_get", 
"Bronkhorst: successfully reconnected");
 
 1000   if (cmd == BH_NO_CMD) { 
 
 1012         cm_msg(MERROR, 
"BH_get", 
"BH communication or command error.");
 
 1023           cm_msg(MINFO, 
"BH_get", 
"Bronkhorst: try to disconnect and reconnect the bus driver");
 
 1039         cm_msg(MERROR, 
"BH_get", 
"%s", err_msg);
 
 1045   if (cmd == BH_VALVEOUT) {
 
 1046     *pvalue /= BH_MAX_NEEDLE_VALVE;
 
 1092 INT     channel, status;
 
 1098   va_start(argptr, cmd);
 
 1099   status = FE_SUCCESS;
 
 1104       hKey    = va_arg(argptr, HNDLE);
 
 1105       info    = va_arg(argptr, 
void *);
 
 1106       channel = va_arg(argptr, INT);
 
 1107       flags = va_arg(argptr, DWORD);
 
 1108       bd      = va_arg(argptr, 
void *);
 
 1109       status  = 
bh_in_init(hKey, info, channel, bd);
 
 1113       info   = va_arg(argptr, 
void *);
 
 1118       info    = va_arg(argptr, 
void *);
 
 1119       channel = va_arg(argptr, INT);
 
 1120       pvalue  = va_arg(argptr, 
float*);
 
 1121       status  = 
bh_get(info, channel, pvalue);
 
 1125       info    = va_arg(argptr, 
void *);
 
 1126       channel = va_arg(argptr, INT);
 
 1127       name    = va_arg(argptr, 
char *);
 
 1145 INT     channel, status;
 
 1151   va_start(argptr, cmd);
 
 1152   status = FE_SUCCESS;
 
 1157       hKey    = va_arg(argptr, HNDLE);
 
 1158       info    = va_arg(argptr, 
void *);
 
 1159       channel = va_arg(argptr, INT);
 
 1160       flags = va_arg(argptr, DWORD);
 
 1161       bd      = va_arg(argptr, 
void *);
 
 1166       info    = va_arg(argptr, 
void *);
 
 1167       channel = va_arg(argptr, INT);
 
 1168       value   = (float) va_arg(argptr, 
double);
 
 1169       status  = 
bh_set(info, channel, value);
 
 1173       info    = va_arg(argptr, 
void *);
 
 1174       channel = va_arg(argptr, INT);
 
 1175       name    = va_arg(argptr, 
char *);
 
int bh_decode_number(char *rply, int decode_tag, char *err_msg, float *result)
char name[BH_IN_CHANNELS][32]
input channel names 
#define BH_CMD_ERROR
unvalid command error 
#define BH_READ_ERROR
read error tag 
DWORD lasterrtime
timer for error handling 
INT bh_out_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
INT num_channels_in
number of in-channels 
LEM_SC_WATCHDOG scw
slowcontrol watchdog info structure 
BH_IN_SETTINGS bh_in_settings
internal DD settings for the in-channels 
HNDLE hkey
ODB key for bus driver info. 
INT errorcount
error coutner 
int bh_success(char *str, char *error_msg)
INT bh_out_get_label(BH_INFO *info, INT channel, char *name)
INT bh_set_send_rcv(BH_INFO *info, INT cmd, float value)
INT bh_in_get_label(BH_INFO *info, INT channel, char *name)
INT detailed_msg
flag indicating if detailed status/error messages are wanted 
INT bh_get(BH_INFO *info, INT channel, float *pvalue)
DWORD last_reconnect
timer for bus driver reconnect error handling 
#define BH_TIME_OUT
timeout in (ms) for the communication between pc and bronkhorst 
int ets_logout(void *info, int wait, int detailed_msg)
void * bd_info
private info of bus driver 
INT bh_set(BH_INFO *info, INT channel, float value)
INT bh_in_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
#define BH_DELTA_TIME_ERROR
reset error counter after BH_DELTA_TIME_ERROR seconds 
INT bh_exit(BH_INFO *info)
float last_valid_value[2]
stores the last valid value 
INT startup_tag
tag indicating that the DD is starting (see bh_in_init and BH_out_init) 
INT startup_error
startup error tag; if set, the get and bh_set and bh_get routines wont do anything ...
int bd_connected
flag showing if bus driver is connected 
#define BH_IN_SETTINGS_STR
initializing string for the BH_IN_SETTINGS structure. 
#define BH_MAX_ERROR
maximum number of error messages 
INT bh_flow_out(INT cmd,...)
INT readback_failure
counts the number of readback failures 
INT(* bd)(INT cmd,...)
bus driver entry function 
int first_bd_error
flag showing if the bus driver error message is already given 
BH_OUT_SETTINGS bh_out_settings
internal DD settings for the out-channels 
#define BH_INIT_ERROR
initialize error tag 
INT num_channels_out
number of out-channels 
#define BH_RECONNECTION_TIMEOUT
timeout in (sec) between logout terminal server an reconnection trial 
#define BH_SCW_STR
defines the slowcontrol default watchdog info structure 
#define BH_MAX_READBACK_FAILURE
maximum number of readback failures before a reconnect will take place 
INT scw_in_use
flag indicating if the slowcontrol watchdog shall be used 
char name[BH_OUT_CHANNELS][32]
output channel names 
INT bh_get_send_rcv(BH_INFO *info, INT cmd, char *result)
#define BH_OUT_SETTINGS_STR
initializing string for the BH_OUT_SETTINGS structure. 
void hex2ascii(char *str, int len, char *result)
#define BH_ETS_LOGOUT_SLEEP
sleep time (us) between the telnet commands of the ets_logout 
INT bh_flow_in(INT cmd,...)
int reconnection_failures
how often reconnection failed 
INT bh_get_cmd(char *str, int *decode_tag)
int bh_decode_string(char *rply, char *err_msg, char *result)
#define BH_MAX_RECONNECTION_FAILURE
maximum number of reconnections before bailing off 
INT ets_in_use
flag indicating if the rs232 terminal server is in use