Compare commits
13 Commits
static-dep
...
1.0.1
Author | SHA1 | Date | |
---|---|---|---|
847f40970f | |||
deb6e6996e | |||
d1d694ad6b | |||
e0a74c5598 | |||
c334ed9f04 | |||
4b0031c3af | |||
61335970ce | |||
081a21073b | |||
f2e8eb2762 | |||
e93f11e779 | |||
989410474e | |||
8d8561d833 | |||
a56a8cf646 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "sinqMotor"]
|
||||||
|
path = sinqMotor
|
||||||
|
url = https://gitea.psi.ch/lin-epics-modules/sinqMotor
|
16
Makefile
16
Makefile
@ -6,24 +6,26 @@ BUILDCLASSES=Linux
|
|||||||
EPICS_VERSIONS=7.0.7
|
EPICS_VERSIONS=7.0.7
|
||||||
ARCH_FILTER=RHEL%
|
ARCH_FILTER=RHEL%
|
||||||
|
|
||||||
# Additional module dependencies
|
|
||||||
REQUIRED+=sinqMotor
|
|
||||||
|
|
||||||
# Specify the version of asynMotor we want to build against
|
# Specify the version of asynMotor we want to build against
|
||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of sinqMotor we want to build against
|
|
||||||
sinqMotor_VERSION=0.14.0
|
|
||||||
|
|
||||||
# These headers allow to depend on this library for derived drivers.
|
# These headers allow to depend on this library for derived drivers.
|
||||||
HEADERS += src/masterMacsAxis.h
|
HEADERS += src/masterMacsAxis.h
|
||||||
HEADERS += src/masterMacsController.h
|
HEADERS += src/masterMacsController.h
|
||||||
|
|
||||||
# Source files to build
|
# Source files to build
|
||||||
|
SOURCES += sinqMotor/src/msgPrintControl.cpp
|
||||||
|
SOURCES += sinqMotor/src/sinqAxis.cpp
|
||||||
|
SOURCES += sinqMotor/src/sinqController.cpp
|
||||||
SOURCES += src/masterMacsAxis.cpp
|
SOURCES += src/masterMacsAxis.cpp
|
||||||
SOURCES += src/masterMacsController.cpp
|
SOURCES += src/masterMacsController.cpp
|
||||||
|
|
||||||
|
# Store the record files
|
||||||
|
TEMPLATES += sinqMotor/db/asynRecord.db
|
||||||
|
TEMPLATES += sinqMotor/db/sinqMotor.db
|
||||||
|
|
||||||
# This file registers the motor-specific functions in the IOC shell.
|
# This file registers the motor-specific functions in the IOC shell.
|
||||||
|
DBDS += sinqMotor/src/sinqMotor.dbd
|
||||||
DBDS += src/masterMacs.dbd
|
DBDS += src/masterMacs.dbd
|
||||||
|
|
||||||
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Wpedantic -Wextra -Werror
|
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Wextra -Werror
|
||||||
|
1
sinqMotor
Submodule
1
sinqMotor
Submodule
Submodule sinqMotor added at c2eca33ce8
@ -11,6 +11,21 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct masterMacsAxisImpl {
|
||||||
|
/*
|
||||||
|
The axis status and axis error of MasterMACS are given as an integer from
|
||||||
|
the controller. The 16 individual bits contain the actual information.
|
||||||
|
*/
|
||||||
|
std::bitset<16> axisStatus;
|
||||||
|
std::bitset<16> axisError;
|
||||||
|
|
||||||
|
double lastSetSpeed;
|
||||||
|
bool waitForHandshake;
|
||||||
|
time_t timeAtHandshake;
|
||||||
|
bool needInit = true;
|
||||||
|
bool targetReachedUninitialized;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A special communication timeout is used in the following two cases:
|
A special communication timeout is used in the following two cases:
|
||||||
1) Enable command
|
1) Enable command
|
||||||
@ -104,17 +119,14 @@ masterMacsAxis::masterMacsAxis(masterMacsController *pC, int axisNo)
|
|||||||
// Collect all axes into this list which will be used in the hook function
|
// Collect all axes into this list which will be used in the hook function
|
||||||
axes.push_back(this);
|
axes.push_back(this);
|
||||||
|
|
||||||
// Initialize all member variables
|
pMasterMacsA_ = std::make_unique<masterMacsAxisImpl>((masterMacsAxisImpl){
|
||||||
axisStatus_ = std::bitset<16>(0);
|
.axisStatus = std::bitset<16>(0),
|
||||||
axisError_ = std::bitset<16>(0);
|
.axisError = std::bitset<16>(0),
|
||||||
|
.lastSetSpeed = 0.0,
|
||||||
// Initial value for the motor speed, is overwritten in atFirstPoll.
|
.waitForHandshake = false,
|
||||||
lastSetSpeed_ = 0.0;
|
.timeAtHandshake = 0,
|
||||||
|
.targetReachedUninitialized = true,
|
||||||
// Flag for handshake waiting
|
});
|
||||||
waitForHandshake_ = false;
|
|
||||||
timeAtHandshake_ = 0;
|
|
||||||
targetReachedUninitialized_ = true;
|
|
||||||
|
|
||||||
// masterMacs motors can always be disabled
|
// masterMacs motors can always be disabled
|
||||||
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
||||||
@ -138,6 +150,20 @@ masterMacsAxis::masterMacsAxis(masterMacsController *pC, int axisNo)
|
|||||||
pC_->portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
pC_->stringifyAsynStatus(status));
|
pC_->stringifyAsynStatus(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even though this happens already in sinqAxis, a default value for
|
||||||
|
// motorMessageText is set here again, because apparently the sinqAxis
|
||||||
|
// constructor is not run before the string is accessed?
|
||||||
|
status = setStringParam(pC_->motorMessageText(), "");
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
|
||||||
|
"(setting a parameter value failed "
|
||||||
|
"with %s)\n. Terminating IOC",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->stringifyAsynStatus(status));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
masterMacsAxis::~masterMacsAxis(void) {
|
masterMacsAxis::~masterMacsAxis(void) {
|
||||||
@ -239,7 +265,7 @@ asynStatus masterMacsAxis::init() {
|
|||||||
// Cache the motor speed. If this value differs from the one in the motor
|
// Cache the motor speed. If this value differs from the one in the motor
|
||||||
// record at the start of a movement, the motor record value is sent to
|
// record at the start of a movement, the motor record value is sent to
|
||||||
// MasterMACS.
|
// MasterMACS.
|
||||||
lastSetSpeed_ = motorVelocity;
|
pMasterMacsA_->lastSetSpeed = motorVelocity;
|
||||||
|
|
||||||
// Store the motor position in the parameter library
|
// Store the motor position in the parameter library
|
||||||
pl_status = setMotorPosition(motorPosition);
|
pl_status = setMotorPosition(motorPosition);
|
||||||
@ -275,6 +301,10 @@ asynStatus masterMacsAxis::init() {
|
|||||||
pC_->stringifyAsynStatus(pl_status));
|
pC_->stringifyAsynStatus(pl_status));
|
||||||
return pl_status;
|
return pl_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Axis is fully initialized
|
||||||
|
setNeedInit(false);
|
||||||
|
|
||||||
return pl_status;
|
return pl_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,13 +335,21 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
// Does the axis need to be intialized?
|
||||||
|
if (needInit()) {
|
||||||
|
rw_status = init();
|
||||||
|
if (rw_status != asynSuccess) {
|
||||||
|
return rw_status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Are we currently waiting for a handshake?
|
// Are we currently waiting for a handshake?
|
||||||
if (waitForHandshake_) {
|
if (pMasterMacsA_->waitForHandshake) {
|
||||||
|
|
||||||
// Check if the handshake takes too long and communicate an error in
|
// Check if the handshake takes too long and communicate an error in
|
||||||
// this case. A handshake should not take more than 5 seconds.
|
// this case. A handshake should not take more than 5 seconds.
|
||||||
time_t currentTime = time(NULL);
|
time_t currentTime = time(NULL);
|
||||||
bool timedOut = (currentTime > timeAtHandshake_ + 5);
|
bool timedOut = (currentTime > pMasterMacsA_->timeAtHandshake + 5);
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, timedOut,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, timedOut,
|
||||||
@ -321,7 +359,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
"handshake at %ld s and didn't get a positive reply yet "
|
"handshake at %ld s and didn't get a positive reply yet "
|
||||||
"(current time is %ld s).\n",
|
"(current time is %ld s).\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
timeAtHandshake_, currentTime);
|
pMasterMacsA_->timeAtHandshake, currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timedOut) {
|
if (timedOut) {
|
||||||
@ -349,8 +387,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
if (handshakePerformed == 1.0) {
|
if (handshakePerformed == 1.0) {
|
||||||
// Handshake has been performed successfully -> Continue with the
|
// Handshake has been performed successfully -> Continue with the
|
||||||
// poll
|
// poll
|
||||||
waitForHandshake_ = false;
|
pMasterMacsA_->waitForHandshake = false;
|
||||||
targetReachedUninitialized_ = false;
|
pMasterMacsA_->targetReachedUninitialized = false;
|
||||||
} else {
|
} else {
|
||||||
// Still waiting for the handshake - try again in the next busy
|
// Still waiting for the handshake - try again in the next busy
|
||||||
// poll. This is already part of the movement procedure.
|
// poll. This is already part of the movement procedure.
|
||||||
@ -395,7 +433,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetReachedUninitialized_) {
|
if (pMasterMacsA_->targetReachedUninitialized) {
|
||||||
*moving = false;
|
*moving = false;
|
||||||
} else {
|
} else {
|
||||||
if (targetReached() || !switchedOn()) {
|
if (targetReached() || !switchedOn()) {
|
||||||
@ -406,7 +444,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (targetReached()) {
|
if (targetReached()) {
|
||||||
targetReachedUninitialized_ = false;
|
pMasterMacsA_->targetReachedUninitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the current position
|
// Read the current position
|
||||||
@ -460,7 +498,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
// This buffer must be initialized to zero because we build the
|
// This buffer must be initialized to zero because we build the
|
||||||
// error message by appending strings.
|
// error message by appending strings.
|
||||||
char userMessage[pC_->MAXBUF_] = {0};
|
char errorMessage[pC_->MAXBUF_] = {0};
|
||||||
char shellMessage[pC_->MAXBUF_] = {0};
|
char shellMessage[pC_->MAXBUF_] = {0};
|
||||||
|
|
||||||
// Concatenate all other errors
|
// Concatenate all other errors
|
||||||
@ -468,7 +506,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Short circuit fault.");
|
"Short circuit fault.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Short circuit error. Please call the support.");
|
"Short circuit error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -477,7 +515,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
if (encoderError()) {
|
if (encoderError()) {
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Encoder error.");
|
"Encoder error.");
|
||||||
appendErrorMessage(userMessage, sizeof(userMessage),
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
"Encoder error. Please call the support.");
|
"Encoder error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -488,7 +526,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
shellMessage, sizeof(shellMessage),
|
shellMessage, sizeof(shellMessage),
|
||||||
"Maximum callowed following error exceeded.");
|
"Maximum callowed following error exceeded.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Maximum allowed following error exceeded.Check if "
|
"Maximum allowed following error exceeded.Check if "
|
||||||
"movement range is blocked. Otherwise please call the "
|
"movement range is blocked. Otherwise please call the "
|
||||||
"support.");
|
"support.");
|
||||||
@ -499,7 +537,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
if (feedbackError()) {
|
if (feedbackError()) {
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Feedback error.");
|
"Feedback error.");
|
||||||
appendErrorMessage(userMessage, sizeof(userMessage),
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
"Feedback error. Please call the support.");
|
"Feedback error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -535,7 +573,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
// Generic error message for user
|
// Generic error message for user
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Software limits or end switch hit. Try homing the motor, "
|
"Software limits or end switch hit. Try homing the motor, "
|
||||||
"moving in the opposite direction or check the SPS for "
|
"moving in the opposite direction or check the SPS for "
|
||||||
"errors (if available). Otherwise please call the "
|
"errors (if available). Otherwise please call the "
|
||||||
@ -548,7 +586,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Overcurrent error.");
|
"Overcurrent error.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Overcurrent error. Please call the support.");
|
"Overcurrent error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -558,7 +596,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Overtemperature error.");
|
"Overtemperature error.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Overtemperature error. Please call the support.");
|
"Overtemperature error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -568,7 +606,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Overvoltage error.");
|
"Overvoltage error.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Overvoltage error. Please call the support.");
|
"Overvoltage error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -578,7 +616,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"Undervoltage error.");
|
"Undervoltage error.");
|
||||||
appendErrorMessage(
|
appendErrorMessage(
|
||||||
userMessage, sizeof(userMessage),
|
errorMessage, sizeof(errorMessage),
|
||||||
"Undervoltage error. Please call the support.");
|
"Undervoltage error. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -587,7 +625,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
if (stoFault()) {
|
if (stoFault()) {
|
||||||
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
appendErrorMessage(shellMessage, sizeof(shellMessage),
|
||||||
"STO input is on disable state.");
|
"STO input is on disable state.");
|
||||||
appendErrorMessage(userMessage, sizeof(userMessage),
|
appendErrorMessage(errorMessage, sizeof(errorMessage),
|
||||||
"STO fault. Please call the support.");
|
"STO fault. Please call the support.");
|
||||||
|
|
||||||
poll_status = asynError;
|
poll_status = asynError;
|
||||||
@ -605,7 +643,7 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
pl_status = setStringParam(pC_->motorMessageText(), errorMessage);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
@ -805,9 +843,9 @@ asynStatus masterMacsAxis::doMove(double position, int relative,
|
|||||||
|
|
||||||
// Set the new motor speed, if the user is allowed to do so and if the
|
// Set the new motor speed, if the user is allowed to do so and if the
|
||||||
// motor speed changed since the last move command.
|
// motor speed changed since the last move command.
|
||||||
if (motorCanSetSpeed != 0 && lastSetSpeed_ != motorVelocity) {
|
if (motorCanSetSpeed != 0 && pMasterMacsA_->lastSetSpeed != motorVelocity) {
|
||||||
|
|
||||||
lastSetSpeed_ = motorVelocity;
|
pMasterMacsA_->lastSetSpeed = motorVelocity;
|
||||||
|
|
||||||
snprintf(value, sizeof(value), "%lf", motorVelocity);
|
snprintf(value, sizeof(value), "%lf", motorVelocity);
|
||||||
rw_status = pC_->write(axisNo_, 05, value);
|
rw_status = pC_->write(axisNo_, 05, value);
|
||||||
@ -843,7 +881,8 @@ asynStatus masterMacsAxis::doMove(double position, int relative,
|
|||||||
|
|
||||||
// If the motor has just been enabled, use Enable
|
// If the motor has just been enabled, use Enable
|
||||||
double timeout = pC_->comTimeout();
|
double timeout = pC_->comTimeout();
|
||||||
if (targetReachedUninitialized_ && timeout < PowerCycleTimeout) {
|
if (pMasterMacsA_->targetReachedUninitialized &&
|
||||||
|
timeout < PowerCycleTimeout) {
|
||||||
timeout = PowerCycleTimeout;
|
timeout = PowerCycleTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,8 +904,8 @@ asynStatus masterMacsAxis::doMove(double position, int relative,
|
|||||||
|
|
||||||
// In the next poll, we will check if the handshake has been performed in a
|
// In the next poll, we will check if the handshake has been performed in a
|
||||||
// reasonable time
|
// reasonable time
|
||||||
waitForHandshake_ = true;
|
pMasterMacsA_->waitForHandshake = true;
|
||||||
timeAtHandshake_ = time(NULL);
|
pMasterMacsA_->timeAtHandshake = time(NULL);
|
||||||
|
|
||||||
// Waiting for a handshake is already part of the movement procedure =>
|
// Waiting for a handshake is already part of the movement procedure =>
|
||||||
// Start the watchdog
|
// Start the watchdog
|
||||||
@ -897,6 +936,10 @@ asynStatus masterMacsAxis::stop(double acceleration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the driver to idle state and move out of the handshake wait loop,
|
||||||
|
// if we're currently inside it.
|
||||||
|
pMasterMacsA_->waitForHandshake = false;
|
||||||
|
|
||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,6 +962,10 @@ asynStatus masterMacsAxis::doReset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the driver to idle state and move out of the handshake wait loop,
|
||||||
|
// if we're currently inside it.
|
||||||
|
pMasterMacsA_->waitForHandshake = false;
|
||||||
|
|
||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,8 +1014,8 @@ asynStatus masterMacsAxis::doHome(double min_velocity, double max_velocity,
|
|||||||
|
|
||||||
// In the next poll, we will check if the handshake has been performed
|
// In the next poll, we will check if the handshake has been performed
|
||||||
// in a reasonable time
|
// in a reasonable time
|
||||||
waitForHandshake_ = true;
|
pMasterMacsA_->waitForHandshake = true;
|
||||||
timeAtHandshake_ = time(NULL);
|
pMasterMacsA_->timeAtHandshake = time(NULL);
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
} else {
|
} else {
|
||||||
return asynError;
|
return asynError;
|
||||||
@ -1035,8 +1082,6 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
bool moving = false;
|
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1044,8 +1089,15 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
0. In order to prevent the poll method in interpreting the motor state as
|
0. In order to prevent the poll method in interpreting the motor state as
|
||||||
"moving", this flag is used. It is reset in the handshake.
|
"moving", this flag is used. It is reset in the handshake.
|
||||||
*/
|
*/
|
||||||
targetReachedUninitialized_ = true;
|
pMasterMacsA_->targetReachedUninitialized = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Continue regardless of the status returned by the poll; we just want to
|
||||||
|
find out whether the motor is currently moving or not. If the poll
|
||||||
|
function fails before it can determine that, it is assumed that the motor
|
||||||
|
is not moving.
|
||||||
|
*/
|
||||||
|
bool moving = false;
|
||||||
doPoll(&moving);
|
doPoll(&moving);
|
||||||
|
|
||||||
// If the axis is currently moving, it cannot be disabled. Ignore the
|
// If the axis is currently moving, it cannot be disabled. Ignore the
|
||||||
@ -1088,22 +1140,13 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
"Controller \"%s\", axis %d => %s, line %d:\n%s axis.\n",
|
"Controller \"%s\", axis %d => %s, line %d:\n%s axis.\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
on ? "Enable" : "Disable");
|
on ? "Enable" : "Disable");
|
||||||
if (on == 0) {
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Disabling ...");
|
|
||||||
} else {
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Enabling ...");
|
|
||||||
}
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The answer to the enable command on MasterMACS might take some time,
|
// The answer to the enable command on MasterMACS might take some time,
|
||||||
// hence we wait for a custom timespan in seconds instead of
|
// hence we wait for a custom timespan in seconds instead of
|
||||||
// pC_->comTimeout_
|
// pC_->comTimeout_
|
||||||
double timeout = pC_->comTimeout();
|
double timeout = pC_->comTimeout();
|
||||||
if (targetReachedUninitialized_ && timeout < PowerCycleTimeout) {
|
if (pMasterMacsA_->targetReachedUninitialized &&
|
||||||
|
timeout < PowerCycleTimeout) {
|
||||||
timeout = PowerCycleTimeout;
|
timeout = PowerCycleTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1143,7 +1186,7 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
// Output message to user
|
// Output message to user
|
||||||
snprintf(value, sizeof(value), "Failed to %s within %d seconds",
|
snprintf(value, sizeof(value), "Failed to %s within %d seconds",
|
||||||
on ? "enable" : "disable", timeout_enable_disable);
|
on ? "enable" : "disable", timeout_enable_disable);
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Enabling ...");
|
pl_status = setStringParam(pC_->motorMessageText(), value);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
@ -1152,6 +1195,17 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
return asynError;
|
return asynError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::needInit() { return pMasterMacsA_->needInit; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Instruct the axis to run its init() function during the next poll
|
||||||
|
*
|
||||||
|
* @param needInit
|
||||||
|
*/
|
||||||
|
void masterMacsAxis::setNeedInit(bool needInit) {
|
||||||
|
pMasterMacsA_->needInit = needInit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convert a float to an unint16_t bitset
|
Convert a float to an unint16_t bitset
|
||||||
*/
|
*/
|
||||||
@ -1181,7 +1235,7 @@ asynStatus masterMacsAxis::readAxisStatus() {
|
|||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
axisStatus_ = toBitset(axisStatus);
|
pMasterMacsA_->axisStatus = toBitset(axisStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rw_status;
|
return rw_status;
|
||||||
@ -1201,11 +1255,83 @@ asynStatus masterMacsAxis::readAxisError() {
|
|||||||
return pC_->couldNotParseResponse("R11", response, axisNo_,
|
return pC_->couldNotParseResponse("R11", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
axisError_ = toBitset(axisError);
|
pMasterMacsA_->axisError = toBitset(axisError);
|
||||||
}
|
}
|
||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::readyToBeSwitchedOn() {
|
||||||
|
return pMasterMacsA_->axisStatus[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::switchedOn() { return pMasterMacsA_->axisStatus[1]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::faultConditionSet() {
|
||||||
|
return pMasterMacsA_->axisStatus[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::voltagePresent() { return pMasterMacsA_->axisStatus[4]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::quickStopping() {
|
||||||
|
return pMasterMacsA_->axisStatus[5] == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::switchOnDisabled() { return pMasterMacsA_->axisStatus[6]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::warning() { return pMasterMacsA_->axisStatus[7]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::remoteMode() { return pMasterMacsA_->axisStatus[9]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::targetReached() { return pMasterMacsA_->axisStatus[10]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::internalLimitActive() {
|
||||||
|
return pMasterMacsA_->axisStatus[11];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::setEventHasOcurred() {
|
||||||
|
return pMasterMacsA_->axisStatus[14];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::powerEnabled() { return pMasterMacsA_->axisStatus[15]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::shortCircuit() { return pMasterMacsA_->axisError[1]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::encoderError() { return pMasterMacsA_->axisError[2]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::followingError() { return pMasterMacsA_->axisError[3]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::communicationError() {
|
||||||
|
return pMasterMacsA_->axisError[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::feedbackError() { return pMasterMacsA_->axisError[5]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::positiveLimitSwitch() {
|
||||||
|
return pMasterMacsA_->axisError[6];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::negativeLimitSwitch() {
|
||||||
|
return pMasterMacsA_->axisError[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::positiveSoftwareLimit() {
|
||||||
|
return pMasterMacsA_->axisError[8];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::negativeSoftwareLimit() {
|
||||||
|
return pMasterMacsA_->axisError[9];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool masterMacsAxis::overCurrent() { return pMasterMacsA_->axisError[10]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::overTemperature() { return pMasterMacsA_->axisError[11]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::overVoltage() { return pMasterMacsA_->axisError[12]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::underVoltage() { return pMasterMacsA_->axisError[13]; }
|
||||||
|
|
||||||
|
bool masterMacsAxis::stoFault() { return pMasterMacsA_->axisError[15]; }
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/** The following functions are C-wrappers, and can be called directly from
|
/** The following functions are C-wrappers, and can be called directly from
|
||||||
* iocsh */
|
* iocsh */
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
#ifndef masterMacsAXIS_H
|
#ifndef masterMacsAXIS_H
|
||||||
#define masterMacsAXIS_H
|
#define masterMacsAXIS_H
|
||||||
#include "sinqAxis.h"
|
#include "sinqAxis.h"
|
||||||
#include <bitset>
|
#include <memory>
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||||
// between the controller and the axis .h-file. See
|
// between the controller and the axis .h-file. See
|
||||||
// https://en.cppreference.com/w/cpp/language/class.
|
// https://en.cppreference.com/w/cpp/language/class.
|
||||||
class masterMacsController;
|
class masterMacsController;
|
||||||
|
|
||||||
|
struct masterMacsAxisImpl;
|
||||||
|
|
||||||
class masterMacsAxis : public sinqAxis {
|
class masterMacsAxis : public sinqAxis {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -105,23 +107,23 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
*/
|
*/
|
||||||
asynStatus readEncoderType();
|
asynStatus readEncoderType();
|
||||||
|
|
||||||
protected:
|
/**
|
||||||
masterMacsController *pC_;
|
* @brief Check if the axis needs to run its initialization function
|
||||||
double lastSetSpeed_;
|
*
|
||||||
bool waitForHandshake_;
|
* @return true
|
||||||
time_t timeAtHandshake_;
|
* @return false
|
||||||
|
*/
|
||||||
|
bool needInit();
|
||||||
|
|
||||||
bool targetReachedUninitialized_;
|
/**
|
||||||
|
* @brief Instruct the axis to run its init() function during the next poll
|
||||||
|
*
|
||||||
|
* @param needInit
|
||||||
|
*/
|
||||||
|
void setNeedInit(bool needInit);
|
||||||
|
|
||||||
asynStatus readConfig();
|
asynStatus readConfig();
|
||||||
|
|
||||||
/*
|
|
||||||
The axis status and axis error of MasterMACS are given as an integer from
|
|
||||||
the controller. The 16 individual bits contain the actual information.
|
|
||||||
*/
|
|
||||||
std::bitset<16> axisStatus_;
|
|
||||||
std::bitset<16> axisError_;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the Master MACS status with the xR10 command and store the
|
* @brief Read the Master MACS status with the xR10 command and store the
|
||||||
* result in axisStatus_
|
* result in axisStatus_
|
||||||
@ -130,7 +132,7 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
asynStatus readAxisStatus();
|
asynStatus readAxisStatus();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The functions below read the specified status bit from the axisStatus_
|
The functions below read the specified status bit from the axisStatus
|
||||||
bitset. Since a bit can either be 0 or 1, the return value is given as a
|
bitset. Since a bit can either be 0 or 1, the return value is given as a
|
||||||
boolean.
|
boolean.
|
||||||
*/
|
*/
|
||||||
@ -138,68 +140,68 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool readyToBeSwitchedOn() { return axisStatus_[0]; }
|
bool readyToBeSwitchedOn();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool switchedOn() { return axisStatus_[1]; }
|
bool switchedOn();
|
||||||
|
|
||||||
// Bit 2 is unused
|
// Bit 2 is unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool faultConditionSet() { return axisStatus_[3]; }
|
bool faultConditionSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool voltagePresent() { return axisStatus_[4]; }
|
bool voltagePresent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool quickStopping() { return axisStatus_[5] == 0; }
|
bool quickStopping();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool switchOnDisabled() { return axisStatus_[6]; }
|
bool switchOnDisabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool warning() { return axisStatus_[7]; }
|
bool warning();
|
||||||
|
|
||||||
// Bit 8 is unused
|
// Bit 8 is unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool remoteMode() { return axisStatus_[9]; }
|
bool remoteMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool targetReached() { return axisStatus_[10]; }
|
bool targetReached();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool internalLimitActive() { return axisStatus_[11]; }
|
bool internalLimitActive();
|
||||||
|
|
||||||
// Bits 12 and 13 are unused
|
// Bits 12 and 13 are unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool setEventHasOcurred() { return axisStatus_[14]; }
|
bool setEventHasOcurred();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool powerEnabled() { return axisStatus_[15]; }
|
bool powerEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the Master MACS status with the xR10 command and store the
|
* @brief Read the Master MACS status with the xR10 command and store the
|
||||||
@ -217,72 +219,76 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool shortCircuit() { return axisError_[1]; }
|
bool shortCircuit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool encoderError() { return axisError_[2]; }
|
bool encoderError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool followingError() { return axisError_[3]; }
|
bool followingError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool communicationError() { return axisError_[4]; }
|
bool communicationError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool feedbackError() { return axisError_[5]; }
|
bool feedbackError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool positiveLimitSwitch() { return axisError_[6]; }
|
bool positiveLimitSwitch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool negativeLimitSwitch() { return axisError_[7]; }
|
bool negativeLimitSwitch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool positiveSoftwareLimit() { return axisError_[8]; }
|
bool positiveSoftwareLimit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool negativeSoftwareLimit() { return axisError_[9]; }
|
bool negativeSoftwareLimit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overCurrent() { return axisError_[10]; }
|
bool overCurrent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overTemperature() { return axisError_[11]; }
|
bool overTemperature();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overVoltage() { return axisError_[12]; }
|
bool overVoltage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool underVoltage() { return axisError_[13]; }
|
bool underVoltage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool stoFault() { return axisError_[15]; }
|
bool stoFault();
|
||||||
|
|
||||||
|
private:
|
||||||
|
masterMacsController *pC_;
|
||||||
|
std::unique_ptr<masterMacsAxisImpl> pMasterMacsA_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct masterMacsControllerImpl {
|
||||||
|
double comTimeout;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy src into dst and replace all NULL terminators up to the carriage
|
* @brief Copy src into dst and replace all NULL terminators up to the carriage
|
||||||
* return with spaces. This allows to print *dst with asynPrint.
|
* return with spaces. This allows to print *dst with asynPrint.
|
||||||
@ -59,8 +63,10 @@ masterMacsController::masterMacsController(const char *portName,
|
|||||||
// Initialization of local variables
|
// Initialization of local variables
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
|
|
||||||
// Initialization of all member variables
|
pMasterMacsC_ =
|
||||||
comTimeout_ = comTimeout;
|
std::make_unique<masterMacsControllerImpl>((masterMacsControllerImpl){
|
||||||
|
.comTimeout = comTimeout,
|
||||||
|
});
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@ -158,7 +164,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
|
|
||||||
// Check if a custom timeout has been given
|
// Check if a custom timeout has been given
|
||||||
if (comTimeout < 0.0) {
|
if (comTimeout < 0.0) {
|
||||||
comTimeout = comTimeout_;
|
comTimeout = pMasterMacsC_->comTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
@ -192,7 +198,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
msgPrintControlKey comKey =
|
msgPrintControlKey comKey =
|
||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
if (msgPrintControl_.shouldBePrinted(comKey, true, pasynUserSelf)) {
|
if (getMsgPrintControl().shouldBePrinted(comKey, true, pasynUserSelf)) {
|
||||||
char printableCommand[MAXBUF_] = {0};
|
char printableCommand[MAXBUF_] = {0};
|
||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
@ -202,7 +208,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
stringifyAsynStatus(status), printableCommand);
|
stringifyAsynStatus(status), printableCommand);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(comKey, pasynUserSelf);
|
getMsgPrintControl().resetCount(comKey, pasynUserSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create custom error messages for different failure modes
|
// Create custom error messages for different failure modes
|
||||||
@ -252,21 +258,34 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
pl_status = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
pl_status = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Check if the axis already is in an error communication mode. If
|
/*
|
||||||
// it is not, upstream the error. This is done to avoid "flooding"
|
Since the communication failed, there is the possibility that the
|
||||||
// the user with different error messages if more than one error
|
controller is not connected at all to the network. In that case, we
|
||||||
// ocurred before an error-free communication
|
cannot be sure that the information read out in the init method of the
|
||||||
|
axis is still up-to-date the next time we get a connection. Therefore,
|
||||||
|
an info flag is set which the axis object can use at the start of its
|
||||||
|
poll method to try to initialize itself.
|
||||||
|
*/
|
||||||
|
axis->setNeedInit(true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
pl_status =
|
pl_status =
|
||||||
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
return paramLibAccessFailed(pl_status, "motorStatusProblem", axisNo,
|
||||||
axisNo, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (motorStatusProblem == 0) {
|
if (motorStatusProblem == 0) {
|
||||||
pl_status = axis->setStringParam(motorMessageText_, drvMessageText);
|
pl_status =
|
||||||
|
axis->setStringParam(motorMessageText(), drvMessageText);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return paramLibAccessFailed(pl_status, "motorMessageText_",
|
return paramLibAccessFailed(pl_status, "motorMessageText",
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
axisNo, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
@ -405,15 +424,15 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
"Tried to write with a read-only command. This is a "
|
"Tried to write with a read-only command. This is a "
|
||||||
"bug, please call the support.");
|
"bug, please call the support.");
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(parseKey, true,
|
if (getMsgPrintControl().shouldBePrinted(parseKey, true,
|
||||||
pasynUserSelf)) {
|
pasynUserSelf)) {
|
||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d:\nTried to "
|
"Controller \"%s\", axis %d => %s, line %d:\nTried to "
|
||||||
"write with the read-only command %s.%s\n",
|
"write with the read-only command %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
printableCommand, msgPrintControl_.getSuffix());
|
printableCommand, getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
responseValid = false;
|
responseValid = false;
|
||||||
break;
|
break;
|
||||||
@ -421,7 +440,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (responseValid) {
|
if (responseValid) {
|
||||||
msgPrintControl_.resetCount(parseKey, pasynUserSelf);
|
getMsgPrintControl().resetCount(parseKey, pasynUserSelf);
|
||||||
|
|
||||||
// Check if the response matches the expectations. Each response
|
// Check if the response matches the expectations. Each response
|
||||||
// contains the string "axisNo R tcpCmd" (including the spaces)
|
// contains the string "axisNo R tcpCmd" (including the spaces)
|
||||||
@ -445,15 +464,15 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
adjustForPrint(printableResponse, fullResponse, MAXBUF_);
|
adjustForPrint(printableResponse, fullResponse, MAXBUF_);
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(parseKey, true,
|
if (getMsgPrintControl().shouldBePrinted(parseKey, true,
|
||||||
pasynUserSelf)) {
|
pasynUserSelf)) {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
"%d:\nMismatched "
|
"%d:\nMismatched "
|
||||||
"response %s to command %s.%s\n",
|
"response %s to command %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
printableResponse, printableCommand,
|
printableResponse, printableCommand,
|
||||||
msgPrintControl_.getSuffix());
|
getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(drvMessageText, MAXBUF_,
|
snprintf(drvMessageText, MAXBUF_,
|
||||||
@ -462,15 +481,16 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
printableResponse, printableCommand);
|
printableResponse, printableCommand);
|
||||||
return asynError;
|
return asynError;
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(responseMatchKey, pasynUserSelf);
|
getMsgPrintControl().resetCount(responseMatchKey, pasynUserSelf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus sinqController::readInt32(asynUser *pasynUser, epicsInt32 *value) {
|
asynStatus masterMacsController::readInt32(asynUser *pasynUser,
|
||||||
|
epicsInt32 *value) {
|
||||||
// masterMacs can be disabled
|
// masterMacs can be disabled
|
||||||
if (pasynUser->reason == motorCanDisable_) {
|
if (pasynUser->reason == motorCanDisable()) {
|
||||||
*value = 1;
|
*value = 1;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
} else {
|
} else {
|
||||||
@ -478,6 +498,8 @@ asynStatus sinqController::readInt32(asynUser *pasynUser, epicsInt32 *value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double masterMacsController::comTimeout() { return pMasterMacsC_->comTimeout; }
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/** The following functions are C-wrappers, and can be called directly from
|
/** The following functions are C-wrappers, and can be called directly from
|
||||||
* iocsh */
|
* iocsh */
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
#include "masterMacsAxis.h"
|
#include "masterMacsAxis.h"
|
||||||
#include "sinqAxis.h"
|
#include "sinqAxis.h"
|
||||||
#include "sinqController.h"
|
#include "sinqController.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct masterMacsControllerImpl;
|
||||||
|
|
||||||
class masterMacsController : public sinqController {
|
class masterMacsController : public sinqController {
|
||||||
|
|
||||||
@ -31,6 +34,15 @@ class masterMacsController : public sinqController {
|
|||||||
int numAxes, double movingPollPeriod,
|
int numAxes, double movingPollPeriod,
|
||||||
double idlePollPeriod, double comTimeout);
|
double idlePollPeriod, double comTimeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Overloaded version of the sinqController version
|
||||||
|
*
|
||||||
|
* @param pasynUser
|
||||||
|
* @param value
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the axis object
|
* @brief Get the axis object
|
||||||
*
|
*
|
||||||
@ -123,13 +135,10 @@ class masterMacsController : public sinqController {
|
|||||||
*
|
*
|
||||||
* @return double Timeout in seconds
|
* @return double Timeout in seconds
|
||||||
*/
|
*/
|
||||||
double comTimeout() { return comTimeout_; }
|
double comTimeout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
std::unique_ptr<masterMacsControllerImpl> pMasterMacsC_;
|
||||||
Stores the constructor input comTimeout
|
|
||||||
*/
|
|
||||||
double comTimeout_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* masterMacsController_H */
|
#endif /* masterMacsController_H */
|
||||||
|
Reference in New Issue
Block a user