338 lines
7.7 KiB
C
338 lines
7.7 KiB
C
/*--------------------------------------------------------------------------
|
|
E L 7 5 5 D R I V
|
|
|
|
This file contains the implementation for the EL755 magnet controller
|
|
driver.
|
|
|
|
Mark Koennecke, November 1999
|
|
|
|
Copyright: see copyright.h
|
|
----------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <fortify.h>
|
|
#include <strlutil.h>
|
|
|
|
#include <conman.h>
|
|
#include <fortify.h>
|
|
#include "evdriver.h"
|
|
#include "hardsup/el755_def.h"
|
|
#include "hardsup/el755_errcodes.h"
|
|
#include "hardsup/sinq_prototypes.h"
|
|
|
|
#define CAPSIZED -8090
|
|
|
|
#define ABS(x) (x < 0 ? -(x) : (x))
|
|
/*-----------------------------------------------------------------------*/
|
|
typedef struct {
|
|
void *pData;
|
|
char *pHost;
|
|
int iPort;
|
|
int iChannel;
|
|
int iIndex;
|
|
int iLastError;
|
|
int iCapCount;
|
|
} EL755Driv, *pEL755Driv;
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int GetEL755Pos(pEVDriver self, float *fPos)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
int iRet;
|
|
float fSoll;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
iRet = EL755_GetCurrents(&(pMe->pData), &fSoll, fPos);
|
|
if (iRet != 1) {
|
|
return 0;
|
|
}
|
|
/**
|
|
* This here is a check for the condition when the current breaks down.
|
|
* This situation is characterized by the fSoll being something and the
|
|
* fPos being 0.
|
|
*/
|
|
if (ABS(*fPos) < .1 && ABS(fSoll) > .1) {
|
|
pMe->iCapCount++;
|
|
if (pMe->iCapCount > 3) {
|
|
pMe->iLastError = CAPSIZED;
|
|
return 0;
|
|
}
|
|
} else {
|
|
pMe->iCapCount = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
static int EL755Run(pEVDriver self, float fVal)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
int iRet;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
iRet = EL755_SetCurrent(&(pMe->pData), fVal);
|
|
pMe->iCapCount = 0;
|
|
if (iRet != 1) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL755Error(pEVDriver self, int *iCode, char *error, int iErrLen)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
char *pPtr = NULL;
|
|
int i1, i2;
|
|
char pBueffel[132];
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
/* retrieve error */
|
|
EL755_ErrInfo(&pPtr, iCode, &i1, &i2);
|
|
switch (*iCode) {
|
|
case CAPSIZED:
|
|
strlcpy(error, "Powersupply has capsized, try lower current", iErrLen);
|
|
break;
|
|
case EL755__TURNED_OFF:
|
|
strlcpy(error, "EL755__TURNED_OF", iErrLen);
|
|
break;
|
|
case EL755__TOO_MANY:
|
|
strlcpy(error, "EL755__TO_MANY", iErrLen);
|
|
break;
|
|
case EL755__TOO_LARGE:
|
|
strlcpy(error, "EL755__TOO_LARGE", iErrLen);
|
|
break;
|
|
case EL755__OVFLOW:
|
|
strlcpy(error, "EL755_OVFLOW", iErrLen);
|
|
break;
|
|
case EL755__OUT_OF_RANGE:
|
|
strlcpy(error, "EL755_OUT_OF_RANGE", iErrLen);
|
|
break;
|
|
case EL755__OFFLINE:
|
|
strlcpy(error, "EL755_OFFLINE", iErrLen);
|
|
break;
|
|
case EL755__NO_SOCKET:
|
|
strlcpy(error, "EL755__NO_SOCKET", iErrLen);
|
|
break;
|
|
case EL755__NOT_OPEN:
|
|
strlcpy(error, "EL755__NOT_OPEN", iErrLen);
|
|
break;
|
|
case EL755__FORCED_CLOSED:
|
|
strlcpy(error, "EL755__FORCED_CLOSED", iErrLen);
|
|
break;
|
|
case EL755__BAD_TMO:
|
|
strlcpy(error, "EL755__BAD_TMO", iErrLen);
|
|
break;
|
|
case EL755__BAD_SOCKET:
|
|
strlcpy(error, "EL755__BAD_SOCKET", iErrLen);
|
|
break;
|
|
case EL755__BAD_PAR:
|
|
strlcpy(error, "EL755__BAD_PAR", iErrLen);
|
|
break;
|
|
case EL755__BAD_OFL:
|
|
strlcpy(error, "EL755__BAD_OFL", iErrLen);
|
|
break;
|
|
case EL755__BAD_MALLOC:
|
|
strlcpy(error, "EL755__BAD_MALLOC", iErrLen);
|
|
break;
|
|
case EL755__BAD_ILLG:
|
|
strlcpy(error, "EL755__BAD_ILLG", iErrLen);
|
|
break;
|
|
case EL755__BAD_DEV:
|
|
strlcpy(error, "EL755__BAD_DEV", iErrLen);
|
|
break;
|
|
case EL755__BAD_CMD:
|
|
strlcpy(error, "EL755__BAD_CMD", iErrLen);
|
|
break;
|
|
case EL755__BAD_ASYNSRV:
|
|
strlcpy(error, "EL755__BAD_ASYNSRV", iErrLen);
|
|
break;
|
|
default:
|
|
sprintf(pBueffel, "Unknown error %d found", *iCode);
|
|
strlcpy(error, pBueffel, iErrLen);
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------*/
|
|
int EL755_Send(void **handle, char *pCom, char *reply, int iLen);
|
|
/*
|
|
* added to el755_utility by M.K.
|
|
*/
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL755Send(pEVDriver self, char *pCommand, char *pReply,
|
|
int iLen)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
char *pPtr = NULL;
|
|
char pBueffel[132];
|
|
int iRet;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
if (strlen(pCommand) > 130)
|
|
return 0;
|
|
|
|
/* make sure that we have a \r at the end */
|
|
strcpy(pBueffel, pCommand);
|
|
if (strrchr(pBueffel, (int) '\r') == NULL) {
|
|
strcat(pBueffel, "\r");
|
|
}
|
|
|
|
return EL755_Send(&(pMe->pData), pBueffel, pReply, iLen);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL755Init(pEVDriver self)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
int iRet;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
pMe->pData = NULL;
|
|
iRet = EL755_Open(&(pMe->pData), pMe->pHost, pMe->iPort, pMe->iChannel,
|
|
pMe->iIndex);
|
|
return iRet;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL755Close(pEVDriver self)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
int iRet;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
EL755_Close(&(pMe->pData), 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int EL755Fix(pEVDriver self, int iError)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
int iRet;
|
|
|
|
assert(self);
|
|
pMe = (pEL755Driv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
switch (iError) {
|
|
case CAPSIZED:
|
|
case EL755__TURNED_OFF:
|
|
case EL755__TOO_MANY:
|
|
case EL755__TOO_LARGE:
|
|
case EL755__OUT_OF_RANGE:
|
|
case EL755__BAD_PAR:
|
|
case EL755__BAD_SOCKET:
|
|
case EL755__BAD_MALLOC:
|
|
case EL755__BAD_DEV:
|
|
case EL755__BAD_CMD:
|
|
case EL755__BAD_ASYNSRV:
|
|
return DEVFAULT;
|
|
break;
|
|
case EL755__OVFLOW:
|
|
case EL755__BAD_TMO:
|
|
case EL755__BAD_ILLG:
|
|
return DEVREDO;
|
|
break;
|
|
case EL755__OFFLINE:
|
|
case EL755__BAD_OFL:
|
|
EL755_PutOnline(&(pMe->pData), 2);
|
|
return DEVREDO;
|
|
break;
|
|
case EL755__NO_SOCKET:
|
|
case EL755__NOT_OPEN:
|
|
case EL755__FORCED_CLOSED:
|
|
EL755_Open(&(pMe->pData), pMe->pHost, pMe->iPort,
|
|
pMe->iChannel, pMe->iIndex);
|
|
return DEVREDO;
|
|
break;
|
|
default:
|
|
return DEVFAULT;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL755Halt(pEVDriver * self)
|
|
{
|
|
assert(self);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
void KillEL755(void *pData)
|
|
{
|
|
pEL755Driv pMe = NULL;
|
|
|
|
pMe = (pEL755Driv) pData;
|
|
assert(pMe);
|
|
|
|
if (pMe->pHost) {
|
|
free(pMe->pHost);
|
|
}
|
|
free(pMe);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
pEVDriver CreateEL755Driv(int argc, char *argv[])
|
|
{
|
|
pEVDriver pNew = NULL;
|
|
pEL755Driv pSim = NULL;
|
|
|
|
/* check for arguments */
|
|
if (argc < 4) {
|
|
return NULL;
|
|
}
|
|
|
|
pNew = CreateEVDriver(argc, argv);
|
|
pSim = (pEL755Driv) malloc(sizeof(EL755Driv));
|
|
memset(pSim, 0, sizeof(EL755Driv));
|
|
if (!pNew || !pSim) {
|
|
return NULL;
|
|
}
|
|
pNew->pPrivate = pSim;
|
|
pNew->KillPrivate = KillEL755;
|
|
|
|
pSim->iLastError = 0;
|
|
pSim->pHost = strdup(argv[0]);
|
|
pSim->iPort = atoi(argv[1]);
|
|
pSim->iChannel = atoi(argv[2]);
|
|
pSim->iIndex = atoi(argv[3]);
|
|
|
|
/* initialise function pointers */
|
|
pNew->SetValue = EL755Run;
|
|
pNew->GetValue = GetEL755Pos;
|
|
pNew->Send = EL755Send;
|
|
pNew->GetError = EL755Error;
|
|
pNew->TryFixIt = EL755Fix;
|
|
pNew->Init = EL755Init;
|
|
pNew->Close = EL755Close;
|
|
|
|
return pNew;
|
|
}
|