esp32/network_lan: Add a separate argument to set PHY power pin.
Prior to this commit, the pin defined for power would be used by the
esp_idf driver to reset the PHY. That worked, but sometimes the MDIO
configuration started before the power was fully settled, leading to an
error.
With the change in this commit, the power for the PHY is independently
enabled in network_lan.c with a 100ms delay to allow the power to settle.
A separate define for a reset pin is provided, even if the PHY reset
pin is rarely connected.
Fixes issue #14013.
Signed-off-by: robert-hh <robert@hammelrath.com>
diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst
index 9c77dc4..6c07c58 100644
--- a/docs/esp32/quickref.rst
+++ b/docs/esp32/quickref.rst
@@ -128,6 +128,7 @@
- mdc=pin-object # set the mdc and mdio pins.
- mdio=pin-object
+- reset=pin-object # set the reset pin of the PHY device.
- power=pin-object # set the pin which switches the power of the PHY device.
- phy_type=<type> # Select the PHY device type. Supported devices are PHY_LAN8710,
PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041
diff --git a/ports/esp32/network_lan.c b/ports/esp32/network_lan.c
index d7d9a9f..570c9a4 100644
--- a/ports/esp32/network_lan.c
+++ b/ports/esp32/network_lan.c
@@ -51,6 +51,7 @@
bool initialized;
int8_t mdc_pin;
int8_t mdio_pin;
+ int8_t phy_reset_pin;
int8_t phy_power_pin;
int8_t phy_cs_pin;
int8_t phy_int_pin;
@@ -99,12 +100,13 @@
return MP_OBJ_FROM_PTR(&lan_obj);
}
- enum { ARG_id, ARG_mdc, ARG_mdio, ARG_power, ARG_phy_addr, ARG_phy_type,
+ enum { ARG_id, ARG_mdc, ARG_mdio, ARG_reset, ARG_power, ARG_phy_addr, ARG_phy_type,
ARG_spi, ARG_cs, ARG_int, ARG_ref_clk_mode, ARG_ref_clk };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_mdc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_mdio, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_power, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
@@ -128,6 +130,7 @@
self->mdc_pin = GET_PIN(ARG_mdc);
self->mdio_pin = GET_PIN(ARG_mdio);
+ self->phy_reset_pin = GET_PIN(ARG_reset);
self->phy_power_pin = GET_PIN(ARG_power);
self->phy_cs_pin = GET_PIN(ARG_cs);
self->phy_int_pin = GET_PIN(ARG_int);
@@ -179,8 +182,15 @@
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = self->phy_addr;
- phy_config.reset_gpio_num = self->phy_power_pin;
+ phy_config.reset_gpio_num = self->phy_reset_pin;
self->phy = NULL;
+ // Switch on the power before PHY is reset
+ if (self->phy_power_pin >= 0) {
+ mp_hal_pin_output(self->phy_power_pin);
+ mp_hal_pin_write(self->phy_power_pin, 1);
+ // let the power settle
+ mp_hal_delay_ms(100);
+ }
#if CONFIG_ETH_USE_SPI_ETHERNET
spi_device_interface_config_t devcfg = {
.mode = 0,