forked from epics_driver_modules/motorBase
Converted to R3.14.x and C++.
This commit is contained in:
+15
-27
@@ -3,9 +3,9 @@ FILENAME... motor.h
|
||||
USAGE... Definitions and structures common to all levels of motorRecord
|
||||
support (i.e., record, device and driver).
|
||||
|
||||
Version: $Revision: 1.5 $
|
||||
Version: $Revision: 1.6 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 17:10:31 $
|
||||
Last Modified: $Date: 2002-10-21 21:04:30 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -35,6 +35,8 @@ Last Modified: $Date: 2002-07-05 17:10:31 $
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*
|
||||
* .01 10-21-02 rls Convert to R3.14.x and C++.
|
||||
*/
|
||||
|
||||
#ifndef INCmotorh
|
||||
@@ -48,7 +50,15 @@ Last Modified: $Date: 2002-07-05 17:10:31 $
|
||||
message size for each device. */
|
||||
#define MAX_MSG_SIZE 300
|
||||
|
||||
typedef enum BOOLEAN_VALUES {OFF = 0, ON = 1} BOOLEAN;
|
||||
#if defined(OK)
|
||||
#undef OK
|
||||
#endif
|
||||
|
||||
#if defined(ERROR)
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
typedef enum RTN_VALUES {OK = 0, ERROR = 1} RTN_STATUS;
|
||||
|
||||
#define NINT(f) (long)((f)>0 ? (f)+0.5 : (f)-0.5) /* Nearest integer. */
|
||||
|
||||
@@ -83,9 +93,6 @@ enum motor_cmnd {
|
||||
JOG_VELOCITY /* Change Jog velocity. */
|
||||
};
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef enum motor_cmnd motor_cmnd;
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
@@ -126,34 +133,15 @@ typedef enum motor_cmnd motor_cmnd;
|
||||
RA_DONE.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct local_dset
|
||||
{
|
||||
long number; /*number of support routines*/
|
||||
long (*report) (FILE, int); /*print report*/
|
||||
long (*init) (int); /*init support*/
|
||||
long (*init_record) (void *); /*init support for particular record*/
|
||||
long (*get_ioint_info)
|
||||
(int, struct dbCommon *, IOSCANPVT *); /* get io interrupt information*/
|
||||
};
|
||||
#endif
|
||||
|
||||
/* device support entry table */
|
||||
struct motor_dset
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
struct local_dset base;
|
||||
struct dset base;
|
||||
long (*update_values) (struct motorRecord *);
|
||||
long (*start_trans) (struct motorRecord *);
|
||||
long (*build_trans) (motor_cmnd, double *, struct motorRecord *);
|
||||
RTN_STATUS (*build_trans) (motor_cmnd, double *, struct motorRecord *);
|
||||
long (*end_trans) (struct motorRecord *);
|
||||
#else
|
||||
struct dset base;
|
||||
DEVSUPFUN update_values;
|
||||
DEVSUPFUN start_trans;
|
||||
DEVSUPFUN build_trans;
|
||||
DEVSUPFUN end_trans;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* INCmotorh */
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
FILENAME... motorRecord.c
|
||||
FILENAME... motorRecord.cc
|
||||
USAGE... Motor Record Support.
|
||||
|
||||
Version: $Revision: 1.21 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-11 20:36:07 $
|
||||
Last Modified: $Date: 2002-10-21 21:06:03 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -145,56 +145,34 @@ Last Modified: $Date: 2002-07-11 20:36:07 $
|
||||
* - Seperate +/- limit switch status bits.
|
||||
* - CDIR matches TDIR and RA_DIRECTION.
|
||||
* .43 07-11-02 rls Post all fields when recGblResetAlarms() returns an alarm.
|
||||
* .44 09-17-02 rls Joe Sullivan's port to R3.14.x and OSI.
|
||||
*/
|
||||
|
||||
#define VERSION 4.5
|
||||
#define VERSION 5.1
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wdLib.h>
|
||||
#include <alarm.h>
|
||||
#include <dbDefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <callback.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <recGbl.h>
|
||||
#include <recSup.h>
|
||||
#include <dbEvent.h>
|
||||
}
|
||||
#else
|
||||
#include <callback.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbScan.h>
|
||||
#include <recSup.h>
|
||||
#include <dbEvent.h>
|
||||
#endif
|
||||
|
||||
#include <dbFldTypes.h>
|
||||
#include <devSup.h>
|
||||
#include <errMdef.h>
|
||||
#include <math.h>
|
||||
|
||||
#define GEN_SIZE_OFFSET
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include "motorRecord.h"
|
||||
}
|
||||
#else
|
||||
#include "motorRecord.h"
|
||||
#endif
|
||||
#undef GEN_SIZE_OFFSET
|
||||
|
||||
#include "motor.h"
|
||||
|
||||
|
||||
#define STATIC static
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b)) /* nearest integer */
|
||||
|
||||
/*----------------debugging-----------------*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#define Debug(l, f, args...) {if (l <= motorRecordDebug) printf(f, ## args);}
|
||||
#else
|
||||
@@ -202,14 +180,15 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
volatile int motorRecordDebug = 0;
|
||||
/*----------------debugging-----------------*/
|
||||
|
||||
/*** Forward references ***/
|
||||
|
||||
STATIC long do_work(motorRecord *);
|
||||
STATIC void alarm(motorRecord *);
|
||||
STATIC RTN_STATUS do_work(motorRecord *);
|
||||
STATIC void alarm_sub(motorRecord *);
|
||||
STATIC void monitor(motorRecord *);
|
||||
STATIC void post_MARKed_fields(motorRecord *, unsigned short);
|
||||
STATIC void process_motor_info(motorRecord *, BOOLEAN);
|
||||
STATIC void process_motor_info(motorRecord *, bool);
|
||||
STATIC void load_pos(motorRecord *);
|
||||
STATIC void check_speed_and_resolution(motorRecord *);
|
||||
STATIC void set_dial_highlimit(motorRecord *, struct motor_dset *);
|
||||
@@ -219,45 +198,17 @@ STATIC void range_check(motorRecord *, float *, double, double);
|
||||
|
||||
/*** Record Support Entry Table (RSET) functions. ***/
|
||||
|
||||
STATIC long init_record(motorRecord *, int);
|
||||
STATIC long process(motorRecord *);
|
||||
STATIC long special(struct dbAddr *, int);
|
||||
STATIC long get_units(struct dbAddr *, char *);
|
||||
STATIC long get_precision(struct dbAddr *, long *);
|
||||
STATIC long get_graphic_double(struct dbAddr *, struct dbr_grDouble *);
|
||||
STATIC long get_control_double(struct dbAddr *, struct dbr_ctrlDouble *);
|
||||
STATIC long get_alarm_double(struct dbAddr *, struct dbr_alDouble *);
|
||||
STATIC long init_record(dbCommon *, int);
|
||||
STATIC long process(dbCommon *);
|
||||
STATIC long special(DBADDR *, int);
|
||||
STATIC long get_units(const DBADDR *, char *);
|
||||
STATIC long get_precision(const DBADDR *, long *);
|
||||
STATIC long get_graphic_double(const DBADDR *, struct dbr_grDouble *);
|
||||
STATIC long get_control_double(const DBADDR *, struct dbr_ctrlDouble *);
|
||||
STATIC long get_alarm_double(const DBADDR *, struct dbr_alDouble *);
|
||||
|
||||
/* record support entry table */
|
||||
#ifdef __cplusplus
|
||||
struct local_rset
|
||||
{
|
||||
long number; /*number of support routines*/
|
||||
long (*report) (FILE, int); /*print report*/
|
||||
long (*init) (void); /*init support*/
|
||||
long (*init_record) (void *, int); /*init support for particular record*/
|
||||
long (*process) (void *);
|
||||
long (*special) (struct dbAddr *, int);
|
||||
long (*get_value) (void *, struct valueDes *);
|
||||
long (*cvt_dbaddr) (struct dbAddr *);
|
||||
long (*get_array_info) (struct dbAddr *, long *, long *);
|
||||
long (*put_array_info) (struct dbAddr *, long);
|
||||
long (*get_units) (struct dbAddr *, char *);
|
||||
long (*get_precision) (struct dbAddr *, long *);
|
||||
long (*get_enum_str) (struct dbAddr *, char *);
|
||||
long (*get_enum_strs) (struct dbAddr *, struct dbr_enumStrs *);
|
||||
long (*put_enum_str) (struct dbAddr *, char *);
|
||||
long (*get_graphic_double) (struct dbAddr *, struct dbr_grDouble *);
|
||||
long (*get_control_double) (struct dbAddr *, struct dbr_ctrlDouble *);
|
||||
long (*get_alarm_double) (struct dbAddr *, struct dbr_alDouble *);
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct local_rset motorRSET =
|
||||
#else
|
||||
struct rset motorRSET =
|
||||
#endif
|
||||
{
|
||||
RSETNUMBER,
|
||||
NULL,
|
||||
@@ -442,18 +393,17 @@ calls.
|
||||
|
||||
|
||||
/*
|
||||
The DLY feature uses the VxWorks watchdog facility to issue a callbackRequest()
|
||||
on the structure below. This structure is dynamically allocated by
|
||||
init_record(). init_record() saves the pointer to this structure in the
|
||||
motorRecord. See process() for use of this structure when Done Moving field
|
||||
(DMOV) is TRUE.
|
||||
The DLY feature uses the OSI facility, callbackRequestDelayed(), to issue a
|
||||
callbackRequest() on the structure below. This structure is dynamically
|
||||
allocated by init_record(). init_record() saves the pointer to this structure
|
||||
in the motorRecord. See process() for use of this structure when Done Moving
|
||||
field (DMOV) is TRUE.
|
||||
*/
|
||||
|
||||
struct callback /* DLY feature callback structure. */
|
||||
{
|
||||
CALLBACK callback;
|
||||
struct motorRecord *precord;
|
||||
WDOG_ID wd_id;
|
||||
};
|
||||
|
||||
STATIC void callbackFunc(struct callback * pcb)
|
||||
@@ -509,11 +459,11 @@ LOGIC:
|
||||
...
|
||||
...
|
||||
...
|
||||
Initialize Limit violation field OFF.
|
||||
Initialize Limit violation field false.
|
||||
IF (Software Travel limits are NOT disabled), AND,
|
||||
(Dial readback violates dial high limit), OR,
|
||||
(Dial readback violates dial low limit)
|
||||
Set Limit violation field ON.
|
||||
Set Limit violation field true.
|
||||
ENDIF
|
||||
...
|
||||
Call monitor().
|
||||
@@ -521,12 +471,12 @@ LOGIC:
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
STATIC long init_record(motorRecord * pmr, int pass)
|
||||
STATIC long init_record(dbCommon* arg, int pass)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) arg;
|
||||
struct motor_dset *pdset;
|
||||
long status;
|
||||
struct callback *pcallback; /* v3.2 */
|
||||
const unsigned short monitor_mask = DBE_VALUE;
|
||||
const char errmsg[] = "motor:init_record()";
|
||||
|
||||
if (pass == 0)
|
||||
@@ -559,7 +509,6 @@ STATIC long init_record(motorRecord * pmr, int pass)
|
||||
&pcallback->callback);
|
||||
callbackSetPriority(pmr->prio, &pcallback->callback);
|
||||
pcallback->precord = pmr;
|
||||
pcallback->wd_id = wdCreate();
|
||||
|
||||
/*
|
||||
* Reconcile two different ways of specifying speed and resolution; make
|
||||
@@ -619,7 +568,7 @@ STATIC long init_record(motorRecord * pmr, int pass)
|
||||
MARK(M_ERES);
|
||||
}
|
||||
|
||||
process_motor_info(pmr, ON);
|
||||
process_motor_info(pmr, true);
|
||||
enforceMinRetryDeadband(pmr);
|
||||
|
||||
/*
|
||||
@@ -628,7 +577,7 @@ STATIC long init_record(motorRecord * pmr, int pass)
|
||||
* initialize them to the readback values (.rbv and .drbv) set by our
|
||||
* recent call to process_motor_info().
|
||||
*/
|
||||
if (pmr->omsl != CLOSED_LOOP)
|
||||
if (pmr->omsl != menuOmslclosed_loop)
|
||||
{
|
||||
pmr->val = pmr->rbv;
|
||||
MARK(M_VAL);
|
||||
@@ -666,11 +615,6 @@ STATIC long init_record(motorRecord * pmr, int pass)
|
||||
MARK(M_LVIO);
|
||||
}
|
||||
|
||||
/* Make sure readback-delay field accurately conveys the time delay we */
|
||||
/* can actually implement (nearest number of ticks of watchdog timer.) */
|
||||
pmr->dly = (NINT(vxTicksPerSecond * pmr->dly)) / (float) vxTicksPerSecond;
|
||||
db_post_events(pmr, &pmr->dly, monitor_mask);
|
||||
|
||||
monitor(pmr);
|
||||
return(OK);
|
||||
}
|
||||
@@ -711,9 +655,9 @@ LOGIC:
|
||||
...
|
||||
ELSE IF done with backlash after jog.
|
||||
Clear MIP.
|
||||
IF (JOGF field ON, AND, Hard High limit OFF), OR,
|
||||
(JOGR field ON, AND, Hard Low limit OFF)
|
||||
Set Jog request state ON.
|
||||
IF (JOGF field true, AND, Hard High limit false), OR,
|
||||
(JOGR field true, AND, Hard Low limit false)
|
||||
Set Jog request state true.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
@@ -732,7 +676,7 @@ STATIC long postProcess(motorRecord * pmr)
|
||||
|
||||
pmr->pp = FALSE;
|
||||
|
||||
if (pmr->omsl != CLOSED_LOOP && !(pmr->mip & MIP_MOVE) &&
|
||||
if (pmr->omsl != menuOmslclosed_loop && !(pmr->mip & MIP_MOVE) &&
|
||||
!(pmr->mip & MIP_MOVE_BL))
|
||||
{
|
||||
/* Make drive values agree with readback value. */
|
||||
@@ -1014,23 +958,23 @@ LOGIC:
|
||||
IF this record is being processed by another task (i.e., PACT != 0).
|
||||
NORMAL RETURN.
|
||||
ENDIF
|
||||
Set Processing Active indicator field (PACT) ON.
|
||||
Set Processing Active indicator field (PACT) true.
|
||||
Call device support update_values().
|
||||
IF motor status field (MSTA) was modified.
|
||||
Mark MSTA as changed.
|
||||
ENDIF
|
||||
IF function was invoked by a callback, OR, process delay acknowledged is ON?
|
||||
IF function was invoked by a callback, OR, process delay acknowledged is true?
|
||||
Set process reason indicator to CALLBACK_DATA.
|
||||
Call process_motor_info().
|
||||
IF DMOV is TRUE.
|
||||
GOTO Exit.
|
||||
IF motor-in-motion indicator (MOVN) is ON.
|
||||
IF motor-in-motion indicator (MOVN) is true.
|
||||
IF [Sign of RDIF is NOT the same as sign of CDIR], AND,
|
||||
[Dist. to target {DIFF} > 2 x (|Backlash Dist.| + Retry Deadband)], AND,
|
||||
[MIP indicates this move is either (a result of a retry),OR,
|
||||
(not from a Jog* or Hom*)]
|
||||
Send Stop Motor command.
|
||||
Set STOP indicator in MIP ON.
|
||||
Set STOP indicator in MIP true.
|
||||
Mark MIP as changed.
|
||||
ENDIF
|
||||
ELSE
|
||||
@@ -1043,16 +987,16 @@ LOGIC:
|
||||
ENDIF
|
||||
IF the Done Moving field (DMOV) is TRUE.
|
||||
Initialize delay ticks.
|
||||
IF process delay acknowledged is ON, OR, ticks <= 0.
|
||||
IF process delay acknowledged is true, OR, ticks <= 0.
|
||||
Clear process delay request and ack. indicators in MIP field.
|
||||
Mark MIP as changed.
|
||||
Call maybeRetry().
|
||||
ELSE
|
||||
Set process delay request indicator ON in MIP field.
|
||||
Set process delay request indicator true in MIP field.
|
||||
Mark MIP as changed.
|
||||
Start WatchDog?
|
||||
Set the Done Moving field (DMOV) to FALSE.
|
||||
Set Processing Active indicator field (PACT) OFF.
|
||||
Set Processing Active indicator field (PACT) false.
|
||||
NORMAL RETURN.
|
||||
ENDIF
|
||||
ENDIF
|
||||
@@ -1061,9 +1005,9 @@ LOGIC:
|
||||
IF Software travel limits are disabled.
|
||||
Clear Limit violation field.
|
||||
ELSE
|
||||
IF Jog indicator is ON in MIP field.
|
||||
IF Jog indicator is true in MIP field.
|
||||
Update Limit violation (LVIO) based on Jog direction (JOGF/JOGR) and VELO.
|
||||
ELSE IF Homing indicator is ON in MIP field.
|
||||
ELSE IF Homing indicator is true in MIP field.
|
||||
Update Limit violation (LVIO) based on Home direction (HOMF/HOMR) and VELO.
|
||||
ELSE
|
||||
Update Limit violation (LVIO).
|
||||
@@ -1071,17 +1015,17 @@ LOGIC:
|
||||
ENDIF
|
||||
IF Limit violation (LVIO) has changed.
|
||||
Mark LVIO as changed.
|
||||
IF Limit violation (LVIO) is TRUE, AND, SET is OFF (i.e., Use/Set is Set).
|
||||
Set STOP field ON.
|
||||
IF Limit violation (LVIO) is TRUE, AND, SET is false (i.e., Use/Set is Set).
|
||||
Set STOP field true.
|
||||
Clear JOGF and JOGR fields.
|
||||
ENDIF
|
||||
ENDIF
|
||||
IF STOP field is ON, OR,
|
||||
SPMG field Stop indicator is ON, OR,
|
||||
SPMG field Pause indicator is ON, OR,
|
||||
IF STOP field is true, OR,
|
||||
SPMG field Stop indicator is true, OR,
|
||||
SPMG field Pause indicator is true, OR,
|
||||
function was NOT invoked by a callback, OR,
|
||||
Done Moving field (DMOV) is TRUE, OR,
|
||||
RETRY indicator is ON in MIP field.
|
||||
RETRY indicator is true in MIP field.
|
||||
Call do_work().
|
||||
ENDIF
|
||||
Update Readback output link (RLNK), call dbPutLink().
|
||||
@@ -1090,14 +1034,15 @@ LOGIC:
|
||||
ENDIF
|
||||
Exit:
|
||||
Update record timestamp, call recGblGetTimeStamp().
|
||||
Process alarms, call alarm().
|
||||
Process alarms, call alarm_sub().
|
||||
Monitor changes to record fields, call monitor().
|
||||
Set Processing Active indicator field (PACT) OFF.
|
||||
Set Processing Active indicator field (PACT) false.
|
||||
Exit.
|
||||
|
||||
*******************************************************************************/
|
||||
STATIC long process(motorRecord * pmr)
|
||||
STATIC long process(dbCommon *arg)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) arg;
|
||||
long status = OK, process_reason;
|
||||
int old_lvio = pmr->lvio;
|
||||
unsigned int old_msta = pmr->msta;
|
||||
@@ -1138,7 +1083,7 @@ STATIC long process(motorRecord * pmr)
|
||||
* Get position and status from motor controller. Get readback-link
|
||||
* value if link exists.
|
||||
*/
|
||||
process_motor_info(pmr, OFF);
|
||||
process_motor_info(pmr, false);
|
||||
|
||||
if (pmr->movn)
|
||||
{
|
||||
@@ -1196,9 +1141,7 @@ STATIC long process(motorRecord * pmr)
|
||||
/* Are we "close enough" to desired position? */
|
||||
if (pmr->dmov && !(pmr->rhls || pmr->rlls))
|
||||
{
|
||||
int ticks = (int) NINT(vxTicksPerSecond * pmr->dly);
|
||||
|
||||
if (pmr->mip & MIP_DELAY_ACK || (ticks <= 0))
|
||||
if (pmr->mip & MIP_DELAY_ACK || (pmr->dly <= 0.0))
|
||||
{
|
||||
pmr->mip &= ~MIP_DELAY;
|
||||
MARK(M_MIP);/* done delaying */
|
||||
@@ -1208,8 +1151,9 @@ STATIC long process(motorRecord * pmr)
|
||||
{
|
||||
pmr->mip |= MIP_DELAY_REQ;
|
||||
MARK(M_MIP);
|
||||
status = wdStart(pcallback->wd_id, ticks,
|
||||
(FUNCPTR) callbackRequest, (int) pcallback);
|
||||
|
||||
callbackRequestDelayed(&pcallback->callback, (double) pmr->dly);
|
||||
|
||||
pmr->dmov = FALSE;
|
||||
pmr->pact = 0;
|
||||
return(OK);
|
||||
@@ -1220,7 +1164,7 @@ STATIC long process(motorRecord * pmr)
|
||||
|
||||
/* check for soft-limit violation */
|
||||
if ((pmr->dhlm == pmr->dllm) && (pmr->dllm == (float) 0.0))
|
||||
pmr->lvio = OFF;
|
||||
pmr->lvio = false;
|
||||
else
|
||||
{
|
||||
if (pmr->mip & MIP_JOG)
|
||||
@@ -1261,7 +1205,7 @@ STATIC long process(motorRecord * pmr)
|
||||
process_exit:
|
||||
/*** We're done. Report the current state of the motor. ***/
|
||||
recGblGetTimeStamp(pmr);
|
||||
alarm(pmr); /* If we've violated alarm limits, yell. */
|
||||
alarm_sub(pmr); /* If we've violated alarm limits, yell. */
|
||||
monitor(pmr); /* If values have changed, broadcast them. */
|
||||
pmr->pact = 0;
|
||||
Debug(4, "process:---------------------- end; motor \"%s\"\n", pmr->name);
|
||||
@@ -1352,7 +1296,7 @@ LOGIC:
|
||||
IF MSTA indicates an encoder is present.
|
||||
Send the ticks/steps ratio motor command.
|
||||
ENDIF
|
||||
IF the SET position field is ON.
|
||||
IF the SET position field is true.
|
||||
Set the PP field TRUE and send the update info. motor command.
|
||||
ELSE
|
||||
- call load_pos().
|
||||
@@ -1378,7 +1322,7 @@ LOGIC:
|
||||
IF (Software Travel limits are NOT disabled), AND,
|
||||
(Home Forward, AND, (DVAL > DHLM - VELO)), OR,
|
||||
(Home Reverse, AND, (DVAL < DLLM + VELO)))
|
||||
Set Limit violation field ON.
|
||||
Set Limit violation field true.
|
||||
NORMAL RETURN.
|
||||
ENDIF
|
||||
...
|
||||
@@ -1386,18 +1330,18 @@ LOGIC:
|
||||
NORMAL RETURN.
|
||||
ENDIF
|
||||
IF NOT currently jogging, AND, NOT (STOPPED, OR, PAUSED), AND,
|
||||
No Limit violation, AND, Jog Request is ON.
|
||||
No Limit violation, AND, Jog Request is true.
|
||||
IF (Forward jog, AND, DVAL > [DHLM - VELO]), OR,
|
||||
(Reverse jog, AND, DVAL > [DLLM + VELO])
|
||||
Set limit violation (LVIO) ON.
|
||||
Set limit violation (LVIO) true.
|
||||
NORMAL RETURN.
|
||||
ENDIF
|
||||
Set Jogging [forward/reverse] state ON.
|
||||
Set Jogging [forward/reverse] state true.
|
||||
...
|
||||
...
|
||||
NORMAL RETURN
|
||||
ENDIF
|
||||
IF Jog request is OFF, AND, jog is active.
|
||||
IF Jog request is false, AND, jog is active.
|
||||
Set post process TRUE.
|
||||
Send STOP_AXIS message to controller.
|
||||
ELSE IF process jog stop or backlash.
|
||||
@@ -1408,15 +1352,15 @@ LOGIC:
|
||||
|
||||
IF VAL field has changed.
|
||||
Mark VAL changed.
|
||||
IF the SET position field is ON, AND, the FOFF field is "Variable".
|
||||
IF the SET position field is true, AND, the FOFF field is "Variable".
|
||||
....
|
||||
ELSE
|
||||
Calculate DVAL based on VAL, OFF and DIR.
|
||||
Calculate DVAL based on VAL, false and DIR.
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
IF Software travel limits are disabled.
|
||||
Set LVIO OFF.
|
||||
Set LVIO false.
|
||||
ELSE
|
||||
Update LVIO field.
|
||||
ENDIF
|
||||
@@ -1439,7 +1383,7 @@ LOGIC:
|
||||
IF DVAL field has changed, OR, NOT done moving.
|
||||
Mark DVAL as changed.
|
||||
Calculate new DIFF and RDIF fields and mark as changed.
|
||||
IF the SET position field is ON.
|
||||
IF the SET position field is true.
|
||||
Load new raw motor position w/out moving it - call load_pos().
|
||||
NORMAL RETURN.
|
||||
ELSE
|
||||
@@ -1447,9 +1391,9 @@ LOGIC:
|
||||
|
||||
IF (UEIP set to YES, AND, MSTA indicates an encoder is present),
|
||||
OR, ReadbackLink is in use (URIP).
|
||||
Set "use relative move" indicator (use_rel) to ON.
|
||||
Set "use relative move" indicator (use_rel) to true.
|
||||
ELSE
|
||||
Set "use relative move" indicator (use_rel) to OFF.
|
||||
Set "use relative move" indicator (use_rel) to false.
|
||||
ENDIF
|
||||
|
||||
IF new raw commanded position = current raw feedback position.
|
||||
@@ -1472,7 +1416,7 @@ LOGIC:
|
||||
ENDIF
|
||||
....
|
||||
....
|
||||
IF motion in progress indicator is OFF.
|
||||
IF motion in progress indicator is false.
|
||||
Set MIP MOVE indicator ON.
|
||||
.....
|
||||
.....
|
||||
@@ -1486,14 +1430,14 @@ LOGIC:
|
||||
|
||||
|
||||
*******************************************************************************/
|
||||
STATIC long do_work(motorRecord * pmr)
|
||||
STATIC RTN_STATUS do_work(motorRecord * pmr)
|
||||
{
|
||||
struct motor_dset *pdset = (struct motor_dset *) (pmr->dset);
|
||||
int dir_positive = (pmr->dir == motorDIR_Pos);
|
||||
int dir = dir_positive ? 1 : -1;
|
||||
int set = pmr->set;
|
||||
BOOLEAN stop_or_pause = (pmr->spmg == motorSPMG_Stop ||
|
||||
pmr->spmg == motorSPMG_Pause) ? ON : OFF;
|
||||
bool stop_or_pause = (pmr->spmg == motorSPMG_Stop ||
|
||||
pmr->spmg == motorSPMG_Pause) ? true : false;
|
||||
int old_lvio = pmr->lvio;
|
||||
const unsigned short monitor_mask = DBE_VALUE;
|
||||
mmap_field mmap_bits;
|
||||
@@ -1523,20 +1467,20 @@ STATIC long do_work(motorRecord * pmr)
|
||||
*/
|
||||
if (pmr->spmg != pmr->lspg || pmr->stop != 0)
|
||||
{
|
||||
BOOLEAN stop = (pmr->stop != 0) ? ON : OFF;
|
||||
bool stop = (pmr->stop != 0) ? true : false;
|
||||
|
||||
if (pmr->spmg != pmr->lspg)
|
||||
pmr->lspg = pmr->spmg;
|
||||
else
|
||||
pmr->stop = 0;
|
||||
|
||||
if (stop_or_pause == ON || stop == ON)
|
||||
if (stop_or_pause == true || stop == true)
|
||||
{
|
||||
/*
|
||||
* If STOP, make drive values agree with readback values (when the
|
||||
* motor actually stops).
|
||||
*/
|
||||
if (pmr->spmg == motorSPMG_Stop || stop == ON)
|
||||
if (pmr->spmg == motorSPMG_Stop || stop == true)
|
||||
{
|
||||
if (pmr->mip == MIP_DONE || pmr->mip == MIP_STOP || pmr->mip == MIP_RETRY)
|
||||
{
|
||||
@@ -1678,7 +1622,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
return(OK);
|
||||
}
|
||||
/*** Collect .val (User value) changes from all sources. ***/
|
||||
if (pmr->omsl == CLOSED_LOOP && pmr->dol.type == DB_LINK)
|
||||
if (pmr->omsl == menuOmslclosed_loop && pmr->dol.type == DB_LINK)
|
||||
{
|
||||
/** If we're in CLOSED_LOOP mode, get value from input link. **/
|
||||
long status;
|
||||
@@ -1701,7 +1645,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
((pmr->homf && !(pmr->mip & MIP_HOMF) && !pmr->hls) ||
|
||||
(pmr->homr && !(pmr->mip & MIP_HOMR) && !pmr->lls)))
|
||||
{
|
||||
if (stop_or_pause == ON)
|
||||
if (stop_or_pause == true)
|
||||
{
|
||||
pmr->dmov = FALSE;
|
||||
MARK(M_DMOV);
|
||||
@@ -1765,7 +1709,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
* Jog motor. Move continuously until we hit a software limit or a
|
||||
* limit switch, or until user releases button.
|
||||
*/
|
||||
if (!(pmr->mip & MIP_JOG) && stop_or_pause == OFF && !pmr->lvio &&
|
||||
if (!(pmr->mip & MIP_JOG) && stop_or_pause == false && !pmr->lvio &&
|
||||
(pmr->mip & MIP_JOG_REQ))
|
||||
{
|
||||
/* check for limit violation */
|
||||
@@ -1901,7 +1845,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
|
||||
/* Record limit violation */
|
||||
if ((pmr->dhlm == pmr->dllm) && (pmr->dllm == (float) 0.0))
|
||||
pmr->lvio = OFF;
|
||||
pmr->lvio = false;
|
||||
else
|
||||
pmr->lvio = (pmr->dval > pmr->dhlm) ||
|
||||
(pmr->dval > pmr->dhlm + pmr->bdst) ||
|
||||
@@ -1926,7 +1870,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
return(OK);
|
||||
}
|
||||
|
||||
if (stop_or_pause == ON)
|
||||
if (stop_or_pause == true)
|
||||
return(OK);
|
||||
|
||||
/* IF DVAL field has changed, OR, NOT done moving. */
|
||||
@@ -1962,7 +1906,7 @@ STATIC long do_work(motorRecord * pmr)
|
||||
double bvel = pmr->bvel / fabs(pmr->mres); /* backlash speed */
|
||||
double bacc = bvel / pmr->bacc; /* backlash accel. */
|
||||
double slop = 0.95 * pmr->rdbd;
|
||||
BOOLEAN use_rel;
|
||||
bool use_rel;
|
||||
double dMdR = pmr->mres / pmr->mres;
|
||||
double relpos = pmr->diff / pmr->mres;
|
||||
double relbpos = ((pmr->dval - pmr->bdst) - pmr->drbv) / pmr->mres;
|
||||
@@ -1978,9 +1922,9 @@ STATIC long do_work(motorRecord * pmr)
|
||||
|
||||
/*** Use if encoder or ReadbackLink is in use. ***/
|
||||
if (((pmr->msta & EA_PRESENT) && pmr->ueip) || pmr->urip)
|
||||
use_rel = ON;
|
||||
use_rel = true;
|
||||
else
|
||||
use_rel = OFF;
|
||||
use_rel = false;
|
||||
|
||||
rpos = NINT(rbvpos);
|
||||
npos = NINT(newpos);
|
||||
@@ -2022,15 +1966,18 @@ STATIC long do_work(motorRecord * pmr)
|
||||
*/
|
||||
if (fabs(pmr->diff) < slop)
|
||||
{
|
||||
if (((use_rel == OFF) && ((newpos > currpos) != (pmr->bdst > 0))) ||
|
||||
((use_rel == ON) && ((mRelPos > 0) != (pmr->bdst > 0))))
|
||||
if (((use_rel == false) && ((newpos > currpos) != (pmr->bdst > 0))) ||
|
||||
((use_rel == true) && ((mRelPos > 0) != (pmr->bdst > 0))))
|
||||
{
|
||||
pmr->ldvl = pmr->dval;
|
||||
pmr->lval = pmr->val;
|
||||
pmr->lrvl = pmr->rval;
|
||||
|
||||
pmr->dmov = TRUE;
|
||||
MARK(M_DMOV);
|
||||
if (pmr->mip == MIP_DONE)
|
||||
{
|
||||
pmr->ldvl = pmr->dval;
|
||||
pmr->lval = pmr->val;
|
||||
pmr->lrvl = pmr->rval;
|
||||
|
||||
pmr->dmov = TRUE;
|
||||
MARK(M_DMOV);
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
}
|
||||
@@ -2137,17 +2084,17 @@ STATIC long do_work(motorRecord * pmr)
|
||||
/******************************************************************************
|
||||
special()
|
||||
*******************************************************************************/
|
||||
STATIC long special(struct dbAddr * paddr, int after)
|
||||
STATIC long special(DBADDR *paddr, int after)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
struct motor_dset *pdset = (struct motor_dset *) (pmr->dset);
|
||||
const unsigned short monitor_mask = DBE_VALUE;
|
||||
int dir_positive = (pmr->dir == motorDIR_Pos);
|
||||
int dir = dir_positive ? 1 : -1;
|
||||
BOOLEAN changed = OFF;
|
||||
bool changed = false;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
double offset, tmp_raw, tmp_limit, fabs_urev;
|
||||
long rtnval;
|
||||
RTN_STATUS rtnval;
|
||||
motor_cmnd command;
|
||||
double temp_dbl;
|
||||
float *temp_flt;
|
||||
@@ -2436,14 +2383,14 @@ STATIC long special(struct dbAddr * paddr, int after)
|
||||
if (pmr->frac < 0.1)
|
||||
{
|
||||
pmr->frac = 0.1;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
if (pmr->frac > 1.5)
|
||||
{
|
||||
pmr->frac = 1.5;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
if (changed == ON)
|
||||
if (changed == true)
|
||||
db_post_events(pmr, &pmr->frac, monitor_mask);
|
||||
break;
|
||||
|
||||
@@ -2549,15 +2496,6 @@ velcheckB:
|
||||
db_post_events(pmr, &pmr->foff, DBE_VALUE);
|
||||
break;
|
||||
|
||||
/*
|
||||
* New readback-delay time time. Show effect of roundoff to 60-Hz
|
||||
* clock.
|
||||
*/
|
||||
case motorRecordDLY:
|
||||
pmr->dly = (NINT(vxTicksPerSecond * pmr->dly)) / (float) vxTicksPerSecond;
|
||||
db_post_events(pmr, &pmr->dly, monitor_mask);
|
||||
break;
|
||||
|
||||
/* New backlash distance. Make sure retry deadband is achievable. */
|
||||
case motorRecordBDST:
|
||||
enforceMinRetryDeadband(pmr);
|
||||
@@ -2580,12 +2518,12 @@ pidcof:
|
||||
if (*temp_flt < 0.0) /* Validity check; 0.0 <= gain <= 1.0 */
|
||||
{
|
||||
*temp_flt = 0.0;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
else if (*temp_flt > 1.0)
|
||||
{
|
||||
*temp_flt = 1.0;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
temp_dbl = *temp_flt;
|
||||
@@ -2595,7 +2533,7 @@ pidcof:
|
||||
/* If an error occured, build_trans() has reset the gain
|
||||
* parameter to a valid value for this controller. */
|
||||
if (rtnval != OK)
|
||||
changed = ON;
|
||||
changed = true;
|
||||
|
||||
SEND_MSG();
|
||||
if (changed == 1)
|
||||
@@ -2703,7 +2641,7 @@ velcheckA:
|
||||
/******************************************************************************
|
||||
get_units()
|
||||
*******************************************************************************/
|
||||
STATIC long get_units(struct dbAddr * paddr, char *units)
|
||||
STATIC long get_units(const DBADDR *paddr, char *units)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
int siz = dbr_units_size - 1; /* "dbr_units_size" from dbAccess.h */
|
||||
@@ -2752,7 +2690,7 @@ STATIC long get_units(struct dbAddr * paddr, char *units)
|
||||
/******************************************************************************
|
||||
get_graphic_double()
|
||||
*******************************************************************************/
|
||||
STATIC long get_graphic_double(struct dbAddr * paddr, struct dbr_grDouble * pgd)
|
||||
STATIC long get_graphic_double(const DBADDR *paddr, struct dbr_grDouble * pgd)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
@@ -2787,7 +2725,7 @@ STATIC long get_graphic_double(struct dbAddr * paddr, struct dbr_grDouble * pgd)
|
||||
break;
|
||||
|
||||
default:
|
||||
recGblGetGraphicDouble(paddr, pgd);
|
||||
recGblGetGraphicDouble((dbAddr *) paddr, pgd);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2798,7 +2736,7 @@ STATIC long get_graphic_double(struct dbAddr * paddr, struct dbr_grDouble * pgd)
|
||||
get_control_double()
|
||||
*******************************************************************************/
|
||||
STATIC long
|
||||
get_control_double(struct dbAddr * paddr, struct dbr_ctrlDouble * pcd)
|
||||
get_control_double(const DBADDR *paddr, struct dbr_ctrlDouble * pcd)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
@@ -2833,7 +2771,7 @@ STATIC long
|
||||
break;
|
||||
|
||||
default:
|
||||
recGblGetControlDouble(paddr, pcd);
|
||||
recGblGetControlDouble((dbAddr *) paddr, pcd);
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
@@ -2842,7 +2780,7 @@ STATIC long
|
||||
/******************************************************************************
|
||||
get_precision()
|
||||
*******************************************************************************/
|
||||
STATIC long get_precision(struct dbAddr * paddr, long *precision)
|
||||
STATIC long get_precision(const DBADDR *paddr, long *precision)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
@@ -2862,7 +2800,7 @@ STATIC long get_precision(struct dbAddr * paddr, long *precision)
|
||||
break;
|
||||
|
||||
default:
|
||||
recGblGetPrec(paddr, precision);
|
||||
recGblGetPrec((dbAddr *) paddr, precision);
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
@@ -2873,7 +2811,7 @@ STATIC long get_precision(struct dbAddr * paddr, long *precision)
|
||||
/******************************************************************************
|
||||
get_alarm_double()
|
||||
*******************************************************************************/
|
||||
STATIC long get_alarm_double(struct dbAddr * paddr, struct dbr_alDouble * pad)
|
||||
STATIC long get_alarm_double(const DBADDR *paddr, struct dbr_alDouble * pad)
|
||||
{
|
||||
motorRecord *pmr = (motorRecord *) paddr->precord;
|
||||
int fieldIndex = dbGetFieldIndex(paddr);
|
||||
@@ -2887,38 +2825,38 @@ STATIC long get_alarm_double(struct dbAddr * paddr, struct dbr_alDouble * pad)
|
||||
}
|
||||
else
|
||||
{
|
||||
recGblGetAlarmDouble(paddr, pad);
|
||||
recGblGetAlarmDouble((dbAddr *) paddr, pad);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
alarm()
|
||||
alarm_sub()
|
||||
*******************************************************************************/
|
||||
STATIC void alarm(motorRecord * pmr)
|
||||
STATIC void alarm_sub(motorRecord * pmr)
|
||||
{
|
||||
if (pmr->udf == TRUE)
|
||||
{
|
||||
recGblSetSevr(pmr, UDF_ALARM, INVALID_ALARM);
|
||||
recGblSetSevr((dbCommon *) pmr, UDF_ALARM, INVALID_ALARM);
|
||||
return;
|
||||
}
|
||||
/* limit-switch and soft-limit violations */
|
||||
if (pmr->hlsv && (pmr->hls || (pmr->dval > pmr->dhlm)))
|
||||
{
|
||||
recGblSetSevr(pmr, HIGH_ALARM, pmr->hlsv);
|
||||
recGblSetSevr((dbCommon *) pmr, HIGH_ALARM, pmr->hlsv);
|
||||
return;
|
||||
}
|
||||
if (pmr->hlsv && (pmr->lls || (pmr->dval < pmr->dllm)))
|
||||
{
|
||||
recGblSetSevr(pmr, LOW_ALARM, pmr->hlsv);
|
||||
recGblSetSevr((dbCommon *) pmr, LOW_ALARM, pmr->hlsv);
|
||||
return;
|
||||
}
|
||||
if ((pmr->msta & CNTRL_COMM_ERR) != 0)
|
||||
{
|
||||
pmr->msta &= ~CNTRL_COMM_ERR;
|
||||
MARK(M_MSTA);
|
||||
recGblSetSevr(pmr, COMM_ALARM, INVALID_ALARM);
|
||||
recGblSetSevr((dbCommon *) pmr, COMM_ALARM, INVALID_ALARM);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -2933,16 +2871,6 @@ STATIC void monitor(motorRecord * pmr)
|
||||
|
||||
monitor_mask = recGblResetAlarms(pmr);
|
||||
|
||||
/*
|
||||
* Mark .val, .dval changes, and save old values for backlash correction.
|
||||
*/
|
||||
if (pmr->val != pmr->lval)
|
||||
MARK(M_VAL);
|
||||
if (pmr->dval != pmr->ldvl)
|
||||
MARK(M_DVAL);
|
||||
if (pmr->rval != pmr->lrvl)
|
||||
MARK(M_RVAL);
|
||||
|
||||
/* Catch all previous 'calls' to MARK(). */
|
||||
post_MARKed_fields(pmr, monitor_mask);
|
||||
return;
|
||||
@@ -3117,7 +3045,7 @@ STATIC void post_MARKed_fields(motorRecord * pmr, unsigned short mask)
|
||||
process_motor_info()
|
||||
*******************************************************************************/
|
||||
STATIC void
|
||||
process_motor_info(motorRecord * pmr, BOOLEAN initcall)
|
||||
process_motor_info(motorRecord * pmr, bool initcall)
|
||||
{
|
||||
unsigned long status = pmr->msta;
|
||||
double old_drbv = pmr->drbv;
|
||||
@@ -3129,7 +3057,7 @@ STATIC void
|
||||
short old_lls = pmr->lls;
|
||||
short old_athm = pmr->athm;
|
||||
int dir = (pmr->dir == motorDIR_Pos) ? 1 : -1;
|
||||
BOOLEAN ls_active;
|
||||
bool ls_active;
|
||||
|
||||
/*** Process record fields. ***/
|
||||
|
||||
@@ -3167,7 +3095,7 @@ STATIC void
|
||||
pmr->rhls = (status & RA_PLUS_LS) && pmr->cdir;
|
||||
pmr->rlls = (status & RA_MINUS_LS) && !pmr->cdir;
|
||||
|
||||
ls_active = (pmr->rhls || pmr->rlls) ? ON : OFF;
|
||||
ls_active = (pmr->rhls || pmr->rlls) ? true : false;
|
||||
|
||||
pmr->hls = ((pmr->dir == motorDIR_Pos) == (pmr->mres >= 0)) ? pmr->rhls : pmr->rlls;
|
||||
pmr->lls = ((pmr->dir == motorDIR_Pos) == (pmr->mres >= 0)) ? pmr->rlls : pmr->rhls;
|
||||
@@ -3177,7 +3105,7 @@ STATIC void
|
||||
MARK(M_LLS);
|
||||
|
||||
/* Get motor-now-moving indicator. */
|
||||
if (ls_active == ON || (status & (RA_DONE | RA_PROBLEM)))
|
||||
if (ls_active == true || (status & (RA_DONE | RA_PROBLEM)))
|
||||
pmr->movn = 0;
|
||||
else
|
||||
pmr->movn = 1;
|
||||
@@ -3200,7 +3128,7 @@ STATIC void
|
||||
* have been read and propagated to .rbv in case .rdbl is a link involving
|
||||
* that field.
|
||||
*/
|
||||
if (pmr->urip && initcall == OFF)
|
||||
if (pmr->urip && initcall == false)
|
||||
{
|
||||
long status;
|
||||
|
||||
@@ -3452,7 +3380,7 @@ STATIC void set_dial_highlimit(motorRecord *pmr, struct motor_dset *pdset)
|
||||
{
|
||||
int dir_positive = (pmr->dir == motorDIR_Pos);
|
||||
double offset, tmp_raw;
|
||||
long rtnval;
|
||||
RTN_STATUS rtnval;
|
||||
|
||||
tmp_raw = pmr->dhlm / pmr->mres;
|
||||
INIT_MSG();
|
||||
@@ -3486,7 +3414,7 @@ STATIC void set_dial_lowlimit(motorRecord *pmr, struct motor_dset *pdset)
|
||||
{
|
||||
int dir_positive = (pmr->dir == motorDIR_Pos);
|
||||
double offset, tmp_raw;
|
||||
long rtnval;
|
||||
RTN_STATUS rtnval;
|
||||
|
||||
tmp_raw = pmr->dllm / pmr->mres;
|
||||
|
||||
@@ -3540,21 +3468,21 @@ INPUT... parm - pointer to parameter to be range check.
|
||||
STATIC void range_check(motorRecord *pmr, float *parm_ptr, double min, double max)
|
||||
{
|
||||
const unsigned short monitor_mask = DBE_VALUE;
|
||||
BOOLEAN changed = OFF;
|
||||
bool changed = false;
|
||||
double parm_val = *parm_ptr;
|
||||
|
||||
if (parm_val < min)
|
||||
{
|
||||
parm_val = min;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
if (max != 0.0 && parm_val > max)
|
||||
{
|
||||
parm_val = max;
|
||||
changed = ON;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed == ON)
|
||||
if (changed == true)
|
||||
{
|
||||
*parm_ptr = parm_val;
|
||||
db_post_events(pmr, parm_ptr, monitor_mask);
|
||||
@@ -3,9 +3,9 @@ FILENAME: motordevCom.c
|
||||
USAGE... This file contains device functions that are common to all motor
|
||||
record device support modules.
|
||||
|
||||
Version: $Revision: 1.7 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 18:52:58 $
|
||||
Last Modified: $Date: 2002-10-21 21:06:04 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -44,23 +44,14 @@ Last Modified: $Date: 2002-07-05 18:52:58 $
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <callback.h>
|
||||
#include <fast_lock.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <dbAccess.h>
|
||||
#include <recGbl.h>
|
||||
#include <recSup.h>
|
||||
#include <dbEvent.h>
|
||||
}
|
||||
#else
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#include <dbEvent.h>
|
||||
#endif
|
||||
#include <devSup.h>
|
||||
|
||||
#include "motorRecord.h"
|
||||
@@ -104,7 +95,7 @@ long motor_init_com(int after, int brdcnt, struct driver_table *tabptr,
|
||||
card_query.total_axis * sizeof(struct axis_stat));
|
||||
|
||||
for (motor = 0; motor < card_query.total_axis; motor++)
|
||||
brdptr->axis_stat[motor].in_use = OFF;
|
||||
brdptr->axis_stat[motor].in_use = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,19 +119,19 @@ LOGIC...
|
||||
...
|
||||
Error check "card" index, "signal" index and motor "in_use" indicator.
|
||||
IF error detected.
|
||||
Set the MSTA PROBLEM bit ON.
|
||||
Set the MSTA PROBLEM bit true.
|
||||
Set RMP <- REP <- 0.
|
||||
ERROR RETURN.
|
||||
ENDIF
|
||||
|
||||
Get motor information - call get_axis_info() via driver table.
|
||||
Update MSTA.
|
||||
Set axis assigned to a motor record indicator ON.
|
||||
Set axis assigned to a motor record indicator true.
|
||||
|
||||
Set Initialize encoder indicator based on (MSTA indicates an encoder is
|
||||
present, AND, UEIP set to YES).
|
||||
|
||||
IF Initialize encoder indicator is ON.
|
||||
IF Initialize encoder indicator is true.
|
||||
...
|
||||
...
|
||||
ELSE
|
||||
@@ -153,14 +144,14 @@ LOGIC...
|
||||
Set Command Primitive Initialization string indicator based on (non-NULL "init"
|
||||
pointer, AND, non-zero string length.
|
||||
|
||||
IF (Initialize position, OR, encoder, OR, string indicators are ON)
|
||||
IF (Initialize position, OR, encoder, OR, string indicators are true)
|
||||
Create initialization semaphore.
|
||||
...
|
||||
...
|
||||
IF Initialize encoder indicator is ON.
|
||||
IF Initialize encoder indicator is true.
|
||||
Send Set Encoder Ratio command to controller.
|
||||
ENDIF
|
||||
IF Initialize position indicator is ON.
|
||||
IF Initialize position indicator is true.
|
||||
Send Load Position command to controller.
|
||||
ENDIF
|
||||
IF Command Primitive Initialization string present.
|
||||
@@ -183,7 +174,7 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
struct motor_dset *pdset = (struct motor_dset *) (mr->dset);
|
||||
struct board_stat *brdptr;
|
||||
int card, signal;
|
||||
BOOLEAN initEncoder, initPos, initString;
|
||||
bool initEncoder, initPos, initString;
|
||||
struct motor_trans *ptrans;
|
||||
MOTOR_AXIS_QUERY axis_query;
|
||||
struct mess_node *motor_call;
|
||||
@@ -198,9 +189,11 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
ptrans->state = IDLE_STATE;
|
||||
ptrans->callback_changed = NO;
|
||||
ptrans->tabptr = tabptr;
|
||||
ptrans->dpm = OFF;
|
||||
ptrans->dpm = false;
|
||||
|
||||
FASTLOCKINIT(&ptrans->lock);
|
||||
/* Semaphore on private to record field data transfers */
|
||||
ptrans->lock = new epicsEvent(epicsEventFull);
|
||||
|
||||
motor_call = &(ptrans->motor_call);
|
||||
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) motor_callback,
|
||||
@@ -251,7 +244,7 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
/* query motor for all info to fill into record */
|
||||
(tabptr->get_axis_info) (card, signal, &axis_query, tabptr);
|
||||
mr->msta = axis_query.status; /* status info */
|
||||
brdptr->axis_stat[signal].in_use = ON;
|
||||
brdptr->axis_stat[signal].in_use = true;
|
||||
|
||||
/*jps: setting the encoder ratio was moved from init_record() remove callbacks during iocInit */
|
||||
/*
|
||||
@@ -260,8 +253,8 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
* per engineering unit (EGU). Send an array containing this information
|
||||
* to device support.
|
||||
*/
|
||||
initEncoder = ((mr->msta & EA_PRESENT) && mr->ueip) ? ON : OFF;
|
||||
if (initEncoder == ON)
|
||||
initEncoder = ((mr->msta & EA_PRESENT) && mr->ueip) ? true : false;
|
||||
if (initEncoder == true)
|
||||
{
|
||||
if (fabs(mr->mres) < 1.e-9)
|
||||
mr->mres = 1.;
|
||||
@@ -281,27 +274,27 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
ep_mp[1] = 1.;
|
||||
}
|
||||
|
||||
initPos = (mr->dval != 0 && mr->mres != 0 && axis_query.position == 0) ? ON : OFF;
|
||||
initPos = (mr->dval != 0 && mr->mres != 0 && axis_query.position == 0) ? true : false;
|
||||
/* Test for command primitive initialization string. */
|
||||
initString = (mr->init != NULL && strlen(mr->init)) ? ON : OFF;
|
||||
initString = (mr->init != NULL && strlen(mr->init)) ? true : false;
|
||||
|
||||
/* Program the device if an encoder is present */
|
||||
if (initPos == ON || initEncoder == ON || initString == ON)
|
||||
if (initPos == true || initEncoder == true || initString == true)
|
||||
{
|
||||
/* Semaphore used to hold initialization until device is programmed - cleared by callback. */
|
||||
ptrans->initSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
|
||||
ptrans->initSem = new epicsEvent(epicsEventEmpty);
|
||||
|
||||
/* Switch to special init callback so that record will not be processed during iocInit. */
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) motor_init_callback,
|
||||
&(motor_call->callback));
|
||||
if (initEncoder == ON)
|
||||
if (initEncoder == true)
|
||||
{
|
||||
(*pdset->start_trans)(mr);
|
||||
(*pdset->build_trans)(SET_ENC_RATIO, ep_mp, mr);
|
||||
(*pdset->end_trans)(mr);
|
||||
}
|
||||
|
||||
if (initPos == ON)
|
||||
if (initPos == true)
|
||||
{
|
||||
double setPos = mr->dval / mr->mres;
|
||||
|
||||
@@ -310,7 +303,7 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
(*pdset->end_trans)(mr);
|
||||
}
|
||||
|
||||
if (initString == ON)
|
||||
if (initString == true)
|
||||
{
|
||||
(*pdset->start_trans)(mr);
|
||||
(*pdset->build_trans)(PRIMITIVE, NULL, mr);
|
||||
@@ -323,10 +316,10 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
(*pdset->end_trans)(mr);
|
||||
|
||||
/* Wait for callback w/timeout */
|
||||
if ((rtnStat = semTake(ptrans->initSem, SEM_TIMEOUT)) == ERROR)
|
||||
if (ptrans->initSem->wait(1.0) == FALSE)
|
||||
recGblRecordError(S_dev_NoInit, (void *) mr,
|
||||
(char *) "dev_NoInit (init_record_com: callback2 timeout");
|
||||
semDelete(ptrans->initSem);
|
||||
delete(ptrans->initSem);
|
||||
|
||||
/* Restore regular record callback */
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) motor_callback,
|
||||
@@ -340,7 +333,7 @@ long motor_init_record_com(struct motorRecord *mr, int brdcnt, struct driver_tab
|
||||
mr->rmp = axis_query.position; /* raw motor pulse count */
|
||||
mr->rep = axis_query.encoder_position; /* raw encoder pulse count */
|
||||
mr->msta = axis_query.status; /* status info */
|
||||
return(OK);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -361,7 +354,7 @@ long motor_update_values(struct motorRecord * mr)
|
||||
rc = NOTHING_DONE;
|
||||
ptrans = (struct motor_trans *) mr->dpvt;
|
||||
|
||||
FASTLOCK(&ptrans->lock);
|
||||
ptrans->lock->wait();
|
||||
|
||||
/* raw motor pulse count */
|
||||
if (ptrans->callback_changed == YES)
|
||||
@@ -373,7 +366,10 @@ long motor_update_values(struct motorRecord * mr)
|
||||
ptrans->callback_changed = NO;
|
||||
rc = CALLBACK_DATA;
|
||||
}
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
|
||||
/* load event for next transfer */
|
||||
ptrans->lock->signal();
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
@@ -424,7 +420,7 @@ long motor_end_trans_com(struct motorRecord *mr, struct driver_table *tabptr)
|
||||
struct mess_node *motor_call;
|
||||
long rc;
|
||||
|
||||
rc = OK;
|
||||
rc = 0;
|
||||
motor_call = &(trans->motor_call);
|
||||
if ((*trans->tabptr->card_array)[motor_call->card] == NULL)
|
||||
{
|
||||
@@ -434,7 +430,7 @@ long motor_end_trans_com(struct motorRecord *mr, struct driver_table *tabptr)
|
||||
mr->dmov = TRUE;
|
||||
db_post_events(mr, &mr->dmov, DBE_VALUE);
|
||||
mr->msta |= CNTRL_COMM_ERR;
|
||||
return(rc = ERROR);
|
||||
return(rc = -1);
|
||||
}
|
||||
|
||||
switch (trans->state)
|
||||
@@ -447,7 +443,7 @@ long motor_end_trans_com(struct motorRecord *mr, struct driver_table *tabptr)
|
||||
|
||||
case IDLE_STATE:
|
||||
default:
|
||||
rc = ERROR;
|
||||
rc = -1;
|
||||
}
|
||||
return (rc);
|
||||
}
|
||||
@@ -462,11 +458,11 @@ NOTES... This function MUST BE reentrant.
|
||||
static void motor_callback(struct mess_node * motor_return)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) motor_return->mrecord;
|
||||
struct rset *prset = (struct rset *) (motor_return->mrecord->rset);
|
||||
struct motor_trans *ptrans;
|
||||
|
||||
ptrans = (struct motor_trans *) mr->dpvt;
|
||||
FASTLOCK(&ptrans->lock);
|
||||
|
||||
ptrans->lock->wait();
|
||||
|
||||
ptrans->callback_changed = YES;
|
||||
ptrans->motor_pos = motor_return->position;
|
||||
@@ -474,7 +470,8 @@ static void motor_callback(struct mess_node * motor_return)
|
||||
ptrans->vel = motor_return->velocity;
|
||||
ptrans->status = motor_return->status;
|
||||
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
/* load event for next transfer */
|
||||
ptrans->lock->signal();
|
||||
|
||||
/* free the return data buffer */
|
||||
(ptrans->tabptr->free) (motor_return, ptrans->tabptr);
|
||||
@@ -493,7 +490,8 @@ static void motor_init_callback(struct mess_node * motor_return)
|
||||
struct motor_trans *ptrans;
|
||||
|
||||
ptrans = (struct motor_trans *) mr->dpvt;
|
||||
FASTLOCK(&ptrans->lock);
|
||||
|
||||
ptrans->lock->wait();
|
||||
|
||||
ptrans->callback_changed = YES;
|
||||
ptrans->motor_pos = motor_return->position;
|
||||
@@ -503,9 +501,10 @@ static void motor_init_callback(struct mess_node * motor_return)
|
||||
|
||||
/* free the return data buffer */
|
||||
(ptrans->tabptr->free) (motor_return, ptrans->tabptr);
|
||||
semGive(ptrans->initSem);
|
||||
ptrans->initSem->signal();
|
||||
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
/* load event for next transfer */
|
||||
ptrans->lock->signal();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ FILENAME... motordevCom.h
|
||||
USAGE... This file contains definitions and structures that
|
||||
are common to all motor record device support modules.
|
||||
|
||||
Version: $Revision: 1.2 $
|
||||
Version: $Revision: 1.3 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2000-07-17 17:48:55 $
|
||||
Last Modified: $Date: 2002-10-21 21:07:14 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -32,6 +32,7 @@ Last Modified: $Date: 2000-07-17 17:48:55 $
|
||||
#ifndef INCmotordevCom
|
||||
#define INCmotordevCom 1
|
||||
|
||||
#include <epicsEvent.h>
|
||||
#include "motor.h"
|
||||
#include "motordrvCom.h"
|
||||
|
||||
@@ -40,12 +41,10 @@ Last Modified: $Date: 2000-07-17 17:48:55 $
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define SEM_TIMEOUT 50
|
||||
|
||||
/* Axis status. */
|
||||
struct axis_stat
|
||||
{
|
||||
BOOLEAN in_use; /* Indicates axis assigned to a motor record. */
|
||||
bool in_use; /* Indicates axis assigned to a motor record. */
|
||||
};
|
||||
|
||||
/* Controller board status. */
|
||||
@@ -61,16 +60,16 @@ struct board_stat
|
||||
struct motor_trans
|
||||
{
|
||||
int state;
|
||||
FAST_LOCK lock;
|
||||
epicsEvent *lock;
|
||||
struct mess_node motor_call;
|
||||
int callback_changed;
|
||||
int motor_pos;
|
||||
int encoder_pos;
|
||||
int vel;
|
||||
unsigned long status;
|
||||
SEM_ID initSem;
|
||||
epicsEvent *initSem;
|
||||
struct driver_table *tabptr;
|
||||
BOOLEAN dpm; /* For OMS VME58 only, drive power monitoring. */
|
||||
bool dpm; /* For OMS VME58 only, drive power monitoring. */
|
||||
};
|
||||
|
||||
extern long motor_update_values(struct motorRecord *);
|
||||
|
||||
@@ -3,9 +3,9 @@ FILENAME... motordrvCom.c
|
||||
USAGE... This file contains driver functions that are common
|
||||
to all motor record driver modules.
|
||||
|
||||
Version: $Revision: 1.7 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 18:48:44 $
|
||||
Last Modified: $Date: 2002-10-21 21:06:04 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -55,28 +55,19 @@ Last Modified: $Date: 2002-07-05 18:48:44 $
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <callback.h>
|
||||
}
|
||||
#else
|
||||
#include <callback.h>
|
||||
#endif
|
||||
#include <fast_lock.h>
|
||||
#include <tickLib.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include "motor.h"
|
||||
#include "motordrvCom.h"
|
||||
|
||||
/* Function declarations. */
|
||||
static int query_axis(int card, struct driver_table *tabptr, ULONG tick);
|
||||
static void process_messages(struct driver_table *tabptr, ULONG tick);
|
||||
static int query_axis(int card, struct driver_table *tabptr, epicsTime tick);
|
||||
static void process_messages(struct driver_table *tabptr, epicsTime tick);
|
||||
static struct mess_node *get_head_node(struct driver_table *tabptr);
|
||||
static struct mess_node *motor_malloc(struct circ_queue *freelistptr, FAST_LOCK *lockptr);
|
||||
static struct mess_node *motor_malloc(struct circ_queue *freelistptr, epicsEvent *lockptr);
|
||||
|
||||
|
||||
/*
|
||||
@@ -99,12 +90,12 @@ static struct mess_node *motor_malloc(struct circ_queue *freelistptr, FAST_LOCK
|
||||
* ENDIF
|
||||
* Pend on semaphore with "wait_time" timeout argument - call semTake().
|
||||
* Update elapsed time.
|
||||
* IF the "any_motor_in_motion" indicator is ON.
|
||||
* IF the "any_motor_in_motion" indicator is true.
|
||||
* IF VME58 instance of this task.
|
||||
* Start data area update on all cards - Call start_status().
|
||||
* ENDIF
|
||||
* FOR each OMS board.
|
||||
* IF motor data structure defined, AND, motor-in-motion indicator ON.
|
||||
* IF motor data structure defined, AND, motor-in-motion indicator true.
|
||||
* Update OMS board status - call query_axis().
|
||||
* ENDIF
|
||||
* ENDFOR
|
||||
@@ -118,40 +109,44 @@ static struct mess_node *motor_malloc(struct circ_queue *freelistptr, FAST_LOCK
|
||||
*/
|
||||
/*****************************************************/
|
||||
|
||||
int motor_task(int scan_rate, int msw_tab_ptr, int lsw_tab_ptr, int a4, int a5,
|
||||
int a6, int a7, int a8, int a9, int a10)
|
||||
int motor_task(struct thread_args *args)
|
||||
{
|
||||
struct driver_table *tabptr;
|
||||
ULONG tick_used, tick_curr;
|
||||
STATUS sem_ret;
|
||||
int wait_time, itera;
|
||||
bool sem_ret;
|
||||
epicsTimeStamp scan_timestamp;
|
||||
epicsTime scan_time, previous_time, current_time;
|
||||
double scan_sec, wait_time, time_lapse;
|
||||
int itera;
|
||||
|
||||
if (sizeof(int) >= sizeof(char *))
|
||||
tabptr = (struct driver_table *) msw_tab_ptr;
|
||||
else
|
||||
tabptr = (struct driver_table *) ((long) msw_tab_ptr << 16 | (long) lsw_tab_ptr);
|
||||
tabptr = args->table;
|
||||
|
||||
tick_used = tickGet();
|
||||
previous_time = epicsTime::getCurrent();
|
||||
|
||||
scan_sec = 1 / (double) args->motor_scan_rate; /* Convert HZ to seconds. */
|
||||
scan_timestamp.secPastEpoch = 0;
|
||||
scan_timestamp.nsec = (epicsUInt32) (scan_sec * 10E9); /* Convert sec. to nanoseconds. */
|
||||
scan_time = scan_timestamp;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (*tabptr->any_inmotion_ptr == 0)
|
||||
wait_time = WAIT_FOREVER;
|
||||
wait_time = 1000; /* Wait forever = 1,000 seconds. */
|
||||
else
|
||||
{
|
||||
tick_curr = tickGet() - tick_used;
|
||||
if (tick_curr < (ULONG) scan_rate)
|
||||
current_time = epicsTime::getCurrent();
|
||||
time_lapse = current_time - previous_time;
|
||||
if (time_lapse < scan_sec)
|
||||
{
|
||||
wait_time = scan_rate - tick_curr;
|
||||
if (wait_time < 1)
|
||||
wait_time = 1;
|
||||
wait_time = scan_time - current_time;
|
||||
if (wait_time < 0.010)
|
||||
wait_time = 0.010;
|
||||
}
|
||||
else
|
||||
wait_time = 1;
|
||||
wait_time = 0.010;
|
||||
}
|
||||
|
||||
sem_ret = semTake(*tabptr->semptr, wait_time);
|
||||
tick_used = tickGet();
|
||||
sem_ret = tabptr->semptr->wait(wait_time);
|
||||
previous_time = epicsTime::getCurrent();
|
||||
|
||||
if (*tabptr->any_inmotion_ptr)
|
||||
{
|
||||
@@ -162,17 +157,17 @@ int motor_task(int scan_rate, int msw_tab_ptr, int lsw_tab_ptr, int a4, int a5,
|
||||
{
|
||||
struct controller *brdptr = (*tabptr->card_array)[itera];
|
||||
if (brdptr != NULL && brdptr->motor_in_motion)
|
||||
query_axis(itera, tabptr, tick_used);
|
||||
query_axis(itera, tabptr, previous_time);
|
||||
}
|
||||
}
|
||||
if (sem_ret != ERROR)
|
||||
process_messages(tabptr, tick_used);
|
||||
if (sem_ret)
|
||||
process_messages(tabptr, previous_time);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int query_axis(int card, struct driver_table *tabptr, ULONG tick)
|
||||
static int query_axis(int card, struct driver_table *tabptr, epicsTime tick)
|
||||
{
|
||||
struct controller *brdptr;
|
||||
int index;
|
||||
@@ -183,21 +178,19 @@ static int query_axis(int card, struct driver_table *tabptr, ULONG tick)
|
||||
{
|
||||
register struct mess_info *motor_info;
|
||||
register struct mess_node *motor_motion;
|
||||
ULONG delay;
|
||||
double delay;
|
||||
|
||||
motor_info = &(brdptr->motor_info[index]);
|
||||
if ((motor_motion = motor_info->motor_motion) != 0)
|
||||
{
|
||||
if (tick >= motor_info->status_delay)
|
||||
delay = tick - motor_info->status_delay;
|
||||
else
|
||||
delay = tick + (0xFFFFFFFF - motor_info->status_delay);
|
||||
}
|
||||
|
||||
if (motor_motion && (delay >= 2) && (*tabptr->setstat) (card, index))
|
||||
if (motor_motion && (delay >= 0.01) && (*tabptr->setstat) (card, index))
|
||||
{
|
||||
struct mess_node *mess_ret;
|
||||
BOOLEAN ls_active;
|
||||
bool ls_active;
|
||||
|
||||
motor_motion->position = motor_info->position;
|
||||
motor_motion->encoder_position = motor_info->encoder_position;
|
||||
@@ -216,19 +209,19 @@ static int query_axis(int card, struct driver_table *tabptr, ULONG tick)
|
||||
if (motor_motion->status & RA_DIRECTION)
|
||||
{
|
||||
if (motor_motion->status & RA_PLUS_LS)
|
||||
ls_active = ON;
|
||||
ls_active = true;
|
||||
else
|
||||
ls_active = OFF;
|
||||
ls_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (motor_motion->status & RA_MINUS_LS)
|
||||
ls_active = ON;
|
||||
ls_active = true;
|
||||
else
|
||||
ls_active = OFF;
|
||||
ls_active = false;
|
||||
}
|
||||
|
||||
if (ls_active == ON ||
|
||||
if (ls_active == true ||
|
||||
motor_motion->status & RA_DONE ||
|
||||
motor_motion->status & RA_PROBLEM)
|
||||
{
|
||||
@@ -251,10 +244,10 @@ static int query_axis(int card, struct driver_table *tabptr, ULONG tick)
|
||||
}
|
||||
|
||||
|
||||
static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
static void process_messages(struct driver_table *tabptr, epicsTime tick)
|
||||
{
|
||||
struct mess_node *node, *motor_motion;
|
||||
ULONG delay;
|
||||
double delay;
|
||||
|
||||
while ((node = get_head_node(tabptr)))
|
||||
{
|
||||
@@ -273,7 +266,7 @@ static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
char axis_name;
|
||||
|
||||
if (tabptr->axis_names == NULL)
|
||||
axis_name = NULL;
|
||||
axis_name = '0';
|
||||
else
|
||||
axis_name = tabptr->axis_names[axis];
|
||||
|
||||
@@ -285,7 +278,7 @@ static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
{
|
||||
case VELOCITY:
|
||||
(*tabptr->sendmsg) (card, node->message, axis_name);
|
||||
if (brdptr->cmnd_response == ON)
|
||||
if (brdptr->cmnd_response == true)
|
||||
(*tabptr->getmsg) (card, inbuf, 1);
|
||||
|
||||
/*
|
||||
@@ -313,7 +306,7 @@ static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
|
||||
case MOTION:
|
||||
(*tabptr->sendmsg) (card, node->message, axis_name);
|
||||
if (brdptr->cmnd_response == ON)
|
||||
if (brdptr->cmnd_response == true)
|
||||
(*tabptr->getmsg) (card, inbuf, 1);
|
||||
|
||||
/* this is tricky - see velocity comment */
|
||||
@@ -331,10 +324,8 @@ static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
case INFO:
|
||||
if (tick >= motor_info->status_delay)
|
||||
delay = tick - motor_info->status_delay;
|
||||
else
|
||||
delay = tick + (0xFFFFFFFF - motor_info->status_delay);
|
||||
if (delay < 2) /* Status update delay - needed for OMS. */
|
||||
taskDelay((int) (2 - delay)); /* 2 RTOS tick delay. */
|
||||
if (delay < 0.01) /* Status update delay - needed for OMS. */
|
||||
epicsThreadSleep(delay); /* 2 RTOS tick delay. */
|
||||
|
||||
if (tabptr->strtstat != NULL)
|
||||
(*tabptr->strtstat) (card);
|
||||
@@ -361,16 +352,16 @@ static void process_messages(struct driver_table *tabptr, ULONG tick)
|
||||
|
||||
case MOVE_TERM:
|
||||
if (motor_motion != NULL)
|
||||
motor_motion->message[0] = NULL; /* Clear 2nd command from buffer. */
|
||||
motor_motion->message[0] = '0'; /* Clear 2nd command from buffer. */
|
||||
(*tabptr->sendmsg) (card, node->message, axis_name);
|
||||
if (brdptr->cmnd_response == ON)
|
||||
if (brdptr->cmnd_response == true)
|
||||
(*tabptr->getmsg) (card, inbuf, 1);
|
||||
motor_free(node, tabptr); /* free message buffer */
|
||||
break;
|
||||
|
||||
default:
|
||||
(*tabptr->sendmsg) (card, node->message, axis_name);
|
||||
if (brdptr->cmnd_response == ON)
|
||||
if (brdptr->cmnd_response == true)
|
||||
(*tabptr->getmsg) (card, inbuf, 1);
|
||||
motor_free(node, tabptr); /* free message buffer */
|
||||
motor_info->status_delay = tick;
|
||||
@@ -398,7 +389,7 @@ static struct mess_node *get_head_node(struct driver_table *tabptr)
|
||||
struct circ_queue *qptr;
|
||||
struct mess_node *node;
|
||||
|
||||
FASTLOCK(tabptr->quelockptr);
|
||||
tabptr->quelockptr->wait();
|
||||
qptr = tabptr->queptr;
|
||||
node = qptr->head;
|
||||
|
||||
@@ -410,7 +401,9 @@ static struct mess_node *get_head_node(struct driver_table *tabptr)
|
||||
if (node == qptr->tail)
|
||||
qptr->tail = NULL;
|
||||
}
|
||||
FASTUNLOCK(tabptr->quelockptr);
|
||||
|
||||
tabptr->quelockptr->signal();
|
||||
|
||||
return (node);
|
||||
}
|
||||
|
||||
@@ -459,7 +452,9 @@ int motor_send(struct mess_node *u_msg, struct driver_table *tabptr)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
FASTLOCK(tabptr->quelockptr);
|
||||
/* Lock queue */
|
||||
tabptr->quelockptr->wait();
|
||||
|
||||
qptr = tabptr->queptr;
|
||||
if (qptr->tail)
|
||||
{
|
||||
@@ -471,17 +466,20 @@ int motor_send(struct mess_node *u_msg, struct driver_table *tabptr)
|
||||
qptr->tail = new_message;
|
||||
qptr->head = new_message;
|
||||
}
|
||||
FASTUNLOCK(tabptr->quelockptr);
|
||||
|
||||
semGive(*tabptr->semptr);
|
||||
|
||||
/* Unlock message queue */
|
||||
tabptr->quelockptr->signal();
|
||||
|
||||
tabptr->semptr->signal();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct mess_node *motor_malloc(struct circ_queue *freelistptr, FAST_LOCK *lockptr)
|
||||
static struct mess_node *motor_malloc(struct circ_queue *freelistptr, epicsEvent *lockptr)
|
||||
{
|
||||
struct mess_node *node;
|
||||
|
||||
FASTLOCK(lockptr);
|
||||
lockptr->wait();
|
||||
|
||||
if (!freelistptr->head)
|
||||
node = (struct mess_node *) malloc(sizeof(struct mess_node));
|
||||
@@ -492,7 +490,9 @@ static struct mess_node *motor_malloc(struct circ_queue *freelistptr, FAST_LOCK
|
||||
if (!freelistptr->head)
|
||||
freelistptr->tail = (struct mess_node *) NULL;
|
||||
}
|
||||
FASTUNLOCK(lockptr);
|
||||
|
||||
lockptr->signal();
|
||||
|
||||
return (node);
|
||||
}
|
||||
|
||||
@@ -501,7 +501,8 @@ int motor_free(struct mess_node * node, struct driver_table *tabptr)
|
||||
struct circ_queue *freelistptr;
|
||||
|
||||
freelistptr = tabptr->freeptr;
|
||||
FASTLOCK(tabptr->freelockptr);
|
||||
|
||||
tabptr->freelockptr->wait();
|
||||
|
||||
node->next = (struct mess_node *) NULL;
|
||||
|
||||
@@ -516,7 +517,8 @@ int motor_free(struct mess_node * node, struct driver_table *tabptr)
|
||||
freelistptr->tail = node;
|
||||
}
|
||||
|
||||
FASTUNLOCK(tabptr->freelockptr);
|
||||
tabptr->freelockptr->signal();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ FILENAME... motordrvCom.h
|
||||
USAGE... This file contains definitions and structures that
|
||||
are common to all motor record driver support modules.
|
||||
|
||||
Version: $Revision: 1.7 $
|
||||
Version: $Revision: 1.8 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2001-12-14 20:48:00 $
|
||||
Last Modified: $Date: 2002-10-21 21:08:10 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -43,7 +43,11 @@ Last Modified: $Date: 2001-12-14 20:48:00 $
|
||||
#ifndef INCmotordrvComh
|
||||
#define INCmotordrvComh 1
|
||||
|
||||
#include <rngLib.h>
|
||||
#include <callback.h>
|
||||
#include <epicsTypes.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsTime.h>
|
||||
#include <epicsRingPointer.h>
|
||||
|
||||
|
||||
/* Controller communication port type, followed by status. */
|
||||
@@ -150,10 +154,8 @@ struct irqdatastr /* Used only for VME44. */
|
||||
/* Interrupt Handling control elements */
|
||||
int irqErrno; /* Error indicator from isr */
|
||||
epicsUInt8 irqEnable;
|
||||
RING_ID recv_rng; /* message receiving control */
|
||||
SEM_ID recv_sem;
|
||||
RING_ID send_rng; /* message transmitting control */
|
||||
SEM_ID send_sem;
|
||||
epicsRingPointerId recv_rng; /* message receiving control */
|
||||
epicsEvent *recv_sem;
|
||||
};
|
||||
|
||||
struct mess_info
|
||||
@@ -164,7 +166,7 @@ struct mess_info
|
||||
epicsInt32 encoder_position; /* one pos for each axis */
|
||||
epicsInt32 velocity; /* Raw velocity readback(not implemented) */
|
||||
int no_motion_count;
|
||||
ULONG status_delay; /* Insure 10ms delay between motion/velocity
|
||||
epicsTime status_delay; /* Insure 10ms delay between motion/velocity
|
||||
* commands and status query. */
|
||||
unsigned long status; /* one pos for each axis */
|
||||
int pid_present; /* PID control indicator for VME58 (YES/NO). */
|
||||
@@ -178,7 +180,7 @@ struct controller /* Controller board information. */
|
||||
char ident[50]; /* identification string for this card */
|
||||
int total_axis; /* total axis on this card */
|
||||
char *localaddr; /* address of this card */
|
||||
BOOLEAN cmnd_response; /* Indicates controller communication response
|
||||
bool cmnd_response; /* Indicates controller communication response
|
||||
* to VELOCITY, MOTION and MOVE_TERM type commands. */
|
||||
struct irqdatastr *irqdata; /* VME44 only; IRQ data. */
|
||||
void *DevicePrivate; /* Pointer to device specific structure. For
|
||||
@@ -198,10 +200,10 @@ struct driver_table
|
||||
int (*get_card_info) (int, MOTOR_CARD_QUERY *, struct driver_table *);
|
||||
int (*get_axis_info) (int, int, MOTOR_AXIS_QUERY *, struct driver_table *);
|
||||
struct circ_queue *queptr;
|
||||
FAST_LOCK *quelockptr;
|
||||
epicsEvent *quelockptr;
|
||||
struct circ_queue *freeptr;
|
||||
FAST_LOCK *freelockptr;
|
||||
SEM_ID *semptr;
|
||||
epicsEvent *freelockptr;
|
||||
epicsEvent *semptr;
|
||||
struct controller ***card_array;
|
||||
int *cardcnt_ptr;
|
||||
int *any_inmotion_ptr;
|
||||
@@ -210,16 +212,24 @@ struct driver_table
|
||||
int (*setstat) (int, int);
|
||||
void (*query_done) (int, int, struct mess_node *);
|
||||
void (*strtstat) (int); /* Optional; start status function or NULL. */
|
||||
const BOOLEAN *const init_indicator; /* Driver initialized indicator. */
|
||||
const bool *const init_indicator; /* Driver initialized indicator. */
|
||||
char *axis_names; /* Axis name array or NULL. */
|
||||
};
|
||||
|
||||
|
||||
struct thread_args
|
||||
{
|
||||
int motor_scan_rate;
|
||||
struct driver_table *table;
|
||||
};
|
||||
|
||||
|
||||
/* Function prototypes. */
|
||||
|
||||
extern int motor_send(struct mess_node *, struct driver_table *);
|
||||
extern int motor_free(struct mess_node *, struct driver_table *);
|
||||
extern int motor_card_info(int, MOTOR_CARD_QUERY *, struct driver_table *);
|
||||
extern int motor_axis_info(int, int, MOTOR_AXIS_QUERY *, struct driver_table *);
|
||||
extern int motor_task(int a1, int, int, int, int, int, int, int, int, int a10);
|
||||
extern int motor_task(struct thread_args *);
|
||||
|
||||
#endif /* INCmotordrvComh */
|
||||
|
||||
@@ -4,9 +4,9 @@ USAGE... This file contains local variables that are allocated
|
||||
in each motor record driver. The variables are allocated
|
||||
in each driver by including this file.
|
||||
|
||||
Version: $Revision: 1.1 $
|
||||
Version: $Revision: 1.2 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2000-02-08 22:18:45 $
|
||||
Last Modified: $Date: 2002-10-21 21:08:09 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -32,16 +32,19 @@ Last Modified: $Date: 2000-02-08 22:18:45 $
|
||||
#ifndef INCmotordrvComCode
|
||||
#define INCmotordrvComCode 1
|
||||
|
||||
#include <fast_lock.h>
|
||||
#include <epicsTypes.h>
|
||||
#include <epicsEvent.h>
|
||||
|
||||
/* --- Local data common to each driver. --- */
|
||||
STATIC volatile int motor_scan_rate = SCAN_RATE;
|
||||
STATIC struct controller **motor_state;
|
||||
STATIC int total_cards;
|
||||
STATIC int any_motor_in_motion;
|
||||
STATIC struct circ_queue mess_queue; /* in message queue head */
|
||||
STATIC FAST_LOCK queue_lock;
|
||||
STATIC epicsEvent queue_lock(epicsEventFull);
|
||||
STATIC struct circ_queue free_list;
|
||||
STATIC FAST_LOCK freelist_lock;
|
||||
STATIC SEM_ID motor_sem;
|
||||
STATIC BOOLEAN initialized = OFF; /* Driver initialized indicator. */
|
||||
STATIC epicsEvent freelist_lock(epicsEventFull);
|
||||
STATIC epicsEvent motor_sem(epicsEventEmpty);
|
||||
STATIC bool initialized = false; /* Driver initialized indicator. */
|
||||
|
||||
#endif /* INCmotordrvComCode */
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... devOms.c
|
||||
USAGE... Device level support for OMS VME8 and VME44 models.
|
||||
|
||||
Version: $Revision: 1.2 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2000-07-14 20:19:08 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:18 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -43,25 +43,15 @@ Last Modified: $Date: 2000-07-14 20:19:08 $
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h> /* jps: include for init_record wait */
|
||||
#include <alarm.h>
|
||||
#include <callback.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbCommon.h>
|
||||
#include <fast_lock.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <recSup.h>
|
||||
#include <errlog.h>
|
||||
}
|
||||
#else
|
||||
#include <recSup.h>
|
||||
#include <errlog.h>
|
||||
#endif
|
||||
|
||||
#include "motorRecord.h"
|
||||
#include "motor.h"
|
||||
@@ -74,8 +64,8 @@ extern int oms44_num_cards;
|
||||
extern struct driver_table oms_access;
|
||||
|
||||
/* ----------------Create the dsets for devOMS----------------- */
|
||||
STATIC long oms_init(int);
|
||||
STATIC long oms_init_record(struct motorRecord *);
|
||||
STATIC long oms_init(void *);
|
||||
STATIC long oms_init_record(void *);
|
||||
STATIC long oms_start_trans(struct motorRecord *);
|
||||
STATIC long oms_end_trans(struct motorRecord *);
|
||||
|
||||
@@ -91,8 +81,10 @@ struct motor_dset devOMS =
|
||||
STATIC struct board_stat **oms_cards;
|
||||
STATIC const char errmsg[] = {"\n\n!!!ERROR!!! - Oms driver uninitialized.\n"};
|
||||
|
||||
STATIC long oms_init(int after)
|
||||
STATIC long oms_init(void *arg)
|
||||
{
|
||||
int after = (int) arg;
|
||||
|
||||
if (*(oms_access.init_indicator) == NO)
|
||||
{
|
||||
errlogSevPrintf(errlogMinor, "%s", errmsg);
|
||||
@@ -102,8 +94,9 @@ STATIC long oms_init(int after)
|
||||
return(motor_init_com(after, oms44_num_cards, &oms_access, &oms_cards));
|
||||
}
|
||||
|
||||
STATIC long oms_init_record(struct motorRecord *mr)
|
||||
STATIC long oms_init_record(void *arg)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) arg;
|
||||
return(motor_init_record_com(mr, oms44_num_cards, &oms_access, oms_cards));
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... devOms58.c
|
||||
USAGE... Motor record device level support for OMS VME58.
|
||||
|
||||
Version: $Revision: 1.2 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2000-07-14 20:24:20 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:18 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -44,25 +44,15 @@ Last Modified: $Date: 2000-07-14 20:24:20 $
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <semLib.h> /* jps: include for init_record wait */
|
||||
#include <alarm.h>
|
||||
#include <callback.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbCommon.h>
|
||||
#include <fast_lock.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <recSup.h>
|
||||
#include <errlog.h>
|
||||
}
|
||||
#else
|
||||
#include <recSup.h>
|
||||
#include <errlog.h>
|
||||
#endif
|
||||
|
||||
#include "motorRecord.h"
|
||||
#include "motor.h"
|
||||
@@ -75,8 +65,8 @@ extern int oms58_num_cards;
|
||||
extern struct driver_table oms58_access;
|
||||
|
||||
/* ----------------Create the dsets for devOMS----------------- */
|
||||
STATIC long oms_init(int after);
|
||||
STATIC long oms_init_record(struct motorRecord *);
|
||||
STATIC long oms_init(void *);
|
||||
STATIC long oms_init_record(void *);
|
||||
STATIC long oms_start_trans(struct motorRecord *);
|
||||
STATIC long oms_end_trans(struct motorRecord *);
|
||||
|
||||
@@ -93,8 +83,9 @@ struct motor_dset devOms58 =
|
||||
STATIC struct board_stat **oms_cards;
|
||||
STATIC const char errmsg[] = {"\n\n!!!ERROR!!! - Oms58 driver uninitialized.\n"};
|
||||
|
||||
STATIC long oms_init(int after)
|
||||
STATIC long oms_init(void *arg)
|
||||
{
|
||||
int after = (int) arg;
|
||||
if (*(oms58_access.init_indicator) == NO)
|
||||
{
|
||||
errlogSevPrintf(errlogMinor, "%s", errmsg);
|
||||
@@ -104,8 +95,9 @@ STATIC long oms_init(int after)
|
||||
return(motor_init_com(after, oms58_num_cards, &oms58_access, &oms_cards));
|
||||
}
|
||||
|
||||
STATIC long oms_init_record(struct motorRecord *mr)
|
||||
STATIC long oms_init_record(void *arg)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) arg;
|
||||
return(motor_init_record_com(mr, oms58_num_cards, &oms58_access, oms_cards));
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... devOmsCom.c
|
||||
USAGE... Data and functions common to all OMS device level support.
|
||||
|
||||
Version: $Revision: 1.8 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:37:50 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:19 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -51,9 +51,8 @@ Last Modified: $Date: 2002-07-05 19:37:50 $
|
||||
* motor steps.
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <string.h>
|
||||
#include <logLib.h>
|
||||
#include <errlog.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "motorRecord.h"
|
||||
@@ -67,7 +66,7 @@ motor.h
|
||||
|
||||
struct motor_table
|
||||
{
|
||||
unsigned char type;
|
||||
msg_types type;
|
||||
const char *command;
|
||||
int num_parms;
|
||||
};
|
||||
@@ -123,7 +122,7 @@ LOGIC...
|
||||
Read motor controller's GPIO configuration.
|
||||
IF bit corresponding to current axis is configured as an
|
||||
output bit.
|
||||
Set "Driver Power Monitoring" indicator ON.
|
||||
Set "Driver Power Monitoring" indicator true.
|
||||
ELSE
|
||||
Output ERROR message.
|
||||
ENDIF
|
||||
@@ -152,7 +151,7 @@ LOGIC...
|
||||
IF command type is MOTION or VELOCITY.
|
||||
Process PREM and POST fields.
|
||||
ENDIF
|
||||
IF Overtravel status indicator ON, AND, input command is a MOVE.
|
||||
IF Overtravel status indicator true, AND, input command is a MOVE.
|
||||
NOTE: This logic is here as a workaround for the "Moving off a
|
||||
limit switch" OMS firmware error.
|
||||
|
||||
@@ -173,10 +172,10 @@ long oms_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
struct motor_trans *trans = (struct motor_trans *) mr->dpvt;
|
||||
struct mess_node *motor_call;
|
||||
char buffer[40];
|
||||
unsigned char cmnd_type;
|
||||
msg_types cmnd_type;
|
||||
long rtnind;
|
||||
|
||||
rtnind = OK;
|
||||
rtnind = 0;
|
||||
motor_call = &trans->motor_call;
|
||||
|
||||
cmnd_type = oms_table[command].type;
|
||||
@@ -185,7 +184,7 @@ long oms_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
|
||||
/* concatenate onto the dpvt message field */
|
||||
if (trans->state != BUILD_STATE)
|
||||
return(rtnind = ERROR);
|
||||
return(rtnind = -1);
|
||||
|
||||
if ((command == PRIMITIVE) && (mr->init != NULL) &&
|
||||
(strlen(mr->init) != 0))
|
||||
@@ -214,10 +213,10 @@ long oms_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
response = 0; /* Force an error. */
|
||||
bitselect = (1 << motor_call->signal);
|
||||
if ((response & bitselect) == 0)
|
||||
trans->dpm = ON;
|
||||
trans->dpm = true;
|
||||
else
|
||||
logMsg((char *) "Invalid VME58 configuration; RB = 0x%x\n",
|
||||
response, 0, 0, 0, 0 ,0);
|
||||
errPrintf(0, __FILE__, __LINE__,
|
||||
"Invalid VME58 configuration; RB = 0x%x\n", response);
|
||||
}
|
||||
end++;
|
||||
strcpy(buffer, end);
|
||||
@@ -244,7 +243,7 @@ long oms_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
{
|
||||
*parms = 0.00005;
|
||||
mr->pcof = 0.00005;
|
||||
rtnind = ERROR;
|
||||
rtnind = -1;
|
||||
}
|
||||
else if (command == STOP_AXIS)
|
||||
{
|
||||
@@ -4,9 +4,9 @@ FILENAME.. devOmsCom.h
|
||||
USAGE... This file contains OMS device information that is
|
||||
common to all OMS device support modules.
|
||||
|
||||
Version: $Revision: 1.2 $
|
||||
Version: $Revision: 1.3 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2000-07-14 20:01:20 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:48 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -34,6 +34,6 @@ Last Modified: $Date: 2000-07-14 20:01:20 $
|
||||
|
||||
#include "motordevCom.h"
|
||||
|
||||
extern long oms_build_trans(motor_cmnd, double *, struct motorRecord *);
|
||||
extern RTN_VALUES oms_build_trans(motor_cmnd, double *, struct motorRecord *);
|
||||
|
||||
#endif /* INCdevOmsComh */
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... drvOms.c
|
||||
USAGE... Driver level support for OMS models VME8, VME44 and VS4.
|
||||
|
||||
Version: $Revision: 1.10 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:39:28 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:19 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -62,7 +62,6 @@ Last Modified: $Date: 2002-07-05 19:39:28 $
|
||||
|
||||
========================stepper motor driver ========================*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdio.h>
|
||||
#include <sysLib.h>
|
||||
#include <string.h>
|
||||
@@ -89,6 +88,7 @@ extern "C" {
|
||||
#endif
|
||||
#include <errMdef.h>
|
||||
#include <intLib.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include "motor.h"
|
||||
#include "drvOms.h"
|
||||
@@ -153,8 +153,6 @@ STATIC int omsError(int card);
|
||||
STATIC int motorIsrEnable(int card);
|
||||
STATIC void motorIsrDisable(int card);
|
||||
|
||||
/*----------------functions-----------------*/
|
||||
|
||||
struct driver_table oms_access =
|
||||
{
|
||||
NULL,
|
||||
@@ -191,6 +189,10 @@ struct
|
||||
#endif
|
||||
} drvOms = {2, report, init};
|
||||
|
||||
STATIC struct thread_args targs = {SCAN_RATE, &oms_access};
|
||||
|
||||
/*----------------functions-----------------*/
|
||||
|
||||
static long report(int level)
|
||||
{
|
||||
int card;
|
||||
@@ -210,7 +212,7 @@ static long report(int level)
|
||||
|
||||
static long init()
|
||||
{
|
||||
initialized = ON; /* Indicate that driver is initialized. */
|
||||
initialized = true; /* Indicate that driver is initialized. */
|
||||
(void) motor_init();
|
||||
return ((long) 0);
|
||||
}
|
||||
@@ -237,7 +239,7 @@ STATIC int set_status(int card, int signal)
|
||||
char q_buf[50];
|
||||
int index, pos;
|
||||
int rtn_state;
|
||||
BOOLEAN ls_active;
|
||||
bool ls_active;
|
||||
|
||||
motor_info = &(motor_state[card]->motor_info[signal]);
|
||||
|
||||
@@ -275,7 +277,7 @@ STATIC int set_status(int card, int signal)
|
||||
|
||||
if (ax_stat->overtravel == 'L')
|
||||
{
|
||||
ls_active = ON;
|
||||
ls_active = true;
|
||||
if (motor_info->status & RA_DIRECTION)
|
||||
motor_info->status |= RA_PLUS_LS;
|
||||
else
|
||||
@@ -283,7 +285,7 @@ STATIC int set_status(int card, int signal)
|
||||
}
|
||||
else
|
||||
{
|
||||
ls_active = OFF;
|
||||
ls_active = false;
|
||||
motor_info->status &= ~(RA_PLUS_LS | RA_MINUS_LS);
|
||||
}
|
||||
|
||||
@@ -365,11 +367,11 @@ STATIC int set_status(int card, int signal)
|
||||
if (!(motor_info->status & RA_DIRECTION))
|
||||
motor_info->velocity *= -1;
|
||||
|
||||
rtn_state = (!motor_info->no_motion_count || ls_active == ON ||
|
||||
rtn_state = (!motor_info->no_motion_count || ls_active == true ||
|
||||
(motor_info->status & (RA_DONE | RA_PROBLEM))) ? 1 : 0;
|
||||
|
||||
/* Test for post-move string. */
|
||||
if ((motor_info->status & RA_DONE || ls_active == ON) &&
|
||||
if ((motor_info->status & RA_DONE || ls_active == true) &&
|
||||
(motor_info->motor_motion != 0) &&
|
||||
(motor_info->motor_motion->postmsgptr != 0))
|
||||
{
|
||||
@@ -595,12 +597,19 @@ STATIC int omsGet(int card, char *pchar, int timeout)
|
||||
if (pmotorState->irqdata->irqEnable)
|
||||
{
|
||||
/* Get character from isr - if available */
|
||||
while ((getCnt = rngBufGet(pmotorState->irqdata->recv_rng, pchar, 1)) == 0 &&
|
||||
retry < timeout)
|
||||
while (epicsRingPointerIsEmpty(pmotorState->irqdata->recv_rng) && retry < timeout)
|
||||
{
|
||||
semTake(pmotorState->irqdata->recv_sem, 1); /* Wait for character */
|
||||
pmotorState->irqdata->recv_sem->wait(0.01); /* Wait for character */
|
||||
retry += 5000; /* Compensate for semaphore timeout */
|
||||
}
|
||||
if (!epicsRingPointerIsEmpty(pmotorState->irqdata->recv_rng))
|
||||
{
|
||||
void *rtnptr;
|
||||
|
||||
rtnptr = epicsRingPointerPop(pmotorState->irqdata->recv_rng);
|
||||
*pchar = (char) rtnptr;
|
||||
getCnt = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -627,56 +636,30 @@ STATIC int omsPut(int card, char *pmess)
|
||||
{
|
||||
volatile struct controller *pmotorState;
|
||||
volatile struct vmex_motor *pmotor;
|
||||
int key;
|
||||
char *p;
|
||||
int putCnt;
|
||||
char *putptr;
|
||||
int trys;
|
||||
|
||||
pmotorState = motor_state[card];
|
||||
pmotor = (struct vmex_motor *) pmotorState->localaddr;
|
||||
|
||||
/*
|
||||
* This section enables the transmitt interrupt - it is not used because
|
||||
* of driver-failure during worst-case testing.
|
||||
*/
|
||||
if (FALSE)
|
||||
/* Send next message */
|
||||
for (putptr = pmess; *putptr != '\0'; putptr++)
|
||||
{
|
||||
/* Put string into isr transmitt buffer */
|
||||
putCnt = strlen(pmess);
|
||||
if (rngBufPut(pmotorState->irqdata->send_rng, pmess, putCnt) != putCnt)
|
||||
trys = 0;
|
||||
while (!(pmotor->status & STAT_TRANS_BUF_EMPTY))
|
||||
{
|
||||
Debug(1, "omsPut: Put ring full.\n");
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
/* Turn-on transmit buffer interrupt */
|
||||
key = intLock();
|
||||
pmotor->control |= IRQ_TRANS_BUF;
|
||||
intUnlock(key);
|
||||
|
||||
return (semTake(pmotorState->irqdata->send_sem, MAX_COUNT / 5000));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send next message */
|
||||
for (p = pmess; *p != '\0'; p++)
|
||||
{
|
||||
trys = 0;
|
||||
while (!(pmotor->status & STAT_TRANS_BUF_EMPTY))
|
||||
if (trys > max_io_tries)
|
||||
{
|
||||
if (trys > max_io_tries)
|
||||
{
|
||||
Debug(1, "omsPut: Time_out occurred in send\n");
|
||||
return (ERROR);
|
||||
}
|
||||
if (pmotor->status & STAT_ERROR)
|
||||
{
|
||||
Debug(1, "omsPut: error occurred in send\n");
|
||||
}
|
||||
trys++;
|
||||
Debug(1, "omsPut: Time_out occurred in send\n");
|
||||
return (ERROR);
|
||||
}
|
||||
pmotor->data = *p;
|
||||
if (pmotor->status & STAT_ERROR)
|
||||
{
|
||||
Debug(1, "omsPut: error occurred in send\n");
|
||||
}
|
||||
trys++;
|
||||
}
|
||||
pmotor->data = *putptr;
|
||||
}
|
||||
return (OK);
|
||||
}
|
||||
@@ -766,7 +749,7 @@ STATIC void motorIsr(int card)
|
||||
/* Motion done handling */
|
||||
if (status & STAT_DONE)
|
||||
/* Wake up polling task 'motor_task()' to issue callbacks */
|
||||
semGive(motor_sem);
|
||||
motor_sem.signal();
|
||||
|
||||
/* If command error is present - clear it */
|
||||
if (status & STAT_ERROR)
|
||||
@@ -781,32 +764,18 @@ STATIC void motorIsr(int card)
|
||||
pmotorState->irqdata->irqErrno |= STAT_ERROR;
|
||||
}
|
||||
|
||||
/* Send message */
|
||||
/* if (status & STAT_TRANS_BUF_EMPTY) */
|
||||
if (FALSE)
|
||||
{
|
||||
if (rngBufGet(pmotorState->irqdata->send_rng, &dataChar, 1))
|
||||
pmotor->data = dataChar;
|
||||
else
|
||||
{
|
||||
/* Transmit done - disable irq */
|
||||
semGive(pmotorState->irqdata->send_sem);
|
||||
control &= ~IRQ_TRANS_BUF;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read Response */
|
||||
if (status & STAT_INPUT_BUF_FULL)
|
||||
{
|
||||
dataChar = pmotor->data;
|
||||
|
||||
if (!rngBufPut(pmotorState->irqdata->recv_rng, &dataChar, 1))
|
||||
if (!epicsRingPointerPush(pmotorState->irqdata->recv_rng, (void *) dataChar))
|
||||
{
|
||||
logMsg((char *) "card %d recv ring full, lost '%c'\n", card,
|
||||
dataChar, 0, 0, 0, 0);
|
||||
pmotorState->irqdata->irqErrno |= STAT_INPUT_BUF_FULL;
|
||||
}
|
||||
semGive(pmotorState->irqdata->recv_sem);
|
||||
pmotorState->irqdata->recv_sem->signal();
|
||||
}
|
||||
/* Update-interrupt state */
|
||||
pmotor->control = control;
|
||||
@@ -825,7 +794,7 @@ STATIC int motorIsrEnable(int card)
|
||||
pmotor = (struct vmex_motor *) (pmotorState->localaddr);
|
||||
|
||||
status = devConnectInterrupt(intVME, omsInterruptVector + card,
|
||||
(void (*)(void *)) motorIsr, (void *) card);
|
||||
(void (*)()) motorIsr, (void *) card);
|
||||
|
||||
if (!RTN_SUCCESS(status))
|
||||
{
|
||||
@@ -852,11 +821,8 @@ STATIC int motorIsrEnable(int card)
|
||||
pmotor->vector = omsInterruptVector + card;
|
||||
|
||||
|
||||
pmotorState->irqdata->recv_rng = rngCreate(OMS_RESP_Q_SZ);
|
||||
pmotorState->irqdata->recv_sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
|
||||
pmotorState->irqdata->send_rng = rngCreate(MAX_MSG_SIZE * 2);
|
||||
pmotorState->irqdata->send_sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
pmotorState->irqdata->recv_rng = epicsRingPointerCreate(OMS_RESP_Q_SZ);
|
||||
pmotorState->irqdata->recv_sem = new epicsEvent(epicsEventEmpty);
|
||||
|
||||
pmotorState->irqdata->irqEnable = TRUE;
|
||||
pmotorState->irqdata->irqErrno = 0;
|
||||
@@ -885,7 +851,7 @@ STATIC void motorIsrDisable(int card)
|
||||
pmotor->control = 0;
|
||||
|
||||
status = devDisconnectInterrupt(intVME, omsInterruptVector + card,
|
||||
(void (*)(void *)) motorIsr);
|
||||
(void (*)()) motorIsr);
|
||||
if (!RTN_SUCCESS(status))
|
||||
errPrintf(status, __FILE__, __LINE__, "Can't disconnect vector %d\n",
|
||||
omsInterruptVector + card);
|
||||
@@ -893,11 +859,9 @@ STATIC void motorIsrDisable(int card)
|
||||
/* Remove interrupt control functions */
|
||||
pmotorState->irqdata->irqEnable = FALSE;
|
||||
pmotorState->irqdata->irqErrno = 0;
|
||||
rngDelete(pmotorState->irqdata->recv_rng);
|
||||
rngDelete(pmotorState->irqdata->send_rng);
|
||||
epicsRingPointerDelete(pmotorState->irqdata->recv_rng);
|
||||
|
||||
semDelete(pmotorState->irqdata->recv_sem);
|
||||
semDelete(pmotorState->irqdata->send_sem);
|
||||
delete pmotorState->irqdata->recv_sem;
|
||||
}
|
||||
|
||||
|
||||
@@ -947,9 +911,9 @@ int omsSetup(int num_cards, /* maximum number of cards in rack */
|
||||
|
||||
/* Set motor polling task rate */
|
||||
if (scan_rate >= 1 && scan_rate <= sysClkRateGet())
|
||||
motor_scan_rate = sysClkRateGet() / scan_rate;
|
||||
targs.motor_scan_rate = sysClkRateGet() / scan_rate;
|
||||
else
|
||||
motor_scan_rate = SCAN_RATE;
|
||||
targs.motor_scan_rate = SCAN_RATE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -962,7 +926,7 @@ STATIC int motor_init()
|
||||
volatile struct controller *pmotorState;
|
||||
volatile struct vmex_motor *pmotor;
|
||||
long status;
|
||||
int card_index, motor_index, arg3, arg4;
|
||||
int card_index, motor_index;
|
||||
char axis_pos[50], encoder_pos[50];
|
||||
char *tok_save, *pos_ptr;
|
||||
int total_encoders = 0, total_axis = 0;
|
||||
@@ -1000,8 +964,8 @@ STATIC int motor_init()
|
||||
if (PROBE_SUCCESS(status))
|
||||
{
|
||||
status = devRegisterAddress(__FILE__, OMS_ADDRS_TYPE,
|
||||
(void *) probeAddr, OMS_BRD_SIZE,
|
||||
(void **) &localaddr);
|
||||
(size_t) probeAddr, OMS_BRD_SIZE,
|
||||
(volatile void **) &localaddr);
|
||||
Debug(9, "motor_init: devRegisterAddress() status = %d\n",
|
||||
(int) status);
|
||||
if (!RTN_SUCCESS(status))
|
||||
@@ -1019,7 +983,7 @@ STATIC int motor_init()
|
||||
pmotorState = motor_state[card_index];
|
||||
pmotorState->localaddr = (char *) localaddr;
|
||||
pmotorState->motor_in_motion = 0;
|
||||
pmotorState->cmnd_response = OFF;
|
||||
pmotorState->cmnd_response = false;
|
||||
|
||||
/* Disable Interrupts */
|
||||
pmotorState->irqdata = (struct irqdatastr *) malloc(sizeof(struct irqdatastr));
|
||||
@@ -1097,35 +1061,17 @@ STATIC int motor_init()
|
||||
}
|
||||
}
|
||||
|
||||
motor_sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
any_motor_in_motion = 0;
|
||||
|
||||
FASTLOCKINIT(&queue_lock);
|
||||
FASTLOCK(&queue_lock);
|
||||
mess_queue.head = (struct mess_node *) NULL;
|
||||
mess_queue.tail = (struct mess_node *) NULL;
|
||||
FASTUNLOCK(&queue_lock);
|
||||
|
||||
FASTLOCKINIT(&freelist_lock);
|
||||
FASTLOCK(&freelist_lock);
|
||||
free_list.head = (struct mess_node *) NULL;
|
||||
free_list.tail = (struct mess_node *) NULL;
|
||||
FASTUNLOCK(&freelist_lock);
|
||||
|
||||
Debug(3, "Motors initialized\n");
|
||||
|
||||
if (sizeof(int) >= sizeof(char *))
|
||||
{
|
||||
arg3 = (int) (&oms_access);
|
||||
arg4 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
arg3 = (int) ((long) &oms_access >> 16);
|
||||
arg4 = (int) ((long) &oms_access & 0xFFFF);
|
||||
}
|
||||
taskSpawn((char *) "Oms_motor", 64, VX_FP_TASK | VX_STDIO, 5000, motor_task,
|
||||
motor_scan_rate, arg3, arg4, 0, 0, 0, 0, 0, 0, 0);
|
||||
epicsThreadCreate((const char *) "Oms_motor", 64, 5000, (EPICSTHREADFUNC) motor_task, (void *) &targs);
|
||||
|
||||
Debug(3, "Started motor_task\n");
|
||||
return (0);
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... drvOms58.c
|
||||
USAGE... Motor record driver level support for OMS model VME58.
|
||||
|
||||
Version: $Revision: 1.8 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:40:07 $
|
||||
Last Modified: $Date: 2002-10-21 21:10:20 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -59,7 +59,7 @@ Last Modified: $Date: 2002-07-05 19:40:07 $
|
||||
* data after Done detected via ASCII controller
|
||||
* commands. To avoid collisions, skip writing to
|
||||
* control reg. from motorIsr() if update bit is
|
||||
* ON.
|
||||
* true.
|
||||
* .22 02-22-02 rls - start_status() was not checking for a valid
|
||||
* motor_state[card] pointer. This causes a bus error if
|
||||
* the controller array has holes in it.
|
||||
@@ -69,7 +69,6 @@ Last Modified: $Date: 2002-07-05 19:40:07 $
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdio.h>
|
||||
#include <sysLib.h>
|
||||
#include <string.h>
|
||||
@@ -82,7 +81,6 @@ Last Modified: $Date: 2002-07-05 19:40:07 $
|
||||
#include <dbDefs.h>
|
||||
#include <dbAccess.h>
|
||||
#include <dbCommon.h>
|
||||
#include <fast_lock.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
#ifdef __cplusplus
|
||||
@@ -97,6 +95,7 @@ extern "C" {
|
||||
#include <errlog.h>
|
||||
#endif
|
||||
#include <errMdef.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include "motorRecord.h" /* For Driver Power Monitor feature only. */
|
||||
#include "motor.h"
|
||||
@@ -173,8 +172,6 @@ STATIC int motorIsrSetup(int card);
|
||||
STATIC void oms_nanoSleep(int time);
|
||||
STATIC int oms_nanoWakup(int val);
|
||||
|
||||
/*----------------functions-----------------*/
|
||||
|
||||
struct driver_table oms58_access =
|
||||
{
|
||||
NULL,
|
||||
@@ -211,6 +208,10 @@ struct
|
||||
#endif
|
||||
} drvOms58 = {2, report, init};
|
||||
|
||||
STATIC struct thread_args targs = {SCAN_RATE, &oms58_access};
|
||||
|
||||
/*----------------functions-----------------*/
|
||||
|
||||
static long report(int level)
|
||||
{
|
||||
int card;
|
||||
@@ -236,7 +237,7 @@ static long report(int level)
|
||||
|
||||
static long init()
|
||||
{
|
||||
initialized = ON; /* Indicate that driver is initialized. */
|
||||
initialized = true; /* Indicate that driver is initialized. */
|
||||
(void) motor_init();
|
||||
return ((long) 0);
|
||||
}
|
||||
@@ -362,7 +363,7 @@ STATIC int set_status(int card, int signal)
|
||||
struct encoder_status *en_stat;
|
||||
char q_buf[50], outbuf[50];
|
||||
int index;
|
||||
BOOLEAN ls_active;
|
||||
bool ls_active;
|
||||
|
||||
int rtn_state;
|
||||
|
||||
@@ -408,7 +409,7 @@ STATIC int set_status(int card, int signal)
|
||||
|
||||
if (ax_stat->overtravel == 'L')
|
||||
{
|
||||
ls_active = ON;
|
||||
ls_active = true;
|
||||
if (motor_info->status & RA_DIRECTION)
|
||||
motor_info->status |= RA_PLUS_LS;
|
||||
else
|
||||
@@ -416,7 +417,7 @@ STATIC int set_status(int card, int signal)
|
||||
}
|
||||
else
|
||||
{
|
||||
ls_active = OFF;
|
||||
ls_active = false;
|
||||
motor_info->status &= ~(RA_PLUS_LS | RA_MINUS_LS);
|
||||
}
|
||||
|
||||
@@ -500,10 +501,10 @@ STATIC int set_status(int card, int signal)
|
||||
|
||||
motor_info->encoder_position = motorData;
|
||||
|
||||
if (nodeptr != NULL && ls_active == OFF)
|
||||
if (nodeptr != NULL && ls_active == false)
|
||||
{
|
||||
struct motor_trans *trans = (struct motor_trans *) nodeptr->mrecord->dpvt;
|
||||
if (trans->dpm == ON)
|
||||
if (trans->dpm == true)
|
||||
{
|
||||
unsigned char bitselect;
|
||||
unsigned char inputs = pmotor->control.ioLowReg;
|
||||
@@ -517,11 +518,11 @@ STATIC int set_status(int card, int signal)
|
||||
}
|
||||
}
|
||||
|
||||
rtn_state = (!motor_info->no_motion_count || ls_active == ON ||
|
||||
rtn_state = (!motor_info->no_motion_count || ls_active == true ||
|
||||
(motor_info->status & (RA_DONE | RA_PROBLEM))) ? 1 : 0;
|
||||
|
||||
/* Test for post-move string. */
|
||||
if ((motor_info->status & RA_DONE || ls_active == ON) && nodeptr != 0 &&
|
||||
if ((motor_info->status & RA_DONE || ls_active == true) && nodeptr != 0 &&
|
||||
nodeptr->postmsgptr != 0)
|
||||
{
|
||||
strcpy(outbuf, nodeptr->postmsgptr);
|
||||
@@ -541,7 +542,6 @@ STATIC int send_mess(int card, char const *com, char inchar)
|
||||
{
|
||||
volatile struct vmex_motor *pmotor;
|
||||
epicsInt16 putIndex;
|
||||
epicsInt16 deltaIndex;
|
||||
char outbuf[MAX_MSG_SIZE], *p;
|
||||
int return_code;
|
||||
|
||||
@@ -604,6 +604,8 @@ STATIC int send_mess(int card, char const *com, char inchar)
|
||||
|
||||
while (pmotor->outPutIndex != pmotor->outGetIndex)
|
||||
{
|
||||
epicsInt16 deltaIndex;
|
||||
|
||||
Debug(5, "send_mess: Waiting for ack: index delta=%d\n",
|
||||
(((deltaIndex = pmotor->outPutIndex - pmotor->outGetIndex) < 0) ?
|
||||
BUFFER_SIZE + deltaIndex : deltaIndex));
|
||||
@@ -807,10 +809,10 @@ int oms58Setup(int num_cards, /* maximum number of cards in rack */
|
||||
omsInterruptLevel = int_level;
|
||||
|
||||
/* Set motor polling task rate */
|
||||
if (scan_rate >= 1 && scan_rate <= sysClkRateGet())
|
||||
motor_scan_rate = sysClkRateGet() / scan_rate;
|
||||
if (scan_rate >= 1 && scan_rate <= 60)
|
||||
targs.motor_scan_rate = scan_rate;
|
||||
else
|
||||
motor_scan_rate = SCAN_RATE;
|
||||
targs.motor_scan_rate = SCAN_RATE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -853,7 +855,7 @@ STATIC void motorIsr(int card)
|
||||
/* Overtravel - clear on read */
|
||||
limitFlags = pmotor->control.limitReg;
|
||||
|
||||
/* Only write control register if update bit is OFF. */
|
||||
/* Only write control register if update bit is false. */
|
||||
/* Assure proper control register settings */
|
||||
cntrlReg = pmotor->control.cntrlReg;
|
||||
if ((cntrlReg & 0x01) == 0)
|
||||
@@ -867,7 +869,7 @@ STATIC void motorIsr(int card)
|
||||
/* Motion done handling */
|
||||
if (statusBuf.Bits.done)
|
||||
/* Wake up polling task 'motor_task()' to issue callbacks */
|
||||
semGive(motor_sem);
|
||||
motor_sem.signal();
|
||||
|
||||
if (statusBuf.Bits.cmndError)
|
||||
logMsg((char *) "command error detected by motorISR() on card %d\n",
|
||||
@@ -885,7 +887,7 @@ STATIC int motorIsrSetup(int card)
|
||||
pmotor = (struct vmex_motor *) (motor_state[card]->localaddr);
|
||||
|
||||
status = devConnectInterrupt(intVME, omsInterruptVector + card,
|
||||
(void (*)(void *)) motorIsr, (void *) card);
|
||||
(void (*)()) motorIsr, (void *) card);
|
||||
if (!RTN_SUCCESS(status))
|
||||
{
|
||||
errPrintf(status, __FILE__, __LINE__, "Can't connect to vector %d\n", omsInterruptVector + card);
|
||||
@@ -929,7 +931,7 @@ STATIC int motor_init()
|
||||
STATUS_REG statusReg;
|
||||
int8_t omsReg;
|
||||
long status;
|
||||
int card_index, motor_index, arg3, arg4;
|
||||
int card_index, motor_index;
|
||||
char axis_pos[50], encoder_pos[50];
|
||||
char *tok_save, *pos_ptr;
|
||||
int total_encoders = 0, total_axis = 0, total_pidcnt = 0;
|
||||
@@ -978,8 +980,8 @@ STATIC int motor_init()
|
||||
if (PROBE_SUCCESS(status))
|
||||
{
|
||||
status = devRegisterAddress(__FILE__, OMS_ADDRS_TYPE,
|
||||
(void *) probeAddr, OMS_BRD_SIZE,
|
||||
(void **) &localaddr);
|
||||
(size_t) probeAddr, OMS_BRD_SIZE,
|
||||
(volatile void **) &localaddr);
|
||||
Debug(9, "motor_init: devRegisterAddress() status = %d\n", (int) status);
|
||||
if (!RTN_SUCCESS(status))
|
||||
{
|
||||
@@ -995,7 +997,7 @@ STATIC int motor_init()
|
||||
pmotorState = motor_state[card_index];
|
||||
pmotorState->localaddr = (char *) localaddr;
|
||||
pmotorState->motor_in_motion = 0;
|
||||
pmotorState->cmnd_response = OFF;
|
||||
pmotorState->cmnd_response = false;
|
||||
|
||||
pmotorState->irqdata = (struct irqdatastr *) NULL;
|
||||
/* Disable all interrupts */
|
||||
@@ -1104,35 +1106,17 @@ STATIC int motor_init()
|
||||
}
|
||||
}
|
||||
|
||||
motor_sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
any_motor_in_motion = 0;
|
||||
|
||||
FASTLOCKINIT(&queue_lock);
|
||||
FASTLOCK(&queue_lock);
|
||||
mess_queue.head = (struct mess_node *) NULL;
|
||||
mess_queue.tail = (struct mess_node *) NULL;
|
||||
FASTUNLOCK(&queue_lock);
|
||||
|
||||
FASTLOCKINIT(&freelist_lock);
|
||||
FASTLOCK(&freelist_lock);
|
||||
free_list.head = (struct mess_node *) NULL;
|
||||
free_list.tail = (struct mess_node *) NULL;
|
||||
FASTUNLOCK(&freelist_lock);
|
||||
|
||||
Debug(3, "Motors initialized\n");
|
||||
|
||||
if (sizeof(int) >= sizeof(char *))
|
||||
{
|
||||
arg3 = (int) (&oms58_access);
|
||||
arg4 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
arg3 = (int) ((long) &oms58_access >> 16);
|
||||
arg4 = (int) ((long) &oms58_access & 0xFFFF);
|
||||
}
|
||||
taskSpawn((char *) "Oms58_motor", 64, VX_FP_TASK | VX_STDIO, 5000, motor_task,
|
||||
motor_scan_rate, arg3, arg4, 0, 0, 0, 0, 0, 0, 0);
|
||||
epicsThreadCreate((char *) "Oms58_motor", 64, 5000, (EPICSTHREADFUNC) motor_task, (void *) &targs);
|
||||
|
||||
Debug(3, "Started motor_task\n");
|
||||
return (0);
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... devSoft.c
|
||||
USAGE... Motor record device level support for Soft channel.
|
||||
|
||||
Version: $Revision: 1.7 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:43:17 $
|
||||
Last Modified: $Date: 2002-10-21 21:08:59 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -45,18 +45,11 @@ NOTES...
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <dbDefs.h>
|
||||
#include <dbFldTypes.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <dbAccess.h>
|
||||
#include <dbEvent.h>
|
||||
#include <recSup.h>
|
||||
}
|
||||
#else
|
||||
#include <dbEvent.h>
|
||||
#include <recSup.h>
|
||||
#endif
|
||||
|
||||
#include "motorRecord.h"
|
||||
#include "motor.h"
|
||||
@@ -66,7 +59,7 @@ extern "C" {
|
||||
|
||||
STATIC long update(struct motorRecord *);
|
||||
STATIC long start(struct motorRecord *);
|
||||
STATIC long build(motor_cmnd, double *, struct motorRecord *);
|
||||
STATIC RTN_STATUS build(motor_cmnd, double *, struct motorRecord *);
|
||||
STATIC long end(struct motorRecord *);
|
||||
STATIC void soft_process(struct motorRecord *);
|
||||
|
||||
@@ -103,7 +96,7 @@ STATIC long update(struct motorRecord *mr)
|
||||
|
||||
STATIC long start(struct motorRecord *mr)
|
||||
{
|
||||
return((long) OK);
|
||||
return((long) 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,14 +106,14 @@ STATIC long end(struct motorRecord *mr)
|
||||
|
||||
if (ptr->default_done_behavior == YES)
|
||||
mr->msta = RA_DONE;
|
||||
return((long) OK);
|
||||
return((long) 0);
|
||||
}
|
||||
|
||||
|
||||
STATIC long build(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
STATIC RTN_STATUS build(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
{
|
||||
const short int stop = 1;
|
||||
long status;
|
||||
long int status;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
@@ -154,7 +147,7 @@ STATIC long build(motor_cmnd command, double *parms, struct motorRecord *mr)
|
||||
default:
|
||||
status = ERROR;
|
||||
}
|
||||
return(status);
|
||||
return(status == 0 ? OK : ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -191,8 +184,8 @@ void soft_dinp_func(struct motorRecord *mr, short newdinp)
|
||||
{
|
||||
if (mr->dmov == FALSE)
|
||||
ptr->dinp_value = SOFTMOVE;
|
||||
else /* Hard motor is moving independent of soft motor. */
|
||||
{
|
||||
else if (mr->lock == menuYesNoNO)
|
||||
{ /* Hard motor is moving independent of soft motor. */
|
||||
unsigned short mask = (DBE_VALUE | DBE_LOG);
|
||||
|
||||
ptr->dinp_value = HARDMOVE;
|
||||
@@ -232,7 +225,7 @@ void soft_rdbl_func(struct motorRecord *mr, double newrdbl)
|
||||
newrdbl = newrdbl / mr->mres;
|
||||
mr->rmp = NINT(newrdbl);
|
||||
|
||||
if (ptr->initialized == OFF)
|
||||
if (ptr->initialized == false)
|
||||
{
|
||||
/* Reset Target to Actual position. */
|
||||
unsigned short mask = (DBE_VALUE | DBE_LOG);
|
||||
@@ -243,7 +236,7 @@ void soft_rdbl_func(struct motorRecord *mr, double newrdbl)
|
||||
db_post_events(mr, &mr->pp, mask);
|
||||
|
||||
ptr->dinp_value = DONE;
|
||||
ptr->initialized = ON;
|
||||
ptr->initialized = true;
|
||||
}
|
||||
soft_process(mr);
|
||||
}
|
||||
@@ -282,7 +275,7 @@ void soft_motor_callback(CALLBACK *cbptr)
|
||||
{
|
||||
struct motorRecord *mr;
|
||||
|
||||
callbackGetUser(mr, cbptr);
|
||||
callbackGetUser((void *) mr, cbptr);
|
||||
soft_process(mr);
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ FILENAME.. devSoft.h
|
||||
USAGE... This file contains information that is common to
|
||||
all Soft channel device support modules.
|
||||
|
||||
Version: $Revision: 1.6 $
|
||||
Version: $Revision: 1.7 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:40:57 $
|
||||
Last Modified: $Date: 2002-10-21 21:09:31 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -32,6 +32,8 @@ Last Modified: $Date: 2002-07-05 19:40:57 $
|
||||
#ifndef INCdevSofth
|
||||
#define INCdevSofth 1
|
||||
|
||||
#include <callback.h>
|
||||
|
||||
typedef enum DONE_STATES {SOFTMOVE = 0, HARDMOVE = 1, DONE = 2} DONE_STATES;
|
||||
|
||||
#define MAXMSGS 20
|
||||
@@ -40,19 +42,15 @@ struct soft_private
|
||||
{
|
||||
CALLBACK callback;
|
||||
long callback_flag;
|
||||
#ifdef DMR_SOFTMOTOR_MODS
|
||||
BOOLEAN load_position;
|
||||
long new_position;
|
||||
#endif
|
||||
DONE_STATES dinp_value; /* Value from DINP link. */
|
||||
BOOLEAN default_done_behavior; /* If the DINP is not programmed, exhibit
|
||||
bool default_done_behavior; /* If the DINP is not programmed, exhibit
|
||||
* "immediate done" default behavior. */
|
||||
BOOLEAN initialized; /* 1st RDBL call after interruptAccept is TRUE
|
||||
bool initialized; /* 1st RDBL call after interruptAccept is TRUE
|
||||
* sets this ON. */
|
||||
};
|
||||
|
||||
extern long soft_init(int);
|
||||
extern long soft_init_record(struct motorRecord *);
|
||||
extern long soft_init(void *);
|
||||
extern long soft_init_record(void *);
|
||||
extern void soft_dinp_func(struct motorRecord *, short);
|
||||
extern void soft_rdbl_func(struct motorRecord *, double);
|
||||
extern void soft_rinp_func(struct motorRecord *, long);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
FILENAME... devSoftAux.c
|
||||
USAGE... Motor record device level support for Soft channel.
|
||||
|
||||
Version: $Revision: 1.5 $
|
||||
Version: $Revision: 1.1 $
|
||||
Modified By: $Author: sluiter $
|
||||
Last Modified: $Date: 2002-07-05 19:42:20 $
|
||||
Last Modified: $Date: 2002-10-21 21:09:00 $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -36,15 +36,14 @@ in the same file; each defines (redefines) the DBR's.
|
||||
*/
|
||||
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <taskLib.h>
|
||||
#include <msgQLib.h>
|
||||
#include <cadef.h>
|
||||
#include <logLib.h>
|
||||
#include <errlog.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <epicsRingPointer.h>
|
||||
#include <callback.h>
|
||||
#include <epicsThread.h>
|
||||
|
||||
#include "motorRecord.h"
|
||||
|
||||
typedef enum BOOLEAN_VALUES {OFF = 0, ON = 1} BOOLEAN;
|
||||
#include "devSoft.h"
|
||||
|
||||
#define STATIC static
|
||||
@@ -52,9 +51,10 @@ typedef enum BOOLEAN_VALUES {OFF = 0, ON = 1} BOOLEAN;
|
||||
STATIC void soft_dinp(struct event_handler_args);
|
||||
STATIC void soft_rdbl(struct event_handler_args);
|
||||
STATIC void soft_rinp(struct event_handler_args);
|
||||
STATIC int soft_motor_task(int, int, int, int, int, int, int, int, int, int);
|
||||
STATIC SEM_ID soft_motor_sem;
|
||||
STATIC MSG_Q_ID soft_motor_msgQ;
|
||||
STATIC EPICSTHREADFUNC soft_motor_task(void *);
|
||||
STATIC epicsThreadId soft_motor_id;
|
||||
STATIC epicsEventId soft_motor_sem;
|
||||
STATIC epicsRingPointerId soft_motor_msgQ;
|
||||
|
||||
STATIC void soft_dinp(struct event_handler_args args)
|
||||
{
|
||||
@@ -72,51 +72,65 @@ STATIC void soft_rinp(struct event_handler_args args)
|
||||
soft_rinp_func((struct motorRecord *) args.usr, *((long *) args.dbr));
|
||||
}
|
||||
|
||||
long soft_init(int after)
|
||||
long soft_init(void *after)
|
||||
{
|
||||
if (after == 0)
|
||||
int before_after = (int) after;
|
||||
if (before_after == 0)
|
||||
{
|
||||
int dbCaTask_tid, soft_motor_priority;
|
||||
epicsThreadId dbCaTask_tid;
|
||||
unsigned int soft_motor_priority;
|
||||
int retry = 0;
|
||||
|
||||
soft_motor_sem = epicsEventCreate(epicsEventEmpty);
|
||||
soft_motor_msgQ = epicsRingPointerCreate(MAXMSGS);
|
||||
|
||||
/*
|
||||
* Fix for DMOV processing before the last DRBV update; i.e., lower
|
||||
* the priority of the "soft_motor" task below the priority of the
|
||||
* "dbCaLink" task.
|
||||
*/
|
||||
dbCaTask_tid = taskNameToId("dbCaLink");
|
||||
if (dbCaTask_tid == ERROR)
|
||||
logMsg((char *) "soft_init(): dbCaLink not found.\n", 0, 0, 0, 0, 0, 0);
|
||||
taskPriorityGet(dbCaTask_tid, &soft_motor_priority);
|
||||
soft_motor_priority += 1;
|
||||
while((dbCaTask_tid = epicsThreadGetId("dbCaLink")) == 0 && retry < 10)
|
||||
{
|
||||
epicsThreadSleep(0.1);
|
||||
retry++;
|
||||
}
|
||||
|
||||
soft_motor_sem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
|
||||
soft_motor_msgQ = msgQCreate(MAXMSGS, 4, MSG_Q_FIFO);
|
||||
taskSpawn((char *) "soft_motor", soft_motor_priority,
|
||||
VX_FP_TASK | VX_STDIO, 5000, soft_motor_task, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0);
|
||||
if (dbCaTask_tid == 0)
|
||||
{
|
||||
errMessage(0, "cannot find dbCaLink task.");
|
||||
return(-1);
|
||||
}
|
||||
soft_motor_priority = epicsThreadGetPriority(dbCaTask_tid);
|
||||
soft_motor_priority -= 1;
|
||||
|
||||
soft_motor_id = epicsThreadCreate((char *) "soft_motor", soft_motor_priority, 5000,
|
||||
(EPICSTHREADFUNC) soft_motor_task, NULL);
|
||||
}
|
||||
else
|
||||
semGive(soft_motor_sem); /* Start soft_motor_task(). */
|
||||
return((long) OK);
|
||||
epicsEventSignal(soft_motor_sem); /* Start soft_motor_task(). */
|
||||
return((long) 0);
|
||||
}
|
||||
|
||||
|
||||
long soft_init_record(struct motorRecord *mr)
|
||||
long soft_init_record(void *arg)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) arg;
|
||||
struct soft_private *ptr;
|
||||
CALLBACK *cbptr;
|
||||
STATUS status;
|
||||
int status = 0;
|
||||
static int count = 0;
|
||||
|
||||
if (++count > MAXMSGS)
|
||||
return(ERROR);
|
||||
status = msgQSend(soft_motor_msgQ, (char *) &mr, 4, NO_WAIT,
|
||||
MSG_PRI_NORMAL);
|
||||
return(-1);
|
||||
|
||||
if (!epicsRingPointerPush(soft_motor_msgQ, (void *) mr))
|
||||
status = -1;
|
||||
|
||||
/* Allocate space for private field. */
|
||||
mr->dpvt = (struct soft_private *) malloc(sizeof(struct soft_private));
|
||||
ptr = (struct soft_private *) mr->dpvt;
|
||||
ptr->dinp_value = (mr->dmov == 0) ? SOFTMOVE : DONE; /* Must match after initialzation. */
|
||||
ptr->initialized = OFF;
|
||||
ptr->initialized = false;
|
||||
|
||||
cbptr = &ptr->callback;
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) soft_motor_callback,
|
||||
@@ -127,25 +141,25 @@ long soft_init_record(struct motorRecord *mr)
|
||||
}
|
||||
|
||||
|
||||
STATIC int soft_motor_task(int a1, int a2, int a3, int a4, int a5, int a6,
|
||||
int a7, int a8, int a9, int a10)
|
||||
STATIC EPICSTHREADFUNC soft_motor_task(void *parm)
|
||||
{
|
||||
struct motorRecord *mr;
|
||||
chid dinp, rdbl, rinp;
|
||||
|
||||
semTake(soft_motor_sem, WAIT_FOREVER); /* Wait for dbLockInitRecords() to execute. */
|
||||
SEVCHK(ca_task_initialize(),"ca_task_initialize");
|
||||
epicsEventWait(soft_motor_sem); /* Wait for dbLockInitRecords() to execute. */
|
||||
SEVCHK(ca_context_create(ca_enable_preemptive_callback),
|
||||
"soft_motor_task: ca_context_create() error");
|
||||
|
||||
while (msgQReceive(soft_motor_msgQ, (char *) &mr, 4, NO_WAIT) != ERROR)
|
||||
while ((mr = (struct motorRecord *) epicsRingPointerPop(soft_motor_msgQ)))
|
||||
{
|
||||
struct soft_private *ptr = (struct soft_private *) mr->dpvt;
|
||||
if (mr->dinp.value.constantStr == NULL)
|
||||
{
|
||||
ptr->default_done_behavior = ON;
|
||||
ptr->default_done_behavior = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->default_done_behavior = OFF;
|
||||
ptr->default_done_behavior = false;
|
||||
SEVCHK(ca_search(mr->dinp.value.pv_link.pvname, &dinp),
|
||||
"ca_search() failure");
|
||||
SEVCHK(ca_add_event(DBR_SHORT, dinp, soft_dinp, mr, NULL),"ca_add_event() failure");
|
||||
@@ -167,8 +181,8 @@ STATIC int soft_motor_task(int a1, int a2, int a3, int a4, int a5, int a6,
|
||||
}
|
||||
}
|
||||
|
||||
msgQDelete(soft_motor_msgQ);
|
||||
taskSuspend(NULL); /* Wait Forever. */
|
||||
return(ERROR);
|
||||
epicsRingPointerDelete(soft_motor_msgQ);
|
||||
epicsThreadSuspendSelf(); /* Wait Forever. */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user