- improvements in protocols and drivers
This commit is contained in:
122
ipsdriv.c
122
ipsdriv.c
@ -48,6 +48,7 @@ typedef struct {
|
||||
float measured; /* measured current */
|
||||
float inductance; /* induction (read only on startup) */
|
||||
float ampRamp; /* ramp in amps (read only on startup) */
|
||||
float trainedTo; /* use training mode when the field is higher than this value (slow ramp limits) */
|
||||
char *startScript; /* script to be called on startup */
|
||||
int persmode; /* 0: delayed persistant mode, 1: go to persistant mode, 2: leave switch on */
|
||||
int persdelay; /* wait time for delayed persistant mode */
|
||||
@ -56,6 +57,7 @@ typedef struct {
|
||||
int nowait; /* 0: normal, 1: drive finishes immediately, ramp in background */
|
||||
int perswait; /* wait time for persistent mode workaround (sec) */
|
||||
int heaterFault;
|
||||
int trainMode; /* 0/1 read back for train mode, 2/3 command for trainMode */
|
||||
DoThis dothis;
|
||||
char *fmt; /* fmt for field */
|
||||
int force; /* force = 2: put heater switch even when stored field does not match */
|
||||
@ -79,8 +81,10 @@ static int IpsOk(Ips * drv)
|
||||
if (drv->lastfield == PAR_NAN) {
|
||||
drv->lastfield = drv->persfield;
|
||||
}
|
||||
if (fabs(drv->persfield - drv->lastfield) < 1e-5)
|
||||
if (fabs(drv->persfield - drv->lastfield) < 1e-2) {
|
||||
drv->lastfield = drv->persfield;
|
||||
return 1;
|
||||
}
|
||||
if (drv->force != 0)
|
||||
return 1;
|
||||
ParPrintf(drv, eWarning,
|
||||
@ -249,6 +253,17 @@ void IpsParDef(void *object)
|
||||
ParList("");
|
||||
ParFloat(&drv->inductance, 0.0);
|
||||
|
||||
ParName("trainedTo");
|
||||
ParAccess(usUser);
|
||||
ParFmt(drv->fmt);
|
||||
ParTail("Tesla");
|
||||
ParFloat(&drv->trainedTo, 0.0);
|
||||
|
||||
ParName("trainMode");
|
||||
ParEnum(onOff);
|
||||
ParList(0);
|
||||
ParInt(&drv->trainMode, PAR_NAN);
|
||||
|
||||
ParName("startScript");
|
||||
ParAccess(usUser);
|
||||
ParList("");
|
||||
@ -283,7 +298,8 @@ static void IpsStatus(Ips * drv)
|
||||
char *ans;
|
||||
int *code;
|
||||
int swi;
|
||||
|
||||
char *errmsg;
|
||||
|
||||
if (drv->d.b.state != EASE_read)
|
||||
return;
|
||||
ans = drv->d.b.ans;
|
||||
@ -296,28 +312,38 @@ static void IpsStatus(Ips * drv)
|
||||
}
|
||||
switch (ans[1]) {
|
||||
case '0':
|
||||
if (ans[6] > '3') {
|
||||
errmsg = "ERROR: auto-run-down (low He level)";
|
||||
} else {
|
||||
errmsg = "";
|
||||
}
|
||||
break;
|
||||
case '1':
|
||||
ParPrintf(drv, eError, "magnet quenched");
|
||||
errmsg = "ERROR: magnet quenched";
|
||||
drv->lastfield = PAR_NAN;
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
break;
|
||||
case '2':
|
||||
ParPrintf(drv, eError, "IPS overheated");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
errmsg = "ERROR: IPS overheated";
|
||||
break;
|
||||
case '4':
|
||||
ParPrintf(drv, eError, "IPS warming up");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
errmsg = "ERROR: IPS warming up";
|
||||
break;
|
||||
case '8':
|
||||
ParPrintf(drv, eError, "IPS fault");
|
||||
errmsg = "ERROR: IPS fault";
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
ParPrintf(drv, eError, "illegal status response");
|
||||
errmsg = "ERROR: illegal status response";
|
||||
}
|
||||
if (errmsg[0] != '\0') {
|
||||
if (strcmp(errmsg, drv->d.b.msg) != 0) {
|
||||
snprintf(drv->d.b.msg, sizeof drv->d.b.msg, "%s", errmsg);
|
||||
ParPrintf(drv, eError, "%s", errmsg);
|
||||
}
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
} else {
|
||||
drv->d.b.msg[0]='\0'; /* clear status */
|
||||
}
|
||||
if (ans[6] != '3') {
|
||||
if (drv->remote == 2) { /* remote state monitoring local switch */
|
||||
@ -338,6 +364,7 @@ static void IpsStatus(Ips * drv)
|
||||
drv->heaterFault = 1;
|
||||
return;
|
||||
}
|
||||
drv->trainMode = (ans[10] >= '4');
|
||||
drv->heaterFault = 0;
|
||||
if (ans[8] == '1') {
|
||||
swi = 1;
|
||||
@ -376,6 +403,9 @@ static long IpsRead(long pc, void *object)
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
if (eab->state == EASE_abort) {
|
||||
eab->state = EASE_idle;
|
||||
}
|
||||
EasePchk(drv);
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__;
|
||||
@ -407,13 +437,14 @@ static long IpsRead(long pc, void *object)
|
||||
IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield));
|
||||
|
||||
checktodo:
|
||||
if (eab->msg[0] != '\0') goto quit; /* no action when in error */
|
||||
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) {
|
||||
if ((drv->persmode == 1 && now > drv->tim + 10) || now > drv->tim + drv->persdelay) {
|
||||
drv->dothis = SWITCH_OFF;
|
||||
} else {
|
||||
drv->dothis = NOTHING;
|
||||
@ -450,6 +481,9 @@ static long IpsRead(long pc, void *object)
|
||||
goto quit;
|
||||
|
||||
switch_off:
|
||||
EaseWrite(eab, "A0");
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "H0");
|
||||
drv->perswitch = 0;
|
||||
drv->swtim = time(NULL);
|
||||
@ -543,10 +577,12 @@ static long IpsStart(long pc, void *object)
|
||||
float value;
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
int iRet;
|
||||
char msg[256];
|
||||
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
EaseWrite(eab, "V");
|
||||
EaseWrite(eab, "V\rQ4"); /* get version and switch to ext. resolution */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
if (0 == strncmp(eab->version, "IPS120", 6)) {
|
||||
@ -554,10 +590,9 @@ static long IpsStart(long pc, void *object)
|
||||
} else if (0 == strncmp(eab->version, "PS", 2)) {
|
||||
eab->syntax = 0;
|
||||
} else {
|
||||
snprintf(eab->msg, sizeof eab->msg,
|
||||
snprintf(msg, sizeof msg,
|
||||
"unknown power supply version: %s", eab->version);
|
||||
ParPrintf(drv, eLogError, "ERROR: %s", eab->msg);
|
||||
EaseStop(eab);
|
||||
EaseStop(eab, msg);
|
||||
goto quit;
|
||||
}
|
||||
ParPrintf(drv, eLog, "connected to %s", eab->version);
|
||||
@ -621,9 +656,8 @@ static long IpsStart(long pc, void *object)
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
iRet = Tcl_Eval(pTcl, drv->startScript);
|
||||
if (iRet != TCL_OK) {
|
||||
snprintf(eab->msg, sizeof eab->msg, "%s", pTcl->result);
|
||||
ParPrintf(drv, eLogError, "ERROR: %s", eab->msg);
|
||||
EaseStop(eab);
|
||||
snprintf(msg, sizeof msg, "%s", pTcl->result);
|
||||
EaseStop(eab, msg);
|
||||
goto quit;
|
||||
}
|
||||
eab->msg[0]='\0';
|
||||
@ -647,15 +681,24 @@ static long IpsChangeField(long pc, void *object)
|
||||
|
||||
switch (pc) {
|
||||
default: /* FSM BEGIN ****************************** */
|
||||
|
||||
if (eab->syntax == 0) {
|
||||
EaseWrite(eab, "C3"); /* set remote */
|
||||
} else {
|
||||
EaseWrite(eab, "C3\rQ4"); /* set remote and repeat extended resolution (in case of power failure) */
|
||||
}
|
||||
drv->remote = 1; /* remote state */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
if (!EaseGetUpdate(drv, EASE_RUN)) {
|
||||
/* an other flag than EASE_RUN was set -> should not be the case */
|
||||
return 0;
|
||||
}
|
||||
EaseSetUpdate(eab, EASE_RUN, 0);
|
||||
if (drv->nowait) {
|
||||
drv->d.hwstate = HWIdle;
|
||||
drv->d.eMode = EVMonitor; /* finish drive, continue in background */
|
||||
}
|
||||
EaseWrite(eab, "C3");
|
||||
drv->remote = 1; /* remote state */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "F7"); /* switch to tesla on display */
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
@ -725,7 +768,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
||||
if (fabs(drv->current - drv->lastfield) > 1e-5)
|
||||
if (fabs(drv->current - drv->lastfield) >= 1e-4)
|
||||
goto stab1;
|
||||
|
||||
stab2:
|
||||
@ -763,6 +806,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
ParLog(drv);
|
||||
start_ramp:
|
||||
FsmWait(1);
|
||||
drv->tim = time(NULL);
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
|
||||
@ -809,9 +853,7 @@ static long IpsChangeField(long pc, void *object)
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
ramp = OxiGet(eab, 3, NULL, drv->ramp);
|
||||
step = ramp / 3; /* step = ramp * 20 sec */
|
||||
if (step < 0.001)
|
||||
step = 0.001;
|
||||
step = fabs(ramp / 3) + 0.001; /* step = ramp * 20 sec */
|
||||
if (drv->d.targetValue > drv->current + step) {
|
||||
fld = drv->current + step;
|
||||
} else if (drv->d.targetValue < drv->current - step) {
|
||||
@ -821,8 +863,28 @@ static long IpsChangeField(long pc, void *object)
|
||||
if (fabs(drv->current - drv->d.targetValue) < 1e-5)
|
||||
goto target_reached;
|
||||
}
|
||||
if (fabs(fld) >= drv->trainedTo) {
|
||||
if (drv->trainMode == 0) {
|
||||
drv->trainMode = 3; /* remember that we must go to train mode */
|
||||
}
|
||||
drv->trainedTo = fabs(fld);
|
||||
} else {
|
||||
if (drv->trainMode == 1) {
|
||||
drv->trainMode = 2; /* remember that we must go to fast mode */
|
||||
}
|
||||
}
|
||||
OxiSet(eab, "J", fld, 3);
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
if (drv->trainMode < 2) goto ramping;
|
||||
if (drv->trainMode == 2) {
|
||||
ParPrintf(drv, -1, "IPS: switch off train mode");
|
||||
EaseWrite(eab, "M1");
|
||||
} else {
|
||||
ParPrintf(drv, -1, "IPS: switch to train mode (slow ramp)");
|
||||
EaseWrite(eab, "M5");
|
||||
}
|
||||
return __LINE__;
|
||||
case __LINE__: /**********************************/
|
||||
goto ramping;
|
||||
|
||||
|
Reference in New Issue
Block a user