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