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)
|
void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||||
{
|
{
|
||||||
uartSetBaudRate(_uart, baud);
|
uartSetBaudRate(_uart, baud);
|
||||||
|
@ -57,6 +57,10 @@ class HardwareSerial: public Stream
|
|||||||
public:
|
public:
|
||||||
HardwareSerial(int uart_nr);
|
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 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 end(bool turnOffDebug = true);
|
||||||
void updateBaudRate(unsigned long baud);
|
void updateBaudRate(unsigned long baud);
|
||||||
|
@ -34,7 +34,9 @@ struct uart_struct_t {
|
|||||||
uint8_t num;
|
uint8_t num;
|
||||||
bool has_peek;
|
bool has_peek;
|
||||||
uint8_t peek_byte;
|
uint8_t peek_byte;
|
||||||
|
QueueHandle_t uart_event_queue;
|
||||||
|
void (*onReceive)(void);
|
||||||
|
TaskHandle_t envent_task;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CONFIG_DISABLE_HAL_LOCKS
|
#if CONFIG_DISABLE_HAL_LOCKS
|
||||||
@ -43,12 +45,12 @@ struct uart_struct_t {
|
|||||||
#define UART_MUTEX_UNLOCK()
|
#define UART_MUTEX_UNLOCK()
|
||||||
|
|
||||||
static uart_t _uart_bus_array[] = {
|
static uart_t _uart_bus_array[] = {
|
||||||
{0, false, 0},
|
{0, false, 0, NULL, NULL, NULL},
|
||||||
#if SOC_UART_NUM > 1
|
#if SOC_UART_NUM > 1
|
||||||
{1, false, 0},
|
{1, false, 0, NULL, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_NUM > 2
|
#if SOC_UART_NUM > 2
|
||||||
{2, false, 0},
|
{2, false, 0, NULL, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,12 +60,12 @@ static uart_t _uart_bus_array[] = {
|
|||||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||||
|
|
||||||
static uart_t _uart_bus_array[] = {
|
static uart_t _uart_bus_array[] = {
|
||||||
{NULL, 0, false, 0},
|
{NULL, 0, false, 0, NULL, NULL, NULL},
|
||||||
#if SOC_UART_NUM > 1
|
#if SOC_UART_NUM > 1
|
||||||
{NULL, 1, false, 0},
|
{NULL, 1, false, 0, NULL, NULL, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_NUM > 2
|
#if SOC_UART_NUM > 2
|
||||||
{NULL, 2, false, 0},
|
{NULL, 2, false, 0, NULL, NULL, NULL},
|
||||||
#endif
|
#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)
|
bool uartIsDriverInstalled(uart_t* uart)
|
||||||
{
|
{
|
||||||
if(uart == NULL) {
|
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;
|
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_param_config(uart_nr, &uart_config));
|
||||||
ESP_ERROR_CHECK(uart_set_pin(uart_nr, txPin, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
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));
|
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();
|
UART_MUTEX_UNLOCK();
|
||||||
|
|
||||||
uartFlush(uart);
|
uartFlush(uart);
|
||||||
@ -167,6 +236,11 @@ void uartEnd(uart_t* uart)
|
|||||||
|
|
||||||
UART_MUTEX_LOCK();
|
UART_MUTEX_LOCK();
|
||||||
uart_driver_delete(uart->num);
|
uart_driver_delete(uart->num);
|
||||||
|
if (uart->envent_task) {
|
||||||
|
vTaskDelete(uart->envent_task);
|
||||||
|
uart->envent_task = NULL;
|
||||||
|
uart->onReceive = NULL;
|
||||||
|
}
|
||||||
UART_MUTEX_UNLOCK();
|
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);
|
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 uartEnd(uart_t* uart);
|
||||||
|
|
||||||
|
void uartOnReceive(uart_t* uart, void(*function)(void));
|
||||||
|
|
||||||
uint32_t uartAvailable(uart_t* uart);
|
uint32_t uartAvailable(uart_t* uart);
|
||||||
uint32_t uartAvailableForWrite(uart_t* uart);
|
uint32_t uartAvailableForWrite(uart_t* uart);
|
||||||
uint8_t uartRead(uart_t* uart);
|
uint8_t uartRead(uart_t* uart);
|
||||||
|
Reference in New Issue
Block a user