From 5e58b312e26cf09efe2dfba9af3d13f28d678866 Mon Sep 17 00:00:00 2001 From: Clyde Stubbs <2366188+clydebarrow@users.noreply.github.com> Date: Mon, 31 Aug 2026 21:20:20 +1000 Subject: [PATCH] [mipi_rgb] Add ESP32S31 support (#18914) --- esphome/components/mipi_rgb/display.py | 9 ++- esphome/components/mipi_rgb/mipi_rgb.cpp | 5 +- esphome/components/mipi_rgb/mipi_rgb.h | 2 +- .../mipi_rgb/test_mipi_rgb_config.py | 59 ++++++++++++++++++- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/esphome/components/mipi_rgb/display.py b/esphome/components/mipi_rgb/display.py index e23e19a000..b91528160e 100644 --- a/esphome/components/mipi_rgb/display.py +++ b/esphome/components/mipi_rgb/display.py @@ -12,7 +12,12 @@ from esphome.components.const import ( CONF_DRAW_ROUNDING, ) from esphome.components.display import CONF_SHOW_TEST_CARD -from esphome.components.esp32 import VARIANT_ESP32P4, VARIANT_ESP32S3, only_on_variant +from esphome.components.esp32 import ( + VARIANT_ESP32P4, + VARIANT_ESP32S3, + VARIANT_ESP32S31, + only_on_variant, +) from esphome.components.mipi import ( COLOR_ORDERS, CONF_DE_PIN, @@ -226,7 +231,7 @@ def _config_schema(config: ConfigType) -> ConfigType: config = cv.All( schema, cv.only_on_esp32, - only_on_variant(supported=[VARIANT_ESP32S3, VARIANT_ESP32P4]), + only_on_variant(supported=[VARIANT_ESP32S3, VARIANT_ESP32P4, VARIANT_ESP32S31]), )(config) model = MODELS[config[CONF_MODEL].upper()] model.check_requirements() diff --git a/esphome/components/mipi_rgb/mipi_rgb.cpp b/esphome/components/mipi_rgb/mipi_rgb.cpp index 7421d8ad83..aeb04c155c 100644 --- a/esphome/components/mipi_rgb/mipi_rgb.cpp +++ b/esphome/components/mipi_rgb/mipi_rgb.cpp @@ -1,4 +1,4 @@ -#if defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) +#if defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S31) #include "mipi_rgb.h" #include "esphome/core/gpio.h" #include "esphome/core/hal.h" @@ -400,4 +400,5 @@ void MipiRgb::dump_config() { } } // namespace esphome::mipi_rgb -#endif // defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) +#endif // defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) || + // defined(USE_ESP32_VARIANT_ESP32S31) diff --git a/esphome/components/mipi_rgb/mipi_rgb.h b/esphome/components/mipi_rgb/mipi_rgb.h index 1480004833..87b35781e2 100644 --- a/esphome/components/mipi_rgb/mipi_rgb.h +++ b/esphome/components/mipi_rgb/mipi_rgb.h @@ -1,6 +1,6 @@ #pragma once -#if defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) +#if defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4) || defined(USE_ESP32_VARIANT_ESP32S31) #include "esphome/core/gpio.h" #include "esphome/components/display/display.h" #include "esp_lcd_panel_ops.h" diff --git a/tests/component_tests/mipi_rgb/test_mipi_rgb_config.py b/tests/component_tests/mipi_rgb/test_mipi_rgb_config.py index e85327c0ab..497aba4df1 100644 --- a/tests/component_tests/mipi_rgb/test_mipi_rgb_config.py +++ b/tests/component_tests/mipi_rgb/test_mipi_rgb_config.py @@ -10,7 +10,13 @@ from esphome import config_validation as cv # via ch422g) can be validated by the mipi_rgb CONFIG_SCHEMA in this test. import esphome.components.ch422g # noqa: F401 from esphome.components.display import get_display_metadata -from esphome.components.esp32 import KEY_BOARD, VARIANT_ESP32S3 +from esphome.components.esp32 import ( + KEY_BOARD, + VARIANT_ESP32C3, + VARIANT_ESP32P4, + VARIANT_ESP32S3, + VARIANT_ESP32S31, +) import esphome.components.pca9554 # noqa: F401 import esphome.components.xl9535 # noqa: F401 from esphome.const import ( @@ -135,3 +141,54 @@ def test_metadata_records_rotation( config = CONFIG_SCHEMA({**base, "id": "unrotated"}) assert get_display_metadata(config["id"]).rotation == 0 + + +@pytest.mark.parametrize( + ("variant", "board"), + [ + (VARIANT_ESP32S3, "esp32-s3-devkitc-1"), + (VARIANT_ESP32P4, "esp32-p4-evboard"), + # No dedicated board is registered for ESP32-S31 yet; an unknown board + # name simply skips per-board pin validation. + (VARIANT_ESP32S31, "esp32-s31-devkitc"), + ], +) +def test_configuration_succeeds_on_supported_variants( + variant: str, board: str, set_core_config: SetCoreConfigCallable +) -> None: + """mipi_rgb requires a chip with an RGB LCD peripheral: S3, P4 or S31.""" + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: board, KEY_VARIANT: variant}, + ) + + from esphome.components.mipi_rgb.display import CONFIG_SCHEMA + + CONFIG_SCHEMA({"model": "ESP32-8048S070", "data_pins": DATA_PINS, "pclk_pin": 21}) + + +def test_only_on_variant_rejects_unsupported_variant( + set_core_config: SetCoreConfigCallable, +) -> None: + """A variant without the RGB LCD peripheral (e.g. ESP32-C3) is rejected. + + Exercises the exact ``only_on_variant`` call used by ``mipi_rgb.display`` + directly, since building a full model config with GPIO numbers that are + also valid on an unsupported variant like ESP32-C3 is unrelated to what + this checks. + """ + from esphome.components.esp32 import only_on_variant + + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_VARIANT: VARIANT_ESP32C3}, + ) + + validator = only_on_variant( + supported=[VARIANT_ESP32S3, VARIANT_ESP32P4, VARIANT_ESP32S31] + ) + with pytest.raises( + cv.Invalid, + match=r"This feature is only available on ESP32S3, ESP32P4, ESP32S31", + ): + validator({})