diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs index 5cc0bb20..06237799 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32/src/tl_mbox/ble.rs @@ -1,5 +1,3 @@ -use core::mem::MaybeUninit; - use embassy_futures::block_on; use super::cmd::CmdSerial; @@ -10,17 +8,17 @@ use super::{ channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_CHANNEL, TL_REF_TABLE, }; -use crate::ipcc::Ipcc; use crate::tl_mbox::cmd::CmdPacket; +use crate::tl_mbox::ipcc::Ipcc; pub struct Ble; impl Ble { - pub(crate) fn new() -> Self { + pub fn enable() { unsafe { LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); - TL_BLE_TABLE = MaybeUninit::new(BleTable { + TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable { pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), pcs_buffer: CS_BUFFER.as_mut_ptr().cast(), pevt_queue: EVT_QUEUE.as_ptr().cast(), @@ -29,11 +27,9 @@ impl Ble { } Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); - - Ble } - pub(crate) fn evt_handler() { + pub fn evt_handler() { unsafe { let mut node_ptr = core::ptr::null_mut(); let node_ptr_ptr: *mut _ = &mut node_ptr; @@ -51,7 +47,7 @@ impl Ble { Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); } - pub(crate) fn send_cmd(buf: &[u8]) { + pub fn send_cmd(buf: &[u8]) { unsafe { let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial; diff --git a/embassy-stm32/src/tl_mbox/channels.rs b/embassy-stm32/src/tl_mbox/channels.rs index aaa6ce17..25a065ba 100644 --- a/embassy-stm32/src/tl_mbox/channels.rs +++ b/embassy-stm32/src/tl_mbox/channels.rs @@ -50,7 +50,7 @@ //! pub mod cpu1 { - use crate::ipcc::IpccChannel; + use crate::tl_mbox::ipcc::IpccChannel; // Not used currently but reserved pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; @@ -75,7 +75,7 @@ pub mod cpu1 { } pub mod cpu2 { - use crate::ipcc::IpccChannel; + use crate::tl_mbox::ipcc::IpccChannel; pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs index 04feb3e6..47a8b72f 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32/src/tl_mbox/evt.rs @@ -3,7 +3,7 @@ use core::mem::MaybeUninit; use super::cmd::{AclDataPacket, AclDataSerial}; use super::consts::TlPacketType; use super::{PacketHeader, TL_EVT_HEADER_SIZE}; -use crate::tl_mbox::mm; +use crate::tl_mbox::mm::MemoryManager; /// the payload of [`Evt`] for a command status event #[derive(Copy, Clone)] @@ -131,6 +131,6 @@ impl EvtBox { impl Drop for EvtBox { fn drop(&mut self) { - mm::MemoryManager::evt_drop(self.ptr); + MemoryManager::evt_drop(self.ptr); } } diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs index 6e0818cf..e28a6aa0 100644 --- a/embassy-stm32/src/tl_mbox/mm.rs +++ b/embassy-stm32/src/tl_mbox/mm.rs @@ -1,22 +1,20 @@ -use core::mem::MaybeUninit; - use super::evt::EvtPacket; use super::unsafe_linked_list::LinkedListNode; use super::{ channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE, }; -use crate::ipcc::Ipcc; +use crate::tl_mbox::ipcc::Ipcc; pub struct MemoryManager; impl MemoryManager { - pub fn new() -> Self { + pub fn enable() { unsafe { LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr()); LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); - TL_MEM_MANAGER_TABLE = MaybeUninit::new(MemManagerTable { + 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(), ble_pool: EVT_POOL.as_ptr().cast(), @@ -26,8 +24,6 @@ impl MemoryManager { traces_pool_size: 0, }); } - - MemoryManager } pub fn evt_handler() { diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs index 1c927efa..616f7dc5 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32/src/tl_mbox/mod.rs @@ -1,7 +1,9 @@ use core::mem::MaybeUninit; +use atomic_polyfill::{compiler_fence, Ordering}; use bit_field::BitField; use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; +use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; @@ -13,13 +15,16 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam}; use self::sys::Sys; use self::unsafe_linked_list::LinkedListNode; use crate::interrupt; -use crate::ipcc::{Config, Ipcc}; +use crate::peripherals::IPCC; +pub use crate::tl_mbox::ipcc::Config; +use crate::tl_mbox::ipcc::Ipcc; mod ble; mod channels; mod cmd; mod consts; mod evt; +mod ipcc; mod mm; mod shci; mod sys; @@ -60,6 +65,8 @@ pub struct ReceiveInterruptHandler {} impl interrupt::Handler for ReceiveInterruptHandler { unsafe fn on_interrupt() { + // info!("ipcc rx interrupt"); + if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { sys::Sys::evt_handler(); } else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { @@ -74,6 +81,8 @@ pub struct TransmitInterruptHandler {} impl interrupt::Handler for TransmitInterruptHandler { unsafe fn on_interrupt() { + // info!("ipcc tx interrupt"); + if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { // TODO: handle this case let _ = sys::Sys::cmd_evt_handler(); @@ -307,21 +316,24 @@ static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251 // TODO: get a better size, this is a placeholder pub(crate) static TL_CHANNEL: Channel = Channel::new(); -pub struct TlMbox { - _sys: Sys, - _ble: Ble, - _mm: MemoryManager, +pub struct TlMbox<'d> { + _ipcc: PeripheralRef<'d, IPCC>, } -impl TlMbox { +impl<'d> TlMbox<'d> { /// initializes low-level transport between CPU1 and BLE stack on CPU2 - pub fn init( + pub fn new( + ipcc: impl Peripheral

+ 'd, _irqs: impl interrupt::Binding + interrupt::Binding, config: Config, - ) -> TlMbox { + ) -> Self { + into_ref!(ipcc); + unsafe { - TL_REF_TABLE = MaybeUninit::new(RefTable { + compiler_fence(Ordering::AcqRel); + + TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable { device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(), ble_table: TL_BLE_TABLE.as_ptr(), thread_table: TL_THREAD_TABLE.as_ptr(), @@ -334,6 +346,10 @@ impl TlMbox { ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(), }); + // info!("TL_REF_TABLE addr: {:x}", TL_REF_TABLE.as_ptr() as usize); + + compiler_fence(Ordering::AcqRel); + TL_SYS_TABLE = MaybeUninit::zeroed(); TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed(); TL_BLE_TABLE = MaybeUninit::zeroed(); @@ -352,13 +368,15 @@ impl TlMbox { CS_BUFFER = MaybeUninit::zeroed(); BLE_CMD_BUFFER = MaybeUninit::zeroed(); HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); + + compiler_fence(Ordering::AcqRel); } - Ipcc::init(config); + Ipcc::enable(config); - let _sys = Sys::new(); - let _ble = Ble::new(); - let _mm = MemoryManager::new(); + Sys::enable(); + Ble::enable(); + MemoryManager::enable(); // enable interrupts unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend(); @@ -367,7 +385,7 @@ impl TlMbox { unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable(); unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable(); - TlMbox { _sys, _ble, _mm } + Self { _ipcc: ipcc } } pub fn wireless_fw_info(&self) -> Option { diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32/src/tl_mbox/shci.rs index 3d7e994a..6b5b2dd1 100644 --- a/embassy-stm32/src/tl_mbox/shci.rs +++ b/embassy-stm32/src/tl_mbox/shci.rs @@ -3,7 +3,7 @@ use super::cmd::CmdPacket; use super::consts::TlPacketType; use super::{channels, TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE, TL_SYS_TABLE}; -use crate::ipcc::Ipcc; +use crate::tl_mbox::ipcc::Ipcc; const SCHI_OPCODE_BLE_INIT: u16 = 0xfc66; pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs index 79e25714..9685fb92 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32/src/tl_mbox/sys.rs @@ -1,5 +1,3 @@ -use core::mem::MaybeUninit; - use embassy_futures::block_on; use super::cmd::{CmdPacket, CmdSerial}; @@ -7,27 +5,25 @@ use super::consts::TlPacketType; use super::evt::{CcEvt, EvtBox, EvtSerial}; use super::unsafe_linked_list::LinkedListNode; use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_CHANNEL, TL_REF_TABLE, TL_SYS_TABLE}; -use crate::ipcc::Ipcc; +use crate::tl_mbox::ipcc::Ipcc; pub struct Sys; impl Sys { - pub(crate) fn new() -> Self { + pub fn enable() { unsafe { LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); - TL_SYS_TABLE = MaybeUninit::new(SysTable { + TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable { pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), }); } Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); - - Sys } - pub(crate) fn evt_handler() { + pub fn evt_handler() { unsafe { let mut node_ptr = core::ptr::null_mut(); let node_ptr_ptr: *mut _ = &mut node_ptr; @@ -46,7 +42,7 @@ impl Sys { Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); } - pub(crate) fn cmd_evt_handler() -> CcEvt { + pub fn cmd_evt_handler() -> CcEvt { Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); // ST's command response data structure is really convoluted. @@ -68,7 +64,7 @@ impl Sys { } #[allow(dead_code)] - pub(crate) fn send_cmd(buf: &[u8]) { + pub fn send_cmd(buf: &[u8]) { unsafe { // TODO: check this let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer;