- Fixed sicsprompt bug. Sicsprompt caused a core dump

- Removed generation of incommenurate reflections for 0,0,0 in fourmess.c
- Implemented a Poch command for heartbeats
- Fixed 64 bit dimension issues in nxdict
- Fixed different calling conventions for NXReportError deep stack in nxdict
- Stopped ei motor driving when not necessary
- Added yet another monitor for POLDI
- Added a protocoll driver for the JVL motor RS-485 binary protocoll
- Fixed some reporting issues
This commit is contained in:
koennecke
2012-06-05 09:09:22 +00:00
parent 8de4a72782
commit ee6c52450e
5 changed files with 234 additions and 3 deletions

230
jvlprot.c Normal file
View File

@ -0,0 +1,230 @@
/*
* jvlprot.c
*
* This is a protocol driver for the JVL integrated stepper motors.
* They talk on a RS485 bus, half-duplex, 19220 Baud, 8N1. They use
* a weird binary protocol which is documented in the accompanying
* manual.
*
* Created on: May 7, 2012
* Author: koennecke
*/
#include <errno.h>
#include <time.h>
#include <ascon.h>
#include <ascon.i>
#include <stptok.h>
typedef struct {
unsigned char wrBuffer[30];
unsigned char rdBuffer[30];
int toWrite, toRead;
unsigned char *wrPtr, *rdPtr;
int reading;
time_t start;
}JVL, *pJVL;
/*------------------------------------------------------------*/
static int validResponse(pJVL priv)
{
if(priv->rdPtr - priv->rdBuffer > 3){
if((priv->rdBuffer[0] == 0x52 && priv->rdBuffer[1] == 0x52 && priv->rdBuffer[2] == 0x52) ||
(priv->rdBuffer[0] == 0x11 && priv->rdBuffer[1] == 0x11 && priv->rdBuffer[2] == 0x11) ) {
return 1;
} else {
return 0;
}
} else {
return 1;
}
}
/*------------------------------------------------------------*/
static int JVLHandler(Ascon *a)
{
pJVL priv;
char *data, token[20];
int motNo, address,ret;
union {
unsigned char b[4];
int iVal;
}val;
char chr;
priv = (pJVL)a->private;
switch(a->state){
case AsconWriteStart:
data = GetCharArray(a->wrBuffer);
if(data[0] == 'r'){
data = stptok(data,token,20," ");
data = stptok(data,token,20," ");
motNo = atoi(token);
data = stptok(data,token,20," ");
address = atoi(token);
priv->wrBuffer[0] = 80; /* 0x50 */
priv->wrBuffer[1] = 80;
priv->wrBuffer[2] = 80;
priv->wrBuffer[3] = motNo;
priv->wrBuffer[4] = 255 - motNo;
priv->wrBuffer[5] = address;
priv->wrBuffer[6] = 255-address;
priv->wrBuffer[7] = 170; /* 0xAA */
priv->wrBuffer[8] = 170;
priv->toWrite = 9;
priv->toRead = 19;
priv->rdPtr = priv->rdBuffer;
priv->wrPtr = priv->wrBuffer;
a->state = AsconWriting;
priv->reading = 1;
priv->start = time(NULL);
return 1;
} else if(data[0] == 'w'){
data = stptok(data,token,20," ");
data = stptok(data,token,20," ");
motNo = atoi(token);
data = stptok(data,token,20," ");
address = atoi(token);
data = stptok(data,token,20," ");
val.iVal = atoi(token);
priv->wrBuffer[0] = 82; /* 0x52 */
priv->wrBuffer[1] = 82;
priv->wrBuffer[2] = 82;
priv->wrBuffer[3] = motNo;
priv->wrBuffer[4] = 255 - motNo;
priv->wrBuffer[5] = address;
priv->wrBuffer[6] = 255-address;
priv->wrBuffer[7] = 4; /* len */
priv->wrBuffer[8] = 255 - 4;
/*
* This code may be platform byte order dependent
*/
priv->wrBuffer[9] = val.b[0]; /* data */
priv->wrBuffer[10] = 255 -val.b[0];
priv->wrBuffer[11] = val.b[1];
priv->wrBuffer[12] = 255 -val.b[1];
priv->wrBuffer[13] = val.b[2];
priv->wrBuffer[14] = 255 -val.b[2];
priv->wrBuffer[15] = val.b[3];
priv->wrBuffer[16] = 255 -val.b[3];
priv->wrBuffer[17] = 170; /* 0xAA */
priv->wrBuffer[18] = 170;
priv->wrPtr = priv->wrBuffer;
priv->toWrite = 19;
priv->rdPtr = priv->rdBuffer;
priv->toRead = 3;
a->state = AsconWriting;
priv->reading = 0;
priv->start = time(NULL);
return 1;
} else {
priv->reading = 0;
AsconError(a,"Unknown JVL command", 0);
return 1;
}
break;
case AsconWriting:
AsconReadGarbage(a->fd);
ret = AsconWriteChars(a->fd, (char *)priv->wrPtr, priv->toWrite);
if(*priv->wrPtr != 80){
printf("Hugo\n");
}
if (ret < 0) {
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "send failed:", errno);
}
/*
* Ooops: which state shall we go to after a write fail?
* This seems to retry.
*/
} else {
priv->wrPtr += ret;
priv->toWrite -= ret;
if (priv->toWrite <= 0) {
a->state = AsconWriteDone;
}
return 1;
}
break;
case AsconReadStart:
DynStringClear(a->rdBuffer);
a->state = AsconReading;
return 1;
break;
case AsconReading:
if(!validResponse(priv)){
a->state = AsconWriteStart;
return 1;
}
if(time(NULL) > priv->start + 1){
a->state = AsconReadDone;
DynStringConcat(a->rdBuffer,"timeout");
return 1;
}
ret = AsconReadChar(a->fd, &chr);
if (ret < 0) {
/* EINTR means we must retry */
if (errno != EINTR && errno != EAGAIN) {
AsconError(a, "AsconReadChar failed:", errno);
}
} else if (ret > 0) {
*(priv->rdPtr) = (unsigned char)chr;
priv->toRead--;
priv->rdPtr++;
if(priv->toRead <= 0){
a->state = AsconReadDone;
if(priv->reading){
/* This code may be platform byte order dependent */
val.b[0] = priv->rdBuffer[9];
val.b[1] = priv->rdBuffer[11];
val.b[2] = priv->rdBuffer[13];
val.b[3] = priv->rdBuffer[15];
snprintf(token,20,"%d", val.iVal);
DynStringConcat(a->rdBuffer,token);
} else {
if(priv->rdBuffer[0] == 0x11){
DynStringConcat(a->rdBuffer,"OK");
} else {
DynStringConcat(a->rdBuffer,"Unknown response code from JVL: ");
snprintf(token,20,"%x", priv->rdBuffer[0]);
DynStringConcat(a->rdBuffer, token);
}
}
}
}
return 1;
break;
default:
return AsconBaseHandler(a);
}
return AsconBaseHandler(a);
}
/*------------------------------------------------------------------------*/
static int JVLInit(Ascon * a, SConnection * con, int argc, char *argv[])
{
pJVL priv = NULL;
priv = calloc(sizeof(JVL), 1);
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->private = priv;
a->killPrivate = free;
return 1;
}
/*------------------------------------------------------------------------*/
void AddJVLProtocoll()
{
AsconProtocol *prot = NULL;
prot = calloc(sizeof(AsconProtocol), 1);
prot->name = strdup("jvl");
prot->init = JVLInit;
prot->handler = JVLHandler;
AsconInsertProtocol(prot);
}

