Style changes and wakeup detection
This commit is contained in:
parent
d8a2d69e10
commit
529fb52309
24
main.c
24
main.c
@ -323,12 +323,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
|
||||
rgb_status_animation_t animation;
|
||||
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
|
||||
bool asleep = false;
|
||||
bool fake_sleeping = false;
|
||||
while (true) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
if (reload_requested) {
|
||||
#if CIRCUITPY_ALARM
|
||||
if (asleep) {
|
||||
if (fake_sleeping) {
|
||||
board_init();
|
||||
}
|
||||
#endif
|
||||
@ -339,7 +339,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
|
||||
if (serial_connected() && serial_bytes_available()) {
|
||||
#if CIRCUITPY_ALARM
|
||||
if (asleep) {
|
||||
if (fake_sleeping) {
|
||||
board_init();
|
||||
}
|
||||
#endif
|
||||
@ -355,7 +355,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
// an alarm alerts faster than our USB delay or if we pretended to deep
|
||||
// sleep.
|
||||
#if CIRCUITPY_ALARM
|
||||
if (asleep && common_hal_alarm_woken_from_sleep()) {
|
||||
if (fake_sleeping && common_hal_alarm_woken_from_sleep()) {
|
||||
serial_write_compressed(translate("Woken up by alarm.\n"));
|
||||
board_init();
|
||||
supervisor_set_run_reason(RUN_REASON_STARTUP);
|
||||
@ -394,14 +394,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
if (result.return_code & PYEXEC_DEEP_SLEEP) {
|
||||
// Make sure we have been awake long enough for USB to connect (enumeration delay).
|
||||
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
|
||||
if (connecting_delay_ticks > 0) {
|
||||
// Set when we've waited long enough so that we wake up from the
|
||||
// port_idle_until_interrupt below and loop around to the real deep
|
||||
// sleep in the else clause.
|
||||
port_interrupt_after_ticks(connecting_delay_ticks);
|
||||
// Deep sleep if we're not connected to a host.
|
||||
} else if (!asleep) {
|
||||
asleep = true;
|
||||
// Until it's safe to decide whether we're real/fake sleeping, just run the RGB
|
||||
// if (connecting_delay_ticks > 0) {
|
||||
// port_interrupt_after_ticks(connecting_delay_ticks);
|
||||
// // } else if (!fake_sleeping) {
|
||||
if (connecting_delay_ticks < 0 && !fake_sleeping) {
|
||||
fake_sleeping = true;
|
||||
new_status_color(BLACK);
|
||||
board_deinit();
|
||||
if (!supervisor_workflow_active()) {
|
||||
@ -416,7 +414,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!asleep) {
|
||||
if (!fake_sleeping) {
|
||||
tick_rgb_status_animation(&animation);
|
||||
} else {
|
||||
// This waits until a pretend deep sleep alarm occurs. They are set
|
||||
|
@ -101,7 +101,7 @@ bool alarm_pin_pinalarm_woke_us_up(void) {
|
||||
}
|
||||
|
||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// First, check to see if we match any given 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;
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
@ -112,6 +112,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
// For deep sleep, a new alarm must be created
|
||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||
size_t pin_number = 64;
|
||||
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
|
||||
@ -151,7 +152,7 @@ static uint64_t high_alarms = 0;
|
||||
static uint64_t low_alarms = 0;
|
||||
static uint64_t pull_pins = 0;
|
||||
|
||||
void alarm_pin_pinalarm_reset(void) {
|
||||
void alarm_pin_pinalarm_reset_alarms(void) {
|
||||
if (gpio_interrupt_handle != NULL) {
|
||||
esp_intr_free(gpio_interrupt_handle);
|
||||
gpio_interrupt_handle = NULL;
|
||||
|
@ -37,6 +37,3 @@ bool board_requests_safe_mode(void) {
|
||||
void reset_board(void) {
|
||||
|
||||
}
|
||||
|
||||
void board_deinit(void) {
|
||||
}
|
@ -39,70 +39,73 @@
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
|
||||
#define STM_WAKEUP_UNDEF 0
|
||||
#define STM_WAKEUP_GPIO 1
|
||||
#define STM_WAKEUP_TIMER 2
|
||||
#define STM_WAKEUP_RTC 2
|
||||
|
||||
#define STM_ALARM_FLAG RTC->BKP0R
|
||||
|
||||
void common_hal_alarm_reset(void) {
|
||||
// Reset the alarm flag
|
||||
STM_ALARM_FLAG = 0x00;
|
||||
// alarm_sleep_memory_reset();
|
||||
alarm_pin_pinalarm_reset();
|
||||
alarm_time_timealarm_reset();
|
||||
// alarm_touch_touchalarm_reset();
|
||||
// esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||
}
|
||||
|
||||
STATIC uint8_t _get_wakeup_cause(void) {
|
||||
// If in light/fake sleep, check modules
|
||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
||||
return STM_WAKEUP_GPIO;
|
||||
}
|
||||
if (alarm_time_timealarm_woke_us_up()) {
|
||||
return STM_WAKEUP_TIMER;
|
||||
return STM_WAKEUP_RTC;
|
||||
}
|
||||
return 0;
|
||||
if (RTC->BKP0R & 0x01) {
|
||||
// We've woken from deep sleep. Was it the WKUP pin or the RTC?
|
||||
if (RTC->ISR & RTC_FLAG_ALRBF) {
|
||||
// Alarm B is the deep sleep alarm
|
||||
return STM_WAKEUP_RTC;
|
||||
} else {
|
||||
return STM_WAKEUP_GPIO;
|
||||
}
|
||||
}
|
||||
return STM_WAKEUP_UNDEF;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_woken_from_sleep(void) {
|
||||
return _get_wakeup_cause() != 0;
|
||||
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
}
|
||||
// esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||
// switch (cause) {
|
||||
// case ESP_SLEEP_WAKEUP_TIMER: {
|
||||
// return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
// }
|
||||
|
||||
// case ESP_SLEEP_WAKEUP_GPIO:
|
||||
// case ESP_SLEEP_WAKEUP_EXT0:
|
||||
// case ESP_SLEEP_WAKEUP_EXT1: {
|
||||
// return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
// }
|
||||
|
||||
// case ESP_SLEEP_WAKEUP_TOUCHPAD: {
|
||||
// return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
// }
|
||||
|
||||
// case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
// default:
|
||||
// // Not a deep sleep reset.
|
||||
// break;
|
||||
// }
|
||||
// return mp_const_none;
|
||||
uint8_t cause = _get_wakeup_cause();
|
||||
switch (cause) {
|
||||
case STM_WAKEUP_RTC: {
|
||||
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
}
|
||||
case STM_WAKEUP_GPIO: {
|
||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
}
|
||||
case STM_WAKEUP_UNDEF:
|
||||
default:
|
||||
// Not a deep sleep reset.
|
||||
break;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
||||
//return _get_wake_alarm(0, NULL);
|
||||
return mp_const_none;
|
||||
return _get_wake_alarm(0, NULL);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
// alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||
}
|
||||
|
||||
STATIC void _idle_until_alarm(void) {
|
||||
@ -144,16 +147,19 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);
|
||||
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,0);
|
||||
alarm_pin_pinalarm_prepare_for_deep_sleep();
|
||||
alarm_time_timealarm_prepare_for_deep_sleep();
|
||||
port_disable_tick();
|
||||
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
|
||||
// alarm_touch_touchalarm_prepare_for_deep_sleep();
|
||||
|
||||
// Set a flag in the backup registers to indicate sleep wakeup
|
||||
STM_ALARM_FLAG = 0x01;
|
||||
// HAL_PWR_EnableBkUpAccess();
|
||||
// __HAL_RCC_BACKUPRESET_FORCE();
|
||||
// __HAL_RCC_BACKUPRESET_RELEASE();
|
||||
|
||||
HAL_PWR_EnterSTANDBYMode();
|
||||
|
||||
// Should never hit this
|
||||
// The above shuts down RAM, so we should never hit this
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
|
||||
}
|
||||
|
||||
void alarm_pin_pinalarm_reset(void) {
|
||||
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
alarm_pin_triggered = 0;
|
||||
woke_up = false;
|
||||
}
|
||||
@ -118,20 +119,18 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
|
||||
if (deep_sleep) {
|
||||
// Deep sleep only wakes on a rising edge from one pin, WKUP (PA00)
|
||||
// All pin settings are handled automatically.
|
||||
if (alarm->pin != &pin_PA00) {
|
||||
mp_raise_ValueError(translate("Only the WKUP pin can be used to wake from Deep Sleep"));
|
||||
}
|
||||
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
|
||||
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
|
||||
// We can't actually turn WakeUp on here, since enabling it disables EXTI,
|
||||
// so we put it off until right before sleeping.
|
||||
deep_wkup_enabled = true;
|
||||
} else {
|
||||
stm_peripherals_exti_enable(alarm->pin->number);
|
||||
}
|
||||
|
||||
stm_peripherals_exti_enable(alarm->pin->number);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,7 +149,9 @@ void alarm_pin_pinalarm_reset_alarms(bool deep_sleep, size_t n_alarms, const mp_
|
||||
// If we don't have WKUP enabled, ensure it's disabled
|
||||
// TODO; is this really required?
|
||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
|
||||
if (!deep_wkup_enabled) {
|
||||
if (deep_wkup_enabled) {
|
||||
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
|
||||
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include STM32_HAL_H
|
||||
|
||||
STATIC volatile bool woke_up;
|
||||
STATIC uint32_t deep_sleep_ticks;
|
||||
|
||||
void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
|
||||
self->monotonic_time = monotonic_time;
|
||||
@ -95,7 +96,24 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
|
||||
uint32_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs);
|
||||
uint32_t wakeup_in_ticks = wakeup_in_secs * 1024;
|
||||
|
||||
// In the deep sleep case, we can't start the timer until the USB delay has finished
|
||||
if (deep_sleep) {
|
||||
deep_sleep_ticks = wakeup_in_ticks;
|
||||
} else {
|
||||
deep_sleep_ticks = 0;
|
||||
}
|
||||
// Use alarm B, since port reserves A
|
||||
// If true deep sleep is called, it will either ignore or overwrite this depending on
|
||||
// whether it is shorter or longer than the USB delay
|
||||
stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback);
|
||||
stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,wakeup_in_ticks);
|
||||
}
|
||||
|
||||
void alarm_time_timealarm_prepare_for_deep_sleep(void) {
|
||||
if (deep_sleep_ticks) {
|
||||
// This is used for both fake and real deep sleep, so it still needs the callback
|
||||
stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback);
|
||||
stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,deep_sleep_ticks);
|
||||
deep_sleep_ticks = 0;
|
||||
}
|
||||
}
|
||||
|
@ -38,3 +38,5 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *
|
||||
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_prepare_for_deep_sleep(void);
|
||||
|
@ -369,3 +369,9 @@ void _init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if CIRCUITPY_ALARM
|
||||
// in case boards/xxx/board.c does not provide board_deinit()
|
||||
MP_WEAK void board_deinit(void) {
|
||||
}
|
||||
#endif
|
||||
|
@ -92,7 +92,7 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
|
||||
//| This allows the user to interrupt an existing program with ctrl-C,
|
||||
//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep.
|
||||
//| Thus, to use light sleep and save significant power,
|
||||
// it may be necessary to disconnect from the host.
|
||||
//| it may be necessary to disconnect from the host.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
|
Loading…
Reference in New Issue
Block a user