\subsection{The Counter}
This is the SICS object responsible for handling single counters and
monitors.  As usual for SICS hardware objects the
counter is subdivided in a driver and a logical object. The driver will be
discussed first. The same concept with overlaying structures is used
for counters as for motors in order to allow for different drivers. 
  
\subsubsection{The Counter Driver}
Counter drivers are polymorphic. This means that different drivers look the
same to the logical counter objects. This is achieved by having pointers to
functions in the driver. These pointers must be initialised by an actual driver
with functions which implement the required behaviour. 
The counter driver is a large data structure defined below:
\begin{verbatim}
  typedef struct __COUNTER {
                 /* variables */
                    char *name;
                    char *type;
                    CounterMode eMode;
                    float fPreset;
                    int iNoOfMonitors;
                    long lCounts[MAXCOUNT];
                    int iPause;
                 /* functions */
                    int (*GetStatus)(struct __COUNTER *self, float *fControl);
                    int (*Start)(struct __COUNTER *self);
                    int (*Pause)(struct __COUNTER *self);
                    int (*Continue)(struct __COUNTER *self);
                    int (*Halt)(struct __COUNTER *self);     
                    int (*ReadValues)(struct __COUNTER *self);
                    int (*GetError)(struct __COUNTER *self, int *iCode,
                                    char *error, int iErrLen);
                    int (*TryAndFixIt)(struct __COUNTER *self, int iCode);
                    void *pData; /* counter specific data goes here, ONLY for
                                    internal driver use!
                                 */
                 } CounterDriver, *pCounterDriver;
\end{verbatim}                 
All functions take a pointer to a counter structure as first parameter. If
not described otherwise all functions return 0 on failure and 1 on success.
The fields have the following meanings:
\begin{description}
\item[name] The counter name in the system.
\item[type] A string describing the counter type.
\item[eMode] The counting mode of the counter. Can be eTimer for counting
till a preset time has passed or ePreset for counting until one of the
monitors has reached a certain count rate.
\item[fPreset] Depending on the count mode either the time to count or the
monitor rate to wait for for.
\item[iNoOfMonitors] The number of monitors handled by this counter.
\item[lCounts] An array which stores the counts in the array position 0, and
the monitor counts in the other fields of the array.
\item[iPause] A logical which is set when the counter is paused.
\item[GetStatus] GetStatus is the first of the functions a driver has to
define. GetStatus reads the counter status. Possible return values are:
\begin{description}
\item[HWIdle, OKOK] The counter is finished or idle.
\item[HWFault] A fault has been found at the counter instead of an
reasonable answer.
\item[HWNoBeam] There is currently no incident beam. This is usually
detected through a monitor which does not increase over time.
\item[HWPause] Counting has been paused.
\item[HWBusy] The counter is busy counting. 
\end{description}
The parameter fControl is set to the current value of the counting control
variable. This can either be the counting time already passed or the count
rate of the control monitor in ePreset mode.
\item[Start] Starts counting with the current mode and preset parameters. 
\item[Pause] pauses a counting operation.
\item[Continue] continues a paused counting operation.
\item[Halt] cancels a counting operation. This a emergency stop used when
interrupting an operation.
\item[ReadValues] reads the counter and the monitors in the lCounts array.
This gets automatically called through the TransferData routine of the
countable interface after a counting operations finishes. The point is that
data is transfered from the counter once and further requests operate on the
contents of the local array instead of bothering the hardware again.
\item[GetError] This gets called when an error has been detected during one
of the previous operations. The function has to return more information
about the error: iCode an driver dependent integer error code and maximum
iErrLen characters of problem description in error.
\item[TryAndFixIt] takes the integer error code returned in iCode from
GetError and tries to solve the problem with the hardware. This function can
either return COREDO which means the problem has been fixed and the
operation needs to redone or COTERM which means that it is not possible to
resolve the problem in software. 
\item[pData] A pointer to a driver dependent data structure. Whereas the
fields above are required and expected by the counter module for a driver,
this is an area private to the actual driver. 
\end{description}

As most of the action of the counter driver is done in the functions given
in its data structure only few functions are available in order to interact
with it:
\begin{description}
\item[pCounterDriver CreateCounterDriver(char *name, char *type)] creates a
general default counter driver structure.
\item[void DeleteCounterDriver(pCounterDriver self)] deletes a counter
driver.
\item[pCounterDriver NewEL737Counter(char *name, char *host, int iPort, 
                                 int iChannel)] creates a PSI--EL737 counter
driver. The counter box is meant to be reachable at the terminal server
host, listening at iPort and connected to channel iChannel at the macintosh.
\item[void KillEL737Counter(pCounterDriver self)] deletes an EL737 counter
driver.
\item[pCounterDriver NewSIMCounter(char *name)] creates a simulated counter
driver. Needed for software testing and instrument simulation. 
\item[void KillSIMCounter(pCounterDriver self)] deletes a simulated counter
driver.
\end{description}

\subsubsection{The Logical Counter Object}
This is the object which represents the counter to the system. For all
actual hardware action the driver is called. The counter objects data
structure:
\begin{verbatim}
  typedef struct {
                  pObjectDescriptor pDes;
                  char *name;
                  int isUpToDate;
                  int iExponent;
                  pICountable pCountInt;
                  pCounterDriver pDriv;
                  pICallBack pCall;
                  unsigned long tStart;
                 } Counter, *pCounter;
\end{verbatim}
The fields:\begin{description}
\item[pDes] The required object descriptor for any SICS object.
\item[name] The counters name in the system.
\item[isUpToDate] a logical which is true when counting is finished and the
data in the drivers lCount array represent the correct values. 
\item[iExponent] The exponent to apply on preset values in monitor mode. At
SINQ monitor count rates in millions are usual. The exponent saves typing
all those 0's. Each monitor preset value given is multiplied by this value.
\item[pCountInt] A pointer to the countable interface.
\item[pDriv] A pointer to a counter driver for this counter.
\item[pCall] A pointer to the callback interface implemented by this
counter.
\item[tStart] The start time of the last counting operation.
\end{description}
                 
Unlike the counter driver, there exist many functions for interaction with
the counter. Mosts functions take a pointer to a counter structure as first
parameter. In order to communicate error messages, functions which interact
with hardware take a pointer to a connection object as parameter.
\begin{description}
\item[pCounter CreateCounter(char *name, pCounterDriver pDriv)] Creates a
new counter object with name name and counter driver pDriv.
\item[void     DeleteCounter(void *self)] deletes a counter object.
\item[int MakeCounter(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                  int argc, char *argv[])] The counter object factory
function. The function to be hacked (plus DeleteCounter) when a new driver
needs to be introduced into the system.
\item[int SetCounterMode(pCounter self, CounterMode eNew)] sets a new
counter mode.
\item[CounterMode GetCounterMode(pCounter self)] requests the current
counter mode.
\item[int SetCounterPreset(pCounter self, float fVal)] sets a new preset
time or monitor.
\item[float GetCounterPreset(pCounter self)] returns the current preset time
or monitor.  
\item[long GetCounts(pCounter self, SConnection *pCon)] returns the detector
counts.
\item[long GetMonitor(pCounter self, int iNum, SConnection *pCon)] returns
the monitor counts in monitor iNum. This function returns -1 when the
requetsed monitor does not exist. 
\item[  GetNMonitor(pCounter self)] returns the number of monitors
available.
\item[int  DoCount(pCounter self,float fPreset, SConnection *pCon, SicsInterp
*pSics)] does a count operation with fPreset as preset value.
\item[int CountAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                  int argc, char *argv[])] The counter objects wrapper
function. This function defines the user interface to the counter object.
\end{description}





