Compare commits
19 Commits
0.15.2
...
f423002d23
Author | SHA1 | Date | |
---|---|---|---|
f423002d23 | |||
79ec79fac1 | |||
1703542770 | |||
c7d1dc4930 | |||
6fd3848f13 | |||
56f08f3c76 | |||
168bfae983 | |||
0e29750d13 | |||
ba5b921aca | |||
1b810fb353 | |||
4bc3388bc6 | |||
c759156058 | |||
eca513f3a0 | |||
26175290bf | |||
e316fcf67b | |||
6cf00adb60 | |||
9710d442b8 | |||
8dd1dc4af2 | |||
a758db1211 |
@ -31,3 +31,14 @@ record(longout, "$(INSTR)FlushHardware") {
|
|||||||
field(PINI, "NO")
|
field(PINI, "NO")
|
||||||
field(VAL, "1")
|
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)")
|
||||||
|
}
|
Submodule sinqMotor updated: 275672aaef...55a9fe6f3e
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,10 @@
|
|||||||
#ifndef turboPmacAXIS_H
|
#ifndef turboPmacAXIS_H
|
||||||
#define turboPmacAXIS_H
|
#define turboPmacAXIS_H
|
||||||
#include "sinqAxis.h"
|
#include "sinqController.h"
|
||||||
|
#include "turboPmacController.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
struct turboPmacAxisImpl;
|
||||||
// between the controller and the axis .h-file. See
|
|
||||||
// https://en.cppreference.com/w/cpp/language/class.
|
|
||||||
class turboPmacController;
|
|
||||||
|
|
||||||
class turboPmacAxis : public sinqAxis {
|
class turboPmacAxis : public sinqAxis {
|
||||||
public:
|
public:
|
||||||
@ -21,6 +20,7 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Destroy the turboPmacAxis
|
* @brief Destroy the turboPmacAxis
|
||||||
*
|
*
|
||||||
|
* This destructor is necessary in order to use the PIMPL idiom.
|
||||||
*/
|
*/
|
||||||
virtual ~turboPmacAxis();
|
virtual ~turboPmacAxis();
|
||||||
|
|
||||||
@ -123,14 +123,29 @@ class turboPmacAxis : public sinqAxis {
|
|||||||
*/
|
*/
|
||||||
asynStatus handleError(int error, char *userMessage, int sizeUserMessage);
|
asynStatus handleError(int error, char *userMessage, int sizeUserMessage);
|
||||||
|
|
||||||
protected:
|
/**
|
||||||
|
* @brief Check if the axis needs to run its initialization function
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
* @return false
|
||||||
|
*/
|
||||||
|
bool needInit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Instruct the axis to run its init() function during the next poll
|
||||||
|
*
|
||||||
|
* @param needInit
|
||||||
|
*/
|
||||||
|
void setNeedInit(bool needInit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return a pointer to the axis controller
|
||||||
|
*/
|
||||||
|
virtual turboPmacController *pController() override { return pC_; };
|
||||||
|
|
||||||
|
private:
|
||||||
turboPmacController *pC_;
|
turboPmacController *pC_;
|
||||||
|
std::unique_ptr<turboPmacAxisImpl> pTurboPmacA_;
|
||||||
bool waitForHandshake_;
|
|
||||||
time_t timeAtHandshake_;
|
|
||||||
|
|
||||||
// The axis status is used when enabling / disabling the motor
|
|
||||||
int axisStatus_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,24 @@ void adjustResponseForPrint(char *dst, const char *src, size_t buf_length) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct turboPmacControllerImpl {
|
||||||
|
|
||||||
|
// Timeout for the communication process in seconds
|
||||||
|
double comTimeout;
|
||||||
|
|
||||||
|
char lastResponse[sinqController::MAXBUF_];
|
||||||
|
|
||||||
|
// User for writing int32 values to the port driver.
|
||||||
|
asynUser *pasynInt32SyncIOipPort;
|
||||||
|
|
||||||
|
// Indices of additional PVs
|
||||||
|
int rereadEncoderPosition;
|
||||||
|
int readConfig;
|
||||||
|
int flushHardware;
|
||||||
|
int limFromHardware;
|
||||||
|
};
|
||||||
|
#define NUM_turboPmac_DRIVER_PARAMS 3
|
||||||
|
|
||||||
turboPmacController::turboPmacController(const char *portName,
|
turboPmacController::turboPmacController(const char *portName,
|
||||||
const char *ipPortConfigName,
|
const char *ipPortConfigName,
|
||||||
int numAxes, double movingPollPeriod,
|
int numAxes, double movingPollPeriod,
|
||||||
@ -47,21 +65,25 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// The paramLib indices are populated with the calls to createParam
|
||||||
|
pTurboPmacC_ =
|
||||||
|
std::make_unique<turboPmacControllerImpl>((turboPmacControllerImpl){
|
||||||
|
.comTimeout = comTimeout,
|
||||||
|
.lastResponse = {0},
|
||||||
|
});
|
||||||
|
|
||||||
// Initialization of local variables
|
// Initialization of local variables
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
|
|
||||||
// Initialization of all member variables
|
|
||||||
comTimeout_ = comTimeout;
|
|
||||||
|
|
||||||
// Maximum allowed number of subsequent timeouts before the user is
|
// Maximum allowed number of subsequent timeouts before the user is
|
||||||
// informed.
|
// informed.
|
||||||
maxSubsequentTimeouts_ = 10;
|
setMaxSubsequentTimeouts(10);
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Create additional parameter library entries
|
// Create additional parameter library entries
|
||||||
|
|
||||||
status = createParam("REREAD_ENCODER_POSITION", asynParamInt32,
|
status = createParam("REREAD_ENCODER_POSITION", asynParamInt32,
|
||||||
&rereadEncoderPosition_);
|
&pTurboPmacC_->rereadEncoderPosition);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||||
@ -71,7 +93,8 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = createParam("READ_CONFIG", asynParamInt32, &readConfig_);
|
status =
|
||||||
|
createParam("READ_CONFIG", asynParamInt32, &pTurboPmacC_->readConfig);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||||
@ -81,7 +104,19 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = createParam("FLUSH_HARDWARE", asynParamInt32, &flushHardware_);
|
status = createParam("FLUSH_HARDWARE", asynParamInt32,
|
||||||
|
&pTurboPmacC_->flushHardware);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = createParam("LIM_FROM_HARDWARE", asynParamInt32,
|
||||||
|
&pTurboPmacC_->limFromHardware);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
"Controller \"%s\" => %s, line %d\nFATAL ERROR (creating a "
|
||||||
@ -100,7 +135,7 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
const char *message_from_device =
|
const char *message_from_device =
|
||||||
"\006"; // Hex-code for ACK (acknowledge) -> Each message from the MCU
|
"\006"; // Hex-code for ACK (acknowledge) -> Each message from the MCU
|
||||||
// is terminated by this value
|
// is terminated by this value
|
||||||
status = pasynOctetSyncIO->setInputEos(pasynOctetSyncIOipPort_,
|
status = pasynOctetSyncIO->setInputEos(pasynOctetSyncIOipPort(),
|
||||||
message_from_device,
|
message_from_device,
|
||||||
strlen(message_from_device));
|
strlen(message_from_device));
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
@ -109,7 +144,7 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
"(setting input EOS failed with %s).\nTerminating IOC",
|
"(setting input EOS failed with %s).\nTerminating IOC",
|
||||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||||
stringifyAsynStatus(status));
|
stringifyAsynStatus(status));
|
||||||
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort_);
|
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +156,7 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
"with %s).\nTerminating IOC",
|
"with %s).\nTerminating IOC",
|
||||||
portName, __PRETTY_FUNCTION__, __LINE__,
|
portName, __PRETTY_FUNCTION__, __LINE__,
|
||||||
stringifyAsynStatus(status));
|
stringifyAsynStatus(status));
|
||||||
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort_);
|
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,17 +166,21 @@ turboPmacController::turboPmacController(const char *portName,
|
|||||||
We try to connect to the port via the port name provided by the constructor.
|
We try to connect to the port via the port name provided by the constructor.
|
||||||
If this fails, the function is terminated via exit.
|
If this fails, the function is terminated via exit.
|
||||||
*/
|
*/
|
||||||
pasynInt32SyncIO->connect(ipPortConfigName, 0, &pasynInt32SyncIOipPort_,
|
pasynInt32SyncIO->connect(ipPortConfigName, 0,
|
||||||
NULL);
|
&pTurboPmacC_->pasynInt32SyncIOipPort, NULL);
|
||||||
if (status != asynSuccess || pasynInt32SyncIOipPort_ == nullptr) {
|
if (status != asynSuccess ||
|
||||||
|
pTurboPmacC_->pasynInt32SyncIOipPort == nullptr) {
|
||||||
errlogPrintf("Controller \"%s\" => %s, line %d:\nFATAL ERROR (cannot "
|
errlogPrintf("Controller \"%s\" => %s, line %d:\nFATAL ERROR (cannot "
|
||||||
"connect to MCU controller).\n"
|
"connect to MCU controller).\n"
|
||||||
"Terminating IOC",
|
"Terminating IOC",
|
||||||
portName, __PRETTY_FUNCTION__, __LINE__);
|
portName, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
pasynOctetSyncIO->disconnect(pasynOctetSyncIOipPort());
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
turboPmacController::~turboPmacController() {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Access one of the axes of the controller via the axis adress stored in asynUser.
|
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
|
If the axis does not exist or is not a Axis, a nullptr is returned and an
|
||||||
@ -167,7 +206,6 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
|
|
||||||
// Definition of local variables.
|
// Definition of local variables.
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
asynStatus paramLibStatus = asynSuccess;
|
|
||||||
asynStatus timeoutStatus = asynSuccess;
|
asynStatus timeoutStatus = asynSuccess;
|
||||||
// char fullCommand[MAXBUF_] = {0};
|
// char fullCommand[MAXBUF_] = {0};
|
||||||
char drvMessageText[MAXBUF_] = {0};
|
char drvMessageText[MAXBUF_] = {0};
|
||||||
@ -215,20 +253,20 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
*/
|
*/
|
||||||
status = pasynOctetSyncIO->writeRead(
|
status = pasynOctetSyncIO->writeRead(
|
||||||
pasynOctetSyncIOipPort(), command, commandLength, response, MAXBUF_,
|
pasynOctetSyncIOipPort(), command, commandLength, response, MAXBUF_,
|
||||||
comTimeout_, &nbytesOut, &nbytesIn, &eomReason);
|
pTurboPmacC_->comTimeout, &nbytesOut, &nbytesIn, &eomReason);
|
||||||
|
|
||||||
msgPrintControlKey comKey =
|
msgPrintControlKey comKey =
|
||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
if (status == asynTimeout) {
|
if (status == asynTimeout) {
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(comKey, true, pasynUser())) {
|
if (getMsgPrintControl().shouldBePrinted(comKey, true, pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUser(), ASYN_TRACE_ERROR,
|
this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
"Controller \"%s\", axis %d => %s, line %d\nTimeout while "
|
||||||
"writing to the controller. Retrying ...%s\n",
|
"writing to the controller. Retrying ...%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
msgPrintControl_.getSuffix());
|
getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
timeoutStatus = checkComTimeoutWatchdog(axisNo, drvMessageText,
|
||||||
@ -239,13 +277,14 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
checkMaxSubsequentTimeouts(timeoutCounter, axis);
|
checkMaxSubsequentTimeouts(timeoutCounter, axis);
|
||||||
timeoutCounter += 1;
|
timeoutCounter += 1;
|
||||||
|
|
||||||
if (maxSubsequentTimeoutsExceeded_) {
|
if (maxSubsequentTimeoutsExceeded()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = pasynOctetSyncIO->writeRead(
|
status = pasynOctetSyncIO->writeRead(
|
||||||
pasynOctetSyncIOipPort(), command, commandLength, response,
|
pasynOctetSyncIOipPort(), command, commandLength, response,
|
||||||
MAXBUF_, comTimeout_, &nbytesOut, &nbytesIn, &eomReason);
|
MAXBUF_, pTurboPmacC_->comTimeout, &nbytesOut, &nbytesIn,
|
||||||
|
&eomReason);
|
||||||
if (status != asynTimeout) {
|
if (status != asynTimeout) {
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
@ -255,16 +294,28 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (status != asynSuccess) {
|
} else if (status != asynSuccess) {
|
||||||
if (msgPrintControl_.shouldBePrinted(comKey, true, pasynUser())) {
|
if (getMsgPrintControl().shouldBePrinted(comKey, true, pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUser(), ASYN_TRACE_ERROR,
|
this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
"Controller \"%s\", axis %d => %s, line %d\nError %s while "
|
||||||
"writing to the controller.%s\n",
|
"writing to the controller.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
stringifyAsynStatus(status), msgPrintControl_.getSuffix());
|
stringifyAsynStatus(status), getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(comKey, pasynUser());
|
getMsgPrintControl().resetCount(comKey, pasynUser());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
/*
|
||||||
|
Since the communication failed, there is the possibility that the
|
||||||
|
controller is not connected at all to the network. In that case, we
|
||||||
|
cannot be sure that the information read out in the init method of the
|
||||||
|
axis is still up-to-date the next time we get a connection. Therefore,
|
||||||
|
an info flag is set which the axis object can use at the start of its
|
||||||
|
poll method to try to initialize itself.
|
||||||
|
*/
|
||||||
|
axis->setNeedInit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeoutStatus == asynError) {
|
if (timeoutStatus == asynError) {
|
||||||
@ -301,16 +352,17 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
"string detected\"). Please call the support.",
|
"string detected\"). Please call the support.",
|
||||||
reasonStringified);
|
reasonStringified);
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(terminateKey, true, pasynUser())) {
|
if (getMsgPrintControl().shouldBePrinted(terminateKey, true,
|
||||||
|
pasynUser())) {
|
||||||
|
|
||||||
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
"Controller \"%s\", axis %d => %s, line %d\nMessage "
|
||||||
"terminated due to reason %s.%s\n",
|
"terminated due to reason %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
reasonStringified, msgPrintControl_.getSuffix());
|
reasonStringified, getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(terminateKey, pasynUser());
|
getMsgPrintControl().resetCount(terminateKey, pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -327,15 +379,15 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
if (numExpectedResponses != numReceivedResponses) {
|
if (numExpectedResponses != numReceivedResponses) {
|
||||||
adjustResponseForPrint(modResponse, response, MAXBUF_);
|
adjustResponseForPrint(modResponse, response, MAXBUF_);
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(numResponsesKey, true,
|
if (getMsgPrintControl().shouldBePrinted(numResponsesKey, true,
|
||||||
pasynUser())) {
|
pasynUser())) {
|
||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUser(), ASYN_TRACE_ERROR,
|
this->pasynUser(), ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
"Controller \"%s\", axis %d => %s, line %d\nUnexpected "
|
||||||
"response '%s' (carriage returns are replaced with spaces) "
|
"response '%s' (carriage returns are replaced with spaces) "
|
||||||
"for command %s.%s\n",
|
"for command %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__, modResponse,
|
||||||
command, msgPrintControl_.getSuffix());
|
command, getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(drvMessageText, sizeof(drvMessageText),
|
snprintf(drvMessageText, sizeof(drvMessageText),
|
||||||
@ -345,7 +397,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
modResponse, command);
|
modResponse, command);
|
||||||
status = asynError;
|
status = asynError;
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(numResponsesKey, pasynUser());
|
getMsgPrintControl().resetCount(numResponsesKey, pasynUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create custom error messages for different failure modes, if no error
|
// Create custom error messages for different failure modes, if no error
|
||||||
@ -375,41 +427,18 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
|
|||||||
|
|
||||||
// Log the overall status (communication successfull or not)
|
// Log the overall status (communication successfull or not)
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
paramLibStatus = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
setAxisParamChecked(axis, motorStatusCommsError, false);
|
||||||
} else {
|
} else {
|
||||||
// Check if the axis already is in an error communication mode. If
|
// Check if the axis already is in an error communication mode. If
|
||||||
// it is not, upstream the error. This is done to avoid "flooding"
|
// it is not, upstream the error. This is done to avoid "flooding"
|
||||||
// the user with different error messages if more than one error
|
// the user with different error messages if more than one error
|
||||||
// ocurred before an error-free communication
|
// ocurred before an error-free communication
|
||||||
paramLibStatus =
|
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
|
||||||
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
|
||||||
if (paramLibStatus != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(paramLibStatus, "motorStatusProblem_",
|
|
||||||
axisNo, __PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (motorStatusProblem == 0) {
|
if (motorStatusProblem == 0) {
|
||||||
paramLibStatus =
|
setAxisParamChecked(axis, motorMessageText, drvMessageText);
|
||||||
axis->setStringParam(motorMessageText_, drvMessageText);
|
setAxisParamChecked(axis, motorStatusProblem, true);
|
||||||
if (paramLibStatus != asynSuccess) {
|
setAxisParamChecked(axis, motorStatusCommsError, true);
|
||||||
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__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -421,13 +450,13 @@ asynStatus turboPmacController::doFlushHardware() {
|
|||||||
constant defined in pmacAsynIPPort.c. This reason is then used within
|
constant defined in pmacAsynIPPort.c. This reason is then used within
|
||||||
the write method of pasynInt32SyncIO to select the flush function.
|
the write method of pasynInt32SyncIO to select the flush function.
|
||||||
*/
|
*/
|
||||||
int temp = pasynInt32SyncIOipPort_->reason;
|
int temp = pTurboPmacC_->pasynInt32SyncIOipPort->reason;
|
||||||
pasynInt32SyncIOipPort_->reason = FLUSH_HARDWARE;
|
pTurboPmacC_->pasynInt32SyncIOipPort->reason = FLUSH_HARDWARE;
|
||||||
asynStatus status = (asynStatus)pasynInt32SyncIO->write(
|
asynStatus status = (asynStatus)pasynInt32SyncIO->write(
|
||||||
pasynInt32SyncIOipPort_, 1, comTimeout_);
|
pTurboPmacC_->pasynInt32SyncIOipPort, 1, pTurboPmacC_->comTimeout);
|
||||||
|
|
||||||
// Reset the status afterwards
|
// Reset the status afterwards
|
||||||
pasynInt32SyncIOipPort_->reason = temp;
|
pTurboPmacC_->pasynInt32SyncIOipPort->reason = temp;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,11 +469,11 @@ asynStatus turboPmacController::writeInt32(asynUser *pasynUser,
|
|||||||
turboPmacAxis *axis = getTurboPmacAxis(pasynUser);
|
turboPmacAxis *axis = getTurboPmacAxis(pasynUser);
|
||||||
|
|
||||||
// Handle custom PVs
|
// Handle custom PVs
|
||||||
if (function == rereadEncoderPosition_) {
|
if (function == rereadEncoderPosition()) {
|
||||||
return axis->rereadEncoder();
|
return axis->rereadEncoder();
|
||||||
} else if (function == readConfig_) {
|
} else if (function == readConfig()) {
|
||||||
return axis->init();
|
return axis->init();
|
||||||
} else if (function == flushHardware_) {
|
} else if (function == flushHardware()) {
|
||||||
return doFlushHardware();
|
return doFlushHardware();
|
||||||
} else {
|
} else {
|
||||||
return sinqController::writeInt32(pasynUser, value);
|
return sinqController::writeInt32(pasynUser, value);
|
||||||
@ -462,6 +491,19 @@ asynStatus turboPmacController::couldNotParseResponse(const char *command,
|
|||||||
command, modifiedResponse, axisNo, functionName, lineNumber);
|
command, modifiedResponse, axisNo, functionName, lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int turboPmacController::rereadEncoderPosition() {
|
||||||
|
return pTurboPmacC_->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;
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************************/
|
/*************************************************************************************/
|
||||||
/** The following functions are C-wrappers, and can be called directly from
|
/** The following functions are C-wrappers, and can be called directly from
|
||||||
* iocsh */
|
* iocsh */
|
||||||
|
@ -10,7 +10,14 @@
|
|||||||
#define turboPmacController_H
|
#define turboPmacController_H
|
||||||
#include "sinqAxis.h"
|
#include "sinqAxis.h"
|
||||||
#include "sinqController.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 {
|
class turboPmacController : public sinqController {
|
||||||
public:
|
public:
|
||||||
@ -33,6 +40,13 @@ class turboPmacController : public sinqController {
|
|||||||
double idlePollPeriod, double comTimeout,
|
double idlePollPeriod, double comTimeout,
|
||||||
int numExtraParams = 0);
|
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
|
* @brief Get the axis object
|
||||||
*
|
*
|
||||||
@ -116,29 +130,17 @@ class turboPmacController : public sinqController {
|
|||||||
asynStatus doFlushHardware();
|
asynStatus doFlushHardware();
|
||||||
|
|
||||||
// Accessors for additional PVs
|
// Accessors for additional PVs
|
||||||
int rereadEncoderPosition() { return rereadEncoderPosition_; }
|
int rereadEncoderPosition();
|
||||||
int readConfig() { return readConfig_; }
|
int readConfig();
|
||||||
int flushHardware() { return flushHardware_; }
|
int flushHardware();
|
||||||
|
int limFromHardware();
|
||||||
|
|
||||||
asynUser *pasynInt32SyncIOipPort() { return pasynInt32SyncIOipPort_; }
|
asynUser *pasynInt32SyncIOipPort();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<turboPmacControllerImpl> pTurboPmacC_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Timeout for the communication process in seconds
|
|
||||||
double comTimeout_;
|
|
||||||
|
|
||||||
char lastResponse[MAXBUF_];
|
|
||||||
|
|
||||||
// User for writing int32 values to the port driver.
|
|
||||||
asynUser *pasynInt32SyncIOipPort_;
|
|
||||||
|
|
||||||
// Indices of additional PVs
|
|
||||||
#define FIRST_turboPmac_PARAM rereadEncoderPosition_
|
|
||||||
int rereadEncoderPosition_;
|
|
||||||
int readConfig_;
|
|
||||||
int flushHardware_;
|
|
||||||
#define LAST_turboPmac_PARAM flushHardware_
|
|
||||||
};
|
};
|
||||||
#define NUM_turboPmac_DRIVER_PARAMS \
|
|
||||||
(&LAST_turboPmac_PARAM - &FIRST_turboPmac_PARAM + 1)
|
|
||||||
|
|
||||||
#endif /* turboPmacController_H */
|
#endif /* turboPmacController_H */
|
||||||
|
Reference in New Issue
Block a user