- 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

130
lmd200.c
View File

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

View File

@ -23,7 +23,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \ dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \ ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \ rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \
pmacprot.o pfeifferprot.o termprot.o pmacprot.o pfeifferprot.o termprot.o phytron.o
.SECONDARY.: sanslirebin.c .SECONDARY.: sanslirebin.c

100
phytron.c Normal file
View File

@ -0,0 +1,100 @@
/**
* This is an asynchronous protocol driver for the protocol of
* the Phytron MCC-2 motor controller.
* The send format is:
* <STX> DATA <ETX>
* the reply format is:
* <STX> NACK | ACK |& REPLY <ETX>
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, June 2009
*/
#include <errno.h>
#include <ascon.h>
#include <ascon.i>
#include <dynstring.h>
#define STX '\2'
#define ETX '\3'
#define NACK '\5'
#define ACK '\6'
/*---------------------------------------------------------------------------*/
static int PhytronHandler(Ascon * a)
{
char *data = NULL;
int ret, l;
char chr;
switch (a->state) {
case AsconWriteStart:
DynStringInsert(a->wrBuffer,"\2",0);
DynStringConcatChar(a->wrBuffer,ETX);
a->state = AsconWriting;
a->wrPos = 0;
break;
case AsconReading:
ret = AsconReadChar(a->fd, &chr);
if (ret < 0) {
/* EINTR means we must retry */
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "AsconReadChar failed:", errno);
}
return 1;
} else if (ret > 0) {
if(chr == STX){
DynStringClear(a->rdBuffer);
} else if (chr == ACK){
DynStringConcat(a->rdBuffer,"ACK");
} else if(chr == NACK){
DynStringConcat(a->rdBuffer,"NACK");
} else if(chr == ETX){
a->state = AsconReadDone;
} else {
DynStringConcatChar(a->rdBuffer,chr);
}
} else if (ret == 0) {
if (a->timeout > 0) {
if (DoubleTime() - a->start > a->timeout) {
AsconError(a, "read timeout", 0);
a->state = AsconTimeout;
}
}
}
break;
default:
return AsconStdHandler(a);
}
return 1;
}
/*------------------------------------------------------------------------*/
static int PhytronInit(Ascon * a, SConnection * con, int argc, char *argv[])
{
a->fd = -1;
a->state = AsconConnectStart;
a->reconnectInterval = 10;
a->hostport = strdup(argv[1]);
if (argc > 2) {
a->timeout = atof(argv[2]);
} else {
a->timeout = 2.0; /* sec */
}
a->killPrivate = free;
return 1;
}
/*------------------------------------------------------------------------*/
void AddPhytronProtocoll()
{
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("phytron");
prot->init = PhytronInit;
prot->handler = PhytronHandler;
AsconInsertProtocol(prot);
}

3
psi.c
View File

@ -85,6 +85,8 @@ extern void AddPMACProtocoll();
extern void AddPfeifferProtocoll(); extern void AddPfeifferProtocoll();
/* from termprot.c */ /* from termprot.c */
extern void AddTermProtocoll(); extern void AddTermProtocoll();
/* from phytron.c */
extern void AddPhytronProtocoll();
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void SiteInit(void) void SiteInit(void)
@ -114,6 +116,7 @@ void SiteInit(void)
AddPMACProtocoll(); AddPMACProtocoll();
AddPfeifferProtocoll(); AddPfeifferProtocoll();
AddTermProtocoll(); AddTermProtocoll();
AddPhytronProtocoll();
} }