Merge branch 'feat/support_ble_bredr_on_esp32s31' into 'master'

feat(bt): Support Bluetooth LE and Bluetooth Classic on ESP32-S31

Closes IDF-15185, IDF-15188, IDF-15189, IDF-15193, and IDF-15192

See merge request espressif/esp-idf!47330
This commit is contained in:
Wang Meng Yang
2026-04-22 08:03:07 +08:00
207 changed files with 4251 additions and 474 deletions
+32 -22
View File
@@ -102,10 +102,11 @@ if(CONFIG_BT_ENABLED)
list(APPEND srcs "controller/${target_name}/ble.c")
list(APPEND srcs "controller/esp32c2/dummy.c")
set(ldscripts "linker_esp32c2.lf")
elseif(CONFIG_BT_DUAL_MODE_ARCH)
list(APPEND srcs "controller/${target_name}/bt.c")
list(APPEND ldscripts "linker_esp_btdm_controller.lf")
else()
if(NOT CONFIG_BT_DUAL_MODE_ARCH)
list(APPEND srcs "controller/${target_name}/ble.c")
endif()
list(APPEND srcs "controller/${target_name}/ble.c")
list(APPEND ldscripts "linker_esp_ble_controller.lf")
endif()
@@ -1264,31 +1265,40 @@ if(CONFIG_BT_ENABLED)
if(CONFIG_BT_LE_CONTROLLER_LOG_WRAP_PANIC_HANDLER_ENABLE)
target_link_options(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_panic_handler")
endif()
if(CONFIG_IDF_TARGET_ESP32C6)
add_prebuilt_library(libble_app
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a"
REQUIRES esp_phy)
elseif(CONFIG_IDF_TARGET_ESP32C61)
add_prebuilt_library(libble_app
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a"
if(CONFIG_BT_DUAL_MODE_ARCH)
if(CONFIG_BT_CTRL_BLE_ENABLE)
add_prebuilt_library(libble_app "controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a"
REQUIRES esp_phy)
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
endif()
if(CONFIG_BT_CTRL_BREDR_ENABLE)
add_prebuilt_library(libbredr_app "controller/lib_${target_name}/${target_name}-bt-lib/libbredr_app.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libbredr_app)
endif()
add_prebuilt_library(libbtdm_common
"controller/lib_${target_name}/${target_name}-bt-lib/libbtdm_common.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libbtdm_common)
else()
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND CONFIG_IDF_TARGET_ESP32C2)
if(CONFIG_IDF_TARGET_ESP32C6)
add_prebuilt_library(libble_app
"controller/lib_${target_name}/${target_name}-bt-lib/libble_app_flash.a"
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c6/libble_app.a"
REQUIRES esp_phy)
elseif(CONFIG_IDF_TARGET_ESP32C61)
add_prebuilt_library(libble_app
"${CMAKE_CURRENT_LIST_DIR}/controller/lib_esp32c6/esp32c6-bt-lib/esp32c61/libble_app.a"
REQUIRES esp_phy)
else()
add_prebuilt_library(libble_app
"controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a"
REQUIRES esp_phy)
if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND CONFIG_IDF_TARGET_ESP32C2)
add_prebuilt_library(libble_app
"controller/lib_${target_name}/${target_name}-bt-lib/libble_app_flash.a"
REQUIRES esp_phy)
else()
add_prebuilt_library(libble_app
"controller/lib_${target_name}/${target_name}-bt-lib/libble_app.a"
REQUIRES esp_phy)
endif()
endif()
endif()
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
if(CONFIG_BT_DUAL_MODE_ARCH)
add_prebuilt_library(libbtdm_common
"controller/lib_${target_name}/${target_name}-bt-lib/libbtdm_common.a")
target_link_libraries(${COMPONENT_LIB} PRIVATE libbtdm_common)
target_link_libraries(${COMPONENT_LIB} PRIVATE libble_app)
endif()
endif()
+6 -1
View File
@@ -8,10 +8,13 @@ config BT_ALARM_MAX_NUM
choice BT_SMP_CRYPTO_STACK
prompt "SMP cryptographic stack"
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE)
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE || \
BT_CTRL_BREDR_ENABLE)
default BT_SMP_CRYPTO_STACK_TINYCRYPT
help
Select the cryptographic library to use for SMP operations (AES, AES-CMAC, ECDH P-256).
With BR/EDR controller enabled, mbedTLS also enables SHA-256 (for the BR/EDR port)
and ECDH for P-192 on the controller port.
config BT_SMP_CRYPTO_STACK_TINYCRYPT
bool "TinyCrypt"
@@ -22,6 +25,8 @@ choice BT_SMP_CRYPTO_STACK
This is the default option.
config BT_SMP_CRYPTO_STACK_MBEDTLS
# BT Classic requires ECC P-192, which is removed in mbedtls 4.1.0
depends on !BT_CTRL_BREDR_ENABLE
bool "mbedTLS"
select MBEDTLS_AES_C
select MBEDTLS_CMAC_C
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -98,7 +98,13 @@ static_assert(false, "BLE Log SPI Out: Unsupported target architecture");
SPI_OUT_MESH_QUEUE_SIZE)
#if SPI_OUT_LL_ENABLED && CONFIG_SOC_ESP_NIMBLE_CONTROLLER
#if CONFIG_BT_DUAL_MODE_ARCH
#include "ble_mbuf.h"
#define BLE_MBUF_COPY(buf, off, len, dst) ble_mbuf_copydata((struct ble_mbuf *)(buf), off, len, dst)
#else
#include "os/os_mbuf.h"
#define BLE_MBUF_COPY(buf, off, len, dst) os_mbuf_copydata((struct os_mbuf *)(buf), off, len, dst)
#endif // CONFIG_BT_DUAL_MODE_ARCH
#endif /* SPI_OUT_LL_ENABLED && CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
// Private typedefs
@@ -613,8 +619,7 @@ IRAM_ATTR static bool spi_out_log_cb_write(spi_out_log_cb_t *log_cb, const uint8
if (len_append && addr_append) {
#if SPI_OUT_LL_ENABLED && CONFIG_SOC_ESP_NIMBLE_CONTROLLER
if (omdata) {
os_mbuf_copydata((struct os_mbuf *)addr_append, 0,
len_append, buf + SPI_OUT_FRAME_HEAD_LEN + len);
BLE_MBUF_COPY(addr_append, 0, len_append, buf + SPI_OUT_FRAME_HEAD_LEN + len);
}
else
#endif /* SPI_OUT_LL_ENABLED && CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
@@ -677,6 +682,7 @@ static void spi_out_log_cb_dump(spi_out_log_cb_t *log_cb)
}
}
#if SPI_OUT_HOST_ENABLED || SPI_OUT_MESH_ENABLED || SPI_OUT_HCI_ENABLED || SPI_OUT_LE_AUDIO_ENABLED
static void spi_out_update_task_mapping(int idx, void *ptr)
{
// It is a must to clear task handle after task deletion
@@ -684,7 +690,6 @@ static void spi_out_update_task_mapping(int idx, void *ptr)
entry->task_handle = NULL;
}
#if SPI_OUT_HOST_ENABLED || SPI_OUT_MESH_ENABLED || SPI_OUT_HCI_ENABLED || SPI_OUT_LE_AUDIO_ENABLED
static bool spi_out_get_task_mapping(task_map_t *map, size_t num,
spi_out_log_cb_t **log_cb, uint8_t **str_buf)
{
@@ -13,7 +13,13 @@
#include "ble_log_rt.h"
#if CONFIG_SOC_ESP_NIMBLE_CONTROLLER
#if CONFIG_BT_DUAL_MODE_ARCH
#include "ble_mbuf.h"
#define BLE_MBUF_COPY(buf, off, len, dst) ble_mbuf_copydata((struct ble_mbuf *)(buf), off, len, dst)
#else
#include "os/os_mbuf.h"
#define BLE_MBUF_COPY(buf, off, len, dst) os_mbuf_copydata((struct os_mbuf *)(buf), off, len, dst)
#endif // CONFIG_BT_DUAL_MODE_ARCH
#endif /* CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
/* VARIABLE */
@@ -133,8 +139,7 @@ void ble_log_lbm_write_trans(ble_log_prph_trans_t **trans, ble_log_src_t src_cod
if (len_append) {
#if CONFIG_SOC_ESP_NIMBLE_CONTROLLER
if (omdata) {
os_mbuf_copydata((struct os_mbuf *)addr_append, 0,
len_append, buf + BLE_LOG_FRAME_HEAD_LEN + len);
BLE_MBUF_COPY(addr_append, 0, len_append, buf + BLE_LOG_FRAME_HEAD_LEN + len);
}
else
#endif /* CONFIG_SOC_ESP_NIMBLE_CONTROLLER */
@@ -77,12 +77,24 @@
#ifndef __TC_UECC_H__
#define __TC_UECC_H__
#include "sdkconfig.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define uECC_VLI_NATIVE_LITTLE_ENDIAN 1
#define uECC_SUPPORTS_secp256r1 1
#ifndef uECC_SUPPORTS_secp192r1
#if defined(CONFIG_BT_CTRL_BREDR_ENABLE) && (CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT)
#define uECC_SUPPORTS_secp192r1 1
#else
#define uECC_SUPPORTS_secp192r1 0
#endif
#endif
/* Word size (4 bytes considering 32-bits architectures) */
#define uECC_WORD_SIZE 4
@@ -112,6 +124,13 @@ typedef uint64_t uECC_dword_t;
/* Number of bytes to represent an element of the the curve p-256: */
#define NUM_ECC_BYTES (uECC_WORD_SIZE*NUM_ECC_WORDS)
#if uECC_SUPPORTS_secp192r1
/* Number of words of 32 bits to represent an element of the the curve p-192: */
#define NUM_ECC_WORDS_SECP192R1 6
/* Number of bytes to represent an element of the the curve p-192: */
#define NUM_ECC_BYTES_SECP192R1 (uECC_WORD_SIZE * NUM_ECC_WORDS_SECP192R1)
#endif
/* structure that represents an elliptic curve (e.g. p256):*/
struct uECC_Curve_t;
typedef const struct uECC_Curve_t * uECC_Curve;
@@ -200,6 +219,43 @@ static const struct uECC_Curve_t curve_secp256r1 = {
uECC_Curve uECC_secp256r1(void);
#if uECC_SUPPORTS_secp192r1
uECC_Curve uECC_secp192r1(void);
/*
* @brief Computes result = product % curve_p (NIST P-192)
* from http://www.nsa.gov/ia/_files/nist-routines.pdf
* @param result OUT -- product % curve_p
* @param product IN -- value to be reduced mod curve_p
*/
void vli_mmod_fast_secp192r1(unsigned int *result, unsigned int *product);
/* definition of curve NIST p-192: */
static const struct uECC_Curve_t curve_secp192r1 = { NUM_ECC_WORDS_SECP192R1,
NUM_ECC_BYTES_SECP192R1,
192, /* num_n_bits */
{ BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
{ BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14),
BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF),
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) },
{ BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4),
BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C),
BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18),
BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73),
BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63),
BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07) },
{ BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE),
BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F),
BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64) },
&double_jacobian_default,
&x_side_default,
&vli_mmod_fast_secp192r1 };
#endif /* uECC_SUPPORTS_secp192r1 */
/*
* @brief Generates a random integer in the range 0 < random < top.
* Both random and top have num_words words.
+51 -5
View File
@@ -542,6 +542,41 @@ void x_side_default(uECC_word_t *result,
uECC_vli_modAdd(result, result, curve->b, curve->p, num_words);
}
#if uECC_SUPPORTS_secp192r1
uECC_Curve uECC_secp192r1(void)
{
return &curve_secp192r1;
}
void vli_mmod_fast_secp192r1(unsigned int *result, unsigned int *product)
{
unsigned int tmp[NUM_ECC_WORDS_SECP192R1];
int carry;
uECC_vli_set(result, product, NUM_ECC_WORDS_SECP192R1);
uECC_vli_set(tmp, &product[6], NUM_ECC_WORDS_SECP192R1);
carry = uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
tmp[0] = tmp[1] = 0;
tmp[2] = product[6];
tmp[3] = product[7];
tmp[4] = product[8];
tmp[5] = product[9];
carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
tmp[0] = tmp[2] = product[10];
tmp[1] = tmp[3] = product[11];
tmp[4] = tmp[5] = 0;
carry += uECC_vli_add(result, result, tmp, NUM_ECC_WORDS_SECP192R1);
while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, NUM_ECC_WORDS_SECP192R1) != 1) {
carry -= uECC_vli_sub(result, result, curve_secp192r1.p, NUM_ECC_WORDS_SECP192R1);
}
}
#endif /* uECC_SUPPORTS_secp192r1 */
uECC_Curve uECC_secp256r1(void)
{
return &curve_secp256r1;
@@ -766,8 +801,12 @@ void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
wordcount_t num_words = curve->num_words;
/* Only p256r1 is supported currently. */
assert (curve == uECC_secp256r1());
/* Only p256r1 and p192r1 are supported currently. */
assert(curve == uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
|| curve == uECC_secp192r1()
#endif /* #if uECC_SUPPORTS_secp192r1 */
);
esp_tinycrypt_calc_ecc_mult((const uint8_t *)&point[0], (const uint8_t *)&point[num_words],
(uint8_t *)scalar, (uint8_t *)&result[0], (uint8_t *)&result[num_words],
@@ -936,8 +975,11 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
}
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
/* Only p256r1 is supported currently. */
if (curve != uECC_secp256r1()) {
if (curve != uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
&& curve != uECC_secp192r1()
#endif /* uECC_SUPPORTS_secp192r1 */
) {
return -5;
}
@@ -964,14 +1006,16 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve)
{
uECC_word_t _public[NUM_ECC_WORDS * 2];
wordcount_t num_point_words = curve->num_words * 2;
uECC_vli_clear(_public, NUM_ECC_WORDS * 2);
uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
uECC_vli_bytesToNative(
_public + curve->num_words,
public_key + curve->num_bytes,
curve->num_bytes);
if (uECC_vli_cmp_unsafe(_public, curve->G, NUM_ECC_WORDS * 2) == 0) {
if (uECC_vli_cmp_unsafe(_public, curve->G, num_point_words) == 0) {
return -4;
}
@@ -984,6 +1028,8 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key,
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t _public[NUM_ECC_WORDS * 2];
uECC_vli_clear(_private, NUM_ECC_WORDS);
uECC_vli_clear(_public, NUM_ECC_WORDS * 2);
uECC_vli_bytesToNative(
_private,
private_key,
+87 -53
View File
@@ -10,7 +10,13 @@
/* From ESP Bluetooth */
#include "esp_bt.h"
#include "esp_hci_transport.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_priv.h"
#endif
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
#include "bredr_priv.h"
#endif
#include "btdm_osal.h"
#include "btdm_coex.h"
#include "btdm_lp.h"
#include "btdm_log.h"
@@ -26,19 +32,27 @@
#if UC_BT_CTRL_HCI_INTERFACE_USE_RAM
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_VHCI
#elif UC_BT_CTRL_HCI_INTERFACE_USE_UART
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_NO_DMA
#if UC_BT_CTRL_UART_HCI_DMA_MODE
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_UHCI
#else
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_NO_DMA
#endif // UC_BT_CTRL_UART_HCI_DMA_MODE
#else
#error "Unknown HCI transport mode!!"
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_RAM
#if defined(UNUSED)
#undef UNUSED
#endif
#define UNUSED(x) (void)(x)
/*
***************************************************************************************************
* External Functions
***************************************************************************************************
*/
extern const char *r_btdm_get_compile_version(void);
extern int r_btdm_hci_fc_env_init();
extern int r_btdm_hci_fc_env_init(void);
extern void r_btdm_hci_fc_env_deinit(void);
extern int r_btdm_hci_fc_enable(void);
extern void r_btdm_hci_fc_disable(void);
@@ -68,10 +82,68 @@ bt_shutdown(void)
return;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
r_btdm_task_shutdown();
btdm_lp_shutdown();
}
static esp_err_t
bt_controller_deinit(void)
{
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
hci_transport_deinit();
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_deinit();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_deinit();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_env_deinit();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
btdm_lp_deinit();
r_btdm_task_deinit();
btdm_lp_disable_clock();
btdm_coex_deinit();
btdm_external_deinit();
btdm_log_deinit();
btdm_osal_elem_mempool_deinit();
return ESP_OK;
}
static esp_err_t
bt_controller_disable(void)
{
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
esp_unregister_shutdown_handler(bt_shutdown);
r_btdm_task_disable();
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_disable();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_disable();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_disable();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
btdm_coex_disable();
btdm_lp_reset(false);
return ESP_OK;
}
/*
***************************************************************************************************
* Public Function Definitions
@@ -80,6 +152,7 @@ bt_shutdown(void)
esp_err_t
esp_bt_mem_release(esp_bt_mode_t mode)
{
// TODO: Support bluetooth stack memory release
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_mem_release not implement yet!");
return ESP_OK;
}
@@ -87,7 +160,7 @@ esp_bt_mem_release(esp_bt_mode_t mode)
esp_err_t
esp_bt_controller_mem_release(esp_bt_mode_t mode)
{
// TODO: Support bt controller memory release
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_controller_mem_release not implement yet!");
return ESP_OK;
}
@@ -105,6 +178,10 @@ esp_bt_controller_init(esp_bt_controller_config_t *cfg)
.mutex_count = 1,
};
if (cfg == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(BTDM_LOG_TAG, "BTDM version [%s]", r_btdm_get_compile_version());
if (cfg->btdm.bluetooth_mode == ESP_BT_MODE_IDLE) {
@@ -115,9 +192,6 @@ esp_bt_controller_init(esp_bt_controller_config_t *cfg)
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
ret = ESP_FAIL;
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_osal_elem_calc(cfg, &elem);
@@ -196,11 +270,12 @@ esp_bt_controller_init(esp_bt_controller_config_t *cfg)
}
ESP_LOGI(BTDM_LOG_TAG, "BTDM controller init OK");
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
return ESP_OK;
init_failed:
esp_bt_controller_deinit();
bt_controller_deinit();
return ESP_FAIL;
}
@@ -211,31 +286,7 @@ esp_bt_controller_deinit(void)
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
hci_transport_deinit();
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_deinit();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_deinit();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_env_deinit();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
btdm_lp_deinit();
r_btdm_task_deinit();
btdm_lp_disable_clock();
btdm_coex_deinit();
btdm_log_deinit();
btdm_external_deinit();
btdm_osal_elem_mempool_deinit();
return ESP_OK;
return bt_controller_deinit();
}
esp_err_t
@@ -243,10 +294,10 @@ esp_bt_controller_enable(esp_bt_mode_t mode)
{
int ret;
UNUSED(mode);
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
btdm_lp_reset(true);
@@ -291,10 +342,11 @@ esp_bt_controller_enable(esp_bt_mode_t mode)
ESP_LOGW(BTDM_LOG_TAG, "Register shutdown handler failed, ret = 0x%x", ret);
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
return ESP_OK;
enable_failed:
esp_bt_controller_disable();
bt_controller_disable();
return ESP_FAIL;
}
@@ -304,26 +356,8 @@ esp_bt_controller_disable(void)
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
esp_unregister_shutdown_handler(bt_shutdown);
r_btdm_task_disable();
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_disable();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_disable();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_disable();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
btdm_coex_disable();
btdm_lp_reset(false);
bt_controller_disable();
return ESP_OK;
}
@@ -0,0 +1,5 @@
source "$IDF_PATH/components/bt/porting_btdm/Kconfig.in"
config BT_CTRL_MULTI_LINK_ENABLED
bool
default y
+369
View File
@@ -0,0 +1,369 @@
/*
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_err.h"
#include "esp_log.h"
#include "sdkconfig.h"
/* From ESP Bluetooth */
#include "esp_bt.h"
#include "esp_hci_transport.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_priv.h"
#endif
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
#include "bredr_priv.h"
#endif
#include "btdm_osal.h"
#include "btdm_coex.h"
#include "btdm_lp.h"
#include "btdm_log.h"
#include "btdm_external.h"
/*
***************************************************************************************************
* Local Defined Macros
***************************************************************************************************
*/
#define BTDM_LOG_TAG "BTDM_INIT"
#if UC_BT_CTRL_HCI_INTERFACE_USE_RAM
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_VHCI
#elif UC_BT_CTRL_HCI_INTERFACE_USE_UART
#if UC_BT_CTRL_UART_HCI_DMA_MODE
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_UHCI
#else
#define BT_HCI_TRANSPORT_MODE HCI_TRANSPORT_UART_NO_DMA
#endif // UC_BT_CTRL_UART_HCI_DMA_MODE
#else
#error "Unknown HCI transport mode!!"
#endif // UC_BT_CTRL_HCI_INTERFACE_USE_RAM
#if defined(UNUSED)
#undef UNUSED
#endif
#define UNUSED(x) (void)(x)
/*
***************************************************************************************************
* External Functions
***************************************************************************************************
*/
extern const char *r_btdm_get_compile_version(void);
extern int r_btdm_hci_fc_env_init(void);
extern void r_btdm_hci_fc_env_deinit(void);
extern int r_btdm_hci_fc_enable(void);
extern void r_btdm_hci_fc_disable(void);
extern int r_btdm_task_init(esp_btdm_controller_config_t *cfg);
extern void r_btdm_task_deinit(void);
extern int r_btdm_task_enable(void);
extern void r_btdm_task_disable(void);
extern void r_btdm_task_shutdown(void);
/*
***************************************************************************************************
* Local Variables
***************************************************************************************************
*/
esp_bt_controller_status_t s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
/*
***************************************************************************************************
* Static Function Definitions
***************************************************************************************************
*/
static void
bt_shutdown(void)
{
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return;
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
r_btdm_task_shutdown();
btdm_lp_shutdown();
}
static esp_err_t
bt_controller_deinit(void)
{
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
hci_transport_deinit();
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_deinit();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_deinit();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_env_deinit();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
btdm_lp_deinit();
r_btdm_task_deinit();
btdm_lp_disable_clock();
btdm_coex_deinit();
btdm_external_deinit();
btdm_log_deinit();
btdm_osal_elem_mempool_deinit();
return ESP_OK;
}
static esp_err_t
bt_controller_disable(void)
{
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
esp_unregister_shutdown_handler(bt_shutdown);
r_btdm_task_disable();
#if UC_BT_CTRL_CONN_FC_ENABLE
r_btdm_hci_fc_disable();
#endif // UC_BT_CTRL_CONN_FC_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_stack_disable();
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_stack_disable();
#endif // UC_BT_CTRL_BLE_IS_ENABLE
btdm_coex_disable();
btdm_lp_reset(false);
return ESP_OK;
}
/*
***************************************************************************************************
* Public Function Definitions
***************************************************************************************************
*/
esp_err_t
esp_bt_mem_release(esp_bt_mode_t mode)
{
// TODO: Support bluetooth stack memory release
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_mem_release not implement yet!");
return ESP_OK;
}
esp_err_t
esp_bt_controller_mem_release(esp_bt_mode_t mode)
{
// TODO: Support bt controller memory release
ESP_LOGW(BTDM_LOG_TAG, "esp_bt_controller_mem_release not implement yet!");
return ESP_OK;
}
esp_err_t
esp_bt_controller_init(esp_bt_controller_config_t *cfg)
{
int ret;
// TODO: Delete workaround
btdm_osal_elem_num_t elem = {
.evt_count = 3 + 100,
.evtq_count = 1 + 2,
.co_count = 0 + 10,
.sem_count = 0,
.mutex_count = 1,
};
if (cfg == NULL) {
return ESP_ERR_INVALID_ARG;
}
ESP_LOGI(BTDM_LOG_TAG, "BTDM version [%s]", r_btdm_get_compile_version());
if (cfg->btdm.bluetooth_mode == ESP_BT_MODE_IDLE) {
ESP_LOGE(BTDM_LOG_TAG, "bluetooth_mode in cfg is IDLE");
return ESP_ERR_INVALID_ARG;
}
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_osal_elem_calc(cfg, &elem);
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
bredr_osal_elem_calc(cfg, &elem);
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
ret = btdm_osal_elem_mempool_init(&elem);
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_osal_elem_mempool_init failed: %d", ret);
goto init_failed;
}
ret = btdm_log_init();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_log_init failed: %d", ret);
goto init_failed;
}
ret = btdm_external_init();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_external_init failed: %d", ret);
goto init_failed;
}
ret = btdm_coex_init();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_coex_init failed: %d", ret);
goto init_failed;
}
btdm_lp_enable_clock(&cfg->btdm);
ret = r_btdm_task_init(&cfg->btdm);
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_task_init failed: %d", ret);
goto init_failed;
}
ret = btdm_lp_init();
if (ret != ESP_OK) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_lp_init failed %d", ret);
goto init_failed;
}
#if UC_BT_CTRL_CONN_FC_ENABLE
ret = r_btdm_hci_fc_env_init();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_hci_fc_env_init failed: %d", ret);
goto init_failed;
}
#endif // UC_BT_CTRL_CONN_FC_ENABLE
#if UC_BT_CTRL_BLE_IS_ENABLE
ret = ble_stack_init(cfg);
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "ble_stack_init failed: %d", ret);
goto init_failed;
}
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
ret = bredr_stack_init(cfg);
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "bredr_stack_init failed: %d", ret);
goto init_failed;
}
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
ret = hci_transport_init(BT_HCI_TRANSPORT_MODE);
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "hci_transport_init failed %d", ret);
goto init_failed;
}
ESP_LOGI(BTDM_LOG_TAG, "BTDM controller init OK");
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
return ESP_OK;
init_failed:
bt_controller_deinit();
return ESP_FAIL;
}
esp_err_t
esp_bt_controller_deinit(void)
{
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
return bt_controller_deinit();
}
esp_err_t
esp_bt_controller_enable(esp_bt_mode_t mode)
{
int ret;
UNUSED(mode);
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
btdm_lp_reset(true);
ret = btdm_coex_enable();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "btdm_coex_enable failed %d", ret);
goto enable_failed;
}
#if UC_BT_CTRL_BLE_IS_ENABLE
ret = ble_stack_enable();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "ble_stack_enable failed %d", ret);
goto enable_failed;
}
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
ret = bredr_stack_enable();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "bredr_stack_enable failed %d", ret);
goto enable_failed;
}
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_CONN_FC_ENABLE
ret = r_btdm_hci_fc_enable();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_hci_fc_enable failed %d", ret);
goto enable_failed;
}
#endif // UC_BT_CTRL_CONN_FC_ENABLE
ret = r_btdm_task_enable();
if (ret) {
ESP_LOGE(BTDM_LOG_TAG, "r_btdm_task_enable failed %d", ret);
goto enable_failed;
}
ret = esp_register_shutdown_handler(bt_shutdown);
if (ret) {
ESP_LOGW(BTDM_LOG_TAG, "Register shutdown handler failed, ret = 0x%x", ret);
}
s_btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
return ESP_OK;
enable_failed:
bt_controller_disable();
return ESP_FAIL;
}
esp_err_t
esp_bt_controller_disable(void)
{
if (s_btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_controller_disable();
return ESP_OK;
}
esp_bt_controller_status_t
esp_bt_controller_get_status(void)
{
return s_btdm_controller_status;
}
@@ -4522,7 +4522,7 @@ static void bta_dm_set_eir (char *local_name)
if (p_bta_dm_eir_cfg->bta_dm_eir_included_tx_power) {
if (free_eir_length >= 3) {
int min_power_level, max_power_level;
#if (BT_CONTROLLER_INCLUDED == TRUE)
#if (BR_EDR_GET_EIR_TX_PWR_LEVEL == TRUE)
if (esp_bredr_tx_power_get((esp_power_level_t *)&min_power_level, (esp_power_level_t *)&max_power_level) == ESP_OK) {
#else
{
@@ -59,6 +59,10 @@ extern tBTA_HF_CLIENT_CB bta_hf_client_cb;
#define BTA_HF_CLIENT_INDICATOR_CALLSETUP "callsetup"
#define BTA_HF_CLIENT_INDICATOR_CALLHELD "callheld"
#if defined(MIN)
#undef MIN
#endif
#define MIN(a, b) \
({ __typeof__(a) _a = (a); __typeof__(b) _b = (b); (_a < _b) ? _a : _b; })
@@ -372,7 +372,7 @@ bt_status_t btc_hf_init(void)
clear_phone_state();
// set audio path
#if (BT_CONTROLLER_INCLUDED == TRUE)
#if (BR_EDR_SET_CTRL_SCO_DATAPATH == TRUE)
#if BTM_SCO_HCI_INCLUDED
uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
#else
@@ -201,7 +201,7 @@ bt_status_t btc_hf_client_init(void)
clear_state();
#if (BT_CONTROLLER_INCLUDED == TRUE)
#if (BR_EDR_SET_CTRL_SCO_DATAPATH == TRUE)
#if BTM_SCO_HCI_INCLUDED
uint8_t data_path = ESP_SCO_DATA_PATH_HCI;
#else
@@ -1415,6 +1415,19 @@
#define BTM_BLE_CONFORMANCE_TESTING FALSE
#endif
#if (CLASSIC_BT_INCLUDED == TRUE)
#if (BT_CONTROLLER_INCLUDED == TRUE) && (CONFIG_IDF_TARGET_ESP32)
#define BR_EDR_SET_CTRL_SCO_DATAPATH (TRUE)
#else
#define BR_EDR_SET_CTRL_SCO_DATAPATH (FALSE)
#endif
#if (BT_CONTROLLER_INCLUDED == TRUE) && (CONFIG_IDF_TARGET_ESP32)
#define BR_EDR_GET_EIR_TX_PWR_LEVEL (TRUE)
#else
#define BR_EDR_GET_EIR_TX_PWR_LEVEL (FALSE)
#endif
#endif
/******************************************************************************
**
** CONTROLLER TO HOST FLOW CONTROL
@@ -0,0 +1,806 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_BT_H__
#define __ESP_BT_H__
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "sdkconfig.h"
#include "esp_task.h"
#include "esp_assert.h"
#include "btdm_user_cfg.h"
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
#include "bredr_user_cfg.h"
#endif
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_user_cfg.h"
#endif /* UC_BT_CTRL_BLE_IS_ENABLE */
#ifdef CONFIG_BT_LE_HCI_INTERFACE_USE_UART
#include "driver/uart.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Bluetooth mode for controller enable/disable.
*/
typedef enum {
ESP_BT_MODE_IDLE = 0x00, /*!< Bluetooth is not running */
ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */
ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
} esp_bt_mode_t;
/**
* @brief Bluetooth controller enable/disable/initialised/de-initialised status.
*/
typedef enum {
ESP_BT_CONTROLLER_STATUS_IDLE = 0, /*!< Controller is in idle state */
ESP_BT_CONTROLLER_STATUS_INITED, /*!< Controller is in initialising state */
ESP_BT_CONTROLLER_STATUS_ENABLED, /*!< Controller is in enabled state */
ESP_BT_CONTROLLER_STATUS_NUM, /*!< Controller is in disabled state */
} esp_bt_controller_status_t;
#if (UC_BT_CTRL_BR_EDR_IS_ENABLE)
#define ESP_BREDR_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5
#define ESP_BREDR_CTRL_CONFIG_VERSION 0x20250327
#endif // #if (UC_BT_CTRL_BR_EDR_IS_ENABLE)
/**
* @brief BLE tx power type
* ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed.
* when disconnect, the correspond TX power is not effected.
* ESP_BLE_PWR_TYPE_ADV : for advertising/scan response.
* ESP_BLE_PWR_TYPE_SCAN : for scan.
* ESP_BLE_PWR_TYPE_DEFAULT : if each connection's TX power is not set, it will use this default value.
* if neither in scan mode nor in adv mode, it will use this default value.
* If none of power type is set, system will use ESP_PWR_LVL_P3 as default for ADV/SCAN/CONN0-9.
*/
typedef enum {
ESP_BLE_PWR_TYPE_CONN_HDL0 = 0, /*!< For connection handle 0 */
ESP_BLE_PWR_TYPE_CONN_HDL1 = 1, /*!< For connection handle 1 */
ESP_BLE_PWR_TYPE_CONN_HDL2 = 2, /*!< For connection handle 2 */
ESP_BLE_PWR_TYPE_CONN_HDL3 = 3, /*!< For connection handle 3 */
ESP_BLE_PWR_TYPE_CONN_HDL4 = 4, /*!< For connection handle 4 */
ESP_BLE_PWR_TYPE_CONN_HDL5 = 5, /*!< For connection handle 5 */
ESP_BLE_PWR_TYPE_CONN_HDL6 = 6, /*!< For connection handle 6 */
ESP_BLE_PWR_TYPE_CONN_HDL7 = 7, /*!< For connection handle 7 */
ESP_BLE_PWR_TYPE_CONN_HDL8 = 8, /*!< For connection handle 8 */
ESP_BLE_PWR_TYPE_ADV = 9, /*!< For advertising */
ESP_BLE_PWR_TYPE_SCAN = 10, /*!< For scan */
ESP_BLE_PWR_TYPE_DEFAULT = 11, /*!< For default, if not set other, it will use default value */
ESP_BLE_PWR_TYPE_NUM = 12, /*!< TYPE numbers */
} esp_ble_power_type_t;
/**
* @brief Bluetooth TX power level(index), it's just a index corresponding to power(dbm).
*/
typedef enum {
ESP_PWR_LVL_N24 = 0, /*!< Corresponding to -24dbm */
ESP_PWR_LVL_N21 = 1, /*!< Corresponding to -21dbm */
ESP_PWR_LVL_N18 = 2, /*!< Corresponding to -18dbm */
ESP_PWR_LVL_N15 = 3, /*!< Corresponding to -15dbm */
ESP_PWR_LVL_N12 = 4, /*!< Corresponding to -12dbm */
ESP_PWR_LVL_N9 = 5, /*!< Corresponding to -9dbm */
ESP_PWR_LVL_N6 = 6, /*!< Corresponding to -6dbm */
ESP_PWR_LVL_N3 = 7, /*!< Corresponding to -3dbm */
ESP_PWR_LVL_N0 = 8, /*!< Corresponding to 0dbm */
ESP_PWR_LVL_P3 = 9, /*!< Corresponding to +3dbm */
ESP_PWR_LVL_P6 = 10, /*!< Corresponding to +6dbm */
ESP_PWR_LVL_P9 = 11, /*!< Corresponding to +9dbm */
ESP_PWR_LVL_P12 = 12, /*!< Corresponding to +12dbm */
ESP_PWR_LVL_P15 = 13, /*!< Corresponding to +15dbm */
ESP_PWR_LVL_P16 = 14, /*!< Corresponding to +16dbm */
ESP_PWR_LVL_P17 = 15, /*!< Corresponding to +17dbm */
ESP_PWR_LVL_P18 = 16, /*!< Corresponding to +18dbm */
ESP_PWR_LVL_P19 = 17, /*!< Corresponding to +19dbm */
ESP_PWR_LVL_P20 = 18, /*!< Corresponding to +20dbm */
ESP_PWR_LVL_INVALID = 0xFF, /*!< Indicates an invalid value */
} esp_power_level_t;
/**
* @brief The enhanced type of which tx power, could set Advertising/Connection/Default and etc.
*/
typedef enum {
ESP_BLE_ENHANCED_PWR_TYPE_DEFAULT = 0,
ESP_BLE_ENHANCED_PWR_TYPE_ADV,
ESP_BLE_ENHANCED_PWR_TYPE_SCAN,
ESP_BLE_ENHANCED_PWR_TYPE_INIT,
ESP_BLE_ENHANCED_PWR_TYPE_CONN,
ESP_BLE_ENHANCED_PWR_TYPE_MAX,
} esp_ble_enhanced_power_type_t;
/**
* @brief BR/EDR audio data transport path
*/
typedef enum {
ESP_SCO_DATA_PATH_HCI = 0, /*!< data over HCI transport */
ESP_SCO_DATA_PATH_PCM = 1, /*!< data over PCM interface */
} esp_sco_data_path_t;
/**
* @brief Address type and address value.
*/
typedef struct {
uint8_t type; /*!< Type of the Bluetooth address (public, random, etc.) */
uint8_t val[6]; /*!< Array containing the 6-byte Bluetooth address value */
} esp_ble_addr_t;
/**
* @brief Select buffers
*/
typedef enum {
ESP_BLE_LOG_BUF_HCI = 0x02,
ESP_BLE_LOG_BUF_CONTROLLER = 0x05,
} esp_ble_log_buf_t;
#define BLE_CONFIG_VERSION 0x20241029
#define BLE_CONFIG_MAGIC 0x5A5AA5A5
#define BTDM_CONFIG_VERSION 0x20260127
#define BTDM_CONFIG_MAGIC_VALUE 0x5a5aa5a5
/* Types definition
************************************************************************
*/
/**
* @brief mempool handle type used in BR/EDR controller
*/
typedef void * orca_mempool_t;
/**
* @brief mempool operations used in BR/EDR controller
*/
struct orca_mempool_ops {
orca_mempool_t (*create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes); /*!< mempool construction */
void (*destroy)(orca_mempool_t mempool); /*!< mempool destruction */
void *(*malloc)(orca_mempool_t mempool, size_t size); /*!< allocate memory from mempool */
void (*free)(orca_mempool_t mempool, void *ptr); /*!< release memory */
};
/**
* @brief BR/EDR controller configuration options
*/
typedef struct {
/*
* Following parameters can not be configured runtime when call esp_bt_controller_init()
* They will be overwritten by constant values from menuconfig options or from macros.
* So, do not modify the value when esp_bt_controller_init()
*/
uint32_t bredr_version; /*!< version number of the defined structure */
/*
* Following parameters can be configured runtime, when call esp_bt_controller_init()
*/
uint8_t sleep_mode; /*!< controller sleep mode */
uint8_t bt_test_mode_en; /*!< enable br/edr test mode */
uint8_t acl_cca_en; /*!< Enable BR/EDR ACL Transmit Clear Channel Assessment (TX CCA) */
int8_t cca_rssi_thr; /*!< BR/EDR RSSI threshold for Transmit Clear Channel Assessment (CCA) */
uint8_t max_acl_conn; /*!< Maximum number of BR/EDR ACL connections. Configurable in menuconfig */
uint8_t max_sync_conn; /*!< Maximum number of BR/EDR synchronous connections. Configurable in menuconfig */
uint8_t cpb_tx_link_num; /*!< BR/EDR CPB TX link number */
uint8_t cpb_rx_link_num; /*!< BR/EDR CPB RX link number */
uint8_t bt_sco_datapath; /*!< SCO data path, i.e. HCI(0) or PCM(1) */
uint8_t hci_tl_type; /*!< HCI transport layer, UART, VHCI, etc */
void *hci_tl_funcs; /*!< hci transport functions used, must be set when hci_tl_type is UART */
uint32_t cfg_mask; /*!< reserved */
uint32_t hw_target_code; /*!< hardware target */
int8_t acl_min_tx_pwr; /*!< Default transmit power for ACL minimum */
int8_t acl_max_tx_pwr; /*!< Default transmit power for ACL maximum */
int8_t apb_tx_pwr; /*!< Default transmit power for APB */
int8_t page_tx_pwr; /*!< Default transmit power for Page */
int8_t pscan_tx_pwr; /*!< Default transmit power for Page Scan */
int8_t iscan_tx_pwr; /*!< Default transmit power for Inquiry Scan */
int8_t cpb_tx_pwr; /*!< Default transmit power for CPB TX */
int8_t strain_tx_pwr; /*!< Default transmit power for Synchronization Train */
uint8_t rf_hw_type; /*!< RF hardware type */
uint8_t static_aclu_tx_buf_nb; /*!< Static ACL-U TX buffer number */
uint8_t dynamic_aclu_tx_buf_nb; /*!< Dynamic ACL-U TX buffer number */
uint8_t aclu_rx_buf_nb; /*!< ACL-U RX buffer number */
uint8_t sync_tx_buf_nb; /*!< SCO TX buffer number */
uint8_t sync_rx_buf_nb; /*!< SCO RX buffer number */
uint8_t esco_ev4_supp : 1; /*!< eSCO support EV4 packet type */
uint8_t esco_ev5_supp : 1; /*!< eSCO support EV5 packet type */
uint8_t esco_ev3_2_supp : 1; /*!< eSCO support 2-EV3 packet type */
uint8_t esco_ev3_3_supp : 1; /*!< eSCO support 3-EV3 packet type */
uint8_t esco_3_slots_supp : 1; /*!< eSCO support 2-EV5 and/or 3-EV5 packet type */
uint8_t bt_legacy_auth_vs_evt :1; /*!< 1 if BR/EDR Legacy Authentication Vendor Specific Event is enabled, which is required to protect from BIAS attack; 0 otherwise. Configurable in menuconfig */
uint8_t inq_filter_en : 1; /*!< Enable inquiry result filter */
uint8_t dtm_en :1; /*!< BR/EDR direct test mode */
uint32_t mempool_size; /*!< Required mempool size used in BR/EDR controller */
struct orca_mempool_ops *mempool_ops; /*!< mempool operations used in BR/EDR controller */
uint32_t bredr_magic; /*!< Magic number */
} esp_bredr_controller_config_t;
/**
* @brief BTDM controller common configuration options
*/
typedef struct {
uint32_t version; /*!< Version number of the defined structure */
uint16_t task_stack_size; /*!< Size of Bluetooth controller task stack */
uint8_t task_prio; /*!< Priority of the Bluetooth controller task */
uint8_t task_run_cpu; /*!< CPU number on which the Bluetooth controller task runs */
uint8_t hci_cmd_num; /*!< HCI command buffer number */
uint8_t hci_conn_num; /*!< HCI level connection number */
uint8_t sleep_en; /*!< Enable sleep functionality */
uint8_t version_num; /*!< Hardware version number of this chip */
uint8_t bluetooth_mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
uint32_t magic; /*!< Magic number for configuration validation */
} esp_btdm_controller_config_t;
/**
* @brief Controller config options, depend on config mask.
* Config mask indicate which functions enabled, this means
* some options or parameters of some functions enabled by config mask.
*/
typedef struct {
/**
* @brief Bluetooth LE controller configuration options
*/
struct {
uint32_t config_version; /*!< Version number of the defined structure */
uint16_t ble_ll_resolv_list_size; /*!< Size of the resolvable private address list */
uint16_t ble_hci_evt_hi_buf_count; /*!< Count of high buffers for HCI events */
uint16_t ble_hci_evt_lo_buf_count; /*!< Count of low buffers for HCI events */
uint8_t ble_ll_sync_list_cnt; /*!< Number of synchronization lists */
uint8_t ble_ll_sync_cnt; /*!< Number of synchronizations */
uint16_t ble_ll_rsp_dup_list_count; /*!< Count of duplicated lists for scan response packets */
uint16_t ble_ll_adv_dup_list_count; /*!< Count of duplicated lists for advertising packets */
uint8_t ble_ll_tx_pwr_dbm; /*!< Tx power (transmit power) in dBm */
uint64_t rtc_freq; /*!< Frequency of RTC (Real-Time Clock) */
uint16_t ble_ll_sca; /*!< Sleep Clock Accuracy (SCA) parameter */
uint8_t ble_ll_scan_phy_number; /*!< Number of PHYs supported for scanning */
uint16_t ble_ll_conn_def_auth_pyld_tmo; /*!< Connection default authentication payload timeout */
uint8_t ble_ll_jitter_usecs; /*!< Jitter time in microseconds */
uint16_t ble_ll_sched_max_adv_pdu_usecs; /*!< Maximum time in microseconds for advertising PDU scheduling */
uint16_t ble_ll_sched_direct_adv_max_usecs; /*!< Maximum time in microseconds for directed advertising scheduling */
uint16_t ble_ll_sched_adv_max_usecs; /*!< Maximum time in microseconds for advertising scheduling */
uint16_t ble_scan_rsp_data_max_len; /*!< Maximum length of scan response data */
uint8_t ble_ll_cfg_num_hci_cmd_pkts; /*!< Number of HCI command packets that can be queued */
uint32_t ble_ll_ctrl_proc_timeout_ms; /*!< Control processing timeout in milliseconds */
uint16_t nimble_max_connections; /*!< Maximum number of connections supported */
uint8_t ble_whitelist_size; /*!< Size of the white list */
uint16_t ble_acl_buf_size; /*!< Buffer size of ACL (Asynchronous Connection-Less) data */
uint16_t ble_acl_buf_count; /*!< Buffer count of ACL data */
uint16_t ble_hci_evt_buf_size; /*!< Buffer size for HCI event data */
uint16_t ble_multi_adv_instances; /*!< Number of advertising instances */
uint16_t ble_ext_adv_max_size; /*!< Maximum size of extended advertising data */
uint16_t controller_task_stack_size; /*!< Size of Bluetooth controller task stack, to be removed */
uint8_t controller_task_prio; /*!< Priority of the Bluetooth task, to be removed */
uint8_t controller_run_cpu; /*!< CPU number on which the Bluetooth controller task runs, to be removed */
uint8_t enable_qa_test; /*!< Enable for QA test */
uint8_t enable_bqb_test; /*!< Enable for BQB test */
uint8_t enable_tx_cca; /*!< Enable Clear Channel Assessment (CCA) when transmitting */
uint8_t cca_rssi_thresh; /*!< RSSI threshold for CCA */
uint8_t sleep_en; /*!< Enable sleep functionality */
uint8_t coex_phy_coded_tx_rx_time_limit; /*!< Coexistence PHY coded TX and RX time limit */
uint8_t dis_scan_backoff; /*!< Disable scan backoff */
uint8_t ble_scan_classify_filter_enable; /*!< Enable classification filter for BLE scan */
uint8_t cca_drop_mode; /*!< CCA drop mode */
int8_t cca_low_tx_pwr; /*!< Low TX power setting for CCA */
uint8_t main_xtal_freq; /*!< Main crystal frequency */
uint8_t ignore_wl_for_direct_adv; /*!< Ignore the white list for directed advertising */
uint8_t enable_pcl; /*!< Enable power control */
uint8_t csa2_select; /*!< Select CSA2 */
uint8_t enable_csr; /*!< Enable connection subrate */
int8_t backoff_rssi; /*!< Set the lowest rssi threshold for backoff */
bool iso_enabled; /*!< Enable ISO */
bool iso_bqb_test; /*!< Enable ISO BQB test */
bool iso_fra_unseg; /*!< Enable ISO FRA unsegmented */
bool iso_nsfc_en; /*!< Enable ISO NSCF */
uint8_t iso_nsfc_num; /*!< Number of ISO NSCF */
uint8_t iso_buf_count; /*!< Number of ISO buffer */
uint16_t iso_buf_size; /*!< Size of ISO buffer */
uint8_t iso_big_count; /*!< Number of ISO big */
uint16_t iso_bis_count; /*!< Number of ISO bis */
uint8_t iso_bis_per_big; /*!< Number of ISO bis per big */
uint8_t iso_cig_count; /*!< Number of ISO cig */
uint16_t iso_cis_count; /*!< Number of ISO cis */
uint8_t iso_cis_per_cig; /*!< Number of ISO cis per cig */
uint32_t config_magic; /*!< Configuration magic value */
} ble; /*!< Bluetooth LE controller configuration options */
/**
* @brief Bluetooth Classic controller configuration options
*/
esp_bredr_controller_config_t bredr; /*!< Bluetooth Classic controller configuration options */
/**
* @brief Bluetooth controller common configuration options
*/
esp_btdm_controller_config_t btdm; /*!< Bluetooth controller common configuration options */
} esp_bt_controller_config_t;
#if defined(CONFIG_BTDM_CTRL_MODE_BLE_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE
#elif defined(CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY)
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_CLASSIC_BT
#else
#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BTDM
#endif
#if defined(CONFIG_BT_LE_ISO_SUPPORT)
#define DEFAULT_BT_LE_ISO_ENABLED 1
#if defined(CONFIG_BT_LE_ISO_FRA_UNSEG)
#define DEFAULT_BT_LE_ISO_FRA_UNSEG CONFIG_BT_LE_ISO_FRA_UNSEG
#else
#define DEFAULT_BT_LE_ISO_FRA_UNSEG (0)
#endif
#if defined(CONFIG_BT_LE_ISO_NSFC_EN)
#define DEFAULT_BT_LE_ISO_NSFC_EN CONFIG_BT_LE_ISO_NSFC_EN
#define DEFAULT_BT_LE_ISO_NSFC_NUM CONFIG_BT_LE_ISO_NSFC_NUM
#else
#define DEFAULT_BT_LE_ISO_NSFC_EN (0)
#define DEFAULT_BT_LE_ISO_NSFC_NUM (0)
#endif
#define DEFAULT_BT_LE_ISO_BUF_COUNT CONFIG_BT_LE_ISO_BUF_COUNT
#define DEFAULT_BT_LE_ISO_BUF_SIZE CONFIG_BT_LE_ISO_BUF_SIZE
#define DEFAULT_BT_LE_ISO_BIG CONFIG_BT_LE_ISO_BIG
#define DEFAULT_BT_LE_ISO_BIS CONFIG_BT_LE_ISO_BIS
#define DEFAULT_BT_LE_ISO_BIS_PER_BIG CONFIG_BT_LE_ISO_BIS_PER_BIG
#define DEFAULT_BT_LE_ISO_CIG CONFIG_BT_LE_ISO_CIG
#define DEFAULT_BT_LE_ISO_CIS CONFIG_BT_LE_ISO_CIS
#define DEFAULT_BT_LE_ISO_CIS_PER_CIG CONFIG_BT_LE_ISO_CIS_PER_CIG
#else
#define DEFAULT_BT_LE_ISO_ENABLED 0
#define DEFAULT_BT_LE_ISO_FRA_UNSEG 0
#define DEFAULT_BT_LE_ISO_NSFC_EN 0
#define DEFAULT_BT_LE_ISO_NSFC_NUM 0
#define DEFAULT_BT_LE_ISO_BUF_COUNT 0
#define DEFAULT_BT_LE_ISO_BUF_SIZE 0
#define DEFAULT_BT_LE_ISO_BIG 0
#define DEFAULT_BT_LE_ISO_BIS 0
#define DEFAULT_BT_LE_ISO_BIS_PER_BIG 0
#define DEFAULT_BT_LE_ISO_CIG 0
#define DEFAULT_BT_LE_ISO_CIS 0
#define DEFAULT_BT_LE_ISO_CIS_PER_CIG 0
#endif
#if CONFIG_BTDM_CTRL_MODE_BTDM
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.ble = { \
.config_version = BLE_CONFIG_VERSION, \
.ble_ll_resolv_list_size = CONFIG_BT_LE_LL_RESOLV_LIST_SIZE, \
.ble_hci_evt_hi_buf_count = DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT, \
.ble_hci_evt_lo_buf_count = DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT, \
.ble_ll_sync_list_cnt = DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST, \
.ble_ll_sync_cnt = DEFAULT_BT_LE_MAX_PERIODIC_SYNCS, \
.ble_ll_rsp_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
.ble_ll_adv_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
.ble_ll_tx_pwr_dbm = 0, \
.rtc_freq = 32000, \
.ble_ll_sca = CONFIG_BT_LE_LL_SCA, \
.ble_ll_scan_phy_number = BLE_LL_SCAN_PHY_NUMBER_N, \
.ble_ll_conn_def_auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N, \
.ble_ll_jitter_usecs = BLE_LL_JITTER_USECS_N, \
.ble_ll_sched_max_adv_pdu_usecs = BLE_LL_SCHED_MAX_ADV_PDU_USECS_N, \
.ble_ll_sched_direct_adv_max_usecs = BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N, \
.ble_ll_sched_adv_max_usecs = BLE_LL_SCHED_ADV_MAX_USECS_N, \
.ble_scan_rsp_data_max_len = DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N, \
.ble_ll_cfg_num_hci_cmd_pkts = BLE_LL_CFG_NUM_HCI_CMD_PKTS_N, \
.ble_ll_ctrl_proc_timeout_ms = BLE_LL_CTRL_PROC_TIMEOUT_MS_N, \
.nimble_max_connections = DEFAULT_BT_LE_MAX_CONNECTIONS, \
.ble_whitelist_size = DEFAULT_BT_NIMBLE_WHITELIST_SIZE, \
.ble_acl_buf_size = DEFAULT_BT_LE_ACL_BUF_SIZE, \
.ble_acl_buf_count = DEFAULT_BT_LE_ACL_BUF_COUNT, \
.ble_hci_evt_buf_size = DEFAULT_BT_LE_HCI_EVT_BUF_SIZE, \
.ble_multi_adv_instances = DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES, \
.ble_ext_adv_max_size = DEFAULT_BT_LE_EXT_ADV_MAX_SIZE, \
.controller_task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.controller_run_cpu = 0, \
.enable_qa_test = RUN_QA_TEST, \
.enable_bqb_test = RUN_BQB_TEST, \
.enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \
.cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
.coex_phy_coded_tx_rx_time_limit = DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
.dis_scan_backoff = NIMBLE_DISABLE_SCAN_BACKOFF, \
.ble_scan_classify_filter_enable = 1, \
.main_xtal_freq = CONFIG_XTAL_FREQ, \
.ignore_wl_for_direct_adv = 0, \
.enable_pcl = 0, \
.csa2_select = 1, \
.enable_csr = 0, \
.backoff_rssi = -100, \
.iso_enabled = DEFAULT_BT_LE_ISO_ENABLED, \
.iso_bqb_test = false, \
.iso_fra_unseg = DEFAULT_BT_LE_ISO_FRA_UNSEG, \
.iso_nsfc_en = DEFAULT_BT_LE_ISO_NSFC_EN, \
.iso_nsfc_num = DEFAULT_BT_LE_ISO_NSFC_NUM, \
.iso_buf_count = DEFAULT_BT_LE_ISO_BUF_COUNT, \
.iso_buf_size = DEFAULT_BT_LE_ISO_BUF_SIZE, \
.iso_big_count = DEFAULT_BT_LE_ISO_BIG, \
.iso_bis_count = DEFAULT_BT_LE_ISO_BIS, \
.iso_bis_per_big = DEFAULT_BT_LE_ISO_BIS_PER_BIG, \
.iso_cig_count = DEFAULT_BT_LE_ISO_CIG, \
.iso_cis_count = DEFAULT_BT_LE_ISO_CIS, \
.iso_cis_per_cig = DEFAULT_BT_LE_ISO_CIS_PER_CIG, \
.config_magic = BLE_CONFIG_MAGIC, \
}, \
.bredr = { \
.bredr_version = ESP_BREDR_CTRL_CONFIG_VERSION, \
.sleep_mode = 0, \
.bt_test_mode_en = UC_BR_EDR_TEST_MODE_EN, \
.acl_cca_en = UC_BR_EDR_TX_CCA_EN, \
.cca_rssi_thr = -UC_BR_EDR_CCA_RSSI_THRESH, \
.max_acl_conn = UC_BR_EDR_MAX_ACL_CONN, \
.max_sync_conn = UC_BR_EDR_CTRL_MAX_SYNC_CONN, \
.cpb_tx_link_num = UC_BR_EDR_CPB_TX_LINK_NB, \
.cpb_rx_link_num = UC_BR_EDR_CPB_RX_LINK_NB, \
.bt_sco_datapath = UC_BR_EDR_SCO_DATA_PATH, \
.hci_tl_type = 0, \
.hci_tl_funcs = NULL, \
.cfg_mask = 0, \
.hw_target_code = 0, \
.acl_min_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MIN, \
.acl_max_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MAX, \
.apb_tx_pwr = UC_BR_EDR_TX_PWR_APB, \
.page_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_PAGE, \
.pscan_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_PSCAN, \
.iscan_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ISCAN, \
.cpb_tx_pwr = UC_BR_EDR_TX_PWR_CPB, \
.strain_tx_pwr = UC_BR_EDR_TX_PWR_STRAIN, \
.rf_hw_type = 0, \
.static_aclu_tx_buf_nb = UC_BR_EDR_ACLU_TX_BUF_NB - UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB, \
.dynamic_aclu_tx_buf_nb = UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB, \
.aclu_rx_buf_nb = UC_BR_EDR_ACLU_RX_BUF_NB, \
.sync_tx_buf_nb = UC_BR_EDR_SYNC_TX_BUF_NB, \
.sync_rx_buf_nb = UC_BR_EDR_SYNC_RX_BUF_NB, \
.esco_ev4_supp = UC_BR_EDR_ESCO_EV4_SUPP, \
.esco_ev5_supp = UC_BR_EDR_ESCO_EV5_SUPP, \
.esco_ev3_2_supp = UC_BR_EDR_ESCO_EV3_2_SUPP, \
.esco_ev3_3_supp = UC_BR_EDR_ESCO_EV3_3_SUPP, \
.esco_3_slots_supp = UC_BR_EDR_ESCO_3_SLOTS_SUPP, \
.bt_legacy_auth_vs_evt = UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT, \
.inq_filter_en = 0, \
.dtm_en = 0, \
.bredr_magic = ESP_BREDR_CTRL_CONFIG_MAGIC_VAL, \
}, \
.btdm = { \
.version = BTDM_CONFIG_VERSION, \
.task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
.task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.task_run_cpu = CONFIG_BT_CTRL_PINNED_TO_CORE, \
.hci_cmd_num = CONFIG_BT_CTRL_HCI_CMD_NUM, \
.hci_conn_num = DEFAULT_BT_LE_MAX_CONNECTIONS + DEFAULT_BT_LE_ISO_CIS + DEFAULT_BT_LE_ISO_BIS + \
UC_BR_EDR_MAX_ACL_CONN + UC_BR_EDR_CTRL_MAX_SYNC_CONN, \
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
.version_num = 0, \
.bluetooth_mode = BTDM_CONTROLLER_MODE_EFF, \
.magic = BTDM_CONFIG_MAGIC_VALUE, \
}, \
}
#elif CONFIG_BTDM_CTRL_MODE_BLE_ONLY
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.ble = { \
.config_version = BLE_CONFIG_VERSION, \
.ble_ll_resolv_list_size = CONFIG_BT_LE_LL_RESOLV_LIST_SIZE, \
.ble_hci_evt_hi_buf_count = DEFAULT_BT_LE_HCI_EVT_HI_BUF_COUNT, \
.ble_hci_evt_lo_buf_count = DEFAULT_BT_LE_HCI_EVT_LO_BUF_COUNT, \
.ble_ll_sync_list_cnt = DEFAULT_BT_LE_MAX_PERIODIC_ADVERTISER_LIST, \
.ble_ll_sync_cnt = DEFAULT_BT_LE_MAX_PERIODIC_SYNCS, \
.ble_ll_rsp_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
.ble_ll_adv_dup_list_count = CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT, \
.ble_ll_tx_pwr_dbm = 0, \
.rtc_freq = 32000, \
.ble_ll_sca = CONFIG_BT_LE_LL_SCA, \
.ble_ll_scan_phy_number = BLE_LL_SCAN_PHY_NUMBER_N, \
.ble_ll_conn_def_auth_pyld_tmo = BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N, \
.ble_ll_jitter_usecs = BLE_LL_JITTER_USECS_N, \
.ble_ll_sched_max_adv_pdu_usecs = BLE_LL_SCHED_MAX_ADV_PDU_USECS_N, \
.ble_ll_sched_direct_adv_max_usecs = BLE_LL_SCHED_DIRECT_ADV_MAX_USECS_N, \
.ble_ll_sched_adv_max_usecs = BLE_LL_SCHED_ADV_MAX_USECS_N, \
.ble_scan_rsp_data_max_len = DEFAULT_BT_LE_SCAN_RSP_DATA_MAX_LEN_N, \
.ble_ll_cfg_num_hci_cmd_pkts = BLE_LL_CFG_NUM_HCI_CMD_PKTS_N, \
.ble_ll_ctrl_proc_timeout_ms = BLE_LL_CTRL_PROC_TIMEOUT_MS_N, \
.nimble_max_connections = DEFAULT_BT_LE_MAX_CONNECTIONS, \
.ble_whitelist_size = DEFAULT_BT_NIMBLE_WHITELIST_SIZE, \
.ble_acl_buf_size = DEFAULT_BT_LE_ACL_BUF_SIZE, \
.ble_acl_buf_count = DEFAULT_BT_LE_ACL_BUF_COUNT, \
.ble_hci_evt_buf_size = DEFAULT_BT_LE_HCI_EVT_BUF_SIZE, \
.ble_multi_adv_instances = DEFAULT_BT_LE_MAX_EXT_ADV_INSTANCES, \
.ble_ext_adv_max_size = DEFAULT_BT_LE_EXT_ADV_MAX_SIZE, \
.controller_task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.controller_run_cpu = 0, \
.enable_qa_test = RUN_QA_TEST, \
.enable_bqb_test = RUN_BQB_TEST, \
.enable_tx_cca = DEFAULT_BT_LE_TX_CCA_ENABLED, \
.cca_rssi_thresh = 256 - DEFAULT_BT_LE_CCA_RSSI_THRESH, \
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
.coex_phy_coded_tx_rx_time_limit = DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
.dis_scan_backoff = NIMBLE_DISABLE_SCAN_BACKOFF, \
.ble_scan_classify_filter_enable = 1, \
.main_xtal_freq = CONFIG_XTAL_FREQ, \
.ignore_wl_for_direct_adv = 0, \
.enable_pcl = 0, \
.csa2_select = 1, \
.enable_csr = 0, \
.backoff_rssi = -100, \
.iso_enabled = DEFAULT_BT_LE_ISO_ENABLED, \
.iso_bqb_test = false, \
.iso_fra_unseg = DEFAULT_BT_LE_ISO_FRA_UNSEG, \
.iso_nsfc_en = DEFAULT_BT_LE_ISO_NSFC_EN, \
.iso_nsfc_num = DEFAULT_BT_LE_ISO_NSFC_NUM, \
.iso_buf_count = DEFAULT_BT_LE_ISO_BUF_COUNT, \
.iso_buf_size = DEFAULT_BT_LE_ISO_BUF_SIZE, \
.iso_big_count = DEFAULT_BT_LE_ISO_BIG, \
.iso_bis_count = DEFAULT_BT_LE_ISO_BIS, \
.iso_bis_per_big = DEFAULT_BT_LE_ISO_BIS_PER_BIG, \
.iso_cig_count = DEFAULT_BT_LE_ISO_CIG, \
.iso_cis_count = DEFAULT_BT_LE_ISO_CIS, \
.iso_cis_per_cig = DEFAULT_BT_LE_ISO_CIS_PER_CIG, \
.config_magic = BLE_CONFIG_MAGIC, \
}, \
.bredr = { 0 }, \
.btdm = { \
.version = BTDM_CONFIG_VERSION, \
.task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
.task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.task_run_cpu = CONFIG_BT_CTRL_PINNED_TO_CORE, \
.hci_cmd_num = CONFIG_BT_CTRL_HCI_CMD_NUM, \
.hci_conn_num = DEFAULT_BT_LE_MAX_CONNECTIONS + DEFAULT_BT_LE_ISO_CIS + DEFAULT_BT_LE_ISO_BIS, \
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
.version_num = 0, \
.bluetooth_mode = BTDM_CONTROLLER_MODE_EFF, \
.magic = BTDM_CONFIG_MAGIC_VALUE, \
}, \
}
#elif CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.ble = { 0 }, \
.bredr = { \
.bredr_version = ESP_BREDR_CTRL_CONFIG_VERSION, \
.sleep_mode = 0, \
.bt_test_mode_en = UC_BR_EDR_TEST_MODE_EN, \
.acl_cca_en = UC_BR_EDR_TX_CCA_EN, \
.cca_rssi_thr = -UC_BR_EDR_CCA_RSSI_THRESH, \
.max_acl_conn = UC_BR_EDR_MAX_ACL_CONN, \
.max_sync_conn = UC_BR_EDR_CTRL_MAX_SYNC_CONN, \
.cpb_tx_link_num = UC_BR_EDR_CPB_TX_LINK_NB, \
.cpb_rx_link_num = UC_BR_EDR_CPB_RX_LINK_NB, \
.bt_sco_datapath = UC_BR_EDR_SCO_DATA_PATH, \
.hci_tl_type = 0, \
.hci_tl_funcs = NULL, \
.cfg_mask = 0, \
.hw_target_code = 0, \
.acl_min_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MIN, \
.acl_max_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MAX, \
.apb_tx_pwr = UC_BR_EDR_TX_PWR_APB, \
.page_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_PAGE, \
.pscan_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_PSCAN, \
.iscan_tx_pwr = CONFIG_BT_CTRL_BR_EDR_TX_PWR_ISCAN, \
.cpb_tx_pwr = UC_BR_EDR_TX_PWR_CPB, \
.strain_tx_pwr = UC_BR_EDR_TX_PWR_STRAIN, \
.rf_hw_type = 0, \
.static_aclu_tx_buf_nb = UC_BR_EDR_ACLU_TX_BUF_NB - UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB, \
.dynamic_aclu_tx_buf_nb = UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB, \
.aclu_rx_buf_nb = UC_BR_EDR_ACLU_RX_BUF_NB, \
.sync_tx_buf_nb = UC_BR_EDR_SYNC_TX_BUF_NB, \
.sync_rx_buf_nb = UC_BR_EDR_SYNC_RX_BUF_NB, \
.esco_ev4_supp = UC_BR_EDR_ESCO_EV4_SUPP, \
.esco_ev5_supp = UC_BR_EDR_ESCO_EV5_SUPP, \
.esco_ev3_2_supp = UC_BR_EDR_ESCO_EV3_2_SUPP, \
.esco_ev3_3_supp = UC_BR_EDR_ESCO_EV3_3_SUPP, \
.esco_3_slots_supp = UC_BR_EDR_ESCO_3_SLOTS_SUPP, \
.bt_legacy_auth_vs_evt = UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT, \
.inq_filter_en = 0, \
.dtm_en = 0, \
.bredr_magic = ESP_BREDR_CTRL_CONFIG_MAGIC_VAL, \
}, \
.btdm = { \
.version = BTDM_CONFIG_VERSION, \
.task_stack_size = UC_BT_CTRL_TASK_STACK_SIZE, \
.task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
.task_run_cpu = CONFIG_BT_CTRL_PINNED_TO_CORE, \
.hci_cmd_num = CONFIG_BT_CTRL_HCI_CMD_NUM, \
.hci_conn_num = UC_BR_EDR_MAX_ACL_CONN + UC_BR_EDR_CTRL_MAX_SYNC_CONN, \
.sleep_en = UC_BT_CTRL_SLEEP_ENABLE, \
.version_num = 0, \
.bluetooth_mode = BTDM_CONTROLLER_MODE_EFF, \
.magic = BTDM_CONFIG_MAGIC_VALUE, \
}, \
}
#endif
/**
* @brief Set BLE TX power
* Connection Tx power should only be set after connection created.
* @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc
* @param power_level: Power level(index) corresponding to absolute value(dbm)
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level);
/**
* @brief Get BLE TX power
* Connection Tx power should only be get after connection created.
* @param power_type : The type of which tx power, could set Advertising/Connection/Default and etc
* @return >= 0 - Power level, < 0 - Invalid
*/
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
/**
* @brief ENHANCED API for Setting BLE TX power
* Connection Tx power should only be set after connection created.
* @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc
* @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types.
* @param power_level: Power level(index) corresponding to absolute value(dbm)
* @return ESP_OK - success, other - failed
*/
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);
/**
* @brief ENHANCED API of Getting BLE TX power
* Connection Tx power should only be get after connection created.
* @param power_type : The enhanced type of which tx power, could set Advertising/Connection/Default and etc
* @param handle : The handle of Advertising or Connection and the value 0 for other enhanced power types.
* @return >= 0 - Power level, < 0 - Invalid
*/
esp_power_level_t esp_ble_tx_power_get_enhanced(esp_ble_enhanced_power_type_t power_type, uint16_t handle);
/**
* @brief Initialize BT controller to allocate task and other resource.
* This function should be called only once, before any other BT functions are called.
* @param cfg: Initial configuration of BT controller. Different from previous version, there's a mode and some
* connection configuration in "cfg" to configure controller work mode and allocate the resource which is needed.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg);
/**
* @brief Get BT controller is initialised/de-initialised/enabled/disabled
* @return status value
*/
esp_bt_controller_status_t esp_bt_controller_get_status(void);
/**
* @brief De-initialize BT controller to free resource and delete task.
* You should stop advertising and scanning, as well as
* disconnect all existing connections before de-initializing BT controller.
*
* This function should be called only once, after any other BT functions are called.
* This function is not whole completed, esp_bt_controller_init cannot called after this function.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_deinit(void);
/**
* @brief Enable BT controller.
* Due to a known issue, you cannot call esp_bt_controller_enable() a second time
* to change the controller mode dynamically. To change controller mode, call
* esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.
* @param mode : the mode(BLE/BT/BTDM) to enable. For compatible of API, retain this argument. This mode must be
* equal as the mode in "cfg" of esp_bt_controller_init().
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
/**
* @brief Disable BT controller
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_disable(void);
/** @brief esp_vhci_host_callback
* used for vhci call host function to notify what host need to do
*/
typedef struct esp_vhci_host_callback {
void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/
} esp_vhci_host_callback_t;
/** @brief esp_vhci_host_check_send_available
* used for check actively if the host can send packet to controller or not.
* @return true for ready to send, false means cannot send packet
*/
bool esp_vhci_host_check_send_available(void);
/** @brief esp_vhci_host_send_packet
* host send packet to controller
*
* Should not call this function from within a critical section
* or when the scheduler is suspended.
*
* @param data the packet point
* @param len the packet length
*/
void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
/** @brief esp_vhci_host_register_callback
* register the vhci reference callback
* struct defined by vhci_host_callback structure.
* @param callback esp_vhci_host_callback type variable
* @return ESP_OK - success, ESP_FAIL - failed
*/
esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
/** @brief esp_bt_controller_mem_release
* release the controller memory as per the mode
*
* This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
*
* esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
* or after esp_bt_controller_deinit().
*
* Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If the app calls esp_bt_controller_enable(ESP_BT_MODE_BLE) to use BLE only then it is safe to call
* esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT) at initialization time to free unused BT Classic memory.
*
* If the mode is ESP_BT_MODE_BTDM, then it may be useful to call API esp_bt_mem_release(ESP_BT_MODE_BTDM) instead,
* which internally calls esp_bt_controller_mem_release(ESP_BT_MODE_BTDM) and additionally releases the BSS and data
* consumed by the BT/BLE host stack to heap. For more details about usage please refer to the documentation of
* esp_bt_mem_release() function
*
* @param mode : the mode want to release memory
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode);
/** @brief esp_bt_mem_release
* release controller memory and BSS and data section of the BT/BLE host stack as per the mode
*
* This function first releases controller memory by internally calling esp_bt_controller_mem_release().
* Additionally, if the mode is set to ESP_BT_MODE_BTDM, it also releases the BSS and data consumed by the BT/BLE host stack to heap
*
* Note that once BT memory is released, the process cannot be reversed. It means you cannot use the bluetooth
* mode which you have released by this function.
*
* If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
* then do not call this function.
*
* If you never intend to use bluetooth in a current boot-up cycle, you can call esp_bt_mem_release(ESP_BT_MODE_BTDM)
* before esp_bt_controller_init or after esp_bt_controller_deinit.
*
* For example, if a user only uses bluetooth for setting the WiFi configuration, and does not use bluetooth in the rest of the product operation".
* In such cases, after receiving the WiFi configuration, you can disable/deinit bluetooth and release its memory.
* Below is the sequence of APIs to be called for such scenarios:
*
* esp_bluedroid_disable();
* esp_bluedroid_deinit();
* esp_bt_controller_disable();
* esp_bt_controller_deinit();
* esp_bt_mem_release(ESP_BT_MODE_BTDM);
*
* @param mode : the mode whose memory is to be released
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode);
/**
* @brief Returns random static address or -1 if not present.
* @return ESP_OK - success, other - failed
*/
extern int esp_ble_hw_get_static_addr(esp_ble_addr_t *addr);
#if CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
/**
* @brief dump all log information cached in buffers.
* @param output : true for log dump, false will take no effect
*/
void esp_ble_controller_log_dump_all(bool output);
#endif // CONFIG_BT_LE_CONTROLLER_LOG_ENABLED
#ifdef __cplusplus
}
#endif
#endif /* __ESP_BT_H__ */
@@ -0,0 +1,442 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
// @brief HCI VS Commands for Espressif's Bluetooth Host
//
// @note The following vendor-specific HCI commands are exclusively for Espressif's Bluetooth Host (ESP-Bluedroid Host or ESP-NimBLE Host).
// If you are using a non-ESP host or HCI UART, these commands will remain disabled unless the initialization function is explicitly called from the application.
// Note, these init functions as well as these additional HCI VS commands are intended for Espressif's Bluetooth Host use only.
// Application developers **should not** call the init functions in their applications.
//
/**
* @brief Config scanning duplicate exceptional list (OCF: 0x0108)
*
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
*/
#define ESP_BT_VS_CONFIG_DUP_EXC_LIST_OCF (0x0108)
/**
* @brief Update exception list cmd parameters
*/
struct bt_hci_vs_update_exc_list {
uint8_t subcode; /*!< Add, remove or clear exception list */
uint32_t type; /*!< device type */
uint8_t device_info[6]; /*!< device information */
};
/**
* @brief Enable/disable advertising report flow control (OCF: 0x0109)
*
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
*/
#define ESP_BT_VS_SET_ADV_REPORT_FLOW_CTRL_OCF (0x0109)
/**
* @brief Init ADV flow control cmd parameters
*/
struct bt_hci_vs_init_adv_flow_ctrl {
uint8_t enable; /*!< Enable ADV flow control */
uint16_t num; /*!< ADV buffer maximum value */
uint16_t adv_lost_threshold; /*!< ADV lost event triggered threshold */
};
/**
* @brief Update the number of advertising report in ADV flow control (OCF: 0x010A)
*
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
*/
#define ESP_BT_VS_UPD_ADV_REPORT_FLOW_CTRL_NUM_OCF (0x010a)
/**
* @brief Update ADV flow control cmd parameters
*/
struct bt_hci_vs_update_adv_flow_ctrl {
uint16_t num; /*!< The number of ADV report processed */
};
/**
* @brief Clear legacy advertising (same as HCI_LE_Clear_Advertising_Sets) (OCF: 0x010C)
*
* @note The init function is `adv_stack_enableClearLegacyAdvVsCmd(true)`
*/
#define ESP_BT_VS_CLR_LEGACY_ADV_OCF (0x010c)
/**
* @brief Clear legacy ADV cmd parameters
*/
struct bt_hci_vs_ble_clr_legacy_adv {
// no parameters
};
/**
* @brief Set parameters of duplicate list (OCF: 0x010D)
*
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
*/
#define ESP_BT_VS_SET_DUP_LIST_PARAMS_OCF (0x010d)
/**
* @brief Set duplicate list cmd parameters
*/
struct bt_hci_vs_ble_set_dup_params {
uint8_t dup_mode; /*!< Duplicate mode */
uint8_t dup_ad_type; /*!< Duplicate data type */
uint16_t ring_list_max_num; /*!< Duplicate list size */
};
/**
* @brief Enable/disable duplicate and exception list (OCF: 0x010E)
*
* @note The init function is `advFilter_stack_eanbleDupExcListCmd(true)`
*/
#define ESP_BT_VS_ENABLE_DUP_EXC_LIST_OCF (0x010e)
/**
* @brief Enable duplicate and exception list cmd parameters
*/
struct bt_hci_vs_ble_enable_dup_exc {
uint8_t enable; /*!< Enable or disable */
uint8_t ring_list_reset; /*!< Reset list */
};
/**
* @brief Enable optimization of multiple connections (OCF: 0x010F)
*
* @note The init function is `arr_stack_enableMultiConnVsCmd(true)`
*/
#define ESP_BT_VS_ENABLE_ARRANGEMENT_OCF (0x010f)
/**
* @brief Multiple connections optimization cmd parameters
*/
struct bt_hci_vs_ble_enable_arrangement {
uint32_t common_factor; /*!< The greatest common factor of connection interval */
uint8_t enable; /*!< Enable or disable */
};
/**
* @brief Set scheduling length for a certain role (OCF: 0x0110)
*
* @note The init function is `arr_stack_enableMultiConnVsCmd(true)`
*/
#define ESP_BT_VS_SET_SCHED_ROLE_LEN_OCF (0x0110)
/**
* @brief Scheduling length cmd parameters
*/
struct bt_hci_vs_ble_set_sched_role_len {
uint8_t role; /*!< BLE role; 0: central; 1: peripheral */
uint32_t len; /*!< Length is us */
};
/**
* @brief Set RSSI threshold for automatic power control (OCF: 0x0111)
*
* @note The init function is `pcl_stack_enableSetRssiThreshVsCmd(true)`
*/
#define ESP_BT_VS_SET_PCL_RSSI_THRESH_OCF (0x0111)
/**
* @brief PCL RSSI threshold cmd parameters
*/
struct bt_hci_vs_ble_set_pcl_rssi_thresh {
uint16_t conn_handle; /*!< Connection handle */
uint8_t rssi_thresh_min_1M; /*!< Lower limit for 1M */
uint8_t rssi_thresh_max_1M; /*!< Upper limit for 1M */
uint8_t rssi_thresh_min_2M; /*!< Lower limit for 2M */
uint8_t rssi_thresh_max_2M; /*!< Upper limit for 2M */
uint8_t rssi_thresh_min_s2coded; /*!< Lower limit for s2 coded */
uint8_t rssi_thresh_max_s2coded; /*!< Upper limit for s2 coded */
uint8_t rssi_thresh_min_s8coded; /*!< Lower limit for s8 coded */
uint8_t rssi_thresh_max_s8coded; /*!< Upper limit for s8 coded */
};
/**
* @brief Enable/disable channel selection algorithm #2 (OCF: 0x0112)
*
* @note The init function is `chanSel_stack_enableSetCsaVsCmd(true)`
*/
#define ESP_BT_VS_ENABLE_CSA2_OCF (0x0112)
/**
* @brief Enable/disable channel selection algorithm #2 cmd parameters
*/
struct bt_hci_vs_ble_csa_enable {
uint8_t csa2_select; /*!< Select CSA2 */
};
/**
* @brief Set parameters of controller logs (OCF: 0x0114)
*
* @note The init function is `log_stack_enableLogsRelatedVsCmd(true)`
*/
#define ESP_BT_VS_SET_LOG_PARAMS_OCF (0x0114)
/**
* @brief Controller logs cmd parameters
*/
struct bt_hci_vs_ble_log_params {
uint8_t type; /*!< Operation type */
uint32_t output_enable; /*!< Enable/disable output */
uint8_t buffer_optoin /*!< Select log buffers */
};
/**
* @brief Set BLE vendor events mask (OCF: 0x0116)
*
* @note The init function is `hci_stack_enableSetVsEvtMaskVsCmd(true)`
*/
#define ESP_BT_VS_SET_LE_VENDOR_EVTS_MASK_OCF (0x0116)
/**
* @brief Set BLE vendor events mask cmd parameters
*/
struct bt_hci_vs_ble_set_vs_evts_mask {
uint32_t evt_masks; /*!< BLE vendor events Mask */
};
/**
* @brief Set peer sleep clock accuracy to a constant value (OCF: 0x0118)
*
* @note The init function is `winWiden_stack_enableSetConstPeerScaVsCmd(true)`
*/
#define ESP_BT_VS_SET_CONST_PEER_SCA_OCF (0x0118)
/**
* @brief Peer constant SCA cmd parameters
*/
struct bt_hci_vs_ble_set_const_peer_sca {
uint16_t peer_sca; /*!< Peer SCA */
};
// @brief HCI VS Events for Espressif's Bluetooth Host
//
// @note The following HCI VS events are exclusively for Espressif's Bluetooth Host (ESP-Bluedroid Host or ESP-NimBLE Host).
// If you are using a non-ESP host or HCI UART, these events will remain disabled unless the initialization function is explicitly called from the application.
// Note, these init functions as well as these additional HCI VS events are intended for Espressif's Bluetooth Host use only.
// Application developers **should not** call the init functions in their applications.
//
/**
* @brief BLE Scan/Connect Request, Aux Connect Response received event (EVTCODE: 0xFF, SUBCODE: 0xC0)
*
* @note The init function is `adv_stack_enableScanReqRxdVsEvent(true)`
*/
#define ESP_BT_VS_LE_CONN_SCAN_REQ_RXED_EVT_SUBCODE (0xC0)
/**
* @brief BLE Scan/Connect Request, Aux Connect Response received event parameters
*/
struct bt_hci_vs_le_conn_scan_req_rxed_evt {
uint8_t evt_type; /*!< Event type; 0: SCAN_REQ; 1: CONN_IND */
uint8_t handle; /*!< Advertisement handle */
uint8_t peer_addr_type; /*!< Peer address type */
uint8_t peer_addr[6]; /*!< Peer address */
};
/**
* @brief BLE Channel Map Update Completion event (EVTCODE: 0xFF, SUBCODE: 0xC1)
*
* @note The init function is `conn_stack_enableChanMapUpdCompVsEvent(true)`
*/
#define ESP_BT_VS_LE_CHAN_UPDATE_COMP_EVT_SUBCODE (0xC1)
/**
* @brief BLE Channel Map Update Completion event parameters
*/
struct bt_hci_vs_le_chan_update_comp_evt {
uint8_t status; /*!< Controller error code */
uint16_t handle; /*!< Connection handle */
uint8_t ch_map[5]; /*!< Updated channel map */
};
/**
* @brief BLE Wakeup From Sleep event (EVTCODE: 0xFF, SUBCODE: 0xC3)
*
* @note The init function is `sleep_stack_enableWakeupVsEvent(true)`
*/
#define ESP_BT_VS_LE_SLEEP_WAKEUP_EVT_SUBCODE (0xC3)
/**
* @brief BLE wakeup event parameters
*/
struct bt_hci_vs_le_sleep_wakeup_evt {
// no parameters
};
/**
* @brief BLE advertising report lost event for flow control (EVTCODE: 0x3E, SUBCODE: 0xF0)
*
* @note The init function is `scan_stack_enableAdvFlowCtrlVsCmd(true)`
*/
#define ESP_BT_VS_LE_ADV_LOST_EVT_SUBCODE (0xF0)
/**
* @brief ADV lost event parameters
*/
struct bt_hci_vs_le_adv_lost_evt {
uint32_t nb_lost; /*!< The number of ADV report discarded */
};
/**
* @brief This event indicates legacy authentication is completed by remote device (EVTCODE: 0xFF, SUBCODE: 0x03)
*
* @note The init function is `bt_stack_enableSecCtrlVsCmd(true)`
*/
#define ESP_BT_VS_LEGACY_REM_AUTH_EVT_SUBCODE (0x03)
/**
* @brief legacy remote auth event parameters
*/
struct bt_hci_vs_legacy_rem_auth_evt {
uint16_t conhdl; /*!< connection handle */
};
//
// @brief HCI VS Commands for Espressif's Internal-Use Debugging
//
// @note The following HCI VS debugging commands are implemented in Bluetooth controller pre-compiled libraries.
// These commands are not linked into the application binary, unless the function `esp_ble_internalTestFeaturesEnable(true)`is called from the application.
// They are intended for Espressif's internal use only. Application developers **should not** call `esp_ble_internalTestFeaturesEnable(true)` in their applications.
//
#define ESP_BT_VS_CFG_TEST_RELATED_OCF (0x0113)
#define ESP_BT_VS_CFG_TEST_ENABLE_SUBCMD (0X00)
#define ESP_BT_VS_CFG_TEST_ENABLE_ADV_DELAY_SUBCMD (0X01)
#define ESP_BT_VS_CFG_TEST_SET_PREF_CODED_SUBCMD (0X02)
#define ESP_BT_VS_CFG_TEST_SET_DEFAULT_PRIV_MODE_SUBCMD (0X03)
#define ESP_BT_VS_CFG_TEST_SET_SCAN_FOREVER_SUBCMD (0X04)
#define ESP_BT_VS_CFG_TEST_SET_EXPECTED_PEER_SUBCMD (0X05)
#define ESP_BT_VS_CFG_TEST_GET_ADV_TXED_CNT_SUBCMD (0X06)
#define ESP_BT_VS_CFG_TEST_GET_SCAN_RXED_CNT_SUBCMD (0X07)
#define ESP_BT_VS_CFG_TEST_SET_TXPWR_LVL_SUBCMD (0X08)
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_LVL_SUBCMD (0X09)
#define ESP_BT_VS_CFG_TEST_SET_TXPWR_LVL_ENH_SUBCMD (0X0a)
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_LVL_ENH_SUBCMD (0X0b)
#define ESP_BT_VS_CFG_TEST_IGNORE_WL_FOR_DIR_ADV_SUBCMD (0X0c)
#define ESP_BT_VS_CFG_TEST_GET_ADV_RXED_RSSI_SUBCMD (0X0d)
#define ESP_BT_VS_CFG_TEST_ENABLE_CCA_SUBCMD (0X0e)
#define ESP_BT_VS_CFG_TEST_SET_CCA_WIN_SUBCMD (0X0f)
#define ESP_BT_VS_CFG_TEST_READ_CCA_DATA_SUBCM (0X10)
#define ESP_BT_VS_CFG_TEST_CLEAR_RAND_ADDR_SUBCMD (0X11)
#define ESP_BT_VS_CFG_TEST_GET_MAX_TXPWR_SUBCMD (0X12)
#define ESP_BT_VS_CFG_TEST_GET_TXPWR_RANGE_SUBCMD (0X13)
#define ESP_BT_VS_CFG_TEST_SET_SCAN_AA_SUBCMD (0X14)
#define ESP_BT_VS_CFG_TEST_SET_ADV_AA_SUBCMD (0X15)
#define ESP_BT_VS_CFG_TEST_SET_SCAN_CHAN_SUBCMD (0X16)
#define ESP_BT_VS_CFG_TEST_SKIP_LIGHT_SLEEP_CHECK_SUBCMD (0X17)
#define ESP_BT_VS_CFG_TEST_SET_WAKEUP_OVERHEAD_SUBCMD (0X18)
#define ESP_BT_VS_CFG_TEST_GET_ADV_MIN_ITVL_SUBCMD (0X19)
#define ESP_BT_VS_CFG_TEST_GET_CTRL_STATUS_SUBCMD (0X1a)
#define ESP_BT_VS_CFG_TEST_SET_CONN_PHY_TXPWR_SUBCMD (0X1b)
#define ESP_BT_VS_CFG_TEST_GET_CONN_PHY_TXPWR_SUBCMD (0X1c)
#define ESP_BT_VS_CFG_TEST_GET_RXBUF_EMPTY_CNT_SUBCMD (0X1d)
#define ESP_BT_VS_CFG_TEST_RESTART_SUBCMD (0X1e)
#define ESP_BT_VS_CFG_TEST_ENABLE_RECODE_RX_STATE_SUBCMD (0X1f)
#define ESP_BT_VS_CFG_TEST_GET_RECODE_CNT_SUBCMD (0X20)
#define ESP_BT_VS_CFG_TEST_CLR_RECODE_CNT_SUBCMD (0X21)
#define ESP_BT_VS_CFG_TEST_GET_CTRL_COMPILE_VER_SUBCMD (0X24)
#define ESP_BT_VS_CFG_TEST_SET_AUX_ADV_OFFSET_SUBCMD (0X25)
#define ESP_BT_VS_CFG_TEST_INIT_FLEXIBLE_MODE_SUBCMD (0X26)
#define ESP_BT_VS_CFG_TEST_ENABLE_FLEXIBLE_MODE_SUBCMD (0X27)
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_CONN_ERR_SUBCMD (0X28)
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_ADV_ERR_SUBCMD (0X29)
#define ESP_BT_VS_CFG_TEST_SET_FLEXIBLE_SCAN_ERR_SUBCMD (0X2a)
#define ESP_BT_VS_CFG_TEST_GET_TXED_CRCERR_SUBCMD (0X2c)
#define ESP_BT_VS_CFG_TEST_GET_BACKOFF_UPLIMIT_SUBCMD (0X2d)
#define ESP_BT_VS_CFG_TEST_GET_RXED_ADV_ADI_SUBCMD (0X2f)
#define ESP_BT_VS_CFG_TEST_SET_SCH_RAND_MODE_SUBCMD (0X30)
#define ESP_BT_VS_CFG_TEST_SET_RX_SENS_THRESH_SUBCMD (0X31)
#define ESP_BT_VS_CFG_TEST_CHECK_MSYS_BUF_SUBCMD (0X32)
#define ESP_BT_VS_CFG_TEST_UPDATE_BLE_TIMER_SUBCMD (0X33)
#define ESP_BT_VS_CFG_TEST_UPDATE_BLE_RTC_SUBCMD (0X34)
#define ESP_BT_VS_CFG_TEST_SET_LOCKED_MEM_NUM_SUBCMD (0X35)
#define ESP_BT_VS_CFG_TEST_ALLOW_MEM_ALLOC_SUBCMD (0X36)
#define ESP_BT_VS_CFG_TEST_SET_SCH_RAND_INFO_PTR_SUBCMD (0X37)
#define ESP_BT_VS_CFG_TEST_SET_DIAG_IO_SUBCMD (0X38)
#define ESP_BT_VS_CFG_TEST_SET_AGC_MAX_GAIN_SUBCMD (0X39)
#define ESP_BT_VS_CFG_TEST_ENABLE_CHAN_ASSESS_SUBCMD (0X40)
#define ESP_BT_VS_CFG_TEST_SET_BACKOFF_UPLIMIT_SUBCMD (0X41)
#define ESP_BT_VS_CFG_TEST_SET_CONN_TOP_PRIO_RESV_THRESH_SUBCMD (0X42)
#define ESP_BT_VS_CFG_TEST_SET_TEST_EVT_MSK_SUBCMD (0X43)
#define ESP_BT_VS_CFG_TEST_GET_WAKEUP_TIMEOUT_SUBCMD (0X45)
#define ESP_BT_VS_CFG_TEST_RELATED_SUBCMD_MAX (0Xff)
/**
* @note The init function is `bt_stack_enablePktCtrlVsCmd(true)`
*/
#define ESP_BT_VS_WR_DM1_ENABLE_OCF (0x0181)
/**
* @note The init function is `bt_stack_enableClkCtrlVsCmd(true)`
*/
#define ESP_BT_VS_CLK_UPDATE_OCF (0x0183)
/**
* @note The init function is `bt_stack_enableClkCtrlVsCmd(true)`
*/
#define ESP_BT_VS_PCA_OCF (0x0190)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_SET_AFH_OCF (0x0187)
/**
* @note The init function is `bt_stack_enableBasicVsCmd(true)`
*/
#define ESP_BT_VS_SET_EVT_MASK_OCF (0x0188)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_SET_AFH_REPORTING_MODE_OCF (0x0189)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_MASK_RMT_CHANNEL_CLASSIFICATION_OCF (0x018a)
/**
* @note The init function is `bt_stack_enableDTMVsCmd(true)`
*/
#define ESP_BT_VS_DTM_TX_TEST_START_OCF (0x018c)
/**
* @note The init function is `bt_stack_enableDTMVsCmd(true)`
*/
#define ESP_BT_VS_DTM_RX_TEST_START_OCF (0x018d)
/**
* @note The init function is `bt_stack_enableDTMVsCmd(true)`
*/
#define ESP_BT_VS_DTM_TX_TEST_END_OCF (0x018e)
/**
* @note The init function is `bt_stack_enableDTMVsCmd(true)`
*/
#define ESP_BT_VS_DTM_RX_TEST_END_OCF (0x018f)
//
// @brief HCI VS Events for Espressif's Internal-Use Debugging
//
// @note The following HCI VS debugging events are implemented in Bluetooth controller pre-compiled libraries.
// These events are not linked into the application binary, unless the function `esp_ble_internalTestFeaturesEnable(true)`is called from the application.
// Application developers **should not** call `esp_ble_internalTestFeaturesEnable(true)` in their applications.
//
#define ESP_BT_VS_LE_RUNNING_STATUS_EVT_SUBCODE (0xC3)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_AFH_CHG_EVT_SUBCODE (0x05)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_CH_CLASSIFICATION_EVT_SUBCODE (0x06)
/**
* @note The init function is `bt_stack_enableAfhVsCmd(true)`
*/
#define ESP_BT_VS_CH_CLASSIFICATION_REPORTING_MODE_EVT_SUBCODE (0x07)
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,75 @@
[sections:bt_iram_text]
entries:
.iram1+
[sections:high_perf_iram_text]
entries:
.high_perf_code_iram1+
[sections:adv_fast_execute_code_iram_text]
entries:
.adv_fast_execute_code_iram1+
[scheme:bt_default]
entries:
bt_bss -> dram0_bss
bt_common -> dram0_bss
data -> dram0_data
high_perf_iram_text -> iram0_text
if BT_CTRL_RUN_IN_FLASH_ONLY = y:
bt_iram_text -> flash_text
else:
bt_iram_text -> iram0_text
if BT_LE_CTRL_ADV_FAST_TX_EN = y:
adv_fast_execute_code_iram_text -> iram0_text
else:
adv_fast_execute_code_iram_text -> flash_text
# For the following fragments, order matters for
# 'ALIGN(4) ALIGN(4, post) SURROUND(sym)', which generates:
#
# . = ALIGN(4)
# _sym_start
# ...
# . = ALIGN(4)
# _sym_end
[mapping:bt]
archive: libbt.a
entries:
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (bt_extram_bss);
bt_bss -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> extern_ram ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
else:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_data)
[mapping:ble_app]
archive: libble_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
[mapping:btdm_common_app]
archive: libbtdm_common.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
[mapping:bredr_app]
archive: libbredr_app.a
entries:
* (bt_default);
bt_bss -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_bss),
bt_common -> dram0_bss ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_common),
data -> dram0_data ALIGN(4) ALIGN(4, post) SURROUND(bt_controller_data)
+4 -4
View File
@@ -7,17 +7,17 @@ list(APPEND porting_btdm_srcs ${BTDM_COMMON_SRCS})
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/btdm_common/include")
# ble
if(CONFIG_BTDM_CTRL_MODE_BLE_ONLY OR CONFIG_BTDM_CTRL_MODE_BTDM)
if(CONFIG_BT_CTRL_BLE_ENABLE)
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/ble/include")
file(GLOB_RECURSE BLE_SRCS "controller/ble/src/*.c")
list(APPEND porting_btdm_srcs ${BLE_SRCS})
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/ble/include")
endif()
# bredr
if(CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY OR CONFIG_BTDM_CTRL_MODE_BTDM)
if(CONFIG_BT_CTRL_BREDR_ENABLE)
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/bredr/include")
file(GLOB_RECURSE BREDR_SRCS "controller/bredr/src/*.c")
list(APPEND porting_btdm_srcs ${BREDR_SRCS})
list(APPEND porting_btdm_include_dirs "${CMAKE_CURRENT_SOURCE_DIR}/controller/bredr/include")
endif()
# transport
+11 -3
View File
@@ -37,14 +37,22 @@ config BT_DUAL_MODE_ARCH
bool
default y
config BT_CTRL_BLE_ENABLE
bool
default (BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM)
config BT_CTRL_BREDR_ENABLE
bool
default (BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM)
source "$IDF_PATH/components/bt/porting_btdm/transport/Kconfig.in"
menu "BLE Controller Options"
depends on SOC_BLE_SUPPORTED
depends on SOC_BLE_SUPPORTED && (BTDM_CTRL_MODE_BLE_ONLY || BTDM_CTRL_MODE_BTDM)
source "$IDF_PATH/components/bt/porting_btdm/controller/ble/Kconfig.in"
endmenu
menu "BREDR Controller Options"
depends on SOC_BT_CLASSIC_SUPPORTED
menu "BR/EDR Controller Options"
depends on SOC_BT_CLASSIC_SUPPORTED && (BTDM_CTRL_MODE_BR_EDR_ONLY || BTDM_CTRL_MODE_BTDM)
source "$IDF_PATH/components/bt/porting_btdm/controller/bredr/Kconfig.in"
endmenu
@@ -1502,21 +1502,11 @@ int ble_stack_init(esp_bt_controller_config_t *cfg)
}
#endif // CONFIG_BT_LE_ISO_SUPPORT
#if CONFIG_SW_COEXIST_ENABLE
// Should be invoked in ble ?
extern int r_bt_rf_coex_env_init(void);
r_bt_rf_coex_env_init();
#endif /* CONFIG_SW_COEXIST_ENABLE */
return 0;
}
void ble_stack_deinit(void)
{
#if CONFIG_SW_COEXIST_ENABLE
extern void r_bt_rf_coex_env_deinit(void);
r_bt_rf_coex_env_deinit();
#endif /* CONFIG_SW_COEXIST_ENABLE */
#if CONFIG_BT_LE_ISO_SUPPORT
iso_stack_deinitEnv();
#endif // CONFIG_BT_LE_ISO_SUPPORT
@@ -1578,10 +1568,6 @@ int ble_stack_enable(void)
#endif // BT_LE_ISO_SUPPORT
#if CONFIG_SW_COEXIST_ENABLE
extern int r_bt_rf_coex_env_enable(void);
r_bt_rf_coex_env_enable();
#endif /* CONFIG_SW_COEXIST_ENABLE */
return 0;
}
@@ -0,0 +1,234 @@
config BT_CTRL_BR_EDR_MAX_ACL_CONN
int "BR/EDR Max ACL Connections"
default 2
range 1 7
help
BR/EDR ACL maximum connections of bluetooth controller.
config BT_CTRL_BR_EDR_ACL_LINK_ENABLE
bool
default y
if BT_CTRL_BR_EDR_ACL_LINK_ENABLE
menu "ACL Tx/Rx buffer number configurations"
config BT_CTRL_BR_EDR_ACLU_TX_BUF_NB
int "Total BR/EDR ACL-U TX buffer number"
depends on BT_CTRL_BREDR_ENABLE && (BT_CTRL_BR_EDR_MAX_ACL_CONN != 0)
default 4
range 3 10
help
Total BR/EDR ACL-U TX buffer number of bluetooth controller.
config BT_CTRL_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB
int "Dynamic BR/EDR ACL-U TX buffer number"
depends on BT_CTRL_BREDR_ENABLE && (BT_CTRL_BR_EDR_MAX_ACL_CONN != 0)
default 0
range 0 BT_CTRL_BR_EDR_ACLU_TX_BUF_NB
help
BR/EDR dynamic ACL-U TX buffer number of bluetooth controller.
config BT_CTRL_BR_EDR_ACLU_RX_BUF_NB
int "BR/EDR ACL-U RX buffer number"
depends on BT_CTRL_BREDR_ENABLE && (BT_CTRL_BR_EDR_MAX_ACL_CONN != 0)
default 6
range 4 8
help
BR/EDR ACL-U RX buffer number of bluetooth controller.
endmenu
endif
config BT_CTRL_BR_EDR_MAX_SYNC_CONN
int "BR/EDR Max Synchronous(SCO/eSCO) Connections"
default 0
range 0 3
help
BR/EDR Synchronize maximum connections of bluetooth controller.
if BT_CTRL_BR_EDR_MAX_SYNC_CONN != 0
menu "Supported eSCO packet types"
config BT_CTRL_BR_EDR_ESCO_EV4_SUPP
bool "BR/EDR eSCO support EV4 packet type"
default n
help
This will affect the LM features of bluetooth controller.
config BT_CTRL_BR_EDR_ESCO_EV5_SUPP
bool "BR/EDR eSCO support EV5 packet type"
default n
help
This will affect the LM features of bluetooth controller.
config BT_CTRL_BR_EDR_ESCO_EV3_2_SUPP
bool "BR/EDR eSCO support 2-EV3 packet type"
default y
help
This will affect the LM features of bluetooth controller.
config BT_CTRL_BR_EDR_ESCO_EV3_3_SUPP
bool "BR/EDR eSCO support 3-EV3 packet type"
default n
help
This will affect the LM features of bluetooth controller.
config BT_CTRL_BR_EDR_ESCO_3_SLOTS_SUPP
bool "BR/EDR eSCO support 3-slot packet types"
default n
help
This will affect the LM features of bluetooth controller.
endmenu
menu "Synchronous Tx/Rx buffer numbers"
config BT_CTRL_BR_EDR_SYNC_TX_BUF_NB
int "BR/EDR Sync(SCO/eSCO) TX buffer number"
default 4 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 1
default 6 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 2
default 8 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 3
range 2 4 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 1
range 4 8 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 2
range 6 12 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 3
help
BR/EDR Synchronize TX buffer number of bluetooth controller.
config BT_CTRL_BR_EDR_SYNC_RX_BUF_NB
int "BR/EDR Sync(SCO/eSCO) RX buffer number"
default 4 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 1
default 8 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 2
default 12 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 3
range 3 4 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 1
range 6 8 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 2
range 9 12 if BT_CTRL_BR_EDR_MAX_SYNC_CONN = 3
help
BR/EDR Synchronize RX buffer number of bluetooth controller.
endmenu
choice BT_CTRL_BR_EDR_SCO_DATA_PATH
prompt "BR/EDR Sync(SCO/eSCO) default data path"
default BT_CTRL_BR_EDR_SCO_DATA_PATH_HCI
help
SCO/eSCO data path, i.e. HCI or PCM.
SCO data can be sent/received through HCI synchronous packets, or the data
can be routed to on-chip I2S module. The latter option is not yet supported.
config BT_CTRL_BR_EDR_SCO_DATA_PATH_HCI
bool "HCI"
# config BT_CTRL_BR_EDR_SCO_DATA_PATH_PCM
# bool "PCM"
endchoice
endif
config BT_CTRL_BR_EDR_TEST_MODE_EN
bool "Enable BR/EDR test mode"
default n
help
Enable BR/EDR test mode
config BT_CTRL_BR_EDR_APB_EN
bool "Enable BR/EDR Active Peripheral Broadcast"
default n
help
Enable BR/EDR Active Peripheral Broadcast
config BT_CTRL_BR_EDR_CPB_TX_EN
bool "Enable BR/EDR Connectionless Peripheral Broadcast Transimit"
default n
help
Enable BR/EDR Connectionless Peripheral Broadcast Transimit
config BT_CTRL_BR_EDR_CPB_RX_EN
bool "Enable BR/EDR Connectionless Peripheral Broadcast Receive"
default n
help
Enable BR/EDR Connectionless Peripheral Broadcast Receive
config BT_CTRL_BR_EDR_LK_STORE_EN
bool "Enable BR/EDR controller link key storage"
default n
help
Enable BR/EDR controller link key storage, only support store link key in RAM for now.
config BT_CTRL_BR_EDR_TX_CCA_ENABLED
bool "Enable BR/EDR 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_CTRL_BR_EDR_CCA_RSSI_THRESH
int "CCA RSSI threshold value"
depends on BT_CTRL_BR_EDR_TX_CCA_ENABLED
range 20 100
default 20
help
Power threshold of CCA in unit of -1 dBm.
menu "TX Power Level settings"
config BT_CTRL_BR_EDR_TX_PWR_ACL_MIN
int "Default minimum TX power level for ACL"
default -13
range -15 20
help
Minimum BR/EDR transmission power level for ACL.
config BT_CTRL_BR_EDR_TX_PWR_ACL_MAX
int "Default maximum TX power level for ACL"
default 4
range -15 20
help
Maximum BR/EDR transmission power level for ACL.
config BT_CTRL_BR_EDR_TX_PWR_APB
int "Default TX power level for APB"
depends on BT_CTRL_BR_EDR_APB_EN
default 4
range -15 20
help
BR/EDR transmission power level for APB.
config BT_CTRL_BR_EDR_TX_PWR_PAGE
int "Default TX power level for Page"
default 4
range -15 20
help
BR/EDR transmission power level for Page.
config BT_CTRL_BR_EDR_TX_PWR_PSCAN
int "Default TX power level for Page Scan"
default 4
range -15 20
help
BR/EDR transmission power level for Page Scan.
config BT_CTRL_BR_EDR_TX_PWR_ISCAN
int "Default TX power level for Inquiry Scan"
default 4
range -15 20
help
BR/EDR transmission power level for Inquiry Scan.
config BT_CTRL_BR_EDR_TX_PWR_CPB
int "Default TX power level for CPB"
depends on BT_CTRL_BR_EDR_CPB_TX_EN
default 4
range -15 20
help
BR/EDR transmission power level for CPB.
config BT_CTRL_BR_EDR_TX_PWR_STRAIN
int "Default TX power level for Synchronization Train"
depends on BT_CTRL_BR_EDR_CPB_TX_EN
default 4
range -15 20
help
BR/EDR transmission power level for Synchronization Train.
endmenu
menu "BR/EDR Vendor Specific HCI Commands and Events"
config BT_CTRL_BR_EDR_LEGACY_AUTH_VENDOR_EVT
bool "Legacy Authentication Vendor Specific Event Enable"
default y
help
To protect from BIAS attack during Legacy authentication,
Legacy authentication Vendor specific event should be enabled
endmenu
@@ -0,0 +1,25 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __ESP_BREDR_PRIV_H__
#define __ESP_BREDR_PRIV_H__
#include "btdm_osal.h"
int bredr_stack_init(esp_bt_controller_config_t *cfg);
void bredr_stack_deinit(void);
int bredr_stack_enable(void);
void bredr_stack_disable(void);
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
esp_err_t sleep_modem_bredr_mac_modem_state_init(void);
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
void bredr_osal_elem_calc(esp_bt_controller_config_t *cfg, btdm_osal_elem_num_t *elem);
#endif // __ESP_BREDR_PRIV_H__
@@ -0,0 +1,216 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "sdkconfig.h"
#include "btdm_user_cfg.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(CONFIG_BT_BLUEDROID_ENABLED) && (CONFIG_BT_BLUEDROID_ENABLED) && (CONFIG_BT_HFP_ENABLE) && \
defined(CONFIG_BT_CTRL_BR_EDR_MAX_SYNC_CONN) && (CONFIG_BT_CTRL_BR_EDR_MAX_SYNC_CONN == 0)
#pragma message ("BT: forcing BR/EDR max sync conn eff to 1 (Bluedroid HFP requires SCO/eSCO)")
#define UC_BR_EDR_CTRL_MAX_SYNC_CONN (1)
#elif defined(CONFIG_BT_CTRL_BR_EDR_MAX_SYNC_CONN)
#define UC_BR_EDR_CTRL_MAX_SYNC_CONN (CONFIG_BT_CTRL_BR_EDR_MAX_SYNC_CONN)
#else
#define UC_BR_EDR_CTRL_MAX_SYNC_CONN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_MAX_ACL_CONN)
#define UC_BR_EDR_MAX_ACL_CONN (CONFIG_BT_CTRL_BR_EDR_MAX_ACL_CONN)
#else
#define UC_BR_EDR_MAX_ACL_CONN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TEST_MODE_EN)
#define UC_BR_EDR_TEST_MODE_EN 1
#else
#define UC_BR_EDR_TEST_MODE_EN 0
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_APB_EN) && CONFIG_BT_CTRL_BR_EDR_APB_EN
#define UC_BR_EDR_APB_EN 1
#else
#define UC_BR_EDR_APB_EN 0
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_APB_EXT_BCST_ENC_EN) && CONFIG_BT_CTRL_BR_EDR_APB_EXT_BCST_ENC_EN
#define UC_BR_EDR_APB_EXT_BCST_ENC_EN 1
#else
#define UC_BR_EDR_APB_EXT_BCST_ENC_EN 0
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_APB_EXT_PCA_EN) && CONFIG_BT_CTRL_BR_EDR_APB_EXT_PCA_EN
#define UC_BR_EDR_APB_EXT_PCA_EN 1
#else
#define UC_BR_EDR_APB_EXT_PCA_EN 0
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_LK_STORE_EN) && CONFIG_BT_CTRL_BR_EDR_LK_STORE_EN
#define UC_BR_EDR_LK_STORE_EN 1
#else
#define UC_BR_EDR_LK_STORE_EN 0
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_CCA_ENABLED)
#define UC_BR_EDR_TX_CCA_EN (CONFIG_BT_CTRL_BR_EDR_TX_CCA_ENABLED)
#else
#define UC_BR_EDR_TX_CCA_EN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_CCA_RSSI_THRESH)
#define UC_BR_EDR_CCA_RSSI_THRESH (CONFIG_BT_CTRL_BR_EDR_CCA_RSSI_THRESH)
#else
#define UC_BR_EDR_CCA_RSSI_THRESH (50)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ACLU_TX_BUF_NB)
#define UC_BR_EDR_ACLU_TX_BUF_NB (CONFIG_BT_CTRL_BR_EDR_ACLU_TX_BUF_NB)
#else
#define UC_BR_EDR_ACLU_TX_BUF_NB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB)
#define UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB (CONFIG_BT_CTRL_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB)
#else
#define UC_BR_EDR_DYNAMIC_ACLU_TX_BUF_NB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ESCO_EV4_SUPP) && CONFIG_BT_CTRL_BR_EDR_ESCO_EV4_SUPP
#define UC_BR_EDR_ESCO_EV4_SUPP (1)
#else
#define UC_BR_EDR_ESCO_EV4_SUPP (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ESCO_EV5_SUPP) && CONFIG_BT_CTRL_BR_EDR_ESCO_EV5_SUPP
#define UC_BR_EDR_ESCO_EV5_SUPP (1)
#else
#define UC_BR_EDR_ESCO_EV5_SUPP (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ESCO_EV3_2_SUPP) && CONFIG_BT_CTRL_BR_EDR_ESCO_EV3_2_SUPP
#define UC_BR_EDR_ESCO_EV3_2_SUPP (1)
#else
#define UC_BR_EDR_ESCO_EV3_2_SUPP (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ESCO_EV3_3_SUPP) && CONFIG_BT_CTRL_BR_EDR_ESCO_EV3_3_SUPP
#define UC_BR_EDR_ESCO_EV3_3_SUPP (1)
#else
#define UC_BR_EDR_ESCO_EV3_3_SUPP (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_ESCO_3_SLOTS_SUPP) && CONFIG_BT_CTRL_BR_EDR_ESCO_3_SLOTS_SUPP
#define UC_BR_EDR_ESCO_3_SLOTS_SUPP (1)
#else
#define UC_BR_EDR_ESCO_3_SLOTS_SUPP (0)
#endif
#if (UC_BR_EDR_CTRL_MAX_SYNC_CONN != 0) && defined(CONFIG_BT_CTRL_BR_EDR_SYNC_TX_BUF_NB)
#define UC_BR_EDR_SYNC_TX_BUF_NB (CONFIG_BT_CTRL_BR_EDR_SYNC_TX_BUF_NB)
#else
#define UC_BR_EDR_SYNC_TX_BUF_NB (0)
#endif
#if (UC_BR_EDR_CTRL_MAX_SYNC_CONN != 0) && defined(CONFIG_BT_CTRL_BR_EDR_SYNC_RX_BUF_NB)
#define UC_BR_EDR_SYNC_RX_BUF_NB (CONFIG_BT_CTRL_BR_EDR_SYNC_RX_BUF_NB)
#else
#define UC_BR_EDR_SYNC_RX_BUF_NB (0)
#endif
#if (UC_BR_EDR_MAX_ACL_CONN != 0) && defined(CONFIG_BT_CTRL_BR_EDR_ACLU_RX_BUF_NB)
#define UC_BR_EDR_ACLU_RX_BUF_NB (CONFIG_BT_CTRL_BR_EDR_ACLU_RX_BUF_NB)
#else
#define UC_BR_EDR_ACLU_RX_BUF_NB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN) && CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN
#define UC_BR_EDR_CPB_TX_LINK_NB (1)
#else
#define UC_BR_EDR_CPB_TX_LINK_NB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_CPB_RX_EN) && CONFIG_BT_CTRL_BR_EDR_CPB_RX_EN
#define UC_BR_EDR_CPB_RX_LINK_NB (1)
#else
#define UC_BR_EDR_CPB_RX_LINK_NB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_SCO_DATA_PATH_PCM) && CONFIG_BT_CTRL_BR_EDR_SCO_DATA_PATH_PCM
#define UC_BR_EDR_SCO_DATA_PATH (1)
#else
#define UC_BR_EDR_SCO_DATA_PATH (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MIN)
#define UC_BR_EDR_TX_PWR_ACL_MIN (CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MIN)
#else
#define UC_BR_EDR_TX_PWR_ACL_MIN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MAX)
#define UC_BR_EDR_TX_PWR_ACL_MAX (CONFIG_BT_CTRL_BR_EDR_TX_PWR_ACL_MAX)
#else
#define UC_BR_EDR_TX_PWR_ACL_MAX (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_APB_EN) && CONFIG_BT_CTRL_BR_EDR_APB_EN && defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_APB)
#define UC_BR_EDR_TX_PWR_APB (CONFIG_BT_CTRL_BR_EDR_TX_PWR_APB)
#else
#define UC_BR_EDR_TX_PWR_APB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_PAGE)
#define UC_BR_EDR_TX_PWR_PAGE (CONFIG_BT_CTRL_BR_EDR_TX_PWR_PAGE)
#else
#define UC_BR_EDR_TX_PWR_PAGE (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_PSCAN)
#define UC_BR_EDR_TX_PWR_PSCAN (CONFIG_BT_CTRL_BR_EDR_TX_PWR_PSCAN)
#else
#define UC_BR_EDR_TX_PWR_PSCAN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_ISCAN)
#define UC_BR_EDR_TX_PWR_ISCAN (CONFIG_BT_CTRL_BR_EDR_TX_PWR_ISCAN)
#else
#define UC_BR_EDR_TX_PWR_ISCAN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN) && CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN && defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_CPB)
#define UC_BR_EDR_TX_PWR_CPB (CONFIG_BT_CTRL_BR_EDR_TX_PWR_CPB)
#else
#define UC_BR_EDR_TX_PWR_CPB (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN) && CONFIG_BT_CTRL_BR_EDR_CPB_TX_EN && defined(CONFIG_BT_CTRL_BR_EDR_TX_PWR_STRAIN)
#define UC_BR_EDR_TX_PWR_STRAIN (CONFIG_BT_CTRL_BR_EDR_TX_PWR_STRAIN)
#else
#define UC_BR_EDR_TX_PWR_STRAIN (0)
#endif
#if defined(CONFIG_BT_CTRL_BR_EDR_LEGACY_AUTH_VENDOR_EVT) && CONFIG_BT_CTRL_BR_EDR_LEGACY_AUTH_VENDOR_EVT
#define UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT (1)
#else
#define UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT (0)
#endif
#define UC_BR_EDR_BASIC_VENDOR (1)
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,800 @@
/*
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_heap_caps.h"
#include "esp_heap_caps_init.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_types.h"
#include "esp_mac.h"
#include "esp_random.h"
#include "esp_task.h"
#include "riscv/interrupt.h"
#include "esp_attr.h"
#include "esp_phy_init.h"
#include "esp_bt.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_pm.h"
#include "esp_ipc.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/esp_clk.h"
#include "soc/rtc.h"
#include "soc/soc_memory_layout.h"
#include "rom/ets_sys.h"
#if CONFIG_SW_COEXIST_ENABLE
#include "private/esp_coexist_internal.h"
#endif
#include "esp_private/phy.h"
#include "soc/pmu_reg.h"
// #include "soc/lp_clkrst_reg.h"
// #include "soc/lpperi_reg.h"
#include "modem/modem_syscon_reg.h"
#include "modem/modem_lpcon_reg.h"
#include "esp_private/esp_modem_clock.h"
// #include "nimble/nimble_npl.h"
// #include "nimble/nimble_port_freertos.h"
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
#include "btdm_osal.h"
#include "btdm_endian.h"
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
#include "psa/crypto.h"
#endif
#if !CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
#include "tinycrypt/ecc_dh.h"
#include "tinycrypt/ecc.h"
#include "tinycrypt/constants.h"
#include "tinycrypt/sha256.h"
#include "tinycrypt/hmac.h"
#endif
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
#define BREDR_P256_COORD_LEN 32U
#define BREDR_P192_COORD_LEN 24U
#define BREDR_PUB_KEY_LEN_P256 (1U + BREDR_P256_COORD_LEN * 2)
#define BREDR_PUB_KEY_LEN_P192 (1U + BREDR_P192_COORD_LEN * 2)
#define BREDR_LOG_TAG "BREDR_INIT"
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
static const char *TAG_BREDR_CRYPTO = "bredr_crypto";
#endif
/* Types definition
************************************************************************
*/
/* VHCI function interface */
typedef struct vhci_host_callback {
void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/
} vhci_host_callback_t;
typedef int (*bredr_ctrl_callback_t)(void);
/* External functions or values
************************************************************************
*/
extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
extern const char *co_orca_get_git_version_str(void);
extern void esp_bt_modem_clock_reset(void);
/* VHCI */
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);
/* Initialise and De-initialise */
extern int bredr_controller_init(void *cfg);
extern void bredr_controller_deinit(void);
extern int bredr_controller_enable(void);
extern void bredr_controller_disable(void);
extern int bredr_controller_env_init(void *cfg);
extern void bredr_controller_env_deinit(void);
extern void bredr_register_setup_callback(bredr_ctrl_callback_t cbk);
extern void bredr_register_ext_dep_callback(bredr_ctrl_callback_t cbk);
extern int bredr_ctrl_feat_sync_en(void);
extern int bredr_ctrl_feat_apb_en(void);
extern int bredr_ctrl_feat_bcst_enc_en(void);
extern int bredr_ctrl_feat_pca_en(void);
extern int bredr_ctrl_feat_cpb_rx_en(void);
extern int bredr_ctrl_feat_cpb_tx_en(void);
extern int bredr_ctrl_feat_vs_basic_en(void);
extern int bredr_ctrl_feat_vs_sec_ctrl_en(void);
extern int bredr_ctrl_feat_test_en(void);
extern int bredr_ctrl_feat_lk_store_en(void);
extern int bredr_ctrl_feat_coex_en(void);
extern const char *co_orca_get_git_version_str(void);
/* Shutdown */
extern void bredr_controller_shutdown(void);
extern esp_bt_controller_status_t s_btdm_controller_status;
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
extern const sleep_retention_entries_config_t *r_bredr_mac_retention_link_get(uint8_t *size);
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
static uint32_t esp_random_wrapper(void)
{
// TODO: use esp_random
// return (int)esp_random();
static bool first = true;
if (first) {
uint8_t mac[6];
uint32_t seed;
first = false;
btdm_osal_read_efuse_mac(mac);
seed = (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];
srand(seed);
}
return rand();
}
typedef struct bredr_ecc_ops {
int (*ecc256_gen_key_pair)(uint8_t *public, uint8_t *priv);
int (*ecc256_gen_dhkey)(const uint8_t *remote_pub_key_x, const uint8_t *remote_pub_key_y, const uint8_t *local_priv_key, uint8_t *dhkey);
int (*ecc192_gen_key_pair)(uint8_t *public, uint8_t *priv);
int (*ecc192_gen_dhkey)(const uint8_t *remote_pub_key_x, const uint8_t *remote_pub_key_y, const uint8_t *local_priv_key, uint8_t *dhkey);
} bredr_ecc_ops_t;
typedef struct bredr_sha_ops {
int (*sha256)(const uint8_t *msg, uint32_t msg_len, uint8_t *digest);
int (*hmac)(const uint8_t *key, uint32_t key_len, const uint8_t *msg, uint32_t msg_len, uint8_t *digest);
} bredr_sha_ops_t;
typedef struct bredr_crypto_ops {
bredr_ecc_ops_t ecc_ops;
bredr_sha_ops_t sha_ops;
} bredr_crypto_ops_t;
static int bredr_gen_keypair_ecc256(uint8_t *public_key, uint8_t *private_key);
static int bredr_gen_keypair_ecc192(uint8_t *public_key, uint8_t *private_key);
static int
bredr_gen_dhkey_ecc256(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey);
static int
bredr_gen_dhkey_ecc192(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey);
static int bredr_sha256(const uint8_t *msg, uint32_t msg_len, uint8_t *digest);
static int bredr_hmac(const uint8_t *key, uint32_t key_len, const uint8_t *msg, uint32_t msg_len, uint8_t *digest);
const bredr_ecc_ops_t g_bredr_ecc_ops = {
.ecc256_gen_key_pair = bredr_gen_keypair_ecc256,
.ecc256_gen_dhkey = bredr_gen_dhkey_ecc256,
.ecc192_gen_key_pair = bredr_gen_keypair_ecc192,
.ecc192_gen_dhkey = bredr_gen_dhkey_ecc192,
};
const bredr_sha_ops_t g_bredr_sha_ops = {
.sha256 = bredr_sha256,
.hmac = bredr_hmac,
};
const bredr_crypto_ops_t bredr_crypto_ops = {
.ecc_ops = g_bredr_ecc_ops,
.sha_ops = g_bredr_sha_ops,
};
extern int bredr_register_crypto_funcs(bredr_crypto_ops_t *);
struct bredr_bb_cca_set_params {
uint32_t enable;
uint32_t thresh_low;
uint32_t power_drop_0;
uint32_t power_high_0;
uint32_t power_low_0;
uint32_t thresh_high_en;
uint32_t thresh_high;
uint32_t power_drop1;
uint32_t power_high_1;
uint32_t power_low_1;
};
struct bredr_bb_ops {
bool (*cca_fifo_empty)(void);
bool (*cca_fifo_full)(void);
uint32_t (*cca_fifo_count)(void);
uint32_t (*cca_fifo_read)(void);
void (*cca_period)(uint32_t ru_time, uint32_t cca_time);
void (*cca_set)(struct bredr_bb_cca_set_params *param);
void (*cca_fifo_reset)(void);
void (*set_tx_on_delay)(uint32_t delay_us);
};
extern bool bredr_tx_cca_fifo_empty(void);
extern bool bredr_tx_cca_fifo_full(void);
extern uint32_t bredr_tx_cca_fifo_count(void);
extern uint32_t bredr_tx_cca_fifo_read(void);
extern void bredr_tx_cca_period(uint32_t ru_time, uint32_t cca_time);
extern void bredr_tx_cca_set(uint32_t enable,
uint32_t thresh_low,
uint32_t power_drop_0,
uint32_t power_high_0,
uint32_t power_low_0,
uint32_t thresh_high_en,
uint32_t thresh_high,
uint32_t power_drop1,
uint32_t power_high_1,
uint32_t power_low_1);
extern void bredr_tx_cca_fifo_reset(void);
extern void bredr_set_tx_on_delay(uint32_t delay_us);
static void bredr_tx_cca_set_wapper(struct bredr_bb_cca_set_params *param);
struct bredr_bb_ops s_bredr_bb_ops = {
.cca_fifo_empty = bredr_tx_cca_fifo_empty,
.cca_fifo_full = bredr_tx_cca_fifo_full,
.cca_fifo_count = bredr_tx_cca_fifo_count,
.cca_fifo_read = bredr_tx_cca_fifo_read,
.cca_period = bredr_tx_cca_period,
.cca_set = bredr_tx_cca_set_wapper,
.cca_fifo_reset = bredr_tx_cca_fifo_reset,
.set_tx_on_delay = bredr_set_tx_on_delay,
};
extern int bredr_register_bb_funcs(struct bredr_bb_ops *ops);
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
/* Same PSA ECDH pattern as components/bt/controller/esp32c6/bt.c (ble_sm_alg_*). */
static int bredr_psa_gen_keypair(bool p256, uint8_t *public_key, uint8_t *private_key)
{
const size_t coord_len = p256 ? BREDR_P256_COORD_LEN : BREDR_P192_COORD_LEN;
const size_t priv_len = coord_len;
const size_t pub_len = p256 ? BREDR_PUB_KEY_LEN_P256 : BREDR_PUB_KEY_LEN_P192;
psa_key_id_t key_id = 0;
psa_status_t status;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
uint8_t pk[65];
psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attr, p256 ? 256 : 192);
psa_set_key_algorithm(&attr, PSA_ALG_ECDH);
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE | PSA_KEY_USAGE_EXPORT);
status = psa_generate_key(&attr, &key_id);
psa_reset_key_attributes(&attr);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_generate_key failed: %d", (int)status);
return -1;
}
size_t olen = 0;
status = psa_export_public_key(key_id, pk, sizeof(pk), &olen);
if (status != PSA_SUCCESS || olen != pub_len) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_export_public_key failed: %d olen %zu (expect %zu)",
(int)status, olen, pub_len);
psa_destroy_key(key_id);
return -1;
}
status = psa_export_key(key_id, private_key, priv_len, &olen);
if (status != PSA_SUCCESS || olen != priv_len) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_export_key failed: %d olen %zu", (int)status, olen);
psa_destroy_key(key_id);
return -1;
}
psa_destroy_key(key_id);
/* pk: 0x04 || X || Y (big-endian); stack expects per-coordinate endian swap like TinyCrypt path. */
btdm_swap_buf(public_key, &pk[1], coord_len);
btdm_swap_buf(&public_key[coord_len], &pk[1 + coord_len], coord_len);
btdm_swap_in_place(private_key, priv_len);
return 0;
}
static int bredr_psa_gen_dhkey(bool p256, const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y,
const uint8_t *our_priv_key, uint8_t *out_dhkey)
{
const size_t coord_len = p256 ? BREDR_P256_COORD_LEN : BREDR_P192_COORD_LEN;
const size_t priv_len = coord_len;
const size_t pub_len = p256 ? BREDR_PUB_KEY_LEN_P256 : BREDR_PUB_KEY_LEN_P192;
uint8_t priv[32];
uint8_t pk[65];
uint8_t dh[32];
btdm_swap_buf(priv, our_priv_key, priv_len);
pk[0] = 0x04;
btdm_swap_buf(&pk[1], peer_pub_key_x, coord_len);
btdm_swap_buf(&pk[1 + coord_len], peer_pub_key_y, coord_len);
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_status_t status;
psa_set_key_type(&attr, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
psa_set_key_bits(&attr, p256 ? 256 : 192);
psa_set_key_algorithm(&attr, PSA_ALG_ECDH);
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE);
status = psa_import_key(&attr, priv, priv_len, &key_id);
psa_reset_key_attributes(&attr);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_import_key failed: %d", (int)status);
return -1;
}
size_t out_len = 0;
status = psa_raw_key_agreement(PSA_ALG_ECDH, key_id, pk, pub_len, dh, sizeof(dh), &out_len);
psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_raw_key_agreement failed: %d", (int)status);
return -1;
}
if (out_len != coord_len) {
ESP_LOGE(TAG_BREDR_CRYPTO, "unexpected shared secret length %zu (expect %zu)", out_len, coord_len);
return -1;
}
btdm_swap_buf(out_dhkey, dh, coord_len);
return 0;
}
#else /* !CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS */
static int bredr_ecc_rand(uint8_t *dst, unsigned int size)
{
uint8_t *buf_bytes = (uint8_t *)dst;
while (size > 0) {
uint32_t word = esp_random_wrapper();
uint32_t to_copy = MIN(sizeof(word), size);
memcpy(buf_bytes, &word, to_copy);
buf_bytes += to_copy;
size -= to_copy;
}
return 1;
}
#endif /* !CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS */
static int bredr_gen_keypair(bool p256, uint8_t *public_key, uint8_t *private_key)
{
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
return bredr_psa_gen_keypair(p256, public_key, private_key);
#else
uint8_t pub[64];
size_t buf_len;
/* always register rand function again */
uECC_set_rng(bredr_ecc_rand);
if (p256) {
buf_len = 32;
if (uECC_make_key(pub, private_key, uECC_secp256r1()) != TC_CRYPTO_SUCCESS) {
return -1;
}
} else {
buf_len = 24;
if (uECC_make_key(pub, private_key, uECC_secp192r1()) != TC_CRYPTO_SUCCESS) {
return -1;
}
}
btdm_swap_buf(public_key, pub, buf_len);
btdm_swap_buf(&public_key[buf_len], &pub[buf_len], buf_len);
btdm_swap_in_place(private_key, buf_len);
#endif
return 0;
}
static int
bredr_gen_dhkey(bool p256, 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_SMP_CRYPTO_STACK_MBEDTLS
return bredr_psa_gen_dhkey(p256, peer_pub_key_x, peer_pub_key_y, our_priv_key, out_dhkey);
#else
size_t buf_len = p256 ? BREDR_P256_COORD_LEN : BREDR_P192_COORD_LEN;
uint8_t dh[32];
uint8_t pk[64];
uint8_t priv[32];
int rc;
btdm_swap_buf(pk, peer_pub_key_x, buf_len);
btdm_swap_buf(&pk[buf_len], peer_pub_key_y, buf_len);
btdm_swap_buf(priv, our_priv_key, buf_len);
if (p256) {
if (uECC_valid_public_key(pk, uECC_secp256r1()) < 0) {
return -1;
}
rc = uECC_shared_secret(pk, priv, dh, uECC_secp256r1());
if (rc == TC_CRYPTO_FAIL) {
return -1;
}
} else {
if (uECC_valid_public_key(pk, uECC_secp192r1()) < 0) {
return -1;
}
rc = uECC_shared_secret(pk, priv, dh, uECC_secp192r1());
if (rc == TC_CRYPTO_FAIL) {
return -1;
}
}
btdm_swap_buf(out_dhkey, dh, buf_len);
return 0;
#endif /* !CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS */
}
static int bredr_gen_keypair_ecc256(uint8_t *public_key, uint8_t *private_key)
{
return bredr_gen_keypair(true, public_key, private_key);
}
static int bredr_gen_keypair_ecc192(uint8_t *public_key, uint8_t *private_key)
{
return bredr_gen_keypair(false, public_key, private_key);
}
static int
bredr_gen_dhkey_ecc256(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey)
{
return bredr_gen_dhkey(true, peer_pub_key_x, peer_pub_key_y, our_priv_key, out_dhkey);
}
static int
bredr_gen_dhkey_ecc192(const uint8_t *peer_pub_key_x, const uint8_t *peer_pub_key_y, const uint8_t *our_priv_key, uint8_t *out_dhkey)
{
return bredr_gen_dhkey(false, peer_pub_key_x, peer_pub_key_y, our_priv_key, out_dhkey);
}
static int bredr_sha256(const uint8_t *msg, uint32_t msg_len, uint8_t *digest)
{
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
size_t hash_len = 0;
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, msg, (size_t)msg_len, digest, 32, &hash_len);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_hash_compute failed: %d", (int)status);
return -1;
}
if (hash_len != 32) {
ESP_LOGE(TAG_BREDR_CRYPTO, "unexpected SHA-256 length %zu", hash_len);
return -1;
}
return 0;
#else
int rc = -1;
do {
int ret = TC_CRYPTO_SUCCESS;
struct tc_sha256_state_struct state;
ret = tc_sha256_init(&state);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
ret = tc_sha256_update(&state, msg, (size_t)msg_len);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
ret = tc_sha256_final(digest, &state);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
rc = 0;
} while (0);
return rc;
#endif
}
static int bredr_hmac(const uint8_t *key, uint32_t key_len, const uint8_t *msg, uint32_t msg_len, uint8_t *digest)
{
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
psa_status_t status;
size_t mac_len = 0;
if (key_len == 0) {
return -1;
}
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
psa_set_key_bits(&attr, (psa_key_bits_t)(key_len * 8));
status = psa_import_key(&attr, key, (size_t)key_len, &key_id);
psa_reset_key_attributes(&attr);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_import_key (HMAC) failed: %d", (int)status);
return -1;
}
status = psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256), msg, (size_t)msg_len, digest, 32, &mac_len);
psa_destroy_key(key_id);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG_BREDR_CRYPTO, "psa_mac_compute failed: %d", (int)status);
return -1;
}
if (mac_len != 32) {
ESP_LOGE(TAG_BREDR_CRYPTO, "unexpected HMAC length %zu", mac_len);
return -1;
}
return 0;
#else
int rc = -1;
do {
int ret = TC_CRYPTO_SUCCESS;
struct tc_hmac_state_struct state;
ret = tc_hmac_set_key(&state, key, (unsigned int)key_len);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
ret = tc_hmac_init(&state);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
ret = tc_hmac_update(&state, msg, (unsigned int)msg_len);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
ret = tc_hmac_final(digest, TC_SHA256_DIGEST_SIZE, &state);
if (ret != TC_CRYPTO_SUCCESS) {
break;
}
rc = 0;
} while (0);
return rc;
#endif
}
static void bredr_tx_cca_set_wapper(struct bredr_bb_cca_set_params *param)
{
bredr_tx_cca_set(param->enable,
param->thresh_low,
param->power_drop_0,
param->power_high_0,
param->power_low_0,
param->thresh_high_en,
param->thresh_high,
param->power_drop1,
param->power_high_1,
param->power_low_1);
}
const char *bredr_controller_get_compile_version(void)
{
return co_orca_get_git_version_str();
}
orca_mempool_t tlsf_create_with_pool(void *mem, size_t pool_bytes, size_t max_bytes);
void tlsf_destroy(orca_mempool_t tlsf);
void *tlsf_malloc(orca_mempool_t tlsf, size_t size);
void tlsf_free(orca_mempool_t tlsf, void *ptr);
size_t tlsf_block_size(void *ptr);
size_t tlsf_alloc_overhead(void);
struct orca_mempool_ops s_orca_mempool_ops = {
.create_with_pool = tlsf_create_with_pool,
.destroy = NULL,
.malloc = tlsf_malloc,
.free = tlsf_free,
};
static int bredr_ctrl_setup_callback(void)
{
int ret = 0;
do {
#if UC_BR_EDR_CTRL_MAX_SYNC_CONN
ret = bredr_ctrl_feat_sync_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_sync_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_CTRL_MAX_SYNC_CONN */
#if UC_BR_EDR_APB_EN
ret = bredr_ctrl_feat_apb_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_apb_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_APB_EN */
#if UC_BR_EDR_APB_EXT_BCST_ENC_EN
ret = bredr_ctrl_feat_bcst_enc_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_bcst_enc_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_APB_EXT_BCST_ENC_EN */
#if UC_BR_EDR_APB_EXT_PCA_EN
ret = bredr_ctrl_feat_pca_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_pca_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_APB_EXT_PCA_EN */
#if UC_BR_EDR_CPB_RX_LINK_NB
ret = bredr_ctrl_feat_cpb_rx_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_cpb_rx_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_CPB_RX_LINK_NB */
#if UC_BR_EDR_CPB_TX_LINK_NB
ret = bredr_ctrl_feat_cpb_tx_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_cpb_tx_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_CPB_TX_LINK_NB */
#if UC_BR_EDR_BASIC_VENDOR
ret = bredr_ctrl_feat_vs_basic_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_vs_basic_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_BASIC_VENDOR */
#if UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT
ret = bredr_ctrl_feat_vs_sec_ctrl_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_vs_clk_ctrl_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_LEGACY_AUTH_VENDOR_EVT */
#if UC_BR_EDR_TEST_MODE_EN
ret = bredr_ctrl_feat_test_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_test_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_TEST_MODE_EN */
#if UC_BR_EDR_LK_STORE_EN
ret = bredr_ctrl_feat_lk_store_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_lk_store_en failed, ret:%d", ret);
break;
}
#endif /* UC_BR_EDR_LK_STORE_EN */
#if CONFIG_SW_COEXIST_ENABLE
ret = bredr_ctrl_feat_coex_en();
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_ctrl_feat_coex_en failed, ret:%d", ret);
break;
}
#endif /* CONFIG_SW_COEXIST_ENABLE */
} while (0);
return ret;
}
static int bredr_ctrl_ext_dep_callback(void)
{
int ret = 0;
do {
#if CONFIG_BT_SMP_CRYPTO_STACK_MBEDTLS
psa_status_t psa_st = psa_crypto_init();
if (psa_st != PSA_SUCCESS) {
ESP_LOGE(BREDR_LOG_TAG, "psa_crypto_init failed: %d", (int)psa_st);
ret = -1;
break;
}
#endif
ret = bredr_register_crypto_funcs((bredr_crypto_ops_t *)&bredr_crypto_ops);
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_register_crypto_funcs failed, ret:%d", ret);
break;
}
ret = bredr_register_bb_funcs(&s_bredr_bb_ops);
if (ret != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_register_bb_funcs failed, ret:%d", ret);
break;
}
} while (0);
return ret;
}
int esp_bredr_controller_init(esp_bt_controller_config_t *cfg)
{
int status;
esp_err_t err = ESP_OK;
ESP_LOGI(BREDR_LOG_TAG, "BT controller compile version [%s]", co_orca_get_git_version_str());
bredr_register_setup_callback(bredr_ctrl_setup_callback);
bredr_register_ext_dep_callback(bredr_ctrl_ext_dep_callback);
cfg->bredr.mempool_size = 1024 * (cfg->bredr.max_acl_conn + 2);
cfg->bredr.mempool_ops = &s_orca_mempool_ops;
status = bredr_controller_init(&cfg->bredr);
if (status != 0) {
ESP_LOGE(BREDR_LOG_TAG, "bredr_controller_init failed, status:%d", status);
err = ESP_ERR_NO_MEM;
}
return err;
}
int bredr_stack_init(esp_bt_controller_config_t *cfg)
{
return esp_bredr_controller_init(cfg);
}
void bredr_stack_deinit(void)
{
bredr_controller_deinit();
}
int bredr_stack_enable(void)
{
return 0;
}
void bredr_stack_disable(void)
{
}
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
esp_err_t sleep_modem_bredr_mac_modem_state_init(void)
{
uint8_t size;
const sleep_retention_entries_config_t *bredr_mac_modem_config = r_bredr_mac_retention_link_get(&size);
esp_err_t err = sleep_retention_entries_create(bredr_mac_modem_config, size, REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_BLE_MAC);
if (err == ESP_OK) {
ESP_LOGI(BREDR_LOG_TAG, "Modem BREDR MAC retention initialization");
}
return err;
}
#endif // CONFIG_FREERTOS_USE_TICKLESS_IDLE
void
bredr_osal_elem_calc(esp_bt_controller_config_t *cfg, btdm_osal_elem_num_t *elem)
{
elem->evt_count += 4;
elem->evtq_count += 0;
elem->co_count += 0;
elem->sem_count += 1;
elem->mutex_count += 1;
}
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
@@ -22,7 +22,7 @@ extern "C" {
/*
* Function declarations for BTDM EXTERNAL
*/
const int8_t *wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length);
const int8_t *wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length, uint8_t modem_cfg);
int btdm_external_init(void);
void btdm_external_deinit(void);
@@ -5,6 +5,7 @@
*/
#ifndef _BTDM_LP_H_
#define _BTDM_LP_H_
#include "esp_private/esp_modem_clock.h"
void btdm_lp_enable_clock(esp_btdm_controller_config_t *cfg);
@@ -18,4 +19,13 @@ void btdm_lp_reset(bool enable_stage);
void btdm_lp_shutdown(void);
modem_clock_lpclk_src_t btdm_lp_get_lpclk_src(void);
void btdm_lp_set_lpclk_src(modem_clock_lpclk_src_t clk_src);
uint32_t btdm_lp_get_lpclk_freq(void);
void btdm_lp_set_lpclk_freq(uint32_t clk_freq);
#endif
@@ -142,11 +142,11 @@ int wr_btdm_osal_intr_free(btdm_osal_intr_handle_t intr_handle);
void *wr_btdm_osal_malloc(uint32_t size, btdm_osal_malloc_flag_t flags);
void wr_btdm_osal_free(void *ptr);
#if !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED
#if !CONFIG_BT_CTRL_MULTI_LINK_ENABLED
void *wr_btdm_osal_mmgmt_block_malloc(uint32_t size);
void wr_btdm_osal_mmgmt_block_free(void *ptr);
void wr_btdm_osal_mmgmt_block_copy(void *dst, const void *src, uint16_t size);
#endif /* !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED */
#endif /* !CONFIG_BT_CTRL_MULTI_LINK_ENABLED */
// void * wr_btdm_osal_ets_delay_us(uint32_t us);
int wr_btdm_osal_read_efuse_mac(uint8_t *mac);
@@ -9,11 +9,14 @@
#include "btdm_external.h"
extern const int8_t *bt_bb_get_tx_pwr_table(uint8_t *length);
extern const int8_t *bt_bb_tx_pwr_table_get(uint8_t *length, uint8_t modem_cfg);
const int8_t *
wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length)
wr_btdm_external_bb_get_tx_pwr_table(uint8_t *length, uint8_t modem_cfg)
{
assert(length != NULL);
assert (modem_cfg <= 2);
// TODO: replace with bt_bb_tx_pwr_table_get when all the targets(h4, s31, etc) support this API
return bt_bb_get_tx_pwr_table(length);
}
@@ -24,7 +24,12 @@
#include "esp_private/sleep_modem.h"
#include "esp_private/sleep_retention.h"
#endif
#include "soc/rtc.h"
#if CONFIG_IDF_TARGET_ESP32S31
// TODO: remove this include after use of HP_SYS_CLKRST_MODEM_CONF_REG is removed
#include "soc/hp_sys_clkrst_reg.h"
#endif
/*
***************************************************************************************************
* Local Defined Macros
@@ -51,7 +56,7 @@ extern esp_err_t sleep_modem_bredr_mac_modem_state_init(void);
extern esp_err_t sleep_modem_ble_mac_modem_state_init(void);
#endif // UC_BT_CTRL_BLE_IS_ENABLEs
#endif /* CONFIG_FREERTOS_USE_TICKLESS_IDLE */
extern int r_btdm_hal_rtc_freq_set(uint64_t rtc_freq);
extern void r_btdm_sleep_set_sleep_cb(void *s_cb, void *w_cb, void *s_arg, void *w_arg,
uint32_t us_to_enabled);
@@ -66,8 +71,8 @@ static DRAM_ATTR modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_
#ifdef CONFIG_PM_ENABLE
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock = NULL;
#endif // CONFIG_PM_ENABLE
// static modem_clock_lpclk_src_t s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_INVALID;
static uint32_t s_bt_lpclk_freq = 100000;
static uint32_t s_bt_xtal_lpclk_freq = 100000;
static uint32_t s_bt_lpclk_freq = 0;
/*
***************************************************************************************************
@@ -81,7 +86,7 @@ btdm_lp_rtc_slow_clk_select(uint8_t slow_clk_src)
switch (slow_clk_src) {
case MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL:
ESP_LOGI(BTDM_LOG_TAG, "Using main XTAL as clock source");
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (CONFIG_XTAL_FREQ * 1000000 / s_bt_lpclk_freq - 1));
modem_clock_select_lp_clock_source(PERIPH_BT_MODULE, slow_clk_src, (CONFIG_XTAL_FREQ * 1000000 / s_bt_xtal_lpclk_freq - 1));
break;
case MODEM_CLOCK_LPCLK_SRC_RC_SLOW:
ESP_LOGW(BTDM_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!");
@@ -109,32 +114,29 @@ btdm_lp_timer_clk_init(esp_btdm_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;
s_bt_lpclk_freq = s_bt_xtal_lpclk_freq;
#else
#if CONFIG_RTC_CLK_SRC_INT_RC
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC_SLOW;
s_bt_lpclk_freq = esp_clk_tree_lp_slow_get_freq_hz(ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED) / 5;
#elif CONFIG_RTC_CLK_SRC_EXT_CRYS
uint32_t clk_freq = 0;
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
if (!esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL32K, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &clk_freq)) {
if (clk_freq > 32700 && clk_freq < 33800) {
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
} else {
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL detection error, switch to main XTAL as Bluetooth sleep clock");
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
}
} else {
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL detection error, switch to main XTAL as Bluetooth sleep clock");
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
}
if ((rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) &&
!esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_XTAL32K, ESP_CLK_TREE_SRC_FREQ_PRECISION_EXACT, &clk_freq) &&
(clk_freq > 32700 && clk_freq < 33800) ) {
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_XTAL32K;
s_bt_lpclk_freq = 32768;
} else {
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL detection error, switch to main XTAL as Bluetooth sleep clock");
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL;
s_bt_lpclk_freq = s_bt_xtal_lpclk_freq;
}
#elif CONFIG_RTC_CLK_SRC_INT_RC32K
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_RC32K;
s_bt_lpclk_freq = 32000;
#elif CONFIG_RTC_CLK_SRC_EXT_OSC
s_bt_lpclk_src = MODEM_CLOCK_LPCLK_SRC_EXT32K;
s_bt_lpclk_freq = 32000;
#else
ESP_LOGE(BTDM_LOG_TAG, "Unsupported clock source");
assert(0);
@@ -142,22 +144,53 @@ btdm_lp_timer_clk_init(esp_btdm_controller_config_t *cfg)
#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;
// //TODO
// // 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;
// }
btdm_lp_rtc_slow_clk_select(s_bt_lpclk_src);
}
modem_clock_lpclk_src_t btdm_lp_get_lpclk_src(void)
{
return s_bt_lpclk_src;
}
extern esp_bt_controller_status_t esp_ble_controller_get_status(void);
void btdm_lp_set_lpclk_src(modem_clock_lpclk_src_t clk_src)
{
if (esp_ble_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (clk_src >= MODEM_CLOCK_LPCLK_SRC_MAX || clk_src <= MODEM_CLOCK_LPCLK_SRC_INVALID) {
return;
}
s_bt_lpclk_src = clk_src;
}
uint32_t btdm_lp_get_lpclk_freq(void)
{
return s_bt_xtal_lpclk_freq;
}
void btdm_lp_set_lpclk_freq(uint32_t clk_freq)
{
uint32_t xtal_freq;
if (esp_ble_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
if (!clk_freq) {
return;
}
xtal_freq = CONFIG_XTAL_FREQ * 1000000;
if (xtal_freq % clk_freq) {
return;
}
s_bt_xtal_lpclk_freq = clk_freq;
}
static void
btdm_lp_timer_clk_deinit(void)
{
@@ -250,8 +283,6 @@ btdm_lp_enable_clock(esp_btdm_controller_config_t *cfg)
{
modem_clock_module_enable(PERIPH_BT_MODULE);
modem_clock_module_mac_reset(PERIPH_BT_MODULE);
// TODO: set the clock ion modem_clock_module_enable
REG_WRITE(MODEM_SYSCON_CLK_CONF_POWER_ST_REG, 0XFFFFFFFF);
btdm_lp_timer_clk_init(cfg);
}
@@ -300,6 +331,7 @@ btdm_lp_init(void)
}
#endif /* UC_BT_CTRL_SLEEP_ENABLE && CONFIG_FREERTOS_USE_TICKLESS_IDLE */
#endif /* CONFIG_PM_ENABLE */
r_btdm_hal_rtc_freq_set(s_bt_lpclk_freq);
return 0;
}
@@ -335,14 +367,16 @@ btdm_lp_reset(bool enable_stage)
#endif // CONFIG_PM_ENABLE
esp_phy_enable(PHY_MODEM_BT);
#if CONFIG_IDF_TARGET_ESP32H4
// TODO: Need to be deleted.
void phy_set_rfpll_xpd(bool en);
phy_set_rfpll_xpd(0);
#endif
esp_btbb_enable();
s_bt_active = true;
} else {
esp_btbb_disable();
if (s_bt_active) {
esp_btbb_disable();
esp_phy_disable(PHY_MODEM_BT);
#if CONFIG_PM_ENABLE
esp_pm_lock_release(s_pm_lock);
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <string.h>
#include "btdm_osal_freertos.h"
#include "btdm_user_cfg.h"
#include "btdm_mempool.h"
#include "esp_mac.h"
@@ -48,7 +49,7 @@ struct btdm_intr_alloc_params {
};
};
static const char *TAG = "TBTDM OSAL";
static const char *TAG __attribute__((unused)) = "BTDM OSAL";
struct btdm_mempool s_btdm_osal_ev_pool;
static btdm_membuf_t *s_btdm_osal_ev_buf = NULL;
@@ -1147,7 +1148,7 @@ wr_btdm_osal_free(void *ptr)
heap_caps_free(ptr);
}
#if !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED
#if !CONFIG_BT_CTRL_MULTI_LINK_ENABLED
void *
wr_btdm_osal_mmgmt_block_malloc(uint32_t size)
{
@@ -1180,7 +1181,7 @@ wr_btdm_osal_mmgmt_block_copy(void *dst, const void *src, uint16_t size)
extern void r_ble_lll_mmgmt_block_copy(void *addr0, void *addr1, uint16_t size);
r_ble_lll_mmgmt_block_copy((void *)dst, (void *)src, size);
}
#endif /* !CONFIG_BTDM_CTRL_MULTI_LINK_ENABLED */
#endif /* !CONFIG_BT_CTRL_MULTI_LINK_ENABLED */
/*
***************************************************************************************************
@@ -28,6 +28,9 @@
#include "esp_hci_internal.h"
#include "common/hci_driver_h4.h"
#include "common/hci_driver_util.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_mbuf.h"
#endif
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
@@ -151,7 +154,9 @@ hci_h4_sm_w4_header(struct hci_h4_sm *h4sm, struct hci_h4_input_buffer *ib)
memcpy(h4sm->pkt->data, h4sm->hdr, h4sm->len);
break;
}
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
return -1;
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
case HCI_H4_SYNC:
conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
h4sm->exp_len = h4sm->hdr[2] + 3;
@@ -256,8 +261,8 @@ hci_h4_sm_w4_payload(struct hci_h4_sm *h4sm,
return -1;
}
}
break;
#endif // UC_BT_CTRL_BLE_IS_ENABLE
break;
default:
return -2;
}
@@ -361,32 +366,31 @@ hci_h4_sm_free_buf(struct hci_h4_sm *h4sm)
break;
#endif // (!CONFIG_BT_CONTROLLER_ENABLED)
case HCI_H4_ACL:
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
uint16_t conn_handle = btdm_get_le16(&h4sm->hdr[0]) & HCI_INTERNAL_CONN_MASK;
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
#if UC_BT_CTRL_BLE_IS_ENABLE
if (h4sm->om) {
h4sm->frees->acl(h4sm->om);
h4sm->om = NULL;
}
#endif
} else {
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
if (h4sm->pkt) {
h4sm->frees->bredr_acl(h4sm->pkt);
h4sm->pkt = NULL;
}
}
#else
if (h4sm->om) {
h4sm->frees->acl(h4sm->om);
h4sm->om = NULL;
}
#endif
}
break;
#if UC_BT_CTRL_BLE_IS_ENABLE
case HCI_H4_ISO:
if (h4sm->buf) {
h4sm->frees->iso(h4sm->buf);
h4sm->buf = NULL;
}
break;
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
case HCI_H4_SYNC:
if (h4sm->pkt) {
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -8,6 +8,9 @@
#include "esp_hci_internal.h"
#include "common/hci_driver_mem.h"
#include "common/hci_driver_h4.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_mbuf.h"
#endif
hci_driver_packet_t *
hci_driver_mem_cmd_alloc(void)
@@ -23,6 +26,7 @@ hci_driver_mem_evt_alloc(int discardable)
return NULL;
}
#if UC_BT_CTRL_BLE_IS_ENABLE
struct ble_mbuf *
hci_driver_mem_acl_alloc(void)
{
@@ -53,6 +57,8 @@ hci_driver_mem_iso_len_alloc(uint32_t len)
return ble_msys_get_pkthdr(len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
}
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
void
hci_driver_mem_cmd_free(void * ptr)
{
@@ -67,7 +73,7 @@ hci_driver_mem_evt_free(void *ptr)
btdm_hci_trans_buf_free(pkt);
}
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
hci_driver_packet_t *
hci_driver_mem_bredr_acl_alloc(uint16_t handle)
{
@@ -95,27 +101,31 @@ hci_driver_mem_sync_free(void *ptr)
bredr_hci_trans_sync_tx_done(pkt);
bredr_hci_trans_sync_free(pkt);
}
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
const struct hci_h4_allocators s_hci_driver_mem_alloc = {
.cmd = hci_driver_mem_cmd_alloc,
.evt = hci_driver_mem_evt_alloc,
#if UC_BT_CTRL_BLE_IS_ENABLE
.acl = hci_driver_mem_acl_alloc,
.iso = hci_driver_mem_iso_alloc,
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
.sync = hci_driver_mem_sync_alloc,
.bredr_acl = hci_driver_mem_bredr_acl_alloc,
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
};
const struct hci_h4_frees s_hci_driver_mem_free = {
.cmd = hci_driver_mem_cmd_free,
.evt = hci_driver_mem_evt_free,
#if UC_BT_CTRL_BLE_IS_ENABLE
.acl = ble_mbuf_free_chain,
.iso = hci_driver_mem_iso_free,
.le_evt = r_ble_hci_trans_buf_free,
#if UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#endif // UC_BT_CTRL_BLE_IS_ENABLE
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
.sync = hci_driver_mem_sync_free,
.bredr_acl = hci_driver_mem_bredr_acl_free,
#endif // UC_BTDM_CTRL_BR_EDR_IS_ENABLE
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
};
@@ -8,13 +8,17 @@
#include "esp_log.h"
#include "esp_hci_driver.h"
#include "esp_hci_internal.h"
#include "btdm_mempool.h"
#include "common/hci_driver_util.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_mbuf.h"
#endif
#define TAG "HCI_UTIL"
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
#define HCI_DRIVER_UTIL_BREDR_HCI_EVT_TX_POOL_NUM 4
#define HCI_DRIVER_UTIL_BREDR_TX_POOL_NUM \
(CONFIG_BT_CTRL_BR_EDR_ACLU_RX_BUF_NB_EFF + CONFIG_BT_CTRL_BR_EDR_SYNC_RX_BUF_NB_EFF + HCI_DRIVER_UTIL_BREDR_HCI_EVT_TX_POOL_NUM)
(UC_BR_EDR_ACLU_RX_BUF_NB + UC_BR_EDR_SYNC_RX_BUF_NB + HCI_DRIVER_UTIL_BREDR_HCI_EVT_TX_POOL_NUM)
#else
#define HCI_DRIVER_UTIL_BREDR_TX_POOL_NUM 0
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
@@ -170,8 +174,9 @@ hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_
uint32_t data_len;
hci_driver_util_tx_entry_t *tx_entry;
hci_driver_packet_t *pkt = NULL;
#if UC_BT_CTRL_BLE_IS_ENABLE
struct ble_mbuf *om = NULL;
uint16_t out_off;
#endif
/* Check if there is any remaining data that hasn't been sent completely. If it has been completed,
* free the corresponding memory. Therefore, the HCI TX entry needs to be sent one by one; multiple
* entries cannot be sent together.
@@ -184,8 +189,10 @@ hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_
if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) {
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
#if UC_BT_CTRL_BLE_IS_ENABLE
om = (struct ble_mbuf *)tx_entry->data;
ble_mbuf_free_chain(om);
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
}
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
else {
@@ -194,10 +201,13 @@ hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_
#endif // UC_BT_CTRL_BR_EDR_IS_ENABLE
} else {
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
#if UC_BT_CTRL_BLE_IS_ENABLE
uint16_t out_off;
om = (struct ble_mbuf *)tx_entry->data;
om = ble_mbuf_off(om, s_hci_driver_util_env.cur_tx_off, &out_off);
tx_len = min(max_tx_len, om->om_len - out_off);
*tx_data = (void *)&om->om_data[out_off];
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
} else {
tx_len = min(max_tx_len, data_len - s_hci_driver_util_env.cur_tx_off);
*tx_data = &pkt->data[s_hci_driver_util_env.cur_tx_off];
@@ -206,7 +216,9 @@ hci_driver_util_tx_list_dequeue(uint32_t max_tx_len, void **tx_data, bool *last_
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) {
if (s_hci_driver_util_env.cur_tx_off >= data_len) {
if (tx_entry->data_source == HCI_DRIVER_LE_EVT) {
#if UC_BT_CTRL_BLE_IS_ENABLE
r_ble_hci_trans_buf_free(tx_entry->data);
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
}
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
else if (tx_entry->data_source == HCI_DRIVER_BREDR_EVT) {
@@ -307,7 +319,9 @@ hci_driver_util_deinit(void)
next_entry = STAILQ_NEXT(tx_entry, next);
if (tx_entry->data_type == HCI_DRIVER_TYPE_EVT) {
if (tx_entry->data_source == HCI_DRIVER_LE_EVT) {
#if UC_BT_CTRL_BLE_IS_ENABLE
r_ble_hci_trans_buf_free(tx_entry->data);
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
}
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
else if (tx_entry->data_source == HCI_DRIVER_BREDR_EVT) {
@@ -320,7 +334,9 @@ hci_driver_util_deinit(void)
}
} else if (tx_entry->data_type == HCI_DRIVER_TYPE_ACL) {
if (tx_entry->data_source == HCI_DRIVER_LE_ACL) {
#if UC_BT_CTRL_BLE_IS_ENABLE
ble_mbuf_free_chain((struct ble_mbuf *)tx_entry->data);
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
}
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
else {
@@ -147,7 +147,9 @@ hci_driver_uart_rx_task(void *p)
ret = hci_h4_sm_rx(s_hci_driver_uart_env.h4_sm, data, read_len);
if (ret < 0) {
ESP_LOGE(TAG, "parse rx data error! sm_state:%d\n", s_hci_driver_uart_env.h4_sm->state);
#if UC_BT_CTRL_BLE_IS_ENABLE
r_ble_ll_hci_ev_hw_err(ESP_HCI_SYNC_LOSS_ERR);
#endif // #if UC_BT_CTRL_BLE_IS_ENABLE
}
}
}
@@ -5,10 +5,12 @@
*/
#include <string.h>
#include <stdio.h>
#include "ble_mbuf.h"
#include "esp_hci_driver.h"
#include "esp_hci_internal.h"
#include "esp_bt.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_mbuf.h"
#endif
typedef struct {
hci_driver_forward_fn *forward_cb;
@@ -80,14 +82,13 @@ hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, u
int rc = 0;
uint16_t buf_len = length + 1;;
uint8_t *buf = NULL;
struct ble_mbuf *om;
uint8_t old_value = 0;
hci_driver_packet_t *pkt = (hci_driver_packet_t *)data;
if (data_type == HCI_DRIVER_TYPE_ACL) {
#if UC_BT_CTRL_BLE_IS_ENABLE
if (dir == HCI_DRIVER_DIR_LEC2H) {
om = (struct ble_mbuf *)data;
struct ble_mbuf *om = (struct ble_mbuf *)data;
buf = malloc(buf_len);
/* TODO: If there is no memory, should handle it in the controller. */
assert(buf);
@@ -114,6 +115,7 @@ hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, u
} else if (data_type == HCI_DRIVER_TYPE_EVT) {
/* TODO: If there is no memory, should handle it in the controller. */
if (dir == HCI_DRIVER_DIR_LEC2H) {
#if UC_BT_CTRL_BLE_IS_ENABLE
buf = malloc(buf_len);
assert(buf != NULL);
buf[0] = HCI_DRIVER_TYPE_EVT;
@@ -121,6 +123,7 @@ hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, u
rc = hci_driver_vhci_host_recv_with_type(data_type, buf, buf_len);
r_ble_hci_trans_buf_free(data);
free(buf);
#endif
}
#if UC_BT_CTRL_BR_EDR_IS_ENABLE
else if (dir == HCI_DRIVER_DIR_BREDRC2H) {
@@ -175,7 +178,6 @@ hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data, u
static int
hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
{
struct ble_mbuf *om;
uint16_t pkt_len;
uint16_t conn_handle;
hci_driver_packet_t *pkt = NULL;
@@ -195,7 +197,7 @@ hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_
conn_handle = btdm_get_le16(&data[1]) & HCI_INTERNAL_CONN_MASK;
#if UC_BT_CTRL_BLE_IS_ENABLE
if (HCI_INTERNAL_CONN_IS_BLE(conn_handle)) {
om = ble_msys_get_pkthdr(pkt_len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
struct ble_mbuf *om = ble_msys_get_pkthdr(pkt_len, ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE);
assert(om);
assert(ble_mbuf_append(om, &data[1], length - 1) == 0);
data = (uint8_t *)om;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -37,21 +37,27 @@
typedef hci_driver_packet_t *(hci_h4_alloc_cmd)(void);
typedef void *(hci_h4_alloc_evt)(int);
#if CONFIG_BT_CTRL_BLE_ENABLE
typedef struct ble_mbuf *(hci_h4_alloc_acl)(void);
typedef void *(hci_h4_alloc_iso)(uint32_t);
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // #if CONFIG_BT_CTRL_BLE_ENABLE
#if CONFIG_BT_CTRL_BREDR_ENABLE
typedef hci_driver_packet_t *(hci_h4_alloc_sync)(uint16_t);
typedef hci_driver_packet_t *(hci_h4_alloc_bredr_acl)(uint16_t);
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // #if CONFIG_BT_CTRL_BREDR_ENABLE
struct hci_h4_allocators {
hci_h4_alloc_cmd *cmd;
#if CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_alloc_acl *acl;
#endif // #if CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_alloc_evt *evt;
#if CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_alloc_iso *iso;
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // #if CONFIG_BT_CTRL_BLE_ENABLE
#if CONFIG_BT_CTRL_BREDR_ENABLE
hci_h4_alloc_sync *sync;
hci_h4_alloc_bredr_acl *bredr_acl;
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // #if CONFIG_BT_CTRL_BREDR_ENABLE
};
extern const struct hci_h4_allocators hci_h4_allocs_from_ll;
@@ -59,23 +65,29 @@ extern const struct hci_h4_allocators hci_h4_allocs_from_hs;
typedef void (hci_h4_free_cmd)(void * ptr);
typedef void (hci_h4_free_evt)(void * ptr);
#if CONFIG_BT_CTRL_BLE_ENABLE
typedef int (hci_h4_free_acl)(struct ble_mbuf *om);
typedef void (hci_h4_free_iso)(void *ptr);
typedef void (hci_h4_free_le_evt)(uint8_t *buf);
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // #if CONFIG_BT_CTRL_BLE_ENABLE
#if CONFIG_BT_CTRL_BREDR_ENABLE
typedef void (hci_h4_free_sync)(void *ptr);
typedef void (hci_h4_free_bredr_acl)(void *ptr);
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // CONFIG_BT_CTRL_BREDR_ENABLE
struct hci_h4_frees {
hci_h4_free_cmd *cmd;
#if CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_free_acl *acl;
#endif // CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_free_evt *evt;
#if CONFIG_BT_CTRL_BLE_ENABLE
hci_h4_free_iso *iso;
hci_h4_free_le_evt *le_evt;
#if CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // CONFIG_BT_CTRL_BLE_ENABLE
#if CONFIG_BT_CTRL_BREDR_ENABLE
hci_h4_free_sync *sync;
hci_h4_free_bredr_acl *bredr_acl;
#endif // CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY || CONFIG_BTDM_CTRL_MODE_BTDM
#endif // CONFIG_BT_CTRL_BREDR_ENABLE
};
typedef int (hci_h4_frame_cb)(uint8_t pkt_type, void *data, int len, uint8_t data_source);
@@ -12,8 +12,9 @@ extern "C" {
#endif
#include <stdint.h>
#include "esp_hci_driver.h"
#include "ble_mbuf.h"
// forward declaration
struct ble_mbuf;
/* The leadingspace in user info header for ACL data */
#define ESP_HCI_INTERNAL_ACL_MBUF_LEADINGSPCAE (4)
@@ -11,7 +11,6 @@
extern "C" {
#endif
#include <stdint.h>
#include "ble_mbuf.h"
#include "esp_hci_driver.h"
/**
@@ -9,6 +9,9 @@
#include "esp_hci_transport.h"
#include "esp_hci_internal.h"
#include "esp_bt.h"
#if UC_BT_CTRL_BLE_IS_ENABLE
#include "ble_mbuf.h"
#endif // UC_BT_CTRL_BLE_IS_ENABLE
typedef struct hci_transport_env
{
@@ -182,11 +185,13 @@ hci_transport_controller_le_iso_tx(const uint8_t *data, uint16_t len, void *arg)
#endif // CONFIG_BT_LE_ISO_SUPPORT
/* Functions for controller Tx. */
#if UC_BT_CTRL_BLE_IS_ENABLE
static int
hci_transport_controller_le_tx_dummy(void *data, void *arg)
{
return -1;
}
#endif
static int
hci_transport_controller_tx_dummy(hci_driver_packet_t *pkt)
+5
View File
@@ -0,0 +1,5 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
## For ESP32-S31 BR/EDR controller, use prefix "BT_CTRL_" instead of "BTDM_CTRL_"
CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN CONFIG_BT_CTRL_BR_EDR_MAX_ACL_CONN
CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN CONFIG_BT_CTRL_BR_EDR_MAX_SYNC_CONN
@@ -2,7 +2,8 @@
components/bt/test_apps/basic_unit_test:
disable:
- if: IDF_TARGET not in ["esp32", "esp32c3"]
# TODO: Need to enable test for ESP32-S31 for tinycrypt ECC P-192 test
- if: IDF_TARGET not in ["esp32", "esp32c3", "esp32c5"]
reason: Sufficient to run the tests on one chip of each architecture
depends_components:
- bt
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 |
| ----------------- | ----- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 |
| ----------------- | ----- | -------- | -------- |
# `bt` component unit tests
@@ -1,6 +1,7 @@
idf_component_register(SRCS "test_bt_main.c"
"test_bt_common.c"
"test_smp.c"
"test_tinycrypt_ecc.c"
INCLUDE_DIRS "."
PRIV_REQUIRES unity bt
WHOLE_ARCHIVE)
@@ -11,3 +12,4 @@ target_include_directories(${COMPONENT_LIB} PRIVATE ${bt_dir}/host/bluedroid/sta
target_include_directories(${COMPONENT_LIB} PRIVATE ${bt_dir}/host/bluedroid/common/include)
target_include_directories(${COMPONENT_LIB} PRIVATE ${bt_dir}/host/bluedroid/stack/include)
target_include_directories(${COMPONENT_LIB} PRIVATE ${bt_dir}/common/include)
target_include_directories(${COMPONENT_LIB} PRIVATE ${bt_dir}/common/tinycrypt/include)
@@ -8,7 +8,7 @@
#include "unity_test_runner.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT 0
#define TEST_MEMORY_LEAK_THRESHOLD_DEFAULT -150
static int leak_threshold = TEST_MEMORY_LEAK_THRESHOLD_DEFAULT;
void set_leak_threshold(int threshold)
{
@@ -0,0 +1,161 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/*
* Unit tests for TinyCrypt ECC (P-256 / P-192) APIs declared in tinycrypt/ecc.h.
* Procedure mirrors TEST_CASE("ble_smp_public_key_check", "[ble_smp][native_crypto]") in test_smp.c.
*/
#include <stdint.h>
#include <string.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "unity.h"
#include "esp_random.h"
#include "tinycrypt/ecc.h"
#if defined(CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT) && CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT
static void tinycrypt_fill_private_p256(uint8_t *priv)
{
for (int i = 0; i < NUM_ECC_BYTES; i++) {
priv[i] = (uint8_t)(0x10 + (i & 0x0F));
}
}
static void tinycrypt_bt_rand_p256(uint8_t *priv)
{
memset(priv, 0x55, NUM_ECC_BYTES);
for (int i = 0; i < NUM_ECC_BYTES / (int)sizeof(uint32_t); i++) {
uint32_t r = esp_random();
memcpy(priv + i * sizeof(uint32_t), &r, sizeof(uint32_t));
}
}
#if uECC_SUPPORTS_secp192r1
static void tinycrypt_fill_private_p192(uint8_t *priv)
{
for (int i = 0; i < NUM_ECC_BYTES_SECP192R1; i++) {
priv[i] = (uint8_t)(0x10 + (i & 0x0F));
}
}
static void tinycrypt_bt_rand_p192(uint8_t *priv)
{
memset(priv, 0x55, NUM_ECC_BYTES_SECP192R1);
for (int i = 0; i < NUM_ECC_BYTES_SECP192R1 / (int)sizeof(uint32_t); i++) {
uint32_t r = esp_random();
memcpy(priv + i * sizeof(uint32_t), &r, sizeof(uint32_t));
}
}
#endif // uECC_SUPPORTS_secp192r1
/**
* @brief P-256: public key from private, validation, generator on curve, tamper, random keys.
*
* Same flow as ble_smp_public_key_check (native): fixed private public valid;
* zero Y invalid; generator point check; random private loop.
*/
TEST_CASE("tinycrypt_ecc_p256_public_key_check", "[ble_smp][tinycrypt_ecc]")
{
vTaskDelay(200 / portTICK_PERIOD_MS);
uECC_Curve curve = uECC_secp256r1();
uint8_t private_key[NUM_ECC_BYTES];
uint8_t public_key[NUM_ECC_BYTES * 2];
tinycrypt_fill_private_p256(private_key);
TEST_ASSERT_EQUAL_INT(1, uECC_compute_public_key(private_key, public_key, curve));
TEST_ASSERT_EQUAL_INT(0, uECC_valid_public_key(public_key, curve));
for (int i = 0; i < NUM_ECC_BYTES; i++) {
public_key[NUM_ECC_BYTES + i] = 0;
}
TEST_ASSERT_NOT_EQUAL(0, uECC_valid_public_key(public_key, curve));
uint8_t g_pub[NUM_ECC_BYTES * 2];
uECC_vli_nativeToBytes(g_pub, NUM_ECC_BYTES, curve->G);
uECC_vli_nativeToBytes(g_pub + NUM_ECC_BYTES, NUM_ECC_BYTES, curve->G + NUM_ECC_WORDS);
TEST_ASSERT_EQUAL_INT(-4, uECC_valid_public_key(g_pub, curve));
for (int j = 0; j < 100; j++) {
tinycrypt_bt_rand_p256(private_key);
if (uECC_compute_public_key(private_key, public_key, curve) != 1) {
continue;
}
TEST_ASSERT_EQUAL_INT(0, uECC_valid_public_key(public_key, curve));
}
}
TEST_CASE("tinycrypt_ecc_p256_vli_mmod_fast", "[ble_smp][tinycrypt_ecc]")
{
vTaskDelay(200 / portTICK_PERIOD_MS);
uECC_Curve curve = uECC_secp256r1();
unsigned int prod[NUM_ECC_WORDS * 2];
unsigned int res[NUM_ECC_WORDS];
memset(prod, 0, sizeof(prod));
uECC_vli_set(prod, curve->p, NUM_ECC_WORDS);
vli_mmod_fast_secp256r1(res, prod);
TEST_ASSERT(uECC_vli_isZero(res, NUM_ECC_WORDS));
}
#if uECC_SUPPORTS_secp192r1
/**
* @brief P-192: same procedure and uECC_valid_public_key expectations as P-256 (valid key 0, G is -4).
*/
TEST_CASE("tinycrypt_ecc_p192_public_key_check", "[ble_smp][tinycrypt_ecc]")
{
vTaskDelay(200 / portTICK_PERIOD_MS);
uECC_Curve curve = uECC_secp192r1();
uint8_t private_key[NUM_ECC_BYTES_SECP192R1];
uint8_t public_key[NUM_ECC_BYTES_SECP192R1 * 2];
tinycrypt_fill_private_p192(private_key);
TEST_ASSERT_EQUAL_INT(1, uECC_compute_public_key(private_key, public_key, curve));
TEST_ASSERT_EQUAL_INT(0, uECC_valid_public_key(public_key, curve));
for (int i = 0; i < NUM_ECC_BYTES_SECP192R1; i++) {
public_key[NUM_ECC_BYTES_SECP192R1 + i] = 0;
}
TEST_ASSERT_NOT_EQUAL(0, uECC_valid_public_key(public_key, curve));
uint8_t g_pub[NUM_ECC_BYTES_SECP192R1 * 2];
uECC_vli_nativeToBytes(g_pub, NUM_ECC_BYTES_SECP192R1, curve->G);
uECC_vli_nativeToBytes(g_pub + NUM_ECC_BYTES_SECP192R1, NUM_ECC_BYTES_SECP192R1,
curve->G + NUM_ECC_WORDS_SECP192R1);
TEST_ASSERT_EQUAL_INT(-4, uECC_valid_public_key(g_pub, curve));
for (int j = 0; j < 100; j++) {
tinycrypt_bt_rand_p192(private_key);
if (uECC_compute_public_key(private_key, public_key, curve) != 1) {
continue;
}
TEST_ASSERT_EQUAL_INT(0, uECC_valid_public_key(public_key, curve));
}
}
TEST_CASE("tinycrypt_ecc_p192_vli_mmod_fast", "[ble_smp][tinycrypt_ecc]")
{
vTaskDelay(200 / portTICK_PERIOD_MS);
uECC_Curve curve = uECC_secp192r1();
unsigned int prod[NUM_ECC_WORDS_SECP192R1 * 2];
unsigned int res[NUM_ECC_WORDS_SECP192R1];
memset(prod, 0, sizeof(prod));
uECC_vli_set(prod, curve->p, NUM_ECC_WORDS_SECP192R1);
vli_mmod_fast_secp192r1(res, prod);
TEST_ASSERT(uECC_vli_isZero(res, NUM_ECC_WORDS_SECP192R1));
}
#endif /* #if uECC_SUPPORTS_secp192r1 */
#endif /* CONFIG_BT_SMP_CRYPTO_STACK_TINYCRYPT */
@@ -6,6 +6,6 @@ from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.generic
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32c5'], indirect=['target'])
def test_bt(dut: Dut) -> None:
dut.run_all_single_board_cases()
@@ -21,11 +21,8 @@
#define MODEM_ADC_COMMON_FE_CLOCK_DEPS ( MODEM_CLOCKS( MODEM_ADC_COMMON_FE, SOC_PLL_SOURCE_CG ) )
#define PHY_CALIBRATION_WIFI_CLOCK_DEPS ( MODEM_CLOCKS( WIFI_APB, WIFI_BB, WIFI_BB_44M, WIFI_BB_80X1, SOC_PLL_SOURCE_CG ) )
#define PHY_CALIBRATION_BT_I154_CLOCK_DEPS ( MODEM_CLOCKS( WIFI_APB, WIFI_BB_44M, BT_I154_COMMON_BB, SOC_PLL_SOURCE_CG ) )
#if SOC_BT_SUPPORTED //TODO IDF-15185: Remove this once BT is supported
#define PHY_CALIBRATION_CLOCK_DEPS ( PHY_CALIBRATION_WIFI_CLOCK_DEPS | PHY_CALIBRATION_BT_I154_CLOCK_DEPS )
#else
#define PHY_CALIBRATION_CLOCK_DEPS ( PHY_CALIBRATION_WIFI_CLOCK_DEPS )
#endif
uint32_t IRAM_ATTR modem_clock_get_module_deps(shared_periph_module_t module)
{
@@ -11,14 +11,18 @@ extern "C" {
#endif
// btbb sleep retention reg
#define BB_PART_CNT 3
#define BB_PART_CNT 4
#define BB_PART_0_SIZE 128
#define BB_PART_1_SIZE 68
#define BB_PART_2_SIZE 19
#define BB_PART_0_ADDR 0x600A2000
#define BB_PART_1_ADDR 0x600A2800
#define BB_PART_2_ADDR 0x600A2C00
#define BB_PART_3_SIZE 64
#define BB_PART_0_ADDR 0x20102000
#define BB_PART_1_ADDR 0x20102800
#define BB_PART_2_ADDR 0x20102C00
#define BB_PART_3_ADDR 0x20102400
#ifdef __cplusplus
}
+4 -2
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -37,6 +37,9 @@ static esp_err_t btbb_sleep_retention_init(void *arg)
#if BB_PART_CNT > 2
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x02), BB_PART_2_ADDR, BB_PART_2_ADDR, BB_PART_2_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
#endif // BB_PART_CNT > 2
#if BB_PART_CNT > 3
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEM_BT_BB_LINK(0x03), BB_PART_3_ADDR, BB_PART_3_ADDR, BB_PART_3_SIZE, 0, 0), .owner = BTBB_LINK_OWNER },
#endif // BB_PART_CNT > 3
};
esp_err_t err = sleep_retention_entries_create(btbb_regs_retention, ARRAY_SIZE(btbb_regs_retention), REGDMA_LINK_PRI_BT_MAC_BB, SLEEP_RETENTION_MODULE_BT_BB);
ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for btbb retention");
@@ -57,7 +60,6 @@ static void btbb_sleep_retention_deinit(void)
}
#endif // SOC_PM_MODEM_RETENTION_BY_REGDMA && CONFIG_FREERTOS_USE_TICKLESS_IDLE
void esp_btbb_enable(void)
{
_lock_acquire(&s_btbb_access_lock);
@@ -251,6 +251,10 @@ config SOC_IEEE802154_SUPPORTED
bool
default y
config SOC_BT_SUPPORTED
bool
default y
config SOC_PHY_CALIBRATION_CLOCK_IS_INDEPENDENT
bool
default y
@@ -1150,3 +1154,47 @@ config SOC_WIFI_NAN_SUPPORT
config SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH
int
default 12
config SOC_BT_CLASSIC_SUPPORTED
bool
default y
config SOC_BLE_SUPPORTED
bool
default y
config SOC_ESP_NIMBLE_CONTROLLER
bool
default y
config SOC_BLE_50_SUPPORTED
bool
default y
config SOC_BLE_DEVICE_PRIVACY_SUPPORTED
bool
default y
config SOC_BLE_POWER_CONTROL_SUPPORTED
bool
default y
config SOC_BLE_MULTI_CONN_OPTIMIZATION
bool
default y
config SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED
bool
default y
config SOC_BLE_CTE_SUPPORTED
bool
default y
config SOC_BLE_SUBRATE_SUPPORTED
bool
default y
config SOC_BLE_PERIODIC_ADV_WITH_RESPONSE
bool
default y
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -508,3 +508,20 @@
#define SIG_IN_FUNC255_IDX 255
// version date 2312260
#define SIG_GPIO_OUT_IDX 256
#define ANT_SEL0_IDX PAD_MODEM_ANT_SEL0_IDX
#define ANT_SEL1_IDX PAD_MODEM_ANT_SEL1_IDX
#define ANT_SEL2_IDX PAD_MODEM_ANT_SEL2_IDX
#define ANT_SEL3_IDX PAD_MODEM_ANT_SEL3_IDX
#define ANT_SEL4_IDX PAD_MODEM_ANT_SEL4_IDX
#define ANT_SEL5_IDX PAD_MODEM_ANT_SEL5_IDX
#define ANT_SEL6_IDX PAD_MODEM_ANT_SEL6_IDX
#define ANT_SEL7_IDX PAD_MODEM_ANT_SEL7_IDX
#define ANT_SEL8_IDX PAD_MODEM_ANT_SEL8_IDX
#define ANT_SEL9_IDX PAD_MODEM_ANT_SEL9_IDX
#define ANT_SEL10_IDX PAD_MODEM_ANT_SEL10_IDX
#define ANT_SEL11_IDX PAD_MODEM_ANT_SEL11_IDX
#define ANT_SEL12_IDX PAD_MODEM_ANT_SEL12_IDX
#define ANT_SEL13_IDX PAD_MODEM_ANT_SEL13_IDX
#define ANT_SEL14_IDX PAD_MODEM_ANT_SEL14_IDX
#define ANT_SEL15_IDX PAD_MODEM_ANT_SEL15_IDX
+19 -1
View File
@@ -113,7 +113,8 @@
#define SOC_PHY_SUPPORTED 1
#define SOC_WIFI_SUPPORTED 1
#define SOC_IEEE802154_SUPPORTED 1
#define SOC_IEEE802154_SUPPORTED 1
#define SOC_BT_SUPPORTED 1
#define SOC_PHY_CALIBRATION_CLOCK_IS_INDEPENDENT 1
/*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_40M 1
@@ -470,6 +471,7 @@
/*--------------------------- JPEG --------------------------------*/
#define SOC_JPEG_DECODE_SUPPORTED (1)
#define SOC_JPEG_ENCODE_SUPPORTED (1)
/*------------------------------------ WI-FI CAPS ------------------------------------*/
#define SOC_WIFI_HW_TSF (1) /*!< Support hardware TSF */
#define SOC_WIFI_FTM_SUPPORT (1) /*!< Support FTM */
@@ -483,3 +485,19 @@
/*--------------- WIFI LIGHT SLEEP CLOCK WIDTH CAPS --------------------------*/
#define SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH (12)
/*---------------------------------- Bluetooth CAPS ----------------------------------*/
#define SOC_BT_CLASSIC_SUPPORTED (1) /*!< Support Bluetooth Classic hardware */
#define SOC_BLE_SUPPORTED (1) /*!< Support Bluetooth Low Energy hardware */
// #define SOC_BLE_MESH_SUPPORTED (1) /*!< Support BLE MESH */
#define SOC_ESP_NIMBLE_CONTROLLER (1) /*!< Support BLE EMBEDDED controller V1 */
#define SOC_BLE_50_SUPPORTED (1) /*!< Support Bluetooth 5.0 */
#define SOC_BLE_DEVICE_PRIVACY_SUPPORTED (1) /*!< Support BLE device privacy mode */
#define SOC_BLE_POWER_CONTROL_SUPPORTED (1) /*!< Support Bluetooth Power Control */
#define SOC_BLE_MULTI_CONN_OPTIMIZATION (1) /*!< Support multiple connections optimization */
#define SOC_BLE_PERIODIC_ADV_ENH_SUPPORTED (1) /*!< Support For BLE Periodic Adv Enhancements */
// #define SOC_BLUFI_SUPPORTED (1) // TODO: enable this feature coexistence is supported
#define SOC_BLE_CTE_SUPPORTED (1) /*!< Support Bluetooth LE Constant Tone Extension (CTE) */
#define SOC_BLE_SUBRATE_SUPPORTED (1) /*!< Support Bluetooth LE Connection Subrating */
#define SOC_BLE_PERIODIC_ADV_WITH_RESPONSE (1) /*!< Support Bluetooth LE Periodic Advertising with Response (PAwR) */
// #define SOC_BLE_ISO_SUPPORTED (1) /*!< Support Bluetooth ISO */