From a6fbd4a5d84df26facfa24f3fa3745748e9d0eb4 Mon Sep 17 00:00:00 2001 From: AnHardt Date: Thu, 24 Nov 2016 21:17:25 +0100 Subject: [PATCH] Distribute GLCD screen updates in time Currently we draw and send the screens for a graphical LCD all at once. We draw in two or four parts but draw them directly behind each other. For the tested status screen this takes 59-62ms in a single block. During this time nothing else (except the interrupts) can be done. When printing a sequence of very short moves the buffer drains - sometimes until it's empty. This PR splits the screen update into parts. Currently we have 10 time slots. During the first one the complete screen is drawn. (60,0,0,0,0,0,0,0,0,0,0) Here i introduce pauses for doing other things. (30,30,0,0,0,0,0,0) or (15,15,15,15,0,0,0,0,0,0) Drawing in consecutive time slots prevents from lagging too much. Even with a 4 stripe display all the drawing is done after 400ms. Previous experiments with a even better distribution of the time slots like (30,0,0,0,0,30,0,0,0,0) and (15,0,15,0,15,0,15,0,0,0) did not feel good when using the menu, because of too much lag. Because of the previous PRs to speed up the display updates and especially reducing the difference between drawing 2 or 4 stripes, it now makes sense for the REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER to go from 2 to 4 stripes. This costs about 1-2ms per complete screen update, but is payed back by having partial updates lasting only the half time and two additional brakes. Also ~256 byte of framebuffer are saved in RAM. 13:45:59.213 : echo: #:17 >:13 s:30; #:16 >:13 s:29; S#:33 S>:26 S:59 13:46:00.213 : echo: #:16 >:14 s:30; #:17 >:13 s:30; S#:33 S>:27 S:60 13:46:01.215 : echo: #:17 >:13 s:30; #:16 >:13 s:29; S#:33 S>:26 S:59 13:46:02.215 : echo: #:16 >:13 s:29; #:16 >:14 s:30; S#:32 S>:27 S:59 13:46:03.214 : echo: #:17 >:13 s:30; #:17 >:13 s:30; S#:34 S>:26 S:60 13:46:04.214 : echo: #:16 >:13 s:29; #:16 >:14 s:30; S#:32 S>:27 S:59 13:46:05.212 : echo: #:16 >:14 s:30; #:17 >:13 s:30; S#:33 S>:27 S:60 13:46:06.212 : echo: #:17 >:13 s:30; #:16 >:13 s:29; S#:33 S>:26 S:59 03:30:36.779 : echo: #:8 >:7 s:15; #:10 >:7 s:17; #:8 >:6 s:14; #:8 >:7 s:15; S#:34 S>:27 S:61 03:30:37.778 : echo: #:8 >:6 s:14; #:10 >:7 s:17; #:9 >:7 s:16; #:8 >:6 s:14; S#:35 S>:26 S:61 03:30:38.778 : echo: #:8 >:6 s:14; #:11 >:7 s:18; #:8 >:6 s:14; #:8 >:7 s:15; S#:35 S>:26 S:61 03:30:39.777 : echo: #:8 >:6 s:14; #:10 >:7 s:17; #:8 >:8 s:16; #:8 >:6 s:14; S#:34 S>:27 S:61 03:30:40.780 : echo: #:8 >:6 s:14; #:11 >:7 s:18; #:8 >:6 s:14; #:8 >:6 s:14; S#:35 S>:25 S:60 03:30:41.780 : echo: #:9 >:6 s:15; #:10 >:7 s:17; #:8 >:6 s:14; #:9 >:6 s:15; S#:36 S>:25 S:61 03:30:42.779 : echo: #:8 >:6 s:14; #:10 >:8 s:18; #:8 >:6 s:14; #:8 >:6 s:14; S#:34 S>:26 S:60 03:30:43.778 : echo: #:9 >:6 s:15; #:10 >:7 s:17; #:8 >:7 s:15; #:9 >:6 s:15; S#:36 S>:26 S:62 #: draw a stripe >: transfer a stripe s: sum of of draw and transfer for one stripe S#: sum of draws for a complete screen S>: sum of transfers for a complete screen S: time to draw and transfer a complete screen --- Marlin/ultralcd.cpp | 96 +++++++++++++++++------------ Marlin/ultralcd_impl_DOGM.h | 2 +- Marlin/ultralcd_st7920_u8glib_rrd.h | 4 +- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 2aa5055b6..dda4418f0 100755 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -64,6 +64,9 @@ void lcd_status_screen(); millis_t next_lcd_update_ms; uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to draw, decrements after every draw. Set to 2 in LCD routines so the LCD gets at least 1 full redraw (first redraw is partial) +#if ENABLED(DOGLCD) + bool drawing_screen = false; +#endif #if ENABLED(DAC_STEPPER_CURRENT) #include "stepper_dac.h" //was dac_mcp4728.h MarlinMain uses stepper dac for the m-codes @@ -413,6 +416,9 @@ uint8_t lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW; // Set when the LCD needs to #endif lcdDrawUpdate = LCDVIEW_CALL_REDRAW_NEXT; screen_changed = true; + #if ENABLED(DOGLCD) + drawing_screen = false; + #endif } } @@ -2832,6 +2838,9 @@ void lcd_update() { encoderPosition += (encoderDiff * encoderMultiplier) / ENCODER_PULSES_PER_STEP; encoderDiff = 0; + #if ENABLED(DOGLCD) + drawing_screen = false; // refresh the complete screen for a encoder change (different menu-item/value) + #endif } return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS; lcdDrawUpdate = LCDVIEW_REDRAW_NOW; @@ -2864,20 +2873,28 @@ void lcd_update() { if (LCD_HANDLER_CONDITION) { - if (lcdDrawUpdate) { - - switch (lcdDrawUpdate) { - case LCDVIEW_CALL_NO_REDRAW: - lcdDrawUpdate = LCDVIEW_NONE; - break; - case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) - case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) - lcdDrawUpdate = LCDVIEW_REDRAW_NOW; - case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT - case LCDVIEW_NONE: - break; - } // switch - + #if ENABLED(DOGLCD) + if (lcdDrawUpdate || drawing_screen) + #else + if (lcdDrawUpdate) + #endif + { + #if ENABLED(DOGLCD) + if (!drawing_screen) + #endif + { + switch (lcdDrawUpdate) { + case LCDVIEW_CALL_NO_REDRAW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_CLEAR_CALL_REDRAW: // set by handlers, then altered after (rarely occurs here) + case LCDVIEW_CALL_REDRAW_NEXT: // set by handlers, then altered after (never occurs here?) + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + case LCDVIEW_REDRAW_NOW: // set above, or by a handler through LCDVIEW_CALL_REDRAW_NEXT + case LCDVIEW_NONE: + break; + } // switch + } #if ENABLED(ULTIPANEL) #define CURRENTSCREEN() (*currentScreen)(), lcd_clicked = false #else @@ -2885,17 +2902,13 @@ void lcd_update() { #endif #if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display - static int8_t dot_color = 0; - dot_color = 1 - dot_color; - u8g.firstPage(); - do { - lcd_setFont(FONT_MENU); - u8g.setPrintPos(125, 0); - u8g.setColorIndex(dot_color); // Set color for the alive dot - u8g.drawPixel(127, 63); // draw alive dot - u8g.setColorIndex(1); // black on white - CURRENTSCREEN(); - } while (u8g.nextPage()); + if (!drawing_screen) { + u8g.firstPage(); + drawing_screen = 1; + } + lcd_setFont(FONT_MENU); + CURRENTSCREEN(); + if (drawing_screen && (drawing_screen = u8g.nextPage())) return; #else CURRENTSCREEN(); #endif @@ -2911,22 +2924,25 @@ void lcd_update() { #endif // ULTIPANEL - switch (lcdDrawUpdate) { - case LCDVIEW_CLEAR_CALL_REDRAW: - lcd_implementation_clear(); - case LCDVIEW_CALL_REDRAW_NEXT: - lcdDrawUpdate = LCDVIEW_REDRAW_NOW; - break; - case LCDVIEW_REDRAW_NOW: - lcdDrawUpdate = LCDVIEW_NONE; - break; - case LCDVIEW_NONE: - break; - } // switch - + #if ENABLED(DOGLCD) + if (!drawing_screen) + #endif + { + switch (lcdDrawUpdate) { + case LCDVIEW_CLEAR_CALL_REDRAW: + lcd_implementation_clear(); + case LCDVIEW_CALL_REDRAW_NEXT: + lcdDrawUpdate = LCDVIEW_REDRAW_NOW; + break; + case LCDVIEW_REDRAW_NOW: + lcdDrawUpdate = LCDVIEW_NONE; + break; + case LCDVIEW_NONE: + break; + } // switch + } } // LCD_HANDLER_CONDITION - - } + } // ELAPSED(ms, next_lcd_update_ms) } void set_utf_strlen(char* s, uint8_t n) { diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h index 46a522561..f8ffe7498 100644 --- a/Marlin/ultralcd_impl_DOGM.h +++ b/Marlin/ultralcd_impl_DOGM.h @@ -145,7 +145,7 @@ #elif ENABLED(U8GLIB_ST7920) //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes // No 4 stripe device available from u8glib. - //U8GLIB_ST7920_128X64 u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 8 stripes + //U8GLIB_ST7920_128X64_1X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 8 stripes U8GLIB_ST7920_128X64_RRD u8g(0); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT #elif ENABLED(CARTESIO_UI) // The CartesioUI display diff --git a/Marlin/ultralcd_st7920_u8glib_rrd.h b/Marlin/ultralcd_st7920_u8glib_rrd.h index 1dc39360f..66e1f1722 100644 --- a/Marlin/ultralcd_st7920_u8glib_rrd.h +++ b/Marlin/ultralcd_st7920_u8glib_rrd.h @@ -32,8 +32,8 @@ #define ST7920_CS_PIN LCD_PINS_RS //#define PAGE_HEIGHT 8 //128 byte framebuffer -//#define PAGE_HEIGHT 16 //256 byte framebuffer -#define PAGE_HEIGHT 32 //512 byte framebuffer +#define PAGE_HEIGHT 16 //256 byte framebuffer +//#define PAGE_HEIGHT 32 //512 byte framebuffer #define LCD_PIXEL_WIDTH 128 #define LCD_PIXEL_HEIGHT 64