diff options
| author | goueslati <[email protected]> | 2023-06-12 12:27:51 +0100 |
|---|---|---|
| committer | goueslati <[email protected]> | 2023-06-12 12:27:51 +0100 |
| commit | ca8957da435eb91242fa33eb986e80a33bbc4da0 (patch) | |
| tree | 89b66bdff52630cd4ef1d609122c2b04417ccd73 | |
| parent | ce1d72c609ae1e04410e68458ec3d6c36c7dae27 (diff) | |
stm32/ipcc: move tl_mbox into `embassy-stm32-wpan`
| -rw-r--r-- | embassy-stm32-wpan/Cargo.toml | 23 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/ble.rs (renamed from embassy-stm32/src/tl_mbox/ble.rs) | 39 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/channels.rs (renamed from embassy-stm32/src/tl_mbox/channels.rs) | 16 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/cmd.rs (renamed from embassy-stm32/src/tl_mbox/cmd.rs) | 4 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/consts.rs (renamed from embassy-stm32/src/tl_mbox/consts.rs) | 0 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/evt.rs (renamed from embassy-stm32/src/tl_mbox/evt.rs) | 14 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/fmt.rs | 225 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/lib.rs (renamed from embassy-stm32/src/tl_mbox/mod.rs) | 266 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/mm.rs (renamed from embassy-stm32/src/tl_mbox/mm.rs) | 18 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/rc.rs | 50 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/shci.rs (renamed from embassy-stm32/src/tl_mbox/shci.rs) | 4 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sys.rs (renamed from embassy-stm32/src/tl_mbox/sys.rs) | 36 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/tables.rs | 175 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/unsafe_linked_list.rs (renamed from embassy-stm32/src/tl_mbox/unsafe_linked_list.rs) | 9 | ||||
| -rw-r--r-- | embassy-stm32/src/ipcc.rs (renamed from embassy-stm32/src/tl_mbox/ipcc.rs) | 60 | ||||
| -rw-r--r-- | embassy-stm32/src/lib.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/hci.rs | 60 | ||||
| -rw-r--r-- | examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | 20 |
18 files changed, 653 insertions, 370 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml new file mode 100644 index 000000000..a6673d472 --- /dev/null +++ b/embassy-stm32-wpan/Cargo.toml | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | [package] | ||
| 2 | name = "embassy-stm32-wpan" | ||
| 3 | version = "0.1.0" | ||
| 4 | edition = "2021" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", features = ["stm32wb55rg"] } | ||
| 9 | embassy-sync = { version = "0.2.0", path = "../embassy-sync" } | ||
| 10 | embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true } | ||
| 11 | embassy-futures = { version = "0.1.0", path = "../embassy-futures" } | ||
| 12 | embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]} | ||
| 13 | embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" } | ||
| 14 | embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } | ||
| 15 | |||
| 16 | defmt = { version = "0.3", optional = true } | ||
| 17 | cortex-m = "0.7.6" | ||
| 18 | heapless = "0.7.16" | ||
| 19 | |||
| 20 | bit_field = "0.10.2" | ||
| 21 | |||
| 22 | [features] | ||
| 23 | defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"] | ||
diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32-wpan/src/ble.rs index 45bf81ef2..4546bde07 100644 --- a/embassy-stm32/src/tl_mbox/ble.rs +++ b/embassy-stm32-wpan/src/ble.rs | |||
| @@ -1,23 +1,24 @@ | |||
| 1 | use embassy_futures::block_on; | 1 | use core::mem::MaybeUninit; |
| 2 | 2 | ||
| 3 | use super::cmd::{CmdPacket, CmdSerial}; | 3 | use embassy_stm32::ipcc::Ipcc; |
| 4 | use super::consts::TlPacketType; | 4 | |
| 5 | use super::evt::EvtBox; | 5 | use crate::cmd::{CmdPacket, CmdSerial}; |
| 6 | use super::ipcc::Ipcc; | 6 | use crate::consts::TlPacketType; |
| 7 | use super::unsafe_linked_list::LinkedListNode; | 7 | use crate::evt::EvtBox; |
| 8 | use super::{ | 8 | use crate::tables::BleTable; |
| 9 | channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, HEAPLESS_EVT_QUEUE, TL_BLE_TABLE, | 9 | use crate::unsafe_linked_list::LinkedListNode; |
| 10 | TL_REF_TABLE, | 10 | use crate::{ |
| 11 | channels, BLE_CMD_BUFFER, CS_BUFFER, EVT_CHANNEL, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_REF_TABLE, | ||
| 11 | }; | 12 | }; |
| 12 | 13 | ||
| 13 | pub struct Ble; | 14 | pub struct Ble; |
| 14 | 15 | ||
| 15 | impl Ble { | 16 | impl Ble { |
| 16 | pub(super) fn new() -> Self { | 17 | pub(super) fn enable() { |
| 17 | unsafe { | 18 | unsafe { |
| 18 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | 19 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |
| 19 | 20 | ||
| 20 | TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable { | 21 | TL_BLE_TABLE = MaybeUninit::new(BleTable { |
| 21 | pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), | 22 | pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), |
| 22 | pcs_buffer: CS_BUFFER.as_ptr().cast(), | 23 | pcs_buffer: CS_BUFFER.as_ptr().cast(), |
| 23 | pevt_queue: EVT_QUEUE.as_ptr().cast(), | 24 | pevt_queue: EVT_QUEUE.as_ptr().cast(), |
| @@ -26,8 +27,6 @@ impl Ble { | |||
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); | 29 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); |
| 29 | |||
| 30 | Ble | ||
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | pub(super) fn evt_handler() { | 32 | pub(super) fn evt_handler() { |
| @@ -41,20 +40,22 @@ impl Ble { | |||
| 41 | let event = node_ptr.cast(); | 40 | let event = node_ptr.cast(); |
| 42 | let event = EvtBox::new(event); | 41 | let event = EvtBox::new(event); |
| 43 | 42 | ||
| 44 | block_on(HEAPLESS_EVT_QUEUE.send(event)); | 43 | EVT_CHANNEL.try_send(event).unwrap(); |
| 45 | } | 44 | } |
| 46 | } | 45 | } |
| 47 | 46 | ||
| 48 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); | 47 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | pub(super) fn acl_data_handler(&self) { | 50 | pub(super) fn acl_data_handler() { |
| 52 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, false); | 51 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, false); |
| 53 | 52 | ||
| 54 | // TODO: ACL data ack to the user | 53 | // TODO: ACL data ack to the user |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | pub fn send_cmd(buf: &[u8]) { | 56 | pub fn ble_send_cmd(buf: &[u8]) { |
| 57 | debug!("writing ble cmd"); | ||
| 58 | |||
| 58 | unsafe { | 59 | unsafe { |
| 59 | let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; | 60 | let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; |
| 60 | let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmdserial; | 61 | let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmdserial; |
| @@ -70,8 +71,8 @@ impl Ble { | |||
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | #[allow(dead_code)] // Not used currently but reserved | 73 | #[allow(dead_code)] // Not used currently but reserved |
| 73 | pub(super) fn send_acl_data() { | 74 | pub(super) fn ble_send_acl_data() { |
| 74 | let cmd_packet = unsafe { &mut *(*TL_REF_TABLE.assume_init().ble_table).phci_acl_data_buffer }; | 75 | let mut cmd_packet = unsafe { &mut *(*TL_REF_TABLE.assume_init().ble_table).phci_acl_data_buffer }; |
| 75 | 76 | ||
| 76 | cmd_packet.acl_data_serial.ty = TlPacketType::AclData as u8; | 77 | cmd_packet.acl_data_serial.ty = TlPacketType::AclData as u8; |
| 77 | 78 | ||
diff --git a/embassy-stm32/src/tl_mbox/channels.rs b/embassy-stm32-wpan/src/channels.rs index 25a065ba4..9a2be1cfa 100644 --- a/embassy-stm32/src/tl_mbox/channels.rs +++ b/embassy-stm32-wpan/src/channels.rs | |||
| @@ -50,36 +50,30 @@ | |||
| 50 | //! | 50 | //! |
| 51 | 51 | ||
| 52 | pub mod cpu1 { | 52 | pub mod cpu1 { |
| 53 | use crate::tl_mbox::ipcc::IpccChannel; | 53 | use embassy_stm32::ipcc::IpccChannel; |
| 54 | 54 | ||
| 55 | // Not used currently but reserved | ||
| 56 | pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; | 55 | pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; |
| 57 | // Not used currently but reserved | ||
| 58 | pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2; | 56 | pub const IPCC_SYSTEM_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel2; |
| 59 | #[allow(dead_code)] // Not used currently but reserved | ||
| 60 | pub const IPCC_THREAD_OT_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; | 57 | pub const IPCC_THREAD_OT_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 61 | #[allow(dead_code)] // Not used currently but reserved | 58 | #[allow(dead_code)] // Not used currently but reserved |
| 62 | pub const IPCC_ZIGBEE_CMD_APPLI_CHANNEL: IpccChannel = IpccChannel::Channel3; | 59 | pub const IPCC_ZIGBEE_CMD_APPLI_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 63 | #[allow(dead_code)] // Not used currently but reserved | 60 | #[allow(dead_code)] // Not used currently but reserved |
| 64 | pub const IPCC_MAC_802_15_4_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; | 61 | pub const IPCC_MAC_802_15_4_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 65 | // Not used currently but reserved | ||
| 66 | pub const IPCC_MM_RELEASE_BUFFER_CHANNEL: IpccChannel = IpccChannel::Channel4; | ||
| 67 | #[allow(dead_code)] // Not used currently but reserved | 62 | #[allow(dead_code)] // Not used currently but reserved |
| 63 | pub const IPCC_MM_RELEASE_BUFFER_CHANNEL: IpccChannel = IpccChannel::Channel4; | ||
| 68 | pub const IPCC_THREAD_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; | 64 | pub const IPCC_THREAD_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; |
| 69 | #[allow(dead_code)] // Not used currently but reserved | 65 | #[allow(dead_code)] // Not used currently but reserved |
| 70 | pub const IPCC_LLDTESTS_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; | 66 | pub const IPCC_LLDTESTS_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; |
| 71 | #[allow(dead_code)] // Not used currently but reserved | 67 | #[allow(dead_code)] // Not used currently but reserved |
| 72 | pub const IPCC_BLE_LLD_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; | 68 | pub const IPCC_BLE_LLD_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; |
| 73 | #[allow(dead_code)] // Not used currently but reserved | ||
| 74 | pub const IPCC_HCI_ACL_DATA_CHANNEL: IpccChannel = IpccChannel::Channel6; | 69 | pub const IPCC_HCI_ACL_DATA_CHANNEL: IpccChannel = IpccChannel::Channel6; |
| 75 | } | 70 | } |
| 76 | 71 | ||
| 77 | pub mod cpu2 { | 72 | pub mod cpu2 { |
| 78 | use crate::tl_mbox::ipcc::IpccChannel; | 73 | use embassy_stm32::ipcc::IpccChannel; |
| 79 | 74 | ||
| 80 | pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; | 75 | pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; |
| 81 | pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; | 76 | pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; |
| 82 | #[allow(dead_code)] // Not used currently but reserved | ||
| 83 | pub const IPCC_THREAD_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; | 77 | pub const IPCC_THREAD_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 84 | #[allow(dead_code)] // Not used currently but reserved | 78 | #[allow(dead_code)] // Not used currently but reserved |
| 85 | pub const IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; | 79 | pub const IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| @@ -88,10 +82,8 @@ pub mod cpu2 { | |||
| 88 | #[allow(dead_code)] // Not used currently but reserved | 82 | #[allow(dead_code)] // Not used currently but reserved |
| 89 | pub const IPCC_LDDTESTS_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; | 83 | pub const IPCC_LDDTESTS_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 90 | #[allow(dead_code)] // Not used currently but reserved | 84 | #[allow(dead_code)] // Not used currently but reserved |
| 91 | pub const IPCC_BLE_LLD_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; | 85 | pub const IPCC_BLE_LLDÇM0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; |
| 92 | #[allow(dead_code)] // Not used currently but reserved | ||
| 93 | pub const IPCC_TRACES_CHANNEL: IpccChannel = IpccChannel::Channel4; | 86 | pub const IPCC_TRACES_CHANNEL: IpccChannel = IpccChannel::Channel4; |
| 94 | #[allow(dead_code)] // Not used currently but reserved | ||
| 95 | pub const IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel5; | 87 | pub const IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel5; |
| 96 | #[allow(dead_code)] // Not used currently but reserved | 88 | #[allow(dead_code)] // Not used currently but reserved |
| 97 | pub const IPCC_LLDTESTS_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; | 89 | pub const IPCC_LLDTESTS_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; |
diff --git a/embassy-stm32/src/tl_mbox/cmd.rs b/embassy-stm32-wpan/src/cmd.rs index 781aa669d..1f7dae7f7 100644 --- a/embassy-stm32/src/tl_mbox/cmd.rs +++ b/embassy-stm32-wpan/src/cmd.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | use crate::tl_mbox::evt::{EvtPacket, EvtSerial}; | 1 | use crate::evt::{EvtPacket, EvtSerial}; |
| 2 | use crate::tl_mbox::{PacketHeader, TL_EVT_HEADER_SIZE}; | 2 | use crate::{PacketHeader, TL_EVT_HEADER_SIZE}; |
| 3 | 3 | ||
| 4 | #[derive(Copy, Clone)] | 4 | #[derive(Copy, Clone)] |
| 5 | #[repr(C, packed)] | 5 | #[repr(C, packed)] |
diff --git a/embassy-stm32/src/tl_mbox/consts.rs b/embassy-stm32-wpan/src/consts.rs index caf26c06b..caf26c06b 100644 --- a/embassy-stm32/src/tl_mbox/consts.rs +++ b/embassy-stm32-wpan/src/consts.rs | |||
diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32-wpan/src/evt.rs index 77ce7b4ca..b53fe506e 100644 --- a/embassy-stm32/src/tl_mbox/evt.rs +++ b/embassy-stm32-wpan/src/evt.rs | |||
| @@ -2,13 +2,13 @@ use core::mem::MaybeUninit; | |||
| 2 | 2 | ||
| 3 | use super::cmd::{AclDataPacket, AclDataSerial}; | 3 | use super::cmd::{AclDataPacket, AclDataSerial}; |
| 4 | use super::consts::TlPacketType; | 4 | use super::consts::TlPacketType; |
| 5 | use super::mm::MemoryManager; | ||
| 6 | use super::{PacketHeader, TL_EVT_HEADER_SIZE}; | 5 | use super::{PacketHeader, TL_EVT_HEADER_SIZE}; |
| 6 | use crate::mm; | ||
| 7 | 7 | ||
| 8 | /** | 8 | /** |
| 9 | * The payload of `Evt` for a command status event | 9 | * The payload of `Evt` for a command status event |
| 10 | */ | 10 | */ |
| 11 | #[derive(Debug, Copy, Clone)] | 11 | #[derive(Copy, Clone)] |
| 12 | #[repr(C, packed)] | 12 | #[repr(C, packed)] |
| 13 | pub struct CsEvt { | 13 | pub struct CsEvt { |
| 14 | pub status: u8, | 14 | pub status: u8, |
| @@ -19,7 +19,7 @@ pub struct CsEvt { | |||
| 19 | /** | 19 | /** |
| 20 | * The payload of `Evt` for a command complete event | 20 | * The payload of `Evt` for a command complete event |
| 21 | */ | 21 | */ |
| 22 | #[derive(Debug, Copy, Clone, Default)] | 22 | #[derive(Copy, Clone, Default)] |
| 23 | #[repr(C, packed)] | 23 | #[repr(C, packed)] |
| 24 | pub struct CcEvt { | 24 | pub struct CcEvt { |
| 25 | pub num_cmd: u8, | 25 | pub num_cmd: u8, |
| @@ -41,14 +41,14 @@ impl CcEvt { | |||
| 41 | } | 41 | } |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | #[derive(Debug, Copy, Clone, Default)] | 44 | #[derive(Copy, Clone, Default)] |
| 45 | #[repr(C, packed)] | 45 | #[repr(C, packed)] |
| 46 | pub struct AsynchEvt { | 46 | pub struct AsynchEvt { |
| 47 | sub_evt_code: u16, | 47 | sub_evt_code: u16, |
| 48 | payload: [u8; 1], | 48 | payload: [u8; 1], |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | #[derive(Debug, Copy, Clone, Default)] | 51 | #[derive(Copy, Clone, Default)] |
| 52 | #[repr(C, packed)] | 52 | #[repr(C, packed)] |
| 53 | pub struct Evt { | 53 | pub struct Evt { |
| 54 | pub evt_code: u8, | 54 | pub evt_code: u8, |
| @@ -56,7 +56,7 @@ pub struct Evt { | |||
| 56 | pub payload: [u8; 1], | 56 | pub payload: [u8; 1], |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | #[derive(Debug, Copy, Clone, Default)] | 59 | #[derive(Copy, Clone, Default)] |
| 60 | #[repr(C, packed)] | 60 | #[repr(C, packed)] |
| 61 | pub struct EvtSerial { | 61 | pub struct EvtSerial { |
| 62 | pub kind: u8, | 62 | pub kind: u8, |
| @@ -171,6 +171,6 @@ impl EvtBox { | |||
| 171 | 171 | ||
| 172 | impl Drop for EvtBox { | 172 | impl Drop for EvtBox { |
| 173 | fn drop(&mut self) { | 173 | fn drop(&mut self) { |
| 174 | MemoryManager::evt_drop(self.ptr); | 174 | mm::MemoryManager::evt_drop(self.ptr); |
| 175 | } | 175 | } |
| 176 | } | 176 | } |
diff --git a/embassy-stm32-wpan/src/fmt.rs b/embassy-stm32-wpan/src/fmt.rs new file mode 100644 index 000000000..066970813 --- /dev/null +++ b/embassy-stm32-wpan/src/fmt.rs | |||
| @@ -0,0 +1,225 @@ | |||
| 1 | #![macro_use] | ||
| 2 | #![allow(unused_macros)] | ||
| 3 | |||
| 4 | #[cfg(all(feature = "defmt", feature = "log"))] | ||
| 5 | compile_error!("You may not enable both `defmt` and `log` features."); | ||
| 6 | |||
| 7 | macro_rules! assert { | ||
| 8 | ($($x:tt)*) => { | ||
| 9 | { | ||
| 10 | #[cfg(not(feature = "defmt"))] | ||
| 11 | ::core::assert!($($x)*); | ||
| 12 | #[cfg(feature = "defmt")] | ||
| 13 | ::defmt::assert!($($x)*); | ||
| 14 | } | ||
| 15 | }; | ||
| 16 | } | ||
| 17 | |||
| 18 | macro_rules! assert_eq { | ||
| 19 | ($($x:tt)*) => { | ||
| 20 | { | ||
| 21 | #[cfg(not(feature = "defmt"))] | ||
| 22 | ::core::assert_eq!($($x)*); | ||
| 23 | #[cfg(feature = "defmt")] | ||
| 24 | ::defmt::assert_eq!($($x)*); | ||
| 25 | } | ||
| 26 | }; | ||
| 27 | } | ||
| 28 | |||
| 29 | macro_rules! assert_ne { | ||
| 30 | ($($x:tt)*) => { | ||
| 31 | { | ||
| 32 | #[cfg(not(feature = "defmt"))] | ||
| 33 | ::core::assert_ne!($($x)*); | ||
| 34 | #[cfg(feature = "defmt")] | ||
| 35 | ::defmt::assert_ne!($($x)*); | ||
| 36 | } | ||
| 37 | }; | ||
| 38 | } | ||
| 39 | |||
| 40 | macro_rules! debug_assert { | ||
| 41 | ($($x:tt)*) => { | ||
| 42 | { | ||
| 43 | #[cfg(not(feature = "defmt"))] | ||
| 44 | ::core::debug_assert!($($x)*); | ||
| 45 | #[cfg(feature = "defmt")] | ||
| 46 | ::defmt::debug_assert!($($x)*); | ||
| 47 | } | ||
| 48 | }; | ||
| 49 | } | ||
| 50 | |||
| 51 | macro_rules! debug_assert_eq { | ||
| 52 | ($($x:tt)*) => { | ||
| 53 | { | ||
| 54 | #[cfg(not(feature = "defmt"))] | ||
| 55 | ::core::debug_assert_eq!($($x)*); | ||
| 56 | #[cfg(feature = "defmt")] | ||
| 57 | ::defmt::debug_assert_eq!($($x)*); | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | } | ||
| 61 | |||
| 62 | macro_rules! debug_assert_ne { | ||
| 63 | ($($x:tt)*) => { | ||
| 64 | { | ||
| 65 | #[cfg(not(feature = "defmt"))] | ||
| 66 | ::core::debug_assert_ne!($($x)*); | ||
| 67 | #[cfg(feature = "defmt")] | ||
| 68 | ::defmt::debug_assert_ne!($($x)*); | ||
| 69 | } | ||
| 70 | }; | ||
| 71 | } | ||
| 72 | |||
| 73 | macro_rules! todo { | ||
| 74 | ($($x:tt)*) => { | ||
| 75 | { | ||
| 76 | #[cfg(not(feature = "defmt"))] | ||
| 77 | ::core::todo!($($x)*); | ||
| 78 | #[cfg(feature = "defmt")] | ||
| 79 | ::defmt::todo!($($x)*); | ||
| 80 | } | ||
| 81 | }; | ||
| 82 | } | ||
| 83 | |||
| 84 | macro_rules! unreachable { | ||
| 85 | ($($x:tt)*) => { | ||
| 86 | { | ||
| 87 | #[cfg(not(feature = "defmt"))] | ||
| 88 | ::core::unreachable!($($x)*); | ||
| 89 | #[cfg(feature = "defmt")] | ||
| 90 | ::defmt::unreachable!($($x)*); | ||
| 91 | } | ||
| 92 | }; | ||
| 93 | } | ||
| 94 | |||
| 95 | macro_rules! panic { | ||
| 96 | ($($x:tt)*) => { | ||
| 97 | { | ||
| 98 | #[cfg(not(feature = "defmt"))] | ||
| 99 | ::core::panic!($($x)*); | ||
| 100 | #[cfg(feature = "defmt")] | ||
| 101 | ::defmt::panic!($($x)*); | ||
| 102 | } | ||
| 103 | }; | ||
| 104 | } | ||
| 105 | |||
| 106 | macro_rules! trace { | ||
| 107 | ($s:literal $(, $x:expr)* $(,)?) => { | ||
| 108 | { | ||
| 109 | #[cfg(feature = "log")] | ||
| 110 | ::log::trace!($s $(, $x)*); | ||
| 111 | #[cfg(feature = "defmt")] | ||
| 112 | ::defmt::trace!($s $(, $x)*); | ||
| 113 | #[cfg(not(any(feature = "log", feature="defmt")))] | ||
| 114 | let _ = ($( & $x ),*); | ||
| 115 | } | ||
| 116 | }; | ||
| 117 | } | ||
| 118 | |||
| 119 | macro_rules! debug { | ||
| 120 | ($s:literal $(, $x:expr)* $(,)?) => { | ||
| 121 | { | ||
| 122 | #[cfg(feature = "log")] | ||
| 123 | ::log::debug!($s $(, $x)*); | ||
| 124 | #[cfg(feature = "defmt")] | ||
| 125 | ::defmt::debug!($s $(, $x)*); | ||
| 126 | #[cfg(not(any(feature = "log", feature="defmt")))] | ||
| 127 | let _ = ($( & $x ),*); | ||
| 128 | } | ||
| 129 | }; | ||
| 130 | } | ||
| 131 | |||
| 132 | macro_rules! info { | ||
| 133 | ($s:literal $(, $x:expr)* $(,)?) => { | ||
| 134 | { | ||
| 135 | #[cfg(feature = "log")] | ||
| 136 | ::log::info!($s $(, $x)*); | ||
| 137 | #[cfg(feature = "defmt")] | ||
| 138 | ::defmt::info!($s $(, $x)*); | ||
| 139 | #[cfg(not(any(feature = "log", feature="defmt")))] | ||
| 140 | let _ = ($( & $x ),*); | ||
| 141 | } | ||
| 142 | }; | ||
| 143 | } | ||
| 144 | |||
| 145 | macro_rules! warn { | ||
| 146 | ($s:literal $(, $x:expr)* $(,)?) => { | ||
| 147 | { | ||
| 148 | #[cfg(feature = "log")] | ||
| 149 | ::log::warn!($s $(, $x)*); | ||
| 150 | #[cfg(feature = "defmt")] | ||
| 151 | ::defmt::warn!($s $(, $x)*); | ||
| 152 | #[cfg(not(any(feature = "log", feature="defmt")))] | ||
| 153 | let _ = ($( & $x ),*); | ||
| 154 | } | ||
| 155 | }; | ||
| 156 | } | ||
| 157 | |||
| 158 | macro_rules! error { | ||
| 159 | ($s:literal $(, $x:expr)* $(,)?) => { | ||
| 160 | { | ||
| 161 | #[cfg(feature = "log")] | ||
| 162 | ::log::error!($s $(, $x)*); | ||
| 163 | #[cfg(feature = "defmt")] | ||
| 164 | ::defmt::error!($s $(, $x)*); | ||
| 165 | #[cfg(not(any(feature = "log", feature="defmt")))] | ||
| 166 | let _ = ($( & $x ),*); | ||
| 167 | } | ||
| 168 | }; | ||
| 169 | } | ||
| 170 | |||
| 171 | #[cfg(feature = "defmt")] | ||
| 172 | macro_rules! unwrap { | ||
| 173 | ($($x:tt)*) => { | ||
| 174 | ::defmt::unwrap!($($x)*) | ||
| 175 | }; | ||
| 176 | } | ||
| 177 | |||
| 178 | #[cfg(not(feature = "defmt"))] | ||
| 179 | macro_rules! unwrap { | ||
| 180 | ($arg:expr) => { | ||
| 181 | match $crate::fmt::Try::into_result($arg) { | ||
| 182 | ::core::result::Result::Ok(t) => t, | ||
| 183 | ::core::result::Result::Err(e) => { | ||
| 184 | ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | }; | ||
| 188 | ($arg:expr, $($msg:expr),+ $(,)? ) => { | ||
| 189 | match $crate::fmt::Try::into_result($arg) { | ||
| 190 | ::core::result::Result::Ok(t) => t, | ||
| 191 | ::core::result::Result::Err(e) => { | ||
| 192 | ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] | ||
| 199 | pub struct NoneError; | ||
| 200 | |||
| 201 | pub trait Try { | ||
| 202 | type Ok; | ||
| 203 | type Error; | ||
| 204 | fn into_result(self) -> Result<Self::Ok, Self::Error>; | ||
| 205 | } | ||
| 206 | |||
| 207 | impl<T> Try for Option<T> { | ||
| 208 | type Ok = T; | ||
| 209 | type Error = NoneError; | ||
| 210 | |||
| 211 | #[inline] | ||
| 212 | fn into_result(self) -> Result<T, NoneError> { | ||
| 213 | self.ok_or(NoneError) | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | impl<T, E> Try for Result<T, E> { | ||
| 218 | type Ok = T; | ||
| 219 | type Error = E; | ||
| 220 | |||
| 221 | #[inline] | ||
| 222 | fn into_result(self) -> Self { | ||
| 223 | self | ||
| 224 | } | ||
| 225 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32-wpan/src/lib.rs index 21a954417..b3206428e 100644 --- a/embassy-stm32/src/tl_mbox/mod.rs +++ b/embassy-stm32-wpan/src/lib.rs | |||
| @@ -1,30 +1,37 @@ | |||
| 1 | #![no_std] | ||
| 2 | |||
| 3 | // This must go FIRST so that all the other modules see its macros. | ||
| 4 | pub mod fmt; | ||
| 5 | |||
| 1 | use core::mem::MaybeUninit; | 6 | use core::mem::MaybeUninit; |
| 2 | 7 | ||
| 3 | use bit_field::BitField; | 8 | use cmd::CmdPacket; |
| 4 | use embassy_cortex_m::interrupt::Interrupt; | 9 | use embassy_cortex_m::interrupt::Interrupt; |
| 5 | use embassy_futures::block_on; | 10 | use embassy_futures::block_on; |
| 6 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 11 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; |
| 12 | use embassy_stm32::interrupt; | ||
| 13 | use embassy_stm32::ipcc::{Config, Ipcc}; | ||
| 14 | use embassy_stm32::peripherals::IPCC; | ||
| 7 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 15 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 8 | use embassy_sync::channel::Channel; | 16 | use embassy_sync::channel::Channel; |
| 9 | use embassy_sync::signal::Signal; | 17 | use embassy_sync::signal::Signal; |
| 10 | 18 | use evt::{CcEvt, EvtBox}; | |
| 11 | use self::cmd::{AclDataPacket, CmdPacket}; | 19 | use tables::{ |
| 12 | use self::evt::{CcEvt, EvtBox}; | 20 | BleTable, DeviceInfoTable, Mac802_15_4Table, MemManagerTable, RefTable, SysTable, ThreadTable, TracesTable, |
| 13 | use self::ipcc::{Config, Ipcc}; | 21 | WirelessFwInfoTable, |
| 14 | use self::unsafe_linked_list::LinkedListNode; | 22 | }; |
| 15 | use crate::interrupt; | 23 | use unsafe_linked_list::LinkedListNode; |
| 16 | use crate::peripherals::IPCC; | ||
| 17 | 24 | ||
| 18 | pub mod ble; | 25 | pub mod ble; |
| 19 | pub mod channels; | 26 | pub mod channels; |
| 20 | pub mod cmd; | 27 | pub mod cmd; |
| 21 | pub mod consts; | 28 | pub mod consts; |
| 22 | pub mod evt; | 29 | pub mod evt; |
| 23 | pub mod hci; | ||
| 24 | pub mod ipcc; | ||
| 25 | pub mod mm; | 30 | pub mod mm; |
| 31 | pub mod rc; | ||
| 26 | pub mod shci; | 32 | pub mod shci; |
| 27 | pub mod sys; | 33 | pub mod sys; |
| 34 | pub mod tables; | ||
| 28 | pub mod unsafe_linked_list; | 35 | pub mod unsafe_linked_list; |
| 29 | 36 | ||
| 30 | /// Interrupt handler. | 37 | /// Interrupt handler. |
| @@ -32,16 +39,12 @@ pub struct ReceiveInterruptHandler {} | |||
| 32 | 39 | ||
| 33 | impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler { | 40 | impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler { |
| 34 | unsafe fn on_interrupt() { | 41 | unsafe fn on_interrupt() { |
| 35 | debug!("ipcc rx interrupt"); | ||
| 36 | |||
| 37 | if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { | 42 | if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { |
| 38 | debug!("sys evt"); | 43 | debug!("RX SYS evt"); |
| 39 | sys::Sys::evt_handler(); | 44 | sys::Sys::evt_handler(); |
| 40 | } else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { | 45 | } else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { |
| 41 | debug!("ble evt"); | 46 | debug!("RX BLE evt"); |
| 42 | ble::Ble::evt_handler(); | 47 | ble::Ble::evt_handler(); |
| 43 | } else { | ||
| 44 | todo!() | ||
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | STATE.signal(()); | 50 | STATE.signal(()); |
| @@ -52,198 +55,23 @@ pub struct TransmitInterruptHandler {} | |||
| 52 | 55 | ||
| 53 | impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler { | 56 | impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler { |
| 54 | unsafe fn on_interrupt() { | 57 | unsafe fn on_interrupt() { |
| 55 | debug!("ipcc tx interrupt"); | ||
| 56 | |||
| 57 | if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { | 58 | if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { |
| 58 | debug!("sys cmd rsp"); | 59 | debug!("TX SYS cmd rsp"); |
| 59 | // TODO: handle this case | ||
| 60 | let cc = sys::Sys::cmd_evt_handler(); | 60 | let cc = sys::Sys::cmd_evt_handler(); |
| 61 | let a = unsafe { core::slice::from_raw_parts(&cc as *const _ as *const u8, core::mem::size_of::<CcEvt>()) }; | ||
| 62 | debug!("{:#04x}", a); | ||
| 63 | 61 | ||
| 64 | LAST_CC_EVT.signal(cc); | 62 | LAST_CC_EVT.signal(cc); |
| 65 | } else if Ipcc::is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { | 63 | } else if Ipcc::is_tx_pending(channels::cpu1::IPCC_MM_RELEASE_BUFFER_CHANNEL) { |
| 66 | debug!("mm"); | 64 | debug!("TX MM release"); |
| 67 | mm::MemoryManager::free_buf_handler(); | 65 | mm::MemoryManager::free_buf_handler(); |
| 68 | } else { | 66 | } else if Ipcc::is_tx_pending(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL) { |
| 69 | todo!() | 67 | debug!("TX HCI acl"); |
| 68 | ble::Ble::acl_data_handler(); | ||
| 70 | } | 69 | } |
| 71 | 70 | ||
| 72 | STATE.signal(()); | 71 | STATE.signal(()); |
| 73 | } | 72 | } |
| 74 | } | 73 | } |
| 75 | 74 | ||
| 76 | #[derive(Debug, Copy, Clone)] | ||
| 77 | #[repr(C, packed)] | ||
| 78 | pub struct SafeBootInfoTable { | ||
| 79 | version: u32, | ||
| 80 | } | ||
| 81 | |||
| 82 | #[derive(Debug, Copy, Clone)] | ||
| 83 | #[repr(C, packed)] | ||
| 84 | pub struct RssInfoTable { | ||
| 85 | version: u32, | ||
| 86 | memory_size: u32, | ||
| 87 | rss_info: u32, | ||
| 88 | } | ||
| 89 | |||
| 90 | /** | ||
| 91 | * Version | ||
| 92 | * [0:3] = Build - 0: Untracked - 15:Released - x: Tracked version | ||
| 93 | * [4:7] = branch - 0: Mass Market - x: ... | ||
| 94 | * [8:15] = Subversion | ||
| 95 | * [16:23] = Version minor | ||
| 96 | * [24:31] = Version major | ||
| 97 | * | ||
| 98 | * Memory Size | ||
| 99 | * [0:7] = Flash ( Number of 4k sector) | ||
| 100 | * [8:15] = Reserved ( Shall be set to 0 - may be used as flash extension ) | ||
| 101 | * [16:23] = SRAM2b ( Number of 1k sector) | ||
| 102 | * [24:31] = SRAM2a ( Number of 1k sector) | ||
| 103 | */ | ||
| 104 | #[derive(Debug, Copy, Clone)] | ||
| 105 | #[repr(C, packed)] | ||
| 106 | pub struct WirelessFwInfoTable { | ||
| 107 | version: u32, | ||
| 108 | memory_size: u32, | ||
| 109 | thread_info: u32, | ||
| 110 | ble_info: u32, | ||
| 111 | } | ||
| 112 | |||
| 113 | impl WirelessFwInfoTable { | ||
| 114 | pub fn version_major(&self) -> u8 { | ||
| 115 | let version = self.version; | ||
| 116 | (version.get_bits(24..31) & 0xff) as u8 | ||
| 117 | } | ||
| 118 | |||
| 119 | pub fn version_minor(&self) -> u8 { | ||
| 120 | let version = self.version; | ||
| 121 | (version.clone().get_bits(16..23) & 0xff) as u8 | ||
| 122 | } | ||
| 123 | |||
| 124 | pub fn subversion(&self) -> u8 { | ||
| 125 | let version = self.version; | ||
| 126 | (version.clone().get_bits(8..15) & 0xff) as u8 | ||
| 127 | } | ||
| 128 | |||
| 129 | /// Size of FLASH, expressed in number of 4K sectors. | ||
| 130 | pub fn flash_size(&self) -> u8 { | ||
| 131 | let memory_size = self.memory_size; | ||
| 132 | (memory_size.clone().get_bits(0..7) & 0xff) as u8 | ||
| 133 | } | ||
| 134 | |||
| 135 | /// Size of SRAM2a, expressed in number of 1K sectors. | ||
| 136 | pub fn sram2a_size(&self) -> u8 { | ||
| 137 | let memory_size = self.memory_size; | ||
| 138 | (memory_size.clone().get_bits(24..31) & 0xff) as u8 | ||
| 139 | } | ||
| 140 | |||
| 141 | /// Size of SRAM2b, expressed in number of 1K sectors. | ||
| 142 | pub fn sram2b_size(&self) -> u8 { | ||
| 143 | let memory_size = self.memory_size; | ||
| 144 | (memory_size.clone().get_bits(16..23) & 0xff) as u8 | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | #[derive(Debug, Clone)] | ||
| 149 | #[repr(C, align(4))] | ||
| 150 | pub struct DeviceInfoTable { | ||
| 151 | pub safe_boot_info_table: SafeBootInfoTable, | ||
| 152 | pub rss_info_table: RssInfoTable, | ||
| 153 | pub wireless_fw_info_table: WirelessFwInfoTable, | ||
| 154 | } | ||
| 155 | |||
| 156 | #[derive(Debug)] | ||
| 157 | #[repr(C, align(4))] | ||
| 158 | struct BleTable { | ||
| 159 | pcmd_buffer: *mut CmdPacket, | ||
| 160 | pcs_buffer: *const u8, | ||
| 161 | pevt_queue: *const u8, | ||
| 162 | phci_acl_data_buffer: *mut AclDataPacket, | ||
| 163 | } | ||
| 164 | |||
| 165 | #[derive(Debug)] | ||
| 166 | #[repr(C, align(4))] | ||
| 167 | struct ThreadTable { | ||
| 168 | nostack_buffer: *const u8, | ||
| 169 | clicmdrsp_buffer: *const u8, | ||
| 170 | otcmdrsp_buffer: *const u8, | ||
| 171 | } | ||
| 172 | |||
| 173 | // TODO: use later | ||
| 174 | #[derive(Debug)] | ||
| 175 | #[repr(C, align(4))] | ||
| 176 | pub struct LldTestsTable { | ||
| 177 | clicmdrsp_buffer: *const u8, | ||
| 178 | m0cmd_buffer: *const u8, | ||
| 179 | } | ||
| 180 | |||
| 181 | // TODO: use later | ||
| 182 | #[derive(Debug)] | ||
| 183 | #[repr(C, align(4))] | ||
| 184 | pub struct BleLldTable { | ||
| 185 | cmdrsp_buffer: *const u8, | ||
| 186 | m0cmd_buffer: *const u8, | ||
| 187 | } | ||
| 188 | |||
| 189 | // TODO: use later | ||
| 190 | #[derive(Debug)] | ||
| 191 | #[repr(C, align(4))] | ||
| 192 | pub struct ZigbeeTable { | ||
| 193 | notif_m0_to_m4_buffer: *const u8, | ||
| 194 | appli_cmd_m4_to_m0_bufer: *const u8, | ||
| 195 | request_m0_to_m4_buffer: *const u8, | ||
| 196 | } | ||
| 197 | |||
| 198 | #[derive(Debug)] | ||
| 199 | #[repr(C, align(4))] | ||
| 200 | struct SysTable { | ||
| 201 | pcmd_buffer: *mut CmdPacket, | ||
| 202 | sys_queue: *const LinkedListNode, | ||
| 203 | } | ||
| 204 | |||
| 205 | #[derive(Debug)] | ||
| 206 | #[repr(C, align(4))] | ||
| 207 | struct MemManagerTable { | ||
| 208 | spare_ble_buffer: *const u8, | ||
| 209 | spare_sys_buffer: *const u8, | ||
| 210 | |||
| 211 | blepool: *const u8, | ||
| 212 | blepoolsize: u32, | ||
| 213 | |||
| 214 | pevt_free_buffer_queue: *mut LinkedListNode, | ||
| 215 | |||
| 216 | traces_evt_pool: *const u8, | ||
| 217 | tracespoolsize: u32, | ||
| 218 | } | ||
| 219 | |||
| 220 | #[derive(Debug)] | ||
| 221 | #[repr(C, align(4))] | ||
| 222 | struct TracesTable { | ||
| 223 | traces_queue: *const u8, | ||
| 224 | } | ||
| 225 | |||
| 226 | #[derive(Debug)] | ||
| 227 | #[repr(C, align(4))] | ||
| 228 | struct Mac802_15_4Table { | ||
| 229 | p_cmdrsp_buffer: *const u8, | ||
| 230 | p_notack_buffer: *const u8, | ||
| 231 | evt_queue: *const u8, | ||
| 232 | } | ||
| 233 | |||
| 234 | /// Reference table. Contains pointers to all other tables. | ||
| 235 | #[derive(Debug, Copy, Clone)] | ||
| 236 | #[repr(C)] | ||
| 237 | pub struct RefTable { | ||
| 238 | device_info_table: *const DeviceInfoTable, | ||
| 239 | ble_table: *const BleTable, | ||
| 240 | thread_table: *const ThreadTable, | ||
| 241 | sys_table: *const SysTable, | ||
| 242 | mem_manager_table: *const MemManagerTable, | ||
| 243 | traces_table: *const TracesTable, | ||
| 244 | mac_802_15_4_table: *const Mac802_15_4Table, | ||
| 245 | } | ||
| 246 | |||
| 247 | #[link_section = "TL_REF_TABLE"] | 75 | #[link_section = "TL_REF_TABLE"] |
| 248 | pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit(); | 76 | pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit(); |
| 249 | 77 | ||
| @@ -338,25 +166,21 @@ static mut BLE_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit(); | |||
| 338 | // fuck these "magic" numbers from ST ---v---v | 166 | // fuck these "magic" numbers from ST ---v---v |
| 339 | static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); | 167 | static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); |
| 340 | 168 | ||
| 341 | static HEAPLESS_EVT_QUEUE: Channel<CriticalSectionRawMutex, EvtBox, 32> = Channel::new(); | ||
| 342 | |||
| 343 | static STATE: Signal<CriticalSectionRawMutex, ()> = Signal::new(); | ||
| 344 | |||
| 345 | /// current event that is produced during IPCC IRQ handler execution | 169 | /// current event that is produced during IPCC IRQ handler execution |
| 346 | /// on SYS channel | 170 | /// on SYS channel |
| 171 | static EVT_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 32> = Channel::new(); | ||
| 172 | |||
| 347 | /// last received Command Complete event | 173 | /// last received Command Complete event |
| 348 | static LAST_CC_EVT: Signal<CriticalSectionRawMutex, CcEvt> = Signal::new(); | 174 | static LAST_CC_EVT: Signal<CriticalSectionRawMutex, CcEvt> = Signal::new(); |
| 349 | 175 | ||
| 350 | pub struct TlMbox<'d> { | 176 | static STATE: Signal<CriticalSectionRawMutex, ()> = Signal::new(); |
| 351 | sys: sys::Sys, | ||
| 352 | ble: ble::Ble, | ||
| 353 | _mm: mm::MemoryManager, | ||
| 354 | 177 | ||
| 178 | pub struct TlMbox<'d> { | ||
| 355 | _ipcc: PeripheralRef<'d, IPCC>, | 179 | _ipcc: PeripheralRef<'d, IPCC>, |
| 356 | } | 180 | } |
| 357 | 181 | ||
| 358 | impl<'d> TlMbox<'d> { | 182 | impl<'d> TlMbox<'d> { |
| 359 | pub fn new( | 183 | pub fn init( |
| 360 | ipcc: impl Peripheral<P = IPCC> + 'd, | 184 | ipcc: impl Peripheral<P = IPCC> + 'd, |
| 361 | _irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler> | 185 | _irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler> |
| 362 | + interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>, | 186 | + interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>, |
| @@ -365,7 +189,7 @@ impl<'d> TlMbox<'d> { | |||
| 365 | into_ref!(ipcc); | 189 | into_ref!(ipcc); |
| 366 | 190 | ||
| 367 | unsafe { | 191 | unsafe { |
| 368 | TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable { | 192 | TL_REF_TABLE = MaybeUninit::new(RefTable { |
| 369 | device_info_table: TL_DEVICE_INFO_TABLE.as_mut_ptr(), | 193 | device_info_table: TL_DEVICE_INFO_TABLE.as_mut_ptr(), |
| 370 | ble_table: TL_BLE_TABLE.as_ptr(), | 194 | ble_table: TL_BLE_TABLE.as_ptr(), |
| 371 | thread_table: TL_THREAD_TABLE.as_ptr(), | 195 | thread_table: TL_THREAD_TABLE.as_ptr(), |
| @@ -394,23 +218,20 @@ impl<'d> TlMbox<'d> { | |||
| 394 | 218 | ||
| 395 | Ipcc::enable(config); | 219 | Ipcc::enable(config); |
| 396 | 220 | ||
| 397 | let sys = sys::Sys::new(); | 221 | sys::Sys::enable(); |
| 398 | let ble = ble::Ble::new(); | 222 | ble::Ble::enable(); |
| 399 | let mm = mm::MemoryManager::new(); | 223 | mm::MemoryManager::enable(); |
| 400 | 224 | ||
| 401 | // enable interrupts | 225 | // enable interrupts |
| 402 | crate::interrupt::IPCC_C1_RX::unpend(); | 226 | interrupt::IPCC_C1_RX::unpend(); |
| 403 | crate::interrupt::IPCC_C1_TX::unpend(); | 227 | interrupt::IPCC_C1_TX::unpend(); |
| 404 | 228 | ||
| 405 | unsafe { crate::interrupt::IPCC_C1_RX::enable() }; | 229 | unsafe { interrupt::IPCC_C1_RX::enable() }; |
| 406 | unsafe { crate::interrupt::IPCC_C1_TX::enable() }; | 230 | unsafe { interrupt::IPCC_C1_TX::enable() }; |
| 407 | 231 | ||
| 408 | Self { | 232 | STATE.reset(); |
| 409 | sys, | 233 | |
| 410 | ble, | 234 | Self { _ipcc: ipcc } |
| 411 | _mm: mm, | ||
| 412 | _ipcc: ipcc, | ||
| 413 | } | ||
| 414 | } | 235 | } |
| 415 | 236 | ||
| 416 | /// Returns CPU2 wireless firmware information (if present). | 237 | /// Returns CPU2 wireless firmware information (if present). |
| @@ -429,16 +250,15 @@ impl<'d> TlMbox<'d> { | |||
| 429 | /// | 250 | /// |
| 430 | /// Internal event queu is populated in IPCC_RX_IRQ handler | 251 | /// Internal event queu is populated in IPCC_RX_IRQ handler |
| 431 | pub fn dequeue_event(&mut self) -> Option<EvtBox> { | 252 | pub fn dequeue_event(&mut self) -> Option<EvtBox> { |
| 432 | HEAPLESS_EVT_QUEUE.try_recv().ok() | 253 | EVT_CHANNEL.try_recv().ok() |
| 433 | } | 254 | } |
| 434 | 255 | ||
| 435 | /// retrieves last Command Complete event and removes it from mailbox | 256 | /// retrieves last Command Complete event and removes it from mailbox |
| 436 | pub fn pop_last_cc_evt(&mut self) -> Option<CcEvt> { | 257 | pub fn pop_last_cc_evt(&mut self) -> Option<CcEvt> { |
| 437 | if LAST_CC_EVT.signaled() { | 258 | if LAST_CC_EVT.signaled() { |
| 438 | let cc = Some(block_on(LAST_CC_EVT.wait())); | 259 | let cc = block_on(LAST_CC_EVT.wait()); |
| 439 | LAST_CC_EVT.reset(); | 260 | LAST_CC_EVT.reset(); |
| 440 | 261 | Some(cc) | |
| 441 | cc | ||
| 442 | } else { | 262 | } else { |
| 443 | None | 263 | None |
| 444 | } | 264 | } |
diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32-wpan/src/mm.rs index a40438499..ed13b0dbf 100644 --- a/embassy-stm32/src/tl_mbox/mm.rs +++ b/embassy-stm32-wpan/src/mm.rs | |||
| @@ -2,18 +2,20 @@ | |||
| 2 | 2 | ||
| 3 | use core::mem::MaybeUninit; | 3 | use core::mem::MaybeUninit; |
| 4 | 4 | ||
| 5 | use super::evt::EvtPacket; | 5 | use embassy_stm32::ipcc::Ipcc; |
| 6 | use super::ipcc::Ipcc; | 6 | |
| 7 | use super::unsafe_linked_list::LinkedListNode; | 7 | use crate::evt::EvtPacket; |
| 8 | use super::{ | 8 | use crate::tables::MemManagerTable; |
| 9 | channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, | 9 | use crate::unsafe_linked_list::LinkedListNode; |
| 10 | SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE, | 10 | use crate::{ |
| 11 | channels, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, | ||
| 12 | TL_MEM_MANAGER_TABLE, TL_REF_TABLE, | ||
| 11 | }; | 13 | }; |
| 12 | 14 | ||
| 13 | pub(super) struct MemoryManager; | 15 | pub(super) struct MemoryManager; |
| 14 | 16 | ||
| 15 | impl MemoryManager { | 17 | impl MemoryManager { |
| 16 | pub fn new() -> Self { | 18 | pub fn enable() { |
| 17 | unsafe { | 19 | unsafe { |
| 18 | LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); | 20 | LinkedListNode::init_head(FREE_BUF_QUEUE.as_mut_ptr()); |
| 19 | LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); | 21 | LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); |
| @@ -28,8 +30,6 @@ impl MemoryManager { | |||
| 28 | tracespoolsize: 0, | 30 | tracespoolsize: 0, |
| 29 | }); | 31 | }); |
| 30 | } | 32 | } |
| 31 | |||
| 32 | MemoryManager | ||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | pub fn evt_drop(evt: *mut EvtPacket) { | 35 | pub fn evt_drop(evt: *mut EvtPacket) { |
diff --git a/embassy-stm32-wpan/src/rc.rs b/embassy-stm32-wpan/src/rc.rs new file mode 100644 index 000000000..aae2265ed --- /dev/null +++ b/embassy-stm32-wpan/src/rc.rs | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | use crate::ble::Ble; | ||
| 2 | use crate::consts::TlPacketType; | ||
| 3 | use crate::{shci, TlMbox, STATE}; | ||
| 4 | |||
| 5 | pub struct RadioCoprocessor<'d> { | ||
| 6 | mbox: TlMbox<'d>, | ||
| 7 | rx_buf: [u8; 500], | ||
| 8 | } | ||
| 9 | |||
| 10 | impl<'d> RadioCoprocessor<'d> { | ||
| 11 | pub fn new(mbox: TlMbox<'d>) -> Self { | ||
| 12 | Self { | ||
| 13 | mbox, | ||
| 14 | rx_buf: [0u8; 500], | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | pub fn write(&self, buf: &[u8]) { | ||
| 19 | let cmd_code = buf[0]; | ||
| 20 | let cmd = TlPacketType::try_from(cmd_code).unwrap(); | ||
| 21 | |||
| 22 | match &cmd { | ||
| 23 | TlPacketType::BleCmd => Ble::ble_send_cmd(buf), | ||
| 24 | _ => todo!(), | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | pub async fn read(&mut self) -> &[u8] { | ||
| 29 | loop { | ||
| 30 | STATE.wait().await; | ||
| 31 | |||
| 32 | while let Some(evt) = self.mbox.dequeue_event() { | ||
| 33 | let event = evt.evt(); | ||
| 34 | |||
| 35 | evt.write(&mut self.rx_buf).unwrap(); | ||
| 36 | |||
| 37 | if event.kind() == 18 { | ||
| 38 | shci::shci_ble_init(Default::default()); | ||
| 39 | self.rx_buf[0] = 0x04; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | if self.mbox.pop_last_cc_evt().is_some() { | ||
| 44 | continue; | ||
| 45 | } | ||
| 46 | |||
| 47 | return &self.rx_buf; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/shci.rs b/embassy-stm32-wpan/src/shci.rs index b19baa702..4f4d08886 100644 --- a/embassy-stm32/src/tl_mbox/shci.rs +++ b/embassy-stm32-wpan/src/shci.rs | |||
| @@ -75,7 +75,7 @@ pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE | |||
| 75 | const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; | 75 | const TL_BLE_EVT_CS_BUFFER_SIZE: usize = TL_PACKET_HEADER_SIZE + TL_BLE_EVT_CS_PACKET_SIZE; |
| 76 | 76 | ||
| 77 | pub fn shci_ble_init(param: ShciBleInitCmdParam) { | 77 | pub fn shci_ble_init(param: ShciBleInitCmdParam) { |
| 78 | debug!("shci init"); | 78 | debug!("sending SHCI"); |
| 79 | 79 | ||
| 80 | let mut packet = ShciBleInitCmdPacket { | 80 | let mut packet = ShciBleInitCmdPacket { |
| 81 | header: ShciHeader::default(), | 81 | header: ShciHeader::default(), |
| @@ -95,6 +95,6 @@ pub fn shci_ble_init(param: ShciBleInitCmdParam) { | |||
| 95 | 95 | ||
| 96 | p_cmd_buffer.cmdserial.ty = TlPacketType::SysCmd as u8; | 96 | p_cmd_buffer.cmdserial.ty = TlPacketType::SysCmd as u8; |
| 97 | 97 | ||
| 98 | sys::send_cmd(); | 98 | sys::Sys::send_cmd(); |
| 99 | } | 99 | } |
| 100 | } | 100 | } |
diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32-wpan/src/sys.rs index c87aa440c..a19d12d27 100644 --- a/embassy-stm32/src/tl_mbox/sys.rs +++ b/embassy-stm32-wpan/src/sys.rs | |||
| @@ -1,27 +1,27 @@ | |||
| 1 | use embassy_futures::block_on; | 1 | use core::mem::MaybeUninit; |
| 2 | 2 | ||
| 3 | use super::cmd::{CmdPacket, CmdSerial}; | 3 | use embassy_stm32::ipcc::Ipcc; |
| 4 | use super::evt::{CcEvt, EvtBox, EvtSerial}; | 4 | |
| 5 | use super::ipcc::Ipcc; | 5 | use crate::cmd::{CmdPacket, CmdSerial}; |
| 6 | use super::unsafe_linked_list::LinkedListNode; | 6 | use crate::evt::{CcEvt, EvtBox, EvtSerial}; |
| 7 | use super::{channels, SysTable, HEAPLESS_EVT_QUEUE, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE}; | 7 | use crate::tables::SysTable; |
| 8 | use crate::unsafe_linked_list::LinkedListNode; | ||
| 9 | use crate::{channels, EVT_CHANNEL, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE}; | ||
| 8 | 10 | ||
| 9 | pub struct Sys; | 11 | pub struct Sys; |
| 10 | 12 | ||
| 11 | impl Sys { | 13 | impl Sys { |
| 12 | pub fn new() -> Self { | 14 | pub fn enable() { |
| 13 | unsafe { | 15 | unsafe { |
| 14 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | 16 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |
| 15 | 17 | ||
| 16 | TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable { | 18 | TL_SYS_TABLE = MaybeUninit::new(SysTable { |
| 17 | pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), | 19 | pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), |
| 18 | sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), | 20 | sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), |
| 19 | }) | 21 | }) |
| 20 | } | 22 | } |
| 21 | 23 | ||
| 22 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); | 24 | Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); |
| 23 | |||
| 24 | Sys | ||
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | pub fn cmd_evt_handler() -> CcEvt { | 27 | pub fn cmd_evt_handler() -> CcEvt { |
| @@ -38,12 +38,6 @@ impl Sys { | |||
| 38 | // 5. profit | 38 | // 5. profit |
| 39 | unsafe { | 39 | unsafe { |
| 40 | let pcmd: *const CmdPacket = (*TL_SYS_TABLE.as_ptr()).pcmd_buffer; | 40 | let pcmd: *const CmdPacket = (*TL_SYS_TABLE.as_ptr()).pcmd_buffer; |
| 41 | |||
| 42 | let a = unsafe { | ||
| 43 | core::slice::from_raw_parts(&pcmd as *const _ as *const u8, core::mem::size_of::<CmdPacket>()) | ||
| 44 | }; | ||
| 45 | debug!("shci response {:#04x}", a); | ||
| 46 | |||
| 47 | let cmd_serial: *const CmdSerial = &(*pcmd).cmdserial; | 41 | let cmd_serial: *const CmdSerial = &(*pcmd).cmdserial; |
| 48 | let evt_serial: *const EvtSerial = cmd_serial.cast(); | 42 | let evt_serial: *const EvtSerial = cmd_serial.cast(); |
| 49 | let cc: *const CcEvt = (*evt_serial).evt.payload.as_ptr().cast(); | 43 | let cc: *const CcEvt = (*evt_serial).evt.payload.as_ptr().cast(); |
| @@ -62,15 +56,15 @@ impl Sys { | |||
| 62 | let event = node_ptr.cast(); | 56 | let event = node_ptr.cast(); |
| 63 | let event = EvtBox::new(event); | 57 | let event = EvtBox::new(event); |
| 64 | 58 | ||
| 65 | block_on(HEAPLESS_EVT_QUEUE.send(event)); | 59 | EVT_CHANNEL.try_send(event).unwrap(); |
| 66 | } | 60 | } |
| 67 | } | 61 | } |
| 68 | 62 | ||
| 69 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); | 63 | Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); |
| 70 | } | 64 | } |
| 71 | } | ||
| 72 | 65 | ||
| 73 | pub fn send_cmd() { | 66 | pub fn send_cmd() { |
| 74 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); | 67 | Ipcc::c1_set_flag_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL); |
| 75 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); | 68 | Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, true); |
| 69 | } | ||
| 76 | } | 70 | } |
diff --git a/embassy-stm32-wpan/src/tables.rs b/embassy-stm32-wpan/src/tables.rs new file mode 100644 index 000000000..151216958 --- /dev/null +++ b/embassy-stm32-wpan/src/tables.rs | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | use bit_field::BitField; | ||
| 2 | |||
| 3 | use crate::cmd::{AclDataPacket, CmdPacket}; | ||
| 4 | use crate::unsafe_linked_list::LinkedListNode; | ||
| 5 | |||
| 6 | #[derive(Debug, Copy, Clone)] | ||
| 7 | #[repr(C, packed)] | ||
| 8 | pub struct SafeBootInfoTable { | ||
| 9 | version: u32, | ||
| 10 | } | ||
| 11 | |||
| 12 | #[derive(Debug, Copy, Clone)] | ||
| 13 | #[repr(C, packed)] | ||
| 14 | pub struct RssInfoTable { | ||
| 15 | pub version: u32, | ||
| 16 | pub memory_size: u32, | ||
| 17 | pub rss_info: u32, | ||
| 18 | } | ||
| 19 | |||
| 20 | /** | ||
| 21 | * Version | ||
| 22 | * [0:3] = Build - 0: Untracked - 15:Released - x: Tracked version | ||
| 23 | * [4:7] = branch - 0: Mass Market - x: ... | ||
| 24 | * [8:15] = Subversion | ||
| 25 | * [16:23] = Version minor | ||
| 26 | * [24:31] = Version major | ||
| 27 | * | ||
| 28 | * Memory Size | ||
| 29 | * [0:7] = Flash ( Number of 4k sector) | ||
| 30 | * [8:15] = Reserved ( Shall be set to 0 - may be used as flash extension ) | ||
| 31 | * [16:23] = SRAM2b ( Number of 1k sector) | ||
| 32 | * [24:31] = SRAM2a ( Number of 1k sector) | ||
| 33 | */ | ||
| 34 | #[derive(Debug, Copy, Clone)] | ||
| 35 | #[repr(C, packed)] | ||
| 36 | pub struct WirelessFwInfoTable { | ||
| 37 | pub version: u32, | ||
| 38 | pub memory_size: u32, | ||
| 39 | pub thread_info: u32, | ||
| 40 | pub ble_info: u32, | ||
| 41 | } | ||
| 42 | |||
| 43 | impl WirelessFwInfoTable { | ||
| 44 | pub fn version_major(&self) -> u8 { | ||
| 45 | let version = self.version; | ||
| 46 | (version.get_bits(24..31) & 0xff) as u8 | ||
| 47 | } | ||
| 48 | |||
| 49 | pub fn version_minor(&self) -> u8 { | ||
| 50 | let version = self.version; | ||
| 51 | (version.clone().get_bits(16..23) & 0xff) as u8 | ||
| 52 | } | ||
| 53 | |||
| 54 | pub fn subversion(&self) -> u8 { | ||
| 55 | let version = self.version; | ||
| 56 | (version.clone().get_bits(8..15) & 0xff) as u8 | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Size of FLASH, expressed in number of 4K sectors. | ||
| 60 | pub fn flash_size(&self) -> u8 { | ||
| 61 | let memory_size = self.memory_size; | ||
| 62 | (memory_size.clone().get_bits(0..7) & 0xff) as u8 | ||
| 63 | } | ||
| 64 | |||
| 65 | /// Size of SRAM2a, expressed in number of 1K sectors. | ||
| 66 | pub fn sram2a_size(&self) -> u8 { | ||
| 67 | let memory_size = self.memory_size; | ||
| 68 | (memory_size.clone().get_bits(24..31) & 0xff) as u8 | ||
| 69 | } | ||
| 70 | |||
| 71 | /// Size of SRAM2b, expressed in number of 1K sectors. | ||
| 72 | pub fn sram2b_size(&self) -> u8 { | ||
| 73 | let memory_size = self.memory_size; | ||
| 74 | (memory_size.clone().get_bits(16..23) & 0xff) as u8 | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | #[derive(Debug, Clone)] | ||
| 79 | #[repr(C, align(4))] | ||
| 80 | pub struct DeviceInfoTable { | ||
| 81 | pub safe_boot_info_table: SafeBootInfoTable, | ||
| 82 | pub rss_info_table: RssInfoTable, | ||
| 83 | pub wireless_fw_info_table: WirelessFwInfoTable, | ||
| 84 | } | ||
| 85 | |||
| 86 | #[derive(Debug)] | ||
| 87 | #[repr(C, align(4))] | ||
| 88 | pub struct BleTable { | ||
| 89 | pub pcmd_buffer: *mut CmdPacket, | ||
| 90 | pub pcs_buffer: *const u8, | ||
| 91 | pub pevt_queue: *const u8, | ||
| 92 | pub phci_acl_data_buffer: *mut AclDataPacket, | ||
| 93 | } | ||
| 94 | |||
| 95 | #[derive(Debug)] | ||
| 96 | #[repr(C, align(4))] | ||
| 97 | pub struct ThreadTable { | ||
| 98 | pub nostack_buffer: *const u8, | ||
| 99 | pub clicmdrsp_buffer: *const u8, | ||
| 100 | pub otcmdrsp_buffer: *const u8, | ||
| 101 | } | ||
| 102 | |||
| 103 | // TODO: use later | ||
| 104 | #[derive(Debug)] | ||
| 105 | #[repr(C, align(4))] | ||
| 106 | pub struct LldTestsTable { | ||
| 107 | pub clicmdrsp_buffer: *const u8, | ||
| 108 | pub m0cmd_buffer: *const u8, | ||
| 109 | } | ||
| 110 | |||
| 111 | // TODO: use later | ||
| 112 | #[derive(Debug)] | ||
| 113 | #[repr(C, align(4))] | ||
| 114 | pub struct BleLldTable { | ||
| 115 | pub cmdrsp_buffer: *const u8, | ||
| 116 | pub m0cmd_buffer: *const u8, | ||
| 117 | } | ||
| 118 | |||
| 119 | // TODO: use later | ||
| 120 | #[derive(Debug)] | ||
| 121 | #[repr(C, align(4))] | ||
| 122 | pub struct ZigbeeTable { | ||
| 123 | pub notif_m0_to_m4_buffer: *const u8, | ||
| 124 | pub appli_cmd_m4_to_m0_bufer: *const u8, | ||
| 125 | pub request_m0_to_m4_buffer: *const u8, | ||
| 126 | } | ||
| 127 | |||
| 128 | #[derive(Debug)] | ||
| 129 | #[repr(C, align(4))] | ||
| 130 | pub struct SysTable { | ||
| 131 | pub pcmd_buffer: *mut CmdPacket, | ||
| 132 | pub sys_queue: *const LinkedListNode, | ||
| 133 | } | ||
| 134 | |||
| 135 | #[derive(Debug)] | ||
| 136 | #[repr(C, align(4))] | ||
| 137 | pub struct MemManagerTable { | ||
| 138 | pub spare_ble_buffer: *const u8, | ||
| 139 | pub spare_sys_buffer: *const u8, | ||
| 140 | |||
| 141 | pub blepool: *const u8, | ||
| 142 | pub blepoolsize: u32, | ||
| 143 | |||
| 144 | pub pevt_free_buffer_queue: *mut LinkedListNode, | ||
| 145 | |||
| 146 | pub traces_evt_pool: *const u8, | ||
| 147 | pub tracespoolsize: u32, | ||
| 148 | } | ||
| 149 | |||
| 150 | #[derive(Debug)] | ||
| 151 | #[repr(C, align(4))] | ||
| 152 | pub struct TracesTable { | ||
| 153 | pub traces_queue: *const u8, | ||
| 154 | } | ||
| 155 | |||
| 156 | #[derive(Debug)] | ||
| 157 | #[repr(C, align(4))] | ||
| 158 | pub struct Mac802_15_4Table { | ||
| 159 | pub p_cmdrsp_buffer: *const u8, | ||
| 160 | pub p_notack_buffer: *const u8, | ||
| 161 | pub evt_queue: *const u8, | ||
| 162 | } | ||
| 163 | |||
| 164 | /// Reference table. Contains pointers to all other tables. | ||
| 165 | #[derive(Debug, Copy, Clone)] | ||
| 166 | #[repr(C)] | ||
| 167 | pub struct RefTable { | ||
| 168 | pub device_info_table: *const DeviceInfoTable, | ||
| 169 | pub ble_table: *const BleTable, | ||
| 170 | pub thread_table: *const ThreadTable, | ||
| 171 | pub sys_table: *const SysTable, | ||
| 172 | pub mem_manager_table: *const MemManagerTable, | ||
| 173 | pub traces_table: *const TracesTable, | ||
| 174 | pub mac_802_15_4_table: *const Mac802_15_4Table, | ||
| 175 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs b/embassy-stm32-wpan/src/unsafe_linked_list.rs index 482e2bf5a..52c106fa2 100644 --- a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs +++ b/embassy-stm32-wpan/src/unsafe_linked_list.rs | |||
| @@ -57,6 +57,7 @@ impl LinkedListNode { | |||
| 57 | }); | 57 | }); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | /// Remove `node` from the linked list | ||
| 60 | pub unsafe fn remove_node(mut node: *mut LinkedListNode) { | 61 | pub unsafe fn remove_node(mut node: *mut LinkedListNode) { |
| 61 | interrupt::free(|_| { | 62 | interrupt::free(|_| { |
| 62 | (*(*node).prev).next = (*node).next; | 63 | (*(*node).prev).next = (*node).next; |
| @@ -64,6 +65,7 @@ impl LinkedListNode { | |||
| 64 | }); | 65 | }); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 68 | /// Remove `list_head` into `node` | ||
| 67 | pub unsafe fn remove_head(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 69 | pub unsafe fn remove_head(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { |
| 68 | interrupt::free(|_| { | 70 | interrupt::free(|_| { |
| 69 | *node = (*list_head).next; | 71 | *node = (*list_head).next; |
| @@ -71,10 +73,11 @@ impl LinkedListNode { | |||
| 71 | }); | 73 | }); |
| 72 | } | 74 | } |
| 73 | 75 | ||
| 74 | pub unsafe fn remove_tail(mut list_head: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | 76 | /// Remove `list_tail` into `node` |
| 77 | pub unsafe fn remove_tail(mut list_tail: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | ||
| 75 | interrupt::free(|_| { | 78 | interrupt::free(|_| { |
| 76 | *node = (*list_head).prev; | 79 | *node = (*list_tail).prev; |
| 77 | Self::remove_node((*list_head).prev); | 80 | Self::remove_node((*list_tail).prev); |
| 78 | }); | 81 | }); |
| 79 | } | 82 | } |
| 80 | 83 | ||
diff --git a/embassy-stm32/src/tl_mbox/ipcc.rs b/embassy-stm32/src/ipcc.rs index d1ac731ed..8bb0774b8 100644 --- a/embassy-stm32/src/tl_mbox/ipcc.rs +++ b/embassy-stm32/src/ipcc.rs | |||
| @@ -167,8 +167,68 @@ impl sealed::Instance for crate::peripherals::IPCC { | |||
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | unsafe fn _configure_pwr() { | 169 | unsafe fn _configure_pwr() { |
| 170 | let pwr = crate::pac::PWR; | ||
| 170 | let rcc = crate::pac::RCC; | 171 | let rcc = crate::pac::RCC; |
| 171 | 172 | ||
| 173 | rcc.cfgr().modify(|w| w.set_stopwuck(true)); | ||
| 174 | |||
| 175 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 176 | pwr.cr1().modify(|w| w.set_dbp(true)); | ||
| 177 | |||
| 178 | // configure LSE | ||
| 179 | rcc.bdcr().modify(|w| w.set_lseon(true)); | ||
| 180 | |||
| 181 | // select system clock source = PLL | ||
| 182 | // set PLL coefficients | ||
| 183 | // m: 2, | ||
| 184 | // n: 12, | ||
| 185 | // r: 3, | ||
| 186 | // q: 4, | ||
| 187 | // p: 3, | ||
| 188 | let src_bits = 0b11; | ||
| 189 | let pllp = (3 - 1) & 0b11111; | ||
| 190 | let pllq = (4 - 1) & 0b111; | ||
| 191 | let pllr = (3 - 1) & 0b111; | ||
| 192 | let plln = 12 & 0b1111111; | ||
| 193 | let pllm = (2 - 1) & 0b111; | ||
| 194 | rcc.pllcfgr().modify(|w| { | ||
| 195 | w.set_pllsrc(src_bits); | ||
| 196 | w.set_pllm(pllm); | ||
| 197 | w.set_plln(plln); | ||
| 198 | w.set_pllr(pllr); | ||
| 199 | w.set_pllp(pllp); | ||
| 200 | w.set_pllpen(true); | ||
| 201 | w.set_pllq(pllq); | ||
| 202 | w.set_pllqen(true); | ||
| 203 | }); | ||
| 204 | // enable PLL | ||
| 205 | rcc.cr().modify(|w| w.set_pllon(true)); | ||
| 206 | rcc.cr().write(|w| w.set_hsion(false)); | ||
| 207 | // while !rcc.cr().read().pllrdy() {} | ||
| 208 | |||
| 209 | // configure SYSCLK mux to use PLL clocl | ||
| 210 | rcc.cfgr().modify(|w| w.set_sw(0b11)); | ||
| 211 | |||
| 212 | // configure CPU1 & CPU2 dividers | ||
| 213 | rcc.cfgr().modify(|w| w.set_hpre(0)); // not divided | ||
| 214 | rcc.extcfgr().modify(|w| { | ||
| 215 | w.set_c2hpre(0b1000); // div2 | ||
| 216 | w.set_shdhpre(0); // not divided | ||
| 217 | }); | ||
| 218 | |||
| 219 | // apply APB1 / APB2 values | ||
| 220 | rcc.cfgr().modify(|w| { | ||
| 221 | w.set_ppre1(0b000); // not divided | ||
| 222 | w.set_ppre2(0b000); // not divided | ||
| 223 | }); | ||
| 224 | |||
| 225 | // TODO: required | ||
| 172 | // set RF wake-up clock = LSE | 226 | // set RF wake-up clock = LSE |
| 173 | rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); | 227 | rcc.csr().modify(|w| w.set_rfwkpsel(0b01)); |
| 228 | |||
| 229 | // set LPTIM1 & LPTIM2 clock source | ||
| 230 | rcc.ccipr().modify(|w| { | ||
| 231 | w.set_lptim1sel(0b00); // PCLK | ||
| 232 | w.set_lptim2sel(0b00); // PCLK | ||
| 233 | }); | ||
| 174 | } | 234 | } |
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 75d8af3dd..8c13774a0 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -41,6 +41,8 @@ pub mod crc; | |||
| 41 | pub mod flash; | 41 | pub mod flash; |
| 42 | #[cfg(all(spi_v1, rcc_f4))] | 42 | #[cfg(all(spi_v1, rcc_f4))] |
| 43 | pub mod i2s; | 43 | pub mod i2s; |
| 44 | #[cfg(stm32wb)] | ||
| 45 | pub mod ipcc; | ||
| 44 | pub mod pwm; | 46 | pub mod pwm; |
| 45 | #[cfg(quadspi)] | 47 | #[cfg(quadspi)] |
| 46 | pub mod qspi; | 48 | pub mod qspi; |
| @@ -52,8 +54,6 @@ pub mod rtc; | |||
| 52 | pub mod sdmmc; | 54 | pub mod sdmmc; |
| 53 | #[cfg(spi)] | 55 | #[cfg(spi)] |
| 54 | pub mod spi; | 56 | pub mod spi; |
| 55 | #[cfg(stm32wb)] | ||
| 56 | pub mod tl_mbox; | ||
| 57 | #[cfg(usart)] | 57 | #[cfg(usart)] |
| 58 | pub mod usart; | 58 | pub mod usart; |
| 59 | #[cfg(usb)] | 59 | #[cfg(usb)] |
diff --git a/embassy-stm32/src/tl_mbox/hci.rs b/embassy-stm32/src/tl_mbox/hci.rs deleted file mode 100644 index 5bb4ba666..000000000 --- a/embassy-stm32/src/tl_mbox/hci.rs +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | use super::ble::Ble; | ||
| 2 | use super::consts::TlPacketType; | ||
| 3 | use super::evt::CcEvt; | ||
| 4 | use super::shci::{shci_ble_init, ShciBleInitCmdParam}; | ||
| 5 | use super::{TlMbox, STATE}; | ||
| 6 | |||
| 7 | pub struct RadioCoprocessor<'d> { | ||
| 8 | mbox: TlMbox<'d>, | ||
| 9 | config: ShciBleInitCmdParam, | ||
| 10 | rx_buffer: [u8; 500], | ||
| 11 | } | ||
| 12 | |||
| 13 | impl<'d> RadioCoprocessor<'d> { | ||
| 14 | pub fn new(mbox: TlMbox<'d>, config: ShciBleInitCmdParam) -> Self { | ||
| 15 | Self { | ||
| 16 | mbox, | ||
| 17 | config, | ||
| 18 | rx_buffer: [0u8; 500], | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | pub fn write(&mut self, params: &[u8]) -> Result<(), ()> { | ||
| 23 | let cmd_code = params[0]; | ||
| 24 | let cmd = TlPacketType::try_from(cmd_code)?; | ||
| 25 | |||
| 26 | match cmd { | ||
| 27 | TlPacketType::BleCmd => Ble::send_cmd(params), | ||
| 28 | _ => todo!(), | ||
| 29 | } | ||
| 30 | |||
| 31 | Ok(()) | ||
| 32 | } | ||
| 33 | |||
| 34 | pub async fn read(&mut self) -> &[u8] { | ||
| 35 | self.rx_buffer = [0u8; 500]; | ||
| 36 | |||
| 37 | loop { | ||
| 38 | STATE.wait().await; | ||
| 39 | |||
| 40 | if let Some(evt) = self.mbox.dequeue_event() { | ||
| 41 | let event = evt.evt(); | ||
| 42 | evt.write(&mut self.rx_buffer).unwrap(); | ||
| 43 | |||
| 44 | if event.kind() == 18 { | ||
| 45 | shci_ble_init(self.config); | ||
| 46 | self.rx_buffer[0] = 0x04; // replace event code with one that is supported by HCI | ||
| 47 | } | ||
| 48 | |||
| 49 | if let Some(cc) = self.mbox.pop_last_cc_evt() { | ||
| 50 | |||
| 51 | |||
| 52 | continue; | ||
| 53 | } | ||
| 54 | |||
| 55 | let payload_len = self.rx_buffer[2]; | ||
| 56 | return &self.rx_buffer[..3 + payload_len as usize]; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
diff --git a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs index 0525d3f37..3132ab3e4 100644 --- a/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs +++ b/examples/stm32wb/src/bin/tl_mbox_tx_rx.rs | |||
| @@ -4,15 +4,15 @@ | |||
| 4 | 4 | ||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_stm32::tl_mbox::hci::RadioCoprocessor; | 7 | use embassy_stm32::bind_interrupts; |
| 8 | use embassy_stm32::tl_mbox::ipcc::Config; | 8 | use embassy_stm32::ipcc::Config; |
| 9 | use embassy_stm32::tl_mbox::TlMbox; | 9 | use embassy_stm32_wpan::rc::RadioCoprocessor; |
| 10 | use embassy_stm32::{bind_interrupts, tl_mbox}; | 10 | use embassy_stm32_wpan::TlMbox; |
| 11 | use {defmt_rtt as _, panic_probe as _}; | 11 | use {defmt_rtt as _, panic_probe as _}; |
| 12 | 12 | ||
| 13 | bind_interrupts!(struct Irqs{ | 13 | bind_interrupts!(struct Irqs{ |
| 14 | IPCC_C1_RX => tl_mbox::ReceiveInterruptHandler; | 14 | IPCC_C1_RX => embassy_stm32_wpan::ReceiveInterruptHandler; |
| 15 | IPCC_C1_TX => tl_mbox::TransmitInterruptHandler; | 15 | IPCC_C1_TX => embassy_stm32_wpan::TransmitInterruptHandler; |
| 16 | }); | 16 | }); |
| 17 | 17 | ||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| @@ -45,16 +45,16 @@ async fn main(_spawner: Spawner) { | |||
| 45 | info!("Hello World!"); | 45 | info!("Hello World!"); |
| 46 | 46 | ||
| 47 | let config = Config::default(); | 47 | let config = Config::default(); |
| 48 | let mbox = TlMbox::new(p.IPCC, Irqs, config); | 48 | let mbox = TlMbox::init(p.IPCC, Irqs, config); |
| 49 | 49 | ||
| 50 | let mut rc = RadioCoprocessor::new(mbox, Default::default()); | 50 | let mut rc = RadioCoprocessor::new(mbox); |
| 51 | rc.write(&[0x01, 0x03, 0x0c, 0x00, 0x00]).unwrap(); | ||
| 52 | 51 | ||
| 53 | let response = rc.read().await; | 52 | let response = rc.read().await; |
| 54 | info!("coprocessor ready {}", response); | 53 | info!("coprocessor ready {}", response); |
| 55 | 54 | ||
| 55 | rc.write(&[0x01, 0x03, 0x0c, 0x00, 0x00]); | ||
| 56 | let response = rc.read().await; | 56 | let response = rc.read().await; |
| 57 | info!("coprocessor ready {}", response); | 57 | info!("ble reset rsp {}", response); |
| 58 | 58 | ||
| 59 | info!("Test OK"); | 59 | info!("Test OK"); |
| 60 | cortex_m::asm::bkpt(); | 60 | cortex_m::asm::bkpt(); |
