mirror of
https://github.com/esphome/esphome.git
synced 2025-03-13 14:18:14 +00:00
Merge b8835b658d1bb8180f4ba67864a15ad2160c830f into 755b0bbfc7d404d9ce1a4a02ee8c99c4c838e63f
This commit is contained in:
commit
a1cfd624d2
@ -2,13 +2,16 @@ import logging
|
||||
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BOARD,
|
||||
CONF_INPUT,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_OUTPUT,
|
||||
CONF_PULLDOWN,
|
||||
CONF_PULLUP,
|
||||
PLATFORM_ESP32,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
from esphome.pins import check_strapping_pin
|
||||
|
||||
_ESP_SDIO_PINS = {
|
||||
@ -18,14 +21,33 @@ _ESP_SDIO_PINS = {
|
||||
11: "Flash Command",
|
||||
}
|
||||
|
||||
_BOARD_GPIO_PIN_VALIDATION_OVERRIDES = {
|
||||
"adafruit_feather_esp32_v2": [7, 8],
|
||||
"adafruit_qtpy_esp32": [7, 8],
|
||||
"ESP32-Pico-V3-02": [7, 8],
|
||||
}
|
||||
|
||||
_ESP32_STRAPPING_PINS = {0, 2, 5, 12, 15}
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_board_value():
|
||||
if PLATFORM_ESP32 not in CORE.data:
|
||||
return None
|
||||
|
||||
return CORE.data[PLATFORM_ESP32].get(CONF_BOARD)
|
||||
|
||||
|
||||
def esp32_validate_gpio_pin(value):
|
||||
board_value = _get_board_value()
|
||||
|
||||
if value < 0 or value > 39:
|
||||
raise cv.Invalid(f"Invalid pin number: {value} (must be 0-39)")
|
||||
if value in _ESP_SDIO_PINS:
|
||||
if value in _ESP_SDIO_PINS and not (
|
||||
board_value is not None
|
||||
and board_value in _BOARD_GPIO_PIN_VALIDATION_OVERRIDES
|
||||
and value in _BOARD_GPIO_PIN_VALIDATION_OVERRIDES[board_value]
|
||||
):
|
||||
raise cv.Invalid(
|
||||
f"This pin cannot be used on ESP32s and is already used by the flash interface (function: {_ESP_SDIO_PINS[value]})"
|
||||
)
|
||||
|
51
tests/unit_tests/test_gpio_esp32.py
Normal file
51
tests/unit_tests/test_gpio_esp32.py
Normal file
@ -0,0 +1,51 @@
|
||||
import pytest
|
||||
|
||||
from esphome.components.esp32.gpio_esp32 import (
|
||||
_BOARD_GPIO_PIN_VALIDATION_OVERRIDES,
|
||||
esp32_validate_gpio_pin,
|
||||
)
|
||||
from esphome.const import CONF_BOARD, PLATFORM_ESP32
|
||||
from esphome.core import CORE
|
||||
|
||||
|
||||
@pytest.fixture(name="mock_esp32_core")
|
||||
def fixture_mock_esp32_core():
|
||||
CORE.data[PLATFORM_ESP32] = {}
|
||||
yield
|
||||
CORE.data.clear()
|
||||
|
||||
|
||||
def test_gpio_validation_with_board_overrides(mock_esp32_core):
|
||||
# Test valid pin configurations for specific boards
|
||||
for board, allowed_pins in _BOARD_GPIO_PIN_VALIDATION_OVERRIDES.items():
|
||||
CORE.data[PLATFORM_ESP32][CONF_BOARD] = board
|
||||
|
||||
# Test that allowed pins don't raise exceptions
|
||||
for pin in allowed_pins:
|
||||
assert esp32_validate_gpio_pin(pin) == pin
|
||||
|
||||
# Test invalid board
|
||||
CORE.data[PLATFORM_ESP32][CONF_BOARD] = "unknown_board"
|
||||
with pytest.raises(Exception) as exc:
|
||||
esp32_validate_gpio_pin(7)
|
||||
assert "flash interface" in str(exc.value)
|
||||
|
||||
|
||||
def test_gpio_validation_without_board():
|
||||
# Test that SDIO pins are rejected when no board is specified
|
||||
with pytest.raises(Exception) as exc:
|
||||
esp32_validate_gpio_pin(7)
|
||||
assert "flash interface" in str(exc.value)
|
||||
|
||||
|
||||
def test_gpio_validation_invalid_pins(mock_esp32_core):
|
||||
CORE.data[PLATFORM_ESP32][CONF_BOARD] = "adafruit_feather_esp32_v2"
|
||||
|
||||
# Test invalid pin numbers
|
||||
with pytest.raises(Exception) as exc:
|
||||
esp32_validate_gpio_pin(-1)
|
||||
assert "Invalid pin number" in str(exc.value)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
esp32_validate_gpio_pin(40)
|
||||
assert "Invalid pin number" in str(exc.value)
|
Loading…
x
Reference in New Issue
Block a user