esp_radio/ble/
os_adapter_esp32c3_s3.rs

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    // Get time in microseconds since boot
161    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_cca_funcs_reset();
232        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/// Antenna Selection
261#[derive(Default, Clone, Copy, Eq, PartialEq)]
262#[cfg_attr(feature = "defmt", derive(defmt::Format))]
263pub enum Antenna {
264    /// Use Antenna 0
265    #[default]
266    Antenna0 = 0,
267    /// Use Antenna 1
268    Antenna1 = 1,
269}
270
271/// Transmission Power Level
272#[derive(Default, Clone, Copy, Eq, PartialEq)]
273#[cfg_attr(feature = "defmt", derive(defmt::Format))]
274pub enum TxPower {
275    /// -15 dBm
276    N15,
277    /// -12 dBm
278    N12,
279    /// -9 dBm
280    N9,
281    /// -6 dBm
282    N6,
283    /// -3 dBm
284    N3,
285    /// 0 dBm
286    N0,
287    /// 3 dBm
288    P3,
289    /// 6 dBm
290    P6,
291    /// 9 dBm
292    #[default]
293    P9,
294    /// 12 dBm
295    P12,
296    /// 15 dBm
297    P15,
298    /// 18 dBm
299    P18,
300    /// 20 dBm
301    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/// BLE CCA mode.
344#[derive(Default, Clone, Copy, Eq, PartialEq)]
345#[cfg_attr(feature = "defmt", derive(defmt::Format))]
346pub enum CcaMode {
347    /// Disabled
348    #[default]
349    Disabled          = 0,
350    /// Hardware Triggered
351    HardwareTriggered = 1,
352    /// Software Triggered (experimental)
353    SoftwareTriggered = 2,
354}
355
356/// Bluetooth controller configuration.
357#[derive(BuilderLite, Clone, Copy, Eq, PartialEq)]
358#[cfg_attr(feature = "defmt", derive(defmt::Format))]
359pub struct Config {
360    /// The priority of the RTOS task.
361    task_priority: u8,
362
363    /// The stack size of the RTOS task.
364    task_stack_size: u16,
365
366    /// The CPU core on which the BLE controller task should run.
367    #[cfg(multi_core)]
368    task_cpu: Cpu,
369
370    /// The maximum number of simultaneous connections.
371    ///
372    /// Range: 1 - 10
373    max_connections: u8,
374
375    /// Enable QA test mode.
376    qa_test_mode: bool,
377
378    /// Maximum number of devices in scan duplicate filtering list.
379    ///
380    /// Range: 10 - 1000
381    scan_duplicate_list_count: u16,
382
383    /// Scan duplicate filtering list refresh period in seconds.
384    ///
385    /// Range: 0 - 1000 seconds
386    scan_duplicate_refresh_period: u16,
387
388    /// Enables verification of the Access Address within the `CONNECT_IND` PDU.
389    ///
390    /// Enabling this option will add stricter verification of the Access Address in the
391    /// `CONNECT_IND` PDU. This improves security by ensuring that only connection requests with
392    /// valid Access Addresses are accepted. If disabled, only basic checks are applied,
393    /// improving compatibility.
394    // TODO: this needs additional setup
395    verify_access_address: bool,
396
397    /// Enable BLE channel assessment.
398    channel_assessment: bool,
399
400    /// Enable BLE ping procedure.
401    ping: bool,
402
403    /// Default TX antenna.
404    default_tx_antenna: Antenna,
405
406    /// Default RX antenna.
407    default_rx_antenna: Antenna,
408
409    /// Default TX power.
410    default_tx_power: TxPower,
411
412    /// Coexistence: limit on MAX Tx/Rx time for coded-PHY connection.
413    limit_time_for_coded_phy_connection: bool,
414
415    /// Enable / disable uncoded phy / coded phy hardware re-correction.
416    hw_recorrect_en: bool,
417
418    /// BLE Clear Channel Assessment (CCA) mode.
419    cca_mode: CcaMode,
420
421    /// Absolute value of hardware-triggered CCA threshold.
422    ///
423    /// The CCA threshold is always negative.
424    ///
425    /// If the channel assessment result exceeds the CCA threshold (e.g. -75 dBm), indicating
426    /// the channel is busy, the hardware will not transmit packets on that channel.
427    ///
428    /// Range: 20 dBm - 100 dBm
429    cca_threshold: u8,
430
431    /// Enable / disable auxiliary packets when the extended ADV data length is zero.
432    data_length_zero_aux: bool,
433
434    /// Enable / disable DTM.
435    dtm: bool,
436
437    /// Enable / disable encryption.
438    encryption: bool,
439
440    /// Enable / disable connection.
441    connection: bool,
442
443    /// Enable / disable scanning.
444    scan: bool,
445
446    /// Enable / disable ADV.
447    adv: bool,
448
449    /// Disconnect when Instant Passed (0x28) occurs during ACL connection update.
450    disconnect_llcp_conn_update: bool,
451
452    /// Disconnect when Instant Passed (0x28) occurs during ACL channel map update.
453    disconnect_llcp_chan_map_update: bool,
454
455    /// Disconnect when Instant Passed (0x28) occurs during ACL PHY update.
456    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, // 4096?
466            #[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, // CONFIG_BT_CTRL_HW_CCA_VAL is 0 which is not valid
481            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    // keep them aligned with BT_CONTROLLER_INIT_CONFIG_DEFAULT in ESP-IDF
514    // ideally _some_ of these values should be configurable
515    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        // Bluetooth mesh options, currently not supported
543        scan_duplicate_mode: 0, // normal mode
544        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        // esp-idf: "Please do not modify this value"
559        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    // NO-OP
588    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    // nothing
603}
604
605pub(crate) fn disable_sleep_mode() {
606    // nothing
607}
608
609// OSI functions
610
611pub(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}