Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit dca1a1e

Browse filesBrowse files
authored
Changes UART ISR to only trigger on RX FIFO Full and timeout (espressif#6930)
* Changes UART ISR to only trigger on RX FIFO Full and timeout * changes initial RX timeout * Eliminates extra testing for _uart != NULL * reconfiguration with "uartSetFastReading()" * Adds new function "uartSetFastReading()" * changed default onReceive() behaviour * forces User callback in case of error * Error Code Order Set NO_ERROR as first error code, same as ESP_OK = 0
1 parent 85aecec commit dca1a1e
Copy full SHA for dca1a1e

File tree

4 files changed

+80
-13
lines changed
Filter options

4 files changed

+80
-13
lines changed

‎cores/esp32/HardwareSerial.cpp

Copy file name to clipboardExpand all lines: cores/esp32/HardwareSerial.cpp
+25-10Lines changed: 25 additions & 10 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(2),
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
}
@@ -250,6 +262,7 @@ void HardwareSerial::_uartEventTask(void *args)
250262
for(;;) {
251263
//Waiting for UART event.
252264
if(xQueueReceive(uartEventQueue, (void * )&event, (portTickType)portMAX_DELAY)) {
265+
hardwareSerial_error_t currentErr = UART_NO_ERROR;
253266
switch(event.type) {
254267
case UART_DATA:
255268
if(uart->_onReceiveCB && uart->available() > 0 &&
@@ -258,28 +271,32 @@ void HardwareSerial::_uartEventTask(void *args)
258271
break;
259272
case UART_FIFO_OVF:
260273
log_w("UART%d FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
261-
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FIFO_OVF_ERROR);
274+
currentErr = UART_FIFO_OVF_ERROR;
262275
break;
263276
case UART_BUFFER_FULL:
264277
log_w("UART%d Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
265-
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BUFFER_FULL_ERROR);
278+
currentErr = UART_BUFFER_FULL_ERROR;
266279
break;
267280
case UART_BREAK:
268281
log_w("UART%d RX break.", uart->_uart_nr);
269-
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_BREAK_ERROR);
282+
currentErr = UART_BREAK_ERROR;
270283
break;
271284
case UART_PARITY_ERR:
272285
log_w("UART%d parity error.", uart->_uart_nr);
273-
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_PARITY_ERROR);
286+
currentErr = UART_PARITY_ERROR;
274287
break;
275288
case UART_FRAME_ERR:
276289
log_w("UART%d frame error.", uart->_uart_nr);
277-
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(UART_FRAME_ERROR);
290+
currentErr = UART_FRAME_ERROR;
278291
break;
279292
default:
280293
log_w("UART%d unknown event type %d.", uart->_uart_nr, event.type);
281294
break;
282295
}
296+
if (currentErr != UART_NO_ERROR) {
297+
if(uart->_onReceiveErrorCB) uart->_onReceiveErrorCB(currentErr);
298+
if(uart->_onReceiveCB && uart->available() > 0) uart->_onReceiveCB(); // forces User Callback too
299+
}
283300
}
284301
}
285302
}
@@ -366,9 +383,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
366383
}
367384

368385
// Set UART RX timeout
369-
if (_uart != NULL) {
370-
uart_set_rx_timeout(_uart_nr, _rxTimeout);
371-
}
386+
uartSetRxTimeout(_uart, _rxTimeout);
372387

373388
HSERIAL_MUTEX_UNLOCK();
374389
}

‎cores/esp32/HardwareSerial.h

Copy file name to clipboardExpand all lines: cores/esp32/HardwareSerial.h
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "freertos/semphr.h"
5858

