- Adapted indenation to new agreed upon system

- Added support for second generation scriptcontext based counter
This commit is contained in:
koennecke
2009-02-13 09:00:03 +00:00
parent a3dcad2bfa
commit 91d4af0541
405 changed files with 88101 additions and 88173 deletions

504
countersec.c Normal file
View File

@ -0,0 +1,504 @@
/**
* This is a second generation style counter object. It is supposed to work
* nicely with a scriptcontext to drive the actual hardware. This is supposed
* to interface to single counters and histogram memories. This tries to be
* backwards compatible with the old style counter module; thus some
* fields in the data structure will not be used.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, February 2009
*/
#include <time.h>
#include <sics.h>
#include <counter.h>
#include "sicshipadaba.h"
/*---------------------------------------------------------------------------
* defines for commmands
* -------------------------------------------------------------------------*/
#define START 1000
#define STOP 1001
#define PAUSE 1002
#define CONT 1003
/*---------------------------------------------------------------------------*/
typedef struct {
float fPreset;
float fCurrent;
char *pName;
} MonEvent, *pMonEvent;
/*---------------------------------------------------------------------------*/
static int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code)
{
pHdb node = NULL;
hdbValue v;
node = GetHipadabaNode(self->pDes->parNode, "control");
assert(node != NULL);
v = MakeHdbFloat(code);
return SetHipadabaPar(node,v,pCon);
}
/*---------------------------------------------------------------------------*/
static int SecCtrHalt(void *pData)
{
pCounter self = (pCounter)pData;
assert(self != NULL);
SecCtrInvokeFunction(self,pServ->dummyCon, STOP);
ReleaseCountLock(self->pCountInt);
return 1;
}
/*---------------------------------------------------------------------------*/
static int SecStartCount(void *pData, SConnection *pCon)
{
pCounter self = (pCounter)pData;
int status;
pHdb node;
assert(self != NULL);
if (!GetCountLock(self->pCountInt, pCon)) {
return 0;
}
status = SecCtrInvokeFunction(self,pCon, START);
if(status == 1){
self->isUpToDate = 0;
self->badStatusCount = 0;
self->tStart = time(NULL);
node = GetHipadabaNode(self->pDes->parNode, "status");
UpdateHipadabaPar(node,MakeHdbText("run"), pCon);
SetHdbProperty(node,"geterror", NULL);
InvokeCallBack(self->pCall,COUNTSTART, pCon);
return 1;
} else {
ReleaseCountLock(self->pCountInt);
return HWFault;
}
}
/*---------------------------------------------------------------------------*/
static int SecPause(void *pData, SConnection *pCon)
{
pCounter self = (pCounter)pData;
assert(self != NULL);
return SecCtrInvokeFunction(self,pCon, PAUSE);
}
/*---------------------------------------------------------------------------*/
static int SecContinue(void *pData, SConnection *pCon)
{
pCounter self = (pCounter)pData;
assert(self != NULL);
return SecCtrInvokeFunction(self,pCon, CONT);
}
/*----------------------------------------------------------------------------*/
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;
assert(self != NULL);
node = GetHipadabaNode(self->pDes->parNode,"status");
assert(node != NULL);
status = GetHipadabaPar(node,&v,pCon);
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;
}
/*
* check for overrun timers
*/
if(self->getMode(self) == eTimer &&
time(NULL) > self->tStart + self->getPreset(self)){
SecCtrHalt(self);
}
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;
if (self->iCallbackCounter > 20) {
InvokeCallBack(self->pCall, MONITOR, &sMon);
self->iCallbackCounter = 0;
} else {
self->iCallbackCounter++;
}
return status;
}
/*---------------------------------------------------------------------------
* Here is an issue: this ought to wait until data has arrived. Callers
* think now that the data is up to date. With scriptcontext this may not be
* the case. The update may come later or even never. Perhaps this needs
* to be emulated:
* - set a property to some value when starting
* - 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.
* -----------------------------------------------------------------------*/
static int SecCtrTransferData(void *pData, SConnection *pCon)
{
pCounter self = (pCounter)pData;
assert(self != NULL);
pHdb node = NULL;
hdbValue v;
node = GetHipadabaNode(self->pDes->parNode,"values");
assert(node != NULL);
self->isUpToDate = 1;
return GetHipadabaPar(node,&v,pCon);
}
/*------------------------------------------------------------------------*/
static void *SecCtrCounterGetInterface(void *pData, int iID)
{
pCounter self = NULL;
self = (pCounter) pData;
assert(self);
if (iID == COUNTID) {
return self->pCountInt;
} else if (iID == CALLBACKINTERFACE) {
return self->pCall;
}
return NULL;
}
/*--------------------------------------------------------------------------*/
static int SecCtrSetMode(pCounter self, CounterMode eNew)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"mode");
assert(node != NULL);
switch(eNew){
case eTimer:
v = MakeHdbText("timer");
break;
case ePreset:
v = MakeHdbText("timer");
break;
}
return SetHipadabaPar(node,v,NULL);
}
/*---------------------------------------------------------------------------*/
static CounterMode SecCtrGetMode(pCounter self)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"mode");
assert(node != NULL);
GetHipadabaPar(node,&v,NULL);
assert(v.v.text != NULL);
if(strcmp(v.v.text,"timer") == 0){
return eTimer;
} else {
return ePreset;
}
}
/*--------------------------------------------------------------------------*/
static int SecCtrSetPreset(pCounter self, float val)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"preset");
assert(node != NULL);
v = MakeHdbFloat(val);
return SetHipadabaPar(node,v,NULL);
}
/*--------------------------------------------------------------------------*/
static void SecCtrSetCountParameters(void *pData, float fPreset,
CounterMode eMode)
{
pCounter self = NULL;
assert(pData);
self = (pCounter) pData;
SetCounterPreset(self, fPreset);
SetCounterMode(self, eMode);
}
/*---------------------------------------------------------------------------*/
static float SecCtrGetPreset(pCounter self)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"preset");
assert(node != NULL);
GetHipadabaPar(node,&v,NULL);
return (float)v.v.doubleValue;
}
/*--------------------------------------------------------------------------*/
static int SecCtrGetNMonitor(pCounter self)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"values");
assert(node != NULL);
GetHipadabaPar(node,&v,NULL);
return v.arrayLength;
}
/*--------------------------------------------------------------------------*/
static long SecCtrGetMonitor(pCounter self, int iNum, SConnection *pCon)
{
hdbValue v;
pHdb node = NULL;
if (!self->isUpToDate) {
self->pCountInt->TransferData(self, pCon);
}
node = GetHipadabaNode(self->pDes->parNode,"values");
assert(node != NULL);
GetHipadabaPar(node,&v,pCon);
if(iNum >= 0 && iNum < v.arrayLength){
return (long)v.v.intArray[iNum];
} else {
return -1L;
}
}
/*--------------------------------------------------------------------------*/
static long SecCtrGetCounts(pCounter self, SConnection *pCon)
{
return SecCtrGetMonitor(self,0,pCon);
}
/*--------------------------------------------------------------------------*/
static void SecCtrSetMonitor(pCounter self, int iNum, long val)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"values");
assert(node != NULL);
GetHipadabaPar(node,&v,NULL);
if(iNum >= 0 && iNum < v.arrayLength){
v.v.intArray[iNum] = val;
UpdateHipadabaPar(node,v,NULL);
}
}
/*---------------------------------------------------------------------------*/
static float SecCtrGetTime(pCounter self, SConnection *pCon)
{
hdbValue v;
pHdb node = NULL;
node = GetHipadabaNode(self->pDes->parNode,"time");
assert(node != NULL);
GetHipadabaPar(node,&v,pCon);
return (float)v.v.doubleValue;
}
/*--------------------------------------------------------------------------*/
static int CountCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
float preset;
if(nPar < 1){
return 0;
}
preset = par[0]->value.v.doubleValue;
return DoCount((pCounter)ccmd, preset, con, 1);
}
/*--------------------------------------------------------------------------*/
static int CountNBCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
float preset;
if(nPar < 1){
return 0;
}
preset = par[0]->value.v.doubleValue;
return DoCount((pCounter)ccmd, preset, con, 0);
}
/*--------------------------------------------------------------------------*/
static int StopCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pCounter self = (pCounter)ccmd;
return self->pCountInt->Halt(self);
}
/*--------------------------------------------------------------------------*/
static int PauseCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pCounter self = (pCounter)ccmd;
return self->pCountInt->Pause(self,con);
}
/*--------------------------------------------------------------------------*/
static int ContinueCmd(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar)
{
pCounter self = (pCounter)ccmd;
return self->pCountInt->Continue(self,con);
}
/*--------------------------------------------------------------------------*/
int MakeSecCter(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pCounter pRes = NULL;
int status, length;
pHdb node, child;
if(argc < 3) {
SCWrite(pCon,"ERROR: need at least a name and length to create a counter",
eError);
return 0;
}
length = atoi(argv[2]);
pRes = (pCounter) malloc(sizeof(Counter));
if (!pRes) {
SCWrite(pCon,"ERROR: out of memory in MakeSecCter", eError);
return 0;
}
memset(pRes,0,sizeof(Counter));
pRes->pDes = CreateDescriptor("SingleCounter");
if (!pRes->pDes) {
SCWrite(pCon,"ERROR: out of memory in MakeSecCter", eError);
return 0;
}
/* initialize Descriptor functions */
pRes->pDes->GetInterface = SecCtrCounterGetInterface;
pRes->pDes->SaveStatus = SaveSICSOBJ;
/* initialise countable interface */
pRes->pCountInt = CreateCountableInterface();
if (!pRes->pCountInt) {
DeleteDescriptor(pRes->pDes);
SCWrite(pCon,"ERROR: out of memory in MakeSecCter", eError);
return 0;
}
pRes->pCountInt->SetCountParameters = SecCtrSetCountParameters;
pRes->pCountInt->StartCount = SecStartCount;
pRes->pCountInt->CheckCountStatus = SecCtrCheckStatus;
pRes->pCountInt->TransferData = SecCtrTransferData;
pRes->pCountInt->Halt = SecCtrHalt;
pRes->pCountInt->Pause = SecPause;
pRes->pCountInt->Continue = SecContinue;
pRes->iCallbackCounter = 20;
pRes->setMode = SecCtrSetMode;
pRes->getMode = SecCtrGetMode;
pRes->getNMonitor = SecCtrGetNMonitor;
pRes->setPreset = SecCtrSetPreset;
pRes->getPreset = SecCtrGetPreset;
pRes->getCounts = SecCtrGetCounts;
pRes->getMonitor = SecCtrGetMonitor;
pRes->setMonitor = SecCtrSetMonitor;
pRes->getTime = SecCtrGetTime;
pRes->pCall = CreateCallBackInterface();
pRes->isUpToDate = 1;
pRes->iExponent = 0;
pRes->name = strdup(argv[1]);
node = MakeHipadabaNode(argv[1],HIPNONE, 0);
pRes->pDes->parNode = node;
pRes->objectNode = node;
child = MakeSICSHdbPar("time", usInternal, MakeHdbFloat(.0));
if (child == NULL) {
return 0;
}
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("preset", usUser, MakeHdbFloat(.0));
if (child == NULL) {
return 0;
}
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("mode", usUser, MakeHdbText("monitor"));
if (child == NULL) {
return 0;
}
SetHdbProperty(child, "__save", "true");
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle"));
if (child == NULL) {
return 0;
}
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("control", usUser, MakeHdbFloat(.0));
if (child == NULL) {
return 0;
}
AddHipadabaChild(node, child, NULL);
child = MakeSICSHdbPar("values", usInternal,
makeHdbValue(HIPINTAR, length));
if (child == NULL) {
return 0;
}
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,"stop", usUser, MakeSICSFunc(StopCmd));
child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd));
child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd));
status =
AddCommand(pSics, argv[1], InterInvokeSICSOBJ, DeleteCounter,
(void *) pRes);
if (status != 1) {
SCPrintf(pCon,eError, "ERROR: duplicate command %s not created", argv[1]);
return 0;
}
return 1;
}