From 86d225a714881af2a971684637a255dafe0a2faf Mon Sep 17 00:00:00 2001 From: zolliker Date: Tue, 19 Jun 2012 07:19:03 +0000 Subject: [PATCH] - improvements in protocols and drivers --- binprot.c | 42 +++++++++++++++++- dumprot.c | 10 +++-- ease.c | 79 ++++++++++++++++++++++++--------- ease.h | 7 +-- haakedriv.c | 8 ++-- ighdriv.c | 8 ++-- ilmdriv.c | 10 ++--- ipsdriv.c | 122 ++++++++++++++++++++++++++++++++++++++------------- itcdriv.c | 13 +++--- linadriv.c | 8 ++-- lsc370driv.c | 8 ++-- lscsupport.c | 2 +- oxinst.c | 21 ++++++--- 13 files changed, 243 insertions(+), 95 deletions(-) diff --git a/binprot.c b/binprot.c index 886c793..dcae992 100644 --- a/binprot.c +++ b/binprot.c @@ -59,7 +59,7 @@ typedef enum {intType, hexType, floatType, skipType, codeType, crcType, dumpType, errorType} BinDataType; // dumpType, errorType must be the last items -typedef enum {modbusCrc, kellerCrc, syconCrc} CrcAlgorithm; +typedef enum {modbusCrc, kellerCrc, rsportCrc, syconCrc} CrcAlgorithm; typedef struct { CrcAlgorithm crcAlgorithm; @@ -104,6 +104,37 @@ static int calc_crc(char *inp, int inpLen) } return crc; } +/*----------------------------------------------------------------------------*/ +static int calc_crc8(char *inp, int inpLen) +{ +/** CRC-8 (x8+x5+x4+1) Algorithm + * crc calculation: + * returns the 8bit CRC value of a message + * crc check: + * returns 0 when the crc appended to the message is correct + */ + + unsigned char crc = 0; + unsigned char data; + int n; + + while (inpLen--) { + data = *(unsigned char *) inp; + for (n = 0; n < 8; n++) { + if ((crc ^ data) & 1) { + crc ^= 0x18; + crc >>= 1; + crc |= 0x80; + } else { + crc >>= 1; + crc &= 0x7f; + } + data >>= 1; + } + inp++; + } + return crc; +} /*----------------------------------------------------------------------------*/ int BinReadItem(Ascon *a) { @@ -250,6 +281,10 @@ int BinHandler(Ascon *a) { DynStringConcatChar(dyn, crc % 256); DynStringConcatChar(dyn, crc / 256); break; + case rsportCrc: + crc = calc_crc8(GetCharArray(dyn), l); + DynStringConcatChar(dyn, crc); + break; } } else if (strncasecmp(item, "int", 3) == 0) { sscanf(item + 3, "%d", &size); @@ -475,6 +510,7 @@ int BinHandler(Ascon *a) { str[l-1] = i; /* fall through */ case modbusCrc: + case rsportCrc: if (calc_crc(str, l) != 0) { DynStringConcat(p->result, "badCRC "); } @@ -503,7 +539,7 @@ static int BinInit(Ascon * a, SConnection * con, int argc, char *argv[]) { BinPrivate *p; -/* argv[2] may be modbus-crc (default), keller-crc or sycon-crc */ +/* argv[2] may be modbus-crc (default), keller-crc, rsport-crc or sycon-crc */ if (argc < 2) { return 0; @@ -517,6 +553,8 @@ static int BinInit(Ascon * a, SConnection * con, int argc, char *argv[]) p->crcAlgorithm = kellerCrc; } else if (strcasecmp(argv[2], "sycon-crc") == 0) { p->crcAlgorithm = syconCrc; + } else if (strcasecmp(argv[2], "rsport-crc") == 0) { + p->crcAlgorithm = rsportCrc; } else if (strcasecmp(argv[2], "modbus-crc") != 0) { SCPrintf(con, eError, "ERROR: unknown crc-algorithm %s", argv[2]); a->private = NULL; diff --git a/dumprot.c b/dumprot.c index 1235608..3081e20 100644 --- a/dumprot.c +++ b/dumprot.c @@ -2,7 +2,7 @@ #include "ascon.i" /* - * this is a scriptcontext driver connecting to its own sics server + * this is a scriptcontext driver connecting to its own sics server. * after a send command the configured polling script is called repeatedly * with the sent command as argument until it returns something else than 0 * @@ -12,8 +12,9 @@ /*----------------------------------------------------------------------------*/ int DumProtHandler(Ascon *a) { - Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics); - int ret, l = -1; + Tcl_Interp *pTcl; + int ret; + char *result = NULL; int iRet = 1; @@ -30,7 +31,8 @@ int DumProtHandler(Ascon *a) break; case AsconReadStart: case AsconReading: - ret = Tcl_EvalEx(pTcl, GetCharArray(a->wrBuffer), l, 0); + pTcl = InterpGetTcl(pServ->pSics); + ret = Tcl_EvalEx(pTcl, GetCharArray(a->wrBuffer), GetDynStringLength(a->wrBuffer), 0); result = (char *) Tcl_GetStringResult(pTcl); DynStringCopy(a->rdBuffer, result); if (ret != TCL_OK || strcmp(result, "0") != 0) { diff --git a/ease.c b/ease.c index 8a62496..c0c06a2 100644 --- a/ease.c +++ b/ease.c @@ -15,6 +15,7 @@ Markus Zolliker, March 2005 #include #include #include +#include #include "sics.h" #include "splitter.h" #include "ease.h" @@ -50,10 +51,16 @@ EaseDriv *EaseDrivCast(void *object) } /*----------------------------------------------------------------------------*/ -void EaseStop(EaseBase * eab) +void EaseStop(EaseBase * eab, char *reason) { - FsmStop(eab->task, eab->idle); - closeRS232(eab->ser); + if (eab->state >= EASE_idle) { + FsmStop(eab->task, eab->idle); + closeRS232(eab->ser); + } + if (reason != NULL) { + snprintf(eab->msg, sizeof eab->msg, "offline (%s)", reason); + ParPrintf(eab, eLogError, "ERROR: %s", eab->msg); + } eab->state = EASE_notconnected; } @@ -92,7 +99,7 @@ void EaseWriteError(EaseBase * eab) case EASE_DEV_CHANGED: ParPrintf(eab, eError, "ERROR: controller was exchanged on %s", eab->p.name); - /* EaseStop(eab); */ + EaseStop(eab, "controller exchanged"); break; case EASE_FAULT: ParPrintf(eab, eError, "ERROR: error on %s", eab->p.name); @@ -112,7 +119,11 @@ void EaseWrite(EaseBase * eab, char *cmd) char trash[64]; int l; - if (eab->errCode || eab->state == EASE_expect) + if (eab->errCode) { + eab->state = EASE_abort; + return; + } + if (eab->state == EASE_expect || eab->state == EASE_abort) return; while (availableRS232(eab->ser) == 1) { l = sizeof(trash); @@ -129,7 +140,7 @@ void EaseWrite(EaseBase * eab, char *cmd) if (iRet < 0) { FsmStop(eab->task, eab->idle); snprintf(eab->msg, sizeof eab->msg, - "connection to %s:%d lost", eab->ser->pHost, eab->ser->iPort); + "offline (connection to %s:%d lost)", eab->ser->pHost, eab->ser->iPort); ParPrintf(eab, eError, "ERROR: %s", eab->msg); closeRS232(eab->ser); eab->state = EASE_notconnected; @@ -143,6 +154,7 @@ void EaseWrite(EaseBase * eab, char *cmd) } eab->state = EASE_expect; eab->cmdtime = time(NULL); + eab->chktime = time(NULL) + 5; } /*----------------------------------------------------------------------------*/ @@ -222,8 +234,10 @@ static int EaseRestart(EaseBase * eab) EaseWriteError(eab); return -1; } - snprintf(eab->msg, sizeof eab->msg, - "connecting to %s:%d", eab->ser->pHost, eab->ser->iPort); + if (eab->cmdtime == 0) { + snprintf(eab->msg, sizeof eab->msg, + "connecting to %s:%d", eab->ser->pHost, eab->ser->iPort); + } return 0; } @@ -232,7 +246,7 @@ int EaseHandler(EaseBase * eab) { EaseDriv *ead = EaseDrivCast(eab);; int iret; - + EaseSavePars(); if (ead && ead->stopped && ead->hwstate == HWBusy) { ead->stopped = 0; @@ -243,6 +257,9 @@ int EaseHandler(EaseBase * eab) } } + if (eab->state == EASE_offline) { + return 0; + } if (eab->state == EASE_expect) { if (eab->cmdtime != 0 && time(NULL) > eab->cmdtime + eab->p.period * 2) { snprintf(eab->msg, sizeof eab->msg, "no response since %d sec", @@ -254,6 +271,9 @@ int EaseHandler(EaseBase * eab) snprintf(eab->msg, sizeof eab->msg, "no response"); } if (eab->state == EASE_notconnected) { + if (time(0) >= eab->cmdtime + 10) { + EaseRestart(eab); + } return 0; } if (eab->state == EASE_connecting) { @@ -261,11 +281,19 @@ int EaseHandler(EaseBase * eab) if (iret == 0) return 0; /* waiting for connection */ if (iret < 0) { - snprintf(eab->msg, sizeof eab->msg, - "connection for %s failed", eab->p.name); - ParPrintf(eab, eError, "%s", eab->msg); + if (errno == ECONNREFUSED) { + snprintf(eab->msg, sizeof eab->msg, + "Connection refused"); + } else { + snprintf(eab->msg, sizeof eab->msg, + "Connection failed (%s)", strerror(errno)); + } + if (eab->cmdtime == 0) { + ParPrintf(eab, eError, "%s: %s", eab->p.name, eab->msg); + } closeRS232(eab->ser); eab->state = EASE_notconnected; + eab->cmdtime = time(0); return 0; } else { if (eab->tmo > 20) { @@ -278,10 +306,13 @@ int EaseHandler(EaseBase * eab) } if (eab->errCode) { if (eab->errCode == BADSEND) { + eab->cmdtime = 0; /* means: this is not a repeated restart */ EaseRestart(eab); return 0; } - EaseWriteError(eab); + if (eab->state != EASE_abort) { + EaseWriteError(eab); + } eab->errCode = 0; if (ead) { ead->hwstate = HWFault; @@ -379,6 +410,9 @@ static long EaseIdle(long pc, void *object) case __LINE__: /**********************************/ eab->startOk = 1; + if (eab->state == EASE_abort) { + eab->state = EASE_idle; + } rd: /* if (eab->state == EASE_lost) { @@ -475,7 +509,7 @@ int EaseGetUpdate(void *object, int flag) assert(flag <= eab->maxflag); i = flag / EASE_FLAGBITS; if ((1 << (flag % EASE_FLAGBITS)) & eab->updateFlags[i]) { - return flag; + return 1; } return 0; } @@ -673,7 +707,9 @@ static int EaseStdHandler(void *object) if (eab->state < EASE_idle) goto quit; if (availableNetRS232(eab->ser) || availableRS232(eab->ser)) { - eab->msg[0] = '\0'; + if (strncmp(eab->msg, "ERROR:", 6) != 0) { + eab->msg[0] = '\0'; + } l = sizeof(eab->ans); iret = readRS232TillTerm(eab->ser, eab->ans, &l); if (eab->state != EASE_expect && eab->state != EASE_lost) { @@ -781,7 +817,6 @@ static int EaseInit(SConnection * pCon, EaseBase * eab, int argc, eab->startOk = 0; eab->errCode = 0; - eab->cmdtime = 0; eab->version[0] = '\0'; eab->maxflag = maxflag; eab->sendCmd = NULL; @@ -799,6 +834,7 @@ static int EaseInit(SConnection * pCon, EaseBase * eab, int argc, setRS232Debug(eab->ser, 0); eab->task = NULL; + eab->cmdtime = 0; /* means: this is not a repeated restart */ if (EaseRestart(eab) < 0) return -1; eab->task = FsmStartTask(eab, eab->handler, eab->idle, eab->p.name); @@ -920,6 +956,7 @@ void EaseMsgPar(void *object) assert(eab); ParName("status"); + ParAccess(usUser); ParLogAs(NULL); if (eab->msg[0] == '\0') { ParList(""); /* do not list when empty */ @@ -976,8 +1013,9 @@ int EaseRestartWrapper(void *object, void *userarg, int argc, char *argv[]) eab->ser->iPort = port; } if (eab->task) { - EaseStop(eab); + EaseStop(eab, NULL); } + eab->cmdtime = 0; /* means: this is not a repeated restart */ EaseRestart(eab); return 0; } @@ -987,9 +1025,10 @@ int EaseDisconnectWrapper(void *object, void *userarg, int argc, char *argv[]) { EaseBase *eab = EaseBaseCast(object); - ParPrintf(object, eWarning, "%s disabled (enable with: %s restart)", - eab->p.name, eab->p.name); - EaseStop(eab); + snprintf(eab->msg, sizeof eab->msg, "disconnected"); + ParPrintf(object, eWarning, "%s", eab->msg); + EaseStop(eab, NULL); + eab->state = EASE_offline; return 0; } diff --git a/ease.h b/ease.h index b6d4c54..640a6ac 100644 --- a/ease.h +++ b/ease.h @@ -22,8 +22,8 @@ Markus Zolliker, March 2005 #define EASE_RUN 0 -typedef enum { EASE_connecting, EASE_notconnected, - EASE_idle, EASE_read, EASE_expect, EASE_lost +typedef enum { EASE_offline, EASE_notconnected, EASE_connecting, + EASE_idle, EASE_abort, EASE_read, EASE_expect, EASE_lost } EaseState; typedef enum { EASE_notMonitored, EASE_inTolerance, EASE_outOfTolerance } EaseTolState; @@ -41,6 +41,7 @@ typedef struct { int errCode; /* error code of last operation. not changed on success */ EaseState state; time_t cmdtime; + time_t chktime; int syntax; /* not used in ease, may be used by the driver. used by oxinst.c */ char cmd[64]; char ans[64]; @@ -89,7 +90,7 @@ void EaseKillDriv(EaseDriv * ead); void EaseDrivPar(void *object, char *fmt, char *unit); void EasePchk(void *drv); void EaseParHasChanged(void); -void EaseStop(EaseBase * eab); +void EaseStop(EaseBase * eab, char *reason); int EaseCheckDoit(EaseBase * eab); int EaseNextFullRead(EaseBase * eab); diff --git a/haakedriv.c b/haakedriv.c index 4d28ffc..0c1e936 100644 --- a/haakedriv.c +++ b/haakedriv.c @@ -285,7 +285,8 @@ static long HaakeStart(long pc, void *object) Haake *drv = ParCast(&haakeClass, object); EaseBase *eab = object; char unitcmd[8] = "W TE K"; - + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -293,10 +294,9 @@ static long HaakeStart(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ if (0 != strncmp(eab->version, "1P/H", 4)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown temperature controller version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } ParPrintf(drv, eLog, "connected to haake thermostat %s", diff --git a/ighdriv.c b/ighdriv.c index bb2b381..4e9bc9b 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -567,7 +567,8 @@ static long IghStart(long pc, void *object) { Igh *drv = ParCast(&ighClass, object); EaseBase *eab = object; - + char msg[128]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -575,10 +576,9 @@ static long IghStart(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ if (0 != strncmp(eab->version, "IGH", 3)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown gas handling system version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } if (strstr(eab->version, "2.01") != NULL) { diff --git a/ilmdriv.c b/ilmdriv.c index 36868df..7346698 100644 --- a/ilmdriv.c +++ b/ilmdriv.c @@ -1,7 +1,7 @@ /*--------------------------------------------------------------------------- ilmdriv.c -Driver for the Oxford Instruments ILM503/ILM4 temperature controller +Driver for the Oxford Instruments ILM200 series level monitor Version 2 (based on ease). Markus Zolliker, April 2005 @@ -193,7 +193,8 @@ static long IlmStart(long pc, void *object) { Ilm *drv = ParCast(&ilmClass, object); EaseBase *eab = object; - + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -201,10 +202,9 @@ static long IlmStart(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ if (0 != strncmp(eab->version, "ILM", 3)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown level meter version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } ParPrintf(drv, eLog, "connected to %s", eab->version); diff --git a/ipsdriv.c b/ipsdriv.c index be69586..6182eca 100644 --- a/ipsdriv.c +++ b/ipsdriv.c @@ -48,6 +48,7 @@ typedef struct { float measured; /* measured current */ float inductance; /* induction (read only on startup) */ float ampRamp; /* ramp in amps (read only on startup) */ + float trainedTo; /* use training mode when the field is higher than this value (slow ramp limits) */ char *startScript; /* script to be called on startup */ int persmode; /* 0: delayed persistant mode, 1: go to persistant mode, 2: leave switch on */ int persdelay; /* wait time for delayed persistant mode */ @@ -56,6 +57,7 @@ typedef struct { int nowait; /* 0: normal, 1: drive finishes immediately, ramp in background */ int perswait; /* wait time for persistent mode workaround (sec) */ int heaterFault; + int trainMode; /* 0/1 read back for train mode, 2/3 command for trainMode */ DoThis dothis; char *fmt; /* fmt for field */ int force; /* force = 2: put heater switch even when stored field does not match */ @@ -79,8 +81,10 @@ static int IpsOk(Ips * drv) if (drv->lastfield == PAR_NAN) { drv->lastfield = drv->persfield; } - if (fabs(drv->persfield - drv->lastfield) < 1e-5) + if (fabs(drv->persfield - drv->lastfield) < 1e-2) { + drv->lastfield = drv->persfield; return 1; + } if (drv->force != 0) return 1; ParPrintf(drv, eWarning, @@ -249,6 +253,17 @@ void IpsParDef(void *object) ParList(""); ParFloat(&drv->inductance, 0.0); + ParName("trainedTo"); + ParAccess(usUser); + ParFmt(drv->fmt); + ParTail("Tesla"); + ParFloat(&drv->trainedTo, 0.0); + + ParName("trainMode"); + ParEnum(onOff); + ParList(0); + ParInt(&drv->trainMode, PAR_NAN); + ParName("startScript"); ParAccess(usUser); ParList(""); @@ -283,7 +298,8 @@ static void IpsStatus(Ips * drv) char *ans; int *code; int swi; - + char *errmsg; + if (drv->d.b.state != EASE_read) return; ans = drv->d.b.ans; @@ -296,28 +312,38 @@ static void IpsStatus(Ips * drv) } switch (ans[1]) { case '0': + if (ans[6] > '3') { + errmsg = "ERROR: auto-run-down (low He level)"; + } else { + errmsg = ""; + } break; case '1': - ParPrintf(drv, eError, "magnet quenched"); + errmsg = "ERROR: magnet quenched"; drv->lastfield = PAR_NAN; - *code = EASE_FAULT; - return; + break; case '2': - ParPrintf(drv, eError, "IPS overheated"); - *code = EASE_FAULT; - return; + errmsg = "ERROR: IPS overheated"; + break; case '4': - ParPrintf(drv, eError, "IPS warming up"); - *code = EASE_FAULT; - return; + errmsg = "ERROR: IPS warming up"; + break; case '8': - ParPrintf(drv, eError, "IPS fault"); + errmsg = "ERROR: IPS fault"; *code = EASE_FAULT; - return; + break; default: - ParPrintf(drv, eError, "illegal status response"); + errmsg = "ERROR: illegal status response"; + } + if (errmsg[0] != '\0') { + if (strcmp(errmsg, drv->d.b.msg) != 0) { + snprintf(drv->d.b.msg, sizeof drv->d.b.msg, "%s", errmsg); + ParPrintf(drv, eError, "%s", errmsg); + } *code = EASE_FAULT; return; + } else { + drv->d.b.msg[0]='\0'; /* clear status */ } if (ans[6] != '3') { if (drv->remote == 2) { /* remote state monitoring local switch */ @@ -338,6 +364,7 @@ static void IpsStatus(Ips * drv) drv->heaterFault = 1; return; } + drv->trainMode = (ans[10] >= '4'); drv->heaterFault = 0; if (ans[8] == '1') { swi = 1; @@ -376,6 +403,9 @@ static long IpsRead(long pc, void *object) switch (pc) { default: /* FSM BEGIN ****************************** */ + if (eab->state == EASE_abort) { + eab->state = EASE_idle; + } EasePchk(drv); EaseWrite(eab, "X"); return __LINE__; @@ -407,13 +437,14 @@ static long IpsRead(long pc, void *object) IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield)); checktodo: + if (eab->msg[0] != '\0') goto quit; /* no action when in error */ now = time(NULL); if (drv->persmode == 2) { /* persistent mode off */ drv->dothis = NOTHING; goto nothing; } else { if (drv->perswitch) { - if (drv->persmode == 1 || now > drv->tim + drv->persdelay) { + if ((drv->persmode == 1 && now > drv->tim + 10) || now > drv->tim + drv->persdelay) { drv->dothis = SWITCH_OFF; } else { drv->dothis = NOTHING; @@ -450,6 +481,9 @@ static long IpsRead(long pc, void *object) goto quit; switch_off: + EaseWrite(eab, "A0"); + return __LINE__; + case __LINE__: /**********************************/ EaseWrite(eab, "H0"); drv->perswitch = 0; drv->swtim = time(NULL); @@ -543,10 +577,12 @@ static long IpsStart(long pc, void *object) float value; Tcl_Interp *pTcl = NULL; int iRet; + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ - EaseWrite(eab, "V"); + EaseWrite(eab, "V\rQ4"); /* get version and switch to ext. resolution */ return __LINE__; case __LINE__: /**********************************/ if (0 == strncmp(eab->version, "IPS120", 6)) { @@ -554,10 +590,9 @@ static long IpsStart(long pc, void *object) } else if (0 == strncmp(eab->version, "PS", 2)) { eab->syntax = 0; } else { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown power supply version: %s", eab->version); - ParPrintf(drv, eLogError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } ParPrintf(drv, eLog, "connected to %s", eab->version); @@ -621,9 +656,8 @@ static long IpsStart(long pc, void *object) pTcl = InterpGetTcl(pServ->pSics); iRet = Tcl_Eval(pTcl, drv->startScript); if (iRet != TCL_OK) { - snprintf(eab->msg, sizeof eab->msg, "%s", pTcl->result); - ParPrintf(drv, eLogError, "ERROR: %s", eab->msg); - EaseStop(eab); + snprintf(msg, sizeof msg, "%s", pTcl->result); + EaseStop(eab, msg); goto quit; } eab->msg[0]='\0'; @@ -647,15 +681,24 @@ static long IpsChangeField(long pc, void *object) switch (pc) { default: /* FSM BEGIN ****************************** */ + + if (eab->syntax == 0) { + EaseWrite(eab, "C3"); /* set remote */ + } else { + EaseWrite(eab, "C3\rQ4"); /* set remote and repeat extended resolution (in case of power failure) */ + } + drv->remote = 1; /* remote state */ + return __LINE__; + case __LINE__: /**********************************/ + if (!EaseGetUpdate(drv, EASE_RUN)) { + /* an other flag than EASE_RUN was set -> should not be the case */ + return 0; + } EaseSetUpdate(eab, EASE_RUN, 0); if (drv->nowait) { drv->d.hwstate = HWIdle; drv->d.eMode = EVMonitor; /* finish drive, continue in background */ } - EaseWrite(eab, "C3"); - drv->remote = 1; /* remote state */ - return __LINE__; - case __LINE__: /**********************************/ EaseWrite(eab, "F7"); /* switch to tesla on display */ return __LINE__; case __LINE__: /**********************************/ @@ -725,7 +768,7 @@ static long IpsChangeField(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ - if (fabs(drv->current - drv->lastfield) > 1e-5) + if (fabs(drv->current - drv->lastfield) >= 1e-4) goto stab1; stab2: @@ -763,6 +806,7 @@ static long IpsChangeField(long pc, void *object) ParLog(drv); start_ramp: FsmWait(1); + drv->tim = time(NULL); return __LINE__; case __LINE__: /**********************************/ @@ -809,9 +853,7 @@ static long IpsChangeField(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ ramp = OxiGet(eab, 3, NULL, drv->ramp); - step = ramp / 3; /* step = ramp * 20 sec */ - if (step < 0.001) - step = 0.001; + step = fabs(ramp / 3) + 0.001; /* step = ramp * 20 sec */ if (drv->d.targetValue > drv->current + step) { fld = drv->current + step; } else if (drv->d.targetValue < drv->current - step) { @@ -821,8 +863,28 @@ static long IpsChangeField(long pc, void *object) if (fabs(drv->current - drv->d.targetValue) < 1e-5) goto target_reached; } + if (fabs(fld) >= drv->trainedTo) { + if (drv->trainMode == 0) { + drv->trainMode = 3; /* remember that we must go to train mode */ + } + drv->trainedTo = fabs(fld); + } else { + if (drv->trainMode == 1) { + drv->trainMode = 2; /* remember that we must go to fast mode */ + } + } OxiSet(eab, "J", fld, 3); return __LINE__; + case __LINE__: /**********************************/ + if (drv->trainMode < 2) goto ramping; + if (drv->trainMode == 2) { + ParPrintf(drv, -1, "IPS: switch off train mode"); + EaseWrite(eab, "M1"); + } else { + ParPrintf(drv, -1, "IPS: switch to train mode (slow ramp)"); + EaseWrite(eab, "M5"); + } + return __LINE__; case __LINE__: /**********************************/ goto ramping; diff --git a/itcdriv.c b/itcdriv.c index 1a702d1..5474e96 100644 --- a/itcdriv.c +++ b/itcdriv.c @@ -731,7 +731,8 @@ static long ItcStart(long pc, void *object) { Itc *drv = ParCast(&itcClass, object); EaseBase *eab = object; - + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -740,10 +741,9 @@ static long ItcStart(long pc, void *object) case __LINE__: /**********************************/ if (eab->syntax == TESLATRON) { if (0 != strncmp(eab->version, "TESLATRON", 9)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown teslatron version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } } else { @@ -752,11 +752,10 @@ static long ItcStart(long pc, void *object) } else if (0 == strncmp(eab->version, "ITC4", 4)) { eab->syntax = 0; } else { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown temperature controller version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } } diff --git a/linadriv.c b/linadriv.c index 3bcd0b4..619ebe0 100644 --- a/linadriv.c +++ b/linadriv.c @@ -233,7 +233,8 @@ static long LinaStart(long pc, void *object) { Lina *drv = ParCast(&linaClass, object); EaseBase *eab = object; - + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -241,10 +242,9 @@ static long LinaStart(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ if (0 != strncmp(eab->version, "7265", 4)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown lock in amplifier version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } ParPrintf(drv, eLog, "connected to %s", eab->version); diff --git a/lsc370driv.c b/lsc370driv.c index eac66d4..29fb6b3 100644 --- a/lsc370driv.c +++ b/lsc370driv.c @@ -405,7 +405,8 @@ static long Lsc370Start(long pc, void *object) { Lsc370 *drv = ParCast(&lsc370Class, object); EaseBase *eab = object; - + char msg[256]; + switch (pc) { default: /* FSM BEGIN ****************************** */ EasePchk(drv); @@ -413,10 +414,9 @@ static long Lsc370Start(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ if (0 != strncmp(eab->version, "LSCI,MODEL370", 13)) { - snprintf(eab->msg, sizeof eab->msg, + snprintf(msg, sizeof msg, "unknown temperature controller version: %s", eab->version); - ParPrintf(drv, eError, "ERROR: %s", eab->msg); - EaseStop(eab); + EaseStop(eab, msg); goto quit; } ParPrintf(drv, eLog, "connected to %s", eab->version); diff --git a/lscsupport.c b/lscsupport.c index 4d1d8f7..9f6164b 100644 --- a/lscsupport.c +++ b/lscsupport.c @@ -56,7 +56,7 @@ int LscHandler(void *object) eab->state = EASE_idle; goto quit; } else { - eab->tmo = 120; + /* eab->tmo = 120; do not know why this is needed */ } } if (iret != 1) { diff --git a/oxinst.c b/oxinst.c index a130a22..78c3a09 100644 --- a/oxinst.c +++ b/oxinst.c @@ -68,7 +68,9 @@ int OxiHandler(void *object) if (eab->state < EASE_idle) goto quit; if (availableNetRS232(eab->ser) || availableRS232(eab->ser)) { - eab->msg[0] = '\0'; + if (strncmp(eab->msg, "ERROR:", 6) != 0) { + eab->msg[0] = '\0'; + } l = sizeof(eab->ans); iret = readRS232TillTerm(eab->ser, eab->ans, &l); if (eab->state != EASE_expect && eab->state != EASE_lost) { @@ -82,8 +84,8 @@ int OxiHandler(void *object) if (strcmp(eab->ans, "??ck") == 0) { if (eab->state == EASE_lost) { EaseWrite(eab, "V"); - goto quit; } + goto quit; } else if (eab->state == EASE_lost) { goto quit; } else if (eab->cmd[0] == 'V') { @@ -100,14 +102,14 @@ int OxiHandler(void *object) goto quit; } else if (eab->cmd[2] == 'k') { /* ?ck */ } else { - eab->tmo = 120; /* long timeout: the user may block the response with the adjust keys */ - if (eab->syntax <= -8) { + eab->tmo = 20; /* long timeout: the user may block the response with the adjust keys */ + if (eab->syntax <= -8) { /* OLDIGH */ corr = OxiCorrect(eab->ans); if (corr) { -// ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr); +/* ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr); */ } } - if (eab->cmd[0] != eab->ans[0]) { + if (eab->cmd[0] != eab->ans[0] && eab->cmd[0] != '{') { iret = EASE_ILL_ANS; } } @@ -119,6 +121,11 @@ int OxiHandler(void *object) } eab->state = EASE_read; } else if (eab->state == EASE_expect) { + if (time(NULL) > eab->chktime) { + writeRS232(eab->ser, "?ck", 3); + ParPrintf(eab, -2, "cmd: ?ck"); + eab->chktime = time(NULL); + } if (time(NULL) > eab->cmdtime + eab->tmo) { eab->state = EASE_lost; } @@ -177,7 +184,7 @@ void OxiSet(EaseBase * eab, char *cmd, double val, int dig) f = fabs(val); if (f < 1.0) f = 1.0; - dig = 5 - log10(f); + dig = 7 - log10(f); if (dig < 0) dig = 0; }