diff --git a/embassy-stm32-wpan/src/cmd.rs b/embassy-stm32-wpan/src/cmd.rs index 581e5019..edca8239 100644 --- a/embassy-stm32-wpan/src/cmd.rs +++ b/embassy-stm32-wpan/src/cmd.rs @@ -1,8 +1,7 @@ use core::ptr; use crate::consts::TlPacketType; -use crate::evt::{EvtPacket, EvtSerial}; -use crate::{PacketHeader, TL_EVT_HEADER_SIZE}; +use crate::PacketHeader; #[derive(Copy, Clone)] #[repr(C, packed)] @@ -60,31 +59,6 @@ impl CmdPacket { ptr::copy_nonoverlapping(payload as *const _ as *const u8, p_payload, payload.len()); } - - /// Writes an underlying CmdPacket into the provided buffer. - /// Returns a number of bytes that were written. - /// Returns an error if event kind is unknown or if provided buffer size is not enough. - #[allow(clippy::result_unit_err)] - pub fn write(&self, buf: &mut [u8]) -> Result { - unsafe { - let cmd_ptr: *const CmdPacket = self; - let self_as_evt_ptr: *const EvtPacket = cmd_ptr.cast(); - let evt_serial: *const EvtSerial = &(*self_as_evt_ptr).evt_serial; - - let acl_data: *const AclDataPacket = cmd_ptr.cast(); - let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; - let acl_serial_buf: *const u8 = acl_serial.cast(); - - let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; - if len > buf.len() { - return Err(()); - } - - core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); - - Ok(len) - } - } } #[derive(Copy, Clone)] @@ -96,9 +70,35 @@ pub struct AclDataSerial { pub acl_data: [u8; 1], } +#[derive(Copy, Clone)] +#[repr(C, packed)] +pub struct AclDataSerialStub { + pub ty: u8, + pub handle: u16, + pub length: u16, +} + #[derive(Copy, Clone)] #[repr(C, packed)] pub struct AclDataPacket { pub header: PacketHeader, pub acl_data_serial: AclDataSerial, } + +impl AclDataPacket { + pub unsafe fn write_into(cmd_buf: *mut AclDataPacket, packet_type: TlPacketType, handle: u16, payload: &[u8]) { + let p_cmd_serial = &mut (*cmd_buf).acl_data_serial as *mut _ as *mut AclDataSerialStub; + let p_payload = &mut (*cmd_buf).acl_data_serial.acl_data as *mut _; + + ptr::write_volatile( + p_cmd_serial, + AclDataSerialStub { + ty: packet_type as u8, + handle: handle, + length: payload.len() as u16, + }, + ); + + ptr::copy_nonoverlapping(payload as *const _ as *const u8, p_payload, payload.len()); + } +} diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs index 82f73a6f..3a9d0357 100644 --- a/embassy-stm32-wpan/src/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs @@ -1,8 +1,6 @@ -use core::mem::MaybeUninit; +use core::{ptr, slice}; -use super::cmd::{AclDataPacket, AclDataSerial}; -use super::consts::TlPacketType; -use super::{PacketHeader, TL_EVT_HEADER_SIZE}; +use super::PacketHeader; use crate::mm; /** @@ -63,6 +61,12 @@ pub struct EvtSerial { pub evt: Evt, } +#[derive(Copy, Clone, Default)] +pub struct EvtStub { + pub kind: u8, + pub evt_code: u8, +} + /// This format shall be used for all events (asynchronous and command response) reported /// by the CPU2 except for the command response of a system command where the header is not there /// and the format to be used shall be `EvtSerial`. @@ -101,72 +105,85 @@ impl EvtBox { Self { ptr } } - /// copies event data from inner pointer and returns an event structure - pub fn evt(&self) -> EvtPacket { - let mut evt = MaybeUninit::uninit(); + /// Returns information about the event + pub fn stub(&self) -> EvtStub { unsafe { - self.ptr.copy_to(evt.as_mut_ptr(), 1); - evt.assume_init() + let p_evt_stub = &(*self.ptr).evt_serial as *const _ as *const EvtStub; + + ptr::read_volatile(p_evt_stub) } } - /// writes an underlying [`EvtPacket`] into the provided buffer. - /// Returns the number of bytes that were written. - /// Returns an error if event kind is unknown or if provided buffer size is not enough. - #[allow(clippy::result_unit_err)] - pub fn write(&self, buf: &mut [u8]) -> Result { + pub fn payload<'a>(&self) -> &'a [u8] { unsafe { - let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + let p_payload_len = &(*self.ptr).evt_serial.evt.payload_len as *const u8; + let p_payload = &(*self.ptr).evt_serial.evt.payload as *const u8; - let evt_data: *const EvtPacket = self.ptr.cast(); - let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; - let evt_serial_buf: *const u8 = evt_serial.cast(); + let payload_len = ptr::read_volatile(p_payload_len); - let acl_data: *const AclDataPacket = self.ptr.cast(); - let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; - let acl_serial_buf: *const u8 = acl_serial.cast(); - - if let TlPacketType::AclData = evt_kind { - let len = (*acl_serial).length as usize + 5; - if len > buf.len() { - return Err(()); - } - - core::ptr::copy(evt_serial_buf, buf.as_mut_ptr(), len); - - Ok(len) - } else { - let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; - if len > buf.len() { - return Err(()); - } - - core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); - - Ok(len) - } + slice::from_raw_parts(p_payload, payload_len as usize) } } - /// returns the size of a buffer required to hold this event - #[allow(clippy::result_unit_err)] - pub fn size(&self) -> Result { - unsafe { - let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + // TODO: bring back acl - let evt_data: *const EvtPacket = self.ptr.cast(); - let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; - - let acl_data: *const AclDataPacket = self.ptr.cast(); - let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; - - if let TlPacketType::AclData = evt_kind { - Ok((*acl_serial).length as usize + 5) - } else { - Ok((*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE) - } - } - } + // /// writes an underlying [`EvtPacket`] into the provided buffer. + // /// Returns the number of bytes that were written. + // /// Returns an error if event kind is unknown or if provided buffer size is not enough. + // #[allow(clippy::result_unit_err)] + // pub fn write(&self, buf: &mut [u8]) -> Result { + // unsafe { + // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + // + // let evt_data: *const EvtPacket = self.ptr.cast(); + // let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; + // let evt_serial_buf: *const u8 = evt_serial.cast(); + // + // let acl_data: *const AclDataPacket = self.ptr.cast(); + // let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; + // let acl_serial_buf: *const u8 = acl_serial.cast(); + // + // if let TlPacketType::AclData = evt_kind { + // let len = (*acl_serial).length as usize + 5; + // if len > buf.len() { + // return Err(()); + // } + // + // core::ptr::copy(evt_serial_buf, buf.as_mut_ptr(), len); + // + // Ok(len) + // } else { + // let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; + // if len > buf.len() { + // return Err(()); + // } + // + // core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); + // + // Ok(len) + // } + // } + // } + // + // /// returns the size of a buffer required to hold this event + // #[allow(clippy::result_unit_err)] + // pub fn size(&self) -> Result { + // unsafe { + // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + // + // let evt_data: *const EvtPacket = self.ptr.cast(); + // let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; + // + // let acl_data: *const AclDataPacket = self.ptr.cast(); + // let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; + // + // if let TlPacketType::AclData = evt_kind { + // Ok((*acl_serial).length as usize + 5) + // } else { + // Ok((*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE) + // } + // } + // } } impl Drop for EvtBox { diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs index 91a0f9c0..84a4f78e 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs @@ -48,7 +48,6 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let _ = TlMbox::init(p.IPCC, Irqs, config); - let mut rx_buf = [0u8; 500]; Sys::shci_c2_ble_init(Default::default()).await; info!("starting ble..."); @@ -56,9 +55,8 @@ async fn main(_spawner: Spawner) { info!("waiting for ble..."); let ble_event = Ble::read().await; - ble_event.write(&mut rx_buf).unwrap(); - info!("ble event: {}", rx_buf); + info!("ble event: {}", ble_event.payload()); info!("Test OK"); cortex_m::asm::bkpt(); diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs index bb38204b..259889e3 100644 --- a/tests/stm32/src/bin/tl_mbox.rs +++ b/tests/stm32/src/bin/tl_mbox.rs @@ -6,6 +6,8 @@ #[path = "../common.rs"] mod common; +use core::mem; + use common::*; use embassy_executor::Spawner; use embassy_futures::poll_once; @@ -36,12 +38,13 @@ async fn main(spawner: Spawner) { let config = Config::default(); let mbox = TlMbox::init(p.IPCC, Irqs, config); - let mut rx_buf = [0u8; 500]; let ready_event = Sys::read().await; let _ = poll_once(Sys::read()); // clear rx not - ready_event.write(&mut rx_buf).unwrap(); - info!("coprocessor ready {}", rx_buf); + info!("coprocessor ready {}", ready_event.payload()); + + // test memory manager + mem::drop(ready_event); loop { let wireless_fw_info = mbox.wireless_fw_info(); @@ -74,11 +77,10 @@ async fn main(spawner: Spawner) { info!("waiting for ble..."); let ble_event = Ble::read().await; - ble_event.write(&mut rx_buf).unwrap(); - info!("ble event: {}", rx_buf); + info!("ble event: {}", ble_event.payload()); - // Timer::after(Duration::from_secs(3)).await; + Timer::after(Duration::from_millis(150)).await; info!("Test OK"); cortex_m::asm::bkpt(); }