Skip to content

Commit feff243

Browse files
committed
Add RTC deep sleep alarm support
1 parent 24041f3 commit feff243

File tree

7 files changed

+49
-22
lines changed

7 files changed

+49
-22
lines changed

locale/circuitpython.pot

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,6 @@ msgstr ""
611611
msgid "Can't set CCCD on local Characteristic"
612612
msgstr ""
613613

614-
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c
615-
msgid "Cannot alarm from RTC in deep sleep"
616-
msgstr ""
617-
618614
#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c
619615
#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c
620616
msgid "Cannot change USB devices now"

ports/raspberrypi/common-hal/alarm/SleepMemory.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void alarm_sleep_memory_reset(void) {
4040
}
4141

4242
uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) {
43-
return 0;//sizeof(_sleep_mem);
43+
return 0;// sizeof(_sleep_mem);
4444
}
4545

4646
bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t *values, uint32_t len) {

ports/raspberrypi/common-hal/alarm/__init__.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,31 @@
5858
// Not used elsewhere in the SDK for now, keep an eye on it
5959
#define RP_WKUP_SCRATCH_REG 0
6060

61-
// Turn off nonvolatile Busio and other wake-only peripherals
61+
// Light sleep turns off nonvolatile Busio and other wake-only peripherals
6262
// TODO: this only saves about 2mA right now, expand with other non-essentials
6363
const uint32_t RP_LIGHTSLEEP_EN0_MASK = ~(
64-
CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS &
65-
CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS &
66-
CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS &
67-
CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS &
68-
CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS &
69-
CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS &
70-
CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS &
71-
CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS &
72-
CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS &
73-
CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS &
64+
CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS |
65+
CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS |
66+
CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS |
67+
CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS |
68+
CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS |
69+
CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS |
70+
CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS |
71+
CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS |
72+
CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS |
73+
CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS |
7474
CLOCKS_SLEEP_EN0_CLK_ADC_ADC_BITS
7575
);
76-
7776
// This bank has the USB clocks in it, leave it for now
7877
const uint32_t RP_LIGHTSLEEP_EN1_MASK = CLOCKS_SLEEP_EN1_RESET;
7978

79+
// Light sleeps used for TimeAlarm deep sleep turn off almost everything
80+
const uint32_t RP_LIGHTSLEEP_EN0_MASK_HARSH = (
81+
CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS |
82+
CLOCKS_SLEEP_EN0_CLK_SYS_PADS_BITS
83+
);
84+
const uint32_t RP_LIGHTSLEEP_EN1_MASK_HARSH = 0x0;
85+
8086
STATIC void prepare_for_dormant_xosc(void);
8187

8288
// Singleton instance of SleepMemory.
@@ -144,7 +150,6 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) {
144150

145151
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
146152
_setup_sleep_alarms(false, n_alarms, alarms);
147-
// alarm_pin_pinalarm_light_reset();
148153

149154
mp_obj_t wake_alarm = mp_const_none;
150155

@@ -173,7 +178,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
173178
// Prune the clock for sleep
174179
clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK;
175180
clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK;
176-
// port_idle_until_interrupt();
177181

178182
// Enable System Control Block (SCB) deep sleep
179183
uint save = scb_hw->scr;
@@ -195,8 +199,21 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
195199
}
196200

197201
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
198-
prepare_for_dormant_xosc();
199-
xosc_dormant();
202+
bool timealarm_set = alarm_time_timealarm_is_set();
203+
204+
// If there's a timealarm, just enter a very deep light sleep
205+
if (timealarm_set) {
206+
// Prune the clock for sleep
207+
clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK_HARSH;
208+
clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK_HARSH;
209+
// Enable System Control Block (SCB) deep sleep
210+
uint save = scb_hw->scr;
211+
scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS;
212+
__wfi();
213+
} else {
214+
prepare_for_dormant_xosc();
215+
xosc_dormant();
216+
}
200217
// // TODO: support ROSC when available in SDK
201218
// rosc_set_dormant();
202219

ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
STATIC bool woke_up;
3939
STATIC uint64_t alarm_triggered_pins; // 36 actual pins
4040
STATIC uint64_t alarm_reserved_pins; // 36 actual pins
41+
STATIC bool _pinalarm_set = false;
4142

4243
#define GPIO_IRQ_ALL_EVENTS 0x15u
4344

@@ -152,6 +153,12 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
152153
if (deep_sleep) {
153154
gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true);
154155
}
156+
157+
_pinalarm_set = true;
155158
}
156159
}
157160
}
161+
162+
bool alarm_pin_pinalarm_is_set(void) {
163+
return _pinalarm_set;
164+
}

ports/raspberrypi/common-hal/alarm/pin/PinAlarm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ void alarm_pin_pinalarm_reset(void);
4242
void alarm_pin_pinalarm_light_reset(void);
4343
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4444
bool alarm_pin_pinalarm_woke_this_cycle(void);
45+
bool alarm_pin_pinalarm_is_set(void);

ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "hardware/rtc.h"
3636

3737
STATIC bool woke_up = false;
38+
STATIC bool _timealarm_set = false;
3839

3940
void timer_callback(void) {
4041
woke_up = true;
@@ -92,7 +93,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
9293
return;
9394
}
9495
if (deep_sleep) {
95-
mp_raise_ValueError(translate("Cannot alarm from RTC in deep sleep"));
96+
_timealarm_set = true;
9697
}
9798

9899
// Compute how long to actually sleep, considering the time now.
@@ -123,3 +124,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
123124

124125
woke_up = false;
125126
}
127+
128+
bool alarm_time_timealarm_is_set(void) {
129+
return _timealarm_set;
130+
}

ports/raspberrypi/common-hal/alarm/time/TimeAlarm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
3838
void alarm_time_timealarm_reset(void);
3939
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4040
bool alarm_time_timealarm_woke_this_cycle(void);
41+
bool alarm_time_timealarm_is_set(void);

0 commit comments

Comments
 (0)