stm32/ipcc: static methods for IPCC
This commit is contained in:
@ -16,7 +16,7 @@ use crate::tl_mbox::cmd::CmdPacket;
|
||||
pub struct Ble;
|
||||
|
||||
impl Ble {
|
||||
pub(crate) fn new(ipcc: &mut Ipcc) -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
unsafe {
|
||||
LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
|
||||
|
||||
@ -28,12 +28,12 @@ impl Ble {
|
||||
});
|
||||
}
|
||||
|
||||
ipcc.c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true);
|
||||
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true);
|
||||
|
||||
Ble
|
||||
}
|
||||
|
||||
pub(crate) fn evt_handler(ipcc: &mut Ipcc) {
|
||||
pub(crate) fn evt_handler() {
|
||||
unsafe {
|
||||
let mut node_ptr = core::ptr::null_mut();
|
||||
let node_ptr_ptr: *mut _ = &mut node_ptr;
|
||||
@ -48,10 +48,10 @@ impl Ble {
|
||||
}
|
||||
}
|
||||
|
||||
ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL);
|
||||
Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL);
|
||||
}
|
||||
|
||||
pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) {
|
||||
pub(crate) 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;
|
||||
@ -63,6 +63,6 @@ impl Ble {
|
||||
cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8;
|
||||
}
|
||||
|
||||
ipcc.c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL);
|
||||
Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
@ -131,9 +131,6 @@ impl EvtBox {
|
||||
|
||||
impl Drop for EvtBox {
|
||||
fn drop(&mut self) {
|
||||
use crate::ipcc::Ipcc;
|
||||
|
||||
let mut ipcc = Ipcc::new_inner(unsafe { crate::Peripherals::steal() }.IPCC);
|
||||
mm::MemoryManager::evt_drop(self.ptr, &mut ipcc);
|
||||
mm::MemoryManager::evt_drop(self.ptr);
|
||||
}
|
||||
}
|
||||
|
@ -30,27 +30,27 @@ impl MemoryManager {
|
||||
MemoryManager
|
||||
}
|
||||
|
||||
pub fn evt_handler(ipcc: &mut Ipcc) {
|
||||
ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, false);
|
||||
pub fn evt_handler() {
|
||||
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);
|
||||
Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL);
|
||||
}
|
||||
|
||||
pub fn evt_drop(evt: *mut EvtPacket, ipcc: &mut Ipcc) {
|
||||
pub fn evt_drop(evt: *mut EvtPacket) {
|
||||
unsafe {
|
||||
let list_node = evt.cast();
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use bit_field::BitField;
|
||||
use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::Channel;
|
||||
|
||||
@ -12,7 +13,7 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam};
|
||||
use self::sys::Sys;
|
||||
use self::unsafe_linked_list::LinkedListNode;
|
||||
use crate::interrupt;
|
||||
use crate::ipcc::Ipcc;
|
||||
use crate::ipcc::{Config, Ipcc};
|
||||
|
||||
mod ble;
|
||||
mod channels;
|
||||
@ -58,13 +59,30 @@ pub struct FusInfoTable {
|
||||
pub struct ReceiveInterruptHandler {}
|
||||
|
||||
impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler {
|
||||
unsafe fn on_interrupt() {}
|
||||
unsafe fn on_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) {
|
||||
ble::Ble::evt_handler();
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TransmitInterruptHandler {}
|
||||
|
||||
impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler {
|
||||
unsafe fn on_interrupt() {}
|
||||
unsafe fn on_interrupt() {
|
||||
if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) {
|
||||
// TODO: handle this case
|
||||
let _ = sys::Sys::cmd_evt_handler();
|
||||
} else if Ipcc::is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) {
|
||||
mm::MemoryManager::evt_handler();
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// # Version
|
||||
@ -298,9 +316,9 @@ pub struct TlMbox {
|
||||
impl TlMbox {
|
||||
/// initializes low-level transport between CPU1 and BLE stack on CPU2
|
||||
pub fn init(
|
||||
ipcc: &mut Ipcc,
|
||||
_irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler>
|
||||
+ interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>,
|
||||
config: Config,
|
||||
) -> TlMbox {
|
||||
unsafe {
|
||||
TL_REF_TABLE = MaybeUninit::new(RefTable {
|
||||
@ -336,29 +354,18 @@ impl TlMbox {
|
||||
HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed();
|
||||
}
|
||||
|
||||
ipcc.init();
|
||||
Ipcc::init(config);
|
||||
|
||||
let _sys = Sys::new(ipcc);
|
||||
let _ble = Ble::new(ipcc);
|
||||
let _sys = Sys::new();
|
||||
let _ble = Ble::new();
|
||||
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();
|
||||
// enable interrupts
|
||||
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend();
|
||||
unsafe { crate::interrupt::IPCC_C1_TX::steal() }.unpend();
|
||||
|
||||
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable();
|
||||
unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable();
|
||||
|
||||
TlMbox { _sys, _ble, _mm }
|
||||
}
|
||||
@ -374,42 +381,19 @@ impl TlMbox {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shci_ble_init(&self, ipcc: &mut Ipcc, param: ShciBleInitCmdParam) {
|
||||
shci_ble_init(ipcc, param);
|
||||
pub fn shci_ble_init(&self, param: ShciBleInitCmdParam) {
|
||||
shci_ble_init(param);
|
||||
}
|
||||
|
||||
pub fn send_ble_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) {
|
||||
ble::Ble::send_cmd(ipcc, buf);
|
||||
pub fn send_ble_cmd(&self, buf: &[u8]) {
|
||||
ble::Ble::send_cmd(buf);
|
||||
}
|
||||
|
||||
// pub fn send_sys_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) {
|
||||
// sys::Sys::send_cmd(ipcc, buf);
|
||||
// pub fn send_sys_cmd(&self, buf: &[u8]) {
|
||||
// sys::Sys::send_cmd(buf);
|
||||
// }
|
||||
|
||||
pub async fn read(&self) -> EvtBox {
|
||||
TL_CHANNEL.recv().await
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ pub struct ShciBleInitCmdPacket {
|
||||
param: ShciBleInitCmdParam,
|
||||
}
|
||||
|
||||
pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) {
|
||||
pub fn shci_ble_init(param: ShciBleInitCmdParam) {
|
||||
let mut packet = ShciBleInitCmdPacket {
|
||||
header: ShciHeader::default(),
|
||||
param,
|
||||
@ -95,7 +95,7 @@ pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) {
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use crate::ipcc::Ipcc;
|
||||
pub struct Sys;
|
||||
|
||||
impl Sys {
|
||||
pub(crate) fn new(ipcc: &mut Ipcc) -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
unsafe {
|
||||
LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
|
||||
|
||||
@ -22,12 +22,12 @@ impl Sys {
|
||||
});
|
||||
}
|
||||
|
||||
ipcc.c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true);
|
||||
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true);
|
||||
|
||||
Sys
|
||||
}
|
||||
|
||||
pub(crate) fn evt_handler(ipcc: &mut Ipcc) {
|
||||
pub(crate) fn evt_handler() {
|
||||
unsafe {
|
||||
let mut node_ptr = core::ptr::null_mut();
|
||||
let node_ptr_ptr: *mut _ = &mut node_ptr;
|
||||
@ -43,11 +43,11 @@ impl Sys {
|
||||
}
|
||||
}
|
||||
|
||||
ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL);
|
||||
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);
|
||||
pub(crate) 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,11 +68,11 @@ impl Sys {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) {
|
||||
pub(crate) fn send_cmd(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: *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());
|
||||
@ -80,8 +80,8 @@ impl Sys {
|
||||
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);
|
||||
ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user