From 686012426d0c066aa0b8562612808e973d0fa645 Mon Sep 17 00:00:00 2001 From: Michael Himing Date: Sat, 19 Mar 2022 12:40:01 +1100 Subject: [PATCH 1/2] Espressif: Fix interrupts in UART workflow --- ports/espressif/common-hal/busio/UART.c | 50 ++++++++++++++++++++++++- ports/espressif/common-hal/busio/UART.h | 3 ++ supervisor/shared/status_leds.h | 4 +- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/ports/espressif/common-hal/busio/UART.c b/ports/espressif/common-hal/busio/UART.c index 5aac1635af..0c44107e60 100644 --- a/ports/espressif/common-hal/busio/UART.c +++ b/ports/espressif/common-hal/busio/UART.c @@ -30,16 +30,47 @@ #include "components/driver/include/driver/uart.h" #include "mpconfigport.h" +#include "shared/readline/readline.h" #include "shared/runtime/interrupt_char.h" #include "py/gc.h" #include "py/mperrno.h" #include "py/runtime.h" #include "py/stream.h" +#include "supervisor/port.h" #include "supervisor/shared/translate.h" #include "supervisor/shared/tick.h" uint8_t never_reset_uart_mask = 0; +static void uart_event_task(void *param) { + busio_uart_obj_t *self = param; + uart_event_t event; + while (true) { + if (xQueueReceive(self->event_queue, &event, portMAX_DELAY)) { + switch (event.type) { + case UART_PATTERN_DET: + // When the debug uart receives CTRL+C, wake the main task and schedule a keyboard interrupt + if (self->is_debug) { + port_wake_main_task(); + if (mp_interrupt_char == CHAR_CTRL_C) { + uart_flush(self->uart_num); + mp_sched_keyboard_interrupt(); + } + } + break; + case UART_DATA: + // When the debug uart receives any key, wake the main task + if (self->is_debug) { + port_wake_main_task(); + } + break; + default: + break; + } + } + } +} + void uart_reset(void) { for (uart_port_t num = 0; num < UART_NUM_MAX; num++) { // Ignore the UART used by the IDF. @@ -125,10 +156,26 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint8_t rx_threshold = UART_FIFO_LEN - 8; // Install the driver before we change the settings. - if (uart_driver_install(self->uart_num, receiver_buffer_size, 0, 0, NULL, 0) != ESP_OK || + if (uart_driver_install(self->uart_num, receiver_buffer_size, 0, 20, &self->event_queue, 0) != ESP_OK || uart_set_mode(self->uart_num, mode) != ESP_OK) { mp_raise_ValueError(translate("Could not initialize UART")); } + // On the debug uart, enable pattern detection to look for CTRL+C + #ifdef CIRCUITPY_DEBUG_UART_RX + if (rx == CIRCUITPY_DEBUG_UART_RX) { + self->is_debug = true; + uart_enable_pattern_det_baud_intr(self->uart_num, CHAR_CTRL_C, 1, 1, 0, 0); + } + #endif + // Start a task to listen for uart events + xTaskCreatePinnedToCore( + uart_event_task, + "uart_event_task", + configMINIMAL_STACK_SIZE, + self, + CONFIG_PTHREAD_TASK_PRIO_DEFAULT, + &self->event_task, + xPortGetCoreID()); uart_set_hw_flow_ctrl(self->uart_num, flow_control, rx_threshold); // Set baud rate @@ -230,6 +277,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { if (common_hal_busio_uart_deinited(self)) { return; } + vTaskDelete(self->event_task); uart_driver_delete(self->uart_num); common_hal_reset_pin(self->rx_pin); diff --git a/ports/espressif/common-hal/busio/UART.h b/ports/espressif/common-hal/busio/UART.h index 1e0ed3dd99..ca5b3f925b 100644 --- a/ports/espressif/common-hal/busio/UART.h +++ b/ports/espressif/common-hal/busio/UART.h @@ -42,6 +42,9 @@ typedef struct { uint8_t character_bits; bool rx_error; uint32_t timeout_ms; + bool is_debug; + QueueHandle_t event_queue; + TaskHandle_t event_task; } busio_uart_obj_t; void uart_reset(void); diff --git a/supervisor/shared/status_leds.h b/supervisor/shared/status_leds.h index 3d2fa978a8..99aa0277d6 100644 --- a/supervisor/shared/status_leds.h +++ b/supervisor/shared/status_leds.h @@ -44,8 +44,8 @@ // To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and // neopixel_write implemented. -#define CIRCUITPY_PWM_RGB_LED defined(CIRCUITPY_RGB_STATUS_R) || defined(CIRCUITPY_RGB_STATUS_G) || defined(CIRCUITPY_RGB_STATUS_B) -#define CIRCUITPY_STATUS_LED (CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)) || defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || CIRCUITPY_PWM_RGB_LED +#define CIRCUITPY_PWM_RGB_LED (defined(CIRCUITPY_RGB_STATUS_R) || defined(CIRCUITPY_RGB_STATUS_G) || defined(CIRCUITPY_RGB_STATUS_B)) +#define CIRCUITPY_STATUS_LED ((CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS)) || defined(MICROPY_HW_NEOPIXEL) || (defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK)) || CIRCUITPY_PWM_RGB_LED) void status_led_init(void); void status_led_deinit(void); From f96cd7361dbfa557f862a39862eac35d0dd18e45 Mon Sep 17 00:00:00 2001 From: Michael Himing Date: Fri, 25 Mar 2022 22:30:20 +1100 Subject: [PATCH 2/2] Fix esp32s2 build --- ports/espressif/common-hal/busio/UART.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/espressif/common-hal/busio/UART.h b/ports/espressif/common-hal/busio/UART.h index ca5b3f925b..cd2dcc4d57 100644 --- a/ports/espressif/common-hal/busio/UART.h +++ b/ports/espressif/common-hal/busio/UART.h @@ -32,6 +32,10 @@ #include "components/hal/include/hal/uart_types.h" #include "py/obj.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" + typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *rx_pin;