- 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

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);
}