Skip to content

Commit e8475d7

Browse files
committed
feat(esp_hw_support): compensate the error introduced to LACT during APB frequency switching
1 parent 3114935 commit e8475d7

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

components/esp_hw_support/linker.lf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ entries:
1616
if PM_SLP_IRAM_OPT = y:
1717
rtc_clk (noflash)
1818
rtc_time (noflash_text)
19+
if IDF_TARGET_ESP32 = y:
20+
rtc_clk:rtc_clk_cpu_freq_to_pll_mhz (noflash)
21+
rtc_clk:rtc_clk_cpu_freq_to_xtal (noflash)
1922
if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED = y:
2023
rtc_init:rtc_vddsdio_get_config (noflash)
2124
rtc_init:rtc_vddsdio_set_config (noflash)

components/esp_hw_support/port/esp32/rtc_clk.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,19 +402,49 @@ static void rtc_clk_cpu_freq_to_8m(void)
402402
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
403403
}
404404

405+
#ifndef BOOTLOADER_BUILD
406+
static const DRAM_ATTR int16_t dfs_lact_conpensate_table[3][3] = { \
407+
/* From / To 80 160 240*/ \
408+
/* 10 */ {138, 220, 18}, \
409+
/* 20 */ {128, 205, -3579}, \
410+
/* 40 */ {34, 100, 0}, \
411+
};
412+
413+
__attribute__((weak)) IRAM_ATTR int16_t rtc_clk_get_lact_compensation_delay(uint32_t cur_freq, uint32_t tar_freq)
414+
{
415+
return dfs_lact_conpensate_table[(cur_freq == 10) ? 0 : (cur_freq == 20) ? 1 : 2][(tar_freq == 80) ? 0 : (tar_freq == 160) ? 1 : 2];
416+
}
417+
#endif
418+
405419
/**
406420
* Switch to one of PLL-based frequencies. Current frequency can be XTAL or PLL.
407421
* PLL must already be enabled.
408422
* @param cpu_freq new CPU frequency
409423
*/
410-
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
424+
__attribute__((optimize("-O2")))
425+
NOINLINE_ATTR static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
411426
{
412427
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
413428
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
414429
#ifndef BOOTLOADER_BUILD
415-
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
430+
uint32_t cur_freq = esp_rom_get_cpu_ticks_per_us();
431+
int16_t delay_cycle = rtc_clk_get_lact_compensation_delay(cur_freq, cpu_freq_mhz);
432+
if (cur_freq <= 40 && delay_cycle >= 0) {
433+
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
434+
for (int i = 0; i < delay_cycle; ++i) {
435+
__asm__ __volatile__("nop");
436+
}
437+
}
416438
#endif
417439
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
440+
#ifndef BOOTLOADER_BUILD
441+
if (cur_freq <= 40 && delay_cycle < 0) {
442+
for (int i = 0; i > delay_cycle; --i) {
443+
__asm__ __volatile__("nop");
444+
}
445+
timer_ll_set_lact_clock_prescale(TIMER_LL_GET_HW(LACT_MODULE), 80 / LACT_TICKS_PER_US);
446+
}
447+
#endif
418448
/* adjust ref_tick */
419449
clk_ll_ref_tick_set_divider(SOC_CPU_CLK_SRC_PLL, cpu_freq_mhz);
420450
/* switch clock source */

0 commit comments

Comments
 (0)