diff options
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/ble.rs | 26 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/channels.rs | 104 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/cmd.rs | 49 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/evt.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/mm.rs | 30 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/mod.rs | 318 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/sys.rs | 24 | ||||
| -rw-r--r-- | embassy-stm32/src/tl_mbox/unsafe_linked_list.rs | 123 |
9 files changed, 684 insertions, 0 deletions
diff --git a/embassy-stm32/src/lib.rs b/embassy-stm32/src/lib.rs index 11820b7a0..b3dbe1e2f 100644 --- a/embassy-stm32/src/lib.rs +++ b/embassy-stm32/src/lib.rs | |||
| @@ -57,6 +57,8 @@ pub mod rtc; | |||
| 57 | pub mod sdmmc; | 57 | pub mod sdmmc; |
| 58 | #[cfg(spi)] | 58 | #[cfg(spi)] |
| 59 | pub mod spi; | 59 | pub mod spi; |
| 60 | #[cfg(stm32wb)] | ||
| 61 | pub mod tl_mbox; | ||
| 60 | #[cfg(usart)] | 62 | #[cfg(usart)] |
| 61 | pub mod usart; | 63 | pub mod usart; |
| 62 | #[cfg(all(usb, feature = "time"))] | 64 | #[cfg(all(usb, feature = "time"))] |
diff --git a/embassy-stm32/src/tl_mbox/ble.rs b/embassy-stm32/src/tl_mbox/ble.rs new file mode 100644 index 000000000..a2c0758d1 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/ble.rs | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use super::unsafe_linked_list::LST_init_head; | ||
| 4 | use super::{channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; | ||
| 5 | use crate::ipcc::Ipcc; | ||
| 6 | |||
| 7 | pub struct Ble; | ||
| 8 | |||
| 9 | impl Ble { | ||
| 10 | pub fn new(ipcc: &mut Ipcc) -> Self { | ||
| 11 | unsafe { | ||
| 12 | LST_init_head(EVT_QUEUE.as_mut_ptr()); | ||
| 13 | |||
| 14 | TL_BLE_TABLE = MaybeUninit::new(BleTable { | ||
| 15 | pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), | ||
| 16 | pcs_buffer: CS_BUFFER.as_mut_ptr().cast(), | ||
| 17 | pevt_queue: EVT_QUEUE.as_ptr().cast(), | ||
| 18 | phci_acl_data_buffer: HCI_ACL_DATA_BUFFER.as_mut_ptr().cast(), | ||
| 19 | }); | ||
| 20 | } | ||
| 21 | |||
| 22 | ipcc.c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); | ||
| 23 | |||
| 24 | Ble | ||
| 25 | } | ||
| 26 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/channels.rs b/embassy-stm32/src/tl_mbox/channels.rs new file mode 100644 index 000000000..1dde5d61c --- /dev/null +++ b/embassy-stm32/src/tl_mbox/channels.rs | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | //! CPU1 CPU2 | ||
| 2 | //! | (SYSTEM) | | ||
| 3 | //! |----HW_IPCC_SYSTEM_CMD_RSP_CHANNEL-------------->| | ||
| 4 | //! | | | ||
| 5 | //! |<---HW_IPCC_SYSTEM_EVENT_CHANNEL-----------------| | ||
| 6 | //! | | | ||
| 7 | //! | (ZIGBEE) | | ||
| 8 | //! |----HW_IPCC_ZIGBEE_CMD_APPLI_CHANNEL------------>| | ||
| 9 | //! | | | ||
| 10 | //! |----HW_IPCC_ZIGBEE_CMD_CLI_CHANNEL-------------->| | ||
| 11 | //! | | | ||
| 12 | //! |<---HW_IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL-------| | ||
| 13 | //! | | | ||
| 14 | //! |<---HW_IPCC_ZIGBEE_CLI_NOTIF_ACK_CHANNEL---------| | ||
| 15 | //! | | | ||
| 16 | //! | (THREAD) | | ||
| 17 | //! |----HW_IPCC_THREAD_OT_CMD_RSP_CHANNEL----------->| | ||
| 18 | //! | | | ||
| 19 | //! |----HW_IPCC_THREAD_CLI_CMD_CHANNEL-------------->| | ||
| 20 | //! | | | ||
| 21 | //! |<---HW_IPCC_THREAD_NOTIFICATION_ACK_CHANNEL------| | ||
| 22 | //! | | | ||
| 23 | //! |<---HW_IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL--| | ||
| 24 | //! | | | ||
| 25 | //! | (BLE) | | ||
| 26 | //! |----HW_IPCC_BLE_CMD_CHANNEL--------------------->| | ||
| 27 | //! | | | ||
| 28 | //! |----HW_IPCC_HCI_ACL_DATA_CHANNEL---------------->| | ||
| 29 | //! | | | ||
| 30 | //! |<---HW_IPCC_BLE_EVENT_CHANNEL--------------------| | ||
| 31 | //! | | | ||
| 32 | //! | (BLE LLD) | | ||
| 33 | //! |----HW_IPCC_BLE_LLD_CMD_CHANNEL----------------->| | ||
| 34 | //! | | | ||
| 35 | //! |<---HW_IPCC_BLE_LLD_RSP_CHANNEL------------------| | ||
| 36 | //! | | | ||
| 37 | //! |<---HW_IPCC_BLE_LLD_M0_CMD_CHANNEL---------------| | ||
| 38 | //! | | | ||
| 39 | //! | (MAC) | | ||
| 40 | //! |----HW_IPCC_MAC_802_15_4_CMD_RSP_CHANNEL-------->| | ||
| 41 | //! | | | ||
| 42 | //! |<---HW_IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL| | ||
| 43 | //! | | | ||
| 44 | //! | (BUFFER) | | ||
| 45 | //! |----HW_IPCC_MM_RELEASE_BUFFER_CHANNE------------>| | ||
| 46 | //! | | | ||
| 47 | //! | (TRACE) | | ||
| 48 | //! |<----HW_IPCC_TRACES_CHANNEL----------------------| | ||
| 49 | //! | | | ||
| 50 | //! | ||
| 51 | |||
| 52 | pub mod cpu1 { | ||
| 53 | use crate::ipcc::IpccChannel; | ||
| 54 | |||
| 55 | #[allow(dead_code)] // Not used currently but reserved | ||
| 56 | pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; | ||
| 57 | #[allow(dead_code)] // Not used currently but reserved | ||
| 58 | 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; | ||
| 61 | #[allow(dead_code)] // Not used currently but reserved | ||
| 62 | pub const IPCC_ZIGBEE_CMD_APPLI_CHANNEL: IpccChannel = IpccChannel::Channel3; | ||
| 63 | #[allow(dead_code)] // Not used currently but reserved | ||
| 64 | pub const IPCC_MAC_802_15_4_CMD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel3; | ||
| 65 | #[allow(dead_code)] // 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 | ||
| 68 | pub const IPCC_THREAD_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 69 | #[allow(dead_code)] // Not used currently but reserved | ||
| 70 | pub const IPCC_LLDTESTS_CLI_CMD_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 71 | #[allow(dead_code)] // Not used currently but reserved | ||
| 72 | 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; | ||
| 75 | } | ||
| 76 | |||
| 77 | pub mod cpu2 { | ||
| 78 | use crate::ipcc::IpccChannel; | ||
| 79 | |||
| 80 | pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; | ||
| 81 | 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; | ||
| 84 | #[allow(dead_code)] // Not used currently but reserved | ||
| 85 | pub const IPCC_ZIGBEE_APPLI_NOTIF_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; | ||
| 86 | #[allow(dead_code)] // Not used currently but reserved | ||
| 87 | pub const IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel3; | ||
| 88 | #[allow(dead_code)] // Not used currently but reserved | ||
| 89 | pub const IPCC_LDDTESTS_M0_CMD_CHANNEL: IpccChannel = IpccChannel::Channel3; | ||
| 90 | #[allow(dead_code)] // Not used currently but reserved | ||
| 91 | 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; | ||
| 94 | #[allow(dead_code)] // Not used currently but reserved | ||
| 95 | pub const IPCC_THREAD_CLI_NOTIFICATION_ACK_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 96 | #[allow(dead_code)] // Not used currently but reserved | ||
| 97 | pub const IPCC_LLDTESTS_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 98 | #[allow(dead_code)] // Not used currently but reserved | ||
| 99 | pub const IPCC_BLE_LLD_CLI_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 100 | #[allow(dead_code)] // Not used currently but reserved | ||
| 101 | pub const IPCC_BLE_LLD_RSP_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 102 | #[allow(dead_code)] // Not used currently but reserved | ||
| 103 | pub const IPCC_ZIGBEE_M0_REQUEST_CHANNEL: IpccChannel = IpccChannel::Channel5; | ||
| 104 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/cmd.rs b/embassy-stm32/src/tl_mbox/cmd.rs new file mode 100644 index 000000000..3507c3231 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/cmd.rs | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | use super::PacketHeader; | ||
| 2 | |||
| 3 | #[repr(C, packed)] | ||
| 4 | #[derive(Copy, Clone)] | ||
| 5 | pub struct Cmd { | ||
| 6 | pub cmd_code: u16, | ||
| 7 | pub payload_len: u8, | ||
| 8 | pub payload: [u8; 255], | ||
| 9 | } | ||
| 10 | |||
| 11 | impl Default for Cmd { | ||
| 12 | fn default() -> Self { | ||
| 13 | Self { | ||
| 14 | cmd_code: 0, | ||
| 15 | payload_len: 0, | ||
| 16 | payload: [0u8; 255], | ||
| 17 | } | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | #[repr(C, packed)] | ||
| 22 | #[derive(Copy, Clone, Default)] | ||
| 23 | pub struct CmdSerial { | ||
| 24 | pub ty: u8, | ||
| 25 | pub cmd: Cmd, | ||
| 26 | } | ||
| 27 | |||
| 28 | #[repr(C, packed)] | ||
| 29 | #[derive(Copy, Clone, Default)] | ||
| 30 | pub struct CmdPacket { | ||
| 31 | pub header: PacketHeader, | ||
| 32 | pub cmd_serial: CmdSerial, | ||
| 33 | } | ||
| 34 | |||
| 35 | #[repr(C, packed)] | ||
| 36 | #[derive(Copy, Clone)] | ||
| 37 | pub struct AclDataSerial { | ||
| 38 | pub ty: u8, | ||
| 39 | pub handle: u16, | ||
| 40 | pub length: u16, | ||
| 41 | pub acl_data: [u8; 1], | ||
| 42 | } | ||
| 43 | |||
| 44 | #[repr(C, packed)] | ||
| 45 | #[derive(Copy, Clone)] | ||
| 46 | pub struct AclDataPacket { | ||
| 47 | pub header: PacketHeader, | ||
| 48 | pub acl_data_serial: AclDataSerial, | ||
| 49 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/evt.rs b/embassy-stm32/src/tl_mbox/evt.rs new file mode 100644 index 000000000..4244db810 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/evt.rs | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | /// the payload of [`Evt`] for a command status event | ||
| 2 | #[derive(Copy, Clone)] | ||
| 3 | #[repr(C, packed)] | ||
| 4 | pub struct CsEvt { | ||
| 5 | pub status: u8, | ||
| 6 | pub num_cmd: u8, | ||
| 7 | pub cmd_code: u16, | ||
| 8 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/mm.rs b/embassy-stm32/src/tl_mbox/mm.rs new file mode 100644 index 000000000..cf4797305 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/mm.rs | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use super::unsafe_linked_list::LST_init_head; | ||
| 4 | use super::{ | ||
| 5 | MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, SYS_SPARE_EVT_BUF, | ||
| 6 | TL_MEM_MANAGER_TABLE, | ||
| 7 | }; | ||
| 8 | |||
| 9 | pub struct MemoryManager; | ||
| 10 | |||
| 11 | impl MemoryManager { | ||
| 12 | pub fn new() -> Self { | ||
| 13 | unsafe { | ||
| 14 | LST_init_head(FREE_BUFF_QUEUE.as_mut_ptr()); | ||
| 15 | LST_init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); | ||
| 16 | |||
| 17 | TL_MEM_MANAGER_TABLE = MaybeUninit::new(MemManagerTable { | ||
| 18 | spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), | ||
| 19 | spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), | ||
| 20 | ble_pool: EVT_POOL.as_ptr().cast(), | ||
| 21 | ble_pool_size: POOL_SIZE as u32, | ||
| 22 | pevt_free_buffer_queue: FREE_BUFF_QUEUE.as_mut_ptr(), | ||
| 23 | traces_evt_pool: core::ptr::null(), | ||
| 24 | traces_pool_size: 0, | ||
| 25 | }); | ||
| 26 | } | ||
| 27 | |||
| 28 | MemoryManager | ||
| 29 | } | ||
| 30 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/mod.rs b/embassy-stm32/src/tl_mbox/mod.rs new file mode 100644 index 000000000..623546dc9 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/mod.rs | |||
| @@ -0,0 +1,318 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use bit_field::BitField; | ||
| 4 | |||
| 5 | use self::ble::Ble; | ||
| 6 | use self::cmd::{AclDataPacket, CmdPacket}; | ||
| 7 | use self::evt::CsEvt; | ||
| 8 | use self::mm::MemoryManager; | ||
| 9 | use self::sys::Sys; | ||
| 10 | use self::unsafe_linked_list::LinkedListNode; | ||
| 11 | use crate::ipcc::Ipcc; | ||
| 12 | |||
| 13 | mod ble; | ||
| 14 | mod channels; | ||
| 15 | mod cmd; | ||
| 16 | mod evt; | ||
| 17 | mod mm; | ||
| 18 | mod sys; | ||
| 19 | mod unsafe_linked_list; | ||
| 20 | |||
| 21 | pub type PacketHeader = LinkedListNode; | ||
| 22 | |||
| 23 | const TL_PACKET_HEADER_SIZE: usize = core::mem::size_of::<PacketHeader>(); | ||
| 24 | const TL_EVT_HEADER_SIZE: usize = 3; | ||
| 25 | const TL_CS_EVT_SIZE: usize = core::mem::size_of::<CsEvt>(); | ||
| 26 | |||
| 27 | const CFG_TL_BLE_EVT_QUEUE_LENGTH: usize = 5; | ||
| 28 | const CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE: usize = 255; | ||
| 29 | const TL_BLE_EVENT_FRAME_SIZE: usize = TL_EVT_HEADER_SIZE + CFG_TL_BLE_MOST_EVENT_PAYLOAD_SIZE; | ||
| 30 | |||
| 31 | const POOL_SIZE: usize = CFG_TL_BLE_EVT_QUEUE_LENGTH * 4 * divc(TL_PACKET_HEADER_SIZE + TL_BLE_EVENT_FRAME_SIZE, 4); | ||
| 32 | |||
| 33 | const fn divc(x: usize, y: usize) -> usize { | ||
| 34 | (x + y - 1) / y | ||
| 35 | } | ||
| 36 | |||
| 37 | #[repr(C, packed)] | ||
| 38 | #[derive(Copy, Clone)] | ||
| 39 | pub struct SafeBootInfoTable { | ||
| 40 | version: u32, | ||
| 41 | } | ||
| 42 | |||
| 43 | #[repr(C, packed)] | ||
| 44 | #[derive(Copy, Clone)] | ||
| 45 | pub struct RssInfoTable { | ||
| 46 | version: u32, | ||
| 47 | memory_size: u32, | ||
| 48 | rss_info: u32, | ||
| 49 | } | ||
| 50 | |||
| 51 | /// # Version | ||
| 52 | /// - 0 -> 3 = Build - 0: Untracked - 15:Released - x: Tracked version | ||
| 53 | /// - 4 -> 7 = branch - 0: Mass Market - x: ... | ||
| 54 | /// - 8 -> 15 = Subversion | ||
| 55 | /// - 16 -> 23 = Version minor | ||
| 56 | /// - 24 -> 31 = Version major | ||
| 57 | /// # Memory Size | ||
| 58 | /// - 0 -> 7 = Flash ( Number of 4k sector) | ||
| 59 | /// - 8 -> 15 = Reserved ( Shall be set to 0 - may be used as flash extension ) | ||
| 60 | /// - 16 -> 23 = SRAM2b ( Number of 1k sector) | ||
| 61 | /// - 24 -> 31 = SRAM2a ( Number of 1k sector) | ||
| 62 | #[repr(C, packed)] | ||
| 63 | #[derive(Copy, Clone)] | ||
| 64 | pub struct WirelessFwInfoTable { | ||
| 65 | version: u32, | ||
| 66 | memory_size: u32, | ||
| 67 | thread_info: u32, | ||
| 68 | ble_info: u32, | ||
| 69 | } | ||
| 70 | |||
| 71 | impl WirelessFwInfoTable { | ||
| 72 | pub fn version_major(&self) -> u8 { | ||
| 73 | let version = self.version; | ||
| 74 | (version.get_bits(24..31) & 0xff) as u8 | ||
| 75 | } | ||
| 76 | |||
| 77 | pub fn version_minor(&self) -> u8 { | ||
| 78 | let version = self.version; | ||
| 79 | (version.get_bits(16..23) & 0xff) as u8 | ||
| 80 | } | ||
| 81 | |||
| 82 | pub fn subversion(&self) -> u8 { | ||
| 83 | let version = self.version; | ||
| 84 | (version.get_bits(8..15) & 0xff) as u8 | ||
| 85 | } | ||
| 86 | |||
| 87 | /// size of FLASH, expressed in number of 4K sectors | ||
| 88 | pub fn flash_size(&self) -> u8 { | ||
| 89 | let memory_size = self.memory_size; | ||
| 90 | (memory_size.get_bits(0..7) & 0xff) as u8 | ||
| 91 | } | ||
| 92 | |||
| 93 | /// size for SRAM2a, expressed in number of 1K sectors | ||
| 94 | pub fn sram2a_size(&self) -> u8 { | ||
| 95 | let memory_size = self.memory_size; | ||
| 96 | (memory_size.get_bits(24..31) & 0xff) as u8 | ||
| 97 | } | ||
| 98 | |||
| 99 | /// size of SRAM2b, expressed in number of 1K sectors | ||
| 100 | pub fn sram2b_size(&self) -> u8 { | ||
| 101 | let memory_size = self.memory_size; | ||
| 102 | (memory_size.get_bits(16..23) & 0xff) as u8 | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | #[repr(C, packed)] | ||
| 107 | #[derive(Copy, Clone)] | ||
| 108 | pub struct DeviceInfoTable { | ||
| 109 | pub safe_boot_info_table: SafeBootInfoTable, | ||
| 110 | pub rss_info_table: RssInfoTable, | ||
| 111 | pub wireless_fw_info_table: WirelessFwInfoTable, | ||
| 112 | } | ||
| 113 | |||
| 114 | #[repr(C, packed)] | ||
| 115 | struct BleTable { | ||
| 116 | pcmd_buffer: *const CmdPacket, | ||
| 117 | pcs_buffer: *const u8, | ||
| 118 | pevt_queue: *const u8, | ||
| 119 | phci_acl_data_buffer: *mut AclDataPacket, | ||
| 120 | } | ||
| 121 | |||
| 122 | #[repr(C, packed)] | ||
| 123 | struct ThreadTable { | ||
| 124 | no_stack_buffer: *const u8, | ||
| 125 | cli_cmd_rsp_buffer: *const u8, | ||
| 126 | ot_cmd_rsp_buffer: *const u8, | ||
| 127 | } | ||
| 128 | |||
| 129 | #[repr(C, packed)] | ||
| 130 | struct SysTable { | ||
| 131 | pcmd_buffer: *mut CmdPacket, | ||
| 132 | sys_queue: *const LinkedListNode, | ||
| 133 | } | ||
| 134 | |||
| 135 | #[allow(dead_code)] // Not used currently but reserved | ||
| 136 | #[repr(C, packed)] | ||
| 137 | struct LldTestTable { | ||
| 138 | cli_cmd_rsp_buffer: *const u8, | ||
| 139 | m0_cmd_buffer: *const u8, | ||
| 140 | } | ||
| 141 | |||
| 142 | #[allow(dead_code)] // Not used currently but reserved | ||
| 143 | #[repr(C, packed)] | ||
| 144 | struct BleLldTable { | ||
| 145 | cmd_rsp_buffer: *const u8, | ||
| 146 | m0_cmd_buffer: *const u8, | ||
| 147 | } | ||
| 148 | |||
| 149 | #[allow(dead_code)] // Not used currently but reserved | ||
| 150 | #[repr(C, packed)] | ||
| 151 | struct ZigbeeTable { | ||
| 152 | notif_m0_to_m4_buffer: *const u8, | ||
| 153 | appli_cmd_m4_to_m0_buffer: *const u8, | ||
| 154 | request_m0_to_m4_buffer: *const u8, | ||
| 155 | } | ||
| 156 | |||
| 157 | #[repr(C, packed)] | ||
| 158 | struct MemManagerTable { | ||
| 159 | spare_ble_buffer: *const u8, | ||
| 160 | spare_sys_buffer: *const u8, | ||
| 161 | |||
| 162 | ble_pool: *const u8, | ||
| 163 | ble_pool_size: u32, | ||
| 164 | |||
| 165 | pevt_free_buffer_queue: *mut LinkedListNode, | ||
| 166 | |||
| 167 | traces_evt_pool: *const u8, | ||
| 168 | traces_pool_size: u32, | ||
| 169 | } | ||
| 170 | |||
| 171 | #[repr(C, packed)] | ||
| 172 | struct TracesTable { | ||
| 173 | traces_queue: *const u8, | ||
| 174 | } | ||
| 175 | |||
| 176 | #[repr(C, packed)] | ||
| 177 | struct Mac802_15_4Table { | ||
| 178 | pcmd_rsp_buffer: *const u8, | ||
| 179 | pnotack_buffer: *const u8, | ||
| 180 | evt_queue: *const u8, | ||
| 181 | } | ||
| 182 | |||
| 183 | /// reference table. Contains pointers to all other tables | ||
| 184 | #[repr(C, packed)] | ||
| 185 | #[derive(Copy, Clone)] | ||
| 186 | pub struct RefTable { | ||
| 187 | pub device_info_table: *const DeviceInfoTable, | ||
| 188 | ble_table: *const BleTable, | ||
| 189 | thread_table: *const ThreadTable, | ||
| 190 | sys_table: *const SysTable, | ||
| 191 | mem_manager_table: *const MemManagerTable, | ||
| 192 | traces_table: *const TracesTable, | ||
| 193 | mac_802_15_4_table: *const Mac802_15_4Table, | ||
| 194 | } | ||
| 195 | |||
| 196 | #[link_section = "TL_REF_TABLE"] | ||
| 197 | pub static mut TL_REF_TABLE: MaybeUninit<RefTable> = MaybeUninit::uninit(); | ||
| 198 | |||
| 199 | #[link_section = "TL_DEVICE_INFO_TABLE"] | ||
| 200 | static mut TL_DEVICE_INFO_TABLE: MaybeUninit<DeviceInfoTable> = MaybeUninit::uninit(); | ||
| 201 | |||
| 202 | #[link_section = "TL_BLE_TABLE"] | ||
| 203 | static mut TL_BLE_TABLE: MaybeUninit<BleTable> = MaybeUninit::uninit(); | ||
| 204 | |||
| 205 | #[link_section = "TL_THREAD_TABLE"] | ||
| 206 | static mut TL_THREAD_TABLE: MaybeUninit<ThreadTable> = MaybeUninit::uninit(); | ||
| 207 | |||
| 208 | #[link_section = "TL_SYS_TABLE"] | ||
| 209 | static mut TL_SYS_TABLE: MaybeUninit<SysTable> = MaybeUninit::uninit(); | ||
| 210 | |||
| 211 | #[link_section = "TL_MEM_MANAGER_TABLE"] | ||
| 212 | static mut TL_MEM_MANAGER_TABLE: MaybeUninit<MemManagerTable> = MaybeUninit::uninit(); | ||
| 213 | |||
| 214 | #[link_section = "TL_TRACES_TABLE"] | ||
| 215 | static mut TL_TRACES_TABLE: MaybeUninit<TracesTable> = MaybeUninit::uninit(); | ||
| 216 | |||
| 217 | #[link_section = "TL_MAC_802_15_4_TABLE"] | ||
| 218 | static mut TL_MAC_802_15_4_TABLE: MaybeUninit<Mac802_15_4Table> = MaybeUninit::uninit(); | ||
| 219 | |||
| 220 | #[allow(dead_code)] // Not used currently but reserved | ||
| 221 | #[link_section = "FREE_BUF_QUEUE"] | ||
| 222 | static mut FREE_BUFF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); | ||
| 223 | |||
| 224 | // not in shared RAM | ||
| 225 | static mut LOCAL_FREE_BUF_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); | ||
| 226 | |||
| 227 | #[allow(dead_code)] // Not used currently but reserved | ||
| 228 | #[link_section = "TRACES_EVT_QUEUE"] | ||
| 229 | static mut TRACES_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); | ||
| 230 | |||
| 231 | #[link_section = "CS_BUFFER"] | ||
| 232 | static mut CS_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE]> = | ||
| 233 | MaybeUninit::uninit(); | ||
| 234 | |||
| 235 | #[link_section = "EVT_QUEUE"] | ||
| 236 | static mut EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); | ||
| 237 | |||
| 238 | #[link_section = "SYSTEM_EVT_QUEUE"] | ||
| 239 | static mut SYSTEM_EVT_QUEUE: MaybeUninit<LinkedListNode> = MaybeUninit::uninit(); | ||
| 240 | |||
| 241 | #[link_section = "SYS_CMD_BUF"] | ||
| 242 | static mut SYS_CMD_BUF: MaybeUninit<CmdPacket> = MaybeUninit::uninit(); | ||
| 243 | |||
| 244 | #[link_section = "EVT_POOL"] | ||
| 245 | static mut EVT_POOL: MaybeUninit<[u8; POOL_SIZE]> = MaybeUninit::uninit(); | ||
| 246 | |||
| 247 | #[link_section = "SYS_SPARE_EVT_BUF"] | ||
| 248 | static mut SYS_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = | ||
| 249 | MaybeUninit::uninit(); | ||
| 250 | |||
| 251 | #[link_section = "BLE_SPARE_EVT_BUF"] | ||
| 252 | static mut BLE_SPARE_EVT_BUF: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + TL_EVT_HEADER_SIZE + 255]> = | ||
| 253 | MaybeUninit::uninit(); | ||
| 254 | |||
| 255 | #[link_section = "BLE_CMD_BUFFER"] | ||
| 256 | static mut BLE_CMD_BUFFER: MaybeUninit<CmdPacket> = MaybeUninit::uninit(); | ||
| 257 | |||
| 258 | #[link_section = "HCI_ACL_DATA_BUFFER"] | ||
| 259 | // "magic" numbers from ST ---v---v | ||
| 260 | static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251]> = MaybeUninit::uninit(); | ||
| 261 | |||
| 262 | pub struct TlMbox { | ||
| 263 | _sys: Sys, | ||
| 264 | _ble: Ble, | ||
| 265 | _mm: MemoryManager, | ||
| 266 | } | ||
| 267 | |||
| 268 | impl TlMbox { | ||
| 269 | /// initializes low-level transport between CPU1 and BLE stack on CPU2 | ||
| 270 | pub fn init(ipcc: &mut Ipcc) -> TlMbox { | ||
| 271 | unsafe { | ||
| 272 | TL_REF_TABLE = MaybeUninit::new(RefTable { | ||
| 273 | device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(), | ||
| 274 | ble_table: TL_BLE_TABLE.as_ptr(), | ||
| 275 | thread_table: TL_THREAD_TABLE.as_ptr(), | ||
| 276 | sys_table: TL_SYS_TABLE.as_ptr(), | ||
| 277 | mem_manager_table: TL_MEM_MANAGER_TABLE.as_ptr(), | ||
| 278 | traces_table: TL_TRACES_TABLE.as_ptr(), | ||
| 279 | mac_802_15_4_table: TL_MAC_802_15_4_TABLE.as_ptr(), | ||
| 280 | }); | ||
| 281 | |||
| 282 | TL_SYS_TABLE = MaybeUninit::zeroed(); | ||
| 283 | TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed(); | ||
| 284 | TL_BLE_TABLE = MaybeUninit::zeroed(); | ||
| 285 | TL_THREAD_TABLE = MaybeUninit::zeroed(); | ||
| 286 | TL_MEM_MANAGER_TABLE = MaybeUninit::zeroed(); | ||
| 287 | TL_TRACES_TABLE = MaybeUninit::zeroed(); | ||
| 288 | TL_MAC_802_15_4_TABLE = MaybeUninit::zeroed(); | ||
| 289 | |||
| 290 | EVT_POOL = MaybeUninit::zeroed(); | ||
| 291 | SYS_SPARE_EVT_BUF = MaybeUninit::zeroed(); | ||
| 292 | BLE_SPARE_EVT_BUF = MaybeUninit::zeroed(); | ||
| 293 | |||
| 294 | CS_BUFFER = MaybeUninit::zeroed(); | ||
| 295 | BLE_CMD_BUFFER = MaybeUninit::zeroed(); | ||
| 296 | HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); | ||
| 297 | } | ||
| 298 | |||
| 299 | ipcc.init(); | ||
| 300 | |||
| 301 | let _sys = Sys::new(ipcc); | ||
| 302 | let _ble = Ble::new(ipcc); | ||
| 303 | let _mm = MemoryManager::new(); | ||
| 304 | |||
| 305 | TlMbox { _sys, _ble, _mm } | ||
| 306 | } | ||
| 307 | |||
| 308 | pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> { | ||
| 309 | let info = unsafe { &(*(*TL_REF_TABLE.as_ptr()).device_info_table).wireless_fw_info_table }; | ||
| 310 | |||
| 311 | // zero version indicates that CPU2 wasn't active and didn't fill the information table | ||
| 312 | if info.version != 0 { | ||
| 313 | Some(*info) | ||
| 314 | } else { | ||
| 315 | None | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/sys.rs b/embassy-stm32/src/tl_mbox/sys.rs new file mode 100644 index 000000000..13ae7f9f9 --- /dev/null +++ b/embassy-stm32/src/tl_mbox/sys.rs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | use core::mem::MaybeUninit; | ||
| 2 | |||
| 3 | use super::unsafe_linked_list::LST_init_head; | ||
| 4 | use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_SYS_TABLE}; | ||
| 5 | use crate::ipcc::Ipcc; | ||
| 6 | |||
| 7 | pub struct Sys; | ||
| 8 | |||
| 9 | impl Sys { | ||
| 10 | pub fn new(ipcc: &mut Ipcc) -> Self { | ||
| 11 | unsafe { | ||
| 12 | LST_init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | ||
| 13 | |||
| 14 | TL_SYS_TABLE = MaybeUninit::new(SysTable { | ||
| 15 | pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), | ||
| 16 | sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), | ||
| 17 | }); | ||
| 18 | } | ||
| 19 | |||
| 20 | ipcc.c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); | ||
| 21 | |||
| 22 | Sys | ||
| 23 | } | ||
| 24 | } | ||
diff --git a/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs new file mode 100644 index 000000000..9caf01d1d --- /dev/null +++ b/embassy-stm32/src/tl_mbox/unsafe_linked_list.rs | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | //! Unsafe linked list. | ||
| 2 | //! Translated from ST's C by `c2rust` tool. | ||
| 3 | |||
| 4 | #![allow( | ||
| 5 | dead_code, | ||
| 6 | mutable_transmutes, | ||
| 7 | non_camel_case_types, | ||
| 8 | non_snake_case, | ||
| 9 | non_upper_case_globals, | ||
| 10 | unused_assignments, | ||
| 11 | unused_mut | ||
| 12 | )] | ||
| 13 | |||
| 14 | use cortex_m::interrupt; | ||
| 15 | |||
| 16 | #[derive(Copy, Clone)] | ||
| 17 | #[repr(C, packed(4))] | ||
| 18 | pub struct LinkedListNode { | ||
| 19 | pub next: *mut LinkedListNode, | ||
| 20 | pub prev: *mut LinkedListNode, | ||
| 21 | } | ||
| 22 | |||
| 23 | impl Default for LinkedListNode { | ||
| 24 | fn default() -> Self { | ||
| 25 | LinkedListNode { | ||
| 26 | next: core::ptr::null_mut(), | ||
| 27 | prev: core::ptr::null_mut(), | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | pub unsafe fn LST_init_head(mut listHead: *mut LinkedListNode) { | ||
| 33 | (*listHead).next = listHead; | ||
| 34 | (*listHead).prev = listHead; | ||
| 35 | } | ||
| 36 | |||
| 37 | pub unsafe fn LST_is_empty(mut listHead: *mut LinkedListNode) -> bool { | ||
| 38 | interrupt::free(|_| ((*listHead).next) == listHead) | ||
| 39 | } | ||
| 40 | |||
| 41 | pub unsafe fn LST_insert_head(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { | ||
| 42 | interrupt::free(|_| { | ||
| 43 | (*node).next = (*listHead).next; | ||
| 44 | (*node).prev = listHead; | ||
| 45 | (*listHead).next = node; | ||
| 46 | (*(*node).next).prev = node; | ||
| 47 | }); | ||
| 48 | } | ||
| 49 | |||
| 50 | pub unsafe fn LST_insert_tail(mut listHead: *mut LinkedListNode, mut node: *mut LinkedListNode) { | ||
| 51 | interrupt::free(|_| { | ||
| 52 | (*node).next = listHead; | ||
| 53 | (*node).prev = (*listHead).prev; | ||
| 54 | (*listHead).prev = node; | ||
| 55 | (*(*node).prev).next = node; | ||
| 56 | }); | ||
| 57 | } | ||
| 58 | |||
| 59 | pub unsafe fn LST_remove_node(mut node: *mut LinkedListNode) { | ||
| 60 | interrupt::free(|_| { | ||
| 61 | (*(*node).prev).next = (*node).next; | ||
| 62 | (*(*node).next).prev = (*node).prev; | ||
| 63 | }); | ||
| 64 | } | ||
| 65 | |||
| 66 | pub unsafe fn LST_remove_head(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | ||
| 67 | interrupt::free(|_| { | ||
| 68 | *node = (*listHead).next; | ||
| 69 | LST_remove_node((*listHead).next); | ||
| 70 | }); | ||
| 71 | } | ||
| 72 | |||
| 73 | pub unsafe fn LST_remove_tail(mut listHead: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | ||
| 74 | interrupt::free(|_| { | ||
| 75 | *node = (*listHead).prev; | ||
| 76 | LST_remove_node((*listHead).prev); | ||
| 77 | }); | ||
| 78 | } | ||
| 79 | |||
| 80 | pub unsafe fn LST_insert_node_after(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { | ||
| 81 | interrupt::free(|_| { | ||
| 82 | (*node).next = (*ref_node).next; | ||
| 83 | (*node).prev = ref_node; | ||
| 84 | (*ref_node).next = node; | ||
| 85 | (*(*node).next).prev = node; | ||
| 86 | }); | ||
| 87 | } | ||
| 88 | |||
| 89 | pub unsafe fn LST_insert_node_before(mut node: *mut LinkedListNode, mut ref_node: *mut LinkedListNode) { | ||
| 90 | interrupt::free(|_| { | ||
| 91 | (*node).next = ref_node; | ||
| 92 | (*node).prev = (*ref_node).prev; | ||
| 93 | (*ref_node).prev = node; | ||
| 94 | (*(*node).prev).next = node; | ||
| 95 | }); | ||
| 96 | } | ||
| 97 | |||
| 98 | pub unsafe fn LST_get_size(mut listHead: *mut LinkedListNode) -> usize { | ||
| 99 | interrupt::free(|_| { | ||
| 100 | let mut size = 0; | ||
| 101 | let mut temp: *mut LinkedListNode = core::ptr::null_mut::<LinkedListNode>(); | ||
| 102 | |||
| 103 | temp = (*listHead).next; | ||
| 104 | while temp != listHead { | ||
| 105 | size += 1; | ||
| 106 | temp = (*temp).next | ||
| 107 | } | ||
| 108 | |||
| 109 | size | ||
| 110 | }) | ||
| 111 | } | ||
| 112 | |||
| 113 | pub unsafe fn LST_get_next_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | ||
| 114 | interrupt::free(|_| { | ||
| 115 | *node = (*ref_node).next; | ||
| 116 | }); | ||
| 117 | } | ||
| 118 | |||
| 119 | pub unsafe fn LST_get_prev_node(mut ref_node: *mut LinkedListNode, mut node: *mut *mut LinkedListNode) { | ||
| 120 | interrupt::free(|_| { | ||
| 121 | *node = (*ref_node).prev; | ||
| 122 | }); | ||
| 123 | } | ||
