Fixed a bug in readInt32 and prepared the turboPmac library to serve the

detectorTower library
This commit is contained in:
2025-02-26 14:08:37 +01:00
parent 4c104cb90c
commit 8f597550fa
6 changed files with 74 additions and 52 deletions

View File

@ -14,7 +14,7 @@ REQUIRED+=sinqMotor
motorBase_VERSION=7.2.2
# Specify the version of sinqMotor we want to build against
sinqMotor_VERSION=0.7.0
sinqMotor_VERSION=mathis_s
# These headers allow to depend on this library for derived drivers.
HEADERS += src/turboPmacAxis.h

View File

@ -17,25 +17,45 @@ The folder "utils" contains utility scripts for working with pmac motor controll
### Usage in IOC shell
turboPmac exposes the following IOC shell functions (all in turboPmacController.cpp):
turboPmac exports the following IOC shell functions:
- `turboPmacController`: Create a new controller object.
- `turboPmacAxis`: Create a new axis object.
These functions are parametrized as follows:
The full mcu.cmd file looks like this:
```
turboPmacController(
"$(NAME)", # Name of the MCU, e.g. mcu1. This parameter should be provided by an environment variable.
"$(ASYN_PORT)", # IP-Port of the MCU. This parameter should be provided by an environment variable.
8, # Maximum number of axes
0.05, # Busy poll period in seconds
1, # Idle poll period in seconds
0.05 # Communication timeout in seconds
);
```
```
turboPmacAxis(
"$(NAME)", # Name of the associated MCU, e.g. mcu1. This parameter should be provided by an environment variable.
1 # Index of the axis.
);
# Define the name of the controller and the corresponding port
epicsEnvSet("NAME","mcu")
epicsEnvSet("ASYN_PORT","p$(NAME)")
# 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
drvAsynIPPortConfigure("$(ASYN_PORT)","172.28.101.24:1025")
# Create the controller object with the defined name and connect it to the socket via the port name.
# The other parameters are as follows:
# 8: Maximum number of axes
# 0.05: Busy poll period in seconds
# 1: Idle poll period in seconds
# 1: Socket communication timeout in seconds
turboPmacController("$(NAME)", "$(ASYN_PORT)", 8, 0.05, 1, 1);
# Define some axes for the specified MCU at the given slot (1, 2 and 5). No slot may be used twice!
turboPmacAxis("$(NAME)",1);
turboPmacAxis("$(NAME)",2);
turboPmacAxis("$(NAME)",5);
# Set the number of subsequent timeouts
setMaxSubsequentTimeouts("$(NAME)", 20);
# Configure the timeout frequency watchdog:
setThresholdComTimeout("$(NAME)", 100, 1);
# Parametrize the EPICS record database with the substitution file named after the MCU.
epicsEnvSet("SINQDBPATH","$(sinqMotor_DB)/sinqMotor.db")
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
epicsEnvSet("SINQDBPATH","$(turboPmac_DB)/turboPmac.db")
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
dbLoadRecords("$(sinqMotor_DB)/asynRecord.db","P=$(INSTR)$(NAME),PORT=$(ASYN_PORT)")
```
### Versioning

View File

