Skip to content

Commit 529fb52

Browse files
committed
Style changes and wakeup detection
1 parent d8a2d69 commit 529fb52

File tree

9 files changed

+88
-59
lines changed

9 files changed

+88
-59
lines changed

main.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
323323

324324
rgb_status_animation_t animation;
325325
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
326-
bool asleep = false;
326+
bool fake_sleeping = false;
327327
while (true) {
328328
RUN_BACKGROUND_TASKS;
329329
if (reload_requested) {
330330
#if CIRCUITPY_ALARM
331-
if (asleep) {
331+
if (fake_sleeping) {
332332
board_init();
333333
}
334334
#endif
@@ -339,7 +339,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
339339

340340
if (serial_connected() && serial_bytes_available()) {
341341
#if CIRCUITPY_ALARM
342-
if (asleep) {
342+
if (fake_sleeping) {
343343
board_init();
344344
}
345345
#endif
@@ -355,7 +355,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
355355
// an alarm alerts faster than our USB delay or if we pretended to deep
356356
// sleep.
357357
#if CIRCUITPY_ALARM
358-
if (asleep && common_hal_alarm_woken_from_sleep()) {
358+
if (fake_sleeping && common_hal_alarm_woken_from_sleep()) {
359359
serial_write_compressed(translate("Woken up by alarm.\n"));
360360
board_init();
361361
supervisor_set_run_reason(RUN_REASON_STARTUP);
@@ -394,14 +394,12 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
394394
if (result.return_code & PYEXEC_DEEP_SLEEP) {
395395
// Make sure we have been awake long enough for USB to connect (enumeration delay).
396396
int64_t connecting_delay_ticks = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - port_get_raw_ticks(NULL);
397-
if (connecting_delay_ticks > 0) {
398-
// Set when we've waited long enough so that we wake up from the
399-
// port_idle_until_interrupt below and loop around to the real deep
400-
// sleep in the else clause.
401-
port_interrupt_after_ticks(connecting_delay_ticks);
402-
// Deep sleep if we're not connected to a host.
403-
} else if (!asleep) {
404-
asleep = true;
397+
// Until it's safe to decide whether we're real/fake sleeping, just run the RGB
398+
// if (connecting_delay_ticks > 0) {
399+
// port_interrupt_after_ticks(connecting_delay_ticks);
400+
// // } else if (!fake_sleeping) {
401+
if (connecting_delay_ticks < 0 && !fake_sleeping) {
402+
fake_sleeping = true;
405403
new_status_color(BLACK);
406404
board_deinit();
407405
if (!supervisor_workflow_active()) {
@@ -416,7 +414,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
416414
}
417415
#endif
418416

419-
if (!asleep) {
417+
if (!fake_sleeping) {
420418
tick_rgb_status_animation(&animation);
421419
} else {
422420
// This waits until a pretend deep sleep alarm occurs. They are set

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ bool alarm_pin_pinalarm_woke_us_up(void) {
101101
}
102102

103103
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
104-
// First, check to see if we match any given alarms.
104+
// For light sleep, we check if we match any existing alarms
105105
uint64_t pin_status = ((uint64_t) pin_63_32_status) << 32 | pin_31_0_status;
106106
for (size_t i = 0; i < n_alarms; i++) {
107107
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
112112
return alarms[i];
113113
}
114114
}
115+
// For deep sleep, a new alarm must be created
115116
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
116117
size_t pin_number = 64;
117118
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
@@ -151,7 +152,7 @@ static uint64_t high_alarms = 0;
151152
static uint64_t low_alarms = 0;
152153
static uint64_t pull_pins = 0;
153154

154-
void alarm_pin_pinalarm_reset(void) {
155+
void alarm_pin_pinalarm_reset_alarms(void) {
155156
if (gpio_interrupt_handle != NULL) {
156157
esp_intr_free(gpio_interrupt_handle);
157158
gpio_interrupt_handle = NULL;

ports/stm/boards/feather_stm32f405_express/board.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,3 @@ bool board_requests_safe_mode(void) {
3737
void reset_board(void) {
3838

3939
}
40-
41-
void board_deinit(void) {
42-
}

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

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,70 +39,73 @@
3939
#include "supervisor/port.h"
4040
#include "supervisor/shared/workflow.h"
4141

42+
#define STM_WAKEUP_UNDEF 0
4243
#define STM_WAKEUP_GPIO 1
43-
#define STM_WAKEUP_TIMER 2
44+
#define STM_WAKEUP_RTC 2
45+
46+
#define STM_ALARM_FLAG RTC->BKP0R
4447

4548
void common_hal_alarm_reset(void) {
49+
// Reset the alarm flag
50+
STM_ALARM_FLAG = 0x00;
4651
// alarm_sleep_memory_reset();
4752
alarm_pin_pinalarm_reset();
4853
alarm_time_timealarm_reset();
49-
// alarm_touch_touchalarm_reset();
5054
// esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
5155
}
5256

5357
STATIC uint8_t _get_wakeup_cause(void) {
58+
// If in light/fake sleep, check modules
5459
if (alarm_pin_pinalarm_woke_us_up()) {
5560
return STM_WAKEUP_GPIO;
5661
}
5762
if (alarm_time_timealarm_woke_us_up()) {
58-
return STM_WAKEUP_TIMER;
63+
return STM_WAKEUP_RTC;
64+
}
65+
if (RTC->BKP0R & 0x01) {
66+
// We've woken from deep sleep. Was it the WKUP pin or the RTC?
67+
if (RTC->ISR & RTC_FLAG_ALRBF) {
68+
// Alarm B is the deep sleep alarm
69+
return STM_WAKEUP_RTC;
70+
} else {
71+
return STM_WAKEUP_GPIO;
72+
}
5973
}
60-
return 0;
74+
return STM_WAKEUP_UNDEF;
6175
}
6276

6377
bool common_hal_alarm_woken_from_sleep(void) {
64-
return _get_wakeup_cause() != 0;
78+
return _get_wakeup_cause() != STM_WAKEUP_UNDEF;
6579
}
6680

6781
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
6882
if (alarm_pin_pinalarm_woke_us_up()) {
6983
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
7084
}
71-
// esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
72-
// switch (cause) {
73-
// case ESP_SLEEP_WAKEUP_TIMER: {
74-
// return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
75-
// }
76-
77-
// case ESP_SLEEP_WAKEUP_GPIO:
78-
// case ESP_SLEEP_WAKEUP_EXT0:
79-
// case ESP_SLEEP_WAKEUP_EXT1: {
80-
// return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
81-
// }
82-
83-
// case ESP_SLEEP_WAKEUP_TOUCHPAD: {
84-
// return alarm_touch_touchalarm_get_wakeup_alarm(n_alarms, alarms);
85-
// }
86-
87-
// case ESP_SLEEP_WAKEUP_UNDEFINED:
88-
// default:
89-
// // Not a deep sleep reset.
90-
// break;
91-
// }
92-
// return mp_const_none;
85+
uint8_t cause = _get_wakeup_cause();
86+
switch (cause) {
87+
case STM_WAKEUP_RTC: {
88+
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
89+
}
90+
case STM_WAKEUP_GPIO: {
91+
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
92+
}
93+
case STM_WAKEUP_UNDEF:
94+
default:
95+
// Not a deep sleep reset.
96+
break;
97+
}
9398
return mp_const_none;
9499
}
95100

96101
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
97-
//return _get_wake_alarm(0, NULL);
98-
return mp_const_none;
102+
return _get_wake_alarm(0, NULL);
99103
}
100104

101105
// Set up light sleep or deep sleep alarms.
102106
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
103107
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
104108
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
105-
// alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
106109
}
107110

108111
STATIC void _idle_until_alarm(void) {
@@ -144,16 +147,19 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) {
144147
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);
145148
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,0);
146149
alarm_pin_pinalarm_prepare_for_deep_sleep();
150+
alarm_time_timealarm_prepare_for_deep_sleep();
147151
port_disable_tick();
148152
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
149-
// alarm_touch_touchalarm_prepare_for_deep_sleep();
153+
154+
// Set a flag in the backup registers to indicate sleep wakeup
155+
STM_ALARM_FLAG = 0x01;
150156
// HAL_PWR_EnableBkUpAccess();
151157
// __HAL_RCC_BACKUPRESET_FORCE();
152158
// __HAL_RCC_BACKUPRESET_RELEASE();
153159

154160
HAL_PWR_EnterSTANDBYMode();
155161

156-
// Should never hit this
162+
// The above shuts down RAM, so we should never hit this
157163
while(1);
158164
}
159165

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al
109109
}
110110

111111
void alarm_pin_pinalarm_reset(void) {
112+
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
112113
alarm_pin_triggered = 0;
113114
woke_up = false;
114115
}
@@ -118,20 +119,18 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob
118119
for (size_t i = 0; i < n_alarms; i++) {
119120
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
120121
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
121-
122122
if (deep_sleep) {
123123
// Deep sleep only wakes on a rising edge from one pin, WKUP (PA00)
124+
// All pin settings are handled automatically.
124125
if (alarm->pin != &pin_PA00) {
125126
mp_raise_ValueError(translate("Only the WKUP pin can be used to wake from Deep Sleep"));
126127
}
127-
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
128-
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
129-
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
130-
128+
// We can't actually turn WakeUp on here, since enabling it disables EXTI,
129+
// so we put it off until right before sleeping.
131130
deep_wkup_enabled = true;
132-
} else {
133-
stm_peripherals_exti_enable(alarm->pin->number);
134131
}
132+
133+
stm_peripherals_exti_enable(alarm->pin->number);
135134
}
136135
}
137136
}
@@ -150,7 +149,9 @@ void alarm_pin_pinalarm_reset_alarms(bool deep_sleep, size_t n_alarms, const mp_
150149
// If we don't have WKUP enabled, ensure it's disabled
151150
// TODO; is this really required?
152151
void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
153-
if (!deep_wkup_enabled) {
152+
if (deep_wkup_enabled) {
154153
HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
154+
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
155+
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
155156
}
156157
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include STM32_HAL_H
3535

3636
STATIC volatile bool woke_up;
37+
STATIC uint32_t deep_sleep_ticks;
3738

3839
void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
3940
self->monotonic_time = monotonic_time;
@@ -95,7 +96,24 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_
9596
uint32_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs);
9697
uint32_t wakeup_in_ticks = wakeup_in_secs * 1024;
9798

99+
// In the deep sleep case, we can't start the timer until the USB delay has finished
100+
if (deep_sleep) {
101+
deep_sleep_ticks = wakeup_in_ticks;
102+
} else {
103+
deep_sleep_ticks = 0;
104+
}
98105
// Use alarm B, since port reserves A
106+
// If true deep sleep is called, it will either ignore or overwrite this depending on
107+
// whether it is shorter or longer than the USB delay
99108
stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback);
100109
stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,wakeup_in_ticks);
101110
}
111+
112+
void alarm_time_timealarm_prepare_for_deep_sleep(void) {
113+
if (deep_sleep_ticks) {
114+
// This is used for both fake and real deep sleep, so it still needs the callback
115+
stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback);
116+
stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,deep_sleep_ticks);
117+
deep_sleep_ticks = 0;
118+
}
119+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *
3838
bool alarm_time_timealarm_woke_us_up(void);
3939
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
4040
void alarm_time_timealarm_reset(void);
41+
42+
void alarm_time_timealarm_prepare_for_deep_sleep(void);

ports/stm/supervisor/port.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,9 @@ void _init(void)
369369
{
370370

371371
}
372+
373+
#if CIRCUITPY_ALARM
374+
// in case boards/xxx/board.c does not provide board_deinit()
375+
MP_WEAK void board_deinit(void) {
376+
}
377+
#endif

shared-bindings/alarm/__init__.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
9292
//| This allows the user to interrupt an existing program with ctrl-C,
9393
//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep.
9494
//| Thus, to use light sleep and save significant power,
95-
// it may be necessary to disconnect from the host.
95+
//| it may be necessary to disconnect from the host.
9696
//| """
9797
//| ...
9898
//|

0 commit comments

Comments
 (0)