From 224371dfc6ba8de61d0255714b942df04c445da7 Mon Sep 17 00:00:00 2001
From: Tanguy Pruvot <tpruvot@users.noreply.github.com>
Date: Tue, 14 Sep 2021 04:07:08 +0200
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20TFT=20Screen/Backlight=20Sleep=20(#?=
 =?UTF-8?q?22617)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Marlin/Configuration.h                        |  2 +
 Marlin/src/MarlinCore.cpp                     |  3 +-
 Marlin/src/inc/Conditionals_LCD.h             |  3 ++
 .../dogm/u8g_dev_tft_upscale_from_128x64.cpp  | 50 +++++++++++++------
 Marlin/src/lcd/marlinui.cpp                   | 17 ++++++-
 Marlin/src/lcd/marlinui.h                     |  6 ++-
 Marlin/src/lcd/menu/menu.cpp                  |  1 +
 Marlin/src/lcd/tft/touch.cpp                  | 33 +++++++++++-
 Marlin/src/lcd/tft/touch.h                    | 10 +++-
 Marlin/src/lcd/tft/ui_1024x600.cpp            |  1 +
 Marlin/src/lcd/tft/ui_320x240.cpp             |  1 +
 Marlin/src/lcd/tft/ui_480x320.cpp             |  1 +
 Marlin/src/lcd/tft/ui_common.cpp              | 21 ++++++++
 Marlin/src/lcd/tft/ui_common.h                |  4 ++
 Marlin/src/lcd/tft_io/tft_io.h                |  1 -
 Marlin/src/lcd/touch/touch_buttons.cpp        | 36 ++++++++++++-
 Marlin/src/lcd/touch/touch_buttons.h          | 11 +++-
 17 files changed, 176 insertions(+), 25 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 741652422f4..12d1ee70649 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -2780,6 +2780,8 @@
   #define BUTTON_DELAY_EDIT  50 // (ms) Button repeat delay for edit screens
   #define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
 
+  //#define TOUCH_IDLE_SLEEP 300 // (secs) Turn off the TFT backlight if set (5mn)
+
   #define TOUCH_SCREEN_CALIBRATION
 
   //#define TOUCH_CALIBRATION_X 12316
diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index 5bbfcd087b7..07a9d0186f2 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -542,6 +542,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
           next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N;               \
           CODE;                                                        \
           queue.inject_P(PSTR(BUTTON##N##_GCODE));                     \
+          TERN_(HAS_LCD_MENU, ui.quick_feedback());                    \
         }                                                              \
       }                                                                \
     }while(0)
@@ -1354,7 +1355,7 @@ void setup() {
   #endif
 
   #if HAS_TOUCH_BUTTONS
-    SETUP_RUN(touch.init());
+    SETUP_RUN(touchBt.init());
   #endif
 
   TERN_(HAS_M206_COMMAND, current_position += home_offset); // Init current position based on home_offset
diff --git a/Marlin/src/inc/Conditionals_LCD.h b/Marlin/src/inc/Conditionals_LCD.h
index 7f8891b5146..023bf464261 100644
--- a/Marlin/src/inc/Conditionals_LCD.h
+++ b/Marlin/src/inc/Conditionals_LCD.h
@@ -1360,6 +1360,9 @@
 
 // This emulated DOGM has 'touch/xpt2046', not 'tft/xpt2046'
 #if ENABLED(TOUCH_SCREEN)
+  #if TOUCH_IDLE_SLEEP
+    #define HAS_TOUCH_SLEEP 1
+  #endif
   #if NONE(TFT_TOUCH_DEVICE_GT911, TFT_TOUCH_DEVICE_XPT2046)
     #define TFT_TOUCH_DEVICE_XPT2046          // ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8
   #endif
diff --git a/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp b/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp
index 9b5f206fa9d..df7b4000a99 100644
--- a/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp
+++ b/Marlin/src/lcd/dogm/u8g_dev_tft_upscale_from_128x64.cpp
@@ -73,13 +73,18 @@ TFT_IO tftio;
 #define HEIGHT LCD_PIXEL_HEIGHT
 #define PAGE_HEIGHT 8
 
-#include "../touch/touch_buttons.h"
-
 #if ENABLED(TOUCH_SCREEN_CALIBRATION)
   #include "../tft_io/touch_calibration.h"
   #include "../marlinui.h"
 #endif
 
+#if HAS_TOUCH_BUTTONS
+  #include "../touch/touch_buttons.h"
+  #if HAS_TOUCH_SLEEP
+    #define HAS_TOUCH_BUTTONS_SLEEP 1
+  #endif
+#endif
+
 #define X_HI (UPSCALE(TFT_PIXEL_OFFSET_X, WIDTH) - 1)
 #define Y_HI (UPSCALE(TFT_PIXEL_OFFSET_Y, HEIGHT) - 1)
 
@@ -340,6 +345,18 @@ static uint8_t page;
   }
 #endif // HAS_TOUCH_BUTTONS
 
