PSI sics-cvs-psi_pre-ansto
This commit is contained in:
180
doc/programmer/counter.tex
Normal file
180
doc/programmer/counter.tex
Normal file
@@ -0,0 +1,180 @@
|
||||
\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}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user