
- Added strlcpy and strlcat to SICS - Added a driver for the POLDI power supplies SKIPPED: psi/A1931.c psi/autowin.c psi/bruker.c psi/docho.c psi/dornier2.c psi/dspcode.c psi/ease.c psi/ecb.c psi/ecbcounter.c psi/ecbdriv.c psi/el734dc.c psi/el734driv.c psi/el734hp.c psi/el737driv.c psi/el737hpdriv.c psi/el737hpdrivsps.c psi/el737hpv2driv.c psi/el755driv.c psi/eurodriv.c psi/haakedriv.c psi/itc4driv.c psi/julcho.c psi/linadriv.c psi/lmd200.c psi/lscsupport.c psi/ltc11.c psi/make_gen psi/oicom.c psi/oxinst.c psi/pimotor.c psi/pipiezo.c psi/polterwrite.c psi/psi.c psi/sanscook.c psi/sanslirebin.c psi/sanswave.c psi/sinqhmdriv.c psi/sinqhttp.c psi/slsecho.c psi/slsmagnet.c psi/slsvme.c psi/sps.c psi/swmotor.c psi/swmotor2.c psi/tabledrive.c psi/tasscan.c psi/tdchm.c psi/velodorn.c psi/velodornier.c
330 lines
10 KiB
C
330 lines
10 KiB
C
/**
|
|
* This is a histogram memory driver for a slave histogram. This is for
|
|
* supporting multiple banks of histogram memory data in one physical
|
|
* histogram memory, possibly with different dimensions. On HM will connect
|
|
* to the physical histogram memory server and configure and control it and
|
|
* also handle bank 0. Other HM's may use this slave drive to to connect to
|
|
* the main HM for retrieving further banks. Thus this HM just becomes a
|
|
* data container for bank data. And this is the driver for such slave HM's.
|
|
* It mostly implements empty functions as control is through the main HM. The
|
|
* execption is data loading which will load the associated bank from the
|
|
* main HM.
|
|
*
|
|
* This is as of March 2007 defunct. The reason is that there are problems
|
|
* with buffering the data.
|
|
*
|
|
* copyright: see file COPYRIGHT
|
|
*
|
|
* Mark Koennecke, March 2007
|
|
*/
|
|
#include <sics.h>
|
|
#include <countdriv.h>
|
|
#include <counter.h>
|
|
#include <HistMem.h>
|
|
#include <HistMem.i>
|
|
#include <stringdict.h>
|
|
#include <HistDriv.i>
|
|
#include <hmdata.h>
|
|
|
|
typedef struct {
|
|
pHistMem master;
|
|
int bank;
|
|
} *HMSlave, sHMSlave;
|
|
/*-------------------------------------------------------------------
|
|
Configures the HM from the options in pOpt and the HM data structure
|
|
Returns 1 on success, 0 on failure
|
|
---------------------------------------------------------------------*/
|
|
static int HMSlaveConfigure(pHistDriver self, SConnection * pCon,
|
|
pStringDict pOpt, SicsInterp * pSics)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
char buffer[80], error[256];
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
|
|
if (StringDictGet(pOpt, "master", buffer, 79) == 1) {
|
|
pPriv->master =
|
|
(pHistMem) FindCommandData(pServ->pSics, buffer, "HistMem");
|
|
if (pPriv->master == NULL) {
|
|
snprintf(error, 255, "ERROR: failed to find master HM %s", buffer);
|
|
SCWrite(pCon, error, eError);
|
|
return 0;
|
|
}
|
|
} else {
|
|
SCWrite(pCon, "ERROR: required configuration option master missing",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
if (StringDictGet(pOpt, "bank", buffer, 79) == 1) {
|
|
pPriv->bank = atoi(buffer);
|
|
} else {
|
|
SCWrite(pCon, "ERROR: required configuration option bank missing",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Start histogramming, Returns HWFault on failure, 1 on success
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveStart(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Stops histogramming, Returns HWFault on failure, 1 on success
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveHalt(pHistDriver self)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Checks histogramming status, Returns HWFault on failure,
|
|
HWIdle when finished, HWBusy when counting
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveCountStatus(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return HWIdle;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Get info on error after last HWFault, returns 1 always.
|
|
Puts an int error code into *code and errLen chars of
|
|
error description into error
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveGetError(pHistDriver self, int *code,
|
|
char *error, int errLen)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
strlcpy(error, "Weird status: slaves do not err..", errLen);
|
|
*code = -77;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Try to fix the HM error in code. Returns COREDO when the last
|
|
operation needs to be redone, COTERM when the error cannot be
|
|
fixed.
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveFixIt(pHistDriver self, int code)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return COTERM;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
GetData reads updates the internal cache of monitor values
|
|
from the hardware, Returns 1 or HWFault
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveGetData(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
GetMonitor reads the monitor value i. Returns either the monitor
|
|
value or -9999 if no such monitor exists or an error occurred
|
|
----------------------------------------------------------------------*/
|
|
static long HMSlaveGetMonitor(pHistDriver self, int i, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return -9999;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
GetTime reads the total counting time. Returns either the
|
|
value or -9999.99 if no such value exists or an error occurred
|
|
----------------------------------------------------------------------*/
|
|
static float HMSlaveGetTime(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return -9999.99;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Pause histogramming, Returns HWFault on failure, 1 on success
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlavePause(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Continue histogramming, Returns HWFault on failure, 1 on success
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveContinue(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Free the data associated with the private data structure of the driver
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveFree(pHistDriver self)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
if (pPriv != NULL) {
|
|
free(pPriv);
|
|
}
|
|
self->pPriv = NULL;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
* fixTimebinning assures that our time binning dn the masters
|
|
* time binning are the same. So that diemsnions are right
|
|
* ------------------------------------------------------------------*/
|
|
static int fixTimeBinning(pHistDriver self, SConnection * pCon)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
if (isInTOFMode(pPriv->master->pDriv->data) &&
|
|
getNoOfTimebins(pPriv->master->pDriv->data) !=
|
|
getNoOfTimebins(self->data)) {
|
|
self->data->tofMode = 1;
|
|
self->data->nTimeChan = getNoOfTimebins(pPriv->master->pDriv->data);
|
|
if (!resizeBuffer(self->data)) {
|
|
SCWrite(pCon,
|
|
"ERROR: out of memory allocating HMData for slave", eError);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Set The HM data or a subset of it. Returns HWFault or 1
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveSetHistogram(pHistDriver self,
|
|
SConnection * pCon,
|
|
int i, int iStart, int iEnd,
|
|
HistInt * pData)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
HistInt *start = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
if (fixTimeBinning(self, pCon) == 1) {
|
|
start = self->data->localBuffer + iStart;
|
|
memcpy(start, pData, (iEnd - iStart) * sizeof(HistInt));
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Set HM to a preset value, Returns HWFault on failure, 1 on success
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlavePreset(pHistDriver self, SConnection * pCon,
|
|
HistInt value)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
int i;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
if (fixTimeBinning(self, pCon) == 1) {
|
|
for (i = 0; i < getHMDataLength(self->data); i++) {
|
|
self->data->localBuffer[i] = value;
|
|
}
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
get The HM data or a subset of it. Returns HWFault or 1
|
|
----------------------------------------------------------------------*/
|
|
static int HMSlaveGetHistogram(pHistDriver self,
|
|
SConnection * pCon,
|
|
int i, int iStart, int iEnd,
|
|
HistInt * pData)
|
|
{
|
|
HMSlave pPriv = NULL;
|
|
|
|
pPriv = (HMSlave) self->pPriv;
|
|
return pPriv->master->pDriv->GetHistogram(pPriv->master->pDriv,
|
|
pCon, pPriv->bank, iStart,
|
|
iEnd, pData);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------
|
|
Make the HMDriver, returns a driver or NULL on failure
|
|
----------------------------------------------------------------------*/
|
|
pHistDriver MakeHMSlaveHM(pStringDict pOption)
|
|
{
|
|
pHistDriver pNew = NULL;
|
|
HMSlave pPriv = NULL;
|
|
|
|
/* create the general driver */
|
|
pNew = CreateHistDriver(pOption);
|
|
if (!pNew) {
|
|
return NULL;
|
|
}
|
|
|
|
/*Create private data structure */
|
|
pPriv = (HMSlave) malloc(sizeof(sHMSlave));
|
|
if (pPriv == NULL) {
|
|
return NULL;
|
|
}
|
|
pNew->pPriv = pPriv;
|
|
|
|
/* add our options */
|
|
StringDictAddPair(pOption, "master", "unknown");
|
|
StringDictAddPair(pOption, "bank", "1");
|
|
|
|
/* configure all those functions */
|
|
pNew->Configure = HMSlaveConfigure;
|
|
pNew->Start = HMSlaveStart;
|
|
pNew->Halt = HMSlaveHalt;
|
|
pNew->GetCountStatus = HMSlaveCountStatus;
|
|
pNew->GetError = HMSlaveGetError;
|
|
pNew->TryAndFixIt = HMSlaveFixIt;
|
|
pNew->GetData = HMSlaveGetData;
|
|
pNew->GetHistogram = HMSlaveGetHistogram;
|
|
pNew->SetHistogram = HMSlaveSetHistogram;
|
|
pNew->GetMonitor = HMSlaveGetMonitor;
|
|
pNew->GetTime = HMSlaveGetTime;
|
|
pNew->Preset = HMSlavePreset;
|
|
pNew->FreePrivate = HMSlaveFree;
|
|
pNew->Pause = HMSlavePause;
|
|
pNew->Continue = HMSlaveContinue;
|
|
|
|
return pNew;
|
|
}
|