Converted to R3.14.x and C++.

This commit is contained in:
Ron Sluiter
2002-10-21 21:10:48 +00:00
parent 9559b510a6
commit 666480bcdf
16 changed files with 500 additions and 652 deletions
+15 -27
View File
@@ -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;
}
+7 -8
View File
@@ -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);
}
+24 -14
View File
@@ -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 */
+10 -7
View File
@@ -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)
{
+3 -3
View File
@@ -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);
}
+8 -10
View File
@@ -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);
}