From c2aa54ae661612e68768e10b76fd942af036ecda Mon Sep 17 00:00:00 2001 From: root Date: Thu, 5 Nov 2020 11:10:40 -0600 Subject: [PATCH 1/8] Check for Ctrl-C during sleeps --- ports/esp32s2/supervisor/port.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 0b9c03f747..2aa01cb152 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -203,7 +203,16 @@ void port_sleep_until_interrupt(void) { if (sleep_time_duration == 0) { return; } - vTaskDelayUntil(&sleep_time_set, sleep_time_duration); + // Need to run in a loop in order to check if CTRL-C was received + TickType_t start_ticks = 0; + while (sleep_time_duration > start_ticks ) { + vTaskDelayUntil(&sleep_time_set, 1); + if ( mp_hal_is_interrupted() ) { + mp_handle_pending(); + } + start_ticks = start_ticks + 1; + } + } From da04efbf2ed205d73de4f0082017ed15c3f59896 Mon Sep 17 00:00:00 2001 From: DavePutz Date: Thu, 5 Nov 2020 14:25:45 -0600 Subject: [PATCH 2/8] Fix missing include in port.c --- ports/esp32s2/supervisor/port.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 2aa01cb152..5cd6204405 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -30,6 +30,7 @@ #include "supervisor/port.h" #include "boards/board.h" #include "modules/module.h" +#include "py/runtime.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" From d948e6570f32b08de71b5d088ab445d2de3a7661 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 5 Nov 2020 21:27:21 -0600 Subject: [PATCH 3/8] Changes to handle Ctrl-C during sleep --- ports/esp32s2/supervisor/port.c | 32 ++++++++++++++------------------ ports/esp32s2/supervisor/usb.c | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 2aa01cb152..46de636276 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -30,6 +30,7 @@ #include "supervisor/port.h" #include "boards/board.h" #include "modules/module.h" +#include "py/runtime.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -54,6 +55,7 @@ uint32_t* heap; uint32_t heap_size; +extern TaskHandle_t xTaskToNotify; STATIC esp_timer_handle_t _tick_timer; @@ -188,34 +190,28 @@ void port_disable_tick(void) { esp_timer_stop(_tick_timer); } -TickType_t sleep_time_set; TickType_t sleep_time_duration; +uint32_t NotifyValue = 0; +BaseType_t notify_wait = 0; + void port_interrupt_after_ticks(uint32_t ticks) { - sleep_time_set = xTaskGetTickCount(); - sleep_time_duration = ticks / portTICK_PERIOD_MS; - // esp_sleep_enable_timer_wakeup(uint64_t time_in_us) + sleep_time_duration = (ticks * 100)/1024; + xTaskToNotify = xTaskGetCurrentTaskHandle(); } void port_sleep_until_interrupt(void) { - // FreeRTOS delay here maybe. - // Light sleep shuts down BLE and wifi. - // esp_light_sleep_start() + if (sleep_time_duration == 0) { return; } - // Need to run in a loop in order to check if CTRL-C was received - TickType_t start_ticks = 0; - while (sleep_time_duration > start_ticks ) { - vTaskDelayUntil(&sleep_time_set, 1); - if ( mp_hal_is_interrupted() ) { - mp_handle_pending(); - } - start_ticks = start_ticks + 1; - } - + notify_wait = xTaskNotifyWait(0x01,0x01,&NotifyValue, + sleep_time_duration ); + if (NotifyValue == 1) { + xTaskToNotify = NULL; + mp_handle_pending(); + } } - // Wrap main in app_main that the IDF expects. extern void main(void); void app_main(void) { diff --git a/ports/esp32s2/supervisor/usb.c b/ports/esp32s2/supervisor/usb.c index 1ad6af0470..86186d36b8 100644 --- a/ports/esp32s2/supervisor/usb.c +++ b/ports/esp32s2/supervisor/usb.c @@ -52,6 +52,8 @@ StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; +TaskHandle_t xTaskToNotify = NULL; + // USB Device Driver task // This top level thread process all usb events and invoke callbacks void usb_device_task(void* param) @@ -114,3 +116,21 @@ void init_usb_hardware(void) { usb_device_stack, &usb_device_taskdef); } +/** + * Callback invoked when received an "wanted" char. + * @param itf Interface index (for multiple cdc interfaces) + * @param wanted_char The wanted char (set previously) + */ +void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) +{ + (void) itf; // not used + // Workaround for using lib/utils/interrupt_char.c + // Compare mp_interrupt_char with wanted_char and ignore if not matched + if (mp_interrupt_char == wanted_char) { + tud_cdc_read_flush(); // flush read fifo + mp_keyboard_interrupt(); + if (xTaskToNotify != NULL) { + xTaskNotifyGive(xTaskToNotify); + } + } +} From 9adb77a2d0179f89c7402451f6b25be74629ffbd Mon Sep 17 00:00:00 2001 From: foamyguy Date: Sun, 8 Nov 2020 19:28:46 -0600 Subject: [PATCH 4/8] set moved true when unhiding tilegrid --- shared-module/displayio/TileGrid.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index e3642107f8..e8050a5397 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -83,10 +83,16 @@ bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self) { void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden) { self->hidden = hidden; + if(!hidden){ + self->moved = true; + } } void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden) { self->hidden_by_parent = hidden; + if(!hidden){ + self->moved = true; + } } bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_area_t* area) { From 46c9b28dd880d4e2e2764ab67f64356b175f5f98 Mon Sep 17 00:00:00 2001 From: foamyguy Date: Mon, 9 Nov 2020 18:14:31 -0600 Subject: [PATCH 5/8] use full_change instead of moved --- shared-module/displayio/TileGrid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index e8050a5397..19ea10e552 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -84,14 +84,14 @@ bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t* self) { void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t* self, bool hidden) { self->hidden = hidden; if(!hidden){ - self->moved = true; + self->full_change = true; } } void displayio_tilegrid_set_hidden_by_parent(displayio_tilegrid_t *self, bool hidden) { self->hidden_by_parent = hidden; if(!hidden){ - self->moved = true; + self->full_change = true; } } From 2d8ebfcf633a0e744e49fe14cc0025d8d7d348fc Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 10 Nov 2020 10:41:10 -0600 Subject: [PATCH 6/8] esp32s2: Correct port_stack_get_top() Closes #3649 --- ports/esp32s2/supervisor/port.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 0b9c03f747..a25bcce00a 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -148,7 +148,18 @@ uint32_t *port_stack_get_limit(void) { } uint32_t *port_stack_get_top(void) { - return port_stack_get_limit() + CONFIG_ESP_MAIN_TASK_STACK_SIZE / (sizeof(uint32_t) / sizeof(StackType_t)); + // The sizeof-arithmetic is so that the pointer arithmetic is done on units + // of uint32_t instead of units of StackType_t. StackType_t is an alias + // for a byte sized type. + // + // The main stack is bigger than CONFIG_ESP_MAIN_TASK_STACK_SIZE -- an + // "extra" size is added to it (TASK_EXTRA_STACK_SIZE). This total size is + // available as ESP_TASK_MAIN_STACK. Presumably TASK_EXTRA_STACK_SIZE is + // additional stack that can be used by the esp-idf runtime. But what's + // important for us is that some very outermost stack frames, such as + // pyexec_friendly_repl, could lie inside the "extra" area and be invisible + // to the garbage collector. + return port_stack_get_limit() + ESP_TASK_MAIN_STACK / (sizeof(uint32_t) / sizeof(StackType_t)); } supervisor_allocation _fixed_stack; From 44425b8d94d25709cb874b35f74a31da95bbfa38 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 10 Nov 2020 11:32:59 -0600 Subject: [PATCH 7/8] Requested review changes made --- ports/esp32s2/supervisor/port.c | 13 ++++++------- ports/esp32s2/supervisor/usb.c | 8 +++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 46de636276..4b9a4f7eff 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -55,8 +55,7 @@ uint32_t* heap; uint32_t heap_size; -extern TaskHandle_t xTaskToNotify; - +extern TaskHandle_t sleeping_circuitpython_task; STATIC esp_timer_handle_t _tick_timer; extern void esp_restart(void) NORETURN; @@ -191,23 +190,23 @@ void port_disable_tick(void) { } TickType_t sleep_time_duration; -uint32_t NotifyValue = 0; -BaseType_t notify_wait = 0; void port_interrupt_after_ticks(uint32_t ticks) { sleep_time_duration = (ticks * 100)/1024; - xTaskToNotify = xTaskGetCurrentTaskHandle(); + sleeping_circuitpython_task = xTaskGetCurrentTaskHandle(); } void port_sleep_until_interrupt(void) { + uint32_t NotifyValue = 0; + if (sleep_time_duration == 0) { return; } - notify_wait = xTaskNotifyWait(0x01,0x01,&NotifyValue, + xTaskNotifyWait(0x01,0x01,&NotifyValue, sleep_time_duration ); if (NotifyValue == 1) { - xTaskToNotify = NULL; + sleeping_circuitpython_task = NULL; mp_handle_pending(); } } diff --git a/ports/esp32s2/supervisor/usb.c b/ports/esp32s2/supervisor/usb.c index 86186d36b8..2bfcdfb125 100644 --- a/ports/esp32s2/supervisor/usb.c +++ b/ports/esp32s2/supervisor/usb.c @@ -52,7 +52,7 @@ StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -TaskHandle_t xTaskToNotify = NULL; +TaskHandle_t sleeping_circuitpython_task = NULL; // USB Device Driver task // This top level thread process all usb events and invoke callbacks @@ -129,8 +129,10 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) if (mp_interrupt_char == wanted_char) { tud_cdc_read_flush(); // flush read fifo mp_keyboard_interrupt(); - if (xTaskToNotify != NULL) { - xTaskNotifyGive(xTaskToNotify); + // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. + // So, we must notify the other task when a CTRL-C is received. + if (sleeping_circuitpython_task != NULL) { + xTaskNotifyGive(sleeping_circuitpython_task); } } } From fe7ed999393e369243319c48453cc2f7add3e7f0 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 10 Nov 2020 12:45:39 -0600 Subject: [PATCH 8/8] Split out extern declare to ports/esp32s2/supervisor/esp_port.h --- ports/esp32s2/supervisor/esp_port.h | 35 +++++++++++++++++++++++++++++ ports/esp32s2/supervisor/port.c | 3 ++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ports/esp32s2/supervisor/esp_port.h diff --git a/ports/esp32s2/supervisor/esp_port.h b/ports/esp32s2/supervisor/esp_port.h new file mode 100644 index 0000000000..1164666cda --- /dev/null +++ b/ports/esp32s2/supervisor/esp_port.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_SUPERVISOR_PORT_H +#define MICROPY_INCLUDED_ESP32S2_SUPERVISOR_PORT_H + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +extern TaskHandle_t sleeping_circuitpython_task; + +#endif // MICROPY_INCLUDED_ESP32S2_SUPERVISOR_PORT_H diff --git a/ports/esp32s2/supervisor/port.c b/ports/esp32s2/supervisor/port.c index 4b9a4f7eff..0ac2236d31 100644 --- a/ports/esp32s2/supervisor/port.c +++ b/ports/esp32s2/supervisor/port.c @@ -31,6 +31,7 @@ #include "boards/board.h" #include "modules/module.h" #include "py/runtime.h" +#include "supervisor/esp_port.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -55,7 +56,7 @@ uint32_t* heap; uint32_t heap_size; -extern TaskHandle_t sleeping_circuitpython_task; + STATIC esp_timer_handle_t _tick_timer; extern void esp_restart(void) NORETURN;