aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan/src/lib.rs')
-rw-r--r--embassy-stm32-wpan/src/lib.rs186
1 files changed, 9 insertions, 177 deletions
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs
index 40ff14795..3fabe112a 100644
--- a/embassy-stm32-wpan/src/lib.rs
+++ b/embassy-stm32-wpan/src/lib.rs
@@ -13,187 +13,19 @@
13 13
14#![no_std] 14#![no_std]
15#![allow(async_fn_in_trait)] 15#![allow(async_fn_in_trait)]
16#![allow(unsafe_op_in_unsafe_fn)]
16#![doc = include_str!("../README.md")] 17#![doc = include_str!("../README.md")]
17// #![warn(missing_docs)] 18// #![warn(missing_docs)]
18#![allow(static_mut_refs)] // TODO: Fix 19#![allow(static_mut_refs)] // TODO: Fix
19 20
20// This must go FIRST so that all the other modules see its macros. 21#[cfg(feature = "wb55")]
21mod fmt; 22mod wb55;
22 23
23use core::mem::MaybeUninit; 24#[cfg(feature = "wb55")]
24use core::sync::atomic::{compiler_fence, Ordering}; 25pub use wb55::*;
25 26
26use embassy_hal_internal::Peri; 27#[cfg(feature = "wba")]
27use embassy_stm32::interrupt; 28mod wba;
28use embassy_stm32::ipcc::{Config, Ipcc, ReceiveInterruptHandler, TransmitInterruptHandler};
29use embassy_stm32::peripherals::IPCC;
30use sub::mm::MemoryManager;
31use sub::sys::Sys;
32use tables::*;
33use unsafe_linked_list::LinkedListNode;
34 29
35pub mod channels; 30#[cfg(feature = "wba")]
36pub mod cmd; 31pub use wba::*;
37pub mod consts;
38pub mod evt;
39pub mod lhci;
40pub mod shci;
41pub mod sub;
42pub mod tables;
43pub mod unsafe_linked_list;
44
45#[cfg(feature = "mac")]
46pub mod mac;
47
48#[cfg(feature = "ble")]
49pub use crate::sub::ble::hci;
50
51type PacketHeader = LinkedListNode;
52
53/// Transport Layer for the Mailbox interface
54pub struct TlMbox<'d> {
55 _ipcc: Peri<'d, IPCC>,
56
57 pub sys_subsystem: Sys,
58 pub mm_subsystem: MemoryManager,
59 #[cfg(feature = "ble")]
60 pub ble_subsystem: sub::ble::Ble,
61 #[cfg(feature = "mac")]
62 pub mac_subsystem: sub::mac::Mac,
63}
64
65impl<'d> TlMbox<'d> {
66 /// Initialise the Transport Layer, and creates and returns a wrapper around it.
67 ///
68 /// This method performs the initialisation laid out in AN5289 annex 14.1. However, it differs
69 /// from the implementation documented in Figure 64, to avoid needing to reference any C
70 /// function pointers.
71 ///
72 /// Annex 14.1 lays out the following methods that should be called:
73 /// 1. tl_mbox.c/TL_Init, which initialises the reference table that is shared between CPU1
74 /// and CPU2.
75 /// 2. shci_tl.c/shci_init(), which initialises the system transport layer, and in turn
76 /// calls tl_mbox.c/TL_SYS_Init, which initialises SYSTEM_EVT_QUEUE channel.
77 /// 3. tl_mbox.c/TL_MM_Init(), which initialises the channel used for sending memory
78 /// manager commands.
79 /// 4. tl_mbox.c/TL_Enable(), which enables the IPCC, and starts CPU2.
80 /// This implementation initialises all of the shared refernce tables and all IPCC channel that
81 /// would be initialised by this process. The developer should therefore treat this method as
82 /// completing all steps in Figure 64.
83 ///
84 /// Once this method has been called, no system commands may be sent until the CPU2 ready
85 /// signal is received, via [sys_subsystem.read]; this completes the procedure laid out in
86 /// Figure 65.
87 ///
88 /// If the `ble` feature is enabled, at this point, the user should call
89 /// [sys_subsystem.shci_c2_ble_init], before any commands are written to the
90 /// [TlMbox.ble_subsystem] ([sub::ble::Ble::new()] completes the process that would otherwise
91 /// be handled by `TL_BLE_Init`; see Figure 66). This completes the procedure laid out in
92 /// Figure 66.
93 // TODO: document what the user should do after calling init to use the mac_802_15_4 subsystem
94 pub fn init(
95 ipcc: Peri<'d, IPCC>,
96 _irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
97 + interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
98 config: Config,
99 ) -> Self {
100 // this is an inlined version of TL_Init from the STM32WB firmware as requested by AN5289.
101 // HW_IPCC_Init is not called, and its purpose is (presumably?) covered by this
102 // implementation
103 unsafe {
104 TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable {
105 device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(),
106 ble_table: TL_BLE_TABLE.as_ptr(),
107 thread_table: TL_THREAD_TABLE.as_ptr(),
108 sys_table: TL_SYS_TABLE.as_ptr(),
109 mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(),
110 traces_table: TL_TRACES_TABLE.as_ptr(),
111 mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(),
112 zigbee_table: TL_ZIGBEE_TABLE.as_ptr(),
113 lld_tests_table: TL_LLD_TESTS_TABLE.as_ptr(),
114 ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(),
115 });
116
117 TL_SYS_TABLE
118 .as_mut_ptr()
119 .write_volatile(MaybeUninit::zeroed().assume_init());
120 TL_DEVICE_INFO_TABLE
121 .as_mut_ptr()
122 .write_volatile(MaybeUninit::zeroed().assume_init());
123 TL_BLE_TABLE
124 .as_mut_ptr()
125 .write_volatile(MaybeUninit::zeroed().assume_init());
126 TL_THREAD_TABLE
127 .as_mut_ptr()
128 .write_volatile(MaybeUninit::zeroed().assume_init());
129 TL_MEM_MANAGER_TABLE
130 .as_mut_ptr()
131 .write_volatile(MaybeUninit::zeroed().assume_init());
132
133 TL_TRACES_TABLE
134 .as_mut_ptr()
135 .write_volatile(MaybeUninit::zeroed().assume_init());
136 TL_MAC_802_15_4_TABLE
137 .as_mut_ptr()
138 .write_volatile(MaybeUninit::zeroed().assume_init());
139 TL_ZIGBEE_TABLE
140 .as_mut_ptr()
141 .write_volatile(MaybeUninit::zeroed().assume_init());
142 TL_LLD_TESTS_TABLE
143 .as_mut_ptr()
144 .write_volatile(MaybeUninit::zeroed().assume_init());
145 TL_BLE_LLD_TABLE
146 .as_mut_ptr()
147 .write_volatile(MaybeUninit::zeroed().assume_init());
148
149 EVT_POOL
150 .as_mut_ptr()
151 .write_volatile(MaybeUninit::zeroed().assume_init());
152 SYS_SPARE_EVT_BUF
153 .as_mut_ptr()
154 .write_volatile(MaybeUninit::zeroed().assume_init());
155 CS_BUFFER
156 .as_mut_ptr()
157 .write_volatile(MaybeUninit::zeroed().assume_init());
158
159 #[cfg(feature = "ble")]
160 {
161 BLE_SPARE_EVT_BUF
162 .as_mut_ptr()
163 .write_volatile(MaybeUninit::zeroed().assume_init());
164
165 BLE_CMD_BUFFER
166 .as_mut_ptr()
167 .write_volatile(MaybeUninit::zeroed().assume_init());
168 HCI_ACL_DATA_BUFFER
169 .as_mut_ptr()
170 .write_volatile(MaybeUninit::zeroed().assume_init());
171 }
172
173 #[cfg(feature = "mac")]
174 {
175 MAC_802_15_4_CMD_BUFFER
176 .as_mut_ptr()
177 .write_volatile(MaybeUninit::zeroed().assume_init());
178 MAC_802_15_4_NOTIF_RSP_EVT_BUFFER
179 .as_mut_ptr()
180 .write_volatile(MaybeUninit::zeroed().assume_init());
181 }
182 }
183
184 compiler_fence(Ordering::SeqCst);
185
186 // this is equivalent to `HW_IPCC_Enable`, which is called by `TL_Enable`
187 Ipcc::enable(config);
188
189 Self {
190 _ipcc: ipcc,
191 sys_subsystem: sub::sys::Sys::new(),
192 #[cfg(feature = "ble")]
193 ble_subsystem: sub::ble::Ble::new(),
194 #[cfg(feature = "mac")]
195 mac_subsystem: sub::mac::Mac::new(),
196 mm_subsystem: sub::mm::MemoryManager::new(),
197 }
198 }
199}