Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
55b523ddaa | |||
75292a6a9c | |||
53bbe2aae8 | |||
1597dc34e0 | |||
dde7066f40 | |||
b4d6447b32 | |||
2f83060ec1 | |||
a3e3a79788 | |||
2c5fdc7d0a | |||
7bf31ac256 | |||
47e72d65a9 | |||
5298b5ef69 | |||
29f23216ad | |||
26bc3df876 | |||
87d3cbb3eb | |||
66552d5ffc | |||
253f65b25b |
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -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
|
14
Makefile
14
Makefile
@ -1,4 +1,4 @@
|
|||||||
# Use the PSI build system
|
# Include the external Makefile
|
||||||
include /ioc/tools/driver.makefile
|
include /ioc/tools/driver.makefile
|
||||||
|
|
||||||
MODULE=turboPmac
|
MODULE=turboPmac
|
||||||
@ -8,28 +8,30 @@ ARCH_FILTER=RHEL%
|
|||||||
|
|
||||||
# Additional module dependencies
|
# Additional module dependencies
|
||||||
REQUIRED+=motorBase
|
REQUIRED+=motorBase
|
||||||
REQUIRED+=sinqMotor
|
|
||||||
|
|
||||||
# Specify the version of motorBase we want to build against
|
# Specify the version of motorBase we want to build against
|
||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of sinqMotor we want to build against
|
|
||||||
sinqMotor_VERSION=mathis_s
|
|
||||||
|
|
||||||
# These headers allow to depend on this library for derived drivers.
|
# These headers allow to depend on this library for derived drivers.
|
||||||
HEADERS += src/pmacAsynIPPort.h
|
HEADERS += src/pmacAsynIPPort.h
|
||||||
HEADERS += src/turboPmacAxis.h
|
HEADERS += src/turboPmacAxis.h
|
||||||
HEADERS += src/turboPmacController.h
|
HEADERS += src/turboPmacController.h
|
||||||
|
|
||||||
# Source files to build
|
# 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/pmacAsynIPPort.c
|
||||||
SOURCES += src/turboPmacAxis.cpp
|
SOURCES += src/turboPmacAxis.cpp
|
||||||
SOURCES += src/turboPmacController.cpp
|
SOURCES += src/turboPmacController.cpp
|
||||||
|
|
||||||
# Store the record files
|
# Store the record files
|
||||||
|
TEMPLATES += sinqMotor/db/asynRecord.db
|
||||||
|
TEMPLATES += sinqMotor/db/sinqMotor.db
|
||||||
TEMPLATES += db/turboPmac.db
|
TEMPLATES += db/turboPmac.db
|
||||||
|
|
||||||
# This file registers the motor-specific functions in the IOC shell.
|
# This file registers the motor-specific functions in the IOC shell.
|
||||||
|
DBDS += sinqMotor/src/sinqMotor.dbd
|
||||||
DBDS += src/turboPmac.dbd
|
DBDS += src/turboPmac.dbd
|
||||||
|
|
||||||
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings
|
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Werror # -Wpedantic // Does not work because EPICS macros trigger warnings
|
@ -54,11 +54,11 @@ setMaxSubsequentTimeouts("$(DRIVER_PORT)", 20);
|
|||||||
setThresholdComTimeout("$(DRIVER_PORT)", 300, 10);
|
setThresholdComTimeout("$(DRIVER_PORT)", 300, 10);
|
||||||
|
|
||||||
# Parametrize the EPICS record database with the substitution file named after the MCU.
|
# 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)")
|
dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)")
|
||||||
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
|
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
|
||||||
dbLoadTemplate("$(TOP)/$(DRIVER_PORT).substitutions", "INSTR=$(INSTR)$(DRIVER_PORT):,CONTROLLER=$(DRIVER_PORT)")
|
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
|
### Additional records
|
||||||
@ -73,4 +73,4 @@ Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-e
|
|||||||
|
|
||||||
### How to build it
|
### 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.
|
||||||
|
1
sinqMotor
Submodule
1
sinqMotor
Submodule
Submodule sinqMotor added at e088bfbbcb
@ -71,6 +71,20 @@ turboPmacAxis::turboPmacAxis(turboPmacController *pC, int axisNo,
|
|||||||
exit(-1);
|
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
|
// turboPmac motors can always be disabled
|
||||||
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
status = pC_->setIntegerParam(axisNo_, pC_->motorCanDisable(), 1);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
@ -397,13 +411,6 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
case -5:
|
case -5:
|
||||||
// Axis is deactivated
|
// Axis is deactivated
|
||||||
*moving = false;
|
*moving = false;
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Deactivated");
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case -4:
|
case -4:
|
||||||
// Emergency stop
|
// Emergency stop
|
||||||
@ -426,19 +433,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
|
|||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case -3:
|
case -3:
|
||||||
// Disabled
|
// Disabled
|
||||||
*moving = false;
|
*moving = false;
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Disabled");
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
// Idle
|
// Idle
|
||||||
@ -599,8 +597,7 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
|||||||
resetError = false;
|
resetError = false;
|
||||||
|
|
||||||
status = setStringParam(pC_->motorMessageText(),
|
status = setStringParam(pC_->motorMessageText(),
|
||||||
"Target position would exceed software "
|
"Target position would exceed software limits");
|
||||||
"limits. Please call the support.");
|
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
@ -783,10 +780,10 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
|
|||||||
}
|
}
|
||||||
resetError = false;
|
resetError = false;
|
||||||
|
|
||||||
snprintf(userMessage, sizeUserMessage,
|
snprintf(
|
||||||
"Driver hardware error (P%2.2d01 = 13). "
|
userMessage, sizeUserMessage,
|
||||||
"Please call the support.",
|
"Driver hardware error (P%2.2d01 = 13). Please call the support.",
|
||||||
axisNo_);
|
axisNo_);
|
||||||
status = setStringParam(pC_->motorMessageText(), userMessage);
|
status = setStringParam(pC_->motorMessageText(), userMessage);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
return pC_->paramLibAccessFailed(status, "motorMessageText_",
|
||||||
@ -1084,22 +1081,7 @@ asynStatus turboPmacAxis::doHome(double min_velocity, double max_velocity,
|
|||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Homing");
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
return callParamCallbacks();
|
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;
|
return asynSuccess;
|
||||||
@ -1271,6 +1253,8 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
// Status of parameter library operations
|
// Status of parameter library operations
|
||||||
asynStatus pl_status = asynSuccess;
|
asynStatus pl_status = asynSuccess;
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Continue regardless of the status returned by the poll; we just want to
|
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
|
find out whether the motor is currently moving or not. If the poll
|
||||||
@ -1280,8 +1264,6 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
bool moving = false;
|
bool moving = false;
|
||||||
doPoll(&moving);
|
doPoll(&moving);
|
||||||
|
|
||||||
// =========================================================================
|
|
||||||
|
|
||||||
// If the axis is currently moving, it cannot be disabled. Ignore the
|
// 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
|
// 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
|
// instead of "moving", since status -6 is also moving, but the motor can
|
||||||
@ -1330,16 +1312,7 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
"Controller \"%s\", axis %d => %s, line %d\n%s axis\n",
|
"Controller \"%s\", axis %d => %s, line %d\n%s axis\n",
|
||||||
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
|
||||||
on ? "Enable" : "Disable");
|
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);
|
rw_status = pC_->writeRead(axisNo_, command, response, 0);
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
return rw_status;
|
return rw_status;
|
||||||
@ -1382,7 +1355,7 @@ asynStatus turboPmacAxis::enable(bool on) {
|
|||||||
// Output message to user
|
// Output message to user
|
||||||
snprintf(command, sizeof(command), "Failed to %s within %d seconds",
|
snprintf(command, sizeof(command), "Failed to %s within %d seconds",
|
||||||
on ? "enable" : "disable", timeout_enable_disable);
|
on ? "enable" : "disable", timeout_enable_disable);
|
||||||
pl_status = setStringParam(pC_->motorMessageText(), "Enabling ...");
|
pl_status = setStringParam(pC_->motorMessageText(), command);
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
|
||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
|
@ -31,7 +31,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* value is currently not used.
|
* value is currently not used.
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus stop(double acceleration);
|
virtual asynStatus stop(double acceleration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the `doHome` function from sinqAxis. The
|
* @brief Implementation of the `doHome` function from sinqAxis. The
|
||||||
@ -43,8 +43,8 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* @param forwards
|
* @param forwards
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus doHome(double minVelocity, double maxVelocity,
|
virtual asynStatus doHome(double minVelocity, double maxVelocity,
|
||||||
double acceleration, int forwards);
|
double acceleration, int forwards);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the `doPoll` function from sinqAxis. The
|
* @brief Implementation of the `doPoll` function from sinqAxis. The
|
||||||
@ -53,7 +53,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* @param moving
|
* @param moving
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus doPoll(bool *moving);
|
virtual asynStatus doPoll(bool *moving);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the `doMove` function from sinqAxis. The
|
* @brief Implementation of the `doMove` function from sinqAxis. The
|
||||||
@ -66,8 +66,9 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* @param acceleration
|
* @param acceleration
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus doMove(double position, int relative, double min_velocity,
|
virtual asynStatus doMove(double position, int relative,
|
||||||
double max_velocity, double acceleration);
|
double min_velocity, double max_velocity,
|
||||||
|
double acceleration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Readout of some values from the controller at IOC startup
|
* @brief Readout of some values from the controller at IOC startup
|
||||||
@ -79,7 +80,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
*
|
*
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus init();
|
virtual asynStatus init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the `doReset` function from sinqAxis.
|
* @brief Implementation of the `doReset` function from sinqAxis.
|
||||||
@ -87,7 +88,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* @param on
|
* @param on
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus doReset();
|
virtual asynStatus doReset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable / disable the axis.
|
* @brief Enable / disable the axis.
|
||||||
@ -95,7 +96,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
* @param on
|
* @param on
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus enable(bool on);
|
virtual asynStatus enable(bool on);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the encoder type (incremental or absolute) for this axis from
|
* @brief Read the encoder type (incremental or absolute) for this axis from
|
||||||
@ -103,14 +104,14 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
*
|
*
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus readEncoderType();
|
virtual asynStatus readEncoderType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Trigger a rereading of the encoder position.
|
* @brief Trigger a rereading of the encoder position.
|
||||||
*
|
*
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus rereadEncoder();
|
virtual asynStatus rereadEncoder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Interpret the error code and populate the user message accordingly
|
* @brief Interpret the error code and populate the user message accordingly
|
||||||
|
@ -120,17 +120,10 @@ class turboPmacController : public sinqController {
|
|||||||
int readConfig() { return readConfig_; }
|
int readConfig() { return readConfig_; }
|
||||||
int flushHardware() { return flushHardware_; }
|
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_; }
|
asynUser *pasynInt32SyncIOipPort() { return pasynInt32SyncIOipPort_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*
|
// Timeout for the communication process in seconds
|
||||||
Timeout for the communication process in seconds
|
|
||||||
*/
|
|
||||||
double comTimeout_;
|
double comTimeout_;
|
||||||
|
|
||||||
char lastResponse[MAXBUF_];
|
char lastResponse[MAXBUF_];
|
||||||
|
Reference in New Issue
Block a user