From b4dbf4d18a03029f44217e73b7dbe8c7b5123a91 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 12 Dec 2016 21:56:05 -0800 Subject: [PATCH] Non-reentrant "Moving..." screen to safely wait in LCD --- Marlin/language_en.h | 3 +++ Marlin/ultralcd.cpp | 36 +++++++++++++++++++++++++---- Marlin/ultralcd_impl_DOGM.h | 42 +++++++++++++++------------------- Marlin/ultralcd_impl_HD44780.h | 40 +++++++++++++++----------------- 4 files changed, 71 insertions(+), 50 deletions(-) diff --git a/Marlin/language_en.h b/Marlin/language_en.h index f19de3b33..4f8dd2060 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -138,6 +138,9 @@ #ifndef MSG_LEVEL_BED #define MSG_LEVEL_BED "Level bed" #endif +#ifndef MSG_MOVING + #define MSG_MOVING "Moving..." +#endif #ifndef MSG_MOVE_X #define MSG_MOVE_X "Move X" #endif diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index bae069b79..479da86b1 100755 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -390,7 +390,7 @@ uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to bool screen_changed; // LCD and menu clicks - bool lcd_clicked, wait_for_unclick, defer_return_to_status; + bool lcd_clicked, wait_for_unclick, defer_return_to_status, no_reentrance; // Variables used when editing values. const char* editLabel; @@ -422,6 +422,27 @@ uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to } } + /** + * Synchronize safely while holding the current screen + * This blocks all further screen or stripe updates once called + */ + inline void lcd_synchronize() { + lcd_implementation_drawmenu_static(LCD_HEIGHT >= 4 ? 1 : 0, PSTR(MSG_MOVING)); + if (no_reentrance) return; + no_reentrance = true; + screenFunc_t old_screen = currentScreen; + lcd_goto_screen(lcd_synchronize); + stepper.synchronize(); + no_reentrance = false; + lcd_goto_screen(old_screen); + } + + inline void lcd_wait_for_homing() { + no_reentrance = true; + while (!axis_homed[X_AXIS] || !axis_homed[Y_AXIS] || !axis_homed[Z_AXIS]) idle(); + no_reentrance = true; + } + void lcd_return_to_status() { lcd_goto_screen(lcd_status_screen); } void lcd_save_previous_screen() { @@ -1063,6 +1084,7 @@ void kill_screen(const char* lcd_msg) { // Note: During Manual Bed Leveling the homed Z position is MESH_HOME_SEARCH_Z // Z position will be restored with the final action, a G28 inline void _mbl_goto_xy(float x, float y) { + if (no_reentrance) return; current_position[Z_AXIS] = LOGICAL_Z_POSITION(MESH_HOME_SEARCH_Z + Z_HOMING_HEIGHT); line_to_current(Z_AXIS); current_position[X_AXIS] = LOGICAL_X_POSITION(x); @@ -1072,7 +1094,7 @@ void kill_screen(const char* lcd_msg) { current_position[Z_AXIS] = LOGICAL_Z_POSITION(MESH_HOME_SEARCH_Z); line_to_current(Z_AXIS); #endif - stepper.synchronize(); + lcd_synchronize(); } void _lcd_level_goto_next_point(); @@ -1094,6 +1116,8 @@ void kill_screen(const char* lcd_msg) { void _lcd_level_bed_get_z() { ENCODER_DIRECTION_NORMAL(); + if (no_reentrance) goto KeepDrawing; + // Encoder wheel adjusts the Z position if (encoderPosition) { refresh_cmd_timeout(); @@ -1121,7 +1145,7 @@ void kill_screen(const char* lcd_msg) { current_position[Z_AXIS] = MESH_HOME_SEARCH_Z + Z_HOMING_HEIGHT; line_to_current(Z_AXIS); - stepper.synchronize(); + lcd_synchronize(); mbl.set_has_mesh(true); enqueue_and_echo_commands_P(PSTR("G28")); @@ -1141,6 +1165,7 @@ void kill_screen(const char* lcd_msg) { debounce_click = false; } +KeepDrawing: // Update on first display, then only on updates to Z position // Show message above on clicks instead if (lcdDrawUpdate) { @@ -1215,8 +1240,9 @@ void kill_screen(const char* lcd_msg) { LCDVIEW_CALL_NO_REDRAW #endif ; - if (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS]) - lcd_goto_screen(_lcd_level_bed_homing_done); + if (no_reentrance) return; + lcd_wait_for_homing(); + lcd_goto_screen(_lcd_level_bed_homing_done); } /** diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h index f8ffe7498..4adba37d2 100644 --- a/Marlin/ultralcd_impl_DOGM.h +++ b/Marlin/ultralcd_impl_DOGM.h @@ -656,34 +656,30 @@ static void lcd_implementation_status_screen() { u8g.setPrintPos((START_COL) * (DOG_CHAR_WIDTH), row_y2); } - #if ENABLED(LCD_INFO_MENU) || ENABLED(FILAMENT_CHANGE_FEATURE) + // Draw a static line of text in the same idiom as a menu item + static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char* valstr=NULL) { - // Draw a static line of text in the same idiom as a menu item - static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char* valstr=NULL) { + lcd_implementation_mark_as_selected(row, invert); - lcd_implementation_mark_as_selected(row, invert); - - if (!PAGE_CONTAINS(row_y1, row_y2)) return; + if (!PAGE_CONTAINS(row_y1, row_y2)) return; - char c; - int8_t n = LCD_WIDTH - (START_COL); + char c; + int8_t n = LCD_WIDTH - (START_COL); - if (center && !valstr) { - int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; - while (--pad >= 0) { u8g.print(' '); n--; } - } - while (n > 0 && (c = pgm_read_byte(pstr))) { - n -= lcd_print_and_count(c); - pstr++; - } - if (valstr) while (n > 0 && (c = *valstr)) { - n -= lcd_print_and_count(c); - valstr++; - } - while (n-- > 0) u8g.print(' '); + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { u8g.print(' '); n--; } } - - #endif // LCD_INFO_MENU || FILAMENT_CHANGE_FEATURE + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= lcd_print_and_count(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= lcd_print_and_count(c); + valstr++; + } + while (n-- > 0) u8g.print(' '); + } // Draw a generic menu item static void lcd_implementation_drawmenu_generic(const bool isSelected, const uint8_t row, const char* pstr, const char pre_char, const char post_char) { diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h index a5efb0e09..bc2504c14 100644 --- a/Marlin/ultralcd_impl_HD44780.h +++ b/Marlin/ultralcd_impl_HD44780.h @@ -792,29 +792,25 @@ static void lcd_implementation_status_screen() { #if ENABLED(ULTIPANEL) - #if ENABLED(LCD_INFO_MENU) || ENABLED(FILAMENT_CHANGE_FEATURE) - - static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char *valstr=NULL) { - UNUSED(invert); - char c; - int8_t n = LCD_WIDTH; - lcd.setCursor(0, row); - if (center && !valstr) { - int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; - while (--pad >= 0) { lcd.print(' '); n--; } - } - while (n > 0 && (c = pgm_read_byte(pstr))) { - n -= charset_mapper(c); - pstr++; - } - if (valstr) while (n > 0 && (c = *valstr)) { - n -= charset_mapper(c); - valstr++; - } - while (n-- > 0) lcd.print(' '); + static void lcd_implementation_drawmenu_static(const uint8_t row, const char* pstr, const bool center=true, const bool invert=false, const char *valstr=NULL) { + UNUSED(invert); + char c; + int8_t n = LCD_WIDTH; + lcd.setCursor(0, row); + if (center && !valstr) { + int8_t pad = (LCD_WIDTH - lcd_strlen_P(pstr)) / 2; + while (--pad >= 0) { lcd.print(' '); n--; } } - - #endif // LCD_INFO_MENU || FILAMENT_CHANGE_FEATURE + while (n > 0 && (c = pgm_read_byte(pstr))) { + n -= charset_mapper(c); + pstr++; + } + if (valstr) while (n > 0 && (c = *valstr)) { + n -= charset_mapper(c); + valstr++; + } + while (n-- > 0) lcd.print(' '); + } static void lcd_implementation_drawmenu_generic(const bool sel, const uint8_t row, const char* pstr, const char pre_char, const char post_char) { char c;