diff --git a/sleep/CMakeLists.txt b/sleep/CMakeLists.txt old mode 100644 new mode 100755 index 30c19c4..a45f913 --- a/sleep/CMakeLists.txt +++ b/sleep/CMakeLists.txt @@ -1,4 +1,4 @@ if (NOT PICO_NO_HARDWARE) - add_subdirectory_exclude_platforms(hello_dormant "rp2350.*") - add_subdirectory_exclude_platforms(hello_sleep "rp2350.*") + add_subdirectory(hello_dormant) + add_subdirectory(hello_sleep) endif () diff --git a/sleep/hello_dormant/CMakeLists.txt b/sleep/hello_dormant/CMakeLists.txt old mode 100644 new mode 100755 index afd5a0d..1682b86 --- a/sleep/hello_dormant/CMakeLists.txt +++ b/sleep/hello_dormant/CMakeLists.txt @@ -1,8 +1,16 @@ -add_executable(hello_dormant - hello_dormant.c +add_executable(hello_dormant_gpio + hello_dormant_gpio.c ) +target_link_libraries(hello_dormant_gpio + pico_stdlib + hardware_sleep) +pico_add_extra_outputs(hello_dormant_gpio) -target_link_libraries(hello_dormant pico_stdlib hardware_sleep) - -# create map/bin/hex file etc. -pico_add_extra_outputs(hello_dormant) \ No newline at end of file +add_executable(hello_dormant_aon + hello_dormant_aon.c + ) +target_link_libraries(hello_dormant_aon + pico_stdlib + hardware_sleep + ) +pico_add_extra_outputs(hello_dormant_aon) diff --git a/sleep/hello_dormant/hello_dormant.c b/sleep/hello_dormant/hello_dormant.c deleted file mode 100644 index 4d33ff8..0000000 --- a/sleep/hello_dormant/hello_dormant.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "pico/stdlib.h" -#include "pico/sleep.h" - -int main() { - stdio_init_all(); - printf("Hello Dormant!\n"); - - printf("Switching to XOSC\n"); - uart_default_tx_wait_blocking(); - - // UART will be reconfigured by sleep_run_from_xosc - sleep_run_from_xosc(); - - printf("Running from XOSC\n"); - uart_default_tx_wait_blocking(); - - printf("XOSC going dormant\n"); - uart_default_tx_wait_blocking(); - - // Go to sleep until we see a high edge on GPIO 10 - sleep_goto_dormant_until_edge_high(10); - - uint i = 0; - while (1) { - printf("XOSC awake %d\n", i++); - } - - return 0; -} \ No newline at end of file diff --git a/sleep/hello_dormant/hello_dormant_aon.c b/sleep/hello_dormant/hello_dormant_aon.c new file mode 100644 index 0000000..481af1b --- /dev/null +++ b/sleep/hello_dormant/hello_dormant_aon.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "pico/stdlib.h" +#include "pico/sleep.h" + +// For clock_configure_gpin +#ifdef PICO_RP2040 +#include "hardware/clocks.h" +#endif + +// For RP2040 this example needs an external clock fed into the GP20 +// Note: Only GP20 and GP22 can be used for clock input, See the GPIO function table in the datasheet. +// You can use another Pico to generate this. See the clocks/hello_gpout example for more details. +// rp2040: clock_gpio_init(21, CLOCKS_CLK_GPOUT3_CTRL_AUXSRC_VALUE_CLK_RTC, 1); // 46875Hz can only export a clock on gpios 21,23,24,25 and only 21 is exposed by Pico +// RP2350 has an LPOSC it can use, so doesn't need this +#define EXTERNAL_CLOCK_INPUT_PIN 20 +#define RTC_FREQ_HZ 46875 + +static void sleep_callback(void) { + printf("AON timer woke us up\n"); +} + +static void aon_sleep(void) { + + // Get the time from the aon timer and set our alarm time + struct timespec ts; + aon_timer_get_time(&ts); + ts.tv_sec += 10; + + printf("Sleeping for 10 seconds\n"); + uart_default_tx_wait_blocking(); + +#if PICO_RP2040 + // The RTC must be run from an external source, since the dormant source will be inactive + clock_configure_gpin(clk_rtc, EXTERNAL_CLOCK_INPUT_PIN, RTC_FREQ_HZ, 46875); +#endif + + // Go to sleep for 10 seconds, with RTC running off GP20 + // The external clock is the RTC of another pico being fed to GP20 + sleep_goto_dormant_until(&ts, &sleep_callback); +} + +int main() { + + stdio_init_all(); + printf("Hello Dormant AON Timer!\n"); + + struct timespec ts = { .tv_sec = 1723124088, .tv_nsec = 0 }; + aon_timer_start(&ts); + + while(true) { + printf("Awake for 10s\n"); + sleep_ms(10000); + + uart_default_tx_wait_blocking(); + + // Set the crystal oscillator as the dormant clock source, UART will be reconfigured from here + // This is necessary before sending the pico dormant +#if PICO_RP2040 + printf("Switching to XOSC\n"); + sleep_run_from_xosc(); +#else + printf("Switching to LPSC\n"); + sleep_run_from_lposc(); +#endif + + uart_default_tx_wait_blocking(); + + printf("Going dormant\n"); + uart_default_tx_wait_blocking(); + + // Go to sleep until the RTC interrupt is generated after 10 seconds + aon_sleep(); + + // Re-enabling clock sources and generators. + sleep_power_up(); + } + return 0; +} diff --git a/sleep/hello_dormant/hello_dormant_gpio.c b/sleep/hello_dormant/hello_dormant_gpio.c new file mode 100755 index 0000000..fd111ae --- /dev/null +++ b/sleep/hello_dormant/hello_dormant_gpio.c @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "pico/stdlib.h" +#include "pico/sleep.h" + +#define WAKE_GPIO 10 + +int main() { + stdio_init_all(); + printf("Hello Dormant GPIO!\n"); + + printf("Test starting in 10s\n"); + sleep_ms(10000); + + while(true) { + printf("Switching to XOSC\n"); + uart_default_tx_wait_blocking(); + + // Set the crystal oscillator as the dormant clock source, UART will be reconfigured from here + // This is necessary before sending the pico into dormancy + sleep_run_from_xosc(); + + printf("Going dormant until GPIO %d goes edge high\n", WAKE_GPIO); + uart_default_tx_wait_blocking(); + + // Go to sleep until we see a high edge on GPIO 10 + sleep_goto_dormant_until_edge_high(WAKE_GPIO); + + // Re-enabling clock sources and generators. + sleep_power_up(); + printf("Now awake for 10s\n"); + sleep_ms(1000 * 10); + } + + return 0; +} \ No newline at end of file diff --git a/sleep/hello_sleep/CMakeLists.txt b/sleep/hello_sleep/CMakeLists.txt old mode 100644 new mode 100755 index a45f6ac..dcc63c7 --- a/sleep/hello_sleep/CMakeLists.txt +++ b/sleep/hello_sleep/CMakeLists.txt @@ -1,8 +1,18 @@ -add_executable(hello_sleep - hello_sleep.c +add_executable(hello_sleep_alarm + hello_sleep_alarm.c ) +target_link_libraries(hello_sleep_alarm + pico_stdlib + hardware_sleep + ) +pico_add_extra_outputs(hello_sleep_alarm) -target_link_libraries(hello_sleep pico_stdlib hardware_sleep) - -# create map/bin/hex file etc. -pico_add_extra_outputs(hello_sleep) \ No newline at end of file +add_executable(hello_sleep_aon + hello_sleep_aon.c + ) +target_link_libraries(hello_sleep_aon + pico_stdlib + hardware_sleep + pico_aon_timer + ) +pico_add_extra_outputs(hello_sleep_aon) diff --git a/sleep/hello_sleep/hello_sleep.c b/sleep/hello_sleep/hello_sleep.c deleted file mode 100644 index 7a8a48e..0000000 --- a/sleep/hello_sleep/hello_sleep.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "pico/stdlib.h" -#include "pico/sleep.h" - -#include "hardware/rtc.h" - -static bool awake; - -static void sleep_callback(void) { - printf("RTC woke us up\n"); - awake = true; -} - -static void rtc_sleep(void) { - // Start on Friday 5th of June 2020 15:45:00 - datetime_t t = { - .year = 2020, - .month = 06, - .day = 05, - .dotw = 5, // 0 is Sunday, so 5 is Friday - .hour = 15, - .min = 45, - .sec = 00 - }; - - // Alarm 10 seconds later - datetime_t t_alarm = { - .year = 2020, - .month = 06, - .day = 05, - .dotw = 5, // 0 is Sunday, so 5 is Friday - .hour = 15, - .min = 45, - .sec = 10 - }; - - // Start the RTC - rtc_init(); - rtc_set_datetime(&t); - - printf("Sleeping for 10 seconds\n"); - uart_default_tx_wait_blocking(); - - sleep_goto_sleep_until(&t_alarm, &sleep_callback); -} - -int main() { - stdio_init_all(); - printf("Hello Sleep!\n"); - - printf("Switching to XOSC\n"); - - // Wait for the fifo to be drained so we get reliable output - uart_default_tx_wait_blocking(); - - // UART will be reconfigured by sleep_run_from_xosc - sleep_run_from_xosc(); - - printf("Switched to XOSC\n"); - - awake = false; - - rtc_sleep(); - - // Make sure we don't wake - while (!awake) { - printf("Should be sleeping\n"); - } - - return 0; -} diff --git a/sleep/hello_sleep/hello_sleep_alarm.c b/sleep/hello_sleep/hello_sleep_alarm.c new file mode 100755 index 0000000..205bf35 --- /dev/null +++ b/sleep/hello_sleep/hello_sleep_alarm.c @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "pico/stdlib.h" +#include "pico/sleep.h" + +static bool awake; + +static void alarm_sleep_callback(uint alarm_id) { + printf("alarm woke us up\n"); + uart_default_tx_wait_blocking(); + awake = true; + hardware_alarm_set_callback(alarm_id, NULL); + hardware_alarm_unclaim(alarm_id); +} + +int main() { + + stdio_init_all(); + printf("Hello Alarm Sleep!\n"); + + do { + printf("Awake for 10 seconds\n"); + sleep_ms(1000 * 10); + + printf("Switching to XOSC\n"); + + // Wait for the fifo to be drained so we get reliable output + uart_default_tx_wait_blocking(); + + // Set the crystal oscillator as the dormant clock source, UART will be reconfigured from here + // This is only really necessary before sending the pico dormant but running from xosc while asleep saves power + sleep_run_from_xosc(); + awake = false; + + // Go to sleep until the alarm interrupt is generated after 10 seconds + printf("Sleeping for 10 seconds\n"); + uart_default_tx_wait_blocking(); + + if (sleep_goto_sleep_for(10000, &alarm_sleep_callback)) { + // Make sure we don't wake + while (!awake) { + printf("Should be sleeping\n"); + } + } + + // Re-enabling clock sources and generators. + sleep_power_up(); + } while(true); + + return 0; +} diff --git a/sleep/hello_sleep/hello_sleep_aon.c b/sleep/hello_sleep/hello_sleep_aon.c new file mode 100644 index 0000000..256dc8e --- /dev/null +++ b/sleep/hello_sleep/hello_sleep_aon.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "pico/stdlib.h" +#include "pico/sleep.h" +#include "pico/aon_timer.h" + +static bool awake; + +static void sleep_callback(void) { + printf("AON Timer woke us up\n"); + uart_default_tx_wait_blocking(); + awake = true; +} + +static void aon_sleep(void) { + + // Get the time from the aon timer and set our alarm time + struct timespec ts; + aon_timer_get_time(&ts); + ts.tv_sec += 10; + + printf("Sleeping for 10 seconds\n"); + uart_default_tx_wait_blocking(); + + // Go to sleep + sleep_goto_sleep_until(&ts, &sleep_callback); +} + +int main() { + + stdio_init_all(); + + printf("Hello AON timer Sleep!\n"); + + struct timespec ts = { .tv_sec = 1723124088, .tv_nsec = 0 }; + aon_timer_start(&ts); + + do { + printf("Awake for 10 seconds\n"); + sleep_ms(1000 * 10); + + printf("Switching to XOSC\n"); + + // Wait for the fifo to be drained so we get reliable output + uart_default_tx_wait_blocking(); + + // Set the crystal oscillator as the dormant clock source, UART will be reconfigured from here + // This is only really necessary before sending the pico into dormancy but running from xosc while asleep saves power + sleep_run_from_xosc(); + + // Go to sleep until an interrupt is generated after 10 seconds + awake = false; + aon_sleep(); + + // Make sure we don't wake + while (!awake) { + printf("Should be sleeping\n"); + } + + // Re-enabling clock sources and generators. + sleep_power_up(); + } while(true); + + return 0; +}