From 690e1ffddaf66e3ea1b40dfd1146d0b3472da03b Mon Sep 17 00:00:00 2001 From: MarkRivers Date: Mon, 12 Sep 2005 19:43:50 +0000 Subject: [PATCH] Changes for multiple motors/group --- motorApp/NewportSrc/devXPSC8.cc | 297 ++++++++++++--------- motorApp/NewportSrc/drvXPSC8.cc | 442 +++++++++++++++++++++++--------- motorApp/NewportSrc/drvXPSC8.h | 37 ++- 3 files changed, 525 insertions(+), 251 deletions(-) diff --git a/motorApp/NewportSrc/devXPSC8.cc b/motorApp/NewportSrc/devXPSC8.cc index 6089c2ef..060e3f94 100755 --- a/motorApp/NewportSrc/devXPSC8.cc +++ b/motorApp/NewportSrc/devXPSC8.cc @@ -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); } diff --git a/motorApp/NewportSrc/drvXPSC8.cc b/motorApp/NewportSrc/drvXPSC8.cc index 5aa12c76..0067ff48 100755 --- a/motorApp/NewportSrc/drvXPSC8.cc +++ b/motorApp/NewportSrc/drvXPSC8.cc @@ -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 @@ -18,35 +27,31 @@ #include #include #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; imotor_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; axisaxis[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), diff --git a/motorApp/NewportSrc/drvXPSC8.h b/motorApp/NewportSrc/drvXPSC8.h index 65123b73..76b11112 100755 --- a/motorApp/NewportSrc/drvXPSC8.h +++ b/motorApp/NewportSrc/drvXPSC8.h @@ -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 */