Compare commits

..

7 Commits

Author SHA1 Message Date
mathis_s d94341e1c0 Guard against race condition with targetReached
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 8s
2026-06-09 13:36:51 +02:00
mathis_s df7a15eeb2 Extended description of bit 2 in utils/decodeStatus.py 2026-06-09 13:24:32 +02:00
mathis_s 5165923595 Only print help in utils scripts if specifically requested (bugfix)
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 8s
2026-06-09 13:13:24 +02:00
mathis_s c7a2a32c73 Bugfix
Test And Build / Lint (push) Failing after 5s
Test And Build / Build (push) Successful in 7s
2026-05-11 11:20:52 +02:00
mathis_s 21cd9320ee Fixed bug in enable method and adjusted PowerCycleTimeout value
Test And Build / Lint (push) Failing after 5s
Test And Build / Build (push) Failing after 6s
2026-05-11 11:16:59 +02:00
mathis_s 9098a932fa Fixed bug in response parsing
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 8s
If the byte 15 is encountered in the message, the parseResponse function
must return asynDisconnected (instead of asynSuccess) so the state of
the axis is accounted for properly.
2026-04-09 10:47:27 +02:00
mathis_s b96605916f Rolled back to motorBase 7.3.2 because 7.4.0 is bugged
Test And Build / Lint (push) Failing after 5s
Test And Build / Build (push) Successful in 8s
In particular, the following problem can happen (shown for a TurboPMAC,
but MasterMACS will run into the same issue):

2026/03/31 11:45:04.698 asynPortDriver:getDoubleParam: port=turboPmac1 error getting parameter 42 MOTOR_STATUS_HOMED, in list 1, wrong type
2026/03/31 11:45:04.698 Controller "turboPmac1", axis 1 => virtual asynStatus turboPmacAxis::init(), line 168:
Accessing the parameter library failed for parameter motorRecResolution_ with error wrong type.

This is definitely because of 7.4.0, because forcing 7.3.2 fixes it.
2026-04-01 10:37:06 +02:00
5 changed files with 23 additions and 19 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ EPICS_VERSIONS=7.0.7
ARCH_FILTER=RHEL%
# Specify the version of asynMotor we want to build against
motorBase_VERSION=7.4
motorBase_VERSION=7.3.2
# These headers allow to depend on this library for derived drivers.
HEADERS += src/masterMacsAxis.h
+18 -14
View File
@@ -38,7 +38,7 @@ A special communication timeout is used in the following two cases:
2) First move command after enabling the motor
This is due to MasterMACS running a powerup cycle, which can delay the answer.
*/
#define PowerCycleTimeout 10.0 // Value in seconds
#define PowerCycleTimeout 6.0 // Value in seconds
/*
Contains all instances of turboPmacAxis which have been created and is used in
@@ -532,9 +532,9 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
} else {
// If we wait for a handshake, but the motor was moving in its last poll
// cycle and has reached its target, it is not moving. Otherwise it is
// considered moving, even if we're still waiting for the handshake.
// If the motor hasn't moved after being enabled, we cannot trust
// targetReached. Hence, the targetReachedUninitialized flag guards
// against invalid detection of the "moving" status.
if (pMasterMacsA_->targetReachedUninitialized) {
*moving = false;
} else {
@@ -545,7 +545,13 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
}
}
if (targetReached()) {
// If the motor is not switched on, the targetReached bit is set to
// true. targetReachedUninitialized is set to true in the enable
// function, which is in a separate thread than doPoll. Therefore,
// doPoll can reset targetReachedUninitialized, which then can lead to
// a false "moving" status. Therefore, we only trust targetReached if
// the motor is switched on.
if (targetReached() && switchedOn()) {
pMasterMacsA_->targetReachedUninitialized = false;
}
}
@@ -1119,7 +1125,6 @@ asynStatus masterMacsAxis::readEncoderType() {
asynStatus masterMacsAxis::enable(bool on) {
int timeout_enable_disable = 2;
char msg[pC_->MAXBUF_];
// =========================================================================
@@ -1177,8 +1182,7 @@ asynStatus masterMacsAxis::enable(bool on) {
// hence we wait for a custom timespan in seconds instead of
// pC_->comTimeout_
double timeout = pC_->comTimeout();
if (pMasterMacsA_->targetReachedUninitialized &&
timeout < PowerCycleTimeout) {
if (timeout < PowerCycleTimeout) {
timeout = PowerCycleTimeout;
}
@@ -1190,7 +1194,7 @@ asynStatus masterMacsAxis::enable(bool on) {
// Query the axis status every few milliseconds until the axis has been
// enabled or until the timeout has been reached
int startTime = time(NULL);
while (time(NULL) < startTime + timeout_enable_disable) {
while (time(NULL) < startTime + PowerCycleTimeout) {
// Read the axis status
usleep(100000);
@@ -1207,17 +1211,17 @@ asynStatus masterMacsAxis::enable(bool on) {
}
}
// Failed to change axis status within timeout_enable_disable => Send a
// Failed to change axis status within PowerCycleTimeout => Send a
// corresponding message
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFailed to %s axis "
"within %d seconds\n",
"within %f seconds\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
on ? "enable" : "disable", timeout_enable_disable);
on ? "enable" : "disable", PowerCycleTimeout);
// Output message to user
snprintf(msg, sizeof(msg), "Failed to %s within %d seconds",
on ? "enable" : "disable", timeout_enable_disable);
snprintf(msg, sizeof(msg), "Failed to %s within %f seconds",
on ? "enable" : "disable", PowerCycleTimeout);
setAxisParamChecked(this, motorMessageText, msg);
return asynError;
+1 -1
View File
@@ -493,7 +493,7 @@ asynStatus masterMacsController::parseResponse(
}
}
}
break;
return asynDisconnected;
} else if (fullResponse[i] == '\x18') {
// CAN
snprintf(drvMessageText, MAXBUF_,
+1 -1
View File
@@ -67,7 +67,7 @@ the next value can be typed in. Type 'quit' to close the prompt.
if __name__ == "__main__":
from sys import argv
if "-h" or "--help" in argv:
if "-h" in argv or "--help" in argv:
print(help)
if len(argv) == 1:
+2 -2
View File
@@ -18,7 +18,7 @@ from decodeCommon import interactive, decode, print_decoded
interpretation = [
("Not ready to be switched on", "Ready to be switched on"), # Bit 0
("Not switched on", "Switched on"), # Bit 1
("Disabled", "Enabled"), # Bit 2
("Operation disabled (no current)", "Operation enabled (current)"), # Bit 2
("Ok", "Fault condition set"), # Bit 3
("Motor supply voltage absent ", "Motor supply voltage present"), # Bit 4
("Motor performs quick stop", "Ok"), # Bit 5
@@ -68,7 +68,7 @@ the next value can be typed in. Type 'quit' to close the prompt.
if __name__ == "__main__":
from sys import argv
if "-h" or "--help" in argv:
if "-h" in argv or "--help" in argv:
print(help)
if len(argv) == 1: