diff options
| author | cooljqln <cooljqln@noreply.codeberg.org> | 2025-08-04 03:39:45 +0200 |
|---|---|---|
| committer | cooljqln <cooljqln@noreply.codeberg.org> | 2025-08-04 03:39:45 +0200 |
| commit | fd064b996a432074b3e5c18b6a8c5439a372f281 (patch) | |
| tree | 4e3b2880e11f3169000d4273323399677af8c05f /lib/bt/controller | |
| parent | df8fc4104e5ed884f3b52257558191955375d1e7 (diff) | |
| parent | f4eea3a18add40b84ea2494970ef5945c755f578 (diff) | |
| download | tangara-fw-fd064b996a432074b3e5c18b6a8c5439a372f281.tar.gz | |
Merge pull request 'Update esp-idf to the v5.5' (#418) from jqln/idfv5.5 into main
Reviewed-on: https://codeberg.org/cool-tech-zone/tangara-fw/pulls/418
Diffstat (limited to 'lib/bt/controller')
43 files changed, 5678 insertions, 1466 deletions
diff --git a/lib/bt/controller/esp32/Kconfig.in b/lib/bt/controller/esp32/Kconfig.in index 7254a6ae..d3c04a11 100644 --- a/lib/bt/controller/esp32/Kconfig.in +++ b/lib/bt/controller/esp32/Kconfig.in @@ -23,6 +23,14 @@ config BTDM_CTRL_BLE_MAX_CONN BLE maximum connections of bluetooth controller. Each connection uses 1KB static DRAM whenever the BT controller is enabled. +config BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT + int "BR/EDR default minimum size of encryption key" + depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM + default 7 + range 7 16 + help + BR/EDR default minimum size of encryption key when start encryption. + config BTDM_CTRL_BR_EDR_MAX_ACL_CONN int "BR/EDR ACL Max Connections" depends on BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM @@ -67,7 +75,7 @@ config BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF default 0 menuconfig BTDM_CTRL_PCM_ROLE_EDGE_CONFIG - bool "PCM Signal Config (Role and Polar)" + bool "PCM Signal Configurations: Role, Polar and Channel Mode(Stereo/Mono)" depends on BTDM_CTRL_BR_EDR_SCO_DATA_PATH_PCM default y @@ -95,6 +103,37 @@ choice BTDM_CTRL_PCM_POLAR bool "Rising Edge" endchoice +choice BTDM_CTRL_PCM_FSYNCSHP + prompt "Channel Mode(Stereo/Mono)" + depends on BTDM_CTRL_PCM_ROLE_EDGE_CONFIG + default BTDM_CTRL_PCM_FSYNCSHP_STEREO_MODE + help + PCM frame synchronization signal shape can be configured as Stereo Mode or Mono Mode. + (There are detailed instructions under the path examples/bluetooth/bluedroid/classic_bt/hfp_ag/README.md) + + config BTDM_CTRL_PCM_FSYNCSHP_STEREO_MODE + bool "Stereo Mode" + help + Stereo Mode(Dual channel): FSYNC and DOUT signals both change simultaneously on the edge of CLK. + The FSYNC signal continues until the end of the current channel-data transmission. + (There is a waveform graph under the path examples/bluetooth/bluedroid/classic_bt/hfp_ag/image) + + config BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_LF + bool "Mono Mode 1" + help + Mono Mode 1(Single channel): FSYNC signal starts to change a CLK clock cycle earlier than the DOUT signal. + The FSYNC signal continues for one extra CLK clock cycle. + (There is a waveform graph under the path examples/bluetooth/bluedroid/classic_bt/hfp_ag/image) + + config BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_FF + bool "Mono Mode 2" + help + Mono Mode 2(Single channel): FSYNC and DOUT signals both change simultaneously on the edge of CLK. + The FSYNC signal continues for one extra CLK clock cycle. + (There is a waveform graph under the path examples/bluetooth/bluedroid/classic_bt/hfp_ag/image) + +endchoice + config BTDM_CTRL_PCM_ROLE_EFF int default 0 if BTDM_CTRL_PCM_ROLE_MASTER @@ -107,6 +146,13 @@ config BTDM_CTRL_PCM_POLAR_EFF default 1 if BTDM_CTRL_PCM_POLAR_RISING_EDGE default 0 +config BTDM_CTRL_PCM_FSYNCSHP_EFF + int + default 0 if BTDM_CTRL_PCM_FSYNCSHP_STEREO_MODE + default 1 if BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_LF + default 2 if BTDM_CTRL_PCM_FSYNCSHP_MONO_MODE_FF + default 0 + config BTDM_CTRL_AUTO_LATENCY bool "Auto latency" depends on BTDM_CTRL_MODE_BTDM @@ -139,6 +185,11 @@ config BTDM_CTRL_BLE_MAX_CONN_EFF default BTDM_CTRL_BLE_MAX_CONN if BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM default 0 +config BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT_EFF + int + default BTDM_CTRL_BR_EDR_MIN_ENC_KEY_SZ_DFT if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM + default 0 + config BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF int default BTDM_CTRL_BR_EDR_MAX_ACL_CONN if BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM @@ -262,10 +313,10 @@ menu "MODEM SLEEP Options" the bluetooth low power clock source. config BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL - bool "External 32kHz crystal" - depends on RTC_CLK_SRC_EXT_CRYS + bool "External 32kHz crystal/oscillator" + depends on RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC help - External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency + External 32kHz crystal/oscillator has a nominal frequency of 32.768kHz and provides good frequency stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth modem sleep to be used with both DFS and light sleep. endchoice @@ -282,7 +333,7 @@ choice BTDM_BLE_SLEEP_CLOCK_ACCURACY needs a larger RX window to synchronize with master in each anchor point, thus resulting in an increase of power consumption but a higher level of robustness in keeping connected. According to the requirements of Bluetooth Core specification 4.2, the worst-case accuracy of Classic - Bluetooth low power oscialltor(LPO) is +/-250ppm in STANDBY and in low power modes such as + Bluetooth Low Power Oscillator (LPO) is +/-250ppm in STANDBY and in low power modes such as sniff. For BLE the worst-case SCA is +/-500ppm. - "151ppm to 250ppm" option is the default value for Bluetooth Dual mode @@ -403,9 +454,18 @@ config BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX default n help Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to - minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active + minimize collision of scan request PDUs from multiple scanners. If scan backoff is disabled, in active scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU. +config BTDM_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + + config BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP bool "BLE adv report flow control supported" depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY) @@ -440,6 +500,48 @@ config BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD If you set `BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD` to a small value or printf every adv lost event, it may cause adv packets lost more. +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BTDM_BLE_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + depends on (BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM) + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BTDM_BLE_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + depends on (BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM) + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. +endmenu + +config BTDM_BLE_CHAN_ASS_EN + bool "Enable channel assessment" + depends on (BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM) + default y + help + If this option is enabled, The Controller will records the communication quality + for each channel and then start a timer to check and update the channel map every 4 seconds. + +config BTDM_BLE_PING_EN + bool "Enable LE Ping procedure" + depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY) + default y + help + If this option is disabled, The Controller will not start the LE authenticated payload timer. + This option is used for some compatibility problems related to LE ping procedure. + +config BTDM_CTRL_CONTROLLER_DEBUG_MODE_1 + bool "Enable Bluetooth controller debugging mode 1 (for internal use only)" + default n + depends on BT_ENABLED + help + Enables specific debugging features for the Bluetooth controller. + This option is strictly for internal debugging purposes and should not be enabled in production environments, + as it may impact performance and stability. config BTDM_RESERVE_DRAM hex diff --git a/lib/bt/controller/esp32/bt.c b/lib/bt/controller/esp32/bt.c index f26dd4bc..4f95d120 100644 --- a/lib/bt/controller/esp32/bt.c +++ b/lib/bt/controller/esp32/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -48,6 +48,10 @@ #include "esp_rom_sys.h" #include "hli_api.h" +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + #if CONFIG_BT_ENABLED /* Macro definition @@ -96,6 +100,7 @@ do{\ #define OSI_VERSION 0x00010005 #define OSI_MAGIC_VALUE 0xFADEBEAD +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL) /* Types definition ************************************************************************ */ @@ -248,6 +253,16 @@ extern void config_bt_funcs_reset(void); extern void config_ble_funcs_reset(void); extern void config_btdm_funcs_reset(void); +#ifdef CONFIG_BT_BLUEDROID_ENABLED +extern void bt_stack_enableSecCtrlVsCmd(bool en); +#endif // CONFIG_BT_BLUEDROID_ENABLED +#if defined(CONFIG_BT_NIMBLE_ENABLED) || defined(CONFIG_BT_BLUEDROID_ENABLED) +extern void bt_stack_enableCoexVsCmd(bool en); +extern void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +extern void adv_stack_enableClearLegacyAdvVsCmd(bool en); +extern void advFilter_stack_enableDupExcListVsCmd(bool en); +#endif // (CONFIG_BT_NIMBLE_ENABLED) || (CONFIG_BT_BLUEDROID_ENABLED) + /* Local Function Declare ********************************************************************* */ @@ -448,7 +463,11 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit f #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG // used low power clock -static DRAM_ATTR uint8_t btdm_lpclk_sel; +#if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL +static DRAM_ATTR uint8_t btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL; +#else +static DRAM_ATTR uint8_t btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL; +#endif /* CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL */ #endif /* #ifdef CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG */ static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL; @@ -868,7 +887,21 @@ static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no) static void *malloc_internal_wrapper(size_t size) { - return heap_caps_malloc(size, MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL); + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +void *malloc_ble_controller_mem(size_t size) +{ + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); + if(p == NULL) { + ESP_LOGE(BTDM_LOG_TAG, "Malloc failed"); + } + return p; +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); } static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) @@ -932,7 +965,7 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles) assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US); // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift // and set the timer in advance - uint32_t uncertainty = (us_to_sleep >> 11); + uint32_t uncertainty = (us_to_sleep / 1000); if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) { uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US; } @@ -1027,9 +1060,8 @@ static bool async_wakeup_request(int event) switch (event) { case BTDM_ASYNC_WAKEUP_REQ_HCI: - btdm_in_wakeup_requesting_set(true); - // NO break case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA: + btdm_in_wakeup_requesting_set(true); if (!btdm_power_state_active()) { do_wakeup_request = true; @@ -1062,10 +1094,10 @@ static void async_wakeup_request_end(int event) bool request_lock = false; switch (event) { case BTDM_ASYNC_WAKEUP_REQ_HCI: + case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA: request_lock = true; break; case BTDM_ASYNC_WAKEUP_REQ_COEX: - case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA: request_lock = false; break; default: @@ -1330,7 +1362,8 @@ static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode) //already released if (!(mode & btdm_dram_available_region[0].mode)) { - return ESP_ERR_INVALID_STATE; + ESP_LOGW(BTDM_LOG_TAG, "%s already released, mode %d",__func__, mode); + return ESP_OK; } for (int i = 0; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) { @@ -1432,6 +1465,14 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) .name = "BT Controller Data" }; + /* + * Free data and BSS section for Bluetooth controller ROM code. + * Note that rom mem release must be performed before section _bt_data_start to _bt_data_end is released, + * otherwise `btdm_dram_available_region` will no longer be available when performing rom mem release and + * thus causing heap corruption. + */ + ret = esp_bt_controller_rom_mem_release(mode); + if (mode == ESP_BT_MODE_BTDM) { /* Start by freeing Bluetooth BSS section */ if (ret == ESP_OK) { @@ -1444,11 +1485,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) } } - /* free data and BSS section for Bluetooth controller ROM code */ - if (ret == ESP_OK) { - ret = esp_bt_controller_rom_mem_release(mode); - } - return ret; } @@ -1472,6 +1508,117 @@ static void hli_queue_setup_pinned_to_core(int core_id) } #endif /* CONFIG_BTDM_CTRL_HLI */ +// init low-power control resources +static esp_err_t btdm_low_power_mode_init(void) +{ + esp_err_t err = ESP_OK; + +#ifdef CONFIG_PM_ENABLE + s_btdm_allow_light_sleep = false; +#endif + + // set default sleep clock cycle and its fractional bits + btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; + btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); + +#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG + if (btdm_lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { + // check whether or not EXT_CRYS is working + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { +#ifdef CONFIG_PM_ENABLE + s_btdm_allow_light_sleep = true; +#endif + } else { + ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n" + "light sleep mode will not be able to apply when bluetooth is enabled"); + btdm_lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL; // set default value + } + } else if (btdm_lpclk_sel != ESP_BT_SLEEP_CLOCK_MAIN_XTAL) { + assert(0); + } + + bool select_src_ret __attribute__((unused)); + bool set_div_ret __attribute__((unused)); + if (btdm_lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) { + select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL); + set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() * 2 / MHZ - 1); + assert(select_src_ret && set_div_ret); + btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; + btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); + } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K + select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K); + set_div_ret = btdm_lpclk_set_div(0); + assert(select_src_ret && set_div_ret); + btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; + btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) : + (1000000 >> (15 - RTC_CLK_CAL_FRACT)); + assert(btdm_lpcycle_us != 0); + } + btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG); + +#elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED + btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_EVED); +#else + btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); +#endif + +#ifdef CONFIG_PM_ENABLE + if (!s_btdm_allow_light_sleep) { + if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) { + return err; + } + } + if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) { + return err; + } + esp_timer_create_args_t create_args = { + .callback = btdm_slp_tmr_callback, + .arg = NULL, + .name = "btSlp" + }; + if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) { + return err; + } + + s_pm_lock_acquired = true; +#endif + + return err; +} + +esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void) +{ +#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG + if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED && + btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { + return ESP_BT_SLEEP_CLOCK_NONE; + } + return btdm_lpclk_sel; +#else + return ESP_BT_SLEEP_CLOCK_NONE; +#endif +} + +esp_err_t esp_bt_set_lpclk_src(esp_bt_sleep_clock_t lpclk) +{ +#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG + if (lpclk < ESP_BT_SLEEP_CLOCK_MAIN_XTAL || lpclk > ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { + return ESP_ERR_INVALID_ARG; + } + + if (btdm_controller_status == ESP_BT_CONTROLLER_STATUS_INITED || + btdm_controller_status == ESP_BT_CONTROLLER_STATUS_ENABLED) { + ESP_LOGW(BTDM_LOG_TAG, "Please set the Bluetooth sleep clock source before Bluetooth initialization"); + return ESP_ERR_INVALID_STATE; + } + + btdm_lpclk_sel = lpclk; + return ESP_OK; +#else + return ESP_ERR_NOT_SUPPORTED; +#endif +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { esp_err_t err; @@ -1534,58 +1681,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) btdm_controller_mem_init(); periph_module_enable(PERIPH_BT_MODULE); - -#ifdef CONFIG_PM_ENABLE - s_btdm_allow_light_sleep = false; -#endif - - // set default sleep clock cycle and its fractional bits - btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; - btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); - -#if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG - - btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value -#if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL - // check whether or not EXT_CRYS is working - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32kHz XTAL -#ifdef CONFIG_PM_ENABLE - s_btdm_allow_light_sleep = true; -#endif - } else { - ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n" - "light sleep mode will not be able to apply when bluetooth is enabled"); - btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value - } -#else - btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value -#endif - - bool select_src_ret __attribute__((unused)); - bool set_div_ret __attribute__((unused)); - if (btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL) { - select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL); - set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() * 2 / MHZ - 1); - assert(select_src_ret && set_div_ret); - btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; - btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac); - } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K - select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K); - set_div_ret = btdm_lpclk_set_div(0); - assert(select_src_ret && set_div_ret); - btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT; - btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) : - (1000000 >> (15 - RTC_CLK_CAL_FRACT)); - assert(btdm_lpcycle_us != 0); - } - btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG); - -#elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED - btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_EVED); -#else - btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); -#endif + periph_module_reset(PERIPH_BT_MODULE); #if CONFIG_BTDM_CTRL_HCI_UART_FLOW_CTRL_EN sdk_config_set_uart_flow_ctrl_enable(true); @@ -1593,44 +1689,53 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) sdk_config_set_uart_flow_ctrl_enable(false); #endif -#ifdef CONFIG_PM_ENABLE - if (!s_btdm_allow_light_sleep) { - if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) { - goto error; - } - } - if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) { - goto error; - } - esp_timer_create_args_t create_args = { - .callback = btdm_slp_tmr_callback, - .arg = NULL, - .name = "btSlp" - }; - if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) { + if ((err = btdm_low_power_mode_init()) != ESP_OK) { + ESP_LOGE(BTDM_LOG_TAG, "Low power module initialization failed"); goto error; } - s_pm_lock_acquired = true; -#endif - #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + ESP_LOGE(BTDM_LOG_TAG, "BLE Log SPI output init failed"); + err = ESP_ERR_NO_MEM; + goto error; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + btdm_cfg_mask = btdm_config_mask_load(); - if (btdm_controller_init(btdm_cfg_mask, cfg) != 0) { + err = btdm_controller_init(btdm_cfg_mask, cfg); + + if (err != 0) { + ESP_LOGE(BTDM_LOG_TAG, "%s %d\n",__func__,err); err = ESP_ERR_NO_MEM; goto error; } +#ifdef CONFIG_BT_BLUEDROID_ENABLED + bt_stack_enableSecCtrlVsCmd(true); +#endif // CONFIG_BT_BLUEDROID_ENABLED +#if defined(CONFIG_BT_NIMBLE_ENABLED) || defined(CONFIG_BT_BLUEDROID_ENABLED) + bt_stack_enableCoexVsCmd(true); + scan_stack_enableAdvFlowCtrlVsCmd(true); + adv_stack_enableClearLegacyAdvVsCmd(true); + advFilter_stack_enableDupExcListVsCmd(true); +#endif // (CONFIG_BT_NIMBLE_ENABLED) || (CONFIG_BT_BLUEDROID_ENABLED) + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; return ESP_OK; error: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + bt_controller_deinit_internal(); return err; @@ -1642,17 +1747,30 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_ERR_INVALID_STATE; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + btdm_controller_deinit(); bt_controller_deinit_internal(); +#ifdef CONFIG_BT_BLUEDROID_ENABLED + bt_stack_enableSecCtrlVsCmd(false); +#endif // CONFIG_BT_BLUEDROID_ENABLED +#if defined(CONFIG_BT_NIMBLE_ENABLED) || defined(CONFIG_BT_BLUEDROID_ENABLED) + bt_stack_enableCoexVsCmd(false); + scan_stack_enableAdvFlowCtrlVsCmd(false); + adv_stack_enableClearLegacyAdvVsCmd(false); + advFilter_stack_enableDupExcListVsCmd(false); +#endif // (CONFIG_BT_NIMBLE_ENABLED) || (CONFIG_BT_BLUEDROID_ENABLED) + return ESP_OK; } -static void bt_controller_deinit_internal(void) +// deinit low power control resources +static void btdm_low_power_mode_deinit(void) { - periph_module_disable(PERIPH_BT_MODULE); - #ifdef CONFIG_PM_ENABLE if (!s_btdm_allow_light_sleep) { esp_pm_lock_delete(s_light_sleep_pm_lock); @@ -1673,6 +1791,16 @@ static void bt_controller_deinit_internal(void) s_pm_lock_acquired = false; #endif + btdm_lpcycle_us = 0; + btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); +} + +static void bt_controller_deinit_internal(void) +{ + periph_module_disable(PERIPH_BT_MODULE); + + btdm_low_power_mode_deinit(); + if (s_wakeup_req_sem) { semphr_delete_wrapper(s_wakeup_req_sem); s_wakeup_req_sem = NULL; @@ -1685,9 +1813,6 @@ static void bt_controller_deinit_internal(void) btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; - btdm_lpcycle_us = 0; - btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE); - esp_bt_power_domain_off(); esp_phy_modem_deinit(); @@ -1798,6 +1923,7 @@ esp_err_t esp_bt_controller_disable(void) while (!btdm_power_state_active()) { esp_rom_delay_us(1000); } + async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA); } btdm_controller_disable(); @@ -1910,7 +2036,7 @@ esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path) return ESP_OK; } -esp_err_t esp_ble_scan_dupilcate_list_flush(void) +esp_err_t esp_ble_scan_duplicate_list_flush(void) { if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; @@ -1919,6 +2045,11 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void) return ESP_OK; } +esp_err_t esp_ble_scan_dupilcate_list_flush(void) +{ + return esp_ble_scan_duplicate_list_flush(); +} + /** * This function re-write controller's function, * As coredump can not show parameters in function which is in a .a file. diff --git a/lib/bt/controller/esp32c2/Kconfig.in b/lib/bt/controller/esp32c2/Kconfig.in index 9a04ae63..c720fcb8 100644 --- a/lib/bt/controller/esp32c2/Kconfig.in +++ b/lib/bt/controller/esp32c2/Kconfig.in @@ -2,15 +2,15 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice @@ -73,12 +73,26 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 2048 help - Set the size of uart task stack + This configures stack size of hci transport task endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -95,85 +109,99 @@ menuconfig BT_LE_50_FEATURE_SUPPORT help Enable BLE 5 feature -config BT_LE_LL_CFG_FEAT_LE_2M_PHY - bool "Enable 2M Phy" - depends on BT_LE_50_FEATURE_SUPPORT - default y - help - Enable 2M-PHY - -config BT_LE_LL_CFG_FEAT_LE_CODED_PHY - bool "Enable coded Phy" - depends on BT_LE_50_FEATURE_SUPPORT - default y - help - Enable coded-PHY - -config BT_LE_EXT_ADV - bool "Enable extended advertising" - depends on BT_LE_50_FEATURE_SUPPORT - default y - help - Enable this option to do extended advertising. Extended advertising - will be supported from BLE 5.0 onwards. - -if BT_LE_EXT_ADV - config BT_LE_MAX_EXT_ADV_INSTANCES - int "Maximum number of extended advertising instances." - range 0 4 - default 1 - depends on BT_LE_EXT_ADV - help - Change this option to set maximum number of extended advertising - instances. Minimum there is always one instance of - advertising. Enter how many more advertising instances you - want. - Each extended advertising instance will take about 0.5k DRAM. - - config BT_LE_EXT_ADV_MAX_SIZE - int "Maximum length of the advertising data." - range 0 1650 - default 1650 - depends on BT_LE_EXT_ADV +if BT_LE_50_FEATURE_SUPPORT + config BT_LE_LL_CFG_FEAT_LE_2M_PHY + bool "Enable 2M Phy" + depends on BT_LE_50_FEATURE_SUPPORT + default y help - Defines the length of the extended adv data. The value should not - exceed 1650. + Enable 2M-PHY - config BT_LE_ENABLE_PERIODIC_ADV - bool "Enable periodic advertisement." + config BT_LE_LL_CFG_FEAT_LE_CODED_PHY + bool "Enable coded Phy" + depends on BT_LE_50_FEATURE_SUPPORT default y - depends on BT_LE_EXT_ADV help - Enable this option to start periodic advertisement. + Enable coded-PHY - config BT_LE_PERIODIC_ADV_SYNC_TRANSFER - bool "Enable Transfer Sync Events" - depends on BT_LE_ENABLE_PERIODIC_ADV + config BT_LE_EXT_ADV + bool "Enable extended advertising" + depends on BT_LE_50_FEATURE_SUPPORT default y help - This enables controller transfer periodic sync events to host + Enable this option to do extended advertising. Extended advertising + will be supported from BLE 5.0 onwards. + + if BT_LE_EXT_ADV + config BT_LE_MAX_EXT_ADV_INSTANCES + int "Maximum number of extended advertising instances." + range 0 4 + default 1 + depends on BT_LE_EXT_ADV + help + Change this option to set maximum number of extended advertising + instances. Minimum there is always one instance of + advertising. Enter how many more advertising instances you + want. + Each extended advertising instance will take about 0.5k DRAM. + + config BT_LE_EXT_ADV_MAX_SIZE + int "Maximum length of the advertising data." + range 0 1650 + default 1650 + depends on BT_LE_EXT_ADV + help + Defines the length of the extended adv data. The value should not + exceed 1650. -endif + config BT_LE_ENABLE_PERIODIC_ADV + bool "Enable periodic advertisement." + default y + depends on BT_LE_EXT_ADV + help + Enable this option to start periodic advertisement. -config BT_LE_MAX_PERIODIC_SYNCS - int "Maximum number of periodic advertising syncs" - depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED + config BT_LE_PERIODIC_ADV_SYNC_TRANSFER + bool "Enable Transfer Sync Events" + depends on BT_LE_ENABLE_PERIODIC_ADV + default y + help + This enables controller transfer periodic sync events to host + endif - range 0 3 - default 1 if BT_LE_ENABLE_PERIODIC_ADV - default 0 - help - Set this option to set the upper limit for number of periodic sync - connections. This should be less than maximum connections allowed by - controller. + config BT_LE_EXT_SCAN + bool "Enable extended scanning" + depends on BT_LE_50_FEATURE_SUPPORT && BT_LE_ROLE_OBSERVER_ENABLE + default y + help + Enable this option to do extended scanning. -config BT_LE_MAX_PERIODIC_ADVERTISER_LIST - int "Maximum number of periodic advertiser list" - depends on BT_LE_50_FEATURE_SUPPORT && !BT_NIMBLE_ENABLED - range 1 5 - default 5 - help - Set this option to set the upper limit for number of periodic advertiser list. + config BT_LE_ENABLE_PERIODIC_SYNC + bool "Enable periodic sync" + default y + depends on BT_LE_EXT_SCAN + help + Enable this option to receive periodic advertisement. + + if BT_LE_ENABLE_PERIODIC_SYNC + config BT_LE_MAX_PERIODIC_SYNCS + int "Maximum number of periodic advertising syncs" + range 0 3 + default 1 if BT_LE_ENABLE_PERIODIC_ADV + default 0 + help + Set this option to set the upper limit for number of periodic sync + connections. This should be less than maximum connections allowed by + controller. + + config BT_LE_MAX_PERIODIC_ADVERTISER_LIST + int "Maximum number of periodic advertiser list" + range 1 5 + default 5 + help + Set this option to set the upper limit for number of periodic advertiser list. + endif +endif menu "Memory Settings" depends on !BT_NIMBLE_ENABLED @@ -280,6 +308,33 @@ config BT_LE_CONTROLLER_LOG_DUMP_ONLY help Only operate in dump mode +config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + bool "Output ble controller logs to SPI bus (Experimental)" + depends on BT_LE_CONTROLLER_LOG_ENABLED + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + select BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Output ble controller logs to SPI bus + +config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + +config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + config BT_LE_LOG_CTRL_BUF1_SIZE int "size of the first BLE controller LOG buffer" depends on BT_LE_CONTROLLER_LOG_ENABLED @@ -301,6 +356,19 @@ config BT_LE_LOG_HCI_BUF_SIZE help Configure the size of the BLE HCI LOG buffer. +config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE + bool "Enable wrap panic handler" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Wrap esp_panic_handler to get controller logs when PC pointer exception crashes. + +config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + bool "Enable esp_task_wdt_isr_user_handler implementation" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered. config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" range 1 5 @@ -356,7 +424,7 @@ config BT_LE_CRYPTO_STACK_MBEDTLS config BT_LE_WHITELIST_SIZE int "BLE white list size" - range 1 15 + range 1 31 default 12 depends on !BT_NIMBLE_ENABLED @@ -377,6 +445,23 @@ config BT_LE_LL_SCA help Sleep clock accuracy of our device (in ppm) +config BT_LE_LL_PEER_SCA_SET_ENABLE + bool "Enable to set constant peer SCA" + default n + help + Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM. + Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value + to calculate the window widening instead of the value received from peer device. + + +config BT_LE_LL_PEER_SCA + int "Constant peer sleep clock accuracy value" + range 0 10000 + depends on BT_LE_LL_PEER_SCA_SET_ENABLE + default 0 + help + Set the sleep clock accuracy of peer device + config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED @@ -491,14 +576,22 @@ config BT_LE_TX_CCA_ENABLED help Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold. +config BT_LE_DTM_ENABLED + bool "Enable Direct Test Mode (DTM) feature" + default n + config BT_LE_CCA_RSSI_THRESH int "CCA RSSI threshold value" depends on BT_LE_TX_CCA_ENABLED range 20 100 - default 20 + default 65 help Power threshold of CCA in unit of -1 dBm. +config BT_LE_FEAT_LL_ENCRYPTION + bool "Enable controller ACL encryption" + default y + config BT_LE_ROLE_CENTROL_ENABLE bool "Enable BLE Centrol role function" depends on !BT_NIMBLE_ENABLED @@ -526,3 +619,126 @@ config BT_LE_ROLE_OBSERVER_ENABLE default y help Enable observer role function. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 + +config BT_CTRL_RUN_IN_FLASH_ONLY + bool "Reduce BLE IRAM usage (READ DOCS FIRST) (EXPERIMENTAL)" + default n + help + Move most IRAM into flash. This will increase the usage of flash and reduce ble performance. + Because the code is moved to the flash, the execution speed of the code is reduced. + To have a small impact on performance, you need to enable flash suspend (SPI_FLASH_AUTO_SUSPEND). + + - Only one Tx-Rx can be performed in each connection interval. Therefore, reduce the connection interval + as much as possible to improve the throughput. If you want higher connection performance, you can + enable BT_LE_PLACE_CONN_RELATED_INTO_IRAM to put the connection-related code into iram. + - For HCI_LE_Extended_Create_Connection command, only 1M phy's connection parameters will be applied. + Other phys' will be ignored. + - For extended scanning, we may be unable to receive the extended adv with 300us MAFS. + - To match performance, phy needs to be reduced, you need to disable ESP_PHY_IRAM_OPT. + +config BT_LE_PLACE_CONN_RELATED_INTO_IRAM + bool "Place the connection-related code into IRAM" + depends on BT_CTRL_RUN_IN_FLASH_ONLY + default n + +config BT_LE_PLACE_SLEEP_RELATED_INTO_IRAM + bool + depends on BT_CTRL_RUN_IN_FLASH_ONLY && BT_LE_SLEEP_ENABLE + default y + +config BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_LE_CTRL_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_LE_CTRL_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu + +config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + int "The value of upperlimitmax during scan backoff procedure" + range 1 256 + default 32 + help + The value of upperlimitmax needs to be a power of 2. diff --git a/lib/bt/controller/esp32c2/ble.c b/lib/bt/controller/esp32c2/ble.c new file mode 100644 index 00000000..dd6db35e --- /dev/null +++ b/lib/bt/controller/esp32c2/ble.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include <stdlib.h> + +#include "sdkconfig.h" +#include "esp_bt_cfg.h" + +/* External functions or variables + ************************************************************************ + */ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +void adv_stack_enableClearLegacyAdvVsCmd(bool en); +void chanSel_stack_enableSetCsaVsCmd(bool en); +void hci_stack_enableSetVsEvtMaskVsCmd(bool en); + +void adv_stack_enableScanReqRxdVsEvent(bool en); +void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +/* Local functions definition + *************************************************************************** + */ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void ble_stack_enableVsCmds(bool en) +{ +#if DEFAULT_BT_LE_ROLE_BROADCASTER + adv_stack_enableClearLegacyAdvVsCmd(en); +#endif // DEFAULT_BT_LE_ROLE_BROADCASTER + +#if DEFAULT_BT_LE_ROLE_OBSERVER + scan_stack_enableAdvFlowCtrlVsCmd(en); +#endif // DEFAULT_BT_LE_ROLE_OBSERVER + + chanSel_stack_enableSetCsaVsCmd(en); + hci_stack_enableSetVsEvtMaskVsCmd(en); +} + +void ble_stack_enableVsEvents(bool en) +{ +#if DEFAULT_BT_LE_ROLE_BROADCASTER + adv_stack_enableScanReqRxdVsEvent(en); +#endif // DEFAULT_BT_LE_ROLE_BROADCASTER + conn_stack_enableChanMapUpdCompVsEvent(en); +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE +} +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +int ble_stack_enable(void) +{ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsCmds(true); + ble_stack_enableVsEvents(true); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + + return 0; +} + +void ble_stack_disable(void) +{ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsEvents(false); + ble_stack_enableVsCmds(false); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +} diff --git a/lib/bt/controller/esp32c2/ble_priv.h b/lib/bt/controller/esp32c2/ble_priv.h new file mode 100644 index 00000000..024bb042 --- /dev/null +++ b/lib/bt/controller/esp32c2/ble_priv.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _BLE_PRIV_H_ +#define _BLE_PRIV_H_ + +int ble_stack_enable(void); + +void ble_stack_disable(void); + +#endif // _BLE_PRIV_H_ diff --git a/lib/bt/controller/esp32c2/bt.c b/lib/bt/controller/esp32c2/bt.c index 29c33326..a329881e 100644 --- a/lib/bt/controller/esp32c2/bt.c +++ b/lib/bt/controller/esp32c2/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -31,10 +31,11 @@ #endif #include "nimble/nimble_npl_os.h" -#include "ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" +#include "ble_priv.h" #include "esp_intr_alloc.h" #include "esp_sleep.h" #include "esp_pm.h" @@ -44,16 +45,13 @@ #include "soc/syscon_reg.h" #include "soc/modem_clkrst_reg.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" +#include "esp_private/esp_clk_tree_common.h" #include "bt_osi_mem.h" -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif - #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE +#include "esp_private/esp_modem_clock.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -67,6 +65,11 @@ #include "hal/efuse_ll.h" #include "soc/rtc.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + /* Macro definition ************************************************************************ */ @@ -79,17 +82,6 @@ #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf - -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - -typedef enum ble_rtc_slow_clk_src { - BT_SLOW_CLK_SRC_MAIN_XTAL, - BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0, -} ble_rtc_slow_clk_src_t; - /* Types definition ************************************************************************ */ @@ -108,12 +100,12 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); + void (*_rsv1)(int); + int (*_rsv2)(int, int (*)(void *arg), int (*)(void *arg, uint8_t byte), int (*)(void *arg, uint8_t byte), void *); + int (*_rsv3)(int, int32_t, uint8_t, uint8_t, int, int); + int (*_rsv4)(int); + void (*_rsv5)(int, uint8_t); + int (*_rsv6)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); void (*_osi_assert)(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); @@ -126,7 +118,12 @@ struct ext_funcs_t { }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); + +enum { + BLE_LOG_INTERFACE_FLAG_CONTINUE = 0, + BLE_LOG_INTERFACE_FLAG_END, +}; #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables @@ -135,10 +132,12 @@ typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int ble_controller_init(esp_bt_controller_config_t *cfg); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int ble_log_deinit_async(void); +extern int ble_log_init_simple(interface_func_t interface, void *handler); +extern void ble_log_deinit_simple(void); extern void ble_log_async_output_dump_all(bool output); -extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); +extern void esp_panic_handler_feed_wdts(void); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int ble_controller_deinit(void); extern int ble_controller_enable(uint8_t mode); @@ -158,6 +157,9 @@ extern void r_ble_rtc_wake_up_state_clr(void); #if CONFIG_FREERTOS_USE_TICKLESS_IDLE extern void esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE +extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE extern int os_msys_init(void); extern void os_msys_buf_free(void); extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, @@ -170,6 +172,10 @@ extern int ble_get_npl_element_info(esp_bt_controller_config_t *cfg, ble_npl_cou extern void bt_track_pll_cap(void); extern char *ble_controller_get_compile_version(void); extern const char *r_ble_controller_get_rom_compile_version(void); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY +extern void ble_ll_supported_features_init(void); +#endif //CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + #if CONFIG_BT_RELEASE_IRAM extern uint32_t _iram_bt_text_start; extern uint32_t _bss_bt_end; @@ -191,16 +197,6 @@ static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status); static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); @@ -211,16 +207,270 @@ static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** */ +#if (CONFIG_ESP32C2_REV_MIN_FULL < 200) && (!CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY) +void *g_ble_lll_rfmgmt_env_p; +#endif /* Static variable declare */ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +static bool log_is_inited = false; + +esp_err_t esp_bt_controller_log_init(void) +{ + if (log_is_inited) { + return ESP_OK; + } + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + log_is_inited = true; + return ESP_OK; + +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; +} + +void esp_bt_controller_log_deinit(void) +{ +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + assert(log_partition != NULL); + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + ble_log_async_output_dump_all(true); + esp_bt_controller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_feed_wdts(); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(); + assert(err == ESP_OK); + +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) +{ + bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END)); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + + if (len && addr) { + for (int i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); } + } + if (len_append && addr_append) { + for (int i = 0; i < len_append; i++) { esp_rom_printf("%02x ", addr_append[i]); } + } + if (end) { esp_rom_printf("\n"); } + + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +} +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + +void esp_ble_controller_log_dump_all(bool output) +{ +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + BT_ASSERT_PRINT("\r\n[DUMP_START:"); + ble_log_async_output_dump_all(output); + BT_ASSERT_PRINT(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); +#endif +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE +void esp_task_wdt_isr_user_handler(void) +{ + esp_ble_controller_log_dump_all(true); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE +void __real_esp_panic_handler(void *info); +void __wrap_esp_panic_handler (void *info) +{ + esp_ble_controller_log_dump_all(true); + __real_esp_panic_handler(info); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ @@ -229,9 +479,27 @@ static bool s_ble_active = false; static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; #define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +#ifdef CONFIG_XTAL_FREQ_26 +#define MAIN_XTAL_FREQ_HZ (26000000) +static DRAM_ATTR uint32_t s_bt_lpclk_freq = 40000; +#else +#define MAIN_XTAL_FREQ_HZ (40000000) +static DRAM_ATTR uint32_t s_bt_lpclk_freq = 32000; +#endif +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; #define BLE_RTC_DELAY_US (1800) +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA) +void *malloc_ble_controller_mem(size_t size) +{ + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, @@ -248,14 +516,6 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, @@ -302,83 +562,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -/** - * Allocates an mbuf for use by the nimble host. - */ -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -/** - * Allocates an mbuf suitable for an HCI ACL data packet. - * - * @return An empty mbuf on success; null on memory - * exhaustion. - */ -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < CONFIG_FREERTOS_NUMBER_OF_CORES ? core_id : tskNO_AFFINITY)); @@ -408,78 +591,65 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) +static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + int rc = esp_intr_alloc(source, flags, handler, arg, (intr_handle_t *)ret_handle_in); +#else + int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); +#endif -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits,uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); return rc; } -static int hci_uart_close_wrapper(int uart_no) +static int esp_intr_free_wrapper(void **ret_handle) { - int rc = -1; - rc = hci_uart_close(uart_no); + int rc = 0; + rc = esp_intr_free((intr_handle_t) * ret_handle); + *ret_handle = NULL; return rc; } -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) { - //This function is nowhere to use. + return s_bt_lpclk_src; } -static int hci_uart_init_wrapper(int uart_no, void *cfg) +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) { - //This function is nowhere to use. - return 0; -} + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; + s_bt_lpclk_src = clk_src; } -static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) +uint32_t esp_bt_get_lpclk_freq(void) { - int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); - return rc; + return s_bt_lpclk_freq; } -static int esp_intr_free_wrapper(void **ret_handle) +void esp_bt_set_lpclk_freq(uint32_t clk_freq) { - int rc = 0; - rc = esp_intr_free((intr_handle_t) * ret_handle); - *ret_handle = NULL; - return rc; -} + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + if (!clk_freq) { + return; + } -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE -void sleep_modem_light_sleep_overhead_set(uint32_t overhead) -{ - esp_ble_set_wakeup_overhead(overhead); + if (MAIN_XTAL_FREQ_HZ % clk_freq) { + return; + } + + s_bt_lpclk_freq = clk_freq; } -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) +void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { return; @@ -492,20 +662,27 @@ IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) s_ble_active = false; } -IRAM_ATTR void controller_wakeup_cb(void *arg) +void controller_wakeup_cb(void *arg) { if (s_ble_active) { return; } - esp_phy_enable(PHY_MODEM_BT); - // need to check if need to call pm lock here #ifdef CONFIG_PM_ENABLE + esp_pm_config_t pm_config; esp_pm_lock_acquire(s_pm_lock); + esp_pm_get_configuration(&pm_config); + assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz); #endif //CONFIG_PM_ENABLE + esp_phy_enable(PHY_MODEM_BT); + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + uint32_t *clk_freq = (uint32_t *)arg; + *clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + } + // need to check if need to call pm lock here s_ble_active = true; } -esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) +esp_err_t controller_sleep_init(modem_clock_lpclk_src_t slow_clk_src) { esp_err_t rc = 0; #ifdef CONFIG_BT_LE_SLEEP_ENABLE @@ -513,7 +690,7 @@ esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) r_ble_lll_rfmgmt_set_sleep_cb(controller_sleep_cb, controller_wakeup_cb, 0, 0, 500 + BLE_RTC_DELAY_US); #ifdef CONFIG_PM_ENABLE - if (slow_clk_src == BT_SLOW_CLK_SRC_MAIN_XTAL) { + if (slow_clk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON); } else { esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO); @@ -532,7 +709,7 @@ esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); - rc = esp_pm_register_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + rc = esp_pm_register_inform_out_light_sleep_overhead_callback(esp_ble_set_wakeup_overhead); if (rc != ESP_OK) { goto error; } @@ -542,7 +719,7 @@ esp_err_t controller_sleep_init(ble_rtc_slow_clk_src_t slow_clk_src) error: #if CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_sleep_disable_bt_wakeup(); - esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_ble_set_wakeup_overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ /*lock should release first and then delete*/ if (s_pm_lock != NULL) { @@ -559,7 +736,7 @@ void controller_sleep_deinit(void) r_ble_rtc_wake_up_state_clr(); esp_sleep_disable_bt_wakeup(); esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_AUTO); - esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); + esp_pm_unregister_inform_out_light_sleep_overhead_callback(esp_ble_set_wakeup_overhead); #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE #ifdef CONFIG_PM_ENABLE /*lock should release first and then delete*/ @@ -568,23 +745,19 @@ void controller_sleep_deinit(void) #endif //CONFIG_PM_ENABLE } -static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) +static void esp_bt_rtc_slow_clk_select(modem_clock_lpclk_src_t slow_clk_src) { /* Select slow clock source for BT momdule */ switch (slow_clk_src) { - case BT_SLOW_CLK_SRC_MAIN_XTAL: + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); -#ifdef CONFIG_XTAL_FREQ_26 - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 129, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); -#else - SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); -#endif // CONFIG_XTAL_FREQ_26 + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, (MAIN_XTAL_FREQ_HZ/(5 * s_bt_lpclk_freq) - 1), MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); break; - case BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0: + case MODEM_CLOCK_LPCLK_SRC_EXT32K: ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); @@ -592,6 +765,14 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 0, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); break; + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!"); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S); + SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 0, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S); + break; default: ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported slow clock"); assert(0); @@ -601,40 +782,43 @@ static void esp_bt_rtc_slow_clk_select(ble_rtc_slow_clk_src_t slow_clk_src) SET_PERI_REG_BITS(MODEM_CLKRST_ETM_CLK_CONF_REG, 1, 0, MODEM_CLKRST_ETM_CLK_SEL_S); } -static ble_rtc_slow_clk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +static modem_clock_lpclk_src_t ble_rtc_clk_init(esp_bt_controller_config_t *cfg) { - ble_rtc_slow_clk_src_t slow_clk_src; - + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { #if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL -#ifdef CONFIG_XTAL_FREQ_26 - cfg->rtc_freq = 40000; + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; #else - cfg->rtc_freq = 32000; -#endif // CONFIG_XTAL_FREQ_26 - slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; -#else - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { - cfg->rtc_freq = 32768; - slow_clk_src = BT_SLOW_CLK_SRC_32K_XTAL_ON_PIN0; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); -#ifdef CONFIG_XTAL_FREQ_26 - cfg->rtc_freq = 40000; -#else - cfg->rtc_freq = 32000; -#endif // CONFIG_XTAL_FREQ_26 - slow_clk_src = BT_SLOW_CLK_SRC_MAIN_XTAL; +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_OSC_SLOW) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#endif // CONFIG_RTC_CLK_SRC_INT_RC +#endif // CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL } -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ - esp_bt_rtc_slow_clk_select(slow_clk_src); - return slow_clk_src; + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = s_bt_lpclk_freq; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + cfg->ble_ll_sca = 3000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); + return s_bt_lpclk_src; } esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - ble_rtc_slow_clk_src_t rtc_clk_src; + modem_clock_lpclk_src_t rtc_clk_src; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { @@ -655,6 +839,8 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) return ret; } + /* If we place the ble code into flash, don't need to initialize ROM. */ +#if !CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY #if DEFAULT_BT_LE_50_FEATURE_SUPPORT || DEFAULT_BT_LE_ROLE_CENTROL || DEFAULT_BT_LE_ROLE_OBSERVER extern int esp_ble_rom_func_ptr_init_all(void); esp_ble_rom_func_ptr_init_all(); @@ -663,6 +849,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) extern int esp_ble_rom_func_ptr_init_legacy_adv_and_slave(void); esp_ble_rom_func_ptr_init_legacy_adv_and_slave(); #endif +#endif //!CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY /* Initialize the function pointers for OS porting */ npl_freertos_funcs_init(); @@ -712,30 +899,26 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #if CONFIG_SW_COEXIST_ENABLE coex_init(); #endif + +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + ble_ll_supported_features_init(); +#endif //CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + ret = ble_controller_init(cfg); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_init failed %d", ret); goto modem_deint; } +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble rom commit:[%s]", r_ble_controller_get_rom_compile_version()); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto controller_init_err; @@ -751,20 +934,32 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) uint8_t mac[6]; ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + swap_in_place(mac, 6); esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED controller_init_err: - ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); modem_deint: @@ -789,10 +984,11 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED ble_controller_deinit(); @@ -846,6 +1042,12 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) #if CONFIG_SW_COEXIST_ENABLE coex_enable(); #endif + + if (ble_stack_enable() != 0) { + ret = ESP_FAIL; + goto error; + } + if (ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; @@ -855,6 +1057,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_OK; error: + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -877,7 +1080,7 @@ esp_err_t esp_bt_controller_disable(void) if (ble_controller_disable() != 0) { return ESP_FAIL; } - + ble_stack_disable(); if (s_ble_active) { esp_phy_disable(PHY_MODEM_BT); #if CONFIG_PM_ENABLE @@ -1028,9 +1231,17 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ switch (power_type) { case ESP_BLE_PWR_TYPE_DEFAULT: + if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_ADV: + if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0xFF, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_SCAN: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1060,9 +1271,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type esp_err_t stat = ESP_FAIL; switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1085,11 +1300,15 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; + case ESP_BLE_PWR_TYPE_ADV: + tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0); + break; + case ESP_BLE_PWR_TYPE_SCAN: + tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); + break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: case ESP_BLE_PWR_TYPE_CONN_HDL2: @@ -1118,9 +1337,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: @@ -1142,30 +1363,6 @@ uint8_t esp_ble_get_chip_rev_version(void) return efuse_ll_get_chip_wafer_version_minor(); } -#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) -{ - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); - } - if (end) { - esp_rom_printf("\n"); - } -} - -void esp_ble_controller_log_dump_all(bool output) -{ - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; - - portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); - BT_ASSERT_PRINT("\r\n[DUMP_START:"); - ble_log_async_output_dump_all(output); - BT_ASSERT_PRINT(":DUMP_END]\r\n"); - portEXIT_CRITICAL_SAFE(&spinlock); -} -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - #if (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) #if CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #define BLE_SM_KEY_ERR 0x17 diff --git a/lib/bt/controller/esp32c2/dummy.c b/lib/bt/controller/esp32c2/dummy.c new file mode 100644 index 00000000..0621f547 --- /dev/null +++ b/lib/bt/controller/esp32c2/dummy.c @@ -0,0 +1,320 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_bt_cfg.h" + +#define BLE_ERR_UNKNOWN_HCI_CMD (0x01) +/* LL Features */ +#define BLE_LL_FEAT_LE_ENCRYPTION (0x0000000001) +#define BLE_LL_FEAT_CONN_PARM_REQ (0x0000000002) +#define BLE_LL_FEAT_EXTENDED_REJ (0x0000000004) +#define BLE_LL_FEAT_PERIPH_INIT (0x0000000008) +#define BLE_LL_FEAT_LE_PING (0x0000000010) +#define BLE_LL_FEAT_DATA_LEN_EXT (0x0000000020) +#define BLE_LL_FEAT_LL_PRIVACY (0x0000000040) +#define BLE_LL_FEAT_EXT_SCAN_FILT (0x0000000080) +#define BLE_LL_FEAT_LE_2M_PHY (0x0000000100) +#define BLE_LL_FEAT_STABLE_MOD_ID_TX (0x0000000200) +#define BLE_LL_FEAT_STABLE_MOD_ID_RX (0x0000000400) +#define BLE_LL_FEAT_LE_CODED_PHY (0x0000000800) +#define BLE_LL_FEAT_EXT_ADV (0x0000001000) +#define BLE_LL_FEAT_PERIODIC_ADV (0x0000002000) +#define BLE_LL_FEAT_CSA2 (0x0000004000) +#define BLE_LL_FEAT_LE_POWER_CLASS_1 (0x0000008000) +#define BLE_LL_FEAT_MIN_USED_CHAN (0x0000010000) +#define BLE_LL_FEAT_CTE_REQ (0x0000020000) +#define BLE_LL_FEAT_CTE_RSP (0x0000040000) +#define BLE_LL_FEAT_CTE_TX (0x0000080000) +#define BLE_LL_FEAT_CTE_RX (0x0000100000) +#define BLE_LL_FEAT_CTE_AOD (0x0000200000) +#define BLE_LL_FEAT_CTE_AOA (0x0000400000) +#define BLE_LL_FEAT_CTE_RECV (0x0000800000) +#define BLE_LL_FEAT_SYNC_TRANS_SEND (0x0001000000) +#define BLE_LL_FEAT_SYNC_TRANS_RECV (0x0002000000) +#define BLE_LL_FEAT_SCA_UPDATE (0x0004000000) +#define BLE_LL_FEAT_REM_PKEY (0x0008000000) +#define BLE_LL_FEAT_CIS_CENTRAL (0x0010000000) +#define BLE_LL_FEAT_CIS_PERIPH (0x0020000000) +#define BLE_LL_FEAT_ISO_BROADCASTER (0x0040000000) +#define BLE_LL_FEAT_SYNC_RECV (0x0080000000) +#define BLE_LL_FEAT_CIS_HOST (0x0100000000) +#define BLE_LL_FEAT_POWER_CTRL_REQ (0x0200000000) +#define BLE_LL_FEAT_POWER_CHANGE_IND (0x0400000000) +#define BLE_LL_FEAT_PATH_LOSS_MON (0x0800000000) +#define BLE_LL_FEAT_PERIODIC_ADV_ADI (0x1000000000) +#define BLE_LL_FEAT_CONN_SUBRATING (0x2000000000) +#define BLE_LL_FEAT_CONN_SUBRATING_HOST (0x4000000000) +#define BLE_LL_FEAT_CHANNEL_CLASS (0x8000000000) + +uint64_t ble_ll_supported_features; + +void +ble_ll_supported_features_init(void) +{ + ble_ll_supported_features = BLE_LL_FEAT_EXTENDED_REJ; + ble_ll_supported_features |= BLE_LL_FEAT_DATA_LEN_EXT; + +#if DEFAULT_BT_LE_ROLE_CENTROL || DEFAULT_BT_LE_ROLE_PERIPHERAL + ble_ll_supported_features |= BLE_LL_FEAT_PERIPH_INIT; + ble_ll_supported_features |= BLE_LL_FEAT_CONN_PARM_REQ; +#endif + +#if CONFIG_BT_LE_FEAT_LL_ENCRYPTION + ble_ll_supported_features |= BLE_LL_FEAT_LE_ENCRYPTION; +#endif + + ble_ll_supported_features |= (BLE_LL_FEAT_LL_PRIVACY | BLE_LL_FEAT_EXT_SCAN_FILT); + ble_ll_supported_features |= BLE_LL_FEAT_LE_PING; + +#if DEFAULT_BT_LE_EXT_ADV + ble_ll_supported_features |= BLE_LL_FEAT_EXT_ADV; +#endif + +#if DEFAULT_BT_LE_PERIODIC_ADV + ble_ll_supported_features |= BLE_LL_FEAT_PERIODIC_ADV; + ble_ll_supported_features |= BLE_LL_FEAT_PERIODIC_ADV_ADI; +#endif + +#if DEFAULT_BT_LE_PAST + ble_ll_supported_features |= BLE_LL_FEAT_SYNC_TRANS_RECV; + ble_ll_supported_features |= BLE_LL_FEAT_SYNC_TRANS_SEND; +#endif + +#if DEGAULT_BT_LE_2M_PHY + ble_ll_supported_features |= BLE_LL_FEAT_LE_2M_PHY; +#endif + +#if DEGAULT_BT_LE_CODED_PHY + ble_ll_supported_features |= BLE_LL_FEAT_LE_CODED_PHY; +#endif + +#if DEFAULT_BT_LE_50_FEATURE_SUPPORT + ble_ll_supported_features |= BLE_LL_FEAT_CSA2; + ble_ll_supported_features |= BLE_LL_FEAT_SCA_UPDATE; + ble_ll_supported_features |= BLE_LL_FEAT_REM_PKEY; + ble_ll_supported_features |= BLE_LL_FEAT_CHANNEL_CLASS; +#endif +} + +#if !DEFAULT_BT_LE_ROLE_BROADCASTER +void r_ble_ll_adv_rpa_timeout(void) { } +void r_ble_lll_adv_halt(void) { } +void r_ble_lll_adv_event_rmvd_from_sched(void) { } +void r_ble_lll_adv_ext_event_rmvd_from_sched(void) { } +int r_ble_ll_adv_enabled(void) { return 0; } +int r_ble_ll_adv_can_chg_whitelist(void) { return 1; } +int r_ble_ll_adv_set_random_addr(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +void r_ble_ll_adv_reset(void) { } +void r_ble_ll_adv_init(void) { } +void r_ble_ll_adv_deinit(void) { } +int r_ble_ll_adv_env_init(void) { return 0; } +void r_ble_ll_adv_env_deinit(void) { } +int r_ble_lll_adv_rx_pkt_isr(void) { return -1; } +void r_ble_ll_adv_rx_pkt_in(void) { } +int r_ble_ll_adv_set_adv_params(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_read_txpwr(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_set_adv_data(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_set_scan_rsp_data(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_adv_set_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_vendor_hci_legacy_adv_clear(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_set_data_related_addr_change(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif // !DEFAULT_BT_LE_ROLE_BROADCASTER + +#if !DEFAULT_BT_LE_EXT_ADV +bool r_ble_ll_adv_ext_check_data_itvl(void) { return true; } +void r_ble_lll_adv_coex_dpc_update_on_aux_scheduled(void) { } +void r_ble_lll_adv_coex_dpc_calc_pti_update_itvl(void) { } +void r_ble_lll_adv_sec_done(void) { } +int r_ble_lll_adv_sec_schedule_next_aux(void) { return 0; } +void r_ble_lll_adv_sec_event_done(void) { } +int r_ble_lll_adv_secondary_tx_start_cb(void) { return 0; } +void r_ble_lll_adv_aux_schedule(void) { } +void r_ble_lll_adv_update_rsp_offset(void) { } +int r_ble_ll_adv_hci_set_random_addr(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_ext_set_param(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_ext_set_adv_data(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_ext_set_scan_rsp(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_ext_set_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_rd_max_adv_data_len(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_rd_sup_adv_sets(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_remove(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_clear_all(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_EXT_ADV + +#if !DEFAULT_BT_LE_PERIODIC_ADV +void r_ble_ll_adv_sm_stop_periodic(void) { } +void r_ble_lll_adv_periodic_event_done(void) { } +int r_ble_lll_adv_sync_tx_start_cb(void) { return 0; } +void r_ble_lll_adv_sync_tx_end(void) { } +int r_ble_lll_adv_periodic_start(void) { return 0; } +void r_ble_lll_adv_periodic_rmvd_from_sched(void) { } +int r_ble_ll_adv_periodic_set_param(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_periodic_set_data(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_adv_periodic_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_PERIODIC_ADV + +#if !DEFAULT_BT_LE_ROLE_OBSERVER +void r_ble_lll_scan_halt(void) { } +void r_ble_ll_scan_end_adv_evt(void) { } +void r_ble_ll_scan_rx_pkt_in(void) { } +int r_ble_lll_scan_rx_pkt_isr(void) { return -1; } +int r_ble_ll_scan_env_init(void) { return 0; } +void r_ble_ll_scan_env_deinit(void) { } +void r_ble_ll_scan_init(void) { } +void r_ble_ll_scan_deinit(void) { } +void r_ble_ll_scan_reset(void) { } +int r_ble_ll_scan_can_chg_whitelist(void) { return 1; } +int r_ble_ll_scan_enabled(void) { return false; } +int r_ble_lll_scan_chk_resume(void) { return -1; } +int r_ble_ll_scan_set_scan_params(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_scan_set_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_scan_hci_update_adv_report_flow_ctrl(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_scan_hci_set_adv_report_flow_ctrl(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_OBSERVER + +#if !DEFAULT_BT_LE_EXT_SCAN +void r_ble_lll_scan_duration_period_timers_restart(void) { } +void r_ble_lll_scan_duration_period_timers_stop(void) { } +int r_ble_ll_hci_send_legacy_ext_adv_report(void) { return -1; } +void r_ble_lll_sched_rmv_elem_type(void) { } +void r_ble_ll_scan_send_truncated(void) { } +void r_ble_ll_scan_aux_data_unref(void) { } +void r_ble_lll_scan_sched_remove(void) { } +void r_ble_lll_scan_aux_data_free(void) { } +void r_ble_lll_aux_scan_drop(void) { } +int r_ble_lll_sched_aux_scan(void) { return -1; } +int r_ble_lll_scan_rx_isr_on_aux(void) { return -1; } +void r_ble_lll_scan_period_timer_cb(void) { } +void r_ble_lll_scan_duration_timer_cb(void) { } +void r_ble_ll_scan_rx_pkt_in_on_aux(void) { } +int r_ble_ll_set_ext_scan_params(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_ext_scan_set_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_EXT_SCAN + +#if !DEFAULT_BT_LE_ROLE_CENTROL +void r_ble_ll_init_rx_pkt_in(void) { } +int r_ble_lll_init_rx_pkt_isr(void) { return -1; } +int r_ble_ll_conn_create(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_create_cancel(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_CENTROL + +#if !DEFAULT_BT_LE_ROLE_CENTROL || !DEFAULT_BT_LE_EXT_SCAN +int r_ble_ll_ext_conn_create(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_CENTROL || !DEFAULT_BT_LE_EXT_SCAN + +#if !DEFAULT_BT_LE_ROLE_PERIPHERAL +int r_ble_ll_conn_slave_start(void) { return 0; } +#endif //!DEFAULT_BT_LE_ROLE_PERIPHERAL + +#if !DEFAULT_BT_LE_ROLE_CENTROL && !DEFAULT_BT_LE_ROLE_PERIPHERAL +void r_ble_ll_conn_rx_data_pdu(void) { } +int r_ble_lll_conn_rx_pkt_isr(void) { return -1; } +int r_ble_ll_hci_disconnect(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_rd_rem_ver_cmd(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_update(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_rd_chan_map(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_read_rem_features(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_param_rr(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_param_nrr(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_CENTROL && !DEFAULT_BT_LE_ROLE_PERIPHERAL + +#if !CONFIG_BT_LE_FEAT_LL_ENCRYPTION +int r_ble_ll_conn_chk_phy_upd_start(void) { return -1; } +void r_ble_ll_hci_ev_encrypt_chg(void) { } +int r_ble_ll_ctrl_enc_allowed_pdu_rx(void) { return 1; } +int r_ble_ll_ctrl_enc_allowed_pdu_tx(void) { return 1; } +uint8_t r_ble_ll_ctrl_rx_start_enc_rsp(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_pause_enc_rsp(void) { return 0x07; } +int r_ble_ll_hci_le_encrypt(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!CONFIG_BT_LE_FEAT_LL_ENCRYPTION + +#if !DEFAULT_BT_LE_ROLE_PERIPHERAL || !CONFIG_BT_LE_FEAT_LL_ENCRYPTION +uint8_t r_ble_ll_ctrl_rx_pause_enc_req(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_enc_req(void) { return 0x07; } +int r_ble_ll_conn_hci_le_ltk_reply(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_le_ltk_neg_reply(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_PERIPHERAL || !CONFIG_BT_LE_FEAT_LL_ENCRYPTION + +#if !DEFAULT_BT_LE_ROLE_CENTROL || !CONFIG_BT_LE_FEAT_LL_ENCRYPTION +uint8_t r_ble_ll_ctrl_rx_start_enc_req(void) { return 0x07; } +void r_ble_ll_ctrl_rx_enc_rsp(void) { } +void r_ble_ll_ctrl_enc_req_make(void) { } +int r_ble_ll_conn_hci_le_start_encrypt(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_ROLE_CENTROL || !CONFIG_BT_LE_FEAT_LL_ENCRYPTION + +#if !DEGAULT_BT_LE_2M_PHY && !DEGAULT_BT_LE_CODED_PHY +void r_ble_ll_ctrl_phy_update_proc_complete(void) { } +void r_ble_ll_ctrl_phy_update_cancel(void) { } +uint8_t r_ble_ll_ctrl_rx_phy_update_ind(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_phy_rsp(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_phy_req(void) { return 0x07; } +void r_ble_ll_ctrl_phy_req_rsp_make(void) { } +#endif //DEGAULT_BT_LE_2M_PHY && DEGAULT_BT_LE_CODED_PHY + +#if !DEFAULT_BT_LE_PERIODIC_SYNC +void r_ble_lll_sync_halt(void) { } +void r_ble_lll_sync_rmvd_from_sched(void) { } +int r_ble_ll_sync_list_search(void) { return -1; } +uint8_t r_ble_ll_ctrl_rx_periodic_sync_ind(void) { return 0x07; } +void r_ble_ll_sync_rx_pkt_in(void) { } +int r_ble_lll_sync_rx_pkt_isr(void) { return -1; } +int r_ble_ll_sync_env_init(void) { return 0; } +void r_ble_ll_sync_env_deinit(void) { } +void r_ble_ll_sync_init(void) { } +void r_ble_ll_sync_deinit(void) { } +void r_ble_ll_sync_reset(void) { } +bool r_ble_ll_sync_enabled(void) { return false; } +int r_ble_ll_sync_create(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_cancel(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_terminate(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_list_add(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_list_remove(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_list_clear(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_list_size(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_sync_receive_enable(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_PERIODIC_SYNC + +#if !DEFAULT_BT_LE_PAST || !DEFAULT_BT_LE_PERIODIC_ADV +int r_ble_ll_adv_periodic_set_info_transfer(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_PAST || !DEFAULT_BT_LE_PERIODIC_ADV + +#if !DEFAULT_BT_LE_PAST || !DEFAULT_BT_LE_PERIODIC_SYNC +int r_ble_ll_sync_transfer(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_set_sync_transfer_params(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_set_default_sync_transfer_params(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_PAST || !DEFAULT_BT_LE_PERIODIC_SYNC + +#if !DEFAULT_BT_LE_50_FEATURE_SUPPORT +uint8_t r_ble_ll_ctrl_rx_channel_reporting_ind(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_channel_status_ind(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_sca_req(void) { return 0x07; } +uint8_t r_ble_ll_ctrl_rx_sca_rsp(void) { return 0x07; } +void r_ble_ll_ctrl_channel_class_reporting_make(void) { } +void r_ble_ll_ctrl_channel_class_enable_make(void) { } +void r_ble_ll_ctrl_sca_req_rsp_make(void) { } +int r_ble_ll_modify_sca(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_req_peer_sca(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_50_FEATURE_SUPPORT + +#if !DEFAULT_BT_LE_50_FEATURE_SUPPORT +int r_ble_ll_conn_hci_le_rd_phy(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_hci_le_set_def_phy(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_ll_conn_hci_le_set_phy(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!DEFAULT_BT_LE_50_FEATURE_SUPPORT + +#if !CONFIG_BT_LE_DTM_ENABLED +void r_ble_lll_dtm_rx_pkt_in(void) { } +int r_ble_lll_dtm_rx_isr_end(void) { return -1; } +void r_ble_lll_dtm_reset(void) { } +void r_ble_lll_dtm_init(void) { } +void r_ble_lll_dtm_deinit(void) { } +int r_ble_lll_dtm_env_init(void) { return 0; } +void r_ble_lll_dtm_env_deinit(void) { } +int r_ble_lll_hci_dtm_tx_test(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_lll_hci_dtm_rx_test(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_lll_dtm_end_test(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_lll_hci_dtm_rx_test_v2(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +int r_ble_lll_hci_dtm_tx_test_v2(void) { return BLE_ERR_UNKNOWN_HCI_CMD; } +#endif //!CONFIG_BT_LE_DTM_ENABLED diff --git a/lib/bt/controller/esp32c2/esp_bt_cfg.h b/lib/bt/controller/esp32c2/esp_bt_cfg.h index 0cb4168e..95a3c6b2 100644 --- a/lib/bt/controller/esp32c2/esp_bt_cfg.h +++ b/lib/bt/controller/esp32c2/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -28,7 +28,6 @@ extern "C" { #else #define BLE_LL_SCAN_PHY_NUMBER_N (1) #endif - #define DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST MYNEWT_VAL(BLE_MAX_PERIODIC_ADVERTISER_LIST) #define DEFAULT_BT_LE_MAX_PERIODIC_SYNCS MYNEWT_VAL(BLE_MAX_PERIODIC_SYNCS) #define DEFAULT_BT_LE_MAX_CONNECTIONS MYNEWT_VAL(BLE_MAX_CONNECTIONS) @@ -46,6 +45,14 @@ extern "C" { #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + #define DEGAULT_BT_LE_2M_PHY (CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_2M_PHY) + #define DEGAULT_BT_LE_CODED_PHY (CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_CODED_PHY) + #define DEFAULT_BT_LE_EXT_ADV (CONFIG_BT_NIMBLE_EXT_ADV) + #define DEFAULT_BT_LE_PERIODIC_ADV (CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV) + #define DEFAULT_BT_LE_EXT_SCAN (CONFIG_BT_NIMBLE_EXT_SCAN) + #define DEFAULT_BT_LE_PERIODIC_SYNC (CONFIG_BT_NIMBLE_ENABLE_PERIODIC_SYNC) + #define DEFAULT_BT_LE_PAST (CONFIG_BT_NIMBLE_PERIODIC_ADV_SYNC_TRANSFER) + #define DEFAULT_BT_LE_ROLE_OBSERVER MYNEWT_VAL(BLE_ROLE_OBSERVER) #define DEFAULT_BT_LE_ROLE_CENTROL MYNEWT_VAL(BLE_ROLE_CENTRAL) #define DEFAULT_BT_LE_ROLE_PERIPHERAL MYNEWT_VAL(BLE_ROLE_PERIPHERAL) @@ -123,12 +130,55 @@ extern "C" { #else #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT (8) #endif + #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + #if defined(CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY) + #define DEGAULT_BT_LE_2M_PHY (CONFIG_BT_LE_LL_CFG_FEAT_LE_2M_PHY) + #else + #define DEGAULT_BT_LE_2M_PHY (0) + #endif + + #if defined(CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY) + #define DEGAULT_BT_LE_CODED_PHY (CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY) + #else + #define DEGAULT_BT_LE_CODED_PHY (0) + #endif + + #if defined(CONFIG_BT_LE_EXT_ADV) + #define DEFAULT_BT_LE_EXT_ADV (CONFIG_BT_LE_EXT_ADV) + #else + #define DEFAULT_BT_LE_EXT_ADV (0) + #endif + + #if defined(CONFIG_BT_LE_ENABLE_PERIODIC_ADV) + #define DEFAULT_BT_LE_PERIODIC_ADV (CONFIG_BT_LE_ENABLE_PERIODIC_ADV) + #else + #define DEFAULT_BT_LE_PERIODIC_ADV (0) + #endif + + #if defined(CONFIG_BT_LE_EXT_SCAN) + #define DEFAULT_BT_LE_EXT_SCAN (CONFIG_BT_LE_EXT_SCAN) + #else + #define DEFAULT_BT_LE_EXT_SCAN (0) + #endif + + #if defined(CONFIG_BT_LE_ENABLE_PERIODIC_SYNC) + #define DEFAULT_BT_LE_PERIODIC_SYNC (CONFIG_BT_LE_ENABLE_PERIODIC_SYNC) + #else + #define DEFAULT_BT_LE_PERIODIC_SYNC (0) + #endif + + #if defined(BT_LE_PERIODIC_ADV_SYNC_TRANSFER) + #define DEFAULT_BT_LE_PAST (BT_LE_PERIODIC_ADV_SYNC_TRANSFER) + #else + #define DEFAULT_BT_LE_PAST (0) + #endif + #if defined(CONFIG_BT_LE_ROLE_CENTROL_ENABLE) #define DEFAULT_BT_LE_ROLE_CENTROL (1) #else @@ -152,16 +202,68 @@ extern "C" { #else #define DEFAULT_BT_LE_ROLE_OBSERVER (0) #endif + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF +#ifdef CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS) +#else +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CONN_UPDATE +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (1<<0) +#else +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (0<<0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (1<<1) +#else +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (0<<1) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_PHY_UPDATE +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (1<<2) +#else +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (0<<2) +#endif + +#define BT_LE_CTRL_LLCP_DISC_FLAG (BT_CTRL_BLE_LLCP_CONN_UPDATE | BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE | BT_CTRL_BLE_LLCP_PHY_UPDATE) + +#ifdef CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX) +#else +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (256) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else #define HCI_UART_EN 0 // hci ram mode #endif +#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#define DEFAULT_BT_LE_VHCI_ENABLED (CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) +#else +#define DEFAULT_BT_LE_VHCI_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else @@ -192,8 +294,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -202,8 +302,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -232,7 +330,7 @@ extern "C" { #define RTC_FREQ_N (32000) /* in Hz */ #endif // CONFIG_XTAL_FREQ_26 -#define BLE_LL_TX_PWR_DBM_N (9) +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) diff --git a/lib/bt/controller/esp32c3/Kconfig.in b/lib/bt/controller/esp32c3/Kconfig.in index 059e71da..bc75b9bb 100644 --- a/lib/bt/controller/esp32c3/Kconfig.in +++ b/lib/bt/controller/esp32c3/Kconfig.in @@ -66,7 +66,7 @@ endchoice config BT_CTRL_HCI_TL int default 0 if BT_CTRL_HCI_MODE_UART_H4 - default 1 if BT_CTRL_HCI_M0DE_VHCI + default 1 if BT_CTRL_HCI_MODE_VHCI default 1 help HCI mode as VHCI or UART(H4) @@ -76,20 +76,23 @@ config BT_CTRL_ADV_DUP_FILT_MAX range 1 500 default 30 help - The maximum number of suplicate scan filter + The maximum number of 5.0 extend duplicate choice BT_BLE_CCA_MODE prompt "BLE CCA mode" default BT_BLE_CCA_MODE_NONE help Define BT BLE CCA mode + Note that if CCA feature is enabled, the hardware may not transmit packets due to channel busy. + Therefore, it may potentially lead to an increase in the time taken for scanning advertising packet + and establishing connections, or a decrease in the throughput rate of the connection. config BT_BLE_CCA_MODE_NONE bool "NONE" config BT_BLE_CCA_MODE_HW bool "Hardware" config BT_BLE_CCA_MODE_SW - bool "Software" + bool "Software (experimental)" endchoice config BT_BLE_CCA_MODE @@ -101,9 +104,11 @@ config BT_BLE_CCA_MODE config BT_CTRL_HW_CCA_VAL int "CCA threshold value" range 20 100 - default 20 + default 75 help It is the threshold value of HW CCA, if the value is 30, it means CCA threshold is -30 dBm. + If the channel assessment result exceeds the CCA threshold (e.g. -75 dBm), indicating the channel is busy, + the hardware will not transmit packets on that channel. config BT_CTRL_HW_CCA_EFF int @@ -200,8 +205,8 @@ choice BT_CTRL_DFT_TX_POWER_LEVEL bool "+15dBm" config BT_CTRL_DFT_TX_POWER_LEVEL_P18 bool "+18dBm" - config BT_CTRL_DFT_TX_POWER_LEVEL_P21 - bool "+21dBm" + config BT_CTRL_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" endchoice config BT_CTRL_DFT_TX_POWER_LEVEL_EFF @@ -221,11 +226,12 @@ config BT_CTRL_DFT_TX_POWER_LEVEL_EFF default 12 if BT_CTRL_DFT_TX_POWER_LEVEL_P12 default 13 if BT_CTRL_DFT_TX_POWER_LEVEL_P15 default 14 if BT_CTRL_DFT_TX_POWER_LEVEL_P18 - default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P21 + default 15 if BT_CTRL_DFT_TX_POWER_LEVEL_P20 default 0 config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP bool "BLE adv report flow control supported" + depends on BT_CTRL_BLE_SCAN default y help The function is mainly used to enable flow control for advertising reports. When it is enabled, @@ -402,10 +408,10 @@ menu "MODEM SLEEP Options" bluetooth can work under light sleep enabled. Main crystal has a relatively better performance than other bluetooth low power clock sources. config BT_CTRL_LPCLK_SEL_EXT_32K_XTAL - bool "External 32kHz crystal" - depends on RTC_CLK_SRC_EXT_CRYS + bool "External 32kHz crystal/oscillator" + depends on RTC_CLK_SRC_EXT_CRYS || RTC_CLK_SRC_EXT_OSC help - External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency + External 32kHz crystal/oscillator has a nominal frequency of 32.768kHz and provides good frequency stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth modem sleep to be used with both DFS and light sleep. @@ -444,7 +450,7 @@ config BT_CTRL_SLEEP_CLOCK_EFF config BT_CTRL_HCI_TL_EFF int default 0 if BT_CTRL_HCI_MODE_UART_H4 - default 1 if BT_CTRL_HCI_M0DE_VHCI + default 1 if BT_CTRL_HCI_MODE_VHCI default 1 config BT_CTRL_AGC_RECORRECT_EN @@ -465,7 +471,7 @@ config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX default n help Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to - minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active + minimize collision of scan request PDUs from multiple scanners. If scan backoff is disabled, in active scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU. config BT_BLE_ADV_DATA_LENGTH_ZERO_AUX @@ -489,3 +495,138 @@ config BT_CTRL_LE_PING_EN help If this option is disabled, The Controller will not start the LE authenticated payload timer. This option is used for some compatibility problems related to LE ping procedure. + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_CTRL_BLE_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_CTRL_BLE_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu +config BT_CTRL_RUN_IN_FLASH_ONLY + bool "Put all BLE Controller code in flash" + default n + help + If this option is enabled, all code for the Bluetooth controller will be moved from ROM and IRAM + to flash, saving over 20K bytes of memory. However, it will require more flash resources and the + performance of Bluetooth will decrease If this option is enabled, Bluetooth may not work properly + during erasing flash. It is recommended to turn on the auto suspend function of flash. After auto + suspend is turned on, Bluetooth interrupts can be executed normally during erasing flash, with less + impact on Bluetooth performance. + +config BT_CTRL_DTM_ENABLE + bool "Enable direct test mode feature" + default y + +config BT_CTRL_BLE_MASTER + bool "Enable BLE connection feature" + default y + help + If this option is disabled, it is not recommended to use connectable ADV. + +config BT_CTRL_BLE_TEST + bool "Enable BLE QA test feature (Not Used)" + default n + +config BT_CTRL_BLE_SCAN + bool "Enable BLE scan feature" + default y + +config BT_CTRL_BLE_SECURITY_ENABLE + bool "Enable BLE security feature" + default y + +config BT_CTRL_BLE_ADV + bool "Enable BLE ADV feature" + default y + +config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + +menu "Controller debug log Options (Experimental)" + config BT_CTRL_LE_LOG_EN + depends on BT_CTRL_RUN_IN_FLASH_ONLY + bool "Enable BLE debug log" + default n + + config BT_CTRL_LE_HCI_LOG_EN + depends on BT_CTRL_LE_LOG_EN + bool "Enable BLE HCI log" + default n + + config BT_CTRL_LE_LOG_DUMP_ONLY + depends on BT_CTRL_LE_LOG_EN + bool "Enable BLE log dump only" + default n + + config BT_CTRL_LE_LOG_STORAGE_EN + depends on BT_CTRL_LE_LOG_EN + bool "Enable BLE log storage to flash" + default n + + config BT_CTRL_LE_LOG_PARTITION_SIZE + int "The size of ble controller log partition(Multiples of 4K)" + depends on BT_CTRL_LE_LOG_STORAGE_EN + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + + config BT_CTRL_LE_LOG_SPI_OUT_EN + bool "Output ble controller logs to SPI bus" + depends on BT_CTRL_LE_LOG_EN + depends on !BT_CTRL_LE_LOG_DUMP_ONLY + select BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Output ble controller logs to SPI bus + + config BT_CTRL_LE_LOG_MODE_EN + depends on BT_CTRL_LE_LOG_EN + int "Enable log for specified BLE mode" + range 0 4095 + default 4093 + + config BT_CTRL_LE_LOG_LEVEL + depends on BT_CTRL_LE_LOG_EN + int "The level of BLE log" + range 0 5 + default 2 + + config BT_CTRL_LE_LOG_BUF1_SIZE + depends on BT_CTRL_LE_LOG_EN + int "The size of BLE log buffer1" + default 1024 + + config BT_CTRL_LE_LOG_HCI_BUF_SIZE + depends on BT_CTRL_LE_LOG_EN + int "The size of BLE log HCI buffer" + default 1024 + + config BT_CTRL_LE_LOG_BUF2_SIZE + depends on BT_CTRL_LE_LOG_EN + int "The size of BLE log buffer2" + default 1024 +endmenu diff --git a/lib/bt/controller/esp32c3/bt.c b/lib/bt/controller/esp32c3/bt.c index e053cfdf..5a1ec437 100644 --- a/lib/bt/controller/esp32c3/bt.c +++ b/lib/bt/controller/esp32c3/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -49,6 +49,13 @@ #else //CONFIG_IDF_TARGET_ESP32S3 #include "esp32s3/rom/rom_layout.h" #endif +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +#include "esp_partition.h" +#include "hal/wdt_hal.h" +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN #if CONFIG_BT_ENABLED /* Macro definition @@ -115,9 +122,20 @@ do{\ } while(0) #define OSI_FUNCS_TIME_BLOCKING 0xffffffff -#define OSI_VERSION 0x00010008 +#define OSI_VERSION 0x0001000A #define OSI_MAGIC_VALUE 0xFADEBEAD +#define BLE_PWR_HDL_INVL 0xFFFF + +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA) + +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +#define MAX_STORAGE_SIZE (CONFIG_BT_CTRL_LE_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" +#endif + /* Types definition ************************************************************************ */ @@ -142,15 +160,24 @@ typedef struct { typedef void (* osi_intr_handler)(void); +typedef struct { + int source; /*!< ISR source */ + int flags; /*!< ISR alloc flag */ + void (*fn)(void *); /*!< ISR function */ + void *arg; /*!< ISR function args*/ + intr_handle_t *handle; /*!< ISR handle */ + esp_err_t ret; +} btdm_isr_alloc_t; + /* OSI function */ struct osi_funcs_t { uint32_t _magic; uint32_t _version; - void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio); - void (*_interrupt_clear)(int interrupt_source, int interrupt_no); - void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg); - void (*_interrupt_disable)(void); - void (*_interrupt_restore)(void); + int (* _interrupt_alloc)(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); + int (* _interrupt_free)(void *handle); + void (*_interrupt_handler_set_rsv)(int interrupt_no, intr_handler_t fn, void *arg); + void (*_global_intr_disable)(void); + void (*_global_intr_restore)(void); void (*_task_yield)(void); void (*_task_yield_from_isr)(void); void *(*_semphr_create)(uint32_t max, uint32_t init); @@ -195,8 +222,8 @@ struct osi_funcs_t { uint32_t (* _coex_schm_interval_get)(void); uint8_t (* _coex_schm_curr_period_get)(void); void *(* _coex_schm_curr_phase_get)(void); - void (* _interrupt_on)(int intr_num); - void (* _interrupt_off)(int intr_num); + int (* _interrupt_enable)(void *handle); + int (* _interrupt_disable)(void *handle); void (* _esp_hw_power_down)(void); void (* _esp_hw_power_up)(void); void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem); @@ -204,8 +231,13 @@ struct osi_funcs_t { void (* _btdm_rom_table_ready)(void); bool (* _coex_bt_wakeup_request)(void); void (* _coex_bt_wakeup_request_end)(void); + int64_t (*_get_time_us)(void); + void (* _assert)(void); }; +#if CONFIG_BT_CTRL_LE_LOG_EN +typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +#endif // CONFIG_BT_CTRL_LE_LOG_EN /* External functions or values ************************************************************************ @@ -245,10 +277,9 @@ extern bool API_vhci_host_check_send_available(void); extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len); extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback); /* TX power */ -extern int ble_txpwr_set(int power_type, int power_level); -extern int ble_txpwr_get(int power_type); +extern int ble_txpwr_set(int power_type, uint16_t handle, int power_level); +extern int ble_txpwr_get(int power_type, uint16_t handle); -extern uint16_t l2c_ble_link_get_tx_buf_num(void); extern void coex_pti_v2(void); extern bool btdm_deep_sleep_mem_init(void); @@ -264,6 +295,33 @@ extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, b #endif extern void btdm_cca_feature_enable(void); +extern void btdm_aa_check_enhance_enable(void); + +/* BLE Log module */ +#if CONFIG_BT_CTRL_LE_LOG_EN +extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_deinit_async(void); +extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); +extern void r_ble_log_async_output_dump_all(bool output); +extern void esp_panic_handler_feed_wdts(void); +#endif // CONFIG_BT_CTRL_LE_LOG_EN +#if (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) +extern void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +extern void adv_stack_enableClearLegacyAdvVsCmd(bool en); +extern void advFilter_stack_enableDupExcListVsCmd(bool en); +extern void chanSel_stack_enableSetCsaVsCmd(bool en); +#endif // (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) + +extern void ble_dtm_funcs_reset(void); +extern void ble_scan_funcs_reset(void); +extern void ble_42_adv_funcs_reset(void); +extern void ble_init_funcs_reset(void); +extern void ble_con_funcs_reset(void); +extern void ble_cca_funcs_reset(void); +extern void ble_ext_adv_funcs_reset(void); +extern void ble_ext_scan_funcs_reset(void); +extern void ble_base_funcs_reset(void); +extern void ble_enc_funcs_reset(void); extern uint32_t _bt_bss_start; extern uint32_t _bt_bss_end; @@ -277,11 +335,10 @@ extern uint32_t _bt_controller_data_end; /* Local Function Declare ********************************************************************* */ -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio); -static void interrupt_clear_wrapper(int intr_source, int intr_num); -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg); -static void interrupt_disable(void); -static void interrupt_restore(void); +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle); +static int interrupt_free_wrapper(void *handle); +static void global_interrupt_disable(void); +static void global_interrupt_restore(void); static void task_yield_from_isr(void); static void *semphr_create_wrapper(uint32_t max, uint32_t init); static void semphr_delete_wrapper(void *semphr); @@ -319,14 +376,16 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static uint32_t coex_schm_interval_get_wrapper(void); static uint8_t coex_schm_curr_period_get_wrapper(void); static void * coex_schm_curr_phase_get_wrapper(void); -static void interrupt_on_wrapper(int intr_num); -static void interrupt_off_wrapper(int intr_num); +static int interrupt_enable_wrapper(void *handle); +static int interrupt_disable_wrapper(void *handle); static void btdm_hw_mac_power_up_wrapper(void); static void btdm_hw_mac_power_down_wrapper(void); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); static void btdm_funcs_table_ready_wrapper(void); static bool coex_bt_wakeup_request(void); static void coex_bt_wakeup_request_end(void); +static int64_t get_time_us_wrapper(void); +static void assert_wrapper(void); static void btdm_slp_tmr_callback(void *arg); @@ -334,6 +393,15 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end); static void bt_controller_deinit_internal(void); +#if CONFIG_BT_CTRL_LE_LOG_EN +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +void esp_bt_read_ctrl_log_from_flash(bool output); +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end); +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // #if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +#endif // CONFIG_BT_CTRL_LE_LOG_EN + /* Local variable definition *************************************************************************** */ @@ -341,11 +409,11 @@ static void bt_controller_deinit_internal(void); static const struct osi_funcs_t osi_funcs_ro = { ._magic = OSI_MAGIC_VALUE, ._version = OSI_VERSION, - ._interrupt_set = interrupt_set_wrapper, - ._interrupt_clear = interrupt_clear_wrapper, - ._interrupt_handler_set = interrupt_handler_set_wrapper, - ._interrupt_disable = interrupt_disable, - ._interrupt_restore = interrupt_restore, + ._interrupt_alloc = interrupt_alloc_wrapper, + ._interrupt_free = interrupt_free_wrapper, + ._interrupt_handler_set_rsv = NULL, + ._global_intr_disable = global_interrupt_disable, + ._global_intr_restore = global_interrupt_restore, ._task_yield = vPortYield, ._task_yield_from_isr = task_yield_from_isr, ._semphr_create = semphr_create_wrapper, @@ -390,8 +458,8 @@ static const struct osi_funcs_t osi_funcs_ro = { ._coex_schm_interval_get = coex_schm_interval_get_wrapper, ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, - ._interrupt_on = interrupt_on_wrapper, - ._interrupt_off = interrupt_off_wrapper, + ._interrupt_enable = interrupt_enable_wrapper, + ._interrupt_disable = interrupt_disable_wrapper, ._esp_hw_power_down = btdm_hw_mac_power_down_wrapper, ._esp_hw_power_up = btdm_hw_mac_power_up_wrapper, ._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper, @@ -399,6 +467,8 @@ static const struct osi_funcs_t osi_funcs_ro = { ._btdm_rom_table_ready = btdm_funcs_table_ready_wrapper, ._coex_bt_wakeup_request = coex_bt_wakeup_request, ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end, + ._get_time_us = get_time_us_wrapper, + ._assert = assert_wrapper, }; static DRAM_ATTR struct osi_funcs_t *osi_funcs_p; @@ -427,6 +497,255 @@ static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock; static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock; #endif +#if CONFIG_BT_CTRL_LE_LOG_EN +enum log_out_mode { + LOG_DUMP_MEMORY, + LOG_ASYNC_OUT, + LOG_STORAGE_TO_FLASH, + LOG_SPI_OUT, +}; + +const static uint32_t log_bufs_size[] = {CONFIG_BT_CTRL_LE_LOG_BUF1_SIZE, CONFIG_BT_CTRL_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_CTRL_LE_LOG_BUF2_SIZE}; +bool log_is_inited = false; +#if CONFIG_BT_CTRL_LE_LOG_DUMP_ONLY +uint8_t log_output_mode = LOG_DUMP_MEMORY; +#else +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +uint8_t log_output_mode = LOG_STORAGE_TO_FLASH; +#elif CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN +uint8_t log_output_mode = LOG_SPI_OUT; +#else +uint8_t log_output_mode = LOG_ASYNC_OUT; +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +#endif // CONFIG_BT_CTRL_LE_LOG_DUMP_ONLY +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + esp_bt_controller_log_storage(len, addr, end); +#endif //CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + for (int i = 0; i < len; i++) { + esp_rom_printf("%02x ", addr[i]); + } + + if (end) { + esp_rom_printf("\n"); + } + portEXIT_CRITICAL_SAFE(&spinlock); + } +} + +#if CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN +static IRAM_ATTR void esp_bt_controller_spi_log_interface(uint32_t len, const uint8_t *addr, bool end) +{ + ble_log_spi_out_write(BLE_LOG_SPI_OUT_SOURCE_ESP_LEGACY, addr, len); +} +#endif // CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN + +void esp_ble_controller_log_dump_all(bool output) +{ + if (log_output_mode == LOG_STORAGE_TO_FLASH) { +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + esp_bt_read_ctrl_log_from_flash(output); +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + } else { + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + esp_rom_printf("\r\n[DUMP_START:"); + r_ble_log_async_output_dump_all(output); + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + } +} + +void esp_bt_log_output_mode_set(uint8_t output_mode) +{ + log_output_mode = output_mode; +} + +uint8_t esp_bt_log_output_mode_get(void) +{ + return log_output_mode; +} + +esp_err_t esp_bt_controller_log_init(uint8_t log_output_mode) +{ + esp_err_t ret = ESP_OK; + interface_func_t bt_controller_log_interface; + bt_controller_log_interface = esp_bt_controller_log_interface; + bool task_create; + uint8_t buffers = 0; + + if (log_is_inited) { + return ret; + } + +#if CONFIG_BT_CTRL_LE_LOG_EN + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_CTRL_LE_LOG_EN +#if CONFIG_BT_CTRL_LE_HCI_LOG_EN + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_CTRL_LE_HCI_LOG_EN + + switch (log_output_mode) { + case LOG_DUMP_MEMORY: + task_create = false; + break; + case LOG_ASYNC_OUT: + case LOG_STORAGE_TO_FLASH: + task_create = true; +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + if (log_output_mode == LOG_STORAGE_TO_FLASH) { + esp_bt_ctrl_log_partition_get_and_erase_first_block(); + } +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN + break; + case LOG_SPI_OUT: + task_create = true; +#if CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN + bt_controller_log_interface = esp_bt_controller_spi_log_interface; +#endif // CONFIG_BT_CTRL_LE_LOG_SPI_OUT_EN + break; + default: + assert(0); + } + + ret = r_ble_log_init_async(bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size); + if (ret == ESP_OK) { + log_is_inited = true; + } + + return ret; +} + +void esp_bt_ontroller_log_deinit(void) +{ + r_ble_log_deinit_async(); + log_is_inited = false; +} + +#if CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + r_ble_log_async_output_dump_all(true); + esp_bt_ontroller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_feed_wdts(); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_CTRL_LE_LOG_STORAGE_EN +#endif // CONFIG_BT_CTRL_LE_LOG_EN + void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void) { #if CONFIG_MAC_BB_PD @@ -478,35 +797,48 @@ static inline void esp_bt_power_domain_off(void) esp_wifi_bt_power_domain_off(); } -static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio) +static void btdm_intr_alloc(void *arg) { - esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); -#if __riscv - esprv_int_set_priority(intr_num, intr_prio); - esprv_int_set_type(intr_num, 0); -#endif + btdm_isr_alloc_t *p = arg; + p->ret = esp_intr_alloc(p->source, p->flags, p->fn, p->arg, p->handle); } -static void interrupt_clear_wrapper(int intr_source, int intr_num) +static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle) { + btdm_isr_alloc_t p; + p.source = source; +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + p.flags = ESP_INTR_FLAG_LEVEL3; +#else + p.flags = ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM; +#endif + p.fn = handler; + p.arg = arg; + p.handle = (intr_handle_t *)ret_handle; +#if CONFIG_FREERTOS_UNICORE + btdm_intr_alloc(&p); +#else + esp_ipc_call_blocking(cpu_id, btdm_intr_alloc, &p); +#endif + return p.ret; } -static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg) +static int interrupt_free_wrapper(void *handle) { - esp_cpu_intr_set_handler(n, fn, arg); + return esp_intr_free((intr_handle_t)handle); } -static void interrupt_on_wrapper(int intr_num) +static int interrupt_enable_wrapper(void *handle) { - esp_cpu_intr_enable(1 << intr_num); + return esp_intr_enable((intr_handle_t)handle); } -static void interrupt_off_wrapper(int intr_num) +static int interrupt_disable_wrapper(void *handle) { - esp_cpu_intr_disable(1<<intr_num); + return esp_intr_disable((intr_handle_t)handle); } -static void IRAM_ATTR interrupt_disable(void) +static void IRAM_ATTR global_interrupt_disable(void) { if (xPortInIsrContext()) { portENTER_CRITICAL_ISR(&global_int_mux); @@ -515,7 +847,7 @@ static void IRAM_ATTR interrupt_disable(void) } } -static void IRAM_ATTR interrupt_restore(void) +static void IRAM_ATTR global_interrupt_restore(void) { if (xPortInIsrContext()) { portEXIT_CRITICAL_ISR(&global_int_mux); @@ -670,13 +1002,27 @@ static bool IRAM_ATTR is_in_isr_wrapper(void) static void *malloc_internal_wrapper(size_t size) { - void *p = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA); + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); + if(p == NULL) { + ESP_LOGE(BT_LOG_TAG, "Malloc failed"); + } + return p; +} + +void *malloc_ble_controller_mem(size_t size) +{ + void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); if(p == NULL) { ESP_LOGE(BT_LOG_TAG, "Malloc failed"); } return p; } +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} + static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]) { int ret = esp_read_mac(mac, ESP_MAC_BT); @@ -747,7 +1093,8 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles) // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift // and set the timer in advance uint32_t uncertainty = (us_to_sleep >> 11); -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP + // recalculate clock drift when Bluetooth using main XTAL during light sleep if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) { uncertainty = us_to_sleep * BTDM_RTC_SLOW_CLK_RC_DRIFT_PERCENT / 100; } @@ -926,6 +1273,49 @@ static void btdm_funcs_table_ready_wrapper(void) #if BT_BLE_CCA_MODE == 2 btdm_cca_feature_enable(); #endif +#if BLE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS_ENABLED + btdm_aa_check_enhance_enable(); +#endif +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + // do nothing +#else + ESP_LOGI(BT_LOG_TAG, "Feature Config, ADV:%d, BLE_50:%d, DTM:%d, SCAN:%d, CCA:%d, SMP:%d, CONNECT:%d", + BT_CTRL_BLE_ADV, BT_CTRL_50_FEATURE_SUPPORT, BT_CTRL_DTM_ENABLE, BT_CTRL_BLE_SCAN, + BT_BLE_CCA_MODE, BLE_SECURITY_ENABLE, BT_CTRL_BLE_MASTER); + + ble_base_funcs_reset(); +#if CONFIG_BT_CTRL_BLE_ADV + ble_42_adv_funcs_reset(); +#if (BT_CTRL_50_FEATURE_SUPPORT == 1) + ble_ext_adv_funcs_reset(); +#endif // +#endif // CONFIG_BT_CTRL_BLE_ADV + +#if CONFIG_BT_CTRL_DTM_ENABLE + ble_dtm_funcs_reset(); +#endif // CONFIG_BT_CTRL_DTM_ENABLE + +#if CONFIG_BT_CTRL_BLE_SCAN + ble_scan_funcs_reset(); +#if (BT_CTRL_50_FEATURE_SUPPORT == 1) + ble_ext_scan_funcs_reset(); +#endif // (BT_CTRL_50_FEATURE_SUPPORT == 1) +#endif // CONFIG_BT_CTRL_BLE_SCAN + +#if (BT_BLE_CCA_MODE != 0) + ble_cca_funcs_reset(); +#endif // (BT_BLE_CCA_MODE != 0) + +#if CONFIG_BT_CTRL_BLE_SECURITY_ENABLE + ble_enc_funcs_reset(); +#endif // CONFIG_BT_CTRL_BLE_SECURITY_ENABLE + +#if CONFIG_BT_CTRL_BLE_MASTER + ble_init_funcs_reset(); + ble_con_funcs_reset(); +#endif // CONFIG_BT_CTRL_BLE_MASTER + +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY } bool bt_async_wakeup_request(void) @@ -949,6 +1339,18 @@ static void coex_bt_wakeup_request_end(void) return; } +static IRAM_ATTR int64_t get_time_us_wrapper(void) +{ + return esp_timer_get_time(); +} + +static IRAM_ATTR void assert_wrapper(void) +{ +#if CONFIG_BT_CTRL_LE_LOG_EN + esp_ble_controller_log_dump_all(true); +#endif // CONFIG_BT_CTRL_LE_LOG_EN +} + bool esp_vhci_host_check_send_available(void) { if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { @@ -1391,6 +1793,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version()); +#if (CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY) + ESP_LOGI(BT_LOG_TAG,"Put all controller code in flash"); +#endif + if ((err = btdm_low_power_mode_init(cfg)) != ESP_OK) { ESP_LOGE(BT_LOG_TAG, "Low power module initialization failed"); goto error; @@ -1400,20 +1806,49 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) coex_init(); #endif +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + ESP_LOGE(BT_LOG_TAG, "BLE Log SPI output init failed"); + goto error; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + periph_module_enable(PERIPH_BT_MODULE); periph_module_reset(PERIPH_BT_MODULE); - if (btdm_controller_init(cfg) != 0) { +#if CONFIG_BT_CTRL_LE_LOG_EN + err = esp_bt_controller_log_init(log_output_mode); + if (err != ESP_OK) { + ESP_LOGW(BT_LOG_TAG, "ble_controller_log_init failed %d", err); + goto error; + } +#endif // CONFIG_BT_CTRL_LE_LOG_EN + + err = btdm_controller_init(cfg); + + if (err != 0) { + ESP_LOGE(BT_LOG_TAG, "%s %d\n",__func__,err); err = ESP_ERR_NO_MEM; goto error; } +#if (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) + scan_stack_enableAdvFlowCtrlVsCmd(true); + adv_stack_enableClearLegacyAdvVsCmd(true); + advFilter_stack_enableDupExcListVsCmd(true); + chanSel_stack_enableSetCsaVsCmd(true); +#endif // (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) + btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; return ESP_OK; error: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + bt_controller_deinit_internal(); return err; @@ -1425,6 +1860,17 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_ERR_INVALID_STATE; } +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) + scan_stack_enableAdvFlowCtrlVsCmd(false); + adv_stack_enableClearLegacyAdvVsCmd(false); + advFilter_stack_enableDupExcListVsCmd(false); + chanSel_stack_enableSetCsaVsCmd(false); +#endif // (CONFIG_BT_BLUEDROID_ENABLED || CONFIG_BT_NIMBLE_ENABLED) + btdm_controller_deinit(); bt_controller_deinit_internal(); @@ -1503,6 +1949,10 @@ static void bt_controller_deinit_internal(void) #endif esp_phy_modem_deinit(); +#if CONFIG_BT_CTRL_LE_LOG_EN + esp_bt_ontroller_log_deinit(); +#endif // CONFIG_BT_CTRL_LE_LOG_EN + if (osi_funcs_p != NULL) { free(osi_funcs_p); osi_funcs_p = NULL; @@ -1657,16 +2107,89 @@ esp_bt_controller_status_t esp_bt_controller_get_status(void) return btdm_controller_status; } +static int enh_power_type_get(esp_ble_power_type_t power_type) +{ + switch (power_type) { + case ESP_BLE_PWR_TYPE_ADV: + return ESP_BLE_ENHANCED_PWR_TYPE_ADV; + case ESP_BLE_PWR_TYPE_SCAN: + return ESP_BLE_ENHANCED_PWR_TYPE_SCAN; + case ESP_BLE_PWR_TYPE_CONN_HDL0: + case ESP_BLE_PWR_TYPE_CONN_HDL1: + case ESP_BLE_PWR_TYPE_CONN_HDL2: + case ESP_BLE_PWR_TYPE_CONN_HDL3: + case ESP_BLE_PWR_TYPE_CONN_HDL4: + case ESP_BLE_PWR_TYPE_CONN_HDL5: + case ESP_BLE_PWR_TYPE_CONN_HDL6: + case ESP_BLE_PWR_TYPE_CONN_HDL7: + case ESP_BLE_PWR_TYPE_CONN_HDL8: + return ESP_BLE_ENHANCED_PWR_TYPE_CONN; + case ESP_BLE_PWR_TYPE_DEFAULT: + return ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT; + default: + break; + } + + return power_type; +} + /* extra functions */ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level) { esp_err_t stat = ESP_FAIL; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_ERR_NOT_SUPPORTED; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + if (ble_txpwr_set(enh_pwr_type, handle, power_level) == 0) { + stat = ESP_OK; + } + + return stat; +} + +esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) +{ + esp_power_level_t lvl; + uint16_t handle = BLE_PWR_HDL_INVL; + int enh_pwr_type = enh_power_type_get(power_type); + + if (power_type > ESP_BLE_PWR_TYPE_DEFAULT) { + return ESP_PWR_LVL_INVALID; + } + + if (enh_pwr_type == ESP_BLE_ENHANCED_PWR_TYPE_CONN) { + handle = power_type; + } + + lvl = (esp_power_level_t)ble_txpwr_get(enh_pwr_type, handle); + + return lvl; +} + +esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle, + esp_power_level_t power_level) +{ + esp_err_t stat = ESP_FAIL; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - case ESP_BLE_PWR_TYPE_DEFAULT: - if (ble_txpwr_set(power_type, power_level) == 0) { + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + if (ble_txpwr_set(power_type, BLE_PWR_HDL_INVL, power_level) == 0) { + stat = ESP_OK; + } + break; + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + if (ble_txpwr_set(power_type, handle, power_level) == 0) { stat = ESP_OK; } break; @@ -1678,33 +2201,26 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ return stat; } -esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) +esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, + uint16_t handle) { - esp_power_level_t lvl; + int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: - lvl = (esp_power_level_t)ble_txpwr_get(power_type); + case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: + case ESP_BLE_ENHANCED_PWR_TYPE_INIT: + tx_level = ble_txpwr_get(power_type, BLE_PWR_HDL_INVL); break; - case ESP_BLE_PWR_TYPE_CONN_HDL0: - case ESP_BLE_PWR_TYPE_CONN_HDL1: - case ESP_BLE_PWR_TYPE_CONN_HDL2: - case ESP_BLE_PWR_TYPE_CONN_HDL3: - case ESP_BLE_PWR_TYPE_CONN_HDL4: - case ESP_BLE_PWR_TYPE_CONN_HDL5: - case ESP_BLE_PWR_TYPE_CONN_HDL6: - case ESP_BLE_PWR_TYPE_CONN_HDL7: - case ESP_BLE_PWR_TYPE_CONN_HDL8: - case ESP_BLE_PWR_TYPE_DEFAULT: - lvl = (esp_power_level_t)ble_txpwr_get(ESP_BLE_PWR_TYPE_DEFAULT); + case ESP_BLE_ENHANCED_PWR_TYPE_ADV: + case ESP_BLE_ENHANCED_PWR_TYPE_CONN: + tx_level = ble_txpwr_get(power_type, handle); break; default: - lvl = ESP_PWR_LVL_INVALID; - break; + return ESP_PWR_LVL_INVALID; } - return lvl; + return (esp_power_level_t)tx_level; } esp_err_t esp_bt_sleep_enable (void) @@ -1765,11 +2281,6 @@ int IRAM_ATTR esp_bt_h4tl_eif_io_event_notify(int event) return btdm_hci_tl_io_event_post(event); } -uint16_t esp_bt_get_tx_buf_num(void) -{ - return l2c_ble_link_get_tx_buf_num(); -} - static void coex_wifi_sleep_set_hook(bool sleep) { diff --git a/lib/bt/controller/esp32c5/Kconfig.in b/lib/bt/controller/esp32c5/Kconfig.in index 02ac4995..2e6db9fd 100644 --- a/lib/bt/controller/esp32c5/Kconfig.in +++ b/lib/bt/controller/esp32c5/Kconfig.in @@ -2,15 +2,15 @@ menu "HCI Config" choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice @@ -73,12 +73,26 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 256 help - Set the size of uart task stack + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 2048 + help + This configures stack size of hci transport task endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -269,54 +283,131 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -menuconfig BT_LE_CONTROLLER_LOG_ENABLED - bool "Controller log enable" - default n - help - Enable controller log +menu "Controller debug features" + menuconfig BT_LE_CONTROLLER_LOG_ENABLED + bool "Controller log enable" + default n + help + Enable controller log -config BT_LE_CONTROLLER_LOG_CTRL_ENABLED - bool "enable controller log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable controller log module -config BT_LE_CONTROLLER_LOG_HCI_ENABLED - bool "enable HCI log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable hci log module -config BT_LE_CONTROLLER_LOG_DUMP_ONLY - bool "Controller log dump mode only" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_DUMP_ONLY + bool "Controller log dump mode only" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Only operate in dump mode -config BT_LE_LOG_CTRL_BUF1_SIZE - int "size of the first BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + bool "Output ble controller logs to SPI bus (Experimental)" + depends on BT_LE_CONTROLLER_LOG_ENABLED + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + select BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Output ble controller logs to SPI bus + + config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + + config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + + config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the first BLE controller LOG buffer. -config BT_LE_LOG_CTRL_BUF2_SIZE - int "size of the second BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 1024 - help + config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help Configure the size of the second BLE controller LOG buffer. -config BT_LE_LOG_HCI_BUF_SIZE - int "size of the BLE HCI LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the BLE HCI LOG buffer. + config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE + bool "Enable wrap panic handler" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Wrap esp_panic_handler to get controller logs when PC pointer exception crashes. + + config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + bool "Enable esp_task_wdt_isr_user_handler implementation" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered. + + config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL + int "The output level of controller log" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 5 + default 1 + help + The output level of controller log. + + config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH + hex "The switch of module log output" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 0xFFFFFFFF + default 0xFFFFFFFF + help + The switch of module log output, this is an unsigned 32-bit hexadecimal value. + + config BT_LE_ERROR_SIM_ENABLED + bool "Enable controller features for internal testing" + default n + + config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" + default n + + config BT_LE_DEBUG_REMAIN_SCENE_ENABLED + bool "Remain scene with GDB to capture relevant status info(Experimental)" + default n + help + Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n +endmenu + config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" range 1 5 @@ -372,7 +463,7 @@ config BT_LE_CRYPTO_STACK_MBEDTLS config BT_LE_WHITELIST_SIZE int "BLE white list size" - range 1 15 + range 1 31 default 12 depends on !BT_NIMBLE_ENABLED @@ -393,6 +484,23 @@ config BT_LE_LL_SCA help Sleep clock accuracy of our device (in ppm) +config BT_LE_LL_PEER_SCA_SET_ENABLE + bool "Enable to set constant peer SCA" + default n + help + Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM. + Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value + to calculate the window widening instead of the value received from peer device. + + +config BT_LE_LL_PEER_SCA + int "Constant peer sleep clock accuracy value" + range 0 10000 + depends on BT_LE_LL_PEER_SCA_SET_ENABLE + default 0 + help + Set the sleep clock accuracy of peer device + config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED @@ -463,6 +571,7 @@ config BT_LE_USE_ESP_TIMER help Set this option to use Esp Timer which has higher priority timer instead of FreeRTOS timer + config BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP bool "BLE adv report flow control supported" default y @@ -561,3 +670,145 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD config BT_LE_MSYS_INIT_IN_CONTROLLER bool "Msys Mbuf Init in Controller" default y + +config BT_LE_TX_CCA_ENABLED + bool "Enable TX CCA feature" + default n + help + Enable CCA feature to cancel sending the packet if the signal power is stronger than CCA threshold. + +config BT_LE_CCA_RSSI_THRESH + int "CCA RSSI threshold value" + depends on BT_LE_TX_CCA_ENABLED + range 20 100 + default 65 + help + Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 + +config BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + +config BT_CTRL_RUN_IN_FLASH_ONLY + bool "Reduce BLE IRAM usage (READ DOCS FIRST) (EXPERIMENTAL)" + default n + help + Move most IRAM into flash. This will increase the usage of flash and reduce ble performance. + Because the code is moved to the flash, the execution speed of the code is reduced. + To have a small impact on performance, you need to enable flash suspend (SPI_FLASH_AUTO_SUSPEND). + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_LE_CTRL_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_LE_CTRL_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu + +config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + int "The value of upperlimitmax during scan backoff procedure" + range 1 256 + default 32 + help + The value of upperlimitmax needs to be a power of 2. + +config BT_LE_CTRL_CHAN_ASS_EN + bool "Enable channel assessment(Experimental)" + default n + help + If this option is enabled, The Controller will records the communication quality + for each channel and then start a timer to check and update the channel map every 4 seconds. + +config BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX + bool "Enable aux packet when ext adv data length is zero(Experimental)" + default y + help + When this option is enabled, auxiliary packets will be present in the events of + 'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0. + If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0. + +config BT_LE_RXBUF_OPT_ENABLED + bool "Enable rxbuf optimization feature" + default y + +config BT_LE_CTRL_FAST_CONN_DATA_TX_EN + bool "Enable fast sending of connection data" + default y + help + If this option is enabled, The Controller will continue to + Send an empty PDU after sending valid connection data within an interval. diff --git a/lib/bt/controller/esp32c5/ble.c b/lib/bt/controller/esp32c5/ble.c new file mode 100644 index 00000000..8aef45a9 --- /dev/null +++ b/lib/bt/controller/esp32c5/ble.c @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include <stdlib.h> + +#include "sdkconfig.h" +#include "esp_bt_cfg.h" +#include "esp_bit_defs.h" + +/* External functions or variables + ************************************************************************ + */ +int base_stack_initEnv(void); +void base_stack_deinitEnv(void); +int base_stack_enable(void); +void base_stack_disable(void); + +int conn_stack_initEnv(void); +void conn_stack_deinitEnv(void); +int conn_stack_enable(void); +void conn_stack_disable(void); + +#if CONFIG_BT_LE_ERROR_SIM_ENABLED +int conn_errorSim_initEnv(void); +void conn_errorSim_deinitEnv(void); +int conn_errorSim_enable(void); +void conn_errorSim_disable(void); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void adv_stack_enableClearLegacyAdvVsCmd(bool en); +void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +void advFilter_stack_enableDupExcListVsCmd(bool en); +void arr_stack_enableMultiConnVsCmd(bool en); +void pcl_stack_enableSetRssiThreshVsCmd(bool en); +void chanSel_stack_enableSetCsaVsCmd(bool en); +void log_stack_enableLogsRelatedVsCmd(bool en); +void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); + +void adv_stack_enableScanReqRxdVsEvent(bool en); +void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED +extern void mmgmt_enableRxbufOptFeature(void); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + +/* Local functions definition + *************************************************************************** + */ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void ble_stack_enableVsCmds(bool en) +{ + adv_stack_enableClearLegacyAdvVsCmd(en); + advFilter_stack_enableDupExcListVsCmd(en); + scan_stack_enableAdvFlowCtrlVsCmd(en); + arr_stack_enableMultiConnVsCmd(en); + pcl_stack_enableSetRssiThreshVsCmd(en); + chanSel_stack_enableSetCsaVsCmd(en); + log_stack_enableLogsRelatedVsCmd(en); + hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); +} + +void ble_stack_enableVsEvents(bool en) +{ + adv_stack_enableScanReqRxdVsEvent(en); + conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE +} +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +int ble_stack_initEnv(void) +{ + int rc; + + rc = base_stack_initEnv(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_initEnv(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_initEnv(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + return 0; +} + +void ble_stack_deinitEnv(void) +{ +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_deinitEnv(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_deinitEnv(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_deinitEnv(); +} + +int ble_stack_enable(void) +{ + int rc; + + rc = base_stack_enable(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_enable(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_enable(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsCmds(true); + ble_stack_enableVsEvents(true); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED + mmgmt_enableRxbufOptFeature(); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + + return 0; +} + +void ble_stack_disable(void) +{ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsEvents(false); + ble_stack_enableVsCmds(false); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_disable(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_disable(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_disable(); +} diff --git a/lib/bt/controller/esp32c5/ble_priv.h b/lib/bt/controller/esp32c5/ble_priv.h new file mode 100644 index 00000000..82dc4d16 --- /dev/null +++ b/lib/bt/controller/esp32c5/ble_priv.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +int ble_stack_initEnv(void); + +void ble_stack_deinitEnv(void); + +int ble_stack_enable(void); + +void ble_stack_disable(void); diff --git a/lib/bt/controller/esp32c5/bt.c b/lib/bt/controller/esp32c5/bt.c index 17794564..e6070f52 100644 --- a/lib/bt/controller/esp32c5/bt.c +++ b/lib/bt/controller/esp32c5/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,38 +30,36 @@ #endif // CONFIG_SW_COEXIST_ENABLE #include "nimble/nimble_npl_os.h" -#include "ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" +#include "ble_priv.h" #include "esp_intr_alloc.h" #include "esp_sleep.h" #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" +#include "soc/retention_periph_defs.h" +#include "soc/regdma.h" #include "bt_osi_mem.h" -#if SOC_PM_RETENTION_HAS_CLOCK_BUG -#include "esp_private/sleep_retention.h" -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG - #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" +#include "esp_private/sleep_retention.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED - #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "esp_private/periph_ctrl.h" -#include "esp_sleep.h" - +#include "esp_private/esp_clk_tree_common.h" #include "hal/efuse_hal.h" #include "soc/rtc.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + /* Macro definition ************************************************************************ */ @@ -69,16 +67,11 @@ #define OSI_COEX_VERSION 0x00010006 #define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20250415 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - /* Types definition ************************************************************************ */ @@ -97,12 +90,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -111,25 +98,33 @@ struct ext_funcs_t { int (* _ecc_gen_key_pair)(uint8_t *public, uint8_t *priv); int (* _ecc_gen_dh_key)(const uint8_t *remote_pub_key_x, const uint8_t *remote_pub_key_y, const uint8_t *local_priv_key, uint8_t *dhkey); - void (* _esp_reset_rpa_moudle)(void); uint32_t magic; }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); -#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +enum { + BLE_LOG_INTERFACE_FLAG_CONTINUE = 0, + BLE_LOG_INTERFACE_FLAG_END, +}; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); +extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); -extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); +extern void esp_panic_handler_feed_wdts(void); +extern int r_ble_log_ctrl_level_and_mod(uint8_t log_level, uint32_t mod_switch); +extern int r_ble_ctrl_mod_type(uint16_t mod, uint32_t mod_type_switch); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int r_ble_controller_deinit(void); extern int r_ble_controller_enable(uint8_t mode); @@ -147,11 +142,17 @@ extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY +extern void r_ble_ll_scan_start_time_init_compensation(uint32_t init_compensation); +extern void r_priv_sdk_config_insert_proc_time_set(uint16_t insert_proc_time); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); -extern void esp_ble_set_wakeup_overhead(uint32_t overhead); +extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void r_esp_ble_change_rtc_freq(uint32_t freq); +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE +extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); @@ -179,27 +180,21 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); static void osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); static uint32_t osi_random_wrapper(void); -static void esp_reset_rpa_moudle(void); static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** @@ -209,18 +204,242 @@ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTR #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +static bool log_is_inited = false; + +esp_err_t esp_bt_controller_log_init(void) +{ + if (log_is_inited) { + return ESP_OK; + } + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; + } + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; +} + +void esp_bt_controller_log_deinit(void) +{ +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + r_ble_log_async_output_dump_all(true); + esp_bt_controller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_feed_wdts(); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE +void esp_task_wdt_isr_user_handler(void) +{ + esp_ble_controller_log_dump_all(true); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE +void __real_esp_panic_handler(void *info); +void __wrap_esp_panic_handler (void *info) +{ + esp_ble_controller_log_dump_all(true); + __real_esp_panic_handler(info); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ static bool s_ble_active = false; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; -#define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +#define MAIN_XTAL_FREQ_HZ (48000000) +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; +static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000; #define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500) #define BLE_RTC_DELAY_US_MODEM_SLEEP (500) +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA) +void *malloc_ble_controller_mem(size_t size) +{ + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} + static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, ._version = OSI_COEX_VERSION, @@ -236,29 +455,15 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, ._os_random = osi_random_wrapper, ._ecc_gen_key_pair = esp_ecc_gen_key_pair, ._ecc_gen_dh_key = esp_ecc_gen_dh_key, - ._esp_reset_rpa_moudle = esp_reset_rpa_moudle, .magic = EXT_FUNC_MAGIC_VALUE, }; -static void IRAM_ATTR esp_reset_rpa_moudle(void) -{ - -} - static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) { @@ -288,75 +493,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -388,103 +524,91 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) +static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, + void *arg, void **ret_handle_in) { - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + int rc = esp_intr_alloc(source, flags, handler, arg, (intr_handle_t *)ret_handle_in); +#else + int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); +#endif return rc; } - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) +static int esp_intr_free_wrapper(void **ret_handle) { - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); + int rc = 0; + rc = esp_intr_free((intr_handle_t) * ret_handle); + *ret_handle = NULL; return rc; } -static int hci_uart_close_wrapper(int uart_no) +void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) { - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; + /* Select slow clock source for BT momdule */ + switch (slow_clk_src) { + case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_XTAL32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_RC32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + case MODEM_CLOCK_LPCLK_SRC_EXT32K: + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); + break; + default: + } } -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) { - //This function is nowhere to use. + return s_bt_lpclk_src; } -static int hci_uart_init_wrapper(int uart_no, void *cfg) +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) { - //This function is nowhere to use. - return 0; -} + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; + s_bt_lpclk_src = clk_src; } -static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, - void *arg, void **ret_handle_in) +uint32_t esp_bt_get_lpclk_freq(void) { - int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, - arg, (intr_handle_t *)ret_handle_in); - return rc; + return s_bt_lpclk_freq; } -static int esp_intr_free_wrapper(void **ret_handle) +void esp_bt_set_lpclk_freq(uint32_t clk_freq) { - int rc = 0; - rc = esp_intr_free((intr_handle_t) * ret_handle); - *ret_handle = NULL; - return rc; -} + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } -void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) -{ - /* Select slow clock source for BT momdule */ - // switch (slow_clk_src) { - // case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: - // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); - // uint32_t chip_version = efuse_hal_chip_revision(); - // if (chip_version == 0) { - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1)); - // } else{ - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); - // } - // break; - // case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: - // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); - // break; - // case MODEM_CLOCK_LPCLK_SRC_XTAL32K: - // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using external 32.768 kHz XTAL as clock source"); - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); - // break; - // case MODEM_CLOCK_LPCLK_SRC_RC32K: - // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); - // break; - // case MODEM_CLOCK_LPCLK_SRC_EXT32K: - // ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 32 kHz oscillator as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); - // modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (1 - 1)); - // break; - // default: - // } + if (!clk_freq) { + return; + } + + if (MAIN_XTAL_FREQ_HZ % clk_freq) { + return; + } + + s_bt_lpclk_freq = clk_freq; } IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) @@ -508,18 +632,26 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) return; } #ifdef CONFIG_PM_ENABLE + esp_pm_config_t pm_config; esp_pm_lock_acquire(s_pm_lock); + esp_pm_get_configuration(&pm_config); + assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz); r_ble_rtc_wake_up_state_clr(); #endif //CONFIG_PM_ENABLE esp_phy_enable(PHY_MODEM_BT); + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + uint32_t *clk_freq = (uint32_t *)arg; + *clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + } s_ble_active = true; } #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + int extra = *(int *)arg; + sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); @@ -527,14 +659,32 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) return err; } +static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) +{ + int retention_args = extra; + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, + .depends = RETENTION_MODULE_BITMAP_INIT(BT_BB) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_BLE_MAC); + } + return err; +} + static void sleep_modem_ble_mac_modem_state_deinit(void) { - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_BLE_MAC); + esp_err_t err = sleep_retention_module_free(SLEEP_RETENTION_MODULE_BLE_MAC); + if (err == ESP_OK) { + err = sleep_retention_module_deinit(SLEEP_RETENTION_MODULE_BLE_MAC); + assert(err == ESP_OK); + } } -void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +void IRAM_ATTR sleep_modem_light_sleep_overhead_set(uint32_t overhead) { - esp_ble_set_wakeup_overhead(overhead); + r_esp_ble_set_wakeup_overhead(overhead); } #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ @@ -559,10 +709,13 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE /* Create a new regdma link for BLE related register restoration */ - rc = sleep_modem_ble_mac_modem_state_init(1); - assert(rc == 0); + rc = sleep_modem_ble_mac_modem_state_init(0); + if (rc != ESP_OK) { + goto error; + } esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); @@ -575,19 +728,21 @@ esp_err_t controller_sleep_init(void) sleep_modem_register_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ return rc; +#ifdef CONFIG_PM_ENABLE error: - -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE #if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD esp_sleep_disable_bt_wakeup(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#ifdef CONFIG_PM_ENABLE /*lock should release first and then delete*/ if (s_pm_lock != NULL) { esp_pm_lock_delete(s_pm_lock); @@ -600,7 +755,7 @@ error: void controller_sleep_deinit(void) { -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE #if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); @@ -688,15 +843,55 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = s_bt_lpclk_freq; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + cfg->ble_ll_sca = 3000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_ERR_INVALID_STATE; @@ -745,33 +940,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); esp_phy_modem_init(); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { @@ -785,20 +954,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = r_ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = r_ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -810,14 +966,23 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto modem_deint; } + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + ret = r_ble_controller_init(cfg); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); goto modem_deint; } - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + + ret = ble_stack_initEnv(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret); + goto free_controller; + } ble_controller_scan_duplicate_config(); @@ -832,24 +997,37 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } + ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); + ble_stack_deinitEnv(); r_ble_controller_deinit(); modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED esp_phy_modem_deinit(); // modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); @@ -873,6 +1051,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -881,10 +1060,11 @@ esp_err_t esp_bt_controller_deinit(void) // modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + ble_stack_deinitEnv(); r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -930,6 +1110,16 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + r_ble_ll_scan_start_time_init_compensation(500); + r_priv_sdk_config_insert_proc_time_set(500); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + + if (ble_stack_enable() != 0) { + ret = ESP_FAIL; + goto error; + } + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; @@ -938,6 +1128,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_OK; error: + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -961,6 +1152,7 @@ esp_err_t esp_bt_controller_disable(void) if (r_ble_controller_disable() != 0) { return ESP_FAIL; } + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -1090,9 +1282,17 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ switch (power_type) { case ESP_BLE_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_ADV: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0xFF, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_SCAN: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1123,9 +1323,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type esp_err_t stat = ESP_FAIL; switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1148,11 +1352,15 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; + case ESP_BLE_PWR_TYPE_ADV: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0); + break; + case ESP_BLE_PWR_TYPE_SCAN: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); + break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: case ESP_BLE_PWR_TYPE_CONN_HDL2: @@ -1182,9 +1390,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: @@ -1202,26 +1412,47 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); + bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END)); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + + if (len && addr) { + for (int i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); } } - if (end) { - esp_rom_printf("\n"); + if (len_append && addr_append) { + for (int i = 0; i < len_append; i++) { esp_rom_printf("%02x ", addr_append[i]); } } + if (end) { esp_rom_printf("\n"); } + + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); + esp_panic_handler_feed_wdts(); BT_ASSERT_PRINT("\r\n[DUMP_START:"); r_ble_log_async_output_dump_all(output); BT_ASSERT_PRINT(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED @@ -1436,3 +1667,36 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) + +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED +#include "esp_gdbstub.h" +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + +int IRAM_ATTR +ble_capture_info_user_handler(uint8_t type, uint32_t reason, uint32_t param1, uint32_t param2) +{ + int i; + + switch(type) { + case 0: + for (i = 0; i < 2; i++) { + esp_ble_controller_info_capture(0x010101); + } +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + uintptr_t sp; + __asm__ volatile ("mv %0, sp" : "=r" (sp)); + esp_gdbstub_panic_handler(&sp); +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + break; +#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + case 1: + if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { + osi_assert_wrapper(__LINE__,__func__, type, reason); + } + break; +#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + default: + break; + } + return 0; +} diff --git a/lib/bt/controller/esp32c5/esp_bt_cfg.h b/lib/bt/controller/esp32c5/esp_bt_cfg.h index b9597034..48a845a3 100644 --- a/lib/bt/controller/esp32c5/esp_bt_cfg.h +++ b/lib/bt/controller/esp32c5/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -129,16 +129,93 @@ extern "C" { #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF +#ifdef CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS) +#else +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CONN_UPDATE +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (1<<0) +#else +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (0<<0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (1<<1) +#else +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (0<<1) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_PHY_UPDATE +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (1<<2) +#else +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (0<<2) +#endif + +#define BT_LE_CTRL_LLCP_DISC_FLAG (BT_CTRL_BLE_LLCP_CONN_UPDATE | BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE | BT_CTRL_BLE_LLCP_PHY_UPDATE) + +#ifdef CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX) +#else +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (256) +#endif + +#if defined(CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#else +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#else +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#else +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else #define HCI_UART_EN 0 // hci ram mode #endif +#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#define DEFAULT_BT_LE_VHCI_ENABLED (CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) +#else +#define DEFAULT_BT_LE_VHCI_ENABLED (0) +#endif + +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else @@ -169,8 +246,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -179,8 +254,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -205,8 +278,7 @@ extern "C" { #define RTC_FREQ_N (32768) /* in Hz */ -#define BLE_LL_TX_PWR_DBM_N (9) - +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) #define RUN_QA_TEST (0) diff --git a/lib/bt/controller/esp32c6/Kconfig.in b/lib/bt/controller/esp32c6/Kconfig.in index 0dcc8996..949349aa 100644 --- a/lib/bt/controller/esp32c6/Kconfig.in +++ b/lib/bt/controller/esp32c6/Kconfig.in @@ -1,20 +1,37 @@ menu "HCI Config" - choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +90,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 2048 help - Set the size of uart task stack + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 + help + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -182,6 +227,16 @@ config BT_LE_POWER_CONTROL_ENABLED help Set this option to enable the Power Control feature on controller +config BT_LE_CTE_FEATURE_ENABLED + bool "Enable Bluetooth LE Direction Finding (AoA/AoD)" + depends on BT_LE_50_FEATURE_SUPPORT && SOC_BLE_CTE_SUPPORTED + default n + help + Enable this option to activate Bluetooth LE Direction Finding (AoA/AoD) feature. + Note: + This feature allows devices to determine the direction of a Bluetooth CTE signal, + enabling Angle of Arrival (AoA) and Angle of Departure (AoD) functionality. + menu "Memory Settings" depends on !BT_NIMBLE_ENABLED @@ -269,54 +324,131 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -menuconfig BT_LE_CONTROLLER_LOG_ENABLED - bool "Controller log enable" - default n - help - Enable controller log +menu "Controller debug features" + menuconfig BT_LE_CONTROLLER_LOG_ENABLED + bool "Controller log enable" + default n + help + Enable controller log -config BT_LE_CONTROLLER_LOG_CTRL_ENABLED - bool "enable controller log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable controller log module -config BT_LE_CONTROLLER_LOG_HCI_ENABLED - bool "enable HCI log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable hci log module -config BT_LE_CONTROLLER_LOG_DUMP_ONLY - bool "Controller log dump mode only" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_DUMP_ONLY + bool "Controller log dump mode only" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Only operate in dump mode -config BT_LE_LOG_CTRL_BUF1_SIZE - int "size of the first BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + bool "Output ble controller logs to SPI bus (Experimental)" + depends on BT_LE_CONTROLLER_LOG_ENABLED + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + select BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Output ble controller logs to SPI bus + + config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + + config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + + config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the first BLE controller LOG buffer. -config BT_LE_LOG_CTRL_BUF2_SIZE - int "size of the second BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 1024 - help + config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help Configure the size of the second BLE controller LOG buffer. -config BT_LE_LOG_HCI_BUF_SIZE - int "size of the BLE HCI LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the BLE HCI LOG buffer. + config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE + bool "Enable wrap panic handler" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Wrap esp_panic_handler to get controller logs when PC pointer exception crashes. + + config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + bool "Enable esp_task_wdt_isr_user_handler implementation" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered. + + config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL + int "The output level of controller log" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 5 + default 1 + help + The output level of controller log. + + config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH + hex "The switch of module log output" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 0xFFFFFFFF + default 0xFFFFFFFF + help + The switch of module log output, this is an unsigned 32-bit hexadecimal value. + + config BT_LE_ERROR_SIM_ENABLED + bool "Enable controller features for internal testing" + default n + + config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" + default n + + config BT_LE_DEBUG_REMAIN_SCENE_ENABLED + bool "Remain scene with GDB to capture relevant status info(Experimental)" + default n + help + Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n +endmenu + config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" range 1 5 @@ -372,7 +504,7 @@ config BT_LE_CRYPTO_STACK_MBEDTLS config BT_LE_WHITELIST_SIZE int "BLE white list size" - range 1 15 + range 1 31 default 12 depends on !BT_NIMBLE_ENABLED @@ -393,6 +525,23 @@ config BT_LE_LL_SCA help Sleep clock accuracy of our device (in ppm) +config BT_LE_LL_PEER_SCA_SET_ENABLE + bool "Enable to set constant peer SCA" + default n + help + Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM. + Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value + to calculate the window widening instead of the value received from peer device. + + +config BT_LE_LL_PEER_SCA + int "Constant peer sleep clock accuracy value" + range 0 10000 + depends on BT_LE_LL_PEER_SCA_SET_ENABLE + default 0 + help + Set the sleep clock accuracy of peer device + config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED @@ -572,6 +721,128 @@ config BT_LE_CCA_RSSI_THRESH int "CCA RSSI threshold value" depends on BT_LE_TX_CCA_ENABLED range 20 100 - default 20 + default 65 help Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 + +config BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + +config BT_CTRL_RUN_IN_FLASH_ONLY + bool "Reduce BLE IRAM usage (READ DOCS FIRST) (EXPERIMENTAL)" + default n + help + Move most IRAM into flash. This will increase the usage of flash and reduce ble performance. + Because the code is moved to the flash, the execution speed of the code is reduced. + To have a small impact on performance, you need to enable flash suspend (SPI_FLASH_AUTO_SUSPEND). + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_LE_CTRL_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_LE_CTRL_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu + +config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + int "The value of upperlimitmax during scan backoff procedure" + range 1 256 + default 32 + help + The value of upperlimitmax needs to be a power of 2. + +config BT_LE_CTRL_CHAN_ASS_EN + bool "Enable channel assessment(Experimental)" + default n + help + If this option is enabled, The Controller will records the communication quality + for each channel and then start a timer to check and update the channel map every 4 seconds. + +config BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX + bool "Enable aux packet when ext adv data length is zero(Experimental)" + default y + help + When this option is enabled, auxiliary packets will be present in the events of + 'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0. + If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0. + +config BT_LE_RXBUF_OPT_ENABLED + bool "Enable rxbuf optimization feature" + default y + +config BT_LE_CTRL_FAST_CONN_DATA_TX_EN + bool "Enable fast sending of connection data" + default y + help + If this option is enabled, The Controller will continue to + Send an empty PDU after sending valid connection data within an interval. diff --git a/lib/bt/controller/esp32c6/ble.c b/lib/bt/controller/esp32c6/ble.c new file mode 100644 index 00000000..a1eb1374 --- /dev/null +++ b/lib/bt/controller/esp32c6/ble.c @@ -0,0 +1,171 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include <stdlib.h> + +#include "sdkconfig.h" +#include "esp_bt_cfg.h" +#include "esp_bit_defs.h" + +/* External functions or variables + ************************************************************************ + */ +int base_stack_initEnv(void); +void base_stack_deinitEnv(void); +int base_stack_enable(void); +void base_stack_disable(void); + +int conn_stack_initEnv(void); +void conn_stack_deinitEnv(void); +int conn_stack_enable(void); +void conn_stack_disable(void); + +#if CONFIG_BT_LE_ERROR_SIM_ENABLED +int conn_errorSim_initEnv(void); +void conn_errorSim_deinitEnv(void); +int conn_errorSim_enable(void); +void conn_errorSim_disable(void); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void adv_stack_enableClearLegacyAdvVsCmd(bool en); +void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +void advFilter_stack_enableDupExcListVsCmd(bool en); +void arr_stack_enableMultiConnVsCmd(bool en); +void pcl_stack_enableSetRssiThreshVsCmd(bool en); +void chanSel_stack_enableSetCsaVsCmd(bool en); +void log_stack_enableLogsRelatedVsCmd(bool en); +void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); +#if CONFIG_IDF_TARGET_ESP32C61_ECO3 +void conn_stack_enableSetPrefTxRxCntVsCmd(bool en); +#endif // CONFIG_IDF_TARGET_ESP32C61_ECO3 + +void adv_stack_enableScanReqRxdVsEvent(bool en); +void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED +extern void mmgmt_enableRxbufOptFeature(void); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + +/* Local functions definition + *************************************************************************** + */ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void ble_stack_enableVsCmds(bool en) +{ + adv_stack_enableClearLegacyAdvVsCmd(en); + advFilter_stack_enableDupExcListVsCmd(en); + scan_stack_enableAdvFlowCtrlVsCmd(en); + arr_stack_enableMultiConnVsCmd(en); + pcl_stack_enableSetRssiThreshVsCmd(en); + chanSel_stack_enableSetCsaVsCmd(en); + log_stack_enableLogsRelatedVsCmd(en); + hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); +#if CONFIG_IDF_TARGET_ESP32C61_ECO3 + conn_stack_enableSetPrefTxRxCntVsCmd(en); +#endif // CONFIG_IDF_TARGET_ESP32C61_ECO3 +} + +void ble_stack_enableVsEvents(bool en) +{ + adv_stack_enableScanReqRxdVsEvent(en); + conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE +} +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +int ble_stack_initEnv(void) +{ + int rc; + + rc = base_stack_initEnv(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_initEnv(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_initEnv(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + return 0; +} + +void ble_stack_deinitEnv(void) +{ +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_deinitEnv(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_deinitEnv(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_deinitEnv(); +} + +int ble_stack_enable(void) +{ + int rc; + + rc = base_stack_enable(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_enable(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_enable(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsCmds(true); + ble_stack_enableVsEvents(true); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED + mmgmt_enableRxbufOptFeature(); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + + return 0; +} + +void ble_stack_disable(void) +{ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsEvents(false); + ble_stack_enableVsCmds(false); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_disable(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_disable(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_disable(); +} diff --git a/lib/bt/controller/esp32c6/ble_priv.h b/lib/bt/controller/esp32c6/ble_priv.h new file mode 100644 index 00000000..82dc4d16 --- /dev/null +++ b/lib/bt/controller/esp32c6/ble_priv.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +int ble_stack_initEnv(void); + +void ble_stack_deinitEnv(void); + +int ble_stack_enable(void); + +void ble_stack_disable(void); diff --git a/lib/bt/controller/esp32c6/bt.c b/lib/bt/controller/esp32c6/bt.c index 489327f0..dd57e8b3 100644 --- a/lib/bt/controller/esp32c6/bt.c +++ b/lib/bt/controller/esp32c6/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,32 +30,26 @@ #endif // CONFIG_ESP_COEX_ENABLED #include "nimble/nimble_npl_os.h" -#include "ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" #include "esp_intr_alloc.h" +#include "ble_priv.h" #include "esp_sleep.h" #include "esp_pm.h" #ifdef CONFIG_ESP_PHY_ENABLED #include "esp_phy_init.h" #endif #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" +#include "esp_private/esp_clk_tree_common.h" #include "bt_osi_mem.h" -#if SOC_PM_RETENTION_HAS_CLOCK_BUG -#include "esp_private/sleep_retention.h" -#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG - #if CONFIG_FREERTOS_USE_TICKLESS_IDLE #include "esp_private/sleep_modem.h" +#include "esp_private/sleep_retention.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED - #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -64,6 +58,12 @@ #include "hal/efuse_hal.h" #include "soc/rtc.h" +#include "modem/modem_syscon_struct.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + /* Macro definition ************************************************************************ */ @@ -71,16 +71,11 @@ #define OSI_COEX_VERSION 0x00010006 #define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20250415 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - /* Types definition ************************************************************************ */ @@ -99,12 +94,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -113,25 +102,42 @@ struct ext_funcs_t { int (* _ecc_gen_key_pair)(uint8_t *public, uint8_t *priv); int (* _ecc_gen_dh_key)(const uint8_t *remote_pub_key_x, const uint8_t *remote_pub_key_y, const uint8_t *local_priv_key, uint8_t *dhkey); - void (* _esp_reset_rpa_moudle)(void); +#if CONFIG_IDF_TARGET_ESP32C6 + void (* _esp_reset_modem)(uint8_t mdl_opts, uint8_t start); +#endif // CONFIG_IDF_TARGET_ESP32C6 uint32_t magic; }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); + +enum { + BLE_LOG_INTERFACE_FLAG_CONTINUE = 0, + BLE_LOG_INTERFACE_FLAG_END, +}; #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables ************************************************************************ */ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE +extern void coex_hw_timer_set(uint8_t idx,uint8_t src, uint8_t pti,uint32_t latency, uint32_t perioidc); +extern void coex_hw_timer_enable(uint8_t idx); +extern void coex_hw_timer_disable(uint8_t idx); +#endif // CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); +extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); -extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); +extern void esp_panic_handler_feed_wdts(void); +extern int r_ble_log_ctrl_level_and_mod(uint8_t log_level, uint32_t mod_switch); +extern int r_ble_ctrl_mod_type(uint16_t mod, uint32_t mod_type_switch); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int r_ble_controller_deinit(void); extern int r_ble_controller_enable(uint8_t mode); @@ -149,11 +155,17 @@ extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY +extern void r_ble_ll_scan_start_time_init_compensation(uint32_t init_compensation); +extern void r_priv_sdk_config_insert_proc_time_set(uint16_t insert_proc_time); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void r_esp_ble_change_rtc_freq(uint32_t freq); +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE +extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); @@ -181,27 +193,24 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); static void osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); static uint32_t osi_random_wrapper(void); -static void esp_reset_rpa_moudle(void); +#if CONFIG_IDF_TARGET_ESP32C6 +static void esp_reset_modem(uint8_t mdl_opts,uint8_t start); +#endif // CONFIG_IDF_TARGET_ESP32C6 static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** @@ -211,18 +220,243 @@ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTR #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +static bool log_is_inited = false; + +esp_err_t esp_bt_controller_log_init(void) +{ + if (log_is_inited) { + return ESP_OK; + } + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; + } + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; +} + +void esp_bt_controller_log_deinit(void) +{ +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + r_ble_log_async_output_dump_all(true); + esp_bt_controller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_feed_wdts(); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(log_output_mode); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE +void esp_task_wdt_isr_user_handler(void) +{ + esp_ble_controller_log_dump_all(true); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE +void __real_esp_panic_handler(void *info); +void __wrap_esp_panic_handler (void *info) +{ + esp_ble_controller_log_dump_all(true); + __real_esp_panic_handler(info); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ static bool s_ble_active = false; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; -#define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +#define MAIN_XTAL_FREQ_HZ (40000000) +#define MAIN_XTAL_FREQ_HZ_WORKROUND (500000) +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; +static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000; -#define BLE_RTC_DELAY_US_LIGHT_SLEEP (2500) +#define BLE_RTC_DELAY_US_LIGHT_SLEEP (3200) #define BLE_RTC_DELAY_US_MODEM_SLEEP (500) +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA) +void *malloc_ble_controller_mem(size_t size) +{ + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} + static const struct osi_coex_funcs_t s_osi_coex_funcs_ro = { ._magic = OSI_COEX_MAGIC_VALUE, ._version = OSI_COEX_VERSION, @@ -238,29 +472,40 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, ._os_random = osi_random_wrapper, ._ecc_gen_key_pair = esp_ecc_gen_key_pair, ._ecc_gen_dh_key = esp_ecc_gen_dh_key, - ._esp_reset_rpa_moudle = esp_reset_rpa_moudle, +#if CONFIG_IDF_TARGET_ESP32C6 + ._esp_reset_modem = esp_reset_modem, +#endif // CONFIG_IDF_TARGET_ESP32C6 .magic = EXT_FUNC_MAGIC_VALUE, }; -static void IRAM_ATTR esp_reset_rpa_moudle(void) +#if CONFIG_IDF_TARGET_ESP32C6 +static void IRAM_ATTR esp_reset_modem(uint8_t mdl_opts,uint8_t start) { + if (mdl_opts == 0x05) { + if (start) { +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_hw_timer_set(0x04, 0x02, 15, 0, 5000); + coex_hw_timer_enable(0x04); +#endif // CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + MODEM_SYSCON.modem_rst_conf.val |= (BIT(16) | BIT(18)); + MODEM_SYSCON.modem_rst_conf.val &= ~(BIT(16) | BIT(18)); + } else { +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_hw_timer_disable(0x04); +#endif // CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + } + } } +#endif // CONFIG_IDF_TARGET_ESP32C6 + static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) { @@ -290,75 +535,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -390,61 +566,13 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) +static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - -static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, - void *arg, void **ret_handle_in) -{ - int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, - arg, (intr_handle_t *)ret_handle_in); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + int rc = esp_intr_alloc(source, flags, handler, arg, (intr_handle_t *)ret_handle_in); +#else + int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); +#endif return rc; } @@ -461,16 +589,21 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) /* Select slow clock source for BT momdule */ switch (slow_clk_src) { case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); +#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND uint32_t chip_version = efuse_hal_chip_revision(); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source, chip ver: %d", chip_version); if (chip_version == 0) { - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (400 - 1)); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1)); } else{ - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ_WORKROUND/s_bt_lpclk_freq - 1)); } +#else + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1)); +#endif // SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND break; case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!"); modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); break; case MODEM_CLOCK_LPCLK_SRC_XTAL32K: @@ -489,6 +622,56 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) } } +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + +uint32_t esp_bt_get_lpclk_freq(void) +{ + return s_bt_lpclk_freq; +} + +void esp_bt_set_lpclk_freq(uint32_t clk_freq) +{ + uint32_t xtal_freq; + + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + + if (!clk_freq) { + return; + } + + xtal_freq = MAIN_XTAL_FREQ_HZ; +#if SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND + uint32_t chip_version = efuse_hal_chip_revision(); + if (chip_version == 1) { + xtal_freq = MAIN_XTAL_FREQ_HZ_WORKROUND; + } +#endif // SOC_BLE_USE_WIFI_PWR_CLK_WORKAROUND + + if (xtal_freq % clk_freq) { + return; + } + + s_bt_lpclk_freq = clk_freq; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -510,10 +693,17 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) return; } #ifdef CONFIG_PM_ENABLE + esp_pm_config_t pm_config; esp_pm_lock_acquire(s_pm_lock); + esp_pm_get_configuration(&pm_config); + assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz); r_ble_rtc_wake_up_state_clr(); #endif //CONFIG_PM_ENABLE esp_phy_enable(PHY_MODEM_BT); + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + uint32_t *clk_freq = (uint32_t *)arg; + *clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + } s_ble_active = true; } @@ -522,7 +712,7 @@ static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; int extra = *(int *)arg; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); @@ -535,7 +725,7 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) int retention_args = extra; sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, - .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + .depends = RETENTION_MODULE_BITMAP_INIT(BT_BB) }; esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); if (err == ESP_OK) { @@ -553,7 +743,7 @@ static void sleep_modem_ble_mac_modem_state_deinit(void) } } -void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +void IRAM_ATTR sleep_modem_light_sleep_overhead_set(uint32_t overhead) { r_esp_ble_set_wakeup_overhead(overhead); } @@ -580,13 +770,20 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE -#if CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if SOC_PM_RETENTION_HAS_CLOCK_BUG && !CONFIG_MAC_BB_PD #error "CONFIG_MAC_BB_PD required for BLE light sleep to run properly" -#endif // CONFIG_BT_LE_SLEEP_ENABLE && !CONFIG_MAC_BB_PD +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && !CONFIG_MAC_BB_PD /* Create a new regdma link for BLE related register restoration */ +#if SOC_PM_RETENTION_HAS_CLOCK_BUG rc = sleep_modem_ble_mac_modem_state_init(1); - assert(rc == 0); +#else + rc = sleep_modem_ble_mac_modem_state_init(0); +#endif // SOC_PM_RETENTION_HAS_CLOCK_BUG + if (rc != ESP_OK) { + goto error; + } esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); @@ -599,19 +796,21 @@ esp_err_t controller_sleep_init(void) sleep_modem_register_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ return rc; +#ifdef CONFIG_PM_ENABLE error: - -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE #if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); #endif // SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD esp_sleep_disable_bt_wakeup(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#ifdef CONFIG_PM_ENABLE /*lock should release first and then delete*/ if (s_pm_lock != NULL) { esp_pm_lock_delete(s_pm_lock); @@ -624,7 +823,7 @@ error: void controller_sleep_deinit(void) { -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE #if SOC_PM_RETENTION_HAS_CLOCK_BUG && CONFIG_MAC_BB_PD sleep_modem_unregister_mac_bb_module_prepare_callback(sleep_modem_mac_bb_power_down_prepare, sleep_modem_mac_bb_power_up_prepare); @@ -633,7 +832,7 @@ void controller_sleep_deinit(void) esp_sleep_disable_bt_wakeup(); sleep_modem_ble_mac_modem_state_deinit(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #ifdef CONFIG_PM_ENABLE /* lock should be released first */ esp_pm_lock_delete(s_pm_lock); @@ -712,15 +911,55 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = s_bt_lpclk_freq; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + cfg->ble_ll_sca = 3000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "invalid controller state"); return ESP_ERR_INVALID_STATE; @@ -769,33 +1008,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); esp_phy_modem_init(); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { @@ -809,20 +1022,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = r_ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = r_ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -834,14 +1034,23 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto modem_deint; } + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + ret = r_ble_controller_init(cfg); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); goto modem_deint; } - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + + ret = ble_stack_initEnv(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret); + goto free_controller; + } ble_controller_scan_duplicate_config(); @@ -856,24 +1065,40 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } + ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); + ble_stack_deinitEnv(); r_ble_controller_deinit(); modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED esp_phy_modem_deinit(); modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); @@ -897,6 +1122,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -905,10 +1131,11 @@ esp_err_t esp_bt_controller_deinit(void) modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + ble_stack_deinitEnv(); r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -954,6 +1181,16 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + r_ble_ll_scan_start_time_init_compensation(500); + r_priv_sdk_config_insert_proc_time_set(500); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + + if (ble_stack_enable() != 0) { + ret = ESP_FAIL; + goto error; + } + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; @@ -962,6 +1199,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_OK; error: + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -985,6 +1223,7 @@ esp_err_t esp_bt_controller_disable(void) if (r_ble_controller_disable() != 0) { return ESP_FAIL; } + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -1114,9 +1353,17 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ switch (power_type) { case ESP_BLE_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_ADV: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0xFF, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_SCAN: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1147,9 +1394,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type esp_err_t stat = ESP_FAIL; switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1172,11 +1423,15 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; + case ESP_BLE_PWR_TYPE_ADV: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0); + break; + case ESP_BLE_PWR_TYPE_SCAN: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); + break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: case ESP_BLE_PWR_TYPE_CONN_HDL2: @@ -1206,9 +1461,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: @@ -1226,26 +1483,47 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); + bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END)); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + + if (len && addr) { + for (int i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); } } - if (end) { - esp_rom_printf("\n"); + if (len_append && addr_append) { + for (int i = 0; i < len_append; i++) { esp_rom_printf("%02x ", addr_append[i]); } } + if (end) { esp_rom_printf("\n"); } + + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); + esp_panic_handler_feed_wdts(); BT_ASSERT_PRINT("\r\n[DUMP_START:"); r_ble_log_async_output_dump_all(output); BT_ASSERT_PRINT(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED @@ -1460,3 +1738,36 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) + +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED +#include "esp_gdbstub.h" +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + +int IRAM_ATTR +ble_capture_info_user_handler(uint8_t type, uint32_t reason, uint32_t param1, uint32_t param2) +{ + int i; + + switch(type) { + case 0: + for (i = 0; i < 2; i++) { + esp_ble_controller_info_capture(0x010101); + } +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + uintptr_t sp; + __asm__ volatile ("mv %0, sp" : "=r" (sp)); + esp_gdbstub_panic_handler(&sp); +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + break; +#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + case 1: + if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { + osi_assert_wrapper(__LINE__,__func__, type, reason); + } + break; +#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + default: + break; + } + return 0; +} diff --git a/lib/bt/controller/esp32c6/esp_bt_cfg.h b/lib/bt/controller/esp32c6/esp_bt_cfg.h index 9e341e32..f22c4c75 100644 --- a/lib/bt/controller/esp32c6/esp_bt_cfg.h +++ b/lib/bt/controller/esp32c6/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +40,7 @@ extern "C" { #define DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_COUNT) #define DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT MYNEWT_VAL(BLE_TRANSPORT_EVT_DISCARDABLE_COUNT) #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED MYNEWT_VAL(BLE_POWER_CONTROL) + #define DEFAULT_BT_LE_SUBRATE_ENABLED MYNEWT_VAL(BLE_CONN_SUBRATING) #if defined(CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT) #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) #else @@ -129,16 +130,95 @@ extern "C" { #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + + #define DEFAULT_BT_LE_SUBRATE_ENABLED 0 #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF +#ifdef CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS) +#else +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CONN_UPDATE +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (1<<0) +#else +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (0<<0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (1<<1) +#else +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (0<<1) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_PHY_UPDATE +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (1<<2) +#else +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (0<<2) +#endif + +#define BT_LE_CTRL_LLCP_DISC_FLAG (BT_CTRL_BLE_LLCP_CONN_UPDATE | BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE | BT_CTRL_BLE_LLCP_PHY_UPDATE) + +#ifdef CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX) +#else +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (256) +#endif + +#if defined(CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#else +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#else +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#else +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else #define HCI_UART_EN 0 // hci ram mode #endif +#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#define DEFAULT_BT_LE_VHCI_ENABLED (CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) +#else +#define DEFAULT_BT_LE_VHCI_ENABLED (0) +#endif + +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else @@ -169,8 +249,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -179,8 +257,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -205,8 +281,7 @@ extern "C" { #define RTC_FREQ_N (32768) /* in Hz */ -#define BLE_LL_TX_PWR_DBM_N (9) - +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) #define RUN_QA_TEST (0) diff --git a/lib/bt/controller/esp32c61/Kconfig.in b/lib/bt/controller/esp32c61/Kconfig.in index e69de29b..806ee5e8 100644 --- a/lib/bt/controller/esp32c61/Kconfig.in +++ b/lib/bt/controller/esp32c61/Kconfig.in @@ -0,0 +1 @@ +source "$IDF_PATH/components/bt/controller/esp32c6/Kconfig.in" diff --git a/lib/bt/controller/esp32h2/Kconfig.in b/lib/bt/controller/esp32h2/Kconfig.in index e0c49361..14330540 100644 --- a/lib/bt/controller/esp32h2/Kconfig.in +++ b/lib/bt/controller/esp32h2/Kconfig.in @@ -1,20 +1,37 @@ menu "HCI Config" - choice BT_LE_HCI_INTERFACE - prompt "Select HCI interface" + prompt "HCI mode" default BT_LE_HCI_INTERFACE_USE_RAM config BT_LE_HCI_INTERFACE_USE_RAM - bool "ram" + bool "VHCI" help Use RAM as HCI interface config BT_LE_HCI_INTERFACE_USE_UART - bool "uart" + bool "UART(H4)" help Use UART as HCI interface endchoice + choice BT_LE_UART_HCI_MODE_CHOICE + prompt "UART HCI mode" + depends on BT_LE_HCI_INTERFACE_USE_UART + default BT_LE_UART_HCI_NO_DMA_MODE + help + Specify UART HCI mode: DMA or No DMA + + config BT_LE_UART_HCI_DMA_MODE + bool "UHCI(UART with DMA)(EXPERIMENTAL)" + help + UART HCI Mode with DMA functionality. + + config BT_LE_UART_HCI_NO_DMA_MODE + bool "UART(NO DMA)" + help + UART HCI Mode without DMA functionality. + endchoice + config BT_LE_HCI_UART_PORT int "HCI UART port" depends on BT_LE_HCI_INTERFACE_USE_UART @@ -73,12 +90,40 @@ menu "HCI Config" UART_PARITY_ODD endchoice - config BT_LE_HCI_UART_TASK_STACK_SIZE - int "HCI uart task stack size" - depends on BT_LE_HCI_INTERFACE_USE_UART - default 1000 + config BT_LE_HCI_UART_RX_BUFFER_SIZE + int "The size of rx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 512 + help + The size of rx ring buffer memory + + config BT_LE_HCI_UART_TX_BUFFER_SIZE + int "The size of tx ring buffer memory" + depends on BT_LE_UART_HCI_NO_DMA_MODE + default 256 + help + The size of tx ring buffer memory + + config BT_LE_HCI_TRANS_TASK_STACK_SIZE + int "HCI transport task stack size" + depends on !BT_LE_HCI_INTERFACE_USE_RAM + default 2048 help - Set the size of uart task stack + This configures stack size of hci transport task + + config BT_LE_HCI_TRANS_RX_MEM_NUM + int "The amount of rx memory received at the same time" + depends on BT_LE_UART_HCI_DMA_MODE + default 3 + help + The amount of rx memory received at the same time + + config BT_LE_HCI_LLDESCS_POOL_NUM + int "The amount of lldecs memory for driver dma mode" + depends on BT_LE_UART_HCI_DMA_MODE + default 20 + help + The amount of lldecs memory for driver dma mode endmenu config BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT @@ -182,6 +227,19 @@ config BT_LE_POWER_CONTROL_ENABLED help Set this option to enable the Power Control feature on controller +config BT_LE_CTE_FEATURE_ENABLED + bool "Enable Bluetooth LE Direction Finding (AoA/AoD)" + depends on BT_LE_50_FEATURE_SUPPORT && SOC_BLE_CTE_SUPPORTED && !(BT_LE_SECURITY_ENABLE) + default n + help + Enable this option to activate Bluetooth LE Direction Finding (AoA/AoD) feature. + Note: + This feature allows devices to determine the direction of a Bluetooth CTE signal, + enabling Angle of Arrival (AoA) and Angle of Departure (AoD) functionality. + In chip esp32h2, Direction Finding is not supported in encrypted + communication scenarios. If you are using chip esp32h2, ensure that encryption is + disabled when using this feature. + menu "Memory Settings" depends on !BT_NIMBLE_ENABLED @@ -260,54 +318,131 @@ config BT_LE_CONTROLLER_TASK_STACK_SIZE help This configures stack size of NimBLE controller task -menuconfig BT_LE_CONTROLLER_LOG_ENABLED - bool "Controller log enable" - default n - help - Enable controller log +menu "Controller debug features" + menuconfig BT_LE_CONTROLLER_LOG_ENABLED + bool "Controller log enable" + default n + help + Enable controller log -config BT_LE_CONTROLLER_LOG_CTRL_ENABLED - bool "enable controller log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_CTRL_ENABLED + bool "enable controller log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable controller log module -config BT_LE_CONTROLLER_LOG_HCI_ENABLED - bool "enable HCI log module" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_HCI_ENABLED + bool "enable HCI log module" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Enable hci log module -config BT_LE_CONTROLLER_LOG_DUMP_ONLY - bool "Controller log dump mode only" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default y - help + config BT_LE_CONTROLLER_LOG_DUMP_ONLY + bool "Controller log dump mode only" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default y + help Only operate in dump mode -config BT_LE_LOG_CTRL_BUF1_SIZE - int "size of the first BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + bool "Output ble controller logs to SPI bus (Experimental)" + depends on BT_LE_CONTROLLER_LOG_ENABLED + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + select BT_BLE_LOG_SPI_OUT_ENABLED + default n + help + Output ble controller logs to SPI bus + + config BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + bool "Store ble controller logs to flash(Experimental)" + depends on !BT_LE_CONTROLLER_LOG_DUMP_ONLY + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Store ble controller logs to flash memory. + + config BT_LE_CONTROLLER_LOG_PARTITION_SIZE + int "size of ble controller log partition(Multiples of 4K)" + depends on BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + default 65536 + help + The size of ble controller log partition shall be a multiples of 4K. + The name of log partition shall be "bt_ctrl_log". + The partition type shall be ESP_PARTITION_TYPE_DATA. + The partition sub_type shall be ESP_PARTITION_SUBTYPE_ANY. + + config BT_LE_LOG_CTRL_BUF1_SIZE + int "size of the first BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the first BLE controller LOG buffer. -config BT_LE_LOG_CTRL_BUF2_SIZE - int "size of the second BLE controller LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 1024 - help + config BT_LE_LOG_CTRL_BUF2_SIZE + int "size of the second BLE controller LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 1024 + help Configure the size of the second BLE controller LOG buffer. -config BT_LE_LOG_HCI_BUF_SIZE - int "size of the BLE HCI LOG buffer" - depends on BT_LE_CONTROLLER_LOG_ENABLED - default 4096 - help + config BT_LE_LOG_HCI_BUF_SIZE + int "size of the BLE HCI LOG buffer" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default 4096 + help Configure the size of the BLE HCI LOG buffer. + config BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE + bool "Enable wrap panic handler" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Wrap esp_panic_handler to get controller logs when PC pointer exception crashes. + + config BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + bool "Enable esp_task_wdt_isr_user_handler implementation" + depends on BT_LE_CONTROLLER_LOG_ENABLED + default n + help + Implement esp_task_wdt_isr_user_handler to get controller logs when task wdt issue is triggered. + + config BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL + int "The output level of controller log" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 5 + default 1 + help + The output level of controller log. + + config BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH + hex "The switch of module log output" + depends on BT_LE_CONTROLLER_LOG_ENABLED + range 0 0xFFFFFFFF + default 0xFFFFFFFF + help + The switch of module log output, this is an unsigned 32-bit hexadecimal value. + + config BT_LE_ERROR_SIM_ENABLED + bool "Enable controller features for internal testing" + default n + + config BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + bool "When ACL disconnects abnormally, assertion processing is performed(Experimental)" + default n + + config BT_LE_DEBUG_REMAIN_SCENE_ENABLED + bool "Remain scene with GDB to capture relevant status info(Experimental)" + default n + help + Retain scene with GDB to capture info, requires disabling WDT (CONFIG_ESP_INT_WDT, CONFIG_ESP_TASK_WDT_EN). + + config BT_LE_PTR_CHECK_ENABLED + bool "Enable boundary check for internal memory" + default n +endmenu + config BT_LE_LL_RESOLV_LIST_SIZE int "BLE LL Resolving list size" range 1 5 @@ -363,7 +498,7 @@ config BT_LE_CRYPTO_STACK_MBEDTLS config BT_LE_WHITELIST_SIZE int "BLE white list size" - range 1 15 + range 1 31 default 12 depends on !BT_NIMBLE_ENABLED @@ -384,6 +519,23 @@ config BT_LE_LL_SCA help Sleep clock accuracy of our device (in ppm) +config BT_LE_LL_PEER_SCA_SET_ENABLE + bool "Enable to set constant peer SCA" + default n + help + Enable setting of constant peer SCA, use this if peer device has SCA larger than 500 PPM. + Enable this option, the controller will always use BT_LE_LL_PEER_SCA as the peer SCA value + to calculate the window widening instead of the value received from peer device. + + +config BT_LE_LL_PEER_SCA + int "Constant peer sleep clock accuracy value" + range 0 10000 + depends on BT_LE_LL_PEER_SCA_SET_ENABLE + default 0 + help + Set the sleep clock accuracy of peer device + config BT_LE_MAX_CONNECTIONS int "Maximum number of concurrent connections" depends on !BT_NIMBLE_ENABLED @@ -551,7 +703,7 @@ config BT_LE_SCAN_DUPL_CACHE_REFRESH_PERIOD again. config BT_LE_MSYS_INIT_IN_CONTROLLER - bool + bool "Msys Mbuf Init in Controller" default y config BT_LE_TX_CCA_ENABLED @@ -564,6 +716,137 @@ config BT_LE_CCA_RSSI_THRESH int "CCA RSSI threshold value" depends on BT_LE_TX_CCA_ENABLED range 20 100 - default 20 + default 65 help Power threshold of CCA in unit of -1 dBm. + +choice BT_LE_DFT_TX_POWER_LEVEL_DBM + prompt "BLE default Tx power level(dBm)" + default BT_LE_DFT_TX_POWER_LEVEL_P9 + help + Specify default Tx power level(dBm). + config BT_LE_DFT_TX_POWER_LEVEL_N24 + bool "-24dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N21 + bool "-21dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N18 + bool "-18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N15 + bool "-15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N12 + bool "-12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N9 + bool "-9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N6 + bool "-6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N3 + bool "-3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_N0 + bool "0dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P3 + bool "+3dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P6 + bool "+6dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P9 + bool "+9dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P12 + bool "+12dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P15 + bool "+15dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P18 + bool "+18dBm" + config BT_LE_DFT_TX_POWER_LEVEL_P20 + bool "+20dBm" +endchoice + +config BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF + int + default -24 if BT_LE_DFT_TX_POWER_LEVEL_N24 + default -21 if BT_LE_DFT_TX_POWER_LEVEL_N21 + default -18 if BT_LE_DFT_TX_POWER_LEVEL_N18 + default -15 if BT_LE_DFT_TX_POWER_LEVEL_N15 + default -12 if BT_LE_DFT_TX_POWER_LEVEL_N12 + default -9 if BT_LE_DFT_TX_POWER_LEVEL_N9 + default -6 if BT_LE_DFT_TX_POWER_LEVEL_N6 + default -3 if BT_LE_DFT_TX_POWER_LEVEL_N3 + default 0 if BT_LE_DFT_TX_POWER_LEVEL_N0 + default 3 if BT_LE_DFT_TX_POWER_LEVEL_P3 + default 6 if BT_LE_DFT_TX_POWER_LEVEL_P6 + default 9 if BT_LE_DFT_TX_POWER_LEVEL_P9 + default 12 if BT_LE_DFT_TX_POWER_LEVEL_P12 + default 15 if BT_LE_DFT_TX_POWER_LEVEL_P15 + default 18 if BT_LE_DFT_TX_POWER_LEVEL_P18 + default 20 if BT_LE_DFT_TX_POWER_LEVEL_P20 + default 0 + +config BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS + bool "Enable enhanced Access Address check in CONNECT_IND" + default n + help + Enabling this option will add stricter verification of the Access Address in the CONNECT_IND PDU. + This improves security by ensuring that only connection requests with valid Access Addresses are accepted. + If disabled, only basic checks are applied, improving compatibility. + +config BT_CTRL_RUN_IN_FLASH_ONLY + bool "Reduce BLE IRAM usage (READ DOCS FIRST) (EXPERIMENTAL)" + default n + help + Move most IRAM into flash. This will increase the usage of flash and reduce ble performance. + Because the code is moved to the flash, the execution speed of the code is reduced. + To have a small impact on performance, you need to enable flash suspend (SPI_FLASH_AUTO_SUSPEND). + +menu "BLE disconnects when Instant Passed (0x28) occurs" + config BT_LE_CTRL_LLCP_CONN_UPDATE + bool "BLE ACL connection update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs during connection update procedure. + + config BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE + bool "BLE ACL channel map update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in channel map update procedure. + + config BT_LE_CTRL_LLCP_PHY_UPDATE + bool "BLE ACL PHY update procedure" + default n + help + If this option is enabled, Controller will terminate the connection + when Instant Passed (0x28) error occurs in PHY update procedure. +endmenu + +config BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX + int "The value of upperlimitmax during scan backoff procedure" + range 1 256 + default 32 + help + The value of upperlimitmax needs to be a power of 2. + +config BT_LE_CTRL_CHAN_ASS_EN + bool "Enable channel assessment(Experimental)" + default n + help + If this option is enabled, The Controller will records the communication quality + for each channel and then start a timer to check and update the channel map every 4 seconds. + +config BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX + bool "Enable aux packet when ext adv data length is zero(Experimental)" + default y + help + When this option is enabled, auxiliary packets will be present in the events of + 'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0. + If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0. + +config BT_LE_RXBUF_OPT_ENABLED + bool "Enable rxbuf optimization feature" + default y + +config BT_LE_CTRL_FAST_CONN_DATA_TX_EN + bool "Enable fast sending of connection data" + default y + help + If this option is enabled, The Controller will continue to + Send an empty PDU after sending valid connection data within an interval. diff --git a/lib/bt/controller/esp32h2/ble.c b/lib/bt/controller/esp32h2/ble.c new file mode 100644 index 00000000..8aef45a9 --- /dev/null +++ b/lib/bt/controller/esp32h2/ble.c @@ -0,0 +1,165 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include <stdlib.h> + +#include "sdkconfig.h" +#include "esp_bt_cfg.h" +#include "esp_bit_defs.h" + +/* External functions or variables + ************************************************************************ + */ +int base_stack_initEnv(void); +void base_stack_deinitEnv(void); +int base_stack_enable(void); +void base_stack_disable(void); + +int conn_stack_initEnv(void); +void conn_stack_deinitEnv(void); +int conn_stack_enable(void); +void conn_stack_disable(void); + +#if CONFIG_BT_LE_ERROR_SIM_ENABLED +int conn_errorSim_initEnv(void); +void conn_errorSim_deinitEnv(void); +int conn_errorSim_enable(void); +void conn_errorSim_disable(void); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void adv_stack_enableClearLegacyAdvVsCmd(bool en); +void scan_stack_enableAdvFlowCtrlVsCmd(bool en); +void advFilter_stack_enableDupExcListVsCmd(bool en); +void arr_stack_enableMultiConnVsCmd(bool en); +void pcl_stack_enableSetRssiThreshVsCmd(bool en); +void chanSel_stack_enableSetCsaVsCmd(bool en); +void log_stack_enableLogsRelatedVsCmd(bool en); +void hci_stack_enableSetVsEvtMaskVsCmd(bool en); +void winWiden_stack_enableSetConstPeerScaVsCmd(bool en); + +void adv_stack_enableScanReqRxdVsEvent(bool en); +void conn_stack_enableChanMapUpdCompVsEvent(bool en); +void sleep_stack_enableWakeupVsEvent(bool en); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED +extern void mmgmt_enableRxbufOptFeature(void); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + +/* Local functions definition + *************************************************************************** + */ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) +void ble_stack_enableVsCmds(bool en) +{ + adv_stack_enableClearLegacyAdvVsCmd(en); + advFilter_stack_enableDupExcListVsCmd(en); + scan_stack_enableAdvFlowCtrlVsCmd(en); + arr_stack_enableMultiConnVsCmd(en); + pcl_stack_enableSetRssiThreshVsCmd(en); + chanSel_stack_enableSetCsaVsCmd(en); + log_stack_enableLogsRelatedVsCmd(en); + hci_stack_enableSetVsEvtMaskVsCmd(en); + winWiden_stack_enableSetConstPeerScaVsCmd(en); +} + +void ble_stack_enableVsEvents(bool en) +{ + adv_stack_enableScanReqRxdVsEvent(en); + conn_stack_enableChanMapUpdCompVsEvent(en); + +#if CONFIG_BT_LE_SLEEP_ENABLE + sleep_stack_enableWakeupVsEvent(en); +#endif // CONFIG_BT_LE_SLEEP_ENABLE +} +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +int ble_stack_initEnv(void) +{ + int rc; + + rc = base_stack_initEnv(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_initEnv(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_initEnv(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + return 0; +} + +void ble_stack_deinitEnv(void) +{ +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_deinitEnv(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_deinitEnv(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_deinitEnv(); +} + +int ble_stack_enable(void) +{ + int rc; + + rc = base_stack_enable(); + if (rc) { + return rc; + } + +#if DEFAULT_BT_LE_MAX_CONNECTIONS + rc = conn_stack_enable(); + if (rc) { + return rc; + } +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + rc = conn_errorSim_enable(); + if (rc) { + return rc; + } +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsCmds(true); + ble_stack_enableVsEvents(true); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if CONFIG_BT_LE_RXBUF_OPT_ENABLED + mmgmt_enableRxbufOptFeature(); +#endif // CONFIG_BT_LE_RXBUF_OPT_ENABLED + + return 0; +} + +void ble_stack_disable(void) +{ +#if (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + ble_stack_enableVsEvents(false); + ble_stack_enableVsCmds(false); +#endif // (CONFIG_BT_NIMBLE_ENABLED || CONFIG_BT_BLUEDROID_ENABLED) + +#if DEFAULT_BT_LE_MAX_CONNECTIONS +#if CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_errorSim_disable(); +#endif // CONFIG_BT_LE_ERROR_SIM_ENABLED + conn_stack_disable(); +#endif // DEFAULT_BT_LE_MAX_CONNECTIONS + + base_stack_disable(); +} diff --git a/lib/bt/controller/esp32h2/ble_priv.h b/lib/bt/controller/esp32h2/ble_priv.h new file mode 100644 index 00000000..82dc4d16 --- /dev/null +++ b/lib/bt/controller/esp32h2/ble_priv.h @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +int ble_stack_initEnv(void); + +void ble_stack_deinitEnv(void); + +int ble_stack_enable(void); + +void ble_stack_disable(void); diff --git a/lib/bt/controller/esp32h2/bt.c b/lib/bt/controller/esp32h2/bt.c index adb10d49..2c564b91 100644 --- a/lib/bt/controller/esp32h2/bt.c +++ b/lib/bt/controller/esp32h2/bt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -30,16 +30,16 @@ #endif // CONFIG_ESP_COEX_ENABLED #include "nimble/nimble_npl_os.h" -#include "ble_hci_trans.h" +#include "esp_hci_transport.h" #include "os/endian.h" #include "esp_bt.h" +#include "ble_priv.h" #include "esp_intr_alloc.h" #include "esp_sleep.h" #include "esp_pm.h" #include "esp_phy_init.h" #include "esp_private/periph_ctrl.h" -#include "hci_uart.h" #include "bt_osi_mem.h" #if CONFIG_FREERTOS_USE_TICKLESS_IDLE @@ -47,16 +47,18 @@ #include "esp_private/sleep_retention.h" #endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE -#ifdef CONFIG_BT_BLUEDROID_ENABLED -#include "hci/hci_hal.h" -#endif // CONFIG_BT_BLUEDROID_ENABLED - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_private/periph_ctrl.h" +#include "esp_private/esp_clk_tree_common.h" #include "esp_sleep.h" #include "soc/rtc.h" + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#include "ble_log/ble_log_spi_out.h" +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + /* Macro definition ************************************************************************ */ @@ -64,16 +66,11 @@ #define OSI_COEX_VERSION 0x00010006 #define OSI_COEX_MAGIC_VALUE 0xFADEBEAD -#define EXT_FUNC_VERSION 0x20221122 +#define EXT_FUNC_VERSION 0x20250415 #define EXT_FUNC_MAGIC_VALUE 0xA5A5A5A5 #define BT_ASSERT_PRINT ets_printf -#ifdef CONFIG_BT_BLUEDROID_ENABLED -/* ACL_DATA_MBUF_LEADINGSPCAE: The leadingspace in user info header for ACL data */ -#define ACL_DATA_MBUF_LEADINGSPCAE 4 -#endif // CONFIG_BT_BLUEDROID_ENABLED - /* Types definition ************************************************************************ */ @@ -92,12 +89,6 @@ struct ext_funcs_t { int (*_esp_intr_free)(void **ret_handle); void *(* _malloc)(size_t size); void (*_free)(void *p); - void (*_hal_uart_start_tx)(int); - int (*_hal_uart_init_cbs)(int, hci_uart_tx_char, hci_uart_tx_done, hci_uart_rx_char, void *); - int (*_hal_uart_config)(int, int32_t, uint8_t, uint8_t, uart_parity_t, uart_hw_flowcontrol_t); - int (*_hal_uart_close)(int); - void (*_hal_uart_blocking_tx)(int, uint8_t); - int (*_hal_uart_init)(int, void *); int (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); void (* _task_delete)(void *task_handle); @@ -106,24 +97,33 @@ struct ext_funcs_t { int (* _ecc_gen_key_pair)(uint8_t *public, uint8_t *priv); int (* _ecc_gen_dh_key)(const uint8_t *remote_pub_key_x, const uint8_t *remote_pub_key_y, const uint8_t *local_priv_key, uint8_t *dhkey); - void (* _esp_reset_rpa_moudle)(void); uint32_t magic; }; #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -typedef void (*interface_func_t) (uint32_t len, const uint8_t*addr, bool end); +typedef void (*interface_func_t) (uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); + +enum { + BLE_LOG_INTERFACE_FLAG_CONTINUE = 0, + BLE_LOG_INTERFACE_FLAG_END, +}; #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* External functions or variables ************************************************************************ */ extern int ble_osi_coex_funcs_register(struct osi_coex_funcs_t *coex_funcs); extern int r_ble_controller_init(esp_bt_controller_config_t *cfg); +extern void esp_ble_controller_info_capture(uint32_t cycle_times); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -extern int r_ble_log_init_async(interface_func_t bt_controller_log_interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); +extern int r_ble_log_init_async(interface_func_t interface, bool task_create, uint8_t buffers, uint32_t *bufs_size); extern int r_ble_log_deinit_async(void); +extern int r_ble_log_init_simple(interface_func_t interface, void *handler); +extern void r_ble_log_deinit_simple(void); extern void r_ble_log_async_select_dump_buffers(uint8_t buffers); extern void r_ble_log_async_output_dump_all(bool output); -extern void esp_panic_handler_reconfigure_wdts(uint32_t timeout_ms); +extern void esp_panic_handler_feed_wdts(void); +extern int r_ble_log_ctrl_level_and_mod(uint8_t log_level, uint32_t mod_switch); +extern int r_ble_ctrl_mod_type(uint16_t mod, uint32_t mod_type_switch); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED extern int r_ble_controller_deinit(void); extern int r_ble_controller_enable(uint8_t mode); @@ -141,11 +141,20 @@ extern void r_ble_lll_rfmgmt_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, extern void r_ble_rtc_wake_up_state_clr(void); extern int os_msys_init(void); extern void os_msys_deinit(void); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY +extern void r_ble_ll_scan_start_time_init_compensation(uint32_t init_compensation); +extern void r_priv_sdk_config_insert_proc_time_set(uint16_t insert_proc_time); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY #if CONFIG_FREERTOS_USE_TICKLESS_IDLE -extern const sleep_retention_entries_config_t *esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); +extern sleep_retention_entries_config_t *r_esp_ble_mac_retention_link_get(uint8_t *size, uint8_t extra); extern void r_esp_ble_set_wakeup_overhead(uint32_t overhead); #endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ -extern void r_esp_ble_change_rtc_freq(uint32_t freq); +#if CONFIG_PM_ENABLE +extern void r_esp_ble_stop_wakeup_timing(void); +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE +extern void r_ble_ll_customize_peer_sca_set(uint16_t peer_sca); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE extern int ble_sm_alg_gen_dhkey(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); @@ -173,27 +182,21 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status); static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id); static void task_delete_wrapper(void *task_handle); -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no); -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg); -static int hci_uart_config_wrapper(int uart_no, int32_t speed, uint8_t databits, uint8_t stopbits, - uart_parity_t parity, uart_hw_flowcontrol_t flow_ctl); -static int hci_uart_close_wrapper(int uart_no); -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data); -static int hci_uart_init_wrapper(int uart_no, void *cfg); -#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in); static int esp_intr_free_wrapper(void **ret_handle); static void osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2); static uint32_t osi_random_wrapper(void); -static void esp_reset_rpa_moudle(void); static int esp_ecc_gen_key_pair(uint8_t *pub, uint8_t *priv); static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end); +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag); +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* Local variable definition *************************************************************************** @@ -203,14 +206,238 @@ static DRAM_ATTR esp_bt_controller_status_t ble_controller_status = ESP_BT_CONTR #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED const static uint32_t log_bufs_size[] = {CONFIG_BT_LE_LOG_CTRL_BUF1_SIZE, CONFIG_BT_LE_LOG_HCI_BUF_SIZE, CONFIG_BT_LE_LOG_CTRL_BUF2_SIZE}; +static bool log_is_inited = false; + +esp_err_t esp_bt_controller_log_init(void) +{ + if (log_is_inited) { + return ESP_OK; + } + +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + if (ble_log_spi_out_init() != 0) { + goto spi_out_init_failed; + } +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + if (r_ble_log_init_simple(ble_log_spi_out_ll_write, ble_log_spi_out_ll_log_ev_proc) != 0) { + goto log_init_failed; + } +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + uint8_t buffers = 0; +#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED + buffers |= ESP_BLE_LOG_BUF_CONTROLLER; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + buffers |= ESP_BLE_LOG_BUF_HCI; +#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED + + bool task_create = true; +#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY + task_create = false; +#elif CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_ctrl_log_partition_get_and_erase_first_block(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_init_async(esp_bt_controller_log_interface, task_create, buffers, (uint32_t *)log_bufs_size) != 0) { + goto log_init_failed; + } +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + if (r_ble_log_ctrl_level_and_mod(CONFIG_BT_LE_CONTROLLER_LOG_OUTPUT_LEVEL, CONFIG_BT_LE_CONTROLLER_LOG_MOD_OUTPUT_SWITCH) != ESP_OK) { + goto ctrl_level_init_failed; + } + log_is_inited = true; + return ESP_OK; + +ctrl_level_init_failed: +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +log_init_failed: +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +spi_out_init_failed: +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + return ESP_FAIL; +} + +void esp_bt_controller_log_deinit(void) +{ +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_deinit(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + +#if CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_simple(); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + r_ble_log_deinit_async(); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + + log_is_inited = false; +} + +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE +#include "esp_partition.h" +#include "hal/wdt_hal.h" + +#define MAX_STORAGE_SIZE (CONFIG_BT_LE_CONTROLLER_LOG_PARTITION_SIZE) +#define BLOCK_SIZE (4096) +#define THRESHOLD (3072) +#define PARTITION_NAME "bt_ctrl_log" + +static const esp_partition_t *log_partition; +static uint32_t write_index = 0; +static uint32_t next_erase_index = BLOCK_SIZE; +static bool block_erased = false; +static bool stop_write = false; +static bool is_filled = false; + +static void esp_bt_ctrl_log_partition_get_and_erase_first_block(void) +{ + log_partition = NULL; + assert(MAX_STORAGE_SIZE % BLOCK_SIZE == 0); + // Find the partition map in the partition table + log_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARTITION_NAME); + assert(log_partition != NULL); + // Prepare data to be read later using the mapped address + ESP_ERROR_CHECK(esp_partition_erase_range(log_partition, 0, BLOCK_SIZE)); + write_index = 0; + next_erase_index = BLOCK_SIZE; + block_erased = false; + is_filled = false; + stop_write = false; +} + +static int esp_bt_controller_log_storage(uint32_t len, const uint8_t *addr, bool end) +{ + if (len > MAX_STORAGE_SIZE) { + return -1; + } + + if (stop_write) { + return 0; + } + + if (((write_index) % BLOCK_SIZE) >= THRESHOLD && !block_erased) { + // esp_rom_printf("Ers nxt: %d,%d\n", next_erase_index, write_index); + esp_partition_erase_range(log_partition, next_erase_index, BLOCK_SIZE); + next_erase_index = (next_erase_index + BLOCK_SIZE) % MAX_STORAGE_SIZE; + block_erased = true; + } + + if (((write_index + len) / BLOCK_SIZE) > (write_index / BLOCK_SIZE)) { + block_erased = false; + } + + if (write_index + len <= MAX_STORAGE_SIZE) { + esp_partition_write(log_partition, write_index, addr, len); + write_index = (write_index + len) % MAX_STORAGE_SIZE; + } else { + uint32_t first_part_len = MAX_STORAGE_SIZE - write_index; + esp_partition_write(log_partition, write_index, addr, first_part_len); + esp_partition_write(log_partition, 0, addr + first_part_len, len - first_part_len); + write_index = len - first_part_len; + is_filled = true; + // esp_rom_printf("old idx: %d,%d\n",next_erase_index, write_index); + } + + return 0; +} + +void esp_bt_read_ctrl_log_from_flash(bool output) +{ + esp_partition_mmap_handle_t mmap_handle; + uint32_t read_index; + const void *mapped_ptr; + const uint8_t *buffer; + uint32_t print_len; + uint32_t max_print_len; + esp_err_t err; + + print_len = 0; + max_print_len = 4096; + err = esp_partition_mmap(log_partition, 0, MAX_STORAGE_SIZE, ESP_PARTITION_MMAP_DATA, &mapped_ptr, &mmap_handle); + if (err != ESP_OK) { + ESP_LOGE("FLASH", "Mmap failed: %s", esp_err_to_name(err)); + return; + } + + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + r_ble_log_async_output_dump_all(true); + esp_bt_controller_log_deinit(); + stop_write = true; + + buffer = (const uint8_t *)mapped_ptr; + esp_panic_handler_feed_wdts(); + if (is_filled) { + read_index = next_erase_index; + } else { + read_index = 0; + } + + esp_rom_printf("\r\nREAD_CHECK:%ld,%ld,%d\r\n",read_index, write_index, is_filled); + esp_rom_printf("\r\n[DUMP_START:"); + while (read_index != write_index) { + esp_rom_printf("%02x ", buffer[read_index]); + if (print_len > max_print_len) { + esp_panic_handler_feed_wdts(); + print_len = 0; + } + + print_len++; + read_index = (read_index + 1) % MAX_STORAGE_SIZE; + } + + esp_rom_printf(":DUMP_END]\r\n"); + portEXIT_CRITICAL_SAFE(&spinlock); + esp_partition_munmap(mmap_handle); + err = esp_bt_controller_log_init(); + assert(err == ESP_OK); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE +void esp_task_wdt_isr_user_handler(void) +{ + esp_ble_controller_log_dump_all(true); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_TASK_WDT_USER_HANDLER_ENABLE + +#if CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE +void __real_esp_panic_handler(void *info); +void __wrap_esp_panic_handler (void *info) +{ + esp_ble_controller_log_dump_all(true); + __real_esp_panic_handler(info); +} +#endif // CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED /* This variable tells if BLE is running */ static bool s_ble_active = false; #ifdef CONFIG_PM_ENABLE static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL; -#define BTDM_MIN_TIMER_UNCERTAINTY_US (200) #endif // CONFIG_PM_ENABLE +#define MAIN_XTAL_FREQ_HZ (32000000) +static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID; +static DRAM_ATTR uint32_t s_bt_lpclk_freq = 100000; + +#define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA) +void *malloc_ble_controller_mem(size_t size) +{ + return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS); +} + +uint32_t get_ble_controller_free_heap_size(void) +{ + return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS); +} #define BLE_RTC_DELAY_US_LIGHT_SLEEP (5100) #define BLE_RTC_DELAY_US_MODEM_SLEEP (1500) @@ -230,29 +457,15 @@ struct ext_funcs_t ext_funcs_ro = { ._esp_intr_free = esp_intr_free_wrapper, ._malloc = bt_osi_mem_malloc_internal, ._free = bt_osi_mem_free, -#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART - ._hal_uart_start_tx = hci_uart_start_tx_wrapper, - ._hal_uart_init_cbs = hci_uart_init_cbs_wrapper, - ._hal_uart_config = hci_uart_config_wrapper, - ._hal_uart_close = hci_uart_close_wrapper, - ._hal_uart_blocking_tx = hci_uart_blocking_tx_wrapper, - ._hal_uart_init = hci_uart_init_wrapper, -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART ._task_create = task_create_wrapper, ._task_delete = task_delete_wrapper, ._osi_assert = osi_assert_wrapper, ._os_random = osi_random_wrapper, ._ecc_gen_key_pair = esp_ecc_gen_key_pair, ._ecc_gen_dh_key = esp_ecc_gen_dh_key, - ._esp_reset_rpa_moudle = esp_reset_rpa_moudle, .magic = EXT_FUNC_MAGIC_VALUE, }; -static void IRAM_ATTR esp_reset_rpa_moudle(void) -{ - -} - static void IRAM_ATTR osi_assert_wrapper(const uint32_t ln, const char *fn, uint32_t param1, uint32_t param2) { @@ -282,75 +495,6 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status) #endif // CONFIG_SW_COEXIST_ENABLE } -#ifdef CONFIG_BT_BLUEDROID_ENABLED -bool esp_vhci_host_check_send_available(void) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return false; - } - return true; -} - -static struct os_mbuf *ble_hs_mbuf_gen_pkt(uint16_t leading_space) -{ - struct os_mbuf *om; - int rc; - - om = os_msys_get_pkthdr(0, 0); - if (om == NULL) { - return NULL; - } - - if (om->om_omp->omp_databuf_len < leading_space) { - rc = os_mbuf_free_chain(om); - assert(rc == 0); - return NULL; - } - - om->om_data += leading_space; - - return om; -} - -struct os_mbuf *ble_hs_mbuf_acl_pkt(void) -{ - return ble_hs_mbuf_gen_pkt(4 + 1); -} - -void esp_vhci_host_send_packet(uint8_t *data, uint16_t len) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return; - } - - if (*(data) == DATA_TYPE_COMMAND) { - struct ble_hci_cmd *cmd = NULL; - cmd = (struct ble_hci_cmd *) ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); - assert(cmd); - memcpy((uint8_t *)cmd, data + 1, len - 1); - ble_hci_trans_hs_cmd_tx((uint8_t *)cmd); - } - - if (*(data) == DATA_TYPE_ACL) { - struct os_mbuf *om = os_msys_get_pkthdr(len, ACL_DATA_MBUF_LEADINGSPCAE); - assert(om); - assert(os_mbuf_append(om, &data[1], len - 1) == 0); - ble_hci_trans_hs_acl_tx(om); - } -} - -esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback) -{ - if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) { - return ESP_FAIL; - } - - ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL); - - return ESP_OK; -} -#endif // CONFIG_BT_BLUEDROID_ENABLED - static int task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id) { @@ -382,61 +526,14 @@ static int esp_ecc_gen_dh_key(const uint8_t *peer_pub_key_x, const uint8_t *peer return rc; } -#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART -static void hci_uart_start_tx_wrapper(int uart_no) -{ - hci_uart_start_tx(uart_no); -} - -static int hci_uart_init_cbs_wrapper(int uart_no, hci_uart_tx_char tx_func, - hci_uart_tx_done tx_done, hci_uart_rx_char rx_func, void *arg) -{ - int rc = -1; - rc = hci_uart_init_cbs(uart_no, tx_func, tx_done, rx_func, arg); - return rc; -} - - -static int hci_uart_config_wrapper(int port_num, int32_t baud_rate, uint8_t data_bits, - uint8_t stop_bits, uart_parity_t parity, - uart_hw_flowcontrol_t flow_ctl) -{ - int rc = -1; - rc = hci_uart_config(port_num, baud_rate, data_bits, stop_bits, parity, flow_ctl); - return rc; -} - -static int hci_uart_close_wrapper(int uart_no) -{ - int rc = -1; - rc = hci_uart_close(uart_no); - return rc; -} - -static void hci_uart_blocking_tx_wrapper(int port, uint8_t data) -{ - //This function is nowhere to use. -} - -static int hci_uart_init_wrapper(int uart_no, void *cfg) -{ - //This function is nowhere to use. - return 0; -} - -#endif //CONFIG_BT_LE_HCI_INTERFACE_USE_UART - -static int ble_hci_unregistered_hook(void*, void*) -{ - ESP_LOGD(NIMBLE_PORT_LOG_TAG,"%s ble hci rx_evt is not registered.",__func__); - return 0; -} - static int esp_intr_alloc_wrapper(int source, int flags, intr_handler_t handler, void *arg, void **ret_handle_in) { - int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, - arg, (intr_handle_t *)ret_handle_in); +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + int rc = esp_intr_alloc(source, flags, handler, arg, (intr_handle_t *)ret_handle_in); +#else + int rc = esp_intr_alloc(source, flags | ESP_INTR_FLAG_IRAM, handler, arg, (intr_handle_t *)ret_handle_in); +#endif return rc; } @@ -454,10 +551,10 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) switch (slow_clk_src) { case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL: ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using main XTAL as clock source"); - modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (320 - 1)); + modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (MAIN_XTAL_FREQ_HZ/s_bt_lpclk_freq - 1)); break; case MODEM_CLOCK_LPCLK_SRC_RC_SLOW: - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, can only run legacy ADV or SCAN due to low clock accuracy!"); + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Using 136 kHz RC as clock source, use with caution as it may not maintain ACL or Sync process due to low clock accuracy!"); modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (5 - 1)); break; case MODEM_CLOCK_LPCLK_SRC_XTAL32K: @@ -476,6 +573,46 @@ void esp_bt_rtc_slow_clk_select(uint8_t slow_clk_src) } } +modem_clock_lpclk_src_t esp_bt_get_lpclk_src(void) +{ + return s_bt_lpclk_src; +} + +void esp_bt_set_lpclk_src(modem_clock_lpclk_src_t clk_src) +{ + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + + if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX) { + return; + } + + s_bt_lpclk_src = clk_src; +} + +uint32_t esp_bt_get_lpclk_freq(void) +{ + return s_bt_lpclk_freq; +} + +void esp_bt_set_lpclk_freq(uint32_t clk_freq) +{ + if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { + return; + } + + if (!clk_freq) { + return; + } + + if (MAIN_XTAL_FREQ_HZ % clk_freq) { + return; + } + + s_bt_lpclk_freq = clk_freq; +} + IRAM_ATTR void controller_sleep_cb(uint32_t enable_tick, void *arg) { if (!s_ble_active) { @@ -497,10 +634,17 @@ IRAM_ATTR void controller_wakeup_cb(void *arg) return; } #ifdef CONFIG_PM_ENABLE + esp_pm_config_t pm_config; esp_pm_lock_acquire(s_pm_lock); + esp_pm_get_configuration(&pm_config); + assert(esp_rom_get_cpu_ticks_per_us() == pm_config.max_freq_mhz); r_ble_rtc_wake_up_state_clr(); #endif //CONFIG_PM_ENABLE esp_phy_enable(PHY_MODEM_BT); + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + uint32_t *clk_freq = (uint32_t *)arg; + *clk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + } s_ble_active = true; } @@ -509,7 +653,7 @@ static esp_err_t sleep_modem_ble_mac_retention_init(void *arg) { uint8_t size; int extra = *(int *)arg; - const sleep_retention_entries_config_t *ble_mac_modem_config = esp_ble_mac_retention_link_get(&size, extra); + sleep_retention_entries_config_t *ble_mac_modem_config = r_esp_ble_mac_retention_link_get(&size, extra); esp_err_t err = sleep_retention_entries_create(ble_mac_modem_config, size, REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BLE_MAC); if (err == ESP_OK) { ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Modem BLE MAC retention initialization"); @@ -522,7 +666,7 @@ static esp_err_t sleep_modem_ble_mac_modem_state_init(uint8_t extra) int retention_args = extra; sleep_retention_module_init_param_t init_param = { .cbs = { .create = { .handle = sleep_modem_ble_mac_retention_init, .arg = &retention_args } }, - .depends = BIT(SLEEP_RETENTION_MODULE_BT_BB) + .depends = RETENTION_MODULE_BITMAP_INIT(BT_BB) }; esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_BLE_MAC, &init_param); if (err == ESP_OK) { @@ -540,7 +684,7 @@ static void sleep_modem_ble_mac_modem_state_deinit(void) } } -void sleep_modem_light_sleep_overhead_set(uint32_t overhead) +void IRAM_ATTR sleep_modem_light_sleep_overhead_set(uint32_t overhead) { r_esp_ble_set_wakeup_overhead(overhead); } @@ -567,10 +711,17 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE + rc = esp_deep_sleep_register_hook(&r_esp_ble_stop_wakeup_timing); + if (rc != ESP_OK) { + goto error; + } +#endif //CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE /* Create a new regdma link for BLE related register restoration */ rc = sleep_modem_ble_mac_modem_state_init(0); - assert(rc == 0); + if (rc != ESP_OK) { + goto error; + } esp_sleep_enable_bt_wakeup(); ESP_LOGW(NIMBLE_PORT_LOG_TAG, "Enable light sleep, the wake up source is BLE timer"); @@ -578,15 +729,18 @@ esp_err_t controller_sleep_init(void) if (rc != ESP_OK) { goto error; } -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ return rc; +#ifdef CONFIG_PM_ENABLE error: - -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#endif // CONFIG_PM_ENABLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE esp_sleep_disable_bt_wakeup(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#ifdef CONFIG_PM_ENABLE + esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing); /*lock should release first and then delete*/ if (s_pm_lock != NULL) { esp_pm_lock_delete(s_pm_lock); @@ -599,13 +753,14 @@ error: void controller_sleep_deinit(void) { -#if CONFIG_FREERTOS_USE_TICKLESS_IDLE +#if CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE r_ble_rtc_wake_up_state_clr(); esp_sleep_disable_bt_wakeup(); sleep_modem_ble_mac_modem_state_deinit(); esp_pm_unregister_inform_out_light_sleep_overhead_callback(sleep_modem_light_sleep_overhead_set); -#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */ +#endif /* CONFIG_BT_LE_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */ #ifdef CONFIG_PM_ENABLE + esp_deep_sleep_deregister_hook(&r_esp_ble_stop_wakeup_timing); /* lock should be released first */ esp_pm_lock_delete(s_pm_lock); s_pm_lock = NULL; @@ -683,12 +838,53 @@ void ble_controller_scan_duplicate_config(void) ble_vhci_disc_duplicate_set_max_cache_size(cache_size); } +static void ble_rtc_clk_init(esp_bt_controller_config_t *cfg) +{ + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_INVALID) { +#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; +#else +#if CONFIG_RTC_CLK_SRC_INT_RC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW; +#elif CONFIG_RTC_CLK_SRC_EXT_CRYS + if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K; + } else { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL; + } +#elif CONFIG_RTC_CLK_SRC_INT_RC32K + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K; +#elif CONFIG_RTC_CLK_SRC_EXT_OSC + s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K; +#else + ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); + assert(0); +#endif +#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + } + + if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) { + cfg->rtc_freq = s_bt_lpclk_freq; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_XTAL32K) { + cfg->rtc_freq = 32768; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC_SLOW) { + cfg->rtc_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5; + cfg->ble_ll_sca = 3000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_RC32K) { + cfg->rtc_freq = 32000; + } else if (s_bt_lpclk_src == MODEM_CLOCK_LPCLK_SRC_EXT32K) { + cfg->rtc_freq = 32000; + } + esp_bt_rtc_slow_clk_select(s_bt_lpclk_src); +} + esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) { uint8_t mac[6]; esp_err_t ret = ESP_OK; ble_npl_count_info_t npl_info; - uint32_t slow_clk_freq = 0; + uint8_t hci_transport_mode; memset(&npl_info, 0, sizeof(ble_npl_count_info_t)); if (ble_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) { @@ -739,33 +935,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) modem_clock_module_enable(PERIPH_BT_MODULE); modem_clock_module_mac_reset(PERIPH_BT_MODULE); /* Select slow clock source for BT momdule */ -#if CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; -#else -#if CONFIG_RTC_CLK_SRC_INT_RC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC_SLOW); - slow_clk_freq = 30000; -#elif CONFIG_RTC_CLK_SRC_EXT_CRYS - if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) { - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_XTAL32K); - slow_clk_freq = 32768; - } else { - ESP_LOGW(NIMBLE_PORT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock"); - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL); - slow_clk_freq = 100000; - } -#elif CONFIG_RTC_CLK_SRC_INT_RC32K - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_RC32K); - slow_clk_freq = 32000; -#elif CONFIG_RTC_CLK_SRC_EXT_OSC - esp_bt_rtc_slow_clk_select(MODEM_CLOCK_LPCLK_SRC_EXT32K); - slow_clk_freq = 32000; -#else - ESP_LOGE(NIMBLE_PORT_LOG_TAG, "Unsupported clock source"); - assert(0); -#endif -#endif /* CONFIG_BT_LE_LP_CLK_SRC_MAIN_XTAL */ + ble_rtc_clk_init(cfg); if (ble_osi_coex_funcs_register((struct osi_coex_funcs_t *)&s_osi_coex_funcs_ro) != 0) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "osi coex funcs reg failed"); @@ -778,20 +948,7 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) #endif // CONFIG_SW_COEXIST_ENABLE #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - interface_func_t bt_controller_log_interface; - bt_controller_log_interface = esp_bt_controller_log_interface; - uint8_t buffers = 0; -#if CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED - buffers |= ESP_BLE_LOG_BUF_CONTROLLER; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_CTRL_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED - buffers |= ESP_BLE_LOG_BUF_HCI; -#endif // CONFIG_BT_LE_CONTROLLER_LOG_HCI_ENABLED -#if CONFIG_BT_LE_CONTROLLER_LOG_DUMP_ONLY - ret = r_ble_log_init_async(bt_controller_log_interface, false, buffers, (uint32_t *)log_bufs_size); -#else - ret = r_ble_log_init_async(bt_controller_log_interface, true, buffers, (uint32_t *)log_bufs_size); -#endif // CONFIG_BT_CONTROLLER_LOG_DUMP + ret = esp_bt_controller_log_init(); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_controller_log_init failed %d", ret); goto modem_deint; @@ -803,14 +960,23 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) goto modem_deint; } + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); + ret = r_ble_controller_init(cfg); if (ret != ESP_OK) { ESP_LOGW(NIMBLE_PORT_LOG_TAG, "r_ble_controller_init failed %d", ret); goto modem_deint; } - ESP_LOGI(NIMBLE_PORT_LOG_TAG, "ble controller commit:[%s]", ble_controller_get_compile_version()); - r_esp_ble_change_rtc_freq(slow_clk_freq); +#if CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + r_ble_ll_customize_peer_sca_set(CONFIG_BT_LE_LL_PEER_SCA); +#endif // CONFIG_BT_LE_LL_PEER_SCA_SET_ENABLE + + ret = ble_stack_initEnv(); + if (ret != ESP_OK) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "ble_stack_initEnv failed %d", ret); + goto free_controller; + } ble_controller_scan_duplicate_config(); @@ -825,24 +991,40 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg) ESP_LOGW(NIMBLE_PORT_LOG_TAG, "controller_sleep_init failed %d", ret); goto free_controller; } + ESP_ERROR_CHECK(esp_read_mac((uint8_t *)mac, ESP_MAC_BT)); + ESP_LOGI(NIMBLE_PORT_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); swap_in_place(mac, 6); r_esp_ble_ll_set_public_addr(mac); ble_controller_status = ESP_BT_CONTROLLER_STATUS_INITED; - ble_hci_trans_cfg_hs((ble_hci_trans_rx_cmd_fn *)ble_hci_unregistered_hook,NULL, - (ble_hci_trans_rx_acl_fn *)ble_hci_unregistered_hook,NULL); - return ESP_OK; +#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + hci_transport_mode = HCI_TRANSPORT_VHCI; +#elif CONFIG_BT_LE_HCI_INTERFACE_USE_UART + hci_transport_mode = HCI_TRANSPORT_UART_NO_DMA; +#if CONFIG_BT_LE_UART_HCI_DMA_MODE + hci_transport_mode = HCI_TRANSPORT_UART_UHCI; +#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE +#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM + ret = hci_transport_init(hci_transport_mode); + if (ret) { + ESP_LOGW(NIMBLE_PORT_LOG_TAG, "hci transport init failed %d", ret); + goto free_controller; + } + return ESP_OK; free_controller: + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); + ble_stack_deinitEnv(); r_ble_controller_deinit(); modem_deint: esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); @@ -865,6 +1047,7 @@ esp_err_t esp_bt_controller_deinit(void) return ESP_FAIL; } + hci_transport_deinit(); controller_sleep_deinit(); os_msys_deinit(); @@ -872,10 +1055,11 @@ esp_err_t esp_bt_controller_deinit(void) modem_clock_deselect_lp_clock_source(PERIPH_BT_MODULE); modem_clock_module_disable(PERIPH_BT_MODULE); + ble_stack_deinitEnv(); r_ble_controller_deinit(); esp_ble_unregister_bb_funcs(); #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED - r_ble_log_deinit_async(); + esp_bt_controller_log_deinit(); #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED #if CONFIG_BT_NIMBLE_ENABLED @@ -921,6 +1105,16 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) coex_enable(); #endif // CONFIG_SW_COEXIST_ENABLE +#if CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + r_ble_ll_scan_start_time_init_compensation(500); + r_priv_sdk_config_insert_proc_time_set(500); +#endif // CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY + + if (ble_stack_enable() != 0) { + ret = ESP_FAIL; + goto error; + } + if (r_ble_controller_enable(mode) != 0) { ret = ESP_FAIL; goto error; @@ -929,6 +1123,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode) return ESP_OK; error: + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -952,6 +1147,7 @@ esp_err_t esp_bt_controller_disable(void) if (r_ble_controller_disable() != 0) { return ESP_FAIL; } + ble_stack_disable(); #if CONFIG_SW_COEXIST_ENABLE coex_disable(); #endif @@ -1069,7 +1265,6 @@ esp_err_t esp_bt_mem_release(esp_bt_mode_t mode) return ret; } - esp_bt_controller_status_t esp_bt_controller_get_status(void) { return ble_controller_status; @@ -1081,9 +1276,17 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_ switch (power_type) { case ESP_BLE_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_ADV: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0xFF, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_PWR_TYPE_SCAN: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1114,9 +1317,13 @@ esp_err_t esp_ble_tx_power_set_enhanced(esp_ble_enhanced_power_type_t power_type esp_err_t stat = ESP_FAIL; switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + stat = ESP_OK; + } + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0, power_level) == 0) { + if (r_ble_txpwr_set(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0, power_level) == 0) { stat = ESP_OK; } break; @@ -1139,11 +1346,15 @@ esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type) int tx_level = 0; switch (power_type) { - case ESP_BLE_PWR_TYPE_ADV: - case ESP_BLE_PWR_TYPE_SCAN: case ESP_BLE_PWR_TYPE_DEFAULT: tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); break; + case ESP_BLE_PWR_TYPE_ADV: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_ADV, 0); + break; + case ESP_BLE_PWR_TYPE_SCAN: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); + break; case ESP_BLE_PWR_TYPE_CONN_HDL0: case ESP_BLE_PWR_TYPE_CONN_HDL1: case ESP_BLE_PWR_TYPE_CONN_HDL2: @@ -1173,9 +1384,11 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po switch (power_type) { case ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT: + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + break; case ESP_BLE_ENHANCED_PWR_TYPE_SCAN: case ESP_BLE_ENHANCED_PWR_TYPE_INIT: - tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT, 0); + tx_level = r_ble_txpwr_get(ESP_BLE_ENHANCED_PWR_TYPE_SCAN, 0); break; case ESP_BLE_ENHANCED_PWR_TYPE_ADV: case ESP_BLE_ENHANCED_PWR_TYPE_CONN: @@ -1193,26 +1406,47 @@ esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t po } #if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED -static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, bool end) +#if !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED +static void esp_bt_controller_log_interface(uint32_t len, const uint8_t *addr, uint32_t len_append, const uint8_t *addr_append, uint32_t flag) { - for (int i = 0; i < len; i++) { - esp_rom_printf("%02x ", addr[i]); + bool end = (flag & BIT(BLE_LOG_INTERFACE_FLAG_END)); +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_controller_log_storage(len, addr, end); +#else // !CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + portENTER_CRITICAL_SAFE(&spinlock); + esp_panic_handler_feed_wdts(); + + if (len && addr) { + for (int i = 0; i < len; i++) { esp_rom_printf("%02x ", addr[i]); } } - if (end) { - esp_rom_printf("\n"); + if (len_append && addr_append) { + for (int i = 0; i < len_append; i++) { esp_rom_printf("%02x ", addr_append[i]); } } + if (end) { esp_rom_printf("\n"); } + + portEXIT_CRITICAL_SAFE(&spinlock); +#endif // CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE } +#endif // !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED void esp_ble_controller_log_dump_all(bool output) { - portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; +#if CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED + ble_log_spi_out_dump_all(); +#endif // CONFIG_BT_BLE_LOG_SPI_OUT_ENABLED +#if CONFIG_BT_LE_CONTROLLER_LOG_STORAGE_ENABLE + esp_bt_read_ctrl_log_from_flash(output); +#elif !CONFIG_BT_LE_CONTROLLER_LOG_SPI_OUT_ENABLED + portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; portENTER_CRITICAL_SAFE(&spinlock); - esp_panic_handler_reconfigure_wdts(5000); + esp_panic_handler_feed_wdts(); BT_ASSERT_PRINT("\r\n[DUMP_START:"); r_ble_log_async_output_dump_all(output); BT_ASSERT_PRINT(":DUMP_END]\r\n"); portEXIT_CRITICAL_SAFE(&spinlock); +#endif } #endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED @@ -1427,3 +1661,35 @@ int ble_sm_alg_gen_key_pair(uint8_t *pub, uint8_t *priv) #endif // CONFIG_BT_LE_SM_LEGACY || CONFIG_BT_LE_SM_SC #endif // (!CONFIG_BT_NIMBLE_ENABLED) && (CONFIG_BT_CONTROLLER_ENABLED) +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED +#include "esp_gdbstub.h" +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + +int IRAM_ATTR +ble_capture_info_user_handler(uint8_t type, uint32_t reason, uint32_t param1, uint32_t param2) +{ + int i; + + switch(type) { + case 0: + for (i = 0; i < 2; i++) { + esp_ble_controller_info_capture(0x010101); + } +#if CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + uintptr_t sp; + __asm__ volatile ("mv %0, sp" : "=r" (sp)); + esp_gdbstub_panic_handler(&sp); +#endif // CONFIG_BT_LE_DEBUG_REMAIN_SCENE_ENABLED + break; +#if CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + case 1: + if ((reason == 0x08) || (reason == 0x3d) || (reason == 0x28)) { + osi_assert_wrapper(__LINE__,__func__, type, reason); + } + break; +#endif // CONFIG_BT_LE_ASSERT_WHEN_ABNORMAL_DISCONN_ENABLED + default: + break; + } + return 0; +} diff --git a/lib/bt/controller/esp32h2/esp_bt_cfg.h b/lib/bt/controller/esp32h2/esp_bt_cfg.h index c0c5801a..48a845a3 100644 --- a/lib/bt/controller/esp32h2/esp_bt_cfg.h +++ b/lib/bt/controller/esp32h2/esp_bt_cfg.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -124,22 +124,98 @@ extern "C" { #else #define DEFAULT_BT_LE_POWER_CONTROL_ENABLED (0) #endif - #if defined(CONFIG_BT_LE_50_FEATURE_SUPPORT) #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (1) #else #define DEFAULT_BT_LE_50_FEATURE_SUPPORT (0) #endif + + #if defined (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (CONFIG_BT_LE_HCI_UART_FLOWCTRL) + #if DEFAULT_BT_LE_HCI_UART_FLOW_CTRL + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (CONFIG_BT_LE_HCI_UART_CTS_PIN) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (CONFIG_BT_LE_HCI_UART_RTS_PIN) + #else + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif + #else + #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) + #define DEFAULT_BT_LE_HCI_UART_CTS_PIN (-1) + #define DEFAULT_BT_LE_HCI_UART_RTS_PIN (-1) + #endif #endif #define DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF +#ifdef CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (CONFIG_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS) +#else +#define DEFAULT_BT_LE_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS (0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CONN_UPDATE +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (1<<0) +#else +#define BT_CTRL_BLE_LLCP_CONN_UPDATE (0<<0) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_CHAN_MAP_UPDATE +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (1<<1) +#else +#define BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE (0<<1) +#endif + +#ifdef CONFIG_BT_LE_CTRL_LLCP_PHY_UPDATE +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (1<<2) +#else +#define BT_CTRL_BLE_LLCP_PHY_UPDATE (0<<2) +#endif + +#define BT_LE_CTRL_LLCP_DISC_FLAG (BT_CTRL_BLE_LLCP_CONN_UPDATE | BT_CTRL_BLE_LLCP_CHAN_MAP_UPDATE | BT_CTRL_BLE_LLCP_PHY_UPDATE) + +#ifdef CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX) +#else +#define BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX (256) +#endif + +#if defined(CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (CONFIG_BT_LE_CTRL_CHAN_ASS_EN) +#else +#define DEFAULT_BT_LE_CTRL_CHAN_ASS_EN (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (CONFIG_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX) +#else +#define DEFAULT_BT_LE_CTRL_ADV_DATA_LENGTH_ZERO_AUX (0) +#endif + +#if defined(CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (CONFIG_BT_LE_CTRL_FAST_CONN_DATA_TX_EN) +#else +#define DEFAULT_BT_LE_CTRL_FAST_CONN_DATA_TX_EN (0) +#endif + #ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART #define HCI_UART_EN CONFIG_BT_LE_HCI_INTERFACE_USE_UART #else #define HCI_UART_EN 0 // hci ram mode #endif +#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_RAM +#define DEFAULT_BT_LE_VHCI_ENABLED (CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) +#else +#define DEFAULT_BT_LE_VHCI_ENABLED (0) +#endif + +#ifdef CONFIG_BT_LE_PTR_CHECK_ENABLED +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (CONFIG_BT_LE_PTR_CHECK_ENABLED) +#else +#define DEFAULT_BT_LE_PTR_CHECK_ENABLED (0) +#endif + #ifdef CONFIG_BT_LE_SLEEP_ENABLE #define NIMBLE_SLEEP_ENABLE CONFIG_BT_LE_SLEEP_ENABLE #else @@ -170,8 +246,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (UART_DATA_8_BITS) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (UART_STOP_BITS_1) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (CONFIG_BT_LE_HCI_UART_TASK_STACK_SIZE) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #else #define DEFAULT_BT_LE_HCI_UART_TX_PIN (0) #define DEFAULT_BT_LE_HCI_UART_RX_PIN (0) @@ -180,8 +254,6 @@ extern "C" { #define DEFAULT_BT_LE_HCI_UART_DATA_BITS (0) #define DEFAULT_BT_LE_HCI_UART_STOP_BITS (0) #define DEFAULT_BT_LE_HCI_UART_PARITY (0) - #define DEFAULT_BT_LE_HCI_UART_TASK_STACK_SIZE (0) - #define DEFAULT_BT_LE_HCI_UART_FLOW_CTRL (0) #endif /* Unchanged configuration */ @@ -206,8 +278,7 @@ extern "C" { #define RTC_FREQ_N (32768) /* in Hz */ -#define BLE_LL_TX_PWR_DBM_N (9) - +#define BLE_LL_TX_PWR_DBM_N (CONFIG_BT_LE_DFT_TX_POWER_LEVEL_DBM_EFF) #define RUN_BQB_TEST (0) #define RUN_QA_TEST (0) diff --git a/lib/bt/controller/esp32h21/Kconfig.in b/lib/bt/controller/esp32h21/Kconfig.in new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/lib/bt/controller/esp32h21/Kconfig.in diff --git a/lib/bt/controller/esp32h4/Kconfig.in b/lib/bt/controller/esp32h4/Kconfig.in new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/lib/bt/controller/esp32h4/Kconfig.in diff --git a/lib/bt/controller/lib_esp32/esp32/libbtdm_app.a b/lib/bt/controller/lib_esp32/esp32/libbtdm_app.a Binary files differindex 7e190d8a..558e9ec8 100644 --- a/lib/bt/controller/lib_esp32/esp32/libbtdm_app.a +++ b/lib/bt/controller/lib_esp32/esp32/libbtdm_app.a diff --git a/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a b/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a Binary files differindex 4df30d81..62e70fd3 100644..100755 --- a/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a +++ b/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a diff --git a/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app_flash.a b/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app_flash.a Binary files differnew file mode 100755 index 00000000..0156a515 --- /dev/null +++ b/lib/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app_flash.a diff --git a/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a b/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a Binary files differindex 8d1cc4fe..2141b846 100644..100755 --- a/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a +++ b/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app.a diff --git a/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app_flash.a b/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app_flash.a Binary files differnew file mode 100755 index 00000000..674f6487 --- /dev/null +++ b/lib/bt/controller/lib_esp32c3_family/esp32c3/libbtdm_app_flash.a diff --git a/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app.a b/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app.a Binary files differindex 7d450357..08a8f5f1 100644..100755 --- a/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app.a +++ b/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app.a diff --git a/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app_flash.a b/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app_flash.a Binary files differnew file mode 100755 index 00000000..eb87092f --- /dev/null +++ b/lib/bt/controller/lib_esp32c3_family/esp32s3/libbtdm_app_flash.a diff --git a/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/NOTICE b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/NOTICE new file mode 100644 index 00000000..f996f9a2 --- /dev/null +++ b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/NOTICE @@ -0,0 +1,9 @@ +Apache Mynewt NimBLE +Copyright 2015-2021 The Apache Software Foundation +Modifications Copyright 2017-2024 Espressif Systems (Shanghai) CO., LTD. + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Portions of this software were developed at +Runtime Inc, copyright 2015.
\ No newline at end of file diff --git a/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/README.md b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/README.md new file mode 100644 index 00000000..7a64988a --- /dev/null +++ b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/README.md @@ -0,0 +1 @@ +This software includes portions of code derived from mynewt-nimble project. See [NOTICE](NOTICE) file for details. diff --git a/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/libble_app.a b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/libble_app.a Binary files differnew file mode 100755 index 00000000..1ec27254 --- /dev/null +++ b/lib/bt/controller/lib_esp32c5/esp32c5-bt-lib/libble_app.a diff --git a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/NOTICE b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/NOTICE index a0cb7d8b..f996f9a2 100644 --- a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/NOTICE +++ b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/NOTICE @@ -1,6 +1,6 @@ Apache Mynewt NimBLE Copyright 2015-2021 The Apache Software Foundation -Modifications Copyright 2017-2023 Espressif Systems (Shanghai) CO., LTD. +Modifications Copyright 2017-2024 Espressif Systems (Shanghai) CO., LTD. This product includes software developed at The Apache Software Foundation (http://www.apache.org/). diff --git a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a Binary files differnew file mode 100755 index 00000000..82dd0ff6 --- /dev/null +++ b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a diff --git a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a Binary files differnew file mode 100755 index 00000000..10e59d9e --- /dev/null +++ b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a diff --git a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a b/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a Binary files differdeleted file mode 100644 index d39ed65a..00000000 --- a/lib/bt/controller/lib_esp32c6/esp32c6-bt-lib/libble_app.a +++ /dev/null diff --git a/lib/bt/controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a b/lib/bt/controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a Binary files differindex 184b2def..69436b7f 100644..100755 --- a/lib/bt/controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a +++ b/lib/bt/controller/lib_esp32h2/esp32h2-bt-lib/libble_app.a |
