aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/tl_mbox/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/tl_mbox/mod.rs')
-rw-r--r--embassy-stm32/src/tl_mbox/mod.rs318
1 files changed, 318 insertions, 0 deletions
diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs
new file mode 100644
index 000000000..623546dc9
--- /dev/null
+++ b/embassy-stm32/src/tl_mbox/mod.rs
@@ -0,0 +1,318 @@
1use core::mem::MaybeUninit;
2
3use bit_field::BitField;
4
5use self::ble::Ble;
6use self::cmd::{AclDataPacket, CmdPacket};
7use self::evt::CsEvt;
8use self::mm::MemoryManager;
9use self::sys::Sys;
10use self::unsafe_linked_list::LinkedListNode;
11use crate::ipcc::Ipcc;
12
13mod ble;
14mod channels;
15mod cmd;
16mod evt;
17mod mm;
18mod sys;
19mod unsafe_linked_list;
20
21pub type PacketHeader = LinkedListNode;
22
23const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::<PacketHeader>();
24const TL_EVT_HEADER_SIZE: usize = 3;
25const TL_CS_EVT_SIZE: usize = core::mem::size_of::<CsEvt>();
26
27const CFG_TL_BLE_EVT_QUEUE_LENGTH: usize = 5;
28const CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE: usize = 255;
29const TL_BLE_EVENT_FRAME_SIZE: usize = TL_EVT_HEADER_SIZE + CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE;
30
31const POOL_SIZE: usize = CFG_TL_BLE_EVT_QUEUE_LENGTH * 4 * divc(TL_PACKET_HEADER_SIZE + TL_BLE_EVENT_FRAME_SIZE, 4);
32
33const fn divc(x: usize, y: usize) -> usize {
34 (x + y - 1) / y
35}
36
37#[repr(C, packed)]
38#[derive(Copy, Clone)]
39pub struct SafeBootInfoTable {
40 version: u32,
41}
42
43#[repr(C, packed)]
44#[derive(Copy, Clone)]
45pub struct RssInfoTable {
46 version: u32,
47 memory_size: u32,
48 rss_info: u32,
49}
50
51/// # Version
52/// - 0 -> 3 = Build - 0: Untracked - 15:Released - x: Tracked version
53/// - 4 -> 7 = branch - 0: Mass Market - x: ...
54/// - 8 -> 15 = Subversion
55/// - 16 -> 23 = Version minor
56/// - 24 -> 31 = Version major
57/// # Memory Size
58/// - 0 -> 7 = Flash ( Number of 4k sector)
59/// - 8 -> 15 = Reserved ( Shall be set to 0 - may be used as flash extension )
60/// - 16 -> 23 = SRAM2b ( Number of 1k sector)
61/// - 24 -> 31 = SRAM2a ( Number of 1k sector)
62#[repr(C, packed)]
63#[derive(Copy, Clone)]
64pub struct WirelessFwInfoTable {
65 version: u32,
66 memory_size: u32,
67 thread_info: u32,
68 ble_info: u32,
69}
70
71impl WirelessFwInfoTable {
72 pub fn version_major(&self) -> u8 {
73 let version = self.version;
74 (version.get_bits(24..31) & 0xff) as u8
75 }
76
77 pub fn version_minor(&self) -> u8 {
78 let version = self.version;
79 (version.get_bits(16..23) & 0xff) as u8
80 }
81
82 pub fn subversion(&self) -> u8 {
83 let version = self.version;
84 (version.get_bits(8..15) & 0xff) as u8
85 }
86
87 /// size of FLASH, expressed in number of 4K sectors
88 pub fn flash_size(&self) -> u8 {
89 let memory_size = self.memory_size;
90 (memory_size.get_bits(0..7) & 0xff) as u8
91 }
92
93 /// size for SRAM2a, expressed in number of 1K sectors
94 pub fn sram2a_size(&self) -> u8 {
95 let memory_size = self.memory_size;
96 (memory_size.get_bits(24..31) & 0xff) as u8
97 }
98
99 /// size of SRAM2b, expressed in number of 1K sectors
100 pub fn sram2b_size(&self) -> u8 {
101 let memory_size = self.memory_size;
102 (memory_size.get_bits(16..23) & 0xff) as u8
103 }
104}
105
106#[repr(C, packed)]
107#[derive(Copy, Clone)]
108pub struct DeviceInfoTable {
109 pub safe_boot_info_table: SafeBootInfoTable,
110 pub rss_info_table: RssInfoTable,
111 pub wireless_fw_info_table: WirelessFwInfoTable,
112}
113
114#[repr(C, packed)]
115struct BleTable {
116 pcmd_buffer: *const CmdPacket,
117 pcs_buffer: *const u8,
118 pevt_queue: *const u8,
119 phci_acl_data_buffer: *mut AclDataPacket,
120}
121
122#[repr(C, packed)]
123struct ThreadTable {
124 no_stack_buffer: *const u8,
125 cli_cmd_rsp_buffer: *const u8,
126 ot_cmd_rsp_buffer: *const u8,
127}
128
129#[repr(C, packed)]
130struct SysTable {
131 pcmd_buffer: *mut CmdPacket,
132 sys_queue: *const LinkedListNode,
133}
134
135#[allow(dead_code)] // Not used currently but reserved
136#[repr(C, packed)]
137struct LldTestTable {
138 cli_cmd_rsp_buffer: *const u8,
139 m0_cmd_buffer: *const u8,
140}
141
142#[allow(dead_code)] // Not used currently but reserved
143#[repr(C, packed)]
144struct BleLldTable {
145 cmd_rsp_buffer: *const u8,
146 m0_cmd_buffer: *const u8,
147}
148
149#[allow(dead_code)] // Not used currently but reserved
150#[repr(C, packed)]
151struct ZigbeeTable {
152 notif_m0_to_m4_buffer: *const u8,
153 appli_cmd_m4_to_m0_buffer: *const u8,
154 request_m0_to_m4_buffer: *const u8,
155}
156
157#[repr(C, packed)]
158struct MemManagerTable {
159 spare_ble_buffer: *const u8,
160 spare_sys_buffer: *const u8,
161
162 ble_pool: *const u8,
163 ble_pool_size: u32,
164
165 pevt_free_buffer_queue: *mut LinkedListNode,
166
167 traces_evt_pool: *const u8,
168 traces_pool_size: u32,
169}
170
171#[repr(C, packed)]
172struct TracesTable {
173 traces_queue: *const u8,
174}
175
176#[repr(C, packed)]
177struct Mac802_15_4Table {
178 pcmd_rsp_buffer: *const u8,
179 pnotack_buffer: *const u8,
180 evt_queue: *const u8,
181}
182
183/// reference table. Contains pointers to all other tables
184#[repr(C, packed)]
185#[derive(Copy, Clone)]
186pub struct RefTable {
187 pub device_info_table: *const DeviceInfoTable,
188 ble_table: *const BleTable,
189 thread_table: *const ThreadTable,
190 sys_table: *const SysTable,
191 mem_manager_table: *const MemManagerTable,
192 traces_table: *const TracesTable,
193 mac_802_15_4_table: *const Mac802_15_4Table,
194}
195
196#[link_section = "TL_REF_TABLE"]
197pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit();
198
199#[link_section = "TL_DEVICE_INFO_TABLE"]
200static mut TL_DEVICE_INFO_TABLE: MaybeUninit<DeviceInfoTable> = MaybeUninit::uninit();
201
202#[link_section = "TL_BLE_TABLE"]
203static mut TL_BLE_TABLE: MaybeUninit<BleTable> = MaybeUninit::uninit();
204
205#[link_section = "TL_THREAD_TABLE"]
206static mut TL_THREAD_TABLE: MaybeUninit<ThreadTable> = MaybeUninit::uninit();
207
208#[link_section = "TL_SYS_TABLE"]
209static mut TL_SYS_TABLE: MaybeUninit<SysTable> = MaybeUninit::uninit();
210
211#[link_section = "TL_MEM_MANAGER_TABLE"]
212static mut TL_MEM_MANAGER_TABLE: MaybeUninit<MemManagerTable> = MaybeUninit::uninit();
213
214#[link_section = "TL_TRACES_TABLE"]
215static mut TL_TRACES_TABLE: MaybeUninit<TracesTable> = MaybeUninit::uninit();
216
217#[link_section = "TL_MAC_802_15_4_TABLE"]
218static mut TL_MAC_802_15_4_TABLE: MaybeUninit<Mac802_15_4Table> = MaybeUninit::uninit();
219
220#[allow(dead_code)] // Not used currently but reserved
221#[link_section = "FREE_BUF_QUEUE"]
222static mut FREE_BUFF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
223
224// not in shared RAM
225static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
226
227#[allow(dead_code)] // Not used currently but reserved
228#[link_section = "TRACES_EVT_QUEUE"]
229static mut TRACES_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
230
231#[link_section = "CS_BUFFER"]
232static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> =
233 MaybeUninit::uninit();
234
235#[link_section = "EVT_QUEUE"]
236static mut EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
237
238#[link_section = "SYSTEM_EVT_QUEUE"]
239static mut SYSTEM_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit();
240
241#[link_section = "SYS_CMD_BUF"]
242static mut SYS_CMD_BUF: MaybeUninit<CmdPacket> = MaybeUninit::uninit();
243
244#[link_section = "EVT_POOL"]
245static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit();
246
247#[link_section = "SYS_SPARE_EVT_BUF"]
248static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> =
249 MaybeUninit::uninit();
250
251#[link_section = "BLE_SPARE_EVT_BUF"]
252static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> =
253 MaybeUninit::uninit();
254
255#[link_section = "BLE_CMD_BUFFER"]
256static mut BLE_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit();
257
258#[link_section = "HCI_ACL_DATA_BUFFER"]
259// "magic" numbers from ST ---v---v
260static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit();
261
262pub struct TlMbox {
263 _sys: Sys,
264 _ble: Ble,
265 _mm: MemoryManager,
266}
267
268impl TlMbox {
269 /// initializes low-level transport between CPU1 and BLE stack on CPU2
270 pub fn init(ipcc: &mut Ipcc) -> TlMbox {
271 unsafe {
272 TL_REF_TABLE = MaybeUninit::new(RefTable {
273 device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(),
274 ble_table: TL_BLE_TABLE.as_ptr(),
275 thread_table: TL_THREAD_TABLE.as_ptr(),
276 sys_table: TL_SYS_TABLE.as_ptr(),
277 mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(),
278 traces_table: TL_TRACES_TABLE.as_ptr(),
279 mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(),
280 });
281
282 TL_SYS_TABLE = MaybeUninit::zeroed();
283 TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed();
284 TL_BLE_TABLE = MaybeUninit::zeroed();
285 TL_THREAD_TABLE = MaybeUninit::zeroed();
286 TL_MEM_MANAGER_TABLE = MaybeUninit::zeroed();
287 TL_TRACES_TABLE = MaybeUninit::zeroed();
288 TL_MAC_802_15_4_TABLE = MaybeUninit::zeroed();
289
290 EVT_POOL = MaybeUninit::zeroed();
291 SYS_SPARE_EVT_BUF = MaybeUninit::zeroed();
292 BLE_SPARE_EVT_BUF = MaybeUninit::zeroed();
293
294 CS_BUFFER = MaybeUninit::zeroed();
295 BLE_CMD_BUFFER = MaybeUninit::zeroed();
296 HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed();
297 }
298
299 ipcc.init();
300
301 let _sys = Sys::new(ipcc);
302 let _ble = Ble::new(ipcc);
303 let _mm = MemoryManager::new();
304
305 TlMbox { _sys, _ble, _mm }
306 }
307
308 pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {
309 let info = unsafe { &(*(*TL_REF_TABLE.as_ptr()).device_info_table).wireless_fw_info_table };
310
311 // zero version indicates that CPU2 wasn't active and didn't fill the information table
312 if info.version != 0 {
313 Some(*info)
314 } else {
315 None
316 }
317 }
318}