From 29f32ce00ec0f50ef5e3b29c7e50f7f5479b4967 Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 23 Jun 2023 17:54:06 -0500 Subject: stm32/wpan: reorg subsystems --- embassy-stm32-wpan/src/ble.rs | 79 ------------------- embassy-stm32-wpan/src/evt.rs | 4 +- embassy-stm32-wpan/src/lhci.rs | 8 +- embassy-stm32-wpan/src/lib.rs | 26 +++---- embassy-stm32-wpan/src/mac.rs | 111 --------------------------- embassy-stm32-wpan/src/mm.rs | 79 ------------------- embassy-stm32-wpan/src/sub/ble.rs | 79 +++++++++++++++++++ embassy-stm32-wpan/src/sub/mac.rs | 111 +++++++++++++++++++++++++++ embassy-stm32-wpan/src/sub/mm.rs | 79 +++++++++++++++++++ embassy-stm32-wpan/src/sub/mod.rs | 6 ++ embassy-stm32-wpan/src/sub/sys.rs | 86 +++++++++++++++++++++ embassy-stm32-wpan/src/sys.rs | 86 --------------------- examples/stm32wb/src/bin/eddystone_beacon.rs | 14 ++-- tests/stm32/src/bin/tl_mbox.rs | 17 ++-- 14 files changed, 396 insertions(+), 389 deletions(-) delete mode 100644 embassy-stm32-wpan/src/ble.rs delete mode 100644 embassy-stm32-wpan/src/mac.rs delete mode 100644 embassy-stm32-wpan/src/mm.rs create mode 100644 embassy-stm32-wpan/src/sub/ble.rs create mode 100644 embassy-stm32-wpan/src/sub/mac.rs create mode 100644 embassy-stm32-wpan/src/sub/mm.rs create mode 100644 embassy-stm32-wpan/src/sub/mod.rs create mode 100644 embassy-stm32-wpan/src/sub/sys.rs delete mode 100644 embassy-stm32-wpan/src/sys.rs diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs deleted file mode 100644 index 619cd66a0..000000000 --- a/embassy-stm32-wpan/src/ble.rs +++ /dev/null @@ -1,79 +0,0 @@ -use core::marker::PhantomData; - -use embassy_stm32::ipcc::Ipcc; -use hci::Opcode; - -use crate::channels; -use crate::cmd::CmdPacket; -use crate::consts::TlPacketType; -use crate::evt::EvtBox; -use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; -use crate::unsafe_linked_list::LinkedListNode; - -pub struct Ble { - phantom: PhantomData, -} - -impl Ble { - pub(crate) fn new() -> Self { - unsafe { - LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); - - TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable { - pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), - pcs_buffer: CS_BUFFER.as_ptr().cast(), - pevt_queue: EVT_QUEUE.as_ptr().cast(), - phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(), - }); - } - - Self { phantom: PhantomData } - } - /// `HW_IPCC_BLE_EvtNot` - pub async fn tl_read(&self) -> EvtBox { - Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { - if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { - Some(EvtBox::new(node_ptr.cast())) - } else { - None - } - }) - .await - } - - /// `TL_BLE_SendCmd` - pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { - Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { - CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); - }) - .await; - } - - /// `TL_BLE_SendAclData` - pub async fn acl_write(&self, handle: u16, payload: &[u8]) { - Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { - CmdPacket::write_into( - HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, - TlPacketType::AclData, - handle, - payload, - ); - }) - .await; - } -} - -pub extern crate stm32wb_hci as hci; - -impl hci::Controller for Ble { - async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) { - self.tl_write(opcode.0, payload).await; - } - - async fn controller_read_into(&self, buf: &mut [u8]) { - let evt_box = self.tl_read().await; - let evt_serial = evt_box.serial(); - - buf[..evt_serial.len()].copy_from_slice(evt_serial); - } -} diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index 25249a13a..22f089037 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -145,14 +145,14 @@ impl Drop for EvtBox { fn drop(&mut self) { #[cfg(feature = "ble")] unsafe { - use crate::mm; + use crate::sub::mm; mm::MemoryManager::drop_event_packet(self.ptr) }; #[cfg(feature = "mac")] unsafe { - use crate::mac; + use crate::sub::mac; mac::Mac::drop_event_packet(self.ptr) } diff --git a/embassy-stm32-wpan/src/lhci.rs b/embassy-stm32-wpan/src/lhci.rs index 62116a695..284103705 100644 --- a/embassy-stm32-wpan/src/lhci.rs +++ b/embassy-stm32-wpan/src/lhci.rs @@ -1,7 +1,9 @@ +use core::ptr; + use crate::cmd::CmdPacket; use crate::consts::{TlPacketType, TL_EVT_HEADER_SIZE}; use crate::evt::{CcEvt, EvtPacket, EvtSerial}; -use crate::tables::{DeviceInfoTable, RssInfoTable, SafeBootInfoTable, WirelessFwInfoTable}; +use crate::tables::{DeviceInfoTable, RssInfoTable, SafeBootInfoTable, WirelessFwInfoTable, TL_DEVICE_INFO_TABLE}; use crate::TL_REF_TABLE; const TL_BLEEVT_CC_OPCODE: u8 = 0x0e; @@ -38,7 +40,7 @@ impl Default for LhciC1DeviceInformationCcrp { safe_boot_info_table, rss_info_table, wireless_fw_info_table, - } = unsafe { &*(*TL_REF_TABLE.as_ptr()).device_info_table }.clone(); + } = unsafe { ptr::read_volatile(TL_DEVICE_INFO_TABLE.as_ptr()) }; let device_id = stm32_device_signature::device_id(); let uid96_0 = (device_id[3] as u32) << 24 @@ -105,7 +107,7 @@ impl LhciC1DeviceInformationCcrp { let self_ptr: *const LhciC1DeviceInformationCcrp = self; let self_buf = self_ptr.cast(); - core::ptr::copy(self_buf, evt_cc_payload_buf, self_size); + ptr::copy(self_buf, evt_cc_payload_buf, self_size); } } } diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs index bf0f0466e..99c610583 100644 --- a/embassy-stm32-wpan/src/lib.rs +++ b/embassy-stm32-wpan/src/lib.rs @@ -11,26 +11,24 @@ use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; use embassy_stm32::peripherals::IPCC; -use mm::MemoryManager; -use sys::Sys; +use sub::mm::MemoryManager; +use sub::sys::Sys; use tables::*; use unsafe_linked_list::LinkedListNode; -#[cfg(feature = "ble")] -pub mod ble; pub mod channels; pub mod cmd; pub mod consts; pub mod evt; pub mod lhci; -#[cfg(feature = "mac")] -pub mod mac; -pub mod mm; pub mod shci; -pub mod sys; +pub mod sub; pub mod tables; pub mod unsafe_linked_list; +#[cfg(feature = "ble")] +pub use crate::sub::ble::hci; + type PacketHeader = LinkedListNode; pub struct TlMbox<'d> { @@ -39,9 +37,9 @@ pub struct TlMbox<'d> { pub sys_subsystem: Sys, pub mm_subsystem: MemoryManager, #[cfg(feature = "ble")] - pub ble_subsystem: ble::Ble, + pub ble_subsystem: sub::ble::Ble, #[cfg(feature = "mac")] - pub mac_subsystem: mac::Mac, + pub mac_subsystem: sub::mac::Mac, } impl<'d> TlMbox<'d> { @@ -128,12 +126,12 @@ impl<'d> TlMbox<'d> { Self { _ipcc: ipcc, - sys_subsystem: sys::Sys::new(), + sys_subsystem: sub::sys::Sys::new(), #[cfg(feature = "ble")] - ble_subsystem: ble::Ble::new(), + ble_subsystem: sub::ble::Ble::new(), #[cfg(feature = "mac")] - mac_subsystem: mac::Mac::new(), - mm_subsystem: mm::MemoryManager::new(), + mac_subsystem: sub::mac::Mac::new(), + mm_subsystem: sub::mm::MemoryManager::new(), } } } diff --git a/embassy-stm32-wpan/src/mac.rs b/embassy-stm32-wpan/src/mac.rs deleted file mode 100644 index d2be1b85c..000000000 --- a/embassy-stm32-wpan/src/mac.rs +++ /dev/null @@ -1,111 +0,0 @@ -use core::future::poll_fn; -use core::marker::PhantomData; -use core::ptr; -use core::sync::atomic::{AtomicBool, Ordering}; -use core::task::Poll; - -use embassy_futures::poll_once; -use embassy_stm32::ipcc::Ipcc; -use embassy_sync::waitqueue::AtomicWaker; - -use crate::channels; -use crate::cmd::CmdPacket; -use crate::consts::TlPacketType; -use crate::evt::{EvtBox, EvtPacket}; -use crate::tables::{ - Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, -}; - -static MAC_WAKER: AtomicWaker = AtomicWaker::new(); -static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); - -pub struct Mac { - phantom: PhantomData, -} - -impl Mac { - pub(crate) fn new() -> Self { - unsafe { - TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table { - p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(), - p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(), - evt_queue: ptr::null_mut(), - }); - } - - Self { phantom: PhantomData } - } - - /// SAFETY: passing a pointer to something other than a managed event packet is UB - pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) { - // Write the ack - CmdPacket::write_into( - MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, - TlPacketType::OtAck, - 0, - &[], - ); - - // Clear the rx flag - let _ = poll_once(Ipcc::receive::( - channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, - || None, - )); - - // Allow a new read call - MAC_EVT_OUT.store(false, Ordering::SeqCst); - MAC_WAKER.wake(); - } - - /// `HW_IPCC_MAC_802_15_4_EvtNot` - /// - /// This function will stall if the previous `EvtBox` has not been dropped - pub async fn read(&self) -> EvtBox { - // Wait for the last event box to be dropped - poll_fn(|cx| { - MAC_WAKER.register(cx.waker()); - if MAC_EVT_OUT.load(Ordering::SeqCst) { - Poll::Pending - } else { - Poll::Ready(()) - } - }) - .await; - - // Return a new event box - Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { - // The closure is not async, therefore the closure must execute to completion (cannot be dropped) - // Therefore, the event box is guaranteed to be cleaned up if it's not leaked - MAC_EVT_OUT.store(true, Ordering::SeqCst); - - Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) - }) - .await - } - - /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` - pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { - self.write(opcode, payload).await; - Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; - - unsafe { - let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; - let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; - - ptr::read_volatile(p_mac_rsp_evt) - } - } - - /// `TL_MAC_802_15_4_SendCmd` - pub async fn write(&self, opcode: u16, payload: &[u8]) { - Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { - CmdPacket::write_into( - MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), - TlPacketType::OtCmd, - opcode, - payload, - ); - }) - .await; - } -} diff --git a/embassy-stm32-wpan/src/mm.rs b/embassy-stm32-wpan/src/mm.rs deleted file mode 100644 index 047fddcd4..000000000 --- a/embassy-stm32-wpan/src/mm.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Memory manager routines -use core::future::poll_fn; -use core::marker::PhantomData; -use core::mem::MaybeUninit; -use core::task::Poll; - -use cortex_m::interrupt; -use embassy_stm32::ipcc::Ipcc; -use embassy_sync::waitqueue::AtomicWaker; - -use crate::channels; -use crate::consts::POOL_SIZE; -use crate::evt::EvtPacket; -use crate::tables::{ - MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, -}; -use crate::unsafe_linked_list::LinkedListNode; - -static MM_WAKER: AtomicWaker = AtomicWaker::new(); -static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); - -pub struct MemoryManager { - phantom: PhantomData, -} - -impl MemoryManager { - pub(crate) fn new() -> Self { - unsafe { - LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); - LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); - - TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable { - spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), - spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), - blepool: EVT_POOL.as_ptr().cast(), - blepoolsize: POOL_SIZE as u32, - pevt_free_buffer_queue: FREE_BUF_QUEUE.as_mut_ptr(), - traces_evt_pool: core::ptr::null(), - tracespoolsize: 0, - }); - } - - Self { phantom: PhantomData } - } - - #[allow(dead_code)] - /// SAFETY: passing a pointer to something other than a managed event packet is UB - pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) { - interrupt::free(|_| unsafe { - LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); - }); - - MM_WAKER.wake(); - } - - pub async fn run_queue(&self) { - loop { - poll_fn(|cx| unsafe { - MM_WAKER.register(cx.waker()); - if LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { - Poll::Pending - } else { - Poll::Ready(()) - } - }) - .await; - - Ipcc::send(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, || { - interrupt::free(|_| unsafe { - // CS required while moving nodes - while let Some(node_ptr) = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { - LinkedListNode::insert_head(FREE_BUF_QUEUE.as_mut_ptr(), node_ptr); - } - }) - }) - .await; - } - } -} diff --git a/embassy-stm32-wpan/src/sub/ble.rs b/embassy-stm32-wpan/src/sub/ble.rs new file mode 100644 index 000000000..619cd66a0 --- /dev/null +++ b/embassy-stm32-wpan/src/sub/ble.rs @@ -0,0 +1,79 @@ +use core::marker::PhantomData; + +use embassy_stm32::ipcc::Ipcc; +use hci::Opcode; + +use crate::channels; +use crate::cmd::CmdPacket; +use crate::consts::TlPacketType; +use crate::evt::EvtBox; +use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; +use crate::unsafe_linked_list::LinkedListNode; + +pub struct Ble { + phantom: PhantomData, +} + +impl Ble { + pub(crate) fn new() -> Self { + unsafe { + LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); + + TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable { + pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), + pcs_buffer: CS_BUFFER.as_ptr().cast(), + pevt_queue: EVT_QUEUE.as_ptr().cast(), + phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(), + }); + } + + Self { phantom: PhantomData } + } + /// `HW_IPCC_BLE_EvtNot` + pub async fn tl_read(&self) -> EvtBox { + Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { + if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { + Some(EvtBox::new(node_ptr.cast())) + } else { + None + } + }) + .await + } + + /// `TL_BLE_SendCmd` + pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { + CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); + }) + .await; + } + + /// `TL_BLE_SendAclData` + pub async fn acl_write(&self, handle: u16, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { + CmdPacket::write_into( + HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, + TlPacketType::AclData, + handle, + payload, + ); + }) + .await; + } +} + +pub extern crate stm32wb_hci as hci; + +impl hci::Controller for Ble { + async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) { + self.tl_write(opcode.0, payload).await; + } + + async fn controller_read_into(&self, buf: &mut [u8]) { + let evt_box = self.tl_read().await; + let evt_serial = evt_box.serial(); + + buf[..evt_serial.len()].copy_from_slice(evt_serial); + } +} diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs new file mode 100644 index 000000000..d2be1b85c --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac.rs @@ -0,0 +1,111 @@ +use core::future::poll_fn; +use core::marker::PhantomData; +use core::ptr; +use core::sync::atomic::{AtomicBool, Ordering}; +use core::task::Poll; + +use embassy_futures::poll_once; +use embassy_stm32::ipcc::Ipcc; +use embassy_sync::waitqueue::AtomicWaker; + +use crate::channels; +use crate::cmd::CmdPacket; +use crate::consts::TlPacketType; +use crate::evt::{EvtBox, EvtPacket}; +use crate::tables::{ + Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, +}; + +static MAC_WAKER: AtomicWaker = AtomicWaker::new(); +static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); + +pub struct Mac { + phantom: PhantomData, +} + +impl Mac { + pub(crate) fn new() -> Self { + unsafe { + TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table { + p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(), + p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(), + evt_queue: ptr::null_mut(), + }); + } + + Self { phantom: PhantomData } + } + + /// SAFETY: passing a pointer to something other than a managed event packet is UB + pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) { + // Write the ack + CmdPacket::write_into( + MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, + TlPacketType::OtAck, + 0, + &[], + ); + + // Clear the rx flag + let _ = poll_once(Ipcc::receive::( + channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, + || None, + )); + + // Allow a new read call + MAC_EVT_OUT.store(false, Ordering::SeqCst); + MAC_WAKER.wake(); + } + + /// `HW_IPCC_MAC_802_15_4_EvtNot` + /// + /// This function will stall if the previous `EvtBox` has not been dropped + pub async fn read(&self) -> EvtBox { + // Wait for the last event box to be dropped + poll_fn(|cx| { + MAC_WAKER.register(cx.waker()); + if MAC_EVT_OUT.load(Ordering::SeqCst) { + Poll::Pending + } else { + Poll::Ready(()) + } + }) + .await; + + // Return a new event box + Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { + // The closure is not async, therefore the closure must execute to completion (cannot be dropped) + // Therefore, the event box is guaranteed to be cleaned up if it's not leaked + MAC_EVT_OUT.store(true, Ordering::SeqCst); + + Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) + }) + .await + } + + /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` + pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { + self.write(opcode, payload).await; + Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + + unsafe { + let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; + let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; + + ptr::read_volatile(p_mac_rsp_evt) + } + } + + /// `TL_MAC_802_15_4_SendCmd` + pub async fn write(&self, opcode: u16, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { + CmdPacket::write_into( + MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), + TlPacketType::OtCmd, + opcode, + payload, + ); + }) + .await; + } +} diff --git a/embassy-stm32-wpan/src/sub/mm.rs b/embassy-stm32-wpan/src/sub/mm.rs new file mode 100644 index 000000000..047fddcd4 --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mm.rs @@ -0,0 +1,79 @@ +//! Memory manager routines +use core::future::poll_fn; +use core::marker::PhantomData; +use core::mem::MaybeUninit; +use core::task::Poll; + +use cortex_m::interrupt; +use embassy_stm32::ipcc::Ipcc; +use embassy_sync::waitqueue::AtomicWaker; + +use crate::channels; +use crate::consts::POOL_SIZE; +use crate::evt::EvtPacket; +use crate::tables::{ + MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, +}; +use crate::unsafe_linked_list::LinkedListNode; + +static MM_WAKER: AtomicWaker = AtomicWaker::new(); +static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); + +pub struct MemoryManager { + phantom: PhantomData, +} + +impl MemoryManager { + pub(crate) fn new() -> Self { + unsafe { + LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); + LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); + + TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable { + spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), + spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), + blepool: EVT_POOL.as_ptr().cast(), + blepoolsize: POOL_SIZE as u32, + pevt_free_buffer_queue: FREE_BUF_QUEUE.as_mut_ptr(), + traces_evt_pool: core::ptr::null(), + tracespoolsize: 0, + }); + } + + Self { phantom: PhantomData } + } + + #[allow(dead_code)] + /// SAFETY: passing a pointer to something other than a managed event packet is UB + pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) { + interrupt::free(|_| unsafe { + LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); + }); + + MM_WAKER.wake(); + } + + pub async fn run_queue(&self) { + loop { + poll_fn(|cx| unsafe { + MM_WAKER.register(cx.waker()); + if LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { + Poll::Pending + } else { + Poll::Ready(()) + } + }) + .await; + + Ipcc::send(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, || { + interrupt::free(|_| unsafe { + // CS required while moving nodes + while let Some(node_ptr) = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { + LinkedListNode::insert_head(FREE_BUF_QUEUE.as_mut_ptr(), node_ptr); + } + }) + }) + .await; + } + } +} diff --git a/embassy-stm32-wpan/src/sub/mod.rs b/embassy-stm32-wpan/src/sub/mod.rs new file mode 100644 index 000000000..bee3dbdf1 --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mod.rs @@ -0,0 +1,6 @@ +#[cfg(feature = "ble")] +pub mod ble; +#[cfg(feature = "mac")] +pub mod mac; +pub mod mm; +pub mod sys; diff --git a/embassy-stm32-wpan/src/sub/sys.rs b/embassy-stm32-wpan/src/sub/sys.rs new file mode 100644 index 000000000..2b699b725 --- /dev/null +++ b/embassy-stm32-wpan/src/sub/sys.rs @@ -0,0 +1,86 @@ +use core::marker::PhantomData; +use core::ptr; + +use crate::cmd::CmdPacket; +use crate::consts::TlPacketType; +use crate::evt::{CcEvt, EvtBox, EvtPacket}; +#[allow(unused_imports)] +use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; +use crate::tables::{SysTable, WirelessFwInfoTable}; +use crate::unsafe_linked_list::LinkedListNode; +use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; + +pub struct Sys { + phantom: PhantomData, +} + +impl Sys { + /// TL_Sys_Init + pub(crate) fn new() -> Self { + unsafe { + LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); + + TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable { + pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), + sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), + }); + } + + Self { phantom: PhantomData } + } + + /// Returns CPU2 wireless firmware information (if present). + pub fn wireless_fw_info(&self) -> Option { + let info = unsafe { TL_DEVICE_INFO_TABLE.as_mut_ptr().read_volatile().wireless_fw_info_table }; + + // Zero version indicates that CPU2 wasn't active and didn't fill the information table + if info.version != 0 { + Some(info) + } else { + None + } + } + + pub async fn write(&self, opcode: ShciOpcode, payload: &[u8]) { + Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || unsafe { + CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); + }) + .await; + } + + /// `HW_IPCC_SYS_CmdEvtNot` + pub async fn write_and_get_response(&self, opcode: ShciOpcode, payload: &[u8]) -> SchiCommandStatus { + self.write(opcode, payload).await; + Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + + unsafe { + let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; + let p_command_event = &((*p_event_packet).evt_serial.evt.payload) as *const _ as *const CcEvt; + let p_payload = &((*p_command_event).payload) as *const u8; + + ptr::read_volatile(p_payload).try_into().unwrap() + } + } + + #[cfg(feature = "mac")] + pub async fn shci_c2_mac_802_15_4_init(&self) -> SchiCommandStatus { + self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await + } + + #[cfg(feature = "ble")] + pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> SchiCommandStatus { + self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await + } + + /// `HW_IPCC_SYS_EvtNot` + pub async fn read(&self) -> EvtBox { + Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { + if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { + Some(EvtBox::new(node_ptr.cast())) + } else { + None + } + }) + .await + } +} diff --git a/embassy-stm32-wpan/src/sys.rs b/embassy-stm32-wpan/src/sys.rs deleted file mode 100644 index 2b699b725..000000000 --- a/embassy-stm32-wpan/src/sys.rs +++ /dev/null @@ -1,86 +0,0 @@ -use core::marker::PhantomData; -use core::ptr; - -use crate::cmd::CmdPacket; -use crate::consts::TlPacketType; -use crate::evt::{CcEvt, EvtBox, EvtPacket}; -#[allow(unused_imports)] -use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; -use crate::tables::{SysTable, WirelessFwInfoTable}; -use crate::unsafe_linked_list::LinkedListNode; -use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; - -pub struct Sys { - phantom: PhantomData, -} - -impl Sys { - /// TL_Sys_Init - pub(crate) fn new() -> Self { - unsafe { - LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); - - TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable { - pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), - sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), - }); - } - - Self { phantom: PhantomData } - } - - /// Returns CPU2 wireless firmware information (if present). - pub fn wireless_fw_info(&self) -> Option { - let info = unsafe { TL_DEVICE_INFO_TABLE.as_mut_ptr().read_volatile().wireless_fw_info_table }; - - // Zero version indicates that CPU2 wasn't active and didn't fill the information table - if info.version != 0 { - Some(info) - } else { - None - } - } - - pub async fn write(&self, opcode: ShciOpcode, payload: &[u8]) { - Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || unsafe { - CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); - }) - .await; - } - - /// `HW_IPCC_SYS_CmdEvtNot` - pub async fn write_and_get_response(&self, opcode: ShciOpcode, payload: &[u8]) -> SchiCommandStatus { - self.write(opcode, payload).await; - Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; - - unsafe { - let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; - let p_command_event = &((*p_event_packet).evt_serial.evt.payload) as *const _ as *const CcEvt; - let p_payload = &((*p_command_event).payload) as *const u8; - - ptr::read_volatile(p_payload).try_into().unwrap() - } - } - - #[cfg(feature = "mac")] - pub async fn shci_c2_mac_802_15_4_init(&self) -> SchiCommandStatus { - self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await - } - - #[cfg(feature = "ble")] - pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> SchiCommandStatus { - self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await - } - - /// `HW_IPCC_SYS_EvtNot` - pub async fn read(&self) -> EvtBox { - Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { - if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { - Some(EvtBox::new(node_ptr.cast())) - } else { - None - } - }) - .await - } -} diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs index fdd5be4a2..b99f8cb2e 100644 --- a/examples/stm32wb/src/bin/eddystone_beacon.rs +++ b/examples/stm32wb/src/bin/eddystone_beacon.rs @@ -8,15 +8,15 @@ use defmt::*; use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; -use embassy_stm32_wpan::ble::hci::host::uart::UartHci; -use embassy_stm32_wpan::ble::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; -use embassy_stm32_wpan::ble::hci::types::AdvertisingType; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gap::{ +use embassy_stm32_wpan::hci::host::uart::UartHci; +use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; +use embassy_stm32_wpan::hci::types::AdvertisingType; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::gap::{ AdvertisingDataType, DiscoverableParameters, GapCommands, Role, }; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gatt::GattCommands; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; -use embassy_stm32_wpan::ble::hci::BdAddr; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::gatt::GattCommands; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; +use embassy_stm32_wpan::hci::BdAddr; use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; use embassy_stm32_wpan::TlMbox; use {defmt_rtt as _, panic_probe as _}; diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs index 76c736a5b..8880554de 100644 --- a/tests/stm32/src/bin/tl_mbox.rs +++ b/tests/stm32/src/bin/tl_mbox.rs @@ -12,17 +12,18 @@ use common::*; use embassy_executor::Spawner; use embassy_stm32::bind_interrupts; use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; -use embassy_stm32_wpan::ble::hci::host::uart::UartHci; -use embassy_stm32_wpan::ble::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; -use embassy_stm32_wpan::ble::hci::types::AdvertisingType; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gap::{ +use embassy_stm32_wpan::hci::host::uart::UartHci; +use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; +use embassy_stm32_wpan::hci::types::AdvertisingType; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::gap::{ AdvertisingDataType, DiscoverableParameters, GapCommands, Role, }; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gatt::GattCommands; -use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; -use embassy_stm32_wpan::ble::hci::BdAddr; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::gatt::GattCommands; +use embassy_stm32_wpan::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; +use embassy_stm32_wpan::hci::BdAddr; use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; -use embassy_stm32_wpan::{mm, TlMbox}; +use embassy_stm32_wpan::sub::mm; +use embassy_stm32_wpan::TlMbox; use {defmt_rtt as _, panic_probe as _}; bind_interrupts!(struct Irqs{ -- cgit From f23b34951a20f569997bbe028048f3943d7e4c56 Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 23 Jun 2023 17:55:47 -0500 Subject: rustfmt --- embassy-stm32-wpan/src/lhci.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/embassy-stm32-wpan/src/lhci.rs b/embassy-stm32-wpan/src/lhci.rs index 284103705..89f204f99 100644 --- a/embassy-stm32-wpan/src/lhci.rs +++ b/embassy-stm32-wpan/src/lhci.rs @@ -4,7 +4,6 @@ use crate::cmd::CmdPacket; use crate::consts::{TlPacketType, TL_EVT_HEADER_SIZE}; use crate::evt::{CcEvt, EvtPacket, EvtSerial}; use crate::tables::{DeviceInfoTable, RssInfoTable, SafeBootInfoTable, WirelessFwInfoTable, TL_DEVICE_INFO_TABLE}; -use crate::TL_REF_TABLE; const TL_BLEEVT_CC_OPCODE: u8 = 0x0e; const LHCI_OPCODE_C1_DEVICE_INF: u16 = 0xfd62; -- cgit From 91fdd76053c747c569b0eefe0715522465fe0194 Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 23 Jun 2023 18:08:42 -0500 Subject: stm32/wpan: use align to align data --- embassy-stm32-wpan/Cargo.toml | 1 + embassy-stm32-wpan/src/tables.rs | 34 +++++++++++++--------------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 6d78ca577..4b830cab3 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -21,6 +21,7 @@ embassy-embedded-hal = { version = "0.1.0", path = "../embassy-embedded-hal" } defmt = { version = "0.3", optional = true } cortex-m = "0.7.6" heapless = "0.7.16" +aligned = "0.4.1" bit_field = "0.10.2" stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs index 3f26282c6..1b5dcdf2e 100644 --- a/embassy-stm32-wpan/src/tables.rs +++ b/embassy-stm32-wpan/src/tables.rs @@ -1,5 +1,6 @@ use core::mem::MaybeUninit; +use aligned::{Aligned, A4}; use bit_field::BitField; use crate::cmd::{AclDataPacket, CmdPacket}; @@ -164,9 +165,6 @@ pub struct Mac802_15_4Table { pub evt_queue: *const u8, } -#[repr(C, align(4))] -pub struct AlignedData([u8; L]); - /// Reference table. Contains pointers to all other tables. #[derive(Debug, Copy, Clone)] #[repr(C)] @@ -222,10 +220,9 @@ pub static mut FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit #[link_section = "MB_MEM1"] pub static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); -const CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; - #[link_section = "MB_MEM2"] -pub static mut CS_BUFFER: MaybeUninit> = MaybeUninit::uninit(); +pub static mut CS_BUFFER: MaybeUninit> = + MaybeUninit::uninit(); #[link_section = "MB_MEM2"] pub static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); @@ -238,35 +235,30 @@ pub static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::unin #[link_section = "MB_MEM2"] pub static mut MAC_802_15_4_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); -#[cfg(feature = "mac")] -const MAC_802_15_4_NOTIF_RSP_EVT_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; - #[cfg(feature = "mac")] #[link_section = "MB_MEM2"] -pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit> = - MaybeUninit::uninit(); +pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit< + Aligned, +> = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] -pub static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); +pub static mut EVT_POOL: MaybeUninit> = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] pub static mut SYS_CMD_BUF: MaybeUninit = MaybeUninit::uninit(); -const SYS_SPARE_EVT_BUF_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; - #[link_section = "MB_MEM2"] -pub static mut SYS_SPARE_EVT_BUF: MaybeUninit> = MaybeUninit::uninit(); +pub static mut SYS_SPARE_EVT_BUF: MaybeUninit> = + MaybeUninit::uninit(); #[link_section = "MB_MEM1"] pub static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); -const BLE_SPARE_EVT_BUF_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255; - #[link_section = "MB_MEM2"] -pub static mut BLE_SPARE_EVT_BUF: MaybeUninit> = MaybeUninit::uninit(); - -const HCI_ACL_DATA_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + 5 + 251; +pub static mut BLE_SPARE_EVT_BUF: MaybeUninit> = + MaybeUninit::uninit(); #[link_section = "MB_MEM2"] // fuck these "magic" numbers from ST ---v---v -pub static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; HCI_ACL_DATA_BUFFER_SIZE]> = MaybeUninit::uninit(); +pub static mut HCI_ACL_DATA_BUFFER: MaybeUninit> = + MaybeUninit::uninit(); -- cgit From d43417e97c4de487b4ebf018830825e034c5394e Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 23 Jun 2023 19:59:48 -0500 Subject: stm32/wpan: implement mm pattern --- embassy-stm32-wpan/src/consts.rs | 4 ++++ embassy-stm32-wpan/src/evt.rs | 33 ++++++++++----------------- embassy-stm32-wpan/src/sub/ble.rs | 25 ++++++++++++++++---- embassy-stm32-wpan/src/sub/mac.rs | 48 ++++++++++++++++++++------------------- embassy-stm32-wpan/src/sub/mm.rs | 23 ++++++++++--------- embassy-stm32-wpan/src/sub/sys.rs | 3 ++- tests/stm32/src/bin/tl_mbox.rs | 4 ++-- 7 files changed, 78 insertions(+), 62 deletions(-) diff --git a/embassy-stm32-wpan/src/consts.rs b/embassy-stm32-wpan/src/consts.rs index 9a107306c..f234151d7 100644 --- a/embassy-stm32-wpan/src/consts.rs +++ b/embassy-stm32-wpan/src/consts.rs @@ -87,3 +87,7 @@ pub const fn divc(x: usize, y: usize) -> usize { pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; #[allow(dead_code)] pub const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; + +pub const TL_BLEEVT_CC_OPCODE: u8 = 0x0E; +pub const TL_BLEEVT_CS_OPCODE: u8 = 0x0F; +pub const TL_BLEEVT_VS_OPCODE: u8 = 0xFF; diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index 22f089037..c6528413d 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -1,3 +1,4 @@ +use core::marker::PhantomData; use core::{ptr, slice}; use super::PacketHeader; @@ -93,17 +94,22 @@ impl EvtPacket { } } +pub trait MemoryManager { + unsafe fn drop_event_packet(evt: *mut EvtPacket); +} + /// smart pointer to the [`EvtPacket`] that will dispose of [`EvtPacket`] buffer automatically /// on [`Drop`] #[derive(Debug)] -pub struct EvtBox { +pub struct EvtBox { ptr: *mut EvtPacket, + mm: PhantomData, } -unsafe impl Send for EvtBox {} -impl EvtBox { +unsafe impl Send for EvtBox {} +impl EvtBox { pub(super) fn new(ptr: *mut EvtPacket) -> Self { - Self { ptr } + Self { ptr, mm: PhantomData } } /// Returns information about the event @@ -126,9 +132,6 @@ impl EvtBox { } } - /// writes an underlying [`EvtPacket`] into the provided buffer. - /// Returns the number of bytes that were written. - /// Returns an error if event kind is unknown or if provided buffer size is not enough. pub fn serial<'a>(&'a self) -> &'a [u8] { unsafe { let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial; @@ -141,20 +144,8 @@ impl EvtBox { } } -impl Drop for EvtBox { +impl Drop for EvtBox { fn drop(&mut self) { - #[cfg(feature = "ble")] - unsafe { - use crate::sub::mm; - - mm::MemoryManager::drop_event_packet(self.ptr) - }; - - #[cfg(feature = "mac")] - unsafe { - use crate::sub::mac; - - mac::Mac::drop_event_packet(self.ptr) - } + unsafe { T::drop_event_packet(self.ptr) }; } } diff --git a/embassy-stm32-wpan/src/sub/ble.rs b/embassy-stm32-wpan/src/sub/ble.rs index 619cd66a0..cd32692e1 100644 --- a/embassy-stm32-wpan/src/sub/ble.rs +++ b/embassy-stm32-wpan/src/sub/ble.rs @@ -1,14 +1,16 @@ use core::marker::PhantomData; +use core::ptr; use embassy_stm32::ipcc::Ipcc; use hci::Opcode; -use crate::channels; use crate::cmd::CmdPacket; -use crate::consts::TlPacketType; -use crate::evt::EvtBox; +use crate::consts::{TlPacketType, TL_BLEEVT_CC_OPCODE, TL_BLEEVT_CS_OPCODE}; +use crate::evt::{EvtBox, EvtPacket, EvtStub}; +use crate::sub::mm; use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; use crate::unsafe_linked_list::LinkedListNode; +use crate::{channels, evt}; pub struct Ble { phantom: PhantomData, @@ -30,7 +32,7 @@ impl Ble { Self { phantom: PhantomData } } /// `HW_IPCC_BLE_EvtNot` - pub async fn tl_read(&self) -> EvtBox { + pub async fn tl_read(&self) -> EvtBox { Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { Some(EvtBox::new(node_ptr.cast())) @@ -63,6 +65,21 @@ impl Ble { } } +impl evt::MemoryManager for Ble { + /// SAFETY: passing a pointer to something other than a managed event packet is UB + unsafe fn drop_event_packet(evt: *mut EvtPacket) { + let stub = unsafe { + let p_evt_stub = &(*evt).evt_serial as *const _ as *const EvtStub; + + ptr::read_volatile(p_evt_stub) + }; + + if !(stub.evt_code == TL_BLEEVT_CS_OPCODE || stub.evt_code == TL_BLEEVT_CC_OPCODE) { + mm::MemoryManager::drop_event_packet(evt); + } + } +} + pub extern crate stm32wb_hci as hci; impl hci::Controller for Ble { diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs index d2be1b85c..fd8af8609 100644 --- a/embassy-stm32-wpan/src/sub/mac.rs +++ b/embassy-stm32-wpan/src/sub/mac.rs @@ -8,13 +8,13 @@ use embassy_futures::poll_once; use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; -use crate::channels; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::{EvtBox, EvtPacket}; use crate::tables::{ Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, }; +use crate::{channels, evt}; static MAC_WAKER: AtomicWaker = AtomicWaker::new(); static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); @@ -36,31 +36,10 @@ impl Mac { Self { phantom: PhantomData } } - /// SAFETY: passing a pointer to something other than a managed event packet is UB - pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) { - // Write the ack - CmdPacket::write_into( - MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, - TlPacketType::OtAck, - 0, - &[], - ); - - // Clear the rx flag - let _ = poll_once(Ipcc::receive::( - channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, - || None, - )); - - // Allow a new read call - MAC_EVT_OUT.store(false, Ordering::SeqCst); - MAC_WAKER.wake(); - } - /// `HW_IPCC_MAC_802_15_4_EvtNot` /// /// This function will stall if the previous `EvtBox` has not been dropped - pub async fn read(&self) -> EvtBox { + pub async fn read(&self) -> EvtBox { // Wait for the last event box to be dropped poll_fn(|cx| { MAC_WAKER.register(cx.waker()); @@ -109,3 +88,26 @@ impl Mac { .await; } } + +impl evt::MemoryManager for Mac { + /// SAFETY: passing a pointer to something other than a managed event packet is UB + unsafe fn drop_event_packet(_: *mut EvtPacket) { + // Write the ack + CmdPacket::write_into( + MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, + TlPacketType::OtAck, + 0, + &[], + ); + + // Clear the rx flag + let _ = poll_once(Ipcc::receive::( + channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, + || None, + )); + + // Allow a new read call + MAC_EVT_OUT.store(false, Ordering::SeqCst); + MAC_WAKER.wake(); + } +} diff --git a/embassy-stm32-wpan/src/sub/mm.rs b/embassy-stm32-wpan/src/sub/mm.rs index 047fddcd4..1f2ecac2e 100644 --- a/embassy-stm32-wpan/src/sub/mm.rs +++ b/embassy-stm32-wpan/src/sub/mm.rs @@ -8,13 +8,13 @@ use cortex_m::interrupt; use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; -use crate::channels; use crate::consts::POOL_SIZE; use crate::evt::EvtPacket; use crate::tables::{ MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, }; use crate::unsafe_linked_list::LinkedListNode; +use crate::{channels, evt}; static MM_WAKER: AtomicWaker = AtomicWaker::new(); static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); @@ -43,16 +43,6 @@ impl MemoryManager { Self { phantom: PhantomData } } - #[allow(dead_code)] - /// SAFETY: passing a pointer to something other than a managed event packet is UB - pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) { - interrupt::free(|_| unsafe { - LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); - }); - - MM_WAKER.wake(); - } - pub async fn run_queue(&self) { loop { poll_fn(|cx| unsafe { @@ -77,3 +67,14 @@ impl MemoryManager { } } } + +impl evt::MemoryManager for MemoryManager { + /// SAFETY: passing a pointer to something other than a managed event packet is UB + unsafe fn drop_event_packet(evt: *mut EvtPacket) { + interrupt::free(|_| unsafe { + LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _); + }); + + MM_WAKER.wake(); + } +} diff --git a/embassy-stm32-wpan/src/sub/sys.rs b/embassy-stm32-wpan/src/sub/sys.rs index 2b699b725..af652860d 100644 --- a/embassy-stm32-wpan/src/sub/sys.rs +++ b/embassy-stm32-wpan/src/sub/sys.rs @@ -6,6 +6,7 @@ use crate::consts::TlPacketType; use crate::evt::{CcEvt, EvtBox, EvtPacket}; #[allow(unused_imports)] use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; +use crate::sub::mm; use crate::tables::{SysTable, WirelessFwInfoTable}; use crate::unsafe_linked_list::LinkedListNode; use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; @@ -73,7 +74,7 @@ impl Sys { } /// `HW_IPCC_SYS_EvtNot` - pub async fn read(&self) -> EvtBox { + pub async fn read(&self) -> EvtBox { Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { Some(EvtBox::new(node_ptr.cast())) diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs index 8880554de..af3832709 100644 --- a/tests/stm32/src/bin/tl_mbox.rs +++ b/tests/stm32/src/bin/tl_mbox.rs @@ -39,14 +39,14 @@ async fn run_mm_queue(memory_manager: mm::MemoryManager) { } #[embassy_executor::main] -async fn main(_spawner: Spawner) { +async fn main(spawner: Spawner) { let p = embassy_stm32::init(config()); info!("Hello World!"); let config = Config::default(); let mut mbox = TlMbox::init(p.IPCC, Irqs, config); - // spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); + spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); let sys_event = mbox.sys_subsystem.read().await; info!("sys event: {}", sys_event.payload()); -- cgit From 49333ce6adf28ff6c3eb1a632c0d4860379ef3ef Mon Sep 17 00:00:00 2001 From: xoviat Date: Fri, 23 Jun 2023 20:09:13 -0500 Subject: stm32/wpan: move linker file into pkg --- embassy-stm32-wpan/build.rs | 13 ++++++++++++- embassy-stm32-wpan/tl_mbox.x.in | 15 +++++++++++++++ embassy-stm32/build.rs | 10 ---------- embassy-stm32/tl_mbox.x.in | 15 --------------- 4 files changed, 27 insertions(+), 26 deletions(-) create mode 100644 embassy-stm32-wpan/tl_mbox.x.in delete mode 100644 embassy-stm32/tl_mbox.x.in diff --git a/embassy-stm32-wpan/build.rs b/embassy-stm32-wpan/build.rs index 4edf73d59..94aac070d 100644 --- a/embassy-stm32-wpan/build.rs +++ b/embassy-stm32-wpan/build.rs @@ -1,4 +1,5 @@ -use std::env; +use std::path::PathBuf; +use std::{env, fs}; fn main() { match env::vars() @@ -10,6 +11,16 @@ fn main() { Err(GetOneError::None) => panic!("No stm32xx Cargo feature enabled"), Err(GetOneError::Multiple) => panic!("Multiple stm32xx Cargo features enabled"), } + + let out_dir = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + // ======== + // stm32wb tl_mbox link sections + + let out_file = out_dir.join("tl_mbox.x").to_string_lossy().to_string(); + fs::write(out_file, fs::read_to_string("tl_mbox.x.in").unwrap()).unwrap(); + println!("cargo:rustc-link-search={}", out_dir.display()); + println!("cargo:rerun-if-changed=tl_mbox.x.in"); } enum GetOneError { diff --git a/embassy-stm32-wpan/tl_mbox.x.in b/embassy-stm32-wpan/tl_mbox.x.in new file mode 100644 index 000000000..b6eecb429 --- /dev/null +++ b/embassy-stm32-wpan/tl_mbox.x.in @@ -0,0 +1,15 @@ +MEMORY +{ + RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* + * Scatter the mailbox interface memory sections in shared memory + */ +SECTIONS +{ + TL_REF_TABLE (NOLOAD) : { *(TL_REF_TABLE) } >RAM_SHARED + + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED +} diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index f71074bcf..40103d322 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -911,16 +911,6 @@ fn main() { println!("cargo:rustc-cfg={}x{}", &chip_name[..9], &chip_name[10..11]); } - // ======== - // stm32wb tl_mbox link sections - - if chip_name.starts_with("stm32wb") { - let out_file = out_dir.join("tl_mbox.x").to_string_lossy().to_string(); - fs::write(out_file, fs::read_to_string("tl_mbox.x.in").unwrap()).unwrap(); - println!("cargo:rustc-link-search={}", out_dir.display()); - println!("cargo:rerun-if-changed=tl_mbox.x.in"); - } - // ======= // Features for targeting groups of chips diff --git a/embassy-stm32/tl_mbox.x.in b/embassy-stm32/tl_mbox.x.in deleted file mode 100644 index b6eecb429..000000000 --- a/embassy-stm32/tl_mbox.x.in +++ /dev/null @@ -1,15 +0,0 @@ -MEMORY -{ - RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K -} - -/* - * Scatter the mailbox interface memory sections in shared memory - */ -SECTIONS -{ - TL_REF_TABLE (NOLOAD) : { *(TL_REF_TABLE) } >RAM_SHARED - - MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED - MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED -} -- cgit From 018622f607a17037903ef7c5592dda762002f89b Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 25 Jun 2023 11:38:48 -0500 Subject: stm32/wpan: update example --- examples/stm32wb/src/bin/tl_mbox_mac.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs index afd319a41..f67be4682 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac.rs +++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs @@ -49,7 +49,9 @@ async fn main(_spawner: Spawner) { let sys_event = mbox.sys_subsystem.read().await; info!("sys event: {}", sys_event.payload()); - mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; + let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; + info!("initialized mac: {}", result); + // // info!("starting ble..."); // mbox.ble_subsystem.t_write(0x0c, &[]).await; -- cgit