How to fix emac_esp32_init(): reset timeout

Problem

While running your ESP32-based Ethernet application, you see the following error log or crash:

E (443) esp.emac: emac_esp32_init(428): reset timeout
E (443) esp_eth: esp_eth_driver_install(228): init mac failed

Solution

The issue is that you are using the Ethernet MAC with an external RMII clock input (EMAC_CLK_EXT_IN), but no clock is being input on GPIO0, which is the only GPIO that can be used for the RMII clock input on the ESP32.

Check the clock using an oscilloscope or logic analyzer. If you do not see a clock signal on GPIO0, you need to provide one.

What exactly is causing the error?

During emac_esp32_init(), ESP-IDF will soft-reset the Ethernet MAC peripheral in the ESP32 and subsequently wait for the reset to complete. It will wait for a maximum of 100 milliseconds. If the reset does not complete within this time, the error reset timeout is raised.

This is the relevant code snippet from the ESP-IDF source code:

emac_hal_reset(&emac->hal);
uint32_t to = 0;
for (to = 0; to < emac->sw_reset_timeout_ms / 10; to++) {
    if (emac_hal_is_reset_done(&emac->hal)) {
        break;
    }
    vTaskDelay(pdMS_TO_TICKS(10));
}
ESP_GOTO_ON_FALSE(to < emac->sw_reset_timeout_ms / 10, ESP_ERR_TIMEOUT, err, TAG, "reset timeout");