aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32-wpan/src/consts.rs2
-rw-r--r--embassy-stm32-wpan/src/sub/mac/commands.rs394
-rw-r--r--embassy-stm32-wpan/src/sub/mac/mod.rs45
-rw-r--r--embassy-stm32-wpan/src/sub/mac/responses.rs0
-rw-r--r--embassy-stm32-wpan/src/sub/mac/typedefs.rs97
-rw-r--r--examples/stm32wb/Cargo.toml2
-rw-r--r--examples/stm32wb/src/bin/mac_ffd.rs174
-rw-r--r--examples/stm32wb/src/bin/mac_rfd.rs (renamed from examples/stm32wb/src/bin/tl_mbox_mac_2.rs)65
8 files changed, 703 insertions, 76 deletions
diff --git a/embassy-stm32-wpan/src/consts.rs b/embassy-stm32-wpan/src/consts.rs
index 1c84addb1..bd70851ea 100644
--- a/embassy-stm32-wpan/src/consts.rs
+++ b/embassy-stm32-wpan/src/consts.rs
@@ -6,6 +6,8 @@ use crate::PacketHeader;
6#[derive(Debug)] 6#[derive(Debug)]
7#[repr(C)] 7#[repr(C)]
8pub enum TlPacketType { 8pub enum TlPacketType {
9 MacCmd = 0x00,
10
9 BleCmd = 0x01, 11 BleCmd = 0x01,
10 AclData = 0x02, 12 AclData = 0x02,
11 BleEvt = 0x04, 13 BleEvt = 0x04,
diff --git a/embassy-stm32-wpan/src/sub/mac/commands.rs b/embassy-stm32-wpan/src/sub/mac/commands.rs
index 75a31d2fc..3c234a3ce 100644
--- a/embassy-stm32-wpan/src/sub/mac/commands.rs
+++ b/embassy-stm32-wpan/src/sub/mac/commands.rs
@@ -1,13 +1,99 @@
1use bit_field::BitField;
2
3use super::opcodes::OpcodeM4ToM0; 1use super::opcodes::OpcodeM4ToM0;
2use super::typedefs::{AddressMode, GtsCharacteristics, MacAddress, PibId};
4 3
5pub trait MacCommand { 4pub trait MacCommand {
6 type Response;
7 const OPCODE: OpcodeM4ToM0; 5 const OPCODE: OpcodeM4ToM0;
8 const SIZE: usize; 6 const SIZE: usize;
9 7
10 fn copy_into_slice(&self, buf: &mut [u8]); 8 fn copy_into_slice(&self, buf: &mut [u8]) {
9 unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) };
10 }
11}
12
13/// MLME ASSOCIATE Request used to request an association
14pub struct AssociateRequest {
15 /// the logical channel on which to attempt association
16 pub channel_number: u8,
17 /// the channel page on which to attempt association
18 pub channel_page: u8,
19 /// coordinator addressing mode
20 pub coord_addr_mode: AddressMode,
21 /// operational capabilities of the associating device
22 pub capability_information: u8,
23 /// the identifier of the PAN with which to associate
24 pub coord_pan_id: [u8; 2],
25 /// the security level to be used
26 pub security_level: u8,
27 /// the mode used to identify the key to be used
28 pub key_id_mode: u8,
29 /// the originator of the key to be used
30 pub key_source: [u8; 8],
31 /// Coordinator address
32 pub coord_address: MacAddress,
33 /// the index of the key to be used
34 pub key_index: u8,
35}
36
37impl MacCommand for AssociateRequest {
38 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq;
39 const SIZE: usize = 25;
40}
41
42/// MLME DISASSOCIATE Request sed to request a disassociation
43pub struct DisassociateRequest {
44 /// device addressing mode used
45 pub device_addr_mode: AddressMode,
46 /// the identifier of the PAN of the device
47 pub device_pan_id: [u8; 2],
48 /// the reason for the disassociation
49 pub disassociate_reason: u8,
50 /// device address
51 pub device_address: MacAddress,
52 /// `true` if the disassociation notification command is to be sent indirectly
53 pub tx_indirect: bool,
54 /// the security level to be used
55 pub security_level: u8,
56 /// the mode to be used to indetify the key to be used
57 pub key_id_mode: u8,
58 /// the index of the key to be used
59 pub key_index: u8,
60 /// the originator of the key to be used
61 pub key_source: [u8; 8],
62}
63
64impl MacCommand for DisassociateRequest {
65 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDisassociateReq;
66 const SIZE: usize = 24;
67}
68
69/// MLME GET Request used to request a PIB value
70pub struct GetRequest {
71 /// the name of the PIB attribute to read
72 pub pib_attribute: PibId,
73}
74
75impl MacCommand for GetRequest {
76 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
77 const SIZE: usize = 4;
78}
79
80/// MLME GTS Request used to request and maintain GTSs
81pub struct GtsRequest {
82 /// the characteristics of the GTS
83 pub characteristics: GtsCharacteristics,
84 /// the security level to be used
85 pub security_level: u8,
86 /// the mode used to identify the key to be used
87 pub key_id_mode: u8,
88 /// the index of the key to be used
89 pub key_index: u8,
90 /// the originator of the key to be used
91 pub key_source: [u8; 8],
92}
93
94impl MacCommand for GtsRequest {
95 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeGetReq;
96 const SIZE: usize = 12;
11} 97}
12 98
13pub struct ResetRequest { 99pub struct ResetRequest {
@@ -16,68 +102,302 @@ pub struct ResetRequest {
16} 102}
17 103
18impl MacCommand for ResetRequest { 104impl MacCommand for ResetRequest {
19 type Response = ();
20 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq; 105 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeResetReq;
21 const SIZE: usize = 4; 106 const SIZE: usize = 4;
107}
108
109/// MLME RX ENABLE Request used to request that the receiver is either enabled
110/// for a finite period of time or disabled
111pub struct RxEnableRequest {
112 /// the request operation can be deferred or not
113 pub defer_permit: bool,
114 /// configure the transceiver to RX with ranging for a value of
115 /// RANGING_ON or to not enable ranging for RANGING_OFF
116 pub ranging_rx_control: u8,
117 /// number of symbols measured before the receiver is to be enabled or disabled
118 pub rx_on_time: [u8; 4],
119 /// number of symbols for which the receiver is to be enabled
120 pub rx_on_duration: [u8; 4],
121}
122
123impl MacCommand for RxEnableRequest {
124 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeRxEnableReq;
125 const SIZE: usize = 12;
22 126
23 fn copy_into_slice(&self, buf: &mut [u8]) { 127 fn copy_into_slice(&self, buf: &mut [u8]) {
24 buf[0] = self.set_default_pib as u8; 128 buf[0] = self.defer_permit as u8;
129 buf[1] = self.ranging_rx_control as u8;
130
131 // stuffing to keep 32bit alignment
132 buf[2] = 0;
133 buf[3] = 0;
134
135 buf[4..8].copy_from_slice(&self.rx_on_time);
136 buf[8..12].copy_from_slice(&self.rx_on_duration);
25 } 137 }
26} 138}
27 139
140/// MLME SCAN Request used to initiate a channel scan over a given list of channels
141pub struct ScanRequest {
142 /// the type of scan to be performed
143 pub scan_type: u8,
144 /// the time spent on scanning each channel
145 pub scan_duration: u8,
146 /// channel page on which to perform the scan
147 pub channel_page: u8,
148 /// security level to be used
149 pub security_level: u8,
150 /// indicate which channels are to be scanned
151 pub scan_channels: [u8; 4],
152 /// originator the key to be used
153 pub key_source: [u8; 8],
154 /// mode used to identify the key to be used
155 pub key_id_mode: u8,
156 /// index of the key to be used
157 pub key_index: u8,
158}
159
160impl MacCommand for ScanRequest {
161 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeScanReq;
162 const SIZE: usize = 20;
163}
164
165/// MLME SET Request used to attempt to write the given value to the indicated PIB attribute
28#[repr(C)] 166#[repr(C)]
29pub struct SetRequest { 167pub struct SetRequest {
168 /// the pointer to the value of the PIB attribute to set
30 pub pib_attribute_ptr: *const u8, 169 pub pib_attribute_ptr: *const u8,
31 pub pib_attribute: u8, 170 /// the name of the PIB attribute to set
32 pub stuffing: [u8; 3], 171 pub pib_attribute: PibId,
33} 172}
34 173
35impl MacCommand for SetRequest { 174impl MacCommand for SetRequest {
36 type Response = ();
37 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq; 175 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSetReq;
38 const SIZE: usize = 8; 176 const SIZE: usize = 8;
177}
39 178
40 fn copy_into_slice(&self, buf: &mut [u8]) { 179/// MLME START Request used by the FFDs to intiate a new PAN or to begin using a new superframe
41 let address = self.pib_attribute_ptr as usize; 180/// configuration
42 181#[derive(Default)]
43 // 68 ff 2 20 6f 182pub struct StartRequest {
44 183 /// PAN indentifier to used by the device
45 let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, Self::SIZE) }; 184 pub pan_id: [u8; 2],
46 debug!("{:#04x}", a); 185 /// logical channel on which to begin
47 186 pub channel_number: u8,
48 unsafe { core::ptr::copy(self as *const _ as *const u8, buf as *mut _ as *mut u8, 8) }; 187 /// channel page on which to begin
188 pub channel_page: u8,
189 /// time at which to begin transmitting beacons
190 pub start_time: [u8; 4],
191 /// indicated how often the beacon is to be transmitted
192 pub beacon_order: u8,
193 /// length of the active portion of the superframe
194 pub superframe_order: u8,
195 /// indicated wheter the device is a PAN coordinator or not
196 pub pan_coordinator: bool,
197 /// indicates if the receiver of the beaconing device is disabled or not
198 pub battery_life_extension: bool,
199 /// indicated if the coordinator realignment command is to be trasmitted
200 pub coord_realignment: u8,
201 /// indicated if the coordinator realignment command is to be trasmitted
202 pub coord_realign_security_level: u8,
203 /// index of the key to be used
204 pub coord_realign_key_id_index: u8,
205 /// originator of the key to be used
206 pub coord_realign_key_source: [u8; 8],
207 /// security level to be used for beacon frames
208 pub beacon_security_level: u8,
209 /// mode used to identify the key to be used
210 pub beacon_key_id_mode: u8,
211 /// index of the key to be used
212 pub beacon_key_index: u8,
213 /// originator of the key to be used
214 pub beacon_key_source: [u8; 8],
215}
49 216
50 // buf[0] = self.pib_attribute_ptr as u8; 217impl MacCommand for StartRequest {
51 // buf[1] = self.pib_attribute; 218 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeStartReq;
52 } 219 const SIZE: usize = 35;
53} 220}
54 221
55pub struct AssociateRequest { 222/// MLME SYNC Request used to synchronize with the coordinator by acquiring and, if
223/// specified, tracking its beacons
224pub struct SyncRequest {
225 /// the channel number on which to attempt coordinator synchronization
56 pub channel_number: u8, 226 pub channel_number: u8,
227 /// the channel page on which to attempt coordinator synchronization
57 pub channel_page: u8, 228 pub channel_page: u8,
58 pub coord_addr_mode: u8, 229 /// `true` if the MLME is to synchronize with the next beacon and attempts
59 pub capability_information: u8, 230 /// to track all future beacons.
60 pub coord_pan_id: [u8; 2], 231 ///
232 /// `false` if the MLME is to synchronize with only the next beacon
233 pub track_beacon: bool,
234}
235
236impl MacCommand for SyncRequest {
237 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSyncReq;
238 const SIZE: usize = 4;
239}
240
241/// MLME POLL Request propmts the device to request data from the coordinator
242pub struct PollRequest {
243 /// addressing mode of the coordinator
244 pub coord_addr_mode: AddressMode,
245 /// security level to be used
61 pub security_level: u8, 246 pub security_level: u8,
247 /// mode used to identify the key to be used
62 pub key_id_mode: u8, 248 pub key_id_mode: u8,
63 pub key_source: [u8; 8], 249 /// index of the key to be used
250 pub key_index: u8,
251 /// coordinator address
64 pub coord_address: MacAddress, 252 pub coord_address: MacAddress,
253 /// originator of the key to be used
254 pub key_source: [u8; 8],
255 /// PAN identifier of the coordinator
256 pub coord_pan_id: [u8; 2],
257}
258
259impl MacCommand for PollRequest {
260 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmePollReq;
261 const SIZE: usize = 24;
262}
263
264/// MLME DPS Request allows the next higher layer to request that the PHY utilize a
265/// given pair of preamble codes for a single use pending expiration of the DPSIndexDuration
266pub struct DpsRequest {
267 /// the index value for the transmitter
268 tx_dps_index: u8,
269 /// the index value of the receiver
270 rx_dps_index: u8,
271 /// the number of symbols for which the transmitter and receiver will utilize the
272 /// respective DPS indices
273 dps_index_duration: u8,
274}
275
276impl MacCommand for DpsRequest {
277 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeDpsReq;
278 const SIZE: usize = 4;
279}
280
281/// MLME SOUNDING request primitive which is used by the next higher layer to request that
282/// the PHY respond with channel sounding information
283pub struct SoundingRequest;
284
285impl MacCommand for SoundingRequest {
286 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeSoundingReq;
287 const SIZE: usize = 4;
288}
289
290/// MLME CALIBRATE request primitive which used to obtain the results of a ranging
291/// calibration request from an RDEV
292pub struct CalibrateRequest;
293
294impl MacCommand for CalibrateRequest {
295 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeCalibrateReq;
296 const SIZE: usize = 4;
297}
298
299/// MCPS DATA Request used for MAC data related requests from the application
300pub struct DataRequest {
301 /// the handle assocated with the MSDU to be transmitted
302 pub msdu_ptr: *const u8,
303 /// source addressing mode used
304 pub src_addr_mode: AddressMode,
305 /// destination addressing mode used
306 pub dst_addr_mode: AddressMode,
307 /// destination PAN Id
308 pub dst_pan_id: [u8; 2],
309 /// destination address
310 pub dst_address: MacAddress,
311 /// the number of octets contained in the MSDU
312 pub msdu_length: u8,
313 /// the handle assocated with the MSDU to be transmitted
314 pub msdu_handle: u8,
315 /// the ACK transmittion options for the MSDU
316 pub ack_tx: u8,
317 /// `true` if a GTS is to be used for transmission
318 ///
319 /// `false` indicates that the CAP will be used
320 pub gts_tx: bool,
321 /// the pending bit transmission options for the MSDU
322 pub indirect_tx: u8,
323 /// the security level to be used
324 pub security_level: u8,
325 /// the mode used to indentify the key to be used
326 pub key_id_mode: u8,
327 /// the index of the key to be used
65 pub key_index: u8, 328 pub key_index: u8,
329 /// the originator of the key to be used
330 pub key_source: [u8; 8],
331 /// 2011 - the pulse repitition value
332 pub uwbprf: u8,
333 /// 2011 - the ranging configuration
334 pub ranging: u8,
335 /// 2011 - the preamble symbol repititions
336 pub uwb_preamble_symbol_repetitions: u8,
337 /// 2011 - indicates the data rate
338 pub datrate: u8,
66} 339}
67 340
68impl MacCommand for AssociateRequest { 341impl MacCommand for DataRequest {
69 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateReq; 342 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsDataReq;
70 const SIZE: usize = 25; 343 const SIZE: usize = 40;
71 type Response = (); 344}
72 345
73 fn copy_into_slice(&self, buf: &mut [u8]) { 346/// for MCPS PURGE Request used to purge an MSDU from the transaction queue
74 let a = unsafe { core::slice::from_raw_parts(&self as *const _ as *const u8, core::mem::size_of::<Self>()) }; 347pub struct PurgeRequest {
348 /// the handle associated with the MSDU to be purged from the transaction
349 /// queue
350 pub msdu_handle: u8,
351}
75 352
76 buf[..a.len()].copy_from_slice(a); 353impl MacCommand for PurgeRequest {
77 } 354 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::McpsPurgeReq;
355 const SIZE: usize = 4;
356}
357
358/// MLME ASSOCIATE Response used to initiate a response to an MLME-ASSOCIATE.indication
359pub struct AssociateResponse {
360 /// extended address of the device requesting association
361 pub device_address: [u8; 8],
362 /// 16-bitshort device address allocated by the coordinator on successful
363 /// association
364 pub assoc_short_address: [u8; 2],
365 /// status of the association attempt
366 pub status: u8,
367 /// security level to be used
368 pub security_level: u8,
369 /// the originator of the key to be used
370 pub key_source: [u8; 8],
371 /// the mode used to identify the key to be used
372 pub key_id_mode: u8,
373 /// the index of the key to be used
374 pub key_index: u8,
375}
376
377impl MacCommand for AssociateResponse {
378 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeAssociateRes;
379 const SIZE: usize = 24;
380}
381
382/// MLME ORPHAN Response used to respond to the MLME ORPHAN Indication
383pub struct OrphanResponse {
384 /// extended address of the orphaned device
385 pub orphan_address: [u8; 8],
386 /// short address allocated to the orphaned device
387 pub short_address: [u8; 2],
388 /// if the orphaned device is associated with coordinator or not
389 pub associated_member: bool,
390 /// security level to be used
391 pub security_level: u8,
392 /// the originator of the key to be used
393 pub key_source: [u8; 8],
394 /// the mode used to identify the key to be used
395 pub key_id_mode: u8,
396 /// the index of the key to be used
397 pub key_index: u8,
78} 398}
79 399
80pub union MacAddress { 400impl MacCommand for OrphanResponse {
81 pub short: [u8; 2], 401 const OPCODE: OpcodeM4ToM0 = OpcodeM4ToM0::MlmeOrphanRes;
82 pub extended: [u8; 8], 402 const SIZE: usize = 24;
83} 403}
diff --git a/embassy-stm32-wpan/src/sub/mac/mod.rs b/embassy-stm32-wpan/src/sub/mac/mod.rs
index 83970a881..8e117d978 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;
9use embassy_sync::waitqueue::AtomicWaker; 9use embassy_sync::waitqueue::AtomicWaker;
10 10
11use self::commands::MacCommand; 11use self::commands::MacCommand;
12use self::typedefs::MacStatus;
12use crate::cmd::CmdPacket; 13use crate::cmd::CmdPacket;
13use crate::consts::TlPacketType; 14use crate::consts::TlPacketType;
14use crate::evt::{EvtBox, EvtPacket}; 15use crate::evt::{EvtBox, EvtPacket};
15use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; 16use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER};
16use crate::{channels, evt}; 17use crate::{channels, evt};
17 18
18pub mod commands;
19mod opcodes; 19mod opcodes;
20pub mod commands;
21pub mod responses;
22pub mod typedefs;
20 23
21static MAC_WAKER: AtomicWaker = AtomicWaker::new(); 24static MAC_WAKER: AtomicWaker = AtomicWaker::new();
22static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); 25static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false);
@@ -59,12 +62,25 @@ impl Mac {
59 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` 62 /// `HW_IPCC_MAC_802_15_4_CmdEvtNot`
60 pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { 63 pub async fn write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 {
61 self.write(opcode, payload).await; 64 self.write(opcode, payload).await;
62 Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; 65 Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await;
63 66
64 unsafe { 67 unsafe {
65 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; 68 let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket;
66 let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; 69 let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8;
67 70
71 let evt_serial = (MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket)
72 .read_volatile()
73 .evt_serial;
74 let kind = (evt_serial).kind;
75 let evt_code = evt_serial.evt.evt_code;
76 let payload_len = evt_serial.evt.payload_len;
77 let payload = evt_serial.evt.payload;
78
79 debug!(
80 "evt kind {} evt_code {} len {} payload {}",
81 kind, evt_code, payload_len, payload
82 );
83
68 ptr::read_volatile(p_mac_rsp_evt) 84 ptr::read_volatile(p_mac_rsp_evt)
69 } 85 }
70 } 86 }
@@ -74,15 +90,32 @@ impl Mac {
74 Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { 90 Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe {
75 CmdPacket::write_into( 91 CmdPacket::write_into(
76 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), 92 MAC_802_15_4_CMD_BUFFER.as_mut_ptr(),
77 TlPacketType::OtCmd, 93 TlPacketType::MacCmd,
78 opcode, 94 opcode,
79 payload, 95 payload,
80 ); 96 );
81 }) 97 })
82 .await; 98 .await;
99
100 unsafe {
101 let typ = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.ty;
102 let cmd_code = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.cmd_code;
103 let payload_len = MAC_802_15_4_CMD_BUFFER
104 .as_ptr()
105 .read_volatile()
106 .cmdserial
107 .cmd
108 .payload_len;
109 let payload = MAC_802_15_4_CMD_BUFFER.as_ptr().read_volatile().cmdserial.cmd.payload;
110
111 debug!(
112 "serial type {} cmd_code {} len {} payload {}",
113 typ, cmd_code, payload_len, payload
114 );
115 }
83 } 116 }
84 117
85 pub async fn send_command<T>(&self, cmd: T) -> u8 118 pub async fn send_command<T>(&self, cmd: T) -> Result<MacStatus, ()>
86 where 119 where
87 T: MacCommand, 120 T: MacCommand,
88 { 121 {
@@ -91,7 +124,9 @@ impl Mac {
91 124
92 debug!("sending {:#x}", payload[..T::SIZE]); 125 debug!("sending {:#x}", payload[..T::SIZE]);
93 126
94 self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await 127 let response = self.write_and_get_response(T::OPCODE as u16, &payload[..T::SIZE]).await;
128
129 MacStatus::try_from(response)
95 } 130 }
96} 131}
97 132
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 000000000..e69de29bb
--- /dev/null
+++ b/embassy-stm32-wpan/src/sub/mac/responses.rs
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 000000000..d43d6e0cf
--- /dev/null
+++ b/embassy-stm32-wpan/src/sub/mac/typedefs.rs
@@ -0,0 +1,97 @@
1#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2pub enum MacStatus {
3 Success = 0x00,
4 Error = 0x01,
5 NotImplemented = 0x02,
6 NotSupported = 0x03,
7 HardwareNotSupported = 0x04,
8 Undefined = 0x05,
9}
10
11impl TryFrom<u8> for MacStatus {
12 type Error = ();
13
14 fn try_from(value: u8) -> Result<Self, <MacStatus as TryFrom<u8>>::Error> {
15 match value {
16 0x00 => Ok(Self::Success),
17 0x01 => Ok(Self::Error),
18 0x02 => Ok(Self::NotImplemented),
19 0x03 => Ok(Self::NotSupported),
20 0x04 => Ok(Self::HardwareNotSupported),
21 0x05 => Ok(Self::Undefined),
22 _ => Err(()),
23 }
24 }
25}
26
27/// this enum contains all the MAC PIB Ids
28#[cfg_attr(feature = "defmt", derive(defmt::Format))]
29pub enum PibId {
30 // PHY
31 CurrentChannel = 0x00,
32 ChannelsSupported = 0x01,
33 TransmitPower = 0x02,
34 CCAMode = 0x03,
35 CurrentPage = 0x04,
36 MaxFrameDuration = 0x05,
37 SHRDuration = 0x06,
38 SymbolsPerOctet = 0x07,
39
40 // MAC
41 AckWaitDuration = 0x40,
42 AssociationPermit = 0x41,
43 AutoRequest = 0x42,
44 BeaconPayload = 0x45,
45 BeaconPayloadLength = 0x46,
46 BeaconOrder = 0x47,
47 Bsn = 0x49,
48 CoordExtendedAdddress = 0x4A,
49 CoordShortAddress = 0x4B,
50 Dsn = 0x4C,
51 MaxFrameTotalWaitTime = 0x58,
52 MaxFrameRetries = 0x59,
53 PanId = 0x50,
54 ResponseWaitTime = 0x5A,
55 RxOnWhenIdle = 0x52,
56 SecurityEnabled = 0x5D,
57 ShortAddress = 0x53,
58 SuperframeOrder = 0x54,
59 TimestampSupported = 0x5C,
60 TransactionPersistenceTime = 0x55,
61 MaxBe = 0x57,
62 LifsPeriod = 0x5E,
63 SifsPeriod = 0x5F,
64 MaxCsmaBackoffs = 0x4E,
65 MinBe = 0x4F,
66 PanCoordinator = 0x10,
67 AssocPanCoordinator = 0x11,
68 ExtendedAddress = 0x6F,
69 AclEntryDescriptor = 0x70,
70 AclEntryDescriptorSize = 0x71,
71 DefaultSecurity = 0x72,
72 DefaultSecurityMaterialLength = 0x73,
73 DefaultSecurityMaterial = 0x74,
74 DefaultSecuritySuite = 0x75,
75 SecurityMode = 0x76,
76 CurrentAclEntries = 0x80,
77 DefaultSecurityExtendedAddress = 0x81,
78 AssociatedPanCoordinator = 0x56,
79 PromiscuousMode = 0x51,
80}
81
82#[cfg_attr(feature = "defmt", derive(defmt::Format))]
83pub enum AddressMode {
84 NoAddress = 0x00,
85 Reserved = 0x01,
86 Short = 0x02,
87 Extended = 0x03,
88}
89
90pub union MacAddress {
91 pub short: [u8; 2],
92 pub extended: [u8; 8],
93}
94
95pub struct GtsCharacteristics {
96 pub fields: u8,
97}
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index 109734546..f23c8afa6 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -36,7 +36,7 @@ name = "tl_mbox_mac"
36required-features = ["mac"] 36required-features = ["mac"]
37 37
38[[bin]] 38[[bin]]
39name = "tl_mbox_mac_2" 39name = "mac_ffd"
40required-features = ["mac"] 40required-features = ["mac"]
41 41
42[[bin]] 42[[bin]]
diff --git a/examples/stm32wb/src/bin/mac_ffd.rs b/examples/stm32wb/src/bin/mac_ffd.rs
new file mode 100644
index 000000000..4100d1ac5
--- /dev/null
+++ b/examples/stm32wb/src/bin/mac_ffd.rs
@@ -0,0 +1,174 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use defmt::*;
6use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts;
8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
9use embassy_stm32_wpan::sub::mac::commands::{ResetRequest, SetRequest, StartRequest};
10use embassy_stm32_wpan::sub::mac::typedefs::PibId;
11use embassy_stm32_wpan::sub::mm;
12use embassy_stm32_wpan::TlMbox;
13use {defmt_rtt as _, panic_probe as _};
14
15bind_interrupts!(struct Irqs{
16 IPCC_C1_RX => ReceiveInterruptHandler;
17 IPCC_C1_TX => TransmitInterruptHandler;
18});
19
20#[embassy_executor::task]
21async fn run_mm_queue(memory_manager: mm::MemoryManager) {
22 memory_manager.run_queue().await;
23}
24
25#[embassy_executor::main]
26async fn main(spawner: Spawner) {
27 /*
28 How to make this work:
29
30 - Obtain a NUCLEO-STM32WB55 from your preferred supplier.
31 - Download and Install STM32CubeProgrammer.
32 - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from
33 gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x
34 - Open STM32CubeProgrammer
35 - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware.
36 - Once complete, click connect to connect to the device.
37 - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services".
38 - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file
39 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
40 - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the
41 stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address.
42 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
43 - Select "Start Wireless Stack".
44 - Disconnect from the device.
45 - In the examples folder for stm32wb, modify the memory.x file to match your target device.
46 - Run this example.
47
48 Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name.
49 */
50
51 let p = embassy_stm32::init(Default::default());
52 info!("Hello World!");
53
54 let config = Config::default();
55 let mbox = TlMbox::init(p.IPCC, Irqs, config);
56
57 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
58
59 let sys_event = mbox.sys_subsystem.read().await;
60 info!("sys event: {}", sys_event.payload());
61
62 core::mem::drop(sys_event);
63
64 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
65 info!("initialized mac: {}", result);
66
67 info!("resetting");
68 let response = mbox
69 .mac_subsystem
70 .send_command(ResetRequest { set_default_pib: true })
71 .await;
72 info!("{}", response);
73
74 info!("setting extended address");
75 let extended_address: u64 = 0xACDE480000000001;
76 let response = mbox
77 .mac_subsystem
78 .send_command(SetRequest {
79 pib_attribute_ptr: &extended_address as *const _ as *const u8,
80 pib_attribute: PibId::ExtendedAddress,
81 })
82 .await;
83 info!("{}", response);
84
85 info!("setting short address");
86 let short_address: u16 = 0x1122;
87 let response = mbox
88 .mac_subsystem
89 .send_command(SetRequest {
90 pib_attribute_ptr: &short_address as *const _ as *const u8,
91 pib_attribute: PibId::ShortAddress,
92 })
93 .await;
94 info!("{}", response);
95
96 info!("setting association permit");
97 let association_permit: bool = true;
98 let response = mbox
99 .mac_subsystem
100 .send_command(SetRequest {
101 pib_attribute_ptr: &association_permit as *const _ as *const u8,
102 pib_attribute: PibId::AssociationPermit,
103 })
104 .await;
105 info!("{}", response);
106
107 info!("setting TX power");
108 let transmit_power: i8 = 2;
109 let response = mbox
110 .mac_subsystem
111 .send_command(SetRequest {
112 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
113 pib_attribute: PibId::TransmitPower,
114 })
115 .await;
116 info!("{}", response);
117
118 info!("starting FFD device");
119 let response = mbox
120 .mac_subsystem
121 .send_command(StartRequest {
122 channel_number: 16,
123 beacon_order: 0x0F,
124 superframe_order: 0x0F,
125 pan_coordinator: true,
126 battery_life_extension: false,
127 ..Default::default()
128 })
129 .await;
130 info!("{}", response);
131
132 info!("setting RX on when idle");
133 let rx_on_while_idle: bool = true;
134 let response = mbox
135 .mac_subsystem
136 .send_command(SetRequest {
137 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
138 pib_attribute: PibId::RxOnWhenIdle,
139 })
140 .await;
141 info!("{}", response);
142
143 // info!("association request");
144 // mbox.mac_subsystem
145 // .send_command(AssociateRequest {
146 // channel_number: 16,
147 // channel_page: 0,
148 // coord_addr_mode: 2,
149 // coord_address: MacAddress { short: [0x22, 0x11] },
150 // capability_information: 0x80,
151 // coord_pan_id: [0xAA, 0x1A],
152 // security_level: 0,
153
154 // key_id_mode: 0,
155 // key_index: 0,
156 // key_source: [0; 8],
157 // })
158 // .await;
159 // info!("reading");
160 // let result = mbox.mac_subsystem.read().await;
161 // info!("{}", result.payload());
162
163 //
164 // info!("starting ble...");
165 // mbox.ble_subsystem.t_write(0x0c, &[]).await;
166 //
167 // info!("waiting for ble...");
168 // let ble_event = mbox.ble_subsystem.tl_read().await;
169 //
170 // info!("ble event: {}", ble_event.payload());
171
172 info!("Test OK");
173 cortex_m::asm::bkpt();
174}
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac_2.rs b/examples/stm32wb/src/bin/mac_rfd.rs
index e069adf87..938fe754f 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::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_stm32::bind_interrupts; 7use embassy_stm32::bind_interrupts;
8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 8use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
9use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, MacAddress, ResetRequest, SetRequest}; 9use embassy_stm32_wpan::sub::mac::commands::{AssociateRequest, ResetRequest, SetRequest, StartRequest};
10use embassy_stm32_wpan::sub::mac::typedefs::{AddressMode, MacAddress, PibId};
10use embassy_stm32_wpan::sub::mm; 11use embassy_stm32_wpan::sub::mm;
11use embassy_stm32_wpan::TlMbox; 12use embassy_stm32_wpan::TlMbox;
12use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
@@ -71,46 +72,44 @@ async fn main(spawner: Spawner) {
71 info!("{}", response); 72 info!("{}", response);
72 73
73 info!("setting extended address"); 74 info!("setting extended address");
74 let extended_address: u64 = 0xACDE480000000001; 75 let extended_address: u64 = 0xACDE480000000002;
75 defmt::debug!("{}", &extended_address as *const _ as *const u8);
76 let response = mbox 76 let response = mbox
77 .mac_subsystem 77 .mac_subsystem
78 .send_command(SetRequest { 78 .send_command(SetRequest {
79 pib_attribute_ptr: &extended_address as *const _ as *const u8, 79 pib_attribute_ptr: &extended_address as *const _ as *const u8,
80 pib_attribute: 0x6F, 80 pib_attribute: PibId::ExtendedAddress,
81 stuffing: [0; 3],
82 }) 81 })
83 .await; 82 .await;
84 info!("{}", response); 83 info!("{}", response);
85 84
86 // info!("association request"); 85 info!("assocation request");
87 // mbox.mac_subsystem 86 let response = mbox
88 // .send_command(AssociateRequest { 87 .mac_subsystem
89 // channel_number: 16, 88 .send_command(AssociateRequest {
90 // channel_page: 0, 89 channel_number: 16,
91 // coord_addr_mode: 2, 90 channel_page: 0,
92 // coord_address: MacAddress { short: [0x22, 0x11] }, 91 coord_addr_mode: AddressMode::Short,
93 // capability_information: 0x80, 92 coord_address: MacAddress { short: [0x22, 0x11] },
94 // coord_pan_id: [0xAA, 0x1A], 93 capability_information: 0x80,
95 // security_level: 0, 94 coord_pan_id: [0xAA, 0x1A],
96 95 security_level: 0x00,
97 // key_id_mode: 0, 96 key_id_mode: 0,
98 // key_index: 0, 97 key_source: [0; 8],
99 // key_source: [0; 8], 98 key_index: 0,
100 // }) 99 })
101 // .await; 100 .await;
102 // info!("reading"); 101 info!("{}", response);
103 // let result = mbox.mac_subsystem.read().await; 102
104 // info!("{}", result.payload()); 103 info!("setting short address");
105 104 let short: u64 = 0xACDE480000000002;
106 // 105 let response = mbox
107 // info!("starting ble..."); 106 .mac_subsystem
108 // mbox.ble_subsystem.t_write(0x0c, &[]).await; 107 .send_command(SetRequest {
109 // 108 pib_attribute_ptr: &short as *const _ as *const u8,
110 // info!("waiting for ble..."); 109 pib_attribute: PibId::ShortAddress,
111 // let ble_event = mbox.ble_subsystem.tl_read().await; 110 })
112 // 111 .await;
113 // info!("ble event: {}", ble_event.payload()); 112 info!("{}", response);
114 113
115 info!("Test OK"); 114 info!("Test OK");
116 cortex_m::asm::bkpt(); 115 cortex_m::asm::bkpt();