forked from epics_driver_modules/motorBase
Removing support for Highland V544.
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
TOP=../..
|
||||
include $(TOP)/configure/CONFIG_APP
|
||||
include $(TOP)/configure/RULES_ARCHS
|
||||
@@ -1,4 +0,0 @@
|
||||
# Highland V544 driver support.
|
||||
device(motor,VME_IO,devV544,"Highland V544")
|
||||
driver(drvV544)
|
||||
|
||||
@@ -1,688 +0,0 @@
|
||||
/* File: devV544.c */
|
||||
/* Version: 1.2a */
|
||||
/* Date Last Modified: 2/19/97 */
|
||||
|
||||
/* Device Support Routines for motor */
|
||||
/*
|
||||
* Original Author: Jim Kowalkowski
|
||||
* Current Author: Joe Sullivan
|
||||
* Date: 11/14/94
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 01-18-93 jbk initialized
|
||||
* .02 11-14-94 jps copy devOms.c and modify to point to vme58 driver
|
||||
* .03 ??-??-95 jps copy devOms58.c and modify to point to Highland driver
|
||||
* .04 06-20-96 jps allow for bumpless-reboot on position
|
||||
* .04a 02-19-97 tmm fixed for EPICS 3.13
|
||||
*/
|
||||
|
||||
#define VERSION 1.3
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdioLib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <semLib.h> /* jps: include for init_record wait */
|
||||
#include <alarm.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <callback.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
}
|
||||
#else
|
||||
#include <callback.h>
|
||||
#include <dbAccess.h>
|
||||
#include <recSup.h>
|
||||
#endif
|
||||
#include <dbDefs.h>
|
||||
#include <dbCommon.h>
|
||||
#include <fast_lock.h>
|
||||
#include <devSup.h>
|
||||
#include <drvSup.h>
|
||||
|
||||
#include "motorRecord.h"
|
||||
#include "motor.h"
|
||||
#include "drvV544.h"
|
||||
|
||||
#define PRIVATE_FUNCTIONS 0 /* normal:1, debug:0 */
|
||||
|
||||
#define STATIC
|
||||
|
||||
#ifdef NODEBUG
|
||||
#define Debug(L,FMT,V) ;
|
||||
#else
|
||||
#define Debug(L,FMT,V) { if(L <= devV544debug) \
|
||||
{ printf("%s(%d):",__FILE__,__LINE__); \
|
||||
printf(FMT,V); } }
|
||||
#endif
|
||||
|
||||
#define NINT(f) (long)((f)>0 ? (f)+0.5 : (f)-0.5) /* tmm */
|
||||
|
||||
/* ----------------Create the dsets for devV544----------------- */
|
||||
static long report();
|
||||
STATIC long v544_init(int after);
|
||||
STATIC long v544_init_record(struct motorRecord *);
|
||||
STATIC long get_ioint_info();
|
||||
STATIC long v544_start_trans(struct motorRecord *);
|
||||
STATIC long v544_update_values(struct motorRecord *);
|
||||
STATIC long v544_build_trans(motor_cmnd, double *, struct motorRecord *);
|
||||
STATIC long v544_end_trans(struct motorRecord *);
|
||||
STATIC void v544_callback(MOTOR_RETURN *);
|
||||
STATIC void v544_init_callback(MOTOR_RETURN *);
|
||||
|
||||
struct motor_dset devV544 =
|
||||
{
|
||||
{8, NULL, v544_init, v544_init_record, NULL},
|
||||
v544_update_values,
|
||||
v544_start_trans,
|
||||
v544_build_trans,
|
||||
v544_end_trans
|
||||
};
|
||||
|
||||
/* xxDSET devXxxx={ 5,report,init,init_rec,get_ioint_info,read_write}; */
|
||||
|
||||
/* --------------------------- program data --------------------- */
|
||||
|
||||
volatile int devV544debug = 0;
|
||||
|
||||
|
||||
struct v544_motor_table
|
||||
{
|
||||
int type;
|
||||
uint16_t command;
|
||||
int num_parms;
|
||||
};
|
||||
|
||||
/* WARNING! this must match "motor_cmnd" in motor.h */
|
||||
|
||||
static struct v544_motor_table v544_table[] = {
|
||||
/* type cmd num_parms */
|
||||
{MOTION, CS_MOVE_ABS, 1}, /* MOVE_ABS */
|
||||
{MOTION, CS_MOVE_INC, 1}, /* MOVE_REL */
|
||||
{MOTION, CS_SEEK_INDX, 1}, /* HOME_FOR */
|
||||
{MOTION, CS_SEEK_INDX, 1}, /* HOME_REV */
|
||||
{IMMEDIATE, CS_SET_POSITION, 1}, /* LOAD_POS */
|
||||
{IMMEDIATE, -1, 1}, /* SET_VELO_BASE - Not supported */
|
||||
{IMMEDIATE, -1, 1}, /* SET_VELO */
|
||||
{IMMEDIATE, -1, 1}, /* SET_ACCEL */
|
||||
{IMMEDIATE, CS_GO, 0}, /* GO */
|
||||
{IMMEDIATE, -1, 2}, /* SET_ENC_RATIO - Not supported */
|
||||
{INFO, -1, 0}, /* GET_INFO */
|
||||
{MOVE_TERM, CS_IDLE, 0}, /* STOP_AXIS */
|
||||
{VELOCITY, -1, 1}, /* JOG */
|
||||
{UNDEFINED, 0, 0}, /* SET_PGAIN */
|
||||
{UNDEFINED, 0, 0}, /* SET_IGAIN */
|
||||
{UNDEFINED, 0, 0}, /* SET_DGAIN */
|
||||
{UNDEFINED, 0, 0}, /* ENABLE_TORQUE */
|
||||
{UNDEFINED, 0, 0}, /* DISABL_TORQUE */
|
||||
{UNDEFINED, 0, 0}, /* PRIMITIVE */
|
||||
{UNDEFINED, 0, 0}, /* SET_HIGH_LIMIT */
|
||||
{UNDEFINED, 0, 0}, /* SET_LOW_LIMIT */
|
||||
{VELOCITY, 0, 0} /* JOG_VELOCITY */
|
||||
};
|
||||
|
||||
/* status of an axis of a board, one present for each axis of each board*/
|
||||
struct a_axis
|
||||
{
|
||||
/*??? int encoder_present; */
|
||||
int in_use;
|
||||
};
|
||||
|
||||
/* the device private data structure of the record */
|
||||
struct v544_trans
|
||||
{
|
||||
int state;
|
||||
FAST_LOCK lock;
|
||||
MOTOR_CALL motor_call;
|
||||
int callback_changed;
|
||||
int32_t motor_pos;
|
||||
int32_t encoder_pos;
|
||||
int32_t vel;
|
||||
unsigned long status;
|
||||
SEM_ID initSem;
|
||||
};
|
||||
|
||||
/* the board status structure */
|
||||
struct v544_stat
|
||||
{
|
||||
int exists;
|
||||
int total_axis;
|
||||
struct a_axis *v544_axis;
|
||||
};
|
||||
|
||||
STATIC struct v544_stat *v544_cards;
|
||||
extern struct v544_support v544_access;
|
||||
|
||||
#define IDLE_STATE 0
|
||||
#define BUILD_STATE 1
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
#define SEM_TIMEOUT 50
|
||||
|
||||
|
||||
/* --------------------------- program data --------------------- */
|
||||
|
||||
/* initialize device support for V544 stepper motor */
|
||||
STATIC long v544_init(int after)
|
||||
{
|
||||
MOTOR_CARD_QUERY card_query;
|
||||
int i, j;
|
||||
|
||||
Debug(1, "v544_init: entry...\n", 0);
|
||||
if (after)
|
||||
return (0);
|
||||
|
||||
/* allocate space for total cards in system */
|
||||
v544_cards = (struct v544_stat *) malloc(V544_NUM_CARDS *
|
||||
sizeof(struct v544_stat));
|
||||
|
||||
/* for each card ask driver for num of axis supported and name */
|
||||
for (i = 0; i < V544_NUM_CARDS; i++)
|
||||
{
|
||||
(*v544_access.get_card_info) (i, &card_query);
|
||||
|
||||
if (card_query.total_axis == 0)
|
||||
v544_cards[i].exists = NO;
|
||||
else
|
||||
{
|
||||
v544_cards[i].exists = YES;
|
||||
v544_cards[i].total_axis = card_query.total_axis;
|
||||
Debug(5, "v544_init: calling malloc(card_query...)\n total axis =%d\n",
|
||||
v544_cards[i].total_axis);
|
||||
v544_cards[i].v544_axis = (struct a_axis *) malloc(
|
||||
card_query.total_axis * sizeof(struct a_axis));
|
||||
|
||||
for (j = 0; j < card_query.total_axis; j++)
|
||||
v544_cards[i].v544_axis[j].in_use = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Debug(1, "v544_init: exit...\n", 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* initialize a record instance */
|
||||
STATIC long v544_init_record(struct motorRecord * mr)
|
||||
{
|
||||
int card, signal;
|
||||
int initEncoder, initPos;
|
||||
struct v544_trans *ptrans;
|
||||
MOTOR_AXIS_QUERY axis_query;
|
||||
MOTOR_CALL *motor_call;
|
||||
double ep_mp[2]; /* encoder pulses, motor pulses */
|
||||
int rtnStat;
|
||||
|
||||
Debug(1, "v544_init_record: entry...\n", 0);
|
||||
|
||||
/* allocate space for private field - an v544_trans structure */
|
||||
Debug(5, "v544_init_record: calling malloc(...v544_trans...)\n", 0);
|
||||
mr->dpvt = (struct v544_trans *) malloc(sizeof(struct v544_trans));
|
||||
|
||||
ptrans = mr->dpvt;
|
||||
ptrans->state = IDLE_STATE;
|
||||
ptrans->callback_changed = NO;
|
||||
FASTLOCKINIT(&ptrans->lock);
|
||||
motor_call = &(ptrans->motor_call);
|
||||
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) v544_callback,
|
||||
&(motor_call->callback));
|
||||
callbackSetPriority(priorityMedium, &(motor_call->callback));
|
||||
|
||||
/* check if axis already in use, then mark card, axis as in use */
|
||||
|
||||
/* out must be an VME_IO */
|
||||
switch (mr->out.type)
|
||||
{
|
||||
case (VME_IO):
|
||||
break;
|
||||
default:
|
||||
recGblRecordError(S_dev_badBus, (void *) mr,
|
||||
(char *) "devV544 (init_record) Illegal OUT Bus Type");
|
||||
return (S_dev_badBus);
|
||||
}
|
||||
|
||||
card = mr->out.value.vmeio.card;
|
||||
Debug(5, "v544_init_record: card %d\n", card);
|
||||
signal = mr->out.value.vmeio.signal;
|
||||
Debug(5, "v544_init_record: signal %d\n", signal);
|
||||
|
||||
rtnStat = 0;
|
||||
|
||||
if (card < 0 || card >= V544_NUM_CARDS || v544_cards[card].exists == NO)
|
||||
{
|
||||
recGblRecordError(S_db_badField, (void *) mr,
|
||||
(char *) "devV544 (init_record) card does not exist!");
|
||||
rtnStat = S_db_badField;
|
||||
}
|
||||
else if (signal < 0 || signal >= v544_cards[card].total_axis)
|
||||
{
|
||||
recGblRecordError(S_db_badField, (void *) mr,
|
||||
(char *) "devV544 (init_record) signal does not exist!");
|
||||
rtnStat = S_db_badField;
|
||||
}
|
||||
else if (v544_cards[card].v544_axis[signal].in_use == YES)
|
||||
{
|
||||
recGblRecordError(S_db_badField, (void *) mr,
|
||||
"(char *) devV544 (init_record) motor already in use!");
|
||||
rtnStat = S_db_badField;
|
||||
}
|
||||
|
||||
if (rtnStat)
|
||||
{
|
||||
/* Initialize readback fields for simulation */
|
||||
mr->msta = RA_PROBLEM;
|
||||
mr->rmp = 0; /* raw motor pulse count */
|
||||
mr->rep = 0; /* raw encoder pulse count */
|
||||
return (rtnStat);
|
||||
}
|
||||
else
|
||||
/* query motor for all info to fill into record */
|
||||
(*v544_access.get_axis_info) (card, signal, &axis_query);
|
||||
|
||||
mr->msta = axis_query.status; /* status info */
|
||||
|
||||
v544_cards[card].v544_axis[signal].in_use = YES;
|
||||
|
||||
|
||||
/*jps: setting the encoder ratio was moved from init_record() remove callbacks during iocInit */
|
||||
/*
|
||||
* Set the encoder ratio. Note this is blatantly device dependent.
|
||||
* Determine the number of encoder pulses and the number of motor pulses
|
||||
* per engineering unit (EGU). Send an array containing this information
|
||||
* to device support.
|
||||
*/
|
||||
if ((initEncoder = (mr->msta & EA_PRESENT)) && mr->ueip)
|
||||
{
|
||||
if (fabs(mr->mres) < 1.e-9)
|
||||
mr->mres = 1.;
|
||||
if (fabs(mr->eres) < 1.e-9)
|
||||
mr->eres = mr->mres;
|
||||
{
|
||||
int m;
|
||||
for (m=10000000; (m > 1) &&
|
||||
(fabs(m/mr->eres) > 1.e6 || fabs(m/mr->mres) > 1.e6);
|
||||
m /= 10)
|
||||
;
|
||||
Debug(5, "oms58_init_record: ER mult = %d\n", m);
|
||||
ep_mp[0] = m / mr->eres; /* encoder pulses per ...*/
|
||||
ep_mp[1] = m / mr->mres; /* motor pulses */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ep_mp[0] = 1.;
|
||||
ep_mp[1] = 1.;
|
||||
}
|
||||
|
||||
|
||||
/* Program the device if an initial position is programmed or
|
||||
* an encoder is present. */
|
||||
|
||||
if ((initPos = (mr->dval && mr->mres)) || initEncoder)
|
||||
{
|
||||
|
||||
/*
|
||||
* Semaphore used to hold initialization until device is programmed -
|
||||
* cleared by callback
|
||||
*/
|
||||
ptrans->initSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
|
||||
|
||||
/*
|
||||
* Switch to special init callback so that record will not be
|
||||
* processed during iocInit
|
||||
*/
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) v544_init_callback,
|
||||
&(motor_call->callback));
|
||||
|
||||
if (initEncoder)
|
||||
{
|
||||
Debug(7, "v544_init_record: encoder pulses per EGU = %f\n", ep_mp[0]);
|
||||
Debug(7, "v544_init_record: motor pulses per EGU = %f\n", ep_mp[1]);
|
||||
|
||||
|
||||
v544_start_trans(mr);
|
||||
v544_build_trans(SET_ENC_RATIO, ep_mp, mr);
|
||||
v544_end_trans(mr);
|
||||
}
|
||||
|
||||
if (initPos)
|
||||
{
|
||||
double setPos = mr->dval / mr->mres;
|
||||
|
||||
Debug(7, "v544_init_record: initial raw position = %f\n", setPos);
|
||||
|
||||
v544_start_trans(mr);
|
||||
v544_build_trans(LOAD_POS, &setPos, mr);
|
||||
v544_end_trans(mr);
|
||||
}
|
||||
|
||||
/* Changing positions or encoder ratio may have
|
||||
* changed the readback value. */
|
||||
v544_start_trans(mr);
|
||||
v544_build_trans(GET_INFO, NULL, mr);
|
||||
v544_end_trans(mr);
|
||||
|
||||
/* Wait for callback w/timeout */
|
||||
if ((rtnStat = semTake(ptrans->initSem, SEM_TIMEOUT)) == ERROR)
|
||||
{
|
||||
recGblRecordError(S_dev_NoInit, (void *) mr,
|
||||
(char *) "dev_NoInit (init_record: callback2 timeout");
|
||||
}
|
||||
semDelete(ptrans->initSem);
|
||||
|
||||
/* Restore regular record callback */
|
||||
callbackSetCallback((void (*)(struct callbackPvt *)) v544_callback,
|
||||
&(motor_call->callback));
|
||||
}
|
||||
|
||||
|
||||
/* query motor for all info to fill into record */
|
||||
|
||||
(*v544_access.get_axis_info) (card, signal, &axis_query);
|
||||
|
||||
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 */
|
||||
Debug(7, "v544_init_record: rmp = %f\n", mr->rmp);
|
||||
Debug(7, "v544_init_record: rep = %f\n", mr->rep);
|
||||
Debug(7, "v544_init_record: msta = %d\n", mr->msta);
|
||||
|
||||
Debug(1, "v544_init_record: exit...\n", 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
STATIC long v544_update_values(struct motorRecord * mr)
|
||||
{
|
||||
struct v544_trans *ptrans;
|
||||
long rc;
|
||||
|
||||
rc = NOTHING_DONE;
|
||||
ptrans = (struct v544_trans *) mr->dpvt;
|
||||
|
||||
FASTLOCK(&ptrans->lock);
|
||||
|
||||
/* raw motor pulse count */
|
||||
if (ptrans->callback_changed == YES)
|
||||
{
|
||||
mr->rmp = ptrans->motor_pos;
|
||||
mr->rep = ptrans->encoder_pos;
|
||||
mr->rvel = ptrans->vel;
|
||||
mr->msta = ptrans->status;
|
||||
ptrans->callback_changed = NO;
|
||||
rc = CALLBACK_DATA;
|
||||
}
|
||||
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
||||
/* start building a transaction */
|
||||
STATIC long v544_start_trans(struct motorRecord * mr)
|
||||
{
|
||||
int card = mr->out.value.vmeio.card;
|
||||
int axis = mr->out.value.vmeio.signal;
|
||||
struct v544_trans *trans = (struct v544_trans *) mr->dpvt;
|
||||
MOTOR_CALL *motor_call;
|
||||
CMND_DEF *motor_cmnd;
|
||||
|
||||
if (!mr->dpvt)
|
||||
return (S_dev_NoInit);
|
||||
|
||||
motor_call = &(trans->motor_call);
|
||||
|
||||
/*
|
||||
* initialize area to device private field to store command that is to be
|
||||
* built and mark as command build in progress
|
||||
*/
|
||||
|
||||
trans->state = BUILD_STATE;
|
||||
motor_call->card = card;
|
||||
motor_call->signal = axis;
|
||||
motor_call->type = UNDEFINED;
|
||||
motor_call->precord = (struct dbCommon *) mr;
|
||||
motor_call->cmndCnt = 0;
|
||||
motor_call->cmndIndx = 0;
|
||||
|
||||
/* Zero command define structure */
|
||||
bzero((void *)motor_call->cmndList, sizeof(CMND_DEF)*MAX_LIST_SIZE);
|
||||
|
||||
Debug(3, "v544_start_trans: motor %d command started\n", (card * V544_NUM_CHANNELS) + axis);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* end building a transaction */
|
||||
STATIC long v544_end_trans(struct motorRecord * mr)
|
||||
{
|
||||
struct v544_trans *trans = (struct v544_trans *) mr->dpvt;
|
||||
MOTOR_CALL *motor_call;
|
||||
long rc;
|
||||
int card = mr->out.value.vmeio.card;
|
||||
int axis = mr->out.value.vmeio.signal;
|
||||
|
||||
|
||||
rc = 0;
|
||||
motor_call = &(trans->motor_call);
|
||||
|
||||
switch (trans->state)
|
||||
{
|
||||
case BUILD_STATE:
|
||||
/* shut off command build in process thing */
|
||||
trans->state = IDLE_STATE;
|
||||
|
||||
Debug(3, "v544_end_trans: motor %d command send\n", (card * V544_NUM_CHANNELS) + axis);
|
||||
|
||||
rc = (*v544_access.send) (motor_call);
|
||||
break;
|
||||
|
||||
case IDLE_STATE:
|
||||
default:
|
||||
rc = ERROR;
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/* add a part to the transaction */
|
||||
STATIC long v544_build_trans(motor_cmnd command, double *parms, struct motorRecord * mr)
|
||||
{
|
||||
struct v544_trans *trans = (struct v544_trans *) mr->dpvt;
|
||||
MOTOR_CALL *motor_call;
|
||||
char buffer[20];
|
||||
int parmInt;
|
||||
int first_one, i;
|
||||
|
||||
motor_call = &(trans->motor_call);
|
||||
|
||||
if (v544_table[command].type == UNDEFINED)
|
||||
return(OK);
|
||||
|
||||
if (v544_table[command].type > motor_call->type)
|
||||
motor_call->type = v544_table[command].type;
|
||||
|
||||
if (devV544debug >= 4)
|
||||
printf("build_trans: v544 cmndCode %d, cmndParm %12.4f\n", command, *parms);
|
||||
|
||||
/* concatenate onto the dpvt message field */
|
||||
switch (trans->state)
|
||||
{
|
||||
case BUILD_STATE:
|
||||
/* put in command */
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case MOVE_ABS:
|
||||
case MOVE_REL:
|
||||
case HOME_FOR:
|
||||
case HOME_REV:
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= v544_table[command].command;
|
||||
motor_call->cmndList[motor_call->cmndCnt].pos = NINT(*parms);
|
||||
break;
|
||||
case LOAD_POS:
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= v544_table[command].command;
|
||||
motor_call->cmndList[motor_call->cmndCnt].pos = NINT(*parms);
|
||||
motor_call->cmndCnt++;
|
||||
break;
|
||||
case SET_VEL_BASE:
|
||||
break;
|
||||
case SET_VELOCITY:
|
||||
parmInt = NINT(*parms/(double)VEL_SCALE);
|
||||
motor_call->cmndList[motor_call->cmndCnt].vel = parmInt;
|
||||
break;
|
||||
case SET_ACCEL:
|
||||
parmInt = NINT(*parms/(double)(ACC_SCALE*ACC_SCALE));
|
||||
if (parmInt == 0)
|
||||
parmInt = 1;
|
||||
motor_call->cmndList[motor_call->cmndCnt].accel = parmInt;
|
||||
break;
|
||||
case GO:
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= v544_table[command].command;
|
||||
motor_call->cmndCnt++;
|
||||
break;
|
||||
case SET_ENC_RATIO:
|
||||
case GET_INFO:
|
||||
motor_call->cmndCnt++;
|
||||
break;
|
||||
case STOP_AXIS:
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= CS_IDLE;
|
||||
motor_call->cmndList[motor_call->cmndCnt].vel = 0;
|
||||
motor_call->cmndCnt++;
|
||||
break;
|
||||
case JOG:
|
||||
if (*parms >= 0)
|
||||
{
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= CS_RUN_CW;
|
||||
|
||||
parmInt = NINT(*parms/(double)VEL_SCALE);
|
||||
motor_call->cmndList[motor_call->cmndCnt].vel = parmInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
motor_call->cmndList[motor_call->cmndCnt].cmnd |= CS_RUN_CCW;
|
||||
parmInt = -1*NINT(*parms/(double)VEL_SCALE);
|
||||
motor_call->cmndList[motor_call->cmndCnt].vel = parmInt;
|
||||
}
|
||||
motor_call->cmndCnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDLE_STATE:
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* callback from V544 driver for motor in motion */
|
||||
STATIC void v544_callback(MOTOR_RETURN * motor_return)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) motor_return->precord;
|
||||
struct rset *prset = (struct rset *) (motor_return->precord->rset);
|
||||
struct v544_trans *ptrans;
|
||||
|
||||
Debug(5, "v544_callback: entry\n", 0);
|
||||
ptrans = (struct v544_trans *) mr->dpvt;
|
||||
|
||||
Debug(6, "v544_callback: FASTLOCK\n", 0);
|
||||
FASTLOCK(&ptrans->lock);
|
||||
|
||||
/* raw motor pulse count */
|
||||
Debug(6, "v544_callback: update ptrans\n", 0);
|
||||
ptrans->callback_changed = YES;
|
||||
ptrans->motor_pos = motor_return->position;
|
||||
/* raw encoder pulse count */
|
||||
ptrans->encoder_pos = motor_return->encoder_position;
|
||||
/* raw motor velocity */
|
||||
ptrans->vel = motor_return->velocity*VEL_SCALE;
|
||||
ptrans->status = motor_return->status; /* status */
|
||||
|
||||
if (devV544debug >= 4)
|
||||
printf("v544 callback: pos %d, enc %d, vel %d, status =0x%04x\n",
|
||||
ptrans->motor_pos, ptrans->encoder_pos,ptrans->vel, ptrans->status);
|
||||
|
||||
Debug(6, "v544_callback: FASTUNLOCK\n", 0);
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
|
||||
/* free the return data buffer */
|
||||
Debug(6, "v544_callback: free MOTOR_RETURN\n", 0);
|
||||
(*v544_access.free) (motor_return);
|
||||
|
||||
Debug(6, "v544_callback: dbScanLock\n", 0);
|
||||
dbScanLock((struct dbCommon *) mr);
|
||||
Debug(6, "v544_callback: calling process\n", 0);
|
||||
(*prset->process) ((struct dbCommon *) mr);
|
||||
Debug(6, "v544_callback: dbScanUnlock\n", 0);
|
||||
dbScanUnlock((struct dbCommon *) mr);
|
||||
Debug(5, "v544_callback: exit..\n", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* callback from V544 driver for init_record - duplicate of
|
||||
* the v544_callback without the call to process the record */
|
||||
STATIC void v544_init_callback(MOTOR_RETURN * motor_return)
|
||||
{
|
||||
struct motorRecord *mr = (struct motorRecord *) motor_return->precord;
|
||||
struct rset *prset = (struct rset *) (motor_return->precord->rset);
|
||||
struct v544_trans *ptrans;
|
||||
|
||||
Debug(5, "v544_init_callback: entry\n", 0);
|
||||
ptrans = (struct v544_trans *) mr->dpvt;
|
||||
|
||||
Debug(6, "v544_init_callback: FASTLOCK\n", 0);
|
||||
FASTLOCK(&ptrans->lock);
|
||||
|
||||
/* raw motor pulse count */
|
||||
Debug(6, "v544_init_callback: update ptrans\n", 0);
|
||||
ptrans->callback_changed = YES;
|
||||
ptrans->motor_pos = motor_return->position;
|
||||
/* raw encoder pulse count */
|
||||
ptrans->encoder_pos = motor_return->encoder_position;
|
||||
/* raw motor velocity */
|
||||
ptrans->vel = motor_return->velocity;
|
||||
|
||||
ptrans->status = motor_return->status; /* status */
|
||||
|
||||
/* free the return data buffer */
|
||||
Debug(6, "v544_init_callback: free MOTOR_RETURN\n", 0);
|
||||
(*v544_access.free) (motor_return);
|
||||
|
||||
/* Continue record init. */
|
||||
Debug(6, "v544_init_callback: Continue sig.\n", 0);
|
||||
semGive(ptrans->initSem);
|
||||
|
||||
Debug(6, "v544_init_callback: FASTUNLOCK\n", 0);
|
||||
FASTUNLOCK(&ptrans->lock);
|
||||
|
||||
Debug(5, "v544_init_callback: exit\n", 0);
|
||||
return;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,266 +0,0 @@
|
||||
/* File: drvV544.h */
|
||||
/* Version: 1.2 */
|
||||
/* Date Last Modified: 8/6/96 */
|
||||
|
||||
|
||||
/* Device Support Definitions for Highland motor controller */
|
||||
/*
|
||||
* Original Author: Jim Kowalkowski
|
||||
* Current Author: Joe Sullivan
|
||||
* Date: 11/14/94
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 01-18-93 jbk initialized
|
||||
* .02 11-14-94 jps copy drvOms.h and modify to point to vme58 driver
|
||||
* .03 ??-??-95 jps copy drvOms58.h and modify to point to Highland driver
|
||||
* ...
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* valid command types for the driver, the order is importance, 0 is of
|
||||
* lowest importance. Device support will choose the greatest one to use as
|
||||
* the driver transaction type.
|
||||
*/
|
||||
|
||||
#define UNDEFINED (unsigned char)0 /* garbage type */
|
||||
#define IMMEDIATE (unsigned char)1 /* 'i' an execute immediate, no reply */
|
||||
#define MOVE_TERM (unsigned char)2 /* 't' terminate a previous active
|
||||
* motion */
|
||||
#define MOTION (unsigned char)3 /* 'm' will produce motion updates */
|
||||
#define VELOCITY (unsigned char)4 /* 'v' make motion updates till
|
||||
* MOVE_TERM */
|
||||
#define INFO (unsigned char)5 /* 'f' get curr motor/encoder pos and
|
||||
* stat */
|
||||
#define QUERY (unsigned char)6 /* 'q' specialty type, not needed */
|
||||
|
||||
/* Set list size to accomidate the 2 move commands
|
||||
* when all parameters are being changed */
|
||||
#define MAX_LIST_SIZE 10
|
||||
|
||||
typedef struct CmndDef
|
||||
{
|
||||
int32_t pos;
|
||||
uint16_t vel;
|
||||
uint16_t accel;
|
||||
uint16_t standby; /* Drive current standby percent */
|
||||
uint16_t cmnd; /* Motion command (ABS,INC, HOME,...) */
|
||||
} CMND_DEF;
|
||||
|
||||
/* message queue management - device and driver support only */
|
||||
struct mess_node
|
||||
{
|
||||
CALLBACK callback;
|
||||
int signal;
|
||||
int card;
|
||||
unsigned char type;
|
||||
int cmndCnt; /* Number of commands in list */
|
||||
int cmndIndx; /* Current command index */
|
||||
CMND_DEF cmndList[MAX_LIST_SIZE];
|
||||
long position;
|
||||
long encoder_position;
|
||||
long velocity;
|
||||
unsigned long status;
|
||||
struct dbCommon *precord;
|
||||
struct mess_node *next;
|
||||
};
|
||||
typedef struct mess_node MOTOR_CALL;
|
||||
typedef struct mess_node MOTOR_RETURN;
|
||||
|
||||
typedef struct mess_card_query
|
||||
{
|
||||
char *card_name;
|
||||
int total_axis;
|
||||
} MOTOR_CARD_QUERY;
|
||||
|
||||
typedef struct mess_axis_query
|
||||
{
|
||||
long position;
|
||||
long encoder_position;
|
||||
unsigned long status;
|
||||
} MOTOR_AXIS_QUERY;
|
||||
|
||||
struct v544_support
|
||||
{
|
||||
int (*send) (MOTOR_CALL *);
|
||||
int (*free) (struct mess_node *);
|
||||
int (*get_card_info) (int, MOTOR_CARD_QUERY *);
|
||||
int (*get_axis_info) (int, int signal, MOTOR_AXIS_QUERY *);
|
||||
};
|
||||
|
||||
/* Board control register structures */
|
||||
|
||||
|
||||
/*
|
||||
* V544 default profile
|
||||
*/
|
||||
|
||||
#define V544_NUM_CARDS 8
|
||||
#define V544_NUM_CHANNELS 4
|
||||
#define V544_INTERRUPT_TYPE intVME
|
||||
#define V544_ADDRS_TYPE atVMEA16
|
||||
#define V544_NUM_ADDRS 0xDD00
|
||||
#define V544_INT_LEVEL 5 /* default interrupt level (1-6) */
|
||||
#define V544_BRD_SIZE 0x80 /* card address boundary */
|
||||
|
||||
/* Board type info */
|
||||
#define V544_LABEL "V544"
|
||||
#define V544_VXID 0xFEEE /* Manufacturer registered VXI ID */
|
||||
|
||||
#define BRD_OFFSET 0x80
|
||||
#define VXI_BASE 0xC000
|
||||
#define VXI_VECTOR(v) ((v-VXI_BASE)/0x40)
|
||||
|
||||
/* V544 Parameter Scaling Constants */
|
||||
/* (assuming half step scaling by the record */
|
||||
#define STEP_SCALE 256 /* Position scaling per step */
|
||||
#define VEL_SCALE 16 /* Velocity scaling per step/sec */
|
||||
#define ACC_SCALE 256 /* Acceleration scaling per step/sec/sec */
|
||||
|
||||
/* V544 Parameter Limits */
|
||||
#define MAX_VEL 4096
|
||||
#define MAX_ACCEL 65535
|
||||
#define MAX_POS (2**31)
|
||||
|
||||
/* V544 Control Register Definitions */
|
||||
|
||||
/* VCSR register status bits (board level status) */
|
||||
#define VCSR_RES 0x1 /* Soft Reset */
|
||||
#define VCSR_SFT 0x4 /* Self-test passed */
|
||||
#define VCSR_RDY 0x8 /* Ready to operate */
|
||||
#define VCSR_MOD 0x4000 /* Module ID 'off' */
|
||||
|
||||
/* VCSR register commands (board level commands) */
|
||||
#define VCSR_FRZ 0x8000 /* Board level freeze on motor positions updates */
|
||||
|
||||
/* OPTS (options) register status masks */
|
||||
#define OPTS_ENC 0x1 /* Encoder option enabled */
|
||||
#define OPTS_ACT 0x2 /* Encoder FPGA installed */
|
||||
#define OPTS_SER 0x4 /* Serial port enabled */
|
||||
|
||||
/* Per-axis Command/Status register definitions */
|
||||
/* status bits */
|
||||
#define CS_BUSY_TO 2 /* Maximum command ACK lantency in polling cycles */
|
||||
#define CS_ABORT_TO 1900 /* Dwell loop count for send_cmnd() check of abort bug */
|
||||
#define CS_ERROR 0x8000 /* Command error flag */
|
||||
#define CS_DONE 0x80 /* Command completed flag */
|
||||
#define CS_BUSY 0x40 /* Command accepted */
|
||||
|
||||
/* CMD codes (bits 0-4)*/
|
||||
#define CS_IDLE 0x0 /* Soft-reset - update status/position regs */
|
||||
#define CS_RUN_CW 0x1 /* Constant velocity - CW */
|
||||
#define CS_RUN_CCW 0x2 /* Constant velocity - CCW */
|
||||
#define CS_MOVE_ABS 0x3 /* Move to absolute motor position */
|
||||
#define CS_MOVE_INC 0x4 /* Move to relative motor position */
|
||||
#define CS_SEEK_INDX 0x5 /* Stop ABS move at index switch */
|
||||
#define CS_BACKOFF_CW 0x6 /* Stop CW ABS move when off limit switch */
|
||||
#define CS_BACKOFF_CCW 0x7 /* Stop CCW ABS move when off limit switch */
|
||||
#define CS_SET_ZERO 0x8 /* Set absolute zero to motor position */
|
||||
#define CS_SET_POSITION 0x9 /* Set logical position to motor position */
|
||||
#define CS_READ_THETA 0xA /* Read motor quadrant/microstep position */
|
||||
|
||||
/* Operations */
|
||||
#define CS_GO 0x20 /* Initiate command execution */
|
||||
|
||||
/* Interrupt control */
|
||||
#define CS_IEN_ON 0x4000 /* Bit 14 - Enable interrupt on "DONE" */
|
||||
#define CS_IEN_OFF 0x0
|
||||
|
||||
/* Motor PARKing currents (bits 9,10) */
|
||||
#define CS_PARK_100 0x000 /* Part motor at 100% current */
|
||||
#define CS_PARK_75 0x200 /* 75% */
|
||||
#define CS_PARK_50 0x400 /* 50% */
|
||||
#define CS_PARK_0 0x600 /* 0% */
|
||||
|
||||
|
||||
/* V544 STATus Register Bit Mapping */
|
||||
#define STAT_BADC 0x8000 /* Illegal command detected */
|
||||
#define STAT_SPRA 0x20 /* Spare limit switch status */
|
||||
#define STAT_MOTR 0x8 /* Motor driver error */
|
||||
#define STAT_CCWL 0x4 /* CCW limit switch status */
|
||||
#define STAT_CWL 0x2 /* CW limit switch status */
|
||||
#define STAT_INDX 0x1 /* INDEX switch status */
|
||||
|
||||
|
||||
|
||||
|
||||
/* V544 DUAL-PORT MEMORY MAP */
|
||||
/* Define byte offsets into axis control registers */
|
||||
#define COARSE_POS_ID 0x0
|
||||
#define FINE_POS_ID 0x2
|
||||
#define VELOCITY_ID 0x4
|
||||
#define ACCEL_ID 0x6
|
||||
#define LS_DECEL_ID 0x8
|
||||
#define AUX_REG_ID 0xa
|
||||
#define STAT_REG_ID 0xc
|
||||
#define CMND_REG_ID 0xe
|
||||
|
||||
/*
|
||||
* union posReg{
|
||||
* int32_t all;
|
||||
* struct {
|
||||
* int16_t high;
|
||||
* int16_t low;
|
||||
* } split;
|
||||
* };
|
||||
*/
|
||||
|
||||
typedef struct pos_reg_str {
|
||||
int16_t coarse;
|
||||
uint16_t fine;
|
||||
} POS_REG;
|
||||
|
||||
/* Define register structure */
|
||||
typedef struct motor_reg_str {
|
||||
POS_REG pos;
|
||||
uint16_t velocity;
|
||||
uint16_t accel;
|
||||
uint16_t lsDecel;
|
||||
uint16_t aux;
|
||||
uint16_t status;
|
||||
uint16_t cmnd;
|
||||
} MOTOR_REG;
|
||||
|
||||
|
||||
struct vmex_motor {
|
||||
uint16_t vxid;
|
||||
uint16_t vtype;
|
||||
uint16_t vcsr;
|
||||
uint16_t pgid;
|
||||
uint16_t prev;
|
||||
uint16_t vsn;
|
||||
uint16_t opts;
|
||||
uint16_t scan;
|
||||
|
||||
/* Programming/Status Registers */
|
||||
MOTOR_REG motorReg[V544_NUM_CHANNELS];
|
||||
|
||||
/* Readback Registers */
|
||||
POS_REG posReg[V544_NUM_CHANNELS]; /* Actual positions */
|
||||
uint16_t velReg[V544_NUM_CHANNELS]; /* Actual velocity */
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user