feat(i2s): support i2s & apll on esp32s31

This commit is contained in:
laokaiyao
2026-04-22 09:30:53 +08:00
committed by Chen Chen
parent 91105b65b6
commit 8d0fca08a0
45 changed files with 2452 additions and 132 deletions
@@ -5,6 +5,7 @@
*/
#include <stdint.h>
#include <stdatomic.h>
#include "esp_clk_tree.h"
#include "esp_err.h"
#include "esp_check.h"
@@ -16,6 +17,9 @@
ESP_LOG_ATTR_TAG(TAG, "esp_clk_tree");
static _Atomic int16_t s_pll_src_cg_ref_cnt[SOC_MOD_CLK_INVALID] = { 0 };
static bool s_clk_tree_initialized = false;
esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_src_freq_precision_t precision,
uint32_t *freq_value)
{
@@ -52,6 +56,9 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
case SOC_MOD_CLK_MPLL:
clk_src_freq = clk_ll_mpll_get_freq_mhz(clk_hal_xtal_get_freq_mhz()) * MHZ;
break;
case SOC_MOD_CLK_APLL:
clk_src_freq = clk_hal_apll_get_freq_hz();
break;
case SOC_MOD_CLK_RTC_SLOW:
clk_src_freq = esp_clk_tree_lp_slow_get_freq_hz(precision);
break;
@@ -82,9 +89,22 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr
esp_err_t esp_clk_tree_src_set_freq_hz(soc_module_clk_t clk_src, uint32_t expt_freq_value, uint32_t *ret_freq_value)
{
/* TODO: [ESP32S31] IDF-14733 */
(void)clk_src; (void)expt_freq_value; (void)ret_freq_value;
return ESP_ERR_NOT_SUPPORTED;
ESP_RETURN_ON_FALSE(clk_src > 0 && clk_src < SOC_MOD_CLK_INVALID, ESP_ERR_INVALID_ARG, TAG, "unknown clk src");
ESP_RETURN_ON_FALSE(expt_freq_value > 0, ESP_ERR_INVALID_ARG, TAG, "invalid frequency");
uint32_t real_freq_value = 0;
esp_err_t ret = ESP_OK;
switch (clk_src) {
case SOC_MOD_CLK_APLL:
ret = esp_clk_tree_apll_freq_set(expt_freq_value, &real_freq_value);
break;
default:
return ESP_ERR_NOT_SUPPORTED;
}
if (ret_freq_value) {
*ret_freq_value = real_freq_value;
}
return ret;
}
static int16_t s_cpll_ref_cnt = 0;
@@ -102,6 +122,7 @@ void esp_clk_tree_initialize(void)
// Gating
// flash clock source is set to BBPLL in bootloader
s_clk_tree_initialized = true;
}
bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
@@ -134,6 +155,49 @@ bool esp_clk_tree_enable_power(soc_root_clk_circuit_t clk_circuit, bool enable)
esp_err_t esp_clk_tree_enable_src(soc_module_clk_t clk_src, bool enable)
{
if (clk_src < 1 || clk_src >= SOC_MOD_CLK_INVALID) {
// some conditions is legal, e.g. -1 means external clock source
return ESP_OK;
}
if (!s_clk_tree_initialized) {
return ESP_OK;
}
// These clock sources have their own reference counting
switch (clk_src) {
case SOC_MOD_CLK_APLL:
if (enable) {
esp_clk_tree_apll_acquire();
} else {
esp_clk_tree_apll_release();
}
return ESP_OK;
case SOC_MOD_CLK_MPLL:
if (enable) {
return esp_clk_tree_mpll_acquire();
} else {
esp_clk_tree_mpll_release();
}
return ESP_OK;
default:
break;
}
// Other clock sources use the global reference counting
int16_t prev_ref_cnt = 0;
if (enable) {
prev_ref_cnt = atomic_fetch_add(&s_pll_src_cg_ref_cnt[clk_src], 1);
} else {
prev_ref_cnt = atomic_fetch_sub(&s_pll_src_cg_ref_cnt[clk_src], 1);
if (prev_ref_cnt <= 0) {
ESP_EARLY_LOGW(TAG, "soc_module_clk_t %d disabled multiple times!!", clk_src);
atomic_store(&s_pll_src_cg_ref_cnt[clk_src], 0);
return ESP_OK;
}
}
// TODO: IDF-15502
return ESP_OK;
}
@@ -592,7 +592,18 @@ uint32_t rtc_clk_apll_coeff_calc(uint32_t freq, uint32_t *_o_div, uint32_t *_sdm
void rtc_clk_apll_coeff_set(uint32_t o_div, uint32_t sdm0, uint32_t sdm1, uint32_t sdm2)
{
// TODO: IDF-14771, IDF-14750
clk_ll_apll_set_config(o_div, sdm0, sdm1, sdm2);
/* calibration */
ANALOG_CLOCK_ENABLE();
clk_ll_apll_set_calibration();
/* wait for calibration end */
while (!clk_ll_apll_calibration_is_done()) {
/* use esp_rom_delay_us so the RTC bus doesn't get flooded */
esp_rom_delay_us(1);
}
ANALOG_CLOCK_DISABLE();
}
void rtc_dig_clk8m_enable(void)