- Added a counter driver for MORPHEUS-2D which checks an SPS for an
detector overcount condition.
This commit is contained in:
704
el737hpdrivsps.c
Normal file
704
el737hpdrivsps.c
Normal file
@ -0,0 +1,704 @@
|
||||
/*-----------------------------------------------------------------------
|
||||
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
|
||||
|
||||
This is a special version for MORPHEUS which checks the SPS when in
|
||||
No Beam state. Because NoBeam can be caused by the shutter being closed
|
||||
in order to prevent overloading the 2D detector.
|
||||
|
||||
Mark Koennecke, March 2007
|
||||
-------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <fortify.h>
|
||||
#include <string.h>
|
||||
#include <sics.h>
|
||||
#include <rs232controller.h>
|
||||
#include <countdriv.h>
|
||||
#include <splitter.h>
|
||||
#include "sps.h"
|
||||
|
||||
#define MONTHRESH 20
|
||||
|
||||
#define STATSEND 0
|
||||
#define STATRECEIVE 2
|
||||
#define BADTRANGE -117766
|
||||
/*-----------------------------------------------------------------------
|
||||
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;
|
||||
time_t startRequest;
|
||||
int lastStatus; /* need to remember last status, otherwise I get oscillating
|
||||
NoBeam and Counting status if the beam goes off
|
||||
*/
|
||||
char *badReply;
|
||||
int readErrorCount; /* need to remember failed reads: on RDOE, upper level
|
||||
code will see busy's and thus not catch the case of
|
||||
multiple failures
|
||||
*/
|
||||
pSPS sps;
|
||||
} EL737hpsps, *pEL737hpsps;
|
||||
/*--------------------- 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
|
||||
#define TIMEOUT737 -12
|
||||
#define TOMANYREADERRORS -23
|
||||
#define DETOVERLOAD -24
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void setBadReply(pEL737hpsps self, char *reply){
|
||||
if(self->badReply != NULL){
|
||||
free(self->badReply);
|
||||
}
|
||||
self->badReply = strdup(reply);
|
||||
}
|
||||
/*-----------------------------------------------------------------------
|
||||
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(pEL737hpsps pPriv){
|
||||
char pBuffer[256];
|
||||
int len = 255;
|
||||
|
||||
if(pPriv->statusMode == STATRECEIVE){
|
||||
readRS232TillTerm(pPriv->controller,pBuffer,&len);
|
||||
pPriv->statusMode = STATSEND;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------*/
|
||||
static int EL737SCommand(pEL737hpsps 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(pEL737hpsps pPriv, int *RS){
|
||||
int status, len = 131;
|
||||
char reply[132];
|
||||
|
||||
status = readRS232TillTerm(pPriv->controller,
|
||||
reply,&len);
|
||||
if(status < 0) {
|
||||
pPriv->readErrorCount++;
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
status = checkEL737Error(reply);
|
||||
if(status < 0){
|
||||
pPriv->readErrorCount++;
|
||||
pPriv->errorCode = status;
|
||||
return 0;
|
||||
}
|
||||
status = sscanf(reply,"%d",RS);
|
||||
if(status < 1){
|
||||
pPriv->readErrorCount++;
|
||||
pPriv->errorCode = BADREPLY;
|
||||
setBadReply(pPriv,reply);
|
||||
return 0;
|
||||
}
|
||||
pPriv->readErrorCount = 0;
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
static int decodeRS(pEL737hpsps 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;
|
||||
pEL737hpsps pPriv = NULL;
|
||||
char reply[132];
|
||||
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
if(!EL737SCommand(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;
|
||||
setBadReply(pPriv,reply);
|
||||
printf("Bad reply to EL737 RA command: %s\n", reply);
|
||||
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 = m1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int EL737SStatus(struct __COUNTER *self, float *fControl){
|
||||
int status, RS, returnValue;
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int iBit = 0;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
/*
|
||||
handle STATSEND mode
|
||||
*/
|
||||
if(pPriv->statusMode == STATSEND){
|
||||
status = writeRS232(pPriv->controller,"RS\r",3);
|
||||
if(status < 0){
|
||||
pPriv->errorCode = status;
|
||||
return HWFault;
|
||||
}
|
||||
pPriv->statusMode = STATRECEIVE;
|
||||
pPriv->startRequest = time(NULL);
|
||||
*fControl = pPriv->cachedControl;
|
||||
return pPriv->lastStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
now we are dealing with STATRECEIVE mode.
|
||||
Check for timeout first.
|
||||
*/
|
||||
if(time(NULL) > pPriv->startRequest + 10){
|
||||
pPriv->statusMode = STATSEND;
|
||||
pPriv->errorCode = TIMEOUT737;
|
||||
pPriv->readErrorCount++;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
check availability of data
|
||||
*/
|
||||
status = availableNetRS232(pPriv->controller);
|
||||
if(status == 0){
|
||||
*fControl = pPriv->cachedControl;
|
||||
return pPriv->lastStatus;
|
||||
} 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);
|
||||
pPriv->lastStatus = returnValue;
|
||||
|
||||
/*
|
||||
check for excessive failed reads
|
||||
*/
|
||||
if(pPriv->readErrorCount > 3){
|
||||
pPriv->errorCode = TOMANYREADERRORS;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
if(returnValue == HWNoBeam){
|
||||
/* ToDo: put in proper bit address when properly known */
|
||||
SPSGetStatus(pPriv->sps,79,&iBit);
|
||||
if(iBit == 1){
|
||||
pPriv->errorCode = DETOVERLOAD;
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int EL737SStart(struct __COUNTER *self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
pPriv->readErrorCount = 0;
|
||||
if(self->eMode == ePreset){
|
||||
snprintf(pCommand,49,"MP %d\r",(int)self->fPreset);
|
||||
} else {
|
||||
if(self->fPreset < .1 || self->fPreset > 200000)
|
||||
{
|
||||
self->iErrorCode = BADTRANGE;
|
||||
return HWFault;
|
||||
}
|
||||
snprintf(pCommand,49,"TP %.2f\r", self->fPreset);
|
||||
}
|
||||
if(EL737SCommand(pPriv,pCommand,pReply,29) != 1){
|
||||
return 0;
|
||||
}
|
||||
pPriv->finishCount = 0;
|
||||
pPriv->lastStatus = HWBusy;
|
||||
return 1;
|
||||
}
|
||||
/* --------------------------------------------------------------------*/
|
||||
static int EL737SPause(struct __COUNTER *self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
pPriv->lastStatus = HWPause;
|
||||
return EL737SCommand(pPriv,"PS\r",pReply,29);
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL737SContinue(struct __COUNTER *self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
pPriv->lastStatus = HWBusy;
|
||||
return EL737SCommand(pPriv,"CO\r",pReply,29);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int EL737SHalt(struct __COUNTER *self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[50], pReply[30];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
pPriv->lastStatus = HWBusy;
|
||||
return EL737SCommand(pPriv,"S\r",pReply,29);
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int EL737STransfer(struct __COUNTER *self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return updateMonitors(self);
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737SGetError(struct __COUNTER *self, int *iCode,
|
||||
char *pError, int errLen){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
*iCode = pPriv->errorCode;
|
||||
switch(pPriv->errorCode){
|
||||
case OFFLINE:
|
||||
strncpy(pError,"EL737 is offline",errLen);
|
||||
break;
|
||||
case OVERFLOW:
|
||||
strncpy(pError,"EL737 reported overflow, communication problem",errLen);
|
||||
break;
|
||||
case BADRANGE:
|
||||
strncpy(pError,"EL737 parameter is out of range",errLen);
|
||||
break;
|
||||
case BADTRANGE:
|
||||
strncpy(pError,"preset timer 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:
|
||||
snprintf(pError,errLen,"EL737 sent an unexpected reply: %s",
|
||||
pPriv->badReply);
|
||||
break;
|
||||
case SELECTFAIL:
|
||||
strncpy(pError,"select system call failed, network trouble",errLen);
|
||||
break;
|
||||
case TIMEOUT737:
|
||||
strncpy(pError,"timeout or network problem while waiting for status repsonse",errLen);
|
||||
break;
|
||||
case TOMANYREADERRORS:
|
||||
strncpy(pError,"Failed more then three times to read counter box",errLen);
|
||||
break;
|
||||
case DETOVERLOAD:
|
||||
strncpy(pError,"Shutter closed due to detector overload",errLen);
|
||||
break;
|
||||
default:
|
||||
getRS232Error(pPriv->errorCode,pError,errLen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737SFixIt(struct __COUNTER *self, int iCode){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pReply[50];
|
||||
char buffer[256];
|
||||
int dataLen = 255;
|
||||
int i;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
switch(iCode){
|
||||
case BADPARAM:
|
||||
case NOPARAM:
|
||||
case BADRANGE:
|
||||
case BADTRANGE:
|
||||
case OVERFLOW:
|
||||
return COREDO;
|
||||
break;
|
||||
case BADREPLY:
|
||||
case TIMEOUT737:
|
||||
case TIMEOUT:
|
||||
for(i = 0; i < 3; i++){
|
||||
status = readRS232TillTerm(pPriv->controller,buffer,&dataLen);
|
||||
if(status == 1){
|
||||
return COREDO;
|
||||
}
|
||||
}
|
||||
/*
|
||||
If nothing can be read, the only fixable cause is a network breakdown
|
||||
Try to fix this. If this does not work: give up
|
||||
*/
|
||||
closeRS232(pPriv->controller);
|
||||
SicsWait(60);
|
||||
status = initRS232(pPriv->controller);
|
||||
if(status != 1){
|
||||
return COTERM;
|
||||
} else {
|
||||
return COREDO;
|
||||
}
|
||||
break;
|
||||
case OFFLINE:
|
||||
EL737SCommand(pPriv,"RMT 1\r",pReply,49);
|
||||
EL737SCommand(pPriv,"echo 2\r",pReply,49);
|
||||
return COREDO;
|
||||
break;
|
||||
case BADCOMMAND: /* can be busy, stop it and try again */
|
||||
EL737SCommand(pPriv,"S\r",pReply,49);
|
||||
return COREDO;
|
||||
break;
|
||||
case TOMANYCOUNTS:
|
||||
case SYSERROR:
|
||||
case DETOVERLOAD:
|
||||
return COTERM;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
network problem; try to reopen
|
||||
*/
|
||||
closeRS232(pPriv->controller);
|
||||
SicsWait(60);
|
||||
status = initRS232(pPriv->controller);
|
||||
if(status != 1){
|
||||
return COTERM;
|
||||
} else {
|
||||
return COREDO;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int EL737SSet(struct __COUNTER *self, char *name, int iCter,
|
||||
float fVal){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[80], pReply[50];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
if(strcmp(name,"threshold") == 0){
|
||||
sprintf(pCommand,"DL %1.1d %f\r",iCter, fVal);
|
||||
if(!EL737SCommand(pPriv,pCommand,pReply,49)){
|
||||
return 0;
|
||||
}
|
||||
sprintf(pCommand,"DR %1.1d\r",iCter);
|
||||
if(!EL737SCommand(pPriv,pCommand,pReply,49)){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
self->iErrorCode = UNKNOWNPAR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int EL737SGet(struct __COUNTER *self, char *name, int iCter,
|
||||
float *fVal){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
int status;
|
||||
char pCommand[80], pReply[50];
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
if(strcmp(name,"threshold") == 0){
|
||||
sprintf(pCommand,"DL %1.1d\r",iCter);
|
||||
if(!EL737SCommand(pPriv,pCommand,pReply,49)){
|
||||
return 0;
|
||||
}
|
||||
sscanf(pReply,"%f", fVal);
|
||||
return 1;
|
||||
} else {
|
||||
self->iErrorCode = UNKNOWNPAR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int EL737SSend(struct __COUNTER *self, char *pText, char *pReply,
|
||||
int iReplyLen){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
fixMode(pPriv);
|
||||
return EL737SCommand(pPriv,pText,pReply,iReplyLen);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static void KillHP(pCounterDriver self){
|
||||
pEL737hpsps pPriv = NULL;
|
||||
|
||||
assert(self);
|
||||
pPriv = (pEL737hpsps)self->pData;
|
||||
|
||||
if(!pPriv){
|
||||
return;
|
||||
}
|
||||
if(pPriv->controller != NULL){
|
||||
KillRS232(pPriv->controller);
|
||||
}
|
||||
if(pPriv->badReply != NULL){
|
||||
free(pPriv->badReply);
|
||||
}
|
||||
free(pPriv);
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
pCounterDriver MakeEL737hpsps(SConnection *pCon, char *name,
|
||||
int argc, char *argv[]){
|
||||
pCounterDriver pNew = NULL;
|
||||
pEL737hpsps pPriv = NULL;
|
||||
char pHost[132];
|
||||
int port, status;
|
||||
|
||||
/*
|
||||
check arguments
|
||||
*/
|
||||
if(argc < 3) {
|
||||
SCWrite(pCon,"ERROR: insufficient no af arguments to create EL737HPSPS",
|
||||
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,"EL737HPSPS");
|
||||
pPriv = (pEL737hpsps)malloc(sizeof(EL737hpsps));
|
||||
if(!pNew || !pPriv){
|
||||
return NULL;
|
||||
}
|
||||
memset(pPriv,0,sizeof(EL737hpsps));
|
||||
pPriv->controller = createRS232(pHost,port);
|
||||
if(!pPriv->controller){
|
||||
DeleteCounterDriver(pNew);
|
||||
return NULL;
|
||||
}
|
||||
pPriv->sps = (pSPS)FindCommandData(pServ->pSics,argv[2],"SPS");
|
||||
if(pPriv->sps == NULL){
|
||||
SCWrite(pCon,"ERROR: SPS not found",eError);
|
||||
DeleteCounterDriver(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* assign functions */
|
||||
pNew->GetStatus = EL737SStatus;
|
||||
pNew->Start = EL737SStart;
|
||||
pNew->Halt = EL737SHalt;
|
||||
pNew->ReadValues = EL737STransfer;
|
||||
pNew->GetError = EL737SGetError;
|
||||
pNew->TryAndFixIt = EL737SFixIt;
|
||||
pNew->Pause = EL737SPause;
|
||||
pNew->Continue = EL737SContinue;
|
||||
pNew->Set = EL737SSet;
|
||||
pNew->Get = EL737SGet;
|
||||
pNew->Send = EL737SSend;
|
||||
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 = EL737SCommand(pPriv,"RMT 1\r",pHost,131);
|
||||
status = EL737SCommand(pPriv,"RMT 1\r",pHost,131);
|
||||
status = EL737SCommand(pPriv,"ECHO 2\r",pHost,131);
|
||||
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user