stm32/wpan: use new ownership model
This commit is contained in:
parent
6d7d617f40
commit
443550b353
@ -1,3 +1,5 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_stm32::ipcc::Ipcc;
|
||||
|
||||
use crate::cmd::CmdPacket;
|
||||
@ -7,10 +9,12 @@ use crate::tables::BleTable;
|
||||
use crate::unsafe_linked_list::LinkedListNode;
|
||||
use crate::{channels, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE};
|
||||
|
||||
pub struct Ble;
|
||||
pub struct Ble {
|
||||
phantom: PhantomData<Ble>,
|
||||
}
|
||||
|
||||
impl Ble {
|
||||
pub(super) fn enable() {
|
||||
pub(crate) fn new() -> Self {
|
||||
unsafe {
|
||||
LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
|
||||
|
||||
@ -21,9 +25,11 @@ impl Ble {
|
||||
phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(),
|
||||
});
|
||||
}
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
}
|
||||
/// `HW_IPCC_BLE_EvtNot`
|
||||
pub async fn read() -> EvtBox {
|
||||
pub async fn 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()))
|
||||
@ -35,7 +41,7 @@ impl Ble {
|
||||
}
|
||||
|
||||
/// `TL_BLE_SendCmd`
|
||||
pub async fn write(opcode: u16, payload: &[u8]) {
|
||||
pub async fn 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);
|
||||
})
|
||||
@ -43,7 +49,7 @@ impl Ble {
|
||||
}
|
||||
|
||||
/// `TL_BLE_SendAclData`
|
||||
pub async fn acl_write(handle: u16, payload: &[u8]) {
|
||||
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 _,
|
||||
|
@ -6,6 +6,7 @@ pub mod fmt;
|
||||
use core::mem::MaybeUninit;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
|
||||
use ble::Ble;
|
||||
use cmd::CmdPacket;
|
||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
|
||||
use embassy_stm32::interrupt;
|
||||
@ -16,9 +17,10 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::Channel;
|
||||
use embassy_sync::signal::Signal;
|
||||
use evt::{CcEvt, EvtBox};
|
||||
use mm::MemoryManager;
|
||||
use sys::Sys;
|
||||
use tables::{
|
||||
BleTable, DeviceInfoTable, Mac802_15_4Table, MemManagerTable, RefTable, SysTable, ThreadTable, TracesTable,
|
||||
WirelessFwInfoTable,
|
||||
};
|
||||
use unsafe_linked_list::LinkedListNode;
|
||||
|
||||
@ -142,6 +144,10 @@ static STATE: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||
|
||||
pub struct TlMbox<'d> {
|
||||
_ipcc: PeripheralRef<'d, IPCC>,
|
||||
|
||||
pub sys_subsystem: Sys,
|
||||
pub mm_subsystem: MemoryManager,
|
||||
pub ble_subsystem: Ble,
|
||||
}
|
||||
|
||||
impl<'d> TlMbox<'d> {
|
||||
@ -226,9 +232,9 @@ impl<'d> TlMbox<'d> {
|
||||
|
||||
Ipcc::enable(config);
|
||||
|
||||
sys::Sys::enable();
|
||||
ble::Ble::enable();
|
||||
mm::MemoryManager::enable();
|
||||
let sys = sys::Sys::new();
|
||||
let ble = ble::Ble::new();
|
||||
let mm = mm::MemoryManager::new();
|
||||
|
||||
// enable interrupts
|
||||
interrupt::typelevel::IPCC_C1_RX::unpend();
|
||||
@ -239,18 +245,11 @@ impl<'d> TlMbox<'d> {
|
||||
|
||||
STATE.reset();
|
||||
|
||||
Self { _ipcc: ipcc }
|
||||
}
|
||||
|
||||
/// Returns CPU2 wireless firmware information (if present).
|
||||
pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {
|
||||
let info = unsafe { &(*(*TL_REF_TABLE.as_ptr()).device_info_table).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
|
||||
Self {
|
||||
_ipcc: ipcc,
|
||||
sys_subsystem: sys,
|
||||
ble_subsystem: ble,
|
||||
mm_subsystem: mm,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
//! Memory manager routines
|
||||
|
||||
use core::future::poll_fn;
|
||||
use core::marker::PhantomData;
|
||||
use core::task::Poll;
|
||||
|
||||
use cortex_m::interrupt;
|
||||
@ -17,10 +18,12 @@ use crate::{
|
||||
|
||||
static MM_WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
pub struct MemoryManager;
|
||||
pub struct MemoryManager {
|
||||
phantom: PhantomData<MemoryManager>,
|
||||
}
|
||||
|
||||
impl MemoryManager {
|
||||
pub fn enable() {
|
||||
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());
|
||||
@ -35,10 +38,12 @@ impl MemoryManager {
|
||||
tracespoolsize: 0,
|
||||
});
|
||||
}
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
}
|
||||
|
||||
/// SAFETY: passing a pointer to something other than an event packet is UB
|
||||
pub unsafe fn drop_event_packet(evt: *mut EvtPacket) {
|
||||
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 _);
|
||||
});
|
||||
@ -46,7 +51,7 @@ impl MemoryManager {
|
||||
MM_WAKER.wake();
|
||||
}
|
||||
|
||||
pub async fn run_queue() {
|
||||
pub async fn run_queue(&self) {
|
||||
loop {
|
||||
poll_fn(|cx| unsafe {
|
||||
MM_WAKER.register(cx.waker());
|
||||
|
@ -1,16 +1,20 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::cmd::CmdPacket;
|
||||
use crate::consts::TlPacketType;
|
||||
use crate::evt::EvtBox;
|
||||
use crate::shci::{ShciBleInitCmdParam, SCHI_OPCODE_BLE_INIT};
|
||||
use crate::tables::SysTable;
|
||||
use crate::tables::{SysTable, WirelessFwInfoTable};
|
||||
use crate::unsafe_linked_list::LinkedListNode;
|
||||
use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE};
|
||||
use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE};
|
||||
|
||||
pub struct Sys;
|
||||
pub struct Sys {
|
||||
phantom: PhantomData<Sys>,
|
||||
}
|
||||
|
||||
impl Sys {
|
||||
/// TL_Sys_Init
|
||||
pub fn enable() {
|
||||
pub(crate) fn new() -> Self {
|
||||
unsafe {
|
||||
LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
|
||||
|
||||
@ -19,30 +23,33 @@ impl Sys {
|
||||
sys_queue: SYSTEM_EVT_QUEUE.as_ptr(),
|
||||
});
|
||||
}
|
||||
|
||||
Self { phantom: PhantomData }
|
||||
}
|
||||
|
||||
// pub async fn shci_c2_ble_init(&mut self, param: ShciBleInitCmdParam) -> SchiCommandStatus {
|
||||
// let command_event = self
|
||||
// .write_and_get_response(TlPacketType::SysCmd, ShciOpcode::BleInit as u16, param.payload())
|
||||
// .await;
|
||||
//
|
||||
// let payload = command_event.payload[0];
|
||||
// // info!("payload: {:x}", payload);
|
||||
//
|
||||
// payload.try_into().unwrap()
|
||||
// }
|
||||
/// Returns CPU2 wireless firmware information (if present).
|
||||
pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {
|
||||
let info = unsafe { TL_DEVICE_INFO_TABLE.as_mut_ptr().read_volatile().wireless_fw_info_table };
|
||||
|
||||
pub fn write(opcode: u16, payload: &[u8]) {
|
||||
// Zero version indicates that CPU2 wasn't active and didn't fill the information table
|
||||
if info.version != 0 {
|
||||
Some(info)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(&self, opcode: u16, payload: &[u8]) {
|
||||
unsafe {
|
||||
CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode, payload);
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn shci_c2_ble_init(param: ShciBleInitCmdParam) {
|
||||
pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) {
|
||||
debug!("sending SHCI");
|
||||
|
||||
Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || {
|
||||
Self::write(SCHI_OPCODE_BLE_INIT, param.payload());
|
||||
self.write(SCHI_OPCODE_BLE_INIT, param.payload());
|
||||
})
|
||||
.await;
|
||||
|
||||
@ -50,7 +57,7 @@ impl Sys {
|
||||
}
|
||||
|
||||
/// `HW_IPCC_SYS_EvtNot`
|
||||
pub async fn read() -> 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()))
|
||||
|
@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) {
|
||||
let mbox = TlMbox::init(p.IPCC, Irqs, config);
|
||||
|
||||
loop {
|
||||
let wireless_fw_info = mbox.wireless_fw_info();
|
||||
let wireless_fw_info = mbox.sys_subsystem.wireless_fw_info();
|
||||
match wireless_fw_info {
|
||||
None => info!("not yet initialized"),
|
||||
Some(fw_info) => {
|
||||
|
@ -6,8 +6,6 @@ use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_stm32::bind_interrupts;
|
||||
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
||||
use embassy_stm32_wpan::ble::Ble;
|
||||
use embassy_stm32_wpan::sys::Sys;
|
||||
use embassy_stm32_wpan::TlMbox;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
@ -46,15 +44,18 @@ async fn main(_spawner: Spawner) {
|
||||
info!("Hello World!");
|
||||
|
||||
let config = Config::default();
|
||||
let _ = TlMbox::init(p.IPCC, Irqs, config);
|
||||
let mbox = TlMbox::init(p.IPCC, Irqs, config);
|
||||
|
||||
Sys::shci_c2_ble_init(Default::default()).await;
|
||||
let sys_event = mbox.sys_subsystem.read().await;
|
||||
info!("sys event: {}", sys_event.payload());
|
||||
|
||||
mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
|
||||
|
||||
info!("starting ble...");
|
||||
Ble::write(0x0c, &[]).await;
|
||||
mbox.ble_subsystem.write(0x0c, &[]).await;
|
||||
|
||||
info!("waiting for ble...");
|
||||
let ble_event = Ble::read().await;
|
||||
let ble_event = mbox.ble_subsystem.read().await;
|
||||
|
||||
info!("ble event: {}", ble_event.payload());
|
||||
|
||||
|
@ -13,8 +13,6 @@ use embassy_executor::Spawner;
|
||||
use embassy_futures::poll_once;
|
||||
use embassy_stm32::bind_interrupts;
|
||||
use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
|
||||
use embassy_stm32_wpan::ble::Ble;
|
||||
use embassy_stm32_wpan::sys::Sys;
|
||||
use embassy_stm32_wpan::{mm, TlMbox};
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
@ -24,8 +22,8 @@ bind_interrupts!(struct Irqs{
|
||||
});
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn run_mm_queue() {
|
||||
mm::MemoryManager::run_queue().await;
|
||||
async fn run_mm_queue(memory_manager: mm::MemoryManager) {
|
||||
memory_manager.run_queue().await;
|
||||
}
|
||||
|
||||
#[embassy_executor::main]
|
||||
@ -33,50 +31,41 @@ async fn main(spawner: Spawner) {
|
||||
let p = embassy_stm32::init(config());
|
||||
info!("Hello World!");
|
||||
|
||||
spawner.spawn(run_mm_queue()).unwrap();
|
||||
|
||||
let config = Config::default();
|
||||
let mbox = TlMbox::init(p.IPCC, Irqs, config);
|
||||
|
||||
let ready_event = Sys::read().await;
|
||||
let _ = poll_once(Sys::read()); // clear rx not
|
||||
spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
|
||||
|
||||
let ready_event = mbox.sys_subsystem.read().await;
|
||||
let _ = poll_once(mbox.sys_subsystem.read()); // clear rx not
|
||||
|
||||
info!("coprocessor ready {}", ready_event.payload());
|
||||
|
||||
// test memory manager
|
||||
mem::drop(ready_event);
|
||||
|
||||
loop {
|
||||
let wireless_fw_info = mbox.wireless_fw_info();
|
||||
match wireless_fw_info {
|
||||
None => {}
|
||||
Some(fw_info) => {
|
||||
let version_major = fw_info.version_major();
|
||||
let version_minor = fw_info.version_minor();
|
||||
let subversion = fw_info.subversion();
|
||||
let fw_info = mbox.sys_subsystem.wireless_fw_info().unwrap();
|
||||
let version_major = fw_info.version_major();
|
||||
let version_minor = fw_info.version_minor();
|
||||
let subversion = fw_info.subversion();
|
||||
|
||||
let sram2a_size = fw_info.sram2a_size();
|
||||
let sram2b_size = fw_info.sram2b_size();
|
||||
let sram2a_size = fw_info.sram2a_size();
|
||||
let sram2b_size = fw_info.sram2b_size();
|
||||
|
||||
info!(
|
||||
"version {}.{}.{} - SRAM2a {} - SRAM2b {}",
|
||||
version_major, version_minor, subversion, sram2a_size, sram2b_size
|
||||
);
|
||||
info!(
|
||||
"version {}.{}.{} - SRAM2a {} - SRAM2b {}",
|
||||
version_major, version_minor, subversion, sram2a_size, sram2b_size
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
Timer::after(Duration::from_millis(50)).await;
|
||||
|
||||
Timer::after(Duration::from_millis(50)).await;
|
||||
}
|
||||
|
||||
Sys::shci_c2_ble_init(Default::default()).await;
|
||||
mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
|
||||
|
||||
info!("starting ble...");
|
||||
Ble::write(0x0c, &[]).await;
|
||||
mbox.ble_subsystem.write(0x0c, &[]).await;
|
||||
|
||||
info!("waiting for ble...");
|
||||
let ble_event = Ble::read().await;
|
||||
let ble_event = mbox.ble_subsystem.read().await;
|
||||
|
||||
info!("ble event: {}", ble_event.payload());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user