feat(esp_hw_support): compensate the error introduced to LACT during APB frequency switching

This commit is contained in:
wuzhenghui
2025-05-21 10:08:03 +08:00
parent 022614b1d3
commit 11f32b88ac
2 changed files with 35 additions and 2 deletions

View File

@ -16,6 +16,9 @@ entries:
if PM_SLP_IRAM_OPT = y:
rtc_clk (noflash)
rtc_time (noflash_text)
if IDF_TARGET_ESP32 = y:
rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash)
rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash)
if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
rtc_init:rtc_vddsdio_get_config (noflash)
rtc_init:rtc_vddsdio_set_config (noflash)

View File

@ -402,19 +402,49 @@ static void rtc_clk_cpu_freq_to_8m(void)
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
}
#ifndef BOOTLOADER_BUILD
static const DRAM_ATTR int16_t dfs_lact_conpensate_table[3][3] = { \
/* From / To 80 160 240*/ \
/* 10 */ {138, 220, 18}, \
/* 20 */ {128, 205, -3579}, \
/* 40 */ {34, 100, 0}, \
};
__attribute__((weak)) IRAM_ATTR int16_t rtc_clk_get_lact_compensation_delay(uint32_t cur_freq, uint32_t tar_freq)
{
return dfs_lact_conpensate_table[(cur_freq == 10) ? 0 : (cur_freq == 20) ? 1 : 2][(tar_freq == 80) ? 0 : (tar_freq == 160) ? 1 : 2];
}
#endif
/**
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
* PLL must already be enabled.
* @param cpu_freq new CPU frequency
*/
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
__attribute__((optimize("-O2")))
NOINLINE_ATTR static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
{
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
#ifndef BOOTLOADER_BUILD
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
uint32_t cur_freq = esp_rom_get_cpu_ticks_per_us();
int16_t delay_cycle = rtc_clk_get_lact_compensation_delay(cur_freq, cpu_freq_mhz);
if (cur_freq <= 40 && delay_cycle >= 0) {
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
for (int i = 0; i < delay_cycle; ++i) {
__asm__ __volatile__("nop");
}
}
#endif
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
#ifndef BOOTLOADER_BUILD
if (cur_freq <= 40 && delay_cycle < 0) {
for (int i = 0; i > delay_cycle; --i) {
__asm__ __volatile__("nop");
}
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
}
#endif
/* adjust ref_tick */
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, cpu_freq_mhz);
/* switch clock source */