aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-23 13:11:18 -0600
committerxoviat <[email protected]>2025-11-23 13:11:18 -0600
commit08125aa919a4dc4de79f91de9a7f3586e51a7739 (patch)
treebe2320ff9ee6b1bb3a2f9b35d714ba8c8d202b18
parent54a153a9a24a58a7cfa1210f78f61beb913baf2d (diff)
wpan: restructure ipcc and hil test wpan_mac
-rwxr-xr-xci.sh2
-rw-r--r--embassy-stm32-wpan/src/channels.rs15
-rw-r--r--embassy-stm32-wpan/src/lib.rs46
-rw-r--r--embassy-stm32-wpan/src/mac/commands.rs9
-rw-r--r--embassy-stm32-wpan/src/mac/control.rs4
-rw-r--r--embassy-stm32-wpan/src/mac/driver.rs6
-rw-r--r--embassy-stm32-wpan/src/mac/event.rs6
-rw-r--r--embassy-stm32-wpan/src/mac/runner.rs12
-rw-r--r--embassy-stm32-wpan/src/shci.rs134
-rw-r--r--embassy-stm32-wpan/src/sub/ble.rs85
-rw-r--r--embassy-stm32-wpan/src/sub/mac.rs144
-rw-r--r--embassy-stm32-wpan/src/sub/mm.rs37
-rw-r--r--embassy-stm32-wpan/src/sub/sys.rs82
-rw-r--r--embassy-stm32-wpan/src/tables.rs50
-rw-r--r--embassy-stm32/src/ipcc.rs250
-rw-r--r--examples/stm32wb/src/bin/eddystone_beacon.rs116
-rw-r--r--examples/stm32wb/src/bin/gatt_server.rs118
-rw-r--r--examples/stm32wb/src/bin/mac_ffd.rs47
-rw-r--r--examples/stm32wb/src/bin/mac_ffd_net.rs9
-rw-r--r--examples/stm32wb/src/bin/mac_rfd.rs40
-rw-r--r--examples/stm32wb/src/bin/tl_mbox.rs2
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_ble.rs21
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_mac.rs12
-rw-r--r--tests/stm32/src/bin/wpan_ble.rs120
-rw-r--r--tests/stm32/src/bin/wpan_mac.rs29
25 files changed, 736 insertions, 660 deletions
diff --git a/ci.sh b/ci.sh
index 6cc2a031d..b4ed0dc18 100755
--- a/ci.sh
+++ b/ci.sh
@@ -35,7 +35,7 @@ rm -rf out/tests/nrf5340-dk
35# disabled because these boards are not on the shelf 35# disabled because these boards are not on the shelf
36rm -rf out/tests/mspm0g3507 36rm -rf out/tests/mspm0g3507
37 37
38rm out/tests/stm32wb55rg/wpan_mac 38# rm out/tests/stm32wb55rg/wpan_mac
39rm out/tests/stm32wb55rg/wpan_ble 39rm out/tests/stm32wb55rg/wpan_ble
40 40
41# unstable, I think it's running out of RAM? 41# unstable, I think it's running out of RAM?
diff --git a/embassy-stm32-wpan/src/channels.rs b/embassy-stm32-wpan/src/channels.rs
index 9a2be1cfa..58f857136 100644
--- a/embassy-stm32-wpan/src/channels.rs
+++ b/embassy-stm32-wpan/src/channels.rs
@@ -48,9 +48,20 @@
48//! |<----HW_IPCC_TRACES_CHANNEL----------------------| 48//! |<----HW_IPCC_TRACES_CHANNEL----------------------|
49//! | | 49//! | |
50//! 50//!
51//!
52
53#[repr(u8)]
54pub enum IpccChannel {
55 Channel1 = 1,
56 Channel2 = 2,
57 Channel3 = 3,
58 Channel4 = 4,
59 Channel5 = 5,
60 Channel6 = 6,
61}
51 62
52pub mod cpu1 { 63pub mod cpu1 {
53 use embassy_stm32::ipcc::IpccChannel; 64 use super::IpccChannel;
54 65
55 pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; 66 pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1;
56 pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2; 67 pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2;
@@ -70,7 +81,7 @@ pub mod cpu1 {
70} 81}
71 82
72pub mod cpu2 { 83pub mod cpu2 {
73 use embassy_stm32::ipcc::IpccChannel; 84 use super::IpccChannel;
74 85
75 pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; 86 pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1;
76 pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; 87 pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2;
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs
index f6b1f6021..18b0feada 100644
--- a/embassy-stm32-wpan/src/lib.rs
+++ b/embassy-stm32-wpan/src/lib.rs
@@ -26,7 +26,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
26 26
27use embassy_hal_internal::Peri; 27use embassy_hal_internal::Peri;
28use embassy_stm32::interrupt; 28use embassy_stm32::interrupt;
29use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler}; 29use embassy_stm32::ipcc::{Config, Ipcc, IpccRxChannel, ReceiveInterruptHandler, TransmitInterruptHandler};
30use embassy_stm32::peripherals::IPCC; 30use embassy_stm32::peripherals::IPCC;
31use sub::mm::MemoryManager; 31use sub::mm::MemoryManager;
32use sub::sys::Sys; 32use sub::sys::Sys;
@@ -53,14 +53,13 @@ type PacketHeader = LinkedListNode;
53 53
54/// Transport Layer for the Mailbox interface 54/// Transport Layer for the Mailbox interface
55pub struct TlMbox<'d> { 55pub struct TlMbox<'d> {
56 _ipcc: Peri<'d, IPCC>, 56 pub sys_subsystem: Sys<'d>,
57 57 pub mm_subsystem: MemoryManager<'d>,
58 pub sys_subsystem: Sys,
59 pub mm_subsystem: MemoryManager,
60 #[cfg(feature = "ble")] 58 #[cfg(feature = "ble")]
61 pub ble_subsystem: sub::ble::Ble, 59 pub ble_subsystem: sub::ble::Ble<'d>,
62 #[cfg(feature = "mac")] 60 #[cfg(feature = "mac")]
63 pub mac_subsystem: sub::mac::Mac, 61 pub mac_subsystem: sub::mac::Mac<'d>,
62 pub traces: IpccRxChannel<'d>,
64} 63}
65 64
66impl<'d> TlMbox<'d> { 65impl<'d> TlMbox<'d> {
@@ -92,7 +91,7 @@ impl<'d> TlMbox<'d> {
92 /// be handled by `TL_BLE_Init`; see Figure 66). This completes the procedure laid out in 91 /// be handled by `TL_BLE_Init`; see Figure 66). This completes the procedure laid out in
93 /// Figure 66. 92 /// Figure 66.
94 // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem 93 // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem
95 pub fn init( 94 pub async fn init(
96 ipcc: Peri<'d, IPCC>, 95 ipcc: Peri<'d, IPCC>,
97 _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler> 96 _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
98 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>, 97 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
@@ -185,16 +184,35 @@ impl<'d> TlMbox<'d> {
185 compiler_fence(Ordering::SeqCst); 184 compiler_fence(Ordering::SeqCst);
186 185
187 // this is equivalent to `HW_IPCC_Enable`, which is called by `TL_Enable` 186 // this is equivalent to `HW_IPCC_Enable`, which is called by `TL_Enable`
188 Ipcc::enable(config); 187 let [
188 (_hw_ipcc_ble_cmd_channel, _ipcc_ble_event_channel),
189 (ipcc_system_cmd_rsp_channel, ipcc_system_event_channel),
190 (_ipcc_mac_802_15_4_cmd_rsp_channel, _ipcc_mac_802_15_4_notification_ack_channel),
191 (ipcc_mm_release_buffer_channel, _ipcc_traces_channel),
192 (_ipcc_ble_lld_cmd_channel, _ipcc_ble_lld_rsp_channel),
193 (_ipcc_hci_acl_data_channel, _),
194 ] = Ipcc::new(ipcc, _irqs, config).split();
195
196 let mm = sub::mm::MemoryManager::new(ipcc_mm_release_buffer_channel);
197 let mut sys = sub::sys::Sys::new(ipcc_system_cmd_rsp_channel, ipcc_system_event_channel);
198
199 debug!("sys event: {}", sys.read().await.payload());
189 200
190 Self { 201 Self {
191 _ipcc: ipcc, 202 sys_subsystem: sys,
192 sys_subsystem: sub::sys::Sys::new(),
193 #[cfg(feature = "ble")] 203 #[cfg(feature = "ble")]
194 ble_subsystem: sub::ble::Ble::new(), 204 ble_subsystem: sub::ble::Ble::new(
205 _hw_ipcc_ble_cmd_channel,
206 _ipcc_ble_event_channel,
207 _ipcc_hci_acl_data_channel,
208 ),
195 #[cfg(feature = "mac")] 209 #[cfg(feature = "mac")]
196 mac_subsystem: sub::mac::Mac::new(), 210 mac_subsystem: sub::mac::Mac::new(
197 mm_subsystem: sub::mm::MemoryManager::new(), 211 _ipcc_mac_802_15_4_cmd_rsp_channel,
212 _ipcc_mac_802_15_4_notification_ack_channel,
213 ),
214 mm_subsystem: mm,
215 traces: _ipcc_traces_channel,
198 } 216 }
199 } 217 }
200} 218}
diff --git a/embassy-stm32-wpan/src/mac/commands.rs b/embassy-stm32-wpan/src/mac/commands.rs
index a3a40f377..d96f0094a 100644
--- a/embassy-stm32-wpan/src/mac/commands.rs
+++ b/embassy-stm32-wpan/src/mac/commands.rs
@@ -393,9 +393,14 @@ impl<'a, T: AsRef<[u8]>> TryFrom<Frame<&'a T>> for DataRequest {
393 dst_pan_id: frame.dst_pan_id().ok_or(())?.into(), 393 dst_pan_id: frame.dst_pan_id().ok_or(())?.into(),
394 dst_address: frame.dst_addr().ok_or(())?.into(), 394 dst_address: frame.dst_addr().ok_or(())?.into(),
395 msdu_handle: frame.sequence_number().ok_or(())?, 395 msdu_handle: frame.sequence_number().ok_or(())?,
396 ack_tx: 0x00, 396 key_source: frame.key_source().unwrap_or_default().try_into().unwrap_or_default(),
397 ack_tx: frame.ack_request() as u8,
397 gts_tx: false, 398 gts_tx: false,
398 security_level: SecurityLevel::Unsecure, 399 security_level: if frame.security_enabled() {
400 SecurityLevel::Secured
401 } else {
402 SecurityLevel::Unsecure
403 },
399 ..Default::default() 404 ..Default::default()
400 }; 405 };
401 406
diff --git a/embassy-stm32-wpan/src/mac/control.rs b/embassy-stm32-wpan/src/mac/control.rs
index d2a7b65ee..14c6fdd2b 100644
--- a/embassy-stm32-wpan/src/mac/control.rs
+++ b/embassy-stm32-wpan/src/mac/control.rs
@@ -20,7 +20,7 @@ use crate::sub::mac::MacTx;
20 20
21pub struct Control<'a> { 21pub struct Control<'a> {
22 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, 22 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
23 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>, 23 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx<'a>>,
24 #[allow(unused)] 24 #[allow(unused)]
25 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>, 25 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
26} 26}
@@ -28,7 +28,7 @@ pub struct Control<'a> {
28impl<'a> Control<'a> { 28impl<'a> Control<'a> {
29 pub(crate) fn new( 29 pub(crate) fn new(
30 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, 30 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
31 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>, 31 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx<'a>>,
32 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>, 32 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
33 ) -> Self { 33 ) -> Self {
34 Self { 34 Self {
diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs
index c43d595b7..41171ce3d 100644
--- a/embassy-stm32-wpan/src/mac/driver.rs
+++ b/embassy-stm32-wpan/src/mac/driver.rs
@@ -37,8 +37,8 @@ impl NetworkState {
37} 37}
38 38
39pub struct DriverState<'d> { 39pub struct DriverState<'d> {
40 pub mac_tx: Mutex<CriticalSectionRawMutex, MacTx>, 40 pub mac_tx: Mutex<CriticalSectionRawMutex, MacTx<'d>>,
41 pub mac_rx: MacRx, 41 pub mac_rx: MacRx<'d>,
42 pub rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'d>>, 42 pub rx_event_channel: ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'d>>,
43 pub rx_data_channel: Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>, 43 pub rx_data_channel: Channel<CriticalSectionRawMutex, MacEvent<'d>, 1>,
44 pub tx_data_channel: Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>, 44 pub tx_data_channel: Channel<CriticalSectionRawMutex, (&'d mut [u8; MTU], usize), BUF_SIZE>,
@@ -48,7 +48,7 @@ pub struct DriverState<'d> {
48} 48}
49 49
50impl<'d> DriverState<'d> { 50impl<'d> DriverState<'d> {
51 pub const fn new(mac: Mac) -> Self { 51 pub const fn new(mac: Mac<'d>) -> Self {
52 let (mac_rx, mac_tx) = mac.split(); 52 let (mac_rx, mac_tx) = mac.split();
53 let mac_tx = Mutex::new(mac_tx); 53 let mac_tx = Mutex::new(mac_tx);
54 54
diff --git a/embassy-stm32-wpan/src/mac/event.rs b/embassy-stm32-wpan/src/mac/event.rs
index 9ca4f5a2a..39856e185 100644
--- a/embassy-stm32-wpan/src/mac/event.rs
+++ b/embassy-stm32-wpan/src/mac/event.rs
@@ -10,7 +10,7 @@ use super::responses::{
10}; 10};
11use crate::evt::{EvtBox, MemoryManager}; 11use crate::evt::{EvtBox, MemoryManager};
12use crate::mac::opcodes::OpcodeM0ToM4; 12use crate::mac::opcodes::OpcodeM0ToM4;
13use crate::sub::mac::{self, Mac}; 13use crate::sub::mac::{self, MacRx};
14 14
15pub(crate) trait ParseableMacEvent: Sized { 15pub(crate) trait ParseableMacEvent: Sized {
16 fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> { 16 fn from_buffer<'a>(buf: &'a [u8]) -> Result<&'a Self, ()> {
@@ -53,7 +53,7 @@ pub enum MacEvent<'a> {
53} 53}
54 54
55impl<'a> MacEvent<'a> { 55impl<'a> MacEvent<'a> {
56 pub(crate) fn new(event_box: EvtBox<Mac>) -> Result<Self, ()> { 56 pub(crate) fn new(event_box: EvtBox<MacRx>) -> Result<Self, ()> {
57 let payload = event_box.payload(); 57 let payload = event_box.payload();
58 let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap()); 58 let opcode = u16::from_le_bytes(payload[0..2].try_into().unwrap());
59 59
@@ -148,6 +148,6 @@ unsafe impl<'a> Send for MacEvent<'a> {}
148 148
149impl<'a> Drop for MacEvent<'a> { 149impl<'a> Drop for MacEvent<'a> {
150 fn drop(&mut self) { 150 fn drop(&mut self) {
151 unsafe { mac::Mac::drop_event_packet(ptr::null_mut()) }; 151 unsafe { mac::MacRx::drop_event_packet(ptr::null_mut()) };
152 } 152 }
153} 153}
diff --git a/embassy-stm32-wpan/src/mac/runner.rs b/embassy-stm32-wpan/src/mac/runner.rs
index acca70019..3b7d895df 100644
--- a/embassy-stm32-wpan/src/mac/runner.rs
+++ b/embassy-stm32-wpan/src/mac/runner.rs
@@ -24,11 +24,11 @@ pub struct Runner<'a> {
24 // therefore, we don't need to worry about overwriting events 24 // therefore, we don't need to worry about overwriting events
25 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, 25 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
26 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, 26 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
27 mac_rx: &'a mut MacRx, 27 mac_rx: Mutex<NoopRawMutex, &'a mut MacRx<'a>>,
28 28
29 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>, 29 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>,
30 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>, 30 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>,
31 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>, 31 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx<'a>>,
32 32
33 #[allow(unused)] 33 #[allow(unused)]
34 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>, 34 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
@@ -38,10 +38,10 @@ impl<'a> Runner<'a> {
38 pub(crate) fn new( 38 pub(crate) fn new(
39 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>, 39 rx_event_channel: &'a ZeroCopyPubSub<CriticalSectionRawMutex, MacEvent<'a>>,
40 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>, 40 rx_data_channel: &'a Channel<CriticalSectionRawMutex, MacEvent<'a>, 1>,
41 mac_rx: &'a mut MacRx, 41 mac_rx: &'a mut MacRx<'a>,
42 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>, 42 tx_data_channel: &'a Channel<CriticalSectionRawMutex, (&'a mut [u8; MTU], usize), BUF_SIZE>,
43 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>, 43 tx_buf_channel: &'a Channel<CriticalSectionRawMutex, &'a mut [u8; MTU], BUF_SIZE>,
44 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx>, 44 mac_tx: &'a Mutex<CriticalSectionRawMutex, MacTx<'a>>,
45 tx_buf_queue: &'a mut [[u8; MTU]; BUF_SIZE], 45 tx_buf_queue: &'a mut [[u8; MTU]; BUF_SIZE],
46 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>, 46 network_state: &'a blocking_mutex::Mutex<CriticalSectionRawMutex, RefCell<NetworkState>>,
47 short_address: [u8; 2], 47 short_address: [u8; 2],
@@ -61,7 +61,7 @@ impl<'a> Runner<'a> {
61 Self { 61 Self {
62 rx_event_channel, 62 rx_event_channel,
63 rx_data_channel, 63 rx_data_channel,
64 mac_rx, 64 mac_rx: Mutex::new(mac_rx),
65 tx_data_channel, 65 tx_data_channel,
66 tx_buf_channel, 66 tx_buf_channel,
67 mac_tx, 67 mac_tx,
@@ -83,7 +83,7 @@ impl<'a> Runner<'a> {
83 join::join( 83 join::join(
84 async { 84 async {
85 loop { 85 loop {
86 if let Ok(mac_event) = self.mac_rx.read().await { 86 if let Ok(mac_event) = self.mac_rx.try_lock().unwrap().read().await {
87 match mac_event { 87 match mac_event {
88 MacEvent::MlmeAssociateCnf(_) 88 MacEvent::MlmeAssociateCnf(_)
89 | MacEvent::MlmeDisassociateCnf(_) 89 | MacEvent::MlmeDisassociateCnf(_)
diff --git a/embassy-stm32-wpan/src/shci.rs b/embassy-stm32-wpan/src/shci.rs
index 30d689716..1946c55fd 100644
--- a/embassy-stm32-wpan/src/shci.rs
+++ b/embassy-stm32-wpan/src/shci.rs
@@ -274,69 +274,64 @@ pub struct ShciBleInitCmdParam {
274 pub options: u8, 274 pub options: u8,
275 /// Reserved for future use - shall be set to 0 275 /// Reserved for future use - shall be set to 0
276 pub hw_version: u8, 276 pub hw_version: u8,
277 // /** 277 ///
278 // * Maximum number of connection-oriented channels in initiator mode. 278 /// Maximum number of connection-oriented channels in initiator mode.
279 // * Range: 0 .. 64 279 /// Range: 0 .. 64
280 // */ 280 pub max_coc_initiator_nbr: u8,
281 // pub max_coc_initiator_nbr: u8, 281
282 // 282 ///
283 // /** 283 /// Minimum transmit power in dBm supported by the Controller.
284 // * Minimum transmit power in dBm supported by the Controller. 284 /// Range: -127 .. 20
285 // * Range: -127 .. 20 285 pub min_tx_power: i8,
286 // */ 286
287 // pub min_tx_power: i8, 287 ///
288 // 288 /// Maximum transmit power in dBm supported by the Controller.
289 // /** 289 /// Range: -127 .. 20
290 // * Maximum transmit power in dBm supported by the Controller. 290 pub max_tx_power: i8,
291 // * Range: -127 .. 20 291
292 // */ 292 ///
293 // pub max_tx_power: i8, 293 /// RX model configuration
294 // 294 /// - bit 0: 1: agc_rssi model improved vs RF blockers 0: Legacy agc_rssi model
295 // /** 295 /// - other bits: reserved ( shall be set to 0)
296 // * RX model configuration 296 pub rx_model_config: u8,
297 // * - bit 0: 1: agc_rssi model improved vs RF blockers 0: Legacy agc_rssi model 297
298 // * - other bits: reserved ( shall be set to 0) 298 /// Maximum number of advertising sets.
299 // */ 299 /// Range: 1 .. 8 with limitation:
300 // pub rx_model_config: u8, 300 /// This parameter is linked to max_adv_data_len such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based
301 // 301 /// on Max Extended advertising configuration supported.
302 // /* Maximum number of advertising sets. 302 /// This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set
303 // * Range: 1 .. 8 with limitation: 303 pub max_adv_set_nbr: u8,
304 // * This parameter is linked to max_adv_data_len such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based 304
305 // * on Max Extended advertising configuration supported. 305 /// Maximum advertising data length (in bytes)
306 // * This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set 306 /// Range: 31 .. 1650 with limitation:
307 // */ 307 /// This parameter is linked to max_adv_set_nbr such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based
308 // pub max_adv_set_nbr: u8, 308 /// on Max Extended advertising configuration supported.
309 // 309 /// This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set
310 // /* Maximum advertising data length (in bytes) 310 pub max_adv_data_len: u16,
311 // * Range: 31 .. 1650 with limitation: 311
312 // * This parameter is linked to max_adv_set_nbr such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based 312 /// RF TX Path Compensation Value (16-bit signed integer). Units: 0.1 dB.
313 // * on Max Extended advertising configuration supported. 313 /// Range: -1280 .. 1280
314 // * This parameter is considered by the CPU2 when Options has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set 314 pub tx_path_compens: i16,
315 // */ 315
316 // pub max_adv_data_len: u16, 316 //// RF RX Path Compensation Value (16-bit signed integer). Units: 0.1 dB.
317 // 317 /// Range: -1280 .. 1280
318 // /* RF TX Path Compensation Value (16-bit signed integer). Units: 0.1 dB. 318 pub rx_path_compens: i16,
319 // * Range: -1280 .. 1280 319
320 // */ 320 /// BLE core specification version (8-bit unsigned integer).
321 // pub tx_path_compens: i16, 321 /// values as: 11(5.2), 12(5.3)
322 // 322 pub ble_core_version: u8,
323 // /* RF RX Path Compensation Value (16-bit signed integer). Units: 0.1 dB. 323
324 // * Range: -1280 .. 1280 324 /// Options flags extension
325 // */ 325 /// - bit 0: 1: appearance Writable 0: appearance Read-Only
326 // pub rx_path_compens: i16, 326 /// - bit 1: 1: Enhanced ATT supported 0: Enhanced ATT not supported
327 // 327 /// - other bits: reserved ( shall be set to 0)
328 // /* BLE core specification version (8-bit unsigned integer). 328 pub options_extension: u8,
329 // * values as: 11(5.2), 12(5.3) 329
330 // */ 330 /// MaxAddEattBearers
331 // pub ble_core_version: u8, 331 /// Maximum number of bearers that can be created for Enhanced ATT
332 // 332 /// in addition to the number of links
333 // /** 333 /// - Range: 0 .. 4
334 // * Options flags extension 334 pub max_add_eatt_bearers: u8,
335 // * - bit 0: 1: appearance Writable 0: appearance Read-Only
336 // * - bit 1: 1: Enhanced ATT supported 0: Enhanced ATT not supported
337 // * - other bits: reserved ( shall be set to 0)
338 // */
339 // pub options_extension: u8,
340} 335}
341 336
342impl ShciBleInitCmdParam { 337impl ShciBleInitCmdParam {
@@ -351,7 +346,7 @@ impl Default for ShciBleInitCmdParam {
351 p_ble_buffer_address: 0, 346 p_ble_buffer_address: 0,
352 ble_buffer_size: 0, 347 ble_buffer_size: 0,
353 num_attr_record: 68, 348 num_attr_record: 68,
354 num_attr_serv: 8, 349 num_attr_serv: 4,
355 attr_value_arr_size: 1344, 350 attr_value_arr_size: 1344,
356 num_of_links: 2, 351 num_of_links: 2,
357 extended_packet_length_enable: 1, 352 extended_packet_length_enable: 1,
@@ -366,6 +361,17 @@ impl Default for ShciBleInitCmdParam {
366 viterbi_enable: 1, 361 viterbi_enable: 1,
367 options: 0, 362 options: 0,
368 hw_version: 0, 363 hw_version: 0,
364 max_coc_initiator_nbr: 32,
365 min_tx_power: -40,
366 max_tx_power: 6,
367 rx_model_config: 0,
368 max_adv_set_nbr: 2,
369 max_adv_data_len: 1650,
370 tx_path_compens: 0,
371 rx_path_compens: 0,
372 ble_core_version: 11,
373 options_extension: 0,
374 max_add_eatt_bearers: 4,
369 } 375 }
370 } 376 }
371} 377}
diff --git a/embassy-stm32-wpan/src/sub/ble.rs b/embassy-stm32-wpan/src/sub/ble.rs
index cd69a0479..d5ed2ca28 100644
--- a/embassy-stm32-wpan/src/sub/ble.rs
+++ b/embassy-stm32-wpan/src/sub/ble.rs
@@ -1,6 +1,6 @@
1use core::ptr; 1use core::ptr;
2 2
3use embassy_stm32::ipcc::Ipcc; 3use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel};
4use hci::Opcode; 4use hci::Opcode;
5 5
6use crate::cmd::CmdPacket; 6use crate::cmd::CmdPacket;
@@ -9,7 +9,7 @@ use crate::evt::{EvtBox, EvtPacket, EvtStub};
9use crate::sub::mm; 9use crate::sub::mm;
10use crate::tables::{BLE_CMD_BUFFER, BleTable, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; 10use crate::tables::{BLE_CMD_BUFFER, BleTable, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE};
11use crate::unsafe_linked_list::LinkedListNode; 11use crate::unsafe_linked_list::LinkedListNode;
12use crate::{channels, evt}; 12use crate::evt;
13 13
14/// A guard that, once constructed, may be used to send BLE commands to CPU2. 14/// A guard that, once constructed, may be used to send BLE commands to CPU2.
15/// 15///
@@ -36,15 +36,21 @@ use crate::{channels, evt};
36/// # mbox.ble_subsystem.reset().await; 36/// # mbox.ble_subsystem.reset().await;
37/// # let _reset_response = mbox.ble_subsystem.read().await; 37/// # let _reset_response = mbox.ble_subsystem.read().await;
38/// ``` 38/// ```
39pub struct Ble { 39pub struct Ble<'a> {
40 _private: (), 40 hw_ipcc_ble_cmd_channel: IpccTxChannel<'a>,
41 ipcc_ble_event_channel: IpccRxChannel<'a>,
42 ipcc_hci_acl_data_channel: IpccTxChannel<'a>,
41} 43}
42 44
43impl Ble { 45impl<'a> Ble<'a> {
44 /// Constructs a guard that allows for BLE commands to be sent to CPU2. 46 /// Constructs a guard that allows for BLE commands to be sent to CPU2.
45 /// 47 ///
46 /// This takes the place of `TL_BLE_Init`, completing that step as laid out in AN5289, Fig 66. 48 /// This takes the place of `TL_BLE_Init`, completing that step as laid out in AN5289, Fig 66.
47 pub(crate) fn new() -> Self { 49 pub(crate) fn new(
50 hw_ipcc_ble_cmd_channel: IpccTxChannel<'a>,
51 ipcc_ble_event_channel: IpccRxChannel<'a>,
52 ipcc_hci_acl_data_channel: IpccTxChannel<'a>,
53 ) -> Self {
48 unsafe { 54 unsafe {
49 LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); 55 LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
50 56
@@ -56,44 +62,51 @@ impl Ble {
56 }); 62 });
57 } 63 }
58 64
59 Self { _private: () } 65 Self {
66 hw_ipcc_ble_cmd_channel,
67 ipcc_ble_event_channel,
68 ipcc_hci_acl_data_channel,
69 }
60 } 70 }
61 71
62 /// `HW_IPCC_BLE_EvtNot` 72 /// `HW_IPCC_BLE_EvtNot`
63 pub async fn tl_read(&self) -> EvtBox<Self> { 73 pub async fn tl_read(&mut self) -> EvtBox<Self> {
64 Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { 74 self.ipcc_ble_event_channel
65 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { 75 .receive(|| unsafe {
66 Some(EvtBox::new(node_ptr.cast())) 76 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) {
67 } else { 77 Some(EvtBox::new(node_ptr.cast()))
68 None 78 } else {
69 } 79 None
70 }) 80 }
71 .await 81 })
82 .await
72 } 83 }
73 84
74 /// `TL_BLE_SendCmd` 85 /// `TL_BLE_SendCmd`
75 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { 86 pub async fn tl_write(&mut self, opcode: u16, payload: &[u8]) {
76 Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { 87 self.hw_ipcc_ble_cmd_channel
77 CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); 88 .send(|| unsafe {
78 }) 89 CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload);
79 .await; 90 })
91 .await;
80 } 92 }
81 93
82 /// `TL_BLE_SendAclData` 94 /// `TL_BLE_SendAclData`
83 pub async fn acl_write(&self, handle: u16, payload: &[u8]) { 95 pub async fn acl_write(&mut self, handle: u16, payload: &[u8]) {
84 Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { 96 self.ipcc_hci_acl_data_channel
85 CmdPacket::write_into( 97 .send(|| unsafe {
86 HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, 98 CmdPacket::write_into(
87 TlPacketType::AclData, 99 HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _,
88 handle, 100 TlPacketType::AclData,
89 payload, 101 handle,
90 ); 102 payload,
91 }) 103 );
92 .await; 104 })
105 .await;
93 } 106 }
94} 107}
95 108
96impl evt::MemoryManager for Ble { 109impl<'a> evt::MemoryManager for Ble<'a> {
97 /// SAFETY: passing a pointer to something other than a managed event packet is UB 110 /// SAFETY: passing a pointer to something other than a managed event packet is UB
98 unsafe fn drop_event_packet(evt: *mut EvtPacket) { 111 unsafe fn drop_event_packet(evt: *mut EvtPacket) {
99 let stub = unsafe { 112 let stub = unsafe {
@@ -110,13 +123,17 @@ impl evt::MemoryManager for Ble {
110 123
111pub extern crate stm32wb_hci as hci; 124pub extern crate stm32wb_hci as hci;
112 125
113impl hci::Controller for Ble { 126impl<'a> hci::Controller for Ble<'a> {
114 async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) { 127 async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) {
115 self.tl_write(opcode.0, payload).await; 128 self.tl_write(opcode.0, payload).await;
116 } 129 }
117 130
131 #[allow(invalid_reference_casting)]
118 async fn controller_read_into(&self, buf: &mut [u8]) { 132 async fn controller_read_into(&self, buf: &mut [u8]) {
119 let evt_box = self.tl_read().await; 133 // A complete hack since I cannot update the trait
134 let s = unsafe { &mut *(self as *const _ as *mut Ble) };
135
136 let evt_box = s.tl_read().await;
120 let evt_serial = evt_box.serial(); 137 let evt_serial = evt_box.serial();
121 138
122 buf[..evt_serial.len()].copy_from_slice(evt_serial); 139 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
index 93cafbc72..ce2903e61 100644
--- a/embassy-stm32-wpan/src/sub/mac.rs
+++ b/embassy-stm32-wpan/src/sub/mac.rs
@@ -4,67 +4,78 @@ use core::sync::atomic::{AtomicBool, Ordering};
4use core::task::Poll; 4use core::task::Poll;
5 5
6use embassy_futures::poll_once; 6use embassy_futures::poll_once;
7use embassy_stm32::ipcc::Ipcc; 7use embassy_stm32::ipcc::{Ipcc, IpccRxChannel, IpccTxChannel};
8use embassy_sync::waitqueue::AtomicWaker; 8use embassy_sync::waitqueue::AtomicWaker;
9 9
10use crate::cmd::CmdPacket; 10use crate::cmd::CmdPacket;
11use crate::consts::TlPacketType; 11use crate::consts::TlPacketType;
12use crate::evt;
12use crate::evt::{EvtBox, EvtPacket}; 13use crate::evt::{EvtBox, EvtPacket};
13use crate::mac::commands::MacCommand; 14use crate::mac::commands::MacCommand;
14use crate::mac::event::MacEvent; 15use crate::mac::event::MacEvent;
15use crate::mac::typedefs::MacError; 16use crate::mac::typedefs::MacError;
16use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; 17use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER};
17use crate::{channels, evt}; 18use crate::unsafe_linked_list::LinkedListNode;
18 19
19static MAC_WAKER: AtomicWaker = AtomicWaker::new(); 20static MAC_WAKER: AtomicWaker = AtomicWaker::new();
20static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); 21static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false);
21 22
22pub struct Mac { 23pub struct Mac<'a> {
23 _private: (), 24 ipcc_mac_802_15_4_cmd_rsp_channel: IpccTxChannel<'a>,
25 ipcc_mac_802_15_4_notification_ack_channel: IpccRxChannel<'a>,
24} 26}
25 27
26impl Mac { 28impl<'a> Mac<'a> {
27 pub(crate) fn new() -> Self { 29 pub(crate) fn new(
28 Self { _private: () } 30 ipcc_mac_802_15_4_cmd_rsp_channel: IpccTxChannel<'a>,
29 } 31 ipcc_mac_802_15_4_notification_ack_channel: IpccRxChannel<'a>,
30 32 ) -> Self {
31 pub const fn split(self) -> (MacRx, MacTx) { 33 use crate::tables::{
32 (MacRx { _private: () }, MacTx { _private: () }) 34 MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, Mac802_15_4Table, TL_MAC_802_15_4_TABLE,
33 } 35 TL_TRACES_TABLE, TRACES_EVT_QUEUE, TracesTable,
34 36 };
35 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 {
36 MacTx { _private: () }.tl_write_and_get_response(opcode, payload).await
37 }
38
39 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) {
40 MacTx { _private: () }.tl_write(opcode, payload).await
41 }
42
43 pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError>
44 where
45 T: MacCommand,
46 {
47 MacTx { _private: () }.send_command(cmd).await
48 }
49 37
50 pub async fn tl_read(&self) -> EvtBox<Mac> { 38 unsafe {
51 MacRx { _private: () }.tl_read().await 39 LinkedListNode::init_head(TRACES_EVT_QUEUE.as_mut_ptr() as *mut _);
40
41 TL_TRACES_TABLE.as_mut_ptr().write_volatile(TracesTable {
42 traces_queue: TRACES_EVT_QUEUE.as_ptr() as *const _,
43 });
44
45 TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table {
46 p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(),
47 p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(),
48 evt_queue: core::ptr::null_mut(),
49 });
50 };
51
52 Self {
53 ipcc_mac_802_15_4_cmd_rsp_channel,
54 ipcc_mac_802_15_4_notification_ack_channel,
55 }
52 } 56 }
53 57
54 pub async fn read(&self) -> Result<MacEvent<'_>, ()> { 58 pub const fn split(self) -> (MacRx<'a>, MacTx<'a>) {
55 MacRx { _private: () }.read().await 59 (
60 MacRx {
61 ipcc_mac_802_15_4_notification_ack_channel: self.ipcc_mac_802_15_4_notification_ack_channel,
62 },
63 MacTx {
64 ipcc_mac_802_15_4_cmd_rsp_channel: self.ipcc_mac_802_15_4_cmd_rsp_channel,
65 },
66 )
56 } 67 }
57} 68}
58 69
59pub struct MacTx { 70pub struct MacTx<'a> {
60 _private: (), 71 ipcc_mac_802_15_4_cmd_rsp_channel: IpccTxChannel<'a>,
61} 72}
62 73
63impl MacTx { 74impl<'a> MacTx<'a> {
64 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` 75 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot`
65 pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { 76 pub async fn tl_write_and_get_response(&mut self, opcode: u16, payload: &[u8]) -> u8 {
66 self.tl_write(opcode, payload).await; 77 self.tl_write(opcode, payload).await;
67 Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await; 78 self.ipcc_mac_802_15_4_cmd_rsp_channel.flush().await;
68 79
69 unsafe { 80 unsafe {
70 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; 81 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket;
@@ -75,19 +86,20 @@ impl MacTx {
75 } 86 }
76 87
77 /// `TL_MAC_802_15_4_SendCmd` 88 /// `TL_MAC_802_15_4_SendCmd`
78 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { 89 pub async fn tl_write(&mut self, opcode: u16, payload: &[u8]) {
79 Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { 90 self.ipcc_mac_802_15_4_cmd_rsp_channel
80 CmdPacket::write_into( 91 .send(|| unsafe {
81 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), 92 CmdPacket::write_into(
82 TlPacketType::MacCmd, 93 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(),
83 opcode, 94 TlPacketType::MacCmd,
84 payload, 95 opcode,
85 ); 96 payload,
86 }) 97 );
87 .await; 98 })
99 .await;
88 } 100 }
89 101
90 pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError> 102 pub async fn send_command<T>(&mut self, cmd: &T) -> Result<(), MacError>
91 where 103 where
92 T: MacCommand, 104 T: MacCommand,
93 { 105 {
@@ -101,19 +113,19 @@ impl MacTx {
101 } 113 }
102} 114}
103 115
104pub struct MacRx { 116pub struct MacRx<'a> {
105 _private: (), 117 ipcc_mac_802_15_4_notification_ack_channel: IpccRxChannel<'a>,
106} 118}
107 119
108impl MacRx { 120impl<'a> MacRx<'a> {
109 /// `HW_IPCC_MAC_802_15_4_EvtNot` 121 /// `HW_IPCC_MAC_802_15_4_EvtNot`
110 /// 122 ///
111 /// This function will stall if the previous `EvtBox` has not been dropped 123 /// This function will stall if the previous `EvtBox` has not been dropped
112 pub async fn tl_read(&self) -> EvtBox<Mac> { 124 pub async fn tl_read(&mut self) -> EvtBox<MacRx<'a>> {
113 // Wait for the last event box to be dropped 125 // Wait for the last event box to be dropped
114 poll_fn(|cx| { 126 poll_fn(|cx| {
115 MAC_WAKER.register(cx.waker()); 127 MAC_WAKER.register(cx.waker());
116 if MAC_EVT_OUT.load(Ordering::SeqCst) { 128 if MAC_EVT_OUT.load(Ordering::Acquire) {
117 Poll::Pending 129 Poll::Pending
118 } else { 130 } else {
119 Poll::Ready(()) 131 Poll::Ready(())
@@ -122,22 +134,23 @@ impl MacRx {
122 .await; 134 .await;
123 135
124 // Return a new event box 136 // Return a new event box
125 Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { 137 self.ipcc_mac_802_15_4_notification_ack_channel
126 // The closure is not async, therefore the closure must execute to completion (cannot be dropped) 138 .receive(|| unsafe {
127 // Therefore, the event box is guaranteed to be cleaned up if it's not leaked 139 // The closure is not async, therefore the closure must execute to completion (cannot be dropped)
128 MAC_EVT_OUT.store(true, Ordering::SeqCst); 140 // Therefore, the event box is guaranteed to be cleaned up if it's not leaked
129 141 MAC_EVT_OUT.store(true, Ordering::SeqCst);
130 Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) 142
131 }) 143 Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _))
132 .await 144 })
145 .await
133 } 146 }
134 147
135 pub async fn read(&self) -> Result<MacEvent<'_>, ()> { 148 pub async fn read<'b>(&mut self) -> Result<MacEvent<'b>, ()> {
136 MacEvent::new(self.tl_read().await) 149 MacEvent::new(self.tl_read().await)
137 } 150 }
138} 151}
139 152
140impl evt::MemoryManager for Mac { 153impl<'a> evt::MemoryManager for MacRx<'a> {
141 /// SAFETY: passing a pointer to something other than a managed event packet is UB 154 /// SAFETY: passing a pointer to something other than a managed event packet is UB
142 unsafe fn drop_event_packet(_: *mut EvtPacket) { 155 unsafe fn drop_event_packet(_: *mut EvtPacket) {
143 trace!("mac drop event"); 156 trace!("mac drop event");
@@ -151,13 +164,10 @@ impl evt::MemoryManager for Mac {
151 ); 164 );
152 165
153 // Clear the rx flag 166 // Clear the rx flag
154 let _ = poll_once(Ipcc::receive::<()>( 167 let _ = poll_once(Ipcc::receive::<()>(3, || None));
155 channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL,
156 || None,
157 ));
158 168
159 // Allow a new read call 169 // Allow a new read call
160 MAC_EVT_OUT.store(false, Ordering::SeqCst); 170 MAC_EVT_OUT.store(false, Ordering::Release);
161 MAC_WAKER.wake(); 171 MAC_WAKER.wake();
162 } 172 }
163} 173}
diff --git a/embassy-stm32-wpan/src/sub/mm.rs b/embassy-stm32-wpan/src/sub/mm.rs
index a90c6ee55..aac252929 100644
--- a/embassy-stm32-wpan/src/sub/mm.rs
+++ b/embassy-stm32-wpan/src/sub/mm.rs
@@ -5,26 +5,26 @@ use core::task::Poll;
5 5
6use aligned::{A4, Aligned}; 6use aligned::{A4, Aligned};
7use cortex_m::interrupt; 7use cortex_m::interrupt;
8use embassy_stm32::ipcc::Ipcc; 8use embassy_stm32::ipcc::IpccTxChannel;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use crate::consts::POOL_SIZE; 11use crate::consts::POOL_SIZE;
12use crate::evt;
12use crate::evt::EvtPacket; 13use crate::evt::EvtPacket;
13#[cfg(feature = "ble")] 14#[cfg(feature = "ble")]
14use crate::tables::BLE_SPARE_EVT_BUF; 15use crate::tables::BLE_SPARE_EVT_BUF;
15use crate::tables::{EVT_POOL, FREE_BUF_QUEUE, MemManagerTable, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE}; 16use crate::tables::{EVT_POOL, FREE_BUF_QUEUE, MemManagerTable, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE};
16use crate::unsafe_linked_list::LinkedListNode; 17use 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: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit()); 20static mut LOCAL_FREE_BUF_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit());
21 21
22pub struct MemoryManager { 22pub struct MemoryManager<'a> {
23 _private: (), 23 ipcc_mm_release_buffer_channel: IpccTxChannel<'a>,
24} 24}
25 25
26impl MemoryManager { 26impl<'a> MemoryManager<'a> {
27 pub(crate) fn new() -> Self { 27 pub(crate) fn new(ipcc_mm_release_buffer_channel: IpccTxChannel<'a>) -> Self {
28 unsafe { 28 unsafe {
29 LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); 29 LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr());
30 LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); 30 LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr());
@@ -43,10 +43,12 @@ impl MemoryManager {
43 }); 43 });
44 } 44 }
45 45
46 Self { _private: () } 46 Self {
47 ipcc_mm_release_buffer_channel,
48 }
47 } 49 }
48 50
49 pub async fn run_queue(&self) -> ! { 51 pub async fn run_queue(&mut self) -> ! {
50 loop { 52 loop {
51 poll_fn(|cx| unsafe { 53 poll_fn(|cx| unsafe {
52 MM_WAKER.register(cx.waker()); 54 MM_WAKER.register(cx.waker());
@@ -58,20 +60,21 @@ impl MemoryManager {
58 }) 60 })
59 .await; 61 .await;
60 62
61 Ipcc::send(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, || { 63 self.ipcc_mm_release_buffer_channel
62 interrupt::free(|_| unsafe { 64 .send(|| {
63 // CS required while moving nodes 65 interrupt::free(|_| unsafe {
64 while let Some(node_ptr) = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { 66 // CS required while moving nodes
65 LinkedListNode::insert_head(FREE_BUF_QUEUE.as_mut_ptr(), node_ptr); 67 while let Some(node_ptr) = LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) {
66 } 68 LinkedListNode::insert_head(FREE_BUF_QUEUE.as_mut_ptr(), node_ptr);
69 }
70 })
67 }) 71 })
68 }) 72 .await;
69 .await;
70 } 73 }
71 } 74 }
72} 75}
73 76
74impl evt::MemoryManager for MemoryManager { 77impl<'a> evt::MemoryManager for MemoryManager<'a> {
75 /// SAFETY: passing a pointer to something other than a managed event packet is UB 78 /// SAFETY: passing a pointer to something other than a managed event packet is UB
76 unsafe fn drop_event_packet(evt: *mut EvtPacket) { 79 unsafe fn drop_event_packet(evt: *mut EvtPacket) {
77 interrupt::free(|_| unsafe { 80 interrupt::free(|_| unsafe {
diff --git a/embassy-stm32-wpan/src/sub/sys.rs b/embassy-stm32-wpan/src/sub/sys.rs
index 8a3382f86..dffe9942c 100644
--- a/embassy-stm32-wpan/src/sub/sys.rs
+++ b/embassy-stm32-wpan/src/sub/sys.rs
@@ -1,5 +1,7 @@
1use core::ptr; 1use core::ptr;
2 2
3use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel};
4
3use crate::cmd::CmdPacket; 5use crate::cmd::CmdPacket;
4use crate::consts::TlPacketType; 6use crate::consts::TlPacketType;
5use crate::evt::{CcEvt, EvtBox, EvtPacket}; 7use crate::evt::{CcEvt, EvtBox, EvtPacket};
@@ -8,16 +10,20 @@ use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode};
8use crate::sub::mm; 10use crate::sub::mm;
9use crate::tables::{SysTable, WirelessFwInfoTable}; 11use crate::tables::{SysTable, WirelessFwInfoTable};
10use crate::unsafe_linked_list::LinkedListNode; 12use crate::unsafe_linked_list::LinkedListNode;
11use crate::{Ipcc, SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE, channels}; 13use crate::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE};
12 14
13/// A guard that, once constructed, allows for sys commands to be sent to CPU2. 15/// A guard that, once constructed, allows for sys commands to be sent to CPU2.
14pub struct Sys { 16pub struct Sys<'a> {
15 _private: (), 17 ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>,
18 ipcc_system_event_channel: IpccRxChannel<'a>,
16} 19}
17 20
18impl Sys { 21impl<'a> Sys<'a> {
19 /// TL_Sys_Init 22 /// TL_Sys_Init
20 pub(crate) fn new() -> Self { 23 pub(crate) fn new(
24 ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>,
25 ipcc_system_event_channel: IpccRxChannel<'a>,
26 ) -> Self {
21 unsafe { 27 unsafe {
22 LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); 28 LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
23 29
@@ -27,7 +33,10 @@ impl Sys {
27 }); 33 });
28 } 34 }
29 35
30 Self { _private: () } 36 Self {
37 ipcc_system_cmd_rsp_channel,
38 ipcc_system_event_channel,
39 }
31 } 40 }
32 41
33 /// Returns CPU2 wireless firmware information (if present). 42 /// Returns CPU2 wireless firmware information (if present).
@@ -38,17 +47,22 @@ impl Sys {
38 if info.version != 0 { Some(info) } else { None } 47 if info.version != 0 { Some(info) } else { None }
39 } 48 }
40 49
41 pub async fn write(&self, opcode: ShciOpcode, payload: &[u8]) { 50 pub async fn write(&mut self, opcode: ShciOpcode, payload: &[u8]) {
42 Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || unsafe { 51 self.ipcc_system_cmd_rsp_channel
43 CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); 52 .send(|| unsafe {
44 }) 53 CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload);
45 .await; 54 })
55 .await;
46 } 56 }
47 57
48 /// `HW_IPCC_SYS_CmdEvtNot` 58 /// `HW_IPCC_SYS_CmdEvtNot`
49 pub async fn write_and_get_response(&self, opcode: ShciOpcode, payload: &[u8]) -> Result<SchiCommandStatus, ()> { 59 pub async fn write_and_get_response(
60 &mut self,
61 opcode: ShciOpcode,
62 payload: &[u8],
63 ) -> Result<SchiCommandStatus, ()> {
50 self.write(opcode, payload).await; 64 self.write(opcode, payload).await;
51 Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; 65 self.ipcc_system_cmd_rsp_channel.flush().await;
52 66
53 unsafe { 67 unsafe {
54 let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; 68 let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket;
@@ -60,26 +74,7 @@ impl Sys {
60 } 74 }
61 75
62 #[cfg(feature = "mac")] 76 #[cfg(feature = "mac")]
63 pub async fn shci_c2_mac_802_15_4_init(&self) -> Result<SchiCommandStatus, ()> { 77 pub async fn shci_c2_mac_802_15_4_init(&mut self) -> Result<SchiCommandStatus, ()> {
64 use crate::tables::{
65 MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, Mac802_15_4Table, TL_MAC_802_15_4_TABLE,
66 TL_TRACES_TABLE, TRACES_EVT_QUEUE, TracesTable,
67 };
68
69 unsafe {
70 LinkedListNode::init_head(TRACES_EVT_QUEUE.as_mut_ptr() as *mut _);
71
72 TL_TRACES_TABLE.as_mut_ptr().write_volatile(TracesTable {
73 traces_queue: TRACES_EVT_QUEUE.as_ptr() as *const _,
74 });
75
76 TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table {
77 p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(),
78 p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(),
79 evt_queue: core::ptr::null_mut(),
80 });
81 };
82
83 self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await 78 self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await
84 } 79 }
85 80
@@ -90,7 +85,7 @@ impl Sys {
90 /// `HW_IPCC_SYS_EvtNot`, aka `IoBusCallBackUserEvt` (as detailed in Figure 65), aka 85 /// `HW_IPCC_SYS_EvtNot`, aka `IoBusCallBackUserEvt` (as detailed in Figure 65), aka
91 /// [crate::sub::ble::hci::host::uart::UartHci::read]. 86 /// [crate::sub::ble::hci::host::uart::UartHci::read].
92 #[cfg(feature = "ble")] 87 #[cfg(feature = "ble")]
93 pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> { 88 pub async fn shci_c2_ble_init(&mut self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> {
94 self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await 89 self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await
95 } 90 }
96 91
@@ -99,14 +94,15 @@ impl Sys {
99 /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, 94 /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`,
100 /// as the embassy implementation avoids the need to call C public bindings, and instead 95 /// as the embassy implementation avoids the need to call C public bindings, and instead
101 /// handles the event channels directly. 96 /// handles the event channels directly.
102 pub async fn read(&self) -> EvtBox<mm::MemoryManager> { 97 pub async fn read<'b>(&mut self) -> EvtBox<mm::MemoryManager<'b>> {
103 Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { 98 self.ipcc_system_event_channel
104 if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { 99 .receive(|| unsafe {
105 Some(EvtBox::new(node_ptr.cast())) 100 if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) {
106 } else { 101 Some(EvtBox::new(node_ptr.cast()))
107 None 102 } else {
108 } 103 None
109 }) 104 }
110 .await 105 })
106 .await
111 } 107 }
112} 108}
diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs
index 1dafed159..20d2c190f 100644
--- a/embassy-stm32-wpan/src/tables.rs
+++ b/embassy-stm32-wpan/src/tables.rs
@@ -191,93 +191,93 @@ pub struct RefTable {
191 191
192// --------------------- ref table --------------------- 192// --------------------- ref table ---------------------
193#[unsafe(link_section = "TL_REF_TABLE")] 193#[unsafe(link_section = "TL_REF_TABLE")]
194pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit(); 194pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::zeroed();
195 195
196#[unsafe(link_section = "MB_MEM1")] 196#[unsafe(link_section = "MB_MEM1")]
197pub static mut TL_DEVICE_INFO_TABLE: Aligned<A4, MaybeUninit<DeviceInfoTable>> = Aligned(MaybeUninit::uninit()); 197pub static mut TL_DEVICE_INFO_TABLE: Aligned<A4, MaybeUninit<DeviceInfoTable>> = Aligned(MaybeUninit::zeroed());
198 198
199#[unsafe(link_section = "MB_MEM1")] 199#[unsafe(link_section = "MB_MEM1")]
200pub static mut TL_BLE_TABLE: Aligned<A4, MaybeUninit<BleTable>> = Aligned(MaybeUninit::uninit()); 200pub static mut TL_BLE_TABLE: Aligned<A4, MaybeUninit<BleTable>> = Aligned(MaybeUninit::zeroed());
201 201
202#[unsafe(link_section = "MB_MEM1")] 202#[unsafe(link_section = "MB_MEM1")]
203pub static mut TL_THREAD_TABLE: Aligned<A4, MaybeUninit<ThreadTable>> = Aligned(MaybeUninit::uninit()); 203pub static mut TL_THREAD_TABLE: Aligned<A4, MaybeUninit<ThreadTable>> = Aligned(MaybeUninit::zeroed());
204 204
205#[unsafe(link_section = "MB_MEM1")] 205#[unsafe(link_section = "MB_MEM1")]
206pub static mut TL_LLD_TESTS_TABLE: Aligned<A4, MaybeUninit<LldTestsTable>> = Aligned(MaybeUninit::uninit()); 206pub static mut TL_LLD_TESTS_TABLE: Aligned<A4, MaybeUninit<LldTestsTable>> = Aligned(MaybeUninit::zeroed());
207 207
208#[unsafe(link_section = "MB_MEM1")] 208#[unsafe(link_section = "MB_MEM1")]
209pub static mut TL_BLE_LLD_TABLE: Aligned<A4, MaybeUninit<BleLldTable>> = Aligned(MaybeUninit::uninit()); 209pub static mut TL_BLE_LLD_TABLE: Aligned<A4, MaybeUninit<BleLldTable>> = Aligned(MaybeUninit::zeroed());
210 210
211#[unsafe(link_section = "MB_MEM1")] 211#[unsafe(link_section = "MB_MEM1")]
212pub static mut TL_SYS_TABLE: Aligned<A4, MaybeUninit<SysTable>> = Aligned(MaybeUninit::uninit()); 212pub static mut TL_SYS_TABLE: Aligned<A4, MaybeUninit<SysTable>> = Aligned(MaybeUninit::zeroed());
213 213
214#[unsafe(link_section = "MB_MEM1")] 214#[unsafe(link_section = "MB_MEM1")]
215pub static mut TL_MEM_MANAGER_TABLE: Aligned<A4, MaybeUninit<MemManagerTable>> = Aligned(MaybeUninit::uninit()); 215pub static mut TL_MEM_MANAGER_TABLE: Aligned<A4, MaybeUninit<MemManagerTable>> = Aligned(MaybeUninit::zeroed());
216 216
217#[unsafe(link_section = "MB_MEM1")] 217#[unsafe(link_section = "MB_MEM1")]
218pub static mut TL_TRACES_TABLE: Aligned<A4, MaybeUninit<TracesTable>> = Aligned(MaybeUninit::uninit()); 218pub static mut TL_TRACES_TABLE: Aligned<A4, MaybeUninit<TracesTable>> = Aligned(MaybeUninit::zeroed());
219 219
220#[unsafe(link_section = "MB_MEM1")] 220#[unsafe(link_section = "MB_MEM1")]
221pub static mut TL_MAC_802_15_4_TABLE: Aligned<A4, MaybeUninit<Mac802_15_4Table>> = Aligned(MaybeUninit::uninit()); 221pub static mut TL_MAC_802_15_4_TABLE: Aligned<A4, MaybeUninit<Mac802_15_4Table>> = Aligned(MaybeUninit::zeroed());
222 222
223#[unsafe(link_section = "MB_MEM1")] 223#[unsafe(link_section = "MB_MEM1")]
224pub static mut TL_ZIGBEE_TABLE: Aligned<A4, MaybeUninit<ZigbeeTable>> = Aligned(MaybeUninit::uninit()); 224pub static mut TL_ZIGBEE_TABLE: Aligned<A4, MaybeUninit<ZigbeeTable>> = Aligned(MaybeUninit::zeroed());
225 225
226// --------------------- tables --------------------- 226// --------------------- tables ---------------------
227#[unsafe(link_section = "MB_MEM1")] 227#[unsafe(link_section = "MB_MEM1")]
228pub static mut FREE_BUF_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit()); 228pub static mut FREE_BUF_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::zeroed());
229 229
230#[allow(dead_code)] 230#[allow(dead_code)]
231#[unsafe(link_section = "MB_MEM1")] 231#[unsafe(link_section = "MB_MEM1")]
232pub static mut TRACES_EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit()); 232pub static mut TRACES_EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::zeroed());
233 233
234#[unsafe(link_section = "MB_MEM2")] 234#[unsafe(link_section = "MB_MEM2")]
235pub static mut CS_BUFFER: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]>> = 235pub static mut CS_BUFFER: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]>> =
236 Aligned(MaybeUninit::uninit()); 236 Aligned(MaybeUninit::zeroed());
237 237
238#[unsafe(link_section = "MB_MEM2")] 238#[unsafe(link_section = "MB_MEM2")]
239pub static mut EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit()); 239pub static mut EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::zeroed());
240 240
241#[unsafe(link_section = "MB_MEM2")] 241#[unsafe(link_section = "MB_MEM2")]
242pub static mut SYSTEM_EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::uninit()); 242pub static mut SYSTEM_EVT_QUEUE: Aligned<A4, MaybeUninit<LinkedListNode>> = Aligned(MaybeUninit::zeroed());
243 243
244// --------------------- app tables --------------------- 244// --------------------- app tables ---------------------
245#[cfg(feature = "mac")] 245#[cfg(feature = "mac")]
246#[unsafe(link_section = "MB_MEM2")] 246#[unsafe(link_section = "MB_MEM2")]
247pub static mut MAC_802_15_4_CMD_BUFFER: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::uninit()); 247pub static mut MAC_802_15_4_CMD_BUFFER: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::zeroed());
248 248
249#[cfg(feature = "mac")] 249#[cfg(feature = "mac")]
250#[unsafe(link_section = "MB_MEM2")] 250#[unsafe(link_section = "MB_MEM2")]
251pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit< 251pub static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit<
252 Aligned<A4, [u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>, 252 Aligned<A4, [u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>,
253> = MaybeUninit::uninit(); 253> = MaybeUninit::zeroed();
254 254
255#[unsafe(link_section = "MB_MEM2")] 255#[unsafe(link_section = "MB_MEM2")]
256pub static mut EVT_POOL: Aligned<A4, MaybeUninit<[u8; POOL_SIZE]>> = Aligned(MaybeUninit::uninit()); 256pub static mut EVT_POOL: Aligned<A4, MaybeUninit<[u8; POOL_SIZE]>> = Aligned(MaybeUninit::zeroed());
257 257
258#[unsafe(link_section = "MB_MEM2")] 258#[unsafe(link_section = "MB_MEM2")]
259pub static mut SYS_CMD_BUF: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::uninit()); 259pub static mut SYS_CMD_BUF: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::zeroed());
260 260
261#[unsafe(link_section = "MB_MEM2")] 261#[unsafe(link_section = "MB_MEM2")]
262pub static mut SYS_SPARE_EVT_BUF: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>> = 262pub static mut SYS_SPARE_EVT_BUF: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>> =
263 Aligned(MaybeUninit::uninit()); 263 Aligned(MaybeUninit::zeroed());
264 264
265#[cfg(feature = "mac")] 265#[cfg(feature = "mac")]
266#[unsafe(link_section = "MB_MEM2")] 266#[unsafe(link_section = "MB_MEM2")]
267pub static mut MAC_802_15_4_CNFINDNOT: Aligned<A4, MaybeUninit<[u8; C_SIZE_CMD_STRING]>> = 267pub static mut MAC_802_15_4_CNFINDNOT: Aligned<A4, MaybeUninit<[u8; C_SIZE_CMD_STRING]>> =
268 Aligned(MaybeUninit::uninit()); 268 Aligned(MaybeUninit::zeroed());
269 269
270#[cfg(feature = "ble")] 270#[cfg(feature = "ble")]
271#[unsafe(link_section = "MB_MEM1")] 271#[unsafe(link_section = "MB_MEM1")]
272pub static mut BLE_CMD_BUFFER: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::uninit()); 272pub static mut BLE_CMD_BUFFER: Aligned<A4, MaybeUninit<CmdPacket>> = Aligned(MaybeUninit::zeroed());
273 273
274#[cfg(feature = "ble")] 274#[cfg(feature = "ble")]
275#[unsafe(link_section = "MB_MEM2")] 275#[unsafe(link_section = "MB_MEM2")]
276pub static mut BLE_SPARE_EVT_BUF: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>> = 276pub static mut BLE_SPARE_EVT_BUF: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]>> =
277 Aligned(MaybeUninit::uninit()); 277 Aligned(MaybeUninit::zeroed());
278 278
279#[cfg(feature = "ble")] 279#[cfg(feature = "ble")]
280#[unsafe(link_section = "MB_MEM2")] 280#[unsafe(link_section = "MB_MEM2")]
281// fuck these "magic" numbers from ST ---v---v 281// fuck these "magic" numbers from ST ---v---v
282pub static mut HCI_ACL_DATA_BUFFER: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]>> = 282pub static mut HCI_ACL_DATA_BUFFER: Aligned<A4, MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]>> =
283 Aligned(MaybeUninit::uninit()); 283 Aligned(MaybeUninit::zeroed());
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs
index e1d8b1c2a..10c4a820b 100644
--- a/embassy-stm32/src/ipcc.rs
+++ b/embassy-stm32/src/ipcc.rs
@@ -1,9 +1,11 @@
1//! Inter-Process Communication Controller (IPCC) 1//! Inter-Process Communication Controller (IPCC)
2 2
3use core::future::poll_fn; 3use core::future::poll_fn;
4use core::marker::PhantomData;
4use core::sync::atomic::{Ordering, compiler_fence}; 5use core::sync::atomic::{Ordering, compiler_fence};
5use core::task::Poll; 6use core::task::Poll;
6 7
8use embassy_hal_internal::Peri;
7use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
8 10
9use crate::interrupt::typelevel::Interrupt; 11use crate::interrupt::typelevel::Interrupt;
@@ -17,25 +19,16 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_RX> for Receive
17 unsafe fn on_interrupt() { 19 unsafe fn on_interrupt() {
18 let regs = IPCC::regs(); 20 let regs = IPCC::regs();
19 21
20 let channels = [
21 IpccChannel::Channel1,
22 IpccChannel::Channel2,
23 IpccChannel::Channel3,
24 IpccChannel::Channel4,
25 IpccChannel::Channel5,
26 IpccChannel::Channel6,
27 ];
28
29 // Status register gives channel occupied status. For rx, use cpu1. 22 // Status register gives channel occupied status. For rx, use cpu1.
30 let sr = regs.cpu(1).sr().read(); 23 let sr = regs.cpu(1).sr().read();
31 regs.cpu(0).mr().modify(|w| { 24 regs.cpu(0).mr().modify(|w| {
32 for channel in channels { 25 for index in 0..5 {
33 if sr.chf(channel as usize) { 26 if sr.chf(index as usize) {
34 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt 27 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt
35 w.set_chom(channel as usize, true); 28 w.set_chom(index as usize, true);
36 29
37 // There shouldn't be a race because the channel is masked only if the interrupt has fired 30 // There shouldn't be a race because the channel is masked only if the interrupt has fired
38 IPCC::state().rx_waker_for(channel).wake(); 31 IPCC::state().rx_waker_for(index).wake();
39 } 32 }
40 } 33 }
41 }) 34 })
@@ -49,25 +42,16 @@ impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_TX> for Transmi
49 unsafe fn on_interrupt() { 42 unsafe fn on_interrupt() {
50 let regs = IPCC::regs(); 43 let regs = IPCC::regs();
51 44
52 let channels = [
53 IpccChannel::Channel1,
54 IpccChannel::Channel2,
55 IpccChannel::Channel3,
56 IpccChannel::Channel4,
57 IpccChannel::Channel5,
58 IpccChannel::Channel6,
59 ];
60
61 // Status register gives channel occupied status. For tx, use cpu0. 45 // Status register gives channel occupied status. For tx, use cpu0.
62 let sr = regs.cpu(0).sr().read(); 46 let sr = regs.cpu(0).sr().read();
63 regs.cpu(0).mr().modify(|w| { 47 regs.cpu(0).mr().modify(|w| {
64 for channel in channels { 48 for index in 0..5 {
65 if !sr.chf(channel as usize) { 49 if !sr.chf(index as usize) {
66 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt 50 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt
67 w.set_chfm(channel as usize, true); 51 w.set_chfm(index as usize, true);
68 52
69 // There shouldn't be a race because the channel is masked only if the interrupt has fired 53 // There shouldn't be a race because the channel is masked only if the interrupt has fired
70 IPCC::state().tx_waker_for(channel).wake(); 54 IPCC::state().tx_waker_for(index).wake();
71 } 55 }
72 } 56 }
73 }); 57 });
@@ -82,76 +66,55 @@ pub struct Config {
82 // reserved for future use 66 // reserved for future use
83} 67}
84 68
85/// Channel. 69/// IPCC TX Channel
86#[allow(missing_docs)] 70pub struct IpccTxChannel<'a> {
87#[derive(Debug, Clone, Copy)] 71 index: u8,
88#[repr(C)] 72 _lifetime: PhantomData<&'a mut usize>,
89pub enum IpccChannel {
90 Channel1 = 0,
91 Channel2 = 1,
92 Channel3 = 2,
93 Channel4 = 3,
94 Channel5 = 4,
95 Channel6 = 5,
96} 73}
97 74
98/// IPCC driver. 75impl<'a> IpccTxChannel<'a> {
99pub struct Ipcc; 76 pub(crate) const fn new(index: u8) -> Self {
100 77 core::assert!(index < 6);
101impl Ipcc {
102 /// Enable IPCC.
103 pub fn enable(_config: Config) {
104 rcc::enable_and_reset::<IPCC>();
105 IPCC::set_cpu2(true);
106
107 let regs = IPCC::regs();
108
109 regs.cpu(0).cr().modify(|w| {
110 w.set_rxoie(true);
111 w.set_txfie(true);
112 });
113
114 // enable interrupts
115 crate::interrupt::typelevel::IPCC_C1_RX::unpend();
116 crate::interrupt::typelevel::IPCC_C1_TX::unpend();
117 78
118 unsafe { crate::interrupt::typelevel::IPCC_C1_RX::enable() }; 79 Self {
119 unsafe { crate::interrupt::typelevel::IPCC_C1_TX::enable() }; 80 index: index,
81 _lifetime: PhantomData,
82 }
120 } 83 }
121 84
122 /// Send data to an IPCC channel. The closure is called to write the data when appropriate. 85 /// Send data to an IPCC channel. The closure is called to write the data when appropriate.
123 pub async fn send(channel: IpccChannel, f: impl FnOnce()) { 86 pub async fn send(&mut self, f: impl FnOnce()) {
124 let regs = IPCC::regs(); 87 let regs = IPCC::regs();
125 88
126 Self::flush(channel).await; 89 self.flush().await;
127 90
128 f(); 91 f();
129 92
130 compiler_fence(Ordering::SeqCst); 93 compiler_fence(Ordering::SeqCst);
131 94
132 trace!("ipcc: ch {}: send data", channel as u8); 95 trace!("ipcc: ch {}: send data", self.index as u8);
133 regs.cpu(0).scr().write(|w| w.set_chs(channel as usize, true)); 96 regs.cpu(0).scr().write(|w| w.set_chs(self.index as usize, true));
134 } 97 }
135 98
136 /// Wait for the tx channel to become clear 99 /// Wait for the tx channel to become clear
137 pub async fn flush(channel: IpccChannel) { 100 pub async fn flush(&mut self) {
138 let regs = IPCC::regs(); 101 let regs = IPCC::regs();
139 102
140 // This is a race, but is nice for debugging 103 // This is a race, but is nice for debugging
141 if regs.cpu(0).sr().read().chf(channel as usize) { 104 if regs.cpu(0).sr().read().chf(self.index as usize) {
142 trace!("ipcc: ch {}: wait for tx free", channel as u8); 105 trace!("ipcc: ch {}: wait for tx free", self.index as u8);
143 } 106 }
144 107
145 poll_fn(|cx| { 108 poll_fn(|cx| {
146 IPCC::state().tx_waker_for(channel).register(cx.waker()); 109 IPCC::state().tx_waker_for(self.index).register(cx.waker());
147 // If bit is set to 1 then interrupt is disabled; we want to enable the interrupt 110 // If bit is set to 1 then interrupt is disabled; we want to enable the interrupt
148 regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, false)); 111 regs.cpu(0).mr().modify(|w| w.set_chfm(self.index as usize, false));
149 112
150 compiler_fence(Ordering::SeqCst); 113 compiler_fence(Ordering::SeqCst);
151 114
152 if !regs.cpu(0).sr().read().chf(channel as usize) { 115 if !regs.cpu(0).sr().read().chf(self.index as usize) {
153 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt 116 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt
154 regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, true)); 117 regs.cpu(0).mr().modify(|w| w.set_chfm(self.index as usize, true));
155 118
156 Poll::Ready(()) 119 Poll::Ready(())
157 } else { 120 } else {
@@ -160,27 +123,44 @@ impl Ipcc {
160 }) 123 })
161 .await; 124 .await;
162 } 125 }
126}
127
128/// IPCC RX Channel
129pub struct IpccRxChannel<'a> {
130 index: u8,
131 _lifetime: PhantomData<&'a mut usize>,
132}
133
134impl<'a> IpccRxChannel<'a> {
135 pub(crate) const fn new(index: u8) -> Self {
136 core::assert!(index < 6);
137
138 Self {
139 index: index,
140 _lifetime: PhantomData,
141 }
142 }
163 143
164 /// Receive data from an IPCC channel. The closure is called to read the data when appropriate. 144 /// Receive data from an IPCC channel. The closure is called to read the data when appropriate.
165 pub async fn receive<R>(channel: IpccChannel, mut f: impl FnMut() -> Option<R>) -> R { 145 pub async fn receive<R>(&mut self, mut f: impl FnMut() -> Option<R>) -> R {
166 let regs = IPCC::regs(); 146 let regs = IPCC::regs();
167 147
168 loop { 148 loop {
169 // This is a race, but is nice for debugging 149 // This is a race, but is nice for debugging
170 if !regs.cpu(1).sr().read().chf(channel as usize) { 150 if !regs.cpu(1).sr().read().chf(self.index as usize) {
171 trace!("ipcc: ch {}: wait for rx occupied", channel as u8); 151 trace!("ipcc: ch {}: wait for rx occupied", self.index as u8);
172 } 152 }
173 153
174 poll_fn(|cx| { 154 poll_fn(|cx| {
175 IPCC::state().rx_waker_for(channel).register(cx.waker()); 155 IPCC::state().rx_waker_for(self.index).register(cx.waker());
176 // If bit is set to 1 then interrupt is disabled; we want to enable the interrupt 156 // If bit is set to 1 then interrupt is disabled; we want to enable the interrupt
177 regs.cpu(0).mr().modify(|w| w.set_chom(channel as usize, false)); 157 regs.cpu(0).mr().modify(|w| w.set_chom(self.index as usize, false));
178 158
179 compiler_fence(Ordering::SeqCst); 159 compiler_fence(Ordering::SeqCst);
180 160
181 if regs.cpu(1).sr().read().chf(channel as usize) { 161 if regs.cpu(1).sr().read().chf(self.index as usize) {
182 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt 162 // If bit is set to 1 then interrupt is disabled; we want to disable the interrupt
183 regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, true)); 163 regs.cpu(0).mr().modify(|w| w.set_chfm(self.index as usize, true));
184 164
185 Poll::Ready(()) 165 Poll::Ready(())
186 } else { 166 } else {
@@ -189,21 +169,111 @@ impl Ipcc {
189 }) 169 })
190 .await; 170 .await;
191 171
192 trace!("ipcc: ch {}: read data", channel as u8); 172 trace!("ipcc: ch {}: read data", self.index as u8);
193 173
194 match f() { 174 match f() {
195 Some(ret) => return ret, 175 Some(ret) => return ret,
196 None => {} 176 None => {}
197 } 177 }
198 178
199 trace!("ipcc: ch {}: clear rx", channel as u8); 179 trace!("ipcc: ch {}: clear rx", self.index as u8);
200 compiler_fence(Ordering::SeqCst); 180 compiler_fence(Ordering::SeqCst);
201 // If the channel is clear and the read function returns none, fetch more data 181 // If the channel is clear and the read function returns none, fetch more data
202 regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true)); 182 regs.cpu(0).scr().write(|w| w.set_chc(self.index as usize, true));
203 } 183 }
204 } 184 }
205} 185}
206 186
187/// IPCC Channel
188pub struct IpccChannel<'a> {
189 index: u8,
190 _lifetime: PhantomData<&'a mut usize>,
191}
192
193impl<'a> IpccChannel<'a> {
194 pub(crate) const fn new(number: u8) -> Self {
195 core::assert!(number > 0 && number <= 6);
196
197 Self {
198 index: number - 1,
199 _lifetime: PhantomData,
200 }
201 }
202
203 /// Split into a tx and rx channel
204 pub const fn split(self) -> (IpccTxChannel<'a>, IpccRxChannel<'a>) {
205 (IpccTxChannel::new(self.index), IpccRxChannel::new(self.index))
206 }
207}
208
209/// IPCC driver.
210pub struct Ipcc {
211 _private: (),
212}
213
214impl Ipcc {
215 /// Creates a new HardwareSemaphore instance.
216 pub fn new<'d>(
217 _peripheral: Peri<'d, crate::peripherals::IPCC>,
218 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
219 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>
220 + 'd,
221 _config: Config,
222 ) -> Self {
223 rcc::enable_and_reset::<IPCC>();
224 IPCC::set_cpu2(true);
225
226 let regs = IPCC::regs();
227
228 regs.cpu(0).cr().modify(|w| {
229 w.set_rxoie(true);
230 w.set_txfie(true);
231 });
232
233 // enable interrupts
234 crate::interrupt::typelevel::IPCC_C1_RX::unpend();
235 crate::interrupt::typelevel::IPCC_C1_TX::unpend();
236
237 unsafe { crate::interrupt::typelevel::IPCC_C1_RX::enable() };
238 unsafe { crate::interrupt::typelevel::IPCC_C1_TX::enable() };
239
240 Self { _private: () }
241 }
242
243 /// Split into a tx and rx channel
244 pub const fn split<'a>(self) -> [(IpccTxChannel<'a>, IpccRxChannel<'a>); 6] {
245 [
246 IpccChannel::new(1).split(),
247 IpccChannel::new(2).split(),
248 IpccChannel::new(3).split(),
249 IpccChannel::new(4).split(),
250 IpccChannel::new(5).split(),
251 IpccChannel::new(6).split(),
252 ]
253 }
254
255 /// Receive from a channel number
256 pub async unsafe fn receive<R>(number: u8, f: impl FnMut() -> Option<R>) -> R {
257 core::assert!(number > 0 && number <= 6);
258
259 IpccRxChannel::new(number - 1).receive(f).await
260 }
261
262 /// Send to a channel number
263 pub async unsafe fn send(number: u8, f: impl FnOnce()) {
264 core::assert!(number > 0 && number <= 6);
265
266 IpccTxChannel::new(number - 1).send(f).await
267 }
268
269 /// Send to a channel number
270 pub async unsafe fn flush(number: u8) {
271 core::assert!(number > 0 && number <= 6);
272
273 IpccTxChannel::new(number - 1).flush().await
274 }
275}
276
207impl SealedInstance for crate::peripherals::IPCC { 277impl SealedInstance for crate::peripherals::IPCC {
208 fn regs() -> crate::pac::ipcc::Ipcc { 278 fn regs() -> crate::pac::ipcc::Ipcc {
209 crate::pac::IPCC 279 crate::pac::IPCC
@@ -232,26 +302,12 @@ impl State {
232 } 302 }
233 } 303 }
234 304
235 const fn rx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { 305 const fn rx_waker_for(&self, index: u8) -> &AtomicWaker {
236 match channel { 306 &self.rx_wakers[index as usize]
237 IpccChannel::Channel1 => &self.rx_wakers[0],
238 IpccChannel::Channel2 => &self.rx_wakers[1],
239 IpccChannel::Channel3 => &self.rx_wakers[2],
240 IpccChannel::Channel4 => &self.rx_wakers[3],
241 IpccChannel::Channel5 => &self.rx_wakers[4],
242 IpccChannel::Channel6 => &self.rx_wakers[5],
243 }
244 } 307 }
245 308
246 const fn tx_waker_for(&self, channel: IpccChannel) -> &AtomicWaker { 309 const fn tx_waker_for(&self, index: u8) -> &AtomicWaker {
247 match channel { 310 &self.tx_wakers[index as usize]
248 IpccChannel::Channel1 => &self.tx_wakers[0],
249 IpccChannel::Channel2 => &self.tx_wakers[1],
250 IpccChannel::Channel3 => &self.tx_wakers[2],
251 IpccChannel::Channel4 => &self.tx_wakers[3],
252 IpccChannel::Channel5 => &self.tx_wakers[4],
253 IpccChannel::Channel6 => &self.tx_wakers[5],
254 }
255 } 311 }
256} 312}
257 313
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs
index f309ca3a2..413b1ac8f 100644
--- a/examples/stm32wb/src/bin/eddystone_beacon.rs
+++ b/examples/stm32wb/src/bin/eddystone_beacon.rs
@@ -57,126 +57,112 @@ async fn main(_spawner: Spawner) {
57 info!("Hello World!"); 57 info!("Hello World!");
58 58
59 let config = Config::default(); 59 let config = Config::default();
60 let mut mbox = TlMbox::init(p.IPCC, Irqs, config); 60 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
61 let mut sys = mbox.sys_subsystem;
62 let mut ble = mbox.ble_subsystem;
61 63
62 let sys_event = mbox.sys_subsystem.read().await; 64 let _ = sys.shci_c2_ble_init(Default::default()).await;
63 info!("sys event: {}", sys_event.payload());
64
65 let _ = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
66 65
67 info!("resetting BLE..."); 66 info!("resetting BLE...");
68 mbox.ble_subsystem.reset().await; 67 ble.reset().await;
69 let response = mbox.ble_subsystem.read().await.unwrap(); 68 let response = ble.read().await.unwrap();
70 defmt::info!("{}", response); 69 defmt::info!("{}", response);
71 70
72 info!("config public address..."); 71 info!("config public address...");
73 mbox.ble_subsystem 72 ble.write_config_data(&ConfigData::public_address(get_bd_addr()).build())
74 .write_config_data(&ConfigData::public_address(get_bd_addr()).build())
75 .await; 73 .await;
76 let response = mbox.ble_subsystem.read().await.unwrap(); 74 let response = ble.read().await.unwrap();
77 defmt::info!("{}", response); 75 defmt::info!("{}", response);
78 76
79 info!("config random address..."); 77 info!("config random address...");
80 mbox.ble_subsystem 78 ble.write_config_data(&ConfigData::random_address(get_random_addr()).build())
81 .write_config_data(&ConfigData::random_address(get_random_addr()).build())
82 .await; 79 .await;
83 let response = mbox.ble_subsystem.read().await.unwrap(); 80 let response = ble.read().await.unwrap();
84 defmt::info!("{}", response); 81 defmt::info!("{}", response);
85 82
86 info!("config identity root..."); 83 info!("config identity root...");
87 mbox.ble_subsystem 84 ble.write_config_data(&ConfigData::identity_root(&get_irk()).build())
88 .write_config_data(&ConfigData::identity_root(&get_irk()).build())
89 .await; 85 .await;
90 let response = mbox.ble_subsystem.read().await.unwrap(); 86 let response = ble.read().await.unwrap();
91 defmt::info!("{}", response); 87 defmt::info!("{}", response);
92 88
93 info!("config encryption root..."); 89 info!("config encryption root...");
94 mbox.ble_subsystem 90 ble.write_config_data(&ConfigData::encryption_root(&get_erk()).build())
95 .write_config_data(&ConfigData::encryption_root(&get_erk()).build())
96 .await; 91 .await;
97 let response = mbox.ble_subsystem.read().await.unwrap(); 92 let response = ble.read().await.unwrap();
98 defmt::info!("{}", response); 93 defmt::info!("{}", response);
99 94
100 info!("config tx power level..."); 95 info!("config tx power level...");
101 mbox.ble_subsystem.set_tx_power_level(PowerLevel::ZerodBm).await; 96 ble.set_tx_power_level(PowerLevel::ZerodBm).await;
102 let response = mbox.ble_subsystem.read().await.unwrap(); 97 let response = ble.read().await.unwrap();
103 defmt::info!("{}", response); 98 defmt::info!("{}", response);
104 99
105 info!("GATT init..."); 100 info!("GATT init...");
106 mbox.ble_subsystem.init_gatt().await; 101 ble.init_gatt().await;
107 let response = mbox.ble_subsystem.read().await.unwrap(); 102 let response = ble.read().await.unwrap();
108 defmt::info!("{}", response); 103 defmt::info!("{}", response);
109 104
110 info!("GAP init..."); 105 info!("GAP init...");
111 mbox.ble_subsystem 106 ble.init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH).await;
112 .init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH) 107 let response = ble.read().await.unwrap();
113 .await;
114 let response = mbox.ble_subsystem.read().await.unwrap();
115 defmt::info!("{}", response); 108 defmt::info!("{}", response);
116 109
117 // info!("set scan response..."); 110 // info!("set scan response...");
118 // mbox.ble_subsystem.le_set_scan_response_data(&[]).await.unwrap(); 111 // ble.le_set_scan_response_data(&[]).await.unwrap();
119 // let response = mbox.ble_subsystem.read().await.unwrap(); 112 // let response = ble.read().await.unwrap();
120 // defmt::info!("{}", response); 113 // defmt::info!("{}", response);
121 114
122 info!("set discoverable..."); 115 info!("set discoverable...");
123 mbox.ble_subsystem 116 ble.set_discoverable(&DiscoverableParameters {
124 .set_discoverable(&DiscoverableParameters { 117 advertising_type: AdvertisingType::NonConnectableUndirected,
125 advertising_type: AdvertisingType::NonConnectableUndirected, 118 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))),
126 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))), 119 address_type: OwnAddressType::Public,
127 address_type: OwnAddressType::Public, 120 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan,
128 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan, 121 local_name: None,
129 local_name: None, 122 advertising_data: &[],
130 advertising_data: &[], 123 conn_interval: (None, None),
131 conn_interval: (None, None), 124 })
132 }) 125 .await
133 .await 126 .unwrap();
134 .unwrap(); 127
135 128 let response = ble.read().await;
136 let response = mbox.ble_subsystem.read().await;
137 defmt::info!("{}", response); 129 defmt::info!("{}", response);
138 130
139 // remove some advertisement to decrease the packet size 131 // remove some advertisement to decrease the packet size
140 info!("delete tx power ad type..."); 132 info!("delete tx power ad type...");
141 mbox.ble_subsystem 133 ble.delete_ad_type(AdvertisingDataType::TxPowerLevel).await;
142 .delete_ad_type(AdvertisingDataType::TxPowerLevel) 134 let response = ble.read().await.unwrap();
143 .await;
144 let response = mbox.ble_subsystem.read().await.unwrap();
145 defmt::info!("{}", response); 135 defmt::info!("{}", response);
146 136
147 info!("delete conn interval ad type..."); 137 info!("delete conn interval ad type...");
148 mbox.ble_subsystem 138 ble.delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
149 .delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
150 .await; 139 .await;
151 let response = mbox.ble_subsystem.read().await.unwrap(); 140 let response = ble.read().await.unwrap();
152 defmt::info!("{}", response); 141 defmt::info!("{}", response);
153 142
154 info!("update advertising data..."); 143 info!("update advertising data...");
155 mbox.ble_subsystem 144 ble.update_advertising_data(&eddystone_advertising_data())
156 .update_advertising_data(&eddystone_advertising_data())
157 .await 145 .await
158 .unwrap(); 146 .unwrap();
159 let response = mbox.ble_subsystem.read().await.unwrap(); 147 let response = ble.read().await.unwrap();
160 defmt::info!("{}", response); 148 defmt::info!("{}", response);
161 149
162 info!("update advertising data type..."); 150 info!("update advertising data type...");
163 mbox.ble_subsystem 151 ble.update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
164 .update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
165 .await 152 .await
166 .unwrap(); 153 .unwrap();
167 let response = mbox.ble_subsystem.read().await.unwrap(); 154 let response = ble.read().await.unwrap();
168 defmt::info!("{}", response); 155 defmt::info!("{}", response);
169 156
170 info!("update advertising data flags..."); 157 info!("update advertising data flags...");
171 mbox.ble_subsystem 158 ble.update_advertising_data(&[
172 .update_advertising_data(&[ 159 2,
173 2, 160 AdvertisingDataType::Flags as u8,
174 AdvertisingDataType::Flags as u8, 161 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support
175 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support 162 ])
176 ]) 163 .await
177 .await 164 .unwrap();
178 .unwrap(); 165 let response = ble.read().await.unwrap();
179 let response = mbox.ble_subsystem.read().await.unwrap();
180 defmt::info!("{}", response); 166 defmt::info!("{}", response);
181 167
182 cortex_m::asm::wfi(); 168 cortex_m::asm::wfi();
diff --git a/examples/stm32wb/src/bin/gatt_server.rs b/examples/stm32wb/src/bin/gatt_server.rs
index 2ed257566..3484f1844 100644
--- a/examples/stm32wb/src/bin/gatt_server.rs
+++ b/examples/stm32wb/src/bin/gatt_server.rs
@@ -69,92 +69,85 @@ async fn main(spawner: Spawner) {
69 info!("Hello World!"); 69 info!("Hello World!");
70 70
71 let config = Config::default(); 71 let config = Config::default();
72 let mut mbox = TlMbox::init(p.IPCC, Irqs, config); 72 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
73 let mut sys = mbox.sys_subsystem;
74 let mut ble = mbox.ble_subsystem;
73 75
74 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 76 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
75 let sys_event = mbox.sys_subsystem.read().await;
76 info!("sys event: {}", sys_event.payload());
77 77
78 let _ = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; 78 let _ = sys.shci_c2_ble_init(Default::default()).await;
79 79
80 info!("resetting BLE..."); 80 info!("resetting BLE...");
81 mbox.ble_subsystem.reset().await; 81 ble.reset().await;
82 let response = mbox.ble_subsystem.read().await; 82 let response = ble.read().await;
83 defmt::debug!("{}", response); 83 defmt::debug!("{}", response);
84 84
85 info!("config public address..."); 85 info!("config public address...");
86 mbox.ble_subsystem 86 ble.write_config_data(&ConfigData::public_address(get_bd_addr()).build())
87 .write_config_data(&ConfigData::public_address(get_bd_addr()).build())
88 .await; 87 .await;
89 let response = mbox.ble_subsystem.read().await; 88 let response = ble.read().await;
90 defmt::debug!("{}", response); 89 defmt::debug!("{}", response);
91 90
92 info!("config random address..."); 91 info!("config random address...");
93 mbox.ble_subsystem 92 ble.write_config_data(&ConfigData::random_address(get_random_addr()).build())
94 .write_config_data(&ConfigData::random_address(get_random_addr()).build())
95 .await; 93 .await;
96 let response = mbox.ble_subsystem.read().await; 94 let response = ble.read().await;
97 defmt::debug!("{}", response); 95 defmt::debug!("{}", response);
98 96
99 info!("config identity root..."); 97 info!("config identity root...");
100 mbox.ble_subsystem 98 ble.write_config_data(&ConfigData::identity_root(&get_irk()).build())
101 .write_config_data(&ConfigData::identity_root(&get_irk()).build())
102 .await; 99 .await;
103 let response = mbox.ble_subsystem.read().await; 100 let response = ble.read().await;
104 defmt::debug!("{}", response); 101 defmt::debug!("{}", response);
105 102
106 info!("config encryption root..."); 103 info!("config encryption root...");
107 mbox.ble_subsystem 104 ble.write_config_data(&ConfigData::encryption_root(&get_erk()).build())
108 .write_config_data(&ConfigData::encryption_root(&get_erk()).build())
109 .await; 105 .await;
110 let response = mbox.ble_subsystem.read().await; 106 let response = ble.read().await;
111 defmt::debug!("{}", response); 107 defmt::debug!("{}", response);
112 108
113 info!("config tx power level..."); 109 info!("config tx power level...");
114 mbox.ble_subsystem.set_tx_power_level(PowerLevel::ZerodBm).await; 110 ble.set_tx_power_level(PowerLevel::ZerodBm).await;
115 let response = mbox.ble_subsystem.read().await; 111 let response = ble.read().await;
116 defmt::debug!("{}", response); 112 defmt::debug!("{}", response);
117 113
118 info!("GATT init..."); 114 info!("GATT init...");
119 mbox.ble_subsystem.init_gatt().await; 115 ble.init_gatt().await;
120 let response = mbox.ble_subsystem.read().await; 116 let response = ble.read().await;
121 defmt::debug!("{}", response); 117 defmt::debug!("{}", response);
122 118
123 info!("GAP init..."); 119 info!("GAP init...");
124 mbox.ble_subsystem 120 ble.init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH).await;
125 .init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH) 121 let response = ble.read().await;
126 .await;
127 let response = mbox.ble_subsystem.read().await;
128 defmt::debug!("{}", response); 122 defmt::debug!("{}", response);
129 123
130 info!("set IO capabilities..."); 124 info!("set IO capabilities...");
131 mbox.ble_subsystem.set_io_capability(IoCapability::DisplayConfirm).await; 125 ble.set_io_capability(IoCapability::DisplayConfirm).await;
132 let response = mbox.ble_subsystem.read().await; 126 let response = ble.read().await;
133 defmt::debug!("{}", response); 127 defmt::debug!("{}", response);
134 128
135 info!("set authentication requirements..."); 129 info!("set authentication requirements...");
136 mbox.ble_subsystem 130 ble.set_authentication_requirement(&AuthenticationRequirements {
137 .set_authentication_requirement(&AuthenticationRequirements { 131 bonding_required: false,
138 bonding_required: false, 132 keypress_notification_support: false,
139 keypress_notification_support: false, 133 mitm_protection_required: false,
140 mitm_protection_required: false, 134 encryption_key_size_range: (8, 16),
141 encryption_key_size_range: (8, 16), 135 fixed_pin: Pin::Requested,
142 fixed_pin: Pin::Requested, 136 identity_address_type: AddressType::Public,
143 identity_address_type: AddressType::Public, 137 secure_connection_support: SecureConnectionSupport::Optional,
144 secure_connection_support: SecureConnectionSupport::Optional, 138 })
145 }) 139 .await
146 .await 140 .unwrap();
147 .unwrap(); 141 let response = ble.read().await;
148 let response = mbox.ble_subsystem.read().await;
149 defmt::debug!("{}", response); 142 defmt::debug!("{}", response);
150 143
151 info!("set scan response data..."); 144 info!("set scan response data...");
152 mbox.ble_subsystem.le_set_scan_response_data(b"TXTX").await.unwrap(); 145 ble.le_set_scan_response_data(b"TXTX").await.unwrap();
153 let response = mbox.ble_subsystem.read().await; 146 let response = ble.read().await;
154 defmt::debug!("{}", response); 147 defmt::debug!("{}", response);
155 148
156 defmt::info!("initializing services and characteristics..."); 149 defmt::info!("initializing services and characteristics...");
157 let mut ble_context = init_gatt_services(&mut mbox.ble_subsystem).await.unwrap(); 150 let mut ble_context = init_gatt_services(&mut ble).await.unwrap();
158 defmt::info!("{}", ble_context); 151 defmt::info!("{}", ble_context);
159 152
160 let discovery_params = DiscoverableParameters { 153 let discovery_params = DiscoverableParameters {
@@ -168,12 +161,12 @@ async fn main(spawner: Spawner) {
168 }; 161 };
169 162
170 info!("set discoverable..."); 163 info!("set discoverable...");
171 mbox.ble_subsystem.set_discoverable(&discovery_params).await.unwrap(); 164 ble.set_discoverable(&discovery_params).await.unwrap();
172 let response = mbox.ble_subsystem.read().await; 165 let response = ble.read().await;
173 defmt::debug!("{}", response); 166 defmt::debug!("{}", response);
174 167
175 loop { 168 loop {
176 let response = mbox.ble_subsystem.read().await; 169 let response = ble.read().await;
177 defmt::debug!("{}", response); 170 defmt::debug!("{}", response);
178 171
179 if let Ok(Packet::Event(event)) = response { 172 if let Ok(Packet::Event(event)) = response {
@@ -184,24 +177,23 @@ async fn main(spawner: Spawner) {
184 Event::DisconnectionComplete(_) => { 177 Event::DisconnectionComplete(_) => {
185 defmt::info!("disconnected"); 178 defmt::info!("disconnected");
186 ble_context.is_subscribed = false; 179 ble_context.is_subscribed = false;
187 mbox.ble_subsystem.set_discoverable(&discovery_params).await.unwrap(); 180 ble.set_discoverable(&discovery_params).await.unwrap();
188 } 181 }
189 Event::Vendor(vendor_event) => match vendor_event { 182 Event::Vendor(vendor_event) => match vendor_event {
190 VendorEvent::AttReadPermitRequest(read_req) => { 183 VendorEvent::AttReadPermitRequest(read_req) => {
191 defmt::info!("read request received {}, allowing", read_req); 184 defmt::info!("read request received {}, allowing", read_req);
192 mbox.ble_subsystem.allow_read(read_req.conn_handle).await 185 ble.allow_read(read_req.conn_handle).await
193 } 186 }
194 VendorEvent::AttWritePermitRequest(write_req) => { 187 VendorEvent::AttWritePermitRequest(write_req) => {
195 defmt::info!("write request received {}, allowing", write_req); 188 defmt::info!("write request received {}, allowing", write_req);
196 mbox.ble_subsystem 189 ble.write_response(&WriteResponseParameters {
197 .write_response(&WriteResponseParameters { 190 conn_handle: write_req.conn_handle,
198 conn_handle: write_req.conn_handle, 191 attribute_handle: write_req.attribute_handle,
199 attribute_handle: write_req.attribute_handle, 192 status: Ok(()),
200 status: Ok(()), 193 value: write_req.value(),
201 value: write_req.value(), 194 })
202 }) 195 .await
203 .await 196 .unwrap()
204 .unwrap()
205 } 197 }
206 VendorEvent::GattAttributeModified(attribute) => { 198 VendorEvent::GattAttributeModified(attribute) => {
207 defmt::info!("{}", ble_context); 199 defmt::info!("{}", ble_context);
@@ -224,7 +216,7 @@ async fn main(spawner: Spawner) {
224} 216}
225 217
226#[embassy_executor::task] 218#[embassy_executor::task]
227async fn run_mm_queue(memory_manager: mm::MemoryManager) { 219async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
228 memory_manager.run_queue().await; 220 memory_manager.run_queue().await;
229} 221}
230 222
@@ -285,7 +277,7 @@ pub struct CharHandles {
285 pub notify: AttributeHandle, 277 pub notify: AttributeHandle,
286} 278}
287 279
288pub async fn init_gatt_services(ble_subsystem: &mut Ble) -> Result<BleContext, ()> { 280pub async fn init_gatt_services<'a>(ble_subsystem: &mut Ble<'a>) -> Result<BleContext, ()> {
289 let service_handle = gatt_add_service(ble_subsystem, Uuid::Uuid16(0x500)).await?; 281 let service_handle = gatt_add_service(ble_subsystem, Uuid::Uuid16(0x500)).await?;
290 282
291 let read = gatt_add_char( 283 let read = gatt_add_char(
@@ -322,7 +314,7 @@ pub async fn init_gatt_services(ble_subsystem: &mut Ble) -> Result<BleContext, (
322 }) 314 })
323} 315}
324 316
325async fn gatt_add_service(ble_subsystem: &mut Ble, uuid: Uuid) -> Result<AttributeHandle, ()> { 317async fn gatt_add_service<'a>(ble_subsystem: &mut Ble<'a>, uuid: Uuid) -> Result<AttributeHandle, ()> {
326 ble_subsystem 318 ble_subsystem
327 .add_service(&AddServiceParameters { 319 .add_service(&AddServiceParameters {
328 uuid, 320 uuid,
@@ -348,8 +340,8 @@ async fn gatt_add_service(ble_subsystem: &mut Ble, uuid: Uuid) -> Result<Attribu
348 } 340 }
349} 341}
350 342
351async fn gatt_add_char( 343async fn gatt_add_char<'a>(
352 ble_subsystem: &mut Ble, 344 ble_subsystem: &mut Ble<'a>,
353 service_handle: AttributeHandle, 345 service_handle: AttributeHandle,
354 characteristic_uuid: Uuid, 346 characteristic_uuid: Uuid,
355 characteristic_properties: CharacteristicProperty, 347 characteristic_properties: CharacteristicProperty,
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs
index 18a52e162..4bab6ea9f 100644
--- a/examples/stm32wb/src/bin/mac_ffd.rs
+++ b/examples/stm32wb/src/bin/mac_ffd.rs
@@ -19,7 +19,7 @@ bind_interrupts!(struct Irqs{
19}); 19});
20 20
21#[embassy_executor::task] 21#[embassy_executor::task]
22async fn run_mm_queue(memory_manager: mm::MemoryManager) { 22async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
23 memory_manager.run_queue().await; 23 memory_manager.run_queue().await;
24} 24}
25 25
@@ -54,74 +54,72 @@ async fn main(spawner: Spawner) {
54 info!("Hello World!"); 54 info!("Hello World!");
55 55
56 let config = Config::default(); 56 let config = Config::default();
57 let mbox = TlMbox::init(p.IPCC, Irqs, config); 57 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
58 let mut sys = mbox.sys_subsystem;
58 59
59 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 60 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
60 61
61 let sys_event = mbox.sys_subsystem.read().await; 62 let result = sys.shci_c2_mac_802_15_4_init().await;
62 info!("sys event: {}", sys_event.payload());
63
64 core::mem::drop(sys_event);
65
66 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
67 info!("initialized mac: {}", result); 63 info!("initialized mac: {}", result);
68 64
65 let (mut mac_rx, mut mac_tx) = mbox.mac_subsystem.split();
66
69 info!("resetting"); 67 info!("resetting");
70 mbox.mac_subsystem 68 mac_tx
71 .send_command(&ResetRequest { 69 .send_command(&ResetRequest {
72 set_default_pib: true, 70 set_default_pib: true,
73 ..Default::default() 71 ..Default::default()
74 }) 72 })
75 .await 73 .await
76 .unwrap(); 74 .unwrap();
77 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 75 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
78 76
79 info!("setting extended address"); 77 info!("setting extended address");
80 let extended_address: u64 = 0xACDE480000000001; 78 let extended_address: u64 = 0xACDE480000000001;
81 mbox.mac_subsystem 79 mac_tx
82 .send_command(&SetRequest { 80 .send_command(&SetRequest {
83 pib_attribute_ptr: &extended_address as *const _ as *const u8, 81 pib_attribute_ptr: &extended_address as *const _ as *const u8,
84 pib_attribute: PibId::ExtendedAddress, 82 pib_attribute: PibId::ExtendedAddress,
85 }) 83 })
86 .await 84 .await
87 .unwrap(); 85 .unwrap();
88 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 86 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
89 87
90 info!("setting short address"); 88 info!("setting short address");
91 let short_address: u16 = 0x1122; 89 let short_address: u16 = 0x1122;
92 mbox.mac_subsystem 90 mac_tx
93 .send_command(&SetRequest { 91 .send_command(&SetRequest {
94 pib_attribute_ptr: &short_address as *const _ as *const u8, 92 pib_attribute_ptr: &short_address as *const _ as *const u8,
95 pib_attribute: PibId::ShortAddress, 93 pib_attribute: PibId::ShortAddress,
96 }) 94 })
97 .await 95 .await
98 .unwrap(); 96 .unwrap();
99 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 97 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
100 98
101 info!("setting association permit"); 99 info!("setting association permit");
102 let association_permit: bool = true; 100 let association_permit: bool = true;
103 mbox.mac_subsystem 101 mac_tx
104 .send_command(&SetRequest { 102 .send_command(&SetRequest {
105 pib_attribute_ptr: &association_permit as *const _ as *const u8, 103 pib_attribute_ptr: &association_permit as *const _ as *const u8,
106 pib_attribute: PibId::AssociationPermit, 104 pib_attribute: PibId::AssociationPermit,
107 }) 105 })
108 .await 106 .await
109 .unwrap(); 107 .unwrap();
110 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 108 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
111 109
112 info!("setting TX power"); 110 info!("setting TX power");
113 let transmit_power: i8 = 2; 111 let transmit_power: i8 = 2;
114 mbox.mac_subsystem 112 mac_tx
115 .send_command(&SetRequest { 113 .send_command(&SetRequest {
116 pib_attribute_ptr: &transmit_power as *const _ as *const u8, 114 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
117 pib_attribute: PibId::TransmitPower, 115 pib_attribute: PibId::TransmitPower,
118 }) 116 })
119 .await 117 .await
120 .unwrap(); 118 .unwrap();
121 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 119 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
122 120
123 info!("starting FFD device"); 121 info!("starting FFD device");
124 mbox.mac_subsystem 122 mac_tx
125 .send_command(&StartRequest { 123 .send_command(&StartRequest {
126 pan_id: PanId([0x1A, 0xAA]), 124 pan_id: PanId([0x1A, 0xAA]),
127 channel_number: MacChannel::Channel16, 125 channel_number: MacChannel::Channel16,
@@ -133,28 +131,27 @@ async fn main(spawner: Spawner) {
133 }) 131 })
134 .await 132 .await
135 .unwrap(); 133 .unwrap();
136 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 134 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
137 135
138 info!("setting RX on when idle"); 136 info!("setting RX on when idle");
139 let rx_on_while_idle: bool = true; 137 let rx_on_while_idle: bool = true;
140 mbox.mac_subsystem 138 mac_tx
141 .send_command(&SetRequest { 139 .send_command(&SetRequest {
142 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8, 140 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
143 pib_attribute: PibId::RxOnWhenIdle, 141 pib_attribute: PibId::RxOnWhenIdle,
144 }) 142 })
145 .await 143 .await
146 .unwrap(); 144 .unwrap();
147 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 145 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
148 146
149 loop { 147 loop {
150 let evt = mbox.mac_subsystem.read().await; 148 let evt = mac_rx.read().await;
151 if let Ok(evt) = evt { 149 if let Ok(evt) = evt {
152 defmt::info!("parsed mac event"); 150 defmt::info!("parsed mac event");
153 defmt::info!("{:#x}", evt); 151 defmt::info!("{:#x}", evt);
154 152
155 match evt { 153 match evt {
156 MacEvent::MlmeAssociateInd(association) => mbox 154 MacEvent::MlmeAssociateInd(association) => mac_tx
157 .mac_subsystem
158 .send_command(&AssociateResponse { 155 .send_command(&AssociateResponse {
159 device_address: association.device_address, 156 device_address: association.device_address,
160 assoc_short_address: [0x33, 0x44], 157 assoc_short_address: [0x33, 0x44],
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs
index 5d946b35b..b4789e3ee 100644
--- a/examples/stm32wb/src/bin/mac_ffd_net.rs
+++ b/examples/stm32wb/src/bin/mac_ffd_net.rs
@@ -27,7 +27,7 @@ bind_interrupts!(struct Irqs{
27}); 27});
28 28
29#[embassy_executor::task] 29#[embassy_executor::task]
30async fn run_mm_queue(memory_manager: mm::MemoryManager) -> ! { 30async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) -> ! {
31 memory_manager.run_queue().await 31 memory_manager.run_queue().await
32} 32}
33 33
@@ -72,15 +72,10 @@ async fn main(spawner: Spawner) {
72 info!("Hello World!"); 72 info!("Hello World!");
73 73
74 let config = Config::default(); 74 let config = Config::default();
75 let mbox = TlMbox::init(p.IPCC, Irqs, config); 75 let mut mbox = TlMbox::init(p.IPCC, Irqs, config).await;
76 76
77 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 77 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
78 78
79 let sys_event = mbox.sys_subsystem.read().await;
80 info!("sys event: {}", sys_event.payload());
81
82 core::mem::drop(sys_event);
83
84 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; 79 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
85 info!("initialized mac: {}", result); 80 info!("initialized mac: {}", result);
86 81
diff --git a/examples/stm32wb/src/bin/mac_rfd.rs b/examples/stm32wb/src/bin/mac_rfd.rs
index 883179023..dae3c5200 100644
--- a/examples/stm32wb/src/bin/mac_rfd.rs
+++ b/examples/stm32wb/src/bin/mac_rfd.rs
@@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs{
21}); 21});
22 22
23#[embassy_executor::task] 23#[embassy_executor::task]
24async fn run_mm_queue(memory_manager: mm::MemoryManager) { 24async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
25 memory_manager.run_queue().await; 25 memory_manager.run_queue().await;
26} 26}
27 27
@@ -56,41 +56,39 @@ async fn main(spawner: Spawner) {
56 info!("Hello World!"); 56 info!("Hello World!");
57 57
58 let config = Config::default(); 58 let config = Config::default();
59 let mbox = TlMbox::init(p.IPCC, Irqs, config); 59 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
60 let mut sys = mbox.sys_subsystem;
60 61
61 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 62 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
62 63
63 let sys_event = mbox.sys_subsystem.read().await; 64 let result = sys.shci_c2_mac_802_15_4_init().await;
64 info!("sys event: {}", sys_event.payload());
65
66 core::mem::drop(sys_event);
67
68 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
69 info!("initialized mac: {}", result); 65 info!("initialized mac: {}", result);
70 66
67 let (mut mac_rx, mut mac_tx) = mbox.mac_subsystem.split();
68
71 info!("resetting"); 69 info!("resetting");
72 mbox.mac_subsystem 70 mac_tx
73 .send_command(&ResetRequest { 71 .send_command(&ResetRequest {
74 set_default_pib: true, 72 set_default_pib: true,
75 ..Default::default() 73 ..Default::default()
76 }) 74 })
77 .await 75 .await
78 .unwrap(); 76 .unwrap();
79 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 77 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
80 78
81 info!("setting extended address"); 79 info!("setting extended address");
82 let extended_address: u64 = 0xACDE480000000002; 80 let extended_address: u64 = 0xACDE480000000002;
83 mbox.mac_subsystem 81 mac_tx
84 .send_command(&SetRequest { 82 .send_command(&SetRequest {
85 pib_attribute_ptr: &extended_address as *const _ as *const u8, 83 pib_attribute_ptr: &extended_address as *const _ as *const u8,
86 pib_attribute: PibId::ExtendedAddress, 84 pib_attribute: PibId::ExtendedAddress,
87 }) 85 })
88 .await 86 .await
89 .unwrap(); 87 .unwrap();
90 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap()); 88 defmt::info!("{:#x}", mac_rx.read().await.unwrap());
91 89
92 info!("getting extended address"); 90 info!("getting extended address");
93 mbox.mac_subsystem 91 mac_tx
94 .send_command(&GetRequest { 92 .send_command(&GetRequest {
95 pib_attribute: PibId::ExtendedAddress, 93 pib_attribute: PibId::ExtendedAddress,
96 ..Default::default() 94 ..Default::default()
@@ -99,7 +97,7 @@ async fn main(spawner: Spawner) {
99 .unwrap(); 97 .unwrap();
100 98
101 { 99 {
102 let evt = mbox.mac_subsystem.read().await.unwrap(); 100 let evt = mac_rx.read().await.unwrap();
103 info!("{:#x}", evt); 101 info!("{:#x}", evt);
104 102
105 if let MacEvent::MlmeGetCnf(evt) = evt { 103 if let MacEvent::MlmeGetCnf(evt) = evt {
@@ -125,9 +123,9 @@ async fn main(spawner: Spawner) {
125 key_index: 152, 123 key_index: 152,
126 }; 124 };
127 info!("{}", a); 125 info!("{}", a);
128 mbox.mac_subsystem.send_command(&a).await.unwrap(); 126 mac_tx.send_command(&a).await.unwrap();
129 let short_addr = { 127 let short_addr = {
130 let evt = mbox.mac_subsystem.read().await.unwrap(); 128 let evt = mac_rx.read().await.unwrap();
131 info!("{:#x}", evt); 129 info!("{:#x}", evt);
132 130
133 if let MacEvent::MlmeAssociateCnf(conf) = evt { 131 if let MacEvent::MlmeAssociateCnf(conf) = evt {
@@ -138,7 +136,7 @@ async fn main(spawner: Spawner) {
138 }; 136 };
139 137
140 info!("setting short address"); 138 info!("setting short address");
141 mbox.mac_subsystem 139 mac_tx
142 .send_command(&SetRequest { 140 .send_command(&SetRequest {
143 pib_attribute_ptr: &short_addr as *const _ as *const u8, 141 pib_attribute_ptr: &short_addr as *const _ as *const u8,
144 pib_attribute: PibId::ShortAddress, 142 pib_attribute: PibId::ShortAddress,
@@ -146,13 +144,13 @@ async fn main(spawner: Spawner) {
146 .await 144 .await
147 .unwrap(); 145 .unwrap();
148 { 146 {
149 let evt = mbox.mac_subsystem.read().await.unwrap(); 147 let evt = mac_rx.read().await.unwrap();
150 info!("{:#x}", evt); 148 info!("{:#x}", evt);
151 } 149 }
152 150
153 info!("sending data"); 151 info!("sending data");
154 let data = b"Hello from embassy!"; 152 let data = b"Hello from embassy!";
155 mbox.mac_subsystem 153 mac_tx
156 .send_command( 154 .send_command(
157 DataRequest { 155 DataRequest {
158 src_addr_mode: AddressMode::Short, 156 src_addr_mode: AddressMode::Short,
@@ -170,12 +168,12 @@ async fn main(spawner: Spawner) {
170 .await 168 .await
171 .unwrap(); 169 .unwrap();
172 { 170 {
173 let evt = mbox.mac_subsystem.read().await.unwrap(); 171 let evt = mac_rx.read().await.unwrap();
174 info!("{:#x}", evt); 172 info!("{:#x}", evt);
175 } 173 }
176 174
177 loop { 175 loop {
178 match mbox.mac_subsystem.read().await { 176 match mac_rx.read().await {
179 Ok(evt) => info!("{:#x}", evt), 177 Ok(evt) => info!("{:#x}", evt),
180 _ => continue, 178 _ => continue,
181 }; 179 };
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs
index 4e7f2304d..0902e28e8 100644
--- a/examples/stm32wb/src/bin/tl_mbox.rs
+++ b/examples/stm32wb/src/bin/tl_mbox.rs
@@ -46,7 +46,7 @@ async fn main(_spawner: Spawner) {
46 info!("Hello World!"); 46 info!("Hello World!");
47 47
48 let config = Config::default(); 48 let config = Config::default();
49 let mbox = TlMbox::init(p.IPCC, Irqs, config); 49 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
50 50
51 loop { 51 loop {
52 let wireless_fw_info = mbox.sys_subsystem.wireless_fw_info(); 52 let wireless_fw_info = mbox.sys_subsystem.wireless_fw_info();
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs
index 72a4c18e6..763dc32cd 100644
--- a/examples/stm32wb/src/bin/tl_mbox_ble.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs
@@ -7,6 +7,7 @@ use embassy_stm32::bind_interrupts;
7use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 7use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
8use embassy_stm32::rcc::WPAN_DEFAULT; 8use embassy_stm32::rcc::WPAN_DEFAULT;
9use embassy_stm32_wpan::TlMbox; 9use embassy_stm32_wpan::TlMbox;
10use embassy_stm32_wpan::sub::mm;
10use {defmt_rtt as _, panic_probe as _}; 11use {defmt_rtt as _, panic_probe as _};
11 12
12bind_interrupts!(struct Irqs{ 13bind_interrupts!(struct Irqs{
@@ -14,8 +15,13 @@ bind_interrupts!(struct Irqs{
14 IPCC_C1_TX => TransmitInterruptHandler; 15 IPCC_C1_TX => TransmitInterruptHandler;
15}); 16});
16 17
18#[embassy_executor::task]
19async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
20 memory_manager.run_queue().await;
21}
22
17#[embassy_executor::main] 23#[embassy_executor::main]
18async fn main(_spawner: Spawner) { 24async fn main(spawner: Spawner) {
19 /* 25 /*
20 How to make this work: 26 How to make this work:
21 27
@@ -45,18 +51,19 @@ async fn main(_spawner: Spawner) {
45 info!("Hello World!"); 51 info!("Hello World!");
46 52
47 let config = Config::default(); 53 let config = Config::default();
48 let mbox = TlMbox::init(p.IPCC, Irqs, config); 54 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
55 let mut sys = mbox.sys_subsystem;
56 let mut ble = mbox.ble_subsystem;
49 57
50 let sys_event = mbox.sys_subsystem.read().await; 58 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
51 info!("sys event: {}", sys_event.payload());
52 59
53 let _ = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; 60 let _ = sys.shci_c2_ble_init(Default::default()).await;
54 61
55 info!("starting ble..."); 62 info!("starting ble...");
56 mbox.ble_subsystem.tl_write(0x0c, &[]).await; 63 ble.tl_write(0x0c, &[]).await;
57 64
58 info!("waiting for ble..."); 65 info!("waiting for ble...");
59 let ble_event = mbox.ble_subsystem.tl_read().await; 66 let ble_event = ble.tl_read().await;
60 67
61 info!("ble event: {}", ble_event.payload()); 68 info!("ble event: {}", ble_event.payload());
62 69
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs
index 16d0a1527..235a48241 100644
--- a/examples/stm32wb/src/bin/tl_mbox_mac.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs
@@ -16,7 +16,7 @@ bind_interrupts!(struct Irqs{
16}); 16});
17 17
18#[embassy_executor::task] 18#[embassy_executor::task]
19async fn run_mm_queue(memory_manager: mm::MemoryManager) { 19async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
20 memory_manager.run_queue().await; 20 memory_manager.run_queue().await;
21} 21}
22 22
@@ -51,16 +51,12 @@ async fn main(spawner: Spawner) {
51 info!("Hello World!"); 51 info!("Hello World!");
52 52
53 let config = Config::default(); 53 let config = Config::default();
54 let mbox = TlMbox::init(p.IPCC, Irqs, config); 54 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
55 let mut sys = mbox.sys_subsystem;
55 56
56 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 57 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
57 58
58 let sys_event = mbox.sys_subsystem.read().await; 59 let result = sys.shci_c2_mac_802_15_4_init().await;
59 info!("sys event: {}", sys_event.payload());
60
61 core::mem::drop(sys_event);
62
63 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
64 info!("initialized mac: {}", result); 60 info!("initialized mac: {}", result);
65 61
66 // 62 //
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs
index 0f396b848..b4c0cbf56 100644
--- a/tests/stm32/src/bin/wpan_ble.rs
+++ b/tests/stm32/src/bin/wpan_ble.rs
@@ -32,7 +32,7 @@ bind_interrupts!(struct Irqs{
32const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7; 32const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7;
33 33
34#[embassy_executor::task] 34#[embassy_executor::task]
35async fn run_mm_queue(memory_manager: mm::MemoryManager) { 35async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
36 memory_manager.run_queue().await; 36 memory_manager.run_queue().await;
37} 37}
38 38
@@ -45,14 +45,13 @@ async fn main(spawner: Spawner) {
45 info!("Hello World!"); 45 info!("Hello World!");
46 46
47 let config = Config::default(); 47 let config = Config::default();
48 let mut mbox = TlMbox::init(p.IPCC, Irqs, config); 48 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
49 let mut sys = mbox.sys_subsystem;
50 let mut ble = mbox.ble_subsystem;
49 51
50 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 52 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
51 53
52 let sys_event = mbox.sys_subsystem.read().await; 54 let fw_info = sys.wireless_fw_info().unwrap();
53 info!("sys event: {}", sys_event.payload());
54
55 let fw_info = mbox.sys_subsystem.wireless_fw_info().unwrap();
56 let version_major = fw_info.version_major(); 55 let version_major = fw_info.version_major();
57 let version_minor = fw_info.version_minor(); 56 let version_minor = fw_info.version_minor();
58 let subversion = fw_info.subversion(); 57 let subversion = fw_info.subversion();
@@ -65,121 +64,108 @@ async fn main(spawner: Spawner) {
65 version_major, version_minor, subversion, sram2a_size, sram2b_size 64 version_major, version_minor, subversion, sram2a_size, sram2b_size
66 ); 65 );
67 66
68 let _ = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; 67 let _ = sys.shci_c2_ble_init(Default::default()).await;
69 68
70 info!("resetting BLE..."); 69 info!("resetting BLE...");
71 mbox.ble_subsystem.reset().await; 70 ble.reset().await;
72 let response = mbox.ble_subsystem.read().await.unwrap(); 71 let response = ble.read().await.unwrap();
73 info!("{}", response); 72 info!("{}", response);
74 73
75 info!("config public address..."); 74 info!("config public address...");
76 mbox.ble_subsystem 75 ble.write_config_data(&ConfigData::public_address(get_bd_addr()).build())
77 .write_config_data(&ConfigData::public_address(get_bd_addr()).build())
78 .await; 76 .await;
79 let response = mbox.ble_subsystem.read().await.unwrap(); 77 let response = ble.read().await.unwrap();
80 info!("{}", response); 78 info!("{}", response);
81 79
82 info!("config random address..."); 80 info!("config random address...");
83 mbox.ble_subsystem 81 ble.write_config_data(&ConfigData::random_address(get_random_addr()).build())
84 .write_config_data(&ConfigData::random_address(get_random_addr()).build())
85 .await; 82 .await;
86 let response = mbox.ble_subsystem.read().await.unwrap(); 83 let response = ble.read().await.unwrap();
87 info!("{}", response); 84 info!("{}", response);
88 85
89 info!("config identity root..."); 86 info!("config identity root...");
90 mbox.ble_subsystem 87 ble.write_config_data(&ConfigData::identity_root(&get_irk()).build())
91 .write_config_data(&ConfigData::identity_root(&get_irk()).build())
92 .await; 88 .await;
93 let response = mbox.ble_subsystem.read().await.unwrap(); 89 let response = ble.read().await.unwrap();
94 info!("{}", response); 90 info!("{}", response);
95 91
96 info!("config encryption root..."); 92 info!("config encryption root...");
97 mbox.ble_subsystem 93 ble.write_config_data(&ConfigData::encryption_root(&get_erk()).build())
98 .write_config_data(&ConfigData::encryption_root(&get_erk()).build())
99 .await; 94 .await;
100 let response = mbox.ble_subsystem.read().await.unwrap(); 95 let response = ble.read().await.unwrap();
101 info!("{}", response); 96 info!("{}", response);
102 97
103 info!("config tx power level..."); 98 info!("config tx power level...");
104 mbox.ble_subsystem.set_tx_power_level(PowerLevel::ZerodBm).await; 99 ble.set_tx_power_level(PowerLevel::ZerodBm).await;
105 let response = mbox.ble_subsystem.read().await.unwrap(); 100 let response = ble.read().await.unwrap();
106 info!("{}", response); 101 info!("{}", response);
107 102
108 info!("GATT init..."); 103 info!("GATT init...");
109 mbox.ble_subsystem.init_gatt().await; 104 ble.init_gatt().await;
110 let response = mbox.ble_subsystem.read().await.unwrap(); 105 let response = ble.read().await.unwrap();
111 info!("{}", response); 106 info!("{}", response);
112 107
113 info!("GAP init..."); 108 info!("GAP init...");
114 mbox.ble_subsystem 109 ble.init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH).await;
115 .init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH) 110 let response = ble.read().await.unwrap();
116 .await;
117 let response = mbox.ble_subsystem.read().await.unwrap();
118 info!("{}", response); 111 info!("{}", response);
119 112
120 // info!("set scan response..."); 113 // info!("set scan response...");
121 // mbox.ble_subsystem.le_set_scan_response_data(&[]).await.unwrap(); 114 // ble.le_set_scan_response_data(&[]).await.unwrap();
122 // let response = mbox.ble_subsystem.read().await.unwrap(); 115 // let response = ble.read().await.unwrap();
123 // info!("{}", response); 116 // info!("{}", response);
124 117
125 info!("set discoverable..."); 118 info!("set discoverable...");
126 mbox.ble_subsystem 119 ble.set_discoverable(&DiscoverableParameters {
127 .set_discoverable(&DiscoverableParameters { 120 advertising_type: AdvertisingType::NonConnectableUndirected,
128 advertising_type: AdvertisingType::NonConnectableUndirected, 121 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))),
129 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))), 122 address_type: OwnAddressType::Public,
130 address_type: OwnAddressType::Public, 123 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan,
131 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan, 124 local_name: None,
132 local_name: None, 125 advertising_data: &[],
133 advertising_data: &[], 126 conn_interval: (None, None),
134 conn_interval: (None, None), 127 })
135 }) 128 .await
136 .await 129 .unwrap();
137 .unwrap(); 130
138 131 let response = ble.read().await;
139 let response = mbox.ble_subsystem.read().await;
140 info!("{}", response); 132 info!("{}", response);
141 133
142 // remove some advertisement to decrease the packet size 134 // remove some advertisement to decrease the packet size
143 info!("delete tx power ad type..."); 135 info!("delete tx power ad type...");
144 mbox.ble_subsystem 136 ble.delete_ad_type(AdvertisingDataType::TxPowerLevel).await;
145 .delete_ad_type(AdvertisingDataType::TxPowerLevel) 137 let response = ble.read().await.unwrap();
146 .await;
147 let response = mbox.ble_subsystem.read().await.unwrap();
148 info!("{}", response); 138 info!("{}", response);
149 139
150 info!("delete conn interval ad type..."); 140 info!("delete conn interval ad type...");
151 mbox.ble_subsystem 141 ble.delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
152 .delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
153 .await; 142 .await;
154 let response = mbox.ble_subsystem.read().await.unwrap(); 143 let response = ble.read().await.unwrap();
155 info!("{}", response); 144 info!("{}", response);
156 145
157 info!("update advertising data..."); 146 info!("update advertising data...");
158 mbox.ble_subsystem 147 ble.update_advertising_data(&eddystone_advertising_data())
159 .update_advertising_data(&eddystone_advertising_data())
160 .await 148 .await
161 .unwrap(); 149 .unwrap();
162 let response = mbox.ble_subsystem.read().await.unwrap(); 150 let response = ble.read().await.unwrap();
163 info!("{}", response); 151 info!("{}", response);
164 152
165 info!("update advertising data type..."); 153 info!("update advertising data type...");
166 mbox.ble_subsystem 154 ble.update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
167 .update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
168 .await 155 .await
169 .unwrap(); 156 .unwrap();
170 let response = mbox.ble_subsystem.read().await.unwrap(); 157 let response = ble.read().await.unwrap();
171 info!("{}", response); 158 info!("{}", response);
172 159
173 info!("update advertising data flags..."); 160 info!("update advertising data flags...");
174 mbox.ble_subsystem 161 ble.update_advertising_data(&[
175 .update_advertising_data(&[ 162 2,
176 2, 163 AdvertisingDataType::Flags as u8,
177 AdvertisingDataType::Flags as u8, 164 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support
178 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support 165 ])
179 ]) 166 .await
180 .await 167 .unwrap();
181 .unwrap(); 168 let response = ble.read().await.unwrap();
182 let response = mbox.ble_subsystem.read().await.unwrap();
183 info!("{}", response); 169 info!("{}", response);
184 170
185 info!("Test OK"); 171 info!("Test OK");
diff --git a/tests/stm32/src/bin/wpan_mac.rs b/tests/stm32/src/bin/wpan_mac.rs
index f27146c44..42db39e7e 100644
--- a/tests/stm32/src/bin/wpan_mac.rs
+++ b/tests/stm32/src/bin/wpan_mac.rs
@@ -25,7 +25,7 @@ bind_interrupts!(struct Irqs{
25}); 25});
26 26
27#[embassy_executor::task] 27#[embassy_executor::task]
28async fn run_mm_queue(memory_manager: mm::MemoryManager) { 28async fn run_mm_queue(mut memory_manager: mm::MemoryManager<'static>) {
29 memory_manager.run_queue().await; 29 memory_manager.run_queue().await;
30} 30}
31 31
@@ -38,20 +38,17 @@ async fn main(spawner: Spawner) {
38 info!("Hello World!"); 38 info!("Hello World!");
39 39
40 let config = Config::default(); 40 let config = Config::default();
41 let mbox = TlMbox::init(p.IPCC, Irqs, config); 41 let mbox = TlMbox::init(p.IPCC, Irqs, config).await;
42 let mut sys = mbox.sys_subsystem;
43 let (mut mac_rx, mut mac_tx) = mbox.mac_subsystem.split();
42 44
43 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap()); 45 spawner.spawn(run_mm_queue(mbox.mm_subsystem).unwrap());
44 46
45 let sys_event = mbox.sys_subsystem.read().await; 47 let result = sys.shci_c2_mac_802_15_4_init().await;
46 info!("sys event: {}", sys_event.payload());
47
48 core::mem::drop(sys_event);
49
50 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
51 info!("initialized mac: {}", result); 48 info!("initialized mac: {}", result);
52 49
53 info!("resetting"); 50 info!("resetting");
54 mbox.mac_subsystem 51 mac_tx
55 .send_command(&ResetRequest { 52 .send_command(&ResetRequest {
56 set_default_pib: true, 53 set_default_pib: true,
57 ..Default::default() 54 ..Default::default()
@@ -59,13 +56,13 @@ async fn main(spawner: Spawner) {
59 .await 56 .await
60 .unwrap(); 57 .unwrap();
61 { 58 {
62 let evt = mbox.mac_subsystem.read().await.unwrap(); 59 let evt = mac_rx.read().await.unwrap();
63 info!("{:#x}", evt); 60 info!("{:#x}", evt);
64 } 61 }
65 62
66 info!("setting extended address"); 63 info!("setting extended address");
67 let extended_address: u64 = 0xACDE480000000002; 64 let extended_address: u64 = 0xACDE480000000002;
68 mbox.mac_subsystem 65 mac_tx
69 .send_command(&SetRequest { 66 .send_command(&SetRequest {
70 pib_attribute_ptr: &extended_address as *const _ as *const u8, 67 pib_attribute_ptr: &extended_address as *const _ as *const u8,
71 pib_attribute: PibId::ExtendedAddress, 68 pib_attribute: PibId::ExtendedAddress,
@@ -73,12 +70,12 @@ async fn main(spawner: Spawner) {
73 .await 70 .await
74 .unwrap(); 71 .unwrap();
75 { 72 {
76 let evt = mbox.mac_subsystem.read().await.unwrap(); 73 let evt = mac_rx.read().await.unwrap();
77 info!("{:#x}", evt); 74 info!("{:#x}", evt);
78 } 75 }
79 76
80 info!("getting extended address"); 77 info!("getting extended address");
81 mbox.mac_subsystem 78 mac_tx
82 .send_command(&GetRequest { 79 .send_command(&GetRequest {
83 pib_attribute: PibId::ExtendedAddress, 80 pib_attribute: PibId::ExtendedAddress,
84 ..Default::default() 81 ..Default::default()
@@ -87,7 +84,7 @@ async fn main(spawner: Spawner) {
87 .unwrap(); 84 .unwrap();
88 85
89 { 86 {
90 let evt = mbox.mac_subsystem.read().await.unwrap(); 87 let evt = mac_rx.read().await.unwrap();
91 info!("{:#x}", evt); 88 info!("{:#x}", evt);
92 89
93 if let MacEvent::MlmeGetCnf(evt) = evt { 90 if let MacEvent::MlmeGetCnf(evt) = evt {
@@ -113,8 +110,8 @@ async fn main(spawner: Spawner) {
113 key_index: 152, 110 key_index: 152,
114 }; 111 };
115 info!("{}", a); 112 info!("{}", a);
116 mbox.mac_subsystem.send_command(&a).await.unwrap(); 113 mac_tx.send_command(&a).await.unwrap();
117 let short_addr = if let MacEvent::MlmeAssociateCnf(conf) = mbox.mac_subsystem.read().await.unwrap() { 114 let short_addr = if let MacEvent::MlmeAssociateCnf(conf) = mac_rx.read().await.unwrap() {
118 conf.assoc_short_address 115 conf.assoc_short_address
119 } else { 116 } else {
120 defmt::panic!() 117 defmt::panic!()