diff --git a/esphome/components/esp32/gpio.py b/esphome/components/esp32/gpio.py index 6950cd58a0..a53649e3e4 100644 --- a/esphome/components/esp32/gpio.py +++ b/esphome/components/esp32/gpio.py @@ -11,6 +11,7 @@ from esphome.const import ( CONF_OUTPUT, CONF_PULLDOWN, CONF_PULLUP, + CONF_IGNORE_STRAPPING_WARNING, ) from esphome import pins from esphome.core import CORE @@ -176,6 +177,7 @@ ESP32_PIN_SCHEMA = cv.All( } ), cv.Optional(CONF_INVERTED, default=False): cv.boolean, + cv.Optional(CONF_IGNORE_STRAPPING_WARNING, default=False): cv.boolean, cv.Optional(CONF_DRIVE_STRENGTH, default="20mA"): cv.All( cv.float_with_unit("current", "mA", optional_unit=True), cv.enum(DRIVE_STRENGTHS), diff --git a/esphome/components/esp32/gpio_esp32.py b/esphome/components/esp32/gpio_esp32.py index 91f006444c..d10b266c7a 100644 --- a/esphome/components/esp32/gpio_esp32.py +++ b/esphome/components/esp32/gpio_esp32.py @@ -9,6 +9,7 @@ from esphome.const import ( CONF_PULLUP, ) import esphome.config_validation as cv +from esphome.pins import check_strapping_pin _ESP_SDIO_PINS = { @@ -35,13 +36,6 @@ def esp32_validate_gpio_pin(value): "flash interface in QUAD IO flash mode.", value, ) - if value in _ESP32_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 (24, 28, 29, 30, 31): # These pins are not exposed in GPIO mux (reason unknown) # but they're missing from IO_MUX list in datasheet @@ -74,4 +68,5 @@ def esp32_validate_supports(value): f"GPIO{num} (34-39) does not support pulldowns.", [CONF_MODE, CONF_PULLDOWN] ) + check_strapping_pin(value, _ESP32_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_c2.py b/esphome/components/esp32/gpio_esp32_c2.py index c444f804a3..0bee7d82bf 100644 --- a/esphome/components/esp32/gpio_esp32_c2.py +++ b/esphome/components/esp32/gpio_esp32_c2.py @@ -1,6 +1,7 @@ import logging from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER +from esphome.pins import check_strapping_pin import esphome.config_validation as cv @@ -12,13 +13,6 @@ _LOGGER = logging.getLogger(__name__) def esp32_c2_validate_gpio_pin(value): if value < 0 or value > 20: raise cv.Invalid(f"Invalid pin number: {value} (must be 0-20)") - if value in _ESP32C2_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, - ) return value @@ -34,4 +28,6 @@ def esp32_c2_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + + check_strapping_pin(value, _ESP32C2_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_c3.py b/esphome/components/esp32/gpio_esp32_c3.py index fc1cef29e5..6c70c09f9e 100644 --- a/esphome/components/esp32/gpio_esp32_c3.py +++ b/esphome/components/esp32/gpio_esp32_c3.py @@ -6,6 +6,7 @@ from esphome.const import ( CONF_NUMBER, ) import esphome.config_validation as cv +from esphome.pins import check_strapping_pin _ESP32C3_SPI_PSRAM_PINS = { 12: "SPIHD", @@ -28,13 +29,6 @@ def esp32_c3_validate_gpio_pin(value): raise cv.Invalid( f"This pin cannot be used on ESP32-C3s and is already used by the SPI/PSRAM interface (function: {_ESP32C3_SPI_PSRAM_PINS[value]})" ) - if value in _ESP32C3_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, - ) return value @@ -50,4 +44,6 @@ def esp32_c3_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + + check_strapping_pin(value, _ESP32C3_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_c6.py b/esphome/components/esp32/gpio_esp32_c6.py index b26b6bc6b4..a1f777c625 100644 --- a/esphome/components/esp32/gpio_esp32_c6.py +++ b/esphome/components/esp32/gpio_esp32_c6.py @@ -3,6 +3,7 @@ import logging from esphome.const import CONF_INPUT, CONF_MODE, CONF_NUMBER import esphome.config_validation as cv +from esphome.pins import check_strapping_pin _ESP32C6_SPI_PSRAM_PINS = { 24: "SPICS0", @@ -26,13 +27,6 @@ def esp32_c6_validate_gpio_pin(value): raise cv.Invalid( f"This pin cannot be used on ESP32-C6s and is already used by the SPI/PSRAM interface (function: {_ESP32C6_SPI_PSRAM_PINS[value]})" ) - if value in _ESP32C6_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, - ) return value @@ -47,4 +41,6 @@ def esp32_c6_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + + check_strapping_pin(value, _ESP32C6_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_s2.py b/esphome/components/esp32/gpio_esp32_s2.py index db244b6259..82449532ec 100644 --- a/esphome/components/esp32/gpio_esp32_s2.py +++ b/esphome/components/esp32/gpio_esp32_s2.py @@ -10,6 +10,7 @@ from esphome.const import ( ) import esphome.config_validation as cv +from esphome.pins import check_strapping_pin _ESP32S2_SPI_PSRAM_PINS = { 26: "SPICS1", @@ -34,13 +35,6 @@ def esp32_s2_validate_gpio_pin(value): raise cv.Invalid( f"This pin cannot be used on ESP32-S2s and is already used by the SPI/PSRAM interface (function: {_ESP32S2_SPI_PSRAM_PINS[value]})" ) - if value in _ESP32S2_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 (22, 23, 24, 25): # These pins are not exposed in GPIO mux (reason unknown) @@ -77,4 +71,5 @@ def esp32_s2_validate_supports(value): f"GPIO{num} does not support pulldowns.", [CONF_MODE, CONF_PULLDOWN] ) + check_strapping_pin(value, _ESP32S2_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/components/esp32/gpio_esp32_s3.py b/esphome/components/esp32/gpio_esp32_s3.py index f729a757c2..8dcbf8c7bb 100644 --- a/esphome/components/esp32/gpio_esp32_s3.py +++ b/esphome/components/esp32/gpio_esp32_s3.py @@ -7,6 +7,7 @@ from esphome.const import ( ) import esphome.config_validation as cv +from esphome.pins import check_strapping_pin _ESP_32S3_SPI_PSRAM_PINS = { 26: "SPICS1", @@ -45,14 +46,6 @@ def esp32_s3_validate_gpio_pin(value): value, ) - if value in _ESP_32S3_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 (22, 23, 24, 25): # These pins are not exposed in GPIO mux (reason unknown) # but they're missing from IO_MUX list in datasheet @@ -71,4 +64,6 @@ def esp32_s3_validate_supports(value): if is_input: # All ESP32 pins support input mode pass + + check_strapping_pin(value, _ESP_32S3_STRAPPING_PINS, _LOGGER) return value diff --git a/esphome/const.py b/esphome/const.py index eb7a5dab09..be561c2880 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -335,6 +335,7 @@ CONF_IDLE_LEVEL = "idle_level" CONF_IDLE_TIME = "idle_time" CONF_IF = "if" CONF_IGNORE_EFUSE_MAC_CRC = "ignore_efuse_mac_crc" +CONF_IGNORE_STRAPPING_WARNING = "ignore_strapping_warning" CONF_IIR_FILTER = "iir_filter" CONF_ILLUMINANCE = "illuminance" CONF_IMPEDANCE = "impedance" diff --git a/esphome/pins.py b/esphome/pins.py index 2ac4cd4b54..cec715b922 100644 --- a/esphome/pins.py +++ b/esphome/pins.py @@ -9,11 +9,11 @@ from esphome.const import ( CONF_OUTPUT, CONF_PULLDOWN, CONF_PULLUP, + CONF_IGNORE_STRAPPING_WARNING, ) from esphome.util import SimpleRegistry from esphome.core import CORE - PIN_SCHEMA_REGISTRY = SimpleRegistry() @@ -146,3 +146,18 @@ internal_gpio_input_pullup_pin_number = _internal_number_creator( CONF_PULLUP: True, } ) + + +def check_strapping_pin(conf, strapping_pin_list, logger): + import esphome.config_validation as cv + + num = conf[CONF_NUMBER] + if num in strapping_pin_list and not conf.get(CONF_IGNORE_STRAPPING_WARNING): + logger.warning( + f"GPIO{num} is a strapping PIN and should only be used for I/O with care.\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", + ) + # mitigate undisciplined use of strapping: + if num not in strapping_pin_list and conf.get(CONF_IGNORE_STRAPPING_WARNING): + raise cv.Invalid(f"GPIO{num} is not a strapping pin") diff --git a/tests/test8.yaml b/tests/test8.yaml index 3ba8aa19ef..cbac2cb833 100644 --- a/tests/test8.yaml +++ b/tests/test8.yaml @@ -65,7 +65,9 @@ i2c: touchscreen: - platform: tt21100 - interrupt_pin: GPIO3 + interrupt_pin: + number: GPIO3 + ignore_strapping_warning: true reset_pin: GPIO48 binary_sensor: