Skip to content

Commit 35db8fc

Browse files
committed
Add a couple of simple powman examples
powman_timer: Repeatedly switches the device off for 5s powman_gpio: Repeatedly switches the device off until a GPIO goes high
1 parent 816a198 commit 35db8fc

File tree

9 files changed

+223
-0
lines changed

9 files changed

+223
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ add_subdirectory(otp)
7575
add_subdirectory(picoboard)
7676
add_subdirectory(pico_w)
7777
add_subdirectory(pio)
78+
add_subdirectory(powman)
7879
add_subdirectory(pwm)
7980
add_subdirectory(reset)
8081
add_subdirectory(rtc)

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,13 @@ App|Description
294294
[ws2812](pio/ws2812) | Examples of driving WS2812 addressable RGB LEDs.
295295
[addition](pio/addition) | Add two integers together using PIO. Only around 8 billion times slower than Cortex-M0+.
296296

297+
### POWMAN
298+
299+
App|Description
300+
---|---
301+
[powman_timer](powman/powman_timer) | Example demonstrating how to turn the device off and back on at a certain time
302+
[powman_gpio](powman/powman_gpio) | Example demonstrating how to turn the device off and back on when a GPIO goes high
303+
297304
### PWM
298305

299306
App|Description

powman/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
add_library(powman_example INTERFACE)
2+
target_sources(powman_example INTERFACE
3+
${CMAKE_CURRENT_LIST_DIR}/powman_example.c
4+
)
5+
target_include_directories(powman_example INTERFACE
6+
${CMAKE_CURRENT_LIST_DIR}
7+
)
8+
target_link_libraries(powman_example INTERFACE
9+
hardware_powman
10+
hardware_gpio
11+
)
12+
13+
add_subdirectory(powman_timer)
14+
add_subdirectory(powman_gpio)

powman/powman_example.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include <stdio.h>
2+
#include <inttypes.h>
3+
4+
#include "pico/stdio.h"
5+
#include "pico/sync.h"
6+
#include "hardware/gpio.h"
7+
#include "hardware/powman.h"
8+
#include "powman_example.h"
9+
10+
static powman_power_state off_state;
11+
static powman_power_state on_state;
12+
13+
// Initialise everything
14+
void powman_example_init(uint64_t abs_time_ms) {
15+
// start powman and set the time
16+
powman_timer_start();
17+
powman_timer_set_ms(abs_time_ms);
18+
19+
// Allow power down when debugger connected
20+
powman_set_debug_power_request_ignored(true);
21+
22+
// Power states
23+
powman_power_state P1_7 = POWMAN_POWER_STATE_NONE;
24+
25+
powman_power_state P0_3 = POWMAN_POWER_STATE_NONE;
26+
P0_3 = powman_power_state_with_domain_on(P0_3, POWMAN_POWER_DOMAIN_SWITCHED_CORE);
27+
P0_3 = powman_power_state_with_domain_on(P0_3, POWMAN_POWER_DOMAIN_XIP_CACHE);
28+
29+
off_state = P1_7;
30+
on_state = P0_3;
31+
}
32+
33+
// Initiate power off
34+
static int powman_example_off(void) {
35+
// Get ready to power off
36+
stdio_flush();
37+
38+
// Set power states
39+
bool valid_state = powman_configure_wakeup_state(off_state, on_state);
40+
if (!valid_state) {
41+
return PICO_ERROR_INVALID_STATE;
42+
}
43+
44+
// reboot to main
45+
powman_hw->boot[0] = 0;
46+
powman_hw->boot[1] = 0;
47+
powman_hw->boot[2] = 0;
48+
powman_hw->boot[3] = 0;
49+
50+
// Switch to required power state
51+
int rc = powman_set_power_state(off_state);
52+
if (rc != PICO_OK) {
53+
return rc;
54+
}
55+
56+
// Power down
57+
while (true) __wfi();
58+
}
59+
60+
// Power off until a gpio goes high
61+
int powman_example_off_until_gpio_high(int gpio) {
62+
gpio_init(gpio);
63+
gpio_set_dir(gpio, false);
64+
if (gpio_get(gpio)) {
65+
printf("Waiting for gpio %d to go low\n", gpio);
66+
while(gpio_get(gpio)) {
67+
sleep_ms(100);
68+
}
69+
}
70+
printf("Powering off until GPIO %d goes high\n", gpio);
71+
powman_enable_gpio_wakeup(0, gpio, false, true);
72+
return powman_example_off();
73+
}
74+
75+
// Power off until an absolute time
76+
int powman_example_off_until_time(uint64_t abs_time_ms) {
77+
// Start powman timer and turn off
78+
printf("Powering off for %"PRIu64"ms\n", powman_timer_get_ms() - abs_time_ms);
79+
powman_enable_alarm_wakeup_at_ms(abs_time_ms);
80+
return powman_example_off();
81+
}
82+
83+
// Power off for a number of milliseconds
84+
int powman_example_off_for_ms(uint64_t duration_ms) {
85+
printf("Powering off for %"PRIu64"ms\n", duration_ms);
86+
uint64_t ms = powman_timer_get_ms();
87+
return powman_example_off_until_time(ms + duration_ms);
88+
}

