Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
295cd34993 | |||
b62a5fd699 | |||
a990da4245 |
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ REQUIRED+=sinqMotor
|
|||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of sinqMotor we want to build against
|
# Specify the version of sinqMotor we want to build against
|
||||||
sinqMotor_VERSION=0.9.0
|
sinqMotor_VERSION=0.11.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/turboPmacAxis.h
|
HEADERS += src/turboPmacAxis.h
|
||||||
|
10
README.md
10
README.md
@ -1,5 +1,7 @@
|
|||||||
# turboPmac
|
# turboPmac
|
||||||
|
|
||||||
|
## <span style="color:red">Please read the documentation of sinqMotor first: https://git.psi.ch/sinq-epics-modules/sinqmotor</span>
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This is a driver for the Turbo PMAC motion controller with the SINQ communication protocol. It is based on the sinqMotor shared library (https://git.psi.ch/sinq-epics-modules/sinqmotor). The header files contain detailed documentation for all public functions. The headers themselves are exported when building the library to allow other drivers to depend on this one.
|
This is a driver for the Turbo PMAC motion controller with the SINQ communication protocol. It is based on the sinqMotor shared library (https://git.psi.ch/sinq-epics-modules/sinqmotor). The header files contain detailed documentation for all public functions. The headers themselves are exported when building the library to allow other drivers to depend on this one.
|
||||||
@ -21,11 +23,11 @@ turboPmac exports the following IOC shell functions:
|
|||||||
- `turboPmacController`: Create a new controller object.
|
- `turboPmacController`: Create a new controller object.
|
||||||
- `turboPmacAxis`: Create a new axis object.
|
- `turboPmacAxis`: Create a new axis object.
|
||||||
|
|
||||||
The full mcu.cmd file looks like this:
|
The full turboPmacX.cmd file looks like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Define the name of the controller and the corresponding port
|
# Define the name of the controller and the corresponding port
|
||||||
epicsEnvSet("NAME","mcu")
|
epicsEnvSet("NAME","turboPmacX")
|
||||||
epicsEnvSet("ASYN_PORT","p$(NAME)")
|
epicsEnvSet("ASYN_PORT","p$(NAME)")
|
||||||
|
|
||||||
# Create the TCP/IP socket used to talk with the controller. The socket can be adressed from within the IOC shell via the port name
|
# Create the TCP/IP socket used to talk with the controller. The socket can be adressed from within the IOC shell via the port name
|
||||||
@ -47,8 +49,8 @@ turboPmacAxis("$(NAME)",5);
|
|||||||
# Set the number of subsequent timeouts
|
# Set the number of subsequent timeouts
|
||||||
setMaxSubsequentTimeouts("$(NAME)", 20);
|
setMaxSubsequentTimeouts("$(NAME)", 20);
|
||||||
|
|
||||||
# Configure the timeout frequency watchdog:
|
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed in 300 seconds before an alarm message is sent.
|
||||||
setThresholdComTimeout("$(NAME)", 100, 1);
|
setThresholdComTimeout("$(NAME)", 300, 10);
|
||||||
|
|
||||||
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
||||||
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
|
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
|
||||||
|
@ -96,13 +96,8 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
|||||||
// turboPmac motors can always be disabled
|
// turboPmac motors can always be disabled
|
||||||
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(
|
pC_->paramLibAccessFailed(status, "motorCanDisable", axisNo_,
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
"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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default values for the watchdog timeout mechanism
|
// Default values for the watchdog timeout mechanism
|
||||||
@ -122,7 +117,7 @@ asynStatus turboPmacAxis::init() {
|
|||||||
char command[pC_->MAXBUF_], response[pC_->MAXBUF_];
|
char command[pC_->MAXBUF_], response[pC_->MAXBUF_];
|
||||||
int nvals = 0;
|
int nvals = 0;
|
||||||
double motorRecResolution = 0.0;
|
double motorRecResolution = 0.0;
|
||||||
double motorPosition = 0.0;
|
double motorPos = 0.0;
|
||||||
double motorVelocity = 0.0;
|
double motorVelocity = 0.0;
|
||||||
double motorVmax = 0.0;
|
double motorVmax = 0.0;
|
||||||
double motorAccel = 0.0;
|
double motorAccel = 0.0;
|
||||||
@ -166,7 +161,7 @@ asynStatus turboPmacAxis::init() {
|
|||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPosition,
|
nvals = sscanf(response, "%d %lf %lf %lf %lf %d", &axStatus, &motorPos,
|
||||||
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
&motorVmax, &motorVelocity, &motorAccel, &acoDelay);
|
||||||
|
|
||||||
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
|
||||||
@ -178,18 +173,14 @@ asynStatus turboPmacAxis::init() {
|
|||||||
motorAccel = motorAccel * 1000;
|
motorAccel = motorAccel * 1000;
|
||||||
|
|
||||||
if (nvals != 6) {
|
if (nvals != 6) {
|
||||||
return pC_->errMsgCouldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform from motor to parameter library coordinates
|
|
||||||
motorPosition = motorPosition / motorRecResolution;
|
|
||||||
|
|
||||||
// Store these values in the parameter library
|
// Store these values in the parameter library
|
||||||
status = pC_->setDoubleParam(axisNo_, pC_->motorPosition(), motorPosition);
|
status = setMotorPosition(motorPos);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(status, "motorPosition_", axisNo_,
|
return status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial motor status is idle
|
// Initial motor status is idle
|
||||||
@ -230,7 +221,7 @@ asynStatus turboPmacAxis::init() {
|
|||||||
asynStatus turboPmacAxis::doPoll(bool *moving) {
|
asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||||
|
|
||||||
// Return value for the poll
|
// Return value for the poll
|
||||||
asynStatus poll_status = asynSuccess;
|
asynStatus errorStatus = asynSuccess;
|
||||||
|
|
||||||
// Status of read-write-operations of ASCII commands to the controller
|
// Status of read-write-operations of ASCII commands to the controller
|
||||||
asynStatus rw_status = asynSuccess;
|
asynStatus rw_status = asynSuccess;
|
||||||
@ -297,8 +288,8 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
nvals = sscanf(response, "%d %d", &handshakePerformed, &error);
|
nvals = sscanf(response, "%d %d", &handshakePerformed, &error);
|
||||||
if (nvals != 2) {
|
if (nvals != 2) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
command, response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
@ -333,7 +324,6 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Motor resolution from parameter library
|
|
||||||
pl_status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
|
pl_status = pC_->getDoubleParam(axisNo_, pC_->motorRecResolution(),
|
||||||
&motorRecResolution);
|
&motorRecResolution);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
@ -343,14 +333,11 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the previous motor position
|
// Read the previous motor position
|
||||||
pl_status =
|
pl_status = motorPosition(&previousPosition);
|
||||||
pC_->getDoubleParam(axisNo_, pC_->motorPosition(), &previousPosition);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_,
|
return pl_status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the previous motor position
|
|
||||||
pl_status = pC_->getIntegerParam(axisNo_, pC_->motorStatusDone(),
|
pl_status = pC_->getIntegerParam(axisNo_, pC_->motorStatusDone(),
|
||||||
&previousStatusDone);
|
&previousStatusDone);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
@ -358,10 +345,6 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform from EPICS to motor coordinates (see comment in
|
|
||||||
// turboPmacAxis::atFirstPoll)
|
|
||||||
previousPosition = previousPosition * motorRecResolution;
|
|
||||||
|
|
||||||
// Query the axis status
|
// Query the axis status
|
||||||
snprintf(command, sizeof(command),
|
snprintf(command, sizeof(command),
|
||||||
"P%2.2d00 Q%2.2d10 P%2.2d01 Q%2.2d13 Q%2.2d14", axisNo_, axisNo_,
|
"P%2.2d00 Q%2.2d10 P%2.2d01 Q%2.2d13 Q%2.2d14", axisNo_, axisNo_,
|
||||||
@ -374,8 +357,8 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
nvals = sscanf(response, "%d %lf %d %lf %lf", &axStatus, ¤tPosition,
|
nvals = sscanf(response, "%d %lf %d %lf %lf", &axStatus, ¤tPosition,
|
||||||
&error, &highLimit, &lowLimit);
|
&error, &highLimit, &lowLimit);
|
||||||
if (nvals != 5) {
|
if (nvals != 5) {
|
||||||
return pC_->errMsgCouldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -543,284 +526,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the unique callsite identifier manually so it can be used later in
|
errorStatus = handleError(error, userMessage, sizeof(userMessage));
|
||||||
// the shouldBePrinted calls.
|
|
||||||
msgPrintControlKey keyError = msgPrintControlKey(
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
|
||||||
bool resetError = true;
|
|
||||||
|
|
||||||
switch (error) {
|
|
||||||
case 0:
|
|
||||||
// No error -> Reset the message repetition watchdog
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
// EPICS should already prevent this issue in the first place,
|
|
||||||
// since it contains the user limits
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nTarget "
|
|
||||||
"position would exceed user limits.%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(),
|
|
||||||
"Target position would exceed software "
|
|
||||||
"limits. Please call the support.");
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// Command not possible
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyStatus, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(
|
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
|
||||||
"still moving, but received another move command. EPICS "
|
|
||||||
"should prevent this, check if *moving is set correctly.%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(),
|
|
||||||
"Axis received move command while it is "
|
|
||||||
"still moving. Please call the support.");
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAir cushion "
|
|
||||||
"feedback stopped during movement (P%2.2d01 = %d).%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(userMessage, sizeof(userMessage),
|
|
||||||
"Air cushion feedback stopped during movement (P%2.2d01 = "
|
|
||||||
"%d). Please call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(
|
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
|
|
||||||
"feedback before movement start (P%2.2d01 = %d).%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
|
||||||
error, pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(userMessage, sizeof(userMessage),
|
|
||||||
"No air cushion feedback before movement start (P%2.2d01 = "
|
|
||||||
"%d). Please call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(
|
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
|
||||||
"controller limits.%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(userMessage, sizeof(userMessage),
|
|
||||||
"Software limits or end switch hit (P%2.2d01 = %d). Try "
|
|
||||||
"homing the motor, moving in the opposite direction or check "
|
|
||||||
"the SPS for errors (if available). "
|
|
||||||
"Otherwise please call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
// Following error
|
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(
|
|
||||||
pC_->asynUserSelf(), 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());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(command, sizeof(command),
|
|
||||||
"Maximum allowed following error exceeded (P%2.2d01 = %d). "
|
|
||||||
"Check if movement range is blocked. "
|
|
||||||
"Otherwise please call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), command);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 12:
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nSecurity "
|
|
||||||
"input is triggered (P%2.2d01 = %d).%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(command, sizeof(command),
|
|
||||||
"Security input is triggered (P%2.2d01 = %d). Check the SPS "
|
|
||||||
"for errors (if available). Otherwise please call "
|
|
||||||
"the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), command);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13:
|
|
||||||
// Driver hardware error triggered
|
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nDriver "
|
|
||||||
"hardware error triggered.%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(command, sizeof(command),
|
|
||||||
"Driver hardware error (P%2.2d01 = 13). "
|
|
||||||
"Please call the support.",
|
|
||||||
axisNo_);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), command);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
// EPICS should already prevent this issue in the first place,
|
|
||||||
// since it contains the user limits
|
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nMove "
|
|
||||||
"command exceeds hardware limits (P%2.2d01 = %d).%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(userMessage, sizeof(userMessage),
|
|
||||||
"Move command exceeds hardware limits (P%2.2d01 = %d). Please "
|
|
||||||
"call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
|
||||||
pC_->asynUserSelf())) {
|
|
||||||
asynPrint(
|
|
||||||
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
|
||||||
"P%2.2d01 = %d.%s\n",
|
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
|
||||||
error, pC_->getMsgPrintControl().getSuffix());
|
|
||||||
}
|
|
||||||
resetError = false;
|
|
||||||
|
|
||||||
snprintf(userMessage, sizeof(userMessage),
|
|
||||||
"Unknown error P%2.2d01 = %d. Please call the support.",
|
|
||||||
axisNo_, error);
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), userMessage);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_status = asynError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetError) {
|
|
||||||
pC_->getMsgPrintControl().resetCount(keyError, pC_->asynUserSelf());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the parameter library
|
// Update the parameter library
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
@ -876,17 +582,296 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform from motor to EPICS coordinates (see comment in
|
pl_status = setMotorPosition(currentPosition);
|
||||||
// turboPmacAxis::init())
|
|
||||||
currentPosition = currentPosition / motorRecResolution;
|
|
||||||
|
|
||||||
pl_status = setDoubleParam(pC_->motorPosition(), currentPosition);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_,
|
return pl_status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
}
|
||||||
|
return errorStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
||||||
|
int sizeUserMessage) {
|
||||||
|
asynStatus status = asynSuccess;
|
||||||
|
|
||||||
|
// Create the unique callsite identifier manually so it can be used later in
|
||||||
|
// the shouldBePrinted calls.
|
||||||
|
msgPrintControlKey keyError = msgPrintControlKey(
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
bool resetError = true;
|
||||||
|
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
// No error -> Reset the message repetition watchdog
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// EPICS should already prevent this issue in the first place,
|
||||||
|
// since it contains the user limits
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nTarget "
|
||||||
|
"position would exceed user limits.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
status = setStringParam(pC_->motorMessageText(),
|
||||||
|
"Target position would exceed software "
|
||||||
|
"limits. Please call the support.");
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
// Command not possible
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(
|
||||||
|
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||||
|
"still moving, but received another move command. EPICS "
|
||||||
|
"should prevent this, check if *moving is set correctly.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
status = setStringParam(pC_->motorMessageText(),
|
||||||
|
"Axis received move command while it is "
|
||||||
|
"still moving. Please call the support.");
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nAir cushion "
|
||||||
|
"feedback stopped during movement (P%2.2d01 = %d).%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Air cushion feedback stopped during movement (P%2.2d01 = "
|
||||||
|
"%d). Please call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(
|
||||||
|
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
|
||||||
|
"feedback before movement start (P%2.2d01 = %d).%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||||
|
error, pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"No air cushion feedback before movement start (P%2.2d01 = "
|
||||||
|
"%d). Please call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(
|
||||||
|
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
||||||
|
"controller limits.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Software limits or end switch hit (P%2.2d01 = %d). Try "
|
||||||
|
"homing the motor, moving in the opposite direction or check "
|
||||||
|
"the SPS for errors (if available). "
|
||||||
|
"Otherwise please call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
// Following error
|
||||||
|
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(
|
||||||
|
pC_->asynUserSelf(), 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());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Maximum allowed following error exceeded (P%2.2d01 = %d). "
|
||||||
|
"Check if movement range is blocked. "
|
||||||
|
"Otherwise please call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nSecurity "
|
||||||
|
"input is triggered (P%2.2d01 = %d).%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Security input is triggered (P%2.2d01 = %d). Check the SPS "
|
||||||
|
"for errors (if available). Otherwise please call "
|
||||||
|
"the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 13:
|
||||||
|
// Driver hardware error triggered
|
||||||
|
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nDriver "
|
||||||
|
"hardware error triggered.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Driver hardware error (P%2.2d01 = 13). "
|
||||||
|
"Please call the support.",
|
||||||
|
axisNo_);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
// EPICS should already prevent this issue in the first place,
|
||||||
|
// since it contains the user limits
|
||||||
|
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nMove "
|
||||||
|
"command exceeds hardware limits (P%2.2d01 = %d).%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Move command exceeds hardware limits (P%2.2d01 = %d). Please "
|
||||||
|
"call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
if (pC_->getMsgPrintControl().shouldBePrinted(keyError, true,
|
||||||
|
pC_->asynUserSelf())) {
|
||||||
|
asynPrint(
|
||||||
|
pC_->asynUserSelf(), ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
||||||
|
"P%2.2d01 = %d.%s\n",
|
||||||
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||||
|
error, pC_->getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
resetError = false;
|
||||||
|
|
||||||
|
snprintf(userMessage, sizeUserMessage,
|
||||||
|
"Unknown error P%2.2d01 = %d. Please call the support.",
|
||||||
|
axisNo_, error);
|
||||||
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = asynError;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return poll_status;
|
if (resetError) {
|
||||||
|
pC_->getMsgPrintControl().resetCount(keyError, pC_->asynUserSelf());
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus turboPmacAxis::doMove(double position, int relative,
|
asynStatus turboPmacAxis::doMove(double position, int relative,
|
||||||
@ -1042,7 +1027,7 @@ asynStatus turboPmacAxis::stop(double acceleration) {
|
|||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus turboPmacAxis::reset() {
|
asynStatus turboPmacAxis::doReset() {
|
||||||
|
|
||||||
// Status of read-write-operations of ASCII commands to the controller
|
// Status of read-write-operations of ASCII commands to the controller
|
||||||
asynStatus rw_status = asynSuccess;
|
asynStatus rw_status = asynSuccess;
|
||||||
@ -1160,16 +1145,16 @@ asynStatus turboPmacAxis::readEncoderType() {
|
|||||||
|
|
||||||
int reponse_length = strlen(response);
|
int reponse_length = strlen(response);
|
||||||
if (reponse_length < 3) {
|
if (reponse_length < 3) {
|
||||||
return pC_->errMsgCouldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are only interested in the last two digits and the last value in
|
// We are only interested in the last two digits and the last value in
|
||||||
// the string before the terminator is \r
|
// the string before the terminator is \r
|
||||||
nvals = sscanf(response + (reponse_length - 3), "%2X", &encoder_id);
|
nvals = sscanf(response + (reponse_length - 3), "%2X", &encoder_id);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(command, sizeof(command), "P46");
|
snprintf(command, sizeof(command), "P46");
|
||||||
@ -1299,7 +1284,10 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
bool moving = false;
|
bool moving = false;
|
||||||
doPoll(&moving);
|
rw_status = doPoll(&moving);
|
||||||
|
if (rw_status != asynSuccess) {
|
||||||
|
return rw_status;
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@ -1380,8 +1368,8 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%d", &axisStatus_);
|
nvals = sscanf(response, "%d", &axisStatus_);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
command, response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((axisStatus_ != -3) == on) {
|
if ((axisStatus_ != -3) == on) {
|
||||||
|
@ -82,12 +82,12 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
asynStatus init();
|
asynStatus init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset the axis error
|
* @brief Implementation of the `doReset` function from sinqAxis.
|
||||||
*
|
*
|
||||||
* @param on
|
* @param on
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus reset();
|
asynStatus doReset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable / disable the axis.
|
* @brief Enable / disable the axis.
|
||||||
@ -112,6 +112,16 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
*/
|
*/
|
||||||
asynStatus rereadEncoder();
|
asynStatus rereadEncoder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Interpret the error code and populate the user message accordingly
|
||||||
|
*
|
||||||
|
* @param error
|
||||||
|
* @param userMessage
|
||||||
|
* @param sizeUserMessage
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
asynStatus handleError(int error, char *userMessage, int sizeUserMessage);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
turboPmacController *pC_;
|
turboPmacController *pC_;
|
||||||
|
|
||||||
|
@ -484,23 +484,14 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus turboPmacController::readInt32(asynUser *pasynUser,
|
asynStatus turboPmacController::couldNotParseResponse(const char *command,
|
||||||
epicsInt32 *value) {
|
const char *response,
|
||||||
// PMACs can be disabled
|
int axisNo,
|
||||||
if (pasynUser->reason == motorCanDisable_) {
|
const char *functionName,
|
||||||
*value = 1;
|
int lineNumber) {
|
||||||
return asynSuccess;
|
|
||||||
} else {
|
|
||||||
return sinqController::readInt32(pasynUser, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asynStatus turboPmacController::errMsgCouldNotParseResponse(
|
|
||||||
const char *command, const char *response, int axisNo,
|
|
||||||
const char *functionName, int lineNumber) {
|
|
||||||
char modifiedResponse[MAXBUF_] = {0};
|
char modifiedResponse[MAXBUF_] = {0};
|
||||||
adjustResponseForPrint(modifiedResponse, response, MAXBUF_);
|
adjustResponseForPrint(modifiedResponse, response, MAXBUF_);
|
||||||
return sinqController::errMsgCouldNotParseResponse(
|
return sinqController::couldNotParseResponse(
|
||||||
command, modifiedResponse, axisNo, functionName, lineNumber);
|
command, modifiedResponse, axisNo, functionName, lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,17 +51,6 @@ class turboPmacController : public sinqController {
|
|||||||
*/
|
*/
|
||||||
turboPmacAxis *getTurboPmacAxis(int axisNo);
|
turboPmacAxis *getTurboPmacAxis(int axisNo);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Overloaded function of sinqController
|
|
||||||
*
|
|
||||||
* The function is overloaded in order to read motorCanDisable_.
|
|
||||||
*
|
|
||||||
* @param pasynUser
|
|
||||||
* @param value
|
|
||||||
* @return asynStatus
|
|
||||||
*/
|
|
||||||
virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Overloaded function of sinqController
|
* @brief Overloaded function of sinqController
|
||||||
*
|
*
|
||||||
@ -93,13 +82,13 @@ class turboPmacController : public sinqController {
|
|||||||
int numExpectedResponses);
|
int numExpectedResponses);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Specialized version of sinqController::errMsgCouldNotParseResponse
|
* @brief Specialized version of sinqController::couldNotParseResponse
|
||||||
* for turboPmac
|
* for turboPmac
|
||||||
*
|
*
|
||||||
* This is an overloaded version of
|
* This is an overloaded version of
|
||||||
* sinqController::errMsgCouldNotParseResponse which calls
|
* sinqController::couldNotParseResponse which calls
|
||||||
* adjustResponseForLogging on response before handing it over to
|
* adjustResponseForLogging on response before handing it over to
|
||||||
* sinqController::errMsgCouldNotParseResponse.
|
* sinqController::couldNotParseResponse.
|
||||||
*
|
*
|
||||||
* @param command Command which led to the unparseable message
|
* @param command Command which led to the unparseable message
|
||||||
* @param response Response which wasn't parseable
|
* @param response Response which wasn't parseable
|
||||||
@ -110,10 +99,9 @@ class turboPmacController : public sinqController {
|
|||||||
called. It is recommended to use a macro, e.g. __LINE__.
|
called. It is recommended to use a macro, e.g. __LINE__.
|
||||||
* @return asynStatus Returns asynError.
|
* @return asynStatus Returns asynError.
|
||||||
*/
|
*/
|
||||||
asynStatus errMsgCouldNotParseResponse(const char *command,
|
asynStatus couldNotParseResponse(const char *command, const char *response,
|
||||||
const char *response, int axisNo_,
|
int axisNo_, const char *functionName,
|
||||||
const char *functionName,
|
int lineNumber);
|
||||||
int lineNumber);
|
|
||||||
|
|
||||||
// Accessors for additional PVs
|
// Accessors for additional PVs
|
||||||
int rereadEncoderPosition() { return rereadEncoderPosition_; }
|
int rereadEncoderPosition() { return rereadEncoderPosition_; }
|
||||||
|
Reference in New Issue
Block a user