Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
fe52245e38 | |||
a3e849f386 |
2
Makefile
2
Makefile
@ -13,7 +13,7 @@ REQUIRED+=sinqMotor
|
|||||||
motorBase_VERSION=7.2.2
|
motorBase_VERSION=7.2.2
|
||||||
|
|
||||||
# Specify the version of sinqMotor we want to build against
|
# Specify the version of sinqMotor we want to build against
|
||||||
sinqMotor_VERSION=0.9.0
|
sinqMotor_VERSION=0.10.0
|
||||||
|
|
||||||
# These headers allow to depend on this library for derived drivers.
|
# These headers allow to depend on this library for derived drivers.
|
||||||
HEADERS += src/masterMacsAxis.h
|
HEADERS += src/masterMacsAxis.h
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# masterMacs
|
# masterMacs
|
||||||
|
|
||||||
|
## <span style="color:red">Please read the documentation of sinqMotor first: https://git.psi.ch/sinq-epics-modules/sinqmotor</span>
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This is a driver for the masterMacs motion controller with the SINQ communication protocol. It is based on the sinqMotor shared library (https://git.psi.ch/sinq-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 masterMacs motion controller with the SINQ communication protocol. It is based on the sinqMotor shared library (https://git.psi.ch/sinq-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.
|
||||||
|
@ -190,8 +190,8 @@ asynStatus masterMacsAxis::init() {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &motorPosition);
|
nvals = sscanf(response, "%lf", &motorPosition);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse("R12", response, axisNo_,
|
return pC_->couldNotParseResponse("R12", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read out the current velocity
|
// Read out the current velocity
|
||||||
@ -201,8 +201,8 @@ asynStatus masterMacsAxis::init() {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &motorVelocity);
|
nvals = sscanf(response, "%lf", &motorVelocity);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse("R05", response, axisNo_,
|
return pC_->couldNotParseResponse("R05", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read out the maximum velocity
|
// Read out the maximum velocity
|
||||||
@ -212,8 +212,8 @@ asynStatus masterMacsAxis::init() {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &motorVmax);
|
nvals = sscanf(response, "%lf", &motorVmax);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse("R26", response, axisNo_,
|
return pC_->couldNotParseResponse("R26", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read out the acceleration
|
// Read out the acceleration
|
||||||
@ -223,8 +223,8 @@ asynStatus masterMacsAxis::init() {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &motorAccel);
|
nvals = sscanf(response, "%lf", &motorAccel);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse("R06", response, axisNo_,
|
return pC_->couldNotParseResponse("R06", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the motor speed. If this value differs from the one in the motor
|
// Cache the motor speed. If this value differs from the one in the motor
|
||||||
@ -232,15 +232,10 @@ asynStatus masterMacsAxis::init() {
|
|||||||
// MasterMACS.
|
// MasterMACS.
|
||||||
lastSetSpeed_ = motorVelocity;
|
lastSetSpeed_ = motorVelocity;
|
||||||
|
|
||||||
// Transform from motor to parameter library coordinates
|
// Store the motor position in the parameter library
|
||||||
motorPosition = motorPosition / motorRecResolution;
|
pl_status = setMotorPosition(motorPosition);
|
||||||
|
|
||||||
// Store these values in the parameter library
|
|
||||||
pl_status =
|
|
||||||
pC_->setDoubleParam(axisNo_, pC_->motorPosition(), motorPosition);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_,
|
return pl_status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to the motor record fields
|
// Write to the motor record fields
|
||||||
@ -338,8 +333,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
|
|
||||||
nvals = sscanf(response, "%lf", &handshakePerformed);
|
nvals = sscanf(response, "%lf", &handshakePerformed);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse("R86", response, axisNo_,
|
||||||
"R86", response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handshakePerformed == 1.0) {
|
if (handshakePerformed == 1.0) {
|
||||||
@ -379,17 +374,11 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the previous motor position
|
// Read the previous motor position
|
||||||
pl_status =
|
pl_status = motorPosition(&previousPosition);
|
||||||
pC_->getDoubleParam(axisNo_, pC_->motorPosition(), &previousPosition);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_,
|
return pl_status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform from EPICS to motor coordinates (see comment in
|
|
||||||
// masterMacsAxis::readConfig())
|
|
||||||
previousPosition = previousPosition * motorRecResolution;
|
|
||||||
|
|
||||||
// Update the axis status
|
// Update the axis status
|
||||||
rw_status = readAxisStatus();
|
rw_status = readAxisStatus();
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
@ -411,8 +400,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", ¤tPosition);
|
nvals = sscanf(response, "%lf", ¤tPosition);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse("R12", response, axisNo_,
|
return pC_->couldNotParseResponse("R12", response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -619,8 +608,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &lowLimit);
|
nvals = sscanf(response, "%lf", &lowLimit);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse("R34", response, axisNo_,
|
||||||
"R34", response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
rw_status = pC_->read(axisNo_, 33, response);
|
rw_status = pC_->read(axisNo_, 33, response);
|
||||||
@ -629,8 +618,8 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
}
|
}
|
||||||
nvals = sscanf(response, "%lf", &highLimit);
|
nvals = sscanf(response, "%lf", &highLimit);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse("R33", response, axisNo_,
|
||||||
"R33", response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -719,14 +708,9 @@ asynStatus masterMacsAxis::doPoll(bool *moving) {
|
|||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform from motor to EPICS coordinates (see comment in
|
pl_status = setMotorPosition(currentPosition);
|
||||||
// masterMacsAxis::init())
|
|
||||||
currentPosition = currentPosition / motorRecResolution;
|
|
||||||
|
|
||||||
pl_status = setDoubleParam(pC_->motorPosition(), currentPosition);
|
|
||||||
if (pl_status != asynSuccess) {
|
if (pl_status != asynSuccess) {
|
||||||
return pC_->paramLibAccessFailed(pl_status, "motorPosition_", axisNo_,
|
return pl_status;
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return poll_status;
|
return poll_status;
|
||||||
@ -894,7 +878,7 @@ asynStatus masterMacsAxis::stop(double acceleration) {
|
|||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus masterMacsAxis::reset() {
|
asynStatus masterMacsAxis::doReset() {
|
||||||
// Status of read-write-operations of ASCII commands to the controller
|
// Status of read-write-operations of ASCII commands to the controller
|
||||||
asynStatus rw_status = asynSuccess;
|
asynStatus rw_status = asynSuccess;
|
||||||
|
|
||||||
@ -994,8 +978,8 @@ asynStatus masterMacsAxis::readEncoderType() {
|
|||||||
|
|
||||||
nvals = sscanf(response, "%d", &encoder_id);
|
nvals = sscanf(response, "%d", &encoder_id);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(command, response, axisNo_,
|
return pC_->couldNotParseResponse(command, response, axisNo_,
|
||||||
__PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1084,7 +1068,11 @@ asynStatus masterMacsAxis::enable(bool on) {
|
|||||||
axisNo_, __PRETTY_FUNCTION__,
|
axisNo_, __PRETTY_FUNCTION__,
|
||||||
__LINE__);
|
__LINE__);
|
||||||
}
|
}
|
||||||
rw_status = pC_->write(axisNo_, 04, value);
|
|
||||||
|
// The answer to the enable command on MasterMACS might take some time,
|
||||||
|
// hence we wait for a custom timespan in seconds instead of
|
||||||
|
// pC_->comTimeout_
|
||||||
|
rw_status = pC_->write(axisNo_, 04, value, 1.0);
|
||||||
if (rw_status != asynSuccess) {
|
if (rw_status != asynSuccess) {
|
||||||
return rw_status;
|
return rw_status;
|
||||||
}
|
}
|
||||||
@ -1154,8 +1142,8 @@ asynStatus masterMacsAxis::readAxisStatus() {
|
|||||||
float axisStatus = 0;
|
float axisStatus = 0;
|
||||||
int nvals = sscanf(response, "%f", &axisStatus);
|
int nvals = sscanf(response, "%f", &axisStatus);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse("R10", response, axisNo_,
|
||||||
"R10", response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
axisStatus_ = toBitset(axisStatus);
|
axisStatus_ = toBitset(axisStatus);
|
||||||
@ -1175,8 +1163,8 @@ asynStatus masterMacsAxis::readAxisError() {
|
|||||||
float axisError = 0;
|
float axisError = 0;
|
||||||
int nvals = sscanf(response, "%f", &axisError);
|
int nvals = sscanf(response, "%f", &axisError);
|
||||||
if (nvals != 1) {
|
if (nvals != 1) {
|
||||||
return pC_->errMsgCouldNotParseResponse(
|
return pC_->couldNotParseResponse("R11", response, axisNo_,
|
||||||
"R11", response, axisNo_, __PRETTY_FUNCTION__, __LINE__);
|
__PRETTY_FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
axisError_ = toBitset(axisError);
|
axisError_ = toBitset(axisError);
|
||||||
}
|
}
|
||||||
|
@ -70,12 +70,12 @@ class masterMacsAxis : public sinqAxis {
|
|||||||
asynStatus stop(double acceleration);
|
asynStatus stop(double acceleration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reset the axis error
|
* @brief Implementation of the `doReset` function from sinqAxis.
|
||||||
*
|
*
|
||||||
* @param on
|
* @param on
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus reset();
|
asynStatus doReset();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Readout of some values from the controller at IOC startup
|
* @brief Readout of some values from the controller at IOC startup
|
||||||
|
@ -113,18 +113,19 @@ masterMacsAxis *masterMacsController::getMasterMacsAxis(int axisNo) {
|
|||||||
return dynamic_cast<masterMacsAxis *>(asynAxis);
|
return dynamic_cast<masterMacsAxis *>(asynAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus masterMacsController::read(int axisNo, int tcpCmd, char *response) {
|
asynStatus masterMacsController::read(int axisNo, int tcpCmd, char *response,
|
||||||
|
double comTimeout) {
|
||||||
return writeRead(axisNo, tcpCmd, NULL, response);
|
return writeRead(axisNo, tcpCmd, NULL, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus masterMacsController::write(int axisNo, int tcpCmd,
|
asynStatus masterMacsController::write(int axisNo, int tcpCmd,
|
||||||
const char *payload) {
|
const char *payload, double comTimeout) {
|
||||||
return writeRead(axisNo, tcpCmd, payload, NULL);
|
return writeRead(axisNo, tcpCmd, payload, NULL, comTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
||||||
const char *payload,
|
const char *payload, char *response,
|
||||||
char *response) {
|
double comTimeout) {
|
||||||
|
|
||||||
// Definition of local variables.
|
// Definition of local variables.
|
||||||
asynStatus status = asynSuccess;
|
asynStatus status = asynSuccess;
|
||||||
@ -156,6 +157,11 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
// Check if a timeout has been given
|
||||||
|
if (comTimeout < 0.0) {
|
||||||
|
comTimeout = comTimeout_;
|
||||||
|
}
|
||||||
|
|
||||||
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
masterMacsAxis *axis = getMasterMacsAxis(axisNo);
|
||||||
if (axis == nullptr) {
|
if (axis == nullptr) {
|
||||||
// We already did the error logging directly in getAxis
|
// We already did the error logging directly in getAxis
|
||||||
@ -179,8 +185,16 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
adjustForPrint(printableCommand, fullCommand, MAXBUF_);
|
||||||
|
|
||||||
// Send out the command
|
// Send out the command
|
||||||
status = pasynOctetSyncIO->write(
|
status = pasynOctetSyncIO->write(ipPortUser_, fullCommand,
|
||||||
ipPortUser_, fullCommand, fullCommandLength, comTimeout_, &nbytesOut);
|
fullCommandLength, comTimeout, &nbytesOut);
|
||||||
|
|
||||||
|
if (status != asynSuccess) {
|
||||||
|
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
|
"Controller \"%s\", axis %d => %s, line %d:\nError "
|
||||||
|
"%s while writing to the controller\n",
|
||||||
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
stringifyAsynStatus(status));
|
||||||
|
}
|
||||||
|
|
||||||
msgPrintControlKey writeKey =
|
msgPrintControlKey writeKey =
|
||||||
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
msgPrintControlKey(portName, axisNo, __PRETTY_FUNCTION__, __LINE__);
|
||||||
@ -207,24 +221,28 @@ asynStatus masterMacsController::writeRead(int axisNo, int tcpCmd,
|
|||||||
https://www.slac.stanford.edu/grp/lcls/controls/global/doc/epics-modules/R3-14-12/asyn/asyn-R4-18-lcls2/asyn/interfaces/asynOctetBase.c)
|
https://www.slac.stanford.edu/grp/lcls/controls/global/doc/epics-modules/R3-14-12/asyn/asyn-R4-18-lcls2/asyn/interfaces/asynOctetBase.c)
|
||||||
*/
|
*/
|
||||||
status = pasynOctetSyncIO->read(ipPortUser_, fullResponse, MAXBUF_,
|
status = pasynOctetSyncIO->read(ipPortUser_, fullResponse, MAXBUF_,
|
||||||
comTimeout_, &nbytesIn, &eomReason);
|
comTimeout, &nbytesIn, &eomReason);
|
||||||
pasynOctetSyncIO->flush(ipPortUser_);
|
pasynOctetSyncIO->flush(ipPortUser_);
|
||||||
|
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
status = parseResponse(fullCommand, fullResponse,
|
status = parseResponse(fullCommand, fullResponse,
|
||||||
drvMessageText, &valueStart, &valueStop,
|
drvMessageText, &valueStart, &valueStop,
|
||||||
axisNo, tcpCmd, isRead);
|
axisNo, tcpCmd, isRead);
|
||||||
|
|
||||||
if (status == asynSuccess) {
|
if (status == asynSuccess) {
|
||||||
// Received the correct message
|
// Received the correct message
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR,
|
if (status != asynTimeout) {
|
||||||
"Controller \"%s\", axis %d => %s, line %d:\nError "
|
asynPrint(
|
||||||
"%s while reading from the controller\n",
|
this->pasynUserSelf, ASYN_TRACE_ERROR,
|
||||||
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
"Controller \"%s\", axis %d => %s, line %d:\nError "
|
||||||
stringifyAsynStatus(status));
|
"%s while reading from the controller\n",
|
||||||
break;
|
portName, axisNo, __PRETTY_FUNCTION__, __LINE__,
|
||||||
|
stringifyAsynStatus(status));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i + 1 == maxTrials && status == asynError) {
|
if (i + 1 == maxTrials && status == asynError) {
|
||||||
|
@ -57,7 +57,8 @@ class masterMacsController : public sinqController {
|
|||||||
* @param payload Value send to MasterMACS.
|
* @param payload Value send to MasterMACS.
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus write(int axisNo, int tcpCmd, const char *payload);
|
asynStatus write(int axisNo, int tcpCmd, const char *payload,
|
||||||
|
double comTimeout = -1.0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a command to the hardware and receive a response (R mode)
|
* @brief Send a command to the hardware and receive a response (R mode)
|
||||||
@ -68,7 +69,8 @@ class masterMacsController : public sinqController {
|
|||||||
* expected to have the size MAXBUF_.
|
* expected to have the size MAXBUF_.
|
||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus read(int axisNo, int tcpCmd, char *response);
|
asynStatus read(int axisNo, int tcpCmd, char *response,
|
||||||
|
double comTimeout = -1.0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a command to the hardware (R or S mode) and receive a
|
* @brief Send a command to the hardware (R or S mode) and receive a
|
||||||
@ -85,7 +87,7 @@ class masterMacsController : public sinqController {
|
|||||||
* @return asynStatus
|
* @return asynStatus
|
||||||
*/
|
*/
|
||||||
asynStatus writeRead(int axisNo, int tcpCmd, const char *payload,
|
asynStatus writeRead(int axisNo, int tcpCmd, const char *payload,
|
||||||
char *response);
|
char *response, double comTimeout = -1.0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parse "fullResponse" received upon sending "fullCommand".
|
* @brief Parse "fullResponse" received upon sending "fullCommand".
|
||||||
|
Reference in New Issue
Block a user