2879 lines
94 KiB
C
2879 lines
94 KiB
C
#define ident "1D08"
|
||
#ifdef VAXC
|
||
#module EL734_Utility ident
|
||
#endif
|
||
#ifdef __DECC
|
||
#pragma module EL734_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]EL734_Utility.C
|
||
**
|
||
** Author . . . . . . . . . . : D. Maden
|
||
** Date of creation . . . . . . : Nov 1995
|
||
**
|
||
** To compile this module, use:
|
||
|
||
$ import tasmad
|
||
$ define/group sinq_c_tlb mad_lib:sinq_c.tlb
|
||
$ cc /debug /noopt /obj=[]EL734_Utility -
|
||
tasmad_disk:[mad.psi.lib.sinq]EL734_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 EL734_Utility debug
|
||
$
|
||
$ define/group sinq_olb mad_lib:sinq.olb
|
||
$ @tasmad_disk:[mad.lib.sinq]sinq_olb EL734_Utility
|
||
**
|
||
** Updates:
|
||
** 1A01 2-Nov-1995 DM. Initial version.
|
||
** 1B01 21-Mar-1996 DM. Move from DELTAT.OLB to SINQ.OLB.
|
||
** 1C01 3-Mar-1997 DM. Add "Forced-close" capability.
|
||
** 1C02 14-Apr-1997 DM. Add EL734__BAD_STP to EL734_MoveNoWait.
|
||
** 1C11 18-Jun-1998 DM. Modify EL734_GetZeroPoint.
|
||
** 1D01 4-Aug-1998 DM. Put messages into a .MSG file.
|
||
**============================================================================
|
||
** The entry points included in this module are described below. Prototypes
|
||
** can be defined via:
|
||
**
|
||
** #include <sinq_prototypes.h>
|
||
**
|
||
** EL734_AddCallStack - Add a routine name to the call stack.
|
||
** EL734_Close - Close a connection to a motor.
|
||
** EL734_Config - Configure a connection to a motor.
|
||
** EL734_EncodeMSR - Encode the MSR status into text.
|
||
** EL734_EncodeSS - Encode the SS flags into text.
|
||
** EL734_ErrInfo - Return detailed status from last operation.
|
||
** EL734_GetAirCush - Get W and AC register values.
|
||
** EL734_GetEncGearing - Get FD register values.
|
||
** EL734_GetId - Get ID register value.
|
||
** EL734_GetLimits - Get H register values.
|
||
** EL734_GetMotorGearing - Get FM register values.
|
||
** EL734_GetNullPoint - Get V register value.
|
||
** EL734_GetPosition - Get U register value = current position.
|
||
** EL734_GetPrecision - Get A register value.
|
||
** EL734_GetRefMode - Get K register value.
|
||
** EL734_GetRefParam - Get Q register value.
|
||
** EL734_GetSpeeds - Get G, J and E register values.
|
||
** EL734_GetStatus - Get MSR/SS/U register values.
|
||
** EL734_GetZeroPoint - Get zero-point of motor.
|
||
** EL734_MoveNoWait - Move motor and don't wait for completion.
|
||
** EL734_MoveWait - Move motor and wait for completion.
|
||
** EL734_Open - Open a connection to a motor.
|
||
** EL734_PutOffline - Put the EL734 off-line.
|
||
** EL734_PutOnline - Put the EL734 on-line.
|
||
** EL734_SendCmnd - Send a command to RS232C server.
|
||
** EL734_SetAirCush - Set the air-cushion (AC register).
|
||
** EL734_SetErrcode - Set up EL734_errcode.
|
||
** EL734_SetHighSpeed - Set the max speed (J register).
|
||
** EL734_SetLowSpeed - Set the start/stop speed (G register).
|
||
** EL734_SetRamp - Set the start/stop ramp (E register).
|
||
** EL734_Stop - Send a stop command to motor.
|
||
** EL734_WaitIdle - Wait till MSR goes to zero.
|
||
** EL734_ZeroStatus - Zero the "ored-MSR" and fault counters.
|
||
**---------------------------------------------------------------------
|
||
** int EL734_AddCallStack (&handle, &name)
|
||
** ------------------
|
||
** Add a routine name to the call stack (internal use).
|
||
** Input Args:
|
||
** struct EL734info *handle - The pointer to the structure returned by
|
||
** EL734_Open.
|
||
** char *name - The name to be added to the call stack.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** False if an error is detected, otherwise True.
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** If an error has already occurred (EL734_errcode != 0), the routine
|
||
** simply returns False. Otherwise, *name is added to the call stack.
|
||
** Then *handle is checked.
|
||
** If NULL, error EL734__NOT_OPEN is set and False is returned.
|
||
** Otherwise, the connection's TCP/IP socket number is checked.
|
||
** If zero, error EL734__NO_SOCKET is set and False is returned.
|
||
** If negative, error EL734__FORCED_CLOSE is set and False is returned.
|
||
** Otherwise, True is returned.
|
||
**---------------------------------------------------------------------
|
||
** int EL734_Close (&handle, int force_flag)
|
||
** -----------
|
||
** Close a connection to a motor.
|
||
** 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 EL734_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 the
|
||
** motors on an EL734, then calling EL734_Close doesn't actually close
|
||
** the socket until all connections have been closed. In the situation
|
||
** where an error has been detected on a motor, it is often desirable to
|
||
** close and re-open the socket as part of the recovery procedure. Calling
|
||
** EL734_Close with 'force_flag' non-zero will force the socket to be
|
||
** closed and will mark all connections using this socket so that they
|
||
** will be informed of the event when they next call an EL734_utility
|
||
** routine.
|
||
**
|
||
** 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. EL737 neutron cntr) on the same server.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_Config (&handle, &par_id, par_val, ...)
|
||
** ------------
|
||
** Configure a connection to a motor.
|
||
** 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 EL734_Open.
|
||
** It is used to hold the config info for the connection.
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_errcode
|
||
** is set to indicate the nature of the problem as follows:
|
||
** EL734__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 EL734info 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 EL734. The valid range is 100 to
|
||
** 999'999. Default is 10'000.
|
||
** "eot" char* The expected terminators in responses to
|
||
** commands sent to the EL734. The first
|
||
** character specifies the number of
|
||
** terminators (max=3). Default is "1\r".
|
||
** "motor" int The index of the motor in the range 1-12 to be
|
||
** associated with this connection.
|
||
** "chan" int The RS-232-C channel number of the EL734
|
||
** controller associated with this connection.
|
||
**-------------------------------------------------------------------------
|
||
** char *EL734_EncodeMSR (&text, text_len, msr, ored_msr, fp_cntr, fr_cntr)
|
||
** ---------------
|
||
** Encode the MSR status into text.
|
||
** Input Args:
|
||
** int text_len - The size of text.
|
||
** int msr - The current MSR.
|
||
** int ored_msr - The 'ored' MSR to be encoded.
|
||
** int fp_cntr - The counter of *FP faults.
|
||
** int fr_cntr - The counter of *FR faults.
|
||
** Output Args:
|
||
** char *text - The resulting text string is stored here.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** A pointer to "text".
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** The routine makes an intelligible message out of the MSR input data.
|
||
**-------------------------------------------------------------------------
|
||
** char *EL734_EncodeSS (&text, text_len, ss)
|
||
** --------------
|
||
** Encode the SS flags into text.
|
||
** Input Args:
|
||
** int text_len - The size of text.
|
||
** int ss - The value of SS register.
|
||
** Output Args:
|
||
** char *text - The resulting text string is stored here.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** A pointer to "text".
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** The routine makes an intelligible message out of the input SS data.
|
||
**-------------------------------------------------------------------------
|
||
** void EL734_ErrInfo (&entry_txt_ptr, &errcode, &my_errno, &vaxc_errno)
|
||
** -------------
|
||
** Return detailed status from last operation.
|
||
** 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 EL734_GetAirCush (&handle, &present, &state)
|
||
** ----------------
|
||
** Get W and AC register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *present - The W register. If non-zero, motor has an air-cushion.
|
||
** int *state - The AC register. If non-zero, air-cushion is up.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "W" command and then an "AC" command instead of an "FD" command to
|
||
** the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetEncGearing (&handle, &numerator, &denominator)
|
||
** -------------------
|
||
** Get FD register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *numerator - The encoder gearing numerator.
|
||
** int *denominator - The encoder gearing denominator.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_GetEncGearing are (other values may be set by the called
|
||
** routines):
|
||
** EL734__BAD_TMO, BAD_LOC, BAD_CMD, BAD_OFL,
|
||
** BAD_ADR, EMERG_STOP --> see EL734_Open.
|
||
** EL734__BAD_ILLG --> the response was probably not 2 integers.
|
||
** This could happen if there is noise on the
|
||
** RS232C connection to the EL734.
|
||
** If an error is detected, *numerator and *denominator are set to 0.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The routine issues an "FD" command to the controller and analyses
|
||
** the result. The two parameters of the "FD" command are the numerator
|
||
** and denominator respectively.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetId (&handle, &id_txt, id_len)
|
||
** -----------
|
||
** Get ID register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** int id_len - The size of the <id_txt> buffer in bytes.
|
||
** Output Args:
|
||
** char *id_txt - The EL734 identifier ("ID" parameter).
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** an "ID" command instead of an "H" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetLimits (&handle, &lo, &hi)
|
||
** ---------------
|
||
** Get H register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** float *lo - The lower software limit.
|
||
** float *hi - The higher software limit.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** an "H" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetMotorGearing (&handle, &numerator, &denominator)
|
||
** ---------------------
|
||
** Get FM register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *numerator - The motor gearing numerator.
|
||
** int *denominator - The motor gearing denominator.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** an "FM" command instead of an "FD" command to the controller. The
|
||
** two parameters of the "FM" command are the numerator and denominator
|
||
** respectively.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetNullPoint (&handle, &null_pt)
|
||
** ------------------
|
||
** Get V register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *null_pt - The null point ("V" parameter) of the EL734.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "V" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetPosition (&handle, &ist_posit)
|
||
** -----------------
|
||
** Get U register value = current position.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** float *ist_posit - The current position (U command) of the motor.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "U" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetPrecision (&handle, &n_dec)
|
||
** ------------------
|
||
** Get A register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *n_dec - The precision ("A" parameter) of the EL734.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "A" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetRefMode (&handle, &mode)
|
||
** ----------------
|
||
** Get K register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *mode - The reference seek mode ("K" parameter) of the EL734.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "K" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetRefParam (&handle, ¶m)
|
||
** -----------------
|
||
** Get Q register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** float *param - The reference seek param ("Q" parameter) of the EL734.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "Q" command instead of an "FD" command to the controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetSpeeds (&handle, &lo, &hi, &ramp)
|
||
** ---------------
|
||
** Get G, J and E register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *lo - The start/stop speed (G register). Units = Steps/sec.
|
||
** int *hi - The maximum speed (J register). Units = Steps/sec.
|
||
** int *ramp - The start/stop ramp (E register). Units = kHz/sec.
|
||
** Description:
|
||
** The routine is the same as EL734_GetEncGearing except that it issues
|
||
** a "G", "J" and "E" commands instead of an "FD" command to the
|
||
** controller.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetStatus (&handle, &msr, &ored_msr, &fp_cntr, &fr_cntr,
|
||
** --------------- &ss, &ist_posit)
|
||
** Get MSR/SS/U register values.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *msr - The MSR register.
|
||
** int *ored_msr - The 'ored'-MSR register. This gets zeroed every time
|
||
** a 'positioning' command is executed.
|
||
** int *fp_cntr - A counter of the 'Position Faults' (*FP). This gets
|
||
** zeroed whenever ored_msr is zeroed.
|
||
** int *fr_cntr - A counter of the 'Run Faults' (*FR). This gets
|
||
** zeroed whenever ored_msr is zeroed.
|
||
** int *ss - The SS register. This will be -1 if the motor is busy.
|
||
** float *ist_posit - The current position (U command) of the motor.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_GetStatus are (other values may be set by the called routines):
|
||
** EL734__BAD_TMO, BAD_LOC, BAD_CMD, BAD_OFL,
|
||
** BAD_ADR, EMERG_STOP --> see EL734_Open.
|
||
** EL734__BAD_ILLG --> one of the responses could probably not
|
||
** be decoded. This could happen if there is noise
|
||
** on the RS232C connection to the EL734.
|
||
** If an error is detected, ist_posit is set to 0.0 and all other
|
||
** arguments to -1.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The routine issues an "MSR", "SS" and "U" command to the controller and
|
||
** analyses the result. A count is kept of each time the *FP and *FR bits
|
||
** are found to be set and an inclusive-or value of MSR is maintained.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_GetZeroPoint (&handle, &zero_pt)
|
||
** ------------------
|
||
** Get zero-point of motor.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** float *zero_pt - The zero point of the EL734.
|
||
** Return status:
|
||
** Any of the errors generated by the called routines is possible plus:
|
||
** EL734__BAD_OVFL --> The encoder gearing ratio is zero so
|
||
** the conversion would overflow.
|
||
** Routines called:
|
||
** EL734_AddCallStack, EL734_GetEncGearing, EL734_GetNullPoint
|
||
** Description:
|
||
** This routine returns the zero point of the motor in the same units
|
||
** as used by the "P" and "U" commands. In other words, it reads the
|
||
** "V" parameter and converts it from "encoder-step" units to physical
|
||
** units using the encoder-gearing parameters.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_MoveNoWait (&handle, soll_posit)
|
||
** ----------------
|
||
** Move motor and don't wait for completion.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** float soll_posit - The position to which the motor should move.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_MoveNoWait are (other values may be set by the called routines):
|
||
** EL734__BAD_TMO, BAD_LOC, BAD_CMD, BAD_OFL,
|
||
** BAD_ADR, EMERG_STOP --> see EL734_Open.
|
||
** EL734__BAD_RNG --> Destination is out-of-range.
|
||
** EL734__BAD_STP --> Motor is disabled via Hardware "Stop"
|
||
** signal.
|
||
** EL734__BAD_ILLG --> some other response obtained from EL734.
|
||
** This could happen if there is noise
|
||
** on the RS232C connection to the EL734.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The appropriate "P" command is sent to the motor and the response
|
||
** checked to check that it has been accepted. The fields "ored_msr",
|
||
** "fp_cntr" and "fr_cntr" in the handle are cleared, if so.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_MoveWait (&handle, soll_posit, &ored_msr, &fp_cntr, &fr_cntr,
|
||
** -------------- &ist_posit)
|
||
** Move motor and wait for completion.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** float soll_posit - The position to which the motor should move.
|
||
** Output Args:
|
||
** int *ored_msr \
|
||
** int *fp_cntr \ Same as EL734_WaitIdle.
|
||
** int *fr_cntr /
|
||
** float *ist_posit /
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False. If False, errcode (see
|
||
** EL734_ErrInfo) will have been set by EL734_MoveNoWait or EL734_WaitIdle.
|
||
** Routines called:
|
||
** EL734_AddCallStack, EL734_MoveNoWait, EL734_WaitIdle
|
||
** Description:
|
||
** The routine calls EL734_MoveNoWait and, if successful, EL734_WaitIdle.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_Open (&handle, host, port, chan, motor, id)
|
||
** ----------
|
||
** Open a connection to a motor.
|
||
** 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.
|
||
** int motor - The motor to be driven.
|
||
** char *id - The expected ID of the device, normally "STPMC EL734".
|
||
** If id is NULL, the device ID is not checked.
|
||
** Output Args:
|
||
** void *handle - A pointer to a structure of type EL734info needed for
|
||
** subsequent calls to EL734_... routines. Buffer space
|
||
** for the structure is allocated dynamically. It gets
|
||
** released via a call to EL734_Close.
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False. If False, EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_Open are (other values may be set by the called routines):
|
||
** EL734__BAD_TMO --> Time-out error ("?TMO" - this gets
|
||
** generated by the RS232C server).
|
||
** EL734__BAD_LOC --> EL734 off-line ("?LOC"). This should not
|
||
** happen on calls to EL734_Open since it
|
||
** sends an "RMT 1" cmnd.
|
||
** EL734__BAD_CMD --> Command error ("?CMD"). This could be
|
||
** caused by noise in the RS-232-C
|
||
** transmission.
|
||
** EL734__BAD_OFL --> Connection to EL734 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.
|
||
** EL734__BAD_ILLG --> Some other unrecognised response. This
|
||
** should never occur, of course!
|
||
** EL734__BAD_SOCKET --> Call to "AsynSrv_Open" failed.
|
||
** EL734__BAD_DEV --> Device has wrong ID
|
||
** EL734__BAD_MALLOC --> Call to "malloc" failed
|
||
** EL734__BAD_ADR --> Bad motor address ("?ADR"). Probably
|
||
** a non-existent motor has been addressed.
|
||
** EL734__EMERG_STOP --> Emergency stop ("*ES") detected.
|
||
** Routines called:
|
||
** AsynSrv_Open, the memory alloc routine "malloc", StrJoin,
|
||
** EL734_Config, AsynSrv_SendCmnds, AsynSrv_GetReply,
|
||
** AsynSrv_Close (if an error is detected).
|
||
** Description:
|
||
** The routine calls AsynSrv_Open to open a TCP/IP connection to a server
|
||
** offering the "RS-232-C" service for an EL734 Motor Controller. "RMT 1"
|
||
** and "ECHO 0" commands are sent to ensure the device is on-line, an "ID"
|
||
** command is sent (only if 'id' is non-NULL) to ensure that an EL734 is
|
||
** being addressed and an "MSR <motor>" command is sent to ensure that
|
||
** the motor exists.
|
||
** Note:
|
||
** For all error status returns, there is no open connection to the server
|
||
** and the handle is set to zero.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_PutOffline (&handle)
|
||
** ----------------
|
||
** Send "ECHO 1" and "RMT 0" commands to EL734 server.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and errcode (see
|
||
** EL734_ErrInfo) is set to indicate the nature of the problem.
|
||
** Values of Errcode set by EL734_PutOffline are (other values may be set
|
||
** by the called routines):
|
||
** EL734__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility.
|
||
** Call AsynSrv_ErrInfo for more info.
|
||
** EL734__BAD_ILLG --> an unrecognised response. This
|
||
** should never occur, of course!
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The routine calls AsynSrv_SendCmnds to execute "RMT 1", "ECHO 1"
|
||
** and "RMT 0" commands. The replies are checked.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_PutOnline (&handle, echo)
|
||
** ---------------
|
||
** Send "RMT 1" and "ECHO x" commands to EL734 server.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** int echo - The value for the ECHO command.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and errcode (see
|
||
** EL734_ErrInfo) is set to indicate the nature of the problem.
|
||
** Values of Errcode set by EL734_PutOnline are (other values may be set
|
||
** by the called routines):
|
||
** EL734__BAD_PAR --> "echo" is not 0, 1 or 2.
|
||
** EL734__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility.
|
||
** Call AsynSrv_ErrInfo for more info.
|
||
** EL734__BAD_ILLG --> an unrecognised response. This
|
||
** should never occur, of course!
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The routine calls AsynSrv_SendCmnds to execute "RMT 1" and "ECHO x"
|
||
** commands. The replies are checked.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SendCmnd (&handle, &cmnd, &rply, rply_size)
|
||
** --------------
|
||
** Send a command to RS232C server.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** char *cmnd - A command, terminated by NULL, for sending to the
|
||
** EL734 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
|
||
** EL734_ErrInfo) is set to indicate the nature of the problem.
|
||
** Values of Errcode set by EL734_SendCmnd are (other values may be set
|
||
** by the called routines):
|
||
** EL734__BAD_ASYNSRV --> An error occurred in AsynSrv_Utility.
|
||
** Call AsynSrv_ErrInfo for more info.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply
|
||
** Description:
|
||
** The command is passed to AsynSrv_SendCmnds and the reply extracted.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SetAirCush (&handle, state)
|
||
** ----------------
|
||
** Set AC register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Input Args:
|
||
** int state - The new state of the AC register. 0 --> down
|
||
** non-zero --> up
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_SetAirCush are (other values may be set by the called
|
||
** routines):
|
||
** EL734__BAD_TMO, BAD_LOC, BAD_CMD, BAD_OFL,
|
||
** BAD_ADR, EMERG_STOP --> see EL734_Open.
|
||
** EL734__VFY_ERR --> the value for the AC register returned by the
|
||
** call to EL734_GetAirCush was not the value which
|
||
** was sent via the AC command. This could happen
|
||
** if there is noise on the RS232C connection to
|
||
** the EL734.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply,
|
||
** EL734_GetAirCush
|
||
** Description:
|
||
** The routine issues an "AC" command to the controller to set the air-
|
||
** cushions of the motor up or down. It then calls EL734_GetAirCush
|
||
** to check that the air-cushions were set correctly.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SetErrcode (&info_ptr, &response, &cmnd)
|
||
** ----------------
|
||
** Set up EL734_errcode (for internal use only)
|
||
** Input Args:
|
||
** struct EL734info *info_ptr - The pntr to the structure returned by
|
||
** EL734_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 EL734_errcode.
|
||
** Routines called:
|
||
** AsynSrv_SendCmnds
|
||
** Description:
|
||
** The command checks *response for certain keywords. If not recognised,
|
||
** extra action is undertaken to try to see if the emergency stop state
|
||
** is active or not.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SetHighSpeed (&handle, hi)
|
||
** ------------------
|
||
** Set J register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Input Args:
|
||
** int hi - The maximum speed (J register). Units = Steps/sec.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and EL734_ErrInfo
|
||
** can be called to identify the problem. Values of Errcode set by
|
||
** EL734_SetHighSpeed are (other values may be set by the called
|
||
** routines):
|
||
** EL734__BAD_TMO, BAD_LOC, BAD_CMD, BAD_OFL,
|
||
** BAD_ADR, EMERG_STOP --> see EL734_Open.
|
||
** EL734__VFY_ERR --> the value for the J register returned by the call
|
||
** to EL734_GetSpeeds was not the value which was
|
||
** sent via the J command. This could happen if
|
||
** there is noise on the RS232C connection to
|
||
** the EL734.
|
||
** Routines called:
|
||
** EL734_AddCallStack, AsynSrv_SendCmnds, AsynSrv_GetReply, EL734_GetSpeeds
|
||
** Description:
|
||
** The routine issues a "J" command to the controller to set the max speed
|
||
** of the motor. It then calls EL734_GetSpeeds to check that the speed
|
||
** was set correctly.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SetLowSpeed (&handle, hi)
|
||
** -----------------
|
||
** Set G register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Input Args:
|
||
** int lo - The start/stop speed (G register). Units = Steps/sec.
|
||
** Description:
|
||
** The routine is identical to the EL734_SetHighSpeed routine except that
|
||
** a "G" command rather than a "J" command is issued to the controller to
|
||
** set the start/stop speed.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_SetRamp (&handle, ramp)
|
||
** -------------
|
||
** Set E register value.
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Input Args:
|
||
** int ramp - The start/stop ramp (E register). Units = kHz/sec.
|
||
** Description:
|
||
** The routine is identical to the EL734_SetHighSpeed routine except that
|
||
** an "E" command rather than a "J" command is issued to the controller to
|
||
** set the start/stop ramp.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_Stop (&handle)
|
||
** ----------
|
||
** Send a stop command to motor
|
||
** Input Args:
|
||
** void **handle - The pointer to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** None
|
||
** Description:
|
||
** The routine is similar to EL734_GetEncGearing except that it issues
|
||
** a "Q m" command instead of an "FD" command to the controller and
|
||
** a null response (rather than parameter values) is expected.
|
||
**-------------------------------------------------------------------------
|
||
** int EL734_WaitIdle (&handle, &ored_msr, &fp_cntr, &fr_cntr, &ist_posit)
|
||
** --------------
|
||
** Wait till MSR goes to zero.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** int *ored_msr \
|
||
** int *fp_cntr \ Same as EL734_GetStatus.
|
||
** int *fr_cntr /
|
||
** float *ist_posit /
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** True if no problems detected, otherwise False and Errcode (see
|
||
** EL734_ErrInfo) will have been set by the called routines to indicate
|
||
** the nature of the problem.
|
||
** Routines called:
|
||
** EL734_AddCallStack, EL734_GetStatus
|
||
** Description:
|
||
** Routine EL734_GetStatus is called repeatedly at a predefined frequency
|
||
** until the MSR__BUSY bit in the MSR register is zero.
|
||
**-------------------------------------------------------------------------
|
||
** void EL734_ZeroStatus (&handle)
|
||
** -----------------
|
||
** Zero the "ored-MSR" and fault counters.
|
||
** Input Args:
|
||
** void **handle - The pntr to the structure returned by EL734_Open.
|
||
** Output Args:
|
||
** none
|
||
** Modified Args:
|
||
** none
|
||
** Return status:
|
||
** none
|
||
** Routines called:
|
||
** none
|
||
** Description:
|
||
** The "ored-MSR" and fault counters in the handle are zeroed.
|
||
**============================================================================*/
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** Global Definitions
|
||
*/
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <stdarg.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 <rs232c_def.h>
|
||
#include <asynsrv_def.h>
|
||
#include <el734_def.h>
|
||
#include <sinq_prototypes.h>
|
||
|
||
#define True 1
|
||
#define False 0
|
||
/*--------------------------------------------------------------------------
|
||
** Global Variables
|
||
*/
|
||
static int EL734_call_depth = 0;
|
||
static char EL734_routine[5][64];
|
||
static int EL734_errcode = 0;
|
||
static int EL734_errno, EL734_vaxc_errno;
|
||
char EL734_IllgText[256];
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_AddCallStack: Add a routine name to the call stack.
|
||
** This allows EL734_ErrInfo to generate a
|
||
** trace-back in case of error.
|
||
*/
|
||
int EL734_AddCallStack(
|
||
/* ==================
|
||
*/ struct EL734info *pntr,
|
||
char *name)
|
||
{
|
||
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
|
||
if (EL734_call_depth < 5) {
|
||
strcpy(EL734_routine[EL734_call_depth], name);
|
||
EL734_call_depth++;
|
||
}
|
||
|
||
if (pntr == NULL) {
|
||
EL734_errcode = EL734__NOT_OPEN;
|
||
return False;
|
||
}
|
||
|
||
if (pntr->asyn_info.skt <= 0) {
|
||
memset(pntr->from_host.msg_size,
|
||
'0', sizeof(pntr->from_host.msg_size));
|
||
EL734_errcode = (pntr->asyn_info.skt < 0) ? EL734__FORCED_CLOSED
|
||
: EL734__NO_SOCKET;
|
||
return False;
|
||
}
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_Close: Close a connection to a motor.
|
||
*/
|
||
int EL734_Close(
|
||
/* ===========
|
||
*/ void **handle,
|
||
int force_flag)
|
||
{
|
||
|
||
struct EL734info *info_ptr;
|
||
char buff[4];
|
||
|
||
info_ptr = (struct EL734info *) *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;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_Config: Configure a connection to a motor.
|
||
*/
|
||
int EL734_Config(
|
||
/* ============
|
||
*/ void **handle,
|
||
...)
|
||
{
|
||
|
||
char buff[16];
|
||
va_list ap; /* Pointer to variable args */
|
||
char *txt_ptr;
|
||
int intval;
|
||
struct EL734info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_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)) {
|
||
EL734_errcode = EL734__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) {
|
||
EL734_errcode = EL734__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:
|
||
EL734_errcode = EL734__BAD_PAR;
|
||
return False;
|
||
}
|
||
} else if (strcmp(txt_ptr, "motor") == 0) {
|
||
intval = va_arg(ap, int);
|
||
if ((intval < 1) || (intval > 12)) {
|
||
EL734_errcode = EL734__BAD_PAR;
|
||
return False;
|
||
}
|
||
info_ptr->motor = intval;
|
||
} else if (strcmp(txt_ptr, "chan") == 0) {
|
||
intval = va_arg(ap, int);
|
||
if ((intval < 0) || (intval > 255)) {
|
||
EL734_errcode = EL734__BAD_PAR;
|
||
return False;
|
||
}
|
||
info_ptr->asyn_info.chan = intval;
|
||
sprintf(buff, "%04d", intval); /* Convert to ASCII */
|
||
memcpy(info_ptr->asyn_info.chan_char, buff, 4);
|
||
} else {
|
||
EL734_errcode = EL734__BAD_PAR;
|
||
return False;
|
||
}
|
||
txt_ptr = va_arg(ap, char *); /* Get pntr to next parameter ident */
|
||
}
|
||
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_EncodeMSR: Encode the MSR status into text.
|
||
*/
|
||
char *EL734_EncodeMSR(char *text, int text_len,
|
||
/* ===============
|
||
*/ int msr,
|
||
int ored_msr, int fp_cntr, int fr_cntr)
|
||
{
|
||
int len;
|
||
char my_text[132];
|
||
char my_text_0[32];
|
||
|
||
if (msr == 0) {
|
||
ored_msr = ored_msr & ~(MSR__BUSY); /* Zero "Busy" bit */
|
||
if (ored_msr == MSR__OK) {
|
||
StrJoin(text, text_len, "Status, MSR = Idle. Positioned OK.", "");
|
||
} else {
|
||
if ((ored_msr & MSR__OK) != 0) {
|
||
StrJoin(text, text_len, "Status, MSR = Idle. Positioned OK. ", "");
|
||
} else {
|
||
StrJoin(text, text_len, "Status, MSR = Idle. ", "");
|
||
}
|
||
if ((ored_msr & MSR__REF_OK) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Ref. Pos'n OK. ");
|
||
}
|
||
if ((ored_msr & MSR__LIM_ERR) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Limit Switch Problem. ");
|
||
}
|
||
if ((ored_msr & MSR__AC_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Air-Cushion Error. ");
|
||
}
|
||
if ((ored_msr & MSR__REF_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Ref. Pos'n Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__POS_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Pos'n Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__POS_FAULT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
if (fp_cntr == 1) {
|
||
StrJoin(text, text_len, my_text, "1 Pos'n Fault. ");
|
||
} else {
|
||
sprintf(my_text_0, "%d Pos'n Faults. ", fp_cntr);
|
||
StrJoin(text, text_len, my_text, my_text_0);
|
||
}
|
||
}
|
||
if ((ored_msr & MSR__RUN_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Run Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__RUN_FAULT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
if (fr_cntr == 1) {
|
||
StrJoin(text, text_len, my_text, "1 Run Fault. ");
|
||
} else {
|
||
sprintf(my_text_0, "%d Run Faults. ", fr_cntr);
|
||
StrJoin(text, text_len, my_text, my_text_0);
|
||
}
|
||
}
|
||
if ((ored_msr & MSR__HALT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Halt. ");
|
||
}
|
||
if ((ored_msr & MSR__HI_LIM) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Hit HiLim. ");
|
||
}
|
||
if ((ored_msr & MSR__LO_LIM) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Hit LoLim. ");
|
||
}
|
||
if ((ored_msr & MSR__STOPPED) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Stopped. ");
|
||
}
|
||
}
|
||
} else if ((msr & ~(0x2fff)) != 0) {
|
||
StrJoin(text, text_len, "Status, MSR = ??", "");
|
||
} else {
|
||
sprintf(my_text, "%#x ", msr);
|
||
StrJoin(text, text_len, "Status, MSR = ", my_text);
|
||
if ((msr & MSR__LIM_ERR) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Limit Switch Problem/");
|
||
}
|
||
if ((msr & MSR__AC_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Air-Cushion Error/");
|
||
}
|
||
if ((msr & MSR__REF_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Ref. Pos'n Fail/");
|
||
}
|
||
if ((msr & MSR__POS_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Pos'n Fail/");
|
||
}
|
||
if ((msr & MSR__POS_FAULT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Pos'n Fault/");
|
||
}
|
||
if ((msr & MSR__RUN_FAIL) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Run Fail/");
|
||
}
|
||
if ((msr & MSR__RUN_FAULT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Run Fault/");
|
||
}
|
||
if ((msr & MSR__HALT) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Halt/");
|
||
}
|
||
if ((msr & MSR__HI_LIM) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Hit HiLim/");
|
||
}
|
||
if ((msr & MSR__LO_LIM) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Hit LoLim/");
|
||
}
|
||
if ((msr & MSR__STOPPED) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Stopped/");
|
||
}
|
||
if ((msr & MSR__REF_OK) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Ref. Pos'n OK/");
|
||
}
|
||
if ((msr & MSR__OK) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "OK/");
|
||
}
|
||
if ((msr & MSR__BUSY) != 0) {
|
||
StrJoin(my_text, sizeof(my_text), text, "");
|
||
StrJoin(text, text_len, my_text, "Busy/");
|
||
}
|
||
len = strlen(text);
|
||
text[len - 1] = '\0';
|
||
}
|
||
return text;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_EncodeSS: Encode the SS flags into text.
|
||
*/
|
||
char *EL734_EncodeSS(char *text, int text_len, int ss)
|
||
{
|
||
/* ==============
|
||
*/
|
||
int len;
|
||
char my_text[132];
|
||
char my_text_0[32];
|
||
|
||
if (ss == 0) {
|
||
StrJoin(text, text_len, "Flags, SS = 0", "");
|
||
} else if ((ss & ~(0x3f)) != 0) {
|
||
StrJoin(text, text_len, "Flags, SS = ??", "");
|
||
} else {
|
||
sprintf(my_text, "Flags, SS = 0x%02X ", ss);
|
||
my_text_0[0] = '\0';
|
||
if ((ss & 0x20) != 0)
|
||
strcat(my_text_0, "LSX/");
|
||
if ((ss & 0x10) != 0)
|
||
strcat(my_text_0, "LS2/");
|
||
if ((ss & 0x08) != 0)
|
||
strcat(my_text_0, "LS1/");
|
||
if ((ss & 0x04) != 0)
|
||
strcat(my_text_0, "STP/");
|
||
if ((ss & 0x02) != 0)
|
||
strcat(my_text_0, "CCW/");
|
||
if ((ss & 0x01) != 0)
|
||
strcat(my_text_0, "HLT/");
|
||
len = strlen(my_text_0);
|
||
my_text_0[len - 1] = '\0';
|
||
StrJoin(text, text_len, my_text, my_text_0);
|
||
}
|
||
return text;
|
||
}
|
||
|
||
/*
|
||
**-------------------------------------------------------------------------
|
||
** EL734_ErrInfo: Return detailed status from last operation.
|
||
*/
|
||
void EL734_ErrInfo(
|
||
/* =============
|
||
*/ char **entry_txt,
|
||
int *errcode, int *my_errno, int *vaxc_errno)
|
||
{
|
||
|
||
int i;
|
||
char buff[80], *txt;
|
||
int asyn_errcode, asyn_errno, asyn_vaxerrno;
|
||
char *asyn_errtxt;
|
||
|
||
if (EL734_call_depth <= 0) {
|
||
strcpy(EL734_routine[0], "EL734_no_error_detected");
|
||
*errcode = 0;
|
||
*my_errno = 0;
|
||
*vaxc_errno = 0;
|
||
} else {
|
||
if (EL734_call_depth > 1) { /* Concatenate the names */
|
||
for (i = 1; i < EL734_call_depth; i++) {
|
||
strcat(EL734_routine[0], "/");
|
||
StrJoin(EL734_routine[0], sizeof(EL734_routine),
|
||
EL734_routine[0], EL734_routine[i]);
|
||
}
|
||
}
|
||
*errcode = EL734_errcode;
|
||
*my_errno = EL734_errno;
|
||
*vaxc_errno = EL734_vaxc_errno;
|
||
switch (EL734_errcode) {
|
||
case EL734__BAD_ADR:
|
||
txt = "/EL734__BAD_ADR";
|
||
break;
|
||
case EL734__BAD_ASYNSRV:
|
||
txt = "/EL734__BAD_ASYNSRV";
|
||
break;
|
||
case EL734__BAD_CMD:
|
||
txt = "/EL734__BAD_CMD";
|
||
break;
|
||
case EL734__BAD_DEV:
|
||
txt = "/EL734__BAD_DEV";
|
||
break;
|
||
case EL734__BAD_ILLG:
|
||
txt = "/EL734__BAD_ILLG";
|
||
break;
|
||
case EL734__BAD_LOC:
|
||
txt = "/EL734__BAD_LOC";
|
||
break;
|
||
case EL734__BAD_MALLOC:
|
||
txt = "/EL734__BAD_MALLOC";
|
||
break;
|
||
case EL734__BAD_OFL:
|
||
txt = "/EL734__BAD_OFL";
|
||
break;
|
||
case EL734__BAD_OVFL:
|
||
txt = "/EL734__BAD_OVFL";
|
||
break;
|
||
case EL734__BAD_PAR:
|
||
txt = "/EL734__BAD_PAR";
|
||
break;
|
||
case EL734__BAD_RNG:
|
||
txt = "/EL734__BAD_RNG";
|
||
break;
|
||
case EL734__BAD_SOCKET:
|
||
txt = "/EL734__BAD_SOCKET";
|
||
break;
|
||
case EL734__BAD_STP:
|
||
txt = "/EL734__BAD_STP";
|
||
break;
|
||
case EL734__BAD_TMO:
|
||
txt = "/EL734__BAD_TMO";
|
||
break;
|
||
case EL734__EMERG_STOP:
|
||
txt = "/EL734__EMERG_STOP";
|
||
break;
|
||
case EL734__FORCED_CLOSED:
|
||
txt = "/EL734__FORCED_CLOSED";
|
||
break;
|
||
case EL734__NOT_OPEN:
|
||
txt = "/EL734__NOT_OPEN";
|
||
break;
|
||
case EL734__NO_SOCKET:
|
||
txt = "/EL734__NO_SOCKET";
|
||
break;
|
||
default:
|
||
sprintf(buff, "/EL734__unknown_err_code: %d", EL734_errcode);
|
||
txt = buff;
|
||
}
|
||
StrJoin(EL734_routine[0], sizeof(EL734_routine), EL734_routine[0],
|
||
txt);
|
||
}
|
||
AsynSrv_ErrInfo(&asyn_errtxt, &asyn_errcode, &asyn_errno,
|
||
&asyn_vaxerrno);
|
||
if (asyn_errcode != 0) {
|
||
strcat(EL734_routine[0], "/");
|
||
StrJoin(EL734_routine[0], sizeof(EL734_routine),
|
||
EL734_routine[0], asyn_errtxt);
|
||
}
|
||
*entry_txt = EL734_routine[0];
|
||
EL734_call_depth = 0;
|
||
EL734_errcode = 0;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetAirCush: Get W and AC register values.
|
||
*/
|
||
int EL734_GetAirCush(
|
||
/* ================
|
||
*/ void **handle,
|
||
int *present, int *state)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10], cmnd1[10];
|
||
char *rply_ptr, *rply_ptr0, *rply_ptr1;
|
||
/*----------------------------------------------
|
||
*/
|
||
*present = *state = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetAirCush"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send W and AC cmnds to EL734
|
||
*/
|
||
sprintf(cmnd0, "w %d\r", info_ptr->motor);
|
||
sprintf(cmnd1, "ac %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, cmnd1, NULL);
|
||
if (!status) {
|
||
*present = *state = 0;
|
||
EL734_errcode = EL734__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 = "?no_response";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?no_response";
|
||
|
||
if ((sscanf(rply_ptr0, "%d", present) != 1) ||
|
||
(sscanf(rply_ptr1, "%d", state) != 1)) {
|
||
if (*rply_ptr0 == '?') {
|
||
rply_ptr = rply_ptr0;
|
||
} else if (*rply_ptr1 == '?') {
|
||
rply_ptr = rply_ptr1;
|
||
} else {
|
||
rply_ptr = "?funny_response";
|
||
}
|
||
*present = *state = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr, "W\" or \"AC");
|
||
return False;
|
||
}
|
||
}
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetEncGearing: Get FD register values.
|
||
*/
|
||
int EL734_GetEncGearing(
|
||
/* ===================
|
||
*/ void **handle,
|
||
int *nominator, int *denominator)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*nominator = *denominator = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetEncGearing"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send FD cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "fd %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*nominator = *denominator = 0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%d %d", nominator, denominator) == 2) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*nominator = *denominator = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "FD");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetId: Get ID register value.
|
||
*/
|
||
int EL734_GetId(
|
||
/* ===========
|
||
*/ void **handle,
|
||
char *id_txt, int id_len)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*id_txt = '\0';
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetId"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send ID cmnd to EL734
|
||
*/
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"id\r", NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if ((rply_ptr0 != NULL) && (*rply_ptr0 != '\0') && (*rply_ptr0 != '?')) {
|
||
StrJoin(id_txt, id_len, rply_ptr0, "");
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "ID");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetLimits: Get H register values.
|
||
*/
|
||
int EL734_GetLimits(
|
||
/* ===============
|
||
*/ void **handle,
|
||
float *lo, float *hi)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*lo = *hi = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetLimits"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send H cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "h %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*lo = *hi = 0.0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%f %f", lo, hi) == 2) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*lo = *hi = 0.0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "H");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetMotorGearing: Get FM register values.
|
||
*/
|
||
int EL734_GetMotorGearing(
|
||
/* =====================
|
||
*/ void **handle,
|
||
int *nominator, int *denominator)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*nominator = *denominator = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetMotorGearing"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send FM cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "fm %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*nominator = *denominator = 0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%d %d", nominator, denominator) == 2) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*nominator = *denominator = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "FM");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetNullPoint: Get V register value.
|
||
*/
|
||
int EL734_GetNullPoint(
|
||
/* ==================
|
||
*/ void **handle,
|
||
int *null_pt)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*null_pt = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetNullPoint"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send V cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "v %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*null_pt = 0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%d", null_pt) == 1) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*null_pt = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "V");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetPosition: Get U register value, the current position.
|
||
*/
|
||
int EL734_GetPosition(
|
||
/* =================
|
||
*/ void **handle,
|
||
float *ist_posit)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*ist_posit = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetPosition"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send U cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "u %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*ist_posit = 0.0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%f", ist_posit) == 1) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*ist_posit = 0.0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "U");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetPrecision: Get A register value.
|
||
*/
|
||
int EL734_GetPrecision(
|
||
/* ==================
|
||
*/ void **handle,
|
||
int *n_dec)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*n_dec = 3;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetPrecision"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send A cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "a %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*n_dec = 3;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%d", n_dec) == 1) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*n_dec = 3;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "A");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetRefMode: Get K register value.
|
||
*/
|
||
int EL734_GetRefMode(
|
||
/* ================
|
||
*/ void **handle,
|
||
int *mode)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*mode = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetRefMode"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send K cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "k %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*mode = 0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%d", mode) == 1) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*mode = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "K");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetRefParam: Get Q register value.
|
||
*/
|
||
int EL734_GetRefParam(
|
||
/* =================
|
||
*/ void **handle,
|
||
float *param)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*param = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetRefParam"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send Q cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "q %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
*param = 0.0;
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (sscanf(rply_ptr0, "%f", param) == 1) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
*param = 0.0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "Q");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetSpeeds: Get G/J/E register values.
|
||
*/
|
||
int EL734_GetSpeeds(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int *lo, int *hi, int *ramp)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char cmnd1[10];
|
||
char cmnd2[10];
|
||
char *rply_ptr;
|
||
char *rply_ptr0;
|
||
char *rply_ptr1;
|
||
char *rply_ptr2;
|
||
/*----------------------------------------------
|
||
*/
|
||
*lo = *hi = *ramp = 0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetSpeeds"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send G, J and E cmnds to EL734
|
||
*/
|
||
sprintf(cmnd0, "g %d\r", info_ptr->motor);
|
||
sprintf(cmnd1, "j %d\r", info_ptr->motor);
|
||
sprintf(cmnd2, "e %d\r", info_ptr->motor);
|
||
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, cmnd1, cmnd2, NULL);
|
||
if (!status) {
|
||
*lo = *hi = *ramp = 0;
|
||
EL734_errcode = EL734__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 = "?no_response";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?no_response";
|
||
if (rply_ptr2 == NULL)
|
||
rply_ptr2 = "?no_response";
|
||
|
||
if ((sscanf(rply_ptr0, "%d", lo) != 1) ||
|
||
(sscanf(rply_ptr1, "%d", hi) != 1) ||
|
||
(sscanf(rply_ptr2, "%d", ramp) != 1)) {
|
||
if (*rply_ptr0 == '?') {
|
||
rply_ptr = rply_ptr0;
|
||
} else if (*rply_ptr1 == '?') {
|
||
rply_ptr = rply_ptr1;
|
||
} else if (*rply_ptr2 == '?') {
|
||
rply_ptr = rply_ptr2;
|
||
} else {
|
||
rply_ptr = "?funny_response";
|
||
}
|
||
*lo = *hi = *ramp = 0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr, "G\", \"J\" or \"E");
|
||
return False;
|
||
}
|
||
}
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetStatus: Get MSR/SS/U register values.
|
||
*/
|
||
int EL734_GetStatus(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int *msr,
|
||
int *ored_msr,
|
||
int *fp_cntr, int *fr_cntr, int *ss, float *ist_posit)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char cmnd1[10];
|
||
char cmnd2[10];
|
||
char *rply_ptr;
|
||
char *rply_ptr0;
|
||
char *rply_ptr1;
|
||
char *rply_ptr2;
|
||
/*----------------------------------------------
|
||
*/
|
||
*msr = *ored_msr = *fp_cntr = *fr_cntr = *ss = -1;
|
||
*ist_posit = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetStatus"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send MSR, SS and U cmnds to EL734
|
||
*/
|
||
sprintf(cmnd0, "msr %d\r", info_ptr->motor);
|
||
sprintf(cmnd1, "ss %d\r", info_ptr->motor);
|
||
sprintf(cmnd2, "u %d\r", info_ptr->motor);
|
||
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, cmnd1, cmnd2, NULL);
|
||
if (!status) {
|
||
*msr = *ored_msr = *fp_cntr = *fr_cntr = *ss = -1;
|
||
*ist_posit = 0.0;
|
||
EL734_errcode = EL734__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 = "?no_response";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?no_response";
|
||
if (rply_ptr2 == NULL)
|
||
rply_ptr2 = "?no_response";
|
||
|
||
if ((sscanf(rply_ptr0, "%x", msr) == 1) &&
|
||
(sscanf(rply_ptr2, "%f", ist_posit) == 1)) {
|
||
info_ptr->ored_msr = info_ptr->ored_msr | *msr;
|
||
if ((*msr & MSR__POS_FAULT) != 0)
|
||
info_ptr->fp_cntr++;
|
||
if ((*msr & MSR__RUN_FAULT) != 0)
|
||
info_ptr->fr_cntr++;
|
||
*ored_msr = info_ptr->ored_msr;
|
||
*fp_cntr = info_ptr->fp_cntr;
|
||
*fr_cntr = info_ptr->fr_cntr;
|
||
/* Remember: we may get "?BSY" for SS and
|
||
** this should not be treated as an error!
|
||
*/
|
||
if (sscanf(rply_ptr1, "%x", ss) != 1)
|
||
*ss = -1;
|
||
} else {
|
||
if (*rply_ptr0 == '?') {
|
||
rply_ptr = rply_ptr0;
|
||
} else if (*rply_ptr1 == '?') {
|
||
rply_ptr = rply_ptr1;
|
||
} else if (*rply_ptr2 == '?') {
|
||
rply_ptr = rply_ptr2;
|
||
} else {
|
||
rply_ptr = "?funny_response";
|
||
}
|
||
*msr = *ored_msr = *fp_cntr = *fr_cntr = *ss = -1;
|
||
*ist_posit = 0.0;
|
||
EL734_SetErrcode(info_ptr, rply_ptr, "MSR\", \"SS\" or \"U");
|
||
return False;
|
||
}
|
||
}
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_GetZeroPoint: Get zero point (= converted V register value)
|
||
*/
|
||
int EL734_GetZeroPoint(
|
||
/* ==================
|
||
*/ void **handle,
|
||
float *zero_pt)
|
||
{
|
||
|
||
int status, null_pt, nom, denom;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
*zero_pt = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_GetZeroPoint"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Get V register value.
|
||
*/
|
||
status = EL734_GetNullPoint(handle, &null_pt);
|
||
if (!status)
|
||
return False;
|
||
|
||
/*----------------------------------------------
|
||
** FD register values.
|
||
*/
|
||
status = EL734_GetEncGearing(handle, &nom, &denom);
|
||
if (!status)
|
||
return False;
|
||
|
||
if (nom == 0) {
|
||
EL734_errcode = EL734__BAD_OVFL; /* Encoder gearing ratio is zero */
|
||
return False;
|
||
}
|
||
|
||
*zero_pt = ((float) denom) / ((float) nom);
|
||
*zero_pt *= (float) null_pt;
|
||
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_MoveNoWait: Move motor and don't wait for completion.
|
||
*/
|
||
int EL734_MoveNoWait(
|
||
/* ================
|
||
*/ void **handle,
|
||
float soll_posit)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[32];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_MoveNoWait"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send P cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "p %d %.3f\r", info_ptr->motor, soll_posit);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (*rply_ptr0 == '\0' || *rply_ptr0 == '\r') {
|
||
/*
|
||
** The command was accepted - so zero the statistics
|
||
** fields in the handle and return to caller.
|
||
*/
|
||
info_ptr->ored_msr = info_ptr->fp_cntr = info_ptr->fr_cntr = 0;
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "P");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_MoveWait: Move motor and wait for completion.
|
||
*/
|
||
int EL734_MoveWait(
|
||
/* ==============
|
||
*/ void **handle,
|
||
float soll_posit,
|
||
int *ored_msr,
|
||
int *fp_cntr, int *fr_cntr, float *ist_posit)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
*ored_msr = *fp_cntr = *fr_cntr = -1;
|
||
*ist_posit = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_MoveWait"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Start the movement.
|
||
*/
|
||
status = EL734_MoveNoWait(handle, soll_posit);
|
||
if (status) {
|
||
status = EL734_WaitIdle(handle, ored_msr, fp_cntr, fr_cntr, ist_posit);
|
||
}
|
||
if (status && (EL734_errcode == 0))
|
||
EL734_call_depth--;
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
return status;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_Open: Open a connection to a motor.
|
||
*/
|
||
int EL734_Open(
|
||
/* ==========
|
||
*/ void **handle,
|
||
char *host, int port, int chan, int motor, char *device_id)
|
||
{
|
||
|
||
int my_msr, status;
|
||
struct EL734info *my_handle;
|
||
char tmo_save[4];
|
||
char msr_cmnd[20];
|
||
char *rply_ptr;
|
||
char *rply_ptr0;
|
||
char *rply_ptr1;
|
||
char *rply_ptr2;
|
||
char *rply_ptr3;
|
||
/*--------------------------------------------------------
|
||
** Initialise the error info stack and pre-set the
|
||
** routine name (in case of error).
|
||
*/
|
||
EL734_errcode = EL734_errno = EL734_vaxc_errno = 0;
|
||
strcpy(EL734_routine[0], "EL734_Open");
|
||
EL734_call_depth = 1;
|
||
/*--------------------------------------------------------
|
||
** Assume trouble
|
||
*/
|
||
*handle = NULL;
|
||
/*--------------------------------------------------------
|
||
** Reserve space for the data we need to store.
|
||
*/
|
||
my_handle = (struct EL734info *) malloc(sizeof(*my_handle));
|
||
if (my_handle == NULL) {
|
||
EL734_errcode = EL734__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) {
|
||
EL734_errcode = EL734__BAD_SOCKET;
|
||
GetErrno(&EL734_errno, &EL734_vaxc_errno); /* Save errno info */
|
||
fprintf(stderr, "\nEL734_Open/AsynSrv_Open: "
|
||
"Failed to make connection.\n");
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
|
||
memcpy(tmo_save, my_handle->asyn_info.tmo, 4); /* Save time-out */
|
||
EL734_Config((void *) &my_handle, "msecTmo", 500, /* Set a short time-out initially since
|
||
** there should be no reason for the RMT,
|
||
** ECHO or ID commands to take very long.
|
||
*/
|
||
"eot", "1\r", "motor", motor, NULL);
|
||
my_handle->ored_msr = 0;
|
||
my_handle->fp_cntr = 0;
|
||
my_handle->fr_cntr = 0;
|
||
/*
|
||
** Now ensure the EL734 is on-line. The first "RMT 1" command can
|
||
** fail due to pending characters in the EL734 input buffer causing
|
||
** the "RMT 1" to be corrupted. The response of the EL734 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);
|
||
sprintf(msr_cmnd, "msr %d\r", motor);
|
||
if (status) {
|
||
if (device_id != NULL) {
|
||
status = AsynSrv_SendCmnds(&my_handle->asyn_info,
|
||
&my_handle->to_host,
|
||
&my_handle->from_host, "rmt 1\r",
|
||
"echo 0\r", "id\r", msr_cmnd, NULL);
|
||
} else {
|
||
status = AsynSrv_SendCmnds(&my_handle->asyn_info,
|
||
&my_handle->to_host,
|
||
&my_handle->from_host, "rmt 1\r",
|
||
"echo 0\r", "echo 0\r", msr_cmnd, NULL);
|
||
}
|
||
}
|
||
memcpy(my_handle->asyn_info.tmo, tmo_save, 4); /* Restore time-out */
|
||
if (!status) {
|
||
/* Some error occurred in AsynSrv_SendCmnds */
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
} else {
|
||
/* Check the responses carefully. The 3rd response should
|
||
** be the device identifier (if to be checked). The 4th
|
||
** response should be a hex integer.
|
||
** MK: But first we check for *ES, emergency stop.
|
||
** The desired behaviour is that we continue in this
|
||
** case and hope for the best.
|
||
*/
|
||
rply_ptr1 = rply_ptr2 = rply_ptr3 = 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_ptr2 != NULL)
|
||
rply_ptr3 =
|
||
AsynSrv_GetReply(&my_handle->asyn_info, &my_handle->from_host,
|
||
rply_ptr2);
|
||
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?no_response";
|
||
if (rply_ptr2 == NULL)
|
||
rply_ptr2 = "?no_response";
|
||
if (rply_ptr3 == NULL)
|
||
rply_ptr3 = "?no_response";
|
||
|
||
if (strstr(rply_ptr0, "*ES") != NULL) {
|
||
*handle = my_handle;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
if (*rply_ptr1 == '?')
|
||
rply_ptr0 = rply_ptr1;
|
||
if (*rply_ptr2 == '?')
|
||
rply_ptr0 = rply_ptr2;
|
||
if (*rply_ptr3 == '?')
|
||
rply_ptr0 = rply_ptr3;
|
||
if (*rply_ptr0 != '?') {
|
||
if (device_id != NULL) { /* Check device ID? */
|
||
if (*rply_ptr2 == '\0') { /* Yes. But if response is blank, it
|
||
** may be because Emergency Stop is set.
|
||
*/
|
||
EL734_SetErrcode(my_handle, rply_ptr2, "ID");
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
} else {
|
||
if (strncmp(rply_ptr2, device_id, strlen(device_id)) != 0) {
|
||
EL734_errcode = EL734__BAD_DEV; /* Device has wrong ID */
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
}
|
||
}
|
||
if (sscanf(rply_ptr3, "%x", &my_msr) != 1) {
|
||
/* MSR response is bad */
|
||
EL734_SetErrcode(my_handle, rply_ptr3, msr_cmnd); /* Check for *ES */
|
||
if (EL734_errcode != EL734__EMERG_STOP)
|
||
EL734_errcode = EL734__BAD_DEV;
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
/*
|
||
** The connection is complete. Pass the data structure
|
||
** back to the caller as a handle.
|
||
*/
|
||
*handle = my_handle;
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
} else {
|
||
EL734_errcode = EL734__BAD_DEV;
|
||
if (strcmp(rply_ptr0, "?OFL") == 0)
|
||
EL734_errcode = EL734__BAD_OFL;
|
||
if (strcmp(rply_ptr0, "?CMD") == 0)
|
||
EL734_errcode = EL734__BAD_CMD;
|
||
if (strcmp(rply_ptr0, "?LOC") == 0)
|
||
EL734_errcode = EL734__BAD_LOC;
|
||
if (strcmp(rply_ptr0, "?ADR") == 0)
|
||
EL734_errcode = EL734__BAD_ADR;
|
||
if (strcmp(rply_ptr0, "*ES") == 0)
|
||
EL734_errcode = EL734__EMERG_STOP;
|
||
if (strncmp(rply_ptr0, "?TMO", 4) == 0)
|
||
EL734_errcode = EL734__BAD_TMO;
|
||
if (EL734_errcode == EL734__BAD_DEV)
|
||
fprintf(stderr, " Unrecognised initial response: \"%s\"\n",
|
||
rply_ptr0);
|
||
}
|
||
}
|
||
AsynSrv_Close(&my_handle->asyn_info, False);
|
||
free(my_handle);
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_PutOffline: put the EL734 off-line
|
||
*/
|
||
int EL734_PutOffline(
|
||
/* ================
|
||
*/ void **handle)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char *rply_ptr0, *rply_ptr1, *rply_ptr2;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_PutOffline"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** The problem which this routine has is that the EL734
|
||
** may already be off-line. The following is, therefore,
|
||
** rather pedantic for most cases which occur in practice.
|
||
*/
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"\r", "rmt 1\r", "echo 1\r", "rmt 0\r", NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"RMT\r", "", NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
rply_ptr1 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (rply_ptr1 == NULL)
|
||
rply_ptr1 = "?no_response";
|
||
if ((strcmp(rply_ptr0, "RMT") == 0) && (strcmp(rply_ptr1, "\n0") == 0)) {
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "RMT");
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_PutOnline: put the EL734 on-line
|
||
*/
|
||
int EL734_PutOnline(
|
||
/* ===============
|
||
*/ void **handle,
|
||
int echo)
|
||
{
|
||
|
||
int status, my_echo;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_PutOnline"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
*/
|
||
if ((echo != 0) && (echo != 1) && (echo != 2)) {
|
||
EL734_errcode = EL734__BAD_PAR;
|
||
return False;
|
||
}
|
||
/*----------------------------------------------
|
||
** The problem which this routine has is that the state
|
||
** of the EL734 is not known. The following is, therefore,
|
||
** rather pedantic for most cases which occur in practice.
|
||
*/
|
||
sprintf(cmnd0, "echo %d\r", echo);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"\r", "rmt 1\r", cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"echo\r", NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
}
|
||
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (strcmp(rply_ptr0, "ECHO") == 0) {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host,
|
||
rply_ptr0);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
}
|
||
if ((sscanf(rply_ptr0, "%d", &my_echo) == 1) && (my_echo == echo)) {
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "ECHO");
|
||
return False;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SendCmnd - Send a command to RS232C server.
|
||
*/
|
||
int EL734_SendCmnd(
|
||
/* ==============
|
||
*/ void **handle,
|
||
char *cmnd, char *rply, int rply_size)
|
||
{
|
||
|
||
struct EL734info *info_ptr;
|
||
int my_status;
|
||
char *rply_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_SendCmnd"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send command to EL734.
|
||
*/
|
||
my_status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd, NULL);
|
||
if (!my_status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr == NULL)
|
||
rply_ptr = "?no_response";
|
||
StrJoin(rply, rply_size, rply_ptr, "");
|
||
}
|
||
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SetAirCush: Set the air-cushion register (AC register)
|
||
*/
|
||
int EL734_SetAirCush(
|
||
/* ================
|
||
*/ void **handle,
|
||
int state)
|
||
{
|
||
|
||
int status, dum1, my_state;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[32];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_SetAirCush"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send AC cmnd to EL734
|
||
*/
|
||
if (state != 0)
|
||
state = 1;
|
||
sprintf(cmnd0, "ac %d %d\r", info_ptr->motor, state);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (*rply_ptr0 == '\0') {
|
||
/*
|
||
** The command was accepted - check value is set OK.
|
||
*/
|
||
status = EL734_GetAirCush(handle, &dum1, &my_state);
|
||
if (!status)
|
||
return False;
|
||
if (state != my_state) {
|
||
EL734_errcode = EL734__VFY_ERR;
|
||
return False;
|
||
}
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "AC");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SetErrcode - Set up EL734_errcode
|
||
*/
|
||
int EL734_SetErrcode(
|
||
/* ================
|
||
*/ struct EL734info *info_ptr,
|
||
char *response, char *cmnd)
|
||
{
|
||
|
||
int status;
|
||
char *rply;
|
||
char tmo_save[4];
|
||
char eot_save[4];
|
||
|
||
EL734_errcode = EL734__BAD_ILLG;
|
||
if (strcmp(response, "?OFL") == 0)
|
||
EL734_errcode = EL734__BAD_OFL;
|
||
if (strcmp(response, "?CMD") == 0)
|
||
EL734_errcode = EL734__BAD_CMD;
|
||
if (strcmp(response, "?LOC") == 0)
|
||
EL734_errcode = EL734__BAD_LOC;
|
||
if (strcmp(response, "?ADR") == 0)
|
||
EL734_errcode = EL734__BAD_ADR;
|
||
if (strcmp(response, "?RNG") == 0)
|
||
EL734_errcode = EL734__BAD_RNG;
|
||
if (strcmp(response, "*ES") == 0)
|
||
EL734_errcode = EL734__EMERG_STOP;
|
||
if (strcmp(response, "*MS") == 0)
|
||
EL734_errcode = EL734__BAD_STP;
|
||
if (strncmp(response, "?TMO", 4) == 0)
|
||
EL734_errcode = EL734__BAD_TMO;
|
||
if (EL734_errcode != EL734__BAD_ILLG)
|
||
return EL734_errcode;
|
||
/*
|
||
** The response is not recognised. Perhaps the emergency stop
|
||
** signal is set. To check this, it is necessary to turn off
|
||
** terminator checking since the EL734 prefixes its "*ES"
|
||
** response with a <Return> character. We also therefore set
|
||
** a very short time-out.
|
||
*/
|
||
memcpy(tmo_save, info_ptr->asyn_info.tmo, 4); /* Save time-out */
|
||
memcpy(eot_save, info_ptr->asyn_info.eot, 4); /* Save terminators */
|
||
AsynSrv_Config(&info_ptr->asyn_info, "msecTmo", 100, /* Set short time-out */
|
||
"eot", "0", /* Set no terminator */
|
||
NULL);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
"ID\r", NULL);
|
||
memcpy(info_ptr->asyn_info.eot, eot_save, 4); /* Restore terminators */
|
||
memcpy(info_ptr->asyn_info.tmo, tmo_save, 4); /* Restore time-out */
|
||
if (status) {
|
||
rply =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply == NULL)
|
||
rply = "?no_response";
|
||
} else {
|
||
rply = "?no_response";
|
||
}
|
||
if (strstr(rply, "*ES") != NULL)
|
||
EL734_errcode = EL734__EMERG_STOP;
|
||
|
||
if ((EL734_errcode == EL734__BAD_ILLG) && (cmnd != NULL)) {
|
||
fprintf(stderr, " Unrecognised response to \"%s\" command: \"%s\"\n",
|
||
cmnd, response);
|
||
strcpy(EL734_IllgText, cmnd);
|
||
strcat(EL734_IllgText, " : ");
|
||
strcat(EL734_IllgText, response);
|
||
}
|
||
return EL734_errcode;
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SetHighSpeed: Set the max speed (J register)
|
||
*/
|
||
int EL734_SetHighSpeed(
|
||
/* ==================
|
||
*/ void **handle,
|
||
int hi)
|
||
{
|
||
|
||
int status, my_lo, my_hi, my_ramp;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[32];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_SetHighSpeed"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send J cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "j %d %d\r", info_ptr->motor, hi);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (*rply_ptr0 == '\0') {
|
||
/*
|
||
** The command was accepted - check value is set OK.
|
||
*/
|
||
status = EL734_GetSpeeds(handle, &my_lo, &my_hi, &my_ramp);
|
||
if (!status)
|
||
return False;
|
||
if (hi != my_hi) {
|
||
EL734_errcode = EL734__VFY_ERR;
|
||
return False;
|
||
}
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "J");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SetLowSpeed: Set the start/stop speed (G register)
|
||
*/
|
||
int EL734_SetLowSpeed(
|
||
/* =================
|
||
*/ void **handle,
|
||
int lo)
|
||
{
|
||
|
||
int status, my_lo, my_hi, my_ramp;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[32];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_SetLowSpeed"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send G cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "g %d %d\r", info_ptr->motor, lo);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (*rply_ptr0 == '\0') {
|
||
/*
|
||
** The command was accepted - check value is set OK.
|
||
*/
|
||
status = EL734_GetSpeeds(handle, &my_lo, &my_hi, &my_ramp);
|
||
if (!status)
|
||
return False;
|
||
if (lo != my_lo) {
|
||
EL734_errcode = EL734__VFY_ERR;
|
||
return False;
|
||
}
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "G");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_SetRamp: Set the start/stop ramp (E register)
|
||
*/
|
||
int EL734_SetRamp(
|
||
/* =============
|
||
*/ void **handle,
|
||
int ramp)
|
||
{
|
||
|
||
int status, my_lo, my_hi, my_ramp;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[32];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_SetRamp"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send E cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "e %d %d\r", info_ptr->motor, ramp);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (*rply_ptr0 == '\0') {
|
||
/*
|
||
** The command was accepted - check value is set OK.
|
||
*/
|
||
status = EL734_GetSpeeds(handle, &my_lo, &my_hi, &my_ramp);
|
||
if (!status)
|
||
return False;
|
||
if (ramp != my_ramp) {
|
||
EL734_errcode = EL734__VFY_ERR;
|
||
return False;
|
||
}
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "E");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_Stop: Send a stop command to motor.
|
||
*/
|
||
int EL734_Stop(
|
||
/* ==========
|
||
*/ void **handle)
|
||
{
|
||
|
||
int status;
|
||
struct EL734info *info_ptr;
|
||
char cmnd0[10];
|
||
char *rply_ptr0;
|
||
/*----------------------------------------------
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_Stop"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Send S cmnd to EL734
|
||
*/
|
||
sprintf(cmnd0, "s %d\r", info_ptr->motor);
|
||
status = AsynSrv_SendCmnds(&info_ptr->asyn_info,
|
||
&info_ptr->to_host, &info_ptr->from_host,
|
||
cmnd0, NULL);
|
||
if (!status) {
|
||
EL734_errcode = EL734__BAD_ASYNSRV;
|
||
return False;
|
||
} else {
|
||
rply_ptr0 =
|
||
AsynSrv_GetReply(&info_ptr->asyn_info, &info_ptr->from_host, NULL);
|
||
if (rply_ptr0 == NULL)
|
||
rply_ptr0 = "?no_response";
|
||
if (rply_ptr0[0] == '\0') {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
EL734_SetErrcode(info_ptr, rply_ptr0, "S");
|
||
return False;
|
||
}
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_WaitIdle: Wait till MSR goes to zero.
|
||
*/
|
||
int EL734_WaitIdle(
|
||
/* ==============
|
||
*/ void **handle,
|
||
int *ored_msr,
|
||
int *fp_cntr, int *fr_cntr, float *ist_posit)
|
||
{
|
||
#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 msr, ss;
|
||
struct EL734info *info_ptr;
|
||
/*----------------------------------------------
|
||
*/
|
||
*ored_msr = *fp_cntr = *fr_cntr = -1;
|
||
*ist_posit = 0.0;
|
||
info_ptr = (struct EL734info *) *handle;
|
||
|
||
if (!EL734_AddCallStack(info_ptr, "EL734_WaitIdle"))
|
||
return False;
|
||
/*----------------------------------------------
|
||
** Poll the motor status till not moving.
|
||
*/
|
||
while (EL734_GetStatus(handle,
|
||
&msr, ored_msr, fp_cntr, fr_cntr, &ss,
|
||
ist_posit)) {
|
||
if ((msr & MSR__BUSY) == 0) {
|
||
if (EL734_errcode != 0)
|
||
return False;
|
||
EL734_call_depth--;
|
||
return True;
|
||
}
|
||
hibernate;
|
||
}
|
||
return False; /* Error detected in EL734_GetStatus */
|
||
}
|
||
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EL734_ZeroStatus: Zero the "ored-MSR" and fault counters.
|
||
*/
|
||
void EL734_ZeroStatus(
|
||
/* ================
|
||
*/ void **handle)
|
||
{
|
||
|
||
struct EL734info *info_ptr;
|
||
/*
|
||
** Do nothing if no handle!
|
||
*/
|
||
info_ptr = (struct EL734info *) *handle;
|
||
if (info_ptr == NULL)
|
||
return;
|
||
/*
|
||
** Zero the data structure items.
|
||
*/
|
||
info_ptr->ored_msr = 0;
|
||
info_ptr->fp_cntr = 0;
|
||
info_ptr->fr_cntr = 0;
|
||
memset(info_ptr->from_host.msg_size,
|
||
'0', sizeof(info_ptr->from_host.msg_size));
|
||
return;
|
||
}
|
||
|
||
/*-------------------------------------------- End of EL734_Utility.C =======*/
|