From bcff0549fc9084d6d3eeaf190cf7cc2471fef19e Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Fri, 5 Sep 2025 15:56:01 +0100 Subject: [PATCH] Implement low_power_sleep_until_irq Add to hello_sleep_gpio test using chars_available_callback --- src/rp2_common/pico_low_power/low_power.c | 20 ++++++++++++++++++++ test/hello_sleep/hello_sleep_gpio.c | 16 ++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/rp2_common/pico_low_power/low_power.c b/src/rp2_common/pico_low_power/low_power.c index db684c2a..d12e02fe 100644 --- a/src/rp2_common/pico_low_power/low_power.c +++ b/src/rp2_common/pico_low_power/low_power.c @@ -182,6 +182,26 @@ static void restore_other_interrupts(void) { } } +int low_power_sleep_until_irq(const clock_dest_set_t *keep_enabled) { + clock_dest_set_t local_keep_enabled; + replace_null_enable_values(keep_enabled, &local_keep_enabled); + + add_stdio_clocks(&local_keep_enabled); + + prepare_for_clock_gating(); + // gate clocks + clock_gate_sleep_en(&local_keep_enabled); + + low_power_enable_processor_deep_sleep(); + // Go to sleep until any event happens + __wfi(); + low_power_disable_processor_deep_sleep(); + + post_clock_gating(); + + return 0; +} + // only the deep_sleep variant of this, as DORMANT cannot wake from TIMER int low_power_sleep_until_timer(timer_hw_t *timer, absolute_time_t until, const clock_dest_set_t *keep_enabled, bool exclusive) { diff --git a/test/hello_sleep/hello_sleep_gpio.c b/test/hello_sleep/hello_sleep_gpio.c index 0a925cee..f2789f61 100644 --- a/test/hello_sleep/hello_sleep_gpio.c +++ b/test/hello_sleep/hello_sleep_gpio.c @@ -24,6 +24,13 @@ bool repeater(repeating_timer_t *timer) { return true; } +void chars_available_callback(__unused void *param) { + char buf[16] = {0}; + while (stdio_get_until(buf, sizeof(buf), make_timeout_time_us(10)) > 0) { + printf("Chars available callback: %s\n", buf); + } +} + #if HAS_POWMAN_TIMER static bool came_from_pstate = false; static char powman_last_pwrup[100]; @@ -61,6 +68,9 @@ int main() { repeating_timer_t repeat; add_repeating_timer_ms(500, repeater, NULL, &repeat); + // test stdio_set_chars_available_callback + stdio_set_chars_available_callback(chars_available_callback, NULL); + #if HAS_POWMAN_TIMER if (came_from_pstate) { printf("Came from powerup %s with (%s) memory kept on - skipping to end\n", powman_last_pwrup, powman_last_pstate); @@ -96,6 +106,12 @@ int main() { printf("Doing %d second pause to prove timer running\n", SLEEP_TIME_S); busy_wait_ms(SLEEP_TIME_MS); + printf("Going to sleep until any wakeup (expecting stdin characters)\n"); + + low_power_sleep_until_irq(NULL); + printf("Doing %d second pause to prove timer running\n", SLEEP_TIME_S); + busy_wait_ms(SLEEP_TIME_MS); + // todo, ah; we should start the aon timer; still have to decide what to do about keeping them in sync start_time = get_absolute_time(); us_to_timespec(start_time, &ts);