diff --git a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp index 26c2ae8848..c62f6a06ec 100644 --- a/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp +++ b/Marlin/src/HAL/HAL_DUE/u8g_com_HAL_DUE_shared_hw_spi.cpp @@ -94,10 +94,8 @@ void u8g_SetPILevel_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index, uint8_t level) { else port->PIO_CODR = mask; } -uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) -{ - switch(msg) - { +uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch(msg) { case U8G_COM_MSG_STOP: break; diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 80e022b82c..294195a1a4 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -1687,6 +1687,7 @@ static_assert(X_MAX_LENGTH >= X_BED_SIZE && Y_MAX_LENGTH >= Y_BED_SIZE, && DISABLED(MKS_12864OLED_SSD1306) ) \ + (ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && DISABLED(BQ_LCD_SMART_CONTROLLER)) \ + ENABLED(LCD_FOR_MELZI) \ + + ENABLED(MALYAN_LCD) \ + ENABLED(MKS_12864OLED) \ + ENABLED(MKS_12864OLED_SSD1306) \ + ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602) \ diff --git a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp index 2d657f050d..413f11872f 100644 --- a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp +++ b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp @@ -19,7 +19,7 @@ #include "../ultralcd.h" #include "../../Marlin.h" -#include "ultralcd_common_HD44780.h" +#include "ultralcd_HD44780.h" #include diff --git a/Marlin/src/lcd/HD44780/ultralcd_impl_HD44780.cpp b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp similarity index 99% rename from Marlin/src/lcd/HD44780/ultralcd_impl_HD44780.cpp rename to Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp index edd38fb867..1c5c9832a3 100644 --- a/Marlin/src/lcd/HD44780/ultralcd_impl_HD44780.cpp +++ b/Marlin/src/lcd/HD44780/ultralcd_HD44780.cpp @@ -31,7 +31,7 @@ * These are the most common LCD character displays. */ -#include "ultralcd_common_HD44780.h" +#include "ultralcd_HD44780.h" #include "../ultralcd.h" #include "../../sd/cardreader.h" diff --git a/Marlin/src/lcd/HD44780/ultralcd_common_HD44780.h b/Marlin/src/lcd/HD44780/ultralcd_HD44780.h similarity index 100% rename from Marlin/src/lcd/HD44780/ultralcd_common_HD44780.h rename to Marlin/src/lcd/HD44780/ultralcd_HD44780.h diff --git a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h index 93d57bb792..e1a2ea9806 100644 --- a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h +++ b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h @@ -21,56 +21,63 @@ */ #pragma once +#include "../../inc/MarlinConfig.h" + // use this file to create the public interface for device drivers that are NOT in the U8G library extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi; extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi; -class U8GLIB_64128N_2X_HAL : public U8GLIB -{ - public: - U8GLIB_64128N_2X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset) - { } - U8GLIB_64128N_2X_HAL(pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_hw_spi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset) - { } + +class U8GLIB_64128N_2X_HAL : public U8GLIB { +public: + U8GLIB_64128N_2X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset) + { } + U8GLIB_64128N_2X_HAL(pin_t cs, pin_t a0, pin_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_hw_spi, (uint8_t)cs, (uint8_t)a0, (uint8_t)reset) + { } }; extern u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_sw_spi; extern u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_hw_spi; -class U8GLIB_ST7920_128X64_4X_HAL : public U8GLIB -{ - public: - U8GLIB_ST7920_128X64_4X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE - { } - U8GLIB_ST7920_128X64_4X_HAL(pin_t cs, pin_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_hw_spi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE - { } + +class U8GLIB_ST7920_128X64_4X_HAL : public U8GLIB { +public: + U8GLIB_ST7920_128X64_4X_HAL(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE + { } + U8GLIB_ST7920_128X64_4X_HAL(pin_t cs, pin_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_hw_spi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE + { } }; -// AVR version uses ultralcd_st7920_u8glib_rrd_AVR.cpp, HAL version uses u8g_dev_st7920_128x64_HAL.cpp +// +// AVR version uses ultralcd_st7920_u8glib_rrd_AVR.cpp +// HAL version uses u8g_dev_st7920_128x64_HAL.cpp +// extern u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi; -class U8GLIB_ST7920_128X64_RRD : public U8GLIB -{ - public: - U8GLIB_ST7920_128X64_RRD(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE - { } + +class U8GLIB_ST7920_128X64_RRD : public U8GLIB { +public: + U8GLIB_ST7920_128X64_RRD(pin_t sck, pin_t mosi, pin_t cs, pin_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi, (uint8_t)sck, (uint8_t)mosi, (uint8_t)cs, U8G_PIN_NONE, (uint8_t)reset) // a0 = U8G_PIN_NONE + { } }; extern u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire; + class U8GLIB_SH1106_128X64_2X_I2C_2_WIRE : public U8GLIB { - public: - U8GLIB_SH1106_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) - : U8GLIB(&u8g_dev_sh1106_128x64_2x_i2c_2_wire, options) - { } +public: + U8GLIB_SH1106_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) + : U8GLIB(&u8g_dev_sh1106_128x64_2x_i2c_2_wire, options) + { } }; extern u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire; + class U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE : public U8GLIB { - public: - U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) - : U8GLIB(&u8g_dev_ssd1306_128x64_2x_i2c_2_wire, options) - { } +public: + U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) + : U8GLIB(&u8g_dev_ssd1306_128x64_2x_i2c_2_wire, options) + { } }; diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp index af209a07df..f70bd486be 100644 --- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp +++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp @@ -30,8 +30,10 @@ #if HAS_GRAPHICAL_LCD && DISABLED(LIGHTWEIGHT_UI) #include "dogm_Statusscreen.h" +#include "ultralcd_DOGM.h" #include "../ultralcd.h" #include "../lcdprint.h" + #include "../../module/motion.h" #include "../../module/temperature.h" diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp index 40c47868f9..e02423e64b 100644 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp +++ b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.cpp @@ -45,7 +45,7 @@ #if ENABLED(LIGHTWEIGHT_UI) -#include "status_screen_lite_ST7920_class.h" +#include "status_screen_lite_ST7920.h" #include "../ultralcd.h" #include "../fontutils.h" @@ -916,8 +916,7 @@ void ST7920_Lite_Status_Screen::on_exit() { } // This is called prior to the KILL screen to -// clear the screen so we don't end up with a -// garbled display. +// clear the screen, preventing a garbled display. void ST7920_Lite_Status_Screen::clear_text_buffer() { cs(); reset_state_from_unknown(); @@ -926,23 +925,42 @@ void ST7920_Lite_Status_Screen::clear_text_buffer() { ncs(); } +#if ENABLED(U8GLIB_ST7920) && !defined(U8G_HAL_LINKS) && !defined(__SAM3X8E__) + + #include "ultralcd_st7920_u8glib_rrd_AVR.h" + + void ST7920_Lite_Status_Screen::cs() { + ST7920_CS(); + current_bits.synced = false; + } + + void ST7920_Lite_Status_Screen::ncs() { + ST7920_NCS(); + current_bits.synced = false; + } + + void ST7920_Lite_Status_Screen::sync_cmd() { + ST7920_SET_CMD(); + } + + void ST7920_Lite_Status_Screen::sync_dat() { + ST7920_SET_DAT(); + } + + void ST7920_Lite_Status_Screen::write_byte(const uint8_t data) { + ST7920_WRITE_BYTE(data); + } + +#endif + void MarlinUI::draw_status_screen() { ST7920_Lite_Status_Screen::update(false); } -/** - * In order to properly update the lite Status Screen, - * we must know when we have entered and left the - * Status Screen. Since the ultralcd code is not - * set up for doing this, we call this function before - * each update indicating whether the current screen - * is the Status Screen. - * - * This function keeps track of whether we have left or - * entered the Status Screen and calls the on_entry() - * and on_exit() methods for cleanup. - */ -void lcd_in_status(const bool inStatus) { +// This method is called before each screen update and +// fires on_entry() and on_exit() events upon entering +// or exiting the Status Screen. +void MarlinUI::lcd_in_status(const bool inStatus) { static bool lastInStatus = false; if (lastInStatus == inStatus) return; if ((lastInStatus = inStatus)) diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920_class.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920.h similarity index 100% rename from Marlin/src/lcd/dogm/status_screen_lite_ST7920_class.h rename to Marlin/src/lcd/dogm/status_screen_lite_ST7920.h diff --git a/Marlin/src/lcd/dogm/status_screen_lite_ST7920_spi.h b/Marlin/src/lcd/dogm/status_screen_lite_ST7920_spi.h deleted file mode 100644 index 9c59068f46..0000000000 --- a/Marlin/src/lcd/dogm/status_screen_lite_ST7920_spi.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Lightweight Status Screen for the RepRapDiscount Full - * Graphics Smart Controller (ST7920-based 128x64 LCD) - * - * (c) 2017 Aleph Objects, Inc. - * - * The code in this page is free software: you can - * redistribute it and/or modify it under the terms of the GNU - * General Public License (GNU GPL) as published by the Free Software - * Foundation, either version 3 of the License, or (at your option) - * any later version. The code is distributed WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. - * - */ - -#include "status_screen_lite_ST7920_class.h" - -void ST7920_Lite_Status_Screen::cs() { - ST7920_CS(); - current_bits.synced = false; -} - -void ST7920_Lite_Status_Screen::ncs() { - ST7920_NCS(); - current_bits.synced = false; -} - -void ST7920_Lite_Status_Screen::sync_cmd() { - ST7920_SET_CMD(); -} - -void ST7920_Lite_Status_Screen::sync_dat() { - ST7920_SET_DAT(); -} - -void ST7920_Lite_Status_Screen::write_byte(const uint8_t data) { - ST7920_WRITE_BYTE(data); -} diff --git a/Marlin/src/lcd/dogm/ultralcd_impl_DOGM.cpp b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp similarity index 99% rename from Marlin/src/lcd/dogm/ultralcd_impl_DOGM.cpp rename to Marlin/src/lcd/dogm/ultralcd_DOGM.cpp index 4d0b94b9d7..80e53fd137 100644 --- a/Marlin/src/lcd/dogm/ultralcd_impl_DOGM.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.cpp @@ -39,14 +39,13 @@ #if HAS_GRAPHICAL_LCD -#include "../ultralcd.h" - -#include -#include "HAL_LCD_class_defines.h" +#include "ultralcd_DOGM.h" #include "u8g_fontutf8.h" +#include "dogm_Bootscreen.h" + #include "../lcdprint.h" #include "../fontutils.h" -#include "dogm_Bootscreen.h" +#include "../ultralcd.h" #include "../../sd/cardreader.h" #include "../../module/temperature.h" @@ -177,7 +176,7 @@ void MarlinUI::set_font(const MarlinFont font_nr) { #endif // SHOW_BOOTSCREEN #if ENABLED(LIGHTWEIGHT_UI) - #include "status_screen_lite_ST7920_class.h" + #include "status_screen_lite_ST7920.h" #endif // Initialize or re-initialize the LCD diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h new file mode 100644 index 0000000000..ca55546b9f --- /dev/null +++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h @@ -0,0 +1,174 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * ultralcd_impl_DOGM.h + */ + +#include "../../inc/MarlinConfigPre.h" + +#include +#include "HAL_LCD_class_defines.h" + +// LCD selection +#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + #define U8G_CLASS U8GLIB_ST7920_128X64_4X + #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) + #define U8G_PARAM LCD_PINS_RS + #else + #define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS + #endif + +#elif ENABLED(U8GLIB_ST7920) + // RepRap Discount Full Graphics Smart Controller + #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) + #define U8G_CLASS U8GLIB_ST7920_128X64_4X_HAL + #define U8G_PARAM LCD_PINS_RS // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter) + #else + //#define U8G_CLASS U8GLIB_ST7920_128X64_4X + //#define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS // Original u8glib device. 2 stripes, SW SPI + #define U8G_CLASS U8GLIB_ST7920_128X64_RRD + #define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT + // AVR version ignores these pin settings + // HAL version uses these pin settings + #endif + +#elif ENABLED(CARTESIO_UI) + // The CartesioUI display + //#define U8G_CLASS U8GLIB_DOGM128_2X + //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes + #define U8G_CLASS U8GLIB_DOGM128_2X + #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes + +#elif ENABLED(U8GLIB_LM6059_AF) + // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) + //#define U8G_CLASS U8GLIB_LM6059 + //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 8 stripes + #define U8G_CLASS U8GLIB_LM6059_2X + #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes + +#elif ENABLED(U8GLIB_ST7565_64128N) + // The MaKrPanel, Mini Viki, Viki 2.0 & AZSMZ 12864 ST7565 controller + #define SMART_RAMPS (MB(RAMPS_SMART_EFB) || MB(RAMPS_SMART_EEB) || MB(RAMPS_SMART_EFF) || MB(RAMPS_SMART_EEF) || MB(RAMPS_SMART_SF)) + #if DOGLCD_SCK == SCK_PIN && DOGLCD_MOSI == MOSI_PIN && !SMART_RAMPS + #define U8G_CLASS U8GLIB_64128N_2X_HAL + #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // using HW-SPI + #else + #define U8G_CLASS U8GLIB_64128N_2X_HAL + #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // using SW-SPI + #endif + +#elif ENABLED(MKS_12864OLED_SSD1306) + // MKS 128x64 (SSD1306) OLED I2C LCD + #define U8G_CLASS U8GLIB_SSD1306_128X64 + #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 8 stripes + //#define U8G_CLASS U8GLIB_SSD1306_128X64_2X + //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes + +#elif ENABLED(U8GLIB_SSD1306) + // Generic support for SSD1306 OLED I2C LCDs + //#define U8G_CLASS U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE + //#define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes + #define U8G_CLASS U8GLIB_SSD1306_128X64_2X + #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes + +#elif ENABLED(MKS_12864OLED) + // MKS 128x64 (SH1106) OLED I2C LCD + #define U8G_CLASS U8GLIB_SH1106_128X64 + #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 8 stripes + //#define U8G_CLASS U8GLIB_SH1106_128X64_2X + //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes +#elif ENABLED(U8GLIB_SH1106) + // Generic support for SH1106 OLED I2C LCDs + //#define U8G_CLASS U8GLIB_SH1106_128X64_2X_I2C_2_WIRE + //#define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes + #define U8G_CLASS U8GLIB_SH1106_128X64_2X + #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes +#elif ENABLED(U8GLIB_SSD1309) + // Generic support for SSD1309 OLED I2C LCDs + #define U8G_CLASS U8GLIB_SSD1309_128X64 + #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) +#elif ENABLED(MINIPANEL) + // The MINIPanel display + //#define U8G_CLASS U8GLIB_MINI12864 + //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 8 stripes + #define U8G_CLASS U8GLIB_MINI12864_2X + #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes +#elif ENABLED(U8GLIB_SH1106_EINSTART) + // Connected via motherboard header + #define U8G_CLASS U8GLIB_SH1106_128X64 + #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS +#else + // for regular DOGM128 display with HW-SPI + //#define U8G_CLASS U8GLIB_DOGM128 + //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // HW-SPI Com: CS, A0 // 8 stripes + #define U8G_CLASS U8GLIB_DOGM128_2X + #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // HW-SPI Com: CS, A0 // 4 stripes +#endif + +#ifndef LCD_PIXEL_WIDTH + #define LCD_PIXEL_WIDTH 128 +#endif +#ifndef LCD_PIXEL_HEIGHT + #define LCD_PIXEL_HEIGHT 64 +#endif + +// For selective rendering within a Y range +#define PAGE_UNDER(yb) (u8g.getU8g()->current_page.y0 <= (yb)) +#define PAGE_CONTAINS(ya, yb) (PAGE_UNDER(yb) && u8g.getU8g()->current_page.y1 >= (ya)) + +// Only Western languages support big / small fonts +#if DISABLED(DISPLAY_CHARSET_ISO10646_1) + #undef USE_BIG_EDIT_FONT + #undef USE_SMALL_INFOFONT +#endif + +#define MENU_FONT_NAME ISO10646_1_5x7 +#define MENU_FONT_WIDTH 6 +#define MENU_FONT_ASCENT 10 +#define MENU_FONT_DESCENT 2 +#define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) + +#if ENABLED(USE_BIG_EDIT_FONT) + #define EDIT_FONT_NAME u8g_font_9x18 + #define EDIT_FONT_WIDTH 9 + #define EDIT_FONT_ASCENT 10 + #define EDIT_FONT_DESCENT 3 +#else + #define EDIT_FONT_NAME MENU_FONT_NAME + #define EDIT_FONT_WIDTH MENU_FONT_WIDTH + #define EDIT_FONT_ASCENT MENU_FONT_ASCENT + #define EDIT_FONT_DESCENT MENU_FONT_DESCENT +#endif +#define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) + +// Get the Ascent, Descent, and total Height for the Info Screen font +#if ENABLED(USE_SMALL_INFOFONT) + extern const u8g_fntpgm_uint8_t u8g_font_6x9[]; + #define INFO_FONT_ASCENT 7 +#else + #define INFO_FONT_ASCENT 8 +#endif +#define INFO_FONT_DESCENT 2 +#define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) + +extern U8G_CLASS u8g; diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp index 039a049085..c3d1942a59 100644 --- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp +++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp @@ -27,60 +27,7 @@ #if ENABLED(U8GLIB_ST7920) && !defined(U8G_HAL_LINKS) && !defined(__SAM3X8E__) -#include "../../HAL/shared/Delay.h" - -#define ST7920_CLK_PIN LCD_PINS_D4 -#define ST7920_DAT_PIN LCD_PINS_ENABLE -#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 LCD_PIXEL_WIDTH 128 -#define LCD_PIXEL_HEIGHT 64 - -#include - -//set optimization so ARDUINO optimizes this file -#pragma GCC optimize (3) - -// If you want you can define your own set of delays in Configuration.h -//#define ST7920_DELAY_1 DELAY_NS(0) -//#define ST7920_DELAY_2 DELAY_NS(0) -//#define ST7920_DELAY_3 DELAY_NS(0) - -#if F_CPU >= 20000000 - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(0) - #define CPU_ST7920_DELAY_3 DELAY_NS(50) -#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(188) - #define CPU_ST7920_DELAY_3 DELAY_NS(0) -#elif MB(MINIRAMBO) || MB(EINSY_RAMBO) || MB(EINSY_RETRO) - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(250) - #define CPU_ST7920_DELAY_3 DELAY_NS(0) -#elif MB(RAMBO) - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(0) - #define CPU_ST7920_DELAY_3 DELAY_NS(0) -#elif MB(BQ_ZUM_MEGA_3D) - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(0) - #define CPU_ST7920_DELAY_3 DELAY_NS(189) -#elif defined(ARDUINO_ARCH_STM32) - #define CPU_ST7920_DELAY_1 DELAY_NS(300) - #define CPU_ST7920_DELAY_2 DELAY_NS(40) - #define CPU_ST7920_DELAY_3 DELAY_NS(340) -#elif F_CPU == 16000000 - #define CPU_ST7920_DELAY_1 DELAY_NS(0) - #define CPU_ST7920_DELAY_2 DELAY_NS(0) - #define CPU_ST7920_DELAY_3 DELAY_NS(63) -#else - #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd_AVR.h'" -#endif +#include "ultralcd_st7920_u8glib_rrd_AVR.h" #ifndef ST7920_DELAY_1 #define ST7920_DELAY_1 CPU_ST7920_DELAY_1 @@ -92,13 +39,19 @@ #define ST7920_DELAY_3 CPU_ST7920_DELAY_3 #endif +// Optimize this code with -O3 +#pragma GCC optimize (3) + #define ST7920_SND_BIT \ WRITE(ST7920_CLK_PIN, LOW); ST7920_DELAY_1; \ WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_DELAY_2; \ WRITE(ST7920_CLK_PIN, HIGH); ST7920_DELAY_3; \ val <<= 1 -static void ST7920_SWSPI_SND_8BIT(uint8_t val) { +// Optimize this code with -O3 +#pragma GCC optimize (3) + +void ST7920_SWSPI_SND_8BIT(uint8_t val) { ST7920_SND_BIT; // 1 ST7920_SND_BIT; // 2 ST7920_SND_BIT; // 3 @@ -109,19 +62,6 @@ static void ST7920_SWSPI_SND_8BIT(uint8_t val) { ST7920_SND_BIT; // 8 } -#if DOGM_SPI_DELAY_US > 0 - #define U8G_DELAY() DELAY_US(DOGM_SPI_DELAY_US) -#else - #define U8G_DELAY() DELAY_US(10) -#endif - -#define ST7920_CS() { WRITE(ST7920_CS_PIN,1); U8G_DELAY(); } -#define ST7920_NCS() { WRITE(ST7920_CS_PIN,0); } -#define ST7920_SET_CMD() { ST7920_SWSPI_SND_8BIT(0xF8); U8G_DELAY(); } -#define ST7920_SET_DAT() { ST7920_SWSPI_SND_8BIT(0xFA); U8G_DELAY(); } -#define ST7920_WRITE_BYTE(a) { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u)); U8G_DELAY(); } -#define ST7920_WRITE_BYTES(p,l) { for (uint8_t i = l + 1; --i;) { ST7920_SWSPI_SND_8BIT(*p&0xF0); ST7920_SWSPI_SND_8BIT(*p<<4); p++; } U8G_DELAY(); } - uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { uint8_t i, y; switch (msg) { @@ -192,12 +132,6 @@ uint8_t u8g_dev_st7920_128x64_rrd_buf[(LCD_PIXEL_WIDTH) * (PAGE_HEIGHT) / 8] U u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_rrd_buf}; u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn, &u8g_dev_st7920_128x64_rrd_pb, &u8g_com_null_fn}; -#if ENABLED(LIGHTWEIGHT_UI) - // We have to include the code for the lightweight UI here - // as it relies on macros that are only defined in this file. - #include "status_screen_lite_ST7920_spi.h" -#endif - #pragma GCC reset_options #endif // U8GLIB_ST7920 && !U8G_HAL_LINKS && !__SAM3X8E__ diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h new file mode 100644 index 0000000000..4e601b6179 --- /dev/null +++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.h @@ -0,0 +1,97 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// NOTE - the HAL version of the rrd device uses a generic ST7920 device. See the +// file u8g_dev_st7920_128x64_HAL.cpp for the HAL version. + +#include "../../inc/MarlinConfig.h" + +#if ENABLED(U8GLIB_ST7920) && !defined(U8G_HAL_LINKS) && !defined(__SAM3X8E__) + +#include "../../HAL/shared/Delay.h" + +#define ST7920_CLK_PIN LCD_PINS_D4 +#define ST7920_DAT_PIN LCD_PINS_ENABLE +#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 LCD_PIXEL_WIDTH 128 +#define LCD_PIXEL_HEIGHT 64 + +#include + +// If you want you can define your own set of delays in Configuration.h +//#define ST7920_DELAY_1 DELAY_NS(0) +//#define ST7920_DELAY_2 DELAY_NS(0) +//#define ST7920_DELAY_3 DELAY_NS(0) + +#if F_CPU >= 20000000 + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(0) + #define CPU_ST7920_DELAY_3 DELAY_NS(50) +#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(188) + #define CPU_ST7920_DELAY_3 DELAY_NS(0) +#elif MB(MINIRAMBO) || MB(EINSY_RAMBO) || MB(EINSY_RETRO) + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(250) + #define CPU_ST7920_DELAY_3 DELAY_NS(0) +#elif MB(RAMBO) + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(0) + #define CPU_ST7920_DELAY_3 DELAY_NS(0) +#elif MB(BQ_ZUM_MEGA_3D) + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(0) + #define CPU_ST7920_DELAY_3 DELAY_NS(189) +#elif defined(ARDUINO_ARCH_STM32) + #define CPU_ST7920_DELAY_1 DELAY_NS(300) + #define CPU_ST7920_DELAY_2 DELAY_NS(40) + #define CPU_ST7920_DELAY_3 DELAY_NS(340) +#elif F_CPU == 16000000 + #define CPU_ST7920_DELAY_1 DELAY_NS(0) + #define CPU_ST7920_DELAY_2 DELAY_NS(0) + #define CPU_ST7920_DELAY_3 DELAY_NS(63) +#else + #error "No valid condition for delays in 'ultralcd_st7920_u8glib_rrd_AVR.h'" +#endif + +void ST7920_SWSPI_SND_8BIT(uint8_t val); + +#if DOGM_SPI_DELAY_US > 0 + #define U8G_DELAY() DELAY_US(DOGM_SPI_DELAY_US) +#else + #define U8G_DELAY() DELAY_US(10) +#endif + +#define ST7920_CS() { WRITE(ST7920_CS_PIN,1); U8G_DELAY(); } +#define ST7920_NCS() { WRITE(ST7920_CS_PIN,0); } +#define ST7920_SET_CMD() { ST7920_SWSPI_SND_8BIT(0xF8); U8G_DELAY(); } +#define ST7920_SET_DAT() { ST7920_SWSPI_SND_8BIT(0xFA); U8G_DELAY(); } +#define ST7920_WRITE_BYTE(a) { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u)); U8G_DELAY(); } +#define ST7920_WRITE_BYTES(p,l) { for (uint8_t i = l + 1; --i;) { ST7920_SWSPI_SND_8BIT(*p&0xF0); ST7920_SWSPI_SND_8BIT(*p<<4); p++; } U8G_DELAY(); } + +#endif // U8GLIB_ST7920 && !U8G_HAL_LINKS && !__SAM3X8E__ diff --git a/Marlin/src/lcd/extensible_ui/ui_api.cpp b/Marlin/src/lcd/extensible_ui/ui_api.cpp index 343910e13b..8d045a2a71 100644 --- a/Marlin/src/lcd/extensible_ui/ui_api.cpp +++ b/Marlin/src/lcd/extensible_ui/ui_api.cpp @@ -45,6 +45,7 @@ #if ENABLED(EXTENSIBLE_UI) +#include "../ultralcd.h" #include "../../gcode/queue.h" #include "../../module/motion.h" #include "../../module/planner.h" @@ -712,32 +713,9 @@ void MarlinUI::update() { UI::onIdle(); } -bool MarlinUI::hasstatus() { return true; } -bool MarlinUI::detected() { return true; } -void MarlinUI::reset_alert_level() { } -void MarlinUI::refresh() { } -void MarlinUI::setstatus(const char * const message, const bool persist /* = false */) { UI::onStatusChanged(message); } -void MarlinUI::setstatusPGM(const char * const message, int8_t level /* = 0 */) { UI::onStatusChanged((progmem_str)message); } -void MarlinUI::setalertstatusPGM(const char * const message) { setstatusPGM(message, 0); } - -void MarlinUI::reset_status() { - static const char paused[] PROGMEM = MSG_PRINT_PAUSED; - static const char printing[] PROGMEM = MSG_PRINTING; - static const char welcome[] PROGMEM = WELCOME_MSG; - PGM_P msg; - if (print_job_timer.isPaused()) - msg = paused; - #if ENABLED(SDSUPPORT) - else if (IS_SD_PRINTING()) - return setstatus(card.longest_filename(), true); - #endif - else if (print_job_timer.isRunning()) - msg = printing; - else - msg = welcome; - - setstatusPGM(msg, -1); -} +void MarlinUI::setstatus(const char * const message, const bool persist/*=false*/) { UI::onStatusChanged(message); } +void MarlinUI::setstatusPGM(PGM_P const message, int8_t level/*=0*/) { UI::onStatusChanged((progmem_str)message); } +void MarlinUI::setalertstatusPGM(PGM_P const message) { setstatusPGM(message, 0); } void MarlinUI::status_printf_P(const uint8_t level, const char * const fmt, ...) { char buff[64]; diff --git a/Marlin/src/lcd/malyanlcd.cpp b/Marlin/src/lcd/malyanlcd.cpp index efc46f42e2..3e57cb1b3d 100644 --- a/Marlin/src/lcd/malyanlcd.cpp +++ b/Marlin/src/lcd/malyanlcd.cpp @@ -45,6 +45,7 @@ #if ENABLED(MALYAN_LCD) +#include "ultralcd.h" #include "../module/temperature.h" #include "../module/planner.h" #include "../module/stepper.h" @@ -479,10 +480,10 @@ void MarlinUI::init() { /** * Set an alert. */ -void MarlinUI::setalertstatusPGM(PGM_P message) { - char message_buffer[MAX_CURLY_COMMAND]; - sprintf_P(message_buffer, PSTR("{E:%s}"), message); - write_to_lcd(message_buffer); +void MarlinUI::setalertstatusPGM(PGM_P const message) { + write_to_lcd_P(PSTR("{E:")); + write_to_lcd_P(message); + write_to_lcd_P("}"); } #endif // MALYAN_LCD diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index 5b639e18e9..74b2e93690 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -22,48 +22,35 @@ #include "../inc/MarlinConfigPre.h" -#if HAS_SPI_LCD - -#include +// These displays all share the MarlinUI class +#if HAS_SPI_LCD || ENABLED(MALYAN_LCD) || ENABLED(EXTENSIBLE_UI) + #include "ultralcd.h" + MarlinUI ui; +#endif -#include "ultralcd.h" +#if HAS_SPI_LCD -MarlinUI ui; +#if HAS_GRAPHICAL_LCD + #include "dogm/ultralcd_DOGM.h" +#endif #include "lcdprint.h" #include "../sd/cardreader.h" #include "../module/temperature.h" #include "../module/planner.h" -#include "../module/stepper.h" -#include "../module/motion.h" -#include "../module/probe.h" #include "../module/printcounter.h" -#include "../gcode/gcode.h" +#include "../module/motion.h" #include "../gcode/queue.h" -#include "../module/configuration_store.h" -#include "../module/tool_change.h" #include "../Marlin.h" -#if ENABLED(ADVANCED_PAUSE_FEATURE) - #include "../feature/pause.h" -#endif - #if ENABLED(POWER_LOSS_RECOVERY) - #include "../feature/power_loss_recovery.h" -#endif - -#if ENABLED(PRINTCOUNTER) && ENABLED(LCD_INFO_MENU) - #include "../libs/duration_t.h" -#endif - -#if ENABLED(BLTOUCH) - #include "../module/endstops.h" + #include "../feature/power_loss_recovery.h" #endif -#if HAS_LEVELING - #include "../feature/bedlevel/bedlevel.h" +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../feature/bedlevel/bedlevel.h" #endif #if DISABLED(LCD_USE_I2C_BUZZER) @@ -454,28 +441,6 @@ void MarlinUI::status_screen() { draw_status_screen(); } -/** - * Reset the status message - */ -void MarlinUI::reset_status() { - static const char paused[] PROGMEM = MSG_PRINT_PAUSED; - static const char printing[] PROGMEM = MSG_PRINTING; - static const char welcome[] PROGMEM = WELCOME_MSG; - PGM_P msg; - if (print_job_timer.isPaused()) - msg = paused; - #if ENABLED(SDSUPPORT) - else if (IS_SD_PRINTING()) - return setstatus(card.longest_filename(), true); - #endif - else if (print_job_timer.isRunning()) - msg = printing; - else - msg = welcome; - - setstatusPGM(msg, -1); -} - void MarlinUI::kill_screen(PGM_P lcd_msg) { init(); setalertstatusPGM(lcd_msg); @@ -507,6 +472,10 @@ void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) { #endif } +//////////////////////////////////////////// +/////////////// Manual Move //////////////// +//////////////////////////////////////////// + #if HAS_LCD_MENU extern bool no_reentry; // Flag to prevent recursion into menu handlers @@ -891,101 +860,6 @@ void MarlinUI::update() { } // ELAPSED(ms, next_lcd_update_ms) } -void MarlinUI::finishstatus(const bool persist) { - - #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) - UNUSED(persist); - #endif - - #if ENABLED(LCD_PROGRESS_BAR) - progress_bar_ms = millis(); - #if PROGRESS_MSG_EXPIRE > 0 - expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; - #endif - #endif - - #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) - next_filament_display = millis() + 5000UL; // Show status message for 5s - #endif - - #if ENABLED(STATUS_MESSAGE_SCROLLING) - status_scroll_offset = 0; - #endif - - refresh(); -} - -bool MarlinUI::hasstatus() { return (status_message[0] != '\0'); } - -void MarlinUI::setstatus(const char * const message, const bool persist) { - if (status_message_level > 0) return; - - // Here we have a problem. The message is encoded in UTF8, so - // arbitrarily cutting it will be a problem. We MUST be sure - // that there is no cutting in the middle of a multibyte character! - - // Get a pointer to the null terminator - const char* pend = message + strlen(message); - - // If length of supplied UTF8 string is greater than - // our buffer size, start cutting whole UTF8 chars - while ((pend - message) > MAX_MESSAGE_LENGTH) { - --pend; - while (!START_OF_UTF8_CHAR(*pend)) --pend; - }; - - // At this point, we have the proper cut point. Use it - uint8_t maxLen = pend - message; - strncpy(status_message, message, maxLen); - status_message[maxLen] = '\0'; - - finishstatus(persist); -} - -void MarlinUI::setstatusPGM(PGM_P const message, int8_t level) { - if (level < 0) level = status_message_level = 0; - if (level < status_message_level) return; - status_message_level = level; - - // Here we have a problem. The message is encoded in UTF8, so - // arbitrarily cutting it will be a problem. We MUST be sure - // that there is no cutting in the middle of a multibyte character! - - // Get a pointer to the null terminator - PGM_P pend = message + strlen_P(message); - - // If length of supplied UTF8 string is greater than - // our buffer size, start cutting whole UTF8 chars - while ((pend - message) > MAX_MESSAGE_LENGTH) { - --pend; - while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend; - }; - - // At this point, we have the proper cut point. Use it - uint8_t maxLen = pend - message; - strncpy_P(status_message, message, maxLen); - status_message[maxLen] = '\0'; - - finishstatus(level > 0); -} - -void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) { - if (level < status_message_level) return; - status_message_level = level; - va_list args; - va_start(args, fmt); - vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args); - va_end(args); - finishstatus(level > 0); -} - -void MarlinUI::setalertstatusPGM(PGM_P const message) { - setstatusPGM(message, 1); - #if HAS_LCD_MENU - return_to_status(); - #endif -} - #if ENABLED(ADC_KEYPAD) typedef struct { @@ -1185,4 +1059,133 @@ void MarlinUI::setalertstatusPGM(PGM_P const message) { #endif // HAS_ENCODER_ACTION +//////////////////////////////////////////// +/////////////// Status Line //////////////// +//////////////////////////////////////////// + +void MarlinUI::finishstatus(const bool persist) { + + #if !(ENABLED(LCD_PROGRESS_BAR) && (PROGRESS_MSG_EXPIRE > 0)) + UNUSED(persist); + #endif + + #if ENABLED(LCD_PROGRESS_BAR) + progress_bar_ms = millis(); + #if PROGRESS_MSG_EXPIRE > 0 + expire_status_ms = persist ? 0 : progress_bar_ms + PROGRESS_MSG_EXPIRE; + #endif + #endif + + #if ENABLED(FILAMENT_LCD_DISPLAY) && ENABLED(SDSUPPORT) + next_filament_display = millis() + 5000UL; // Show status message for 5s + #endif + + #if ENABLED(STATUS_MESSAGE_SCROLLING) + status_scroll_offset = 0; + #endif + + refresh(); +} + +bool MarlinUI::hasstatus() { return (status_message[0] != '\0'); } + +void MarlinUI::setstatus(const char * const message, const bool persist) { + if (status_message_level > 0) return; + + // Here we have a problem. The message is encoded in UTF8, so + // arbitrarily cutting it will be a problem. We MUST be sure + // that there is no cutting in the middle of a multibyte character! + + // Get a pointer to the null terminator + const char* pend = message + strlen(message); + + // If length of supplied UTF8 string is greater than + // our buffer size, start cutting whole UTF8 chars + while ((pend - message) > MAX_MESSAGE_LENGTH) { + --pend; + while (!START_OF_UTF8_CHAR(*pend)) --pend; + }; + + // At this point, we have the proper cut point. Use it + uint8_t maxLen = pend - message; + strncpy(status_message, message, maxLen); + status_message[maxLen] = '\0'; + + finishstatus(persist); +} + +#include + +void MarlinUI::status_printf_P(const uint8_t level, PGM_P const fmt, ...) { + if (level < status_message_level) return; + status_message_level = level; + va_list args; + va_start(args, fmt); + vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args); + va_end(args); + finishstatus(level > 0); +} + +void MarlinUI::setstatusPGM(PGM_P const message, int8_t level) { + if (level < 0) level = status_message_level = 0; + if (level < status_message_level) return; + status_message_level = level; + + // Here we have a problem. The message is encoded in UTF8, so + // arbitrarily cutting it will be a problem. We MUST be sure + // that there is no cutting in the middle of a multibyte character! + + // Get a pointer to the null terminator + PGM_P pend = message + strlen_P(message); + + // If length of supplied UTF8 string is greater than + // our buffer size, start cutting whole UTF8 chars + while ((pend - message) > MAX_MESSAGE_LENGTH) { + --pend; + while (!START_OF_UTF8_CHAR(pgm_read_byte(pend))) --pend; + }; + + // At this point, we have the proper cut point. Use it + uint8_t maxLen = pend - message; + strncpy_P(status_message, message, maxLen); + status_message[maxLen] = '\0'; + + finishstatus(level > 0); +} + +void MarlinUI::setalertstatusPGM(PGM_P const message) { + setstatusPGM(message, 1); + #if HAS_LCD_MENU + return_to_status(); + #endif +} + #endif // HAS_SPI_LCD + +#if HAS_SPI_LCD || ENABLED(EXTENSIBLE_UI) + + #include "../module/printcounter.h" + + /** + * Reset the status message + */ + void MarlinUI::reset_status() { + static const char paused[] PROGMEM = MSG_PRINT_PAUSED; + static const char printing[] PROGMEM = MSG_PRINTING; + static const char welcome[] PROGMEM = WELCOME_MSG; + PGM_P msg; + if (print_job_timer.isPaused()) + msg = paused; + #if ENABLED(SDSUPPORT) + else if (IS_SD_PRINTING()) + return setstatus(card.longest_filename(), true); + #endif + else if (print_job_timer.isRunning()) + msg = printing; + else + msg = welcome; + + setstatusPGM(msg, -1); + } + +#endif diff --git a/Marlin/src/lcd/ultralcd.h b/Marlin/src/lcd/ultralcd.h index b3a7038c95..7e1db1f807 100644 --- a/Marlin/src/lcd/ultralcd.h +++ b/Marlin/src/lcd/ultralcd.h @@ -38,166 +38,6 @@ #include "../libs/buzzer.h" #endif -#if HAS_GRAPHICAL_LCD - - #ifndef LCD_PIXEL_WIDTH - #define LCD_PIXEL_WIDTH 128 - #endif - #ifndef LCD_PIXEL_HEIGHT - #define LCD_PIXEL_HEIGHT 64 - #endif - - // LCD selection - #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - #define U8G_CLASS U8GLIB_ST7920_128X64_4X - #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) - #define U8G_PARAM LCD_PINS_RS - #else - #define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS - #endif - - #elif ENABLED(U8GLIB_ST7920) - // RepRap Discount Full Graphics Smart Controller - #if DISABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN) && (LCD_PINS_ENABLE == MOSI_PIN) - #define U8G_CLASS U8GLIB_ST7920_128X64_4X_HAL - #define U8G_PARAM LCD_PINS_RS // 2 stripes, HW SPI (shared with SD card, on AVR does not use standard LCD adapter) - #else - //#define U8G_CLASS U8GLIB_ST7920_128X64_4X - //#define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS // Original u8glib device. 2 stripes, SW SPI - #define U8G_CLASS U8GLIB_ST7920_128X64_RRD - #define U8G_PARAM LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT - // AVR version ignores these pin settings - // HAL version uses these pin settings - #endif - - #elif ENABLED(CARTESIO_UI) - // The CartesioUI display - //#define U8G_CLASS U8GLIB_DOGM128_2X - //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes - #define U8G_CLASS U8GLIB_DOGM128_2X - #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes - - #elif ENABLED(U8GLIB_LM6059_AF) - // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) - //#define U8G_CLASS U8GLIB_LM6059 - //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 8 stripes - #define U8G_CLASS U8GLIB_LM6059_2X - #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes - - #elif ENABLED(U8GLIB_ST7565_64128N) - // The MaKrPanel, Mini Viki, Viki 2.0 & AZSMZ 12864 ST7565 controller - #define SMART_RAMPS (MB(RAMPS_SMART_EFB) || MB(RAMPS_SMART_EEB) || MB(RAMPS_SMART_EFF) || MB(RAMPS_SMART_EEF) || MB(RAMPS_SMART_SF)) - #if DOGLCD_SCK == SCK_PIN && DOGLCD_MOSI == MOSI_PIN && !SMART_RAMPS - #define U8G_CLASS U8GLIB_64128N_2X_HAL - #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // using HW-SPI - #else - #define U8G_CLASS U8GLIB_64128N_2X_HAL - #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // using SW-SPI - #endif - - #elif ENABLED(MKS_12864OLED_SSD1306) - // MKS 128x64 (SSD1306) OLED I2C LCD - #define U8G_CLASS U8GLIB_SSD1306_128X64 - #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 8 stripes - //#define U8G_CLASS U8GLIB_SSD1306_128X64_2X - //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes - - #elif ENABLED(U8GLIB_SSD1306) - // Generic support for SSD1306 OLED I2C LCDs - //#define U8G_CLASS U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE - //#define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes - #define U8G_CLASS U8GLIB_SSD1306_128X64_2X - #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes - - #elif ENABLED(MKS_12864OLED) - // MKS 128x64 (SH1106) OLED I2C LCD - #define U8G_CLASS U8GLIB_SH1106_128X64 - #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 8 stripes - //#define U8G_CLASS U8GLIB_SH1106_128X64_2X - //#define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0 // 4 stripes - #elif ENABLED(U8GLIB_SH1106) - // Generic support for SH1106 OLED I2C LCDs - //#define U8G_CLASS U8GLIB_SH1106_128X64_2X_I2C_2_WIRE - //#define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes - #define U8G_CLASS U8GLIB_SH1106_128X64_2X - #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) // 4 stripes - #elif ENABLED(U8GLIB_SSD1309) - // Generic support for SSD1309 OLED I2C LCDs - #define U8G_CLASS U8GLIB_SSD1309_128X64 - #define U8G_PARAM (U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST) - #elif ENABLED(MINIPANEL) - // The MINIPanel display - //#define U8G_CLASS U8GLIB_MINI12864 - //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 8 stripes - #define U8G_CLASS U8GLIB_MINI12864_2X - #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // 4 stripes - #elif ENABLED(U8GLIB_SH1106_EINSTART) - // Connected via motherboard header - #define U8G_CLASS U8GLIB_SH1106_128X64 - #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, LCD_PINS_DC, LCD_PINS_RS - #else - // for regular DOGM128 display with HW-SPI - //#define U8G_CLASS U8GLIB_DOGM128 - //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // HW-SPI Com: CS, A0 // 8 stripes - #define U8G_CLASS U8GLIB_DOGM128_2X - #define U8G_PARAM DOGLCD_CS, DOGLCD_A0 // HW-SPI Com: CS, A0 // 4 stripes - #endif - - #include - #include "dogm/HAL_LCD_class_defines.h" - extern U8G_CLASS u8g; - - // For selective rendering within a Y range - #define PAGE_UNDER(yb) (u8g.getU8g()->current_page.y0 <= (yb)) - #define PAGE_CONTAINS(ya, yb) (PAGE_UNDER(yb) && u8g.getU8g()->current_page.y1 >= (ya)) - - // Only Western languages support big / small fonts - #if DISABLED(DISPLAY_CHARSET_ISO10646_1) - #undef USE_BIG_EDIT_FONT - #undef USE_SMALL_INFOFONT - #endif - - #define MENU_FONT_NAME ISO10646_1_5x7 - #define MENU_FONT_WIDTH 6 - #define MENU_FONT_ASCENT 10 - #define MENU_FONT_DESCENT 2 - #define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) - - #if ENABLED(USE_BIG_EDIT_FONT) - #define EDIT_FONT_NAME u8g_font_9x18 - #define EDIT_FONT_WIDTH 9 - #define EDIT_FONT_ASCENT 10 - #define EDIT_FONT_DESCENT 3 - #else - #define EDIT_FONT_NAME MENU_FONT_NAME - #define EDIT_FONT_WIDTH MENU_FONT_WIDTH - #define EDIT_FONT_ASCENT MENU_FONT_ASCENT - #define EDIT_FONT_DESCENT MENU_FONT_DESCENT - #endif - #define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) - - // Get the Ascent, Descent, and total Height for the Info Screen font - #if ENABLED(USE_SMALL_INFOFONT) - extern const u8g_fntpgm_uint8_t u8g_font_6x9[]; - #define INFO_FONT_ASCENT 7 - #else - #define INFO_FONT_ASCENT 8 - #endif - #define INFO_FONT_DESCENT 2 - #define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) - - enum MarlinFont : uint8_t { - FONT_STATUSMENU = 1, - FONT_EDIT, - FONT_MENU - }; - - #if ENABLED(LIGHTWEIGHT_UI) - void lcd_in_status(const bool inStatus); - #endif - -#endif // HAS_GRAPHICAL_LCD - #define HAS_ENCODER_ACTION (HAS_LCD_MENU || ENABLED(ULTIPANEL_FEEDMULTIPLY)) #if HAS_SPI_LCD @@ -364,6 +204,14 @@ #endif #endif +#if HAS_GRAPHICAL_LCD + enum MarlinFont : uint8_t { + FONT_STATUSMENU = 1, + FONT_EDIT, + FONT_MENU + }; +#endif + #define LCD_MESSAGEPGM(x) ui.setstatusPGM(PSTR(x)) #define LCD_ALERTMESSAGEPGM(x) ui.setalertstatusPGM(PSTR(x)) @@ -397,12 +245,10 @@ public: #if HAS_SPI_LCD || ENABLED(MALYAN_LCD) || ENABLED(EXTENSIBLE_UI) static void init(); static void update(); - static bool detected(); static void setalertstatusPGM(PGM_P message); #else // NO LCD static inline void init() {} static inline void update() {} - static constexpr bool detected() { return true; } static inline void setalertstatusPGM(PGM_P message) { UNUSED(message); } #endif @@ -410,6 +256,8 @@ public: #if HAS_SPI_LCD + static bool detected(); + static LCDViewAction lcdDrawUpdate; static inline bool should_draw() { return bool(lcdDrawUpdate); } static inline void refresh(const LCDViewAction type) { lcdDrawUpdate = type; } @@ -455,6 +303,7 @@ public: #if ENABLED(STATUS_MESSAGE_SCROLLING) static uint8_t status_scroll_offset; #endif + static bool hasstatus(); static uint8_t lcd_status_update_delay; static uint8_t status_message_level; // Higher levels block lower levels @@ -495,15 +344,15 @@ public: #else - static void refresh(); - static void reset_alert_level(); + static void refresh() {} + static inline void reset_alert_level() {} + static constexpr bool hasstatus() { return true; } #endif static bool get_blink(); static void kill_screen(PGM_P const lcd_msg); static void draw_kill_screen(); - static bool hasstatus(); static void setstatus(const char* const message, const bool persist=false); static void setstatusPGM(PGM_P const message, const int8_t level=0); static void status_printf_P(const uint8_t level, PGM_P const fmt, ...); @@ -512,12 +361,12 @@ public: #else // MALYAN_LCD or NO LCD static inline void refresh() {} - static constexpr bool hasstatus() { return false; } static inline void setstatus(const char* const message, const bool persist=false) { UNUSED(message); UNUSED(persist); } static inline void setstatusPGM(PGM_P const message, const int8_t level=0) { UNUSED(message); UNUSED(level); } static inline void status_printf_P(const uint8_t level, PGM_P const fmt, ...) { UNUSED(level); UNUSED(fmt); } static inline void reset_status() {} static inline void reset_alert_level() {} + static constexpr bool hasstatus() { return false; } #endif @@ -563,6 +412,10 @@ public: static inline bool on_status_screen() { return currentScreen == status_screen; } static inline void run_current_screen() { (*currentScreen)(); } + #if ENABLED(LIGHTWEIGHT_UI) + static void lcd_in_status(const bool inStatus); + #endif + static inline void defer_status_screen(const bool defer) { #if LCD_TIMEOUT_TO_STATUS defer_return_to_status = defer; @@ -636,13 +489,13 @@ public: static inline void encoder_direction_menus() { encoderDirection = -(ENCODERBASE); } #else static constexpr int8_t encoderDirection = ENCODERBASE; - static inline void encoder_direction_normal() { } - static inline void encoder_direction_menus() { } + static inline void encoder_direction_normal() {} + static inline void encoder_direction_menus() {} #endif #else - static inline void update_buttons() { } + static inline void update_buttons() {} #endif @@ -660,6 +513,8 @@ private: #endif static void draw_status_screen(); static void finishstatus(const bool persist); + #else + static inline void finishstatus(const bool persist) { UNUSED(persist); refresh(); } #endif };