From d9cf06ba33fdce4cdfd74ad0f062251bad11fc51 Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Fri, 22 Aug 2025 17:49:54 +0100 Subject: [PATCH] Demonstrate non-exclusive sleep --- test/hello_sleep/hello_sleep.c | 36 +++++++++++++++++++++++------ test/hello_sleep/hello_sleep_gpio.c | 15 ++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/test/hello_sleep/hello_sleep.c b/test/hello_sleep/hello_sleep.c index d8715960..2a8f1404 100644 --- a/test/hello_sleep/hello_sleep.c +++ b/test/hello_sleep/hello_sleep.c @@ -18,9 +18,9 @@ bool repeater(repeating_timer_t *timer) { if (aon_timer_is_running()) { - printf(" Repeating timer at %dms (aon: %dms)\n", to_ms_since_boot(get_absolute_time()), to_ms_since_boot(aon_timer_get_absolute_time())); + printf(" Repeating timer %d at %dms (aon: %dms)\n", *(uint32_t*)timer->user_data, to_ms_since_boot(get_absolute_time()), to_ms_since_boot(aon_timer_get_absolute_time())); } else { - printf(" Repeating timer at %dms (aon: not running)\n", to_ms_since_boot(get_absolute_time())); + printf(" Repeating timer %d at %dms (aon: not running)\n", *(uint32_t*)timer->user_data, to_ms_since_boot(get_absolute_time())); } status_led_set_state(!status_led_get_state()); return true; @@ -56,24 +56,32 @@ int main() { stdio_init_all(); status_led_init(); printf("Hello Sleep!\n"); + + // use a repeating timer on the same TIMER instance; it should be disabled + // during exclusive sleep (todo not sure how it affects power!) + repeating_timer_t repeat; + uint32_t repeater_id = 0; + add_repeating_timer_ms(500, repeater, &repeater_id, &repeat); + #if !PICO_RP2040 // use a second repeating timer on the other TIMER instance; it should be gated // during our sleep (todo not sure how it affects power!) alarm_pool_t *alarm_pool = alarm_pool_create_on_timer_with_unused_hardware_alarm(timer1_hw, 4); - repeating_timer_t repeat; - alarm_pool_add_repeating_timer_ms(alarm_pool, 500, repeater, NULL, &repeat); + repeating_timer_t repeat2; + uint32_t repeater2_id = 1; + alarm_pool_add_repeating_timer_ms(alarm_pool, 500, repeater, &repeater2_id, &repeat2); if (came_from_pstate) { printf("Came from powerup %s with (%s) memory kept on - skipping to end\n", powman_last_pwrup, powman_last_pstate); goto post_pstate_timer; } - printf("Waiting %d seconds\n", SLEEP_TIME_S); // so we can see some repeat printfs - busy_wait_ms(SLEEP_TIME_MS); - pstate_bitset_t pstate; #endif + printf("Waiting %d seconds\n", SLEEP_TIME_S); // so we can see some repeat printfs + busy_wait_ms(SLEEP_TIME_MS); + absolute_time_t start_time; absolute_time_t wakeup_time; int64_t diff; @@ -94,6 +102,20 @@ int main() { printf("Doing %d second pause to prove timer running\n", SLEEP_TIME_S); busy_wait_ms(SLEEP_TIME_MS); + printf("Going to non-exclusive sleep for %d seconds via TIMER\n", SLEEP_TIME_S); + + start_time = get_absolute_time(); + wakeup_time = delayed_by_ms(start_time, SLEEP_TIME_MS); + low_power_sleep_until_timer(timer_hw, wakeup_time, NULL, false); + diff = absolute_time_diff_us(wakeup_time, get_absolute_time()); + printf("Woken up now @%dus since target\n", (int)diff); + if (diff < 0) { + printf("ERROR: Woke up too soon\n"); + return -1; + } + printf("Doing %d second pause to prove timer running\n", SLEEP_TIME_S); + busy_wait_ms(SLEEP_TIME_MS); + printf("Going DORMANT for %d seconds via AON TIMER\n", SLEEP_TIME_S); // todo, ah; we should start the aon timer; still have to decide what to do about keeping them in sync diff --git a/test/hello_sleep/hello_sleep_gpio.c b/test/hello_sleep/hello_sleep_gpio.c index b929855b..36daf350 100644 --- a/test/hello_sleep/hello_sleep_gpio.c +++ b/test/hello_sleep/hello_sleep_gpio.c @@ -81,6 +81,21 @@ int main() { printf("Doing %d second pause to prove timer running\n", SLEEP_TIME_S); busy_wait_ms(SLEEP_TIME_MS); + printf("Going to non-exclusive sleep until GPIO wakeup\n"); + + // need to keep the timer running + clock_dest_set_t keep_enabled = clock_dest_set_none(); +#if PICO_RP2040 + clock_dest_set_add(&keep_enabled, CLK_DEST_SYS_TIMER); +#else + clock_dest_set_add(&keep_enabled, CLK_DEST_SYS_TIMER0); + clock_dest_set_add(&keep_enabled, CLK_DEST_REF_TICKS); +#endif + + low_power_sleep_until_pin_state(PICO_DEFAULT_UART_RX_PIN, true, false, &keep_enabled, false); + 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);