Skip to content

Commit f1792c8

Browse files
committed
Extract EXTI, create base sleep framework
1 parent 766e79a commit f1792c8

File tree

27 files changed

+934
-137
lines changed

27 files changed

+934
-137
lines changed

main.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ STATIC void start_mp(supervisor_allocation* heap) {
157157

158158
#if CIRCUITPY_ALARM
159159
// Record which alarm woke us up, if any. An object may be created so the heap must be functional.
160-
alarm_save_wake_alarm();
160+
common_hal_alarm_save_wake_alarm();
161161
// Reset alarm module only after we retrieved the wakeup alarm.
162-
alarm_reset();
162+
common_hal_alarm_reset();
163163
#endif
164164

165165
#if CIRCUITPY_NETWORK
@@ -357,7 +357,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
357357
// an alarm alerts faster than our USB delay or if we pretended to deep
358358
// sleep.
359359
#if CIRCUITPY_ALARM
360-
if (asleep && alarm_woken_from_sleep()) {
360+
if (asleep && common_hal_alarm_woken_from_sleep()) {
361361
serial_write_compressed(translate("Woken up by alarm.\n"));
362362
board_init();
363363
supervisor_set_run_reason(RUN_REASON_STARTUP);
@@ -409,7 +409,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
409409
if (!supervisor_workflow_active()) {
410410
// Enter true deep sleep. When we wake up we'll be back at the
411411
// top of main(), not in this loop.
412-
alarm_enter_deep_sleep();
412+
common_hal_alarm_enter_deep_sleep();
413413
// Does not return.
414414
} else {
415415
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
5454
},
5555
};
5656

57-
void alarm_reset(void) {
57+
void common_hal_alarm_reset(void) {
5858
alarm_sleep_memory_reset();
5959
alarm_pin_pinalarm_reset();
6060
alarm_time_timealarm_reset();
@@ -75,10 +75,12 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
7575
return esp_sleep_get_wakeup_cause();
7676
}
7777

78-
bool alarm_woken_from_sleep(void) {
78+
bool common_hal_alarm_woken_from_sleep(void) {
7979
return _get_wakeup_cause() != ESP_SLEEP_WAKEUP_UNDEFINED;
8080
}
8181

82+
// When called to populate the global dict, the module functions create new alarm objects.
83+
// Otherwise, they scan the existing alarms for matches.
8284
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
8385
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
8486
switch (cause) {
@@ -104,6 +106,8 @@ STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
104106
return mp_const_none;
105107
}
106108

109+
// This function is used to create a new alarm object for the global dict after deep sleep,
110+
// rather than finding an existing one during runtime.
107111
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
108112
return _get_wake_alarm(0, NULL);
109113
}
@@ -120,8 +124,9 @@ STATIC void _idle_until_alarm(void) {
120124
while (!mp_hal_is_interrupted()) {
121125
RUN_BACKGROUND_TASKS;
122126
// Allow ctrl-C interrupt.
123-
if (alarm_woken_from_sleep()) {
124-
alarm_save_wake_alarm();
127+
if (common_hal_alarm_woken_from_sleep()) {
128+
// This saves the return of common_hal_alarm_get_wake_alarm through Shared Bindings
129+
common_hal_alarm_save_wake_alarm();
125130
return;
126131
}
127132
port_idle_until_interrupt();
@@ -139,15 +144,15 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
139144
}
140145

141146
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
142-
alarm_reset();
147+
alarm_pin_pinalarm_reset_alarms(n_alarms, alarms);
143148
return wake_alarm;
144149
}
145150

146151
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
147152
_setup_sleep_alarms(true, n_alarms, alarms);
148153
}
149154

150-
void NORETURN alarm_enter_deep_sleep(void) {
155+
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
151156
alarm_pin_pinalarm_prepare_for_deep_sleep();
152157
alarm_touch_touchalarm_prepare_for_deep_sleep();
153158

ports/esp32s2/common-hal/alarm/__init__.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@
3131

3232
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj;
3333

34-
extern void alarm_reset(void);
34+
extern void common_hal_alarm_reset(void);
3535

3636
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H

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

Lines changed: 0 additions & 35 deletions
This file was deleted.

ports/stm/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ SRC_C += \
220220
boards/$(BOARD)/board.c \
221221
boards/$(BOARD)/pins.c \
222222
peripherals/timers.c \
223+
peripherals/exti.c \
224+
peripherals/rtc.c \
223225
peripherals/stm32$(MCU_SERIES_LOWER)/clocks.c \
224226
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/pins.c \
225227
peripherals/stm32$(MCU_SERIES_LOWER)/$(MCU_VARIANT_LOWER)/gpio.c \

ports/stm/boards/feather_stm32f405_express/board.c

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

3939
}
40+
41+
void board_deinit(void) {
42+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <string.h>
28+
29+
#include "py/runtime.h"
30+
#include "common-hal/alarm/SleepMemory.h"
31+
32+
void alarm_sleep_memory_reset(void) {
33+
34+
}
35+
36+
uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) {
37+
return 0;
38+
}
39+
40+
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) {
41+
return false;
42+
}
43+
44+
void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) {
45+
return;
46+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H
28+
#define MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H
29+
30+
#include "py/obj.h"
31+
32+
typedef struct {
33+
mp_obj_base_t base;
34+
} alarm_sleep_memory_obj_t;
35+
36+
extern void alarm_sleep_memory_reset(void);
37+
38+
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_ALARM_SLEEPMEMORY_H

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

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 Lucian Copeland for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "py/gc.h"
28+
#include "py/obj.h"
29+
#include "py/objtuple.h"
30+
#include "py/runtime.h"
31+
#include "lib/utils/interrupt_char.h"
32+
33+
#include "shared-bindings/alarm/__init__.h"
34+
#include "shared-bindings/alarm/pin/PinAlarm.h"
35+
#include "shared-bindings/alarm/time/TimeAlarm.h"
36+
37+
#include "shared-bindings/microcontroller/__init__.h"
38+
39+
#include "supervisor/port.h"
40+
#include "supervisor/shared/workflow.h"
41+
42+
#define STM_WAKEUP_GPIO 1
43+
#define STM_WAKEUP_TIMER 2
44+
45+
void common_hal_alarm_reset(void) {
46+
// alarm_sleep_memory_reset();
47+
alarm_pin_pinalarm_reset();
48+
// alarm_time_timealarm_reset();
49+
// alarm_touch_touchalarm_reset();
50+
// esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
51+
}
52+
53+
STATIC uint8_t _get_wakeup_cause(void) {
54+
if (alarm_pin_pinalarm_woke_us_up()) {
55+
return STM_WAKEUP_GPIO;
56+
}
57+
if (alarm_time_timealarm_woke_us_up()) {
58+
return STM_WAKEUP_TIMER;
59+
}
60+
return 0;
61+
}
62+
63+
bool common_hal_alarm_woken_from_sleep(void) {
64+
return _get_wakeup_cause() != 0;
65+
}
66+
67+
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
68+
if (alarm_pin_pinalarm_woke_us_up()) {
69+
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
70+
}
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;
93+
return mp_const_none;
94+
}
95+
96+
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
97+
//return _get_wake_alarm(0, NULL);
98+
return mp_const_none;
99+
}
100+
101+
// Set up light sleep or deep sleep alarms.
102+
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
103+
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
104+
// alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
105+
// alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
106+
}
107+
108+
STATIC void _idle_until_alarm(void) {
109+
// Poll for alarms.
110+
while (!mp_hal_is_interrupted()) {
111+
RUN_BACKGROUND_TASKS;
112+
// Allow ctrl-C interrupt.
113+
if (common_hal_alarm_woken_from_sleep()) {
114+
common_hal_alarm_save_wake_alarm();
115+
return;
116+
}
117+
// port_idle_until_interrupt();
118+
}
119+
}
120+
121+
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
122+
// if (supervisor_workflow_active()) {
123+
// mp_raise_NotImplementedError(translate("Cannot sleep with USB connected"));
124+
// }
125+
_setup_sleep_alarms(false, n_alarms, alarms);
126+
127+
// If USB is active, only pretend to sleep. Otherwise, light sleep
128+
if (supervisor_workflow_active()) {
129+
_idle_until_alarm();
130+
} else {
131+
port_disable_tick();
132+
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
133+
port_enable_tick();
134+
}
135+
136+
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
137+
common_hal_alarm_reset();
138+
return wake_alarm;
139+
}
140+
141+
void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
142+
_setup_sleep_alarms(true, n_alarms, alarms);
143+
}
144+
145+
//#define NORETURN __attribute__((noreturn))
146+
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
147+
// alarm_pin_pinalarm_prepare_for_deep_sleep();
148+
// alarm_touch_touchalarm_prepare_for_deep_sleep();
149+
while(1);
150+
151+
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
152+
// We don't need to worry about resetting them in the interim.
153+
// esp_deep_sleep_start();
154+
}
155+
156+
void common_hal_alarm_gc_collect(void) {
157+
gc_collect_ptr(common_hal_alarm_get_wake_alarm());
158+
}

0 commit comments

Comments
 (0)