- Added a protocol driver for the munich sputter machine

- Added a multicountsersec to teplace hmcontrol and multicounter
- Fixed a case sensitivity bug in haddcheck
- Made oscillate work with second generation motors for POLDI
- Added a time stamper to trace. Now there will be time stamps in trace files which allow
  to correlate things from the master log with the trace.
- Updated polterwrite.
- Updated testprot to work with the behave test
This commit is contained in:
koennecke
2013-11-04 12:55:16 +00:00
parent f0872ae16b
commit b526c0541a
4 changed files with 184 additions and 1 deletions

View File

@ -25,7 +25,7 @@ OBJ=psi.o buffer.o ruli.o sps.o pimotor.o charbychar.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 \
pmacprot.o pfeifferprot.o termprot.o phytron.o autowin.o eigera2.o \ pmacprot.o pfeifferprot.o termprot.o phytron.o autowin.o eigera2.o \
tclClock.o tclDate.o tclUnixTime.o jvlprot.o epicscounter.o \ tclClock.o tclDate.o tclUnixTime.o jvlprot.o epicscounter.o \
eigermono.o eigermono.o sputterprot.o
.SECONDARY.: sanslirebin.c .SECONDARY.: sanslirebin.c

View File

@ -432,6 +432,7 @@ static void PoldiStart(pPolterdi self, SConnection * pCon)
SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "detx0", "x0_det"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "detx0", "x0_det");
SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "dety0", "y0_det"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "dety0", "y0_det");
SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "theta", "twotheta"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "theta", "twotheta");
SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "cnhepress","he_pressure");
/* /*
write Histogram write Histogram
*/ */

1
psi.c
View File

@ -73,6 +73,7 @@ void SiteInit(void)
INIT(AddSeaClientProtocol); INIT(AddSeaClientProtocol);
INIT(AddDumProtocol); INIT(AddDumProtocol);
INIT(AddJVLProtocoll); INIT(AddJVLProtocoll);
INIT(AddSputterProtocoll);
} }

181
sputterprot.c Normal file
View File

@ -0,0 +1,181 @@
/**
* This is a protocol handler for the Munich sputter system. The protocol
* is described in a separate manual. Messages to send look like this:
*
* 2 character length of message + command=value or ? + checksum
*
* Responses come like this:
*
* 2 characters length + status = transmission code + checksum
* 2 character length + 2 characters command status + command=value + checksum
*
* An additional feauture is that the Labview server closes the connection after
* each communication.........
*
* I am lazy: rather then creating a private data structure I use the line count
* to keep track of the 2 messages expected as reply. The linecount also signals
* reconnect with a value of -10
*
* Mark Koennecke, October 2013
*/
#include <errno.h>
#include <ascon.h>
#include <ascon.i>
static int mustReadMore(Ascon *a)
{
int len;
char lenString[3], *cmd;
if(GetDynStringLength(a->rdBuffer) < 2){
return 1;
}
cmd = GetCharArray(a->rdBuffer);
memset(lenString,0,sizeof(lenString));
lenString[0] = cmd[0];
lenString[1] = cmd[1];
len = atoi(lenString);
if(GetDynStringLength(a->rdBuffer) < len + 2){ /* length + checksum */
return 1;
}
return 0;
}
/*-------------------------------------------------------------------------------*/
static void processStatusLine(Ascon *a)
{
char *cmd, *pPtr;
int status;
cmd = GetCharArray(a->rdBuffer);
if(strstr(cmd,"status") == NULL){
AsconError(a,"wrong reply",0);
return;
}
pPtr = strchr(cmd,'=');
pPtr++;
pPtr[3] = '\0';
status = atoi(pPtr);
if(status != 10) {
AsconError(a,"bad transmission status",status);
}
DynStringClear(a->rdBuffer);
a->lineCount++;
}
/*-------------------------------------------------------------------------------*/
static void processPayLoad(Ascon *a)
{
char *cmd, code[3];
int status, len;
cmd = strdup(GetCharArray(a->rdBuffer));
memset(code,0,sizeof(code));
code[0] = cmd[2];
code[1] = cmd[3];
status = atoi(code);
switch(status){
case 30:
len = strlen(cmd);
cmd[len-2] = '\0';
DynStringClear(a->rdBuffer);
DynStringConcat(a->rdBuffer,cmd+4);
break;
case 35:
DynStringClear(a->rdBuffer);
DynStringConcat(a->rdBuffer,"ERROR: Command unknown");
break;
case 36:
DynStringClear(a->rdBuffer);
DynStringConcat(a->rdBuffer,"ERROR: Syntax error");
break;
case 37:
DynStringClear(a->rdBuffer);
DynStringConcat(a->rdBuffer,"ERROR: out of range");
break;
}
free(cmd);
a->state = AsconReadDone;
a->lineCount = -10;
}
/*-------------------------------------------------------------------------------*/
static int SputterHandler(Ascon *a)
{
char *cmd, lenString[3], chr;
int len, checksum, i, ret;
switch(a->state){
case AsconWriteStart:
/*
reconnect when something had been done
*/
if(a->lineCount == -10){
AsconReconnect(a,NULL);
a->lineCount = 0;
return 1;
}
/*
Prepend length and append checksum
*/
cmd = strdup(GetCharArray(a->wrBuffer));
len = strlen(cmd) + 2;
DynStringClear(a->wrBuffer);
sprintf(lenString,"%02d",len);
DynStringConcat(a->wrBuffer,lenString);
DynStringConcat(a->wrBuffer,cmd);
free(cmd);
cmd = GetCharArray(a->wrBuffer);
for(i = 0, checksum = 0; i < strlen(cmd); i++){
checksum += (int)cmd[i];
}
checksum = checksum % 256;
sprintf(lenString,"%2X",checksum);
if(lenString[0] == ' ') {
lenString[0] = '0';
}
DynStringConcat(a->wrBuffer,lenString);
a->state = AsconWriting;
a->lineCount = 0;
a->wrPos = 0;
DynStringClear(a->rdBuffer);
break;
case AsconReading:
if(mustReadMore(a)){
ret = AsconReadChar(a->fd, &chr);
if (ret < 0) {
/* EINTR means we must retry */
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "AsconReadChar failed:", errno);
}
} else if (ret > 0) {
DynStringConcatChar(a->rdBuffer,chr);
}
} else {
if(a->lineCount == 0) {
processStatusLine(a);
} else {
processPayLoad(a);
}
}
break;
default:
return AsconStdHandler(a);
}
return 1;
}
/*----------------------------------------------------------------------------*/
static int SputterInit(Ascon *a, SConnection *con, int argc, char *argv[])
{
a->hostport = strdup(argv[1]);
a->timeout = 3*60;
return 1;
}
/*-----------------------------------------------------------------------------*/
void AddSputterProtocoll()
{
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("sputter");
prot->init = SputterInit;
prot->handler = SputterHandler;
AsconInsertProtocol(prot);
}