OLIMEX / ESP32-POE

ESP32 IoT development board with 100Mb Ethernet and 802.3 Power Over Ethernet (POE)
Apache License 2.0
292 stars 110 forks source link

Ethernet initialization error on Olimex ESP32-PoE Rev E #16

Closed danieltang3434 closed 1 year ago

danieltang3434 commented 3 years ago

When I try to initialize and start using the ethernet on Olimex ESP32-PoE, I encounter with the error message below:

E (1039) emac: Timed out waiting for PHY register 0x2 to have value 0x0007(mask 0xffff). Current value 0x0000
E (2040) emac: Timed out waiting for PHY register 0x3 to have value 0xc0f0(mask 0xfff0). Current value 0x0000
E (2041) emac: Initialise PHY device Timeout
[E][ETH.cpp:101] begin(): esp_eth_enable error: -1

The platform/framework/tool that I using is: PlatformIO, Arduino Framework, Visual Studio Code Editor.

Code snippet:

// Ethernet port parameters
// ETH_CLOCK_GPIO17_OUT - 50MHz clock from internal APLL inverted output on GPIO17 - tested with LAN8720.
#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT
// Pin number of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source).
#define ETH_POWER_PIN -1
// Type of the Ethernet PHY (LAN8720 or TLK110).
#define ETH_TYPE ETH_PHY_LAN8720
// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110).
#define ETH_ADDR 0
// Pin number of the I²C clock signal for the Ethernet PHY.
#define ETH_MDC_PIN 23
// Pin number of the I²C IO signal for the Ethernet PHY.
#define ETH_MDIO_PIN 18

#include <Arduino.h>
#include <ETH.h>
#include <WiFi.h>

void WiFiEvent(WiFiEvent_t event)
{
    switch (event)
    {
    case SYSTEM_EVENT_ETH_START:
        Serial.println("ETH Started");
        //set eth hostname here
        ETH.setHostname("esp32-ethernet");
        break;
    case SYSTEM_EVENT_ETH_CONNECTED:
        Serial.println("ETH Connected");
        break;
    case SYSTEM_EVENT_ETH_GOT_IP:
        Serial.print("ETH MAC: ");
        Serial.print(ETH.macAddress());
        Serial.print(", IPv4: ");
        Serial.print(ETH.localIP());
        if (ETH.fullDuplex())
        {
            Serial.print(", FULL_DUPLEX");
        }
        Serial.print(", ");
        Serial.print(ETH.linkSpeed());
        Serial.println("Mbps");
        eth_connected = true;
        break;
    case SYSTEM_EVENT_ETH_DISCONNECTED:
        Serial.println("ETH Disconnected");
        eth_connected = false;
        break;
    case SYSTEM_EVENT_ETH_STOP:
        Serial.println("ETH Stopped");
        eth_connected = false;
        break;
    default:
        break;
    }
}

void setup()
{
    Serial.begin(115200);
    Serial.println();
    Serial.println();
    Serial.println();

    // Set on connected event
    WiFi.onEvent(WiFiEvent);
    // Init Ethernet
    ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE);
    Serial.print("Waiting for Ethernet... ");
    // Wait for connected status
    while(!eth_connected) {
        Serial.print(".");
        delay(500);
    }
    Serial.println("Ethernet connected! ");
}

The board cannot connect to Internet and the LAN cable has been tested with other board such as "Olimex ESP32-EVB" and it is working, so probably not the LAN cable issue. Can anyone help to point out any false parts? Thank you so much.

DanKoloff commented 3 years ago

ESP32-EVB and ESP32-POE have different Ethernet clock circuit - it is not surprising that the code that works on ESP32-EVB doesn't run on ESP32-POE without changes! Good news is that only few changes for the pins for the Ethernet are required!

ESP32-EVB uses external clock generator, while ESP32-POE uses internal clock generator and power enable/disable pin.

For ESP32-POE the two pins are:

define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT

define ETH_PHY_POWER 12

The reason for this difference is that ESP32-EVB has a lot of hardware (since the design was research, evaluation and development) and the external generator saves one GPIO pin. ESP32-POE has less hardware and more available pins, so it is not a problem to switch to the more common Ethernet circuit with internal clock and GPIO for power enable and disable.