Compare commits
29 Commits
static-dep
...
1.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 954fc82414 | |||
| ff183576ec | |||
| 83f9be3be8 | |||
| 2c0c9a33b7 | |||
| 8bb81b1716 | |||
| c32708e49c | |||
| 14a733fb67 | |||
| 64b932c3ae | |||
| 09897b6125 | |||
| 9d47cd4e24 | |||
| 52fa4e1e78 | |||
| a9e08460d9 | |||
| 37dacbd3ee | |||
| d198dc8c9f | |||
| 13f2ec4fbf | |||
| 6ccb60f263 | |||
| b8730e80e0 | |||
| deb6e6996e | |||
| d1d694ad6b | |||
| e0a74c5598 | |||
| c334ed9f04 | |||
| 4b0031c3af | |||
| 61335970ce | |||
| 081a21073b | |||
| f2e8eb2762 | |||
| e93f11e779 | |||
| 989410474e | |||
| 8d8561d833 | |||
| a56a8cf646 |
24
.gitea/workflows/action.yaml
Normal file
24
.gitea/workflows/action.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: Test And Build
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Lint:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: cppcheck
|
||||||
|
run: cppcheck --std=c++17 --addon=cert --addon=misc --error-exitcode=1 src/*.cpp
|
||||||
|
- name: formatting
|
||||||
|
run: clang-format --style=file --Werror --dry-run src/*.cpp
|
||||||
|
Build:
|
||||||
|
runs-on: linepics
|
||||||
|
steps:
|
||||||
|
- name: checkout repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: 'true'
|
||||||
|
- run: |
|
||||||
|
sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
|
||||||
|
echo -e "\nIGNORE_SUBMODULES += sinqmotor" >> Makefile
|
||||||
|
make install
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
default:
|
|
||||||
image: docker.psi.ch:5000/sinqdev/sinqepics:latest
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- lint
|
|
||||||
- build
|
|
||||||
- test
|
|
||||||
|
|
||||||
cppcheck:
|
|
||||||
stage: lint
|
|
||||||
script:
|
|
||||||
- cppcheck --std=c++17 --addon=cert --addon=misc --suppress=cert-STR07-C --error-exitcode=1 src/*.cpp
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
|
|
||||||
formatting:
|
|
||||||
stage: lint
|
|
||||||
script:
|
|
||||||
- clang-format --style=file --Werror --dry-run src/*.cpp
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
|
|
||||||
build_module:
|
|
||||||
stage: build
|
|
||||||
script:
|
|
||||||
- export SINQMOTOR_VERSION="$(grep 'sinqMotor_VERSION=' Makefile | cut -d= -f2)"
|
|
||||||
- git clone --depth 1 --branch "${SINQMOTOR_VERSION}" https://gitlab-ci-token:${CI_JOB_TOKEN}@git.psi.ch/sinq-epics-modules/sinqmotor.git
|
|
||||||
- pushd sinqmotor
|
|
||||||
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
|
|
||||||
- echo "LIBVERSION=${SINQMOTOR_VERSION}" >> Makefile
|
|
||||||
- make install
|
|
||||||
- popd
|
|
||||||
- sed -i 's/ARCH_FILTER=.*/ARCH_FILTER=linux%/' Makefile
|
|
||||||
- echo "LIBVERSION=${CI_COMMIT_TAG:-0.0.1}" >> Makefile
|
|
||||||
- make install
|
|
||||||
- cp -rT "/ioc/modules/masterMacs/$(ls -U /ioc/modules/masterMacs/ | head -1)" "./masterMacs-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
|
|
||||||
artifacts:
|
|
||||||
name: "masterMacs-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}"
|
|
||||||
paths:
|
|
||||||
- "masterMacs-${CI_COMMIT_TAG:-$CI_COMMIT_SHORT_SHA}/*"
|
|
||||||
expire_in: 1 week
|
|
||||||
when: always
|
|
||||||
tags:
|
|
||||||
- sinq
|
|
||||||
5
Makefile
5
Makefile
@@ -6,9 +6,6 @@ BUILDCLASSES=Linux
|
|||||||
EPICS_VERSIONS=7.0.7
|
EPICS_VERSIONS=7.0.7
|
||||||
ARCH_FILTER=RHEL%
|
ARCH_FILTER=RHEL%
|
||||||
|
|
||||||
# Additional module dependencies
|
|
||||||
REQUIRED+=sinqMotor
|
|
||||||
|
|
||||||
# Specify the version of asynMotor we want to build against
|
# Specify the version of asynMotor we want to build against
|
||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
@@ -31,4 +28,4 @@ TEMPLATES += sinqMotor/db/sinqMotor.db
|
|||||||
DBDS += sinqMotor/src/sinqMotor.dbd
|
DBDS += sinqMotor/src/sinqMotor.dbd
|
||||||
DBDS += src/masterMacs.dbd
|
DBDS += src/masterMacs.dbd
|
||||||
|
|
||||||
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Wpedantic -Wextra -Werror
|
USR_CFLAGS += -Wall -Wextra -Weffc++ -Wunused-result -Wextra -Werror
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ setThresholdComTimeout("$(NAME)", 100, 1);
|
|||||||
# 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","$(masterMacs_DB)/sinqMotor.db")
|
epicsEnvSet("SINQDBPATH","$(masterMacs_DB)/sinqMotor.db")
|
||||||
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
||||||
|
epicsEnvSet("SINQDBPATH","$(masterMacs_DB)/masterMacs.db")
|
||||||
|
dbLoadTemplate("$(TOP)/$(NAME).substitutions", "INSTR=$(INSTR)$(NAME):,CONTROLLER=$(NAME)")
|
||||||
dbLoadRecords("$(masterMacs_DB)/asynRecord.db","P=$(INSTR)$(NAME),PORT=$(ASYN_PORT)")
|
dbLoadRecords("$(masterMacs_DB)/asynRecord.db","P=$(INSTR)$(NAME),PORT=$(ASYN_PORT)")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -66,4 +68,4 @@ Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-e
|
|||||||
|
|
||||||
### How to build it
|
### 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.
|
Please see the documentation for the module sinqMotor: https://git.psi.ch/sinq-epics-modules/sinqmotor/-/blob/main/README.md.
|
||||||
|
|||||||
Submodule sinqMotor updated: 5689402375...c65a8de5dd
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,10 @@
|
|||||||
#ifndef masterMacsAXIS_H
|
#ifndef masterMacsAXIS_H
|
||||||
#define masterMacsAXIS_H
|
#define masterMacsAXIS_H
|
||||||
|
#include "masterMacsController.h"
|
||||||
#include "sinqAxis.h"
|
#include "sinqAxis.h"
|
||||||
#include <bitset>
|
#include <memory>
|
||||||
|
|
||||||
// Forward declaration of the controller class to resolve the cyclic dependency
|
struct masterMacsAxisImpl;
|
||||||
// between the controller and the axis .h-file. See
|
|
||||||
// https://en.cppreference.com/w/cpp/language/class.
|
|
||||||
class masterMacsController;
|
|
||||||
|
|
||||||
class masterMacsAxis : public sinqAxis {
|
class masterMacsAxis : public sinqAxis {
|
||||||
public:
|
public:
|
||||||
@@ -105,22 +103,25 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
*/
|
*/
|
||||||
asynStatus readEncoderType();
|
asynStatus readEncoderType();
|
||||||
|
|
||||||
protected:
|
/**
|
||||||
masterMacsController *pC_;
|
* @brief Check if the axis needs to run its initialization function
|
||||||
double lastSetSpeed_;
|
*
|
||||||
bool waitForHandshake_;
|
* @return true
|
||||||
time_t timeAtHandshake_;
|
* @return false
|
||||||
|
*/
|
||||||
|
bool needInit();
|
||||||
|
|
||||||
bool targetReachedUninitialized_;
|
/**
|
||||||
|
* @brief Instruct the axis to run its init() function during the next poll
|
||||||
|
*
|
||||||
|
* @param needInit
|
||||||
|
*/
|
||||||
|
void setNeedInit(bool needInit);
|
||||||
|
|
||||||
asynStatus readConfig();
|
/**
|
||||||
|
* @brief Return a pointer to the axis controller
|
||||||
/*
|
*/
|
||||||
The axis status and axis error of MasterMACS are given as an integer from
|
virtual masterMacsController *pController() override { return pC_; };
|
||||||
the controller. The 16 individual bits contain the actual information.
|
|
||||||
*/
|
|
||||||
std::bitset<16> axisStatus_;
|
|
||||||
std::bitset<16> axisError_;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the Master MACS status with the xR10 command and store the
|
* @brief Read the Master MACS status with the xR10 command and store the
|
||||||
@@ -130,7 +131,7 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
asynStatus readAxisStatus();
|
asynStatus readAxisStatus();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The functions below read the specified status bit from the axisStatus_
|
The functions below read the specified status bit from the axisStatus
|
||||||
bitset. Since a bit can either be 0 or 1, the return value is given as a
|
bitset. Since a bit can either be 0 or 1, the return value is given as a
|
||||||
boolean.
|
boolean.
|
||||||
*/
|
*/
|
||||||
@@ -138,68 +139,68 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool readyToBeSwitchedOn() { return axisStatus_[0]; }
|
bool readyToBeSwitchedOn();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool switchedOn() { return axisStatus_[1]; }
|
bool switchedOn();
|
||||||
|
|
||||||
// Bit 2 is unused
|
// Bit 2 is unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool faultConditionSet() { return axisStatus_[3]; }
|
bool faultConditionSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool voltagePresent() { return axisStatus_[4]; }
|
bool voltagePresent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool quickStopping() { return axisStatus_[5] == 0; }
|
bool quickStopping();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool switchOnDisabled() { return axisStatus_[6]; }
|
bool switchOnDisabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool warning() { return axisStatus_[7]; }
|
bool warning();
|
||||||
|
|
||||||
// Bit 8 is unused
|
// Bit 8 is unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool remoteMode() { return axisStatus_[9]; }
|
bool remoteMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool targetReached() { return axisStatus_[10]; }
|
bool targetReached();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool internalLimitActive() { return axisStatus_[11]; }
|
bool internalLimitActive();
|
||||||
|
|
||||||
// Bits 12 and 13 are unused
|
// Bits 12 and 13 are unused
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool setEventHasOcurred() { return axisStatus_[14]; }
|
bool setEventHasOcurred();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisStatus_
|
* @brief Read the property from axisStatus_
|
||||||
*/
|
*/
|
||||||
bool powerEnabled() { return axisStatus_[15]; }
|
bool powerEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the Master MACS status with the xR10 command and store the
|
* @brief Read the Master MACS status with the xR10 command and store the
|
||||||
@@ -217,72 +218,76 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool shortCircuit() { return axisError_[1]; }
|
bool shortCircuit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool encoderError() { return axisError_[2]; }
|
bool encoderError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool followingError() { return axisError_[3]; }
|
bool followingError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool communicationError() { return axisError_[4]; }
|
bool communicationError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool feedbackError() { return axisError_[5]; }
|
bool feedbackError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool positiveLimitSwitch() { return axisError_[6]; }
|
bool positiveLimitSwitch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool negativeLimitSwitch() { return axisError_[7]; }
|
bool negativeLimitSwitch();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool positiveSoftwareLimit() { return axisError_[8]; }
|
bool positiveSoftwareLimit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool negativeSoftwareLimit() { return axisError_[9]; }
|
bool negativeSoftwareLimit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overCurrent() { return axisError_[10]; }
|
bool overCurrent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overTemperature() { return axisError_[11]; }
|
bool overTemperature();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool overVoltage() { return axisError_[12]; }
|
bool overVoltage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool underVoltage() { return axisError_[13]; }
|
bool underVoltage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the property from axisError_
|
* @brief Read the property from axisError_
|
||||||
*/
|
*/
|
||||||
bool stoFault() { return axisError_[15]; }
|
bool stoFault();
|
||||||
|
|
||||||
|
private:
|
||||||
|
masterMacsController *pC_;
|
||||||
|
std::unique_ptr<masterMacsAxisImpl> pMasterMacsA_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,6 +12,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
struct masterMacsControllerImpl {
|
||||||
|
double comTimeout;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copy src into dst and replace all NULL terminators up to the carriage
|
* @brief Copy src into dst and replace all NULL terminators up to the carriage
|
||||||
* return with spaces. This allows to print *dst with asynPrint.
|
* return with spaces. This allows to print *dst with asynPrint.
|
||||||
@@ -59,8 +63,10 @@ masterMacsController::masterMacsController(const char *portName,
|
|||||||
// Initialization of local variables
|
// Initialization of local variables
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
|
|
||||||
// Initialization of all member variables
|
pMasterMacsC_ =
|
||||||
comTimeout_ = comTimeout;
|
std::make_unique<masterMacsControllerImpl>((masterMacsControllerImpl){
|
||||||
|
.comTimeout = comTimeout,
|
||||||
|
});
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
@@ -130,7 +136,6 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
|
|
||||||
// Definition of local variables.
|
// Definition of local variables.
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
asynStatus pl_status = asynSuccess;
|
|
||||||
char fullCommand[MAXBUF_] = {0};
|
char fullCommand[MAXBUF_] = {0};
|
||||||
char fullResponse[MAXBUF_] = {0};
|
char fullResponse[MAXBUF_] = {0};
|
||||||
char drvMessageText[MAXBUF_] = {0};
|
char drvMessageText[MAXBUF_] = {0};
|
||||||
@@ -158,7 +163,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
|
|
||||||
// Check if a custom timeout has been given
|
// Check if a custom timeout has been given
|
||||||
if (comTimeout < 0.0) {
|
if (comTimeout < 0.0) {
|
||||||
comTimeout = comTimeout_;
|
comTimeout = pMasterMacsC_->comTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
@@ -192,7 +197,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
msgPrintControlKey comKey =
|
msgPrintControlKey comKey =
|
||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
if (msgPrintControl_.shouldBePrinted(comKey, true, pasynUserSelf)) {
|
if (getMsgPrintControl().shouldBePrinted(comKey, true, pasynUserSelf)) {
|
||||||
char printableCommand[MAXBUF_] = {0};
|
char printableCommand[MAXBUF_] = {0};
|
||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
@@ -202,7 +207,7 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
stringifyAsynStatus(status), printableCommand);
|
stringifyAsynStatus(status), printableCommand);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
msgPrintControl_.resetCount(comKey, pasynUserSelf);
|
getMsgPrintControl().resetCount(comKey, pasynUserSelf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create custom error messages for different failure modes
|
// Create custom error messages for different failure modes
|
||||||
@@ -249,48 +254,31 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
|
|
||||||
// Log the overall status (communication successfull or not)
|
// Log the overall status (communication successfull or not)
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
pl_status = axis->setIntegerParam(this->motorStatusCommsError_, 0);
|
setAxisParamChecked(axis, motorStatusCommsError, false);
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(pl_status, "motorStatusCommsError_",
|
|
||||||
axisNo, __PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
|
||||||
} else if (status == asynDisconnected) {
|
|
||||||
// Do nothing
|
|
||||||
} else {
|
} else {
|
||||||
// Set the error status bits only if the axis is not disconnected
|
|
||||||
|
|
||||||
// Check if the axis already is in an error communication mode. If
|
/*
|
||||||
// it is not, upstream the error. This is done to avoid "flooding"
|
Since the communication failed, there is the possibility that the
|
||||||
// the user with different error messages if more than one error
|
controller is not connected at all to the network. In that case, we
|
||||||
// ocurred before an error-free communication
|
cannot be sure that the information read out in the init method of the
|
||||||
pl_status =
|
axis is still up-to-date the next time we get a connection. Therefore,
|
||||||
getIntegerParam(axisNo, motorStatusProblem_, &motorStatusProblem);
|
an info flag is set which the axis object can use at the start of its
|
||||||
if (pl_status != asynSuccess) {
|
poll method to try to initialize itself.
|
||||||
return paramLibAccessFailed(pl_status, "motorStatusProblem_",
|
*/
|
||||||
axisNo, __PRETTY_FUNCTION__, __LINE__);
|
axis->setNeedInit(true);
|
||||||
}
|
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
getAxisParamChecked(axis, motorStatusProblem, &motorStatusProblem);
|
||||||
|
|
||||||
if (motorStatusProblem == 0) {
|
if (motorStatusProblem == 0) {
|
||||||
pl_status = axis->setStringParam(motorMessageText_, drvMessageText);
|
setAxisParamChecked(axis, motorMessageText, drvMessageText);
|
||||||
if (pl_status != asynSuccess) {
|
setAxisParamChecked(axis, motorStatusProblem, true);
|
||||||
return paramLibAccessFailed(pl_status, "motorMessageText_",
|
setAxisParamChecked(axis, motorStatusCommsError, false);
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pl_status = axis->setIntegerParam(motorStatusProblem_, 1);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(pl_status, "motorStatusProblem",
|
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
pl_status = axis->setIntegerParam(motorStatusProblem_, 1);
|
|
||||||
if (pl_status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(pl_status, "motorStatusCommsError_",
|
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,6 +298,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
const char *fullCommand, const char *fullResponse, char *drvMessageText,
|
const char *fullCommand, const char *fullResponse, char *drvMessageText,
|
||||||
int *valueStart, int *valueStop, int axisNo, int tcpCmd, bool isRead) {
|
int *valueStart, int *valueStop, int axisNo, int tcpCmd, bool isRead) {
|
||||||
|
|
||||||
|
bool responseValid = false;
|
||||||
int responseStart = 0;
|
int responseStart = 0;
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
int prevConnected = 0;
|
int prevConnected = 0;
|
||||||
@@ -319,13 +308,14 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
msgPrintControlKey parseKey =
|
msgPrintControlKey parseKey =
|
||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
// Was the motor previously connected?
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
status = getIntegerParam(axisNo, motorConnected(), &prevConnected);
|
if (axis == nullptr) {
|
||||||
if (status != asynSuccess) {
|
return asynError;
|
||||||
return paramLibAccessFailed(status, "motorConnected", axisNo,
|
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Was the motor previously connected?
|
||||||
|
getAxisParamChecked(axis, motorConnected, &prevConnected);
|
||||||
|
|
||||||
// We don't use strlen here since the C string terminator 0x00
|
// We don't use strlen here since the C string terminator 0x00
|
||||||
// occurs in the middle of the char array.
|
// occurs in the middle of the char array.
|
||||||
for (uint32_t i = 0; i < MAXBUF_; i++) {
|
for (uint32_t i = 0; i < MAXBUF_; i++) {
|
||||||
@@ -336,6 +326,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
} else if (fullResponse[i] == '\x06') {
|
} else if (fullResponse[i] == '\x06') {
|
||||||
// ACK
|
// ACK
|
||||||
*valueStop = i;
|
*valueStop = i;
|
||||||
|
responseValid = true;
|
||||||
|
|
||||||
// Motor wasn't connected before -> Update the paramLib entry and PV
|
// Motor wasn't connected before -> Update the paramLib entry and PV
|
||||||
// to show it is now connected.
|
// to show it is now connected.
|
||||||
@@ -347,16 +338,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
"connected.\n",
|
"connected.\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
setAxisParamChecked(axis, motorConnected, true);
|
||||||
if (axis == nullptr) {
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
status = axis->setIntegerParam(motorConnected(), 1);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(status, "motorConnected",
|
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
status = callParamCallbacks();
|
status = callParamCallbacks();
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
@@ -367,51 +349,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msgPrintControl_.resetCount(parseKey, pasynUserSelf);
|
break;
|
||||||
|
|
||||||
// Check if the response matches the expectations. Each response
|
|
||||||
// contains the string "axisNo R tcpCmd" (including the spaces)
|
|
||||||
char expectedResponseSubstring[MAXBUF_] = {0};
|
|
||||||
|
|
||||||
// The response does not contain a leading 0 if tcpCmd only has
|
|
||||||
// a single digit!
|
|
||||||
if (isRead) {
|
|
||||||
snprintf(expectedResponseSubstring, MAXBUF_ - 4, "%d R %d",
|
|
||||||
axisNo, tcpCmd);
|
|
||||||
} else {
|
|
||||||
snprintf(expectedResponseSubstring, MAXBUF_ - 4, "%d S %d",
|
|
||||||
axisNo, tcpCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
msgPrintControlKey responseMatchKey = msgPrintControlKey(
|
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
|
||||||
|
|
||||||
if (strstr(&fullResponse[responseStart],
|
|
||||||
expectedResponseSubstring) == NULL) {
|
|
||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
|
||||||
adjustForPrint(printableResponse, fullResponse, MAXBUF_);
|
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(parseKey, true,
|
|
||||||
pasynUserSelf)) {
|
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
|
||||||
"Controller \"%s\", axis %d => %s, line "
|
|
||||||
"%d:\nMismatched "
|
|
||||||
"response %s to command %s.%s\n",
|
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
|
||||||
printableResponse, printableCommand,
|
|
||||||
msgPrintControl_.getSuffix());
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(
|
|
||||||
drvMessageText, MAXBUF_,
|
|
||||||
"Mismatched response %s to command %s. Please call the "
|
|
||||||
"support.",
|
|
||||||
printableResponse, printableCommand);
|
|
||||||
return asynError;
|
|
||||||
} else {
|
|
||||||
msgPrintControl_.resetCount(responseMatchKey, pasynUserSelf);
|
|
||||||
}
|
|
||||||
return asynSuccess;
|
|
||||||
} else if (fullResponse[i] == '\x15') {
|
} else if (fullResponse[i] == '\x15') {
|
||||||
/*
|
/*
|
||||||
NAK
|
NAK
|
||||||
@@ -428,16 +366,7 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
"disconnected.\n",
|
"disconnected.\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
setAxisParamChecked(axis, motorConnected, false);
|
||||||
if (axis == nullptr) {
|
|
||||||
return asynError;
|
|
||||||
}
|
|
||||||
status = axis->setIntegerParam(motorConnected(), 0);
|
|
||||||
if (status != asynSuccess) {
|
|
||||||
return paramLibAccessFailed(status, "motorConnected",
|
|
||||||
axisNo, __PRETTY_FUNCTION__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
status = callParamCallbacks();
|
status = callParamCallbacks();
|
||||||
if (status != asynSuccess) {
|
if (status != asynSuccess) {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
@@ -447,33 +376,80 @@ asynStatus masterMacsController::parseResponse(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return asynDisconnected;
|
break;
|
||||||
} else if (fullResponse[i] == '\x18') {
|
} else if (fullResponse[i] == '\x18') {
|
||||||
// CAN
|
// CAN
|
||||||
snprintf(drvMessageText, MAXBUF_,
|
snprintf(drvMessageText, MAXBUF_,
|
||||||
"Tried to write with a read-only command. This is a "
|
"Tried to write with a read-only command. This is a "
|
||||||
"bug, please call the support.");
|
"bug, please call the support.");
|
||||||
|
|
||||||
if (msgPrintControl_.shouldBePrinted(parseKey, true,
|
if (getMsgPrintControl().shouldBePrinted(parseKey, true,
|
||||||
pasynUserSelf)) {
|
pasynUserSelf)) {
|
||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
asynPrint(
|
asynPrint(
|
||||||
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
"Controller \"%s\", axis %d => %s, line %d:\nTried to "
|
"Controller \"%s\", axis %d => %s, line %d:\nTried to "
|
||||||
"write with the read-only command %s.%s\n",
|
"write with the read-only command %s.%s\n",
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
printableCommand, msgPrintControl_.getSuffix());
|
printableCommand, getMsgPrintControl().getSuffix());
|
||||||
}
|
}
|
||||||
return asynError;
|
responseValid = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return asynError;
|
|
||||||
|
if (responseValid) {
|
||||||
|
getMsgPrintControl().resetCount(parseKey, pasynUserSelf);
|
||||||
|
|
||||||
|
// Check if the response matches the expectations. Each response
|
||||||
|
// contains the string "axisNo R tcpCmd" (including the spaces)
|
||||||
|
char expectedResponseSubstring[MAXBUF_] = {0};
|
||||||
|
|
||||||
|
// The response does not contain a leading 0 if tcpCmd only has
|
||||||
|
// a single digit!
|
||||||
|
if (isRead) {
|
||||||
|
snprintf(expectedResponseSubstring, MAXBUF_ - 4, "%d R %d", axisNo,
|
||||||
|
tcpCmd);
|
||||||
|
} else {
|
||||||
|
snprintf(expectedResponseSubstring, MAXBUF_ - 4, "%d S %d", axisNo,
|
||||||
|
tcpCmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
msgPrintControlKey responseMatchKey =
|
||||||
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
|
|
||||||
|
if (strstr(&fullResponse[responseStart], expectedResponseSubstring) ==
|
||||||
|
NULL) {
|
||||||
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
|
adjustForPrint(printableResponse, fullResponse, MAXBUF_);
|
||||||
|
|
||||||
|
if (getMsgPrintControl().shouldBePrinted(parseKey, true,
|
||||||
|
pasynUserSelf)) {
|
||||||
|
asynPrint(this->pasynUserSelf, ASYN_TRACEIO_DRIVER,
|
||||||
|
"Controller \"%s\", axis %d => %s, line "
|
||||||
|
"%d:\nMismatched "
|
||||||
|
"response %s to command %s.%s\n",
|
||||||
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
printableResponse, printableCommand,
|
||||||
|
getMsgPrintControl().getSuffix());
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(drvMessageText, MAXBUF_,
|
||||||
|
"Mismatched response %s to command %s. Please call the "
|
||||||
|
"support.",
|
||||||
|
printableResponse, printableCommand);
|
||||||
|
return asynError;
|
||||||
|
} else {
|
||||||
|
getMsgPrintControl().resetCount(responseMatchKey, pasynUserSelf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return asynSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus masterMacsController::readInt32(asynUser *pasynUser,
|
asynStatus masterMacsController::readInt32(asynUser *pasynUser,
|
||||||
epicsInt32 *value) {
|
epicsInt32 *value) {
|
||||||
// masterMacs can be disabled
|
// masterMacs can be disabled
|
||||||
if (pasynUser->reason == motorCanDisable_) {
|
if (pasynUser->reason == motorCanDisable()) {
|
||||||
*value = 1;
|
*value = 1;
|
||||||
return asynSuccess;
|
return asynSuccess;
|
||||||
} else {
|
} else {
|
||||||
@@ -481,6 +457,8 @@ asynStatus masterMacsController::readInt32(asynUser *pasynUser,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double masterMacsController::comTimeout() { return pMasterMacsC_->comTimeout; }
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/** 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 */
|
||||||
|
|||||||
@@ -8,9 +8,16 @@
|
|||||||
|
|
||||||
#ifndef masterMacsController_H
|
#ifndef masterMacsController_H
|
||||||
#define masterMacsController_H
|
#define masterMacsController_H
|
||||||
#include "masterMacsAxis.h"
|
|
||||||
#include "sinqAxis.h"
|
#include "sinqAxis.h"
|
||||||
#include "sinqController.h"
|
#include "sinqController.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 masterMacsAxis;
|
||||||
|
|
||||||
|
struct masterMacsControllerImpl;
|
||||||
|
|
||||||
class masterMacsController : public sinqController {
|
class masterMacsController : public sinqController {
|
||||||
|
|
||||||
@@ -31,6 +38,15 @@ class masterMacsController : public sinqController {
|
|||||||
int numAxes, double movingPollPeriod,
|
int numAxes, double movingPollPeriod,
|
||||||
double idlePollPeriod, double comTimeout);
|
double idlePollPeriod, double comTimeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Overloaded version of the sinqController version
|
||||||
|
*
|
||||||
|
* @param pasynUser
|
||||||
|
* @param value
|
||||||
|
* @return asynStatus
|
||||||
|
*/
|
||||||
|
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the axis object
|
* @brief Get the axis object
|
||||||
*
|
*
|
||||||
@@ -123,15 +139,10 @@ class masterMacsController : public sinqController {
|
|||||||
*
|
*
|
||||||
* @return double Timeout in seconds
|
* @return double Timeout in seconds
|
||||||
*/
|
*/
|
||||||
double comTimeout() { return comTimeout_; }
|
double comTimeout();
|
||||||
|
|
||||||
asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
std::unique_ptr<masterMacsControllerImpl> pMasterMacsC_;
|
||||||
Stores the constructor input comTimeout
|
|
||||||
*/
|
|
||||||
double comTimeout_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* masterMacsController_H */
|
#endif /* masterMacsController_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user