Detect stallguard on Selector+Idler - report MOVE_FAILED
parent
fbb46e5951
commit
f2e2859465
|
|
@ -13,11 +13,11 @@
|
|||
|
||||
namespace logic {
|
||||
|
||||
inline ErrorCode &operator|=(ErrorCode &a, ErrorCode b) {
|
||||
constexpr ErrorCode &operator|=(ErrorCode &a, ErrorCode b) {
|
||||
return a = (ErrorCode)((uint16_t)a | (uint16_t)b);
|
||||
}
|
||||
|
||||
static ErrorCode TMC2130ToErrorCode(const hal::tmc2130::ErrorFlags &ef) {
|
||||
constexpr ErrorCode TMC2130ToErrorCode(const hal::tmc2130::ErrorFlags &ef) {
|
||||
ErrorCode e = ErrorCode::RUNNING;
|
||||
|
||||
if (ef.reset_flag) {
|
||||
|
|
@ -39,7 +39,7 @@ static ErrorCode TMC2130ToErrorCode(const hal::tmc2130::ErrorFlags &ef) {
|
|||
return e;
|
||||
}
|
||||
|
||||
static ErrorCode AddErrorAxisBit(ErrorCode ec, uint8_t tmcIndex) {
|
||||
constexpr ErrorCode AddErrorAxisBit(ErrorCode ec, uint8_t tmcIndex) {
|
||||
switch (tmcIndex) {
|
||||
case config::Axis::Pulley:
|
||||
ec |= ErrorCode::TMC_PULLEY_BIT;
|
||||
|
|
@ -61,12 +61,14 @@ ErrorCode CheckMovable(mm::MovableBase &m) {
|
|||
case mm::MovableBase::TMCFailed:
|
||||
return AddErrorAxisBit(TMC2130ToErrorCode(m.TMCErrorFlags()), m.Axis());
|
||||
case mm::MovableBase::HomingFailed:
|
||||
return AddErrorAxisBit(ErrorCode::HOMING_FAILED, m.Axis());
|
||||
return m.SupportsHoming() ? AddErrorAxisBit(ErrorCode::HOMING_FAILED, m.Axis()) : ErrorCode::RUNNING;
|
||||
case mm::MovableBase::MoveFailed:
|
||||
return m.SupportsHoming() ? AddErrorAxisBit(ErrorCode::MOVE_FAILED, m.Axis()) : ErrorCode::RUNNING;
|
||||
}
|
||||
return ErrorCode::RUNNING;
|
||||
}
|
||||
|
||||
static inline ErrorCode WithoutAxisBits(ErrorCode ec) {
|
||||
constexpr ErrorCode WithoutAxisBits(ErrorCode ec) {
|
||||
return static_cast<ErrorCode>(
|
||||
static_cast<uint16_t>(ec)
|
||||
& (~(static_cast<uint16_t>(ErrorCode::TMC_SELECTOR_BIT)
|
||||
|
|
@ -93,19 +95,35 @@ bool CommandBase::WaitForOneModuleErrorRecovery(ErrorCode ec, modules::motion::M
|
|||
}
|
||||
|
||||
switch (state) {
|
||||
case ProgressCode::ERRWaitingForUser: // waiting for a recovery - mask axis bits:
|
||||
if (WithoutAxisBits(ec) == ErrorCode::HOMING_FAILED) {
|
||||
// homing can be recovered
|
||||
mui::Event ev = mui::userInput.ConsumeEvent();
|
||||
if (ev == mui::Event::Middle) {
|
||||
recoveringMovableErrorAxisMask |= axisMask;
|
||||
m.PlanHome(); // force initiate a new homing attempt
|
||||
case ProgressCode::ERRWaitingForUser: { // waiting for a recovery - mask axis bits:
|
||||
mui::Event ev = mui::userInput.ConsumeEvent();
|
||||
if (ev == mui::Event::Middle) {
|
||||
switch (WithoutAxisBits(ec)) {
|
||||
case ErrorCode::MOVE_FAILED:
|
||||
// A failed move can be recovered for Idler and Selector (doesn't make sense on the Pulley).
|
||||
// But - force initiate a new homing attempt of BOTH Idler and Selector (that's the main difference from HomingFailed)
|
||||
// because we expect the user disassembled the whole MMU to remove a stuck piece of filament
|
||||
// and therefore we cannot rely on Idler's and Selector's position
|
||||
recoveringMovableErrorAxisMask |= 0x3; // @@TODO better axis masks
|
||||
mi::idler.PlanHome();
|
||||
ms::selector.PlanHome();
|
||||
state = ProgressCode::Homing;
|
||||
error = ErrorCode::RUNNING;
|
||||
break;
|
||||
case ErrorCode::HOMING_FAILED:
|
||||
// A failed homing can be recovered
|
||||
recoveringMovableErrorAxisMask |= axisMask;
|
||||
m.PlanHome(); // force initiate a new homing attempt just on the failed axis
|
||||
state = ProgressCode::Homing;
|
||||
error = ErrorCode::RUNNING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TMC errors cannot be recovered safely, waiting for power cycling the MMU
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return true; // prevent descendant from taking over while in an error state
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@ enum class ErrorCode : uint_fast16_t {
|
|||
///< - a piece of filament was left inside - pushed in front of the loaded filament causing the fsensor trigger too early
|
||||
///< - fsensor is faulty producing bogus triggers
|
||||
|
||||
MOVE_FAILED = 0x800a, ///< generic move failed error - always reported with the corresponding axis bit set (Idler or Selector) as follows:
|
||||
MOVE_SELECTOR_FAILED = MOVE_FAILED | TMC_SELECTOR_BIT, ///< E32905 the Selector was unable to move to desired position properly - that means something is blocking its movement, e.g. a piece of filament got out of pulley body
|
||||
MOVE_IDLER_FAILED = MOVE_FAILED | TMC_IDLER_BIT, ///< E33033 the Idler was unable to move - unused at the time of creation, but added for completeness
|
||||
MOVE_PULLEY_FAILED = MOVE_FAILED | TMC_PULLEY_BIT, ///< E32841 the Pulley was unable to move - unused at the time of creation, but added for completeness
|
||||
|
||||
QUEUE_FULL = 0x802b, ///< E32811 internal logic error - attempt to move with a full queue
|
||||
|
||||
VERSION_MISMATCH = 0x802c, ///< E32812 internal error of the printer - incompatible version of the MMU FW
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ public:
|
|||
/// - blocked -> set idler's position according to the active filament slot
|
||||
void Init();
|
||||
|
||||
virtual bool SupportsHoming() override { return true; }
|
||||
|
||||
protected:
|
||||
virtual void PrepareMoveToPlannedSlot() override;
|
||||
virtual void PlanHomingMoveForward() override;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ void MovableBase::PerformMove() {
|
|||
// TMC2130 entered some error state, the planned move couldn't have been finished - result of operation is Failed
|
||||
tmcErrorFlags = mm::motion.DriverForAxis(axis).GetErrorFlags(); // save the failed state
|
||||
state = TMCFailed;
|
||||
} else if (mm::motion.StallGuard(axis) && SupportsHoming()) {
|
||||
// Axis stalled while moving - dangerous especially with the Selector
|
||||
// Checked only for axes which support homing (because we plan a homing move after the error is resolved to regain precise position)
|
||||
mm::motion.StallGuardReset(axis);
|
||||
mm::motion.AbortPlannedMoves(axis, true);
|
||||
// @@TODO move a bit back from where it came from to enable easier removal of whatever is blocking the axis
|
||||
state = MoveFailed;
|
||||
} else if (mm::motion.QueueEmpty(axis)) {
|
||||
// move finished
|
||||
currentSlot = plannedSlot;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ public:
|
|||
HomeForward,
|
||||
HomeBack,
|
||||
TMCFailed,
|
||||
HomingFailed
|
||||
HomingFailed,
|
||||
MoveFailed,
|
||||
};
|
||||
|
||||
/// Operation (Engage/Disengage/MoveToSlot) return values
|
||||
|
|
@ -67,6 +68,8 @@ public:
|
|||
|
||||
inline config::Axis Axis() const { return axis; }
|
||||
|
||||
virtual bool SupportsHoming() = 0;
|
||||
|
||||
protected:
|
||||
/// internal state of the automaton
|
||||
uint8_t state;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ public:
|
|||
void InitAxis();
|
||||
void Disable();
|
||||
|
||||
virtual bool SupportsHoming() override { return false; }
|
||||
|
||||
protected:
|
||||
virtual void PrepareMoveToPlannedSlot() override {}
|
||||
virtual void PlanHomingMoveForward() override {}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ public:
|
|||
/// - blocked -> set selector's position according to the active filament slot
|
||||
void Init();
|
||||
|
||||
virtual bool SupportsHoming() override { return true; }
|
||||
|
||||
protected:
|
||||
virtual void PrepareMoveToPlannedSlot() override;
|
||||
virtual void PlanHomingMoveForward() override;
|
||||
|
|
|
|||
Loading…
Reference in New Issue