Add protocol support for the Knauer HPLC pump

This commit is contained in:
Douglas Clowes
2014-08-20 13:35:13 +10:00
parent 5fa021ce88
commit f1f9ee2c01
6 changed files with 173 additions and 2 deletions

View File

@ -0,0 +1,148 @@
#include "knauer_asyncprotocol.h"
#include "asyncprotocol.h"
#include "asyncqueue.h"
#define SYN1 0x55
#define SYN2 0xAA
#define CR '\r'
#define LF '\n'
/* Sample Messages
55 aa 00 08 52 45 4d 4f 54 45 3a 30
55 aa 00 16 45 52 52 4f 52 3a 34 38 2c 4e 6f 74 20 73 75 70 70 6f 72 74 65 64
55 aa 00 18 45 52 52 4f 52 3a 31 36 2c 49 6e 76 61 6c 69 64 20 63 6f 6d 6d 61 6e 64
*/
typedef struct knauer_private_t Private, *pPrivate;
struct knauer_private_t {
int len;
};
/*
* Protocol transmit function
* Called by AsyncQueue to transmit a line
*/
static int KNAUER_Tx(pAsyncProtocol p, pAsyncTxn pTxn) {
int iRet = 1;
if (pTxn) {
pTxn->txn_status = ATX_ACTIVE;
iRet = AsyncUnitWrite(pTxn->unit, pTxn->out_buf, pTxn->out_len);
/* TODO handle errors */
if (iRet < 0) { /* TODO: EOF */
/*
iRet = AsyncUnitReconnect(pTxn->unit);
if (iRet == 0)
*/
return 0;
}
}
return 1;
}
/*
* Protocol receive character - characater by character
*/
static int KNAUER_Rx(pAsyncProtocol p, pAsyncTxn pTxn, int rxchar) {
int iRet = 1;
pPrivate myPriv = (pPrivate) pTxn->proto_private;
rxchar &= 0xFF;
switch (pTxn->txn_state) {
case 0: /* first SYN byte */
if (rxchar != SYN1) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
pTxn->txn_state = 1;
break;
case 1: /* second SYN byte */
if (rxchar != SYN2) {
/* TODO: error */
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
break;
}
pTxn->txn_state = 2;
break;
case 2: /* MS length byte */
myPriv->len = 256 * rxchar;
pTxn->txn_state = 3;
break;
case 3: /* LS length byte */
myPriv->len += rxchar;
pTxn->txn_state = 4;
break;
case 4: /* receiving text */
if (pTxn->inp_idx < pTxn->inp_len)
pTxn->inp_buf[pTxn->inp_idx++] = rxchar;
if (pTxn->inp_idx >= myPriv->len) {
pTxn->txn_state = 99;
pTxn->txn_status = ATX_COMPLETE;
}
break;
}
if (pTxn->txn_state == 99) {
iRet = 0;
}
if (iRet == 0) { /* end of command */
free(pTxn->proto_private);
pTxn->proto_private = NULL;
return AQU_POP_CMD;
}
return iRet;
}
/*
* AsyncProtocol Event callback
*/
static int KNAUER_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
free(pTxn->proto_private);
pTxn->proto_private = NULL;
if (event == AQU_TIMEOUT) {
/* handle command timeout */
pTxn->txn_status = ATX_TIMEOUT;
return AQU_POP_CMD;
}
return AQU_POP_CMD;
}
static int KNAUER_PrepareTxn(pAsyncProtocol p, pAsyncTxn pTxn, const char* cmd, int cmd_len, int rsp_len) {
pPrivate myPriv = (pPrivate) malloc(sizeof(Private));
if (myPriv == NULL) {
SICSLogWrite("ERROR: Out of memory in KNAUER_PrepareTxn", eError);
return 0;
}
myPriv->len = 0;
pTxn->out_buf = (char*) malloc(cmd_len + 1);
if (pTxn->out_buf == NULL) {
SICSLogWrite("ERROR: Out of memory in KNAUER_PrepareTxn", eError);
free(myPriv);
return 0;
}
pTxn->proto_private = myPriv;
memcpy(pTxn->out_buf, cmd, cmd_len);
pTxn->out_buf[cmd_len] = CR;
pTxn->out_len = cmd_len + 1;
return 1;
}
static pAsyncProtocol KNAUER_Protocol = NULL;
/*
* Protocol Initialisation
*/
void KNAUERInitProtocol(SicsInterp *pSics) {
if (KNAUER_Protocol == NULL) {
KNAUER_Protocol = AsyncProtocolCreate(pSics, "KNAUER_AP", NULL, NULL);
KNAUER_Protocol->sendCommand = KNAUER_Tx;
KNAUER_Protocol->handleInput = KNAUER_Rx;
KNAUER_Protocol->handleEvent = KNAUER_Ev;
KNAUER_Protocol->prepareTxn = KNAUER_PrepareTxn;
KNAUER_Protocol->killPrivate = NULL;
}
}

View File

@ -0,0 +1,5 @@
#ifndef KNAUER_ASYNCPROTOCOL_H
#define KNAUER_ASYNCPROTOCOL_H
#include "sics.h"
void KNAUERInitProtocol(SicsInterp *pSics);
#endif

View File

@ -0,0 +1,12 @@
#include "loader_asyncprotocol.h"
#include "huber_asyncprotocol.h"
#include "knauer_asyncprotocol.h"
#include "omron_asyncprotocol.h"
#include "sics.h"
void LOADERInitProtocol(SicsInterp *pSics)
{
HUBERInitProtocol(pSics);
KNAUERInitProtocol(pSics);
OMRONInitProtocol(pSics);
}

View File

@ -0,0 +1,5 @@
#ifndef LOADER_ASYNCPROTOCOL_H
#define LOADER_ASYNCPROTOCOL_H
#include "sics.h"
void LOADERInitProtocol(SicsInterp *pSics);
#endif

View File

@ -37,6 +37,8 @@ HOBJ += sct_asyncqueue.o
HOBJ += aqp_opalstatus.o
HOBJ += omron_asyncprotocol.o
HOBJ += huber_asyncprotocol.o
HOBJ += knauer_asyncprotocol.o
HOBJ += loader_asyncprotocol.o
libhlib.a: $(HOBJ)
rm -f libhlib.a

View File

@ -383,8 +383,7 @@ static void AddCommands(SicsInterp *pInter)
LS340InitProtocol(pInter);
CameraInitProtocol(pInter);
OpalStatusInitProtocol(pInter);
OMRONInitProtocol(pInter);
HUBERInitProtocol(pInter);
LOADERInitProtocol(pInter);
AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL);
AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL);
AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);