- Adapted indenation to new agreed upon system
- Fixed bad status in poldi zug driver
This commit is contained in:
508
ipsdriv.c
508
ipsdriv.c
@ -33,20 +33,20 @@ Markus Zolliker, May 2005
|
||||
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
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;
|
||||
} Ips;
|
||||
|
||||
@ -54,115 +54,154 @@ static ParClass ipsClass = { "IPS", sizeof(Ips) };
|
||||
static char *onOff[] = { "off", "on", NULL };
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int IpsOk(Ips *drv) {
|
||||
static int IpsOk(Ips * drv)
|
||||
{
|
||||
float dif;
|
||||
|
||||
if (drv->d.b.msg[0] != '\0') return 1; /* connection not yet confirmed */
|
||||
if (drv->perswitch) return 1;
|
||||
if (fabs(drv->persfield - drv->lastfield) < 1e-5) return 1;
|
||||
if (drv->force != 0) return 1;
|
||||
|
||||
if (drv->d.b.msg[0] != '\0')
|
||||
return 1; /* connection not yet confirmed */
|
||||
if (drv->perswitch)
|
||||
return 1;
|
||||
if (fabs(drv->persfield - drv->lastfield) < 1e-5)
|
||||
return 1;
|
||||
if (drv->force != 0)
|
||||
return 1;
|
||||
ParPrintf(drv, eWarning,
|
||||
"\nit is not sure which field is in the magnet\n"
|
||||
"value stored in power supply: %f\n"
|
||||
" in software: %f\n"
|
||||
"use command\n \n %s confirm ...\n \n"
|
||||
"to specify the persistent field\n \n"
|
||||
, drv->persfield, drv->lastfield, drv->d.b.p.name);
|
||||
"\nit is not sure which field is in the magnet\n"
|
||||
"value stored in power supply: %f\n"
|
||||
" in software: %f\n"
|
||||
"use command\n \n %s confirm ...\n \n"
|
||||
"to specify the persistent field\n \n", drv->persfield,
|
||||
drv->lastfield, drv->d.b.p.name);
|
||||
drv->force = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int IpsConfirm(void *object, void *userarg, int argc, char *argv[])
|
||||
static int IpsConfirm(void *object, void *userarg, int argc, char *argv[])
|
||||
{
|
||||
Ips *drv = ParCast(&ipsClass, object);
|
||||
float fld;
|
||||
|
||||
|
||||
assert(drv);
|
||||
if (argc > 0) {
|
||||
if (argc > 1) {
|
||||
ParPrintf(object, eError, "Too many arguments");
|
||||
return 0;
|
||||
}
|
||||
fld=atof(argv[0]);
|
||||
fld = atof(argv[0]);
|
||||
if (fld > drv->d.upperLimit || fld < drv->d.lowerLimit) {
|
||||
ParPrintf(object, eError, "Field outside limit");
|
||||
return 0;
|
||||
}
|
||||
if (drv->perswitch) {
|
||||
ParPrintf(object, eWarning, "switch heater is on - field is %f", drv->current);
|
||||
ParPrintf(object, eWarning, "switch heater is on - field is %f",
|
||||
drv->current);
|
||||
return 0;
|
||||
}
|
||||
if (fabs(fld - drv->persfield) > 1e-5 && fabs(fld - drv->lastfield) > 1e-5) {
|
||||
ParPrintf(object, eWarning, "Be aware that this does neither match the field"
|
||||
" stored in software\nnor the field stored in power supply.");
|
||||
if (fabs(fld - drv->persfield) > 1e-5
|
||||
&& fabs(fld - drv->lastfield) > 1e-5) {
|
||||
ParPrintf(object, eWarning,
|
||||
"Be aware that this does neither match the field"
|
||||
" stored in software\nnor the field stored in power supply.");
|
||||
}
|
||||
if (drv->force && fld != drv->confirmfield) drv->force = 0;
|
||||
if (drv->force && fld != drv->confirmfield)
|
||||
drv->force = 0;
|
||||
if (drv->force == 0) {
|
||||
ParPrintf(object, eWarning, "Please repeat this command, to confirm again"
|
||||
" the persistent field of\n %f Tesla.", fld);
|
||||
ParPrintf(object, eWarning,
|
||||
"Please repeat this command, to confirm again"
|
||||
" the persistent field of\n %f Tesla.", fld);
|
||||
drv->confirmfield = fld;
|
||||
drv->force=1;
|
||||
drv->force = 1;
|
||||
} else {
|
||||
drv->force=2;
|
||||
drv->lastfield=fld;
|
||||
drv->force = 2;
|
||||
drv->lastfield = fld;
|
||||
EaseParHasChanged();
|
||||
ParPrintf(object, eValue, "%s confirm = %f", drv->d.b.p.name, fld);
|
||||
}
|
||||
} else {
|
||||
ParPrintf(object, eValue, "%s lastfield = %f", drv->d.b.p.name, drv->lastfield);
|
||||
ParPrintf(object, eValue, "%s lastfield = %f", drv->d.b.p.name,
|
||||
drv->lastfield);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IpsParDef(void *object) {
|
||||
void IpsParDef(void *object)
|
||||
{
|
||||
Ips *drv = ParCast(&ipsClass, object);
|
||||
|
||||
ParName(""); ParFmt(drv->fmt); ParTail("Tesla");
|
||||
ParName("");
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla");
|
||||
ParFloat(&drv->persfield, PAR_NAN);
|
||||
|
||||
ParName("persmode"); ParAccess(usUser); ParEnum(onOff); ParList(0);
|
||||
|
||||
ParName("persmode");
|
||||
ParAccess(usUser);
|
||||
ParEnum(onOff);
|
||||
ParList(0);
|
||||
ParInt(&drv->persmode, 1);
|
||||
|
||||
ParName("perswitch"); ParEnum(onOff); ParList(0);
|
||||
|
||||
ParName("perswitch");
|
||||
ParEnum(onOff);
|
||||
ParList(0);
|
||||
ParInt(&drv->perswitch, PAR_NAN);
|
||||
|
||||
ParName("nowait"); ParAccess(usUser); ParEnum(onOff); ParList(0);
|
||||
ParName("nowait");
|
||||
ParAccess(usUser);
|
||||
ParEnum(onOff);
|
||||
ParList(0);
|
||||
ParInt(&drv->nowait, 0);
|
||||
|
||||
ParName("maxlimit"); ParSave(1); ParFloat(&drv->maxlimit, 0.0);
|
||||
|
||||
ParName("limit"); ParAccess(usUser); ParFmt(drv->fmt); ParTail("Tesla");
|
||||
ParName("maxlimit");
|
||||
ParSave(1);
|
||||
ParFloat(&drv->maxlimit, 0.0);
|
||||
|
||||
ParName("limit");
|
||||
ParAccess(usUser);
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla");
|
||||
ParFloat(&drv->d.upperLimit, 0.0);
|
||||
if (ParActionIs(PAR_SET) > 0) {
|
||||
if (drv->maxlimit == 0) { /* first time: set maxlimit */
|
||||
if (drv->maxlimit == 0) { /* first time: set maxlimit */
|
||||
drv->maxlimit = drv->d.upperLimit;
|
||||
} else if (drv->d.upperLimit > drv->maxlimit) {
|
||||
drv->d.upperLimit= drv->maxlimit;
|
||||
ParPrintf(drv, eWarning, "limit is too high, set back to %.5g\n", drv->maxlimit);
|
||||
drv->d.upperLimit = drv->maxlimit;
|
||||
ParPrintf(drv, eWarning, "limit is too high, set back to %.5g\n",
|
||||
drv->maxlimit);
|
||||
}
|
||||
drv->d.lowerLimit = - drv->d.upperLimit;
|
||||
drv->d.lowerLimit = -drv->d.upperLimit;
|
||||
}
|
||||
|
||||
ParName("ramp"); ParAccess(usUser); ParFmt(drv->fmt); ParTail("Tesla/min");
|
||||
|
||||
ParName("ramp");
|
||||
ParAccess(usUser);
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla/min");
|
||||
ParFloat(&drv->ramp, 1.0);
|
||||
|
||||
ParName("current"); ParFmt(drv->fmt); ParTail("Tesla equivalent");
|
||||
|
||||
ParName("current");
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla equivalent");
|
||||
ParFloat(&drv->current, PAR_NAN);
|
||||
|
||||
|
||||
ParName("lastfield");
|
||||
ParSave(1);
|
||||
ParFloat(&drv->lastfield, 0);
|
||||
|
||||
ParName("confirm"); ParCmd(IpsConfirm, NULL);
|
||||
|
||||
|
||||
ParName("confirm");
|
||||
ParCmd(IpsConfirm, NULL);
|
||||
|
||||
EaseBasePar(drv);
|
||||
EaseSendPar(drv);
|
||||
ParStdDef();
|
||||
|
||||
ParName("targetValue"); ParFmt(drv->fmt); ParTail("Tesla");
|
||||
|
||||
ParName("targetValue");
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla");
|
||||
ParFloat(&drv->d.targetValue, PAR_NAN);
|
||||
|
||||
if (ParActionIs(PAR_LIST) || ParActionIs(PAR_SET) || ParActionIs(PAR_SHOW)) {
|
||||
|
||||
if (ParActionIs(PAR_LIST) || ParActionIs(PAR_SET)
|
||||
|| ParActionIs(PAR_SHOW)) {
|
||||
IpsOk(drv);
|
||||
}
|
||||
if (ParActionIs(PAR_KILL)) {
|
||||
@ -170,30 +209,43 @@ void IpsParDef(void *object) {
|
||||
}
|
||||
EaseMsgPar(drv);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void IpsStatus(Ips *drv) {
|
||||
static void IpsStatus(Ips * drv)
|
||||
{
|
||||
char *ans;
|
||||
int *code;
|
||||
int swi;
|
||||
|
||||
if (drv->d.b.state != EASE_read) return;
|
||||
ans=drv->d.b.ans;
|
||||
code=&drv->d.b.errCode;
|
||||
|
||||
if (drv->d.b.state != EASE_read)
|
||||
return;
|
||||
ans = drv->d.b.ans;
|
||||
code = &drv->d.b.errCode;
|
||||
if (ans[0] != 'X' ||
|
||||
ans[3] != 'A' ||
|
||||
ans[5] != 'C' ||
|
||||
ans[7] != 'H' ||
|
||||
ans[9] != 'M') {
|
||||
ans[3] != 'A' || ans[5] != 'C' || ans[7] != 'H' || ans[9] != 'M') {
|
||||
ParPrintf(drv, eError, "illegal status response");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
}
|
||||
switch (ans[1]) {
|
||||
case '0': break;
|
||||
case '1': ParPrintf(drv, eError, "magnet quenched"); *code = EASE_FAULT; return;
|
||||
case '2': ParPrintf(drv, eError, "IPS overheated"); *code = EASE_FAULT; return;
|
||||
case '4': ParPrintf(drv, eError, "IPS warming up"); *code = EASE_FAULT; return;
|
||||
case '8': ParPrintf(drv, eError, "IPS fault"); *code = EASE_FAULT; return;
|
||||
case '0':
|
||||
break;
|
||||
case '1':
|
||||
ParPrintf(drv, eError, "magnet quenched");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
case '2':
|
||||
ParPrintf(drv, eError, "IPS overheated");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
case '4':
|
||||
ParPrintf(drv, eError, "IPS warming up");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
case '8':
|
||||
ParPrintf(drv, eError, "IPS fault");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
default:
|
||||
ParPrintf(drv, eError, "illegal status response");
|
||||
*code = EASE_FAULT;
|
||||
@ -209,7 +261,7 @@ static void IpsStatus(Ips *drv) {
|
||||
if (drv->d.hwstate == HWBusy && drv->d.b.doit == NULL) {
|
||||
drv->d.hwstate = HWIdle;
|
||||
drv->d.stopped = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ans[8] == '5') {
|
||||
drv->heaterFault = 1;
|
||||
@ -226,8 +278,10 @@ static void IpsStatus(Ips *drv) {
|
||||
drv->perswitch = swi;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void IpsSetField(Ips *drv, float val) {
|
||||
static void IpsSetField(Ips * drv, float val)
|
||||
{
|
||||
ParLog(drv);
|
||||
if (drv->perswitch) {
|
||||
drv->current = val;
|
||||
@ -238,46 +292,58 @@ static void IpsSetField(Ips *drv, float val) {
|
||||
drv->persfield = val;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long IpsRead(long pc, void *object) {
|
||||
static long IpsRead(long pc, void *object)
|
||||
{
|
||||
Ips *drv = ParCast(&ipsClass, object);
|
||||
EaseBase *eab = object;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IpsStatus(drv);
|
||||
rd:
|
||||
EaseWrite(eab, "R7"); /* read current (in Tesla) */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "R7"); /* read current (in Tesla) */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
drv->current = OxiGet(eab, 3, NULL, drv->current);
|
||||
if (drv->perswitch) {
|
||||
IpsSetField(drv, drv->current);
|
||||
goto quit;
|
||||
}
|
||||
EaseWrite(eab, "R18"); /* read persistant field (in Tesla) */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "R18"); /* read persistant field (in Tesla) */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield));
|
||||
|
||||
|
||||
quit:
|
||||
ParLog(drv);
|
||||
return 0; } /* FSM END ********************************************/
|
||||
return 0;
|
||||
} /* FSM END ******************************************* */
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long IpsStart(long pc, void *object) {
|
||||
static long IpsStart(long pc, void *object)
|
||||
{
|
||||
Ips *drv = ParCast(&ipsClass, object);
|
||||
EaseBase *eab = object;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
EaseWrite(eab, "V");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
if (0 == strncmp(eab->version, "IPS120", 6)) {
|
||||
eab->syntax = 1;
|
||||
} else if (0 == strncmp(eab->version, "PS", 2)) {
|
||||
eab->syntax = 0;
|
||||
} else {
|
||||
snprintf(eab->msg, sizeof eab->msg, "unknown power supply version: %s", eab->version);
|
||||
snprintf(eab->msg, sizeof eab->msg,
|
||||
"unknown power supply version: %s", eab->version);
|
||||
ParPrintf(drv, eError, "ERROR: %s", eab->msg);
|
||||
EaseStop(eab);
|
||||
goto quit;
|
||||
@ -289,22 +355,27 @@ static long IpsStart(long pc, void *object) {
|
||||
drv->fmt = "%.3f";
|
||||
}
|
||||
FsmCall(IpsRead);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
||||
quit:
|
||||
return 0; } /* FSM END ********************************************/
|
||||
return 0;
|
||||
} /* FSM END ******************************************* */
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long IpsChangeField(long pc, void *object) {
|
||||
static long IpsChangeField(long pc, void *object)
|
||||
{
|
||||
Ips *drv = ParCast(&ipsClass, object);
|
||||
EaseBase *eab = object;
|
||||
float fld;
|
||||
float step;
|
||||
float ramp;
|
||||
time_t delay;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
EaseSetUpdate(eab, EASE_RUN, 0);
|
||||
if (drv->nowait) {
|
||||
drv->d.hwstate = HWIdle;
|
||||
@ -312,76 +383,97 @@ static long IpsChangeField(long pc, void *object) {
|
||||
}
|
||||
EaseWrite(eab, "C3");
|
||||
drv->remote = 1;
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "F7"); /* switch to tesla on display */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A0"); /* hold */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "F7"); /* switch to tesla on display */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A0"); /* hold */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
FsmCall(IpsRead);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
drv->remote = 2;
|
||||
if (!IpsOk(drv)) goto finish;
|
||||
if (!IpsOk(drv))
|
||||
goto finish;
|
||||
if (fabs(drv->d.targetValue - drv->lastfield) < 1e-5) {
|
||||
ParPrintf(drv, -1, "IPS: we are already at field %f", drv->lastfield);
|
||||
ParPrintf(drv, -1, "IPS: we are already at field %f",
|
||||
drv->lastfield);
|
||||
if (drv->persmode) {
|
||||
if (!drv->perswitch) goto finish;
|
||||
if (!drv->perswitch)
|
||||
goto finish;
|
||||
goto target_reached;
|
||||
} else {
|
||||
if (drv->perswitch) goto finish;
|
||||
if (drv->perswitch)
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
if (fabs(drv->current - drv->lastfield) < 1e-5) {
|
||||
goto switch_on;
|
||||
}
|
||||
OxiSet(eab, "J", drv->lastfield, 3); /* set point */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
OxiSet(eab, "J", drv->lastfield, 3); /* set point */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A1");
|
||||
ParPrintf(drv, -1, "IPS: ramp to current for %f Tesla", drv->lastfield);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
ParPrintf(drv, -1, "IPS: ramp to current for %f Tesla",
|
||||
drv->lastfield);
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
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__: /**********************************/
|
||||
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);
|
||||
if (fabs(drv->current - drv->lastfield) > 1e-5) goto stab1;
|
||||
|
||||
if (fabs(drv->current - drv->lastfield) > 1e-5)
|
||||
goto stab1;
|
||||
|
||||
stab2:
|
||||
FsmWait(1);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IpsStatus(drv);
|
||||
if (time(NULL) < drv->tim + 10) goto stab2; /* stabilize */
|
||||
|
||||
if (time(NULL) < drv->tim + 10)
|
||||
goto stab2; /* stabilize */
|
||||
|
||||
switch_on:
|
||||
if (drv->perswitch) goto wait_open;
|
||||
if (drv->perswitch)
|
||||
goto wait_open;
|
||||
if (drv->force == 2) {
|
||||
EaseWrite(eab, "H2");
|
||||
} else {
|
||||
EaseWrite(eab, "H1");
|
||||
}
|
||||
drv->force = 0;
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
drv->perswitch = 1;
|
||||
drv->swtim = time(NULL);
|
||||
|
||||
|
||||
wait_open:
|
||||
delay = drv->swtim + 30 - time(NULL);
|
||||
if (delay > 0)
|
||||
ParPrintf(drv, -1, "IPS: wait %d sec to open switch", delay);
|
||||
|
||||
|
||||
start_ramp:
|
||||
ParLog(drv);
|
||||
FsmWait(1);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
IpsStatus(drv); /* check for errors */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IpsStatus(drv); /* check for errors */
|
||||
if (drv->heaterFault) {
|
||||
if (time(NULL) > drv->swtim + 3) {
|
||||
ParPrintf(drv, eError, "IPS heater fault");
|
||||
@ -389,130 +481,162 @@ static long IpsChangeField(long pc, void *object) {
|
||||
goto off_finish;
|
||||
}
|
||||
}
|
||||
if (time(NULL) < drv->swtim + 30) goto start_ramp; /* wait */
|
||||
if (time(NULL) < drv->swtim + 30)
|
||||
goto start_ramp; /* wait */
|
||||
OxiSet(eab, "T", drv->ramp, 3);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
OxiSet(eab, "J", drv->current, 3); /* put set point to actual value */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A1"); /* go to setpoint (do not yet run) */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
OxiSet(eab, "J", drv->current, 3); /* put set point to actual value */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A1"); /* go to setpoint (do not yet run) */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
ParPrintf(drv, -1, "IPS: ramp to %f Tesla", drv->d.targetValue);
|
||||
|
||||
|
||||
ramping:
|
||||
ParLog(drv);
|
||||
FsmWait(1);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "R7"); /* read "current" in Tesla */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
IpsSetField(drv, OxiGet(eab, 3, NULL, drv->current)); /* set drv->current and callback */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "R7"); /* read "current" in Tesla */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
IpsSetField(drv, OxiGet(eab, 3, NULL, drv->current)); /* set drv->current and callback */
|
||||
EaseWrite(eab, "X");
|
||||
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 */
|
||||
if (step < 0.001) step=0.001;
|
||||
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 */
|
||||
if (step < 0.001)
|
||||
step = 0.001;
|
||||
if (drv->d.targetValue > drv->current + step) {
|
||||
fld=drv->current + step;
|
||||
fld = drv->current + step;
|
||||
} else if (drv->d.targetValue < drv->current - step) {
|
||||
fld=drv->current - step;
|
||||
fld = drv->current - step;
|
||||
} else {
|
||||
fld=drv->d.targetValue;
|
||||
if (fabs(drv->current - drv->d.targetValue) < 1e-5) goto target_reached;
|
||||
fld = drv->d.targetValue;
|
||||
if (fabs(drv->current - drv->d.targetValue) < 1e-5)
|
||||
goto target_reached;
|
||||
}
|
||||
OxiSet(eab, "J", fld, 3);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
goto ramping;
|
||||
|
||||
|
||||
target_reached:
|
||||
drv->d.hwstate = HWIdle;
|
||||
drv->d.eMode = EVMonitor; /* we are at field, drive has finished */
|
||||
if (!drv->persmode) goto hold_finish;
|
||||
drv->d.eMode = EVMonitor; /* we are at field, drive has finished */
|
||||
if (!drv->persmode)
|
||||
goto hold_finish;
|
||||
/* but we continue in the background */
|
||||
drv->tim = time(NULL);
|
||||
stab3:
|
||||
ParLog(drv);
|
||||
FsmWait(1);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "X");
|
||||
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__: /**********************************/
|
||||
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__: /**********************************/
|
||||
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__: /**********************************/
|
||||
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 */
|
||||
IpsSetField(drv, fld); /* set drv->current and callback */
|
||||
drv->lastfield = fld;
|
||||
EaseParHasChanged();
|
||||
}
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
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 */
|
||||
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__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
goto finish;
|
||||
|
||||
hold_finish:
|
||||
EaseWrite(eab, "A0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
goto finish;
|
||||
|
||||
|
||||
off_finish:
|
||||
if (drv->perswitch) {
|
||||
drv->lastfield = drv->current;
|
||||
drv->swtim = time(NULL);
|
||||
}
|
||||
EaseWrite(eab, "H0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
||||
finish:
|
||||
EaseWrite(eab, "C0");
|
||||
drv->remote = 0;
|
||||
drv->d.hwstate = HWIdle;
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
return 0; } /* FSM END ********************************************/
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
||||
return 0;
|
||||
} /* FSM END ******************************************* */
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int IpsInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
static int IpsInit(SConnection * con, int argc, char *argv[], int dynamic)
|
||||
{
|
||||
/* args:
|
||||
MakeObject objectname ips <rs232>
|
||||
<host> <port>
|
||||
MakeObject objectname ips <rs232>
|
||||
<host> <port>
|
||||
*/
|
||||
Ips *drv;
|
||||
|
||||
drv = EaseMakeDriv(con, &ipsClass, argc, argv, dynamic, 7,
|
||||
IpsParDef, OxiHandler, IpsStart, NULL, IpsRead,
|
||||
IpsChangeField);
|
||||
if (drv == NULL) return 0;
|
||||
IpsParDef, OxiHandler, IpsStart, NULL, IpsRead,
|
||||
IpsChangeField);
|
||||
if (drv == NULL)
|
||||
return 0;
|
||||
drv->d.maxwait = 999999;
|
||||
drv->d.tolerance = 0.001;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IpsStartup(void) {
|
||||
void IpsStartup(void)
|
||||
{
|
||||
ParMakeClass(&ipsClass, EaseDrivClass());
|
||||
MakeDriver("IPS", IpsInit, 0, "OI Power Supply");
|
||||
MakeDriver("IPS", IpsInit, 0, "OI Power Supply");
|
||||
}
|
||||
|
Reference in New Issue
Block a user