Skip to content

Commit bb77f1d

Browse files
committed
wip: initial code changes, starting from @tannewt's sleepio branch
2 parents 8d3a878 + 9a4efed commit bb77f1d

File tree

45 files changed

+1182
-74
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1182
-74
lines changed

locale/circuitpython.pot

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ msgstr ""
1717
"Content-Type: text/plain; charset=CHARSET\n"
1818
"Content-Transfer-Encoding: 8bit\n"
1919

20+
#: main.c
21+
msgid ""
22+
"\n"
23+
"\n"
24+
"------ soft reboot ------\n"
25+
msgstr ""
26+
2027
#: main.c
2128
msgid ""
2229
"\n"
@@ -982,6 +989,10 @@ msgstr ""
982989
msgid "I2SOut not available"
983990
msgstr ""
984991

992+
#: ports/esp32s2/common-hal/alarm_io/__init__.c
993+
msgid "IOs 0, 2 & 4 do not support internal pullup in sleep"
994+
msgstr ""
995+
985996
#: shared-bindings/aesio/aes.c
986997
#, c-format
987998
msgid "IV must be %d bytes long"
@@ -2793,6 +2804,10 @@ msgstr ""
27932804
msgid "invalid syntax for number"
27942805
msgstr ""
27952806

2807+
#: ports/esp32s2/common-hal/alarm_io/__init__.c
2808+
msgid "io must be rtc io"
2809+
msgstr ""
2810+
27962811
#: py/objtype.c
27972812
msgid "issubclass() arg 1 must be a class"
27982813
msgstr ""
@@ -3313,7 +3328,7 @@ msgstr ""
33133328
msgid "size is defined for ndarrays only"
33143329
msgstr ""
33153330

3316-
#: shared-bindings/time/__init__.c
3331+
#: shared-bindings/alarm_time/__init__.c shared-bindings/time/__init__.c
33173332
msgid "sleep length must be non-negative"
33183333
msgstr ""
33193334

@@ -3329,10 +3344,6 @@ msgstr ""
33293344
msgid "small int overflow"
33303345
msgstr ""
33313346

3332-
#: main.c
3333-
msgid "soft reboot\n"
3334-
msgstr ""
3335-
33363347
#: extmod/ulab/code/numerical/numerical.c
33373348
msgid "sort argument must be an ndarray"
33383349
msgstr ""
@@ -3417,6 +3428,10 @@ msgstr ""
34173428
msgid "threshold must be in the range 0-65536"
34183429
msgstr ""
34193430

3431+
#: ports/esp32s2/common-hal/alarm_time/__init__.c
3432+
msgid "time out of range"
3433+
msgstr ""
3434+
34203435
#: shared-bindings/time/__init__.c
34213436
msgid "time.struct_time() takes a 9-sequence"
34223437
msgstr ""
@@ -3462,6 +3477,10 @@ msgstr ""
34623477
msgid "trapz is defined for 1D arrays of equal length"
34633478
msgstr ""
34643479

3480+
#: ports/esp32s2/common-hal/alarm_io/__init__.c
3481+
msgid "trigger level must be 0 or 1"
3482+
msgstr ""
3483+
34653484
#: extmod/ulab/code/linalg/linalg.c
34663485
msgid "tuple index out of range"
34673486
msgstr ""
@@ -3604,6 +3623,10 @@ msgstr ""
36043623
msgid "vectors must have same lengths"
36053624
msgstr ""
36063625

3626+
#: ports/esp32s2/common-hal/alarm_io/__init__.c
3627+
msgid "wakeup conflict"
3628+
msgstr ""
3629+
36073630
#: shared-bindings/watchdog/WatchDogTimer.c
36083631
msgid "watchdog timeout must be greater than 0"
36093632
msgstr ""

main.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
#include "supervisor/shared/status_leds.h"
5858
#include "supervisor/shared/stack.h"
5959
#include "supervisor/serial.h"
60+
#include "supervisor/usb.h"
61+
62+
#include "shared-bindings/microcontroller/__init__.h"
6063

6164
#include "boards/board.h"
6265

@@ -85,6 +88,10 @@
8588
#include "common-hal/canio/CAN.h"
8689
#endif
8790

