diff --git a/esphome/components/esp32/gpio_esp32_h2.py b/esphome/components/esp32/gpio_esp32_h2.py index 7c3a658b17..f37297764b 100644 --- a/esphome/components/esp32/gpio_esp32_h2.py +++ b/esphome/components/esp32/gpio_esp32_h2.py @@ -2,6 +2,7 @@ import logging import esphome.config_validation as cv from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER +from esphome.pins import check_strapping_pin _ESP32H2_SPI_FLASH_PINS = {6, 7, 15, 16, 17, 18, 19, 20, 21} @@ -15,13 +16,6 @@ _LOGGER = logging.getLogger(__name__) def esp32_h2_validate_gpio_pin(value): if value < 0 or value > 27: raise cv.Invalid(f"Invalid pin number: {value} (must be 0-27)") - if value in _ESP32H2_STRAPPING_PINS: - _LOGGER.warning( - "GPIO%d is a Strapping PIN and should be avoided.\n" - "Attaching external pullup/down resistors to strapping pins can cause unexpected failures.\n" - "See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins", - value, - ) if value in _ESP32H2_SPI_FLASH_PINS: _LOGGER.warning( "GPIO%d is reserved for SPI Flash communication on some ESP32-H2 chip variants.\n" @@ -49,4 +43,5 @@ def esp32_h2_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + check_strapping_pin(value, _ESP32H2_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_p4.py b/esphome/components/esp32/gpio_esp32_p4.py index 650d06e108..34d1b3139d 100644 --- a/esphome/components/esp32/gpio_esp32_p4.py +++ b/esphome/components/esp32/gpio_esp32_p4.py @@ -2,6 +2,7 @@ import logging import esphome.config_validation as cv from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER +from esphome.pins import check_strapping_pin _ESP32P4_USB_JTAG_PINS = {24, 25} @@ -13,13 +14,6 @@ _LOGGER = logging.getLogger(__name__) def esp32_p4_validate_gpio_pin(value): if value < 0 or value > 54: raise cv.Invalid(f"Invalid pin number: {value} (must be 0-54)") - if value in _ESP32P4_STRAPPING_PINS: - _LOGGER.warning( - "GPIO%d is a Strapping PIN and should be avoided.\n" - "Attaching external pullup/down resistors to strapping pins can cause unexpected failures.\n" - "See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins", - value, - ) if value in _ESP32P4_USB_JTAG_PINS: _LOGGER.warning( "GPIO%d is reserved for the USB-Serial-JTAG interface.\n" @@ -40,4 +34,5 @@ def esp32_p4_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + check_strapping_pin(value, _ESP32P4_STRAPPING_PINS, _LOGGER) return value diff --git a/tests/component_tests/mipi_spi/conftest.py b/tests/component_tests/mipi_spi/conftest.py new file mode 100644 index 0000000000..c3070c7965 --- /dev/null +++ b/tests/component_tests/mipi_spi/conftest.py @@ -0,0 +1,43 @@ +"""Tests for mpip_spi configuration validation.""" + +from collections.abc import Callable, Generator + +import pytest + +from esphome import config_validation as cv +from esphome.components.esp32 import KEY_ESP32, KEY_VARIANT, VARIANTS +from esphome.components.esp32.gpio import validate_gpio_pin +from esphome.const import CONF_INPUT, CONF_OUTPUT +from esphome.core import CORE +from esphome.pins import gpio_pin_schema + + +@pytest.fixture +def choose_variant_with_pins() -> Generator[Callable[[list], None]]: + """ + Set the ESP32 variant for the given model based on pins. For ESP32 only since the other platforms + do not have variants. + """ + + def chooser(pins: list) -> None: + for v in VARIANTS: + try: + CORE.data[KEY_ESP32][KEY_VARIANT] = v + for pin in pins: + if pin is not None: + pin = gpio_pin_schema( + { + CONF_INPUT: True, + CONF_OUTPUT: True, + }, + internal=True, + )(pin) + validate_gpio_pin(pin) + return + except cv.Invalid: + continue + raise cv.Invalid( + f"No compatible variant found for pins: {', '.join(map(str, pins))}" + ) + + yield chooser diff --git a/tests/component_tests/mipi_spi/test_init.py b/tests/component_tests/mipi_spi/test_init.py index c4c93866ca..fbb3222812 100644 --- a/tests/component_tests/mipi_spi/test_init.py +++ b/tests/component_tests/mipi_spi/test_init.py @@ -9,13 +9,10 @@ import pytest from esphome import config_validation as cv from esphome.components.esp32 import ( KEY_BOARD, - KEY_ESP32, KEY_VARIANT, VARIANT_ESP32, VARIANT_ESP32S3, - VARIANTS, ) -from esphome.components.esp32.gpio import validate_gpio_pin from esphome.components.mipi import CONF_NATIVE_HEIGHT from esphome.components.mipi_spi.display import ( CONF_BUS_MODE, @@ -32,8 +29,6 @@ from esphome.const import ( CONF_WIDTH, PlatformFramework, ) -from esphome.core import CORE -from esphome.pins import internal_gpio_pin_number from esphome.types import ConfigType from tests.component_tests.types import SetCoreConfigCallable @@ -43,28 +38,6 @@ def run_schema_validation(config: ConfigType) -> None: FINAL_VALIDATE_SCHEMA(CONFIG_SCHEMA(config)) -@pytest.fixture -def choose_variant_with_pins() -> Callable[..., None]: - """ - Set the ESP32 variant for the given model based on pins. For ESP32 only since the other platforms - do not have variants. - """ - - def chooser(*pins: int | str | None) -> None: - for v in VARIANTS: - try: - CORE.data[KEY_ESP32][KEY_VARIANT] = v - for pin in pins: - if pin is not None: - pin = internal_gpio_pin_number(pin) - validate_gpio_pin(pin) - return - except cv.Invalid: - continue - - return chooser - - @pytest.mark.parametrize( ("config", "error_match"), [ @@ -315,7 +288,7 @@ def test_custom_model_with_all_options( def test_all_predefined_models( set_core_config: SetCoreConfigCallable, set_component_config: Callable[[str, Any], None], - choose_variant_with_pins: Callable[..., None], + choose_variant_with_pins: Callable[[list], None], ) -> None: """Test all predefined display models validate successfully with appropriate defaults.""" set_core_config(