Compare commits

..

67 Commits

Author SHA1 Message Date
mathis_s 7a96ed2b71 Fixed bug: Wrong scale used before
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 8s
The correct scale from counts to engeering units is Qxx00.
2025-09-10 11:52:51 +02:00
mathis_s cf43a1c57a Updated to sinqMotor 1.5 to get deadband feature
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 7s
2025-09-09 16:52:19 +02:00
mathis_s 85317e24cd Deadband check in driver code 2025-09-09 13:43:11 +02:00
mathis_s 1ee483f8e9 Removed C++ only flag from USR_CFLAGS
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 7s
USR_CFLAGS only applies to .c files, which are compiled with a C
compiler, therefore the C++ flag is not applied, resulting in a warning
during compilation.
2025-08-22 15:27:28 +02:00
mathis_s 002b5d2616 Fixed bug with errorprint to ioc console
The previous setup created one print key for all error types. The
problem with that is that if an error directly followed another error
(without an error = 0 in between), the MsgPrintControl prevented
printing of the new error. Now every error has its own key.
2025-08-22 15:25:31 +02:00
mathis_s ce80426790 Updated sinqMotor to fix bug in forcedPoll
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 7s
2025-08-14 17:21:58 +02:00
mathis_s 72f3965881 Fixed imprecise comment
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 8s
2025-08-12 15:42:43 +02:00
mathis_s d41e7bf054 Updated to sinqMotor 1.4.0
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 8s
2025-08-12 09:14:38 +02:00
mathis_s 30bfa1cac5 Hide visibility of classes to avoid symbol clashes 2025-08-12 09:00:42 +02:00
mathis_s 235816fd20 Hide symbols via compilerflag 2025-08-11 16:46:22 +02:00
mathis_s bd0966d2c9 Added flag to see whether we are in the middle of enabling / disabling
Test And Build / Lint (push) Failing after 9s
Test And Build / Build (push) Successful in 13s
2025-08-11 15:47:27 +02:00
mathis_s 9d5d90574a Added sleep after write commands
See comment in writeRead for explanation.
2025-08-11 15:47:27 +02:00
mathis_s 6effc5e906 Updated sinqMotor to latest version 2025-08-11 15:47:27 +02:00
wall_e bc5de11b16 remove unneeded line
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 8s
2025-07-04 14:16:48 +02:00
wall_e aa488627f9 remove old pipeline file
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Successful in 9s
2025-07-04 14:12:54 +02:00
wall_e ccaee6c5d1 no newline
Test And Build / Lint (push) Failing after 4s
Test And Build / Build (push) Successful in 8s
2025-07-04 14:07:20 +02:00
wall_e 323b030581 adds IGNORE_SUBMODULES as other makefile tries to pull everything anew
Test And Build / Lint (push) Failing after 12s
Test And Build / Build (push) Failing after 3s
2025-07-04 13:54:24 +02:00
wall_e b206012df2 time to build
Test And Build / Build (push) Failing after 5s
2025-07-04 12:57:23 +02:00
wall_e 21ec7e8467 time to build
Test And Build / Build (push) Failing after 5s
2025-07-04 12:55:24 +02:00
wall_e 398bc8241a time to build
Test And Build / Build (push) Failing after 4s
2025-07-04 12:53:13 +02:00
wall_e 8ca684604d typo
Test And Build / Build (push) Successful in 3s
2025-07-04 12:51:04 +02:00
wall_e 72fe2b3681 it should already be there it is now a submodule...
Test And Build / Build (push) Failing after 3s
2025-07-04 12:50:28 +02:00
wall_e 5911e62029 :)
Test And Build / Build (push) Failing after 40s
2025-07-04 12:45:16 +02:00
wall_e 682024091f is the url wrong ?
Test And Build / Build (push) Failing after 31s
2025-07-04 12:43:33 +02:00
wall_e 335de72bc5 maybe a key is necessary
Test And Build / Build (push) Failing after 39s
2025-07-04 12:38:57 +02:00
wall_e 8e5055d6b8 Can I check out another repository?
Test And Build / Build (push) Failing after 31s
2025-07-04 12:31:40 +02:00
wall_e 1cab6e14ff Can I check out another repository?
Test And Build / Lint (push) Failing after 3s
Test And Build / Build (push) Failing after 40s
2025-07-04 12:30:53 +02:00
mathis_s 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
mathis_s 6b91ab6d51 Links in README.md updated to point to Gitea now. 2025-06-26 13:56:57 +02:00
mathis_s f423002d23 Updated sinqMotor 2025-06-18 08:26:49 +02:00
mathis_s 79ec79fac1 Updated sinqMotor 2025-06-18 08:18:53 +02:00
mathis_s 1703542770 Use new sinqMotor version 2025-06-17 13:16:20 +02:00
mathis_s c7d1dc4930 Added getAxisParam variant for char arrays 2025-06-17 10:25:02 +02:00
mathis_s 6fd3848f13 Fixed template for char arrays 2025-06-17 08:45:07 +02:00
mathis_s 56f08f3c76 Fixed template error in sinqMotor 2025-06-17 08:41:07 +02:00
mathis_s 168bfae983 Updated sinqMotor 2025-06-17 08:34:07 +02:00
mathis_s 0e29750d13 Updated sinqMotor version 2025-06-16 16:18:06 +02:00
mathis_s ba5b921aca Committed new sinqMotor version 2025-06-16 15:55:40 +02:00
mathis_s 1b810fb353 Adjusted dependency to use AxisParamChecked branch 2025-06-16 15:26:44 +02:00
mathis_s 4bc3388bc6 Added destructor for controller 2025-06-10 14:58:59 +02:00
mathis_s c759156058 Added destructor for controller 2025-06-10 14:53:26 +02:00
mathis_s eca513f3a0 Updated sinqMotor version to 1.1 2025-06-10 14:11:48 +02:00
mathis_s 26175290bf Added flag to disable reading the limits from the hardware 2025-06-10 13:53:39 +02:00
mathis_s e316fcf67b Changed priority of IOC shell message 2025-06-06 11:20:50 +02:00
mathis_s 6cf00adb60 Ready for release 1.0 2025-05-23 12:27:31 +02:00
mathis_s 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
mathis_s 8dd1dc4af2 Fixed poller bug in sinqMotor 2025-05-23 11:20:20 +02:00
mathis_s a758db1211 Change to latest sinqMotor version 2025-05-23 10:11:27 +02:00
mathis_s a11d10cb6c Updated sinqMotor to 0.15.2 2025-05-16 16:03:30 +02:00
mathis_s ba353c4e5d Fixed remote git link in repo. 2025-05-16 15:58:17 +02:00
mathis_s 55b523ddaa Made some functions virtual so they can be overwritten in subclasses 2025-05-15 14:54:18 +02:00
mathis_s 75292a6a9c Fixed some merge bugs 2025-05-15 12:32:30 +02:00
mathis_s 53bbe2aae8 Merge branch 'static-dep' 2025-05-15 12:27:26 +02:00
mathis_s 1597dc34e0 Added default value for motorMessageText 2025-05-15 12:25:08 +02:00
mathis_s dde7066f40 Use latest version of sinqMotor 2025-05-15 11:41:53 +02:00
mathis_s b4d6447b32 Fixed serious bug in sinqMotor 2025-05-15 11:29:13 +02:00
mathis_s 2f83060ec1 Addes error message for failing to enable / disable within timeout 2025-05-14 16:26:55 +02:00
mathis_s a3e3a79788 Adjusted usage of motorMessageText to act as an error message only. 2025-05-14 16:17:14 +02:00
mathis_s 2c5fdc7d0a Use new version of sinqMotor 2025-05-14 16:13:10 +02:00
mathis_s 7bf31ac256 Allow enabling / disabling the motor regardless of the status returned by the poll 2025-05-13 14:44:24 +02:00
mathis_s 47e72d65a9 Fixed small inaccuracy in the README 2025-05-12 17:04:09 +02:00
mathis_s 5298b5ef69 Fixed typo 2025-05-12 16:59:59 +02:00
mathis_s 29f23216ad Added some comments that this library now uses sinqMotor as static
dependency.
2025-05-12 16:43:57 +02:00
mathis_s 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
mathis_s 87d3cbb3eb Specified new version for sinqMotor 2025-05-12 12:00:49 +02:00
mathis_s 66552d5ffc Pinned sinqMotor version 2025-05-12 11:58:56 +02:00
mathis_s 253f65b25b Added sinqMotor as a submodule for static linking 2025-05-12 08:52:10 +02:00
8 changed files with 69 additions and 112 deletions
-8
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
+1 -2
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 -Wunused-result -Werror -fvisibility=hidden # -Wpedantic // Does not work because EPICS macros trigger warnings
+12 -34
View File
@@ -4,26 +4,15 @@
## 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
@@ -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,22 +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://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.
Binary file not shown.
Submodule
+1
Submodule sinqMotor added at cff64f5ecf
+31 -39
View File
@@ -143,6 +143,7 @@ asynStatus turboPmacAxis::init() {
// Offset time for the movement watchdog caused by the air cushions in
// milliseconds.
int acoDelay = 0.0;
int axStatus = 0;
// The parameter library takes some time to be initialized. Therefore we
// wait until the status is not asynParamUndefined anymore.
@@ -176,9 +177,11 @@ asynStatus turboPmacAxis::init() {
Ixx65.
*/
snprintf(command, sizeof(command),
"Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 Q%2.2d00 I%2.2d65",
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_);
status = pC_->writeRead(axisNo_, command, response, 7);
"P%2.2d00 Q%2.2d10 Q%2.2d03 Q%2.2d04 Q%2.2d06 P%2.2d22 Q%2.2d00 "
"I%2.2d65",
axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_, axisNo_,
axisNo_);
status = pC_->writeRead(axisNo_, command, response, 8);
if (status != asynSuccess) {
asynPrint(
pC_->pasynUser(), ASYN_TRACE_ERROR,
@@ -190,9 +193,9 @@ asynStatus turboPmacAxis::init() {
pC_->portName, axisNo(), __PRETTY_FUNCTION__, __LINE__);
pTurboPmacA_->needInit = true;
}
nvals = sscanf(response, "%lf %lf %lf %lf %d %lf %lf", &motorPos,
&motorVmax, &motorVelocity, &motorAccel, &acoDelay,
&counts_to_eu, &deadband_counts);
nvals = sscanf(response, "%d %lf %lf %lf %lf %d %lf %lf", &axStatus,
&motorPos, &motorVmax, &motorVelocity, &motorAccel,
&acoDelay, &counts_to_eu, &deadband_counts);
// The acoDelay is given in milliseconds -> Convert to seconds, rounded up
setOffsetMovTimeout(std::ceil(acoDelay / 1000.0));
@@ -202,7 +205,7 @@ asynStatus turboPmacAxis::init() {
// here to mm/s^2.
motorAccel = motorAccel * 1000;
if (nvals != 7) {
if (nvals != 8) {
return pC_->couldNotParseResponse(command, response, axisNo_,
__PRETTY_FUNCTION__, __LINE__);
}
@@ -552,6 +555,11 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
errorStatus = handleError(error, userMessage, sizeof(userMessage));
// Update the parameter library
if (error != 0) {
setAxisParamChecked(this, motorStatusProblem, true);
}
if (*moving == false) {
setAxisParamChecked(this, motorMoveToHome, false);
}
@@ -620,18 +628,16 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
if (pC_->getMsgPrintControl().shouldBePrinted(
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, true,
pC_->pasynUser())) {
asynPrint(
pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nLost feedback "
"from auxiliary device during movement (P%2.2d01 = %d).%s\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
error, pC_->getMsgPrintControl().getSuffix());
asynPrint(pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nAir cushion "
"feedback stopped during movement (P%2.2d01 = %d).%s\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
axisNo_, error, pC_->getMsgPrintControl().getSuffix());
}
snprintf(
userMessage, sizeUserMessage,
"Lost feedback from auxiliary device during movement (P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
snprintf(userMessage, sizeUserMessage,
"Air cushion feedback stopped during movement (P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 9:
@@ -640,17 +646,16 @@ asynStatus turboPmacAxis::handleError(int error, char *userMessage,
pC_->pasynUser())) {
asynPrint(
pC_->pasynUser(), ASYN_TRACE_ERROR,
"Controller \"%s\", axis %d => %s, line %d\nNo feedback from "
"auxiliary device before movement (P%2.2d01 = %d).%s\n",
"Controller \"%s\", axis %d => %s, line %d\nNo air cushion "
"feedback before movement start (P%2.2d01 = %d).%s\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
error, pC_->getMsgPrintControl().getSuffix());
}
snprintf(
userMessage, sizeUserMessage,
"No feedback from auxiliary device before movement (P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
snprintf(userMessage, sizeUserMessage,
"No air cushion feedback before movement start (P%2.2d01 = "
"%d). Please call the support.",
axisNo_, error);
setAxisParamChecked(this, motorMessageText, userMessage);
break;
case 10:
@@ -790,10 +795,6 @@ asynStatus turboPmacAxis::doMove(double position, int relative,
// =========================================================================
// Suppress unused variables warning
(void)minVelocity;
(void)acceleration;
getAxisParamChecked(this, motorEnableRBV, &enabled);
getAxisParamChecked(this, motorRecResolution, &motorRecResolution);
@@ -882,9 +883,6 @@ 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);
@@ -949,7 +947,7 @@ asynStatus turboPmacAxis::doReset() {
/*
Home the axis. On absolute encoder systems, this is a no-op
*/
asynStatus turboPmacAxis::doHome(double minVelocity, double maxVelocity,
asynStatus turboPmacAxis::doHome(double min_velocity, double max_velocity,
double acceleration, int forwards) {
// Status of read-write-operations of ASCII commands to the controller
@@ -960,12 +958,6 @@ asynStatus turboPmacAxis::doHome(double minVelocity, double maxVelocity,
// =========================================================================
// 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
+12 -16
View File
@@ -13,10 +13,6 @@ class HIDDEN turboPmacAxis : public sinqAxis {
*
* @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);
@@ -28,18 +24,6 @@ class HIDDEN turboPmacAxis : public sinqAxis {
*/
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 +70,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.
*
+12 -13
View File
@@ -61,17 +61,17 @@ turboPmacController::turboPmacController(const char *portName,
- REREAD_ENCODER_POSITION
- READ_CONFIG
*/
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
})) {
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},
});
// Initialization of local variables
asynStatus status = asynSuccess;
@@ -573,8 +573,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);