- Fixed a bug fix with Fixed motor in TAS code
- Made AMOR write HDF-5 data in chunks - Added driver for a PSI-DSP magnet controller as used at SLS - Added code for directly accessing RS232 controllers connected to a terminal server, thereby bypassing the SerPortServer - A rounding problem in the PSD histogram memory was resolved.
This commit is contained in:
388
slsmagnet.c
Normal file
388
slsmagnet.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
S L S M A G N E T
|
||||
|
||||
This file contains the driver for the PSI-DSP magnet controller as
|
||||
aquired from SLS.
|
||||
|
||||
Mark Koennecke, October 2001
|
||||
|
||||
Copyright: see copyright.h
|
||||
----------------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include "fortify.h"
|
||||
#include "conman.h"
|
||||
#include "servlog.h"
|
||||
#include "fortify.h"
|
||||
|
||||
typedef struct __EVDriver *pEVDriver;
|
||||
|
||||
#include "evdriver.i"
|
||||
#include "hardsup/el734_def.h"
|
||||
#include "hardsup/el734fix.h"
|
||||
#include "network.h"
|
||||
#include "rs232controller.h"
|
||||
|
||||
/*
|
||||
error codes
|
||||
*/
|
||||
#define BADECHO -5100
|
||||
#define NOTCONNECTED -5200
|
||||
#define TIMEOUT -5300
|
||||
|
||||
/*
|
||||
when waiting for results, the code loops at max MAXLOOP times
|
||||
before doing a timeout. 100 corresponds to one second
|
||||
*/
|
||||
#define MAXLOOP 100
|
||||
|
||||
/*
|
||||
packet header codes
|
||||
*/
|
||||
#define DSPWRITE 0x80
|
||||
#define DSPREAD 0x0
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
mkChannel *pSock;
|
||||
char *pHost;
|
||||
int iPort;
|
||||
int iError;
|
||||
} SLSDriv, *pSLSDriv;
|
||||
/*-------------------------------------------------------------------------
|
||||
Code for data conversion from Lukas Tanner. The ULONG is system dependent,
|
||||
it MUST describe a 32 bit value.
|
||||
-------------------------------------------------------------------------*/
|
||||
#define ULONG int
|
||||
/***********************************************************************/
|
||||
static ULONG double2DSPfloat( double input )
|
||||
/***********************************************************************/
|
||||
/* Konvertiert eine normale double Variable in ein 32bit DSP Float Format. */
|
||||
{
|
||||
ULONG output;
|
||||
double mantissa;
|
||||
int exponent;
|
||||
|
||||
if (input == 0) {
|
||||
output = 0;
|
||||
} else {
|
||||
mantissa = 2 * (frexp(fabs(input), &exponent));
|
||||
mantissa = ldexp(mantissa, 23);
|
||||
exponent =exponent - 1 + 127;
|
||||
if (exponent < 0) {
|
||||
exponent = 0;
|
||||
} else if (exponent > 0xFE) {
|
||||
exponent = 0xFE;
|
||||
}
|
||||
exponent = exponent << 23;
|
||||
output = ((ULONG) mantissa) & 0x7FFFFF;
|
||||
output = output | ((ULONG) (exponent));
|
||||
if (input < 0) {
|
||||
output = output | 0x80000000;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
static double DSPfloat2double( ULONG input )
|
||||
/***********************************************************************/
|
||||
/* Konvertiert eine Variable inder ein 32bit DSP Float Wert abgelegt ist,
|
||||
in ein normales double Format
|
||||
32bit IEEE Float => SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM; S = Sign Bit
|
||||
E = Exponent
|
||||
M = Mantissa (23)*/
|
||||
{
|
||||
double output;
|
||||
if ((input & 0x7FFFFF) == 0 && ((input >> 23) & 0xFF) == 0) {
|
||||
output = 0;
|
||||
} else {
|
||||
output = ldexp(input & 0x7FFFFF,-23) + 1;
|
||||
output = output * pow(-1, ((input >>31) & 1));
|
||||
output = output * ldexp(1, (((input >>23) & 0xFF) - 127));
|
||||
}
|
||||
return output;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6])
|
||||
{
|
||||
long lVal = 0;
|
||||
int iRet, i;
|
||||
|
||||
if(!pSock)
|
||||
return NOTCONNECTED;
|
||||
|
||||
iRet = NETWrite(pSock,msg,6);
|
||||
if(iRet < 0)
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
for(i = 0; i < MAXLOOP; i++)
|
||||
{
|
||||
iRet = NETAvailable(pSock,10);
|
||||
if(iRet < 0)
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
else if(iRet == 1)
|
||||
{
|
||||
lVal += NETRead(pSock,reply+lVal,6-lVal,-10);
|
||||
if(lVal >= 6)
|
||||
{
|
||||
return (int)lVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TIMEOUT;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int GetSLSPos(pEVDriver self, float *fPos)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
int iRet, ival;
|
||||
double dval;
|
||||
char msg[6], reply[6];
|
||||
long lVal;
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv)self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
msg[0] = DSPREAD; /* read request */
|
||||
msg[1] = 0x92; /* address of mag current */
|
||||
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||
if(iRet < 0)
|
||||
{
|
||||
pMe->iError = iRet;
|
||||
return iRet;
|
||||
}
|
||||
memcpy(&ival,reply+2,4);
|
||||
dval = DSPfloat2double(ival);
|
||||
*fPos = (float)dval;
|
||||
pMe->iError = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SLSRun(pEVDriver self, float fVal)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
int iRet, ival,i;
|
||||
char msg[6], reply[6];
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv )self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
msg[0] = DSPWRITE;
|
||||
msg[1] = 0x90;
|
||||
ival = double2DSPfloat((double)fVal);
|
||||
memcpy(msg+2, &ival,4);
|
||||
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||
if(iRet <= 0)
|
||||
{
|
||||
pMe->iError = iRet;
|
||||
return iRet;
|
||||
}
|
||||
for(i = 1; i < 6; i++)
|
||||
{
|
||||
if(msg[i] != reply[i])
|
||||
{
|
||||
pMe->iError = BADECHO;
|
||||
return BADECHO;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SLSError(pEVDriver self, int *iCode, char *error, int iErrLen)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
char *pPtr = NULL;
|
||||
int i1, i2;
|
||||
char pBueffel[132];
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv)self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
*iCode = pMe->iError;
|
||||
switch(*iCode)
|
||||
{
|
||||
case BADECHO:
|
||||
strncpy(error,"message sent and reply did not match", iErrLen);
|
||||
break;
|
||||
case NOTCONNECTED:
|
||||
strncpy(error,"Not connected to device", iErrLen);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
strncpy(error,"Timeout waiting for response", iErrLen);
|
||||
break;
|
||||
default:
|
||||
getRS232Error(*iCode,error,iErrLen);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int SLSSend(pEVDriver self, char *pCommand, char *pReply, int iLen)
|
||||
{
|
||||
strncpy(pReply,"PSI-DSP understands only binary, send disabled",iLen);
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SLSInit(pEVDriver self)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
int iRet, ival, i;
|
||||
char msg[6], reply[6];
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv )self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
pMe->pSock = NULL;
|
||||
pMe->pSock = NETConnect(pMe->pHost,pMe->iPort);
|
||||
if(!pMe->pSock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
/*
|
||||
try to switch device on
|
||||
*/
|
||||
msg[0] = DSPWRITE;
|
||||
msg[1] = 0x31;
|
||||
ival = 1;
|
||||
memcpy(msg+2, &ival,4);
|
||||
iRet = communicateSLS(pMe->pSock,msg,reply);
|
||||
if(iRet <= 0)
|
||||
{
|
||||
pMe->iError = iRet;
|
||||
return iRet;
|
||||
}
|
||||
for(i = 1; i < 6; i++)
|
||||
{
|
||||
if(msg[i] != reply[i])
|
||||
{
|
||||
pMe->iError = BADECHO;
|
||||
return BADECHO;
|
||||
}
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SLSClose(pEVDriver self)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
int iRet;
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv )self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
NETClosePort(pMe->pSock);
|
||||
pMe->pSock = NULL;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SLSFix(pEVDriver self, int iError)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
int iRet;
|
||||
|
||||
assert(self);
|
||||
pMe = (pSLSDriv )self->pPrivate;
|
||||
assert(pMe);
|
||||
|
||||
switch(iError)
|
||||
{
|
||||
case BADECHO:
|
||||
case TIMEOUT:
|
||||
return DEVREDO;
|
||||
default:
|
||||
SLSClose(self);
|
||||
iRet = SLSInit(self);
|
||||
if(iRet)
|
||||
{
|
||||
return DEVREDO;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DEVFAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SLSHalt(pEVDriver *self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
void KillSLS(void *pData)
|
||||
{
|
||||
pSLSDriv pMe = NULL;
|
||||
|
||||
pMe = (pSLSDriv)pData;
|
||||
assert(pMe);
|
||||
|
||||
if(pMe->pHost)
|
||||
{
|
||||
free(pMe->pHost);
|
||||
}
|
||||
free(pMe);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pEVDriver CreateSLSDriv(int argc, char *argv[])
|
||||
{
|
||||
pEVDriver pNew = NULL;
|
||||
pSLSDriv pSim = NULL;
|
||||
|
||||
/* check for arguments */
|
||||
if(argc < 2)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pNew = CreateEVDriver(argc,argv);
|
||||
pSim = (pSLSDriv)malloc(sizeof(SLSDriv));
|
||||
memset(pSim,0,sizeof(SLSDriv));
|
||||
if(!pNew || !pSim)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
pNew->pPrivate = pSim;
|
||||
pNew->KillPrivate = KillSLS;
|
||||
|
||||
pSim->pHost = strdup(argv[0]);
|
||||
pSim->iPort = atoi(argv[1]);
|
||||
|
||||
/* initialise function pointers */
|
||||
pNew->SetValue = SLSRun;
|
||||
pNew->GetValue = GetSLSPos;
|
||||
pNew->Send = SLSSend;
|
||||
pNew->GetError = SLSError;
|
||||
pNew->TryFixIt = SLSFix;
|
||||
pNew->Init = SLSInit;
|
||||
pNew->Close = SLSClose;
|
||||
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user