/*--------------------------------------------------------------------------- lcdriv.c Driver for the Oxford Instruments Teslatron lambda controller Markus Zolliker, Sept 2004 ----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "oicom.h" #include "fsm.h" typedef struct { Eve eve; float t[4]; /* set t. & 3 temperatures */ int dig[4]; /* format for these */ float gas; int remote; int hot; } LcDriv; static long LcSetGas(long pc, void *obj); /*----------------------------------------------------------------------------*/ #define A EVE_ACTPAR #define L EVE_LOGPAR #define S EVE_SAVEPAR void LcPars(LcDriv * me, EveParArg * arg) { char fmt[80]; sprintf(fmt, "%%.%df\tK", me->dig[2]); EveFloatPar(arg, "t2", &me->t[2], fmt, usInternal, (me->dig[2] >= 0) * A + L); sprintf(fmt, "%%.%df\tK", me->dig[3]); EveFloatPar(arg, "t3", &me->t[3], fmt, usInternal, (me->dig[3] >= 0) * A + L); EveFloatCmd(arg, "gas", &me->gas, "%.1f\t%%", LcSetGas, usUser, A + L); EveIntPar(arg, "dig1", &me->dig[1], usUser, S); EveIntPar(arg, "dig2", &me->dig[2], usUser, S); EveIntPar(arg, "dig3", &me->dig[3], usUser, S); sprintf(fmt, "%%.%df\tmbar", me->dig[1]); EveStdParEnd(arg, fmt, 0); } /*----------------------------------------------------------------------------*/ void LcStatus(LcDriv * me) { char *ans; int *code; Eve *eve = &me->eve; if (eve->state != readState) return; ans = eve->ans; code = &eve->errCode; if (ans[0] != 'X' || ans[2] != 'A' || ans[4] != 'C' || ans[6] != 'S') { EvePrintf(eve, eError, "illegal status response"); *code = EVE_FAULT; return; } if (ans[6] != '3' && me->remote == 2) { EvePrintf(eve, eError, "LC switched to local"); *code = EVE_FAULT; me->remote = 1; return; } } /*----------------------------------------------------------------------------*/ static int LcRead(long pc, LcDriv * me) { Eve *eve = &me->eve; char *p; int l; FSM_BEGIN EveWrite(eve, "X"); FSM_NEXT LcStatus(me); /* check for errors */ /* if (!me->remote) goto skiprmt; EveWrite(eve, "C0"); me->remote = 0; FSM_NEXT */ skiprmt: if (me->dig[1] < 0) goto skip1; EveWrite(eve, "R1"); /* read sensor 1 */ FSM_NEXT me->t[1] = OiGetFlt(eve, me->dig[1], NULL); me->eve.value = me->t[1]; skip1: if (me->dig[2] < 0) goto skip2; EveWrite(eve, "R2"); /* read sensor 2 */ FSM_NEXT me->t[2] = OiGetFlt(eve, me->dig[2], NULL); skip2: if (me->dig[3] < 0) goto skip3; EveWrite(eve, "R3"); /* read sensor 3 */ FSM_NEXT me->t[3] = OiGetFlt(eve, me->dig[3], NULL); skip3: FSM_END} /*----------------------------------------------------------------------------*/ static long LcSetGas(long pc, void *obj) { LcDriv *me = obj; Eve *eve = &me->eve; pEVControl evc = eve->evc; float fld; float step; float ramp; char buf[4]; SConnection *pCon; int a; FSM_BEGIN if (me->remote) goto skipremote; EveWrite(eve, "C1"); FSM_NEXT skipremote: OiSet(eve, "G", me->gas, 1); /* cold valve setting */ FSM_NEXT quit: FSM_END} /*----------------------------------------------------------------------------*/ static int LcStart(long pc, LcDriv * me) { Eve *eve = &me->eve; FSM_BEGIN EveWrite(eve, "V"); FSM_NEXT if (0 == strncmp(eve->version, "TESLATRON", 9)) { me->eve.syntax = 0; me->dig[1] = 1; me->dig[2] = 2; me->dig[3] = 1; } else { EvePrintf(eve, eError, "unknown lambda controller version: %s", eve->version); goto quit; } EvePrintf(eve, eLog, "connected to %s", eve->version); FSM_CALL(LcRead); quit: FSM_END} /*----------------------------------------------------------------------------*/ static int LcSetTemp(long pc, LcDriv * me) { Eve *eve = &me->eve; pEVControl evc = eve->evc; float fld; float step; float ramp; char buf[4]; SConnection *pCon; FSM_BEGIN FSM_END} /*------------------------------------------------------------------------*/ pEVControl LcMakeEVC(SConnection * pCon, int argc, char *argv[]) { /* args: lc */ Eve *eve; pEVControl evc; LcDriv *me = NULL; evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon); if (!evc) return NULL; me = evc->pDriv->pPrivate; eve = &me->eve; eve->run = (FsmFunc) LcSetTemp; eve->read = (FsmFunc) LcRead; eve->pardef = (EveParDef) LcPars; eve->todo = (FsmFunc) LcStart; eve->task = FsmStartTask(me, (FsmHandler) OiHandler, (FsmFunc) EveIdle); return evc; }