forked from epics_driver_modules/motorBase
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
This commit is contained in:
@@ -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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user