1906 lines
63 KiB
C
1906 lines
63 KiB
C
#define ident "2B03"
|
||
#ifdef VAXC
|
||
#module EL737_Utility ident
|
||
#endif
|
||
#ifdef __DECC
|
||
#pragma module EL737_Utility ident
|
||
#endif
|
||
/*
|
||
** +--------------------------------------------------------------+
|
||
** | Paul Scherrer Institute |
|
||
** | Department ASQ |
|
||
** | |
|
||
** | This software may be used freely by non-profit organizations.|
|
||
** | It may be copied provided that the name of P.S.I. and of the |
|
||
** | author is included. Neither P.S.I. nor the author assume any |
|
||
** | responsibility for the use of this software outside of P.S.I.|
|
||
** +--------------------------------------------------------------+
|
||
**
|
||
** Module Name . . . . . . . . : [...LIB.SINQ]EL737_Utility.C
|
||
**
|
||
** Author . . . . . . . . . . : D. Maden
|
||
** Date of creation . . . . . . : Apr 1996
|
||
**
|
||
** To compile this module, use:
|
||
|
||
$ import tasmad
|
||
$ define/group sinq_c_tlb mad_lib:sinq_c.tlb
|
||
$ cc /debug /noopt /obj=[]EL737_Utility -
|
||
tasmad_disk:[mad.psi.lib.sinq]EL737_Utility + -
|
||
sinq_c_tlb/lib
|
||
|
||
** To include this module in SINQ.OLB, use:
|
||
|
||
$ import tasmad
|
||
$ define/group sinq_c_tlb mad_lib:sinq_c.tlb
|
||
$
|
||
$ define/group sinq_olb mad_lib:sinq_dbg.olb
|
||
$ @tasmad_disk:[mad.lib.sinq]sinq_olb EL737_Utility debug
|
||
$
|
||
$ define/group sinq_olb mad_lib:sinq.olb
|
||
$ @tasmad_disk:[mad.lib.sinq]sinq_olb EL737_Utility
|
||
**
|
||
** Updates:
|
||
** 1A01 2-Nov-1995 DM. Initial version.
|
||
** 1B01 21-Mar-1996 DM. Move from DELTAT.OLB to SINQ.OLB.
|
||
** 1C01 16-Jul-1997 DM. Add code for EL737_Pause
|
||
** 2A01 6-Aug-1997 DM. Cope with new RA response format (= timer first)
|
||
** Add EL737_GetLongStatus.
|
||
** 2B01 5-Aug-1998 DM. Put messages into a .MSG file.
|
||
** 2B02 22-Apr-1999 DM. Add EL737_GetThresh and EL737_SetThresh.
|
||
**============================================================================
|
||
** The entry points included in this module are described below. Prototypes
|
||
** can be defined via:
|
||
**
|
||
** #include <sinq_prototypes.h>
|
||
**
|
||
** EL737_Close - Close a connection to an EL737 counter.
|
||
** EL737_Config - Configure a connection to an EL737 counter.
|
||
** EL737_Continue - Continue a measurement with an EL737 counter.
|
||
** EL737_EnableThresh - Enable/disable threshold monitoring.
|
||
** EL737_ErrInfo - Return detailed status from last operation.
|
||
** EL737_GetMonIntegTime - Get Monitor Integration Time (DI register).
|
||
** EL737_GetRateIntegTime - Get Rate Integration Time (DT register).
|
||
** EL737_GetStatus - Get 4 counters and counter status.
|
||
** EL737_GetStatusExtra - Get counters 5 to 8.
|
||
** EL737_GetThresh - Get threshold monitoring status.
|
||
** EL737_Open - Open a connection to an EL737 counter.
|
||
** EL737_Pause - Pause a measurement with an EL737 counter.
|
||
** EL737_SendCmnd - Send a command to RS232C server.
|
||
** EL737_SetErrcode - Set up EL737_errcode.
|
||
** EL737_SetThresh - Set threshold monitoring level.
|
||
** EL737_StartCnt - Start a preset cnt measurement with an EL737.
|
||
** EL737_StartTime - Start a preset time measurement with an EL737.
|
||
** EL737_Stop - Stop a measurement with an EL737 counter.
|
||
** EL737_StopFast - Same as EL737_Stop but no registers are returned.
|
||
** EL737_WaitIdle - Wait till status goes to zero.
|
||
**---------------------------------------------------------------------
|
||
** int EL737_Close (&handle, force_flag)
|
||
** -----------
|
||
** Input Args:
|
||
** int force_flag - if non-zero, all connections using the same socket
|
||
** will also be closed (this gets AsynSrv_Close to
|
||
** actually close the socket and is needed for error
|
||
** recovery operations).
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** On return, the pointer is set to NULL.
|
||
** Return status:
|
||
** True always (error returns from close and free are not checked).
|
||
** Routines called:
|
||
** AsynSrv_Close
|
||
** Description:
|
||
** The routine calls AsynSrv_Close to close the connection to the RS232C
|
||
** server. If 'force_flag' is non-zero, all other connections to the
|
||
** RS232C server which use the same socket will also be closed.
|
||
**
|
||
** The 'force_flag' can be useful in error recovery situations. The AsynSrv
|
||
** utility operates by only opening a socket for each separate combination
|
||
** of host/port. Hence, if several connections are open to a server,
|
||
** then calling EL737_Close doesn't actually close the socket until all
|
||
** connections have been closed. In the situation where an error has been
|
||
** detected, it is often desirable to close and re-open the socket as part
|
||
** of the recovery procedure. Calling EL737_Close with 'force_flag'
|
||
** non-zero will force the socket to be closed and will mark all other
|
||
** connections using this socket so that they will be informed of the
|
||
** event when they next call try to be used.
|
||
**
|
||
** Note: The force-close action is effected by the AsynSrv package. A
|
||
** force-close will thus also close any connections to other
|
||
** RS-232-C devices (e.g. EL734 motors) on the same server.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_Config (&handle, &par_id, par_val, ...)
|
||
** ------------
|
||
** Input Args:
|
||
** char* par_id - Text string identifying the next argument (see below).
|
||
** NULL indicates the end of the argument list.
|
||
** <??> par_val - The value to set for the argument. The type of the
|
||
** argument can depend on par_id.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** It is used to hold the config info for the connection.
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_errcode
|
||
** is set to indicate the nature of the problem as follows:
|
||
** EL737__BAD_PAR --> Unrecognised par_id or msecTmo < 100 or
|
||
** msecTmo > 999'999 or bad eot or ..
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** The routine sets values in the EL737info data structure. Values which
|
||
** may be taken by par_id (warning -- par_id is case-sensitive) and the
|
||
** corresponding variable type of par_val are:
|
||
**
|
||
** "msecTmo" int The time-out response for commands sent to
|
||
** the EL737. The valid range is 100 to
|
||
** 999'999. Default is 10'000.
|
||
** "eot" char* The expected terminators in responses to
|
||
** commands sent to the EL737. The first
|
||
** character specifies the number of
|
||
** terminators (max=3). Default is "1\r".
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_Continue (&handle, &status)
|
||
** --------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *status - The status (RS) of the counter after the CO cmnd.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_Continue are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> the response to the RS command was probably not
|
||
** an integer. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *status is set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_Continue sends a CO command to the counter to get it to continue
|
||
** a paused measurement and then an RS command to read its status.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_EnableThresh (&handle, indx)
|
||
** ------------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** int indx - The number of the counter to select as the "active"
|
||
** threshold monitoring counter. If (indx == 0),
|
||
** threshold monitoring is disabled.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_EnableThresh are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_BSY --> "?2" response received - cntr probably in
|
||
** wrong state.
|
||
** EL737__BAD_PAR --> Bad parameter. Illegal value for <indx> or "?3"
|
||
** or "?4" response received.
|
||
** EL737__BAD_ILLG --> the response to the commands was illegal in
|
||
** some way. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** A "DR <indx>" command is sent to select counter <indx> to be the
|
||
** "active" threshold monitoring counter. A value of 0 causes
|
||
** threshold monitoring to be disabled in the EL737. The threshold
|
||
** for the selected counter will not be changed. If it is required
|
||
** to set a threshold value as well as enabling monitoring, it is
|
||
** simplest to use EL737_SetThresh.
|
||
**-------------------------------------------------------------------------
|
||
** void EL737_ErrInfo (&entry_txt_ptr, &errcode, &my_errno, &vaxc_errno)
|
||
** -------------
|
||
** Input Args:
|
||
** None
|
||
** Output Args:
|
||
** char **entry_txt_ptr - Pointer to a text string giving the call stack
|
||
** at the time that the error was detected.
|
||
** int *errcode - An internal error code indicating the detected error.
|
||
** int *my_errno - Saved value of errno.
|
||
** int *vaxc_errno - Saved value of vaxc$errno (OpenVMS only).
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** none
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** Returns detailed status of the last operation. Once an error has been
|
||
** detected, the error status is frozen until this routine has been called.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_GetMonIntegTime (&handle, indx, &mon_integ_time)
|
||
** ---------------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** int indx - The counter whose integ time is wanted.
|
||
** Output Args:
|
||
** float *mon_integ_time - The integration time used for monitoring
|
||
** the rate threshold.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_GetMonIntegTime are (other values may be set by the called
|
||
** routines):
|
||
** EL737__BAD_TMO, _LOC, _CMD, _OFL, _ADR, _ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> the response was probably not a floating point
|
||
** number. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *mon_integ_time is set to 0.1.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The routine issues a "DI <indx>" command to the controller and
|
||
** analyses the result.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_GetRateIntegTime (&handle, &rate_integ_time)
|
||
** ----------------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** float *rate_integ_time - The integration time used for calculating
|
||
** the rates.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_GetRateIntegTime are (other values may be set by the called
|
||
** routines):
|
||
** EL737__BAD_TMO, _LOC, _CMD, _OFL, _ADR, _ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> the response was probably not a floating point
|
||
** number. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *rate_integ_time is set to 0.1.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The routine issues a DT command to the controller and
|
||
** analyses the result.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_GetStatus (&handle, &c1, &c2, &c3, &c4, &timer, &rs)
|
||
** ---------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *c1 - Counter 1 (Monitor).
|
||
** int *c2 - Counter 2 (Detector).
|
||
** int *c3 - Counter 3.
|
||
** int *c4 - Counter 4.
|
||
** float *timer - The measured time.
|
||
** int *rs - The counter status (RS command).
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_GetStatus are (other values may be set by the called routines):
|
||
** EL737__BAD_TMO, _LOC, _CMD, _OFL, _ADR, _ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> one of the responses could probably not be
|
||
** decoded. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, all arguments are set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The routine issues an RA and RS command to the controller and
|
||
** analyses the result. If a syntax error is detected in either the RA
|
||
** or RS response, the routine tries up to 3 times to get a meaningful
|
||
** reply.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_GetStatusExtra (&handle, &c5, &c6, &c7, &c8)
|
||
** --------------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *c5 - Counter 5.
|
||
** int *c6 - Counter 6.
|
||
** int *c7 - Counter 7.
|
||
** int *c8 - Counter 8.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True always.
|
||
** Routines called:
|
||
** None
|
||
** Description:
|
||
** The routine returns values for the counters 5, 6, 7 and 8 from the
|
||
** counter's structure. A successful call to any of the routines which
|
||
** return values for counters 1, 2, 3 and 4 must precede a call to
|
||
** EL737_GetStatusExtra.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_GetThresh (&handle, &indx, &val)
|
||
** ---------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *indx - The number of the threshold monitor counter. If =0,
|
||
** threshold monitoring is disabled.
|
||
** float *val - If *indx != 0, the value of the threshold. Otherwise,
|
||
** it is zero.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_GetThresh are (other values may be set by the called routines):
|
||
** EL737__BAD_TMO, _LOC, _CMD, _OFL, _ADR, _ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> one of the responses could probably not be
|
||
** decoded. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, all arguments are set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The routine issues a DR and, if threshold monitoring is enabled,
|
||
** a "DL <indx>" command to the controller and analyses the responses.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_Open (&handle, &host, port, chan)
|
||
** ----------
|
||
** Input Args:
|
||
** char *host - Name of host offering the TCP/IP service.
|
||
** int port - Number of TCP/IP port of TCP/IP server.
|
||
** int chan - RS-232-C Channel number on the TCP/IP server.
|
||
** Output Args:
|
||
** void *handle - A pointer to a structure of type EL737info needed for
|
||
** subsequent calls to EL737_... routines. Buffer space
|
||
** for the structure is allocated dynamically. It gets
|
||
** released via a call to EL737_Close.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False. If False, EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_Open are (other values may be set by the called routines):
|
||
** EL737__BAD_TMO --> Time-out error ("?TMO" - this gets
|
||
** generated by the RS232C server).
|
||
** EL737__BAD_LOC --> EL737 off-line ("?OF"). This should not
|
||
** happen on calls to EL737_Open since it
|
||
** sends an "RMT 1" cmnd.
|
||
** EL737__BAD_CMD --> Syntax error ("?1"). This could be
|
||
** caused by noise in the RS-232-C
|
||
** transmission.
|
||
** EL737__BAD_OFL --> Connection to EL737 broken ("?OFL").
|
||
** This can get generated by RS232C_SRV
|
||
** if, for example, the connection is via
|
||
** a terminal server and the terminal
|
||
** server loses power.
|
||
** EL737__BAD_ILLG --> Some other unrecognised response. This
|
||
** should never occur, of course!
|
||
** EL737__BAD_DEV --> Device doesn't seem to be an EL737. The
|
||
** response to the RA command was bad.
|
||
** EL737__BAD_MALLOC --> Call to "malloc" failed.
|
||
** EL737__BAD_ASYNSRV --> Call to AsynSrv_SendCmnds failed. Use
|
||
** AsynSrv_ErrInfo to get more details.
|
||
** Routines called:
|
||
** AsynSrv_Open, memory allocation routine "malloc" and AsynSrv_SendCmnds.
|
||
** Description:
|
||
** The routine opens a TCP/IP connection to a server offering the
|
||
** "RS-232-C" service for an EL737 Neutron Counter. "RMT 1" and
|
||
** "ECHO 2" commands are sent to ensure the device is on-line and an RA
|
||
** command is sent to ensure that an EL737 is being addressed.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_Pause (&handle, &status)
|
||
** -----------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *status - The status (RS) of the counter after the PS cmnd.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_Pause are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> the response to the RS command was probably not
|
||
** an integer. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *status is set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_Pause sends a PS command to the counter to get it to pause
|
||
** a measurement and then an RS command to read its status.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_SendCmnd (&handle, &cmnd, &rply, rply_size)
|
||
** --------------
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL737_Open.
|
||
** char *cmnd - A command, terminated by NULL, for sending to the
|
||
** EL737 counter controller. The command must have
|
||
** any necessary \r character included.
|
||
** int rply_size - the size of the <rply> buffer.
|
||
** Output Args:
|
||
** char *rply - A buffer for receiving the reply.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and errcode (see
|
||
** EL737_ErrInfo) is set to indicate the nature of the problem.
|
||
** EL737_errcode may be set as follows:
|
||
** EL737__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility.
|
||
** Call AsynSrv_ErrInfo for more info.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The command is passed to AsynSrv_SendCmnds and the reply extracted.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_SetErrcode (&info_ptr, &response, &cmnd)
|
||
** ----------------
|
||
** Set up EL737_errcode (for internal use only)
|
||
** Input Args:
|
||
** struct EL737info *info_ptr - The pntr to the structure returned by
|
||
** EL737_Open.
|
||
** char *response - The response received from a command.
|
||
** char *cmnd - The command which was sent.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** The value of EL737_errcode.
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** The command checks *response for certain keywords and sets EL737_errcode
|
||
** accordingly.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_SetThresh (&handle, indx, val)
|
||
** ---------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** int indx - The number of the counter whose threshold is to
|
||
** be set. If (indx == 0), threshold monitoring is
|
||
** disabled and val is not used.
|
||
** float val - The value of the threshold to be set.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_SetThresh are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_BSY --> "?2" response received - cntr probably in
|
||
** wrong state.
|
||
** EL737__BAD_PAR --> Bad parameter. Illegal value for <indx> or "?3"
|
||
** or "?4" response received.
|
||
** EL737__BAD_ILLG --> the response to the commands was illegal in
|
||
** some way. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds, EL737_EnableThresh
|
||
** Description:
|
||
** a) If (indx == 0): EL737_SetThresh simply calls EL737_EnableThresh to
|
||
** send a "DR 0" command which will disable threshold
|
||
** monitoring by the counter.
|
||
**
|
||
** b) If (indx != 0): First of all, a "DL <indx> |<val>|" command is sent
|
||
** to the counter to set the threshold for counter <indx>
|
||
** to the absolute value of <val>.
|
||
** Then, if (val >= 0), EL737_EnableThresh is then called
|
||
** to select counter <indx> to be the "active" threshold
|
||
** monitoring counter. Otherwise, the "active" counter
|
||
** is not changed.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_StartCnt (&handle, count, &status)
|
||
** --------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** int count - The preset-count for the measurement.
|
||
** Output Args:
|
||
** int *status - The status (RS) of the counter after the MP cmnd.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_StartCnt are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_BSY --> "?2" response received - cntr probably in
|
||
** wrong state.
|
||
** EL737__BAD_PAR --> "?3" response received - bad parameter.
|
||
** EL737__BAD_ILLG --> the response to the RS command was probably not
|
||
** an integer. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *status is set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_StartCnt sends a MP command to the counter to get it to start
|
||
** a preset-count measurement and then an RS command to read its status.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_StartTime (&handle, timer, &status)
|
||
** ---------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** float timer - The preset-time for the measurement.
|
||
** Output Args:
|
||
** int *status - The status (RS) of the counter after the TP cmnd.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_StartTime are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_BSY --> "?2" response received - cntr probably in
|
||
** wrong state.
|
||
** EL737__BAD_PAR --> "?3" response received - bad parameter.
|
||
** EL737__BAD_ILLG --> the response to the RS command was probably not
|
||
** an integer. This could happen if there is noise
|
||
** on the RS232C connection to the EL737.
|
||
** If an error is detected, *status is set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_StartTime sends a TP command to the counter to get it to start
|
||
** a preset-time measurement and then an RS command to read its status.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_Stop (&handle, &c1, &c2, &c3, &c4, &timer, &rs)
|
||
** ----------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *c1 - Counter 1 (Monitor).
|
||
** int *c2 - Counter 2 (Detector).
|
||
** int *c3 - Counter 3.
|
||
** int *c4 - Counter 4.
|
||
** float *timer - The measured time.
|
||
** int *rs - The counter status (RS command) after the S cmnd.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL737_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL737_Stop are (other values may be set by the called routines):
|
||
** EL737__OFL, __BAD_CMD, __BAD_TMO, __BAD_ASYNSRV --> see EL737_Open.
|
||
** EL737__BAD_ILLG --> the response to the RA or RS command was
|
||
** probably not an integer. This could happen if
|
||
** there is noise on the RS232C connection to the
|
||
** EL737.
|
||
** If an error is detected, all output args are set to 0.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_Stop sends an S command to the counter to get it to stop
|
||
** a measurement. It then calls EL737_GetStatus to read the registers
|
||
** and status.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_StopFast (&handle)
|
||
** --------------
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** None
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** See EL737_Stop
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** EL737_StopFast sends an S command to the counter to get it to stop
|
||
** a measurement. Unlike EL737_Stop, the registers are not read out.
|
||
**-------------------------------------------------------------------------
|
||
** int EL737_WaitIdle (&handle, &c1, &c2, &c3, &c4, &timer)
|
||
** --------------
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL737_Open.
|
||
** Output Args:
|
||
** int *c1 \
|
||
** int *c2 \
|
||
** int *c3 \ Same as EL737_GetStatus.
|
||
** int *c4 /
|
||
** float *timer /
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and Errcode (see
|
||
** EL737_ErrInfo) will have been set by the called routines to indicate
|
||
** the nature of the problem.
|
||
** Routines called:
|
||
** EL737_GetStatus
|
||
** Description:
|
||
** Routine EL737_GetStatus is called repeatedly at a predefined frequency
|
||
** until the RS register is zero.
|
||
**============================================================================*/
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** Global Definitions
|
||
*/
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <stdarg.h>
|
||
#include <math.h>
|
||
#include <errno.h>
|
||
#include <signal.h>
|
||
#include <netdb.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>
|
||
|
||
#include <string.h>
|
||
|
||
#ifdef __VMS
|
||
#include <unixio.h>
|
||
#else
|
||
#include <unistd.h>
|
||
#ifdef FORTIFY
|
||
#include <fortify.h>
|
||
#endif
|
||
#endif
|
||
/*-----------------------------------------------------------------*/
|
||
#include <sinq_prototypes.h>
|
||
#include <el737_def.h>
|
||
#include <rs232c_def.h>
|
||
|
||
#define True 1
|
||
#define False 0
|
||
/*--------------------------------------------------------------------------
|
||
** Global Variables
|
||
*/
|
||
static int EL737_call_depth = 0;
|
||
static char EL737_routine[5][64];
|
||
static int EL737_errcode = 0;
|
||
static int EL737_errno, EL737_vaxc_errno;
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_AddCallStack: Add a routine name to the call stack.
|
||
** This allows EL737_ErrInfo to generate a
|
||
** trace-back in case of error.
|
||
*/
|
||
int EL737_AddCallStack(
|
||
/* ==================
|
||
*/ struct EL737info *pntr,
|
||
char *name)
|
||
{
|
||
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
|
||
if (EL737_call_depth < 5) {
|
||
strcpy(EL737_routine[EL737_call_depth], name);
|
||
EL737_call_depth++;
|
||
}
|
||
|
||
if (pntr == NULL) {
|
||
EL737_errcode = EL737__NOT_OPEN;
|
||
return False;
|
||
}
|
||
|
||
if (pntr->asyn_info.skt <= 0) {
|
||
memset(pntr->from_host.msg_size,
|
||
'0', sizeof(pntr->from_host.msg_size));
|
||
EL737_errcode = (pntr->asyn_info.skt < 0) ? EL737__FORCED_CLOSED
|
||
: EL737__NO_SOCKET;
|
||
return False;
|
||
}
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Close: Close a connection to an EL737 counter.
|
||
*/
|
||
int EL737_Close(
|
||
/* ===========
|
||
*/ void **handle,
|
||
int force_flag)
|
||
{
|
||
|
||
struct EL737info *info_ptr;
|
||
char buff[4];
|
||
|
||
info_ptr = (struct EL737info *) *handle;
|
||
if (info_ptr == NULL)
|
||
return True;
|
||
|
||
if (info_ptr->asyn_info.skt != 0) {
|
||
if (info_ptr->asyn_info.skt > 0) {
|
||
AsynSrv_Close(*handle, force_flag);
|
||
}
|
||
}
|
||
free(*handle);
|
||
*handle = NULL;
|
||
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Config: Configure a connection to an EL737 counter.
|
||
*/
|
||
int EL737_Config(
|
||
/* ============
|
||
*/ void **handle,
|
||
...)
|
||
{
|
||
|
||
char buff[16];
|
||
va_list ap; /* Pointer to variable args */
|
||
char *txt_ptr;
|
||
int intval;
|
||
struct EL737info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_Config"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
*/
|
||
va_start(ap, handle); /* Set up var arg machinery */
|
||
txt_ptr = va_arg(ap, char *); /* Get pntr to first parameter ident */
|
||
while (txt_ptr != NULL) {
|
||
if (strcmp(txt_ptr, "msecTmo") == 0) {
|
||
intval = va_arg(ap, int);
|
||
if ((intval < 100) || (intval > 999999)) {
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
sprintf(buff, "%04d", intval / 100); /* Convert to ASCII as ..
|
||
** .. deci-secs */
|
||
memcpy(info_ptr->asyn_info.tmo, buff, 4);
|
||
} else if (strcmp(txt_ptr, "eot") == 0) {
|
||
txt_ptr = va_arg(ap, char *);
|
||
if (txt_ptr == NULL) {
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
memcpy(info_ptr->asyn_info.eot, "\0\0\0\0", 4);
|
||
switch (txt_ptr[0]) {
|
||
case '3':
|
||
info_ptr->asyn_info.eot[3] = txt_ptr[3];
|
||
case '2':
|
||
info_ptr->asyn_info.eot[2] = txt_ptr[2];
|
||
case '1':
|
||
info_ptr->asyn_info.eot[1] = txt_ptr[1];
|
||
case '0':
|
||
info_ptr->asyn_info.eot[0] = txt_ptr[0];
|
||
break;
|
||
default:
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
} else {
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
txt_ptr = va_arg(ap, char *); /* Get pntr to next parameter ident */
|
||
}
|
||
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Continue: Continue a measurement with an EL737 counter.
|
||
*/
|
||
int EL737_Continue(
|
||
/* ==============
|
||
*/ void **handle,
|
||
int *status)
|
||
{
|
||
|
||
int my_status;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1;
|
||
/*----------------------------------------------
|
||
*/
|
||
*status = 0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_Continue"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send CO and RS cmnds to EL737
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"CO\r", "RS\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
rply_ptr1 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) &&
|
||
(sscanf(rply_ptr1, "%d", status) == 1)) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
*status = 0;
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, "CO\" or \"RS");
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_EnableThresh: Enable/disable Threshold Monitoring.
|
||
*/
|
||
int EL737_EnableThresh(
|
||
/* ==================
|
||
*/ void **handle,
|
||
int indx)
|
||
{
|
||
|
||
int status;
|
||
char cmnd[20];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_EnableThresh"))
|
||
return False;
|
||
|
||
if ((indx < 0) || (indx > 8)) {
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
/*----------------------------------------------
|
||
** Send "DR <indx>" cmnd to EL737 to select the
|
||
** "active" threshold rate counter.
|
||
*/
|
||
sprintf(cmnd, "DR %d\r", indx);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if ((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) {
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
** -------------------------------------------------------------------------
|
||
** EL737_ErrInfo: Return detailed status from last operation.
|
||
*/
|
||
void EL737_ErrInfo(
|
||
/* =============
|
||
*/ char **entry_txt,
|
||
int *errcode, int *my_errno, int *vaxc_errno)
|
||
{
|
||
|
||
int i;
|
||
char buff[80];
|
||
int asyn_errcode, asyn_errno, asyn_vaxerrno;
|
||
char *asyn_errtxt;
|
||
|
||
if (EL737_call_depth <= 0) {
|
||
strcpy(EL737_routine[0], "EL737_no_error_detected");
|
||
*errcode = 0;
|
||
*my_errno = 0;
|
||
*vaxc_errno = 0;
|
||
} else {
|
||
if (EL737_call_depth > 1) { /* Concatenate the names */
|
||
for (i = 1; i < EL737_call_depth; i++) {
|
||
strcat(EL737_routine[0], "/");
|
||
StrJoin(EL737_routine[0], sizeof(EL737_routine),
|
||
EL737_routine[0], EL737_routine[i]);
|
||
}
|
||
}
|
||
*errcode = EL737_errcode;
|
||
*my_errno = EL737_errno;
|
||
*vaxc_errno = EL737_vaxc_errno;
|
||
switch (EL737_errcode) {
|
||
case EL737__BAD_ASYNSRV:
|
||
strcpy(buff, "/EL737__BAD_ASYNSRV");
|
||
break;
|
||
case EL737__BAD_BSY:
|
||
strcpy(buff, "/EL737__BAD_BSY");
|
||
break;
|
||
case EL737__BAD_CMD:
|
||
strcpy(buff, "/EL737__BAD_CMD");
|
||
break;
|
||
case EL737__BAD_CNTR:
|
||
strcpy(buff, "/EL737__BAD_CNTR");
|
||
break;
|
||
case EL737__BAD_DEV:
|
||
strcpy(buff, "/EL737__BAD_DEV");
|
||
break;
|
||
case EL737__BAD_ILLG:
|
||
strcpy(buff, "/EL737__BAD_ILLG");
|
||
break;
|
||
case EL737__BAD_LOC:
|
||
strcpy(buff, "/EL737__BAD_LOC");
|
||
break;
|
||
case EL737__BAD_MALLOC:
|
||
strcpy(buff, "/EL737__BAD_MALLOC");
|
||
break;
|
||
case EL737__BAD_OFL:
|
||
strcpy(buff, "/EL737__BAD_OFL");
|
||
break;
|
||
case EL737__BAD_OVFL:
|
||
strcpy(buff, "/EL737__BAD_OVFL");
|
||
break;
|
||
case EL737__BAD_PAR:
|
||
strcpy(buff, "/EL737__BAD_PAR");
|
||
break;
|
||
case EL737__BAD_SOCKET:
|
||
strcpy(buff, "/EL737__BAD_SOCKET");
|
||
break;
|
||
case EL737__BAD_TMO:
|
||
strcpy(buff, "/EL737__BAD_TMO");
|
||
break;
|
||
case EL737__CNTR_OVFL:
|
||
strcpy(buff, "/EL737__CNTR_OVFL");
|
||
break;
|
||
case EL737__FORCED_CLOSED:
|
||
strcpy(buff, "/EL737__FORCED_CLOSED");
|
||
break;
|
||
case EL737__NOT_OPEN:
|
||
strcpy(buff, "/EL737__NOT_OPEN");
|
||
break;
|
||
case EL737__NO_SOCKET:
|
||
strcpy(buff, "/EL737__NO_SOCKET");
|
||
break;
|
||
case EL737__NO_VALUE:
|
||
strcpy(buff, "/EL737__NO_VALUE");
|
||
break;
|
||
default:
|
||
sprintf(buff, "/EL737__unknown_err_code: %d", EL737_errcode);
|
||
}
|
||
StrJoin(EL737_routine[0], sizeof(EL737_routine), EL737_routine[0],
|
||
buff);
|
||
}
|
||
AsynSrv_ErrInfo(&asyn_errtxt, &asyn_errcode, &asyn_errno,
|
||
&asyn_vaxerrno);
|
||
if (asyn_errcode != 0) {
|
||
strcat(EL737_routine[0], "/");
|
||
StrJoin(EL737_routine[0], sizeof(EL737_routine),
|
||
EL737_routine[0], asyn_errtxt);
|
||
}
|
||
*entry_txt = EL737_routine[0];
|
||
EL737_call_depth = 0;
|
||
EL737_errcode = 0;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_GetMonIntegTime: Get DI register value for a counter.
|
||
*/
|
||
int EL737_GetMonIntegTime(
|
||
/* =====================
|
||
*/ void **handle,
|
||
int indx, float *mon_integ_time)
|
||
{
|
||
|
||
int status;
|
||
char cmnd[20];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*mon_integ_time = 0.1;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_GetMonIntegTime"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send "DI <indx>" cmnd to EL737
|
||
*/
|
||
sprintf(cmnd, "DI %d\r", indx);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (sscanf(rply_ptr0, "%f", mon_integ_time) == 1) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
*mon_integ_time = 0.1;
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_GetRateIntegTime: Get DT register value.
|
||
*/
|
||
int EL737_GetRateIntegTime(
|
||
/* ======================
|
||
*/ void **handle,
|
||
float *rate_integ_time)
|
||
{
|
||
|
||
int status;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*rate_integ_time = 0.1;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_GetRateIntegTime"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send DT cmnd to EL737
|
||
*/
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"DT\r", NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (sscanf(rply_ptr0, "%f", rate_integ_time) == 1) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, "DT");
|
||
*rate_integ_time = 0.1;
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_GetStatus: Get RA/RS register values.
|
||
*/
|
||
int EL737_GetStatus(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int *c1,
|
||
int *c2, int *c3, int *c4, float *timer, int *rs)
|
||
{
|
||
|
||
int i, status, nvals;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr, *p_cmnd;
|
||
/*----------------------------------------------
|
||
*/
|
||
*c1 = *c2 = *c3 = *c4 = *rs = 0;
|
||
*timer = 0.0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_GetStatus"))
|
||
return False;
|
||
info_ptr->c5 = info_ptr->c6 = info_ptr->c7 = info_ptr->c8 = 0;
|
||
/*----------------------------------------------
|
||
** Send RA and RS cmnds to EL737. Since this routine gets
|
||
** used such a lot, try up to 3 times if a syntax error in
|
||
** the reply is detected.
|
||
*/
|
||
for (i = 0; i < 3; i++) {
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"RA\r", "RS\r", NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
p_cmnd = "RA";
|
||
rply_ptr =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr != NULL) {
|
||
nvals = sscanf(rply_ptr, "%f %d %d %d %d %d %d %d %d",
|
||
timer, c1, c2, c3, c4,
|
||
&info_ptr->c5, &info_ptr->c6,
|
||
&info_ptr->c7, &info_ptr->c8);
|
||
if (nvals != 9)
|
||
nvals = sscanf(rply_ptr, "%d %d %d %d %f", c1, c2, c3, c4, timer);
|
||
if (nvals == 5) {
|
||
info_ptr->c5 = info_ptr->c6 = info_ptr->c7 = info_ptr->c8 = 0;
|
||
nvals = 9;
|
||
}
|
||
if (nvals == 9) {
|
||
p_cmnd = "RS";
|
||
rply_ptr =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
if (sscanf(rply_ptr, "%d", rs) == 1) {
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (rply_ptr == NULL)
|
||
rply_ptr = "?";
|
||
EL737_SetErrcode(info_ptr, rply_ptr, p_cmnd);
|
||
*c1 = *c2 = *c3 = *c4 = *rs = 0;
|
||
*timer = 0.0;
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_GetStatusExtra: Get values of extra counters.
|
||
*/
|
||
int EL737_GetStatusExtra(
|
||
/* ====================
|
||
*/ void **handle,
|
||
int *c5, int *c6, int *c7, int *c8)
|
||
{
|
||
|
||
struct EL737info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
*c5 = *c6 = *c7 = *c8 = 0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_GetStatusExtra"))
|
||
return False;
|
||
|
||
*c5 = info_ptr->c5;
|
||
*c6 = info_ptr->c6;
|
||
*c7 = info_ptr->c7;
|
||
*c8 = info_ptr->c8;
|
||
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_GetThresh: Get threshold monitoring status.
|
||
*/
|
||
int EL737_GetThresh(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int *indx, float *val)
|
||
{
|
||
|
||
int status, my_indx;
|
||
float my_val;
|
||
char cmnd[20];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*indx = 0;
|
||
*val = 0.0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_GetThresh"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send DR cmnd to EL737 to get the number of the
|
||
** "active" threshold rate counter.
|
||
*/
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"DR\r", NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if ((sscanf(rply_ptr0, "%d", &my_indx) == 1) &&
|
||
(my_indx >= 0) && (my_indx <= 8)) {
|
||
*indx = my_indx;
|
||
if (my_indx != 0) {
|
||
/*----------------------------------------------
|
||
** Now send DL cmnd to EL737 to get the threshold value.
|
||
*/
|
||
sprintf(cmnd, "DL %d\r", my_indx);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (sscanf(rply_ptr0, "%f", &my_val) == 1) {
|
||
*val = my_val;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
} else {
|
||
*val = 0.0;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Open: Open a connection to an EL737 counter.
|
||
*/
|
||
int EL737_Open(
|
||
/* ==========
|
||
*/ void **handle,
|
||
char *host, int port, int chan)
|
||
{
|
||
|
||
int status, c1, c2, c3, c4, nvals;
|
||
float timer;
|
||
struct EL737info *my_handle;
|
||
char tmo_save[4];
|
||
char *rply_ptr;
|
||
char *rply_ptr0;
|
||
char *rply_ptr1;
|
||
char *rply_ptr2;
|
||
/*--------------------------------------------------------
|
||
** Initialise the error info stack and pre-set the
|
||
** routine name (in case of error).
|
||
*/
|
||
EL737_errcode = EL737_errno = EL737_vaxc_errno = 0;
|
||
strcpy(EL737_routine[0], "EL737_Open");
|
||
EL737_call_depth = 1;
|
||
/*--------------------------------------------------------
|
||
** Assume trouble
|
||
*/
|
||
*handle = NULL;
|
||
/*--------------------------------------------------------
|
||
** Reserve space for the data we need to store.
|
||
*/
|
||
my_handle = (struct EL737info *) malloc(sizeof(*my_handle));
|
||
if (my_handle == NULL) {
|
||
EL737_errcode = EL737__BAD_MALLOC; /* malloc failed!! */
|
||
return False;
|
||
}
|
||
memset(my_handle, 0, sizeof(*my_handle));
|
||
/*--------------------------------------------------------
|
||
** Set up the connection
|
||
*/
|
||
StrJoin(my_handle->asyn_info.host, sizeof(my_handle->asyn_info.host),
|
||
host, "");
|
||
my_handle->asyn_info.port = port;
|
||
my_handle->asyn_info.chan = chan;
|
||
status = AsynSrv_Open(&my_handle->asyn_info);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_SOCKET;
|
||
GetErrno(&EL737_errno, &EL737_vaxc_errno); /* Save errno info */
|
||
fprintf(stderr, "\nEL737_Open/AsynSrv_Open: "
|
||
"Failed to make connection.\n");
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
|
||
memcpy(tmo_save, my_handle->asyn_info.tmo, 4);
|
||
EL737_Config((void *) &my_handle, "msecTmo", 500, /* Set a short time-out initially since
|
||
** there should be no reason for the RMT,
|
||
** ECHO or RA commands to take very long
|
||
*/
|
||
"eot", "1\r", NULL);
|
||
/*
|
||
** Now ensure the EL737 is on-line. The first "RMT 1" command can
|
||
** fail due to pending characters in the EL737 input buffer causing
|
||
** the "RMT 1" to be corrupted. The response of the EL737 to this
|
||
** command is ignored for this reason (but the AsynSrv_SendCmnds
|
||
** status must be OK otherwise it indicates a network problem).
|
||
*/
|
||
status = AsynSrv_SendCmnds(&my_handle->asyn_info,
|
||
&my_handle->to_host, &my_handle->from_host,
|
||
"RMT 1\r", NULL);
|
||
if (status) {
|
||
status = AsynSrv_SendCmnds(&my_handle->asyn_info,
|
||
&my_handle->to_host, &my_handle->from_host,
|
||
"RMT 1\r", "ECHO 2\r", "RA\r", NULL);
|
||
}
|
||
if (!status) {
|
||
/* Some error occurred in AsynSrv_SendCmnds */
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
} else {
|
||
/* Check the responses carefully.
|
||
*/
|
||
rply_ptr1 = rply_ptr2 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host,
|
||
NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host,
|
||
rply_ptr0);
|
||
if (rply_ptr1 != NULL)
|
||
rply_ptr2 =
|
||
AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host,
|
||
rply_ptr1);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (rply_ptr2 == NULL)
|
||
rply_ptr2 = "?";
|
||
|
||
if (*rply_ptr1 == '?')
|
||
rply_ptr0 = rply_ptr1;
|
||
if (*rply_ptr2 == '?')
|
||
rply_ptr0 = rply_ptr2;
|
||
if (*rply_ptr0 != '?') {
|
||
nvals = sscanf(rply_ptr2, "%f %d %d %d %d %d %d %d %d",
|
||
&timer, &c1, &c2, &c3, &c4,
|
||
&my_handle->c5, &my_handle->c6,
|
||
&my_handle->c7, &my_handle->c8);
|
||
if (nvals != 9)
|
||
nvals = sscanf(rply_ptr2, "%d %d %d %d %f",
|
||
&c1, &c2, &c3, &c4, &timer);
|
||
if (nvals == 5) {
|
||
my_handle->c5 = my_handle->c6 = my_handle->c7 = my_handle->c8 = 0;
|
||
nvals = 9;
|
||
}
|
||
if (nvals != 9) {
|
||
EL737_errcode = EL737__BAD_DEV; /* Device is not EL737 */
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
memcpy(my_handle->asyn_info.tmo, tmo_save, 4); /* Restore time-out */
|
||
/*
|
||
** The connection is complete. Pass the data structure
|
||
** back to the caller as a handle.
|
||
*/
|
||
*handle = my_handle;
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
} else {
|
||
EL737_SetErrcode(my_handle, rply_ptr0, "RMT\", \"ECHO\" or \"RA");
|
||
}
|
||
}
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Pause: Pause a measurement with an EL737 counter.
|
||
*/
|
||
int EL737_Pause(
|
||
/* ===========
|
||
*/ void **handle,
|
||
int *status)
|
||
{
|
||
|
||
int my_status;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1;
|
||
/*----------------------------------------------
|
||
*/
|
||
*status = 0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_Pause"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send PS and RS cmnds to EL737
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"PS\r", "RS\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr1 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) &&
|
||
(sscanf(rply_ptr1, "%d", status) == 1)) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, "PS\" or \"RS");
|
||
*status = 0;
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_SendCmnd - Send a command to RS232C server.
|
||
*/
|
||
int EL737_SendCmnd(
|
||
/* ==============
|
||
*/ void **handle,
|
||
char *cmnd, char *rply, int rply_size)
|
||
{
|
||
|
||
struct EL737info *info_ptr;
|
||
int my_status;
|
||
char *rply_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_SendCmnd"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send command to EL737.
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr == NULL)
|
||
rply_ptr = "?";
|
||
StrJoin(rply, rply_size, rply_ptr, "");
|
||
}
|
||
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_SetErrcode - Set up EL737_errcode
|
||
*/
|
||
int EL737_SetErrcode(
|
||
/* ================
|
||
*/ struct EL737info *info_ptr,
|
||
char *response, char *cmnd)
|
||
{
|
||
|
||
int status, s_len;
|
||
char *rply;
|
||
char tmo_save[4];
|
||
char eot_save[4];
|
||
|
||
EL737_errcode = EL737__BAD_ILLG;
|
||
if (strcmp(response, "?OF") == 0)
|
||
EL737_errcode = EL737__BAD_LOC;
|
||
if (strcmp(response, "?OFL") == 0)
|
||
EL737_errcode = EL737__BAD_OFL;
|
||
if (strcmp(response, "?OV") == 0)
|
||
EL737_errcode = EL737__BAD_OVFL;
|
||
if (strcmp(response, "?1") == 0)
|
||
EL737_errcode = EL737__BAD_CMD;
|
||
if (strcmp(response, "?2") == 0)
|
||
EL737_errcode = EL737__BAD_BSY;
|
||
if (strcmp(response, "?3") == 0)
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
if (strcmp(response, "?4") == 0)
|
||
EL737_errcode = EL737__BAD_CNTR;
|
||
if (strcmp(response, "?5") == 0)
|
||
EL737_errcode = EL737__NO_VALUE;
|
||
if (strcmp(response, "?6") == 0)
|
||
EL737_errcode = EL737__CNTR_OVFL;
|
||
if (strncmp(response, "?TMO", 4) == 0)
|
||
EL737_errcode = EL737__BAD_TMO;
|
||
|
||
if ((EL737_errcode == EL737__BAD_ILLG) && (cmnd != NULL)) {
|
||
s_len = strlen(cmnd);
|
||
if (cmnd[s_len - 1] == '\r')
|
||
s_len--;
|
||
fprintf(stderr, " Unrecognised response to \"%.*s\" command: \"%s\"\n",
|
||
s_len, cmnd, response);
|
||
}
|
||
|
||
return EL737_errcode;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_SetThresh: Set threshold monitoring level.
|
||
*/
|
||
int EL737_SetThresh(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int indx, float val)
|
||
{
|
||
|
||
int status;
|
||
char cmnd[32];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_SetThresh"))
|
||
return False;
|
||
|
||
if ((indx < 0) || (indx > 8)) {
|
||
EL737_errcode = EL737__BAD_PAR;
|
||
return False;
|
||
}
|
||
/*----------------------------------------------
|
||
** If <indx> is zero, simply call EL737_EnableThresh to
|
||
** disable threshold monitoring by the counter.
|
||
*/
|
||
if (indx == 0) {
|
||
return EL737_EnableThresh(handle, 0);
|
||
}
|
||
/*----------------------------------------------
|
||
** Send "DR <indx> |<val>|" cmnd to EL737 to set the
|
||
** threshold for counter <indx>.
|
||
*/
|
||
sprintf(cmnd, "DL %d %.3f\r", indx, fabs(val));
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if ((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) {
|
||
if (val >= 0)
|
||
return EL737_EnableThresh(handle, indx);
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_StartCnt: Start a preset cnt measurement with an EL737.
|
||
*/
|
||
int EL737_StartCnt(
|
||
/* ==============
|
||
*/ void **handle,
|
||
int count, int *status)
|
||
{
|
||
|
||
int my_status;
|
||
char cmnd[20];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1;
|
||
/*----------------------------------------------
|
||
*/
|
||
*status = 0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_StartCnt"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send MP and RS cmnds to EL737
|
||
*/
|
||
sprintf(cmnd, "MP %d\r", count); /* Encode an appropriate command */
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info, /* Send it */
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, "RS\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr1 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) &&
|
||
(sscanf(rply_ptr1, "%d", status) == 1)) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
*status = 0;
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_StartTime: Start a preset time measurement with an EL737.
|
||
*/
|
||
int EL737_StartTime(
|
||
/* ===============
|
||
*/ void **handle,
|
||
float timer, int *status)
|
||
{
|
||
|
||
int my_status;
|
||
char cmnd[20];
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1;
|
||
/*----------------------------------------------
|
||
*/
|
||
*status = 0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_StartTime"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send TP and RS cmnds to EL737
|
||
*/
|
||
sprintf(cmnd, "TP %.2f\r", timer); /* Encode an appropriate command */
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info, /* Send it */
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, "RS\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr1 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (((*rply_ptr0 == '\0') || (*rply_ptr0 == 'r')) &&
|
||
(sscanf(rply_ptr1, "%d", status) == 1)) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, cmnd);
|
||
*status = 0;
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_Stop: stop a measurement with an EL737 counter.
|
||
*/
|
||
int EL737_Stop(
|
||
/* ==========
|
||
*/ void **handle,
|
||
int *c1, int *c2, int *c3, int *c4, float *timer, int *rs)
|
||
{
|
||
|
||
int my_status, nvals;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1, *rply_ptr2;
|
||
/*----------------------------------------------
|
||
*/
|
||
*c1 = *c2 = *c3 = *c4 = *rs = 0;
|
||
*timer = 0.0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_Stop"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send S, RS and RA cmnds to EL737
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"S\r", "RS\r", "RA\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr1 = rply_ptr2 = NULL;
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 != NULL)
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
if (rply_ptr1 != NULL)
|
||
rply_ptr2 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr1);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?";
|
||
if (rply_ptr2 == NULL)
|
||
rply_ptr2 = "?";
|
||
|
||
nvals = sscanf(rply_ptr2, "%f %d %d %d %d %d %d %d %d",
|
||
timer, c1, c2, c3, c4,
|
||
&info_ptr->c5, &info_ptr->c6,
|
||
&info_ptr->c7, &info_ptr->c8);
|
||
if (nvals != 9)
|
||
nvals = sscanf(rply_ptr2, "%d %d %d %d %f", c1, c2, c3, c4, timer);
|
||
if (nvals == 5) {
|
||
info_ptr->c5 = info_ptr->c6 = info_ptr->c7 = info_ptr->c8 = 0;
|
||
nvals = 9;
|
||
}
|
||
if (((*rply_ptr0 == '\0') || (*rply_ptr0 == '\r')) &&
|
||
(sscanf(rply_ptr1, "%d", rs) == 1) && (nvals == 9)) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
if (*rply_ptr0 != '?') {
|
||
if (*rply_ptr1 == '?')
|
||
rply_ptr0 = rply_ptr1;
|
||
if (*rply_ptr0 == '?')
|
||
rply_ptr0 = rply_ptr2;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, "S\", \"RS\" or \"RA");
|
||
*c1 = *c2 = *c3 = *c4 = *rs = 0;
|
||
*timer = 0.0;
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_StopFast: stop a measurement with an EL737 counter.
|
||
*/
|
||
int EL737_StopFast(
|
||
/* ==============
|
||
*/ void **handle)
|
||
{
|
||
|
||
int my_status, nvals;
|
||
struct EL737info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_StopFast"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send S cmnd to EL737
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"S\r", NULL);
|
||
if (!my_status) {
|
||
EL737_errcode = EL737__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?";
|
||
|
||
if ((*rply_ptr0 == '\0' || (*rply_ptr0 == '\r'))) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
EL737_SetErrcode(info_ptr, rply_ptr0, "S");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL737_WaitIdle: Wait till RS goes to zero.
|
||
*/
|
||
int EL737_WaitIdle(
|
||
/* ==============
|
||
*/ void **handle,
|
||
int *c1, int *c2, int *c3, int *c4, float *timer)
|
||
{
|
||
#ifdef __VMS
|
||
#include <lib$routines.h>
|
||
#define hibernate lib$wait (0.25)
|
||
#else
|
||
#include <unistd.h>
|
||
#include <time.h>
|
||
struct timespec delay = { 0, 250000000 };
|
||
struct timespec delay_left;
|
||
#ifdef LINUX
|
||
#define hibernate nanosleep(&delay, &delay_left)
|
||
#else
|
||
#define hibernate nanosleep_d9 (&delay, &delay_left)
|
||
#endif
|
||
|
||
#endif
|
||
int my_rs;
|
||
struct EL737info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
*c1 = *c2 = *c3 = *c4 = 0;
|
||
*timer = 0.0;
|
||
info_ptr = (struct EL737info *) *handle;
|
||
|
||
if (!EL737_AddCallStack(info_ptr, "EL737_WaitIdle"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Keep reading status till idle.
|
||
*/
|
||
while (EL737_GetStatus(handle, c1, c2, c3, c4, timer, &my_rs)) {
|
||
if (my_rs == 0) {
|
||
if (EL737_errcode != 0)
|
||
return False;
|
||
EL737_call_depth--;
|
||
return True;
|
||
}
|
||
hibernate;
|
||
}
|
||
return False; /* Error detected in EL737_GetStatus */
|
||
}
|
||
|
||
/*-------------------------------------------- End of EL737_Utility.C =======*/
|