diff options
| -rw-r--r-- | embassy-stm32/src/ipcc.rs | 66 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/ble.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/evt.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/mm.rs | 14 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/mod.rs | 90 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/shci.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/sys.rs | 20 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox.rs | 8 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 21 |
9 files changed, 104 insertions, 138 deletions
diff --git a/embassy-stm32/src/ipcc.rs b/embassy-stm32/src/ipcc.rs index 2b9caf8e5..ea33b32c7 100644 --- a/embassy-stm32/src/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | ||
| 2 | |||
| 3 | use crate::ipcc::sealed::Instance; | 1 | use crate::ipcc::sealed::Instance; |
| 4 | use crate::peripherals::IPCC; | 2 | use crate::peripherals::IPCC; |
| 5 | use crate::rcc::sealed::RccPeripheral; | 3 | use crate::rcc::sealed::RccPeripheral; |
| @@ -29,22 +27,10 @@ pub(crate) mod sealed { | |||
| 29 | } | 27 | } |
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | pub struct Ipcc<'d> { | 30 | pub(crate) struct Ipcc; |
| 33 | _peri: PeripheralRef<'d, IPCC>, | ||
| 34 | } | ||
| 35 | |||
| 36 | impl<'d> Ipcc<'d> { | ||
| 37 | pub fn new(peri: impl Peripheral<P = IPCC> + 'd, _config: Config) -> Self { | ||
| 38 | Self::new_inner(peri) | ||
| 39 | } | ||
| 40 | |||
| 41 | pub(crate) fn new_inner(peri: impl Peripheral<P = IPCC> + 'd) -> Self { | ||
| 42 | into_ref!(peri); | ||
| 43 | 31 | ||
| 44 | Self { _peri: peri } | 32 | impl Ipcc { |
| 45 | } | 33 | pub(crate) fn init(_config: Config) { |
| 46 | |||
| 47 | pub fn init(&mut self) { | ||
| 48 | IPCC::enable(); | 34 | IPCC::enable(); |
| 49 | IPCC::reset(); | 35 | IPCC::reset(); |
| 50 | IPCC::set_cpu2(true); | 36 | IPCC::set_cpu2(true); |
| @@ -61,56 +47,60 @@ impl<'d> Ipcc<'d> { | |||
| 61 | } | 47 | } |
| 62 | } | 48 | } |
| 63 | 49 | ||
| 64 | pub fn c1_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) { | 50 | pub(crate) fn c1_set_rx_channel(channel: IpccChannel, enabled: bool) { |
| 65 | let regs = IPCC::regs(); | 51 | let regs = IPCC::regs(); |
| 66 | 52 | ||
| 67 | // If bit is set to 1 then interrupt is disabled | 53 | // If bit is set to 1 then interrupt is disabled |
| 68 | unsafe { regs.cpu(0).mr().modify(|w| w.set_chom(channel as usize, !enabled)) } | 54 | unsafe { regs.cpu(0).mr().modify(|w| w.set_chom(channel as usize, !enabled)) } |
| 69 | } | 55 | } |
| 70 | 56 | ||
| 71 | pub fn c1_get_rx_channel(&self, channel: IpccChannel) -> bool { | 57 | pub(crate) fn c1_get_rx_channel(channel: IpccChannel) -> bool { |
| 72 | let regs = IPCC::regs(); | 58 | let regs = IPCC::regs(); |
| 73 | 59 | ||
| 74 | // If bit is set to 1 then interrupt is disabled | 60 | // If bit is set to 1 then interrupt is disabled |
| 75 | unsafe { !regs.cpu(0).mr().read().chom(channel as usize) } | 61 | unsafe { !regs.cpu(0).mr().read().chom(channel as usize) } |
| 76 | } | 62 | } |
| 77 | 63 | ||
| 78 | pub fn c2_set_rx_channel(&mut self, channel: IpccChannel, enabled: bool) { | 64 | #[allow(dead_code)] |
| 65 | pub(crate) fn c2_set_rx_channel(channel: IpccChannel, enabled: bool) { | ||
| 79 | let regs = IPCC::regs(); | 66 | let regs = IPCC::regs(); |
| 80 | 67 | ||
| 81 | // If bit is set to 1 then interrupt is disabled | 68 | // If bit is set to 1 then interrupt is disabled |
| 82 | unsafe { regs.cpu(1).mr().modify(|w| w.set_chom(channel as usize, !enabled)) } | 69 | unsafe { regs.cpu(1).mr().modify(|w| w.set_chom(channel as usize, !enabled)) } |
| 83 | } | 70 | } |
| 84 | 71 | ||
| 85 | pub fn c2_get_rx_channel(&self, channel: IpccChannel) -> bool { | 72 | #[allow(dead_code)] |
| 73 | pub(crate) fn c2_get_rx_channel(channel: IpccChannel) -> bool { | ||
| 86 | let regs = IPCC::regs(); | 74 | let regs = IPCC::regs(); |
| 87 | 75 | ||
| 88 | // If bit is set to 1 then interrupt is disabled | 76 | // If bit is set to 1 then interrupt is disabled |
| 89 | unsafe { !regs.cpu(1).mr().read().chom(channel as usize) } | 77 | unsafe { !regs.cpu(1).mr().read().chom(channel as usize) } |
| 90 | } | 78 | } |
| 91 | 79 | ||
| 92 | pub fn c1_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) { | 80 | pub(crate) fn c1_set_tx_channel(channel: IpccChannel, enabled: bool) { |
| 93 | let regs = IPCC::regs(); | 81 | let regs = IPCC::regs(); |
| 94 | 82 | ||
| 95 | // If bit is set to 1 then interrupt is disabled | 83 | // If bit is set to 1 then interrupt is disabled |
| 96 | unsafe { regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) } | 84 | unsafe { regs.cpu(0).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) } |
| 97 | } | 85 | } |
| 98 | 86 | ||
| 99 | pub fn c1_get_tx_channel(&self, channel: IpccChannel) -> bool { | 87 | pub(crate) fn c1_get_tx_channel(channel: IpccChannel) -> bool { |
| 100 | let regs = IPCC::regs(); | 88 | let regs = IPCC::regs(); |
| 101 | 89 | ||
| 102 | // If bit is set to 1 then interrupt is disabled | 90 | // If bit is set to 1 then interrupt is disabled |
| 103 | unsafe { !regs.cpu(0).mr().read().chfm(channel as usize) } | 91 | unsafe { !regs.cpu(0).mr().read().chfm(channel as usize) } |
| 104 | } | 92 | } |
| 105 | 93 | ||
| 106 | pub fn c2_set_tx_channel(&mut self, channel: IpccChannel, enabled: bool) { | 94 | #[allow(dead_code)] |
| 95 | pub(crate) fn c2_set_tx_channel(channel: IpccChannel, enabled: bool) { | ||
| 107 | let regs = IPCC::regs(); | 96 | let regs = IPCC::regs(); |
| 108 | 97 | ||
| 109 | // If bit is set to 1 then interrupt is disabled | 98 | // If bit is set to 1 then interrupt is disabled |
| 110 | unsafe { regs.cpu(1).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) } | 99 | unsafe { regs.cpu(1).mr().modify(|w| w.set_chfm(channel as usize, !enabled)) } |
| 111 | } | 100 | } |
| 112 | 101 | ||
| 113 | pub fn c2_get_tx_channel(&self, channel: IpccChannel) -> bool { | 102 | #[allow(dead_code)] |
| 103 | pub(crate) fn c2_get_tx_channel(channel: IpccChannel) -> bool { | ||
| 114 | let regs = IPCC::regs(); | 104 | let regs = IPCC::regs(); |
| 115 | 105 | ||
| 116 | // If bit is set to 1 then interrupt is disabled | 106 | // If bit is set to 1 then interrupt is disabled |
| @@ -118,53 +108,51 @@ impl<'d> Ipcc<'d> { | |||
| 118 | } | 108 | } |
| 119 | 109 | ||
| 120 | /// clears IPCC receive channel status for CPU1 | 110 | /// clears IPCC receive channel status for CPU1 |
| 121 | pub fn c1_clear_flag_channel(&mut self, channel: IpccChannel) { | 111 | pub(crate) fn c1_clear_flag_channel(channel: IpccChannel) { |
| 122 | let regs = IPCC::regs(); | 112 | let regs = IPCC::regs(); |
| 123 | 113 | ||
| 124 | unsafe { regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true)) } | 114 | unsafe { regs.cpu(0).scr().write(|w| w.set_chc(channel as usize, true)) } |
| 125 | } | 115 | } |
| 126 | 116 | ||
| 117 | #[allow(dead_code)] | ||
| 127 | /// clears IPCC receive channel status for CPU2 | 118 | /// clears IPCC receive channel status for CPU2 |
| 128 | pub fn c2_clear_flag_channel(&mut self, channel: IpccChannel) { | 119 | pub(crate) fn c2_clear_flag_channel(channel: IpccChannel) { |
| 129 | let regs = IPCC::regs(); | 120 | let regs = IPCC::regs(); |
| 130 | 121 | ||
| 131 | unsafe { regs.cpu(1).scr().write(|w| w.set_chc(channel as usize, true)) } | 122 | unsafe { regs.cpu(1).scr().write(|w| w.set_chc(channel as usize, true)) } |
| 132 | } | 123 | } |
| 133 | 124 | ||
| 134 | pub fn c1_set_flag_channel(&mut self, channel: IpccChannel) { | 125 | pub(crate) fn c1_set_flag_channel(channel: IpccChannel) { |
| 135 | let regs = IPCC::regs(); | 126 | let regs = IPCC::regs(); |
| 136 | 127 | ||
| 137 | unsafe { regs.cpu(0).scr().write(|w| w.set_chs(channel as usize, true)) } | 128 | unsafe { regs.cpu(0).scr().write(|w| w.set_chs(channel as usize, true)) } |
| 138 | } | 129 | } |
| 139 | 130 | ||
| 140 | pub fn c2_set_flag_channel(&mut self, channel: IpccChannel) { | 131 | #[allow(dead_code)] |
| 132 | pub(crate) fn c2_set_flag_channel(channel: IpccChannel) { | ||
| 141 | let regs = IPCC::regs(); | 133 | let regs = IPCC::regs(); |
| 142 | 134 | ||
| 143 | unsafe { regs.cpu(1).scr().write(|w| w.set_chs(channel as usize, true)) } | 135 | unsafe { regs.cpu(1).scr().write(|w| w.set_chs(channel as usize, true)) } |
| 144 | } | 136 | } |
| 145 | 137 | ||
| 146 | pub fn c1_is_active_flag(&self, channel: IpccChannel) -> bool { | 138 | pub(crate) fn c1_is_active_flag(channel: IpccChannel) -> bool { |
| 147 | let regs = IPCC::regs(); | 139 | let regs = IPCC::regs(); |
| 148 | 140 | ||
| 149 | unsafe { regs.cpu(0).sr().read().chf(channel as usize) } | 141 | unsafe { regs.cpu(0).sr().read().chf(channel as usize) } |
| 150 | } | 142 | } |
| 151 | 143 | ||
| 152 | pub fn c2_is_active_flag(&self, channel: IpccChannel) -> bool { | 144 | pub(crate) fn c2_is_active_flag(channel: IpccChannel) -> bool { |
| 153 | let regs = IPCC::regs(); | 145 | let regs = IPCC::regs(); |
| 154 | 146 | ||
| 155 | unsafe { regs.cpu(1).sr().read().chf(channel as usize) } | 147 | unsafe { regs.cpu(1).sr().read().chf(channel as usize) } |
| 156 | } | 148 | } |
| 157 | 149 | ||
| 158 | pub fn is_tx_pending(&self, channel: IpccChannel) -> bool { | 150 | pub(crate) fn is_tx_pending(channel: IpccChannel) -> bool { |
| 159 | !self.c1_is_active_flag(channel) && self.c1_get_tx_channel(channel) | 151 | !Self::c1_is_active_flag(channel) && Self::c1_get_tx_channel(channel) |
| 160 | } | ||
| 161 | |||
| 162 | pub fn is_rx_pending(&self, channel: IpccChannel) -> bool { | ||
| 163 | self.c2_is_active_flag(channel) && self.c1_get_rx_channel(channel) | ||
| 164 | } | 152 | } |
| 165 | 153 | ||
| 166 | pub fn as_mut_ptr(&self) -> *mut Self { | 154 | pub(crate) fn is_rx_pending(channel: IpccChannel) -> bool { |
| 167 | unsafe { &mut core::ptr::read(self) as *mut _ } | 155 | Self::c2_is_active_flag(channel) && Self::c1_get_rx_channel(channel) |
| 168 | } | 156 | } |
| 169 | } | 157 | } |
| 170 | 158 | ||
diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs index d8bf14d4f..5cc0bb200 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32/src/tl_mbox/ble.rs | |||
| @@ -16,7 +16,7 @@ use crate::tl_mbox::cmd::CmdPacket; | |||
| 16 | pub struct Ble; | 16 | pub struct Ble; |
| 17 | 17 | ||
| 18 | impl Ble { | 18 | impl Ble { |
| 19 | pub(crate) fn new(ipcc: &mut Ipcc) -> Self { | 19 | pub(crate) fn new() -> Self { |
| 20 | unsafe { | 20 | unsafe { |
| 21 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | 21 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |
| 22 | 22 | ||
| @@ -28,12 +28,12 @@ impl Ble { | |||
| 28 | }); | 28 | }); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | ipcc.c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); | 31 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); |
| 32 | 32 | ||
| 33 | Ble | 33 | Ble |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | pub(crate) fn evt_handler(ipcc: &mut Ipcc) { | 36 | pub(crate) fn evt_handler() { |
| 37 | unsafe { | 37 | unsafe { |
| 38 | let mut node_ptr = core::ptr::null_mut(); | 38 | let mut node_ptr = core::ptr::null_mut(); |
| 39 | let node_ptr_ptr: *mut _ = &mut node_ptr; | 39 | let node_ptr_ptr: *mut _ = &mut node_ptr; |
| @@ -48,10 +48,10 @@ impl Ble { | |||
| 48 | } | 48 | } |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); | 51 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { | 54 | pub(crate) fn send_cmd(buf: &[u8]) { |
| 55 | unsafe { | 55 | unsafe { |
| 56 | let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; | 56 | let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; |
| 57 | let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial; | 57 | let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial; |
| @@ -63,6 +63,6 @@ impl Ble { | |||
| 63 | cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8; | 63 | cmd_packet.cmd_serial.ty = TlPacketType::BleCmd as u8; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | ipcc.c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL); | 66 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_BLE_CMD_CHANNEL); |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs index 770133f29..04feb3e68 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32/src/tl_mbox/evt.rs | |||
| @@ -131,9 +131,6 @@ impl EvtBox { | |||
| 131 | 131 | ||
| 132 | impl Drop for EvtBox { | 132 | impl Drop for EvtBox { |
| 133 | fn drop(&mut self) { | 133 | fn drop(&mut self) { |
| 134 | use crate::ipcc::Ipcc; | 134 | mm::MemoryManager::evt_drop(self.ptr); |
| 135 | |||
| 136 | let mut ipcc = Ipcc::new_inner(unsafe { crate::Peripherals::steal() }.IPCC); | ||
| 137 | mm::MemoryManager::evt_drop(self.ptr, &mut ipcc); | ||
| 138 | } | 135 | } |
| 139 | } | 136 | } |
diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs index f99ffa399..6e0818cf1 100644 --- a/embassy-stm32/src/tl_mbox/mm.rs +++ b/embassy-stm32/src/tl_mbox/mm.rs | |||
| @@ -30,27 +30,27 @@ impl MemoryManager { | |||
| 30 | MemoryManager | 30 | MemoryManager |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn evt_handler(ipcc: &mut Ipcc) { | 33 | pub fn evt_handler() { |
| 34 | ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, false); | 34 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, false); |
| 35 | Self::send_free_buf(); | 35 | Self::send_free_buf(); |
| 36 | ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); | 36 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | pub fn evt_drop(evt: *mut EvtPacket, ipcc: &mut Ipcc) { | 39 | pub fn evt_drop(evt: *mut EvtPacket) { |
| 40 | unsafe { | 40 | unsafe { |
| 41 | let list_node = evt.cast(); | 41 | let list_node = evt.cast(); |
| 42 | 42 | ||
| 43 | LinkedListNode::remove_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); | 43 | LinkedListNode::remove_tail(LOCAL_FREE_BUF_QUEUE.as_mut_ptr(), list_node); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | let channel_is_busy = ipcc.c1_is_active_flag(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); | 46 | let channel_is_busy = Ipcc::c1_is_active_flag(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); |
| 47 | 47 | ||
| 48 | // postpone event buffer freeing to IPCC interrupt handler | 48 | // postpone event buffer freeing to IPCC interrupt handler |
| 49 | if channel_is_busy { | 49 | if channel_is_busy { |
| 50 | ipcc.c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, true); | 50 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL, true); |
| 51 | } else { | 51 | } else { |
| 52 | Self::send_free_buf(); | 52 | Self::send_free_buf(); |
| 53 | ipcc.c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); | 53 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL); |
| 54 | } | 54 | } |
| 55 | } | 55 | } |
| 56 | 56 | ||
diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs index dc6104cc3..1c927efa0 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32/src/tl_mbox/mod.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use core::mem::MaybeUninit; | 1 | use core::mem::MaybeUninit; |
| 2 | 2 | ||
| 3 | use bit_field::BitField; | 3 | use bit_field::BitField; |
| 4 | use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; | ||
| 4 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 5 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 5 | use embassy_sync::channel::Channel; | 6 | use embassy_sync::channel::Channel; |
| 6 | 7 | ||
| @@ -12,7 +13,7 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam}; | |||
| 12 | use self::sys::Sys; | 13 | use self::sys::Sys; |
| 13 | use self::unsafe_linked_list::LinkedListNode; | 14 | use self::unsafe_linked_list::LinkedListNode; |
| 14 | use crate::interrupt; | 15 | use crate::interrupt; |
| 15 | use crate::ipcc::Ipcc; | 16 | use crate::ipcc::{Config, Ipcc}; |
| 16 | 17 | ||
| 17 | mod ble; | 18 | mod ble; |
| 18 | mod channels; | 19 | mod channels; |
| @@ -58,13 +59,30 @@ pub struct FusInfoTable { | |||
| 58 | pub struct ReceiveInterruptHandler {} | 59 | pub struct ReceiveInterruptHandler {} |
| 59 | 60 | ||
| 60 | impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler { | 61 | impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler { |
| 61 | unsafe fn on_interrupt() {} | 62 | unsafe fn on_interrupt() { |
| 63 | if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { | ||
| 64 | sys::Sys::evt_handler(); | ||
| 65 | } else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { | ||
| 66 | ble::Ble::evt_handler(); | ||
| 67 | } else { | ||
| 68 | todo!() | ||
| 69 | } | ||
| 70 | } | ||
| 62 | } | 71 | } |
| 63 | 72 | ||
| 64 | pub struct TransmitInterruptHandler {} | 73 | pub struct TransmitInterruptHandler {} |
| 65 | 74 | ||
| 66 | impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler { | 75 | impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler { |
| 67 | unsafe fn on_interrupt() {} | 76 | unsafe fn on_interrupt() { |
| 77 | if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { | ||
| 78 | // TODO: handle this case | ||
| 79 | let _ = sys::Sys::cmd_evt_handler(); | ||
| 80 | } else if Ipcc::is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { | ||
| 81 | mm::MemoryManager::evt_handler(); | ||
| 82 | } else { | ||
| 83 | todo!() | ||
| 84 | } | ||
| 85 | } | ||
| 68 | } | 86 | } |
| 69 | 87 | ||
| 70 | /// # Version | 88 | /// # Version |
| @@ -298,9 +316,9 @@ pub struct TlMbox { | |||
| 298 | impl TlMbox { | 316 | impl TlMbox { |
| 299 | /// initializes low-level transport between CPU1 and BLE stack on CPU2 | 317 | /// initializes low-level transport between CPU1 and BLE stack on CPU2 |
| 300 | pub fn init( | 318 | pub fn init( |
| 301 | ipcc: &mut Ipcc, | ||
| 302 | _irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler> | 319 | _irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler> |
| 303 | + interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>, | 320 | + interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>, |
| 321 | config: Config, | ||
| 304 | ) -> TlMbox { | 322 | ) -> TlMbox { |
| 305 | unsafe { | 323 | unsafe { |
| 306 | TL_REF_TABLE = MaybeUninit::new(RefTable { | 324 | TL_REF_TABLE = MaybeUninit::new(RefTable { |
| @@ -336,29 +354,18 @@ impl TlMbox { | |||
| 336 | HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); | 354 | HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); |
| 337 | } | 355 | } |
| 338 | 356 | ||
| 339 | ipcc.init(); | 357 | Ipcc::init(config); |
| 340 | 358 | ||
| 341 | let _sys = Sys::new(ipcc); | 359 | let _sys = Sys::new(); |
| 342 | let _ble = Ble::new(ipcc); | 360 | let _ble = Ble::new(); |
| 343 | let _mm = MemoryManager::new(); | 361 | let _mm = MemoryManager::new(); |
| 344 | 362 | ||
| 345 | // rx_irq.disable(); | 363 | // enable interrupts |
| 346 | // tx_irq.disable(); | 364 | unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend(); |
| 347 | // | 365 | unsafe { crate::interrupt::IPCC_C1_TX::steal() }.unpend(); |
| 348 | // rx_irq.set_handler_context(ipcc.as_mut_ptr() as *mut ()); | 366 | |
| 349 | // tx_irq.set_handler_context(ipcc.as_mut_ptr() as *mut ()); | 367 | unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable(); |
| 350 | // | 368 | unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable(); |
| 351 | // rx_irq.set_handler(|ipcc| { | ||
| 352 | // let ipcc: &mut Ipcc = unsafe { &mut *ipcc.cast() }; | ||
| 353 | // Self::interrupt_ipcc_rx_handler(ipcc); | ||
| 354 | // }); | ||
| 355 | // tx_irq.set_handler(|ipcc| { | ||
| 356 | // let ipcc: &mut Ipcc = unsafe { &mut *ipcc.cast() }; | ||
| 357 | // Self::interrupt_ipcc_tx_handler(ipcc); | ||
| 358 | // }); | ||
| 359 | // | ||
| 360 | // rx_irq.enable(); | ||
| 361 | // tx_irq.enable(); | ||
| 362 | 369 | ||
| 363 | TlMbox { _sys, _ble, _mm } | 370 | TlMbox { _sys, _ble, _mm } |
| 364 | } | 371 | } |
| @@ -374,42 +381,19 @@ impl TlMbox { | |||
| 374 | } | 381 | } |
| 375 | } | 382 | } |
| 376 | 383 | ||
| 377 | pub fn shci_ble_init(&self, ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { | 384 | pub fn shci_ble_init(&self, param: ShciBleInitCmdParam) { |
| 378 | shci_ble_init(ipcc, param); | 385 | shci_ble_init(param); |
| 379 | } | 386 | } |
| 380 | 387 | ||
| 381 | pub fn send_ble_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { | 388 | pub fn send_ble_cmd(&self, buf: &[u8]) { |
| 382 | ble::Ble::send_cmd(ipcc, buf); | 389 | ble::Ble::send_cmd(buf); |
| 383 | } | 390 | } |
| 384 | 391 | ||
| 385 | // pub fn send_sys_cmd(&self, ipcc: &mut Ipcc, buf: &[u8]) { | 392 | // pub fn send_sys_cmd(&self, buf: &[u8]) { |
| 386 | // sys::Sys::send_cmd(ipcc, buf); | 393 | // sys::Sys::send_cmd(buf); |
| 387 | // } | 394 | // } |
| 388 | 395 | ||
| 389 | pub async fn read(&self) -> EvtBox { | 396 | pub async fn read(&self) -> EvtBox { |
| 390 | TL_CHANNEL.recv().await | 397 | TL_CHANNEL.recv().await |
| 391 | } | 398 | } |
| 392 | |||
| 393 | #[allow(dead_code)] | ||
| 394 | fn interrupt_ipcc_rx_handler(ipcc: &mut Ipcc) { | ||
| 395 | if ipcc.is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { | ||
| 396 | sys::Sys::evt_handler(ipcc); | ||
| 397 | } else if ipcc.is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { | ||
| 398 | ble::Ble::evt_handler(ipcc); | ||
| 399 | } else { | ||
| 400 | todo!() | ||
| 401 | } | ||
| 402 | } | ||
| 403 | |||
| 404 | #[allow(dead_code)] | ||
| 405 | fn interrupt_ipcc_tx_handler(ipcc: &mut Ipcc) { | ||
| 406 | if ipcc.is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { | ||
| 407 | // TODO: handle this case | ||
| 408 | let _ = sys::Sys::cmd_evt_handler(ipcc); | ||
| 409 | } else if ipcc.is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { | ||
| 410 | mm::MemoryManager::evt_handler(ipcc); | ||
| 411 | } else { | ||
| 412 | todo!() | ||
| 413 | } | ||
| 414 | } | ||
| 415 | } | 399 | } |
diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32/src/tl_mbox/shci.rs index 61fd9e4a3..3d7e994ae 100644 --- a/embassy-stm32/src/tl_mbox/shci.rs +++ b/embassy-stm32/src/tl_mbox/shci.rs | |||
| @@ -76,7 +76,7 @@ pub struct ShciBleInitCmdPacket { | |||
| 76 | param: ShciBleInitCmdParam, | 76 | param: ShciBleInitCmdParam, |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { | 79 | pub fn shci_ble_init(param: ShciBleInitCmdParam) { |
| 80 | let mut packet = ShciBleInitCmdPacket { | 80 | let mut packet = ShciBleInitCmdPacket { |
| 81 | header: ShciHeader::default(), | 81 | header: ShciHeader::default(), |
| 82 | param, | 82 | param, |
| @@ -95,7 +95,7 @@ pub fn shci_ble_init(ipcc: &mut Ipcc, param: ShciBleInitCmdParam) { | |||
| 95 | 95 | ||
| 96 | cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8; | 96 | cmd_buf.cmd_serial.ty = TlPacketType::SysCmd as u8; |
| 97 | 97 | ||
| 98 | ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); | 98 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); |
| 99 | ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); | 99 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); |
| 100 | } | 100 | } |
| 101 | } | 101 | } |
diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs index 31ebde721..79e257148 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32/src/tl_mbox/sys.rs | |||
| @@ -12,7 +12,7 @@ use crate::ipcc::Ipcc; | |||
| 12 | pub struct Sys; | 12 | pub struct Sys; |
| 13 | 13 | ||
| 14 | impl Sys { | 14 | impl Sys { |
| 15 | pub(crate) fn new(ipcc: &mut Ipcc) -> Self { | 15 | pub(crate) fn new() -> Self { |
| 16 | unsafe { | 16 | unsafe { |
| 17 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | 17 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |
| 18 | 18 | ||
| @@ -22,12 +22,12 @@ impl Sys { | |||
| 22 | }); | 22 | }); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | ipcc.c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); | 25 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); |
| 26 | 26 | ||
| 27 | Sys | 27 | Sys |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | pub(crate) fn evt_handler(ipcc: &mut Ipcc) { | 30 | pub(crate) fn evt_handler() { |
| 31 | unsafe { | 31 | unsafe { |
| 32 | let mut node_ptr = core::ptr::null_mut(); | 32 | let mut node_ptr = core::ptr::null_mut(); |
| 33 | let node_ptr_ptr: *mut _ = &mut node_ptr; | 33 | let node_ptr_ptr: *mut _ = &mut node_ptr; |
| @@ -43,11 +43,11 @@ impl Sys { | |||
| 43 | } | 43 | } |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | ipcc.c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); | 46 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | pub(crate) fn cmd_evt_handler(ipcc: &mut Ipcc) -> CcEvt { | 49 | pub(crate) fn cmd_evt_handler() -> CcEvt { |
| 50 | ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); | 50 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); |
| 51 | 51 | ||
| 52 | // ST's command response data structure is really convoluted. | 52 | // ST's command response data structure is really convoluted. |
| 53 | // | 53 | // |
| @@ -68,11 +68,11 @@ impl Sys { | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | #[allow(dead_code)] | 70 | #[allow(dead_code)] |
| 71 | pub(crate) fn send_cmd(ipcc: &mut Ipcc, buf: &[u8]) { | 71 | pub(crate) fn send_cmd(buf: &[u8]) { |
| 72 | unsafe { | 72 | unsafe { |
| 73 | // TODO: check this | 73 | // TODO: check this |
| 74 | let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; | 74 | let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; |
| 75 | let cmd_serial: *mut CmdSerial = &mut (*cmd_buffer).cmd_serial; | 75 | let cmd_serial: *mut CmdSerial = &mut cmd_buffer.cmd_serial; |
| 76 | let cmd_serial_buf = cmd_serial.cast(); | 76 | let cmd_serial_buf = cmd_serial.cast(); |
| 77 | 77 | ||
| 78 | core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len()); | 78 | core::ptr::copy(buf.as_ptr(), cmd_serial_buf, buf.len()); |
| @@ -80,8 +80,8 @@ impl Sys { | |||
| 80 | let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; | 80 | let cmd_packet = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; |
| 81 | cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8; | 81 | cmd_packet.cmd_serial.ty = TlPacketType::SysCmd as u8; |
| 82 | 82 | ||
| 83 | ipcc.c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); | 83 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); |
| 84 | ipcc.c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); | 84 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); |
| 85 | } | 85 | } |
| 86 | } | 86 | } |
| 87 | } | 87 | } |
diff --git a/examples/stm32wb/src/bin/tl_mbox.rs b/examples/stm32wb/src/bin/tl_mbox.rs index 326e4be85..18d93a279 100644 --- a/examples/stm32wb/src/bin/tl_mbox.rs +++ b/examples/stm32wb/src/bin/tl_mbox.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::ipcc::{Config, Ipcc}; | 7 | use embassy_stm32::ipcc::Config; |
| 8 | use embassy_stm32::tl_mbox::TlMbox; | 8 | use embassy_stm32::tl_mbox::TlMbox; |
| 9 | use embassy_stm32::{bind_interrupts, tl_mbox}; | 9 | use embassy_stm32::{bind_interrupts, tl_mbox}; |
| 10 | use embassy_time::{Duration, Timer}; | 10 | use embassy_time::{Duration, Timer}; |
| @@ -41,13 +41,11 @@ async fn main(_spawner: Spawner) { | |||
| 41 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 41 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 42 | */ | 42 | */ |
| 43 | 43 | ||
| 44 | let p = embassy_stm32::init(Default::default()); | 44 | let _p = embassy_stm32::init(Default::default()); |
| 45 | info!("Hello World!"); | 45 | info!("Hello World!"); |
| 46 | 46 | ||
| 47 | let config = Config::default(); | 47 | let config = Config::default(); |
| 48 | let mut ipcc = Ipcc::new(p.IPCC, config); | 48 | let mbox = TlMbox::init(Irqs, config); |
| 49 | |||
| 50 | let mbox = TlMbox::init(&mut ipcc, Irqs); | ||
| 51 | 49 | ||
| 52 | loop { | 50 | loop { |
| 53 | let wireless_fw_info = mbox.wireless_fw_info(); | 51 | 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 index 7a69f26b7..41c450a53 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::ipcc::{Config, Ipcc}; | 7 | use embassy_stm32::ipcc::Config; |
| 8 | use embassy_stm32::tl_mbox::TlMbox; | 8 | use embassy_stm32::tl_mbox::TlMbox; |
| 9 | use embassy_stm32::{bind_interrupts, tl_mbox}; | 9 | use embassy_stm32::{bind_interrupts, tl_mbox}; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -40,16 +40,11 @@ async fn main(_spawner: Spawner) { | |||
| 40 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. | 40 | Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. |
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | let p = embassy_stm32::init(Default::default()); | 43 | let _p = embassy_stm32::init(Default::default()); |
| 44 | info!("Hello World!"); | 44 | info!("Hello World!"); |
| 45 | 45 | ||
| 46 | let config = Config::default(); | 46 | let config = Config::default(); |
| 47 | let mut ipcc = Ipcc::new(p.IPCC, config); | 47 | let mbox = TlMbox::init(Irqs, config); |
| 48 | |||
| 49 | let mbox = TlMbox::init(&mut ipcc, Irqs); | ||
| 50 | |||
| 51 | // initialize ble stack, does not return a response | ||
| 52 | mbox.shci_ble_init(&mut ipcc, Default::default()); | ||
| 53 | 48 | ||
| 54 | info!("waiting for coprocessor to boot"); | 49 | info!("waiting for coprocessor to boot"); |
| 55 | let event_box = mbox.read().await; | 50 | let event_box = mbox.read().await; |
| @@ -74,10 +69,11 @@ async fn main(_spawner: Spawner) { | |||
| 74 | ); | 69 | ); |
| 75 | } | 70 | } |
| 76 | 71 | ||
| 77 | mbox.shci_ble_init(&mut ipcc, Default::default()); | 72 | // initialize ble stack, does not return a response |
| 73 | mbox.shci_ble_init(Default::default()); | ||
| 78 | 74 | ||
| 79 | info!("resetting BLE"); | 75 | info!("resetting BLE"); |
| 80 | mbox.send_ble_cmd(&mut ipcc, &[0x01, 0x03, 0x0c, 0x00, 0x00]); | 76 | mbox.send_ble_cmd(&[0x01, 0x03, 0x0c, 0x00, 0x00]); |
| 81 | 77 | ||
| 82 | let event_box = mbox.read().await; | 78 | let event_box = mbox.read().await; |
| 83 | 79 | ||
| @@ -92,7 +88,10 @@ async fn main(_spawner: Spawner) { | |||
| 92 | 88 | ||
| 93 | info!( | 89 | info!( |
| 94 | "==> kind: {:#04x}, code: {:#04x}, payload_length: {}, payload: {:#04x}", | 90 | "==> kind: {:#04x}, code: {:#04x}, payload_length: {}, payload: {:#04x}", |
| 95 | kind, code, payload_len, payload | 91 | kind, |
| 92 | code, | ||
| 93 | payload_len, | ||
| 94 | payload[3..] | ||
| 96 | ); | 95 | ); |
| 97 | 96 | ||
| 98 | loop {} | 97 | loop {} |
