From b526c0541a8c96362633ab61344bae3e19f0a423 Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 4 Nov 2013 12:55:16 +0000 Subject: [PATCH] - 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 --- make_gen | 2 +- polterwrite.c | 1 + psi.c | 1 + sputterprot.c | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 sputterprot.c diff --git a/make_gen b/make_gen index cc6a561..cd16266 100644 --- a/make_gen +++ b/make_gen @@ -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 \ pmacprot.o pfeifferprot.o termprot.o phytron.o autowin.o eigera2.o \ tclClock.o tclDate.o tclUnixTime.o jvlprot.o epicscounter.o \ - eigermono.o + eigermono.o sputterprot.o .SECONDARY.: sanslirebin.c diff --git a/polterwrite.c b/polterwrite.c index 0c79db5..c4aebd1 100644 --- a/polterwrite.c +++ b/polterwrite.c @@ -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, "dety0", "y0_det"); SNXSPutVariable(pServ->pSics, pCon, hfil, hdict, "theta", "twotheta"); + SNXSPutDrivable(pServ->pSics, pCon, hfil, hdict, "cnhepress","he_pressure"); /* write Histogram */ diff --git a/psi.c b/psi.c index 55018b5..d095f06 100644 --- a/psi.c +++ b/psi.c @@ -73,6 +73,7 @@ void SiteInit(void) INIT(AddSeaClientProtocol); INIT(AddDumProtocol); INIT(AddJVLProtocoll); + INIT(AddSputterProtocoll); } diff --git a/sputterprot.c b/sputterprot.c new file mode 100644 index 0000000..b725335 --- /dev/null +++ b/sputterprot.c @@ -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 +#include +#include + +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); +}