From 45a07c9ddc5ca02a8a310c2d87b74b4ca1499422 Mon Sep 17 00:00:00 2001 From: cvs Date: Fri, 14 Feb 2003 13:00:28 +0000 Subject: [PATCH] - Driver for the Risoe Temperature controller - HM is now working - display code added --- A1931.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++ A1931.h | 20 +++ Makefile | 2 +- counter.c | 2 +- ecb.c | 3 + ecbdriv.c | 70 ++++++++++ evcontroller.c | 40 ++++++ gpib.w | 1 + gpibcontroller.c | 108 ++++++++++++++- gpibcontroller.h | 1 + hmdata.c | 1 + motor.c | 4 +- nxscript.c | 11 +- sans2.tcl | 18 ++- sans2com.tcl | 95 +++++++++++-- sans2dis.tcl | 39 ++++++ sicsstat.tcl | 14 +- tdchm.c | 8 +- 18 files changed, 748 insertions(+), 27 deletions(-) create mode 100644 A1931.c create mode 100644 A1931.h create mode 100644 sans2dis.tcl diff --git a/A1931.c b/A1931.c new file mode 100644 index 00000000..b58c4824 --- /dev/null +++ b/A1931.c @@ -0,0 +1,338 @@ +/*------------------------------------------------------------------------- + This is the implementation file for a driver for the Risoe A1931a + temperature controller. This driver controls the device through a GPIB + interface. + + copyright: see file COPYRIGHT + + Mark Koennecke, February 2003 + -------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "fortify.h" +#include "sics.h" +#include "obpar.h" +#include "evcontroller.h" +#include "evcontroller.i" +#include "evdriver.i" +#include "gpibcontroller.h" +#include "A1931.h" + +/*========================== private data structure ====================*/ +typedef struct { + int sensor; /* the control sensor */ + pGPIB gpib; /* the GPIB interface to use in order to talk to the thing*/ + int gpibAddress; /* address on bus */ + int devID; /* deviceID of the controller on the GPIB */ + char errorBuffer[132]; /* a buffer for error meesages from the thing*/ + int errorCode; /* error indicator */ +}A1931, *pA1931; +/*============================ defines ================================*/ +#define COMMERROR -300 +#define A1931ERROR -301 +#define FILEERROR -302 +/*====================================================================*/ +static char *A1931comm(pEVDriver pData, char *command){ + char buffer[256], *pPtr; + int status; + pA1931 self = NULL; + Tcl_DString reply; + + self = (pA1931)pData->pPrivate; + assert(self); + + /* + send + */ + strncpy(buffer,command,250); + strcat(buffer,"\n"); + status = GPIBsend(self->gpib,self->devID,buffer,(int)strlen(buffer)); + if(status < 0){ + self->errorCode = COMMERROR; + GPIBerrorDescription(self->gpib,status,self->errorBuffer,131); + return NULL; + } + + /* + read until > is found + */ + Tcl_DStringInit(&reply); + while(1){ + pPtr = GPIBreadTillTerm(self->gpib,self->devID,10); + if(strstr(pPtr,"GPIB READ ERROR") != NULL){ + free(pPtr); + self->errorCode = COMMERROR; + Tcl_DStringFree(&reply); + return NULL; + } else { + Tcl_DStringAppend(&reply,pPtr,-1); + if(strchr(pPtr,'>') != NULL){ + /* + finished + */ + free(pPtr); + break; + } + free(pPtr); + } + } + pPtr = NULL; + pPtr = strdup(Tcl_DStringValue(&reply)); + Tcl_DStringFree(&reply); + if(pPtr[0] == '#'){ + /* + error + */ + self->errorCode = A1931ERROR; + strncpy(self->errorBuffer,pPtr,131); + free(pPtr); + return NULL; + } + return pPtr; +} +/*--------------------------------------------------------------------*/ +static int A1931command(pEVDriver pData, char *command, char *replyBuffer, + int replyBufferLen){ + pA1931 self = NULL; + char *pReply = NULL; + + self = (pA1931)pData->pPrivate; + assert(self); + + pReply = A1931comm(pData,command); + if(pReply != NULL){ + strncpy(replyBuffer,pReply,replyBufferLen); + free(pReply); + return 1; + } else { + strncpy(replyBuffer,self->errorBuffer,replyBufferLen); + return 0; + } +} +/*====================================================================*/ +static int A1931Init(pEVDriver pData){ + pA1931 self = NULL; + + self = (pA1931)pData->pPrivate; + assert(self); + + self->devID = GPIBattach(self->gpib,0,self->gpibAddress,0,13,0,0); + if(self->devID < 0){ + return 0; + } + return 1; +} +/*====================================================================*/ +static int A1931Close(pEVDriver pData){ + pA1931 self = NULL; + + self = (pA1931)pData->pPrivate; + assert(self); + + GPIBdetach(self->gpib,self->devID); + self->devID = 0; + return 1; +} +/*===================================================================*/ +static int A1931Get(pEVDriver pData,float *fPos){ + pA1931 self = NULL; + char buffer[132], command[50]; + int status; + + self = (pA1931)pData->pPrivate; + assert(self); + + sprintf(command,"?TEMP%1.1d",self->sensor); + status = A1931command(pData,command,buffer,131); + if(!status){ + return 0; + } + sscanf(buffer,"%f",fPos); + return 1; +} +/*=====================================================================*/ +static int A1931Set(pEVDriver pData, float fNew){ + pA1931 self = NULL; + char buffer[132], command[50]; + int status; + + self = (pA1931)pData->pPrivate; + assert(self); + + sprintf(command,"SET%1.1d=%f",self->sensor,fNew); + status = A1931command(pData,command,buffer,131); + if(!status){ + return 0; + } + return 1; +} +/*====================================================================*/ +static int A1931error(pEVDriver pData, int *iCode, char *errBuff, int bufLen){ + pA1931 self = NULL; + char pError[256]; + + self = (pA1931)pData->pPrivate; + assert(self); + + *iCode = self->errorCode; + sprintf(pError,"ERROR: %s",self->errorBuffer); + strncpy(errBuff,pError,bufLen); + return 1; +} +/*====================================================================*/ +static int A1931fix(pEVDriver pData, int iCode){ + pA1931 self = NULL; + char pError[256]; + + self = (pA1931)pData->pPrivate; + assert(self); + + if(iCode == COMMERROR){ + GPIBclear(self->gpib,self->devID); + return DEVREDO; + } + return DEVFAULT; +} +/*=====================================================================*/ +pEVDriver CreateA1931Driver(int argc, char *argv[]){ + pEVDriver self = NULL; + pA1931 priv = NULL; + + if(argc < 2){ + return NULL; + } + + /* + allocate space + */ + self = CreateEVDriver(argc,argv); + priv = (pA1931)malloc(sizeof(A1931)); + if(self == NULL || priv == NULL){ + return NULL; + } + memset(priv,0,sizeof(A1931)); + self->pPrivate = priv; + self->KillPrivate = free; + + /* + initialize + */ + priv->gpib = (pGPIB)FindCommandData(pServ->pSics,argv[0],"GPIB"); + if(!priv->gpib){ + DeleteEVDriver(self); + return NULL; + } + priv->sensor = 1; + priv->gpibAddress = atoi(argv[1]); + + /* + initialize function pointers + */ + self->Send = A1931command; + self->Init = A1931Init; + self->Close = A1931Close; + self->GetValue = A1931Get; + self->SetValue = A1931Set; + self->GetError = A1931error; + self->TryFixIt = A1931fix; + + return self; +} +/*=======================================================================*/ +static int downloadFile(pA1931 self, FILE *fd){ + char buffer[132], *pPtr; + int status; + + while(1){ + if(fgets(buffer,130,fd) == NULL){ + self->errorCode = FILEERROR; + strcpy(self->errorBuffer,"Failed to read from file"); + return 0; + } + if(strstr(buffer,"$END") != NULL){ + break; + } + status = GPIBsend(self->gpib,self->devID,buffer,(int)strlen(buffer)); + if(status < 0){ + self->errorCode = COMMERROR; + GPIBerrorDescription(self->gpib,status,self->errorBuffer,131); + return 0; + } + pPtr = GPIBreadTillTerm(self->gpib,self->devID,10); + if(pPtr[0] == '#'){ + self->errorCode = A1931ERROR; + strcpy(self->errorBuffer,pPtr); + free(pPtr); + return 0; + } + free(pPtr); + } + return 1; +} +/*=======================================================================*/ +int A1931Action(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]){ + pEVControl pEV = NULL; + pA1931 self = NULL; + char buffer[256]; + char error[132]; + FILE *fd = NULL; + int status, iCode; + + pEV = (pEVControl)pData; + assert(pEV); + self = (pA1931)pEV->pDriv->pPrivate; + assert(self); + + if(argc > 1){ + strtolower(argv[1]); + if(strcmp(argv[1],"sensor") == 0){ + if(argc > 2){ + /* set case */ + if(!SCMatchRights(pCon,usUser)){ + return 0; + } + self->sensor = atoi(argv[2]); + SCSendOK(pCon); + return 1; + } else { + /* get case */ + sprintf(buffer,"%s.sensor = %d",argv[0],self->sensor); + SCWrite(pCon,buffer,eValue); + return 1; + } + }else if(strcmp(argv[1],"list") == 0){ + sprintf(buffer,"%s.sensor = %d",argv[0],self->sensor); + SCWrite(pCon,buffer,eValue); + return EVControlWrapper(pCon,pSics,pData,argc,argv); + } else if(strcmp(argv[1],"file") == 0){ + if(!SCMatchRights(pCon,usUser)){ + return 0; + } + if(argc < 3){ + SCWrite(pCon,"ERROR: need filename argument",eError); + return 0; + } + fd = fopen(argv[2],"r"); + if(fd == NULL){ + sprintf(buffer,"ERROR: failed to open %s", argv[2]); + SCWrite(pCon,buffer,eError); + return 0; + } + status = downloadFile(self,fd); + fclose(fd); + if(!status){ + A1931error(pEV->pDriv,&iCode,error,131); + sprintf(buffer,"%s while transfering file", error); + SCWrite(pCon,buffer,eError); + return 0; + } + SCSendOK(pCon); + return 1; + } + } + return EVControlWrapper(pCon,pSics,pData,argc,argv); +} diff --git a/A1931.h b/A1931.h new file mode 100644 index 00000000..954813f7 --- /dev/null +++ b/A1931.h @@ -0,0 +1,20 @@ +/*------------------------------------------------------------------------- + This is the header file for a driver for the Risoe A1931a temperature + controller. This driver controls the device through a GPIB interface. + + copyright: see file COPYRIGHT + + Mark Koennecke, February 2003 + -------------------------------------------------------------------------*/ +#ifndef A1931A +#define A19131A + +#include "sics.h" + +pEVDriver CreateA1931Driver(int argc, char *argv[]); + +int A1931Action(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + + +#endif diff --git a/Makefile b/Makefile index 3b44d34c..cb46a86a 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \ polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \ s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.o \ - ecbcounter.o hmdata.o tdchm.o nxscript.o + ecbcounter.o hmdata.o tdchm.o nxscript.o A1931.o MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/counter.c b/counter.c index b84e41a1..7dcac5ff 100644 --- a/counter.c +++ b/counter.c @@ -902,7 +902,7 @@ self->pDriv->fLastCurrent, GetMonitor(self,4,pCon)/100000); } - SCWrite(pCon,pBueffel,eWarning); + SCWrite(pCon,pBueffel,eValue); return 1; case 12: /* gettime */ fVal = GetCountTime(self,pCon); diff --git a/ecb.c b/ecb.c index cc5ed1e5..50a878a6 100644 --- a/ecb.c +++ b/ecb.c @@ -352,6 +352,9 @@ int ECBAction(SConnection *pCon, SicsInterp *pSics, void *pData, ecbClear(self); SCSendOK(pCon); return 1; + }else if(strcmp(argv[1],"toint")== 0){ + sprintf(pBuffer,"%d",argv[2][0]); + SCWrite(pCon,pBuffer,eValue); } else { SCWrite(pCon,"ERROR: ECB does not understand keyword", eError); return 0; diff --git a/ecbdriv.c b/ecbdriv.c index c1be5d8c..11b31b09 100644 --- a/ecbdriv.c +++ b/ecbdriv.c @@ -448,6 +448,72 @@ static int loadOffset(pECBMotDriv self, float offset){ } return status; } +/*--------------------------------------------------------------------- + This loads the gearing parameters for the CRT display. This should + not have any influence on the running of the motor + ------------------------------------------------------------------------*/ +static double To_ten(int v) { + double vv; + + + vv = 1.0; + if (v == 1) + vv = 10.0; + if (v == 2) + vv = 100.0; + if (v == 3) + vv = 1000.0; + if (v == 4) + vv = 10000.0; + if (v == 5) + vv = 100000.0; + if (v == 6) + vv = 1000000.0; + if (v == 7) + vv = 10000000.0; + return (vv); +} +/*----------------------------------------------------------------------*/ +static int loadGearing(pECBMotDriv self){ + int status; + double dgear; + int gdec, dec = 0, ratio; + Ecb_pack data; + Z80_reg in, out; + + in.c = self->ecbIndex; + dgear = (double) ObVal(self->driverPar,STEPS2DEG);; + + /* Calculate decimals in display and gearing ratio for the ECB system*/ + gdec = (int) (1.0 + (log10(dgear - .01))); + if (dec < gdec) + dec = gdec; /* Display does not work with decimals < gdec */ + ratio = (long) (0.5 + dgear*To_ten(6 + 1 - dec)); + + data.result = ratio; + in.b = data.b.byt2; + in.d = data.b.byt1; + in.e = data.b.byt0; + status = ecbExecute(self->ecb,174,in,&out); + if(status != 1){ + self->errorCode = COMMERROR; + } + + if(ObVal(self->driverPar,ENCODER) == 0){ + in.b = self->ecbIndex; + } else { + in.b = 1; + in.e = (unsigned char)ObVal(self->driverPar,ENCODER); + } + in.d = 0; + in.e = dec; + status = ecbExecute(self->ecb,173,in,&out); + if(status != 1){ + self->errorCode = COMMERROR; + } + + return 1; +} /*----------------------------------------------------------------------*/ static int downloadECBParam(pECBMotDriv self){ int status, parameter; @@ -504,6 +570,10 @@ static int downloadECBParam(pECBMotDriv self){ self->driverPar[MULT].fVal = .0; } + if(status = loadGearing(self) <= 0){ + return 0; + } + return 1; } /*--------------------------------------------------------------------*/ diff --git a/evcontroller.c b/evcontroller.c index 627ea8ad..584f3a3b 100644 --- a/evcontroller.c +++ b/evcontroller.c @@ -61,6 +61,7 @@ #include "ltc11.h" #include "eurodriv.h" #include "el755driv.h" +#include "A1931.h" #include "tecsdriv.h" #include "chadapter.h" #include "status.h" @@ -1410,6 +1411,45 @@ extern pEVDriver CreateSLSDriv(int argc, char *argv[]); } EVRegisterController(FindEMON(pSics),argv[2],pNew, pCon); SCSendOK(pCon); + return 1; + }else if(strcmp(argv[3],"a1931") == 0) + /* Risoe A1931 temperature controller*/ + { + /* Create a driver */ + pDriv = CreateA1931Driver(argc-4,&argv[4]); + if(!pDriv) + { + SCWrite(pCon,"ERROR: failed to create A1931 device driver", + eError); + return 0; + } + /* got a driver, initialise everything */ + pNew = CreateEVController(pDriv,argv[2],&iRet); + if(!pNew) + { + SCWrite(pCon,"ERROR creating Environment Controller",eError); + return 0; + } + if(!iRet) + { + SCWrite(pCon,"ERROR: problem initialising Environment controller", + eError); + pDriv->GetError(pDriv,&iRet,pError,131); + sprintf(pBueffel,"HW reported: %s",pError); + SCWrite(pCon,pBueffel,eError); + } + /* install command */ + iRet = AddCommand(pSics,argv[2],A1931Action,DeleteEVController, + pNew); + if(!iRet) + { + sprintf(pBueffel,"ERROR: duplicate command %s not created",argv[2]); + DeleteEVController((void *)pNew); + SCWrite(pCon,pBueffel,eError); + return 0; + } + EVRegisterController(FindEMON(pSics),argv[2],pNew, pCon); + SCSendOK(pCon); return 1; } else if(strcmp(argv[3],"tcl") == 0) /* Tcl driver */ diff --git a/gpib.w b/gpib.w index 0328f1b3..2297adca 100644 --- a/gpib.w +++ b/gpib.w @@ -40,6 +40,7 @@ The interface for this controller: int GPIBdetach(pGPIB self, int devID); int GPIBsend(pGPIB self, int devID, void *buffer, int bytesToWrite); int GPIBread(pGPIB self, int devID, void *buffer, int bytesToRead); + char *GPIBreadTillTerm(pGPIB self, int devID, int terminator); void GPIBclear(pGPIB self, int devID); void GPIBerrorDescription(pGPIB self, int code, char *buffer, int maxBuffer); diff --git a/gpibcontroller.c b/gpibcontroller.c index 583b1a1c..e077cecd 100644 --- a/gpibcontroller.c +++ b/gpibcontroller.c @@ -32,8 +32,30 @@ int GPIBread(pGPIB self, int devID, void *buffer, int bytesToRead){ return self->read(devID, buffer,bytesToRead); } /*--------------------------------------------------------------------*/ +char *GPIBreadTillTerm(pGPIB self, int devID, int terminator){ + unsigned char buchstabe[2]; + Tcl_DString buffer; + char *result = NULL; + int status; + + Tcl_DStringInit(&buffer); + buchstabe[1] = '\0'; + GPIBread(self,devID,buchstabe,1); + while(buchstabe[0] != (unsigned char)terminator){ + Tcl_DStringAppend(&buffer,buchstabe,-1); + status = GPIBread(self,devID,buchstabe,1); + if(status != 1){ + Tcl_DStringAppend(&buffer,"GPIB Read Error",-1); + break; + } + } + result = strdup(Tcl_DStringValue(&buffer)); + Tcl_DStringFree(&buffer); + return result; +} +/*--------------------------------------------------------------------*/ void GPIBclear(pGPIB self, int devID){ - return self->clear(devID); + self->clear(devID); } /*--------------------------------------------------------------------*/ void GPIBerrorDescription(pGPIB self, int code, char *buffer, int maxBuf){ @@ -83,8 +105,9 @@ int GPIBAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){ pGPIB self = (pGPIB)pData; int boardID, devID, tmo, count, eoi, eot, address, - secondaryAddress, status; + secondaryAddress, status, terminator; char pBuffer[1024]; + char *result = NULL; assert(self != NULL); @@ -151,11 +174,28 @@ int GPIBAction(SConnection *pCon, SicsInterp *pSics, void *pData, SCWrite(pCon,pBuffer,eError); return 0; } + } else if(strcmp(argv[1],"clear") == 0){ + /* + clear command + */ + if(argc < 2){ + SCWrite(pCon,"ERROR: insufficient number of arguments to clear", + eError); + return 0; + } + if(Tcl_GetInt(pSics->pTcl,argv[2],&devID) != TCL_OK){ + SCWrite(pCon,"ERROR: failed to convert arguments to integer", + eError); + return 0; + } + GPIBclear(self,devID); + SCSendOK(pCon); + return 1; } else if(strcmp(argv[1],"send") == 0){ /* send command */ - if(argc < 2){ + if(argc < 4){ SCWrite(pCon,"ERROR: insufficient number of arguments to send", eError); return 0; @@ -165,8 +205,38 @@ int GPIBAction(SConnection *pCon, SicsInterp *pSics, void *pData, eError); return 0; } - Arg2Text(argc-2,argv+2,pBuffer,1023); - status = GPIBsend(self,devID,pBuffer, strlen(pBuffer)); + Arg2Text(argc-3,argv+3,pBuffer,1023); + status = GPIBsend(self,devID,pBuffer, (int)strlen(pBuffer)); + if(status > 0){ + SCSendOK(pCon); + return 1; + } else { + sprintf(pBuffer,"ERROR: error %d on send", status); + SCWrite(pCon,pBuffer,eError); + return 0; + } + } else if(strcmp(argv[1],"sendwithterm") == 0){ + /* + send command + */ + if(argc < 5){ + SCWrite(pCon,"ERROR: insufficient number of arguments to sendwithterm", + eError); + return 0; + } + if(Tcl_GetInt(pSics->pTcl,argv[2],&devID) != TCL_OK){ + SCWrite(pCon,"ERROR: failed to convert arguments to integer", + eError); + return 0; + } + if(Tcl_GetInt(pSics->pTcl,argv[4],&terminator) != TCL_OK){ + SCWrite(pCon,"ERROR: failed to convert arguments to integer", + eError); + return 0; + } + strncpy(pBuffer,argv[3], 1024); + pBuffer[strlen(pBuffer)] = (char)terminator; + status = GPIBsend(self,devID,pBuffer, (int)strlen(pBuffer)); if(status > 0){ SCSendOK(pCon); return 1; @@ -198,6 +268,34 @@ int GPIBAction(SConnection *pCon, SicsInterp *pSics, void *pData, SCWrite(pCon,pBuffer,eError); return 0; } + } else if(strcmp(argv[1],"readtillterm") == 0){ + /* + read command + */ + if(argc < 3){ + SCWrite(pCon,"ERROR: insufficient number of arguments to read", + eError); + return 0; + } + if(Tcl_GetInt(pSics->pTcl,argv[2],&devID) != TCL_OK){ + SCWrite(pCon,"ERROR: failed to convert arguments to integer", + eError); + return 0; + } + if(Tcl_GetInt(pSics->pTcl,argv[3],&terminator) != TCL_OK){ + SCWrite(pCon,"ERROR: failed to convert arguments to integer", + eError); + return 0; + } + result = GPIBreadTillTerm(self,devID,terminator); + if(result != NULL){ + SCWrite(pCon,result,eValue); + free(result); + return 1; + } else { + SCWrite(pCon,"ERROR: failed to read at GPIB",eError); + return 0; + } } else { SCWrite(pCon,"ERROR: command not recognized",eError); return 0; diff --git a/gpibcontroller.h b/gpibcontroller.h index 943c22a8..62f19b5e 100644 --- a/gpibcontroller.h +++ b/gpibcontroller.h @@ -29,6 +29,7 @@ int GPIBdetach(pGPIB self, int devID); int GPIBsend(pGPIB self, int devID, void *buffer, int bytesToWrite); int GPIBread(pGPIB self, int devID, void *buffer, int bytesToRead); + char *GPIBreadTillTerm(pGPIB self, int devID, int terminator); void GPIBclear(pGPIB self, int devID); void GPIBerrorDescription(pGPIB self, int code, char *buffer, int maxBuffer); diff --git a/hmdata.c b/hmdata.c index fb564c8e..1c7bdf86 100644 --- a/hmdata.c +++ b/hmdata.c @@ -56,6 +56,7 @@ static int resizeBuffer(pHMdata self){ return 0; } memset(self->localBuffer,0,size*sizeof(HistInt)); + self->updateFlag = 1; return 1; } /*-----------------------------------------------------------------------*/ diff --git a/motor.c b/motor.c index e1ea8f1f..629da7fe 100644 --- a/motor.c +++ b/motor.c @@ -917,7 +917,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray); return 0; } } - if(strcmp(argv[2],"ecb") == 0) + else if(strcmp(argv[2],"ecb") == 0) { iD = argc - 3; pDriver = CreateECBMotor(pCon,iD,&argv[3]); @@ -988,7 +988,7 @@ extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray); } else { - sprintf(pBueffel,"Motor Type %s cot recognized for motor %s", + sprintf(pBueffel,"Motor Type %s not recognized for motor %s", argv[2],argv[1]); SCWrite(pCon,pBueffel,eError); return 0; diff --git a/nxscript.c b/nxscript.c index 76c3a633..a656e67d 100644 --- a/nxscript.c +++ b/nxscript.c @@ -19,6 +19,7 @@ #include "HistMem.h" #include "motor.h" #include "counter.h" +#include "udpquieck.h" #include "nxdict.h" #include "nxscript.h" /*============== a personal data structure ============================*/ @@ -30,15 +31,23 @@ typedef struct { /*======================== Action =======================================*/ static int handleFileOperations(SConnection *pCon, pNXScript self, int argc, char *argv[]){ - int status; + int status,i, iVal; NXaccess access; char buffer[512]; if(strcmp(argv[1],"close") == 0){ + /* + close everything! and send a message to trigger file synchronisation + to the central server + */ + i = 511; + iVal = NX_CHAR; + NXgetattr(self->fileHandle,"file_name",buffer,&i,&iVal); NXclose(&self->fileHandle); NXDclose(self->dictHandle,NULL); self->fileHandle = NULL; self->dictHandle = NULL; + SendQuieck(QUIECK,buffer); SCSendOK(pCon); return 1; } else if(strcmp(argv[1],"reopen") == 0){ diff --git a/sans2.tcl b/sans2.tcl index db92e962..38a11ab5 100644 --- a/sans2.tcl +++ b/sans2.tcl @@ -534,8 +534,9 @@ proc sans2rack args { Publish sans2rack User #---------for testing purposes anticollision script sans2rack #====================== PSI Motoren =================================== -Motor ome SIM -180. 180. .1 -.1 -Motor chi SIM -20. 20. .1 -.1 +Motor ome EL734 sans2 4000 2 1 +Motor chi EL734 sans2 4000 2 2 +Motor tilt EL734 sans2 4000 3 1 #====================== Multi Motor Setup ============================== MakeMulti detector detector alias dz x @@ -586,6 +587,17 @@ banana init banana exponent 6 banana CountMode timer banana preset 100 +#=========================== velocity selector ======================== +VelocitySelector nvs tilt SIM +nvs add -20 28800 +nvs add 3600 4300 +nvs add 7600 9600 +nvs add 13400 13450 +nvs add 24200 24250 +MakeSANSWave lambda nvs +emon unregister nvswatch +#===================================== auxiliary hardware ============== +set distoCON [gpib attach 0 14 0 13 0 1] #===================================== data file writing ================ MakeNXScript #===================================== install commands ================== @@ -594,6 +606,8 @@ MakeRuenBuffer commandlog auto #=================================== load specific command file =========== source $root/sans2com.tcl +#=================================== load display definition ============= +source $root/sans2dis.tcl diff --git a/sans2com.tcl b/sans2com.tcl index 5558f928..dee4e901 100644 --- a/sans2com.tcl +++ b/sans2com.tcl @@ -21,6 +21,11 @@ if { [info exists sansinit] == 0 } { Publish count User Publish Repeat User Publish storedata User + Publish disto Spy + Publish statusinfo Spy + Publish displaycontrol User + Publish displayunits User + Publish setdispar User } #======================== general useful stuff ====================== proc SplitReply { text } { @@ -135,16 +140,13 @@ proc count { {mode NULL } { preset NULL } } { set b [banana CountMode] set bb [SplitReply $b] set tt [sicstime] - set sn [sample] + set sn [SplitReply [sample]] starttime [sicstime] ClientPut [format " Starting counting in %s mode with a preset of %s" \ $bb $aa ] ClientPut [format "Count started at %s" $tt] ClientPut [format " sample name: %s" $sn] #------- count - banana InitVal 0 - wait 1 - set ret [catch {Success} msg] banana count set ret [catch {Success} msg] #------- StoreData @@ -172,9 +174,11 @@ proc writeBeforeSample args { nxscript puttext sname SINQ, Paul Scherrer Institut nxscript puttext stype Continuous flux spallation source nxscript puttext vname Dornier velocity selector -# writeFloatVar vrot velo -# writeFloatVar vtilt tilt -# writeFloatvar vlambda lambda + set res [nvs list] + set l [split $res "\n"] + nxscript putfloat vrot [SplitReply [lindex $l 0]] + writeFloatVar vtilt tilt + writeFloatvar vlambda lambda writeFloatVar colli collimator # writeFloatVar atti attenuator } @@ -255,7 +259,76 @@ proc storedata args { nxscript close } - - - - +#========================= laser distance reading ======================== +proc disto args { + global distoCON + gpib sendwithterm $distoCON a 13 + gpib readtillterm $distoCON 10 + gpib sendwithterm $distoCON g 13 + set result [gpib readtillterm $distoCON 10] + set l [split $result " +" ] + return [string trim [lindex $l 1] 0] +} +#========================= helper function for status display ============ +proc statusinfo {} { + append result "SICS = " [SplitReply [status]] " \n" + append result [title] " \n" + append result [sample] " \n" + append result [user] " \n" + set tst [nvs list] + set l [split $tst "\n"] + append result "Velocity selector rotation = " \ + [SplitReply [lindex $l 0]] " \n" + append result "lambda = " [SplitReply [lambda]] " \n" + append result "Collimation length = " [SplitReply [collimator]] " \n" + append result "filenumber = " [SplitReply [sicsdatanumber]] " \n" + return $result +} +#============= scripts for controlling the ECB display unit ============ +proc disloadpar {unit offset val} { + ecb1 func 166 0 [expr $unit -1] $offset $val +} +#----------------------------------------------------------------------- +proc startdisplay {} { + ecb1 func 128 0 0 0 1 +} +#---------------------------------------------------------------------- +proc stopdisplay {} { + ecb1 func 129 0 0 0 0 +} +#----------------------------------------------------------------------- +proc setdispar {unit name key parnum} { + switch $key { + timer {set type 1} + scaler {set type 2} + ratemeter {set type 4} + motor {set type 3} + encoder {set type 5} + default { + error "Unknown parameter key" + } + } + stopdisplay + disloadpar $unit 0 [ecb1 toint [string index $name 0]] + disloadpar $unit 1 [ecb1 toint [string index $name 1]] + disloadpar $unit 2 [ecb1 toint [string index $name 2]] + disloadpar $unit 3 $parnum + disloadpar $unit 4 $type + startdisplay +} +#-------------------------------------------------------------------------- +proc cleardisplay {} { + ecb1 func 131 0 0 0 0 +} +#------------------------------------------------------------------------- +proc defdisplay { num} { + ecb1 func 166 1 $num 0 0 +} +#------------------------------------------------------------------------ +proc displayunits { u1 u2 u3 u4} { + ecb1 func 130 $u1 $u2 $u3 $u4 +} +#----------------------------------------------------------------------- +proc displaycontrol {command} { + ecb1 func 170 0 0 $command 0 +} \ No newline at end of file diff --git a/sans2dis.tcl b/sans2dis.tcl new file mode 100644 index 00000000..cd3fb092 --- /dev/null +++ b/sans2dis.tcl @@ -0,0 +1,39 @@ +#-------------------------------------------------------------------------- +# display control file for SANS-II +# +# A place of genuine mystery and magic hacked from the appropriate TASCOM +# file. +# +# Mark Koennecke, February 2003 +#------------------------------------------------------------------------ +setdispar 1 RmS ratemeter 1 +setdispar 2 RmM ratemeter 1 +setdispar 3 RmF ratemeter 1 +setdispar 4 MON scaler 1 +setdispar 5 TIM timer 0 +setdispar 6 "I " scaler 2 +setdispar 7 "sr " motor 1 +setdispar 8 stx motor 2 +setdispar 9 stz motor 3 +setdispar 10 "sc " motor 4 +setdispar 11 "gu " motor 5 +setdispar 12 "gl " motor 6 +setdispar 13 "tu " motor 7 +setdispar 14 "tl " motor 8 +setdispar 15 "om " encoder 1 +setdispar 16 "sz " motor 10 +setdispar 17 "sx " motor 11 +setdispar 18 "sy " motor 12 +setdispar 19 "dz " motor 13 +setdispar 20 "dh " motor 14 +setdispar 21 "dv " motor 15 +setdispar 22 at1 motor 16 +setdispar 23 at2 motor 17 +setdispar 24 aux scaler 3 +setdispar 25 "I4 " scaler 4 +setdispar 26 "I5 " scaler 5 +setdispar 27 "I6 " scaler 6 +setdispar 28 RdS ratemeter 2 +setdispar 29 RdM ratemeter 2 +setdispar 30 RdF ratemeter 2 + diff --git a/sicsstat.tcl b/sicsstat.tcl index 008c022f..0b6ab7c4 100644 --- a/sicsstat.tcl +++ b/sicsstat.tcl @@ -1,8 +1,16 @@ banana CountMode timer -banana preset 100.000000 +banana preset 10.000000 # Counter counter -counter SetPreset 12.000000 +counter SetPreset 10.000000 counter SetMode Timer +# Motor tilt +tilt sign 1.000000 +tilt SoftZero 0.000000 +tilt SoftLowerLim -403.623993 +tilt SoftUpperLim 396.376007 +tilt Fixed -1.000000 +tilt InterruptMode 0.000000 +tilt AccessCode 2.000000 # Motor chi chi sign 1.000000 chi SoftZero 0.000000 @@ -157,7 +165,7 @@ sr InterruptMode 0.000000 sr AccessCode 2.000000 sampletable UNKNOWN sampletable setAccess 2 -starttime UNKNOWN +starttime 2003-02-13 13:52:54 starttime setAccess 2 batchroot /afs/psi.ch/user/k/koennecke/src/sics batchroot setAccess 2 diff --git a/tdchm.c b/tdchm.c index 15768905..7cd66c73 100644 --- a/tdchm.c +++ b/tdchm.c @@ -486,7 +486,13 @@ static int TDCGetHistogram(pHistDriver self, SConnection *pCon, return HWFault; } - address = 0; + address = (unsigned short)iStart; + /* + this is a fix because the TDC cannot send more then 64KB + */ + if(length >= 16384){ + length = 16383; + } byteCount = length *4; status = ecbDMARead(tdc->tdc,address,pData,byteCount); if(status != 1){