diff --git a/components/esp_lcd/include/esp_lcd_panel_ops.h b/components/esp_lcd/include/esp_lcd_panel_ops.h index fcea1db00bc8..f4f9f58c8780 100644 --- a/components/esp_lcd/include/esp_lcd_panel_ops.h +++ b/components/esp_lcd/include/esp_lcd_panel_ops.h @@ -133,6 +133,17 @@ esp_err_t esp_lcd_panel_disp_on_off(esp_lcd_panel_handle_t panel, bool on_off); esp_err_t esp_lcd_panel_disp_off(esp_lcd_panel_handle_t panel, bool off) __attribute__((deprecated("use esp_lcd_panel_disp_on_off instead"))); +/** + * @brief Turn display in sleep mode + * + * @param[in] panel LCD panel handle, which is created by other factory API like `esp_lcd_new_panel_st7789()` + * @param[in] sleep True turn display on sleep mode, False wake up + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_SUPPORTED if this function is not supported by the panel + */ +esp_err_t esp_lcd_panel_disp_sleep(esp_lcd_panel_handle_t panel, bool sleep); + #ifdef __cplusplus } #endif diff --git a/components/esp_lcd/interface/esp_lcd_panel_interface.h b/components/esp_lcd/interface/esp_lcd_panel_interface.h index 463b2d032557..f7b05e272576 100644 --- a/components/esp_lcd/interface/esp_lcd_panel_interface.h +++ b/components/esp_lcd/interface/esp_lcd_panel_interface.h @@ -120,6 +120,17 @@ struct esp_lcd_panel_t { */ esp_err_t (*disp_on_off)(esp_lcd_panel_t *panel, bool on_off); + /** + * @brief Turn display in sleep mode + * + * @param[in] panel LCD panel handle, which is created by other factory API like `esp_lcd_new_panel_st7789()` + * @param[in] sleep True turn display on sleep mode, False wake up + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_SUPPORTED if this function is not supported by the panel + */ + esp_err_t (*disp_sleep)(esp_lcd_panel_t *panel, bool sleep); + void *user_data; /*!< User data, used to store externally customized data */ }; diff --git a/components/esp_lcd/src/esp_lcd_panel_ops.c b/components/esp_lcd/src/esp_lcd_panel_ops.c index b70611e2468d..5f0ebf8eb55c 100644 --- a/components/esp_lcd/src/esp_lcd_panel_ops.c +++ b/components/esp_lcd/src/esp_lcd_panel_ops.c @@ -68,3 +68,13 @@ esp_err_t esp_lcd_panel_disp_off(esp_lcd_panel_handle_t panel, bool off) { return esp_lcd_panel_disp_on_off(panel, !off); } + +esp_err_t esp_lcd_panel_disp_sleep(esp_lcd_panel_handle_t panel, bool sleep) +{ + ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid panel handle"); + if (panel->disp_sleep) { + return panel->disp_sleep(panel, sleep); + } else { + return ESP_ERR_NOT_SUPPORTED; + } +} diff --git a/components/esp_lcd/src/esp_lcd_panel_st7789.c b/components/esp_lcd/src/esp_lcd_panel_st7789.c index 36c39110bf5c..7c4d5284244a 100644 --- a/components/esp_lcd/src/esp_lcd_panel_st7789.c +++ b/components/esp_lcd/src/esp_lcd_panel_st7789.c @@ -40,6 +40,7 @@ static esp_err_t panel_st7789_mirror(esp_lcd_panel_t *panel, bool mirror_x, bool static esp_err_t panel_st7789_swap_xy(esp_lcd_panel_t *panel, bool swap_axes); static esp_err_t panel_st7789_set_gap(esp_lcd_panel_t *panel, int x_gap, int y_gap); static esp_err_t panel_st7789_disp_on_off(esp_lcd_panel_t *panel, bool off); +static esp_err_t panel_st7789_sleep(esp_lcd_panel_t *panel, bool sleep); typedef struct { esp_lcd_panel_t base; @@ -53,6 +54,7 @@ typedef struct { uint8_t colmod_val; // save current value of LCD_CMD_COLMOD register uint8_t ramctl_val_1; uint8_t ramctl_val_2; + bool sleep; } st7789_panel_t; esp_err_t @@ -124,6 +126,7 @@ esp_lcd_new_panel_st7789(const esp_lcd_panel_io_handle_t io, const esp_lcd_panel st7789->base.mirror = panel_st7789_mirror; st7789->base.swap_xy = panel_st7789_swap_xy; st7789->base.disp_on_off = panel_st7789_disp_on_off; + st7789->base.disp_sleep = panel_st7789_sleep; *ret_panel = &(st7789->base); ESP_LOGD(TAG, "new st7789 panel @%p", st7789); @@ -179,6 +182,7 @@ static esp_err_t panel_st7789_init(esp_lcd_panel_t *panel) ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, LCD_CMD_SLPOUT, NULL, 0), TAG, "io tx param LCD_CMD_SLPOUT failed"); vTaskDelay(pdMS_TO_TICKS(100)); + st7789->sleep = false; ESP_RETURN_ON_ERROR(esp_lcd_panel_io_tx_param(io, LCD_CMD_MADCTL, (uint8_t[]) { st7789->madctl_val, }, 1), TAG, "io tx param LCD_CMD_MADCTL failed"); @@ -287,7 +291,12 @@ static esp_err_t panel_st7789_disp_on_off(esp_lcd_panel_t *panel, bool on_off) st7789_panel_t *st7789 = __containerof(panel, st7789_panel_t, base); esp_lcd_panel_io_handle_t io = st7789->io; int command = 0; + if (on_off) { + if (st7789->sleep) { + esp_lcd_panel_io_tx_param(io, LCD_CMD_SLPOUT, NULL, 0); + vTaskDelay(pdMS_TO_TICKS(100)); + } command = LCD_CMD_DISPON; } else { command = LCD_CMD_DISPOFF; @@ -296,3 +305,21 @@ static esp_err_t panel_st7789_disp_on_off(esp_lcd_panel_t *panel, bool on_off) "io tx param LCD_CMD_DISPON/LCD_CMD_DISPOFF failed"); return ESP_OK; } + +static esp_err_t panel_st7789_sleep(esp_lcd_panel_t *panel, bool sleep) +{ + st7789_panel_t *st7789 = __containerof(panel, st7789_panel_t, base); + esp_lcd_panel_io_handle_t io = st7789->io; + int command = 0; + if (sleep) { + command = LCD_CMD_SLPIN; + } else { + command = LCD_CMD_SLPOUT; + } + esp_lcd_panel_io_tx_param(io, command, NULL, 0); + + st7789->sleep = sleep; + vTaskDelay(pdMS_TO_TICKS(100)); + + return ESP_OK; +}