1 /*
2 * SPDX-FileCopyrightText: 2015-2021 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_system.h"
22 #include "esp_task.h"
23 #include "riscv/interrupt.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 "driver/periph_ctrl.h"
32 #include "soc/rtc.h"
33 #include "soc/rtc_cntl_reg.h"
34 #include "soc/soc_memory_layout.h"
35 #include "esp32c3/clk.h"
36 #include "esp_coexist_internal.h"
37 #include "esp32c3/rom/rom_layout.h"
38 #include "esp_timer.h"
39 #include "esp_sleep.h"
40 #include "phy.h"
41
42 #if CONFIG_BT_ENABLED
43
44 /* Macro definition
45 ************************************************************************
46 */
47
48 #define BTDM_LOG_TAG "BTDM_INIT"
49
50 #define BTDM_INIT_PERIOD (5000) /* ms */
51
52 /* Low Power Clock Selection */
53 #define BTDM_LPCLK_SEL_XTAL (0)
54 #define BTDM_LPCLK_SEL_XTAL32K (1)
55 #define BTDM_LPCLK_SEL_RTC_SLOW (2)
56 #define BTDM_LPCLK_SEL_8M (3)
57
58 // wakeup request sources
59 enum {
60 BTDM_ASYNC_WAKEUP_SRC_VHCI = 0,
61 BTDM_ASYNC_WAKEUP_SRC_DISA,
62 BTDM_ASYNC_WAKEUP_SRC_TMR,
63 BTDM_ASYNC_WAKEUP_SRC_MAX,
64 };
65
66 // low power control struct
67 typedef union {
68 struct {
69 uint32_t enable : 1; // whether low power mode is required
70 uint32_t lpclk_sel : 2; // low power clock source
71 uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) force-power-down is required during sleep
72 uint32_t wakeup_timer_required : 1; // whether system timer is needed
73 uint32_t no_light_sleep : 1; // do not allow system to enter light sleep after bluetooth is enabled
74 uint32_t reserved : 26; // reserved
75 };
76 uint32_t val;
77 } btdm_lpcntl_t;
78
79 // low power control status
80 typedef union {
81 struct {
82 uint32_t pm_lock_released : 1; // whether power management lock is released
83 uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) is powered down
84 uint32_t phy_enabled : 1; // whether phy is switched on
85 uint32_t wakeup_timer_started : 1; // whether wakeup timer is started
86 uint32_t reserved : 28; // reserved
87 };
88 uint32_t val;
89 } btdm_lpstat_t;
90
91 /* Sleep and wakeup interval control */
92 #define BTDM_MIN_SLEEP_DURATION (24) // threshold of interval in half slots to allow to fall into modem sleep
93 #define BTDM_MODEM_WAKE_UP_DELAY (8) // delay in half slots of modem wake up procedure, including re-enable PHY/RF
94
95 #define BT_DEBUG(...)
96 #define BT_API_CALL_CHECK(info, api_call, ret) \
97 do{\
98 esp_err_t __err = (api_call);\
99 if ((ret) != __err) {\
100 BT_DEBUG("%s %d %s ret=0x%X\n", __FUNCTION__, __LINE__, (info), __err);\
101 return __err;\
102 }\
103 } while(0)
104
105 #define OSI_FUNCS_TIME_BLOCKING 0xffffffff
106 #define OSI_VERSION 0x00010006
107 #define OSI_MAGIC_VALUE 0xFADEBEAD
108
109 /* Types definition
110 ************************************************************************
111 */
112 /* vendor dependent signals to be posted to controller task */
113 typedef enum {
114 BTDM_VND_OL_SIG_WAKEUP_TMR = 0,
115 BTDM_VND_OL_SIG_NUM,
116 } btdm_vnd_ol_sig_t;
117
118 /* prototype of function to handle vendor dependent signals */
119 typedef void (* btdm_vnd_ol_task_func_t)(void *param);
120
121 /* VHCI function interface */
122 typedef struct vhci_host_callback {
123 void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */
124 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*/
125 } vhci_host_callback_t;
126
127 /* Dram region */
128 typedef struct {
129 esp_bt_mode_t mode;
130 intptr_t start;
131 intptr_t end;
132 } btdm_dram_available_region_t;
133
134 typedef void (* osi_intr_handler)(void);
135
136 /* OSI function */
137 struct osi_funcs_t {
138 uint32_t _magic;
139 uint32_t _version;
140 void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio);
141 void (*_interrupt_clear)(int interrupt_source, int interrupt_no);
142 void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg);
143 void (*_interrupt_disable)(void);
144 void (*_interrupt_restore)(void);
145 void (*_task_yield)(void);
146 void (*_task_yield_from_isr)(void);
147 void *(*_semphr_create)(uint32_t max, uint32_t init);
148 void (*_semphr_delete)(void *semphr);
149 int (*_semphr_take_from_isr)(void *semphr, void *hptw);
150 int (*_semphr_give_from_isr)(void *semphr, void *hptw);
151 int (*_semphr_take)(void *semphr, uint32_t block_time_ms);
152 int (*_semphr_give)(void *semphr);
153 void *(*_mutex_create)(void);
154 void (*_mutex_delete)(void *mutex);
155 int (*_mutex_lock)(void *mutex);
156 int (*_mutex_unlock)(void *mutex);
157 void *(* _queue_create)(uint32_t queue_len, uint32_t item_size);
158 void (* _queue_delete)(void *queue);
159 int (* _queue_send)(void *queue, void *item, uint32_t block_time_ms);
160 int (* _queue_send_from_isr)(void *queue, void *item, void *hptw);
161 int (* _queue_recv)(void *queue, void *item, uint32_t block_time_ms);
162 int (* _queue_recv_from_isr)(void *queue, void *item, void *hptw);
163 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);
164 void (* _task_delete)(void *task_handle);
165 bool (* _is_in_isr)(void);
166 int (* _cause_sw_intr_to_core)(int core_id, int intr_no);
167 void *(* _malloc)(size_t size);
168 void *(* _malloc_internal)(size_t size);
169 void (* _free)(void *p);
170 int (* _read_efuse_mac)(uint8_t mac[6]);
171 void (* _srand)(unsigned int seed);
172 int (* _rand)(void);
173 uint32_t (* _btdm_lpcycles_2_hus)(uint32_t cycles, uint32_t *error_corr);
174 uint32_t (* _btdm_hus_2_lpcycles)(uint32_t hus);
175 bool (* _btdm_sleep_check_duration)(int32_t *slot_cnt);
176 void (* _btdm_sleep_enter_phase1)(uint32_t lpcycles); /* called when interrupt is disabled */
177 void (* _btdm_sleep_enter_phase2)(void);
178 void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */
179 void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */
180 void (* _btdm_sleep_exit_phase3)(void); /* called from task */
181 void (* _coex_wifi_sleep_set)(bool sleep);
182 int (* _coex_core_ble_conn_dyn_prio_get)(bool *low, bool *high);
183 void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
184 void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
185 void (* _interrupt_on)(int intr_num);
186 void (* _interrupt_off)(int intr_num);
187 void (* _esp_hw_power_down)(void);
188 void (* _esp_hw_power_up)(void);
189 void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem);
190 };
191
192
193 /* External functions or values
194 ************************************************************************
195 */
196
197 /* not for user call, so don't put to include file */
198 /* OSI */
199 extern int btdm_osi_funcs_register(void *osi_funcs);
200 /* Initialise and De-initialise */
201 extern int btdm_controller_init(esp_bt_controller_config_t *config_opts);
202 extern void btdm_controller_deinit(void);
203 extern int btdm_controller_enable(esp_bt_mode_t mode);
204 extern void btdm_controller_disable(void);
205 extern uint8_t btdm_controller_get_mode(void);
206 extern const char *btdm_controller_get_compile_version(void);
207 extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
208
209 /* Sleep */
210 extern void btdm_controller_enable_sleep(bool enable);
211 extern uint8_t btdm_controller_get_sleep_mode(void);
212 extern bool btdm_power_state_active(void);
213 extern void btdm_wakeup_request(void);
214 extern void btdm_in_wakeup_requesting_set(bool in_wakeup_requesting);
215
216 /* vendor dependent tasks to be posted and handled by controller task*/
217 extern int btdm_vnd_offload_task_register(btdm_vnd_ol_sig_t sig, btdm_vnd_ol_task_func_t func);
218 extern int btdm_vnd_offload_task_deregister(btdm_vnd_ol_sig_t sig);
219 extern int btdm_vnd_offload_post_from_isr(btdm_vnd_ol_sig_t sig, void *param, bool need_yield);
220 extern int btdm_vnd_offload_post(btdm_vnd_ol_sig_t sig, void *param);
221
222 /* Low Power Clock */
223 extern bool btdm_lpclk_select_src(uint32_t sel);
224 extern bool btdm_lpclk_set_div(uint32_t div);
225 extern int btdm_hci_tl_io_event_post(int event);
226
227 /* VHCI */
228 extern bool API_vhci_host_check_send_available(void);
229 extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
230 extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback);
231 /* TX power */
232 extern int ble_txpwr_set(int power_type, int power_level);
233 extern int ble_txpwr_get(int power_type);
234
235 extern uint16_t l2c_ble_link_get_tx_buf_num(void);
236 extern int coex_core_ble_conn_dyn_prio_get(bool *low, bool *high);
237
238 extern bool btdm_deep_sleep_mem_init(void);
239 extern void btdm_deep_sleep_mem_deinit(void);
240 extern void btdm_ble_power_down_dma_copy(bool copy);
241 extern uint8_t btdm_sleep_clock_sync(void);
242
243 #if CONFIG_MAC_BB_PD
244 extern void esp_mac_bb_power_down(void);
245 extern void esp_mac_bb_power_up(void);
246 extern void ets_backup_dma_copy(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem);
247 #endif
248
249 extern char _bss_start_btdm;
250 extern char _bss_end_btdm;
251 extern char _data_start_btdm;
252 extern char _data_end_btdm;
253 extern uint32_t _data_start_btdm_rom;
254 extern uint32_t _data_end_btdm_rom;
255
256 extern uint32_t _bt_bss_start;
257 extern uint32_t _bt_bss_end;
258 extern uint32_t _btdm_bss_start;
259 extern uint32_t _btdm_bss_end;
260 extern uint32_t _bt_data_start;
261 extern uint32_t _bt_data_end;
262 extern uint32_t _btdm_data_start;
263 extern uint32_t _btdm_data_end;
264
265 extern char _bt_tmp_bss_start;
266 extern char _bt_tmp_bss_end;
267
268 /* Local Function Declare
269 *********************************************************************
270 */
271 static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio);
272 static void interrupt_clear_wrapper(int intr_source, int intr_num);
273 static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg);
274 static void IRAM_ATTR interrupt_disable(void);
275 static void IRAM_ATTR interrupt_restore(void);
276 static void IRAM_ATTR task_yield_from_isr(void);
277 static void *semphr_create_wrapper(uint32_t max, uint32_t init);
278 static void semphr_delete_wrapper(void *semphr);
279 static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw);
280 static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw);
281 static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms);
282 static int semphr_give_wrapper(void *semphr);
283 static void *mutex_create_wrapper(void);
284 static void mutex_delete_wrapper(void *mutex);
285 static int mutex_lock_wrapper(void *mutex);
286 static int mutex_unlock_wrapper(void *mutex);
287 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
288 static void queue_delete_wrapper(void *queue);
289 static int queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
290 static int IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw);
291 static int queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
292 static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw);
293 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);
294 static void task_delete_wrapper(void *task_handle);
295 static bool IRAM_ATTR is_in_isr_wrapper(void);
296 static void *malloc_internal_wrapper(size_t size);
297 static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]);
298 static void IRAM_ATTR srand_wrapper(unsigned int seed);
299 static int IRAM_ATTR rand_wrapper(void);
300 static uint32_t IRAM_ATTR btdm_lpcycles_2_hus(uint32_t cycles, uint32_t *error_corr);
301 static uint32_t IRAM_ATTR btdm_hus_2_lpcycles(uint32_t hus);
302 static bool IRAM_ATTR btdm_sleep_check_duration(int32_t *slot_cnt);
303 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
304 static void btdm_sleep_enter_phase2_wrapper(void);
305 static void btdm_sleep_exit_phase3_wrapper(void);
306 static void coex_wifi_sleep_set_hook(bool sleep);
307 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
308 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
309 static void interrupt_on_wrapper(int intr_num);
310 static void interrupt_off_wrapper(int intr_num);
311 static void btdm_hw_mac_power_up_wrapper(void);
312 static void btdm_hw_mac_power_down_wrapper(void);
313 static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem);
314
315 static void btdm_slp_tmr_callback(void *arg);
316 /* Local variable definition
317 ***************************************************************************
318 */
319 /* OSI funcs */
320 static const struct osi_funcs_t osi_funcs_ro = {
321 ._magic = OSI_MAGIC_VALUE,
322 ._version = OSI_VERSION,
323 ._interrupt_set = interrupt_set_wrapper,
324 ._interrupt_clear = interrupt_clear_wrapper,
325 ._interrupt_handler_set = interrupt_handler_set_wrapper,
326 ._interrupt_disable = interrupt_disable,
327 ._interrupt_restore = interrupt_restore,
328 ._task_yield = vPortYield,
329 ._task_yield_from_isr = task_yield_from_isr,
330 ._semphr_create = semphr_create_wrapper,
331 ._semphr_delete = semphr_delete_wrapper,
332 ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
333 ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
334 ._semphr_take = semphr_take_wrapper,
335 ._semphr_give = semphr_give_wrapper,
336 ._mutex_create = mutex_create_wrapper,
337 ._mutex_delete = mutex_delete_wrapper,
338 ._mutex_lock = mutex_lock_wrapper,
339 ._mutex_unlock = mutex_unlock_wrapper,
340 ._queue_create = queue_create_wrapper,
341 ._queue_delete = queue_delete_wrapper,
342 ._queue_send = queue_send_wrapper,
343 ._queue_send_from_isr = queue_send_from_isr_wrapper,
344 ._queue_recv = queue_recv_wrapper,
345 ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
346 ._task_create = task_create_wrapper,
347 ._task_delete = task_delete_wrapper,
348 ._is_in_isr = is_in_isr_wrapper,
349 ._cause_sw_intr_to_core = NULL,
350 ._malloc = malloc,
351 ._malloc_internal = malloc_internal_wrapper,
352 ._free = free,
353 ._read_efuse_mac = read_mac_wrapper,
354 ._srand = srand_wrapper,
355 ._rand = rand_wrapper,
356 ._btdm_lpcycles_2_hus = btdm_lpcycles_2_hus,
357 ._btdm_hus_2_lpcycles = btdm_hus_2_lpcycles,
358 ._btdm_sleep_check_duration = btdm_sleep_check_duration,
359 ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
360 ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
361 ._btdm_sleep_exit_phase1 = NULL,
362 ._btdm_sleep_exit_phase2 = NULL,
363 ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
364 ._coex_wifi_sleep_set = coex_wifi_sleep_set_hook,
365 ._coex_core_ble_conn_dyn_prio_get = coex_core_ble_conn_dyn_prio_get,
366 ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
367 ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
368 ._interrupt_on = interrupt_on_wrapper,
369 ._interrupt_off = interrupt_off_wrapper,
370 ._esp_hw_power_down = btdm_hw_mac_power_down_wrapper,
371 ._esp_hw_power_up = btdm_hw_mac_power_up_wrapper,
372 ._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper,
373 };
374
375 static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
376
377 /* Static variable declare */
378 static DRAM_ATTR esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
379
380 static DRAM_ATTR portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
381
382 // low power control struct
383 static DRAM_ATTR btdm_lpcntl_t s_lp_cntl;
384 // low power status struct
385 static DRAM_ATTR btdm_lpstat_t s_lp_stat;
386 // measured average low power clock period in micro seconds
387 static DRAM_ATTR uint32_t btdm_lpcycle_us = 0;
388 // number of fractional bit for btdm_lpcycle_us
389 static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0;
390 // semaphore used for blocking VHCI API to wait for controller to wake up
391 static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
392 // wakeup timer
393 static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
394
395 #ifdef CONFIG_PM_ENABLE
396 static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
397 // pm_lock to prevent light sleep due to incompatibility currently
398 static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
399 #endif
400
btdm_hw_mac_power_down_wrapper(void)401 void IRAM_ATTR btdm_hw_mac_power_down_wrapper(void)
402 {
403 #if CONFIG_MAC_BB_PD
404 // Bluetooth module power down
405 SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
406 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
407
408 esp_mac_bb_power_down();
409 #endif
410 }
411
btdm_hw_mac_power_up_wrapper(void)412 void IRAM_ATTR btdm_hw_mac_power_up_wrapper(void)
413 {
414 #if CONFIG_MAC_BB_PD
415 // Bluetooth module power up
416 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
417 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
418
419 esp_mac_bb_power_up();
420 #endif
421 }
422
esp_bt_power_domain_on(void)423 static inline void esp_bt_power_domain_on(void)
424 {
425 // Bluetooth module power up
426 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
427 CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
428 esp_wifi_bt_power_domain_on();
429 }
430
esp_bt_power_domain_off(void)431 static inline void esp_bt_power_domain_off(void)
432 {
433 // Bluetooth module power down
434 SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_BT_FORCE_ISO);
435 SET_PERI_REG_MASK(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_FORCE_PD);
436 esp_wifi_bt_power_domain_off();
437 }
438
btdm_backup_dma_copy_wrapper(uint32_t reg,uint32_t mem_addr,uint32_t num,bool to_mem)439 void IRAM_ATTR btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem)
440 {
441 #if CONFIG_MAC_BB_PD
442 ets_backup_dma_copy(reg, mem_addr, num, to_mem);
443 #endif
444 }
445
interrupt_set_wrapper(int cpu_no,int intr_source,int intr_num,int intr_prio)446 static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio)
447 {
448 intr_matrix_route(intr_source, intr_num);
449 esprv_intc_int_set_priority(intr_num, intr_prio);
450 //esprv_intc_int_enable_level(1 << intr_num);
451 esprv_intc_int_set_type(intr_num, 0);
452 }
453
interrupt_clear_wrapper(int intr_source,int intr_num)454 static void interrupt_clear_wrapper(int intr_source, int intr_num)
455 {
456 }
457
interrupt_handler_set_wrapper(int n,intr_handler_t fn,void * arg)458 static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg)
459 {
460 intr_handler_set(n, fn, arg);
461 }
462
interrupt_on_wrapper(int intr_num)463 static void interrupt_on_wrapper(int intr_num)
464 {
465 esprv_intc_int_enable(1 << intr_num);
466 }
467
interrupt_off_wrapper(int intr_num)468 static void interrupt_off_wrapper(int intr_num)
469 {
470 esprv_intc_int_disable(1<<intr_num);
471 }
472
interrupt_disable(void)473 static void IRAM_ATTR interrupt_disable(void)
474 {
475 if (xPortInIsrContext()) {
476 portENTER_CRITICAL_ISR(&global_int_mux);
477 } else {
478 portENTER_CRITICAL(&global_int_mux);
479 }
480 }
481
interrupt_restore(void)482 static void IRAM_ATTR interrupt_restore(void)
483 {
484 if (xPortInIsrContext()) {
485 portEXIT_CRITICAL_ISR(&global_int_mux);
486 } else {
487 portEXIT_CRITICAL(&global_int_mux);
488 }
489 }
490
task_yield_from_isr(void)491 static void IRAM_ATTR task_yield_from_isr(void)
492 {
493 portYIELD_FROM_ISR();
494 }
495
semphr_create_wrapper(uint32_t max,uint32_t init)496 static void *semphr_create_wrapper(uint32_t max, uint32_t init)
497 {
498 return (void *)xSemaphoreCreateCounting(max, init);
499 }
500
semphr_delete_wrapper(void * semphr)501 static void semphr_delete_wrapper(void *semphr)
502 {
503 vSemaphoreDelete(semphr);
504 }
505
semphr_take_from_isr_wrapper(void * semphr,void * hptw)506 static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
507 {
508 return (int)xSemaphoreTakeFromISR(semphr, hptw);
509 }
510
semphr_give_from_isr_wrapper(void * semphr,void * hptw)511 static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
512 {
513 return (int)xSemaphoreGiveFromISR(semphr, hptw);
514 }
515
semphr_take_wrapper(void * semphr,uint32_t block_time_ms)516 static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
517 {
518 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
519 return (int)xSemaphoreTake(semphr, portMAX_DELAY);
520 } else {
521 return (int)xSemaphoreTake(semphr, block_time_ms / portTICK_PERIOD_MS);
522 }
523 }
524
semphr_give_wrapper(void * semphr)525 static int semphr_give_wrapper(void *semphr)
526 {
527 return (int)xSemaphoreGive(semphr);
528 }
529
mutex_create_wrapper(void)530 static void *mutex_create_wrapper(void)
531 {
532 return (void *)xSemaphoreCreateMutex();
533 }
534
mutex_delete_wrapper(void * mutex)535 static void mutex_delete_wrapper(void *mutex)
536 {
537 vSemaphoreDelete(mutex);
538 }
539
mutex_lock_wrapper(void * mutex)540 static int mutex_lock_wrapper(void *mutex)
541 {
542 return (int)xSemaphoreTake(mutex, portMAX_DELAY);
543 }
544
mutex_unlock_wrapper(void * mutex)545 static int mutex_unlock_wrapper(void *mutex)
546 {
547 return (int)xSemaphoreGive(mutex);
548 }
549
queue_create_wrapper(uint32_t queue_len,uint32_t item_size)550 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
551 {
552 return (void *)xQueueCreate(queue_len, item_size);
553 }
554
queue_delete_wrapper(void * queue)555 static void queue_delete_wrapper(void *queue)
556 {
557 vQueueDelete(queue);
558 }
559
queue_send_wrapper(void * queue,void * item,uint32_t block_time_ms)560 static int queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms)
561 {
562 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
563 return (int)xQueueSend(queue, item, portMAX_DELAY);
564 } else {
565 return (int)xQueueSend(queue, item, block_time_ms / portTICK_PERIOD_MS);
566 }
567 }
568
queue_send_from_isr_wrapper(void * queue,void * item,void * hptw)569 static int IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw)
570 {
571 return (int)xQueueSendFromISR(queue, item, hptw);
572 }
573
queue_recv_wrapper(void * queue,void * item,uint32_t block_time_ms)574 static int queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms)
575 {
576 if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
577 return (int)xQueueReceive(queue, item, portMAX_DELAY);
578 } else {
579 return (int)xQueueReceive(queue, item, block_time_ms / portTICK_PERIOD_MS);
580 }
581 }
582
queue_recv_from_isr_wrapper(void * queue,void * item,void * hptw)583 static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw)
584 {
585 return (int)xQueueReceiveFromISR(queue, item, hptw);
586 }
587
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)588 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)
589 {
590 return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY));
591 }
592
task_delete_wrapper(void * task_handle)593 static void task_delete_wrapper(void *task_handle)
594 {
595 vTaskDelete(task_handle);
596 }
597
is_in_isr_wrapper(void)598 static bool IRAM_ATTR is_in_isr_wrapper(void)
599 {
600 return (bool)xPortInIsrContext();
601 }
602
malloc_internal_wrapper(size_t size)603 static void *malloc_internal_wrapper(size_t size)
604 {
605 return heap_caps_malloc(size, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL|MALLOC_CAP_DMA);
606 }
607
read_mac_wrapper(uint8_t mac[6])608 static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
609 {
610 int ret = esp_read_mac(mac, ESP_MAC_BT);
611 ESP_LOGI(BTDM_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
612 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
613
614 return ret;
615 }
616
srand_wrapper(unsigned int seed)617 static void IRAM_ATTR srand_wrapper(unsigned int seed)
618 {
619 /* empty function */
620 }
621
rand_wrapper(void)622 static int IRAM_ATTR rand_wrapper(void)
623 {
624 return (int)esp_random();
625 }
626
btdm_lpcycles_2_hus(uint32_t cycles,uint32_t * error_corr)627 static uint32_t IRAM_ATTR btdm_lpcycles_2_hus(uint32_t cycles, uint32_t *error_corr)
628 {
629 uint64_t local_error_corr = (error_corr == NULL) ? 0 : (uint64_t)(*error_corr);
630 uint64_t res = (uint64_t)btdm_lpcycle_us * cycles * 2;
631 local_error_corr += res;
632 res = (local_error_corr >> btdm_lpcycle_us_frac);
633 local_error_corr -= (res << btdm_lpcycle_us_frac);
634 if (error_corr) {
635 *error_corr = (uint32_t) local_error_corr;
636 }
637 return (uint32_t)res;
638 }
639
640 /*
641 * @brief Converts a duration in half us into a number of low power clock cycles.
642 */
btdm_hus_2_lpcycles(uint32_t hus)643 static uint32_t IRAM_ATTR btdm_hus_2_lpcycles(uint32_t hus)
644 {
645 // The number of sleep duration(us) should not lead to overflow. Thrs: 100s
646 // Compute the sleep duration in us to low power clock cycles, with calibration result applied
647 // clock measurement is conducted
648 uint64_t cycles = ((uint64_t)(hus) << btdm_lpcycle_us_frac) / btdm_lpcycle_us;
649 cycles >>= 1;
650
651 return (uint32_t)cycles;
652 }
653
btdm_sleep_check_duration(int32_t * half_slot_cnt)654 static bool IRAM_ATTR btdm_sleep_check_duration(int32_t *half_slot_cnt)
655 {
656 if (*half_slot_cnt < BTDM_MIN_SLEEP_DURATION) {
657 return false;
658 }
659 /* wake up in advance considering the delay in enabling PHY/RF */
660 *half_slot_cnt -= BTDM_MODEM_WAKE_UP_DELAY;
661 return true;
662 }
663
btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)664 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
665 {
666 if (s_lp_cntl.wakeup_timer_required == 0) {
667 return;
668 }
669
670 // start a timer to wake up and acquire the pm_lock before modem_sleep awakes
671 uint32_t us_to_sleep = btdm_lpcycles_2_hus(lpcycles, NULL) >> 1;
672
673 #define BTDM_MIN_TIMER_UNCERTAINTY_US (1800)
674 assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
675 // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
676 // and set the timer in advance
677 uint32_t uncertainty = (us_to_sleep >> 11);
678 if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) {
679 uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
680 }
681
682 assert (s_lp_stat.wakeup_timer_started == 0);
683 if (esp_timer_start_once(s_btdm_slp_tmr, us_to_sleep - uncertainty) == ESP_OK) {
684 s_lp_stat.wakeup_timer_started = 1;
685 } else {
686 ESP_LOGE(BTDM_LOG_TAG, "timer start failed");
687 assert(0);
688 }
689 }
690
btdm_sleep_enter_phase2_wrapper(void)691 static void btdm_sleep_enter_phase2_wrapper(void)
692 {
693 if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) {
694 if (s_lp_stat.phy_enabled) {
695 esp_phy_disable();
696 s_lp_stat.phy_enabled = 0;
697 } else {
698 assert(0);
699 }
700
701 if (s_lp_stat.pm_lock_released == 0) {
702 #ifdef CONFIG_PM_ENABLE
703 esp_pm_lock_release(s_pm_lock);
704 #endif
705 s_lp_stat.pm_lock_released = 1;
706 }
707 }
708 }
709
btdm_sleep_exit_phase3_wrapper(void)710 static void btdm_sleep_exit_phase3_wrapper(void)
711 {
712 #ifdef CONFIG_PM_ENABLE
713 // If BT wakeup before esp timer coming due to timer task have no chance to run.
714 // Then we will not run into `btdm_sleep_exit_phase0` and acquire PM lock,
715 // Do it again here to fix this issue.
716 if (s_lp_stat.pm_lock_released) {
717 esp_pm_lock_acquire(s_pm_lock);
718 s_lp_stat.pm_lock_released = 0;
719 }
720 #endif
721
722 if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) {
723 if (s_lp_stat.phy_enabled == 0) {
724 esp_phy_enable();
725 s_lp_stat.phy_enabled = 1;
726 }
727 }
728
729 // If BT wakeup before esp timer coming due to timer task have no chance to run.
730 // Then we will not run into `btdm_sleep_exit_phase0` and stop esp timer,
731 // Do it again here to fix this issue.
732 if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
733 esp_timer_stop(s_btdm_slp_tmr);
734 s_lp_stat.wakeup_timer_started = 0;
735 }
736
737 // wait for the sleep state to change
738 // the procedure duration is at micro-second level or less
739 while (btdm_sleep_clock_sync()) {
740 ;
741 }
742 }
743
btdm_sleep_exit_phase0(void * param)744 static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
745 {
746 assert(s_lp_cntl.enable == 1);
747
748 #ifdef CONFIG_PM_ENABLE
749 if (s_lp_stat.pm_lock_released) {
750 esp_pm_lock_acquire(s_pm_lock);
751 s_lp_stat.pm_lock_released = 0;
752 }
753 #endif
754
755 int event = (int) param;
756 if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI || event == BTDM_ASYNC_WAKEUP_SRC_DISA) {
757 btdm_wakeup_request();
758 }
759
760 if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
761 esp_timer_stop(s_btdm_slp_tmr);
762 s_lp_stat.wakeup_timer_started = 0;
763 }
764
765 if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI || event == BTDM_ASYNC_WAKEUP_SRC_DISA) {
766 semphr_give_wrapper(s_wakeup_req_sem);
767 }
768 }
769
btdm_slp_tmr_callback(void * arg)770 static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
771 {
772 #ifdef CONFIG_PM_ENABLE
773 btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR, (void *)BTDM_ASYNC_WAKEUP_SRC_TMR);
774 #endif
775 }
776
777
async_wakeup_request(int event)778 static bool async_wakeup_request(int event)
779 {
780 if (s_lp_cntl.enable == 0) {
781 return false;
782 }
783
784 bool do_wakeup_request = false;
785 switch (event) {
786 case BTDM_ASYNC_WAKEUP_SRC_VHCI:
787 case BTDM_ASYNC_WAKEUP_SRC_DISA:
788 btdm_in_wakeup_requesting_set(true);
789 if (!btdm_power_state_active()) {
790 btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR, (void *)event);
791 do_wakeup_request = true;
792 semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING);
793 }
794 break;
795 default:
796 break;
797 }
798
799 return do_wakeup_request;
800 }
801
async_wakeup_request_end(int event)802 static void async_wakeup_request_end(int event)
803 {
804 if (s_lp_cntl.enable == 0) {
805 return;
806 }
807
808 bool allow_to_sleep;
809 switch (event) {
810 case BTDM_ASYNC_WAKEUP_SRC_VHCI:
811 case BTDM_ASYNC_WAKEUP_SRC_DISA:
812 allow_to_sleep = true;
813 break;
814 default:
815 allow_to_sleep = true;
816 break;
817 }
818
819 if (allow_to_sleep) {
820 btdm_in_wakeup_requesting_set(false);
821 }
822
823 return;
824 }
825
coex_schm_status_bit_set_wrapper(uint32_t type,uint32_t status)826 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
827 {
828 #if CONFIG_SW_COEXIST_ENABLE
829 coex_schm_status_bit_set(type, status);
830 #endif
831 }
832
coex_schm_status_bit_clear_wrapper(uint32_t type,uint32_t status)833 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
834 {
835 #if CONFIG_SW_COEXIST_ENABLE
836 coex_schm_status_bit_clear(type, status);
837 #endif
838 }
839
esp_vhci_host_check_send_available(void)840 bool esp_vhci_host_check_send_available(void)
841 {
842 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
843 return false;
844 }
845 return API_vhci_host_check_send_available();
846 }
847
esp_vhci_host_send_packet(uint8_t * data,uint16_t len)848 void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
849 {
850 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
851 return;
852 }
853 async_wakeup_request(BTDM_ASYNC_WAKEUP_SRC_VHCI);
854
855 API_vhci_host_send_packet(data, len);
856
857 async_wakeup_request_end(BTDM_ASYNC_WAKEUP_SRC_VHCI);
858 }
859
esp_vhci_host_register_callback(const esp_vhci_host_callback_t * callback)860 esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
861 {
862 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
863 return ESP_FAIL;
864 }
865 return API_vhci_host_register_callback((const vhci_host_callback_t *)callback) == 0 ? ESP_OK : ESP_FAIL;
866 }
867
btdm_controller_mem_init(void)868 static void btdm_controller_mem_init(void)
869 {
870 extern void btdm_controller_rom_data_init(void );
871 btdm_controller_rom_data_init();
872 }
873
esp_bt_controller_mem_release(esp_bt_mode_t mode)874 esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
875 {
876 ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return OK", __func__);
877 return ESP_OK;
878 }
879
esp_bt_mem_release(esp_bt_mode_t mode)880 esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
881 {
882 ESP_LOGW(BTDM_LOG_TAG, "%s not implemented, return OK", __func__);
883 return ESP_OK;
884 }
885
try_heap_caps_add_region(intptr_t start,intptr_t end)886 static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
887 {
888 int ret = heap_caps_add_region(start, end);
889 /* heap_caps_add_region() returns ESP_ERR_INVALID_SIZE if the memory region is
890 * is too small to fit a heap. This cannot be termed as a fatal error and hence
891 * we replace it by ESP_OK
892 */
893 if (ret == ESP_ERR_INVALID_SIZE) {
894 return ESP_OK;
895 }
896 return ret;
897 }
898
899 // release wifi and coex memory, free about 720 bytes,
esp_release_wifi_and_coex_mem(void)900 void esp_release_wifi_and_coex_mem(void)
901 {
902 ESP_ERROR_CHECK(try_heap_caps_add_region((intptr_t)ets_rom_layout_p->dram_start_coexist, (intptr_t)ets_rom_layout_p->dram_end_pp));
903 ESP_ERROR_CHECK(try_heap_caps_add_region((intptr_t)ets_rom_layout_p->data_start_interface_coexist,(intptr_t)ets_rom_layout_p->bss_end_interface_pp));
904 }
905
906 #if CONFIG_FREERTOS_USE_TICKLESS_IDLE
btdm_mac_bb_power_down_cb(void)907 static void IRAM_ATTR btdm_mac_bb_power_down_cb(void)
908 {
909 if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd == 0) {
910 #if (CONFIG_MAC_BB_PD)
911 btdm_ble_power_down_dma_copy(true);
912 #endif
913 s_lp_stat.mac_bb_pd = 1;
914 }
915 }
916
btdm_mac_bb_power_up_cb(void)917 static void IRAM_ATTR btdm_mac_bb_power_up_cb(void)
918 {
919 #if (CONFIG_MAC_BB_PD)
920 if (s_lp_cntl.mac_bb_pd && s_lp_stat.mac_bb_pd) {
921 btdm_ble_power_down_dma_copy(false);
922 s_lp_stat.mac_bb_pd = 0;
923 }
924 #endif
925 }
926 #endif
927
esp_bt_controller_init(esp_bt_controller_config_t * cfg)928 esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
929 {
930 esp_err_t err = ESP_FAIL;
931
932 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
933 return ESP_ERR_INVALID_STATE;
934 }
935
936 if (cfg == NULL) {
937 return ESP_ERR_INVALID_ARG;
938 }
939
940 if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO
941 || cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) {
942 ESP_LOGE(BTDM_LOG_TAG, "Invalid controller task prioriy or stack size");
943 return ESP_ERR_INVALID_ARG;
944 }
945
946 if (cfg->bluetooth_mode != ESP_BT_MODE_BLE) {
947 ESP_LOGE(BTDM_LOG_TAG, "%s controller only support BLE only mode", __func__);
948 return ESP_ERR_NOT_SUPPORTED;
949 }
950
951 if (cfg->bluetooth_mode & ESP_BT_MODE_BLE) {
952 if ((cfg->ble_max_act <= 0) || (cfg->ble_max_act > BT_CTRL_BLE_MAX_ACT_LIMIT)) {
953 ESP_LOGE(BTDM_LOG_TAG, "Invalid value of ble_max_act");
954 return ESP_ERR_INVALID_ARG;
955 }
956 }
957
958 if (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) {
959 if (cfg->sleep_clock == ESP_BT_SLEEP_CLOCK_NONE) {
960 ESP_LOGE(BTDM_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured");
961 return ESP_ERR_INVALID_ARG;
962 }
963 }
964
965 // overwrite some parameters
966 cfg->magic = ESP_BT_CTRL_CONFIG_MAGIC_VAL;
967
968 #if CONFIG_MAC_BB_PD
969 esp_mac_bb_pd_mem_init();
970 #endif
971 esp_bt_power_domain_on();
972
973 btdm_controller_mem_init();
974
975 #if CONFIG_MAC_BB_PD
976 if (esp_register_mac_bb_pd_callback(btdm_mac_bb_power_down_cb) != 0) {
977 err = ESP_ERR_INVALID_ARG;
978 goto error;
979 }
980
981 if (esp_register_mac_bb_pu_callback(btdm_mac_bb_power_up_cb) != 0) {
982 err = ESP_ERR_INVALID_ARG;
983 goto error;
984 }
985 #endif
986
987 osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
988 if (osi_funcs_p == NULL) {
989 return ESP_ERR_NO_MEM;
990 }
991
992 memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t));
993 if (btdm_osi_funcs_register(osi_funcs_p) != 0) {
994 return ESP_ERR_INVALID_ARG;
995 }
996
997 ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
998
999 // init low-power control resources
1000 do {
1001 // set default values for global states or resources
1002 s_lp_stat.val = 0;
1003 s_lp_cntl.val = 0;
1004 s_wakeup_req_sem = NULL;
1005 s_btdm_slp_tmr = NULL;
1006
1007 // configure and initialize resources
1008 s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
1009 s_lp_cntl.no_light_sleep = 1;
1010
1011 if (s_lp_cntl.enable) {
1012 #if (CONFIG_MAC_BB_PD)
1013 if (!btdm_deep_sleep_mem_init()) {
1014 err = ESP_ERR_NO_MEM;
1015 goto error;
1016 }
1017 s_lp_cntl.mac_bb_pd = 1;
1018 #endif
1019 #ifdef CONFIG_PM_ENABLE
1020 s_lp_cntl.wakeup_timer_required = 1;
1021 #endif
1022 // async wakeup semaphore for VHCI
1023 s_wakeup_req_sem = semphr_create_wrapper(1, 0);
1024 if (s_wakeup_req_sem == NULL) {
1025 err = ESP_ERR_NO_MEM;
1026 goto error;
1027 }
1028 btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0);
1029 }
1030
1031 if (s_lp_cntl.wakeup_timer_required) {
1032 esp_timer_create_args_t create_args = {
1033 .callback = btdm_slp_tmr_callback,
1034 .arg = NULL,
1035 .name = "btSlp",
1036 };
1037 if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
1038 goto error;
1039 }
1040 }
1041
1042 // set default bluetooth sleep clock cycle and its fractional bits
1043 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1044 btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1045
1046 // set default bluetooth sleep clock source
1047 s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1048 #if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
1049 // check whether or not EXT_CRYS is working
1050 if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_32K_XTAL) {
1051 s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL
1052 s_lp_cntl.no_light_sleep = 0;
1053 } else {
1054 ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
1055 "light sleep mode will not be able to apply when bluetooth is enabled");
1056 }
1057 #elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
1058 // check whether or not EXT_CRYS is working
1059 if (rtc_clk_slow_freq_get() == RTC_SLOW_FREQ_RTC) {
1060 s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
1061 ESP_LOGW(BTDM_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
1062 "required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
1063 } else {
1064 ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected.");
1065 assert(0);
1066 }
1067 #else
1068 s_lp_cntl.no_light_sleep = 1;
1069 #endif
1070
1071 bool select_src_ret __attribute__((unused));
1072 bool set_div_ret __attribute__((unused));
1073 if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
1074 select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
1075 set_div_ret = btdm_lpclk_set_div(rtc_clk_xtal_freq_get() * 2);
1076 assert(select_src_ret && set_div_ret);
1077 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1078 btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1079 } else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL32K) {
1080 select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
1081 set_div_ret = btdm_lpclk_set_div(0);
1082 assert(select_src_ret && set_div_ret);
1083 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1084 btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
1085 (1000000 >> (15 - RTC_CLK_CAL_FRACT));
1086 assert(btdm_lpcycle_us != 0);
1087 } else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_RTC_SLOW) {
1088 select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
1089 set_div_ret = btdm_lpclk_set_div(0);
1090 assert(select_src_ret && set_div_ret);
1091 btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1092 btdm_lpcycle_us = esp_clk_slowclk_cal_get();
1093 } else {
1094 err = ESP_ERR_INVALID_ARG;
1095 goto error;
1096 }
1097
1098 #ifdef CONFIG_PM_ENABLE
1099 if (s_lp_cntl.no_light_sleep) {
1100 if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
1101 err = ESP_ERR_NO_MEM;
1102 goto error;
1103 }
1104 }
1105 if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
1106 err = ESP_ERR_NO_MEM;
1107 goto error;
1108 } else {
1109 s_lp_stat.pm_lock_released = 1;
1110 }
1111 #endif
1112 } while (0);
1113
1114 #if CONFIG_SW_COEXIST_ENABLE
1115 coex_init();
1116 #endif
1117
1118 periph_module_enable(PERIPH_BT_MODULE);
1119
1120 esp_phy_enable();
1121 s_lp_stat.phy_enabled = 1;
1122
1123 if (btdm_controller_init(cfg) != 0) {
1124 err = ESP_ERR_NO_MEM;
1125 goto error;
1126 }
1127
1128 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1129
1130 return ESP_OK;
1131
1132 error:
1133 if (s_lp_stat.phy_enabled) {
1134 esp_phy_disable();
1135 s_lp_stat.phy_enabled = 0;
1136 }
1137
1138 do {
1139 // deinit low power control resources
1140 #ifdef CONFIG_PM_ENABLE
1141 if (s_lp_cntl.no_light_sleep) {
1142 if (s_light_sleep_pm_lock != NULL) {
1143 esp_pm_lock_delete(s_light_sleep_pm_lock);
1144 s_light_sleep_pm_lock = NULL;
1145 }
1146 }
1147 if (s_pm_lock != NULL) {
1148 esp_pm_lock_delete(s_pm_lock);
1149 s_pm_lock = NULL;
1150 s_lp_stat.pm_lock_released = 0;
1151 }
1152
1153 #endif
1154 if (s_lp_cntl.wakeup_timer_required && s_btdm_slp_tmr != NULL) {
1155 esp_timer_delete(s_btdm_slp_tmr);
1156 s_btdm_slp_tmr = NULL;
1157 }
1158
1159 #if (CONFIG_MAC_BB_PD)
1160 if (s_lp_cntl.mac_bb_pd) {
1161 btdm_deep_sleep_mem_deinit();
1162 s_lp_cntl.mac_bb_pd = 0;
1163 }
1164 #endif
1165 if (s_lp_cntl.enable) {
1166 btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
1167 if (s_wakeup_req_sem != NULL) {
1168 semphr_delete_wrapper(s_wakeup_req_sem);
1169 s_wakeup_req_sem = NULL;
1170 }
1171 }
1172 } while (0);
1173
1174 #if CONFIG_MAC_BB_PD
1175 esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb);
1176
1177 esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb);
1178 #endif
1179
1180 if (osi_funcs_p != NULL) {
1181 free(osi_funcs_p);
1182 osi_funcs_p = NULL;
1183 }
1184 return err;
1185 }
1186
esp_bt_controller_deinit(void)1187 esp_err_t esp_bt_controller_deinit(void)
1188 {
1189 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1190 return ESP_ERR_INVALID_STATE;
1191 }
1192
1193 btdm_controller_deinit();
1194 periph_module_disable(PERIPH_BT_MODULE);
1195
1196 if (s_lp_stat.phy_enabled) {
1197 esp_phy_disable();
1198 s_lp_stat.phy_enabled = 0;
1199 } else {
1200 assert(0);
1201 }
1202
1203 // deinit low power control resources
1204 do {
1205 #if (CONFIG_MAC_BB_PD)
1206 btdm_deep_sleep_mem_deinit();
1207 #endif
1208
1209 #ifdef CONFIG_PM_ENABLE
1210 if (s_lp_cntl.no_light_sleep) {
1211 esp_pm_lock_delete(s_light_sleep_pm_lock);
1212 s_light_sleep_pm_lock = NULL;
1213 }
1214
1215 esp_pm_lock_delete(s_pm_lock);
1216 s_pm_lock = NULL;
1217 s_lp_stat.pm_lock_released = 0;
1218 #endif
1219 if (s_lp_cntl.wakeup_timer_required) {
1220 if (s_lp_stat.wakeup_timer_started) {
1221 esp_timer_stop(s_btdm_slp_tmr);
1222 }
1223 s_lp_stat.wakeup_timer_started = 0;
1224 esp_timer_delete(s_btdm_slp_tmr);
1225 s_btdm_slp_tmr = NULL;
1226 }
1227
1228 if (s_lp_cntl.enable) {
1229 btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
1230
1231 semphr_delete_wrapper(s_wakeup_req_sem);
1232 s_wakeup_req_sem = NULL;
1233 }
1234 } while (0);
1235
1236 #if CONFIG_MAC_BB_PD
1237 esp_unregister_mac_bb_pd_callback(btdm_mac_bb_power_down_cb);
1238 esp_unregister_mac_bb_pu_callback(btdm_mac_bb_power_up_cb);
1239 #endif
1240
1241 /* Fix the issue caused by the power off the bt power domain.
1242 * This issue is only on ESP32C3.
1243 */
1244 phy_init_flag();
1245
1246 esp_bt_power_domain_off();
1247
1248 free(osi_funcs_p);
1249 osi_funcs_p = NULL;
1250
1251 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
1252 btdm_lpcycle_us = 0;
1253 return ESP_OK;
1254 }
1255
esp_bt_controller_enable(esp_bt_mode_t mode)1256 esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
1257 {
1258 int ret = ESP_OK;
1259
1260 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1261 return ESP_ERR_INVALID_STATE;
1262 }
1263
1264 //As the history reason, mode should be equal to the mode which set in esp_bt_controller_init()
1265 if (mode != btdm_controller_get_mode()) {
1266 ESP_LOGE(BTDM_LOG_TAG, "invalid mode %d, controller support mode is %d", mode, btdm_controller_get_mode());
1267 return ESP_ERR_INVALID_ARG;
1268 }
1269
1270 #if CONFIG_SW_COEXIST_ENABLE
1271 coex_enable();
1272 #endif
1273
1274 // enable low power mode
1275 do {
1276 #ifdef CONFIG_PM_ENABLE
1277 if (s_lp_cntl.no_light_sleep) {
1278 esp_pm_lock_acquire(s_light_sleep_pm_lock);
1279 }
1280 esp_pm_lock_acquire(s_pm_lock);
1281 s_lp_stat.pm_lock_released = 0;
1282 #endif
1283
1284 if (s_lp_cntl.enable) {
1285 btdm_controller_enable_sleep(true);
1286 }
1287 } while (0);
1288
1289 if (btdm_controller_enable(mode) != 0) {
1290 ret = ESP_ERR_INVALID_STATE;
1291 goto error;
1292 }
1293
1294 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
1295
1296 return ret;
1297
1298 error:
1299 // disable low power mode
1300 do {
1301 btdm_controller_enable_sleep(false);
1302 #ifdef CONFIG_PM_ENABLE
1303 if (s_lp_cntl.no_light_sleep) {
1304 esp_pm_lock_release(s_light_sleep_pm_lock);
1305 }
1306 if (s_lp_stat.pm_lock_released == 0) {
1307 esp_pm_lock_release(s_pm_lock);
1308 s_lp_stat.pm_lock_released = 1;
1309 }
1310 #endif
1311 } while (0);
1312
1313 return ret;
1314 }
1315
esp_bt_controller_disable(void)1316 esp_err_t esp_bt_controller_disable(void)
1317 {
1318 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1319 return ESP_ERR_INVALID_STATE;
1320 }
1321
1322 async_wakeup_request(BTDM_ASYNC_WAKEUP_SRC_DISA);
1323 while (!btdm_power_state_active()){}
1324 btdm_controller_disable();
1325
1326 async_wakeup_request_end(BTDM_ASYNC_WAKEUP_SRC_DISA);
1327
1328 #if CONFIG_SW_COEXIST_ENABLE
1329 coex_disable();
1330 #endif
1331
1332 btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1333
1334 // disable low power mode
1335 do {
1336 #ifdef CONFIG_PM_ENABLE
1337 if (s_lp_cntl.no_light_sleep) {
1338 esp_pm_lock_release(s_light_sleep_pm_lock);
1339 }
1340
1341 if (s_lp_stat.pm_lock_released == 0) {
1342 esp_pm_lock_release(s_pm_lock);
1343 s_lp_stat.pm_lock_released = 1;
1344 } else {
1345 assert(0);
1346 }
1347 #endif
1348 } while (0);
1349
1350 return ESP_OK;
1351 }
1352
esp_bt_controller_get_status(void)1353 esp_bt_controller_status_t esp_bt_controller_get_status(void)
1354 {
1355 return btdm_controller_status;
1356 }
1357
1358 /* extra functions */
esp_ble_tx_power_set(esp_ble_power_type_t power_type,esp_power_level_t power_level)1359 esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level)
1360 {
1361 esp_err_t stat = ESP_FAIL;
1362
1363 switch (power_type) {
1364 case ESP_BLE_PWR_TYPE_ADV:
1365 case ESP_BLE_PWR_TYPE_SCAN:
1366 case ESP_BLE_PWR_TYPE_DEFAULT:
1367 if (ble_txpwr_set(power_type, power_level) == 0) {
1368 stat = ESP_OK;
1369 }
1370 break;
1371 default:
1372 stat = ESP_ERR_NOT_SUPPORTED;
1373 break;
1374 }
1375
1376 return stat;
1377 }
1378
esp_ble_tx_power_get(esp_ble_power_type_t power_type)1379 esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type)
1380 {
1381 esp_power_level_t lvl;
1382
1383 switch (power_type) {
1384 case ESP_BLE_PWR_TYPE_ADV:
1385 case ESP_BLE_PWR_TYPE_SCAN:
1386 lvl = (esp_power_level_t)ble_txpwr_get(power_type);
1387 break;
1388 case ESP_BLE_PWR_TYPE_CONN_HDL0:
1389 case ESP_BLE_PWR_TYPE_CONN_HDL1:
1390 case ESP_BLE_PWR_TYPE_CONN_HDL2:
1391 case ESP_BLE_PWR_TYPE_CONN_HDL3:
1392 case ESP_BLE_PWR_TYPE_CONN_HDL4:
1393 case ESP_BLE_PWR_TYPE_CONN_HDL5:
1394 case ESP_BLE_PWR_TYPE_CONN_HDL6:
1395 case ESP_BLE_PWR_TYPE_CONN_HDL7:
1396 case ESP_BLE_PWR_TYPE_CONN_HDL8:
1397 case ESP_BLE_PWR_TYPE_DEFAULT:
1398 lvl = (esp_power_level_t)ble_txpwr_get(ESP_BLE_PWR_TYPE_DEFAULT);
1399 break;
1400 default:
1401 lvl = ESP_PWR_LVL_INVALID;
1402 break;
1403 }
1404
1405 return lvl;
1406 }
1407
esp_bt_sleep_enable(void)1408 esp_err_t esp_bt_sleep_enable (void)
1409 {
1410 esp_err_t status;
1411 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1412 return ESP_ERR_INVALID_STATE;
1413 }
1414 if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) {
1415 btdm_controller_enable_sleep (true);
1416 status = ESP_OK;
1417 } else {
1418 status = ESP_ERR_NOT_SUPPORTED;
1419 }
1420
1421 return status;
1422 }
1423
esp_bt_sleep_disable(void)1424 esp_err_t esp_bt_sleep_disable (void)
1425 {
1426 esp_err_t status;
1427 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1428 return ESP_ERR_INVALID_STATE;
1429 }
1430 if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1) {
1431 btdm_controller_enable_sleep (false);
1432 status = ESP_OK;
1433 } else {
1434 status = ESP_ERR_NOT_SUPPORTED;
1435 }
1436
1437 return status;
1438 }
1439
esp_bt_controller_is_sleeping(void)1440 bool esp_bt_controller_is_sleeping(void)
1441 {
1442 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED ||
1443 btdm_controller_get_sleep_mode() != ESP_BT_SLEEP_MODE_1) {
1444 return false;
1445 }
1446
1447 return !btdm_power_state_active();
1448 }
1449
esp_bt_controller_wakeup_request(void)1450 void esp_bt_controller_wakeup_request(void)
1451 {
1452 if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED ||
1453 btdm_controller_get_sleep_mode() != ESP_BT_SLEEP_MODE_1) {
1454 return;
1455 }
1456
1457 btdm_wakeup_request();
1458
1459 }
1460
esp_bt_h4tl_eif_io_event_notify(int event)1461 int IRAM_ATTR esp_bt_h4tl_eif_io_event_notify(int event)
1462 {
1463 return btdm_hci_tl_io_event_post(event);
1464 }
1465
esp_bt_get_tx_buf_num(void)1466 uint16_t esp_bt_get_tx_buf_num(void)
1467 {
1468 return l2c_ble_link_get_tx_buf_num();
1469 }
1470
coex_wifi_sleep_set_hook(bool sleep)1471 static void coex_wifi_sleep_set_hook(bool sleep)
1472 {
1473
1474 }
1475 #endif /* CONFIG_BT_ENABLED */
1476