Added MsgTxt support to pmac controller driver

This commit is contained in:
2019-01-08 11:47:02 +01:00
parent 972131d86a
commit 02ab5ff9b8
4 changed files with 58 additions and 28 deletions

View File

@ -19,6 +19,10 @@
* I check and cause an alarm in this state too. * I check and cause an alarm in this state too.
* *
* Mark Koennecke, February 2013 * Mark Koennecke, February 2013
*
* Modified to use the MsgTxt field for SINQ
*
* Mark Koennecke, January 2019
********************************************/ ********************************************/
#include <stdlib.h> #include <stdlib.h>
@ -51,7 +55,7 @@ extern "C" void shutdownCallback(void *pPvt)
// These are the pmacAxis class methods // These are the pmacAxis class methods
pmacAxis::pmacAxis(pmacController *pC, int axisNo) pmacAxis::pmacAxis(pmacController *pC, int axisNo)
: asynMotorAxis(pC, axisNo), : SINQAxis(pC, axisNo),
pC_(pC) pC_(pC)
{ {
static const char *functionName = "pmacAxis::pmacAxis"; static const char *functionName = "pmacAxis::pmacAxis";
@ -106,7 +110,7 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
static const char *functionName = "pmacAxis::getAxisInitialStatus"; static const char *functionName = "pmacAxis::getAxisInitialStatus";
sprintf(command, "Q%2.2d00", axisNo_); sprintf(command, "Q%2.2d00", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf(response, "%lf", &scale_); nvals = sscanf(response, "%lf", &scale_);
if (cmdStatus || nvals != 1) { if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read scale_factor on axis %d.\n", functionName, axisNo_); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read scale_factor on axis %d.\n", functionName, axisNo_);
@ -114,7 +118,7 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
} }
sprintf(command, "I%d13", axisNo_); sprintf(command, "I%d13", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf(response, "%d", &limVal); nvals = sscanf(response, "%d", &limVal);
if (cmdStatus || nvals != 1) { if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read high limit on axis %d.\n", functionName, axisNo_); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read high limit on axis %d.\n", functionName, axisNo_);
@ -123,7 +127,7 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
high_limit = ((double)limVal)*scale_; high_limit = ((double)limVal)*scale_;
sprintf(command, "I%d14", axisNo_); sprintf(command, "I%d14", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf(response, "%d", &limVal); nvals = sscanf(response, "%d", &limVal);
if (cmdStatus || nvals != 1) { if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read low limit on axis %d.\n", functionName, axisNo_); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: failed to read low limit on axis %d.\n", functionName, axisNo_);
@ -141,7 +145,7 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
// Enable the axis. After startup, the axis are disabled on the controller... // Enable the axis. After startup, the axis are disabled on the controller...
sprintf(command, "M%2.2d14=1", axisNo_); sprintf(command, "M%2.2d14=1", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
if (cmdStatus ) { if (cmdStatus ) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: enaabling axis %d failed.\n", functionName, axisNo_); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "%s: Error: enaabling axis %d failed.\n", functionName, axisNo_);
return asynError; return asynError;
@ -165,6 +169,8 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
static const char *functionName = "pmacAxis::move"; static const char *functionName = "pmacAxis::move";
double realPosition; double realPosition;
updateMsgTxtFromDriver("");
pC_->debugFlow(functionName); pC_->debugFlow(functionName);
char command[128] = {0}; char command[128] = {0};
@ -183,7 +189,7 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
sprintf( command, "P%2.2d23=0 Q%2.2d01=%12.4f M%2.2d=1", axisNo_, axisNo_, realPosition, axisNo_); sprintf( command, "P%2.2d23=0 Q%2.2d01=%12.4f M%2.2d=1", axisNo_, axisNo_, realPosition, axisNo_);
status = pC_->lowLevelWriteRead(command, response); status = pC_->lowLevelWriteRead(axisNo_,command, response);
return status; return status;
} }
@ -199,9 +205,11 @@ asynStatus pmacAxis::home(double min_velocity, double max_velocity, double accel
pC_->debugFlow(functionName); pC_->debugFlow(functionName);
updateMsgTxtFromDriver("");
sprintf(command, "M%2.2d=9", axisNo_); sprintf(command, "M%2.2d=9", axisNo_);
status = pC_->lowLevelWriteRead(command, response); status = pC_->lowLevelWriteRead(axisNo_,command, response);
homing = 1; homing = 1;
return status; return status;
@ -218,7 +226,7 @@ asynStatus pmacAxis::moveVelocity(double min_velocity, double max_velocity, doub
return asynError; // can we do this, actually? return asynError; // can we do this, actually?
// status = pC_->lowLevelWriteRead(command, response); // status = pC_->lowLevelWriteRead(axisNo_,command, response);
return status; return status;
} }
@ -248,7 +256,7 @@ asynStatus pmacAxis::stop(double acceleration)
sprintf( command, "M%2.2d=8", axisNo_ ); sprintf( command, "M%2.2d=8", axisNo_ );
status = pC_->lowLevelWriteRead(command, response); status = pC_->lowLevelWriteRead(axisNo_,command, response);
return status; return status;
} }
@ -337,34 +345,37 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
/* read our status items one by one: our PMAC does not seem to give multiple responses ..*/ /* read our status items one by one: our PMAC does not seem to give multiple responses ..*/
sprintf(command,"P%2.2d01",axisNo_); sprintf(command,"P%2.2d01",axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf( response, "%d", &axErr); nvals = sscanf( response, "%d", &axErr);
if ( cmdStatus || nvals != 1) { if ( cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read axis Error Status: %d\nCommand :%s\nResponse:%s\n", "drvPmacAxisGetStatus: Failed to read axis Error Status: %d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response ); cmdStatus, command, response );
updateMsgTxtFromDriver("Cannot read Axis Error Status");
} }
sprintf(command,"Q%2.2d10",axisNo_); sprintf(command,"Q%2.2d10",axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf( response, "%lf", &position); nvals = sscanf( response, "%lf", &position);
if ( cmdStatus || nvals != 1) { if ( cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read position Status: %d\nCommand :%s\nResponse:%s\n", "drvPmacAxisGetStatus: Failed to read position Status: %d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response ); cmdStatus, command, response );
updateMsgTxtFromDriver("Cannot read Axis position");
} }
sprintf(command,"P%2.2d00",axisNo_); sprintf(command,"P%2.2d00",axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf( response, "%d", &axStat); nvals = sscanf( response, "%d", &axStat);
if ( cmdStatus || nvals != 1) { if ( cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read axis status, Status: %d\nCommand :%s\nResponse:%s\n", "drvPmacAxisGetStatus: Failed to read axis status, Status: %d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response ); cmdStatus, command, response );
updateMsgTxtFromDriver("Cannot read Axis Status");
} }
sprintf(command,"M%2.2d21", axisNo_); sprintf(command,"M%2.2d21", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf( response, "%d", &highLim); nvals = sscanf( response, "%d", &highLim);
if ( cmdStatus || nvals != 1) { if ( cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
@ -373,7 +384,7 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
} }
sprintf(command,"M%2.2d22", axisNo_); sprintf(command,"M%2.2d22", axisNo_);
cmdStatus = pC_->lowLevelWriteRead(command, response); cmdStatus = pC_->lowLevelWriteRead(axisNo_,command, response);
nvals = sscanf( response, "%d", &lowLim); nvals = sscanf( response, "%d", &lowLim);
if ( cmdStatus || nvals != 1) { if ( cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
@ -419,6 +430,7 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
setIntegerParam(pC_->motorStatusDone_, true); setIntegerParam(pC_->motorStatusDone_, true);
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n", axisNo_); errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n", axisNo_);
updateMsgTxtFromDriver("Axis did not start within 10 seconds");
starting = 0; starting = 0;
return asynSuccess; return asynSuccess;
} }
@ -437,6 +449,7 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
setIntegerParam(pC_->motorStatusDone_, true); setIntegerParam(pC_->motorStatusDone_, true);
setIntegerParam(pC_->motorStatusProblem_, true); setIntegerParam(pC_->motorStatusProblem_, true);
errlogPrintf("Axis %d stayed in 5,6 for more then 60 seconds BROKEN\n", axisNo_); errlogPrintf("Axis %d stayed in 5,6 for more then 60 seconds BROKEN\n", axisNo_);
updateMsgTxtFromDriver("Axis stayed in 5,6 for more then 60 seconds: BROKEN");
status6Time = 0; status6Time = 0;
return asynSuccess; return asynSuccess;
} }
@ -464,16 +477,19 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
/* search for trouble */ /* search for trouble */
if(highLim){ if(highLim){
setIntegerParam(pC_->motorStatusHighLimit_, true ); setIntegerParam(pC_->motorStatusHighLimit_, true );
updateMsgTxtFromDriver("High Limit Hit");
} else { } else {
setIntegerParam(pC_->motorStatusHighLimit_, false ); setIntegerParam(pC_->motorStatusHighLimit_, false );
} }
if(lowLim){ if(lowLim){
setIntegerParam(pC_->motorStatusLowLimit_, true ); setIntegerParam(pC_->motorStatusLowLimit_, true );
updateMsgTxtFromDriver("Low Limit Hit");
} else { } else {
setIntegerParam(pC_->motorStatusLowLimit_, false ); setIntegerParam(pC_->motorStatusLowLimit_, false );
} }
if(axErr == 11) { if(axErr == 11) {
setIntegerParam(pC_->motorStatusFollowingError_,true ); setIntegerParam(pC_->motorStatusFollowingError_,true );
updateMsgTxtFromDriver("Following error triggered");
} else { } else {
setIntegerParam(pC_->motorStatusFollowingError_,false); setIntegerParam(pC_->motorStatusFollowingError_,false);
} }
@ -485,6 +501,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Axis %d is in deep trouble: axis error code %d, translated: %s:, status code = %d\n", "drvPmacAxisGetStatus: Axis %d is in deep trouble: axis error code %d, translated: %s:, status code = %d\n",
axisNo_, axErr, axMessage, axStat); axisNo_, axErr, axMessage, axStat);
snprintf(message,sizeof(message), "PMAC Axis error: %s",axMessage);
updateMsgTxtFromDriver(message);
if(axMessage != NULL){ if(axMessage != NULL){
free(axMessage); free(axMessage);
} }