5959
typedef enum {
60+
UART_NO_ERROR,
6061
UART_BREAK_ERROR,
6162
UART_BUFFER_FULL_ERROR,
6263
UART_FIFO_OVF_ERROR,
@@ -81,6 +82,12 @@ class HardwareSerial: public Stream
8182
// For a baudrate of 9600, SERIAL_8N1 (10 bit symbol) and symbols_timeout = 3, the timeout would be 3 / (9600 / 10) = 3.125 ms
8283
void setRxTimeout(uint8_t symbols_timeout);
8384

85+
// setRxFIFOFull(uint8_t fifoBytes) will set the number of bytes that will trigger UART_INTR_RXFIFO_FULL interrupt and fill up RxRingBuffer
86+
// This affects some functions such as Serial::available() and Serial.read() because, in a UART flow of receiving data, Serial internal
87+
// RxRingBuffer will be filled only after these number of bytes arrive or a RX Timeout happens.
88+
// 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.
89+
void setRxFIFOFull(uint8_t fifoBytes);
90+
8491
// onReceive will setup a callback that will be called whenever an UART interruption occurs (UART_INTR_RXFIFO_FULL or UART_INTR_RXFIFO_TOUT)
8592
// UART_INTR_RXFIFO_FULL interrupt triggers at UART_FULL_THRESH_DEFAULT bytes received (defined as 120 bytes by default in IDF)
8693
// UART_INTR_RXFIFO_TOUT interrupt triggers at UART_TOUT_THRESH_DEFAULT symbols passed without any reception (defined as 10 symbos by default in IDF)
@@ -91,7 +98,7 @@ class HardwareSerial: public Stream
9198
// false -- The callback will be called when FIFO reaches 120 bytes and also on RX Timeout.
9299
// The stream of incommig bytes will be "split" into blocks of 120 bytes on each callback.
93100
// This option avoid any sort of Rx Overflow, but leaves the UART packet reassembling work to the Application.
94-
void onReceive(OnReceiveCb function, bool onlyOnTimeout = true);
101+
void onReceive(OnReceiveCb function, bool onlyOnTimeout = false);
95102

96103
// onReceive will be called on error events (see hardwareSerial_error_t)
97104
void onReceiveError(OnReceiveErrorCb function);

‎cores/esp32/esp32-hal-uart.c

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-uart.c
+44-2Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ 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-
166165
ESP_ERROR_CHECK(uart_driver_install(uart_nr, rx_buffer_size, tx_buffer_size, 20, &(uart->uart_event_queue), 0));
167166
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
168167
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
@@ -172,13 +171,56 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
172171
// invert signal for both Rx and Tx
173172
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
174173
}
175-
174+
176175
UART_MUTEX_UNLOCK();
177176

178177
uartFlush(uart);
179178
return uart;
180179
}
181180

181+
// This code is under testing - for now just keep it here
182+
void uartSetFastReading(uart_t* uart)
183+
{
184+
if(uart == NULL) {
185+
return;
186+
}
187+
188+
UART_MUTEX_LOCK();
189+
// override default RX IDF Driver Interrupt - no BREAK, PARITY or OVERFLOW
190+
uart_intr_config_t uart_intr = {
191+
.intr_enable_mask = UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT, // only these IRQs - no BREAK, PARITY or OVERFLOW
192+
.rx_timeout_thresh = 1,
193+
.txfifo_empty_intr_thresh = 10,
194+
.rxfifo_full_thresh = 2,
195+
};
196+
197+
ESP_ERROR_CHECK(uart_intr_config(uart->num, &uart_intr));
198+
UART_MUTEX_UNLOCK();
199+
}
200+
201+
202+
void uartSetRxTimeout(uart_t* uart, uint8_t numSymbTimeout)
203+
{
204+
if(uart == NULL) {
205+
return;
206+
}
207+
208+
UART_MUTEX_LOCK();
209+
uart_set_rx_timeout(uart->num, numSymbTimeout);
210+
UART_MUTEX_UNLOCK();
211+
}
212+
213+
void uartSetRxFIFOFull(uart_t* uart, uint8_t numBytesFIFOFull)
214+
{
215+
if(uart == NULL) {
216+
return;
217+
}
218+
219+
UART_MUTEX_LOCK();
220+
uart_set_rx_full_threshold(uart->num, numBytesFIFOFull);
221+
UART_MUTEX_UNLOCK();
222+
}
223+
182224
void uartEnd(uart_t* uart)
183225
{
184226
if(uart == NULL) {

‎cores/esp32/esp32-hal-uart.h

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-uart.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ 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);
87+
void uartSetFastReading(uart_t* uart);
8588

8689
void uartSetDebug(uart_t* uart);
8790
int uartGetDebug();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.