Skip to content

Commit 35ee4ad

Browse files
authored
Merge pull request #4388 from hierophect/stm-alarm
STM32: Alarms and sleep
2 parents c50847c + 849e3a7 commit 35ee4ad

File tree

30 files changed

+1369
-221
lines changed

30 files changed

+1369
-221
lines changed

locale/circuitpython.pot

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,10 @@ msgstr ""
846846
msgid "Data too large for advertisement packet"
847847
msgstr ""
848848

849+
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
850+
msgid "Deep sleep pins must use a rising edge with pulldown"
851+
msgstr ""
852+
849853
#: shared-bindings/audiobusio/PDMIn.c
850854
msgid "Destination capacity is smaller than destination_length."
851855
msgstr ""
@@ -1670,6 +1674,10 @@ msgid ""
16701674
"Only Windows format, uncompressed BMP supported: given header size is %d"
16711675
msgstr ""
16721676

1677+
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
1678+
msgid "Only edge detection is available on this hardware"
1679+
msgstr ""
1680+
16731681
#: shared-module/displayio/OnDiskBitmap.c
16741682
#, c-format
16751683
msgid ""
@@ -1683,6 +1691,7 @@ msgstr ""
16831691

16841692
#: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
16851693
#: ports/nrf/common-hal/alarm/time/TimeAlarm.c
1694+
#: ports/stm/common-hal/alarm/time/TimeAlarm.c
16861695
msgid "Only one alarm.time alarm can be set."
16871696
msgstr ""
16881697

@@ -1758,6 +1767,10 @@ msgstr ""
17581767
msgid "Permission denied"
17591768
msgstr ""
17601769

1770+
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
1771+
msgid "Pin cannot wake from Deep Sleep"
1772+
msgstr ""
1773+
17611774
#: ports/raspberrypi/bindings/rp2pio/StateMachine.c
17621775
msgid "Pin count must be at least 1"
17631776
msgstr ""
@@ -1776,6 +1789,11 @@ msgstr ""
17761789
msgid "Pin does not have ADC capabilities"
17771790
msgstr ""
17781791

1792+
#: ports/stm/common-hal/alarm/pin/PinAlarm.c
1793+
#: ports/stm/common-hal/pulseio/PulseIn.c
1794+
msgid "Pin interrupt already in use"
1795+
msgstr ""
1796+
17791797
#: shared-bindings/adafruit_bus_device/SPIDevice.c
17801798
#: shared-bindings/digitalio/DigitalInOut.c
17811799
msgid "Pin is input only"
@@ -1789,10 +1807,6 @@ msgstr ""
17891807
msgid "Pin must support hardware interrupts"
17901808
msgstr ""
17911809

1792-
#: ports/stm/common-hal/pulseio/PulseIn.c
1793-
msgid "Pin number already reserved by EXTI"
1794-
msgstr ""
1795-
17961810
#: shared-bindings/rgbmatrix/RGBMatrix.c
17971811
#, c-format
17981812
msgid ""
@@ -2013,6 +2027,10 @@ msgstr ""
20132027
msgid "Size not supported"
20142028
msgstr ""
20152029

2030+
#: ports/stm/common-hal/alarm/SleepMemory.c
2031+
msgid "Sleep Memory not available"
2032+
msgstr ""
2033+
20162034
#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c
20172035
msgid "Slice and value different lengths."
20182036
msgstr ""
@@ -2153,6 +2171,10 @@ msgstr ""
21532171
msgid "Total data to write is larger than %q"
21542172
msgstr ""
21552173

2174+
#: ports/stm/common-hal/alarm/touch/TouchAlarm.c
2175+
msgid "Touch alarms not available"
2176+
msgstr ""
2177+
21562178
#: py/obj.c
21572179
msgid "Traceback (most recent call last):\n"
21582180
msgstr ""

