From 3810fe6a2058d04054c7242216a7bc9d2993667b Mon Sep 17 00:00:00 2001 From: goueslati Date: Fri, 12 May 2023 10:26:46 +0100 Subject: [PATCH 01/14] tl_mbox: added zigee, lld tests and ble lld tables to ref table --- embassy-stm32/src/tl_mbox/mod.rs | 36 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs index 73d2ca6d..0cee26b7 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32/src/tl_mbox/mod.rs @@ -42,10 +42,10 @@ pub struct SafeBootInfoTable { #[repr(C, packed)] #[derive(Copy, Clone)] -pub struct RssInfoTable { +pub struct FusInfoTable { version: u32, memory_size: u32, - rss_info: u32, + fus_info: u32, } /// # Version @@ -64,8 +64,8 @@ pub struct RssInfoTable { pub struct WirelessFwInfoTable { version: u32, memory_size: u32, - thread_info: u32, - ble_info: u32, + info_stack: u32, + reserved: u32, } impl WirelessFwInfoTable { @@ -107,7 +107,7 @@ impl WirelessFwInfoTable { #[derive(Copy, Clone)] pub struct DeviceInfoTable { pub safe_boot_info_table: SafeBootInfoTable, - pub rss_info_table: RssInfoTable, + pub fus_info_table: FusInfoTable, pub wireless_fw_info_table: WirelessFwInfoTable, } @@ -191,6 +191,9 @@ pub struct RefTable { mem_manager_table: *const MemManagerTable, traces_table: *const TracesTable, mac_802_15_4_table: *const Mac802_15_4Table, + zigbee_table: *const ZigbeeTable, + lld_tests_table: *const LldTestTable, + ble_lld_table: *const BleLldTable, } #[link_section = "TL_REF_TABLE"] @@ -205,6 +208,12 @@ static mut TL_BLE_TABLE: MaybeUninit = MaybeUninit::uninit(); #[link_section = "MB_MEM1"] static mut TL_THREAD_TABLE: MaybeUninit = MaybeUninit::uninit(); +#[link_section = "MB_MEM1"] +static mut TL_LLD_TESTS_TABLE: MaybeUninit = MaybeUninit::uninit(); + +#[link_section = "MB_MEM1"] +static mut TL_BLE_LLD_TABLE: MaybeUninit = MaybeUninit::uninit(); + #[link_section = "MB_MEM1"] static mut TL_SYS_TABLE: MaybeUninit = MaybeUninit::uninit(); @@ -217,25 +226,28 @@ static mut TL_TRACES_TABLE: MaybeUninit = MaybeUninit::uninit(); #[link_section = "MB_MEM1"] static mut TL_MAC_802_15_4_TABLE: MaybeUninit = MaybeUninit::uninit(); +#[link_section = "MB_MEM1"] +static mut TL_ZIGBEE_TABLE: MaybeUninit = MaybeUninit::uninit(); + #[allow(dead_code)] // Not used currently but reserved -#[link_section = "MB_MEM2"] +#[link_section = "MB_MEM1"] static mut FREE_BUFF_QUEUE: MaybeUninit = MaybeUninit::uninit(); // not in shared RAM static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); #[allow(dead_code)] // Not used currently but reserved -#[link_section = "MB_MEM2"] +#[link_section = "MB_MEM1"] static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = MaybeUninit::uninit(); -#[link_section = "MB_MEM2"] +#[link_section = "MB_MEM1"] static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); -#[link_section = "MB_MEM2"] +#[link_section = "MB_MEM1"] static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] @@ -277,6 +289,9 @@ impl TlMbox { mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(), traces_table: TL_TRACES_TABLE.as_ptr(), mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(), + zigbee_table: TL_ZIGBEE_TABLE.as_ptr(), + lld_tests_table: TL_LLD_TESTS_TABLE.as_ptr(), + ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(), }); TL_SYS_TABLE = MaybeUninit::zeroed(); @@ -286,6 +301,9 @@ impl TlMbox { TL_MEM_MANAGER_TABLE = MaybeUninit::zeroed(); TL_TRACES_TABLE = MaybeUninit::zeroed(); TL_MAC_802_15_4_TABLE = MaybeUninit::zeroed(); + TL_ZIGBEE_TABLE = MaybeUninit::zeroed(); + TL_LLD_TESTS_TABLE = MaybeUninit::zeroed(); + TL_BLE_LLD_TABLE = MaybeUninit::zeroed(); EVT_POOL = MaybeUninit::zeroed(); SYS_SPARE_EVT_BUF = MaybeUninit::zeroed(); From d97724cca3164250118c732759f403f4f94d4629 Mon Sep 17 00:00:00 2001 From: goueslati Date: Mon, 15 May 2023 10:25:02 +0100 Subject: [PATCH 02/14] tl_mbox read and write --- embassy-stm32/src/ipcc.rs | 15 ++ embassy-stm32/src/tl_mbox/ble.rs | 48 ++++++- embassy-stm32/src/tl_mbox/channels.rs | 8 +- embassy-stm32/src/tl_mbox/consts.rs | 53 +++++++ embassy-stm32/src/tl_mbox/evt.rs | 163 ++++++++++++++++++++++ embassy-stm32/src/tl_mbox/mm.rs | 47 ++++++- embassy-stm32/src/tl_mbox/mod.rs | 77 ++++++++-- embassy-stm32/src/tl_mbox/shci.rs | 101 ++++++++++++++ embassy-stm32/src/tl_mbox/sys.rs | 69 ++++++++- examples/stm32wb/src/bin/tl_mbox.rs | 6 +- examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 96 +++++++++++++ 11 files changed, 661 insertions(+), 22 deletions(-) create mode 100644 embassy-stm32/src/tl_mbox/consts.rs create mode 100644 embassy-stm32/src/tl_mbox/shci.rs create mode 100644 examples/stm32wb/src/bin/tl_mbox_tx_rx.rs diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 903aeca3..9af5f171 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -158,6 +158,10 @@ impl<'d> Ipcc<'d> { pub fn is_rx_pending(&self, channel: IpccChannel) -> bool { self.c2_is_active_flag(channel) && self.c1_get_rx_channel(channel) } + + pub fn as_mut_ptr(&self) -> *mut Self { + unsafe { &mut core::ptr::read(self) as *mut _ } + } } impl sealed::Instance for crate::peripherals::IPCC { @@ -176,3 +180,14 @@ unsafe fn _configure_pwr() { // set RF wake-up clock = LSE rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); } + +// TODO: if anyone has a better idea, please let me know +/// extension trait that constrains the [`Ipcc`] peripheral +pub trait IpccExt<'d> { + fn constrain(self) -> Ipcc<'d>; +} +impl<'d> IpccExt<'d> for IPCC { + fn constrain(self) -> Ipcc<'d> { + Ipcc { _peri: self.into_ref() } + } +} diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs index a2c0758d..a285e314 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32/src/tl_mbox/ble.rs @@ -1,13 +1,22 @@ use core::mem::MaybeUninit; -use super::unsafe_linked_list::LST_init_head; -use super::{channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; +use embassy_futures::block_on; + +use super::cmd::CmdSerial; +use super::consts::TlPacketType; +use super::evt::EvtBox; +use super::unsafe_linked_list::{LST_init_head, LST_is_empty, LST_remove_head}; +use super::{ + channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_CHANNEL, + TL_REF_TABLE, +}; use crate::ipcc::Ipcc; +use crate::tl_mbox::cmd::CmdPacket; pub struct Ble; impl Ble { - pub fn new(ipcc: &mut Ipcc) -> Self { + pub(crate) fn new(ipcc: &mut Ipcc) -> Self { unsafe { LST_init_head(EVT_QUEUE.as_mut_ptr()); @@ -23,4 +32,37 @@ impl Ble { Ble } + + pub(crate) fn evt_handler(ipcc: &mut Ipcc) { + unsafe { + let mut node_ptr = core::ptr::null_mut(); + let node_ptr_ptr: *mut _ = &mut node_ptr; + + while !LST_is_empty(EVT_QUEUE.as_mut_ptr()) { + LST_remove_head(EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); + + let event = node_ptr.cast(); + let event = EvtBox::new(event); + + block_on(TL_CHANNEL.send(event)); + } + } + + ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); + } + + pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { + unsafe { + let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; + let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial; + let pcmd_serial_buf: *mut u8 = pcmd_serial.cast(); + + core::ptr::copy(buf.as_ptr(), pcmd_serial_buf, buf.len()); + + let mut cmd_packet = &mut *(*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; + cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8; + } + + ipcc.c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL); + } } diff --git a/embassy-stm32/src/tl_mbox/channels.rs b/embassy-stm32/src/tl_mbox/channels.rs index 1dde5d61..aaa6ce17 100644 --- a/embassy-stm32/src/tl_mbox/channels.rs +++ b/embassy-stm32/src/tl_mbox/channels.rs @@ -52,9 +52,9 @@ pub mod cpu1 { use crate::ipcc::IpccChannel; - #[allow(dead_code)] // Not used currently but reserved + // Not used currently but reserved pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; - #[allow(dead_code)] // Not used currently but reserved + // Not used currently but reserved pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2; #[allow(dead_code)] // Not used currently but reserved pub const IPCC_THREAD_OT_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; @@ -62,7 +62,7 @@ pub mod cpu1 { pub const IPCC_ZIGBEE_CMD_APPLI_CHANNEL: IpccChannel = IpccChannel::Channel3; #[allow(dead_code)] // Not used currently but reserved pub const IPCC_MAC_802_15_4_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; - #[allow(dead_code)] // Not used currently but reserved + // Not used currently but reserved pub const IPCC_MM_RELEASE_BUFFER_CHANNEL: IpccChannel = IpccChannel::Channel4; #[allow(dead_code)] // Not used currently but reserved pub const IPCC_THREAD_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; @@ -88,7 +88,7 @@ pub mod cpu2 { #[allow(dead_code)] // Not used currently but reserved pub const IPCC_LDDTESTS_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; #[allow(dead_code)] // Not used currently but reserved - pub const IPCC_BLE_LLDÇM0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; + pub const IPCC_BLE_LLD_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; #[allow(dead_code)] // Not used currently but reserved pub const IPCC_TRACES_CHANNEL: IpccChannel = IpccChannel::Channel4; #[allow(dead_code)] // Not used currently but reserved diff --git a/embassy-stm32/src/tl_mbox/consts.rs b/embassy-stm32/src/tl_mbox/consts.rs new file mode 100644 index 00000000..e16a26cd --- /dev/null +++ b/embassy-stm32/src/tl_mbox/consts.rs @@ -0,0 +1,53 @@ +#[derive(PartialEq)] +#[repr(C)] +pub enum TlPacketType { + BleCmd = 0x01, + AclData = 0x02, + BleEvt = 0x04, + + OtCmd = 0x08, + OtRsp = 0x09, + CliCmd = 0x0A, + OtNot = 0x0C, + OtAck = 0x0D, + CliNot = 0x0E, + CliAck = 0x0F, + + SysCmd = 0x10, + SysRsp = 0x11, + SysEvt = 0x12, + + LocCmd = 0x20, + LocRsp = 0x21, + + TracesApp = 0x40, + TracesWl = 0x41, +} + +impl TryFrom for TlPacketType { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 0x01 => Ok(TlPacketType::BleCmd), + 0x02 => Ok(TlPacketType::AclData), + 0x04 => Ok(TlPacketType::BleEvt), + 0x08 => Ok(TlPacketType::OtCmd), + 0x09 => Ok(TlPacketType::OtRsp), + 0x0A => Ok(TlPacketType::CliCmd), + 0x0C => Ok(TlPacketType::OtNot), + 0x0D => Ok(TlPacketType::OtAck), + 0x0E => Ok(TlPacketType::CliNot), + 0x0F => Ok(TlPacketType::CliAck), + 0x10 => Ok(TlPacketType::SysCmd), + 0x11 => Ok(TlPacketType::SysRsp), + 0x12 => Ok(TlPacketType::SysEvt), + 0x20 => Ok(TlPacketType::LocCmd), + 0x21 => Ok(TlPacketType::LocRsp), + 0x40 => Ok(TlPacketType::TracesApp), + 0x41 => Ok(TlPacketType::TracesWl), + + _ => Err(()), + } + } +} diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs index 4244db81..8ae2a255 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32/src/tl_mbox/evt.rs @@ -1,3 +1,10 @@ +use core::mem::MaybeUninit; + +use super::cmd::{AclDataPacket, AclDataSerial}; +use super::consts::TlPacketType; +use super::{PacketHeader, TL_EVT_HEADER_SIZE}; +use crate::tl_mbox::mm; + /// the payload of [`Evt`] for a command status event #[derive(Copy, Clone)] #[repr(C, packed)] @@ -6,3 +13,159 @@ pub struct CsEvt { pub num_cmd: u8, pub cmd_code: u16, } + +/// the payload of [`Evt`] for a command complete event +#[derive(Clone, Copy, Default)] +#[repr(C, packed)] +pub struct CcEvt { + pub num_cmd: u8, + pub cmd_code: u8, + pub payload: [u8; 1], +} + +#[derive(Clone, Copy, Default)] +#[repr(C, packed)] +pub struct Evt { + pub evt_code: u8, + pub payload_len: u8, + pub payload: [u8; 1], +} + +#[derive(Clone, Copy, Default)] +#[repr(C, packed)] +pub struct EvtSerial { + pub kind: u8, + pub evt: Evt, +} + +/// 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`. +/// +/// ### Note: +/// Be careful that the asynchronous events reported by the CPU2 on the system channel do +/// include the header and shall use `EvtPacket` format. Only the command response format on the +/// system channel is different. +#[derive(Clone, Copy, Default)] +#[repr(C, packed)] +pub struct EvtPacket { + pub header: PacketHeader, + pub evt_serial: EvtSerial, +} + +/// Smart pointer to the [`EvtPacket`] that will dispose of it automatically on drop +pub struct EvtBox { + ptr: *mut EvtPacket, +} + +unsafe impl Send for EvtBox {} +impl EvtBox { + pub(super) fn new(ptr: *mut EvtPacket) -> Self { + Self { ptr } + } + + /// Copies the event data from inner pointer and returns and event structure + pub fn evt(&self) -> EvtPacket { + let mut evt = MaybeUninit::uninit(); + unsafe { + self.ptr.copy_to(evt.as_mut_ptr(), 1); + evt.assume_init() + } + } + + /// Returns the size of a buffer required to hold this event + pub fn size(&self) -> Result { + unsafe { + let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + + if evt_kind == TlPacketType::AclData { + let acl_data: *const AclDataPacket = self.ptr.cast(); + let acl_serial: *const AclDataSerial = &(*acl_data).acl_data_serial; + + Ok((*acl_serial).length as usize + 5) + } else { + let evt_data: *const EvtPacket = self.ptr.cast(); + let evt_serial: *const EvtSerial = &(*evt_data).evt_serial; + + 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 unkown or if provided buffer size is not enough + pub fn copy_into_slice(&self, buf: &mut [u8]) -> Result { + // TODO: double check this + // unsafe { + // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; + + // if let TlPacketType::AclData = evt_kind { + // 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(); + + // let len = (*acl_serial).length as usize + 5; + // if len > buf.len() { + // return Err(()); + // } + + // core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); + + // Ok(len) + // } else { + // 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 len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; + // if len > buf.len() { + // return Err(()); + // } + + // core::ptr::copy(evt_serial_buf, buf.as_mut_ptr(), len); + + // Ok(len) + // } + // } + + 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) + } + } + } +} + +impl Drop for EvtBox { + fn drop(&mut self) { + use crate::ipcc::IpccExt; + let mut ipcc = unsafe { crate::Peripherals::steal() }.IPCC.constrain(); + mm::MemoryManager::evt_drop(self.ptr, &mut ipcc); + } +} diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs index cf479730..588b3291 100644 --- a/embassy-stm32/src/tl_mbox/mm.rs +++ b/embassy-stm32/src/tl_mbox/mm.rs @@ -1,10 +1,12 @@ use core::mem::MaybeUninit; -use super::unsafe_linked_list::LST_init_head; +use super::evt::EvtPacket; +use super::unsafe_linked_list::{LST_init_head, LST_insert_tail, LST_is_empty, LST_remove_head}; use super::{ - MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, - TL_MEM_MANAGER_TABLE, + channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, + SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE, }; +use crate::ipcc::Ipcc; pub struct MemoryManager; @@ -27,4 +29,43 @@ impl MemoryManager { MemoryManager } + + pub fn evt_handler(ipcc: &mut Ipcc) { + ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, false); + Self::send_free_buf(); + ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); + } + + pub fn evt_drop(evt: *mut EvtPacket, ipcc: &mut Ipcc) { + unsafe { + let list_node = evt.cast(); + + LST_insert_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); + } + + let channel_is_busy = ipcc.c1_is_active_flag(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); + + // postpone event buffer freeing to IPCC interrupt handler + if channel_is_busy { + ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, true); + } else { + Self::send_free_buf(); + ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); + } + } + + fn send_free_buf() { + unsafe { + let mut node_ptr = core::ptr::null_mut(); + let node_ptr_ptr: *mut _ = &mut node_ptr; + + while !LST_is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { + LST_remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), node_ptr_ptr); + LST_insert_tail( + (*(*TL_REF_TABLE.as_ptr()).mem_manager_table).pevt_free_buffer_queue, + node_ptr, + ); + } + } + } } diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs index 0cee26b7..3651b8ea 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32/src/tl_mbox/mod.rs @@ -1,20 +1,27 @@ use core::mem::MaybeUninit; use bit_field::BitField; +use embassy_cortex_m::interrupt::InterruptExt; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::channel::Channel; use self::ble::Ble; use self::cmd::{AclDataPacket, CmdPacket}; -use self::evt::CsEvt; +use self::evt::{CsEvt, EvtBox}; use self::mm::MemoryManager; +use self::shci::{shci_ble_init, ShciBleInitCmdParam}; use self::sys::Sys; use self::unsafe_linked_list::LinkedListNode; +use crate::_generated::interrupt::{IPCC_C1_RX, IPCC_C1_TX}; use crate::ipcc::Ipcc; mod ble; mod channels; mod cmd; +mod consts; mod evt; mod mm; +mod shci; mod sys; mod unsafe_linked_list; @@ -236,18 +243,14 @@ static mut FREE_BUFF_QUEUE: MaybeUninit = MaybeUninit::uninit(); // not in shared RAM static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit = MaybeUninit::uninit(); -#[allow(dead_code)] // Not used currently but reserved -#[link_section = "MB_MEM1"] -static mut TRACES_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); - #[link_section = "MB_MEM2"] static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = MaybeUninit::uninit(); -#[link_section = "MB_MEM1"] +#[link_section = "MB_MEM2"] static mut EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); -#[link_section = "MB_MEM1"] +#[link_section = "MB_MEM2"] static mut SYSTEM_EVT_QUEUE: MaybeUninit = MaybeUninit::uninit(); #[link_section = "MB_MEM2"] @@ -271,6 +274,9 @@ static mut BLE_CMD_BUFFER: MaybeUninit = MaybeUninit::uninit(); // "magic" numbers from ST ---v---v static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); +// TODO: get a better size, this is a placeholder +pub(crate) static TL_CHANNEL: Channel = Channel::new(); + pub struct TlMbox { _sys: Sys, _ble: Ble, @@ -279,7 +285,7 @@ pub struct TlMbox { impl TlMbox { /// initializes low-level transport between CPU1 and BLE stack on CPU2 - pub fn init(ipcc: &mut Ipcc) -> TlMbox { + pub fn init(ipcc: &mut Ipcc, rx_irq: IPCC_C1_RX, tx_irq: IPCC_C1_TX) -> TlMbox { unsafe { TL_REF_TABLE = MaybeUninit::new(RefTable { device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(), @@ -320,6 +326,24 @@ impl TlMbox { let _ble = Ble::new(ipcc); let _mm = MemoryManager::new(); + rx_irq.disable(); + tx_irq.disable(); + + rx_irq.set_handler_context(ipcc.as_mut_ptr() as *mut ()); + tx_irq.set_handler_context(ipcc.as_mut_ptr() as *mut ()); + + rx_irq.set_handler(|ipcc| { + let ipcc: &mut Ipcc = unsafe { &mut *ipcc.cast() }; + Self::interrupt_ipcc_rx_handler(ipcc); + }); + tx_irq.set_handler(|ipcc| { + let ipcc: &mut Ipcc = unsafe { &mut *ipcc.cast() }; + Self::interrupt_ipcc_tx_handler(ipcc); + }); + + rx_irq.enable(); + tx_irq.enable(); + TlMbox { _sys, _ble, _mm } } @@ -333,4 +357,41 @@ impl TlMbox { None } } + + pub fn shci_ble_init(&self, ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { + shci_ble_init(ipcc, param); + } + + pub fn send_ble_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { + ble::Ble::send_cmd(ipcc, buf); + } + + // pub fn send_sys_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { + // sys::Sys::send_cmd(ipcc, buf); + // } + + pub async fn read(&self) -> EvtBox { + TL_CHANNEL.recv().await + } + + fn interrupt_ipcc_rx_handler(ipcc: &mut Ipcc) { + if ipcc.is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { + sys::Sys::evt_handler(ipcc); + } else if ipcc.is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { + ble::Ble::evt_handler(ipcc); + } else { + todo!() + } + } + + fn interrupt_ipcc_tx_handler(ipcc: &mut Ipcc) { + if ipcc.is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { + // TODO: handle this case + let _ = sys::Sys::cmd_evt_handler(ipcc); + } else if ipcc.is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { + mm::MemoryManager::evt_handler(ipcc); + } else { + todo!() + } + } } diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32/src/tl_mbox/shci.rs new file mode 100644 index 00000000..7f224cb1 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/shci.rs @@ -0,0 +1,101 @@ +//! HCI commands for system channel + +use super::cmd::CmdPacket; +use super::consts::TlPacketType; +use super::{channels, TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE, TL_SYS_TABLE}; +use crate::ipcc::Ipcc; + +const SCHI_OPCODE_BLE_INIT: u16 = 0xfc66; +pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; +#[allow(dead_code)] +const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; + +#[derive(Clone, Copy)] +#[repr(C, packed)] +pub struct ShciBleInitCmdParam { + /// NOT USED CURRENTLY + pub p_ble_buffer_address: u32, + + /// Size of the Buffer allocated in pBleBufferAddress + pub ble_buffer_size: u32, + + pub num_attr_record: u16, + pub num_attr_serv: u16, + pub attr_value_arr_size: u16, + pub num_of_links: u8, + pub extended_packet_length_enable: u8, + pub pr_write_list_size: u8, + pub mb_lock_count: u8, + + pub att_mtu: u16, + pub slave_sca: u16, + pub master_sca: u8, + pub ls_source: u8, + pub max_conn_event_length: u32, + pub hs_startup_time: u16, + pub viterbi_enable: u8, + pub ll_only: u8, + pub hw_version: u8, +} + +impl Default for ShciBleInitCmdParam { + fn default() -> Self { + Self { + p_ble_buffer_address: 0, + ble_buffer_size: 0, + num_attr_record: 68, + num_attr_serv: 8, + attr_value_arr_size: 1344, + num_of_links: 2, + extended_packet_length_enable: 1, + pr_write_list_size: 0x3A, + mb_lock_count: 0x79, + att_mtu: 156, + slave_sca: 500, + master_sca: 0, + ls_source: 1, + max_conn_event_length: 0xFFFFFFFF, + hs_startup_time: 0x148, + viterbi_enable: 1, + ll_only: 0, + hw_version: 0, + } + } +} + +#[derive(Clone, Copy, Default)] +#[repr(C, packed)] +pub struct ShciHeader { + metadata: [u32; 3], +} + +#[derive(Clone, Copy)] +#[repr(C, packed)] +pub struct ShciBleInitCmdPacket { + header: ShciHeader, + param: ShciBleInitCmdParam, +} + +pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { + let mut packet = ShciBleInitCmdPacket { + header: ShciHeader::default(), + param, + }; + + let packet_ptr: *mut ShciBleInitCmdPacket = &mut packet; + + unsafe { + let cmd_ptr: *mut CmdPacket = packet_ptr.cast(); + + (*cmd_ptr).cmd_serial.cmd.cmd_code = SCHI_OPCODE_BLE_INIT; + (*cmd_ptr).cmd_serial.cmd.payload_len = core::mem::size_of::() as u8; + + let mut cmd_buf = &mut *(*TL_SYS_TABLE.as_mut_ptr()).pcmd_buffer; + core::ptr::write(cmd_buf, *cmd_ptr); + + cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8; + + ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); + ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); + } +} diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs index 13ae7f9f..12265755 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32/src/tl_mbox/sys.rs @@ -1,13 +1,18 @@ use core::mem::MaybeUninit; -use super::unsafe_linked_list::LST_init_head; -use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE}; +use embassy_futures::block_on; + +use super::cmd::{CmdPacket, CmdSerial}; +use super::consts::TlPacketType; +use super::evt::{CcEvt, EvtBox, EvtSerial}; +use super::unsafe_linked_list::{LST_init_head, LST_is_empty, LST_remove_head}; +use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_CHANNEL, TL_REF_TABLE, TL_SYS_TABLE}; use crate::ipcc::Ipcc; pub struct Sys; impl Sys { - pub fn new(ipcc: &mut Ipcc) -> Self { + pub(crate) fn new(ipcc: &mut Ipcc) -> Self { unsafe { LST_init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); @@ -21,4 +26,62 @@ impl Sys { Sys } + + pub(crate) fn evt_handler(ipcc: &mut Ipcc) { + unsafe { + let mut node_ptr = core::ptr::null_mut(); + let node_ptr_ptr: *mut _ = &mut node_ptr; + + while !LST_is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { + LST_remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); + + let event = node_ptr.cast(); + let event = EvtBox::new(event); + + // TODO: not really happy about this + block_on(TL_CHANNEL.send(event)); + } + } + + ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); + } + + pub(crate) fn cmd_evt_handler(ipcc: &mut Ipcc) -> CcEvt { + ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); + + // ST's command response data structure is really convoluted. + // + // for command response events on SYS channel, the header is missing + // and one should: + // 1. interpret the content of CMD_BUFFER as CmdPacket + // 2. Access CmdPacket's cmdserial field and interpret its content as EvtSerial + // 3. Access EvtSerial's evt field (as Evt) and interpret its payload as CcEvt + // 4. CcEvt type is the actual SHCI response + // 5. profit + unsafe { + let cmd: *const CmdPacket = (*TL_SYS_TABLE.as_ptr()).pcmd_buffer; + let cmd_serial: *const CmdSerial = &(*cmd).cmd_serial; + let evt_serial: *const EvtSerial = cmd_serial.cast(); + let cc = (*evt_serial).evt.payload.as_ptr().cast(); + *cc + } + } + + #[allow(dead_code)] + pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { + unsafe { + // TODO: check this + let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; + let cmd_serial: *mut CmdSerial = &mut (*cmd_buffer).cmd_serial; + let cmd_serial_buf = cmd_serial.cast(); + + core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len()); + + let mut cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; + cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8; + + ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); + ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); + } + } } diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 6876526a..ccd01cbc 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs @@ -4,6 +4,7 @@ use defmt::*; use embassy_executor::Spawner; +use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc}; use embassy_stm32::tl_mbox::TlMbox; use embassy_time::{Duration, Timer}; @@ -40,7 +41,10 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let mut ipcc = Ipcc::new(p.IPCC, config); - let mbox = TlMbox::init(&mut ipcc); + let rx_irq = interrupt::take!(IPCC_C1_RX); + let tx_irq = interrupt::take!(IPCC_C1_TX); + + let mbox = TlMbox::init(&mut ipcc, rx_irq, tx_irq); loop { let wireless_fw_info = mbox.wireless_fw_info(); diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs new file mode 100644 index 00000000..315172df --- /dev/null +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs @@ -0,0 +1,96 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::interrupt; +use embassy_stm32::ipcc::{Config, Ipcc}; +use embassy_stm32::tl_mbox::TlMbox; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + /* + How to make this work: + + - Obtain a NUCLEO-STM32WB55 from your preferred supplier. + - Download and Install STM32CubeProgrammer. + - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from + gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x + - Open STM32CubeProgrammer + - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. + - Once complete, click connect to connect to the device. + - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services". + - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the + stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Disconnect from the device. + - In the examples folder for stm32wb, modify the memory.x file to match your target device. + - Run this example. + + Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. + */ + + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let config = Config::default(); + let mut ipcc = Ipcc::new(p.IPCC, config); + + let rx_irq = interrupt::take!(IPCC_C1_RX); + let tx_irq = interrupt::take!(IPCC_C1_TX); + + let mbox = TlMbox::init(&mut ipcc, rx_irq, tx_irq); + + // initialize ble stack, does not return a response + // mbox.shci_ble_init(&mut ipcc, Default::default()); + + info!("waiting for coprocessor to boot"); + let event_box = mbox.read().await; + + let mut payload = [0u8; 6]; + event_box.copy_into_slice(&mut payload).unwrap(); + + let event_packet = event_box.evt(); + let kind = event_packet.evt_serial.kind; + + // means recieved SYS event, which indicates in this case that the coprocessor is ready + if kind == 0x12 { + let code = event_packet.evt_serial.evt.evt_code; + let payload_len = event_packet.evt_serial.evt.payload_len; + + info!( + "==> kind: {:#04x}, code: {:#04x}, payload_length: {}, payload: {:#04x}", + kind, + code, + payload_len, + payload[3..] + ); + } + + mbox.shci_ble_init(&mut ipcc, Default::default()); + + info!("resetting BLE"); + mbox.send_ble_cmd(&mut ipcc, &[0x01, 0x03, 0x0c]); + + let event_box = mbox.read().await; + + let mut payload = [0u8; 7]; + event_box.copy_into_slice(&mut payload).unwrap(); + + let event_packet = event_box.evt(); + let kind = event_packet.evt_serial.kind; + + let code = event_packet.evt_serial.evt.evt_code; + let payload_len = event_packet.evt_serial.evt.payload_len; + + info!( + "==> kind: {:#04x}, code: {:#04x}, payload_length: {}, payload: {:#04x}", + kind, code, payload_len, payload + ); + + loop {} +} From a8953b5c669da3403437e012a3d106b100e2a1f4 Mon Sep 17 00:00:00 2001 From: goueslati Date: Mon, 15 May 2023 10:34:52 +0100 Subject: [PATCH 03/14] cleanup --- embassy-stm32/src/tl_mbox/evt.rs | 33 -------------------------------- 1 file changed, 33 deletions(-) diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs index 8ae2a255..0ecd4dab 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32/src/tl_mbox/evt.rs @@ -95,39 +95,6 @@ impl EvtBox { /// writes an underlying [`EvtPacket`] into the provided buffer. Returns the number of bytes that were /// written. Returns an error if event kind is unkown or if provided buffer size is not enough pub fn copy_into_slice(&self, buf: &mut [u8]) -> Result { - // TODO: double check this - // unsafe { - // let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; - - // if let TlPacketType::AclData = evt_kind { - // 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(); - - // let len = (*acl_serial).length as usize + 5; - // if len > buf.len() { - // return Err(()); - // } - - // core::ptr::copy(acl_serial_buf, buf.as_mut_ptr(), len); - - // Ok(len) - // } else { - // 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 len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE; - // if len > buf.len() { - // return Err(()); - // } - - // core::ptr::copy(evt_serial_buf, buf.as_mut_ptr(), len); - - // Ok(len) - // } - // } - unsafe { let evt_kind = TlPacketType::try_from((*self.ptr).evt_serial.kind)?; From d736c9205c1cfff2b4f5e83fd7d70a6e1b09a08d Mon Sep 17 00:00:00 2001 From: goueslati Date: Fri, 19 May 2023 15:40:09 +0100 Subject: [PATCH 04/14] updated test case --- tests/stm32/src/bin/ble.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/stm32/src/bin/ble.rs b/tests/stm32/src/bin/ble.rs index f4c864c6..0f711fda 100644 --- a/tests/stm32/src/bin/ble.rs +++ b/tests/stm32/src/bin/ble.rs @@ -20,7 +20,13 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let mut ipcc = Ipcc::new(p.IPCC, config); - let mbox = TlMbox::init(&mut ipcc); + let config = Config::default(); + let mut ipcc = Ipcc::new(p.IPCC, config); + + let rx_irq = interrupt::take!(IPCC_C1_RX); + let tx_irq = interrupt::take!(IPCC_C1_TX); + + let mbox = TlMbox::init(&mut ipcc, rx_irq, tx_irq); loop { let wireless_fw_info = mbox.wireless_fw_info(); From 661b1f33738e56cd1b6092c0e3f014cb8e9726d3 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 May 2023 10:10:21 -0500 Subject: [PATCH 05/14] stm32/ipcc: remove constrain --- embassy-stm32/src/ipcc.rs | 15 ++++----------- embassy-stm32/src/tl_mbox/evt.rs | 5 +++-- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 9af5f171..2b9caf8e 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs @@ -35,6 +35,10 @@ pub struct Ipcc<'d> { impl<'d> Ipcc<'d> { pub fn new(peri: impl Peripheral

+ 'd, _config: Config) -> Self { + Self::new_inner(peri) + } + + pub(crate) fn new_inner(peri: impl Peripheral

+ 'd) -> Self { into_ref!(peri); Self { _peri: peri } @@ -180,14 +184,3 @@ unsafe fn _configure_pwr() { // set RF wake-up clock = LSE rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); } - -// TODO: if anyone has a better idea, please let me know -/// extension trait that constrains the [`Ipcc`] peripheral -pub trait IpccExt<'d> { - fn constrain(self) -> Ipcc<'d>; -} -impl<'d> IpccExt<'d> for IPCC { - fn constrain(self) -> Ipcc<'d> { - Ipcc { _peri: self.into_ref() } - } -} diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs index 0ecd4dab..770133f2 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32/src/tl_mbox/evt.rs @@ -131,8 +131,9 @@ impl EvtBox { impl Drop for EvtBox { fn drop(&mut self) { - use crate::ipcc::IpccExt; - let mut ipcc = unsafe { crate::Peripherals::steal() }.IPCC.constrain(); + use crate::ipcc::Ipcc; + + let mut ipcc = Ipcc::new_inner(unsafe { crate::Peripherals::steal() }.IPCC); mm::MemoryManager::evt_drop(self.ptr, &mut ipcc); } } From 5e86188c25331d16fb6bfe071ff4485f1a51d664 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 May 2023 10:11:29 -0500 Subject: [PATCH 06/14] stm32/ipcc: cleanup naming --- embassy-stm32/src/tl_mbox/ble.rs | 8 +- embassy-stm32/src/tl_mbox/mm.rs | 14 +- embassy-stm32/src/tl_mbox/sys.rs | 8 +- .../src/tl_mbox/unsafe_linked_list.rs | 184 +++++++++--------- 4 files changed, 108 insertions(+), 106 deletions(-) diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs index a285e314..84c6307f 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32/src/tl_mbox/ble.rs @@ -5,7 +5,7 @@ use embassy_futures::block_on; use super::cmd::CmdSerial; use super::consts::TlPacketType; use super::evt::EvtBox; -use super::unsafe_linked_list::{LST_init_head, LST_is_empty, LST_remove_head}; +use super::unsafe_linked_list::LinkedListNode; use super::{ channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_CHANNEL, TL_REF_TABLE, @@ -18,7 +18,7 @@ pub struct Ble; impl Ble { pub(crate) fn new(ipcc: &mut Ipcc) -> Self { unsafe { - LST_init_head(EVT_QUEUE.as_mut_ptr()); + LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); TL_BLE_TABLE = MaybeUninit::new(BleTable { pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), @@ -38,8 +38,8 @@ impl Ble { let mut node_ptr = core::ptr::null_mut(); let node_ptr_ptr: *mut _ = &mut node_ptr; - while !LST_is_empty(EVT_QUEUE.as_mut_ptr()) { - LST_remove_head(EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); + while !LinkedListNode::is_empty(EVT_QUEUE.as_mut_ptr()) { + LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); let event = node_ptr.cast(); let event = EvtBox::new(event); diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs index 588b3291..f99ffa39 100644 --- a/embassy-stm32/src/tl_mbox/mm.rs +++ b/embassy-stm32/src/tl_mbox/mm.rs @@ -1,7 +1,7 @@ use core::mem::MaybeUninit; use super::evt::EvtPacket; -use super::unsafe_linked_list::{LST_init_head, LST_insert_tail, LST_is_empty, LST_remove_head}; +use super::unsafe_linked_list::LinkedListNode; use super::{ channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE, @@ -13,8 +13,8 @@ pub struct MemoryManager; impl MemoryManager { pub fn new() -> Self { unsafe { - LST_init_head(FREE_BUFF_QUEUE.as_mut_ptr()); - LST_init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); + LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr()); + LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); TL_MEM_MANAGER_TABLE = MaybeUninit::new(MemManagerTable { spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), @@ -40,7 +40,7 @@ impl MemoryManager { unsafe { let list_node = evt.cast(); - LST_insert_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); + LinkedListNode::remove_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); } let channel_is_busy = ipcc.c1_is_active_flag(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); @@ -59,9 +59,9 @@ impl MemoryManager { let mut node_ptr = core::ptr::null_mut(); let node_ptr_ptr: *mut _ = &mut node_ptr; - while !LST_is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { - LST_remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), node_ptr_ptr); - LST_insert_tail( + while !LinkedListNode::is_empty(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()) { + LinkedListNode::remove_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), node_ptr_ptr); + LinkedListNode::insert_tail( (*(*TL_REF_TABLE.as_ptr()).mem_manager_table).pevt_free_buffer_queue, node_ptr, ); diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs index 12265755..d22dfb58 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32/src/tl_mbox/sys.rs @@ -5,7 +5,7 @@ use embassy_futures::block_on; use super::cmd::{CmdPacket, CmdSerial}; use super::consts::TlPacketType; use super::evt::{CcEvt, EvtBox, EvtSerial}; -use super::unsafe_linked_list::{LST_init_head, LST_is_empty, LST_remove_head}; +use super::unsafe_linked_list::LinkedListNode; use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_CHANNEL, TL_REF_TABLE, TL_SYS_TABLE}; use crate::ipcc::Ipcc; @@ -14,7 +14,7 @@ pub struct Sys; impl Sys { pub(crate) fn new(ipcc: &mut Ipcc) -> Self { unsafe { - LST_init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); + LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); TL_SYS_TABLE = MaybeUninit::new(SysTable { pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), @@ -32,8 +32,8 @@ impl Sys { let mut node_ptr = core::ptr::null_mut(); let node_ptr_ptr: *mut _ = &mut node_ptr; - while !LST_is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { - LST_remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); + while !LinkedListNode::is_empty(SYSTEM_EVT_QUEUE.as_mut_ptr()) { + LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr(), node_ptr_ptr); let event = node_ptr.cast(); let event = EvtBox::new(event); diff --git a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs index 9caf01d1..45bf5bda 100644 --- a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs +++ b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs @@ -29,95 +29,97 @@ impl Default for LinkedListNode { } } -pub unsafe fn LST_init_head(mut listHead: *mut LinkedListNode) { - (*listHead).next = listHead; - (*listHead).prev = listHead; -} - -pub unsafe fn LST_is_empty(mut listHead: *mut LinkedListNode) -> bool { - interrupt::free(|_| ((*listHead).next) == listHead) -} - -pub unsafe fn LST_insert_head(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { - interrupt::free(|_| { - (*node).next = (*listHead).next; - (*node).prev = listHead; - (*listHead).next = node; - (*(*node).next).prev = node; - }); -} - -pub unsafe fn LST_insert_tail(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { - interrupt::free(|_| { - (*node).next = listHead; - (*node).prev = (*listHead).prev; - (*listHead).prev = node; - (*(*node).prev).next = node; - }); -} - -pub unsafe fn LST_remove_node(mut node: *mut LinkedListNode) { - interrupt::free(|_| { - (*(*node).prev).next = (*node).next; - (*(*node).next).prev = (*node).prev; - }); -} - -pub unsafe fn LST_remove_head(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { - interrupt::free(|_| { - *node = (*listHead).next; - LST_remove_node((*listHead).next); - }); -} - -pub unsafe fn LST_remove_tail(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { - interrupt::free(|_| { - *node = (*listHead).prev; - LST_remove_node((*listHead).prev); - }); -} - -pub unsafe fn LST_insert_node_after(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { - interrupt::free(|_| { - (*node).next = (*ref_node).next; - (*node).prev = ref_node; - (*ref_node).next = node; - (*(*node).next).prev = node; - }); -} - -pub unsafe fn LST_insert_node_before(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { - interrupt::free(|_| { - (*node).next = ref_node; - (*node).prev = (*ref_node).prev; - (*ref_node).prev = node; - (*(*node).prev).next = node; - }); -} - -pub unsafe fn LST_get_size(mut listHead: *mut LinkedListNode) -> usize { - interrupt::free(|_| { - let mut size = 0; - let mut temp: *mut LinkedListNode = core::ptr::null_mut::(); - - temp = (*listHead).next; - while temp != listHead { - size += 1; - temp = (*temp).next - } - - size - }) -} - -pub unsafe fn LST_get_next_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { - interrupt::free(|_| { - *node = (*ref_node).next; - }); -} - -pub unsafe fn LST_get_prev_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { - interrupt::free(|_| { - *node = (*ref_node).prev; - }); +impl LinkedListNode { + pub unsafe fn init_head(mut listHead: *mut LinkedListNode) { + (*listHead).next = listHead; + (*listHead).prev = listHead; + } + + pub unsafe fn is_empty(mut listHead: *mut LinkedListNode) -> bool { + interrupt::free(|_| ((*listHead).next) == listHead) + } + + pub unsafe fn insert_head(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { + interrupt::free(|_| { + (*node).next = (*listHead).next; + (*node).prev = listHead; + (*listHead).next = node; + (*(*node).next).prev = node; + }); + } + + pub unsafe fn insert_tail(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { + interrupt::free(|_| { + (*node).next = listHead; + (*node).prev = (*listHead).prev; + (*listHead).prev = node; + (*(*node).prev).next = node; + }); + } + + pub unsafe fn remove_node(mut node: *mut LinkedListNode) { + interrupt::free(|_| { + (*(*node).prev).next = (*node).next; + (*(*node).next).prev = (*node).prev; + }); + } + + pub unsafe fn remove_head(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + interrupt::free(|_| { + *node = (*listHead).next; + Self::remove_node((*listHead).next); + }); + } + + pub unsafe fn remove_tail(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + interrupt::free(|_| { + *node = (*listHead).prev; + Self::remove_node((*listHead).prev); + }); + } + + pub unsafe fn insert_node_after(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { + interrupt::free(|_| { + (*node).next = (*ref_node).next; + (*node).prev = ref_node; + (*ref_node).next = node; + (*(*node).next).prev = node; + }); + } + + pub unsafe fn insert_node_before(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { + interrupt::free(|_| { + (*node).next = ref_node; + (*node).prev = (*ref_node).prev; + (*ref_node).prev = node; + (*(*node).prev).next = node; + }); + } + + pub unsafe fn get_size(mut listHead: *mut LinkedListNode) -> usize { + interrupt::free(|_| { + let mut size = 0; + let mut temp: *mut LinkedListNode = core::ptr::null_mut::(); + + temp = (*listHead).next; + while temp != listHead { + size += 1; + temp = (*temp).next + } + + size + }) + } + + pub unsafe fn get_next_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + interrupt::free(|_| { + *node = (*ref_node).next; + }); + } + + pub unsafe fn get_prev_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + interrupt::free(|_| { + *node = (*ref_node).prev; + }); + } } From 383bef1711d5d6464e49dfe9722e0fa3dd5a4ad9 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 May 2023 10:20:35 -0500 Subject: [PATCH 07/14] stm32/ipcc: naming --- .../src/tl_mbox/unsafe_linked_list.rs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs index 45bf5bda..482e2bf5 100644 --- a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs +++ b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs @@ -30,29 +30,29 @@ impl Default for LinkedListNode { } impl LinkedListNode { - pub unsafe fn init_head(mut listHead: *mut LinkedListNode) { - (*listHead).next = listHead; - (*listHead).prev = listHead; + pub unsafe fn init_head(mut list_head: *mut LinkedListNode) { + (*list_head).next = list_head; + (*list_head).prev = list_head; } - pub unsafe fn is_empty(mut listHead: *mut LinkedListNode) -> bool { - interrupt::free(|_| ((*listHead).next) == listHead) + pub unsafe fn is_empty(mut list_head: *mut LinkedListNode) -> bool { + interrupt::free(|_| ((*list_head).next) == list_head) } - pub unsafe fn insert_head(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { + pub unsafe fn insert_head(mut list_head: *mut LinkedListNode, mut node: *mut LinkedListNode) { interrupt::free(|_| { - (*node).next = (*listHead).next; - (*node).prev = listHead; - (*listHead).next = node; + (*node).next = (*list_head).next; + (*node).prev = list_head; + (*list_head).next = node; (*(*node).next).prev = node; }); } - pub unsafe fn insert_tail(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { + pub unsafe fn insert_tail(mut list_head: *mut LinkedListNode, mut node: *mut LinkedListNode) { interrupt::free(|_| { - (*node).next = listHead; - (*node).prev = (*listHead).prev; - (*listHead).prev = node; + (*node).next = list_head; + (*node).prev = (*list_head).prev; + (*list_head).prev = node; (*(*node).prev).next = node; }); } @@ -64,17 +64,17 @@ impl LinkedListNode { }); } - pub unsafe fn remove_head(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + pub unsafe fn remove_head(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { interrupt::free(|_| { - *node = (*listHead).next; - Self::remove_node((*listHead).next); + *node = (*list_head).next; + Self::remove_node((*list_head).next); }); } - pub unsafe fn remove_tail(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { + pub unsafe fn remove_tail(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { interrupt::free(|_| { - *node = (*listHead).prev; - Self::remove_node((*listHead).prev); + *node = (*list_head).prev; + Self::remove_node((*list_head).prev); }); } @@ -96,13 +96,13 @@ impl LinkedListNode { }); } - pub unsafe fn get_size(mut listHead: *mut LinkedListNode) -> usize { + pub unsafe fn get_size(mut list_head: *mut LinkedListNode) -> usize { interrupt::free(|_| { let mut size = 0; let mut temp: *mut LinkedListNode = core::ptr::null_mut::(); - temp = (*listHead).next; - while temp != listHead { + temp = (*list_head).next; + while temp != list_head { size += 1; temp = (*temp).next } From 7f702fd6f19811a65e5ee659a5182fc291524e51 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sat, 20 May 2023 11:29:53 -0500 Subject: [PATCH 08/14] stm32/ipcc: fix warnings --- embassy-stm32/src/tl_mbox/ble.rs | 2 +- embassy-stm32/src/tl_mbox/shci.rs | 2 +- embassy-stm32/src/tl_mbox/sys.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs index 84c6307f..d8bf14d4 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32/src/tl_mbox/ble.rs @@ -59,7 +59,7 @@ impl Ble { core::ptr::copy(buf.as_ptr(), pcmd_serial_buf, buf.len()); - let mut cmd_packet = &mut *(*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; + let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8; } diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32/src/tl_mbox/shci.rs index 7f224cb1..61fd9e4a 100644 --- a/embassy-stm32/src/tl_mbox/shci.rs +++ b/embassy-stm32/src/tl_mbox/shci.rs @@ -90,7 +90,7 @@ pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { (*cmd_ptr).cmd_serial.cmd.cmd_code = SCHI_OPCODE_BLE_INIT; (*cmd_ptr).cmd_serial.cmd.payload_len = core::mem::size_of::() as u8; - let mut cmd_buf = &mut *(*TL_SYS_TABLE.as_mut_ptr()).pcmd_buffer; + let cmd_buf = &mut *(*TL_SYS_TABLE.as_mut_ptr()).pcmd_buffer; core::ptr::write(cmd_buf, *cmd_ptr); cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8; diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs index d22dfb58..31ebde72 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32/src/tl_mbox/sys.rs @@ -77,7 +77,7 @@ impl Sys { core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len()); - let mut cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; + let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8; ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); From eb09d7d67174d4b1f94e84e452f2920dd5fe442b Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 21 May 2023 18:39:13 -0500 Subject: [PATCH 09/14] stm32/ipcc: update doc --- examples/stm32wb/src/bin/tl_mbox.rs | 1 + examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index ccd01cbc..acbc60c8 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs @@ -28,6 +28,7 @@ async fn main(_spawner: Spawner) { - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Select "Start Wireless Stack". - Disconnect from the device. - In the examples folder for stm32wb, modify the memory.x file to match your target device. - Run this example. diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs index 315172df..ff506338 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs @@ -27,6 +27,7 @@ async fn main(_spawner: Spawner) { - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Select "Start Wireless Stack". - Disconnect from the device. - In the examples folder for stm32wb, modify the memory.x file to match your target device. - Run this example. From 1f65a4eb6f4e7e0c6f5e036f3ea97650b9637ad9 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 21 May 2023 18:40:29 -0500 Subject: [PATCH 10/14] stm32/ipcc: enable test --- tests/stm32/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index bd8d90ab..4ce05649 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -12,7 +12,7 @@ stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo -stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma"] # Nucleo +stm32wb55rg = ["embassy-stm32/stm32wb55rg", "ble", "not-gpdma"] # Nucleo stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board From d1dfaa190518df6adc66ab0716236bac3fe5f894 Mon Sep 17 00:00:00 2001 From: xoviat Date: Sun, 21 May 2023 20:18:26 -0500 Subject: [PATCH 11/14] stm32/ipcc: fix hil test --- examples/stm32wb/memory.x | 2 +- tests/stm32/build.rs | 3 +++ tests/stm32/memory_ble.x | 23 +++++++++++++++++++++++ tests/stm32/src/bin/ble.rs | 8 +++----- 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 tests/stm32/memory_ble.x diff --git a/examples/stm32wb/memory.x b/examples/stm32wb/memory.x index 5a07b7d1..e1f0530b 100644 --- a/examples/stm32wb/memory.x +++ b/examples/stm32wb/memory.x @@ -11,7 +11,7 @@ MEMORY } /* - Memory size for STM32WB55xC with 512K FLASH + Memory size for STM32WB55xG with 512K FLASH MEMORY { diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index 7ae31177..ca76b70b 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs @@ -12,6 +12,9 @@ fn main() -> Result<(), Box> { if cfg!(any(feature = "stm32f103c8", feature = "stm32c031c6")) { println!("cargo:rustc-link-arg-bins=-Tlink.x"); println!("cargo:rerun-if-changed=link.x"); + } else if cfg!(feature = "stm32wb55rg") { + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + fs::write(out.join("memory.x"), include_bytes!("memory_ble.x")).unwrap(); } else { println!("cargo:rustc-link-arg-bins=-Tlink_ram.x"); println!("cargo:rerun-if-changed=link_ram.x"); diff --git a/tests/stm32/memory_ble.x b/tests/stm32/memory_ble.x new file mode 100644 index 00000000..4332e2c7 --- /dev/null +++ b/tests/stm32/memory_ble.x @@ -0,0 +1,23 @@ +/* + Memory size for STM32WB55xG with 512K FLASH +*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K + RAM (xrw) : ORIGIN = 0x20000008, LENGTH = 0x2FFF8 + RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K +} + +/* Place stack at the end of SRAM1 */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); + +/* + * Scatter the mailbox interface memory sections in shared memory + */ +SECTIONS { + TL_REF_TABLE (NOLOAD) : { *(TL_REF_TABLE) } >RAM_SHARED + + MB_MEM1 (NOLOAD) : { *(MB_MEM1) } >RAM_SHARED + MB_MEM2 (NOLOAD) : { _sMB_MEM2 = . ; *(MB_MEM2) ; _eMB_MEM2 = . ; } >RAM_SHARED +} diff --git a/tests/stm32/src/bin/ble.rs b/tests/stm32/src/bin/ble.rs index 0f711fda..aedf9a38 100644 --- a/tests/stm32/src/bin/ble.rs +++ b/tests/stm32/src/bin/ble.rs @@ -7,6 +7,7 @@ #[path = "../example_common.rs"] mod example_common; use embassy_executor::Spawner; +use embassy_stm32::interrupt; use embassy_stm32::ipcc::{Config, Ipcc}; use embassy_stm32::tl_mbox::TlMbox; use embassy_time::{Duration, Timer}; @@ -20,9 +21,6 @@ async fn main(_spawner: Spawner) { let config = Config::default(); let mut ipcc = Ipcc::new(p.IPCC, config); - let config = Config::default(); - let mut ipcc = Ipcc::new(p.IPCC, config); - let rx_irq = interrupt::take!(IPCC_C1_RX); let tx_irq = interrupt::take!(IPCC_C1_TX); @@ -31,7 +29,7 @@ async fn main(_spawner: Spawner) { loop { let wireless_fw_info = mbox.wireless_fw_info(); match wireless_fw_info { - None => error!("not yet initialized"), + None => {} Some(fw_info) => { let version_major = fw_info.version_major(); let version_minor = fw_info.version_minor(); @@ -49,7 +47,7 @@ async fn main(_spawner: Spawner) { } } - Timer::after(Duration::from_millis(500)).await; + Timer::after(Duration::from_millis(50)).await; } info!("Test OK"); From 12720737e1c099b5626e45946b4f92b606922c2d Mon Sep 17 00:00:00 2001 From: goueslati Date: Mon, 22 May 2023 10:52:05 +0100 Subject: [PATCH 12/14] stm32/ipcc: fix incorrect example --- examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs index ff506338..be606399 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs @@ -75,7 +75,7 @@ async fn main(_spawner: Spawner) { mbox.shci_ble_init(&mut ipcc, Default::default()); info!("resetting BLE"); - mbox.send_ble_cmd(&mut ipcc, &[0x01, 0x03, 0x0c]); + mbox.send_ble_cmd(&mut ipcc, &[0x01, 0x03, 0x0c, 0x00, 0x00]); let event_box = mbox.read().await; From 059ab358a5bd9102df09e511b190a70684e9c261 Mon Sep 17 00:00:00 2001 From: goueslati Date: Mon, 22 May 2023 11:13:22 +0100 Subject: [PATCH 13/14] stm32/ipcc: uncomment shci init cmd --- examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs index be606399..1008e1e4 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs @@ -47,7 +47,7 @@ async fn main(_spawner: Spawner) { let mbox = TlMbox::init(&mut ipcc, rx_irq, tx_irq); // initialize ble stack, does not return a response - // mbox.shci_ble_init(&mut ipcc, Default::default()); + mbox.shci_ble_init(&mut ipcc, Default::default()); info!("waiting for coprocessor to boot"); let event_box = mbox.read().await; From 64092169e3133b572626c1efa106963139a63b3f Mon Sep 17 00:00:00 2001 From: xoviat Date: Mon, 22 May 2023 20:14:37 -0500 Subject: [PATCH 14/14] stm32/ipcc: disable test --- tests/stm32/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 4ce05649..bd8d90ab 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml @@ -12,7 +12,7 @@ stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma"] # Nucleo stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma"] # Nucleo -stm32wb55rg = ["embassy-stm32/stm32wb55rg", "ble", "not-gpdma"] # Nucleo +stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma"] # Nucleo stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board