Compare commits

..

1 Commits

Author SHA1 Message Date
50ed53f395 Incremented required motorBase version to match upstream (7.3.2 was a local patch version which doesn't exist upstream)
Some checks failed
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Failing after 7s
2026-03-24 14:27:35 +01:00
5 changed files with 52 additions and 73 deletions

View File

@@ -10,7 +10,7 @@ ARCH_FILTER=RHEL%
REQUIRED+=motorBase
# Specify the version of motorBase we want to build against
motorBase_VERSION=7.3.2
motorBase_VERSION=7.4
# These headers allow to depend on this library for derived drivers.
HEADERS += src/pmacAsynIPPort.h

View File

@@ -91,9 +91,9 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
}
// Even though this happens already in sinqAxis, a default value for
// motorErrorMessage is set here again, because apparently the sinqAxis
// motorMessageText is set here again, because apparently the sinqAxis
// constructor is not run before the string is accessed?
status = setStringParam(pC_->motorErrorMessage(), "");
status = setStringParam(pC_->motorMessageText(), "");
if (status != asynSuccess) {
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d:\nFATAL ERROR "
@@ -140,9 +140,6 @@ asynStatus turboPmacAxis::init() {
// Deadband in counts. Can be a fraction of a count, hence double.
double deadband_counts = 0.0;
// Read from the controller if the motor has been homed before
int hasBeenHomed = 0;
// Offset time for the movement watchdog caused by the air cushions in
// milliseconds.
int acoDelay = 0.0;
@@ -179,11 +176,9 @@ asynStatus turboPmacAxis::init() {
Ixx65.
*/
snprintf(command, sizeof(command),
"Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 Q%2.2d00 I%2.2d65 "
"M%2.2d45",
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_,
axisNo_);
status = pC_->writeRead(axisNo_, command, response, 8);
"Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 Q%2.2d00 I%2.2d65",
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
status = pC_->writeRead(axisNo_, command, response, 7);
msgPrintControlKey keyDisconnected = msgPrintControlKey(
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, 1);
@@ -210,14 +205,9 @@ asynStatus turboPmacAxis::init() {
pC_->getMsgPrintControl().resetCount(keyDisconnected, pC_->pasynUser());
}
nvals = sscanf(response, "%lf %lf %lf %lf %d %lf %lf %d", &motorPos,
nvals = sscanf(response, "%lf %lf %lf %lf %d %lf %lf", &motorPos,
&motorVmax, &motorVelocity, &motorAccel, &acoDelay,
&counts_to_eu, &deadband_counts, &hasBeenHomed);
if (nvals != 8) {
return pC_->couldNotParseResponse(command, response, axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
&counts_to_eu, &deadband_counts);
// The acoDelay is given in milliseconds -> Convert to seconds, rounded
// up
@@ -228,6 +218,11 @@ asynStatus turboPmacAxis::init() {
// here to mm/s^2.
motorAccel = motorAccel * 1000;
if (nvals != 7) {
return pC_->couldNotParseResponse(command, response, axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
// Store these values in the parameter library
status = setMotorPosition(motorPos);
if (status != asynSuccess) {
@@ -287,9 +282,6 @@ asynStatus turboPmacAxis::init() {
pTurboPmacA_->needInit = false;
}
// Use the homing status reported by the controller
setAxisParamChecked(this, motorStatusHomed, hasBeenHomed);
return status;
}
@@ -347,7 +339,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
}
if (timedOut) {
setAxisParamChecked(this, motorErrorMessage,
setAxisParamChecked(this, motorMessageText,
"Timed out while waiting for a handshake");
pTurboPmacA_->waitForHandshake = false;
}
@@ -467,7 +459,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
pC_->getMsgPrintControl().getSuffix());
}
resetCountStatus = false;
setAxisParamChecked(this, motorErrorMessage, "Emergency stop");
setAxisParamChecked(this, motorMessageText, "Emergency stop");
break;
case -3:
// Disabled
@@ -560,7 +552,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
userMessage, sizeof(userMessage),
"Reached unknown state P%2.2d00 = %d. Please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
}
if (resetCountStatus) {
@@ -624,7 +616,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->getMsgPrintControl().getSuffix());
}
setAxisParamChecked(this, motorErrorMessage,
setAxisParamChecked(this, motorMessageText,
"Target position would exceed software limits");
break;
case 5:
@@ -640,7 +632,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
pC_->getMsgPrintControl().getSuffix());
}
setAxisParamChecked(this, motorErrorMessage,
setAxisParamChecked(this, motorMessageText,
"Axis received move command while it is still "
"moving. Please call the support.");
break;
@@ -661,7 +653,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"(P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 9:
if (pC_->getMsgPrintControl().shouldBePrinted(
@@ -680,7 +672,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"No feedback from auxiliary device before movement (P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 10:
/*
@@ -706,7 +698,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"the SPS for errors (if available). "
"Otherwise please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 11:
// Following error
@@ -726,7 +718,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"Check if movement range is blocked. "
"Otherwise please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 12:
@@ -744,7 +736,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"for errors (if available). Otherwise please call "
"the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 13:
@@ -763,7 +755,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"Driver hardware error (P%2.2d01 = 13). Please call the "
"support.",
axisNo_);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 14:
// EPICS should already prevent this issue in the first place,
@@ -781,7 +773,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
"Move command exceeds hardware limits (P%2.2d01 = %d). Please "
"call the support.",
axisNo_, error);
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
default:
@@ -795,7 +787,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
error, pC_->getMsgPrintControl().getSuffix());
}
setAxisParamChecked(this, motorErrorMessage, userMessage);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
}
return status;
@@ -1112,7 +1104,7 @@ asynStatus turboPmacAxis::rereadEncoder() {
"disabled before rereading the encoder.\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
setAxisParamChecked(
this, motorErrorMessage,
this, motorMessageText,
"Axis must be disabled before rereading the encoder.");
return asynError;
} else {
@@ -1175,7 +1167,7 @@ asynStatus turboPmacAxis::enable(bool on) {
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
axStatus);
setAxisParamChecked(this, motorErrorMessage,
setAxisParamChecked(this, motorMessageText,
"Axis cannot be disabled while it is moving.");
pTurboPmacA_->enableDisable = false;
return asynError;
@@ -1245,9 +1237,7 @@ asynStatus turboPmacAxis::enable(bool on) {
// Enabling / disabling procedure is completed (successfully)
pTurboPmacA_->enableDisable = false;
// Reinitialize the motor
return init();
return asynSuccess;
}
}
@@ -1262,7 +1252,7 @@ asynStatus turboPmacAxis::enable(bool on) {
// Output message to user
snprintf(command, sizeof(command), "Failed to %s within %d seconds",
on ? "enable" : "disable", timeout_enable_disable);
setAxisParamChecked(this, motorErrorMessage, command);
setAxisParamChecked(this, motorMessageText, command);
// Enabling / disabling procedure failed
pTurboPmacA_->enableDisable = false;

View File

@@ -445,7 +445,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
if (motorStatusProblem == 0) {
setAxisParamChecked(axis, motorErrorMessage, drvMessageText);
setAxisParamChecked(axis, motorMessageText, drvMessageText);
setAxisParamChecked(axis, motorStatusProblem, true);
setAxisParamChecked(axis, motorStatusCommsError, true);
}

View File

@@ -9,55 +9,45 @@ Stefan Mathis, December 2024
import struct
import socket
import curses
import time
def packPmacCommand(command):
# 0x40 = VR_DOWNLOAD
# 0x40 = VR_DOWNLOAD
# 0xBF = VR_PMAC_GETRESPONSE
buf = struct.pack('BBHHH', 0x40, 0xBF, 0, 0, socket.htons(len(command)))
buf = buf + command.encode('utf-8')
buf = struct.pack('BBHHH',0x40,0xBF,0,0,socket.htons(len(command)))
buf = buf + bytes(command,'utf-8')
return buf
def readPmacReply(sock):
def readPmacReply(input):
msg = bytearray()
expectAck = True
sock.settimeout(2.0)
while True:
try:
b = sock.recv(1)
except socket.timeout:
print('Timed out')
return None
bint = int.from_bytes(b, byteorder='little')
if bint == 2 or bint == 7: # STX or BELL
b = input.recv(1)
bint = int.from_bytes(b,byteorder='little')
if bint == 2 or bint == 7: #STX or BELL
expectAck = False
continue
if expectAck and bint == 6: # ACK
if expectAck and bint == 6: # ACK
return bytes(msg)
else:
if bint == 13 and not expectAck: # CR
if bint == 13 and not expectAck: # CR
return bytes(msg)
else:
msg.append(bint)
if __name__ == "__main__":
from sys import argv
try:
addr = argv[1].split(':')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((addr[0], int(addr[1])))
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((addr[0],int(addr[1])))
if len(argv) == 3:
buf = packPmacCommand(argv[2])
s.send(buf)
reply = readPmacReply(s)
if reply:
print(reply.decode('utf-8') + '\n')
print(reply.decode('utf-8') + '\n')
else:
@@ -91,13 +81,13 @@ if __name__ == "__main__":
if ptr > 0:
ptr -= 1
stdscr.addch("\r")
stdscr.clrtoeol()
stdscr.clrtoeol()
stdscr.addstr(">> " + history[ptr])
elif c == curses.KEY_DOWN:
if ptr < len(history) - 1:
ptr += 1
stdscr.addch("\r")
stdscr.clrtoeol()
stdscr.clrtoeol()
stdscr.addstr(">> " + history[ptr])
elif c == curses.KEY_ENTER or c == ord('\n') or c == ord('\r'):
if history[ptr] == 'quit':
@@ -123,7 +113,7 @@ if __name__ == "__main__":
stdscr.refresh()
else:
if ptr < len(history) - 1: # Modifying previous input
if ptr < len(history) - 1: # Modifying previous input
if len(history[-1]) == 0:
history[-1] = history[ptr]
ptr = len(history) - 1
@@ -136,20 +126,18 @@ if __name__ == "__main__":
if len(history[ptr]) == 0:
continue
(y, x) = stdscr.getyx()
history[ptr] = history[ptr][0:x-4] + \
history[ptr][x-3:]
history[ptr] = history[ptr][0:x-4] + history[ptr][x-3:]
stdscr.addch("\r")
stdscr.clrtoeol()
stdscr.clrtoeol()
stdscr.addstr(">> " + history[ptr])
stdscr.move(y, x-1)
stdscr.refresh()
else:
(y, x) = stdscr.getyx()
history[ptr] = history[ptr][0:x-3] + \
chr(c) + history[ptr][x-3:]
history[ptr] = history[ptr][0:x-3] + chr(c) + history[ptr][x-3:]
stdscr.addch("\r")
stdscr.clrtoeol()
stdscr.clrtoeol()
stdscr.addstr(">> " + history[ptr])
stdscr.move(y, x+1)
stdscr.refresh()
@@ -181,3 +169,4 @@ if __name__ == "__main__":
the reponse, before being prompted to again enter a command. Type
'quit' to close prompt.
""")