aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/wb55/evt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan/src/wb55/evt.rs')
-rw-r--r--embassy-stm32-wpan/src/wb55/evt.rs152
1 files changed, 152 insertions, 0 deletions
diff --git a/embassy-stm32-wpan/src/wb55/evt.rs b/embassy-stm32-wpan/src/wb55/evt.rs
new file mode 100644
index 000000000..f32821269
--- /dev/null
+++ b/embassy-stm32-wpan/src/wb55/evt.rs
@@ -0,0 +1,152 @@
1use core::marker::PhantomData;
2use core::{ptr, slice};
3
4use super::PacketHeader;
5use crate::consts::TL_EVT_HEADER_SIZE;
6
7/**
8 * The payload of `Evt` for a command status event
9 */
10#[derive(Copy, Clone)]
11#[repr(C, packed)]
12pub struct CsEvt {
13 pub status: u8,
14 pub num_cmd: u8,
15 pub cmd_code: u16,
16}
17
18/**
19 * The payload of `Evt` for a command complete event
20 */
21#[derive(Copy, Clone, Default)]
22#[repr(C, packed)]
23pub struct CcEvt {
24 pub num_cmd: u8,
25 pub cmd_code: u16,
26 pub payload: [u8; 1],
27}
28
29impl CcEvt {
30 pub fn write(&self, buf: &mut [u8]) {
31 unsafe {
32 let len = core::mem::size_of::<CcEvt>();
33 assert!(buf.len() >= len);
34
35 let self_ptr: *const CcEvt = self;
36 let self_buf_ptr: *const u8 = self_ptr.cast();
37
38 core::ptr::copy(self_buf_ptr, buf.as_mut_ptr(), len);
39 }
40 }
41}
42
43#[derive(Copy, Clone, Default)]
44#[repr(C, packed)]
45pub struct AsynchEvt {
46 sub_evt_code: u16,
47 payload: [u8; 1],
48}
49
50#[derive(Copy, Clone)]
51#[repr(C, packed)]
52pub struct Evt {
53 pub evt_code: u8,
54 pub payload_len: u8,
55 pub payload: [u8; 255],
56}
57
58#[derive(Copy, Clone)]
59#[repr(C, packed)]
60pub struct EvtSerial {
61 pub kind: u8,
62 pub evt: Evt,
63}
64
65#[derive(Copy, Clone, Default)]
66#[repr(C, packed)]
67pub struct EvtStub {
68 pub kind: u8,
69 pub evt_code: u8,
70 pub payload_len: u8,
71}
72
73/// This format shall be used for all events (asynchronous and command response) reported
74/// by the CPU2 except for the command response of a system command where the header is not there
75/// and the format to be used shall be `EvtSerial`.
76///
77/// ### Note:
78/// Be careful that the asynchronous events reported by the CPU2 on the system channel do
79/// include the header and shall use `EvtPacket` format. Only the command response format on the
80/// system channel is different.
81#[derive(Copy, Clone)]
82#[repr(C, packed)]
83pub struct EvtPacket {
84 pub header: PacketHeader,
85 pub evt_serial: EvtSerial,
86}
87
88impl EvtPacket {
89 pub fn kind(&self) -> u8 {
90 self.evt_serial.kind
91 }
92
93 pub fn evt(&self) -> &Evt {
94 &self.evt_serial.evt
95 }
96}
97
98pub trait MemoryManager {
99 unsafe fn drop_event_packet(evt: *mut EvtPacket);
100}
101
102/// smart pointer to the [`EvtPacket`] that will dispose of [`EvtPacket`] buffer automatically
103/// on [`Drop`]
104#[derive(Debug)]
105pub struct EvtBox<T: MemoryManager> {
106 ptr: *mut EvtPacket,
107 mm: PhantomData<T>,
108}
109
110unsafe impl<T: MemoryManager> Send for EvtBox<T> {}
111impl<T: MemoryManager> EvtBox<T> {
112 pub(super) fn new(ptr: *mut EvtPacket) -> Self {
113 Self { ptr, mm: PhantomData }
114 }
115
116 /// Returns information about the event
117 pub fn stub(&self) -> EvtStub {
118 unsafe {
119 let p_evt_stub = &(*self.ptr).evt_serial as *const _ as *const EvtStub;
120
121 ptr::read_volatile(p_evt_stub)
122 }
123 }
124
125 pub fn payload<'a>(&'a self) -> &'a [u8] {
126 unsafe {
127 let p_payload_len = &(*self.ptr).evt_serial.evt.payload_len as *const u8;
128 let p_payload = &(*self.ptr).evt_serial.evt.payload as *const u8;
129
130 let payload_len = ptr::read_volatile(p_payload_len);
131
132 slice::from_raw_parts(p_payload, payload_len as usize)
133 }
134 }
135
136 pub fn serial<'a>(&'a self) -> &'a [u8] {
137 unsafe {
138 let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial;
139 let evt_serial_buf: *const u8 = evt_serial.cast();
140
141 let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE;
142
143 slice::from_raw_parts(evt_serial_buf, len)
144 }
145 }
146}
147
148impl<T: MemoryManager> Drop for EvtBox<T> {
149 fn drop(&mut self) {
150 unsafe { T::drop_event_packet(self.ptr) };
151 }
152}