Detect stallguard on Selector+Idler - report MOVE_FAILED
parent
fbb46e5951
commit
f2e2859465
|
|
@ -13,11 +13,11 @@
|
||||||
|
|
||||||
namespace logic {
|
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);
|
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;
|
ErrorCode e = ErrorCode::RUNNING;
|
||||||
|
|
||||||
if (ef.reset_flag) {
|
if (ef.reset_flag) {
|
||||||
|
|
@ -39,7 +39,7 @@ static ErrorCode TMC2130ToErrorCode(const hal::tmc2130::ErrorFlags &ef) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ErrorCode AddErrorAxisBit(ErrorCode ec, uint8_t tmcIndex) {
|
constexpr ErrorCode AddErrorAxisBit(ErrorCode ec, uint8_t tmcIndex) {
|
||||||
switch (tmcIndex) {
|
switch (tmcIndex) {
|
||||||
case config::Axis::Pulley:
|
case config::Axis::Pulley:
|
||||||
ec |= ErrorCode::TMC_PULLEY_BIT;
|
ec |= ErrorCode::TMC_PULLEY_BIT;
|
||||||
|
|
@ -61,12 +61,14 @@ ErrorCode CheckMovable(mm::MovableBase &m) {
|
||||||
case mm::MovableBase::TMCFailed:
|
case mm::MovableBase::TMCFailed:
|
||||||
return AddErrorAxisBit(TMC2130ToErrorCode(m.TMCErrorFlags()), m.Axis());
|
return AddErrorAxisBit(TMC2130ToErrorCode(m.TMCErrorFlags()), m.Axis());
|
||||||
case mm::MovableBase::HomingFailed:
|
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;
|
return ErrorCode::RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ErrorCode WithoutAxisBits(ErrorCode ec) {
|
constexpr ErrorCode WithoutAxisBits(ErrorCode ec) {
|
||||||
return static_cast<ErrorCode>(
|
return static_cast<ErrorCode>(
|
||||||
static_cast<uint16_t>(ec)
|
static_cast<uint16_t>(ec)
|
||||||
& (~(static_cast<uint16_t>(ErrorCode::TMC_SELECTOR_BIT)
|
& (~(static_cast<uint16_t>(ErrorCode::TMC_SELECTOR_BIT)
|
||||||
|
|
@ -93,19 +95,35 @@ bool CommandBase::WaitForOneModuleErrorRecovery(ErrorCode ec, modules::motion::M
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case ProgressCode::ERRWaitingForUser: // waiting for a recovery - mask axis bits:
|
case ProgressCode::ERRWaitingForUser: { // waiting for a recovery - mask axis bits:
|
||||||
if (WithoutAxisBits(ec) == ErrorCode::HOMING_FAILED) {
|
mui::Event ev = mui::userInput.ConsumeEvent();
|
||||||
// homing can be recovered
|
if (ev == mui::Event::Middle) {
|
||||||
mui::Event ev = mui::userInput.ConsumeEvent();
|
switch (WithoutAxisBits(ec)) {
|
||||||
if (ev == mui::Event::Middle) {
|
case ErrorCode::MOVE_FAILED:
|
||||||
recoveringMovableErrorAxisMask |= axisMask;
|
// A failed move can be recovered for Idler and Selector (doesn't make sense on the Pulley).
|
||||||
m.PlanHome(); // force initiate a new homing attempt
|
// 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;
|
state = ProgressCode::Homing;
|
||||||
error = ErrorCode::RUNNING;
|
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
|
// TMC errors cannot be recovered safely, waiting for power cycling the MMU
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return true; // prevent descendant from taking over while in an error state
|
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
|
///< - 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
|
///< - 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
|
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
|
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
|
/// - blocked -> set idler's position according to the active filament slot
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
virtual bool SupportsHoming() override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrepareMoveToPlannedSlot() override;
|
virtual void PrepareMoveToPlannedSlot() override;
|
||||||
virtual void PlanHomingMoveForward() 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
|
// 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
|
tmcErrorFlags = mm::motion.DriverForAxis(axis).GetErrorFlags(); // save the failed state
|
||||||
state = TMCFailed;
|
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)) {
|
} else if (mm::motion.QueueEmpty(axis)) {
|
||||||
// move finished
|
// move finished
|
||||||
currentSlot = plannedSlot;
|
currentSlot = plannedSlot;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ public:
|
||||||
HomeForward,
|
HomeForward,
|
||||||
HomeBack,
|
HomeBack,
|
||||||
TMCFailed,
|
TMCFailed,
|
||||||
HomingFailed
|
HomingFailed,
|
||||||
|
MoveFailed,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Operation (Engage/Disengage/MoveToSlot) return values
|
/// Operation (Engage/Disengage/MoveToSlot) return values
|
||||||
|
|
@ -67,6 +68,8 @@ public:
|
||||||
|
|
||||||
inline config::Axis Axis() const { return axis; }
|
inline config::Axis Axis() const { return axis; }
|
||||||
|
|
||||||
|
virtual bool SupportsHoming() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// internal state of the automaton
|
/// internal state of the automaton
|
||||||
uint8_t state;
|
uint8_t state;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ public:
|
||||||
void InitAxis();
|
void InitAxis();
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
|
virtual bool SupportsHoming() override { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrepareMoveToPlannedSlot() override {}
|
virtual void PrepareMoveToPlannedSlot() override {}
|
||||||
virtual void PlanHomingMoveForward() override {}
|
virtual void PlanHomingMoveForward() override {}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ public:
|
||||||
/// - blocked -> set selector's position according to the active filament slot
|
/// - blocked -> set selector's position according to the active filament slot
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
virtual bool SupportsHoming() override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrepareMoveToPlannedSlot() override;
|
virtual void PrepareMoveToPlannedSlot() override;
|
||||||
virtual void PlanHomingMoveForward() override;
|
virtual void PlanHomingMoveForward() override;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue