8000 esp32/uart: Use high level IDF uart driver for repl. · micropython/micropython@9e240ec · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e240ec

Browse files
committed
esp32/uart: Use high level IDF uart driver for repl.
1 parent 18acd03 commit 9e240ec

File tree

4 files changed

+147
-32
lines changed

4 files changed

+147
-32
lines changed

ports/esp32/main/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ set(MICROPY_SOURCE_SHARED
1919
${MICROPY_DIR}/shared/readline/readline.c
2020
${MICROPY_DIR}/shared/netutils/netutils.c
2121
${MICROPY_DIR}/shared/timeutils/timeutils.c
22-
${MICROPY_DIR}/shared/runtime/interrupt_char.c
2322
${MICROPY_DIR}/shared/runtime/stdout_helpers.c
2423
${MICROPY_DIR}/shared/runtime/sys_stdio_mphal.c
2524
${MICROPY_DIR}/shared/runtime/pyexec.c

ports/esp32/mphalport.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
#include "esp32s3/rom/uart.h"
4444
#endif
4545

46+
#include "uart.h"
47+
48+
#include "driver/uart.h"
49+
#include "soc/uart_periph.h"
50+
4651
#include "py/obj.h"
4752
#include "py/objstr.h"
4853
#include "py/stream.h"
@@ -94,8 +99,15 @@ void check_esp_err(esp_err_t code) {
9499

95100
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
96101
uintptr_t ret = 0;
97-
if ((poll_flags & MP_STREAM_POLL_RD) && stdin_ringbuf.iget != stdin_ringbuf.iput) {
98-
ret |= MP_STREAM_POLL_RD;
102+
if (poll_flags & MP_STREAM_POLL_RD) {
103+
size_t any = 0;
104+
if (stdin_ringbuf.iget != stdin_ringbuf.iput) {
105+
ret |= MP_STREAM_POLL_RD;
106+
} else if (uart_get_buffered_data_len(UART_NUM_0, &any) == ESP_OK) {
107+
if (any > 0) {
108+
ret |= MP_STREAM_POLL_RD;
109+
}
110+
}
99111
}
100112
return ret;
101113
}
@@ -106,11 +118,28 @@ int mp_hal_stdin_rx_chr(void) {
106118
if (c != -1) {
107119
return c;
108120
}
121+
uint8_t uc = 0;
122+
int ret = uart_read_bytes(UART_NUM_0, &uc, 1, 5);
123+
if (ret > 0) {
124+
return uc;
125+
}
126+
109127
MICROPY_EVENT_POLL_HOOK
110128
ulTaskNotifyTake(pdFALSE, 1);
111129
}
112130
}
113131

132+
#if MICROPY_KBD_EXCEPTION
133+
134+
int mp_interrupt_char = -1;
135+
136+
void mp_hal_set_interrupt_char(int c) {
137+
mp_interrupt_char = c;
138+
uart_repl_set_pattern_detect(c);
139+
}
140+
141+
#endif
142+
114143
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
115144
// Only release the GIL if many characters are being sent
116145
bool release_gil = len > 20;
@@ -122,9 +151,7 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) {
122151
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
123152
usb_serial_jtag_tx_strn(str, len);
124153
#else
125-
for (uint32_t i = 0; i < len; ++i) {
126-
uart_tx_one_char(str[i]);
127-
}
154+
uart_write_bytes(UART_NUM_0, str, len);
128155
#endif
129156
if (release_gil) {
130157
MP_THREAD_GIL_ENTER();

ports/esp32/uart.c

Lines changed: 114 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,42 +28,130 @@
2828

2929
#include <stdio.h>
3030

31+
#include "uart.h"
3132
#include "driver/uart.h"
3233
#include "soc/uart_periph.h"
3334

3435
#include "py/runtime.h"
3536
#include "py/mphal.h"
3637

37-
STATIC void uart_irq_handler(void *arg);
38+
static QueueHandle_t uart0_queue;
39+
40+
static void uart_event_task(void *pvParameters);
41+
3842

3943
void uart_init(void) {
40-
uart_isr_handle_t handle;
41-
uart_isr_register(UART_NUM_0, uart_irq_handler, NULL, ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM, &handle);
42-
uart_enable_rx_intr(UART_NUM_0);
44+
uart_config_t uartcfg = {
45+
.baud_rate = 115200,
46+
.data_bits = UART_DATA_8_BITS,
47+
.parity = UART_PARITY_DISABLE,
48+
.stop_bits = UART_STOP_BITS_1,
49+
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
50+
.rx_flow_ctrl_thresh = 0
51+
};
52+
uart_param_config(UART_NUM_0, &uartcfg);
53+
54+
const uint32_t rxbuf = 260;
55+
const uint32_t txbuf = 260;
56+
57+
uart_driver_install(UART_NUM_0, rxbuf, txbuf, 20, &uart0_queue, 0);
58+
59+
uart_repl_set_pattern_detect(mp_interrupt_char);
60+
61+
//Create a task to handler UART event from ISR
62+
xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
63+
64+
}
65+
66+
void uart_repl_set_pattern_detect(const char pattern) {
67+
//Set uart pattern detect function.
68+
uart_enable_pattern_det_baud_intr(UART_NUM_0, pattern, 1, 9, 0, 0);
69+
//Reset the pattern queue length to record at most 20 pattern positions.
70+
uart_pattern_queue_reset(UART_NUM_0, 20);
4371
}
4472

45-
// all code executed in ISR must be in IRAM, and any const data must be in DRAM
46-
STATIC void IRAM_ATTR uart_irq_handler(void *arg) {
47-
volatile uart_dev_t *uart = &UART0;
48-
#if CONFIG_IDF_TARGET_ESP32S3
49-
uart->int_clr.rxfifo_full_int_clr = 1;
50-
uart->int_clr.rxfifo_tout_int_clr = 1;
51-
#else
52-
uart->int_clr.rxfifo_full = 1;
53-
uart->int_clr.rxfifo_tout = 1;
54-
uart->int_clr.frm_err = 1;
55-
#endif
56-
while (uart->status.rxfifo_cnt) {
57-
#if CONFIG_IDF_TARGET_ESP32
58-
uint8_t c = uart->fifo.rw_byte;
59-
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
60-
uint8_t c = READ_PERI_REG(UART_FIFO_AHB_REG(0)); // UART0
61-
#endif
62-
if (c == mp_interrupt_char) {
63-
mp_sched_keyboard_interrupt();
64-
} else {
65-
// this is an inline function so will be in IRAM
66-
ringbuf_put(&stdin_ringbuf, c);
73+
void uart_event_task(void *pvParameters)
74+
{
75+
uart_event_t event;
76+
size_t buffered_size;
77+
// uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
78+
for(;;) {
79+
//Waiting for UART event.
80+
if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
81+
// bzero(dtmp, RD_BUF_SIZE);
82+
// ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0);
83+
switch(event.type) {
84+
//Event of UART receving data
85+
/*We'd better handler data event fast, there would be much more data events than
86+
other types of events. If we take too much time on data event, the queue might
87+
be full.*/
88+
// case UART_DATA:
89+
// ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
90+
// uart_read_bytes(UART_NUM_0, dtmp, event.size, portMAX_DELAY);
91+
// ESP_LOGI(TAG, "[DATA EVT]:");
92+
// uart_write_bytes(UART_NUM_0, (const char*) dtmp, event.size);
93+
// break;
94+
//Event of HW FIFO overflow detected
95+
// case UART_FIFO_OVF:
96+
// ESP_LOGI(TAG, "hw fifo overflow");
97+
// // If fifo overflow happened, you should consider adding flow control for your application.
98+
// // The ISR has already reset the rx FIFO,
99+
// // As an example, we directly flush the rx buffer here in order to read more data.
100+
// uart_flush_input(UART_NUM_0);
101+
// xQueueReset(uart0_queue);
102+
// break;
103+
//Event of UART ring buffer full
104+
// case UART_BUFFER_FULL:
105+
// ESP_LOGI(TAG, "ring buffer full");
106+
// // If buffer full happened, you should consider encreasing your buffer size
107+
// // As an example, we directly flush the rx buffer here in order to read more data.
108+
// uart_flush_input(UART_NUM_0);
109+
// xQueueReset(uart0_queue);
110+
// break;
111+
//Event of UART RX break detected
112+
// case UART_BREAK:
113+
// ESP_LOGI(TAG, "uart rx break");
114+
// break;
115+
//Event of UART parity check error
116+
// case UART_PARITY_ERR:
117+
// ESP_LOGI(TAG, "uart parity error");
118+
// break;
119+
//Event of UART frame error
120+
// case UART_FRAME_ERR:
121+
// ESP_LOGI(TAG, "uart frame error");
122+
// break;
123+
//UART_PATTERN_DET
124+
case UART_PATTERN_DET:
125+
uart_get_buffered_data_len(UART_NUM_0, &buffered_size);
126+
int pos = uart_pattern_pop_pos(UART_NUM_0);
127+
// ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
128+
if (pos == -1) {
129+
// There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
130+
// record the position. We should set a larger queue size.
131+
// As an example, we directly flush the rx buffer here.
132+
// uart_flush_input(UART_NUM_0);
133+
} else {
134+
uint8_t c = 0;
135+
for (int i = 0; i < pos; i++) {
136+
uart_read_bytes(UART_NUM_0, &c, 1, 100 / portTICK_PERIOD_MS);
137+
ringbuf_put(&stdin_ringbuf, c);
138+
}
139+
// uint8_t pat[PATTERN_CHR_NUM + 1];
140+
// memset(pat, 0, sizeof(pat));
141+
uart_read_bytes(UART_NUM_0, &c, 1, 100 / portTICK_PERIOD_MS);
142+
// ESP_LOGI(TAG, "read data: %s", dtmp);
143+
// ESP_LOGI(TAG, "read pat : %s", pat);
144+
}
145+
mp_sched_keyboard_interrupt();
146+
break;
147+
//Others
148+
default:
149+
// ESP_LOGI(TAG, "uart event type: %d", event.type);
150+
break;
151+
}
67152
}
68153
}
154+
// free(dtmp);
155+
// dtmp = NULL;
156+
vTaskDelete(NULL);
69157
}

ports/esp32/uart.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
#define MICROPY_INCLUDED_ESP32_UART_H
3030

3131
void uart_init(void);
32+
void uart_repl_set_pattern_detect(const char pattern);
3233

3334
#endif // MICROPY_INCLUDED_ESP32_UART_H

0 commit comments

Comments
 (0)
0