Merge pull request #4606 from hierophect/sleep-revamp
Internal API revisions to sleep
This commit is contained in:
commit
f5aa55c247
2
main.c
2
main.c
@ -162,7 +162,7 @@ STATIC void start_mp(supervisor_allocation* heap) {
|
|||||||
|
|
||||||
#if CIRCUITPY_ALARM
|
#if CIRCUITPY_ALARM
|
||||||
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
|
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
|
||||||
shared_alarm_save_wake_alarm();
|
shared_alarm_save_wake_alarm(common_hal_alarm_create_wake_alarm());
|
||||||
// Reset alarm module only after we retrieved the wakeup alarm.
|
// Reset alarm module only after we retrieved the wakeup alarm.
|
||||||
alarm_reset();
|
alarm_reset();
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,15 +63,18 @@ void alarm_reset(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
|
STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
|
||||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
// First check if the modules remember what last woke up
|
||||||
|
if (alarm_pin_pinalarm_woke_this_cycle()) {
|
||||||
return ESP_SLEEP_WAKEUP_GPIO;
|
return ESP_SLEEP_WAKEUP_GPIO;
|
||||||
}
|
}
|
||||||
if (alarm_time_timealarm_woke_us_up()) {
|
if (alarm_time_timealarm_woke_this_cycle()) {
|
||||||
return ESP_SLEEP_WAKEUP_TIMER;
|
return ESP_SLEEP_WAKEUP_TIMER;
|
||||||
}
|
}
|
||||||
if (alarm_touch_touchalarm_woke_us_up()) {
|
if (alarm_touch_touchalarm_woke_this_cycle()) {
|
||||||
return ESP_SLEEP_WAKEUP_TOUCHPAD;
|
return ESP_SLEEP_WAKEUP_TOUCHPAD;
|
||||||
}
|
}
|
||||||
|
// If waking from true deep sleep, modules will have lost their state,
|
||||||
|
// so check the deep wakeup cause manually
|
||||||
return esp_sleep_get_wakeup_cause();
|
return esp_sleep_get_wakeup_cause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,23 +82,23 @@ bool common_hal_alarm_woken_from_sleep(void) {
|
|||||||
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
|
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When called to populate the global dict, the module functions create new alarm objects.
|
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
|
||||||
// Otherwise, they scan the existing alarms for matches.
|
// If woken from deep sleep, create a copy alarm similar to what would have
|
||||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
// been passed in originally. Otherwise, just return none
|
||||||
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
case ESP_SLEEP_WAKEUP_TIMER: {
|
case ESP_SLEEP_WAKEUP_TIMER: {
|
||||||
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_time_timealarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_GPIO:
|
case ESP_SLEEP_WAKEUP_GPIO:
|
||||||
case ESP_SLEEP_WAKEUP_EXT0:
|
case ESP_SLEEP_WAKEUP_EXT0:
|
||||||
case ESP_SLEEP_WAKEUP_EXT1: {
|
case ESP_SLEEP_WAKEUP_EXT1: {
|
||||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_pin_pinalarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
|
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
|
||||||
return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_touch_touchalarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
|
|
||||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||||
@ -106,12 +109,6 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is used to create a new alarm object for the global dict after deep sleep,
|
|
||||||
// rather than finding an existing one during runtime.
|
|
||||||
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
|
||||||
return _get_wake_alarm(0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up light sleep or deep sleep alarms.
|
// Set up light sleep or deep sleep alarms.
|
||||||
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
@ -119,31 +116,44 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t
|
|||||||
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void _idle_until_alarm(void) {
|
|
||||||
// Poll for alarms.
|
|
||||||
while (!mp_hal_is_interrupted()) {
|
|
||||||
RUN_BACKGROUND_TASKS;
|
|
||||||
// Allow ctrl-C interrupt.
|
|
||||||
if (common_hal_alarm_woken_from_sleep()) {
|
|
||||||
// This saves the return of common_hal_alarm_get_wake_alarm through Shared Bindings
|
|
||||||
shared_alarm_save_wake_alarm();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
port_idle_until_interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
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);
|
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||||
|
|
||||||
|
mp_obj_t wake_alarm = mp_const_none;
|
||||||
|
|
||||||
// We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
|
// We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
|
||||||
_idle_until_alarm();
|
while (!mp_hal_is_interrupted()) {
|
||||||
|
RUN_BACKGROUND_TASKS;
|
||||||
|
// Detect if interrupt was alarm or ctrl-C interrupt.
|
||||||
|
if (common_hal_alarm_woken_from_sleep()) {
|
||||||
|
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||||
|
switch (cause) {
|
||||||
|
case ESP_SLEEP_WAKEUP_TIMER: {
|
||||||
|
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ESP_SLEEP_WAKEUP_GPIO: {
|
||||||
|
wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
|
||||||
|
wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Should not reach this, if all light sleep types are covered correctly
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shared_alarm_save_wake_alarm(wake_alarm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
port_idle_until_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
if (mp_hal_is_interrupted()) {
|
if (mp_hal_is_interrupted()) {
|
||||||
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
|
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
|
||||||
alarm_reset();
|
alarm_reset();
|
||||||
return wake_alarm;
|
return wake_alarm;
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,11 @@ void gpio_interrupt(void *arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void) {
|
bool alarm_pin_pinalarm_woke_this_cycle(void) {
|
||||||
return pin_31_0_status != 0 || pin_63_32_status != 0;
|
return pin_31_0_status != 0 || pin_63_32_status != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// For light sleep, we check if we match any existing alarms
|
|
||||||
uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status;
|
uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status;
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
@ -112,9 +111,16 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
|||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// For deep sleep, a new alarm must be created
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) {
|
||||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
|
|
||||||
|
// Pin status will persist into a fake deep sleep
|
||||||
|
uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status;
|
||||||
size_t pin_number = 64;
|
size_t pin_number = 64;
|
||||||
|
|
||||||
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
|
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
|
||||||
pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL);
|
pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -34,8 +34,10 @@ typedef struct {
|
|||||||
bool pull;
|
bool pull;
|
||||||
} alarm_pin_pinalarm_obj_t;
|
} alarm_pin_pinalarm_obj_t;
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void);
|
||||||
|
|
||||||
|
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
||||||
void alarm_pin_pinalarm_reset(void);
|
void alarm_pin_pinalarm_reset(void);
|
||||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
bool alarm_pin_pinalarm_woke_this_cycle(void);
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void);
|
|
||||||
|
@ -42,13 +42,16 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala
|
|||||||
return self->monotonic_time;
|
return self->monotonic_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// First, check to see if we match
|
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) {
|
||||||
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
||||||
timer->base.type = &alarm_time_timealarm_type;
|
timer->base.type = &alarm_time_timealarm_type;
|
||||||
// TODO: Set monotonic_time based on the RTC state.
|
// TODO: Set monotonic_time based on the RTC state.
|
||||||
@ -66,7 +69,7 @@ void timer_callback(void *arg) {
|
|||||||
xTaskNotifyGive(circuitpython_task);
|
xTaskNotifyGive(circuitpython_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void) {
|
bool alarm_time_timealarm_woke_this_cycle(void) {
|
||||||
return woke_up;
|
return woke_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ typedef struct {
|
|||||||
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
||||||
} alarm_time_timealarm_obj_t;
|
} alarm_time_timealarm_obj_t;
|
||||||
|
|
||||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
|
||||||
// Check for the wake up alarm from pretend deep sleep.
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void);
|
|
||||||
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
|
||||||
void alarm_time_timealarm_reset(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);
|
||||||
|
@ -42,14 +42,16 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s
|
|||||||
self->pin = pin;
|
self->pin = pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// First, check to see if we match any given alarms.
|
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) {
|
if (mp_obj_is_type(alarms[i], &alarm_touch_touchalarm_type)) {
|
||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) {
|
||||||
// Create TouchAlarm object.
|
// Create TouchAlarm object.
|
||||||
alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t);
|
alarm_touch_touchalarm_obj_t *alarm = m_new_obj(alarm_touch_touchalarm_obj_t);
|
||||||
alarm->base.type = &alarm_touch_touchalarm_type;
|
alarm->base.type = &alarm_touch_touchalarm_type;
|
||||||
@ -168,7 +170,7 @@ void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
|
|||||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_touch_touchalarm_woke_us_up(void) {
|
bool alarm_touch_touchalarm_woke_this_cycle(void) {
|
||||||
return woke_up;
|
return woke_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,12 +35,12 @@ typedef struct {
|
|||||||
const mcu_pin_obj_t *pin;
|
const mcu_pin_obj_t *pin;
|
||||||
} alarm_touch_touchalarm_obj_t;
|
} alarm_touch_touchalarm_obj_t;
|
||||||
|
|
||||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
||||||
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void);
|
||||||
// Check for the wake up alarm from pretend deep sleep.
|
|
||||||
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
|
||||||
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
|
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
|
||||||
bool alarm_touch_touchalarm_woke_us_up(void);
|
|
||||||
void alarm_touch_touchalarm_reset(void);
|
void alarm_touch_touchalarm_reset(void);
|
||||||
|
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
bool alarm_touch_touchalarm_woke_this_cycle(void);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H
|
#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H
|
||||||
|
@ -69,15 +69,18 @@ void alarm_reset(void) {
|
|||||||
|
|
||||||
extern uint32_t reset_reason_saved;
|
extern uint32_t reset_reason_saved;
|
||||||
STATIC nrf_sleep_source_t _get_wakeup_cause(void) {
|
STATIC nrf_sleep_source_t _get_wakeup_cause(void) {
|
||||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
// First check if the modules remember what last woke up
|
||||||
|
if (alarm_pin_pinalarm_woke_this_cycle()) {
|
||||||
return NRF_SLEEP_WAKEUP_GPIO;
|
return NRF_SLEEP_WAKEUP_GPIO;
|
||||||
}
|
}
|
||||||
if (alarm_time_timealarm_woke_us_up()) {
|
if (alarm_time_timealarm_woke_this_cycle()) {
|
||||||
return NRF_SLEEP_WAKEUP_TIMER;
|
return NRF_SLEEP_WAKEUP_TIMER;
|
||||||
}
|
}
|
||||||
if (alarm_touch_touchalarm_woke_us_up()) {
|
if (alarm_touch_touchalarm_woke_this_cycle()) {
|
||||||
return NRF_SLEEP_WAKEUP_TOUCHPAD;
|
return NRF_SLEEP_WAKEUP_TOUCHPAD;
|
||||||
}
|
}
|
||||||
|
// If waking from true deep sleep, modules will have lost their state,
|
||||||
|
// so check the deep wakeup cause manually
|
||||||
if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) {
|
if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) {
|
||||||
return NRF_SLEEP_WAKEUP_RESETPIN;
|
return NRF_SLEEP_WAKEUP_RESETPIN;
|
||||||
} else if (reset_reason_saved & NRF_POWER_RESETREAS_OFF_MASK) {
|
} else if (reset_reason_saved & NRF_POWER_RESETREAS_OFF_MASK) {
|
||||||
@ -116,17 +119,19 @@ bool common_hal_alarm_woken_from_sleep(void) {
|
|||||||
|| cause == NRF_SLEEP_WAKEUP_TOUCHPAD;
|
|| cause == NRF_SLEEP_WAKEUP_TOUCHPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
|
||||||
|
// If woken from deep sleep, create a copy alarm similar to what would have
|
||||||
|
// been passed in originally. Otherwise, just return none
|
||||||
nrf_sleep_source_t cause = _get_wakeup_cause();
|
nrf_sleep_source_t cause = _get_wakeup_cause();
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
case NRF_SLEEP_WAKEUP_TIMER: {
|
case NRF_SLEEP_WAKEUP_TIMER: {
|
||||||
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_time_timealarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
case NRF_SLEEP_WAKEUP_TOUCHPAD: {
|
case NRF_SLEEP_WAKEUP_TOUCHPAD: {
|
||||||
return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_touch_touchalarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
case NRF_SLEEP_WAKEUP_GPIO: {
|
case NRF_SLEEP_WAKEUP_GPIO: {
|
||||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_pin_pinalarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -134,11 +139,6 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
|
||||||
mp_obj_t obj = _get_wake_alarm(0, NULL);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up light sleep or deep sleep alarms.
|
// Set up light sleep or deep sleep alarms.
|
||||||
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
@ -257,7 +257,7 @@ void system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
mp_obj_t wake_alarm;
|
mp_obj_t wake_alarm = mp_const_none;
|
||||||
alarm_time_timealarm_clear_wakeup_time();
|
alarm_time_timealarm_clear_wakeup_time();
|
||||||
_setup_sleep_alarms(false, n_alarms, alarms);
|
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||||
|
|
||||||
@ -271,7 +271,23 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
|
|||||||
if (mp_hal_is_interrupted()) {
|
if (mp_hal_is_interrupted()) {
|
||||||
wake_alarm = mp_const_none;
|
wake_alarm = mp_const_none;
|
||||||
} else {
|
} else {
|
||||||
wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
if (common_hal_alarm_woken_from_sleep()) {
|
||||||
|
nrf_sleep_source_t cause = _get_wakeup_cause();
|
||||||
|
switch (cause) {
|
||||||
|
case NRF_SLEEP_WAKEUP_TIMER: {
|
||||||
|
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NRF_SLEEP_WAKEUP_GPIO: {
|
||||||
|
wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Should not reach this, if all light sleep types are covered correctly
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shared_alarm_save_wake_alarm(wake_alarm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
alarm_reset();
|
alarm_reset();
|
||||||
return wake_alarm;
|
return wake_alarm;
|
||||||
|
@ -85,12 +85,12 @@ static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t
|
|||||||
sleepmem_wakeup_pin = pin & 0xFF;
|
sleepmem_wakeup_pin = pin & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void) {
|
bool alarm_pin_pinalarm_woke_this_cycle(void) {
|
||||||
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN &&
|
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN &&
|
||||||
sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF;
|
sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// First, check to see if we match any given alarms.
|
// First, check to see if we match any given alarms.
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
@ -101,6 +101,10 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
|||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) {
|
||||||
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
||||||
alarm->base.type = &alarm_pin_pinalarm_type;
|
alarm->base.type = &alarm_pin_pinalarm_type;
|
||||||
alarm->pin = NULL;
|
alarm->pin = NULL;
|
||||||
|
@ -34,8 +34,10 @@ typedef struct {
|
|||||||
bool pull;
|
bool pull;
|
||||||
} alarm_pin_pinalarm_obj_t;
|
} alarm_pin_pinalarm_obj_t;
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void);
|
||||||
|
|
||||||
void alarm_pin_pinalarm_reset(void);
|
void alarm_pin_pinalarm_reset(void);
|
||||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
bool alarm_pin_pinalarm_woke_this_cycle(void);
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void);
|
|
||||||
|
@ -40,13 +40,16 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala
|
|||||||
return self->monotonic_time;
|
return self->monotonic_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// First, check to see if we match
|
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) {
|
||||||
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
||||||
timer->base.type = &alarm_time_timealarm_type;
|
timer->base.type = &alarm_time_timealarm_type;
|
||||||
// TODO: Set monotonic_time based on the RTC state.
|
// TODO: Set monotonic_time based on the RTC state.
|
||||||
@ -54,7 +57,7 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *
|
|||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void) {
|
bool alarm_time_timealarm_woke_this_cycle(void) {
|
||||||
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_TIMER;
|
return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_TIMER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ extern volatile int rtc_woke_up_counter;
|
|||||||
extern void port_disable_interrupt_after_ticks_ch(uint32_t channel);
|
extern void port_disable_interrupt_after_ticks_ch(uint32_t channel);
|
||||||
extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks);
|
extern void port_interrupt_after_ticks_ch(uint32_t channel, uint32_t ticks);
|
||||||
|
|
||||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
|
||||||
// Check for the wake up alarm from pretend deep sleep.
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void);
|
bool alarm_time_timealarm_woke_this_cycle(void);
|
||||||
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_time_timealarm_reset(void);
|
void alarm_time_timealarm_reset(void);
|
||||||
|
|
||||||
|
@ -35,7 +35,11 @@ void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *s
|
|||||||
(void)pin;
|
(void)pin;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +49,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar
|
|||||||
void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
|
void alarm_touch_touchalarm_prepare_for_deep_sleep(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_touch_touchalarm_woke_us_up(void) {
|
bool alarm_touch_touchalarm_woke_this_cycle(void) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,12 @@ typedef struct {
|
|||||||
} alarm_touch_touchalarm_obj_t;
|
} alarm_touch_touchalarm_obj_t;
|
||||||
|
|
||||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
// Find the alarm object that caused us to wake up or create an equivalent one.
|
||||||
mp_obj_t alarm_touch_touchalarm_get_wakeup_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
mp_obj_t alarm_touch_touchalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
mp_obj_t alarm_touch_touchalarm_create_wakeup_alarm(void);
|
||||||
// Check for the wake up alarm from pretend deep sleep.
|
// Check for the wake up alarm from pretend deep sleep.
|
||||||
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
|
void alarm_touch_touchalarm_prepare_for_deep_sleep(void);
|
||||||
bool alarm_touch_touchalarm_woke_us_up(void);
|
bool alarm_touch_touchalarm_woke_this_cycle(void);
|
||||||
void alarm_touch_touchalarm_reset(void);
|
void alarm_touch_touchalarm_reset(void);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H
|
#endif // MICROPY_INCLUDED_COMMON_HAL_ALARM_TOUCH_TOUCHALARM_H
|
||||||
|
@ -48,10 +48,8 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
STATIC stm_sleep_source_t true_deep_wake_reason;
|
STATIC stm_sleep_source_t true_deep_wake_reason;
|
||||||
STATIC mp_obj_t most_recent_alarm;
|
|
||||||
|
|
||||||
void alarm_reset(void) {
|
void alarm_reset(void) {
|
||||||
most_recent_alarm = NULL;
|
|
||||||
// Reset the alarm flag
|
// Reset the alarm flag
|
||||||
STM_ALARM_FLAG = 0x00;
|
STM_ALARM_FLAG = 0x00;
|
||||||
alarm_pin_pinalarm_reset();
|
alarm_pin_pinalarm_reset();
|
||||||
@ -66,10 +64,10 @@ void alarm_set_wakeup_reason(stm_sleep_source_t reason) {
|
|||||||
|
|
||||||
STATIC stm_sleep_source_t _get_wakeup_cause(void) {
|
STATIC stm_sleep_source_t _get_wakeup_cause(void) {
|
||||||
// If in light/fake sleep, check modules
|
// If in light/fake sleep, check modules
|
||||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
if (alarm_pin_pinalarm_woke_this_cycle()) {
|
||||||
return STM_WAKEUP_GPIO;
|
return STM_WAKEUP_GPIO;
|
||||||
}
|
}
|
||||||
if (alarm_time_timealarm_woke_us_up()) {
|
if (alarm_time_timealarm_woke_this_cycle()) {
|
||||||
return STM_WAKEUP_RTC;
|
return STM_WAKEUP_RTC;
|
||||||
}
|
}
|
||||||
// Check to see if we woke from deep sleep (reason set in port_init)
|
// Check to see if we woke from deep sleep (reason set in port_init)
|
||||||
@ -83,14 +81,16 @@ bool common_hal_alarm_woken_from_sleep(void) {
|
|||||||
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
|
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t common_hal_alarm_create_wake_alarm(void) {
|
||||||
|
// If woken from deep sleep, create a copy alarm similar to what would have
|
||||||
|
// been passed in originally. Otherwise, just return none
|
||||||
stm_sleep_source_t cause = _get_wakeup_cause();
|
stm_sleep_source_t cause = _get_wakeup_cause();
|
||||||
switch (cause) {
|
switch (cause) {
|
||||||
case STM_WAKEUP_RTC: {
|
case STM_WAKEUP_RTC: {
|
||||||
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_time_timealarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
case STM_WAKEUP_GPIO: {
|
case STM_WAKEUP_GPIO: {
|
||||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
return alarm_pin_pinalarm_create_wakeup_alarm();
|
||||||
}
|
}
|
||||||
case STM_WAKEUP_UNDEF:
|
case STM_WAKEUP_UNDEF:
|
||||||
default:
|
default:
|
||||||
@ -100,58 +100,51 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
|||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
|
||||||
// If we woke from light sleep, override with that alarm
|
|
||||||
if (most_recent_alarm != NULL) {
|
|
||||||
return most_recent_alarm;
|
|
||||||
}
|
|
||||||
return _get_wake_alarm(0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up light sleep or deep sleep alarms.
|
// Set up light sleep or deep sleep alarms.
|
||||||
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void _idle_until_alarm(void) {
|
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// Poll for alarms.
|
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||||
|
mp_obj_t wake_alarm = mp_const_none;
|
||||||
|
|
||||||
|
// TODO: add more dynamic clock shutdown/restart logic
|
||||||
while (!mp_hal_is_interrupted()) {
|
while (!mp_hal_is_interrupted()) {
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
// Detect if interrupt was alarm or ctrl-C interrupt.
|
// Detect if interrupt was alarm or ctrl-C interrupt.
|
||||||
if (common_hal_alarm_woken_from_sleep()) {
|
if (common_hal_alarm_woken_from_sleep()) {
|
||||||
return;
|
stm_sleep_source_t cause = _get_wakeup_cause();
|
||||||
|
switch (cause) {
|
||||||
|
case STM_WAKEUP_RTC: {
|
||||||
|
wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case STM_WAKEUP_GPIO: {
|
||||||
|
wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Should not reach this, if all light sleep types are covered correctly
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shared_alarm_save_wake_alarm(wake_alarm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// HAL_PWR_EnterSLEEPMode is just a WFI anyway so don't bother
|
||||||
port_idle_until_interrupt();
|
port_idle_until_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mp_hal_is_interrupted()) {
|
||||||
|
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
alarm_reset();
|
||||||
// If USB is active, only pretend to sleep. Otherwise, light sleep
|
|
||||||
if (supervisor_workflow_active()) {
|
|
||||||
_setup_sleep_alarms(false, n_alarms, alarms);
|
|
||||||
_idle_until_alarm();
|
|
||||||
} else {
|
|
||||||
_setup_sleep_alarms(false, n_alarms, alarms);
|
|
||||||
port_disable_tick();
|
|
||||||
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
|
|
||||||
port_enable_tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
|
||||||
|
|
||||||
// TODO: make assignment to global array less roundabout
|
|
||||||
most_recent_alarm = wake_alarm;
|
|
||||||
shared_alarm_save_wake_alarm();
|
|
||||||
|
|
||||||
// Can't use alarm_reset since it resets most_recent_alarm
|
|
||||||
alarm_pin_pinalarm_reset();
|
|
||||||
alarm_time_timealarm_reset();
|
|
||||||
return wake_alarm;
|
return wake_alarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
most_recent_alarm = NULL;
|
|
||||||
_setup_sleep_alarms(true, n_alarms, alarms);
|
_setup_sleep_alarms(true, n_alarms, alarms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,11 +85,11 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
|
|||||||
return self->pull;
|
return self->pull;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void) {
|
bool alarm_pin_pinalarm_woke_this_cycle(void) {
|
||||||
return woke_up;
|
return woke_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
if (!mp_obj_is_type(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||||
continue;
|
continue;
|
||||||
@ -99,8 +99,10 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
|||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
// If the above isn't true, we woke from deep sleep, so create a new alarm
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void) {
|
||||||
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
||||||
alarm->base.type = &alarm_pin_pinalarm_type;
|
alarm->base.type = &alarm_pin_pinalarm_type;
|
||||||
// TODO: replace this if/when other WKUP pins are supported
|
// TODO: replace this if/when other WKUP pins are supported
|
||||||
|
@ -37,10 +37,12 @@ typedef struct {
|
|||||||
bool pull;
|
bool pull;
|
||||||
} alarm_pin_pinalarm_obj_t;
|
} alarm_pin_pinalarm_obj_t;
|
||||||
|
|
||||||
|
mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
mp_obj_t alarm_pin_pinalarm_create_wakeup_alarm(void);
|
||||||
|
|
||||||
void alarm_pin_pinalarm_reset(void);
|
void alarm_pin_pinalarm_reset(void);
|
||||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
||||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
bool alarm_pin_pinalarm_woke_this_cycle(void);
|
||||||
bool alarm_pin_pinalarm_woke_us_up(void);
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H
|
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_PINALARM_H
|
||||||
|
@ -44,13 +44,17 @@ mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timeala
|
|||||||
return self->monotonic_time;
|
return self->monotonic_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||||
// First, check to see if we match
|
// First, check to see if we match
|
||||||
for (size_t i = 0; i < n_alarms; i++) {
|
for (size_t i = 0; i < n_alarms; i++) {
|
||||||
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
if (mp_obj_is_type(alarms[i], &alarm_time_timealarm_type)) {
|
||||||
return alarms[i];
|
return alarms[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void) {
|
||||||
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
||||||
timer->base.type = &alarm_time_timealarm_type;
|
timer->base.type = &alarm_time_timealarm_type;
|
||||||
// TODO: Set monotonic_time based on the RTC state.
|
// TODO: Set monotonic_time based on the RTC state.
|
||||||
@ -63,7 +67,7 @@ STATIC void timer_callback(void) {
|
|||||||
woke_up = true;
|
woke_up = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void) {
|
bool alarm_time_timealarm_woke_this_cycle(void) {
|
||||||
return woke_up;
|
return woke_up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,10 @@ typedef struct {
|
|||||||
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
||||||
} alarm_time_timealarm_obj_t;
|
} alarm_time_timealarm_obj_t;
|
||||||
|
|
||||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
mp_obj_t alarm_time_timealarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
mp_obj_t alarm_time_timealarm_create_wakeup_alarm(void);
|
||||||
// Check for the wake up alarm from pretend deep sleep.
|
|
||||||
bool alarm_time_timealarm_woke_us_up(void);
|
bool alarm_time_timealarm_woke_this_cycle(void);
|
||||||
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||||
void alarm_time_timealarm_reset(void);
|
void alarm_time_timealarm_reset(void);
|
||||||
|
|
||||||
|
@ -228,13 +228,13 @@ mp_obj_t shared_alarm_get_wake_alarm(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize .wake_alarm value.
|
// Initialize .wake_alarm value.
|
||||||
void shared_alarm_save_wake_alarm(void) {
|
void shared_alarm_save_wake_alarm(mp_obj_t alarm) {
|
||||||
// Equivalent of:
|
// Equivalent of:
|
||||||
// alarm.wake_alarm = alarm
|
// alarm.wake_alarm = alarm
|
||||||
mp_map_elem_t *elem =
|
mp_map_elem_t *elem =
|
||||||
mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP);
|
mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP);
|
||||||
if (elem) {
|
if (elem) {
|
||||||
elem->value = common_hal_alarm_get_wake_alarm();
|
elem->value = alarm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
|
|
||||||
#include "common-hal/alarm/__init__.h"
|
#include "common-hal/alarm/__init__.h"
|
||||||
|
|
||||||
|
// Light sleep fully self-contained and does not exit user code. It will return
|
||||||
|
// the same alarm object that was orignally passed in, unlike deep sleep, which
|
||||||
|
// must create an identical copy due to the VM reset
|
||||||
extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
|
|
||||||
// Deep sleep is a two step process. Alarms are set when the VM is valid but
|
// Deep sleep is a two step process. Alarms are set when the VM is valid but
|
||||||
@ -38,22 +41,27 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const
|
|||||||
// not actually happen if the user is connected to the device. In this case, the
|
// not actually happen if the user is connected to the device. In this case, the
|
||||||
// supervisor will idle using `port_wait_for_interrupt`. After each call, it will
|
// supervisor will idle using `port_wait_for_interrupt`. After each call, it will
|
||||||
// call alarm_woken_from_sleep to see if we've been woken by an alarm and if so,
|
// call alarm_woken_from_sleep to see if we've been woken by an alarm and if so,
|
||||||
// it will exit idle as if deep sleep was exited.
|
// it will exit idle as if deep sleep was exited
|
||||||
extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||||
// Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix.
|
|
||||||
extern NORETURN void common_hal_alarm_enter_deep_sleep(void);
|
extern NORETURN void common_hal_alarm_enter_deep_sleep(void);
|
||||||
|
|
||||||
|
// May be used to re-initialize peripherals like GPIO, if the VM reset returned
|
||||||
|
// them to a default state
|
||||||
extern void common_hal_alarm_pretending_deep_sleep(void);
|
extern void common_hal_alarm_pretending_deep_sleep(void);
|
||||||
|
|
||||||
// Fetches value from module dict.
|
// Fetches value from module dict.
|
||||||
extern mp_obj_t shared_alarm_get_wake_alarm(void);
|
extern mp_obj_t shared_alarm_get_wake_alarm(void);
|
||||||
|
|
||||||
extern void common_hal_alarm_gc_collect(void);
|
// Creates a new alarm object after exiting deep sleep (real or fake)
|
||||||
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);
|
extern mp_obj_t common_hal_alarm_create_wake_alarm(void);
|
||||||
|
|
||||||
// Used by wake-up code.
|
// Saves alarm to global array
|
||||||
void shared_alarm_save_wake_alarm(void);
|
void shared_alarm_save_wake_alarm(mp_obj_t alarm);
|
||||||
|
|
||||||
// True if an alarm is alerting. This is most useful for pretend deep sleep.
|
// True if an alarm is alerting. Used in light sleep/fake deep sleep
|
||||||
extern bool common_hal_alarm_woken_from_sleep(void);
|
extern bool common_hal_alarm_woken_from_sleep(void);
|
||||||
|
|
||||||
|
extern void common_hal_alarm_gc_collect(void);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H
|
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H
|
||||||
|
Loading…
Reference in New Issue
Block a user