Description
Board
Any board with Ethernet
Device Description
Any board with Ethernet
Hardware Configuration
Any board with Ethernet
Version
latest master (checkout manually)
IDE Name
not relevant
Operating System
not relevant
Flash frequency
not relevant
PSRAM enabled
yes
Upload speed
not relevant
Description
ETHClass::begin
accepts phy_addr
as uint8_t
introduced in IDF 5.x the new mode ESP_ETH_PHY_ADDR_AUTO
(defined as -1) to automatically detect the Ethernet PHY address.
The problem arises from a mismatch in signedness between the parameter phy_addr
of ETHClass::begin
and its counterpart in the eth_phy_config_t
struct, where phy_addr
is defined as int32_t
. This discrepancy leads to unintended behavior: the value -1, when interpreted as an unsigned uint8_t, becomes 255, resulting in a failed PHY detection process.
Additionally, the error message "SPI Ethernet driver install failed" is inaccurately displayed for all Ethernet drivers, not just SPI.
Sketch
/*
This sketch shows the Ethernet event usage
*/
// Important to be defined BEFORE including ETH.h for ETH.begin() to work.
// Example RMII LAN8720 (Olimex, etc.)
#ifndef ETH_PHY_TYPE
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#define ETH_PHY_ADDR ESP_ETH_PHY_ADDR_AUTO
#define ETH_PHY_MDC 23
#define ETH_PHY_MDIO 18
#define ETH_PHY_POWER -1
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
#endif
#include <ETH.h>
static bool eth_connected = false;
// WARNING: WiFiEvent is called from a separate FreeRTOS task (thread)!
void WiFiEvent(WiFiEvent_t event)
{
switch (event) {
case ARDUINO_EVENT_ETH_START:
Serial.println("ETH Started");
// The hostname must be set after the interface is started, but needs
// to be set before DHCP, so set it from the event handler thread.
ETH.setHostname("esp32-ethernet");
break;
case ARDUINO_EVENT_ETH_CONNECTED:
Serial.println("ETH Connected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
Serial.println("ETH Got IP");
ETH.printInfo(Serial);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_STOP:
Serial.println("ETH Stopped");
eth_connected = false;
break;
default:
break;
}
}
void testClient(const char * host, uint16_t port)
{
Serial.print("\nconnecting to ");
Serial.println(host);
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
return;
}
client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
while (client.connected() && !client.available());
while (client.available()) {
Serial.write(client.read());
}
Serial.println("closing connection\n");
client.stop();
}
void setup()
{
Serial.begin(115200);
WiFi.onEvent(WiFiEvent); // Will call WiFiEvent() from another thread.
ETH.begin();
}
void loop()
{
if (eth_connected) {
testClient("google.com", 80);
}
delay(10000);
}
Debug Message
[ 4152][E][eth_phy_802_3]: esp_eth_phy_802_3_pwrctl(244): power up timeout
[ 4160][E][eth_phy_802_3]: esp_eth_phy_802_3_basic_phy_init(410): power control failed
[ 4169][E][lan87xx]: lan87xx_init(341): failed to init PHY
[ 4175][E][esp_eth]: esp_eth_driver_install(229): init phy failed
[ 2188][E][ETH.cpp:171] begin(): SPI Ethernet driver install failed: -1
Other Steps to Reproduce
- Call
ETHClass::begin
withphy_addr
set toESP_ETH_PHY_ADDR_AUTO
. - Observe the value of
phy_addr
within theeth_phy_config_t
struct. - Notice the discrepancy between the expected and actual values, leading to failed PHY detection.
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Metadata
Metadata
Assignees
Type
Projects
Status