Skip to content

Commit

Permalink
Merge branch 'feature/support_i2s_on_p4' into 'master'
Browse files Browse the repository at this point in the history
feat(i2s): support i2s on esp32p4

Closes IDF-6508

See merge request espressif/esp-idf!24280
  • Loading branch information
L-KAYA committed Sep 28, 2023
2 parents 4a40c7b + e1039f9 commit 4c6f4b3
Show file tree
Hide file tree
Showing 58 changed files with 2,541 additions and 717 deletions.
3 changes: 2 additions & 1 deletion components/driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ endif()
# I2S related source files
if(CONFIG_SOC_I2S_SUPPORTED)
list(APPEND srcs "i2s/i2s_common.c"
"i2s/i2s_platform.c"
"i2s/i2s_std.c"
"deprecated/i2s_legacy.c")
if(CONFIG_SOC_I2S_SUPPORTS_PDM)
Expand Down Expand Up @@ -236,7 +237,7 @@ else()
# Can be removed together with legacy drivers)
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${includes}
PRIV_REQUIRES efuse esp_timer
PRIV_REQUIRES efuse esp_timer esp_mm
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
LDFRAGMENTS ${ldfragments}
)
Expand Down
3 changes: 2 additions & 1 deletion components/driver/dac/esp32/dac_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "hal/adc_ll.h"
#include "hal/i2s_hal.h"
#include "hal/i2s_types.h"
#include "hal/clk_tree_ll.h"
#include "soc/i2s_periph.h"
#include "../dac_priv_dma.h"
#include "esp_private/i2s_platform.h"
Expand Down Expand Up @@ -46,7 +47,7 @@ static const char *TAG = "DAC_DMA";
static uint32_t s_dac_set_apll_freq(uint32_t mclk)
{
/* Calculate the expected APLL */
int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1);
int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1);
/* apll_freq = mclk * div
* when div = 1, hardware will still divide 2
* when div = 0, hardware will divide 255
Expand Down
7 changes: 4 additions & 3 deletions components/driver/dac/esp32s2/dac_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "hal/dac_ll.h"
#include "hal/adc_ll.h"
#include "hal/hal_utils.h"
#include "hal/clk_tree_ll.h"
#include "soc/lldesc.h"
#include "soc/soc.h"
#include "soc/soc_caps.h"
Expand Down Expand Up @@ -75,9 +76,9 @@ static esp_err_t s_dac_dma_periph_set_clock(uint32_t freq_hz, bool is_apll){
uint32_t digi_ctrl_freq; // Digital controller clock
if (is_apll) {
/* Theoretical frequency range (due to the limitation of DAC, the maximum frequency may not reach):
* SOC_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz
* SOC_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */
digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? SOC_APLL_MIN_HZ :SOC_APLL_MAX_HZ);
* CLK_LL_APLL_MAX_HZ: 119.24 Hz ~ 67.5 MHz
* CLK_LL_APLL_MIN_HZ: 5.06 Hz ~ 2.65 MHz */
digi_ctrl_freq = s_dac_set_apll_freq(freq_hz < 120 ? CLK_LL_APLL_MIN_HZ :CLK_LL_APLL_MAX_HZ);
ESP_RETURN_ON_FALSE(digi_ctrl_freq, ESP_ERR_INVALID_ARG, TAG, "set APLL coefficients failed");
} else {
digi_ctrl_freq = APB_CLK_FREQ;
Expand Down
111 changes: 42 additions & 69 deletions components/driver/deprecated/i2s_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
#include "hal/gpio_hal.h"
#include "driver/i2s_types_legacy.h"
#include "hal/i2s_hal.h"
#if SOC_I2S_SUPPORTS_APLL
#include "hal/clk_tree_ll.h"
#endif

#if SOC_I2S_SUPPORTS_DAC
#include "hal/dac_ll.h"
#include "hal/dac_types.h"
Expand All @@ -48,6 +52,7 @@
#include "esp_pm.h"
#include "esp_efuse.h"
#include "esp_rom_gpio.h"
#include "esp_private/i2s_platform.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"

Expand All @@ -58,6 +63,18 @@ static const char *TAG = "i2s(legacy)";
#define I2S_ENTER_CRITICAL(i2s_num) portENTER_CRITICAL(&i2s_spinlock[i2s_num])
#define I2S_EXIT_CRITICAL(i2s_num) portEXIT_CRITICAL(&i2s_spinlock[i2s_num])

#if SOC_PERIPH_CLK_CTRL_SHARED
#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2S_CLOCK_SRC_ATOMIC()
#endif

#if !SOC_RCC_IS_INDEPENDENT
#define I2S_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define I2S_RCC_ATOMIC()
#endif

#define I2S_DMA_BUFFER_MAX_SIZE 4092

#if SOC_I2S_SUPPORTS_ADC_DAC
Expand Down Expand Up @@ -134,9 +151,6 @@ typedef struct {
uint32_t total_slot; /*!< Total slot number */
} i2s_obj_t;

// Record the component name that using I2S peripheral
static const char *comp_using_i2s[SOC_I2S_NUM] = {[0 ... SOC_I2S_NUM - 1] = NULL};

// Global I2S object pointer
static i2s_obj_t *p_i2s[SOC_I2S_NUM] = {
[0 ... SOC_I2S_NUM - 1] = NULL,
Expand All @@ -147,11 +161,6 @@ static portMUX_TYPE i2s_spinlock[SOC_I2S_NUM] = {
[0 ... SOC_I2S_NUM - 1] = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED,
};


__attribute__((weak)) esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name);

__attribute__((weak)) esp_err_t i2s_platform_release_occupation(int id);

/*-------------------------------------------------------------
I2S DMA operation
-------------------------------------------------------------*/
Expand Down Expand Up @@ -633,7 +642,7 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3
#if SOC_I2S_SUPPORTS_APLL
if (use_apll) {
/* Calculate the expected APLL */
int div = (int)((SOC_APLL_MIN_HZ / mclk) + 1);
int div = (int)((CLK_LL_APLL_MIN_HZ / mclk) + 1);
/* apll_freq = mclk * div
* when div = 1, hardware will still divide 2
* when div = 0, the final mclk will be unpredictable
Expand All @@ -654,12 +663,12 @@ static uint32_t i2s_config_source_clock(i2s_port_t i2s_num, bool use_apll, uint3
/* In APLL mode, there is no sclk but only mclk, so return 0 here to indicate APLL mode */
return real_freq;
}
return I2S_LL_DEFAULT_PLL_CLK_FREQ;
return I2S_LL_DEFAULT_CLK_FREQ;
#else
if (use_apll) {
ESP_LOGW(TAG, "APLL not supported on current chip, use I2S_CLK_SRC_DEFAULT as default clock source");
}
return I2S_LL_DEFAULT_PLL_CLK_FREQ;
return I2S_LL_DEFAULT_CLK_FREQ;
#endif
}