View File

@ -7,17 +7,20 @@
* Matthew Pearson * Matthew Pearson
* 23 May 2012 * 23 May 2012
* *
* Modified to use the MsgTxt field for SINQ
*
* Mark Koennecke, January 2019
********************************************/ ********************************************/
#ifndef pmacAxis_H #ifndef pmacAxis_H
#define pmacAxis_H #define pmacAxis_H
#include "asynMotorController.h" #include "SINQController.h"
#include "asynMotorAxis.h" #include "SINQAxis.h"
class pmacController; class pmacController;
class pmacAxis : public asynMotorAxis class pmacAxis : public SINQAxis
{ {
public: public:
/* These are the methods we override from the base class */ /* These are the methods we override from the base class */

View File

@ -13,6 +13,11 @@
* This affects also the commands they understand. * This affects also the commands they understand.
* *
* Mark Koennecke, February 2013 * Mark Koennecke, February 2013
*
* Updated to use the MsgTxt field for error messages as
* used at ESS and SINQ
*
* Mark Koennecke, January 2019
********************************************/ ********************************************/
@ -38,6 +43,7 @@ using std::endl;
#include "asynOctetSyncIO.h" #include "asynOctetSyncIO.h"
#include "pmacController.h" #include "pmacController.h"
#include "pmacAxis.h"
#define MULT 1000. #define MULT 1000.
@ -132,12 +138,7 @@ extern "C" {
pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, pmacController::pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress,
int numAxes, double movingPollPeriod, double idlePollPeriod) int numAxes, double movingPollPeriod, double idlePollPeriod)
: asynMotorController(portName, numAxes+1, NUM_MOTOR_DRIVER_PARAMS, : SINQController(portName, lowLevelPortName, numAxes+1)
0, // No additional interfaces
0, // No addition interrupt interfaces
ASYN_CANBLOCK | ASYN_MULTIDEVICE,
1, // autoconnect
0, 0) // Default priority and stack size
{ {
static const char *functionName = "pmacController::pmacController"; static const char *functionName = "pmacController::pmacController";
@ -251,7 +252,7 @@ asynStatus pmacController::printConnectedStatus()
* @param command - String command to send. * @param command - String command to send.
* @response response - String response back. * @response response - String response back.
*/ */
asynStatus pmacController::lowLevelWriteRead(const char *command, char *response) asynStatus pmacController::lowLevelWriteRead(int axisNo, const char *command, char *response)
{ {
asynStatus status = asynSuccess; asynStatus status = asynSuccess;
@ -260,6 +261,7 @@ asynStatus pmacController::lowLevelWriteRead(const char *command, char *response
size_t nread = 0; size_t nread = 0;
int commsError = 0; int commsError = 0;
static const char *functionName = "pmacController::lowLevelWriteRead"; static const char *functionName = "pmacController::lowLevelWriteRead";
pmacAxis *axis = getAxis(axisNo);
debugFlow(functionName); debugFlow(functionName);
@ -286,6 +288,9 @@ asynStatus pmacController::lowLevelWriteRead(const char *command, char *response
if (status) { if (status) {
asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR, "%s: Error from pasynOctetSyncIO->writeRead. command: %s\n", functionName, command); asynPrint(lowLevelPortUser_, ASYN_TRACE_ERROR, "%s: Error from pasynOctetSyncIO->writeRead. command: %s\n", functionName, command);
setIntegerParam(this->motorStatusCommsError_, 1); setIntegerParam(this->motorStatusCommsError_, 1);
if(axis!= NULL){
axis->updateMsgTxtFromDriver("Lost connection to motor controller");
}
} else { } else {
setIntegerParam(this->motorStatusCommsError_, 0); setIntegerParam(this->motorStatusCommsError_, 0);
} }
@ -422,7 +427,7 @@ asynStatus pmacController::writeFloat64(asynUser *pasynUser, epicsFloat64 value)
//Execute the command. //Execute the command.
if (command[0] != 0 && status == asynSuccess) { if (command[0] != 0 && status == asynSuccess) {
status = lowLevelWriteRead(command, response); status = lowLevelWriteRead(pAxis->axisNo_,command, response);
} }
//Call base class method //Call base class method

View File

@ -7,19 +7,23 @@
* Matthew Pearson * Matthew Pearson
* 23 May 2012 * 23 May 2012
* *
*
* Modified to use the MsgTxt field for SINQ
*
* Mark Koennecke, January 2019
********************************************/ ********************************************/
#ifndef pmacController_H #ifndef pmacController_H
#define pmacController_H #define pmacController_H
#include "asynMotorController.h" #include "SINQController.h"
#include "asynMotorAxis.h" #include "asynMotorAxis.h"
#include "pmacAxis.h" #include "pmacAxis.h"
#define PMAC_C_GlobalStatusString "PMAC_C_GLOBALSTATUS" #define PMAC_C_GlobalStatusString "PMAC_C_GLOBALSTATUS"
#define PMAC_C_CommsErrorString "PMAC_C_COMMSERROR" #define PMAC_C_CommsErrorString "PMAC_C_COMMSERROR"
class pmacController : public asynMotorController { class pmacController : public SINQController {
public: public:
pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod, pmacController(const char *portName, const char *lowLevelPortName, int lowLevelPortAddress, int numAxes, double movingPollPeriod,
@ -49,7 +53,7 @@ class pmacController : public asynMotorController {
private: private:
asynUser* lowLevelPortUser_; asynUser* lowLevelPortUser_;
epicsUInt32 debugFlag_; epicsUInt32 debugFlag_;
asynStatus lowLevelWriteRead(const char *command, char *response); asynStatus lowLevelWriteRead(int axisNo, const char *command, char *response);
int lowLevelPortConnect(const char *port, int addr, asynUser **ppasynUser, char *inputEos, char *outputEos); int lowLevelPortConnect(const char *port, int addr, asynUser **ppasynUser, char *inputEos, char *outputEos);
void debugFlow(const char *message); void debugFlow(const char *message);