\subsection{The ECB Controller}
The ECB Controller is an electronic device created by the Risoe
neutron scattering institute. At its base is a Z80 8-bit
processor. This Z80 processor can perform certain functions such as
controlling count operations, running a motor etc. To this purpose
further electronic widgets are connected to the Z80's backplane. At
the other end is a GPIB controller which allows to discuss with the
Z80. 

This module now implements three basic functionalities of the ECB:
\begin{itemize}
\item Execute a function 
\item Read some memory
\item Write some memory
\end{itemize}

This module also takes care of the encoder assignment for the ECB. The
ECB can  have up to three encoders which can be assigned to motors. As
a single motor driver does not know about the assignments of the other
motors, the task of encoder assignement is handled in this module. 

WARNING: this module contains code which may be endian dependend!

In order to do this we need the following data structure:
@d ecbdat @{
	struct __ECB {
			pObjectDescriptor pDes;
			pGPIB gpib;
			int boardNumber;
			int ecbAddress;
			int ecbDeviceID;
			int lastError;
                        int encoder[3];
			int encoderDirty;
			}ECB;
@}
The fields:
\begin{description}
\item[pDes] The standard SICS object descriptor.
\item[gpib] The GPIB controller used for accessing the ECB.
\item[boardNumber] The GPIB board number in the NI driver.
\item[ecbAddress] The GPIB address of the ECB controller.
\item[ecbDeviceID] The device ID assigned to the ECB when the ECB has
been attached to. 
\item[lastError] The last error which occurred.
\item[encoder] An array holding the motor numbers assigned to the
three encoder.
\item[encoderDirty] is a flag which is set to true if a download of
the encoder assignments is necessary.
\end{description}

A function in the ECB is executed by sending a function number first,
followed by the content of the Z80 4 registers. In order to do this a
data structure is required for these registers:
 
@d z80 @{
typedef struct {
    unsigned char d;            /* D register in Z80 */
    unsigned char e;            /* E register in Z80 */
    unsigned char b;            /* B register in Z80 */
    unsigned char c;            /* C register in Z80 */
  } Z80_reg;
@}

The function interface then looks like:

@d ecbfunc @{
	typedef struct __ECB *pECB;

	int ecbExecute(pECB self, int func, Z80_reg in, Z80_reg *out);
	int ecbRead(pECB self, unsigned short address, 
		    void *buffer, int byteCount);
	int ecbWrite(pECB self, unsigned short address, 
		    void *buffer, int byteCount);
	int ecbDMARead(pECB self, unsigned short address, void *buffer,
			unsigned short byteCount);
        void ecbClear(pECB self);
	int fixECBError(pECB self);
	void ecbErrorDescription(pECB self, char *buffer,
                                 int maxBytes);
	int ecbAssignEncoder(pECB self, int encoder, int motorNumber);
	int ecbLoadEncoder(pECB self);




@}
\begin{description}
\item[ecbExecute] tries to execute the ECB function func. The input register
content is in in, on success the outpt registers are stored in out.
\item[ecbRead] reads byteCount bytes from the ECB address address into
buffer. Please note that address in this contest is an address in the
ECB's memory space and not the GPIB address.
\item[ecbDMARead] reads byteCount bytes from the ECB DMA address address into
buffer. Please note that address in this contest is an address in the
ECB's memory space and not the GPIB address.
\item[ecbWrite] writes byteCount bytes from buffer to the ECB address
address. Please note that address in this contest is an address in the
ECB's memory space and not the GPIB address.
\item[ecbClear] tries to clear the ECB interface.
\item[fixECBError] tries to fix the last ECB error.
\item[ecbErrorDescription] retrieves a text description of the last
ECB problem. Max maxBytes of description are copied into buffer.
\item[assignEncoder] assigns an encoder to a motor number.
\item[loadEncoder] downloads the encoder assignment to the ECB if necessary. 
\end{description}


There is also an interface to the SICS interpreter for the ECB. This
can be useful for debugging and testing and as a tool for scriptingy
auxiliary equipment controlled through the ECB. The interface to the
SICS interpreter for the ECB is represented through the ECB Factory
function:
@d ecbint @{
	int MakeECB(SConnection *pCon, SicsInterp *pSics,
		    void *pData,
		    int ragc, char *argv[]);
@} 

@o ecb.h @{
/*-----------------------------------------------------------------------
  The ECB is a rack controller from Risoe based on a Z80 processor. 
  This module provides some functions for communicating with such a
  device.

  WARNING: This contains code which may be endian dependent!

  copyright: see file COPYRIGHT

  Mark Koennecke, January 2002, with some bits taken out of the
  original tascom code.
------------------------------------------------------------------------*/
#ifndef ECBCON
#define ECBCON
#include "gpibcontroller.h"

@<z80@>
/*-----------------------------------------------------------------------*/
@<ecbfunc@>
/*-----------------------------------------------------------------------*/
@<ecbint@>

/*----------------------------------------------------------------------
  for byte packing. result must be an 32 bit integer
----------------------------------------------------------------------*/
typedef union                   /* Used to extract and load data to Z80 regs. */{
    unsigned int result;
    struct
      { 
        unsigned char byt0;     /* Least significant byte */
        unsigned char byt1;
        unsigned char byt2;
        unsigned char byt3;     /* Most significant byte */
      }b;
}Ecb_pack;

#endif
@}

@o ecb.i @{
/*-----------------------------------------------------------------------
  The ECB is a rack controller from Risoe based on a Z80 processor. 
  This module provides some functions for communicating with such a
  device. This is an internal data structure definition file.

  copyright: see file COPYRIGHT

  Mark Koennecke, January 2002, with some bits taken out of the
  original tascom code.
------------------------------------------------------------------------*/
@<ecbdat@>
@}

