Cleaned up ANSTO code to merge with sinqdev.sics
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
This commit is contained in:
308
countersec.c
308
countersec.c
@@ -9,10 +9,13 @@
|
||||
*
|
||||
* Mark Koennecke, February 2009
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <sics.h>
|
||||
#include <counter.h>
|
||||
#include "sicshipadaba.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* defines for commmands
|
||||
* -------------------------------------------------------------------------*/
|
||||
@@ -26,6 +29,19 @@ typedef struct {
|
||||
float fCurrent;
|
||||
char *pName;
|
||||
} MonEvent, *pMonEvent;
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void SecCounterSetError(pCounter self, char *text)
|
||||
{
|
||||
hdbValue v;
|
||||
pHdb node;
|
||||
|
||||
node = GetHipadabaNode(self->pDes->parNode, "error");
|
||||
if(node != NULL){
|
||||
v = MakeHdbText(strdup(text));
|
||||
UpdateHipadabaPar(node,v,NULL);
|
||||
ReleaseHdbValue(&v);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code)
|
||||
{
|
||||
@@ -52,7 +68,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
{
|
||||
pCounter self = (pCounter)pData;
|
||||
int status;
|
||||
pHdb node;
|
||||
pHdb node, statusNode;
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
@@ -60,14 +76,14 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
return 0;
|
||||
}
|
||||
|
||||
statusNode = GetHipadabaNode(self->pDes->parNode, "status");
|
||||
UpdateHipadabaPar(statusNode,MakeHdbText("run"), pCon);
|
||||
status = SecCtrInvokeFunction(self,pCon, START);
|
||||
self->haltFixFlag = 0;
|
||||
if(status == 1){
|
||||
self->isUpToDate = 0;
|
||||
self->badStatusCount = 0;
|
||||
self->tStart = time(NULL);
|
||||
node = GetHipadabaNode(self->pDes->parNode, "status");
|
||||
UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
|
||||
node = GetHipadabaNode(self->pDes->parNode, "control");
|
||||
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
|
||||
SetHdbProperty(node,"geterror", NULL);
|
||||
@@ -79,8 +95,10 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
node = GetHipadabaNode(self->pDes->parNode, "time");
|
||||
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
|
||||
InvokeCallBack(self->pCall,COUNTSTART, pCon);
|
||||
SecCounterSetError(self,"None");
|
||||
return 1;
|
||||
} else {
|
||||
UpdateHipadabaPar(statusNode,MakeHdbText("error"), pCon);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
return HWFault;
|
||||
}
|
||||
@@ -104,85 +122,96 @@ static int SecContinue(void *pData, SConnection *pCon)
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int SecCtrCheckStatus(void *pData, SConnection *pCon)
|
||||
{
|
||||
pCounter self = (pCounter)pData;
|
||||
pHdb node = NULL, control = NULL;
|
||||
hdbValue v;
|
||||
int status;
|
||||
MonEvent sMon;
|
||||
float fControl, fPreset;
|
||||
pCounter self = (pCounter)pData;
|
||||
pHdb node = NULL, control = NULL;
|
||||
hdbValue v;
|
||||
int status;
|
||||
MonEvent sMon;
|
||||
float fControl, fPreset;
|
||||
char error[132];
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
assert(self != NULL);
|
||||
node = GetHipadabaNode(self->pDes->parNode,"status");
|
||||
assert(node != NULL);
|
||||
status = GetHipadabaPar(node,&v,pCon);
|
||||
|
||||
node = GetHipadabaNode(self->pDes->parNode,"status");
|
||||
assert(node != NULL);
|
||||
status = GetHipadabaPar(node,&v,pCon);
|
||||
if(status != 1){
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
if(status != 1){
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
if(v.v.text == NULL){
|
||||
return HWBusy;
|
||||
}
|
||||
if (strstr(v.v.text, "idle") != NULL) {
|
||||
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
status = HWIdle;
|
||||
} else if (strstr(v.v.text, "run") != NULL) {
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "nobeam") != NULL) {
|
||||
status = HWNoBeam;
|
||||
} else if (strstr(v.v.text, "pause") != NULL) {
|
||||
status = HWPause;
|
||||
} else if (strstr(v.v.text, "error") != NULL) {
|
||||
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
status = HWFault;
|
||||
} else {
|
||||
SCPrintf(pCon, eError, "ERROR: unknown counter status %s found",
|
||||
v.v.text);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
status = HWFault;
|
||||
}
|
||||
ReleaseHdbValue(&v);
|
||||
if(v.v.text == NULL){
|
||||
return HWBusy;
|
||||
}
|
||||
if (strstr(v.v.text, "idle") != NULL) {
|
||||
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
status = HWIdle;
|
||||
} else if (strstr(v.v.text, "run") != NULL) {
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "nobeam") != NULL) {
|
||||
status = HWNoBeam;
|
||||
} else if (strstr(v.v.text, "pause") != NULL) {
|
||||
status = HWPause;
|
||||
} else if (strstr(v.v.text, "restart") != NULL) {
|
||||
SecStartCount(self, pCon);
|
||||
return HWBusy;
|
||||
} else if (strstr(v.v.text, "error") != NULL) {
|
||||
InvokeCallBack(self->pCall, COUNTEND, NULL);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
if(GetHdbProperty(node,"geterror",error,sizeof(error)) == 1){
|
||||
SCPrintf(pCon,eError,"ERROR: %s", error);
|
||||
SecCounterSetError(self,error);
|
||||
} else {
|
||||
SecCounterSetError(self,"Undefined counter error: set status geterror");
|
||||
SCPrintf(pCon,eError,"ERROR: Unknown counter status error: set status geterror property");
|
||||
}
|
||||
status = HWFault;
|
||||
} else {
|
||||
SCPrintf(pCon, eError, "ERROR: unknown counter status %s found",
|
||||
v.v.text);
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
status = HWFault;
|
||||
}
|
||||
ReleaseHdbValue(&v);
|
||||
|
||||
|
||||
node = GetHipadabaNode(self->pDes->parNode,"control");
|
||||
assert(node != NULL);
|
||||
GetHipadabaPar(node,&v,pCon);
|
||||
fControl = v.v.doubleValue;
|
||||
node = GetHipadabaNode(self->pDes->parNode,"preset");
|
||||
assert(node != NULL);
|
||||
GetHipadabaPar(node,&v,pCon);
|
||||
fPreset = v.v.doubleValue;
|
||||
node = GetHipadabaNode(self->pDes->parNode,"control");
|
||||
assert(node != NULL);
|
||||
GetHipadabaPar(node,&v,pCon);
|
||||
fControl = v.v.doubleValue;
|
||||
node = GetHipadabaNode(self->pDes->parNode,"preset");
|
||||
assert(node != NULL);
|
||||
GetHipadabaPar(node,&v,pCon);
|
||||
fPreset = v.v.doubleValue;
|
||||
|
||||
sMon.fCurrent = fControl;
|
||||
sMon.fPreset = fPreset;
|
||||
sMon.pName = self->name;
|
||||
self->badStatusCount = 0;
|
||||
sMon.fCurrent = fControl;
|
||||
sMon.fPreset = fPreset;
|
||||
sMon.pName = self->name;
|
||||
self->badStatusCount = 0;
|
||||
|
||||
/*
|
||||
* check for overrun counter boxes
|
||||
*/
|
||||
if(self->getMode(self) == eTimer &&
|
||||
(sMon.fCurrent > sMon.fPreset +1)
|
||||
&& self->haltFixFlag == 0){
|
||||
SecCtrHalt(self);
|
||||
self->haltFixFlag = 1;
|
||||
}
|
||||
/*
|
||||
* check for overrun counter boxes
|
||||
*/
|
||||
if(self->getMode(self) == eTimer &&
|
||||
(sMon.fCurrent > sMon.fPreset +1)
|
||||
&& self->haltFixFlag == 0){
|
||||
SecCtrHalt(self);
|
||||
self->haltFixFlag = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* invoke notifiactions, if necessary
|
||||
*/
|
||||
if (self->iCallbackCounter > 20) {
|
||||
InvokeCallBack(self->pCall, MONITOR, &sMon);
|
||||
self->iCallbackCounter = 0;
|
||||
} else {
|
||||
self->iCallbackCounter++;
|
||||
}
|
||||
/*
|
||||
* invoke notifiactions, if necessary
|
||||
*/
|
||||
if (self->iCallbackCounter > 20) {
|
||||
InvokeCallBack(self->pCall, MONITOR, &sMon);
|
||||
self->iCallbackCounter = 0;
|
||||
} else {
|
||||
self->iCallbackCounter++;
|
||||
}
|
||||
|
||||
return status;
|
||||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------
|
||||
* Here is an issue: this ought to wait until data has arrived. Callers
|
||||
@@ -193,6 +222,12 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
|
||||
* - add an update callback which deletes the property when done.
|
||||
* - Check that property or the geterror property here in a loop
|
||||
* until done or we timeout.
|
||||
*
|
||||
* Nope! Update October 2013:
|
||||
* How it is normally done is to read the data through scripcontext when
|
||||
* counting is finished and not to finish with counting until this has
|
||||
* been done. The code below is only usefule for non scriptcontext
|
||||
* drivers.
|
||||
* -----------------------------------------------------------------------*/
|
||||
static int SecCtrTransferData(void *pData, SConnection *pCon)
|
||||
{
|
||||
@@ -373,25 +408,68 @@ static int CountCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
float preset;
|
||||
pHdb presetNode = NULL;
|
||||
|
||||
if(nPar < 1){
|
||||
return 0;
|
||||
presetNode = GetHipadabaNode(ccmd->objectNode,"preset");
|
||||
if(presetNode != NULL){
|
||||
preset = presetNode->value.v.doubleValue;
|
||||
} else {
|
||||
/*
|
||||
This can really only happen when the counter is corrupt
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
preset = par[0]->value.v.doubleValue;
|
||||
}
|
||||
|
||||
preset = par[0]->value.v.doubleValue;
|
||||
return DoCount((pCounter)ccmd, preset, con, 1);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int GetMonitorCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
long counts;
|
||||
pCounter self = (pCounter)ccmd;
|
||||
if(nPar < 1) {
|
||||
SCWrite(con,"ERROR: missing monitor no in getmonitor",eError);
|
||||
return 0;
|
||||
}
|
||||
counts = self->getMonitor(self,par[0]->value.v.intValue,con);
|
||||
SCPrintf(con,eValue,"%s.monitor.%d = %ld", self->name,
|
||||
par[0]->value.v.intValue,counts);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int GetCountsCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
long counts;
|
||||
pCounter self = (pCounter)ccmd;
|
||||
counts = self->getCounts(self,con);
|
||||
SCPrintf(con,eValue,"%s.counts = %ld", self->name,counts);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int CountNBCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
float preset;
|
||||
pHdb presetNode = NULL;
|
||||
|
||||
if(nPar < 1){
|
||||
return 0;
|
||||
presetNode = GetHipadabaNode(ccmd->objectNode,"preset");
|
||||
if(presetNode != NULL){
|
||||
preset = presetNode->value.v.doubleValue;
|
||||
} else {
|
||||
/*
|
||||
This can really only happen when the counter is corrupt
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
preset = par[0]->value.v.doubleValue;
|
||||
}
|
||||
|
||||
preset = par[0]->value.v.doubleValue;
|
||||
return DoCount((pCounter)ccmd, preset, con, 0);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -415,6 +493,55 @@ static int ContinueCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
pCounter self = (pCounter)ccmd;
|
||||
return self->pCountInt->Continue(self,con);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
extern int CounterInterest(int iEvent, void *pEvent, void *pUser);
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int InterestCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
long lID;
|
||||
pCounter self = (pCounter)ccmd;
|
||||
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
|
||||
SCCopyConnection(con), SCDeleteConnection);
|
||||
SCSendOK(con);
|
||||
return 1;
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int CountStatusCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
Hdb * cmdNode, Hdb * par[], int nPar)
|
||||
{
|
||||
float preset, done;
|
||||
int exponent;
|
||||
pHdb node, data;
|
||||
|
||||
node = GetHipadabaNode(ccmd->objectNode,"preset");
|
||||
assert(node != NULL);
|
||||
preset = node->value.v.doubleValue;
|
||||
|
||||
node = GetHipadabaNode(ccmd->objectNode,"mode");
|
||||
assert(node != NULL);
|
||||
strtolower(node->value.v.text);
|
||||
if(strcmp(node->value.v.text,"timer") == 0) {
|
||||
data = GetHipadabaNode(ccmd->objectNode,"time");
|
||||
assert(data != NULL);
|
||||
done = data->value.v.doubleValue;
|
||||
} else {
|
||||
data = GetHipadabaNode(ccmd->objectNode,"values");
|
||||
assert(data != NULL);
|
||||
done = data->value.v.intArray[0];
|
||||
data = GetHipadabaNode(ccmd->objectNode,"exponent");
|
||||
assert(data != NULL);
|
||||
exponent = data->value.v.intValue;
|
||||
if(exponent != 0){
|
||||
done /= pow(10,exponent);
|
||||
}
|
||||
}
|
||||
SCPrintf(con,eValue,"%s.CountStatus = %f %f",
|
||||
ccmd->objectNode->name, preset, done);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
{
|
||||
@@ -491,6 +618,9 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
return NULL;
|
||||
}
|
||||
SetHdbProperty(child, "__save", "true");
|
||||
SetHdbProperty(child, "values", "timer,monitor");
|
||||
PrependHipadabaCallback(child,MakeHipadabaCallback(SICSValueCheckCallback,
|
||||
NULL,NULL));
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle"));
|
||||
@@ -499,6 +629,12 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
}
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("error", usInternal, MakeHdbText("None"));
|
||||
if (child == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("control", usUser, MakeHdbFloat(.0));
|
||||
if (child == NULL) {
|
||||
return NULL;
|
||||
@@ -512,15 +648,29 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
}
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("exponent", usUser,
|
||||
MakeHdbInt(0));
|
||||
if (child == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SetHdbProperty(child, "__save", "true");
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = AddSICSHdbPar(node,"count", usUser, MakeSICSFunc(CountCmd));
|
||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
||||
|
||||
child = AddSICSHdbPar(node,"countnb", usUser, MakeSICSFunc(CountNBCmd));
|
||||
AddSICSHdbPar(child, "preset", usUser, MakeHdbFloat(2));
|
||||
|
||||
child = AddSICSHdbPar(node,"getmonitor", usSpy, MakeSICSFunc(GetMonitorCmd));
|
||||
AddSICSHdbPar(child, "no", usSpy, MakeHdbInt(1));
|
||||
child = AddSICSHdbPar(node,"getcounts", usUser, MakeSICSFunc(GetCountsCmd));
|
||||
|
||||
child = AddSICSHdbPar(node,"stop", usUser, MakeSICSFunc(StopCmd));
|
||||
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
|
||||
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
|
||||
child = AddSICSHdbPar(node,"interest", usUser, MakeSICSFunc(InterestCmd));
|
||||
child = AddSICSHdbPar(node,"countstatus", usUser, MakeSICSFunc(CountStatusCmd));
|
||||
|
||||
return pRes;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user