refactor(i2s): stop to output mclk after uninstalled on esp32

This commit is contained in:
laokaiyao 2023-09-11 15:09:31 +08:00 committed by wuzhenghui
parent d6cda1b6e1
commit e2c182ab4b
3 changed files with 35 additions and 29 deletions

View File

@ -39,6 +39,10 @@
#include "driver/adc_types_legacy.h"
#endif // SOC_I2S_SUPPORTS_ADC
#if CONFIG_IDF_TARGET_ESP32
#include "esp_clock_output.h"
#endif
#if SOC_GDMA_SUPPORTED
#include "esp_private/gdma.h"
#endif
@ -135,7 +139,9 @@ typedef struct {
bool use_apll; /*!< I2S use APLL clock */
int fixed_mclk; /*!< I2S fixed MLCK clock */
i2s_mclk_multiple_t mclk_multiple; /*!< The multiple of I2S master clock(MCLK) to sample rate */
#if CONFIG_IDF_TARGET_ESP32
esp_clock_output_mapping_handle_t mclk_out_hdl;
#endif
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock;
#endif
@ -1500,6 +1506,12 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
i2s_obj_t *obj = p_i2s[i2s_num];
i2s_stop(i2s_num);
#if CONFIG_IDF_TARGET_ESP32
if (obj->mclk_out_hdl) {
esp_clock_output_stop(obj->mclk_out_hdl);
}
#endif
#if SOC_I2S_SUPPORTS_ADC_DAC
if ((int)(obj->mode) == I2S_COMM_MODE_ADC_DAC) {
if (obj->dir & I2S_DIR_TX) {
@ -1800,20 +1812,8 @@ static esp_err_t i2s_check_set_mclk(i2s_port_t i2s_num, gpio_num_t gpio_num)
return ESP_OK;
}
#if CONFIG_IDF_TARGET_ESP32
ESP_RETURN_ON_FALSE((gpio_num == GPIO_NUM_0 || gpio_num == GPIO_NUM_1 || gpio_num == GPIO_NUM_3),
ESP_ERR_INVALID_ARG, TAG,
"ESP32 only support to set GPIO0/GPIO1/GPIO3 as mclk signal, error GPIO number:%d", gpio_num);
bool is_i2s0 = i2s_num == I2S_NUM_0;
if (gpio_num == GPIO_NUM_0) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFFF0 : 0xFFFF);
} else if (gpio_num == GPIO_NUM_1) {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3);
WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xF0F0 : 0xF0FF);
} else {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2);
WRITE_PERI_REG(PIN_CTRL, is_i2s0 ? 0xFF00 : 0xFF0F);
}
soc_clkout_sig_id_t clkout_sig = (i2s_num == I2S_NUM_0) ? CLKOUT_SIG_I2S0 : CLKOUT_SIG_I2S1;
ESP_RETURN_ON_ERROR(esp_clock_output_start(clkout_sig, gpio_num, &p_i2s[i2s_num]->mclk_out_hdl), TAG, "mclk configure failed");
#else
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid");
gpio_matrix_out_check_and_set(gpio_num, i2s_periph_signal[i2s_num].mck_out_sig, 0, 0);

View File

@ -46,6 +46,10 @@
#include "driver/i2s_common.h"
#include "i2s_private.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp_clock_output.h"
#endif
#include "clk_ctrl_os.h"
#include "esp_clk_tree.h"
#include "esp_intr_alloc.h"
@ -152,6 +156,11 @@ static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj)
ESP_ERR_INVALID_STATE, TAG,
"there still have channels under this i2s controller");
int id = (*i2s_obj)->id;
#if CONFIG_IDF_TARGET_ESP32
if ((*i2s_obj)->mclk_out_hdl) {
esp_clock_output_stop((*i2s_obj)->mclk_out_hdl);
}
#endif
#if SOC_I2S_HW_VERSION_1
i2s_ll_enable_dma((*i2s_obj)->hal.dev, false);
#endif
@ -739,20 +748,11 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_sr
return ESP_OK;
}
#if CONFIG_IDF_TARGET_ESP32
ESP_RETURN_ON_FALSE((gpio_num == GPIO_NUM_0 || gpio_num == GPIO_NUM_1 || gpio_num == GPIO_NUM_3),
ESP_ERR_INVALID_ARG, TAG,
"ESP32 only support to set GPIO0/GPIO1/GPIO3 as mclk signal, error GPIO number:%d", gpio_num);
bool is_i2s0 = id == I2S_NUM_0;
bool is_apll = clk_src == I2S_CLK_SRC_APLL;
if (gpio_num == GPIO_NUM_0) {
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1);
gpio_ll_set_iomux_pin_ctrl(is_apll ? 0xFFF6 : (is_i2s0 ? 0xFFF0 : 0xFFFF), 0xFFFFFFFF, 0);
} else if (gpio_num == GPIO_NUM_1) {
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3);
gpio_ll_set_iomux_pin_ctrl(is_apll ? 0xF6F6 : (is_i2s0 ? 0xF0F0 : 0xF0FF), 0xFFFFFFFF, 0);
} else {
gpio_hal_iomux_func_sel(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2);
gpio_ll_set_iomux_pin_ctrl(is_apll ? 0xFF66 : (is_i2s0 ? 0xFF00 : 0xFF0F), 0xFFFFFFFF, 0);
if (g_i2s.controller[id]->mclk_out_hdl == NULL) {
soc_clkout_sig_id_t clkout_sig = is_apll ? CLKOUT_SIG_APLL : (is_i2s0 ? CLKOUT_SIG_I2S0 : CLKOUT_SIG_I2S1);
ESP_RETURN_ON_ERROR(esp_clock_output_start(clkout_sig, gpio_num, &(g_i2s.controller[id]->mclk_out_hdl)), TAG, "mclk configure failed");
}
#else
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid");

View File

@ -7,12 +7,15 @@
#pragma once
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "soc/lldesc.h"
#include "soc/soc_caps.h"
#include "hal/i2s_hal.h"
#include "driver/i2s_types.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#if CONFIG_IDF_TARGET_ESP32
#include "esp_clock_output.h"
#endif
#if SOC_GDMA_SUPPORTED
#include "esp_private/gdma.h"
#endif
@ -114,6 +117,9 @@ typedef struct {
i2s_chan_handle_t tx_chan; /*!< tx channel handler */
i2s_chan_handle_t rx_chan; /*!< rx channel handler */
int mclk; /*!< MCK out pin, shared by tx/rx*/
#if CONFIG_IDF_TARGET_ESP32
esp_clock_output_mapping_handle_t mclk_out_hdl; /*!< The handle of MCLK output signal */
#endif
} i2s_controller_t;
struct i2s_channel_obj_t {