stm32/wpan: modify evtbox to use slice view

This commit is contained in:
xoviat 2023-06-17 14:38:36 -05:00
parent 041a4a4208
commit c7b0df569b
4 changed files with 112 additions and 95 deletions

View file

@ -1,8 +1,7 @@
use core::ptr; use core::ptr;
use crate::consts::TlPacketType; use crate::consts::TlPacketType;
use crate::evt::{EvtPacket, EvtSerial}; use crate::PacketHeader;
use crate::{PacketHeader, TL_EVT_HEADER_SIZE};
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C, packed)] #[repr(C, packed)]
@ -60,31 +59,6 @@ impl CmdPacket {
ptr::copy_nonoverlapping(payload as *const _ as *const u8, p_payload, payload.len()); 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<usize, ()> {
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)] #[derive(Copy, Clone)]
@ -96,9 +70,35 @@ pub struct AclDataSerial {
pub acl_data: [u8; 1], 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)] #[derive(Copy, Clone)]
#[repr(C, packed)] #[repr(C, packed)]
pub struct AclDataPacket { pub struct AclDataPacket {
pub header: PacketHeader, pub header: PacketHeader,
pub acl_data_serial: AclDataSerial, 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());
}
}

View file

@ -1,8 +1,6 @@
use core::mem::MaybeUninit; use core::{ptr, slice};
use super::cmd::{AclDataPacket, AclDataSerial}; use super::PacketHeader;
use super::consts::TlPacketType;
use super::{PacketHeader, TL_EVT_HEADER_SIZE};
use crate::mm; use crate::mm;
/** /**
@ -63,6 +61,12 @@ pub struct EvtSerial {
pub evt: Evt, 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 /// 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 /// 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`. /// and the format to be used shall be `EvtSerial`.
@ -101,72 +105,85 @@ impl EvtBox {
Self { ptr } Self { ptr }
} }
/// copies event data from inner pointer and returns an event structure /// Returns information about the event
pub fn evt(&self) -> EvtPacket { pub fn stub(&self) -> EvtStub {
let mut evt = MaybeUninit::uninit();
unsafe { unsafe {
self.ptr.copy_to(evt.as_mut_ptr(), 1); let p_evt_stub = &(*self.ptr).evt_serial as *const _ as *const EvtStub;
evt.assume_init()
ptr::read_volatile(p_evt_stub)
} }
} }
/// writes an underlying [`EvtPacket`] into the provided buffer. pub fn payload<'a>(&self) -> &'a [u8] {
/// 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<usize, ()> {
unsafe { 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 payload_len = ptr::read_volatile(p_payload_len);
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(); slice::from_raw_parts(p_payload, payload_len as usize)
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 // TODO: bring back acl
#[allow(clippy::result_unit_err)]
pub fn size(&self) -> Result<usize, ()> {
unsafe {
let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?;
let evt_data: *const EvtPacket = self.ptr.cast(); // /// writes an underlying [`EvtPacket`] into the provided buffer.
let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; // /// Returns the number of bytes that were written.
// /// Returns an error if event kind is unknown or if provided buffer size is not enough.
let acl_data: *const AclDataPacket = self.ptr.cast(); // #[allow(clippy::result_unit_err)]
let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; // pub fn write(&self, buf: &mut [u8]) -> Result<usize, ()> {
// unsafe {
if let TlPacketType::AclData = evt_kind { // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?;
Ok((*acl_serial).length as usize + 5) //
} else { // let evt_data: *const EvtPacket = self.ptr.cast();
Ok((*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE) // 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<usize, ()> {
// 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 { impl Drop for EvtBox {

View file

@ -48,7 +48,6 @@ async fn main(_spawner: Spawner) {
let config = Config::default(); let config = Config::default();
let _ = TlMbox::init(p.IPCC, Irqs, config); let _ = TlMbox::init(p.IPCC, Irqs, config);
let mut rx_buf = [0u8; 500];
Sys::shci_c2_ble_init(Default::default()).await; Sys::shci_c2_ble_init(Default::default()).await;
info!("starting ble..."); info!("starting ble...");
@ -56,9 +55,8 @@ async fn main(_spawner: Spawner) {
info!("waiting for ble..."); info!("waiting for ble...");
let ble_event = Ble::read().await; 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"); info!("Test OK");
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();

View file

@ -6,6 +6,8 @@
#[path = "../common.rs"] #[path = "../common.rs"]
mod common; mod common;
use core::mem;
use common::*; use common::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_futures::poll_once; use embassy_futures::poll_once;
@ -36,12 +38,13 @@ async fn main(spawner: Spawner) {
let config = Config::default(); let config = Config::default();
let mbox = TlMbox::init(p.IPCC, Irqs, config); let mbox = TlMbox::init(p.IPCC, Irqs, config);
let mut rx_buf = [0u8; 500];
let ready_event = Sys::read().await; let ready_event = Sys::read().await;
let _ = poll_once(Sys::read()); // clear rx not 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 { loop {
let wireless_fw_info = mbox.wireless_fw_info(); let wireless_fw_info = mbox.wireless_fw_info();
@ -74,11 +77,10 @@ async fn main(spawner: Spawner) {
info!("waiting for ble..."); info!("waiting for ble...");
let ble_event = Ble::read().await; 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"); info!("Test OK");
cortex_m::asm::bkpt(); cortex_m::asm::bkpt();
} }