From 682a852b30971cc6742a7763a7f03c5029496b9c Mon Sep 17 00:00:00 2001 From: Leandro Martins dos Santos Date: Tue, 29 Apr 2025 12:16:55 +0100 Subject: [PATCH 1/3] Add hardware interface for AxisLimits string --- pmacApp/src/pmacAxis.cpp | 6 +++--- pmacApp/src/pmacHardwareInterface.h | 2 ++ pmacApp/src/pmacHardwarePower.cpp | 13 +++++++++++-- pmacApp/src/pmacHardwarePower.h | 3 +++ pmacApp/src/pmacHardwareTurbo.cpp | 16 ++++++++++++---- pmacApp/src/pmacHardwareTurbo.h | 3 +++ 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/pmacApp/src/pmacAxis.cpp b/pmacApp/src/pmacAxis.cpp index 16b1a456..6e684a37 100755 --- a/pmacApp/src/pmacAxis.cpp +++ b/pmacApp/src/pmacAxis.cpp @@ -155,7 +155,7 @@ void pmacAxis::initialSetup(int axisNo) { sprintf(var, "#%dF", axisNo); pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var); // Request ixx24 readback - sprintf(var, "i%d24", axisNo); + sprintf(var, pC_->pHardware_->getAxisLimitsCmd(axisNo), axisNo); pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var); // Setup any specific hardware status items @@ -333,7 +333,7 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do if (limitsDisabled_) { char buffer[PMAC_MAXBUF] = {0}; /* Re-enable limits */ - sprintf(buffer, " i%d24=i%d24&$FDFFFF", axisNo_, axisNo_); + sprintf(buffer, "i%d24=i%d24&$FDFFFF", axisNo_, axisNo_); strncat(command, buffer, PMAC_MAXBUF - 1); limitsDisabled_ = 0; } @@ -935,7 +935,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_); diff --git a/pmacApp/src/pmacHardwareInterface.h b/pmacApp/src/pmacHardwareInterface.h index a5b751fa..4320f9ef 100644 --- a/pmacApp/src/pmacHardwareInterface.h +++ b/pmacApp/src/pmacHardwareInterface.h @@ -72,6 +72,8 @@ class pmacHardwareInterface { virtual asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &status) = 0; + virtual std::string getAxisLimitsCmd(int axis) = 0; + virtual asynStatus setupCSStatus(int csNo) = 0; virtual asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &status) = 0; diff --git a/pmacApp/src/pmacHardwarePower.cpp b/pmacApp/src/pmacHardwarePower.cpp index 5f230819..a08e297a 100755 --- a/pmacApp/src/pmacHardwarePower.cpp +++ b/pmacApp/src/pmacHardwarePower.cpp @@ -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"; @@ -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; @@ -217,6 +217,15 @@ pmacHardwarePower::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus return status; } +std::string pmacHardwarePower::getAxisLimitsCmd(int axis) { + char cmd[8]; + static const char *functionName = "getAxisLimitsCmd"; + + debug(DEBUG_TRACE, functionName, "Axis", axis); + sprintf(cmd, AXIS_LIMITS.c_str(), axis); + return std::string(cmd); +} + asynStatus pmacHardwarePower::setupCSStatus(int csNo) { asynStatus status = asynSuccess; char var[30]; diff --git a/pmacApp/src/pmacHardwarePower.h b/pmacApp/src/pmacHardwarePower.h index b192ebf9..8ae6c1f0 100755 --- a/pmacApp/src/pmacHardwarePower.h +++ b/pmacApp/src/pmacHardwarePower.h @@ -29,6 +29,8 @@ class pmacHardwarePower : public pmacHardwareInterface, pmacDebugger { asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus); + std::string getAxisLimitsCmd(int axis); + asynStatus setupCSStatus(int csNo); asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus); @@ -65,6 +67,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; diff --git a/pmacApp/src/pmacHardwareTurbo.cpp b/pmacApp/src/pmacHardwareTurbo.cpp index f2d672bd..da4dc7e1 100644 --- a/pmacApp/src/pmacHardwareTurbo.cpp +++ b/pmacApp/src/pmacHardwareTurbo.cpp @@ -10,6 +10,7 @@ const std::string pmacHardwareTurbo::GLOBAL_STATUS = "???"; const std::string pmacHardwareTurbo::AXIS_STATUS = "#%d?"; +const std::string pmacHardwareTurbo::AXIS_LIMITS = "i%d24"; const std::string pmacHardwareTurbo::CS_STATUS = "&%d??"; const std::string pmacHardwareTurbo::CS_VEL_CMD = "&%dQ70=%f "; const std::string pmacHardwareTurbo::CS_ACCELERATION_CMD = "I%d87=%f"; @@ -185,6 +186,15 @@ pmacHardwareTurbo::parseGlobalStatus(const std::string &statusString, globalStat return status; } +std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis) { + char cmd[8]; + static const char *functionName = "getAxisLimitsCmd"; + + debug(DEBUG_TRACE, functionName, "Axis", axis); + sprintf(cmd, AXIS_LIMITS.c_str(), axis); + return std::string(cmd); +} + std::string pmacHardwareTurbo::getAxisStatusCmd(int axis) { char cmd[8]; static const char *functionName = "getAxisStatusCmd"; @@ -203,8 +213,7 @@ asynStatus pmacHardwareTurbo::setupAxisStatus(int axis) { return status; } -asynStatus -pmacHardwareTurbo::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus) { +asynStatus pmacHardwareTurbo::parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus) { asynStatus status = asynSuccess; int nvals = 0; std::string statusString = ""; @@ -278,8 +287,7 @@ asynStatus pmacHardwareTurbo::setupCSStatus(int csNo) { return status; } -asynStatus -pmacHardwareTurbo::parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus) { +asynStatus pmacHardwareTurbo::parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus) { asynStatus status = asynSuccess; int nvals = 0; std::string statusString = ""; diff --git a/pmacApp/src/pmacHardwareTurbo.h b/pmacApp/src/pmacHardwareTurbo.h index c38d9c25..297224de 100644 --- a/pmacApp/src/pmacHardwareTurbo.h +++ b/pmacApp/src/pmacHardwareTurbo.h @@ -29,6 +29,8 @@ class pmacHardwareTurbo : public pmacHardwareInterface, pmacDebugger { asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus); + std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis); + asynStatus setupCSStatus(int csNo); asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus); @@ -66,6 +68,7 @@ class pmacHardwareTurbo : public pmacHardwareInterface, pmacDebugger { static const std::string GLOBAL_STATUS; static const std::string AXIS_STATUS; + static const std::string AXIS_LIMITS; static const std::string CS_STATUS; static const std::string CS_VEL_CMD; static const std::string CS_ACCELERATION_CMD; From f574781d533bda0212ce501d5ec5b2735d76ace8 Mon Sep 17 00:00:00 2001 From: Leandro Martins dos Santos Date: Mon, 16 Jun 2025 11:31:18 +0100 Subject: [PATCH 2/3] Parse axes limits check status --- pmacApp/src/pmacAxis.cpp | 102 +++++++++++++++++----------- pmacApp/src/pmacHardwareInterface.h | 5 ++ pmacApp/src/pmacHardwarePower.cpp | 56 ++++++++++++++- pmacApp/src/pmacHardwarePower.h | 4 ++ pmacApp/src/pmacHardwareTurbo.cpp | 40 ++++++++--- pmacApp/src/pmacHardwareTurbo.h | 4 +- 6 files changed, 160 insertions(+), 51 deletions(-) diff --git a/pmacApp/src/pmacAxis.cpp b/pmacApp/src/pmacAxis.cpp index 6e684a37..c54bab90 100755 --- a/pmacApp/src/pmacAxis.cpp +++ b/pmacApp/src/pmacAxis.cpp @@ -147,7 +147,7 @@ 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); @@ -155,7 +155,7 @@ void pmacAxis::initialSetup(int axisNo) { sprintf(var, "#%dF", axisNo); pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var); // Request ixx24 readback - sprintf(var, pC_->pHardware_->getAxisLimitsCmd(axisNo), axisNo); + sprintf(var, "%s", pC_->pHardware_->getAxisLimitsCmd(axisNo).c_str()); pC_->monitorPMACVariable(pmacMessageBroker::PMAC_FAST_READ, var); // Setup any specific hardware status items @@ -333,6 +333,7 @@ asynStatus pmacAxis::move(double position, int relative, double min_velocity, do if (limitsDisabled_) { char buffer[PMAC_MAXBUF] = {0}; /* Re-enable limits */ + // LMDS sprintf(buffer, "i%d24=i%d24&$FDFFFF", axisNo_, axisNo_); strncat(command, buffer, PMAC_MAXBUF - 1); limitsDisabled_ = 0; @@ -393,39 +394,61 @@ 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; + // /* 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}; + // // Gets limits pointer + // sprintf(buffer, "Motor[%d].pLimits", axisNo_); + // status = pC_->lowLevelWriteRead(buffer, response); + // strncpy(limitsAddress, response, PMAC_MAXBUF); + // sprintf(buffer, "Gate3[%d].Chan[%d].CaptCtrl Gate3[%d].Chan[%d].CaptFlag %s Motor[%d].HomeVel Motor[%d].HomeOffset", + // gateIndex, chanIndex, gateIndex, chanIndex, limitsAddress, axisNo_, axisNo_); + // status = pC_->lowLevelWriteRead(buffer, response); + // nvals = sscanf(response, "%d %d $%x %lf %d", &home_type, &home_flag, &flag_mode, &home_velocity, + // &home_offset); } - 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; - } - + // 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_, @@ -466,10 +489,10 @@ pmacAxis::home(double min_velocity, double max_velocity, double acceleration, in if ((home_type <= 15) && (home_type % 4 >= 2) && - !(flag_mode & 0x20000) && + !(flag_mode & 0x20000) && // are the limits disabled? ((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_); + sprintf(buffer, " i%d24=i%d24|$20000", axisNo_, axisNo_); // Disable limits strncat(command, buffer, PMAC_MAXBUF - 1); limitsDisabled_ = 1; asynPrint(pC_->pasynUserSelf, ASYN_TRACE_FLOW, @@ -678,7 +701,7 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) { double enc_position = 0; int nvals = 0; int axisProblemFlag = 0; - int limitsDisabledBit = 0; + int limitsStatus = 0; bool printErrors = true; char key[16]; std::string value = ""; @@ -842,11 +865,8 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) { // 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) { + retStatus = pC_->pHardware_->parseAxisLimitsCmd(axisNo_, sPtr, &limitsStatus); + if (!(limitsStatus)) { axisProblemFlag = 1; if (printErrors) { asynPrint(pC_->pasynUserSelf, ASYN_TRACE_ERROR, diff --git a/pmacApp/src/pmacHardwareInterface.h b/pmacApp/src/pmacHardwareInterface.h index 4320f9ef..8ad5f5a2 100644 --- a/pmacApp/src/pmacHardwareInterface.h +++ b/pmacApp/src/pmacHardwareInterface.h @@ -74,6 +74,11 @@ class pmacHardwareInterface { virtual std::string getAxisLimitsCmd(int axis) = 0; + virtual asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) = 0; + + // virtual asynStatus disableLimitsCmd(int axis, pmacCommandStore *sPtr, int *savedStatus) = 0; + // virtual asynStatus restoreLimitsCmd(int axis, pmacCommandStore *sPtr, int *savedStatus) = 0; + virtual asynStatus setupCSStatus(int csNo) = 0; virtual asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &status) = 0; diff --git a/pmacApp/src/pmacHardwarePower.cpp b/pmacApp/src/pmacHardwarePower.cpp index a08e297a..3a3500bd 100755 --- a/pmacApp/src/pmacHardwarePower.cpp +++ b/pmacApp/src/pmacHardwarePower.cpp @@ -218,7 +218,7 @@ asynStatus pmacHardwarePower::parseAxisStatus(int axis, pmacCommandStore *sPtr, } std::string pmacHardwarePower::getAxisLimitsCmd(int axis) { - char cmd[8]; + char cmd[32]; static const char *functionName = "getAxisLimitsCmd"; debug(DEBUG_TRACE, functionName, "Axis", axis); @@ -226,6 +226,60 @@ std::string pmacHardwarePower::getAxisLimitsCmd(int 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); +} + +asynStatus pmacHardwarePower::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) { + asynStatus status = asynSuccess; + int nvals = 0; + std::string pLimitsString = ""; + + static const char *functionName = "parseAxisLimitsCmd"; + + // Get the symbolic pointer string + pLimitsString = trim(sPtr->readValue(this->getAxisLimitsCmd(axis))); // e.g., "Gate3[0].Chan[0].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 "+$" + *limitStatus = 1; + } else { + // Disabled + *limitStatus = 0; + } + + return status; +} + +// asynStatus pmacHardwarePower::disableAxisLimits(int axis, int *addr) { +// asynStatus status = asynSuccess; +// int nvals = 0; +// char cmd[32] = {}; +// std::string pLimitsString = ""; +// std::string storedLimitsString = ""; + +// static const char *functionName = "disableAxisLimits"; + +// storedLimitsString = this->getAxisLimitsCmd(axis); +// // TODO Store previous settting +// sprintf(cmd, "%s=0", this->getAxisLimitsCmd(axis).c_str()); +// // Do the write one level above +// debug(DEBUG_VARIABLE, functionName, "pLimit string", pLimitsString); + +// return status; + +// } + asynStatus pmacHardwarePower::setupCSStatus(int csNo) { asynStatus status = asynSuccess; char var[30]; diff --git a/pmacApp/src/pmacHardwarePower.h b/pmacApp/src/pmacHardwarePower.h index 8ae6c1f0..854c27be 100755 --- a/pmacApp/src/pmacHardwarePower.h +++ b/pmacApp/src/pmacHardwarePower.h @@ -31,6 +31,10 @@ class pmacHardwarePower : public pmacHardwareInterface, pmacDebugger { std::string getAxisLimitsCmd(int axis); + asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus); + + // asynStatus disableAxisLimits(int axis, int *addr); + asynStatus setupCSStatus(int csNo); asynStatus parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus); diff --git a/pmacApp/src/pmacHardwareTurbo.cpp b/pmacApp/src/pmacHardwareTurbo.cpp index da4dc7e1..ede04069 100644 --- a/pmacApp/src/pmacHardwareTurbo.cpp +++ b/pmacApp/src/pmacHardwareTurbo.cpp @@ -186,14 +186,6 @@ pmacHardwareTurbo::parseGlobalStatus(const std::string &statusString, globalStat return status; } -std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis) { - char cmd[8]; - static const char *functionName = "getAxisLimitsCmd"; - - debug(DEBUG_TRACE, functionName, "Axis", axis); - sprintf(cmd, AXIS_LIMITS.c_str(), axis); - return std::string(cmd); -} std::string pmacHardwareTurbo::getAxisStatusCmd(int axis) { char cmd[8]; @@ -287,6 +279,38 @@ asynStatus pmacHardwareTurbo::setupCSStatus(int csNo) { return status; } +std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis) { + char cmd[8]; + static const char *functionName = "getAxisLimitsCmd"; + + debug(DEBUG_TRACE, functionName, "Axis", axis); + sprintf(cmd, AXIS_LIMITS.c_str(), axis); + return std::string(cmd); +} + +asynStatus pmacHardwareTurbo::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) { + asynStatus status = asynSuccess; + int nvals = 0; + int limitsBits = 0; + std::string pLimitsString = ""; + static const char *functionName = "parseAxisLimitsCmd"; + + pLimitsString = sPtr->readValue(this->getAxisLimitsCmd(axis)); + + // Response parsed for PowerPMAC + debug(DEBUG_VARIABLE, functionName, "pLimit string", pLimitsString); + nvals = sscanf(pLimitsString.c_str(), "$%x", &limitsBits); + if (nvals != 1) { + debug(DEBUG_ERROR, functionName, "Error reading axis limits", AXIS_LIMITS); + debug(DEBUG_ERROR, functionName, " nvals", nvals); + debug(DEBUG_ERROR, functionName, " response", pLimitsString); + status = asynError; + } + *limitStatus = ~((0x20000 & limitsBits) >> 17); + + return status; +} + asynStatus pmacHardwareTurbo::parseCSStatus(int csNo, pmacCommandStore *sPtr, csStatus &coordStatus) { asynStatus status = asynSuccess; int nvals = 0; diff --git a/pmacApp/src/pmacHardwareTurbo.h b/pmacApp/src/pmacHardwareTurbo.h index 297224de..67caea9c 100644 --- a/pmacApp/src/pmacHardwareTurbo.h +++ b/pmacApp/src/pmacHardwareTurbo.h @@ -29,7 +29,9 @@ class pmacHardwareTurbo : public pmacHardwareInterface, pmacDebugger { asynStatus parseAxisStatus(int axis, pmacCommandStore *sPtr, axisStatus &axStatus); - std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis); + std::string getAxisLimitsCmd(int axis); + + asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus); asynStatus setupCSStatus(int csNo); From dd2b147e02ecde14a857370f918fd7097694c305 Mon Sep 17 00:00:00 2001 From: Leandro Martins dos Santos Date: Fri, 26 Sep 2025 10:01:19 +0100 Subject: [PATCH 3/3] Add methods for getting string for disable and restore limits --- pmacApp/src/pmacAxis.cpp | 103 +++++++++------------------- pmacApp/src/pmacAxis.h | 11 +-- pmacApp/src/pmacHardwareInterface.h | 7 +- pmacApp/src/pmacHardwarePower.cpp | 57 ++++++++------- pmacApp/src/pmacHardwarePower.h | 6 +- pmacApp/src/pmacHardwareTurbo.cpp | 25 ++++++- pmacApp/src/pmacHardwareTurbo.h | 6 +- 7 files changed, 107 insertions(+), 108 deletions(-) diff --git a/pmacApp/src/pmacAxis.cpp b/pmacApp/src/pmacAxis.cpp index c54bab90..564b5293 100755 --- a/pmacApp/src/pmacAxis.cpp +++ b/pmacApp/src/pmacAxis.cpp @@ -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; @@ -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; @@ -330,13 +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 */ - // LMDS - 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); @@ -394,38 +395,6 @@ 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 */ @@ -433,18 +402,15 @@ pmacAxis::home(double min_velocity, double max_velocity, double acceleration, in // 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}; - // // Gets limits pointer - // sprintf(buffer, "Motor[%d].pLimits", axisNo_); - // status = pC_->lowLevelWriteRead(buffer, response); + 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].CaptFlag %s Motor[%d].HomeVel Motor[%d].HomeOffset", - // gateIndex, chanIndex, gateIndex, chanIndex, limitsAddress, axisNo_, axisNo_); - // status = pC_->lowLevelWriteRead(buffer, response); - // nvals = sscanf(response, "%d %d $%x %lf %d", &home_type, &home_flag, &flag_mode, &home_velocity, - // &home_offset); + 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_ @@ -489,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) && // are the limits disabled? + 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_); // Disable limits - 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); @@ -540,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); @@ -701,7 +667,6 @@ asynStatus pmacAxis::getAxisStatus(pmacCommandStore *sPtr) { double enc_position = 0; int nvals = 0; int axisProblemFlag = 0; - int limitsStatus = 0; bool printErrors = true; char key[16]; std::string value = ""; @@ -863,18 +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 - retStatus = pC_->pHardware_->parseAxisLimitsCmd(axisNo_, sPtr, &limitsStatus); - if (!(limitsStatus)) { - 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); @@ -886,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. diff --git a/pmacApp/src/pmacAxis.h b/pmacApp/src/pmacAxis.h index df81c171..e261e4ae 100644 --- a/pmacApp/src/pmacAxis.h +++ b/pmacApp/src/pmacAxis.h @@ -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 @@ -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_; @@ -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 diff --git a/pmacApp/src/pmacHardwareInterface.h b/pmacApp/src/pmacHardwareInterface.h index 8ad5f5a2..e86f2420 100644 --- a/pmacApp/src/pmacHardwareInterface.h +++ b/pmacApp/src/pmacHardwareInterface.h @@ -74,10 +74,11 @@ class pmacHardwareInterface { virtual std::string getAxisLimitsCmd(int axis) = 0; - virtual asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) = 0; + virtual std::string getDisableAxisLimitsCmd(int axis) = 0; - // virtual asynStatus disableLimitsCmd(int axis, pmacCommandStore *sPtr, int *savedStatus) = 0; - // virtual asynStatus restoreLimitsCmd(int axis, pmacCommandStore *sPtr, int *savedStatus) = 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; diff --git a/pmacApp/src/pmacHardwarePower.cpp b/pmacApp/src/pmacHardwarePower.cpp index 3a3500bd..bc406bcc 100755 --- a/pmacApp/src/pmacHardwarePower.cpp +++ b/pmacApp/src/pmacHardwarePower.cpp @@ -232,15 +232,39 @@ static inline std::string trim(const std::string& s) { return (start == std::string::npos) ? "" : s.substr(start, end - start + 1); } -asynStatus pmacHardwarePower::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) { - asynStatus status = asynSuccess; - int nvals = 0; - std::string pLimitsString = ""; +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[0].Chan[0].Status.a" or "0" + 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") { @@ -252,34 +276,15 @@ asynStatus pmacHardwarePower::parseAxisLimitsCmd(int axis, pmacCommandStore *sPt // - Case 2 // - it must begin with: "Sys.pushm", or "Sys.piom" // - it might contain "+$" - *limitStatus = 1; + *limitsEnabled = true; } else { // Disabled - *limitStatus = 0; + *limitsEnabled = false; } return status; } -// asynStatus pmacHardwarePower::disableAxisLimits(int axis, int *addr) { -// asynStatus status = asynSuccess; -// int nvals = 0; -// char cmd[32] = {}; -// std::string pLimitsString = ""; -// std::string storedLimitsString = ""; - -// static const char *functionName = "disableAxisLimits"; - -// storedLimitsString = this->getAxisLimitsCmd(axis); -// // TODO Store previous settting -// sprintf(cmd, "%s=0", this->getAxisLimitsCmd(axis).c_str()); -// // Do the write one level above -// debug(DEBUG_VARIABLE, functionName, "pLimit string", pLimitsString); - -// return status; - -// } - asynStatus pmacHardwarePower::setupCSStatus(int csNo) { asynStatus status = asynSuccess; char var[30]; diff --git a/pmacApp/src/pmacHardwarePower.h b/pmacApp/src/pmacHardwarePower.h index 854c27be..b6cb86b9 100755 --- a/pmacApp/src/pmacHardwarePower.h +++ b/pmacApp/src/pmacHardwarePower.h @@ -31,9 +31,11 @@ class pmacHardwarePower : public pmacHardwareInterface, pmacDebugger { std::string getAxisLimitsCmd(int axis); - asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus); + std::string getDisableAxisLimitsCmd(int axis); - // asynStatus disableAxisLimits(int axis, int *addr); + std::string getRestoreAxisLimitsCmd(int axis, const std::string savedStatus); + + asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, bool *limitsEnabled, std::string &pLimitsString); asynStatus setupCSStatus(int csNo); diff --git a/pmacApp/src/pmacHardwareTurbo.cpp b/pmacApp/src/pmacHardwareTurbo.cpp index ede04069..dde5d33d 100644 --- a/pmacApp/src/pmacHardwareTurbo.cpp +++ b/pmacApp/src/pmacHardwareTurbo.cpp @@ -288,13 +288,34 @@ std::string pmacHardwareTurbo::getAxisLimitsCmd(int axis) { return std::string(cmd); } -asynStatus pmacHardwareTurbo::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus) { +std::string pmacHardwareTurbo::getDisableAxisLimitsCmd(int axis) { + char cmd[32]; + static const char *functionName = "getDisableAxisLimitsCmd"; + + debug(DEBUG_TRACE, functionName, "Axis", axis); + sprintf(cmd, " i%d24=i%d24|$20000", axis, axis); // Disable limits + + return(cmd); +} + +std::string pmacHardwareTurbo::getRestoreAxisLimitsCmd(int axis, const std::string) { + char cmd[32]; + static const char *functionName = "getRestoreAxisLimitsCmd"; + + debug(DEBUG_TRACE, functionName, "Axis", axis); + sprintf(cmd, " i%d24=i%d24&$FDFFFF", axis, axis); // Re-enable limits + return(cmd); +} + + +asynStatus pmacHardwareTurbo::parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, bool *limitsEnabled, std::string&) { asynStatus status = asynSuccess; int nvals = 0; int limitsBits = 0; std::string pLimitsString = ""; static const char *functionName = "parseAxisLimitsCmd"; + debug(DEBUG_TRACE, functionName, "Axis", axis); pLimitsString = sPtr->readValue(this->getAxisLimitsCmd(axis)); // Response parsed for PowerPMAC @@ -306,7 +327,7 @@ asynStatus pmacHardwareTurbo::parseAxisLimitsCmd(int axis, pmacCommandStore *sPt debug(DEBUG_ERROR, functionName, " response", pLimitsString); status = asynError; } - *limitStatus = ~((0x20000 & limitsBits) >> 17); + *limitsEnabled = ~((0x20000 & limitsBits) >> 17); return status; } diff --git a/pmacApp/src/pmacHardwareTurbo.h b/pmacApp/src/pmacHardwareTurbo.h index 67caea9c..a10bbe72 100644 --- a/pmacApp/src/pmacHardwareTurbo.h +++ b/pmacApp/src/pmacHardwareTurbo.h @@ -31,7 +31,11 @@ class pmacHardwareTurbo : public pmacHardwareInterface, pmacDebugger { std::string getAxisLimitsCmd(int axis); - asynStatus parseAxisLimitsCmd(int axis, pmacCommandStore *sPtr, int *limitStatus); + 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);