diff --git a/binprot.c b/binprot.c index 04965a9..c3a3c6b 100644 --- a/binprot.c +++ b/binprot.c @@ -3,6 +3,7 @@ #include "ascon.h" #include "ascon.i" #include "dynstring.h" +#include "cnvrt.h" /* * this is a (scriptcontext) general binary protocol driver @@ -64,65 +65,6 @@ typedef struct { int dumpFrom; } BinPrivate; -/*-------------------------------------------------------------------------*/ -static void double2ieee(double input, char ieee[4]) -{ - -/* convert double to IEEE 32 bit floating number (denormalized numbers are considered as zero) */ - - long mantissa; - int exponent; - - if (input == 0) { - ieee[0] = 0; - ieee[1] = 0; - ieee[2] = 0; - ieee[3] = 0; - } else { - mantissa = 0x1000000 * (frexp(fabs(input), &exponent)); - exponent = exponent - 1 + 127; - if (exponent < 0) { - exponent = 0; - } else if (exponent > 0xFE) { - exponent = 0xFE; - } - if (input < 0) { - ieee[0] = 0x80 | (exponent >> 1); - } else { - ieee[0] = exponent >> 1; - } - ieee[1] = (exponent & 1) << 7 | ((mantissa & 0x7F0000) >> 16); - ieee[2] = (mantissa & 0xFF00) >> 8; - ieee[3] = mantissa & 0xFF; - } - return; -} - -/*-------------------------------------------------------------------------*/ -static double ieee2double(char ieee[4]) -{ - -/* IEEE 32 bit floating number to double (denormalized numbers are considered as zero) */ - - long mantissa; - double output; - int exponent; - - mantissa = ((ieee[1] << 16) & 0x7FFFFF) - | ((ieee[2] << 8) & 0xFF00) - | ((ieee[3]) & 0xFF); - - exponent = (ieee[0] & 0x7F) * 2 + ((ieee[1] >> 7) & 1); /* raw exponent */ - if (exponent == 0 && mantissa == 0) { - return 0.0; - } - output = ldexp(mantissa, -23) + 1.0; - if (ieee[0] & 0x80) { - output = -output; - } - return output * ldexp(1, exponent - 127); -} - /*----------------------------------------------------------------------------*/ static int calc_crc(char *inp, int inpLen) { diff --git a/ighdriv.c b/ighdriv.c index 13b5bde..bb2b381 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -271,8 +271,12 @@ static void IghParDef(void *object) vList[l] = '\0'; ParPrintf(NULL, eValue, "open valves:%s", vList); } + EaseBasePar(drv); EaseSendPar(drv); + if (eab->syntax != OLDIGH) { + EaseDrivPar(drv, "%.5g", "K"); + } ParStdDef(); EaseMsgPar(eab); } @@ -324,12 +328,14 @@ void IghStatus(Igh * drv) drv->e = ans[20] - '0'; } } +/* if (ans[5] != '3' && drv->remote == 2) { ParPrintf(drv, eError, "IGH switched to local"); *code = EASE_FAULT; drv->remote = 1; return; } +*/ } /*----------------------------------------------------------------------------*/ @@ -710,6 +716,9 @@ static long IghSet(long pc, void *object) if (drv->mixP > 0) { drv->e = IghPower2Range(drv->mixP); mp = drv->mixP / IghRange2Max(drv->e) * 2000; + if (mp < 2001 && mp > 1999) { + mp = 1999; + } } else { mp = 0; /* range unchanged for external heater signal */ } @@ -727,10 +736,6 @@ static long IghSet(long pc, void *object) case __LINE__: /**********************************/ goto loop; - EaseWrite(eab, "A1"); - return __LINE__; - case __LINE__: /**********************************/ - set_max_pow: if (drv->e == 0) goto seta0; @@ -738,10 +743,11 @@ static long IghSet(long pc, void *object) EaseWrite(eab, buf); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "M0"); + if (drv->a == 2) goto loop; + EaseWrite(eab, "A1"); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "A1"); + EaseWrite(eab, "M0"); return __LINE__; case __LINE__: /**********************************/ goto loop; @@ -760,6 +766,7 @@ static long IghSet(long pc, void *object) drv->d.targetValue = 0; if (drv->d.targetValue > 1.999) drv->d.targetValue = 1.999; + drv->setT = drv->d.targetValue; OxiSet(eab, "T", drv->d.targetValue, 4); return __LINE__; case __LINE__: /**********************************/ diff --git a/ipsdriv.c b/ipsdriv.c index fe16009..6965366 100644 --- a/ipsdriv.c +++ b/ipsdriv.c @@ -31,27 +31,38 @@ Markus Zolliker, May 2005 #include "fsm.h" #include "initializer.h" +typedef enum {NOTHING, SWITCH_OFF, RAMP_DOWN, + RAMP_ALMOST, RAMP_ZERO, RAMPED_DOWN} DoThis; + typedef struct { EaseDriv d; - float current; /* current (in Tesla) */ - float persfield; /* persistent field from IPS (in Tesla) */ - float lastfield; /* persistent field from last drive */ - float confirmfield; /* field confirmed in 1st step */ - float ramp; /* actual ramp rate (Tesla/min) */ - float maxlimit; /* hard field limit */ - int persmode; /* 0: leave switch on, 1: go to persistant mode */ - int perswitch; /* state of switch */ - int remote; /* 0: local, 1: remote, do not check, 2: remote, check */ - int nowait; /* 0: normal, 1: drive finishes immediately, ramp in background */ + float current; /* current (in Tesla) */ + float persfield; /* persistent field from IPS (in Tesla) */ + float lastfield; /* persistent field from last drive */ + float confirmfield; /* field confirmed in 1st step */ + float ramp; /* actual ramp rate (Tesla/min) */ + float maxlimit; /* hard field limit */ + float perscurrent; /* current for persistent mode workaround (Tesla) */ + float perslimit; /* field limit for activating persistent mode workaround (Tesla) */ + float voltage; /* voltage */ + float measured; /* measured current */ + int persmode; /* 0: delayed persistant mode, 1: go to persistant mode, 2: leave switch on */ + int persdelay; /* wait time for delayed persistant mode */ + int perswitch; /* state of switch */ + int remote; /* 0: local, 1: remote, do not check, 2: remote, check */ + int nowait; /* 0: normal, 1: drive finishes immediately, ramp in background */ + int perswait; /* wait time for persistent mode workaround (sec) */ int heaterFault; - char *fmt; /* fmt for field */ - int force; /* force = 2: put heater switch even when stored field does not match */ - time_t swtim; /* time when last switching the heater */ - time_t tim; + DoThis dothis; + char *fmt; /* fmt for field */ + int force; /* force = 2: put heater switch even when stored field does not match */ + time_t swtim; /* time when last switching the heater */ + time_t tim; /* outside IpsChangeField: time of last Field Change */ } Ips; static ParClass ipsClass = { "IPS", sizeof(Ips) }; static char *onOff[] = { "off", "on", NULL }; +static char *persMode[] = { "auto", "on", "off", NULL }; /*----------------------------------------------------------------------------*/ static int IpsOk(Ips * drv) @@ -141,7 +152,7 @@ void IpsParDef(void *object) ParName("persmode"); ParAccess(usUser); - ParEnum(onOff); + ParEnum(persMode); ParList(0); ParInt(&drv->persmode, 1); @@ -182,11 +193,43 @@ void IpsParDef(void *object) ParTail("Tesla/min"); ParFloat(&drv->ramp, 1.0); + ParName("perscurrent"); + ParAccess(usUser); + ParFmt(drv->fmt); + ParTail("Tesla"); + ParFloat(&drv->perscurrent, 0.0); + + ParName("perslimit"); + ParAccess(usUser); + ParFmt(drv->fmt); + ParTail("Tesla"); + ParFloat(&drv->perslimit, 10.0); + + ParName("perswait"); + ParAccess(usUser); + ParTail("sec"); + ParInt(&drv->perswait, 1800); + + ParName("persdelay"); + ParAccess(usUser); + ParTail("sec"); + ParInt(&drv->persdelay, 1800); + ParName("current"); ParFmt(drv->fmt); ParTail("Tesla equivalent"); ParFloat(&drv->current, PAR_NAN); + ParName("measured"); + ParFmt(drv->fmt); + ParTail("Amps"); + ParFloat(&drv->measured, PAR_NAN); + + ParName("voltage"); + ParFmt(drv->fmt); + ParTail("Volt"); + ParFloat(&drv->voltage, PAR_NAN); + ParName("lastfield"); ParSave(1); ParFloat(&drv->lastfield, PAR_NAN); @@ -256,12 +299,15 @@ static void IpsStatus(Ips * drv) return; } if (ans[6] != '3') { - if (drv->remote == 2) { + if (drv->remote == 2) { /* remote state monitoring local switch */ ParPrintf(drv, eError, "IPS switched to local"); *code = EASE_FAULT; - drv->remote = 1; + drv->remote = 3; /* signal to switch back to C0 local locked */ return; } + if (ans[6] == '1') { + drv->remote = 3; /* signal to switch back to C0 local locked */ + } if (drv->d.hwstate == HWBusy && drv->d.b.doit == NULL) { drv->d.hwstate = HWIdle; drv->d.stopped = 0; @@ -280,6 +326,9 @@ static void IpsStatus(Ips * drv) if (swi != drv->perswitch || drv->swtim == 0) { drv->swtim = time(NULL); drv->perswitch = swi; + if (drv->perswitch && drv->dothis == RAMP_ALMOST) { + drv->dothis = NOTHING; + } } } @@ -302,6 +351,7 @@ static long IpsRead(long pc, void *object) { Ips *drv = ParCast(&ipsClass, object); EaseBase *eab = object; + time_t expire, now; switch (pc) { default: /* FSM BEGIN ****************************** */ @@ -310,20 +360,153 @@ static long IpsRead(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ IpsStatus(drv); - rd: + EaseWrite(eab, "R7"); /* read current (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ drv->current = OxiGet(eab, 3, NULL, drv->current); + + EaseWrite(eab, "R2"); /* read measured current (in amps) */ + return __LINE__; + case __LINE__: /**********************************/ + drv->measured = OxiGet(eab, 3, NULL, drv->measured); + + EaseWrite(eab, "R1"); /* read measured voltage */ + return __LINE__; + case __LINE__: /**********************************/ + drv->voltage = OxiGet(eab, 3, NULL, drv->voltage); + if (drv->perswitch) { IpsSetField(drv, drv->current); - goto quit; + goto checktodo; } EaseWrite(eab, "R18"); /* read persistant field (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield)); + checktodo: + 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) { + drv->dothis = SWITCH_OFF; + } else { + drv->dothis = NOTHING; + goto nothing; + } + } else if (drv->dothis == RAMP_ALMOST) { + if (now > drv->tim + drv->perswait) { + drv->dothis = RAMP_ZERO; + } else { + goto nothing; + } + } else if (drv->dothis == SWITCH_OFF) { + if (now > drv->swtim + 30) { + drv->dothis = RAMP_DOWN; + } else { + goto nothing; + } + } else { + goto nothing; + } + } + + EaseWrite(eab, "C3"); + drv->remote = 1; /* remote state */ + return __LINE__; + case __LINE__: /**********************************/ + + switch (drv->dothis) { + case SWITCH_OFF: goto switch_off; + case RAMP_DOWN: goto ramp_down; + case RAMP_ZERO: goto ramp_zero; + } + /* we should never get here */ + goto quit; + + switch_off: + EaseWrite(eab, "H0"); + drv->perswitch = 0; + drv->swtim = time(NULL); + drv->lastfield = drv->current; + EaseParHasChanged(); + return __LINE__; + case __LINE__: /**********************************/ + ParPrintf(drv, -1, "IPS: go to persistent mode, wait 30 sec for switch"); + goto localLocked; + + ramp_down: + if (drv->current == 0) + goto localLocked; + if (drv->perscurrent == 0 || drv->persfield < drv->perslimit) { + drv->dothis = RAMP_ZERO; + goto ramp_zero; + } + + OxiSet(eab, "J", drv->perscurrent, 3); /* put set point to a low value, above the CLACK value */ + return __LINE__; + case __LINE__: + EaseWrite(eab, "A1"); /* goto set (almost zero) */ + ParPrintf(drv, -1, "IPS: ramp current to %f (almost zero)", drv->perscurrent); + return __LINE__; + case __LINE__: /**********************************/ + drv->tim = time(NULL); + drv->dothis = RAMP_ALMOST; + goto localLocked; + + ramp_zero: + EaseWrite(eab, "A2"); /* goto zero */ + ParPrintf(drv, -1, "IPS: ramp current to 0"); + drv->dothis = RAMPED_DOWN; + return __LINE__; + case __LINE__: /**********************************/ + goto localLocked; + + nothing: + if (drv->remote != 3) /* NOT signal to switch back to local locked */ + goto quit; + + localLocked: + EaseWrite(eab, "C0"); + drv->remote = 0; /* local state */ + return __LINE__; + case __LINE__: /**********************************/ + + quit: + ParLog(drv); + return 0; + } /* FSM END ******************************************* */ + +} + +/*----------------------------------------------------------------------------*/ +static long IpsMeas(long pc, void *object) +{ + Ips *drv = ParCast(&ipsClass, object); + EaseBase *eab = object; + + switch (pc) { + default: /* FSM BEGIN ****************************** */ + EasePchk(drv); + EaseWrite(eab, "X"); + return __LINE__; + case __LINE__: /**********************************/ + IpsStatus(drv); + + EaseWrite(eab, "R2"); /* read measured current (in amps) */ + return __LINE__; + case __LINE__: /**********************************/ + drv->measured = OxiGet(eab, 3, NULL, drv->measured); + + EaseWrite(eab, "R1"); /* read measured voltage */ + return __LINE__; + case __LINE__: /**********************************/ + drv->voltage = OxiGet(eab, 3, NULL, drv->voltage); + quit: ParLog(drv); return 0; @@ -359,6 +542,7 @@ static long IpsStart(long pc, void *object) } else { drv->fmt = "%.3f"; } + drv->tim = time(NULL); FsmCall(IpsRead); return __LINE__; case __LINE__: /**********************************/ @@ -388,7 +572,7 @@ static long IpsChangeField(long pc, void *object) drv->d.eMode = EVMonitor; /* finish drive, continue in background */ } EaseWrite(eab, "C3"); - drv->remote = 1; + drv->remote = 1; /* remote state */ return __LINE__; case __LINE__: /**********************************/ EaseWrite(eab, "F7"); /* switch to tesla on display */ @@ -397,10 +581,21 @@ static long IpsChangeField(long pc, void *object) EaseWrite(eab, "A0"); /* hold */ return __LINE__; case __LINE__: /**********************************/ - FsmCall(IpsRead); + + EaseWrite(eab, "R7"); /* read current (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ - drv->remote = 2; + drv->current = OxiGet(eab, 3, NULL, drv->current); + + EaseWrite(eab, "R18"); /* read persistant field (in Tesla) */ + return __LINE__; + case __LINE__: /**********************************/ + IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield)); + + FsmCall(IpsMeas); + return __LINE__; + case __LINE__: /**********************************/ + drv->remote = 2; /* remote state monitoring local switch */ if (!IpsOk(drv)) goto finish; if (drv->lastfield == PAR_NAN) { @@ -409,7 +604,7 @@ static long IpsChangeField(long pc, void *object) if (fabs(drv->d.targetValue - drv->lastfield) < 1e-5) { ParPrintf(drv, -1, "IPS: we are already at field %f", drv->lastfield); - if (drv->persmode) { + if (drv->persmode == 1) { if (!drv->perswitch) goto finish; goto target_reached; @@ -432,15 +627,15 @@ static long IpsChangeField(long pc, void *object) drv->tim = time(NULL); stab1: - EaseWrite(eab, "X"); - return __LINE__; - case __LINE__: /**********************************/ - IpsStatus(drv); /* just check for errors */ EaseWrite(eab, "R7"); /* read current (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ drv->current = OxiGet(eab, 3, NULL, drv->current); - ParLog(drv); + + FsmCall(IpsMeas); + return __LINE__; + case __LINE__: /**********************************/ + if (fabs(drv->current - drv->lastfield) > 1e-5) goto stab1; @@ -448,10 +643,11 @@ static long IpsChangeField(long pc, void *object) FsmWait(1); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "X"); + + FsmCall(IpsMeas); return __LINE__; case __LINE__: /**********************************/ - IpsStatus(drv); + if (time(NULL) < drv->tim + 10) goto stab2; /* stabilize */ @@ -467,30 +663,33 @@ static long IpsChangeField(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ drv->perswitch = 1; + drv->dothis = NOTHING; drv->swtim = time(NULL); wait_open: - delay = drv->swtim + 30 - time(NULL); + delay = drv->swtim + 15 - time(NULL); if (delay > 0) ParPrintf(drv, -1, "IPS: wait %d sec to open switch", delay); - start_ramp: ParLog(drv); + start_ramp: FsmWait(1); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "X"); + + FsmCall(IpsMeas); return __LINE__; case __LINE__: /**********************************/ - IpsStatus(drv); /* check for errors */ + if (drv->heaterFault) { if (time(NULL) > drv->swtim + 3) { - ParPrintf(drv, eError, "IPS heater fault"); + ParPrintf(drv, eError, "IPS: switch heater not connected"); eab->errCode = EASE_FAULT; goto off_finish; } } - if (time(NULL) < drv->swtim + 30) + + if (time(NULL) < drv->swtim + 15) goto start_ramp; /* wait */ OxiSet(eab, "T", drv->ramp, 3); return __LINE__; @@ -512,15 +711,16 @@ static long IpsChangeField(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ IpsSetField(drv, OxiGet(eab, 3, NULL, drv->current)); /* set drv->current and callback */ - EaseWrite(eab, "X"); + + FsmCall(IpsMeas); return __LINE__; case __LINE__: /**********************************/ - IpsStatus(drv); /* just check for errors */ + EaseWrite(eab, "R9"); /* read back ramp rate (may be sweep limited) */ return __LINE__; case __LINE__: /**********************************/ ramp = OxiGet(eab, 3, NULL, drv->ramp); - step = ramp / 6; /* step = ramp * 10 sec */ + step = ramp / 3; /* step = ramp * 20 sec */ if (step < 0.001) step = 0.001; if (drv->d.targetValue > drv->current + step) { @@ -540,63 +740,27 @@ static long IpsChangeField(long pc, void *object) target_reached: drv->d.hwstate = HWIdle; drv->d.eMode = EVMonitor; /* we are at field, drive has finished */ - if (!drv->persmode) + if (drv->persmode != 1) goto hold_finish; /* but we continue in the background */ drv->tim = time(NULL); stab3: - ParLog(drv); FsmWait(1); return __LINE__; case __LINE__: /**********************************/ - EaseWrite(eab, "X"); + + FsmCall(IpsMeas); return __LINE__; case __LINE__: /**********************************/ - IpsStatus(drv); /* just check for errors */ + if (time(NULL) < drv->tim + 10) goto stab3; /* stabilize */ EaseWrite(eab, "A0"); /* hold */ return __LINE__; - case __LINE__: /**********************************/ - EaseWrite(eab, "H0"); - drv->perswitch = 0; - drv->swtim = time(NULL); - drv->lastfield = drv->current; - EaseParHasChanged(); - return __LINE__; - case __LINE__: /**********************************/ - ParPrintf(drv, -1, "IPS: wait 30 sec to close switch"); - - wait_closed: - ParLog(drv); - FsmWait(1); - return __LINE__; - case __LINE__: /**********************************/ - EaseWrite(eab, "R18"); /* read persistent field in Tesla */ - return __LINE__; - case __LINE__: /**********************************/ - fld = OxiGet(eab, 3, NULL, drv->current); - if (fld != drv->lastfield) { - IpsSetField(drv, fld); /* set drv->current and callback */ - drv->lastfield = fld; - EaseParHasChanged(); - } - EaseWrite(eab, "X"); - return __LINE__; - case __LINE__: /**********************************/ - IpsStatus(drv); - if (time(NULL) < drv->swtim + 30) - goto wait_closed; /* wait */ - - if (drv->current == 0) - goto finish; - EaseWrite(eab, "A2"); /* goto zero */ - ParPrintf(drv, -1, "IPS: ramp current to 0"); - return __LINE__; case __LINE__: /**********************************/ goto finish; - + hold_finish: EaseWrite(eab, "A0"); return __LINE__; @@ -614,8 +778,9 @@ static long IpsChangeField(long pc, void *object) finish: EaseWrite(eab, "C0"); - drv->remote = 0; + drv->remote = 0; /* local state */ drv->d.hwstate = HWIdle; + drv->tim = time(NULL); /* time of last field change */ return __LINE__; case __LINE__: /**********************************/ @@ -640,6 +805,7 @@ static int IpsInit(SConnection * con, int argc, char *argv[], int dynamic) return 0; drv->d.maxwait = 999999; drv->d.tolerance = 0.001; + drv->dothis = NOTHING; return 1; } diff --git a/lsc370driv.c b/lsc370driv.c index c6a5a01..eac66d4 100644 --- a/lsc370driv.c +++ b/lsc370driv.c @@ -262,7 +262,7 @@ static void Lsc370ParDef(void *object) ParName("maxPower"); ParTail("mW"); power = Lsc370Power(drv, 100.0); - ParFmt("%.0g"); + ParFmt("%.3g"); ParFloat(&power, 0.0); ParName("power"); diff --git a/make_gen b/make_gen index da9b1a8..996e6ce 100644 --- a/make_gen +++ b/make_gen @@ -29,7 +29,8 @@ OBJ=psi.o buffer.o ruli.o sps.o pimotor.o charbychar.o\ MZOBJ=fsm.o sugar.o pardef.o ease.o strobj.o oxinst.o \ ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \ - lscsupport.o lsc370driv.o linadriv.o haakedriv.o amilevel.o binprot.o + lscsupport.o lsc370driv.o linadriv.o haakedriv.o amilevel.o binprot.o \ + cnvrt.o libpsi.a: $(OBJ) rm -f libpsi.a diff --git a/modbus.c b/modbus.c index b2acb2b..249a068 100644 --- a/modbus.c +++ b/modbus.c @@ -18,67 +18,9 @@ is not changed, i.e. an existing errCode is not overwritten. #include #include "sics.h" #include "modbus.h" +#include "cnvrt.h" -/*-------------------------------------------------------------------------*/ -static void double2ieee(double input, char ieee[4]) -{ - -/* convert double to IEEE 32 bit floating number (denormalized numbers are considered as zero) */ - - long mantissa; - int exponent; - - if (input == 0) { - ieee[0] = 0; - ieee[1] = 0; - ieee[2] = 0; - ieee[3] = 0; - } else { - mantissa = 0x1000000 * (frexp(fabs(input), &exponent)); - exponent = exponent - 1 + 127; - if (exponent < 0) { - exponent = 0; - } else if (exponent > 0xFE) { - exponent = 0xFE; - } - if (input < 0) { - ieee[0] = 0x80 | (exponent >> 1); - } else { - ieee[0] = exponent >> 1; - } - ieee[1] = (exponent & 1) << 7 | ((mantissa & 0x7F0000) >> 16); - ieee[2] = (mantissa & 0xFF00) >> 8; - ieee[3] = mantissa & 0xFF; - } - return; -} - -/*-------------------------------------------------------------------------*/ -static double ieee2double(char ieee[4]) -{ - -/* IEEE 32 bit floating number to double (denormalized numbers are considered as zero) */ - - long mantissa; - double output; - int exponent; - - mantissa = ((ieee[1] << 16) & 0x7FFFFF) - | ((ieee[2] << 8) & 0xFF00) - | ((ieee[3]) & 0xFF); - - exponent = (ieee[0] & 0x7F) * 2 + ((ieee[1] >> 7) & 1); /* raw exponent */ - if (exponent == 0 && mantissa == 0) { - return 0.0; - } - output = ldexp(mantissa, -23) + 1.0; - if (ieee[0] & 0x80) { - output = -output; - } - return output * ldexp(1, exponent - 127); -} - /*----------------------------------------------------------------------------*/ static void uint2word(unsigned int adr, char word[2]) { diff --git a/pardef.c b/pardef.c index d7958e2..374e074 100644 --- a/pardef.c +++ b/pardef.c @@ -151,7 +151,7 @@ int ParPrintf(void *object, int iOut, const char *fmt, ...) return 0; /* no connection, no verbose output */ if (-iOut > pobj->verbose) return 0; /* check verbosity level */ - iOut = eValue; + iOut = eLog; } va_start(ap, fmt); diff --git a/psi.c b/psi.c index ddb7553..3ed746e 100644 --- a/psi.c +++ b/psi.c @@ -123,6 +123,7 @@ static void AddPsiCommands(SicsInterp * pInter) SCMD("MakeTRICSSupport", MakeTricsSupport); SCMD("PolterInstall", PolterInstall); SCMD("SerialInit", SerialInit); + PCMD("cnvrt", CnvrtAction); /* SCMD("MakeDifrac",MakeDifrac); */ diff --git a/tecs/make_crv b/tecs/make_crv index d764413..a444b97 100644 --- a/tecs/make_crv +++ b/tecs/make_crv @@ -77,6 +77,9 @@ $(CFGDIR)cma11r4rc.crv: ccrv inp/cma11r4rc.inp $(CFGDIR)cma6.crv: ccrv inp/cma6.inp $Q -p$(CFGDIR) +$(CFGDIR)cma7.crv: ccrv inp/cma7.inp + $Q -p$(CFGDIR) + $(CFGDIR)cplus45.crv: ccrv inp/cplus45.inp $Q -p$(CFGDIR) @@ -380,6 +383,15 @@ $(CFGDIR)x58599.crv: ccrv inp/x58599.inp $(CFGDIR)x58600.crv: ccrv inp/x58600.inp $Q -p$(CFGDIR) +$(CFGDIR)x68061.crv: ccrv inp/x68061.inp + $Q -p$(CFGDIR) + +$(CFGDIR)x68258.crv: ccrv inp/x68258.inp + $Q -p$(CFGDIR) + +$(CFGDIR)x68433.crv: ccrv inp/x68433.inp + $Q -p$(CFGDIR) + $(CFGDIR)z030114.crv: ccrv inp/z030114.inp $Q -p$(CFGDIR) @@ -410,6 +422,7 @@ all_crv: dev.list \ $(CFGDIR)cma11r3lc.crv \ $(CFGDIR)cma11r4rc.crv \ $(CFGDIR)cma6.crv \ + $(CFGDIR)cma7.crv \ $(CFGDIR)cplus45.crv \ $(CFGDIR)cplus70.crv \ $(CFGDIR)cs405.crv \ @@ -511,6 +524,9 @@ all_crv: dev.list \ $(CFGDIR)x55918.crv \ $(CFGDIR)x58599.crv \ $(CFGDIR)x58600.crv \ + $(CFGDIR)x68061.crv \ + $(CFGDIR)x68258.crv \ + $(CFGDIR)x68433.crv \ $(CFGDIR)z030114.crv \ ALLINP= \ @@ -540,6 +556,7 @@ inp/cma11r2ol.inp \ inp/cma11r3lc.inp \ inp/cma11r4rc.inp \ inp/cma6.inp \ +inp/cma7.inp \ inp/cplus45.inp \ inp/cplus70.inp \ inp/cs405.inp \ @@ -641,5 +658,8 @@ inp/x55606.inp \ inp/x55918.inp \ inp/x58599.inp \ inp/x58600.inp \ +inp/x68061.inp \ +inp/x68258.inp \ +inp/x68433.inp \ inp/z030114.inp \ diff --git a/tecs/tecs.c b/tecs/tecs.c index 357ee6e..0e22322 100644 --- a/tecs/tecs.c +++ b/tecs/tecs.c @@ -187,6 +187,7 @@ static int switch heater range on when controller switched it off */ initMaxPower=0, /* set MaxPower for the first time */ unit=1, /* 1: Kelvin, 2: Celsius */ + autoconfig=1, lockAlarm, cntError; @@ -216,6 +217,8 @@ static char devHelp[10000], update[32], /* update script option */ lscfg[256], /* lsc commands for configuration */ + devname0[64], /* name of plugs from codes */ + devname1[64], maxPower[128], controlChannel[4]="A"; @@ -501,7 +504,7 @@ int InstalCurve(SensorT *sensor, char *devArg) { str_upcase(head, chead); ERR_P(LscCmd(ser, "CRVHDR [num]:[head];INCRV [chan]:[num];MNMX [chan]:1,[unit]")); logfileOut(LOG_MAIN, "curve %d selected on channel %s\n", num, chan); - saveTime=tim+30; + saveTime = (tim/3600/24 + 1) * 3600*24; /* save at midnight GMT */ } FREE(crv); crv=NULL; @@ -1926,9 +1929,17 @@ int ConfigByCode(int plugNr) { plug->devcmd=0; ConcatDevice(); if (plug->code==0) { - logfileOut(LOG_MAIN ,"reset inputs on plug%d\n", plugNr); - plug->sensor1->present=0; - plug->sensor2->present=0; + if (autoconfig) { + logfileOut(LOG_MAIN ,"reset inputs on plug%d\n", plugNr); + plug->sensor1->present=0; + plug->sensor2->present=0; + } else { + if (plugNr == 0) { + str_copy(devname0, "none"); + } else { + str_copy(devname1, "none"); + } + } } else { str_copy(buf, binDir); str_append(buf, LSC_CODES); @@ -1947,11 +1958,20 @@ int ConfigByCode(int plugNr) { logfileOut(LOG_MAIN+LOG_STAT ,"unknown code %d on plug%d\n", plug->code, plugNr); return 0; } else { - logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for %s (code %d)\n", plugNr, nam, plug->code); - str_copy(buf, "'"); - str_append(buf, nam); - str_append(buf, "'"); - ERR_I(PrepInput(buf)); + if (autoconfig) { + logfileOut(LOG_MAIN+LOG_STAT ,"configure plug%d for %s (code %d)\n", plugNr, nam, plug->code); + str_copy(buf, "'"); + str_append(buf, nam); + str_append(buf, "'"); + ERR_I(PrepInput(buf)); + } else { + logfileOut(LOG_MAIN+LOG_STAT ,"%s on plug%d (code %d)\n", nam, plugNr, plug->code); + if (plugNr == 0) { + str_copy(devname0, nam); + } else { + str_copy(devname1, nam); + } + } } } settingsFlag=1; @@ -2296,6 +2316,7 @@ int PeriodicTask(void) { str_copy(plug0.device, buf1+1); plug0.codChanged=0; ConfigByName(0); + if (autoconfig == 0) ConfigByCode(0); } else { if (plug0.code!=0) str_copy(plug0.device, buf1); plug0.devcmd=0; @@ -2304,6 +2325,7 @@ int PeriodicTask(void) { str_copy(plug1.device, buf2+1); plug1.codChanged=0; ConfigByName(1); + if (autoconfig == 0) ConfigByCode(1); } else { if (plug1.code!=0) str_copy(plug1.device, buf2); plug1.devcmd=0; @@ -2554,29 +2576,32 @@ int PeriodicTask(void) { } } - if ((plug0.code1 & 0x2a) == 0x20) { - sensA0.t = DATA_UNDEF; - sensA1.t = DATA_UNDEF; - sensA2.t = DATA_UNDEF; - sensA3.t = DATA_UNDEF; - switch ((int)scanChan) { - case 0: sensA0.t = te; break; - case 1: sensA1.t = te; break; - case 2: sensA2.t = te; break; - case 3: sensA3.t = te; break; - default: break; - } - } +/* obsolete + * if ((plug0.code1 & 0x2a) == 0x20) { + * sensA0.t = DATA_UNDEF; + * sensA1.t = DATA_UNDEF; + * sensA2.t = DATA_UNDEF; + * sensA3.t = DATA_UNDEF; + * switch ((int)scanChan) { + * case 0: sensA0.t = te; break; + * case 1: sensA1.t = te; break; + * case 2: sensA2.t = te; break; + * case 3: sensA3.t = te; break; + * default: break; + * } + * } + */ if (out1==30 && out2==29) { /* code conversion */ plug0.code1=3*decod[cod2 % 8] ^ 2*decod[cod1 % 8]; /* ^ is exclusive OR */ - if ((plug0.code1 & 0x2a) == 0x20) { - /* for external switch (MA09) */ - scanChan = cod1 & 0x03; - plug0.code1 = plug0.code1 & 0x30; - } else { - scanChan = DATA_UNDEF; - } +/* obsolete, for external switch (MA09) + * if ((plug0.code1 & 0x2a) == 0x20) { + * scanChan = cod1 & 0x03; + * plug0.code1 = plug0.code1 & 0x30; + * } else { + * scanChan = DATA_UNDEF; + * } + */ plug1.code1=-(3*decod[cod2 / 8] ^ 2*decod[cod1 / 8]); for (i=0; i<2; i++) { plug=plugs[i]; @@ -2949,7 +2974,7 @@ int StillHdl(int mode, void *base, int fd) { return COC_DWR; } else if (mode==COC_DWR) { fbuf=still; - ERR_P(LscCmd(ser,"ANALOG 1:0,2,,,,,[fbuf]")); + ERR_P(LscCmd(ser,"ANALOG 1:1,2,,,,,[fbuf]")); } return 0; OnError: return -1; @@ -3500,6 +3525,7 @@ int main(int argc, char *argv[]) { CocDefInt(rdTim, RD); CocDefInt(tim0, RD); CocDefInt(ibuf, RD); + CocDefInt(autoconfig, RW); CocDefInt(logMask, RW); CocDefInt(logPeriod, RW); @@ -3520,6 +3546,8 @@ int main(int argc, char *argv[]) { CocDefStr(grapar, RA); CocDefArr(gradata, RD); CocHdl(GraHdl); grasize=CocSizePtr(); + CocDefStr(devname0, RW); + CocDefStr(devname1, RW); CocAlias(tempX,cryo.temp); CocAlias(tempP,samp.temp); CocAlias(Ta,sensA.t); @@ -3560,6 +3588,9 @@ int main(int argc, char *argv[]) { } else if ('s'==opt) { use_stdout=1; opt=' '; + } else if ('a'==opt) { + autoconfig=0; + opt=' '; } else if ('n'==opt) { i++; str_copy(serverId, argv[i]); diff --git a/tecs/tecs_lsc.c b/tecs/tecs_lsc.c index c01bd4a..3b678c3 100644 --- a/tecs/tecs_lsc.c +++ b/tecs/tecs_lsc.c @@ -49,7 +49,7 @@ char *LscCmd(SerChannel *ser, const char *cmds) { char cmd[SER_BUF_LEN]; char varname[32]; DeclStrBuf(sbuf, SER_BUF_LEN); - int nres, i, response; + int nres, i, response, try; nres=0; response=0; @@ -111,8 +111,18 @@ char *LscCmd(SerChannel *ser, const char *cmds) { } else { sbuf.buf[sbuf.wrpos-1]='\0'; /* strip off trailing ";" */ } - ERR_P(res=SerCmd(ser, sbuf.buf)); - if (0==strncmp("?TMO", res, 4)) ERR_MSG("timeout"); + + try = 3; + while (1) { + ERR_P(res=SerCmd(ser, sbuf.buf)); + if (0!=strncmp("?TMO", res, 4)) { + break; + } + try--; + if (try <= 0) { + ERR_MSG("timeout"); + } + } /* list[0..nres-1] contains a now: for a command with return request: diff --git a/tecs/tecs_serial.c b/tecs/tecs_serial.c index bb70891..3f94722 100644 --- a/tecs/tecs_serial.c +++ b/tecs/tecs_serial.c @@ -212,7 +212,11 @@ char *SerCmd(SerChannel *serch, char *cmnd) { /* Wait for an event on tser->fd or a timeout tmo */ iret=tser->idleHdl(tser->tmo, tser->fd); if (iret==0) { - if (result==NULL) ERR_MSG("timeout"); + if (result==NULL) { + result="?TMO"; + return result; + } + /* if (result==NULL) ERR_MSG("timeout"); */ ERR_MSG("missing terminator"); } ERR_SI(l=recv(tser->fd, pos, n, 0));