1use procmacros::BuilderLite;
2
3use super::*;
4#[cfg(multi_core)]
5use crate::hal::system::Cpu;
6use crate::{
7 ble::InvalidConfigError,
8 common_adapter::*,
9 hal::{interrupt::Priority, peripherals::BT},
10 interrupt_dispatch::Handler,
11};
12
13static ISR_INTERRUPT_5: Handler = Handler::new();
14static ISR_INTERRUPT_8: Handler = Handler::new();
15
16#[repr(C)]
17pub(super) struct osi_funcs_s {
18 magic: u32,
19 version: u32,
20 interrupt_alloc: Option<
21 unsafe extern "C" fn(i32, i32, extern "C" fn(*const ()), *const (), *mut *const ()) -> i32,
22 >,
23 interrupt_free: Option<unsafe extern "C" fn(*const ()) -> i32>,
24 interrupt_handler_set: Option<unsafe extern "C" fn(i32, extern "C" fn(*const ()), *const ())>,
25 interrupt_disable: Option<unsafe extern "C" fn()>,
26 interrupt_restore: Option<unsafe extern "C" fn()>,
27 task_yield: Option<unsafe extern "C" fn()>,
28 task_yield_from_isr: Option<unsafe extern "C" fn()>,
29 semphr_create: Option<unsafe extern "C" fn(u32, u32) -> *mut c_void>,
30 semphr_delete: Option<unsafe extern "C" fn(*mut c_void)>,
31 semphr_take_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut bool) -> i32>,
32 semphr_give_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut bool) -> i32>,
33 semphr_take: Option<unsafe extern "C" fn(*mut c_void, u32) -> i32>,
34 semphr_give: Option<unsafe extern "C" fn(*mut c_void) -> i32>,
35 mutex_create: Option<unsafe extern "C" fn() -> *const ()>,
36 mutex_delete: Option<unsafe extern "C" fn(*const ())>,
37 mutex_lock: Option<unsafe extern "C" fn(*const ()) -> i32>,
38 mutex_unlock: Option<unsafe extern "C" fn(*const ()) -> i32>,
39 queue_create: Option<unsafe extern "C" fn(u32, u32) -> *mut c_void>,
40 queue_delete: Option<unsafe extern "C" fn(*mut c_void)>,
41 queue_send: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, u32) -> i32>,
42 queue_send_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> i32>,
43 queue_recv: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, u32) -> i32>,
44 queue_recv_from_isr: Option<unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void) -> i32>,
45 task_create: Option<
46 unsafe extern "C" fn(
47 *mut c_void,
48 *const c_char,
49 u32,
50 *mut c_void,
51 u32,
52 *mut c_void,
53 u32,
54 ) -> i32,
55 >,
56 task_delete: Option<unsafe extern "C" fn(*mut ())>,
57 is_in_isr: Option<unsafe extern "C" fn() -> i32>,
58 cause_sw_intr_to_core: Option<unsafe extern "C" fn(i32, i32) -> i32>,
59 malloc: Option<unsafe extern "C" fn(u32) -> *mut c_void>,
60 malloc_internal: Option<unsafe extern "C" fn(u32) -> *mut c_void>,
61 free: Option<unsafe extern "C" fn(*mut c_void)>,
62 read_efuse_mac: Option<unsafe extern "C" fn(*const ()) -> i32>,
63 srand: Option<unsafe extern "C" fn(u32)>,
64 rand: Option<unsafe extern "C" fn() -> i32>,
65 btdm_lpcycles_2_hus: Option<unsafe extern "C" fn(u32, u32) -> u32>,
66 btdm_hus_2_lpcycles: Option<unsafe extern "C" fn(u32) -> u32>,
67 btdm_sleep_check_duration: Option<unsafe extern "C" fn(i32) -> i32>,
68 btdm_sleep_enter_phase1: Option<unsafe extern "C" fn(i32)>,
69 btdm_sleep_enter_phase2: Option<unsafe extern "C" fn()>,
70 btdm_sleep_exit_phase1: Option<unsafe extern "C" fn()>,
71 btdm_sleep_exit_phase2: Option<unsafe extern "C" fn()>,
72 btdm_sleep_exit_phase3: Option<unsafe extern "C" fn()>,
73 coex_wifi_sleep_set: Option<unsafe extern "C" fn(i32)>,
74 coex_core_ble_conn_dyn_prio_get: Option<unsafe extern "C" fn(*mut i32, *mut i32) -> i32>,
75 coex_schm_register_btdm_callback: Option<unsafe extern "C" fn(*mut c_void) -> i32>,
76 coex_schm_status_bit_set: Option<unsafe extern "C" fn(i32, i32)>,
77 coex_schm_status_bit_clear: Option<unsafe extern "C" fn(i32, i32)>,
78 coex_schm_interval_get: Option<unsafe extern "C" fn() -> u32>,
79 coex_schm_curr_period_get: Option<unsafe extern "C" fn() -> u8>,
80 coex_schm_curr_phase_get: Option<unsafe extern "C" fn() -> *mut c_void>,
81 interrupt_on: Option<unsafe extern "C" fn(i32) -> i32>,
82 interrupt_off: Option<unsafe extern "C" fn(i32) -> i32>,
83 esp_hw_power_down: Option<unsafe extern "C" fn()>,
84 esp_hw_power_up: Option<unsafe extern "C" fn()>,
85 ets_backup_dma_copy: Option<unsafe extern "C" fn(u32, u32, u32, i32)>,
86 ets_delay_us: Option<unsafe extern "C" fn(u32)>,
87 btdm_rom_table_ready: Option<unsafe extern "C" fn()>,
88 coex_bt_wakeup_request: Option<unsafe extern "C" fn()>,
89 coex_bt_wakeup_request_end: Option<unsafe extern "C" fn()>,
90 get_time_us: Option<unsafe extern "C" fn() -> u64>,
91 assert: Option<unsafe extern "C" fn()>,
92}
93
94pub(super) static G_OSI_FUNCS: osi_funcs_s = osi_funcs_s {
95 magic: 0xfadebead,
96 version: 0x0001000A,
97 interrupt_alloc: Some(interrupt_set),
98 interrupt_free: Some(interrupt_clear),
99 interrupt_handler_set: Some(interrupt_handler_set),
100 interrupt_disable: Some(interrupt_disable),
101 interrupt_restore: Some(interrupt_enable),
102 task_yield: Some(task_yield),
103 task_yield_from_isr: Some(task_yield_from_isr),
104 semphr_create: Some(semphr_create),
105 semphr_delete: Some(semphr_delete),
106 semphr_take_from_isr: Some(semphr_take_from_isr),
107 semphr_give_from_isr: Some(semphr_give_from_isr),
108 semphr_take: Some(semphr_take),
109 semphr_give: Some(semphr_give),
110 mutex_create: Some(mutex_create),
111 mutex_delete: Some(mutex_delete),
112 mutex_lock: Some(mutex_lock),
113 mutex_unlock: Some(mutex_unlock),
114 queue_create: Some(queue_create),
115 queue_delete: Some(queue_delete),
116 queue_send: Some(queue_send),
117 queue_send_from_isr: Some(queue_send_from_isr),
118 queue_recv: Some(queue_recv),
119 queue_recv_from_isr: Some(queue_recv_from_isr),
120 task_create: Some(task_create),
121 task_delete: Some(task_delete),
122 is_in_isr: Some(is_in_isr),
123 cause_sw_intr_to_core: None,
124 malloc: Some(crate::ble::malloc),
125 malloc_internal: Some(crate::ble::malloc_internal),
126 free: Some(crate::ble::free),
127 read_efuse_mac: Some(read_efuse_mac),
128 srand: Some(crate::ble::btdm::srand),
129 rand: Some(crate::ble::btdm::rand),
130 btdm_lpcycles_2_hus: Some(btdm_lpcycles_2_hus),
131 btdm_hus_2_lpcycles: Some(btdm_hus_2_lpcycles),
132 btdm_sleep_check_duration: Some(btdm_sleep_check_duration),
133 btdm_sleep_enter_phase1: Some(btdm_sleep_enter_phase1),
134 btdm_sleep_enter_phase2: Some(btdm_sleep_enter_phase2),
135 btdm_sleep_exit_phase1: Some(btdm_sleep_exit_phase1),
136 btdm_sleep_exit_phase2: Some(btdm_sleep_exit_phase2),
137 btdm_sleep_exit_phase3: Some(btdm_sleep_exit_phase3),
138 coex_wifi_sleep_set: Some(coex_wifi_sleep_set),
139 coex_core_ble_conn_dyn_prio_get: Some(coex_core_ble_conn_dyn_prio_get),
140 coex_schm_register_btdm_callback: Some(coex_schm_register_btdm_callback),
141 coex_schm_status_bit_set: Some(coex_schm_status_bit_set),
142 coex_schm_status_bit_clear: Some(coex_schm_status_bit_clear),
143 coex_schm_interval_get: Some(coex_schm_interval_get),
144 coex_schm_curr_period_get: Some(coex_schm_curr_period_get),
145 coex_schm_curr_phase_get: Some(coex_schm_curr_phase_get),
146 interrupt_on: Some(interrupt_on),
147 interrupt_off: Some(interrupt_off),
148 esp_hw_power_down: Some(esp_hw_power_down),
149 esp_hw_power_up: Some(esp_hw_power_up),
150 ets_backup_dma_copy: Some(ets_backup_dma_copy),
151 ets_delay_us: Some(ets_delay_us_wrapper),
152 btdm_rom_table_ready: Some(btdm_rom_table_ready_wrapper),
153 coex_bt_wakeup_request: Some(coex_bt_wakeup_request),
154 coex_bt_wakeup_request_end: Some(coex_bt_wakeup_request_end),
155 get_time_us: Some(get_time_us_wrapper),
156 assert: Some(assert_wrapper),
157};
158
159extern "C" fn get_time_us_wrapper() -> u64 {
160 crate::preempt::now()
162}
163
164extern "C" fn assert_wrapper() {
165 panic!("assert_wrapper called - inspect the logs");
166}
167
168extern_coex_fns! {
169 fn coex_core_ble_conn_dyn_prio_get(low: *mut i32, high: *mut i32) -> i32;
170}
171
172coex_fns! {
173 fn coex_schm_interval_get() -> u32;
174 fn coex_schm_curr_period_get() -> u8;
175 fn coex_schm_curr_phase_get() -> *mut c_void;
176}
177
178extern "C" fn coex_schm_register_btdm_callback(_callback: *mut c_void) -> i32 {
179 trace!("coex_schm_register_btdm_callback");
180
181 cfg_if::cfg_if! {
182 if #[cfg(feature = "coex")] {
183 unsafe {
184 const COEX_SCHM_CALLBACK_TYPE_BT: u32 = 1;
185 coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, _callback)
186 }
187 } else {
188 0
189 }
190 }
191}
192
193extern "C" fn coex_bt_wakeup_request() {
194 trace!("coex_bt_wakeup_request");
195
196 unsafe extern "C" {
197 fn btdm_wakeup_request();
198 }
199
200 unsafe {
201 btdm_wakeup_request();
202 }
203}
204
205extern "C" fn coex_bt_wakeup_request_end() {
206 trace!("coex_bt_wakeup_request_end");
207
208 unsafe extern "C" {
209 fn btdm_in_wakeup_requesting_set(set: bool);
210 }
211
212 unsafe {
213 btdm_in_wakeup_requesting_set(false);
214 }
215}
216
217extern "C" fn ets_delay_us_wrapper(us: u32) {
218 unsafe extern "C" {
219 fn ets_delay_us(us: u32);
220 }
221
222 unsafe {
223 ets_delay_us(us);
224 }
225}
226
227extern "C" fn btdm_rom_table_ready_wrapper() {
228 trace!("btdm_rom_table_ready_wrapper");
229
230 unsafe extern "C" {
231 fn ble_dtm_funcs_reset();
233 fn ble_42_adv_funcs_reset();
234 fn ble_init_funcs_reset();
235 fn ble_con_funcs_reset();
236 fn ble_scan_funcs_reset();
237 fn ble_ext_adv_funcs_reset();
238 fn ble_ext_scan_funcs_reset();
239 fn ble_base_funcs_reset();
240 fn ble_enc_funcs_reset();
241 }
242
243 unsafe {
244 ble_base_funcs_reset();
245 ble_42_adv_funcs_reset();
246 ble_ext_adv_funcs_reset();
247 ble_dtm_funcs_reset();
248 ble_scan_funcs_reset();
249 ble_ext_scan_funcs_reset();
250 ble_enc_funcs_reset();
251 ble_init_funcs_reset();
252 ble_con_funcs_reset();
253 }
254}
255
256unsafe extern "C" {
257 fn btdm_controller_rom_data_init() -> i32;
258}
259
260#[derive(Default, Clone, Copy, Eq, PartialEq)]
262#[cfg_attr(feature = "defmt", derive(defmt::Format))]
263pub enum Antenna {
264 #[default]
266 Antenna0 = 0,
267 Antenna1 = 1,
269}
270
271#[derive(Default, Clone, Copy, Eq, PartialEq)]
273#[cfg_attr(feature = "defmt", derive(defmt::Format))]
274pub enum TxPower {
275 N15,
277 N12,
279 N9,
281 N6,
283 N3,
285 N0,
287 P3,
289 P6,
291 #[default]
293 P9,
294 P12,
296 P15,
298 P18,
300 P20,
302}
303
304#[allow(dead_code)]
305impl TxPower {
306 fn idx(self) -> esp_power_level_t {
307 match self {
308 Self::N15 => esp_power_level_t_ESP_PWR_LVL_N15,
309 Self::N12 => esp_power_level_t_ESP_PWR_LVL_N12,
310 Self::N9 => esp_power_level_t_ESP_PWR_LVL_N9,
311 Self::N6 => esp_power_level_t_ESP_PWR_LVL_N6,
312 Self::N3 => esp_power_level_t_ESP_PWR_LVL_N3,
313 Self::N0 => esp_power_level_t_ESP_PWR_LVL_N0,
314 Self::P3 => esp_power_level_t_ESP_PWR_LVL_P3,
315 Self::P6 => esp_power_level_t_ESP_PWR_LVL_P6,
316 Self::P9 => esp_power_level_t_ESP_PWR_LVL_P9,
317 Self::P12 => esp_power_level_t_ESP_PWR_LVL_P12,
318 Self::P15 => esp_power_level_t_ESP_PWR_LVL_P15,
319 Self::P18 => esp_power_level_t_ESP_PWR_LVL_P18,
320 Self::P20 => esp_power_level_t_ESP_PWR_LVL_P20,
321 }
322 }
323
324 fn dbm(self) -> i8 {
325 match self {
326 Self::N15 => -15,
327 Self::N12 => -12,
328 Self::N9 => -9,
329 Self::N6 => -6,
330 Self::N3 => -3,
331 Self::N0 => 0,
332 Self::P3 => 3,
333 Self::P6 => 6,
334 Self::P9 => 9,
335 Self::P12 => 12,
336 Self::P15 => 15,
337 Self::P18 => 18,
338 Self::P20 => 20,
339 }
340 }
341}
342
343#[derive(Default, Clone, Copy, Eq, PartialEq)]
345#[cfg_attr(feature = "defmt", derive(defmt::Format))]
346pub enum CcaMode {
347 #[default]
349 Disabled = 0,
350 HardwareTriggered = 1,
352 SoftwareTriggered = 2,
354}
355
356#[derive(BuilderLite, Clone, Copy, Eq, PartialEq)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359pub struct Config {
360 task_priority: u8,
362
363 task_stack_size: u16,
365
366 #[cfg(multi_core)]
368 task_cpu: Cpu,
369
370 max_connections: u8,
374
375 qa_test_mode: bool,
377
378 scan_duplicate_list_count: u16,
382
383 scan_duplicate_refresh_period: u16,
387
388 verify_access_address: bool,
396
397 channel_assessment: bool,
399
400 ping: bool,
402
403 default_tx_antenna: Antenna,
405
406 default_rx_antenna: Antenna,
408
409 default_tx_power: TxPower,
411
412 limit_time_for_coded_phy_connection: bool,
414
415 hw_recorrect_en: bool,
417
418 cca_mode: CcaMode,
420
421 cca_threshold: u8,
430
431 data_length_zero_aux: bool,
433
434 dtm: bool,
436
437 encryption: bool,
439
440 connection: bool,
442
443 scan: bool,
445
446 adv: bool,
448
449 disconnect_llcp_conn_update: bool,
451
452 disconnect_llcp_chan_map_update: bool,
454
455 disconnect_llcp_phy_update: bool,
457}
458
459impl Default for Config {
460 fn default() -> Self {
461 Self {
462 task_priority: crate::preempt::max_task_priority()
463 .saturating_sub(2)
464 .min(255) as u8,
465 task_stack_size: 8192, #[cfg(multi_core)]
467 task_cpu: Cpu::ProCpu,
468 max_connections: 6,
469 qa_test_mode: false,
470 scan_duplicate_list_count: 100,
471 scan_duplicate_refresh_period: 0,
472 verify_access_address: true,
473 channel_assessment: false,
474 ping: false,
475 default_tx_antenna: Antenna::default(),
476 default_rx_antenna: Antenna::default(),
477 default_tx_power: TxPower::default(),
478 limit_time_for_coded_phy_connection: false,
479 hw_recorrect_en: AGC_RECORRECT_EN != 0,
480 cca_threshold: 75, cca_mode: CcaMode::default(),
482 data_length_zero_aux: false,
483 dtm: true,
484 encryption: true,
485 connection: true,
486 scan: true,
487 adv: true,
488 disconnect_llcp_conn_update: false,
489 disconnect_llcp_chan_map_update: false,
490 disconnect_llcp_phy_update: false,
491 }
492 }
493}
494
495impl Config {
496 pub(crate) fn validate(&self) -> Result<(), InvalidConfigError> {
497 crate::ble::validate_range!(
498 self,
499 task_priority,
500 0,
501 crate::preempt::max_task_priority().min(255) as u8
502 );
503 crate::ble::validate_range!(self, max_connections, 1, 10);
504 crate::ble::validate_range!(self, scan_duplicate_list_count, 10, 1000);
505 crate::ble::validate_range!(self, scan_duplicate_refresh_period, 0, 1000);
506 crate::ble::validate_range!(self, cca_threshold, 20, 100);
507
508 Ok(())
509 }
510}
511
512pub(crate) fn create_ble_config(config: &Config) -> esp_bt_controller_config_t {
513 esp_bt_controller_config_t {
516 version: 0x02509280,
517 controller_task_stack_size: config.task_stack_size,
518 controller_task_prio: config.task_priority,
519 #[cfg(multi_core)]
520 controller_task_run_cpu: config.task_cpu as u8,
521 #[cfg(single_core)]
522 controller_task_run_cpu: 0,
523
524 bluetooth_mode: esp_bt_mode_t_ESP_BT_MODE_BLE as _,
525
526 ble_max_act: config.max_connections,
527 sleep_mode: 0,
528 sleep_clock: 0,
529 ble_st_acl_tx_buf_nb: 0,
530 ble_hw_cca_check: 0,
531 ble_adv_dup_filt_max: 30,
532 coex_param_en: false,
533 ce_len_type: 0,
534 coex_use_hooks: false,
535 hci_tl_type: 1,
536 hci_tl_funcs: core::ptr::null_mut(),
537 txant_dft: config.default_tx_antenna as u8,
538 rxant_dft: config.default_rx_antenna as u8,
539 txpwr_dft: config.default_tx_power as u8,
540 cfg_mask: CFG_MASK,
541
542 scan_duplicate_mode: 0, scan_duplicate_type: 0,
545 mesh_adv_size: 0,
546
547 normal_adv_size: config.scan_duplicate_list_count,
548 coex_phy_coded_tx_rx_time_limit: if cfg!(feature = "coex") {
549 config.limit_time_for_coded_phy_connection as u8
550 } else {
551 0
552 },
553 hw_target_code: if cfg!(esp32c3) {
554 0x01010000
555 } else {
556 0x02010000
557 },
558 slave_ce_len_min: SLAVE_CE_LEN_MIN_DEFAULT as _,
560 hw_recorrect_en: config.hw_recorrect_en as u8,
561 cca_thresh: config.cca_threshold,
562 dup_list_refresh_period: config.scan_duplicate_refresh_period,
563 scan_backoff_upperlimitmax: 0,
564 ble_50_feat_supp: BT_CTRL_50_FEATURE_SUPPORT != 0,
565 ble_cca_mode: config.cca_mode as u8,
566 ble_chan_ass_en: config.channel_assessment as u8,
567 ble_data_lenth_zero_aux: config.data_length_zero_aux as u8,
568 ble_ping_en: config.ping as u8,
569 ble_llcp_disc_flag: config.disconnect_llcp_conn_update as u8
570 | ((config.disconnect_llcp_chan_map_update as u8) << 1)
571 | ((config.disconnect_llcp_phy_update as u8) << 2),
572 run_in_flash: false,
573 dtm_en: config.dtm,
574 enc_en: config.encryption,
575 qa_test: config.qa_test_mode,
576 connect_en: config.connection,
577 scan_en: config.scan,
578 ble_aa_check: config.verify_access_address,
579 adv_en: config.adv,
580 magic: ESP_BT_CTRL_CONFIG_MAGIC_VAL,
581 }
582}
583
584pub(crate) unsafe extern "C" fn interrupt_on(intr_num: i32) -> i32 {
585 trace!("interrupt_on {}", intr_num);
586
587 0
589}
590
591pub(crate) unsafe extern "C" fn interrupt_off(_intr_num: i32) -> i32 {
592 todo!();
593}
594
595pub(crate) fn btdm_controller_mem_init() {
596 unsafe {
597 btdm_controller_rom_data_init();
598 }
599}
600
601pub(crate) fn bt_periph_module_enable() {
602 }
604
605pub(crate) fn disable_sleep_mode() {
606 }
608
609pub(crate) unsafe extern "C" fn interrupt_set(
612 cpu_no: i32,
613 intr_source: i32,
614 handler: extern "C" fn(*const ()),
615 arg: *const (),
616 ret_handle: *mut *const (),
617) -> i32 {
618 trace!(
619 "interrupt_set {} {} {} {} {}",
620 cpu_no, intr_source, handler as usize, arg as u32, ret_handle as usize,
621 );
622
623 unsafe {
624 interrupt_handler_set(intr_source, handler, arg);
625 }
626
627 0
628}
629
630pub(crate) unsafe extern "C" fn interrupt_clear(_handler: *const ()) -> i32 {
631 todo!();
632}
633
634pub(crate) unsafe extern "C" fn interrupt_handler_set(
635 interrupt_no: i32,
636 func: extern "C" fn(*const ()),
637 arg: *const (),
638) {
639 trace!(
640 "interrupt_handler_set {} {:?} {:?}",
641 interrupt_no, func, arg
642 );
643
644 match interrupt_no {
645 5 => unsafe {
646 ISR_INTERRUPT_5.set(func as *const c_void, arg.cast());
647 #[cfg(esp32c3)]
648 BT::steal().enable_rwbt_interrupt(Priority::Priority1);
649 BT::steal().enable_bb_interrupt(Priority::Priority1);
650 },
651 8 => unsafe {
652 ISR_INTERRUPT_8.set(func as *const c_void, arg.cast());
653 BT::steal().enable_rwble_interrupt(Priority::Priority1);
654 },
655 _ => panic!("Unsupported interrupt number {}", interrupt_no),
656 }
657}
658
659pub(crate) unsafe extern "C" fn coex_wifi_sleep_set(sleep: i32) {
660 trace!(
661 "ignored coex_wifi_sleep_set {} - because original implementation does the same",
662 sleep
663 );
664}
665
666pub(crate) unsafe extern "C" fn esp_hw_power_down() {
667 todo!();
668}
669
670pub(crate) unsafe extern "C" fn esp_hw_power_up() {
671 todo!();
672}
673
674pub(crate) unsafe extern "C" fn ets_backup_dma_copy(
675 _reg: u32,
676 _mem_addr: u32,
677 _num: u32,
678 _to_rem: i32,
679) {
680 todo!();
681}
682
683#[cfg(esp32c3)]
684#[unsafe(no_mangle)]
685#[crate::hal::ram]
686extern "C" fn RWBT() {
687 ISR_INTERRUPT_5.dispatch();
688}
689
690#[unsafe(no_mangle)]
691#[crate::hal::ram]
692extern "C" fn RWBLE() {
693 ISR_INTERRUPT_8.dispatch();
694}
695
696#[unsafe(no_mangle)]
697#[crate::hal::ram]
698extern "C" fn BT_BB() {
699 ISR_INTERRUPT_5.dispatch();
700}
701
702pub(crate) fn shutdown_ble_isr() {
703 unsafe {
704 #[cfg(esp32c3)]
705 BT::steal().disable_rwbt_interrupt_on_all_cores();
706 BT::steal().disable_rwble_interrupt_on_all_cores();
707 BT::steal().disable_bb_interrupt_on_all_cores();
708 }
709}