main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,13 +297,17 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
297297
stack_resize();
298298
filesystem_flush();
299299
supervisor_allocation* heap = allocate_remaining_memory();
300+
301+
// Prepare the VM state. Includes an alarm check/reset for sleep.
300302
start_mp(heap);
301303

302304
#if CIRCUITPY_USB
303305
usb_setup_with_vm();
304306
#endif
305307

308+
// This is where the user's python code is actually executed:
306309
found_main = maybe_run_list(supported_filenames, &result);
310+
// If that didn't work, double check the extensions
307311
#if CIRCUITPY_FULL_BUILD
308312
if (!found_main){
309313
found_main = maybe_run_list(double_extension_filenames, &result);
@@ -313,6 +317,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
313317
}
314318
#endif
315319

320+
// Finished executing python code. Cleanup includes a board reset.
316321
cleanup_after_vm(heap);
317322

318323
if (result.return_code & PYEXEC_FORCED_EXIT) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ 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
}
@@ -121,6 +125,7 @@ STATIC void _idle_until_alarm(void) {
121125
RUN_BACKGROUND_TASKS;
122126
// Allow ctrl-C interrupt.
123127
if (common_hal_alarm_woken_from_sleep()) {
128+
// This saves the return of common_hal_alarm_get_wake_alarm through Shared Bindings
124129
shared_alarm_save_wake_alarm();
125130
return;
126131
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
3939
#include "components/xtensa/include/esp_debug_helpers.h"
4040

41-
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
41+
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, const mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
4242
if (edge) {
4343
mp_raise_ValueError(translate("Cannot wake on pin edge. Only level."));
4444
}
@@ -51,7 +51,7 @@ void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu
5151
self->pull = pull;
5252
}
5353

54-
mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
54+
const mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
5555
return self->pin;
5656
}
5757

@@ -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) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
typedef struct {
3131
mp_obj_base_t base;
32-
mcu_pin_obj_t *pin;
32+
const mcu_pin_obj_t *pin;
3333
bool value;
3434
bool pull;
3535
} alarm_pin_pinalarm_obj_t;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ static bool pins_configured = false;
5050
extern uint32_t reset_reason_saved;
5151
extern void dbg_dump_GPIOregs(void);
5252

53-
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
53+
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, const mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
5454
if (edge) {
5555
mp_raise_ValueError(translate("Cannot wake on pin edge. Only level."));
5656
}
@@ -62,7 +62,7 @@ void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu
6262
self->pull = pull;
6363
}
6464

65-
mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
65+
const mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
6666
return self->pin;
6767
}
6868

ports/nrf/common-hal/alarm/pin/PinAlarm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
typedef struct {
3131
mp_obj_base_t base;
32-
mcu_pin_obj_t *pin;
32+
const mcu_pin_obj_t *pin;
3333
bool value;
3434
bool pull;
3535
} alarm_pin_pinalarm_obj_t;

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/stm32f411ce_blackpill_with_flash/mpconfigboard.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,9 @@ MCU_PACKAGE = UFQFPN48
1717
LD_COMMON = boards/common_default.ld
1818
LD_FILE = boards/STM32F411_nvm_nofs.ld
1919

20+
# Too big for the flash
21+
CIRCUITPY_AUDIOCORE = 0
22+
CIRCUITPY_AUDIOPWMIO = 0
23+
CIRCUITPY_SYNTHIO = 0
2024
CIRCUITPY_BITMAPTOOLS = 0
2125
CIRCUITPY_VECTORIO = 0
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
mp_raise_NotImplementedError(translate("Sleep Memory not available"));
38+
return 0;
39+
}
40+
41+
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) {
42+
mp_raise_NotImplementedError(translate("Sleep Memory not available"));
43+
return false;
44+
}
45+
46+
void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t *values, uint32_t len) {
47+
mp_raise_NotImplementedError(translate("Sleep Memory not available"));
48+
return;
49+
}
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

0 commit comments

Comments
 (0)