Compare commits

..

24 Commits
1.6.1 ... 1.0.1

Author SHA1 Message Date
e316fcf67b Changed priority of IOC shell message 2025-06-06 11:20:50 +02:00
6cf00adb60 Ready for release 1.0 2025-05-23 12:27:31 +02:00
9710d442b8 Removed exit(-1) from init
When the initialization fails, the motor will now try again during each
poll.
2025-05-23 11:56:45 +02:00
8dd1dc4af2 Fixed poller bug in sinqMotor 2025-05-23 11:20:20 +02:00
a758db1211 Change to latest sinqMotor version 2025-05-23 10:11:27 +02:00
a11d10cb6c Updated sinqMotor to 0.15.2 2025-05-16 16:03:30 +02:00
ba353c4e5d Fixed remote git link in repo. 2025-05-16 15:58:17 +02:00
55b523ddaa Made some functions virtual so they can be overwritten in subclasses 2025-05-15 14:54:18 +02:00
75292a6a9c Fixed some merge bugs 2025-05-15 12:32:30 +02:00
53bbe2aae8 Merge branch 'static-dep' 2025-05-15 12:27:26 +02:00
1597dc34e0 Added default value for motorMessageText 2025-05-15 12:25:08 +02:00
dde7066f40 Use latest version of sinqMotor 2025-05-15 11:41:53 +02:00
b4d6447b32 Fixed serious bug in sinqMotor 2025-05-15 11:29:13 +02:00
2f83060ec1 Addes error message for failing to enable / disable within timeout 2025-05-14 16:26:55 +02:00
a3e3a79788 Adjusted usage of motorMessageText to act as an error message only. 2025-05-14 16:17:14 +02:00
2c5fdc7d0a Use new version of sinqMotor 2025-05-14 16:13:10 +02:00
7bf31ac256 Allow enabling / disabling the motor regardless of the status returned by the poll 2025-05-13 14:44:24 +02:00
47e72d65a9 Fixed small inaccuracy in the README 2025-05-12 17:04:09 +02:00
5298b5ef69 Fixed typo 2025-05-12 16:59:59 +02:00
29f23216ad Added some comments that this library now uses sinqMotor as static
dependency.
2025-05-12 16:43:57 +02:00
26bc3df876 Fixed bug where the motor could be in state -6 and the driver would
interpret this as "not moving"
2025-05-12 16:19:34 +02:00
87d3cbb3eb Specified new version for sinqMotor 2025-05-12 12:00:49 +02:00
66552d5ffc Pinned sinqMotor version 2025-05-12 11:58:56 +02:00
253f65b25b Added sinqMotor as a submodule for static linking 2025-05-12 08:52:10 +02:00
15 changed files with 748 additions and 631 deletions

View File

