From 731108ea98fc70629b79cdc7de686c386d8d75a4 Mon Sep 17 00:00:00 2001 From: cvs Date: Tue, 6 Jul 2004 13:11:33 +0000 Subject: [PATCH] Added IPS Driver M.Z. --- ipsdriv.c | 844 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ipsdriv.h | 25 ++ make_gen | 2 +- psi.c | 26 +- 4 files changed, 890 insertions(+), 7 deletions(-) create mode 100644 ipsdriv.c create mode 100644 ipsdriv.h diff --git a/ipsdriv.c b/ipsdriv.c new file mode 100644 index 0000000..4a0367a --- /dev/null +++ b/ipsdriv.c @@ -0,0 +1,844 @@ +/*--------------------------------------------------------------------------- + I P S D R I V . C + +Driver for the Oxford Instruments IPS/PS magnet power supply. + +Markus Zolliker, June 2004 + +----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + IPS_INIT, + IPS_IDLE, + IPS_START, + IPS_WAIT, + IPS_UP, + IPS_STAB1, + IPS_START_RAMP, + IPS_RAMP, + IPS_STAB2, + IPS_DOWN +} rampState; + +typedef struct { + rs232 *ser; /* serial connection */ + int errCode; + int isPS; /* is an old PS-120 instead of an IPS-120 */ + rampState state; + float target; /* target field */ + float field; /* actual field */ + float ramp; /* actual ramp rate */ + int persmode; /* 0: leave switch on, 1: go to persistant mode */ + int perswitch; /* state of switch */ + int force; /* flag: put heater switch even when stored field not matched */ + float forcedfield; /* field user thinks is in magnet */ + int verbose; /* verbosity 0..2 */ + int settle; /* settling time/4 */ + int stabilize; /* do we need to stabilize ? */ + time_t tim; /* time when last switching the heater */ + float voltage[4]; /* voltage history */ + char xstat[32]; /* status response */ + char msg[2048]; /* a message to return */ +} IpsDriv; + +#define OX_ILL_ANS -3000 +#define OX_ILL_FLD -3001 + +/*----------------------------------------------------------------------------*/ +void IpsSay(IpsDriv *me, int verbosity, char *fmt, ...) { + va_list ap; + int iRet, l; + + if (verbosity <= me->verbose) { + l=strlen(me->msg); + if (l > 0 && l < sizeof(me->msg)-1) { + strcat(me->msg, "\n"); + l++; + } + va_start(ap, fmt); + vsnprintf(me->msg+l, sizeof(me->msg)-l, fmt, ap); + va_end(ap); + } +} +/*----------------------------------------------------------------------------*/ +static void IpsWriteError(IpsDriv *me) { + switch (me->errCode) { + case NOTCONNECTED: + IpsSay(me, 0, "terminalserver for IPS not connected"); + break; + case FAILEDCONNECT: + IpsSay(me, 0, "can not connect to IPS"); + break; + case TIMEOUT: + IpsSay(me, 0, "IPS not properly connected"); + break; + case INCOMPLETE: + IpsSay(me, 0, "incomplete answer from IPS"); + break; + case OX_ILL_ANS: + IpsSay(me, 0, "illegal answer from IPS"); + break; + default: + IpsSay(me, 0, "error code %d", me->errCode); + break; + } +} +/*----------------------------------------------------------------------------*/ +static char *IpsCmd(IpsDriv *me, char *cmd, int *ret) { + int iret; + static char buf[32]; + *ret=transactRS232(me->ser, cmd, strlen(cmd), buf, sizeof(buf)); + IpsSay(me, 2, "command: %s, answer: %s", cmd, buf); + if (*ret != 1) { + if (*ret == 0) { + *ret == 1; + IpsSay(me, 0, "IPS: unknown RS232 error"); + } else { + IpsWriteError(me); + } + return NULL; + } + if (buf[0] != cmd[0]) { + IpsSay(me, 0, "command: %s, answer: %s", cmd, buf); + *ret=OX_ILL_ANS; + IpsWriteError(me); + } else { + *ret=0; + } + return buf; +} +/*----------------------------------------------------------------------------*/ +static float IpsRead(IpsDriv *me, char *cmd, int fmt, int *ret) { + char *buf; + float val; + + buf=IpsCmd(me, cmd, ret); + if (*ret) return 0.0; + if (me->isPS) { /* no decimal point expected */ + val=atoi(buf+1); + for (; fmt>0; fmt--) val=val*0.1; + } else { + val=atof(buf+1); + } + return val; +} +/*----------------------------------------------------------------------------*/ +static char *IpsStatus(IpsDriv *me, int *ret) { + char *ans; + ans=IpsCmd(me, "X", ret); + if (*ret) return me->xstat; + strncpy(me->xstat, ans, sizeof(me->xstat)); + me->xstat[sizeof(me->xstat)-1]='\0'; + return me->xstat; +} +/*----------------------------------------------------------------------------*/ +static int IpsCheckField(IpsDriv *me, char *name, int *ret) { + float fld; + if (strstr(me->xstat, "H1")==NULL) { + me->perswitch=0; + fld=IpsRead(me, "R18", 3, ret); /* read persistant field */ + if (fabs(fld - me->field) >= 1e-5) { + IpsSay(me, 0, "\nit is not sure which field is in the magnet\n" + "value stored in power supply: %f\n" + " in sics: %f\n" + "use command\n \n %s confirm ...\n \n" + "to specify the persistent field\n \n" + , fld, me->field, name); + return -1; + } + return 0; + } + me->perswitch=1; + fld=IpsRead(me, "R7", 3, ret); /* read actual field */ + me->field=fld; + return 1; +} +/*----------------------------------------------------------------------------*/ +static void IpsSet(IpsDriv *me, char *cmd, float val, int fmt, int *ret) { + char buf[64]; + + if (me->isPS) { + for (;fmt>0;fmt--) val=val*10; + snprintf(buf, sizeof(buf), "%s%05d", cmd, val); + } else { + snprintf(buf, sizeof(buf), "%s%f", cmd, val); + } + IpsCmd(me, buf, ret); +} +/*----------------------------------------------------------------------------*/ +static int IpsIsStable(IpsDriv *me) { +/* returns 1 when 4 subsequent readings within 0.01 Volts. + the timeinterval for the readings is specified with me->settle */ + + time_t now; + float v, vmin, vmax; + int i; + int *ret; + + assert(me); + ret=&me->errCode; + time(&now); + now = now / me->settle; + v = IpsRead(me, "R1", 2, ret); /* voltage */ + if (*ret) return 0; + i = now % 4; + me->voltage[i] = v; + vmin=me->voltage[0]; + vmax=vmin; + for (i=1; i<4; i++) { + if (me->voltage[i] < vmin) vmin = me->voltage[i]; + if (me->voltage[i] > vmax) vmax = me->voltage[i]; + } + return (fabs(vmax-vmin) < 0.015); +} +/*----------------------------------------------------------------------------*/ +static int IpsWait(IpsDriv *me) { + time_t now; + time(&now); + if (now < me->tim + 30) { /* we have to wait for stabilizing the switch heater */ + IpsSay(me, 2, "waiting %d sec", me->tim + 30 - now); + if (strstr(me->xstat, "H5")!=NULL && now > me->tim+5) { + IpsSay(me, 0, "IPS: switch heater is not connected"); + me->state=IPS_IDLE; + return HWFault; + } + if (now < me->tim+30) return HWBusy; + } + return 0; +} +/*----------------------------------------------------------------------------*/ +static int IpsStepper(void *evcV, SConnection *pCon) { + pEVControl evc; + pEVDriver self; + IpsDriv *me; + int *ret; + float fld; + float step; + float ramp; + int i; + int swi; + int hwstate; + char *ans; + time_t now; + + evc=evcV; + assert(evc); + self=evc->pDriv; + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + me->msg[0]='\0'; + me->errCode=0; + ret=&me->errCode; + + /* check status */ + if (me->state == IPS_IDLE) { + hwstate = HWIdle; + } else { + hwstate = HWBusy; + ans = IpsStatus(me, ret); + if (*ret) goto error; + if (strstr(ans, "X00") != ans + || strchr(ans, 'A') == NULL + || strchr(ans, 'C') == NULL + || strchr(ans, 'H') == NULL + || strchr(ans, 'M') == NULL + || strchr(ans, 'P') == NULL) { + IpsSay(me, 0, "IPS illegal status: %s", ans); + goto error; + } + if (strstr(ans, "C3") == NULL && me->state > IPS_START) { + IpsSay(me, 0, "IPS switched to local - stopped"); + IpsCmd(me, "C0", ret); + goto error; + } + if (evc->iStop) { + IpsSay(me, 0, "IPS stopped"); + IpsCmd(me, "C0", ret); + me->state = IPS_IDLE; + hwstate = HWIdle; + } + } + + switch (me->state) { + case IPS_START: + swi=IpsCheckField(me, evc->pName, ret); + if (*ret) goto error; + if (swi < 0) { + *ret=1; + goto error; + } + if (fabs(evc->fTarget - me->field) < 1e-5 && me->perswitch != me->persmode) { + IpsSay(me, 1, "IPS: we are already at field %f", me->field); + me->state = IPS_IDLE; + hwstate = HWIdle; + break; + } + IpsCmd(me, "C3", ret); + if (*ret) goto error; + IpsCmd(me, "F7", ret); /* show current in Tesla */ + if (*ret) goto error; + IpsCmd(me, "A0", ret); /* hold */ + if (*ret) goto error; + if (swi < 0) { + *ret=OX_ILL_FLD; + goto error; + } + me->stabilize=0; + if (!me->perswitch) { + fld=IpsRead(me, "R7", 3, ret); /* read actual current (in Tesla) */ + if (*ret) goto error; + if (fabs(fld - me->field) >= 1e-5) { + me->stabilize=1; + time(&now); + if (now < me->tim+30) { + IpsSay(me, 1, "IPS: wait until heat switch is open"); + } + } + } + me->state=IPS_WAIT; + /* fall through */ + + case IPS_WAIT: + if (me->stabilize) { + i=IpsWait(me); + if (i) { hwstate=i; break; } + IpsSet(me, "J", me->field, 3, ret); /* set point */ + if (*ret) goto error; + IpsSay(me, 1, "IPS: ramp to current for %f Tesla", me->field); + IpsCmd(me, "A1", ret); /* go to setpoint */ + if (*ret) goto error; + for (i=0; i<4; i++) { /* initialize voltage history */ + me->voltage[i] = 10*i; /* just some dirty values */ + } + } + me->state = IPS_UP; + /* fall through */ + + case IPS_UP: + fld=IpsRead(me, "R7", 3, ret); /* read actual field */ + if (fabs(fld - me->field) > 1e-5) break; + me->state = IPS_STAB1; + if (me->stabilize) { + IpsSay(me, 1, "IPS: stabilize"); + } + + case IPS_STAB1: + if (me->stabilize && ! IpsIsStable(me)) break; + + me->state=IPS_START_RAMP; + if (strstr(me->xstat, "H1")==NULL) { + if (me->force==2) { + IpsCmd(me, "H2", ret); + } else { + IpsCmd(me, "H1", ret); + } + if (*ret) goto error; + me->perswitch = 1; + me->force = 0; + time(&me->tim); + IpsSay(me, 1, "IPS: wait until heat switch is open"); + break; + } + me->perswitch = 1; + me->force=0; + /* fall through */ + + case IPS_START_RAMP: + i=IpsWait(me); + if (i) { hwstate=i; break; } + IpsSet(me, "T", me->ramp, 3, ret); + if (*ret) goto error; + IpsSay(me, 1, "IPS: ramp to %f Tesla", evc->fTarget); + + IpsCmd(me, "A1", ret); + if (*ret) goto error; + me->state=IPS_RAMP; + /* fall through */ + + case IPS_RAMP: + ramp=IpsRead(me, "R9", 3, ret); /* read ramp rate */ + if (*ret) goto error; + me->field=IpsRead(me, "R7", 3, ret); /* read "current" in Tesla */ + if (*ret) goto error; + step=ramp/20; /* step = ramp * 3sec */ + if (step < 0.001) step=0.001; + if (evc->fTarget > me->field + step) { + fld=me->field + step; + } else if (evc->fTarget < me->field - step) { + fld=me->field - step; + } else { + fld=evc->fTarget; + if (fabs(me->field - evc->fTarget) < 1e-5) { + IpsCmd(me, "A0", ret); + if (!me->persmode) { + IpsCmd(me, "C0", ret); + if (*ret) goto error; + me->state = IPS_IDLE; + hwstate = HWIdle; + break; + } + for (i=0; i<4; i++) { /* initialize voltage history */ + me->voltage[i]=10*i; /* just some dirty values */ + } + me->state = IPS_STAB2; + IpsSay(me, 1, "IPS: stabilize"); + } + } + IpsSet(me, "J", fld, 3, ret); + if (*ret) goto error; + break; + + case IPS_STAB2: + evc->eMode = EVMonitor; + if (!me->persmode || IpsIsStable(me)) { + IpsSay(me, 1, "IPS: wait until heat switch is closed"); + IpsCmd(me, "H0", ret); + if (*ret) goto error; + me->perswitch = 0; + time(&me->tim); + me->state = IPS_DOWN; + } + hwstate = HWIdle; + break; + + case IPS_DOWN: + hwstate = HWIdle; + i=IpsWait(me); + if (i) { + if (i == HWFault) { + hwstate = HWFault; + } + } else { + IpsSay(me, 1, "IPS: ramp current down"); + IpsCmd(me, "A2", ret); + if (*ret) goto error; + IpsCmd(me, "C0", ret); + if (*ret) goto error; + me->state = IPS_IDLE; + } + break; + } +error: + if (*ret) { + me->state = IPS_IDLE; + hwstate=HWFault; + } + if (me->msg[0] != '\0') { + if (pCon != NULL) { + SCWrite(pCon, me->msg, eWarning); + } else { + ServerWriteGlobal(me->msg, eWarning); + } + me->msg[0]='\0'; + } + return hwstate; +} +/*-------------------------------------------------------------------------*/ +int IpsWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]) { + pEVControl self = NULL; + char cmd[256], result[256], *res; + int iRet, *ret; + pEVDriver pD; + IpsDriv *me; + float fVal, fVal2, pf; + + self = (pEVControl)pData; + assert(self); + assert(pCon); + assert(pSics); + + if (argc < 2) { + return EVControlWrapper(pCon,pSics,pData,argc,argv); + } + pD=self->pDriv; assert(pD); + me=pD->pPrivate; assert(me); + me->msg[0]='\0'; + ret=&me->errCode; + + if (strlen(argv[1]) >= sizeof(cmd)) { + return EVControlWrapper(pCon,pSics,pData,argc,argv); + } + strcpy(cmd, argv[1]); + strtolower(cmd); + if (0==strcmp(cmd, "ramp")) { + if (argc > 2) { + me->ramp=atof(argv[2]); + } + sprintf(result, "%f", me->ramp); + } else if (0==strcmp(cmd, "limit")) { + if (argc == 2) { + fVal=ObVal(self->pParam, UPLIMIT); + fVal2=ObVal(self->pParam, LOWLIMIT); + if (-fVal2 > fVal) fVal=fVal2; + } else { + fVal=atof(argv[2]); + iRet = EVCSetPar(self, "upperlimit", fabs(fVal),pCon); + if (!iRet) { *ret=1; goto error; } + iRet = EVCSetPar(self, "lowerlimit", fVal,pCon); + if (!iRet) { *ret=1; goto error; } + } + sprintf(result, "%f", fVal); + } else if (0==strcmp(cmd, "persmode")) { + if (argc > 2) { + me->persmode = atoi(argv[2]); + } + sprintf(result, "%d", me->persmode); + } else if (0==strcmp(cmd, "verbose")) { + if (argc > 2) { + me->verbose = atoi(argv[2]); + } + sprintf(result, "%d", me->verbose); + } else if (0==strcmp(cmd, "list")) { + IpsStatus(me, ret); + if (*ret) goto error; + IpsCheckField(me, self->pName, ret); + if (*ret) goto error; + IpsSay(me, 0, "%s.%s = %.0f", self->pName, "access", ObVal(self->pParam, ACCESS)); + IpsSay(me, 0, "%s.%s = %.0f", self->pName, "ErrorHandler", ObVal(self->pParam, ERRORHANDLER)); + IpsSay(me, 0, "%s.%s = %.0f", self->pName, "interrupt", ObVal(self->pParam, INTERRUPT)); + IpsSay(me, 0, "%s.%s = %d", self->pName, "persmode", me->persmode); + IpsSay(me, 0, "%s.%s = %d", self->pName, "perswitch", me->perswitch); + IpsSay(me, 0, "%s.%s = %d", self->pName, "verbose", me->verbose); + fVal=ObVal(self->pParam, UPLIMIT); + fVal2=ObVal(self->pParam, LOWLIMIT); + if (-fVal2 > fVal) fVal=fVal2; + IpsSay(me, 0, "%s.%s = %f", self->pName, "limit", fVal); + IpsSay(me, 0, "%s.%s = %f", self->pName, "ramp", me->ramp); + IpsSay(me, 0, "%s.%s = %f", self->pName, "CurrentValue", me->field); + IpsSay(me, 0, "%s.%s = %f", self->pName, "TargetValue", self->fTarget); + IpsSay(me, 0, "%s.driver = %s", self->pName, self->driverName); + if (self->errorScript != NULL) { + IpsSay(me, 0, "%s.errorScript = %s", self->pName, self->errorScript); + } else { + IpsSay(me, 0, "%s.errorScript = UNDEFINED", self->pName); + } + result[0]='\0'; + } else if (0==strcmp(cmd, "confirm")) { + if (argc > 2) { + if (argc > 3) { + IpsSay(me, 0, "Too many arguments"); + goto error; + } + fVal=atof(argv[2]); + if (fVal < ObVal(self->pParam, LOWLIMIT) || + fVal > ObVal(self->pParam, UPLIMIT)) { + IpsSay(me, 0, "Field outside limit"); + goto error; + } + res=IpsStatus(me, ret); + if (*ret) goto error; + if (NULL!=strstr(res, "H1")) { + pf=IpsRead(me, "R7", 3, ret); /* read actual field */ + if (*ret) goto error; + IpsSay(me, 0, "switch heater is on - field is %f", pf); + goto error; + } + pf=IpsRead(me, "R18", 3, ret); /* read persistant field */ + if (*ret) goto error; + if (fabs(fVal - me->forcedfield) > 1e-5) { + me->force=0; + } + if (me->force==0) { + if (fabs(fVal - pf) > 1e-5 && fabs(fVal - me->field) > 1e-5) { + IpsSay(me, 0, "Be aware that this does neither match the stored" + " field in sics\nnor the field stored in power supply."); + } + IpsSay(me, 0, "Please repeat this command, to confirm again" + " the persistent field of\n %f Tesla.", fVal); + me->force=1; + result[0]='\0'; + } else if (me->force=1) { + me->force=2; + me->field=fVal; + sprintf(result, "%f", me->field); + } + me->forcedfield = fVal; + } else { + IpsStatus(me, ret); + if (*ret) goto error; + IpsCheckField(me, self->pName, ret); + if (*ret) goto error; + sprintf(result, "%f", me->field); + } + } else { + return EVControlWrapper(pCon,pSics,pData,argc,argv); + } + if (result[0] != '\0') { + IpsSay(me, 0, "%s.%s = %s", self->pName, argv[1], result); + } +error: + if (me->msg[0] != '\0') { + SCWrite(pCon, me->msg, eWarning); + me->msg[0]='\0'; + } + if (*ret) { + return 0; + } else { + return 1; + } +} +/*----------------------------------------------------------------------------*/ +static int IpsGet(pEVDriver self, float *fPos) { + IpsDriv *me = NULL; + int *ret; + time_t now; + float fld; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + ret=&me->errCode; + IpsStatus(me, ret); + if (!*ret) { + IpsCheckField(me, "magfield", ret); + } + *fPos=me->field; + if(*ret < 0) { + return 0; + } + return 1; +} +/*----------------------------------------------------------------------------*/ +static int IpsRun(pEVDriver self, float fVal) { + IpsDriv *me; + int *ret; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + ret=&me->errCode; + IpsStatus(me, ret); + if (*ret) return 0; + me->state=IPS_START; + return 1; +} +/*--------------------------------------------------------------------------*/ +int IpsError(pEVDriver self, int *iCode, char *error, int iErrLen) { + IpsDriv *me = NULL; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + *iCode = 1; /* severe */ + if (me->msg[0]=='\0') { + strncpy(error, "undefined error", iErrLen); + } else { + strncpy(error, me->msg, iErrLen); + } + error[iErrLen-1]='\0'; + return 1; +} +/*---------------------------------------------------------------------------*/ +static int IpsFix(pEVDriver self, int iError) { + IpsDriv *me = NULL; + int iRet; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + return(DEVFAULT); /* severe */ + + /* never used: return(DEVREDO); */ +} +/*--------------------------------------------------------------------------*/ +static int IpsSend(pEVDriver self, char *pCommand, char *pReply, int iLen) { + IpsDriv *me = NULL; + int iRet; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + iRet = transactRS232(me->ser, pCommand, strlen(pCommand), pReply, iLen); + if(iRet < 0) + { + me->errCode = iRet; + IpsWriteError(me); + return 0; + } + return 1; +} +/*--------------------------------------------------------------------------*/ +static int IpsInit(pEVDriver self) { + IpsDriv *me = NULL; + int iRet; + char *res, buf[128]; + pExeList exe; + SConnection *con; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + iRet = initRS232(me->ser); + if (iRet != 1) { + me->errCode = iRet; + IpsWriteError(me); + return 0; + } + setRS232ReplyTerminator(me->ser,"\r"); + setRS232SendTerminator(me->ser,"\r"); + setRS232Timeout(me->ser,1000); /* microseconds ? milliseconds ? */ + setRS232Debug(me->ser,0); + + iRet=transactRS232(me->ser, "V", 1, buf, sizeof(buf)); + if (iRet != 1) { + if (iRet == 0) { + me->errCode = 1; + IpsSay(me, 0, "IPS: unknown RS232 error"); + } else { + me->errCode = iRet; + IpsWriteError(me); + } + return 0; + } + + if (0==strncmp(buf, "IPS120", 6)) { + me->isPS=0; + } else if (0==strncmp(buf, "PS120", 5)) { + me->isPS=1; + } else { + IpsSay(me, 0, "unknown power supply version: %s", buf); + return 0; + } + + IpsStatus(me, &iRet); + me->msg[0]='\0'; + IpsCheckField(me, "magfield", &iRet); + me->state = IPS_IDLE; + return 1; +} +/*--------------------------------------------------------------------------*/ +static int IpsClose(pEVDriver self) { +/* + seems not to be needed + + IpsDriv *me = NULL; + int iRet; + + assert(self); + me = (IpsDriv *)self->pPrivate; + assert(me); + + me->pData=NULL; +*/ + return 1; +} +/*--------------------------------------------------------------------------*/ +static int IpsHalt(pEVDriver *self) { + assert(self); + /* to be implemented */ + return 1; +} +/*------------------------------------------------------------------------*/ +void IpsKill(void *pData) { + IpsDriv *me = NULL; + + me = (IpsDriv *)pData; + assert(me); + KillRS232(me->ser); + free(me); +} +/*------------------------------------------------------------------------*/ +pEVDriver CreateIpsDriver(int argc, char *argv[]) { + pEVDriver new = NULL; + IpsDriv *me = NULL; + int port; + + if (argc < 2) { + return NULL; + } + new = CreateEVDriver(argc,argv); + me = (IpsDriv *)malloc(sizeof(IpsDriv)); + memset(me,0,sizeof(IpsDriv)); + if(!new || !me) return NULL; + + new->pPrivate = me; + new->KillPrivate = IpsKill; + + /* initalise IpsDriver */ + /* me->lastError = NULL; */ + me->verbose = 0; + me->field = 0; + me->persmode = 1; + me->perswitch = 0; + me->force = 0; + me->tim = 0; + me->settle = 1; + me->state=IPS_INIT; + me->ramp=0.1; + me->isPS=0; + + port=atoi(argv[1]); + if (port==0) return NULL; + + me->ser=createRS232(argv[0], port); + if (me->ser == NULL) return NULL; + + /* initialise function pointers */ + new->SetValue = IpsRun; + new->GetValue = IpsGet; + new->Send = IpsSend; + new->GetError = IpsError; + new->TryFixIt = IpsFix; + new->Init = IpsInit; + new->Close = IpsClose; + + return new; +} +/*------------------------------------------------------------------------*/ +static int IpsWatcher(void *data) { + pEVControl self; + pExeList exe; + SConnection *con; + int iRet; + + assert(data); + self= (pEVControl)data; + exe = GetExecutor(); + con = GetExeOwner(exe); + iRet = IpsStepper(self, con); + return 1; +} +/*------------------------------------------------------------------------*/ +void IpsCustomize(SConnection *pCon, pEVControl pEvc) { +/* customize tecs driver */ + IpsDriv *me; + + me=pEvc->pDriv->pPrivate; + assert(me); + pEvc->pDrivInt->CheckStatus=IpsStepper; + pEvc->pEnvir->IsInTolerance=IpsWatcher; + EVCSetPar(pEvc,"upperlimit",14.9,pCon); + EVCSetPar(pEvc,"lowerlimit",-14.9,pCon); + if (me->msg[0]!='\0') { /* write message from IpsInit */ + SCWrite(pCon, me->msg, eWarning); + } +} diff --git a/ipsdriv.h b/ipsdriv.h new file mode 100644 index 0000000..c777df1 --- /dev/null +++ b/ipsdriv.h @@ -0,0 +1,25 @@ +/*------------------------------------------------------------------------- + I P S D R I V . H + +Driver for the Oxford Instruments IPS/PS magnet power supply. + + Markus Zolliker, June 2004 + + copyright: see implementation file. + +-----------------------------------------------------------------------------*/ +#ifndef SICSIPS +#define SICSIPS +/*------------------------- The Driver ------------------------------------*/ + + pEVDriver CreateIpsDriver(int argc, char *argv[]); + + +/*------------------------- The Tecs object ------------------------------*/ + + int IpsWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + + void IpsCustomize(SConnection *pCon, pEVControl pEvc); + +#endif diff --git a/make_gen b/make_gen index d8673ee..2cee481 100644 --- a/make_gen +++ b/make_gen @@ -18,7 +18,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \ el755driv.o amorscan.o serial.o scontroller.o t_update.o \ t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \ - el737hpv2driv.o swmotor2.o + el737hpv2driv.o swmotor2.o ipsdriv.o libpsi.a: $(OBJ) rm -f libpsi.a diff --git a/psi.c b/psi.c index 2d472d5..862cbb1 100644 --- a/psi.c +++ b/psi.c @@ -39,6 +39,7 @@ #include "tdchm.h" #include "tecsdriv.h" #include "itc4.h" +#include "ipsdriv.h" #include "bruker.h" #include "ltc11.h" #include "A1931.h" @@ -313,6 +314,8 @@ static void ConfigureController(char *name, pEVControl pNew, EVCSetPar(pNew,"lowerlimit",1.0,pCon); if(strcmp(name,"tecs") == 0){ TecsCustomize(pCon, pNew); + } else if(strcmp(name,"ips") == 0){ + IpsCustomize(pCon, pNew); } else if(strcmp(name,"euro") == 0){ EVCSetPar(pNew,"upperlimit",750.0,pCon); EVCSetPar(pNew,"lowerlimit",15.0,pCon); @@ -367,6 +370,17 @@ static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics, commandInstalled = 1; } } + } else if(strcmp(argv[3],"ips") == 0) { + checkError = 1; + pDriv = CreateIpsDriver(argc-4,&argv[4]); + if(pDriv){ + pNew = CreateEVController(pDriv,argv[2],&status); + if(pNew != NULL){ + AddCommand(pSics,argv[2],IpsWrapper,DeleteEVController, + pNew); + commandInstalled = 1; + } + } } else if(strcmp(argv[3],"bruker") == 0){ checkError = 1; pDriv = CreateBrukerDriver(argc-4,&argv[4]); @@ -429,12 +443,6 @@ static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics, SCWrite(pCon,"ERROR: failed to create driver",eError); return NULL; } - if(pNew == NULL){ - SCWrite(pCon,"ERROR: failed to create environment device object", - eError); - DeleteEVDriver(pDriv); - return NULL; - } if(status != 1) { SCWrite(pCon,"ERROR: failed to initialize device", eError); @@ -442,6 +450,12 @@ static pEVControl InstallPsiEnvironmentController(SicsInterp *pSics, sprintf(pBueffel,"HW reported: %s",pError); SCWrite(pCon,pBueffel,eError); } + if(pNew == NULL){ + SCWrite(pCon,"ERROR: failed to create environment device object", + eError); + DeleteEVDriver(pDriv); + return NULL; + } if(commandInstalled == 0){ AddCommand(pSics,argv[2],EVControlWrapper,DeleteEVController,pNew); }