From 9737722b8c78c4db2bbd04ce8970b689d725134c Mon Sep 17 00:00:00 2001 From: koennecke Date: Wed, 30 May 2007 11:57:50 +0000 Subject: [PATCH] - Added hmslave.c - Tasub only drives required motors - Tasub handles fixed motors more gracefully --- confvirtualmot.c | 1 + hipadaba.c | 6 + hmslave.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++ napi5.c | 5 +- nxscript.c | 2 +- protocol.c | 6 + rs232controller.c | 2 +- tasdrive.c | 16 ++- tasub.c | 30 ++++- 9 files changed, 355 insertions(+), 6 deletions(-) create mode 100644 hmslave.c diff --git a/confvirtualmot.c b/confvirtualmot.c index 4a7f5e44..73074fb1 100644 --- a/confvirtualmot.c +++ b/confvirtualmot.c @@ -333,6 +333,7 @@ static float invokeReadScript(pConfigurableVirtualMotor self, if(status != TCL_OK){ snprintf(self->scriptError,510,"ERROR: Tcl subsystem reported %s", Tcl_GetStringResult(pTcl)); + SCWrite(pCon,self->scriptError,eError); } return atof(Tcl_GetStringResult(pTcl)); } diff --git a/hipadaba.c b/hipadaba.c index 7ca1cf87..f45ec8cd 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -454,6 +454,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){ if(v1.arrayLength != v2.arrayLength){ return 0; } + if(v1.v.intArray == NULL || v2.v.intArray == NULL){ + return 0; + } for(i = 0; i < v1.arrayLength; i++){ if(v1.v.intArray[i] != v2.v.intArray[i]){ return 0; @@ -466,6 +469,9 @@ int compareHdbValue(hdbValue v1, hdbValue v2){ if(v1.arrayLength != v2.arrayLength){ return 0; } + if(v1.v.floatArray == NULL || v2.v.floatArray == NULL){ + return 0; + } for(i = 0; i < v1.arrayLength; i++){ if(ABS(v1.v.floatArray[i] - v2.v.floatArray[i]) > .01){ return 0; diff --git a/hmslave.c b/hmslave.c new file mode 100644 index 00000000..0a59538f --- /dev/null +++ b/hmslave.c @@ -0,0 +1,293 @@ +/** + * 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; +} diff --git a/napi5.c b/napi5.c index 48089269..dafc3a59 100644 --- a/napi5.c +++ b/napi5.c @@ -588,7 +588,7 @@ static void ignoreError(void *data, char *text){ int i, byte_zahl; hsize_t chunkdims[H5S_MAX_RANK]; hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK]; - hsize_t size[2]; + hsize_t size[H5S_MAX_RANK]; hsize_t maxdims[H5S_MAX_RANK]; pFile = NXI5assert (fid); @@ -992,7 +992,7 @@ static void ignoreError(void *data, char *text){ int rank; hssize_t myStart[H5S_MAX_RANK]; hsize_t mySize[H5S_MAX_RANK]; - hsize_t size[1],maxdims[H5S_MAX_RANK]; + hsize_t size[H5S_MAX_RANK],maxdims[H5S_MAX_RANK]; hid_t filespace,dataspace; pFile = NXI5assert (fid); @@ -1006,6 +1006,7 @@ static void ignoreError(void *data, char *text){ { myStart[i] = iStart[i]; mySize[i] = iSize[i]; + size[i] = iSize[i]; } iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims); dataspace = H5Screate_simple (rank, mySize, NULL); diff --git a/nxscript.c b/nxscript.c index 1857b78e..f5b2a6aa 100644 --- a/nxscript.c +++ b/nxscript.c @@ -681,7 +681,7 @@ static void putSlab(SConnection *pCon, SicsInterp *pSics, pNXScript self, eError); return; } - + status = NXDopenalias(self->fileHandle, self->dictHandle,argv[2]); if(status != NX_OK){ SCPrintf(pCon,eError,"ERROR: failed to open alias %s", argv[2]); diff --git a/protocol.c b/protocol.c index 8c006ac4..98eb6f2e 100644 --- a/protocol.c +++ b/protocol.c @@ -301,6 +301,12 @@ int ProtocolGet(SConnection* pCon, void* pData, char *pProName, int len) return 0; } + if(pData == NULL) + { + pCon->iProtocolID = 0; + return 1; + } + /* lazy initialisation of defaultWriter since connection is verified */ if(0==pPro->isDefaultSet) { diff --git a/rs232controller.c b/rs232controller.c index 7b717502..9d6c22ca 100644 --- a/rs232controller.c +++ b/rs232controller.c @@ -460,7 +460,7 @@ int fixRS232Error(prs232 self, int iCode){ case BADSEND: closeRS232(self); status = initRS232(self); - if(status){ + if(status > 0){ return 1; } else { return 0; diff --git a/tasdrive.c b/tasdrive.c index ad3ba81d..2d00de02 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -4,6 +4,9 @@ copyright: see file COPYRIGHT Mark Koennecke, May 2005 + + In the long run it might be useful to switch all this to the more + general motor list driving code. --------------------------------------------------------------------*/ #include #include "sics.h" @@ -248,6 +251,7 @@ static int startMotors(ptasMot self, tasAngles angles, int status, silent; silent = self->math->silent; + self->math->mustRecalculate = 1; /* monochromator */ @@ -472,13 +476,23 @@ static int calculateAndDrive(ptasMot self, SConnection *pCon){ /*-----------------------------------------------------------------------------*/ static int checkMotors(ptasMot self, SConnection *pCon){ int i, status, length = 12; + int mask[12]; self->math->mustRecalculate = 1; if(self->math->tasMode == ELASTIC){ length = 8; } + memset(mask,0,12*sizeof(int)); + for(i = 0; i < length; i++){ + mask[i] = 1; + } + if(self->math->outOfPlaneAllowed != 0){ + mask[SGU] = 0; + mask[SGL] = 0; + } + for(i = 0; i < 12; i++){ - if(self->math->motors[i] != NULL){ + if(self->math->motors[i] != NULL && mask[i] != 0){ status = self->math->motors[i]->pDrivInt->CheckStatus(self->math->motors[i], pCon); if(status != HWIdle && status != OKOK){ diff --git a/tasub.c b/tasub.c index 48b0ad0f..0b49b0c2 100644 --- a/tasub.c +++ b/tasub.c @@ -227,6 +227,13 @@ static int testMotor(ptasUB pNew, SConnection *pCon, char *name, int idx){ return 1; } } +/*-------------------------------------------------------------------*/ +static void updateTargets(ptasUB pNew, SConnection *pCon){ + tasAngles ang; + + readTASAngles(pNew,pCon,&ang); + calcTasQEPosition(&pNew->machine, ang, &pNew->target); +} /*--------------------------------------------------------------------*/ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]){ @@ -303,7 +310,7 @@ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData, SCWrite(pCon,"ERROR: a required motor is mssing, tasub NOT installed",eError); return 0; } - + status = AddCommand(pSics,argv[1], TasUBWrapper, KillTasUB, @@ -1438,6 +1445,21 @@ static int setUB(SConnection *pCon, SicsInterp *pSics, ptasUB self, return 1; } /*------------------------------------------------------------------*/ +static int getUB(SConnection *pCon, SicsInterp *pSics, ptasUB self, + int argc, char *argv[]){ + double value; + char pBueffel[512]; + int status; + + snprintf(pBueffel,511,"tasub.ub = %f %f %f %f %f %f %f %f %f", + self->machine.UB[0][0], self->machine.UB[0][1], self->machine.UB[0][2], + self->machine.UB[1][0], self->machine.UB[1][1], self->machine.UB[1][2], + self->machine.UB[2][0], self->machine.UB[2][1], self->machine.UB[2][2]); + SCWrite(pCon,pBueffel,eValue); + + return 1; +} +/*------------------------------------------------------------------*/ static int setNormal(SConnection *pCon, SicsInterp *pSics, ptasUB self, int argc, char *argv[]){ double value; @@ -1652,6 +1674,8 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData, return calcQFromAngles(self,pCon,pSics,argc,argv); } else if(strcmp(argv[1],"setub") == 0){ return setUB(pCon,pSics,self,argc,argv); + } else if(strcmp(argv[1],"getub") == 0){ + return getUB(pCon,pSics,self,argc,argv); } else if(strcmp(argv[1],"setnormal") == 0){ return setNormal(pCon,pSics,self,argc,argv); } else if(strcmp(argv[1],"settarget") == 0){ @@ -1664,6 +1688,10 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData, return readReflection(pCon,pSics,&self->r1,argc,argv); } else if(strcmp(argv[1],"r2") == 0){ return readReflection(pCon,pSics,&self->r2,argc,argv); + } else if(strcmp(argv[1],"updatetargets") == 0){ + updateTargets(self,pCon); + SCSendOK(pCon); + return 1; } else if(strcmp(argv[1],"const") == 0){ if(argc > 2){ strtolower(argv[2]);