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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user