Enable clock output for Ethernet RMII on ESP32 (#5274)
fixes #5239 * Add back clock mode argument
This commit is contained in:
parent
ea236e28e5
commit
1f4f2b6e97
@ -20,12 +20,18 @@
|
|||||||
|
|
||||||
#include "ETH.h"
|
#include "ETH.h"
|
||||||
#include "esp_system.h"
|
#include "esp_system.h"
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR
|
#if ESP_IDF_VERSION_MAJOR > 3
|
||||||
#include "esp_event.h"
|
#include "esp_event.h"
|
||||||
#include "esp_eth.h"
|
#include "esp_eth.h"
|
||||||
#include "esp_eth_phy.h"
|
#include "esp_eth_phy.h"
|
||||||
#include "esp_eth_mac.h"
|
#include "esp_eth_mac.h"
|
||||||
#include "esp_eth_com.h"
|
#include "esp_eth_com.h"
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
#include "soc/emac_ext_struct.h"
|
||||||
|
#include "soc/rtc.h"
|
||||||
|
//#include "soc/io_mux_reg.h"
|
||||||
|
//#include "hal/gpio_hal.h"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include "eth_phy/phy.h"
|
#include "eth_phy/phy.h"
|
||||||
#include "eth_phy/phy_tlk110.h"
|
#include "eth_phy/phy_tlk110.h"
|
||||||
@ -36,7 +42,7 @@
|
|||||||
|
|
||||||
extern void tcpipInit();
|
extern void tcpipInit();
|
||||||
|
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR
|
#if ESP_IDF_VERSION_MAJOR > 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback function invoked when lowlevel initialization is finished
|
* @brief Callback function invoked when lowlevel initialization is finished
|
||||||
@ -47,13 +53,123 @@ extern void tcpipInit();
|
|||||||
* - ESP_OK: process extra lowlevel initialization successfully
|
* - ESP_OK: process extra lowlevel initialization successfully
|
||||||
* - ESP_FAIL: error occurred when processing extra lowlevel initialization
|
* - ESP_FAIL: error occurred when processing extra lowlevel initialization
|
||||||
*/
|
*/
|
||||||
//static esp_err_t on_lowlevel_init_done(esp_eth_handle_t eth_handle){
|
|
||||||
//#define PIN_PHY_POWER 2
|
static eth_clock_mode_t eth_clock_mode = ETH_CLK_MODE;
|
||||||
// pinMode(PIN_PHY_POWER, OUTPUT);
|
|
||||||
// digitalWrite(PIN_PHY_POWER, HIGH);
|
#if CONFIG_ETH_RMII_CLK_INPUT
|
||||||
// delay(100);
|
static void emac_config_apll_clock(void)
|
||||||
// return ESP_OK;
|
{
|
||||||
//}
|
/* apll_freq = xtal_freq * (4 + sdm2 + sdm1/256 + sdm0/65536)/((o_div + 2) * 2) */
|
||||||
|
rtc_xtal_freq_t rtc_xtal_freq = rtc_clk_xtal_freq_get();
|
||||||
|
switch (rtc_xtal_freq) {
|
||||||
|
case RTC_XTAL_FREQ_40M: // Recommended
|
||||||
|
/* 50 MHz = 40MHz * (4 + 6) / (2 * (2 + 2) = 50.000 */
|
||||||
|
/* sdm0 = 0, sdm1 = 0, sdm2 = 6, o_div = 2 */
|
||||||
|
rtc_clk_apll_enable(true, 0, 0, 6, 2);
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_26M:
|
||||||
|
/* 50 MHz = 26MHz * (4 + 15 + 118 / 256 + 39/65536) / ((3 + 2) * 2) = 49.999992 */
|
||||||
|
/* sdm0 = 39, sdm1 = 118, sdm2 = 15, o_div = 3 */
|
||||||
|
rtc_clk_apll_enable(true, 39, 118, 15, 3);
|
||||||
|
break;
|
||||||
|
case RTC_XTAL_FREQ_24M:
|
||||||
|
/* 50 MHz = 24MHz * (4 + 12 + 255 / 256 + 255/65536) / ((2 + 2) * 2) = 49.499977 */
|
||||||
|
/* sdm0 = 255, sdm1 = 255, sdm2 = 12, o_div = 2 */
|
||||||
|
rtc_clk_apll_enable(true, 255, 255, 12, 2);
|
||||||
|
break;
|
||||||
|
default: // Assume we have a 40M xtal
|
||||||
|
rtc_clk_apll_enable(true, 0, 0, 6, 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static esp_err_t on_lowlevel_init_done(esp_eth_handle_t eth_handle){
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
if(eth_clock_mode > ETH_CLOCK_GPIO17_OUT){
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
// First deinit current config if different
|
||||||
|
#if CONFIG_ETH_RMII_CLK_INPUT
|
||||||
|
if(eth_clock_mode != ETH_CLOCK_GPIO0_IN && eth_clock_mode != ETH_CLOCK_GPIO0_OUT){
|
||||||
|
pinMode(0, INPUT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_ETH_RMII_CLK_OUTPUT
|
||||||
|
#if CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
|
||||||
|
if(eth_clock_mode > ETH_CLOCK_GPIO0_OUT){
|
||||||
|
pinMode(0, INPUT);
|
||||||
|
}
|
||||||
|
#elif CONFIG_ETH_RMII_CLK_OUT_GPIO == 16
|
||||||
|
if(eth_clock_mode != ETH_CLOCK_GPIO16_OUT){
|
||||||
|
pinMode(16, INPUT);
|
||||||
|
}
|
||||||
|
#elif CONFIG_ETH_RMII_CLK_OUT_GPIO == 17
|
||||||
|
if(eth_clock_mode != ETH_CLOCK_GPIO17_OUT){
|
||||||
|
pinMode(17, INPUT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Setup interface for the correct pin
|
||||||
|
#if CONFIG_ETH_PHY_INTERFACE_MII
|
||||||
|
EMAC_EXT.ex_phyinf_conf.phy_intf_sel = 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(eth_clock_mode == ETH_CLOCK_GPIO0_IN){
|
||||||
|
#ifndef CONFIG_ETH_RMII_CLK_INPUT
|
||||||
|
// RMII clock (50MHz) input to GPIO0
|
||||||
|
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_EMAC_TX_CLK);
|
||||||
|
//PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[0]);
|
||||||
|
pinMode(0, INPUT);
|
||||||
|
pinMode(0, FUNCTION_6);
|
||||||
|
EMAC_EXT.ex_clk_ctrl.ext_en = 1;
|
||||||
|
EMAC_EXT.ex_clk_ctrl.int_en = 0;
|
||||||
|
EMAC_EXT.ex_oscclk_conf.clk_sel = 1;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
if(eth_clock_mode == ETH_CLOCK_GPIO0_OUT){
|
||||||
|
#ifndef CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0
|
||||||
|
// APLL clock output to GPIO0 (must be configured to 50MHz!)
|
||||||
|
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
|
||||||
|
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[0]);
|
||||||
|
pinMode(0, OUTPUT);
|
||||||
|
pinMode(0, FUNCTION_2);
|
||||||
|
// Choose the APLL clock to output on GPIO
|
||||||
|
REG_WRITE(PIN_CTRL, 6);
|
||||||
|
#endif
|
||||||
|
} else if(eth_clock_mode == ETH_CLOCK_GPIO16_OUT){
|
||||||
|
#if CONFIG_ETH_RMII_CLK_OUT_GPIO != 16
|
||||||
|
// RMII CLK (50MHz) output to GPIO16
|
||||||
|
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO16_U, FUNC_GPIO16_EMAC_CLK_OUT);
|
||||||
|
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[16]);
|
||||||
|
pinMode(16, OUTPUT);
|
||||||
|
pinMode(16, FUNCTION_6);
|
||||||
|
#endif
|
||||||
|
} else if(eth_clock_mode == ETH_CLOCK_GPIO17_OUT){
|
||||||
|
#if CONFIG_ETH_RMII_CLK_OUT_GPIO != 17
|
||||||
|
// RMII CLK (50MHz) output to GPIO17
|
||||||
|
//gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO17_U, FUNC_GPIO17_EMAC_CLK_OUT_180);
|
||||||
|
//PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[17]);
|
||||||
|
pinMode(17, OUTPUT);
|
||||||
|
pinMode(17, FUNCTION_6);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if CONFIG_ETH_RMII_CLK_INPUT
|
||||||
|
EMAC_EXT.ex_clk_ctrl.ext_en = 0;
|
||||||
|
EMAC_EXT.ex_clk_ctrl.int_en = 1;
|
||||||
|
EMAC_EXT.ex_oscclk_conf.clk_sel = 0;
|
||||||
|
emac_config_apll_clock();
|
||||||
|
EMAC_EXT.ex_clkout_conf.div_num = 0;
|
||||||
|
EMAC_EXT.ex_clkout_conf.h_div_num = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback function invoked when lowlevel deinitialization is finished
|
* @brief Callback function invoked when lowlevel deinitialization is finished
|
||||||
@ -110,9 +226,10 @@ ETHClass::ETHClass()
|
|||||||
ETHClass::~ETHClass()
|
ETHClass::~ETHClass()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#ifdef ESP_IDF_VERSION_MAJOR
|
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
|
||||||
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type){
|
{
|
||||||
|
#if ESP_IDF_VERSION_MAJOR > 3
|
||||||
|
eth_clock_mode = clock_mode;
|
||||||
tcpipInit();
|
tcpipInit();
|
||||||
|
|
||||||
tcpip_adapter_set_default_eth_handlers();
|
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
|
|||||||
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
mac_config.smi_mdc_gpio_num = mdc;
|
mac_config.smi_mdc_gpio_num = mdc;
|
||||||
mac_config.smi_mdio_gpio_num = mdio;
|
mac_config.smi_mdio_gpio_num = mdio;
|
||||||
//mac_config.sw_reset_timeout_ms = 1000;
|
mac_config.sw_reset_timeout_ms = 1000;
|
||||||
eth_mac = esp_eth_mac_new_esp32(&mac_config);
|
eth_mac = esp_eth_mac_new_esp32(&mac_config);
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_ETH_SPI_ETHERNET_DM9051
|
#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
|
|||||||
|
|
||||||
eth_handle = NULL;
|
eth_handle = NULL;
|
||||||
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(eth_mac, eth_phy);
|
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(eth_mac, eth_phy);
|
||||||
//eth_config.on_lowlevel_init_done = on_lowlevel_init_done;
|
eth_config.on_lowlevel_init_done = on_lowlevel_init_done;
|
||||||
//eth_config.on_lowlevel_deinit_done = on_lowlevel_deinit_done;
|
//eth_config.on_lowlevel_deinit_done = on_lowlevel_deinit_done;
|
||||||
if(esp_eth_driver_install(ð_config, ð_handle) != ESP_OK || eth_handle == NULL){
|
if(esp_eth_driver_install(ð_config, ð_handle) != ESP_OK || eth_handle == NULL){
|
||||||
log_e("esp_eth_driver_install failed");
|
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
|
|||||||
log_e("esp_eth_start failed");
|
log_e("esp_eth_start failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type, eth_clock_mode_t clock_mode)
|
|
||||||
{
|
|
||||||
esp_err_t err;
|
esp_err_t err;
|
||||||
if(initialized){
|
if(initialized){
|
||||||
err = esp_eth_enable();
|
err = esp_eth_enable();
|
||||||
@ -256,9 +368,9 @@ bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_typ
|
|||||||
} else {
|
} else {
|
||||||
log_e("esp_eth_init error: %d", err);
|
log_e("esp_eth_init error: %d", err);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2)
|
bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2)
|
||||||
{
|
{
|
||||||
|
@ -45,13 +45,16 @@
|
|||||||
#define ETH_PHY_MDIO 18
|
#define ETH_PHY_MDIO 18
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ESP_IDF_VERSION_MAJOR < 4
|
|
||||||
#ifndef ETH_CLK_MODE
|
#ifndef ETH_CLK_MODE
|
||||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
|
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ESP_IDF_VERSION_MAJOR > 3
|
||||||
|
typedef enum { ETH_CLOCK_GPIO0_IN, ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT } eth_clock_mode_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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;
|
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;
|
||||||
|
#define ETH_PHY_IP101 ETH_PHY_TLK110
|
||||||
|
|
||||||
class ETHClass {
|
class ETHClass {
|
||||||
private:
|
private:
|
||||||
@ -72,12 +75,8 @@ class ETHClass {
|
|||||||
ETHClass();
|
ETHClass();
|
||||||
~ETHClass();
|
~ETHClass();
|
||||||
|
|
||||||
#if ESP_IDF_VERSION_MAJOR > 3
|
|
||||||
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);
|
|
||||||
#else
|
|
||||||
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);
|
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);
|
||||||
#endif
|
|
||||||
|
|
||||||
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
|
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
|
||||||
|
|
||||||
const char * getHostname();
|
const char * getHostname();
|
||||||
|
@ -658,5 +658,5 @@
|
|||||||
#define CONFIG_ULP_COPROC_ENABLED CONFIG_ESP32_ULP_COPROC_ENABLED
|
#define CONFIG_ULP_COPROC_ENABLED CONFIG_ESP32_ULP_COPROC_ENABLED
|
||||||
#define CONFIG_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
#define CONFIG_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
||||||
#define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS
|
#define CONFIG_WARN_WRITE_STRINGS CONFIG_COMPILER_WARN_WRITE_STRINGS
|
||||||
#define CONFIG_ARDUINO_IDF_COMMIT "1d7068e4b"
|
#define CONFIG_ARDUINO_IDF_COMMIT ""
|
||||||
#define CONFIG_ARDUINO_IDF_BRANCH "master"
|
#define CONFIG_ARDUINO_IDF_BRANCH "master"
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user