Bugfix + cleanup

This commit is contained in:
Michele Brambilla
2022-03-10 15:26:08 +01:00
committed by brambilla_m
parent 92364a1de8
commit ad05433602

View File

@ -15,8 +15,8 @@
* I use a starting flag to catch a peculiar feature of our PMAC implementation:
* when the motor is hung, it wont start. I check for this and cause an alarm.
*
* Another mode where the motor is in trouble is if it stays too long in status 5 or 6.
* I check and cause an alarm in this state too.
* Another mode where the motor is in trouble is if it stays too long in status
*5 or 6. I check and cause an alarm in this state too.
*
* Mark Koennecke, February 2013
*
@ -30,23 +30,22 @@
*
********************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <epicsExit.h>
#include <epicsExport.h>
#include <epicsString.h>
#include <epicsThread.h>
#include <epicsTime.h>
#include <errlog.h>
#include <iocsh.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <epicsTime.h>
#include <epicsThread.h>
#include <epicsExport.h>
#include <epicsExit.h>
#include <epicsString.h>
#include <iocsh.h>
#include <errlog.h>
#include <typeinfo>
#include "pmacController.h"
#include <typeinfo>
template <typename T>
const char *getClassName(T) {
return typeid(T).name();
@ -59,8 +58,7 @@ const char* getClassName(T) {
#define ABS(x) (x < 0 ? -(x) : (x))
extern "C" void shutdownCallback(void *pPvt)
{
extern "C" void shutdownCallback(void *pPvt) {
pmacController *pC = static_cast<pmacController *>(pPvt);
pC->lock();
@ -70,10 +68,7 @@ extern "C" void shutdownCallback(void *pPvt)
// These are the pmacAxis class methods
pmacAxis::pmacAxis(pmacController *pC, int axisNo, bool enable)
: SINQAxis(pC, axisNo),
pC_(pC),
autoEnable(enable)
{
: SINQAxis(pC, axisNo), pC_(pC), autoEnable(enable) {
static const char *functionName = "pmacAxis::pmacAxis";
pC_->debugFlow(functionName);
@ -96,26 +91,26 @@ pmacAxis::pmacAxis(pmacController *pC, int axisNo, bool enable)
homing = 0;
next_poll = -1;
/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
/* Set an EPICS exit handler that will shut down polling before asyn kills the
* IP sockets */
epicsAtExit(shutdownCallback, pC_);
// Do an initial poll to get some values from the PMAC
if (getAxisInitialStatus() != asynSuccess) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"%s: getAxisInitialStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
"%s: getAxisInitialStatus failed to return asynSuccess. "
"Controller: %s, Axis: %d.\n",
functionName, pC_->portName, axisNo_);
}
callParamCallbacks();
/* Wake up the poller task which will make it do a poll,
* updating values for this axis to use the new resolution (stepSize_) */
pC_->wakeupPoller();
}
asynStatus pmacAxis::getAxisInitialStatus(void)
{
asynStatus pmacAxis::getAxisInitialStatus(void) {
char command[pC_->PMAC_MAXBUF_];
char response[pC_->PMAC_MAXBUF_];
int cmdStatus = 0;
@ -130,7 +125,9 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%lf", &scale_);
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_);
return asynError;
}
@ -138,7 +135,9 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d", &limVal);
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_);
return asynError;
}
high_limit = ((double)limVal) * scale_;
@ -147,20 +146,23 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d", &limVal);
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_);
return asynError;
}
low_limit = ((double)limVal) * scale_;
char message[132];
sprintf(message,"scale_factor = %lf, high = %lf, low = %lf", scale_,high_limit, low_limit);
sprintf(message, "scale_factor = %lf, high = %lf, low = %lf", scale_,
high_limit, low_limit);
pC_->debugFlow(message);
setIntegerParam(pC_->motorStatusHasEncoder_, 1);
/*
In some configurations at SINQ, the high and low limits are interchanged in the motor controller.
This messy bit of code takes care of this messy electronics configuration.
In some configurations at SINQ, the high and low limits are interchanged in
the motor controller. This messy bit of code takes care of this messy
electronics configuration.
*/
if (high_limit > low_limit) {
setDoubleParam(pC_->motorLowLimit_, low_limit);
@ -174,10 +176,13 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
// Warning: Selene lift axis should not be automatically enabled
if (autoEnable) {
sprintf(command, "M%2.2d14=1\n", axisNo_);
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Enable axis %d: %s",axisNo_,command);
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, "Enable axis %d: %s",
axisNo_, command);
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
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;
}
}
@ -187,15 +192,12 @@ asynStatus pmacAxis::getAxisInitialStatus(void)
return asynSuccess;
}
pmacAxis::~pmacAxis()
{
pmacAxis::~pmacAxis() {
// Destructor
}
asynStatus pmacAxis::move(double position, int relative, double min_velocity, double max_velocity, double acceleration)
{
asynStatus pmacAxis::move(double position, int relative, double min_velocity,
double max_velocity, double acceleration) {
asynStatus status = asynError;
static const char *functionName = "pmacAxis::move";
double realPosition;
@ -218,7 +220,8 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
status6Time = 0;
starting = 1;
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(axisNo_, command, response);
@ -227,10 +230,8 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
return status;
}
asynStatus pmacAxis::home(double min_velocity, double max_velocity, double acceleration, int forwards)
{
asynStatus pmacAxis::home(double min_velocity, double max_velocity,
double acceleration, int forwards) {
asynStatus status = asynError;
char command[128] = {0};
char response[128] = {0};
@ -250,8 +251,8 @@ asynStatus pmacAxis::home(double min_velocity, double max_velocity, double accel
return status;
}
asynStatus pmacAxis::moveVelocity(double min_velocity, double max_velocity, double acceleration)
{
asynStatus pmacAxis::moveVelocity(double min_velocity, double max_velocity,
double acceleration) {
asynStatus status = asynError;
static const char *functionName = "pmacAxis::moveVelocity";
@ -264,9 +265,7 @@ asynStatus pmacAxis::moveVelocity(double min_velocity, double max_velocity, doub
return status;
}
asynStatus pmacAxis::setPosition(double position)
{
asynStatus pmacAxis::setPosition(double position) {
// int status = 0;
static const char *functionName = "pmacAxis::setPosition";
errlogPrintf("executing : %s\n", functionName);
@ -278,8 +277,7 @@ asynStatus pmacAxis::setPosition(double position)
return asynSuccess;
}
asynStatus pmacAxis::stop(double acceleration)
{
asynStatus pmacAxis::stop(double acceleration) {
asynStatus status = asynError;
static const char *functionName = "pmacAxis::stopAxis";
@ -294,8 +292,7 @@ asynStatus pmacAxis::stop(double acceleration)
return status;
}
asynStatus pmacAxis::poll(bool *moving)
{
asynStatus pmacAxis::poll(bool *moving) {
int status = 0;
static const char *functionName = "pmacAxis::poll";
char message[132];
@ -311,7 +308,9 @@ asynStatus pmacAxis::poll(bool *moving)
// Now poll axis status
if ((status = this->getAxisStatus(moving)) != asynSuccess) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, "
"Axis: %d.\n",
functionName, pC_->portName, axisNo_);
}
if (*moving) {
@ -324,8 +323,7 @@ asynStatus pmacAxis::poll(bool *moving)
return status ? asynError : asynSuccess;
}
static char *translateAxisError(int axErr)
{
static char *translateAxisError(int axErr) {
switch (axErr) {
case 0:
return strdup("");
@ -372,11 +370,11 @@ static char *translateAxisError(int axErr)
}
}
asynStatus pmacAxis::getAxisStatus(bool *moving)
{
asynStatus pmacAxis::getAxisStatus(bool *moving) {
char command[pC_->PMAC_MAXBUF_];
char response[pC_->PMAC_MAXBUF_];
int cmdStatus = 0;;
int cmdStatus = 0;
;
int done = 0, posChanging = 0;
double position = 0;
int nvals = 0;
@ -384,13 +382,15 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
epicsUInt32 axErr = 0, highLim = 0, lowLim = 0;
char message[132], *axMessage;
/* 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_);
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d", &axErr);
if (cmdStatus || nvals != 1) {
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);
updateMsgTxtFromDriver("Cannot read Axis Error Status");
}
@ -400,7 +400,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
nvals = sscanf(response, "%lf", &position);
if (cmdStatus || nvals != 1) {
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);
updateMsgTxtFromDriver("Cannot read Axis position");
}
@ -410,7 +411,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
nvals = sscanf(response, "%d", &axStat);
if (cmdStatus || nvals != 1) {
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);
updateMsgTxtFromDriver("Cannot read Axis Status");
}
@ -420,7 +422,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
nvals = sscanf(response, "%d", &highLim);
if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read high limit flag Status: %d\nCommand :%s\nResponse:%s\n",
"drvPmacAxisGetStatus: Failed to read high limit flag Status: "
"%d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response);
}
@ -429,11 +432,11 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
nvals = sscanf(response, "%d", &lowLim);
if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to low limit flag Status: %d\nCommand :%s\nResponse:%s\n",
"drvPmacAxisGetStatus: Failed to low limit flag Status: "
"%d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response);
}
int direction = 0;
setDoubleParam(pC_->motorPosition_, position * MULT);
@ -453,7 +456,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
previous_position_ = position;
previous_direction_ = direction;
// errlogPrintf("Polling, axStat = %d, axErr = %d, position = %f\n", axStat, axErr, position);
// errlogPrintf("Polling, axStat = %d, axErr = %d, position = %f\n", axStat,
// axErr, position);
/* are we done? */
if ((axStat == 0 || axStat == 14 || axStat < 0) && starting == 0) {
@ -494,8 +498,11 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
setIntegerParam(pC_->motorStatusMoving_, false);
setIntegerParam(pC_->motorStatusDone_, true);
setIntegerParam(pC_->motorStatusProblem_, true);
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");
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;
return asynSuccess;
} else {
@ -506,7 +513,6 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
}
}
if (!done) {
*moving = true;
setIntegerParam(pC_->motorStatusMoving_, true);
@ -550,7 +556,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
if (axisErrorCount < 10) {
axMessage = translateAxisError(axErr);
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);
snprintf(message, sizeof(message), "PMAC Axis error: %s", axMessage);
updateMsgTxtFromDriver(message);
@ -559,7 +566,8 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
}
axisErrorCount++;
} else if (axisErrorCount == 10) {
asynPrint(pC_->pasynUserSelf,ASYN_TRACE_ERROR, "Suppressing further axis error messages\n");
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"Suppressing further axis error messages\n");
axisErrorCount++;
}
} else {
@ -568,12 +576,10 @@ asynStatus pmacAxis::getAxisStatus(bool *moving)
}
setIntegerParam(pC_->motorStatusProblem_, axisProblemFlag);
return asynSuccess;
}
asynStatus pmacHRPTAxis::getAxisStatus(bool *moving)
{
asynStatus pmacHRPTAxis::getAxisStatus(bool *moving) {
char command[pC_->PMAC_MAXBUF_];
char response[pC_->PMAC_MAXBUF_];
int cmdStatus = 0, nvals, crashSignal;
@ -584,7 +590,8 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving)
nvals = sscanf(response, "%d", &crashSignal);
if (cmdStatus || nvals != 1) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read crash flag Status: %d\nCommand :%s\nResponse:%s\n",
"drvPmacAxisGetStatus: Failed to read crash flag Status: "
"%d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response);
}
if (crashSignal == 1) {
@ -595,7 +602,6 @@ asynStatus pmacHRPTAxis::getAxisStatus(bool *moving)
setIntegerParam(pC_->motorStatusMoving_, false);
setIntegerParam(pC_->motorStatusDone_, true);
setIntegerParam(pC_->motorStatusProblem_, true);
}
return result;
}
@ -610,10 +616,10 @@ asynStatus pmacAxis::enable(int on) {
return asynSuccess;
}
/*================================= SeleneAxis code ======================================================*/
/*================================= SeleneAxis code
* ======================================================*/
SeleneAxis::SeleneAxis(SeleneController *pC, int axisNo, double limitTarget)
: pmacAxis(pC, axisNo, false)
{
: pmacAxis(pC, axisNo, false) {
static const char *functionName = "pmacAxis::pmacAxis";
pC_->debugFlow(functionName);
@ -635,27 +641,27 @@ SeleneAxis::SeleneAxis(SeleneController *pC, int axisNo, double limitTarget)
starting = 0;
homing = 0;
/* Set an EPICS exit handler that will shut down polling before asyn kills the IP sockets */
/* Set an EPICS exit handler that will shut down polling before asyn kills the
* IP sockets */
epicsAtExit(shutdownCallback, pC_);
// Do an initial poll to get some values from the PMAC
if (getSeleneAxisInitialStatus() != asynSuccess) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"%s: getAxisInitialStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
"%s: getAxisInitialStatus failed to return asynSuccess. "
"Controller: %s, Axis: %d.\n",
functionName, pC_->portName, axisNo_);
}
this->limitTarget = limitTarget;
callParamCallbacks();
/* Wake up the poller task which will make it do a poll,
* updating values for this axis to use the new resolution (stepSize_) */
pC_->wakeupPoller();
}
/*-------------------------------------------------------------------------------------------*/
asynStatus SeleneAxis::getSeleneAxisInitialStatus(void)
{
asynStatus SeleneAxis::getSeleneAxisInitialStatus(void) {
char command[pC_->PMAC_MAXBUF_];
char response[pC_->PMAC_MAXBUF_];
int cmdStatus = 0;
@ -670,7 +676,9 @@ asynStatus SeleneAxis::getSeleneAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%lf", &scale_);
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_);
return asynError;
}
@ -678,7 +686,9 @@ asynStatus SeleneAxis::getSeleneAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d", &limVal);
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_);
return asynError;
}
high_limit = ((double)limVal) * scale_;
@ -687,20 +697,23 @@ asynStatus SeleneAxis::getSeleneAxisInitialStatus(void)
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d", &limVal);
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_);
return asynError;
}
low_limit = ((double)limVal) * scale_;
char message[132];
sprintf(message,"scale_factor = %lf, high = %lf, low = %lf", scale_,high_limit, low_limit);
sprintf(message, "scale_factor = %lf, high = %lf, low = %lf", scale_,
high_limit, low_limit);
pC_->debugFlow(message);
setIntegerParam(pC_->motorStatusHasEncoder_, 1);
/*
In some configurations at SINQ, the high and low limits are interchanged in the motor controller.
This messy bit of code takes care of this messy electronics configuration.
In some configurations at SINQ, the high and low limits are interchanged in
the motor controller. This messy bit of code takes care of this messy
electronics configuration.
*/
if (high_limit > low_limit) {
setDoubleParam(pC_->motorLowLimit_, low_limit);
@ -715,10 +728,9 @@ asynStatus SeleneAxis::getSeleneAxisInitialStatus(void)
return asynSuccess;
}
/*----------------------------------------------------------------------------------------------------------*/
asynStatus SeleneAxis::home(double min_velocity, double max_velocity, double acceleration, int forwards)
{
asynStatus SeleneAxis::home(double min_velocity, double max_velocity,
double acceleration, int forwards) {
asynStatus status = asynError;
static const char *functionName = "SeleneAxis::home";
@ -726,12 +738,11 @@ asynStatus SeleneAxis::home(double min_velocity, double max_velocity, double acc
updateMsgTxtFromDriver("Cannot home on this axis type");
return status;
}
/*----------------------------------------------------------------------------------------------------------------*/
asynStatus SeleneAxis::move(double position, int relative, double min_velocity, double max_velocity, double acceleration)
{
asynStatus SeleneAxis::move(double position, int relative, double min_velocity,
double max_velocity, double acceleration) {
asynStatus status = asynError;
static const char *functionName = "SeleneAxis::move";
double realPosition;
@ -771,8 +782,7 @@ asynStatus SeleneAxis::move(double position, int relative, double min_velocity,
return status;
}
/*----------------------------------------------------------------------------------------------------*/
asynStatus SeleneAxis::setPosition(double position)
{
asynStatus SeleneAxis::setPosition(double position) {
asynStatus status = asynError;
static const char *functionName = "SeleneAxis::setPosition";
char command[128] = {0};
@ -785,18 +795,17 @@ asynStatus SeleneAxis::setPosition(double position)
errlogPrintf("Sending set position : %s\n", command);
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
"Setting Position on %d to value %f, command: %s",
axisNo_, position/MULT, command);
"Setting Position on %d to value %f, command: %s", axisNo_,
position / MULT, command);
next_poll = -1;
return status;
}
/*======================================= Selene Lift Axis Code ===========================================*/
/*======================================= Selene Lift Axis Code
* ===========================================*/
asynStatus LiftAxis::move(double position, int relative, double min_velocity,
double max_velocity, double acceleration)
{
double max_velocity, double acceleration) {
asynStatus status = asynError;
static const char *functionName = "LiftAxis::move";
double realPosition;
@ -828,11 +837,10 @@ asynStatus LiftAxis::move(double position, int relative, double min_velocity,
return status;
}
/*--------------------------------------------------------------------------------------------------------
Return *moving until the motor moved started moving. This enables the start command
to be sent separatly.
Return *moving until the motor moved started moving. This enables the start
command to be sent separatly.
----------------------------------------------------------------------------------------------------------*/
asynStatus LiftAxis::poll(bool *moving)
{
asynStatus LiftAxis::poll(bool *moving) {
asynStatus status;
// Protect against excessive polling
@ -859,18 +867,16 @@ asynStatus LiftAxis::poll(bool *moving)
return status;
}
/*--------------------------------------------------------------------------------------------------------------*/
asynStatus LiftAxis::stop(double acceleration)
{
asynStatus LiftAxis::stop(double acceleration) {
waitStart = 0;
return pmacAxis::stop(acceleration);
}
/*-------------------------------------------------------------------------------------------------------------*/
pmacV3Axis::pmacV3Axis(pmacController *pController, int axisNo) : pmacAxis(pController,axisNo, false) { };
pmacV3Axis::pmacV3Axis(pmacController *pController, int axisNo)
: pmacAxis(pController, axisNo, false){};
asynStatus pmacV3Axis::poll(bool *moving)
{
asynStatus pmacV3Axis::poll(bool *moving) {
int status = 0;
static const char *functionName = "pmacV3Axis::poll";
char message[132];
@ -886,7 +892,9 @@ asynStatus pmacV3Axis::poll(bool *moving)
// Now poll axis status
if ((status = this->getAxisStatus(moving)) != asynSuccess) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, Axis: %d.\n", functionName, pC_->portName, axisNo_);
"%s: getAxisStatus failed to return asynSuccess. Controller: %s, "
"Axis: %d.\n",
functionName, pC_->portName, axisNo_);
}
if (*moving) {
@ -899,23 +907,217 @@ asynStatus pmacV3Axis::poll(bool *moving)
return status ? asynError : asynSuccess;
}
// asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
// char command[pC_->PMAC_MAXBUF_];
// char response[pC_->PMAC_MAXBUF_];
// int cmdStatus = 0;
// int done = 0, posChanging = 0;
// double position = 0;
// int nvals = 0;
// int axisProblemFlag = 0;
// epicsUInt32 axErr = 0, highLim = 0, lowLim = 0, axDone = 0;
// int axStat=0;
// char message[132], *axMessage;
// static const char *functionName = "pmacV3Axis::getAxisStatus";
// pmacV3Controller* p3C_ = (pmacV3Controller*)pC_;
// sprintf(command, "Q%2.2d10 P%2.2d00 P%2.2d23", axisNo_, axisNo_, axisNo_);
// cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
// nvals = sscanf(response, "%lf %d %d", &position, &axStat, &axDone);
// if (cmdStatus || nvals != 3) {
// asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
// "drvPmacAxisGetStatus: Failed to read position and status, "
// "Status: %d\nCommand :%s\nResponse:%s\n",
// cmdStatus, command, response);
// updateMsgTxtFromDriver("Cannot read Axis position and status");
// }
// int st = setIntegerParam(p3C_->axisEnabled_, axStat >= 0);
// // st = callParamCallbacks();
// // printf("axStat: callParamCallbacks -> ok: %d\n", st == asynSuccess);
// setDoubleParam(pC_->motorPosition_, position * MULT);
// setDoubleParam(pC_->motorEncoderPosition_, position * MULT);
// /* Use previous position and current position to calculate direction.*/
// int direction = previous_direction_;
// if ((position - previous_position_) > 0) {
// direction = 1;
// }
// if ((position - previous_position_) < 0) {
// direction = 0;
// }
// setIntegerParam(pC_->motorStatusDirection_, direction);
// /*Store position to calculate direction for next poll.*/
// previous_position_ = position;
// previous_direction_ = direction;
// // errlogPrintf("Polling, axStat = %d, position = %f\n", axStat, position);
// /* are we done? */
// if ( axDone == 0 && starting == 0) {
// done = 1;
// } else {
// starting = 0;
// done = 0;
// }
// if (starting && time(NULL) > startTime + 10) {
// /*
// did not start in 10 seconds: messed up: cause an alarm
// */
// done = 1;
// *moving = false;
// setIntegerParam(pC_->motorStatusMoving_, false);
// setIntegerParam(pC_->motorStatusDone_, true);
// setIntegerParam(pC_->motorStatusProblem_, true);
// errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n",
// axisNo_); updateMsgTxtFromDriver("Axis did not start within 10 seconds");
// starting = 0;
// callParamCallbacks();
// return asynSuccess;
// }
// /*
// code to test against too long status 5 or 6
// */
// if (axStat == 5 || axStat == 6) {
// if (status6Time == 0) {
// status6Time = time(NULL);
// statusPos = position;
// } else {
// if (time(NULL) > status6Time + 60) {
// /* trigger error only when not moving */
// if (abs(position - statusPos) < .1) {
// done = 1;
// *moving = false;
// setIntegerParam(pC_->motorStatusMoving_, false);
// setIntegerParam(pC_->motorStatusDone_, true);
// setIntegerParam(pC_->motorStatusProblem_, true);
// 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;
// callParamCallbacks();
// return asynSuccess;
// } else {
// status6Time = time(NULL);
// statusPos = position;
// }
// }
// }
// }
// if (!done) {
// *moving = true;
// setIntegerParam(pC_->motorStatusMoving_, true);
// setIntegerParam(pC_->motorStatusDone_, false);
// } else {
// *moving = false;
// setIntegerParam(pC_->motorStatusMoving_, false);
// setIntegerParam(pC_->motorStatusDone_, true);
// if (homing) {
// setIntegerParam(pC_->motorStatusHomed_, done);
// homing = 0;
// }
// }
// sprintf(message, "poll results: axis %d, status %d, done = %d",
// axisNo_, axStat, axDone);
// pC_->debugFlow(message);
// if (*moving == false) {
// sprintf(command, "P%2.2d01 P%2.2d37 P%2.2d38", axisNo_, axisNo_,
// axisNo_); cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
// nvals = sscanf(response, "%d %d %d", &axErr, &highLim, &lowLim);
// if (cmdStatus || nvals != 1) {
// asynPrint(
// pC_->pasynUserSelf, ASYN_TRACE_ERROR,
// "drvPmacAxisGetStatus: Failed to read axis Error, high and low
// limit " "flags Status: %d\nCommand :%s\nResponse:%s\n",
// cmdStatus, command, response);
// updateMsgTxtFromDriver(
// "Cannot read Axis Error, high and low limit flag Status");
// }
// // errlogPrintf("Polling, axErr = %d, highLim = %d, lowLim = %d\n",
// axStat,
// // axErr, highLim, lowLim);
// sprintf(message, "poll results: axis %d, axErr %d", axisNo_, axErr);
// pC_->debugFlow(message);
// /* search for trouble */
// if (highLim) {
// setIntegerParam(pC_->motorStatusHighLimit_, true);
// updateMsgTxtFromDriver("High Limit Hit");
// } else {
// setIntegerParam(pC_->motorStatusHighLimit_, false);
// }
// if (lowLim) {
// setIntegerParam(pC_->motorStatusLowLimit_, true);
// updateMsgTxtFromDriver("Low Limit Hit");
// } else {
// setIntegerParam(pC_->motorStatusLowLimit_, false);
// }
// if (axErr == 11) {
// setIntegerParam(pC_->motorStatusFollowingError_, true);
// updateMsgTxtFromDriver("Following error triggered");
// } else {
// setIntegerParam(pC_->motorStatusFollowingError_, false);
// }
// /* Set any axis specific general problem bits. */
// }
// if ((axStat < 0 && axStat != -3) || axErr != 0) {
// axisProblemFlag = 1;
// if (axisErrorCount < 10) {
// axMessage = translateAxisError(axErr);
// printf("axErr: %d\taxStat: %d\taxMessage: %s\n", axErr, axStat,
// axMessage); asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
// "drvPmacAxisGetStatus: Axis %d is in deep trouble: axis error
// " "code %d, translated: %s:, status code = %d\n", axisNo_,
// axErr, axMessage, axStat);
// snprintf(message, sizeof(message), "PMAC Axis error: %s", axMessage);
// updateMsgTxtFromDriver(message);
// if (axMessage != NULL) {
// free(axMessage);
// }
// axisErrorCount++;
// } else if (axisErrorCount == 10) {
// asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
// "Suppressing further axis error messages\n");
// axisErrorCount++;
// }
// } else {
// axisProblemFlag = 0;
// axisErrorCount = 0;
// }
// setIntegerParam(pC_->motorStatusProblem_, axisProblemFlag);
// callParamCallbacks();
// return asynSuccess;
// }
asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
char command[pC_->PMAC_MAXBUF_];
char response[pC_->PMAC_MAXBUF_];
int cmdStatus = 0;
int done = 0, posChanging = 0;
double position = 0;
int nvals = 0;
int axisProblemFlag = 0;
epicsUInt32 axErr = 0, highLim = 0, lowLim = 0, axDone = 0;
int axStat=0;
int axisProblemFlag = 0, axStat = 0, axDone;
epicsUInt32 axErr = 0, highLim = 0, lowLim = 0;
char message[132], *axMessage;
static const char *functionName = "pmacV3Axis::getAxisStatus";
pmacV3Controller* p3C_ = (pmacV3Controller*)pC_;
sprintf(command, "Q%2.2d10 P%2.2d00 P%2.2d23", axisNo_, axisNo_, axisNo_);
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%lf %d %d", &position, &axStat, &axDone);
@ -927,20 +1129,33 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
updateMsgTxtFromDriver("Cannot read Axis position and status");
}
pmacV3Controller *p3C_ = (pmacV3Controller *)pC_;
int st = setIntegerParam(p3C_->axisEnabled_, axStat >= 0);
// st = callParamCallbacks();
// printf("axStat: callParamCallbacks -> ok: %d\n", st == asynSuccess);
sprintf(command, "P%2.2d01 P%2.2d37 P%2.2d38", axisNo_, axisNo_, axisNo_);
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d %d %d", &axErr, &highLim, &lowLim);
if (cmdStatus || nvals != 3) {
asynPrint(
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read axis Error, high and low limit "
"flags Status: %d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response);
updateMsgTxtFromDriver(
"Cannot read Axis Error, high and low limit flag Status");
}
int direction = 0;
setDoubleParam(pC_->motorPosition_, position * MULT);
setDoubleParam(pC_->motorEncoderPosition_, position * MULT);
/* Use previous position and current position to calculate direction.*/
int direction = previous_direction_;
if ((position - previous_position_) > 0) {
direction = 1;
}
if ((position - previous_position_) < 0) {
} else if (position - previous_position_ == 0.0) {
direction = previous_direction_;
} else {
direction = 0;
}
setIntegerParam(pC_->motorStatusDirection_, direction);
@ -949,10 +1164,11 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
previous_position_ = position;
previous_direction_ = direction;
// errlogPrintf("Polling, axStat = %d, position = %f\n", axStat, position);
// errlogPrintf("Polling, axStat = %d, axErr = %d, position = %f\n", axStat,
// axErr, position);
/* are we done? */
if ( axDone == 0 && starting == 0) {
if ((axStat == 0 || axStat == 14 || axStat < 0) && starting == 0) {
done = 1;
} else {
starting = 0;
@ -971,7 +1187,6 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
errlogPrintf("Axis %d did not start within 10 seconds!! BROKEN\n", axisNo_);
updateMsgTxtFromDriver("Axis did not start within 10 seconds");
starting = 0;
callParamCallbacks();
return asynSuccess;
}
@ -997,7 +1212,6 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
updateMsgTxtFromDriver(
"Axis stayed in 5,6 for more then 60 seconds: BROKEN");
status6Time = 0;
callParamCallbacks();
return asynSuccess;
} else {
status6Time = time(NULL);
@ -1021,29 +1235,8 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
}
}
sprintf(message, "poll results: axis %d, status %d, done = %d",
axisNo_, axStat, axDone);
pC_->debugFlow(message);
if (*moving == false) {
sprintf(command, "P%2.2d01 P%2.2d37 P%2.2d38", axisNo_, axisNo_, axisNo_);
cmdStatus = pC_->lowLevelWriteRead(axisNo_, command, response);
nvals = sscanf(response, "%d %d %d", &axErr, &highLim, &lowLim);
if (cmdStatus || nvals != 1) {
asynPrint(
pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Failed to read axis Error, high and low limit "
"flags Status: %d\nCommand :%s\nResponse:%s\n",
cmdStatus, command, response);
updateMsgTxtFromDriver(
"Cannot read Axis Error, high and low limit flag Status");
}
// errlogPrintf("Polling, axErr = %d, highLim = %d, lowLim = %d\n", axStat,
// axErr, highLim, lowLim);
sprintf(message, "poll results: axis %d, axErr %d", axisNo_, axErr);
sprintf(message, "poll results: axis %d, status %d, axErr %d, done = %d",
axisNo_, axStat, axErr, done);
pC_->debugFlow(message);
/* search for trouble */
@ -1066,13 +1259,10 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
setIntegerParam(pC_->motorStatusFollowingError_, false);
}
/* Set any axis specific general problem bits. */
}
if ((axStat < 0 && axStat != -3) || axErr != 0) {
if (axErr != 0) {
axisProblemFlag = 1;
if (axisErrorCount < 10) {
axMessage = translateAxisError(axErr);
printf("axErr: %d\taxStat: %d\taxMessage: %s\n", axErr, axStat, axMessage);
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"drvPmacAxisGetStatus: Axis %d is in deep trouble: axis error "
"code %d, translated: %s:, status code = %d\n",
@ -1094,8 +1284,5 @@ asynStatus pmacV3Axis::getAxisStatus(bool *moving) {
}
setIntegerParam(pC_->motorStatusProblem_, axisProblemFlag);
callParamCallbacks();
return asynSuccess;
}