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