diff --git a/motorApp/ACRSrc/ACRMotorDriver.cpp b/motorApp/ACRSrc/ACRMotorDriver.cpp index bad2335b..f010e09c 100644 --- a/motorApp/ACRSrc/ACRMotorDriver.cpp +++ b/motorApp/ACRSrc/ACRMotorDriver.cpp @@ -27,6 +27,13 @@ March 4, 2011 static const char *driverName = "ACRMotorDriver"; +/** Creates a new ACRController object. + * \param[in] portName The name of the asyn port that will be created for this driver + * \param[in] ACRPortName The name of the drvAsynIPPPort that was created previously to connect to the ACR controller + * \param[in] numAxes The number of axes that this controller supports + * \param[in] movingPollPeriod The time between polls when any axis is moving + * \param[in] idlePollPeriod The time between polls when no axis is moving + */ ACRController::ACRController(const char *portName, const char *ACRPortName, int numAxes, double movingPollPeriod, double idlePollPeriod) : asynMotorController(portName, numAxes, NUM_ACR_PARAMS, @@ -89,11 +96,18 @@ ACRController::ACRController(const char *portName, const char *ACRPortName, int callParamCallbacks(axis); } - startPoller(movingPollPeriod/1000., idlePollPeriod/1000.); + startPoller(movingPollPeriod/1000., idlePollPeriod/1000., 2); } -/** Configuration command, called directly or from iocsh */ +/** Creates a new ACRController object. + * Configuration command, called directly or from iocsh + * \param[in] portName The name of the asyn port that will be created for this driver + * \param[in] ACRPortName The name of the drvAsynIPPPort that was created previously to connect to the ACR controller + * \param[in] numAxes The number of axes that this controller supports + * \param[in] movingPollPeriod The time in ms between polls when any axis is moving + * \param[in] idlePollPeriod The time in ms between polls when no axis is moving + */ extern "C" int ACRCreateController(const char *portName, const char *ACRPortName, int numAxes, int movingPollPeriod, int idlePollPeriod) { @@ -103,6 +117,13 @@ extern "C" int ACRCreateController(const char *portName, const char *ACRPortName return(asynSuccess); } +/** Reports on status of the driver + * \param[in] fp The file pointer on which report information will be written + * \param[in] level The level of report detail desired + * + * If details > 0 then information is printed about each axis. + * After printing controller-specific information calls asynMotorController::report() + */ void ACRController::report(FILE *fp, int level) { int axis; @@ -132,17 +153,32 @@ void ACRController::report(FILE *fp, int level) asynMotorController::report(fp, level); } +/** Returns a pointer to an ACRMotorAxis object. + * Returns NULL if the axis number encoded in pasynUser is invalid. + * \param[in] pasynUser asynUser structure that encodes the axis index number. */ ACRAxis* ACRController::getAxis(asynUser *pasynUser) { return static_cast(asynMotorController::getAxis(pasynUser)); } +/** Returns a pointer to an ACRMotorAxis object. + * Returns NULL if the axis number encoded in pasynUser is invalid. + * \param[in] axisNo Axis index number. */ ACRAxis* ACRController::getAxis(int axisNo) { return static_cast(asynMotorController::getAxis(axisNo)); } +/** Called when asyn clients call pasynInt32->write(). + * Extracts the function and axis number from pasynUser. + * Sets the value in the parameter library. + * If the function is motorSetClosedLoop_ then it turns the drive power on or off. + * If the function is ACRReadBinaryIO_ then it reads the binary I/O registers on the controller. + * For all other functions it calls asynMotorController::writeInt32. + * Calls any registered callbacks for this pasynUser->reason and address. + * \param[in] pasynUser asynUser structure that encodes the reason and address. + * \param[in] value Value to write. */ asynStatus ACRController::writeInt32(asynUser *pasynUser, epicsInt32 value) { int function = pasynUser->reason; @@ -155,14 +191,7 @@ asynStatus ACRController::writeInt32(asynUser *pasynUser, epicsInt32 value) * status at the end, but that's OK */ status = setIntegerParam(pAxis->axisNo_, function, value); - if (function == motorDeferMoves_) - { - asynPrint(pasynUser, ASYN_TRACE_FLOW, - "%s:%s: %sing Deferred Move flag on driver %s\n", - value != 0.0?"Sett":"Clear", - driverName, functionName, this->portName); - } - else if (function == motorSetClosedLoop_) + if (function == motorSetClosedLoop_) { sprintf(outString_, "DRIVE %s %s", value ? "ON":"OFF", pAxis->axisName_); writeController(); @@ -193,6 +222,15 @@ asynStatus ACRController::writeInt32(asynUser *pasynUser, epicsInt32 value) return status; } +/** Called when asyn clients call pasynFloat64->write(). + * Extracts the function and axis number from pasynUser. + * Sets the value in the parameter library. + * If the function is ACRJerk_ it sets the jerk value in the controller. + * then it calls pAxis->move(), pAxis->moveVelocity(), pAxis->home(), or pAxis->setPosition(). + * Calls any registered callbacks for this pasynUser->reason and address. + * For all other functions it calls asynMotorController::writeFloat64. + * \param[in] pasynUser asynUser structure that encodes the reason and address. + * \param[in] value Value to write. */ asynStatus ACRController::writeFloat64(asynUser *pasynUser, epicsFloat64 value) { int function = pasynUser->reason; @@ -227,10 +265,15 @@ asynStatus ACRController::writeFloat64(asynUser *pasynUser, epicsFloat64 value) return status; } +/** Called when asyn clients call pasynUInt32Digital->write(). + * Writes a single bit to one of the ACR binary output registers. + * This function is limited to writing a single bit, because we use the BIT command. + * It writes to least significant bit that is set in the mask. + * \param[in] pasynUser pasynUser structure that encodes the reason and address. + * \param[in] value Value to write. + * \param[in] mask Mask value to use when writinging the value. */ asynStatus ACRController::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask) { - // This function is limited to writing a single bit, because we use the BIT command. - // It writes to least significant bit that is set in the mask int bit, tmask=0x1; asynStatus status; //static const char *functionName = "writeUInt32Digital"; @@ -247,6 +290,10 @@ asynStatus ACRController::writeUInt32Digital(asynUser *pasynUser, epicsUInt32 va return(status); } +/** Reads the binary input and binary output registers on the ACR. + * Sets the values in the parameter library. + * Keeps track of which bits have changed. + * Calls any registered callbacks for this pasynUser->reason and address. */ asynStatus ACRController::readBinaryIO() { asynStatus status; @@ -277,21 +324,16 @@ asynStatus ACRController::readBinaryIO() return status; } -asynStatus ACRController::triggerProfile(asynUser *pasynUser) -{ - return asynError; -} - -asynStatus ACRController::profileMove(asynUser *pasynUser, int npoints, double positions[], double times[], int relative, int trigger) -{ - return asynError; -} - +/** Writes a string to the ACR controller. + * Calls writeController() with a default location of the string to write and a default timeout. */ asynStatus ACRController::writeController() { return writeController(outString_, ACR_TIMEOUT); } +/** Writes a string to the ACR controller. + * \param[in] output The string to be written. + * \param[in] timeout Timeout before returning an error.*/ asynStatus ACRController::writeController(const char *output, double timeout) { size_t nwrite; @@ -304,12 +346,21 @@ asynStatus ACRController::writeController(const char *output, double timeout) return status ; } +/** Writes a string to the ACR controller and reads the response. + * Calls writeReadController() with default locations of the input and output strings + * and default timeout. */ asynStatus ACRController::writeReadController() { size_t nread; return writeReadController(outString_, inString_, sizeof(inString_), &nread, ACR_TIMEOUT); } +/** Writes a string to the ACR controller and reads a response. + * \param[in] output Pointer to the output string. + * \param[out] input Pointer to the input string location. + * \param[in] maxChars Size of the input buffer. + * \param[out] nread Number of characters read. + * \param[out] timeout Timeout before returning an error.*/ asynStatus ACRController::writeReadController(const char *output, char *input, size_t maxChars, size_t *nread, double timeout) { size_t nwrite; @@ -324,9 +375,18 @@ asynStatus ACRController::writeReadController(const char *output, char *input, s return status; } -ACRAxis::ACRAxis(ACRController *pController, int axisNo) - : asynMotorAxis(pController, axisNo), - pC_(pController) + +// These are the ACRAxis methods + +/** Creates a new ACRAxis object. + * \param[in] pC Pointer to the ACRController to which this axis belongs. + * \param[in] axisNo Index number of this axis, range 0 to pC->numAxes_-1. + * + * Initializes register numbers, etc. + */ +ACRAxis::ACRAxis(ACRController *pC, int axisNo) + : asynMotorAxis(pC, axisNo), + pC_(pC) { sprintf(axisName_, "AXIS%d", axisNo); encoderPositionReg_ = 12290 + 256*axisNo; @@ -414,6 +474,13 @@ asynStatus ACRAxis::setPosition(double position) return status; } +/** Polls the axis. + * This function reads the controller position, encoder position, the limit status, the moving status, + * and the drive power-on status. It does not current detect following error, etc. but this could be + * added. + * It calls setIntegerParam() and setDoubleParam() for each item that it polls, + * and then calls callParamCallbacks() at the end. + * \param[out] moving A flag that is set indicating that the axis is moving (1) or done (0). */ asynStatus ACRAxis::poll(int *moving) { int done; diff --git a/motorApp/ACRSrc/ACRMotorDriver.h b/motorApp/ACRSrc/ACRMotorDriver.h index d87dd9b2..ffa288c3 100644 --- a/motorApp/ACRSrc/ACRMotorDriver.h +++ b/motorApp/ACRSrc/ACRMotorDriver.h @@ -9,7 +9,7 @@ March 28, 2011 #include "asynMotorDriver.h" -// drvInfo strings for extra parameters that the ACR controller supports +/** drvInfo strings for extra parameters that the ACR controller supports */ #define ACRJerkString "ACR_JERK" #define ACRReadBinaryIOString "ACR_READ_BINARY_IO" #define ACRBinaryInString "ACR_BINARY_IN" @@ -22,7 +22,7 @@ class ACRAxis : public asynMotorAxis { public: /* These are the methods we override from the base class */ - ACRAxis(class ACRController *pController, int axis); + ACRAxis(class ACRController *pC, int axis); asynStatus move(double position, int relative, double min_velocity, double max_velocity, double acceleration); asynStatus moveVelocity(double min_velocity, double max_velocity, double acceleration); asynStatus home(double min_velocity, double max_velocity, double acceleration, int forwards); @@ -31,17 +31,18 @@ public: asynStatus setPosition(double position); private: - ACRController *pC_; - char axisName_[10]; - double pulsesPerUnit_; - int flagsReg_; - int limitsReg_; - int encoderPositionReg_; - int theoryPositionReg_; - double encoderPosition_; - double theoryPosition_; - int currentFlags_; - int currentLimits_; + ACRController *pC_; /**< Pointer to the asynMotorController to which this axis belongs. + * Abbreviated because it is used very frequently */ + char axisName_[10]; /**< Name of each axis, used in commands to ACR controller */ + double pulsesPerUnit_; /**< Pulses per engineering unit, which is what ACR controller uses */ + int flagsReg_; /**< Address of the flags register */ + int limitsReg_; /**< Address of the limits register */ + int encoderPositionReg_; /**< Address of the encoder position register */ + int theoryPositionReg_; /**< Address of the theoretical position register */ + double encoderPosition_; /**< Cached copy of the encoder position */ + double theoryPosition_; /**< Cached copy of the theoretical position */ + int currentFlags_; /**< Cached copy of the current flags */ + int currentLimits_; /**< Cached copy of the current limits */ friend class ACRController; }; @@ -49,16 +50,17 @@ friend class ACRController; class ACRController : public asynMotorController { public: ACRController(const char *portName, const char *ACRPortName, int numAxes, double movingPollPeriod, double idlePollPeriod); + + /* These are the methods that we override from asynPortDriver */ + asynStatus writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask); /* These are the methods that we override from asynMotorDriver */ asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value); asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value); - asynStatus writeUInt32Digital(asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask); void report(FILE *fp, int level); ACRAxis* getAxis(asynUser *pasynUser); ACRAxis* getAxis(int axisNo); - asynStatus profileMove(asynUser *pasynUser, int npoints, double positions[], double times[], int relative, int trigger); - asynStatus triggerProfile(asynUser *pasynUser); + /* These are the methods that are new to this class */ asynStatus readBinaryIO(); @@ -68,12 +70,12 @@ public: asynStatus writeReadController(const char *output, char *response, size_t maxResponseLen, size_t *responseLen, double timeout); protected: - int ACRJerk_; + int ACRJerk_; /**< Jerk time parameter index */ #define FIRST_ACR_PARAM ACRJerk_ - int ACRReadBinaryIO_; - int ACRBinaryIn_; - int ACRBinaryOut_; - int ACRBinaryOutRBV_; + int ACRReadBinaryIO_; /**< Read binary I/O parameter index */ + int ACRBinaryIn_; /**< Binary input parameter index */ + int ACRBinaryOut_; /**< Binary output parameter index */ + int ACRBinaryOutRBV_; /**< Binary output readback parameter index */ #define LAST_ACR_PARAM ACRBinaryOutRBV_ #define NUM_ACR_PARAMS (&LAST_ACR_PARAM - &FIRST_ACR_PARAM + 1)