@ -109,9 +109,6 @@ turboPmacAxis::~turboPmacAxis(void) {
// clean up the pointer pC here.
}
/**
Read the configuration at the first poll
*/
asynStatus turboPmacAxis::init() {
// Local variable declaration
@ -478,9 +475,11 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
"state P%2.2d00 = %d\n",
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
axStatus);
pl_status = setStringParam(
pC_->motorMessageText_,
"Unreachable state has been reached. Please call the support.");
snprintf(userMessage, sizeof(userMessage),
"Unknown state P%2.2d00 = %d has been reached. Please call "
"the support.",
axisNo_, error);
pl_status = setStringParam(pC_->motorMessageText_, userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
@ -675,11 +674,11 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__, axisNo_,
error);
snprintf(command, sizeof(command),
snprintf(userMessage, sizeof(userMessage),
"Move command exceeds hardware limits (P%2.2d01 = %d). Please "
"call the support.",
axisNo_, error);
pl_status = setStringParam(pC_->motorMessageText_, command);
pl_status = setStringParam(pC_->motorMessageText_, userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,
@ -695,9 +694,10 @@ asynStatus turboPmacAxis::doPoll(bool *moving) {
pC_->portName, axisNo_, __PRETTY_FUNCTION__, __LINE__,
axisNo_, error);
pl_status = setStringParam(
pC_->motorMessageText_,
"Unknown error P%2.2d01 = %d. Please call the support.");
snprintf(userMessage, sizeof(userMessage),
"Unknown error P%2.2d01 = %d. Please call the support.",
axisNo_, error);
pl_status = setStringParam(pC_->motorMessageText_, userMessage);
if (pl_status != asynSuccess) {
return pC_->paramLibAccessFailed(pl_status, "motorMessageText_",
axisNo_, __PRETTY_FUNCTION__,

View File

@ -3,7 +3,7 @@
#include "sinqAxis.h"
// Forward declaration of the controller class to resolve the cyclic dependency
// between C804Controller.h and C804Axis.h. See
// between the controller and the axis .h-file. See
// https://en.cppreference.com/w/cpp/language/class.
class turboPmacController;
@ -74,7 +74,7 @@ class turboPmacAxis : public sinqAxis {
* 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 accordint to the initial status of the axis.
* - Set the enable PV according to the initial status of the axis.
*
* @return asynStatus
*/

View File

@ -29,23 +29,11 @@ void adjustResponseForPrint(char *dst, const char *src, size_t buf_length) {
}
}
/**
* @brief Construct a new turboPmacController::turboPmacController object
*
* @param portName See documentation of sinqController
* @param ipPortConfigName See documentation of sinqController
* @param numAxes See documentation of sinqController
* @param movingPollPeriod See documentation of sinqController
* @param idlePollPeriod See documentation of sinqController
* @param comTimeout Time after which a communication timeout error
* is declared in writeRead (in seconds)
* @param extraParams See documentation of sinqController
*/
turboPmacController::turboPmacController(const char *portName,
const char *ipPortConfigName,
int numAxes, double movingPollPeriod,
double idlePollPeriod,
double comTimeout)
double comTimeout, int numExtraParams)
: sinqController(
portName, ipPortConfigName, numAxes, movingPollPeriod, idlePollPeriod,
/*
@ -53,7 +41,7 @@ turboPmacController::turboPmacController(const char *portName,
- REREAD_ENCODER_POSITION
- READ_CONFIG
*/
NUM_turboPmac_DRIVER_PARAMS)
numExtraParams + NUM_turboPmac_DRIVER_PARAMS)
{
@ -510,13 +498,14 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
}
}
asynStatus sinqController::readInt32(asynUser *pasynUser, epicsInt32 *value) {
asynStatus turboPmacController::readInt32(asynUser *pasynUser,
epicsInt32 *value) {
// PMACs can be disabled
if (pasynUser->reason == motorCanDisable_) {
*value = 1;
return asynSuccess;
} else {
return asynMotorController::readInt32(pasynUser, value);
return sinqController::readInt32(pasynUser, value);
}
}
@ -582,7 +571,7 @@ static const iocshArg CreateControllerArg5 = {"Communication timeout (s)",
static const iocshArg *const CreateControllerArgs[] = {
&CreateControllerArg0, &CreateControllerArg1, &CreateControllerArg2,
&CreateControllerArg3, &CreateControllerArg4, &CreateControllerArg5};
static const iocshFuncDef configturboPmacCreateController = {
static const iocshFuncDef configTurboPmacCreateController = {
"turboPmacController", 6, CreateControllerArgs};
static void configTurboPmacCreateControllerCallFunc(const iocshArgBuf *args) {
turboPmacCreateController(args[0].sval, args[1].sval, args[2].ival,
@ -592,7 +581,7 @@ static void configTurboPmacCreateControllerCallFunc(const iocshArgBuf *args) {
// This function is made known to EPICS in turboPmac.dbd and is called by EPICS
// in order to register both functions in the IOC shell
static void turboPmacControllerRegister(void) {
iocshRegister(&configturboPmacCreateController,
iocshRegister(&configTurboPmacCreateController,
configTurboPmacCreateControllerCallFunc);
}
epicsExportRegistrar(turboPmacControllerRegister);

View File

@ -13,10 +13,10 @@
#include "turboPmacAxis.h"
class turboPmacController : public sinqController {
public:
/**
* @brief Construct a new turboPmacController object
* @brief Construct a new turboPmacController object. This function is meant
to be called from a child class constructor.
*
* @param portName See sinqController constructor
* @param ipPortConfigName See sinqController constructor
@ -26,10 +26,12 @@ class turboPmacController : public sinqController {
* @param comTimeout When trying to communicate with the device,
the underlying asynOctetSyncIO interface waits for a response until this
time (in seconds) has passed, then it declares a timeout.
* @param numExtraParams Number of extra parameters from a child class
*/
turboPmacController(const char *portName, const char *ipPortConfigName,
int numAxes, double movingPollPeriod,
double idlePollPeriod, double comTimeout);
double idlePollPeriod, double comTimeout,
int numExtraParams = 0);
/**
* @brief Get the axis object
@ -49,6 +51,17 @@ class turboPmacController : public sinqController {
*/
turboPmacAxis *getAxis(int axisNo);
/**
* @brief Overloaded function of sinqController
*
* The function is overloaded in order to read motorCanDisable_
*
* @param pasynUser
* @param value
* @return asynStatus
*/
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
/**
* @brief Overloaded function of sinqController
*
@ -114,7 +127,7 @@ class turboPmacController : public sinqController {
const char *functionName,
int lineNumber);
private:
protected:
// 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.