Skip to content

Commit 171efd5

Browse files
authored
Merge pull request adafruit#3830 from tannewt/pin_alarm
Add pin alarming
2 parents 1b7fbaf + 6c7e6ab commit 171efd5

File tree

33 files changed

+541
-210
lines changed

33 files changed

+541
-210
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git
153153
[submodule "ports/esp32s2/esp-idf"]
154154
path = ports/esp32s2/esp-idf
155-
url = https://github.com/jepler/esp-idf.git
155+
url = https://github.com/adafruit/esp-idf.git
156156
[submodule "ports/esp32s2/certificates/nina-fw"]
157157
path = ports/esp32s2/certificates/nina-fw
158158
url = https://github.com/adafruit/nina-fw.git

locale/circuitpython.pot

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: PACKAGE VERSION\n"
1010
"Report-Msgid-Bugs-To: \n"
11-
"POT-Creation-Date: 2020-12-23 16:41-0500\n"
11+
"POT-Creation-Date: 2020-12-23 23:04-0500\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <[email protected]>\n"
@@ -20,7 +20,13 @@ msgstr ""
2020
#: main.c
2121
msgid ""
2222
"\n"
23-
"Code done running. Waiting for reload.\n"
23+
"Code done running.\n"
24+
msgstr ""
25+
26+
#: main.c
27+
msgid ""
28+
"\n"
29+
"Code stopped by auto-reload.\n"
2430
msgstr ""
2531

2632
#: supervisor/shared/safe_mode.c
@@ -534,6 +540,18 @@ msgstr ""
534540
msgid "Call super().__init__() before accessing native object."
535541
msgstr ""
536542

543+
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
544+
msgid "Can only alarm on RTC IO from deep sleep."
545+
msgstr ""
546+
547+
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
548+
msgid "Can only alarm on one low pin while others alarm high from deep sleep."
549+
msgstr ""
550+
551+
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
552+
msgid "Can only alarm on two low pins from deep sleep."
553+
msgstr ""
554+
537555
#: ports/nrf/common-hal/_bleio/Characteristic.c
538556
msgid "Can't set CCCD on local Characteristic"
539557
msgstr ""
@@ -566,6 +584,10 @@ msgstr ""
566584
msgid "Cannot output both channels on the same pin"
567585
msgstr ""
568586

587+
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
588+
msgid "Cannot pull on input-only pin."
589+
msgstr ""
590+
569591
#: shared-module/bitbangio/SPI.c
570592
msgid "Cannot read without MISO pin."
571593
msgstr ""
@@ -609,6 +631,10 @@ msgstr ""
609631
msgid "Cannot vary frequency on a timer that is already in use"
610632
msgstr ""
611633

634+
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
635+
msgid "Cannot wake on pin edge. Only level."
636+
msgstr ""
637+
612638
#: shared-module/bitbangio/SPI.c
613639
msgid "Cannot write without MOSI pin."
614640
msgstr ""
@@ -1458,7 +1484,7 @@ msgid ""
14581484
"%d bpp given"
14591485
msgstr ""
14601486

1461-
#: ports/esp32s2/common-hal/alarm/__init__.c
1487+
#: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
14621488
msgid "Only one alarm.time alarm can be set."
14631489
msgstr ""
14641490

@@ -1520,10 +1546,6 @@ msgstr ""
15201546
msgid "Pin number already reserved by EXTI"
15211547
msgstr ""
15221548

1523-
#: ports/esp32s2/common-hal/alarm/__init__.c
1524-
msgid "PinAlarm not yet implemented"
1525-
msgstr ""
1526-
15271549
#: shared-bindings/rgbmatrix/RGBMatrix.c
15281550
#, c-format
15291551
msgid ""
@@ -1564,7 +1586,7 @@ msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n"
15641586
msgstr ""
15651587

15661588
#: main.c
1567-
msgid "Pretending to deep sleep until alarm, any key or file write.\n"
1589+
msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n"
15681590
msgstr ""
15691591

15701592
#: shared-bindings/digitalio/DigitalInOut.c

main.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,10 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
260260
STATIC bool run_code_py(safe_mode_t safe_mode) {
261261
bool serial_connected_at_start = serial_connected();
262262
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
263-
if (serial_connected_at_start) {
264-
serial_write("\n");
265-
print_code_py_status_message(safe_mode);
266-
}
263+
serial_write("\n");
264+
print_code_py_status_message(safe_mode);
265+
print_safe_mode_message(safe_mode);
266+
serial_write("\n");
267267
#endif
268268

269269
pyexec_result_t result;
@@ -307,16 +307,17 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
307307
if (result.return_code & PYEXEC_FORCED_EXIT) {
308308
return reload_requested;
309309
}
310+
311+
if (reload_requested && result.return_code == PYEXEC_EXCEPTION) {
312+
serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
313+
} else {
314+
serial_write_compressed(translate("\nCode done running.\n"));
315+
}
310316
}
311317

