Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
d6adf1ad2a | |||
dfb55a1b76 | |||
8f597550fa |
2
Makefile
2
Makefile
@ -14,7 +14,7 @@ REQUIRED+=sinqMotor
|
||||
motorBase_VERSION=7.2.2
|
||||
|
||||
# Specify the version of sinqMotor we want to build against
|
||||
sinqMotor_VERSION=0.7.0
|
||||
sinqMotor_VERSION=0.8.0
|
||||
|
||||
# These headers allow to depend on this library for derived drivers.
|
||||
HEADERS += src/turboPmacAxis.h
|
||||
|
52
README.md
52
README.md
@ -17,25 +17,45 @@ The folder "utils" contains utility scripts for working with pmac motor controll
|
||||
|
||||
### Usage in IOC shell
|
||||
|
||||
turboPmac exposes the following IOC shell functions (all in turboPmacController.cpp):
|
||||
turboPmac exports the following IOC shell functions:
|
||||
- `turboPmacController`: Create a new controller object.
|
||||
- `turboPmacAxis`: Create a new axis object.
|
||||
These functions are parametrized as follows:
|
||||
|
||||
The full mcu.cmd file looks like this:
|
||||
|
||||
```
|
||||
turboPmacController(
|
||||
"$(NAME)", # Name of the MCU, e.g. mcu1. This parameter should be provided by an environment variable.
|
||||
"$(ASYN_PORT)", # IP-Port of the MCU. This parameter should be provided by an environment variable.
|
||||
8, # Maximum number of axes
|
||||
0.05, # Busy poll period in seconds
|
||||
1, # Idle poll period in seconds
|
||||
0.05 # Communication timeout in seconds
|
||||
);
|
||||
```
|
||||
```
|
||||
turboPmacAxis(
|
||||
"$(NAME)", # Name of the associated MCU, e.g. mcu1. This parameter should be provided by an environment variable.
|
||||
1 # Index of the axis.
|
||||
);
|
||||
# Define the name of the controller and the corresponding port
|
||||
epicsEnvSet("NAME","mcu")
|
||||
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
|
||||
drvAsynIPPortConfigure("$(ASYN_PORT)","172.28.101.24:1025")
|
||||
|
||||
# Create the controller object with the defined name and connect it to the socket via the port name.
|
||||
# The other parameters are as follows:
|
||||
# 8: Maximum number of axes
|
||||
# 0.05: Busy poll period in seconds
|
||||
# 1: Idle poll period in seconds
|
||||
# 1: Socket communication timeout in seconds
|
||||
turboPmacController("$(NAME)", "$(ASYN_PORT)", 8, 0.05, 1, 1);
|
||||
|
||||
# Define some axes for the specified MCU at the given slot (1, 2 and 5). No slot may be used twice!
|
||||
turboPmacAxis("$(NAME)",1);
|
||||
turboPmacAxis("$(NAME)",2);
|
||||
turboPmacAxis("$(NAME)",5);
|
||||
|
||||
# Set the number of subsequent timeouts
|
||||
setMaxSubsequentTimeouts("$(NAME)", 20);
|
||||
|
||||
# Configure the timeout frequency watchdog:
|
||||
setThresholdComTimeout("$(NAME)", 100, 1);
|
||||
|
||||
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
||||
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
|
||||
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
||||
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
|
||||
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
||||
dbLoadRecords("$(sinqMotor_DB)/asynRecord.db","P=$(INSTR)$(NAME),PORT=$(ASYN_PORT)")
|
||||
```
|
||||
|
||||
### Versioning
|
||||
|
@ -35,7 +35,8 @@ static void epicsInithookFunction(initHookState iState) {
|
||||
}
|
||||
}
|
||||
|
||||
turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo)
|
||||
turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
||||
bool initialize)
|
||||
: sinqAxis(pC, axisNo), pC_(pC) {
|
||||
|
||||
asynStatus status = asynSuccess;
|
||||
@ -63,13 +64,17 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Register the hook function during construction of the first axis object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
if (initialize) {
|
||||
// Register the hook function during construction of the first axis
|
||||
// object
|
||||
if (axes.empty()) {
|
||||
initHookRegister(&epicsInithookFunction);
|
||||
}
|
||||
|
||||
// Collect all axes into this list which will be used in the hook function
|
||||
axes.push_back(this);
|
||||
// Collect all axes into this list which will be used in the hook
|
||||
// function
|
||||
axes.push_back(this);
|
||||
}
|
||||
|
||||
// Initialize all member variables
|
||||
waitForHandshake_ = false;
|
||||
@ -109,9 +114,6 @@ turboPmacAxis::~turboPmacAxis(void) {
|
||||
// clean up the pointer pC here.
|
||||
}
|
||||
|
||||
/**
|
||||
Read the configuration at the first poll
|
||||
*/
|
||||
asynStatus turboPmacAxis::init() {
|
||||
|
||||
// Local variable declaration
|
||||
@ -363,39 +365,43 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
__PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// Intepret the status
|
||||
// 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;
|
||||
|
||||
// Interpret the status
|
||||
switch (axStatus) {
|
||||
case -6:
|
||||
// Axis is stopping
|
||||
*moving = true;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is stopping\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case -5:
|
||||
// Axis is deactivated
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is "
|
||||
"deactivated\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Deactivated");
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
__LINE__);
|
||||
}
|
||||
|
||||
break;
|
||||
case -4:
|
||||
// Emergency stop
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||
"activated\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nEmergency stop "
|
||||
"activated.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetCountStatus = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Emergency stop");
|
||||
if (pl_status != asynSuccess) {
|
||||
@ -406,13 +412,9 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
break;
|
||||
case -3:
|
||||
// Disabled
|
||||
*moving = false;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis %d is disabled\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_);
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_, "Disabled");
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||
@ -422,43 +424,24 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
break;
|
||||
case 0:
|
||||
// Idle
|
||||
*moving = false;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is idle\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 1:
|
||||
// Move order acknowledged
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove order "
|
||||
"acknowledged\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 2:
|
||||
// Move order confirmed possible
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove order is "
|
||||
"possible\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 3:
|
||||
// Axis in Air Cushion Output status
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis in Air "
|
||||
"Cushion Output status\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 4:
|
||||
// Axis in Air Cushion Input status
|
||||
*moving = true;
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis in Air "
|
||||
"Cushion Input status\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
break;
|
||||
case 5:
|
||||
*moving = true;
|
||||
@ -472,15 +455,22 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
default:
|
||||
*moving = false;
|
||||
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nReached unreachable "
|
||||
"state P%2.2d00 = %d\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
axStatus);
|
||||
pl_status = setStringParam(
|
||||
pC_->motorMessageText_,
|
||||
"Unreachable state has been reached. Please call the support.");
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nReached "
|
||||
"unreachable state P%2.2d00 = %d.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, axStatus, pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetCountStatus = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Unknown state P%2.2d00 = %d has been reached. 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__,
|
||||
@ -488,6 +478,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
}
|
||||
|
||||
if (resetCountStatus) {
|
||||
pC_->msgPrintControl_.resetCount(keyStatus);
|
||||
}
|
||||
|
||||
if (*moving) {
|
||||
// If the axis is moving, evaluate the movement direction
|
||||
if ((currentPosition - previousPosition) > 0) {
|
||||
@ -497,19 +491,28 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
}
|
||||
|
||||
// Error handling
|
||||
// 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
|
||||
// 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
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTarget position would "
|
||||
"exceed user limits.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, 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_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_,
|
||||
"Target position would exceed software "
|
||||
@ -524,11 +527,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
case 5:
|
||||
// Command not possible
|
||||
asynPrint(pC_->pasynUserSelf, 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.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyStatus, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, 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_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
pl_status = setStringParam(pC_->motorMessageText_,
|
||||
"Axis received move command while it is "
|
||||
@ -542,12 +551,15 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
poll_status = asynError;
|
||||
break;
|
||||
case 8:
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAir cushion feedback "
|
||||
"stopped during movement (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, 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_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Air cushion feedback stopped during movement (P%2.2d01 = "
|
||||
@ -562,11 +574,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
|
||||
"feedback before movement start (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error);
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, 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_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"No air cushion feedback before movement start (P%2.2d01 = "
|
||||
@ -586,10 +603,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
error case can only happen if either the axis has an incremental encoder
|
||||
which is not properly homed or if a bug occured.
|
||||
*/
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
||||
"controller limits.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis hit the "
|
||||
"controller limits.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(userMessage, sizeof(userMessage),
|
||||
"Software limits or end switch hit (P%2.2d01 = %d). Try "
|
||||
@ -609,10 +633,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
case 11:
|
||||
// Following error
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||
"following error exceeded.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMaximum allowed "
|
||||
"following error exceeded.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"Maximum allowed following error exceeded (P%2.2d01 = %d). "
|
||||
@ -630,6 +661,16 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, 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_->msgPrintControl_.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 "
|
||||
@ -647,11 +688,17 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
|
||||
case 13:
|
||||
// Driver hardware error triggered
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDriver hardware error "
|
||||
"triggered.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDriver "
|
||||
"hardware error triggered.%s\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
pC_->msgPrintControl_.getSuffix());
|
||||
}
|
||||
resetError = false;
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"Driver hardware error (P%2.2d01 = 13). "
|
||||
"Please call the support.",
|
||||
@ -668,18 +715,22 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
case 14:
|
||||
// EPICS should already prevent this issue in the first place,
|
||||
// since it contains the user limits
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMove command exceeds "
|
||||
"hardware limits (P%2.2d01 = %d).\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
|
||||
error);
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(pC_->pasynUserSelf, 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_->msgPrintControl_.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_, command);
|
||||
pl_status = setStringParam(pC_->motorMessageText_, userMessage);
|
||||
if (pl_status != asynSuccess) {
|
||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||
axisNo_, __PRETTY_FUNCTION__,
|
||||
@ -689,15 +740,22 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
poll_status = asynError;
|
||||
break;
|
||||
default:
|
||||
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnknown error "
|
||||
"P%2.2d01 = %d.\n",
|
||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||
axisNo_, error);
|
||||
|
||||
pl_status = setStringParam(
|
||||
pC_->motorMessageText_,
|
||||
"Unknown error P%2.2d01 = %d. Please call the support.");
|
||||
if (pC_->msgPrintControl_.shouldBePrinted(keyError, true,
|
||||
pC_->pasynUserSelf)) {
|
||||
asynPrint(
|
||||
pC_->pasynUserSelf, 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_->msgPrintControl_.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__,
|
||||
@ -708,6 +766,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (resetError) {
|
||||
pC_->msgPrintControl_.resetCount(keyError);
|
||||
}
|
||||
|
||||
// Update the parameter library
|
||||
if (error != 0) {
|
||||
pl_status = setIntegerParam(pC_->motorStatusProblem_, true);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "sinqAxis.h"
|
||||
|
||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
||||
// between C804Controller.h and C804Axis.h. See
|
||||
// between the controller and the axis .h-file. See
|
||||
// https://en.cppreference.com/w/cpp/language/class.
|
||||
class turboPmacController;
|
||||
|
||||
@ -15,7 +15,8 @@ class turboPmacAxis : public sinqAxis {
|
||||
* @param pController Pointer to the associated controller
|
||||
* @param axisNo Index of the axis
|
||||
*/
|
||||
turboPmacAxis(turboPmacController *pController, int axisNo);
|
||||
turboPmacAxis(turboPmacController *pController, int axisNo,
|
||||
bool initialize = true);
|
||||
|
||||
/**
|
||||
* @brief Destroy the turboPmacAxis
|
||||
@ -74,7 +75,7 @@ class turboPmacAxis : public sinqAxis {
|
||||
* The following steps are performed:
|
||||
* - Read out the motor status, motor position, velocity and acceleration
|
||||
* from the MCU and store this information in the parameter library.
|
||||
* - Set the enable PV accordint to the initial status of the axis.
|
||||
* - Set the enable PV according to the initial status of the axis.
|
||||
*
|
||||
* @return asynStatus
|
||||
*/
|
||||
|
@ -29,23 +29,11 @@ void adjustResponseForPrint(char *dst, const char *src, size_t buf_length) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new turboPmacController::turboPmacController object
|
||||
*
|
||||
* @param portName See documentation of sinqController
|
||||
* @param ipPortConfigName See documentation of sinqController
|
||||
* @param numAxes See documentation of sinqController
|
||||
* @param movingPollPeriod See documentation of sinqController
|
||||
* @param idlePollPeriod See documentation of sinqController
|
||||
* @param comTimeout Time after which a communication timeout error
|
||||
* is declared in writeRead (in seconds)
|
||||
* @param extraParams See documentation of sinqController
|
||||
*/
|
||||
turboPmacController::turboPmacController(const char *portName,
|
||||
const char *ipPortConfigName,
|
||||
int numAxes, double movingPollPeriod,
|
||||
double idlePollPeriod,
|
||||
double comTimeout)
|
||||
double comTimeout, int numExtraParams)
|
||||
: sinqController(
|
||||
portName, ipPortConfigName, numAxes, movingPollPeriod, idlePollPeriod,
|
||||
/*
|
||||
@ -53,7 +41,7 @@ turboPmacController::turboPmacController(const char *portName,
|
||||
- REREAD_ENCODER_POSITION
|
||||
- READ_CONFIG
|
||||
*/
|
||||
NUM_turboPmac_DRIVER_PARAMS)
|
||||
numExtraParams + NUM_turboPmac_DRIVER_PARAMS)
|
||||
|
||||
{
|
||||
|
||||
@ -145,39 +133,18 @@ Access one of the axes of the controller via the axis adress stored in asynUser.
|
||||
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||
error is emitted.
|
||||
*/
|
||||
turboPmacAxis *turboPmacController::getAxis(asynUser *pasynUser) {
|
||||
turboPmacAxis *turboPmacController::getTurboPmacAxis(asynUser *pasynUser) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(pasynUser);
|
||||
return turboPmacController::castToAxis(asynAxis);
|
||||
return dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
/*
|
||||
Access one of the axes of the controller via the axis index.
|
||||
If the axis does not exist or is not a Axis, the function must return Null
|
||||
*/
|
||||
turboPmacAxis *turboPmacController::getAxis(int axisNo) {
|
||||
turboPmacAxis *turboPmacController::getTurboPmacAxis(int axisNo) {
|
||||
asynMotorAxis *asynAxis = asynMotorController::getAxis(axisNo);
|
||||
return turboPmacController::castToAxis(asynAxis);
|
||||
}
|
||||
|
||||
turboPmacAxis *turboPmacController::castToAxis(asynMotorAxis *asynAxis) {
|
||||
|
||||
// =========================================================================
|
||||
|
||||
// If the axis slot of the pAxes_ array is empty, a nullptr must be returned
|
||||
if (asynAxis == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Here, an error is emitted since asyn_axis is not a nullptr but also not
|
||||
// an instance of Axis
|
||||
turboPmacAxis *axis = dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
if (axis == nullptr) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nAxis is not "
|
||||
"an instance of turboPmacAxis",
|
||||
portName, axis->axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
||||
}
|
||||
return axis;
|
||||
return dynamic_cast<turboPmacAxis *>(asynAxis);
|
||||
}
|
||||
|
||||
asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
@ -216,7 +183,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
|
||||
// =========================================================================
|
||||
|
||||
turboPmacAxis *axis = getAxis(axisNo);
|
||||
turboPmacAxis *axis = getTurboPmacAxis(axisNo);
|
||||
if (axis == nullptr) {
|
||||
// We already did the error logging directly in getAxis
|
||||
return asynError;
|
||||
@ -273,10 +240,6 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
// +1 for the carriage return.
|
||||
const size_t fullComandLength = offset + commandLength + 1;
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nSending command %s",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, fullCommand);
|
||||
|
||||
/*
|
||||
We use separated write and read commands here, not the combined writeRead
|
||||
method, because the latter is actually a flushWriteRead (see
|
||||
@ -294,12 +257,19 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
status = pasynOctetSyncIO->write(lowLevelPortUser_, fullCommand,
|
||||
fullComandLength, comTimeout_, &nbytesOut);
|
||||
|
||||
msgPrintControlKey writeKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (status == asynTimeout) {
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"writing to the MCU\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (msgPrintControl_.shouldBePrinted(writeKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"writing to the MCU.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||
sizeof(drvMessageText));
|
||||
@ -321,23 +291,35 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
}
|
||||
} else if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"writing to the controller\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
if (msgPrintControl_.shouldBePrinted(writeKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"writing to the controller.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status), msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(writeKey);
|
||||
}
|
||||
|
||||
// Read the response from the MCU buffer
|
||||
status = pasynOctetSyncIO->read(lowLevelPortUser_, response, MAXBUF_,
|
||||
comTimeout_, &nbytesIn, &eomReason);
|
||||
|
||||
msgPrintControlKey readKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
|
||||
if (status == asynTimeout) {
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"reading from the MCU\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (msgPrintControl_.shouldBePrinted(readKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||
"reading from the MCU.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
// Add this event to the back of the timeout event counter
|
||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||
@ -360,11 +342,16 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
}
|
||||
} else if (status != asynSuccess) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"reading from the controller\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status));
|
||||
if (msgPrintControl_.shouldBePrinted(readKey, true, pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||
"reading from the controller.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
stringifyAsynStatus(status), msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(readKey);
|
||||
}
|
||||
|
||||
if (timeoutStatus == asynError) {
|
||||
@ -372,6 +359,8 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
}
|
||||
|
||||
// The message should only ever terminate due to reason 2
|
||||
msgPrintControlKey terminateKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (eomReason != 2) {
|
||||
status = asynError;
|
||||
|
||||
@ -379,10 +368,16 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
"Terminated message due to reason %d (should be 2).",
|
||||
eomReason);
|
||||
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||
"terminated due to reason %i\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, eomReason);
|
||||
if (msgPrintControl_.shouldBePrinted(terminateKey, true,
|
||||
pasynUserSelf)) {
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||
"terminated due to reason %i.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||
eomReason, msgPrintControl_.getSuffix());
|
||||
}
|
||||
} else {
|
||||
msgPrintControl_.resetCount(terminateKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -394,20 +389,30 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
numReceivedResponses++;
|
||||
}
|
||||
}
|
||||
msgPrintControlKey numResponsesKey =
|
||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||
if (numExpectedResponses != numReceivedResponses) {
|
||||
adjustResponseForPrint(modResponse, response, MAXBUF_);
|
||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
||||
"response '%s' (carriage returns are replaced with spaces) "
|
||||
"for command %s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
||||
command);
|
||||
|
||||
if (msgPrintControl_.shouldBePrinted(numResponsesKey, true,
|
||||
pasynUserSelf)) {
|
||||
asynPrint(
|
||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
||||
"response '%s' (carriage returns are replaced with spaces) "
|
||||
"for command %s.%s\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
||||
command, msgPrintControl_.getSuffix());
|
||||
}
|
||||
|
||||
snprintf(drvMessageText, sizeof(drvMessageText),
|
||||
"Received unexpected response '%s' (carriage returns "
|
||||
"are replaced with spaces) for command %s. "
|
||||
"Please call the support",
|
||||
modResponse, command);
|
||||
status = asynError;
|
||||
} else {
|
||||
msgPrintControl_.resetCount(numResponsesKey);
|
||||
}
|
||||
|
||||
// Create custom error messages for different failure modes, if no error
|
||||
@ -437,23 +442,12 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
||||
|
||||
// Log the overall status (communication successfull or not)
|
||||
if (status == asynSuccess) {
|
||||
|
||||
asynPrint(lowLevelPortUser_, ASYN_TRACEIO_DRIVER,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nDevice "
|
||||
"response: %s (carriage returns are replaced with spaces)\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse);
|
||||
paramLibStatus = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
||||
} else {
|
||||
asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR,
|
||||
"Controller \"%s\", axis %d => %s, line %d\nCommunication "
|
||||
"failed for command %s (%s)\n",
|
||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, fullCommand,
|
||||
stringifyAsynStatus(status));
|
||||
|
||||
// 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
|
||||
// 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
|
||||
paramLibStatus =
|
||||
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
||||
if (paramLibStatus != asynSuccess) {
|
||||
@ -494,11 +488,7 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
|
||||
|
||||
// =====================================================================
|
||||
|
||||
turboPmacAxis *axis = getAxis(pasynUser);
|
||||
if (axis == nullptr) {
|
||||
// We already did the error logging directly in getAxis
|
||||
return asynError;
|
||||
}
|
||||
turboPmacAxis *axis = getTurboPmacAxis(pasynUser);
|
||||
|
||||
// Handle custom PVs
|
||||
if (function == rereadEncoderPosition_) {
|
||||
@ -510,13 +500,14 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
|
||||
}
|
||||
}
|
||||
|
||||
asynStatus sinqController::readInt32(asynUser *pasynUser, epicsInt32 *value) {
|
||||
asynStatus turboPmacController::readInt32(asynUser *pasynUser,
|
||||
epicsInt32 *value) {
|
||||
// PMACs can be disabled
|
||||
if (pasynUser->reason == motorCanDisable_) {
|
||||
*value = 1;
|
||||
return asynSuccess;
|
||||
} else {
|
||||
return asynMotorController::readInt32(pasynUser, value);
|
||||
return sinqController::readInt32(pasynUser, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,8 +540,8 @@ asynStatus turboPmacCreateController(const char *portName,
|
||||
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"
|
||||
@ -582,17 +573,17 @@ static const iocshArg CreateControllerArg5 = {"Communication timeout (s)",
|
||||
static const iocshArg *const CreateControllerArgs[] = {
|
||||
&CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2,
|
||||
&CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5};
|
||||
static const iocshFuncDef configturboPmacCreateController = {
|
||||
static const iocshFuncDef configTurboPmacCreateController = {
|
||||
"turboPmacController", 6, CreateControllerArgs};
|
||||
static void configTurboPmacCreateControllerCallFunc(const iocshArgBuf *args) {
|
||||
turboPmacCreateController(args[0].sval, args[1].sval, args[2].ival,
|
||||
args[3].dval, args[4].dval, args[5].dval);
|
||||
}
|
||||
|
||||
// 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 turboPmacControllerRegister(void) {
|
||||
iocshRegister(&configturboPmacCreateController,
|
||||
iocshRegister(&configTurboPmacCreateController,
|
||||
configTurboPmacCreateControllerCallFunc);
|
||||
}
|
||||
epicsExportRegistrar(turboPmacControllerRegister);
|
||||
|
@ -13,10 +13,10 @@
|
||||
#include "turboPmacAxis.h"
|
||||
|
||||
class turboPmacController : public sinqController {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new turboPmacController object
|
||||
* @brief Construct a new turboPmacController object. This function is meant
|
||||
to be called from a child class constructor.
|
||||
*
|
||||
* @param portName See sinqController constructor
|
||||
* @param ipPortConfigName See sinqController constructor
|
||||
@ -26,10 +26,12 @@ class turboPmacController : public sinqController {
|
||||
* @param comTimeout When trying to communicate with the device,
|
||||
the underlying asynOctetSyncIO interface waits for a response until this
|
||||
time (in seconds) has passed, then it declares a timeout.
|
||||
* @param numExtraParams Number of extra parameters from a child class
|
||||
*/
|
||||
turboPmacController(const char *portName, const char *ipPortConfigName,
|
||||
int numAxes, double movingPollPeriod,
|
||||
double idlePollPeriod, double comTimeout);
|
||||
double idlePollPeriod, double comTimeout,
|
||||
int numExtraParams = 0);
|
||||
|
||||
/**
|
||||
* @brief Get the axis object
|
||||
@ -38,7 +40,7 @@ class turboPmacController : public sinqController {
|
||||
* @return turboPmacAxis* If no axis could be found, this is a
|
||||
* nullptr
|
||||
*/
|
||||
turboPmacAxis *getAxis(asynUser *pasynUser);
|
||||
turboPmacAxis *getTurboPmacAxis(asynUser *pasynUser);
|
||||
|
||||
/**
|
||||
* @brief Get the axis object
|
||||
@ -47,7 +49,18 @@ class turboPmacController : public sinqController {
|
||||
* @return turboPmacAxis* If no axis could be found, this is a
|
||||
* nullptr
|
||||
*/
|
||||
turboPmacAxis *getAxis(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
|
||||
@ -58,7 +71,7 @@ class turboPmacController : public sinqController {
|
||||
* @param value New value
|
||||
* @return asynStatus
|
||||
*/
|
||||
asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
|
||||
|
||||
protected:
|
||||
asynUser *lowLevelPortUser_;
|
||||
@ -82,15 +95,6 @@ class turboPmacController : public sinqController {
|
||||
asynStatus writeRead(int axisNo, const char *command, char *response,
|
||||
int numExpectedResponses);
|
||||
|
||||
/**
|
||||
* @brief Save cast of the given asynAxis pointer to a turboPmacAxis
|
||||
* pointer. If the cast fails, this function returns a nullptr.
|
||||
*
|
||||
* @param asynAxis
|
||||
* @return turboPmacAxis*
|
||||
*/
|
||||
turboPmacAxis *castToAxis(asynMotorAxis *asynAxis);
|
||||
|
||||
/**
|
||||
* @brief Specialized version of sinqController::errMsgCouldNotParseResponse
|
||||
* for turboPmac
|
||||
@ -114,7 +118,7 @@ class turboPmacController : public sinqController {
|
||||
const char *functionName,
|
||||
int lineNumber);
|
||||
|
||||
private:
|
||||
protected:
|
||||
// Set the maximum buffer size. This is an empirical value which must be
|
||||
// large enough to avoid overflows for all commands to the device /
|
||||
// responses from it.
|
||||
|
Reference in New Issue
Block a user