Browse Source

Convert button on LCD into button for MMU

- Dependent on current MMU error being processed
- Includes rename of LEFT_BUTTON_CHOICE -> LCD_LEFT_BUTTON_CHOICE (and right, middle as well) to avoid confusion with MMU buttons' ordering
D.R.racer 2 years ago
parent
commit
5082da78d2

+ 6 - 6
Firmware/Marlin_main.cpp

@@ -648,7 +648,7 @@ void crashdet_detected(uint8_t mask)
         lcd_puts_P(_T(MSG_RESUME_PRINT));
         lcd_putc('?');
         bool yesno = lcd_show_yes_no_and_wait(false);
-		if (yesno == LEFT_BUTTON_CHOICE)
+		if (yesno == LCD_LEFT_BUTTON_CHOICE)
 		{
 			enquecommand_P(PSTR("CRASH_RECOVER"));
 		}
@@ -1604,7 +1604,7 @@ void setup()
           #ifdef DEBUG_UVLO_AUTOMATIC_RECOVER 
         puts_P(_N("Normal recovery!")); 
           #endif 
-          if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) == LEFT_BUTTON_CHOICE) {
+          if ( lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_RECOVER_PRINT), false) == LCD_LEFT_BUTTON_CHOICE) {
               recover_print(0); 
           } else { 
               eeprom_update_byte((uint8_t*)EEPROM_UVLO, 0); 
@@ -3289,7 +3289,7 @@ bool gcode_M45(bool onlyZ, int8_t verbosity_level)
 			KEEPALIVE_STATE(PAUSED_FOR_USER);
 			#ifdef STEEL_SHEET
 			bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
-			if(result == LEFT_BUTTON_CHOICE) {
+			if(result == LCD_LEFT_BUTTON_CHOICE) {
 				lcd_show_fullscreen_message_and_wait_P(_T(MSG_REMOVE_STEEL_SHEET));
 			}
 			#endif //STEEL_SHEET
@@ -3586,8 +3586,8 @@ static void gcode_M600(bool automatic, float x_position, float y_position, float
     if (!MMU2::mmu2.Enabled()) {
         KEEPALIVE_STATE(PAUSED_FOR_USER);
         lcd_change_fil_state =
-            lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=2
-        if (lcd_change_fil_state == MIDDLE_BUTTON_CHOICE) {
+            lcd_show_fullscreen_message_yes_no_and_wait_P(_i("Was filament unload successful?"), false, LCD_LEFT_BUTTON_CHOICE); ////MSG_UNLOAD_SUCCESSFUL c=20 r=2
+        if (lcd_change_fil_state == LCD_MIDDLE_BUTTON_CHOICE) {
             lcd_clear();
             lcd_puts_at_P(0, 2, _T(MSG_PLEASE_WAIT));
             current_position[X_AXIS] -= 100;
@@ -4920,7 +4920,7 @@ eeprom_update_word((uint16_t*)EEPROM_NOZZLE_DIAMETER_uM,0xFFFF);
         lcd_show_fullscreen_message_and_wait_P(_i("Stable ambient temperature 21-26C is needed a rigid stand is required."));////MSG_TEMP_CAL_WARNING c=20 r=4
         bool result = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
 
-        if (result == LEFT_BUTTON_CHOICE)
+        if (result == LCD_LEFT_BUTTON_CHOICE)
         {
             current_position[Z_AXIS] = MESH_HOME_Z_SEARCH;
             plan_buffer_line_curposXYZE(3000 / 60);

+ 16 - 2
Firmware/mmu2/buttons.h

@@ -2,8 +2,8 @@
 #include <stdint.h>
 
 // Helper macros to parse the operations from Btns()
-#define BUTTON_OP_HI_NIBBLE(X) ( ( X & 0xF0 ) >> 4 )
-#define BUTTON_OP_LO_NIBBLE(X) ( X & 0x0F )
+#define BUTTON_OP_RIGHT(X) ( ( X & 0xF0 ) >> 4 )
+#define BUTTON_OP_MIDDLE(X) ( X & 0x0F )
 
 namespace MMU2 {
 
@@ -19,4 +19,18 @@ enum class ButtonOperations : uint8_t {
     DisableMMU  = 6,
 };
 
+/// Button codes + extended actions performed on the printer's side
+enum Buttons : uint8_t {
+    Left = 0,
+    Middle,
+    Right,
+    
+    // performed on the printer's side
+    RestartMMU,
+    StopPrint,
+    
+    NoButton = 0xff // shall be kept last
+};
+
+
 } // namespace MMU2

+ 8 - 7
Firmware/mmu2/errors_list.h

@@ -273,7 +273,8 @@ static const char * const errorDescs[] PROGMEM = {
 // 01234567890123456789
 // >bttxt >bttxt >MoreW
 // Therefore at least some of the buttons, which can occur on the screen together, need to be 5-chars long max @@TODO.
-// @@TODO beware - this doesn't correspond to the HW MMU buttons - needs to be discussed
+// Beware - we only have space for 2 buttons on the LCD while the MMU has 3 buttons
+// -> the left button on the MMU is not used/rendered on the LCD (it is also almost unused on the MMU side)
 static const char btnRetry[] PROGMEM_I1 = ISTR("Retry");
 static const char btnContinue[] PROGMEM_I1 = ISTR("Done");
 static const char btnRestartMMU[] PROGMEM_I1 = ISTR("RstMMU");
@@ -295,15 +296,15 @@ static const char * const btnOperation[] PROGMEM = {
 // We have 8 different operations/buttons at this time, so we need at least 4 bits to encode each.
 // Since one of the buttons is always "More", we can skip that one.
 // Therefore we need just 1 byte to describe the necessary buttons for each screen.
-uint8_t constexpr Btns(ButtonOperations b0, ButtonOperations b1){
-    return ((uint8_t)b1) << 4 | ((uint8_t)b0);
+uint8_t constexpr Btns(ButtonOperations bMiddle, ButtonOperations bRight){
+    return ((uint8_t)bRight) << 4 | ((uint8_t)bMiddle);
 }
 
 static const uint8_t errorButtons[] PROGMEM = {
-    Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
-    Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
-    Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
-    Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
+    Btns(ButtonOperations::Retry, ButtonOperations::Continue),
+    Btns(ButtonOperations::Retry, ButtonOperations::Continue),
+    Btns(ButtonOperations::Retry, ButtonOperations::Continue),
+    Btns(ButtonOperations::Retry, ButtonOperations::Continue),
     
     Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),
     Btns(ButtonOperations::Retry, ButtonOperations::NoOperation),

+ 129 - 0
Firmware/mmu2_error_converter.cpp

@@ -6,6 +6,8 @@
 
 namespace MMU2 {
 
+static ButtonOperations buttonSelectedOperation = ButtonOperations::NoOperation;
+
 // we don't have a constexpr find_if in C++17/STL yet
 template <class InputIt, class UnaryPredicate>
 constexpr InputIt find_if_cx(InputIt first, InputIt last, UnaryPredicate p) {
@@ -151,4 +153,131 @@ const char * const PrusaErrorButtonMore(){
     return btnMore;
 }
 
+struct ResetOnExit {
+    ResetOnExit() = default;
+    ~ResetOnExit(){
+        buttonSelectedOperation = ButtonOperations::NoOperation;
+    }
+};
+
+Buttons ButtonPressed(uint16_t ec) {
+    if (buttonSelectedOperation == ButtonOperations::NoOperation) {
+        return NoButton; // no button
+    }
+    
+    ResetOnExit ros; // clear buttonSelectedOperation on exit from this call
+    
+    uint8_t ei = PrusaErrorCodeIndex(ec);
+    
+    // The list of responses which occur in mmu error dialogs
+    // Return button index or perform some action on the MK4 by itself (like restart MMU)
+    // Based on Prusa-Error-Codes errors_list.h
+    // So far hardcoded, but shall be generated in the future
+    switch ( PrusaErrorCode(ei) ) {
+    case ERR_MECHANICAL_FINDA_DIDNT_TRIGGER:
+    case ERR_MECHANICAL_FINDA_DIDNT_GO_OFF:
+    case ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER:
+    case ERR_MECHANICAL_FSENSOR_DIDNT_GO_OFF:
+    case ERR_MECHANICAL_FSENSOR_TOO_EARLY:
+        switch (buttonSelectedOperation) {
+        case ButtonOperations::Retry: // "Repeat action"
+            return Middle;
+        case ButtonOperations::Continue: // "Continue"
+            return Right;
+        default:
+            break;
+        }
+        break;
+    case ERR_MECHANICAL_SELECTOR_CANNOT_HOME:
+    case ERR_MECHANICAL_IDLER_CANNOT_HOME:
+    case ERR_MECHANICAL_PULLEY_CANNOT_MOVE:
+        switch (buttonSelectedOperation) {
+        // may be allow move selector right and left in the future
+        case ButtonOperations::Retry: // "Repeat action"
+            return Middle;
+        default:
+            break;
+        }
+        break;
+        
+    case ERR_TEMPERATURE_PULLEY_WARNING_TMC_TOO_HOT:
+    case ERR_TEMPERATURE_SELECTOR_WARNING_TMC_TOO_HOT:
+    case ERR_TEMPERATURE_IDLER_WARNING_TMC_TOO_HOT:
+        switch (buttonSelectedOperation) {
+        case ButtonOperations::Continue: // "Continue"
+            return Left;
+        case ButtonOperations::RestartMMU: // "Restart MMU"
+            return RestartMMU;
+        default:
+            break;
+        }
+        break;
+        
+    case ERR_TEMPERATURE_PULLEY_TMC_OVERHEAT_ERROR:
+    case ERR_TEMPERATURE_SELECTOR_TMC_OVERHEAT_ERROR:
+    case ERR_TEMPERATURE_IDLER_TMC_OVERHEAT_ERROR:
+        
+    case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_ERROR:
+    case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_ERROR:
+    case ERR_ELECTRICAL_IDLER_TMC_DRIVER_ERROR:
+        
+    case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_RESET:
+    case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_RESET:
+    case ERR_ELECTRICAL_IDLER_TMC_DRIVER_RESET:
+        
+    case ERR_ELECTRICAL_PULLEY_TMC_UNDERVOLTAGE_ERROR:
+    case ERR_ELECTRICAL_SELECTOR_TMC_UNDERVOLTAGE_ERROR:
+    case ERR_ELECTRICAL_IDLER_TMC_UNDERVOLTAGE_ERROR:
+        
+    case ERR_ELECTRICAL_PULLEY_TMC_DRIVER_SHORTED:
+    case ERR_ELECTRICAL_SELECTOR_TMC_DRIVER_SHORTED:
+    case ERR_ELECTRICAL_IDLER_TMC_DRIVER_SHORTED:
+        
+    case ERR_CONNECT_MMU_NOT_RESPONDING:
+    case ERR_CONNECT_COMMUNICATION_ERROR:
+        
+    case ERR_SYSTEM_QUEUE_FULL:
+    case ERR_SYSTEM_FW_RUNTIME_ERROR:
+        switch (buttonSelectedOperation) {
+        case ButtonOperations::RestartMMU: // "Restart MMU"
+            return RestartMMU;
+        default:
+            break;
+        }
+        break;
+        
+    case ERR_SYSTEM_FILAMENT_ALREADY_LOADED:
+        switch (buttonSelectedOperation) {
+        case ButtonOperations::Unload: // "Unload"
+            return Left;
+        case ButtonOperations::Continue: // "Proceed/Continue"
+            return Right;
+        case ButtonOperations::RestartMMU: // "Restart MMU"
+            return RestartMMU;
+        default:
+            break;
+        }
+        break;
+        
+    case ERR_SYSTEM_INVALID_TOOL:
+        switch (buttonSelectedOperation) {
+        case ButtonOperations::StopPrint: // "Stop print"
+            return StopPrint;
+        case ButtonOperations::RestartMMU: // "Restart MMU"
+            return RestartMMU;
+        default:
+            break;
+        }
+        break;
+    default:
+        break;
+    }
+    
+    return NoButton;
+}
+
+void SetButtonResponse(ButtonOperations rsp){
+    buttonSelectedOperation = rsp;
+}
+
 } // namespace MMU2

+ 8 - 0
Firmware/mmu2_error_converter.h

@@ -1,6 +1,7 @@
 #pragma once
 #include <stdint.h>
 #include <stddef.h>
+#include "mmu2/buttons.h"
 
 namespace MMU2 {
 
@@ -31,4 +32,11 @@ const char * const PrusaErrorButtonTitle(uint8_t bi);
 /// @returns pointer to a PROGMEM string representing the "More" button
 const char * const PrusaErrorButtonMore();
 
+/// Sets the selected button for later pick-up by the MMU state machine.
+/// Used to save the GUI selection/decoupling
+void SetButtonResponse(ButtonOperations rsp);
+
+/// @returns button index/code based on currently processed error/screen
+Buttons ButtonPressed(uint16_t ec);
+
 } // namespace MMU2

+ 16 - 53
Firmware/mmu2_reporting.cpp

@@ -62,12 +62,11 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec) {
     // Read and determine what operations should be shown on the menu
     // Note: uint16_t is used here to avoid compiler warning. uint8_t is only half the size of void*
     const uint8_t button_operation   = PrusaErrorButtons(ei);
-    const uint8_t button_high_nibble = BUTTON_OP_HI_NIBBLE(button_operation);
-    const uint8_t button_low_nibble  = BUTTON_OP_LO_NIBBLE(button_operation);
+    const uint8_t button_op_right = BUTTON_OP_RIGHT(button_operation);
+    const uint8_t button_op_middle  = BUTTON_OP_MIDDLE(button_operation);
 
     // Check if the menu should have three or two choices
-    if (button_high_nibble == (uint8_t)ButtonOperations::NoOperation)
-    {
+    if (button_op_right == (uint8_t)ButtonOperations::NoOperation){
         // Two operations not specified, the error menu should only show two choices
         two_choices = true;
     }
@@ -75,69 +74,37 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec) {
 back_to_choices:
     lcd_clear();
     lcd_update_enable(false);
-     
+
     // Print title and header
     lcd_printf_P(PSTR("%.20S\nprusa3d.com/ERR04%hu"), _T(PrusaErrorTitle(ei)), PrusaErrorCode(ei) );
 
-    // Render static characters in third line
-    lcd_set_cursor(0, 2);
-    lcd_printf_P(PSTR("FI:  FS:    >  %c   %c"), LCD_STR_THERMOMETER[0], LCD_STR_DEGREE[0]);
-
     // Render the choices and store selection in 'choice_selected'
     choice_selected = lcd_show_multiscreen_message_with_choices_and_wait_P(
         NULL, // NULL, since title screen is not in PROGMEM
         false,
-        two_choices ? LEFT_BUTTON_CHOICE : MIDDLE_BUTTON_CHOICE,
-        _T(PrusaErrorButtonTitle(button_low_nibble)),
-        _T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_high_nibble)),
+        two_choices ? LCD_LEFT_BUTTON_CHOICE : LCD_MIDDLE_BUTTON_CHOICE, // beware - LEFT button on the LCD matches the MIDDLE button on the MMU!
+        _T(PrusaErrorButtonTitle(button_op_middle)),
+        _T(two_choices ? PrusaErrorButtonMore() : PrusaErrorButtonTitle(button_op_right)),
         two_choices ? nullptr : _T(PrusaErrorButtonMore()),
-        two_choices ? 
-            10 // If two choices, allow the first choice to have more characters
-            : 7,
-        ReportErrorHook_cb
+        two_choices ? 10 : 7 // If two choices, allow the first choice to have more characters
     );
 
-    if ((two_choices && choice_selected == MIDDLE_BUTTON_CHOICE)      // Two choices and middle button selected
-        || (!two_choices && choice_selected == RIGHT_BUTTON_CHOICE)) // Three choices and right most button selected
+    if ((two_choices && choice_selected == LCD_MIDDLE_BUTTON_CHOICE)      // Two choices and middle button selected
+        || (!two_choices && choice_selected == LCD_RIGHT_BUTTON_CHOICE)) // Three choices and right most button selected
     {
         // 'More' show error description
         lcd_show_fullscreen_message_and_wait_P(_T(PrusaErrorDesc(ei)));
 
         // Return back to the choice menu
         goto back_to_choices;
-    } else if(choice_selected == MIDDLE_BUTTON_CHOICE) {
-        // TODO: User selected middle choice, not sure what to do.
-        //       At the moment just return to the status screen
-        switch (button_high_nibble)
-        {
-        case (uint8_t)ButtonOperations::Retry:
-        case (uint8_t)ButtonOperations::Continue:
-        case (uint8_t)ButtonOperations::RestartMMU:
-        case (uint8_t)ButtonOperations::Unload:
-        case (uint8_t)ButtonOperations::StopPrint:
-        case (uint8_t)ButtonOperations::DisableMMU:
-        default:
-            lcd_update_enable(true);
-            lcd_return_to_status();
-            break;
-        }
+    } else if(choice_selected == LCD_MIDDLE_BUTTON_CHOICE) {
+        SetButtonResponse((ButtonOperations)button_op_right);
     } else {
-        // TODO: User selected the left most choice, not sure what to do.
-        //       At the moment just return to the status screen
-        switch (button_low_nibble)
-        {
-        case (uint8_t)ButtonOperations::Retry:
-        case (uint8_t)ButtonOperations::Continue:
-        case (uint8_t)ButtonOperations::RestartMMU:
-        case (uint8_t)ButtonOperations::Unload:
-        case (uint8_t)ButtonOperations::StopPrint:
-        case (uint8_t)ButtonOperations::DisableMMU:
-        default:
-            lcd_update_enable(true);
-            lcd_return_to_status();
-            break;
-        }
+        SetButtonResponse((ButtonOperations)button_op_middle);
     }
+    // if any button/command selected, close the screen
+    lcd_update_enable(true);
+    lcd_return_to_status();
 }
 
 void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
@@ -145,8 +112,4 @@ void ReportProgressHook(CommandInProgress cip, uint16_t ec) {
     lcd_setstatuspgm( _T(ProgressCodeToText(ec)) );
 }
 
-Buttons ButtonPressed(uint16_t ec) { 
-    // query the MMU error screen if a button has been pressed/selected
-}
-
 } // namespace MMU2

+ 0 - 15
Firmware/mmu2_reporting.h

@@ -28,21 +28,6 @@ void ReportErrorHook(CommandInProgress cip, uint16_t ec);
 /// Called when the MMU sends operation progress update
 void ReportProgressHook(CommandInProgress cip, uint16_t ec);
 
-/// Button codes + extended actions performed on the printer's side
-enum Buttons : uint8_t {
-    Left = 0,
-    Middle,
-    Right,
-    
-    // performed on the printer's side
-    RestartMMU,
-    StopPrint,
-    
-    NoButton = 0xff // shall be kept last
-};
-
-Buttons ButtonPressed(uint16_t ec);
-
 /// @returns true if the MMU is communicating and available
 /// can change at runtime
 bool MMUAvailable();

+ 34 - 33
Firmware/ultralcd.cpp

@@ -2299,11 +2299,11 @@ void show_preheat_nozzle_warning()
 
 void lcd_load_filament_color_check()
 {
-	bool clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LEFT_BUTTON_CHOICE);
-	while (clean == MIDDLE_BUTTON_CHOICE) {
+	bool clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LCD_LEFT_BUTTON_CHOICE);
+	while (clean == LCD_MIDDLE_BUTTON_CHOICE) {
 		load_filament_final_feed();
 		st_synchronize();
-		clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LEFT_BUTTON_CHOICE);
+		clean = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_CLEAN), false, LCD_LEFT_BUTTON_CHOICE);
 	}
 }
 
@@ -3193,23 +3193,25 @@ int8_t lcd_show_multiscreen_message_yes_no_and_wait_P(const char *msg, bool allo
 void lcd_show_choices_prompt_P(uint8_t selected, const char *first_choice, const char *second_choice, uint8_t second_col, const char *third_choice = nullptr)
 {
     lcd_set_cursor(0, 3);
-    lcd_print(selected == LEFT_BUTTON_CHOICE ? '>': ' ');
+    lcd_print(selected == LCD_LEFT_BUTTON_CHOICE ? '>': ' ');
     lcd_puts_P(first_choice);
     if (third_choice)
     {
         lcd_set_cursor(7, 3);
-        lcd_print(selected == MIDDLE_BUTTON_CHOICE ? '>': ' ');
+        lcd_print(selected == LCD_MIDDLE_BUTTON_CHOICE ? '>': ' ');
         lcd_puts_P(second_choice);
         lcd_set_cursor(13, 3);
-        lcd_print(selected == RIGHT_BUTTON_CHOICE ? '>': ' ');
+        lcd_print(selected == LCD_RIGHT_BUTTON_CHOICE ? '>': ' ');
         lcd_puts_P(third_choice);
     } else {
         lcd_set_cursor(second_col, 3);
-        lcd_print(selected == MIDDLE_BUTTON_CHOICE ? '>': ' ');
+        lcd_print(selected == LCD_MIDDLE_BUTTON_CHOICE ? '>': ' ');
         lcd_puts_P(second_choice);
     }
 }
 
+typedef ;
+
 //! @brief Show single or multiple screen message with two possible choices and wait with possible timeout
 //! @param msg Message to show. If NULL, do not clear the screen and handle choice selection only.
 //! @param allow_timeouting bool, if true, allows time outing of the screen
@@ -3231,25 +3233,24 @@ int8_t lcd_show_multiscreen_message_with_choices_and_wait_P(const char * const m
 	bool multi_screen = msg_next != NULL;
 	lcd_set_custom_characters_nextpage();
 
-	// Initial status/prompt on single-screen messages
-	uint8_t current_selection = default_selection;
-	if (!msg_next) {
-		lcd_show_choices_prompt_P(current_selection, first_choice, second_choice, second_col, third_choice);
-	}
-	// Wait for user confirmation or a timeout.
-	unsigned long previous_millis_cmd = _millis();
-	int8_t enc_dif = lcd_encoder_diff;
-	lcd_consume_click();
-	KEEPALIVE_STATE(PAUSED_FOR_USER);
-	for (;;) {
-		for (uint8_t i = 0; i < 100; ++i) {
-			delay_keep_alive(50);
-			if (allow_timeouting && _millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS)
-			{
-				return -1;
-			}
-			manage_heater();
-			manage_inactivity(true);
+    // Initial status/prompt on single-screen messages
+    uint8_t current_selection = default_selection;
+    if (!msg_next) {
+        lcd_show_choices_prompt_P(current_selection, first_choice, second_choice, second_col, third_choice);
+    }
+    // Wait for user confirmation or a timeout.
+    unsigned long previous_millis_cmd = _millis();
+    int8_t enc_dif = lcd_encoder_diff;
+    lcd_consume_click();
+    KEEPALIVE_STATE(PAUSED_FOR_USER);
+    for (;;) {
+        for (uint8_t i = 0; i < 100; ++i) {
+            delay_keep_alive(50);
+            if (allow_timeouting && _millis() - previous_millis_cmd > LCD_TIMEOUT_TO_STATUS) {
+                return -1;
+            }
+            manage_heater();
+            manage_inactivity(true);
 
 			if (multiscreen_cb)
 			{
@@ -3848,7 +3849,7 @@ void lcd_v2_calibration()
 	    }
 	    else
 	    {
-	        loaded = !lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), false, LEFT_BUTTON_CHOICE);
+	        loaded = !lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), false, LCD_LEFT_BUTTON_CHOICE);
 	        lcd_update_enabled = true;
 
 	    }
@@ -4040,8 +4041,8 @@ void lcd_wizard(WizState state)
 				lcd_show_fullscreen_message_and_wait_P(_T(MSG_WIZARD_WELCOME_SHIPPING));
 				state = S::Restore;
 			} else {
-				wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_T(MSG_WIZARD_WELCOME), false, LEFT_BUTTON_CHOICE);
-				if (wizard_event == LEFT_BUTTON_CHOICE) {
+				wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_T(MSG_WIZARD_WELCOME), false, LCD_LEFT_BUTTON_CHOICE);
+				if (wizard_event == LCD_LEFT_BUTTON_CHOICE) {
 					state = S::Restore;
 					eeprom_update_byte((uint8_t*)EEPROM_WIZARD_ACTIVE, 1);
 				} else { // MIDDLE_BUTTON_CHOICE
@@ -4080,7 +4081,7 @@ void lcd_wizard(WizState state)
 			lcd_show_fullscreen_message_and_wait_P(_i("Now remove the test print from steel sheet."));////MSG_REMOVE_TEST_PRINT c=20 r=4
 			lcd_show_fullscreen_message_and_wait_P(_i("I will run z calibration now."));////MSG_WIZARD_Z_CAL c=20 r=8
 			wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_STEEL_SHEET_CHECK), false);
-			if (wizard_event == MIDDLE_BUTTON_CHOICE) {
+			if (wizard_event == LCD_MIDDLE_BUTTON_CHOICE) {
 				lcd_show_fullscreen_message_and_wait_P(_T(MSG_PLACE_STEEL_SHEET));
 			}
 			wizard_event = gcode_M45(true, 0);
@@ -4104,7 +4105,7 @@ void lcd_wizard(WizState state)
 			setTargetHotend(PLA_PREHEAT_HOTEND_TEMP, 0);
 			setTargetBed(PLA_PREHEAT_HPB_TEMP);
 			wizard_event = lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_FILAMENT_LOADED), true);
-			if (wizard_event == LEFT_BUTTON_CHOICE) {
+			if (wizard_event == LCD_LEFT_BUTTON_CHOICE) {
 				state = S::Lay1CalCold;
 			} else { // MIDDLE_BUTTON_CHOICE
 			    if(MMU2::mmu2.Enabled()) state = S::LoadFilCold;
@@ -4137,7 +4138,7 @@ void lcd_wizard(WizState state)
             break;
 		case S::RepeatLay1Cal:
 			wizard_event = lcd_show_multiscreen_message_yes_no_and_wait_P(_i("Do you want to repeat last step to readjust distance between nozzle and heatbed?"), false);////MSG_WIZARD_REPEAT_V2_CAL c=20 r=7
-			if (wizard_event == LEFT_BUTTON_CHOICE)
+			if (wizard_event == LCD_LEFT_BUTTON_CHOICE)
 			{
 				lcd_show_fullscreen_message_and_wait_P(_i("Please clean heatbed and then press the knob."));////MSG_WIZARD_CLEAN_HEATBED c=20 r=8
 				state = S::Lay1CalCold;
@@ -5092,7 +5093,7 @@ char reset_menu() {
 static void lcd_disable_farm_mode()
 {
 	int8_t disable = lcd_show_fullscreen_message_yes_no_and_wait_P(PSTR("Disable farm mode?"), true); //allow timeouting, default no
-	if (disable == LEFT_BUTTON_CHOICE)
+	if (disable == LCD_LEFT_BUTTON_CHOICE)
 	{
 		enquecommand_P(PSTR("G99"));
 		lcd_return_to_status();

+ 5 - 6
Firmware/ultralcd.h

@@ -64,11 +64,10 @@ void lcd_crash_detect_enable();
 void lcd_crash_detect_disable();
 #endif
 
-enum ButtonChoice
-{
-    LEFT_BUTTON_CHOICE = 0,
-    MIDDLE_BUTTON_CHOICE = 1,
-    RIGHT_BUTTON_CHOICE = 2,
+enum LCDButtonChoice : uint_fast8_t {
+    LCD_LEFT_BUTTON_CHOICE = 0,
+    LCD_MIDDLE_BUTTON_CHOICE = 1,
+    LCD_RIGHT_BUTTON_CHOICE = 2,
 };
 
 extern const char* lcd_display_message_fullscreen_P(const char *msg);
@@ -78,7 +77,7 @@ extern void lcd_wait_for_click();
 extern bool lcd_wait_for_click_delay(uint16_t nDelay);
 extern void lcd_show_fullscreen_message_and_wait_P(const char *msg);
 // 1: no, 0: yes, -1: timeouted
-extern int8_t lcd_show_yes_no_and_wait(bool allow_timeouting = true, uint8_t default_selection = MIDDLE_BUTTON_CHOICE);
+extern int8_t lcd_show_yes_no_and_wait(bool allow_timeouting = true, uint8_t default_selection = LCD_MIDDLE_BUTTON_CHOICE);
 // 1: no, 0: yes, -1: timeouted
 extern int8_t lcd_show_fullscreen_message_yes_no_and_wait_P(const char *msg, bool allow_timeouting = true, uint8_t default_selection = MIDDLE_BUTTON_CHOICE);
 extern int8_t lcd_show_multiscreen_message_with_choices_and_wait_P(const char * const msg, bool allow_timeouting, uint8_t default_selection,