883 lines
22 KiB
C
883 lines
22 KiB
C
/*-------------------------------------------------------------------------
|
|
B r u k e r
|
|
|
|
An environment control driver and an additonal wrapper function for
|
|
controlling a Bruker B-EC-1 magnet controller. This controller can
|
|
either control a current or control the current through an external hall
|
|
sensor mesuring the magnetic field. In both cases both values: the field
|
|
and the current must be readable.
|
|
|
|
copyright: see copyright.h
|
|
|
|
Mark Koennecke, October 1998
|
|
---------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <tcl.h>
|
|
#include <math.h>
|
|
#include <assert.h>
|
|
#include <fortify.h>
|
|
#include <sics.h>
|
|
#include <obpar.h>
|
|
#include <evcontroller.h>
|
|
#include <evcontroller.i>
|
|
#include <evdriver.i>
|
|
#include "hardsup/serialsinq.h"
|
|
#include "hardsup/el734_errcodes.h"
|
|
#include "hardsup/el734fix.h"
|
|
#include "bruker.h"
|
|
|
|
/*
|
|
#define debug 1
|
|
*/
|
|
/*-----------------------------------------------------------------------
|
|
The Bruker Data Structure
|
|
*/
|
|
typedef struct {
|
|
void *pData;
|
|
char *pHost;
|
|
int iPort;
|
|
int iChannel;
|
|
int iMode;
|
|
int iLastError;
|
|
} BrukerDriv, *pBrukerDriv;
|
|
/*-----------------------------------------------------------------------
|
|
A couple of defines for Bruker modes and special error conditions
|
|
*/
|
|
#define FIELD 100
|
|
#define CURRENT 200
|
|
|
|
/* errors */
|
|
#define NOFUNC -1601
|
|
#define BADARG -1602
|
|
#define NOACCESS -1603
|
|
#define BADRANGE -1604
|
|
#define ERRPENDING -1605
|
|
#define NOPOWER -1606
|
|
#define NOTFIELD -1607
|
|
#define BADINTERN -1608
|
|
#define NOCONN -1609
|
|
#define BTIMEOUT -1610
|
|
#define NOPOLUNIT -1620
|
|
|
|
/* polarity */
|
|
#define PPLUS 0
|
|
#define PMINUS 1
|
|
#define PBUSY 3
|
|
|
|
/* rmtrail.c */
|
|
extern char *rmtrail(char *p);
|
|
|
|
/*---------------------------------------------------------------------------
|
|
This Bruker thing has a lot of internal error conditions and a few nasty
|
|
habits. Such as to lock up after an error ocurred until the error is reset.
|
|
Or to switch the power off, when a current above the limit is requested
|
|
after setting a bad value for the magnetic field. These problems can be
|
|
detected by analysing the return values from the Bruker. Usually the Bruker
|
|
returns the command given to the user plus additional values if requested.
|
|
On an error a string of the type E0n is appended to the command echo with
|
|
n being a small integer. In order to handle this all commands to the Bruker
|
|
are processed through this special function which takes care of the error
|
|
handling.
|
|
*/
|
|
static int BrukerCommand(pBrukerDriv self, char *pCommand,
|
|
char *pReplyBuffer, int iReplyLen)
|
|
{
|
|
int iTest, iCode;
|
|
char *pPtr;
|
|
|
|
assert(self);
|
|
assert(iReplyLen > 20); /* so small a buffer will hide errors */
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
/* send the command to the Bruker */
|
|
rmtrail(pCommand);
|
|
iTest =
|
|
SerialWriteRead(&(self->pData), pCommand, pReplyBuffer, iReplyLen);
|
|
#ifdef debug
|
|
printf("Comm: %s , Reply %s\n", pCommand, pReplyBuffer);
|
|
#endif
|
|
if (iTest != 1) { /* communication error */
|
|
self->iLastError = iTest;
|
|
return 0;
|
|
}
|
|
|
|
/* identify timeout */
|
|
if (strstr(pReplyBuffer, "?TMO") != NULL) {
|
|
self->iLastError = BTIMEOUT;
|
|
return 0;
|
|
}
|
|
|
|
/* try to find a E0 response indicating a Bruker error */
|
|
if ((pPtr = strstr(pReplyBuffer, "E0")) == NULL) {
|
|
return 1;
|
|
}
|
|
|
|
/* decode the error */
|
|
sscanf(pPtr + 1, "%x", &iCode);
|
|
switch (iCode) {
|
|
case 1:
|
|
self->iLastError = NOFUNC;
|
|
break;
|
|
case 2:
|
|
self->iLastError = BADARG;
|
|
break;
|
|
case 4:
|
|
self->iLastError = NOACCESS;
|
|
break;
|
|
case 5:
|
|
self->iLastError = BADRANGE;
|
|
break;
|
|
case 7:
|
|
self->iLastError = ERRPENDING;
|
|
break;
|
|
case 9:
|
|
self->iLastError = NOPOWER;
|
|
break;
|
|
case 10:
|
|
self->iLastError = NOTFIELD;
|
|
break;
|
|
default:
|
|
self->iLastError = BADINTERN;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int BrukerReadField(pEVControl pEva, float *fField)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr, *pSign;
|
|
int iSign = 1;
|
|
float fVal;
|
|
|
|
self = (pBrukerDriv) pEva->pDriv->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
strcpy(pCommand, "FIE/");
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
if (!iRet) {
|
|
*fField = -99;
|
|
return 0;
|
|
}
|
|
|
|
pPtr = pBueffel + 4; /* skip over echo */
|
|
/* deal with obstructing sign */
|
|
if ((pSign = strchr(pPtr, '+')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = 1;
|
|
}
|
|
if ((pSign = strchr(pPtr, '-')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = -1;
|
|
}
|
|
sscanf(pPtr, "%f", &fVal);
|
|
*fField = iSign * fVal;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int BrukerReadCurrent(pEVControl pEva, float *fField)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet, iSign = 1;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr, *pSign = NULL;
|
|
float fVal;
|
|
|
|
self = (pBrukerDriv) pEva->pDriv->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
strcpy(pCommand, "CHN/");
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
if (!iRet) {
|
|
*fField = -99;
|
|
return 0;
|
|
}
|
|
|
|
pPtr = pBueffel + 4; /* skip over echo */
|
|
/* deal with obstructing sign */
|
|
if ((pSign = strchr(pPtr, '+')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = 1;
|
|
}
|
|
if ((pSign = strchr(pPtr, '-')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = -1;
|
|
}
|
|
sscanf(pPtr, "%f", &fVal);
|
|
*fField = iSign * fVal;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int BrukerGet(pEVDriver pEva, float *fValue)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet=0, iSign = 1;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr, *pSign = NULL;
|
|
float fVal;
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if (self->iMode == FIELD) {
|
|
strcpy(pCommand, "CUF/");
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
} else if (self->iMode == CURRENT) {
|
|
strcpy(pCommand, "CUR/");
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
} else {
|
|
/* programming error */
|
|
assert(1);
|
|
}
|
|
|
|
if (!iRet) {
|
|
*fValue = -99;
|
|
return 0;
|
|
}
|
|
|
|
pPtr = pBueffel + 4; /* skip over echo */
|
|
/* deal with obstructing sign */
|
|
if ((pSign = strchr(pPtr, '+')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = 1;
|
|
}
|
|
if ((pSign = strchr(pPtr, '-')) != NULL) {
|
|
*pSign = ' ';
|
|
iSign = -1;
|
|
}
|
|
sscanf(pPtr, "%f", &fVal);
|
|
*fValue = iSign * fVal;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int BrukerRun(pEVDriver pEva, float fVal)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet =0;
|
|
char pBueffel[80];
|
|
char pCommand[40];
|
|
char *pPtr;
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if (self->iMode == FIELD) {
|
|
sprintf(pCommand, "PTF=%-6.2f", fVal);
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
} else if (self->iMode == CURRENT) {
|
|
sprintf(pCommand, "PNT=%-6.2f", fVal);
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
} else {
|
|
/* programming error */
|
|
assert(1);
|
|
}
|
|
|
|
if (!iRet) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int BrukerError(pEVDriver pEva, int *iCode, char *pError,
|
|
int iErrLen)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
*iCode = self->iLastError;
|
|
switch (*iCode) {
|
|
case NOFUNC:
|
|
strlcpy(pError, "Function not supported", iErrLen);
|
|
break;
|
|
case BADINTERN:
|
|
case BADARG:
|
|
strlcpy(pError,
|
|
"Programming problem, reset Controller & contact Programmer",
|
|
iErrLen);
|
|
break;
|
|
case NOTFIELD:
|
|
strlcpy(pError, "Bruker not switched to field mode", iErrLen);
|
|
break;
|
|
case BADRANGE:
|
|
strlcpy(pError, "Requested value out of range", iErrLen);
|
|
break;
|
|
case NOACCESS:
|
|
strlcpy(pError, "No Access, check key position at Controller",
|
|
iErrLen);
|
|
break;
|
|
case ERRPENDING:
|
|
strlcpy(pError, "Error condition pending in Bruker Controller",
|
|
iErrLen);
|
|
break;
|
|
case NOPOWER:
|
|
strlcpy(pError,
|
|
"Power OFF as consequence of some error in Bruker Controller",
|
|
iErrLen);
|
|
break;
|
|
case NOCONN:
|
|
strlcpy(pError, "No Connection to Bruker Controller", iErrLen);
|
|
break;
|
|
case BTIMEOUT:
|
|
strlcpy(pError, "Timeout at serial port", iErrLen);
|
|
break;
|
|
case NOPOLUNIT:
|
|
strlcpy(pError,
|
|
"No polarity switching unit, try setting negative current",
|
|
iErrLen);
|
|
break;
|
|
default:
|
|
SerialError(*iCode, pError, iErrLen);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int BrukerSend(pEVDriver pEva, char *pCommand, char *pReply,
|
|
int iReplyLen)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
|
|
iRet = SerialWriteRead(&(self->pData), pCommand, pReply, iReplyLen);
|
|
if (iRet != 1) {
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int BrukerInit(pEVDriver pEva)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80], pCommand[20];
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
/* open port connection */
|
|
self->pData = NULL;
|
|
iRet =
|
|
SerialOpen(&(self->pData), self->pHost, self->iPort, self->iChannel);
|
|
if (iRet != 1) {
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
/* configure serial port terminators */
|
|
SerialSendTerm(&(self->pData), "\r");
|
|
SerialATerm(&(self->pData), "1\r\n");
|
|
|
|
/* set power on */
|
|
strcpy(pCommand, "DCP=1");
|
|
iRet = SerialWriteRead(&(self->pData), pCommand, pBueffel, 80);
|
|
if (iRet != 1) {
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
|
|
/* switch to current mode as default init mode */
|
|
self->iMode = CURRENT;
|
|
strcpy(pCommand, "EXT=0");
|
|
iRet = SerialWriteRead(&(self->pData), pCommand, pBueffel, 80);
|
|
if (iRet != 1) {
|
|
self->iLastError = iRet;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int BrukerClose(pEVDriver pEva)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
|
|
self = (pBrukerDriv) pEva->pPrivate;
|
|
assert(self);
|
|
|
|
SerialClose(&(self->pData));
|
|
self->pData = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int BrukerFix(pEVDriver self, int iError)
|
|
{
|
|
pBrukerDriv pMe = NULL;
|
|
int iRet;
|
|
char pCommand[20], pBueffel[80];
|
|
|
|
assert(self);
|
|
pMe = (pBrukerDriv) self->pPrivate;
|
|
assert(pMe);
|
|
|
|
switch (iError) {
|
|
/* network errors */
|
|
case EL734__BAD_FLUSH:
|
|
case EL734__BAD_RECV:
|
|
case EL734__BAD_RECV_NET:
|
|
case EL734__BAD_RECV_UNKN:
|
|
case EL734__BAD_RECVLEN:
|
|
case EL734__BAD_RECV1:
|
|
case EL734__BAD_RECV1_PIPE:
|
|
case EL734__BAD_RNG:
|
|
case EL734__BAD_SEND:
|
|
case EL734__BAD_SEND_PIPE:
|
|
case EL734__BAD_SEND_NET:
|
|
case EL734__BAD_SEND_UNKN:
|
|
case EL734__BAD_SENDLEN:
|
|
BrukerClose(self);
|
|
iRet = BrukerInit(self);
|
|
if (iRet) {
|
|
return DEVREDO;
|
|
} else {
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
case EL734__FORCED_CLOSED:
|
|
case NOCONN:
|
|
iRet = BrukerInit(self);
|
|
if (iRet) {
|
|
return DEVREDO;
|
|
} else {
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
/* fixable Bruker Errors */
|
|
case ERRPENDING:
|
|
strcpy(pCommand, "RST=0");
|
|
iRet = BrukerCommand(pMe, pCommand, pBueffel, 79);
|
|
if (iRet) {
|
|
return DEVREDO;
|
|
} else {
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
case NOPOWER:
|
|
strcpy(pCommand, "RST=0");
|
|
iRet = BrukerCommand(pMe, pCommand, pBueffel, 79);
|
|
strcpy(pCommand, "DCP=1");
|
|
iRet = BrukerCommand(pMe, pCommand, pBueffel, 79);
|
|
if (iRet) {
|
|
return DEVREDO;
|
|
} else {
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
case NOTFIELD:
|
|
strcpy(pCommand, "EXT=2");
|
|
iRet = BrukerCommand(pMe, pCommand, pBueffel, 79);
|
|
if (iRet) {
|
|
return DEVREDO;
|
|
} else {
|
|
return DEVFAULT;
|
|
}
|
|
break;
|
|
/* handable protocoll errors */
|
|
case EL734__BAD_TMO:
|
|
case BTIMEOUT:
|
|
case NOFUNC:
|
|
return DEVREDO;
|
|
break;
|
|
default:
|
|
return DEVFAULT;
|
|
break;
|
|
}
|
|
return DEVFAULT;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
void KillBruker(void *pData)
|
|
{
|
|
pBrukerDriv pMe = NULL;
|
|
|
|
pMe = (pBrukerDriv) pData;
|
|
assert(pMe);
|
|
|
|
if (pMe->pHost) {
|
|
free(pMe->pHost);
|
|
}
|
|
free(pMe);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
pEVDriver CreateBrukerDriver(int argc, char *argv[])
|
|
{
|
|
pEVDriver pNew = NULL;
|
|
pBrukerDriv pSim = NULL;
|
|
|
|
/* check for arguments */
|
|
if (argc < 3) {
|
|
return NULL;
|
|
}
|
|
|
|
pNew = CreateEVDriver(argc, argv);
|
|
pSim = (pBrukerDriv) malloc(sizeof(BrukerDriv));
|
|
memset(pSim, 0, sizeof(BrukerDriv));
|
|
if (!pNew || !pSim) {
|
|
return NULL;
|
|
}
|
|
pNew->pPrivate = pSim;
|
|
pNew->KillPrivate = KillBruker;
|
|
|
|
/* initalise pBrukerDriver */
|
|
pSim->iLastError = 0;
|
|
pSim->pHost = strdup(argv[0]);
|
|
pSim->iPort = atoi(argv[1]);
|
|
pSim->iChannel = atoi(argv[2]);
|
|
|
|
|
|
/* initialise function pointers */
|
|
pNew->SetValue = BrukerRun;
|
|
pNew->GetValue = BrukerGet;
|
|
pNew->Send = BrukerSend;
|
|
pNew->GetError = BrukerError;
|
|
pNew->TryFixIt = BrukerFix;
|
|
pNew->Init = BrukerInit;
|
|
pNew->Close = BrukerClose;
|
|
|
|
return pNew;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int BrukerSetMode(pEVControl pEva, SConnection * pCon, int iMode)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr;
|
|
|
|
self = (pBrukerDriv) pEva->pDriv->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if (iMode == CURRENT) {
|
|
strcpy(pCommand, "EXT=0");
|
|
} else if (iMode == FIELD) {
|
|
strcpy(pCommand, "EXT=2");
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Internal: invalid mode for Bruker given",
|
|
eError);
|
|
return 0;
|
|
}
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR:");
|
|
BrukerError(pEva->pDriv, &iRet, (pBueffel + 7), 70);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
self->iMode = iMode;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int BrukerGetPolarity(pEVControl pEva, SConnection * pCon, int *iMode)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr;
|
|
|
|
self = (pBrukerDriv) pEva->pDriv->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
strcpy(pCommand, "POL/");
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR:");
|
|
BrukerError(pEva->pDriv, &iRet, (pBueffel + 7), 70);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
pPtr = pBueffel + 4;
|
|
sscanf(pPtr, "%d", iMode);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
int BrukerSetPolarity(pEVControl pEva, SConnection * pCon, int iMode)
|
|
{
|
|
pBrukerDriv self = NULL;
|
|
int iRet;
|
|
char pBueffel[80];
|
|
char pCommand[6];
|
|
char *pPtr;
|
|
|
|
self = (pBrukerDriv) pEva->pDriv->pPrivate;
|
|
assert(self);
|
|
|
|
if (self->pData == NULL) {
|
|
self->iLastError = NOCONN;
|
|
return 0;
|
|
}
|
|
|
|
if (iMode == PPLUS) {
|
|
strcpy(pCommand, "POL=0");
|
|
} else if (iMode == PMINUS) {
|
|
strcpy(pCommand, "POL=1");
|
|
} else {
|
|
assert(1); /* programming error */
|
|
}
|
|
|
|
iRet = BrukerCommand(self, pCommand, pBueffel, 79);
|
|
if ((strstr(pBueffel, "POL=0E01") != NULL) ||
|
|
(strstr(pBueffel, "POL=1E01") != NULL)) {
|
|
self->iLastError = NOPOLUNIT;
|
|
iRet = 0;
|
|
}
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR:");
|
|
BrukerError(pEva->pDriv, &iRet, (pBueffel + 6), 70);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
handle Bruker specific commands:
|
|
- polarity for switching polarity
|
|
- field for reading field
|
|
- current for reading current
|
|
- mode for setting and retrieving the current control mode
|
|
- list append our own stuff to the rest
|
|
in all other cases fall back and call EVControllerWrapper to handle it or
|
|
eventually throw an error.
|
|
*/
|
|
int BrukerAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
|
|
pEVControl self = NULL;
|
|
int iRet, iMode;
|
|
char pBueffel[256];
|
|
pBrukerDriv pMe = NULL;
|
|
float fVal;
|
|
|
|
self = (pEVControl) pData;
|
|
assert(self);
|
|
pMe = (pBrukerDriv) self->pDriv->pPrivate;
|
|
assert(pMe);
|
|
|
|
if (argc > 1) {
|
|
strtolower(argv[1]);
|
|
/*------ polarity */
|
|
if (strcmp(argv[1], "polarity") == 0) {
|
|
if (argc > 2) { /* set case */
|
|
strtolower(argv[2]);
|
|
if (strcmp(argv[2], "plus") == 0) {
|
|
iMode = PPLUS;
|
|
} else if (strcmp(argv[2], "minus") == 0) {
|
|
iMode = PMINUS;
|
|
} else {
|
|
sprintf(pBueffel, "ERROR: %s is no knwon polarity mode",
|
|
argv[2]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
/* check permission */
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
/* do it */
|
|
iRet = BrukerSetPolarity(self, pCon, iMode);
|
|
if (iRet) {
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else { /* get case */
|
|
|
|
iRet = BrukerGetPolarity(self, pCon, &iMode);
|
|
if (iRet) {
|
|
if (iMode == PPLUS) {
|
|
sprintf(pBueffel, "%s.polarity = plus", argv[0]);
|
|
} else if (iMode == PMINUS) {
|
|
sprintf(pBueffel, "%s.polarity = minus", argv[0]);
|
|
} else {
|
|
assert(1); /* programming problem */
|
|
}
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
/*-------- control mode */
|
|
else if (strcmp(argv[1], "mode") == 0) {
|
|
if (argc > 2) { /* set case */
|
|
strtolower(argv[2]);
|
|
if (strcmp(argv[2], "field") == 0) {
|
|
iMode = FIELD;
|
|
} else if (strcmp(argv[2], "current") == 0) {
|
|
iMode = CURRENT;
|
|
} else {
|
|
sprintf(pBueffel, "ERROR: %s is no known control mode", argv[2]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
/* check permission */
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
/* do it */
|
|
iRet = BrukerSetMode(self, pCon, iMode);
|
|
if (iRet) {
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else { /* get case */
|
|
|
|
if (pMe->iMode == FIELD) {
|
|
sprintf(pBueffel, "%s.mode = field", argv[0]);
|
|
} else if (pMe->iMode == CURRENT) {
|
|
sprintf(pBueffel, "%s.mode = current", argv[0]);
|
|
} else {
|
|
assert(1); /* programming problem */
|
|
}
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*-----------field */
|
|
else if (strcmp(argv[1], "field") == 0) {
|
|
iRet = BrukerReadField(self, &fVal);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR: ");
|
|
self->pDriv->GetError(self->pDriv, &iMode, pBueffel + 7, 240);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
sprintf(pBueffel, "%s.field = %f Tesla", argv[0], fVal);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
}
|
|
/*----------- current */
|
|
else if (strcmp(argv[1], "current") == 0) {
|
|
iRet = BrukerReadCurrent(self, &fVal);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR: ");
|
|
self->pDriv->GetError(self->pDriv, &iMode, pBueffel + 7, 240);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
sprintf(pBueffel, "%s.current = %f A", argv[0], fVal);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
}
|
|
/*--------- list */
|
|
else if (strcmp(argv[1], "list") == 0) {
|
|
/* print generals first */
|
|
EVControlWrapper(pCon, pSics, pData, argc, argv);
|
|
/* print our add on stuff */
|
|
iRet = BrukerReadCurrent(self, &fVal);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR: ");
|
|
self->pDriv->GetError(self->pDriv, &iMode, pBueffel + 7, 240);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
} else {
|
|
sprintf(pBueffel, "%s.current = %f A", argv[0], fVal);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
}
|
|
iRet = BrukerReadField(self, &fVal);
|
|
if (!iRet) {
|
|
strcpy(pBueffel, "ERROR: ");
|
|
self->pDriv->GetError(self->pDriv, &iMode, pBueffel + 7, 240);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
} else {
|
|
sprintf(pBueffel, "%s.field = %f Tesla", argv[0], fVal);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
}
|
|
if (pMe->iMode == FIELD) {
|
|
sprintf(pBueffel, "%s.mode = field", argv[0]);
|
|
} else if (pMe->iMode == CURRENT) {
|
|
sprintf(pBueffel, "%s.mode = current", argv[0]);
|
|
} else {
|
|
sprintf(pBueffel, "ERROR: Programming error");
|
|
}
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
iRet = BrukerGetPolarity(self, pCon, &iMode);
|
|
if (iRet) {
|
|
if (iMode == PPLUS) {
|
|
sprintf(pBueffel, "%s.polarity = plus", argv[0]);
|
|
} else if (iMode == PMINUS) {
|
|
sprintf(pBueffel, "%s.polarity = minus", argv[0]);
|
|
} else if (iMode == PBUSY) {
|
|
sprintf(pBueffel, "%s.polarity = busy", argv[0]);
|
|
} else {
|
|
sprintf(pBueffel, "ERROR: Programming problem");
|
|
}
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
} else {
|
|
SCWrite(pCon, "ERROR: cannot read polarity", eError);
|
|
}
|
|
return 1;
|
|
} else {
|
|
return EVControlWrapper(pCon, pSics, pData, argc, argv);
|
|
}
|
|
}
|
|
return EVControlWrapper(pCon, pSics, pData, argc, argv);
|
|
}
|