stm32/ipcc: refactor tl_mbox

This commit is contained in:
xoviat 2023-05-27 15:05:23 -05:00
parent 7e501855fc
commit 37e104a6b3
7 changed files with 51 additions and 45 deletions

View file

@ -1,5 +1,3 @@
use core::mem::MaybeUninit;
use embassy_futures::block_on;
use super::cmd::CmdSerial;
@ -10,17 +8,17 @@ 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;
use crate::tl_mbox::ipcc::Ipcc;
pub struct Ble;
impl Ble {
pub(crate) fn new() -> Self {
pub fn enable() {
unsafe {
LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
TL_BLE_TABLE = MaybeUninit::new(BleTable {
TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable {
pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(),
pcs_buffer: CS_BUFFER.as_mut_ptr().cast(),
pevt_queue: EVT_QUEUE.as_ptr().cast(),
@ -29,11 +27,9 @@ impl Ble {
}
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true);
Ble
}
pub(crate) fn evt_handler() {
pub fn evt_handler() {
unsafe {
let mut node_ptr = core::ptr::null_mut();
let node_ptr_ptr: *mut _ = &mut node_ptr;
@ -51,7 +47,7 @@ impl Ble {
Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL);
}
pub(crate) fn send_cmd(buf: &[u8]) {
pub fn send_cmd(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;

View file

@ -50,7 +50,7 @@
//!
pub mod cpu1 {
use crate::ipcc::IpccChannel;
use crate::tl_mbox::ipcc::IpccChannel;
// Not used currently but reserved
pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1;
@ -75,7 +75,7 @@ pub mod cpu1 {
}
pub mod cpu2 {
use crate::ipcc::IpccChannel;
use crate::tl_mbox::ipcc::IpccChannel;
pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1;
pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2;

View file

@ -3,7 +3,7 @@ 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;
use crate::tl_mbox::mm::MemoryManager;
/// the payload of [`Evt`] for a command status event
#[derive(Copy, Clone)]
@ -131,6 +131,6 @@ impl EvtBox {
impl Drop for EvtBox {
fn drop(&mut self) {
mm::MemoryManager::evt_drop(self.ptr);
MemoryManager::evt_drop(self.ptr);
}
}

View file

@ -1,22 +1,20 @@
use core::mem::MaybeUninit;
use super::evt::EvtPacket;
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,
};
use crate::ipcc::Ipcc;
use crate::tl_mbox::ipcc::Ipcc;
pub struct MemoryManager;
impl MemoryManager {
pub fn new() -> Self {
pub fn enable() {
unsafe {
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 {
TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable {
spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(),
spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(),
ble_pool: EVT_POOL.as_ptr().cast(),
@ -26,8 +24,6 @@ impl MemoryManager {
traces_pool_size: 0,
});
}
MemoryManager
}
pub fn evt_handler() {

View file

@ -1,7 +1,9 @@
use core::mem::MaybeUninit;
use atomic_polyfill::{compiler_fence, Ordering};
use bit_field::BitField;
use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;
@ -13,13 +15,16 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam};
use self::sys::Sys;
use self::unsafe_linked_list::LinkedListNode;
use crate::interrupt;
use crate::ipcc::{Config, Ipcc};
use crate::peripherals::IPCC;
pub use crate::tl_mbox::ipcc::Config;
use crate::tl_mbox::ipcc::Ipcc;
mod ble;
mod channels;
mod cmd;
mod consts;
mod evt;
mod ipcc;
mod mm;
mod shci;
mod sys;
@ -60,6 +65,8 @@ pub struct ReceiveInterruptHandler {}
impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler {
unsafe fn on_interrupt() {
// info!("ipcc rx interrupt");
if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) {
sys::Sys::evt_handler();
} else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) {
@ -74,6 +81,8 @@ pub struct TransmitInterruptHandler {}
impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler {
unsafe fn on_interrupt() {
// info!("ipcc tx interrupt");
if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) {
// TODO: handle this case
let _ = sys::Sys::cmd_evt_handler();
@ -307,21 +316,24 @@ static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251
// TODO: get a better size, this is a placeholder
pub(crate) static TL_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 5> = Channel::new();
pub struct TlMbox {
_sys: Sys,
_ble: Ble,
_mm: MemoryManager,
pub struct TlMbox<'d> {
_ipcc: PeripheralRef<'d, IPCC>,
}
impl TlMbox {
impl<'d> TlMbox<'d> {
/// initializes low-level transport between CPU1 and BLE stack on CPU2
pub fn init(
pub fn new(
ipcc: impl Peripheral<P = IPCC> + 'd,
_irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler>
+ interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>,
config: Config,
) -> TlMbox {
) -> Self {
into_ref!(ipcc);
unsafe {
TL_REF_TABLE = MaybeUninit::new(RefTable {
compiler_fence(Ordering::AcqRel);
TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable {
device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(),
ble_table: TL_BLE_TABLE.as_ptr(),
thread_table: TL_THREAD_TABLE.as_ptr(),
@ -334,6 +346,10 @@ impl TlMbox {
ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(),
});
// info!("TL_REF_TABLE addr: {:x}", TL_REF_TABLE.as_ptr() as usize);
compiler_fence(Ordering::AcqRel);
TL_SYS_TABLE = MaybeUninit::zeroed();
TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed();
TL_BLE_TABLE = MaybeUninit::zeroed();
@ -352,13 +368,15 @@ impl TlMbox {
CS_BUFFER = MaybeUninit::zeroed();
BLE_CMD_BUFFER = MaybeUninit::zeroed();
HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed();
compiler_fence(Ordering::AcqRel);
}
Ipcc::init(config);
Ipcc::enable(config);
let _sys = Sys::new();
let _ble = Ble::new();
let _mm = MemoryManager::new();
Sys::enable();
Ble::enable();
MemoryManager::enable();
// enable interrupts
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend();
@ -367,7 +385,7 @@ impl TlMbox {
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable();
unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable();
TlMbox { _sys, _ble, _mm }
Self { _ipcc: ipcc }
}
pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {

View file

@ -3,7 +3,7 @@
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;
use crate::tl_mbox::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;

View file

@ -1,5 +1,3 @@
use core::mem::MaybeUninit;
use embassy_futures::block_on;
use super::cmd::{CmdPacket, CmdSerial};
@ -7,27 +5,25 @@ use super::consts::TlPacketType;
use super::evt::{CcEvt, EvtBox, EvtSerial};
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;
use crate::tl_mbox::ipcc::Ipcc;
pub struct Sys;
impl Sys {
pub(crate) fn new() -> Self {
pub fn enable() {
unsafe {
LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
TL_SYS_TABLE = MaybeUninit::new(SysTable {
TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable {
pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(),
sys_queue: SYSTEM_EVT_QUEUE.as_ptr(),
});
}
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true);
Sys
}
pub(crate) fn evt_handler() {
pub fn evt_handler() {
unsafe {
let mut node_ptr = core::ptr::null_mut();
let node_ptr_ptr: *mut _ = &mut node_ptr;
@ -46,7 +42,7 @@ impl Sys {
Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL);
}
pub(crate) fn cmd_evt_handler() -> CcEvt {
pub fn cmd_evt_handler() -> CcEvt {
Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false);
// ST's command response data structure is really convoluted.
@ -68,7 +64,7 @@ impl Sys {
}
#[allow(dead_code)]
pub(crate) fn send_cmd(buf: &[u8]) {
pub fn send_cmd(buf: &[u8]) {
unsafe {
// TODO: check this
let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer;