Merge pull request #6187 from prplz/espressif-uart-workflow-fixes
Espressif: Fix interrupts in UART workflow
This commit is contained in:
commit
ec5c9507b9
@ -30,16 +30,47 @@
|
|||||||
#include "components/driver/include/driver/uart.h"
|
#include "components/driver/include/driver/uart.h"
|
||||||
|
|
||||||
#include "mpconfigport.h"
|
#include "mpconfigport.h"
|
||||||
|
#include "shared/readline/readline.h"
|
||||||
#include "shared/runtime/interrupt_char.h"
|
#include "shared/runtime/interrupt_char.h"
|
||||||
#include "py/gc.h"
|
#include "py/gc.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/stream.h"
|
#include "py/stream.h"
|
||||||
|
#include "supervisor/port.h"
|
||||||
#include "supervisor/shared/translate.h"
|
#include "supervisor/shared/translate.h"
|
||||||
#include "supervisor/shared/tick.h"
|
#include "supervisor/shared/tick.h"
|
||||||
|
|
||||||
uint8_t never_reset_uart_mask = 0;
|
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) {
|
void uart_reset(void) {
|
||||||
for (uart_port_t num = 0; num < UART_NUM_MAX; num++) {
|
for (uart_port_t num = 0; num < UART_NUM_MAX; num++) {
|
||||||
// Ignore the UART used by the IDF.
|
// 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;
|
uint8_t rx_threshold = UART_FIFO_LEN - 8;
|
||||||
// Install the driver before we change the settings.
|
// 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) {
|
uart_set_mode(self->uart_num, mode) != ESP_OK) {
|
||||||
mp_raise_ValueError(translate("Could not initialize UART"));
|
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);
|
uart_set_hw_flow_ctrl(self->uart_num, flow_control, rx_threshold);
|
||||||
|
|
||||||
// Set baud rate
|
// 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)) {
|
if (common_hal_busio_uart_deinited(self)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
vTaskDelete(self->event_task);
|
||||||
uart_driver_delete(self->uart_num);
|
uart_driver_delete(self->uart_num);
|
||||||
|
|
||||||
common_hal_reset_pin(self->rx_pin);
|
common_hal_reset_pin(self->rx_pin);
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
#include "components/hal/include/hal/uart_types.h"
|
#include "components/hal/include/hal/uart_types.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
const mcu_pin_obj_t *rx_pin;
|
const mcu_pin_obj_t *rx_pin;
|
||||||
@ -42,6 +46,9 @@ typedef struct {
|
|||||||
uint8_t character_bits;
|
uint8_t character_bits;
|
||||||
bool rx_error;
|
bool rx_error;
|
||||||
uint32_t timeout_ms;
|
uint32_t timeout_ms;
|
||||||
|
bool is_debug;
|
||||||
|
QueueHandle_t event_queue;
|
||||||
|
TaskHandle_t event_task;
|
||||||
} busio_uart_obj_t;
|
} busio_uart_obj_t;
|
||||||
|
|
||||||
void uart_reset(void);
|
void uart_reset(void);
|
||||||
|
@ -44,8 +44,8 @@
|
|||||||
// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
|
// To work with a NeoPixel, one must have MICROPY_HW_NEOPIXEL defined and
|
||||||
// neopixel_write implemented.
|
// 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_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_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_init(void);
|
||||||
void status_led_deinit(void);
|
void status_led_deinit(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user