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