View File

@ -24,7 +24,7 @@ OBJ=psi.o buffer.o ruli.o sps.o pimotor.o charbychar.o\
ritastorage.o poldizug.o audinelib.o delcam.o el737hpdrivsps.o \
rebin.o sanslirebin.o lmd200.o slsvme.o julprot.o sinqhttpprot.o \
pmacprot.o pfeifferprot.o termprot.o phytron.o autowin.o eigera2.o \
tclClock.o tclDate.o tclUnixTime.o
tclClock.o tclDate.o tclUnixTime.o jvlprot.o
.SECONDARY.: sanslirebin.c

View File

@ -545,6 +545,8 @@ static void PoldiUpdate(pPolterdi self, SConnection * pCon)
NXDputalias(hfil, hdict, "cntime", &fVal);
lVal = GetMonitor(pCount, 1, pCon);
NXDputalias(hfil, hdict, "cnmon1", &lVal);
lVal = GetMonitor(pCount, 0, pCon);
NXDputalias(hfil, hdict, "cnprot", &lVal);
lVal = GetMonitor(pCount, 2, pCon);
NXDputalias(hfil, hdict, "cnmon2", &lVal);
eMode = GetCounterMode(pCount);

1
psi.c
View File

@ -74,6 +74,7 @@ void SiteInit(void)
INIT(AddCharByCharProtocoll);
INIT(AddBinProtocol);
INIT(AddDumProtocol);
INIT(AddJVLProtocoll);
}

View File

@ -407,11 +407,9 @@ static char *S7InitHandler(void *actionData, char *reply, int comerror)
dblength = ntohs(dblength);
InitializeSPSDataBase(self,self->spsNode);
node = GetHipadabaNode(self->spsNode,"init");
/*
if(node != NULL){
UpdateHipadabaPar(node,MakeHdbInt(1), NULL);
}
*/
return NULL;
}
}