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