Skip to content

Commit c014eaf

Browse files
authored
Adds UART RX IRQ Callback with onReceive() (espressif#6134)
* Adds UART RX IRQ Callback with onReceive()
1 parent 5ae3886 commit c014eaf

File tree

4 files changed

+93
-8
lines changed

4 files changed

+93
-8
lines changed

cores/esp32/HardwareSerial.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
159159
}
160160
}
161161

162+
void HardwareSerial::onReceive(void(*function)(void))
163+
{
164+
uartOnReceive(_uart, function);
165+
}
166+
162167
void HardwareSerial::updateBaudRate(unsigned long baud)
163168
{
164169
uartSetBaudRate(_uart, baud);

cores/esp32/HardwareSerial.h

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class HardwareSerial: public Stream
5757
public:
5858
HardwareSerial(int uart_nr);
5959

60+
// onReceive will setup a callback for whenever UART data is received
61+
// it will work as UART Rx interrupt
62+
void onReceive(void(*function)(void));
63+
6064
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
6165
void end(bool turnOffDebug = true);
6266
void updateBaudRate(unsigned long baud);

cores/esp32/esp32-hal-uart.c

+82-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ struct uart_struct_t {
3434
uint8_t num;
3535
bool has_peek;
3636
uint8_t peek_byte;
37-
37+
QueueHandle_t uart_event_queue;
38+
void (*onReceive)(void);
39+
TaskHandle_t envent_task;
3840
};
3941

4042
#if CONFIG_DISABLE_HAL_LOCKS
@@ -43,12 +45,12 @@ struct uart_struct_t {
4345
#define UART_MUTEX_UNLOCK()
4446

4547
static uart_t _uart_bus_array[] = {
46-
{0, false, 0},
48+
{0, false, 0, NULL, NULL, NULL},
4749
#if SOC_UART_NUM > 1
48-
{1, false, 0},
50+
{1, false, 0, NULL, NULL, NULL},
4951
#endif
5052
#if SOC_UART_NUM > 2
51-
{2, false, 0},
53+
{2, false, 0, NULL, NULL, NULL},
5254
#endif
5355
};
5456

@@ -58,12 +60,12 @@ static uart_t _uart_bus_array[] = {
5860
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
5961

6062
static uart_t _uart_bus_array[] = {
61-
{NULL, 0, false, 0},
63+
{NULL, 0, false, 0, NULL, NULL, NULL},
6264
#if SOC_UART_NUM > 1
63-
{NULL, 1, false, 0},
65+
{NULL, 1, false, 0, NULL, NULL, NULL},
6466
#endif
6567
#if SOC_UART_NUM > 2
66-
{NULL, 2, false, 0},
68+
{NULL, 2, false, 0, NULL, NULL, NULL},
6769
#endif
6870
};
6971

@@ -82,6 +84,67 @@ uint32_t _get_effective_baudrate(uint32_t baudrate)
8284
}
8385
}
8486

87+
88+
void uartOnReceive(uart_t* uart, void(*function)(void))
89+
{
90+
if(uart == NULL || function == NULL) {
91+
return;
92+
}
93+
UART_MUTEX_LOCK();
94+
uart->onReceive = function;
95+
UART_MUTEX_UNLOCK();
96+
}
97+
98+
99+
static void uart_event_task(void *args)
100+
{
101+
uart_t* uart = (uart_t *)args;
102+
uart_event_t event;
103+
for(;;) {
104+
//Waiting for UART event.
105+
if(xQueueReceive(uart->uart_event_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
106+
switch(event.type) {
107+
//Event of UART receving data
108+
case UART_DATA:
109+
UART_MUTEX_LOCK();
110+
if(uart->onReceive) uart->onReceive();
111+
UART_MUTEX_UNLOCK();
112+
break;
113+
//Event of HW FIFO overflow detected
114+
case UART_FIFO_OVF:
115+
log_w("UART%d FIFO Overflow. Flushing data. Consider adding Flow Control to your Application.", uart->num);
116+
uart_flush_input(uart->num);
117+
xQueueReset(uart->uart_event_queue);
118+
break;
119+
//Event of UART ring buffer full
120+
case UART_BUFFER_FULL:
121+
log_w("UART%d Buffer Full. Flushing data. Consider encreasing your buffer size of your Application.", uart->num);
122+
uart_flush_input(uart->num);
123+
xQueueReset(uart->uart_event_queue);
124+
break;
125+
//Event of UART RX break detected
126+
case UART_BREAK:
127+
log_w("UART%d RX break.", uart->num);
128+
break;
129+
//Event of UART parity check error
130+
case UART_PARITY_ERR:
131+
log_w("UART%d parity error.", uart->num);
132+
break;
133+
//Event of UART frame error
134+
case UART_FRAME_ERR:
135+
log_w("UART%d frame error.", uart->num);
136+
break;
137+
//Others
138+
default:
139+
log_w("UART%d unknown event type %d.", uart->num, event.type);
140+
break;
141+
}
142+
}
143+
}
144+
vTaskDelete(NULL);
145+
}
146+
147+
85148
bool uartIsDriverInstalled(uart_t* uart)
86149
{
87150
if(uart == NULL) {
@@ -143,7 +206,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
143206
uart_config.source_clk = UART_SCLK_APB;
144207

145208

146-
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0));
209+
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 20, &(uart->uart_event_queue), 0));
147210
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
148211
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
149212

@@ -153,6 +216,12 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
153216
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
154217
}
155218

219+
// Creating UART event Task
220+
xTaskCreate(uart_event_task, "uart_event_task", 2048, uart, configMAX_PRIORITIES - 1, &(uart->envent_task));
221+
if (!uart->envent_task) {
222+
log_e(" -- UART%d Event Task not Created!", uart_nr);
223+
}
224+
156225
UART_MUTEX_UNLOCK();
157226

158227
uartFlush(uart);
@@ -167,6 +236,11 @@ void uartEnd(uart_t* uart)
167236

168237
UART_MUTEX_LOCK();
169238
uart_driver_delete(uart->num);
239+
if (uart->envent_task) {
240+
vTaskDelete(uart->envent_task);
241+
uart->envent_task = NULL;
242+
uart->onReceive = NULL;
243+
}
170244
UART_MUTEX_UNLOCK();
171245
}
172246

cores/esp32/esp32-hal-uart.h

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ typedef struct uart_struct_t uart_t;
5454
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted, uint8_t rxfifo_full_thrhd);
5555
void uartEnd(uart_t* uart);
5656

57+
void uartOnReceive(uart_t* uart, void(*function)(void));
58+
5759
uint32_t uartAvailable(uart_t* uart);
5860
uint32_t uartAvailableForWrite(uart_t* uart);
5961
uint8_t uartRead(uart_t* uart);

0 commit comments

Comments
 (0)