Explorar o código

Merge branch 'feature/decrease_bt_contrller_memory_with_new_mem_reserved' into 'master'

decrease bt contrller memory with new mem reserved

See merge request idf/esp-idf!2791
Jiang Jiang Jian %!s(int64=7) %!d(string=hai) anos
pai
achega
00ef8bf726
Modificáronse 31 ficheiros con 540 adicións e 226 borrados
  1. 103 37
      components/bt/Kconfig
  2. 3 2
      components/bt/bluedroid/hci/hci_hal_h4.c
  3. 234 124
      components/bt/bt.c
  4. 85 51
      components/bt/include/esp_bt.h
  5. 1 1
      components/bt/lib
  6. 1 0
      components/esp32/ld/esp32.rom.ld
  7. 32 0
      components/soc/include/soc/soc_memory_layout.h
  8. 3 0
      examples/bluetooth/a2dp_sink/sdkconfig.defaults
  9. 3 0
      examples/bluetooth/a2dp_source/sdkconfig.defaults
  10. 3 0
      examples/bluetooth/ble_adv/sdkconfig.defaults
  11. 3 1
      examples/bluetooth/ble_eddystone/sdkconfig.defaults
  12. 3 0
      examples/bluetooth/ble_hid_device_demo/sdkconfig.defaults
  13. 3 1
      examples/bluetooth/ble_ibeacon/sdkconfig.defaults
  14. 3 1
      examples/bluetooth/ble_spp_client/sdkconfig.defaults
  15. 4 1
      examples/bluetooth/ble_spp_server/sdkconfig.defaults
  16. 4 0
      examples/bluetooth/ble_throughput/throughput_client/sdkconfig.defaults
  17. 4 0
      examples/bluetooth/ble_throughput/throughput_server/sdkconfig.defaults
  18. 3 0
      examples/bluetooth/blufi/sdkconfig.defaults
  19. 3 0
      examples/bluetooth/bt_discovery/sdkconfig.defaults
  20. 4 1
      examples/bluetooth/bt_spp_acceptor/sdkconfig.defaults
  21. 4 1
      examples/bluetooth/bt_spp_initiator/sdkconfig.defaults
  22. 4 1
      examples/bluetooth/bt_spp_vfs_acceptor/sdkconfig.defaults
  23. 4 1
      examples/bluetooth/bt_spp_vfs_initiator/sdkconfig.defaults
  24. 6 0
      examples/bluetooth/controller_hci_uart/sdkconfig.defaults
  25. 3 0
      examples/bluetooth/gatt_client/sdkconfig.defaults
  26. 3 1
      examples/bluetooth/gatt_security_client/sdkconfig.defaults
  27. 3 0
      examples/bluetooth/gatt_security_server/sdkconfig.defaults
  28. 3 0
      examples/bluetooth/gatt_server/sdkconfig.defaults
  29. 3 0
      examples/bluetooth/gatt_server_service_table/sdkconfig.defaults
  30. 4 1
      examples/bluetooth/gattc_multi_connect/sdkconfig.defaults
  31. 1 1
      tools/ci/build_examples.sh

+ 103 - 37
components/bt/Kconfig

@@ -6,6 +6,68 @@ config BT_ENABLED
     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 Connections"
+    depends on BTDM_CONTROLLER_MODE_BLE_ONLY || BTDM_CONTROLLER_MODE_BTDM
+    default 3
+    range 1 9
+    help
+        BLE maximum connections of bluetooth controller.
+        Each connection uses 1KB static DRAM whenever the BT controller is enabled.
+
+config BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN
+    int "BR/EDR ACL Max Connections"
+    depends on BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+    default 2
+    range 1 7
+    help
+        BR/EDR ACL maximum connections of bluetooth controller. 
+        Each connection uses 1.2KB static DRAM whenever the BT controller is enabled.
+
+config BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN
+    int "BR/EDR Sync(SCO/eSCO) Max Connections"
+    depends on BTDM_CONTROLLER_MODE_BR_EDR_ONLY || BTDM_CONTROLLER_MODE_BTDM
+    default 0
+    range 0 3
+    help
+        BR/EDR Synchronize maximum connections of bluetooth controller.
+        Each connection uses 2KB static DRAM whenever the BT controller is enabled.
+
+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
@@ -104,6 +166,42 @@ config BTDM_LPCLK_SEL_EXT_32K_XTAL
     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