@@ -1,24 +0,0 @@
name: Test And Build
on: [push]
jobs:
Lint:
runs-on: linepics
steps:
- name: checkout repo
uses: actions/checkout@v4
- name: cppcheck
run: cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
- name: formatting
run: clang-format --style=file --Werror --dry-run src/*.cpp
Build:
runs-on: linepics
steps:
- name: checkout repo
uses: actions/checkout@v4
with:
submodules: 'true'
- run: |
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
echo -e "\nIGNORE_SUBMODULES += sinqmotor" >> Makefile
make install

8
.gitignore vendored
View File

@@ -1,8 +0,0 @@
O.*
.cvsignore
.vscode
src/.vscode
utils/analyzeTcpDump/__pycache__
utils/analyzeTcpDump/demo.pcap.json
utils/analyzeTcpDump/demovenv
utils/analyzeTcpDump/venv

58
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,58 @@
default:
image: docker.psi.ch:5000/sinqdev/sinqepics:latest
stages:
- lint
- build
- test
cppcheck:
stage: lint
script:
- cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
artifacts:
expire_in: 1 week
tags:
- sinq
formatting:
stage: lint
script:
- clang-format --style=file --Werror --dry-run src/*.cpp
artifacts:
expire_in: 1 week
tags:
- sinq
# clangtidy:
# stage: lint
# script:
# - curl https://docker.psi.ch:5000/v2/_catalog
# # - dnf update -y
# # - dnf install -y clang-tools-extra
# # - clang-tidy sinqEPICSApp/src/*.cpp sinqEPICSApp/src/*.c sinqEPICSApp/src/*.h -checks=cppcoreguidelines-*,cert-*
# # tags:
# # - sinq
build_module:
stage: build
script:
- export SINQMOTOR_VERSION="$(grep 'sinqMotor_VERSION=' Makefile | cut -d= -f2)"
- git clone --depth 1 --branch "${SINQMOTOR_VERSION}" https://gitlab-ci-token:${CI_JOB_TOKEN}@git.psi.ch/sinq-epics-modules/sinqmotor.git
- pushd sinqmotor
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
- echo "LIBVERSION=${SINQMOTOR_VERSION}" >> Makefile
- make install
- popd
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
- echo "LIBVERSION=${CI_COMMIT_TAG:-0.0.1}" >> Makefile
- make install
- cp -rT "/ioc/modules/turboPmac/$(ls -U /ioc/modules/turboPmac/ | head -1)" "./turboPmac-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
artifacts:
name: "turboPmac-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
paths:
- "turboPmac-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}/*"
expire_in: 1 week
when: always
tags:
- sinq

3
.gitmodules vendored
View File

@@ -1,3 +1,6 @@
[submodule "sinqmotor"]
path = sinqmotor
url = https://gitea.psi.ch/lin-epics-modules/sinqmotor
[submodule "sinqMotor"]
path = sinqMotor
url = https://gitea.psi.ch/lin-epics-modules/sinqMotor

View File

@@ -34,5 +34,4 @@ TEMPLATES += db/turboPmac.db
DBDS += sinqMotor/src/sinqMotor.dbd
DBDS += src/turboPmac.dbd
USR_CFLAGS += -Wall -Wextra -Wunused-result -Werror -fvisibility=hidden # -Wpedantic // Does not work because EPICS macros trigger warnings
USR_CXXFLAGS += -Wall -Wextra -Wunused-result -Werror -fvisibility=hidden
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings

View File

@@ -1,29 +1,18 @@
# turboPmac
## <span style="color:red">Please read the documentation of sinqMotor first: https://gitea.psi.ch/lin-epics-modules/sinqMotor</span>
## <span style="color:red">Please read the documentation of sinqMotor first: https://git.psi.ch/sinq-epics-modules/sinqmotor</span>
## 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://gitea.psi.ch/lin-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://gitea.psi.ch/lin-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.
## User guide
This driver is a standard sinqMotor-derived which however uses a special low
level IP Port driver (`pmacAsynIPPortConfigure`) instead of the standard
`drvAsynIPPortConfigure`. For the general configuration, please see
https://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/main/README.md.
This driver is a standard sinqMotor-derived which however uses a special low level IP Port driver (`pmacAsynIPPortConfigure`) instead of the standard `drvAsynIPPortConfigure`. For the general configuration, please see https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md.
The folder "utils" contains utility scripts for working with pmac motor
controllers. To read their manual, run the scripts without any arguments.
- writeRead.py: Allows sending commands to and receiving commands from a pmac
controller over an ethernet connection.
- analyzeTcpDump.py: Parse the TCP communication between an IOC and a MCU and
format it into a dictionary. "demo.py" shows how this data can be easily
visualized for analysis.
The folder "utils" contains utility scripts for working with pmac motor controllers. To read their manual, run the scripts without any arguments.
- writeRead.py: Allows sending commands to and receiving commands from a pmac controller over an ethernet connection.
- analyzeTcpDump.py: Parse the TCP communication between an IOC and a MCU and format it into a dictionary. "demo.py" shows how this data can be easily visualized for analysis.
### IOC startup script
@@ -33,15 +22,13 @@ turboPmac exports the following IOC shell functions:
The full turboPmacX.cmd file looks like this:
```bash
```
# Define the name of the controller and the corresponding port
epicsEnvSet("DRIVER_PORT","turboPmacX")
epicsEnvSet("IP_PORT","p$(DRIVER_PORT)")
# 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.
# We do not use the standard asyn port driver here, but a PMAC-specific one
# which enables the usage of StreamDevices for
# 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.
# We do not use the standard asyn port driver here, but a PMAC-specific one which enables the usage of StreamDevices for
# communicating with the controller directly.
pmacAsynIPPortConfigure("$(IP_PORT)","172.28.101.24:1025")
@@ -61,8 +48,7 @@ turboPmacAxis("$(DRIVER_PORT)",5);
# Set the number of subsequent timeouts
setMaxSubsequentTimeouts("$(DRIVER_PORT)", 20);
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed
# in 300 seconds before an alarm message is sent.
# Configure the timeout frequency watchdog: A maximum of 10 timeouts are allowed in 300 seconds before an alarm message is sent.
setThresholdComTimeout("$(DRIVER_PORT)", 300, 10);
# Parametrize the EPICS record database with the substitution file named after the MCU.
@@ -75,58 +61,14 @@ dbLoadRecords("$(turboPmac_DB)/asynRecord.db","P=$(INSTR)$(DRIVER_PORT),PORT=$(I
### Additional records
`turboPmac` provides a variety of additional records. See `db/turboPmac.db` for
the complete list and the documentation.
`turboPmac` provides a variety of additional records. See `db/turboPmac.db` for the complete list and the documentation.
## Developer guide
### Versioning
Please see the documentation for the module sinqMotor:
https://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/main/README.md.
Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md.
### How to build it
This driver can be compiled and installed by running `make install` from the
same directory where the Makefile is located. However, since it uses the git
submodule sinqMotor, make sure that the correct version of the submodule
repository is checked out AND the change is commited (`git status` shows no
non-committed changes). Please see the section "Usage as static dependency" in
https://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/main/README.md for
more details.
## FAQ
### Axis hardware error at startup
If at IOC startup you are met with the following errors:
```
2026/02/02 16:56:49.470 Controller "turboPmac1", axis 3 => asynStatus turboPmacAxis::handleError(int, char*, int), line 735
Driver hardware error triggered.
2026/02/02 16:56:49.485 Controller "turboPmac1", axis 7 => asynStatus turboPmacAxis::handleError(int, char*, int), line 735
Driver hardware error triggered.
2026/02/02 16:56:49.492 Controller "turboPmac1", axis 8 => asynStatus turboPmacAxis::handleError(int, char*, int), line 735
Driver hardware error triggered.
```
You may need to reset to do a axis reset. This can be done with
`utils/writeRead.py`. The following example does so for axis 3.
Confirm the hardware error:
```
utils/writeRead.py 172.28.87.24:1025 P0301 # 03 specifies axis 3, 01 is the command to read out the error.
# If it returns 13 it's a hardware error.
# For the full list of errors see TurboPMAC_manual.pdf or src/turboPmacAxis.cpp, function "handleError".
```
Reset the axis:
```
utils/writeRead.py 172.28.87.24:1025 P0301=0
```
Check if the error has appeared again:
```
utils/writeRead.py 172.28.87.24:1025 P0301
```
If the console output is not 0, the error has been deleted, but appeared
immediately again. In this case, the error cannot be reset remotely.
If it is an error such as 10 (limit switches hit), the motor needs to be
moved away from the limits, this resets the error automatically.
Other errors like 13 represent an actual issue on the hardware which
needs to be resolved by the electronics motion engineers.
This driver can be compiled and installed by running `make install` from the same directory where the Makefile is located. However, since it uses the git submodule sinqMotor, make sure that the correct version of the submodule repository is checked out AND the change is commited (`git status` shows no non-committed changes). Please see the section "Usage as static dependency" in https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md for more details.

Binary file not shown.

View File

@@ -31,14 +31,3 @@ record(longout, "$(INSTR)FlushHardware") {
field(PINI, "NO")
field(VAL, "1")
}
# If this PV is set to 1 (default), the position limits are read out from the
# controller. Otherwise, the limits given in the substitution file (DHLM and
# DLLM) are used.
# This record is coupled to the parameter library via limFromHardware -> LIM_FROM_HARDWARE.
record(longout, "$(INSTR)$(M):LimFromHardware") {
field(DTYP, "asynInt32")
field(OUT, "@asyn($(CONTROLLER),$(AXIS),1) LIM_FROM_HARDWARE")
field(PINI, "YES")
field(VAL, "$(LIMFROMHARDWARE=1)")
}

View File

@@ -230,7 +230,8 @@ static asynStatus sendPmacGetBuffer(pmacPvt *pPmacPvt, asynUser *pasynUser,
// =============================================================================
int pmacAsynIPPortConfigure(const char *portName, const char *hostInfo) {
epicsShareFunc int pmacAsynIPPortConfigure(const char *portName,
const char *hostInfo) {
asynStatus status = asynSuccess;
asynInterface *int32LowerLevelInterface = NULL;
asynInterface *octetLowerLevelInterface = NULL;

View File

@@ -2,7 +2,6 @@
#define asynInterposePmac_H
#include <epicsExport.h>
#include <macros.h>
#include <shareLib.h>
/*
@@ -26,7 +25,8 @@ extern "C" {
* 172.23.243.156:1025)
* @return status
*/
int HIDDEN pmacAsynIPPortConfigure(const char *portName, const char *hostInfo);
epicsShareFunc int pmacAsynIPPortConfigure(const char *portName,
const char *hostInfo);
#ifdef __cplusplus
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,22 @@
#ifndef turboPmacAXIS_H
#define turboPmacAXIS_H
#include "sinqController.h"
#include "turboPmacController.h"
#include "sinqAxis.h"
#include <memory>
struct HIDDEN turboPmacAxisImpl;
struct turboPmacAxisImpl;
class HIDDEN turboPmacAxis : public sinqAxis {
// Forward declaration of the controller class to resolve the cyclic dependency
// between the controller and the axis .h-file. See
// https://en.cppreference.com/w/cpp/language/class.
class turboPmacController;
class turboPmacAxis : public sinqAxis {
public:
/**
* @brief Construct a new turboPmacAxis
*
* @param pController Pointer to the associated controller
* @param axisNo Index of the axis
* @param initialize By setting this parameter to false, the
* initialization functions of the axes are not executed. This is e.g.
* necessary when this constructor is called from a children class
* constructor which performs its own initialization.
*/
turboPmacAxis(turboPmacController *pController, int axisNo,
bool initialize = true);
@@ -24,22 +24,9 @@ class HIDDEN turboPmacAxis : public sinqAxis {
/**
* @brief Destroy the turboPmacAxis
*
* This destructor is necessary in order to use the PIMPL idiom.
*/
virtual ~turboPmacAxis();
/**
* @brief Readout of some values from the controller at IOC startup
*
* 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 according to the initial status of the axis.
*
* @return asynStatus
*/
virtual asynStatus init();
/**
* @brief Implementation of the `stop` function from asynMotorAxis
*
@@ -86,6 +73,18 @@ class HIDDEN turboPmacAxis : public sinqAxis {
double min_velocity, double max_velocity,
double acceleration);
/**
* @brief Readout of some values from the controller at IOC startup
*
* 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 according to the initial status of the axis.
*
* @return asynStatus
*/
virtual asynStatus init();
/**
* @brief Implementation of the `doReset` function from sinqAxis.
*
@@ -142,11 +141,6 @@ class HIDDEN turboPmacAxis : public sinqAxis {
*/
void setNeedInit(bool needInit);
/**
* @brief Return a pointer to the axis controller
*/
virtual turboPmacController *pController() override { return pC_; };
private:
turboPmacController *pC_;
std::unique_ptr<turboPmacAxisImpl> pTurboPmacA_;

View File

@@ -41,13 +41,12 @@ struct turboPmacControllerImpl {
// User for writing int32 values to the port driver.
asynUser *pasynInt32SyncIOipPort;
// Indices of additional ParamLib entries
// Indices of additional PVs
int rereadEncoderPosition;
int readConfig;
int flushHardware;
int limFromHardware;
};
#define NUM_turboPmac_DRIVER_PARAMS 5
#define NUM_turboPmac_DRIVER_PARAMS 3
turboPmacController::turboPmacController(const char *portName,
const char *ipPortConfigName,
@@ -61,17 +60,17 @@ turboPmacController::turboPmacController(const char *portName,
- REREAD_ENCODER_POSITION
- READ_CONFIG
*/
numExtraParams + NUM_turboPmac_DRIVER_PARAMS),
pTurboPmacC_(
numExtraParams + NUM_turboPmac_DRIVER_PARAMS)
{
// The paramLib indices are populated with the calls to createParam
pTurboPmacC_ =
std::make_unique<turboPmacControllerImpl>((turboPmacControllerImpl){
.comTimeout = comTimeout,
.lastResponse = {0},
.pasynInt32SyncIOipPort = nullptr, // Populated in constructor
.rereadEncoderPosition = 0, // Populated in constructor
.readConfig = 0, // Populated in constructor
.flushHardware = 0, // Populated in constructor
.limFromHardware = 0, // Populated in constructor
})) {
});
// Initialization of local variables
asynStatus status = asynSuccess;
@@ -115,17 +114,6 @@ turboPmacController::turboPmacController(const char *portName,
exit(-1);
}
status = createParam("LIM_FROM_HARDWARE", asynParamInt32,
&pTurboPmacC_->limFromHardware);
if (status != asynSuccess) {
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
"parameter failed with %s).\nTerminating IOC",
portName, __PRETTY_FUNCTION__, __LINE__,
stringifyAsynStatus(status));
exit(-1);
}
/*
Define the end-of-string of a message coming from the device to EPICS.
It is not necessary to append a terminator to outgoing messages, since
@@ -179,8 +167,6 @@ turboPmacController::turboPmacController(const char *portName,
}
}
turboPmacController::~turboPmacController() {}
/*
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
@@ -206,6 +192,9 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
// Definition of local variables.
asynStatus status = asynSuccess;
asynStatus paramLibStatus = asynSuccess;
asynStatus timeoutStatus = asynSuccess;
// char fullCommand[MAXBUF_] = {0};
char drvMessageText[MAXBUF_] = {0};
char modResponse[MAXBUF_] = {0};
int motorStatusProblem = 0;
@@ -253,22 +242,6 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
pasynOctetSyncIOipPort(), command, commandLength, response, MAXBUF_,
pTurboPmacC_->comTimeout, &nbytesOut, &nbytesIn, &eomReason);
/*
If sth. is written to the controller, it needs some time to process the
command. However, the controller returns the acknowledgment via
pasynOctetSyncIO->writeRead immediately, signalling to the driver that it is
ready to receive the next command. In practice, this can result in commands
getting discarded on the driver side or in bringing the driver in undefined
states (e.g. stuck in status 1).
To prevent this, we wait for 20 ms after a write command to give the
controller enough time to process everything. A write command can be
identified by looking for the equal sign.
*/
if (strchr(command, '=')) {
usleep(20000);
}
msgPrintControlKey comKey =
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
@@ -283,7 +256,8 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
getMsgPrintControl().getSuffix());
}
checkComTimeoutWatchdog(axisNo, drvMessageText, sizeof(drvMessageText));
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
sizeof(drvMessageText));
int timeoutCounter = 0;
while (1) {
@@ -331,10 +305,14 @@ 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 (status == asynSuccess && eomReason != 2) {
if (eomReason != 2) {
status = asynError;
char reasonStringified[30] = {0};
@@ -385,7 +363,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
}
msgPrintControlKey numResponsesKey =
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
if (status == asynSuccess && numExpectedResponses != numReceivedResponses) {
if (numExpectedResponses != numReceivedResponses) {
adjustResponseForPrint(modResponse, response, MAXBUF_);
if (getMsgPrintControl().shouldBePrinted(numResponsesKey, true,
@@ -436,18 +414,41 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
// Log the overall status (communication successfull or not)
if (status == asynSuccess) {
setAxisParamChecked(axis, motorStatusCommsError, false);
paramLibStatus = axis->setIntegerParam(this->motorStatusCommsError_, 0);
} else {
// 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
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
paramLibStatus =
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
if (paramLibStatus != asynSuccess) {
return paramLibAccessFailed(paramLibStatus, "motorStatusProblem",
axisNo, __PRETTY_FUNCTION__, __LINE__);
}
if (motorStatusProblem == 0) {
setAxisParamChecked(axis, motorMessageText, drvMessageText);
setAxisParamChecked(axis, motorStatusProblem, true);
setAxisParamChecked(axis, motorStatusCommsError, true);
paramLibStatus =
axis->setStringParam(motorMessageText(), drvMessageText);
if (paramLibStatus != asynSuccess) {
return paramLibAccessFailed(paramLibStatus, "motorMessageText",
axisNo, __PRETTY_FUNCTION__,
__LINE__);
}
paramLibStatus = axis->setIntegerParam(motorStatusProblem_, 1);
if (paramLibStatus != asynSuccess) {
return paramLibAccessFailed(paramLibStatus,
"motorStatusProblem", axisNo,
__PRETTY_FUNCTION__, __LINE__);
}
paramLibStatus = axis->setIntegerParam(motorStatusProblem_, 1);
if (paramLibStatus != asynSuccess) {
return paramLibAccessFailed(paramLibStatus,
"motorStatusCommsError", axisNo,
__PRETTY_FUNCTION__, __LINE__);
}
}
}
return status;
@@ -505,9 +506,6 @@ int turboPmacController::rereadEncoderPosition() {
}
int turboPmacController::readConfig() { return pTurboPmacC_->readConfig; }
int turboPmacController::flushHardware() { return pTurboPmacC_->flushHardware; }
int turboPmacController::limFromHardware() {
return pTurboPmacC_->limFromHardware;
}
asynUser *turboPmacController::pasynInt32SyncIOipPort() {
return pTurboPmacC_->pasynInt32SyncIOipPort;
@@ -567,8 +565,7 @@ static const iocshArg *const CreateControllerArgs[] = {
&CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2,
&CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5};
static const iocshFuncDef configTurboPmacCreateController = {
"turboPmacController", 6, CreateControllerArgs,
"Create a new instance of a TurboPMAC controller."};
"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);

View File

@@ -10,16 +10,12 @@
#define turboPmacController_H
#include "sinqAxis.h"
#include "sinqController.h"
#include "turboPmacAxis.h"
#include <memory>
// Forward declaration of the controller class to resolve the cyclic dependency
// between the controller and the axis .h-file. See
// https://en.cppreference.com/w/cpp/language/class.
class HIDDEN turboPmacAxis;
struct turboPmacControllerImpl;
struct HIDDEN turboPmacControllerImpl;
class HIDDEN turboPmacController : public sinqController {
class turboPmacController : public sinqController {
public:
/**
* @brief Construct a new turboPmacController object. This function is meant
@@ -40,13 +36,6 @@ class HIDDEN turboPmacController : public sinqController {
double idlePollPeriod, double comTimeout,
int numExtraParams = 0);
/**
* @brief Destroy the controller. Its implementation is empty, however the
* destructor needs to be provided for handling turboPmacControllerImpl.
*
*/
virtual ~turboPmacController();
/**
* @brief Get the axis object
*
@@ -93,8 +82,7 @@ class HIDDEN turboPmacController : public sinqController {
* @return asynStatus
*/
asynStatus writeRead(int axisNo, const char *command, char *response,
int numExpectedResponses)
__attribute__((visibility("hidden")));
int numExpectedResponses);
/**
* @brief Specialized version of sinqController::couldNotParseResponse
@@ -134,7 +122,6 @@ class HIDDEN turboPmacController : public sinqController {
int rereadEncoderPosition();
int readConfig();
int flushHardware();
int limFromHardware();
asynUser *pasynInt32SyncIOipPort();