powman/powman_example.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef POWMAN_EXAMPLE_H
2+
#define POWMAN_EXAMPLE_H
3+
4+
void powman_example_init(uint64_t abs_time_ms);
5+
int powman_example_off_until_gpio_high(int gpio);
6+
int powman_example_off_until_time(uint64_t abs_time_ms);
7+
int powman_example_off_for_ms(uint64_t duration_ms);
8+
9+
#endif

powman/powman_gpio/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_executable(powman_gpio
2+
powman_gpio.c
3+
)
4+
target_link_libraries(powman_gpio
5+
pico_stdlib
6+
powman_example)
7+
8+
# create map/bin/hex file etc.
9+
pico_add_extra_outputs(powman_gpio)
10+
11+
# add url via pico_set_program_url
12+
example_auto_set_url(powman_gpio)

powman/powman_gpio/powman_gpio.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include <stdio.h>
8+
#include "pico/stdlib.h"
9+
#include "hardware/powman.h"
10+
#include "powman_example.h"
11+
12+
#ifndef WAKEUP_GPIO
13+
#define WAKEUP_GPIO 15
14+
#endif
15+
16+
// How long to wait
17+
#define PAUSE_TIME_MS 5000
18+
19+
// Got to sleep and wakeup when a GPIO goes high
20+
// The example will repeatedly wait until GPIO 15 is low then switch off until GPIO 15 goes high
21+
// To test this you can connect the GPIO to ground and then 3V3(OUT)
22+
// The debugger will appear to be unresponsive while the device is off
23+
int main() {
24+
stdio_init_all();
25+
26+
// Initialise the example
27+
powman_example_init(1704067200000);
28+
29+
// Scratch register survives power down
30+
printf("Wake up, test run: %u\n", powman_hw->scratch[0]++);
31+
32+
// Stay awake for a few seconds
33+
printf("Awake for %dms\n", PAUSE_TIME_MS);
34+
sleep_ms(PAUSE_TIME_MS);
35+
36+
// power off
37+
int rc = powman_example_off_until_gpio_high(WAKEUP_GPIO);
38+
hard_assert(rc == PICO_OK);
39+
40+
hard_assert(false); // should never get here!
41+
return 0;
42+
}

powman/powman_timer/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_executable(powman_timer
2+
powman_timer.c
3+
)
4+
target_link_libraries(powman_timer PRIVATE
5+
pico_stdlib
6+
powman_example
7+
)
8+
9+
# create map/bin/hex file etc.
10+
pico_add_extra_outputs(powman_timer)
11+
12+
# add url via pico_set_program_url
13+
example_auto_set_url(powman_timer)

powman/powman_timer/powman_timer.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#include <stdio.h>
8+
#include "pico/stdlib.h"
9+
#include "hardware/powman.h"
10+
#include "powman_example.h"
11+
12+
// How long to wait
13+
#define PAUSE_TIME_MS 5000
14+
15+
// Got to sleep and wakeup after 5 seconds
16+
// The example will repeatedly wait 5 seconds then switch off for 5 seconds
17+
// The debugger will appear to be unresponsive while the device is off
18+
int main() {
19+
stdio_init_all();
20+
21+
// Initialise the example
22+
powman_example_init(1704067200000);
23+
24+
// Scratch register survives power down
25+
printf("Wake up, test run: %u\n", powman_hw->scratch[0]++);
26+
27+
// Stay awake for a few seconds
28+
printf("Awake for %dms\n", PAUSE_TIME_MS);
29+
sleep_ms(PAUSE_TIME_MS);
30+
31+
// power off
32+
int rc = powman_example_off_for_ms(PAUSE_TIME_MS);
33+
hard_assert(rc == PICO_OK);
34+
35+
hard_assert(false); // should never get here!
36+
return 0;
37+
}

0 commit comments

Comments
 (0)