From 81ca5a4cd43944bd7e9fffd740ce3abfb89a8687 Mon Sep 17 00:00:00 2001
From: Bob Kuhn <bob.kuhn@att.net>
Date: Sun, 21 Apr 2019 20:48:53 -0500
Subject: [PATCH] Fix and improve FYSETC LCD support (#13767)

---
 Marlin/Configuration.h                        |  6 ++
 Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp        | 44 +++++++++-
 Marlin/src/inc/Conditionals_LCD.h             |  6 +-
 Marlin/src/inc/SanityCheck.h                  |  7 --
 Marlin/src/lcd/dogm/HAL_LCD_class_defines.h   | 13 +++
 .../lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp | 67 ++++++++-------
 Marlin/src/lcd/dogm/ultralcd_DOGM.h           |  4 +-
 Marlin/src/lcd/ultralcd.cpp                   |  4 +-
 Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h       | 51 ++++++++----
 Marlin/src/pins/pins_FYSETC_F6_13.h           | 46 ++++++++---
 Marlin/src/pins/pins_RAMPS.h                  | 37 +++++++--
 Marlin/src/pins/pins_RAMPS_FD_V1.h            | 81 ++++++++++++++-----
 Marlin/src/pins/pins_RAMPS_RE_ARM.h           |  1 +
 Marlin/src/pins/pins_RURAMPS4D_11.h           | 78 +++++++++++++-----
 Marlin/src/pins/pins_RURAMPS4D_13.h           | 66 +++++++++++----
 15 files changed, 369 insertions(+), 142 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 7ea040803c..43ce28baaf 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -1910,6 +1910,12 @@
 // https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8
 //
 //#define FYSETC_MINI_12864
+#ifdef FYSETC_MINI_12864
+  #define FYSETC_MINI_12864_REV_1_2              //  types C, D, E & F  back light is monochrome (always on) - discrete RGB signals
+  //#define FYSETC_MINI_12864_REV_2_0            //  types A & B  back light is RGB - requires LED_USER_PRESET_STARTUP - discrete RGB signals
+  //#define FYSETC_MINI_12864_REV_2_1            //  types A & B  back light is RGB - requires LED_USER_PRESET_STARTUP -  RGB
+  //#define FYSETC_MINI_12864_REV_2_1            //  types A & B  back light is RGB - requires LED_USER_PRESET_STARTUP - Neopixel
+#endif
 
 //
 // Factory display for Creality CR-10
diff --git a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
index a1934886f9..5adc7fcf09 100644
--- a/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
+++ b/Marlin/src/HAL/HAL_DUE/HAL_spi_Due.cpp
@@ -53,7 +53,7 @@
 // Public functions
 // --------------------------------------------------------------------------
 
-#if ENABLED(DUE_SOFTWARE_SPI)
+#if EITHER(DUE_SOFTWARE_SPI, FORCE_SOFT_SPI)
 
   // --------------------------------------------------------------------------
   // software SPI
@@ -739,7 +739,42 @@
     #define SPI_MODE_2_DUE_HW 0
     #define SPI_MODE_3_DUE_HW 1
 
+    /**
+     *  The DUE SPI controller is set up so the upper word of the longword
+     *  written to the transmit data register selects which SPI Chip Select
+     *  Register is used. This allows different streams to have different SPI
+     *  settings.
+     *
+     *  In practice it's spooky. Some combinations hang the system, while others
+     *  upset the peripheral device.
+     *
+     *  SPI mode should be the same for all streams. The FYSETC_MINI_12864 gets
+     *  upset if the clock phase changes after chip select goes active.
+     *
+     *  SPI_CSR_CSAAT should be set for all streams. If not the WHILE_TX(0)
+     *  macro returns immediately which can result in the SPI chip select going
+     *  inactive before all the data has been sent.
+     *
+     *  The TMC2130 library uses SPI0->SPI_CSR[3].
+     *
+     *  The U8G hardware SPI uses SPI0->SPI_CSR[0]. The system hangs and/or the
+     *  FYSETC_MINI_12864 gets upset if lower baud rates are used and the SD card
+     *  is inserted or removed.
+     *
+     *  The SD card uses SPI0->SPI_CSR[3]. Efforts were made to use [1] and [2]
+     *  but they all resulted in hangs or garbage on the LCD.
+     *
+     *  The SPI controlled chip selects are NOT enabled in the GPIO controller.
+     *  The application must control the chip select.
+     *
+     *  All of the above can be avoided by defining FORCE_SOFT_SPI to force the
+     *  display to use software SPI.
+     *
+     */
+
     void spiInit(uint8_t spiRate=6) {  // Default to slowest rate if not specified)
+                                       // Also sets U8G SPI rate to 4MHz and the SPI mode to 3
+
       // 8.4 MHz, 4 MHz, 2 MHz, 1 MHz, 0.5 MHz, 0.329 MHz, 0.329 MHz
       constexpr int spiDivider[] = { 10, 21, 42, 84, 168, 255, 255 };
       if (spiRate > 6) spiRate = 1;
@@ -760,15 +795,16 @@
       // TMC2103 compatible setup
       // Master mode, no fault detection, PCS bits in data written to TDR select CSR register
       SPI0->SPI_MR = SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS;
-      // SPI mode 0, 8 Bit data transfer, baud rate
-      SPI0->SPI_CSR[3] = SPI_CSR_SCBR(spiDivider[spiRate]) | SPI_CSR_CSAAT | SPI_MODE_0_DUE_HW;  // use same CSR as TMC2130
+      // SPI mode 3, 8 Bit data transfer, baud rate
+      SPI0->SPI_CSR[3] = SPI_CSR_SCBR(spiDivider[spiRate]) | SPI_CSR_CSAAT | SPI_MODE_3_DUE_HW;  // use same CSR as TMC2130
+      SPI0->SPI_CSR[0] = SPI_CSR_SCBR(spiDivider[1]) | SPI_CSR_CSAAT | SPI_MODE_3_DUE_HW;  // U8G default to 4MHz
     }
 
     void spiBegin() { spiInit(); }
 
     static uint8_t spiTransfer(uint8_t data) {
       WHILE_TX(0);
-      SPI0->SPI_TDR = (uint32_t)data | 0x00070000UL;  // Add TMC2130 PCS bits to every byte
+      SPI0->SPI_TDR = (uint32_t)data | 0x00070000UL;  // Add TMC2130 PCS bits to every byte (use SPI0->SPI_CSR[3])
       WHILE_TX(0);
       WHILE_RX(0);
       return SPI0->SPI_RDR;
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 3013dae7a9..81c0678e3f 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -138,6 +138,8 @@
 #elif ENABLED(MKS_MINI_12864)
 
   #define MINIPANEL
+  #define DEFAULT_LCD_CONTRAST 150
+  #define LCD_CONTRAST_MAX 255
 
 #elif ENABLED(FYSETC_MINI_12864)
 
@@ -153,7 +155,9 @@
 #if EITHER(MAKRPANEL, MINIPANEL)
   #define DOGLCD
   #define ULTIPANEL
-  #define DEFAULT_LCD_CONTRAST 17
+  #ifndef DEFAULT_LCD_CONTRAST
+    #define DEFAULT_LCD_CONTRAST 17
+  #endif
 #endif
 
 #if ENABLED(ULTI_CONTROLLER)
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 05ff1a4ac9..d76c28bbf2 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -1786,13 +1786,6 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
   #error "Please select no more than one LCD controller option."
 #endif
 
-/**
- * Fysetc Mini 12864 requirements
- */
-#if ENABLED(FYSETC_MINI_12864) && DISABLED(LED_USER_PRESET_STARTUP)
-  #error "FYSETC_MINI_12864 requires LED_USER_PRESET_STARTUP to enable the backlight on startup."
-#endif
-
 /**
  * Check existing CS pins against enabled TMC SPI drivers.
  */
diff --git a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h
index 7141eeb180..d25b58d9a4 100644
--- a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h
+++ b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h
@@ -94,3 +94,16 @@ public:
   : U8GLIB(&u8g_dev_tft_320x240_upscale_from_128x64, cs, rs, reset)
   { }
 };
+
+
+extern u8g_dev_t u8g_dev_uc1701_mini12864_HAL_2x_sw_spi, u8g_dev_uc1701_mini12864_HAL_2x_hw_spi;
+
+class U8GLIB_MINI12864_2X_HAL : public U8GLIB {
+public:
+  U8GLIB_MINI12864_2X_HAL(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE)
+    : U8GLIB(&u8g_dev_uc1701_mini12864_HAL_2x_sw_spi, sck, mosi, cs, a0, reset)
+    { }
+  U8GLIB_MINI12864_2X_HAL(uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE)
+    : U8GLIB(&u8g_dev_uc1701_mini12864_HAL_2x_hw_spi, cs, a0, reset)
+    { }
+};
diff --git a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp
index 35f7d4161a..4dd8759e7a 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_uc1701_mini12864_HAL.cpp
@@ -66,42 +66,47 @@
 #define PAGE_HEIGHT 8
 
 static const uint8_t u8g_dev_uc1701_mini12864_HAL_init_seq[] PROGMEM = {
-  U8G_ESC_CS(0),             /* disable chip */
-  U8G_ESC_ADR(0),           /* instruction mode */
-  U8G_ESC_RST(1),           /* do reset low pulse with (1*16)+2 milliseconds */
-  U8G_ESC_CS(1),             /* enable chip */
+  U8G_ESC_CS(0),              /* disable chip */
+  U8G_ESC_ADR(0),             /* instruction mode */
+  U8G_ESC_RST(1),             /* do reset low pulse with (1*16)+2 milliseconds */
+  U8G_ESC_CS(1),              /* enable chip */
 
-  0x0E2,            /* soft reset */
-  0x040,    /* set display start line to 0 */
-  0x0A0,    /* ADC set to reverse */
-  0x0C8,    /* common output mode */
-  0x0A6,    /* display normal, bit val 0: LCD pixel off. */
-  0x0A2,    /* LCD bias 1/9 */
-  0x02F,    /* all power  control circuits on */
-  0x0F8,    /* set booster ratio to */
-  0x000,    /* 4x */
-  0x023,    /* set V0 voltage resistor ratio to large */
-  0x081,    /* set contrast */
-  0x027,    /* contrast value */
-  0x0AC,    /* indicator */
-  0x000,    /* disable */
-  0x0AF,    /* display on */
+  0x0E2,                      /* soft reset */
+  0x040,                      /* set display start line to 0 */
+  0x0A0,                      /* ADC set to reverse */
+  0x0C8,                      /* common output mode */
+  0x0A6,                      /* display normal, bit val 0: LCD pixel off. */
+  0x0A2,                      /* LCD bias 1/9 */
+  0x02F,                      /* all power control circuits on */
+  0x0F8,                      /* set booster ratio to */
+  0x000,                      /* 4x */
+  0x023,                      /* set V0 voltage resistor ratio to large */
+  0x081,                      /* set contrast */
+  0x027,                      /* contrast value */
+  0x0AC,                      /* indicator */
+  0x000,                      /* disable */
+  0x0AF,                      /* display on */
 
-  U8G_ESC_DLY(100),       /* delay 100 ms */
-  0x0A5,                    /* display all points, ST7565 */
-  U8G_ESC_DLY(100),       /* delay 100 ms */
-  U8G_ESC_DLY(100),       /* delay 100 ms */
-  0x0A4,                    /* normal display */
-  U8G_ESC_CS(0),             /* disable chip */
-  U8G_ESC_END                /* end of sequence */
+  U8G_ESC_CS(0),              /* disable chip */
+  U8G_ESC_DLY(100),           /* delay 100 ms */
+  U8G_ESC_CS(1),              /* enable chip */
+
+  0x0A5,                      /* display all points, ST7565 */
+  U8G_ESC_CS(0),              /* disable chip */
+  U8G_ESC_DLY(100),           /* delay 100 ms */
+  U8G_ESC_DLY(100),           /* delay 100 ms */
+  U8G_ESC_CS(1),              /* enable chip */
+  0x0A4,                      /* normal display */
+  U8G_ESC_CS(0),              /* disable chip */
+  U8G_ESC_END                 /* end of sequence */
 };
 
 static const uint8_t u8g_dev_uc1701_mini12864_HAL_data_start[] PROGMEM = {
-  U8G_ESC_ADR(0),           /* instruction mode */
-  U8G_ESC_CS(1),             /* enable chip */
-  0x010,    /* set upper 4 bit of the col adr to 0 */
-  0x000,    /* set lower 4 bit of the col adr to 4  */
-  U8G_ESC_END                /* end of sequence */
+  U8G_ESC_ADR(0),             /* instruction mode */
+  U8G_ESC_CS(1),              /* enable chip */
+  0x010,                      /* set upper 4 bit of the col adr to 0 */
+  0x000,                      /* set lower 4 bit of the col adr to 4 */
+  U8G_ESC_END                 /* end of sequence */
 };
 
 uint8_t u8g_dev_uc1701_mini12864_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
diff --git a/Marlin/src/lcd/dogm/ultralcd_DOGM.h b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
index 4319bd5fd6..8ce25d0e77 100644
--- a/Marlin/src/lcd/dogm/ultralcd_DOGM.h
+++ b/Marlin/src/lcd/dogm/ultralcd_DOGM.h
@@ -111,8 +111,8 @@
   // The MINIPanel display
   //#define U8G_CLASS U8GLIB_MINI12864
   //#define U8G_PARAM DOGLCD_CS, DOGLCD_A0                            // 8 stripes
-  #define U8G_CLASS U8GLIB_MINI12864_2X
-  #if ENABLED(FYSETC_MINI_12864) && DOGLCD_SCK > 0
+  #define U8G_CLASS U8GLIB_MINI12864_2X_HAL
+  #if BOTH(FYSETC_MINI_12864, FORCE_SOFT_SPI)
     #define U8G_PARAM DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0   // 4 stripes SW-SPI
   #else
     #define U8G_PARAM DOGLCD_CS, DOGLCD_A0                            // 4 stripes HW-SPI
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index cb8b308df3..cf1f8f98ea 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -668,6 +668,7 @@ void MarlinUI::update() {
 
   static uint16_t max_display_update_time = 0;
   static millis_t next_lcd_update_ms;
+  millis_t ms = millis();
 
   #if HAS_LCD_MENU
 
@@ -729,11 +730,12 @@ void MarlinUI::update() {
 
       refresh();
       init_lcd(); // May revive the LCD if static electricity killed it
+      ms = millis();
+      next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;  // delay LCD update until after SD activity completes
     }
 
   #endif // SDSUPPORT && SD_DETECT_PIN
 
-  const millis_t ms = millis();
   if (ELAPSED(ms, next_lcd_update_ms)
     #if HAS_GRAPHICAL_LCD
       || drawing_screen
diff --git a/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h b/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h
index 3812195c65..319c56f31f 100644
--- a/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h
+++ b/Marlin/src/pins/pins_BIGTREE_SKR_V1.3.h
@@ -202,26 +202,45 @@
     #define SD_DETECT_PIN   P1_31   // (49) (NOT 5V tolerant)
 
     #if ENABLED(FYSETC_MINI_12864)
-      #define DOGLCD_CS     P1_18 
+      #define DOGLCD_CS     P1_18
       #define DOGLCD_A0     P1_19
-      #define LCD_RESET_PIN P1_20
+
       #define LCD_BACKLIGHT_PIN -1
 
-      #define RGB_LED
-      #ifndef RGB_LED_R_PIN
-        #define RGB_LED_R_PIN P1_21
-      #endif
-      #ifndef RGB_LED_G_PIN
-        #define RGB_LED_G_PIN P1_22
-      #endif
-      #ifndef RGB_LED_B_PIN
-        #define RGB_LED_B_PIN P1_23
-      #endif
-      #ifndef RGB_LED_W_PIN
-        #define RGB_LED_W_PIN -1
+      #define LCD_RESET_PIN P1_20   // Must be high or open for LCD to operate normally.
+                                    // Seems to work best if left open.
+
+      #define FYSETC_MINI_12864_REV_1_2
+      //#define FYSETC_MINI_12864_REV_2_0
+      //#define FYSETC_MINI_12864_REV_2_1
+      #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+        #define RGB_LED
+        #ifndef RGB_LED_R_PIN
+          #define RGB_LED_R_PIN P1_21
+        #endif
+        #ifndef RGB_LED_G_PIN
+          #define RGB_LED_G_PIN P1_22
+        #endif
+        #ifndef RGB_LED_B_PIN
+          #define RGB_LED_B_PIN P1_23
+        #endif
+      #elif defined(FYSETC_MINI_12864_REV_2_1)
+        #define NEOPIXEL_LED
+        #define NEOPIXEL_TYPE   NEO_GRB  // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+        #define NEOPIXEL_PIN    P1_21    // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+        #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+        #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+        #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+        #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+      #else
+        #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
       #endif
 
-    #else
+      #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+        #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
+      #endif
+
+    #else // !FYSETC_MINI_12864
 
       #if ENABLED(MKS_MINI_12864)
         #define DOGLCD_CS     P1_21
@@ -234,7 +253,7 @@
         #define LCD_PINS_D7   P1_23
       #endif
 
-    #endif // FYSETC_MINI_12864
+    #endif // !FYSETC_MINI_12864
 
   #endif
 
diff --git a/Marlin/src/pins/pins_FYSETC_F6_13.h b/Marlin/src/pins/pins_FYSETC_F6_13.h
index 84b834842c..d40abd1024 100644
--- a/Marlin/src/pins/pins_FYSETC_F6_13.h
+++ b/Marlin/src/pins/pins_FYSETC_F6_13.h
@@ -28,8 +28,8 @@
   #error "Oops! Select 'FYSETC F6' in 'Tools > Board.'"
 #endif
 
-#ifdef SD_DETECT_INVERTED
-  #error "SD_DETECT_INVERTED must be disabled for the FYSETC_F6_13 board."
+#if ENABLED(SD_DETECT_INVERTED)
+  //#error "SD_DETECT_INVERTED must be disabled for the FYSETC_F6_13 board."
 #endif
 
 #define BOARD_NAME "FYSETC F6 1.3"
@@ -190,20 +190,42 @@
   //
   #define DOGLCD_A0        16
   #define DOGLCD_CS        17
-  #ifndef RGB_LED_R_PIN
-    #define RGB_LED_R_PIN  25
-  #endif
-  #ifndef RGB_LED_G_PIN
-    #define RGB_LED_G_PIN  27
-  #endif
-  #ifndef RGB_LED_B_PIN
-    #define RGB_LED_B_PIN  29
-  #endif
 
   #define LCD_BACKLIGHT_PIN -1
-  #define LCD_RESET_PIN    23
   #define KILL_PIN         41
 
+  #define LCD_RESET_PIN    23   // Must be high or open for LCD to operate normally.
+                                // Seems to work best if left open.
+
+  #define FYSETC_MINI_12864_REV_1_2
+  //#define FYSETC_MINI_12864_REV_2_0
+  //#define FYSETC_MINI_12864_REV_2_1
+  #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+    #ifndef RGB_LED_R_PIN
+      #define RGB_LED_R_PIN 25
+    #endif
+    #ifndef RGB_LED_G_PIN
+      #define RGB_LED_G_PIN 27
+    #endif
+    #ifndef RGB_LED_B_PIN
+      #define RGB_LED_B_PIN 29
+    #endif
+  #elif defined(FYSETC_MINI_12864_REV_2_1)
+    #define NEOPIXEL_LED
+    #define NEOPIXEL_TYPE   NEO_GRB  // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+    #define NEOPIXEL_PIN    25       // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+    #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+    #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+    #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+    #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+  #else
+    #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
+  #endif
+
+  #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+    #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
+  #endif
+
 #elif HAS_GRAPHICAL_LCD
 
   #define LCD_PINS_RS      16
diff --git a/Marlin/src/pins/pins_RAMPS.h b/Marlin/src/pins/pins_RAMPS.h
index 40d3dd11e2..a705e3e194 100644
--- a/Marlin/src/pins/pins_RAMPS.h
+++ b/Marlin/src/pins/pins_RAMPS.h
@@ -526,7 +526,6 @@
 
       // From https://wiki.fysetc.com/Mini12864_Panel/?fbclid=IwAR1FyjuNdVOOy9_xzky3qqo_WeM5h-4gpRnnWhQr_O1Ef3h0AFnFXmCehK8
       #define BEEPER_PIN        37
-      #define LCD_RESET_PIN     23
 
       #define DOGLCD_A0         16
       #define DOGLCD_CS         17
@@ -537,14 +536,36 @@
 
       #define SD_DETECT_PIN     49
 
-      #ifndef RGB_LED_R_PIN
-        #define RGB_LED_R_PIN   25
+      #define LCD_RESET_PIN     23   // Must be high or open for LCD to operate normally.
+                                     // Seems to work best if left open.
+
+      #define FYSETC_MINI_12864_REV_1_2
+      //#define FYSETC_MINI_12864_REV_2_0
+      //#define FYSETC_MINI_12864_REV_2_1
+      #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+        #ifndef RGB_LED_R_PIN
+          #define RGB_LED_R_PIN 25
+        #endif
+        #ifndef RGB_LED_G_PIN
+          #define RGB_LED_G_PIN 27
+        #endif
+        #ifndef RGB_LED_B_PIN
+          #define RGB_LED_B_PIN 29
+        #endif
+      #elif defined(FYSETC_MINI_12864_REV_2_1)
+        #define NEOPIXEL_LED
+        #define NEOPIXEL_TYPE   NEO_GRB  // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+        #define NEOPIXEL_PIN    25       // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+        #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+        #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+        #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+        #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+      #else
+        #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
       #endif
-      #ifndef RGB_LED_G_PIN
-        #define RGB_LED_G_PIN   27
-      #endif
-      #ifndef RGB_LED_B_PIN
-        #define RGB_LED_B_PIN   29
+
+      #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+        #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
       #endif
 
     #elif ENABLED(MINIPANEL)
diff --git a/Marlin/src/pins/pins_RAMPS_FD_V1.h b/Marlin/src/pins/pins_RAMPS_FD_V1.h
index a8bec209ef..78e75d9116 100644
--- a/Marlin/src/pins/pins_RAMPS_FD_V1.h
+++ b/Marlin/src/pins/pins_RAMPS_FD_V1.h
@@ -150,32 +150,71 @@
   #if ENABLED(NEWPANEL)
     #define LCD_PINS_RS    16
     #define LCD_PINS_ENABLE 17
-    #define LCD_PINS_D4    23
-    #define LCD_PINS_D5    25
-    #define LCD_PINS_D6    27
-    #define LCD_PINS_D7    29
   #endif
 
   #if ENABLED(FYSETC_MINI_12864)
     #define DOGLCD_CS      LCD_PINS_ENABLE
     #define DOGLCD_A0      LCD_PINS_RS
-  #elif ENABLED(MINIPANEL)
-    #define DOGLCD_CS      25
-    #define DOGLCD_A0      27
+
+    //#define FORCE_SOFT_SPI    // Use this if default of hardware SPI causes problems
+
+    #define LCD_RESET_PIN  23   // Must be high or open for LCD to operate normally.
+                                // Seems to work best if left open.
+
+    #define FYSETC_MINI_12864_REV_1_2
+    //#define FYSETC_MINI_12864_REV_2_0
+    //#define FYSETC_MINI_12864_REV_2_1
+    #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+      #ifndef RGB_LED_R_PIN
+        #define RGB_LED_R_PIN 25
+      #endif
+      #ifndef RGB_LED_G_PIN
+        #define RGB_LED_G_PIN 27
+      #endif
+      #ifndef RGB_LED_B_PIN
+        #define RGB_LED_B_PIN 29
+      #endif
+    #elif defined(FYSETC_MINI_12864_REV_2_1)
+      #define NEOPIXEL_LED
+      #define NEOPIXEL_TYPE NEO_GRB    // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+      #define NEOPIXEL_PIN    25       // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+      #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+      #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+      #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+      #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+    #else
+      #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
+    #endif
+
+    #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+      #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
+    #endif
+
+  #elif ENABLED(NEWPANEL)
+
+    #define LCD_PINS_D4    23
+    #define LCD_PINS_D5    25
+    #define LCD_PINS_D6    27
+    #define LCD_PINS_D7    29
+
+    #if ENABLED(MINIPANEL)
+      #define DOGLCD_CS    25
+      #define DOGLCD_A0    27
+    #endif
+
   #endif
 
   #if ANY(VIKI2, miniVIKI)
-    #define DOGLCD_A0           16
-    #define KILL_PIN            51
-    #define STAT_LED_BLUE_PIN   29
-    #define STAT_LED_RED_PIN    23
-    #define DOGLCD_CS           17
-    #define DOGLCD_SCK          76   // SCK_PIN   - These are required for DUE Hardware SPI
-    #define DOGLCD_MOSI         75   // MOSI_PIN
-    #define DOGLCD_MISO         74   // MISO_PIN
+    #define DOGLCD_A0      16
+    #define KILL_PIN       51
+    #define STAT_LED_BLUE_PIN 29
+    #define STAT_LED_RED_PIN 23
+    #define DOGLCD_CS      17
+    #define DOGLCD_SCK     76   // SCK_PIN   - Required for DUE Hardware SPI
+    #define DOGLCD_MOSI    75   // MOSI_PIN
+    #define DOGLCD_MISO    74   // MISO_PIN
   #endif
 
-
 #endif // ULTRA_LCD
 
 #if HAS_DRIVER(TMC2208)
@@ -201,10 +240,8 @@
 //
 // M3/M4/M5 - Spindle/Laser Control
 //
-#if ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENA)
-  #if HOTENDS < 3
-    #define SPINDLE_LASER_ENA_PIN     45   // Use E2 ENA
-    #define SPINDLE_LASER_PWM_PIN     12   // MUST BE HARDWARE PWM
-    #define SPINDLE_DIR_PIN           47   // Use E2 DIR
-  #endif
+#if HOTENDS < 3 && ENABLED(SPINDLE_LASER_ENABLE) && !PIN_EXISTS(SPINDLE_LASER_ENA)
+  #define SPINDLE_LASER_ENA_PIN 45   // Use E2 ENA
+  #define SPINDLE_LASER_PWM_PIN 12   // MUST BE HARDWARE PWM
+  #define SPINDLE_DIR_PIN       47   // Use E2 DIR
 #endif
diff --git a/Marlin/src/pins/pins_RAMPS_RE_ARM.h b/Marlin/src/pins/pins_RAMPS_RE_ARM.h
index 9c7bbf4eea..5871b80d15 100644
--- a/Marlin/src/pins/pins_RAMPS_RE_ARM.h
+++ b/Marlin/src/pins/pins_RAMPS_RE_ARM.h
@@ -320,6 +320,7 @@
       #define DOGLCD_MOSI  P0_18
       #define DOGLCD_CS    P1_09  // use Ethernet connector for EXP1 cable signals
       #define DOGLCD_A0    P1_14
+      #define FORCE_SOFT_SPI      // required on a Re-ARM system
     #else
       #define DOGLCD_CS    P0_26   // (63) J5-3 & AUX-2
       #define DOGLCD_A0    P2_06   // (59) J3-8 & AUX-2
diff --git a/Marlin/src/pins/pins_RURAMPS4D_11.h b/Marlin/src/pins/pins_RURAMPS4D_11.h
index 517be5b9b5..718e44651e 100644
--- a/Marlin/src/pins/pins_RURAMPS4D_11.h
+++ b/Marlin/src/pins/pins_RURAMPS4D_11.h
@@ -202,31 +202,24 @@
 //
 #if ENABLED(ULTRA_LCD)
 
-  #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER)
-
+  #if ANY(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER, REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
     #define BEEPER_PIN      62
+    #define LCD_PINS_D4     48
+    #define LCD_PINS_D5     50
+    #define LCD_PINS_D6     52
+    #define LCD_PINS_D7     53
+    #define SD_DETECT_PIN   51
+  #endif
+
+  #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER)
 
     #define LCD_PINS_RS     63
     #define LCD_PINS_ENABLE 64
-    #define LCD_PINS_D4     48
-    #define LCD_PINS_D5     50
-    #define LCD_PINS_D6     52
-    #define LCD_PINS_D7     53
-
-    #define SD_DETECT_PIN   51
 
   #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
 
-    #define BEEPER_PIN      62
-
     #define LCD_PINS_RS     52
     #define LCD_PINS_ENABLE 53
-    #define LCD_PINS_D4     48
-    #define LCD_PINS_D5     50
-    #define LCD_PINS_D6     52
-    #define LCD_PINS_D7     53
-
-    #define SD_DETECT_PIN   51
 
   #elif HAS_SSD1306_OLED_I2C
 
@@ -234,16 +227,57 @@
     #define LCD_SDSS        10
     #define SD_DETECT_PIN   51
 
+  #elif ENABLED(FYSETC_MINI_12864)
+
+    #define BEEPER_PIN      62
+    #define DOGLCD_CS       64
+    #define DOGLCD_A0       63
+
+    //#define FORCE_SOFT_SPI     // Use this if default of hardware SPI causes problems
+
+    #define LCD_RESET_PIN   48   // Must be high or open for LCD to operate normally.
+                                 // Seems to work best if left open.
+
+    #define FYSETC_MINI_12864_REV_1_2
+    //#define FYSETC_MINI_12864_REV_2_0
+    //#define FYSETC_MINI_12864_REV_2_1
+    #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+      #define RGB_LED
+      #ifndef RGB_LED_R_PIN
+        #define RGB_LED_R_PIN 50   // D5
+      #endif
+      #ifndef RGB_LED_G_PIN
+        #define RGB_LED_G_PIN 52   // D6
+      #endif
+      #ifndef RGB_LED_B_PIN
+        #define RGB_LED_B_PIN 53   // D7
+      #endif
+    #elif defined(FYSETC_MINI_12864_REV_2_1)
+      #define NEOPIXEL_LED
+      #define NEOPIXEL_TYPE   NEO_GRB  // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+      #define NEOPIXEL_PIN  50         // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+      #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+      #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+      #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+      #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+    #else
+      #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
+    #endif
+
+    #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+      #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
+    #endif
+
   #elif ENABLED(SPARK_FULL_GRAPHICS)
 
     //http://doku.radds.org/dokumentation/other-electronics/sparklcd/
     #error "Oops! SPARK_FULL_GRAPHICS not supported with RURAMPS4D."
-    //#define LCD_PINS_D4     29//?
-    //#define LCD_PINS_ENABLE 27//?
-    //#define LCD_PINS_RS     25//?
-    //#define BTN_EN1         35//?
-    //#define BTN_EN2         33//?
-    //#define BTN_ENC         37//?
+    //#define LCD_PINS_D4     29   //?
+    //#define LCD_PINS_ENABLE 27   //?
+    //#define LCD_PINS_RS     25   //?
+    //#define BTN_EN1         35   //?
+    //#define BTN_EN2         33   //?
+    //#define BTN_ENC         37   //?
 
   #endif // SPARK_FULL_GRAPHICS
 
diff --git a/Marlin/src/pins/pins_RURAMPS4D_13.h b/Marlin/src/pins/pins_RURAMPS4D_13.h
index ab4aea0f2b..ddae87c245 100644
--- a/Marlin/src/pins/pins_RURAMPS4D_13.h
+++ b/Marlin/src/pins/pins_RURAMPS4D_13.h
@@ -188,31 +188,24 @@
 //
 #if ENABLED(ULTRA_LCD)
 
-  #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER)
-
+  #if ANY(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER, REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
     #define BEEPER_PIN      62
+    #define LCD_PINS_D4     48
+    #define LCD_PINS_D5     50
+    #define LCD_PINS_D6     52
+    #define LCD_PINS_D7     53
+    #define SD_DETECT_PIN   51
+  #endif
+
+  #if EITHER(RADDS_DISPLAY, REPRAP_DISCOUNT_SMART_CONTROLLER)
 
     #define LCD_PINS_RS     63
     #define LCD_PINS_ENABLE 64
-    #define LCD_PINS_D4     48
-    #define LCD_PINS_D5     50
-    #define LCD_PINS_D6     52
-    #define LCD_PINS_D7     53
-
-    #define SD_DETECT_PIN   51
 
   #elif ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
 
-    #define BEEPER_PIN      62
-
     #define LCD_PINS_RS     52
     #define LCD_PINS_ENABLE 53
-    #define LCD_PINS_D4     48
-    #define LCD_PINS_D5     50
-    #define LCD_PINS_D6     52
-    #define LCD_PINS_D7     53
-
-    #define SD_DETECT_PIN   51
 
   #elif HAS_SSD1306_OLED_I2C
 
@@ -220,6 +213,47 @@
     #define LCD_SDSS        10
     #define SD_DETECT_PIN   51
 
+  #elif ENABLED(FYSETC_MINI_12864)
+
+    #define BEEPER_PIN      62
+    #define DOGLCD_CS       64
+    #define DOGLCD_A0       63
+
+    //#define FORCE_SOFT_SPI     // Use this if default of hardware SPI causes problems
+
+    #define LCD_RESET_PIN   48   // Must be high or open for LCD to operate normally.
+                                 // Seems to work best if left open.
+
+    #define FYSETC_MINI_12864_REV_1_2
+    //#define FYSETC_MINI_12864_REV_2_0
+    //#define FYSETC_MINI_12864_REV_2_1
+    #if EITHER(FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0)
+      #define RGB_LED
+      #ifndef RGB_LED_R_PIN
+        #define RGB_LED_R_PIN 50   // D5
+      #endif
+      #ifndef RGB_LED_G_PIN
+        #define RGB_LED_G_PIN 52   // D6
+      #endif
+      #ifndef RGB_LED_B_PIN
+        #define RGB_LED_B_PIN 53   // D7
+      #endif
+    #elif defined(FYSETC_MINI_12864_REV_2_1)
+      #define NEOPIXEL_LED
+      #define NEOPIXEL_TYPE   NEO_GRB  // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
+      #define NEOPIXEL_PIN  50         // LED driving pin on motherboard 4 => D4 (EXP2-5 on Printrboard) / 30 => PC7 (EXP3-13 on Rumba)
+      #define NEOPIXEL_PIXELS  3       // Number of LEDs in the strip
+      #define NEOPIXEL_IS_SEQUENTIAL   // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
+      #define NEOPIXEL_BRIGHTNESS 127  // Initial brightness (0-255)
+      #define NEOPIXEL_STARTUP_TEST    // Cycle through colors at startup
+    #else
+      #error "Either FYSETC_MINI_12864_REV_1_2, FYSETC_MINI_12864_REV_2_0 or FYSETC_MINI_12864_REV_2_1 must be defined"
+    #endif
+
+    #if !defined(LED_USER_PRESET_STARTUP) && EITHER(FYSETC_MINI_12864_REV_2_0, FYSETC_MINI_12864_REV_2_1)
+      #error "LED_USER_PRESET_STARTUP must be enabled when using FYSETC_MINI_12864 REV 2.0 and later"
+    #endif
+
   #elif ENABLED(MKS_MINI_12864)
 
     #define ORIG_BEEPER_PIN 62