@@ -213,28 +311,28 @@ endchoice
 
 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.
@@ -1018,38 +1116,6 @@ config BLE_HOST_QUEUE_CONGESTION_CHECK
         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
@@ -1058,7 +1124,7 @@ config SMP_ENABLE
 # 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

+ 3 - 2
components/bt/bluedroid/hci/hci_hal_h4.c

@@ -112,8 +112,9 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks)
     xTaskCreatePinnedToCore(hci_hal_h4_rx_handler, HCI_H4_TASK_NAME, HCI_H4_TASK_STACK_SIZE, NULL, HCI_H4_TASK_PRIO, &xHciH4TaskHandle, HCI_H4_TASK_PINNED_TO_CORE);
 
     //register vhci host cb
-    esp_vhci_host_register_callback(&vhci_host_cb);
-
+    if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
+        return false;
+    }
 
     return true;
 }

+ 234 - 124
components/bt/bt.c

@@ -41,11 +41,16 @@
 #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 */
@@ -56,65 +61,20 @@
 #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) \
@@ -127,45 +87,43 @@ do{\
 } 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);
@@ -193,6 +151,7 @@ struct osi_funcs_t {
     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);
@@ -202,8 +161,175 @@ struct osi_funcs_t {
     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;
@@ -220,7 +346,7 @@ static esp_pm_lock_handle_t s_pm_lock;
 #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;
@@ -241,7 +367,7 @@ bool IRAM_ATTR btdm_queue_generic_register(const btdm_queue_item_t *queue)
     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;
@@ -579,6 +705,11 @@ static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no)
     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);
@@ -650,45 +781,6 @@ static void IRAM_ATTR btdm_sleep_exit_wrapper(void)
     }
 }
 
-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();
@@ -702,19 +794,15 @@ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
     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
@@ -730,10 +818,11 @@ static uint32_t btdm_config_mask_load(void)
 
 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);
@@ -834,6 +923,16 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
     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;
     }
@@ -852,6 +951,16 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
         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) {
@@ -873,8 +982,6 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
     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);
@@ -936,6 +1043,9 @@ esp_err_t esp_bt_controller_deinit(void)
     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;
@@ -956,8 +1066,8 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
         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;
     }
 

+ 85 - 51
components/bt/include/esp_bt.h

@@ -25,78 +25,90 @@
 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
@@ -104,14 +116,34 @@ the adv packet will be discarded until the memory is restored. */
 #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
@@ -123,7 +155,6 @@ typedef enum {
     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.
@@ -231,10 +262,11 @@ esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_l
 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);
 
@@ -252,7 +284,8 @@ esp_err_t esp_bt_controller_deinit(void);
  *               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);
@@ -294,8 +327,9 @@ void esp_vhci_host_send_packet(uint8_t *data, uint16_t len);
  * 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

+ 1 - 1
components/bt/lib

@@ -1 +1 @@
-Subproject commit d3c834d66153b1acd6b4e5e744a66aaa55ae5c40
+Subproject commit fb64c036cef2baa41408573a60dcdc7a58176f6d

+ 1 - 0
components/esp32/ld/esp32.rom.ld

@@ -1620,6 +1620,7 @@ PROVIDE ( hci_tl_env = 0x3ffb8154 );
 PROVIDE ( ld_acl_env = 0x3ffb8258 );
 PROVIDE ( ea_env = 0x3ffb80ec );
 PROVIDE ( lc_sco_data_path_config = 0x3ffb81f8 );
+PROVIDE ( lc_sco_env = 0x3ffb81fc );
 PROVIDE ( ld_active_ch_map = 0x3ffb8334 );
 PROVIDE ( ld_bcst_acl_env = 0x3ffb8274 );
 PROVIDE ( ld_csb_rx_env = 0x3ffb8278 );

+ 32 - 0
components/soc/include/soc/soc_memory_layout.h

@@ -20,6 +20,38 @@
 #include "sdkconfig.h"
 #include "esp_attr.h"
 
