- 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:
181
sputterprot.c
Normal file
181
sputterprot.c
Normal 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);
|
||||
}
|
Reference in New Issue
Block a user