From 37f34f237f10c52bbd65eb5f804574d5e21b391b Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 14:26:20 -0300 Subject: [PATCH 1/3] driver: clock: espressif: get frequency default to calibrated value When clock get_rate() is called, return by default the calibrated frequency instead of nominal one. This improves accuracy specially when internal RC SLOW clock is used. To guarantee that nominal values can be still be retrieved, add a new type of clock subsys for such scenario. west.yml is also updated to add fix into calibration sources. Signed-off-by: Sylvio Alves --- drivers/clock_control/clock_control_esp32.c | 10 ++++++++-- .../zephyr/drivers/clock_control/esp32_clock_control.h | 2 ++ west.yml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/clock_control/clock_control_esp32.c b/drivers/clock_control/clock_control_esp32.c index a7f00a4962a1f..11df4ad0ee469 100644 --- a/drivers/clock_control/clock_control_esp32.c +++ b/drivers/clock_control/clock_control_esp32.c @@ -567,10 +567,16 @@ static int clock_control_esp32_get_rate(const struct device *dev, clock_control_ switch ((int)sys) { case ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST: - *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED); break; case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW: - *rate = clk_hal_lp_slow_get_freq_hz(); + *rate = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED); + break; + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL: + *rate = esp_clk_tree_lp_fast_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); + break; + case ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL: + *rate = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX); break; default: *rate = clk_hal_cpu_get_freq_hz(); diff --git a/include/zephyr/drivers/clock_control/esp32_clock_control.h b/include/zephyr/drivers/clock_control/esp32_clock_control.h index a56e9142e9d5d..30351ed9ffc32 100644 --- a/include/zephyr/drivers/clock_control/esp32_clock_control.h +++ b/include/zephyr/drivers/clock_control/esp32_clock_control.h @@ -26,6 +26,8 @@ #define ESP32_CLOCK_CONTROL_SUBSYS_CPU 50 #define ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST 51 #define ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW 52 +#define ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL 53 +#define ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL 54 struct esp32_cpu_clock_config { int clk_src; diff --git a/west.yml b/west.yml index 9e17860323029..9e49a4548e5c4 100644 --- a/west.yml +++ b/west.yml @@ -169,7 +169,7 @@ manifest: groups: - hal - name: hal_espressif - revision: 78f88d79bfdca7e84ec7aafb12c0ddd7440bf3d1 + revision: pull/507/head path: modules/hal/espressif west-commands: west/west-commands.yml groups: From ee34c5f78a621e038db3a4d2c11a979ba62408c5 Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 15:56:49 -0300 Subject: [PATCH 2/3] tests: counter_basic_api: esp32h2: remove custom tolerance ESP32-H2 counter test works with default tolerance. Signed-off-by: Sylvio Alves --- tests/drivers/counter/counter_basic_api/socs/esp32h2.conf | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/drivers/counter/counter_basic_api/socs/esp32h2.conf diff --git a/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf b/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf deleted file mode 100644 index e87bbb9811817..0000000000000 --- a/tests/drivers/counter/counter_basic_api/socs/esp32h2.conf +++ /dev/null @@ -1,2 +0,0 @@ -# LP Timer is driven by RC_SLOW, which has limited precision -CONFIG_TEST_DRIVER_COUNTER_TOLERANCE=20 From 4142de8e0ad4a6eac42ff4e27a9012aebf19c4af Mon Sep 17 00:00:00 2001 From: Sylvio Alves Date: Fri, 5 Dec 2025 15:58:18 -0300 Subject: [PATCH 3/3] tests: espressif: rtc_clk: update to keep nominal tests usage Update the test case to use the nominal clock_subsys and print calibration deviation. Signed-off-by: Sylvio Alves --- .../espressif/rtc_clk/src/rtc_clk_test.c | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c index 6933849e3942f..36a2114a92cf5 100644 --- a/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c +++ b/tests/boards/espressif/rtc_clk/src/rtc_clk_test.c @@ -141,27 +141,43 @@ ZTEST(rtc_clk, test_rtc_fast_src) { struct esp32_clock_config clk_cfg = {0}; int ret = 0; - uint32_t cpu_rate = 0; + uint32_t nominal_rate = 0; + uint32_t calibrated_rate = 0; clk_cfg.cpu.xtal_freq = (DT_PROP(DT_INST(0, DT_CPU_COMPAT), xtal_freq) / MHZ(1)); for (uint8_t i = 0; i < ARRAY_SIZE(rtc_rtc_fast_clk_src); i++) { clk_cfg.rtc.rtc_fast_clock_src = rtc_rtc_fast_clk_src[i]; - TC_PRINT("Testing RTC FAST CLK freq: %d MHz\n", rtc_rtc_fast_clk_src_freq_mhz[i]); + TC_PRINT("Testing RTC FAST CLK source: %d\n", rtc_rtc_fast_clk_src_freq_mhz[i]); ret = clock_control_configure( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST, &clk_cfg); - zassert_false(ret, "Failed to set CPU clock source"); + zassert_false(ret, "Failed to set RTC fast clock source"); + /* Verify nominal frequency matches expected value for selected source */ + ret = clock_control_get_rate( + clk_dev, + (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST_NOMINAL, + &nominal_rate); + zassert_false(ret, "Failed to get RTC_FAST nominal clock rate"); + zassert_equal(nominal_rate, rtc_rtc_fast_clk_src_freq_mhz[i], + "Nominal rate mismatch (%d != %d)", nominal_rate, + rtc_rtc_fast_clk_src_freq_mhz[i]); + + /* Also retrieve calibrated value for informational purposes */ ret = clock_control_get_rate( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_FAST, - &cpu_rate); - zassert_false(ret, "Failed to get RTC_FAST clock rate"); - zassert_equal(cpu_rate, rtc_rtc_fast_clk_src_freq_mhz[i], - "CPU clock rate is not equal to configured frequency (%d != %d)", - cpu_rate, rtc_rtc_fast_clk_src_freq_mhz[i]); + &calibrated_rate); + zassert_false(ret, "Failed to get RTC_FAST calibrated clock rate"); + + int32_t diff = (int32_t)calibrated_rate - (int32_t)nominal_rate; + int32_t deviation_tenths = (diff * 1000) / (int32_t)nominal_rate; + + TC_PRINT("Nominal: %d Hz, Calibrated: %d Hz (deviation: %d.%d%%)\n", nominal_rate, + calibrated_rate, deviation_tenths / 10, + (deviation_tenths < 0 ? -deviation_tenths : deviation_tenths) % 10); } } @@ -199,7 +215,8 @@ ZTEST(rtc_clk, test_rtc_slow_src) { struct esp32_clock_config clk_cfg = {0}; int ret = 0; - uint32_t cpu_rate = 0; + uint32_t nominal_rate = 0; + uint32_t calibrated_rate = 0; clk_cfg.cpu.xtal_freq = (DT_PROP(DT_INST(0, DT_CPU_COMPAT), xtal_freq) / MHZ(1)); @@ -213,13 +230,28 @@ ZTEST(rtc_clk, test_rtc_slow_src) &clk_cfg); zassert_false(ret, "Failed to set CPU clock source"); + /* Verify nominal frequency matches expected value for selected source */ + ret = clock_control_get_rate( + clk_dev, + (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW_NOMINAL, + &nominal_rate); + zassert_false(ret, "Failed to get RTC_SLOW nominal clock rate"); + zassert_equal(nominal_rate, rtc_rtc_slow_clk_src_freq[i], + "Nominal rate mismatch (%d != %d)", nominal_rate, + rtc_rtc_slow_clk_src_freq[i]); + + /* Also retrieve calibrated value for informational purposes */ ret = clock_control_get_rate( clk_dev, (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW, - &cpu_rate); - zassert_false(ret, "Failed to get RTC_SLOW clock rate"); - zassert_equal(cpu_rate, rtc_rtc_slow_clk_src_freq[i], - "CPU clock rate is not equal to configured frequency (%d != %d)", - cpu_rate, rtc_rtc_slow_clk_src_freq[i]); + &calibrated_rate); + zassert_false(ret, "Failed to get RTC_SLOW calibrated clock rate"); + + int32_t diff = (int32_t)calibrated_rate - (int32_t)nominal_rate; + int32_t deviation_tenths = (diff * 1000) / (int32_t)nominal_rate; + + TC_PRINT("Nominal: %d Hz, Calibrated: %d Hz (deviation: %d.%d%%)\n", nominal_rate, + calibrated_rate, deviation_tenths / 10, + (deviation_tenths < 0 ? -deviation_tenths : deviation_tenths) % 10); } }