+#ifdef CONFIG_BT_ENABLED
+
+#define SOC_MEM_BT_DATA_START               0x3ffae6e0
+#define SOC_MEM_BT_DATA_END                 0x3ffaff10
+#define SOC_MEM_BT_EM_START                 0x3ffb0000
+#define SOC_MEM_BT_EM_END                   0x3ffb7cd8
+#define SOC_MEM_BT_EM_BTDM0_START           0x3ffb0000
+#define SOC_MEM_BT_EM_BTDM0_END             0x3ffb09a8
+#define SOC_MEM_BT_EM_BLE_START             0x3ffb09a8
+#define SOC_MEM_BT_EM_BLE_END               0x3ffb1ddc
+#define SOC_MEM_BT_EM_BTDM1_START           0x3ffb1ddc
+#define SOC_MEM_BT_EM_BTDM1_END             0x3ffb2730
+#define SOC_MEM_BT_EM_BREDR_START           0x3ffb2730
+#define SOC_MEM_BT_EM_BREDR_NO_SYNC_END     0x3ffb6388  //Not calculate with synchronize connection support
+#define SOC_MEM_BT_EM_BREDR_END             0x3ffb7cd8  //Calculate with synchronize connection support
+#define SOC_MEM_BT_EM_SYNC0_START           0x3ffb6388
+#define SOC_MEM_BT_EM_SYNC0_END             0x3ffb6bf8
+#define SOC_MEM_BT_EM_SYNC1_START           0x3ffb6bf8
+#define SOC_MEM_BT_EM_SYNC1_END             0x3ffb7468
+#define SOC_MEM_BT_EM_SYNC2_START           0x3ffb7468
+#define SOC_MEM_BT_EM_SYNC2_END             0x3ffb7cd8
+#define SOC_MEM_BT_BSS_START                0x3ffb8000
+#define SOC_MEM_BT_BSS_END                  0x3ffb9a20
+#define SOC_MEM_BT_MISC_START               0x3ffbdb28
+#define SOC_MEM_BT_MISC_END                 0x3ffbdb5c
+
+#define SOC_MEM_BT_EM_PER_SYNC_SIZE         0x870
+
+#define SOC_MEM_BT_EM_BREDR_REAL_END        (SOC_MEM_BT_EM_BREDR_NO_SYNC_END + CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF * SOC_MEM_BT_EM_PER_SYNC_SIZE)
+
+#endif //CONFIG_BT_ENABLED
+
 #define SOC_MEMORY_TYPE_NO_PRIOS 3
 
 /* Type descriptor holds a description for a particular type of memory on a particular SoC.

+ 3 - 0
examples/bluetooth/a2dp_sink/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled and
 # Classic BT is enabled and BT_DRAM_RELEASE is disabled
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_BLUEDROID_ENABLED=y
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_A2DP_ENABLE=y

+ 3 - 0
examples/bluetooth/a2dp_source/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled and
 # Classic BT is enabled
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_BLUEDROID_ENABLED=y
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_A2DP_ENABLE=y

+ 3 - 0
examples/bluetooth/ble_adv/sdkconfig.defaults

@@ -5,3 +5,6 @@
 # BT config
 #
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 1
examples/bluetooth/ble_eddystone/sdkconfig.defaults

@@ -1,4 +1,6 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
-CONFIG_WIFI_ENABLED=n
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 0
examples/bluetooth/ble_hid_device_demo/sdkconfig.defaults

@@ -1,3 +1,6 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 1
examples/bluetooth/ble_ibeacon/sdkconfig.defaults

@@ -1,4 +1,6 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
-CONFIG_WIFI_ENABLED=n
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 1
examples/bluetooth/ble_spp_client/sdkconfig.defaults

@@ -1,4 +1,6 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
-CONFIG_WIFI_ENABLED=n
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 4 - 1
examples/bluetooth/ble_spp_server/sdkconfig.defaults

@@ -5,7 +5,10 @@
 # BT config
 #
 CONFIG_BT_ENABLED=y
-
+CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 #
 # ESP32-specific config
 #

+ 4 - 0
examples/bluetooth/ble_throughput/throughput_client/sdkconfig.defaults

@@ -1,6 +1,10 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
+CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=9
 CONFIG_GATTS_NOTIFY_THROUGHPUT=y
 CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n
 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=y

+ 4 - 0
examples/bluetooth/ble_throughput/throughput_server/sdkconfig.defaults

@@ -1,6 +1,10 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
+CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=9
 CONFIG_GATTS_NOTIFY_THROUGHPUT=y
 CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=n
 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=y

+ 3 - 0
examples/bluetooth/blufi/sdkconfig.defaults

@@ -5,6 +5,9 @@
 # BT config
 #
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0=y
 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=
 CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0

+ 3 - 0
examples/bluetooth/bt_discovery/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled and
 # Classic BT is enabled and BT_DRAM_RELEASE is disabled
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_A2DP_ENABLE=
 CONFIG_GATTS_ENABLE=

+ 4 - 1
examples/bluetooth/bt_spp_acceptor/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_WIFI_ENABLED=n
-CONFIG_BT_SPP_ENABLED=y
+CONFIG_BT_SPP_ENABLED=y

+ 4 - 1
examples/bluetooth/bt_spp_initiator/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_WIFI_ENABLED=n
-CONFIG_BT_SPP_ENABLED=y
+CONFIG_BT_SPP_ENABLED=y

+ 4 - 1
examples/bluetooth/bt_spp_vfs_acceptor/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_WIFI_ENABLED=n
-CONFIG_BT_SPP_ENABLED=y
+CONFIG_BT_SPP_ENABLED=y

+ 4 - 1
examples/bluetooth/bt_spp_vfs_initiator/sdkconfig.defaults

@@ -1,6 +1,9 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 CONFIG_CLASSIC_BT_ENABLED=y
 CONFIG_WIFI_ENABLED=n
-CONFIG_BT_SPP_ENABLED=y
+CONFIG_BT_SPP_ENABLED=y

+ 6 - 0
examples/bluetooth/controller_hci_uart/sdkconfig.defaults

@@ -5,6 +5,12 @@
 # BT config
 #
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=y
+CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=9
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=7
+CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=3
 CONFIG_BLUEDROID_ENABLED=n
 CONFIG_BT_HCI_UART=y
 CONFIG_BT_HCI_UART_NO_DEFAULT=1

+ 3 - 0
examples/bluetooth/gatt_client/sdkconfig.defaults

@@ -1,3 +1,6 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 1
examples/bluetooth/gatt_security_client/sdkconfig.defaults

@@ -1,4 +1,6 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
-CONFIG_WIFI_ENABLED=n
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 0
examples/bluetooth/gatt_security_server/sdkconfig.defaults

@@ -1,3 +1,6 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 0
examples/bluetooth/gatt_server/sdkconfig.defaults

@@ -1,3 +1,6 @@
 # Override some defaults so BT stack is enabled
 # by default in this example
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=

+ 3 - 0
examples/bluetooth/gatt_server_service_table/sdkconfig.defaults

@@ -5,6 +5,9 @@
 # BT config
 #
 CONFIG_BT_ENABLED=y
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
 
 #
 # ESP32-specific config

+ 4 - 1
examples/bluetooth/gattc_multi_connect/sdkconfig.defaults

@@ -1,4 +1,7 @@
 # Override some defaults so BT stack is enabled
 # and WiFi disabled by default in this example
 CONFIG_BT_ENABLED=y
-CONFIG_WIFI_ENABLED=n
+CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y
+CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=
+CONFIG_BTDM_CONTROLLER_MODE_BTDM=
+CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=9

+ 1 - 1
tools/ci/build_examples.sh

@@ -158,7 +158,7 @@ echo -e "\nFound issues:"
 # "error.o" or "-Werror" in compiler's command line
 # "reassigning to symbol" or "changes choice state" in sdkconfig
 sort -u "${LOG_SUSPECTED}" | \
-grep -v "library/error.o\|\ -Werror\|reassigning to symbol\|changes choice state" \
+grep -v "library/error\.o\|\ -Werror\|error\.d\|reassigning to symbol\|changes choice state" \
     && RESULT=$RESULT_ISSUES \
     || echo -e "\tNone"