Files
sicspsi/oxinst.c
zolliker 01fce80d95 - changed OxiGet
- various bug fixes and improvements
2005-11-17 07:57:19 +00:00

169 lines
4.4 KiB
C

/*---------------------------------------------------------------------------
oxinst.c
Communication routines for Oxford Instruments equipment
Markus Zolliker, March 2005
----------------------------------------------------------------------------
there is no error return value, eab->errCode is used. On success, eab->errCode
is not changed, i.e. an existing errCode is not overwritten.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fortify.h>
#include "sics.h"
#include "oxinst.h"
/*----------------------------------------------------------------------------*/
char *OxiCorrect(char *str) {
/* there are sometimes communication errors with the IGH
as the errors always follow the same pattern, they can
be corrected, with the following code. The argument
is corrected in place, the result is NULL or a text
describing the conversion */
int i;
unsigned char chr;
static char buf[32];
char *result = NULL;
for (i=0; i<=24; i++, str++) {
chr = *str;
if (chr == 0) return result;
if (chr > 0x60) {
if (chr > 0xC0) {
chr -= 0x80;
} else {
chr -= 0x40;
}
snprintf(buf, sizeof buf, "%2.2x->%2.2x (%c)", *str, chr, chr);
*str = chr;
result = buf;
}
}
if (result) {
strcat(buf, " overflow");
return result;
} else {
return "overflow";
}
}
/*----------------------------------------------------------------------------*/
int OxiHandler(void *object) {
int iret, l;
EaseBase *eab = EaseBaseCast(object);
char *corr;
if (eab->state < EASE_idle) goto quit;
if (availableNetRS232(eab->ser) || availableRS232(eab->ser)) {
eab->msg[0] = '\0';
l = sizeof(eab->ans);
iret = readRS232TillTerm(eab->ser, eab->ans, &l);
if (eab->state != EASE_expect && eab->state != EASE_lost) {
if (iret == 1) {
ParPrintf(eab, eError, "unexpected answer: %s", eab->ans);
}
goto quit;
}
if (iret == 1) {
if (eab->syntax <= -8) {
corr = OxiCorrect(eab->ans);
if (corr) {
ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr);
}
}
ParPrintf(eab, -2, "ans: %s", eab->ans);
if (strcmp(eab->ans, "??ck") == 0) {
if (eab->state == EASE_lost) {
EaseWrite(eab, "V");
goto quit;
}
} else if (eab->state == EASE_lost) {
goto quit;
} else if (eab->cmd[0] == 'V') {
if (strcmp(eab->ans, eab->version) == 0) {
/* we are still connected with the same device */
} else if (*eab->version == '\0') {
strncat(eab->version, eab->ans, sizeof(eab->version)-1);
} else { /* version (and therefore device) changed */
eab->errCode = EASE_DEV_CHANGED;
eab->state = EASE_idle;
goto error;
}
eab->state = EASE_idle;
goto quit;
} else if (eab->cmd[2] == 'k') { /* ?ck */
} else if (eab->cmd[0] != eab->ans[0]) {
iret = EASE_ILL_ANS;
}
}
if (iret != 1) {
eab->errCode = iret;
eab->state = EASE_idle;
goto error;
}
eab->state = EASE_read;
} else if (eab->state == EASE_expect) {
if (time(NULL) > eab->cmdtime+20) {
eab->state = EASE_lost;
}
} else if (eab->state == EASE_lost) {
if (time(NULL) > eab->cmdtime) {
EaseWrite(eab, "?ck");
eab->state = EASE_lost;
}
}
goto quit;
error:
/* EaseWriteError(eab); */
quit:
return EaseHandler(eab);
}
double OxiGet(EaseBase *eab, int dig, int *pdig, double old) {
char *endp, *p;
double val;
if (eab->state != EASE_read) {
eab->errCode = EASE_ILL_ANS;
return old;
}
p = strchr(eab->ans, '.');
if (p) {
if (pdig != NULL) {
*pdig = strlen(eab->ans) - (p - eab->ans) - 1;
}
val=strtod(eab->ans+1, &endp);
if (*endp != '\0') {
eab->errCode = EASE_ILL_ANS;
return old;
}
} else {
val=strtol(eab->ans+1, &endp, 10);
if (*endp != '\0') {
eab->errCode = EASE_ILL_ANS;
return old;
}
if (eab->syntax <= 0) { /* old style format */
for (; dig > 0; dig--) val=val*0.1;
}
}
return val;
}
void OxiSet(EaseBase *eab, char *cmd, double val, int dig) {
char buf[64];
int l;
if (eab->syntax <= 0) {
snprintf(buf, sizeof(buf), "%s%.*f", cmd, dig, val);
} else {
snprintf(buf, sizeof(buf), "%s%f", cmd, val);
}
EaseWrite(eab, buf);
}