8000 Increase UART concurrency · stickbreaker/arduino-esp32@6b3a9de · GitHub
[go: up one dir, main page]

Skip to content

Commit 6b3a9de

Browse files
authored
Increase UART concurrency
While data is beginning received, it is stuck in the RX Fifo until the fifo fills to rxfifo_full_thrhd, or there is a break in the continuous data stream longer than the configured rx_tout_thrhd. This fix changes processing so that if a read() sees an empty queue, or available() is called, the RX fifo is flushed. This will decrease any latency between reception at the port and data handling in Serial(). This mod has not been exhaustively tested, but I have encountered no issues with my per-existing code.
1 parent 0de0d3f commit 6b3a9de

File tree

1 file changed

+54
-14
lines changed

1 file changed

+54
-14
lines changed

cores/esp32/esp32-hal-uart.c

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,23 @@ static uart_t _uart_bus_array[3] = {
6666
};
6767
#endif
6868

69+
static void _uart_rx_flush( uart_t * uart){
70+
uint8_t c;
71+
UART_MUTEX_LOCK();
72+
UBaseType_t spaces=0;
73+
if(uart->queue != NULL) {
74+
spaces=uxQueueSpacesAvailable( uart->queue);
75+
}
76+
while(((spaces--) >0)&&(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr))) {
77+
c = uart->dev->fifo.rw_byte;
78+
xQueueSend(uart->queue, &c,0);
79+
}
80+
UART_MUTEX_UNLOCK();
81+
}
82+
6983
static void IRAM_ATTR _uart_isr(void *arg)
7084
{
71-
uint8_t i, c;
85+
uint8_t i,c;
7286
BaseType_t xHigherPriorityTaskWoken;
7387
uart_t* uart;
7488

@@ -77,15 +91,15 @@ static void IRAM_ATTR _uart_isr(void *arg)
7791
if(uart->intr_handle == NULL){
7892
continue;
7993
}
94+
while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
95+
c = uart->dev->fifo.rw_byte;
96+
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
97+
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
98+
}
8099
uart->dev->int_clr.rxfifo_full = 1;
81100
uart->dev->int_clr.frm_err = 1;
82101
uart->dev->int_clr.rxfifo_tout = 1;
83-
while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
84-
c = uart->dev->fifo.rw_byte;
85-
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
86-
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
87-
}
88-
}
102+
}
89103
}
90104

91105
if (xHigherPriorityTaskWoken) {
@@ -96,14 +110,14 @@ static void IRAM_ATTR _uart_isr(void *arg)
96110
void uartEnableInterrupt(uart_t* uart)
97111
{
98112
UART_MUTEX_LOCK();
99-
uart->dev->conf1.rxfifo_full_thrhd = 112;
100-
uart->dev->conf1.rx_tout_thrhd = 2;
113+
uart->dev->conf1.rxfifo_full_thrhd = 112; // needs speed compensation?
114+
uart->dev->conf1.rx_tout_thrhd = 32; // no need to force rxFiFo empty, because uartRead() will empty if necessary
101115
uart->dev->conf1.rx_tout_en = 1;
102116
uart->dev->int_ena.rxfifo_full = 1;
103117
uart->dev->int_ena.frm_err = 1;
104118
uart->dev->int_ena.rxfifo_tout = 1;
105119
uart->dev->int_clr.val = 0xffffffff;
106-
120+
// can this share an interrupt?
107121
esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle);
108122
UART_MUTEX_UNLOCK();
109123
}
@@ -185,12 +199,15 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
185199
}
186200
}
187201
if(uart_nr == 1){
202+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
188203
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
189204
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
190205
} else if(uart_nr == 2){
206+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
191207
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
192208
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
193209
} else {
210+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
194211
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
195212
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
196213
}
@@ -224,20 +241,32 @@ void uartEnd(uart_t* uart)
224241
return;
225242
}
226243

244+
uartDetachRx(uart); // release pin, disable interrupt
245+
uartDetachTx(uart); // release pin
246+
227247
UART_MUTEX_LOCK();
248+
249+
uart->dev->conf0.val = 0;
250+
// power down uart, disable clocking
251+
if(uart->num == 1){
252+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
253+
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
254+
} else if(uart->num == 2){
255+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
256+
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
257+
} else {
258+
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
259+
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
260+
}
228261
if(uart->queue != NULL) {
229262
uint8_t c;
230263
while(xQueueReceive(uart->queue, &c, 0));
231264
vQueueDelete(uart->queue);
232265
uart->queue = NULL;
233266
}
234267

235-
uart->dev->conf0.val = 0;
236-
237268
UART_MUTEX_UNLOCK();
238269

239-
uartDetachRx(uart);
240-
uartDetachTx(uart);
241270
}
242271

243272
size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
@@ -265,6 +294,7 @@ uint32_t uartAvailable(uart_t* uart)
265294
if(uart == NULL || uart->queue == NULL) {
266295
return 0;
267296
}
297+
_uart_rx_flush(uart);
268298
return uxQueueMessagesWaiting(uart->queue);
269299
}
270300

@@ -284,6 +314,11 @@ uint8_t uartRead(uart_t* uart)
284314
uint8_t c;
285315
if(xQueueReceive(uart->queue, &c, 0)) {
286316
return c;
317+
} else {
318+
_uart_rx_flush(uart);
319+
if(xQueueReceive(uart->queue, &c, 0)) {
320+
return c;
321+
}
287322
}
288323
return 0;
289324
}
@@ -296,6 +331,11 @@ uint8_t uartPeek(uart_t* uart)
296331
uint8_t c;
297332
if(xQueuePeek(uart->queue, &c, 0)) {
298333
return c;
334+
} else {
335+
_uart_rx_flush(uart);
336+
if(xQueueReceive(uart->queue, &c, 0)) {
337+
return c;
338+
}
299339
}
300340
return 0;
301341
}

0 commit comments

Comments
 (0)
0