\subsection{SPS Controllers}
This module is very specific to SINQ. At SINQ there are Siemens SPS
controllers which are used to put beam components in, lift air cushions etc.
Essentially these are push button devices. There exists a protocoll for
pushing buttons through a RS--232 interface. This protocoll is described
elsewhere. 

These obscure SPS devices support three types of functionalities:
\begin{itemize}
\item Bits may be flipped. This correcponds to pushing a button. There are
12b bytes of those with 8 bits each.
\item Status bits may be read. This allows to figure out if an operation
succeeded. 128 status bits are available.
\item Furthermore this thing has up to 8 ADC inputs. These can be read as
well.
\end{itemize}
This module implements a means to communicate with SPS devices. It will
support the three functionalities in the list above. This is more a module
providing a basic functionality. In practice this will and should be wrapped
into Tcl wrapper functions. This is the best solution because bit
assignements vary between instruments and tend to change all the time. Or at
least seem to, as the electricians don't talk to us.  As this is no general
device the usual SICS division between hardware object and hardware driver
will not be upheld. 

There is a problem with pushing buttons. Not all buttons may be pushed
remotely, for instance it may not be permitted to operate the beam shutter
remotely. Not all of the bits in the SPS actually correspond to a pressable
button but are set as consequence of a pushed button. In order to run all
this a permission list must be configured for each SPS controller. This list
holds the adress of the bit and the privelege required to operate this
button. If a bit is not in the list permission is automatically not given to
operate it. Each entry in this permission list looks like this:

@d permlist @{
   typedef struct {
                   int iByte;
                   int iBit;
                   int iPrivilege;
                  }Permission, *pPermission;
@}
The fields are: the byte we refer to, the bit in the byte and the Privilege
required to operate this switch. Entries of this kind will be held in a
standard linked list.



In order to run the SPS, the following data strucure is required:

@d spsdata @{
   typedef struct __SPS {
                           pObjectDescriptor pDes;
                           int iMode;
                           int iLastError;
                           char *pHost;
                           int iPort;
                           int iChannel;
                           int lPermissions;
                           void *pData;
                         } SPS;
@}

The fields are:
\begin{description}
\item[pDes] The SICS standard object descriptor.
\item[iMode] The SPS can be operated in simulation mode for software
testing. This flag denotes that.
\item[iLastError] an integer code representing the last error, if any.
\item[pHost] The Macintosh computer running the serial port server.
\item[iPort] The TCP/IP port number where the Macintosh serial port server
is listening.
\item[iChannel] The serial port ID to which the SPS controller is connected
to.
\item[lPermissions] The linked list where the permissions are stored.
\item[pData] The private data structure for serial communication with the
SPS.
\end{description}


The external interface to this module looks like this:

@d spshead @{
   typedef struct __SPS *pSPS;
/*-------------------------------------------------------------------------*/
   int SPSSetButton(pSPS self, SConnection *pCon, int iByte, int iBit);
   int SPSGetStatus(pSPS self, int iStatus, int *iSet);
   int SPSGetSANS(pSPS self, float *fVal);
   int SPSGetADC(pSPS self, int iWhich, int *iValue);
   void SPSAddPermission(pSPS self, int iByte, int iBit, int iRight);
/*------------------------------------------------------------------------*/
   int SPSFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
                  int argc, char *argv[]);

   int SPSAction(SConnection *pCon, SicsInterp *pSics, void *pData,
                 int argc, char *argv[]);
@}

The functions and their meaning are described below. All function return 1
on success and 0 on failure.
\begin{description}
\item[SPSSetButton] Tries to set the button described by iByte and iBit.
pCon is needed to determine user rights associated with the request. Please note that a
successful return from this function means that the button has been pressed
but not that the SPS has successfully completed the requested action. In
order to check for that you have to check the associated status bit.
\item[SPSGetStatus] Requests the value of the status bit iStatus. iSet will
be set to 1 if the bit is set or 0 if not.
\item[SPSGetSANS] is a special function for reading the collimation 
length from the SANS collimator SPS controller. This requires checking tons
 of bits. For efficiency this has been put into a separate function. 
\item[SPSGetADC] requests the value of the ADC channel iWhich. The value is
returned in iValue. Please note that this is probably a meaningless integer
value which has to be converted to a physically meaningful value.
\item[SPSFactory] is the interpreter factory function which will be used to
create command in the interpreter representing SPS controllers.
\item[SPSAction] implements the actual commands in the SICS interpreter for
interacting with the SPS controller. 
\end{description} 

@o sps.i @{
/*--------------------------------------------------------------------------
  SPS Controller module internal header file. Do not include. Leave 
  alone. Is automatically created from another file.
---------------------------------------------------------------------------*/
@<permlist@>

@<spsdata@>
      
@}

@o sps.h @{
/*------------------------------------------------------------------------
                            S P S

  A module to handle Siemens SPS controllers at SINQ. For more information 
  see sps.tex

  Mark Koennecke, Juli 1998
----------------------------------------------------------------------------*/
#ifndef SICSSPS
#define SICSSPS
@<spshead@>
#endif
@}