312318
// Program has finished running.
313319

314-
// Display a different completion message if the user has no USB attached (cannot save files)
315-
if (!serial_connected_at_start) {
316-
serial_write_compressed(translate("\nCode done running. Waiting for reload.\n"));
317-
}
318-
319-
bool serial_connected_before_animation = false;
320+
bool serial_connected_before_animation = serial_connected();
320321
#if CIRCUITPY_DISPLAYIO
321322
bool refreshed_epaper_display = false;
322323
#endif
@@ -409,7 +410,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
409410
alarm_enter_deep_sleep();
410411
// Does not return.
411412
} else {
412-
serial_write_compressed(translate("Pretending to deep sleep until alarm, any key or file write.\n"));
413+
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
413414
}
414415
}
415416
}
@@ -615,6 +616,10 @@ void gc_collect(void) {
615616

616617
background_callback_gc_collect();
617618

619+
#if CIRCUITPY_ALARM
620+
common_hal_alarm_gc_collect();
621+
#endif
622+
618623
#if CIRCUITPY_DISPLAYIO
619624
displayio_gc_collect();
620625
#endif

ports/esp32s2/Makefile

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ LDFLAGS += -L$(BUILD)/esp-idf/esp-idf/esp32s2 \
145145
-Tesp32s2.peripherals.ld \
146146
-Lesp-idf/components/esp_rom/esp32s2/ld \
147147
-Tesp32s2.rom.ld \
148-
-Tesp32s2.rom.api.ld \
149148
-Tesp32s2.rom.libgcc.ld \
150149
-Tesp32s2.rom.newlib-data.ld \
151150
-Tesp32s2.rom.newlib-funcs.ld \
@@ -278,7 +277,7 @@ menuconfig: $(BUILD)/esp-idf/config
278277
# qstr builds include headers so we need to make sure they are up to date
279278
$(HEADER_BUILD)/qstr.split: | $(BUILD)/esp-idf/config/sdkconfig.h
280279

281-
ESP_IDF_COMPONENTS_LINK = freertos log hal esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom esp-tls
280+
ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp-tls
282281

283282
ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc
284283

@@ -290,11 +289,11 @@ ESP_IDF_WIFI_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_WIFI_COMPONENT
290289
MBEDTLS_COMPONENTS_LINK = crypto tls x509
291290
MBEDTLS_COMPONENTS_LINK_EXPANDED = $(foreach component, $(MBEDTLS_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libmbed$(component).a)
292291

293-
BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libxt_hal.a
292+
BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libhal.a
294293
BINARY_WIFI_BLOBS = libcoexist.a libcore.a libespnow.a libmesh.a libnet80211.a libpp.a librtc.a libsmartconfig.a libphy.a
295294
BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/esp32s2/, $(BINARY_WIFI_BLOBS))
296295

297-
ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a esp-idf/components/xtensa/esp32s2/libxt_hal.a
296+
ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a
298297
ESP_AUTOGEN_LD = $(BUILD)/esp-idf/esp-idf/esp32s2/esp32s2_out.ld $(BUILD)/esp-idf/esp-idf/esp32s2/ld/esp32s2.project.ld
299298

300299
FLASH_FLAGS = --flash_mode $(CIRCUITPY_ESP_FLASH_MODE) --flash_freq $(CIRCUITPY_ESP_FLASH_FREQ) --flash_size $(CIRCUITPY_ESP_FLASH_SIZE)
@@ -310,7 +309,6 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h
310309
esp-idf/esp32s2/ld/esp32s2.project.ld \
311310
esp-idf/esp_event/libesp_event.a \
312311
esp-idf/esp_netif/libesp_netif.a \
313-
esp-idf/esp_rom/libesp_rom.a \
314312
esp-idf/esp_system/libesp_system.a \
315313
esp-idf/esp_wifi/libesp_wifi.a \
316314
esp-idf/lwip/liblwip.a \

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

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
* THE SOFTWARE.
2626
*/
2727

28+
#include "py/gc.h"
2829
#include "py/obj.h"
2930
#include "py/objtuple.h"
3031
#include "py/runtime.h"
3132

33+
#include "shared-bindings/alarm/__init__.h"
3234
#include "shared-bindings/alarm/pin/PinAlarm.h"
3335
#include "shared-bindings/alarm/SleepMemory.h"
3436
#include "shared-bindings/alarm/time/TimeAlarm.h"
@@ -38,20 +40,21 @@
3840
#include "supervisor/port.h"
3941
#include "supervisor/shared/workflow.h"
4042

41-
#include "common-hal/alarm/__init__.h"
42-
4343
#include "esp_sleep.h"
4444

45+
#include "components/soc/soc/esp32s2/include/soc/rtc_cntl_reg.h"
46+
#include "components/driver/include/driver/uart.h"
47+
4548
// Singleton instance of SleepMemory.
4649
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
4750
.base = {
4851
.type = &alarm_sleep_memory_type,
4952
},
5053
};
5154

