From 6f4172fbc1280fdd9190ccddcf3cf6f25788c7be Mon Sep 17 00:00:00 2001 From: goueslati Date: Tue, 11 Jul 2023 16:07:33 +0100 Subject: [PATCH] wip: added MAC commands --- embassy-stm32-wpan/src/consts.rs | 2 + embassy-stm32-wpan/src/sub/mac/commands.rs | 426 +++++++++++++++--- embassy-stm32-wpan/src/sub/mac/mod.rs | 45 +- embassy-stm32-wpan/src/sub/mac/responses.rs | 0 embassy-stm32-wpan/src/sub/mac/typedefs.rs | 97 ++++ examples/stm32wb/Cargo.toml | 2 +- examples/stm32wb/src/bin/mac_ffd.rs | 174 +++++++ .../src/bin/{tl_mbox_mac_2.rs => mac_rfd.rs} | 63 ++- 8 files changed, 718 insertions(+), 91 deletions(-) create mode 100644 embassy-stm32-wpan/src/sub/mac/responses.rs create mode 100644 embassy-stm32-wpan/src/sub/mac/typedefs.rs create mode 100644 examples/stm32wb/src/bin/mac_ffd.rs rename examples/stm32wb/src/bin/{tl_mbox_mac_2.rs => mac_rfd.rs} (72%) diff --git a/embassy-stm32-wpan/src/consts.rs b/embassy-stm32-wpan/src/consts.rs index 1c84addb..bd70851e 100644 --- a/embassy-stm32-wpan/src/consts.rs +++ b/embassy-stm32-wpan/src/consts.rs @@ -6,6 +6,8 @@ use crate::PacketHeader; #[derive(Debug)] #[repr(C)] pub enum TlPacketType { + MacCmd = 0x00, + BleCmd = 0x01, AclData = 0x02, BleEvt = 0x04, diff --git a/embassy-stm32-wpan/src/sub/mac/commands.rs b/embassy-stm32-wpan/src/sub/mac/commands.rs index 75a31d2f..3c234a3c 100644 --- a/embassy-stm32-wpan/src/sub/mac/commands.rs +++ b/embassy-stm32-wpan/src/sub/mac/commands.rs @@ -1,13 +1,99 @@ -use bit_field::BitField; - use super::opcodes::OpcodeM4ToM0; +use super::typedefs::{AddressMode, GtsCharacteristics, MacAddress, PibId}; pub trait MacCommand { - type Response; const OPCODE: OpcodeM4ToM0; const SIZE: usize; - fn copy_into_slice(&self, buf: &mut [u8]); + fn copy_into_slice(&self, buf: &mut [u8]) { + unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) }; + } +} + +/// MLME ASSOCIATE Request used to request an association +pub struct AssociateRequest { + /// the logical channel on which to attempt association + pub channel_number: u8, + /// the channel page on which to attempt association + pub channel_page: u8, + /// coordinator addressing mode + pub coord_addr_mode: AddressMode, + /// operational capabilities of the associating device + pub capability_information: u8, + /// the identifier of the PAN with which to associate + pub coord_pan_id: [u8; 2], + /// the security level to be used + pub security_level: u8, + /// the mode used to identify the key to be used + pub key_id_mode: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], + /// Coordinator address + pub coord_address: MacAddress, + /// the index of the key to be used + pub key_index: u8, +} + +impl MacCommand for AssociateRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; + const SIZE: usize = 25; +} + +/// MLME DISASSOCIATE Request sed to request a disassociation +pub struct DisassociateRequest { + /// device addressing mode used + pub device_addr_mode: AddressMode, + /// the identifier of the PAN of the device + pub device_pan_id: [u8; 2], + /// the reason for the disassociation + pub disassociate_reason: u8, + /// device address + pub device_address: MacAddress, + /// `true` if the disassociation notification command is to be sent indirectly + pub tx_indirect: bool, + /// the security level to be used + pub security_level: u8, + /// the mode to be used to indetify the key to be used + pub key_id_mode: u8, + /// the index of the key to be used + pub key_index: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], +} + +impl MacCommand for DisassociateRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq; + const SIZE: usize = 24; +} + +/// MLME GET Request used to request a PIB value +pub struct GetRequest { + /// the name of the PIB attribute to read + pub pib_attribute: PibId, +} + +impl MacCommand for GetRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; + const SIZE: usize = 4; +} + +/// MLME GTS Request used to request and maintain GTSs +pub struct GtsRequest { + /// the characteristics of the GTS + pub characteristics: GtsCharacteristics, + /// the security level to be used + pub security_level: u8, + /// the mode used to identify the key to be used + pub key_id_mode: u8, + /// the index of the key to be used + pub key_index: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], +} + +impl MacCommand for GtsRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq; + const SIZE: usize = 12; } pub struct ResetRequest { @@ -16,68 +102,302 @@ pub struct ResetRequest { } impl MacCommand for ResetRequest { - type Response = (); const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; const SIZE: usize = 4; +} + +/// MLME RX ENABLE Request used to request that the receiver is either enabled +/// for a finite period of time or disabled +pub struct RxEnableRequest { + /// the request operation can be deferred or not + pub defer_permit: bool, + /// configure the transceiver to RX with ranging for a value of + /// RANGING_ON or to not enable ranging for RANGING_OFF + pub ranging_rx_control: u8, + /// number of symbols measured before the receiver is to be enabled or disabled + pub rx_on_time: [u8; 4], + /// number of symbols for which the receiver is to be enabled + pub rx_on_duration: [u8; 4], +} + +impl MacCommand for RxEnableRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq; + const SIZE: usize = 12; fn copy_into_slice(&self, buf: &mut [u8]) { - buf[0] = self.set_default_pib as u8; + buf[0] = self.defer_permit as u8; + buf[1] = self.ranging_rx_control as u8; + + // stuffing to keep 32bit alignment + buf[2] = 0; + buf[3] = 0; + + buf[4..8].copy_from_slice(&self.rx_on_time); + buf[8..12].copy_from_slice(&self.rx_on_duration); } } -#[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, +/// MLME SCAN Request used to initiate a channel scan over a given list of channels +pub struct ScanRequest { + /// the type of scan to be performed + pub scan_type: u8, + /// the time spent on scanning each channel + pub scan_duration: u8, + /// channel page on which to perform the scan pub channel_page: u8, - pub coord_addr_mode: u8, - pub capability_information: u8, - pub coord_pan_id: [u8; 2], + /// security level to be used pub security_level: u8, - pub key_id_mode: u8, + /// indicate which channels are to be scanned + pub scan_channels: [u8; 4], + /// originator the key to be used pub key_source: [u8; 8], - pub coord_address: MacAddress, + /// mode used to identify the key to be used + pub key_id_mode: u8, + /// index of the key to be used 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); - } +impl MacCommand for ScanRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq; + const SIZE: usize = 20; } -pub union MacAddress { - pub short: [u8; 2], - pub extended: [u8; 8], +/// MLME SET Request used to attempt to write the given value to the indicated PIB attribute +#[repr(C)] +pub struct SetRequest { + /// the pointer to the value of the PIB attribute to set + pub pib_attribute_ptr: *const u8, + /// the name of the PIB attribute to set + pub pib_attribute: PibId, +} + +impl MacCommand for SetRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; + const SIZE: usize = 8; +} + +/// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe +/// configuration +#[derive(Default)] +pub struct StartRequest { + /// PAN indentifier to used by the device + pub pan_id: [u8; 2], + /// logical channel on which to begin + pub channel_number: u8, + /// channel page on which to begin + pub channel_page: u8, + /// time at which to begin transmitting beacons + pub start_time: [u8; 4], + /// indicated how often the beacon is to be transmitted + pub beacon_order: u8, + /// length of the active portion of the superframe + pub superframe_order: u8, + /// indicated wheter the device is a PAN coordinator or not + pub pan_coordinator: bool, + /// indicates if the receiver of the beaconing device is disabled or not + pub battery_life_extension: bool, + /// indicated if the coordinator realignment command is to be trasmitted + pub coord_realignment: u8, + /// indicated if the coordinator realignment command is to be trasmitted + pub coord_realign_security_level: u8, + /// index of the key to be used + pub coord_realign_key_id_index: u8, + /// originator of the key to be used + pub coord_realign_key_source: [u8; 8], + /// security level to be used for beacon frames + pub beacon_security_level: u8, + /// mode used to identify the key to be used + pub beacon_key_id_mode: u8, + /// index of the key to be used + pub beacon_key_index: u8, + /// originator of the key to be used + pub beacon_key_source: [u8; 8], +} + +impl MacCommand for StartRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq; + const SIZE: usize = 35; +} + +/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if +/// specified, tracking its beacons +pub struct SyncRequest { + /// the channel number on which to attempt coordinator synchronization + pub channel_number: u8, + /// the channel page on which to attempt coordinator synchronization + pub channel_page: u8, + /// `true` if the MLME is to synchronize with the next beacon and attempts + /// to track all future beacons. + /// + /// `false` if the MLME is to synchronize with only the next beacon + pub track_beacon: bool, +} + +impl MacCommand for SyncRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq; + const SIZE: usize = 4; +} + +/// MLME POLL Request propmts the device to request data from the coordinator +pub struct PollRequest { + /// addressing mode of the coordinator + pub coord_addr_mode: AddressMode, + /// security level to be used + pub security_level: u8, + /// mode used to identify the key to be used + pub key_id_mode: u8, + /// index of the key to be used + pub key_index: u8, + /// coordinator address + pub coord_address: MacAddress, + /// originator of the key to be used + pub key_source: [u8; 8], + /// PAN identifier of the coordinator + pub coord_pan_id: [u8; 2], +} + +impl MacCommand for PollRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq; + const SIZE: usize = 24; +} + +/// MLME DPS Request allows the next higher layer to request that the PHY utilize a +/// given pair of preamble codes for a single use pending expiration of the DPSIndexDuration +pub struct DpsRequest { + /// the index value for the transmitter + tx_dps_index: u8, + /// the index value of the receiver + rx_dps_index: u8, + /// the number of symbols for which the transmitter and receiver will utilize the + /// respective DPS indices + dps_index_duration: u8, +} + +impl MacCommand for DpsRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq; + const SIZE: usize = 4; +} + +/// MLME SOUNDING request primitive which is used by the next higher layer to request that +/// the PHY respond with channel sounding information +pub struct SoundingRequest; + +impl MacCommand for SoundingRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq; + const SIZE: usize = 4; +} + +/// MLME CALIBRATE request primitive which used to obtain the results of a ranging +/// calibration request from an RDEV +pub struct CalibrateRequest; + +impl MacCommand for CalibrateRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq; + const SIZE: usize = 4; +} + +/// MCPS DATA Request used for MAC data related requests from the application +pub struct DataRequest { + /// the handle assocated with the MSDU to be transmitted + pub msdu_ptr: *const u8, + /// source addressing mode used + pub src_addr_mode: AddressMode, + /// destination addressing mode used + pub dst_addr_mode: AddressMode, + /// destination PAN Id + pub dst_pan_id: [u8; 2], + /// destination address + pub dst_address: MacAddress, + /// the number of octets contained in the MSDU + pub msdu_length: u8, + /// the handle assocated with the MSDU to be transmitted + pub msdu_handle: u8, + /// the ACK transmittion options for the MSDU + pub ack_tx: u8, + /// `true` if a GTS is to be used for transmission + /// + /// `false` indicates that the CAP will be used + pub gts_tx: bool, + /// the pending bit transmission options for the MSDU + pub indirect_tx: u8, + /// the security level to be used + pub security_level: u8, + /// the mode used to indentify the key to be used + pub key_id_mode: u8, + /// the index of the key to be used + pub key_index: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], + /// 2011 - the pulse repitition value + pub uwbprf: u8, + /// 2011 - the ranging configuration + pub ranging: u8, + /// 2011 - the preamble symbol repititions + pub uwb_preamble_symbol_repetitions: u8, + /// 2011 - indicates the data rate + pub datrate: u8, +} + +impl MacCommand for DataRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq; + const SIZE: usize = 40; +} + +/// for MCPS PURGE Request used to purge an MSDU from the transaction queue +pub struct PurgeRequest { + /// the handle associated with the MSDU to be purged from the transaction + /// queue + pub msdu_handle: u8, +} + +impl MacCommand for PurgeRequest { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq; + const SIZE: usize = 4; +} + +/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication +pub struct AssociateResponse { + /// extended address of the device requesting association + pub device_address: [u8; 8], + /// 16-bitshort device address allocated by the coordinator on successful + /// association + pub assoc_short_address: [u8; 2], + /// status of the association attempt + pub status: u8, + /// security level to be used + pub security_level: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], + /// the mode used to identify the key to be used + pub key_id_mode: u8, + /// the index of the key to be used + pub key_index: u8, +} + +impl MacCommand for AssociateResponse { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes; + const SIZE: usize = 24; +} + +/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication +pub struct OrphanResponse { + /// extended address of the orphaned device + pub orphan_address: [u8; 8], + /// short address allocated to the orphaned device + pub short_address: [u8; 2], + /// if the orphaned device is associated with coordinator or not + pub associated_member: bool, + /// security level to be used + pub security_level: u8, + /// the originator of the key to be used + pub key_source: [u8; 8], + /// the mode used to identify the key to be used + pub key_id_mode: u8, + /// the index of the key to be used + pub key_index: u8, +} + +impl MacCommand for OrphanResponse { + const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes; + const SIZE: usize = 24; } diff --git a/embassy-stm32-wpan/src/sub/mac/mod.rs b/embassy-stm32-wpan/src/sub/mac/mod.rs index 83970a88..8e117d97 100644 --- a/embassy-stm32-wpan/src/sub/mac/mod.rs +++ b/embassy-stm32-wpan/src/sub/mac/mod.rs @@ -9,14 +9,17 @@ use embassy_stm32::ipcc::Ipcc; use embassy_sync::waitqueue::AtomicWaker; use self::commands::MacCommand; +use self::typedefs::MacStatus; 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; +pub mod commands; +pub mod responses; +pub mod typedefs; static MAC_WAKER: AtomicWaker = AtomicWaker::new(); static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); @@ -59,12 +62,25 @@ impl Mac { /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { self.write(opcode, payload).await; - Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; + Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await; unsafe { let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; + let evt_serial = (MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket) + .read_volatile() + .evt_serial; + let kind = (evt_serial).kind; + let evt_code = evt_serial.evt.evt_code; + let payload_len = evt_serial.evt.payload_len; + let payload = evt_serial.evt.payload; + + debug!( + "evt kind {} evt_code {} len {} payload {}", + kind, evt_code, payload_len, payload + ); + ptr::read_volatile(p_mac_rsp_evt) } } @@ -74,15 +90,32 @@ impl Mac { Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { CmdPacket::write_into( MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), - TlPacketType::OtCmd, + TlPacketType::MacCmd, opcode, payload, ); }) .await; + + unsafe { + let typ = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.ty; + let cmd_code = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.cmd_code; + let payload_len = MAC_802_15_4_CMD_BUFFER + .as_ptr() + .read_volatile() + .cmdserial + .cmd + .payload_len; + let payload = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.payload; + + debug!( + "serial type {} cmd_code {} len {} payload {}", + typ, cmd_code, payload_len, payload + ); + } } - pub async fn send_command(&self, cmd: T) -> u8 + pub async fn send_command(&self, cmd: T) -> Result where T: MacCommand, { @@ -91,7 +124,9 @@ impl Mac { debug!("sending {:#x}", payload[..T::SIZE]); - self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await + let response = self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await; + + MacStatus::try_from(response) } } diff --git a/embassy-stm32-wpan/src/sub/mac/responses.rs b/embassy-stm32-wpan/src/sub/mac/responses.rs new file mode 100644 index 00000000..e69de29b diff --git a/embassy-stm32-wpan/src/sub/mac/typedefs.rs b/embassy-stm32-wpan/src/sub/mac/typedefs.rs new file mode 100644 index 00000000..d43d6e0c --- /dev/null +++ b/embassy-stm32-wpan/src/sub/mac/typedefs.rs @@ -0,0 +1,97 @@ +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum MacStatus { + Success = 0x00, + Error = 0x01, + NotImplemented = 0x02, + NotSupported = 0x03, + HardwareNotSupported = 0x04, + Undefined = 0x05, +} + +impl TryFrom for MacStatus { + type Error = (); + + fn try_from(value: u8) -> Result>::Error> { + match value { + 0x00 => Ok(Self::Success), + 0x01 => Ok(Self::Error), + 0x02 => Ok(Self::NotImplemented), + 0x03 => Ok(Self::NotSupported), + 0x04 => Ok(Self::HardwareNotSupported), + 0x05 => Ok(Self::Undefined), + _ => Err(()), + } + } +} + +/// this enum contains all the MAC PIB Ids +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum PibId { + // PHY + CurrentChannel = 0x00, + ChannelsSupported = 0x01, + TransmitPower = 0x02, + CCAMode = 0x03, + CurrentPage = 0x04, + MaxFrameDuration = 0x05, + SHRDuration = 0x06, + SymbolsPerOctet = 0x07, + + // MAC + AckWaitDuration = 0x40, + AssociationPermit = 0x41, + AutoRequest = 0x42, + BeaconPayload = 0x45, + BeaconPayloadLength = 0x46, + BeaconOrder = 0x47, + Bsn = 0x49, + CoordExtendedAdddress = 0x4A, + CoordShortAddress = 0x4B, + Dsn = 0x4C, + MaxFrameTotalWaitTime = 0x58, + MaxFrameRetries = 0x59, + PanId = 0x50, + ResponseWaitTime = 0x5A, + RxOnWhenIdle = 0x52, + SecurityEnabled = 0x5D, + ShortAddress = 0x53, + SuperframeOrder = 0x54, + TimestampSupported = 0x5C, + TransactionPersistenceTime = 0x55, + MaxBe = 0x57, + LifsPeriod = 0x5E, + SifsPeriod = 0x5F, + MaxCsmaBackoffs = 0x4E, + MinBe = 0x4F, + PanCoordinator = 0x10, + AssocPanCoordinator = 0x11, + ExtendedAddress = 0x6F, + AclEntryDescriptor = 0x70, + AclEntryDescriptorSize = 0x71, + DefaultSecurity = 0x72, + DefaultSecurityMaterialLength = 0x73, + DefaultSecurityMaterial = 0x74, + DefaultSecuritySuite = 0x75, + SecurityMode = 0x76, + CurrentAclEntries = 0x80, + DefaultSecurityExtendedAddress = 0x81, + AssociatedPanCoordinator = 0x56, + PromiscuousMode = 0x51, +} + +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum AddressMode { + NoAddress = 0x00, + Reserved = 0x01, + Short = 0x02, + Extended = 0x03, +} + +pub union MacAddress { + pub short: [u8; 2], + pub extended: [u8; 8], +} + +pub struct GtsCharacteristics { + pub fields: u8, +} diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index 10973454..f23c8afa 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml @@ -36,7 +36,7 @@ name = "tl_mbox_mac" required-features = ["mac"] [[bin]] -name = "tl_mbox_mac_2" +name = "mac_ffd" required-features = ["mac"] [[bin]] diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs new file mode 100644 index 00000000..4100d1ac --- /dev/null +++ b/examples/stm32wb/src/bin/mac_ffd.rs @@ -0,0 +1,174 @@ +#![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::{ResetRequest, SetRequest, StartRequest}; +use embassy_stm32_wpan::sub::mac::typedefs::PibId; +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; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &extended_address as *const _ as *const u8, + pib_attribute: PibId::ExtendedAddress, + }) + .await; + info!("{}", response); + + info!("setting short address"); + let short_address: u16 = 0x1122; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &short_address as *const _ as *const u8, + pib_attribute: PibId::ShortAddress, + }) + .await; + info!("{}", response); + + info!("setting association permit"); + let association_permit: bool = true; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &association_permit as *const _ as *const u8, + pib_attribute: PibId::AssociationPermit, + }) + .await; + info!("{}", response); + + info!("setting TX power"); + let transmit_power: i8 = 2; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &transmit_power as *const _ as *const u8, + pib_attribute: PibId::TransmitPower, + }) + .await; + info!("{}", response); + + info!("starting FFD device"); + let response = mbox + .mac_subsystem + .send_command(StartRequest { + channel_number: 16, + beacon_order: 0x0F, + superframe_order: 0x0F, + pan_coordinator: true, + battery_life_extension: false, + ..Default::default() + }) + .await; + info!("{}", response); + + info!("setting RX on when idle"); + let rx_on_while_idle: bool = true; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8, + pib_attribute: PibId::RxOnWhenIdle, + }) + .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/examples/stm32wb/src/bin/tl_mbox_mac_2.rs b/examples/stm32wb/src/bin/mac_rfd.rs similarity index 72% rename from examples/stm32wb/src/bin/tl_mbox_mac_2.rs rename to examples/stm32wb/src/bin/mac_rfd.rs index e069adf8..938fe754 100644 --- a/examples/stm32wb/src/bin/tl_mbox_mac_2.rs +++ b/examples/stm32wb/src/bin/mac_rfd.rs @@ -6,7 +6,8 @@ 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::mac::commands::{AssociateRequest, ResetRequest, SetRequest, StartRequest}; +use embassy_stm32_wpan::sub::mac::typedefs::{AddressMode, MacAddress, PibId}; use embassy_stm32_wpan::sub::mm; use embassy_stm32_wpan::TlMbox; use {defmt_rtt as _, panic_probe as _}; @@ -71,46 +72,44 @@ async fn main(spawner: Spawner) { info!("{}", response); info!("setting extended address"); - let extended_address: u64 = 0xACDE480000000001; - defmt::debug!("{}", &extended_address as *const _ as *const u8); + let extended_address: u64 = 0xACDE480000000002; let response = mbox .mac_subsystem .send_command(SetRequest { pib_attribute_ptr: &extended_address as *const _ as *const u8, - pib_attribute: 0x6F, - stuffing: [0; 3], + pib_attribute: PibId::ExtendedAddress, }) .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, + info!("assocation request"); + let response = mbox + .mac_subsystem + .send_command(AssociateRequest { + channel_number: 16, + channel_page: 0, + coord_addr_mode: AddressMode::Short, + coord_address: MacAddress { short: [0x22, 0x11] }, + capability_information: 0x80, + coord_pan_id: [0xAA, 0x1A], + security_level: 0x00, + key_id_mode: 0, + key_source: [0; 8], + key_index: 0, + }) + .await; + info!("{}", response); - // 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!("setting short address"); + let short: u64 = 0xACDE480000000002; + let response = mbox + .mac_subsystem + .send_command(SetRequest { + pib_attribute_ptr: &short as *const _ as *const u8, + pib_attribute: PibId::ShortAddress, + }) + .await; + info!("{}", response); info!("Test OK"); cortex_m::asm::bkpt();