Compare commits

..

25 Commits
1.0.0 ... 1.3.1

Author SHA1 Message Date
62a3d8c834 Added documenation for enableDisable flag 2025-07-29 11:50:34 +02:00
fd2afa9ec6 Added sleep to stop to make sure at least one poll happens and EPCIS knows the motor is moving 2025-07-29 09:44:26 +02:00
949e9faef3 Fixed various bugs found by the automated tests 2025-07-25 16:53:52 +02:00
5df84d6017 Using fixed 1.3.0 version 2025-07-24 11:32:44 +02:00
08c85129f3 Updated sinqMotor to 1.3.0 2025-07-24 11:16:37 +02:00
a980740fd5 Test timing problem 2025-07-24 09:40:52 +02:00
338b4d61b4 Added sleep after write commands
See comment in writeRead for explanation.
2025-07-24 08:51:38 +02:00
25b832a6e9 Updated sinqMotor to latest version 2025-07-23 09:55:24 +02:00
1e8a6495b8 Disable the axis on reset, if it is not moving
Resetting the axis now also disables it, if it is not moving.
2025-07-01 13:11:06 +02:00
6b91ab6d51 Links in README.md updated to point to Gitea now. 2025-06-26 13:56:57 +02:00
f423002d23 Updated sinqMotor 2025-06-18 08:26:49 +02:00
79ec79fac1 Updated sinqMotor 2025-06-18 08:18:53 +02:00
1703542770 Use new sinqMotor version 2025-06-17 13:16:20 +02:00
c7d1dc4930 Added getAxisParam variant for char arrays 2025-06-17 10:25:02 +02:00
6fd3848f13 Fixed template for char arrays 2025-06-17 08:45:07 +02:00
56f08f3c76 Fixed template error in sinqMotor 2025-06-17 08:41:07 +02:00
168bfae983 Updated sinqMotor 2025-06-17 08:34:07 +02:00
0e29750d13 Updated sinqMotor version 2025-06-16 16:18:06 +02:00
ba5b921aca Committed new sinqMotor version 2025-06-16 15:55:40 +02:00
1b810fb353 Adjusted dependency to use AxisParamChecked branch 2025-06-16 15:26:44 +02:00
4bc3388bc6 Added destructor for controller 2025-06-10 14:58:59 +02:00
c759156058 Added destructor for controller 2025-06-10 14:53:26 +02:00
eca513f3a0 Updated sinqMotor version to 1.1 2025-06-10 14:11:48 +02:00
26175290bf Added flag to disable reading the limits from the hardware 2025-06-10 13:53:39 +02:00
e316fcf67b Changed priority of IOC shell message 2025-06-06 11:20:50 +02:00
7 changed files with 227 additions and 452 deletions

View File

@@ -1,6 +1,6 @@
# turboPmac
## <span style="color:red">Please read the documentation of sinqMotor first: https://git.psi.ch/sinq-epics-modules/sinqmotor</span>
## <span style="color:red">Please read the documentation of sinqMotor first: https://gitea.psi.ch/lin-epics-modules/sinqMotor</span>
## Overview
@@ -8,7 +8,7 @@ This is a driver for the Turbo PMAC motion controller with the SINQ communicatio
## 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://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/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.
@@ -67,8 +67,8 @@ dbLoadRecords("$(turboPmac_DB)/asynRecord.db","P=$(INSTR)$(DRIVER_PORT),PORT=$(I
### Versioning
Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/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://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://gitea.psi.ch/lin-epics-modules/sinqMotor/src/branch/main/README.md for more details.

View File

@@ -31,3 +31,14 @@ 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)")
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,11 @@
#ifndef turboPmacAXIS_H
#define turboPmacAXIS_H
#include "sinqAxis.h"
#include "sinqController.h"
#include "turboPmacController.h"
#include <memory>
struct turboPmacAxisImpl;
// 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:
/**
@@ -24,6 +20,7 @@ class turboPmacAxis : public sinqAxis {
/**
* @brief Destroy the turboPmacAxis
*
* This destructor is necessary in order to use the PIMPL idiom.
*/
virtual ~turboPmacAxis();
@@ -141,6 +138,11 @@ class 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

@@ -45,6 +45,7 @@ struct turboPmacControllerImpl {
int rereadEncoderPosition;
int readConfig;
int flushHardware;
int limFromHardware;
};
#define NUM_turboPmac_DRIVER_PARAMS 3
@@ -114,6 +115,17 @@ 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
@@ -167,6 +179,8 @@ 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
@@ -192,9 +206,7 @@ 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;
@@ -242,6 +254,10 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
pasynOctetSyncIOipPort(), command, commandLength, response, MAXBUF_,
pTurboPmacC_->comTimeout, &nbytesOut, &nbytesIn, &eomReason);
// if (strchr(command, '=')) {
// usleep(20000);
// }
msgPrintControlKey comKey =
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
@@ -414,41 +430,18 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
// Log the overall status (communication successfull or not)
if (status == asynSuccess) {
paramLibStatus = axis->setIntegerParam(this->motorStatusCommsError_, 0);
setAxisParamChecked(axis, motorStatusCommsError, false);
} 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
paramLibStatus =
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
if (paramLibStatus != asynSuccess) {
return paramLibAccessFailed(paramLibStatus, "motorStatusProblem",
axisNo, __PRETTY_FUNCTION__, __LINE__);
}
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
if (motorStatusProblem == 0) {
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__);
}
setAxisParamChecked(axis, motorMessageText, drvMessageText);
setAxisParamChecked(axis, motorStatusProblem, true);
setAxisParamChecked(axis, motorStatusCommsError, true);
}
}
return status;
@@ -506,6 +499,9 @@ 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;

View File

@@ -10,9 +10,13 @@
#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 turboPmacAxis;
struct turboPmacControllerImpl;
class turboPmacController : public sinqController {
@@ -36,6 +40,13 @@ class 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
*
@@ -122,6 +133,7 @@ class turboPmacController : public sinqController {
int rereadEncoderPosition();
int readConfig();
int flushHardware();
int limFromHardware();
asynUser *pasynInt32SyncIOipPort();