- Extended sicshdbadapter to attach a node to the target of any
drivable. Required a new event in devexec.c - Fixed the phytron driver to handle speed well - Added a protocol driver for the TCP/IP bridge to the SLS magnets
This commit is contained in:
4
make_gen
4
make_gen
@ -10,7 +10,7 @@
|
|||||||
tjxp $*.tc $*.c
|
tjxp $*.tc $*.c
|
||||||
|
|
||||||
OBJ=psi.o buffer.o ruli.o sps.o pimotor.o \
|
OBJ=psi.o buffer.o ruli.o sps.o pimotor.o \
|
||||||
pipiezo.o sanswave.o faverage.o \
|
pipiezo.o sanswave.o faverage.o fetchwrite.o\
|
||||||
amorstat.o tasinit.o ptasdrive.o tasutil.o tasscan.o swmotor.o \
|
amorstat.o tasinit.o ptasdrive.o tasutil.o tasscan.o swmotor.o \
|
||||||
polterwrite.o ecb.o frame.o el734driv.o el734dc.o ecbdriv.o \
|
polterwrite.o ecb.o frame.o el734driv.o el734dc.o ecbdriv.o \
|
||||||
ecbcounter.o el737driv.o sinqhmdriv.o tdchm.o velodorn.o \
|
ecbcounter.o el737driv.o sinqhmdriv.o tdchm.o velodorn.o \
|
||||||
@ -19,7 +19,7 @@ OBJ=psi.o buffer.o ruli.o sps.o pimotor.o \
|
|||||||
el755driv.o serial.o scontroller.o t_update.o \
|
el755driv.o serial.o scontroller.o t_update.o \
|
||||||
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \
|
||||||
el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \
|
el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \
|
||||||
$(MZOBJ) amordrive.o amorset.o sinqhttp.o\
|
$(MZOBJ) amordrive.o amorset.o sinqhttp.o slsecho.o\
|
||||||
dgrambroadcast.o sinq.o tabledrive.o julcho.o \
|
dgrambroadcast.o sinq.o tabledrive.o julcho.o \
|
||||||
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
|
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
|
||||||
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \
|
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \
|
||||||
|
@ -65,7 +65,7 @@ static int PhytronHandler(Ascon * a)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return AsconStdHandler(a);
|
return AsconStdHandler(a);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
3
psi.c
3
psi.c
@ -20,8 +20,8 @@
|
|||||||
Markus Zolliker, Jan 2010
|
Markus Zolliker, Jan 2010
|
||||||
-----------------------------------------------------------------------*/
|
-----------------------------------------------------------------------*/
|
||||||
#include <tcl.h>
|
#include <tcl.h>
|
||||||
#include "site.h"
|
|
||||||
#include "sics.h"
|
#include "sics.h"
|
||||||
|
#include "site.h"
|
||||||
#include <motor.h>
|
#include <motor.h>
|
||||||
#include <site.h>
|
#include <site.h>
|
||||||
#include "ecbdriv.h"
|
#include "ecbdriv.h"
|
||||||
@ -69,6 +69,7 @@ void SiteInit(void)
|
|||||||
INIT(AddPfeifferProtocoll);
|
INIT(AddPfeifferProtocoll);
|
||||||
INIT(AddTermProtocoll);
|
INIT(AddTermProtocoll);
|
||||||
INIT(AddPhytronProtocoll);
|
INIT(AddPhytronProtocoll);
|
||||||
|
INIT(AddSLSEchoProtocoll);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
288
slsecho.c
Normal file
288
slsecho.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* slsecho.c
|
||||||
|
* This is a protocol adapter for yet another driver for the
|
||||||
|
* SLS DPC magnet controller. This one is for the shiny, silvery
|
||||||
|
* little box with TCP/IP, 8 fibre optic magnet couplers and
|
||||||
|
* two wires for power. The current assumption is that this
|
||||||
|
* device communicates with 64 byte message going back and forth,
|
||||||
|
* 8 bytes for each channel. Where the first two seem to be unused
|
||||||
|
* and the last 6 being the DSP codes as described elsewhere.
|
||||||
|
*
|
||||||
|
* The expected input for this is:
|
||||||
|
*
|
||||||
|
* channel:mode:code:val:convertflag
|
||||||
|
*
|
||||||
|
* with mode being either r or w and convertflag being one of
|
||||||
|
* none,read,write
|
||||||
|
*
|
||||||
|
* Created on: Mar 18, 2010
|
||||||
|
* Author: Mark Koennecke
|
||||||
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ascon.h>
|
||||||
|
#include <ascon.i>
|
||||||
|
#include <stptok.h>
|
||||||
|
|
||||||
|
#define NONE 0
|
||||||
|
#define READ 1
|
||||||
|
#define WRITE 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char sendbuf[64];
|
||||||
|
char readbuf[64];
|
||||||
|
int convertflag; /* which conversions need to be done */
|
||||||
|
int channel; /* magnet channel number, starting at 0 */
|
||||||
|
} SLSEcho, *pSLSEcho;
|
||||||
|
|
||||||
|
/*
|
||||||
|
packet header codes
|
||||||
|
*/
|
||||||
|
#define DSPWRITE 0x80
|
||||||
|
#define DSPREAD 0x0
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
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 EchoPack(Ascon *a)
|
||||||
|
{
|
||||||
|
pSLSEcho echo = NULL;
|
||||||
|
char *pMessage = NULL, *pPtr = NULL;
|
||||||
|
char token[20], parseString[255];
|
||||||
|
int code, val;
|
||||||
|
double dval;
|
||||||
|
|
||||||
|
echo = a->private;
|
||||||
|
assert(echo != NULL);
|
||||||
|
|
||||||
|
memset(echo->sendbuf,0,sizeof(echo->sendbuf));
|
||||||
|
memset(echo->readbuf,0,sizeof(echo->readbuf));
|
||||||
|
|
||||||
|
assert(GetDynStringLength(a->wrBuffer) < 255);
|
||||||
|
memset(parseString,0,sizeof(parseString));
|
||||||
|
strcpy(parseString,GetCharArray(a->wrBuffer));
|
||||||
|
pPtr = parseString;
|
||||||
|
|
||||||
|
/* read num */
|
||||||
|
pPtr = stptok(pPtr,token,sizeof(token),":");
|
||||||
|
echo->channel = atoi(token);
|
||||||
|
pMessage = echo->sendbuf + echo->channel*8;
|
||||||
|
|
||||||
|
/* read mode */
|
||||||
|
pPtr = stptok(pPtr,token,sizeof(token),":");
|
||||||
|
if(token[0] == 'r'){
|
||||||
|
pMessage[2] = DSPREAD;
|
||||||
|
} else if(token[0] == 'w'){
|
||||||
|
pMessage[2] = DSPWRITE;
|
||||||
|
} else {
|
||||||
|
a->state = AsconFailed;
|
||||||
|
DynStringConcat(a->errmsg,"ERROR: bad mode token ");
|
||||||
|
DynStringConcat(a->errmsg,token);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read code */
|
||||||
|
pPtr = stptok(pPtr,token,sizeof(token),":");
|
||||||
|
sscanf(token,"%x", &code);
|
||||||
|
pMessage[3] = code;
|
||||||
|
|
||||||
|
/* read value */
|
||||||
|
pPtr = stptok(pPtr,token,sizeof(token),":");
|
||||||
|
dval = atof(token);
|
||||||
|
val = dval;
|
||||||
|
|
||||||
|
/* read convertflag */
|
||||||
|
pPtr = stptok(pPtr,token,sizeof(token),":");
|
||||||
|
if(strcmp(token,"none") == 0){
|
||||||
|
echo->convertflag = NONE;
|
||||||
|
} else if(strcmp(token,"read") == 0){
|
||||||
|
echo->convertflag = READ;
|
||||||
|
} else if(strcmp(token,"write") == 0){
|
||||||
|
echo->convertflag = WRITE;
|
||||||
|
} else {
|
||||||
|
a->state = AsconFailed;
|
||||||
|
DynStringConcat(a->errmsg,"ERROR: bad convertflag ");
|
||||||
|
DynStringConcat(a->errmsg,token);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(echo->convertflag == WRITE){
|
||||||
|
val = double2DSPfloat(dval);
|
||||||
|
}
|
||||||
|
memcpy(pMessage+4,&val,4);
|
||||||
|
|
||||||
|
/* printf("Sending code: 0x%x, val = %d\n", code, val); */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int EchoUnpack(Ascon *a)
|
||||||
|
{
|
||||||
|
pSLSEcho echo = a->private;
|
||||||
|
char *pMessage = NULL, printbuf[30];
|
||||||
|
int code, val;
|
||||||
|
double dval;
|
||||||
|
|
||||||
|
|
||||||
|
DynStringClear(a->rdBuffer);
|
||||||
|
pMessage = echo->readbuf + echo->channel*8;
|
||||||
|
|
||||||
|
code = pMessage[3];
|
||||||
|
snprintf(printbuf,sizeof(printbuf),"%x", code);
|
||||||
|
DynStringConcat(a->rdBuffer,printbuf);
|
||||||
|
DynStringConcatChar(a->rdBuffer,':');
|
||||||
|
|
||||||
|
memcpy(&val,pMessage+4, 4);
|
||||||
|
dval = (double)val;
|
||||||
|
|
||||||
|
if(echo->convertflag == READ){
|
||||||
|
dval = DSPfloat2double(val);
|
||||||
|
}
|
||||||
|
snprintf(printbuf,sizeof(printbuf),"%f", dval);
|
||||||
|
DynStringConcat(a->rdBuffer,printbuf);
|
||||||
|
/* printf("Reading code: 0x%x, val = %d\n", code, val);*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int SLSEchoHandler(Ascon *a)
|
||||||
|
{
|
||||||
|
pSLSEcho echo = a->private;
|
||||||
|
int written, read;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
assert(echo != NULL);
|
||||||
|
|
||||||
|
switch(a->state){
|
||||||
|
case AsconWriteStart:
|
||||||
|
EchoPack(a);
|
||||||
|
a->wrPos = 0;
|
||||||
|
a->state = AsconWriting;
|
||||||
|
break;
|
||||||
|
case AsconWriting:
|
||||||
|
AsconReadGarbage(a->fd);
|
||||||
|
written = send(a->fd, echo->sendbuf+a->wrPos,64-a->wrPos, 0);
|
||||||
|
if(written > 0){
|
||||||
|
a->wrPos += written;
|
||||||
|
if(a->wrPos >= 64){
|
||||||
|
a->state = AsconWriteDone;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (written == 0) {
|
||||||
|
errno = ECONNRESET;
|
||||||
|
return ASCON_DISCONNECTED;
|
||||||
|
} else {
|
||||||
|
return ASCON_SEND_ERROR;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AsconReadStart:
|
||||||
|
a->start = DoubleTime();
|
||||||
|
a->state = AsconReading;
|
||||||
|
a->wrPos = 0; /* reusing wrPos for character count received*/
|
||||||
|
break;
|
||||||
|
case AsconReading:
|
||||||
|
read = AsconReadChar(a->fd,&c);
|
||||||
|
if (read <= 0) {
|
||||||
|
if (read < 0) {
|
||||||
|
AsconError(a, "ASC5", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (a->timeout > 0) {
|
||||||
|
if (DoubleTime() - a->start > a->timeout) {
|
||||||
|
AsconError(a, "no response", 0);
|
||||||
|
a->state = AsconTimeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
echo->readbuf[a->wrPos] = c;
|
||||||
|
a->wrPos++;
|
||||||
|
if(a->wrPos >= 64){
|
||||||
|
a->state = AsconReadDone;
|
||||||
|
EchoUnpack(a);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return AsconStdHandler(a);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int SLSEchoInit(Ascon * a, SConnection * con, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
a->fd = -1;
|
||||||
|
a->state = AsconConnectStart;
|
||||||
|
a->reconnectInterval = 10;
|
||||||
|
a->hostport = strdup(argv[1]);
|
||||||
|
if (argc > 2) {
|
||||||
|
a->timeout = atof(argv[2]);
|
||||||
|
} else {
|
||||||
|
a->timeout = 2.0; /* sec */
|
||||||
|
}
|
||||||
|
a->private = malloc(sizeof(SLSEcho));
|
||||||
|
if(a->private == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a->killPrivate = free;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
void AddSLSEchoProtocoll()
|
||||||
|
{
|
||||||
|
AsconProtocol *prot = NULL;
|
||||||
|
|
||||||
|
prot = calloc(sizeof(AsconProtocol), 1);
|
||||||
|
prot->name = strdup("slsecho");
|
||||||
|
prot->init = SLSEchoInit;
|
||||||
|
prot->handler = SLSEchoHandler;
|
||||||
|
AsconInsertProtocol(prot);
|
||||||
|
}
|
2
sps.c
2
sps.c
@ -67,7 +67,7 @@ static int init(pSPS self)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
setRS232SendTerminator(rs232,"\r\n");
|
setRS232SendTerminator(rs232,"\r\n");
|
||||||
setRS232ReplyTerminator(rs232,"\n");
|
setRS232ReplyTerminator(rs232,"\r\n");
|
||||||
setRS232Timeout(rs232,10000);
|
setRS232Timeout(rs232,10000);
|
||||||
/* setRS232Debug(rs232,1); */
|
/* setRS232Debug(rs232,1); */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user