summaryrefslogtreecommitdiff
path: root/lib/bt/controller/esp32/bt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bt/controller/esp32/bt.c')
-rw-r--r--lib/bt/controller/esp32/bt.c194
1 files changed, 138 insertions, 56 deletions
diff --git a/lib/bt/controller/esp32/bt.c b/lib/bt/controller/esp32/bt.c
index d8792e0f..f26dd4bc 100644
--- a/lib/bt/controller/esp32/bt.c
+++ b/lib/bt/controller/esp32/bt.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -25,7 +25,9 @@
#include "esp_task.h"
#include "esp_intr_alloc.h"
#include "esp_attr.h"
+#ifdef CONFIG_ESP_PHY_ENABLED
#include "esp_phy_init.h"
+#endif
#include "esp_bt.h"
#include "esp_err.h"
#include "esp_log.h"
@@ -35,7 +37,9 @@
#include "soc/rtc.h"
#include "soc/soc_memory_layout.h"
#include "soc/dport_reg.h"
+#ifdef CONFIG_ESP_COEX_ENABLED
#include "private/esp_coexist_internal.h"
+#endif
#include "esp_timer.h"
#if !CONFIG_FREERTOS_UNICORE
#include "esp_ipc.h"
@@ -89,7 +93,7 @@ do{\
} while(0)
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
-#define OSI_VERSION 0x00010004
+#define OSI_VERSION 0x00010005
#define OSI_MAGIC_VALUE 0xFADEBEAD
/* Types definition
@@ -176,6 +180,7 @@ struct osi_funcs_t {
void (*_interrupt_l3_restore)(void);
void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size);
int (* _coex_version_get)(unsigned int *major, unsigned int *minor, unsigned int *patch);
+ void (* _patch_apply)(void);
uint32_t _magic;
};
@@ -232,16 +237,16 @@ extern uint32_t _data_end_btdm_rom;
extern uint32_t _bt_bss_start;
extern uint32_t _bt_bss_end;
-extern uint32_t _nimble_bss_start;
-extern uint32_t _nimble_bss_end;
-extern uint32_t _btdm_bss_start;
-extern uint32_t _btdm_bss_end;
+extern uint32_t _bt_controller_bss_start;
+extern uint32_t _bt_controller_bss_end;
extern uint32_t _bt_data_start;
extern uint32_t _bt_data_end;
-extern uint32_t _nimble_data_start;
-extern uint32_t _nimble_data_end;
-extern uint32_t _btdm_data_start;
-extern uint32_t _btdm_data_end;
+extern uint32_t _bt_controller_data_start;
+extern uint32_t _bt_controller_data_end;
+
+extern void config_bt_funcs_reset(void);
+extern void config_ble_funcs_reset(void);
+extern void config_btdm_funcs_reset(void);
/* Local Function Declare
*********************************************************************
@@ -315,6 +320,7 @@ static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t i
static void interrupt_l3_disable(void);
static void interrupt_l3_restore(void);
static void bt_controller_deinit_internal(void);
+static void patch_apply(void);
/* Local variable definition
***************************************************************************
@@ -402,6 +408,7 @@ static const struct osi_funcs_t osi_funcs_ro = {
._customer_queue_create = NULL,
#endif /* CONFIG_BTDM_CTRL_HLI */
._coex_version_get = coex_version_get_wrapper,
+ ._patch_apply = patch_apply,
._magic = OSI_MAGIC_VALUE,
};
@@ -753,7 +760,7 @@ static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block
* @param item The message which will be send
* @param hptw need do task yield or not
* @return send success or not
- * There is an issue here: When the queue is full, it may reture true but it send fail to the queue, sometimes.
+ * There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes.
* But in Bluetooth controller's isr, We don't care about the return value.
* It only required tp send success when the queue is empty all the time.
* So, this function meets the requirement.
@@ -823,7 +830,7 @@ static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, vo
static int32_t task_create_wrapper(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id)
{
- return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY));
+ return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < CONFIG_FREERTOS_NUMBER_OF_CORES ? core_id : tskNO_AFFINITY));
}
static void task_delete_wrapper(void *task_handle)
@@ -1274,7 +1281,45 @@ static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
return ret;
}
-esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
+typedef struct {
+ intptr_t start;
+ intptr_t end;
+ const char* name;
+} bt_area_t;
+
+
+static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
+{
+ esp_err_t ret = ESP_OK;
+ intptr_t mem_start = area->start;
+ intptr_t mem_end = area->end;
+ if (mem_start != mem_end) {
+ ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
+ ret = try_heap_caps_add_region(mem_start, mem_end);
+ }
+ return ret;
+}
+
+static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
+{
+ esp_err_t ret = ESP_OK;
+
+ if (area1->end == area2->start) {
+ bt_area_t merged_area = {
+ .start = area1->start,
+ .end = area2->end,
+ .name = area1->name
+ };
+ ret = esp_bt_mem_release_area(&merged_area);
+ } else {
+ esp_bt_mem_release_area(area1);
+ ret = esp_bt_mem_release_area(area2);
+ }
+
+ return ret;
+}
+
+static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
{
bool update = true;
intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
@@ -1325,61 +1370,86 @@ esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
}
}
+ return ESP_OK;
+}
+
+esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
+{
+ esp_err_t ret = ESP_OK;
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
+ return ESP_ERR_INVALID_STATE;
+ }
+
if (mode == ESP_BT_MODE_BTDM) {
- mem_start = (intptr_t)&_btdm_bss_start;
- mem_end = (intptr_t)&_btdm_bss_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release BTDM BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
- }
- mem_start = (intptr_t)&_btdm_data_start;
- mem_end = (intptr_t)&_btdm_data_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release BTDM Data [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
- }
+ bt_area_t cont_bss = {
+ .start = (intptr_t)&_bt_controller_bss_start,
+ .end = (intptr_t)&_bt_controller_bss_end,
+ .name = "BT Controller BSS",
+ };
+ bt_area_t cont_data = {
+ .start = (intptr_t)&_bt_controller_data_start,
+ .end = (intptr_t)&_bt_controller_data_end,
+ .name = "BT Controller Data"
+ };
+
+ ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
}
- return ESP_OK;
+
+ if (ret == ESP_OK) {
+ ret = esp_bt_controller_rom_mem_release(mode);
+ }
+
+ return ret;
}
esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
{
- int ret;
- intptr_t mem_start, mem_end;
+ esp_err_t ret = ESP_OK;
- ret = esp_bt_controller_mem_release(mode);
- if (ret != ESP_OK) {
- return ret;
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
+ return ESP_ERR_INVALID_STATE;
}
+ bt_area_t bss = {
+ .start = (intptr_t)&_bt_bss_start,
+ .end = (intptr_t)&_bt_bss_end,
+ .name = "BT BSS",
+ };
+ bt_area_t cont_bss = {
+ .start = (intptr_t)&_bt_controller_bss_start,
+ .end = (intptr_t)&_bt_controller_bss_end,
+ .name = "BT Controller BSS",
+ };
+ bt_area_t data = {
+ .start = (intptr_t)&_bt_data_start,
+ .end = (intptr_t)&_bt_data_end,
+ .name = "BT Data",
+ };
+ bt_area_t cont_data = {
+ .start = (intptr_t)&_bt_controller_data_start,
+ .end = (intptr_t)&_bt_controller_data_end,
+ .name = "BT Controller Data"
+ };
+
if (mode == ESP_BT_MODE_BTDM) {
- mem_start = (intptr_t)&_bt_bss_start;
- mem_end = (intptr_t)&_bt_bss_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release BT BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
- }
- mem_start = (intptr_t)&_bt_data_start;
- mem_end = (intptr_t)&_bt_data_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release BT Data [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
+ /* Start by freeing Bluetooth BSS section */
+ if (ret == ESP_OK) {
+ ret = esp_bt_mem_release_areas(&bss, &cont_bss);
}
- mem_start = (intptr_t)&_nimble_bss_start;
- mem_end = (intptr_t)&_nimble_bss_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE BSS [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
- }
- mem_start = (intptr_t)&_nimble_data_start;
- mem_end = (intptr_t)&_nimble_data_end;
- if (mem_start != mem_end) {
- ESP_LOGD(BTDM_LOG_TAG, "Release NimBLE Data [0x%08x] - [0x%08x]", mem_start, mem_end);
- ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
+ /* Do the same thing with the Bluetooth data section */
+ if (ret == ESP_OK) {
+ ret = esp_bt_mem_release_areas(&data, &cont_data);
}
}
- return ESP_OK;
+
+ /* free data and BSS section for Bluetooth controller ROM code */
+ if (ret == ESP_OK) {
+ ret = esp_bt_controller_rom_mem_release(mode);
+ }
+
+ return ret;
}
#if CONFIG_BTDM_CTRL_HLI
@@ -1643,6 +1713,18 @@ static void bt_shutdown(void)
return;
}
+static void patch_apply(void)
+{
+ config_btdm_funcs_reset();
+
+#ifndef CONFIG_BTDM_CTRL_MODE_BLE_ONLY
+ config_bt_funcs_reset();
+#endif
+
+#ifndef CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
+ config_ble_funcs_reset();
+#endif
+}
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
{
@@ -1676,7 +1758,7 @@ esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
sdk_config_set_bt_pll_track_enable(true);
- // inititalize bluetooth baseband
+ // initialize bluetooth baseband
btdm_check_and_init_bb();
ret = btdm_controller_enable(mode);
@@ -1839,7 +1921,7 @@ esp_err_t esp_ble_scan_dupilcate_list_flush(void)
/**
* This function re-write controller's function,
- * As coredump can not show paramerters in function which is in a .a file.
+ * As coredump can not show parameters in function which is in a .a file.
*
* After coredump fixing this issue, just delete this function.
*/