From 04c10eda92ee34ae45da75cd85c42211c23cf1e8 Mon Sep 17 00:00:00 2001
From: Victor Oliveira <rhapsodyv@gmail.com>
Date: Tue, 4 Aug 2020 01:41:23 -0300
Subject: [PATCH] Fix MKS Nano v1.2 FSMC display (#18901)

---
 Marlin/src/inc/SanityCheck.h                  |  2 +-
 ...8g_dev_tft_320x240_upscale_from_128x64.cpp | 54 ++++++++---
 Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h | 97 +++++--------------
 3 files changed, 66 insertions(+), 87 deletions(-)

diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 5608fcff033..e1b162a96f9 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -819,7 +819,7 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
  */
 #if ENABLED(ADVANCED_PAUSE_FEATURE)
   #if !HAS_RESUME_CONTINUE
-    #error "ADVANCED_PAUSE_FEATURE currently requires an LCD controller or EMERGENCY_PARSER."
+    #error "ADVANCED_PAUSE_FEATURE requires a supported LCD controller (or EMERGENCY_PARSER)."
   #elif DISABLED(NOZZLE_PARK_FEATURE)
     #error "ADVANCED_PAUSE_FEATURE requires NOZZLE_PARK_FEATURE."
   #elif !defined(FILAMENT_UNLOAD_PURGE_FEEDRATE)
diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
index 0f6cbcbb8a6..82bef782444 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_tft_320x240_upscale_from_128x64.cpp
@@ -242,6 +242,7 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
     }
   }
   #define WRITE_ESC_SEQUENCE(V) writeEscSequence(V)
+  #define WRITE_ESC_SEQUENCE16(V) writeEscSequence(V)
 #else
   void writeEscSequence8(u8g_t *u8g, u8g_dev_t *dev, const uint16_t *sequence) {
     uint16_t data;
@@ -289,6 +290,8 @@ void (*setWindow)(u8g_t *u8g, u8g_dev_t *dev, uint16_t Xmin, uint16_t Ymin, uint
     }
     u8g_SetAddress(u8g, dev, 1);
   }
