From 98cfb3ddda9f2691f53e52650b829f055b5cfac4 Mon Sep 17 00:00:00 2001
From: cvs
Date: Wed, 19 Feb 2003 08:29:46 +0000
Subject: [PATCH] - Implemented defpos for multiple motors - Implemented
automatic backup on parameter change - Implemented silent restore - Cleaned a
couple of unused flags from connection object
---
Makefile | 48 +++++-----
SCinter.c | 11 +--
conman.c | 154 +++++++++++++++++++++++++++-----
conman.h | 22 +++--
counter.c | 10 ++-
devexec.c | 4 -
doc/manager/hwini.htm | 199 +++++++++++++++++++++++++++++++++++++++++-
doc/user/sanscom.htm | 4 +-
drive.c | 1 -
ecb.c | 7 +-
fitcenter.c | 1 -
gpibcontroller.c | 13 +--
histmem.c | 5 +-
hkl.c | 2 -
hmdata.c | 5 ++
macro.c | 1 -
motor.c | 4 +-
mumo.c | 61 ++++++++++++-
mumo.i | 2 +
mumoconf.c | 2 +-
nxscript.c | 2 +-
sans2com.tcl | 4 +-
scan.c | 5 ++
sicscron.c | 1 -
sicvar.c | 1 +
sinqhm/SinqHM_def.h | 2 +-
slsmagnet.c | 1 +
status.c | 11 +++
tasdrive.c | 1 -
tasscan.c | 7 +-
tdchm.c | 1 +
31 files changed, 491 insertions(+), 101 deletions(-)
diff --git a/Makefile b/Makefile
index cb46a86a..8ee274a4 100644
--- a/Makefile
+++ b/Makefile
@@ -16,12 +16,12 @@ FORTIFYOBJ = fortify.o strdup.o
#==========================================================================
# assign if the National Instrument GPIB driver is available
-NI= -DHAVENI
-NIOBJ= nigpib.o
-NILIB=-lgpibenet
-#NI=
-#NIOBJ=
-#NILIB=
+#NI= -DHAVENI
+#NIOBJ= nigpib.o
+#NILIB=-lgpibenet
+NI=
+NIOBJ=
+NILIB=
#----- comment or uncomment if a difrac version is required
# Do not forget to remove or add comments to ofac.c as well if changes
@@ -72,18 +72,18 @@ VELOOBJ = velo.o velosim.o velodorn.o velodornier.o
#----- comment or uncomment the following according to operating system
#------------- for Digital Unix
-#BINTARGET = bin
-#HDFROOT=/data/lnslib
-#CC=cc
-#EXTRA=
+BINTARGET = bin
+HDFROOT=/data/lnslib
+CC=cc
+EXTRA=
#CFLAGS = -I$(HDFROOT)/include -Ihardsup -DHDF4 -DHDF5 -I. -std1 \
# -g -warnprotos -c
-#CFLAGS = -I$(HDFROOT)/include -DFORTIFY -DHDF4 -DHDF5 -Ihardsup -g \
-# -std1 -warnprotos -c
-#LIBS = -L$(HDFROOT)/lib -Lhardsup -lhlib -Lmatrix -lmatrix -Ltecs \
-# -ltecsl -ltcl8.0 -lfor $(HDFROOT)/lib/libhdf5.a \
-# $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
-# $(HDFROOT)/lib/libjpeg.a -lz -lm -ll -lc
+CFLAGS = -I$(HDFROOT)/include -DFORTIFY -DHDF4 -DHDF5 -Ihardsup -g \
+ -std1 -warnprotos -c
+LIBS = -L$(HDFROOT)/lib -Lhardsup -lhlib -Lmatrix -lmatrix -Ltecs \
+ -ltecsl -ltcl8.0 -lfor $(HDFROOT)/lib/libhdf5.a \
+ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \
+ $(HDFROOT)/lib/libjpeg.a -lz -lm -ll -lc
#------- for cygnus
#HDFROOT=../HDF411
@@ -94,16 +94,16 @@ VELOOBJ = velo.o velosim.o velodorn.o velodornier.o
# -lmfhdf -ldf -ljpeg -lz -lm
#---------- for linux
-BINTARGET=../../bin
-HDFROOT=$(SINQDIR)/linux
-CC=gcc
+#BINTARGET=../../bin
+#HDFROOT=$(SINQDIR)/linux
+#CC=gcc
#CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) -Ihardsup \
# -fwritable-strings -DCYGNUS -DNONINTF -g -c
-CFLAGS = -I$(HDFROOT)/include -DFORTIFY -DHDF4 -DHDF5 $(NI) -Ihardsup \
- -fwritable-strings -DCYGNUS -DNONINTF -g -c
-LIBS= -L$(HDFROOT)/lib -Lhardsup -Ltecs -ltecsl -Lmatrix -lmatrix -lhlib \
- $(NILIB) -ltcl -lhdf5 -lmfhdf -ldf -ljpeg -lz -lm -lg2c -ldl
-EXTRA=nintf.o
+#CFLAGS = -I$(HDFROOT)/include -DFORTIFY -DHDF4 -DHDF5 $(NI) -Ihardsup \
+# -fwritable-strings -DCYGNUS -DNONINTF -g -c
+#LIBS= -L$(HDFROOT)/lib -Lhardsup -Ltecs -ltecsl -Lmatrix -lmatrix -lhlib \
+# $(NILIB) -ltcl -lhdf5 -lmfhdf -ldf -ljpeg -lz -lm -lg2c -ldl
+#EXTRA=nintf.o
#---------------------------------
.c.o:
diff --git a/SCinter.c b/SCinter.c
index 9d464003..9308bd3f 100644
--- a/SCinter.c
+++ b/SCinter.c
@@ -222,15 +222,8 @@ extern char *SkipSpace(char *pPtr);
}
else
{
- if(!pCon->iDummy)
- {
- printf("Executing -> %s <- from dummy socket\n", pText);
- }
- else
- {
- sprintf(pBueffel,"Executing -> %s <- from sicscron",pText);
- SICSLogWrite(pBueffel,eCommand);
- }
+ printf("Executing -> %s <- from dummy socket\n", pText);
+ SICSLogWrite(pBueffel,eCommand);
}
/* convert to argc, argv */
diff --git a/conman.c b/conman.c
index a2a542b0..0d27705b 100644
--- a/conman.c
+++ b/conman.c
@@ -130,7 +130,6 @@ extern pServer pServ;
pRes->pSics = pSics;
pRes->eInterrupt = eContinue;
pRes->lMagic = CONMAGIC;
- pRes->iDummy = 0;
pRes->iLogin = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
@@ -216,7 +215,6 @@ extern pServer pServ;
pRes->pSics = pSics;
pRes->lMagic = CONMAGIC;
pRes->eInterrupt = eContinue;
- pRes->iDummy = 0;
pRes->iLogin = 0;
pRes->conStart = time(NULL);
pRes->write = SCNormalWrite;
@@ -546,6 +544,24 @@ extern pServer pServ;
}
return self->write(self,pBuffer,iOut);
}
+/*-------------------------------------------------------------------------*/
+writeFunc SCGetWriteFunc(SConnection *self)
+{
+ if(!VerifyConnection(self))
+ {
+ return 0;
+ }
+ return self->write;
+}
+/*-------------------------------------------------------------------------*/
+void SCSetWriteFunc(SConnection *self, writeFunc x)
+{
+ if(!VerifyConnection(self))
+ {
+ return;
+ }
+ self->write = x;
+}
/*--------------------------------------------------------------------------*/
static int SCNormalWrite(SConnection *self, char *buffer, int iOut)
{
@@ -658,6 +674,95 @@ extern pServer pServ;
}
return 1;
}
+/*--------------------------------------------------------------------------*/
+ int SCOnlySockWrite(SConnection *self, char *buffer, int iOut)
+ {
+ int i, iPtr, iRet;
+ char pBueffel[80];
+
+ if(!VerifyConnection(self))
+ {
+ return 0;
+ }
+
+ /* log it for any case */
+ if(self->pSock)
+ {
+ iRet = self->pSock->sockid;
+ }
+ else
+ {
+ iRet = 0;
+ }
+ sprintf(pBueffel,"Next line intended for socket: %d",iRet);
+ SICSLogWrite(pBueffel,eInternal);
+ SICSLogWrite(buffer,iOut);
+
+ /* put it into the interpreter if present */
+ if(SCinMacro(self))
+ {
+ InterpWrite(self->pSics,buffer);
+ }
+ else /* not in interpreter, normal logic */
+ {
+ /* is this really to be printed ? */
+ if(iOut < self->iOutput)
+ return 0;
+
+ /* the socket */
+ if(self->pSock)
+ {
+ if(self->iTelnet)
+ {
+ iRet = TelnetWrite(self->pSock,buffer);
+ }
+ else
+ {
+ iRet = NETWrite(self->pSock,buffer,strlen(buffer));
+ if(!HasNL(buffer))
+ {
+ iRet = NETWrite(self->pSock,"\n",sizeof("\n"));
+ }
+ }
+ if(!iRet)
+ {
+ SCnoSock(self);
+ WriteToCommandLog("SYS> ","Send broken to connection");
+ }
+ }
+ else
+ {
+ printf("%s \n",buffer);
+ }
+ }
+ return 1;
+ }
+/*--------------------------------------------------------------------------*/
+ int SCNotWrite(SConnection *self, char *buffer, int iOut)
+ {
+ int i, iPtr, iRet;
+ char pBueffel[80];
+
+ if(!VerifyConnection(self))
+ {
+ return 0;
+ }
+
+ /* log it for any case */
+ if(self->pSock)
+ {
+ iRet = self->pSock->sockid;
+ }
+ else
+ {
+ iRet = 0;
+ }
+ sprintf(pBueffel,"Next line intended for socket: %d",iRet);
+ SICSLogWrite(pBueffel,eInternal);
+ SICSLogWrite(buffer,iOut);
+
+ return 1;
+ }
/*--------------------------------------------------------------------------
This version writes only to configured log files but not to sockets.
Used for automatic file execution for the WWW interface
@@ -1176,33 +1281,13 @@ extern pServer pServ;
return self->eInterrupt;
}
-/*--------------------------------------------------------------------------*/
- void SCSetError(SConnection *self, int eCode)
- {
- if(!VerifyConnection(self))
- {
- return;
- }
-
- self->iErrCode = eCode;
- }
-/*---------------------------------------------------------------------------*/
- int SCGetError(SConnection *self)
- {
- if(!VerifyConnection(self))
- {
- return 0;
- }
-
- return self->iErrCode;
- }
/* --------------------------------------------------------------------------*/
int SCInvoke(SConnection *self, SicsInterp *pInter, char *pCommand)
{
int iRet;
long lLen;
const char *pResult = NULL;
- char *pBuffer = NULL;
+ char *pBuffer = NULL, *pFile = NULL;
char pBueffel[80];
int i, iSpace;
@@ -1238,8 +1323,20 @@ extern pServer pServ;
/* invoke */
self->inUse++;
self->eInterrupt = eContinue;
- self->iErrCode = OKOK;
+ self->parameterChange = 0;
iRet = InterpExecute(pInter,self,pCommand);
+ if(self->parameterChange == 1)
+ {
+ /*
+ automatically save changed parameters
+ */
+ pFile = IFindOption(pSICSOptions,"statusfile");
+ if(pFile != NULL)
+ {
+ WriteSicsStatus(pInter,pFile,0);
+ self->parameterChange = 0;
+ }
+ }
self->inUse--;
return iRet;
}
@@ -1701,3 +1798,12 @@ extern pServer pServ;
self->iGrab = 1;
}
}
+/*-----------------------------------------------------------------------*/
+void SCparChange(SConnection *self)
+{
+ if(!VerifyConnection(self))
+ {
+ return;
+ }
+ self->parameterChange = 1;
+}
diff --git a/conman.h b/conman.h
index faaa74fd..93011394 100644
--- a/conman.h
+++ b/conman.h
@@ -22,6 +22,9 @@
#define MAXLOGFILES 10
+typedef int (*writeFunc)(struct __SConnection *pCon,
+ char *pMessage, int iCode);
+
typedef struct __SConnection {
/* object basics */
pObjectDescriptor pDes;
@@ -35,8 +38,7 @@
int iTelnet;
int iOutput;
int iFiles;
- int (*write)(struct __SConnection *pCon,
- char *pMessage, int iCode);
+ writeFunc write;
mkChannel *pDataSock;
char *pDataComp;
int iDataPort;
@@ -45,10 +47,11 @@
int eInterrupt;
int iUserRights;
int inUse;
- int iDummy;
int iGrab;
- int iErrCode;
SicsInterp *pSics;
+
+ /* flag for parameter change */
+ int parameterChange;
/* a FIFO */
pCosta pStack;
@@ -88,19 +91,22 @@
int SCnoSock(SConnection *pCon);
int SCWriteUUencoded(SConnection *pCon, char *pName, void *iData, int iLen);
int SCWriteZipped(SConnection *pCon, char *pName, void *pData, int iDataLen);
+ writeFunc SCGetWriteFunc(SConnection *pCon);
+ void SCSetWriteFunc(SConnection *pCon, writeFunc x);
+ int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
+ int SCNotWrite(SConnection *self, char *buffer, int iOut);
/************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);
int SCUnregister(SConnection *pCon, void *pInter);
-/******************************* Error **************************************/
+/******************************* Interrupt *********************************/
void SCSetInterrupt(SConnection *self, int eCode);
int SCGetInterrupt(SConnection *self);
- void SCSetError(SConnection *pCon, int iCode);
- int SCGetError(SConnection *pCon);
/****************************** Macro ***************************************/
int SCinMacro(SConnection *pCon);
int SCsetMacro(SConnection *pCon, int iMode);
-
+/************************** parameters changed ? **************************/
+ void SCparChange(SConnection *pCon);
/* *************************** Info *************************************** */
int SCGetRights(SConnection *self);
int SCSetRights(SConnection *pCon, int iNew);
diff --git a/counter.c b/counter.c
index 7dcac5ff..72e0e849 100644
--- a/counter.c
+++ b/counter.c
@@ -230,7 +230,6 @@
{
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
SCSetInterrupt(pCon,eAbortBatch);
- SCSetError(pCon,eCt);
return eCt;
}
else
@@ -795,6 +794,7 @@
if(isAuthorised(pCon,usUser))
{
iRet2 = SetCounterPreset(self,PaRes.Arg[0].fVal);
+ SCparChange(pCon);
if(iRet2)
SCSendOK(pCon);
return iRet2;
@@ -823,12 +823,14 @@
if(strcmp(PaRes.Arg[0].text,"timer") == 0)
{
SetCounterMode(self,eTimer);
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
else if(strcmp(PaRes.Arg[0].text,"monitor") == 0)
{
SetCounterMode(self,ePreset);
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
@@ -869,6 +871,7 @@
return 0;
}
self->iExponent = PaRes.Arg[0].iVal;
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
case 8: /* GetExponent */
@@ -960,6 +963,7 @@
}
else
{
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
@@ -982,12 +986,14 @@
if(strcmp(PaRes.Arg[0].text,"timer") == 0)
{
SetCounterMode(self,eTimer);
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
else if(strcmp(PaRes.Arg[0].text,"monitor") == 0)
{
SetCounterMode(self,ePreset);
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
@@ -1025,6 +1031,7 @@
iRet2 = SetCounterPreset(self,PaRes.Arg[0].fVal);
if(iRet2)
SCSendOK(pCon);
+ SCparChange(pCon);
return iRet2;
}
else
@@ -1069,6 +1076,7 @@
PaRes.Arg[1].iVal, PaRes.Arg[2].fVal);
if(iRet == 1)
{
+ SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
diff --git a/devexec.c b/devexec.c
index d0becf37..954f87b3 100644
--- a/devexec.c
+++ b/devexec.c
@@ -196,7 +196,6 @@
if(!pNew)
{
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
- SCSetError(pCon,NOMEMORY);
return 0;
}
@@ -240,7 +239,6 @@
{
sprintf(pBueffel,"ERROR: cannot start device %s",name);
SCWrite(pCon,pBueffel,eError);
- SCSetError(self->pOwner,iRet);
DeleteDevEntry(pNew);
if(LLDcheck(self->iList) >= LIST_EMPTY)
{
@@ -398,7 +396,6 @@
self->iStatus = DEVDONE;
break;
case HWFault: /* real HW error: burning, no net etc.. */
- SCSetError(self->pOwner,iRet);
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
self->iStatus = DEVERROR;
@@ -442,7 +439,6 @@
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
- SCSetError(self->pOwner,eCode);
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
self->iStatus = DEVERROR;
diff --git a/doc/manager/hwini.htm b/doc/manager/hwini.htm
index 08010e30..ac53ad8e 100644
--- a/doc/manager/hwini.htm
+++ b/doc/manager/hwini.htm
@@ -63,6 +63,77 @@ number of the motor in the EL734DC motor controller.
Creates a piezo electric positioning device. Again the controller is a
Physik Instrumente controller. pararray has the same meaning as for the
C804 controller given above.
+Motor name ecb ecbcontroller ecb-number lowerlimit upperlimit
+This creates a motor which is controlled through the Risoe ECB
+ electronic. The parameters:
+
+- ecbcontroller
+
- The ECB controller to which this motor is connected to. See below
+for more on ECB controllers.
+
- ecb-number
+
- Number of the motor in the ECB system.
+
- lowerlimit
+
- The lower hardware limit for this motors operation
+
- upperlimit
+
- The upper hardware limit for this motors operation
+
+In contrast to normal motors, the ECB motors have quite a number of
+hardware parameters which must be configured. The general syntax to
+configure them is: motorname parametername value. The following
+parameters are available:
+
+- encoder
+
- 0 if there is no encoder for this motor, 1-3 for the encoder used
+for this motor.
+
- control
+
- The control bit flag. This falg determines if the motor sets a
+control bit in the ECB controller. This control bit can be used to
+drive air cushions and the like. If required set to 1, else leave at
+0.
+
- delay
+
- Delay time to wait after setting a control bit.
+
- range
+
- The speed range for the motor: 0 for slow, 1 for fast
+
- multi
+
- The ECB controller supports up to 24 motors. In some instances
+this is not enough. Then one ECB channel can be multiplexed into
+several motors. This flag (),1) determines if this is the case.
+
- multchan
+
- The multiplexer channel for a multiplexed motor.
+
- port
+
- The ECB port a multiplexed motor is using.
+
- acceleration
+
- The speed with which the motor accelerates to its final speed.
+
- rotation_dir
+
- Rotation direction of the motor.
+
- startspeed
+
- Starting speed of the motor.
+
- maxspeed
+
- The maximum speed for this motor.
+
- auto
+
- Speed in automatic mode
+
- manuell
+
- Speed used when driving the motor through the manual control box.
+
- offset
+
- When using an encoder: the offset between the motor zero and the
+encoder zero.
+
- dtolerance
+
- hardware tolerance of the motor.
+
- step2dig
+
- conversion factor from encoder steps to physical values.
+
- step2deg
+
- Conversion factor from motor pseudo encoder steps to physical
+values.
+
- backlash
+
- In order to correct for backlash, Risoe motors always approach a
+target position from the same direction. In order to do this the motor
+has to overshoot and drive back when driving in the wrong
+direction. The parameter backlash determines how much to overshoot.
+
+ECB motors have another quirck: 8 motors in a rack share a power
+supply! This has the consequence that only one of the 8 motors can run
+at any given time. In SICS this is directed through the anticollider
+module described elsewhere.
@@ -78,7 +149,10 @@ failures. This can be used in a instrument simulation server.
MakeCounter name EL737 host port chan
This command creates a single
counter name, using an EL737 driver. The counter is at host host, listening
-at port port and sits at serial port chan.
+at port port and sits at serial port chan.
+ MakeCounter name ecb ecb-controller
+Installs a counetr on top of the Risoe ECB hardware. The only
+parameter is the name of the ECB controller to use.
MakeHMControl name counter hm1 hm2 hm3
At some instruments (for instance TRICS) multiple counters or
histogram memories are controlled by a master counter which watches
@@ -109,8 +183,9 @@ HM. Histogram memory objects can be created using the command:
MakeHM name type
The parameter name specifies the name under which the HM will be
avialable in the system. type specifies which type of driver to use.
-Currently two types of drivers are supported: SIM for a simulated HM and
-SINQHM for the SINQ histogram memory. Please care to note, that the SINQHM
+Currently three types of drivers are supported: SIM for a simulated HM
+, SINQHM for the SINQ histogram memory and tdc for the Risoe histogram memory.
+ Please care to note, that the SINQHM
requires a EL737 counter box for count control. This counter must have been
defined before creating the HM object.
@@ -121,7 +196,7 @@ MakeHM banana SINQHM
banana configure HistMode Normal
banana configure OverFlowMode Ceil
banana configure Rank 1
-banana configure Length 400
+banana configure dim0 400
banana configure BinWidth 4
banana preset 100.
banana CountMode Timer
@@ -237,6 +312,122 @@ which the device is connected. This is usally the port number plus 3000.
To be expanded. Please note, that environment devices such as temperature
controllers are dynamically configured into the system at run time.
Therefore the necessary commands are described in the user documentation.
+
+GPIB Controller Access
+
+GPIB is yet another bus system. Up to 30 devices can share the bus and
+transfer data on it. SICS likest to speak to GPIB devices through the
+National Instrument ENET-100 TCP/IP bridge. In order for this to work
+the National Instruments driver software must have been installed on
+the computer running SICS. SICS has to be compiled with the define
+HAVENI defined and the proper paths to the header file and library
+configured. The an GPIB controller can be installed into SICS with the
+command:
+
+MakeGPIB name drivertype
+
+Name is the name under which the GPIB controller is addressable within
+SICS afterwards. drivertype is the driver to use for the GPIB
+device. Supported values are:
+
+- sim
+
- Simulation
+
- ni
+<>National instruments driver, see above.
+
+The GPIB controller supports a couple of commands for communicating
+with devices on the GPIB bus directly. Use with extra care because it
+is very easy to lock things up on the GPIB bus. In the following
+documantation of the command set it is assumed that a GPIB controller
+has been configured into the system under the name gpib>. Please
+note, that managers privilege is required in order to be allowed to
+wrestle with this controller.
+
+-
+
gpib attach controller-no gpib-address gpib-secondary timeout
+ eos eot
+This attaches the GPIB controller to a certain device at a certain
+ address for later communication. The return value is an integer
+ handle which will be used later on a s a handle devID when referring
+ to the conenction. The parameters are:
+
+- controller-no
+
- The number of the GPIB controller on the computer. There may be
+more then one GPIB controllerinstalled on a given system. Usually this
+is 0.
+
- gpib-address
+
- The GPIB address of the device on the bus.
+
- gpib-secondary
+
- GPIB devices may have a seconadry address. This can be specified
+with this parameter. Usually this is 0.
+
- timeout
+
- The time to wait for answers on the GPIB bus. 13 is 10 seconds and
+ussually a good value.
+
- eot
+
- A parameter determining the termination mode on this
+connection. Consult NI documentation for this or leave at 0.
+
- eoi
+
- A terminator. Set to 1 or understand NI documentation for this
+parameter.
+
+
- gpib detach devID
+
- Breaks the connection described through devID. devID is the return
+value from attach.
+
- gpib clear devID
+
- Tries to clear the GPIB buffers for the conenction described
+through devID. Usually in vain.
+
- gpib send devID bal bla bla
+
- sends data to the device at devID.
+
- gpib sendwithterm devID string terminator
+
- Sends string to the device at devID. The terminator character
+identified through the integer terminator is automatically
+appended. Use this to send things which require a
+terminator. Terminators included in strings sent by send get messed up
+through Tcl!
+
- gpib read devID
+
- Reads data from the device at devID and returns it as a string.
+
- gpib readtillterm devID terminator
+
- Read from teh device devID unti the terminator character described
+through the interger terminator is read. Then return the data read as
+a string.
+
+
+ECB Controllers
+
+ECB controllers are at the heart of the Risoe data aquisition
+system. These are essentially Z80 processors wired to the GPIB
+bus. Functions can be invoked in this processor by sending a function
+code followed by the contents of 4 8 bit registers. As a result the
+contents of the registers after the function call are returned. A ECB
+can be made knwon to SICS through the initialisation command:
+
+MakeECB name gpib-controller gbib-controller-number gpib-address
+
+The parameters:
+
+- name
+
- The name used as a token for this controller later on.
+
- gpib-controller
+
- the name of the GPIB interface to use. See above.
+
- gbib-controller-no
+
- The number of the GPIB board in the system
+
- gpib-address
+
- The GPIB address of the ECB on the GPIB bus.
+
+Once installed, the ECB controller understands a few commands:
+
+- ecb1 func funcode d e bc
+
- Invoke ECB function funcode with the registers d e b c.Returns the
+contents of the registers d e b c. Function codes and register
+contents are documented, if at all, in the ECB documentation.
+
- ecb1 clear
+
- Tries, usually in vain, to clear the communications interface to
+the ECB.
+
- ecb1 toint char
+
- A helper function which converts the character char to an
+integer. Tcl does not seem to be able to do that.
+
+