52-
5355
void alarm_reset(void) {
5456
alarm_time_timealarm_reset();
57+
alarm_pin_pinalarm_reset();
5558
alarm_sleep_memory_reset();
5659
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
5760
}
@@ -60,6 +63,9 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
6063
if (alarm_time_timealarm_woke_us_up()) {
6164
return ESP_SLEEP_WAKEUP_TIMER;
6265
}
66+
if (alarm_pin_pinalarm_woke_us_up()) {
67+
return ESP_SLEEP_WAKEUP_GPIO;
68+
}
6369

6470
return esp_sleep_get_wakeup_cause();
6571
}
@@ -69,14 +75,16 @@ bool alarm_woken_from_sleep(void) {
6975
}
7076

7177
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
72-
switch (_get_wakeup_cause()) {
78+
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
79+
switch (cause) {
7380
case ESP_SLEEP_WAKEUP_TIMER: {
7481
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
7582
}
7683

77-
case ESP_SLEEP_WAKEUP_EXT0: {
78-
// TODO: implement pin alarm wake.
79-
break;
84+
case ESP_SLEEP_WAKEUP_GPIO:
85+
case ESP_SLEEP_WAKEUP_EXT0:
86+
case ESP_SLEEP_WAKEUP_EXT1: {
87+
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
8088
}
8189

8290
case ESP_SLEEP_WAKEUP_TOUCHPAD:
@@ -98,24 +106,8 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
98106

99107
// Set up light sleep or deep sleep alarms.
100108
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
101-
bool time_alarm_set = false;
102-
alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL;
103-
104-
for (size_t i = 0; i < n_alarms; i++) {
105-
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) {
106-
mp_raise_NotImplementedError(translate("PinAlarm not yet implemented"));
107-
} else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) {
108-
if (time_alarm_set) {
109-
mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
110-
}
111-
time_alarm = MP_OBJ_TO_PTR(alarms[i]);
112-
time_alarm_set = true;
113-
}
114-
}
115-
116-
if (time_alarm_set) {
117-
alarm_time_timealarm_set_alarm(time_alarm);
118-
}
109+
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
110+
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
119111
}
120112

121113
STATIC void _idle_until_alarm(void) {
@@ -131,21 +123,16 @@ STATIC void _idle_until_alarm(void) {
131123
}
132124
}
133125

134-
// Is it safe to do a light sleep? Check whether WiFi is on or there are
135-
// other ongoing tasks that should not be shut down.
136-
STATIC bool _light_sleep_ok(void) {
137-
return !common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) && !supervisor_workflow_active();
138-
}
139-
140126
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
141127
_setup_sleep_alarms(false, n_alarms, alarms);
142128

143-
// Light sleep can break some functionality so only do it when possible. Otherwise we idle.
144-
if (_light_sleep_ok()) {
145-
esp_light_sleep_start();
146-
} else {
147-
_idle_until_alarm();
129+
// We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
130+
_idle_until_alarm();
131+
132+
if (mp_hal_is_interrupted()) {
133+
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
148134
}
135+
149136
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
150137
alarm_reset();
151138
return wake_alarm;
@@ -156,7 +143,12 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
156143
}
157144

158145
void NORETURN alarm_enter_deep_sleep(void) {
146+
alarm_pin_pinalarm_prepare_for_deep_sleep();
159147
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
160148
// We don't need to worry about resetting them in the interim.
161149
esp_deep_sleep_start();
162150
}
151+
152+
void common_hal_alarm_gc_collect(void) {
153+
gc_collect_ptr(alarm_get_wake_alarm());
154+
}

0 commit comments

Comments
 (0)