mirror of
https://github.com/esphome/esphome.git
synced 2026-03-24 15:06:08 +08:00
[wifi] Reject WiFi config on RP2040/RP2350 boards without CYW43 chip (#14990)
This commit is contained in:
@@ -24,6 +24,7 @@ from esphome.const import (
|
||||
from esphome.core import CORE, CoroPriority, EsphomeError, coroutine_with_priority
|
||||
from esphome.helpers import copy_file_if_changed, read_file, write_file_if_changed
|
||||
|
||||
from . import boards
|
||||
from .const import KEY_BOARD, KEY_PIO_FILES, KEY_RP2040, rp2040_ns
|
||||
|
||||
# force import gpio to register pin schema
|
||||
@@ -35,6 +36,23 @@ AUTO_LOAD = ["preferences"]
|
||||
IS_TARGET_PLATFORM = True
|
||||
|
||||
|
||||
def get_board() -> str:
|
||||
"""Return the configured board name."""
|
||||
return CORE.data[KEY_RP2040][KEY_BOARD]
|
||||
|
||||
|
||||
def board_has_wifi() -> bool:
|
||||
"""Return True if the configured board has WiFi (CYW43 wireless chip).
|
||||
|
||||
Returns True for unknown/custom boards to avoid rejecting valid
|
||||
configurations for boards not in the generated list.
|
||||
"""
|
||||
board_info = boards.BOARDS.get(get_board())
|
||||
if board_info is None:
|
||||
return True
|
||||
return board_info.get("wifi", False)
|
||||
|
||||
|
||||
def set_core_data(config):
|
||||
CORE.data[KEY_RP2040] = {}
|
||||
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_RP2040
|
||||
|
||||
@@ -1910,6 +1910,7 @@ BOARDS = {
|
||||
"name": "Pimoroni PicoPlus2W",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"pimoroni_plasma2040": {
|
||||
@@ -1926,6 +1927,7 @@ BOARDS = {
|
||||
"name": "Pimoroni Plasma2350W",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
},
|
||||
"pimoroni_servo2040": {
|
||||
"name": "Pimoroni Servo2040",
|
||||
@@ -1976,12 +1978,14 @@ BOARDS = {
|
||||
"name": "Raspberry Pi Pico 2W",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"rpipicow": {
|
||||
"name": "Raspberry Pi Pico W",
|
||||
"mcu": "rp2040",
|
||||
"max_pin": 29,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"sea_picro": {
|
||||
@@ -2013,6 +2017,7 @@ BOARDS = {
|
||||
"name": "Soldered Electronics NULA RP2350",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
},
|
||||
"solderparty_rp2040_stamp": {
|
||||
"name": "Solder Party RP2040 Stamp",
|
||||
@@ -2038,6 +2043,7 @@ BOARDS = {
|
||||
"name": "SparkFun IoT RedBoard RP2350",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
},
|
||||
"sparkfun_micromodrp2040": {
|
||||
"name": "SparkFun MicroMod RP2040",
|
||||
@@ -2063,18 +2069,21 @@ BOARDS = {
|
||||
"name": "SparkFun Thing Plus RP2350",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"sparkfun_xrp_controller": {
|
||||
"name": "SparkFun XRP Controller",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"sparkfun_xrp_controller_beta": {
|
||||
"name": "SparkFun XRP Controller (Beta)",
|
||||
"mcu": "rp2040",
|
||||
"max_pin": 29,
|
||||
"wifi": True,
|
||||
"max_virtual_pin": 64,
|
||||
},
|
||||
"upesy_rp2040_devkit": {
|
||||
@@ -2161,6 +2170,7 @@ BOARDS = {
|
||||
"name": "Waveshare RP2350B Plus W",
|
||||
"mcu": "rp2350",
|
||||
"max_pin": 47,
|
||||
"wifi": True,
|
||||
},
|
||||
"wiznet_5100s_evb_pico": {
|
||||
"name": "WIZnet W5100S-EVB-Pico",
|
||||
|
||||
@@ -78,11 +78,17 @@ def load_boards(arduino_pico_path: Path) -> tuple[dict, dict]:
|
||||
|
||||
display_name = f"{vendor} {name}".strip() if vendor else name
|
||||
|
||||
boards[board_name] = {
|
||||
extra_flags = build.get("extra_flags", "")
|
||||
has_wifi = "PICO_CYW43_SUPPORTED=1" in extra_flags
|
||||
|
||||
board_entry: dict = {
|
||||
"name": display_name,
|
||||
"mcu": mcu,
|
||||
"max_pin": MCU_MAX_PIN.get(mcu, DEFAULT_MAX_PIN),
|
||||
}
|
||||
if has_wifi:
|
||||
board_entry["wifi"] = True
|
||||
boards[board_name] = board_entry
|
||||
|
||||
# Get pins for this variant
|
||||
if variant not in variant_pins_cache:
|
||||
|
||||
@@ -235,6 +235,14 @@ def validate_variant(_):
|
||||
variant = get_esp32_variant()
|
||||
if variant in NO_WIFI_VARIANTS and "esp32_hosted" not in fv.full_config.get():
|
||||
raise cv.Invalid(f"WiFi requires component esp32_hosted on {variant}")
|
||||
if CORE.is_rp2040:
|
||||
from esphome.components.rp2040 import board_has_wifi, get_board
|
||||
|
||||
if not board_has_wifi():
|
||||
raise cv.Invalid(
|
||||
f"Board '{get_board()}' does not have WiFi support (no CYW43 wireless chip). "
|
||||
f"Use a WiFi-capable board like 'rpipicow' or 'rpipico2w'."
|
||||
)
|
||||
|
||||
|
||||
def _apply_min_auth_mode_default(config):
|
||||
|
||||
@@ -59,6 +59,7 @@ def _add_board(
|
||||
vendor: str = "",
|
||||
name: str | None = None,
|
||||
pins_header: str | None = None,
|
||||
extra_flags: str = "",
|
||||
) -> None:
|
||||
"""Add a board JSON and variant to the fake arduino-pico tree."""
|
||||
if variant is None:
|
||||
@@ -69,11 +70,15 @@ def _add_board(
|
||||
json_dir = arduino_pico / "tools" / "json"
|
||||
variants_dir = arduino_pico / "variants"
|
||||
|
||||
build: dict = {
|
||||
"mcu": mcu,
|
||||
"variant": variant,
|
||||
}
|
||||
if extra_flags:
|
||||
build["extra_flags"] = extra_flags
|
||||
|
||||
board_json = {
|
||||
"build": {
|
||||
"mcu": mcu,
|
||||
"variant": variant,
|
||||
},
|
||||
"build": build,
|
||||
"name": name,
|
||||
"vendor": vendor,
|
||||
}
|
||||
@@ -271,3 +276,35 @@ def test_placeholder_pins_not_treated_as_virtual(arduino_pico: Path) -> None:
|
||||
|
||||
assert "MISO" not in board_pins["badpin"]
|
||||
assert boards["badpin"]["max_virtual_pin"] == 64
|
||||
|
||||
|
||||
def test_cyw43_supported_flag_sets_wifi(arduino_pico: Path) -> None:
|
||||
"""Boards with PICO_CYW43_SUPPORTED=1 in extra_flags should have wifi=True."""
|
||||
_add_board(
|
||||
arduino_pico,
|
||||
"rpipicow",
|
||||
vendor="Raspberry Pi",
|
||||
name="Pico W",
|
||||
pins_header=PICOW_PINS_HEADER,
|
||||
extra_flags="-DARDUINO_RASPBERRY_PI_PICO_W -DPICO_CYW43_SUPPORTED=1 -DCYW43_PIN_WL_DYNAMIC=1",
|
||||
)
|
||||
|
||||
_, boards = load_boards(arduino_pico)
|
||||
|
||||
assert boards["rpipicow"]["wifi"] is True
|
||||
|
||||
|
||||
def test_board_without_cyw43_has_no_wifi(arduino_pico: Path) -> None:
|
||||
"""Boards without PICO_CYW43_SUPPORTED should not have wifi field."""
|
||||
_add_board(
|
||||
arduino_pico,
|
||||
"rpipico",
|
||||
vendor="Raspberry Pi",
|
||||
name="Pico",
|
||||
pins_header=PICO_PINS_HEADER,
|
||||
extra_flags="-DARDUINO_RASPBERRY_PI_PICO",
|
||||
)
|
||||
|
||||
_, boards = load_boards(arduino_pico)
|
||||
|
||||
assert "wifi" not in boards["rpipico"]
|
||||
|
||||
Reference in New Issue
Block a user