Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 46 additions & 63 deletions pmacApp/src/pmacAxis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pmacAxis::pmacAxis(pmacController *pC, int axisNo)
highLimit_ = 0.0;
lowLimit_ = 0.0;
limitsDisabled_ = 0;
limitsEnabled_ = true;
stepSize_ = 1; //Don't need?
deferredPosition_ = 0.0;
cachedPosition_ = 0.0;
Expand All @@ -92,6 +93,7 @@ pmacAxis::pmacAxis(pmacController *pC, int axisNo)
fatal_following_ = 0;
encoder_axis_ = 0;
limitsCheckDisable_ = 0;
limitsEnableAddr_ = "";
nowTimeSecs_ = 0.0;
lastTimeSecs_ = 0.0;
printNextError_ = false;
Expand Down Expand Up @@ -147,15 +149,15 @@ void pmacAxis::initialSetup(int axisNo) {

callParamCallbacks();
if (axisNo > 0) {
char var[16];
char var[32];
// Request position readback
sprintf(var, "#%dP", axisNo);
pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var);
// Request following error readback
sprintf(var, "#%dF", axisNo);
pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var);
// Request ixx24 readback
sprintf(var, "i%d24", axisNo);
sprintf(var, "%s", pC_->pHardware_->getAxisLimitsCmd(axisNo).c_str());
pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var);

// Setup any specific hardware status items
Expand Down Expand Up @@ -330,12 +332,12 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do
}

#ifdef REMOVE_LIMITS_ON_HOME
if (limitsDisabled_) {
if (!limitsEnabled_) {
char buffer[PMAC_MAXBUF] = {0};
/* Re-enable limits */
sprintf(buffer, " i%d24=i%d24&$FDFFFF", axisNo_, axisNo_);
strncat(buffer, pC_->pHardware_->getRestoreAxisLimitsCmd(axisNo_, limitsEnableAddr_).c_str(), PMAC_MAXBUF - 1);
strncat(command, buffer, PMAC_MAXBUF - 1);
limitsDisabled_ = 0;
limitsEnabled_ = true;
}
#endif
debug(DEBUG_TRACE, functionName, "Axis Move command", command);
Expand Down Expand Up @@ -393,39 +395,26 @@ pmacAxis::home(double min_velocity, double max_velocity, double acceleration, in
double home_velocity = 0.0;
char buffer[PMAC_MAXBUF] = {0};

/* Discover type of controller */
strncpy(buffer, "cid", PMAC_MAXBUF);
status = pC_->lowLevelWriteRead(buffer, response);
if (status != asynSuccess) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"Controller %s Addr %d. %s: ERROR Reading Controller Type.\n", pC_->portName, axisNo_,
functionName);
return asynError;
}
nvals = sscanf(response, "%d", &controller_type);

if (controller_type == pC_->PMAC_CID_GEOBRICK_ || controller_type == pC_->PMAC_CID_CLIPPER_) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
"Controller %s Addr %d. %s: This is a Geobrick LV.\n", pC_->portName, axisNo_,
functionName);
} else if (controller_type == pC_->PMAC_CID_PMAC_) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
"Controller %s Addr %d. %s: This is a Turbo PMAC 2 Ultralite.\n", pC_->portName,
axisNo_, functionName);
} else if (controller_type == pC_->PMAC_CID_POWER_) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
"Controller %s Addr %d. %s: This is a Power Brick.\n", pC_->portName,
axisNo_, functionName);
} else {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"Controller %s Addr %d. %s: ERROR Unknown controller type = %d.\n", pC_->portName,
axisNo_, functionName, controller_type);
return asynError;
controller_type = pC_->cid_;
if ( controller_type == pC_->PMAC_CID_POWER_) {
/* Read home flags and home direction from PowerBrick LV */
// ixx23 and ixx26 are just valid up to Motor[49], so to avoid execptions the Motor[x] structure was used instead
// ixx24 has a different purpose on PowerPMAC, so Motor[x].pLimits was used instead
// 'Gate3' was used instead of the alias 'PowerBrick' to reduce the number of characters

int gateIndex = (axisNo_ < 5) ? 0 : 1;
int chanIndex = (axisNo_ < 5) ? axisNo_ - 1 : axisNo_ - 5;
char limitsAddress[PMAC_MAXBUF] = {0};
// strncpy(limitsAddress, response, PMAC_MAXBUF);
sprintf(buffer, "Gate3[%d].Chan[%d].CaptCtrl Gate3[%d].Chan[%d].CaptFlagSel Motor[%d].pLimits Motor[%d].HomeVel Motor[%d].HomeOffset",
gateIndex, chanIndex, gateIndex, chanIndex, axisNo_, axisNo_, axisNo_);
status = (pC_->lowLevelWriteRead(buffer, response));
nvals = sscanf(response, "%d %d %s %lf %d", &home_type, &home_flag, limitsAddress, &home_velocity,
&home_offset);
}

