aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/Cargo.toml10
-rw-r--r--embassy-stm32/src/tl_mbox/ble.rs23
-rw-r--r--embassy-stm32/src/tl_mbox/channels.rs144
-rw-r--r--embassy-stm32/src/tl_mbox/mac_802_15_4.rs82
-rw-r--r--embassy-stm32/src/tl_mbox/mm.rs12
-rw-r--r--embassy-stm32/src/tl_mbox/mod.rs115
-rw-r--r--embassy-stm32/src/tl_mbox/shci.rs4
-rw-r--r--embassy-stm32/src/tl_mbox/sys.rs16
8 files changed, 305 insertions, 101 deletions
diff --git a/embassy-stm32/Cargo.toml b/embassy-stm32/Cargo.toml
index 21adb5ddf..c2b0a3ec2 100644
--- a/embassy-stm32/Cargo.toml
+++ b/embassy-stm32/Cargo.toml
@@ -110,6 +110,16 @@ unstable-pac = []
110# Implement embedded-hal-async traits if `nightly` is set as well. 110# Implement embedded-hal-async traits if `nightly` is set as well.
111unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"] 111unstable-traits = ["embedded-hal-1", "dep:embedded-hal-nb"]
112 112
113# stm32wb specific
114# support for wireless stacks
115ble = []
116thread = []
117lld-tests = []
118ble-lld = []
119mac-802_15_4 = []
120zigbee = []
121traces = []
122
113# Chip-selection features 123# Chip-selection features
114stm32c011d6 = [ "stm32-metapac/stm32c011d6" ] 124stm32c011d6 = [ "stm32-metapac/stm32c011d6" ]
115stm32c011f4 = [ "stm32-metapac/stm32c011f4" ] 125stm32c011f4 = [ "stm32-metapac/stm32c011f4" ]
diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs
index d8bf14d4f..21688ff49 100644
--- a/embassy-stm32/src/tl_mbox/ble.rs
+++ b/embassy-stm32/src/tl_mbox/ble.rs
@@ -16,7 +16,7 @@ use crate::tl_mbox::cmd::CmdPacket;
16pub struct Ble; 16pub struct Ble;
17 17
18impl Ble { 18impl Ble {
19 pub(crate) fn new(ipcc: &mut Ipcc) -> Self { 19 pub(crate) fn init(ipcc: &mut Ipcc) -> Self {
20 unsafe { 20 unsafe {
21 LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); 21 LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
22 22
@@ -28,7 +28,7 @@ impl Ble {
28 }); 28 });
29 } 29 }
30 30
31 ipcc.c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); 31 ipcc.c1_set_rx_channel(channels::Cpu2Channel::BleEvent.into(), true);
32 32
33 Ble 33 Ble
34 } 34 }
@@ -48,7 +48,11 @@ impl Ble {
48 } 48 }
49 } 49 }
50 50
51 ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); 51 ipcc.c1_clear_flag_channel(channels::Cpu2Channel::BleEvent.into());
52 }
53
54 pub(crate) fn acl_data_evt_handler(ipcc: &mut Ipcc) {
55 ipcc.c1_set_tx_channel(channels::Cpu1Channel::HciAclData.into(), false);
52 } 56 }
53 57
54 pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { 58 pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) {
@@ -63,6 +67,17 @@ impl Ble {
63 cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8; 67 cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8;
64 } 68 }
65 69
66 ipcc.c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL); 70 ipcc.c1_set_flag_channel(channels::Cpu1Channel::BleCmd.into());
71 }
72
73 pub(crate) fn send_acl_data(ipcc: &mut Ipcc) {
74 unsafe {
75 (*(*TL_REF_TABLE.assume_init().ble_table).phci_acl_data_buffer)
76 .acl_data_serial
77 .ty = TlPacketType::AclData as u8;
78 }
79
80 ipcc.c1_set_flag_channel(channels::Cpu1Channel::HciAclData.into());
81 ipcc.c1_set_tx_channel(channels::Cpu1Channel::HciAclData.into(), true);
67 } 82 }
68} 83}
diff --git a/embassy-stm32/src/tl_mbox/channels.rs b/embassy-stm32/src/tl_mbox/channels.rs
index aaa6ce177..94e97230f 100644
--- a/embassy-stm32/src/tl_mbox/channels.rs
+++ b/embassy-stm32/src/tl_mbox/channels.rs
@@ -49,56 +49,104 @@
49//! | | 49//! | |
50//! 50//!
51 51
52pub mod cpu1 { 52use crate::ipcc::IpccChannel;
53 use crate::ipcc::IpccChannel;
54 53
55 // Not used currently but reserved 54pub enum Cpu1Channel {
56 pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; 55 BleCmd,
57 // Not used currently but reserved 56 SystemCmdRsp,
58 pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2; 57 #[cfg(feature = "thread")]
59 #[allow(dead_code)] // Not used currently but reserved 58 ThreadOtCmdRsp,
60 pub const IPCC_THREAD_OT_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; 59 #[cfg(feature = "zigbee")]
61 #[allow(dead_code)] // Not used currently but reserved 60 ZigbeeCmdAppli,
62 pub const IPCC_ZIGBEE_CMD_APPLI_CHANNEL: IpccChannel = IpccChannel::Channel3; 61 MmReleaseBuffer,
63 #[allow(dead_code)] // Not used currently but reserved 62 #[cfg(feature = "mac-802_15_4")]
64 pub const IPCC_MAC_802_15_4_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; 63 Mac802_15_4cmdRsp,
65 // Not used currently but reserved 64 #[cfg(feature = "thread")]
66 pub const IPCC_MM_RELEASE_BUFFER_CHANNEL: IpccChannel = IpccChannel::Channel4; 65 ThreadCliCmd,
67 #[allow(dead_code)] // Not used currently but reserved 66 #[cfg(feature = "lld-tests")]
68 pub const IPCC_THREAD_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; 67 LldTestsCliCmd,
69 #[allow(dead_code)] // Not used currently but reserved 68 #[cfg(feature = "ble-lld")]
70 pub const IPCC_LLDTESTS_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; 69 BleLldCmd,
71 #[allow(dead_code)] // Not used currently but reserved 70 HciAclData,
72 pub const IPCC_BLE_LLD_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5;
73 #[allow(dead_code)] // Not used currently but reserved
74 pub const IPCC_HCI_ACL_DATA_CHANNEL: IpccChannel = IpccChannel::Channel6;
75} 71}
76 72
77pub mod cpu2 { 73impl From<Cpu1Channel> for IpccChannel {
78 use crate::ipcc::IpccChannel; 74 fn from(value: Cpu1Channel) -> Self {
75 match value {
76 Cpu1Channel::BleCmd => IpccChannel::Channel1,
77 Cpu1Channel::SystemCmdRsp => IpccChannel::Channel2,
78 #[cfg(feature = "thread")]
79 Cpu1Channel::ThreadOtCmdRsp => IpccChannel::Channel3,
80 #[cfg(feature = "zigbee")]
81 Cpu1Channel::ZigbeeCmdAppli => IpccChannel::Channel3,
82 #[cfg(feature = "mac-802_15_4")]
83 Cpu1Channel::Mac802_15_4cmdRsp => IpccChannel::Channel3,
84 Cpu1Channel::MmReleaseBuffer => IpccChannel::Channel4,
85 #[cfg(feature = "thread")]
86 Cpu1Channel::ThreadCliCmd => IpccChannel::Channel5,
87 #[cfg(feature = "lld-tests")]
88 Cpu1Channel::LldTestsCliCmd => IpccChannel::Channel5,
89 #[cfg(feature = "ble-lld")]
90 Cpu1Channel::BleLldCmd => IpccChannel::Channel5,
91 Cpu1Channel::HciAclData => IpccChannel::Channel6,
92 }
93 }
94}
95
96pub enum Cpu2Channel {
97 BleEvent,
98 SystemEvent,
99 #[cfg(feature = "thread")]
100 ThreadNotifAck,
101 #[cfg(feature = "zigbee")]
102 ZigbeeAppliNotifAck,
103 #[cfg(feature = "mac-802_15_4")]
104 Mac802_15_4NotifAck,
105 #[cfg(feature = "lld-tests")]
106 LldTestsM0Cmd,
107 #[cfg(feature = "ble-lld")]
108 BleLldM0Cmd,
109 #[cfg(feature = "traces")]
110 Traces,
111 #[cfg(feature = "thread")]
112 ThreadCliNotifAck,
113 #[cfg(feature = "lld-tests")]
114 LldTestsCliRsp,
115 #[cfg(feature = "ble-lld")]
116 BleLldCliRsp,
117 #[cfg(feature = "ble-lld")]
118 BleLldRsp,
119 #[cfg(feature = "zigbee")]
120 ZigbeeM0Request,
121}
79 122
80 pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; 123impl From<Cpu2Channel> for IpccChannel {
81 pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; 124 fn from(value: Cpu2Channel) -> Self {
82 #[allow(dead_code)] // Not used currently but reserved 125 match value {
83 pub const IPCC_THREAD_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; 126 Cpu2Channel::BleEvent => IpccChannel::Channel1,
84 #[allow(dead_code)] // Not used currently but reserved 127 Cpu2Channel::SystemEvent => IpccChannel::Channel2,
85 pub const IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; 128 #[cfg(feature = "thread")]
86 #[allow(dead_code)] // Not used currently but reserved 129 Cpu2Channel::ThreadNotifAck => IpccChannel::Channel3,
87 pub const IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; 130 #[cfg(feature = "zigbee")]
88 #[allow(dead_code)] // Not used currently but reserved 131 Cpu2Channel::ZigbeeAppliNotifAck => IpccChannel::Channel3,
89 pub const IPCC_LDDTESTS_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; 132 #[cfg(feature = "mac-802_15_4")]
90 #[allow(dead_code)] // Not used currently but reserved 133 Cpu2Channel::Mac802_15_4NotifAck => IpccChannel::Channel3,
91 pub const IPCC_BLE_LLD_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; 134 #[cfg(feature = "lld-tests")]
92 #[allow(dead_code)] // Not used currently but reserved 135 Cpu2Channel::LldTestsM0Cmd => IpccChannel::Channel3,
93 pub const IPCC_TRACES_CHANNEL: IpccChannel = IpccChannel::Channel4; 136 #[cfg(feature = "ble-lld")]
94 #[allow(dead_code)] // Not used currently but reserved 137 Cpu2Channel::BleLldM0Cmd => IpccChannel::Channel3,
95 pub const IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel5; 138 #[cfg(feature = "traces")]
96 #[allow(dead_code)] // Not used currently but reserved 139 Cpu2Channel::Traces => IpccChannel::Channel4,
97 pub const IPCC_LLDTESTS_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; 140 #[cfg(feature = "thread")]
98 #[allow(dead_code)] // Not used currently but reserved 141 Cpu2Channel::ThreadCliNotifAck => IpccChannel::Channel5,
99 pub const IPCC_BLE_LLD_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; 142 #[cfg(feature = "lld-tests")]
100 #[allow(dead_code)] // Not used currently but reserved 143 Cpu2Channel::LldTestsCliRsp => IpccChannel::Channel5,
101 pub const IPCC_BLE_LLD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; 144 #[cfg(feature = "ble-lld")]
102 #[allow(dead_code)] // Not used currently but reserved 145 Cpu2Channel::BleLldCliRsp => IpccChannel::Channel5,
103 pub const IPCC_ZIGBEE_M0_REQUEST_CHANNEL: IpccChannel = IpccChannel::Channel5; 146 #[cfg(feature = "ble-lld")]
147 Cpu2Channel::BleLldRsp => IpccChannel::Channel5,
148 #[cfg(feature = "zigbee")]
149 Cpu2Channel::ZigbeeM0Request => IpccChannel::Channel5,
150 }
151 }
104} 152}
diff --git a/embassy-stm32/src/tl_mbox/mac_802_15_4.rs b/embassy-stm32/src/tl_mbox/mac_802_15_4.rs
new file mode 100644
index 000000000..19f951130
--- /dev/null
+++ b/embassy-stm32/src/tl_mbox/mac_802_15_4.rs
@@ -0,0 +1,82 @@
1use core::mem::MaybeUninit;
2
3use embassy_futures::block_on;
4
5use super::cmd::{CmdPacket, CmdSerial};
6use super::consts::TlPacketType;
7use super::evt::{EvtBox, EvtPacket};
8use super::unsafe_linked_list::LinkedListNode;
9use super::{
10 channels, Mac802_15_4Table, EVT_QUEUE, MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, TL_CHANNEL,
11 TL_MAC_802_15_4_TABLE, TL_REF_TABLE,
12};
13use crate::ipcc::Ipcc;
14
15pub struct Mac802_15_4;
16
17impl Mac802_15_4 {
18 pub(crate) fn init(ipcc: &mut Ipcc) -> Self {
19 unsafe {
20 LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
21
22 TL_MAC_802_15_4_TABLE = MaybeUninit::new(Mac802_15_4Table {
23 pcmd_rsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(),
24 pnotack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(),
25 evt_queue: EVT_QUEUE.as_ptr().cast(),
26 });
27 }
28
29 ipcc.c1_set_rx_channel(channels::Cpu2Channel::Mac802_15_4NotifAck.into(), true);
30
31 Self
32 }
33
34 pub(crate) fn notif_evt_handler(ipcc: &mut Ipcc) {
35 unsafe {
36 let notif_buffer: *mut EvtPacket = (*TL_REF_TABLE.assume_init().mac_802_15_4_table).pnotack_buffer.cast();
37 let event = EvtBox::new(notif_buffer);
38
39 block_on(TL_CHANNEL.send(event));
40 }
41
42 ipcc.c1_set_rx_channel(channels::Cpu2Channel::Mac802_15_4NotifAck.into(), false);
43 }
44
45 pub(crate) fn cmd_evt_handler(ipcc: &mut Ipcc) {
46 unsafe {
47 let _notif_buffer = (*TL_REF_TABLE.assume_init().mac_802_15_4_table).pcmd_rsp_buffer;
48
49 // NOTE: ST's HAL does nothing with this buffer, ??????
50 }
51
52 ipcc.c1_set_tx_channel(channels::Cpu1Channel::Mac802_15_4cmdRsp.into(), false);
53 }
54
55 pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) {
56 unsafe {
57 let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().mac_802_15_4_table).pcmd_rsp_buffer.cast();
58 let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial;
59 let pcmd_serial_buf: *mut u8 = pcmd_serial.cast();
60
61 core::ptr::copy(buf.as_ptr(), pcmd_serial_buf, buf.len());
62
63 let cmd_packet: &mut CmdPacket =
64 &mut *(*TL_REF_TABLE.assume_init().mac_802_15_4_table).pcmd_rsp_buffer.cast();
65 cmd_packet.cmd_serial.ty = TlPacketType::OtCmd as u8;
66 }
67
68 ipcc.c1_set_flag_channel(channels::Cpu1Channel::Mac802_15_4cmdRsp.into());
69 ipcc.c1_set_tx_channel(channels::Cpu1Channel::Mac802_15_4cmdRsp.into(), true);
70 }
71
72 pub(crate) fn send_ack(ipcc: &mut Ipcc) {
73 // TODO
74 unsafe {
75 let packet: &mut CmdPacket = &mut *(*TL_REF_TABLE.assume_init().mac_802_15_4_table).pnotack_buffer.cast();
76 packet.cmd_serial.ty = TlPacketType::OtAck as u8;
77 }
78
79 ipcc.c1_clear_flag_channel(channels::Cpu2Channel::Mac802_15_4NotifAck.into());
80 ipcc.c1_set_rx_channel(channels::Cpu2Channel::Mac802_15_4NotifAck.into(), true);
81 }
82}
diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs
index f99ffa399..5dec397e4 100644
--- a/embassy-stm32/src/tl_mbox/mm.rs
+++ b/embassy-stm32/src/tl_mbox/mm.rs
@@ -11,7 +11,7 @@ use crate::ipcc::Ipcc;
11pub struct MemoryManager; 11pub struct MemoryManager;
12 12
13impl MemoryManager { 13impl MemoryManager {
14 pub fn new() -> Self { 14 pub fn init() -> Self {
15 unsafe { 15 unsafe {
16 LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr()); 16 LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr());
17 LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); 17 LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr());
@@ -31,9 +31,9 @@ impl MemoryManager {
31 } 31 }
32 32
33 pub fn evt_handler(ipcc: &mut Ipcc) { 33 pub fn evt_handler(ipcc: &mut Ipcc) {
34 ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, false); 34 ipcc.c1_set_tx_channel(channels::Cpu1Channel::MmReleaseBuffer.into(), false);
35 Self::send_free_buf(); 35 Self::send_free_buf();
36 ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); 36 ipcc.c1_set_flag_channel(channels::Cpu1Channel::MmReleaseBuffer.into());
37 } 37 }
38 38
39 pub fn evt_drop(evt: *mut EvtPacket, ipcc: &mut Ipcc) { 39 pub fn evt_drop(evt: *mut EvtPacket, ipcc: &mut Ipcc) {
@@ -43,14 +43,14 @@ impl MemoryManager {
43 LinkedListNode::remove_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); 43 LinkedListNode::remove_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node);
44 } 44 }
45 45
46 let channel_is_busy = ipcc.c1_is_active_flag(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); 46 let channel_is_busy = ipcc.c1_is_active_flag(channels::Cpu1Channel::MmReleaseBuffer.into());
47 47
48 // postpone event buffer freeing to IPCC interrupt handler 48 // postpone event buffer freeing to IPCC interrupt handler
49 if channel_is_busy { 49 if channel_is_busy {
50 ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, true); 50 ipcc.c1_set_tx_channel(channels::Cpu1Channel::MmReleaseBuffer.into(), true);
51 } else { 51 } else {
52 Self::send_free_buf(); 52 Self::send_free_buf();
53 ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); 53 ipcc.c1_set_flag_channel(channels::Cpu1Channel::MmReleaseBuffer.into());
54 } 54 }
55 } 55 }
56 56
diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs
index dc6104cc3..b2d3a27e1 100644
--- a/embassy-stm32/src/tl_mbox/mod.rs
+++ b/embassy-stm32/src/tl_mbox/mod.rs
@@ -4,9 +4,12 @@ use bit_field::BitField;
4use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; 4use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
5use embassy_sync::channel::Channel; 5use embassy_sync::channel::Channel;
6 6
7#[cfg(feature = "ble")]
7use self::ble::Ble; 8use self::ble::Ble;
8use self::cmd::{AclDataPacket, CmdPacket}; 9use self::cmd::{AclDataPacket, CmdPacket};
9use self::evt::{CsEvt, EvtBox}; 10use self::evt::{CsEvt, EvtBox};
11#[cfg(feature = "mac-802_15_4")]
12use self::mac_802_15_4::Mac802_15_4;
10use self::mm::MemoryManager; 13use self::mm::MemoryManager;
11use self::shci::{shci_ble_init, ShciBleInitCmdParam}; 14use self::shci::{shci_ble_init, ShciBleInitCmdParam};
12use self::sys::Sys; 15use self::sys::Sys;
@@ -14,7 +17,6 @@ use self::unsafe_linked_list::LinkedListNode;
14use crate::interrupt; 17use crate::interrupt;
15use crate::ipcc::Ipcc; 18use crate::ipcc::Ipcc;
16 19
17mod ble;
18mod channels; 20mod channels;
19mod cmd; 21mod cmd;
20mod consts; 22mod consts;
@@ -24,6 +26,11 @@ mod shci;
24mod sys; 26mod sys;
25mod unsafe_linked_list; 27mod unsafe_linked_list;
26 28
29#[cfg(feature = "ble")]
30mod ble;
31#[cfg(feature = "mac-802_15_4")]
32mod mac_802_15_4;
33
27pub type PacketHeader = LinkedListNode; 34pub type PacketHeader = LinkedListNode;
28 35
29const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::<PacketHeader>(); 36const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::<PacketHeader>();
@@ -194,8 +201,8 @@ struct TracesTable {
194 201
195#[repr(C, packed)] 202#[repr(C, packed)]
196struct Mac802_15_4Table { 203struct Mac802_15_4Table {
197 pcmd_rsp_buffer: *const u8, 204 pcmd_rsp_buffer: *mut u8,
198 pnotack_buffer: *const u8, 205 pnotack_buffer: *mut u8,
199 evt_queue: *const u8, 206 evt_queue: *const u8,
200} 207}
201 208
@@ -215,6 +222,7 @@ pub struct RefTable {
215 ble_lld_table: *const BleLldTable, 222 ble_lld_table: *const BleLldTable,
216} 223}
217 224
225// -------------------- reference table --------------------
218#[link_section = "TL_REF_TABLE"] 226#[link_section = "TL_REF_TABLE"]
219pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit(); 227pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit();
220 228
@@ -248,38 +256,50 @@ static mut TL_MAC_802_15_4_TABLE: MaybeUninit<Mac802_15_4Table> = MaybeUninit::u
248#[link_section = "MB_MEM1"] 256#[link_section = "MB_MEM1"]
249static mut TL_ZIGBEE_TABLE: MaybeUninit<ZigbeeTable> = MaybeUninit::uninit(); 257static mut TL_ZIGBEE_TABLE: MaybeUninit<ZigbeeTable> = MaybeUninit::uninit();
250 258
251#[allow(dead_code)] // Not used currently but reserved 259// -------------------- tables --------------------
252#[link_section = "MB_MEM1"] 260#[link_section = "MB_MEM1"]
253static mut FREE_BUFF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); 261static mut FREE_BUFF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
254 262
255// not in shared RAM
256static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
257
258#[link_section = "MB_MEM2"] 263#[link_section = "MB_MEM2"]
259static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = 264static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> =
260 MaybeUninit::uninit(); 265 MaybeUninit::uninit();
261 266
262#[link_section = "MB_MEM2"] 267#[link_section = "MB_MEM1"]
263static mut EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); 268static mut EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
264 269
265#[link_section = "MB_MEM2"] 270#[link_section = "MB_MEM2"]
266static mut SYSTEM_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); 271static mut SYSTEM_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
267 272
268#[link_section = "MB_MEM2"] 273// not in shared RAM
269static mut SYS_CMD_BUF: MaybeUninit<CmdPacket> = MaybeUninit::uninit(); 274static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
270 275
276// -------------------- app tables --------------------
271#[link_section = "MB_MEM2"] 277#[link_section = "MB_MEM2"]
272static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); 278static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit();
273 279
274#[link_section = "MB_MEM2"] 280#[link_section = "MB_MEM2"]
281static mut SYS_CMD_BUF: MaybeUninit<CmdPacket> = MaybeUninit::uninit();
282
283#[link_section = "MB_MEM2"]
275static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = 284static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> =
276 MaybeUninit::uninit(); 285 MaybeUninit::uninit();
277 286
287#[cfg(feature = "mac-802_15_4")]
278#[link_section = "MB_MEM2"] 288#[link_section = "MB_MEM2"]
279static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = 289static mut MAC_802_15_4_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit();
290
291#[cfg(feature = "mac-802_15_4")]
292#[link_section = "MB_MEM2"]
293static mut MAC_802_15_4_NOTIF_RSP_EVT_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> =
280 MaybeUninit::uninit(); 294 MaybeUninit::uninit();
281 295
296#[cfg(feature = "ble")]
282#[link_section = "MB_MEM2"] 297#[link_section = "MB_MEM2"]
298static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> =
299 MaybeUninit::uninit();
300
301#[cfg(feature = "ble")]
302#[link_section = "MB_MEM1"]
283static mut BLE_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit(); 303static mut BLE_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit();
284 304
285#[link_section = "MB_MEM2"] 305#[link_section = "MB_MEM2"]
@@ -289,10 +309,14 @@ static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251
289// TODO: get a better size, this is a placeholder 309// TODO: get a better size, this is a placeholder
290pub(crate) static TL_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 5> = Channel::new(); 310pub(crate) static TL_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 5> = Channel::new();
291 311
292pub struct TlMbox { 312pub struct TlMbox;
293 _sys: Sys, 313
294 _ble: Ble, 314pub enum MailboxTarget {
295 _mm: MemoryManager, 315 Sys,
316 #[cfg(feature = "ble")]
317 Ble,
318 #[cfg(feature = "mac-802_15_4")]
319 Mac802_15_4,
296} 320}
297 321
298impl TlMbox { 322impl TlMbox {
@@ -338,9 +362,14 @@ impl TlMbox {
338 362
339 ipcc.init(); 363 ipcc.init();
340 364
341 let _sys = Sys::new(ipcc); 365 Sys::init(ipcc);
342 let _ble = Ble::new(ipcc); 366 MemoryManager::init();
343 let _mm = MemoryManager::new(); 367
368 #[cfg(feature = "ble")]
369 Ble::init(ipcc);
370
371 #[cfg(feature = "mac-802_15_4")]
372 Mac802_15_4::init(ipcc);
344 373
345 // rx_irq.disable(); 374 // rx_irq.disable();
346 // tx_irq.disable(); 375 // tx_irq.disable();
@@ -360,7 +389,7 @@ impl TlMbox {
360 // rx_irq.enable(); 389 // rx_irq.enable();
361 // tx_irq.enable(); 390 // tx_irq.enable();
362 391
363 TlMbox { _sys, _ble, _mm } 392 Self
364 } 393 }
365 394
366 pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> { 395 pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {
@@ -374,17 +403,30 @@ impl TlMbox {
374 } 403 }
375 } 404 }
376 405
406 #[cfg(feature = "ble")]
377 pub fn shci_ble_init(&self, ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { 407 pub fn shci_ble_init(&self, ipcc: &mut Ipcc, param: ShciBleInitCmdParam) {
378 shci_ble_init(ipcc, param); 408 shci_ble_init(ipcc, param);
379 } 409 }
380 410
381 pub fn send_ble_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { 411 pub fn send_cmd(&self, ipcc: &mut Ipcc, buf: &[u8], target: MailboxTarget) {
382 ble::Ble::send_cmd(ipcc, buf); 412 match target {
413 MailboxTarget::Sys => Sys::send_cmd(ipcc, buf),
414 #[cfg(feature = "ble")]
415 MailboxTarget::Ble => Ble::send_cmd(ipcc, buf),
416 #[cfg(feature = "mac-802_15_4")]
417 MailboxTarget::Mac802_15_4 => Mac802_15_4::send_cmd(ipcc, buf),
418 }
383 } 419 }
384 420
385 // pub fn send_sys_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { 421 pub fn send_ack(&self, ipcc: &mut Ipcc, target: MailboxTarget) {
386 // sys::Sys::send_cmd(ipcc, buf); 422 match target {
387 // } 423 #[cfg(feature = "ble")]
424 MailboxTarget::Ble => Ble::send_acl_data(ipcc),
425 #[cfg(feature = "mac-802_15_4")]
426 MailboxTarget::Mac802_15_4 => Mac802_15_4::send_ack(ipcc),
427 MailboxTarget::Sys => { /* does nothing */ }
428 }
429 }
388 430
389 pub async fn read(&self) -> EvtBox { 431 pub async fn read(&self) -> EvtBox {
390 TL_CHANNEL.recv().await 432 TL_CHANNEL.recv().await
@@ -392,10 +434,14 @@ impl TlMbox {
392 434
393 #[allow(dead_code)] 435 #[allow(dead_code)]
394 fn interrupt_ipcc_rx_handler(ipcc: &mut Ipcc) { 436 fn interrupt_ipcc_rx_handler(ipcc: &mut Ipcc) {
395 if ipcc.is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { 437 if ipcc.is_rx_pending(channels::Cpu2Channel::SystemEvent.into()) {
396 sys::Sys::evt_handler(ipcc); 438 Sys::evt_handler(ipcc);
397 } else if ipcc.is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { 439 } else if cfg!(feature = "ble") && ipcc.is_rx_pending(channels::Cpu2Channel::BleEvent.into()) {
398 ble::Ble::evt_handler(ipcc); 440 Ble::evt_handler(ipcc);
441 } else if cfg!(feature = "mac-802_15_4")
442 && ipcc.is_rx_pending(channels::Cpu2Channel::Mac802_15_4NotifAck.into())
443 {
444 Mac802_15_4::notif_evt_handler(ipcc);
399 } else { 445 } else {
400 todo!() 446 todo!()
401 } 447 }
@@ -403,11 +449,16 @@ impl TlMbox {
403 449
404 #[allow(dead_code)] 450 #[allow(dead_code)]
405 fn interrupt_ipcc_tx_handler(ipcc: &mut Ipcc) { 451 fn interrupt_ipcc_tx_handler(ipcc: &mut Ipcc) {
406 if ipcc.is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { 452 if ipcc.is_tx_pending(channels::Cpu1Channel::SystemCmdRsp.into()) {
407 // TODO: handle this case 453 // TODO: handle this case
408 let _ = sys::Sys::cmd_evt_handler(ipcc); 454 let _ = Sys::cmd_evt_handler(ipcc);
409 } else if ipcc.is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { 455 } else if ipcc.is_tx_pending(channels::Cpu1Channel::MmReleaseBuffer.into()) {
410 mm::MemoryManager::evt_handler(ipcc); 456 MemoryManager::evt_handler(ipcc);
457 } else if cfg!(feature = "ble") && ipcc.is_tx_pending(channels::Cpu1Channel::HciAclData.into()) {
458 Ble::acl_data_evt_handler(ipcc);
459 } else if cfg!(feature = "mac-802_15_4") && ipcc.is_tx_pending(channels::Cpu1Channel::Mac802_15_4cmdRsp.into())
460 {
461 Mac802_15_4::cmd_evt_handler(ipcc)
411 } else { 462 } else {
412 todo!() 463 todo!()
413 } 464 }
diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32/src/tl_mbox/shci.rs
index 61fd9e4a3..53f0882b7 100644
--- a/embassy-stm32/src/tl_mbox/shci.rs
+++ b/embassy-stm32/src/tl_mbox/shci.rs
@@ -95,7 +95,7 @@ pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) {
95 95
96 cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8; 96 cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8;
97 97
98 ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); 98 ipcc.c1_set_flag_channel(channels::Cpu1Channel::SystemCmdRsp.into());
99 ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); 99 ipcc.c1_set_tx_channel(channels::Cpu1Channel::SystemCmdRsp.into(), true);
100 } 100 }
101} 101}
diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs
index 31ebde721..1dc43bfee 100644
--- a/embassy-stm32/src/tl_mbox/sys.rs
+++ b/embassy-stm32/src/tl_mbox/sys.rs
@@ -12,7 +12,7 @@ use crate::ipcc::Ipcc;
12pub struct Sys; 12pub struct Sys;
13 13
14impl Sys { 14impl Sys {
15 pub(crate) fn new(ipcc: &mut Ipcc) -> Self { 15 pub(crate) fn init(ipcc: &mut Ipcc) -> Self {
16 unsafe { 16 unsafe {
17 LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); 17 LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
18 18
@@ -22,7 +22,7 @@ impl Sys {
22 }); 22 });
23 } 23 }
24 24
25 ipcc.c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); 25 ipcc.c1_set_rx_channel(channels::Cpu2Channel::SystemEvent.into(), true);
26 26
27 Sys 27 Sys
28 } 28 }
@@ -43,11 +43,11 @@ impl Sys {
43 } 43 }
44 } 44 }
45 45
46 ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); 46 ipcc.c1_clear_flag_channel(channels::Cpu2Channel::SystemEvent.into());
47 } 47 }
48 48
49 pub(crate) fn cmd_evt_handler(ipcc: &mut Ipcc) -> CcEvt { 49 pub(crate) fn cmd_evt_handler(ipcc: &mut Ipcc) -> CcEvt {
50 ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); 50 ipcc.c1_set_tx_channel(channels::Cpu1Channel::SystemCmdRsp.into(), false);
51 51
52 // ST's command response data structure is really convoluted. 52 // ST's command response data structure is really convoluted.
53 // 53 //
@@ -67,12 +67,10 @@ impl Sys {
67 } 67 }
68 } 68 }
69 69
70 #[allow(dead_code)]
71 pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { 70 pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) {
72 unsafe { 71 unsafe {
73 // TODO: check this
74 let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; 72 let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer;
75 let cmd_serial: *mut CmdSerial = &mut (*cmd_buffer).cmd_serial; 73 let cmd_serial: *mut CmdSerial = &mut cmd_buffer.cmd_serial;
76 let cmd_serial_buf = cmd_serial.cast(); 74 let cmd_serial_buf = cmd_serial.cast();
77 75
78 core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len()); 76 core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len());
@@ -80,8 +78,8 @@ impl Sys {
80 let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; 78 let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer;
81 cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8; 79 cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8;
82 80
83 ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); 81 ipcc.c1_set_flag_channel(channels::Cpu1Channel::SystemCmdRsp.into());
84 ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); 82 ipcc.c1_set_tx_channel(channels::Cpu1Channel::SystemCmdRsp.into(), true);
85 } 83 }
86 } 84 }
87} 85}