diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 9b329e61e2..5b2cc3e6aa 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -11,27 +11,65 @@ config BLUEDROID_ENABLED This enables the default Bluedroid Bluetooth stack config BTC_TASK_STACK_SIZE - int "Bluetooth event (callback to application) task stack size" + int "Bluetooth event (callback to application) task stack size" depends on BT_ENABLED - default 3072 - help - This select btc task stack size + default 3072 + help + This select btc task stack size config BLUEDROID_MEM_DEBUG - bool "Bluedroid memory debug" + bool "Bluedroid memory debug" depends on BT_ENABLED - default n - help - Bluedroid memory debug + default n + help + Bluedroid memory debug config BT_DRAM_RELEASE - bool "Release DRAM from Classic BT controller" + bool "Release DRAM from Classic BT controller" depends on BT_ENABLED - default n - help - This option should only be used when BLE only. - Open this option will release about 30K DRAM from Classic BT. - The released DRAM will be used as system heap memory. + default n + help + This option should only be used when BLE only. + Open this option will release about 30K DRAM from Classic BT. + The released DRAM will be used as system heap memory. + +#disable now for app cpu due to a known issue +config BTDM_CONTROLLER_RUN_APP_CPU + bool "Run controller on APP CPU" + depends on BT_ENABLED && !FREERTOS_UNICORE && 0 + default n + help + Run controller on APP CPU. + +config BTDM_CONTROLLER_RUN_CPU + int + depends on BT_ENABLED + default 1 if BTDM_CONTROLLER_RUN_APP_CPU + default 0 + +menuconfig BT_HCI_UART + bool "HCI use UART as IO" + depends on BT_ENABLED + default n + help + Default HCI use VHCI, if this option choose, HCI will use UART(0/1/2) as IO. + Besides, it can set uart number and uart baudrate. + +config BT_HCI_UART_NO + int "UART Number for HCI" + depends on BT_HCI_UART + range 1 2 + default 1 + help + Uart number for HCI. + +config BT_HCI_UART_BAUDRATE + int "UART Baudrate for HCI" + depends on BT_HCI_UART + range 115200 921600 + default 921600 + help + UART Baudrate for HCI. Please use standard baudrate. # Memory reserved at start of DRAM for Bluetooth stack config BT_RESERVE_DRAM diff --git a/components/bt/bt.c b/components/bt/bt.c index e8f4204ef4..34b29b9c0c 100644 --- a/components/bt/bt.c +++ b/components/bt/bt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -33,13 +34,15 @@ #if CONFIG_BT_ENABLED /* Bluetooth system and controller config */ -#define BTDM_CFG_BT_EM_RELEASE (1<<0) -#define BTDM_CFG_BT_DATA_RELEASE (1<<1) +#define BTDM_CFG_BT_EM_RELEASE (1<<0) +#define BTDM_CFG_BT_DATA_RELEASE (1<<1) +#define BTDM_CFG_HCI_UART (1<<2) +#define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<3) /* Other reserved for future */ /* not for user call, so don't put to include file */ extern void btdm_osi_funcs_register(void *osi_funcs); -extern void btdm_controller_init(uint32_t config_mask); +extern void btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts); extern void btdm_controller_schedule(void); extern void btdm_controller_deinit(void); extern int btdm_controller_enable(esp_bt_mode_t mode); @@ -79,12 +82,14 @@ struct osi_funcs_t { int32_t (*_mutex_lock)(void *mutex); int32_t (*_mutex_unlock)(void *mutex); int32_t (* _read_efuse_mac)(uint8_t mac[6]); + void (* _srand)(unsigned int seed); + int (* _rand)(void); }; /* Static variable declare */ static bool btdm_bb_init_flag = false; static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - +static esp_bt_controller_config_t btdm_cfg_opts; static xTaskHandle btControllerTaskHandle; static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED; @@ -134,6 +139,16 @@ static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) return esp_read_mac(mac, ESP_MAC_BT); } +static void IRAM_ATTR srand_wrapper(unsigned int seed) +{ + /* empty function */ +} + +static int IRAM_ATTR rand_wrapper(void) +{ + return (int)esp_random(); +} + static struct osi_funcs_t osi_funcs = { ._set_isr = xt_set_interrupt_handler, ._ints_on = xt_ints_on, @@ -146,7 +161,9 @@ static struct osi_funcs_t osi_funcs = { ._mutex_create = mutex_create_wrapper, ._mutex_lock = mutex_lock_wrapper, ._mutex_unlock = mutex_unlock_wrapper, - ._read_efuse_mac = read_mac_wrapper + ._read_efuse_mac = read_mac_wrapper, + ._srand = srand_wrapper, + ._rand = rand_wrapper, }; bool esp_vhci_host_check_send_available(void) @@ -170,6 +187,12 @@ static uint32_t btdm_config_mask_load(void) #ifdef CONFIG_BT_DRAM_RELEASE mask |= (BTDM_CFG_BT_EM_RELEASE | BTDM_CFG_BT_DATA_RELEASE); +#endif +#ifdef CONFIG_BT_HCI_UART + mask |= BTDM_CFG_HCI_UART; +#endif +#ifdef CONFIG_BTDM_CONTROLLER_RUN_APP_CPU + mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU; #endif return mask; } @@ -178,30 +201,46 @@ static void bt_controller_task(void *pvParam) { uint32_t btdm_cfg_mask = 0; + btdm_cfg_mask = btdm_config_mask_load(); + btdm_osi_funcs_register(&osi_funcs); - btdm_cfg_mask = btdm_config_mask_load(); - btdm_controller_init(btdm_cfg_mask); + btdm_controller_init(btdm_cfg_mask, &btdm_cfg_opts); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - /* Loop */ btdm_controller_schedule(); } -void esp_bt_controller_init() +esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { + BaseType_t ret; + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { - return; + return ESP_ERR_INVALID_STATE; } - xTaskCreatePinnedToCore(bt_controller_task, "btController", + if (cfg == NULL) { + return ESP_ERR_INVALID_ARG; + } + + memcpy(&btdm_cfg_opts, cfg, sizeof(esp_bt_controller_config_t)); + + ret = xTaskCreatePinnedToCore(bt_controller_task, "btController", ESP_TASK_BT_CONTROLLER_STACK, NULL, - ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0); + ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, CONFIG_BTDM_CONTROLLER_RUN_CPU); + + if (ret != pdPASS) { + memset(&btdm_cfg_opts, 0x0, sizeof(esp_bt_controller_config_t)); + return ESP_ERR_NO_MEM; + } + + return ESP_OK; } void esp_bt_controller_deinit(void) { + memset(&btdm_cfg_opts, 0x0, sizeof(esp_bt_controller_config_t)); vTaskDelete(btControllerTaskHandle); btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; } diff --git a/components/bt/include/bt.h b/components/bt/include/bt.h index e3bd7f0840..5a244e0c80 100644 --- a/components/bt/include/bt.h +++ b/components/bt/include/bt.h @@ -18,11 +18,44 @@ #include #include #include "esp_err.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Controller config options, depend on config mask. + * Config mask indicate which functions enabled, this means + * some options or parameters of some functions enabled by config mask. + */ +typedef struct { + uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */ + uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */ +} esp_bt_controller_config_t; + +#ifdef CONFIG_BT_ENABLED + +#ifdef CONFIG_BT_HCI_UART_NO +#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO +#else +#define BT_HCI_UART_NO_DEFAULT 1 +#endif /* BT_HCI_UART_NO_DEFAULT */ + +#ifdef CONFIG_BT_HCI_UART_BAUDRATE +#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE +#else +#define BT_HCI_UART_BAUDRATE_DEFAULT 921600 +#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */ + +#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \ + .hci_uart_no = BT_HCI_UART_NO_DEFAULT,\ + .hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT,\ +}; +#else +#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() {0}; _Static_assert(0, "please enable bluetooth in menuconfig to use bt.h"); +#endif + /** * @brief Bluetooth mode for controller enable/disable */ @@ -45,10 +78,11 @@ typedef enum { /** * @brief Initialize BT controller to allocate task and other resource. - * + * @param cfg: Initial configuration of BT controller. * This function should be called only once, before any other BT functions are called. + * @return ESP_OK - success, other - failed */ -void esp_bt_controller_init(void); +esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg); /** * @brief De-initialize BT controller to free resource and delete task. diff --git a/components/bt/lib b/components/bt/lib index 9a4bb1d528..0986936c6d 160000 --- a/components/bt/lib +++ b/components/bt/lib @@ -1 +1 @@ -Subproject commit 9a4bb1d5287572664f170f9df4dbfd71babdfc68 +Subproject commit 0986936c6d21a009d7d4249cbae8a23b0f3bd20b diff --git a/docs/api/bluetooth/controller_vhci.rst b/docs/api/bluetooth/controller_vhci.rst index 9fc5910c25..6241adfbd1 100644 --- a/docs/api/bluetooth/controller_vhci.rst +++ b/docs/api/bluetooth/controller_vhci.rst @@ -38,6 +38,9 @@ Enumerations Structures ^^^^^^^^^^ +.. doxygenstruct:: esp_bt_controller_config_t + :members: + .. doxygenstruct:: esp_vhci_host_callback :members: diff --git a/examples/bluetooth/ble_adv/main/app_bt.c b/examples/bluetooth/ble_adv/main/app_bt.c index 67ab2c8fe0..31e8f2fa00 100644 --- a/examples/bluetooth/ble_adv/main/app_bt.c +++ b/examples/bluetooth/ble_adv/main/app_bt.c @@ -13,10 +13,13 @@ // limitations under the License. #include +#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "bt.h" -#include +#include "esp_log.h" + +static const char *tag = "BLE_ADV"; #define HCI_H4_CMD_PREAMBLE_SIZE (4) @@ -214,9 +217,15 @@ void bleAdvtTask(void *pvParameters) void app_main() { - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + + if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + ESP_LOGI(tag, "Bluetooth controller initialize failed"); + return; + } if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + ESP_LOGI(tag, "Bluetooth controller enable failed"); return; } diff --git a/examples/bluetooth/blufi/main/blufi_example_main.c b/examples/bluetooth/blufi/main/blufi_example_main.c index 05f39c4859..2a3f2ce629 100644 --- a/examples/bluetooth/blufi/main/blufi_example_main.c +++ b/examples/bluetooth/blufi/main/blufi_example_main.c @@ -315,7 +315,11 @@ void app_main() ESP_ERROR_CHECK( nvs_flash_init() ); initialise_wifi(); - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + BLUFI_ERROR("%s initialize bt controller failed\n", __func__); + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { diff --git a/examples/bluetooth/controller_hci_uart/Makefile b/examples/bluetooth/controller_hci_uart/Makefile new file mode 100644 index 0000000000..0773931993 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := controller_hci_uart + +include $(IDF_PATH)/make/project.mk diff --git a/examples/bluetooth/controller_hci_uart/README.rst b/examples/bluetooth/controller_hci_uart/README.rst new file mode 100644 index 0000000000..f51c6c2c68 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/README.rst @@ -0,0 +1,7 @@ +ESP-IDF UART HCI Controller +=========================== + +This is a btdm controller use UART as HCI IO. This require the UART device support RTS/CTS mandatory. +It can do the configuration of UART number and UART baudrate by menuconfig. + + diff --git a/examples/bluetooth/controller_hci_uart/main/component.mk b/examples/bluetooth/controller_hci_uart/main/component.mk new file mode 100644 index 0000000000..a98f634eae --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/main/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c b/examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c new file mode 100644 index 0000000000..6270596d92 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/main/controller_hci_uart_demo.c @@ -0,0 +1,53 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "bt.h" +#include "driver/uart.h" +#include "esp_log.h" + +static const char *tag = "CONTROLLER_UART_HCI"; + +static void uart_gpio_reset(void) +{ +#if CONFIG_BT_HCI_UART_NO + ESP_LOGI(tag, "HCI UART%d Pin select: TX 5, RX, 18, CTS 23, RTS 19", CONFIG_BT_HCI_UART_NO); + + uart_set_pin(CONFIG_BT_HCI_UART_NO, 5, 18, 19, 23); +#endif +} + +void app_main() +{ + esp_err_t ret; + + /* As the UART1/2 pin conflict with flash pin, so do matrix of the signal and pin */ + uart_gpio_reset(); + + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed, ret %d", ret); + return; + } + + ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); + if (ret != ESP_OK) { + ESP_LOGE(tag, "Bluetooth Controller initialize failed, ret %d", ret); + return; + } +} + diff --git a/examples/bluetooth/controller_hci_uart/sdkconfig.defaults b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults new file mode 100644 index 0000000000..32a86537f6 --- /dev/null +++ b/examples/bluetooth/controller_hci_uart/sdkconfig.defaults @@ -0,0 +1,10 @@ +# Override some defaults so BT stack is enabled +# in this example + +# +# BT config +# +CONFIG_BT_ENABLED=y +CONFIG_BT_HCI_UART=y +CONFIG_BT_HCI_UART_NO_DEFAULT=1 +CONFIG_BT_HCI_UART_BAUDRATE_DEFAULT=921600 diff --git a/examples/bluetooth/gatt_client/main/gattc_demo.c b/examples/bluetooth/gatt_client/main/gattc_demo.c index 2904484913..9985ccdc3b 100644 --- a/examples/bluetooth/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/gatt_client/main/gattc_demo.c @@ -402,7 +402,8 @@ void gattc_client_test(void) void app_main() { - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BTDM); gattc_client_test(); diff --git a/examples/bluetooth/gatt_server/main/gatts_demo.c b/examples/bluetooth/gatt_server/main/gatts_demo.c index 39d33286a0..934078aa73 100644 --- a/examples/bluetooth/gatt_server/main/gatts_demo.c +++ b/examples/bluetooth/gatt_server/main/gatts_demo.c @@ -398,7 +398,12 @@ void app_main() { esp_err_t ret; - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TAG, "%s initialize controller failed\n", __func__); + return; + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) { diff --git a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c index 9bb03e7e89..291d9f5941 100644 --- a/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c +++ b/examples/bluetooth/gatt_server_service_table/main/gatts_table_creat_demo.c @@ -313,7 +313,12 @@ void app_main() { esp_err_t ret; - esp_bt_controller_init(); + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + ret = esp_bt_controller_init(&bt_cfg); + if (ret) { + ESP_LOGE(GATTS_TABLE_TAG, "%s enable controller failed\n", __func__); + return; + } ret = esp_bt_controller_enable(ESP_BT_MODE_BTDM); if (ret) {