Adds C++ std::function to Serial.onReceive() (#6364)

* Adds C++ std::function to Serial.onReceive()

* fixes LOCK macro when disabled
This commit is contained in:
Rodrigo Garcia
2022-03-02 10:20:43 -03:00
committed by GitHub
parent 95b8e7e42b
commit 7d4992a811
4 changed files with 201 additions and 90 deletions

View File

@ -34,9 +34,7 @@ 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;
QueueHandle_t uart_event_queue; // export it by some uartGetEventQueue() function
};
#if CONFIG_DISABLE_HAL_LOCKS
@ -45,12 +43,12 @@ struct uart_struct_t {
#define UART_MUTEX_UNLOCK()
static uart_t _uart_bus_array[] = {
{0, false, 0, NULL, NULL, NULL},
{0, false, 0, NULL},
#if SOC_UART_NUM > 1
{1, false, 0, NULL, NULL, NULL},
{1, false, 0, NULL},
#endif
#if SOC_UART_NUM > 2
{2, false, 0, NULL, NULL, NULL},
{2, false, 0, NULL},
#endif
};
@ -60,12 +58,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, NULL, NULL},
{NULL, 0, false, 0, NULL},
#if SOC_UART_NUM > 1
{NULL, 1, false, 0, NULL, NULL, NULL},
{NULL, 1, false, 0, NULL},
#endif
#if SOC_UART_NUM > 2
{NULL, 2, false, 0, NULL, NULL, NULL},
{NULL, 2, false, 0, NULL},
#endif
};
@ -84,69 +82,22 @@ uint32_t _get_effective_baudrate(uint32_t baudrate)
}
}
void uartOnReceive(uart_t* uart, void(*function)(void))
// Routines that take care of UART events will be in the HardwareSerial Class code
void uartGetEventQueue(uart_t* uart, QueueHandle_t *q)
{
if(uart == NULL || function == NULL) {
// passing back NULL for the Queue pointer when UART is not initialized yet
*q = NULL;
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
uart->onReceive = function;
UART_MUTEX_UNLOCK();
*q = uart->uart_event_queue;
return;
}
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:
if(uart->onReceive) uart->onReceive();
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) {
return 0;
return false;
}
if (uart_is_driver_installed(uart->num)) {
@ -222,12 +173,6 @@ 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);
@ -242,11 +187,6 @@ 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();
}