/** * 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 #include #include #include #include #include #include #include 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; }