// TODO: store flag_mode for re-enabling the limits correctly
if (controller_type == pC_->PMAC_CID_GEOBRICK_
|| controller_type == pC_->PMAC_CID_CLIPPER_
|| controller_type == pC_->PMAC_CID_POWER_) {
|| controller_type == pC_->PMAC_CID_CLIPPER_) {
/* Read home flags and home direction from Geobrick LV */
if (axisNo_ < 5) {
sprintf(buffer, "I70%d2 I70%d3 i%d24 i%d23 i%d26", axisNo_, axisNo_, axisNo_, axisNo_,
Expand Down Expand Up @@ -466,12 +455,12 @@ pmacAxis::home(double min_velocity, double max_velocity, double acceleration, in

if ((home_type <= 15) &&
(home_type % 4 >= 2) &&
!(flag_mode & 0x20000) &&
limitsEnabled_ &&
((home_velocity > 0 && home_flag == 1 && home_offset <= 0) ||
(home_velocity < 0 && home_flag == 2 && home_offset >= 0))) {
sprintf(buffer, " i%d24=i%d24|$20000", axisNo_, axisNo_);
strncat(command, buffer, PMAC_MAXBUF - 1);
limitsDisabled_ = 1;
// Concatenate string to disable limits to command
strncat(command, pC_->pHardware_->getDisableAxisLimitsCmd(axisNo_).c_str(), PMAC_MAXBUF - 1);
limitsEnabled_ = false;
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW,
"%s. Disabling limits whilst homing PMAC controller %s, axis %d, type:%d, flag:$%x, vel:%f\n",
functionName, pC_->portName, axisNo_, home_type, home_flag, home_velocity);
Expand Down Expand Up @@ -517,12 +506,12 @@ asynStatus pmacAxis::moveVelocity(double min_velocity, double max_velocity, doub
sprintf(command, "%s%s#%d %s", vel_buff, acc_buff, axisNo_, (max_velocity < 0 ? "J-" : "J+"));

#ifdef REMOVE_LIMITS_ON_HOME
if (limitsDisabled_) {
if (!limitsEnabled_) {
char buffer[PMAC_MAXBUF];
/* Re-enable limits */
sprintf(buffer, " i%d24=i%d24&$FDFFFF", axisNo_, axisNo_);
strncat(buffer, pC_->pHardware_->getRestoreAxisLimitsCmd(axisNo_, limitsEnableAddr_).c_str(), PMAC_MAXBUF - 1);
strncat(command, buffer, PMAC_MAXBUF - 1);
limitsDisabled_ = 0;
limitsEnabled_ = true;
}
#endif
debug(DEBUG_TRACE, functionName, "Axis MoveVelocity command", command);
Expand Down Expand Up @@ -678,7 +667,6 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) {
double enc_position = 0;
int nvals = 0;
int axisProblemFlag = 0;
int limitsDisabledBit = 0;
bool printErrors = true;
char key[16];
std::string value = "";
Expand Down Expand Up @@ -840,21 +828,16 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) {
// flag, which the user can set to disable this feature.*/
if (!limitsCheckDisable_) {
// Check we haven't intentially disabled limits for homing.
if (!limitsDisabled_) {
// Parse ixx24
sprintf(key, "i%d24", axisNo_);
value = sPtr->readValue(key);
sscanf(value.c_str(), "$%x", &limitsDisabledBit);
limitsDisabledBit = ((0x20000 & limitsDisabledBit) >> 17);
if (limitsDisabledBit) {
axisProblemFlag = 1;
if (printErrors) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"*** WARNING *** Limits are disabled on controller %s, axis %d\n",
pC_->portName, axisNo_);
printNextError_ = false;
}
}
// Parse ixx24 or Motor[x].pLimits
retStatus = pC_->pHardware_->parseAxisLimitsCmd(axisNo_, sPtr, &limitsEnabled_, limitsEnableAddr_);
if (!(limitsEnabled_)) {
axisProblemFlag = 1;
if (printErrors) {
asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR,
"*** WARNING *** Limits are disabled on controller %s, axis %d\n",
pC_->portName, axisNo_);
printNextError_ = false;
}
}
}
setIntegerParam(pC_->motorStatusProblem_, axisProblemFlag);
Expand All @@ -866,12 +849,12 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) {
}

#ifdef REMOVE_LIMITS_ON_HOME
if (limitsDisabled_ && (axStatus.status24Bit2_ & pC_->PMAC_STATUS2_HOME_COMPLETE) &&
if (!limitsEnabled_ && (axStatus.status24Bit2_ & pC_->PMAC_STATUS2_HOME_COMPLETE) &&
(axStatus.status24Bit1_ & pC_->PMAC_STATUS1_DESIRED_VELOCITY_ZERO)) {
// Re-enable limits
sprintf(command, "i%d24=i%d24&$FDFFFF", axisNo_, axisNo_);
strncat(command, pC_->pHardware_->getRestoreAxisLimitsCmd(axisNo_, limitsEnableAddr_).c_str(), PMAC_MAXBUF - 1);
cmdStatus = pC_->lowLevelWriteRead(command, response);
limitsDisabled_ = (cmdStatus != 0);
limitsEnabled_ = (cmdStatus == 0);
}
#endif
// Set amplifier enabled bit.
Expand Down Expand Up @@ -935,7 +918,7 @@ asynStatus pmacAxis::poll(bool *moving) {
}
callParamCallbacks();

// If the controller is initialised and connected, but this axis is not
// If the controller is initialised and connected, but this axis is not
// then re-execute the initialisation
if (pC_->initialised_ && pC_->connected_ && !initialised_){
initialSetup(axisNo_);
Expand Down
11 changes: 7 additions & 4 deletions pmacApp/src/pmacAxis.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/********************************************
* pmacAxis.cpp
*
* PMAC Asyn motor based on the
*
* PMAC Asyn motor based on the
* asynMotorAxis class.
*
*
* Matthew Pearson
* 23 May 2012
*
*
********************************************/

#ifndef pmacAxis_H
Expand Down Expand Up @@ -101,6 +101,7 @@ class pmacAxis : public asynMotorAxis, pmacCallbackInterface, public pmacDebugge
double highLimit_;
double lowLimit_;
int limitsDisabled_;
bool limitsEnabled_;
double stepSize_;
double deferredPosition_;
double cachedPosition_;
Expand All @@ -118,12 +119,14 @@ class pmacAxis : public asynMotorAxis, pmacCallbackInterface, public pmacDebugge
int fatal_following_;
int encoder_axis_;
int limitsCheckDisable_;
std::string limitsEnableAddr_;
epicsTimeStamp nowTime_;
epicsFloat64 nowTimeSecs_;
epicsFloat64 lastTimeSecs_;
bool printNextError_;
bool moving_; // only valid within poll time - used as a hint for validating deferred coordinated moves
axisStatus status_;
bool limitsStatus_;

bool connected_; // Current connection status of the hardware
bool initialised_; // We need to keep a record of this in case the software starts up without a connection
Expand Down
8 changes: 8 additions & 0 deletions pmacApp/src/pmacHardwareInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ class pmacHardwareInterface {

virtual asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &status) = 0;

virtual std::string getAxisLimitsCmd(int axis) = 0;

virtual std::string getDisableAxisLimitsCmd(int axis) = 0;

virtual std::string getRestoreAxisLimitsCmd(int axis, const std::string savedStatus) = 0;

virtual asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, bool *limitsEnabled, std::string &pLimitsString) = 0;

virtual asynStatus setupCSStatus(int csNo) = 0;

virtual asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &status) = 0;
Expand Down
72 changes: 70 additions & 2 deletions pmacApp/src/pmacHardwarePower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

const std::string pmacHardwarePower::GLOBAL_STATUS = "?";
const std::string pmacHardwarePower::AXIS_STATUS = "#%d?";
const std::string pmacHardwarePower::AXIS_LIMITS = "Motor[%d].pLimits";
const std::string pmacHardwarePower::AXIS_CS_NUMBER = "Motor[%d].Coord";
const std::string pmacHardwarePower::CS_STATUS = "&%d?";
const std::string pmacHardwarePower::CS_INPOS = "Coord[%d].InPos";
Expand Down Expand Up @@ -141,8 +142,7 @@ asynStatus pmacHardwarePower::setupAxisStatus(int axis) {
return status;
}

asynStatus
pmacHardwarePower::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus) {
asynStatus pmacHardwarePower::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus) {
asynStatus status = asynSuccess;
int nvals = 0;
int dummyVal = 0;
Expand Down Expand Up @@ -217,6 +217,74 @@ pmacHardwarePower::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus
return status;
}

std::string pmacHardwarePower::getAxisLimitsCmd(int axis) {
char cmd[32];
static const char *functionName = "getAxisLimitsCmd";

debug(DEBUG_TRACE, functionName, "Axis", axis);
sprintf(cmd, AXIS_LIMITS.c_str(), axis);
return std::string(cmd);
}

static inline std::string trim(const std::string& s) {
size_t start = s.find_first_not_of(" \t\r\n");
size_t end = s.find_last_not_of(" \t\r\n");
return (start == std::string::npos) ? "" : s.substr(start, end - start + 1);
}

std::string pmacHardwarePower::getDisableAxisLimitsCmd(int axis) {
char cmd[32];
static const char *functionName = "getDisableAxisLimitsCmd";
char savedStatus[32];

debug(DEBUG_TRACE, functionName, "Axis", axis);
sprintf(cmd, this->getAxisLimitsCmd(axis).c_str());
printf("DEBUG: savedStatus= '%s'\n", savedStatus);
sprintf(cmd, "Motor[%d].pLimits=0", axis);
printf("DEBUG: DisableAxisLimitsCmd= '%s'\n", cmd);

return std::string(cmd);
}

std::string pmacHardwarePower::getRestoreAxisLimitsCmd(int axis, const std::string savedStatus) {
char cmd[128];
static const char *functionName = "getRestoreAxisLimitsCmd";

debug(DEBUG_TRACE, functionName, "Axis", axis);

// Re-enable limits
snprintf(cmd, sizeof(cmd), "Motor[%d].pLimits = %s", axis, savedStatus.c_str());
return std::string(cmd);
}

asynStatus pmacHardwarePower::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, bool *limitsEnabled, std::string &pLimitsString) {
asynStatus status = asynSuccess;
static const char *functionName = "parseAxisLimitsCmd";

debug(DEBUG_TRACE, functionName, "Axis", axis);

// Get the symbolic pointer string
pLimitsString = trim(sPtr->readValue(this->getAxisLimitsCmd(axis))); // e.g., "Gate3[i].Chan[j].Status.a" or "0"
debug(DEBUG_VARIABLE, functionName, "pLimit string", pLimitsString);

if (pLimitsString != "0") {
// Not disabled
// TODO Add sanity checks:
// - Case 1
// - it must begin with: "Gate3", "PowerBrick", "Clipper", "CK3WECS", "ECAT", or related
// - it must end with ".a"
// - Case 2
// - it must begin with: "Sys.pushm", or "Sys.piom"
// - it might contain "+$"
*limitsEnabled = true;
} else {
// Disabled
*limitsEnabled = false;
}

return status;
}

asynStatus pmacHardwarePower::setupCSStatus(int csNo) {
asynStatus status = asynSuccess;
char var[30];
Expand Down
9 changes: 9 additions & 0 deletions pmacApp/src/pmacHardwarePower.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class pmacHardwarePower : public pmacHardwareInterface, pmacDebugger {

asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus);

std::string getAxisLimitsCmd(int axis);

std::string getDisableAxisLimitsCmd(int axis);

std::string getRestoreAxisLimitsCmd(int axis, const std::string savedStatus);

asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, bool *limitsEnabled, std::string &pLimitsString);

asynStatus setupCSStatus(int csNo);

asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus);
Expand Down Expand Up @@ -65,6 +73,7 @@ class pmacHardwarePower : public pmacHardwareInterface, pmacDebugger {
private:
static const std::string GLOBAL_STATUS;
static const std::string AXIS_STATUS;
static const std::string AXIS_LIMITS;
static const std::string AXIS_CS_NUMBER;
static const std::string CS_STATUS;
static const std::string CS_INPOS;
Expand Down
Loading