required inclusion of a matrix package. - modified counter error handling to send a Stop when the _BAD_BUSY error is received. - added an environment interface to the general controller stuff in choco.* Also added setting a parameter directly at the controller object. - Added a driver for the ETH High Temperature Furnace to be used at SANS.
736 lines
18 KiB
C
736 lines
18 KiB
C
/*------------------------------------------------------------------------
|
|
G E N C O U N T
|
|
|
|
Some general stuff for handling a CounterDriver.
|
|
|
|
|
|
Mark Koennecke, January 1997
|
|
|
|
Copyright:
|
|
|
|
Labor fuer Neutronenstreuung
|
|
Paul Scherrer Institut
|
|
CH-5423 Villigen-PSI
|
|
|
|
|
|
The authors hereby grant permission to use, copy, modify, distribute,
|
|
and license this software and its documentation for any purpose, provided
|
|
that existing copyright notices are retained in all copies and that this
|
|
notice is included verbatim in any distributions. No written agreement,
|
|
license, or royalty fee is required for any of the authorized uses.
|
|
Modifications to this software may be copyrighted by their authors
|
|
and need not follow the licensing terms described here, provided that
|
|
the new terms are clearly indicated on the first page of each file where
|
|
they apply.
|
|
|
|
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
|
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
|
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
|
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
|
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
|
MODIFICATIONS.
|
|
----------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include "fortify.h"
|
|
#include <string.h>
|
|
#include "Scommon.h"
|
|
#include "countdriv.h"
|
|
#include "hardsup/sinq_prototypes.h"
|
|
#include "hardsup/el737_def.h"
|
|
#include "hardsup/el737fix.h"
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
pCounterDriver CreateCounterDriver(char *name, char *type)
|
|
{
|
|
pCounterDriver pRes = NULL;
|
|
|
|
pRes = (pCounterDriver)malloc(sizeof(CounterDriver));
|
|
if(!pRes)
|
|
{
|
|
return NULL;
|
|
}
|
|
memset(pRes,0,sizeof(CounterDriver));
|
|
|
|
pRes->name = strdup(name);
|
|
pRes->type = strdup(type);
|
|
pRes->eMode = eTimer;
|
|
pRes->fPreset = 1000.;
|
|
pRes->fTime = 0.;
|
|
pRes->iNoOfMonitors = 0;
|
|
pRes->iPause = 0;
|
|
pRes->Start = NULL;
|
|
pRes->GetStatus = NULL;
|
|
pRes->ReadValues = NULL;
|
|
pRes->GetError = NULL;
|
|
pRes->TryAndFixIt = NULL;
|
|
pRes->Halt = NULL;
|
|
pRes->pData = NULL;
|
|
pRes->Pause = NULL;
|
|
pRes->Continue = NULL;
|
|
|
|
return pRes;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
void DeleteCounterDriver(pCounterDriver self)
|
|
{
|
|
assert(self);
|
|
if(self->name)
|
|
{
|
|
free(self->name);
|
|
}
|
|
if(self->type)
|
|
{
|
|
free(self->type);
|
|
}
|
|
if(self->pData)
|
|
{
|
|
free(self->pData);
|
|
}
|
|
free(self);
|
|
}
|
|
/*----------------------------- EL737 ------------------------------------*/
|
|
typedef struct {
|
|
char *host;
|
|
int iPort;
|
|
int iChannel;
|
|
void *pData;
|
|
} EL737st;
|
|
/*------------------------------------------------------------------------*/
|
|
static int EL737GetStatus(struct __COUNTER *self, float *fControl)
|
|
{
|
|
int iRet;
|
|
int iC1, iC2, iC3,iC4,iRS;
|
|
float fTime;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
iRet = EL737_GetStatus(&pEL737->pData,&iC1,&iC2,&iC3,&iC4,&fTime,&iRS);
|
|
if(self->eMode == eTimer)
|
|
{
|
|
*fControl = fTime;
|
|
}
|
|
else
|
|
{
|
|
*fControl = iC1;
|
|
}
|
|
/* store time */
|
|
self->fTime = fTime;
|
|
|
|
if(iRet != 1)
|
|
{
|
|
return HWFault;
|
|
}
|
|
self->lCounts[0] = iC2;
|
|
self->lCounts[1] = iC1;
|
|
self->lCounts[2] = iC3;
|
|
self->lCounts[3] = iC4;
|
|
|
|
/* get extra counters for 8-fold counter boxes */
|
|
iRet = EL737_GetStatusExtra(&pEL737->pData,&iC1,&iC2,&iC3,&iC4);
|
|
self->lCounts[4] = iC1;
|
|
self->lCounts[5] = iC2;
|
|
self->lCounts[6] = iC3;
|
|
self->lCounts[7] = iC4;
|
|
if(iRS == 0)
|
|
{
|
|
return HWIdle;
|
|
}
|
|
else if((iRS == 1) || (iRS == 2))
|
|
{
|
|
return HWBusy;
|
|
}
|
|
else if( (iRS == 5) || (iRS == 6))
|
|
{
|
|
return HWNoBeam;
|
|
}
|
|
else
|
|
{
|
|
return HWPause;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Start(struct __COUNTER *self)
|
|
{
|
|
int iRet, iRS;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
|
|
self->fTime = 0.;
|
|
|
|
if(self->eMode == ePreset)
|
|
{
|
|
iRet = EL737_StartCnt(&pEL737->pData,(int)nintf(self->fPreset),&iRS);
|
|
if(iRet == 1)
|
|
{
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
}
|
|
else if(self->eMode == eTimer)
|
|
{
|
|
iRet = EL737_StartTime(&pEL737->pData,self->fPreset,&iRS);
|
|
if(iRet == 1)
|
|
{
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Pause(struct __COUNTER *self)
|
|
{
|
|
int iRet, iRS;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
|
|
iRet = EL737_Pause(&pEL737->pData,&iRS);
|
|
if(iRet == 1)
|
|
{
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Continue(struct __COUNTER *self)
|
|
{
|
|
int iRet, iRS;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
|
|
iRet = EL737_Continue(&pEL737->pData,&iRS);
|
|
if(iRet == 1)
|
|
{
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL737Halt(struct __COUNTER *self)
|
|
{
|
|
int iRet, iC1, iC2, iC3, iC4,iRS;
|
|
float fPreset;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
|
|
|
|
iRet = EL737_Stop(&pEL737->pData,&iC1, &iC2,&iC3,&iC4,&fPreset,&iRS);
|
|
if(iRet == 1)
|
|
{
|
|
self->lCounts[0] = iC2;
|
|
self->lCounts[1] = iC1;
|
|
self->lCounts[2] = iC3;
|
|
self->lCounts[3] = iC4;
|
|
return OKOK;
|
|
}
|
|
return HWFault;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL737ReadValues(struct __COUNTER *self)
|
|
{
|
|
int iRet;
|
|
int iC1, iC2, iC3,iC4,iRS;
|
|
float fTime;
|
|
EL737st *pEL737;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
|
|
iRet = EL737_GetStatus(&pEL737->pData,&iC1,&iC2,&iC3,&iC4,&fTime,&iRS);
|
|
if(iRet != 1)
|
|
{
|
|
return HWFault;
|
|
}
|
|
self->fTime = fTime;
|
|
|
|
self->lCounts[0] = iC2;
|
|
self->lCounts[1] = iC1;
|
|
self->lCounts[2] = iC3;
|
|
self->lCounts[3] = iC4;
|
|
/* get extra counters for 8-fold counter boxes */
|
|
iRet = EL737_GetStatusExtra(&pEL737->pData,&iC1,&iC2,&iC3,&iC4);
|
|
self->lCounts[4] = iC1;
|
|
self->lCounts[5] = iC2;
|
|
self->lCounts[6] = iC3;
|
|
self->lCounts[7] = iC4;
|
|
|
|
return OKOK;
|
|
}
|
|
/*---------------------------------------------------------------------------
|
|
|
|
EL737Error2Text converts between an EL734 error code to text
|
|
-----------------------------------------------------------------------------*/
|
|
static void EL737Error2Text(char *pBuffer, int iErr)
|
|
{
|
|
switch(iErr)
|
|
{
|
|
case EL737__BAD_ADR:
|
|
strcpy(pBuffer,"EL737__BAD_ADR");
|
|
break;
|
|
case EL737__BAD_OVFL:
|
|
strcpy(pBuffer,"EL737__BAD_OVFL");
|
|
break;
|
|
case EL737__BAD_BSY:
|
|
strcpy(pBuffer,"EL737__BAD_BSY");
|
|
break;
|
|
case EL737__BAD_SNTX:
|
|
strcpy(pBuffer,"EL737__BAD_SNTX");
|
|
break;
|
|
case EL737__BAD_CONNECT:
|
|
strcpy(pBuffer,"EL737__BAD_CONNECT");
|
|
break;
|
|
case EL737__BAD_FLUSH:
|
|
strcpy(pBuffer,"EL737__BAD_FLUSH");
|
|
break;
|
|
case EL737__BAD_DEV:
|
|
strcpy(pBuffer,"EL734__BAD_DEV");
|
|
break;
|
|
case EL737__BAD_ID:
|
|
strcpy(pBuffer,"EL737__BAD_ID");
|
|
break;
|
|
case EL737__BAD_ILLG:
|
|
strcpy(pBuffer,"EL737__BAD_ILLG");
|
|
break;
|
|
case EL737__BAD_LOC:
|
|
strcpy(pBuffer,"EL737__BAD_LOC");
|
|
break;
|
|
case EL737__BAD_MALLOC:
|
|
strcpy(pBuffer,"EL737__BAD_MALLOC");
|
|
break;
|
|
case EL737__BAD_NOT_BCD:
|
|
strcpy(pBuffer,"EL737__BAD_NOT_BCD");
|
|
break;
|
|
case EL737__BAD_OFL:
|
|
strcpy(pBuffer,"EL737__BAD_OFL");
|
|
break;
|
|
case EL737__BAD_PAR:
|
|
strcpy(pBuffer,"EL737__BAD_PAR");
|
|
break;
|
|
|
|
case EL737__BAD_RECV:
|
|
strcpy(pBuffer,"EL737__BAD_RECV");
|
|
break;
|
|
case EL737__BAD_RECV_NET:
|
|
strcpy(pBuffer,"EL737__BAD_RECV_NET");
|
|
break;
|
|
case EL737__BAD_RECV_PIPE:
|
|
strcpy(pBuffer,"EL737__BAD_RECV_PIPE");
|
|
break;
|
|
case EL737__BAD_RECV_UNKN:
|
|
strcpy(pBuffer,"EL737__BAD_RECV_UNKN");
|
|
break;
|
|
case EL737__BAD_RECVLEN:
|
|
strcpy(pBuffer,"EL737__BAD_RECVLEN");
|
|
break;
|
|
case EL737__BAD_RECV1:
|
|
strcpy(pBuffer,"EL737__BAD_RECV1");
|
|
break;
|
|
case EL737__BAD_RECV1_NET:
|
|
strcpy(pBuffer,"EL737__BAD_RECV1_NET");
|
|
break;
|
|
case EL737__BAD_RECV1_PIPE:
|
|
strcpy(pBuffer,"EL737__BAD_RECV1_PIPE");
|
|
break;
|
|
case EL737__BAD_RNG:
|
|
strcpy(pBuffer,"EL737__BAD_RNG");
|
|
break;
|
|
case EL737__BAD_SEND:
|
|
strcpy(pBuffer,"EL737__BAD_SEND");
|
|
break;
|
|
case EL737__BAD_SEND_PIPE:
|
|
strcpy(pBuffer,"EL737__BAD_SEND_PIPE");
|
|
break;
|
|
case EL737__BAD_SEND_NET:
|
|
strcpy(pBuffer,"EL737__BAD_SEND_NET");
|
|
break;
|
|
case EL737__BAD_SEND_UNKN:
|
|
strcpy(pBuffer,"EL737__BAD_SEND_UNKN");
|
|
break;
|
|
case EL737__BAD_SENDLEN:
|
|
strcpy(pBuffer,"EL737__BAD_SENDLEN");
|
|
break;
|
|
case EL737__BAD_SOCKET:
|
|
strcpy(pBuffer,"EL737__BAD_SOCKET");
|
|
break;
|
|
case EL737__BAD_TMO:
|
|
strcpy(pBuffer,"EL737__BAD_TMO");
|
|
break;
|
|
case EL737__FORCED_CLOSED:
|
|
strcpy(pBuffer,"EL737__FORCED_CLOSED");
|
|
break;
|
|
case EL737__BAD_ASYNSRV:
|
|
strcpy(pBuffer,"EL737__BAD_ASYNSRV");
|
|
break;
|
|
default:
|
|
sprintf(pBuffer,"Unknown EL737 error %d", iErr);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL737GetError(struct __COUNTER *self, int *iCode,
|
|
char *error, int iErrLen)
|
|
{
|
|
char *pErr = NULL;
|
|
int iC1, iC2, iC3;
|
|
char pBueffel[256];
|
|
|
|
if(self->iErrorCode == UNKNOWNPAR)
|
|
{
|
|
strncpy(error,"unknown internal parameter code",iErrLen);
|
|
*iCode = self->iErrorCode;
|
|
self->iErrorCode = 0;
|
|
return 1;
|
|
}
|
|
else if(self->iErrorCode == BADCOUNTER)
|
|
{
|
|
strncpy(error,"monitor cannot be selected",iErrLen);
|
|
*iCode = self->iErrorCode;
|
|
self->iErrorCode = 0;
|
|
return 1;
|
|
}
|
|
|
|
EL737_ErrInfo(&pErr,&iC1,&iC2, &iC3);
|
|
EL737Error2Text(pBueffel,iC1);
|
|
|
|
strncpy(error,pBueffel,iErrLen);
|
|
*iCode = iC1;
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int EL737TryAndFixIt(struct __COUNTER *self, int iCode)
|
|
{
|
|
EL737st *pEL737;
|
|
int iRet;
|
|
char pCommand[50], pReply[50];
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
switch(iCode)
|
|
{
|
|
case EL737__BAD_ILLG:
|
|
case EL737__BAD_ADR:
|
|
case EL737__BAD_PAR:
|
|
case EL737__BAD_TMO:
|
|
case EL737__BAD_REPLY:
|
|
case EL737__BAD_SNTX:
|
|
case EL737__BAD_OVFL:
|
|
return COREDO;
|
|
break;
|
|
case EL737__BAD_BSY:
|
|
strcpy(pCommand,"S \r");
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49);
|
|
if(iRet < 0)
|
|
{
|
|
return COTERM;
|
|
}
|
|
else
|
|
{
|
|
return COREDO;
|
|
}
|
|
break;
|
|
case EL737__BAD_LOC:
|
|
strcpy(pCommand,"rmt 1\r");
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49);
|
|
if(iRet < 0)
|
|
{
|
|
return COTERM;
|
|
}
|
|
strcpy(pCommand,"echo 2\r");
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49);
|
|
if(iRet < 0)
|
|
{
|
|
return COTERM;
|
|
}
|
|
strcpy(pCommand,"ra\r");
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49);
|
|
if(iRet < 0)
|
|
{
|
|
return COTERM;
|
|
}
|
|
return COREDO;
|
|
break;
|
|
case EL737__BAD_DEV:
|
|
case EL737__BAD_ID:
|
|
case EL737__BAD_NOT_BCD:
|
|
case UNKNOWNPAR:
|
|
case BADCOUNTER:
|
|
return COTERM;
|
|
break;
|
|
case EL737__FORCED_CLOSED:
|
|
iRet = EL737_Open(&pEL737->pData,pEL737->host, pEL737->iPort,
|
|
pEL737->iChannel);
|
|
if(iRet == 1)
|
|
{
|
|
return COREDO;
|
|
}
|
|
else
|
|
{
|
|
return COTERM;
|
|
}
|
|
break;
|
|
case EL737__BAD_OFL:
|
|
EL737_Close(&pEL737->pData,0);
|
|
iRet = EL737_Open(&pEL737->pData,pEL737->host, pEL737->iPort,
|
|
pEL737->iChannel);
|
|
if(iRet == 1)
|
|
{
|
|
return COREDO;
|
|
}
|
|
else
|
|
{
|
|
return COTERM;
|
|
}
|
|
break;
|
|
/* case EL737__BAD_ASYNSRV:
|
|
EL737_Close(&pEL737->pData,1);
|
|
return COREDO;
|
|
*/ default:
|
|
/* try to reopen connection */
|
|
|
|
EL737_Close(&pEL737->pData,1);
|
|
iRet = EL737_Open(&pEL737->pData,pEL737->host, pEL737->iPort,
|
|
pEL737->iChannel);
|
|
if(iRet == 1)
|
|
{
|
|
return COREDO;
|
|
}
|
|
else
|
|
{
|
|
return COTERM;
|
|
}
|
|
break;
|
|
}
|
|
return COTERM;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Set(struct __COUNTER *self, int iCode, int iCter,
|
|
float fVal)
|
|
{
|
|
int iRet;
|
|
EL737st *pEL737;
|
|
char pCommand[80],pReply[80];
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
if(iCode == PARTHRESHOLD)
|
|
{
|
|
sprintf(pCommand,"DL %1.1d %f\r",iCter,fVal);
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,79);
|
|
if(iRet == 1)
|
|
{
|
|
if(pCommand[0] == '?')
|
|
{
|
|
self->iErrorCode = BADCOUNTER;
|
|
return HWFault;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
sprintf(pCommand,"DR %1.1d \r",iCter);
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,79);
|
|
if(iRet == 1)
|
|
{
|
|
if(pCommand[0] == '?')
|
|
{
|
|
self->iErrorCode = BADCOUNTER;
|
|
return HWFault;
|
|
}
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self->iErrorCode = UNKNOWNPAR;
|
|
return HWFault;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Get(struct __COUNTER *self, int iCode, int iCter,
|
|
float *fVal)
|
|
{
|
|
int iRet;
|
|
EL737st *pEL737;
|
|
char pCommand[80],pReply[80];
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
if(iCode == PARTHRESHOLD)
|
|
{
|
|
sprintf(pCommand,"DL %1.1d\r",iCter);
|
|
iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,79);
|
|
if(iRet == 1)
|
|
{
|
|
if(pReply[0] == '?')
|
|
{
|
|
self->iErrorCode = BADCOUNTER;
|
|
return HWFault;
|
|
}
|
|
sscanf(pReply,"%f",fVal);
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
return HWFault;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self->iErrorCode = UNKNOWNPAR;
|
|
return HWFault;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EL737Send(struct __COUNTER *self, char *pText, char *pReply,
|
|
int iReplyLen)
|
|
{
|
|
EL737st *pEL737;
|
|
char pBuffer[256];
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
/* ensure a \r at the end of the text */
|
|
if(strlen(pText) > 254)
|
|
{
|
|
strncpy(pReply,"Command to long",iReplyLen);
|
|
return 1;
|
|
}
|
|
strcpy(pBuffer,pText);
|
|
if(strchr(pBuffer,(int)'\r') == NULL)
|
|
{
|
|
strcat(pBuffer,"\r");
|
|
}
|
|
|
|
return EL737_SendCmnd(&pEL737->pData,pBuffer,pReply,iReplyLen);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
pCounterDriver NewEL737Counter(char *name, char *host, int iPort, int iChannel)
|
|
{
|
|
pCounterDriver pRes = NULL;
|
|
EL737st *pData = NULL;
|
|
int iRet;
|
|
int iC1, iC2, iC3;
|
|
char *pErr;
|
|
char pBueffel[132];
|
|
|
|
pRes = CreateCounterDriver(name, "EL737");
|
|
if(!pRes)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* open connection to counter */
|
|
pData = (EL737st *)malloc(sizeof(EL737st));
|
|
if(!pData)
|
|
{
|
|
DeleteCounterDriver(pRes);
|
|
return NULL;
|
|
}
|
|
pData->host = strdup(host);
|
|
pData->iPort = iPort;
|
|
pData->iChannel = iChannel;
|
|
pData->pData = NULL;
|
|
iRet = EL737_Open(&(pData->pData), host,iPort,iChannel);
|
|
if(iRet != 1)
|
|
{
|
|
EL737_ErrInfo(&pErr,&iC1,&iC2, &iC3);
|
|
DeleteCounterDriver(pRes);
|
|
if(pData->host)
|
|
{
|
|
free(pData->host);
|
|
}
|
|
return NULL;
|
|
}
|
|
pRes->pData = (void *)pData;
|
|
|
|
/* assign functions */
|
|
pRes->GetStatus = EL737GetStatus;
|
|
pRes->Start = EL737Start;
|
|
pRes->Halt = EL737Halt;
|
|
pRes->ReadValues = EL737ReadValues;
|
|
pRes->GetError = EL737GetError;
|
|
pRes->TryAndFixIt = EL737TryAndFixIt;
|
|
pRes->Pause = EL737Pause;
|
|
pRes->Continue = EL737Continue;
|
|
pRes->Set = EL737Set;
|
|
pRes->Get = EL737Get;
|
|
pRes->Send = EL737Send;
|
|
pRes->iNoOfMonitors = 7;
|
|
pRes->fTime = 0.;
|
|
|
|
return pRes;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
void KillEL737Counter(pCounterDriver self)
|
|
{
|
|
EL737st *pEL737 = NULL;
|
|
|
|
assert(self);
|
|
pEL737 = (EL737st *)self->pData;
|
|
assert(pEL737);
|
|
|
|
EL737_Close(&pEL737->pData,0);
|
|
if(pEL737->host)
|
|
{
|
|
free(pEL737->host);
|
|
}
|
|
DeleteCounterDriver(self);
|
|
}
|
|
|