1use core::ptr::addr_of_mut;
2
3use procmacros::BuilderLite;
4
5use super::*;
6use crate::{
7 binary::include::{
8 esp_bt_controller_config_t,
9 esp_bt_mode_t,
10 esp_bt_mode_t_ESP_BT_MODE_BLE,
11 esp_bt_mode_t_ESP_BT_MODE_BTDM,
12 esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT,
13 esp_bt_mode_t_ESP_BT_MODE_IDLE,
14 },
15 ble::InvalidConfigError,
16 common_adapter::*,
17 hal::{interrupt, peripherals::Interrupt},
18};
19
20pub(crate) static mut ISR_INTERRUPT_5: (*mut c_void, *mut c_void) =
21 (core::ptr::null_mut(), core::ptr::null_mut());
22
23pub(crate) static mut ISR_INTERRUPT_8: (*mut c_void, *mut c_void) =
24 (core::ptr::null_mut(), core::ptr::null_mut());
25
26pub(crate) static mut ISR_INTERRUPT_7: (*mut c_void, *mut c_void) =
27 (core::ptr::null_mut(), core::ptr::null_mut());
28
29#[repr(C)]
30pub(super) struct osi_funcs_s {
31 version: u32,
32 set_isr: Option<unsafe extern "C" fn(i32, unsafe extern "C" fn(), *const ()) -> i32>,
33 ints_on: Option<unsafe extern "C" fn(u32)>,
34 interrupt_disable: Option<unsafe extern "C" fn()>,
35 interrupt_restore: Option<unsafe extern "C" fn()>,
36 task_yield: Option<unsafe extern "C" fn()>,
37 task_yield_from_isr: Option<unsafe extern "C" fn()>,
38 semphr_create: Option<unsafe extern "C" fn(u32, u32) -> *mut c_void>,
39 semphr_delete: Option<unsafe extern "C" fn(*mut c_void)>,
40 semphr_take_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut bool) -> i32>,
41 semphr_give_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut bool) -> i32>,
42 semphr_take: Option<unsafe extern "C" fn(*mut c_void, u32) -> i32>,
43 semphr_give: Option<unsafe extern "C" fn(*mut c_void) -> i32>,
44 mutex_create: Option<unsafe extern "C" fn() -> *const ()>,
45 mutex_delete: Option<unsafe extern "C" fn(*const ())>,
46 mutex_lock: Option<unsafe extern "C" fn(*const ()) -> i32>,
47 mutex_unlock: Option<unsafe extern "C" fn(*const ()) -> i32>,
48 queue_create: Option<unsafe extern "C" fn(u32, u32) -> *mut c_void>,
49 queue_delete: Option<unsafe extern "C" fn(*mut c_void)>,
50 queue_send: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, u32) -> i32>,
51 queue_send_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> i32>,
52 queue_recv: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, u32) -> i32>,
53 queue_recv_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> i32>,
54 task_create: Option<
55 unsafe extern "C" fn(
56 *mut c_void,
57 *const c_char,
58 u32,
59 *mut c_void,
60 u32,
61 *mut c_void,
62 u32,
63 ) -> i32,
64 >,
65 task_delete: Option<unsafe extern "C" fn(*mut ())>,
66 is_in_isr: Option<unsafe extern "C" fn() -> i32>,
67 cause_sw_intr_to_core: Option<unsafe extern "C" fn(i32, i32) -> i32>,
68 malloc: Option<unsafe extern "C" fn(u32) -> *mut c_void>,
69 malloc_internal: Option<unsafe extern "C" fn(u32) -> *mut c_void>,
70 free: Option<unsafe extern "C" fn(*mut c_void)>,
71 read_efuse_mac: Option<unsafe extern "C" fn(*const ()) -> i32>,
72 srand: Option<unsafe extern "C" fn(u32)>,
73 rand: Option<unsafe extern "C" fn() -> i32>,
74 btdm_lpcycles_2_hus: Option<unsafe extern "C" fn(u32, u32) -> u32>,
75 btdm_hus_2_lpcycles: Option<unsafe extern "C" fn(u32) -> u32>,
76 btdm_sleep_check_duration: Option<unsafe extern "C" fn(i32) -> i32>,
77 btdm_sleep_enter_phase1: Option<unsafe extern "C" fn(i32)>,
78 btdm_sleep_enter_phase2: Option<unsafe extern "C" fn()>,
79 btdm_sleep_exit_phase1: Option<unsafe extern "C" fn()>,
80 btdm_sleep_exit_phase2: Option<unsafe extern "C" fn()>,
81 btdm_sleep_exit_phase3: Option<unsafe extern "C" fn()>,
82 coex_bt_wakeup_request: Option<unsafe extern "C" fn() -> bool>,
83 coex_bt_wakeup_request_end: Option<unsafe extern "C" fn()>,
84 coex_bt_request: Option<unsafe extern "C" fn(u32, u32, u32) -> i32>,
85 coex_bt_release: Option<unsafe extern "C" fn(u32) -> i32>,
86 coex_register_bt_cb: Option<unsafe extern "C" fn(unsafe extern "C" fn()) -> i32>,
87 coex_bb_reset_lock: Option<unsafe extern "C" fn() -> u32>,
88 coex_bb_reset_unlock: Option<unsafe extern "C" fn(u32)>,
89 coex_schm_register_btdm_callback: Option<unsafe extern "C" fn(unsafe extern "C" fn()) -> i32>,
90 coex_schm_status_bit_clear: Option<unsafe extern "C" fn(i32, i32)>,
91 coex_schm_status_bit_set: Option<unsafe extern "C" fn(i32, i32)>,
92 coex_schm_interval_get: Option<unsafe extern "C" fn() -> u32>,
93 coex_schm_curr_period_get: Option<unsafe extern "C" fn() -> u8>,
94 coex_schm_curr_phase_get: Option<unsafe extern "C" fn() -> *const ()>,
95 coex_wifi_channel_get: Option<unsafe extern "C" fn(*mut u8, *mut u8) -> i32>,
96 coex_register_wifi_channel_change_callback:
97 Option<unsafe extern "C" fn(unsafe extern "C" fn()) -> i32>,
98 set_isr13: Option<unsafe extern "C" fn(i32, unsafe extern "C" fn(), *const ()) -> i32>,
99 interrupt_l3_disable: Option<unsafe extern "C" fn()>,
100 interrupt_l3_restore: Option<unsafe extern "C" fn()>,
101 custom_queue_create: Option<unsafe extern "C" fn(u32, u32) -> *mut c_void>,
102 coex_version_get: Option<unsafe extern "C" fn(*mut c_uint, *mut c_uint, *mut c_uint) -> c_int>,
103 patch_apply: Option<unsafe extern "C" fn()>,
104 magic: u32,
105}
106
107pub(super) static G_OSI_FUNCS: osi_funcs_s = osi_funcs_s {
108 version: 0x00010005,
109 set_isr: Some(ble_os_adapter_chip_specific::set_isr),
110 ints_on: Some(ble_os_adapter_chip_specific::ints_on),
111 interrupt_disable: Some(interrupt_disable),
112 interrupt_restore: Some(interrupt_enable),
113 task_yield: Some(task_yield),
114 task_yield_from_isr: Some(task_yield_from_isr),
115 semphr_create: Some(semphr_create),
116 semphr_delete: Some(semphr_delete),
117 semphr_take_from_isr: Some(semphr_take_from_isr),
118 semphr_give_from_isr: Some(semphr_give_from_isr),
119 semphr_take: Some(semphr_take),
120 semphr_give: Some(semphr_give),
121 mutex_create: Some(mutex_create),
122 mutex_delete: Some(mutex_delete),
123 mutex_lock: Some(mutex_lock),
124 mutex_unlock: Some(mutex_unlock),
125 queue_create: Some(queue_create),
126 queue_delete: Some(queue_delete),
127 queue_send: Some(queue_send),
128 queue_send_from_isr: Some(queue_send_from_isr),
129 queue_recv: Some(queue_recv),
130 queue_recv_from_isr: Some(queue_recv_from_isr),
131 task_create: Some(task_create),
132 task_delete: Some(task_delete),
133 is_in_isr: Some(is_in_isr),
134 cause_sw_intr_to_core: Some(cause_sw_intr_to_core),
135 malloc: Some(crate::ble::malloc),
136 malloc_internal: Some(crate::ble::malloc_internal),
137 free: Some(crate::ble::free),
138 read_efuse_mac: Some(read_efuse_mac),
139 srand: Some(crate::ble::btdm::srand),
140 rand: Some(crate::ble::btdm::rand),
141 btdm_lpcycles_2_hus: Some(btdm_lpcycles_2_hus),
142 btdm_hus_2_lpcycles: Some(btdm_hus_2_lpcycles),
143 btdm_sleep_check_duration: Some(btdm_sleep_check_duration),
144 btdm_sleep_enter_phase1: Some(btdm_sleep_enter_phase1),
145 btdm_sleep_enter_phase2: Some(btdm_sleep_enter_phase2),
146 btdm_sleep_exit_phase1: Some(btdm_sleep_exit_phase1),
147 btdm_sleep_exit_phase2: Some(btdm_sleep_exit_phase2),
148 btdm_sleep_exit_phase3: Some(btdm_sleep_exit_phase3),
149 coex_bt_wakeup_request: Some(ble_os_adapter_chip_specific::coex_bt_wakeup_request),
150 coex_bt_wakeup_request_end: Some(ble_os_adapter_chip_specific::coex_bt_wakeup_request_end),
151 coex_bt_request: Some(ble_os_adapter_chip_specific::coex_bt_request),
152 coex_bt_release: Some(ble_os_adapter_chip_specific::coex_bt_release),
153 coex_register_bt_cb: Some(ble_os_adapter_chip_specific::coex_register_bt_cb_wrapper),
154 coex_bb_reset_lock: Some(ble_os_adapter_chip_specific::coex_bb_reset_lock),
155 coex_bb_reset_unlock: Some(ble_os_adapter_chip_specific::coex_bb_reset_unlock),
156 coex_schm_register_btdm_callback: Some(
157 ble_os_adapter_chip_specific::coex_schm_register_btdm_callback_wrapper,
158 ),
159 coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear),
160 coex_schm_status_bit_set: Some(coex_schm_status_bit_set),
161 coex_schm_interval_get: Some(ble_os_adapter_chip_specific::coex_schm_interval_get),
162 coex_schm_curr_period_get: Some(ble_os_adapter_chip_specific::coex_schm_curr_period_get),
163 coex_schm_curr_phase_get: Some(ble_os_adapter_chip_specific::coex_schm_curr_phase_get),
164 coex_wifi_channel_get: Some(ble_os_adapter_chip_specific::coex_wifi_channel_get),
165 coex_register_wifi_channel_change_callback: Some(
166 ble_os_adapter_chip_specific::coex_register_wifi_channel_change_callback,
167 ),
168 set_isr13: Some(set_isr13),
169 interrupt_l3_disable: Some(interrupt_l3_disable),
170 interrupt_l3_restore: Some(interrupt_l3_restore),
171 custom_queue_create: Some(custom_queue_create),
172 coex_version_get: Some(coex_version_get_wrapper),
173 patch_apply: Some(patch_apply),
174 magic: 0xfadebead,
175};
176
177extern "C" fn patch_apply() {
178 trace!("patch apply");
179
180 unsafe extern "C" {
181 fn config_ble_funcs_reset();
182 fn config_btdm_funcs_reset();
183 }
184
185 unsafe {
186 config_btdm_funcs_reset();
187 config_ble_funcs_reset();
188 }
189}
190
191extern "C" fn coex_version_get_wrapper(major: *mut u32, minor: *mut u32, patch: *mut u32) -> i32 {
192 unsafe {
193 let mut version = crate::binary::include::coex_version_t {
194 major: 0,
195 minor: 0,
196 patch: 0,
197 };
198 if coex_version_get_value(&mut version) == 0 {
199 info!(
200 "COEX Version {}.{}.{}",
201 version.major, version.minor, version.patch
202 );
203
204 major.write_volatile(version.major as u32);
205 minor.write_volatile(version.minor as u32);
206 patch.write_volatile(version.patch as u32);
207 } else {
208 error!("Unable to get COEX version");
209 }
210 }
211
212 0
213}
214
215#[repr(C)]
216struct btdm_dram_available_region_t {
217 mode: esp_bt_mode_t,
218 start: u32, end: u32, }
221
222const SOC_MEM_BT_DATA_START: u32 = 0x3ffae6e0;
223const SOC_MEM_BT_DATA_END: u32 = 0x3ffaff10;
224const SOC_MEM_BT_EM_BTDM0_START: u32 = 0x3ffb0000;
225const SOC_MEM_BT_EM_BTDM0_END: u32 = 0x3ffb09a8;
226const SOC_MEM_BT_EM_BLE_START: u32 = 0x3ffb09a8;
227const SOC_MEM_BT_EM_BLE_END: u32 = 0x3ffb1ddc;
228const SOC_MEM_BT_EM_BTDM1_START: u32 = 0x3ffb1ddc;
229const SOC_MEM_BT_EM_BTDM1_END: u32 = 0x3ffb2730;
230const SOC_MEM_BT_EM_BREDR_START: u32 = 0x3ffb2730;
231const SOC_MEM_BT_BSS_START: u32 = 0x3ffb8000;
232const SOC_MEM_BT_BSS_END: u32 = 0x3ffb9a20;
233const SOC_MEM_BT_MISC_START: u32 = 0x3ffbdb28;
234const SOC_MEM_BT_MISC_END: u32 = 0x3ffbdb5c;
235
236const SOC_MEM_BT_EM_BREDR_REAL_END: u32 = 0x3ffb6388; static BTDM_DRAM_AVAILABLE_REGION: [btdm_dram_available_region_t; 7] = [
240 btdm_dram_available_region_t {
242 mode: esp_bt_mode_t_ESP_BT_MODE_BTDM,
243 start: SOC_MEM_BT_DATA_START,
244 end: SOC_MEM_BT_DATA_END,
245 },
246 btdm_dram_available_region_t {
248 mode: esp_bt_mode_t_ESP_BT_MODE_BTDM,
249 start: SOC_MEM_BT_EM_BTDM0_START,
250 end: SOC_MEM_BT_EM_BTDM0_END,
251 },
252 btdm_dram_available_region_t {
253 mode: esp_bt_mode_t_ESP_BT_MODE_BLE,
254 start: SOC_MEM_BT_EM_BLE_START,
255 end: SOC_MEM_BT_EM_BLE_END,
256 },
257 btdm_dram_available_region_t {
258 mode: esp_bt_mode_t_ESP_BT_MODE_BTDM,
259 start: SOC_MEM_BT_EM_BTDM1_START,
260 end: SOC_MEM_BT_EM_BTDM1_END,
261 },
262 btdm_dram_available_region_t {
263 mode: esp_bt_mode_t_ESP_BT_MODE_CLASSIC_BT,
264 start: SOC_MEM_BT_EM_BREDR_START,
265 end: SOC_MEM_BT_EM_BREDR_REAL_END,
266 },
267 btdm_dram_available_region_t {
269 mode: esp_bt_mode_t_ESP_BT_MODE_BTDM,
270 start: SOC_MEM_BT_BSS_START,
271 end: SOC_MEM_BT_BSS_END,
272 },
273 btdm_dram_available_region_t {
274 mode: esp_bt_mode_t_ESP_BT_MODE_BTDM,
275 start: SOC_MEM_BT_MISC_START,
276 end: SOC_MEM_BT_MISC_END,
277 },
278];
279
280#[derive(BuilderLite, Clone, Copy, Eq, PartialEq)]
282#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
283#[cfg_attr(feature = "defmt", derive(defmt::Format))]
284pub struct Config {
285 task_priority: u8,
287
288 task_stack_size: u16,
290
291 max_connections: u8,
295
296 scan_duplicate_list_count: u16,
300
301 scan_duplicate_refresh_period: u16,
305
306 ble_scan_backoff: bool,
308
309 enc_key_sz_min: u8,
313
314 verify_access_address: bool,
316
317 channel_assessment: bool,
319
320 ping: bool,
322
323 disconnect_llcp_conn_update: bool,
325
326 disconnect_llcp_chan_map_update: bool,
328}
329
330impl Default for Config {
331 fn default() -> Self {
332 Self {
333 task_priority: 29,
335 task_stack_size: 4096,
336 max_connections: CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF as _,
337 scan_duplicate_list_count: CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE as _,
338 scan_duplicate_refresh_period: SCAN_DUPL_CACHE_REFRESH_PERIOD as _,
339 ble_scan_backoff: false,
340 enc_key_sz_min: 7,
341 verify_access_address: false,
342 channel_assessment: false,
343 ping: false,
344 disconnect_llcp_conn_update: false,
345 disconnect_llcp_chan_map_update: false,
346 }
347 }
348}
349
350impl Config {
351 pub(crate) fn validate(&self) -> Result<(), InvalidConfigError> {
352 crate::ble::validate_range!(self, max_connections, 1, 9);
353 crate::ble::validate_range!(self, scan_duplicate_list_count, 10, 1000);
354 crate::ble::validate_range!(self, scan_duplicate_refresh_period, 0, 1000);
355 crate::ble::validate_range!(self, enc_key_sz_min, 7, 16);
356
357 Ok(())
358 }
359}
360
361pub(crate) fn create_ble_config(config: &Config) -> esp_bt_controller_config_t {
362 esp_bt_controller_config_t {
365 controller_task_stack_size: config.task_stack_size,
366 controller_task_prio: config.task_priority,
367
368 hci_uart_no: 1,
370 hci_uart_baudrate: 921600,
371 scan_duplicate_mode: 0, scan_duplicate_type: 0,
374 mesh_adv_size: 0,
375
376 normal_adv_size: config.scan_duplicate_list_count,
377 send_adv_reserved_size: SCAN_SEND_ADV_RESERVED_SIZE as _,
378 controller_debug_flag: BTDM_CTRL_CONTROLLER_DEBUG_FLAG as _,
379 mode: esp_bt_mode_t_ESP_BT_MODE_BLE as _,
380 ble_max_conn: config.max_connections,
381 bt_max_acl_conn: 0,
382 bt_sco_datapath: 0,
383 auto_latency: false,
384 bt_legacy_auth_vs_evt: false,
385 bt_max_sync_conn: 1,
386 ble_sca: 1,
387 pcm_role: 0,
388 pcm_polar: 0,
389 hli: false,
390 dup_list_refresh_period: config.scan_duplicate_refresh_period,
391 ble_scan_backoff: config.ble_scan_backoff,
392 pcm_fsyncshp: 0,
393 enc_key_sz_min: config.enc_key_sz_min,
394 ble_llcp_disc_flag: config.disconnect_llcp_conn_update as u8
395 | ((config.disconnect_llcp_chan_map_update as u8) << 1),
396 ble_aa_check: config.verify_access_address,
397 ble_chan_ass_en: config.channel_assessment as u8,
398 ble_ping_en: config.ping as u8,
399 magic: ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL,
400 }
401}
402
403pub(crate) fn btdm_controller_mem_init() {
404 unsafe extern "C" {
405 static mut _data_start_btdm: u32;
406 static mut _data_end_btdm: u32;
407 static _data_start_btdm_rom: u32;
408 }
409
410 unsafe {
412 let data_start = addr_of_mut!(_data_start_btdm).cast::<u8>();
413 let data_end = addr_of_mut!(_data_end_btdm).cast::<u8>();
414
415 let data_start_rom = _data_start_btdm_rom as *const u8;
418
419 let len = data_end as usize - data_start as usize;
420
421 core::ptr::copy_nonoverlapping(data_start_rom, data_start, len);
422
423 debug!(
424 "btdm_controller_mem_init {:?} {:?} {}",
425 data_start_rom, data_start, len,
426 );
427 }
428
429 let btdm_dram_regions = BTDM_DRAM_AVAILABLE_REGION.len();
431
432 #[allow(clippy::needless_range_loop)] for i in 1..btdm_dram_regions {
434 if BTDM_DRAM_AVAILABLE_REGION[i].mode != esp_bt_mode_t_ESP_BT_MODE_IDLE {
435 unsafe {
436 core::ptr::write_bytes(
437 BTDM_DRAM_AVAILABLE_REGION[i].start as *mut u8,
438 0x0,
439 (BTDM_DRAM_AVAILABLE_REGION[i].end - BTDM_DRAM_AVAILABLE_REGION[i].start)
440 as usize,
441 );
442 }
443 debug!(
444 ".bss initialise {:x} - {:x}\n",
445 BTDM_DRAM_AVAILABLE_REGION[i].start, BTDM_DRAM_AVAILABLE_REGION[i].end
446 );
447 }
448 }
449
450 debug!("btdm_controller_mem_init done");
451}
452
453pub(crate) fn bt_periph_module_enable() {
454 }
456
457pub(crate) fn disable_sleep_mode() {
458 unsafe extern "C" {
459 fn btdm_controller_set_sleep_mode(mode: u8);
460 }
461
462 const BTDM_MODEM_SLEEP_MODE_NONE: u8 = 0;
463
464 unsafe {
465 btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
466 }
467}
468
469pub(crate) unsafe extern "C" fn coex_bt_wakeup_request() -> bool {
470 trace!("coex_bt_wakeup_request");
471
472 true
483}
484
485pub(crate) unsafe extern "C" fn coex_bt_wakeup_request_end() {
486 trace!("coex_bt_wakeup_request_end");
487
488 }
497
498#[allow(unused_variables)]
499pub(crate) unsafe extern "C" fn coex_bt_request(event: u32, latency: u32, duration: u32) -> i32 {
500 trace!("coex_bt_request");
501 unsafe extern "C" {
502 #[cfg(coex)]
503 fn coex_bt_request(event: u32, latency: u32, duration: u32) -> i32;
504 }
505
506 #[cfg(coex)]
507 return unsafe { coex_bt_request(event, latency, duration) };
508
509 #[cfg(not(coex))]
510 0
511}
512
513#[allow(unused_variables)]
514pub(crate) unsafe extern "C" fn coex_bt_release(event: u32) -> i32 {
515 trace!("coex_bt_release");
516 unsafe extern "C" {
517 #[cfg(coex)]
518 fn coex_bt_release(event: u32) -> i32;
519 }
520
521 #[cfg(coex)]
522 return unsafe { coex_bt_release(event) };
523
524 #[cfg(not(coex))]
525 0
526}
527
528pub(crate) unsafe extern "C" fn coex_register_bt_cb_wrapper(
529 callback: unsafe extern "C" fn(),
530) -> i32 {
531 trace!("coex_register_bt_cb {:?}", callback);
532 unsafe extern "C" {
533 #[cfg(coex)]
534 fn coex_register_bt_cb(callback: unsafe extern "C" fn()) -> i32;
535 }
536
537 #[cfg(coex)]
538 return unsafe { coex_register_bt_cb(callback) };
539
540 #[cfg(not(coex))]
541 0
542}
543
544pub(crate) unsafe extern "C" fn coex_bb_reset_lock() -> u32 {
545 trace!("coex_bb_reset_lock");
546 unsafe extern "C" {
547 #[cfg(coex)]
548 fn coex_bb_reset_lock() -> u32;
549 }
550
551 #[cfg(coex)]
552 return unsafe { coex_bb_reset_lock() };
553
554 #[cfg(not(coex))]
555 0
556}
557
558#[allow(unused_variables)]
559pub(crate) unsafe extern "C" fn coex_bb_reset_unlock(event: u32) {
560 trace!("coex_bb_reset_unlock");
561 unsafe extern "C" {
562 #[cfg(coex)]
563 fn coex_bb_reset_unlock(event: u32);
564 }
565
566 #[cfg(coex)]
567 unsafe {
568 coex_bb_reset_unlock(event)
569 };
570}
571
572pub(crate) unsafe extern "C" fn coex_schm_register_btdm_callback_wrapper(
573 callback: unsafe extern "C" fn(),
574) -> i32 {
575 trace!("coex_schm_register_btdm_callback {:?}", callback);
576 unsafe extern "C" {
577 #[cfg(coex)]
578 fn coex_schm_register_callback(kind: u32, callback: unsafe extern "C" fn()) -> i32;
579 }
580
581 #[cfg(coex)]
582 return unsafe { coex_schm_register_callback(1, callback) }; #[cfg(not(coex))]
585 0
586}
587
588pub(crate) unsafe extern "C" fn coex_schm_interval_get() -> u32 {
589 trace!("coex_schm_interval_get");
590
591 #[cfg(coex)]
592 return unsafe { crate::binary::include::coex_schm_interval_get() };
593
594 #[cfg(not(coex))]
595 0
596}
597
598pub(crate) unsafe extern "C" fn coex_schm_curr_period_get() -> u8 {
599 trace!("coex_schm_curr_period_get");
600
601 #[cfg(coex)]
602 return unsafe { crate::binary::include::coex_schm_curr_period_get() };
603
604 #[cfg(not(coex))]
605 0
606}
607
608pub(crate) unsafe extern "C" fn coex_schm_curr_phase_get() -> *const () {
609 trace!("coex_schm_curr_phase_get");
610
611 #[cfg(coex)]
612 return unsafe { crate::binary::include::coex_schm_curr_phase_get() } as *const ();
613
614 #[cfg(not(coex))]
615 return core::ptr::null::<()>();
616}
617
618#[allow(unused_variables)]
619pub(crate) unsafe extern "C" fn coex_wifi_channel_get(primary: *mut u8, secondary: *mut u8) -> i32 {
620 trace!("coex_wifi_channel_get");
621 unsafe extern "C" {
622 #[cfg(coex)]
623 fn coex_wifi_channel_get(primary: *mut u8, secondary: *mut u8) -> i32;
624 }
625
626 #[cfg(coex)]
627 return unsafe { coex_wifi_channel_get(primary, secondary) };
628
629 #[cfg(not(coex))]
630 -1
631}
632
633#[allow(unused_variables)]
634pub(crate) unsafe extern "C" fn coex_register_wifi_channel_change_callback(
635 callback: unsafe extern "C" fn(),
636) -> i32 {
637 trace!("coex_register_wifi_channel_change_callback");
638 unsafe extern "C" {
639 #[cfg(coex)]
640 fn coex_register_wifi_channel_change_callback(callback: unsafe extern "C" fn()) -> i32;
641 }
642
643 #[cfg(coex)]
644 return unsafe { coex_register_wifi_channel_change_callback(callback) };
645
646 #[cfg(not(coex))]
647 0
648}
649
650pub(crate) unsafe extern "C" fn set_isr(n: i32, f: unsafe extern "C" fn(), arg: *const ()) -> i32 {
651 trace!("set_isr called {} {:?} {:?}", n, f, arg);
652
653 match n {
654 5 => {
655 unsafe {
656 ISR_INTERRUPT_5 = (f as *mut c_void, arg as *mut c_void);
657 }
658 unwrap!(interrupt::enable(
659 Interrupt::RWBT,
660 interrupt::Priority::Priority1
661 ));
662 unwrap!(interrupt::enable(
663 Interrupt::RWBLE,
664 interrupt::Priority::Priority1
665 ));
666 }
667 7 => unsafe {
668 ISR_INTERRUPT_7 = (f as *mut c_void, arg as *mut c_void);
669 },
670 8 => {
671 unsafe {
672 ISR_INTERRUPT_8 = (f as *mut c_void, arg as *mut c_void);
673 }
674 unwrap!(interrupt::enable(
675 Interrupt::BT_BB,
676 interrupt::Priority::Priority1,
677 ));
678 }
679 _ => panic!("set_isr - unsupported interrupt number {}", n),
680 }
681
682 0
683}
684
685pub(crate) unsafe extern "C" fn ints_on(mask: u32) {
686 trace!("chip_ints_on esp32 {:b}", mask);
687 unsafe {
688 crate::hal::xtensa_lx::interrupt::enable_mask(mask);
689 }
690}
691
692#[cfg(coex)]
693pub(crate) const BTDM_ASYNC_WAKEUP_REQ_HCI: i32 = 0;
694
695#[cfg(coex)]
696pub(crate) const BTDM_ASYNC_WAKEUP_REQ_COEX: i32 = 1;
697
698#[cfg(coex)]
714pub(crate) fn async_wakeup_request(event: i32) -> bool {
715 trace!("async_wakeup_request {}", event);
716
717 unsafe extern "C" {
718 fn btdm_in_wakeup_requesting_set(set: bool);
719
720 fn btdm_power_state_active() -> bool;
721
722 fn btdm_wakeup_request();
723 }
724
725 match event {
726 e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => {
727 unsafe {
728 btdm_in_wakeup_requesting_set(true);
729 }
730 false
731 }
732 e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => {
733 unsafe {
734 btdm_in_wakeup_requesting_set(true);
735 }
736
737 if !unsafe { btdm_power_state_active() } {
738 unsafe {
739 btdm_wakeup_request();
740 }
741 true
742 } else {
743 false
744 }
745 }
746 _ => false,
747 }
748}
749
750#[cfg(coex)]
764pub(crate) fn async_wakeup_request_end(event: i32) {
765 trace!("async_wakeup_request_end {}", event);
766
767 let request_lock = match event {
768 e if e == BTDM_ASYNC_WAKEUP_REQ_HCI => true,
769 e if e == BTDM_ASYNC_WAKEUP_REQ_COEX => false,
770 _ => return,
771 };
772
773 unsafe extern "C" {
774 fn btdm_in_wakeup_requesting_set(set: bool);
775 }
776
777 if request_lock {
778 unsafe { btdm_in_wakeup_requesting_set(false) };
779 }
780}