Compare commits
18 Commits
c2eca33ce8
...
55a9fe6f3e
Author | SHA1 | Date | |
---|---|---|---|
55a9fe6f3e | |||
e618b39687 | |||
41dfd1de5a | |||
07cab3ac2a | |||
e194736206 | |||
30af284f5d | |||
6069aa9194 | |||
c475beee66 | |||
b1fe452ed6 | |||
d395c7bbb7 | |||
a6f2890c76 | |||
fef61bc804 | |||
3d984f26bc | |||
2f8ae23d57 | |||
603b3e77af | |||
31ff26cb78 | |||
43df40aaea | |||
bdefc6090d |
184
src/sinqAxis.cpp
184
src/sinqAxis.cpp
@ -10,6 +10,8 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define getControllerMethod pController
|
||||||
|
|
||||||
struct sinqAxisImpl {
|
struct sinqAxisImpl {
|
||||||
// Internal variables used in the movement timeout watchdog
|
// Internal variables used in the movement timeout watchdog
|
||||||
time_t expectedArrivalTime;
|
time_t expectedArrivalTime;
|
||||||
@ -28,178 +30,6 @@ struct sinqAxisImpl {
|
|||||||
epicsTimeStamp lastPollTime;
|
epicsTimeStamp lastPollTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generic fallback - if the compiler tries to compile this function, it fails.
|
|
||||||
template <typename T>
|
|
||||||
asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), T writeValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
static_assert(
|
|
||||||
sizeof(T) == 0,
|
|
||||||
"no specialization of setAxisParam exists for the given type");
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus setAxisParam<int>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), int writeValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->setIntegerParam(indexValue, writeValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus setAxisParam<bool>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), bool writeValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
return setAxisParam(axis, indexName, func, static_cast<int>(writeValue),
|
|
||||||
callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus
|
|
||||||
setAxisParam<double>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), double writeValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->setDoubleParam(indexValue, writeValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus setAxisParam<char *>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), char *writeValue,
|
|
||||||
const char *callerFunctionName,
|
|
||||||
int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->setStringParam(indexValue, writeValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus setAxisParam<const char *>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(),
|
|
||||||
const char *writeValue,
|
|
||||||
const char *callerFunctionName,
|
|
||||||
int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->setStringParam(indexValue, writeValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic fallback - if the compiler tries to compile this function, it fails.
|
|
||||||
template <typename T>
|
|
||||||
asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), T *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
static_assert(
|
|
||||||
sizeof(T) == 0,
|
|
||||||
"no specialization of getAxisParam exists for the given type");
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus getAxisParam<int>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), int *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->pController()->getIntegerParam(
|
|
||||||
axis->axisNo(), indexValue, readValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus getAxisParam<bool>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), bool *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
return getAxisParam(axis, indexName, func, (int *)readValue,
|
|
||||||
callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus
|
|
||||||
getAxisParam<double>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), double *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->pController()->getDoubleParam(
|
|
||||||
axis->axisNo(), indexValue, readValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus getAxisParam<char>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), char *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
|
|
||||||
int maxChars = 200;
|
|
||||||
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
asynStatus status = axis->pController()->getStringParam(
|
|
||||||
axis->axisNo(), indexValue, maxChars, readValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N>
|
|
||||||
asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), char (&readValue)[N],
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
// Decay the array to char*
|
|
||||||
return getAxisParam<char>(axis, indexName, func,
|
|
||||||
static_cast<char *>(readValue),
|
|
||||||
callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
asynStatus
|
|
||||||
getAxisParam<std::string>(sinqAxis *axis, const char *indexName,
|
|
||||||
int (sinqController::*func)(), std::string *readValue,
|
|
||||||
const char *callerFunctionName, int lineNumber) {
|
|
||||||
int indexValue = (axis->pController()->*func)();
|
|
||||||
|
|
||||||
// Convert the pointer to a reference, since getStringParam expects the
|
|
||||||
// latter.
|
|
||||||
std::string &rReadValue = *readValue;
|
|
||||||
|
|
||||||
asynStatus status = axis->pController()->getStringParam(
|
|
||||||
axis->axisNo(), indexValue, rReadValue);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return axis->pController()->paramLibAccessFailed(
|
|
||||||
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
|
|
||||||
sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
|
sinqAxis::sinqAxis(class sinqController *pC, int axisNo)
|
||||||
: asynMotorAxis((asynMotorController *)pC, axisNo), pC_(pC) {
|
: asynMotorAxis((asynMotorController *)pC, axisNo), pC_(pC) {
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
@ -821,6 +651,16 @@ asynStatus sinqAxis::setScaleMovTimeout(time_t scaleMovTimeout) {
|
|||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sinqAxis::wasMoving() { return pSinqA_->wasMoving; }
|
||||||
|
|
||||||
|
void sinqAxis::setWasMoving(bool wasMoving) { pSinqA_->wasMoving = wasMoving; }
|
||||||
|
|
||||||
|
double sinqAxis::targetPosition() { return pSinqA_->targetPosition; }
|
||||||
|
|
||||||
|
void sinqAxis::setTargetPosition(double targetPosition) {
|
||||||
|
pSinqA_->targetPosition = targetPosition;
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// IOC shell functions
|
// IOC shell functions
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
328
src/sinqAxis.h
328
src/sinqAxis.h
@ -365,9 +365,52 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
asynStatus assertConnected();
|
asynStatus assertConnected();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return a pointer to the axis controller
|
* @brief Return a pointer to the axis controller.
|
||||||
|
*
|
||||||
|
* This function should be overriden in derived classes using the `override`
|
||||||
|
* keyword so the macros `getAxisParamChecked` and `setAxisParamChecked`
|
||||||
|
* work correctly:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* class mySpecialAxis : public sinqAxis {
|
||||||
|
public:
|
||||||
|
mySpecialController* getControllerMethod() override {
|
||||||
|
return mySpecialControllerPtr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
sinqController *pController() { return pC_; };
|
virtual sinqController *pController() { return pC_; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true, if the axis was moving in the last poll cycle, and
|
||||||
|
* false otherwise.
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool wasMoving();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Override the wasMoving flag (normally, it is automatically updated
|
||||||
|
* during each poll).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setWasMoving(bool wasMoving);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read out the last received target position in engineering units.
|
||||||
|
*
|
||||||
|
* @return double
|
||||||
|
*/
|
||||||
|
double targetPosition();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Override the targetPosition value (normally, it is automatically
|
||||||
|
* updated at every call of the move() method).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setTargetPosition(double targetPosition);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<sinqAxisImpl> pSinqA_;
|
std::unique_ptr<sinqAxisImpl> pSinqA_;
|
||||||
@ -377,6 +420,84 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Helper functions and definitions for the macro setAxisParamChecked
|
// Helper functions and definitions for the macro setAxisParamChecked
|
||||||
|
|
||||||
|
template <typename T> struct TypeTag {};
|
||||||
|
|
||||||
|
// Generic fallback - if the compiler tries to compile this function, it fails.
|
||||||
|
template <typename A, typename C, typename T>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), T writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<void>) {
|
||||||
|
static_assert(sizeof(T) == 0, "Unsupported type for setAxisParamImpl");
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), int writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<int>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status = axis->setIntegerParam(indexValue, writeValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), bool writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<bool>) {
|
||||||
|
return setAxisParamImpl(axis, controller, indexName, func,
|
||||||
|
static_cast<int>(writeValue), callerFunctionName,
|
||||||
|
lineNumber, TypeTag<int>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), double writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<double>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status = axis->setDoubleParam(indexValue, writeValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), char *writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<char *>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status = axis->setStringParam(indexValue, writeValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus setAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), const char *writeValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
TypeTag<const char *>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status = axis->setStringParam(indexValue, writeValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper function to set an integer / double / string parameter for an
|
* @brief Helper function to set an integer / double / string parameter for an
|
||||||
* axis in the paramLib
|
* axis in the paramLib
|
||||||
@ -384,8 +505,11 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
* This function should not be used directly, but rather through its macro
|
* This function should not be used directly, but rather through its macro
|
||||||
* variant `setAxisParamChecked`.
|
* variant `setAxisParamChecked`.
|
||||||
*
|
*
|
||||||
|
* @tparam A
|
||||||
|
* @tparam C
|
||||||
* @tparam T
|
* @tparam T
|
||||||
* @param axis
|
* @param axis
|
||||||
|
* @param controller
|
||||||
* @param indexName
|
* @param indexName
|
||||||
* @param func
|
* @param func
|
||||||
* @param writeValue
|
* @param writeValue
|
||||||
@ -393,10 +517,13 @@ class epicsShareClass sinqAxis : public asynMotorAxis {
|
|||||||
* @param lineNumber
|
* @param lineNumber
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename A, typename C, typename T>
|
||||||
asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
asynStatus setAxisParam(A *axis, C *controller, const char *indexName,
|
||||||
int (sinqController::*func)(), T writeValue,
|
int (C::*func)(), T writeValue,
|
||||||
const char *callerFunctionName, int lineNumber);
|
const char *callerFunctionName, int lineNumber) {
|
||||||
|
return setAxisParamImpl(axis, controller, indexName, func, writeValue,
|
||||||
|
callerFunctionName, lineNumber, TypeTag<T>{});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Macro to set an paramLib parameter and error checking the return value
|
* @brief Macro to set an paramLib parameter and error checking the return value
|
||||||
@ -412,10 +539,10 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* expands into the following code:
|
* expands into the following code:
|
||||||
* ```
|
* ```
|
||||||
* {
|
* {
|
||||||
* int indexValue = axis->pController()->motorStatusProblem_();
|
* int indexValue = controller->motorStatusProblem_();
|
||||||
* asynStatus status = axis->setIntegerParam(indexValue, writeValue);
|
* asynStatus status = axis->setIntegerParam(indexValue, writeValue);
|
||||||
* if (status != asynSuccess) {
|
* if (status != asynSuccess) {
|
||||||
* return axis->pController()->paramLibAccessFailed(
|
* return controller->paramLibAccessFailed(
|
||||||
* status, "motorStatusProblem_", axis->axisNo(), __PRETTY_FUNCTION__,
|
* status, "motorStatusProblem_", axis->axisNo(), __PRETTY_FUNCTION__,
|
||||||
* __LINE__);
|
* __LINE__);
|
||||||
* }
|
* }
|
||||||
@ -424,23 +551,116 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* ```
|
* ```
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
#define setAxisParamChecked(axis, indexGetterFunction, writeValue) \
|
#define setAxisParamChecked(axis, indexSetterFunction, writeValue) \
|
||||||
{ \
|
do { \
|
||||||
asynStatus setStatus = setAxisParam( \
|
auto *ctrlPtr = (axis)->pController(); \
|
||||||
axis, #indexGetterFunction, \
|
using ControllerType = \
|
||||||
&std::remove_pointer< \
|
typename std::remove_pointer<decltype(ctrlPtr)>::type; \
|
||||||
decltype(axis->pController())>::type::indexGetterFunction, \
|
asynStatus setStatus = \
|
||||||
writeValue, __PRETTY_FUNCTION__, __LINE__); \
|
setAxisParam(axis, ctrlPtr, #indexSetterFunction, \
|
||||||
if (setStatus != asynSuccess) { \
|
static_cast<int (ControllerType::*)()>( \
|
||||||
|
&ControllerType::indexSetterFunction), \
|
||||||
|
writeValue, __PRETTY_FUNCTION__, __LINE__); \
|
||||||
|
if (setStatus != asynSuccess) \
|
||||||
return setStatus; \
|
return setStatus; \
|
||||||
} \
|
} while (0)
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Helper functions and definitions for the macro getAxisParamChecked
|
// Helper functions and definitions for the macro getAxisParamChecked
|
||||||
|
|
||||||
|
// Generic fallback - if the compiler tries to compile this function, it fails.
|
||||||
|
template <typename A, typename C, typename T>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), T *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<void>) {
|
||||||
|
static_assert(
|
||||||
|
sizeof(T) == 0,
|
||||||
|
"no specialization of getAxisParam exists for the given type");
|
||||||
|
return asynError;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), int *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<int>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status =
|
||||||
|
controller->getIntegerParam(axis->axisNo(), indexValue, readValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), bool *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<bool>) {
|
||||||
|
int readValueInt = 0;
|
||||||
|
asynStatus status = getAxisParamImpl(axis, controller, indexName, func,
|
||||||
|
&readValueInt, callerFunctionName,
|
||||||
|
lineNumber, msgSize, TypeTag<int>{});
|
||||||
|
*readValue = readValueInt != 0;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), double *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<double>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status =
|
||||||
|
controller->getDoubleParam(axis->axisNo(), indexValue, readValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), char *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<char>) {
|
||||||
|
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
asynStatus status = controller->getStringParam(axis->axisNo(), indexValue,
|
||||||
|
msgSize, readValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename A, typename C>
|
||||||
|
asynStatus getAxisParamImpl(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), std::string *readValue,
|
||||||
|
const char *callerFunctionName, int lineNumber,
|
||||||
|
size_t msgSize, TypeTag<std::string>) {
|
||||||
|
int indexValue = (controller->*func)();
|
||||||
|
|
||||||
|
// Convert the pointer to a reference, since getStringParam expects the
|
||||||
|
// latter.
|
||||||
|
std::string &rReadValue = *readValue;
|
||||||
|
|
||||||
|
asynStatus status =
|
||||||
|
controller->getStringParam(axis->axisNo(), indexValue, rReadValue);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return controller->paramLibAccessFailed(
|
||||||
|
status, indexName, axis->axisNo(), callerFunctionName, lineNumber);
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper function to set an integer / double / string parameter for an
|
* @brief Helper function to get an integer / double / string parameter for an
|
||||||
* axis in the paramLib
|
* axis in the paramLib
|
||||||
*
|
*
|
||||||
* This function should not be used directly, but rather through its macro
|
* This function should not be used directly, but rather through its macro
|
||||||
@ -448,6 +668,7 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
*
|
*
|
||||||
* @tparam T
|
* @tparam T
|
||||||
* @param axis
|
* @param axis
|
||||||
|
* @param controller
|
||||||
* @param indexName
|
* @param indexName
|
||||||
* @param func
|
* @param func
|
||||||
* @param readValue
|
* @param readValue
|
||||||
@ -458,17 +679,48 @@ asynStatus setAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* to.
|
* to.
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename A, typename C, typename T>
|
||||||
asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
asynStatus getAxisParam(A *axis, C *controller, const char *indexName,
|
||||||
int (sinqController::*func)(), T *readValue,
|
int (C::*func)(), T *readValue,
|
||||||
const char *callerFunctionName, int lineNumber);
|
const char *callerFunctionName, int lineNumber) {
|
||||||
|
return getAxisParamImpl(axis, controller, indexName, func, readValue,
|
||||||
|
callerFunctionName, lineNumber,
|
||||||
|
controller->msgSize(), TypeTag<T>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper function to get a string parameter for an
|
||||||
|
* axis in the paramLib into a char array
|
||||||
|
*
|
||||||
|
* This function should not be used directly, but rather through its macro
|
||||||
|
* variant `getAxisParamChecked`. It is a specialized variant of the general
|
||||||
|
* getAxisParam defined above for char arrays.
|
||||||
|
*
|
||||||
|
* @tparam A
|
||||||
|
* @tparam C
|
||||||
|
* @tparam N
|
||||||
|
* @param axis
|
||||||
|
* @param controller
|
||||||
|
* @param indexName
|
||||||
|
* @param func
|
||||||
|
* @param callerFunctionName
|
||||||
|
* @param lineNumber
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
template <typename A, typename C, size_t N>
|
||||||
|
asynStatus getAxisParam(A *axis, C *controller, const char *indexName,
|
||||||
|
int (C::*func)(), char (*readValue)[N],
|
||||||
|
const char *callerFunctionName, int lineNumber) {
|
||||||
|
return getAxisParamImpl(axis, controller, indexName, func, *readValue,
|
||||||
|
callerFunctionName, lineNumber, N, TypeTag<char>{});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Macro to get an paramLib parameter and error checking the return value
|
* @brief Macro to get an paramLib parameter and error checking the return value
|
||||||
*
|
*
|
||||||
* This macro is a wrapper around `getIntegerParam` / `getDoubleParam` /
|
* This macro is a wrapper around `getIntegerParam` / `getDoubleParam` /
|
||||||
* `getStringParam` which checks if the operation was successfull. If it wasn't,
|
* `getStringParam` which checks if the operation was successfull. If it wasn't,
|
||||||
* it returns by calling the paramLibAccessFailed function.
|
* it returns by calling the paramLibAccessFailed function. In order
|
||||||
*
|
*
|
||||||
* For example, the following input:
|
* For example, the following input:
|
||||||
* ```
|
* ```
|
||||||
@ -477,10 +729,10 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* expands into the following code:
|
* expands into the following code:
|
||||||
* ```
|
* ```
|
||||||
* {
|
* {
|
||||||
* int indexValue = axis->pController()->motorStatusProblem_();
|
* int indexValue = controller->motorStatusProblem_();
|
||||||
* asynStatus status = axis->pController()->getIntegerParam(axis->axisNo(),
|
* asynStatus status = controller->getIntegerParam(axis->axisNo(),
|
||||||
* indexValue, readValue); if (status != asynSuccess) { return
|
* indexValue, readValue); if (status != asynSuccess) { return
|
||||||
* axis->pController()->paramLibAccessFailed( status, "motorStatusProblem_",
|
* controller->paramLibAccessFailed( status, "motorStatusProblem_",
|
||||||
* axis->axisNo(), __PRETTY_FUNCTION__,
|
* axis->axisNo(), __PRETTY_FUNCTION__,
|
||||||
* __LINE__);
|
* __LINE__);
|
||||||
* }
|
* }
|
||||||
@ -490,15 +742,17 @@ asynStatus getAxisParam(sinqAxis *axis, const char *indexName,
|
|||||||
* =============================================================================
|
* =============================================================================
|
||||||
*/
|
*/
|
||||||
#define getAxisParamChecked(axis, indexGetterFunction, readValue) \
|
#define getAxisParamChecked(axis, indexGetterFunction, readValue) \
|
||||||
{ \
|
do { \
|
||||||
asynStatus getStatus = getAxisParam( \
|
auto *ctrlPtr = (axis)->pController(); \
|
||||||
axis, #indexGetterFunction, \
|
using ControllerType = \
|
||||||
&std::remove_pointer< \
|
typename std::remove_pointer<decltype(ctrlPtr)>::type; \
|
||||||
decltype(axis->pController())>::type::indexGetterFunction, \
|
asynStatus getStatus = \
|
||||||
readValue, __PRETTY_FUNCTION__, __LINE__); \
|
getAxisParam(axis, ctrlPtr, #indexGetterFunction, \
|
||||||
if (getStatus != asynSuccess) { \
|
static_cast<int (ControllerType::*)()>( \
|
||||||
|
&ControllerType::indexGetterFunction), \
|
||||||
|
readValue, __PRETTY_FUNCTION__, __LINE__); \
|
||||||
|
if (getStatus != asynSuccess) \
|
||||||
return getStatus; \
|
return getStatus; \
|
||||||
} \
|
} while (0)
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -380,9 +380,17 @@ class epicsShareClass sinqController : public asynMotorController {
|
|||||||
*/
|
*/
|
||||||
int outstandingForcedFastPolls();
|
int outstandingForcedFastPolls();
|
||||||
|
|
||||||
// Maximum error message buffer size. This is an empirical value which must
|
/**
|
||||||
// be large enough to avoid overflows for all commands to the device /
|
* @brief Return the maximum error message buffer size
|
||||||
// responses from it.
|
*
|
||||||
|
* This is an empirical value which must be large enough to avoid overflows
|
||||||
|
* for all commands to the device / responses from it.
|
||||||
|
*
|
||||||
|
* @return uint32_t
|
||||||
|
*/
|
||||||
|
uint32_t msgSize() { return MAXBUF_; }
|
||||||
|
|
||||||
|
// Maximum message size
|
||||||
static const uint32_t MAXBUF_ = 200;
|
static const uint32_t MAXBUF_ = 200;
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
Reference in New Issue
Block a user