EthPhy.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef ETH_PHY_H | ||
| 2 | #define ETH_PHY_H | ||
| 3 | #include <stdint.h> | ||
| 4 | #if __has_include(<sdkconfig.h>) | ||
| 5 | #include <sdkconfig.h> | ||
| 6 | #endif | ||
| 7 | |||
| 8 | // Ethernet needs the RMII MAC, which only the original ESP32 and the P4 have. | ||
| 9 | // The C3, C5, S3 and C6 build without it. | ||
| 10 | #if defined(CONFIG_ETH_USE_ESP32_EMAC) && CONFIG_ETH_USE_ESP32_EMAC | ||
| 11 | #define HAS_ETHERNET 1 | ||
| 12 | #else | ||
| 13 | #define HAS_ETHERNET 0 | ||
| 14 | #endif | ||
| 15 | |||
| 16 | // PHY chip ids as stored in NVS and backups and sent to the web UI. They are | ||
| 17 | // Arduino 2.x's eth_phy_type_t values, frozen: Arduino 3.x renumbered that | ||
| 18 | // enum, so an id is translated by name when Ethernet starts, never cast. | ||
| 19 | enum class eth_phy_id_t : uint8_t { | ||
| 20 | LAN8720 = 0, | ||
| 21 | TLK110 = 1, | ||
| 22 | RTL8201 = 2, | ||
| 23 | DP83848 = 3, | ||
| 24 | DM9051 = 4, // An SPI chip. The RMII MAC can't drive it. | ||
| 25 | KSZ8041 = 5, | ||
| 26 | KSZ8081 = 6 | ||
| 27 | }; | ||
| 28 | |||
| 29 | // RMII clock ids as stored in NVS and backups and sent to the web UI: the | ||
| 30 | // original ESP32's eth_clock_mode_t values. The P4's eth_clock_mode_t is the | ||
| 31 | // IDF's emac_rmii_clock_mode_t, a different enum, so an id is translated. | ||
| 32 | enum class eth_clock_id_t : uint8_t { | ||
| 33 | GPIO0_IN = 0, // The clock comes in. On the P4, on GPIO 50. | ||
| 34 | GPIO0_OUT = 1, | ||
| 35 | GPIO16_OUT = 2, | ||
| 36 | GPIO17_OUT = 3 | ||
| 37 | }; | ||
| 38 | // The highest clock id the chip takes: the P4's ETH.begin() takes the clock | ||
| 39 | // in on GPIO 50 only. | ||
| 40 | #if defined(CONFIG_IDF_TARGET_ESP32P4) | ||
| 41 | constexpr uint8_t ETH_CLOCK_ID_MAX = 0; | ||
| 42 | #else | ||
| 43 | constexpr uint8_t ETH_CLOCK_ID_MAX = 3; | ||
| 44 | #endif | ||
| 45 | |||
| 46 | // The GPIO a stored clock id puts the RMII clock on, -1 for an id the chip | ||
| 47 | // can't use. | ||
| 48 | 8 | inline int8_t ethClockPin(uint8_t id) { | |
| 49 | #if defined(CONFIG_IDF_TARGET_ESP32P4) | ||
| 50 | 3 | return static_cast<eth_clock_id_t>(id) == eth_clock_id_t::GPIO0_IN ? 50 : -1; | |
| 51 | #else | ||
| 52 | 5 | switch(static_cast<eth_clock_id_t>(id)) { | |
| 53 | 2 | case eth_clock_id_t::GPIO0_IN: | |
| 54 | 2 | case eth_clock_id_t::GPIO0_OUT: return 0; | |
| 55 | 1 | case eth_clock_id_t::GPIO16_OUT: return 16; | |
| 56 | 1 | case eth_clock_id_t::GPIO17_OUT: return 17; | |
| 57 | 1 | default: return -1; | |
| 58 | } | ||
| 59 | #endif | ||
| 60 | } | ||
| 61 | |||
| 62 | #if HAS_ETHERNET | ||
| 63 | #include <ETH.h> | ||
| 64 | // Sets type to the framework's PHY for a stored id. False for an id the RMII | ||
| 65 | // MAC can't drive. | ||
| 66 | 11 | inline bool ethPhyType(uint8_t id, eth_phy_type_t &type) { | |
| 67 | 11 | switch(static_cast<eth_phy_id_t>(id)) { | |
| 68 | 2 | case eth_phy_id_t::LAN8720: type = ETH_PHY_LAN8720; return true; | |
| 69 | 2 | case eth_phy_id_t::TLK110: type = ETH_PHY_TLK110; return true; | |
| 70 | 1 | case eth_phy_id_t::RTL8201: type = ETH_PHY_RTL8201; return true; | |
| 71 | 1 | case eth_phy_id_t::DP83848: type = ETH_PHY_DP83848; return true; | |
| 72 | 1 | case eth_phy_id_t::KSZ8041: type = ETH_PHY_KSZ8041; return true; | |
| 73 | 1 | case eth_phy_id_t::KSZ8081: type = ETH_PHY_KSZ8081; return true; | |
| 74 | 3 | default: return false; | |
| 75 | } | ||
| 76 | } | ||
| 77 | // Sets mode to the framework's clock mode for a stored id. False for an id | ||
| 78 | // the chip can't use. | ||
| 79 | 15 | inline bool ethClockMode(uint8_t id, eth_clock_mode_t &mode) { | |
| 80 | 15 | switch(static_cast<eth_clock_id_t>(id)) { | |
| 81 | #if defined(CONFIG_IDF_TARGET_ESP32P4) | ||
| 82 | 2 | case eth_clock_id_t::GPIO0_IN: mode = EMAC_CLK_EXT_IN; return true; | |
| 83 | #else | ||
| 84 | 1 | case eth_clock_id_t::GPIO0_IN: mode = ETH_CLOCK_GPIO0_IN; return true; | |
| 85 | 1 | case eth_clock_id_t::GPIO0_OUT: mode = ETH_CLOCK_GPIO0_OUT; return true; | |
| 86 | 1 | case eth_clock_id_t::GPIO16_OUT: mode = ETH_CLOCK_GPIO16_OUT; return true; | |
| 87 | 2 | case eth_clock_id_t::GPIO17_OUT: mode = ETH_CLOCK_GPIO17_OUT; return true; | |
| 88 | #endif | ||
| 89 | 8 | default: return false; | |
| 90 | } | ||
| 91 | } | ||
| 92 | #endif | ||
| 93 | #endif | ||
| 94 |