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