/** * 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; strncpy(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; }