
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
307 lines
6.7 KiB
C
307 lines
6.7 KiB
C
/*--------------------------------------------------------------------------
|
|
This is a counter for use in automated regression tests.
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, September 2006
|
|
|
|
Added generating a gaussian for scan testing
|
|
|
|
Mark Koennecke, April 2013
|
|
----------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <time.h>
|
|
#include "fortify.h"
|
|
#include <string.h>
|
|
#include "sics.h"
|
|
#include "countdriv.h"
|
|
/*---------------------------------- possible error types ------------------*/
|
|
#define NONE 0
|
|
#define STARTFAIL 1
|
|
#define STATUSFAIL 2
|
|
#define PAUSEFAIL 3
|
|
#define CONTFAIL 4
|
|
#define READFAIL 5
|
|
#define GAUSS 6
|
|
|
|
#define STATEIDLE 0
|
|
#define STATERUN 1
|
|
#define STATEPAU 2
|
|
/*---------------------------- for generating a gaussian -------------------*/
|
|
#define FWHM 2.5
|
|
#define POS 6.
|
|
#define HEIGHT 100.
|
|
/*--------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
int errType;
|
|
int recover;
|
|
int state;
|
|
time_t endTime;
|
|
int startCount;
|
|
} RegressSt;
|
|
/*---------------------------------------------------------------------------*/
|
|
static int RegressGetStatus(struct __COUNTER *self, float *fControl)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
time_t tD, tDe;
|
|
int iRun;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->errType == STATUSFAIL) {
|
|
return HWFault;
|
|
}
|
|
if (time(NULL) > pSim->endTime) {
|
|
pSim->state = STATEIDLE;
|
|
}
|
|
switch (pSim->state) {
|
|
case STATEIDLE:
|
|
return HWIdle;
|
|
break;
|
|
case STATERUN:
|
|
return HWBusy;
|
|
break;
|
|
case STATEPAU:
|
|
return HWPause;
|
|
break;
|
|
}
|
|
assert(0);
|
|
return HWFault;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int RegressStart(struct __COUNTER *self)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
time_t tD;
|
|
int iRun;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->errType == STARTFAIL) {
|
|
return HWFault;
|
|
}
|
|
pSim->state = STATERUN;
|
|
if (self->eMode == eTimer) {
|
|
pSim->endTime = time(NULL) + (int) self->fPreset;
|
|
} else {
|
|
pSim->endTime = time(NULL) + 7;
|
|
}
|
|
pSim->startCount++;
|
|
|
|
return OKOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int RegressPause(struct __COUNTER *self)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
time_t tD;
|
|
int iRun;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->errType == PAUSEFAIL) {
|
|
return HWFault;
|
|
}
|
|
|
|
pSim->state = STATEPAU;
|
|
|
|
return OKOK;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int RegressContinue(struct __COUNTER *self)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->errType == CONTFAIL) {
|
|
return HWFault;
|
|
}
|
|
|
|
pSim->state = STATERUN;
|
|
|
|
return OKOK;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int RegressHalt(struct __COUNTER *self)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
pSim->state = STATEIDLE;
|
|
|
|
return OKOK;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int RegressReadValues(struct __COUNTER *self)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
int i;
|
|
float stddev, tmp, y;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->errType == READFAIL) {
|
|
return HWFault;
|
|
}
|
|
|
|
for (i = 0; i < MAXCOUNT; i++) {
|
|
self->lCounts[i] = i * 10 + 5;
|
|
}
|
|
if(pSim->errType == GAUSS){
|
|
stddev = FWHM/2.254;
|
|
tmp = ((float)pSim->startCount - POS)/stddev;
|
|
y = HEIGHT*exp(-.5*tmp*tmp);
|
|
self->lCounts[0] = (long)y + 10;
|
|
}
|
|
self->lCounts[1] = self->fPreset;
|
|
self->fTime = self->fPreset;
|
|
return OKOK;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int RegressGetError(struct __COUNTER *self, int *iCode, char *error,
|
|
int iErrLen)
|
|
{
|
|
strlcpy(error, "Regression counter error", iErrLen);
|
|
*iCode = 1;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int RegressTryAndFixIt(struct __COUNTER *self, int iCode)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (pSim->recover == 1) {
|
|
pSim->errType = NONE;
|
|
return COREDO;
|
|
} else {
|
|
return COTERM;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int RegressSet(struct __COUNTER *self, char *name, int iCter,
|
|
float FVal)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (strcmp(name, "errortype") == 0) {
|
|
pSim->errType = (int) FVal;
|
|
if(pSim->errType == GAUSS){
|
|
pSim->startCount = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
if (strcmp(name, "recover") == 0) {
|
|
pSim->recover = (int) FVal;
|
|
return 1;
|
|
}
|
|
if (strcmp(name, "finish") == 0) {
|
|
pSim->state = STATEIDLE;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int RegressGet(struct __COUNTER *self, char *name,
|
|
int iCter, float *fVal)
|
|
{
|
|
RegressSt *pSim = NULL;
|
|
|
|
assert(self);
|
|
pSim = (RegressSt *) self->pData;
|
|
assert(pSim);
|
|
|
|
if (strcmp(name, "errortype") == 0) {
|
|
*fVal = pSim->errType;
|
|
return 1;
|
|
}
|
|
if (strcmp(name, "recover") == 0) {
|
|
*fVal = pSim->recover;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int RegressSend(struct __COUNTER *self, char *pText,
|
|
char *pReply, int iReplyLen)
|
|
{
|
|
strlcpy(pReply, "Simulated response", iReplyLen);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
pCounterDriver NewRegressCounter(char *name)
|
|
{
|
|
pCounterDriver pRes = NULL;
|
|
RegressSt *pData = NULL;
|
|
int iRet;
|
|
int iC1, iC2, iC3;
|
|
char *pErr;
|
|
char pBueffel[132];
|
|
|
|
pRes = CreateCounterDriver(name, "Regress");
|
|
if (!pRes) {
|
|
return NULL;
|
|
}
|
|
|
|
pData = (RegressSt *) malloc(sizeof(RegressSt));
|
|
if (!pData) {
|
|
DeleteCounterDriver(pRes);
|
|
return NULL;
|
|
}
|
|
memset(pData, 0, sizeof(RegressSt));
|
|
pRes->pData = pData;
|
|
|
|
/*
|
|
* assign functions
|
|
*/
|
|
pRes->GetStatus = RegressGetStatus;
|
|
pRes->Start = RegressStart;
|
|
pRes->Halt = RegressHalt;
|
|
pRes->ReadValues = RegressReadValues;
|
|
pRes->GetError = RegressGetError;
|
|
pRes->TryAndFixIt = RegressTryAndFixIt;
|
|
pRes->Pause = RegressPause;
|
|
pRes->Continue = RegressContinue;
|
|
pRes->Set = RegressSet;
|
|
pRes->Get = RegressGet;
|
|
pRes->Send = RegressSend;
|
|
pRes->KillPrivate = NULL;
|
|
pRes->iNoOfMonitors = 8;
|
|
|
|
return pRes;
|
|
}
|