Changes for multiple motors/group

This commit is contained in:
MarkRivers
2005-09-12 19:43:50 +00:00
parent f9fba22c43
commit 690e1ffdda
3 changed files with 525 additions and 251 deletions
+174 -123
View File
@@ -4,6 +4,20 @@
/*
* Original Author: Jon Kelly
*
* Modification Log:
* -----------------
*
* 13th May 2005
*
* 1) The use of multiaxis groups has been enabled with the addition of
* variables to the drvXPSC8.cc: XPSC8Name_config function used in the st.cmd.
* 2) A cue feature has now been added so that if a command is sent while
* a group is busy it is cued until the group becomes static.
* 3) The driver waits for a time specified in drvXPSC8.h: XPSC8_QUE_PAUSE when
* a command is issued. It then performs all the motions specified in the lapsed
* time as a single syncronised motion. The pause is performed in drvXPSC8.cc:
* send_mess.
*
*/
@@ -16,9 +30,8 @@
#include "motorRecord.h"
#include "motor.h"
#include "motordevCom.h"
#include "drvXPSC8.h"
/*#define DLL _declspec(dllexport)*/
#include "drvXPSC8.h"
#include "xps_c8_driver.h"
#define STATIC static
@@ -31,24 +44,23 @@ extern struct driver_table XPSC8_access;
#define MOVING 1
/*----------------debugging-----------------*/
#define DEBUG
#ifdef __GNUG__
#ifdef DEBUG
volatile int devXPSC8Debug = 0;
volatile int devXPSC8Debug = 3;
#define Debug(L, FMT, V...) { if(L <= devXPSC8Debug) \
{ printf("%s(%d):",__FILE__,__LINE__); \
printf(FMT,##V); } }
epicsExportAddress(int, devXPSC8Debug);
#else
#else
#define Debug(L, FMT, V...)
#endif
#else
#endif
#else
#define Debug()
#endif
/* Debugging levels:
* devXPSC8Debug >= 3 Print new part of command and command string so far
* at the end of XPSC8_build_trans
*/
/* ----------------Create the dsets for devXPSC8----------------- */
@@ -59,6 +71,7 @@ STATIC long XPSC8_start_trans(struct motorRecord *);
STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd, double *, struct motorRecord *);
STATIC RTN_STATUS XPSC8_end_trans(struct motorRecord *);
struct motor_dset devXPSC8 =
{
{8, NULL, (DEVSUPFUN)XPSC8_init, (DEVSUPFUN)XPSC8_init_record, NULL},
@@ -109,16 +122,16 @@ STATIC long XPSC8_init(int after)
{
long rtnval;
Debug(1, "XPSC8_init, after=%d\n", after);
Debug(10, "XPSC8_init, after=%d\n", after);
if (after == 0) {
drvtabptr = &XPSC8_access;
Debug(1, "XPSC8_init, calling driver initialization\n");
Debug(10, "XPSC8_init, calling driver initialization\n");
(drvtabptr->init)();
}
rtnval = motor_init_com(after, *drvtabptr->cardcnt_ptr, drvtabptr,
&XPSC8_cards);
Debug(1, "XPSC8_init, end of function\n");
Debug(10, "XPSC8_init, end of function\n");
return(rtnval);
}
@@ -134,7 +147,7 @@ STATIC long XPSC8_init_record(struct motorRecord *mr)
struct XPSC8axis *cntrl;
int card, signal;
Debug(1, "--------XPSC8_init_record \n");
Debug(10, "--------XPSC8_init_record \n");
rtnval = motor_init_record_com(mr, *drvtabptr->cardcnt_ptr,
drvtabptr, XPSC8_cards);
/* We have a logic problem here. motor_init has read in the motor
@@ -151,10 +164,10 @@ STATIC long XPSC8_init_record(struct motorRecord *mr)
control = (struct XPSC8controller *) brdptr->DevicePrivate;
cntrl = (struct XPSC8axis *)&control->axis[signal];
cntrl->resolution = mr->mres; /* Set the motor resolution */
mr->rmp = NINT(cntrl->currentposition[1] / cntrl->resolution);
Debug(1, "XPSC8_init_record: card=%d, signal=%d, currentposition[1]=%f"\
mr->rmp = NINT((cntrl->currentposition) / (cntrl->resolution));
Debug(1, "XPSC8_init_record: card=%d, signal=%d, currentposition=%f"\
" resolution=%f, mr->rmp=%d\n",\
card, signal, cntrl->currentposition[1], cntrl->resolution, mr->rmp);
card, signal, cntrl->currentposition, cntrl->resolution, mr->rmp);
return(rtnval);
}
@@ -162,7 +175,6 @@ STATIC long XPSC8_init_record(struct motorRecord *mr)
/* start building a transaction */
STATIC long XPSC8_start_trans(struct motorRecord *mr)
{
Debug(1, "--------XPSC8_start_trans\n");
long rtnval;
rtnval = motor_start_trans_com(mr, XPSC8_cards);
return(rtnval);
@@ -172,7 +184,6 @@ STATIC long XPSC8_start_trans(struct motorRecord *mr)
/* end building a transaction */
STATIC RTN_STATUS XPSC8_end_trans(struct motorRecord *mr)
{
Debug(1, "--------XPSC8_end_trans\n");
RTN_STATUS rtnval;
rtnval = motor_end_trans_com(mr, drvtabptr);
return(rtnval);
@@ -181,23 +192,26 @@ STATIC RTN_STATUS XPSC8_end_trans(struct motorRecord *mr)
/* add a part to the transaction */
STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command, double *parms, struct motorRecord *mr)
STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command,\
double *parms, \
struct motorRecord *mr)
{
struct motor_trans *trans = (struct motor_trans *) mr->dpvt;
struct mess_node *motor_call;
struct controller *brdptr;
struct XPSC8controller *control;
struct XPSC8axis *cntrl;
double dval=0.,resolution,steps;
struct XPSC8group *groupcntrl; /*XPS group specific data */
double dval=0.0,resolution,steps;
int ival=0;
RTN_STATUS rtnval=OK;
int card, signal;
int groupnumber, groupsize;
int axisingroup, groupstatus;
int status;
int positioner, status;
positioner = 1; /* Means only move one axis at a time */
if (parms != NULL){
dval = parms[0]; /* I assume this is the record DVAL which you set*/
dval = parms[0]; /* This is the record DVAL which you set */
/* to move e.g. dval = 10mm and command = MOVE_ABS*/
ival = NINT(parms[0]);
}
@@ -207,195 +221,233 @@ STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command, double *parms, struct mo
signal = motor_call->signal;
brdptr = (*trans->tabptr->card_array)[card];
Debug(11, "XPSC8_build_trans: After brdptr command\n");
Debug(10, "XPSC8_build_trans: After brdptr command\n");
if (brdptr == NULL)
return(rtnval = ERROR);
control = (struct XPSC8controller *) brdptr->DevicePrivate;
cntrl = (struct XPSC8axis *)&control->axis[signal];
groupstatus = cntrl->groupstatus; /* From XPS controller */
axisingroup = cntrl->axisingroup; /* Pull in group info */
groupnumber = cntrl->groupnumber;
groupcntrl = (struct XPSC8group *)&control->group[groupnumber];
groupsize = groupcntrl->groupsize; /* Number of motors in group */
cntrl->resolution = mr->mres; /* Read in the motor resolution */
resolution = cntrl->resolution;
steps = resolution * dval;
steps = resolution * dval; /* This could be a position or velocity */
/* mr->dllm = cntrl->minlimit;*/ /* set the epics limits to the XPS limits */
/* mr->dhlm = cntrl->maxlimit; */
Debug(1, "XPSC8_build_trans: card=%d, signal=%d, command=%d, ival=%d"\
Debug(10, "XPSC8_build_trans: card=%d, signal=%d, command=%d, ival=%d"\
" dval=%f, steps=%f\n",\
card, signal, command, ival, dval, steps);
Debug(1, "XPSC8_build_trans: resolution=%f\n",resolution);
Debug(10, "XPSC8_build_trans: resolution=%f\n",resolution);
if (XPSC8_table[command] > motor_call->type)
motor_call->type = XPSC8_table[command];
Debug(11, "XPSC8_build_trans: After cntrl command\n");
if (trans->state != BUILD_STATE)
return(rtnval = ERROR);
Debug(11, "XPSC8_build_trans: After cntrl command\n");
/* Take a lock so that only 1 thread can be talking to the XPSC8 at
* once. I don't know if this is needed? */
epicsMutexLock(control->XPSC8Lock);
/* No need to deal with initialization, premove or postmove strings,
XPSC8 does not support */
Debug(1, "build_trans: Top Of Switch command=%d, cntrl->moving=%d"\
" GStat=%d-\n", command,cntrl->moving,cntrl->groupstatus);
Debug(10, "build_trans: Top Of Switch command=%d, cntrl->moving=%d"\
" \n GroupStat=%d\n", command,cntrl->moving,cntrl->groupstatus);
Debug(5,"Build_trans: com=%d, axis=%d, moving=%d socket=%i psocket=%i\n",\
command,signal,cntrl->moving,cntrl->socket,cntrl->devpollsocket);
status = GroupStatusGet(cntrl->devpollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0)
printf("BuildTrans Error performing GroupStatusGet status=%d\n", status);
groupstatus = cntrl->groupstatus; /* Update groupstatus */
switch (command) {
case MOVE_ABS:/* command 0*/
Debug(1, "XPSC8_build_trans: command=%d, Move_ABS moving=%d steps=%f\n",\
command,cntrl->moving, steps);
if ((groupstatus < 10) || (groupstatus == 47)) {
/* ie not initialized state or Jogging!*/
break;}
/* If there is no cue, update the cue array to make sure you don't move */
/* the wrong motors */
if ((groupcntrl->cuesize == 0) && (groupstatus > 9 && groupstatus < 20)){
status = GroupPositionCurrentGet(cntrl->devpollsocket,
cntrl->groupname,
groupsize,
groupcntrl->positionarray); /* Array! */
if ((cntrl->moving) == MOVING) {
printf("--STILL MOVING--\n");
goto done;
} /* This is set in drvXPSC8.cc*/
if (status != 0) {
printf(" Error performing GroupPositionCurrentGet\n");
}
}
Debug(11, "Move_ABS socket=%d posiname=%s posit=%d dval=%f\n",\
cntrl->socket, cntrl->positionername, positioner, dval);
epicsThreadSleep(0.1);
status = GroupMoveAbsolute(cntrl->socket, cntrl->positionername,
positioner, &steps);
if (status != 0) {
printf(" Error performing GroupMoveAbsolute\n");
}
Debug(1, "--After GroupMoveAbsolute command=%d,Move_ABS moving=%d \n",\
command,cntrl->moving);
/* Always add the move to the cue */
groupcntrl->positionarray[axisingroup] = steps;
++groupcntrl->cuesize; /* Add 1 to cue total */
if (groupcntrl->cuesize == 1)
groupcntrl->cueflag = 1;/* If first call set flag */
if (groupcntrl->cuesize > 1)
Debug(2,"******Adding move to an existing cue***\n");
/* The communication and looping has been moved to drvXPSC8 send_mess */
break;
case MOVE_REL:
/* Using the SGamma setings in stages.ini */
if (cntrl->moving == MOVING) goto done;
/* This is set in drvXPSC8.cc*/
status = GroupMoveRelative(cntrl->socket, cntrl->positionername,
positioner, &steps);
if (status != 0) printf(" Error performing GroupMoveRelative\n");
break;
case MOVE_REL:/*1*/
/* The motor record seems to impliment the relative move by
calculating the new position and calling MOVE_ABS */
case HOME_FOR:
case HOME_REV:
/* If motion has been killed the group will need to be initialized*/
case HOME_FOR:
case HOME_REV: /*3*/
if (cntrl->groupstatus == 43 ) { /* Allready Homing */
break;}
/* If motion has been killed the group will need to be initialized*/
/* and homed before the motors can be driven again */
if (cntrl->groupstatus < 10 ) {
if (cntrl->groupstatus < 10 ) {
/* ie not initialized state!*/
status = GroupInitialize(cntrl->pollsocket,cntrl->groupname);
status = GroupInitialize(cntrl->devpollsocket,cntrl->groupname);
if (status != 0) {
printf("HOME Command Error performing GroupInitialise\n");
}
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0) {
printf(" Error performing GroupStatusGet\n");
}
Debug(1, "XPSC8_build_trans:****** Perform GroupInitialize\n");
status = GroupHomeSearch(cntrl->socket,cntrl->groupname);
if (status != 0) {
printf(" Error performing GroupHomeSearch\n");
}
Debug(1, "XPSC8_build_trans:******* Perform GroupHomeSearch\n");
}
break;
goto home_rev_end;
}
status = GroupKill(cntrl->pollsocket,cntrl->groupname);
/* Else kill all the motions an home */
status = GroupKill(cntrl->devpollsocket,cntrl->groupname);
if (status != 0) {
printf(" Error performing GroupKill\n");
}
status = GroupInitialize(cntrl->pollsocket,cntrl->groupname);
status = GroupInitialize(cntrl->devpollsocket,cntrl->groupname);
if (status != 0) {
printf("HOME Command Error performing GroupInitialise\n");
}
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0) {
printf(" Error performing GroupStatusGet\n");
}
Debug(1, "XPSC8_build_trans:****** Perform GroupInitialize\n");
status = GroupHomeSearch(cntrl->socket,cntrl->groupname);
if (status != 0) {
printf(" Error performing GroupHomeSearch\n");
}
Debug(1, "XPSC8_build_trans:******* Perform GroupHomeSearch\n");
Debug(2, "XPSC8_build_trans:******* Perform GroupHomeSearch\n");
Debug(2, "XPSC8_build_trans:groupsize=%i\n",groupsize);
/*}*/
/* if (cntrl->groupstatus == NOTREF ){ */
/* you must kill a group before homing*/
/*}*/
home_rev_end: /* Used for goto statment above */
/* When a group is homed the drive cue is emptied */
groupcntrl->cuesize = 0; /* Reset cue */
groupcntrl->cueflag = 0;
break;
case LOAD_POS:
/* command 4 I assume it means just update the position value? */
/*status = GroupPositionCurrentGet(cntrl->socket,
cntrl->positionername,
positioner,
&cntrl->currentposition[1]);
if (status != 0)
printf(" Error performing GroupPositionCurrentGet Load Pos\n");*/
case LOAD_POS:/* 4*/
/* command 4 Not used*/
break;
case SET_VEL_BASE:
/* The XPS does not have a different Base velocity!!!*/
break;
case SET_VELOCITY:
case SET_VELOCITY: /*6*/
/* The XPS does not have a different Base velocity!!!!!
So I perform the same operation for VEL_BASE and VEL*/
status = PositionerSGammaParametersSet(cntrl->pollsocket,
status = PositionerSGammaParametersSet(cntrl->devpollsocket,
cntrl->positionername, steps,
cntrl->accel,
cntrl->minjerktime,
cntrl->maxjerktime);
if (status != 0)
if (status != 0) {
printf(" Error performing PositionerSGammaParameters Set Vel\n");
printf(" steps=%f resoulution=%f DVAL=%f\n",steps,resolution,dval);
}
else cntrl->velocity = steps;
break;
case SET_ACCEL: /* command 7 */
status = PositionerSGammaParametersSet(cntrl->pollsocket,
status = PositionerSGammaParametersSet(cntrl->devpollsocket,
cntrl->positionername,
cntrl->velocity,
steps, cntrl->minjerktime,
cntrl->maxjerktime);
if (status != 0)
printf(" Error performing PositionerSGammaParameters Set Accel\n");
if (status != 0) {
printf(" Error performing PositionerSGammaParameters Set Accel %i\n",
status);
printf(" steps=%f resoulution=%f DVAL=%f\n",steps,resolution,dval);
if (status == -17)
printf("devXPSC8 BuildTrans: One of the parameters was out of range!");
}
else cntrl->accel = steps;
break;
case GO:
case GO: /* 8 */
if (groupstatus == 20) { /* If disabled then enable */
status = GroupMotionEnable(cntrl->devpollsocket,cntrl->groupname);
if (status != 0)
printf(" Error performing GroupMotionEnable %i\n",status);
}
break;
case SET_ENC_RATIO: /* These must be set in the Stages.ini file */
break;
case GET_INFO: /* Again I don't know what this is intended to do? */
case GET_INFO: /* 10 * This is run when you press Go from stop!*/
break;
case STOP_AXIS:
case STOP_AXIS: /* 11 */
/* The whole group must stop, not just 1 axis */
if (cntrl->groupstatus > 42) {
/* Update status to see if the group is moving */
if (cntrl->groupstatus > 42) {
/* Then the group is moving! */
status = GroupMoveAbort(cntrl->pollsocket,cntrl->groupname);
if (status != 0) printf(" Error performing GroupMoveAbort(\n");
}
status = GroupMoveAbort(cntrl->devpollsocket,cntrl->groupname);
if (status != 0) {
printf(" Error performing GroupMoveAbort = %i %s(\n",\
status,cntrl->groupname);
}
/* When a group is stopped the drive cue is emptied and reset*/
status = GroupPositionCurrentGet(cntrl->devpollsocket,
cntrl->groupname,
groupsize,
groupcntrl->positionarray);
if (status != 0) {
printf(" Error performing GroupPositionCurrentGet\n");
}
}
groupcntrl->cuesize = 0; /* Reset cue */
groupcntrl->cueflag = 0;
break;
case JOG:
/* I need more commandds to impliment this i.e. enable/disable
/* I need more commandds to impliment this i.e. enable/disable jog
set velocity and acceleration */
break;
case SET_PGAIN:
case SET_PGAIN: /* 13 */
case SET_IGAIN:
case SET_DGAIN:
/* These can be implimented but there are so many variables */
@@ -405,12 +457,12 @@ STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command, double *parms, struct mo
/* The XPSC8 does not support gain or torque commands */
break;
case SET_HIGH_LIMIT:
Debug(1, "XPSC8_build_trans highlimit: socket=%d, posname=%s, "\
case SET_HIGH_LIMIT: /*18 */
Debug(10, "XPSC8_build_trans highlimit: socket=%d, posname=%s, "\
"minlim=%f, steps=%f\n",\
cntrl->socket, cntrl->positionername, cntrl->minlimit, steps);
status = PositionerUserTravelLimitsSet(cntrl->pollsocket,
status = PositionerUserTravelLimitsSet(cntrl->devpollsocket,
cntrl->positionername,
cntrl->minlimit, steps);
if (status != 0)
@@ -420,7 +472,7 @@ STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command, double *parms, struct mo
break;
case SET_LOW_LIMIT:
status = PositionerUserTravelLimitsSet(cntrl->pollsocket,
status = PositionerUserTravelLimitsSet(cntrl->devpollsocket,
cntrl->positionername,
steps, cntrl->maxlimit);
if (status != 0)
@@ -432,9 +484,8 @@ STATIC RTN_STATUS XPSC8_build_trans(motor_cmnd command, double *parms, struct mo
rtnval = ERROR;
}
done:
/* Free the lock */
epicsMutexUnlock(control->XPSC8Lock);
Debug(1, "End Of Build_trans after Switch\n");
Debug(10, "End Of Build_trans after Switch\n");
return (rtnval);
}
+323 -119
View File
@@ -2,12 +2,21 @@
* drvXPSC8.cc
* Motor record driver level support for Newport XPSC8 motor controller.
*
* Original Author: Mark Rivers
* Date: 10-May-2000
* By Jon Kelly
* 2005
*
* Modification Log:
* -----------------
* 13th May 2005
* The driver waits for a time specified in drvXPSC8.h: XPSC8_QUE_PAUSE when
* a command is issued. It then performs all the motions specified in the lasped
* time as a single syncronised motion. The pause is performed in drvXPSC8.cc:
* send_mess.
*
* 30th June 2005
* The driver is converted to asyn. The XPS some times returns an accel=zero in
* readStatus so I have added a do loop to repeat the command until a non zero
* value is returned
*/
#include <string.h>
@@ -18,35 +27,31 @@
#include <epicsString.h>
#include <drvSup.h>
#include "motor.h"
#include "drvXPSC8.h"
#include "drvXPSC8.h"
#include "xps_c8_driver.h"
#define STATIC static
/*----------------debugging-----------------*/
#define DEBUG
#ifdef __GNUG__
#ifdef DEBUG
volatile int drvXPSC8Debug = 0;
#define Debug(L, FMT, V...) { if(L <= drvXPSC8Debug) \
{ printf("%s(%d):",__FILE__,__LINE__); \
printf(FMT,##V); } }
epicsExportAddress(int, drvXPSC8Debug);
#define Debug(l, f, args...) { if(l<=drvXPSC8Debug) printf(f,## args); }
#else
#define Debug(l, f, args...)
#endif
#else
#define Debug()
#endif
/* --- Local data. --- */
volatile int drvXPSC8Debug = 6;
/* --- Local data. --- */
int XPSC8_num_cards = 0;
/* Local data required for every driver; see "motordrvComCode.h" */
#include "motordrvComCode.h"
/* Why are not all the functions declared here? */
/*----------------functions-----------------*/
STATIC int recv_mess(int, char *, int);
@@ -136,7 +141,8 @@ static long init()
{
if (XPSC8_num_cards <= 0)
{
Debug(1, "init(): XPSC8 driver disabled. XPSC8etup() missing from startup script.\n");
Debug(10, "init() XPSC8etup() missing from startup script.%i\n",
XPSC8_num_cards);
}
return ((long) 0);
}
@@ -155,7 +161,7 @@ STATIC void start_status(int card)
{
int itera;
Debug(2, "start_status: card=%d total_cards=%d\n", card,total_cards);
Debug(10, "start_status: card=%d total_cards=%d\n", card,total_cards);
if (card >= 0) {
readXPSC8Status(card);
} else {
@@ -173,63 +179,97 @@ STATIC void readXPSC8Status(int card)
{
struct XPSC8controller *control =
(struct XPSC8controller *) motor_state[card]->DevicePrivate;
struct XPSC8axis *cntrl;
struct XPSC8axis *cntrl;
int status,statuserror;
int XPSC8_num_axes;
int positioner,i; /* this = 1 because we are talking to 1 axis at a time */
int i;
struct mess_node *nodeptr; /* These are to print the DONE flag */
register struct mess_info *motor_info;
msta_field statusflags;
positioner = 1;
int groupsize, groupnumber; /* To be read in from struct */
struct XPSC8group *groupcntrl; /*XPS group specific data */
double position[XPSC8_NUM_CHANNELS]; /* To temp store position array */
int axisingroup;
int loop; /* Variables used when the XPS returns accel=zero */
int max_loop = 10; /* This creates an error when we set the vel/accel */
msta_field statusflags;
status = 0;
statuserror = 0; /* this = 1 if an error occurs */
XPSC8_num_axes = motor_state[card]->total_axis;
Debug(2, "XPSC8:readXPSC8Status card=%d num_axes=%d\n",card,XPSC8_num_axes);
Debug(10, "XPSC8:readXPSC8Status card=%d num_axes=%d\n",card,XPSC8_num_axes);
/* Take a lock so that only 1 thread can be talking to the Neport XPSC8
*/
epicsMutexLock(control->XPSC8Lock);
for (i=0; i<XPSC8_num_axes;i++) {
/*epicsThreadSleep(10);*/
for (i=0; i<XPSC8_num_axes;i++) {
motor_info = &(motor_state[card]->motor_info[i]); /*To print DONE flag*/
nodeptr = motor_info->motor_motion;
statusflags.All = motor_info->status.All;
Debug(9, "XPSC8:readXPSC8Status RA_DONE=%d, RA_MOVING=%d, "\
"RA_PROBLEM=%d\n",\
statusflags.Bits.RA_DONE, statusflags.Bits.RA_MOVING,\
Debug(10, "XPSC8:readXPSC8Status RA_DONE=%d, RA_MOVING=%d, "
"RA_PROBLEM=%d\n",
statusflags.Bits.RA_DONE, statusflags.Bits.RA_MOVING,
statusflags.Bits.RA_PROBLEM);
control = (struct XPSC8controller *) motor_state[card]->DevicePrivate;
cntrl = (struct XPSC8axis *)&control->axis[i];
Debug(2, "XPSC8:readXPSC8Status card=%d axis=%d sock=%d gp=%s\n",card,i,\
cntrl->socket,cntrl->groupname);
/* Where I have used "&" the func requires an pointer */
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0) {
printf(" Error performing GroupStatusGet status=%d\n", status);
axisingroup = cntrl->axisingroup;
if ((axisingroup < 0) || (axisingroup > 7) ) {
printf(" Error Axis In Group Out Of Range status=%d\n", status);
statuserror =1;
}
status = PositionerSGammaParametersGet(cntrl->pollsocket,
groupnumber = cntrl->groupnumber;
if ((groupnumber < 0) || (groupnumber > 7) ) {
printf(" Error Group Number Out Of Range status=%d\n", status);
statuserror =1;
}
groupcntrl = (struct XPSC8group *)&control->group[groupnumber];
groupsize = groupcntrl->groupsize;
if ((groupsize < 1) || (groupsize > 8) ) {
printf(" Error Group Size Out Of Range status=%d\n", status);
statuserror =1;
}
Debug(10, "XPSC8:readXPSC8Status groupsize=%i groupnumber=%i\n",
groupsize,groupnumber);
Debug(10, "XPSC8:readXPSC8Status card=%d axis=%d sock=%d gp=%s\n",card,i,
cntrl->socket,cntrl->groupname);
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0) {
printf(" ReadStatus Error performing GroupStatusGet status=%d\n", status);
statuserror =1;
}
/* This do loop is required because some times the XPS returns accel=zero*/
loop = 0;
do {
status = PositionerSGammaParametersGet(cntrl->pollsocket,
cntrl->positionername,
&cntrl->velocity,
&cntrl->accel,
&cntrl->minjerktime,
&cntrl->maxjerktime);
if (status != 0) {
loop++;
}
while ((cntrl->accel < 0.00001) && (loop < max_loop));
if (status != 0) {
printf(" Error performing PositionerSGammaParametersGet\n");
statuserror =1;
}
/* Is the XPS sending the wrong accel and vel data? */
if (cntrl->accel <= 0.00001 )
printf("drvXPSC8 Error PositionerSGammaParametersGet accel=%f vel=%f loop=%i\n",
cntrl->accel,cntrl->velocity,loop);
/* The jog function is not enabled*/
/*
/* Not implimented due to lack of epics motor commands
status = GroupJogParametersGet(cntrl->pollsocket,
cntrl->groupname,
positioner,
@@ -241,35 +281,40 @@ STATIC void readXPSC8Status(int card)
}
*/
status = GroupPositionCurrentGet(cntrl->pollsocket,
cntrl->positionername,
positioner,
&cntrl->currentposition[1]);
cntrl->groupname,
groupsize,
position); /* Array! */
if (status != 0) {
printf(" Error performing GroupPositionCurrentGet\n");
statuserror =1;
}
} else {
/* Place the position data into the axis structure */
cntrl->currentposition = position[axisingroup];}
status = GroupPositionTargetGet(cntrl->pollsocket,
cntrl->positionername,
positioner,
&cntrl->targetposition[1]);
cntrl->groupname,
groupsize,
position); /* Re use Array! */
if (status != 0) {
printf(" Error performing GroupPositionTargetGet\n");
statuserror =1;
}
} else {
/* Place the position data into the axis structure */
cntrl->targetposition = position[axisingroup];}
status = GroupPositionSetpointGet(cntrl->pollsocket,
cntrl->positionername,
positioner,
&cntrl->setpointposition[1]);
cntrl->groupname,
groupsize,
position); /* Re-re use Array! */
if (status != 0) {
printf(" Error performing GroupPositionSetpointGet\n");
statuserror =1;
}
} else {
/* Place the position data into the axis structure */
cntrl->setpointposition = position[axisingroup];}
status = PositionerErrorGet(cntrl->pollsocket,
cntrl->positionername,
@@ -291,7 +336,7 @@ STATIC void readXPSC8Status(int card)
statuserror =1;
}
Debug(11, "readXPSC8Status, socket=%d, groupname=%s, minlim=%f\n",\
Debug(10, "readXPSC8Status, socket=%d, groupname=%s, minlim=%f\n",
cntrl->socket,cntrl->groupname,cntrl->minlimit);
if (status == 1)
@@ -318,7 +363,7 @@ STATIC int set_status(int card, int signal)
int positionererror;
int rtn_state, groupstatus;
double motorData, pos,resolution;
double motorData,pos,target,resolution;
bool ls_active = false;
msta_field status;
@@ -332,32 +377,28 @@ STATIC int set_status(int card, int signal)
/* Lock access to global data structure */
epicsMutexLock(control->XPSC8Lock);
Debug(2, "XPSC8:set_status entry: card=%d, signal=%d\n", card, signal);
Debug(10, "XPSC8:set_status entry: card=%d, signal=%d\n", card, signal);
/* Parse the error and position values read within the readXPSC8Status
function */
positionererror = cntrl->positionererror;
pos = cntrl->currentposition[1];
pos = cntrl->currentposition;
target = cntrl->targetposition;
groupstatus = cntrl->groupstatus;
Debug(2, "XPSC8:set_status entry: positionererror=%d, pos=%f,"\
" resolution=%f\n",\
positionererror, pos, resolution);
Debug(11, "XPSC8:set_status entry: pos0=%f, pos1=%f\n",\
cntrl->currentposition[0], cntrl->currentposition[1]);
if (cntrl->velocity >= 0)
/*if (cntrl->velocity >= 0)
status.Bits.RA_DIRECTION = 1;
else
status.Bits.RA_DIRECTION=0;
status.Bits.RA_DIRECTION=0;*/
if (groupstatus > 9 && groupstatus < 20) {
/* These states mean ready from move/home/jog etc*/
status.Bits.RA_DONE=1; /* 1 means cd ready */
Debug(2, "Set_status: Done -->groupstatus=%d\n", groupstatus);
Debug(10, "Set_status: Done -->groupstatus=%d\n", groupstatus);
} else {
status.Bits.RA_DONE=0;
Debug(2, "Set_status: Not Done -->groupstatus=%d\n", groupstatus);
Debug(10, "Set_status: Not Done -->groupstatus=%d\n", groupstatus);
}
status.Bits.RA_PLUS_LS=0;
status.Bits.RA_MINUS_LS=0;
@@ -367,11 +408,20 @@ STATIC int set_status(int card, int signal)
if (groupstatus > 42 && groupstatus < 49) {
/* These states mean it is moving/homeing/jogging etc*/
cntrl->moving = 1;
if (target >= pos) {
status.Bits.RA_DIRECTION = 1;
Debug(2, "Set_status: Positive Direction\n");
} else {
status.Bits.RA_DIRECTION = 0;
Debug(2, "Set_status: Negative Direction\n");
}
}
/* These are hard limits */
if (positionererror & XPSC8_END_OF_RUN_MINUS ) {
/* I am unsure of the use of & !!*/
status.Bits.RA_MINUS_LS=1; /* defined in drvXPSC8.h */
ls_active = true;
}
@@ -410,10 +460,13 @@ STATIC int set_status(int card, int signal)
status.Bits.RA_PROBLEM=0;
Debug(11, "--------above inisialisation test \n");
if (groupstatus < 9 || (groupstatus > 19 && groupstatus < 43)) {
/* not initialized or disabled*/
/* Set the Hard limits To show that it is unable to move */
/* not initialized, homed or disabled */
if ((groupstatus >= 0 && groupstatus < 10) || (groupstatus >= 20 && groupstatus < 43)) {
/* Set the Hard limits To show that it is unable to move. This means when you
home the motor record will only let you home away from the current shown
limit */
status.Bits.RA_MINUS_LS=1;
status.Bits.RA_PLUS_LS=1;
status.Bits.RA_PROBLEM=1; /*This variable is to do with polling*/
@@ -422,16 +475,10 @@ STATIC int set_status(int card, int signal)
}
motor_info->velocity = (int)cntrl->velocity;
/* I don't know what this is used for */
/* if (status.Bits.RA_DIRECTION==0)
motor_info->velocity *= -1;*/
rtn_state = (!motor_info->no_motion_count || ls_active == true ||
(status.Bits.RA_DONE | status.Bits.RA_PROBLEM)) ? 1 : 0;
Debug(1, "--------set_status rtn_state=%d \n",rtn_state);
if (cntrl->status == XPSC8_COMM_ERR)
/* I defined this to be -1! */
@@ -442,6 +489,10 @@ STATIC int set_status(int card, int signal)
/* Free the lock */
epicsMutexUnlock(control->XPSC8Lock);
motor_info->status.All = status.All;
Debug(12, "status.Bits.RA_PROBLEM: %i status.Bits.RA_DONE: %i",
status.Bits.RA_PROBLEM,status.Bits.RA_DONE);
return(rtn_state);
}
@@ -450,9 +501,135 @@ STATIC int set_status(int card, int signal)
/* send a message to the XPS board */
/* send_mess() */
/*****************************************************/
STATIC RTN_STATUS send_mess(int card, char const *com, char *name)
STATIC RTN_STATUS send_mess(int card, char const *com, char *c)
{
/* This is a no-op for the XPS, but must be present */
struct XPSC8controller *control;
struct XPSC8axis *cntrl;
struct XPSC8group *groupcntrl; /*XPS group specific data */
int groupnumber, groupsize;
int axisingroup, groupstatus;
int status;
int waitcount;
/*******************************************************************************/
if (motor_state[0] == NULL)
return(ERROR);
int signal = -1; /* This is incremented up to 0 further down */
control = (struct XPSC8controller *) motor_state[card]->DevicePrivate;
epicsMutexLock(control->XPSC8Lock);
/*control = (struct XPSC8controller *) brdptr->DevicePrivate;*/
/* Loop until you find the axis/group with a move cued up! */
do
{
++signal;
cntrl = (struct XPSC8axis *)&control->axis[signal];
groupstatus = cntrl->groupstatus; /* From XPS controller */
axisingroup = cntrl->axisingroup; /* Pull in group info */
groupnumber = cntrl->groupnumber;
groupcntrl = (struct XPSC8group *)&control->group[groupnumber];
groupsize = groupcntrl->groupsize; /* Number of motors in group */
}
while ((groupcntrl->cuesize == 0) && (signal < (XPSC8_NUM_CHANNELS-1)));
Debug(5,"Send_mess After do loop axisingp=%d, groupstatus=%i socket=%i cue=%i flag=%i \n",
axisingroup,groupstatus,cntrl->socket,groupcntrl->cuesize,groupcntrl->cueflag);
if((signal == (XPSC8_NUM_CHANNELS-1)) && (groupcntrl->cuesize == 0))
goto send_mess_end; /*No moves to perform */
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus); /* Update Status */
groupstatus = cntrl->groupstatus;
if (status != 0)
printf(" SendMess Error performing GroupStatusGet status=%d\n", status);
if (groupstatus > 9 && groupstatus < 20){ /* Ready from move */
if (groupcntrl->cueflag == 1) /* First motor called */
{
epicsMutexUnlock(control->XPSC8Lock);/* Free up for the other motors*/
epicsThreadSleep(XPSC8_QUE_PAUSE_READY); /* Wait for other motors */
epicsMutexLock(control->XPSC8Lock);
groupcntrl->cuesize = 0; /* Reset cue */
groupcntrl->cueflag = 0;
status = GroupMoveAbsolute(cntrl->socket,
cntrl->groupname,
groupsize,
groupcntrl->positionarray); /*Pointer to array*/
if (status != 0 && status != -27)
printf(" Error performing GroupMoveAbsolute %i\n",status);
/* Error -27 is caused when the motor record changes dir i.e.
when it aborts a move!*/
Debug(5,"Send_mess After move in Send_mess axisingp=%d, groupstatus=%i socket=%i psocket=%i\n",
cntrl->axisingroup,groupstatus,cntrl->socket,cntrl->pollsocket);
goto send_mess_end;
}
}
if (groupstatus > 42 && groupstatus < 47){ /* Moveing/Homing*/
if (groupcntrl->cuesize > 1)
Debug(1,"Send_mess**Added move to the cue group busy ie xps moving***\n");
if (groupcntrl->cueflag == 1){ /* First motor called */
groupcntrl->cueflag = 0;
waitcount = 0;
while((groupstatus > 42 && groupstatus < 49) &&
(waitcount <= XPSC8_MAX_WAIT)){
epicsMutexUnlock(control->XPSC8Lock);/* Free up for the others*/
epicsThreadSleep(XPSC8_QUE_PAUSE_MOVING); /* Wait for end of motion */
epicsMutexLock(control->XPSC8Lock);
++waitcount;
status = GroupStatusGet(cntrl->pollsocket, cntrl->groupname,
&cntrl->groupstatus);
if (status != 0)
printf("Error performing GroupStatusGet Bottom Send_mess status=%d\n", status);
groupstatus = cntrl->groupstatus; /* Update groupstatus */
}
if (waitcount >= XPSC8_MAX_WAIT){
printf(" Error Motor Cue timed out \n");
groupcntrl->cuesize = 0; /* Reset cue */
groupcntrl->cueflag = 0;
/* Re set the cue array to current positions */
status = GroupPositionCurrentGet(cntrl->pollsocket,
cntrl->groupname,
groupsize,
groupcntrl->positionarray);
if (status != 0)
printf(" Error performing GroupPositionCurrentGet\n");
goto send_mess_end;
}
if (groupstatus > 9 && groupstatus < 20){ /* Ready from move */
groupcntrl->cuesize = 0; /* Reset cue */
groupcntrl->cueflag = 0;
status = GroupMoveAbsolute(cntrl->socket,
cntrl->groupname,
groupsize,
groupcntrl->positionarray); /*Pointer to array*/
/* Error -27 is caused when the motor record changes dir i.e.
when it aborts a move!*/
if (status != 0 && status != -27 )
printf(" Error performing GroupMoveAbsolute %i\n",status);
}
}
}
send_mess_end:
epicsMutexUnlock(control->XPSC8Lock);
return (OK);
}
@@ -476,19 +653,19 @@ STATIC int recv_mess(int card, char *com, int flag)
/* XPSC8Setup() */
/*****************************************************/
RTN_STATUS XPSC8Setup(int num_cards, /* number of controllers in system. */
int scan_rate) /* I think this is for the epicsthread */
int scan_rate) /* Poll rate */
{
Debug(1, "XPSC8Setup: Controllers=%d Scan Rate=%d\n",num_cards,scan_rate);
Debug(10, "XPSC8Setup: Controllers=%d Scan Rate=%d\n",num_cards,scan_rate);
int itera;
if (num_cards > XPSC8_NUM_CHANNELS)
printf(" Error in setup too many channels\n");
if (num_cards > XPSC8_MAX_CONTROLLERS)
printf(" Error in setup too many controllers\n");
if (num_cards < 1)
XPSC8_num_cards = 1;
else
XPSC8_num_cards = num_cards;
/* Set motor polling task rate */
/* Set motor polling task rate */
if (scan_rate >= 1 && scan_rate <= 60)
targs.motor_scan_rate = scan_rate;
else
@@ -511,23 +688,23 @@ RTN_STATUS XPSC8Setup(int num_cards, /* number of controllers in system. */
/* XPSC8Config() */
/*****************************************************/
RTN_STATUS XPSC8Config(int card, /* Controller number */
const char *ip, /* XPS IP address*/
int port, /* This may be 5001 */
int totalaxes) /* Number of axis/positioners used*/
const char *ip, /* XPS IP address*/
int port, /* This may be 5001 */
int totalaxes) /* Number of axis/positioners used*/
{
struct XPSC8controller *control;
struct XPSC8axis *cntrl;
int statuserror, status, socket, pollsocket, axis;
int statuserror, status, socket, pollsocket, devpollsocket, axis;
char *ipchar, List[1000];
statuserror = 0;
status = 0;
ipchar = (char *)ip;
socket = 0;
pollsocket = 0;
devpollsocket = 0;
Debug(1, "XPSC8Config: IP=%s, Port=%d, Card=%d, totalaxes=%d\n",\
Debug(10, "XPSC8Config: IP=%s, Port=%d, Card=%d, totalaxes=%d\n",
ipchar, port, card, totalaxes);
if (totalaxes < 0 || totalaxes > XPSC8_NUM_CHANNELS) {return (ERROR);}
@@ -539,9 +716,22 @@ RTN_STATUS XPSC8Config(int card, /* Controller number */
control = (struct XPSC8controller *) motor_state[card]->DevicePrivate;
motor_state[card]->total_axis = totalaxes;
pollsocket = TCP_ConnectToServer(ipchar,port,TIMEOUT);
if (pollsocket < 0) {
printf(" Error TCP_ConnectToServer for pollsocket\n");
statuserror =1;
}
devpollsocket = TCP_ConnectToServer(ipchar,port,TIMEOUT);
if (devpollsocket < 0) {
printf(" Error TCP_ConnectToServer for pollsocket\n");
statuserror =1;
}
for (axis=0; axis<totalaxes; axis++) {
socket = TCP_ConnectToServer(ipchar,port,TIMEOUT);
/* Find a socket number */
@@ -549,24 +739,18 @@ RTN_STATUS XPSC8Config(int card, /* Controller number */
printf(" Error TCP_ConnectToServer for move-socket\n");
statuserror =1;
}
pollsocket = TCP_ConnectToServer(ipchar,port,TIMEOUT);
/* Find a socket number */
if (pollsocket < 0) {
printf(" Error TCP_ConnectToServer for pollsocket\n");
statuserror =1;
}
cntrl = (struct XPSC8axis *)&control->axis[axis];
Debug(11, "XPSC8Config: axis=%d, cntrl=%p\n", axis, cntrl);
cntrl->pollsocket = pollsocket;
cntrl->devpollsocket = devpollsocket;
cntrl->socket = socket;
cntrl->ip = epicsStrDup(ip);
Debug(1, "XPSC8Config: Socket=%d, PollSock=%d, ip=%s, port=%d,"\
" axis=%d controller=%d\n",\
Debug(10, "XPSC8Config: Socket=%d, PollSock=%d, ip=%s, port=%d,"
" axis=%d controller=%d\n",
cntrl->socket,cntrl->pollsocket,ip,port,axis,card);
}
Debug(11, "XPSC8Config: Above OjectsListGet\n");
@@ -587,21 +771,29 @@ RTN_STATUS XPSC8Config(int card, /* Controller number */
/*********************************************************/
RTN_STATUS XPSC8NameConfig(int card, /*specify which controller 0-up*/
int axis, /*axis number 0-7*/
int groupnumber, /* 0-7*/
int groupsize, /* 1-8*/
int axisingroup, /* eg 4th axis in group 2 */
const char *gpname, /*group name e.g. Diffractometer */
const char *posname) /*positioner name e.g. Diffractometer.Phi*/
{
struct XPSC8controller *control;
struct XPSC8axis *cntrl;
struct XPSC8group *groupcntrl; /*XPS group specific data */
Debug(1, "XPSC8NameConfig: card=%d axis=%d, group=%s, positioner=%s\n",\
Debug(10, "XPSC8NameConfig: card=%d axis=%d, group=%s, positioner=%s\n",
card, axis, gpname, posname);
control = (struct XPSC8controller *) motor_state[card]->DevicePrivate;
cntrl = (struct XPSC8axis *)&control->axis[axis];
groupcntrl = (struct XPSC8group *)&control->group[groupnumber];
cntrl->groupname = epicsStrDup(gpname);
cntrl->positionername = epicsStrDup(posname);
cntrl->groupnumber = groupnumber;
cntrl->axisingroup = axisingroup;
groupcntrl->groupsize = groupsize;
return (OK);
}
@@ -617,25 +809,26 @@ STATIC int motor_init()
struct controller *brdptr;
struct XPSC8controller *control;
struct XPSC8axis *cntrl;
struct XPSC8group *groupcntrl; /*XPS group specific data */
int card_index, motor_index;
int status, totalaxes;
int status = 0, totalaxes;
int i,counter; /* Used in for loops */
bool errind;
initialized = true; /* Indicate that driver is initialized. */
/* Check for setup */
Debug(1, "XPSC8:motor_init: num_cards=%d\n", XPSC8_num_cards);
Debug(10, "XPSC8:motor_init: num_cards=%d\n", XPSC8_num_cards);
if (XPSC8_num_cards <= 0){
return (ERROR);
}
for (card_index = 0; card_index < XPSC8_num_cards; card_index++) {
totalaxes = motor_state[card_index]->total_axis;
Debug(5, "XPSC8:motor_init: Card init loop card_index=%d\n",card_index);
Debug(10, "XPSC8:motor_init: Card init loop card_index=%d\n",card_index);
brdptr = motor_state[card_index];
total_cards = card_index + 1;
Debug(5, "XPSC8:motor_init: Above control def card_index=%d\n",\
Debug(10, "XPSC8:motor_init: Above control def card_index=%d\n",
card_index);
control = (struct XPSC8controller *) brdptr->DevicePrivate;
@@ -645,12 +838,30 @@ STATIC int motor_init()
control->XPSC8Lock = epicsMutexCreate();
errind = false;
/* just to test status, 0 means the call worked*/
status = GroupStatusGet(cntrl->socket,cntrl->groupname,
&cntrl->groupstatus);
/* Just to test status, 0 means the call worked */
counter = 0;
/* wait incase the socket is busy */
while (status < 0 && counter < (TIMEOUT*10)) {
status = GroupStatusGet(cntrl->pollsocket,cntrl->groupname,
&cntrl->groupstatus);
counter++;
epicsThreadSleep(0.1);
}
if (status !=0) errind = true;
Debug(5, "XPSC8:motor_init: card_index=%d, errind=%d\n",\
Debug(10, "XPSC8:motor_init: card_index=%d, errind=%d\n",
card_index, errind);
Debug(10, "XPSC8:motor_init: psocket %i, gpname %s, gpstatus %i status %i\n",
cntrl->pollsocket,cntrl->groupname,cntrl->groupstatus,status);
/* Set the XPSC8group struct variables to zero */
for(i=0 ; i< XPSC8_NUM_CHANNELS ; ++i){
groupcntrl = (struct XPSC8group *)&control->group[i];
groupcntrl->cuesize = 0;
groupcntrl->cueflag = 0;
}
if (errind == false) {
brdptr->localaddr = (char *) NULL;
@@ -668,7 +879,6 @@ STATIC int motor_init()
start_status(card_index);
/*Read in all the parameters vel/accel ect */
Debug(5, "XPSC8:motor_init: called start_status OK\n");
for (motor_index = 0; motor_index < totalaxes; motor_index++) {
struct mess_info *motor_info = &brdptr->motor_info[motor_index];
motor_info->status.All = 0;
@@ -676,15 +886,11 @@ STATIC int motor_init()
motor_info->encoder_position = 0;
motor_info->position = 0;
/* Read status of each motor */
Debug(5, " XPSC8:motor_init: calling set_status for motor %d\n",\
motor_index);
set_status(card_index, motor_index);
}
}
else
motor_state[card_index] = (struct controller *) NULL;
}
Debug(5, "XPSC8:motor_init: done with start_status and set_status\n");
any_motor_in_motion = 0;
@@ -693,8 +899,6 @@ STATIC int motor_init()
free_list.head = (struct mess_node *) NULL;
free_list.tail = (struct mess_node *) NULL;
Debug(5, "XPSC8:motor_init: spawning XPSC8_motor task\n");
epicsThreadCreate((char *) "XPSC8_motor", epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackMedium),
+28 -9
View File
@@ -13,19 +13,29 @@
#define XPSC8_END_OF_RUN_MINUS 0x80000100
#define XPSC8_END_OF_RUN_PLUS 0x80000200
#define XPSC8_NUM_CHANNELS 8
#define XPSC8_NUM_CHANNELS 8 /* Number of axes in one XPS */
#define XPSC8_MAX_CONTROLLERS 2 /* Set to diffractometer number*/
#define XPSC8_COMM_ERR -1
#define TIMEOUT 1
#define XPSC8_MAX_WAIT 120 /* Cue timeout limit 1min 120*0.5 sec*/
#define XPSC8_QUE_PAUSE_READY 0.2 /* Time the driver waits for further
comands to group together before
performing a move from stationary*/
#define XPSC8_QUE_PAUSE_MOVING 0.1 /* Poll time the driver waits to check if
the motor is still moving after a
cue has been started*/
#define TIMEOUT 0.5 /* TCP/IP timeout */
#define NOTREF 42
/*------ This defines the XPSC8 specific property structure */
struct XPSC8axis
{
int socket;
int pollsocket; /* This is the same for all motors to poll!*/
double currentposition[1]; /* the XPS commands want an array */
double setpointposition[1];
double targetposition[1];
int socket; /* Each Axis has its own drive socket */
int pollsocket; /*socket for drvXPSC8 thread polling */
int devpollsocket; /*socket for devXPSC8 thread polling */
double currentposition; /* the XPS commands want an array */
double setpointposition; /* but the values are then assigned */
double targetposition; /* to these variables. */
double velocity;
double accel;
double minjerktime; /* for the SGamma function */
@@ -35,7 +45,6 @@ struct XPSC8axis
double maxlimit;
double minlimit;
double resolution;
char *ip;
char *positionername; /* read in using NameConfig*/
char *groupname;
@@ -45,11 +54,21 @@ struct XPSC8axis
int status; /* Included to fit in with the camac driver template
Not a value from the XPS controller!*/
int groupnumber; /* (0-7) This axis is a member of which group?*/
int axisingroup; /* (0-7) eg the 4th axis in the 2nd group */
};
struct XPSC8group{ /* This structure is for each group not axis */
double positionarray[XPSC8_NUM_CHANNELS]; /* Used to store cued moves */
int groupsize; /* (1-8) Number of members of a group */
int cuesize; /* Number of axes in the cue */
int cueflag; /* 1 = move/wait loop needs to be started */
};
struct XPSC8controller{
epicsMutexId XPSC8Lock;
struct XPSC8axis axis[XPSC8_NUM_CHANNELS];
struct XPSC8axis axis[XPSC8_NUM_CHANNELS]; /* maximum of 8 axes */
struct XPSC8group group[XPSC8_NUM_CHANNELS]; /* maximum of 8 groups */
};
/* Global function, used by both driver and device support */