Skip to content

Commit 1f4f2b6

Browse files
authored
Enable clock output for Ethernet RMII on ESP32 (#5274)
fixes #5239 * Add back clock mode argument
1 parent ea236e2 commit 1f4f2b6

File tree

4 files changed

+139
-28
lines changed

4 files changed

+139
-28
lines changed

Diff for: libraries/WiFi/src/ETH.cpp

+133-21
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020

2121
#include "ETH.h"
2222
#include "esp_system.h"
23-
#ifdef ESP_IDF_VERSION_MAJOR
23+
#if ESP_IDF_VERSION_MAJOR > 3
2424
#include "esp_event.h"
2525
#include "esp_eth.h"
2626
#include "esp_eth_phy.h"
2727
#include "esp_eth_mac.h"
2828
#include "esp_eth_com.h"
29+
#if CONFIG_IDF_TARGET_ESP32
30+
#include "soc/emac_ext_struct.h"
31+
#include "soc/rtc.h"
32+
//#include "soc/io_mux_reg.h"
33+
//#include "hal/gpio_hal.h"
34+
#endif
2935
#else
3036
#include "eth_phy/phy.h"
3137
#include "eth_phy/phy_tlk110.h"
@@ -36,7 +42,7 @@
3642

3743
extern void tcpipInit();
3844

39-
#ifdef ESP_IDF_VERSION_MAJOR
45+
#if ESP_IDF_VERSION_MAJOR > 3
4046

4147
/**
4248
* @brief Callback function invoked when lowlevel initialization is finished
@@ -47,13 +53,123 @@ extern void tcpipInit();
4753
* - ESP_OK: process extra lowlevel initialization successfully
4854
* - ESP_FAIL: error occurred when processing extra lowlevel initialization
4955
*/
50-
//static esp_err_t on_lowlevel_init_done(esp_eth_handle_t eth_handle){
51-
//#define PIN_PHY_POWER 2
52-
// pinMode(PIN_PHY_POWER, OUTPUT);
53-
// digitalWrite(PIN_PHY_POWER, HIGH);
54-
// delay(100);
55-
// return ESP_OK;
56-
//}
56+
57+
static eth_clock_mode_t eth_clock_mode = ETH_CLK_MODE;
58+
59+
#if CONFIG_ETH_RMII_CLK_INPUT
60+
static void emac_config_apll_clock(void)
61+
{
62+
/* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) */
63+
rtc_xtal_freq_t rtc_xtal_freq = rtc_clk_xtal_freq_get();
64+
switch (rtc_xtal_freq) {
65+
case RTC_XTAL_FREQ_40M: // Recommended
66+
/* 50 MHz = 40MHz * (4 + 6) / (2 * (2 + 2) = 50.000 */
67+
/* sdm0 = 0, sdm1 = 0, sdm2 = 6, o_div = 2 */
68+
rtc_clk_apll_enable(true, 0, 0, 6, 2);
69+
break;
70+
case RTC_XTAL_FREQ_26M:
71+
/* 50 MHz = 26MHz * (4 + 15 + 118 / 256 + 39/65536) / ((3 + 2) * 2) = 49.999992 */
72+
/* sdm0 = 39, sdm1 = 118, sdm2 = 15, o_div = 3 */
73+
rtc_clk_apll_enable(true, 39, 118, 15, 3);
74+
break;
75+
case RTC_XTAL_FREQ_24M:
76+
/* 50 MHz = 24MHz * (4 + 12 + 255 / 256 + 255/65536) / ((2 + 2) * 2) = 49.499977 */
77+
/* sdm0 = 255, sdm1 = 255, sdm2 = 12, o_div = 2 */
78+
rtc_clk_apll_enable(true, 255, 255, 12, 2);
79+
break;
80+
default: // Assume we have a 40M xtal
81+
rtc_clk_apll_enable(true, 0, 0, 6, 2);
82+
break;
83+
}
84+
}
85+
#endif
86+
87+
static esp_err_t on_lowlevel_init_done(esp_eth_handle_t eth_handle){
88+
#if CONFIG_IDF_TARGET_ESP32
89+
if(eth_clock_mode > ETH_CLOCK_GPIO17_OUT){
90+
return ESP_FAIL;
91+
}
92+
// First deinit current config if different
93+
#if CONFIG_ETH_RMII_CLK_INPUT
94+
if(eth_clock_mode != ETH_CLOCK_GPIO0_IN && eth_clock_mode != ETH_CLOCK_GPIO0_OUT){
95+
pinMode(0, INPUT);
96+
}
97+
#endif
98+
99+
#if CONFIG_ETH_RMII_CLK_OUTPUT
100+
#if CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
101+
if(eth_clock_mode > ETH_CLOCK_GPIO0_OUT){
102+
pinMode(0, INPUT);
103+
}
104+
#elif CONFIG_ETH_RMII_CLK_OUT_GPIO == 16
105+
if(eth_clock_mode != ETH_CLOCK_GPIO16_OUT){
106+
pinMode(16, INPUT);
107+
}
108+
#elif CONFIG_ETH_RMII_CLK_OUT_GPIO == 17
109+
if(eth_clock_mode != ETH_CLOCK_GPIO17_OUT){
110+
pinMode(17, INPUT);
111+
}
112+
#endif
113+
#endif
114+
115+
// Setup interface for the correct pin
116+
#if CONFIG_ETH_PHY_INTERFACE_MII
117+
EMAC_EXT.ex_phyinf_conf.phy_intf_sel = 4;
118+
#endif
119+
120+
if(eth_clock_mode == ETH_CLOCK_GPIO0_IN){
121+
#ifndef CONFIG_ETH_RMII_CLK_INPUT
122+
// RMII clock (50MHz) input to GPIO0
123+
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_EMAC_TX_CLK);
124+
//PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[0]);
125+
pinMode(0, INPUT);
126+
pinMode(0, FUNCTION_6);
127+
EMAC_EXT.ex_clk_ctrl.ext_en = 1;
128+
EMAC_EXT.ex_clk_ctrl.int_en = 0;
129+
EMAC_EXT.ex_oscclk_conf.clk_sel = 1;
130+
#endif
131+
} else {
132+
if(eth_clock_mode == ETH_CLOCK_GPIO0_OUT){
133+
#ifndef CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
134+
// APLL clock output to GPIO0 (must be configured to 50MHz!)
135+
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
136+
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[0]);
137+
pinMode(0, OUTPUT);
138+
pinMode(0, FUNCTION_2);
139+
// Choose the APLL clock to output on GPIO
140+
REG_WRITE(PIN_CTRL, 6);
141+
#endif
142+
} else if(eth_clock_mode == ETH_CLOCK_GPIO16_OUT){
143+
#if CONFIG_ETH_RMII_CLK_OUT_GPIO != 16
144+
// RMII CLK (50MHz) output to GPIO16
145+
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
146+
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[16]);
147+
pinMode(16, OUTPUT);
148+
pinMode(16, FUNCTION_6);
149+
#endif
150+
} else if(eth_clock_mode == ETH_CLOCK_GPIO17_OUT){
151+
#if CONFIG_ETH_RMII_CLK_OUT_GPIO != 17
152+
// RMII CLK (50MHz) output to GPIO17
153+
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_EMAC_CLK_OUT_180);
154+
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[17]);
155+
pinMode(17, OUTPUT);
156+
pinMode(17, FUNCTION_6);
157+
#endif
158+
}
159+
#if CONFIG_ETH_RMII_CLK_INPUT
160+
EMAC_EXT.ex_clk_ctrl.ext_en = 0;
161+
EMAC_EXT.ex_clk_ctrl.int_en = 1;
162+
EMAC_EXT.ex_oscclk_conf.clk_sel = 0;
163+
emac_config_apll_clock();
164+
EMAC_EXT.ex_clkout_conf.div_num = 0;
165+
EMAC_EXT.ex_clkout_conf.h_div_num = 0;
166+
#endif
167+
}
168+
#endif
169+
return ESP_OK;
170+
}
171+
172+
57173

