Initial revision
This commit is contained in:
849
sinqhmdriv.c
Normal file
849
sinqhmdriv.c
Normal file
@@ -0,0 +1,849 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
S I N Q H M D R I V
|
||||
|
||||
This is the SICS driver to the SINQ histogram memory.
|
||||
|
||||
Mark Koennecke, April 1997
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
Paul Scherrer Institut
|
||||
CH-5423 Villigen-PSI
|
||||
|
||||
|
||||
The authors hereby grant permission to use, copy, modify, distribute,
|
||||
and license this software and its documentation for any purpose, provided
|
||||
that existing copyright notices are retained in all copies and that this
|
||||
notice is included verbatim in any distributions. No written agreement,
|
||||
license, or royalty fee is required for any of the authorized uses.
|
||||
Modifications to this software may be copyrighted by their authors
|
||||
and need not follow the licensing terms described here, provided that
|
||||
the new terms are clearly indicated on the first page of each file where
|
||||
they apply.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
----------------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include "fortify.h"
|
||||
#include "conman.h"
|
||||
#include "SCinter.h"
|
||||
#include "obdes.h"
|
||||
#include "interface.h"
|
||||
#include "countdriv.h"
|
||||
#include "counter.h"
|
||||
#include "HistMem.h"
|
||||
#include "hardsup/sinqhm.h"
|
||||
#include "hardsup/sinqhm.i" /* for byte switching stuff */
|
||||
#include "stringdict.h"
|
||||
#include "HistDriv.i"
|
||||
#include "sinqhmdriv.i"
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void PrintHMError(char *text, SConnection *pCon)
|
||||
{
|
||||
char pBueffel[1064];
|
||||
|
||||
strcpy(pBueffel,"ERROR: Histogram Memory --> ");
|
||||
strcat(pBueffel,text);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void ErrInit(SinqHMDriv *self)
|
||||
{
|
||||
self->iLastHMError = 0;
|
||||
self->iLastCTError = 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
Configure deconfigures first, in order to have a clean state. Than the HM
|
||||
is configured and a client connection will be built. Configure requires,
|
||||
that the pSINQHM data structure has been initialised by CreateSINQHMDriver.
|
||||
*/
|
||||
|
||||
static int SQConfigure(pHistDriver self, SConnection *pCon,
|
||||
pStringDict pOpt, SicsInterp *pSics)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
int status, iMode;
|
||||
char pError[132];
|
||||
char pHMComputer[256];
|
||||
float fVal;
|
||||
char pcCounter[256];
|
||||
CommandList *pCom = NULL;
|
||||
int iStart = 0;
|
||||
int iInit = 0, i;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
assert(pCon);
|
||||
assert(pOpt);
|
||||
|
||||
pInternal = (SinqHMDriv *)self->pPriv;
|
||||
ErrInit(pInternal);
|
||||
|
||||
/* check BinWidth */
|
||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
||||
&& (self->iBinWidth != 4))
|
||||
{
|
||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if not initialised, analyze options database for the stuff we need*/
|
||||
if(pInternal->pMaster == NULL)
|
||||
{
|
||||
iStart = 1;
|
||||
/* the histogram memory */
|
||||
status = StringDictGet(pOpt,"hmcomputer",pHMComputer,254);
|
||||
if(!status)
|
||||
{
|
||||
PrintHMError("No network name for histogram memory computer found",pCon);
|
||||
return 0;
|
||||
}
|
||||
status = StringDictGetAsNumber(pOpt,"hmport",&fVal);
|
||||
if(!status)
|
||||
{
|
||||
PrintHMError("No network name for histogram memory computer found",pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the counter */
|
||||
status = StringDictGet(pOpt,"counter",pcCounter,254);
|
||||
if(!status)
|
||||
{
|
||||
PrintHMError("No network name for histogram memory computer found",pCon);
|
||||
return 0;
|
||||
}
|
||||
pCom = FindCommand(pSics,pcCounter);
|
||||
if(!pCom)
|
||||
{
|
||||
PrintHMError("EL737 counter for histogram memory not found",pCon);
|
||||
return 0;
|
||||
}
|
||||
pInternal->pCounter = (pCounter)pCom->pData;
|
||||
if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,COUNTID))
|
||||
{
|
||||
PrintHMError("EL737 counter for histogram memory is invalid",pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ok! put in HM */
|
||||
pInternal->pMaster = CreateSINQHM(pHMComputer,(int)fVal);
|
||||
if(!pInternal->pMaster)
|
||||
{
|
||||
PrintHMError("No memory to allocate SINQHM",pCon);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* close the connection if there is such a thing */
|
||||
SINQHMCloseDAQ(pInternal->pMaster);
|
||||
}
|
||||
|
||||
/* in any case let us propagate the state of affairs to
|
||||
SINQHM
|
||||
*/
|
||||
SINQHMSetPar(pInternal->pMaster,self->iRank, self->iLength, self->iBinWidth);
|
||||
|
||||
|
||||
/* actual configuration. On first call, check for flag INIt in
|
||||
options. We do need to configure, if the HM has configured
|
||||
itself already. What is does, these days.
|
||||
*/
|
||||
if(iStart)
|
||||
{
|
||||
status = StringDictGetAsNumber(pOpt,"init",&fVal);
|
||||
if(!status)
|
||||
{
|
||||
iInit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fVal > 0.9 )
|
||||
{
|
||||
iInit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(iInit == 0)
|
||||
{
|
||||
/* do a deconfig first */
|
||||
status = SINQHMDeconfigure(pInternal->pMaster,1);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
||||
&& (self->iBinWidth != 4))
|
||||
{
|
||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* configure */
|
||||
switch(self->eHistMode)
|
||||
{
|
||||
case eHTransparent:
|
||||
iMode = SQHM__TRANS;
|
||||
break;
|
||||
case eHNormal:
|
||||
iMode = SQHM__HM_DIG;
|
||||
break;
|
||||
case eHTOF:
|
||||
iMode = SQHM__TOF;
|
||||
/* recalculate some parameters */
|
||||
self->iLength = 1;
|
||||
for(i = 0; i < self->iRank; i++)
|
||||
{
|
||||
self->iLength *= self->iDims[i];
|
||||
}
|
||||
self->iLength *= self->iTimeChan;
|
||||
SINQHMDefineBank(pInternal->pMaster,0,0,self->iDims[0],
|
||||
self->fTime,self->iTimeChan);
|
||||
break;
|
||||
case eHStrobo:
|
||||
iMode = SQHM__HM_PSD | SQHM__STROBO;
|
||||
break;
|
||||
case eHRPT:
|
||||
iMode = SQHM__HRPT;
|
||||
break;
|
||||
default:
|
||||
PrintHMError("Unsupported mode requested",pCon);
|
||||
return 0;
|
||||
}
|
||||
switch(self->eFlow)
|
||||
{
|
||||
case eOIgnore:
|
||||
iMode = iMode | SQHM__BO_IGN;
|
||||
break;
|
||||
case eOCeil:
|
||||
iMode = iMode | SQHM__BO_SMAX;
|
||||
break;
|
||||
case eOCount:
|
||||
iMode = iMode | SQHM__BO_CNT;
|
||||
break;
|
||||
case eReflect:
|
||||
iMode = iMode | SQHM__REFLECT;
|
||||
break;
|
||||
default:
|
||||
PrintHMError("Unsupported overflowmode requested",pCon);
|
||||
return 0;
|
||||
}
|
||||
status = SINQHMConfigure(pInternal->pMaster,
|
||||
iMode,
|
||||
self->iRank,
|
||||
self->iLength,
|
||||
self->iBinWidth,
|
||||
0,0);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* initiate a client connection for DAQ */
|
||||
status = SINQHMOpenDAQ(pInternal->pMaster);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* tell the counter box our current status */
|
||||
SetCounterMode(pInternal->pCounter,self->eCount);
|
||||
SetCounterPreset(pInternal->pCounter,self->fCountPreset);
|
||||
|
||||
self->iReconfig = 0;
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQStart(pHistDriver self, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int status, iMode;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* tell the counter box our current status */
|
||||
SetCounterMode(pInternal->pCounter,self->eCount);
|
||||
pInternal->pCounter->pDriv->fPreset = self->fCountPreset;
|
||||
|
||||
|
||||
/* first zero the HM */
|
||||
status = SINQHMZero(pInternal->pMaster,-1,0,self->iRank*self->iLength);
|
||||
if(status < 0)
|
||||
{
|
||||
pInternal->iLastHMError = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/* start the HM */
|
||||
status = SINQHMStartDAQ(pInternal->pMaster);
|
||||
if( (status < 0) && (status != DAQ_INHIBIT) )
|
||||
{
|
||||
pInternal->iLastHMError = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/* start the El737 counter */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
return pCountInt->StartCount(pInternal->pCounter,pCon);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQPause(pHistDriver self, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int status, iMode;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* pause the HM */
|
||||
status = SINQHMInhibitDAQ(pInternal->pMaster);
|
||||
if( (status < 0) && (status != DAQ_INHIBIT) )
|
||||
{
|
||||
pInternal->iLastHMError = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/* pause the El737 counter */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
return pCountInt->Pause(pInternal->pCounter,pCon);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQContinue(pHistDriver self, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int status, iMode;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* continue the HM */
|
||||
status = SINQHMContinueDAQ(pInternal->pMaster);
|
||||
if( (status < 0) && (status != DAQ_INHIBIT) )
|
||||
{
|
||||
pInternal->iLastHMError = status;
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/* continue the El737 counter */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
return pCountInt->Continue(pInternal->pCounter,pCon);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQHalt(pHistDriver self)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int status, iRet;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
iRet = 1;
|
||||
|
||||
/* Halt HM */
|
||||
status = SINQHMStopDAQ(pInternal->pMaster);
|
||||
if(status < 0)
|
||||
{
|
||||
iRet = 0;
|
||||
}
|
||||
|
||||
/* Halt counter */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
status = pCountInt->Halt(pInternal->pCounter);
|
||||
if(!status)
|
||||
{
|
||||
iRet = 0;
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SQStatus(pHistDriver self, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int status, iRet;
|
||||
char pError[132];
|
||||
int iMode, iRank, iLength, iDaq, iBin, iClient;
|
||||
float fControl;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* first check at counter */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
status = pCountInt->CheckCountStatus(pInternal->pCounter,
|
||||
pCon);
|
||||
if( (status == HWFault) )
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* now check at HM */
|
||||
iRet = SINQHMGetStatus(pInternal->pMaster,&iMode,&iDaq,
|
||||
&iRank, &iBin, &iLength, &iClient);
|
||||
if(iRet < 0)
|
||||
{
|
||||
SINQHMError2Text(iRet, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
if(iDaq == 2)
|
||||
{
|
||||
return HWPause;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQError(pHistDriver self, int *iCode, char *pError, int iErrLen)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* first check for HM errors */
|
||||
if(pInternal->iLastHMError < 0)
|
||||
{
|
||||
SINQHMError2Text(pInternal->iLastHMError,pError,iErrLen);
|
||||
*iCode = pInternal->iLastHMError;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* now counter errors */
|
||||
return pInternal->pCounter->pDriv->GetError(pInternal->pCounter->pDriv,
|
||||
iCode,
|
||||
pError,
|
||||
iErrLen);
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQFixIt(pHistDriver self, int iCode)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* check for HM Errors */
|
||||
if(pInternal->iLastHMError < 0)
|
||||
{
|
||||
switch(iCode)
|
||||
{
|
||||
case RECEIVE_ERROR:
|
||||
case INSUFFICIENT_DATA:
|
||||
/* may happen after a bad command. Currently the HM-client
|
||||
dies in this stage. This should fix this.
|
||||
*/
|
||||
SINQHMCloseDAQ(pInternal->pMaster);
|
||||
SINQHMOpenDAQ(pInternal->pMaster);
|
||||
return COREDO;
|
||||
break;
|
||||
|
||||
case BYTE_ORDER_CHAOS:
|
||||
case HIST_BAD_RECV:
|
||||
case SEND_ERROR:
|
||||
return COREDO;
|
||||
break;
|
||||
|
||||
default:
|
||||
return COTERM;
|
||||
}
|
||||
}
|
||||
|
||||
/* do counter errors */
|
||||
return pInternal->pCounter->pDriv->TryAndFixIt(pInternal->pCounter->pDriv,
|
||||
iCode);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SQGetData(pHistDriver self, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
pICountable pCountInt = NULL;
|
||||
int iMode, iDaq, iRank, iBin, iLength, iClient, iRet;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* now check at HM */
|
||||
iRet = SINQHMGetStatus(pInternal->pMaster,&iMode,&iDaq,
|
||||
&iRank, &iBin, &iLength, &iClient);
|
||||
if(iRet < 0)
|
||||
{
|
||||
SINQHMError2Text(iRet, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
/* stop DAQ, if still active */
|
||||
if(iDaq == 1)
|
||||
{
|
||||
SINQHMStopDAQ(pInternal->pMaster);
|
||||
}
|
||||
|
||||
|
||||
/* do only counter, histograms are read on demand */
|
||||
pCountInt = pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID);
|
||||
if(pCountInt)
|
||||
{
|
||||
return pCountInt->TransferData(pInternal->pCounter,
|
||||
pCon);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQGetHistogram(pHistDriver self, SConnection *pCon,
|
||||
int iNum, int iStart, int iEnd,
|
||||
HistInt *plData)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
void *pData = NULL;
|
||||
char *pPtr;
|
||||
SQint16 *pPtr16;
|
||||
SQint32 *pPtr32;
|
||||
int i, iLen, iByte, status;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* we do not need to do a lot of copying when datasizes match! */
|
||||
iByte = iEnd * self->iBinWidth;
|
||||
if(self->iBinWidth == sizeof(HistInt))
|
||||
{
|
||||
/* read HM */
|
||||
status = SINQHMRead(pInternal->pMaster,
|
||||
iNum,iStart, iEnd, plData, iByte);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* we need to convert datasizes: allocate storage */
|
||||
pData = (void *)malloc(iByte*sizeof(char));
|
||||
if(!pData)
|
||||
{
|
||||
PrintHMError("Out of memory in SinqHMDriv",pCon);
|
||||
return 0;
|
||||
}
|
||||
memset(pData,0,iByte);
|
||||
|
||||
/* read HM */
|
||||
status = SINQHMRead(pInternal->pMaster,iNum,iStart, iEnd, pData, iByte);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert to correct datasize */
|
||||
switch(self->iBinWidth)
|
||||
{
|
||||
case 1:
|
||||
pPtr = (char *)pData;
|
||||
for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
plData[i] = (HistInt)pPtr[i];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pPtr16 = (SQint16 *)pData;
|
||||
for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
plData[i] = (HistInt)pPtr[i];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* 32 bit is native here now. May need change on other machine,
|
||||
no conversion necessary
|
||||
*/
|
||||
pPtr32 = (SQint32 *)pData;
|
||||
/* for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
plData[i] = (HistInt)pPtr32[i];
|
||||
}
|
||||
*/
|
||||
memcpy(plData,pPtr32,iEnd*sizeof(HistInt));
|
||||
break;
|
||||
}
|
||||
|
||||
free(pData);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQSetHistogram(pHistDriver self, SConnection *pCon,
|
||||
int iNum, int iStart, int iEnd,
|
||||
HistInt *plData)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
void *pData = NULL;
|
||||
char *pPtr;
|
||||
SQint16 *pPtr16;
|
||||
SQint32 *pPtr32;
|
||||
int i, iLen, iByte, status;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* allocate storage */
|
||||
iByte = iEnd * self->iBinWidth;
|
||||
pData = (void *)malloc(iByte*sizeof(char));
|
||||
if(!pData)
|
||||
{
|
||||
PrintHMError("Out of memory in SinqHMDriv",pCon);
|
||||
return 0;
|
||||
}
|
||||
memset(pData,0,iByte);
|
||||
|
||||
/* convert from long to supported binwidth */
|
||||
switch(self->iBinWidth)
|
||||
{
|
||||
case 1:
|
||||
pPtr = (char *)pData;
|
||||
for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
pPtr[i] = plData[i];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pPtr16 = (SQint16 *)pData;
|
||||
for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
pPtr16[i] = plData[i];
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
pPtr32 = (SQint32 *)pData;
|
||||
for(i = 0; i < iEnd; i++)
|
||||
{
|
||||
pPtr32[i] = plData[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* send data */
|
||||
status = SINQHMWrite(pInternal->pMaster,iNum,iStart, iEnd, pData);
|
||||
if(status < 0)
|
||||
{
|
||||
SINQHMError2Text(status, pError,131);
|
||||
PrintHMError(pError,pCon);
|
||||
free(pData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(pData);
|
||||
return 1;
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static long SQGetMonitor(pHistDriver self, int i, SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
return GetMonitor(pInternal->pCounter,i,pCon);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static float SQGetTime(pHistDriver self,SConnection *pCon)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
char pError[132];
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
return GetCountTime(pInternal->pCounter,pCon);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SQPreset(pHistDriver self, SConnection *pCon, HistInt iVal)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
char pError[132];
|
||||
HistInt *plData = NULL;
|
||||
int i, status;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* get memory */
|
||||
plData = (HistInt *)malloc(self->iRank*self->iLength*sizeof(HistInt));
|
||||
if(!plData)
|
||||
{
|
||||
PrintHMError("Out of memory in SinqHMDriv",pCon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialise */
|
||||
for(i = 0; i < self->iRank*self->iLength; i++)
|
||||
{
|
||||
plData[i] = iVal;
|
||||
}
|
||||
|
||||
status = SQSetHistogram(self,pCon, -1,0,self->iRank*self->iLength, plData);
|
||||
free(plData);
|
||||
return status;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SQFreePrivate(pHistDriver self)
|
||||
{
|
||||
SinqHMDriv *pInternal;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
|
||||
pInternal = self->pPriv;
|
||||
|
||||
if(pInternal->pMaster)
|
||||
{
|
||||
DeleteSINQHM(pInternal->pMaster);
|
||||
}
|
||||
free(pInternal);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pHistDriver CreateSINQDriver(pStringDict pOption)
|
||||
{
|
||||
pHistDriver pNew = NULL;
|
||||
SinqHMDriv *pInternal = NULL;
|
||||
|
||||
/* create the general driver */
|
||||
pNew = CreateHistDriver(pOption);
|
||||
if(!pNew)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add our options */
|
||||
StringDictAddPair(pOption,"hmcomputer","psds02.psi.ch");
|
||||
StringDictAddPair(pOption,"hmport","2400");
|
||||
StringDictAddPair(pOption,"counter","Rudolf");
|
||||
StringDictAddPair(pOption,"init","1");
|
||||
|
||||
/* initialise our private data structure */
|
||||
pInternal = (SinqHMDriv *)malloc(sizeof(SinqHMDriv));
|
||||
if(!pInternal)
|
||||
{
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
memset(pInternal,0,sizeof(SinqHMDriv));
|
||||
pNew->pPriv = pInternal;
|
||||
|
||||
/* configure all those functions */
|
||||
pNew->Configure = SQConfigure;
|
||||
pNew->Start = SQStart;
|
||||
pNew->Halt = SQHalt;
|
||||
pNew->GetCountStatus = SQStatus;
|
||||
pNew->GetError = SQError;
|
||||
pNew->TryAndFixIt = SQFixIt;
|
||||
pNew->GetData = SQGetData;
|
||||
pNew->GetHistogram = SQGetHistogram;
|
||||
pNew->SetHistogram = SQSetHistogram;
|
||||
pNew->GetMonitor = SQGetMonitor;
|
||||
pNew->GetTime = SQGetTime;
|
||||
pNew->Preset = SQPreset;
|
||||
pNew->FreePrivate = SQFreePrivate;
|
||||
pNew->Pause = SQPause;
|
||||
pNew->Continue = SQContinue;
|
||||
|
||||
return pNew;
|
||||
}
|
||||
Reference in New Issue
Block a user