+static void u8g_upscale_clear_lcd(u8g_t *u8g, u8g_dev_t *dev, uint16_t *buffer) {
+  setWindow(u8g, dev, 0, 0, (TFT_WIDTH) - 1, (TFT_HEIGHT) - 1);
+  #if HAS_LCD_IO
+    UNUSED(buffer);
+    tftio.WriteMultiple(TFT_MARLINBG_COLOR, (TFT_WIDTH) * (TFT_HEIGHT));
+  #else
+    memset2(buffer, TFT_MARLINBG_COLOR, (TFT_WIDTH) / 2);
+    for (uint16_t i = 0; i < (TFT_HEIGHT) * sq(GRAPHICAL_TFT_UPSCALE); i++)
+      u8g_WriteSequence(u8g, dev, (TFT_WIDTH) / 2, (uint8_t *)buffer);
+  #endif
+}
+
 static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
 
 uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {
@@ -365,27 +382,32 @@ uint8_t u8g_dev_tft_320x240_upscale_from_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, u
       tftio.Init();
       tftio.InitTFT();
       TERN_(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration_reset());
-
-      // Clear Screen
-      setWindow(u8g, dev, 0, 0, (TFT_WIDTH) - 1, (TFT_HEIGHT) - 1);
-      #if HAS_LCD_IO
-        tftio.WriteMultiple(TFT_MARLINBG_COLOR, (TFT_WIDTH) * (TFT_HEIGHT));
-      #else
-        memset2(buffer, TFT_MARLINBG_COLOR, (TFT_WIDTH) / 2);
-        for (uint16_t i = 0; i < (TFT_HEIGHT) * sq(GRAPHICAL_TFT_UPSCALE); i++)
-          u8g_WriteSequence(u8g, dev, (TFT_WIDTH) / 2, (uint8_t *)buffer);
-      #endif
+      u8g_upscale_clear_lcd(u8g, dev, buffer);
       return 0;
 
     case U8G_DEV_MSG_STOP: preinit = true; break;
 
-    case U8G_DEV_MSG_PAGE_FIRST:
+    case U8G_DEV_MSG_PAGE_FIRST: {
       page = 0;
+      #if HAS_TOUCH_BUTTONS_SLEEP
+        static bool sleepCleared;
+        if (touchBt.isSleeping()) {
+          if (!sleepCleared) {
+            sleepCleared = true;
+            u8g_upscale_clear_lcd(u8g, dev, buffer);
+            IF_ENABLED(HAS_TOUCH_BUTTONS, redrawTouchButtons = true);
+          }
+          break;
+        }
+        else
+          sleepCleared = false;
+      #endif
       TERN_(HAS_TOUCH_BUTTONS, drawTouchButtons(u8g, dev));
       setWindow(u8g, dev, TFT_PIXEL_OFFSET_X, TFT_PIXEL_OFFSET_Y, X_HI, Y_HI);
-      break;
+    } break;
 
     case U8G_DEV_MSG_PAGE_NEXT:
+      if (TERN0(HAS_TOUCH_BUTTONS_SLEEP, touchBt.isSleeping())) break;
       if (++page > (HEIGHT / PAGE_HEIGHT)) return 1;
 
       LOOP_L_N(y, PAGE_HEIGHT) {
diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp
index 5e5b7a94bce..40f815a3e7f 100644
--- a/Marlin/src/lcd/marlinui.cpp
+++ b/Marlin/src/lcd/marlinui.cpp
@@ -673,8 +673,20 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
     draw_kill_screen();
   }
 
-  void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
+  #if HAS_TOUCH_SLEEP
+    #if HAS_TOUCH_BUTTONS
+      #include "touch/touch_buttons.h"
+    #else
+      #include "tft/touch.h"
+    #endif
+    // Wake up a sleeping TFT
+    void MarlinUI::wakeup_screen() {
+      TERN(HAS_TOUCH_BUTTONS, touchBt.wakeUp(), touch.wakeUp());
+    }
+  #endif
 
+  void MarlinUI::quick_feedback(const bool clear_buttons/*=true*/) {
+    TERN_(HAS_TOUCH_SLEEP, wakeup_screen()); // Wake up the TFT with most buttons
     TERN_(HAS_LCD_MENU, refresh());
 
     #if HAS_ENCODER_ACTION
@@ -926,7 +938,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
 
         if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2;
 
-        TERN_(HAS_ENCODER_ACTION, touch_buttons = touch.read_buttons());
+        TERN_(HAS_ENCODER_ACTION, touch_buttons = touchBt.read_buttons());
 
       #endif
 
@@ -955,6 +967,7 @@ constexpr uint8_t epps = ENCODER_PULSES_PER_STEP;
             abs_diff = epps;                                            // Treat as a full step size
             encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff;        // ...in the spin direction.
           }
+          TERN_(HAS_TOUCH_SLEEP, if (lastEncoderDiff != encoderDiff) wakeup_screen());
           lastEncoderDiff = encoderDiff;
         #endif
 
diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h
index e947ac9e5e0..be016f8683d 100644
--- a/Marlin/src/lcd/marlinui.h
+++ b/Marlin/src/lcd/marlinui.h
@@ -435,11 +435,15 @@ public:
         static millis_t next_filament_display;
       #endif
 
+      #if HAS_TOUCH_SLEEP
+        static void wakeup_screen();
+      #endif
+
       static void quick_feedback(const bool clear_buttons=true);
       #if HAS_BUZZER
         static void completion_feedback(const bool good=true);
       #else
-        static inline void completion_feedback(const bool=true) {}
+        static inline void completion_feedback(const bool=true) { TERN_(HAS_TOUCH_SLEEP, wakeup_screen()); }
       #endif
 
       #if DISABLED(LIGHTWEIGHT_UI)
diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp
index dd52eb2b5b5..a177f329324 100644
--- a/Marlin/src/lcd/menu/menu.cpp
+++ b/Marlin/src/lcd/menu/menu.cpp
@@ -285,6 +285,7 @@ void scroll_screen(const uint8_t limit, const bool is_menu) {
 
 #if HAS_BUZZER
   void MarlinUI::completion_feedback(const bool good/*=true*/) {
+    TERN_(HAS_TOUCH_SLEEP, wakeup_screen()); // Wake up on rotary encoder click...
     if (good) {
       BUZZ(100, 659);
       BUZZ(100, 698);
diff --git a/Marlin/src/lcd/tft/touch.cpp b/Marlin/src/lcd/tft/touch.cpp
index 64dfaa5755f..7262536e77f 100644
--- a/Marlin/src/lcd/tft/touch.cpp
+++ b/Marlin/src/lcd/tft/touch.cpp
@@ -47,7 +47,10 @@ millis_t Touch::last_touch_ms = 0,
          Touch::time_to_hold,
          Touch::repeat_delay,
          Touch::touch_time;
-TouchControlType  Touch::touch_control_type = NONE;
+TouchControlType Touch::touch_control_type = NONE;
+#if HAS_TOUCH_SLEEP
+  millis_t Touch::next_sleep_ms; // = 0
+#endif
 #if HAS_RESUME_CONTINUE
   extern bool wait_for_user;
 #endif
@@ -56,6 +59,7 @@ void Touch::init() {
   TERN_(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration_reset());
   reset();
   io.Init();
+  TERN_(HAS_TOUCH_SLEEP, wakeUp());
   enable();
 }
 
@@ -271,9 +275,34 @@ bool Touch::get_point(int16_t *x, int16_t *y) {
   #elif ENABLED(TFT_TOUCH_DEVICE_GT911)
     bool is_touched = (TOUCH_ORIENTATION == TOUCH_PORTRAIT ? io.getPoint(y, x) : io.getPoint(x, y));
   #endif
-
+  #if HAS_TOUCH_SLEEP
+    if (is_touched)
+      wakeUp();
+    else if (!isSleeping() && ELAPSED(millis(), next_sleep_ms) && ui.on_status_screen())
+      sleepTimeout();
+  #endif
   return is_touched;
 }
+
+#if HAS_TOUCH_SLEEP
+
+  void Touch::sleepTimeout() {
+    #if PIN_EXISTS(TFT_BACKLIGHT)
+      OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
+    #endif
+    next_sleep_ms = TSLP_SLEEPING;
+  }
+  void Touch::wakeUp() {
+    if (isSleeping()) {
+      #if PIN_EXISTS(TFT_BACKLIGHT)
+        WRITE(TFT_BACKLIGHT_PIN, HIGH);
+      #endif
+    }
+    next_sleep_ms = millis() + SEC_TO_MS(TOUCH_IDLE_SLEEP);
+  }
+
+#endif // HAS_TOUCH_SLEEP
+
 Touch touch;
 
 bool MarlinUI::touch_pressed() {
diff --git a/Marlin/src/lcd/tft/touch.h b/Marlin/src/lcd/tft/touch.h
index 54dfb420d8d..238453f765e 100644
--- a/Marlin/src/lcd/tft/touch.h
+++ b/Marlin/src/lcd/tft/touch.h
@@ -90,6 +90,9 @@ typedef struct __attribute__((__packed__)) {
 #define UBL_REPEAT_DELAY    125
 #define FREE_MOVE_RANGE     32
 
+#define TSLP_PREINIT  0
+#define TSLP_SLEEPING 1
+
 class Touch {
   private:
     static TOUCH_DRIVER_CLASS io;
@@ -121,7 +124,12 @@ class Touch {
     }
     static void disable() { enabled = false; }
     static void enable() { enabled = true; }
-
+    #if HAS_TOUCH_SLEEP
+      static millis_t next_sleep_ms;
+      static inline bool isSleeping() { return next_sleep_ms == TSLP_SLEEPING; }
+      static void sleepTimeout();
+      static void wakeUp();
+    #endif
     static void add_control(TouchControlType type, uint16_t x, uint16_t y, uint16_t width, uint16_t height, intptr_t data = 0);
 };
 
diff --git a/Marlin/src/lcd/tft/ui_1024x600.cpp b/Marlin/src/lcd/tft/ui_1024x600.cpp
index 18c50c92f7a..db75c36ef9f 100644
--- a/Marlin/src/lcd/tft/ui_1024x600.cpp
+++ b/Marlin/src/lcd/tft/ui_1024x600.cpp
@@ -47,6 +47,7 @@
 
 void MarlinUI::tft_idle() {
   #if ENABLED(TOUCH_SCREEN)
+    if (TERN0(HAS_TOUCH_SLEEP, lcd_sleep_task())) return;
     if (draw_menu_navigation) {
       add_control(164, TFT_HEIGHT - 50, PAGE_UP, imgPageUp, encoderTopLine > 0);
       add_control(796, TFT_HEIGHT - 50, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items);
diff --git a/Marlin/src/lcd/tft/ui_320x240.cpp b/Marlin/src/lcd/tft/ui_320x240.cpp
index 786dc61f60d..deffbae94cb 100644
--- a/Marlin/src/lcd/tft/ui_320x240.cpp
+++ b/Marlin/src/lcd/tft/ui_320x240.cpp
@@ -47,6 +47,7 @@
 
 void MarlinUI::tft_idle() {
   #if ENABLED(TOUCH_SCREEN)
+    if (TERN0(HAS_TOUCH_SLEEP, lcd_sleep_task())) return;
     if (draw_menu_navigation) {
       add_control(48, 206, PAGE_UP, imgPageUp, encoderTopLine > 0);
       add_control(240, 206, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items);
diff --git a/Marlin/src/lcd/tft/ui_480x320.cpp b/Marlin/src/lcd/tft/ui_480x320.cpp
index 02e3354d93a..c8333f7e4bf 100644
--- a/Marlin/src/lcd/tft/ui_480x320.cpp
+++ b/Marlin/src/lcd/tft/ui_480x320.cpp
@@ -47,6 +47,7 @@
 
 void MarlinUI::tft_idle() {
   #if ENABLED(TOUCH_SCREEN)
+    if (TERN0(HAS_TOUCH_SLEEP, lcd_sleep_task())) return;
     if (draw_menu_navigation) {
       add_control(104, TFT_HEIGHT - 34, PAGE_UP, imgPageUp, encoderTopLine > 0);
       add_control(344, TFT_HEIGHT - 34, PAGE_DOWN, imgPageDown, encoderTopLine + LCD_HEIGHT < screen_items);
diff --git a/Marlin/src/lcd/tft/ui_common.cpp b/Marlin/src/lcd/tft/ui_common.cpp
index 7c053e7be71..a5f41874b09 100644
--- a/Marlin/src/lcd/tft/ui_common.cpp
+++ b/Marlin/src/lcd/tft/ui_common.cpp
@@ -37,6 +37,27 @@ static xy_uint_t cursor;
   bool draw_menu_navigation = false;
 #endif
 
+#if HAS_TOUCH_SLEEP
+
+  bool lcd_sleep_task() {
+    static bool sleepCleared;
+    if (touch.isSleeping()) {
+      tft.queue.reset();
+      if (!sleepCleared) {
+        sleepCleared = true;
+        ui.clear_lcd();
+        tft.queue.async();
+      }
+      touch.idle();
+      return true;
+    }
+    else
+      sleepCleared = false;
+    return false;
+  }
+
+#endif
+
 void menu_line(const uint8_t row, uint16_t color) {
   cursor.set(0, row);
   tft.canvas(0, TFT_TOP_LINE_Y + cursor.y * MENU_LINE_HEIGHT, TFT_WIDTH, MENU_ITEM_HEIGHT);
diff --git a/Marlin/src/lcd/tft/ui_common.h b/Marlin/src/lcd/tft/ui_common.h
index 759712b64c1..d3ffd4bc31a 100644
--- a/Marlin/src/lcd/tft/ui_common.h
+++ b/Marlin/src/lcd/tft/ui_common.h
@@ -51,6 +51,10 @@ void draw_fan_status(uint16_t x, uint16_t y, const bool blink);
 void menu_line(const uint8_t row, uint16_t color=COLOR_BACKGROUND);
 void menu_item(const uint8_t row, bool sel = false);
 
+#if HAS_TOUCH_SLEEP
+  bool lcd_sleep_task();
+#endif
+
 #define ABSOLUTE_ZERO     -273.15
 
 #if HAS_TEMP_CHAMBER && HOTENDS > 1
diff --git a/Marlin/src/lcd/tft_io/tft_io.h b/Marlin/src/lcd/tft_io/tft_io.h
index 0e4322f0d71..65602240d63 100644
--- a/Marlin/src/lcd/tft_io/tft_io.h
+++ b/Marlin/src/lcd/tft_io/tft_io.h
@@ -59,7 +59,6 @@
   #define TFT_ROTATION TFT_NO_ROTATION
 #endif
 
-
 // TFT_ORIENTATION is the "sum" of TFT_DEFAULT_ORIENTATION plus user TFT_ROTATION
 #define TFT_ORIENTATION ((TFT_DEFAULT_ORIENTATION) ^ (TFT_ROTATION))
 
diff --git a/Marlin/src/lcd/touch/touch_buttons.cpp b/Marlin/src/lcd/touch/touch_buttons.cpp
index c9476bd2bb0..2d6158961ec 100644
--- a/Marlin/src/lcd/touch/touch_buttons.cpp
+++ b/Marlin/src/lcd/touch/touch_buttons.cpp
@@ -38,6 +38,10 @@
   #include "../tft_io/touch_calibration.h"
 #endif
 
+#if HAS_TOUCH_SLEEP
+  millis_t TouchButtons::next_sleep_ms;
+#endif
+
 #include "../buttons.h" // For EN_C bit mask
 #include "../marlinui.h" // For ui.refresh
 #include "../tft_io/tft_io.h"
@@ -50,15 +54,24 @@
 #define BUTTON_AREA_TOP BUTTON_Y_LO
 #define BUTTON_AREA_BOT BUTTON_Y_HI
 
-TouchButtons touch;
+TouchButtons touchBt;
 
-void TouchButtons::init() { touchIO.Init(); }
+void TouchButtons::init() {
+  touchIO.Init();
+  TERN_(HAS_TOUCH_SLEEP, next_sleep_ms = millis() + SEC_TO_MS(TOUCH_IDLE_SLEEP));
+}
 
 uint8_t TouchButtons::read_buttons() {
   #ifdef HAS_WIRED_LCD
     int16_t x, y;
 
     const bool is_touched = (TERN(TOUCH_SCREEN_CALIBRATION, touch_calibration.calibration.orientation, TOUCH_ORIENTATION) == TOUCH_PORTRAIT ? touchIO.getRawPoint(&y, &x) : touchIO.getRawPoint(&x, &y));
+    #if HAS_TOUCH_SLEEP
+      if (is_touched)
+        wakeUp();
+      else if (!isSleeping() && ELAPSED(millis(), next_sleep_ms) && ui.on_status_screen())
+        sleepTimeout();
+    #endif
     if (!is_touched) return 0;
 
     #if ENABLED(TOUCH_SCREEN_CALIBRATION)
@@ -96,4 +109,23 @@ uint8_t TouchButtons::read_buttons() {
   return 0;
 }
 
+#if HAS_TOUCH_SLEEP
+
+  void TouchButtons::sleepTimeout() {
+    #if PIN_EXISTS(TFT_BACKLIGHT)
+      OUT_WRITE(TFT_BACKLIGHT_PIN, LOW);
+    #endif
+    next_sleep_ms = TSLP_SLEEPING;
+  }
+  void TouchButtons::wakeUp() {
+    if (isSleeping()) {
+      #if PIN_EXISTS(TFT_BACKLIGHT)
+        WRITE(TFT_BACKLIGHT_PIN, HIGH);
+      #endif
+    }
+    next_sleep_ms = millis() + SEC_TO_MS(TOUCH_IDLE_SLEEP);
+  }
+
+#endif // HAS_TOUCH_SLEEP
+
 #endif // HAS_TOUCH_BUTTONS
diff --git a/Marlin/src/lcd/touch/touch_buttons.h b/Marlin/src/lcd/touch/touch_buttons.h
index a79bb15be42..36be0ee1345 100644
--- a/Marlin/src/lcd/touch/touch_buttons.h
+++ b/Marlin/src/lcd/touch/touch_buttons.h
@@ -50,10 +50,19 @@
 #define BUTTON_Y_HI (TFT_HEIGHT) - BUTTON_SPACING
 #define BUTTON_Y_LO BUTTON_Y_HI - BUTTON_HEIGHT
 
+#define TSLP_PREINIT  0
+#define TSLP_SLEEPING 1
+
 class TouchButtons {
 public:
   static void init();
   static uint8_t read_buttons();
+  #if HAS_TOUCH_SLEEP
+    static millis_t next_sleep_ms;
+    static bool isSleeping() { return next_sleep_ms == TSLP_SLEEPING; }
+    static void sleepTimeout();
+    static void wakeUp();
+  #endif
 };
 
-extern TouchButtons touch;
+extern TouchButtons touchBt;