mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-22 15:40:16 +00:00
btstack_stdin_esp32: add uart output/input buffering
This commit is contained in:
parent
b1847fffde
commit
b5a43cc197
@ -63,6 +63,7 @@ set(priv_requires
|
||||
"bt"
|
||||
"driver"
|
||||
"lwip"
|
||||
"vfs"
|
||||
)
|
||||
|
||||
idf_component_register(SRC_DIRS "${src_dirs}"
|
||||
|
@ -48,11 +48,23 @@
|
||||
#include "btstack_run_loop.h"
|
||||
#include "btstack_run_loop_freertos.h"
|
||||
#include "btstack_defines.h"
|
||||
#include "btstack_debug.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <reent.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/uart.h"
|
||||
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "btstack_uart_console";
|
||||
|
||||
// handle esp-idf change from CONFIG_CONSOLE_UART_NUM to CONFIG_ESP_CONSOLE_UART_NUM
|
||||
#ifndef CONFIG_ESP_CONSOLE_UART_NUM
|
||||
#define CONFIG_ESP_CONSOLE_UART_NUM CONFIG_CONSOLE_UART_NUM
|
||||
@ -65,44 +77,119 @@ volatile char stdin_character;
|
||||
static void (*stdin_handler)(char c);
|
||||
static btstack_data_source_t stdin_data_source;
|
||||
|
||||
// after the capacity of the TX buffer is exceeded the output will block, so
|
||||
// in order to prevent that the TX buffer needs to be big enough or
|
||||
// the baudrate needs to be increased.
|
||||
// Usually the maximum baudrate for the target is preferred
|
||||
#define RX_BUF_SIZE (1024)
|
||||
#define TX_BUF_SIZE (4096)
|
||||
static QueueHandle_t uart_queue = NULL;
|
||||
|
||||
static void btstack_stdin_process(struct btstack_data_source *ds, btstack_data_source_callback_type_t callback_type){
|
||||
if (!stdin_character_received) return;
|
||||
if (stdin_handler){
|
||||
(*stdin_handler)(stdin_character);
|
||||
}
|
||||
stdin_character_received = 0;
|
||||
uart_event_t event;
|
||||
if( xQueueReceive(uart_queue, (void*)&event, 0)) {
|
||||
switch( event.type ) {
|
||||
case UART_DATA: {
|
||||
uint8_t stdin_character;
|
||||
if(!stdin_handler) {
|
||||
uart_flush_input(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
break;
|
||||
}
|
||||
|
||||
for( int i=0; i<event.size; ++i ) {
|
||||
int ret = uart_read_bytes( CONFIG_ESP_CONSOLE_UART_NUM, &stdin_character, 1, 0 );
|
||||
btstack_assert( ret == 1 );
|
||||
(*stdin_handler)(stdin_character);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case UART_FIFO_OVF:
|
||||
ESP_LOGI(TAG, "hw fifo overflow");
|
||||
uart_flush_input(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
xQueueReset(uart_queue);
|
||||
break;
|
||||
case UART_BUFFER_FULL:
|
||||
ESP_LOGI(TAG, "ring buffer full");
|
||||
uart_flush_input(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
xQueueReset(uart_queue);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btstack_esp32_uart_init() {
|
||||
/* Drain stdout before reconfiguring it */
|
||||
fflush(stdout);
|
||||
fsync(fileno(stdout));
|
||||
|
||||
int baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE;
|
||||
#if SOC_UART_SUPPORT_REF_TICK
|
||||
uart_sclk_t clk_source = UART_SCLK_REF_TICK;
|
||||
// REF_TICK clock can't provide a high baudrate
|
||||
if (baud_rate > 1 * 1000 * 1000) {
|
||||
clk_source = UART_SCLK_DEFAULT;
|
||||
ESP_LOGW(TAG, "light sleep UART wakeup might not work at the configured baud rate");
|
||||
}
|
||||
#elif SOC_UART_SUPPORT_XTAL_CLK
|
||||
uart_sclk_t clk_source = UART_SCLK_XTAL;
|
||||
#else
|
||||
#error "No UART clock source is aware of DFS"
|
||||
#endif // SOC_UART_SUPPORT_xxx
|
||||
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = baud_rate,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = clk_source
|
||||
};
|
||||
// Configure UART parameters
|
||||
ESP_ERROR_CHECK(uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config));
|
||||
#ifdef CONFIG_ESP_UART_CUSTOM
|
||||
ESP_ERROR_CHECK(uart_set_pin(
|
||||
CONFIG_ESP_CONSOLE_UART_NUM,
|
||||
CONFIG_ESP_CONSOLE_UART_TX_GPIO,
|
||||
CONFIG_ESP_CONSOLE_UART_RX_GPIO,
|
||||
UART_PIN_NO_CHANGE,
|
||||
UART_PIN_NO_CHANGE));
|
||||
#endif
|
||||
// Setup UART buffered IO with event queue
|
||||
// Install UART driver using an event queue here
|
||||
ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, RX_BUF_SIZE,
|
||||
TX_BUF_SIZE, 10, &uart_queue, 0));
|
||||
|
||||
/* Tell VFS to use UART driver */
|
||||
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
}
|
||||
|
||||
static void btstack_stdin_task(void *arg){
|
||||
UNUSED(arg);
|
||||
|
||||
//Install UART driver, and get the queue.
|
||||
uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, UART_FIFO_LEN * 2, UART_FIFO_LEN * 2, 0, NULL, 0);
|
||||
UNUSED(arg);
|
||||
|
||||
uart_event_t event;
|
||||
do {
|
||||
// read single byte
|
||||
uart_read_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (uint8_t*) &stdin_character, 1, portMAX_DELAY);
|
||||
stdin_character_received = 1;
|
||||
|
||||
// request poll
|
||||
btstack_run_loop_freertos_trigger();
|
||||
|
||||
// busy wait for input processed
|
||||
while (stdin_character_received){
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
if(xQueuePeek(uart_queue, (void*)&event, portMAX_DELAY) ) {
|
||||
// request poll
|
||||
btstack_run_loop_freertos_trigger();
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
void btstack_stdin_setup(void (*handler)(char c)){
|
||||
// set handler
|
||||
stdin_handler = handler;
|
||||
// set handler
|
||||
stdin_handler = handler;
|
||||
|
||||
// set up polling data_source
|
||||
btstack_run_loop_set_data_source_handler(&stdin_data_source, &btstack_stdin_process);
|
||||
btstack_run_loop_enable_data_source_callbacks(&stdin_data_source, DATA_SOURCE_CALLBACK_POLL);
|
||||
btstack_run_loop_add_data_source(&stdin_data_source);
|
||||
btstack_esp32_uart_init();
|
||||
|
||||
//Create a task to block on UART RX
|
||||
xTaskCreate(btstack_stdin_task, "btstack_stdin", 2048, NULL, 12, NULL);
|
||||
// set up polling data_source
|
||||
btstack_run_loop_set_data_source_handler(&stdin_data_source, &btstack_stdin_process);
|
||||
btstack_run_loop_enable_data_source_callbacks(&stdin_data_source, DATA_SOURCE_CALLBACK_POLL);
|
||||
btstack_run_loop_add_data_source(&stdin_data_source);
|
||||
|
||||
//Create a task to block on UART RX
|
||||
xTaskCreate(btstack_stdin_task, "btstack_stdin", 2048, NULL, 12, NULL);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user