diff --git a/port/esp32/components/btstack/CMakeLists.txt b/port/esp32/components/btstack/CMakeLists.txt index 2098b7af7..45b29dfa4 100644 --- a/port/esp32/components/btstack/CMakeLists.txt +++ b/port/esp32/components/btstack/CMakeLists.txt @@ -63,6 +63,7 @@ set(priv_requires "bt" "driver" "lwip" + "vfs" ) idf_component_register(SRC_DIRS "${src_dirs}" diff --git a/port/esp32/components/btstack/btstack_stdin_esp32.c b/port/esp32/components/btstack/btstack_stdin_esp32.c index 55ffcd07c..36bde88f8 100644 --- a/port/esp32/components/btstack/btstack_stdin_esp32.c +++ b/port/esp32/components/btstack/btstack_stdin_esp32.c @@ -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 +#include +#include + +#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 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); }