From 18904c42f6081391c5ffc096c8acf2ce54dc4a34 Mon Sep 17 00:00:00 2001
From: MastS <51464853+MastS@users.noreply.github.com>
Date: Thu, 13 Jun 2019 04:59:39 +0200
Subject: [PATCH] Fysetc LCD backlight timeout (#14265)

---
 Marlin/src/feature/leds/leds.cpp     | 14 ++++++++++++++
 Marlin/src/feature/leds/leds.h       | 11 +++++++++++
 Marlin/src/feature/leds/neopixel.cpp | 20 +++++++++++---------
 Marlin/src/inc/Conditionals_LCD.h    |  3 +++
 Marlin/src/inc/SanityCheck.h         |  7 +++++++
 Marlin/src/lcd/ultralcd.cpp          | 28 ++++++++++++++++++++++++++++
 6 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp
index 3a9b724216..badab971f6 100644
--- a/Marlin/src/feature/leds/leds.cpp
+++ b/Marlin/src/feature/leds/leds.cpp
@@ -148,4 +148,18 @@ void LEDLights::set_color(const LEDColor &incol
   void LEDLights::toggle() { if (lights_on) set_off(); else update(); }
 #endif
 
+#ifdef LED_BACKLIGHT_TIMEOUT
+
+  millis_t LEDLights::led_off_time; // = 0
+
+  void LEDLights::update_timeout(const bool power_on) {
+    const millis_t ms = millis();
+    if (power_on)
+      reset_timeout(ms);
+    else if (ELAPSED(ms, led_off_time))
+      set_off();
+  }
+
+#endif
+
 #endif // HAS_COLOR_LEDS
diff --git a/Marlin/src/feature/leds/leds.h b/Marlin/src/feature/leds/leds.h
index eafede7dc9..e3b060e267 100644
--- a/Marlin/src/feature/leds/leds.h
+++ b/Marlin/src/feature/leds/leds.h
@@ -201,6 +201,17 @@ public:
     static void toggle();  // swap "off" with color
     static inline void update() { set_color(color); }
   #endif
+
+  #ifdef LED_BACKLIGHT_TIMEOUT
+    private:
+      static millis_t led_off_time;
+    public:
+      static inline void reset_timeout(const millis_t &ms) {
+        led_off_time = ms + LED_BACKLIGHT_TIMEOUT;
+        if (!lights_on) set_default();
+      }
+      static void update_timeout(const bool power_on);
+  #endif
 };
 
 extern LEDLights leds;
diff --git a/Marlin/src/feature/leds/neopixel.cpp b/Marlin/src/feature/leds/neopixel.cpp
index ee2854c27a..1c1afcc5fc 100644
--- a/Marlin/src/feature/leds/neopixel.cpp
+++ b/Marlin/src/feature/leds/neopixel.cpp
@@ -36,10 +36,20 @@
 
 Adafruit_NeoPixel pixels(NEOPIXEL_PIXELS, NEOPIXEL_PIN, NEOPIXEL_TYPE + NEO_KHZ800);
 
+#ifdef NEOPIXEL_BKGD_LED_INDEX
+  void set_neopixel_color_background() {
+    uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR;
+    pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, pixels.Color(background_color[0], background_color[1], background_color[2], background_color[3]));
+  }
+#endif
+
 void set_neopixel_color(const uint32_t color) {
   for (uint16_t i = 0; i < pixels.numPixels(); ++i) {
     #ifdef NEOPIXEL_BKGD_LED_INDEX
-      if (NEOPIXEL_BKGD_LED_INDEX == i) i++;
+      if (i == NEOPIXEL_BKGD_LED_INDEX && color != 0x000000) {
+        set_neopixel_color_background();
+        continue;
+      }
     #endif
     pixels.setPixelColor(i, color);
   }
@@ -52,14 +62,6 @@ void set_neopixel_color_startup(const uint32_t color) {
   pixels.show();
 }
 
-#ifdef NEOPIXEL_BKGD_LED_INDEX
-  void set_neopixel_color_background() {
-    uint8_t background_color[4] = NEOPIXEL_BKGD_COLOR;
-    pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, pixels.Color(background_color[0], background_color[1], background_color[2], background_color[3]));
-    pixels.show();
-  }
-#endif
-
 void setup_neopixel() {
   SET_OUTPUT(NEOPIXEL_PIN);
   pixels.setBrightness(NEOPIXEL_BRIGHTNESS); // 0 - 255 range
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index e458ee6481..69b73a9194 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -150,6 +150,9 @@
   #define LCD_CONTRAST_MAX 255
   #define DEFAULT_LCD_CONTRAST 255
   #define LED_COLORS_REDUCE_GREEN
+  #if POWER_SUPPLY > 0 && EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1)
+    #define LED_BACKLIGHT_TIMEOUT 10000
+  #endif
 
   // Require LED backlighting enabled
   #if EITHER(FYSETC_MINI_12864_1_2, FYSETC_MINI_12864_2_0)
diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h
index 8f66fd74c4..c237c3226b 100644
--- a/Marlin/src/inc/SanityCheck.h
+++ b/Marlin/src/inc/SanityCheck.h
@@ -1500,6 +1500,13 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
   #error "LED_CONTROL_MENU requires BLINKM, RGB_LED, RGBW_LED, PCA9533, PCA9632, or NEOPIXEL_LED."
 #endif
 
+/**
+ * LED Backlight Timeout
+ */
+#if defined(LED_BACKLIGHT_TIMEOUT) && !(EITHER(FYSETC_MINI_12864_2_0, FYSETC_MINI_12864_2_1) && POWER_SUPPLY > 0)
+  #error "LED_BACKLIGHT_TIMEOUT requires a Fysetc Mini Panel and a Power Switch."
+#endif
+
 /**
  * Basic multi hotend duplication mode
  */
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index 4822ebd2d7..cd501ef32c 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -22,6 +22,10 @@
 
 #include "../inc/MarlinConfigPre.h"
 
+#ifdef LED_BACKLIGHT_TIMEOUT
+  #include "../feature/leds/leds.h"
+#endif
+
 // These displays all share the MarlinUI class
 #if HAS_DISPLAY
   #include "ultralcd.h"
@@ -563,6 +567,16 @@ void MarlinUI::status_screen() {
 void MarlinUI::kill_screen(PGM_P lcd_msg) {
   init();
   set_alert_status_P(lcd_msg);
+
+  // RED ALERT. RED ALERT.
+  #ifdef LED_BACKLIGHT_TIMEOUT
+    leds.set_color(LEDColorRed());
+    #ifdef NEOPIXEL_BKGD_LED_INDEX
+      pixels.setPixelColor(NEOPIXEL_BKGD_LED_INDEX, 255, 0, 0, 0);
+      pixels.show();
+    #endif
+  #endif
+
   draw_kill_screen();
 }
 
@@ -714,6 +728,10 @@ void MarlinUI::update() {
   static millis_t next_lcd_update_ms;
   millis_t ms = millis();
 
+  #ifdef LED_BACKLIGHT_TIMEOUT
+    leds.update_timeout(powersupply_on);
+  #endif
+
   #if HAS_LCD_MENU
 
     #if LCD_TIMEOUT_TO_STATUS
@@ -777,6 +795,10 @@ void MarlinUI::update() {
 
       ms = millis();
       next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;  // delay LCD update until after SD activity completes
+
+      #ifdef LED_BACKLIGHT_TIMEOUT
+        leds.reset_timeout(ms);
+      #endif
     }
 
   #endif // SDSUPPORT && SD_DETECT_PIN
@@ -851,10 +873,16 @@ void MarlinUI::update() {
           encoderPosition += (encoderDiff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP);
           encoderDiff = 0;
         }
+
         #if HAS_LCD_MENU && LCD_TIMEOUT_TO_STATUS
           return_to_status_ms = ms + LCD_TIMEOUT_TO_STATUS;
         #endif
+
         refresh(LCDVIEW_REDRAW_NOW);
+
+        #ifdef LED_BACKLIGHT_TIMEOUT
+          leds.reset_timeout(ms);
+        #endif
       }
 
     #endif
-- 
GitLab