Merge branch 'feat/lp_core_pre_calc_timer' into 'master'

change(lp_core): changed wakeup time calc to use a precomputed tick value

Closes IDF-10552

See merge request espressif/esp-idf!32283
This commit is contained in:
Marius Vikhammer 2024-07-26 15:29:33 +08:00
commit 8b73c8616d
6 changed files with 42 additions and 6 deletions

View File

@ -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.

View File

@ -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);

View File

@ -29,10 +29,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

View File

@ -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
*

View File

@ -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;
/**

View File

@ -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