91+
#if CIRCUITPY_SLEEP
92+
#include "shared-bindings/sleep/__init__.h"
93+
#endif
94+
8895
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
8996
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
9097
if (lex == NULL) {
@@ -312,6 +319,14 @@ bool run_code_py(safe_mode_t safe_mode) {
312319
bool refreshed_epaper_display = false;
313320
#endif
314321
rgb_status_animation_t animation;
322+
bool ok = result->return_code != PYEXEC_EXCEPTION;
323+
#if CIRCUITPY_SLEEP
324+
// If USB isn't enumerated then deep sleep.
325+
if (ok && !supervisor_workflow_active() && supervisor_ticks_ms64() > CIRCUITPY_USB_ENUMERATION_DELAY * 1024) {
326+
common_hal_sleep_deep_sleep();
327+
}
328+
#endif
329+
// Show the animation every N seconds.
315330
prep_rgb_status_animation(&result, found_main, safe_mode, &animation);
316331
while (true) {
317332
RUN_BACKGROUND_TASKS;
@@ -344,8 +359,24 @@ bool run_code_py(safe_mode_t safe_mode) {
344359
refreshed_epaper_display = maybe_refresh_epaperdisplay();
345360
}
346361
#endif
347-
348-
tick_rgb_status_animation(&animation);
362+
bool animation_done = tick_rgb_status_animation(&animation);
363+
if (animation_done && supervisor_workflow_active()) {
364+
#if CIRCUITPY_SLEEP
365+
int64_t remaining_enumeration_wait = CIRCUITPY_USB_ENUMERATION_DELAY * 1024 - supervisor_ticks_ms64();
366+
// If USB isn't enumerated then deep sleep after our waiting period.
367+
if (ok && remaining_enumeration_wait < 0) {
368+
common_hal_sleep_deep_sleep();
369+
return; // Doesn't actually get here.
370+
}
371+
#endif
372+
// Wake up every so often to flash the error code.
373+
if (!ok) {
374+
port_interrupt_after_ticks(CIRCUITPY_FLASH_ERROR_PERIOD * 1024);
375+
} else {
376+
port_interrupt_after_ticks(remaining_enumeration_wait);
377+
}
378+
port_sleep_until_interrupt();
379+
}
349380
}
350381
}
351382

@@ -392,7 +423,9 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
392423
if (!skip_boot_output) {
393424
// Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write,
394425
// in case power is momentary or will fail shortly due to, say a low, battery.
395-
mp_hal_delay_ms(1500);
426+
if (common_hal_sleep_get_reset_reason() == RESET_REASON_POWER_VALID) {
427+
mp_hal_delay_ms(1500);
428+
}
396429

397430
// USB isn't up, so we can write the file.
398431
filesystem_set_internal_writable_by_usb(false);
@@ -511,7 +544,7 @@ int __attribute__((used)) main(void) {
511544
}
512545
if (exit_code == PYEXEC_FORCED_EXIT) {
513546
if (!first_run) {
514-
serial_write_compressed(translate("soft reboot\n"));
547+
serial_write_compressed(translate("\n\n------ soft reboot ------\n"));
515548
}
516549
first_run = false;
517550
skip_repl = run_code_py(safe_mode);

ports/atmel-samd/common-hal/microcontroller/__init__.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ void common_hal_mcu_reset(void) {
8484
reset();
8585
}
8686

87+
void common_hal_mcu_deep_sleep(void) {
88+
//deep sleep call here
89+
}
90+
8791
// The singleton microcontroller.Processor object, bound to microcontroller.cpu
8892
// It currently only has properties, and no state.
8993
const mcu_processor_obj_t common_hal_mcu_processor_obj = {

ports/cxd56/common-hal/microcontroller/__init__.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ void common_hal_mcu_reset(void) {
8181
boardctl(BOARDIOC_RESET, 0);
8282
}
8383

84+
void common_hal_mcu_deep_sleep(void) {
85+
//deep sleep call here
86+
}
87+
8488
STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = {
8589
{ MP_ROM_QSTR(MP_QSTR_UART2_RXD), MP_ROM_PTR(&pin_UART2_RXD) },
8690
{ MP_ROM_QSTR(MP_QSTR_UART2_TXD), MP_ROM_PTR(&pin_UART2_TXD) },
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
7+
* Copyright (c) 2019 Lucian Copeland for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "shared-bindings/alarm/__init__.h"
29+
#include "shared-bindings/alarm_io/__init__.h"
30+
#include "shared-bindings/alarm_time/__init__.h"
31+
32+
#include "esp_sleep.h"
33+
34+
void common_hal_alarm_disable_all(void) {
35+
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
36+
}
37+
38+
mp_obj_t common_hal_alarm_get_wake_alarm(void) {
39+
switch (esp_sleep_get_wakeup_cause()) {
40+
case ESP_SLEEP_WAKEUP_TIMER: ;
41+
//Wake up from timer.
42+
alarm_time_obj_t *timer = m_new_obj(alarm_time_obj_t);
43+
timer->base.type = &alarm_time_type;
44+
return timer;
45+
case ESP_SLEEP_WAKEUP_EXT0: ;
46+
//Wake up from GPIO
47+
alarm_io_obj_t *ext0 = m_new_obj(alarm_io_obj_t);
48+
ext0->base.type = &alarm_io_type;
49+
return ext0;
50+
case ESP_SLEEP_WAKEUP_TOUCHPAD:
51+
//TODO: implement TouchIO
52+
//Wake up from touch on pad, esp_sleep_get_touchpad_wakeup_status()
53+
break;
54+
case ESP_SLEEP_WAKEUP_UNDEFINED:
55+
default:
56+
//Not a deep sleep reset
57+
break;
58+
}
59+
return mp_const_none;
60+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "shared-bindings/alarm_io/__init__.h"
2+
3+
#include "esp_sleep.h"
4+
#include "driver/rtc_io.h"
5+
6+
mp_obj_t common_hal_alarm_io_pin_state (alarm_io_obj_t *self_in) {
7+
if (!rtc_gpio_is_valid_gpio(self_in->gpio)) {
8+
mp_raise_ValueError(translate("io must be rtc io"));
9+
}
10+
11+
if (self_in->pull && !self_in->level) {
12+
for (uint8_t i = 0; i<=4; i+=2) {
13+
if (self_in->gpio == i) {
14+
mp_raise_ValueError(translate("IOs 0, 2 & 4 do not support internal pullup in sleep"));
15+
}
16+
}
17+
}
18+
19+
switch(esp_sleep_enable_ext0_wakeup(self_in->gpio, self_in->level)) {
20+
case ESP_ERR_INVALID_ARG:
21+
mp_raise_ValueError(translate("trigger level must be 0 or 1"));
22+
case ESP_ERR_INVALID_STATE:
23+
mp_raise_RuntimeError(translate("wakeup conflict"));
24+
default:
25+
break;
26+
}
27+
28+
if (self_in->pull) { (self_in->level) ? rtc_gpio_pulldown_en(self_in->gpio) : rtc_gpio_pullup_en(self_in->gpio); }
29+
30+
return self_in;
31+
}
32+
33+
void common_hal_alarm_io_disable (void) {
34+
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_EXT0 | ESP_SLEEP_WAKEUP_EXT1);
35+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "esp_sleep.h"
2+
3+
#include "shared-bindings/alarm_time/__init__.h"
4+
5+
void common_hal_alarm_time_duration (uint32_t ms) {
6+
if (esp_sleep_enable_timer_wakeup((ms) * 1000) == ESP_ERR_INVALID_ARG) {
7+
mp_raise_ValueError(translate("time out of range"));
8+
}
9+
}
10+
11+
void common_hal_alarm_time_disable (void) {
12+
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
13+
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
* THE SOFTWARE.
2626
*/
2727

28-
#include "py/mphal.h"
2928
#include "py/obj.h"
29+
#include "py/mphal.h"
3030
#include "py/runtime.h"
3131

3232
#include "common-hal/microcontroller/Pin.h"
@@ -41,6 +41,8 @@
4141

4242
#include "freertos/FreeRTOS.h"
4343

44+
#include "esp_sleep.h"
45+
4446
void common_hal_mcu_delay_us(uint32_t delay) {
4547

4648
}
@@ -77,6 +79,10 @@ void common_hal_mcu_reset(void) {
7779
while(1);
7880
}
7981

82+
void common_hal_mcu_deep_sleep(void) {
83+
esp_deep_sleep_start();
84+
}
85+
8086
// The singleton microcontroller.Processor object, bound to microcontroller.cpu
8187
// It currently only has properties, and no state.
8288
const mcu_processor_obj_t common_hal_mcu_processor_obj = {

ports/esp32s2/mpconfigport.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ LONGINT_IMPL = MPZ
1414

1515
# These modules are implemented in ports/<port>/common-hal:
1616
CIRCUITPY_FULL_BUILD = 1
17+
CIRCUITPY_ALARM = 1
18+
CIRCUITPY_ALARM_IO = 1
19+
CIRCUITPY_ALARM_TIME = 1
20+
CIRCUITPY_ALARM_TOUCH = 1
1721
CIRCUITPY_AUDIOBUSIO = 0
1822
CIRCUITPY_AUDIOIO = 0
1923
CIRCUITPY_CANIO = 1
@@ -22,6 +26,7 @@ CIRCUITPY_FREQUENCYIO = 0
2226
CIRCUITPY_I2CPERIPHERAL = 0
2327
CIRCUITPY_ROTARYIO = 1
2428
CIRCUITPY_NVM = 0
29+
2530
# We don't have enough endpoints to include MIDI.
2631
CIRCUITPY_USB_MIDI = 0
2732
CIRCUITPY_WIFI = 1

ports/esp32s2/supervisor/port.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@
3636
#include "freertos/FreeRTOS.h"
3737
#include "freertos/task.h"
3838

39-
#include "common-hal/microcontroller/Pin.h"
4039
#include "common-hal/analogio/AnalogOut.h"
4140
#include "common-hal/busio/I2C.h"
4241
#include "common-hal/busio/SPI.h"
4342
#include "common-hal/busio/UART.h"
44-
#include "common-hal/pulseio/PulseIn.h"
4543
#include "common-hal/pwmio/PWMOut.h"
44+
#include "common-hal/pulseio/PulseIn.h"
45+
#include "common-hal/microcontroller/Pin.h"
4646
#include "common-hal/wifi/__init__.h"
4747
#include "supervisor/memory.h"
4848
#include "supervisor/shared/tick.h"

0 commit comments

Comments
 (0)