Added new feature msgPrintControl from sinqMotor 0.8.0. Correspondingly,
the minimum version requirement for sinqMotor has been bumped to 0.8.0.
This commit is contained in:
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ REQUIRED+=sinqMotor
|
||||
motorBase_VERSION=7.2.2
|
||||
|
||||
# Specify the version of sinqMotor we want to build against
|
||||
sinqMotor_VERSION=mathis_s
|
||||
sinqMotor_VERSION=0.8.0
|
||||
|
||||
# These headers allow to depend on this library for derived drivers.
|
||||
HEADERS += src/turboPmacAxis.h
|
||||
|
@ -35,7 +35,8 @@ static void epicsInithookFunction(initHookState iState) {
|
||||
}
|
||||
}
|
||||
|
||||
turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo)
|
||||
turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
||||
bool initialize)
|
||||
: sinqAxis(pC, axisNo), pC_(pC) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
@ -63,13 +64,17 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Register the hook function during construction of the first axis object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
if (initialize) {
|
||||
// Register the hook function during construction of the first axis
|
||||
// object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
|
||||
// Collect all axes into this list which will be used in the hook function
|
||||
axes.push_back(this);
|
||||
// Collect all axes into this list which will be used in the hook
|
||||
// function
|
||||
axes.push_back(this);
|
||||
}
|
||||
|
||||
// Initialize all member variables
|
||||
waitForHandshake_ = false;
|
||||
@ -360,39 +365,43 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Intepret the status
|
||||
// Create the unique callsite identifier manually so it can be used later in
|
||||
// the shouldBePrinted calls.
|
||||
msgPrintControlKey keyStatus = msgPrintControlKey(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
bool resetCountStatus = true;
|
||||
|
||||
// Interpret the status
|
||||
switch (axStatus) {
|
||||
case -6:
|
||||
// Axis is stopping
|
||||
*moving = true;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is stopping\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case -5:
|
||||
// Axis is deactivated
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"deactivated\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Deactivated");
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
break;
|
||||
case -4:
|
||||
// Emergency stop
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||
"activated\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||
"activated.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetCountStatus = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Emergency stop");
|
||||
if (pl_status != asynSuccess) {
|
||||
@ -403,13 +412,9 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
break;
|
||||
case -3:
|
||||
// Disabled
|
||||
*moving = false;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis %d is disabled\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_);
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Disabled");
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||
@ -419,43 +424,24 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
break;
|
||||
case 0:
|
||||
// Idle
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is idle\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 1:
|
||||
// Move order acknowledged
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove order "
|
||||
"acknowledged\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 2:
|
||||
// Move order confirmed possible
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove order is "
|
||||
"possible\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 3:
|
||||
// Axis in Air Cushion Output status
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis in Air "
|
||||
"Cushion Output status\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 4:
|
||||
// Axis in Air Cushion Input status
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis in Air "
|
||||
"Cushion Input status\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 5:
|
||||
*moving = true;
|
||||
@ -469,12 +455,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
default:
|
||||
*moving = false;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nReached unreachable "
|
||||
"state P%2.2d00 = %d\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
axStatus);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nReached "
|
||||
"unreachable state P%2.2d00 = %d.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, axStatus, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetCountStatus = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Unknown state P%2.2d00 = %d has been reached. Please call "
|
||||
"the support.",
|
||||
@ -487,6 +478,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
}
|
||||
|
||||
if (resetCountStatus) {
|
||||
pC_->msgPrintControl_.resetCount(keyStatus);
|
||||
}
|
||||
|
||||
if (*moving) {
|
||||
// If the axis is moving, evaluate the movement direction
|
||||
if ((currentPosition - previousPosition) > 0) {
|
||||
@ -496,19 +491,30 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
// Create the unique callsite identifier manually so it can be used later in
|
||||
// the shouldBePrinted calls.
|
||||
msgPrintControlKey keyError = msgPrintControlKey(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
bool resetError = true;
|
||||
|
||||
switch (error) {
|
||||
case 0:
|
||||
// No error
|
||||
// No error -> Reset the message repetition watchdog
|
||||
pC_->msgPrintControl_.shouldBePrinted(keyError, false,
|
||||
pC_->pasynUserSelf);
|
||||
break;
|
||||
case 1:
|
||||
// EPICS should already prevent this issue in the first place,
|
||||
// since it contains the user limits
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTarget position would "
|
||||
"exceed user limits.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTarget "
|
||||
"position would exceed user limits.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_,
|
||||
"Target position would exceed software "
|
||||
@ -523,11 +529,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
case 5:
|
||||
// Command not possible
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"still moving, but received another move command. EPICS "
|
||||
"should prevent this, check if *moving is set correctly.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"still moving, but received another move command. EPICS "
|
||||
"should prevent this, check if *moving is set correctly.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_,
|
||||
"Axis received move command while it is "
|
||||
@ -541,12 +553,15 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
poll_status = asynError;
|
||||
break;
|
||||
case 8:
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAir cushion feedback "
|
||||
"stopped during movement (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAir cushion "
|
||||
"feedback stopped during movement (P%2.2d01 = %d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Air cushion feedback stopped during movement (P%2.2d01 = "
|
||||
@ -561,11 +576,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
|
||||
"feedback before movement start (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
|
||||
"feedback before movement start (P%2.2d01 = %d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"No air cushion feedback before movement start (P%2.2d01 = "
|
||||
@ -585,10 +605,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
error case can only happen if either the axis has an incremental encoder
|
||||
which is not properly homed or if a bug occured.
|
||||
*/
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
||||
"controller limits.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
||||
"controller limits.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Software limits or end switch hit (P%2.2d01 = %d). Try "
|
||||
@ -608,10 +635,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
case 11:
|
||||
// Following error
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||
"following error exceeded.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||
"following error exceeded.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"Maximum allowed following error exceeded (P%2.2d01 = %d). "
|
||||
@ -629,6 +663,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nSecurity "
|
||||
"input is triggered (P%2.2d01 = %d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"Security input is triggered (P%2.2d01 = %d). Check the SPS "
|
||||
"for errors (if available). Otherwise please call "
|
||||
@ -646,11 +690,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
case 13:
|
||||
// Driver hardware error triggered
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDriver hardware error "
|
||||
"triggered.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDriver "
|
||||
"hardware error triggered.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"Driver hardware error (P%2.2d01 = 13). "
|
||||
"Please call the support.",
|
||||
@ -667,12 +717,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
case 14:
|
||||
// EPICS should already prevent this issue in the first place,
|
||||
// since it contains the user limits
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove command exceeds "
|
||||
"hardware limits (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove "
|
||||
"command exceeds hardware limits (P%2.2d01 = %d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Move command exceeds hardware limits (P%2.2d01 = %d). Please "
|
||||
@ -688,11 +742,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
poll_status = asynError;
|
||||
break;
|
||||
default:
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
||||
"P%2.2d01 = %d.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
||||
"P%2.2d01 = %d.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Unknown error P%2.2d01 = %d. Please call the support.",
|
||||
@ -708,6 +768,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (resetError) {
|
||||
pC_->msgPrintControl_.resetCount(keyError);
|
||||
}
|
||||
|
||||
// Update the parameter library
|
||||
if (error != 0) {
|
||||
pl_status = setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
|
@ -15,7 +15,8 @@ class turboPmacAxis : public sinqAxis {
|
||||
* @param pController Pointer to the associated controller
|
||||
* @param axisNo Index of the axis
|
||||
*/
|
||||
turboPmacAxis(turboPmacController *pController, int axisNo);
|
||||
turboPmacAxis(turboPmacController *pController, int axisNo,
|
||||
bool initialize = true);
|
||||
|
||||
/**
|
||||
* @brief Destroy the turboPmacAxis
|
||||
|
@ -133,39 +133,18 @@ Access one of the axes of the controller via the axis adress stored in asynUser.
|
||||
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||
error is emitted.
|
||||
*/
|
||||
turboPmacAxis *turboPmacController::getAxis(asynUser *pasynUser) {
|
||||
turboPmacAxis *turboPmacController::getTurboPmacAxis(asynUser *pasynUser) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(pasynUser);
|
||||
return turboPmacController::castToAxis(asynAxis);
|
||||
return dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
/*
|
||||
Access one of the axes of the controller via the axis index.
|
||||
If the axis does not exist or is not a Axis, the function must return Null
|
||||
*/
|
||||
turboPmacAxis *turboPmacController::getAxis(int axisNo) {
|
||||
turboPmacAxis *turboPmacController::getTurboPmacAxis(int axisNo) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(axisNo);
|
||||
return turboPmacController::castToAxis(asynAxis);
|
||||
}
|
||||
|
||||
turboPmacAxis *turboPmacController::castToAxis(asynMotorAxis *asynAxis) {
|
||||
|
||||
// =========================================================================
|
||||
|
||||
// If the axis slot of the pAxes_ array is empty, a nullptr must be returned
|
||||
if (asynAxis == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Here, an error is emitted since asyn_axis is not a nullptr but also not
|
||||
// an instance of Axis
|
||||
turboPmacAxis *axis = dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
if (axis == nullptr) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
||||
"an instance of turboPmacAxis",
|
||||
portName, axis->axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
return axis;
|
||||
return dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
@ -204,7 +183,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
|
||||
// =========================================================================
|
||||
|
||||
turboPmacAxis *axis = getAxis(axisNo);
|
||||
turboPmacAxis *axis = getTurboPmacAxis(axisNo);
|
||||
if (axis == nullptr) {
|
||||
// We already did the error logging directly in getAxis
|
||||
return asynError;
|
||||
@ -261,10 +240,6 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
// +1 for the carriage return.
|
||||
const size_t fullComandLength = offset + commandLength + 1;
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nSending command %s",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, fullCommand);
|
||||
|
||||
/*
|
||||
We use separated write and read commands here, not the combined writeRead
|
||||
method, because the latter is actually a flushWriteRead (see
|
||||
@ -282,12 +257,19 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
status = pasynOctetSyncIO->write(lowLevelPortUser_, fullCommand,
|
||||
fullComandLength, comTimeout_, &nbytesOut);
|
||||
|
||||
msgPrintControlKey writeKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (status == asynTimeout) {
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"writing to the MCU\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (msgPrintControl_.shouldBePrinted(writeKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"writing to the MCU.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||
sizeof(drvMessageText));
|
||||
@ -309,23 +291,35 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
}
|
||||
} else if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"writing to the controller\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
if (msgPrintControl_.shouldBePrinted(writeKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"writing to the controller.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status), msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(writeKey);
|
||||
}
|
||||
|
||||
// Read the response from the MCU buffer
|
||||
status = pasynOctetSyncIO->read(lowLevelPortUser_, response, MAXBUF_,
|
||||
comTimeout_, &nbytesIn, &eomReason);
|
||||
|
||||
msgPrintControlKey readKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (status == asynTimeout) {
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"reading from the MCU\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (msgPrintControl_.shouldBePrinted(readKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"reading from the MCU.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
// Add this event to the back of the timeout event counter
|
||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||
@ -348,11 +342,16 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
}
|
||||
} else if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"reading from the controller\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
if (msgPrintControl_.shouldBePrinted(readKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"reading from the controller.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status), msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(readKey);
|
||||
}
|
||||
|
||||
if (timeoutStatus == asynError) {
|
||||
@ -360,6 +359,8 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
|
||||
// The message should only ever terminate due to reason 2
|
||||
msgPrintControlKey terminateKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (eomReason != 2) {
|
||||
status = asynError;
|
||||
|
||||
@ -367,10 +368,16 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
"Terminated message due to reason %d (should be 2).",
|
||||
eomReason);
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||
"terminated due to reason %i\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, eomReason);
|
||||
if (msgPrintControl_.shouldBePrinted(terminateKey, true,
|
||||
pasynUserSelf)) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||
"terminated due to reason %i.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
eomReason, msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(terminateKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -382,20 +389,30 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
numReceivedResponses++;
|
||||
}
|
||||
}
|
||||
msgPrintControlKey numResponsesKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (numExpectedResponses != numReceivedResponses) {
|
||||
adjustResponseForPrint(modResponse, response, MAXBUF_);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
||||
"response '%s' (carriage returns are replaced with spaces) "
|
||||
"for command %s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
||||
command);
|
||||
|
||||
if (msgPrintControl_.shouldBePrinted(numResponsesKey, true,
|
||||
pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
||||
"response '%s' (carriage returns are replaced with spaces) "
|
||||
"for command %s.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
||||
command, msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
snprintf(drvMessageText, sizeof(drvMessageText),
|
||||
"Received unexpected response '%s' (carriage returns "
|
||||
"are replaced with spaces) for command %s. "
|
||||
"Please call the support",
|
||||
modResponse, command);
|
||||
status = asynError;
|
||||
} else {
|
||||
msgPrintControl_.resetCount(numResponsesKey);
|
||||
}
|
||||
|
||||
// Create custom error messages for different failure modes, if no error
|
||||
@ -425,23 +442,12 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
|
||||
// Log the overall status (communication successfull or not)
|
||||
if (status == asynSuccess) {
|
||||
|
||||
asynPrint(lowLevelPortUser_, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDevice "
|
||||
"response: %s (carriage returns are replaced with spaces)\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse);
|
||||
paramLibStatus = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
||||
} else {
|
||||
asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nCommunication "
|
||||
"failed for command %s (%s)\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, fullCommand,
|
||||
stringifyAsynStatus(status));
|
||||
|
||||
// Check if the axis already is in an error communication mode. If it is
|
||||
// not, upstream the error. This is done to avoid "flooding" the user
|
||||
// with different error messages if more than one error ocurred before
|
||||
// an error-free communication
|
||||
// Check if the axis already is in an error communication mode. If
|
||||
// it is not, upstream the error. This is done to avoid "flooding"
|
||||
// the user with different error messages if more than one error
|
||||
// ocurred before an error-free communication
|
||||
paramLibStatus =
|
||||
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
||||
if (paramLibStatus != asynSuccess) {
|
||||
@ -482,11 +488,7 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
|
||||
|
||||
// =====================================================================
|
||||
|
||||
turboPmacAxis *axis = getAxis(pasynUser);
|
||||
if (axis == nullptr) {
|
||||
// We already did the error logging directly in getAxis
|
||||
return asynError;
|
||||
}
|
||||
turboPmacAxis *axis = getTurboPmacAxis(pasynUser);
|
||||
|
||||
// Handle custom PVs
|
||||
if (function == rereadEncoderPosition_) {
|
||||
@ -538,8 +540,8 @@ asynStatus turboPmacCreateController(const char *portName,
|
||||
https://github.com/epics-modules/motor/blob/master/motorApp/MotorSrc/asynMotorController.cpp
|
||||
https://github.com/epics-modules/asyn/blob/master/asyn/asynPortDriver/asynPortDriver.cpp
|
||||
|
||||
The created object is registered in EPICS in its constructor and can safely
|
||||
be "leaked" here.
|
||||
The created object is registered in EPICS in its constructor and can
|
||||
safely be "leaked" here.
|
||||
*/
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
@ -578,8 +580,8 @@ static void configTurboPmacCreateControllerCallFunc(const iocshArgBuf *args) {
|
||||
args[3].dval, args[4].dval, args[5].dval);
|
||||
}
|
||||
|
||||
// This function is made known to EPICS in turboPmac.dbd and is called by EPICS
|
||||
// in order to register both functions in the IOC shell
|
||||
// This function is made known to EPICS in turboPmac.dbd and is called by
|
||||
// EPICS in order to register both functions in the IOC shell
|
||||
static void turboPmacControllerRegister(void) {
|
||||
iocshRegister(&configTurboPmacCreateController,
|
||||
configTurboPmacCreateControllerCallFunc);
|
||||
|
@ -40,7 +40,7 @@ class turboPmacController : public sinqController {
|
||||
* @return turboPmacAxis* If no axis could be found, this is a
|
||||
* nullptr
|
||||
*/
|
||||
turboPmacAxis *getAxis(asynUser *pasynUser);
|
||||
turboPmacAxis *getTurboPmacAxis(asynUser *pasynUser);
|
||||
|
||||
/**
|
||||
* @brief Get the axis object
|
||||
@ -49,18 +49,18 @@ class turboPmacController : public sinqController {
|
||||
* @return turboPmacAxis* If no axis could be found, this is a
|
||||
* nullptr
|
||||
*/
|
||||
turboPmacAxis *getAxis(int axisNo);
|
||||
turboPmacAxis *getTurboPmacAxis(int axisNo);
|
||||
|
||||
/**
|
||||
* @brief Overloaded function of sinqController
|
||||
*
|
||||
* The function is overloaded in order to read motorCanDisable_
|
||||
* The function is overloaded in order to read motorCanDisable_.
|
||||
*
|
||||
* @param pasynUser
|
||||
* @param value
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||
|
||||
/**
|
||||
* @brief Overloaded function of sinqController
|
||||
@ -71,7 +71,7 @@ class turboPmacController : public sinqController {
|
||||
* @param value New value
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
|
||||
protected:
|
||||
asynUser *lowLevelPortUser_;
|
||||
@ -95,15 +95,6 @@ class turboPmacController : public sinqController {
|
||||
asynStatus writeRead(int axisNo, const char *command, char *response,
|
||||
int numExpectedResponses);
|
||||
|
||||
/**
|
||||
* @brief Save cast of the given asynAxis pointer to a turboPmacAxis
|
||||
* pointer. If the cast fails, this function returns a nullptr.
|
||||
*
|
||||
* @param asynAxis
|
||||
* @return turboPmacAxis*
|
||||
*/
|
||||
turboPmacAxis *castToAxis(asynMotorAxis *asynAxis);
|
||||
|
||||
/**
|
||||
* @brief Specialized version of sinqController::errMsgCouldNotParseResponse
|
||||
* for turboPmac
|
||||
|
Reference in New Issue
Block a user