aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan
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 /embassy-stm32-wpan
parent54a153a9a24a58a7cfa1210f78f61beb913baf2d (diff)
wpan: restructure ipcc and hil test wpan_mac
Diffstat (limited to 'embassy-stm32-wpan')
-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
13 files changed, 348 insertions, 282 deletions
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());