Add RVA SC driver and associated Newport protocol

r3081 | dcl | 2011-03-24 14:51:13 +1100 (Thu, 24 Mar 2011) | 1 line
This commit is contained in:
Douglas Clowes
2011-03-24 14:51:13 +11:00
parent c15a4ca1d6
commit 3cf7bfbf50
4 changed files with 1068 additions and 1 deletions

View File

@@ -10,7 +10,26 @@ SRC = .
CC = gcc
CFLAGS = -g -DLINUX $(DFORTIFY) -I$(SRC) -I../.. $(INC_TCL8) -Wall -Wno-unused -Wextra
HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_modbusprot.o sct_oxfordprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o sct_rfamp.o sinqhttpprot.o sct_protek608.o
HOBJ = nhq200util.o
HOBJ += itc4util.o
HOBJ += lh45util.o
HOBJ += lakeshore340util.o
HOBJ += west4100util.o
HOBJ += asynsrv_utility.o
HOBJ += geterrno.o
HOBJ += strjoin.o
HOBJ += chopper.o
HOBJ += modbustcp.o
HOBJ += sct_galilprot.o
HOBJ += sct_modbusprot.o
HOBJ += sct_oxfordprot.o
HOBJ += sct_newportprot.o
HOBJ += sct_orhvpsprot.o
HOBJ += sct_velselprot.o
HOBJ += sct_usbtmcprot.o
HOBJ += sct_rfamp.o
HOBJ += sinqhttpprot.o
HOBJ += sct_protek608.o
libhlib.a: $(HOBJ)
rm -f libhlib.a

View File

@@ -0,0 +1,228 @@
/** @file Newport protocol handler for script-context based controllers.
*
* If you 'send' commands to a oxford controller using this protocol you
* will get one of three possible responses,
* 1. A response
* eg
* 2. An acknowledgement (ie 'OK')
* eg
* sct_rva send "STT03E8"
* OK
* 3. An error message
* eg
* sct_mc2 send "BGG"
* ASCERR: 20 Begin not valid with motor off (during read finished)
*/
#include <ctype.h>
#include <errno.h>
#include <ascon.h>
#include <ascon.i>
#include <dynstring.h>
struct NewportProtocol_t {
unsigned int magic;
Ascon* parent;
double last_line_time;
double last_char_time;
double inter_line_time;
double inter_char_time;
};
typedef struct NewportProtocol_t NewportProtocol;
/** @brief Set line terminator before sending command
*/
int NewportWriteStart(Ascon *a) {
NewportProtocol* private;
double now;
int i, len;
char *text;
private = (NewportProtocol*) a->private;
assert(private->magic == 0xcafef00d);
now = DoubleTime();
if (now < private->last_line_time) {
private->last_line_time = now;
}
private->last_char_time = now;
/*
if (now > private->last_line_time + private->inter_line_time) {
return 1;
}
*/
len = GetDynStringLength(a->wrBuffer);
text = GetCharArray(a->wrBuffer);
if (len < 1 || text[len - 1] != '\r')
DynStringConcat(a->wrBuffer, "\r");
len = GetDynStringLength(a->wrBuffer);
/* if there is only the terminator, do not send it */
if (len <= 1) {
a->state = AsconWriteDone;
return 1;
}
a->wrPos = 0;
a->state = AsconWriting;
text = GetCharArray(a->wrBuffer);
for (i = 0; i < len; ++i)
if (islower(text[i]))
text[i] = toupper(text[i]);
return 1;
}
/** @brief Write the line one character at a time
*/
int NewportWriting(Ascon *a) {
NewportProtocol* private;
int ret;
double now;
private = (NewportProtocol*) a->private;
assert(private->magic == 0xcafef00d);
now = DoubleTime();
if (now < private->last_char_time) {
private->last_char_time = now;
}
if (now < private->last_char_time + private->inter_char_time) {
return 1;
}
if (a->wrPos == 0)
AsconReadGarbage(a->fd);
ret = AsconWriteChars(a->fd, GetCharArray(a->wrBuffer) + a->wrPos, 1);
if (ret < 0) {
AsconError(a, "send failed:", errno);
/*
* Ooops: which state shall we go to after a write fail?
* This seems to retry.
*/
} else {
private->last_char_time = now;
a->wrPos += ret;
if (a->wrPos >= GetDynStringLength(a->wrBuffer)) {
private->last_line_time = now;
a->state = AsconWriteDone;
}
}
return 1;
}
/** @brief Map replies to OK, ASCERR:..., value.
* You can not use the first character to sort replies from a Newport controller
*/
int NewportReading(Ascon *a) {
int ret;
char chr, ch[2];
char* cp = NULL;
ret = AsconReadChar(a->fd, &chr);
while (ret > 0) {
a->start = DoubleTime();
DynStringConcatChar(a->rdBuffer, chr);
ret = AsconReadChar(a->fd, &chr);
}
if (ret < 0) {
AsconError(a, "AsconReadChar failed:", errno);
return 0;
} else {
/* TODO: should always timeout and check for trailing CR */
double now = DoubleTime();
char *text = GetCharArray(a->rdBuffer);
int len = GetDynStringLength(a->rdBuffer);
double timeout;
if (len < 5) {
if (a->timeout > 0.0)
timeout = a->timeout;
else
timeout = 1.0;
} else if (text[len - 1] == '\r') {
timeout = 0.1;
} else {
timeout = 0.1;
}
if ((now - a->start) > timeout) {
if (len < 5) {
a->state = AsconTimeout;
AsconError(a, "read timeout", 0);
} else if (text[len - 1] != '\r') {
AsconError(a, "missing terminator", 0);
} else if (len > 5 && text[len - 6] != '\r') {
AsconError(a, "format error", 0);
} else {
int i;
for (i = 0; i < len - 1; ++i)
if (text[i] == '\r')
text[i] = ' ';
text[len - 1] = '\0';
a->state = AsconReadDone;
}
}
}
return 0;
}
/** @brief Newport protocol handler.
* This handler formats commands (ie adds cr line terminator) and
* sorts replies into standard responses of
* <value>
* OK
* ASCERR:...
*/
int NewportProtHandler(Ascon *a) {
int ret;
switch(a->state){
case AsconWriteStart:
ret = NewportWriteStart(a);
return ret;
break;
case AsconWriting:
ret = NewportWriting(a);
return ret;
break;
case AsconReadStart:
a->start = DoubleTime();
ret = AsconStdHandler(a);
return ret;
break;
case AsconReading:
ret = NewportReading(a);
return ret;
break;
default:
ret = AsconStdHandler(a);
return ret;
break;
}
return 1;
}
void NewportKillPrivate(void *arg) {
NewportProtocol *private = (NewportProtocol *) arg;
assert(private->magic == 0xcafef00d);
assert(private->parent->private == private);
private->magic = 0;
free(arg);
}
int NewportInit(Ascon *a, SConnection *con,
int argc, char *argv[]) {
NewportProtocol *private;
int ret;
ret = AsconStdInit(a, con, argc, argv);
private = calloc(sizeof(NewportProtocol), 1);
a->private = (void *) private;
private->magic = 0xcafef00d;
private->parent = a;
private->inter_line_time = 0.100;
private->inter_char_time = 0.010;
a->killPrivate = NewportKillPrivate;
return ret;
}
void AddNewportProtocoll(){
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("newport");
prot->init = NewportInit;
prot->handler = NewportProtHandler;
AsconInsertProtocol(prot);
}