diff --git a/esp-wifi/src/ble/btdm.rs b/esp-wifi/src/ble/btdm.rs
index 7e538bb23c4..3aca6832efe 100644
--- a/esp-wifi/src/ble/btdm.rs
+++ b/esp-wifi/src/ble/btdm.rs
@@ -93,6 +93,9 @@ extern "C" fn notify_host_recv(data: *mut u8, len: u16) -> i32 {
let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
queue.enqueue(packet).unwrap();
});
+
+ #[cfg(feature = "async")]
+ crate::ble::controller::asynch::hci_read_data_available();
}
0
@@ -522,6 +525,14 @@ static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256];
static mut BLE_HCI_READ_DATA_INDEX: usize = 0;
static mut BLE_HCI_READ_DATA_LEN: usize = 0;
+#[cfg(feature = "async")]
+pub fn have_hci_read_data() -> bool {
+ critical_section::with(|cs| {
+ let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
+ !queue.is_empty() || unsafe { BLE_HCI_READ_DATA_LEN > 0 && (BLE_HCI_READ_DATA_LEN >= BLE_HCI_READ_DATA_INDEX) }
+ })
+}
+
pub fn read_hci(data: &mut [u8]) -> usize {
unsafe {
if BLE_HCI_READ_DATA_LEN == 0 {
@@ -529,11 +540,9 @@ pub fn read_hci(data: &mut [u8]) -> usize {
let mut queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
if let Some(packet) = queue.dequeue() {
- for i in 0..(packet.len as usize + 0/*1*/) {
- BLE_HCI_READ_DATA[i] = packet.data[i];
- }
-
- BLE_HCI_READ_DATA_LEN = packet.len as usize + 0 /*1*/;
+ BLE_HCI_READ_DATA[..packet.len as usize]
+ .copy_from_slice(&packet.data[..packet.len as usize]);
+ BLE_HCI_READ_DATA_LEN = packet.len as usize;
BLE_HCI_READ_DATA_INDEX = 0;
}
});
diff --git a/esp-wifi/src/ble/controller/mod.rs b/esp-wifi/src/ble/controller/mod.rs
index b2361f383c4..8fa0398979a 100644
--- a/esp-wifi/src/ble/controller/mod.rs
+++ b/esp-wifi/src/ble/controller/mod.rs
@@ -67,3 +67,95 @@ impl Write for BleConnector<'_> {
Ok(())
}
}
+
+#[cfg(feature = "async")]
+pub mod asynch {
+ use core::task::Poll;
+
+ use crate::ble::ble::have_hci_read_data;
+
+ use super::BleConnectorError;
+ use super::{read_hci, send_hci};
+ use embassy_sync::waitqueue::AtomicWaker;
+ use embedded_io::asynch;
+ use embedded_io::Io;
+ use esp_hal_common::peripheral::{Peripheral, PeripheralRef};
+
+ static HCI_WAKER: AtomicWaker = AtomicWaker::new();
+
+ pub(crate) fn hci_read_data_available() {
+ HCI_WAKER.wake();
+ }
+
+ pub struct BleConnector<'d> {
+ _device: PeripheralRef<'d, esp_hal_common::radio::Bluetooth>,
+ }
+
+ impl<'d> BleConnector<'d> {
+ pub fn new(
+ device: impl Peripheral
+ 'd,
+ ) -> BleConnector<'d> {
+ Self {
+ _device: device.into_ref(),
+ }
+ }
+ }
+
+ impl Io for BleConnector<'_> {
+ type Error = BleConnectorError;
+ }
+
+ impl asynch::Read for BleConnector<'_> {
+ async fn read(&mut self, buf: &mut [u8]) -> Result {
+ if !have_hci_read_data() {
+ HciReadyEventFuture.await;
+ }
+
+ let mut total = 0;
+ for b in buf {
+ let mut buffer = [0u8];
+ let len = read_hci(&mut buffer);
+
+ if len == 1 {
+ *b = buffer[0];
+ total += 1;
+ } else {
+ return Ok(total);
+ }
+ }
+
+ Ok(total)
+ }
+ }
+
+ impl asynch::Write for BleConnector<'_> {
+ async fn write(&mut self, buf: &[u8]) -> Result {
+ send_hci(buf);
+ Ok(buf.len())
+ }
+
+ async fn flush(&mut self) -> Result<(), BleConnectorError> {
+ // nothing to do
+ Ok(())
+ }
+ }
+
+ pub(crate) struct HciReadyEventFuture;
+
+ impl core::future::Future for HciReadyEventFuture {
+ type Output = ();
+
+ fn poll(
+ self: core::pin::Pin<&mut Self>,
+ cx: &mut core::task::Context<'_>,
+ ) -> Poll {
+ HCI_WAKER.register(cx.waker());
+
+ if have_hci_read_data() {
+ Poll::Ready(())
+ } else {
+ Poll::Pending
+ }
+ }
+ }
+}
diff --git a/esp-wifi/src/ble/npl.rs b/esp-wifi/src/ble/npl.rs
index 2510db189b6..dbce8d2cbb3 100644
--- a/esp-wifi/src/ble/npl.rs
+++ b/esp-wifi/src/ble/npl.rs
@@ -1232,6 +1232,9 @@ unsafe extern "C" fn ble_hs_hci_rx_evt(cmd: *const u8, arg: *const c_void) {
})
.unwrap();
});
+
+ #[cfg(feature = "async")]
+ crate::ble::controller::asynch::hci_read_data_available();
}
unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) {
@@ -1255,12 +1258,23 @@ unsafe extern "C" fn ble_hs_rx_data(om: *const OsMbuf, arg: *const c_void) {
})
.unwrap();
});
+
+ #[cfg(feature = "async")]
+ crate::ble::controller::asynch::hci_read_data_available();
}
static mut BLE_HCI_READ_DATA: [u8; 256] = [0u8; 256];
static mut BLE_HCI_READ_DATA_INDEX: usize = 0;
static mut BLE_HCI_READ_DATA_LEN: usize = 0;
+#[cfg(feature = "async")]
+pub fn have_hci_read_data() -> bool {
+ critical_section::with(|cs| {
+ let queue = BT_RECEIVE_QUEUE.borrow_ref_mut(cs);
+ !queue.is_empty() || unsafe { BLE_HCI_READ_DATA_LEN > 0 && (BLE_HCI_READ_DATA_LEN >= BLE_HCI_READ_DATA_INDEX) }
+ })
+}
+
pub fn read_hci(data: &mut [u8]) -> usize {
unsafe {
if BLE_HCI_READ_DATA_LEN == 0 {
@@ -1274,7 +1288,6 @@ pub fn read_hci(data: &mut [u8]) -> usize {
BLE_HCI_READ_DATA_INDEX = 0;
}
});
- return 0;
}
if BLE_HCI_READ_DATA_LEN > 0 {
diff --git a/esp-wifi/src/ble/os_adapter_esp32c3.rs b/esp-wifi/src/ble/os_adapter_esp32c3.rs
index 79ff3c67002..767009ccc24 100644
--- a/esp-wifi/src/ble/os_adapter_esp32c3.rs
+++ b/esp-wifi/src/ble/os_adapter_esp32c3.rs
@@ -160,7 +160,7 @@ pub(crate) fn create_ble_config() -> esp_bt_controller_config_t {
hci_tl_funcs: core::ptr::null_mut(),
txant_dft: 0,
rxant_dft: 0,
- txpwr_dft: 7,
+ txpwr_dft: 9,
cfg_mask: 1,
scan_duplicate_mode: 0,
scan_duplicate_type: 0,
@@ -179,9 +179,7 @@ pub(crate) fn create_ble_config() -> esp_bt_controller_config_t {
pub(crate) unsafe extern "C" fn interrupt_on(intr_num: i32) {
trace!("interrupt_on {}", intr_num);
- (*esp32c3::INTERRUPT_CORE0::PTR)
- .cpu_int_enable
- .modify(|r, w| w.bits(r.bits() | 1 << intr_num));
+ // NO-OP
}
pub(crate) unsafe extern "C" fn interrupt_off(_intr_num: i32) {
@@ -218,13 +216,10 @@ pub(crate) unsafe extern "C" fn interrupt_set(
interrupt_prio
);
- ((0x600c2000 + 0x114 + interrupt_no * 4) as *mut u32).write_volatile(interrupt_prio as u32);
-
/* Set the interrupt type (Edge or Level). */
- // ----
-
/* Map the CPU interrupt ID to the peripheral. */
- ((0x600c2000 + intr_source * 4) as *mut u32).write_volatile(interrupt_no as u32);
+
+ // NO-OP
}
pub(crate) unsafe extern "C" fn interrupt_clear(_interrupt_source: i32, _interrupt_no: i32) {
diff --git a/esp-wifi/src/lib.rs b/esp-wifi/src/lib.rs
index b29b47cbbff..44b150d50f2 100644
--- a/esp-wifi/src/lib.rs
+++ b/esp-wifi/src/lib.rs
@@ -1,6 +1,8 @@
#![no_std]
#![cfg_attr(target_arch = "xtensa", feature(asm_experimental_arch))]
#![feature(c_variadic)]
+#![cfg_attr(feature = "async", feature(async_fn_in_trait))]
+#![cfg_attr(feature = "async", allow(incomplete_features))]
use core::cell::RefCell;
use core::mem::MaybeUninit;