From ad11d7ec6f9e06248ac1186f290f6aa64e5f029d Mon Sep 17 00:00:00 2001 From: Peter Denison Date: Tue, 6 Jun 2006 08:50:14 +0000 Subject: [PATCH] Interface changes: Removed motorAxisPrimitive, motorAxisSetLogParam motorAxisSetLog now takes a logParam parameter drvMotorAsynConfigure takes an extra can_block parameter Simulator create function only takes int parameters to avoid problems passing double parameters from the vxWorks shell on PowerPC arch Functional changes: Order of drvMotorAsyn interrupt callbacks has been changed to pass back Float64 interrupts (typically position, etc.) before Int32 interrupts (typically status), so that a move reaches its desired position before it is signalled as complete. This is not a complete solution. More parameter checking, particularly of axis number --- motorApp/MotorSimSrc/drvMotorSim.c | 136 ++++++++------ motorApp/MotorSimSrc/drvMotorSim.h | 2 +- motorApp/MotorSimSrc/motorSimRegister.cc | 8 +- motorApp/MotorSimSrc/motorSimTest.src | 76 ++++---- motorApp/MotorSrc/devMotorAsyn.c | 49 ++++- motorApp/MotorSrc/drvMotorAsyn.c | 221 ++++++++++++++++------- motorApp/MotorSrc/motor_interface.h | 55 ++---- motorApp/NewportSrc/drvMM4000Asyn.c | 52 +++--- motorApp/NewportSrc/drvXPSAsyn.c | 54 +++--- 9 files changed, 397 insertions(+), 256 deletions(-) diff --git a/motorApp/MotorSimSrc/drvMotorSim.c b/motorApp/MotorSimSrc/drvMotorSim.c index 74d72a0d..adbb1edd 100644 --- a/motorApp/MotorSimSrc/drvMotorSim.c +++ b/motorApp/MotorSimSrc/drvMotorSim.c @@ -1,3 +1,20 @@ +/* +FILENAME... drvMotorSim.c +USAGE... Simulated Motor Support. + +Version: $Revision: 1.4 $ +Modified By: $Author: peterd $ +Last Modified: $Date: 2006-06-06 08:50:14 $ +*/ + +/* + * + * + * Modification Log: + * ----------------- + * 20060506 npr Added prolog + */ + #include #include #include @@ -23,15 +40,13 @@ motorAxisDrvSET_t motorSim = { - 20, + 14, motorAxisReport, /**< Standard EPICS driver report function (optional) */ motorAxisInit, /**< Standard EPICS dirver initialisation function (optional) */ motorAxisSetLog, /**< Defines an external logging function (optional) */ - motorAxisSetLogParam, /**< Defines an external logging function user parameter (optional) */ motorAxisOpen, /**< Driver open function */ motorAxisClose, /**< Driver close function */ motorAxisSetCallback, /**< Provides a callback function the driver can call when the status updates */ - motorAxisPrimitive, /**< Passes a controller dependedent string */ motorAxisSetDouble, /**< Pointer to function to set a double value */ motorAxisSetInteger, /**< Pointer to function to set an integer value */ motorAxisGetDouble, /**< Pointer to function to get a double value */ @@ -64,6 +79,7 @@ typedef struct motorAxisHandle double enc_offset; double home; int homing; + motorAxisLogFunc print; void * logParam; epicsTimeStamp tLast; epicsMutexId axisMutex; @@ -74,15 +90,15 @@ typedef struct AXIS_HDL pFirst; epicsThreadId motorThread; motorAxisLogFunc print; + void * logParam; epicsTimeStamp now; } motorSim_t; static int motorSimLogMsg( void * param, const motorAxisLogMask_t logMask, const char *pFormat, ...); -#define PRINT (drv.print) -#define FLOW motorAxisTraceFlow -#define ERROR motorAxisTraceError +#define TRACE_FLOW motorAxisTraceFlow +#define TRACE_ERROR motorAxisTraceError -static motorSim_t drv={ NULL, NULL, motorSimLogMsg, { 0, 0 } }; +static motorSim_t drv={ NULL, NULL, motorSimLogMsg, NULL, { 0, 0 } }; #define MAX(a,b) ((a)>(b)? (a): (b)) #define MIN(a,b) ((a)<(b)? (a): (b)) @@ -129,22 +145,35 @@ static int motorAxisInit( void ) return MOTOR_AXIS_OK; } -static int motorAxisSetLog( motorAxisLogFunc logFunc ) +static int motorAxisSetLog( AXIS_HDL pAxis, motorAxisLogFunc logFunc, void * param ) { - if (logFunc == NULL) drv.print=motorSimLogMsg; - else drv.print = logFunc; - - return MOTOR_AXIS_OK; -} - -static int motorAxisSetLogParam( AXIS_HDL pAxis, void * param ) -{ - if (pAxis == NULL) return MOTOR_AXIS_ERROR; - else + if (pAxis == NULL) { - pAxis->logParam = param; + if (logFunc == NULL) + { + drv.print=motorSimLogMsg; + drv.logParam = NULL; + } + else + { + drv.print=logFunc; + drv.logParam = param; + } } - return MOTOR_AXIS_OK; + else + { + if (logFunc == NULL) + { + pAxis->print=motorSimLogMsg; + pAxis->logParam = NULL; + } + else + { + pAxis->print=logFunc; + pAxis->logParam = param; + } + } + return MOTOR_AXIS_OK; } static AXIS_HDL motorAxisOpen( int card, int axis, char * param ) @@ -190,11 +219,6 @@ static int motorAxisSetCallback( AXIS_HDL pAxis, motorAxisCallbackFunc callback, } } -static int motorAxisPrimitive( AXIS_HDL pAxis, int length, char * string ) -{ - return MOTOR_AXIS_OK; -} - static int motorAxisSetDouble( AXIS_HDL pAxis, motorAxisParam_t function, double value ) { int status = MOTOR_AXIS_OK; @@ -207,47 +231,47 @@ static int motorAxisSetDouble( AXIS_HDL pAxis, motorAxisParam_t function, double case motorAxisPosition: { pAxis->enc_offset = value - pAxis->nextpoint.axis[0].p; - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d to position %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to position %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisResolution: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d resolution to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d resolution to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisEncoderRatio: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d to enc. ratio to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to enc. ratio to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisLowLimit: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d low limit to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d low limit to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisHighLimit: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d high limit to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d high limit to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisPGain: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d pgain to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d pgain to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisIGain: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d igain to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d igain to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisDGain: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d dgain to %f", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d dgain to %f", pAxis->card, pAxis->axis, value ); break; } case motorAxisClosedLoop: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d closed loop to %s", pAxis->card, pAxis->axis, (value!=0?"ON":"OFF") ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d closed loop to %s", pAxis->card, pAxis->axis, (value!=0?"ON":"OFF") ); break; } default: @@ -272,22 +296,22 @@ static int motorAxisSetInteger( AXIS_HDL pAxis, motorAxisParam_t function, int v case motorAxisPosition: { pAxis->enc_offset = (double) value - pAxis->nextpoint.axis[0].p; - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d to position %d", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to position %d", pAxis->card, pAxis->axis, value ); break; } case motorAxisLowLimit: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d low limit to %d", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d low limit to %d", pAxis->card, pAxis->axis, value ); break; } case motorAxisHighLimit: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d high limit to %d", pAxis->card, pAxis->axis, value ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d high limit to %d", pAxis->card, pAxis->axis, value ); break; } case motorAxisClosedLoop: { - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d closed loop to %s", pAxis->card, pAxis->axis, (value?"ON":"OFF") ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d closed loop to %s", pAxis->card, pAxis->axis, (value?"ON":"OFF") ); break; } default: @@ -325,8 +349,8 @@ static int motorAxisMove( AXIS_HDL pAxis, double position, int relative, double motorParam->setInteger( pAxis->params, motorAxisMoving, 1 ); epicsMutexUnlock( pAxis->axisMutex ); - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d move to %f, min vel=%f, max_vel=%f, accel=%f", - pAxis->card, pAxis->axis, position, min_velocity, max_velocity, acceleration ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d move to %f, min vel=%f, max_vel=%f, accel=%f", + pAxis->card, pAxis->axis, position, min_velocity, max_velocity, acceleration ); } } return MOTOR_AXIS_OK; @@ -370,8 +394,8 @@ static int motorAxisHome( AXIS_HDL pAxis, double min_velocity, double max_veloci status = motorAxisVelocity( pAxis, (forwards? max_velocity: -max_velocity), acceleration ); pAxis->homing = 1; - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d to home %s, min vel=%f, max_vel=%f, accel=%f", - pAxis->card, pAxis->axis, (forwards?"FORWARDS":"REVERSE"), min_velocity, max_velocity, acceleration ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to home %s, min vel=%f, max_vel=%f, accel=%f", + pAxis->card, pAxis->axis, (forwards?"FORWARDS":"REVERSE"), min_velocity, max_velocity, acceleration ); } return status; } @@ -388,8 +412,8 @@ static int motorAxisVelocityMove( AXIS_HDL pAxis, double min_velocity, double v { status = motorAxisVelocity( pAxis, velocity, acceleration ); epicsMutexUnlock( pAxis->axisMutex ); - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d move with velocity of %f, accel=%f", - pAxis->card, pAxis->axis, velocity, acceleration ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d move with velocity of %f, accel=%f", + pAxis->card, pAxis->axis, velocity, acceleration ); } } return status; @@ -412,8 +436,8 @@ static int motorAxisStop( AXIS_HDL pAxis, double acceleration ) { motorAxisVelocity( pAxis, 0.0, acceleration ); - PRINT( pAxis->logParam, FLOW, "Set card %d, axis %d to stop with accel=%f", - pAxis->card, pAxis->axis, acceleration ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Set card %d, axis %d to stop with accel=%f", + pAxis->card, pAxis->axis, acceleration ); } return MOTOR_AXIS_OK; } @@ -555,8 +579,10 @@ static int motorSimCreateAxis( motorSim_t * pDrv, int card, int axis, double low pAxis->hiHardLimit = hiLimit; pAxis->lowHardLimit = lowLimit; pAxis->home = home; + pAxis->print = motorSimLogMsg; + pAxis->logParam = NULL; *ppLast = pAxis; - PRINT( pAxis->logParam, FLOW, "Created motor for card %d, signal %d OK", card, axis ); + pAxis->print( pAxis->logParam, TRACE_FLOW, "Created motor for card %d, signal %d OK", card, axis ); } else { @@ -575,13 +601,13 @@ static int motorSimCreateAxis( motorSim_t * pDrv, int card, int axis, double low } else { - PRINT( pAxis->logParam, ERROR, "Motor for card %d, signal %d already exists", card, axis ); + pAxis->print( pAxis->logParam, TRACE_ERROR, "Motor for card %d, signal %d already exists", card, axis ); return MOTOR_AXIS_ERROR; } if (pAxis == NULL) { - PRINT( pAxis->logParam, ERROR, "Cannot create motor for card %d, signal %d", card, axis ); + pAxis->print( pAxis->logParam, TRACE_ERROR, "Cannot create motor for card %d, signal %d", card, axis ); return MOTOR_AXIS_ERROR; } @@ -589,7 +615,7 @@ static int motorSimCreateAxis( motorSim_t * pDrv, int card, int axis, double low } -void motorSimCreate( int card, int axis, double lowLimit, double hiLimit, double home, int nCards, int nAxes ) +void motorSimCreate( int card, int axis, int lowLimit, int hiLimit, int home, int nCards, int nAxes ) { int i; int j; @@ -597,8 +623,8 @@ void motorSimCreate( int card, int axis, double lowLimit, double hiLimit, double if (nCards < 1) nCards = 1; if (nAxes < 1 ) nAxes = 1; - PRINT( NULL, FLOW, - "Creating motor simulator: card: %d, axis: %d, hi: %f, low %f, home: %f, ncards: %d, naxis: %d", + drv.print( drv.logParam, TRACE_FLOW, + "Creating motor simulator: card: %d, axis: %d, hi: %d, low %d, home: %d, ncards: %d, naxis: %d", card, axis, hiLimit, lowLimit, home, nCards, nAxes ); if (drv.motorThread==NULL) @@ -610,7 +636,7 @@ void motorSimCreate( int card, int axis, double lowLimit, double hiLimit, double if (drv.motorThread == NULL) { - PRINT( NULL, ERROR, "Cannot start motor simulation thread" ); + drv.print( drv.logParam, TRACE_ERROR, "Cannot start motor simulation thread" ); return; } } @@ -619,7 +645,7 @@ void motorSimCreate( int card, int axis, double lowLimit, double hiLimit, double { for (j = axis; j < axis+nAxes; j++ ) { - motorSimCreateAxis( &drv, i, j, lowLimit, hiLimit, home ); + motorSimCreateAxis( &drv, i, j, (double) lowLimit, (double) hiLimit, (double) home ); } } } @@ -633,6 +659,6 @@ static int motorSimLogMsg( void * param, const motorAxisLogMask_t mask, const ch va_start(pvar, pFormat); nchar = vfprintf(stdout,pFormat,pvar); va_end (pvar); - printf("\n"); + fprintf(stdout,"\n"); return(nchar); } diff --git a/motorApp/MotorSimSrc/drvMotorSim.h b/motorApp/MotorSimSrc/drvMotorSim.h index 63f54342..b0489418 100644 --- a/motorApp/MotorSimSrc/drvMotorSim.h +++ b/motorApp/MotorSimSrc/drvMotorSim.h @@ -5,7 +5,7 @@ extern "C" { #endif -void motorSimCreate( int card, int axis, double hiLimit, double lowLimit, double home, int nCards, int nAxes ); +void motorSimCreate( int card, int axis, int hiLimit, int lowLimit, int home, int nCards, int nAxes ); #ifdef __cplusplus } diff --git a/motorApp/MotorSimSrc/motorSimRegister.cc b/motorApp/MotorSimSrc/motorSimRegister.cc index d3131621..aa98aec5 100644 --- a/motorApp/MotorSimSrc/motorSimRegister.cc +++ b/motorApp/MotorSimSrc/motorSimRegister.cc @@ -6,9 +6,9 @@ extern "C" { static const iocshArg motorSimCreateArg0 = { "Card", iocshArgInt}; static const iocshArg motorSimCreateArg1 = { "Signal", iocshArgInt}; -static const iocshArg motorSimCreateArg2 = { "High limit", iocshArgDouble}; -static const iocshArg motorSimCreateArg3 = { "Low limit", iocshArgDouble}; -static const iocshArg motorSimCreateArg4 = { "Home position", iocshArgDouble}; +static const iocshArg motorSimCreateArg2 = { "High limit", iocshArgInt}; +static const iocshArg motorSimCreateArg3 = { "Low limit", iocshArgInt}; +static const iocshArg motorSimCreateArg4 = { "Home position", iocshArgInt}; static const iocshArg motorSimCreateArg5 = { "Num cards", iocshArgInt}; static const iocshArg motorSimCreateArg6 = { "Num signals", iocshArgInt}; @@ -25,7 +25,7 @@ static const iocshFuncDef motorSimCreateDef ={"motorSimCreate",7,motorSimCreateA static void motorSimCreateCallFunc(const iocshArgBuf *args) { - motorSimCreate(args[0].ival, args[1].ival, args[2].dval, args[3].dval, args[4].dval, args[5].ival, args[6].ival); + motorSimCreate(args[0].ival, args[1].ival, args[2].ival, args[3].ival, args[4].ival, args[5].ival, args[6].ival); } void motorSimRegister(void) diff --git a/motorApp/MotorSimSrc/motorSimTest.src b/motorApp/MotorSimSrc/motorSimTest.src index 913ecbc9..a5c140f2 100644 --- a/motorApp/MotorSimSrc/motorSimTest.src +++ b/motorApp/MotorSimSrc/motorSimTest.src @@ -1,38 +1,38 @@ -#!$(INSTALL)/bin/$(ARCH)/motorSim - -## You may have to change test to something else -## everywhere it appears in this file - -cd "$(INSTALL)" - -# Load binaries on architectures that need to do so. -# VXWORKS_ONLY, LINUX_ONLY and RTEMS_ONLY are macros that resolve -# to a comment symbol on architectures that are not the current -# build architecture, so they can be used liberally to do architecture -# specific things. Alternatively, you can include an architecture -# specific file. -$(VXWORKS_ONLY)ld < bin/$(ARCH)/test.munch - -## This drvTS initializer is needed if the IOC has a hardware event system -#TSinit - -## Register all support components -dbLoadDatabase("dbd/motorSim.dbd") -motorSim_registerRecordDeviceDriver(pdbbase) - -## Load record instances -dbLoadRecords("db/motorSimTest.db","DEVICE=npr78") -#dbLoadRecords("db/dbExample2.db","user=npr78,no=1,scan=1 second") -#dbLoadRecords("db/dbExample2.db","user=npr78,no=2,scan=2 second") -#dbLoadRecords("db/dbExample2.db","user=npr78,no=3,scan=5 second") -#dbLoadRecords("db/dbSubExample.db","user=npr78") - -## Set this to see messages from mySub -#mySubDebug 1 - -motorSimCreate( 0, 0, -32000, 32000, 0, 1, 1 ) - -iocInit() - -## Start any sequence programs -#seq sncExample,"user=npr78Host" +#!$(INSTALL)/bin/$(ARCH)/motorSim + +## You may have to change test to something else +## everywhere it appears in this file + +cd "$(INSTALL)" + +# Load binaries on architectures that need to do so. +# VXWORKS_ONLY, LINUX_ONLY and RTEMS_ONLY are macros that resolve +# to a comment symbol on architectures that are not the current +# build architecture, so they can be used liberally to do architecture +# specific things. Alternatively, you can include an architecture +# specific file. +$(VXWORKS_ONLY)ld < bin/$(ARCH)/motorSim.munch + +## This drvTS initializer is needed if the IOC has a hardware event system +#TSinit + +## Register all support components +dbLoadDatabase("dbd/motorSim.dbd") +motorSim_registerRecordDeviceDriver(pdbbase) + +## Load record instances +dbLoadRecords("db/motorSimTest.db","DEVICE=motorSim") +#dbLoadRecords("db/dbExample2.db","user=npr78,no=1,scan=1 second") +#dbLoadRecords("db/dbExample2.db","user=npr78,no=2,scan=2 second") +#dbLoadRecords("db/dbExample2.db","user=npr78,no=3,scan=5 second") +#dbLoadRecords("db/dbSubExample.db","user=npr78") + +## Set this to see messages from mySub +#mySubDebug 1 + +motorSimCreate( 0, 0, -32000, 32000, 0, 1, 1 ) + +iocInit() + +## Start any sequence programs +#seq sncExample,"user=npr78Host" diff --git a/motorApp/MotorSrc/devMotorAsyn.c b/motorApp/MotorSrc/devMotorAsyn.c index 4c0006ce..9852c07d 100644 --- a/motorApp/MotorSrc/devMotorAsyn.c +++ b/motorApp/MotorSrc/devMotorAsyn.c @@ -1,5 +1,23 @@ -/* devMotorAsyn.c */ -/* Example device support module */ +/* + * devMotorAsyn.c + * + * Motor record common Asyn device support layer + * + * Copyright (C) 2005-6 Peter Denison, Diamond Light Source + * + * This software is distributed subject to the EPICS Open Licence, which can + * be found at http://www.aps.anl.gov/epics/licence/open.php + * + * Notwithstanding the above, explicit permission is granted for APS to + * redistribute this software. + * + * Version: $Revision: 1.10 $ + * Modified by: $Author: peterd $ + * Last Modified: $Date: 2006-06-06 08:50:14 $ + * + * Original Author: Peter Denison + * Current Author: Peter Denison + */ #include #include @@ -116,7 +134,7 @@ static long init_record(struct motorRecord * pmr ) status = pasynManager->connectDevice(pasynUser, port, signal); if (status != asynSuccess) { asynPrint(pasynUser, ASYN_TRACE_ERROR, - "devMcaAsyn::init_record, %s connectDevice failed to %s\n", + "devMotorAsyn::init_record, %s connectDevice failed to %s\n", pmr->name, port); goto bad; } @@ -358,6 +376,12 @@ static RTN_STATUS build_trans( motor_cmnd command, pmsg->ivalue = 0; pmsg->interface = int32Type; break; + case PRIMITIVE: + asynPrint(pasynUser, ASYN_TRACE_ERROR, + "devMotorAsyn::send_msg: %s: PRIMITIVE no longer supported\n", + pmr->name); + return(ERROR); + break; case SET_HIGH_LIMIT: pmsg->command = motorHighLim; pmsg->dvalue = *param; @@ -378,7 +402,10 @@ static RTN_STATUS build_trans( motor_cmnd command, pmsg->dvalue = *param; break; default: - status = ERROR; + asynPrint(pasynUser, ASYN_TRACE_ERROR, + "devMotorAsyn::send_msg: %s: motor command %d not recognised\n", + pmr->name, command); + return(ERROR); } /* Queue asyn request, so we get a callback when driver is ready */ @@ -398,6 +425,11 @@ static RTN_STATUS end_trans(struct motorRecord * pmr ) return(OK); } +/** + * Called once the request comes off the Asyn internal queue. + * + * The request is still "on its way down" at this point + */ static void asynCallback(asynUser *pasynUser) { motorAsynPvt *pPvt = (motorAsynPvt *)pasynUser->userPvt; @@ -443,6 +475,9 @@ static void asynCallback(asynUser *pasynUser) } } +/** + * True callback to notify that controller status has changed. + */ static void statusCallback(void *drvPvt, asynUser *pasynUser, epicsInt32 value) { @@ -467,6 +502,9 @@ static void statusCallback(void *drvPvt, asynUser *pasynUser, } } +/** + * True callback to notify that controller position has changed. + */ static void positionCallback(void *drvPvt, asynUser *pasynUser, epicsFloat64 value) { @@ -491,6 +529,9 @@ static void positionCallback(void *drvPvt, asynUser *pasynUser, } } +/** + * True callback to notify that controller encoder position has changed. + */ static void encoderCallback(void *drvPvt, asynUser *pasynUser, epicsFloat64 value) { diff --git a/motorApp/MotorSrc/drvMotorAsyn.c b/motorApp/MotorSrc/drvMotorAsyn.c index 68d11922..d751607d 100644 --- a/motorApp/MotorSrc/drvMotorAsyn.c +++ b/motorApp/MotorSrc/drvMotorAsyn.c @@ -1,15 +1,31 @@ -/* drvMotorAsyn.c - - Derived from ip330 driver from GSE-CARS - Original Authors: Jim Kowalkowski, Mark Rivers, Joe Sullivan, and Marty Kraimer -********************COPYRIGHT NOTIFICATION********************************** -This software was developed under a United States Government license -described on the COPYRIGHT_UniversityOfChicago file included as part -of this distribution. -**************************************************************************** - - 22-Sep-2005 Peter Denison -*/ +/* + * drvMotorAsyn.c + * + * Motor record common Asyn driver support layer + * + * Copyright (C) 2005-6 Peter Denison, Diamond Light Source + * + * This software is distributed subject to the EPICS Open Licence, which can + * be found at http://www.aps.anl.gov/epics/licence/open.php + * + * Notwithstanding the above, explicit permission is granted for APS to + * redistribute this software. + * + * Derived from ip330 driver from GSE-CARS which was: + * Original Authors: Jim Kowalkowski, Mark Rivers, Joe Sullivan, and Marty Kraimer + * ********************COPYRIGHT NOTIFICATION****************************** + * This software was developed under a United States Government license + * described on the COPYRIGHT_UniversityOfChicago file included as part + * of this distribution. + * ************************************************************************ + * + * Version: $Revision: 1.8 $ + * Modified by: $Author: peterd $ + * Last Modified: $Date: 2006-06-06 08:50:14 $ + * + * Original Author: Peter Denison + * Current Author: Peter Denison + */ #include #include @@ -92,6 +108,7 @@ typedef struct drvmotorPvt { char *portName; motorAxisDrvSET_t *drvset; int card; + int numAxes; drvmotorAxisPvt *axisData; /* Housekeeping */ epicsMutexId lock; @@ -171,13 +188,17 @@ static asynDrvUser drvMotorDrvUser = { drvUserDestroy }; +static asynUser *defaultAsynUser; + -int drvAsynMotorConfigure(const char *portName, const char *driverName, int card, int num_axes) +int drvAsynMotorConfigure(const char *portName, const char *driverName, + int card, int num_axes, int can_block) { drvmotorPvt *pPvt; drvmotorAxisPvt *pAxis; asynStatus status; int i; + int attributes; pPvt = callocMustSucceed(1, sizeof(*pPvt), "drvAsynMotorConfigure"); pPvt->portName = epicsStrDup(portName); @@ -203,8 +224,13 @@ int drvAsynMotorConfigure(const char *portName, const char *driverName, int card pPvt->drvUser.interfaceType = asynDrvUserType; pPvt->drvUser.pinterface = (void *)&drvMotorDrvUser; pPvt->drvUser.drvPvt = pPvt; + + attributes = ASYN_MULTIDEVICE; + if (can_block) { + attributes |= ASYN_CANBLOCK; + } status = pasynManager->registerPort(portName, - ASYN_MULTIDEVICE, /*is multiDevice*/ + attributes, 1, /* autoconnect */ 0, /* medium priority */ 0); /* default stack size */ @@ -257,10 +283,16 @@ int drvAsynMotorConfigure(const char *portName, const char *driverName, int card pPvt->card = card; config(pPvt); + pPvt->numAxes = num_axes; + pPvt->axisData = callocMustSucceed(num_axes, sizeof(drvmotorAxisPvt), "drvAsynMotorConfigure"); for ( i = 0; i < num_axes; i++) { pAxis = &pPvt->axisData[i]; pAxis->axis = (*pPvt->drvset->open)(card, i, ""); + if (!pAxis->axis) { + asynPrint(pPvt->pasynUser, ASYN_TRACE_ERROR, + "drvAsynMotorConfigure: Failed to open axis %d\n", i); + } pAxis->num = i; pAxis->pPvt = pPvt; /* Create asynUser for debugging */ @@ -271,11 +303,17 @@ int drvAsynMotorConfigure(const char *portName, const char *driverName, int card errlogPrintf("drvAsynMotorConfigure, connectDevice failed\n"); return -1; } - (*pPvt->drvset->setCallback)(pAxis->axis, intCallback, (void *)pAxis); - (*pPvt->drvset->setLogParam)(pAxis->axis, pAxis->pasynUser); - (*pPvt->drvset->setLog)(logFunc); + if (pAxis->axis) { + (*pPvt->drvset->setCallback)(pAxis->axis, intCallback, (void *)pAxis); + (*pPvt->drvset->setLog)(pAxis->axis, logFunc, pAxis->pasynUser); + } setDefaults(pAxis); } + /* Create a fallback asynUser for logging, but only the first time */ + if (!defaultAsynUser) { + defaultAsynUser = pasynManager->createAsynUser(0,0); + } + (*pPvt->drvset->setLog)(NULL, logFunc, defaultAsynUser ); return 0; } @@ -296,9 +334,23 @@ static asynStatus readInt32(void *drvPvt, asynUser *pasynUser, motorCommand command = pasynUser->reason; pasynManager->getAddr(pasynUser, &channel); + if (channel >= pPvt->numAxes) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::readInt32 Invalid axis %d", channel); + return(asynError); + } + pAxis = &pPvt->axisData[channel]; + if (!pAxis->axis) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::readInt32 Uninitialised axis %d", pAxis->num); + return(asynError); + } switch(command) { + case motorStatus: + *value = pAxis->status; + break; case motorPosition: case motorEncoderPosition: (*pPvt->drvset->getInteger)(pAxis->axis, command, value); @@ -325,7 +377,18 @@ static asynStatus readFloat64(void *drvPvt, asynUser *pasynUser, asynStatus status = asynSuccess; pasynManager->getAddr(pasynUser, &channel); + if (channel >= pPvt->numAxes) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::readFloat64 Invalid axis %d", channel); + return(asynError); + } + pAxis = &pPvt->axisData[channel]; + if (!pAxis->axis) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::readFloat64 Uninitialised axis %d", pAxis->num); + return(asynError); + } switch(command) { case motorVelocity: @@ -372,7 +435,18 @@ static asynStatus writeInt32(void *drvPvt, asynUser *pasynUser, asynStatus status; pasynManager->getAddr(pasynUser, &channel); + if (channel >= pPvt->numAxes) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::writeInt32 Invalid axis %d", channel); + return(asynError); + } + pAxis = &pPvt->axisData[channel]; + if (!pAxis->axis) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::writeInt32 Uninitialised axis %d", pAxis->num); + return(asynError); + } switch(command) { case motorStop: @@ -409,7 +483,18 @@ static asynStatus writeFloat64(void *drvPvt, asynUser *pasynUser, asynStatus status = asynError; pasynManager->getAddr(pasynUser, &channel); + if (channel >= pPvt->numAxes) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::writeFloat64 Invalid axis %d", channel); + return(asynError); + } + pAxis = &pPvt->axisData[channel]; + if (!pAxis->axis) { + epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, + "drvMotorAsyn::writeFloat64 Uninitialised axis %d", pAxis->num); + return(asynError); + } asynPrint(pasynUser, ASYN_TRACE_FLOW, "drvMotorAsyn::writeFloat64, reason=%d, pasynUser=%p pAxis=%p\n", @@ -478,6 +563,10 @@ static int logFunc(void *userParam, va_list pvar; asynUser *pasynUser = (asynUser *)userParam; + if (!pasynUser) { + pasynUser = defaultAsynUser; + } + va_start(pvar, pFormat); switch(logMask) { case motorAxisTraceError: @@ -530,6 +619,48 @@ static void intCallback(void *axisPvt, unsigned int nChanged, } } + /* Pass float64 interrupts - these should be dealt with first, so that + * the position etc. are notified before the status, which is an int32. + * This is not a very robust way of dealing with the problem, but may work + * for now.*/ + pasynManager->interruptStart(pPvt->float64InterruptPvt, &pclientList); + pnode = (interruptNode *)ellFirst(pclientList); + while (pnode) { + asynFloat64Interrupt *pfloat64Interrupt = pnode->drvPvt; + addr = pfloat64Interrupt->addr; + reason = pfloat64Interrupt->pasynUser->reason; + if (addr == pAxis->num) { + for (i = 0; i < nChanged; i++) { + if (changed[i] == reason) { + (*pPvt->drvset->getDouble)(pAxis->axis, changed[i], &dvalue); + pfloat64Interrupt->callback(pfloat64Interrupt->userPvt, + pfloat64Interrupt->pasynUser, + dvalue); + } + } + } + pnode = (interruptNode *)ellNext(&pnode->node); + } + pasynManager->interruptEnd(pPvt->float64InterruptPvt); + + /* Pass float64Array interrupts */ + pasynManager->interruptStart(pPvt->float64ArrayInterruptPvt, &pclientList); + pnode = (interruptNode *)ellFirst(pclientList); + while (pnode) { + asynFloat64ArrayInterrupt *pfloat64ArrayInterrupt = pnode->drvPvt; + reason = pfloat64ArrayInterrupt->pasynUser->reason; + switch(reason) { + case motorPosition: + /* pfloat64ArrayInterrupt->callback(pfloat64ArrayInterrupt->userPvt, + pfloat64ArrayInterrupt->pasynUser, + pPvt->position, + MAX_AXES);*/ + break; + } + pnode = (interruptNode *)ellNext(&pnode->node); + } + pasynManager->interruptEnd(pPvt->float64ArrayInterruptPvt); + /* Pass int32 interrupts */ pasynManager->interruptStart(pPvt->int32InterruptPvt, &pclientList); pnode = (interruptNode *)ellFirst(pclientList); @@ -558,50 +689,6 @@ static void intCallback(void *axisPvt, unsigned int nChanged, pnode = (interruptNode *)ellNext(&pnode->node); } pasynManager->interruptEnd(pPvt->int32InterruptPvt); - - /* Pass float64 interrupts */ - pasynManager->interruptStart(pPvt->float64InterruptPvt, &pclientList); - pnode = (interruptNode *)ellFirst(pclientList); - while (pnode) { - asynFloat64Interrupt *pfloat64Interrupt = pnode->drvPvt; - addr = pfloat64Interrupt->addr; - reason = pfloat64Interrupt->pasynUser->reason; - if (addr == pAxis->num) { - switch(reason) { - case motorPosition: - case motorEncoderPosition: - for (i = 0; i < nChanged; i++) { - if (changed[i] == reason) { - (*pPvt->drvset->getDouble)(pAxis->axis, changed[i], &dvalue); - pfloat64Interrupt->callback(pfloat64Interrupt->userPvt, - pfloat64Interrupt->pasynUser, - dvalue); - } - } - break; - } - } - pnode = (interruptNode *)ellNext(&pnode->node); - } - pasynManager->interruptEnd(pPvt->float64InterruptPvt); - - /* Pass float64Array interrupts */ - pasynManager->interruptStart(pPvt->float64ArrayInterruptPvt, &pclientList); - pnode = (interruptNode *)ellFirst(pclientList); - while (pnode) { - asynFloat64ArrayInterrupt *pfloat64ArrayInterrupt = pnode->drvPvt; - reason = pfloat64ArrayInterrupt->pasynUser->reason; - switch(reason) { - case motorPosition: - /* pfloat64ArrayInterrupt->callback(pfloat64ArrayInterrupt->userPvt, - pfloat64ArrayInterrupt->pasynUser, - pPvt->position, - MAX_AXES);*/ - break; - } - pnode = (interruptNode *)ellNext(&pnode->node); - } - pasynManager->interruptEnd(pPvt->float64ArrayInterruptPvt); } @@ -710,7 +797,7 @@ static void report(void *drvPvt, FILE *fp, int details) } pasynManager->interruptEnd(pPvt->float64InterruptPvt); - /* Report int32Array interrupts */ + /* Report float64Array interrupts */ pasynManager->interruptStart(pPvt->float64ArrayInterruptPvt, &pclientList); pnode = (interruptNode *)ellFirst(pclientList); while (pnode) { @@ -745,15 +832,17 @@ static const iocshArg initArg0 = { "portName",iocshArgString}; static const iocshArg initArg1 = { "driverName",iocshArgString}; static const iocshArg initArg2 = { "cardNum",iocshArgInt}; static const iocshArg initArg3 = { "numAxes",iocshArgInt}; -static const iocshArg * const initArgs[4] = {&initArg0, +static const iocshArg initArg4 = { "canBlock",iocshArgInt}; +static const iocshArg * const initArgs[5] = {&initArg0, &initArg1, &initArg2, - &initArg3}; -static const iocshFuncDef initFuncDef = {"drvAsynMotorConfigure",4,initArgs}; + &initArg3, + &initArg4}; +static const iocshFuncDef initFuncDef = {"drvAsynMotorConfigure",5,initArgs}; static void initCallFunc(const iocshArgBuf *args) { drvAsynMotorConfigure(args[0].sval, args[1].sval, args[2].ival, - args[3].ival); + args[3].ival, args[4].ival); } void motorRegister(void) diff --git a/motorApp/MotorSrc/motor_interface.h b/motorApp/MotorSrc/motor_interface.h index 0ce4eede..354f4d70 100644 --- a/motorApp/MotorSrc/motor_interface.h +++ b/motorApp/MotorSrc/motor_interface.h @@ -165,8 +165,9 @@ The latter could be used for the primitive record approach, and the former for the motor record. Finally, in the PREM and the POST fields aren't seen in this -implementation - I assume they are handled via device support calling -motorAxisPrimitive. +implementation - This functionality is no longer supported through the +motor record and should be done by linking to controller specific +device support. \section Status Analysis of commands that provide status information @@ -301,8 +302,8 @@ typedef enum typedef int (*motorAxisLogFunc)( void * userParam, const motorAxisLogMask_t logMask, const char *pFormat, ...); -typedef int (*motorAxisSetLogFunc)( motorAxisLogFunc logFunc ); -typedef int (*motorAxisSetLogParamFunc)( AXIS_HDL pAxis, void * param ); + +typedef int (*motorAxisSetLogFunc)( AXIS_HDL pAxis, motorAxisLogFunc logFunc, void * param ); /** Provide an external logging routine. @@ -315,30 +316,19 @@ typedef int (*motorAxisSetLogParamFunc)( AXIS_HDL pAxis, void * param ); - enabling tracing of errors, flow, and device filter and driver layers. infomational, minor, major or fatal. + If pAxis is NULL, then this logging function and parameter should be used as + a default - i.e. when logging is not taking place in the context of a single + axis (a background polling task, for example). + + \param pAxis [in] Pointer to axis handle returned by motorAxisOpen. \param logFunc [in] Pointer to function of motorAxisLogFunc type. + \param param [in] Pointer to the user parameter to be used for logging on this axis \return Integer indicating 0 (MOTOR_AXIS_OK) for success or non-zero for failure. */ #ifdef DEFINE_MOTOR_PROTOTYPES -static int motorAxisSetLog( motorAxisLogFunc logFunc ); -#endif - - -/** Provide an external logging routine axis specific user parameter. - - This is an optional function which allows external software to provide - axis specific data to the logging function to be used when logging - information about this axis. If the logging information is not axis - specific a NULL pointer should be supplied to the logging routine. - - \param param [in] Pointer to a user parameter to be used for logging on this axis - - \return Integer indicating 0 (MOTOR_AXIS_OK) for success or non-zero for failure. -*/ - -#ifdef DEFINE_MOTOR_PROTOTYPES -static int motorAxisSetLogParam( AXIS_HDL pAxis, void * param ); +static int motorAxisSetLog( AXIS_HDL pAxis, motorAxisLogFunc logFunc, void * param ); #endif /**@}*/ @@ -424,25 +414,6 @@ static int motorAxisSetCallback( AXIS_HDL pAxis, motorAxisCallbackFunc callback, @{ */ -typedef int (*motorAxisStringFunc)( AXIS_HDL pAxis, int, char * ); - -/** Pass a controller specific string to the controller - - This optional routine passes a controller specific string down to the controller. - The exact string format depends on the controller. The length parameter allows - the string to contain embedded nulls. - - \param pAxis [in] Pointer to axis handle returned by motorAxisOpen. - \param length [in] Length of the string to be passed to the controller. - \param string [in] Character string to be passed to the controller. - - \return Integer indicating 0 (MOTOR_AXIS_OK) for success or non-zero for failure. -*/ - -#ifdef DEFINE_MOTOR_PROTOTYPES -static int motorAxisPrimitive( AXIS_HDL pAxis, int length, char * string ); -#endif - typedef int (*motorAxisSetDoubleFunc)( AXIS_HDL pAxis, motorAxisParam_t, double ); /** Sets a double parameter in the controller. @@ -690,11 +661,9 @@ typedef struct motorAxisReportFunc report; /**< Standard EPICS driver report function (optional) */ motorAxisInitFunc init; /**< Standard EPICS dirver initialisation function (optional) */ motorAxisSetLogFunc setLog; /**< Defines an external logging function (optional) */ - motorAxisSetLogParamFunc setLogParam; /**< Defines a parameter to be used when calling the logging function for an axis */ motorAxisOpenFunc open; /**< Driver open function */ motorAxisCloseFunc close; /**< Driver close function */ motorAxisSetCallbackFunc setCallback; /**< Provides a callback function the driver can call when the status updates */ - motorAxisStringFunc primitive; /**< Passes a controller dependedent string */ motorAxisSetDoubleFunc setDouble; /**< Pointer to function to set a double value */ motorAxisSetIntegerFunc setInteger; /**< Pointer to function to set an integer value */ motorAxisGetDoubleFunc getDouble; /**< Pointer to function to get a double value */ diff --git a/motorApp/NewportSrc/drvMM4000Asyn.c b/motorApp/NewportSrc/drvMM4000Asyn.c index 435da7cf..835588df 100644 --- a/motorApp/NewportSrc/drvMM4000Asyn.c +++ b/motorApp/NewportSrc/drvMM4000Asyn.c @@ -26,15 +26,13 @@ motorAxisDrvSET_t motorMM4000 = { - 20, + 14, motorAxisReport, /**< Standard EPICS driver report function (optional) */ motorAxisInit, /**< Standard EPICS dirver initialisation function (optional) */ motorAxisSetLog, /**< Defines an external logging function (optional) */ - motorAxisSetLogParam, /**< Defines an external logging function user parameter (optional) */ motorAxisOpen, /**< Driver open function */ motorAxisClose, /**< Driver close function */ motorAxisSetCallback, /**< Provides a callback function the driver can call when the status updates */ - motorAxisPrimitive, /**< Passes a controller dependedent string */ motorAxisSetDouble, /**< Pointer to function to set a double value */ motorAxisSetInteger, /**< Pointer to function to set an integer value */ motorAxisGetDouble, /**< Pointer to function to get a double value */ @@ -78,6 +76,7 @@ typedef struct motorAxisHandle int card; int axis; int maxDigits; + motorAxisLogFunc print; void *logParam; epicsMutexId mutexId; } motorAxis; @@ -87,6 +86,7 @@ typedef struct AXIS_HDL pFirst; epicsThreadId motorThread; motorAxisLogFunc print; + void *logParam; epicsTimeStamp now; } motorMM4000_t; @@ -113,7 +113,7 @@ static int sendAndReceive(MM4000Controller *pController, char *outputString, cha #define TCP_TIMEOUT 2.0 -static motorMM4000_t drv={ NULL, NULL, motorMM4000LogMsg, { 0, 0 } }; +static motorMM4000_t drv={ NULL, NULL, motorMM4000LogMsg, 0, { 0, 0 } }; static int numMM4000Controllers; /* Pointer to array of controller strutures */ static MM4000Controller *pMM4000Controller=NULL; @@ -161,22 +161,35 @@ static int motorAxisInit(void) return MOTOR_AXIS_OK; } -static int motorAxisSetLog(motorAxisLogFunc logFunc) +static int motorAxisSetLog( AXIS_HDL pAxis, motorAxisLogFunc logFunc, void * param ) { - if (logFunc == NULL) drv.print=motorMM4000LogMsg; - else drv.print = logFunc; - - return MOTOR_AXIS_OK; -} - -static int motorAxisSetLogParam(AXIS_HDL pAxis, void * param) -{ - if (pAxis == NULL) return MOTOR_AXIS_ERROR; - else + if (pAxis == NULL) { - pAxis->logParam = param; + if (logFunc == NULL) + { + drv.print=motorMM4000LogMsg; + drv.logParam = NULL; + } + else + { + drv.print=logFunc; + drv.logParam = param; + } } - return MOTOR_AXIS_OK; + else + { + if (logFunc == NULL) + { + pAxis->print=motorMM4000LogMsg; + pAxis->logParam = NULL; + } + else + { + pAxis->print=logFunc; + pAxis->logParam = param; + } + } + return MOTOR_AXIS_OK; } static AXIS_HDL motorAxisOpen(int card, int axis, char * param) @@ -221,11 +234,6 @@ static int motorAxisSetCallback(AXIS_HDL pAxis, motorAxisCallbackFunc callback, } } -static int motorAxisPrimitive(AXIS_HDL pAxis, int length, char * string) -{ - return MOTOR_AXIS_OK; -} - static int motorAxisSetDouble(AXIS_HDL pAxis, motorAxisParam_t function, double value) { int ret_status = MOTOR_AXIS_ERROR; diff --git a/motorApp/NewportSrc/drvXPSAsyn.c b/motorApp/NewportSrc/drvXPSAsyn.c index 85f10cf6..c0b19d9c 100644 --- a/motorApp/NewportSrc/drvXPSAsyn.c +++ b/motorApp/NewportSrc/drvXPSAsyn.c @@ -26,15 +26,13 @@ motorAxisDrvSET_t motorXPS = { - 20, + 14, motorAxisReport, /**< Standard EPICS driver report function (optional) */ motorAxisInit, /**< Standard EPICS dirver initialisation function (optional) */ motorAxisSetLog, /**< Defines an external logging function (optional) */ - motorAxisSetLogParam, /**< Defines an external logging function user parameter (optional) */ motorAxisOpen, /**< Driver open function */ motorAxisClose, /**< Driver close function */ motorAxisSetCallback, /**< Provides a callback function the driver can call when the status updates */ - motorAxisPrimitive, /**< Passes a controller dependedent string */ motorAxisSetDouble, /**< Pointer to function to set a double value */ motorAxisSetInteger, /**< Pointer to function to set an integer value */ motorAxisGetDouble, /**< Pointer to function to get a double value */ @@ -82,6 +80,7 @@ typedef struct motorAxisHandle int positionerError; int card; int axis; + motorAxisLogFunc print; void *logParam; epicsMutexId mutexId; } motorAxis; @@ -91,11 +90,12 @@ typedef struct AXIS_HDL pFirst; epicsThreadId motorThread; motorAxisLogFunc print; + void *logParam; epicsTimeStamp now; } motorXPS_t; static int motorXPSLogMsg(void * param, const motorAxisLogMask_t logMask, const char *pFormat, ...); -#define PRINT (drv.print) +#define PRINT (pAxis->print) #define FLOW motorAxisTraceFlow #define ERROR motorAxisTraceError #define IODRIVER motorAxisTraceIODriver @@ -105,7 +105,7 @@ static int motorXPSLogMsg(void * param, const motorAxisLogMask_t logMask, const #define XPSC8_END_OF_RUN_PLUS 0x00000200 #define TCP_TIMEOUT 2.0 -static motorXPS_t drv={ NULL, NULL, motorXPSLogMsg, { 0, 0 } }; +static motorXPS_t drv={ NULL, NULL, motorXPSLogMsg, 0, { 0, 0 } }; static int numXPSControllers; /* Pointer to array of controller strutures */ static XPSController *pXPSController=NULL; @@ -144,22 +144,35 @@ static int motorAxisInit(void) return MOTOR_AXIS_OK; } -static int motorAxisSetLog(motorAxisLogFunc logFunc) +static int motorAxisSetLog( AXIS_HDL pAxis, motorAxisLogFunc logFunc, void * param ) { - if (logFunc == NULL) drv.print=motorXPSLogMsg; - else drv.print = logFunc; - - return MOTOR_AXIS_OK; -} - -static int motorAxisSetLogParam(AXIS_HDL pAxis, void * param) -{ - if (pAxis == NULL) return MOTOR_AXIS_ERROR; - else + if (pAxis == NULL) { - pAxis->logParam = param; + if (logFunc == NULL) + { + drv.print=motorXPSLogMsg; + drv.logParam = NULL; + } + else + { + drv.print=logFunc; + drv.logParam = param; + } } - return MOTOR_AXIS_OK; + else + { + if (logFunc == NULL) + { + pAxis->print=motorXPSLogMsg; + pAxis->logParam = NULL; + } + else + { + pAxis->print=logFunc; + pAxis->logParam = param; + } + } + return MOTOR_AXIS_OK; } static AXIS_HDL motorAxisOpen(int card, int axis, char * param) @@ -204,11 +217,6 @@ static int motorAxisSetCallback(AXIS_HDL pAxis, motorAxisCallbackFunc callback, } } -static int motorAxisPrimitive(AXIS_HDL pAxis, int length, char * string) -{ - return MOTOR_AXIS_OK; -} - static int motorAxisSetDouble(AXIS_HDL pAxis, motorAxisParam_t function, double value) { int ret_status = MOTOR_AXIS_ERROR;