58174
/**
59175
* @brief Callback function invoked when lowlevel deinitialization is finished
@@ -110,9 +226,10 @@ ETHClass::ETHClass()
110226
ETHClass::~ETHClass()
111227
{}
112228

113-
#ifdef ESP_IDF_VERSION_MAJOR
114-
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type){
115-
229+
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
230+
{
231+
#if ESP_IDF_VERSION_MAJOR > 3
232+
eth_clock_mode = clock_mode;
116233
tcpipInit();
117234

118235
tcpip_adapter_set_default_eth_handlers();
@@ -136,7 +253,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
136253
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
137254
mac_config.smi_mdc_gpio_num = mdc;
138255
mac_config.smi_mdio_gpio_num = mdio;
139-
//mac_config.sw_reset_timeout_ms = 1000;
256+
mac_config.sw_reset_timeout_ms = 1000;
140257
eth_mac = esp_eth_mac_new_esp32(&mac_config);
141258
#endif
142259
#if CONFIG_ETH_SPI_ETHERNET_DM9051
@@ -182,7 +299,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
182299

183300
eth_handle = NULL;
184301
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(eth_mac, eth_phy);
185-
//eth_config.on_lowlevel_init_done = on_lowlevel_init_done;
302+
eth_config.on_lowlevel_init_done = on_lowlevel_init_done;
186303
//eth_config.on_lowlevel_deinit_done = on_lowlevel_deinit_done;
187304
if(esp_eth_driver_install(&eth_config, &eth_handle) != ESP_OK || eth_handle == NULL){
188305
log_e("esp_eth_driver_install failed");
@@ -199,12 +316,7 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
199316
log_e("esp_eth_start failed");
200317
return false;
201318
}
202-
203-
return true;
204-
}
205319
#else
206-
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
207-
{
208320
esp_err_t err;
209321
if(initialized){
210322
err = esp_eth_enable();
@@ -256,9 +368,9 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
256368
} else {
257369
log_e("esp_eth_init error: %d", err);
258370
}
259-
return false;
260-
}
261371
#endif
372+
return true;
373+
}
262374

263375
bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2)
264376
{

Diff for: libraries/WiFi/src/ETH.h

+5-6
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,16 @@
4545
#define ETH_PHY_MDIO 18
4646
#endif
4747

48-
#if ESP_IDF_VERSION_MAJOR < 4
4948
#ifndef ETH_CLK_MODE
5049
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
5150
#endif
51+
52+
#if ESP_IDF_VERSION_MAJOR > 3
53+
typedef enum { ETH_CLOCK_GPIO0_IN, ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT } eth_clock_mode_t;
5254
#endif
5355

5456
typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_RTL8201, ETH_PHY_DP83848, ETH_PHY_DM9051, ETH_PHY_KSZ8081, ETH_PHY_MAX } eth_phy_type_t;
57+
#define ETH_PHY_IP101 ETH_PHY_TLK110
5558

5659
class ETHClass {
5760
private:
@@ -72,12 +75,8 @@ class ETHClass {
7275
ETHClass();
7376
~ETHClass();
7477

75-
#if ESP_IDF_VERSION_MAJOR > 3
76-
bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE);
77-
#else
7878
bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE, eth_clock_mode_t clk_mode=ETH_CLK_MODE);
79-
#endif
80-
79+
8180
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
8281

8382
const char * getHostname();

Diff for: tools/sdk/esp32/include/config/sdkconfig.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -658,5 +658,5 @@
658658
#define CONFIG_ULP_COPROC_ENABLED CONFIG_ESP32_ULP_COPROC_ENABLED
659659
#define CONFIG_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
660660
#define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS
661-
#define CONFIG_ARDUINO_IDF_COMMIT "1d7068e4b"
661+
#define CONFIG_ARDUINO_IDF_COMMIT ""
662662
#define CONFIG_ARDUINO_IDF_BRANCH "master"

Diff for: tools/sdk/esp32/lib/libesp_eth.a

7.98 KB
Binary file not shown.

0 commit comments

Comments
 (0)