diff options
Diffstat (limited to 'embassy-stm32-wpan/src/wb55/evt.rs')
| -rw-r--r-- | embassy-stm32-wpan/src/wb55/evt.rs | 152 |
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 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | use core::{ptr, slice}; | ||
| 3 | |||
| 4 | use super::PacketHeader; | ||
| 5 | use 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)] | ||
| 12 | pub 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)] | ||
| 23 | pub struct CcEvt { | ||
| 24 | pub num_cmd: u8, | ||
| 25 | pub cmd_code: u16, | ||
| 26 | pub payload: [u8; 1], | ||
| 27 | } | ||
| 28 | |||
| 29 | impl 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)] | ||
| 45 | pub struct AsynchEvt { | ||
| 46 | sub_evt_code: u16, | ||
| 47 | payload: [u8; 1], | ||
| 48 | } | ||
| 49 | |||
| 50 | #[derive(Copy, Clone)] | ||
| 51 | #[repr(C, packed)] | ||
| 52 | pub 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)] | ||
| 60 | pub struct EvtSerial { | ||
| 61 | pub kind: u8, | ||
| 62 | pub evt: Evt, | ||
| 63 | } | ||
| 64 | |||
| 65 | #[derive(Copy, Clone, Default)] | ||
| 66 | #[repr(C, packed)] | ||
| 67 | pub 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)] | ||
| 83 | pub struct EvtPacket { | ||
| 84 | pub header: PacketHeader, | ||
| 85 | pub evt_serial: EvtSerial, | ||
| 86 | } | ||
| 87 | |||
| 88 | impl 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 | |||
| 98 | pub 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)] | ||
| 105 | pub struct EvtBox<T: MemoryManager> { | ||
| 106 | ptr: *mut EvtPacket, | ||
| 107 | mm: PhantomData<T>, | ||
| 108 | } | ||
| 109 | |||
| 110 | unsafe impl<T: MemoryManager> Send for EvtBox<T> {} | ||
| 111 | impl<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 | |||
| 148 | impl<T: MemoryManager> Drop for EvtBox<T> { | ||
| 149 | fn drop(&mut self) { | ||
| 150 | unsafe { T::drop_event_packet(self.ptr) }; | ||
| 151 | } | ||
| 152 | } | ||
