From 9a97419cfc06265e636a65f76944125adc4276d2 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 5 Oct 2026 10:21:23 -0500 Subject: [PATCH] [ethernet] Store PHY registers in a StaticVector sized from the config (#20131) --- esphome/components/ethernet/__init__.py | 29 ++++++++++--------- .../components/ethernet/ethernet_component.h | 10 +++++-- .../ethernet/ethernet_component_esp32.cpp | 8 ++--- esphome/core/defines.h | 1 + tests/components/ethernet/common-rtl8201.yaml | 6 ++++ 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/esphome/components/ethernet/__init__.py b/esphome/components/ethernet/__init__.py index ce7206bf57..ff05caca83 100644 --- a/esphome/components/ethernet/__init__.py +++ b/esphome/components/ethernet/__init__.py @@ -636,6 +636,19 @@ def phy_register(address: int, value: int, page: int) -> cg.StructInitializer: ) +def _add_phy_registers(var: cg.MockObj, config: ConfigType) -> None: + if not (registers := config.get(CONF_PHY_REGISTERS)): + return + cg.add_define("ESPHOME_ETHERNET_PHY_REGISTER_COUNT", len(registers)) + for register_value in registers: + reg = phy_register( + register_value.get(CONF_ADDRESS), + register_value.get(CONF_VALUE), + register_value.get(CONF_PAGE_ID), + ) + cg.add(var.add_phy_register(reg)) + + @coroutine_with_priority(CoroPriority.COMMUNICATION) async def to_code(config: ConfigType) -> None: var = cg.new_Pvariable(config[CONF_ID]) @@ -741,13 +754,7 @@ async def _to_code_esp32(var: cg.MockObj, config: ConfigType) -> None: cg.add(var.set_mdio_pin(config[CONF_MDIO_PIN])) if CONF_POWER_PIN in config: cg.add(var.set_power_pin(config[CONF_POWER_PIN])) - for register_value in config.get(CONF_PHY_REGISTERS, []): - reg = phy_register( - register_value.get(CONF_ADDRESS), - register_value.get(CONF_VALUE), - register_value.get(CONF_PAGE_ID), - ) - cg.add(var.add_phy_register(reg)) + _add_phy_registers(var, config) else: cg.add(var.set_phy_addr(config[CONF_PHY_ADDR])) cg.add(var.set_mdc_pin(config[CONF_MDC_PIN])) @@ -756,13 +763,7 @@ async def _to_code_esp32(var: cg.MockObj, config: ConfigType) -> None: cg.add(var.set_clk_pin(config[CONF_CLK][CONF_PIN])) if CONF_POWER_PIN in config: cg.add(var.set_power_pin(config[CONF_POWER_PIN])) - for register_value in config.get(CONF_PHY_REGISTERS, []): - reg = phy_register( - register_value.get(CONF_ADDRESS), - register_value.get(CONF_VALUE), - register_value.get(CONF_PAGE_ID), - ) - cg.add(var.add_phy_register(reg)) + _add_phy_registers(var, config) # Register Ethernet with the esp32 sdkconfig reconciler. It disables the # WiFi stack and WiFi/BT coexistence only when Ethernet runs without WiFi, diff --git a/esphome/components/ethernet/ethernet_component.h b/esphome/components/ethernet/ethernet_component.h index 71fa9d40b6..44c4d6733d 100644 --- a/esphome/components/ethernet/ethernet_component.h +++ b/esphome/components/ethernet/ethernet_component.h @@ -193,7 +193,9 @@ class EthernetComponent final : public Component { void set_mdio_pin(uint8_t mdio_pin) { this->mdio_pin_ = mdio_pin; } void set_clk_pin(uint8_t clk_pin) { this->clk_pin_ = clk_pin; } void set_clk_mode(emac_rmii_clock_mode_t clk_mode) { this->clk_mode_ = clk_mode; } - void add_phy_register(PHYRegister register_value); +#ifdef ESPHOME_ETHERNET_PHY_REGISTER_COUNT + void add_phy_register(PHYRegister register_value) { this->phy_registers_.push_back(register_value); } +#endif #endif // USE_ETHERNET_SPI #endif // USE_ESP32 @@ -255,8 +257,10 @@ class EthernetComponent final : public Component { /// reset) and set the RGMII Tx/Rx clock delays needed for reliable data sampling. void yt8531_phy_init_(); #endif +#ifdef ESPHOME_ETHERNET_PHY_REGISTER_COUNT /// @brief Set arbitratry PHY registers from config. void write_phy_register_(esp_eth_mac_t *mac, PHYRegister register_data); +#endif #ifdef USE_ETHERNET_SPI uint8_t clk_pin_; @@ -280,7 +284,9 @@ class EthernetComponent final : public Component { // Group all 32-bit members first int power_pin_{-1}; emac_rmii_clock_mode_t clk_mode_{EMAC_CLK_EXT_IN}; - std::vector phy_registers_{}; +#ifdef ESPHOME_ETHERNET_PHY_REGISTER_COUNT + StaticVector phy_registers_{}; +#endif // Group all 8-bit members together uint8_t clk_pin_{0}; diff --git a/esphome/components/ethernet/ethernet_component_esp32.cpp b/esphome/components/ethernet/ethernet_component_esp32.cpp index 2c3c5f1ef9..e9281453c9 100644 --- a/esphome/components/ethernet/ethernet_component_esp32.cpp +++ b/esphome/components/ethernet/ethernet_component_esp32.cpp @@ -462,9 +462,11 @@ void EthernetComponent::ethernet_lazy_init_() { } #endif // USE_ETHERNET_KSZ8081 +#ifdef ESPHOME_ETHERNET_PHY_REGISTER_COUNT for (const auto &phy_register : this->phy_registers_) { this->write_phy_register_(mac, phy_register); } +#endif #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0) #ifdef USE_ETHERNET_GENERIC @@ -1043,10 +1045,6 @@ void EthernetComponent::dump_connect_params_() { #endif /* USE_NETWORK_IPV6 */ } -#ifndef USE_ETHERNET_SPI -void EthernetComponent::add_phy_register(PHYRegister register_value) { this->phy_registers_.push_back(register_value); } -#endif - void EthernetComponent::get_eth_mac_address_raw(uint8_t *mac) { if (!this->ethernet_initialized_) { // External callers (mdns, ethernet_info, etc.) may ask for the MAC before/regardless @@ -1144,6 +1142,7 @@ void EthernetComponent::ksz8081_set_clock_reference_(esp_eth_mac_t *mac) { } #endif // USE_ETHERNET_KSZ8081 +#ifdef ESPHOME_ETHERNET_PHY_REGISTER_COUNT void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister register_data) { esp_err_t err; @@ -1168,6 +1167,7 @@ void EthernetComponent::write_phy_register_(esp_eth_mac_t *mac, PHYRegister regi } #endif } +#endif // ESPHOME_ETHERNET_PHY_REGISTER_COUNT #ifdef USE_ETHERNET_YT8531 void EthernetComponent::yt8531_phy_init_() { diff --git a/esphome/core/defines.h b/esphome/core/defines.h index 97b1395553..be8d89c557 100644 --- a/esphome/core/defines.h +++ b/esphome/core/defines.h @@ -491,6 +491,7 @@ #define USE_ETHERNET_CONNECT_TRIGGER #define USE_ETHERNET_DISCONNECT_TRIGGER #define ESPHOME_ETHERNET_IP_STATE_LISTENERS 2 +#define ESPHOME_ETHERNET_PHY_REGISTER_COUNT 2 #endif #ifdef USE_ESP32 diff --git a/tests/components/ethernet/common-rtl8201.yaml b/tests/components/ethernet/common-rtl8201.yaml index d5a60f6e98..5e24017ff3 100644 --- a/tests/components/ethernet/common-rtl8201.yaml +++ b/tests/components/ethernet/common-rtl8201.yaml @@ -7,6 +7,12 @@ ethernet: mode: CLK_EXT_IN phy_addr: 0 power_pin: 33 + phy_registers: + - address: 0x10 + value: 0x1FFA + page_id: 0x07 + - address: 0x19 + value: 0x0006 manual_ip: static_ip: 192.168.178.56 gateway: 192.168.178.1