moved disconnect handling to sinqMotor
This commit is contained in:
Submodule sinqMotor updated: 2578081814...97c3ed4556
@@ -179,22 +179,52 @@ asynStatus turboPmacAxis::init() {
|
||||
"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);
|
||||
|
||||
if (status != asynSuccess) {
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyDisconnected, true,
|
||||
pC_->pasynUser())) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nCould not communicate "
|
||||
"with controller during IOC initialization. Check if you used "
|
||||
"\"pmacAsynIPPortConfigure\" instead of the standard "
|
||||
"\"drvAsynIPPortConfigure\" function in the .cmd file in order to "
|
||||
"create the port driver.\n",
|
||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
|
||||
pTurboPmacA_->needInit = true;
|
||||
"Controller \"%s\", axis %d => %s, line %d\nCould not "
|
||||
"communicate with controller during IOC initialization (error "
|
||||
"%s). Did you use \"drvAsynIPPortConfigure\" instead of "
|
||||
"\"pmacAsynIPPortConfigure\" in the .cmd file to create the "
|
||||
"port driver?\n",
|
||||
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->stringifyAsynStatus(status));
|
||||
}
|
||||
pTurboPmacA_->needInit = true;
|
||||
|
||||
status = callParamCallbacks();
|
||||
if (status != asynSuccess) {
|
||||
// If we can't communicate with the parameter library, it
|
||||
// doesn't make sense to try and upstream this to the user ->
|
||||
// Just log the error
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line "
|
||||
"%d\ncallParamCallbacks failed with %s.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->stringifyAsynStatus(status));
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// No error has been detected -> Reset the error count
|
||||
if (status == asynSuccess) {
|
||||
pC_->getMsgPrintControl().resetCount(keyDisconnected, pC_->pasynUser());
|
||||
}
|
||||
|
||||
nvals = sscanf(response, "%lf %lf %lf %lf %d %lf %lf", &motorPos,
|
||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay,
|
||||
&counts_to_eu, &deadband_counts);
|
||||
|
||||
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
||||
// The acoDelay is given in milliseconds -> Convert to seconds, rounded
|
||||
// up
|
||||
setOffsetMovTimeout(std::ceil(acoDelay / 1000.0));
|
||||
|
||||
// The PMAC electronic specifies the acceleration in m/s^2. Since we
|
||||
@@ -227,18 +257,18 @@ asynStatus turboPmacAxis::init() {
|
||||
}
|
||||
|
||||
/*
|
||||
Check if the new target position is within the range current position +/-
|
||||
deadband. If that is the case, no movement command should be sent. This
|
||||
functionality is implemented within the motor record itself, we just need to
|
||||
populate the field SPDP (see record PushSPDB2Field in db/turboPmac.db)
|
||||
Check if the new target position is within the range current position
|
||||
+/- deadband. If that is the case, no movement command should be sent.
|
||||
This functionality is implemented within the motor record itself, we
|
||||
just need to populate the field SPDP (see record PushSPDB2Field in
|
||||
db/turboPmac.db)
|
||||
|
||||
First, the deadband is read out (Ixx65, see Turbo PMAC User Manual, p.
|
||||
160). This value then needs to be converted into counts (by dividing it by
|
||||
16). After words, the deadband in counts then need to be converted into
|
||||
engineering units. For this, the scaling factor Qxx10 needs to be applied
|
||||
(see SINQ_2G_MCU_SW_manual_rev7, p. 17):
|
||||
[Qxx10] = engineering units (eu) / counts
|
||||
deadband_eu = Qxx10 * Ixx65 / 16
|
||||
160). This value then needs to be converted into counts (by dividing it
|
||||
by 16). After words, the deadband in counts then need to be converted
|
||||
into engineering units. For this, the scaling factor Qxx10 needs to be
|
||||
applied (see SINQ_2G_MCU_SW_manual_rev7, p. 17): [Qxx10] = engineering
|
||||
units (eu) / counts deadband_eu = Qxx10 * Ixx65 / 16
|
||||
|
||||
The values of Qxx10 and Ixx65 are read out during initialization and are
|
||||
assumed to not change during operation.
|
||||
@@ -249,11 +279,12 @@ asynStatus turboPmacAxis::init() {
|
||||
// Update the parameter library immediately
|
||||
status = callParamCallbacks();
|
||||
if (status != asynSuccess) {
|
||||
// If we can't communicate with the parameter library, it doesn't make
|
||||
// sense to try and upstream this to the user -> Just log the error
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\ncallParamCallbacks "
|
||||
// If we can't communicate with the parameter library, it doesn't
|
||||
// make sense to try and upstream this to the user -> Just log the
|
||||
// error
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line "
|
||||
"%d\ncallParamCallbacks "
|
||||
"failed with %s.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->stringifyAsynStatus(status));
|
||||
@@ -341,13 +372,13 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
// If an error occurred while waiting for the handshake, abort the
|
||||
// waiting procedure and continue with the poll in order to handle
|
||||
// the error.
|
||||
// If an error occurred while waiting for the handshake, abort
|
||||
// the waiting procedure and continue with the poll in order to
|
||||
// handle the error.
|
||||
pTurboPmacA_->waitForHandshake = false;
|
||||
} else if (handshakePerformed == 1) {
|
||||
// Handshake has been performed successfully -> Continue with the
|
||||
// poll
|
||||
// Handshake has been performed successfully -> Continue with
|
||||
// the poll
|
||||
pTurboPmacA_->waitForHandshake = false;
|
||||
} else {
|
||||
// Still waiting for the handshake - try again in the next busy
|
||||
@@ -387,15 +418,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
/*
|
||||
The axis limits are set as: ({[]})
|
||||
where [] are the positive and negative limits set in EPICS/NICOS, {} are the
|
||||
software limits set on the MCU and () are the hardware limit switches. In
|
||||
other words, the EPICS/NICOS limits should be stricter than the software
|
||||
limits on the MCU which in turn should be stricter than the hardware limit
|
||||
switches. For example, if the hardware limit switches are at [-10, 10], the
|
||||
software limits could be at [-9, 9] and the EPICS / NICOS limits could be at
|
||||
where [] are the positive and negative limits set in EPICS/NICOS, {} are
|
||||
the software limits set on the MCU and () are the hardware limit
|
||||
switches. In other words, the EPICS/NICOS limits should be stricter than
|
||||
the software limits on the MCU which in turn should be stricter than the
|
||||
hardware limit switches. For example, if the hardware limit switches are
|
||||
at [-10, 10], the software limits could be at [-9, 9] and the EPICS /
|
||||
NICOS limits could be at
|
||||
[-8, 8]. Therefore, we cannot use the software limits read from the MCU
|
||||
directly, but need to shrink them a bit. In this case, we're shrinking them
|
||||
by limitsOffset on both sides.
|
||||
directly, but need to shrink them a bit. In this case, we're shrinking
|
||||
them by limitsOffset on both sides.
|
||||
*/
|
||||
getAxisParamChecked(this, motorLimitsOffset, &limitsOffset);
|
||||
highLimit = highLimit - limitsOffset;
|
||||
@@ -411,8 +443,8 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
(axStatus != -3 && axStatus != -5));
|
||||
}
|
||||
|
||||
// Create the unique callsite identifier manually so it can be used later in
|
||||
// the shouldBePrinted calls.
|
||||
// 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;
|
||||
@@ -433,9 +465,9 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUser())) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line "
|
||||
"%d\nEmergency stop "
|
||||
"activated.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
@@ -508,8 +540,8 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
*moving = false;
|
||||
break;
|
||||
case 15:
|
||||
// Move is interrupted, but the motor is not ready to receive another
|
||||
// move command. Therefore it is treated as still moving.
|
||||
// Move is interrupted, but the motor is not ready to receive
|
||||
// another move command. Therefore it is treated as still moving.
|
||||
*moving = true;
|
||||
break;
|
||||
case 16:
|
||||
@@ -604,11 +636,11 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, true,
|
||||
pC_->pasynUser())) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
asynPrint(pC_->pasynUser(), 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",
|
||||
"should prevent this, check if *moving is set "
|
||||
"correctly.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
@@ -623,13 +655,14 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nLost feedback "
|
||||
"from auxiliary device during movement (P%2.2d01 = %d).%s\n",
|
||||
"from auxiliary device during movement (P%2.2d01 = "
|
||||
"%d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error, pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
snprintf(
|
||||
userMessage, sizeUserMessage,
|
||||
"Lost feedback from auxiliary device during movement (P%2.2d01 = "
|
||||
snprintf(userMessage, sizeUserMessage,
|
||||
"Lost feedback from auxiliary device during movement "
|
||||
"(P%2.2d01 = "
|
||||
"%d). Please call the support.",
|
||||
axisNo_, error);
|
||||
setAxisParamChecked(this, motorMessageText, userMessage);
|
||||
@@ -638,12 +671,12 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, true,
|
||||
pC_->pasynUser())) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nNo feedback from "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nNo feedback "
|
||||
"from "
|
||||
"auxiliary device before movement (P%2.2d01 = %d).%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error, pC_->getMsgPrintControl().getSuffix());
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
|
||||
snprintf(
|
||||
@@ -655,10 +688,10 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
break;
|
||||
case 10:
|
||||
/*
|
||||
Software limits of the controller have been hit. Since the EPICS limits
|
||||
are derived from the software limits and are a little bit smaller, this
|
||||
error case can only happen if either the axis has an incremental encoder
|
||||
which is not properly homed or if a bug occured.
|
||||
Software limits of the controller have been hit. Since the EPICS
|
||||
limits are derived from the software limits and are a little bit
|
||||
smaller, this error case can only happen if either the axis has an
|
||||
incremental encoder which is not properly homed or if a bug occured.
|
||||
*/
|
||||
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
@@ -685,9 +718,9 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
if (pC_->getMsgPrintControl().shouldBePrinted(
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, true,
|
||||
pC_->pasynUser())) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum "
|
||||
"allowed "
|
||||
"following error exceeded.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
@@ -730,9 +763,9 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->getMsgPrintControl().getSuffix());
|
||||
}
|
||||
snprintf(
|
||||
userMessage, sizeUserMessage,
|
||||
"Driver hardware error (P%2.2d01 = 13). Please call the support.",
|
||||
snprintf(userMessage, sizeUserMessage,
|
||||
"Driver hardware error (P%2.2d01 = 13). Please call the "
|
||||
"support.",
|
||||
axisNo_);
|
||||
setAxisParamChecked(this, motorMessageText, userMessage);
|
||||
break;
|
||||
@@ -798,9 +831,9 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
|
||||
|
||||
if (enabled == 0) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is disabled.\n",
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"disabled.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
return asynSuccess;
|
||||
}
|
||||
@@ -819,8 +852,8 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
getAxisParamChecked(this, motorCanSetSpeed, &motorCanSetSpeed);
|
||||
|
||||
// Prepend the new motor speed, if the user is allowed to set the speed.
|
||||
// Mind the " " (space) before the closing "", as the command created here
|
||||
// is prepended to the one down below.
|
||||
// Mind the " " (space) before the closing "", as the command created
|
||||
// here is prepended to the one down below.
|
||||
if (motorCanSetSpeed != 0) {
|
||||
snprintf(command, sizeof(command), "Q%2.2d04=%lf ", axisNo_,
|
||||
motorVelocity);
|
||||
@@ -833,8 +866,8 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
motorVelocity);
|
||||
}
|
||||
|
||||
// Perform handshake, Set target position (and speed, if allowed) and start
|
||||
// the move command
|
||||
// Perform handshake, Set target position (and speed, if allowed) and
|
||||
// start the move command
|
||||
if (relative) {
|
||||
snprintf(&command[writeOffset], sizeof(command) - writeOffset,
|
||||
"P%2.2d23=0 Q%2.2d02=%lf M%2.2d=2", axisNo_, axisNo_,
|
||||
@@ -849,9 +882,9 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
status = pC_->writeRead(axisNo_, command, response, 0);
|
||||
if (status != asynSuccess) {
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStarting movement to "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStarting "
|
||||
"movement to "
|
||||
"target position %lf failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
motorTargetPosition);
|
||||
@@ -859,8 +892,8 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||
return status;
|
||||
}
|
||||
|
||||
// In the next poll, we will check if the handshake has been performed in a
|
||||
// reasonable time
|
||||
// In the next poll, we will check if the handshake has been performed
|
||||
// in a reasonable time
|
||||
pTurboPmacA_->waitForHandshake = true;
|
||||
pTurboPmacA_->timeAtHandshake = time(NULL);
|
||||
|
||||
@@ -889,25 +922,25 @@ asynStatus turboPmacAxis::stop(double acceleration) {
|
||||
status = pC_->writeRead(axisNo_, command, response, 0);
|
||||
|
||||
if (status != asynSuccess) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStopping the movement "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nStopping "
|
||||
"the movement "
|
||||
"failed.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
setAxisParamChecked(this, motorStatusProblem, true);
|
||||
}
|
||||
|
||||
// Reset the driver to idle state and move out of the handshake wait loop,
|
||||
// if we're currently inside it.
|
||||
// Reset the driver to idle state and move out of the handshake wait
|
||||
// loop, if we're currently inside it.
|
||||
pTurboPmacA_->waitForHandshake = false;
|
||||
|
||||
/*
|
||||
Stopping the motor results in a movement and further move commands have to
|
||||
wait until the stopping movement is done. Therefore, we need to wait until
|
||||
the poller "sees" the changed state (otherwise, we risk issuing move
|
||||
commands while the motor is stopping). To ensure that at least one poll is
|
||||
done, this thread (which also runs move commands) is paused for twice the
|
||||
idle poll period.
|
||||
Stopping the motor results in a movement and further move commands have
|
||||
to wait until the stopping movement is done. Therefore, we need to wait
|
||||
until the poller "sees" the changed state (otherwise, we risk issuing
|
||||
move commands while the motor is stopping). To ensure that at least one
|
||||
poll is done, this thread (which also runs move commands) is paused for
|
||||
twice the idle poll period.
|
||||
*/
|
||||
unsigned int idlePollMicros =
|
||||
(unsigned int)ceil(pC_->idlePollPeriod() * 1e6);
|
||||
@@ -938,8 +971,8 @@ asynStatus turboPmacAxis::doReset() {
|
||||
setAxisParamChecked(this, motorStatusProblem, true);
|
||||
}
|
||||
|
||||
// Reset the driver to idle state and move out of the handshake wait loop,
|
||||
// if we're currently inside it.
|
||||
// Reset the driver to idle state and move out of the handshake wait
|
||||
// loop, if we're currently inside it.
|
||||
pTurboPmacA_->waitForHandshake = false;
|
||||
|
||||
// Disable the axis
|
||||
@@ -1037,13 +1070,14 @@ asynStatus turboPmacAxis::readEncoderType() {
|
||||
}
|
||||
|
||||
/*
|
||||
This is not a command that can always be run when enabling a motor as it also
|
||||
causes relative encoders to reread a position necessitating recalibration. We
|
||||
only want it to run on absolute encoders. We also want it to be clear to
|
||||
instrument scientists, that power has to be cut to the motor, in order to reread
|
||||
the encoder as not all motors have breaks and they may start to move when
|
||||
disabled. For that reason, we don't automatically disable the motors to run the
|
||||
command and instead require that the scientists first disable the motor.
|
||||
This is not a command that can always be run when enabling a motor as it
|
||||
also causes relative encoders to reread a position necessitating
|
||||
recalibration. We only want it to run on absolute encoders. We also want it
|
||||
to be clear to instrument scientists, that power has to be cut to the motor,
|
||||
in order to reread the encoder as not all motors have breaks and they may
|
||||
start to move when disabled. For that reason, we don't automatically disable
|
||||
the motors to run the command and instead require that the scientists first
|
||||
disable the motor.
|
||||
*/
|
||||
asynStatus turboPmacAxis::rereadEncoder() {
|
||||
char command[pC_->MAXBUF_] = {0};
|
||||
@@ -1087,11 +1121,12 @@ asynStatus turboPmacAxis::rereadEncoder() {
|
||||
return asynError;
|
||||
} else {
|
||||
snprintf(command, sizeof(command), "M%2.2d=15", axisNo_);
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nRereading absolute "
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nRereading "
|
||||
"absolute "
|
||||
"encoder via command %s.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, command);
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
command);
|
||||
pC_->writeRead(axisNo_, command, response, 0);
|
||||
}
|
||||
|
||||
@@ -1100,8 +1135,8 @@ asynStatus turboPmacAxis::rereadEncoder() {
|
||||
// it is actually finished, so we instead wait for 0.5 seconds.
|
||||
usleep(500000);
|
||||
|
||||
// Turn off parameter as finished rereading, this will only be immediately
|
||||
// noticed in the read back variable though
|
||||
// Turn off parameter as finished rereading, this will only be
|
||||
// immediately noticed in the read back variable though
|
||||
setAxisParamChecked(this, rereadEncoderPosition, false);
|
||||
return asynSuccess;
|
||||
}
|
||||
@@ -1121,27 +1156,28 @@ asynStatus turboPmacAxis::enable(bool on) {
|
||||
/*
|
||||
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.
|
||||
function fails before it can determine that, it is assumed that the
|
||||
motor is not moving.
|
||||
*/
|
||||
bool moving = false;
|
||||
doPoll(&moving);
|
||||
|
||||
// If the axis is currently moving, it cannot be disabled. Ignore the
|
||||
// command and inform the user. We check the last known status of the axis
|
||||
// instead of "moving", since status -6 is also moving, but the motor can
|
||||
// actually be disabled in this state!
|
||||
// command and inform the user. We check the last known status of the
|
||||
// axis instead of "moving", since status -6 is also moving, but the
|
||||
// motor can actually be disabled in this state!
|
||||
int axStatus = pTurboPmacA_->axisStatus;
|
||||
if (axStatus == 1 || axStatus == 2 || axStatus == 3 || axStatus == 4 ||
|
||||
axStatus == 5 || axStatus == 6 || axStatus == 7 || axStatus == 8 ||
|
||||
axStatus == 9 || axStatus == 10 || axStatus == 11 || axStatus == 12 ||
|
||||
axStatus == 13 || axStatus == 15 || axStatus == 16) {
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
||||
"idle (status %d) and can therefore not be enabled / disabled.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axStatus);
|
||||
"idle (status %d) and can therefore not be enabled / "
|
||||
"disabled.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axStatus);
|
||||
|
||||
setAxisParamChecked(this, motorMessageText,
|
||||
"Axis cannot be disabled while it is moving.");
|
||||
@@ -1152,9 +1188,9 @@ asynStatus turboPmacAxis::enable(bool on) {
|
||||
// Axis is already enabled / disabled and a new enable / disable command
|
||||
// was sent => Do nothing
|
||||
if ((axStatus != -3) == on) {
|
||||
asynPrint(
|
||||
pC_->pasynUser(), ASYN_TRACE_WARNING,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is already %s.\n",
|
||||
asynPrint(pC_->pasynUser(), ASYN_TRACE_WARNING,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"already %s.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
on ? "enabled" : "disabled");
|
||||
return asynSuccess;
|
||||
@@ -1305,8 +1341,8 @@ asynStatus turboPmacCreateAxis(const char *portName, int axis) {
|
||||
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"
|
||||
@@ -1329,14 +1365,15 @@ static const iocshArg *const CreateAxisArgs[] = {&CreateAxisArg0,
|
||||
static const iocshFuncDef configTurboPmacCreateAxis = {
|
||||
"turboPmacAxis", 2, CreateAxisArgs,
|
||||
"Create an instance of a turboPmac axis. The first argument is the "
|
||||
"controller this axis should be attached to, the second argument is the "
|
||||
"controller this axis should be attached to, the second argument is "
|
||||
"the "
|
||||
"axis number."};
|
||||
static void configTurboPmacCreateAxisCallFunc(const iocshArgBuf *args) {
|
||||
turboPmacCreateAxis(args[0].sval, args[1].ival);
|
||||
}
|
||||
|
||||
// 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 turboPmacAxisRegister(void) {
|
||||
iocshRegister(&configTurboPmacCreateAxis,
|
||||
configTurboPmacCreateAxisCallFunc);
|
||||
|
||||
@@ -206,7 +206,6 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
|
||||
// Definition of local variables.
|
||||
asynStatus status = asynSuccess;
|
||||
asynStatus timeoutStatus = asynSuccess;
|
||||
char drvMessageText[MAXBUF_] = {0};
|
||||
char modResponse[MAXBUF_] = {0};
|
||||
int motorStatusProblem = 0;
|
||||
@@ -284,8 +283,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
getMsgPrintControl().getSuffix());
|
||||
}
|
||||
|
||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||
sizeof(drvMessageText));
|
||||
checkComTimeoutWatchdog(axisNo, drvMessageText, sizeof(drvMessageText));
|
||||
|
||||
int timeoutCounter = 0;
|
||||
while (1) {
|
||||
@@ -333,14 +331,10 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
axis->setNeedInit(true);
|
||||
}
|
||||
|
||||
if (timeoutStatus == asynError) {
|
||||
status = asynError;
|
||||
}
|
||||
|
||||
// The message should only ever terminate due to reason 2
|
||||
msgPrintControlKey terminateKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (eomReason != 2) {
|
||||
if (status == asynSuccess && eomReason != 2) {
|
||||
status = asynError;
|
||||
|
||||
char reasonStringified[30] = {0};
|
||||
@@ -391,7 +385,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
msgPrintControlKey numResponsesKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (numExpectedResponses != numReceivedResponses) {
|
||||
if (status == asynSuccess && numExpectedResponses != numReceivedResponses) {
|
||||
adjustResponseForPrint(modResponse, response, MAXBUF_);
|
||||
|
||||
if (getMsgPrintControl().shouldBePrinted(numResponsesKey, true,
|
||||
|
||||
Reference in New Issue
Block a user