Add NHQ200 HV Power Supply Driver

r1385 | dcl | 2006-12-21 17:50:19 +1100 (Thu, 21 Dec 2006) | 2 lines
This commit is contained in:
Douglas Clowes
2006-12-21 17:50:19 +11:00
parent 5c550dd169
commit a488705540
8 changed files with 1481 additions and 2 deletions

488
site_ansto/nhq200driv.c Normal file
View File

@@ -0,0 +1,488 @@
/*--------------------------------------------------------------------------
N H Q 2 0 0 D R I V
This file contains the implementation of a driver for the
NHQ 200 Voltage controller.
Mark Koennecke, Juli 1997
Mark Lesha, January 2006 (based on ITC4 code)
Douglas Clowes, December 2006 (based on LAKESHORE340 code)
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 <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <assert.h>
#include <fortify.h>
#include <conman.h>
#include <servlog.h>
#include <fortify.h>
typedef struct __EVDriver *pEVDriver;
#include <evdriver.i>
/* Do we need these ?
#include <sics.h>
#include <modriv.h>
*/
#include <rs232controller.h>
#include "hardsup/nhq200util.h"
#include "hardsup/el734_def.h"
#include "hardsup/el734fix.h"
#define SHITTYVALUE -777
/*------------------------- The Driver ------------------------------------*/
pEVDriver CreateNHQ200Driver(int argc, char *argv[]);
int ConfigNHQ200(pEVDriver self);
/*-----------------------------------------------------------------------*/
typedef struct {
pNHQ200 pData;
char *pHost;
int iPort;
int iChannel;
int iControl; /* NHQ200 control */
float fDiv;
float fMult;
int iRead; /* NHQ200 sensor */
int iTmo;
int iLastError;
} NHQ200Driv, *pNHQ200Driv;
/*----------------------------------------------------------------------------*/
static int GetNHQ200Pos(pEVDriver self, float *fPos)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv)self->pPrivate;
assert(pMe);
iRet = NHQ200_Read(&pMe->pData,fPos);
if(iRet <= 0 )
{
pMe->iLastError = iRet;
return 0;
}
if( (*fPos < 0) || (*fPos > 10000) )
{
*fPos = -999.;
pMe->iLastError = SHITTYVALUE;
return 0;
}
return 1;
}
/*----------------------------------------------------------------------------*/
static int NHQ200Run(pEVDriver self, float fVal)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
iRet = NHQ200_Set(&pMe->pData,fVal);
if(iRet != 1)
{
pMe->iLastError = iRet;
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int NHQ200Error(pEVDriver self, int *iCode, char *error, int iErrLen)
{
pNHQ200Driv pMe = NULL;
assert(self);
pMe = (pNHQ200Driv)self->pPrivate;
assert(pMe);
*iCode = pMe->iLastError;
if(pMe->iLastError == SHITTYVALUE)
{
strncpy(error,"Invalid temperature returned form NHQ200, check sensor",iErrLen);
}
else
{
NHQ200_ErrorTxt(&pMe->pData,pMe->iLastError,error,iErrLen);
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int NHQ200Send(pEVDriver self, char *pCommand, char *pReply, int iLen)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
iRet = NHQ200_Send(&pMe->pData,pCommand, pReply,iLen);
if(iRet <= 0)
{
pMe->iLastError = iRet;
return 0;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int NHQ200Init(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
pMe->pData = NULL;
iRet = NHQ200_Open(&pMe->pData, pMe->pHost, pMe->iRead, pMe->iControl,0);
if(iRet != 1)
{
if(iRet == NHQ200__NONHQ200)
{
return -1;
}
else
{
pMe->iLastError = iRet;
return 0;
}
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int NHQ200Close(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
NHQ200_Close(&pMe->pData);
return 1;
}
/*---------------------------------------------------------------------------*/
static int NHQ200Fix(pEVDriver self, int iError)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
switch(iError)
{
/* network errors */
case EL734__BAD_FLUSH:
case EL734__BAD_RECV:
case EL734__BAD_RECV_NET:
case EL734__BAD_RECV_UNKN:
case EL734__BAD_RECVLEN:
case EL734__BAD_RECV1:
case EL734__BAD_RECV1_PIPE:
case EL734__BAD_RNG:
case EL734__BAD_SEND:
case EL734__BAD_SEND_PIPE:
case EL734__BAD_SEND_NET:
case EL734__BAD_SEND_UNKN:
case EL734__BAD_SENDLEN:
NHQ200Close(self);
iRet = NHQ200Init(self);
if(iRet)
{
return DEVREDO;
}
else
{
return DEVFAULT;
}
break;
/* handable protocoll errors */
case EL734__BAD_TMO:
return DEVREDO;
break;
case -501: /* Bad_COM */
return DEVREDO;
case -504: /* Badly formatted */
return DEVREDO;
default:
return DEVFAULT;
break;
}
return DEVFAULT;
}
/*--------------------------------------------------------------------------*/
static int NHQ200Halt(pEVDriver *self)
{
assert(self);
return 1;
}
/*------------------------------------------------------------------------*/
void KillNHQ200(void *pData)
{
pNHQ200Driv pMe = NULL;
pMe = (pNHQ200Driv)pData;
assert(pMe);
if(pMe->pHost)
{
free(pMe->pHost);
}
free(pMe);
}
/*------------------------------------------------------------------------*/
pEVDriver CreateNHQ200Driver(int argc, char *argv[])
{
pEVDriver pNew = NULL;
pNHQ200Driv pSim = NULL;
/* check for arguments */
if(argc < 3)
{
return NULL;
}
pNew = CreateEVDriver(argc,argv);
pSim = (pNHQ200Driv)malloc(sizeof(NHQ200Driv));
memset(pSim,0,sizeof(NHQ200Driv));
if(!pNew || !pSim)
{
return NULL;
}
pNew->pPrivate = pSim;
pNew->KillPrivate = KillNHQ200;
/* initalise pNHQ200Driver */
pSim->iControl = atoi(argv[2]);
pSim->iRead = atoi(argv[1]);
pSim->iLastError = 0;
pSim->iTmo = 10;
/* The NHQ200 doesn't require divisors or multipliers
and they are always forced to 1.0 */
pSim->fDiv = 1.0;
pSim->fMult = 1.0;
pSim->pHost = strdup(argv[0]);
pSim->iPort = 0;
pSim->iChannel = 0;
/* initialise function pointers */
pNew->SetValue = NHQ200Run;
pNew->GetValue = GetNHQ200Pos;
pNew->Send = NHQ200Send;
pNew->GetError = NHQ200Error;
pNew->TryFixIt = NHQ200Fix;
pNew->Init = NHQ200Init;
pNew->Close = NHQ200Close;
return pNew;
}
/*--------------------------------------------------------------------------*/
int ConfigNHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
iRet = NHQ200_Config(&pMe->pData, pMe->iTmo, pMe->iRead,
pMe->iControl,pMe->fDiv,pMe->fMult);
if(iRet < 0)
{
pMe->iLastError = iRet;
return 0;
}
return 1;
}
/*-------------------------------------------------------------------------*/
int SetSensorNHQ200(pEVDriver self, int iSensor)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
/* The NHQ200 incorporates two voltage supplies so allow iSensor=1 to 2 */
if( (iSensor < 1) || (iSensor > 2) )
{
return 0;
}
pMe->iRead = iSensor;
pMe->pData->iRead = iSensor;
return 1;
}
/*-------------------------------------------------------------------------*/
int SetControlNHQ200(pEVDriver self, int iSensor)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
/* The NHQ200 incorporates two voltage supplies so allow iSensor=1 to 2 */
if( (iSensor < 1) || (iSensor > 2) )
{
return 0;
}
pMe->iControl = iSensor;
pMe->pData->iControl = iSensor;
return 1;
}
/*-------------------------------------------------------------------------*/
int SetTMONHQ200(pEVDriver self, int iSensor)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
if(iSensor < 10)
{
return 0;
}
pMe->iTmo = iSensor;
return 1;
}
/*-------------------------------------------------------------------------*/
int GetControlNHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
return pMe->iControl;
}
/*-------------------------------------------------------------------------*/
int GetSensorNHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
return pMe->iRead;
}
/*-------------------------------------------------------------------------*/
int GetTMONHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
return pMe->iTmo;
}
/*-------------------------------------------------------------------------*/
float GetDivisorNHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
return pMe->fDiv; /* but forced to 1.0 for NHQ200, not used */
}
/*--------------------------------------------------------------------------*/
int SetDivisorNHQ200(pEVDriver self, float fDiv)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
/* The NHQ200 doesn't need divisor, force to 1.0 */
pMe->fDiv = 1.0; /* fDiv */;
return 1;
}
/*-------------------------------------------------------------------------*/
float GetMultNHQ200(pEVDriver self)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
return pMe->fMult; /* but forced to 1.0 for NHQ200, not used */
}
/*--------------------------------------------------------------------------*/
int SetMultNHQ200(pEVDriver self, float fDiv)
{
pNHQ200Driv pMe = NULL;
int iRet;
assert(self);
pMe = (pNHQ200Driv )self->pPrivate;
assert(pMe);
/* The NHQ200 doesn't need multiplier, force to 1.0 */
pMe->fMult = 1.0; /* fDiv */;
return 1;
}