wip
This commit is contained in:
parent
8a811cfcf7
commit
4aca7c8811
@ -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 }
|
stm32wb-hci = { version = "0.1.2", features = ["version-5-0"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
default = ["stm32wb55rg", "mac", "ble"]
|
||||||
defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"]
|
defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"]
|
||||||
|
|
||||||
ble = ["dep:stm32wb-hci"]
|
ble = ["dep:stm32wb-hci"]
|
||||||
|
83
embassy-stm32-wpan/src/sub/mac/commands.rs
Normal file
83
embassy-stm32-wpan/src/sub/mac/commands.rs
Normal file
@ -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::<Self>()) };
|
||||||
|
|
||||||
|
buf[..a.len()].copy_from_slice(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub union MacAddress {
|
||||||
|
pub short: [u8; 2],
|
||||||
|
pub extended: [u8; 8],
|
||||||
|
}
|
@ -8,12 +8,16 @@ use embassy_futures::poll_once;
|
|||||||
use embassy_stm32::ipcc::Ipcc;
|
use embassy_stm32::ipcc::Ipcc;
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
|
use self::commands::MacCommand;
|
||||||
use crate::cmd::CmdPacket;
|
use crate::cmd::CmdPacket;
|
||||||
use crate::consts::TlPacketType;
|
use crate::consts::TlPacketType;
|
||||||
use crate::evt::{EvtBox, EvtPacket};
|
use crate::evt::{EvtBox, EvtPacket};
|
||||||
use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER};
|
use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER};
|
||||||
use crate::{channels, evt};
|
use crate::{channels, evt};
|
||||||
|
|
||||||
|
pub mod commands;
|
||||||
|
mod opcodes;
|
||||||
|
|
||||||
static MAC_WAKER: AtomicWaker = AtomicWaker::new();
|
static MAC_WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false);
|
static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
@ -77,8 +81,22 @@ impl Mac {
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_command<T>(&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 {
|
impl evt::MemoryManager for Mac {
|
||||||
/// SAFETY: passing a pointer to something other than a managed event packet is UB
|
/// SAFETY: passing a pointer to something other than a managed event packet is UB
|
||||||
unsafe fn drop_event_packet(_: *mut EvtPacket) {
|
unsafe fn drop_event_packet(_: *mut EvtPacket) {
|
27
embassy-stm32-wpan/src/sub/mac/opcodes.rs
Normal file
27
embassy-stm32-wpan/src/sub/mac/opcodes.rs
Normal file
@ -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),
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||||
# replace STM32WB55CCUx with your chip as listed in `probe-rs chip list`
|
# replace STM32WB55CCUx with your chip as listed in `probe-rs chip list`
|
||||||
# runner = "probe-rs run --chip STM32WB55RGVx --speed 1000 --connect-under-reset"
|
runner = "probe-run --chip STM32WB55RGVx --speed 1000 --connect-under-reset"
|
||||||
runner = "teleprobe local run --chip STM32WB55RG --elf"
|
# runner = "teleprobe local run --chip STM32WB55RG --elf"
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
target = "thumbv7em-none-eabihf"
|
target = "thumbv7em-none-eabihf"
|
||||||
|
@ -23,7 +23,7 @@ heapless = { version = "0.7.5", default-features = false }
|
|||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["ble"]
|
default = ["ble", "mac"]
|
||||||
mac = ["embassy-stm32-wpan/mac"]
|
mac = ["embassy-stm32-wpan/mac"]
|
||||||
ble = ["embassy-stm32-wpan/ble"]
|
ble = ["embassy-stm32-wpan/ble"]
|
||||||
|
|
||||||
@ -35,6 +35,10 @@ required-features = ["ble"]
|
|||||||
name = "tl_mbox_mac"
|
name = "tl_mbox_mac"
|
||||||
required-features = ["mac"]
|
required-features = ["mac"]
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "tl_mbox_mac_2"
|
||||||
|
required-features = ["mac"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "eddystone_beacon"
|
name = "eddystone_beacon"
|
||||||
required-features = ["ble"]
|
required-features = ["ble"]
|
||||||
|
117
examples/stm32wb/src/bin/tl_mbox_mac_2.rs
Normal file
117
examples/stm32wb/src/bin/tl_mbox_mac_2.rs
Normal file
@ -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();
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
# Before upgrading check that everything is available on all tier1 targets here:
|
# Before upgrading check that everything is available on all tier1 targets here:
|
||||||
# https://rust-lang.github.io/rustup-components-history
|
# https://rust-lang.github.io/rustup-components-history
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2023-06-28"
|
channel = "nightly"
|
||||||
components = [ "rust-src", "rustfmt", "llvm-tools-preview" ]
|
components = [ "rust-src", "rustfmt", "llvm-tools" ]
|
||||||
targets = [
|
targets = [
|
||||||
"thumbv7em-none-eabi",
|
"thumbv7em-none-eabi",
|
||||||
"thumbv7m-none-eabi",
|
"thumbv7m-none-eabi",
|
||||||
|
Loading…
Reference in New Issue
Block a user