aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-23 19:59:48 -0500
committerxoviat <[email protected]>2023-06-23 19:59:48 -0500
commitd43417e97c4de487b4ebf018830825e034c5394e (patch)
tree2ddd5c40fe44938b969014a732445a1f4c37044d
parent91fdd76053c747c569b0eefe0715522465fe0194 (diff)
stm32/wpan: implement mm pattern
-rw-r--r--embassy-stm32-wpan/src/consts.rs4
-rw-r--r--embassy-stm32-wpan/src/evt.rs33
-rw-r--r--embassy-stm32-wpan/src/sub/ble.rs25
-rw-r--r--embassy-stm32-wpan/src/sub/mac.rs48
-rw-r--r--embassy-stm32-wpan/src/sub/mm.rs23
-rw-r--r--embassy-stm32-wpan/src/sub/sys.rs3
-rw-r--r--tests/stm32/src/bin/tl_mbox.rs4
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 {
87pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; 87pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE;
88#[allow(dead_code)] 88#[allow(dead_code)]
89pub const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; 89pub const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE;
90
91pub const TL_BLEEVT_CC_OPCODE: u8 = 0x0E;
92pub const TL_BLEEVT_CS_OPCODE: u8 = 0x0F;
93pub 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 @@
1use core::marker::PhantomData;
1use core::{ptr, slice}; 2use core::{ptr, slice};
2 3
3use super::PacketHeader; 4use super::PacketHeader;
@@ -93,17 +94,22 @@ impl EvtPacket {
93 } 94 }
94} 95}
95 96
97pub trait MemoryManager {
98 unsafe fn drop_event_packet(evt: *mut EvtPacket);
99}
100
96/// smart pointer to the [`EvtPacket`] that will dispose of [`EvtPacket`] buffer automatically 101/// smart pointer to the [`EvtPacket`] that will dispose of [`EvtPacket`] buffer automatically
97/// on [`Drop`] 102/// on [`Drop`]
98#[derive(Debug)] 103#[derive(Debug)]
99pub struct EvtBox { 104pub struct EvtBox<T: MemoryManager> {
100 ptr: *mut EvtPacket, 105 ptr: *mut EvtPacket,
106 mm: PhantomData<T>,
101} 107}
102 108
103unsafe impl Send for EvtBox {} 109unsafe impl<T: MemoryManager> Send for EvtBox<T> {}
104impl EvtBox { 110impl<T: MemoryManager> EvtBox<T> {
105 pub(super) fn new(ptr: *mut EvtPacket) -> Self { 111 pub(super) fn new(ptr: *mut EvtPacket) -> Self {
106 Self { ptr } 112 Self { ptr, mm: PhantomData }
107 } 113 }
108 114
109 /// Returns information about the event 115 /// Returns information about the event
@@ -126,9 +132,6 @@ impl EvtBox {
126 } 132 }
127 } 133 }
128 134
129 /// writes an underlying [`EvtPacket`] into the provided buffer.
130 /// Returns the number of bytes that were written.
131 /// Returns an error if event kind is unknown or if provided buffer size is not enough.
132 pub fn serial<'a>(&'a self) -> &'a [u8] { 135 pub fn serial<'a>(&'a self) -> &'a [u8] {
133 unsafe { 136 unsafe {
134 let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial; 137 let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial;
@@ -141,20 +144,8 @@ impl EvtBox {
141 } 144 }
142} 145}
143 146
144impl Drop for EvtBox { 147impl<T: MemoryManager> Drop for EvtBox<T> {
145 fn drop(&mut self) { 148 fn drop(&mut self) {
146 #[cfg(feature = "ble")] 149 unsafe { T::drop_event_packet(self.ptr) };
147 unsafe {
148 use crate::sub::mm;
149
150 mm::MemoryManager::drop_event_packet(self.ptr)
151 };
152
153 #[cfg(feature = "mac")]
154 unsafe {
155 use crate::sub::mac;
156
157 mac::Mac::drop_event_packet(self.ptr)
158 }
159 } 150 }
160} 151}
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 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2use core::ptr;
2 3
3use embassy_stm32::ipcc::Ipcc; 4use embassy_stm32::ipcc::Ipcc;
4use hci::Opcode; 5use hci::Opcode;
5 6
6use crate::channels;
7use crate::cmd::CmdPacket; 7use crate::cmd::CmdPacket;
8use crate::consts::TlPacketType; 8use crate::consts::{TlPacketType, TL_BLEEVT_CC_OPCODE, TL_BLEEVT_CS_OPCODE};
9use crate::evt::EvtBox; 9use crate::evt::{EvtBox, EvtPacket, EvtStub};
10use crate::sub::mm;
10use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; 11use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE};
11use crate::unsafe_linked_list::LinkedListNode; 12use crate::unsafe_linked_list::LinkedListNode;
13use crate::{channels, evt};
12 14
13pub struct Ble { 15pub struct Ble {
14 phantom: PhantomData<Ble>, 16 phantom: PhantomData<Ble>,
@@ -30,7 +32,7 @@ impl Ble {
30 Self { phantom: PhantomData } 32 Self { phantom: PhantomData }
31 } 33 }
32 /// `HW_IPCC_BLE_EvtNot` 34 /// `HW_IPCC_BLE_EvtNot`
33 pub async fn tl_read(&self) -> EvtBox { 35 pub async fn tl_read(&self) -> EvtBox<Self> {
34 Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { 36 Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe {
35 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { 37 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) {
36 Some(EvtBox::new(node_ptr.cast())) 38 Some(EvtBox::new(node_ptr.cast()))
@@ -63,6 +65,21 @@ impl Ble {
63 } 65 }
64} 66}
65 67
68impl evt::MemoryManager for Ble {
69 /// SAFETY: passing a pointer to something other than a managed event packet is UB
70 unsafe fn drop_event_packet(evt: *mut EvtPacket) {
71 let stub = unsafe {
72 let p_evt_stub = &(*evt).evt_serial as *const _ as *const EvtStub;
73
74 ptr::read_volatile(p_evt_stub)
75 };
76
77 if !(stub.evt_code == TL_BLEEVT_CS_OPCODE || stub.evt_code == TL_BLEEVT_CC_OPCODE) {
78 mm::MemoryManager::drop_event_packet(evt);
79 }
80 }
81}
82
66pub extern crate stm32wb_hci as hci; 83pub extern crate stm32wb_hci as hci;
67 84
68impl hci::Controller for Ble { 85impl 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;
8use embassy_stm32::ipcc::Ipcc; 8use embassy_stm32::ipcc::Ipcc;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::channels;
12use crate::cmd::CmdPacket; 11use crate::cmd::CmdPacket;
13use crate::consts::TlPacketType; 12use crate::consts::TlPacketType;
14use crate::evt::{EvtBox, EvtPacket}; 13use crate::evt::{EvtBox, EvtPacket};
15use crate::tables::{ 14use crate::tables::{
16 Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE, 15 Mac802_15_4Table, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_MAC_802_15_4_TABLE,
17}; 16};
17use crate::{channels, evt};
18 18
19static MAC_WAKER: AtomicWaker = AtomicWaker::new(); 19static MAC_WAKER: AtomicWaker = AtomicWaker::new();
20static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); 20static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false);
@@ -36,31 +36,10 @@ impl Mac {
36 Self { phantom: PhantomData } 36 Self { phantom: PhantomData }
37 } 37 }
38 38
39 /// SAFETY: passing a pointer to something other than a managed event packet is UB
40 pub(crate) unsafe fn drop_event_packet(_: *mut EvtPacket) {
41 // Write the ack
42 CmdPacket::write_into(
43 MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _,
44 TlPacketType::OtAck,
45 0,
46 &[],
47 );
48
49 // Clear the rx flag
50 let _ = poll_once(Ipcc::receive::<bool>(
51 channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL,
52 || None,
53 ));
54
55 // Allow a new read call
56 MAC_EVT_OUT.store(false, Ordering::SeqCst);
57 MAC_WAKER.wake();
58 }
59
60 /// `HW_IPCC_MAC_802_15_4_EvtNot` 39 /// `HW_IPCC_MAC_802_15_4_EvtNot`
61 /// 40 ///
62 /// This function will stall if the previous `EvtBox` has not been dropped 41 /// This function will stall if the previous `EvtBox` has not been dropped
63 pub async fn read(&self) -> EvtBox { 42 pub async fn read(&self) -> EvtBox<Self> {
64 // Wait for the last event box to be dropped 43 // Wait for the last event box to be dropped
65 poll_fn(|cx| { 44 poll_fn(|cx| {
66 MAC_WAKER.register(cx.waker()); 45 MAC_WAKER.register(cx.waker());
@@ -109,3 +88,26 @@ impl Mac {
109 .await; 88 .await;
110 } 89 }
111} 90}
91
92impl evt::MemoryManager for Mac {
93 /// SAFETY: passing a pointer to something other than a managed event packet is UB
94 unsafe fn drop_event_packet(_: *mut EvtPacket) {
95 // Write the ack
96 CmdPacket::write_into(
97 MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _,
98 TlPacketType::OtAck,
99 0,
100 &[],
101 );
102
103 // Clear the rx flag
104 let _ = poll_once(Ipcc::receive::<bool>(
105 channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL,
106 || None,
107 ));
108
109 // Allow a new read call
110 MAC_EVT_OUT.store(false, Ordering::SeqCst);
111 MAC_WAKER.wake();
112 }
113}
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;
8use embassy_stm32::ipcc::Ipcc; 8use embassy_stm32::ipcc::Ipcc;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::channels;
12use crate::consts::POOL_SIZE; 11use crate::consts::POOL_SIZE;
13use crate::evt::EvtPacket; 12use crate::evt::EvtPacket;
14use crate::tables::{ 13use crate::tables::{
15 MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, 14 MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE,
16}; 15};
17use crate::unsafe_linked_list::LinkedListNode; 16use crate::unsafe_linked_list::LinkedListNode;
17use crate::{channels, evt};
18 18
19static MM_WAKER: AtomicWaker = AtomicWaker::new(); 19static MM_WAKER: AtomicWaker = AtomicWaker::new();
20static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); 20static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
@@ -43,16 +43,6 @@ impl MemoryManager {
43 Self { phantom: PhantomData } 43 Self { phantom: PhantomData }
44 } 44 }
45 45
46 #[allow(dead_code)]
47 /// SAFETY: passing a pointer to something other than a managed event packet is UB
48 pub(crate) unsafe fn drop_event_packet(evt: *mut EvtPacket) {
49 interrupt::free(|_| unsafe {
50 LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _);
51 });
52
53 MM_WAKER.wake();
54 }
55
56 pub async fn run_queue(&self) { 46 pub async fn run_queue(&self) {
57 loop { 47 loop {
58 poll_fn(|cx| unsafe { 48 poll_fn(|cx| unsafe {
@@ -77,3 +67,14 @@ impl MemoryManager {
77 } 67 }
78 } 68 }
79} 69}
70
71impl evt::MemoryManager for MemoryManager {
72 /// SAFETY: passing a pointer to something other than a managed event packet is UB
73 unsafe fn drop_event_packet(evt: *mut EvtPacket) {
74 interrupt::free(|_| unsafe {
75 LinkedListNode::insert_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), evt as *mut _);
76 });
77
78 MM_WAKER.wake();
79 }
80}
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;
6use crate::evt::{CcEvt, EvtBox, EvtPacket}; 6use crate::evt::{CcEvt, EvtBox, EvtPacket};
7#[allow(unused_imports)] 7#[allow(unused_imports)]
8use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; 8use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode};
9use crate::sub::mm;
9use crate::tables::{SysTable, WirelessFwInfoTable}; 10use crate::tables::{SysTable, WirelessFwInfoTable};
10use crate::unsafe_linked_list::LinkedListNode; 11use crate::unsafe_linked_list::LinkedListNode;
11use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; 12use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE};
@@ -73,7 +74,7 @@ impl Sys {
73 } 74 }
74 75
75 /// `HW_IPCC_SYS_EvtNot` 76 /// `HW_IPCC_SYS_EvtNot`
76 pub async fn read(&self) -> EvtBox { 77 pub async fn read(&self) -> EvtBox<mm::MemoryManager> {
77 Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { 78 Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe {
78 if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { 79 if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) {
79 Some(EvtBox::new(node_ptr.cast())) 80 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) {
39} 39}
40 40
41#[embassy_executor::main] 41#[embassy_executor::main]
42async fn main(_spawner: Spawner) { 42async fn main(spawner: Spawner) {
43 let p = embassy_stm32::init(config()); 43 let p = embassy_stm32::init(config());
44 info!("Hello World!"); 44 info!("Hello World!");
45 45
46 let config = Config::default(); 46 let config = Config::default();
47 let mut mbox = TlMbox::init(p.IPCC, Irqs, config); 47 let mut mbox = TlMbox::init(p.IPCC, Irqs, config);
48 48
49 // spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); 49 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
50 50
51 let sys_event = mbox.sys_subsystem.read().await; 51 let sys_event = mbox.sys_subsystem.read().await;
52 info!("sys event: {}", sys_event.payload()); 52 info!("sys event: {}", sys_event.payload());