Compare commits

..

1 Commits
1.5.1 ... main

Author SHA1 Message Date
62ccf046fd Added compiler flags for the C++ code and formatted README
Some checks failed
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Failing after 6s
2025-12-23 13:27:14 +01:00
4 changed files with 62 additions and 25 deletions

View File

@@ -34,4 +34,5 @@ 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_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

View File

@@ -4,15 +4,26 @@
## 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://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/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
@@ -27,8 +38,10 @@ The full turboPmacX.cmd file looks like this:
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")
@@ -48,7 +61,8 @@ 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.
@@ -61,14 +75,22 @@ 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://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/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.
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.

View File

@@ -787,6 +787,10 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
// =========================================================================
// Suppress unused variables warning
(void)minVelocity;
(void)acceleration;
getAxisParamChecked(this, motorEnableRBV, &enabled);
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
@@ -875,6 +879,9 @@ asynStatus turboPmacAxis::stop(double acceleration) {
// =========================================================================
// Suppress unused variables warning
(void)acceleration;
snprintf(command, sizeof(command), "M%2.2d=8", axisNo_);
status = pC_->writeRead(axisNo_, command, response, 0);
@@ -939,7 +946,7 @@ asynStatus turboPmacAxis::doReset() {
/*
Home the axis. On absolute encoder systems, this is a no-op
*/
asynStatus turboPmacAxis::doHome(double min_velocity, double max_velocity,
asynStatus turboPmacAxis::doHome(double minVelocity, double maxVelocity,
double acceleration, int forwards) {
// Status of read-write-operations of ASCII commands to the controller
@@ -950,6 +957,12 @@ asynStatus turboPmacAxis::doHome(double min_velocity, double max_velocity,
// =========================================================================
// Suppress unused variables warning
(void)minVelocity;
(void)maxVelocity;
(void)acceleration;
(void)forwards;
getAxisParamChecked(this, encoderType, &response);
// Only send the home command if the axis has an incremental encoder

View File

@@ -61,17 +61,17 @@ turboPmacController::turboPmacController(const char *portName,
- REREAD_ENCODER_POSITION
- READ_CONFIG
*/
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},
});
numExtraParams + NUM_turboPmac_DRIVER_PARAMS),
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;
@@ -573,7 +573,8 @@ static const iocshArg *const CreateControllerArgs[] = {
&CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2,
&CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5};
static const iocshFuncDef configTurboPmacCreateController = {
"turboPmacController", 6, CreateControllerArgs};
"turboPmacController", 6, CreateControllerArgs,
"Create a new instance of a TurboPMAC controller."};
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);