Skip to content

Commit cdfc6c1

Browse files
robert-hhdpgeorge
authored andcommitted
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 micropython#14013. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent af67be7 commit cdfc6c1

2 files changed

Lines changed: 13 additions & 2 deletions

File tree

docs/esp32/quickref.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ The keyword arguments for the constructor defining the PHY type and interface ar
128128

129129
- mdc=pin-object # set the mdc and mdio pins.
130130
- mdio=pin-object
131+
- reset=pin-object # set the reset pin of the PHY device.
131132
- power=pin-object # set the pin which switches the power of the PHY device.
132133
- phy_type=<type> # Select the PHY device type. Supported devices are PHY_LAN8710,
133134
PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041

ports/esp32/network_lan.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ typedef struct _lan_if_obj_t {
5151
bool initialized;
5252
int8_t mdc_pin;
5353
int8_t mdio_pin;
54+
int8_t phy_reset_pin;
5455
int8_t phy_power_pin;
5556
int8_t phy_cs_pin;
5657
int8_t phy_int_pin;
@@ -99,12 +100,13 @@ static mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
99100
return MP_OBJ_FROM_PTR(&lan_obj);
100101
}
101102

102-
enum { ARG_id, ARG_mdc, ARG_mdio, ARG_power, ARG_phy_addr, ARG_phy_type,
103+
enum { ARG_id, ARG_mdc, ARG_mdio, ARG_reset, ARG_power, ARG_phy_addr, ARG_phy_type,
103104
ARG_spi, ARG_cs, ARG_int, ARG_ref_clk_mode, ARG_ref_clk };
104105
static const mp_arg_t allowed_args[] = {
105106
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = mp_const_none} },
106107
{ MP_QSTR_mdc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
107108
{ MP_QSTR_mdio, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
109+
{ MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
108110
{ MP_QSTR_power, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
109111
{ MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
110112
{ MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
@@ -128,6 +130,7 @@ static mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
128130

129131
self->mdc_pin = GET_PIN(ARG_mdc);
130132
self->mdio_pin = GET_PIN(ARG_mdio);
133+
self->phy_reset_pin = GET_PIN(ARG_reset);
131134
self->phy_power_pin = GET_PIN(ARG_power);
132135
self->phy_cs_pin = GET_PIN(ARG_cs);
133136
self->phy_int_pin = GET_PIN(ARG_int);
@@ -179,8 +182,15 @@ static mp_obj_t get_lan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
179182

180183
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
181184
phy_config.phy_addr = self->phy_addr;
182-
phy_config.reset_gpio_num = self->phy_power_pin;
185+
phy_config.reset_gpio_num = self->phy_reset_pin;
183186
self->phy = NULL;
187+
// Switch on the power before PHY is reset
188+
if (self->phy_power_pin >= 0) {
189+
mp_hal_pin_output(self->phy_power_pin);
190+
mp_hal_pin_write(self->phy_power_pin, 1);
191+
// let the power settle
192+
mp_hal_delay_ms(100);
193+
}
184194
#if CONFIG_ETH_USE_SPI_ETHERNET
185195
spi_device_interface_config_t devcfg = {
186196
.mode = 0,

0 commit comments

Comments
 (0)