diff --git a/Firmware/mmu2.cpp b/Firmware/mmu2.cpp index 37bb72d6a..2f311fe31 100644 --- a/Firmware/mmu2.cpp +++ b/Firmware/mmu2.cpp @@ -78,6 +78,19 @@ void MMU2::StopKeepPowered() { mmu2Serial.close(); } +void MMU2::Tune() { + switch (lastErrorCode) { + case ErrorCode::HOMING_IDLER_FAILED: + { + // Prompt a menu for different values + tuneIdlerStallguardThreshold(); + break; + } + default: + break; + } +} + void MMU2::Reset(ResetForm level) { switch (level) { case Software: @@ -742,6 +755,9 @@ void MMU2::CheckUserInput() { break; } break; + case TuneMMU: + Tune(); + break; case ResetMMU: Reset(ResetPin); // we cannot do power cycle on the MK3 // ... but mmu2_power.cpp knows this and triggers a soft-reset instead. diff --git a/Firmware/mmu2.h b/Firmware/mmu2.h index c5dd5a6df..4488bb92a 100644 --- a/Firmware/mmu2.h +++ b/Firmware/mmu2.h @@ -69,6 +69,10 @@ public: ErrorSourceNone = 0xFF, }; + /// Tune value in MMU registers as a way to recover from errors + /// e.g. Idler Stallguard threshold + void Tune(); + /// Perform a reset of the MMU /// @param level physical form of the reset void Reset(ResetForm level); diff --git a/Firmware/mmu2/buttons.h b/Firmware/mmu2/buttons.h index d24d86f11..81bd0d6ab 100644 --- a/Firmware/mmu2/buttons.h +++ b/Firmware/mmu2/buttons.h @@ -17,6 +17,7 @@ enum class ButtonOperations : uint8_t { Unload = 4, StopPrint = 5, DisableMMU = 6, + Tune = 7, }; /// Button codes + extended actions performed on the printer's side @@ -29,6 +30,7 @@ enum Buttons : uint8_t { ResetMMU, StopPrint, DisableMMU, + TuneMMU, // Printer changes MMU register value NoButton = 0xff // shall be kept last }; diff --git a/Firmware/mmu2/errors_list.h b/Firmware/mmu2/errors_list.h index fdf4bafeb..cfe7d45cf 100644 --- a/Firmware/mmu2/errors_list.h +++ b/Firmware/mmu2/errors_list.h @@ -349,6 +349,7 @@ static const char MSG_BTN_RESET_MMU[] PROGMEM_I1 = ISTR("ResetMMU"); ////MSG_BTN static const char MSG_BTN_UNLOAD[] PROGMEM_I1 = ISTR("Unload"); ////MSG_BTN_UNLOAD c=8 static const char MSG_BTN_STOP[] PROGMEM_I1 = ISTR("Stop"); ////MSG_BTN_STOP c=8 static const char MSG_BTN_DISABLE_MMU[] PROGMEM_I1 = ISTR("Disable"); ////MSG_BTN_DISABLE_MMU c=8 +static const char MSG_BTN_TUNE_MMU[] PROGMEM_I1 = ISTR("Tune"); ////MSG_BTN_DISABLE_MMU c=8 static const char MSG_BTN_MORE[] PROGMEM_N1 = "\x06"; // Used to parse the buttons from Btns(). @@ -359,6 +360,7 @@ static const char * const btnOperation[] PROGMEM = { _R(MSG_BTN_UNLOAD), _R(MSG_BTN_STOP), _R(MSG_BTN_DISABLE_MMU), + _R(MSG_BTN_TUNE_MMU), }; // We have 8 different operations/buttons at this time, so we need at least 4 bits to encode each. @@ -380,7 +382,7 @@ static const uint8_t errorButtons[] PROGMEM = { Btns(ButtonOperations::Continue, ButtonOperations::NoOperation),//LOAD_TO_EXTRUDER_FAILED Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_HOME Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//SELECTOR_CANNOT_MOVE - Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_HOME + Btns(ButtonOperations::Retry, ButtonOperations::Tune),//IDLER_CANNOT_HOME Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),//IDLER_CANNOT_MOVE Btns(ButtonOperations::Continue, ButtonOperations::ResetMMU),//WARNING_TMC_PULLEY_TOO_HOT diff --git a/Firmware/mmu2_error_converter.cpp b/Firmware/mmu2_error_converter.cpp index cfb940bfa..02226797d 100644 --- a/Firmware/mmu2_error_converter.cpp +++ b/Firmware/mmu2_error_converter.cpp @@ -207,7 +207,6 @@ Buttons ButtonAvailable(uint16_t ec) { case ERR_MECHANICAL_INSPECT_FINDA: case ERR_MECHANICAL_SELECTOR_CANNOT_HOME: case ERR_MECHANICAL_SELECTOR_CANNOT_MOVE: - case ERR_MECHANICAL_IDLER_CANNOT_HOME: case ERR_MECHANICAL_IDLER_CANNOT_MOVE: case ERR_MECHANICAL_PULLEY_CANNOT_MOVE: case ERR_SYSTEM_UNLOAD_MANUALLY: @@ -219,6 +218,17 @@ Buttons ButtonAvailable(uint16_t ec) { break; } break; + case ERR_MECHANICAL_IDLER_CANNOT_HOME: + switch (buttonSelectedOperation) { + // may be allow move selector right and left in the future + case ButtonOperations::Tune: // Tune Stallguard threshold + return TuneMMU; + case ButtonOperations::Retry: // "Repeat action" + return Middle; + default: + break; + } + break; case ERR_MECHANICAL_LOAD_TO_EXTRUDER_FAILED: case ERR_SYSTEM_FILAMENT_EJECTED: switch (buttonSelectedOperation) { diff --git a/Firmware/mmu2_reporting.cpp b/Firmware/mmu2_reporting.cpp index ea14fdbea..5198c5543 100644 --- a/Firmware/mmu2_reporting.cpp +++ b/Firmware/mmu2_reporting.cpp @@ -4,6 +4,7 @@ #include "mmu2_error_converter.h" #include "mmu2/error_codes.h" #include "mmu2/buttons.h" +#include "menu.h" #include "ultralcd.h" #include "Filament_sensor.h" #include "language.h" @@ -359,4 +360,38 @@ void ScreenClear(){ lcd_clear(); } +// These are global while testing this concept +uint8_t stallGuardValue = 6; // default +bool tuningDone = false; + +void tuneIdlerStallguardThresholdMenu() { + constexpr uint8_t maxStallguardThreshold = 7; + constexpr uint8_t minStallguardThreshold = 4; + MENU_BEGIN(); + ON_MENU_LEAVE( + tuningDone = true; + mmu2.WriteRegister(0x19, (uint16_t)stallGuardValue); + ); + MENU_ITEM_BACK_P(_i("Done")); + MENU_ITEM_EDIT_int3_P( + _i("Idler"), + &stallGuardValue, + minStallguardThreshold, + maxStallguardThreshold + ); + MENU_END(); +} + +void tuneIdlerStallguardThreshold() { + tuningDone = false; + menu_goto(tuneIdlerStallguardThresholdMenu, 0, 0, 0); + while(!tuningDone) { + manage_heater(); + // Manage inactivity, but don't disable steppers on timeout. + manage_inactivity(true); + lcd_update(0); + } + lcd_return_to_status(); +} + } // namespace MMU2 diff --git a/Firmware/mmu2_reporting.h b/Firmware/mmu2_reporting.h index 071dd545e..0018e032a 100644 --- a/Firmware/mmu2_reporting.h +++ b/Firmware/mmu2_reporting.h @@ -86,4 +86,6 @@ void FullScreenMsgRestoringTemperature(); void ScreenUpdateEnable(); void ScreenClear(); +void tuneIdlerStallguardThreshold(); + } // namespace