refactor(emac): use clock_output driver for configuring RMII reference clock

This commit is contained in:
morris 2023-10-26 18:01:30 +08:00
parent a436eaf045
commit d78750306d
4 changed files with 21 additions and 16 deletions

View File

@ -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");
}

View File

@ -5,7 +5,9 @@
*/
#pragma once
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {

View File

@ -6,13 +6,12 @@
#include <sys/queue.h>
#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;

View File

@ -6,15 +6,11 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#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
}