8000 Merge pull request #6187 from prplz/espressif-uart-workflow-fixes · ReeceRobinson/circuitpython@ec5c950 · GitHub
[go: up one dir, main page]

Skip to content

Commit ec5c950

Browse files
authored
Merge pull request adafruit#6187 from prplz/espressif-uart-workflow-fixes
Espressif: Fix interrupts in UART workflow
2 parents 6fd968f + f96cd73 commit ec5c950

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

ports/espressif/common-hal/busio/UART.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,47 @@
3030
#include "components/driver/include/driver/uart.h"
3131

3232
#include "mpconfigport.h"
33+
#include "shared/readline/readline.h"
3334
#include "shared/runtime/interrupt_char.h"
3435
#include "py/gc.h"
3536
#include "py/mperrno.h"
3637
#include "py/runtime.h"
3738
#include "py/stream.h"
39+
#include "supervisor/port.h"
3840
#include "supervisor/shared/translate.h"
3941
#include "supervisor/shared/tick.h"
4042

4143
uint8_t never_reset_uart_mask = 0;
4244

45+
static void uart_event_task(void *param) {
46+
busio_uart_obj_t *self = param;
47+
uart_event_t event;
48+
while (true) {
49+
if (xQueueReceive(self->event_queue, &event, portMAX_DELAY)) {
50+
switch (event.type) {
51+
case UART_PATTERN_DET:
52+
// When the debug uart receives CTRL+C, wake the main task and schedule a keyboard interrupt
53+
if (self->is_debug) {
54+
port_wake_main_task();
55+
if (mp_interrupt_char == CHAR_CTRL_C) {
56+
uart_flush(self->uart_num);
57+
mp_sched_keyboard_interrupt();
58+
}
59+
}
60+
break;
61+
case UART_DATA:
62+
// When the debug uart receives any key, wake the main task
63+
if (self->is_debug) {
64+
port_wake_main_task();
65+
}
66+
break;
67+
default:
68+
break;
69+
}
70+
}
71+
}
72+
}
73+
4374
void uart_reset(void) {
4475
for (uart_port_t num = 0; num < UART_NUM_MAX; num++) {
4576
// Ignore the UART used by the IDF.
@@ -125,10 +156,26 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
125156

126157
uint8_t rx_threshold = UART_FIFO_LEN - 8;
127158
// Install the driver before we change the settings.
128-
if (uart_driver_install(self->uart_num, receiver_buffer_size, 0, 0, NULL, 0) != ESP_OK ||
159+
if (uart_driver_install(self->uart_num, receiver_buffer_size, 0, 20, &self->event_queue, 0) != ESP_OK ||
129160
uart_set_mode(self->uart_num, mode) != ESP_OK) {
130161
mp_raise_ValueError(translate("Could not initialize UART"));
131162
}
163+
// On the debug uart, enable pattern detection to look for CTRL+C
164+
#ifdef CIRCUITPY_DEBUG_UART_RX
165+
if (rx == CIRCUITPY_DEBUG_UART_RX) {
166+
self->is_debug = true;
167+
uart_enable_pattern_det_baud_intr(self->uart_num, CHAR_CTRL_C, 1, 1, 0, 0);
168+
}
169+
#endif
170+
// Start a task to listen for uart events
171+
xTaskCreatePinnedToCore(
172+
uart_event_task,
173+
"uart_event_task",
174+
configMINIMAL_STACK_SIZE,
175+
self,
176+
CONFIG_PTHREAD_TASK_PRIO_DEFAULT,
177+
&self->event_task,
178+
xPortGetCoreID());
132179
uart_set_hw_flow_ctrl(self->uart_num, flow_control, rx_threshold);
133180

134181
// Set baud rate
@@ -230,6 +277,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
230277
if (common_hal_busio_uart_deinited(self)) {
231278
return;
232279
}
280+
vTaskDelete(self->event_task);
233281
uart_driver_delete(self->uart_num);
234282

235283
common_hal_reset_pin(self->rx_pin);

ports/espressif/common-hal/busio/UART.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#include "components/hal/include/hal/uart_types.h"
3333
#include "py/obj.h"
3434

35+
#include "freertos/FreeRTOS.h"
36+
#include "freertos/task.h"
37+
#include "freertos/queue.h"
38+
3539
typedef struct {
3640
mp_obj_base_t base;
3741
const mcu_pin_obj_t *rx_pin;
@@ -42,6 +46,9 @@ typedef struct {
4246
uint8_t character_bits;
4347
bool rx_error;
4448
uint32_t timeout_ms;
49+
bool is_debug;
50+
QueueHandle_t event_queue;
51+
TaskHandle_t event_task;
4552
} busio_uart_obj_t;
4653

4754
void uart_reset(void);

supervisor/shared/status_leds.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
4545
// neopixel_write implemented.
4646

47-
#define CIRCUITPY_PWM_RGB_LED defined(CIRCUITPY_RGB_STATUS_R) || defined(CIRCUITPY_RGB_STATUS_G) || defined(CIRCUITPY_RGB_STATUS_B)
48-
#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
47+
#define CIRCUITPY_PWM_RGB_LED (defined(CIRCUITPY_RGB_STATUS_R) || defined(CIRCUITPY_RGB_STATUS_G) || defined(CIRCUITPY_RGB_STATUS_B))
48+
#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)
4949

5050
void status_led_init(void);
5151
void status_led_deinit(void);

0 commit comments

Comments
 (0)
0