[wifi] Reject WiFi config on RP2040/RP2350 boards without CYW43 chip

Boards like rpipico2 (Raspberry Pi Pico 2) don't have WiFi hardware
but ESPHome allowed configuring wifi on them, leading to linker errors
from missing CYW43 driver symbols. Add validation to catch this at
config time with a clear error message.

- Add wifi detection to the board generator by checking for
  PICO_CYW43_SUPPORTED=1 in upstream extra_flags
- Add validation in wifi component to reject non-WiFi RP2040 boards

Closes https://github.com/esphome/esphome/issues/14989
This commit is contained in:
J. Nick Koston
2026-03-19 15:57:56 -10:00
parent c2a96ea293
commit ec70166ad2
4 changed files with 36 additions and 1 deletions
+11
View File
@@ -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,16 @@ 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)."""
return boards.BOARDS.get(get_board(), {}).get("wifi", False)
def set_core_data(config):
CORE.data[KEY_RP2040] = {}
CORE.data[KEY_CORE][KEY_TARGET_PLATFORM] = PLATFORM_RP2040
+10
View File
@@ -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",
+7 -1
View File
@@ -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:
+8
View File
@@ -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):