PFW-1530 Refactor the menu to be non-blocking
The UI works much smoother now Saves ~60 bytes of flash
This commit is contained in:
parent
efd85110a3
commit
f0a48b11f7
|
|
@ -153,27 +153,6 @@ bool MMU2::ReadRegister(uint8_t address) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MMU2::ReadRegisterInner(uint8_t address) {
|
|
||||||
if (!WaitForMMUReady())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Plan a request for the register value at address
|
|
||||||
logic.ReadRegister(address);
|
|
||||||
|
|
||||||
do {
|
|
||||||
// Maintain MMU communications
|
|
||||||
marlin_manage_inactivity(true);
|
|
||||||
mmu_loop_inner(false);
|
|
||||||
} while (
|
|
||||||
logicStepLastStatus != StepStatus::Finished
|
|
||||||
&& logic.rsp.request.value == address // If the MMU protocol is busy decoding another request, we must wait
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update cached value
|
|
||||||
lastReadRegisterValue = logic.rsp.paramValue;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __attribute__((noinline)) MMU2::WriteRegister(uint8_t address, uint16_t data) {
|
bool __attribute__((noinline)) MMU2::WriteRegister(uint8_t address, uint16_t data) {
|
||||||
if (!WaitForMMUReady())
|
if (!WaitForMMUReady())
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -840,7 +819,14 @@ bool MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||||
// the E may have some more moves to finish - wait for them
|
// the E may have some more moves to finish - wait for them
|
||||||
ResumeHotendTemp();
|
ResumeHotendTemp();
|
||||||
ResumeUnpark(); // We can now travel back to the tower or wherever we were when we saved.
|
ResumeUnpark(); // We can now travel back to the tower or wherever we were when we saved.
|
||||||
logic.ResetRetryAttempts(); // Reset the retry counter.
|
if (!isErrorScreenSleeping())
|
||||||
|
{
|
||||||
|
// If the error screen is sleeping (running 'Tune' menu)
|
||||||
|
// then don't reset retry attempts because we this will trigger
|
||||||
|
// an automatic retry attempt when 'Tune' button is selected. We want the
|
||||||
|
// error screen to appear once more so the user can hit 'Retry' button manually.
|
||||||
|
logic.ResetRetryAttempts(); // Reset the retry counter.
|
||||||
|
}
|
||||||
planner_synchronize();
|
planner_synchronize();
|
||||||
return true;
|
return true;
|
||||||
case Interrupted:
|
case Interrupted:
|
||||||
|
|
|
||||||
|
|
@ -88,12 +88,6 @@ public:
|
||||||
/// @returns true upon success
|
/// @returns true upon success
|
||||||
bool ReadRegister(uint8_t address);
|
bool ReadRegister(uint8_t address);
|
||||||
|
|
||||||
/// Variant of ReadRegister which runs in blocking context such as manage_response()
|
|
||||||
/// Be careful of using this as it is not recursion protected!
|
|
||||||
/// @param address Address of register in hexidecimal
|
|
||||||
/// @return true upon success
|
|
||||||
bool ReadRegisterInner(uint8_t address);
|
|
||||||
|
|
||||||
/// Write from a MMU register (See gcode M708)
|
/// Write from a MMU register (See gcode M708)
|
||||||
/// @param address Address of register in hexidecimal
|
/// @param address Address of register in hexidecimal
|
||||||
/// @param data Data to write to register
|
/// @param data Data to write to register
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,22 @@ enum ReportErrorHookStates ReportErrorHookState = ReportErrorHookStates::RENDER_
|
||||||
// Helper variable to monitor knob in MMU error screen in blocking functions e.g. manage_response
|
// Helper variable to monitor knob in MMU error screen in blocking functions e.g. manage_response
|
||||||
static bool is_mmu_error_monitor_active;
|
static bool is_mmu_error_monitor_active;
|
||||||
|
|
||||||
|
// Helper variable to stop rendering the error screen when the firmware is rendering complementary
|
||||||
|
// UI to resolve the error screen, for example tuning Idler Stallguard Threshold
|
||||||
|
// Set to false to allow the error screen to render again.
|
||||||
|
static bool putErrorScreenToSleep;
|
||||||
|
|
||||||
bool isErrorScreenRunning() {
|
bool isErrorScreenRunning() {
|
||||||
return is_mmu_error_monitor_active;
|
return is_mmu_error_monitor_active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isErrorScreenSleeping() {
|
||||||
|
return putErrorScreenToSleep;
|
||||||
|
}
|
||||||
|
|
||||||
void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
|
void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
|
||||||
|
if (putErrorScreenToSleep) return;
|
||||||
|
|
||||||
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU) {
|
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU) {
|
||||||
// If the error code suddenly changes to OK, that means
|
// If the error code suddenly changes to OK, that means
|
||||||
// a button was pushed on the MMU and the LCD should
|
// a button was pushed on the MMU and the LCD should
|
||||||
|
|
@ -361,8 +372,6 @@ void ScreenClear(){
|
||||||
lcd_clear();
|
lcd_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tuningDone = false;
|
|
||||||
|
|
||||||
struct TuneItem {
|
struct TuneItem {
|
||||||
uint8_t address;
|
uint8_t address;
|
||||||
uint8_t minValue;
|
uint8_t minValue;
|
||||||
|
|
@ -389,24 +398,28 @@ static_assert(sizeof(menu_data)>= sizeof(_menu_tune_data_t),"_menu_tune_data_t d
|
||||||
|
|
||||||
void tuneIdlerStallguardThresholdMenu() {
|
void tuneIdlerStallguardThresholdMenu() {
|
||||||
static constexpr _menu_tune_data_t * const _md = (_menu_tune_data_t*)&(menu_data[0]);
|
static constexpr _menu_tune_data_t * const _md = (_menu_tune_data_t*)&(menu_data[0]);
|
||||||
|
|
||||||
|
// Do not timeout the screen, otherwise there will be FW crash (menu recursion)
|
||||||
|
lcd_timeoutToStatus.stop();
|
||||||
if (_md->status == 0)
|
if (_md->status == 0)
|
||||||
{
|
{
|
||||||
_md->status = 1; // Menu entered for the first time
|
_md->status = 1; // Menu entered for the first time
|
||||||
lcd_timeoutToStatus.stop(); // Do not timeout the screen
|
|
||||||
|
|
||||||
// Fetch the TuneItem from PROGMEM
|
// Fetch the TuneItem from PROGMEM
|
||||||
const uint8_t offset = (mmu2.MMUCurrentErrorCode() == ErrorCode::HOMING_IDLER_FAILED) ? 1 : 0;
|
const uint8_t offset = (mmu2.MMUCurrentErrorCode() == ErrorCode::HOMING_IDLER_FAILED) ? 1 : 0;
|
||||||
memcpy_P(&(_md->item), &TuneItems[offset], sizeof(TuneItem));
|
memcpy_P(&(_md->item), &TuneItems[offset], sizeof(TuneItem));
|
||||||
|
|
||||||
// Fetch the value which is currently in MMU EEPROM
|
// Fetch the value which is currently in MMU EEPROM
|
||||||
mmu2.ReadRegisterInner((uint8_t)_md->item.address);
|
mmu2.ReadRegister((uint8_t)_md->item.address);
|
||||||
_md->currentValue = mmu2.GetLastReadRegisterValue();
|
_md->currentValue = mmu2.GetLastReadRegisterValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
MENU_BEGIN();
|
MENU_BEGIN();
|
||||||
ON_MENU_LEAVE(
|
ON_MENU_LEAVE(
|
||||||
tuningDone = true;
|
|
||||||
mmu2.WriteRegister(_md->item.address, (uint16_t)_md->currentValue);
|
mmu2.WriteRegister(_md->item.address, (uint16_t)_md->currentValue);
|
||||||
|
putErrorScreenToSleep = false;
|
||||||
|
lcd_return_to_status();
|
||||||
|
return;
|
||||||
);
|
);
|
||||||
MENU_ITEM_BACK_P(_i("Done"));
|
MENU_ITEM_BACK_P(_i("Done"));
|
||||||
MENU_ITEM_EDIT_int3_P(
|
MENU_ITEM_EDIT_int3_P(
|
||||||
|
|
@ -419,12 +432,8 @@ void tuneIdlerStallguardThresholdMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tuneIdlerStallguardThreshold() {
|
void tuneIdlerStallguardThreshold() {
|
||||||
tuningDone = false;
|
putErrorScreenToSleep = true;
|
||||||
menu_goto(tuneIdlerStallguardThresholdMenu, 0, 0, 0);
|
menu_submenu(tuneIdlerStallguardThresholdMenu);
|
||||||
while(!tuningDone) {
|
|
||||||
delay_keep_alive(0);
|
|
||||||
}
|
|
||||||
lcd_return_to_status();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace MMU2
|
} // namespace MMU2
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@ void EndReport(CommandInProgress cip, uint16_t ec);
|
||||||
/// Return true if the printer's LCD is drawing the error screen
|
/// Return true if the printer's LCD is drawing the error screen
|
||||||
bool isErrorScreenRunning();
|
bool isErrorScreenRunning();
|
||||||
|
|
||||||
|
/// Return true if the error screen is sleeping in the background
|
||||||
|
/// Error screen sleeps when the firmware is rendering complementary
|
||||||
|
/// UI to resolve the error screen, for example tuning Idler Stallguard Threshold
|
||||||
|
bool isErrorScreenSleeping();
|
||||||
|
|
||||||
/// @brief Called when the MMU or MK3S sends operation error (even repeatedly).
|
/// @brief Called when the MMU or MK3S sends operation error (even repeatedly).
|
||||||
/// Render MMU error screen on the LCD. This must be non-blocking
|
/// Render MMU error screen on the LCD. This must be non-blocking
|
||||||
/// and allow the MMU and printer to communicate with each other.
|
/// and allow the MMU and printer to communicate with each other.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue