From 965530967a05dcd1b190402cbea4e7b485f0900d Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 21 Aug 2026 11:05:33 +0800 Subject: [PATCH] fix(ulp): hardcode LP core RC_FAST frequency per target The SoC RC_FAST approximation is a nominal figure that can be off by ~10% from the clock the LP core actually runs at, which made ulp_lp_core_delay_us() over-delay by up to 9% and the LP core delay test flake on ESP32-C5 and ESP32-C6. Use a measured per-target value instead, and fail the build for targets that have no measured value so that new chips cannot silently inherit a wrong one. --- .../include/ulp_lp_core_cpu_freq_shared.h | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_cpu_freq_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_cpu_freq_shared.h index d4f2b00ecf9..cbf70c7e161 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_cpu_freq_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_cpu_freq_shared.h @@ -6,13 +6,35 @@ #pragma once #include "sdkconfig.h" -#include "soc/clk_tree_defs.h" #include "soc/soc_caps.h" -/* LP_FAST_CLK is not very accurate, for now use a rough estimate */ +/* + * SOC_CLK_RC_FAST_FREQ_APPROX is a nominal value and can be off by ~10% from the + * clock the LP core actually runs at, e.g. 17.5 MHz nominal vs 16.0 MHz measured + * on ESP32-C6. Hardcode a per-target estimate obtained from the "Test LP core + * delay" test case instead. Values must be a multiple of 500 kHz, otherwise + * LP_CORE_CYCLES_PER_US_NUM below silently rounds them down. + */ +#if CONFIG_IDF_TARGET_ESP32C5 +#define LP_CORE_RC_FAST_FREQUENCY_HZ 16500000U +#elif CONFIG_IDF_TARGET_ESP32C6 +#define LP_CORE_RC_FAST_FREQUENCY_HZ 16000000U +#elif CONFIG_IDF_TARGET_ESP32P4 +#define LP_CORE_RC_FAST_FREQUENCY_HZ 16500000U +#elif CONFIG_IDF_TARGET_ESP32S31 +#define LP_CORE_RC_FAST_FREQUENCY_HZ 17500000U +#else +#error "LP core RC_FAST frequency has not been measured for this target" +#endif + +#if (LP_CORE_RC_FAST_FREQUENCY_HZ % 500000U) != 0U +#error "LP_CORE_RC_FAST_FREQUENCY_HZ must be a multiple of 500 kHz" +#endif + +/* LP_FAST_CLK is not very accurate, for now use a target-specific rough estimate */ #if CONFIG_RTC_FAST_CLK_SRC_RC_FAST -#define LP_CORE_CPU_FREQUENCY_HZ SOC_CLK_RC_FAST_FREQ_APPROX -#define LP_CORE_CYCLES_PER_US_NUM (SOC_CLK_RC_FAST_FREQ_APPROX / 500000U) +#define LP_CORE_CPU_FREQUENCY_HZ LP_CORE_RC_FAST_FREQUENCY_HZ +#define LP_CORE_CYCLES_PER_US_NUM (LP_CORE_RC_FAST_FREQUENCY_HZ / 500000U) #define LP_CORE_CYCLES_PER_US_DENOM 2U #elif CONFIG_RTC_FAST_CLK_SRC_XTAL #if SOC_XTAL_SUPPORT_48M @@ -25,8 +47,8 @@ #define LP_CORE_CYCLES_PER_US_DENOM 1U #endif #else // Default value in chip without rtc fast clock sel option -#define LP_CORE_CPU_FREQUENCY_HZ SOC_CLK_RC_FAST_FREQ_APPROX -#define LP_CORE_CYCLES_PER_US_NUM (SOC_CLK_RC_FAST_FREQ_APPROX / 500000U) +#define LP_CORE_CPU_FREQUENCY_HZ LP_CORE_RC_FAST_FREQUENCY_HZ +#define LP_CORE_CYCLES_PER_US_NUM (LP_CORE_RC_FAST_FREQUENCY_HZ / 500000U) #define LP_CORE_CYCLES_PER_US_DENOM 2U #endif