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:
Guðni Már Gilbert 2023-08-06 12:09:14 +00:00 committed by DRracer
parent efd85110a3
commit f0a48b11f7
4 changed files with 33 additions and 39 deletions

View File

@ -153,27 +153,6 @@ bool MMU2::ReadRegister(uint8_t address) {
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) {
if (!WaitForMMUReady())
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
ResumeHotendTemp();
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();
return true;
case Interrupted:

View File

@ -88,12 +88,6 @@ public:
/// @returns true upon success
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)
/// @param address Address of register in hexidecimal
/// @param data Data to write to register

View File

@ -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
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() {
return is_mmu_error_monitor_active;
}
bool isErrorScreenSleeping() {
return putErrorScreenToSleep;
}
void ReportErrorHook(CommandInProgress /*cip*/, uint16_t ec, uint8_t /*es*/) {
if (putErrorScreenToSleep) return;
if (mmu2.MMUCurrentErrorCode() == ErrorCode::OK && mmu2.MMULastErrorSource() == MMU2::ErrorSourceMMU) {
// If the error code suddenly changes to OK, that means
// a button was pushed on the MMU and the LCD should
@ -361,8 +372,6 @@ void ScreenClear(){
lcd_clear();
}
bool tuningDone = false;
struct TuneItem {
uint8_t address;
uint8_t minValue;
@ -389,24 +398,28 @@ static_assert(sizeof(menu_data)>= sizeof(_menu_tune_data_t),"_menu_tune_data_t d
void tuneIdlerStallguardThresholdMenu() {
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)
{
_md->status = 1; // Menu entered for the first time
lcd_timeoutToStatus.stop(); // Do not timeout the screen
// Fetch the TuneItem from PROGMEM
const uint8_t offset = (mmu2.MMUCurrentErrorCode() == ErrorCode::HOMING_IDLER_FAILED) ? 1 : 0;
memcpy_P(&(_md->item), &TuneItems[offset], sizeof(TuneItem));
// 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();
}
MENU_BEGIN();
ON_MENU_LEAVE(
tuningDone = true;
mmu2.WriteRegister(_md->item.address, (uint16_t)_md->currentValue);
putErrorScreenToSleep = false;
lcd_return_to_status();
return;
);
MENU_ITEM_BACK_P(_i("Done"));
MENU_ITEM_EDIT_int3_P(
@ -419,12 +432,8 @@ void tuneIdlerStallguardThresholdMenu() {
}
void tuneIdlerStallguardThreshold() {
tuningDone = false;
menu_goto(tuneIdlerStallguardThresholdMenu, 0, 0, 0);
while(!tuningDone) {
delay_keep_alive(0);
}
lcd_return_to_status();
putErrorScreenToSleep = true;
menu_submenu(tuneIdlerStallguardThresholdMenu);
}
} // namespace MMU2

View File

@ -25,6 +25,11 @@ void EndReport(CommandInProgress cip, uint16_t ec);
/// Return true if the printer's LCD is drawing the error screen
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).
/// Render MMU error screen on the LCD. This must be non-blocking
/// and allow the MMU and printer to communicate with each other.