- Added protocol from phytron MCCC-2 motor controller

- Modified lmd200.c to reflect new additional values
This commit is contained in:
koennecke
2009-06-30 06:43:59 +00:00
parent 5faf542574
commit cb296cb390
4 changed files with 159 additions and 80 deletions

134
lmd200.c
View File

@ -13,12 +13,14 @@
* copyright: see file COPYRIGHT
*
* Mark Koennecke, October 2007
*
* modifed to use asynnet and to cope with even more data.
* Mark Koennecke, June 2009
*/
#include <sics.h>
#include <sicsobj.h>
#include <sicshipadaba.h>
#include <network.h>
#include <nwatch.h>
#include <asynnet.h>
#include <commandlog.h>
#include <stptok.h>
/*
@ -32,11 +34,9 @@
*/
#define BUFLEN 1024
typedef struct {
int state;
char host[256];
int port;
mkChannel *pSock;
pNWContext watchContext;
int asChannel;
char lineBuffer[BUFLEN];
} LMD200, *pLMD200;
/*----------------------------------------------------------------------------*/
@ -46,16 +46,9 @@ static void killLMD200(void *data)
if (priv == NULL) {
return;
}
if (priv->watchContext != NULL) {
NetWatchRemoveCallback(priv->watchContext);
}
if (priv->pSock != NULL) {
NETClosePort(priv->pSock);
free(priv->pSock);
}
ANETclose(priv->asChannel);
free(priv);
}
/*-------------------------------------------------------------------------*/
static void setAlarm(pSICSOBJ self, char *text)
{
@ -143,72 +136,55 @@ static void interpretLine(pSICSOBJ self, pLMD200 priv)
{
pHdb node = NULL;
switch (priv->state) {
case IDLE:
if (strstr(priv->lineBuffer, "Alarm") != NULL) {
doAlarm(self, priv->lineBuffer);
node = GetHipadabaNode(self->objectNode, "data");
assert(node != NULL);
/*
* TODO: check the message headers against what is now coming out
* of the device.
*/
if (strstr(priv->lineBuffer, "Alarm") != NULL) {
doAlarm(self, priv->lineBuffer);
return;
} else if (strstr(priv->lineBuffer, "Pre") != NULL) {
setAlarm(self, priv->lineBuffer);
} else if (strstr(priv->lineBuffer, "...0") == NULL) {
storeData(self, 0, priv->lineBuffer);
NotifyHipadabaPar(node, NULL);
return;
} else if (strstr(priv->lineBuffer, "Pre") != NULL) {
setAlarm(self, priv->lineBuffer);
} else {
priv->state = WAITDATA1;
setAlarm(self, "I do not feel very alarmed");
return;
}
break;
case WAITDATA1:
if (strstr(priv->lineBuffer, "...0") == NULL) {
/* this data is out of order, recover... */
priv->state = IDLE;
return;
}
storeData(self, 0, priv->lineBuffer);
priv->state = WAITDATA2;
break;
case WAITDATA2:
if (strstr(priv->lineBuffer, "...0") == NULL) {
/* this data is out of order, recover... */
priv->state = IDLE;
return;
}
} else if(strstr(priv->lineBuffer,"..000") == NULL) {
storeData(self, 8, priv->lineBuffer);
priv->state = IDLE;
node = GetHipadabaNode(self->objectNode, "data");
assert(node != NULL);
NotifyHipadabaPar(node, NULL);
break;
}
}
/*---------------------------------------------------------------------------
* This handles the terminator discovery and causes the evaluation of complete
* lines.
* --------------------------------------------------------------------------*/
static int LMD200Callback(void *context, int mode)
/*----------------------------------------------------------------------------*/
static int LMD200Callback(int handle, void *userData)
{
pSICSOBJ self = (pSICSOBJ) context;
pLMD200 priv = NULL;
char buffer[512], *pPtr = NULL, line[132];
assert(self != NULL);
priv = (pLMD200) self->pPrivate;
if (mode == nwatch_read) {
memset(buffer, 0, 512);
memset(line, 0, 132);
NETRead(priv->pSock, buffer, 512, 0);
pPtr = stptok(buffer, line, 132, "\r");
while (pPtr != NULL) {
if (strlen(line) > 3) {
strncpy(priv->lineBuffer, line, BUFLEN);
interpretLine(self, priv);
priv->lineBuffer[0] = '\0';
}
pPtr = stptok(pPtr, line, 132, "\r");
}
}
return 1;
pSICSOBJ self = (pSICSOBJ)userData;
pLMD200 priv = (pLMD200)self->pPrivate;
char *pPtr = NULL, *pEnd = NULL;
int length;
pPtr = ANETreadPtr(priv->asChannel,&length);
pEnd = strchr(pPtr,(int)'\r');
if(pEnd != NULL){
length = pEnd - pPtr;
*pEnd = '\0';
strncpy(priv->lineBuffer,pPtr,BUFLEN);
ANETreadConsume(priv->asChannel,length+1);
interpretLine(self,priv);
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int ClearCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
setAlarm(ccmd,"I do not feel very alarmed...");
SCSendOK(con);
return 1;
}
/*---------------------------------------------------------------------------*/
int MakeLMD200(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@ -228,27 +204,29 @@ int MakeLMD200(SConnection * pCon, SicsInterp * pSics, void *pData,
memset(priv, 0, sizeof(LMD200));
strncpy(priv->host, argv[2], 256);
priv->port = atoi(argv[3]);
priv->pSock = NETConnect(priv->host, priv->port);
if (priv->pSock == NULL) {
priv->asChannel = ANETconnect(priv->host, priv->port);
if (priv->asChannel < 0) {
SCWrite(pCon, "ERROR: failed to connect to LMD200", eError);
killLMD200(priv);
return 0;
}
self = MakeSICSOBJv(argv[1], "LMD400", HIPNONE, 0);
if (self == NULL || priv == NULL) {
return 0;
}
textValue = MakeHdbText("I do not feel very alarmed");
dataValue = makeHdbValue(HIPFLOATAR, 16);
dataValue = makeHdbValue(HIPFLOATAR, 32);
AddSICSHdbPar(self->objectNode, "alarm", usInternal, textValue);
AddSICSHdbPar(self->objectNode, "data", usInternal, dataValue);
self->pPrivate = priv;
self->KillPrivate = killLMD200;
ReleaseHdbValue(&dataValue);
NetWatchRegisterCallback(&priv->watchContext, priv->pSock->sockid,
LMD200Callback, self);
ANETsetReadCallback(priv->asChannel,LMD200Callback,self, NULL);
AddSICSHdbPar(self->objectNode,
"clearalarm", usUser, MakeSICSFunc(ClearCmd));
status = AddCommand(pSics,
argv[1], InterInvokeSICSOBJ, KillSICSOBJ, self);
if (status != 1) {
@ -257,7 +235,5 @@ int MakeLMD200(SConnection * pCon, SicsInterp * pSics, void *pData,
argv[1]);
return 0;
}
return 1;
}