/*--------------------------------------------------------------------------- ilmdriv.c Driver for the Oxford Instruments ILM503/ILM4 temperature controller and for the Oxford 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 #include "oicom.h" #include "fsm.h" typedef struct { Eve eve; float lev2, lev3; int cod1, cod2, cod3; } IlmDriv; char *fmts[10]={"unused", "%.1f\t%% N2", "%.1f\t%% He","%.1f\t%% He","", "","","","","error"}; /*----------------------------------------------------------------------------*/ #define A EVE_ACTPAR #define L EVE_LOGPAR #define S EVE_EVE_SAVEPAR void IlmPars(IlmDriv *me, EveParArg *arg) { EveFloatPar(arg, "chan2", &me->lev2, fmts[me->cod2], usInternal, (me->cod2 > 0) * A + L); EveFloatPar(arg, "chan3", &me->lev2, fmts[me->cod3], usInternal, (me->cod3 > 0) * A + L); EveStdParEnd(arg, fmts[me->cod1], A+L); } /*----------------------------------------------------------------------------*/ void IlmStatus(IlmDriv *me) { char *ans; int *code; Eve *eve=&me->eve; int i; if (eve->state != readState) return; ans=eve->ans; code=&eve->errCode; if (ans[0] != 'X' || ans[4] != 'S' || ans[11] != 'R') { EvePrintf(eve, eError, "illegal status response"); *code = EVE_FAULT; return; } for (i=1; i<3; i++) { if (ans[i]<'0' || ans[i] > '9') ans[i]='9'; } me->cod1 = ans[1]-'0'; me->cod2 = ans[2]-'0'; me->cod3 = ans[3]-'0'; return; } /*----------------------------------------------------------------------------*/ static int IlmRead(long pc, IlmDriv *me) { Eve *eve=&me->eve; FSM_BEGIN EveWrite(eve, "X"); FSM_NEXT IlmStatus(me); /* check for errors */ EveWrite(eve, "R1"); /* read sensor 1 */ FSM_NEXT me->eve.value = OiGetFlt(eve, 1, NULL); if (me->cod2 == 0) goto skip2; EveWrite(eve, "R2"); /* read sensor 1 */ FSM_NEXT me->lev2 = OiGetFlt(eve, 1, NULL); skip2: if (me->cod3 == 0) goto skip3; EveWrite(eve, "R3"); /* read sensor 1 */ FSM_NEXT me->lev3 = OiGetFlt(eve, 1, NULL); skip3: FSM_END } /*----------------------------------------------------------------------------*/ static int IlmStart(long pc, IlmDriv *me) { Eve *eve=&me->eve; FSM_BEGIN EveWrite(eve, "V"); FSM_NEXT if (0 == strncmp(eve->version, "ILM", 3)) { me->eve.syntax = 0; } else { EvePrintf(eve, eError, "unknown level meter version: %s", eve->version); goto quit; } EvePrintf(eve, eStatus, "connected to %s", eve->version); FSM_CALL(IlmRead); quit: FSM_END } /*------------------------------------------------------------------------*/ pEVControl IlmMakeEVC(SConnection *pCon, int argc, char *argv[]) { /* args: temperature ilm */ Eve *eve; pEVControl evc; IlmDriv *me = NULL; evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon); if (!evc) return NULL; me = evc->pDriv->pPrivate; eve=&me->eve; eve->run = NULL; /* no run possible */ eve->read = (FsmFunc)IlmRead; eve->pardef = (EveParDef)IlmPars; eve->todo = (FsmFunc)IlmStart; eve->task = FsmStartTask(me, (FsmHandler)OiHandler, (FsmFunc)EveIdle); evc->pEnvir->IsInTolerance = EveAlwaysOk; return evc; }