+
+  #define WRITE_ESC_SEQUENCE16(V) writeEscSequence16(u8g, dev, V)
 #endif
 
 static const uint16_t st7789v_init[] = {
@@ -378,7 +381,28 @@ static const uint16_t ili9341_init[] = {
   ESC_END
 };
 
-static const uint16_t st9677_init[] = {
+static const uint16_t ili9488_init[] = {
+  ESC_REG(0x00E0), 0x0000, 0x0007, 0x000F, 0x000D, 0x001B, 0x000A, 0x003C, 0x0078, 0x004A, 0x0007, 0x000E, 0x0009, 0x001B, 0x001E, 0x000F,
+  ESC_REG(0x00E1), 0x0000, 0x0022, 0x0024, 0x0006, 0x0012, 0x0007, 0x0036, 0x0047, 0x0047, 0x0006, 0x000A, 0x0007, 0x0030, 0x0037, 0x000F,
+  ESC_REG(0x00C0), 0x0010, 0x0010,
+  ESC_REG(0x00C1), 0x0041,
+  ESC_REG(0x00C5), 0x0000, 0x0022, 0x0080,
+  ESC_REG(0x0036), TERN(GRAPHICAL_TFT_ROTATE_180, 0x00A8, 0x0068),
+  ESC_REG(0x003A), 0x0055,
+  ESC_REG(0x00B0), 0x0000,
+  ESC_REG(0x00B1), 0x00B0, 0x0011,
+  ESC_REG(0x00B4), 0x0002,
+  ESC_REG(0x00B6), 0x0002, 0x0042,
+  ESC_REG(0x00B7), 0x00C6,
+  ESC_REG(0x00E9), 0x0000,
+  ESC_REG(0x00F0), 0x00A9, 0x0051, 0x002C, 0x0082,
+  ESC_REG(0x0029),
+  ESC_REG(0x0011),
+  ESC_DELAY(100),
+  ESC_END
+};
+
+static const uint16_t st7796_init[] = {
   ESC_REG(0x0010), ESC_DELAY(120),
   ESC_REG(0x0001), ESC_DELAY(120),
   ESC_REG(0x0011), ESC_DELAY(120),
@@ -588,8 +612,8 @@ static const uint16_t st9677_init[] = {
 
         LCD_IO_WriteSequence(buffer, length * sq(FSMC_UPSCALE));
       #else
-        u8g_WriteSequence(u8g, dev, k << 1, (uint8_t*)buffer);
-        u8g_WriteSequence(u8g, dev, k << 1, (uint8_t*)buffer);
+        for (uint8_t i = FSMC_UPSCALE; i--;)
+          u8g_WriteSequence(u8g, dev, k << 1, (uint8_t*)buffer);
       #endif
     }
   }
@@ -617,7 +641,7 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
     uint16_t* buffer = &bufferA[0];
     bool allow_async = DISABLED(SPI_GRAPHICAL_TFT);
   #else
-    uint16_t buffer[WIDTH*2]; // 16-bit RGB 565 pixel line buffer
+    uint16_t buffer[WIDTH * FSMC_UPSCALE]; // 16-bit RGB 565 pixel line buffer
   #endif
 
   switch (msg) {
@@ -630,18 +654,21 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
           setWindow = setWindow_st7789v;
           break;
         case 0x9328:  // ILI9328
-          WRITE_ESC_SEQUENCE(ili9328_init);
+          WRITE_ESC_SEQUENCE16(ili9328_init);
           setWindow = setWindow_ili9328;
           break;
         case 0x9341:   // ILI9341
         case 0x8066:   // Anycubic / TronXY TFTs (480x320)
-          WRITE_ESC_SEQUENCE(ili9341_init);
+          WRITE_ESC_SEQUENCE(ili9488_init);
           setWindow = setWindow_st7789v;
           break;
         case 0x7796:
-          WRITE_ESC_SEQUENCE(TERN(HAS_LCD_IO, st9677_init, ili9341_init));
+          WRITE_ESC_SEQUENCE(st7796_init);
           setWindow = setWindow_st7789v;
           break;
+        case 0x9488:
+          WRITE_ESC_SEQUENCE(ili9488_init);
+          setWindow = setWindow_st7789v;
         case 0x0404:  // No connected display on FSMC
           lcd_id = 0;
           return 0;
@@ -664,8 +691,8 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
         LCD_IO_WriteMultiple(TFT_MARLINBG_COLOR, (LCD_FULL_PIXEL_WIDTH) * (LCD_FULL_PIXEL_HEIGHT));
       #else
         memset2(buffer, TFT_MARLINBG_COLOR, (LCD_FULL_PIXEL_WIDTH) / 2);
-        for (uint16_t i = 0; i < (LCD_FULL_PIXEL_WIDTH) * 3; i++)
-          u8g_WriteSequence(u8g, dev, (LCD_FULL_PIXEL_WIDTH) / 2, (uint8_t *)buffer);
+        for (uint16_t i = 0; i < (LCD_FULL_PIXEL_HEIGHT) * sq(FSMC_UPSCALE); i++)
+          u8g_WriteSequence(u8g, dev, LCD_FULL_PIXEL_WIDTH / 2, (uint8_t *)buffer);
       #endif
 
       // Bottom buttons
@@ -721,11 +748,10 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
             LCD_IO_WriteSequence(buffer, COUNT(bufferA));
         #else
           uint8_t* bufptr = (uint8_t*) buffer;
-          for (uint8_t i = 2; i--;) {
-            u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[0]);
-            u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH]);
-            u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*2]);
-            u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH*3]);
+          for (uint8_t i = FSMC_UPSCALE; i--;) {
+            LOOP_S_L_N(n, 0, FSMC_UPSCALE * 2) {
+              u8g_WriteSequence(u8g, dev, WIDTH, &bufptr[WIDTH * n]);
+            }
           }
         #endif
       }
diff --git a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h
index 844fb6b0d6a..a68b4810717 100644
--- a/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h
+++ b/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_NANO.h
@@ -165,28 +165,7 @@
  * to let the bootloader init the screen.
  */
 
-#if ENABLED(TFT_LVGL_UI_SPI)
-
-  #define SPI_TFT_CS_PIN                    PD11
-  #define SPI_TFT_SCK_PIN                   PA5
-  #define SPI_TFT_MISO_PIN                  PA6
-  #define SPI_TFT_MOSI_PIN                  PA7
-  #define SPI_TFT_DC_PIN                    PD10
-  #define SPI_TFT_RST_PIN                   PC6
-
-  #define LCD_BACKLIGHT_PIN                 PD13
-
-  #define TOUCH_CS_PIN                      PE14  // SPI1_NSS
-  #define TOUCH_SCK_PIN                     PA5   // SPI1_SCK
-  #define TOUCH_MISO_PIN                    PA6   // SPI1_MISO
-  #define TOUCH_MOSI_PIN                    PA7   // SPI1_MOSI
-
-  #define BTN_EN1                           PE8
-  #define BTN_EN2                           PE11
-  #define BEEPER_PIN                        PC5
-  #define BTN_ENC                           PE13
-
-#elif ENABLED(TFT_LVGL_UI_FSMC)
+#if ENABLED(TFT_LVGL_UI_FSMC)
 
   #define FSMC_CS_PIN                       PD7   // NE4
   #define FSMC_RS_PIN                       PD11  // A0