Expand Down Expand Up @@ -1021,11 +1030,13 @@ static void i2s_set_clock_legacy(i2s_port_t i2s_num)
i2s_clk_config_t *clk_cfg = &p_i2s[i2s_num]->clk_cfg;
i2s_hal_clock_info_t clk_info;
i2s_calculate_clock(i2s_num, &clk_info);
if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
}
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
i2s_hal_set_rx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
I2S_CLOCK_SRC_ATOMIC() {
if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
i2s_hal_set_tx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
}
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
i2s_hal_set_rx_clock(&(p_i2s[i2s_num]->hal), &clk_info, clk_cfg->clk_src);
}
}
}

Expand Down Expand Up @@ -1479,17 +1490,6 @@ static esp_err_t i2s_init_legacy(i2s_port_t i2s_num, int intr_alloc_flag)
ESP_RETURN_ON_ERROR(i2s_realloc_dma_buffer(i2s_num, p_i2s[i2s_num]->rx), TAG, "Allocate I2S dma rx buffer failed");
}

/* Initialize I2S DMA object */
#if SOC_I2S_HW_VERSION_2
/* Enable tx/rx submodule clock */
if (p_i2s[i2s_num]->dir & I2S_DIR_TX) {
i2s_ll_tx_enable_clock(p_i2s[i2s_num]->hal.dev);
}
if (p_i2s[i2s_num]->dir & I2S_DIR_RX) {
i2s_ll_rx_enable_clock(p_i2s[i2s_num]->hal.dev);
}
#endif

return ESP_OK;
}

Expand Down Expand Up @@ -1538,12 +1538,14 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)

#if SOC_I2S_SUPPORTS_APLL
if (obj->use_apll) {
// switch back to PLL clock source
if (obj->dir & I2S_DIR_TX) {
i2s_ll_tx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT);
}
if (obj->dir & I2S_DIR_RX) {
i2s_ll_rx_clk_set_src(obj->hal.dev, I2S_CLK_SRC_DEFAULT);
I2S_CLOCK_SRC_ATOMIC() {
// switch back to PLL clock source
if (obj->dir & I2S_DIR_TX) {
i2s_hal_set_tx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
}
if (obj->dir & I2S_DIR_RX) {
i2s_hal_set_rx_clock(&obj->hal, NULL, I2S_CLK_SRC_DEFAULT);
}
}
periph_rtc_apll_release();
}
Expand All @@ -1556,11 +1558,13 @@ esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num)
}
#endif
#if SOC_I2S_HW_VERSION_2
if (obj->dir & I2S_DIR_TX) {
i2s_ll_tx_disable_clock(obj->hal.dev);
}
if (obj->dir & I2S_DIR_RX) {
i2s_ll_rx_disable_clock(obj->hal.dev);
I2S_CLOCK_SRC_ATOMIC() {
if (obj->dir & I2S_DIR_TX) {
i2s_ll_tx_disable_clock(obj->hal.dev);
}
if (obj->dir & I2S_DIR_RX) {
i2s_ll_rx_disable_clock(obj->hal.dev);
}
}
#endif
/* Disable module clock */
Expand Down Expand Up @@ -1896,37 +1900,6 @@ esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)
return ESP_OK;
}

esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
{
esp_err_t ret = ESP_ERR_NOT_FOUND;
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
portENTER_CRITICAL(&i2s_spinlock[id]);
if (!comp_using_i2s[id]) {
ret = ESP_OK;
comp_using_i2s[id] = comp_name;
periph_module_enable(i2s_periph_signal[id].module);
i2s_ll_enable_clock(I2S_LL_GET_HW(id));
}
portEXIT_CRITICAL(&i2s_spinlock[id]);
return ret;
}

esp_err_t i2s_platform_release_occupation(int id)
{
esp_err_t ret = ESP_ERR_INVALID_STATE;
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
portENTER_CRITICAL(&i2s_spinlock[id]);
if (comp_using_i2s[id]) {
ret = ESP_OK;
comp_using_i2s[id] = NULL;
/* Disable module clock */
periph_module_disable(i2s_periph_signal[id].module);
i2s_ll_disable_clock(I2S_LL_GET_HW(id));
}
portEXIT_CRITICAL(&i2s_spinlock[id]);
return ret;
}

/**
* @brief This function will be called during start up, to check that the new i2s driver is not running along with the legacy i2s driver
*/
Expand Down
Loading

0 comments on commit 4c6f4b3

Please sign in to comment.