Skip to content

Commit ca422b6

Browse files
committed
Adds UART RX IRQ Callback with onReceive()
1 parent caef400 commit ca422b6

File tree

4 files changed

+92
-8
lines changed

4 files changed

+92
-8
lines changed

cores/esp32/HardwareSerial.cpp

Lines changed: 5 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 81 additions & 8 deletions
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,65 @@ 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+
if(uart->onReceive) uart->onReceive();
110+
break;
111+
//Event of HW FIFO overflow detected
112+
case UART_FIFO_OVF:
113+
log_w("UART%d FIFO Overflow. Flushing data. Consider adding Flow Control to your Application.", uart->num);
114+
uart_flush_input(uart->num);
115+
xQueueReset(uart->uart_event_queue);
116+
break;
117+
//Event of UART ring buffer full
118+
case UART_BUFFER_FULL:
119+
log_w("UART%d Buffer Full. Flushing data. Consider encreasing your buffer size of your Application.", uart->num);
120+
uart_flush_input(uart->num);
121+
xQueueReset(uart->uart_event_queue);
122+
break;
123+
//Event of UART RX break detected
124+
case UART_BREAK:
125+
log_w("UART%d RX break.", uart->num);
126+
break;
127+
//Event of UART parity check error
128+
case UART_PARITY_ERR:
129+
log_w("UART%d parity error.", uart->num);
130+
break;
131+
//Event of UART frame error
132+
case UART_FRAME_ERR:
133+
log_w("UART%d frame error.", uart->num);
134+
break;
135+
//Others
136+
default:
137+
log_w("UART%d unknown event type %d.", uart->num, event.type);
138+
break;
139+
}
140+
}
141+
}
142+
vTaskDelete(NULL);
143+
}
144+
145+
85146
bool uartIsDriverInstalled(uart_t* uart)
86147
{
87148
if(uart == NULL) {
@@ -143,7 +204,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
143204
uart_config.source_clk = UART_SCLK_APB;
144205

145206

146-
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0));
207+
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 20, &(uart->uart_event_queue), 0));
147208
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
148209
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
149210

@@ -156,8 +217,15 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
156217
// Set RS485 half duplex mode on UART. This shall force flush to wait up to sending all bits out
157218
ESP_ERROR_CHECK(uart_set_mode(uart_nr, UART_MODE_RS485_HALF_DUPLEX));
158219

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

228+
161229
uartFlush(uart);
162230
return uart;
163231
}
@@ -170,6 +238,11 @@ void uartEnd(uart_t* uart)
170238

171239
UART_MUTEX_LOCK();
172240
uart_driver_delete(uart->num);
241+
if (uart->envent_task) {
242+
vTaskDelete(uart->envent_task);
243+
uart->envent_task = NULL;
244+
uart->onReceive = NULL;
245+
}
173246
UART_MUTEX_UNLOCK();
174247
}
175248

cores/esp32/esp32-hal-uart.h

Lines changed: 2 additions & 0 deletions
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)