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:
@@ -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
|
||||
|
||||
228
site_ansto/hardsup/sct_newportprot.c
Normal file
228
site_ansto/hardsup/sct_newportprot.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user