From dccd6b0259b091dcfcddec5a47b178207b20a3c2 Mon Sep 17 00:00:00 2001 From: Marius Vikhammer Date: Fri, 19 Jul 2024 15:24:22 +0800 Subject: [PATCH] change(lp_core): changed wakeup time calc to use a precomputed tick value Previously we would calculate the wakeup ticks upon every wakeup using the lp-timer clock frequency, but this caused the binary to pull in software division functions, increasing the binary size. This value is now precalculated by the hp-core when we configure the ULP. This saves about 1k bytes. --- components/ulp/Kconfig | 2 +- components/ulp/lp_core/lp_core.c | 1 + .../ulp/lp_core/lp_core/lp_core_startup.c | 6 +++--- .../include/ulp_lp_core_lp_timer_shared.h | 21 +++++++++++++++++++ .../include/ulp_lp_core_memory_shared.h | 3 ++- .../shared/ulp_lp_core_lp_timer_shared.c | 15 ++++++++++++- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index 94167bd5df..d1092b9a76 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -75,7 +75,7 @@ menu "Ultra Low Power (ULP) Co-processor" config ULP_SHARED_MEM depends on ULP_COPROC_TYPE_LP_CORE hex - default 0x8 + default 0x10 help Size of the shared memory defined in ulp_lp_core_memory_shared.c. Size should be kept in-sync with the size of the struct defined there. diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index e578e077ac..0af75f33c8 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -120,6 +120,7 @@ esp_err_t ulp_lp_core_run(ulp_lp_core_cfg_t* cfg) ESP_LOGI(TAG, "LP timer specified as wakeup source, but no sleep duration set. ULP will only wake-up once unless it calls ulp_lp_core_lp_timer_set_wakeup_time()"); } shared_mem->sleep_duration_us = cfg->lp_timer_sleep_duration_us; + shared_mem->sleep_duration_ticks = ulp_lp_core_lp_timer_calculate_sleep_ticks(cfg->lp_timer_sleep_duration_us); /* Set first wakeup alarm */ ulp_lp_core_lp_timer_set_wakeup_time(cfg->lp_timer_sleep_duration_us); diff --git a/components/ulp/lp_core/lp_core/lp_core_startup.c b/components/ulp/lp_core/lp_core/lp_core_startup.c index 4d87b07fd1..b43f234df1 100644 --- a/components/ulp/lp_core/lp_core/lp_core_startup.c +++ b/components/ulp/lp_core/lp_core/lp_core_startup.c @@ -20,10 +20,10 @@ void lp_core_startup() ulp_lp_core_memory_shared_cfg_t* shared_mem = ulp_lp_core_memory_shared_cfg_get(); #if SOC_LP_TIMER_SUPPORTED - uint64_t sleep_duration = shared_mem->sleep_duration_us; + uint64_t sleep_duration_ticks = shared_mem->sleep_duration_ticks; - if (sleep_duration) { - ulp_lp_core_lp_timer_set_wakeup_time(sleep_duration); + if (sleep_duration_ticks) { + ulp_lp_core_lp_timer_set_wakeup_ticks(sleep_duration_ticks); } #endif //SOC_LP_TIMER_SUPPORTED diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h index dda58dc843..6743ebd603 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_lp_timer_shared.h @@ -31,6 +31,27 @@ uint64_t ulp_lp_core_lp_timer_get_cycle_count(void); */ void ulp_lp_core_lp_timer_set_wakeup_time(uint64_t sleep_duration_us); +/** + * @brief Set the next wakeup alarm in LP timer ticks + * + * @note This only sets the alarm for a single wakeup. For periodic wakeups you will + * have to call this function again after each wakeup to configure the next time. + * + * @note If ulp_lp_core_cfg_t.lp_timer_sleep_duration_us is set the ulp will automatically set + * the next wakeup time after returning from main and override this value. + * + * @param sleep_duration_ticks + */ +void ulp_lp_core_lp_timer_set_wakeup_ticks(uint64_t sleep_duration_ticks); + +/** + * @brief Converts from sleep duration in microseconds to LP timer ticks + * + * @param sleep_duration_us Sleep duration in microseconds + * @return uint64_t Number of LP timer ticks to sleep for + */ +uint64_t ulp_lp_core_lp_timer_calculate_sleep_ticks(uint64_t sleep_duration_us); + /** * @brief Disables the lp timer alarm and clears any pending alarm interrupts * diff --git a/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h b/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h index c76f4d8e2b..890b1ddca9 100644 --- a/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h +++ b/components/ulp/lp_core/shared/include/ulp_lp_core_memory_shared.h @@ -12,7 +12,8 @@ extern "C" { #endif typedef struct { - uint64_t sleep_duration_us; /* Configured sleep duration for periodic wakeup, if set the ulp will automatically schedule the next wakeup */ + uint64_t sleep_duration_us; /* Configured sleep duration for periodic wakeup, if set the ulp will automatically schedule the next wakeup */ + uint64_t sleep_duration_ticks; /* Configured sleep duration, in LP-timer clock ticks, if set it allows us to skip doing integer division when configuring the timer */ } ulp_lp_core_memory_shared_cfg_t; /** diff --git a/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c b/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c index d3947b338b..b39e5ba0f2 100644 --- a/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c +++ b/components/ulp/lp_core/shared/ulp_lp_core_lp_timer_shared.c @@ -42,7 +42,15 @@ uint64_t ulp_lp_core_lp_timer_get_cycle_count(void) void ulp_lp_core_lp_timer_set_wakeup_time(uint64_t sleep_duration_us) { uint64_t cycle_cnt = ulp_lp_core_lp_timer_get_cycle_count(); - uint64_t alarm_target = cycle_cnt + sleep_duration_us * (1 << RTC_CLK_CAL_FRACT) / clk_ll_rtc_slow_load_cal(); + uint64_t alarm_target = cycle_cnt + ulp_lp_core_lp_timer_calculate_sleep_ticks(sleep_duration_us); + + lp_timer_hal_set_alarm_target(alarm_target); +} + +void ulp_lp_core_lp_timer_set_wakeup_ticks(uint64_t sleep_duration_ticks) +{ + uint64_t cycle_cnt = ulp_lp_core_lp_timer_get_cycle_count(); + uint64_t alarm_target = cycle_cnt + sleep_duration_ticks; lp_timer_hal_set_alarm_target(alarm_target); } @@ -53,4 +61,9 @@ void ulp_lp_core_lp_timer_disable(void) lp_timer_ll_clear_lp_alarm_intr_status(lp_timer_context.dev); } +uint64_t ulp_lp_core_lp_timer_calculate_sleep_ticks(uint64_t sleep_duration_us) +{ + return (sleep_duration_us * (1 << RTC_CLK_CAL_FRACT) / clk_ll_rtc_slow_load_cal()); +} + #endif //SOC_LP_TIMER_SUPPORTED