Add RTC deep sleep alarm support
This commit is contained in:
parent
24041f34b0
commit
feff243e8f
|
@ -611,10 +611,6 @@ msgstr ""
|
|||
msgid "Can't set CCCD on local Characteristic"
|
||||
msgstr ""
|
||||
|
||||
#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c
|
||||
msgid "Cannot alarm from RTC in deep sleep"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c
|
||||
#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c
|
||||
msgid "Cannot change USB devices now"
|
||||
|
|
|
@ -40,7 +40,7 @@ void alarm_sleep_memory_reset(void) {
|
|||
}
|
||||
|
||||
uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) {
|
||||
return 0;//sizeof(_sleep_mem);
|
||||
return 0;// sizeof(_sleep_mem);
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -58,25 +58,31 @@
|
|||
// Not used elsewhere in the SDK for now, keep an eye on it
|
||||
#define RP_WKUP_SCRATCH_REG 0
|
||||
|
||||
// Turn off nonvolatile Busio and other wake-only peripherals
|
||||
// Light sleep turns off nonvolatile Busio and other wake-only peripherals
|
||||
// TODO: this only saves about 2mA right now, expand with other non-essentials
|
||||
const uint32_t RP_LIGHTSLEEP_EN0_MASK = ~(
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS &
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_ADC_ADC_BITS
|
||||
);
|
||||
|
||||
// This bank has the USB clocks in it, leave it for now
|
||||
const uint32_t RP_LIGHTSLEEP_EN1_MASK = CLOCKS_SLEEP_EN1_RESET;
|
||||
|
||||
// Light sleeps used for TimeAlarm deep sleep turn off almost everything
|
||||
const uint32_t RP_LIGHTSLEEP_EN0_MASK_HARSH = (
|
||||
CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS |
|
||||
CLOCKS_SLEEP_EN0_CLK_SYS_PADS_BITS
|
||||
);
|
||||
const uint32_t RP_LIGHTSLEEP_EN1_MASK_HARSH = 0x0;
|
||||
|
||||
STATIC void prepare_for_dormant_xosc(void);
|
||||
|
||||
// Singleton instance of SleepMemory.
|
||||
|
@ -144,7 +150,6 @@ mp_obj_t common_hal_alarm_create_wake_alarm(void) {
|
|||
|
||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||
// alarm_pin_pinalarm_light_reset();
|
||||
|
||||
mp_obj_t wake_alarm = mp_const_none;
|
||||
|
||||
|
@ -173,7 +178,6 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
|
|||
// Prune the clock for sleep
|
||||
clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK;
|
||||
clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK;
|
||||
// port_idle_until_interrupt();
|
||||
|
||||
// Enable System Control Block (SCB) deep sleep
|
||||
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
|
|||
}
|
||||
|
||||
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||
bool timealarm_set = alarm_time_timealarm_is_set();
|
||||
|
||||
// If there's a timealarm, just enter a very deep light sleep
|
||||
if (timealarm_set) {
|
||||
// Prune the clock for sleep
|
||||
clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK_HARSH;
|
||||
clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK_HARSH;
|
||||
// Enable System Control Block (SCB) deep sleep
|
||||
uint save = scb_hw->scr;
|
||||
scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS;
|
||||
__wfi();
|
||||
} else {
|
||||
prepare_for_dormant_xosc();
|
||||
xosc_dormant();
|
||||
}
|
||||
// // TODO: support ROSC when available in SDK
|
||||
// rosc_set_dormant();
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
STATIC bool woke_up;
|
||||
STATIC uint64_t alarm_triggered_pins; // 36 actual pins
|
||||
STATIC uint64_t alarm_reserved_pins; // 36 actual pins
|
||||
STATIC bool _pinalarm_set = false;
|
||||
|
||||
#define GPIO_IRQ_ALL_EVENTS 0x15u
|
||||
|
||||
|
@ -152,6 +153,12 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
|
|||
if (deep_sleep) {
|
||||
gpio_set_dormant_irq_enabled((uint)alarm->pin->number, event, true);
|
||||
}
|
||||
|
||||
_pinalarm_set = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool alarm_pin_pinalarm_is_set(void) {
|
||||
return _pinalarm_set;
|
||||
}
|
||||
|
|
|
@ -42,3 +42,4 @@ void alarm_pin_pinalarm_reset(void);
|
|||
void alarm_pin_pinalarm_light_reset(void);
|
||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||
bool alarm_pin_pinalarm_woke_this_cycle(void);
|
||||
bool alarm_pin_pinalarm_is_set(void);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "hardware/rtc.h"
|
||||
|
||||
STATIC bool woke_up = false;
|
||||
STATIC bool _timealarm_set = false;
|
||||
|
||||
void timer_callback(void) {
|
||||
woke_up = true;
|
||||
|
@ -92,7 +93,7 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
|
|||
return;
|
||||
}
|
||||
if (deep_sleep) {
|
||||
mp_raise_ValueError(translate("Cannot alarm from RTC in deep sleep"));
|
||||
_timealarm_set = true;
|
||||
}
|
||||
|
||||
// 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_
|
|||
|
||||
woke_up = false;
|
||||
}
|
||||
|
||||
bool alarm_time_timealarm_is_set(void) {
|
||||
return _timealarm_set;
|
||||
}
|
||||
|
|
|
@ -38,3 +38,4 @@ mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
|
|||
void alarm_time_timealarm_reset(void);
|
||||
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||
bool alarm_time_timealarm_woke_this_cycle(void);
|
||||
bool alarm_time_timealarm_is_set(void);
|
||||
|
|
Loading…
Reference in New Issue