- New drivers for EL737 and EL734 high performance
- Changes to makefiles
This commit is contained in:
610
dornier2.c
Normal file
610
dornier2.c
Normal file
@ -0,0 +1,610 @@
|
||||
/*------------------------------------------------------------------------
|
||||
|
||||
Another driver for a Dornier velocity selector. This is for a newer
|
||||
version of the velocity selector driver as delivered with SANS-2. It
|
||||
also uses a direct connection to the terminal server without David Maden's
|
||||
SerPortServer program in between.
|
||||
|
||||
I believe this is for Dornier software version: NGS037 of 2002.
|
||||
|
||||
The protocoll is inconsistent: status messages come back with a <cr>,
|
||||
command responses tend to come back with a \ and no <cr>!
|
||||
|
||||
There is a scheme here: while waiting for status reponses during driving,
|
||||
the last status read is used for any requests.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, July 2003
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <sics.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <tcl.h>
|
||||
#include <time.h>
|
||||
#include <fortify.h>
|
||||
#include <rs232controller.h>
|
||||
typedef struct __VelSelDriv *pVelSelDriv;
|
||||
|
||||
#include <velodriv.h>
|
||||
#include "velodorn.h"
|
||||
|
||||
/* VELO* MUST be the same as in velo.i!*/
|
||||
#define VELOREDO 2
|
||||
#define VELOFAIL 0
|
||||
#define VELOOK 1
|
||||
#define VSNOCON 0
|
||||
#define VSOK 1
|
||||
#define VSACCEL -7
|
||||
#define VSFAIL -2
|
||||
|
||||
/*--------- special Dornier conditions*/
|
||||
#define STARTED -88
|
||||
#define HALTREQ -77
|
||||
|
||||
/*---------- DORNIER status modes */
|
||||
#define STATSEND 1
|
||||
#define STATREAD 2
|
||||
/*----------------------------- The private data structure ---------------*/
|
||||
typedef struct{
|
||||
prs232 controller;
|
||||
int iTimeOut;
|
||||
int iLastError;
|
||||
time_t t_End;
|
||||
time_t t_timeout;
|
||||
float fTarget;
|
||||
float fLastRPM;
|
||||
int statusMode;
|
||||
DornierStatus lastStatus;
|
||||
int minRPM; /* the minimum control speed of the thing*/
|
||||
int haltCount;
|
||||
} Dornier, *pDornier;
|
||||
/*------------------------------------------------------------------*/
|
||||
static int requestDornierStatus(pDornier pDorn){
|
||||
int status;
|
||||
|
||||
status = writeRS232(pDorn->controller,"???\n",4);
|
||||
if(status < 0){
|
||||
pDorn->iLastError = status;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int readAndInterpretStatus(pDornier pDorn, DornierStatus *DStatus){
|
||||
int status, datalen;
|
||||
char reply[512];
|
||||
|
||||
datalen = 512;
|
||||
status = readRS232TillTerm(pDorn->controller,reply,&datalen);
|
||||
if(status < 0){
|
||||
pDorn->iLastError = status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DecodeNewDornierStatus(reply,DStatus);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int GetDornierPos(pVelSelDriv self, float *fPos)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
DornierStatus DStatus;
|
||||
int status;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
if(pDorn->statusMode == STATSEND){
|
||||
if(!requestDornierStatus(pDorn)){
|
||||
*fPos = -9999.;
|
||||
return 0;
|
||||
}
|
||||
if(!readAndInterpretStatus(pDorn,&DStatus)){
|
||||
*fPos = -9999.;
|
||||
return 0;
|
||||
}
|
||||
pDorn->lastStatus = DStatus;
|
||||
}
|
||||
*fPos = pDorn->lastStatus.cur_rpm;
|
||||
pDorn->fLastRPM = pDorn->lastStatus.cur_rpm;
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int DornierHalt(pVelSelDriv self)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
int iRet;
|
||||
char pCom[50];
|
||||
char pAnswer[80];
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
snprintf(pCom,49,"SDR %d\n",pDorn->minRPM);
|
||||
iRet = transactRS232(pDorn->controller,pCom,strlen(pCom),
|
||||
pAnswer,79);
|
||||
if(iRet != 1)
|
||||
{
|
||||
pDorn->iLastError = iRet;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int DornierRun(pVelSelDriv self, float fVal)
|
||||
{
|
||||
int iRet;
|
||||
char pCommand[50], pAnswer[50];
|
||||
pDornier pDorn = NULL;
|
||||
int startFlag = 0;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
/*
|
||||
less then minRPM, means halt in this case.
|
||||
Accept this only after three times, see code in GetError as well.
|
||||
*/
|
||||
if(fVal < pDorn->minRPM - self->fTolerance)
|
||||
{
|
||||
if(pDorn->haltCount < 3){
|
||||
pDorn->iLastError = HALTREQ;
|
||||
return 0;
|
||||
}
|
||||
strcpy(pCommand,"HAL\n");
|
||||
} else {
|
||||
if(pDorn->lastStatus.cur_rpm < pDorn->minRPM){
|
||||
strcpy(pCommand,"SST\n");
|
||||
startFlag = 1;
|
||||
pDorn->fTarget = pDorn->minRPM;
|
||||
} else {
|
||||
snprintf(pCommand,49,"SDR %5u\n",(int)nintf(fVal));
|
||||
pDorn->fTarget = fVal;
|
||||
}
|
||||
}
|
||||
|
||||
setRS232ReplyTerminator(pDorn->controller,"\\");
|
||||
iRet = transactRS232(pDorn->controller,pCommand,strlen(pCommand),
|
||||
pAnswer,49);
|
||||
setRS232ReplyTerminator(pDorn->controller,"\r\n");
|
||||
if(iRet != 1)
|
||||
{
|
||||
pDorn->iLastError = iRet;
|
||||
return 0;
|
||||
}
|
||||
pDorn->statusMode = STATSEND;
|
||||
if(startFlag){
|
||||
pDorn->iLastError = STARTED;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int DornierError(pVelSelDriv self, int *iCode,
|
||||
char *error, int iErrLen){
|
||||
pDornier pDorn = NULL;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
*iCode = pDorn->iLastError;
|
||||
|
||||
switch(pDorn->iLastError){
|
||||
case HALTREQ:
|
||||
strncpy(error,"Repeat command if you really want to HALT selector",
|
||||
iErrLen);
|
||||
pDorn->haltCount++;
|
||||
break;
|
||||
case STARTED:
|
||||
strncpy(error,
|
||||
"Started selector, standby and check manually when ready",
|
||||
iErrLen);
|
||||
break;
|
||||
default:
|
||||
getRS232Error(pDorn->iLastError,error,iErrLen);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int DornierFixIt(pVelSelDriv self, int iCode){
|
||||
pDornier pDorn = NULL;
|
||||
int status;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
switch(iCode){
|
||||
case NOTCONNECTED:
|
||||
status = initRS232(pDorn->controller);
|
||||
if(status){
|
||||
return VELOREDO;
|
||||
} else {
|
||||
return VELOFAIL;
|
||||
}
|
||||
break;
|
||||
case TIMEOUT:
|
||||
case INCOMPLETE:
|
||||
return VELOREDO;
|
||||
break;
|
||||
default:
|
||||
return VELOFAIL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int statusSendHandler(pDornier pDorn){
|
||||
int status;
|
||||
|
||||
if(!requestDornierStatus(pDorn)){
|
||||
return VSFAIL;
|
||||
}
|
||||
pDorn->t_timeout = time(NULL) + pDorn->iTimeOut/1000;
|
||||
pDorn->statusMode = STATREAD;
|
||||
return VSACCEL;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int evaluateStatus(pVelSelDriv self, int *iCode){
|
||||
int status;
|
||||
DornierStatus sStatus;
|
||||
char pCommand[80];
|
||||
char pAnswer[80];
|
||||
float fDelta;
|
||||
static int iCount = 0;
|
||||
pDornier pDorn = NULL;
|
||||
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
pDorn->statusMode = STATSEND;
|
||||
status = readAndInterpretStatus(pDorn,&sStatus);
|
||||
if(!status){
|
||||
return VELOFAIL;
|
||||
}
|
||||
|
||||
*iCode = ROTMOVE;
|
||||
/*
|
||||
This code considers the velocity selector arrived if it reads
|
||||
four times a difference between requested spped and actual speed
|
||||
below difference
|
||||
*/
|
||||
pDorn->fLastRPM = sStatus.cur_rpm;
|
||||
fDelta = sStatus.cur_rpm - sStatus.nom_rpm;
|
||||
if(fDelta < 0){
|
||||
fDelta = - fDelta;
|
||||
}
|
||||
if(fDelta > self->fTolerance){
|
||||
iCount = 0;
|
||||
return VSACCEL;
|
||||
} else {
|
||||
iCount++;
|
||||
if(iCount > 4){
|
||||
return VSOK;
|
||||
} else {
|
||||
return VSACCEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int statusReceiveHandler(pVelSelDriv self, int *iCode){
|
||||
int status;
|
||||
pDornier pDorn = NULL;
|
||||
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
status = availableRS232(pDorn->controller);
|
||||
if(!status){
|
||||
if(time(NULL) > pDorn->t_timeout){
|
||||
pDorn->iLastError = TIMEOUT;
|
||||
pDorn->statusMode = STATSEND;
|
||||
return VELOFAIL;
|
||||
} else {
|
||||
return VSACCEL;
|
||||
}
|
||||
}
|
||||
|
||||
return evaluateStatus(self, iCode);
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
The Dornier takes a long time to answer a status message. In order to keep
|
||||
SICS responsive the following state machine is implemented:
|
||||
- a status request is sent.
|
||||
- next data availability will be checked, if available: process!
|
||||
---------------------------------------------------------------------------*/
|
||||
static int DornierStatNew(pVelSelDriv self, int *iCode, float *fCur){
|
||||
pDornier pDorn = NULL;
|
||||
int status;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
if(pDorn->statusMode == STATSEND){
|
||||
return statusSendHandler(pDorn);
|
||||
} else {
|
||||
status = statusReceiveHandler(self,iCode);
|
||||
*fCur = pDorn->fLastRPM;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int DornierText(pVelSelDriv self, char *pText, int iTextLen)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
int iRet, iErrStat;
|
||||
DornierStatus sStatus;
|
||||
char pBueffel[1024];
|
||||
char pHelp[80];
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
/*
|
||||
use cached status while waiting for reply during drive
|
||||
*/
|
||||
if(pDorn->statusMode == STATSEND){
|
||||
if(!requestDornierStatus(pDorn)){
|
||||
return 0;
|
||||
}
|
||||
if(!readAndInterpretStatus(pDorn,&sStatus)){
|
||||
return 0;
|
||||
}
|
||||
pDorn->lastStatus = sStatus;
|
||||
} else {
|
||||
sStatus = pDorn->lastStatus;
|
||||
}
|
||||
|
||||
/* format it to a string */
|
||||
sprintf(pHelp,"RPM: %d , should %d\n",sStatus.cur_rpm,sStatus.nom_rpm);
|
||||
strcpy(pBueffel,pHelp);
|
||||
sprintf(pHelp,"State: %s\n",sStatus.rm);
|
||||
strcat(pBueffel,pHelp);
|
||||
sprintf(pHelp,"Current: %d\n",sStatus.pwr);
|
||||
strcat(pBueffel,pHelp);
|
||||
sprintf(pHelp,"Rotor T: %d, Housing T: %d\n",sStatus.rot_temp,
|
||||
sStatus.cont_temp);
|
||||
strcat(pBueffel,pHelp);
|
||||
sprintf(pHelp,"Cooling: In-T: %d, Out-T: %d, Flow: %f\n",
|
||||
sStatus.inl_temp,sStatus.outl_temp,sStatus.cool_wat);
|
||||
strcat(pBueffel,pHelp);
|
||||
sprintf(pHelp,"Vaccum: %f, Accel: %f",sStatus.vacuum, sStatus.accel);
|
||||
strcat(pBueffel,pHelp);
|
||||
|
||||
strncpy(pText,pBueffel, iTextLen);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int DornierLoss(pVelSelDriv self, float *fLoss)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
int iRet, iErrStat, iDelta;
|
||||
DornierStatus DStatus;
|
||||
char pCommand[] = {"BRE\n"};
|
||||
char pAnswer[80];
|
||||
static int iCount;
|
||||
static int iError;
|
||||
int i;
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
|
||||
/* send a command */
|
||||
iRet = transactRS232(pDorn->controller,pCommand,strlen(pCommand),
|
||||
pAnswer,79);
|
||||
if(iRet != 1)
|
||||
{
|
||||
pDorn->iLastError = iRet;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wait 10 seconds before doing anything */
|
||||
SicsWait(10);
|
||||
|
||||
/* loop until back to speed again */
|
||||
for(i = 0; i < 100; i++ )
|
||||
{
|
||||
if(!requestDornierStatus(pDorn)){
|
||||
return 0;
|
||||
}
|
||||
if(!readAndInterpretStatus(pDorn,&DStatus)){
|
||||
return 0;
|
||||
}
|
||||
iError = 0;
|
||||
iDelta = DStatus.cur_rpm - DStatus.nom_rpm;
|
||||
if(iDelta < 0)
|
||||
{
|
||||
iDelta = -iDelta;
|
||||
}
|
||||
if(iDelta < 15)
|
||||
{
|
||||
iCount++;
|
||||
if(iCount > 4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iCount = 0;
|
||||
}
|
||||
}
|
||||
*fLoss = DStatus.pwr;
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void DornierKill(void *pData)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
char pAns[10];
|
||||
|
||||
pDorn = (pDornier)pData;
|
||||
assert(pDorn);
|
||||
|
||||
transactRS232(pDorn->controller,"TTY\n",4,pAns,10);
|
||||
KillRS232(pDorn->controller);
|
||||
free(pDorn);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int DornierInit(pVelSelDriv self, SConnection *pCon)
|
||||
{
|
||||
pDornier pDorn = NULL;
|
||||
int iRet, iError;
|
||||
float fRot;
|
||||
char pError[80], pBueffel[256];
|
||||
|
||||
assert(self);
|
||||
pDorn = (pDornier)self->pPrivate;
|
||||
assert(pDorn);
|
||||
|
||||
iRet = initRS232(pDorn->controller);
|
||||
if(iRet < 0){
|
||||
return 1;
|
||||
}
|
||||
setRS232SendTerminator(pDorn->controller,"\n");
|
||||
setRS232Timeout(pDorn->controller,pDorn->iTimeOut);
|
||||
setRS232Debug(pDorn->controller,1);
|
||||
|
||||
/*
|
||||
tell him that we want control.
|
||||
Funny enough no <cr> or <nl> is sent in the reply to this.
|
||||
*/
|
||||
setRS232ReplyTerminator(pDorn->controller,"\\");
|
||||
iRet = transactRS232(pDorn->controller,"REM\n",4,pError,79);
|
||||
setRS232ReplyTerminator(pDorn->controller,"\r\n");
|
||||
if(iRet != 1)
|
||||
{
|
||||
sprintf(pBueffel,
|
||||
"ERROR: %s while switching velocity selector to remote",
|
||||
pError);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
}
|
||||
/*
|
||||
check which status the velo is in
|
||||
*/
|
||||
pDorn->statusMode = STATSEND;
|
||||
GetDornierPos(self,&fRot);
|
||||
if(fRot < 0){
|
||||
GetDornierPos(self,&fRot);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pVelSelDriv VSCreateDornier2003(char *name, Tcl_Interp *pTcl)
|
||||
{
|
||||
pVelSelDriv pNew = NULL;
|
||||
pDornier pDorn = NULL;
|
||||
char *pPtr = NULL;
|
||||
int iVal, iRet, iPort;
|
||||
char pHost[132];
|
||||
|
||||
|
||||
/* the most likely error is the parameters specified are wrong!
|
||||
So check this first. We''ll use Tcl's result for error reporting.
|
||||
name is the name of an Tcl array which should hold the info
|
||||
necessary
|
||||
*/
|
||||
|
||||
/* allocate a Dornier structure */
|
||||
pDorn = (pDornier)malloc(sizeof(Dornier));
|
||||
if(!pDorn)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(pDorn,0,sizeof(Dornier));
|
||||
|
||||
/* host name */
|
||||
pPtr = Tcl_GetVar2(pTcl,name,"Host",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
Tcl_AppendResult(pTcl,"ERROR: no hostname found in",name,NULL);
|
||||
free(pDorn);
|
||||
return NULL;
|
||||
}
|
||||
strncpy(pHost,pPtr,131);
|
||||
|
||||
/* port number */
|
||||
pPtr = Tcl_GetVar2(pTcl,name,"Port",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
Tcl_AppendResult(pTcl,"ERROR: no port number found in",name,NULL);
|
||||
free(pDorn);
|
||||
return NULL;
|
||||
}
|
||||
iRet = Tcl_GetInt(pTcl,pPtr,&iPort);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
free(pDorn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* time out. This one gets defaulted when not specified */
|
||||
pPtr = Tcl_GetVar2(pTcl,name,"Timeout",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
pDorn->iTimeOut = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
iRet = Tcl_GetInt(pTcl,pPtr,&iVal);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pDorn->iTimeOut = 1000;
|
||||
}
|
||||
pDorn->iTimeOut = iVal;
|
||||
}
|
||||
|
||||
/* minimum control speed */
|
||||
pPtr = Tcl_GetVar2(pTcl,name,"MinControl",TCL_GLOBAL_ONLY);
|
||||
if(!pPtr)
|
||||
{
|
||||
pDorn->minRPM = 3100;
|
||||
}
|
||||
else
|
||||
{
|
||||
iRet = Tcl_GetInt(pTcl,pPtr,&iVal);
|
||||
if(iRet != TCL_OK)
|
||||
{
|
||||
pDorn->minRPM = 3100;
|
||||
}
|
||||
pDorn->minRPM = iVal;
|
||||
}
|
||||
|
||||
|
||||
/* business as usual: allocate memory */
|
||||
pNew = (pVelSelDriv)malloc(sizeof(VelSelDriv));
|
||||
if(!pNew)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* zero the world */
|
||||
memset(pNew,0,sizeof(VelSelDriv));
|
||||
pNew->pPrivate = pDorn;
|
||||
pDorn->controller = createRS232(pHost,iPort);
|
||||
if(!pDorn->controller){
|
||||
DornierKill(pNew->pPrivate);
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialise function pointers */
|
||||
pNew->DeletePrivate = DornierKill;
|
||||
pNew->Halt = DornierHalt;
|
||||
pNew->GetError = DornierError;
|
||||
pNew->TryAndFixIt = DornierFixIt;
|
||||
pNew->GetRotation = GetDornierPos;
|
||||
pNew->SetRotation = DornierRun;
|
||||
pNew->GetStatus = DornierStatNew;
|
||||
pNew->GetDriverText = DornierText;
|
||||
pNew->GetLossCurrent = DornierLoss;
|
||||
pNew->Init = DornierInit;
|
||||
|
||||
/* done it */
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
447
el734hp.c
Normal file
447
el734hp.c
Normal file
@ -0,0 +1,447 @@
|
||||
/*------------------------------------------------------------------------
|
||||
This is another driver for the PSI EL734 motor controllers as used
|
||||
at SINQ. The idea is that this one is performing better then the
|
||||
other one which uses David Madens SerPortServer program. The
|
||||
speedup is gained through:
|
||||
- direct access to the controller
|
||||
- reduction in the amount of data transferred
|
||||
- in status: send first, read only when data available. Cannot do this:
|
||||
up to 8 motors share a controller: I may get a status response for
|
||||
a wrong motor or overload the controller with to many confusing status
|
||||
requests.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, July 2003
|
||||
-----------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <fortify.h>
|
||||
#include <sics.h>
|
||||
#include <modriv.h>
|
||||
#include <rs232controller.h>
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
The motor driver structure. Please note that the first set of fields has
|
||||
be identical with the fields of AbstractModriv in ../modriv.h
|
||||
------------------------------------------------------------------------*/
|
||||
typedef struct __MoDriv {
|
||||
/* general motor driver interface
|
||||
fields. REQUIRED!
|
||||
*/
|
||||
float fUpper; /* upper limit */
|
||||
float fLower; /* lower limit */
|
||||
char *name;
|
||||
int (*GetPosition)(void *self,float *fPos);
|
||||
int (*RunTo)(void *self, float fNewVal);
|
||||
int (*GetStatus)(void *self);
|
||||
void (*GetError)(void *self, int *iCode, char *buffer, int iBufLen);
|
||||
int (*TryAndFixIt)(void *self,int iError, float fNew);
|
||||
int (*Halt)(void *self);
|
||||
int (*GetDriverPar)(void *self, char *name,
|
||||
float *value);
|
||||
int (*SetDriverPar)(void *self,SConnection *pCon,
|
||||
char *name, float newValue);
|
||||
void (*ListDriverPar)(void *self, char *motorName,
|
||||
SConnection *pCon);
|
||||
void (*KillPrivate)(void *self);
|
||||
|
||||
|
||||
/* EL-734 specific fields */
|
||||
prs232 controller;
|
||||
int iMotor;
|
||||
float lastValue;
|
||||
int errorCode;
|
||||
int oredMsr;
|
||||
} EL734Driv, *pEL734Driv;
|
||||
/*------------------- error codes ----------------------------------*/
|
||||
#define BADADR -1
|
||||
#define BADBSY -2
|
||||
#define BADCMD -3
|
||||
#define BADLOC -4
|
||||
#define BADPAR -5
|
||||
#define BADRNG -6
|
||||
#define BADUNKNOWN -7
|
||||
#define BADSTP -8
|
||||
#define BADEMERG -9
|
||||
#define LOWLIM -10
|
||||
#define HILIM -11
|
||||
#define RUNFAULT -12
|
||||
#define POSFAULT -13
|
||||
#define BADCUSHION -14
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int checkResponse(pEL734Driv self, char *pReply){
|
||||
/*
|
||||
error messages start with ?, if none we are done
|
||||
*/
|
||||
if(strstr(pReply,"?") == NULL && strstr(pReply,"*") == NULL){
|
||||
return 1;
|
||||
}
|
||||
strtolower(pReply);
|
||||
if(strstr(pReply,"?adr") != NULL){
|
||||
self->errorCode = BADADR;
|
||||
} else if(strstr(pReply,"?bsy") != NULL){
|
||||
self->errorCode = BADBSY;
|
||||
} else if(strstr(pReply,"?cmd") != NULL){
|
||||
self->errorCode = BADCMD;
|
||||
} else if(strstr(pReply,"?loc") != NULL){
|
||||
self->errorCode = BADLOC;
|
||||
} else if(strstr(pReply,"?par") != NULL){
|
||||
self->errorCode = BADPAR;
|
||||
} else if(strstr(pReply,"?rng") != NULL){
|
||||
self->errorCode = BADRNG;
|
||||
}else if(strstr(pReply,"*es") != NULL){
|
||||
self->errorCode = BADEMERG;
|
||||
} else {
|
||||
self->errorCode = BADUNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int EL734GetPos(void *pData, float *fPos){
|
||||
pEL734Driv self = NULL;
|
||||
int status;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
snprintf(pCommand,79,"u %d\r",self->iMotor);
|
||||
status = transactRS232(self->controller,pCommand,strlen(pCommand),
|
||||
pReply,79);
|
||||
if(status != 1){
|
||||
self->errorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
if(!checkResponse(self,pReply)){
|
||||
return HWFault;
|
||||
}
|
||||
sscanf(pReply,"%f",fPos);
|
||||
self->lastValue = *fPos;
|
||||
return OKOK;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL734Run(void *pData,float fValue){
|
||||
pEL734Driv self = NULL;
|
||||
int status;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
self->oredMsr = 0;
|
||||
snprintf(pCommand,79,"p %d %3.f\r",self->iMotor,fValue);
|
||||
status = transactRS232(self->controller,pCommand,strlen(pCommand),
|
||||
pReply,79);
|
||||
if(status != 1){
|
||||
self->errorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
if(!checkResponse(self,pReply)){
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int decodeMSR(pEL734Driv self, int msr){
|
||||
if(msr == 0){
|
||||
/*
|
||||
we are done: check ored_msr for troubles
|
||||
*/
|
||||
if(self->oredMsr & 0x2){
|
||||
return HWIdle;
|
||||
} else if(self->oredMsr & 0x10){
|
||||
self->errorCode = LOWLIM;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x20){
|
||||
self->errorCode = HILIM;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x80){
|
||||
self->errorCode = RUNFAULT;
|
||||
return HWPosFault;
|
||||
} else if(self->oredMsr & 0x200){
|
||||
self->errorCode = RUNFAULT;
|
||||
return HWPosFault;
|
||||
} else if(self->oredMsr & 0x1000){
|
||||
self->errorCode = BADCUSHION;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x8){
|
||||
self->errorCode = BADSTP;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x40) {
|
||||
self->errorCode = BADSTP;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x100){
|
||||
self->errorCode = POSFAULT;
|
||||
return HWFault;
|
||||
} else if(self->oredMsr & 0x400){
|
||||
self->errorCode = POSFAULT;
|
||||
return HWFault;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
we are still tugging along ............
|
||||
*/
|
||||
if(msr & 0x10){
|
||||
self->errorCode = LOWLIM;
|
||||
return HWFault;
|
||||
} else if(msr & 0x20){
|
||||
self->errorCode = HILIM;
|
||||
return HWFault;
|
||||
} else if(msr & 0x80){
|
||||
self->errorCode = RUNFAULT;
|
||||
return HWPosFault;
|
||||
} else if(self->oredMsr & 0x200){
|
||||
self->errorCode = RUNFAULT;
|
||||
return HWPosFault;
|
||||
} else if(msr & 0x1000){
|
||||
self->errorCode = BADCUSHION;
|
||||
return HWFault;
|
||||
} else if(msr & 0x8){
|
||||
self->errorCode = BADSTP;
|
||||
return HWFault;
|
||||
} else if(msr & 0x40) {
|
||||
self->errorCode = BADSTP;
|
||||
return HWFault;
|
||||
} else if(msr & 0x100){
|
||||
self->errorCode = POSFAULT;
|
||||
return HWFault;
|
||||
} else if(msr & 0x400){
|
||||
self->errorCode = POSFAULT;
|
||||
return HWFault;
|
||||
} else {
|
||||
return HWBusy;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int EL734Status(void *pData){
|
||||
pEL734Driv self = NULL;
|
||||
int status, msr;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
snprintf(pCommand,79,"msr %d\r",self->iMotor);
|
||||
status = transactRS232(self->controller,pCommand,strlen(pCommand),
|
||||
pReply,79);
|
||||
if(status < 0){
|
||||
self->errorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
if(!checkResponse(self,pReply)){
|
||||
return HWFault;
|
||||
}
|
||||
sscanf(pReply,"%x",&msr);
|
||||
self->oredMsr |= msr;
|
||||
return decodeMSR(self,msr);
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void EL734Error(void *pData, int *iCode, char *error, int errLen){
|
||||
pEL734Driv self = NULL;
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
*iCode = self->errorCode;
|
||||
switch(*iCode){
|
||||
case BADADR:
|
||||
strncpy(error,"Bad address",errLen);
|
||||
break;
|
||||
case BADBSY:
|
||||
strncpy(error,"Motor still busy",errLen);
|
||||
break;
|
||||
case BADCMD:
|
||||
strncpy(error,"Bad command",errLen);
|
||||
break;
|
||||
case BADLOC:
|
||||
strncpy(error,"Motor controller is on local",errLen);
|
||||
break;
|
||||
case BADPAR:
|
||||
strncpy(error,"Bad parameter",errLen);
|
||||
break;
|
||||
case BADRNG:
|
||||
strncpy(error,"Bad range",errLen);
|
||||
break;
|
||||
case BADUNKNOWN:
|
||||
strncpy(error,"Unknown error condition",errLen);
|
||||
break;
|
||||
case BADSTP:
|
||||
strncpy(error,"Motor is stopped",errLen);
|
||||
break;
|
||||
case BADEMERG:
|
||||
strncpy(error,"Emergency stop is engaged",errLen);
|
||||
break;
|
||||
case LOWLIM:
|
||||
strncpy(error,"Crashed into lower limit switch",errLen);
|
||||
break;
|
||||
case HILIM:
|
||||
strncpy(error,"Crashed into upper limit switch",errLen);
|
||||
break;
|
||||
case RUNFAULT:
|
||||
strncpy(error,"Run fault detected",errLen);
|
||||
break;
|
||||
case POSFAULT:
|
||||
strncpy(error,"Positioning fault detected",errLen);
|
||||
break;
|
||||
case BADCUSHION:
|
||||
strncpy(error,"Air cushion problem",errLen);
|
||||
break;
|
||||
default:
|
||||
getRS232Error(*iCode,error,errLen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL734Fix(void *pData, int iCode, float fValue){
|
||||
pEL734Driv self = NULL;
|
||||
int status, msr;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
switch(iCode){
|
||||
case BADADR:
|
||||
case BADCMD:
|
||||
case TIMEOUT:
|
||||
case BADPAR:
|
||||
case BADBSY:
|
||||
return MOTREDO;
|
||||
case BADLOC:
|
||||
snprintf(pCommand,49,"RMT 1\r");
|
||||
transactRS232(self->controller,pCommand,strlen(pCommand),pReply,79);
|
||||
return MOTREDO;
|
||||
case NOTCONNECTED:
|
||||
initRS232(self->controller);
|
||||
return MOTREDO;
|
||||
case RUNFAULT:
|
||||
return MOTREDO;
|
||||
}
|
||||
return MOTFAIL;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL734Halt(void *pData){
|
||||
pEL734Driv self = NULL;
|
||||
int status;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
self = (pEL734Driv)pData;
|
||||
assert(self);
|
||||
|
||||
snprintf(pCommand,79,"s %d\r",self->iMotor);
|
||||
status = transactRS232(self->controller,pCommand,strlen(pCommand),
|
||||
pReply,79);
|
||||
if(status != 1){
|
||||
self->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
if(!checkResponse(self,pReply)){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL734GetPar(void *self, char *name,
|
||||
float *fValue){
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL734SetPar(void *self, SConnection *pCon,
|
||||
char *name, float newValue){
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void EL734List(void *self, char *name, SConnection *pCon){
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void KillEL734(void *pData){
|
||||
/*
|
||||
the controller is owned by the controller object and will be
|
||||
deleted when that object is removed
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
MotorDriver *CreateEL734HP(SConnection *pCon, int argc, char *argv[]){
|
||||
pEL734Driv pNew = NULL;
|
||||
int motor, status;
|
||||
prs232 controller = NULL;
|
||||
char pCommand[50],pReply[80];
|
||||
|
||||
/*
|
||||
check arguments
|
||||
*/
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: not enough arguments to create EL734HP driver",
|
||||
eError);
|
||||
return NULL;
|
||||
}
|
||||
controller = (prs232)FindCommandData(pServ->pSics,argv[0],
|
||||
"RS232 Controller");
|
||||
if(!controller){
|
||||
SCWrite(pCon,"ERROR: motor controller not found",eError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
motor = atoi(argv[1]);
|
||||
if(motor < 0 || motor > 12){
|
||||
SCWrite(pCon,"ERROR: invalid motor number",eError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
allocate and initialize data structure
|
||||
*/
|
||||
pNew = (pEL734Driv)malloc(sizeof(EL734Driv));
|
||||
if(!pNew){
|
||||
SCWrite(pCon,"ERROR: no memory to allocate motor driver",
|
||||
eError);
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew,0,sizeof(EL734Driv));
|
||||
pNew->GetPosition = EL734GetPos;
|
||||
pNew->RunTo = EL734Run;
|
||||
pNew->GetStatus = EL734Status;
|
||||
pNew->GetError = EL734Error;
|
||||
pNew->TryAndFixIt = EL734Fix;
|
||||
pNew->Halt = EL734Halt;
|
||||
pNew->GetDriverPar = EL734GetPar;
|
||||
pNew->SetDriverPar = EL734SetPar;
|
||||
pNew->ListDriverPar = EL734List;
|
||||
pNew->KillPrivate = KillEL734;
|
||||
pNew->controller = controller;
|
||||
pNew->iMotor = motor;
|
||||
|
||||
/*
|
||||
connection will already have been set up, read limits
|
||||
*/
|
||||
snprintf(pCommand,49,"h %d\r",pNew->iMotor);
|
||||
status = transactRS232(pNew->controller, pCommand,strlen(pCommand),
|
||||
pReply,79);
|
||||
if(!status){
|
||||
SCWrite(pCon,"ERROR: failed to read HW limits, defaulting..",eError);
|
||||
pNew->fLower = -180.;
|
||||
pNew->fUpper = 180.;
|
||||
} else {
|
||||
if(checkResponse(pNew,pReply)){
|
||||
sscanf(pReply,"%f %f",&pNew->fLower,&pNew->fUpper);
|
||||
} else {
|
||||
SCWrite(pCon,
|
||||
"ERROR: invalid response when reading HW limits, defaulting..",
|
||||
eError);
|
||||
pNew->fLower = -180.;
|
||||
pNew->fUpper = 180.;
|
||||
}
|
||||
}
|
||||
return (MotorDriver *)pNew;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
10
el737driv.c
10
el737driv.c
@ -691,3 +691,13 @@ pCounterDriver CreateEL737Counter(SConnection *pCon, char *name,
|
||||
free(pEL737->host);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
568
el737hpdriv.c
Normal file
568
el737hpdriv.c
Normal file
@ -0,0 +1,568 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
This is another driver for the EL737 counter box used at SINQ. The hp in
|
||||
the name is for high performance, though this only a promise and not yet
|
||||
proven. This version connects directly to the RS232 port of the counter
|
||||
box on the terminal server rather then working with David Maden's
|
||||
SerPortServer program. Other tweaks will be implemented as well, such as
|
||||
reading the monitors only now and then and not on all calls.
|
||||
|
||||
Mark Koennecke, July 2003
|
||||
-------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <fortify.h>
|
||||
#include <string.h>
|
||||
#include <sics.h>
|
||||
#include <rs232controller.h>
|
||||
#include <countdriv.h>
|
||||
|
||||
#define MONTHRESH 20
|
||||
|
||||
#define STATSEND 0
|
||||
#define STATRECEIVE 2
|
||||
/*-----------------------------------------------------------------------
|
||||
our own data struture
|
||||
------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
prs232 controller;
|
||||
int monitorCount; /* read monitors if this is above MONTHRESH */
|
||||
float cachedControl;
|
||||
int errorCode;
|
||||
int finishCount; /* need RS = 0 2 times before really sure finished */
|
||||
int statusMode;
|
||||
} EL737hp, *pEL737hp;
|
||||
/*--------------------- ERROR CODES -------------------------------------*/
|
||||
#define OFFLINE -1
|
||||
#define BADRANGE -3
|
||||
#define BADCOMMAND -4
|
||||
#define BADPARAM -5
|
||||
#define NOPARAM -7
|
||||
#define TOMANYCOUNTS -8
|
||||
#define SYSERROR -9
|
||||
#define BADREPLY -10
|
||||
#define SELECTFAIL -11
|
||||
/*-----------------------------------------------------------------------
|
||||
search errors in a reply from the EL737. Returns 1 on success or a
|
||||
negative error code in case of trouble.
|
||||
------------------------------------------------------------------------*/
|
||||
static int checkEL737Error(char *pReply){
|
||||
|
||||
/*
|
||||
all error start with a ?, if no ? in reply, answer is OK!
|
||||
*/
|
||||
if(strstr(pReply,"?") == NULL){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Now there is an error and we have to identify it
|
||||
*/
|
||||
if(strstr(pReply,"?OF") != NULL){
|
||||
return OFFLINE;
|
||||
} else if(strstr(pReply,"?OV") != NULL){
|
||||
return OVERFLOW;
|
||||
} else if(strstr(pReply,"?1") != NULL){
|
||||
return BADRANGE;
|
||||
} else if(strstr(pReply,"?2") != NULL){
|
||||
return BADCOMMAND;
|
||||
} else if(strstr(pReply,"?3") != NULL){
|
||||
return BADPARAM;
|
||||
} else if(strstr(pReply,"?4") != NULL){
|
||||
return BADCOUNTER;
|
||||
} else if(strstr(pReply,"?5") != NULL){
|
||||
return NOPARAM;
|
||||
} else if(strstr(pReply,"?6") != NULL){
|
||||
return TOMANYCOUNTS;
|
||||
} else {
|
||||
return SYSERROR;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------
|
||||
fixMode checks if we are in STATRECEIVE mode, reads any pending
|
||||
data and sets the mode to STATSEND. This would fix the problem
|
||||
if another client wishes to give a command while we are expecting
|
||||
a status response
|
||||
---------------------------------------------------------------*/
|
||||
static void fixMode(pEL737hp pPriv){
|
||||
char pBuffer[256];
|
||||
int len = 255;
|
||||
|
||||
if(pPriv->statusMode == STATRECEIVE){
|
||||
readRS232TillTerm(pPriv->controller,pBuffer,&len);
|
||||
pPriv->statusMode = STATSEND;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------*/
|
||||
static int EL737Command(pEL737hp pPriv, char *pCommand,
|
||||
char *pReply, int replylen){
|
||||
int status;
|
||||
|
||||
status = transactRS232(pPriv->controller,pCommand,strlen(pCommand),
|
||||
pReply,replylen);
|
||||
if(status < 0){
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
status = checkEL737Error(pReply);
|
||||
if(status < 0){
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------*/
|
||||
static int readRS(pEL737hp pPriv, int *RS){
|
||||
int status, len = 131;
|
||||
char reply[132];
|
||||
|
||||
status = readRS232TillTerm(pPriv->controller,
|
||||
reply,&len);
|
||||
if(status < 0) {
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
status = checkEL737Error(reply);
|
||||
if(status < 0){
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
status = sscanf(reply,"%d",RS);
|
||||
if(status < 1){
|
||||
pPriv->errorCode = BADREPLY;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int decodeRS(pEL737hp pPriv, int RS){
|
||||
int returnValue;
|
||||
|
||||
switch(RS){
|
||||
case 0:
|
||||
pPriv->finishCount++;
|
||||
if(pPriv->finishCount > 2){
|
||||
returnValue = HWIdle;
|
||||
} else {
|
||||
returnValue = HWBusy;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
pPriv->finishCount = 0;
|
||||
returnValue = HWBusy;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
pPriv->finishCount = 0;
|
||||
returnValue = HWNoBeam;
|
||||
break;
|
||||
default:
|
||||
pPriv->finishCount = 0;
|
||||
returnValue = HWPause;
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int updateMonitors(struct __COUNTER *self){
|
||||
int status;
|
||||
int m1,m2,m3,m4,m5,m6,m7,m8;
|
||||
float fTime;
|
||||
pEL737hp pPriv = NULL;
|
||||
char reply[132];
|
||||
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
if(!EL737Command(pPriv,"RA\r",reply,131)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
There are two forms of RA replys: new form with 8 monitors
|
||||
*/
|
||||
status = sscanf(reply,"%f %d %d %d %d %d %d %d %d",
|
||||
&fTime,&m1,&m2,&m3,&m4,&m5,&m6,&m7,&m8);
|
||||
if(status != 9){
|
||||
/*
|
||||
old form with 4 monitors
|
||||
*/
|
||||
status = sscanf(reply,"%d %d %d %d %f",&m1,&m2,&m3,&m4,&fTime);
|
||||
if(status != 5){
|
||||
pPriv->errorCode = BADREPLY;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
self->lCounts[0] = m2;
|
||||
self->lCounts[1] = m1;
|
||||
self->lCounts[2] = m3;
|
||||
self->lCounts[3] = m4;
|
||||
self->lCounts[4] = m5;
|
||||
self->lCounts[5] = m6;
|
||||
self->lCounts[6] = m7;
|
||||
self->lCounts[7] = m8;
|
||||
self->fTime = fTime;
|
||||
|
||||
if(self->eMode == eTimer){
|
||||
pPriv->cachedControl = fTime;
|
||||
} else {
|
||||
pPriv->cachedControl = m2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int EL737Status(struct __COUNTER *self, float *fControl){
|
||||
int status, RS, returnValue;
|
||||
pEL737hp pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
/*
|
||||
handle STATSEND mode
|
||||
*/
|
||||
if(pPriv->statusMode == STATSEND){
|
||||
writeRS232(pPriv->controller,"RS\r",3);
|
||||
pPriv->statusMode = STATRECEIVE;
|
||||
*fControl = pPriv->cachedControl;
|
||||
return HWBusy;
|
||||
}
|
||||
|
||||
/*
|
||||
now we are dealing with STATRECEIVE mode.
|
||||
Check for data availability first.
|
||||
*/
|
||||
status = availableNetRS232(pPriv->controller);
|
||||
if(status == 0){
|
||||
*fControl = pPriv->cachedControl;
|
||||
return HWBusy;
|
||||
} else if(status < 0) {
|
||||
*fControl = pPriv->cachedControl;
|
||||
pPriv->statusMode = STATSEND;
|
||||
pPriv->errorCode = SELECTFAIL;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
The snail in the counter box has replied. Read and process
|
||||
the data
|
||||
*/
|
||||
pPriv->statusMode = STATSEND;
|
||||
if(!readRS(pPriv,&RS)){
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
decode it
|
||||
*/
|
||||
returnValue = decodeRS(pPriv,RS);
|
||||
|
||||
/*
|
||||
check if we update the monitors and do it
|
||||
*/
|
||||
pPriv->monitorCount++;
|
||||
if(pPriv->monitorCount > MONTHRESH){
|
||||
status = updateMonitors(self);
|
||||
pPriv->monitorCount = 0;
|
||||
if(!status){
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
|
||||
*fControl = pPriv->cachedControl;
|
||||
return returnValue;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int EL737Start(struct __COUNTER *self){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
if(self->eMode == ePreset){
|
||||
snprintf(pCommand,49,"MP %d\r",(int)nintf(self->fPreset));
|
||||
} else {
|
||||
snprintf(pCommand,49,"TP %.2f\r", self->fPreset);
|
||||
}
|
||||
if(EL737Command(pPriv,pCommand,pReply,29) != 1){
|
||||
return 0;
|
||||
}
|
||||
pPriv->finishCount = 0;
|
||||
return 1;
|
||||
}
|
||||
/* --------------------------------------------------------------------*/
|
||||
static int EL737Pause(struct __COUNTER *self){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return EL737Command(pPriv,"PS\r",pReply,29);
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL737Continue(struct __COUNTER *self){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return EL737Command(pPriv,"CO\r",pReply,29);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int EL737Halt(struct __COUNTER *self){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return EL737Command(pPriv,"S\r",pReply,29);
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int EL737Transfer(struct __COUNTER *self){
|
||||
pEL737hp pPriv = NULL;
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return updateMonitors(self);
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737GetError(struct __COUNTER *self, int *iCode,
|
||||
char *pError, int errLen){
|
||||
pEL737hp pPriv = NULL;
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
*iCode = pPriv->errorCode;
|
||||
switch(pPriv->errorCode){
|
||||
case OFFLINE:
|
||||
strncpy(pError,"EL737 is offline",errLen);
|
||||
break;
|
||||
case BADRANGE:
|
||||
strncpy(pError,"EL737 parameter is out of range",errLen);
|
||||
break;
|
||||
case BADCOMMAND:
|
||||
strncpy(pError,"EL737 received unknown command or is busy",errLen);
|
||||
break;
|
||||
case BADPARAM:
|
||||
strncpy(pError,"EL737 parameter is awful",errLen);
|
||||
break;
|
||||
case NOPARAM:
|
||||
strncpy(pError,"EL737 parameter missing",errLen);
|
||||
break;
|
||||
case TOMANYCOUNTS:
|
||||
strncpy(pError,"EL737 counters overflowed",errLen);
|
||||
break;
|
||||
case SYSERROR:
|
||||
strncpy(pError,"EL737 has an internal system error",errLen);
|
||||
break;
|
||||
case BADREPLY:
|
||||
strncpy(pError,"EL737 sent an unexpected reply",errLen);
|
||||
break;
|
||||
case SELECTFAIL:
|
||||
strncpy(pError,"select system call failed, network trouble",errLen);
|
||||
default:
|
||||
getRS232Error(pPriv->errorCode,pError,errLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737FixIt(struct __COUNTER *self, int iCode){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pReply[50];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
switch(iCode){
|
||||
case TIMEOUT:
|
||||
case BADREPLY:
|
||||
case BADPARAM:
|
||||
case NOPARAM:
|
||||
case BADRANGE:
|
||||
return COREDO;
|
||||
break;
|
||||
case OFFLINE:
|
||||
EL737Command(pPriv,"RMT 1\r",pReply,49);
|
||||
EL737Command(pPriv,"echo 2\r",pReply,49);
|
||||
return COREDO;
|
||||
break;
|
||||
case BADCOMMAND: /* can be busy, stop it and try again */
|
||||
EL737Command(pPriv,"S\r",pReply,49);
|
||||
return COREDO;
|
||||
break;
|
||||
case TOMANYCOUNTS:
|
||||
case SYSERROR:
|
||||
return COTERM;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
network problem; try to reopen
|
||||
*/
|
||||
status = initRS232(pPriv->controller);
|
||||
if(status != 1){
|
||||
return COTERM;
|
||||
} else {
|
||||
return COREDO;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int EL737Set(struct __COUNTER *self, char *name, int iCter,
|
||||
float fVal){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[80], pReply[50];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
if(strcmp(name,"threshold") == 0){
|
||||
sprintf(pCommand,"DL %1.1d %f\r",iCter, fVal);
|
||||
if(!EL737Command(pPriv,pCommand,pReply,49)){
|
||||
return HWFault;
|
||||
}
|
||||
sprintf(pCommand,"DR %1.1d\r",iCter);
|
||||
if(!EL737Command(pPriv,pCommand,pReply,49)){
|
||||
return HWFault;
|
||||
}
|
||||
return OKOK;
|
||||
} else {
|
||||
self->iErrorCode = UNKNOWNPAR;
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL737Get(struct __COUNTER *self, char *name, int iCter,
|
||||
float *fVal){
|
||||
pEL737hp pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[80], pReply[50];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
if(strcmp(name,"threshold") == 0){
|
||||
sprintf(pCommand,"DL %1.1d\r",iCter);
|
||||
if(!EL737Command(pPriv,pCommand,pReply,49)){
|
||||
return HWFault;
|
||||
}
|
||||
sscanf(pReply,"%f", fVal);
|
||||
return OKOK;
|
||||
} else {
|
||||
self->iErrorCode = UNKNOWNPAR;
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737Send(struct __COUNTER *self, char *pText, char *pReply,
|
||||
int iReplyLen){
|
||||
pEL737hp pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return EL737Command(pPriv,pText,pReply,iReplyLen);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void KillHP(pCounterDriver self){
|
||||
pEL737hp pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hp)self->pData;
|
||||
|
||||
if(!pPriv){
|
||||
return;
|
||||
}
|
||||
if(pPriv->controller != NULL){
|
||||
KillRS232(pPriv->controller);
|
||||
}
|
||||
free(pPriv);
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
pCounterDriver MakeEL737HP(SConnection *pCon, char *name,
|
||||
int argc, char *argv[]){
|
||||
pCounterDriver pNew = NULL;
|
||||
pEL737hp pPriv = NULL;
|
||||
char pHost[132];
|
||||
int port, status;
|
||||
|
||||
/*
|
||||
check arguments
|
||||
*/
|
||||
if(argc < 2) {
|
||||
SCWrite(pCon,"ERROR: insufficient no af arguments to create EL737HP",
|
||||
eError);
|
||||
return NULL;
|
||||
}
|
||||
if(!isNumeric(argv[1])){
|
||||
SCWrite(pCon,"ERROR: expected numeric argument for port number",
|
||||
eError);
|
||||
return NULL;
|
||||
}
|
||||
port = atoi(argv[1]);
|
||||
strncpy(pHost,argv[0],131);
|
||||
|
||||
/*
|
||||
allocate a bank worth of memory ...........
|
||||
*/
|
||||
pNew = CreateCounterDriver(name,"EL737HP");
|
||||
pPriv = (pEL737hp)malloc(sizeof(EL737hp));
|
||||
if(!pNew || !pPriv){
|
||||
return NULL;
|
||||
}
|
||||
memset(pPriv,0,sizeof(EL737hp));
|
||||
pPriv->controller = createRS232(pHost,port);
|
||||
if(!pPriv->controller){
|
||||
DeleteCounterDriver(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* assign functions */
|
||||
pNew->GetStatus = EL737Status;
|
||||
pNew->Start = EL737Start;
|
||||
pNew->Halt = EL737Halt;
|
||||
pNew->ReadValues = EL737Transfer;
|
||||
pNew->GetError = EL737GetError;
|
||||
pNew->TryAndFixIt = EL737FixIt;
|
||||
pNew->Pause = EL737Pause;
|
||||
pNew->Continue = EL737Continue;
|
||||
pNew->Set = EL737Set;
|
||||
pNew->Get = EL737Get;
|
||||
pNew->Send = EL737Send;
|
||||
pNew->KillPrivate = KillHP;
|
||||
pNew->iNoOfMonitors = 7;
|
||||
pNew->fTime = 0.;
|
||||
pNew->pData = pPriv;
|
||||
|
||||
/*
|
||||
initialize connection
|
||||
*/
|
||||
setRS232Debug(pPriv->controller,0);
|
||||
setRS232ReplyTerminator(pPriv->controller,"\r");
|
||||
status = initRS232(pPriv->controller);
|
||||
status = EL737Command(pPriv,"RMT 1\r",pHost,131);
|
||||
status = EL737Command(pPriv,"RMT 1\r",pHost,131);
|
||||
status = EL737Command(pPriv,"ECHO 2\r",pHost,131);
|
||||
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1740,3 +1740,26 @@
|
||||
return False; /* Error detected in EL737_GetStatus */
|
||||
}
|
||||
/*-------------------------------------------- End of EL737_Utility.C =======*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -5,9 +5,8 @@
|
||||
# Mark Koennecke, November 1996
|
||||
# Markus Zolliker, March 2003
|
||||
#--------------------------------------------------------------------------
|
||||
# the following line only for fortified version
|
||||
#DFORTIFY=-DFORTIFY
|
||||
#==========================================================================
|
||||
|
||||
include ../../alpha_def
|
||||
|
||||
CC = cc
|
||||
CFLAGS = -std1 -I../.. -g $(DFORTIFY) -I$(SRC).. -I$(SRC).
|
||||
|
2
make_gen
2
make_gen
@ -14,7 +14,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
||||
velodornier.o docho.o sanscook.o tecsdriv.o itc4driv.o itc4.o\
|
||||
bruker.o ltc11.o A1931.o dilludriv.o eurodriv.o slsmagnet.o \
|
||||
el755driv.o amorscan.o serial.o scontroller.o t_update.o \
|
||||
t_rlp.o t_conv.o
|
||||
t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o
|
||||
|
||||
libpsi.a: $(OBJ)
|
||||
- rm libpsi.a
|
||||
|
@ -4,11 +4,8 @@
|
||||
#
|
||||
# Mark Koennecke, June 2003
|
||||
#--------------------------------------------------------------------------
|
||||
# the following line only for fortified version
|
||||
#DFORTIFY=-DFORTIFY
|
||||
#==========================================================================
|
||||
include ../alpha_def
|
||||
|
||||
HDFROOT=/data/lnslib
|
||||
CC = cc
|
||||
CFLAGS = -std1 -g $(DFORTIFY) -I.. -I$(HDFROOT)/include -DHDF4 -DHDF5 \
|
||||
-Ihardsup
|
||||
|
20
psi.c
20
psi.c
@ -101,6 +101,7 @@ static void RemovePsiCommands(SicsInterp *pSics){
|
||||
/*---------------------------------------------------------------------*/
|
||||
MotorDriver *CreateEL734(SConnection *pCon, int argc, char *argv[]);
|
||||
MotorDriver *CreateEL734DC(SConnection *pCon, int argc, char *argv[]);
|
||||
MotorDriver *CreateEL734HP(SConnection *pCon, int argc, char *argv[]);
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pMotor CreatePsiMotor(SConnection *pCon, int argc, char *argv[]){
|
||||
MotorDriver *pDriver = NULL;
|
||||
@ -134,6 +135,18 @@ static pMotor CreatePsiMotor(SConnection *pCon, int argc, char *argv[]){
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return NULL;
|
||||
}
|
||||
} else if(strcmp(argv[1],"el734hp") == 0){
|
||||
pDriver = (MotorDriver *)CreateEL734HP(pCon,argc-2,&argv[2]);
|
||||
if(!pDriver){
|
||||
return NULL;
|
||||
}
|
||||
/* create the motor */
|
||||
pNew = MotorInit("EL734HP",argv[0],pDriver);
|
||||
if(!pNew){
|
||||
sprintf(pBueffel,"Failure to create motor %s",argv[1]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return NULL;
|
||||
}
|
||||
} else if(strcmp(argv[1],"el734dc") == 0){
|
||||
pDriver = (MotorDriver *)CreateEL734DC(pCon,argc-2,&argv[2]);
|
||||
if(!pDriver){
|
||||
@ -164,6 +177,8 @@ static pMotor CreatePsiMotor(SConnection *pCon, int argc, char *argv[]){
|
||||
/*-------------------------------------------------------------------*/
|
||||
extern pCounterDriver CreateEL737Counter(SConnection *pCon, char *name,
|
||||
int argc, char *argv[]);
|
||||
extern pCounterDriver MakeEL737HP(SConnection *pCon, char *name,
|
||||
int argc, char *argv[]);
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pCounterDriver CreatePsiCounterDriver(SConnection *pCon,
|
||||
int argc,
|
||||
@ -175,6 +190,8 @@ static pCounterDriver CreatePsiCounterDriver(SConnection *pCon,
|
||||
*/
|
||||
if(strcmp(argv[2],"el737") == 0){
|
||||
pNew = CreateEL737Counter(pCon,argv[1],argc-3,&argv[3]);
|
||||
} else if(strcmp(argv[2],"el737hp") == 0){
|
||||
pNew = MakeEL737HP(pCon,argv[1],argc-3,&argv[3]);
|
||||
} else if(strcmp(argv[2],"ecb") == 0){
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,
|
||||
@ -199,12 +216,15 @@ static HistDriver *CreatePsiHistMem(char *name, pStringDict pOptions){
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
extern pVelSelDriv VSCreateDornierSINQ(char *name,Tcl_Interp *pTcl);
|
||||
extern pVelSelDriv VSCreateDornier2003(char *name,Tcl_Interp *pTcl);
|
||||
/*-------------------------------------------------------------------*/
|
||||
static pVelSelDriv CreatePsiVelSelDriv(char *name, char *array,
|
||||
Tcl_Interp *pTcl){
|
||||
pVelSelDriv pNew = NULL;
|
||||
if(strcmp(name,"dornier") == 0){
|
||||
pNew = VSCreateDornierSINQ(array,pTcl);
|
||||
} else if(strcmp(name,"dornier2003") == 0){
|
||||
pNew = VSCreateDornier2003(array,pTcl);
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
@ -4,11 +4,8 @@
|
||||
#
|
||||
# Markus Zolliker, March 2003
|
||||
#--------------------------------------------------------------------------
|
||||
# the following lines only for fortified version
|
||||
#DFORTIFY=-DFORTIFY -I$(SRC)..
|
||||
#FORTIFYOBJ=../strdup.o ../fortify.o
|
||||
#==========================================================================
|
||||
|
||||
include ../../alpha_def
|
||||
|
||||
SICS=src/..
|
||||
|
||||
|
94
velodorn.c
94
velodorn.c
@ -7,6 +7,11 @@
|
||||
|
||||
Mark Koennecke, Juli 1997
|
||||
|
||||
Updated to decode the new dornier status messages as coughed up by the new
|
||||
style Dornier software.
|
||||
|
||||
Mark Koennecke, July 2003
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
@ -89,6 +94,95 @@
|
||||
strcpy(pResult->echo,(const char *)ptr_token);
|
||||
ptr_src += strlen(ptr_token);
|
||||
|
||||
ptr_src = NULL; /* necessary for further search with strtok */
|
||||
for (;;)
|
||||
{
|
||||
/* read text till next separator '/' */
|
||||
ptr_token = strtok(ptr_src, tok_c);
|
||||
if (ptr_token == NULL) break;
|
||||
strcpy(tok_buf,ptr_token);
|
||||
|
||||
for (key_id = 0; key_id<=15; key_id++)
|
||||
{
|
||||
/* search key ? */
|
||||
sl = strlen(keys[key_id]);
|
||||
if (strncmp(&keys[key_id][0], tok_buf, sl) == 0)
|
||||
{
|
||||
/* step over key */
|
||||
for (cnt=0;cnt+sl < TOK_BUF_L; cnt++)
|
||||
tok_buf[cnt] = tok_buf[cnt+sl];
|
||||
switch (key_id)
|
||||
{
|
||||
case 0: {strcpy(pResult->rm, tok_buf); break;}
|
||||
case 1: {sscanf(tok_buf,"%d",&pResult->nom_rpm); break;}
|
||||
case 2: {sscanf(tok_buf,"%d",&pResult->cur_rpm); break;}
|
||||
case 3: {sscanf(tok_buf,"%d",&pResult->pwr); break;}
|
||||
case 4: {sscanf(tok_buf,"%f",&pResult->curr); break;}
|
||||
case 5: {sscanf(tok_buf,"%d",&pResult->rot_temp); break;}
|
||||
case 6: {sscanf(tok_buf,"%d",&pResult->cont_temp); break;}
|
||||
case 7: {sscanf(tok_buf,"%d",&pResult->inl_temp); break;}
|
||||
case 8: {sscanf(tok_buf,"%d",&pResult->outl_temp); break;}
|
||||
case 9: {sscanf(tok_buf,"%f",&pResult->cool_wat); break;}
|
||||
case 10: {sscanf(tok_buf,"%f",&pResult->vacuum); break;}
|
||||
case 11: {sscanf(tok_buf,"%f",&pResult->accel); break;}
|
||||
case 12: {
|
||||
if (strcmp(tok_buf, ena_str) == 0)
|
||||
{pResult->komm = 1; break;}
|
||||
if (strcmp(tok_buf, dis_str) == 0)
|
||||
{pResult->komm = 0;break;}
|
||||
break;
|
||||
}
|
||||
case 13: break; /* date */
|
||||
case 14: break; /* time */
|
||||
case 15: {sscanf(tok_buf,"%d",&pResult->iHz); break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
/*--------------------------- analyse Dornier status string ----------------
|
||||
This is the version for the NGS037 software from Dornier. Main difference
|
||||
is that the keycodes are in germlish.
|
||||
-------------------------------------------------------------------------*/
|
||||
int DecodeNewDornierStatus(char *pText, pDornierStatus pResult)
|
||||
{
|
||||
int cnt, key_id, sl, sts;
|
||||
long err;
|
||||
char ena_str[] = "ENABLED";
|
||||
char dis_str[] = "DISABLED";
|
||||
char keys[16][14] =
|
||||
{
|
||||
"MODE:\0 ",
|
||||
"R_SPEED:\0 ",
|
||||
"A_SPEED:\0 ",
|
||||
"P_LOSS:\0 ",
|
||||
"R_Current:\0 ",
|
||||
"T_ROT:\0 ",
|
||||
"T_HHH:\0 ",
|
||||
"T_INL:\0 ",
|
||||
"T_OUT:\0",
|
||||
"F_RATE:\0",
|
||||
"A_Vac:\0 ",
|
||||
"V_OSC:\0 ",
|
||||
"COM: \0 ",
|
||||
"DATE: \0 ",
|
||||
"TIME: \0 ",
|
||||
"Hz:\0 "};
|
||||
|
||||
char tok_buf[TOK_BUF_L], *ptr_token, *ptr_src, *ptr;
|
||||
const char tok_c[] = "/\\\0";
|
||||
char status[255];
|
||||
|
||||
ptr_src = pText;
|
||||
memset(pResult,0,sizeof(DornierStatus));
|
||||
|
||||
/* skip over first token, should be command echo */
|
||||
ptr_token = strtok(ptr_src, tok_c);
|
||||
if (ptr_token == NULL) return 0; /* error */
|
||||
strcpy(pResult->echo,(const char *)ptr_token);
|
||||
ptr_src += strlen(ptr_token);
|
||||
|
||||
ptr_src = NULL; /* necessary for further search with strtok */
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#line 46 "velodorn.w"
|
||||
#line 47 "velodorn.w"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
V E L O D O R N
|
||||
@ -9,6 +9,8 @@
|
||||
|
||||
Mark Koennecke, Juli 1997
|
||||
|
||||
updated to support new format fo status messages, Mark Koennecke, July 2003
|
||||
|
||||
copyright: see implementation file.
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef VELODORN
|
||||
@ -48,8 +50,9 @@
|
||||
|
||||
int GetDornierStatus(void **pData, pDornierStatus pDornier);
|
||||
int DornierSend(void **pData, char *pCommand, char *pReply, int iLen);
|
||||
int DecodeNewDornierStatus(char *pText, pDornierStatus pDornier);
|
||||
|
||||
#line 89 "velodorn.w"
|
||||
#line 92 "velodorn.w"
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -41,6 +41,7 @@ done in the DornierStat function.
|
||||
@d dh @{
|
||||
int GetDornierStatus(void **pData, pDornierStatus pDornier);
|
||||
int DornierSend(void **pData, char *pCommand, char *pReply, int iLen);
|
||||
int DecodeNewDornierStatus(char *pText, pDornierStatus pDornier);
|
||||
@}
|
||||
|
||||
@o velodorn.h -d @{
|
||||
@ -52,6 +53,8 @@ done in the DornierStat function.
|
||||
|
||||
Mark Koennecke, Juli 1997
|
||||
|
||||
updated to support new format fo status messages, Mark Koennecke, July 2003
|
||||
|
||||
copyright: see implementation file.
|
||||
------------------------------------------------------------------------------*/
|
||||
#ifndef VELODORN
|
||||
|
Reference in New Issue
Block a user