help
Select this option to enable Bluetooth and show the submenu with Bluetooth configuration choices.
+menu "Bluetooth controller"
+ visible if BT_ENABLED
+
+choice BTDM_CONTROLLER_MODE
+ prompt "Bluetooth controller mode (BR/EDR/BLE/DUALMODE)"
+ depends on BT_ENABLED
+ help
+ Specify the bluetooth controller mode (BR/EDR, BLE or dual mode).
+
+config BTDM_CONTROLLER_MODE_BLE_ONLY
+ bool "BLE Only"
+
+config BTDM_CONTROLLER_MODE_BR_EDR_ONLY
+ bool "BR/EDR Only"
+
+config BTDM_CONTROLLER_MODE_BTDM
+ bool "Bluetooth Dual Mode"
+
+endchoice
+
+config BTDM_CONTROLLER_BLE_MAX_CONN
+ int "BLE Max Connection Numbers"
+ depends on BTDM_CONTROLLER_MODE_BLE_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 3
+ range 1 9
+ help
+ Maximum connection numbers of BLE controller.
+ Decrease the value will save the memory of DRAM. Each connection will save 1.2KB DRAM
+
+config BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN
+ int "BR/EDR Max ACL Connection Numbers"
+ depends on BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 2
+ range 1 7
+ help
+ Maximum ACL connection numbers of BR/EDR controller.
+ Decrease the value will save the memory of DRAM. Each connection will save 1KB DRAM.
+
+config BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN
+ int "BR/EDR Max Sync(SCO/eSCO) Connection Numbers"
+ depends on BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 0
+ range 0 3
+ help
+ Maximum Synchronize connection numbers of BR/EDR controller.
+ Decrease the value will save the memory of DRAM. Each connection will save 2KB DRAM.
+
+config BTDM_CONTROLLER_BLE_MAX_CONN_EFF
+ int
+ default BTDM_CONTROLLER_BLE_MAX_CONN if BTDM_CONTROLLER_MODE_BLE_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 0
+
+config BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF
+ int
+ default BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 0
+
+config BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF
+ int
+ default BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN if BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+ default 0
+
choice BTDM_CONTROLLER_PINNED_TO_CORE_CHOICE
prompt "The cpu core which bluetooth controller run"
depends on BT_ENABLED && !FREERTOS_UNICORE
depends on ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL
endchoice
+endmenu
+
+config BLE_SCAN_DUPLICATE
+ bool "BLE Scan Duplicate Options "
+ depends on (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
+ default y
+ help
+ This select enables parameters setting of BLE scan duplicate.
+
+config DUPLICATE_SCAN_CACHE_SIZE
+ int "Maximum number of devices in scan duplicate filter"
+ depends on BLE_SCAN_DUPLICATE
+ range 10 200
+ default 20
+ help
+ Maximum number of devices which can be recorded in scan duplicate filter.
+ When the maximum amount of device in the filter is reached, the cache will be refreshed.
+
+config BLE_MESH_SCAN_DUPLICATE_EN
+ bool "Special duplicate scan mechanism for BLE Mesh scan"
+ depends on BLE_SCAN_DUPLICATE
+ default n
+ help
+ This enables the BLE scan duplicate for special BLE Mesh scan.
+
+config MESH_DUPLICATE_SCAN_CACHE_SIZE
+ int "Maximum number of Mesh adv packets in scan duplicate filter"
+ depends on BLE_MESH_SCAN_DUPLICATE_EN
+ range 10 200
+ default 50
+ help
+ Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
+ When the maximum amount of device in the filter is reached, the cache will be refreshed.
+
+
+
endmenu
menuconfig BLUEDROID_ENABLED
config GATTS_ENABLE
bool "Include GATT server module(GATTS)"
- depends on BLUEDROID_ENABLED
+ depends on BLUEDROID_ENABLED && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default y
help
This option can be disabled when the app work only on gatt client mode
config GATTC_ENABLE
bool "Include GATT client module(GATTC)"
- depends on BLUEDROID_ENABLED
+ depends on BLUEDROID_ENABLED && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default y
help
This option can be close when the app work only on gatt server mode
config GATTC_CACHE_NVS_FLASH
bool "Save gattc cache data to nvs flash"
- depends on GATTC_ENABLE
+ depends on GATTC_ENABLE && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default n
help
This select can save gattc cache data to nvs flash
config BLE_SMP_ENABLE
bool "Include BLE security module(SMP)"
- depends on BLUEDROID_ENABLED
+ depends on BLUEDROID_ENABLED && (BTDM_CONTROLLER_MODE_BTDM || BTDM_CONTROLLER_MODE_BLE_ONLY)
default y
help
This option can be close when the app not used the ble security connect.
handling adv packets is slow, it will cause the controller memory to run out. if enabled, adv packets will be
lost when host queue is congested.
-config BLE_SCAN_DUPLICATE
- bool "BLE Scan Duplicate Options "
- depends on BLUEDROID_ENABLED
- default y
- help
- This select enables parameters setting of BLE scan duplicate.
-
-config DUPLICATE_SCAN_CACHE_SIZE
- int "Maximum number of devices in scan duplicate filter"
- depends on BLE_SCAN_DUPLICATE
- range 10 1000
- default 50
- help
- Maximum number of devices which can be recorded in scan duplicate filter.
- When the maximum amount of device in the filter is reached, the cache will be refreshed.
-
-config BLE_MESH_SCAN_DUPLICATE_EN
- bool "Special duplicate scan mechanism for BLE Mesh scan"
- depends on BLE_SCAN_DUPLICATE
- default n
- help
- This enables the BLE scan duplicate for special BLE Mesh scan.
-
-config MESH_DUPLICATE_SCAN_CACHE_SIZE
- int "Maximum number of Mesh adv packets in scan duplicate filter"
- depends on BLE_MESH_SCAN_DUPLICATE_EN
- range 10 1000
- default 100
- help
- Maximum number of adv packets which can be recorded in duplicate scan cache for BLE Mesh.
- When the maximum amount of device in the filter is reached, the cache will be refreshed.
-
config SMP_ENABLE
bool
depends on BLUEDROID_ENABLED
# Memory reserved at start of DRAM for Bluetooth stack
config BT_RESERVE_DRAM
hex
- default 0x10000 if BT_ENABLED
+ default 0xdb5c if BT_ENABLED
default 0
endmenu
#include "driver/periph_ctrl.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
+#include "soc/soc_memory_layout.h"
#include "esp_clk.h"
#if CONFIG_BT_ENABLED
+/* Macro definition
+ ************************************************************************
+ */
+
#define BTDM_LOG_TAG "BTDM_INIT"
#define BTDM_INIT_PERIOD (5000) /* ms */
#define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<2)
#define BTDM_CFG_SCAN_DUPLICATE_OPTIONS (1<<3)
#define BTDM_CFG_SEND_ADV_RESERVED_SIZE (1<<4)
-/* Other reserved for future */
-
-/* not for user call, so don't put to include file */
-extern void btdm_osi_funcs_register(void *osi_funcs);
-extern int btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts);
-extern void btdm_controller_deinit(void);
-extern int btdm_controller_enable(esp_bt_mode_t mode);
-extern void btdm_controller_disable(void);
-extern uint8_t btdm_controller_get_mode(void);
-extern const char *btdm_controller_get_compile_version(void);
-extern void btdm_rf_bb_init(void);
-extern void btdm_controller_enable_sleep(bool enable);
+/* Sleep mode */
#define BTDM_MODEM_SLEEP_MODE_NONE (0)
#define BTDM_MODEM_SLEEP_MODE_ORIG (1)
#define BTDM_MODEM_SLEEP_MODE_EVED (2)
-extern void btdm_controller_set_sleep_mode(uint8_t mode);
-extern uint8_t btdm_controller_get_sleep_mode(void);
-extern bool btdm_power_state_active(void);
-extern void btdm_wakeup_request(void);
+/* Low Power Clock Selection */
#define BTDM_LPCLK_SEL_XTAL (0)
#define BTDM_LPCLK_SEL_XTAL32K (1)
#define BTDM_LPCLK_SEL_RTC_SLOW (2)
#define BTDM_LPCLK_SEL_8M (3)
-extern bool btdm_lpclk_select_src(uint32_t sel);
-extern bool btdm_lpclk_set_div(uint32_t div);
+/* Sleep duration */
#define BTDM_MIN_SLEEP_DURATION (20)
-/* 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;
-
-extern bool API_vhci_host_check_send_available(void);
-extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
-extern void API_vhci_host_register_callback(const vhci_host_callback_t *callback);
-
-extern int ble_txpwr_set(int power_type, int power_level);
-extern int ble_txpwr_get(int power_type);
-extern int bredr_txpwr_set(int min_power_level, int max_power_level);
-extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
-extern void bredr_sco_datapath_set(uint8_t data_path);
-
-extern char _bss_start_btdm;
-extern char _bss_end_btdm;
-extern uint32_t _bt_bss_start;
-extern uint32_t _bt_bss_end;
-extern uint32_t _btdm_bss_start;
-extern uint32_t _btdm_bss_end;
-extern uint32_t _bt_data_start;
-extern uint32_t _bt_data_end;
-extern uint32_t _btdm_data_start;
-extern uint32_t _btdm_data_end;
-extern char _data_start_btdm;
-extern char _data_end_btdm;
-extern uint32_t _data_start_btdm_rom;
-extern uint32_t _data_end_btdm_rom;
#define BT_DEBUG(...)
#define BT_API_CALL_CHECK(info, api_call, ret) \
} while(0)
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
+#define OSI_VERSION 0x00010001
+#define OSI_MAGIC_VALUE 0xFADEBEAD
+
+/* SPIRAM Configuration */
+#if CONFIG_SPIRAM_USE_MALLOC
+#define BTDM_MAX_QUEUE_NUM (5)
+#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;
+
+/* Dram region */
typedef struct {
esp_bt_mode_t mode;
intptr_t start;
intptr_t end;
} btdm_dram_available_region_t;
-/* the mode column will be modified by release function to indicate the available region */
-static btdm_dram_available_region_t btdm_dram_available_region[] = {
- //following is .data
- {ESP_BT_MODE_BTDM, 0x3ffae6e0, 0x3ffaff10},
- //following is memory which HW will use
- {ESP_BT_MODE_BTDM, 0x3ffb0000, 0x3ffb09a8},
- {ESP_BT_MODE_BLE, 0x3ffb09a8, 0x3ffb1ddc},
- {ESP_BT_MODE_BTDM, 0x3ffb1ddc, 0x3ffb2730},
- {ESP_BT_MODE_CLASSIC_BT, 0x3ffb2730, 0x3ffb8000},
- //following is .bss
- {ESP_BT_MODE_BTDM, 0x3ffb8000, 0x3ffbbb28},
- {ESP_BT_MODE_CLASSIC_BT, 0x3ffbbb28, 0x3ffbdb28},
- {ESP_BT_MODE_BTDM, 0x3ffbdb28, 0x3ffc0000},
-};
-
-/* Reserve the full memory region used by Bluetooth Controller,
- some may be released later at runtime. */
-SOC_RESERVE_MEMORY_REGION(0x3ffb0000, 0x3ffc0000, bt_hardware_shared_mem);
-SOC_RESERVE_MEMORY_REGION(0x3ffae6e0, 0x3ffaff10, rom_bt_data);
-
+/* PSRAM configuration */
#if CONFIG_SPIRAM_USE_MALLOC
typedef struct {
QueueHandle_t handle;
void *storage;
void *buffer;
} btdm_queue_item_t;
-#define BTDM_MAX_QUEUE_NUM (5)
-static btdm_queue_item_t btdm_queue_table[BTDM_MAX_QUEUE_NUM];
-SemaphoreHandle_t btdm_queue_table_mux = NULL;
-#endif /* #if CONFIG_SPIRAM_USE_MALLOC */
+#endif
+/* OSI function */
struct osi_funcs_t {
+ uint32_t _version;
xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
void (*_ints_on)(unsigned int mask);
void (*_interrupt_disable)(void);
bool (* _is_in_isr)(void);
int (* _cause_sw_intr_to_core)(int core_id, int intr_no);
void *(* _malloc)(uint32_t size);
+ void *(* _malloc_internal)(uint32_t size);
void (* _free)(void *p);
int32_t (* _read_efuse_mac)(uint8_t mac[6]);
void (* _srand)(unsigned int seed);
bool (* _btdm_sleep_check_duration)(uint32_t *slot_cnt);
void (* _btdm_sleep_enter)(void);
void (* _btdm_sleep_exit)(void); /* called from ISR */
+ uint32_t _magic;
+};
+
+
+/* External functions or values
+ ************************************************************************
+ */
+
+/* not for user call, so don't put to include file */
+/* OSI */
+extern int btdm_osi_funcs_register(void *osi_funcs);
+/* Initialise and De-initialise */
+extern int btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts);
+extern void btdm_controller_deinit(void);
+extern int btdm_controller_enable(esp_bt_mode_t mode);
+extern void btdm_controller_disable(void);
+extern uint8_t btdm_controller_get_mode(void);
+extern const char *btdm_controller_get_compile_version(void);
+extern void btdm_rf_bb_init(void);
+/* Sleep */
+extern void btdm_controller_enable_sleep(bool enable);
+extern void btdm_controller_set_sleep_mode(uint8_t mode);
+extern uint8_t btdm_controller_get_sleep_mode(void);
+extern bool btdm_power_state_active(void);
+extern void btdm_wakeup_request(void);
+/* Low Power Clock */
+extern bool btdm_lpclk_select_src(uint32_t sel);
+extern bool btdm_lpclk_set_div(uint32_t div);
+/* 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);
+/* TX power */
+extern int ble_txpwr_set(int power_type, int power_level);
+extern int ble_txpwr_get(int power_type);
+extern int bredr_txpwr_set(int min_power_level, int max_power_level);
+extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
+extern void bredr_sco_datapath_set(uint8_t data_path);
+
+extern char _bss_start_btdm;
+extern char _bss_end_btdm;
+extern char _data_start_btdm;
+extern char _data_end_btdm;
+extern uint32_t _data_start_btdm_rom;
+extern uint32_t _data_end_btdm_rom;
+
+extern uint32_t _bt_bss_start;
+extern uint32_t _bt_bss_end;
+extern uint32_t _btdm_bss_start;
+extern uint32_t _btdm_bss_end;
+extern uint32_t _bt_data_start;
+extern uint32_t _bt_data_end;
+extern uint32_t _btdm_data_start;
+extern uint32_t _btdm_data_end;
+
+/* Local Function Declare
+ *********************************************************************
+ */
+#if CONFIG_SPIRAM_USE_MALLOC
+static bool IRAM_ATTR btdm_queue_generic_register(const btdm_queue_item_t *queue);
+static bool IRAM_ATTR btdm_queue_generic_deregister(btdm_queue_item_t *queue);
+#endif /* CONFIG_SPIRAM_USE_MALLOC */
+static void IRAM_ATTR interrupt_disable(void);
+static void IRAM_ATTR interrupt_restore(void);
+static void IRAM_ATTR task_yield_from_isr(void);
+static void *IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init);
+static void IRAM_ATTR semphr_delete_wrapper(void *semphr);
+static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw);
+static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw);
+static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_ms);
+static int32_t IRAM_ATTR semphr_give_wrapper(void *semphr);
+static void *IRAM_ATTR mutex_create_wrapper(void);
+static void IRAM_ATTR mutex_delete_wrapper(void *mutex);
+static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex);
+static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex);
+static void *IRAM_ATTR queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
+static void IRAM_ATTR queue_delete_wrapper(void *queue);
+static int32_t IRAM_ATTR queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
+static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw);
+static int32_t IRAM_ATTR queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
+static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw);
+static int32_t IRAM_ATTR task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id);
+static void IRAM_ATTR task_delete_wrapper(void *task_handle);
+static bool IRAM_ATTR is_in_isr_wrapper(void);
+static void IRAM_ATTR cause_sw_intr(void *arg);
+static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no);
+static void * IRAM_ATTR malloc_internal_wrapper(size_t size);
+static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6]);
+static void IRAM_ATTR srand_wrapper(unsigned int seed);
+static int IRAM_ATTR rand_wrapper(void);
+static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles);
+static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us);
+static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt);
+static void IRAM_ATTR btdm_sleep_enter_wrapper(void);
+static void IRAM_ATTR btdm_sleep_exit_wrapper(void);
+
+/* Local variable definition
+ ***************************************************************************
+ */
+/* OSI funcs */
+static const struct osi_funcs_t osi_funcs_ro = {
+ ._version = OSI_VERSION,
+ ._set_isr = xt_set_interrupt_handler,
+ ._ints_on = xt_ints_on,
+ ._interrupt_disable = interrupt_disable,
+ ._interrupt_restore = interrupt_restore,
+ ._task_yield = vPortYield,
+ ._task_yield_from_isr = task_yield_from_isr,
+ ._semphr_create = semphr_create_wrapper,
+ ._semphr_delete = semphr_delete_wrapper,
+ ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
+ ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
+ ._semphr_take = semphr_take_wrapper,
+ ._semphr_give = semphr_give_wrapper,
+ ._mutex_create = mutex_create_wrapper,
+ ._mutex_delete = mutex_delete_wrapper,
+ ._mutex_lock = mutex_lock_wrapper,
+ ._mutex_unlock = mutex_unlock_wrapper,
+ ._queue_create = queue_create_wrapper,
+ ._queue_delete = queue_delete_wrapper,
+ ._queue_send = queue_send_wrapper,
+ ._queue_send_from_isr = queue_send_from_isr_wrapper,
+ ._queue_recv = queue_recv_wrapper,
+ ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
+ ._task_create = task_create_wrapper,
+ ._task_delete = task_delete_wrapper,
+ ._is_in_isr = is_in_isr_wrapper,
+ ._cause_sw_intr_to_core = cause_sw_intr_to_core_wrapper,
+ ._malloc = malloc,
+ ._malloc_internal = malloc_internal_wrapper,
+ ._free = free,
+ ._read_efuse_mac = read_mac_wrapper,
+ ._srand = srand_wrapper,
+ ._rand = rand_wrapper,
+ ._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
+ ._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
+ ._btdm_sleep_check_duration = btdm_sleep_check_duration,
+ ._btdm_sleep_enter = btdm_sleep_enter_wrapper,
+ ._btdm_sleep_exit = btdm_sleep_exit_wrapper,
+ ._magic = OSI_MAGIC_VALUE,
+};
+
+/* the mode column will be modified by release function to indicate the available region */
+static btdm_dram_available_region_t btdm_dram_available_region[] = {
+ //following is .data
+ {ESP_BT_MODE_BTDM, SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END },
+ //following is memory which HW will use
+ {ESP_BT_MODE_BTDM, SOC_MEM_BT_EM_BTDM0_START, SOC_MEM_BT_EM_BTDM0_END },
+ {ESP_BT_MODE_BLE, SOC_MEM_BT_EM_BLE_START, SOC_MEM_BT_EM_BLE_END },
+ {ESP_BT_MODE_BTDM, SOC_MEM_BT_EM_BTDM1_START, SOC_MEM_BT_EM_BTDM1_END },
+ {ESP_BT_MODE_CLASSIC_BT, SOC_MEM_BT_EM_BREDR_START, SOC_MEM_BT_EM_BREDR_REAL_END},
+ //following is .bss
+ {ESP_BT_MODE_BTDM, SOC_MEM_BT_BSS_START, SOC_MEM_BT_BSS_END },
+ {ESP_BT_MODE_BTDM, SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END },
};
+/* Reserve the full memory region used by Bluetooth Controller,
+ * some may be released later at runtime. */
+SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_EM_START, SOC_MEM_BT_EM_BREDR_REAL_END, rom_bt_em);
+SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_BSS_START, SOC_MEM_BT_BSS_END, rom_bt_bss);
+SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END, rom_bt_misc);
+SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END, rom_bt_data);
+
+static struct osi_funcs_t *osi_funcs_p;
+
+#if CONFIG_SPIRAM_USE_MALLOC
+static btdm_queue_item_t btdm_queue_table[BTDM_MAX_QUEUE_NUM];
+SemaphoreHandle_t btdm_queue_table_mux = NULL;
+#endif /* #if CONFIG_SPIRAM_USE_MALLOC */
/* Static variable declare */
static bool btdm_bb_init_flag = false;
#endif
#if CONFIG_SPIRAM_USE_MALLOC
-bool IRAM_ATTR btdm_queue_generic_register(const btdm_queue_item_t *queue)
+static bool IRAM_ATTR btdm_queue_generic_register(const btdm_queue_item_t *queue)
{
if (!btdm_queue_table_mux || !queue) {
return NULL;
return ret;
}
-bool IRAM_ATTR btdm_queue_generic_deregister(btdm_queue_item_t *queue)
+static bool IRAM_ATTR btdm_queue_generic_deregister(btdm_queue_item_t *queue)
{
if (!btdm_queue_table_mux || !queue) {
return false;
return err;
}
+static void * IRAM_ATTR malloc_internal_wrapper(size_t size)
+{
+ return heap_caps_malloc(size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
+}
+
static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
{
return esp_read_mac(mac, ESP_MAC_BT);
}
}
-static struct osi_funcs_t osi_funcs = {
- ._set_isr = xt_set_interrupt_handler,
- ._ints_on = xt_ints_on,
- ._interrupt_disable = interrupt_disable,
- ._interrupt_restore = interrupt_restore,
- ._task_yield = vPortYield,
- ._task_yield_from_isr = task_yield_from_isr,
- ._semphr_create = semphr_create_wrapper,
- ._semphr_delete = semphr_delete_wrapper,
- ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
- ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
- ._semphr_take = semphr_take_wrapper,
- ._semphr_give = semphr_give_wrapper,
- ._mutex_create = mutex_create_wrapper,
- ._mutex_delete = mutex_delete_wrapper,
- ._mutex_lock = mutex_lock_wrapper,
- ._mutex_unlock = mutex_unlock_wrapper,
- ._queue_create = queue_create_wrapper,
- ._queue_delete = queue_delete_wrapper,
- ._queue_send = queue_send_wrapper,
- ._queue_send_from_isr = queue_send_from_isr_wrapper,
- ._queue_recv = queue_recv_wrapper,
- ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
- ._task_create = task_create_wrapper,
- ._task_delete = task_delete_wrapper,
- ._is_in_isr = is_in_isr_wrapper,
- ._cause_sw_intr_to_core = cause_sw_intr_to_core_wrapper,
- ._malloc = malloc,
- ._free = free,
- ._read_efuse_mac = read_mac_wrapper,
- ._srand = srand_wrapper,
- ._rand = rand_wrapper,
- ._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
- ._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
- ._btdm_sleep_check_duration = btdm_sleep_check_duration,
- ._btdm_sleep_enter = btdm_sleep_enter_wrapper,
- ._btdm_sleep_exit = btdm_sleep_exit_wrapper,
-};
-
bool esp_vhci_host_check_send_available(void)
{
return API_vhci_host_check_send_available();
API_vhci_host_send_packet(data, len);
}
-void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
+esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
{
- API_vhci_host_register_callback((const vhci_host_callback_t *)callback);
+ return API_vhci_host_register_callback((const vhci_host_callback_t *)callback) == 0 ? ESP_OK : ESP_FAIL;
}
static uint32_t btdm_config_mask_load(void)
{
uint32_t mask = 0x0;
- if (btdm_dram_available_region[0].mode == ESP_BT_MODE_BLE) {
- mask |= BTDM_CFG_BT_DATA_RELEASE;
- }
-
#if CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4
mask |= BTDM_CFG_HCI_UART;
#endif
static void btdm_controller_mem_init(void)
{
- /* initialise .bss, .data and .etc section */
+ /* initialise .data section */
memcpy(&_data_start_btdm, (void *)_data_start_btdm_rom, &_data_end_btdm - &_data_start_btdm);
ESP_LOGD(BTDM_LOG_TAG, ".data initialise [0x%08x] <== [0x%08x]\n", (uint32_t)&_data_start_btdm, _data_start_btdm_rom);
+ //initial em, .bss section
for (int i = 1; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) {
if (btdm_dram_available_region[i].mode != ESP_BT_MODE_IDLE) {
memset((void *)btdm_dram_available_region[i].start, 0x0, btdm_dram_available_region[i].end - btdm_dram_available_region[i].start);
BaseType_t ret;
uint32_t btdm_cfg_mask = 0;
+ osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
+ if (osi_funcs_p == NULL) {
+ return ESP_ERR_NO_MEM;
+ }
+
+ memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t));
+ if (btdm_osi_funcs_register(osi_funcs_p) != 0) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return ESP_ERR_INVALID_STATE;
}
return ESP_ERR_INVALID_ARG;
}
+ //overwrite some parameters
+ cfg->bt_max_sync_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF;
+ cfg->magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL;
+
+ if (((cfg->mode & ESP_BT_MODE_BLE) && (cfg->ble_max_conn <= 0 || cfg->ble_max_conn > BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT))
+ || ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_acl_conn <= 0 || cfg->bt_max_acl_conn > BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT))
+ || ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_sync_conn > BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT))) {
+ return ESP_ERR_INVALID_ARG;
+ }
+
#ifdef CONFIG_PM_ENABLE
esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock);
if (err != ESP_OK) {
memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
#endif
- btdm_osi_funcs_register(&osi_funcs);
-
btdm_controller_mem_init();
periph_module_enable(PERIPH_BT_MODULE);
memset(btdm_queue_table, 0, sizeof(btdm_queue_item_t) * BTDM_MAX_QUEUE_NUM);
#endif
+ free(osi_funcs_p);
+ osi_funcs_p = NULL;
+
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
btdm_lpcycle_us = 0;
return ESP_ERR_INVALID_STATE;
}
- //check the mode is available mode
- if (mode & ~btdm_dram_available_region[0].mode) {
+ //As the history reason, mode should be equal to the mode which set in esp_bt_controller_init()
+ if (mode != btdm_controller_get_mode()) {
return ESP_ERR_INVALID_ARG;
}
extern "C" {
#endif
+#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x5A5AA5A5
+
/**
- * @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.
+ * @brief Bluetooth mode for controller enable/disable
*/
-typedef struct {
- uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
- uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
- uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
- uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
- uint8_t scan_duplicate_mode; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
- uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
- uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
- uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
- uint32_t controller_debug_flag; /*!< Controller debug log flag */
-} esp_bt_controller_config_t;
+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;
#ifdef CONFIG_BT_ENABLED
-/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
+/* While scanning, if the free memory value in controller is less than SCAN_SEND_ADV_RESERVED_SIZE,
the adv packet will be discarded until the memory is restored. */
#define SCAN_SEND_ADV_RESERVED_SIZE 1000
/* enable controller log debug when adv lost */
#define CONTROLLER_ADV_LOST_DEBUG_BIT (0<<0)
#ifdef CONFIG_BT_HCI_UART_NO
-#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
+#define BT_HCI_UART_NO_DEFAULT CONFIG_BT_HCI_UART_NO
#else
-#define BT_HCI_UART_NO_DEFAULT 1
+#define BT_HCI_UART_NO_DEFAULT 1
#endif /* BT_HCI_UART_NO_DEFAULT */
#ifdef CONFIG_BT_HCI_UART_BAUDRATE
-#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
+#define BT_HCI_UART_BAUDRATE_DEFAULT CONFIG_BT_HCI_UART_BAUDRATE
#else
-#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
+#define BT_HCI_UART_BAUDRATE_DEFAULT 921600
#endif /* BT_HCI_UART_BAUDRATE_DEFAULT */
/* normal adv cache size */
#ifdef CONFIG_DUPLICATE_SCAN_CACHE_SIZE
-#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
+#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE CONFIG_DUPLICATE_SCAN_CACHE_SIZE
#else
-#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
+#define NORMAL_SCAN_DUPLICATE_CACHE_SIZE 20
#endif
#ifndef CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
#define CONFIG_BLE_MESH_SCAN_DUPLICATE_EN FALSE
#endif
-#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
-#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
+#define SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY 0
+#define SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV 1
#if CONFIG_BLE_MESH_SCAN_DUPLICATE_EN
- #define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
+ #define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_MESH_ADV
#ifdef CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
- #define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
+ #define MESH_DUPLICATE_SCAN_CACHE_SIZE CONFIG_MESH_DUPLICATE_SCAN_CACHE_SIZE
#else
- #define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
+ #define MESH_DUPLICATE_SCAN_CACHE_SIZE 50
#endif
#else
#define SCAN_DUPLICATE_MODE SCAN_DUPLICATE_MODE_NORMAL_ADV_ONLY
- #define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
+ #define MESH_DUPLICATE_SCAN_CACHE_SIZE 0
+#endif
+
+#if defined(CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY)
+#define BTDM_CONTROLLER_MODE_EFF ESP_BT_MODE_BLE
+#elif defined(CONFIG_BTDM_CONTROLLER_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
-#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
- .controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
- .controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
- .hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
- .hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
- .scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
- .normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
- .mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
- .send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
- .controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
+#define BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT 9 //Maximum BLE connection limitation
+#define BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT 7 //Maximum ACL connection limitation
+#define BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT 3 //Maximum SCO/eSCO connection limitation
+
+#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
+ .controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
+ .controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
+ .hci_uart_no = BT_HCI_UART_NO_DEFAULT, \
+ .hci_uart_baudrate = BT_HCI_UART_BAUDRATE_DEFAULT, \
+ .scan_duplicate_mode = SCAN_DUPLICATE_MODE, \
+ .normal_adv_size = NORMAL_SCAN_DUPLICATE_CACHE_SIZE, \
+ .mesh_adv_size = MESH_DUPLICATE_SCAN_CACHE_SIZE, \
+ .send_adv_reserved_size = SCAN_SEND_ADV_RESERVED_SIZE, \
+ .controller_debug_flag = CONTROLLER_ADV_LOST_DEBUG_BIT, \
+ .mode = BTDM_CONTROLLER_MODE_EFF, \
+ .ble_max_conn = CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF, \
+ .bt_max_acl_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF, \
+ .bt_max_sync_conn = CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF, \
+ .magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
};
#else
#endif
/**
- * @brief Bluetooth mode for controller enable/disable
+ * @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 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;
+typedef struct {
+ /*
+ * Following parameters can be configured runtime, when call esp_bt_controller_init()
+ */
+ uint16_t controller_task_stack_size; /*!< Bluetooth controller task stack size */
+ uint8_t controller_task_prio; /*!< Bluetooth controller task priority */
+ uint8_t hci_uart_no; /*!< If use UART1/2 as HCI IO interface, indicate UART number */
+ uint32_t hci_uart_baudrate; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
+ uint8_t scan_duplicate_mode; /*!< If use UART1/2 as HCI IO interface, indicate UART baudrate */
+ uint16_t normal_adv_size; /*!< Normal adv size for scan duplicate */
+ uint16_t mesh_adv_size; /*!< Mesh adv size for scan duplicate */
+ uint16_t send_adv_reserved_size; /*!< Controller minimum memory value */
+ uint32_t controller_debug_flag; /*!< Controller debug log flag */
+ uint8_t mode; /*!< Controller mode: BR/EDR, BLE or Dual Mode */
+ uint8_t ble_max_conn; /*!< BLE maximum connection numbers */
+ uint8_t bt_max_acl_conn; /*!< BR/EDR maximum ACL connection numbers */
+ /*
+ * Following parameters can not be configured runtime when call esp_bt_controller_init()
+ * It will be overwrite with a constant value which in menuconfig or from a macro.
+ * So, do not modify the value when esp_bt_controller_init()
+ */
+ uint8_t bt_max_sync_conn; /*!< BR/EDR maxium ACL connection numbers. Effective in menuconfig */
+ uint32_t magic; /*!< Magic number */
+} esp_bt_controller_config_t;
/**
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
ESP_BT_CONTROLLER_STATUS_NUM,
} esp_bt_controller_status_t;
-
/**
* @brief BLE tx power type
* ESP_BLE_PWR_TYPE_CONN_HDL0-8: for each connection, and only be set after connection completed.
esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path);
/**
- * @brief Initialize BT controller to allocate task and other resource.
- * @param cfg: Initial configuration of BT controller.
- * This function should be called only once, before any other BT functions are called.
- * @return ESP_OK - success, other - failed
+ * @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);
* 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.
+ * @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);
* register the vhci referece callback, the call back
* struct defined by vhci_host_callback structure.
* @param callback esp_vhci_host_callback type variable
+ * @return ESP_OK - success, ESP_FAIL - failed
*/
-void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback);
+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