From c05c06bb5a53d7871e245f73c7e1d3ec657000ca Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 19 Sep 2020 07:44:06 -0500 Subject: [PATCH 1/4] Start on MarlinUI for Creality DWIN --- Marlin/Configuration.h | 6 + Marlin/src/MarlinCore.cpp | 7 +- Marlin/src/inc/Conditionals_LCD.h | 3 + Marlin/src/inc/Conditionals_post.h | 4 + Marlin/src/inc/SanityCheck.h | 1 + Marlin/src/lcd/dwin/dwin_lcd.cpp | 14 +- Marlin/src/lcd/dwin/dwin_lcd.h | 152 ++- Marlin/src/lcd/dwin/e3v2/dwin.cpp | 40 +- Marlin/src/lcd/dwin/e3v2/dwin.h | 134 -- Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp | 2 +- Marlin/src/lcd/dwin/e3v2/rotary_encoder.h | 2 +- Marlin/src/lcd/dwin/marlin/lcdprint_dwin.cpp | 1145 ++++++++++++++++++ Marlin/src/lcd/dwin/marlin/ultralcd_dwin.cpp | 879 ++++++++++++++ Marlin/src/lcd/dwin/marlin/ultralcd_dwin.h | 100 ++ Marlin/src/lcd/lcdprint.h | 12 + Marlin/src/lcd/marlinui.cpp | 3 + Marlin/src/lcd/marlinui.h | 8 +- Marlin/src/pins/stm32f1/pins_CREALITY_V4.h | 2 +- platformio.ini | 7 +- 19 files changed, 2352 insertions(+), 169 deletions(-) create mode 100644 Marlin/src/lcd/dwin/marlin/lcdprint_dwin.cpp create mode 100644 Marlin/src/lcd/dwin/marlin/ultralcd_dwin.cpp create mode 100644 Marlin/src/lcd/dwin/marlin/ultralcd_dwin.h diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 5ec41c596bda..058fe770c60b 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -2320,6 +2320,12 @@ // //#define DWIN_CREALITY_LCD +// +// MarlinUI for Creality's DWIN display (and others) +// +//#define DWIN_MARLINUI_PORTRAIT +//#define DWIN_MARLINUI_LANDSCAPE + // // ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8 // diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp index e395bdccb8c4..daa5c8763822 100644 --- a/Marlin/src/MarlinCore.cpp +++ b/Marlin/src/MarlinCore.cpp @@ -73,7 +73,6 @@ #if ENABLED(DWIN_CREALITY_LCD) #include "lcd/dwin/e3v2/dwin.h" - #include "lcd/dwin/dwin_lcd.h" #include "lcd/dwin/e3v2/rotary_encoder.h" #endif @@ -1077,11 +1076,7 @@ void setup() { // (because EEPROM code calls the UI). #if ENABLED(DWIN_CREALITY_LCD) - delay(800); // Required delay (since boot?) - SERIAL_ECHOPGM("\nDWIN handshake "); - if (DWIN_Handshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error."); - DWIN_Frame_SetDir(1); // Orientation 90° - DWIN_UpdateLCD(); // Show bootscreen (first image) + SETUP_RUN(DWIN_Startup()); #else SETUP_RUN(ui.init()); #if HAS_WIRED_LCD && ENABLED(SHOW_BOOTSCREEN) diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h index 6f632aa569b6..0beb98023809 100644 --- a/Marlin/src/inc/Conditionals_LCD.h +++ b/Marlin/src/inc/Conditionals_LCD.h @@ -477,6 +477,9 @@ #define HAS_MARLINUI_U8GLIB 1 #elif IS_TFTGLCD_PANEL // Neither DOGM nor HD44780. Fully customized interface. + #elif IS_DWIN_MARLINUI + // Since HAS_MARLINUI_U8GLIB refers to U8G displays + // the DWIN display can define its own flags #elif DISABLED(HAS_GRAPHICAL_TFT) #define HAS_MARLINUI_HD44780 1 #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index bb717ba097ef..8327278491b7 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -2661,6 +2661,8 @@ #ifndef LCD_WIDTH #if HAS_MARLINUI_U8GLIB #define LCD_WIDTH 21 + #elif IS_DWIN_MARLINUI + // Defined by header #else #define LCD_WIDTH TERN(IS_ULTIPANEL, 20, 16) #endif @@ -2668,6 +2670,8 @@ #ifndef LCD_HEIGHT #if HAS_MARLINUI_U8GLIB #define LCD_HEIGHT 5 + #elif IS_DWIN_MARLINUI + // Defined by header #else #define LCD_HEIGHT TERN(IS_ULTIPANEL, 4, 2) #endif diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 657e055241cc..eddf867df084 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -2222,6 +2222,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal + COUNT_ENABLED(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON, ANYCUBIC_TFT35) \ + COUNT_ENABLED(DGUS_LCD_UI_ORIGIN, DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY) \ + COUNT_ENABLED(ENDER2_STOCKDISPLAY, CR10_STOCKDISPLAY, DWIN_CREALITY_LCD) \ + + COUNT_ENABLED(ULTRALCD_DWIN_PORTRAIT, ULTRALCD_DWIN_LANDSCAPE) \ + COUNT_ENABLED(FYSETC_MINI_12864_X_X, FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1, FYSETC_GENERIC_12864_1_1) \ + COUNT_ENABLED(LCD_SAINSMART_I2C_1602, LCD_SAINSMART_I2C_2004) \ + COUNT_ENABLED(MKS_12864OLED, MKS_12864OLED_SSD1306) \ diff --git a/Marlin/src/lcd/dwin/dwin_lcd.cpp b/Marlin/src/lcd/dwin/dwin_lcd.cpp index 7d1528bed19b..07ef1ee07680 100644 --- a/Marlin/src/lcd/dwin/dwin_lcd.cpp +++ b/Marlin/src/lcd/dwin/dwin_lcd.cpp @@ -30,7 +30,7 @@ #include "../../inc/MarlinConfigPre.h" -#if ENABLED(DWIN_CREALITY_LCD) +#if ANY(DWIN_CREALITY_LCD, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) #include "../../inc/MarlinConfig.h" @@ -115,6 +115,16 @@ bool DWIN_Handshake(void) { && databuf[3] == 'K' ); } +void DWIN_Startup(void) { + DEBUG_ECHOPGM("\r\nDWIN handshake "); + delay(750); // Delay here or init later in the boot process + const bool success = DWIN_Handshake(); + if (success) DEBUG_ECHOLNPGM("ok."); else DEBUG_ECHOLNPGM("error."); + DWIN_Frame_SetDir(DISABLED(DWIN_MARLINUI_LANDSCAPE) ? 1 : 0); + TERN(SHOW_BOOTSCREEN,,DWIN_Frame_Clear(Color_Bg_Black)); + DWIN_UpdateLCD(); +} + // Set the backlight luminance // luminance: (0x00-0xFF) void DWIN_Backlight_SetLuminance(const uint8_t luminance) { @@ -452,4 +462,4 @@ void DWIN_ICON_AnimationControl(uint16_t state) { // // Flash writing returns 0xA5 0x4F 0x4B -#endif // DWIN_CREALITY_LCD +#endif // DWIN_CREALITY_LCD || DWIN_MARLINUI_PORTRAIT || DWIN_MARLINUI_LANDSCAPE diff --git a/Marlin/src/lcd/dwin/dwin_lcd.h b/Marlin/src/lcd/dwin/dwin_lcd.h index 9ae6d076d502..0c4ba59679b3 100644 --- a/Marlin/src/lcd/dwin/dwin_lcd.h +++ b/Marlin/src/lcd/dwin/dwin_lcd.h @@ -39,8 +39,156 @@ #define DWIN_SCROLL_UP 2 #define DWIN_SCROLL_DOWN 3 -#define DWIN_WIDTH 272 -#define DWIN_HEIGHT 480 +#if DISABLED(DWIN_MARLINUI_LANDSCAPE) + #define DWIN_WIDTH 272 + #define DWIN_HEIGHT 480 +#else + #define DWIN_WIDTH 480 + #define DWIN_HEIGHT 272 +#endif + +// Character matrix width x height +//#define LCD_WIDTH ((DWIN_WIDTH) / 8) +//#define LCD_HEIGHT ((DWIN_HEIGHT) / 12) + +// Picture ID +#define DWIN_Boot_Screen 0 +#define Language_English 1 +#define Language_Chinese 2 + +// ICON ID +#define ICON 0x09 +#define ICON_LOGO 0 +#define ICON_Print_0 1 +#define ICON_Print_1 2 +#define ICON_Prepare_0 3 +#define ICON_Prepare_1 4 +#define ICON_Control_0 5 +#define ICON_Control_1 6 +#define ICON_Leveling_0 7 +#define ICON_Leveling_1 8 +#define ICON_HotendTemp 9 +#define ICON_BedTemp 10 +#define ICON_Speed 11 +#define ICON_Zoffset 12 +#define ICON_Back 13 +#define ICON_File 14 +#define ICON_PrintTime 15 +#define ICON_RemainTime 16 +#define ICON_Setup_0 17 +#define ICON_Setup_1 18 +#define ICON_Pause_0 19 +#define ICON_Pause_1 20 +#define ICON_Continue_0 21 +#define ICON_Continue_1 22 +#define ICON_Stop_0 23 +#define ICON_Stop_1 24 +#define ICON_Bar 25 +#define ICON_More 26 + +#define ICON_Axis 27 +#define ICON_CloseMotor 28 +#define ICON_Homing 29 +#define ICON_SetHome 30 +#define ICON_PLAPreheat 31 +#define ICON_ABSPreheat 32 +#define ICON_Cool 33 +#define ICON_Language 34 + +#define ICON_MoveX 35 +#define ICON_MoveY 36 +#define ICON_MoveZ 37 +#define ICON_Extruder 38 + +#define ICON_Temperature 40 +#define ICON_Motion 41 +#define ICON_WriteEEPROM 42 +#define ICON_ReadEEPROM 43 +#define ICON_ResumeEEPROM 44 +#define ICON_Info 45 + +#define ICON_SetEndTemp 46 +#define ICON_SetBedTemp 47 +#define ICON_FanSpeed 48 +#define ICON_SetPLAPreheat 49 +#define ICON_SetABSPreheat 50 + +#define ICON_MaxSpeed 51 +#define ICON_MaxAccelerated 52 +#define ICON_MaxJerk 53 +#define ICON_Step 54 +#define ICON_PrintSize 55 +#define ICON_Version 56 +#define ICON_Contact 57 +#define ICON_StockConfiguraton 58 +#define ICON_MaxSpeedX 59 +#define ICON_MaxSpeedY 60 +#define ICON_MaxSpeedZ 61 +#define ICON_MaxSpeedE 62 +#define ICON_MaxAccX 63 +#define ICON_MaxAccY 64 +#define ICON_MaxAccZ 65 +#define ICON_MaxAccE 66 +#define ICON_MaxSpeedJerkX 67 +#define ICON_MaxSpeedJerkY 68 +#define ICON_MaxSpeedJerkZ 69 +#define ICON_MaxSpeedJerkE 70 +#define ICON_StepX 71 +#define ICON_StepY 72 +#define ICON_StepZ 73 +#define ICON_StepE 74 +#define ICON_Setspeed 75 +#define ICON_SetZOffset 76 +#define ICON_Rectangle 77 +#define ICON_BLTouch 78 +#define ICON_TempTooLow 79 +#define ICON_AutoLeveling 80 +#define ICON_TempTooHigh 81 +#define ICON_NoTips_C 82 +#define ICON_NoTips_E 83 +#define ICON_Continue_C 84 +#define ICON_Continue_E 85 +#define ICON_Cancel_C 86 +#define ICON_Cancel_E 87 +#define ICON_Confirm_C 88 +#define ICON_Confirm_E 89 +#define ICON_Info_0 90 +#define ICON_Info_1 91 + +/** + * 3-.0:The font size, 0x00-0x09, corresponds to the font size below: + * 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28 + * 0x05=16*32 0x06=20*40 0x07=24*48 0x08=28*56 0x09=32*64 + */ +#define font6x12 0x00 +#define font8x16 0x01 +#define font10x20 0x02 +#define font12x24 0x03 +#define font14x28 0x04 +#define font16x32 0x05 +#define font20x40 0x06 +#define font24x48 0x07 +#define font28x56 0x08 +#define font32x64 0x09 + +#define DWIN_FONT_MENU font8x16 +#define DWIN_FONT_STAT font10x20 +#define DWIN_FONT_HEAD font10x20 +#define DWIN_FONT_ALERT font10x20 + +// Color +#define Color_White 0xFFFF +#define Color_Yellow 0xFF0F +#define Color_Bg_Red 0xF00F // Red background color +#define Color_Bg_Window 0x31E8 // Popup background color +#define Color_Bg_Blue 0x1125 // Dark blue background color +#define Color_Bg_Black 0x0841 // Black background color +#define Popup_Text_Color 0xD6BA // Popup font background color +#define Line_Color 0x3A6A // Split line color +#define Rectangle_Color 0xEE2F // Blue square cursor color +#define Percent_Color 0xFE29 // Percentage color +#define BarFill_Color 0x10E4 // Fill color of progress bar +#define Select_Color 0x33BB // Selected color /*-------------------------------------- System variable function --------------------------------------*/ diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.cpp b/Marlin/src/lcd/dwin/e3v2/dwin.cpp index 45704d5724f8..8030fbe2ef85 100644 --- a/Marlin/src/lcd/dwin/e3v2/dwin.cpp +++ b/Marlin/src/lcd/dwin/e3v2/dwin.cpp @@ -42,10 +42,6 @@ #define JUST_BABYSTEP 1 #endif -#include -#include -#include - #include "../../fontutils.h" #include "../../marlinui.h" @@ -85,6 +81,10 @@ #include "../../../feature/powerloss.h" #endif +#include +#include +#include + #ifndef MACHINE_SIZE #define MACHINE_SIZE "220x220x250" #endif @@ -99,10 +99,6 @@ #define USE_STRING_HEADINGS -#define DWIN_FONT_MENU font8x16 -#define DWIN_FONT_STAT font10x20 -#define DWIN_FONT_HEAD font10x20 - #define MENU_CHAR_LIMIT 24 #define STATUS_Y 360 @@ -149,6 +145,9 @@ constexpr uint16_t TROWS = 6, MROWS = TROWS - 1, // Total rows, and other #define BABY_Z_VAR TERN(HAS_BED_PROBE, probe.offset.z, dwin_zoffset) +#define DWIN_BOTTOM (DWIN_HEIGHT-1) +#define DWIN_RIGHT (DWIN_WIDTH-1) + /* Value Init */ HMI_value_t HMI_ValueStruct; HMI_Flag_t HMI_flag{0}; @@ -402,7 +401,7 @@ void ICON_Stop() { } inline void Clear_Title_Bar() { - DWIN_Draw_Rectangle(1, Color_Bg_Blue, 0, 0, DWIN_WIDTH, 30); + DWIN_Draw_Box(1, Color_Bg_Blue, 0, 0, DWIN_WIDTH, 30); } inline void Draw_Title(const char * const title) { @@ -414,7 +413,7 @@ inline void Draw_Title(const __FlashStringHelper * title) { } inline void Clear_Menu_Area() { - DWIN_Draw_Rectangle(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, STATUS_Y); + DWIN_Draw_Box(1, Color_Bg_Black, 0, 31, DWIN_WIDTH, STATUS_Y - 30); } inline void Clear_Main_Window() { @@ -561,7 +560,9 @@ inline void draw_move_en(const uint16_t line) { DWIN_Frame_AreaCopy(1, 69, 61, 102, 71, LBLX, line); // "Move" } -inline void DWIN_Frame_TitleCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { DWIN_Frame_AreaCopy(id, x1, y1, x2, y2, 14, 8); } +inline void DWIN_Frame_TitleCopy(uint8_t id, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + DWIN_Frame_AreaCopy(id, x1, y1, x2, y2, 14, 8); +} inline void Item_Prepare_Move(const uint8_t row) { if (HMI_IsChinese()) @@ -777,7 +778,7 @@ inline void Draw_Tune_Menu() { Clear_Main_Window(); if (HMI_IsChinese()) { - DWIN_Frame_AreaCopy(1, 73, 2, 100, 13, 14, 9); + DWIN_Frame_TitleCopy(1, 73, 2, 100, 13); DWIN_Frame_AreaCopy(1, 116, 164, 171, 176, LBLX, MBASE(TUNE_CASE_SPEED)); #if HAS_HOTEND DWIN_Frame_AreaCopy(1, 1, 134, 56, 146, LBLX, MBASE(TUNE_CASE_TEMP)); @@ -807,7 +808,7 @@ inline void Draw_Tune_Menu() { #endif DWIN_Draw_String(false, true, font8x16, Color_White, Color_Bg_Black, LBLX, MBASE(TUNE_CASE_ZOFF), GET_TEXT_F(MSG_ZPROBE_ZOFFSET)); #else - DWIN_Frame_AreaCopy(1, 94, 2, 126, 12, 14, 9); + DWIN_Frame_TitleCopy(1, 94, 2, 126, 12); DWIN_Frame_AreaCopy(1, 1, 179, 92, 190, LBLX, MBASE(TUNE_CASE_SPEED)); // Print speed #if HAS_HOTEND DWIN_Frame_AreaCopy(1, 197, 104, 238, 114, LBLX, MBASE(TUNE_CASE_TEMP)); // Hotend... @@ -930,6 +931,7 @@ inline void Draw_Motion_Menu() { // // Draw Popup Windows // + #if HAS_HOTEND || HAS_HEATED_BED void DWIN_Popup_Temperature(const bool toohigh) { @@ -974,7 +976,7 @@ inline void Draw_Popup_Bkgd_60() { DWIN_ICON_Show(ICON, ICON_TempTooLow, 102, 105); if (HMI_IsChinese()) { DWIN_Frame_AreaCopy(1, 103, 371, 136, 386, 69, 240); - DWIN_Frame_AreaCopy(1, 170, 371, 270, 386, 102, 240); + DWIN_Frame_AreaCopy(1, 170, 371, 270, 386, 69 + 33, 240); DWIN_ICON_Show(ICON, ICON_Confirm_C, 86, 280); } else { @@ -1126,14 +1128,13 @@ void Goto_MainMenu() { Clear_Main_Window(); - if (HMI_IsChinese()) { - DWIN_Frame_AreaCopy(1, 2, 2, 27, 14, 14, 9); // "Home" - } + if (HMI_IsChinese()) + DWIN_Frame_TitleCopy(1, 2, 2, 27, 14); // "Home" else { #ifdef USE_STRING_HEADINGS Draw_Title(GET_TEXT_F(MSG_MAIN)); #else - DWIN_Frame_AreaCopy(1, 0, 2, 39, 12, 14, 9); + DWIN_Frame_TitleCopy(1, 0, 2, 39, 12); #endif } @@ -3628,7 +3629,8 @@ void EachMomentUpdate() { Goto_PrintProcess(); Draw_Status_Area(true); } - #endif + #endif // POWER_LOSS_RECOVERY + DWIN_UpdateLCD(); } diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.h b/Marlin/src/lcd/dwin/e3v2/dwin.h index 5bff2e9f7890..99a9f20427a6 100644 --- a/Marlin/src/lcd/dwin/e3v2/dwin.h +++ b/Marlin/src/lcd/dwin/e3v2/dwin.h @@ -93,140 +93,6 @@ enum processID : uint8_t { Popup_Window }; -// Picture ID -#define Start_Process 0 -#define Language_English 1 -#define Language_Chinese 2 - -// ICON ID -#define ICON 0x09 -#define ICON_LOGO 0 -#define ICON_Print_0 1 -#define ICON_Print_1 2 -#define ICON_Prepare_0 3 -#define ICON_Prepare_1 4 -#define ICON_Control_0 5 -#define ICON_Control_1 6 -#define ICON_Leveling_0 7 -#define ICON_Leveling_1 8 -#define ICON_HotendTemp 9 -#define ICON_BedTemp 10 -#define ICON_Speed 11 -#define ICON_Zoffset 12 -#define ICON_Back 13 -#define ICON_File 14 -#define ICON_PrintTime 15 -#define ICON_RemainTime 16 -#define ICON_Setup_0 17 -#define ICON_Setup_1 18 -#define ICON_Pause_0 19 -#define ICON_Pause_1 20 -#define ICON_Continue_0 21 -#define ICON_Continue_1 22 -#define ICON_Stop_0 23 -#define ICON_Stop_1 24 -#define ICON_Bar 25 -#define ICON_More 26 - -#define ICON_Axis 27 -#define ICON_CloseMotor 28 -#define ICON_Homing 29 -#define ICON_SetHome 30 -#define ICON_PLAPreheat 31 -#define ICON_ABSPreheat 32 -#define ICON_Cool 33 -#define ICON_Language 34 - -#define ICON_MoveX 35 -#define ICON_MoveY 36 -#define ICON_MoveZ 37 -#define ICON_Extruder 38 - -#define ICON_Temperature 40 -#define ICON_Motion 41 -#define ICON_WriteEEPROM 42 -#define ICON_ReadEEPROM 43 -#define ICON_ResumeEEPROM 44 -#define ICON_Info 45 - -#define ICON_SetEndTemp 46 -#define ICON_SetBedTemp 47 -#define ICON_FanSpeed 48 -#define ICON_SetPLAPreheat 49 -#define ICON_SetABSPreheat 50 - -#define ICON_MaxSpeed 51 -#define ICON_MaxAccelerated 52 -#define ICON_MaxJerk 53 -#define ICON_Step 54 -#define ICON_PrintSize 55 -#define ICON_Version 56 -#define ICON_Contact 57 -#define ICON_StockConfiguraton 58 -#define ICON_MaxSpeedX 59 -#define ICON_MaxSpeedY 60 -#define ICON_MaxSpeedZ 61 -#define ICON_MaxSpeedE 62 -#define ICON_MaxAccX 63 -#define ICON_MaxAccY 64 -#define ICON_MaxAccZ 65 -#define ICON_MaxAccE 66 -#define ICON_MaxSpeedJerkX 67 -#define ICON_MaxSpeedJerkY 68 -#define ICON_MaxSpeedJerkZ 69 -#define ICON_MaxSpeedJerkE 70 -#define ICON_StepX 71 -#define ICON_StepY 72 -#define ICON_StepZ 73 -#define ICON_StepE 74 -#define ICON_Setspeed 75 -#define ICON_SetZOffset 76 -#define ICON_Rectangle 77 -#define ICON_BLTouch 78 -#define ICON_TempTooLow 79 -#define ICON_AutoLeveling 80 -#define ICON_TempTooHigh 81 -#define ICON_NoTips_C 82 -#define ICON_NoTips_E 83 -#define ICON_Continue_C 84 -#define ICON_Continue_E 85 -#define ICON_Cancel_C 86 -#define ICON_Cancel_E 87 -#define ICON_Confirm_C 88 -#define ICON_Confirm_E 89 -#define ICON_Info_0 90 -#define ICON_Info_1 91 - -/** - * 3-.0:The font size, 0x00-0x09, corresponds to the font size below: - * 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28 - * 0x05=16*32 0x06=20*40 0x07=24*48 0x08=28*56 0x09=32*64 - */ -#define font6x12 0x00 -#define font8x16 0x01 -#define font10x20 0x02 -#define font12x24 0x03 -#define font14x28 0x04 -#define font16x32 0x05 -#define font20x40 0x06 -#define font24x48 0x07 -#define font28x56 0x08 -#define font32x64 0x09 - -// Color -#define Color_White 0xFFFF -#define Color_Yellow 0xFF0F -#define Color_Bg_Window 0x31E8 // Popup background color -#define Color_Bg_Blue 0x1125 // Dark blue background color -#define Color_Bg_Black 0x0841 // Black background color -#define Color_Bg_Red 0xF00F // Red background color -#define Popup_Text_Color 0xD6BA // Popup font background color -#define Line_Color 0x3A6A // Split line color -#define Rectangle_Color 0xEE2F // Blue square cursor color -#define Percent_Color 0xFE29 // Percentage color -#define BarFill_Color 0x10E4 // Fill color of progress bar -#define Select_Color 0x33BB // Selected color - extern uint8_t checkkey; extern float zprobe_zoffset; extern char print_filename[16]; diff --git a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp index d39c6cfbd5e8..886d5975f81e 100644 --- a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp +++ b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.cpp @@ -21,7 +21,7 @@ */ /***************************************************************************** - * @file rotary_encoder.cpp + * @file lcd/dwin/e3v2/rotary_encoder.cpp * @author LEO / Creality3D * @date 2019/07/06 * @version 2.0.1 diff --git a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h index 93e54839d625..e4b15ede6859 100644 --- a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h +++ b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h @@ -22,7 +22,7 @@ #pragma once /***************************************************************************** - * @file rotary_encoder.h + * @file lcd/dwin/e3v2/rotary_encoder.h * @author LEO / Creality3D * @date 2019/07/06 * @version 2.0.1 diff --git a/Marlin/src/lcd/dwin/marlin/lcdprint_dwin.cpp b/Marlin/src/lcd/dwin/marlin/lcdprint_dwin.cpp new file mode 100644 index 000000000000..254f49977cdf --- /dev/null +++ b/Marlin/src/lcd/dwin/marlin/lcdprint_dwin.cpp @@ -0,0 +1,1145 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 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 . + * + */ + +/** + * lcd/dwin/marlin/lcdprint_dwin.cpp + * + * Due to DWIN hardware limitations simplified characters are used + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if IS_DWIN_MARLINUI + +#include "ultralcd_dwin.h" +#include "../dwin_lcd.h" + +#include "../../marlinui.h" +#include "../../../MarlinCore.h" + +#include + +typedef struct _dwin_charmap_t { + wchar_t uchar; // the unicode char + uint8_t idx; // the glyph of the char in the ROM + uint8_t idx2; // the char used to be combined with the idx to simulate a single char +} dwin_charmap_t; + +struct { int16_t x, y; } cursor; + +#ifdef __AVR__ + #define IV(a) U##a +#else + #define IV(a) L##a +#endif + +static const dwin_charmap_t g_dwin_charmap_device[] PROGMEM = { + // sorted by uchar: + #if DISPLAY_CHARSET_HD44780 == JAPANESE + + {IV('¢'), 0xEC, 0}, // A2 + {IV('°'), 0xDF, 0}, // B0, Marlin special: '°' LCD_STR_DEGREE (0x09) + {IV('ä'), 0xE1, 0}, // E4 + {IV('ö'), 0xEF, 0}, // F6 + {IV('÷'), 0xFD, 0}, // 00F7 + {IV('ü'), 0xF5, 0}, // 00FC + {IV('ˣ'), 0xEB, 0}, // 02E3 + + {IV('·'), 0xA5, 0}, // 0387 + {IV('Ώ'), 0xF4, 0}, // 038F + {IV('Θ'), 0xF2, 0}, // 0398, Theta + {IV('Ξ'), 0xE3, 0}, // 039E, Xi + {IV('Σ'), 0xF6, 0}, // 03A3, Sigma + {IV('Ω'), 0xF4, 0}, // 03A9, Omega + {IV('ά'), 0xE0, 0}, // 03AC + {IV('έ'), 0xE3, 0}, // 03AD + {IV('α'), 0xE0, 0}, // 03B1, alpha + {IV('β'), 0xE2, 0}, // 03B2, beta + {IV('ε'), 0xE3, 0}, // 03B5, epsilon + {IV('θ'), 0xF2, 0}, // 03B8, theta + {IV('μ'), 0xE4, 0}, // 03BC, mu + {IV('ξ'), 0xE3, 0}, // 03BE, xi + {IV('π'), 0xF7, 0}, // 03C0, pi + {IV('ρ'), 0xE6, 0}, // 03C1, rho + {IV('σ'), 0xE5, 0}, // 03C3, sigma + + {IV('←'), 0x7F, 0}, // 2190 + {IV('→'), 0x7E, 0}, // 2192, Marlin special: '⮈⮉⮊⮋➤→' LCD_STR_ARROW_RIGHT (0x03) + {IV('√'), 0xE8, 0}, // 221A + {IV('∞'), 0xF3, 0}, // 221E + {IV('█'), 0xFF, 0}, // 2588 + + //{IV(''), 0xA0, 0}, + {IV('。'), 0xA1, 0}, + {IV('「'), 0xA2, 0}, + {IV('」'), 0xA3, 0}, + {IV('゛'), 0xDE, 0}, // ‶ + {IV('゜'), 0xDF, 0}, // '〫' + {IV('゠'), '=', 0}, + {IV('ァ'), 0xA7, 0}, + {IV('ア'), 0xB1, 0}, + {IV('ィ'), 0xA8, 0}, + {IV('イ'), 0xB2, 0}, + {IV('ゥ'), 0xA9, 0}, + {IV('ウ'), 0xB3, 0}, + {IV('ェ'), 0xAA, 0}, + {IV('エ'), 0xB4, 0}, + {IV('ォ'), 0xAB, 0}, + + {IV('オ'), 0xB5, 0}, + {IV('カ'), 0xB6, 0}, + {IV('ガ'), 0xB6, 0xDE}, + {IV('キ'), 0xB7, 0}, + {IV('ギ'), 0xB7, 0xDE}, + {IV('ク'), 0xB8, 0}, + {IV('グ'), 0xB8, 0xDE}, + {IV('ケ'), 0xB9, 0}, + {IV('ゲ'), 0xB9, 0xDE}, + {IV('コ'), 0xBA, 0}, + {IV('ゴ'), 0xBA, 0xDE}, + {IV('サ'), 0xBB, 0}, + {IV('ザ'), 0xBB, 0xDE}, + {IV('シ'), 0xBC, 0}, + {IV('ジ'), 0xBC, 0xDE}, + {IV('ス'), 0xBD, 0}, + {IV('ズ'), 0xBD, 0xDE}, + {IV('セ'), 0xBE, 0}, + {IV('ゼ'), 0xBE, 0xDE}, + {IV('ソ'), 0xBF, 0}, + {IV('ゾ'), 0xBF, 0xDE}, + + {IV('タ'), 0xC0, 0}, + {IV('ダ'), 0xC0, 0xDE}, + {IV('チ'), 0xC1, 0}, + {IV('ヂ'), 0xC1, 0xDE}, + {IV('ッ'), 0xAF, 0}, + {IV('ツ'), 0xC2, 0}, + {IV('ヅ'), 0xC2, 0xDE}, + {IV('テ'), 0xC3, 0}, + {IV('デ'), 0xC3, 0xDE}, + {IV('ト'), 0xC4, 0}, + {IV('ド'), 0xC4, 0xDE}, + {IV('ナ'), 0xC5, 0}, + {IV('ニ'), 0xC6, 0}, + {IV('ヌ'), 0xC7, 0}, + {IV('ネ'), 0xC8, 0}, + {IV('ノ'), 0xC9, 0}, + {IV('ハ'), 0xCA, 0}, + {IV('バ'), 0xCA, 0xDE}, + {IV('パ'), 0xCA, 0xDF}, + {IV('ヒ'), 0xCB, 0}, + {IV('ビ'), 0xCB, 0xDE}, + {IV('ピ'), 0xCB, 0xDF}, + {IV('フ'), 0xCC, 0}, + {IV('ブ'), 0xCC, 0xDE}, + {IV('プ'), 0xCC, 0xDF}, + {IV('ヘ'), 0xCD, 0}, + {IV('ベ'), 0xCD, 0xDE}, + {IV('ペ'), 0xCD, 0xDF}, + {IV('ホ'), 0xCE, 0}, + {IV('ボ'), 0xCE, 0xDE}, + {IV('ポ'), 0xCE, 0xDF}, + {IV('マ'), 0xCF, 0}, + + {IV('ミ'), 0xD0, 0}, + {IV('ム'), 0xD1, 0}, + {IV('メ'), 0xD2, 0}, + {IV('モ'), 0xD3, 0}, + {IV('ャ'), 0xAC, 0}, + {IV('ヤ'), 0xD4, 0}, + {IV('ュ'), 0xAD, 0}, + {IV('ユ'), 0xD5, 0}, + {IV('ョ'), 0xAE, 0}, + {IV('ヨ'), 0xD6, 0}, + {IV('ラ'), 0xD7, 0}, + {IV('リ'), 0xD8, 0}, + {IV('ル'), 0xD9, 0}, + {IV('レ'), 0xDA, 0}, + {IV('ロ'), 0xDB, 0}, + {IV('ワ'), 0xDC, 0}, + {IV('ヲ'), 0xA6, 0}, + {IV('ン'), 0xDD, 0}, + {IV('ヴ'), 0xB3, 0xDE}, + {IV('ヷ'), 0xDC, 0xDE}, + {IV('ヺ'), 0xA6, 0xDE}, + {IV('・'), 0xA5, 0}, + {IV('ー'), 0xB0, 0}, + {IV('ヽ'), 0xA4, 0}, + + //{IV('g'), 0xE7, 0}, // error + //{IV(''), 0xE9, 0}, + //{IV('j'), 0xEA, 0}, // error + //{IV(''), 0xED, 0}, + //{IV(''), 0xEE, 0}, + + //{IV('p'), 0xF0, 0}, // error + //{IV('q'), 0xF1, 0}, // error + //{IV(''), 0xF8, 0}, + //{IV('y'), 0xF9, 0}, // error + {IV('万'), 0xFB, 0}, + {IV('円'), 0xFC, 0}, + {IV('千'), 0xFA, 0}, + //{IV(''), 0xFE, 0}, + + //、・ヲァィゥェォャュョッー + {IV('、'), 0xA4, 0}, //ヽ + {IV('・'), 0xA5, 0}, //・ + {IV('ヲ'), 0xA6, 0}, //ヲ + {IV('ァ'), 0xA7, 0}, //ァ + {IV('ィ'), 0xA8, 0}, //ィ + {IV('ゥ'), 0xA9, 0}, //ゥ + {IV('ェ'), 0xAA, 0}, //ェ + {IV('ォ'), 0xAB, 0}, //ォ + {IV('ャ'), 0xAC, 0}, //ャ + {IV('ュ'), 0xAD, 0}, //ュ + {IV('ョ'), 0xAE, 0}, //ョ + {IV('ッ'), 0xAF, 0}, //ッ + {IV('ー'), 0xB0, 0}, //ー + + //アイウエオカキクケコサシスセ + {IV('ア'), 0xB1, 0}, //ア + {IV('イ'), 0xB2, 0}, //イ + {IV('ウ'), 0xB3, 0}, //ウ + {IV('エ'), 0xB4, 0}, //エ + {IV('オ'), 0xB5, 0}, //オ + {IV('カ'), 0xB6, 0}, //カ + {IV('キ'), 0xB7, 0}, //キ + {IV('ク'), 0xB8, 0}, //ク + {IV('ケ'), 0xB9, 0}, //ケ + {IV('コ'), 0xBA, 0}, //コ + {IV('サ'), 0xBB, 0}, //サ + {IV('シ'), 0xBC, 0}, //シ + {IV('ス'), 0xBD, 0}, //ス + {IV('セ'), 0xBE, 0}, //セ + + //ソタチツテトナニヌネノハヒフ + {IV('ソ'), 0xBF, 0}, //ソ + {IV('タ'), 0xC0, 0}, //タ + {IV('チ'), 0xC1, 0}, //チ + {IV('ツ'), 0xC2, 0}, //ツ + {IV('テ'), 0xC3, 0}, //テ + {IV('ト'), 0xC4, 0}, //ト + {IV('ナ'), 0xC5, 0}, //ナ + {IV('ニ'), 0xC6, 0}, //ニ + {IV('ヌ'), 0xC7, 0}, //ヌ + {IV('ネ'), 0xC8, 0}, //ネ + {IV('ノ'), 0xC9, 0}, //ノ + {IV('ハ'), 0xCA, 0}, //ハ + {IV('ヒ'), 0xCB, 0}, //ヒ + {IV('フ'), 0xCC, 0}, //フ + + //ヘホマミムメモヤユヨラリルレロワン゙゚ + {IV('ヘ'), 0xCD, 0}, //ヘ + {IV('ホ'), 0xCE, 0}, //ホ + {IV('マ'), 0xCF, 0}, //マ + {IV('ミ'), 0xD0, 0}, //ミ + {IV('ム'), 0xD1, 0}, //ム + {IV('メ'), 0xD2, 0}, //メ + {IV('モ'), 0xD3, 0}, //モ + {IV('ヤ'), 0xD4, 0}, //ヤ + {IV('ユ'), 0xD5, 0}, //ユ + {IV('ヨ'), 0xD6, 0}, //ヨ + {IV('ラ'), 0xD7, 0}, //ラ + {IV('リ'), 0xD8, 0}, //リ + {IV('ル'), 0xD9, 0}, //ル + {IV('レ'), 0xDA, 0}, //レ + {IV('ロ'), 0xDB, 0}, //ロ + {IV('ワ'), 0xDC, 0}, //ワ + {IV('ン'), 0xDD, 0}, //ン + {IV('゙'), 0xDE, 0}, // ゛ + {IV('゚'), 0xDF, 0}, // ゜ + + {IV('¥'), 0x5C, 0}, + + #elif DISPLAY_CHARSET_HD44780 == WESTERN + // 0x10 -- 0x1F (except 0x1C) + // 0x80 -- 0xFF (except 0xA7,0xB0,0xB1,0xB3,0xB4,0xBF,0xD1,0xF8,0xFA,0xFC-0xFF) + + {IV('¡'), 0xA9, 0}, + {IV('¢'), 0xA4, 0}, + {IV('£'), 0xA5, 0}, + {IV('¥'), 0xA6, 0}, + {IV('§'), 0xD2, 0}, // section sign + {IV('©'), 0xCF, 0}, + + {IV('ª'), 0x9D, 0}, + {IV('«'), 0xBB, 0}, + {IV('®'), 0xCE, 0}, + + {IV('°'), 0xB2, 0}, // Marlin special: '°' LCD_STR_DEGREE (0x09) + //{IV(''), 0xD1, 0}, + {IV('±'), 0x10, 0}, //∓± + //{'='), 0x1C, 0}, // error + {IV('²'), 0x1E, 0}, + {IV('³'), 0x1F, 0}, + {IV('¶'), 0xD3, 0}, // pilcrow sign + {IV('º'), 0x9E, 0}, + {IV('»'), 0xBC, 0}, // 00BB + //{IV(''), 0xB3, 0}, // error + //{IV(''), 0xB4, 0}, // error + {IV('¼'), 0xB6, 0}, // 00BC + {IV('½'), 0xB5, 0}, // 00BD + //{IV('¾'), '3', 0}, // 00BE + {IV('¿'), 0x9F, 0}, // 00BF + + {IV('Â'), 0x8F, 0}, + {IV('Ã'), 0xAA, 0}, + {IV('Ä'), 0x8E, 0}, + {IV('Æ'), 0x92, 0}, + {IV('Ç'), 0x80, 0}, + {IV('É'), 0x90, 0}, + {IV('Ñ'), 0x9C, 0}, + {IV('Õ'), 0xAC, 0}, + {IV('Ö'), 0x99, 0}, + {IV('×'), 0xB7, 0}, + {IV('Ø'), 0xAE, 0}, + {IV('Ü'), 0x9A, 0}, + {IV('à'), 0x85, 0}, + {IV('á'), 0xA0, 0}, + {IV('â'), 0x83, 0}, + {IV('ã'), 0xAB, 0}, + {IV('ä'), 0x84, 0}, + {IV('å'), 0x86, 0}, + {IV('æ'), 0x91, 0}, + {IV('ç'), 0x87, 0}, + {IV('è'), 0x8A, 0}, + {IV('é'), 0x82, 0}, + {IV('ê'), 0x88, 0}, + {IV('ë'), 0x89, 0}, + {IV('ì'), 0x8D, 0}, + {IV('í'), 0xA1, 0}, + {IV('î'), 0x8C, 0}, + {IV('ï'), 0x8B, 0}, + + {IV('ñ'), 0x9B, 0}, + {IV('ò'), 0x95, 0}, + {IV('ó'), 0xA2, 0}, + {IV('ô'), 0x93, 0}, + {IV('õ'), 0xAD, 0}, + {IV('ö'), 0x94, 0}, + {IV('÷'), 0xB8, 0}, + {IV('ø'), 0xAF, 0}, + {IV('ù'), 0x97, 0}, + {IV('ú'), 0xA3, 0}, + {IV('û'), 0x96, 0}, + {IV('ü'), 0x81, 0}, + {IV('ÿ'), 0x98, 0}, + + //{IV(''), 0xB0, 0}, // error + //{IV(''), 0xB1, 0}, // error + {IV('ƒ'), 0xA8, 0}, // 0192 + + {IV('Ύ'), 0xDB, 0}, // 038E + {IV('Ώ'), 0xDE, 0}, // 038F + {IV('ΐ'), 0xE7, 0}, // 0390 + + {IV('Γ'), 0xD4, 0}, // 0393, Gamma + {IV('Δ'), 0xD5, 0}, // 0394, Delta, ◿ + {IV('Θ'), 0xD6, 0}, // 0398, Theta + {IV('Λ'), 0xD7, 0}, // 039B, Lambda + {IV('Ξ'), 0xD8, 0}, // 039E, Xi + {IV('Π'), 0xD9, 0}, // Pi + {IV('Σ'), 0xDA, 0}, // Sigma + {IV('Υ'), 0xDB, 0}, // Upsilon + {IV('Φ'), 0xDC, 0}, // Phi + {IV('Ψ'), 0xDD, 0}, // Psi + {IV('Ω'), 0xDE, 0}, // Omega + + {IV('ά'), 0xDF, 0}, // 03AC + {IV('έ'), 0xE3, 0}, // 03AD + {IV('ή'), 0xE5, 0}, // 03AE + {IV('ί'), 0xE7, 0}, // 03AF + {IV('ΰ'), 0xF1, 0}, // 03B0 + + {IV('α'), 0xDF, 0}, // alpha + {IV('β'), 0xE0, 0}, // beta + {IV('γ'), 0xE1, 0}, // gamma + {IV('δ'), 0xE2, 0}, // delta + {IV('ε'), 0xE3, 0}, // epsilon + {IV('ζ'), 0xE4, 0}, // zeta + {IV('η'), 0xE5, 0}, // eta + {IV('θ'), 0xE6, 0}, // theta + {IV('ι'), 0xE7, 0}, // lota + {IV('κ'), 0xE8, 0}, // kappa + {IV('λ'), 0xE9, 0}, // lambda + {IV('μ'), 0xEA, 0}, // mu + {IV('ν'), 0xEB, 0}, // nu + {IV('ξ'), 0xEC, 0}, // xi + {IV('π'), 0xED, 0}, // pi + {IV('ρ'), 0xEE, 0}, // rho + {IV('σ'), 0xEF, 0}, // sigma + + {IV('τ'), 0xF0, 0}, // tau + {IV('υ'), 0xF1, 0}, // upsilon + {IV('χ'), 0xF2, 0}, // chi + {IV('ψ'), 0xF3, 0}, // psi + {IV('ω'), 0xF4, 0}, // 03C9, omega + {IV('ϊ'), 0xE7, 0}, // 03CA + {IV('ϋ'), 0xF1, 0}, // 03CB + {IV('ύ'), 0xF1, 0}, // 03CD + {IV('ώ'), 0xF4, 0}, // 03CE + + {IV('•'), 0xCD, 0}, // · + {IV('℞'), 0xA7, 0}, // ℞ Pt ASCII 158 + {IV('™'), 0xD0, 0}, + {IV('↤'), 0xF9, 0}, // ⟻ + {IV('↵'), 0xC4, 0}, + {IV('↻'), 0x04, 0}, // Marlin special: '↻↺⟳⟲' LCD_STR_REFRESH (0x01) + {IV('⇥'), 0xFB, 0}, + {IV('√'), 0xBE, 0}, // √ + {IV('∞'), 0xC2, 0}, // infinity + {IV('∫'), 0x1B, 0}, + {IV('∼'), 0x1D, 0}, + {IV('≈'), 0x1A, 0}, + {IV('≠'), 0xBD, 0}, + {IV('≡'), 0x11, 0}, + {IV('≤'), 0xB9, 0},// ≤≥ ⩽⩾ + {IV('≥'), 0xBA, 0}, + //{IV(''), 0xBF, 0}, // error + + {IV('⌠'), 0xC0, 0}, + {IV('⌡'), 0xC1, 0}, + + {IV('⎧'), 0x14, 0}, + {IV('⎩'), 0x15, 0}, + {IV('⎫'), 0x16, 0}, + {IV('⎭'), 0x17, 0}, + {IV('⎰'), 0x18, 0}, + {IV('⎱'), 0x19, 0}, + + {IV('⎲'), 0x12, 0}, + {IV('⎳'), 0x13, 0}, + + {IV('⏱'), 0x07, 0}, // Marlin special: '🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧 ⌚⌛⏰⏱⏳⧖⧗' LCD_STR_CLOCK (0x05) + {IV('┌'), 0xC9, 0}, + {IV('┐'), 0xCA, 0}, + {IV('└'), 0xCB, 0}, + {IV('┘'), 0xCC, 0}, + {IV('◸'), 0xC3, 0}, // ◿ + {IV('⭠'), 0xC8, 0}, + {IV('⭡'), 0xC5, 0}, + {IV('⭢'), 0xC7, 0}, + {IV('⭣'), 0xC6, 0}, + + + {IV('⯆'), 0xF5, 0}, + {IV('⯇'), 0xF7, 0}, // ⯅ + {IV('⯈'), 0xF6, 0}, + //{IV(''), 0xF8, 0}, // error + //{IV(''), 0xFA, 0}, // error + //{IV(''), 0xFC, 0}, // error + //{IV(''), 0xFD, 0}, // error + //{IV(''), 0xFE, 0}, // error + //{IV(''), 0xFF, 0}, // error + + #elif DISPLAY_CHARSET_HD44780 == CYRILLIC + + {IV('¢'), 0x5C, 0}, // 00A2 + {IV('£'), 0xCF, 0}, // 00A3 + {IV('°'), 0x01, 0}, // 00B0, Marlin special: '°' LCD_STR_DEGREE (0x09) + + //{IV(''), 0x80, 0}, + //{IV(''), 0x81, 0}, + //{IV(''), 0x82, 0}, + //{IV(''), 0x83, 0}, + //{IV(''), 0x84, 0}, + //{IV(''), 0x85, 0}, + //{IV(''), 0x86, 0}, + //{IV(''), 0x87, 0}, + //{IV(''), 0x88, 0}, + //{IV(''), 0x89, 0}, + //{IV(''), 0x8A, 0}, + //{IV(''), 0x8B, 0}, + //{IV(''), 0x8C, 0}, + //{IV(''), 0x8D, 0}, + //{IV(''), 0x8E, 0}, + //{IV(''), 0x8F, 0}, + + //{IV(''), 0x90, 0}, + //{IV(''), 0x91, 0}, + //{IV(''), 0x92, 0}, + //{IV(''), 0x93, 0}, + //{IV(''), 0x94, 0}, + //{IV(''), 0x95, 0}, + //{IV(''), 0x96, 0}, + //{IV(''), 0x97, 0}, + //{IV(''), 0x98, 0}, + //{IV(''), 0x99, 0}, + //{IV(''), 0x9A, 0}, + //{IV(''), 0x9B, 0}, + //{IV(''), 0x9C, 0}, + //{IV(''), 0x9D, 0}, + //{IV(''), 0x9E, 0}, + //{IV(''), 0x9F, 0}, + + + {IV('¼'), 0xF0, 0}, // 00BC + {IV('⅓'), 0xF1, 0}, + {IV('½'), 0xF2, 0}, // 00BD + {IV('¾'), 0xF3, 0}, // 00BE + {IV('¿'), 0xCD, 0}, // 00BF + + #if ENABLED(DISPLAY_CHARSET_ISO10646_5) + + // Map Cyrillic to HD44780 extended CYRILLIC where possible + {IV('Ё'), 0xA2, 0}, // 0401 + {IV('А'), 'A', 0}, // 0410 + {IV('Б'), 0xA0, 0}, + {IV('В'), 'B', 0}, + {IV('Г'), 0xA1, 0}, + {IV('Д'), 0xE0, 0}, + {IV('Е'), 'E', 0}, + {IV('Ж'), 0xA3, 0}, + {IV('З'), 0xA4, 0}, + {IV('И'), 0xA5, 0}, + {IV('Й'), 0xA6, 0}, + {IV('К'), 'K', 0}, + {IV('Л'), 0xA7, 0}, + {IV('М'), 'M', 0}, + {IV('Н'), 'H', 0}, + {IV('О'), 'O', 0}, + {IV('П'), 0xA8, 0}, + {IV('Р'), 'P', 0}, + {IV('С'), 'C', 0}, + {IV('Т'), 'T', 0}, + {IV('У'), 0xA9, 0}, + {IV('Ф'), 0xAA, 0}, + {IV('Х'), 'X', 0}, + {IV('Ц'), 0xE1, 0}, + {IV('Ч'), 0xAB, 0}, + {IV('Ш'), 0xAC, 0}, + {IV('Щ'), 0xE2, 0}, + {IV('Ъ'), 0xAD, 0}, + {IV('Ы'), 0xAE, 0}, + {IV('Ь'), 'b', 0}, + {IV('Э'), 0xAF, 0}, + {IV('Ю'), 0xB0, 0}, + {IV('Я'), 0xB1, 0}, + {IV('а'), 'a', 0}, + + {IV('б'), 0xB2, 0}, + {IV('в'), 0xB3, 0}, + {IV('г'), 0xB4, 0}, + {IV('д'), 0xE3, 0}, + {IV('е'), 'e', 0}, + {IV('ж'), 0xB6, 0}, + {IV('з'), 0xB7, 0}, + {IV('и'), 0xB8, 0}, + {IV('й'), 0xB9, 0}, + {IV('к'), 0xBA, 0}, //клмноп + {IV('л'), 0xBB, 0}, + {IV('м'), 0xBC, 0}, + {IV('н'), 0xBD, 0}, + {IV('о'), 'o', 0}, + {IV('п'), 0xBE, 0}, + {IV('р'), 'p', 0}, + {IV('с'), 'c', 0}, + {IV('т'), 0xBF, 0}, + + {IV('у'), 'y', 0}, + {IV('ф'), 0xE4, 0}, + {IV('х'), 'x', 0}, + {IV('ц'), 0xE5, 0}, + {IV('ч'), 0xC0, 0}, + {IV('ш'), 0xC1, 0}, + {IV('щ'), 0xE6, 0}, + {IV('ъ'), 0xC2, 0}, + {IV('ы'), 0xC3, 0}, + {IV('ь'), 0xC4, 0}, + {IV('э'), 0xC5, 0}, + {IV('ю'), 0xC6, 0}, + {IV('я'), 0xC7, 0}, // 044F + {IV('ё'), 0xB5, 0}, // 0451 + //{IV(''), 0xC8, 0}, + //{IV(''), 0xC9, 0}, + //{IV(''), 0xCA, 0}, + //{IV(''), 0xCB, 0}, + //{IV(''), 0xCC, 0}, + //{IV(''), 0xCD, 0}, + //{IV(''), 0xCE, 0}, + + //{IV(''), 0xD0, 0}, + //{IV(''), 0xD1, 0}, + //{IV(''), 0xD2, 0}, + //{IV(''), 0xD3, 0}, + //{IV(''), 0xD4, 0}, + //{IV(''), 0xD5, 0}, + //{IV(''), 0xD6, 0}, + //{IV(''), 0xD7, 0}, + //{IV(''), 0xD8, 0}, + //{IV(''), 0xDB, 0}, + //{IV(''), 0xDC, 0}, + //{IV(''), 0xDD, 0}, + //{IV(''), 0xDE, 0}, + //{IV(''), 0xDF, 0}, + + //{IV(''), 0xE7, 0}, + //{IV(''), 0xE8, 0}, + //{IV(''), 0xE9, 0}, + //{IV(''), 0xEA, 0}, + //{IV(''), 0xEB, 0}, + //{IV(''), 0xEC, 0}, + //{IV(''), 0xED, 0}, + //{IV(''), 0xEE, 0}, + //{IV(''), 0xEF, 0}, + + //{IV(''), 0xF4, 0}, + //{IV(''), 0xF5, 0}, + //{IV(''), 0xF6, 0}, + //{IV(''), 0xF7, 0}, + //{IV(''), 0xF8, 0}, + //{IV(''), 0xF9, 0}, + //{IV(''), 0xFA, 0}, + //{IV(''), 0xFB, 0}, + //{IV(''), 0xFC, 0}, + //{IV(''), 0xFD, 0}, + //{IV(''), 0xFE, 0}, + //{IV(''), 0xFF, 0}, + + #endif + + {IV('↑'), 0xD9, 0}, // 2191 ←↑→↓ + {IV('↓'), 0xDA, 0}, // 2193 + #endif +}; + +// the plain ASCII replacement for various char +static const dwin_charmap_t g_dwin_charmap_common[] PROGMEM = { + {IV('¡'), 'i', 0}, // A1 + {IV('¢'), 'c', 0}, // A2 + {IV('°'), 0x09, 0}, // B0 Marlin special: '°' LCD_STR_DEGREE (0x09) + + // Map WESTERN code to plain ASCII + {IV('Á'), 'A', 0}, // C1 + {IV('Â'), 'A', 0}, // C2 + {IV('Ã'), 'A', 0}, // C3 + {IV('Ä'), 'A', 0}, // C4 + {IV('Å'), 'A', 0}, // C5 + {IV('Æ'), 'A', 'E'}, // C6 + {IV('Ç'), 'C', 0}, // C7 + {IV('È'), 'E', 0}, // C8 + {IV('É'), 'E', 0}, // C9 + {IV('Í'), 'I', 0}, // CD + {IV('Ñ'), 'N', 0}, // D1 + {IV('Õ'), 'O', 0}, // D5 + {IV('Ö'), 'O', 0}, // D6 + {IV('×'), 'x', 0}, // D7 + {IV('Ü'), 'U', 0}, // DC + {IV('Ý'), 'Y', 0}, // DD + {IV('à'), 'a', 0}, // E0 + {IV('á'), 'a', 0}, + {IV('â'), 'a', 0}, + {IV('ã'), 'a', 0}, + {IV('ä'), 'a', 0}, + {IV('å'), 'a', 0}, + {IV('æ'), 'a', 'e'}, + {IV('ç'), 'c', 0}, + {IV('è'), 'e', 0}, // 00E8 + {IV('é'), 'e', 0}, + {IV('ê'), 'e', 0}, + {IV('ë'), 'e', 0}, + {IV('ì'), 'i', 0}, // 00EC + {IV('í'), 'i', 0}, + {IV('î'), 'i', 0}, + {IV('ï'), 'i', 0}, // 00EF + + {IV('ñ'), 'n', 0}, // 00F1 + {IV('ò'), 'o', 0}, + {IV('ó'), 'o', 0}, + {IV('ô'), 'o', 0}, + {IV('õ'), 'o', 0}, + {IV('ö'), 'o', 0}, + //{IV('÷'), 0xB8, 0}, + {IV('ø'), 'o', 0}, + {IV('ù'), 'u', 0}, + {IV('ú'), 'u', 0}, + {IV('û'), 'u', 0}, + {IV('ü'), 'u', 0}, // FC + {IV('ý'), 'y', 0}, // FD + {IV('ÿ'), 'y', 0}, // FF + + {IV('Ą'), 'A', 0}, // 0104 + {IV('ą'), 'a', 0}, // 0105 + {IV('Ć'), 'C', 0}, // 0106 + {IV('ć'), 'c', 0}, // 0107 + {IV('Č'), 'C', 0}, // 010C + {IV('č'), 'c', 0}, // 010D + {IV('Ď'), 'D', 0}, // 010E + {IV('ď'), 'd', 0}, // 010F + {IV('đ'), 'd', 0}, // 0111 + {IV('ę'), 'e', 0}, // 0119 + {IV('Ě'), 'E', 0}, // 011A + {IV('ě'), 'e', 0}, // 011B + {IV('ğ'), 'g', 0}, // 011F + {IV('İ'), 'I', 0}, // 0130 + {IV('ı'), 'i', 0}, // 0131 + + {IV('Ł'), 'L', 0}, // 0141 + {IV('ł'), 'l', 0}, // 0142 + {IV('Ń'), 'N', 0}, // 0143 + {IV('ń'), 'n', 0}, // 0144 + {IV('ň'), 'n', 0}, // 0148 + + {IV('Ř'), 'R', 0}, // 0158 + {IV('ř'), 'r', 0}, // 0159 + {IV('Ś'), 'S', 0}, // 015A + {IV('ś'), 's', 0}, // 015B + {IV('ş'), 's', 0}, // 015F + {IV('Š'), 'S', 0}, // 0160 + {IV('š'), 's', 0}, // 0161 + {IV('ť'), 't', 0}, // 0165 + {IV('ů'), 'u', 0}, // 016F + {IV('ż'), 'z', 0}, // 017C + {IV('Ž'), 'Z', 0}, // 017D + {IV('ž'), 'z', 0}, // 017E + {IV('ƒ'), 'f', 0}, // 0192 + + {IV('ˣ'), 'x', 0}, // 02E3 + + #if ENABLED(DISPLAY_CHARSET_ISO10646_VI) + + // Map Vietnamese phonetics + + //{IV('à'), 'a', 0}, {IV('À'), 'A', 0}, + {IV('ạ'), 'a', 0}, {IV('Ạ'), 'A', 0}, + {IV('ả'), 'a', 0}, {IV('Ả'), 'A', 0}, + //{IV('ã'), 'a', 0}, {IV('Ã'), 'A', 0}, + //{IV('á'), 'á', 0}, {IV('Á'), 'A', 0}, + {IV('Ạ'), 'A', 0}, + {IV('ă'), 'a', 0}, {IV('Ă'), 'A', 0}, + {IV('ằ'), 'a', 0}, {IV('Ằ'), 'A', 0}, + {IV('ẳ'), 'a', 0}, {IV('Ẳ'), 'A', 0}, + {IV('ẵ'), 'a', 0}, {IV('Ẵ'), 'A', 0}, + {IV('ắ'), 'a', 0}, {IV('Ắ'), 'A', 0}, + {IV('ặ'), 'a', 0}, {IV('Ặ'), 'A', 0}, + {IV('â'), 'a', 0}, {IV('Â'), 'A', 0}, + {IV('ầ'), 'a', 0}, {IV('Ầ'), 'A', 0}, + {IV('ẩ'), 'a', 0}, {IV('Ẩ'), 'A', 0}, + {IV('ẫ'), 'a', 0}, {IV('Ẫ'), 'A', 0}, + {IV('ấ'), 'a', 0}, {IV('Ấ'), 'A', 0}, + {IV('ậ'), 'a', 0}, {IV('Ậ'), 'A', 0}, + //{IV('đ'), 'd', 0}, + {IV('Đ'), 'D', 0}, + {IV('e'), 'e', 0}, {IV('E'), 'E', 0}, + {IV('è'), 'e', 0}, {IV('È'), 'E', 0}, + {IV('ẻ'), 'e', 0}, {IV('Ẻ'), 'E', 0}, + {IV('ẽ'), 'e', 0}, {IV('Ẽ'), 'E', 0}, + {IV('é'), 'e', 0}, {IV('É'), 'E', 0}, + {IV('ẹ'), 'e', 0}, {IV('Ẹ'), 'E', 0}, + {IV('ê'), 'e', 0}, {IV('Ê'), 'E', 0}, + {IV('ề'), 'e', 0}, {IV('Ề'), 'E', 0}, + {IV('ể'), 'e', 0}, {IV('Ể'), 'E', 0}, + {IV('ễ'), 'e', 0}, {IV('Ễ'), 'E', 0}, + {IV('ế'), 'e', 0}, {IV('Ế'), 'E', 0}, + {IV('ệ'), 'e', 0}, {IV('Ệ'), 'E', 0}, + {IV('i'), 'i', 0}, {IV('I'), 'I', 0}, + //{IV('ì'), 'ì', 0}, {IV('Ì'), 'Ì', 0}, + {IV('ỉ'), 'ỉ', 0}, {IV('Ỉ'), 'Ỉ', 0}, + {IV('ĩ'), 'ĩ', 0}, {IV('Ĩ'), 'Ĩ', 0}, + {IV('í'), 'í', 0}, {IV('Í'), 'Í', 0}, + {IV('ị'), 'ị', 0}, {IV('Ị'), 'Ị', 0}, + {IV('o'), 'o', 0}, {IV('O'), 'O', 0}, + {IV('ò'), 'o', 0}, {IV('Ò'), 'O', 0}, + {IV('ỏ'), 'o', 0}, {IV('Ỏ'), 'O', 0}, + {IV('õ'), 'o', 0}, {IV('Õ'), 'O', 0}, + {IV('ó'), 'o', 0}, {IV('Ó'), 'O', 0}, + {IV('ọ'), 'o', 0}, {IV('Ọ'), 'O', 0}, + {IV('ô'), 'o', 0}, {IV('Ô'), 'O', 0}, + {IV('ồ'), 'o', 0}, {IV('Ồ'), 'O', 0}, + {IV('ổ'), 'o', 0}, {IV('Ổ'), 'O', 0}, + {IV('ỗ'), 'o', 0}, {IV('Ỗ'), 'O', 0}, + {IV('ố'), 'o', 0}, {IV('Ố'), 'O', 0}, + {IV('ộ'), 'o', 0}, {IV('Ộ'), 'O', 0}, + {IV('ơ'), 'o', 0}, {IV('Ơ'), 'O', 0}, + {IV('ờ'), 'o', 0}, {IV('Ờ'), 'O', 0}, + {IV('ở'), 'o', 0}, {IV('Ở'), 'O', 0}, + {IV('ỡ'), 'o', 0}, {IV('Ỡ'), 'O', 0}, + {IV('ớ'), 'o', 0}, {IV('Ớ'), 'O', 0}, + {IV('ợ'), 'o', 0}, {IV('Ợ'), 'O', 0}, + {IV('ù'), 'u', 0}, {IV('Ù'), 'U', 0}, + {IV('ủ'), 'u', 0}, {IV('Ủ'), 'U', 0}, + {IV('ũ'), 'u', 0}, {IV('Ũ'), 'U', 0}, + //{IV('ú'), 'u', 0}, {IV('Ú'), 'U', 0}, + {IV('ụ'), 'u', 0}, {IV('Ụ'), 'U', 0}, + {IV('ư'), 'u', 0}, {IV('Ư'), 'U', 0}, + {IV('ừ'), 'u', 0}, {IV('Ừ'), 'U', 0}, + {IV('ử'), 'u', 0}, {IV('Ử'), 'U', 0}, + {IV('ữ'), 'u', 0}, {IV('Ữ'), 'U', 0}, + {IV('ứ'), 'u', 0}, {IV('Ứ'), 'U', 0}, + {IV('ự'), 'u', 0}, {IV('Ự'), 'U', 0}, + {IV('y'), 'y', 0}, {IV('Y'), 'Y', 0}, + + #endif + + #if ENABLED(DISPLAY_CHARSET_ISO10646_GREEK) + + {IV('΄'), '\'', 0}, // 0384 + {IV('΅'), '\'', 0}, // 0385 + {IV('Ά'), 'A', 0}, // 0386 + {IV('·'), '.', 0}, // 0387 + {IV('Έ'), 'E', 0}, // 0388 + {IV('Ή'), 'H', 0}, // 0389 + {IV('Ί'), 'I', 0}, // 038A + {IV('Ό'), 'O', 0}, // 038C + {IV('Ύ'), 'Y', 0}, // 038E + {IV('Ώ'), 'O', 0}, // 038F + {IV('ΐ'), 'i', 0}, // 0390 + {IV('Α'), 'A', 0}, // 0391 + {IV('Β'), 'B', 0}, // 0392 + {IV('Γ'), 'T', 0}, // 0393, Gamma + {IV('Δ'), '4', 0}, // 0394, Delta, ◿ + {IV('Ε'), 'E', 0}, // 0395 + {IV('Ζ'), 'Z', 0}, // 0396 + {IV('Η'), 'H', 0}, // 0397 + {IV('Θ'), '0', 0}, // 0398, Theta + {IV('Ι'), 'I', 0}, // 0399 + {IV('Κ'), 'K', 0}, // 039A + {IV('Λ'), '^', 0}, // 039B, Lambda + {IV('Μ'), 'M', 0}, // 039C + {IV('Ν'), 'N', 0}, // 039D + {IV('Ξ'), '3', 0}, // 039E, Xi + {IV('Ο'), 'O', 0}, // 039F + {IV('Π'), 'n', 0}, // 03A0, Pi + {IV('Ρ'), 'P', 0}, // 03A1 + {IV('Σ'), 'E', 0}, // 03A3, Sigma + {IV('Τ'), 'T', 0}, // 03A4 + {IV('Υ'), 'Y', 0}, // 03A5, Upsilon + {IV('Φ'), 'p', 0}, // 03A6, Phi + {IV('Χ'), 'X', 0}, // 03A7 + {IV('Ψ'), 'P', 0}, // 03A8, Psi + {IV('Ω'), 'O', 0}, // 03A9, Omega + {IV('Ϊ'), 'I', 0}, // 03AA + {IV('Ϋ'), 'Y', 0}, // 03AB + {IV('ά'), 'a', 0}, // 03AC + {IV('έ'), 'e', 0}, // 03AD + {IV('ή'), 'n', 0}, // 03AE + {IV('ί'), 'i', 0}, // 03AF + {IV('ΰ'), 'v', 0}, // 03B0 + {IV('α'), 'a', 0}, // 03B1, alpha + {IV('β'), 'B', 0}, // 03B2, beta + {IV('γ'), 'v', 0}, // 03B3, gamma + {IV('δ'), 'd', 0}, // 03B4, delta + {IV('ε'), 'e', 0}, // 03B5, epsilon + {IV('ζ'), 'Z', 0}, // 03B6, zeta + {IV('η'), 'n', 0}, // 03B7, eta + {IV('θ'), '0', 0}, // 03B8, theta + {IV('ι'), 'i', 0}, // 03B9, lota + {IV('κ'), 'k', 0}, // 03BA, kappa + {IV('λ'), 'L', 0}, // 03BB, lambda + {IV('μ'), 'u', 0}, // 03BC, mu + {IV('ν'), 'v', 0}, // 03BD, nu + {IV('ξ'), 'e', 0}, // 03BE, xi + {IV('ο'), 'o', 0}, // 03BF + {IV('π'), 'n', 0}, // 03C0, pi + {IV('ρ'), 'p', 0}, // 03C1, rho + {IV('ς'), 'c', 0}, // 03C2 + {IV('σ'), 'o', 0}, // 03C3, sigma + {IV('τ'), 't', 0}, // 03C4, tau + {IV('υ'), 'v', 0}, // 03C5, upsilon + {IV('φ'), 'p', 0}, // 03C6 + {IV('χ'), 'X', 0}, // 03C7, chi + {IV('ψ'), 'W', 0}, // 03C8, psi + {IV('ω'), 'w', 0}, // 03C9, omega + {IV('ϊ'), 'i', 0}, // 03CA + {IV('ϋ'), 'v', 0}, // 03CB + {IV('ό'), 'o', 0}, // 03CC + {IV('ύ'), 'v', 0}, // 03CD + {IV('ώ'), 'w', 0}, // 03CE + + #endif + + #if ENABLED(DISPLAY_CHARSET_ISO10646_5) + // Map CYRILLIC code to plain ASCII + {IV('Ё'), 'E', 0}, // 0401 + {IV('А'), 'A', 0}, // 0410 + {IV('Б'), 'b', 0}, // 0411 + {IV('В'), 'B', 0}, // 0412 + {IV('Г'), 'T', 0}, // 0413 + {IV('Д'), 'Q', 0}, // 0414 + {IV('Е'), 'E', 0}, // 0415 + {IV('Ж'), '*', 0}, // 0416 + {IV('З'), 'E', 0}, // 0417 + {IV('И'), 'N', 0}, // 0418 + {IV('Й'), 'N', 0}, // 0419 + {IV('К'), 'K', 0}, // 041A + {IV('Л'), 'T', 0}, // 041B + {IV('М'), 'M', 0}, // 041C + {IV('Н'), 'H', 0}, // 041D + {IV('О'), 'O', 0}, // 041E + {IV('П'), 'n', 0}, // 041F + {IV('Р'), 'P', 0}, // 0420 + {IV('С'), 'C', 0}, // 0421 + {IV('Т'), 'T', 0}, // 0422 + {IV('У'), 'Y', 0}, + {IV('Ф'), 'o', 0}, + {IV('Х'), 'X', 0}, + {IV('Ц'), 'U', 0}, + {IV('Ч'), 'y', 0}, + {IV('Ш'), 'W', 0}, + {IV('Щ'), 'W', 0}, + {IV('Ъ'), 'b', 0}, + {IV('Ы'), 'b', '|'}, + {IV('Ь'), 'b'}, + {IV('Э'), 'e'}, + {IV('Ю'), '|', 'O'}, + {IV('Я'), '9', '|'}, // 042F + + {IV('а'), 'a', 0}, // 0430 + {IV('б'), '6', 0}, // 0431 + {IV('в'), 'B', 0}, // 0432, + {IV('г'), 'r', 0}, // 0433 + {IV('д'), 'a', 0}, // 0434, + {IV('е'), 'e', 0}, // 0435 + {IV('ж'), '*', 0}, // 0436 + {IV('з'), 'e', 0}, // 0437, + {IV('и'), 'u', 0}, // 0438 + {IV('й'), 'u', 0}, // 0439, + {IV('к'), 'k', 0}, // 043A + {IV('л'), 'n', 0}, + {IV('м'), 'm', 0}, + {IV('н'), 'H', 0}, + {IV('о'), 'o', 0}, + {IV('п'), 'n', 0}, + {IV('р'), 'p', 0}, + {IV('с'), 'c', 0}, + {IV('т'), 't', 0}, + {IV('у'), 'y', 0}, + {IV('ф'), 'q', 'p'}, + {IV('х'), 'x', 0}, + {IV('ц'), 'u', 0}, + {IV('ч'), 'y', 0}, + {IV('ш'), 'w', 0}, + {IV('щ'), 'w', 0}, + {IV('ъ'), 'b', 0}, + {IV('ы'), 'b', '|'}, + {IV('ь'), 'b', 0}, + {IV('э'), 'e', 0}, + {IV('ю'), '|', 'o'}, + {IV('я'), 'g', 0}, // 044F + {IV('ё'), 'e', 0}, // 0451 + #endif + + {IV('•'), '.', 0}, // 2022 · + {IV('℞'), 'P', 'x'}, // 211E ℞ Pt ASCII 158 + {IV('™'), 'T', 'M'}, // 2122 + {IV('←'), '<', '-'}, // 2190 + {IV('→'), '-', '>'}, // 2192, Marlin special: '⮈⮉⮊⮋➤→⏵➟➠➡' LCD_STR_ARROW_RIGHT (0x03) + //{IV('↰'), '<', 0}, // 21B0, Marlin special: '⮥⮭⮉⇧↑↰⤴' LCD_STR_UPLEVEL (0x04) + {IV('↰'), 0x03, 0}, // 21B0, Marlin special: '⮥⮭⮉⇧↑↰⤴' LCD_STR_UPLEVEL (0x04) + {IV('↻'), 0x04, 0}, // 21BB Marlin special: '↻↺⟳⟲' LCD_STR_REFRESH (0x01) + {IV('∼'), '~', 0}, // 223C + {IV('≈'), '~', '='}, // 2248 + {IV('≠'), '!', '='}, // 2260 + {IV('≡'), '=', 0}, // 2261 + {IV('≤'), '<', '='},// 2264, ≤≥ ⩽⩾ + {IV('≥'), '>', '='}, // 2265 + {IV('⏱'), 0x07, 0}, // 23F1, Marlin special: '🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧 ⌚⌛⏰⏱⏳⧖⧗' LCD_STR_CLOCK (0x05) + + {IV('゠'), '=', 0}, // 30A0 + + // ⏰⏱⏲⏳◴◵◶◷ + // ⏻⏼♁♂ + //{IV(''), 0x00, 0}, // Marlin special: '' LCD_STR_BEDTEMP (0x07) + {IV('🌡'), 0x02, 0}, // D83CDF21 Marlin special: '🌡' LCD_STR_THERMOMETER (0x08) + {IV('📂'), 0x05, 0}, // D83DDCC2 Marlin special: '📁📂' LCD_STR_FOLDER (0x02) + //{IV(''), 0x06, 0}, // Marlin special: '' LCD_STR_FEEDRATE (0x06) +}; + +/* return v1 - v2 */ +static int dwin_charmap_compare(dwin_charmap_t *v1, dwin_charmap_t *v2) { + return (v1->uchar < v2->uchar) ? -1 : (v1->uchar > v2->uchar) ? 1 : 0; +} + +static int pf_bsearch_cb_comp_dwinmap_pgm(void *userdata, size_t idx, void * data_pin) { + dwin_charmap_t localval; + dwin_charmap_t *p_dwin_charmap = (dwin_charmap_t *)userdata; + memcpy_P(&localval, p_dwin_charmap + idx, sizeof(localval)); + return dwin_charmap_compare(&localval, (dwin_charmap_t *)data_pin); +} + +extern dwin_font_t dwin_font; + +void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) { + // TODO: Maintain a text cursor position + cursor.x = col * dwin_font.width; + cursor.y = row * dwin_font.height; +} + +inline void lcd_advance_cursor() { cursor.x += dwin_font.width; } + +void lcd_put_int(const int i) { + // TODO: Draw an int at the cursor position, advance the cursor +} + +// return < 0 on error +// return the advanced cols +int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) { + + int ret; + size_t idx = 0; + dwin_charmap_t pinval; + dwin_charmap_t *copy_address = nullptr; + pinval.uchar = c; + pinval.idx = -1; + + //if (max_length < dwin_font.width) return 0; + + uint8_t charsize = dwin_font.width; + + // For 8-bit ASCII just print the single character + char str[] = { '?', 0, 0 }; + if (c < 255) { + str[0] = (char)c; + } + else { + copy_address = nullptr; + ret = pf_bsearch_r((void *)g_dwin_charmap_device, COUNT(g_dwin_charmap_device), pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); + if (ret >= 0) { + copy_address = (dwin_charmap_t*)(g_dwin_charmap_device + idx); + } + else { + ret = pf_bsearch_r((void *)g_dwin_charmap_common, COUNT(g_dwin_charmap_common), pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); + if (ret >= 0) + copy_address = (dwin_charmap_t*)(g_dwin_charmap_common + idx); + } + if (ret >= 0) { + dwin_charmap_t localval; + memcpy_P(&localval, copy_address, sizeof(localval)); + str[0] = localval.idx; + if (max_length >= dwin_font.width * 2 && localval.idx2 > 0) { + charsize += dwin_font.width; + str[1] = localval.idx2; + } + } + } + // Draw the char(s) at the cursor and advance the cursor + DWIN_Draw_String(false, dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, str); + cursor.x += charsize; + return charsize; +} + +/** + * @brief Draw a UTF-8 string + * + * @param utf8_str : the UTF-8 string + * @param cb_read_byte : the callback function to read one byte from the utf8_str (from RAM or ROM) + * @param max_length : the pixel length of the string allowed (or number of slots in HD44780) + * + * @return the number of pixels advanced + * + * Draw a UTF-8 string + */ +static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) { + pixel_len_t ret = 0; + uint8_t *p = (uint8_t *)utf8_str; + while (ret < max_length) { + wchar_t ch = 0; + p = get_utf8_value_cb(p, cb_read_byte, &ch); + if (!ch) break; + ret += lcd_put_wchar_max(ch, max_length - ret); + } + return (int)ret; +} + +int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) { + return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length); +} + +int lcd_put_u8str_max_P(PGM_P utf8_str_P, pixel_len_t max_length) { + return lcd_put_u8str_max_cb(utf8_str_P, read_byte_rom, max_length); +} + +#if ENABLED(DEBUG_LCDPRINT) + + int test_dwin_charmap(dwin_charmap_t *data, size_t size, char *name, char flg_show_contents) { + int ret; + size_t idx = 0; + dwin_charmap_t preval = { 0, 0, 0 }; + dwin_charmap_t pinval = { 0, 0, 0 }; + char flg_error = 0; + + int i; + + TRACE("Test %s\n", name); + + for (i = 0; i < size; i ++) { + memcpy_P(&pinval, &(data[i]), sizeof(pinval)); + + if (flg_show_contents) { + #if 1 + TRACE("[% 4d] % 6" PRIu32 "(0x%04" PRIX32 ") --> 0x%02X,0x%02X%s\n", i, pinval.uchar, pinval.uchar, (unsigned int)(pinval.idx), (unsigned int)(pinval.idx2), (preval.uchar < pinval.uchar?"":" <--- ERROR")); + #else + TRACE("[% 4d]", i); + TRACE("% 6" PRIu32 "(0x%04" PRIX32 "),", pinval.uchar, pinval.uchar); + TRACE("0x%02X,", (unsigned int)(pinval.idx)); + TRACE("0x%02X,", (unsigned int)(pinval.idx2)); + TRACE("%s", (preval.uchar < pinval.uchar?"":" <--- ERROR")); + #endif + } + if (preval.uchar >= pinval.uchar) { + flg_error = 1; + //TRACE("Error: out of order in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + memcpy(&preval, &pinval, sizeof(pinval)); + + ret = pf_bsearch_r((void *)data, size, pf_bsearch_cb_comp_dwinmap_pgm, (void *)&pinval, &idx); + if (ret < 0) { + flg_error = 1; + TRACE("Error: not found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + if (idx != i) { + flg_error = 1; + TRACE("Error: wrong index found item in array %s: idx=%d, val=%d(0x%x)\n", name, i, pinval.uchar, pinval.uchar); + //return -1; + } + } + if (flg_error) { + TRACE("\nError: in array %s\n\n", name); + return -1; + } + TRACE("\nPASS array %s\n\n", name); + return 0; + } + + int test_dwin_charmap_all() { + int flg_error = 0; + if (test_dwin_charmap(g_dwin_charmap_device, COUNT(g_dwin_charmap_device), "g_dwin_charmap_device", 0) < 0) { + flg_error = 1; + test_dwin_charmap(g_dwin_charmap_device, COUNT(g_dwin_charmap_device), "g_dwin_charmap_device", 1); + } + if (test_dwin_charmap(g_dwin_charmap_common, COUNT(g_dwin_charmap_common), "g_dwin_charmap_common", 0) < 0) { + flg_error = 1; + test_dwin_charmap(g_dwin_charmap_common, COUNT(g_dwin_charmap_common), "g_dwin_charmap_common", 1); + } + if (flg_error) { + TRACE("\nFAILED in dwin tests!\n"); + return -1; + } + TRACE("\nPASS in dwin tests.\n"); + return 0; + } + +#endif // DEBUG_LCDPRINT + +#endif // DWIN_MARLINUI_LANDSCAPE || DWIN_MARLINUI_PORTRAIT diff --git a/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.cpp b/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.cpp new file mode 100644 index 000000000000..2408715b68b5 --- /dev/null +++ b/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.cpp @@ -0,0 +1,879 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 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 . + * + */ + +/** + * lcd/dwin/marlin/ultralcd_dwin.cpp + * + * MarlinUI implementation for a Creality DWIN display + * with image at index 0 (0_start.jpg) as the Boot Screen. + */ + +#include "../../../inc/MarlinConfigPre.h" + +#if IS_DWIN_MARLINUI + +#include "ultralcd_dwin.h" +#include "../dwin_lcd.h" + +#include "../../lcdprint.h" +#include "../../fontutils.h" +#include "../../../libs/numtostr.h" +#include "../../marlinui.h" + +#include "../../../sd/cardreader.h" +#include "../../../module/motion.h" +#include "../../../module/temperature.h" +#include "../../../module/printcounter.h" + +#if ENABLED(SDSUPPORT) + #include "../../../libs/duration_t.h" +#endif + +#if ENABLED(AUTO_BED_LEVELING_UBL) + #include "../../../feature/bedlevel/bedlevel.h" +#endif + +//#define DEBUG_OUT 1 +#include "../../../core/debug_out.h" + +#define S(V) (char*)(V) + +// DWIN printing specifies the font on each string operation +// but we'll make the font modal for Marlin +dwin_font_t dwin_font = { font8x16, 8, 16, Color_White, Color_Bg_Black, true }; +void MarlinUI::set_font(const uint8_t font_nr) { + if (font_nr != dwin_font.index) { + dwin_font.index = font_nr; + uint8_t w, h; + switch (font_nr) { + default: + case font6x12: w = 6; h = 12; break; + case font8x16: w = 8; h = 16; break; + case font10x20: w = 10; h = 20; break; + case font12x24: w = 12; h = 24; break; + case font14x28: w = 14; h = 28; break; + case font16x32: w = 16; h = 32; break; + case font20x40: w = 20; h = 40; break; + case font24x48: w = 24; h = 48; break; + case font28x56: w = 28; h = 56; break; + case font32x64: w = 32; h = 64; break; + } + dwin_font.width = w; + dwin_font.height = h; + // TODO: Array with dimensions, auto fit menu items, + // update char width / height of the screen based on + // new (fixed-width) font size. + } +} + +// Since we don't have 'lcd' and 'u8g' objects to help out, +// we'll track the cursor, draw color, etc. ourselves. + +void set_dwin_text_fg(const uint16_t color_ind) { dwin_font.fg = color_ind; } +void set_dwin_text_bg(const uint16_t color_ind) { dwin_font.bg = color_ind; } +void set_dwin_text_solid(const bool solid) { dwin_font.solid = solid; } + +// This display is always detected +bool MarlinUI::detected() { return true; } + +// Initialize or re-initialize the LCD +void MarlinUI::init_lcd() { DWIN_Startup(); } + +// This LCD should clear where it will draw anew +void MarlinUI::clear_lcd() { + DWIN_Frame_Clear(Color_Bg_Black); + DWIN_UpdateLCD(); +} + +#if ENABLED(SHOW_BOOTSCREEN) + + // A Bootscreen will be shown if the DWIN_SET includes + // a startup image. So just show a fake "loading" bar + // with this option. + void MarlinUI::show_bootscreen() { + for (uint16_t t = 0; t <= 100; t += 2) { + // Draw the whole bar each time, but then... + DWIN_ICON_Show(ICON, ICON_Bar, 15, 260); + // ...erase the right end of the bar + DWIN_Draw_Rectangle(1, Color_Bg_Black, 15 + t * 242 / 100, 260, 257, 280); + DWIN_UpdateLCD(); + delay(20); // 50 fps + } + clear_lcd(); + } + +#endif + +// The kill screen is displayed for unrecoverable conditions +void MarlinUI::draw_kill_screen() { + set_font(DWIN_FONT_ALERT); + // TODO: Draw a Red and Yellow Box + // Landscape and Portrait versions centered using current font metrics + DWIN_Draw_String(false,true,DWIN_FONT_ALERT, Popup_Text_Color, Color_Bg_Window, 24, 260, status_message); + DWIN_Draw_String(false,true,DWIN_FONT_ALERT, Popup_Text_Color, Color_Bg_Window, 24, 280, GET_TEXT_F(MSG_HALTED)); + DWIN_Draw_String(false,true,DWIN_FONT_ALERT, Popup_Text_Color, Color_Bg_Window, 24, 300, GET_TEXT_F(MSG_PLEASE_RESET)); + DWIN_UpdateLCD(); +} + +// +// Before homing, blink '123' <-> '???'. +// Homed but unknown... '123' <-> ' '. +// Homed and known, display constantly. +// +FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const bool blink) { + lcd_put_wchar('X' + uint8_t(axis)); + if (blink) + lcd_put_u8str(value); + else { + if (!TEST(axis_homed, axis)) + while (const char c = *value++) lcd_put_wchar(c <= '.' ? c : '?'); + else { + #if NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) + if (!TEST(axis_known_position, axis)) + lcd_put_u8str_P(axis == Z_AXIS ? PSTR(" ") : PSTR(" ")); + else + #endif + lcd_put_u8str(value); + } + } +} + +FORCE_INLINE void _draw_heater_status(const heater_id_t heater, const char prefix, const bool blink) { + #if HAS_HEATED_BED + const bool isBed = heater < 0; + const float t1 = (isBed ? thermalManager.degBed() : thermalManager.degHotend(heater)), + t2 = (isBed ? thermalManager.degTargetBed() : thermalManager.degTargetHotend(heater)); + #else + const float t1 = thermalManager.degHotend(heater), t2 = thermalManager.degTargetHotend(heater); + #endif + + if (prefix >= 0) lcd_put_wchar(prefix); + + lcd_put_u8str(i16tostr3rj(t1 + 0.5)); + lcd_put_wchar('/'); + + #if !HEATER_IDLE_HANDLER + UNUSED(blink); + #else + const bool is_idle = ( + #if HAS_HEATED_BED + isBed ? thermalManager.bed_idle.timed_out : + #endif + thermalManager.hotend_idle[heater].timed_out + ); + + if (!blink && is_idle) { + lcd_put_wchar(' '); + if (t2 >= 10) lcd_put_wchar(' '); + if (t2 >= 100) lcd_put_wchar(' '); + } + else + #endif + lcd_put_u8str(i16tostr3left(t2 + 0.5)); + + if (prefix >= 0) { + lcd_put_wchar('C'); + lcd_put_wchar(' '); + if (t2 < 10) lcd_put_wchar(' '); + } +} + +FORCE_INLINE void _draw_bed_status(const bool blink) { + _draw_heater_status(H_BED, ( + #if HAS_LEVELING + planner.leveling_active && blink ? '_' : + #endif + 'B' + ), + blink + ); +} + +#if HAS_PRINT_PROGRESS + + FORCE_INLINE void _draw_print_progress() { + const uint8_t progress = ui.get_progress_percent(); + lcd_put_u8str_P(PSTR( + #if ENABLED(SDSUPPORT) + "SD" + #elif ENABLED(LCD_SET_PROGRESS_MANUALLY) + "P:" + #endif + )); + if (progress) + lcd_put_u8str(ui8tostr3rj(progress)); + else + lcd_put_u8str_P(PSTR("---")); + lcd_put_wchar('%'); + } + +#endif + +#if ENABLED(LCD_PROGRESS_BAR) + + void MarlinUI::draw_progress_bar(const uint8_t percent) { + // TODO: Draw a bar in the status message area, for now + } + +#endif // LCD_PROGRESS_BAR + +void MarlinUI::draw_status_message(const bool blink) { + + lcd_moveto(0, LCD_HEIGHT - 1); + + #if ENABLED(LCD_PROGRESS_BAR) + + // Draw the progress bar if the message has shown long enough + // or if there is no message set. + if (ELAPSED(millis(), progress_bar_ms + PROGRESS_BAR_MSG_TIME) || !has_status()) { + const uint8_t progress = get_progress_percent(); + if (progress > 2) return draw_progress_bar(progress); + } + + #elif BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT) + + // Alternate Status message and Filament display + if (ELAPSED(millis(), next_filament_display)) { + lcd_put_u8str_P(PSTR("Dia ")); + lcd_put_u8str(ftostr12ns(filwidth.measured_mm)); + lcd_put_u8str_P(PSTR(" V")); + lcd_put_u8str(i16tostr3rj(planner.volumetric_percent(parser.volumetric_enabled))); + lcd_put_wchar('%'); + return; + } + + #endif // FILAMENT_LCD_DISPLAY && SDSUPPORT + + #if ENABLED(STATUS_MESSAGE_SCROLLING) + static bool last_blink = false; + + // Get the UTF8 character count of the string + uint8_t slen = utf8_strlen(status_message); + + // If the string fits into the LCD, just print it and do not scroll it + if (slen <= LCD_WIDTH) { + + // The string isn't scrolling and may not fill the screen + lcd_put_u8str(status_message); + + // Fill the rest with spaces + while (slen < LCD_WIDTH) { lcd_put_wchar(' '); ++slen; } + } + else { + // String is larger than the available space in screen. + + // Get a pointer to the next valid UTF8 character + // and the string remaining length + uint8_t rlen; + const char *stat = status_and_len(rlen); + lcd_put_u8str_max(stat, LCD_WIDTH); // The string leaves space + + // If the remaining string doesn't completely fill the screen + if (rlen < LCD_WIDTH) { + lcd_put_wchar('.'); // Always at 1+ spaces left, draw a dot + uint8_t chars = LCD_WIDTH - rlen; // Amount of space left in characters + if (--chars) { // Draw a second dot if there's space + lcd_put_wchar('.'); + if (--chars) + lcd_put_u8str_max(status_message, chars); // Print a second copy of the message + } + } + if (last_blink != blink) { + last_blink = blink; + advance_status_scroll(); + } + } + #else + UNUSED(blink); + + // Get the UTF8 character count of the string + uint8_t slen = utf8_strlen(status_message); + + // Just print the string to the LCD + lcd_put_u8str_max(status_message, LCD_WIDTH); + + // Fill the rest with spaces if there are missing spaces + while (slen < LCD_WIDTH) { + lcd_put_wchar(' '); + ++slen; + } + #endif +} + +/** + * LCD_INFO_SCREEN_STYLE 0 : Classic Status Screen + * + * 16x2 |000/000 B000/000| + * |0123456789012345| + * + * 16x4 |000/000 B000/000| + * |SD---% Z 000.00| + * |F---% T--:--| + * |0123456789012345| + * + * 20x2 |T000/000° B000/000° | + * |01234567890123456789| + * + * 20x4 |T000/000° B000/000° | + * |X 000 Y 000 Z000.000| + * |F---% SD---% T--:--| + * |01234567890123456789| + * + * LCD_INFO_SCREEN_STYLE 1 : Průša-style Status Screen + * + * |T000/000° Z 000.00 | + * |B000/000° F---% | + * |SD---% T--:-- | + * |01234567890123456789| + * + * |T000/000° Z 000.00 | + * |T000/000° F---% | + * |B000/000° SD---% | + * |01234567890123456789| + */ + +void MarlinUI::draw_status_screen() { + + DWIN_Frame_Clear(Color_Bg_Window); + + const bool blink = get_blink(); + + ui.set_font(DWIN_FONT_MENU); + + lcd_moveto(0, 0); + + #if LCD_INFO_SCREEN_STYLE == 0 + + // ========== Line 1 ========== + + // + // Hotend 0 Temperature + // + _draw_heater_status(H_E0, 'T', blink); + + // + // Hotend 1 or Bed Temperature + // + #if HAS_MULTI_HOTEND + lcd_moveto(10, 0); + _draw_heater_status(H_E1, 'T', blink); + #elif HAS_HEATED_BED + lcd_moveto(10, 0); + _draw_bed_status(blink); + #endif + + // ========== Line 2 ========== + + lcd_moveto(0, 1); + + // If the first line has two extruder temps, + // show more temperatures on the next line + + #if HOTENDS > 2 || (HAS_MULTI_HOTEND && HAS_HEATED_BED) + + #if HOTENDS > 2 + _draw_heater_status(H_E2, 'T', blink); + lcd_moveto(10, 1); + #endif + + _draw_bed_status(blink); + + #else // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED) + + #if HAS_DUAL_MIXING + + // Two-component mix / gradient instead of XY + + char mixer_messages[12]; + const char *mix_label; + #if ENABLED(GRADIENT_MIX) + if (mixer.gradient.enabled) { + mixer.update_mix_from_gradient(); + mix_label = "Gr"; + } + else + #endif + { + mixer.update_mix_from_vtool(); + mix_label = "Mx"; + } + sprintf_P(mixer_messages, PSTR("%s %d;%d%% "), mix_label, int(mixer.mix[0]), int(mixer.mix[1])); + lcd_put_u8str(mixer_messages); + + #else // !HAS_DUAL_MIXING + + const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE); + + if (show_e_total) { + #if ENABLED(LCD_SHOW_E_TOTAL) + char tmp[20]; + const uint8_t escale = e_move_accumulator >= 100000.0f ? 10 : 1; // After 100m switch to cm + sprintf_P(tmp, PSTR("E %ld%cm "), uint32_t(_MAX(e_move_accumulator, 0.0f)) / escale, escale == 10 ? 'c' : 'm'); // 1234567mm + lcd_put_u8str(tmp); + #endif + } + else { + const xy_pos_t lpos = current_position.asLogical(); + _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); + lcd_put_wchar(' '); + _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); + } + + #endif // !HAS_DUAL_MIXING + + #endif // HOTENDS <= 2 && (HOTENDS <= 1 || !HAS_HEATED_BED) + + lcd_moveto(LCD_WIDTH - 8, 1); + _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink); + + #if HAS_LEVELING && !HAS_HEATED_BED + lcd_put_wchar(planner.leveling_active || blink ? '_' : ' '); + #endif + + // ========== Line 3 ========== + + lcd_put_wchar(0, 2, 'F'); + lcd_put_u8str(i16tostr3rj(feedrate_percentage)); + lcd_put_wchar('%'); + + char buffer[14]; + duration_t elapsed = print_job_timer.duration(); + const uint8_t len = elapsed.toDigital(buffer), + timepos = LCD_WIDTH - len - 1; + lcd_put_wchar(timepos, 2, 'C'); + lcd_put_u8str(buffer); + + lcd_moveto(timepos - 7, 2); + #if HAS_PRINT_PROGRESS + _draw_print_progress(); + #else + char c; + uint16_t per; + #if HAS_FAN0 + if (true + #if EXTRUDERS && ENABLED(ADAPTIVE_FAN_SLOWING) + && (blink || thermalManager.fan_speed_scaler[0] < 128) + #endif + ) { + uint16_t spd = thermalManager.fan_speed[0]; + if (blink) c = 'F'; + #if ENABLED(ADAPTIVE_FAN_SLOWING) + else { c = '*'; spd = thermalManager.scaledFanSpeed(0, spd); } + #endif + per = thermalManager.fanPercent(spd); + } + else + #endif + { + #if EXTRUDERS + c = 'E'; + per = planner.flow_percentage[0]; + #endif + } + lcd_put_wchar(c); + lcd_put_u8str(i16tostr3rj(per)); + lcd_put_wchar('%'); + #endif + + #elif LCD_INFO_SCREEN_STYLE == 1 + + // ========== Line 1 ========== + + // + // Hotend 0 Temperature + // + _draw_heater_status(H_E0, 'T', blink); + + // + // Z Coordinate + // + lcd_moveto(LCD_WIDTH - 9, 0); + _draw_axis_value(Z_AXIS, ftostr52sp(LOGICAL_Z_POSITION(current_position.z)), blink); + + #if HAS_LEVELING && (HAS_MULTI_HOTEND || !HAS_HEATED_BED) + lcd_put_wchar(LCD_WIDTH - 1, 0, planner.leveling_active || blink ? '_' : ' '); + #endif + + // ========== Line 2 ========== + + // + // Hotend 1 or Bed Temperature + // + lcd_moveto(0, 1); + #if HAS_MULTI_HOTEND + _draw_heater_status(H_E1, 'T', blink); + #elif HAS_HEATED_BED + _draw_bed_status(blink); + #endif + + lcd_put_wchar(LCD_WIDTH - 9, 1, 'F'); + lcd_put_u8str(i16tostr3rj(feedrate_percentage)); + lcd_put_wchar('%'); + + // ========== Line 3 ========== + + // + // SD Percent, Hotend 2, or Bed + // + lcd_moveto(0, 2); + #if HOTENDS > 2 + _draw_heater_status(H_E2, 'T', blink); + #elif HAS_MULTI_HOTEND && HAS_HEATED_BED + _draw_bed_status(blink); + #elif HAS_PRINT_PROGRESS + #define DREW_PRINT_PROGRESS + _draw_print_progress(); + #endif + + // + // Elapsed Time or SD Percent + // + lcd_moveto(LCD_WIDTH - 9, 2); + #if HAS_PRINT_PROGRESS && !defined(DREW_PRINT_PROGRESS) + _draw_print_progress(); + #else + duration_t elapsed = print_job_timer.duration(); + char buffer[14]; + (void)elapsed.toDigital(buffer); + lcd_put_wchar('C'); + lcd_put_u8str(buffer); + #endif + + #endif // LCD_INFO_SCREEN_STYLE 1 + + // ========= Last Line ======== + + // + // Status Message (which may be a Progress Bar or Filament display) + // + draw_status_message(blink); + + //DWIN_UpdateLCD(); +} + +#if HAS_LCD_MENU + + #include "../../menu/menu.h" + + dwin_coord_t row_y1, row_y2; + + #if ENABLED(ADVANCED_PAUSE_FEATURE) + + void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) { + // TODO: Erase the background where these elements will be drawn + row_y1 = row * (MENU_FONT_HEIGHT) + 1; + row_y2 = row_y1 + MENU_FONT_HEIGHT - 1; + + lcd_put_wchar(DWIN_WIDTH - 11 * (MENU_FONT_WIDTH), row_y2, 'E'); + lcd_put_wchar((char)('1' + extruder)); + lcd_put_wchar(' '); + lcd_put_u8str(i16tostr3rj(thermalManager.degHotend(extruder))); + lcd_put_wchar('/'); + + if (get_blink() || !thermalManager.hotend_idle[extruder].timed_out) + lcd_put_u8str(i16tostr3rj(thermalManager.degTargetHotend(extruder))); + } + + #endif // ADVANCED_PAUSE_FEATURE + + // Set the colors for a menu item based on whether it is selected + static bool mark_as_selected(const uint8_t row, const bool sel) { + row_y1 = row * (MENU_FONT_HEIGHT) + 1; + row_y2 = row_y1 + MENU_FONT_HEIGHT - 1; + lcd_moveto(0, row_y2); + if (row_y1 >= LCD_PIXEL_HEIGHT) return false; + + if (sel) { + #if ENABLED(MENU_HOLLOW_FRAME) + DWIN_Draw_HLine(Select_Color, 0, row_y1 + 1, DWIN_WIDTH); + DWIN_Draw_HLine(Select_Color, 0, row_y2 + 2, DWIN_WIDTH); + #else + DWIN_Draw_Box(1, Select_Color, 0, row_y1 + 2, DWIN_WIDTH, MENU_FONT_HEIGHT - 1); + #endif + } + return true; + } + + // Draw a static line of text in the same idiom as a menu item + void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) { + + // TODO: Return if the row to draw is off-screen + // Menus may deal with this for us. + + //const uint8_t old_bkgd = dwin_font.bg; + //set_dwin_text_bg((style & SS_INVERT) ? Select_Color : Color_Bg_Black); + + // Call mark_as_selected to draw a bigger selection box + // and draw the text without a background + + if (mark_as_selected(row, (bool)(style & SS_INVERT))) { + + pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed + + const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0, + vlen = vstr ? utf8_strlen(vstr) : 0; + if (style & SS_CENTER) { + int8_t pad = (LCD_WIDTH - plen - vlen) / 2; + while (--pad >= 0) n -= lcd_put_wchar(' '); + } + + if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH); + if (vlen) n -= lcd_put_u8str_max(vstr, n); + while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); + } + + //set_dwin_text_bg(old_bkgd); + } + + // Draw a generic menu item + void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) { + + // TODO: Exit if the row is off-screen + + //set_dwin_text_bg(sel ? Select_Color : Color_Bg_Black); + if (mark_as_selected(row, sel)) { + pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH); + while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); + lcd_put_wchar(DWIN_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char); + lcd_put_wchar(' '); + } + } + + // Draw a menu item with an editable value + void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) { + if (mark_as_selected(row, sel)) { + const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen((char*)data)); + //dwin_coord_t n = lcd_put_u8str_ind_P(pstr, itemIndex, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH); + pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen) * (MENU_FONT_WIDTH); + if (vallen) { + lcd_put_wchar(':'); + while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); + lcd_moveto(DWIN_WIDTH - (MENU_FONT_WIDTH)*vallen, row_y2); + if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str((char*)data); + } + } + } + + void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) { + ui.encoder_direction_normal(); + + const dwin_coord_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value); + bool extra_row = labellen > LCD_WIDTH - 2 - vallen; + + #if ENABLED(USE_BIG_EDIT_FONT) + // Use the menu font if the label won't fit on a single line + constexpr dwin_coord_t lcd_edit_width = (DWIN_WIDTH) / (EDIT_FONT_WIDTH); + dwin_coord_t lcd_chr_fit, one_chr_width; + if (labellen <= lcd_edit_width - 1) { + if (labellen + vallen + 1 > lcd_edit_width) + extra_row = true; + lcd_chr_fit = lcd_edit_width + 1; + one_chr_width = EDIT_FONT_WIDTH; + ui.set_font(FONT_EDIT); + } + else { + lcd_chr_fit = LCD_WIDTH; + one_chr_width = MENU_FONT_WIDTH; + ui.set_font(DWIN_FONT_MENU); + } + #else + constexpr dwin_coord_t lcd_chr_fit = LCD_WIDTH, + one_chr_width = MENU_FONT_WIDTH; + #endif + + // Center the label and value lines on the middle line + dwin_coord_t baseline = extra_row ? (DWIN_HEIGHT) / 2 - 1 + : (DWIN_HEIGHT + EDIT_FONT_ASCENT) / 2; + + // Assume the label is alpha-numeric (with a descender) + lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex); + + // If a value is included, print a colon, then print the value right-justified + if (value != nullptr) { + lcd_put_wchar(':'); + if (extra_row) { + // Assume that value is numeric (with no descender) + baseline += EDIT_FONT_ASCENT + 2; + } + lcd_put_wchar(((lcd_chr_fit - 1) - (vallen + 1)) * one_chr_width, baseline, ' '); // Right-justified, padded, add a leading space + lcd_put_u8str(value); + } + } + + inline void draw_boxed_string(const dwin_coord_t x, const dwin_coord_t y, PGM_P const pstr, const bool inv) { + const dwin_coord_t len = utf8_strlen_P(pstr), bw = len * (MENU_FONT_WIDTH), + bx = x * (MENU_FONT_WIDTH), by = (y + 1) * (MENU_FONT_HEIGHT); + if (inv) { + DWIN_Draw_Box(1, Select_Color, bx - 1, by - (MENU_FONT_ASCENT) + 1, bw + 2, MENU_FONT_HEIGHT - 1); + set_dwin_text_fg(Color_Bg_Black); + } + lcd_put_u8str_P(bx, by, pstr); + if (inv) set_dwin_text_fg(Color_White); + } + + void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) { + ui.draw_select_screen_prompt(pref, string, suff); + draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno); + draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) + 1), LCD_HEIGHT - 1, yes, yesno); + } + + #if ENABLED(SDSUPPORT) + + void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) { + if (mark_as_selected(row, sel)) { + #if 0 + // TODO: Draw a folder icon (poly) + if (isDir) lcd_put_wchar('F'); + constexpr uint8_t maxlen = LCD_WIDTH - 1; + const dwin_coord_t pixw = maxlen * (MENU_FONT_WIDTH); + dwin_coord_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw); + while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' '); + #endif + } + } + + #endif // SDSUPPORT + + #if ENABLED(AUTO_BED_LEVELING_UBL) + + /** + * UBL LCD "radar" map data + */ + #define MAP_UPPER_LEFT_CORNER_X 35 // These probably should be moved to the .h file But for now, + #define MAP_UPPER_LEFT_CORNER_Y 8 // it is easier to play with things having them here + #define MAP_MAX_PIXELS_X 53 + #define MAP_MAX_PIXELS_Y 49 + + void MarlinUI::ubl_plot(const uint8_t x_plot, const uint8_t y_plot) { + // Scale the box pixels appropriately + dwin_coord_t x_map_pixels = ((MAP_MAX_PIXELS_X - 4) / (GRID_MAX_POINTS_X)) * (GRID_MAX_POINTS_X), + y_map_pixels = ((MAP_MAX_PIXELS_Y - 4) / (GRID_MAX_POINTS_Y)) * (GRID_MAX_POINTS_Y), + + pixels_per_x_mesh_pnt = x_map_pixels / (GRID_MAX_POINTS_X), + pixels_per_y_mesh_pnt = y_map_pixels / (GRID_MAX_POINTS_Y), + + x_offset = MAP_UPPER_LEFT_CORNER_X + 1 + (MAP_MAX_PIXELS_X - x_map_pixels - 2) / 2, + y_offset = MAP_UPPER_LEFT_CORNER_Y + 1 + (MAP_MAX_PIXELS_Y - y_map_pixels - 2) / 2; + + #if 0 + + // Clear the Mesh Map + + set_dwin_text_fg(Color_White); // First draw the bigger box in White so we have a border around the mesh map box + u8g.drawBox(x_offset - 2, y_offset - 2, x_map_pixels + 4, y_map_pixels + 4); + set_dwin_text_fg(Color_Bg_Black); // Now actually clear the mesh map box + u8g.drawBox(x_offset, y_offset, x_map_pixels, y_map_pixels); + + // Display Mesh Point Locations + + set_dwin_text_fg(Color_White); + const dwin_coord_t sx = x_offset + pixels_per_x_mesh_pnt / 2; + dwin_coord_t y = y_offset + pixels_per_y_mesh_pnt / 2; + for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++, y += pixels_per_y_mesh_pnt) + for (uint8_t i = 0, x = sx; i < GRID_MAX_POINTS_X; i++, x += pixels_per_x_mesh_pnt) + u8g.drawBox(x, y, 1, 1); + + // Fill in the Specified Mesh Point + + const uint8_t y_plot_inv = (GRID_MAX_POINTS_Y - 1) - y_plot; // The origin is typically in the lower right corner. We need to + // invert the Y to get it to plot in the right location. + + const dwin_coord_t by = y_offset + y_plot_inv * pixels_per_y_mesh_pnt; + u8g.drawBox( + x_offset + x_plot * pixels_per_x_mesh_pnt, by, + pixels_per_x_mesh_pnt, pixels_per_y_mesh_pnt + ); + + // Put Relevant Text on Display + + // Show X and Y positions at top of screen + set_dwin_text_fg(Color_White); + const xy_pos_t pos = { ubl.mesh_index_to_xpos(x_plot), ubl.mesh_index_to_ypos(y_plot) }, + lpos = pos.asLogical(); + lcd_put_u8str_P(5, 7, X_LBL); + lcd_put_u8str(ftostr52(lpos.x)); + lcd_put_u8str_P(74, 7, Y_LBL); + lcd_put_u8str(ftostr52(lpos.y)); + + // Print plot position + lcd_put_wchar(5, DWIN_HEIGHT, '('); + u8g.print(x_plot); + lcd_put_wchar(','); + u8g.print(y_plot); + lcd_put_wchar(')'); + + // Show the location value + lcd_put_u8str_P(74, DWIN_HEIGHT, Z_LBL); + if (!isnan(ubl.z_values[x_plot][y_plot])) + lcd_put_u8str(ftostr43sign(ubl.z_values[x_plot][y_plot])); + else + lcd_put_u8str_P(PSTR(" -----")); + #endif + } + + #endif // AUTO_BED_LEVELING_UBL + + #if EITHER(BABYSTEP_ZPROBE_GFX_OVERLAY, MESH_EDIT_GFX_OVERLAY) + + // cw_bmp = DWIN_BITMAP_CLOCKWISE; + // ccw_bmp = DWIN_BITMAP_COUNTERCLOCKWISE; + // up_arrow_bmp = DWIN_UP_ARROW; + // down_arrow_bmp = DWIN_DOWN_ARROW; + // offset_bedline_bmp = DWIN_BEDLINE; + // nozzle_bmp = DWIN_NOZZLE; + + void _lcd_zoffset_overlay_gfx(const float zvalue) { + // Determine whether the user is raising or lowering the nozzle. + static int8_t dir; + static float old_zvalue; + if (zvalue != old_zvalue) { + dir = zvalue ? zvalue < old_zvalue ? -1 : 1 : 0; + old_zvalue = zvalue; + } + + #if 0 + const unsigned char *rot_up = TERN(OVERLAY_GFX_REVERSE, ccw_bmp, cw_bmp), + *rot_down = TERN(OVERLAY_GFX_REVERSE, cw_bmp, ccw_bmp); + + #if ENABLED(USE_BIG_EDIT_FONT) + const int left = 0, right = 45, nozzle = 95; + #else + const int left = 5, right = 90, nozzle = 60; + #endif + + // Draw a representation of the nozzle + u8g.drawBitmapP(nozzle + 6, 4 - dir, 2, 12, nozzle_bmp); + u8g.drawBitmapP(nozzle + 0, 20, 3, 1, offset_bedline_bmp); + + // Draw cw/ccw indicator and up/down arrows. + u8g.drawBitmapP(right + 0, 48 - dir, 2, 13, up_arrow_bmp); + u8g.drawBitmapP(left + 0, 49 - dir, 2, 13, down_arrow_bmp); + u8g.drawBitmapP(left + 13, 47, 3, 16, rot_down); + u8g.drawBitmapP(right + 13, 47, 3, 16, rot_up); + #endif + } + + #endif // BABYSTEP_ZPROBE_GFX_OVERLAY || MESH_EDIT_GFX_OVERLAY + +#endif // HAS_LCD_MENU + +#endif // DWIN_MARLINUI_PORTRAIT diff --git a/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.h b/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.h new file mode 100644 index 000000000000..cd414a5f3327 --- /dev/null +++ b/Marlin/src/lcd/dwin/marlin/ultralcd_dwin.h @@ -0,0 +1,100 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 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 . + * + */ +#pragma once + +/** + * lcd/dwin/marlin/lcdprint_dwin.h + */ + +#include "../../../inc/MarlinConfigPre.h" +#include "../dwin_lcd.h" + +typedef uint16_t dwin_coord_t; // Screen can be pretty big +typedef uint16_t lcd_uint_t; +typedef int16_t lcd_int_t; + +typedef struct { + uint8_t index, width, height; + uint16_t fg, bg; + bool solid; +} dwin_font_t; + +extern dwin_font_t dwin_font; + +// Only Western languages support big / small fonts +//#if DISABLED(DISPLAY_CHARSET_ISO10646_1) +// #undef USE_BIG_EDIT_FONT +// #undef USE_SMALL_INFOFONT +//#endif + +#if ENABLED(USE_BIG_EDIT_FONT) + #define DWIN_FONT_EDIT font10x20 +#else + #define DWIN_FONT_EDIT font8x16 +#endif + +#define DWIN_FONT_INFO font8x16 + +#if DWIN_FONT_MENU == font6x12 + #define MENU_FONT_WIDTH 6 + #define MENU_FONT_ASCENT 10 + #define MENU_FONT_DESCENT 2 +#elif DWIN_FONT_MENU == font8x16 + #define MENU_FONT_WIDTH 8 + #define MENU_FONT_ASCENT 13 + #define MENU_FONT_DESCENT 3 +#elif DWIN_FONT_MENU == font10x20 + #define MENU_FONT_WIDTH 10 + #define MENU_FONT_ASCENT 16 + #define MENU_FONT_DESCENT 4 +#endif +#define MENU_FONT_HEIGHT (MENU_FONT_ASCENT + MENU_FONT_DESCENT) + +#if DWIN_FONT_EDIT == font6x12 + #define EDIT_FONT_WIDTH 6 + #define EDIT_FONT_ASCENT 10 + #define EDIT_FONT_DESCENT 2 +#elif DWIN_FONT_EDIT == font8x16 + #define EDIT_FONT_WIDTH 8 + #define EDIT_FONT_ASCENT 13 + #define EDIT_FONT_DESCENT 3 +#elif DWIN_FONT_EDIT == font10x20 + #define EDIT_FONT_WIDTH 10 + #define EDIT_FONT_ASCENT 16 + #define EDIT_FONT_DESCENT 4 +#endif +#define EDIT_FONT_HEIGHT (EDIT_FONT_ASCENT + EDIT_FONT_DESCENT) + +#if DWIN_FONT_INFO == font6x12 + #define INFO_FONT_WIDTH 6 + #define INFO_FONT_ASCENT 10 + #define INFO_FONT_DESCENT 2 +#elif DWIN_FONT_INFO == font8x16 + #define INFO_FONT_WIDTH 8 + #define INFO_FONT_ASCENT 13 + #define INFO_FONT_DESCENT 3 +#elif DWIN_FONT_INFO == font10x20 + #define INFO_FONT_WIDTH 10 + #define INFO_FONT_ASCENT 16 + #define INFO_FONT_DESCENT 4 +#endif +#define INFO_FONT_HEIGHT (INFO_FONT_ASCENT + INFO_FONT_DESCENT) diff --git a/Marlin/src/lcd/lcdprint.h b/Marlin/src/lcd/lcdprint.h index cf34a7ade92e..5a954eaffa30 100644 --- a/Marlin/src/lcd/lcdprint.h +++ b/Marlin/src/lcd/lcdprint.h @@ -79,6 +79,18 @@ #define SETCURSOR(col, row) lcd_moveto((col) * (MENU_FONT_WIDTH), ((row) + 1) * (MENU_FONT_HEIGHT)) #define SETCURSOR_RJ(len, row) lcd_moveto(LCD_PIXEL_WIDTH - (len) * (MENU_FONT_WIDTH), ((row) + 1) * (MENU_FONT_HEIGHT)) +#elif IS_DWIN_MARLINUI + + #include "dwin/marlin/ultralcd_dwin.h" + + #define LCD_PIXEL_WIDTH DWIN_WIDTH + #define LCD_PIXEL_HEIGHT DWIN_HEIGHT + #define LCD_WIDTH ((LCD_PIXEL_WIDTH) / (MENU_FONT_WIDTH)) + #define LCD_HEIGHT ((LCD_PIXEL_HEIGHT) / (MENU_FONT_HEIGHT)) + + #define SETCURSOR(col, row) lcd_moveto(col, row) + #define SETCURSOR_RJ(len, row) SETCURSOR(LCD_WIDTH - (len), row) + #else #define _UxGT(a) a diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp index 487678eccfc1..5f3a1fd8cfbc 100644 --- a/Marlin/src/lcd/marlinui.cpp +++ b/Marlin/src/lcd/marlinui.cpp @@ -1049,6 +1049,9 @@ void MarlinUI::update() { run_current_screen(); + // Apply all DWIN drawing after processing + TERN_(IS_DWIN_MARLINUI, DWIN_UpdateLCD()); + #endif TERN_(HAS_LCD_MENU, lcd_clicked = false); diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h index bf9e47e0c845..32c5e036ee7e 100644 --- a/Marlin/src/lcd/marlinui.h +++ b/Marlin/src/lcd/marlinui.h @@ -408,7 +408,13 @@ class MarlinUI { #else - static void set_custom_characters(const HD44780CharSet screen_charset=CHARSET_INFO); + #if IS_DWIN_MARLINUI + static void set_font(const uint8_t font_nr); + #endif + + #if HAS_MARLINUI_HD44780 + static void set_custom_characters(const HD44780CharSet screen_charset=CHARSET_INFO); + #endif #if ENABLED(LCD_PROGRESS_BAR) static millis_t progress_bar_ms; // Start time for the current progress bar cycle diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h index eb910dd8466e..0caa8c1deb1f 100644 --- a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h @@ -183,7 +183,7 @@ #define BTN_EN1 PB10 #define BTN_EN2 PA6 -#elif ENABLED(DWIN_CREALITY_LCD) +#elif ANY(DWIN_CREALITY_LCD, DWIN_MARLINUI_PORTRAIT, DWIN_MARLINUI_LANDSCAPE) // RET6 DWIN ENCODER LCD #define BTN_ENC PB14 diff --git a/platformio.ini b/platformio.ini index 326dca172ff5..ac92c7766df9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,7 +26,8 @@ include_dir = Marlin # [common] default_src_filter = + - - + - - - - - - - + - - - - - + - - - - - - - - - @@ -230,8 +231,10 @@ HAS_MARLINUI_U8GLIB = U8glib-HAL@~0.4.1 HAS_(FSMC|SPI)_TFT = src_filter=+ + + HAS_FSMC_TFT = src_filter=+ + HAS_SPI_TFT = src_filter=+ + +DWIN_.+ = src_filter=+ +DWIN_CREALITY_LCD = src_filter=+ +DWIN_MARLINUI_.+ = src_filter=+ HAS_GRAPHICAL_TFT = src_filter=+ -DWIN_CREALITY_LCD = src_filter=+ IS_TFTGLCD_PANEL = src_filter=+ HAS_TOUCH_XPT2046 = src_filter=+ HAS_LCD_MENU = src_filter=+ From 9bc90e7d6f308a3801979118ecbfc572f50e13cc Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 19 Sep 2020 07:44:19 -0500 Subject: [PATCH 2/4] Tests --- buildroot/tests/STM32F103RET6_creality-tests | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/buildroot/tests/STM32F103RET6_creality-tests b/buildroot/tests/STM32F103RET6_creality-tests index ca723c7aa229..9af243cdc145 100644 --- a/buildroot/tests/STM32F103RET6_creality-tests +++ b/buildroot/tests/STM32F103RET6_creality-tests @@ -7,10 +7,17 @@ set -e # -# Build with configs included in the PR +# Build with Ender-3 V2 configs # use_example_configs "Creality/Ender-3 V2" +exec_test $1 $2 "Ender 3 v2 with Stock UI" + +# +# Build with Ender-3 V2 configs but with MarlinUI +# +opt_disable DWIN_CREALITY_LCD +opt_add DWIN_MARLINUI_PORTRAIT opt_enable MARLIN_DEV_MODE -exec_test $1 $2 "Ender 3 v2" +exec_test $1 $2 "Ender 3 v2 with MarlinUI" restore_configs From c6f92c402f73bb54a67f2ebd69ce7e47bc1971f1 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sat, 19 Sep 2020 07:44:31 -0500 Subject: [PATCH 3/4] Debug environment --- Marlin/src/pins/pins.h | 4 ++-- platformio.ini | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 3a380def74f5..53d832193110 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -574,9 +574,9 @@ #elif MB(CHITU3D_V6) #include "stm32f1/pins_CHITU3D_V6.h" // STM32F1 env:chitu_f103 #elif MB(CREALITY_V4) - #include "stm32f1/pins_CREALITY_V4.h" // STM32F1 env:STM32F103RET6_creality + #include "stm32f1/pins_CREALITY_V4.h" // STM32F1 env:STM32F103RET6_creality env:STM32F103RET6_creality_debug #elif MB(CREALITY_V427) - #include "stm32f1/pins_CREALITY_V427.h" // STM32F1 env:STM32F103RET6_creality + #include "stm32f1/pins_CREALITY_V427.h" // STM32F1 env:STM32F103RET6_creality env:STM32F103RET6_creality_debug #elif MB(TRIGORILLA_PRO) #include "stm32f1/pins_TRIGORILLA_PRO.h" // STM32F1 env:trigorilla_pro #elif MB(FLY_MINI) diff --git a/platformio.ini b/platformio.ini index ac92c7766df9..50ca6076fa02 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1136,6 +1136,12 @@ debug_tool = jlink upload_protocol = jlink monitor_speed = 115200 +[env:STM32F103RET6_creality_debug] +platform = ${env:STM32F103RET6_creality.platform} +extends = env:STM32F103RET6_creality +debug_tool = stlink +upload_protocol = dfu + # # FLSUN QQ (STM32F103VET6) # From 1b3e91509bbb9ed777bf5399c014f59a36b77831 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 23 Oct 2020 01:05:47 -0500 Subject: [PATCH 4/4] Add pins for CR-6 SE --- Marlin/src/core/boards.h | 7 +- Marlin/src/pins/pins.h | 2 + .../src/pins/stm32f1/pins_CREALITY_CR_6_SE.h | 170 ++++++++++++++++++ Marlin/src/pins/stm32f1/pins_CREALITY_V4.h | 4 +- 4 files changed, 178 insertions(+), 5 deletions(-) create mode 100644 Marlin/src/pins/stm32f1/pins_CREALITY_CR_6_SE.h diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index e11590334299..62d88aaeec64 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -323,9 +323,10 @@ #define BOARD_CHITU3D_V6 4034 // Chitu3D TronXY X5SA V5 Board #define BOARD_CREALITY_V4 4035 // Creality v4.x (STM32F103RE) #define BOARD_CREALITY_V427 4036 // Creality v4.2.7 (STM32F103RE) -#define BOARD_TRIGORILLA_PRO 4037 // Trigorilla Pro (STM32F103ZET6) -#define BOARD_FLY_MINI 4038 // FLY MINI (STM32F103RCT6) -#define BOARD_FLSUN_HISPEED 4039 // FLSUN HiSpeedV1 (STM32F103VET6) +#define BOARD_CREALITY_CR_6_SE 4037 // Creality v4.5.2 (STM32F103??) +#define BOARD_TRIGORILLA_PRO 4038 // Trigorilla Pro (STM32F103ZET6) +#define BOARD_FLY_MINI 4039 // FLY MINI (STM32F103RCT6) +#define BOARD_FLSUN_HISPEED 4040 // FLSUN HiSpeedV1 (STM32F103VET6) // // ARM Cortex-M4F diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index 53d832193110..37b226539787 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -575,6 +575,8 @@ #include "stm32f1/pins_CHITU3D_V6.h" // STM32F1 env:chitu_f103 #elif MB(CREALITY_V4) #include "stm32f1/pins_CREALITY_V4.h" // STM32F1 env:STM32F103RET6_creality env:STM32F103RET6_creality_debug +#elif MB(CREALITY_CR_6_SE) + #include "stm32f1/pins_CREALITY_CR_6_SE.h" // STM32F1 env:STM32F103RET6_creality env:STM32F103RET6_creality_debug #elif MB(CREALITY_V427) #include "stm32f1/pins_CREALITY_V427.h" // STM32F1 env:STM32F103RET6_creality env:STM32F103RET6_creality_debug #elif MB(TRIGORILLA_PRO) diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_CR_6_SE.h b/Marlin/src/pins/stm32f1/pins_CREALITY_CR_6_SE.h new file mode 100644 index 000000000000..ad6d5b579428 --- /dev/null +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_CR_6_SE.h @@ -0,0 +1,170 @@ +/** + * 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 . + * + */ + +/** + * CREALITY (STM32F103) board pin assignments + */ + +#if NOT_TARGET(__STM32F1__) + #error "Oops! Select an STM32F1 board in 'Tools > Board.'" +#endif + +#if HOTENDS > 1 || E_STEPPERS > 1 + #error "CREALITY supports up to 1 hotends / E-steppers. Comment out this line to continue." +#endif + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "Creality CR-6 SE" +#endif +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "CR-6 SE" +#endif + +// +// EEPROM +// +#if NO_EEPROM_SELECTED + // FLASH + //#define FLASH_EEPROM_EMULATION + + // I2C + //#define I2C_EEPROM + //#define E2END 0x3FFF // 16Kb (24c16) + + // BL24C16 + #define IIC_BL24CXX_EEPROM // EEPROM on I2C-0 + #if ENABLED(IIC_BL24CXX_EEPROM) + #define IIC_EEPROM_SDA PA11 + #define IIC_EEPROM_SCL PA12 + #define MARLIN_EEPROM_SIZE 0x800 // 2Kb (24C16) + #else + #define SDCARD_EEPROM_EMULATION // SD EEPROM until all EEPROM is BL24CXX + #define MARLIN_EEPROM_SIZE 0x800 // 2Kb + #endif + + // SPI + //#define SPI_EEPROM // EEPROM on SPI-0 + //#define SPI_CHAN_EEPROM1 ? + //#define SPI_EEPROM1_CS ? + + // 2K EEPROM + //#define SPI_EEPROM2_CS ? + + // 32Mb FLASH + //#define SPI_FLASH_CS ? +#endif + +// +// Servos +// +#define SERVO0_PIN PB0 // BLTouch OUT + +// +// Limit Switches +// +#define X_STOP_PIN PC4 +#define Y_STOP_PIN PC5 + +#ifdef BLTOUCH + #define Z_STOP_PIN PB1 // BLTouch IN PIN +#elif ENABLED(FIX_MOUNTED_PROBE) + #define Z_STOP_PIN PA4 + #define COM_PIN PA5 +#else + #define Z_STOP_PIN PA7 +#endif + +// +// Filament Runout Sensor +// +#ifndef FIL_RUNOUT_PIN + //#define FIL_RUNOUT_PIN PA7 // Opto endstop +#endif + +// +// Steppers +// +#define X_ENABLE_PIN PC3 +#define X_STEP_PIN PB8 +#define X_DIR_PIN PB7 + +#define Y_ENABLE_PIN PC3 +#define Y_STEP_PIN PB6 +#define Y_DIR_PIN PB5 + +#define Z_ENABLE_PIN PC3 +#define Z_STEP_PIN PB4 +#define Z_DIR_PIN PB3 + +#define E0_ENABLE_PIN PC3 +#define E0_STEP_PIN PC2 +#define E0_DIR_PIN PB9 + +#if HAS_TMC220x + + // + // TMC2208 mode + // + //#define TMC2208_STANDALONE + + #define X_HARDWARE_SERIAL MSerial2 + #define Y_HARDWARE_SERIAL MSerial2 + #define Z_HARDWARE_SERIAL MSerial2 + #define E0_HARDWARE_SERIAL MSerial2 + + // + // TMC2208 Software serial + // + //#define HAVE_SW_SERIAL + + // Reduce baud rate to improve software serial reliability + //#define TMC_BAUD_RATE 19200 + +#endif + +// +// Release PB4 (Z_STEP_PIN) from JTAG NRST role +// +#define DISABLE_DEBUG + +// +// Temperature Sensors +// +#define TEMP_0_PIN PB1 // TH1 +#define TEMP_BED_PIN PB0 // TB1 + +// +// Heaters / Fans +// +#define HEATER_0_PIN PA1 // HEATER1 +#define HEATER_BED_PIN PA2 // HOT BED + +#define FAN_PIN PA0 // FAN +#define FAN_SOFT_PWM + +#define LED_CONTROL_PIN PA6 +#define OPTO_SWITCH_PIN PC6 + +// +// SD Card +// +#define SD_DETECT_PIN PC7 diff --git a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h index 0caa8c1deb1f..6b5927e58ffe 100644 --- a/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h +++ b/Marlin/src/pins/stm32f1/pins_CREALITY_V4.h @@ -46,8 +46,8 @@ // FLASH //#define FLASH_EEPROM_EMULATION - // I2C - #define IIC_BL24CXX_EEPROM // EEPROM on I2C-0 used only for display settings + // BL24C16 + #define IIC_BL24CXX_EEPROM // EEPROM on I2C-0 #if ENABLED(IIC_BL24CXX_EEPROM) #define IIC_EEPROM_SDA PA11 #define IIC_EEPROM_SCL PA12