forked from espressif/arduino-esp32
Adds UART RX IRQ Callback with onReceive() (#6134)
* Adds UART RX IRQ Callback with onReceive()
This commit is contained in:
@ -159,6 +159,11 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::onReceive(void(*function)(void))
|
||||
{
|
||||
uartOnReceive(_uart, function);
|
||||
}
|
||||
|
||||
void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||
{
|
||||
uartSetBaudRate(_uart, baud);
|
||||
|
@ -57,6 +57,10 @@ class HardwareSerial: public Stream
|
||||
public:
|
||||
HardwareSerial(int uart_nr);
|
||||
|
||||
// onReceive will setup a callback for whenever UART data is received
|
||||
// it will work as UART Rx interrupt
|
||||
void onReceive(void(*function)(void));
|
||||
|
||||
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);
|
||||
void end(bool turnOffDebug = true);
|
||||
void updateBaudRate(unsigned long baud);
|
||||
|
@ -34,7 +34,9 @@ struct uart_struct_t {
|
||||
uint8_t num;
|
||||
bool has_peek;
|
||||
uint8_t peek_byte;
|
||||
|
||||
QueueHandle_t uart_event_queue;
|
||||
void (*onReceive)(void);
|
||||
TaskHandle_t envent_task;
|
||||
};
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
@ -43,12 +45,12 @@ struct uart_struct_t {
|
||||
#define UART_MUTEX_UNLOCK()
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{0, false, 0},
|
||||
{0, false, 0, NULL, NULL, NULL},
|
||||
#if SOC_UART_NUM > 1
|
||||
{1, false, 0},
|
||||
{1, false, 0, NULL, NULL, NULL},
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
{2, false, 0},
|
||||
{2, false, 0, NULL, NULL, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -58,12 +60,12 @@ static uart_t _uart_bus_array[] = {
|
||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{NULL, 0, false, 0},
|
||||
{NULL, 0, false, 0, NULL, NULL, NULL},
|
||||
#if SOC_UART_NUM > 1
|
||||
{NULL, 1, false, 0},
|
||||
{NULL, 1, false, 0, NULL, NULL, NULL},
|
||||
#endif
|
||||
#if SOC_UART_NUM > 2
|
||||
{NULL, 2, false, 0},
|
||||
{NULL, 2, false, 0, NULL, NULL, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -82,6 +84,67 @@ uint32_t _get_effective_baudrate(uint32_t baudrate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uartOnReceive(uart_t* uart, void(*function)(void))
|
||||
{
|
||||
if(uart == NULL || function == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
uart->onReceive = function;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
|
||||
static void uart_event_task(void *args)
|
||||
{
|
||||
uart_t* uart = (uart_t *)args;
|
||||
uart_event_t event;
|
||||
for(;;) {
|
||||
//Waiting for UART event.
|
||||
if(xQueueReceive(uart->uart_event_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
|
||||
switch(event.type) {
|
||||
//Event of UART receving data
|
||||
case UART_DATA:
|
||||
UART_MUTEX_LOCK();
|
||||
if(uart->onReceive) uart->onReceive();
|
||||
UART_MUTEX_UNLOCK();
|
||||
break;
|
||||
//Event of HW FIFO overflow detected
|
||||
case UART_FIFO_OVF:
|
||||
log_w("UART%d FIFO Overflow. Flushing data. Consider adding Flow Control to your Application.", uart->num);
|
||||
uart_flush_input(uart->num);
|
||||
xQueueReset(uart->uart_event_queue);
|
||||
break;
|
||||
//Event of UART ring buffer full
|
||||
case UART_BUFFER_FULL:
|
||||
log_w("UART%d Buffer Full. Flushing data. Consider encreasing your buffer size of your Application.", uart->num);
|
||||
uart_flush_input(uart->num);
|
||||
xQueueReset(uart->uart_event_queue);
|
||||
break;
|
||||
//Event of UART RX break detected
|
||||
case UART_BREAK:
|
||||
log_w("UART%d RX break.", uart->num);
|
||||
break;
|
||||
//Event of UART parity check error
|
||||
case UART_PARITY_ERR:
|
||||
log_w("UART%d parity error.", uart->num);
|
||||
break;
|
||||
//Event of UART frame error
|
||||
case UART_FRAME_ERR:
|
||||
log_w("UART%d frame error.", uart->num);
|
||||
break;
|
||||
//Others
|
||||
default:
|
||||
log_w("UART%d unknown event type %d.", uart->num, event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
bool uartIsDriverInstalled(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
@ -143,7 +206,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
uart_config.source_clk = UART_SCLK_APB;
|
||||
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 0, NULL, 0));
|
||||
ESP_ERROR_CHECK(uart_driver_install(uart_nr, 2*queueLen, 0, 20, &(uart->uart_event_queue), 0));
|
||||
ESP_ERROR_CHECK(uart_param_config(uart_nr, &uart_config));
|
||||
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
@ -153,6 +216,12 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
|
||||
ESP_ERROR_CHECK(uart_set_line_inverse(uart_nr, UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV));
|
||||
}
|
||||
|
||||
// Creating UART event Task
|
||||
xTaskCreate(uart_event_task, "uart_event_task", 2048, uart, configMAX_PRIORITIES - 1, &(uart->envent_task));
|
||||
if (!uart->envent_task) {
|
||||
log_e(" -- UART%d Event Task not Created!", uart_nr);
|
||||
}
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
uartFlush(uart);
|
||||
@ -167,6 +236,11 @@ void uartEnd(uart_t* uart)
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
uart_driver_delete(uart->num);
|
||||
if (uart->envent_task) {
|
||||
vTaskDelete(uart->envent_task);
|
||||
uart->envent_task = NULL;
|
||||
uart->onReceive = NULL;
|
||||
}
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ typedef struct uart_struct_t uart_t;
|
||||
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);
|
||||
void uartEnd(uart_t* uart);
|
||||
|
||||
void uartOnReceive(uart_t* uart, void(*function)(void));
|
||||
|
||||
uint32_t uartAvailable(uart_t* uart);
|
||||
uint32_t uartAvailableForWrite(uart_t* uart);
|
||||
uint8_t uartRead(uart_t* uart);
|
||||
|
Reference in New Issue
Block a user