Skip to content

Commit 118f815

Browse files
committed
Changes UART ISR to only trigger on RX FIFO Full and timeout
1 parent cf01523 commit 118f815

File tree

4 files changed

+54
-3
lines changed

4 files changed

+54
-3
lines changed

cores/esp32/HardwareSerial.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ _txBufferSize(0),
140140
_onReceiveCB(NULL),
141141
_onReceiveErrorCB(NULL),
142142
_onReceiveTimeout(true),
143-
_rxTimeout(10),
143+
_rxTimeout(1),
144144
_eventTask(NULL)
145145
#if !CONFIG_DISABLE_HAL_LOCKS
146146
,_lock(NULL)
@@ -212,6 +212,18 @@ void HardwareSerial::onReceive(OnReceiveCb function, bool onlyOnTimeout)
212212
HSERIAL_MUTEX_UNLOCK();
213213
}
214214

215+
// This function allow the user to define how many bytes will trigger an Interrupt that will copy RX FIFO to the internal RX Ringbuffer
216+
// ISR will also move data from FIFO to RX Ringbuffer after a RX Timeout defined in HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
217+
// A low value of FIFO Full bytes will consume more CPU time within the ISR
218+
// A high value of FIFO Full bytes will make the application wait longer to have byte available for the Stkech in a streaming scenario
219+
// Both RX FIFO Full and RX Timeout may affect when onReceive() will be called
220+
void HardwareSerial::setRxFIFOFull(uint8_t fifoBytes)
221+
{
222+
HSERIAL_MUTEX_LOCK();
223+
uartSetRxFIFOFull(_uart, fifoBytes); // Set new timeout
224+
HSERIAL_MUTEX_UNLOCK();
225+
}
226+
215227
// timout is calculates in time to receive UART symbols at the UART baudrate.
216228
// the estimation is about 11 bits per symbol (SERIAL_8N1)
217229
void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
@@ -223,7 +235,7 @@ void HardwareSerial::setRxTimeout(uint8_t symbols_timeout)
223235
_rxTimeout = symbols_timeout;
224236
if (!symbols_timeout) _onReceiveTimeout = false; // only when RX timeout is disabled, we also must disable this flag
225237

226-
if(_uart != NULL) uart_set_rx_timeout(_uart_nr, _rxTimeout); // Set new timeout
238+
uartSetRxTimeout(_uart, _rxTimeout); // Set new timeout
227239

228240
HSERIAL_MUTEX_UNLOCK();
229241
}
@@ -367,7 +379,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
367379

368380
// Set UART RX timeout
369381
if (_uart != NULL) {
370-
uart_set_rx_timeout(_uart_nr, _rxTimeout);
382+
uartSetRxTimeout(_uart, _rxTimeout);
371383
}
372384

373385
HSERIAL_MUTEX_UNLOCK();

cores/esp32/HardwareSerial.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class HardwareSerial: public Stream
8181
// For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
8282
void setRxTimeout(uint8_t symbols_timeout);
8383

84+
// setRxFIFOFull(uint8_t fifoBytes) will set the number of bytes that will trigger UART_INTR_RXFIFO_FULL interrupt and fill up RxRingBuffer
85+
// This affects some functions such as Serial::available() and Serial.read() because, in a UART flow of receiving data, Serial internal
86+
// RxRingBuffer will be filled only after these number of bytes arrive or a RX Timeout happens.
87+
// This parameter can be set to 1 in order to receive byte by byte, but it will also consume more CPU time as the ISR will be activates often.
88+
void setRxFIFOFull(uint8_t fifoBytes);
89+
8490
// onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
8591
// UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
8692
// UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)

cores/esp32/esp32-hal-uart.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,12 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
162162
uart_config.rx_flow_ctrl_thresh = rxfifo_full_thrhd;
163163
uart_config.source_clk = UART_SCLK_APB;
164164

165+
uart_intr_config_t uart_intr = {
166+
.intr_enable_mask = UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT, // only these IRQs - no BREAK, PARITY or OVERFLOW
167+
.rx_timeout_thresh = 1,
168+
.txfifo_empty_intr_thresh = 10,
169+
.rxfifo_full_thresh = rxfifo_full_thrhd,
170+
};
165171

166172
ESP_ERROR_CHECK(uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0));
167173
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
@@ -173,12 +179,37 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
173179
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
174180
}
175181

182+
// override default RX IDF Driver Interrupt - no BREAK, PARITY or OVERFLOW
183+
ESP_ERROR_CHECK(uart_intr_config(uart_nr, &uart_intr));
184+
176185
UART_MUTEX_UNLOCK();
177186

178187
uartFlush(uart);
179188
return uart;
180189
}
181190

191+
void uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout)
192+
{
193+
if(uart == NULL) {
194+
return;
195+
}
196+
197+
UART_MUTEX_LOCK();
198+
uart_set_rx_timeout(uart->num, numSymbTimeout);
199+
UART_MUTEX_UNLOCK();
200+
}
201+
202+
void uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull)
203+
{
204+
if(uart == NULL) {
205+
return;
206+
}
207+
208+
UART_MUTEX_LOCK();
209+
uart_set_rx_full_threshold(uart->num, numBytesFIFOFull);
210+
UART_MUTEX_UNLOCK();
211+
}
212+
182213
void uartEnd(uart_t* uart)
183214
{
184215
if(uart == NULL) {

cores/esp32/esp32-hal-uart.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate);
8282
uint32_t uartGetBaudRate(uart_t* uart);
8383

8484
void uartSetRxInvert(uart_t* uart, bool invert);
85+
void uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout);
86+
void uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull);
8587

8688
void uartSetDebug(uart_t* uart);
8789
int uartGetDebug();

0 commit comments

Comments
 (0)