From 4ee211b481f799772fc0b50a3277fd05b91d548f Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 08:52:10 +0200 Subject: [PATCH 01/12] Added sinqMotor as a submodule for static linking --- .gitmodules | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e8d403e --- /dev/null +++ b/.gitmodules @@ -0,0 +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 From 980ea5995866c59634cc1eab6f9f0d234bf06028 Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 11:58:56 +0200 Subject: [PATCH 02/12] Pinned sinqMotor version --- Makefile | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 1c9fa85..c5d088e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Use the PSI build system +# Include the external Makefile include /ioc/tools/driver.makefile MODULE=turboPmac @@ -8,13 +8,12 @@ ARCH_FILTER=RHEL% # Additional module dependencies REQUIRED+=motorBase -REQUIRED+=sinqMotor # Specify the version of motorBase we want to build against motorBase_VERSION=7.2.2 -# Specify the version of sinqMotor we want to build against -sinqMotor_VERSION=mathis_s +# Specify the commit / tag of sinqMotor we want to statically link into this driver +SINQMOTOR = 0.1 # These headers allow to depend on this library for derived drivers. HEADERS += src/pmacAsynIPPort.h @@ -22,14 +21,28 @@ HEADERS += src/turboPmacAxis.h HEADERS += src/turboPmacController.h # Source files to build +SOURCES += sinqMotor/src/msgPrintControl.cpp +SOURCES += sinqMotor/src/sinqAxis.cpp +SOURCES += sinqMotor/src/sinqController.cpp SOURCES += src/pmacAsynIPPort.c SOURCES += src/turboPmacAxis.cpp SOURCES += src/turboPmacController.cpp # Store the record files +TEMPLATES += sinqMotor/db/asynRecord.db +TEMPLATES += sinqMotor/db/sinqMotor.db TEMPLATES += db/turboPmac.db # This file registers the motor-specific functions in the IOC shell. +DBDS += sinqMotor/src/sinqMotor.dbd DBDS += src/turboPmac.dbd USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings + +# Check out the correct version of sinqMotor and call this Makefile again with +# the originall install command +sinqinstall:: + git submodule update --init --recursive + cd sinqMotor && git fetch --tags && git checkout $(SINQMOTOR) + cd .. + @$(MAKE) install \ No newline at end of file From 31875ddd9952dc8ece26dec200373d63b1408627 Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 12:00:49 +0200 Subject: [PATCH 03/12] Specified new version for sinqMotor --- Makefile | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Makefile b/Makefile index c5d088e..f3382bf 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,6 @@ REQUIRED+=motorBase # Specify the version of motorBase we want to build against motorBase_VERSION=7.2.2 -# Specify the commit / tag of sinqMotor we want to statically link into this driver -SINQMOTOR = 0.1 - # These headers allow to depend on this library for derived drivers. HEADERS += src/pmacAsynIPPort.h HEADERS += src/turboPmacAxis.h @@ -37,12 +34,4 @@ TEMPLATES += db/turboPmac.db DBDS += sinqMotor/src/sinqMotor.dbd DBDS += src/turboPmac.dbd -USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings - -# Check out the correct version of sinqMotor and call this Makefile again with -# the originall install command -sinqinstall:: - git submodule update --init --recursive - cd sinqMotor && git fetch --tags && git checkout $(SINQMOTOR) - cd .. - @$(MAKE) install \ No newline at end of file +USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings \ No newline at end of file From 3bafc5110c0b483543e4ccafc0aaeeda028b4f92 Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 16:19:34 +0200 Subject: [PATCH 04/12] Fixed bug where the motor could be in state -6 and the driver would interpret this as "not moving" --- src/turboPmacAxis.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/turboPmacAxis.cpp b/src/turboPmacAxis.cpp index 20446da..9e631d5 100644 --- a/src/turboPmacAxis.cpp +++ b/src/turboPmacAxis.cpp @@ -392,13 +392,7 @@ asynStatus turboPmacAxis::doPoll(bool *moving) { switch (axStatus) { case -6: // Axis is stopping - - // If the axis was already idle during the last poll, it is not moving - if (previousStatusDone == 0) { - *moving = true; - } else { - *moving = false; - } + *moving = true; break; case -5: // Axis is deactivated From d4bb77bae1a0f677346926be49eaa8fe3736f9c5 Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 16:43:57 +0200 Subject: [PATCH 05/12] Added some comments that this library now uses sinqMotor as static dependency. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 71d0f6d..600ff6a 100644 --- a/README.md +++ b/README.md @@ -73,4 +73,4 @@ Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-e ### How to build it -Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md. +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 From 50192858e914651e7da9b9bf58986e4a48815aeb Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 16:59:59 +0200 Subject: [PATCH 06/12] Fixed typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 600ff6a..d59f99f 100644 --- a/README.md +++ b/README.md @@ -73,4 +73,4 @@ Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-e ### 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://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/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://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md for more details. From b53cf770aea7356113235a5851e06e3b37fbffa4 Mon Sep 17 00:00:00 2001 From: smathis Date: Mon, 12 May 2025 17:04:09 +0200 Subject: [PATCH 07/12] Fixed small inaccuracy in the README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d59f99f..a6cf3d1 100644 --- a/README.md +++ b/README.md @@ -54,11 +54,11 @@ setMaxSubsequentTimeouts("$(DRIVER_PORT)", 20); setThresholdComTimeout("$(DRIVER_PORT)", 300, 10); # Parametrize the EPICS record database with the substitution file named after the MCU. -epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db") +epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/sinqMotor.db") dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)") epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db") dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)") -dbLoadRecords("$(sinqMotor_DB)/asynRecord.db","P=$(INSTR)$(DRIVER_PORT),PORT=$(IP_PORT)") +dbLoadRecords("$(turboPmac_DB)/asynRecord.db","P=$(INSTR)$(DRIVER_PORT),PORT=$(IP_PORT)") ``` ### Additional records From f6d7f3846d08c00ea507ffb6582e14eea89272f2 Mon Sep 17 00:00:00 2001 From: smathis Date: Tue, 13 May 2025 14:44:24 +0200 Subject: [PATCH 08/12] Allow enabling / disabling the motor regardless of the status returned by the poll --- src/turboPmacAxis.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/turboPmacAxis.cpp b/src/turboPmacAxis.cpp index 9e631d5..c22f32b 100644 --- a/src/turboPmacAxis.cpp +++ b/src/turboPmacAxis.cpp @@ -1271,14 +1271,17 @@ asynStatus turboPmacAxis::enable(bool on) { // Status of parameter library operations asynStatus pl_status = asynSuccess; - bool moving = false; - rw_status = doPoll(&moving); - if (rw_status != asynSuccess) { - return rw_status; - } - // ========================================================================= + /* + Continue regardless of the status returned by the poll; we just want to + find out whether the motor is currently moving or not. If the poll + function fails before it can determine that, it is assumed that the motor + is not moving. + */ + bool moving = false; + doPoll(&moving); + // If the axis is currently moving, it cannot be disabled. Ignore the // command and inform the user. We check the last known status of the axis // instead of "moving", since status -6 is also moving, but the motor can From a7c82d1238a3e8bef4f566073bafe76775786e23 Mon Sep 17 00:00:00 2001 From: smathis Date: Wed, 14 May 2025 16:10:24 +0200 Subject: [PATCH 09/12] Use new version of sinqMotor --- src/turboPmacController.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/turboPmacController.h b/src/turboPmacController.h index 74cc97f..9636d24 100644 --- a/src/turboPmacController.h +++ b/src/turboPmacController.h @@ -120,17 +120,10 @@ class turboPmacController : public sinqController { int readConfig() { return readConfig_; } int flushHardware() { return flushHardware_; } - // 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. - static const uint32_t MAXBUF_ = 200; - asynUser *pasynInt32SyncIOipPort() { return pasynInt32SyncIOipPort_; } protected: - /* - Timeout for the communication process in seconds - */ + // Timeout for the communication process in seconds double comTimeout_; char lastResponse[MAXBUF_]; From 1054b87467953867ef2ed280c33a2c30785a4d04 Mon Sep 17 00:00:00 2001 From: smathis Date: Wed, 14 May 2025 16:17:14 +0200 Subject: [PATCH 10/12] Adjusted usage of motorMessageText to act as an error message only. --- src/turboPmacAxis.cpp | 59 +++++-------------------------------------- 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/src/turboPmacAxis.cpp b/src/turboPmacAxis.cpp index c22f32b..2440bf7 100644 --- a/src/turboPmacAxis.cpp +++ b/src/turboPmacAxis.cpp @@ -397,13 +397,6 @@ asynStatus turboPmacAxis::doPoll(bool *moving) { case -5: // Axis is deactivated *moving = false; - - 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 @@ -426,19 +419,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) { axisNo_, __PRETTY_FUNCTION__, __LINE__); } - break; case -3: // Disabled *moving = false; - - pl_status = setStringParam(pC_->motorMessageText(), "Disabled"); - if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", - axisNo_, __PRETTY_FUNCTION__, - __LINE__); - } - break; case 0: // Idle @@ -599,8 +583,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage, resetError = false; status = setStringParam(pC_->motorMessageText(), - "Target position would exceed software " - "limits. Please call the support."); + "Target position would exceed software limits"); if (status != asynSuccess) { return pC_->paramLibAccessFailed(status, "motorMessageText_", axisNo_, __PRETTY_FUNCTION__, @@ -783,10 +766,10 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage, } resetError = false; - snprintf(userMessage, sizeUserMessage, - "Driver hardware error (P%2.2d01 = 13). " - "Please call the support.", - axisNo_); + 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_", @@ -1084,22 +1067,7 @@ asynStatus turboPmacAxis::doHome(double min_velocity, double max_velocity, axisNo_, __PRETTY_FUNCTION__, __LINE__); } - - pl_status = setStringParam(pC_->motorMessageText(), "Homing"); - if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", - axisNo_, __PRETTY_FUNCTION__, - __LINE__); - } return callParamCallbacks(); - } else { - pl_status = setStringParam(pC_->motorMessageText(), - "Can't home a motor with absolute encoder"); - if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", - axisNo_, __PRETTY_FUNCTION__, - __LINE__); - } } return asynSuccess; @@ -1330,16 +1298,7 @@ asynStatus turboPmacAxis::enable(bool on) { "Controller \"%s\", axis %d => %s, line %d\n%s axis\n", pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, on ? "Enable" : "Disable"); - if (on == 0) { - pl_status = setStringParam(pC_->motorMessageText(), "Disabling ..."); - } else { - pl_status = setStringParam(pC_->motorMessageText(), "Enabling ..."); - } - if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", - axisNo_, __PRETTY_FUNCTION__, - __LINE__); - } + rw_status = pC_->writeRead(axisNo_, command, response, 0); if (rw_status != asynSuccess) { return rw_status; @@ -1382,12 +1341,6 @@ asynStatus turboPmacAxis::enable(bool on) { // Output message to user snprintf(command, sizeof(command), "Failed to %s within %d seconds", on ? "enable" : "disable", timeout_enable_disable); - pl_status = setStringParam(pC_->motorMessageText(), "Enabling ..."); - if (pl_status != asynSuccess) { - return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", - axisNo_, __PRETTY_FUNCTION__, - __LINE__); - } return asynError; } From c945896da1c00e9bb4493ba083d1cf45b9c098e7 Mon Sep 17 00:00:00 2001 From: smathis Date: Wed, 14 May 2025 16:26:55 +0200 Subject: [PATCH 11/12] Addes error message for failing to enable / disable within timeout --- src/turboPmacAxis.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/turboPmacAxis.cpp b/src/turboPmacAxis.cpp index 2440bf7..436239a 100644 --- a/src/turboPmacAxis.cpp +++ b/src/turboPmacAxis.cpp @@ -1341,6 +1341,12 @@ asynStatus turboPmacAxis::enable(bool on) { // Output message to user snprintf(command, sizeof(command), "Failed to %s within %d seconds", on ? "enable" : "disable", timeout_enable_disable); + pl_status = setStringParam(pC_->motorMessageText(), command); + if (pl_status != asynSuccess) { + return pC_->paramLibAccessFailed(pl_status, "motorMessageText_", + axisNo_, __PRETTY_FUNCTION__, + __LINE__); + } return asynError; } From 2e5059da33cb2408060e000798b1b0ef978a73a7 Mon Sep 17 00:00:00 2001 From: smathis Date: Thu, 15 May 2025 12:25:08 +0200 Subject: [PATCH 12/12] Added default value for motorMessageText --- src/turboPmacAxis.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/turboPmacAxis.cpp b/src/turboPmacAxis.cpp index 436239a..6cabb95 100644 --- a/src/turboPmacAxis.cpp +++ b/src/turboPmacAxis.cpp @@ -71,6 +71,20 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo, exit(-1); } + // Even though this happens already in sinqAxis, a default value for + // motorMessageText is set here again, because apparently the sinqAxis + // constructor is not run before the string is accessed? + status = setStringParam(pC_->motorMessageText(), ""); + if (status != asynSuccess) { + asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR, + "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); + } + // turboPmac motors can always be disabled status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1); if (status != asynSuccess) {