Update pico_sleep examples

Adds examples that sleep via an alarm or via an AON timer
Adds dormant examples that wake on an AON timer or GPIO
Fixed to work for RP2040 and RP2350
pull/48/head
Peter Harper 2024-08-08 14:01:32 +01:00
rodzic 9930bb057b
commit f74bd50af7
9 zmienionych plików z 285 dodań i 127 usunięć

4
sleep/CMakeLists.txt 100644 → 100755
Wyświetl plik

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

20
sleep/hello_dormant/CMakeLists.txt 100644 → 100755
Wyświetl plik

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

Wyświetl plik

@ -1,36 +0,0 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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;
}

Wyświetl plik

@ -0,0 +1,84 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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_aon_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_lpsc();
#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;
}

Wyświetl plik

@ -0,0 +1,41 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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;
}

22
sleep/hello_sleep/CMakeLists.txt 100644 → 100755
Wyświetl plik

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

Wyświetl plik

@ -1,77 +0,0 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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;
}

Wyświetl plik

@ -0,0 +1,58 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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();
int alarm_id = -1;
sleep_goto_sleep_for(10000, &alarm_sleep_callback, &alarm_id);
if (alarm_id >= 0) {
// 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;
}

Wyświetl plik

@ -0,0 +1,70 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#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_aon_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;
}