1 /*
2 * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #include "sdkconfig.h"
13 #include "esp_heap_caps.h"
14 #include "esp_heap_caps_init.h"
15 #include "freertos/FreeRTOS.h"
16 #include "freertos/task.h"
17 #include "freertos/queue.h"
18 #include "freertos/semphr.h"
19 #include "freertos/xtensa_api.h"
20 #include "freertos/portmacro.h"
21 #include "xtensa/core-macros.h"
22 #include "esp_types.h"
23 #include "esp_mac.h"
24 #include "esp_random.h"
25 #include "esp_task.h"
26 #include "esp_intr_alloc.h"
27 #include "esp_attr.h"
28 #include "esp_phy_init.h"
29 #include "esp_bt.h"
30 #include "esp_err.h"
31 #include "esp_log.h"
32 #include "esp_pm.h"
33 #include "esp_private/esp_clk.h"
34 #include "esp_private/periph_ctrl.h"
35 #include "soc/rtc.h"
36 #include "soc/soc_memory_layout.h"
37 #include "soc/dport_reg.h"
38 #include "private/esp_coexist_internal.h"
39 #include "esp_timer.h"
40 #if !CONFIG_FREERTOS_UNICORE
41 #include "esp_ipc.h"
42 #endif
43
44 #include "esp_rom_sys.h"
45 #include "hli_api.h"
46
47 #if CONFIG_BT_ENABLED
48
49 /* Macro definition
50 ************************************************************************
51 */
52
53 #define UNUSED(x) (void)(x)
54 #define BTDM_LOG_TAG "BTDM_INIT"
55
56 #define BTDM_INIT_PERIOD (5000) /* ms */
57
58 /* Bluetooth system and controller config */
59 #define BTDM_CFG_BT_DATA_RELEASE (1<<0)
60 #define BTDM_CFG_HCI_UART (1<<1)
61 #define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1<<2)
62 #define BTDM_CFG_SCAN_DUPLICATE_OPTIONS (1<<3)
63 #define BTDM_CFG_SEND_ADV_RESERVED_SIZE (1<<4)
64 #define BTDM_CFG_BLE_FULL_SCAN_SUPPORTED (1<<5)
65
66 /* Sleep mode */
67 #define BTDM_MODEM_SLEEP_MODE_NONE (0)
68 #define BTDM_MODEM_SLEEP_MODE_ORIG (1)
69 #define BTDM_MODEM_SLEEP_MODE_EVED (2) // sleep mode for BLE controller, used only for internal test.
70
71 /* Low Power Clock Selection */
72 #define BTDM_LPCLK_SEL_XTAL (0)
73 #define BTDM_LPCLK_SEL_XTAL32K (1)
74 #define BTDM_LPCLK_SEL_RTC_SLOW (2)
75 #define BTDM_LPCLK_SEL_8M (3)
76
77 /* Sleep and wakeup interval control */
78 #define BTDM_MIN_SLEEP_DURATION (12) // threshold of interval in slots to allow to fall into modem sleep
79 #define BTDM_MODEM_WAKE_UP_DELAY (4) // delay in slots of modem wake up procedure, including re-enable PHY/RF
80
81 #define BT_DEBUG(...)
82 #define BT_API_CALL_CHECK(info, api_call, ret) \
83 do{\
84 esp_err_t __err = (api_call);\
85 if ((ret) != __err) {\
86 BT_DEBUG("%s %d %s ret=0x%X\n", __FUNCTION__, __LINE__, (info), __err);\
87 return __err;\
88 }\
89 } while(0)
90
91 #define OSI_FUNCS_TIME_BLOCKING 0xffffffff
92 #define OSI_VERSION 0x00010005
93 #define OSI_MAGIC_VALUE 0xFADEBEAD
94
95 #define BLE_CONTROLLER_MALLOC_CAPS (MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL)
96 /* Types definition
97 ************************************************************************
98 */
99
100 /* VHCI function interface */
101 typedef struct vhci_host_callback {
102 void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
103 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*/
104 } vhci_host_callback_t;
105
106 /* Dram region */
107 typedef struct {
108 esp_bt_mode_t mode;
109 intptr_t start;
110 intptr_t end;
111 } btdm_dram_available_region_t;
112
113 typedef struct {
114 void *handle;
115 } btdm_queue_item_t;
116
117 /* OSI function */
118 struct osi_funcs_t {
119 uint32_t _version;
120 xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
121 void (*_ints_on)(unsigned int mask);
122 void (*_interrupt_disable)(void);
123 void (*_interrupt_restore)(void);
124 void (*_task_yield)(void);
125 void (*_task_yield_from_isr)(void);
126 void *(*_semphr_create)(uint32_t max, uint32_t init);
127 void (*_semphr_delete)(void *semphr);
128 int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw);
129 int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);
130 int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);
131 int32_t (*_semphr_give)(void *semphr);
132 void *(*_mutex_create)(void);
133 void (*_mutex_delete)(void *mutex);
134 int32_t (*_mutex_lock)(void *mutex);
135 int32_t (*_mutex_unlock)(void *mutex);
136 void *(* _queue_create)(uint32_t queue_len, uint32_t item_size);
137 void (* _queue_delete)(void *queue);
138 int32_t (* _queue_send)(void *queue, void *item, uint32_t block_time_ms);
139 int32_t (* _queue_send_from_isr)(void *queue, void *item, void *hptw);
140 int32_t (* _queue_recv)(void *queue, void *item, uint32_t block_time_ms);
141 int32_t (* _queue_recv_from_isr)(void *queue, void *item, void *hptw);
142 int32_t (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id);
143 void (* _task_delete)(void *task_handle);
144 bool (* _is_in_isr)(void);
145 int (* _cause_sw_intr_to_core)(int core_id, int intr_no);
146 void *(* _malloc)(size_t size);
147 void *(* _malloc_internal)(size_t size);
148 void (* _free)(void *p);
149 int32_t (* _read_efuse_mac)(uint8_t mac[6]);
150 void (* _srand)(unsigned int seed);
151 int (* _rand)(void);
152 uint32_t (* _btdm_lpcycles_2_us)(uint32_t cycles);
153 uint32_t (* _btdm_us_2_lpcycles)(uint32_t us);
154 bool (* _btdm_sleep_check_duration)(uint32_t *slot_cnt);
155 void (* _btdm_sleep_enter_phase1)(uint32_t lpcycles); /* called when interrupt is disabled */
156 void (* _btdm_sleep_enter_phase2)(void);
157 void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */
158 void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */
159 void (* _btdm_sleep_exit_phase3)(void); /* called from task */
160 bool (* _coex_bt_wakeup_request)(void);
161 void (* _coex_bt_wakeup_request_end)(void);
162 int (* _coex_bt_request)(uint32_t event, uint32_t latency, uint32_t duration);
163 int (* _coex_bt_release)(uint32_t event);
164 int (* _coex_register_bt_cb)(coex_func_cb_t cb);
165 uint32_t (* _coex_bb_reset_lock)(void);
166 void (* _coex_bb_reset_unlock)(uint32_t restore);
167 int (* _coex_schm_register_btdm_callback)(void *callback);
168 void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
169 void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
170 uint32_t (* _coex_schm_interval_get)(void);
171 uint8_t (* _coex_schm_curr_period_get)(void);
172 void *(* _coex_schm_curr_phase_get)(void);
173 int (* _coex_wifi_channel_get)(uint8_t *primary, uint8_t *secondary);
174 int (* _coex_register_wifi_channel_change_callback)(void *cb);
175 xt_handler (*_set_isr_l3)(int n, xt_handler f, void *arg);
176 void (*_interrupt_l3_disable)(void);
177 void (*_interrupt_l3_restore)(void);
178 void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size);
179 int (* _coex_version_get)(unsigned int *major, unsigned int *minor, unsigned int *patch);
180 void (* _patch_apply)(void);
181 uint32_t _magic;
182 };
183
184 typedef void (*workitem_handler_t)(void* arg);
185
186 /* External functions or values
187 ************************************************************************
188 */
189
190 /* not for user call, so don't put to include file */
191 /* OSI */
192 extern int btdm_osi_funcs_register(void *osi_funcs);
193 /* Initialise and De-initialise */
194 extern int btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts);
195 extern void btdm_controller_deinit(void);
196 extern int btdm_controller_enable(esp_bt_mode_t mode);
197 extern void btdm_controller_disable(void);
198 extern uint8_t btdm_controller_get_mode(void);
199 extern const char *btdm_controller_get_compile_version(void);
200 extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
201 extern int btdm_dispatch_work_to_controller(workitem_handler_t callback, void *arg, bool blocking);
202 /* Sleep */
203 extern void btdm_controller_enable_sleep(bool enable);
204 extern void btdm_controller_set_sleep_mode(uint8_t mode);
205 extern uint8_t btdm_controller_get_sleep_mode(void);
206 extern bool btdm_power_state_active(void);
207 extern void btdm_wakeup_request(void);
208 extern void btdm_in_wakeup_requesting_set(bool in_wakeup_requesting);
209 /* Low Power Clock */
210 extern bool btdm_lpclk_select_src(uint32_t sel);
211 extern bool btdm_lpclk_set_div(uint32_t div);
212 /* VHCI */
213 extern bool API_vhci_host_check_send_available(void);
214 extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
215 extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback);
216 /* TX power */
217 extern int ble_txpwr_set(int power_type, int power_level);
218 extern int ble_txpwr_get(int power_type);
219 extern int bredr_txpwr_set(int min_power_level, int max_power_level);
220 extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
221 extern void bredr_sco_datapath_set(uint8_t data_path);
222 extern void btdm_controller_scan_duplicate_list_clear(void);
223 /* Shutdown */
224 extern void esp_bt_controller_shutdown(void);
225 extern void sdk_config_set_bt_pll_track_enable(bool enable);
226 extern void sdk_config_set_uart_flow_ctrl_enable(bool enable);
227
228 extern char _bss_start_btdm;
229 extern char _bss_end_btdm;
230 extern char _data_start_btdm;
231 extern char _data_end_btdm;
232 extern uint32_t _data_start_btdm_rom;
233 extern uint32_t _data_end_btdm_rom;
234
235 extern uint32_t _bt_bss_start;
236 extern uint32_t _bt_bss_end;
237 extern uint32_t _bt_controller_bss_start;
238 extern uint32_t _bt_controller_bss_end;
239 extern uint32_t _bt_data_start;
240 extern uint32_t _bt_data_end;
241 extern uint32_t _bt_controller_data_start;
242 extern uint32_t _bt_controller_data_end;
243
244 extern void config_bt_funcs_reset(void);
245 extern void config_ble_funcs_reset(void);
246 extern void config_btdm_funcs_reset(void);
247 extern void config_ble_vs_qa_funcs_reset(void);
248
249 /* Local Function Declare
250 *********************************************************************
251 */
252 #if CONFIG_BTDM_CTRL_HLI
253 static xt_handler set_isr_hlevel_wrapper(int n, xt_handler f, void *arg);
254 static void interrupt_hlevel_disable(void);
255 static void interrupt_hlevel_restore(void);
256 #endif /* CONFIG_BTDM_CTRL_HLI */
257 static void task_yield(void);
258 static void task_yield_from_isr(void);
259 static void *semphr_create_wrapper(uint32_t max, uint32_t init);
260 static void semphr_delete_wrapper(void *semphr);
261 static int32_t semphr_take_from_isr_wrapper(void *semphr, void *hptw);
262 static int32_t semphr_give_from_isr_wrapper(void *semphr, void *hptw);
263 static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_ms);
264 static int32_t semphr_give_wrapper(void *semphr);
265 static void *mutex_create_wrapper(void);
266 static void mutex_delete_wrapper(void *mutex);
267 static int32_t mutex_lock_wrapper(void *mutex);
268 static int32_t mutex_unlock_wrapper(void *mutex);
269 #if CONFIG_BTDM_CTRL_HLI
270 static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
271 static void queue_delete_hlevel_wrapper(void *queue);
272 static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
273 static int32_t queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
274 static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
275 static int32_t queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
276 #else
277 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
278 static void queue_delete_wrapper(void *queue);
279 static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
280 static int32_t queue_send_from_isr_wrapper(void *queue, void *item, void *hptw);
281 static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
282 static int32_t queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw);
283 #endif /* CONFIG_BTDM_CTRL_HLI */
284 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);
285 static void task_delete_wrapper(void *task_handle);
286 static bool is_in_isr_wrapper(void);
287 static void cause_sw_intr(void *arg);
288 static int cause_sw_intr_to_core_wrapper(int core_id, int intr_no);
289 static void *malloc_internal_wrapper(size_t size);
290 static int32_t read_mac_wrapper(uint8_t mac[6]);
291 static void srand_wrapper(unsigned int seed);
292 static int rand_wrapper(void);
293 static uint32_t btdm_lpcycles_2_us(uint32_t cycles);
294 static uint32_t btdm_us_2_lpcycles(uint32_t us);
295 static bool btdm_sleep_check_duration(uint32_t *slot_cnt);
296 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
297 static void btdm_sleep_enter_phase2_wrapper(void);
298 static void btdm_sleep_exit_phase3_wrapper(void);
299 static bool coex_bt_wakeup_request(void);
300 static void coex_bt_wakeup_request_end(void);
301 static int coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration);
302 static int coex_bt_release_wrapper(uint32_t event);
303 static int coex_register_bt_cb_wrapper(coex_func_cb_t cb);
304 static uint32_t coex_bb_reset_lock_wrapper(void);
305 static void coex_bb_reset_unlock_wrapper(uint32_t restore);
306 static int coex_schm_register_btdm_callback_wrapper(void *callback);
307 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
308 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
309 static uint32_t coex_schm_interval_get_wrapper(void);
310 static uint8_t coex_schm_curr_period_get_wrapper(void);
311 static void * coex_schm_curr_phase_get_wrapper(void);
312 static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary);
313 static int coex_register_wifi_channel_change_callback_wrapper(void *cb);
314 static int coex_version_get_wrapper(unsigned int *major, unsigned int *minor, unsigned int *patch);
315 #if CONFIG_BTDM_CTRL_HLI
316 static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
317 #endif /* CONFIG_BTDM_CTRL_HLI */
318 static void interrupt_l3_disable(void);
319 static void interrupt_l3_restore(void);
320 static void bt_controller_deinit_internal(void);
321 static void patch_apply(void);
322
323 /* Local variable definition
324 ***************************************************************************
325 */
326 /* OSI funcs */
327 static const struct osi_funcs_t osi_funcs_ro = {
328 ._version = OSI_VERSION,
329 #if CONFIG_BTDM_CTRL_HLI
330 ._set_isr = set_isr_hlevel_wrapper,
331 ._ints_on = xt_ints_on,
332 ._interrupt_disable = interrupt_hlevel_disable,
333 ._interrupt_restore = interrupt_hlevel_restore,
334 #else
335 ._set_isr = xt_set_interrupt_handler,
336 ._ints_on = xt_ints_on,
337 ._interrupt_disable = interrupt_l3_disable,
338 ._interrupt_restore = interrupt_l3_restore,
339 #endif /* CONFIG_BTDM_CTRL_HLI */
340 ._task_yield = task_yield,
341 ._task_yield_from_isr = task_yield_from_isr,
342 ._semphr_create = semphr_create_wrapper,
343 ._semphr_delete = semphr_delete_wrapper,
344 ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
345 ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
346 ._semphr_take = semphr_take_wrapper,
347 ._semphr_give = semphr_give_wrapper,
348 ._mutex_create = mutex_create_wrapper,
349 ._mutex_delete = mutex_delete_wrapper,
350 ._mutex_lock = mutex_lock_wrapper,
351 ._mutex_unlock = mutex_unlock_wrapper,
352 #if CONFIG_BTDM_CTRL_HLI
353 ._queue_create = queue_create_hlevel_wrapper,
354 ._queue_delete = queue_delete_hlevel_wrapper,
355 ._queue_send = queue_send_hlevel_wrapper,
356 ._queue_send_from_isr = queue_send_from_isr_hlevel_wrapper,
357 ._queue_recv = queue_recv_hlevel_wrapper,
358 ._queue_recv_from_isr = queue_recv_from_isr_hlevel_wrapper,
359 #else
360 ._queue_create = queue_create_wrapper,
361 ._queue_delete = queue_delete_wrapper,
362 ._queue_send = queue_send_wrapper,
363 ._queue_send_from_isr = queue_send_from_isr_wrapper,
364 ._queue_recv = queue_recv_wrapper,
365 ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
366 #endif /* CONFIG_BTDM_CTRL_HLI */
367 ._task_create = task_create_wrapper,
368 ._task_delete = task_delete_wrapper,
369 ._is_in_isr = is_in_isr_wrapper,
370 ._cause_sw_intr_to_core = cause_sw_intr_to_core_wrapper,
371 ._malloc = malloc,
372 ._malloc_internal = malloc_internal_wrapper,
373 ._free = free,
374 ._read_efuse_mac = read_mac_wrapper,
375 ._srand = srand_wrapper,
376 ._rand = rand_wrapper,
377 ._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
378 ._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
379 ._btdm_sleep_check_duration = btdm_sleep_check_duration,
380 ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
381 ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
382 ._btdm_sleep_exit_phase1 = NULL,
383 ._btdm_sleep_exit_phase2 = NULL,
384 ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
385 ._coex_bt_wakeup_request = coex_bt_wakeup_request,
386 ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end,
387 ._coex_bt_request = coex_bt_request_wrapper,
388 ._coex_bt_release = coex_bt_release_wrapper,
389 ._coex_register_bt_cb = coex_register_bt_cb_wrapper,
390 ._coex_bb_reset_lock = coex_bb_reset_lock_wrapper,
391 ._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper,
392 ._coex_schm_register_btdm_callback = coex_schm_register_btdm_callback_wrapper,
393 ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
394 ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
395 ._coex_schm_interval_get = coex_schm_interval_get_wrapper,
396 ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
397 ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
398 ._coex_wifi_channel_get = coex_wifi_channel_get_wrapper,
399 ._coex_register_wifi_channel_change_callback = coex_register_wifi_channel_change_callback_wrapper,
400 ._set_isr_l3 = xt_set_interrupt_handler,
401 ._interrupt_l3_disable = interrupt_l3_disable,
402 ._interrupt_l3_restore = interrupt_l3_restore,
403 #if CONFIG_BTDM_CTRL_HLI
404 ._customer_queue_create = customer_queue_create_hlevel_wrapper,
405 #else
406 ._customer_queue_create = NULL,
407 #endif /* CONFIG_BTDM_CTRL_HLI */
408 ._coex_version_get = coex_version_get_wrapper,
409 ._patch_apply = patch_apply,
410 ._magic = OSI_MAGIC_VALUE,
411 };
412
413 /* the mode column will be modified by release function to indicate the available region */
414 static btdm_dram_available_region_t btdm_dram_available_region[] = {
415 //following is .data
416 {ESP_BT_MODE_BTDM, SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END },
417 //following is memory which HW will use
418 {ESP_BT_MODE_BTDM, SOC_MEM_BT_EM_BTDM0_START, SOC_MEM_BT_EM_BTDM0_END },
419 {ESP_BT_MODE_BLE, SOC_MEM_BT_EM_BLE_START, SOC_MEM_BT_EM_BLE_END },
420 {ESP_BT_MODE_BTDM, SOC_MEM_BT_EM_BTDM1_START, SOC_MEM_BT_EM_BTDM1_END },
421 {ESP_BT_MODE_CLASSIC_BT, SOC_MEM_BT_EM_BREDR_START, SOC_MEM_BT_EM_BREDR_REAL_END},
422 //following is .bss
423 {ESP_BT_MODE_BTDM, SOC_MEM_BT_BSS_START, SOC_MEM_BT_BSS_END },
424 {ESP_BT_MODE_BTDM, SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END },
425 };
426
427 /* Reserve the full memory region used by Bluetooth Controller,
428 * some may be released later at runtime. */
429 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_EM_START, SOC_MEM_BT_EM_BREDR_REAL_END, rom_bt_em);
430 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_BSS_START, SOC_MEM_BT_BSS_END, rom_bt_bss);
431 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END, rom_bt_misc);
432 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END, rom_bt_data);
433
434 static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
435
436 /* Static variable declare */
437 // timestamp when PHY/RF was switched on
438 static DRAM_ATTR int64_t s_time_phy_rf_just_enabled = 0;
439 static DRAM_ATTR esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
440
441 static DRAM_ATTR portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
442
443 // measured average low power clock period in micro seconds
444 static DRAM_ATTR uint32_t btdm_lpcycle_us = 0;
445 static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit for btdm_lpcycle_us
446
447 #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
448 // used low power clock
449 static DRAM_ATTR uint8_t btdm_lpclk_sel;
450 #endif /* #ifdef CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG */
451
452 static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
453 #ifdef CONFIG_PM_ENABLE
454 static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
455 static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
456 static bool s_pm_lock_acquired = true;
457 static DRAM_ATTR bool s_btdm_allow_light_sleep;
458 // pm_lock to prevent light sleep when using main crystal as Bluetooth low power clock
459 static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
460 static void btdm_slp_tmr_callback(void *arg);
461 #endif /* #ifdef CONFIG_PM_ENABLE */
462
463
esp_bt_power_domain_on(void)464 static inline void esp_bt_power_domain_on(void)
465 {
466 // Bluetooth module power up
467 esp_wifi_bt_power_domain_on();
468 }
469
esp_bt_power_domain_off(void)470 static inline void esp_bt_power_domain_off(void)
471 {
472 // Bluetooth module power down
473 esp_wifi_bt_power_domain_off();
474 }
475
btdm_check_and_init_bb(void)476 static inline void btdm_check_and_init_bb(void)
477 {
478 /* init BT-BB if PHY/RF has been switched off since last BT-BB init */
479 int64_t latest_ts = esp_phy_rf_get_on_ts();
480 if (latest_ts != s_time_phy_rf_just_enabled ||
481 s_time_phy_rf_just_enabled == 0) {
482 btdm_rf_bb_init_phase2();
483 s_time_phy_rf_just_enabled = latest_ts;
484 }
485 }
486
487 #if CONFIG_BTDM_CTRL_HLI
488 struct interrupt_hlevel_cb{
489 uint32_t status;
490 uint8_t nested;
491 };
492
493 static DRAM_ATTR struct interrupt_hlevel_cb hli_cb = {
494 .status = 0,
495 .nested = 0,
496 };
497
set_isr_hlevel_wrapper(int mask,xt_handler f,void * arg)498 static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg)
499 {
500 esp_err_t err = hli_intr_register((intr_handler_t) f, arg, DPORT_PRO_INTR_STATUS_0_REG, mask);
501 if (err == ESP_OK) {
502 return f;
503 } else {
504 return 0;
505 }
506 }
507
interrupt_hlevel_disable(void)508 static void IRAM_ATTR interrupt_hlevel_disable(void)
509 {
510 assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
511 assert(hli_cb.nested != UCHAR_MAX);
512 uint32_t status = hli_intr_disable();
513 if (hli_cb.nested++ == 0) {
514 hli_cb.status = status;
515 }
516 }
517
interrupt_hlevel_restore(void)518 static void IRAM_ATTR interrupt_hlevel_restore(void)
519 {
520 assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
521 assert(hli_cb.nested > 0);
522 if (--hli_cb.nested == 0) {
523 hli_intr_restore(hli_cb.status);
524 }
525 }
526 #endif /* CONFIG_BTDM_CTRL_HLI */
527
interrupt_l3_disable(void)528 static void IRAM_ATTR interrupt_l3_disable(void)
529 {
530 if (xPortInIsrContext()) {
531 portENTER_CRITICAL_ISR(&global_int_mux);
532 } else {
533 portENTER_CRITICAL(&global_int_mux);
534 }
535 }
536
interrupt_l3_restore(void)537 static void IRAM_ATTR interrupt_l3_restore(void)
538 {
539 if (xPortInIsrContext()) {
540 portEXIT_CRITICAL_ISR(&global_int_mux);
541 } else {
542 portEXIT_CRITICAL(&global_int_mux);
543 }
544 }
545
task_yield(void)546 static void IRAM_ATTR task_yield(void)
547 {
548 vPortYield();
549 }
550
551
task_yield_from_isr(void)552 static void IRAM_ATTR task_yield_from_isr(void)
553 {
554 portYIELD_FROM_ISR();
555 }
556
semphr_create_wrapper(uint32_t max,uint32_t init)557 static void *semphr_create_wrapper(uint32_t max, uint32_t init)
558 {
559 btdm_queue_item_t *semphr = heap_caps_calloc(1, sizeof(btdm_queue_item_t), MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
560 assert(semphr);
561
562 void *handle = NULL;
563
564 /* IDF FreeRTOS guarantees that all dynamic memory allocation goes to internal RAM. */
565 handle = (void *)xSemaphoreCreateCounting(max, init);
566 assert(handle);
567
568 #if CONFIG_BTDM_CTRL_HLI
569 SemaphoreHandle_t downstream_semaphore = handle;
570 assert(downstream_semaphore);
571 hli_queue_handle_t s_semaphore = hli_semaphore_create(max, downstream_semaphore);
572 assert(s_semaphore);
573 semphr->handle = (void *)s_semaphore;
574 #else
575 semphr->handle = handle;
576 #endif /* CONFIG_BTDM_CTRL_HLI */
577
578 return semphr;
579 }
580
semphr_delete_wrapper(void * semphr)581 static void semphr_delete_wrapper(void *semphr)
582 {
583 if (semphr == NULL) {
584 return;
585 }
586
587 btdm_queue_item_t *semphr_item = (btdm_queue_item_t *)semphr;
588 void *handle = NULL;
589 #if CONFIG_BTDM_CTRL_HLI
590 if (semphr_item->handle) {
591 handle = ((hli_queue_handle_t)(semphr_item->handle))->downstream;
592 hli_queue_delete((hli_queue_handle_t)(semphr_item->handle));
593 }
594 #else
595 handle = semphr_item->handle;
596 #endif /* CONFIG_BTDM_CTRL_HLI */
597
598 if (handle) {
599 vSemaphoreDelete(handle);
600 }
601
602 free(semphr);
603 }
604
semphr_take_from_isr_wrapper(void * semphr,void * hptw)605 static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
606 {
607 #if CONFIG_BTDM_CTRL_HLI
608 // Not support it
609 assert(0);
610 return 0;
611 #else
612 void *handle = ((btdm_queue_item_t *)semphr)->handle;
613 return (int32_t)xSemaphoreTakeFromISR(handle, hptw);
614 #endif /* CONFIG_BTDM_CTRL_HLI */
615 }
616
semphr_give_from_isr_wrapper(void * semphr,void * hptw)617 static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
618 {
619 void *handle = ((btdm_queue_item_t *)semphr)->handle;
620 #if CONFIG_BTDM_CTRL_HLI
621 UNUSED(hptw);
622 assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
623 return hli_semaphore_give(handle);
624 #else
625 return (int32_t)xSemaphoreGiveFromISR(handle, hptw);
626 #endif /* CONFIG_BTDM_CTRL_HLI */
627 }
628
semphr_take_wrapper(void * semphr,uint32_t block_time_ms)629 static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
630 {
631 bool ret;
632 void *handle = ((btdm_queue_item_t *)semphr)->handle;
633 #if CONFIG_BTDM_CTRL_HLI
634 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
635 ret = xSemaphoreTake(((hli_queue_handle_t)handle)->downstream, portMAX_DELAY);
636 } else {
637 ret = xSemaphoreTake(((hli_queue_handle_t)handle)->downstream, block_time_ms / portTICK_PERIOD_MS);
638 }
639 #else
640 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
641 ret = xSemaphoreTake(handle, portMAX_DELAY);
642 } else {
643 ret = xSemaphoreTake(handle, block_time_ms / portTICK_PERIOD_MS);
644 }
645 #endif /* CONFIG_BTDM_CTRL_HLI */
646 return (int32_t)ret;
647 }
648
semphr_give_wrapper(void * semphr)649 static int32_t semphr_give_wrapper(void *semphr)
650 {
651 void *handle = ((btdm_queue_item_t *)semphr)->handle;
652 #if CONFIG_BTDM_CTRL_HLI
653 return (int32_t)xSemaphoreGive(((hli_queue_handle_t)handle)->downstream);
654 #else
655 return (int32_t)xSemaphoreGive(handle);
656 #endif /* CONFIG_BTDM_CTRL_HLI */
657 }
658
mutex_create_wrapper(void)659 static void *mutex_create_wrapper(void)
660 {
661 return (void *)xSemaphoreCreateMutex();
662 }
663
mutex_delete_wrapper(void * mutex)664 static void mutex_delete_wrapper(void *mutex)
665 {
666 vSemaphoreDelete(mutex);
667 }
668
mutex_lock_wrapper(void * mutex)669 static int32_t mutex_lock_wrapper(void *mutex)
670 {
671 return (int32_t)xSemaphoreTake(mutex, portMAX_DELAY);
672 }
673
mutex_unlock_wrapper(void * mutex)674 static int32_t mutex_unlock_wrapper(void *mutex)
675 {
676 return (int32_t)xSemaphoreGive(mutex);
677 }
678
queue_create_wrapper(uint32_t queue_len,uint32_t item_size)679 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
680 {
681 btdm_queue_item_t *queue = NULL;
682
683 queue = (btdm_queue_item_t*)heap_caps_malloc(sizeof(btdm_queue_item_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
684 assert(queue);
685
686 /* IDF FreeRTOS guarantees that all dynamic memory allocation goes to internal RAM. */
687 queue->handle = xQueueCreate( queue_len, item_size);
688 assert(queue->handle);
689
690 return queue;
691 }
692
queue_delete_wrapper(void * queue)693 static void queue_delete_wrapper(void *queue)
694 {
695 btdm_queue_item_t *queue_item = (btdm_queue_item_t *)queue;
696 if (queue_item) {
697 if(queue_item->handle){
698 vQueueDelete(queue_item->handle);
699 }
700 free(queue_item);
701 }
702 }
703
704 #if CONFIG_BTDM_CTRL_HLI
queue_create_hlevel_wrapper(uint32_t queue_len,uint32_t item_size)705 static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
706 {
707 btdm_queue_item_t *queue_item = queue_create_wrapper(queue_len, item_size);
708 assert(queue_item);
709 QueueHandle_t downstream_queue = queue_item->handle;
710 assert(queue_item->handle);
711 hli_queue_handle_t queue = hli_queue_create(queue_len, item_size, downstream_queue);
712 assert(queue);
713 queue_item->handle = queue;
714 return (void *)queue_item;
715 }
716
customer_queue_create_hlevel_wrapper(uint32_t queue_len,uint32_t item_size)717 static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
718 {
719 btdm_queue_item_t *queue_item = queue_create_wrapper(queue_len, item_size);
720 assert(queue_item);
721 QueueHandle_t downstream_queue = queue_item->handle;
722 assert(queue_item->handle);
723 hli_queue_handle_t queue = hli_customer_queue_create(queue_len, item_size, downstream_queue);
724 assert(queue);
725 queue_item->handle = queue;
726 return (void *)queue_item;
727 }
728
queue_delete_hlevel_wrapper(void * queue)729 static void queue_delete_hlevel_wrapper(void *queue)
730 {
731 if (queue == NULL) {
732 return;
733 }
734
735 btdm_queue_item_t *queue_item = (btdm_queue_item_t *)queue;
736
737 if (queue_item->handle) {
738 void *handle = ((hli_queue_handle_t)(queue_item->handle))->downstream;
739 hli_queue_delete(queue_item->handle);
740 queue_item->handle = handle;
741 queue_delete_wrapper(queue_item);
742 }
743 }
744
queue_send_hlevel_wrapper(void * queue,void * item,uint32_t block_time_ms)745 static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
746 {
747 void *handle = ((btdm_queue_item_t *)queue)->handle;
748 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
749 return (int32_t)xQueueSend(((hli_queue_handle_t)handle)->downstream, item, portMAX_DELAY);
750 } else {
751 return (int32_t)xQueueSend(((hli_queue_handle_t)handle)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
752 }
753 }
754
755 /**
756 * Queue send from isr
757 * @param queue The queue which will send to
758 * @param item The message which will be send
759 * @param hptw need do task yield or not
760 * @return send success or not
761 * There is an issue here: When the queue is full, it may return true but it send fail to the queue, sometimes.
762 * But in Bluetooth controller's isr, We don't care about the return value.
763 * It only required tp send success when the queue is empty all the time.
764 * So, this function meets the requirement.
765 */
queue_send_from_isr_hlevel_wrapper(void * queue,void * item,void * hptw)766 static int32_t IRAM_ATTR queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
767 {
768 UNUSED(hptw);
769 assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
770 void *handle = ((btdm_queue_item_t *)queue)->handle;
771 return hli_queue_put(handle, item);
772 }
773
queue_recv_hlevel_wrapper(void * queue,void * item,uint32_t block_time_ms)774 static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
775 {
776 bool ret;
777 void *handle = ((btdm_queue_item_t *)queue)->handle;
778 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
779 ret = xQueueReceive(((hli_queue_handle_t)handle)->downstream, item, portMAX_DELAY);
780 } else {
781 ret = xQueueReceive(((hli_queue_handle_t)handle)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
782 }
783
784 return (int32_t)ret;
785 }
786
queue_recv_from_isr_hlevel_wrapper(void * queue,void * item,void * hptw)787 static int32_t IRAM_ATTR queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
788 {
789 // Not support it
790 assert(0);
791 return 0;
792 }
793
794 #else
795
queue_send_wrapper(void * queue,void * item,uint32_t block_time_ms)796 static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms)
797 {
798 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
799 return (int32_t)xQueueSend(((btdm_queue_item_t*)queue)->handle, item, portMAX_DELAY);
800 } else {
801 return (int32_t)xQueueSend(((btdm_queue_item_t*)queue)->handle, item, block_time_ms / portTICK_PERIOD_MS);
802 }
803 }
804
queue_send_from_isr_wrapper(void * queue,void * item,void * hptw)805 static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw)
806 {
807 return (int32_t)xQueueSendFromISR(((btdm_queue_item_t*)queue)->handle, item, hptw);
808 }
809
queue_recv_wrapper(void * queue,void * item,uint32_t block_time_ms)810 static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms)
811 {
812 bool ret;
813 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
814 ret = xQueueReceive(((btdm_queue_item_t*)queue)->handle, item, portMAX_DELAY);
815 } else {
816 ret = xQueueReceive(((btdm_queue_item_t*)queue)->handle, item, block_time_ms / portTICK_PERIOD_MS);
817 }
818
819 return (int32_t)ret;
820 }
821
queue_recv_from_isr_wrapper(void * queue,void * item,void * hptw)822 static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw)
823 {
824 return (int32_t)xQueueReceiveFromISR(((btdm_queue_item_t*)queue)->handle, item, hptw);
825 }
826 #endif /* CONFIG_BTDM_CTRL_HLI */
827
828
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)829 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)
830 {
831 return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY));
832 }
833
task_delete_wrapper(void * task_handle)834 static void task_delete_wrapper(void *task_handle)
835 {
836 vTaskDelete(task_handle);
837 }
838
is_in_isr_wrapper(void)839 static bool IRAM_ATTR is_in_isr_wrapper(void)
840 {
841 return !xPortCanYield();
842 }
843
cause_sw_intr(void * arg)844 static void IRAM_ATTR cause_sw_intr(void *arg)
845 {
846 /* just convert void * to int, because the width is the same */
847 uint32_t intr_no = (uint32_t)arg;
848 XTHAL_SET_INTSET((1<<intr_no));
849 }
850
cause_sw_intr_to_core_wrapper(int core_id,int intr_no)851 static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no)
852 {
853 esp_err_t err = ESP_OK;
854
855 #if CONFIG_FREERTOS_UNICORE
856 cause_sw_intr((void *)intr_no);
857 #else /* CONFIG_FREERTOS_UNICORE */
858 if (xPortGetCoreID() == core_id) {
859 cause_sw_intr((void *)intr_no);
860 } else {
861 err = esp_ipc_call(core_id, cause_sw_intr, (void *)intr_no);
862 }
863 #endif /* !CONFIG_FREERTOS_UNICORE */
864 return err;
865 }
866
malloc_internal_wrapper(size_t size)867 static void *malloc_internal_wrapper(size_t size)
868 {
869 return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS);
870 }
871
malloc_ble_controller_mem(size_t size)872 void *malloc_ble_controller_mem(size_t size)
873 {
874 void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS);
875 if(p == NULL) {
876 ESP_LOGE(BTDM_LOG_TAG, "Malloc failed");
877 }
878 return p;
879 }
880
get_ble_controller_free_heap_size(void)881 uint32_t get_ble_controller_free_heap_size(void)
882 {
883 return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS);
884 }
885
read_mac_wrapper(uint8_t mac[6])886 static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
887 {
888 int ret = esp_read_mac(mac, ESP_MAC_BT);
889 ESP_LOGI(BTDM_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x",
890 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
891
892 return ret;
893 }
894
srand_wrapper(unsigned int seed)895 static void IRAM_ATTR srand_wrapper(unsigned int seed)
896 {
897 /* empty function */
898 }
899
rand_wrapper(void)900 static int IRAM_ATTR rand_wrapper(void)
901 {
902 return (int)esp_random();
903 }
904
btdm_lpcycles_2_us(uint32_t cycles)905 static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
906 {
907 // The number of lp cycles should not lead to overflow. Thrs: 100s
908 // clock measurement is conducted
909 uint64_t us = (uint64_t)btdm_lpcycle_us * cycles;
910 us = (us + (1 << (btdm_lpcycle_us_frac - 1))) >> btdm_lpcycle_us_frac;
911 return (uint32_t)us;
912 }
913
914 /*
915 * @brief Converts a duration in slots into a number of low power clock cycles.
916 */
btdm_us_2_lpcycles(uint32_t us)917 static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us)
918 {
919 // The number of sleep duration(us) should not lead to overflow. Thrs: 100s
920 // Compute the sleep duration in us to low power clock cycles, with calibration result applied
921 // clock measurement is conducted
922 uint64_t cycles = ((uint64_t)(us) << btdm_lpcycle_us_frac) / btdm_lpcycle_us;
923
924 return (uint32_t)cycles;
925 }
926
btdm_sleep_check_duration(uint32_t * slot_cnt)927 static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt)
928 {
929 if (*slot_cnt < BTDM_MIN_SLEEP_DURATION) {
930 return false;
931 }
932 /* wake up in advance considering the delay in enabling PHY/RF */
933 *slot_cnt -= BTDM_MODEM_WAKE_UP_DELAY;
934 return true;
935 }
936
btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)937 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
938 {
939 #ifdef CONFIG_PM_ENABLE
940 // start a timer to wake up and acquire the pm_lock before modem_sleep awakes
941 uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles);
942
943 #define BTDM_MIN_TIMER_UNCERTAINTY_US (500)
944 assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
945 // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
946 // and set the timer in advance
947 uint32_t uncertainty = (us_to_sleep >> 11);
948 if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) {
949 uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
950 }
951
952 if (esp_timer_start_once(s_btdm_slp_tmr, us_to_sleep - uncertainty) != ESP_OK) {
953 ESP_LOGW(BTDM_LOG_TAG, "timer start failed");
954 }
955 #endif
956 }
957
btdm_sleep_enter_phase2_wrapper(void)958 static void btdm_sleep_enter_phase2_wrapper(void)
959 {
960 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
961 esp_phy_disable(PHY_MODEM_BT);
962 #ifdef CONFIG_PM_ENABLE
963 if (s_pm_lock_acquired) {
964 esp_pm_lock_release(s_pm_lock);
965 s_pm_lock_acquired = false;
966 }
967 #endif
968 } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
969 esp_phy_disable(PHY_MODEM_BT);
970 // pause bluetooth baseband
971 periph_module_disable(PERIPH_BT_BASEBAND_MODULE);
972 }
973 }
974
btdm_sleep_exit_phase3_wrapper(void)975 static void btdm_sleep_exit_phase3_wrapper(void)
976 {
977 #ifdef CONFIG_PM_ENABLE
978 if (!s_pm_lock_acquired) {
979 s_pm_lock_acquired = true;
980 esp_pm_lock_acquire(s_pm_lock);
981 }
982 #endif
983
984 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
985 esp_phy_enable(PHY_MODEM_BT);
986 btdm_check_and_init_bb();
987 #ifdef CONFIG_PM_ENABLE
988 esp_timer_stop(s_btdm_slp_tmr);
989 #endif
990 } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
991 // resume bluetooth baseband
992 periph_module_enable(PERIPH_BT_BASEBAND_MODULE);
993 esp_phy_enable(PHY_MODEM_BT);
994 }
995 }
996
997 #ifdef CONFIG_PM_ENABLE
btdm_slp_tmr_customer_callback(void * arg)998 static void btdm_slp_tmr_customer_callback(void * arg)
999 {
1000 (void)(arg);
1001
1002 if (!s_pm_lock_acquired) {
1003 s_pm_lock_acquired = true;
1004 esp_pm_lock_acquire(s_pm_lock);
1005 }
1006 }
1007
btdm_slp_tmr_callback(void * arg)1008 static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
1009 {
1010 (void)(arg);
1011 btdm_dispatch_work_to_controller(btdm_slp_tmr_customer_callback, NULL, true);
1012 }
1013 #endif
1014
1015 #define BTDM_ASYNC_WAKEUP_REQ_HCI 0
1016 #define BTDM_ASYNC_WAKEUP_REQ_COEX 1
1017 #define BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA 2
1018 #define BTDM_ASYNC_WAKEUP_REQMAX 3
1019
btdm_wakeup_request_callback(void * arg)1020 static void btdm_wakeup_request_callback(void * arg)
1021 {
1022 (void)(arg);
1023
1024 #if CONFIG_PM_ENABLE
1025 if (!s_pm_lock_acquired) {
1026 s_pm_lock_acquired = true;
1027 esp_pm_lock_acquire(s_pm_lock);
1028 }
1029 esp_timer_stop(s_btdm_slp_tmr);
1030 #endif
1031 btdm_wakeup_request();
1032
1033 semphr_give_wrapper(s_wakeup_req_sem);
1034 }
1035
async_wakeup_request(int event)1036 static bool async_wakeup_request(int event)
1037 {
1038 bool do_wakeup_request = false;
1039
1040 switch (event) {
1041 case BTDM_ASYNC_WAKEUP_REQ_HCI:
1042 btdm_in_wakeup_requesting_set(true);
1043 // NO break
1044 case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
1045 if (!btdm_power_state_active()) {
1046 do_wakeup_request = true;
1047
1048 btdm_dispatch_work_to_controller(btdm_wakeup_request_callback, NULL, true);
1049 semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING);
1050 }
1051 break;
1052 case BTDM_ASYNC_WAKEUP_REQ_COEX:
1053 if (!btdm_power_state_active()) {
1054 do_wakeup_request = true;
1055 #if CONFIG_PM_ENABLE
1056 if (!s_pm_lock_acquired) {
1057 s_pm_lock_acquired = true;
1058 esp_pm_lock_acquire(s_pm_lock);
1059 }
1060 esp_timer_stop(s_btdm_slp_tmr);
1061 #endif
1062 btdm_wakeup_request();
1063 }
1064 break;
1065 default:
1066 return false;
1067 }
1068
1069 return do_wakeup_request;
1070 }
1071
async_wakeup_request_end(int event)1072 static void async_wakeup_request_end(int event)
1073 {
1074 bool request_lock = false;
1075 switch (event) {
1076 case BTDM_ASYNC_WAKEUP_REQ_HCI:
1077 request_lock = true;
1078 break;
1079 case BTDM_ASYNC_WAKEUP_REQ_COEX:
1080 case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
1081 request_lock = false;
1082 break;
1083 default:
1084 return;
1085 }
1086
1087 if (request_lock) {
1088 btdm_in_wakeup_requesting_set(false);
1089 }
1090
1091 return;
1092 }
1093
coex_bt_wakeup_request(void)1094 static bool coex_bt_wakeup_request(void)
1095 {
1096 return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
1097 }
1098
coex_bt_wakeup_request_end(void)1099 static void coex_bt_wakeup_request_end(void)
1100 {
1101 async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX);
1102 return;
1103 }
1104
coex_bt_request_wrapper(uint32_t event,uint32_t latency,uint32_t duration)1105 static int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration)
1106 {
1107 #if CONFIG_SW_COEXIST_ENABLE
1108 return coex_bt_request(event, latency, duration);
1109 #else
1110 return 0;
1111 #endif
1112 }
1113
coex_bt_release_wrapper(uint32_t event)1114 static int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
1115 {
1116 #if CONFIG_SW_COEXIST_ENABLE
1117 return coex_bt_release(event);
1118 #else
1119 return 0;
1120 #endif
1121 }
1122
coex_register_bt_cb_wrapper(coex_func_cb_t cb)1123 static int coex_register_bt_cb_wrapper(coex_func_cb_t cb)
1124 {
1125 #if CONFIG_SW_COEXIST_ENABLE
1126 return coex_register_bt_cb(cb);
1127 #else
1128 return 0;
1129 #endif
1130 }
1131
coex_bb_reset_lock_wrapper(void)1132 static uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
1133 {
1134 #if CONFIG_SW_COEXIST_ENABLE
1135 return coex_bb_reset_lock();
1136 #else
1137 return 0;
1138 #endif
1139 }
1140
coex_bb_reset_unlock_wrapper(uint32_t restore)1141 static void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
1142 {
1143 #if CONFIG_SW_COEXIST_ENABLE
1144 coex_bb_reset_unlock(restore);
1145 #endif
1146 }
1147
coex_schm_register_btdm_callback_wrapper(void * callback)1148 static int coex_schm_register_btdm_callback_wrapper(void *callback)
1149 {
1150 #if CONFIG_SW_COEXIST_ENABLE
1151 return coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, callback);
1152 #else
1153 return 0;
1154 #endif
1155 }
1156
coex_schm_status_bit_clear_wrapper(uint32_t type,uint32_t status)1157 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
1158 {
1159 #if CONFIG_SW_COEXIST_ENABLE
1160 coex_schm_status_bit_clear(type, status);
1161 #endif
1162 }
1163
coex_schm_status_bit_set_wrapper(uint32_t type,uint32_t status)1164 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
1165 {
1166 #if CONFIG_SW_COEXIST_ENABLE
1167 coex_schm_status_bit_set(type, status);
1168 #endif
1169 }
1170
coex_schm_interval_get_wrapper(void)1171 static uint32_t coex_schm_interval_get_wrapper(void)
1172 {
1173 #if CONFIG_SW_COEXIST_ENABLE
1174 return coex_schm_interval_get();
1175 #else
1176 return 0;
1177 #endif
1178 }
1179
coex_schm_curr_period_get_wrapper(void)1180 static uint8_t coex_schm_curr_period_get_wrapper(void)
1181 {
1182 #if CONFIG_SW_COEXIST_ENABLE
1183 return coex_schm_curr_period_get();
1184 #else
1185 return 1;
1186 #endif
1187 }
1188
coex_schm_curr_phase_get_wrapper(void)1189 static void * coex_schm_curr_phase_get_wrapper(void)
1190 {
1191 #if CONFIG_SW_COEXIST_ENABLE
1192 return coex_schm_curr_phase_get();
1193 #else
1194 return NULL;
1195 #endif
1196 }
1197
coex_wifi_channel_get_wrapper(uint8_t * primary,uint8_t * secondary)1198 static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary)
1199 {
1200 #if CONFIG_SW_COEXIST_ENABLE
1201 return coex_wifi_channel_get(primary, secondary);
1202 #else
1203 return -1;
1204 #endif
1205 }
1206
coex_register_wifi_channel_change_callback_wrapper(void * cb)1207 static int coex_register_wifi_channel_change_callback_wrapper(void *cb)
1208 {
1209 #if CONFIG_SW_COEXIST_ENABLE
1210 return coex_register_wifi_channel_change_callback(cb);
1211 #else
1212 return -1;
1213 #endif
1214 }
1215
coex_version_get_wrapper(unsigned int * major,unsigned int * minor,unsigned int * patch)1216 static int coex_version_get_wrapper(unsigned int *major, unsigned int *minor, unsigned int *patch)
1217 {
1218 #if CONFIG_SW_COEXIST_ENABLE
1219 coex_version_t version;
1220 ESP_ERROR_CHECK(coex_version_get_value(&version));
1221 *major = (unsigned int)version.major;
1222 *minor = (unsigned int)version.minor;
1223 *patch = (unsigned int)version.patch;
1224 return 0;
1225 #endif
1226 return -1;
1227 }
1228
esp_vhci_host_check_send_available(void)1229 bool esp_vhci_host_check_send_available(void)
1230 {
1231 return API_vhci_host_check_send_available();
1232 }
1233
esp_vhci_host_send_packet(uint8_t * data,uint16_t len)1234 void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
1235 {
1236 async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_HCI);
1237
1238 API_vhci_host_send_packet(data, len);
1239
1240 async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_HCI);
1241 }
1242
esp_vhci_host_register_callback(const esp_vhci_host_callback_t * callback)1243 esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
1244 {
1245 return API_vhci_host_register_callback((const vhci_host_callback_t *)callback) == 0 ? ESP_OK : ESP_FAIL;
1246 }
1247
btdm_config_mask_load(void)1248 static uint32_t btdm_config_mask_load(void)
1249 {
1250 uint32_t mask = 0x0;
1251
1252 #if CONFIG_BTDM_CTRL_HCI_MODE_UART_H4
1253 mask |= BTDM_CFG_HCI_UART;
1254 #endif
1255 #if CONFIG_BTDM_CTRL_PINNED_TO_CORE == 1
1256 mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU;
1257 #endif
1258 #if CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED
1259 mask |= BTDM_CFG_BLE_FULL_SCAN_SUPPORTED;
1260 #endif /* CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED */
1261 mask |= BTDM_CFG_SCAN_DUPLICATE_OPTIONS;
1262
1263 mask |= BTDM_CFG_SEND_ADV_RESERVED_SIZE;
1264
1265 return mask;
1266 }
1267
btdm_controller_mem_init(void)1268 static void btdm_controller_mem_init(void)
1269 {
1270 /* initialise .data section */
1271 memcpy(&_data_start_btdm, (void *)_data_start_btdm_rom, &_data_end_btdm - &_data_start_btdm);
1272 ESP_LOGD(BTDM_LOG_TAG, ".data initialise [0x%08x] <== [0x%08x]", (uint32_t)&_data_start_btdm, _data_start_btdm_rom);
1273
1274 //initial em, .bss section
1275 for (int i = 1; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) {
1276 if (btdm_dram_available_region[i].mode != ESP_BT_MODE_IDLE) {
1277 memset((void *)btdm_dram_available_region[i].start, 0x0, btdm_dram_available_region[i].end - btdm_dram_available_region[i].start);
1278 ESP_LOGD(BTDM_LOG_TAG, ".bss initialise [0x%08x] - [0x%08x]", btdm_dram_available_region[i].start, btdm_dram_available_region[i].end);
1279 }
1280 }
1281 }
1282
try_heap_caps_add_region(intptr_t start,intptr_t end)1283 static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
1284 {
1285 int ret = heap_caps_add_region(start, end);
1286 /* heap_caps_add_region() returns ESP_ERR_INVALID_SIZE if the memory region is
1287 * is too small to fit a heap. This cannot be termed as a fatal error and hence
1288 * we replace it by ESP_OK
1289 */
1290 if (ret == ESP_ERR_INVALID_SIZE) {
1291 return ESP_OK;
1292 }
1293 return ret;
1294 }
1295
1296 typedef struct {
1297 intptr_t start;
1298 intptr_t end;
1299 const char* name;
1300 } bt_area_t;
1301
1302
esp_bt_mem_release_area(const bt_area_t * area)1303 static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
1304 {
1305 esp_err_t ret = ESP_OK;
1306 intptr_t mem_start = area->start;
1307 intptr_t mem_end = area->end;
1308 if (mem_start != mem_end) {
1309 ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
1310 ret = try_heap_caps_add_region(mem_start, mem_end);
1311 }
1312 return ret;
1313 }
1314
esp_bt_mem_release_areas(const bt_area_t * area1,const bt_area_t * area2)1315 static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
1316 {
1317 esp_err_t ret = ESP_OK;
1318
1319 if (area1->end == area2->start) {
1320 bt_area_t merged_area = {
1321 .start = area1->start,
1322 .end = area2->end,
1323 .name = area1->name
1324 };
1325 ret = esp_bt_mem_release_area(&merged_area);
1326 } else {
1327 esp_bt_mem_release_area(area1);
1328 ret = esp_bt_mem_release_area(area2);
1329 }
1330
1331 return ret;
1332 }
1333
esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)1334 static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
1335 {
1336 bool update = true;
1337 intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
1338
1339 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1340 return ESP_ERR_INVALID_STATE;
1341 }
1342
1343 //already released
1344 if (!(mode & btdm_dram_available_region[0].mode)) {
1345 ESP_LOGW(BTDM_LOG_TAG, "%s already released, mode %d",__func__, mode);
1346 return ESP_OK;
1347 }
1348
1349 for (int i = 0; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) {
1350 //skip the share mode, idle mode and other mode
1351 if (btdm_dram_available_region[i].mode == ESP_BT_MODE_IDLE
1352 || (mode & btdm_dram_available_region[i].mode) != btdm_dram_available_region[i].mode) {
1353 //clear the bit of the mode which will be released
1354 btdm_dram_available_region[i].mode &= ~mode;
1355 continue;
1356 } else {
1357 //clear the bit of the mode which will be released
1358 btdm_dram_available_region[i].mode &= ~mode;
1359 }
1360
1361 if (update) {
1362 mem_start = btdm_dram_available_region[i].start;
1363 mem_end = btdm_dram_available_region[i].end;
1364 update = false;
1365 }
1366
1367 if (i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t) - 1) {
1368 mem_end = btdm_dram_available_region[i].end;
1369 if (btdm_dram_available_region[i+1].mode != ESP_BT_MODE_IDLE
1370 && (mode & btdm_dram_available_region[i+1].mode) == btdm_dram_available_region[i+1].mode
1371 && mem_end == btdm_dram_available_region[i+1].start) {
1372 continue;
1373 } else {
1374 ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]", mem_start, mem_end);
1375 ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
1376 update = true;
1377 }
1378 } else {
1379 mem_end = btdm_dram_available_region[i].end;
1380 ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]", mem_start, mem_end);
1381 ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
1382 update = true;
1383 }
1384 }
1385
1386 return ESP_OK;
1387 }
1388
esp_bt_controller_mem_release(esp_bt_mode_t mode)1389 esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
1390 {
1391 esp_err_t ret = ESP_OK;
1392
1393 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1394 return ESP_ERR_INVALID_STATE;
1395 }
1396
1397 if (mode == ESP_BT_MODE_BTDM) {
1398 bt_area_t cont_bss = {
1399 .start = (intptr_t)&_bt_controller_bss_start,
1400 .end = (intptr_t)&_bt_controller_bss_end,
1401 .name = "BT Controller BSS",
1402 };
1403 bt_area_t cont_data = {
1404 .start = (intptr_t)&_bt_controller_data_start,
1405 .end = (intptr_t)&_bt_controller_data_end,
1406 .name = "BT Controller Data"
1407 };
1408
1409 ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
1410 }
1411
1412 if (ret == ESP_OK) {
1413 ret = esp_bt_controller_rom_mem_release(mode);
1414 }
1415
1416 return ret;
1417 }
1418
esp_bt_mem_release(esp_bt_mode_t mode)1419 esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
1420 {
1421 esp_err_t ret = ESP_OK;
1422
1423 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1424 return ESP_ERR_INVALID_STATE;
1425 }
1426
1427 bt_area_t bss = {
1428 .start = (intptr_t)&_bt_bss_start,
1429 .end = (intptr_t)&_bt_bss_end,
1430 .name = "BT BSS",
1431 };
1432 bt_area_t cont_bss = {
1433 .start = (intptr_t)&_bt_controller_bss_start,
1434 .end = (intptr_t)&_bt_controller_bss_end,
1435 .name = "BT Controller BSS",
1436 };
1437 bt_area_t data = {
1438 .start = (intptr_t)&_bt_data_start,
1439 .end = (intptr_t)&_bt_data_end,
1440 .name = "BT Data",
1441 };
1442 bt_area_t cont_data = {
1443 .start = (intptr_t)&_bt_controller_data_start,
1444 .end = (intptr_t)&_bt_controller_data_end,
1445 .name = "BT Controller Data"
1446 };
1447
1448 /*
1449 * Free data and BSS section for Bluetooth controller ROM code.
1450 * Note that rom mem release must be performed before section _bt_data_start to _bt_data_end is released,
1451 * otherwise `btdm_dram_available_region` will no longer be available when performing rom mem release and
1452 * thus causing heap corruption.
1453 */
1454 ret = esp_bt_controller_rom_mem_release(mode);
1455
1456 if (mode == ESP_BT_MODE_BTDM) {
1457 /* Start by freeing Bluetooth BSS section */
1458 if (ret == ESP_OK) {
1459 ret = esp_bt_mem_release_areas(&bss, &cont_bss);
1460 }
1461
1462 /* Do the same thing with the Bluetooth data section */
1463 if (ret == ESP_OK) {
1464 ret = esp_bt_mem_release_areas(&data, &cont_data);
1465 }
1466 }
1467
1468 return ret;
1469 }
1470
1471 #if CONFIG_BTDM_CTRL_HLI
hli_queue_setup_cb(void * arg)1472 static void hli_queue_setup_cb(void* arg)
1473 {
1474 hli_queue_setup();
1475 }
1476
hli_queue_setup_pinned_to_core(int core_id)1477 static void hli_queue_setup_pinned_to_core(int core_id)
1478 {
1479 #if CONFIG_FREERTOS_UNICORE
1480 hli_queue_setup_cb(NULL);
1481 #else /* CONFIG_FREERTOS_UNICORE */
1482 if (xPortGetCoreID() == core_id) {
1483 hli_queue_setup_cb(NULL);
1484 } else {
1485 esp_ipc_call(core_id, hli_queue_setup_cb, NULL);
1486 }
1487 #endif /* !CONFIG_FREERTOS_UNICORE */
1488 }
1489 #endif /* CONFIG_BTDM_CTRL_HLI */
1490
esp_bt_controller_init(esp_bt_controller_config_t * cfg)1491 esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
1492 {
1493 esp_err_t err;
1494 uint32_t btdm_cfg_mask = 0;
1495
1496 #if CONFIG_BTDM_CTRL_HLI
1497 hli_queue_setup_pinned_to_core(CONFIG_BTDM_CTRL_PINNED_TO_CORE);
1498 #endif /* CONFIG_BTDM_CTRL_HLI */
1499
1500 //if all the bt available memory was already released, cannot initialize bluetooth controller
1501 if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
1502 return ESP_ERR_INVALID_STATE;
1503 }
1504
1505 osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
1506 if (osi_funcs_p == NULL) {
1507 return ESP_ERR_NO_MEM;
1508 }
1509
1510 memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t));
1511 if (btdm_osi_funcs_register(osi_funcs_p) != 0) {
1512 return ESP_ERR_INVALID_ARG;
1513 }
1514
1515 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1516 return ESP_ERR_INVALID_STATE;
1517 }
1518
1519 if (cfg == NULL) {
1520 return ESP_ERR_INVALID_ARG;
1521 }
1522
1523 if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO
1524 || cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) {
1525 return ESP_ERR_INVALID_ARG;
1526 }
1527
1528 //overwrite some parameters
1529 cfg->bt_max_sync_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF;
1530 cfg->magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL;
1531
1532 if (((cfg->mode & ESP_BT_MODE_BLE) && (cfg->ble_max_conn <= 0 || cfg->ble_max_conn > BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT))
1533 || ((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))
1534 || ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_sync_conn > BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT))) {
1535 return ESP_ERR_INVALID_ARG;
1536 }
1537
1538 ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
1539
1540 s_wakeup_req_sem = semphr_create_wrapper(1, 0);
1541 if (s_wakeup_req_sem == NULL) {
1542 err = ESP_ERR_NO_MEM;
1543 goto error;
1544 }
1545
1546 esp_phy_modem_init();
1547
1548 esp_bt_power_domain_on();
1549
1550 btdm_controller_mem_init();
1551
1552 periph_module_enable(PERIPH_BT_MODULE);
1553 periph_module_reset(PERIPH_BT_MODULE);
1554
1555 #ifdef CONFIG_PM_ENABLE
1556 s_btdm_allow_light_sleep = false;
1557 #endif
1558
1559 // set default sleep clock cycle and its fractional bits
1560 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1561 btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1562
1563 #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1564
1565 btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1566 #if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
1567 // check whether or not EXT_CRYS is working
1568 if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
1569 btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32kHz XTAL
1570 #ifdef CONFIG_PM_ENABLE
1571 s_btdm_allow_light_sleep = true;
1572 #endif
1573 } else {
1574 ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
1575 "light sleep mode will not be able to apply when bluetooth is enabled");
1576 btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1577 }
1578 #else
1579 btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1580 #endif
1581
1582 bool select_src_ret __attribute__((unused));
1583 bool set_div_ret __attribute__((unused));
1584 if (btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
1585 select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
1586 set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() * 2 / MHZ - 1);
1587 assert(select_src_ret && set_div_ret);
1588 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1589 btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1590 } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K
1591 select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
1592 set_div_ret = btdm_lpclk_set_div(0);
1593 assert(select_src_ret && set_div_ret);
1594 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1595 btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
1596 (1000000 >> (15 - RTC_CLK_CAL_FRACT));
1597 assert(btdm_lpcycle_us != 0);
1598 }
1599 btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG);
1600
1601 #elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED
1602 btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_EVED);
1603 #else
1604 btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
1605 #endif
1606
1607 #if CONFIG_BTDM_CTRL_HCI_UART_FLOW_CTRL_EN
1608 sdk_config_set_uart_flow_ctrl_enable(true);
1609 #else
1610 sdk_config_set_uart_flow_ctrl_enable(false);
1611 #endif
1612
1613 #ifdef CONFIG_PM_ENABLE
1614 if (!s_btdm_allow_light_sleep) {
1615 if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
1616 goto error;
1617 }
1618 }
1619 if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
1620 goto error;
1621 }
1622 esp_timer_create_args_t create_args = {
1623 .callback = btdm_slp_tmr_callback,
1624 .arg = NULL,
1625 .name = "btSlp"
1626 };
1627 if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
1628 goto error;
1629 }
1630
1631 s_pm_lock_acquired = true;
1632 #endif
1633
1634 #if CONFIG_SW_COEXIST_ENABLE
1635 coex_init();
1636 #endif
1637
1638 btdm_cfg_mask = btdm_config_mask_load();
1639
1640 err = btdm_controller_init(btdm_cfg_mask, cfg);
1641
1642 if (err != 0) {
1643 ESP_LOGE(BTDM_LOG_TAG, "%s %d\n",__func__,err);
1644 err = ESP_ERR_NO_MEM;
1645 goto error;
1646 }
1647
1648 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1649
1650 return ESP_OK;
1651
1652 error:
1653
1654 bt_controller_deinit_internal();
1655
1656 return err;
1657 }
1658
esp_bt_controller_deinit(void)1659 esp_err_t esp_bt_controller_deinit(void)
1660 {
1661 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1662 return ESP_ERR_INVALID_STATE;
1663 }
1664
1665 btdm_controller_deinit();
1666
1667 bt_controller_deinit_internal();
1668
1669 return ESP_OK;
1670 }
1671
bt_controller_deinit_internal(void)1672 static void bt_controller_deinit_internal(void)
1673 {
1674 periph_module_disable(PERIPH_BT_MODULE);
1675
1676 #ifdef CONFIG_PM_ENABLE
1677 if (!s_btdm_allow_light_sleep) {
1678 esp_pm_lock_delete(s_light_sleep_pm_lock);
1679 s_light_sleep_pm_lock = NULL;
1680 }
1681
1682 if (s_pm_lock != NULL) {
1683 esp_pm_lock_delete(s_pm_lock);
1684 s_pm_lock = NULL;
1685 }
1686
1687 if (s_btdm_slp_tmr != NULL) {
1688 esp_timer_stop(s_btdm_slp_tmr);
1689 esp_timer_delete(s_btdm_slp_tmr);
1690 s_btdm_slp_tmr = NULL;
1691 }
1692
1693 s_pm_lock_acquired = false;
1694 #endif
1695
1696 if (s_wakeup_req_sem) {
1697 semphr_delete_wrapper(s_wakeup_req_sem);
1698 s_wakeup_req_sem = NULL;
1699 }
1700
1701 if (osi_funcs_p) {
1702 free(osi_funcs_p);
1703 osi_funcs_p = NULL;
1704 }
1705
1706 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
1707
1708 btdm_lpcycle_us = 0;
1709 btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
1710
1711 esp_bt_power_domain_off();
1712
1713 esp_phy_modem_deinit();
1714 }
1715
bt_controller_shutdown(void * arg)1716 static void bt_controller_shutdown(void* arg)
1717 {
1718 esp_bt_controller_shutdown();
1719 }
1720
bt_shutdown(void)1721 static void bt_shutdown(void)
1722 {
1723 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1724 return;
1725 }
1726 #if !CONFIG_FREERTOS_UNICORE
1727 esp_ipc_call_blocking(CONFIG_BTDM_CTRL_PINNED_TO_CORE, bt_controller_shutdown, NULL);
1728 #else
1729 bt_controller_shutdown(NULL);
1730 #endif
1731 esp_phy_disable(PHY_MODEM_BT);
1732
1733 return;
1734 }
1735
patch_apply(void)1736 static void patch_apply(void)
1737 {
1738 config_btdm_funcs_reset();
1739
1740 #ifndef CONFIG_BTDM_CTRL_MODE_BLE_ONLY
1741 config_bt_funcs_reset();
1742 #endif
1743
1744 #ifndef CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
1745 config_ble_funcs_reset();
1746 #endif
1747
1748 #ifdef CONFIG_BTDM_BLE_VS_QA_SUPPORT
1749 config_ble_vs_qa_funcs_reset();
1750 #endif
1751 }
1752
esp_bt_controller_enable(esp_bt_mode_t mode)1753 esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
1754 {
1755 int ret;
1756
1757 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1758 return ESP_ERR_INVALID_STATE;
1759 }
1760
1761 //As the history reason, mode should be equal to the mode which set in esp_bt_controller_init()
1762 if (mode != btdm_controller_get_mode()) {
1763 return ESP_ERR_INVALID_ARG;
1764 }
1765
1766 #ifdef CONFIG_PM_ENABLE
1767 if (!s_btdm_allow_light_sleep) {
1768 esp_pm_lock_acquire(s_light_sleep_pm_lock);
1769 }
1770 esp_pm_lock_acquire(s_pm_lock);
1771 #endif
1772
1773 esp_phy_enable(PHY_MODEM_BT);
1774
1775 #if CONFIG_SW_COEXIST_ENABLE
1776 coex_enable();
1777 #endif
1778
1779 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
1780 btdm_controller_enable_sleep(true);
1781 }
1782
1783 sdk_config_set_bt_pll_track_enable(true);
1784
1785 // initialize bluetooth baseband
1786 btdm_check_and_init_bb();
1787
1788 ret = btdm_controller_enable(mode);
1789 if (ret != 0) {
1790 #if CONFIG_SW_COEXIST_ENABLE
1791 coex_disable();
1792 #endif
1793 esp_phy_disable(PHY_MODEM_BT);
1794 #ifdef CONFIG_PM_ENABLE
1795 if (!s_btdm_allow_light_sleep) {
1796 esp_pm_lock_release(s_light_sleep_pm_lock);
1797 }
1798 esp_pm_lock_release(s_pm_lock);
1799 #endif
1800 return ESP_ERR_INVALID_STATE;
1801 }
1802
1803 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
1804 ret = esp_register_shutdown_handler(bt_shutdown);
1805 if (ret != ESP_OK) {
1806 ESP_LOGW(BTDM_LOG_TAG, "Register shutdown handler failed, ret = 0x%x", ret);
1807 }
1808
1809 return ESP_OK;
1810 }
1811
esp_bt_controller_disable(void)1812 esp_err_t esp_bt_controller_disable(void)
1813 {
1814 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1815 return ESP_ERR_INVALID_STATE;
1816 }
1817
1818 // disable modem sleep and wake up from sleep mode
1819 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
1820 btdm_controller_enable_sleep(false);
1821 async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA);
1822 while (!btdm_power_state_active()) {
1823 esp_rom_delay_us(1000);
1824 }
1825 }
1826
1827 btdm_controller_disable();
1828
1829 #if CONFIG_SW_COEXIST_ENABLE
1830 coex_disable();
1831 #endif
1832
1833 esp_phy_disable(PHY_MODEM_BT);
1834 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1835 esp_unregister_shutdown_handler(bt_shutdown);
1836
1837 #ifdef CONFIG_PM_ENABLE
1838 if (!s_btdm_allow_light_sleep) {
1839 esp_pm_lock_release(s_light_sleep_pm_lock);
1840 }
1841 esp_pm_lock_release(s_pm_lock);
1842 #endif
1843
1844 return ESP_OK;
1845 }
1846
esp_bt_controller_get_status(void)1847 esp_bt_controller_status_t esp_bt_controller_get_status(void)
1848 {
1849 return btdm_controller_status;
1850 }
1851
1852 /* extra functions */
esp_ble_tx_power_set(esp_ble_power_type_t power_type,esp_power_level_t power_level)1853 esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level)
1854 {
1855 if (ble_txpwr_set(power_type, power_level) != 0) {
1856 return ESP_ERR_INVALID_ARG;
1857 }
1858
1859 return ESP_OK;
1860 }
1861
esp_ble_tx_power_get(esp_ble_power_type_t power_type)1862 esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type)
1863 {
1864 return (esp_power_level_t)ble_txpwr_get(power_type);
1865 }
1866
esp_bredr_tx_power_set(esp_power_level_t min_power_level,esp_power_level_t max_power_level)1867 esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level)
1868 {
1869 esp_err_t err;
1870 int ret;
1871
1872 ret = bredr_txpwr_set(min_power_level, max_power_level);
1873
1874 if (ret == 0) {
1875 err = ESP_OK;
1876 } else if (ret == -1) {
1877 err = ESP_ERR_INVALID_ARG;
1878 } else {
1879 err = ESP_ERR_INVALID_STATE;
1880 }
1881
1882 return err;
1883 }
1884
esp_bredr_tx_power_get(esp_power_level_t * min_power_level,esp_power_level_t * max_power_level)1885 esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level)
1886 {
1887 if (bredr_txpwr_get((int *)min_power_level, (int *)max_power_level) != 0) {
1888 return ESP_ERR_INVALID_ARG;
1889 }
1890
1891 return ESP_OK;
1892 }
1893
esp_bt_sleep_enable(void)1894 esp_err_t esp_bt_sleep_enable (void)
1895 {
1896 esp_err_t status;
1897 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1898 return ESP_ERR_INVALID_STATE;
1899 }
1900 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
1901 btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
1902 btdm_controller_enable_sleep (true);
1903 status = ESP_OK;
1904 } else {
1905 status = ESP_ERR_NOT_SUPPORTED;
1906 }
1907
1908 return status;
1909 }
1910
esp_bt_sleep_disable(void)1911 esp_err_t esp_bt_sleep_disable (void)
1912 {
1913 esp_err_t status;
1914 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1915 return ESP_ERR_INVALID_STATE;
1916 }
1917 if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
1918 btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
1919 btdm_controller_enable_sleep (false);
1920 status = ESP_OK;
1921 } else {
1922 status = ESP_ERR_NOT_SUPPORTED;
1923 }
1924
1925 return status;
1926 }
1927
esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)1928 esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)
1929 {
1930 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1931 return ESP_ERR_INVALID_STATE;
1932 }
1933 bredr_sco_datapath_set(data_path);
1934 return ESP_OK;
1935 }
1936
esp_ble_scan_duplicate_list_flush(void)1937 esp_err_t esp_ble_scan_duplicate_list_flush(void)
1938 {
1939 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1940 return ESP_ERR_INVALID_STATE;
1941 }
1942 btdm_controller_scan_duplicate_list_clear();
1943 return ESP_OK;
1944 }
1945
esp_ble_scan_dupilcate_list_flush(void)1946 esp_err_t esp_ble_scan_dupilcate_list_flush(void)
1947 {
1948 return esp_ble_scan_duplicate_list_flush();
1949 }
1950
1951 /**
1952 * This function re-write controller's function,
1953 * As coredump can not show parameters in function which is in a .a file.
1954 *
1955 * After coredump fixing this issue, just delete this function.
1956 */
r_assert(const char * condition,int param0,int param1,const char * file,int line)1957 void IRAM_ATTR r_assert(const char *condition, int param0, int param1, const char *file, int line)
1958 {
1959 __asm__ __volatile__("ill\n");
1960 }
1961
1962 #endif /* CONFIG_BT_ENABLED */
1963