@@ -198,15 +177,34 @@
 
   #define LCD_BACKLIGHT_PIN                 PD13
 
-#endif
+#elif ENABLED(FSMC_GRAPHICAL_TFT)
 
-#if ENABLED(FSMC_GRAPHICAL_TFT)
-  //#define DOGLCD_MOSI                     -1    // prevent redefine Conditionals_post.h
-  //#define DOGLCD_SCK                      -1
+  #define DOGLCD_MOSI                       -1    // prevent redefine Conditionals_post.h
+  #define DOGLCD_SCK                        -1
+
+  #ifndef FSMC_UPSCALE
+    #define FSMC_UPSCALE                    3
+  #endif
+  #ifndef LCD_FULL_PIXEL_WIDTH
+    #define LCD_FULL_PIXEL_WIDTH            480
+  #endif
+  #ifndef LCD_PIXEL_OFFSET_X
+    #define LCD_PIXEL_OFFSET_X              48
+  #endif
+  #ifndef LCD_FULL_PIXEL_HEIGHT
+    #define LCD_FULL_PIXEL_HEIGHT           320
+  #endif
+  #ifndef LCD_PIXEL_OFFSET_Y
+    #define LCD_PIXEL_OFFSET_Y              32
+  #endif
 
   #define FSMC_CS_PIN                       PD7   // NE4
   #define FSMC_RS_PIN                       PD11  // A0
 
+  #define LCD_USE_DMA_FSMC                  // Use DMA transfers to send data to the TFT
+  #define FSMC_DMA_DEV                      DMA2
+  #define FSMC_DMA_CHANNEL                  DMA_CH5
+
   #define LCD_RESET_PIN                     PC6   // FSMC_RST
   #define LCD_BACKLIGHT_PIN                 PD13
 
@@ -216,54 +214,9 @@
     #define TOUCH_MISO_PIN                  PB14  // SPI2_MISO
     #define TOUCH_MOSI_PIN                  PB15  // SPI2_MOSI
   #endif
+
 #endif
 
-#if HAS_SPI_LCD
-
-  #define BEEPER_PIN                        PC5
-  #define BTN_ENC                           PE13
-  #define LCD_PINS_ENABLE                   PD13
-  #define LCD_PINS_RS                       PC6
-  #define BTN_EN1                           PE8
-  #define BTN_EN2                           PE11
-  #define LCD_BACKLIGHT_PIN                 -1
-
-  // MKS MINI12864 and MKS LCD12864B; If using MKS LCD12864A (Need to remove RPK2 resistor)
-  #if ENABLED(MKS_MINI_12864)
-    #define LCD_BACKLIGHT_PIN               -1
-    #define LCD_RESET_PIN                   -1
-    #define DOGLCD_A0                       PD11
-    #define DOGLCD_CS                       PE15
-    #define DOGLCD_SCK                      PA5
-    #define DOGLCD_MOSI                     PA7
-
-    // Required for MKS_MINI_12864 with this board
-    #define MKS_LCD12864B
-    #undef SHOW_BOOTSCREEN
-
-  #else                                           // !MKS_MINI_12864
-
-    #define LCD_PINS_D4                     PE14
-    #if ENABLED(ULTIPANEL)
-      #define LCD_PINS_D5                   PE15
-      #define LCD_PINS_D6                   PD11
-      #define LCD_PINS_D7                   PD10
-    #endif
-
-    #ifndef BOARD_ST7920_DELAY_1
-      #define BOARD_ST7920_DELAY_1 DELAY_NS(125)
-    #endif
-    #ifndef BOARD_ST7920_DELAY_2
-      #define BOARD_ST7920_DELAY_2 DELAY_NS(125)
-    #endif
-    #ifndef BOARD_ST7920_DELAY_3
-      #define BOARD_ST7920_DELAY_3 DELAY_NS(125)
-    #endif
-
-  #endif // !MKS_MINI_12864
-
-#endif // HAS_SPI_LCD
-
 #define SPI_FLASH
 #if ENABLED(SPI_FLASH)
   #define W25QXX_CS_PIN                     PB12