1 /*
2  * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 
12 #include "sdkconfig.h"
13 #include "esp_heap_caps.h"
14 #include "esp_heap_caps_init.h"
15 #include "freertos/FreeRTOS.h"
16 #include "freertos/task.h"
17 #include "freertos/queue.h"
18 #include "freertos/semphr.h"
19 #include "freertos/xtensa_api.h"
20 #include "freertos/portmacro.h"
21 #include "xtensa/core-macros.h"
22 #include "esp_types.h"
23 #include "esp_mac.h"
24 #include "esp_random.h"
25 #include "esp_task.h"
26 #include "esp_intr_alloc.h"
27 #include "esp_attr.h"
28 #include "esp_phy_init.h"
29 #include "esp_bt.h"
30 #include "esp_err.h"
31 #include "esp_log.h"
32 #include "esp_pm.h"
33 #include "esp_private/esp_clk.h"
34 #include "esp_private/periph_ctrl.h"
35 #include "soc/rtc.h"
36 #include "soc/soc_memory_layout.h"
37 #include "soc/dport_reg.h"
38 #include "private/esp_coexist_internal.h"
39 #include "esp_timer.h"
40 #if !CONFIG_FREERTOS_UNICORE
41 #include "esp_ipc.h"
42 #endif
43 
44 #include "esp_rom_sys.h"
45 #include "hli_api.h"
46 
47 #if CONFIG_BT_ENABLED
48 
49 /* Macro definition
50  ************************************************************************
51  */
52 
53 #define UNUSED(x)                           (void)(x)
54 #define BTDM_LOG_TAG                        "BTDM_INIT"
55 
56 #define BTDM_INIT_PERIOD                    (5000)    /* ms */
57 
58 /* Bluetooth system and controller config */
59 #define BTDM_CFG_BT_DATA_RELEASE            (1<<0)
60 #define BTDM_CFG_HCI_UART                   (1<<1)
61 #define BTDM_CFG_CONTROLLER_RUN_APP_CPU     (1<<2)
62 #define BTDM_CFG_SCAN_DUPLICATE_OPTIONS     (1<<3)
63 #define BTDM_CFG_SEND_ADV_RESERVED_SIZE     (1<<4)
64 #define BTDM_CFG_BLE_FULL_SCAN_SUPPORTED    (1<<5)
65 
66 /* Sleep mode */
67 #define BTDM_MODEM_SLEEP_MODE_NONE          (0)
68 #define BTDM_MODEM_SLEEP_MODE_ORIG          (1)
69 #define BTDM_MODEM_SLEEP_MODE_EVED          (2)  // sleep mode for BLE controller, used only for internal test.
70 
71 /* Low Power Clock Selection */
72 #define BTDM_LPCLK_SEL_XTAL      (0)
73 #define BTDM_LPCLK_SEL_XTAL32K   (1)
74 #define BTDM_LPCLK_SEL_RTC_SLOW  (2)
75 #define BTDM_LPCLK_SEL_8M        (3)
76 
77 /* Sleep and wakeup interval control */
78 #define BTDM_MIN_SLEEP_DURATION          (12) // threshold of interval in slots to allow to fall into modem sleep
79 #define BTDM_MODEM_WAKE_UP_DELAY         (4)  // delay in slots of modem wake up procedure, including re-enable PHY/RF
80 
81 #define BT_DEBUG(...)
82 #define BT_API_CALL_CHECK(info, api_call, ret) \
83 do{\
84     esp_err_t __err = (api_call);\
85     if ((ret) != __err) {\
86         BT_DEBUG("%s %d %s ret=0x%X\n", __FUNCTION__, __LINE__, (info), __err);\
87         return __err;\
88     }\
89 } while(0)
90 
91 #define OSI_FUNCS_TIME_BLOCKING  0xffffffff
92 #define OSI_VERSION              0x00010005
93 #define OSI_MAGIC_VALUE          0xFADEBEAD
94 
95 #define BLE_CONTROLLER_MALLOC_CAPS        (MALLOC_CAP_8BIT|MALLOC_CAP_DMA|MALLOC_CAP_INTERNAL)
96 /* Types definition
97  ************************************************************************
98  */
99 
100 /* VHCI function interface */
101 typedef struct vhci_host_callback {
102     void (*notify_host_send_available)(void);               /*!< callback used to notify that the host can send packet to controller */
103     int (*notify_host_recv)(uint8_t *data, uint16_t len);   /*!< callback used to notify that the controller has a packet to send to the host*/
104 } vhci_host_callback_t;
105 
106 /* Dram region */
107 typedef struct {
108     esp_bt_mode_t mode;
109     intptr_t start;
110     intptr_t end;
111 } btdm_dram_available_region_t;
112 
113 typedef struct {
114     void *handle;
115 } btdm_queue_item_t;
116 
117 /* OSI function */
118 struct osi_funcs_t {
119     uint32_t _version;
120     xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
121     void (*_ints_on)(unsigned int mask);
122     void (*_interrupt_disable)(void);
123     void (*_interrupt_restore)(void);
124     void (*_task_yield)(void);
125     void (*_task_yield_from_isr)(void);
126     void *(*_semphr_create)(uint32_t max, uint32_t init);
127     void (*_semphr_delete)(void *semphr);
128     int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw);
129     int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);
130     int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);
131     int32_t (*_semphr_give)(void *semphr);
132     void *(*_mutex_create)(void);
133     void (*_mutex_delete)(void *mutex);
134     int32_t (*_mutex_lock)(void *mutex);
135     int32_t (*_mutex_unlock)(void *mutex);
136     void *(* _queue_create)(uint32_t queue_len, uint32_t item_size);
137     void (* _queue_delete)(void *queue);
138     int32_t (* _queue_send)(void *queue, void *item, uint32_t block_time_ms);
139     int32_t (* _queue_send_from_isr)(void *queue, void *item, void *hptw);
140     int32_t (* _queue_recv)(void *queue, void *item, uint32_t block_time_ms);
141     int32_t (* _queue_recv_from_isr)(void *queue, void *item, void *hptw);
142     int32_t (* _task_create)(void *task_func, const char *name, uint32_t stack_depth, void *param, uint32_t prio, void *task_handle, uint32_t core_id);
143     void (* _task_delete)(void *task_handle);
144     bool (* _is_in_isr)(void);
145     int (* _cause_sw_intr_to_core)(int core_id, int intr_no);
146     void *(* _malloc)(size_t size);
147     void *(* _malloc_internal)(size_t size);
148     void (* _free)(void *p);
149     int32_t (* _read_efuse_mac)(uint8_t mac[6]);
150     void (* _srand)(unsigned int seed);
151     int (* _rand)(void);
152     uint32_t (* _btdm_lpcycles_2_us)(uint32_t cycles);
153     uint32_t (* _btdm_us_2_lpcycles)(uint32_t us);
154     bool (* _btdm_sleep_check_duration)(uint32_t *slot_cnt);
155     void (* _btdm_sleep_enter_phase1)(uint32_t lpcycles);  /* called when interrupt is disabled */
156     void (* _btdm_sleep_enter_phase2)(void);
157     void (* _btdm_sleep_exit_phase1)(void);  /* called from ISR */
158     void (* _btdm_sleep_exit_phase2)(void);  /* called from ISR */
159     void (* _btdm_sleep_exit_phase3)(void);  /* called from task */
160     bool (* _coex_bt_wakeup_request)(void);
161     void (* _coex_bt_wakeup_request_end)(void);
162     int (* _coex_bt_request)(uint32_t event, uint32_t latency, uint32_t duration);
163     int (* _coex_bt_release)(uint32_t event);
164     int (* _coex_register_bt_cb)(coex_func_cb_t cb);
165     uint32_t (* _coex_bb_reset_lock)(void);
166     void (* _coex_bb_reset_unlock)(uint32_t restore);
167     int (* _coex_schm_register_btdm_callback)(void *callback);
168     void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
169     void (* _coex_schm_status_bit_set)(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 (* _coex_wifi_channel_get)(uint8_t *primary, uint8_t *secondary);
174     int (* _coex_register_wifi_channel_change_callback)(void *cb);
175     xt_handler (*_set_isr_l3)(int n, xt_handler f, void *arg);
176     void (*_interrupt_l3_disable)(void);
177     void (*_interrupt_l3_restore)(void);
178     void *(* _customer_queue_create)(uint32_t queue_len, uint32_t item_size);
179     int (* _coex_version_get)(unsigned int *major, unsigned int *minor, unsigned int *patch);
180     void (* _patch_apply)(void);
181     uint32_t _magic;
182 };
183 
184 typedef void (*workitem_handler_t)(void* arg);
185 
186 /* External functions or values
187  ************************************************************************
188  */
189 
190 /* not for user call, so don't put to include file */
191 /* OSI */
192 extern int btdm_osi_funcs_register(void *osi_funcs);
193 /* Initialise and De-initialise */
194 extern int btdm_controller_init(uint32_t config_mask, esp_bt_controller_config_t *config_opts);
195 extern void btdm_controller_deinit(void);
196 extern int btdm_controller_enable(esp_bt_mode_t mode);
197 extern void btdm_controller_disable(void);
198 extern uint8_t btdm_controller_get_mode(void);
199 extern const char *btdm_controller_get_compile_version(void);
200 extern void btdm_rf_bb_init_phase2(void); // shall be called after PHY/RF is enabled
201 extern int btdm_dispatch_work_to_controller(workitem_handler_t callback, void *arg, bool blocking);
202 /* Sleep */
203 extern void btdm_controller_enable_sleep(bool enable);
204 extern void btdm_controller_set_sleep_mode(uint8_t mode);
205 extern uint8_t btdm_controller_get_sleep_mode(void);
206 extern bool btdm_power_state_active(void);
207 extern void btdm_wakeup_request(void);
208 extern void btdm_in_wakeup_requesting_set(bool in_wakeup_requesting);
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 /* VHCI */
213 extern bool API_vhci_host_check_send_available(void);
214 extern void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
215 extern int API_vhci_host_register_callback(const vhci_host_callback_t *callback);
216 /* TX power */
217 extern int ble_txpwr_set(int power_type, int power_level);
218 extern int ble_txpwr_get(int power_type);
219 extern int bredr_txpwr_set(int min_power_level, int max_power_level);
220 extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
221 extern void bredr_sco_datapath_set(uint8_t data_path);
222 extern void btdm_controller_scan_duplicate_list_clear(void);
223 /* Shutdown */
224 extern void esp_bt_controller_shutdown(void);
225 extern void sdk_config_set_bt_pll_track_enable(bool enable);
226 extern void sdk_config_set_uart_flow_ctrl_enable(bool enable);
227 
228 extern char _bss_start_btdm;
229 extern char _bss_end_btdm;
230 extern char _data_start_btdm;
231 extern char _data_end_btdm;
232 extern uint32_t _data_start_btdm_rom;
233 extern uint32_t _data_end_btdm_rom;
234 
235 extern uint32_t _bt_bss_start;
236 extern uint32_t _bt_bss_end;
237 extern uint32_t _bt_controller_bss_start;
238 extern uint32_t _bt_controller_bss_end;
239 extern uint32_t _bt_data_start;
240 extern uint32_t _bt_data_end;
241 extern uint32_t _bt_controller_data_start;
242 extern uint32_t _bt_controller_data_end;
243 
244 extern void config_bt_funcs_reset(void);
245 extern void config_ble_funcs_reset(void);
246 extern void config_btdm_funcs_reset(void);
247 extern void config_ble_vs_qa_funcs_reset(void);
248 
249 /* Local Function Declare
250  *********************************************************************
251  */
252 #if CONFIG_BTDM_CTRL_HLI
253 static xt_handler set_isr_hlevel_wrapper(int n, xt_handler f, void *arg);
254 static void interrupt_hlevel_disable(void);
255 static void interrupt_hlevel_restore(void);
256 #endif /* CONFIG_BTDM_CTRL_HLI */
257 static void task_yield(void);
258 static void task_yield_from_isr(void);
259 static void *semphr_create_wrapper(uint32_t max, uint32_t init);
260 static void semphr_delete_wrapper(void *semphr);
261 static int32_t semphr_take_from_isr_wrapper(void *semphr, void *hptw);
262 static int32_t semphr_give_from_isr_wrapper(void *semphr, void *hptw);
263 static int32_t  semphr_take_wrapper(void *semphr, uint32_t block_time_ms);
264 static int32_t  semphr_give_wrapper(void *semphr);
265 static void *mutex_create_wrapper(void);
266 static void mutex_delete_wrapper(void *mutex);
267 static int32_t mutex_lock_wrapper(void *mutex);
268 static int32_t mutex_unlock_wrapper(void *mutex);
269 #if CONFIG_BTDM_CTRL_HLI
270 static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
271 static void queue_delete_hlevel_wrapper(void *queue);
272 static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
273 static int32_t queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
274 static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms);
275 static int32_t queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw);
276 #else
277 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
278 static void queue_delete_wrapper(void *queue);
279 static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms);
280 static int32_t queue_send_from_isr_wrapper(void *queue, void *item, void *hptw);
281 static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms);
282 static int32_t queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw);
283 #endif /* CONFIG_BTDM_CTRL_HLI */
284 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);
285 static void task_delete_wrapper(void *task_handle);
286 static bool is_in_isr_wrapper(void);
287 static void cause_sw_intr(void *arg);
288 static int cause_sw_intr_to_core_wrapper(int core_id, int intr_no);
289 static void *malloc_internal_wrapper(size_t size);
290 static int32_t read_mac_wrapper(uint8_t mac[6]);
291 static void srand_wrapper(unsigned int seed);
292 static int rand_wrapper(void);
293 static uint32_t btdm_lpcycles_2_us(uint32_t cycles);
294 static uint32_t btdm_us_2_lpcycles(uint32_t us);
295 static bool btdm_sleep_check_duration(uint32_t *slot_cnt);
296 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
297 static void btdm_sleep_enter_phase2_wrapper(void);
298 static void btdm_sleep_exit_phase3_wrapper(void);
299 static bool coex_bt_wakeup_request(void);
300 static void coex_bt_wakeup_request_end(void);
301 static int coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration);
302 static int coex_bt_release_wrapper(uint32_t event);
303 static int coex_register_bt_cb_wrapper(coex_func_cb_t cb);
304 static uint32_t coex_bb_reset_lock_wrapper(void);
305 static void coex_bb_reset_unlock_wrapper(uint32_t restore);
306 static int coex_schm_register_btdm_callback_wrapper(void *callback);
307 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
308 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
309 static uint32_t coex_schm_interval_get_wrapper(void);
310 static uint8_t coex_schm_curr_period_get_wrapper(void);
311 static void * coex_schm_curr_phase_get_wrapper(void);
312 static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary);
313 static int coex_register_wifi_channel_change_callback_wrapper(void *cb);
314 static int coex_version_get_wrapper(unsigned int *major, unsigned int *minor, unsigned int *patch);
315 #if CONFIG_BTDM_CTRL_HLI
316 static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size);
317 #endif /* CONFIG_BTDM_CTRL_HLI */
318 static void interrupt_l3_disable(void);
319 static void interrupt_l3_restore(void);
320 static void bt_controller_deinit_internal(void);
321 static void patch_apply(void);
322 
323 /* Local variable definition
324  ***************************************************************************
325  */
326 /* OSI funcs */
327 static const struct osi_funcs_t osi_funcs_ro = {
328     ._version = OSI_VERSION,
329 #if CONFIG_BTDM_CTRL_HLI
330     ._set_isr = set_isr_hlevel_wrapper,
331     ._ints_on = xt_ints_on,
332     ._interrupt_disable = interrupt_hlevel_disable,
333     ._interrupt_restore = interrupt_hlevel_restore,
334 #else
335     ._set_isr = xt_set_interrupt_handler,
336     ._ints_on = xt_ints_on,
337     ._interrupt_disable = interrupt_l3_disable,
338     ._interrupt_restore = interrupt_l3_restore,
339 #endif /* CONFIG_BTDM_CTRL_HLI */
340     ._task_yield = task_yield,
341     ._task_yield_from_isr = task_yield_from_isr,
342     ._semphr_create = semphr_create_wrapper,
343     ._semphr_delete = semphr_delete_wrapper,
344     ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
345     ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
346     ._semphr_take = semphr_take_wrapper,
347     ._semphr_give = semphr_give_wrapper,
348     ._mutex_create = mutex_create_wrapper,
349     ._mutex_delete = mutex_delete_wrapper,
350     ._mutex_lock = mutex_lock_wrapper,
351     ._mutex_unlock = mutex_unlock_wrapper,
352 #if CONFIG_BTDM_CTRL_HLI
353     ._queue_create = queue_create_hlevel_wrapper,
354     ._queue_delete = queue_delete_hlevel_wrapper,
355     ._queue_send = queue_send_hlevel_wrapper,
356     ._queue_send_from_isr = queue_send_from_isr_hlevel_wrapper,
357     ._queue_recv = queue_recv_hlevel_wrapper,
358     ._queue_recv_from_isr = queue_recv_from_isr_hlevel_wrapper,
359 #else
360     ._queue_create = queue_create_wrapper,
361     ._queue_delete = queue_delete_wrapper,
362     ._queue_send = queue_send_wrapper,
363     ._queue_send_from_isr = queue_send_from_isr_wrapper,
364     ._queue_recv = queue_recv_wrapper,
365     ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
366 #endif /* CONFIG_BTDM_CTRL_HLI */
367     ._task_create = task_create_wrapper,
368     ._task_delete = task_delete_wrapper,
369     ._is_in_isr = is_in_isr_wrapper,
370     ._cause_sw_intr_to_core = cause_sw_intr_to_core_wrapper,
371     ._malloc = malloc,
372     ._malloc_internal = malloc_internal_wrapper,
373     ._free = free,
374     ._read_efuse_mac = read_mac_wrapper,
375     ._srand = srand_wrapper,
376     ._rand = rand_wrapper,
377     ._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
378     ._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
379     ._btdm_sleep_check_duration = btdm_sleep_check_duration,
380     ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
381     ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
382     ._btdm_sleep_exit_phase1 = NULL,
383     ._btdm_sleep_exit_phase2 = NULL,
384     ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
385     ._coex_bt_wakeup_request = coex_bt_wakeup_request,
386     ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end,
387     ._coex_bt_request = coex_bt_request_wrapper,
388     ._coex_bt_release = coex_bt_release_wrapper,
389     ._coex_register_bt_cb = coex_register_bt_cb_wrapper,
390     ._coex_bb_reset_lock = coex_bb_reset_lock_wrapper,
391     ._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper,
392     ._coex_schm_register_btdm_callback = coex_schm_register_btdm_callback_wrapper,
393     ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
394     ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
395     ._coex_schm_interval_get = coex_schm_interval_get_wrapper,
396     ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
397     ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
398     ._coex_wifi_channel_get = coex_wifi_channel_get_wrapper,
399     ._coex_register_wifi_channel_change_callback = coex_register_wifi_channel_change_callback_wrapper,
400     ._set_isr_l3 = xt_set_interrupt_handler,
401     ._interrupt_l3_disable = interrupt_l3_disable,
402     ._interrupt_l3_restore = interrupt_l3_restore,
403 #if CONFIG_BTDM_CTRL_HLI
404     ._customer_queue_create = customer_queue_create_hlevel_wrapper,
405 #else
406     ._customer_queue_create = NULL,
407 #endif /* CONFIG_BTDM_CTRL_HLI */
408     ._coex_version_get = coex_version_get_wrapper,
409     ._patch_apply = patch_apply,
410     ._magic = OSI_MAGIC_VALUE,
411 };
412 
413 /* the mode column will be modified by release function to indicate the available region */
414 static btdm_dram_available_region_t btdm_dram_available_region[] = {
415     //following is .data
416     {ESP_BT_MODE_BTDM,          SOC_MEM_BT_DATA_START,      SOC_MEM_BT_DATA_END         },
417     //following is memory which HW will use
418     {ESP_BT_MODE_BTDM,          SOC_MEM_BT_EM_BTDM0_START,  SOC_MEM_BT_EM_BTDM0_END     },
419     {ESP_BT_MODE_BLE,           SOC_MEM_BT_EM_BLE_START,    SOC_MEM_BT_EM_BLE_END      },
420     {ESP_BT_MODE_BTDM,          SOC_MEM_BT_EM_BTDM1_START,  SOC_MEM_BT_EM_BTDM1_END     },
421     {ESP_BT_MODE_CLASSIC_BT,    SOC_MEM_BT_EM_BREDR_START,  SOC_MEM_BT_EM_BREDR_REAL_END},
422     //following is .bss
423     {ESP_BT_MODE_BTDM,          SOC_MEM_BT_BSS_START,       SOC_MEM_BT_BSS_END          },
424     {ESP_BT_MODE_BTDM,          SOC_MEM_BT_MISC_START,      SOC_MEM_BT_MISC_END         },
425 };
426 
427 /* Reserve the full memory region used by Bluetooth Controller,
428  *    some may be released later at runtime. */
429 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_EM_START,   SOC_MEM_BT_EM_BREDR_REAL_END,  rom_bt_em);
430 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_BSS_START,  SOC_MEM_BT_BSS_END,            rom_bt_bss);
431 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_MISC_START, SOC_MEM_BT_MISC_END,           rom_bt_misc);
432 SOC_RESERVE_MEMORY_REGION(SOC_MEM_BT_DATA_START, SOC_MEM_BT_DATA_END,           rom_bt_data);
433 
434 static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
435 
436 /* Static variable declare */
437 // timestamp when PHY/RF was switched on
438 static DRAM_ATTR int64_t s_time_phy_rf_just_enabled = 0;
439 static DRAM_ATTR esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
440 
441 static DRAM_ATTR portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
442 
443 // measured average low power clock period in micro seconds
444 static DRAM_ATTR uint32_t btdm_lpcycle_us = 0;
445 static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0; // number of fractional bit for btdm_lpcycle_us
446 
447 #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
448 // used low power clock
449 static DRAM_ATTR uint8_t btdm_lpclk_sel;
450 #endif /* #ifdef CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG */
451 
452 static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
453 #ifdef CONFIG_PM_ENABLE
454 static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
455 static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
456 static bool s_pm_lock_acquired = true;
457 static DRAM_ATTR bool s_btdm_allow_light_sleep;
458 // pm_lock to prevent light sleep when using main crystal as Bluetooth low power clock
459 static DRAM_ATTR esp_pm_lock_handle_t s_light_sleep_pm_lock;
460 static void btdm_slp_tmr_callback(void *arg);
461 #endif /* #ifdef CONFIG_PM_ENABLE */
462 
463 
esp_bt_power_domain_on(void)464 static inline void esp_bt_power_domain_on(void)
465 {
466     // Bluetooth module power up
467     esp_wifi_bt_power_domain_on();
468 }
469 
esp_bt_power_domain_off(void)470 static inline void esp_bt_power_domain_off(void)
471 {
472     // Bluetooth module power down
473     esp_wifi_bt_power_domain_off();
474 }
475 
btdm_check_and_init_bb(void)476 static inline void btdm_check_and_init_bb(void)
477 {
478     /* init BT-BB if PHY/RF has been switched off since last BT-BB init */
479     int64_t latest_ts = esp_phy_rf_get_on_ts();
480     if (latest_ts != s_time_phy_rf_just_enabled ||
481         s_time_phy_rf_just_enabled == 0) {
482         btdm_rf_bb_init_phase2();
483         s_time_phy_rf_just_enabled = latest_ts;
484     }
485 }
486 
487 #if CONFIG_BTDM_CTRL_HLI
488 struct interrupt_hlevel_cb{
489     uint32_t status;
490     uint8_t nested;
491 };
492 
493 static DRAM_ATTR struct interrupt_hlevel_cb hli_cb = {
494     .status = 0,
495     .nested = 0,
496 };
497 
set_isr_hlevel_wrapper(int mask,xt_handler f,void * arg)498 static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg)
499 {
500     esp_err_t err = hli_intr_register((intr_handler_t) f, arg, DPORT_PRO_INTR_STATUS_0_REG, mask);
501     if (err == ESP_OK) {
502         return f;
503     } else {
504         return 0;
505     }
506  }
507 
interrupt_hlevel_disable(void)508 static void IRAM_ATTR interrupt_hlevel_disable(void)
509 {
510     assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
511     assert(hli_cb.nested != UCHAR_MAX);
512     uint32_t status = hli_intr_disable();
513     if (hli_cb.nested++ == 0) {
514         hli_cb.status = status;
515     }
516 }
517 
interrupt_hlevel_restore(void)518 static void IRAM_ATTR interrupt_hlevel_restore(void)
519 {
520     assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
521     assert(hli_cb.nested > 0);
522     if (--hli_cb.nested == 0) {
523         hli_intr_restore(hli_cb.status);
524     }
525 }
526 #endif /* CONFIG_BTDM_CTRL_HLI */
527 
interrupt_l3_disable(void)528 static void IRAM_ATTR interrupt_l3_disable(void)
529 {
530     if (xPortInIsrContext()) {
531         portENTER_CRITICAL_ISR(&global_int_mux);
532     } else {
533         portENTER_CRITICAL(&global_int_mux);
534     }
535 }
536 
interrupt_l3_restore(void)537 static void IRAM_ATTR interrupt_l3_restore(void)
538 {
539     if (xPortInIsrContext()) {
540         portEXIT_CRITICAL_ISR(&global_int_mux);
541     } else {
542         portEXIT_CRITICAL(&global_int_mux);
543     }
544 }
545 
task_yield(void)546 static void IRAM_ATTR task_yield(void)
547 {
548     vPortYield();
549 }
550 
551 
task_yield_from_isr(void)552 static void IRAM_ATTR task_yield_from_isr(void)
553 {
554     portYIELD_FROM_ISR();
555 }
556 
semphr_create_wrapper(uint32_t max,uint32_t init)557 static void *semphr_create_wrapper(uint32_t max, uint32_t init)
558 {
559     btdm_queue_item_t *semphr = heap_caps_calloc(1, sizeof(btdm_queue_item_t), MALLOC_CAP_8BIT|MALLOC_CAP_INTERNAL);
560     assert(semphr);
561 
562     void *handle = NULL;
563 
564     /* IDF FreeRTOS guarantees that all dynamic memory allocation goes to internal RAM. */
565     handle = (void *)xSemaphoreCreateCounting(max, init);
566     assert(handle);
567 
568 #if CONFIG_BTDM_CTRL_HLI
569     SemaphoreHandle_t downstream_semaphore = handle;
570     assert(downstream_semaphore);
571     hli_queue_handle_t s_semaphore = hli_semaphore_create(max, downstream_semaphore);
572     assert(s_semaphore);
573     semphr->handle = (void *)s_semaphore;
574 #else
575     semphr->handle =  handle;
576 #endif /* CONFIG_BTDM_CTRL_HLI */
577 
578     return semphr;
579 }
580 
semphr_delete_wrapper(void * semphr)581 static void semphr_delete_wrapper(void *semphr)
582 {
583     if (semphr == NULL) {
584         return;
585     }
586 
587     btdm_queue_item_t *semphr_item = (btdm_queue_item_t *)semphr;
588     void *handle = NULL;
589 #if CONFIG_BTDM_CTRL_HLI
590     if (semphr_item->handle) {
591         handle = ((hli_queue_handle_t)(semphr_item->handle))->downstream;
592         hli_queue_delete((hli_queue_handle_t)(semphr_item->handle));
593     }
594 #else
595     handle = semphr_item->handle;
596 #endif /* CONFIG_BTDM_CTRL_HLI */
597 
598     if (handle) {
599         vSemaphoreDelete(handle);
600     }
601 
602     free(semphr);
603 }
604 
semphr_take_from_isr_wrapper(void * semphr,void * hptw)605 static int32_t IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
606 {
607 #if CONFIG_BTDM_CTRL_HLI
608     // Not support it
609     assert(0);
610     return 0;
611 #else
612     void *handle = ((btdm_queue_item_t *)semphr)->handle;
613     return (int32_t)xSemaphoreTakeFromISR(handle, hptw);
614 #endif /* CONFIG_BTDM_CTRL_HLI */
615 }
616 
semphr_give_from_isr_wrapper(void * semphr,void * hptw)617 static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
618 {
619     void *handle = ((btdm_queue_item_t *)semphr)->handle;
620 #if CONFIG_BTDM_CTRL_HLI
621     UNUSED(hptw);
622     assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
623     return hli_semaphore_give(handle);
624 #else
625     return (int32_t)xSemaphoreGiveFromISR(handle, hptw);
626 #endif /* CONFIG_BTDM_CTRL_HLI */
627 }
628 
semphr_take_wrapper(void * semphr,uint32_t block_time_ms)629 static int32_t semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
630 {
631     bool ret;
632     void *handle = ((btdm_queue_item_t *)semphr)->handle;
633 #if CONFIG_BTDM_CTRL_HLI
634     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
635         ret = xSemaphoreTake(((hli_queue_handle_t)handle)->downstream, portMAX_DELAY);
636     } else {
637         ret = xSemaphoreTake(((hli_queue_handle_t)handle)->downstream, block_time_ms / portTICK_PERIOD_MS);
638     }
639 #else
640     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
641         ret = xSemaphoreTake(handle, portMAX_DELAY);
642     } else {
643         ret = xSemaphoreTake(handle, block_time_ms / portTICK_PERIOD_MS);
644     }
645 #endif /* CONFIG_BTDM_CTRL_HLI */
646     return (int32_t)ret;
647 }
648 
semphr_give_wrapper(void * semphr)649 static int32_t semphr_give_wrapper(void *semphr)
650 {
651     void *handle = ((btdm_queue_item_t *)semphr)->handle;
652 #if CONFIG_BTDM_CTRL_HLI
653     return (int32_t)xSemaphoreGive(((hli_queue_handle_t)handle)->downstream);
654 #else
655     return (int32_t)xSemaphoreGive(handle);
656 #endif /* CONFIG_BTDM_CTRL_HLI */
657 }
658 
mutex_create_wrapper(void)659 static void *mutex_create_wrapper(void)
660 {
661     return (void *)xSemaphoreCreateMutex();
662 }
663 
mutex_delete_wrapper(void * mutex)664 static void mutex_delete_wrapper(void *mutex)
665 {
666     vSemaphoreDelete(mutex);
667 }
668 
mutex_lock_wrapper(void * mutex)669 static int32_t mutex_lock_wrapper(void *mutex)
670 {
671     return (int32_t)xSemaphoreTake(mutex, portMAX_DELAY);
672 }
673 
mutex_unlock_wrapper(void * mutex)674 static int32_t mutex_unlock_wrapper(void *mutex)
675 {
676     return (int32_t)xSemaphoreGive(mutex);
677 }
678 
queue_create_wrapper(uint32_t queue_len,uint32_t item_size)679 static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
680 {
681     btdm_queue_item_t *queue = NULL;
682 
683     queue = (btdm_queue_item_t*)heap_caps_malloc(sizeof(btdm_queue_item_t), MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
684     assert(queue);
685 
686     /* IDF FreeRTOS guarantees that all dynamic memory allocation goes to internal RAM. */
687     queue->handle = xQueueCreate( queue_len, item_size);
688     assert(queue->handle);
689 
690     return queue;
691 }
692 
queue_delete_wrapper(void * queue)693 static void queue_delete_wrapper(void *queue)
694 {
695     btdm_queue_item_t *queue_item = (btdm_queue_item_t *)queue;
696     if (queue_item) {
697         if(queue_item->handle){
698             vQueueDelete(queue_item->handle);
699         }
700         free(queue_item);
701     }
702 }
703 
704 #if CONFIG_BTDM_CTRL_HLI
queue_create_hlevel_wrapper(uint32_t queue_len,uint32_t item_size)705 static void *queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
706 {
707     btdm_queue_item_t *queue_item = queue_create_wrapper(queue_len, item_size);
708     assert(queue_item);
709     QueueHandle_t downstream_queue = queue_item->handle;
710     assert(queue_item->handle);
711     hli_queue_handle_t queue = hli_queue_create(queue_len, item_size, downstream_queue);
712     assert(queue);
713     queue_item->handle = queue;
714     return (void *)queue_item;
715 }
716 
customer_queue_create_hlevel_wrapper(uint32_t queue_len,uint32_t item_size)717 static void *customer_queue_create_hlevel_wrapper(uint32_t queue_len, uint32_t item_size)
718 {
719     btdm_queue_item_t *queue_item = queue_create_wrapper(queue_len, item_size);
720     assert(queue_item);
721     QueueHandle_t downstream_queue = queue_item->handle;
722     assert(queue_item->handle);
723     hli_queue_handle_t queue = hli_customer_queue_create(queue_len, item_size, downstream_queue);
724     assert(queue);
725     queue_item->handle = queue;
726     return (void *)queue_item;
727 }
728 
queue_delete_hlevel_wrapper(void * queue)729 static void queue_delete_hlevel_wrapper(void *queue)
730 {
731     if (queue == NULL) {
732         return;
733     }
734 
735     btdm_queue_item_t *queue_item = (btdm_queue_item_t *)queue;
736 
737     if (queue_item->handle) {
738         void *handle = ((hli_queue_handle_t)(queue_item->handle))->downstream;
739         hli_queue_delete(queue_item->handle);
740         queue_item->handle = handle;
741         queue_delete_wrapper(queue_item);
742     }
743 }
744 
queue_send_hlevel_wrapper(void * queue,void * item,uint32_t block_time_ms)745 static int32_t queue_send_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
746 {
747     void *handle = ((btdm_queue_item_t *)queue)->handle;
748     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
749         return (int32_t)xQueueSend(((hli_queue_handle_t)handle)->downstream, item, portMAX_DELAY);
750     } else {
751         return (int32_t)xQueueSend(((hli_queue_handle_t)handle)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
752     }
753 }
754 
755 /**
756  * Queue send from isr
757  * @param  queue The queue which will send to
758  * @param  item  The message which will be send
759  * @param  hptw  need do task yield or not
760  * @return       send success or not
761  *               There is an issue here:  When the queue is full, it may return true but it send fail to the queue, sometimes.
762  *               But in Bluetooth controller's isr, We don't care about the return value.
763  *               It only required tp send success when the queue is empty all the time.
764  *               So, this function meets the requirement.
765  */
queue_send_from_isr_hlevel_wrapper(void * queue,void * item,void * hptw)766 static int32_t IRAM_ATTR queue_send_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
767 {
768     UNUSED(hptw);
769     assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
770     void *handle = ((btdm_queue_item_t *)queue)->handle;
771     return hli_queue_put(handle, item);
772 }
773 
queue_recv_hlevel_wrapper(void * queue,void * item,uint32_t block_time_ms)774 static int32_t queue_recv_hlevel_wrapper(void *queue, void *item, uint32_t block_time_ms)
775 {
776     bool ret;
777     void *handle = ((btdm_queue_item_t *)queue)->handle;
778     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
779         ret = xQueueReceive(((hli_queue_handle_t)handle)->downstream, item, portMAX_DELAY);
780     } else {
781         ret = xQueueReceive(((hli_queue_handle_t)handle)->downstream, item, block_time_ms / portTICK_PERIOD_MS);
782     }
783 
784     return (int32_t)ret;
785 }
786 
queue_recv_from_isr_hlevel_wrapper(void * queue,void * item,void * hptw)787 static int32_t IRAM_ATTR queue_recv_from_isr_hlevel_wrapper(void *queue, void *item, void *hptw)
788 {
789     // Not support it
790     assert(0);
791     return 0;
792 }
793 
794 #else
795 
queue_send_wrapper(void * queue,void * item,uint32_t block_time_ms)796 static int32_t queue_send_wrapper(void *queue, void *item, uint32_t block_time_ms)
797 {
798     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
799         return (int32_t)xQueueSend(((btdm_queue_item_t*)queue)->handle, item, portMAX_DELAY);
800     } else {
801         return (int32_t)xQueueSend(((btdm_queue_item_t*)queue)->handle, item, block_time_ms / portTICK_PERIOD_MS);
802     }
803 }
804 
queue_send_from_isr_wrapper(void * queue,void * item,void * hptw)805 static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item, void *hptw)
806 {
807     return (int32_t)xQueueSendFromISR(((btdm_queue_item_t*)queue)->handle, item, hptw);
808 }
809 
queue_recv_wrapper(void * queue,void * item,uint32_t block_time_ms)810 static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t block_time_ms)
811  {
812     bool ret;
813     if (block_time_ms == OSI_FUNCS_TIME_BLOCKING) {
814         ret = xQueueReceive(((btdm_queue_item_t*)queue)->handle, item, portMAX_DELAY);
815     } else {
816         ret = xQueueReceive(((btdm_queue_item_t*)queue)->handle, item, block_time_ms / portTICK_PERIOD_MS);
817     }
818 
819     return (int32_t)ret;
820  }
821 
queue_recv_from_isr_wrapper(void * queue,void * item,void * hptw)822 static int32_t IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item, void *hptw)
823 {
824     return (int32_t)xQueueReceiveFromISR(((btdm_queue_item_t*)queue)->handle, item, hptw);
825 }
826 #endif /* CONFIG_BTDM_CTRL_HLI */
827 
828 
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)829 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)
830 {
831     return (uint32_t)xTaskCreatePinnedToCore(task_func, name, stack_depth, param, prio, task_handle, (core_id < portNUM_PROCESSORS ? core_id : tskNO_AFFINITY));
832 }
833 
task_delete_wrapper(void * task_handle)834 static void task_delete_wrapper(void *task_handle)
835 {
836     vTaskDelete(task_handle);
837 }
838 
is_in_isr_wrapper(void)839 static bool IRAM_ATTR is_in_isr_wrapper(void)
840 {
841     return !xPortCanYield();
842 }
843 
cause_sw_intr(void * arg)844 static void IRAM_ATTR cause_sw_intr(void *arg)
845 {
846     /* just convert void * to int, because the width is the same */
847     uint32_t intr_no = (uint32_t)arg;
848     XTHAL_SET_INTSET((1<<intr_no));
849 }
850 
cause_sw_intr_to_core_wrapper(int core_id,int intr_no)851 static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no)
852 {
853     esp_err_t err = ESP_OK;
854 
855 #if CONFIG_FREERTOS_UNICORE
856     cause_sw_intr((void *)intr_no);
857 #else /* CONFIG_FREERTOS_UNICORE */
858     if (xPortGetCoreID() == core_id) {
859         cause_sw_intr((void *)intr_no);
860     } else {
861         err = esp_ipc_call(core_id, cause_sw_intr, (void *)intr_no);
862     }
863 #endif /* !CONFIG_FREERTOS_UNICORE */
864     return err;
865 }
866 
malloc_internal_wrapper(size_t size)867 static void *malloc_internal_wrapper(size_t size)
868 {
869     return heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS);
870 }
871 
malloc_ble_controller_mem(size_t size)872 void *malloc_ble_controller_mem(size_t size)
873 {
874     void *p = heap_caps_malloc(size, BLE_CONTROLLER_MALLOC_CAPS);
875     if(p == NULL) {
876         ESP_LOGE(BTDM_LOG_TAG, "Malloc failed");
877     }
878     return p;
879 }
880 
get_ble_controller_free_heap_size(void)881 uint32_t get_ble_controller_free_heap_size(void)
882 {
883     return heap_caps_get_free_size(BLE_CONTROLLER_MALLOC_CAPS);
884 }
885 
read_mac_wrapper(uint8_t mac[6])886 static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
887 {
888     int ret = esp_read_mac(mac, ESP_MAC_BT);
889     ESP_LOGI(BTDM_LOG_TAG, "Bluetooth MAC: %02x:%02x:%02x:%02x:%02x:%02x",
890                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
891 
892     return ret;
893 }
894 
srand_wrapper(unsigned int seed)895 static void IRAM_ATTR srand_wrapper(unsigned int seed)
896 {
897     /* empty function */
898 }
899 
rand_wrapper(void)900 static int IRAM_ATTR rand_wrapper(void)
901 {
902     return (int)esp_random();
903 }
904 
btdm_lpcycles_2_us(uint32_t cycles)905 static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
906 {
907     // The number of lp cycles should not lead to overflow. Thrs: 100s
908     // clock measurement is conducted
909     uint64_t us = (uint64_t)btdm_lpcycle_us * cycles;
910     us = (us + (1 << (btdm_lpcycle_us_frac - 1))) >> btdm_lpcycle_us_frac;
911     return (uint32_t)us;
912 }
913 
914 /*
915  * @brief Converts a duration in slots into a number of low power clock cycles.
916  */
btdm_us_2_lpcycles(uint32_t us)917 static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us)
918 {
919     // The number of sleep duration(us) should not lead to overflow. Thrs: 100s
920     // Compute the sleep duration in us to low power clock cycles, with calibration result applied
921     // clock measurement is conducted
922     uint64_t cycles = ((uint64_t)(us) << btdm_lpcycle_us_frac) / btdm_lpcycle_us;
923 
924     return (uint32_t)cycles;
925 }
926 
btdm_sleep_check_duration(uint32_t * slot_cnt)927 static bool IRAM_ATTR btdm_sleep_check_duration(uint32_t *slot_cnt)
928 {
929     if (*slot_cnt < BTDM_MIN_SLEEP_DURATION) {
930         return false;
931     }
932     /* wake up in advance considering the delay in enabling PHY/RF */
933     *slot_cnt -= BTDM_MODEM_WAKE_UP_DELAY;
934     return true;
935 }
936 
btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)937 static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
938 {
939 #ifdef CONFIG_PM_ENABLE
940     // start a timer to wake up and acquire the pm_lock before modem_sleep awakes
941     uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles);
942 
943 #define BTDM_MIN_TIMER_UNCERTAINTY_US      (500)
944     assert(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
945     // allow a maximum time uncertainty to be about 488ppm(1/2048) at least as clock drift
946     // and set the timer in advance
947     uint32_t uncertainty = (us_to_sleep >> 11);
948     if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US) {
949         uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
950     }
951 
952     if (esp_timer_start_once(s_btdm_slp_tmr, us_to_sleep - uncertainty) != ESP_OK) {
953         ESP_LOGW(BTDM_LOG_TAG, "timer start failed");
954     }
955 #endif
956 }
957 
btdm_sleep_enter_phase2_wrapper(void)958 static void btdm_sleep_enter_phase2_wrapper(void)
959 {
960     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
961         esp_phy_disable(PHY_MODEM_BT);
962 #ifdef CONFIG_PM_ENABLE
963         if (s_pm_lock_acquired) {
964             esp_pm_lock_release(s_pm_lock);
965             s_pm_lock_acquired = false;
966         }
967 #endif
968     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
969         esp_phy_disable(PHY_MODEM_BT);
970         // pause bluetooth baseband
971         periph_module_disable(PERIPH_BT_BASEBAND_MODULE);
972     }
973 }
974 
btdm_sleep_exit_phase3_wrapper(void)975 static void btdm_sleep_exit_phase3_wrapper(void)
976 {
977 #ifdef CONFIG_PM_ENABLE
978     if (!s_pm_lock_acquired) {
979         s_pm_lock_acquired = true;
980         esp_pm_lock_acquire(s_pm_lock);
981     }
982 #endif
983 
984     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
985         esp_phy_enable(PHY_MODEM_BT);
986         btdm_check_and_init_bb();
987 #ifdef CONFIG_PM_ENABLE
988         esp_timer_stop(s_btdm_slp_tmr);
989 #endif
990     } else if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
991         // resume bluetooth baseband
992         periph_module_enable(PERIPH_BT_BASEBAND_MODULE);
993         esp_phy_enable(PHY_MODEM_BT);
994     }
995 }
996 
997 #ifdef CONFIG_PM_ENABLE
btdm_slp_tmr_customer_callback(void * arg)998 static void btdm_slp_tmr_customer_callback(void * arg)
999 {
1000     (void)(arg);
1001 
1002     if (!s_pm_lock_acquired) {
1003         s_pm_lock_acquired = true;
1004         esp_pm_lock_acquire(s_pm_lock);
1005     }
1006 }
1007 
btdm_slp_tmr_callback(void * arg)1008 static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
1009 {
1010     (void)(arg);
1011     btdm_dispatch_work_to_controller(btdm_slp_tmr_customer_callback, NULL, true);
1012 }
1013 #endif
1014 
1015 #define BTDM_ASYNC_WAKEUP_REQ_HCI       0
1016 #define BTDM_ASYNC_WAKEUP_REQ_COEX      1
1017 #define BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA 2
1018 #define BTDM_ASYNC_WAKEUP_REQMAX        3
1019 
btdm_wakeup_request_callback(void * arg)1020 static void btdm_wakeup_request_callback(void * arg)
1021 {
1022     (void)(arg);
1023 
1024 #if CONFIG_PM_ENABLE
1025     if (!s_pm_lock_acquired) {
1026         s_pm_lock_acquired = true;
1027         esp_pm_lock_acquire(s_pm_lock);
1028     }
1029     esp_timer_stop(s_btdm_slp_tmr);
1030 #endif
1031     btdm_wakeup_request();
1032 
1033     semphr_give_wrapper(s_wakeup_req_sem);
1034 }
1035 
async_wakeup_request(int event)1036 static bool async_wakeup_request(int event)
1037 {
1038     bool do_wakeup_request = false;
1039 
1040     switch (event) {
1041         case BTDM_ASYNC_WAKEUP_REQ_HCI:
1042             btdm_in_wakeup_requesting_set(true);
1043             // NO break
1044         case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
1045             if (!btdm_power_state_active()) {
1046                 do_wakeup_request = true;
1047 
1048                 btdm_dispatch_work_to_controller(btdm_wakeup_request_callback, NULL, true);
1049                 semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING);
1050             }
1051             break;
1052         case BTDM_ASYNC_WAKEUP_REQ_COEX:
1053             if (!btdm_power_state_active()) {
1054                 do_wakeup_request = true;
1055 #if CONFIG_PM_ENABLE
1056                 if (!s_pm_lock_acquired) {
1057                     s_pm_lock_acquired = true;
1058                     esp_pm_lock_acquire(s_pm_lock);
1059                 }
1060                 esp_timer_stop(s_btdm_slp_tmr);
1061 #endif
1062                 btdm_wakeup_request();
1063             }
1064             break;
1065         default:
1066             return false;
1067     }
1068 
1069     return do_wakeup_request;
1070 }
1071 
async_wakeup_request_end(int event)1072 static void async_wakeup_request_end(int event)
1073 {
1074     bool request_lock = false;
1075     switch (event) {
1076         case BTDM_ASYNC_WAKEUP_REQ_HCI:
1077             request_lock = true;
1078             break;
1079         case BTDM_ASYNC_WAKEUP_REQ_COEX:
1080         case BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA:
1081             request_lock = false;
1082             break;
1083         default:
1084             return;
1085     }
1086 
1087     if (request_lock) {
1088         btdm_in_wakeup_requesting_set(false);
1089     }
1090 
1091     return;
1092 }
1093 
coex_bt_wakeup_request(void)1094 static bool coex_bt_wakeup_request(void)
1095 {
1096     return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
1097 }
1098 
coex_bt_wakeup_request_end(void)1099 static void coex_bt_wakeup_request_end(void)
1100 {
1101     async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX);
1102     return;
1103 }
1104 
coex_bt_request_wrapper(uint32_t event,uint32_t latency,uint32_t duration)1105 static int IRAM_ATTR coex_bt_request_wrapper(uint32_t event, uint32_t latency, uint32_t duration)
1106 {
1107 #if CONFIG_SW_COEXIST_ENABLE
1108     return coex_bt_request(event, latency, duration);
1109 #else
1110     return 0;
1111 #endif
1112 }
1113 
coex_bt_release_wrapper(uint32_t event)1114 static int IRAM_ATTR coex_bt_release_wrapper(uint32_t event)
1115 {
1116 #if CONFIG_SW_COEXIST_ENABLE
1117     return coex_bt_release(event);
1118 #else
1119     return 0;
1120 #endif
1121 }
1122 
coex_register_bt_cb_wrapper(coex_func_cb_t cb)1123 static int coex_register_bt_cb_wrapper(coex_func_cb_t cb)
1124 {
1125 #if CONFIG_SW_COEXIST_ENABLE
1126     return coex_register_bt_cb(cb);
1127 #else
1128     return 0;
1129 #endif
1130 }
1131 
coex_bb_reset_lock_wrapper(void)1132 static uint32_t IRAM_ATTR coex_bb_reset_lock_wrapper(void)
1133 {
1134 #if CONFIG_SW_COEXIST_ENABLE
1135     return coex_bb_reset_lock();
1136 #else
1137     return 0;
1138 #endif
1139 }
1140 
coex_bb_reset_unlock_wrapper(uint32_t restore)1141 static void IRAM_ATTR coex_bb_reset_unlock_wrapper(uint32_t restore)
1142 {
1143 #if CONFIG_SW_COEXIST_ENABLE
1144     coex_bb_reset_unlock(restore);
1145 #endif
1146 }
1147 
coex_schm_register_btdm_callback_wrapper(void * callback)1148 static int coex_schm_register_btdm_callback_wrapper(void *callback)
1149 {
1150 #if CONFIG_SW_COEXIST_ENABLE
1151     return coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, callback);
1152 #else
1153     return 0;
1154 #endif
1155 }
1156 
coex_schm_status_bit_clear_wrapper(uint32_t type,uint32_t status)1157 static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
1158 {
1159 #if CONFIG_SW_COEXIST_ENABLE
1160     coex_schm_status_bit_clear(type, status);
1161 #endif
1162 }
1163 
coex_schm_status_bit_set_wrapper(uint32_t type,uint32_t status)1164 static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
1165 {
1166 #if CONFIG_SW_COEXIST_ENABLE
1167     coex_schm_status_bit_set(type, status);
1168 #endif
1169 }
1170 
coex_schm_interval_get_wrapper(void)1171 static uint32_t coex_schm_interval_get_wrapper(void)
1172 {
1173 #if CONFIG_SW_COEXIST_ENABLE
1174     return coex_schm_interval_get();
1175 #else
1176     return 0;
1177 #endif
1178 }
1179 
coex_schm_curr_period_get_wrapper(void)1180 static uint8_t coex_schm_curr_period_get_wrapper(void)
1181 {
1182 #if CONFIG_SW_COEXIST_ENABLE
1183     return coex_schm_curr_period_get();
1184 #else
1185     return 1;
1186 #endif
1187 }
1188 
coex_schm_curr_phase_get_wrapper(void)1189 static void * coex_schm_curr_phase_get_wrapper(void)
1190 {
1191 #if CONFIG_SW_COEXIST_ENABLE
1192     return coex_schm_curr_phase_get();
1193 #else
1194     return NULL;
1195 #endif
1196 }
1197 
coex_wifi_channel_get_wrapper(uint8_t * primary,uint8_t * secondary)1198 static int coex_wifi_channel_get_wrapper(uint8_t *primary, uint8_t *secondary)
1199 {
1200 #if CONFIG_SW_COEXIST_ENABLE
1201     return coex_wifi_channel_get(primary, secondary);
1202 #else
1203     return -1;
1204 #endif
1205 }
1206 
coex_register_wifi_channel_change_callback_wrapper(void * cb)1207 static int coex_register_wifi_channel_change_callback_wrapper(void *cb)
1208 {
1209 #if CONFIG_SW_COEXIST_ENABLE
1210     return coex_register_wifi_channel_change_callback(cb);
1211 #else
1212     return -1;
1213 #endif
1214 }
1215 
coex_version_get_wrapper(unsigned int * major,unsigned int * minor,unsigned int * patch)1216 static int coex_version_get_wrapper(unsigned int *major, unsigned int *minor, unsigned int *patch)
1217 {
1218 #if CONFIG_SW_COEXIST_ENABLE
1219     coex_version_t version;
1220     ESP_ERROR_CHECK(coex_version_get_value(&version));
1221     *major = (unsigned int)version.major;
1222     *minor = (unsigned int)version.minor;
1223     *patch = (unsigned int)version.patch;
1224     return 0;
1225 #endif
1226     return -1;
1227 }
1228 
esp_vhci_host_check_send_available(void)1229 bool esp_vhci_host_check_send_available(void)
1230 {
1231     return API_vhci_host_check_send_available();
1232 }
1233 
esp_vhci_host_send_packet(uint8_t * data,uint16_t len)1234 void esp_vhci_host_send_packet(uint8_t *data, uint16_t len)
1235 {
1236     async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_HCI);
1237 
1238     API_vhci_host_send_packet(data, len);
1239 
1240     async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_HCI);
1241 }
1242 
esp_vhci_host_register_callback(const esp_vhci_host_callback_t * callback)1243 esp_err_t esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
1244 {
1245     return API_vhci_host_register_callback((const vhci_host_callback_t *)callback) == 0 ? ESP_OK : ESP_FAIL;
1246 }
1247 
btdm_config_mask_load(void)1248 static uint32_t btdm_config_mask_load(void)
1249 {
1250     uint32_t mask = 0x0;
1251 
1252 #if CONFIG_BTDM_CTRL_HCI_MODE_UART_H4
1253     mask |= BTDM_CFG_HCI_UART;
1254 #endif
1255 #if CONFIG_BTDM_CTRL_PINNED_TO_CORE == 1
1256     mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU;
1257 #endif
1258 #if CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED
1259     mask |= BTDM_CFG_BLE_FULL_SCAN_SUPPORTED;
1260 #endif /* CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED */
1261     mask |= BTDM_CFG_SCAN_DUPLICATE_OPTIONS;
1262 
1263     mask |= BTDM_CFG_SEND_ADV_RESERVED_SIZE;
1264 
1265     return mask;
1266 }
1267 
btdm_controller_mem_init(void)1268 static void btdm_controller_mem_init(void)
1269 {
1270     /* initialise .data section */
1271     memcpy(&_data_start_btdm, (void *)_data_start_btdm_rom, &_data_end_btdm - &_data_start_btdm);
1272     ESP_LOGD(BTDM_LOG_TAG, ".data initialise [0x%08x] <== [0x%08x]", (uint32_t)&_data_start_btdm, _data_start_btdm_rom);
1273 
1274     //initial em, .bss section
1275     for (int i = 1; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) {
1276         if (btdm_dram_available_region[i].mode != ESP_BT_MODE_IDLE) {
1277             memset((void *)btdm_dram_available_region[i].start, 0x0, btdm_dram_available_region[i].end - btdm_dram_available_region[i].start);
1278             ESP_LOGD(BTDM_LOG_TAG, ".bss initialise [0x%08x] - [0x%08x]", btdm_dram_available_region[i].start, btdm_dram_available_region[i].end);
1279         }
1280     }
1281 }
1282 
try_heap_caps_add_region(intptr_t start,intptr_t end)1283 static esp_err_t try_heap_caps_add_region(intptr_t start, intptr_t end)
1284 {
1285     int ret = heap_caps_add_region(start, end);
1286     /* heap_caps_add_region() returns ESP_ERR_INVALID_SIZE if the memory region is
1287      * is too small to fit a heap. This cannot be termed as a fatal error and hence
1288      * we replace it by ESP_OK
1289      */
1290     if (ret == ESP_ERR_INVALID_SIZE) {
1291         return ESP_OK;
1292     }
1293     return ret;
1294 }
1295 
1296 typedef struct {
1297     intptr_t start;
1298     intptr_t end;
1299     const char* name;
1300 } bt_area_t;
1301 
1302 
esp_bt_mem_release_area(const bt_area_t * area)1303 static esp_err_t esp_bt_mem_release_area(const bt_area_t *area)
1304 {
1305     esp_err_t ret = ESP_OK;
1306     intptr_t mem_start = area->start;
1307     intptr_t mem_end = area->end;
1308     if (mem_start != mem_end) {
1309         ESP_LOGD(BTDM_LOG_TAG, "Release %s [0x%08x] - [0x%08x], len %d", area->name, mem_start, mem_end, mem_end - mem_start);
1310         ret = try_heap_caps_add_region(mem_start, mem_end);
1311     }
1312     return ret;
1313 }
1314 
esp_bt_mem_release_areas(const bt_area_t * area1,const bt_area_t * area2)1315 static esp_err_t esp_bt_mem_release_areas(const bt_area_t *area1, const bt_area_t *area2)
1316 {
1317     esp_err_t ret = ESP_OK;
1318 
1319     if (area1->end == area2->start) {
1320         bt_area_t merged_area = {
1321             .start = area1->start,
1322             .end = area2->end,
1323             .name = area1->name
1324         };
1325         ret = esp_bt_mem_release_area(&merged_area);
1326     } else {
1327         esp_bt_mem_release_area(area1);
1328         ret = esp_bt_mem_release_area(area2);
1329     }
1330 
1331     return ret;
1332 }
1333 
esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)1334 static esp_err_t esp_bt_controller_rom_mem_release(esp_bt_mode_t mode)
1335 {
1336     bool update = true;
1337     intptr_t mem_start=(intptr_t) NULL, mem_end=(intptr_t) NULL;
1338 
1339     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1340         return ESP_ERR_INVALID_STATE;
1341     }
1342 
1343     //already released
1344     if (!(mode & btdm_dram_available_region[0].mode)) {
1345         ESP_LOGW(BTDM_LOG_TAG, "%s already released, mode %d",__func__, mode);
1346         return ESP_OK;
1347     }
1348 
1349     for (int i = 0; i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t); i++) {
1350         //skip the share mode, idle mode and other mode
1351         if (btdm_dram_available_region[i].mode == ESP_BT_MODE_IDLE
1352                 || (mode & btdm_dram_available_region[i].mode) != btdm_dram_available_region[i].mode) {
1353             //clear the bit of the mode which will be released
1354             btdm_dram_available_region[i].mode &= ~mode;
1355             continue;
1356         } else {
1357             //clear the bit of the mode which will be released
1358             btdm_dram_available_region[i].mode &= ~mode;
1359         }
1360 
1361         if (update) {
1362             mem_start = btdm_dram_available_region[i].start;
1363             mem_end = btdm_dram_available_region[i].end;
1364             update = false;
1365         }
1366 
1367         if (i < sizeof(btdm_dram_available_region)/sizeof(btdm_dram_available_region_t) - 1) {
1368             mem_end = btdm_dram_available_region[i].end;
1369             if (btdm_dram_available_region[i+1].mode != ESP_BT_MODE_IDLE
1370                     && (mode & btdm_dram_available_region[i+1].mode) == btdm_dram_available_region[i+1].mode
1371                     && mem_end == btdm_dram_available_region[i+1].start) {
1372                 continue;
1373             } else {
1374                 ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]", mem_start, mem_end);
1375                 ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
1376                 update = true;
1377             }
1378         } else {
1379             mem_end = btdm_dram_available_region[i].end;
1380             ESP_LOGD(BTDM_LOG_TAG, "Release DRAM [0x%08x] - [0x%08x]", mem_start, mem_end);
1381             ESP_ERROR_CHECK(try_heap_caps_add_region(mem_start, mem_end));
1382             update = true;
1383         }
1384     }
1385 
1386     return ESP_OK;
1387 }
1388 
esp_bt_controller_mem_release(esp_bt_mode_t mode)1389 esp_err_t esp_bt_controller_mem_release(esp_bt_mode_t mode)
1390 {
1391     esp_err_t ret = ESP_OK;
1392 
1393     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1394         return ESP_ERR_INVALID_STATE;
1395     }
1396 
1397     if (mode == ESP_BT_MODE_BTDM) {
1398         bt_area_t cont_bss = {
1399             .start = (intptr_t)&_bt_controller_bss_start,
1400             .end   = (intptr_t)&_bt_controller_bss_end,
1401             .name  = "BT Controller BSS",
1402         };
1403         bt_area_t cont_data = {
1404             .start = (intptr_t)&_bt_controller_data_start,
1405             .end   = (intptr_t)&_bt_controller_data_end,
1406             .name  = "BT Controller Data"
1407         };
1408 
1409         ret = esp_bt_mem_release_areas(&cont_data, &cont_bss);
1410     }
1411 
1412     if (ret == ESP_OK) {
1413         ret = esp_bt_controller_rom_mem_release(mode);
1414     }
1415 
1416     return ret;
1417 }
1418 
esp_bt_mem_release(esp_bt_mode_t mode)1419 esp_err_t esp_bt_mem_release(esp_bt_mode_t mode)
1420 {
1421     esp_err_t ret = ESP_OK;
1422 
1423     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1424         return ESP_ERR_INVALID_STATE;
1425     }
1426 
1427     bt_area_t bss = {
1428         .start = (intptr_t)&_bt_bss_start,
1429         .end   = (intptr_t)&_bt_bss_end,
1430         .name  = "BT BSS",
1431     };
1432     bt_area_t cont_bss = {
1433         .start = (intptr_t)&_bt_controller_bss_start,
1434         .end   = (intptr_t)&_bt_controller_bss_end,
1435         .name  = "BT Controller BSS",
1436     };
1437     bt_area_t data = {
1438         .start = (intptr_t)&_bt_data_start,
1439         .end   = (intptr_t)&_bt_data_end,
1440         .name  = "BT Data",
1441     };
1442     bt_area_t cont_data = {
1443         .start = (intptr_t)&_bt_controller_data_start,
1444         .end   = (intptr_t)&_bt_controller_data_end,
1445         .name  = "BT Controller Data"
1446     };
1447 
1448     /*
1449      * Free data and BSS section for Bluetooth controller ROM code.
1450      * Note that rom mem release must be performed before section _bt_data_start to _bt_data_end is released,
1451      * otherwise `btdm_dram_available_region` will no longer be available when performing rom mem release and
1452      * thus causing heap corruption.
1453      */
1454     ret = esp_bt_controller_rom_mem_release(mode);
1455 
1456     if (mode == ESP_BT_MODE_BTDM) {
1457         /* Start by freeing Bluetooth BSS section */
1458         if (ret == ESP_OK) {
1459             ret = esp_bt_mem_release_areas(&bss, &cont_bss);
1460         }
1461 
1462         /* Do the same thing with the Bluetooth data section */
1463         if (ret == ESP_OK) {
1464             ret = esp_bt_mem_release_areas(&data, &cont_data);
1465         }
1466     }
1467 
1468     return ret;
1469 }
1470 
1471 #if CONFIG_BTDM_CTRL_HLI
hli_queue_setup_cb(void * arg)1472 static void hli_queue_setup_cb(void* arg)
1473 {
1474     hli_queue_setup();
1475 }
1476 
hli_queue_setup_pinned_to_core(int core_id)1477 static void hli_queue_setup_pinned_to_core(int core_id)
1478 {
1479 #if CONFIG_FREERTOS_UNICORE
1480     hli_queue_setup_cb(NULL);
1481 #else /* CONFIG_FREERTOS_UNICORE */
1482     if (xPortGetCoreID() == core_id) {
1483         hli_queue_setup_cb(NULL);
1484     } else {
1485         esp_ipc_call(core_id, hli_queue_setup_cb, NULL);
1486     }
1487 #endif /* !CONFIG_FREERTOS_UNICORE */
1488 }
1489 #endif /* CONFIG_BTDM_CTRL_HLI */
1490 
esp_bt_controller_init(esp_bt_controller_config_t * cfg)1491 esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
1492 {
1493     esp_err_t err;
1494     uint32_t btdm_cfg_mask = 0;
1495 
1496 #if CONFIG_BTDM_CTRL_HLI
1497     hli_queue_setup_pinned_to_core(CONFIG_BTDM_CTRL_PINNED_TO_CORE);
1498 #endif /* CONFIG_BTDM_CTRL_HLI */
1499 
1500     //if all the bt available memory was already released, cannot initialize bluetooth controller
1501     if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE) {
1502         return ESP_ERR_INVALID_STATE;
1503     }
1504 
1505     osi_funcs_p = (struct osi_funcs_t *)malloc_internal_wrapper(sizeof(struct osi_funcs_t));
1506     if (osi_funcs_p == NULL) {
1507         return ESP_ERR_NO_MEM;
1508     }
1509 
1510     memcpy(osi_funcs_p, &osi_funcs_ro, sizeof(struct osi_funcs_t));
1511     if (btdm_osi_funcs_register(osi_funcs_p) != 0) {
1512         return ESP_ERR_INVALID_ARG;
1513     }
1514 
1515     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
1516         return ESP_ERR_INVALID_STATE;
1517     }
1518 
1519     if (cfg == NULL) {
1520         return ESP_ERR_INVALID_ARG;
1521     }
1522 
1523     if (cfg->controller_task_prio != ESP_TASK_BT_CONTROLLER_PRIO
1524             || cfg->controller_task_stack_size < ESP_TASK_BT_CONTROLLER_STACK) {
1525         return ESP_ERR_INVALID_ARG;
1526     }
1527 
1528     //overwrite some parameters
1529     cfg->bt_max_sync_conn = CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF;
1530     cfg->magic  = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL;
1531 
1532     if (((cfg->mode & ESP_BT_MODE_BLE) && (cfg->ble_max_conn <= 0 || cfg->ble_max_conn > BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT))
1533             || ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_acl_conn <= 0 || cfg->bt_max_acl_conn > BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT))
1534             || ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_sync_conn > BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT))) {
1535         return ESP_ERR_INVALID_ARG;
1536     }
1537 
1538     ESP_LOGI(BTDM_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
1539 
1540     s_wakeup_req_sem = semphr_create_wrapper(1, 0);
1541     if (s_wakeup_req_sem == NULL) {
1542         err = ESP_ERR_NO_MEM;
1543         goto error;
1544     }
1545 
1546     esp_phy_modem_init();
1547 
1548     esp_bt_power_domain_on();
1549 
1550     btdm_controller_mem_init();
1551 
1552     periph_module_enable(PERIPH_BT_MODULE);
1553     periph_module_reset(PERIPH_BT_MODULE);
1554 
1555 #ifdef CONFIG_PM_ENABLE
1556     s_btdm_allow_light_sleep = false;
1557 #endif
1558 
1559     // set default sleep clock cycle and its fractional bits
1560     btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1561     btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1562 
1563 #if CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG
1564 
1565     btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1566 #if CONFIG_BTDM_CTRL_LPCLK_SEL_EXT_32K_XTAL
1567     // check whether or not EXT_CRYS is working
1568     if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
1569         btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32kHz XTAL
1570 #ifdef CONFIG_PM_ENABLE
1571         s_btdm_allow_light_sleep = true;
1572 #endif
1573     } else {
1574         ESP_LOGW(BTDM_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock\n"
1575                  "light sleep mode will not be able to apply when bluetooth is enabled");
1576         btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1577     }
1578 #else
1579     btdm_lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
1580 #endif
1581 
1582     bool select_src_ret __attribute__((unused));
1583     bool set_div_ret __attribute__((unused));
1584     if (btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
1585         select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
1586         set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() * 2 / MHZ - 1);
1587         assert(select_src_ret && set_div_ret);
1588         btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1589         btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
1590     } else { // btdm_lpclk_sel == BTDM_LPCLK_SEL_XTAL32K
1591         select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
1592         set_div_ret = btdm_lpclk_set_div(0);
1593         assert(select_src_ret && set_div_ret);
1594         btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
1595         btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
1596             (1000000 >> (15 - RTC_CLK_CAL_FRACT));
1597         assert(btdm_lpcycle_us != 0);
1598     }
1599     btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_ORIG);
1600 
1601 #elif CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_EVED
1602     btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_EVED);
1603 #else
1604     btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
1605 #endif
1606 
1607 #if CONFIG_BTDM_CTRL_HCI_UART_FLOW_CTRL_EN
1608     sdk_config_set_uart_flow_ctrl_enable(true);
1609 #else
1610     sdk_config_set_uart_flow_ctrl_enable(false);
1611 #endif
1612 
1613 #ifdef CONFIG_PM_ENABLE
1614     if (!s_btdm_allow_light_sleep) {
1615         if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
1616             goto error;
1617         }
1618     }
1619     if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
1620         goto error;
1621     }
1622     esp_timer_create_args_t create_args = {
1623         .callback = btdm_slp_tmr_callback,
1624         .arg = NULL,
1625         .name = "btSlp"
1626     };
1627     if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
1628         goto error;
1629     }
1630 
1631     s_pm_lock_acquired = true;
1632 #endif
1633 
1634 #if CONFIG_SW_COEXIST_ENABLE
1635     coex_init();
1636 #endif
1637 
1638     btdm_cfg_mask = btdm_config_mask_load();
1639 
1640     err = btdm_controller_init(btdm_cfg_mask, cfg);
1641 
1642     if (err != 0) {
1643         ESP_LOGE(BTDM_LOG_TAG, "%s %d\n",__func__,err);
1644         err = ESP_ERR_NO_MEM;
1645         goto error;
1646     }
1647 
1648     btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1649 
1650     return ESP_OK;
1651 
1652 error:
1653 
1654     bt_controller_deinit_internal();
1655 
1656     return err;
1657 }
1658 
esp_bt_controller_deinit(void)1659 esp_err_t esp_bt_controller_deinit(void)
1660 {
1661     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1662         return ESP_ERR_INVALID_STATE;
1663     }
1664 
1665     btdm_controller_deinit();
1666 
1667     bt_controller_deinit_internal();
1668 
1669     return ESP_OK;
1670 }
1671 
bt_controller_deinit_internal(void)1672 static void bt_controller_deinit_internal(void)
1673 {
1674     periph_module_disable(PERIPH_BT_MODULE);
1675 
1676 #ifdef CONFIG_PM_ENABLE
1677     if (!s_btdm_allow_light_sleep) {
1678         esp_pm_lock_delete(s_light_sleep_pm_lock);
1679         s_light_sleep_pm_lock = NULL;
1680     }
1681 
1682     if (s_pm_lock != NULL) {
1683         esp_pm_lock_delete(s_pm_lock);
1684         s_pm_lock = NULL;
1685     }
1686 
1687     if (s_btdm_slp_tmr != NULL) {
1688         esp_timer_stop(s_btdm_slp_tmr);
1689         esp_timer_delete(s_btdm_slp_tmr);
1690         s_btdm_slp_tmr = NULL;
1691     }
1692 
1693     s_pm_lock_acquired = false;
1694 #endif
1695 
1696     if (s_wakeup_req_sem) {
1697         semphr_delete_wrapper(s_wakeup_req_sem);
1698         s_wakeup_req_sem = NULL;
1699     }
1700 
1701     if (osi_funcs_p) {
1702         free(osi_funcs_p);
1703         osi_funcs_p = NULL;
1704     }
1705 
1706     btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
1707 
1708     btdm_lpcycle_us = 0;
1709     btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
1710 
1711     esp_bt_power_domain_off();
1712 
1713     esp_phy_modem_deinit();
1714 }
1715 
bt_controller_shutdown(void * arg)1716 static void bt_controller_shutdown(void* arg)
1717 {
1718     esp_bt_controller_shutdown();
1719 }
1720 
bt_shutdown(void)1721 static void bt_shutdown(void)
1722 {
1723     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1724         return;
1725     }
1726 #if !CONFIG_FREERTOS_UNICORE
1727     esp_ipc_call_blocking(CONFIG_BTDM_CTRL_PINNED_TO_CORE, bt_controller_shutdown, NULL);
1728 #else
1729     bt_controller_shutdown(NULL);
1730 #endif
1731     esp_phy_disable(PHY_MODEM_BT);
1732 
1733     return;
1734 }
1735 
patch_apply(void)1736 static void patch_apply(void)
1737 {
1738     config_btdm_funcs_reset();
1739 
1740 #ifndef CONFIG_BTDM_CTRL_MODE_BLE_ONLY
1741     config_bt_funcs_reset();
1742 #endif
1743 
1744 #ifndef CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
1745     config_ble_funcs_reset();
1746 #endif
1747 
1748 #ifdef CONFIG_BTDM_BLE_VS_QA_SUPPORT
1749     config_ble_vs_qa_funcs_reset();
1750 #endif
1751 }
1752 
esp_bt_controller_enable(esp_bt_mode_t mode)1753 esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
1754 {
1755     int ret;
1756 
1757     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
1758         return ESP_ERR_INVALID_STATE;
1759     }
1760 
1761     //As the history reason, mode should be equal to the mode which set in esp_bt_controller_init()
1762     if (mode != btdm_controller_get_mode()) {
1763         return ESP_ERR_INVALID_ARG;
1764     }
1765 
1766 #ifdef CONFIG_PM_ENABLE
1767     if (!s_btdm_allow_light_sleep) {
1768         esp_pm_lock_acquire(s_light_sleep_pm_lock);
1769     }
1770     esp_pm_lock_acquire(s_pm_lock);
1771 #endif
1772 
1773     esp_phy_enable(PHY_MODEM_BT);
1774 
1775 #if CONFIG_SW_COEXIST_ENABLE
1776     coex_enable();
1777 #endif
1778 
1779     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
1780         btdm_controller_enable_sleep(true);
1781     }
1782 
1783     sdk_config_set_bt_pll_track_enable(true);
1784 
1785     // initialize bluetooth baseband
1786     btdm_check_and_init_bb();
1787 
1788     ret = btdm_controller_enable(mode);
1789     if (ret != 0) {
1790 #if CONFIG_SW_COEXIST_ENABLE
1791         coex_disable();
1792 #endif
1793         esp_phy_disable(PHY_MODEM_BT);
1794 #ifdef CONFIG_PM_ENABLE
1795         if (!s_btdm_allow_light_sleep) {
1796             esp_pm_lock_release(s_light_sleep_pm_lock);
1797         }
1798         esp_pm_lock_release(s_pm_lock);
1799 #endif
1800         return ESP_ERR_INVALID_STATE;
1801     }
1802 
1803     btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
1804     ret = esp_register_shutdown_handler(bt_shutdown);
1805     if (ret != ESP_OK) {
1806         ESP_LOGW(BTDM_LOG_TAG, "Register shutdown handler failed, ret = 0x%x", ret);
1807     }
1808 
1809     return ESP_OK;
1810 }
1811 
esp_bt_controller_disable(void)1812 esp_err_t esp_bt_controller_disable(void)
1813 {
1814     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1815         return ESP_ERR_INVALID_STATE;
1816     }
1817 
1818     // disable modem sleep and wake up from sleep mode
1819     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG) {
1820         btdm_controller_enable_sleep(false);
1821         async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_CTRL_DISA);
1822         while (!btdm_power_state_active()) {
1823             esp_rom_delay_us(1000);
1824         }
1825     }
1826 
1827     btdm_controller_disable();
1828 
1829 #if CONFIG_SW_COEXIST_ENABLE
1830     coex_disable();
1831 #endif
1832 
1833     esp_phy_disable(PHY_MODEM_BT);
1834     btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
1835     esp_unregister_shutdown_handler(bt_shutdown);
1836 
1837 #ifdef CONFIG_PM_ENABLE
1838     if (!s_btdm_allow_light_sleep) {
1839         esp_pm_lock_release(s_light_sleep_pm_lock);
1840     }
1841     esp_pm_lock_release(s_pm_lock);
1842 #endif
1843 
1844     return ESP_OK;
1845 }
1846 
esp_bt_controller_get_status(void)1847 esp_bt_controller_status_t esp_bt_controller_get_status(void)
1848 {
1849     return btdm_controller_status;
1850 }
1851 
1852 /* extra functions */
esp_ble_tx_power_set(esp_ble_power_type_t power_type,esp_power_level_t power_level)1853 esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_t power_level)
1854 {
1855     if (ble_txpwr_set(power_type, power_level) != 0) {
1856         return ESP_ERR_INVALID_ARG;
1857     }
1858 
1859     return ESP_OK;
1860 }
1861 
esp_ble_tx_power_get(esp_ble_power_type_t power_type)1862 esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type)
1863 {
1864     return (esp_power_level_t)ble_txpwr_get(power_type);
1865 }
1866 
esp_bredr_tx_power_set(esp_power_level_t min_power_level,esp_power_level_t max_power_level)1867 esp_err_t esp_bredr_tx_power_set(esp_power_level_t min_power_level, esp_power_level_t max_power_level)
1868 {
1869     esp_err_t err;
1870     int ret;
1871 
1872     ret = bredr_txpwr_set(min_power_level, max_power_level);
1873 
1874     if (ret == 0) {
1875         err = ESP_OK;
1876     } else if (ret == -1) {
1877         err = ESP_ERR_INVALID_ARG;
1878     } else {
1879         err = ESP_ERR_INVALID_STATE;
1880     }
1881 
1882     return err;
1883 }
1884 
esp_bredr_tx_power_get(esp_power_level_t * min_power_level,esp_power_level_t * max_power_level)1885 esp_err_t esp_bredr_tx_power_get(esp_power_level_t *min_power_level, esp_power_level_t *max_power_level)
1886 {
1887     if (bredr_txpwr_get((int *)min_power_level, (int *)max_power_level) != 0) {
1888         return ESP_ERR_INVALID_ARG;
1889     }
1890 
1891     return ESP_OK;
1892 }
1893 
esp_bt_sleep_enable(void)1894 esp_err_t esp_bt_sleep_enable (void)
1895 {
1896     esp_err_t status;
1897     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1898         return ESP_ERR_INVALID_STATE;
1899     }
1900     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
1901             btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
1902         btdm_controller_enable_sleep (true);
1903         status = ESP_OK;
1904     } else {
1905         status = ESP_ERR_NOT_SUPPORTED;
1906     }
1907 
1908     return status;
1909 }
1910 
esp_bt_sleep_disable(void)1911 esp_err_t esp_bt_sleep_disable (void)
1912 {
1913     esp_err_t status;
1914     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1915         return ESP_ERR_INVALID_STATE;
1916     }
1917     if (btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_ORIG ||
1918             btdm_controller_get_sleep_mode() == BTDM_MODEM_SLEEP_MODE_EVED) {
1919         btdm_controller_enable_sleep (false);
1920         status = ESP_OK;
1921     } else {
1922         status = ESP_ERR_NOT_SUPPORTED;
1923     }
1924 
1925     return status;
1926 }
1927 
esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)1928 esp_err_t esp_bredr_sco_datapath_set(esp_sco_data_path_t data_path)
1929 {
1930     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1931         return ESP_ERR_INVALID_STATE;
1932     }
1933     bredr_sco_datapath_set(data_path);
1934     return ESP_OK;
1935 }
1936 
esp_ble_scan_duplicate_list_flush(void)1937 esp_err_t esp_ble_scan_duplicate_list_flush(void)
1938 {
1939     if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
1940         return ESP_ERR_INVALID_STATE;
1941     }
1942     btdm_controller_scan_duplicate_list_clear();
1943     return ESP_OK;
1944 }
1945 
esp_ble_scan_dupilcate_list_flush(void)1946 esp_err_t esp_ble_scan_dupilcate_list_flush(void)
1947 {
1948     return esp_ble_scan_duplicate_list_flush();
1949 }
1950 
1951 /**
1952  * This function re-write controller's function,
1953  * As coredump can not show parameters in function which is in a .a file.
1954  *
1955  * After coredump fixing this issue, just delete this function.
1956  */
r_assert(const char * condition,int param0,int param1,const char * file,int line)1957 void IRAM_ATTR r_assert(const char *condition, int param0, int param1, const char *file, int line)
1958 {
1959     __asm__ __volatile__("ill\n");
1960 }
1961 
1962 #endif /*  CONFIG_BT_ENABLED */
1963