- Driver for the Risoe Temperature controller
- HM is now working - display code added
This commit is contained in:
338
A1931.c
Normal file
338
A1931.c
Normal file
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#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);
|
||||
}
|
20
A1931.h
Normal file
20
A1931.h
Normal file
@ -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
|
2
Makefile
2
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
|
||||
|
@ -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);
|
||||
|
3
ecb.c
3
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;
|
||||
|
70
ecbdriv.c
70
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;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
@ -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 */
|
||||
|
1
gpib.w
1
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);
|
||||
|
108
gpibcontroller.c
108
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;
|
||||
|
@ -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);
|
||||
|
1
hmdata.c
1
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;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
4
motor.c
4
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;
|
||||
|
11
nxscript.c
11
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){
|
||||
|
18
sans2.tcl
18
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
|
||||
|
||||
|
||||
|
||||
|
95
sans2com.tcl
95
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
|
||||
}
|
39
sans2dis.tcl
Normal file
39
sans2dis.tcl
Normal file
@ -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
|
||||
|
14
sicsstat.tcl
14
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
|
||||
|
8
tdchm.c
8
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){
|
||||
|
Reference in New Issue
Block a user