forked from epics_driver_modules/motorBase
166 lines
5.9 KiB
C++
166 lines
5.9 KiB
C++
/* asynMotorAxis.cpp
|
|
*
|
|
* Mark Rivers
|
|
*
|
|
* This file defines the base class for an asynMotorAxis. It is the class
|
|
* from which real motor axes are derived.
|
|
*/
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <epicsThread.h>
|
|
|
|
#include <asynPortDriver.h>
|
|
#define epicsExportSharedSymbols
|
|
#include <shareLib.h>
|
|
#include "asynMotorAxis.h"
|
|
#include "asynMotorController.h"
|
|
|
|
static const char *driverName = "asynMotorAxis";
|
|
/** Creates a new asynMotorAxis object.
|
|
* \param[in] pC Pointer to the asynMotorController to which this axis belongs.
|
|
* \param[in] axisNo Index number of this axis, range 0 to pC->numAxes_-1.
|
|
*
|
|
* Checks that pC is not null, and that axisNo is in the valid range.
|
|
* Sets a pointer to itself in pC->pAxes[axisNo_].
|
|
* Connects pasynUser_ to this asyn port and axisNo.
|
|
*/
|
|
asynMotorAxis::asynMotorAxis(class asynMotorController *pC, int axisNo)
|
|
: pC_(pC), axisNo_(axisNo), statusChanged_(1)
|
|
{
|
|
static const char *functionName = "asynMotorAxis::asynMotorAxis";
|
|
|
|
if (!pC) {
|
|
printf("%s:%s: Error, controller is NULL\n",
|
|
driverName, functionName);
|
|
return;
|
|
}
|
|
if ((axisNo < 0) || (axisNo >= pC->numAxes_)) {
|
|
printf("%s:%s: Error, axis=%d is not in range 0 to %d\n",
|
|
driverName, functionName, axisNo, pC->numAxes_-1);
|
|
return;
|
|
}
|
|
pC->pAxes_[axisNo] = this;
|
|
status_.status = 0;
|
|
profilePositions_ = NULL;
|
|
profilePositionsRBV_ = NULL;
|
|
profileFollowingErrors_ = NULL;
|
|
|
|
// Create the asynUser, connect to this axis
|
|
pasynUser_ = pasynManager->createAsynUser(NULL, NULL);
|
|
pasynManager->connectDevice(pasynUser_, pC->portName, axisNo);
|
|
}
|
|
|
|
|
|
// We implement the setIntegerParam, setDoubleParam, and callParamCallbacks methods so we can construct
|
|
// the aggregate status structure and do callbacks on it
|
|
|
|
/** Sets the value for an integer for this axis in the parameter library.
|
|
* This function takes special action if the parameter is one of the motorStatus parameters
|
|
* (motorStatusDirection_, motorStatusHomed_, etc.). In that case it sets or clears the appropriate
|
|
* bit in its private MotorStatus.status structure and if that status has changed sets a flag to
|
|
* do callbacks to devMotorAsyn when callParamCallbacks() is called.
|
|
* \param[in] function The function (parameter) number
|
|
* \param[in] value Value to set */
|
|
asynStatus asynMotorAxis::setIntegerParam(int function, int value)
|
|
{
|
|
int mask;
|
|
epicsUInt32 status;
|
|
// This assumes the parameters defined above are in the same order as the bits the motor record expects!
|
|
if (function >= pC_->motorStatusDirection_ &&
|
|
function <= pC_->motorStatusHomed_) {
|
|
status = status_.status;
|
|
mask = 1 << (function - pC_->motorStatusDirection_);
|
|
if (value) status |= mask;
|
|
else status &= ~mask;
|
|
if (status != status_.status) {
|
|
status_.status = status;
|
|
statusChanged_ = 1;
|
|
}
|
|
}
|
|
// Call the base class method
|
|
return pC_->setIntegerParam(axisNo_, function, value);
|
|
}
|
|
|
|
/** Sets the value for a double for this axis in the parameter library.
|
|
* This function takes special action if the parameter is motorPosition_ or motorEncoderPosition_.
|
|
* In that case it sets the value in the private MotorStatus structure and if the value has changed
|
|
* then sets a flag to do callbacks to devMotorAsyn when callParamCallbacks() is called.
|
|
* \param[in] function The function (parameter) number
|
|
* \param[in] value Value to set */
|
|
asynStatus asynMotorAxis::setDoubleParam(int function, double value)
|
|
{
|
|
if (function == pC_->motorPosition_) {
|
|
if (value != status_.position) {
|
|
statusChanged_ = 1;
|
|
status_.position = value;
|
|
}
|
|
} else if (function == pC_->motorEncoderPosition_) {
|
|
if (value != status_.encoderPosition) {
|
|
statusChanged_ = 1;
|
|
status_.encoderPosition = value;
|
|
}
|
|
}
|
|
// Call the base class method
|
|
return pC_->setDoubleParam(axisNo_, function, value);
|
|
}
|
|
|
|
/** Calls the callbacks for any parameters that have changed for this axis in the parameter library.
|
|
* This function takes special action if the aggregate MotorStatus structure has changed.
|
|
* In that case it does callbacks on the asynGenericPointer interface, typically to devMotorAsyn. */
|
|
asynStatus asynMotorAxis::callParamCallbacks()
|
|
{
|
|
if (statusChanged_) {
|
|
statusChanged_ = 0;
|
|
pC_->doCallbacksGenericPointer((void *)&status_, pC_->motorStatus_, axisNo_);
|
|
}
|
|
return pC_->callParamCallbacks(axisNo_);
|
|
}
|
|
|
|
/* These are the functions for profile moves */
|
|
asynStatus asynMotorAxis::initializeProfile(int maxProfilePoints)
|
|
{
|
|
if (profilePositions_) free(profilePositions_);
|
|
profilePositions_ = (double *)calloc(maxProfilePoints, sizeof(double));
|
|
if (profilePositionsRBV_) free(profilePositionsRBV_);
|
|
profilePositionsRBV_ = (double *)calloc(maxProfilePoints, sizeof(double));
|
|
if (profileFollowingErrors_) free(profileFollowingErrors_);
|
|
profileFollowingErrors_ = (double *)calloc(maxProfilePoints, sizeof(double));
|
|
return asynSuccess;
|
|
}
|
|
|
|
/** Function to build a coordinated move of multiple axes. */
|
|
asynStatus asynMotorAxis::defineProfile(double *positions, int numPoints)
|
|
{
|
|
// static const char *functionName = "asynMotorController::buildProfile";
|
|
|
|
if (numPoints > pC_->maxProfilePoints_) return asynError;
|
|
memcpy(profilePositions_, positions, numPoints*sizeof(double));
|
|
|
|
return asynSuccess;
|
|
}
|
|
|
|
/** Function to build a coordinated move of multiple axes. */
|
|
asynStatus asynMotorAxis::buildProfile()
|
|
{
|
|
// static const char *functionName = "asynMotorController::buildProfile";
|
|
|
|
return asynSuccess;
|
|
}
|
|
|
|
/** Function to execute a coordinated move of multiple axes. */
|
|
asynStatus asynMotorAxis::executeProfile()
|
|
{
|
|
// static const char *functionName = "asynMotorController::executeProfile";
|
|
|
|
return asynSuccess;
|
|
}
|
|
|
|
/** Function to readback the actual motor positions from a coordinated move of multiple axes. */
|
|
asynStatus asynMotorAxis::readbackProfile()
|
|
{
|
|
// static const char *functionName = "asynMotorController::readbackProfile";
|
|
|
|
return asynSuccess;
|
|
}
|