1use alloc::boxed::Box;
2use core::{
3 mem::transmute,
4 ptr::{NonNull, addr_of, addr_of_mut},
5};
6
7use esp_hal::time::Instant;
8use esp_phy::PhyInitGuard;
9
10use super::*;
11use crate::{
12 compat::{self, OSI_FUNCS_TIME_BLOCKING, common::str_from_c, queue},
13 sys::{c_types::*, include::*},
14 time::{blob_ticks_to_micros, blob_ticks_to_millis, millis_to_blob_ticks},
15};
16
17#[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")]
18#[cfg_attr(esp32c5, path = "os_adapter_esp32c5.rs")]
19#[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")]
20#[cfg_attr(esp32c61, path = "os_adapter_esp32c61.rs")]
21#[cfg_attr(esp32h2, path = "os_adapter_esp32h2.rs")]
22pub(crate) mod ble_os_adapter_chip_specific;
23
24const EVENT_QUEUE_SIZE: usize = 16;
25
26const TIME_FOREVER: u32 = crate::compat::OSI_FUNCS_TIME_BLOCKING;
27
28#[cfg(esp32c2)]
29const OS_MSYS_1_BLOCK_COUNT: i32 = 24;
30#[cfg(esp32c2)]
31const SYSINIT_MSYS_1_MEMPOOL_SIZE: usize = 768;
32#[cfg(esp32c2)]
33const SYSINIT_MSYS_1_MEMBLOCK_SIZE: i32 = 128;
34#[cfg(esp32c2)]
35const OS_MSYS_2_BLOCK_COUNT: i32 = 24;
36#[cfg(esp32c2)]
37const SYSINIT_MSYS_2_MEMPOOL_SIZE: usize = 1920;
38#[cfg(esp32c2)]
39const SYSINIT_MSYS_2_MEMBLOCK_SIZE: i32 = 320;
40
41const BLE_HCI_TRANS_BUF_CMD: i32 = 3;
42
43const ACL_DATA_MBUF_LEADINGSPACE: usize = 4;
45
46#[repr(C)]
47#[derive(Copy, Clone)]
48struct Callout {
49 eventq: *const ble_npl_eventq,
50 timer_handle: ets_timer,
51 events: ble_npl_event,
52}
53
54#[repr(C)]
55#[derive(Copy, Clone)]
56struct Event {
57 event_fn_ptr: *const ble_npl_event_fn,
58 ev_arg_ptr: *const c_void,
59 queued: bool,
60}
61
62#[cfg(esp32c2)]
63type OsMembufT = u32;
64
65#[repr(C)]
67pub(crate) struct OsMempool {
68 mp_block_size: u32,
70 mp_num_blocks: u16,
72 mp_num_free: u16,
74 mp_min_free: u16,
76 mp_flags: u8,
78 mp_membuf_addr: u32,
80
81 next: *const OsMempool,
83
84 first: *const c_void,
86
87 name: *const u8,
89}
90
91#[cfg(esp32c2)]
92impl OsMempool {
93 const fn zeroed() -> Self {
94 Self {
95 mp_block_size: 0,
96 mp_num_blocks: 0,
97 mp_num_free: 0,
98 mp_min_free: 0,
99 mp_flags: 0,
100 mp_membuf_addr: 0,
101 next: core::ptr::null(),
102 first: core::ptr::null(),
103 name: core::ptr::null(),
104 }
105 }
106}
107
108#[repr(C)]
114pub(crate) struct OsMbufPool {
115 omp_databuf_len: u16,
118 omp_pool: *const OsMempool,
120
121 next: *const OsMbufPool,
123}
124
125#[cfg(esp32c2)]
126impl OsMbufPool {
127 const fn zeroed() -> Self {
128 Self {
129 omp_databuf_len: 0,
130 omp_pool: core::ptr::null(),
131 next: core::ptr::null(),
132 }
133 }
134}
135
136#[repr(C)]
138pub(crate) struct OsMbuf {
139 om_data: *const u8,
141 om_flags: u8,
143 om_pkthdr_len: u8,
145 om_len: u16,
147
148 om_omp: *const OsMbufPool,
150
151 next: *const OsMbuf,
153
154 om_databuf: u32,
156}
157
158#[cfg(esp32c2)]
159pub(crate) static mut OS_MSYS_INIT_1_DATA: *mut OsMembufT = core::ptr::null_mut();
160#[cfg(esp32c2)]
161pub(crate) static mut OS_MSYS_INIT_1_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed();
162#[cfg(esp32c2)]
163pub(crate) static mut OS_MSYS_INIT_1_MEMPOOL: OsMempool = OsMempool::zeroed();
164
165#[cfg(esp32c2)]
166pub(crate) static mut OS_MSYS_INIT_2_DATA: *mut OsMembufT = core::ptr::null_mut();
167#[cfg(esp32c2)]
168pub(crate) static mut OS_MSYS_INIT_2_MBUF_POOL: OsMbufPool = OsMbufPool::zeroed();
169#[cfg(esp32c2)]
170pub(crate) static mut OS_MSYS_INIT_2_MEMPOOL: OsMempool = OsMempool::zeroed();
171
172unsafe extern "C" {
173 pub(crate) fn r_ble_hci_trans_hs_acl_tx(om: *const OsMbuf) -> i32;
180
181 pub(crate) fn r_ble_hci_trans_hs_cmd_tx(cmd: *const u8) -> i32;
189
190 #[cfg(esp32c2)]
191 pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
192
193 #[cfg(not(esp32c2))]
194 pub(crate) fn r_ble_controller_disable() -> i32;
195
196 #[cfg(not(esp32c2))]
197 pub(crate) fn r_ble_controller_deinit() -> i32;
198
199 #[cfg(esp32c2)]
200 pub(crate) fn ble_controller_deinit() -> i32;
201
202 #[cfg(not(esp32c2))]
203 pub(crate) fn r_ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
204
205 #[cfg(esp32c2)]
206 pub(crate) fn ble_controller_enable(mode: u8) -> i32;
207
208 #[cfg(not(esp32c2))]
209 pub(crate) fn r_ble_controller_enable(mode: u8) -> i32;
210
211 pub(crate) fn esp_unregister_ext_funcs();
212
213 pub(crate) fn esp_register_ext_funcs(funcs: *const ExtFuncsT) -> i32;
214
215 pub(crate) fn esp_register_npl_funcs(funcs: *const npl_funcs_t) -> i32;
216
217 pub(crate) fn esp_unregister_npl_funcs();
218
219 #[cfg(esp32c2)]
220 pub(crate) fn ble_get_npl_element_info(
221 cfg: *const esp_bt_controller_config_t,
222 npl_info: *const BleNplCountInfoT,
223 ) -> i32;
224
225 #[cfg(not(esp32c2))]
226 pub(crate) fn r_ble_get_npl_element_info(
227 cfg: *const esp_bt_controller_config_t,
228 npl_info: *const BleNplCountInfoT,
229 ) -> i32;
230
231 pub(crate) fn bt_bb_v2_init_cmplx(value: u8);
232
233 pub(crate) fn r_ble_hci_trans_cfg_hs(
234 evt: Option<unsafe extern "C" fn(cmd: *const u8, arg: *const c_void) -> i32>,
236 evt_arg: *const c_void,
237 acl_cb: Option<unsafe extern "C" fn(om: *const OsMbuf, arg: *const c_void) -> i32>,
239 acl_arg: *const c_void,
240 );
241
242 #[cfg(esp32c2)]
243 pub(crate) fn esp_ble_ll_set_public_addr(addr: *const u8);
244
245 #[cfg(not(esp32c2))]
246 pub(crate) fn r_esp_ble_ll_set_public_addr(addr: *const u8);
247
248 #[cfg(esp32c2)]
249 pub(crate) fn r_mem_init_mbuf_pool(
250 mem: *const c_void,
251 mempool: *const OsMempool,
252 mbuf_pool: *const OsMbufPool,
253 num_blocks: i32,
254 block_size: i32,
255 name: *const u8,
256 ) -> i32;
257
258 #[cfg(esp32c2)]
259 pub(crate) fn r_os_msys_reset();
260
261 #[cfg(esp32c2)]
262 pub(crate) fn r_os_msys_register(mbuf_pool: *const OsMbufPool) -> i32;
263
264 #[allow(unused)]
265 pub(crate) fn ble_osi_coex_funcs_register(coex_funcs: *const OsiCoexFuncsT) -> i32;
266
267 pub(crate) fn r_os_msys_get_pkthdr(dsize: u16, user_hdr_len: u16) -> *mut OsMbuf;
268
269 pub(crate) fn r_os_mbuf_append(om: *mut OsMbuf, src: *const u8, len: u16) -> i32;
270
271 pub(crate) fn r_os_mbuf_free_chain(om: *mut OsMbuf) -> i32;
272
273 pub(crate) fn r_ble_hci_trans_buf_alloc(typ: i32) -> *const u8;
274
275 pub(crate) fn r_ble_hci_trans_buf_free(buf: *const u8);
276
277 pub(crate) fn coex_pti_v2();
278
279 #[cfg(not(esp32c2))]
280 pub(crate) fn scan_stack_initEnv() -> i32;
281
282 #[cfg(not(esp32c2))]
283 pub(crate) fn scan_stack_deinitEnv();
284}
285
286#[repr(C)]
287pub(crate) struct ExtFuncsT {
289 ext_version: u32,
290 esp_intr_alloc: Option<
291 unsafe extern "C" fn(
292 source: u32,
293 flags: u32,
294 handler: *mut c_void,
295 arg: *mut c_void,
296 ret_handle: *mut *mut c_void,
297 ) -> i32,
298 >,
299 esp_intr_free: Option<unsafe extern "C" fn(ret_handle: *mut *mut c_void) -> i32>,
300 malloc: Option<unsafe extern "C" fn(size: u32) -> *mut c_void>,
301 free: Option<unsafe extern "C" fn(*mut c_void)>,
302 #[cfg(esp32c2)]
303 hal_uart_start_tx: Option<unsafe extern "C" fn(i32)>,
304 #[cfg(esp32c2)]
305 hal_uart_init_cbs: Option<
306 unsafe extern "C" fn(i32, *const c_void, *const c_void, *const c_void, c_void) -> i32,
307 >,
308 #[cfg(esp32c2)]
309 hal_uart_config: Option<unsafe extern "C" fn(i32, i32, u8, u8, u8, u8) -> i32>,
310 #[cfg(esp32c2)]
311 hal_uart_close: Option<unsafe extern "C" fn(i32) -> i32>,
312 #[cfg(esp32c2)]
313 hal_uart_blocking_tx: Option<unsafe extern "C" fn(i32, u8)>,
314 #[cfg(esp32c2)]
315 hal_uart_init: Option<unsafe extern "C" fn(i32, *const c_void) -> i32>,
316 task_create: Option<
317 unsafe extern "C" fn(
318 *mut c_void,
319 *const c_char,
320 u32,
321 *mut c_void,
322 u32,
323 *const c_void,
324 u32,
325 ) -> i32,
326 >,
327 task_delete: Option<unsafe extern "C" fn(*mut c_void)>,
328 osi_assert: Option<unsafe extern "C" fn(u32, *const c_void, u32, u32)>,
329 os_random: Option<unsafe extern "C" fn() -> u32>,
330 ecc_gen_key_pair: Option<unsafe extern "C" fn(*const u8, *const u8) -> i32>,
331 ecc_gen_dh_key: Option<unsafe extern "C" fn(*const u8, *const u8, *const u8, *const u8) -> i32>,
332 #[cfg(any(esp32c6, esp32h2))]
333 esp_reset_modem: Option<unsafe extern "C" fn(mdl_opts: u8, start: u8)>,
334 #[cfg(esp32c2)]
335 esp_reset_rpa_moudle: Option<unsafe extern "C" fn()>,
336 #[cfg(esp32c2)]
337 esp_bt_track_pll_cap: Option<unsafe extern "C" fn()>,
338 magic: u32,
339}
340
341static G_OSI_FUNCS: ExtFuncsT = ExtFuncsT {
342 ext_version: if cfg!(esp32c2) {
343 0x20221122
344 } else {
345 0x20250825
346 },
347
348 esp_intr_alloc: Some(self::ble_os_adapter_chip_specific::esp_intr_alloc),
349 esp_intr_free: Some(esp_intr_free),
350 malloc: Some(crate::ble::malloc),
351 free: Some(crate::ble::free),
352 #[cfg(esp32c2)]
353 hal_uart_start_tx: None,
354 #[cfg(esp32c2)]
355 hal_uart_init_cbs: None,
356 #[cfg(esp32c2)]
357 hal_uart_config: None,
358 #[cfg(esp32c2)]
359 hal_uart_close: None,
360 #[cfg(esp32c2)]
361 hal_uart_blocking_tx: None,
362 #[cfg(esp32c2)]
363 hal_uart_init: None,
364 task_create: Some(task_create),
365 task_delete: Some(task_delete),
366 osi_assert: Some(osi_assert),
367 os_random: Some(os_random),
368 ecc_gen_key_pair: Some(ecc_gen_key_pair),
369 ecc_gen_dh_key: Some(ecc_gen_dh_key),
370 #[cfg(any(esp32c6, esp32h2))]
371 esp_reset_modem: Some(self::ble_os_adapter_chip_specific::reset_modem),
372 #[cfg(esp32c2)]
373 esp_reset_rpa_moudle: Some(self::ble_os_adapter_chip_specific::esp_reset_rpa_moudle),
374 #[cfg(esp32c2)]
375 esp_bt_track_pll_cap: None,
376 magic: 0xA5A5A5A5,
377};
378
379unsafe extern "C" fn ecc_gen_dh_key(_: *const u8, _: *const u8, _: *const u8, _: *const u8) -> i32 {
380 todo!()
381}
382
383unsafe extern "C" fn ecc_gen_key_pair(_: *const u8, _: *const u8) -> i32 {
384 todo!()
385}
386
387unsafe extern "C" fn os_random() -> u32 {
388 trace!("os_random");
389 unsafe { crate::common_adapter::random() as u32 }
390}
391
392unsafe extern "C" fn task_create(
393 task_func: *mut c_void,
394 name: *const c_char,
395 stack_depth: u32,
396 param: *mut c_void,
397 prio: u32,
398 task_handle: *const c_void,
399 core_id: u32,
400) -> i32 {
401 let name_str = unsafe { str_from_c(name) };
402 trace!(
403 "task_create {:?} {} {} {:?} {} {:?} {}",
404 task_func, name_str, stack_depth, param, prio, task_handle, core_id,
405 );
406
407 unsafe {
408 let task_func = transmute::<*mut c_void, extern "C" fn(*mut c_void)>(task_func);
409
410 let task = crate::preempt::task_create(
411 name_str,
412 task_func,
413 param,
414 prio,
415 if core_id < 2 { Some(core_id) } else { None },
416 stack_depth as usize,
417 );
418 *(task_handle as *mut usize) = task.as_ptr() as usize;
419 }
420
421 1
422}
423
424unsafe extern "C" fn task_delete(task: *mut c_void) {
425 trace!("task delete called for {:?}", task);
426
427 unsafe {
428 crate::preempt::schedule_task_deletion(NonNull::new(task.cast::<()>()));
429 }
430}
431
432unsafe extern "C" fn osi_assert(ln: u32, fn_name: *const c_void, param1: u32, param2: u32) {
433 unsafe {
434 let name_str = str_from_c(fn_name as _);
435 panic!("ASSERT {}:{} {} {}", name_str, ln, param1, param2);
436 }
437}
438
439unsafe extern "C" fn esp_intr_free(_ret_handle: *mut *mut c_void) -> i32 {
440 todo!();
441}
442
443#[repr(C)]
444#[allow(non_camel_case_types)]
445pub(crate) struct npl_funcs_t {
447 p_ble_npl_os_started: Option<unsafe extern "C" fn() -> bool>,
448 p_ble_npl_get_current_task_id: Option<unsafe extern "C" fn() -> *const c_void>,
449 p_ble_npl_eventq_init: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq)>,
450 p_ble_npl_eventq_deinit: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq)>,
451 p_ble_npl_eventq_get: Option<
452 unsafe extern "C" fn(
453 queue: *mut ble_npl_eventq,
454 time: ble_npl_time_t,
455 ) -> *const ble_npl_event,
456 >,
457 p_ble_npl_eventq_put:
458 Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq, event: *const ble_npl_event)>,
459 p_ble_npl_eventq_remove:
460 Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq, event: *const ble_npl_event)>,
461 p_ble_npl_event_run: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
462 p_ble_npl_eventq_is_empty: Option<unsafe extern "C" fn(queue: *mut ble_npl_eventq) -> bool>,
463 p_ble_npl_event_init: Option<
464 unsafe extern "C" fn(
465 event: *const ble_npl_event,
466 func: *const ble_npl_event_fn,
467 *const c_void,
468 ),
469 >,
470 p_ble_npl_event_deinit: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
471 p_ble_npl_event_reset: Option<unsafe extern "C" fn(event: *const ble_npl_event)>,
472 p_ble_npl_event_is_queued: Option<unsafe extern "C" fn(event: *const ble_npl_event) -> bool>,
473 p_ble_npl_event_get_arg:
474 Option<unsafe extern "C" fn(event: *const ble_npl_event) -> *const c_void>,
475 p_ble_npl_event_set_arg:
476 Option<unsafe extern "C" fn(event: *const ble_npl_event, arg: *const c_void)>,
477 p_ble_npl_mutex_init:
478 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
479 p_ble_npl_mutex_deinit:
480 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
481 p_ble_npl_mutex_pend: Option<
482 unsafe extern "C" fn(mutex: *const ble_npl_mutex, time: ble_npl_time_t) -> ble_npl_error_t,
483 >,
484 p_ble_npl_mutex_release:
485 Option<unsafe extern "C" fn(mutex: *const ble_npl_mutex) -> ble_npl_error_t>,
486 p_ble_npl_sem_init:
487 Option<unsafe extern "C" fn(sem: *const ble_npl_sem, val: u16) -> ble_npl_error_t>,
488 p_ble_npl_sem_deinit: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> ble_npl_error_t>,
489 p_ble_npl_sem_pend: Option<
490 unsafe extern "C" fn(sem: *const ble_npl_sem, time: ble_npl_time_t) -> ble_npl_error_t,
491 >,
492 p_ble_npl_sem_release: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> ble_npl_error_t>,
493 p_ble_npl_sem_get_count: Option<unsafe extern "C" fn(sem: *const ble_npl_sem) -> u16>,
494 p_ble_npl_callout_init: Option<
495 unsafe extern "C" fn(
496 callout: *const ble_npl_callout,
497 eventq: *const ble_npl_eventq,
498 func: *const ble_npl_event_fn,
499 args: *const c_void,
500 ) -> i32,
501 >,
502 p_ble_npl_callout_reset: Option<
503 unsafe extern "C" fn(
504 callout: *const ble_npl_callout,
505 time: ble_npl_time_t,
506 ) -> ble_npl_error_t,
507 >,
508 p_ble_npl_callout_stop: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
509 p_ble_npl_callout_deinit: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
510 p_ble_npl_callout_mem_reset: Option<unsafe extern "C" fn(callout: *const ble_npl_callout)>,
511 p_ble_npl_callout_is_active:
512 Option<unsafe extern "C" fn(callout: *const ble_npl_callout) -> bool>,
513 p_ble_npl_callout_get_ticks:
514 Option<unsafe extern "C" fn(callout: *const ble_npl_callout) -> ble_npl_time_t>,
515 p_ble_npl_callout_remaining_ticks:
516 Option<unsafe extern "C" fn(callout: *const ble_npl_callout, time: ble_npl_time_t) -> u32>,
517 p_ble_npl_callout_set_arg:
518 Option<unsafe extern "C" fn(callout: *const ble_npl_callout, arg: *const c_void)>,
519 p_ble_npl_time_get: Option<unsafe extern "C" fn() -> u32>,
520 p_ble_npl_time_ms_to_ticks:
521 Option<unsafe extern "C" fn(ms: u32, p_time: *mut ble_npl_time_t) -> ble_npl_error_t>,
522 p_ble_npl_time_ticks_to_ms:
523 Option<unsafe extern "C" fn(time: ble_npl_time_t, *mut u32) -> ble_npl_error_t>,
524 p_ble_npl_time_ms_to_ticks32: Option<unsafe extern "C" fn(ms: u32) -> ble_npl_time_t>,
525 p_ble_npl_time_ticks_to_ms32: Option<unsafe extern "C" fn(time: ble_npl_time_t) -> u32>,
526 p_ble_npl_time_delay: Option<unsafe extern "C" fn(time: ble_npl_time_t)>,
527 p_ble_npl_hw_set_isr: Option<unsafe extern "C" fn(no: i32, mask: u32)>,
528 p_ble_npl_hw_enter_critical: Option<unsafe extern "C" fn() -> u32>,
529 p_ble_npl_hw_exit_critical: Option<unsafe extern "C" fn(mask: u32)>,
530 p_ble_npl_get_time_forever: Option<unsafe extern "C" fn() -> u32>,
531 p_ble_npl_hw_is_in_critical: Option<unsafe extern "C" fn() -> u8>,
532}
533
534static mut G_NPL_FUNCS: npl_funcs_t = npl_funcs_t {
535 p_ble_npl_os_started: Some(ble_npl_os_started),
536 p_ble_npl_get_current_task_id: Some(ble_npl_get_current_task_id),
537 p_ble_npl_eventq_init: Some(ble_npl_eventq_init),
538 p_ble_npl_eventq_deinit: Some(ble_npl_eventq_deinit),
539 p_ble_npl_eventq_get: Some(ble_npl_eventq_get),
540 p_ble_npl_eventq_put: Some(ble_npl_eventq_put),
541 p_ble_npl_eventq_remove: Some(ble_npl_eventq_remove),
542 p_ble_npl_event_run: Some(ble_npl_event_run),
543 p_ble_npl_eventq_is_empty: Some(ble_npl_eventq_is_empty),
544 p_ble_npl_event_init: Some(ble_npl_event_init),
545 p_ble_npl_event_deinit: Some(ble_npl_event_deinit),
546 p_ble_npl_event_reset: Some(ble_npl_event_reset),
547 p_ble_npl_event_is_queued: Some(ble_npl_event_is_queued),
548 p_ble_npl_event_get_arg: Some(ble_npl_event_get_arg),
549 p_ble_npl_event_set_arg: Some(ble_npl_event_set_arg),
550 p_ble_npl_mutex_init: Some(ble_npl_mutex_init),
551 p_ble_npl_mutex_deinit: Some(ble_npl_mutex_deinit),
552 p_ble_npl_mutex_pend: Some(ble_npl_mutex_pend),
553 p_ble_npl_mutex_release: Some(ble_npl_mutex_release),
554 p_ble_npl_sem_init: Some(ble_npl_sem_init),
555 p_ble_npl_sem_deinit: Some(ble_npl_sem_deinit),
556 p_ble_npl_sem_pend: Some(ble_npl_sem_pend),
557 p_ble_npl_sem_release: Some(ble_npl_sem_release),
558 p_ble_npl_sem_get_count: Some(ble_npl_sem_get_count),
559 p_ble_npl_callout_init: Some(ble_npl_callout_init),
560 p_ble_npl_callout_reset: Some(ble_npl_callout_reset),
561 p_ble_npl_callout_stop: Some(ble_npl_callout_stop),
562 p_ble_npl_callout_deinit: Some(ble_npl_callout_deinit),
563 p_ble_npl_callout_mem_reset: Some(ble_npl_callout_mem_reset),
564 p_ble_npl_callout_is_active: Some(ble_npl_callout_is_active),
565 p_ble_npl_callout_get_ticks: Some(ble_npl_callout_get_ticks),
566 p_ble_npl_callout_remaining_ticks: Some(ble_npl_callout_remaining_ticks),
567 p_ble_npl_callout_set_arg: Some(ble_npl_callout_set_arg),
568 p_ble_npl_time_get: Some(ble_npl_time_get),
569 p_ble_npl_time_ms_to_ticks: Some(ble_npl_time_ms_to_ticks),
570 p_ble_npl_time_ticks_to_ms: Some(ble_npl_time_ticks_to_ms),
571 p_ble_npl_time_ms_to_ticks32: Some(ble_npl_time_ms_to_ticks32),
572 p_ble_npl_time_ticks_to_ms32: Some(ble_npl_time_ticks_to_ms32),
573 p_ble_npl_time_delay: Some(ble_npl_time_delay),
574 p_ble_npl_hw_set_isr: Some(ble_npl_hw_set_isr),
575 p_ble_npl_hw_enter_critical: Some(ble_npl_hw_enter_critical),
576 p_ble_npl_hw_exit_critical: Some(ble_npl_hw_exit_critical),
577 p_ble_npl_get_time_forever: Some(ble_npl_get_time_forever),
578 p_ble_npl_hw_is_in_critical: Some(ble_npl_hw_is_in_critical),
579};
580
581#[repr(C)]
582pub(crate) struct OsiCoexFuncsT {
584 magic: u32,
585 version: u32,
586 coex_wifi_sleep_set: Option<unsafe extern "C" fn(sleep: bool)>,
587 coex_core_ble_conn_dyn_prio_get:
588 Option<unsafe extern "C" fn(low: *mut bool, high: *mut bool) -> i32>,
589 coex_schm_status_bit_set: Option<unsafe extern "C" fn(_type: u32, status: u32)>,
590 coex_schm_status_bit_clear: Option<unsafe extern "C" fn(_type: u32, status: u32)>,
591}
592
593#[allow(unused)]
594static G_COEX_FUNCS: OsiCoexFuncsT = OsiCoexFuncsT {
595 magic: 0xFADEBEAD,
596 version: 0x00010006,
597 coex_wifi_sleep_set: Some(coex_wifi_sleep_set),
598 coex_core_ble_conn_dyn_prio_get: Some(coex_core_ble_conn_dyn_prio_get),
599 coex_schm_status_bit_set: Some(coex_schm_status_bit_set),
600 coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear),
601};
602
603#[allow(unused)]
604unsafe extern "C" fn coex_wifi_sleep_set(_sleep: bool) {
605 todo!()
606}
607
608#[allow(unused)]
609unsafe extern "C" fn coex_core_ble_conn_dyn_prio_get(_low: *mut bool, _high: *mut bool) -> i32 {
610 todo!()
611}
612
613#[allow(unused)]
614unsafe extern "C" fn coex_schm_status_bit_set(_type: u32, _status: u32) {
615 trace!("coex_schm_status_bit_set is an empty stub");
616}
617
618#[allow(unused)]
619unsafe extern "C" fn coex_schm_status_bit_clear(_type: u32, _status: u32) {
620 trace!("coex_schm_status_bit_clear is an empty stub");
621}
622
623unsafe extern "C" fn ble_npl_hw_is_in_critical() -> u8 {
624 todo!()
625}
626
627unsafe extern "C" fn ble_npl_get_time_forever() -> u32 {
628 trace!("ble_npl_get_time_forever");
629 TIME_FOREVER
630}
631
632unsafe extern "C" fn ble_npl_hw_exit_critical(mask: u32) {
633 trace!("ble_npl_hw_exit_critical {}", mask);
634 unsafe {
635 let token = esp_sync::RestoreState::new(mask);
636 crate::ESP_RADIO_LOCK.release(token);
637 }
638}
639
640unsafe extern "C" fn ble_npl_hw_enter_critical() -> u32 {
641 trace!("ble_npl_hw_enter_critical");
642 unsafe { crate::ESP_RADIO_LOCK.acquire().inner() }
643}
644
645unsafe extern "C" fn ble_npl_hw_set_isr(_no: i32, _mask: u32) {
646 todo!()
647}
648
649unsafe extern "C" fn ble_npl_time_delay(time: ble_npl_time_t) {
650 let time = blob_ticks_to_micros(time);
651 crate::preempt::usleep(time);
652}
653
654unsafe extern "C" fn ble_npl_time_ticks_to_ms32(time: ble_npl_time_t) -> u32 {
655 trace!("ble_npl_time_ticks_to_ms32 {}", time);
656 blob_ticks_to_millis(time)
657}
658
659unsafe extern "C" fn ble_npl_time_ms_to_ticks32(ms: u32) -> ble_npl_time_t {
660 trace!("ble_npl_time_ms_to_ticks32 {}", ms);
661 millis_to_blob_ticks(ms)
662}
663
664unsafe extern "C" fn ble_npl_time_ticks_to_ms(
665 time: ble_npl_time_t,
666 p_ms: *mut u32,
667) -> ble_npl_error_t {
668 trace!("ble_npl_time_ticks_to_ms {}", time);
669 unsafe { *p_ms = blob_ticks_to_millis(time) };
670 0
671}
672
673unsafe extern "C" fn ble_npl_time_ms_to_ticks(
674 ms: u32,
675 p_time: *mut ble_npl_time_t,
676) -> ble_npl_error_t {
677 trace!("ble_npl_time_ms_to_ticks {}", ms);
678 unsafe { *p_time = millis_to_blob_ticks(ms) };
679 0
680}
681
682unsafe extern "C" fn ble_npl_time_get() -> u32 {
683 trace!("ble_npl_time_get");
684 Instant::now().duration_since_epoch().as_millis() as u32
685}
686
687unsafe extern "C" fn ble_npl_callout_set_arg(
688 _callout: *const ble_npl_callout,
689 _arg: *const c_void,
690) {
691 todo!()
692}
693
694unsafe extern "C" fn ble_npl_callout_remaining_ticks(
695 _callout: *const ble_npl_callout,
696 _time: ble_npl_time_t,
697) -> u32 {
698 todo!()
699}
700
701unsafe extern "C" fn ble_npl_callout_get_ticks(_callout: *const ble_npl_callout) -> ble_npl_time_t {
702 todo!()
703}
704
705unsafe extern "C" fn ble_npl_callout_is_active(callout: *const ble_npl_callout) -> bool {
706 debug!(
707 "Missing real implementation: ble_npl_callout_is_active {:?}",
708 callout
709 );
710
711 assert!(unsafe { (*callout).dummy != 0 });
712
713 unsafe {
714 let co = (*callout).dummy as *mut Callout;
715 compat::timer_compat::compat_timer_is_active(&raw mut (*co).timer_handle)
716 }
717}
718
719unsafe extern "C" fn ble_npl_callout_mem_reset(callout: *const ble_npl_callout) {
720 trace!("ble_npl_callout_mem_reset");
721 unsafe {
722 ble_npl_callout_stop(callout);
723 }
724}
725
726unsafe extern "C" fn ble_npl_callout_deinit(callout: *const ble_npl_callout) {
727 trace!("ble_npl_callout_deinit");
728 unsafe {
729 ble_npl_callout_stop(callout);
730 }
731}
732
733unsafe extern "C" fn ble_npl_callout_stop(callout: *const ble_npl_callout) {
734 trace!("ble_npl_callout_stop {:?}", callout);
735
736 assert!(unsafe { (*callout).dummy != 0 });
737
738 unsafe {
739 let co = (*callout).dummy as *mut Callout;
740 compat::timer_compat::compat_timer_disarm(&raw mut (*co).timer_handle);
742 }
743}
744
745unsafe extern "C" fn ble_npl_callout_reset(
746 callout: *const ble_npl_callout,
747 time: ble_npl_time_t,
748) -> ble_npl_error_t {
749 trace!("ble_npl_callout_reset {:?} {}", callout, time);
750
751 let co = unsafe { (*callout).dummy } as *mut Callout;
752 unsafe {
753 compat::timer_compat::compat_timer_arm(
755 &raw mut (*co).timer_handle,
756 blob_ticks_to_millis(time),
757 false,
758 );
759 }
760 0
761}
762
763unsafe extern "C" fn ble_npl_sem_get_count(_sem: *const ble_npl_sem) -> u16 {
764 todo!()
765}
766
767unsafe extern "C" fn ble_npl_sem_release(_sem: *const ble_npl_sem) -> ble_npl_error_t {
768 todo!()
769}
770
771unsafe extern "C" fn ble_npl_sem_pend(
772 _sem: *const ble_npl_sem,
773 _time: ble_npl_time_t,
774) -> ble_npl_error_t {
775 todo!()
776}
777
778unsafe extern "C" fn ble_npl_sem_deinit(_sem: *const ble_npl_sem) -> ble_npl_error_t {
779 todo!()
780}
781
782unsafe extern "C" fn ble_npl_sem_init(_sem: *const ble_npl_sem, _val: u16) -> ble_npl_error_t {
783 todo!()
784}
785
786unsafe extern "C" fn ble_npl_mutex_release(_mutex: *const ble_npl_mutex) -> ble_npl_error_t {
787 todo!()
788}
789
790unsafe extern "C" fn ble_npl_mutex_pend(
791 _mutex: *const ble_npl_mutex,
792 _time: ble_npl_time_t,
793) -> ble_npl_error_t {
794 todo!()
795}
796
797unsafe extern "C" fn ble_npl_mutex_deinit(_mutex: *const ble_npl_mutex) -> ble_npl_error_t {
798 todo!()
799}
800
801unsafe extern "C" fn ble_npl_event_set_arg(event: *const ble_npl_event, arg: *const c_void) {
802 trace!("ble_npl_event_set_arg {:?} {:?}", event, arg);
803
804 let evt = unsafe { (*event).dummy } as *mut Event;
805 assert!(!evt.is_null());
806
807 unsafe {
808 (*evt).ev_arg_ptr = arg;
809 }
810}
811
812unsafe extern "C" fn ble_npl_event_get_arg(event: *const ble_npl_event) -> *const c_void {
813 trace!("ble_npl_event_get_arg {:?}", event);
814
815 unsafe {
816 let evt = (*event).dummy as *mut Event;
817 assert!(!evt.is_null());
818
819 let arg_ptr = (*evt).ev_arg_ptr;
820
821 trace!("returning arg {:x}", arg_ptr as usize);
822
823 arg_ptr
824 }
825}
826
827unsafe extern "C" fn ble_npl_event_is_queued(event: *const ble_npl_event) -> bool {
828 trace!("ble_npl_event_is_queued {:?}", event);
829
830 let evt = unsafe { (*event).dummy } as *mut Event;
831 assert!(!evt.is_null());
832
833 unsafe { (*evt).queued }
834}
835
836unsafe extern "C" fn ble_npl_event_reset(event: *const ble_npl_event) {
837 trace!("ble_npl_event_reset {:?}", event);
838
839 let evt = unsafe { (*event).dummy } as *mut Event;
840 assert!(!evt.is_null());
841
842 unsafe { (*evt).queued = false }
843}
844
845unsafe extern "C" fn ble_npl_event_deinit(event: *const ble_npl_event) {
846 trace!("ble_npl_event_deinit {:?}", event);
847
848 let event = event as *mut ble_npl_event;
849 let evt = unsafe { (*event).dummy } as *mut Event;
850 assert!(!evt.is_null());
851
852 unsafe {
853 crate::compat::malloc::free(evt.cast());
854 }
855
856 unsafe {
857 (*event).dummy = 0;
858 }
859}
860
861unsafe extern "C" fn ble_npl_event_init(
862 event: *const ble_npl_event,
863 func: *const ble_npl_event_fn,
864 arg: *const c_void,
865) {
866 trace!("ble_npl_event_init {:?} {:?} {:?}", event, func, arg);
867
868 if unsafe { (*event).dummy } == 0 {
869 unsafe {
870 let evt = crate::compat::malloc::calloc(1, core::mem::size_of::<Event>()) as *mut Event;
871
872 (*evt).event_fn_ptr = func;
873 (*evt).ev_arg_ptr = arg;
874 (*evt).queued = false;
875
876 let event = event.cast_mut();
877 (*event).dummy = evt as i32;
878 }
879 }
880}
881
882unsafe extern "C" fn ble_npl_eventq_is_empty(queue: *mut ble_npl_eventq) -> bool {
883 trace!("ble_npl_eventq_is_empty {:?}", queue);
884 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
885
886 queue::queue_messages_waiting(wrapper.dummy as _) == 0
887}
888
889unsafe extern "C" fn ble_npl_event_run(event: *const ble_npl_event) {
890 trace!("ble_npl_event_run {:?}", event);
891
892 let evt = unsafe { (*event).dummy } as *mut Event;
893 assert!(!evt.is_null());
894
895 trace!(
896 "info {:?} with arg {:x}",
897 unsafe { (*evt).event_fn_ptr },
898 event as u32
899 );
900 unsafe {
901 let func: unsafe extern "C" fn(u32) = transmute((*evt).event_fn_ptr);
902 func(event as u32);
903 }
904
905 trace!("ble_npl_event_run done");
906}
907
908unsafe extern "C" fn ble_npl_eventq_remove(
909 queue: *mut ble_npl_eventq,
910 event: *const ble_npl_event,
911) {
912 trace!("ble_npl_eventq_remove {:?} {:?}", queue, event);
913
914 unsafe {
915 let evt = (*event).dummy as *mut Event;
916 assert!(!evt.is_null());
917
918 if !(*evt).queued {
919 return;
920 }
921
922 let wrapper = unwrap!(queue.as_mut(), "queue wrapper is null");
923 queue::queue_remove(wrapper.dummy as _, (&raw const event).cast());
924
925 (*evt).queued = false;
926 }
927}
928
929unsafe extern "C" fn ble_npl_eventq_put(queue: *mut ble_npl_eventq, event: *const ble_npl_event) {
930 trace!("ble_npl_eventq_put {:?} {:?}", queue, event);
931
932 let evt = unsafe { (*event).dummy } as *mut Event;
933 assert!(!evt.is_null());
934
935 if unsafe { (*evt).queued } {
936 trace!("Event already queued, skipping put");
937 return;
938 }
939
940 unsafe {
941 (*evt).queued = true;
942 }
943
944 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
945
946 queue::queue_send_to_back(
948 wrapper.dummy as _,
949 (&raw const event).cast(),
950 OSI_FUNCS_TIME_BLOCKING,
951 );
952}
953
954unsafe extern "C" fn ble_npl_eventq_get(
955 queue: *mut ble_npl_eventq,
956 timeout: ble_npl_time_t,
957) -> *const ble_npl_event {
958 trace!("ble_npl_eventq_get {:?} {}", queue, timeout);
959
960 let mut evt = core::ptr::null_mut::<ble_npl_event>();
961 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
962
963 if queue::queue_receive(
964 wrapper.dummy as _,
965 (&raw mut evt).cast(),
966 blob_ticks_to_micros(timeout),
967 ) == 1
968 {
969 trace!("got {:x}", evt as usize);
970 unsafe {
971 let evt = (*evt).dummy as *mut Event;
972 (*evt).queued = false;
973 }
974 }
975
976 evt.cast_const()
977}
978
979unsafe extern "C" fn ble_npl_eventq_init(queue: *mut ble_npl_eventq) {
980 trace!("ble_npl_eventq_init {:?}", queue);
981
982 let queue_ptr = queue::queue_create(EVENT_QUEUE_SIZE as _, core::mem::size_of::<usize>() as _);
983
984 unsafe {
985 (*queue).dummy = queue_ptr as i32;
986 }
987}
988
989unsafe extern "C" fn ble_npl_eventq_deinit(queue: *mut ble_npl_eventq) {
990 trace!("ble_npl_eventq_deinit {:?}", queue);
991
992 let wrapper = unwrap!(unsafe { queue.as_mut() }, "queue wrapper is null");
993 queue::queue_delete(wrapper.dummy as _);
994 wrapper.dummy = 0;
995}
996
997unsafe extern "C" fn ble_npl_callout_init(
998 callout: *const ble_npl_callout,
999 eventq: *const ble_npl_eventq,
1000 func: *const ble_npl_event_fn,
1001 args: *const c_void,
1002) -> i32 {
1003 trace!(
1004 "ble_npl_callout_init {:?} {:?} {:?} {:?}",
1005 callout, eventq, func, args
1006 );
1007
1008 if unsafe { (*callout).dummy } == 0 {
1009 let callout = callout.cast_mut();
1010
1011 unsafe {
1012 let new_callout =
1013 crate::compat::malloc::calloc(1, core::mem::size_of::<Callout>()) as *mut Callout;
1014 ble_npl_event_init(addr_of_mut!((*new_callout).events), func, args);
1015 (*callout).dummy = new_callout as i32;
1016
1017 crate::compat::timer_compat::compat_timer_setfn(
1018 addr_of_mut!((*new_callout).timer_handle),
1019 callout_timer_callback_wrapper,
1020 callout as *mut c_void,
1021 );
1022 }
1023 }
1024
1025 0
1026}
1027
1028unsafe extern "C" fn callout_timer_callback_wrapper(arg: *mut c_void) {
1029 trace!("callout_timer_callback_wrapper {:?}", arg);
1030 let co = unsafe { (*(arg as *mut ble_npl_callout)).dummy } as *mut Callout;
1031
1032 unsafe {
1033 if !(*co).eventq.is_null() {
1034 ble_npl_eventq_put((*co).eventq.cast_mut(), addr_of!((*co).events));
1035 } else {
1036 ble_npl_event_run(addr_of!((*co).events));
1037 }
1038 }
1039}
1040
1041unsafe extern "C" fn ble_npl_mutex_init(_mutex: *const ble_npl_mutex) -> u32 {
1042 todo!()
1043}
1044
1045unsafe extern "C" fn ble_npl_get_current_task_id() -> *const c_void {
1046 todo!()
1047}
1048
1049unsafe extern "C" fn ble_npl_os_started() -> bool {
1050 true
1051}
1052
1053#[repr(C)]
1054pub(crate) struct BleNplCountInfoT {
1056 evt_count: u16,
1057 evtq_count: u16,
1058 co_count: u16,
1059 sem_count: u16,
1060 mutex_count: u16,
1061}
1062
1063pub(crate) fn ble_init(config: &Config) -> PhyInitGuard<'static> {
1064 let phy_init_guard;
1065 unsafe {
1066 (*addr_of_mut!(HCI_OUT_COLLECTOR)).write(HciOutCollector::new());
1067
1068 #[allow(static_mut_refs)]
1070 #[cfg(all(feature = "print-logs-from-driver", esp32c2))]
1071 {
1072 unsafe extern "C" {
1073 static mut g_ble_plf_log_level: u32;
1074 }
1075
1076 debug!("g_ble_plf_log_level = {}", g_ble_plf_log_level);
1077 g_ble_plf_log_level = 10;
1078 }
1079
1080 self::ble_os_adapter_chip_specific::ble_rtc_clk_init();
1081
1082 let cfg = ble_os_adapter_chip_specific::create_ble_config(config);
1083
1084 let res = esp_register_ext_funcs(&G_OSI_FUNCS as *const ExtFuncsT);
1085 assert!(res == 0, "esp_register_ext_funcs returned {}", res);
1086
1087 #[cfg(esp32c2)]
1088 {
1089 debug!("Init esp_ble_rom_func_ptr_init_all");
1090 unsafe extern "C" {
1091 fn esp_ble_rom_func_ptr_init_all() -> i32;
1092 }
1093 let res = esp_ble_rom_func_ptr_init_all();
1094 assert!(res == 0, "esp_ble_rom_func_ptr_init_all returned {}", res);
1095 }
1096
1097 #[cfg(feature = "coex")]
1098 {
1099 let res = crate::wifi::coex_init();
1100 assert!(res == 0, "coex_init failed");
1101 }
1102
1103 ble_os_adapter_chip_specific::bt_periph_module_enable();
1104
1105 ble_os_adapter_chip_specific::disable_sleep_mode();
1106
1107 let res = esp_register_npl_funcs(core::ptr::addr_of!(G_NPL_FUNCS));
1108 assert!(res == 0, "esp_register_npl_funcs returned {}", res);
1109
1110 let npl_info = BleNplCountInfoT {
1111 evt_count: 0,
1112 evtq_count: 0,
1113 co_count: 0,
1114 sem_count: 0,
1115 mutex_count: 0,
1116 };
1117 #[cfg(esp32c2)]
1118 let res = ble_get_npl_element_info(
1119 &cfg as *const esp_bt_controller_config_t,
1120 &npl_info as *const BleNplCountInfoT,
1121 );
1122 #[cfg(not(esp32c2))]
1123 let res = r_ble_get_npl_element_info(
1124 &cfg as *const esp_bt_controller_config_t,
1125 &npl_info as *const BleNplCountInfoT,
1126 );
1127 assert!(res == 0, "ble_get_npl_element_info returned {}", res);
1128
1129 #[cfg(esp32c2)]
1132 {
1133 let ret = os_msys_buf_alloc();
1135 assert!(ret, "os_msys_buf_alloc failed");
1136
1137 os_msys_init();
1138 }
1139
1140 phy_init_guard = esp_phy::enable_phy();
1141
1142 bt_bb_v2_init_cmplx(1);
1144
1145 coex_pti_v2();
1146
1147 #[cfg(feature = "coex")]
1148 {
1149 let rc = ble_osi_coex_funcs_register(&G_COEX_FUNCS as *const OsiCoexFuncsT);
1150 assert!(rc == 0, "ble_osi_coex_funcs_register returned {}", rc);
1151 }
1152
1153 #[cfg(not(esp32c2))]
1154 {
1155 unsafe extern "C" {
1156 fn esp_ble_register_bb_funcs() -> i32;
1157 }
1158 let res = esp_ble_register_bb_funcs();
1159 assert!(res == 0, "esp_ble_register_bb_funcs returned {}", res);
1160 }
1161
1162 #[cfg(esp32c2)]
1163 let res = ble_controller_init(&cfg as *const esp_bt_controller_config_t);
1164 #[cfg(not(esp32c2))]
1165 let res = r_ble_controller_init(&cfg as *const esp_bt_controller_config_t);
1166
1167 assert!(res == 0, "ble_controller_init returned {}", res);
1168
1169 #[cfg(not(esp32c2))]
1170 {
1171 unsafe extern "C" {
1172 fn r_esp_ble_msys_init(
1173 msys_size1: u16,
1174 msys_size2: u16,
1175 msys_cnt1: u16,
1176 msys_cnt2: u16,
1177 from_heap: u8,
1178 ) -> i32;
1179
1180 fn base_stack_initEnv() -> i32;
1181 fn conn_stack_initEnv() -> i32;
1182 fn adv_stack_initEnv() -> i32;
1183 fn extAdv_stack_initEnv() -> i32;
1184 fn sync_stack_initEnv() -> i32;
1185
1186 fn base_stack_enable() -> i32;
1187 fn adv_stack_enable() -> i32;
1188 fn extAdv_stack_enable() -> i32;
1189 fn scan_stack_enable() -> i32;
1190 fn sync_stack_enable() -> i32;
1191 }
1192
1193 let res = base_stack_initEnv();
1194 assert!(res == 0, "base_stack_initEnv returned {}", res);
1195
1196 let res = adv_stack_initEnv();
1197 assert!(res == 0, "adv_stack_initEnv returned {}", res);
1198
1199 let res = extAdv_stack_initEnv();
1200 assert!(res == 0, "extAdv_stack_initEnv returned {}", res);
1201
1202 #[cfg(not(esp32c2))]
1203 {
1204 let res = scan_stack_initEnv();
1205 assert!(res == 0, "scan_stack_initEnv returned {}", res);
1206 }
1207
1208 let res = conn_stack_initEnv();
1209 assert!(res == 0, "conn_stack_initEnv returned {}", res);
1210
1211 let res = sync_stack_initEnv();
1212 assert!(res == 0, "sync_stack_initEnv returned {}", res);
1213
1214 let res = r_esp_ble_msys_init(256, 320, 12, 24, 1);
1215 assert!(res == 0, "esp_ble_msys_init returned {}", res);
1216
1217 let res = base_stack_enable();
1218 assert!(res == 0, "base_stack_enable returned {}", res);
1219
1220 let res = adv_stack_enable();
1221 assert!(res == 0, "adv_stack_enable returned {}", res);
1222
1223 let res = extAdv_stack_enable();
1224 assert!(res == 0, "extAdv_stack_enable returned {}", res);
1225
1226 let res = scan_stack_enable();
1227 assert!(res == 0, "scan_stack_enable returned {}", res);
1228
1229 let res = sync_stack_enable();
1230 assert!(res == 0, "sync_stack_enable returned {}", res);
1231 }
1232
1233 #[cfg(feature = "coex")]
1234 crate::sys::include::coex_enable();
1235
1236 let mut mac = [0u8; 6];
1237 crate::common_adapter::read_mac(mac.as_mut_ptr(), 2);
1238 mac.reverse();
1239
1240 #[cfg(esp32c2)]
1241 esp_ble_ll_set_public_addr(&mac as *const u8);
1242 #[cfg(not(esp32c2))]
1243 r_esp_ble_ll_set_public_addr(&mac as *const u8);
1244
1245 unsafe extern "C" {
1246 fn r_ble_hci_trans_init(m: u8);
1247 }
1248 r_ble_hci_trans_init(0);
1249
1250 r_ble_hci_trans_cfg_hs(
1251 Some(ble_hs_hci_rx_evt),
1252 core::ptr::null(),
1253 Some(ble_hs_rx_data),
1254 core::ptr::null(),
1255 );
1256
1257 #[cfg(esp32c2)]
1258 let res = ble_controller_enable(1); #[cfg(not(esp32c2))]
1260 let res = r_ble_controller_enable(1); assert!(res == 0, "ble_controller_enable returned {}", res);
1262 }
1263
1264 #[cfg(rng_trng_supported)]
1266 unsafe {
1267 esp_hal::rng::TrngSource::increase_entropy_source_counter()
1268 };
1269
1270 debug!("The ble_controller_init was initialized");
1271 phy_init_guard
1272}
1273
1274pub(crate) fn ble_deinit() {
1275 #[cfg(rng_trng_supported)]
1276 esp_hal::rng::TrngSource::decrease_entropy_source_counter(unsafe {
1277 esp_hal::Internal::conjure()
1278 });
1279
1280 #[cfg(not(esp32c2))]
1281 unsafe extern "C" {
1282 fn base_stack_deinitEnv() -> i32;
1283 fn conn_stack_deinitEnv() -> i32;
1284 fn adv_stack_deinitEnv() -> i32;
1285 fn extAdv_stack_deinitEnv() -> i32;
1286 fn sync_stack_deinitEnv() -> i32;
1287
1288 fn base_stack_disable() -> i32;
1289 fn adv_stack_disable() -> i32;
1290 fn extAdv_stack_disable() -> i32;
1291 fn scan_stack_disable() -> i32;
1292 fn sync_stack_disable() -> i32;
1293 }
1294
1295 #[cfg(esp32c2)]
1296 unsafe extern "C" {
1297 fn ble_controller_disable();
1298 }
1299
1300 unsafe {
1301 npl::r_ble_hci_trans_cfg_hs(None, core::ptr::null(), None, core::ptr::null());
1303
1304 #[cfg(not(esp32c2))]
1305 {
1306 npl::r_ble_controller_disable();
1307 sync_stack_disable();
1308 scan_stack_disable();
1309 extAdv_stack_disable();
1310 adv_stack_disable();
1311 base_stack_disable();
1312 conn_stack_deinitEnv();
1313 sync_stack_deinitEnv();
1314 scan_stack_deinitEnv();
1315 extAdv_stack_deinitEnv();
1316 adv_stack_deinitEnv();
1317 base_stack_deinitEnv();
1318 }
1319
1320 #[cfg(esp32c2)]
1321 {
1322 ble_controller_disable();
1323 }
1324
1325 #[cfg(not(esp32c2))]
1326 let res = npl::r_ble_controller_deinit();
1327
1328 #[cfg(esp32c2)]
1329 let res = npl::ble_controller_deinit();
1330
1331 assert!(res == 0, "ble_controller_deinit returned {}", res);
1332
1333 npl::esp_unregister_npl_funcs();
1334
1335 npl::esp_unregister_ext_funcs();
1336 }
1337}
1338
1339#[cfg(esp32c2)]
1340fn os_msys_buf_alloc() -> bool {
1341 unsafe {
1342 OS_MSYS_INIT_1_DATA = crate::compat::malloc::calloc(
1343 1,
1344 core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_1_MEMPOOL_SIZE,
1345 ) as *mut u32;
1346 OS_MSYS_INIT_2_DATA = crate::compat::malloc::calloc(
1347 1,
1348 core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_2_MEMPOOL_SIZE,
1349 ) as *mut u32;
1350
1351 !(OS_MSYS_INIT_1_DATA.is_null() || OS_MSYS_INIT_2_DATA.is_null())
1352 }
1353}
1354
1355#[cfg(esp32c2)]
1356fn os_msys_init() {
1357 static MSYS1: &[u8] = b"msys_1\0";
1358 static MSYS2: &[u8] = b"msys_2\0";
1359
1360 unsafe {
1361 r_os_msys_reset();
1362
1363 let rc = r_mem_init_mbuf_pool(
1364 OS_MSYS_INIT_1_DATA as *const c_void,
1365 addr_of!(OS_MSYS_INIT_1_MEMPOOL),
1366 addr_of!(OS_MSYS_INIT_1_MBUF_POOL),
1367 OS_MSYS_1_BLOCK_COUNT,
1368 SYSINIT_MSYS_1_MEMBLOCK_SIZE,
1369 MSYS1 as *const _ as *const u8,
1370 );
1371 if rc != 0 {
1372 panic!("r_mem_init_mbuf_pool failed");
1373 }
1374
1375 let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_1_MBUF_POOL));
1376 if rc != 0 {
1377 panic!("r_os_msys_register failed");
1378 }
1379
1380 let rc = r_mem_init_mbuf_pool(
1381 OS_MSYS_INIT_2_DATA as *const c_void,
1382 addr_of!(OS_MSYS_INIT_2_MEMPOOL),
1383 addr_of!(OS_MSYS_INIT_2_MBUF_POOL),
1384 OS_MSYS_2_BLOCK_COUNT,
1385 SYSINIT_MSYS_2_MEMBLOCK_SIZE,
1386 MSYS2 as *const _ as *const u8,
1387 );
1388 if rc != 0 {
1389 panic!("r_mem_init_mbuf_pool failed");
1390 }
1391
1392 let rc = r_os_msys_register(addr_of!(OS_MSYS_INIT_2_MBUF_POOL));
1393 if rc != 0 {
1394 panic!("r_os_msys_register failed");
1395 }
1396 }
1397}
1398
1399unsafe extern "C" fn ble_hs_hci_rx_evt(cmd: *const u8, arg: *const c_void) -> i32 {
1400 trace!("ble_hs_hci_rx_evt {:?} {:?}", cmd, arg);
1401 trace!("$ cmd = {:x}", unsafe { *cmd });
1402 trace!("$ len = {:x}", unsafe { *(cmd.offset(1)) });
1403
1404 let event = unsafe { *cmd };
1405 let len = unsafe { *(cmd.offset(1)) } as usize;
1406 let payload = unsafe { core::slice::from_raw_parts(cmd.offset(2), len) };
1407 trace!("$ pld = {:?}", payload);
1408
1409 super::BT_STATE.with(|state| {
1410 let mut data = [0u8; 256];
1411
1412 data[0] = 0x04; data[1] = event;
1414 data[2] = len as u8;
1415 data[3..][..len].copy_from_slice(payload);
1416
1417 state.rx_queue.push_back(ReceivedPacket {
1418 data: Box::from(&data[..len + 3]),
1419 });
1420
1421 dump_packet_info(&data[..(len + 3)]);
1422 });
1423
1424 unsafe {
1425 r_ble_hci_trans_buf_free(cmd);
1426 }
1427
1428 crate::ble::controller::hci_read_data_available();
1429
1430 0
1431}
1432
1433unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) -> i32 {
1434 trace!("ble_hs_rx_data {:?} {:?}", om, arg);
1435
1436 let data_ptr = unsafe { (*om).om_data };
1437 let len = unsafe { (*om).om_len };
1438 let data_slice = unsafe { core::slice::from_raw_parts(data_ptr, len as usize) };
1439
1440 super::BT_STATE.with(|state| {
1441 let mut data = [0u8; 256];
1442
1443 data[0] = 0x02; data[1..][..data_slice.len()].copy_from_slice(data_slice);
1445
1446 state.rx_queue.push_back(ReceivedPacket {
1447 data: Box::from(&data[..data_slice.len() + 1]),
1448 });
1449
1450 super::dump_packet_info(&data[..(len + 1) as usize]);
1451 });
1452
1453 unsafe {
1454 r_os_mbuf_free_chain(om as *mut _);
1455 }
1456
1457 crate::ble::controller::hci_read_data_available();
1458
1459 0
1460}
1461
1462#[instability::unstable]
1464pub fn send_hci(data: &[u8]) {
1465 let hci_out = unsafe { (*addr_of_mut!(HCI_OUT_COLLECTOR)).assume_init_mut() };
1466 hci_out.push(data);
1467
1468 if hci_out.is_ready() {
1469 let packet = hci_out.packet();
1470
1471 unsafe {
1472 const DATA_TYPE_COMMAND: u8 = 1;
1473 const DATA_TYPE_ACL: u8 = 2;
1474
1475 dump_packet_info(packet);
1476
1477 super::BT_STATE.with(|_state| {
1478 if packet[0] == DATA_TYPE_COMMAND {
1479 let cmd = r_ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD);
1480 core::ptr::copy_nonoverlapping(
1481 &packet[1] as *const _ as *mut u8, cmd as *mut u8,
1483 packet.len() - 1,
1484 );
1485
1486 let res = r_ble_hci_trans_hs_cmd_tx(cmd);
1487
1488 if res != 0 {
1489 warn!("ble_hci_trans_hs_cmd_tx res == {}", res);
1490 }
1491 } else if packet[0] == DATA_TYPE_ACL {
1492 let om = r_os_msys_get_pkthdr(
1493 packet.len() as u16,
1494 ACL_DATA_MBUF_LEADINGSPACE as u16,
1495 );
1496
1497 let res =
1498 r_os_mbuf_append(om, packet.as_ptr().offset(1), (packet.len() - 1) as u16);
1499 if res != 0 {
1500 panic!("r_os_mbuf_append returned {}", res);
1501 }
1502
1503 *((*om).om_data as *mut u8).offset(1) = 0;
1506
1507 let res = r_ble_hci_trans_hs_acl_tx(om);
1508 if res != 0 {
1509 panic!("ble_hci_trans_hs_acl_tx returned {}", res);
1510 }
1511 trace!("ACL tx done");
1512 }
1513 });
1514 }
1515
1516 hci_out.reset();
1517 }
1518}