Files
sinqMotor/src/sinqController.h
2024-12-04 13:38:13 +01:00

155 lines
6.2 KiB
C++

/*
This class extends asynMotorController by some features used in SINQ.
Stefan Mathis, November 2024
*/
#ifndef __sinqController
#define __sinqController
#include "asynMotorController.h"
#define motorMessageIsFromDriverString "MOTOR_MESSAGE_DRIVER"
#define motorMessageTextString "MOTOR_MESSAGE_TEXT"
class epicsShareClass sinqController : public asynMotorController {
public:
/**
* @brief Construct a new sinqController object
*
* @param portName Controller can be found by findAsynPortDriver
* with this name
* @param ipPortConfigName IP adress and port configuration of the
* controller unit, used to connect via pasynOctetSyncIO->connect
* @param numAxes Pointers to the axes are stored in the array
pAxes_ which has the length specified here. When getting an axis, the
`getAxis` function indexes into this array. A length of 8 would therefore
mean that the axis slots 0 to 7 are available. However, in order to keep the
axis enumeration in sync with the electronics counting logic, we start
counting the axes with 1 and end at 8. Therefore, an offset of 1 is added
when forwarding this number to asynMotorController.
* @param movingPollPeriod Time between polls when moving (in seconds)
* @param idlePollPeriod Time between polls when not moving (in
seconds)
* @param extraParams Number of extra parameter library entries
* created in a concrete driver implementation
*/
sinqController(const char *portName, const char *SINQPortName, int numAxes,
double movingPollPeriod, double idlePollPeriod,
int numExtraParams);
/**
* @brief Destroy the sinqController object
*
* In general, there is no real memory cleanup strategy in asynMotor,
* because objects are expected to be alive for the entire lifetime of the
* IOC. We just clean up the allocated axes array here.
*/
virtual ~sinqController(void);
/**
* @brief Overloaded function of asynMotorController
*
* The function is overloaded to allow enabling / disabling the motor.
*
* @param pasynUser Specify the axis via the asynUser
* @param value New value
* @return asynStatus
*/
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
/**
* @brief Overloaded function of asynMotorController
*
* The function is overloaded to get readback values for the enabling /
* disabling status.
*
* @param pasynUser Specify the axis via the asynUser
* @param value Read-out value
* @return asynStatus
*/
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
/**
* @brief Error handling in case accessing the parameter library failed.
*
* If accessing the parameter library failed (return status !=
asynSuccess), calling this function writes a standardized message to both
the IOC shell and the motor message text PV. It then returns the input
status.
*
* @param status Status of the failed parameter library access
* @param parameter Name of the parameter, used to create the
error messages.
* @param functionName Name of the caller function. It is recommended
to use a macro, e.g. __func__ or __PRETTY_FUNCTION__.
* @param lineNumber Source code line where this function is
called. It is recommended to use a macro, e.g. __LINE__.
* @return asynStatus Returns input status.
*/
asynStatus paramLibAccessFailed(asynStatus status, const char *parameter,
const char *functionName, int lineNumber);
/**
* @brief Error handling in case parsing a command response failed.
*
* This function writes a standardized message to both the IOC shell and
the motor message text PV in case parsing a response (e.g. via sscanf)
failed. It always returns asynError. This is convenience feature so the
function call can be used as a return value in an error handling branch.
*
* @param command Command which led to the unparseable message
* @param response Response which wasn't parseable
* @param axisNo_ Axis where the problem occurred
* @param functionName Name of the caller function. It is recommended
to use a macro, e.g. __func__ or __PRETTY_FUNCTION__.
* @param lineNumber Source code line where this function is
called. It is recommended to use a macro, e.g. __LINE__.
* @return asynStatus Returns asynError.
*/
asynStatus errMsgCouldNotParseResponse(const char *command,
const char *response, int axisNo,
const char *functionName,
int lineNumber);
/**
* @brief Convert an asynStatus into a descriptive string.
*
* @param status Status which should be converted to a string.
* @return const char*
*/
const char *stringifyAsynStatus(asynStatus status);
friend class sinqAxis;
protected:
asynUser *lowLevelPortUser_;
#define FIRST_SINQMOTOR_PARAM motorMessageText_
int motorMessageText_;
int motorTargetPosition_;
int motorEnable_;
int motorEnableRBV_;
int motorCanDisable_;
int motorEnableMovWatchdog_;
int motorCanSetSpeed_;
int motorLimitsOffset_;
/*
These parameters are here to write values from the hardware to the EPICS
motor record. Using motorHighLimit_ / motorLowLimit_ does not work:
https://epics.anl.gov/tech-talk/2023/msg00576.php. Therefore, some
additional records are introduced which read from these parameters and write
into the motor record.
*/
int motorVeloFromDriver_;
int motorVbasFromDriver_;
int motorVmaxFromDriver_;
int motorAcclFromDriver_;
int motorHighLimitFromDriver_;
int motorLowLimitFromDriver_;
#define LAST_SINQMOTOR_PARAM motorLowLimitFromDriver_
};
#define NUM_SINQMOTOR_DRIVER_PARAMS \
(&LAST_SINQMOTOR_PARAM - &FIRST_SINQMOTOR_PARAM + 1)
#endif