Skip to content

Commit

Permalink
ESP32-C6 BLE Support (esp-rs#262)
Browse files Browse the repository at this point in the history
* ESP32-C6 BLE Support

* Reformat
  • Loading branch information
bjoernQ committed May 23, 2024
1 parent 472b61b commit ed5a4b2
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 91 deletions.
4 changes: 2 additions & 2 deletions esp-wifi/src/ble/btdm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ unsafe extern "C" fn cause_sw_intr_to_core(_core: i32, _intr_no: i32) -> i32 {
}

unsafe extern "C" fn malloc(size: u32) -> *const () {
crate::compat::malloc::malloc(size) as *const ()
crate::compat::malloc::malloc(size as usize) as *const ()
}

unsafe extern "C" fn malloc_internal(size: u32) -> *const () {
crate::compat::malloc::malloc(size) as *const ()
crate::compat::malloc::malloc(size as usize) as *const ()
}

unsafe extern "C" fn free(ptr: *const ()) {
Expand Down
4 changes: 2 additions & 2 deletions esp-wifi/src/ble/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#[cfg(any(esp32, esp32c3, esp32s3))]
pub(crate) mod btdm;

#[cfg(any(esp32c2))]
#[cfg(any(esp32c2, esp32c6))]
pub(crate) mod npl;

use core::mem::MaybeUninit;

#[cfg(any(esp32, esp32c3, esp32s3))]
use self::btdm as ble;

#[cfg(any(esp32c2))]
#[cfg(any(esp32c2, esp32c6))]
use self::npl as ble;

pub(crate) use ble::ble_init;
Expand Down
31 changes: 15 additions & 16 deletions esp-wifi/src/ble/npl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ use crate::compat::queue::SimpleQueue;
use crate::timer::yield_task;

#[cfg_attr(esp32c2, path = "os_adapter_esp32c2.rs")]
#[cfg_attr(esp32c6, path = "os_adapter_esp32c6.rs")]
pub(crate) mod ble_os_adapter_chip_specific;

const TIME_FOREVER: u32 = u32::MAX;

const OS_MSYS_1_BLOCK_COUNT: i32 = 24;
const SYSINIT_MSYS_1_MEMPOOL_SIZE: u32 = 768;
const SYSINIT_MSYS_1_MEMPOOL_SIZE: usize = 768;
const SYSINIT_MSYS_1_MEMBLOCK_SIZE: i32 = 128;
const OS_MSYS_2_BLOCK_COUNT: i32 = 24;
const SYSINIT_MSYS_2_MEMPOOL_SIZE: u32 = 1920;
const SYSINIT_MSYS_2_MEMPOOL_SIZE: usize = 1920;
const SYSINIT_MSYS_2_MEMBLOCK_SIZE: i32 = 320;

const BLE_HCI_TRANS_BUF_CMD: i32 = 3;
Expand Down Expand Up @@ -217,6 +218,7 @@ pub(crate) static mut OS_MSYS_INIT_2_MEMPOOL: OsMempool = OsMempool::zeroed();
extern "C" {
static ble_hci_trans_funcs_ptr: &'static BleHciTransFuncsT;

#[cfg(esp32c2)]
static mut r_ble_stub_funcs_ptr: *mut u32;

pub(crate) fn ble_controller_init(cfg: *const esp_bt_controller_config_t) -> i32;
Expand Down Expand Up @@ -319,6 +321,7 @@ pub struct ext_funcs_t {
ecc_gen_key_pair: Option<unsafe extern "C" fn(*const u8, *const u8) -> i32>,
ecc_gen_dh_key: Option<unsafe extern "C" fn(*const u8, *const u8, *const u8, *const u8) -> i32>,
esp_reset_rpa_moudle: Option<unsafe extern "C" fn()>,
#[cfg(esp32c2)]
esp_bt_track_pll_cap: Option<unsafe extern "C" fn()>,
magic: u32,
}
Expand All @@ -327,7 +330,7 @@ static G_OSI_FUNCS: ext_funcs_t = ext_funcs_t {
ext_version: 0x20221122,
esp_intr_alloc: Some(self::ble_os_adapter_chip_specific::esp_intr_alloc),
esp_intr_free: Some(esp_intr_free),
malloc: Some(malloc),
malloc: Some(self::malloc),
free: Some(free),
hal_uart_start_tx: None,
hal_uart_init_cbs: None,
Expand All @@ -342,6 +345,7 @@ static G_OSI_FUNCS: ext_funcs_t = ext_funcs_t {
ecc_gen_key_pair: Some(ecc_gen_key_pair),
ecc_gen_dh_key: Some(ecc_gen_dh_key),
esp_reset_rpa_moudle: Some(self::ble_os_adapter_chip_specific::esp_reset_rpa_moudle),
#[cfg(esp32c2)]
esp_bt_track_pll_cap: None,
magic: 0xA5A5A5A5,
};
Expand Down Expand Up @@ -420,7 +424,7 @@ unsafe extern "C" fn esp_intr_free(_ret_handle: *mut *mut crate::binary::c_types
}

unsafe extern "C" fn malloc(size: u32) -> *const u8 {
crate::compat::malloc::malloc(size)
crate::compat::malloc::malloc(size as usize)
}

unsafe extern "C" fn free(ptr: *const crate::binary::c_types::c_void) {
Expand Down Expand Up @@ -1112,7 +1116,11 @@ pub(crate) fn ble_init() {

// "patch" r_ble_ll_random - it needs syscall_table_ptr
// probably long term we should rather initialize syscall_table_ptr
*(r_ble_stub_funcs_ptr.offset(0x7dc / 4)) = ble_ll_random_override as *const u32 as u32;
#[cfg(esp32c2)]
{
*(r_ble_stub_funcs_ptr.offset(0x7dc / 4)) =
self::ble_os_adapter_chip_specific::ble_ll_random_override as *const u32 as u32;
}

// this is a workaround for an unclear problem
// (ASSERT r_ble_hci_ram_hs_cmd_tx:34 0 0)
Expand All @@ -1122,24 +1130,15 @@ pub(crate) fn ble_init() {
}
}

unsafe extern "C" fn ble_ll_random_override() -> u32 {
// this is not very random but good enough for now - it's not used for crypto
unsafe {
static mut VALUE: u32 = 0;
VALUE = VALUE.wrapping_add(3);
VALUE
}
}

fn os_msys_buf_alloc() -> bool {
unsafe {
OS_MSYS_INIT_1_DATA = crate::compat::malloc::calloc(
1,
core::mem::size_of::<OsMembufT>() as u32 * SYSINIT_MSYS_1_MEMPOOL_SIZE,
core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_1_MEMPOOL_SIZE as usize,
) as *mut u32;
OS_MSYS_INIT_2_DATA = crate::compat::malloc::calloc(
1,
core::mem::size_of::<OsMembufT>() as u32 * SYSINIT_MSYS_2_MEMPOOL_SIZE,
core::mem::size_of::<OsMembufT>() * SYSINIT_MSYS_2_MEMPOOL_SIZE,
) as *mut u32;

!(OS_MSYS_INIT_1_DATA.is_null() || OS_MSYS_INIT_2_DATA.is_null())
Expand Down
9 changes: 9 additions & 0 deletions esp-wifi/src/ble/os_adapter_esp32c2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,12 @@ pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() {
unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa();
}
}

pub(super) unsafe extern "C" fn ble_ll_random_override() -> u32 {
// this is not very random but good enough for now - it's not used for crypto
unsafe {
static mut VALUE: u32 = 0;
VALUE = VALUE.wrapping_add(3);
VALUE
}
}
128 changes: 128 additions & 0 deletions esp-wifi/src/ble/os_adapter_esp32c6.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use crate::binary::include::esp_bt_controller_config_t;
use crate::common_adapter::RADIO_CLOCKS;
use crate::hal::system::RadioClockController;
use crate::hal::system::RadioPeripherals;

pub(crate) static mut ISR_INTERRUPT_4: (
*mut crate::binary::c_types::c_void,
*mut crate::binary::c_types::c_void,
) = (core::ptr::null_mut(), core::ptr::null_mut());

pub(crate) static mut ISR_INTERRUPT_7: (
*mut crate::binary::c_types::c_void,
*mut crate::binary::c_types::c_void,
) = (core::ptr::null_mut(), core::ptr::null_mut());

pub(crate) static BLE_CONFIG: esp_bt_controller_config_t = esp_bt_controller_config_t {
config_version: 0x20230113,
ble_ll_resolv_list_size: 4,
ble_hci_evt_hi_buf_count: 30,
ble_hci_evt_lo_buf_count: 8,
ble_ll_sync_list_cnt: 5,
ble_ll_sync_cnt: 20,
ble_ll_rsp_dup_list_count: 20,
ble_ll_adv_dup_list_count: 20,
ble_ll_tx_pwr_dbm: 9,
rtc_freq: 32000,
ble_ll_sca: 60,
ble_ll_scan_phy_number: 1,
ble_ll_conn_def_auth_pyld_tmo: 3000,
ble_ll_jitter_usecs: 16,
ble_ll_sched_max_adv_pdu_usecs: 376,
ble_ll_sched_direct_adv_max_usecs: 502,
ble_ll_sched_adv_max_usecs: 852,
ble_scan_rsp_data_max_len: 31,
ble_ll_cfg_num_hci_cmd_pkts: 1,
ble_ll_ctrl_proc_timeout_ms: 40000,
nimble_max_connections: 2,
ble_whitelist_size: 12,
ble_acl_buf_size: 255,
ble_acl_buf_count: 24,
ble_hci_evt_buf_size: 70,
ble_multi_adv_instances: 1,
ble_ext_adv_max_size: 31,
controller_task_stack_size: 4096,
controller_task_prio: 253,
controller_run_cpu: 0,
enable_qa_test: 0,
enable_bqb_test: 0,
enable_uart_hci: 0,
ble_hci_uart_port: 0,
ble_hci_uart_baud: 0,
ble_hci_uart_data_bits: 0,
ble_hci_uart_stop_bits: 0,
ble_hci_uart_flow_ctrl: 0,
ble_hci_uart_uart_parity: 0,
enable_tx_cca: 0,
cca_rssi_thresh: (256 - 50) as u8,
sleep_en: 0,
coex_phy_coded_tx_rx_time_limit: 0,
dis_scan_backoff: 0,
ble_scan_classify_filter_enable: 0,
cca_drop_mode: 0, //???
cca_low_tx_pwr: 0, //???
main_xtal_freq: 40,
ignore_wl_for_direct_adv: 0,
config_magic: 0x5A5AA5A5,

cpu_freq_mhz: 160,
enable_pcl: 0, // CONFIG_BT_LE_POWER_CONTROL_ENABLED
version_num: 0,
};

pub(crate) fn bt_periph_module_enable() {
unsafe {
unwrap!(RADIO_CLOCKS.as_mut()).enable(RadioPeripherals::Bt);
}
}

pub(crate) fn disable_sleep_mode() {
// nothing
}

pub(super) unsafe extern "C" fn esp_intr_alloc(
source: u32,
flags: u32,
handler: *mut crate::binary::c_types::c_void,
arg: *mut crate::binary::c_types::c_void,
ret_handle: *mut *mut crate::binary::c_types::c_void,
) -> i32 {
debug!(
"esp_intr_alloc {} {} {:?} {:?} {:?}",
source, flags, handler, arg, ret_handle
);

match source {
4 => ISR_INTERRUPT_4 = (handler, arg),
7 => ISR_INTERRUPT_7 = (handler, arg),
_ => panic!("Unexpected interrupt source {}", source),
}

0
}

pub(super) fn ble_rtc_clk_init() {
unsafe {
unwrap!(RADIO_CLOCKS.as_mut()).ble_rtc_clk_init();
}
}

pub(super) unsafe extern "C" fn esp_reset_rpa_moudle() {
trace!("esp_reset_rpa_moudle");
unsafe {
unwrap!(RADIO_CLOCKS.as_mut()).reset_rpa();
}
}

#[allow(improper_ctypes_definitions)]
#[no_mangle]
unsafe extern "C" fn jrand48(
_xsubi: [crate::binary::c_types::c_ushort; 3],
) -> crate::binary::c_types::c_long {
// this is not very random but good enough for now - it's apparently not used for crypto
unsafe {
static mut VALUE: u32 = 0;
VALUE = VALUE.wrapping_add(3);
VALUE as i32
}
}
6 changes: 3 additions & 3 deletions esp-wifi/src/compat/malloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::alloc::Layout;

use crate::HEAP;

pub unsafe extern "C" fn malloc(size: u32) -> *const u8 {
pub unsafe extern "C" fn malloc(size: usize) -> *const u8 {
trace!("alloc {}", size);

let total_size = size as usize + 4;
Expand Down Expand Up @@ -44,10 +44,10 @@ pub unsafe extern "C" fn free(ptr: *const u8) {
}

#[no_mangle]
pub unsafe extern "C" fn calloc(number: u32, size: u32) -> *const u8 {
pub unsafe extern "C" fn calloc(number: u32, size: usize) -> *const u8 {
trace!("calloc {} {}", number, size);

let total_size = number * size;
let total_size = number as usize * size;
let ptr = malloc(total_size) as *mut u8;

if !ptr.is_null() {
Expand Down
8 changes: 2 additions & 6 deletions esp-wifi/src/esp_now/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ impl<'d> EspNowSender<'d> {
data: &[u8],
) -> Result<SendWaiter<'s>, EspNowError> {
ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
check_error!({ esp_now_send(dst_addr.as_ptr(), data.as_ptr(), data.len() as u32) })?;
check_error!({ esp_now_send(dst_addr.as_ptr(), data.as_ptr(), data.len()) })?;
Ok(SendWaiter(PhantomData))
}
}
Expand Down Expand Up @@ -851,11 +851,7 @@ mod asynch {
ESP_NOW_TX_WAKER.register(cx.waker());
ESP_NOW_SEND_CB_INVOKED.store(false, Ordering::Release);
if let Err(e) = check_error!({
esp_now_send(
self.addr.as_ptr(),
self.data.as_ptr(),
self.data.len() as u32,
)
esp_now_send(self.addr.as_ptr(), self.data.as_ptr(), self.data.len())
}) {
return Poll::Ready(Err(e));
}
Expand Down
Loading

0 comments on commit ed5a4b2

Please sign in to comment.