diff --git a/components/esp_eth/src/esp_eth_mac_esp.c b/components/esp_eth/src/esp_eth_mac_esp.c index d59e1e33b4..25472c1e8c 100644 --- a/components/esp_eth/src/esp_eth_mac_esp.c +++ b/components/esp_eth/src/esp_eth_mac_esp.c @@ -18,6 +18,7 @@ #include "esp_cpu.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" +#include "esp_clock_output.h" #include "esp_private/esp_clk.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -51,6 +52,7 @@ typedef struct { int smi_mdc_gpio_num; int smi_mdio_gpio_num; eth_mac_clock_config_t clock_config; + esp_clock_output_mapping_handle_t rmii_clk_hdl; // we use the esp_clock_output driver to output a pre-configured APLL clock as the RMII reference clock uint8_t addr[6]; uint8_t *rx_buf[CONFIG_ETH_DMA_RX_BUFFER_NUM]; uint8_t *tx_buf[CONFIG_ETH_DMA_TX_BUFFER_NUM]; @@ -472,6 +474,9 @@ static void esp_emac_free_driver_obj(emac_esp32_t *emac, void *descriptors) for (int i = 0; i < CONFIG_ETH_DMA_RX_BUFFER_NUM; i++) { free(emac->rx_buf[i]); } + if (emac->rmii_clk_hdl) { + esp_clock_output_stop(emac->rmii_clk_hdl); + } #ifdef CONFIG_PM_ENABLE if (emac->pm_lock) { esp_pm_lock_delete(emac->pm_lock); @@ -519,7 +524,7 @@ static esp_err_t esp_emac_alloc_driver_obj(const eth_mac_config_t *config, emac_ core_num = esp_cpu_get_core_id(); } BaseType_t xReturned = xTaskCreatePinnedToCore(emac_esp32_rx_task, "emac_rx", config->rx_task_stack_size, emac, - config->rx_task_prio, &emac->rx_task_hdl, core_num); + config->rx_task_prio, &emac->rx_task_hdl, core_num); ESP_GOTO_ON_FALSE(xReturned == pdPASS, ESP_FAIL, err, TAG, "create emac_rx task failed"); *out_descriptors = descriptors; @@ -578,15 +583,18 @@ static esp_err_t esp_emac_config_data_interface(const eth_esp32_emac_config_t *e emac->clock_config.rmii.clock_gpio == EMAC_CLK_OUT_180_GPIO, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock output GPIO"); emac_hal_iomux_rmii_clk_ouput(emac->clock_config.rmii.clock_gpio); - if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { - REG_SET_FIELD(PIN_CTRL, CLK_OUT1, 6); - } /* Enable RMII clock */ emac_hal_clock_enable_rmii_output(&emac->hal); - // Power up APLL clock + // the RMII reference comes from the APLL periph_rtc_apll_acquire(); ESP_GOTO_ON_ERROR(emac_config_apll_clock(), err, TAG, "Configure APLL for RMII failed"); emac->use_apll = true; + + // we can also use the IOMUX to route the APLL clock to specific GPIO + if (emac->clock_config.rmii.clock_gpio == EMAC_APPL_CLK_OUT_GPIO) { + ESP_GOTO_ON_ERROR(esp_clock_output_start(CLKOUT_SIG_APLL, EMAC_APPL_CLK_OUT_GPIO, &emac->rmii_clk_hdl), + err, TAG, "start APLL clock output failed"); + } } else { ESP_GOTO_ON_FALSE(false, ESP_ERR_INVALID_ARG, err, TAG, "invalid EMAC clock mode"); } diff --git a/components/esp_hw_support/include/esp_private/clkout_channel.h b/components/esp_hw_support/clkout_channel.h similarity index 99% rename from components/esp_hw_support/include/esp_private/clkout_channel.h rename to components/esp_hw_support/clkout_channel.h index 2daa0d447f..57169f0cc2 100644 --- a/components/esp_hw_support/include/esp_private/clkout_channel.h +++ b/components/esp_hw_support/clkout_channel.h @@ -5,7 +5,9 @@ */ #pragma once + #include "sdkconfig.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_hw_support/esp_clock_output.c b/components/esp_hw_support/esp_clock_output.c index 0ccf012323..1f2248aa40 100644 --- a/components/esp_hw_support/esp_clock_output.c +++ b/components/esp_hw_support/esp_clock_output.c @@ -6,13 +6,12 @@ #include #include "sdkconfig.h" - +#include "freertos/FreeRTOS.h" #include "driver/gpio.h" #include "esp_clock_output.h" #include "esp_check.h" #include "esp_rom_gpio.h" -#include "esp_private/clkout_channel.h" -#include "esp_private/startup_internal.h" +#include "clkout_channel.h" #include "hal/gpio_hal.h" #include "soc/soc_caps.h" #include "soc/io_mux_reg.h" @@ -59,13 +58,13 @@ static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].is_mapped = true; allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } else if ((s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_io_bmap & BIT(gpio_num)) && - (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { + (s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) { allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)]; } allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num); portEXIT_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock); #elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX - for(uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { + for (uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) { portENTER_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock); if (!s_clkout_handle[channel].is_mapped) { s_clkout_handle[channel].is_mapped = true; diff --git a/components/esp_hw_support/include/esp_clock_output.h b/components/esp_hw_support/include/esp_clock_output.h index 33c87f9cec..2acbb1377d 100644 --- a/components/esp_hw_support/include/esp_clock_output.h +++ b/components/esp_hw_support/include/esp_clock_output.h @@ -6,15 +6,11 @@ #pragma once -#include #include -#include "sdkconfig.h" +#include "esp_err.h" #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" - -#include "esp_err.h" #include "driver/gpio.h" -#include "freertos/FreeRTOS.h" #ifdef __cplusplus extern "C" { @@ -46,7 +42,7 @@ esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_nu * - ESP_ERR_INVALID_STATE The clock in handle is already in the disabled state */ esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl); -#endif +#endif // SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX || SOC_GPIO_CLOCKOUT_BY_IO_MUX #ifdef __cplusplus }