stm32/ipcc: static methods for IPCC
This commit is contained in:
		@@ -1,5 +1,3 @@
 | 
			
		||||
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
 | 
			
		||||
 | 
			
		||||
use crate::ipcc::sealed::Instance;
 | 
			
		||||
use crate::peripherals::IPCC;
 | 
			
		||||
use crate::rcc::sealed::RccPeripheral;
 | 
			
		||||
@@ -29,22 +27,10 @@ pub(crate) mod sealed {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Ipcc<'d> {
 | 
			
		||||
    _peri: PeripheralRef<'d, IPCC>,
 | 
			
		||||
}
 | 
			
		||||
pub(crate) struct Ipcc;
 | 
			
		||||
 | 
			
		||||
impl<'d> Ipcc<'d> {
 | 
			
		||||
    pub fn new(peri: impl Peripheral<P = IPCC> + 'd, _config: Config) -> Self {
 | 
			
		||||
        Self::new_inner(peri)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn new_inner(peri: impl Peripheral<P = IPCC> + 'd) -> Self {
 | 
			
		||||
        into_ref!(peri);
 | 
			
		||||
 | 
			
		||||
        Self { _peri: peri }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn init(&mut self) {
 | 
			
		||||
impl Ipcc {
 | 
			
		||||
    pub(crate) fn init(_config: Config) {
 | 
			
		||||
        IPCC::enable();
 | 
			
		||||
        IPCC::reset();
 | 
			
		||||
        IPCC::set_cpu2(true);
 | 
			
		||||
@@ -61,56 +47,60 @@ impl<'d> Ipcc<'d> {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) {
 | 
			
		||||
    pub(crate) fn c1_set_rx_channel(channel: IpccChannel, enabled: bool) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { regs.cpu(0).mr().modify(|w| w.set_chom(channel as usize, !enabled)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_get_rx_channel(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    pub(crate) fn c1_get_rx_channel(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { !regs.cpu(0).mr().read().chom(channel as usize) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) {
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) fn c2_set_rx_channel(channel: IpccChannel, enabled: bool) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { regs.cpu(1).mr().modify(|w| w.set_chom(channel as usize, !enabled)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_get_rx_channel(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) fn c2_get_rx_channel(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { !regs.cpu(1).mr().read().chom(channel as usize) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) {
 | 
			
		||||
    pub(crate) fn c1_set_tx_channel(channel: IpccChannel, enabled: bool) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_get_tx_channel(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    pub(crate) fn c1_get_tx_channel(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { !regs.cpu(0).mr().read().chfm(channel as usize) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) {
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) fn c2_set_tx_channel(channel: IpccChannel, enabled: bool) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
        unsafe { regs.cpu(1).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_get_tx_channel(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) fn c2_get_tx_channel(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        // If bit is set to 1 then interrupt is disabled
 | 
			
		||||
@@ -118,53 +108,51 @@ impl<'d> Ipcc<'d> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// clears IPCC receive channel status for CPU1
 | 
			
		||||
    pub fn c1_clear_flag_channel(&mut self, channel: IpccChannel) {
 | 
			
		||||
    pub(crate) fn c1_clear_flag_channel(channel: IpccChannel) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    /// clears IPCC receive channel status for CPU2
 | 
			
		||||
    pub fn c2_clear_flag_channel(&mut self, channel: IpccChannel) {
 | 
			
		||||
    pub(crate) fn c2_clear_flag_channel(channel: IpccChannel) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(1).scr().write(|w| w.set_chc(channel as usize, true)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_set_flag_channel(&mut self, channel: IpccChannel) {
 | 
			
		||||
    pub(crate) fn c1_set_flag_channel(channel: IpccChannel) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(0).scr().write(|w| w.set_chs(channel as usize, true)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_set_flag_channel(&mut self, channel: IpccChannel) {
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) fn c2_set_flag_channel(channel: IpccChannel) {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(1).scr().write(|w| w.set_chs(channel as usize, true)) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c1_is_active_flag(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    pub(crate) fn c1_is_active_flag(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(0).sr().read().chf(channel as usize) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn c2_is_active_flag(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
    pub(crate) fn c2_is_active_flag(channel: IpccChannel) -> bool {
 | 
			
		||||
        let regs = IPCC::regs();
 | 
			
		||||
 | 
			
		||||
        unsafe { regs.cpu(1).sr().read().chf(channel as usize) }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn is_tx_pending(&self, channel: IpccChannel) -> bool {
 | 
			
		||||
        !self.c1_is_active_flag(channel) && self.c1_get_tx_channel(channel)
 | 
			
		||||
    pub(crate) fn is_tx_pending(channel: IpccChannel) -> bool {
 | 
			
		||||
        !Self::c1_is_active_flag(channel) && Self::c1_get_tx_channel(channel)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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 _ }
 | 
			
		||||
    pub(crate) fn is_rx_pending(channel: IpccChannel) -> bool {
 | 
			
		||||
        Self::c2_is_active_flag(channel) && Self::c1_get_rx_channel(channel)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
use defmt::*;
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_stm32::ipcc::{Config, Ipcc};
 | 
			
		||||
use embassy_stm32::ipcc::Config;
 | 
			
		||||
use embassy_stm32::tl_mbox::TlMbox;
 | 
			
		||||
use embassy_stm32::{bind_interrupts, tl_mbox};
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
@@ -41,13 +41,11 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        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());
 | 
			
		||||
    let _p = embassy_stm32::init(Default::default());
 | 
			
		||||
    info!("Hello World!");
 | 
			
		||||
 | 
			
		||||
    let config = Config::default();
 | 
			
		||||
    let mut ipcc = Ipcc::new(p.IPCC, config);
 | 
			
		||||
 | 
			
		||||
    let mbox = TlMbox::init(&mut ipcc, Irqs);
 | 
			
		||||
    let mbox = TlMbox::init(Irqs, config);
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        let wireless_fw_info = mbox.wireless_fw_info();
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
use defmt::*;
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_stm32::ipcc::{Config, Ipcc};
 | 
			
		||||
use embassy_stm32::ipcc::Config;
 | 
			
		||||
use embassy_stm32::tl_mbox::TlMbox;
 | 
			
		||||
use embassy_stm32::{bind_interrupts, tl_mbox};
 | 
			
		||||
use {defmt_rtt as _, panic_probe as _};
 | 
			
		||||
@@ -40,16 +40,11 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        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());
 | 
			
		||||
    let _p = embassy_stm32::init(Default::default());
 | 
			
		||||
    info!("Hello World!");
 | 
			
		||||
 | 
			
		||||
    let config = Config::default();
 | 
			
		||||
    let mut ipcc = Ipcc::new(p.IPCC, config);
 | 
			
		||||
 | 
			
		||||
    let mbox = TlMbox::init(&mut ipcc, Irqs);
 | 
			
		||||
 | 
			
		||||
    // initialize ble stack, does not return a response
 | 
			
		||||
    mbox.shci_ble_init(&mut ipcc, Default::default());
 | 
			
		||||
    let mbox = TlMbox::init(Irqs, config);
 | 
			
		||||
 | 
			
		||||
    info!("waiting for coprocessor to boot");
 | 
			
		||||
    let event_box = mbox.read().await;
 | 
			
		||||
@@ -74,10 +69,11 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mbox.shci_ble_init(&mut ipcc, Default::default());
 | 
			
		||||
    // initialize ble stack, does not return a response
 | 
			
		||||
    mbox.shci_ble_init(Default::default());
 | 
			
		||||
 | 
			
		||||
    info!("resetting BLE");
 | 
			
		||||
    mbox.send_ble_cmd(&mut ipcc, &[0x01, 0x03, 0x0c, 0x00, 0x00]);
 | 
			
		||||
    mbox.send_ble_cmd(&[0x01, 0x03, 0x0c, 0x00, 0x00]);
 | 
			
		||||
 | 
			
		||||
    let event_box = mbox.read().await;
 | 
			
		||||
 | 
			
		||||
@@ -92,7 +88,10 @@ async fn main(_spawner: Spawner) {
 | 
			
		||||
 | 
			
		||||
    info!(
 | 
			
		||||
        "==> kind: {:#04x}, code: {:#04x}, payload_length: {}, payload: {:#04x}",
 | 
			
		||||
        kind, code, payload_len, payload
 | 
			
		||||
        kind,
 | 
			
		||||
        code,
 | 
			
		||||
        payload_len,
 | 
			
		||||
        payload[3..]
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    loop {}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user