Skip to content

Commit 0b2ae4e

Browse files
committed
Updated uart hal code, with comments regarding the interrupt clearing ;-)
1 parent cf98504 commit 0b2ae4e

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

cores/esp32/esp32-hal-uart.c

+20-6
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,42 @@ static void IRAM_ATTR _uart_isr()
8585
uart_t* uart;
8686
uart_interrupt_t *uart_interrupt;
8787

88+
// Loop through all the uart devices
8889
for(i=0;i<3;i++){
90+
91+
// Get the current uart device
8992
uart = &_uart_bus_array[i];
93+
94+
// Get the interrupt description for this uart device
9095
uart_interrupt = _uart_interrupt_array[i];
9196

97+
// If there is no interrupt handle, skip the rest of the for loop's body
9298
if (uart->intr_handle == NULL) {
9399
continue;
94100
}
101+
102+
// There are cases where bytes might come in between the time you check and handle the bytes and the time you clear the interrupt.
103+
// In that case you will not get an ISR for those bytes.
104+
// We had that happen and scratched heads for quite some time.
105+
// There was another case that I do not recall at this time as well.
106+
// https://github.com/espressif/arduino-esp32/pull/4656#discussion_r555780523
107+
uart->dev->int_clr.rxfifo_full = 1;
108+
uart->dev->int_clr.frm_err = 1;
109+
uart->dev->int_clr.rxfifo_tout = 1;
95110

111+
// Read until fifo is empty
96112
while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
97113
c = uart->dev->fifo.rw_byte;
114+
115+
// Check if an user defined interrupt handling function is present
98116
if (uart_interrupt != NULL && uart_interrupt->dev->num == uart->num && uart_interrupt->func != NULL) {
99117
// Fully optimized code would not create the queue anymore if an function has been specified as an argument.
100118
(*uart_interrupt->func)(c, uart_interrupt->user_arg);
101119
}else if (uart->queue != NULL) {
120+
// No user function is present, handle as you normally would
102121
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
103122
}
104-
}
105-
106-
// Clear the interrupts after everything was read
107-
uart->dev->int_clr.rxfifo_full = 1;
108-
uart->dev->int_clr.frm_err = 1;
109-
uart->dev->int_clr.rxfifo_tout = 1;
123+
}
110124
}
111125

112126
if (xHigherPriorityTaskWoken) {

0 commit comments

Comments
 (0)