1use procmacros::BuilderLite;
2
3use super::*;
4use crate::{
5 binary::include::esp_bt_controller_config_t,
6 ble::InvalidConfigError,
7 hal::{
8 clock::{Clock, RtcClock},
9 efuse::Efuse,
10 interrupt,
11 peripherals::{BT, Interrupt},
12 },
13};
14
15pub(crate) static mut ISR_INTERRUPT_4: (*mut c_void, *mut c_void) =
16 (core::ptr::null_mut(), core::ptr::null_mut());
17
18pub(crate) static mut ISR_INTERRUPT_7: (*mut c_void, *mut c_void) =
19 (core::ptr::null_mut(), core::ptr::null_mut());
20
21#[derive(Default, Clone, Copy, Eq, PartialEq)]
23#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25pub enum TxPower {
26 N24,
28 N21,
30 N18,
32 N15,
34 N12,
36 N9,
38 N6,
40 N3,
42 N0,
44 P3,
46 P6,
48 #[default]
50 P9,
51 P12,
53 P15,
55 P18,
57 P20,
59}
60
61#[allow(dead_code)]
62impl TxPower {
63 fn idx(self) -> esp_power_level_t {
64 match self {
65 Self::N24 => esp_power_level_t_ESP_PWR_LVL_N24,
66 Self::N21 => esp_power_level_t_ESP_PWR_LVL_N21,
67 Self::N18 => esp_power_level_t_ESP_PWR_LVL_N18,
68 Self::N15 => esp_power_level_t_ESP_PWR_LVL_N15,
69 Self::N12 => esp_power_level_t_ESP_PWR_LVL_N12,
70 Self::N9 => esp_power_level_t_ESP_PWR_LVL_N9,
71 Self::N6 => esp_power_level_t_ESP_PWR_LVL_N6,
72 Self::N3 => esp_power_level_t_ESP_PWR_LVL_N3,
73 Self::N0 => esp_power_level_t_ESP_PWR_LVL_N0,
74 Self::P3 => esp_power_level_t_ESP_PWR_LVL_P3,
75 Self::P6 => esp_power_level_t_ESP_PWR_LVL_P6,
76 Self::P9 => esp_power_level_t_ESP_PWR_LVL_P9,
77 Self::P12 => esp_power_level_t_ESP_PWR_LVL_P12,
78 Self::P15 => esp_power_level_t_ESP_PWR_LVL_P15,
79 Self::P18 => esp_power_level_t_ESP_PWR_LVL_P18,
80 Self::P20 => esp_power_level_t_ESP_PWR_LVL_P20,
81 }
82 }
83
84 fn dbm(self) -> i8 {
85 match self {
86 Self::N24 => -24,
87 Self::N21 => -21,
88 Self::N18 => -18,
89 Self::N15 => -15,
90 Self::N12 => -12,
91 Self::N9 => -9,
92 Self::N6 => -6,
93 Self::N3 => -3,
94 Self::N0 => 0,
95 Self::P3 => 3,
96 Self::P6 => 6,
97 Self::P9 => 9,
98 Self::P12 => 12,
99 Self::P15 => 15,
100 Self::P18 => 18,
101 Self::P20 => 20,
102 }
103 }
104}
105
106#[derive(BuilderLite, Clone, Copy, Eq, PartialEq)]
108#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
109#[cfg_attr(feature = "defmt", derive(defmt::Format))]
110pub struct Config {
111 task_priority: u8,
113
114 task_stack_size: u16,
116
117 max_connections: u16,
121
122 qa_test_mode: bool,
124
125 bqb_test: bool,
127
128 ll_resolv_list_size: u16,
130
131 ll_sync_list_cnt: u8,
135
136 ll_sync_cnt: u8,
140
141 ll_rsp_dup_list_count: u16,
145
146 ll_adv_dup_list_count: u16,
150
151 default_tx_power: TxPower,
153
154 hci_high_buffer_count: u16,
156
157 hci_low_buffer_count: u16,
159
160 whitelist_size: u8,
162
163 acl_buf_size: u16,
165
166 acl_buf_count: u16,
168
169 hci_evt_buf_size: u16,
171
172 multi_adv_instances: u16,
174
175 ext_adv_max_size: u16,
179
180 dis_scan_backoff: bool,
182
183 scan_backoff_max: u16,
189
190 verify_access_address: bool,
197
198 cca: bool,
200
201 cca_threshold: u8,
210
211 disconnect_llcp_conn_update: bool,
213
214 disconnect_llcp_chan_map_update: bool,
216
217 disconnect_llcp_phy_update: bool,
219}
220
221impl Default for Config {
222 fn default() -> Self {
223 Self {
224 task_priority: 29,
226 task_stack_size: CONFIG_BT_LE_CONTROLLER_TASK_STACK_SIZE as _,
227 max_connections: CONFIG_BT_LE_MAX_CONNECTIONS as _,
228 qa_test_mode: false,
229 bqb_test: false,
230 ll_resolv_list_size: CONFIG_BT_LE_LL_RESOLV_LIST_SIZE as _,
231 ll_sync_list_cnt: CONFIG_BT_LE_MAX_PERIODIC_ADVERTISER_LIST as _,
232 ll_sync_cnt: CONFIG_BT_LE_MAX_PERIODIC_SYNCS as _,
233 ll_rsp_dup_list_count: CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT as _,
234 ll_adv_dup_list_count: CONFIG_BT_LE_LL_DUP_SCAN_LIST_COUNT as _,
235 default_tx_power: TxPower::default(),
236 hci_high_buffer_count: CONFIG_BT_LE_HCI_EVT_HI_BUF_COUNT as _,
237 hci_low_buffer_count: CONFIG_BT_LE_HCI_EVT_LO_BUF_COUNT as _,
238 whitelist_size: CONFIG_BT_LE_WHITELIST_SIZE as _,
239 acl_buf_size: CONFIG_BT_LE_ACL_BUF_SIZE as _,
240 acl_buf_count: CONFIG_BT_LE_ACL_BUF_COUNT as _,
241 hci_evt_buf_size: CONFIG_BT_LE_HCI_EVT_BUF_SIZE as _,
242 multi_adv_instances: CONFIG_BT_LE_MAX_EXT_ADV_INSTANCES as _,
243 ext_adv_max_size: CONFIG_BT_LE_EXT_ADV_MAX_SIZE as _,
244 dis_scan_backoff: false,
245 scan_backoff_max: CONFIG_BT_CTRL_SCAN_BACKOFF_UPPERLIMITMAX as _,
246 verify_access_address: false,
247 disconnect_llcp_conn_update: false,
248 disconnect_llcp_chan_map_update: false,
249 disconnect_llcp_phy_update: false,
250 cca_threshold: 65,
251 cca: false,
252 }
253 }
254}
255
256impl Config {
257 pub(crate) fn validate(&self) -> Result<(), InvalidConfigError> {
258 crate::ble::validate_range!(self, max_connections, 1, 2);
259 crate::ble::validate_range!(self, ll_sync_cnt, 0, 3);
260 crate::ble::validate_range!(self, ll_sync_list_cnt, 1, 5);
261 crate::ble::validate_range!(self, ll_rsp_dup_list_count, 1, 100);
262 crate::ble::validate_range!(self, ll_adv_dup_list_count, 1, 100);
263 crate::ble::validate_range!(self, whitelist_size, 1, 31);
264 crate::ble::validate_range!(self, multi_adv_instances, 0, 4);
265 crate::ble::validate_range!(self, ext_adv_max_size, 0, 1650);
266 crate::ble::validate_range!(self, scan_backoff_max, 1, 256);
267 crate::ble::validate_range!(self, cca_threshold, 20, 100);
268 Ok(())
269 }
270}
271
272pub(crate) fn create_ble_config(config: &Config) -> esp_bt_controller_config_t {
273 let main_xtal_freq = RtcClock::xtal_freq().mhz() as u8;
274
275 let rtc_freq = if main_xtal_freq == 26 { 40000 } else { 32000 };
276
277 esp_bt_controller_config_t {
280 config_version: CONFIG_VERSION,
281 ble_ll_resolv_list_size: config.ll_resolv_list_size,
282 ble_hci_evt_hi_buf_count: config.hci_high_buffer_count,
283 ble_hci_evt_lo_buf_count: config.hci_low_buffer_count,
284 ble_ll_sync_list_cnt: config.ll_sync_list_cnt,
285 ble_ll_sync_cnt: config.ll_sync_cnt,
286 ble_ll_rsp_dup_list_count: config.ll_rsp_dup_list_count,
287 ble_ll_adv_dup_list_count: config.ll_adv_dup_list_count,
288 ble_ll_tx_pwr_dbm: config.default_tx_power.dbm() as u8,
289 rtc_freq,
290 ble_ll_sca: CONFIG_BT_LE_LL_SCA as _,
291 ble_ll_scan_phy_number: if CONFIG_BT_LE_LL_CFG_FEAT_LE_CODED_PHY != 0 {
292 2
293 } else {
294 1
295 },
296 ble_ll_conn_def_auth_pyld_tmo: 3000,
297 ble_ll_jitter_usecs: 16,
298 ble_ll_sched_max_adv_pdu_usecs: 376,
299 ble_ll_sched_direct_adv_max_usecs: 502,
300 ble_ll_sched_adv_max_usecs: 852,
301 ble_scan_rsp_data_max_len: 31,
302 ble_ll_cfg_num_hci_cmd_pkts: 1,
303 ble_ll_ctrl_proc_timeout_ms: 40000,
304 nimble_max_connections: config.max_connections,
305 ble_whitelist_size: config.whitelist_size,
306 ble_acl_buf_size: config.acl_buf_size,
307 ble_acl_buf_count: config.acl_buf_count,
308 ble_hci_evt_buf_size: config.hci_evt_buf_size,
309 ble_multi_adv_instances: config.multi_adv_instances,
310 ble_ext_adv_max_size: config.ext_adv_max_size,
311 controller_task_stack_size: config.task_stack_size,
312 controller_task_prio: config.task_priority,
313 controller_run_cpu: 0,
314 enable_qa_test: config.qa_test_mode as u8,
315 enable_bqb_test: config.bqb_test as u8,
316 enable_uart_hci: 0,
317 ble_hci_uart_port: 0,
318 ble_hci_uart_baud: 0,
319 ble_hci_uart_data_bits: 0,
320 ble_hci_uart_stop_bits: 0,
321 ble_hci_uart_flow_ctrl: 0,
322 ble_hci_uart_uart_parity: 0,
323 enable_tx_cca: config.cca as u8,
324 cca_rssi_thresh: (256 - config.cca_threshold as u32) as u8,
325 sleep_en: 0, coex_phy_coded_tx_rx_time_limit: CONFIG_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF as _,
327 dis_scan_backoff: config.dis_scan_backoff as u8,
328 ble_scan_classify_filter_enable: 0,
329 cca_drop_mode: 0, cca_low_tx_pwr: 0, main_xtal_freq,
332 version_num: Efuse::minor_chip_version(),
333 ignore_wl_for_direct_adv: 0,
334 csa2_select: CONFIG_BT_LE_50_FEATURE_SUPPORT as _,
335 ble_aa_check: config.verify_access_address as u8,
336 ble_llcp_disc_flag: config.disconnect_llcp_conn_update as u8
337 | ((config.disconnect_llcp_chan_map_update as u8) << 1)
338 | ((config.disconnect_llcp_phy_update as u8) << 2),
339 scan_backoff_upperlimitmax: config.scan_backoff_max,
340 vhci_enabled: CONFIG_BT_LE_HCI_INTERFACE_USE_RAM as _,
341 config_magic: CONFIG_MAGIC,
342 }
343}
344
345pub(crate) fn bt_periph_module_enable() {
346 }
348
349pub(crate) fn disable_sleep_mode() {
350 }
352
353pub(super) unsafe extern "C" fn esp_intr_alloc(
354 source: u32,
355 flags: u32,
356 handler: *mut c_void,
357 arg: *mut c_void,
358 ret_handle: *mut *mut c_void,
359) -> i32 {
360 trace!(
361 "esp_intr_alloc {} {} {:?} {:?} {:?}",
362 source, flags, handler, arg, ret_handle
363 );
364
365 unsafe {
366 match source {
367 4 => {
368 ISR_INTERRUPT_4 = (handler, arg);
369 unwrap!(interrupt::enable(
370 Interrupt::BT_MAC,
371 interrupt::Priority::Priority1
372 ));
373 }
374 7 => {
375 ISR_INTERRUPT_7 = (handler, arg);
376 unwrap!(interrupt::enable(
377 Interrupt::LP_TIMER,
378 interrupt::Priority::Priority1
379 ));
380 }
381 _ => panic!("Unexpected interrupt source {}", source),
382 }
383 }
384
385 0
386}
387
388pub(super) fn ble_rtc_clk_init() {
389 let mut bt = unsafe { BT::steal() };
392 bt.ble_rtc_clk_init();
393}
394
395pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() {
396 trace!("esp_reset_rpa_moudle");
397 let mut bt = unsafe { BT::steal() };
400 bt.reset_rpa();
401}
402
403#[unsafe(no_mangle)]
405unsafe fn g_ble_lll_rfmgmt_env_p() -> *mut esp_wifi_sys::c_types::c_void {
406 unreachable!()
408}