From 4aca7c8811b70e420280893784cdad2acbe326f9 Mon Sep 17 00:00:00 2001 From: goueslati Date: Mon, 10 Jul 2023 16:54:48 +0100 Subject: [PATCH] wip --- embassy-stm32-wpan/Cargo.toml | 1 + embassy-stm32-wpan/src/sub/mac/commands.rs | 83 +++++++++++++ .../src/sub/{mac.rs => mac/mod.rs} | 18 +++ embassy-stm32-wpan/src/sub/mac/opcodes.rs | 27 ++++ examples/stm32wb/.cargo/config.toml | 4 +- examples/stm32wb/Cargo.toml | 6 +- examples/stm32wb/src/bin/tl_mbox_mac_2.rs | 117 ++++++++++++++++++ rust-toolchain.toml | 4 +- 8 files changed, 255 insertions(+), 5 deletions(-) create mode 100644 embassy-stm32-wpan/src/sub/mac/commands.rs rename embassy-stm32-wpan/src/sub/{mac.rs => mac/mod.rs} (88%) create mode 100644 embassy-stm32-wpan/src/sub/mac/opcodes.rs create mode 100644 examples/stm32wb/src/bin/tl_mbox_mac_2.rs diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml index 5141f9bd2..4b5dcdd29 100644 --- a/embassy-stm32-wpan/Cargo.toml +++ b/embassy-stm32-wpan/Cargo.toml @@ -28,6 +28,7 @@ stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] } stm32wb-hci = { version = "0.1.2", features = ["version-5-0"], optional = true } [features] +default = ["stm32wb55rg", "mac", "ble"] defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"] ble = ["dep:stm32wb-hci"] diff --git a/embassy-stm32-wpan/src/sub/mac/commands.rs b/embassy-stm32-wpan/src/sub/mac/commands.rs new file mode 100644 index 000000000..75a31d2fc --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac/commands.rs @@ -0,0 +1,83 @@ +use bit_field::BitField; + +use super::opcodes::OpcodeM4ToM0; + +pub trait MacCommand { + type Response; + const OPCODE: OpcodeM4ToM0; + const SIZE: usize; + + fn copy_into_slice(&self, buf: &mut [u8]); +} + +pub struct ResetRequest { + /// MAC PIB attributes are set to their default values or not during reset + pub set_default_pib: bool, +} + +impl MacCommand for ResetRequest { + type Response = (); + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; + const SIZE: usize = 4; + + fn copy_into_slice(&self, buf: &mut [u8]) { + buf[0] = self.set_default_pib as u8; + } +} + +#[repr(C)] +pub struct SetRequest { + pub pib_attribute_ptr: *const u8, + pub pib_attribute: u8, + pub stuffing: [u8; 3], +} + +impl MacCommand for SetRequest { + type Response = (); + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; + const SIZE: usize = 8; + + fn copy_into_slice(&self, buf: &mut [u8]) { + let address = self.pib_attribute_ptr as usize; + + // 68 ff 2 20 6f + + let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, Self::SIZE) }; + debug!("{:#04x}", a); + + unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) }; + + // buf[0] = self.pib_attribute_ptr as u8; + // buf[1] = self.pib_attribute; + } +} + +pub struct AssociateRequest { + pub channel_number: u8, + pub channel_page: u8, + pub coord_addr_mode: u8, + pub capability_information: u8, + pub coord_pan_id: [u8; 2], + pub security_level: u8, + pub key_id_mode: u8, + pub key_source: [u8; 8], + pub coord_address: MacAddress, + pub key_index: u8, +} + +impl MacCommand for AssociateRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; + const SIZE: usize = 25; + type Response = (); + + fn copy_into_slice(&self, buf: &mut [u8]) { + let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, core::mem::size_of::()) }; + + buf[..a.len()].copy_from_slice(a); + } +} + +pub union MacAddress { + pub short: [u8; 2], + pub extended: [u8; 8], +} diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac/mod.rs similarity index 88% rename from embassy-stm32-wpan/src/sub/mac.rs rename to embassy-stm32-wpan/src/sub/mac/mod.rs index f7a59b0e4..83970a881 100644 --- a/embassy-stm32-wpan/src/sub/mac.rs +++ b/embassy-stm32-wpan/src/sub/mac/mod.rs @@ -8,12 +8,16 @@ use embassy_futures::poll_once; use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; +use self::commands::MacCommand; use crate::cmd::CmdPacket; use crate::consts::TlPacketType; use crate::evt::{EvtBox, EvtPacket}; use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; use crate::{channels, evt}; +pub mod commands; +mod opcodes; + static MAC_WAKER: AtomicWaker = AtomicWaker::new(); static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); @@ -77,8 +81,22 @@ impl Mac { }) .await; } + + pub async fn send_command(&self, cmd: T) -> u8 + where + T: MacCommand, + { + let mut payload = [0u8; MAX_PACKET_SIZE]; + cmd.copy_into_slice(&mut payload); + + debug!("sending {:#x}", payload[..T::SIZE]); + + self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await + } } +const MAX_PACKET_SIZE: usize = 255; + impl evt::MemoryManager for Mac { /// SAFETY: passing a pointer to something other than a managed event packet is UB unsafe fn drop_event_packet(_: *mut EvtPacket) { diff --git a/embassy-stm32-wpan/src/sub/mac/opcodes.rs b/embassy-stm32-wpan/src/sub/mac/opcodes.rs new file mode 100644 index 000000000..511b78157 --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac/opcodes.rs @@ -0,0 +1,27 @@ +const ST_VENDOR_OGF: u16 = 0x3F; +const MAC_802_15_4_CMD_OPCODE_OFFSET: u16 = 0x280; + +const fn opcode(ocf: u16) -> isize { + ((ST_VENDOR_OGF << 9) | (MAC_802_15_4_CMD_OPCODE_OFFSET + ocf)) as isize +} + +pub enum OpcodeM4ToM0 { + MlmeAssociateReq = opcode(0x00), + MlmeAssociateRes = opcode(0x01), + MlmeDisassociateReq = opcode(0x02), + MlmeGetReq = opcode(0x03), + MlmeGtsReq = opcode(0x04), + MlmeOrphanRes = opcode(0x05), + MlmeResetReq = opcode(0x06), + MlmeRxEnableReq = opcode(0x07), + MlmeScanReq = opcode(0x08), + MlmeSetReq = opcode(0x09), + MlmeStartReq = opcode(0x0A), + MlmeSyncReq = opcode(0x0B), + MlmePollReq = opcode(0x0C), + MlmeDpsReq = opcode(0x0D), + MlmeSoundingReq = opcode(0x0E), + MlmeCalibrateReq = opcode(0x0F), + McpsDataReq = opcode(0x10), + McpsPurgeReq = opcode(0x11), +} diff --git a/examples/stm32wb/.cargo/config.toml b/examples/stm32wb/.cargo/config.toml index 8b6d6d754..cf62a10a0 100644 --- a/examples/stm32wb/.cargo/config.toml +++ b/examples/stm32wb/.cargo/config.toml @@ -1,7 +1,7 @@ [target.'cfg(all(target_arch = "arm", target_os = "none"))'] # replace STM32WB55CCUx with your chip as listed in `probe-rs chip list` -# runner = "probe-rs run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" -runner = "teleprobe local run --chip STM32WB55RG --elf" +runner = "probe-run --chip STM32WB55RGVx --speed 1000 --connect-under-reset" +# runner = "teleprobe local run --chip STM32WB55RG --elf" [build] target = "thumbv7em-none-eabihf" diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 203ca1486..109734546 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -23,7 +23,7 @@ heapless = { version = "0.7.5", default-features = false } [features] -default = ["ble"] +default = ["ble", "mac"] mac = ["embassy-stm32-wpan/mac"] ble = ["embassy-stm32-wpan/ble"] @@ -35,6 +35,10 @@ required-features = ["ble"] name = "tl_mbox_mac" required-features = ["mac"] +[[bin]] +name = "tl_mbox_mac_2" +required-features = ["mac"] + [[bin]] name = "eddystone_beacon" required-features = ["ble"] diff --git a/examples/stm32wb/src/bin/tl_mbox_mac_2.rs b/examples/stm32wb/src/bin/tl_mbox_mac_2.rs new file mode 100644 index 000000000..e069adf87 --- /dev/null +++ b/examples/stm32wb/src/bin/tl_mbox_mac_2.rs @@ -0,0 +1,117 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::bind_interrupts; +use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; +use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, MacAddress, ResetRequest, SetRequest}; +use embassy_stm32_wpan::sub::mm; +use embassy_stm32_wpan::TlMbox; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs{ + IPCC_C1_RX => ReceiveInterruptHandler; + IPCC_C1_TX => TransmitInterruptHandler; +}); + +#[embassy_executor::task] +async fn run_mm_queue(memory_manager: mm::MemoryManager) { + memory_manager.run_queue().await; +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + /* + How to make this work: + + - Obtain a NUCLEO-STM32WB55 from your preferred supplier. + - Download and Install STM32CubeProgrammer. + - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from + gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x + - Open STM32CubeProgrammer + - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware. + - Once complete, click connect to connect to the device. + - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services". + - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the + stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address. + - Select that file, the memory address, "verify download", and then "Firmware Upgrade". + - Select "Start Wireless Stack". + - Disconnect from the device. + - In the examples folder for stm32wb, modify the memory.x file to match your target device. + - Run this example. + + Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name. + */ + + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let config = Config::default(); + let mbox = TlMbox::init(p.IPCC, Irqs, config); + + spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap(); + + let sys_event = mbox.sys_subsystem.read().await; + info!("sys event: {}", sys_event.payload()); + + core::mem::drop(sys_event); + + let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; + info!("initialized mac: {}", result); + + info!("resetting"); + let response = mbox + .mac_subsystem + .send_command(ResetRequest { set_default_pib: true }) + .await; + info!("{}", response); + + info!("setting extended address"); + let extended_address: u64 = 0xACDE480000000001; + defmt::debug!("{}", &extended_address as *const _ as *const u8); + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &extended_address as *const _ as *const u8, + pib_attribute: 0x6F, + stuffing: [0; 3], + }) + .await; + info!("{}", response); + + // info!("association request"); + // mbox.mac_subsystem + // .send_command(AssociateRequest { + // channel_number: 16, + // channel_page: 0, + // coord_addr_mode: 2, + // coord_address: MacAddress { short: [0x22, 0x11] }, + // capability_information: 0x80, + // coord_pan_id: [0xAA, 0x1A], + // security_level: 0, + + // key_id_mode: 0, + // key_index: 0, + // key_source: [0; 8], + // }) + // .await; + // info!("reading"); + // let result = mbox.mac_subsystem.read().await; + // info!("{}", result.payload()); + + // + // info!("starting ble..."); + // mbox.ble_subsystem.t_write(0x0c, &[]).await; + // + // info!("waiting for ble..."); + // let ble_event = mbox.ble_subsystem.tl_read().await; + // + // info!("ble event: {}", ble_event.payload()); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5db74c7a9..bad6d3a42 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,8 +1,8 @@ # Before upgrading check that everything is available on all tier1 targets here: # https://rust-lang.github.io/rustup-components-history [toolchain] -channel = "nightly-2023-06-28" -components = [ "rust-src", "rustfmt", "llvm-tools-preview" ] +channel = "nightly" +components = [ "rust-src", "rustfmt", "llvm-tools" ] targets = [ "thumbv7em-none-eabi", "thumbv7m-none-eabi",