From 6b18de0a0364554d220c28ebe6d32d9d0f417a6e Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Mon, 23 Jun 2014 12:47:33 +1000 Subject: [PATCH] Add huber asyncprotocol and make huber_ap and omron_ap to remove name conflicts --- site_ansto/hardsup/huber_asyncprotocol.c | 117 ++++++++++++++++++ site_ansto/hardsup/huber_asyncprotocol.h | 4 + site_ansto/hardsup/makefile | 1 + site_ansto/hardsup/omron_asyncprotocol.c | 8 +- .../config/environment/huber_pilot.sct | 16 +-- .../config/environment/sct_huber_pilot.tcl | 16 +-- site_ansto/site_ansto.c | 3 +- 7 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 site_ansto/hardsup/huber_asyncprotocol.c create mode 100644 site_ansto/hardsup/huber_asyncprotocol.h diff --git a/site_ansto/hardsup/huber_asyncprotocol.c b/site_ansto/hardsup/huber_asyncprotocol.c new file mode 100644 index 00000000..5684673b --- /dev/null +++ b/site_ansto/hardsup/huber_asyncprotocol.c @@ -0,0 +1,117 @@ +#include "sics.h" +#include "asyncprotocol.h" +#include "asyncqueue.h" + +#define LBRACE '{' +#define CR '\r' +#define LF '\n' + +/* + * Protocol transmit function + * Called by AsyncQueue to transmit a line + */ +static int HUBER_Tx(pAsyncProtocol p, pAsyncTxn myCmd) { + int iRet = 1; + + if (myCmd) { + myCmd->txn_status = ATX_ACTIVE; + iRet = AsyncUnitWrite(myCmd->unit, myCmd->out_buf, myCmd->out_len); + /* TODO handle errors */ + if (iRet < 0) { /* TODO: EOF */ + /* + iRet = AsyncUnitReconnect(myCmd->unit); + if (iRet == 0) + */ + return 0; + } + } + return 1; +} + +/* + * Protocol receive character - characater by character + */ +static int HUBER_Rx(pAsyncProtocol p, pAsyncTxn ctx, int rxchar) { + int iRet = 1; + pAsyncTxn myCmd = (pAsyncTxn) ctx; + + switch (myCmd->txn_state) { + case 0: /* first character */ + if (rxchar != LBRACE) { + /* TODO: error */ + myCmd->txn_state = 99; + myCmd->txn_status = ATX_COMPLETE; + break; + } + /* normal data */ + myCmd->txn_state = 1; + /* note fallthrough */ + case 1: /* receiving reply */ + if (myCmd->inp_idx < myCmd->inp_len) + myCmd->inp_buf[myCmd->inp_idx++] = rxchar; + if (rxchar == CR) + myCmd->txn_state = 2; + break; + case 2: /* receiving LF */ + if (myCmd->inp_idx < myCmd->inp_len) + myCmd->inp_buf[myCmd->inp_idx++] = rxchar; + if (rxchar != LF) { + /* TODO: error */ + } + myCmd->txn_state = 99; + myCmd->inp_idx -= 3; + memmove(myCmd->inp_buf, myCmd->inp_buf + 1, myCmd->inp_idx); + break; + } + if (myCmd->txn_state == 99) { + iRet = 0; + } + if (iRet == 0) { /* end of command */ + return AQU_POP_CMD; + } + return iRet; +} + +/* + * AsyncProtocol Event callback + */ +static int HUBER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) { + if (event == AQU_TIMEOUT) { + /* handle command timeout */ + pTxn->txn_status = ATX_TIMEOUT; + return AQU_POP_CMD; + } + return AQU_POP_CMD; +} + +static int HUBER_PrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) { + int i, bcc; + txn->out_buf = (char*) malloc(cmd_len + 3); + if (txn->out_buf == NULL) { + SICSLogWrite("ERROR: Out of memory in HUBER_PrepareTxn", eError); + return 0; + } + memcpy(txn->out_buf + 1, cmd, cmd_len); + txn->out_buf[0] = LBRACE; + txn->out_buf[cmd_len + 1] = CR; + txn->out_buf[cmd_len + 2] = LF; + txn->out_len = cmd_len + 3; + return 1; +} + +static pAsyncProtocol HUBER_Protocol = NULL; + +/* + * Protocol Initialisation + */ +void HUBERInitProtocol(SicsInterp *pSics) { + if (HUBER_Protocol == NULL) { + HUBER_Protocol = AsyncProtocolCreate(pSics, "HUBER_AP", NULL, NULL); + HUBER_Protocol->sendCommand = HUBER_Tx; + HUBER_Protocol->handleInput = HUBER_Rx; + HUBER_Protocol->handleEvent = HUBER_Ev; + HUBER_Protocol->prepareTxn = HUBER_PrepareTxn; + HUBER_Protocol->killPrivate = NULL; + } +} + diff --git a/site_ansto/hardsup/huber_asyncprotocol.h b/site_ansto/hardsup/huber_asyncprotocol.h new file mode 100644 index 00000000..6a3400a5 --- /dev/null +++ b/site_ansto/hardsup/huber_asyncprotocol.h @@ -0,0 +1,4 @@ +#ifndef HUBER_ASYNCPROTOCOL_H +#define HUBER_ASYNCPROTOCOL_H +void HUBERInitProtocol(SicsInterp *pSics); +#endif diff --git a/site_ansto/hardsup/makefile b/site_ansto/hardsup/makefile index 312c73a4..b7196508 100644 --- a/site_ansto/hardsup/makefile +++ b/site_ansto/hardsup/makefile @@ -36,6 +36,7 @@ HOBJ += cameradriver.o HOBJ += sct_asyncqueue.o HOBJ += aqp_opalstatus.o HOBJ += omron_asyncprotocol.o +HOBJ += huber_asyncprotocol.o libhlib.a: $(HOBJ) rm -f libhlib.a diff --git a/site_ansto/hardsup/omron_asyncprotocol.c b/site_ansto/hardsup/omron_asyncprotocol.c index dfea149e..c8c70be8 100644 --- a/site_ansto/hardsup/omron_asyncprotocol.c +++ b/site_ansto/hardsup/omron_asyncprotocol.c @@ -1,6 +1,6 @@ -#include -#include -#include +#include "sics.h" +#include "asyncprotocol.h" +#include "asyncqueue.h" #define STX 2 #define ETX 3 @@ -131,7 +131,7 @@ static pAsyncProtocol OMRON_Protocol = NULL; */ void OMRONInitProtocol(SicsInterp *pSics) { if (OMRON_Protocol == NULL) { - OMRON_Protocol = AsyncProtocolCreate(pSics, "OMRON", NULL, NULL); + OMRON_Protocol = AsyncProtocolCreate(pSics, "OMRON_AP", NULL, NULL); OMRON_Protocol->sendCommand = OMRON_Tx; OMRON_Protocol->handleInput = OMRON_Rx; OMRON_Protocol->handleEvent = OMRON_Ev; diff --git a/site_ansto/instrument/config/environment/huber_pilot.sct b/site_ansto/instrument/config/environment/huber_pilot.sct index bab1921c..b2cb92bc 100644 --- a/site_ansto/instrument/config/environment/huber_pilot.sct +++ b/site_ansto/instrument/config/environment/huber_pilot.sct @@ -53,16 +53,16 @@ driver huber_pilot = { } code getValue = {%% - set cmd "\{M${cmd_str}****" + set cmd "M${cmd_str}****" %%} code rdStatus = {%% - if {[string length ${data}] < 8} { + if {[string length ${data}] < 7} { sct geterror "rdValue short response ${data}" - } elseif { ![string equal -nocase [string range ${data} 1 1] "S"] } { + } elseif { ![string equal -nocase [string range ${data} 0 0] "S"] } { sct geterror "rdValue syntax error ${data}" } else { - set resp [scan [string range ${data} 4 end] "%x" val] + set resp [scan [string range ${data} 3 end] "%x" val] if { ${resp} < 1 } { sct geterror "rdValue scan error ${data}" } else { @@ -72,12 +72,12 @@ driver huber_pilot = { %%} code rdTemp = {%% - if {[string length ${data}] < 8} { + if {[string length ${data}] < 7} { sct geterror "rdValue short response ${data}" - } elseif { ![string equal -nocase [string range ${data} 1 1] "S"] } { + } elseif { ![string equal -nocase [string range ${data} 0 0] "S"] } { sct geterror "rdValue syntax error ${data}" } else { - set resp [scan [string range ${data} 4 end] "%x" val] + set resp [scan [string range ${data} 3 end] "%x" val] if { ${resp} < 1 } { sct geterror "rdValue scan error ${data}" } else { @@ -95,7 +95,7 @@ driver huber_pilot = { code setValue = {%% set param [expr { round(100.0 * [sct target]) }] set param [string range [format "%04X" ${param}] end-3 end] - set cmd "\{M${cmd_str}${param}" + set cmd "M${cmd_str}${param}" %%} } diff --git a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl index 8e44d203..3065ea50 100644 --- a/site_ansto/instrument/config/environment/sct_huber_pilot.tcl +++ b/site_ansto/instrument/config/environment/sct_huber_pilot.tcl @@ -126,7 +126,7 @@ proc ::scobj::huber_pilot::getValue {tc_root nextState cmd_str} { } set cmd "${cmd_str}" # getValue hook code starts - set cmd "\{M${cmd_str}****" + set cmd "M${cmd_str}****" # getValue hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" @@ -178,12 +178,12 @@ proc ::scobj::huber_pilot::rdStatus {tc_root} { error "[sct geterror]" } # rdStatus hook code starts - if {[string length ${data}] < 8} { + if {[string length ${data}] < 7} { sct geterror "rdValue short response ${data}" - } elseif { ![string equal -nocase [string range ${data} 1 1] "S"] } { + } elseif { ![string equal -nocase [string range ${data} 0 0] "S"] } { sct geterror "rdValue syntax error ${data}" } else { - set resp [scan [string range ${data} 4 end] "%x" val] + set resp [scan [string range ${data} 3 end] "%x" val] if { ${resp} < 1 } { sct geterror "rdValue scan error ${data}" } else { @@ -221,12 +221,12 @@ proc ::scobj::huber_pilot::rdTemp {tc_root} { error "[sct geterror]" } # rdTemp hook code starts - if {[string length ${data}] < 8} { + if {[string length ${data}] < 7} { sct geterror "rdValue short response ${data}" - } elseif { ![string equal -nocase [string range ${data} 1 1] "S"] } { + } elseif { ![string equal -nocase [string range ${data} 0 0] "S"] } { sct geterror "rdValue syntax error ${data}" } else { - set resp [scan [string range ${data} 4 end] "%x" val] + set resp [scan [string range ${data} 3 end] "%x" val] if { ${resp} < 1 } { sct geterror "rdValue scan error ${data}" } else { @@ -267,7 +267,7 @@ proc ::scobj::huber_pilot::setValue {tc_root nextState cmd_str} { # setValue hook code starts set param [expr { round(100.0 * [sct target]) }] set param [string range [format "%04X" ${param}] end-3 end] - set cmd "\{M${cmd_str}${param}" + set cmd "M${cmd_str}${param}" # setValue hook code ends if { [hpropexists [sct] geterror] } { debug_log ${tc_root} 9 "[sct] error: [sct geterror]" diff --git a/site_ansto/site_ansto.c b/site_ansto/site_ansto.c index d7c21f34..ec04c1b7 100644 --- a/site_ansto/site_ansto.c +++ b/site_ansto/site_ansto.c @@ -59,6 +59,7 @@ #include "cameradriver.h" #include "aqp_opalstatus.h" #include "omron_asyncprotocol.h" +#include "huber_asyncprotocol.h" /*@observer@*//*@null@*/ pCounterDriver CreateMonCounter(/*@observer@*/SConnection *pCon, /*@observer@*/char *name, char *params); @@ -75,7 +76,6 @@ extern void AddRFAmpProtocol(); extern void AddTCPMBProtocol (); extern void AddLFGenProtocol(); extern void AddSCAQAProtocol(); -extern void OMRONInitProtocol(pInter); extern int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); extern int testLogCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); extern pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq); @@ -356,6 +356,7 @@ static void AddCommands(SicsInterp *pInter) CameraInitProtocol(pInter); OpalStatusInitProtocol(pInter); OMRONInitProtocol(pInter); + HUBERInitProtocol(pInter); AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL); AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL); AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);