diff --git a/esphome/components/it8951/display.py b/esphome/components/it8951/display.py index b5f3019a12..76fbadd196 100644 --- a/esphome/components/it8951/display.py +++ b/esphome/components/it8951/display.py @@ -145,8 +145,8 @@ IT8951Model( reset_pin=12, cs_pin=10, # Board power-enable rails: 1.8V logic supply (GPIO21) and the EPD supply - # (GPIO11). Driven high during setup so no separate power_supply is needed. - enable_pin=[21, 11], + # (GPIO11). Driven high during setup so no separate power_supply is needed, and held low during deep_sleep. + enable_pin=[{"number": 21, "hold_state": True}, {"number": 11, "hold_state": True}], vcom=1400, # reTerminal E1003 panel firmware only accepts the 0x0002 VCOM SET # selector; using the default 0x0001 leaves VCOM unchanged and breaks diff --git a/esphome/components/it8951/it8951.cpp b/esphome/components/it8951/it8951.cpp index 2cfcf111ea..fe99017774 100644 --- a/esphome/components/it8951/it8951.cpp +++ b/esphome/components/it8951/it8951.cpp @@ -351,6 +351,12 @@ void IT8951Display::on_safe_shutdown() { this->spi_cmd_(TCON_SLEEP); } +void IT8951Display::on_powerdown() { + for (auto *pin : this->enable_pins_) { + pin->digital_write(false); + } +} + // --- Init op enqueuers ------------------------------------------------------- void IT8951Display::enqueue_init_reset_() { diff --git a/esphome/components/it8951/it8951.h b/esphome/components/it8951/it8951.h index fcdc6d1d19..e1273587c4 100644 --- a/esphome/components/it8951/it8951.h +++ b/esphome/components/it8951/it8951.h @@ -150,6 +150,7 @@ class IT8951Display : public Display, void loop() override; void dump_config() override; void on_safe_shutdown() override; + void on_powerdown() override; float get_setup_priority() const override { return setup_priority::PROCESSOR; } // --- Config setters (called from generated code) --- diff --git a/tests/component_tests/it8951/__init__.py b/tests/component_tests/it8951/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/component_tests/it8951/test_init.py b/tests/component_tests/it8951/test_init.py new file mode 100644 index 0000000000..46c203e5eb --- /dev/null +++ b/tests/component_tests/it8951/test_init.py @@ -0,0 +1,28 @@ +"""Tests for it8951 configuration validation.""" + +from collections.abc import Callable +from typing import Any + +from esphome.components.const import CONF_HOLD_STATE +from esphome.components.esp32 import KEY_BOARD, KEY_VARIANT, VARIANT_ESP32S3 +from esphome.components.it8951.display import CONFIG_SCHEMA +from esphome.const import CONF_ENABLE_PIN, CONF_NUMBER, PlatformFramework +from tests.component_tests.types import SetCoreConfigCallable + + +def test_reterminal_e1003_enable_pins_hold_state( + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """The reTerminal E1003 enable pins must hold their state during deep sleep.""" + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32-s3-devkitc-1", KEY_VARIANT: VARIANT_ESP32S3}, + ) + set_component_config("spi", {"id": "spi_bus", "clk_pin": 7, "mosi_pin": 9}) + + config = CONFIG_SCHEMA({"id": "test_display", "model": "seeed-reterminal-e1003"}) + + enable_pins = config[CONF_ENABLE_PIN] + assert [pin[CONF_NUMBER] for pin in enable_pins] == [21, 11] + assert all(pin[CONF_HOLD_STATE] for pin in enable_pins)