aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxoviat <[email protected]>2023-06-23 02:09:52 +0000
committerGitHub <[email protected]>2023-06-23 02:09:52 +0000
commit6f17286c7525050a3acfdbb889915730913518b0 (patch)
tree8f62f023c207ffa9203541433f600702cbb5ea1a
parent70907d84f197d1c5d5d112ae1172e9070d41b730 (diff)
parentcaf63b9e7336ed3ddb0dc997d431f15a26ae7693 (diff)
Merge pull request #1576 from OueslatiGhaith/hci_v2
wpan: add BLE HCI
-rw-r--r--embassy-stm32-wpan/Cargo.toml4
-rw-r--r--embassy-stm32-wpan/src/ble.rs20
-rw-r--r--embassy-stm32-wpan/src/cmd.rs2
-rw-r--r--embassy-stm32-wpan/src/evt.rs15
-rw-r--r--embassy-stm32-wpan/src/lhci.rs111
-rw-r--r--embassy-stm32-wpan/src/lib.rs2
-rw-r--r--examples/stm32wb/.cargo/config.toml2
-rw-r--r--examples/stm32wb/Cargo.toml9
-rw-r--r--examples/stm32wb/src/bin/eddystone_beacon.rs249
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_ble.rs4
-rw-r--r--examples/stm32wb/src/bin/tl_mbox_mac.rs4
-rw-r--r--tests/stm32/Cargo.toml3
-rw-r--r--tests/stm32/src/bin/tl_mbox.rs221
13 files changed, 613 insertions, 33 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index f9023ed79..6d78ca577 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -23,11 +23,13 @@ cortex-m = "0.7.6"
23heapless = "0.7.16" 23heapless = "0.7.16"
24 24
25bit_field = "0.10.2" 25bit_field = "0.10.2"
26stm32-device-signature = { version = "0.3.3", features = ["stm32wb5x"] }
27stm32wb-hci = { version = "0.1.2", features = ["version-5-0"], optional = true }
26 28
27[features] 29[features]
28defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"] 30defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt"]
29 31
30ble = [] 32ble = ["dep:stm32wb-hci"]
31mac = [] 33mac = []
32 34
33stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ] 35stm32wb10cc = [ "embassy-stm32/stm32wb10cc" ]
diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs
index 60e0cbdf8..619cd66a0 100644
--- a/embassy-stm32-wpan/src/ble.rs
+++ b/embassy-stm32-wpan/src/ble.rs
@@ -1,6 +1,7 @@
1use core::marker::PhantomData; 1use core::marker::PhantomData;
2 2
3use embassy_stm32::ipcc::Ipcc; 3use embassy_stm32::ipcc::Ipcc;
4use hci::Opcode;
4 5
5use crate::channels; 6use crate::channels;
6use crate::cmd::CmdPacket; 7use crate::cmd::CmdPacket;
@@ -29,7 +30,7 @@ impl Ble {
29 Self { phantom: PhantomData } 30 Self { phantom: PhantomData }
30 } 31 }
31 /// `HW_IPCC_BLE_EvtNot` 32 /// `HW_IPCC_BLE_EvtNot`
32 pub async fn read(&self) -> EvtBox { 33 pub async fn tl_read(&self) -> EvtBox {
33 Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { 34 Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe {
34 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { 35 if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) {
35 Some(EvtBox::new(node_ptr.cast())) 36 Some(EvtBox::new(node_ptr.cast()))
@@ -41,7 +42,7 @@ impl Ble {
41 } 42 }
42 43
43 /// `TL_BLE_SendCmd` 44 /// `TL_BLE_SendCmd`
44 pub async fn write(&self, opcode: u16, payload: &[u8]) { 45 pub async fn tl_write(&self, opcode: u16, payload: &[u8]) {
45 Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { 46 Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe {
46 CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); 47 CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload);
47 }) 48 })
@@ -61,3 +62,18 @@ impl Ble {
61 .await; 62 .await;
62 } 63 }
63} 64}
65
66pub extern crate stm32wb_hci as hci;
67
68impl hci::Controller for Ble {
69 async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) {
70 self.tl_write(opcode.0, payload).await;
71 }
72
73 async fn controller_read_into(&self, buf: &mut [u8]) {
74 let evt_box = self.tl_read().await;
75 let evt_serial = evt_box.serial();
76
77 buf[..evt_serial.len()].copy_from_slice(evt_serial);
78 }
79}
diff --git a/embassy-stm32-wpan/src/cmd.rs b/embassy-stm32-wpan/src/cmd.rs
index c8056aaa7..8428b6ffc 100644
--- a/embassy-stm32-wpan/src/cmd.rs
+++ b/embassy-stm32-wpan/src/cmd.rs
@@ -52,7 +52,7 @@ impl CmdPacket {
52 p_cmd_serial, 52 p_cmd_serial,
53 CmdSerialStub { 53 CmdSerialStub {
54 ty: packet_type as u8, 54 ty: packet_type as u8,
55 cmd_code: cmd_code, 55 cmd_code,
56 payload_len: payload.len() as u8, 56 payload_len: payload.len() as u8,
57 }, 57 },
58 ); 58 );
diff --git a/embassy-stm32-wpan/src/evt.rs b/embassy-stm32-wpan/src/evt.rs
index 47bdc49bf..25249a13a 100644
--- a/embassy-stm32-wpan/src/evt.rs
+++ b/embassy-stm32-wpan/src/evt.rs
@@ -1,6 +1,7 @@
1use core::{ptr, slice}; 1use core::{ptr, slice};
2 2
3use super::PacketHeader; 3use super::PacketHeader;
4use crate::consts::TL_EVT_HEADER_SIZE;
4 5
5/** 6/**
6 * The payload of `Evt` for a command status event 7 * The payload of `Evt` for a command status event
@@ -124,6 +125,20 @@ impl EvtBox {
124 slice::from_raw_parts(p_payload, payload_len as usize) 125 slice::from_raw_parts(p_payload, payload_len as usize)
125 } 126 }
126 } 127 }
128
129 /// writes an underlying [`EvtPacket`] into the provided buffer.
130 /// Returns the number of bytes that were written.
131 /// Returns an error if event kind is unknown or if provided buffer size is not enough.
132 pub fn serial<'a>(&'a self) -> &'a [u8] {
133 unsafe {
134 let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial;
135 let evt_serial_buf: *const u8 = evt_serial.cast();
136
137 let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE;
138
139 slice::from_raw_parts(evt_serial_buf, len)
140 }
141 }
127} 142}
128 143
129impl Drop for EvtBox { 144impl Drop for EvtBox {
diff --git a/embassy-stm32-wpan/src/lhci.rs b/embassy-stm32-wpan/src/lhci.rs
new file mode 100644
index 000000000..62116a695
--- /dev/null
+++ b/embassy-stm32-wpan/src/lhci.rs
@@ -0,0 +1,111 @@
1use crate::cmd::CmdPacket;
2use crate::consts::{TlPacketType, TL_EVT_HEADER_SIZE};
3use crate::evt::{CcEvt, EvtPacket, EvtSerial};
4use crate::tables::{DeviceInfoTable, RssInfoTable, SafeBootInfoTable, WirelessFwInfoTable};
5use crate::TL_REF_TABLE;
6
7const TL_BLEEVT_CC_OPCODE: u8 = 0x0e;
8const LHCI_OPCODE_C1_DEVICE_INF: u16 = 0xfd62;
9
10const PACKAGE_DATA_PTR: *const u8 = 0x1FFF_7500 as _;
11const UID64_PTR: *const u32 = 0x1FFF_7580 as _;
12
13#[derive(Debug, Copy, Clone)]
14#[repr(C, packed)]
15pub struct LhciC1DeviceInformationCcrp {
16 pub status: u8,
17 pub rev_id: u16,
18 pub dev_code_id: u16,
19 pub package_type: u8,
20 pub device_type_id: u8,
21 pub st_company_id: u32,
22 pub uid64: u32,
23
24 pub uid96_0: u32,
25 pub uid96_1: u32,
26 pub uid96_2: u32,
27
28 pub safe_boot_info_table: SafeBootInfoTable,
29 pub rss_info_table: RssInfoTable,
30 pub wireless_fw_info_table: WirelessFwInfoTable,
31
32 pub app_fw_inf: u32,
33}
34
35impl Default for LhciC1DeviceInformationCcrp {
36 fn default() -> Self {
37 let DeviceInfoTable {
38 safe_boot_info_table,
39 rss_info_table,
40 wireless_fw_info_table,
41 } = unsafe { &*(*TL_REF_TABLE.as_ptr()).device_info_table }.clone();
42
43 let device_id = stm32_device_signature::device_id();
44 let uid96_0 = (device_id[3] as u32) << 24
45 | (device_id[2] as u32) << 16
46 | (device_id[1] as u32) << 8
47 | device_id[0] as u32;
48 let uid96_1 = (device_id[7] as u32) << 24
49 | (device_id[6] as u32) << 16
50 | (device_id[5] as u32) << 8
51 | device_id[4] as u32;
52 let uid96_2 = (device_id[11] as u32) << 24
53 | (device_id[10] as u32) << 16
54 | (device_id[9] as u32) << 8
55 | device_id[8] as u32;
56
57 let package_type = unsafe { *PACKAGE_DATA_PTR };
58 let uid64 = unsafe { *UID64_PTR };
59 let st_company_id = unsafe { *UID64_PTR.offset(1) } >> 8 & 0x00FF_FFFF;
60 let device_type_id = (unsafe { *UID64_PTR.offset(1) } & 0x000000FF) as u8;
61
62 LhciC1DeviceInformationCcrp {
63 status: 0,
64 rev_id: 0,
65 dev_code_id: 0,
66 package_type,
67 device_type_id,
68 st_company_id,
69 uid64,
70 uid96_0,
71 uid96_1,
72 uid96_2,
73 safe_boot_info_table,
74 rss_info_table,
75 wireless_fw_info_table,
76 app_fw_inf: (1 << 8), // 0.0.1
77 }
78 }
79}
80
81impl LhciC1DeviceInformationCcrp {
82 pub fn new() -> Self {
83 Self::default()
84 }
85
86 pub fn write(&self, cmd_packet: &mut CmdPacket) {
87 let self_size = core::mem::size_of::<LhciC1DeviceInformationCcrp>();
88
89 unsafe {
90 let cmd_packet_ptr: *mut CmdPacket = cmd_packet;
91 let evet_packet_ptr: *mut EvtPacket = cmd_packet_ptr.cast();
92
93 let evt_serial: *mut EvtSerial = &mut (*evet_packet_ptr).evt_serial;
94 let evt_payload = (*evt_serial).evt.payload.as_mut_ptr();
95 let evt_cc: *mut CcEvt = evt_payload.cast();
96 let evt_cc_payload_buf = (*evt_cc).payload.as_mut_ptr();
97
98 (*evt_serial).kind = TlPacketType::LocRsp as u8;
99 (*evt_serial).evt.evt_code = TL_BLEEVT_CC_OPCODE;
100 (*evt_serial).evt.payload_len = TL_EVT_HEADER_SIZE as u8 + self_size as u8;
101
102 (*evt_cc).cmd_code = LHCI_OPCODE_C1_DEVICE_INF;
103 (*evt_cc).num_cmd = 1;
104
105 let self_ptr: *const LhciC1DeviceInformationCcrp = self;
106 let self_buf = self_ptr.cast();
107
108 core::ptr::copy(self_buf, evt_cc_payload_buf, self_size);
109 }
110 }
111}
diff --git a/embassy-stm32-wpan/src/lib.rs b/embassy-stm32-wpan/src/lib.rs
index 5aec9933c..bf0f0466e 100644
--- a/embassy-stm32-wpan/src/lib.rs
+++ b/embassy-stm32-wpan/src/lib.rs
@@ -1,4 +1,5 @@
1#![no_std] 1#![no_std]
2#![cfg_attr(feature = "ble", feature(async_fn_in_trait))]
2 3
3// This must go FIRST so that all the other modules see its macros. 4// This must go FIRST so that all the other modules see its macros.
4pub mod fmt; 5pub mod fmt;
@@ -21,6 +22,7 @@ pub mod channels;
21pub mod cmd; 22pub mod cmd;
22pub mod consts; 23pub mod consts;
23pub mod evt; 24pub mod evt;
25pub mod lhci;
24#[cfg(feature = "mac")] 26#[cfg(feature = "mac")]
25pub mod mac; 27pub mod mac;
26pub mod mm; 28pub mod mm;
diff --git a/examples/stm32wb/.cargo/config.toml b/examples/stm32wb/.cargo/config.toml
index d23fdc513..35317a297 100644
--- a/examples/stm32wb/.cargo/config.toml
+++ b/examples/stm32wb/.cargo/config.toml
@@ -1,6 +1,6 @@
1[target.'cfg(all(target_arch = "arm", target_os = "none"))'] 1[target.'cfg(all(target_arch = "arm", target_os = "none"))']
2# replace STM32WB55CCUx with your chip as listed in `probe-rs-cli chip list` 2# replace STM32WB55CCUx with your chip as listed in `probe-rs-cli chip list`
3# runner = "probe-rs-cli run --chip STM32WB55CCUx --speed 1000 --connect-under-reset" 3# runner = "probe-rs-cli run --chip STM32WB55RGVx --speed 1000 --connect-under-reset"
4runner = "teleprobe local run --chip STM32WB55RG --elf" 4runner = "teleprobe local run --chip STM32WB55RG --elf"
5 5
6[build] 6[build]
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml
index e41424aad..fbb2d918b 100644
--- a/examples/stm32wb/Cargo.toml
+++ b/examples/stm32wb/Cargo.toml
@@ -33,4 +33,11 @@ required-features = ["ble"]
33 33
34[[bin]] 34[[bin]]
35name = "tl_mbox_mac" 35name = "tl_mbox_mac"
36required-features = ["mac"] \ No newline at end of file 36required-features = ["mac"]
37
38[[bin]]
39name = "eddystone_beacon"
40required-features = ["ble"]
41
42[patch.crates-io]
43stm32wb-hci = { git = "https://github.com/OueslatiGhaith/stm32wb-hci", rev = "9f663be"} \ No newline at end of file
diff --git a/examples/stm32wb/src/bin/eddystone_beacon.rs b/examples/stm32wb/src/bin/eddystone_beacon.rs
new file mode 100644
index 000000000..fdd5be4a2
--- /dev/null
+++ b/examples/stm32wb/src/bin/eddystone_beacon.rs
@@ -0,0 +1,249 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4
5use core::time::Duration;
6
7use defmt::*;
8use embassy_executor::Spawner;
9use embassy_stm32::bind_interrupts;
10use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
11use embassy_stm32_wpan::ble::hci::host::uart::UartHci;
12use embassy_stm32_wpan::ble::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
13use embassy_stm32_wpan::ble::hci::types::AdvertisingType;
14use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gap::{
15 AdvertisingDataType, DiscoverableParameters, GapCommands, Role,
16};
17use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gatt::GattCommands;
18use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel};
19use embassy_stm32_wpan::ble::hci::BdAddr;
20use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp;
21use embassy_stm32_wpan::TlMbox;
22use {defmt_rtt as _, panic_probe as _};
23
24bind_interrupts!(struct Irqs{
25 IPCC_C1_RX => ReceiveInterruptHandler;
26 IPCC_C1_TX => TransmitInterruptHandler;
27});
28
29const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7;
30
31#[embassy_executor::main]
32async fn main(_spawner: Spawner) {
33 /*
34 How to make this work:
35
36 - Obtain a NUCLEO-STM32WB55 from your preferred supplier.
37 - Download and Install STM32CubeProgrammer.
38 - Download stm32wb5x_FUS_fw.bin, stm32wb5x_BLE_Stack_full_fw.bin, and Release_Notes.html from
39 gh:STMicroelectronics/STM32CubeWB@2234d97/Projects/STM32WB_Copro_Wireless_Binaries/STM32WB5x
40 - Open STM32CubeProgrammer
41 - On the right-hand pane, click "firmware upgrade" to upgrade the st-link firmware.
42 - Once complete, click connect to connect to the device.
43 - On the left hand pane, click the RSS signal icon to open "Firmware Upgrade Services".
44 - In the Release_Notes.html, find the memory address that corresponds to your device for the stm32wb5x_FUS_fw.bin file
45 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
46 - Once complete, in the Release_Notes.html, find the memory address that corresponds to your device for the
47 stm32wb5x_BLE_Stack_full_fw.bin file. It should not be the same memory address.
48 - Select that file, the memory address, "verify download", and then "Firmware Upgrade".
49 - Select "Start Wireless Stack".
50 - Disconnect from the device.
51 - In the examples folder for stm32wb, modify the memory.x file to match your target device.
52 - Run this example.
53
54 Note: extended stack versions are not supported at this time. Do not attempt to install a stack with "extended" in the name.
55 */
56
57 let p = embassy_stm32::init(Default::default());
58 info!("Hello World!");
59
60 let config = Config::default();
61 let mut mbox = TlMbox::init(p.IPCC, Irqs, config);
62
63 let sys_event = mbox.sys_subsystem.read().await;
64 info!("sys event: {}", sys_event.payload());
65
66 mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
67
68 info!("resetting BLE...");
69 mbox.ble_subsystem.reset().await;
70 let response = mbox.ble_subsystem.read().await.unwrap();
71 defmt::info!("{}", response);
72
73 info!("config public address...");
74 mbox.ble_subsystem
75 .write_config_data(&ConfigData::public_address(get_bd_addr()).build())
76 .await;
77 let response = mbox.ble_subsystem.read().await.unwrap();
78 defmt::info!("{}", response);
79
80 info!("config random address...");
81 mbox.ble_subsystem
82 .write_config_data(&ConfigData::random_address(get_random_addr()).build())
83 .await;
84 let response = mbox.ble_subsystem.read().await.unwrap();
85 defmt::info!("{}", response);
86
87 info!("config identity root...");
88 mbox.ble_subsystem
89 .write_config_data(&ConfigData::identity_root(&get_irk()).build())
90 .await;
91 let response = mbox.ble_subsystem.read().await.unwrap();
92 defmt::info!("{}", response);
93
94 info!("config encryption root...");
95 mbox.ble_subsystem
96 .write_config_data(&ConfigData::encryption_root(&get_erk()).build())
97 .await;
98 let response = mbox.ble_subsystem.read().await.unwrap();
99 defmt::info!("{}", response);
100
101 info!("config tx power level...");
102 mbox.ble_subsystem.set_tx_power_level(PowerLevel::ZerodBm).await;
103 let response = mbox.ble_subsystem.read().await.unwrap();
104 defmt::info!("{}", response);
105
106 info!("GATT init...");
107 mbox.ble_subsystem.init_gatt().await;
108 let response = mbox.ble_subsystem.read().await.unwrap();
109 defmt::info!("{}", response);
110
111 info!("GAP init...");
112 mbox.ble_subsystem
113 .init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH)
114 .await;
115 let response = mbox.ble_subsystem.read().await.unwrap();
116 defmt::info!("{}", response);
117
118 // info!("set scan response...");
119 // mbox.ble_subsystem.le_set_scan_response_data(&[]).await.unwrap();
120 // let response = mbox.ble_subsystem.read().await.unwrap();
121 // defmt::info!("{}", response);
122
123 info!("set discoverable...");
124 mbox.ble_subsystem
125 .set_discoverable(&DiscoverableParameters {
126 advertising_type: AdvertisingType::NonConnectableUndirected,
127 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))),
128 address_type: OwnAddressType::Public,
129 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan,
130 local_name: None,
131 advertising_data: &[],
132 conn_interval: (None, None),
133 })
134 .await
135 .unwrap();
136
137 let response = mbox.ble_subsystem.read().await;
138 defmt::info!("{}", response);
139
140 // remove some advertisement to decrease the packet size
141 info!("delete tx power ad type...");
142 mbox.ble_subsystem
143 .delete_ad_type(AdvertisingDataType::TxPowerLevel)
144 .await;
145 let response = mbox.ble_subsystem.read().await.unwrap();
146 defmt::info!("{}", response);
147
148 info!("delete conn interval ad type...");
149 mbox.ble_subsystem
150 .delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
151 .await;
152 let response = mbox.ble_subsystem.read().await.unwrap();
153 defmt::info!("{}", response);
154
155 info!("update advertising data...");
156 mbox.ble_subsystem
157 .update_advertising_data(&eddystone_advertising_data())
158 .await
159 .unwrap();
160 let response = mbox.ble_subsystem.read().await.unwrap();
161 defmt::info!("{}", response);
162
163 info!("update advertising data type...");
164 mbox.ble_subsystem
165 .update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
166 .await
167 .unwrap();
168 let response = mbox.ble_subsystem.read().await.unwrap();
169 defmt::info!("{}", response);
170
171 info!("update advertising data flags...");
172 mbox.ble_subsystem
173 .update_advertising_data(&[
174 2,
175 AdvertisingDataType::Flags as u8,
176 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support
177 ])
178 .await
179 .unwrap();
180 let response = mbox.ble_subsystem.read().await.unwrap();
181 defmt::info!("{}", response);
182
183 cortex_m::asm::wfi();
184}
185
186fn get_bd_addr() -> BdAddr {
187 let mut bytes = [0u8; 6];
188
189 let lhci_info = LhciC1DeviceInformationCcrp::new();
190 bytes[0] = (lhci_info.uid64 & 0xff) as u8;
191 bytes[1] = ((lhci_info.uid64 >> 8) & 0xff) as u8;
192 bytes[2] = ((lhci_info.uid64 >> 16) & 0xff) as u8;
193 bytes[3] = lhci_info.device_type_id;
194 bytes[4] = (lhci_info.st_company_id & 0xff) as u8;
195 bytes[5] = (lhci_info.st_company_id >> 8 & 0xff) as u8;
196
197 BdAddr(bytes)
198}
199
200fn get_random_addr() -> BdAddr {
201 let mut bytes = [0u8; 6];
202
203 let lhci_info = LhciC1DeviceInformationCcrp::new();
204 bytes[0] = (lhci_info.uid64 & 0xff) as u8;
205 bytes[1] = ((lhci_info.uid64 >> 8) & 0xff) as u8;
206 bytes[2] = ((lhci_info.uid64 >> 16) & 0xff) as u8;
207 bytes[3] = 0;
208 bytes[4] = 0x6E;
209 bytes[5] = 0xED;
210
211 BdAddr(bytes)
212}
213
214const BLE_CFG_IRK: [u8; 16] = [
215 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
216];
217const BLE_CFG_ERK: [u8; 16] = [
218 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21,
219];
220
221fn get_irk() -> EncryptionKey {
222 EncryptionKey(BLE_CFG_IRK)
223}
224
225fn get_erk() -> EncryptionKey {
226 EncryptionKey(BLE_CFG_ERK)
227}
228
229fn eddystone_advertising_data() -> [u8; 24] {
230 const EDDYSTONE_URL: &[u8] = b"www.rust-lang.com";
231
232 let mut service_data = [0u8; 24];
233 let url_len = EDDYSTONE_URL.len();
234
235 service_data[0] = 6 + url_len as u8;
236 service_data[1] = AdvertisingDataType::ServiceData as u8;
237
238 // 16-bit eddystone uuid
239 service_data[2] = 0xaa;
240 service_data[3] = 0xFE;
241
242 service_data[4] = 0x10; // URL frame type
243 service_data[5] = 22_i8 as u8; // calibrated TX power at 0m
244 service_data[6] = 0x03; // eddystone url prefix = https
245
246 service_data[7..(7 + url_len)].copy_from_slice(EDDYSTONE_URL);
247
248 service_data
249}
diff --git a/examples/stm32wb/src/bin/tl_mbox_ble.rs b/examples/stm32wb/src/bin/tl_mbox_ble.rs
index 439bd01ac..a511e89aa 100644
--- a/examples/stm32wb/src/bin/tl_mbox_ble.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_ble.rs
@@ -52,10 +52,10 @@ async fn main(_spawner: Spawner) {
52 mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; 52 mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
53 53
54 info!("starting ble..."); 54 info!("starting ble...");
55 mbox.ble_subsystem.write(0x0c, &[]).await; 55 mbox.ble_subsystem.tl_write(0x0c, &[]).await;
56 56
57 info!("waiting for ble..."); 57 info!("waiting for ble...");
58 let ble_event = mbox.ble_subsystem.read().await; 58 let ble_event = mbox.ble_subsystem.tl_read().await;
59 59
60 info!("ble event: {}", ble_event.payload()); 60 info!("ble event: {}", ble_event.payload());
61 61
diff --git a/examples/stm32wb/src/bin/tl_mbox_mac.rs b/examples/stm32wb/src/bin/tl_mbox_mac.rs
index a42939bbd..afd319a41 100644
--- a/examples/stm32wb/src/bin/tl_mbox_mac.rs
+++ b/examples/stm32wb/src/bin/tl_mbox_mac.rs
@@ -52,10 +52,10 @@ async fn main(_spawner: Spawner) {
52 mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; 52 mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
53 // 53 //
54 // info!("starting ble..."); 54 // info!("starting ble...");
55 // mbox.ble_subsystem.write(0x0c, &[]).await; 55 // mbox.ble_subsystem.t_write(0x0c, &[]).await;
56 // 56 //
57 // info!("waiting for ble..."); 57 // info!("waiting for ble...");
58 // let ble_event = mbox.ble_subsystem.read().await; 58 // let ble_event = mbox.ble_subsystem.tl_read().await;
59 // 59 //
60 // info!("ble event: {}", ble_event.payload()); 60 // info!("ble event: {}", ble_event.payload());
61 61
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index fe646927a..c2422f7bc 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -46,6 +46,9 @@ rand_chacha = { version = "0.3", default-features = false }
46 46
47chrono = { version = "^0.4", default-features = false, optional = true} 47chrono = { version = "^0.4", default-features = false, optional = true}
48 48
49[patch.crates-io]
50stm32wb-hci = { git = "https://github.com/OueslatiGhaith/stm32wb-hci", rev = "9f663be"}
51
49# BEGIN TESTS 52# BEGIN TESTS
50# Generated by gen_test.py. DO NOT EDIT. 53# Generated by gen_test.py. DO NOT EDIT.
51[[bin]] 54[[bin]]
diff --git a/tests/stm32/src/bin/tl_mbox.rs b/tests/stm32/src/bin/tl_mbox.rs
index f47a89b6f..76c736a5b 100644
--- a/tests/stm32/src/bin/tl_mbox.rs
+++ b/tests/stm32/src/bin/tl_mbox.rs
@@ -6,43 +6,49 @@
6#[path = "../common.rs"] 6#[path = "../common.rs"]
7mod common; 7mod common;
8 8
9use core::mem; 9use core::time::Duration;
10 10
11use common::*; 11use common::*;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_futures::poll_once;
14use embassy_stm32::bind_interrupts; 13use embassy_stm32::bind_interrupts;
15use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 14use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
15use embassy_stm32_wpan::ble::hci::host::uart::UartHci;
16use embassy_stm32_wpan::ble::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType};
17use embassy_stm32_wpan::ble::hci::types::AdvertisingType;
18use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gap::{
19 AdvertisingDataType, DiscoverableParameters, GapCommands, Role,
20};
21use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::gatt::GattCommands;
22use embassy_stm32_wpan::ble::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel};
23use embassy_stm32_wpan::ble::hci::BdAddr;
24use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp;
16use embassy_stm32_wpan::{mm, TlMbox}; 25use embassy_stm32_wpan::{mm, TlMbox};
17use embassy_time::{Duration, Timer}; 26use {defmt_rtt as _, panic_probe as _};
18 27
19bind_interrupts!(struct Irqs{ 28bind_interrupts!(struct Irqs{
20 IPCC_C1_RX => ReceiveInterruptHandler; 29 IPCC_C1_RX => ReceiveInterruptHandler;
21 IPCC_C1_TX => TransmitInterruptHandler; 30 IPCC_C1_TX => TransmitInterruptHandler;
22}); 31});
23 32
33const BLE_GAP_DEVICE_NAME_LENGTH: u8 = 7;
34
24#[embassy_executor::task] 35#[embassy_executor::task]
25async fn run_mm_queue(memory_manager: mm::MemoryManager) { 36async fn run_mm_queue(memory_manager: mm::MemoryManager) {
26 memory_manager.run_queue().await; 37 memory_manager.run_queue().await;
27} 38}
28 39
29#[embassy_executor::main] 40#[embassy_executor::main]
30async fn main(spawner: Spawner) { 41async fn main(_spawner: Spawner) {
31 let p = embassy_stm32::init(config()); 42 let p = embassy_stm32::init(config());
32 info!("Hello World!"); 43 info!("Hello World!");
33 44
34 let config = Config::default(); 45 let config = Config::default();
35 let mbox = TlMbox::init(p.IPCC, Irqs, config); 46 let mut mbox = TlMbox::init(p.IPCC, Irqs, config);
36
37 spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
38
39 let ready_event = mbox.sys_subsystem.read().await;
40 let _ = poll_once(mbox.sys_subsystem.read()); // clear rx not
41 47
42 info!("sys event {:x} : {:x}", ready_event.stub().kind, ready_event.payload()); 48 // spawner.spawn(run_mm_queue(mbox.mm_subsystem)).unwrap();
43 49
44 // test memory manager 50 let sys_event = mbox.sys_subsystem.read().await;
45 mem::drop(ready_event); 51 info!("sys event: {}", sys_event.payload());
46 52
47 let fw_info = mbox.sys_subsystem.wireless_fw_info().unwrap(); 53 let fw_info = mbox.sys_subsystem.wireless_fw_info().unwrap();
48 let version_major = fw_info.version_major(); 54 let version_major = fw_info.version_major();
@@ -57,19 +63,188 @@ async fn main(spawner: Spawner) {
57 version_major, version_minor, subversion, sram2a_size, sram2b_size 63 version_major, version_minor, subversion, sram2a_size, sram2b_size
58 ); 64 );
59 65
60 Timer::after(Duration::from_millis(50)).await; 66 mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await;
67
68 info!("resetting BLE...");
69 mbox.ble_subsystem.reset().await;
70 let response = mbox.ble_subsystem.read().await.unwrap();
71 info!("{}", response);
72
73 info!("config public address...");
74 mbox.ble_subsystem
75 .write_config_data(&ConfigData::public_address(get_bd_addr()).build())
76 .await;
77 let response = mbox.ble_subsystem.read().await.unwrap();
78 info!("{}", response);
79
80 info!("config random address...");
81 mbox.ble_subsystem
82 .write_config_data(&ConfigData::random_address(get_random_addr()).build())
83 .await;
84 let response = mbox.ble_subsystem.read().await.unwrap();
85 info!("{}", response);
86
87 info!("config identity root...");
88 mbox.ble_subsystem
89 .write_config_data(&ConfigData::identity_root(&get_irk()).build())
90 .await;
91 let response = mbox.ble_subsystem.read().await.unwrap();
92 info!("{}", response);
93
94 info!("config encryption root...");
95 mbox.ble_subsystem
96 .write_config_data(&ConfigData::encryption_root(&get_erk()).build())
97 .await;
98 let response = mbox.ble_subsystem.read().await.unwrap();
99 info!("{}", response);
100
101 info!("config tx power level...");
102 mbox.ble_subsystem.set_tx_power_level(PowerLevel::ZerodBm).await;
103 let response = mbox.ble_subsystem.read().await.unwrap();
104 info!("{}", response);
105
106 info!("GATT init...");
107 mbox.ble_subsystem.init_gatt().await;
108 let response = mbox.ble_subsystem.read().await.unwrap();
109 info!("{}", response);
110
111 info!("GAP init...");
112 mbox.ble_subsystem
113 .init_gap(Role::PERIPHERAL, false, BLE_GAP_DEVICE_NAME_LENGTH)
114 .await;
115 let response = mbox.ble_subsystem.read().await.unwrap();
116 info!("{}", response);
117
118 // info!("set scan response...");
119 // mbox.ble_subsystem.le_set_scan_response_data(&[]).await.unwrap();
120 // let response = mbox.ble_subsystem.read().await.unwrap();
121 // info!("{}", response);
122
123 info!("set discoverable...");
124 mbox.ble_subsystem
125 .set_discoverable(&DiscoverableParameters {
126 advertising_type: AdvertisingType::NonConnectableUndirected,
127 advertising_interval: Some((Duration::from_millis(250), Duration::from_millis(250))),
128 address_type: OwnAddressType::Public,
129 filter_policy: AdvertisingFilterPolicy::AllowConnectionAndScan,
130 local_name: None,
131 advertising_data: &[],
132 conn_interval: (None, None),
133 })
134 .await
135 .unwrap();
136
137 let response = mbox.ble_subsystem.read().await;
138 info!("{}", response);
139
140 // remove some advertisement to decrease the packet size
141 info!("delete tx power ad type...");
142 mbox.ble_subsystem
143 .delete_ad_type(AdvertisingDataType::TxPowerLevel)
144 .await;
145 let response = mbox.ble_subsystem.read().await.unwrap();
146 info!("{}", response);
147
148 info!("delete conn interval ad type...");
149 mbox.ble_subsystem
150 .delete_ad_type(AdvertisingDataType::PeripheralConnectionInterval)
151 .await;
152 let response = mbox.ble_subsystem.read().await.unwrap();
153 info!("{}", response);
154
155 info!("update advertising data...");
156 mbox.ble_subsystem
157 .update_advertising_data(&eddystone_advertising_data())
158 .await
159 .unwrap();
160 let response = mbox.ble_subsystem.read().await.unwrap();
161 info!("{}", response);
162
163 info!("update advertising data type...");
164 mbox.ble_subsystem
165 .update_advertising_data(&[3, AdvertisingDataType::UuidCompleteList16 as u8, 0xaa, 0xfe])
166 .await
167 .unwrap();
168 let response = mbox.ble_subsystem.read().await.unwrap();
169 info!("{}", response);
170
171 info!("update advertising data flags...");
172 mbox.ble_subsystem
173 .update_advertising_data(&[
174 2,
175 AdvertisingDataType::Flags as u8,
176 (0x02 | 0x04) as u8, // BLE general discoverable, without BR/EDR support
177 ])
178 .await
179 .unwrap();
180 let response = mbox.ble_subsystem.read().await.unwrap();
181 info!("{}", response);
182
183 info!("Test OK");
184 cortex_m::asm::bkpt();
185}
186
187fn get_bd_addr() -> BdAddr {
188 let mut bytes = [0u8; 6];
61 189
62 let result = mbox.sys_subsystem.shci_c2_ble_init(Default::default()).await; 190 let lhci_info = LhciC1DeviceInformationCcrp::new();
63 info!("subsystem initialization: {}", result); 191 bytes[0] = (lhci_info.uid64 & 0xff) as u8;
192 bytes[1] = ((lhci_info.uid64 >> 8) & 0xff) as u8;
193 bytes[2] = ((lhci_info.uid64 >> 16) & 0xff) as u8;
194 bytes[3] = lhci_info.device_type_id;
195 bytes[4] = (lhci_info.st_company_id & 0xff) as u8;
196 bytes[5] = (lhci_info.st_company_id >> 8 & 0xff) as u8;
64 197
65 info!("starting ble..."); 198 BdAddr(bytes)
66 mbox.ble_subsystem.write(0x0c, &[]).await; 199}
67 200
68 info!("waiting for ble..."); 201fn get_random_addr() -> BdAddr {
69 let ble_event = mbox.ble_subsystem.read().await; 202 let mut bytes = [0u8; 6];
70 203
71 info!("ble event {:x} : {:x}", ble_event.stub().kind, ble_event.payload()); 204 let lhci_info = LhciC1DeviceInformationCcrp::new();
205 bytes[0] = (lhci_info.uid64 & 0xff) as u8;
206 bytes[1] = ((lhci_info.uid64 >> 8) & 0xff) as u8;
207 bytes[2] = ((lhci_info.uid64 >> 16) & 0xff) as u8;
208 bytes[3] = 0;
209 bytes[4] = 0x6E;
210 bytes[5] = 0xED;
72 211
73 info!("Test OK"); 212 BdAddr(bytes)
74 cortex_m::asm::bkpt(); 213}
214
215const BLE_CFG_IRK: [u8; 16] = [
216 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
217];
218const BLE_CFG_ERK: [u8; 16] = [
219 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21,
220];
221
222fn get_irk() -> EncryptionKey {
223 EncryptionKey(BLE_CFG_IRK)
224}
225
226fn get_erk() -> EncryptionKey {
227 EncryptionKey(BLE_CFG_ERK)
228}
229
230fn eddystone_advertising_data() -> [u8; 24] {
231 const EDDYSTONE_URL: &[u8] = b"www.rust-lang.com";
232
233 let mut service_data = [0u8; 24];
234 let url_len = EDDYSTONE_URL.len();
235
236 service_data[0] = 6 + url_len as u8;
237 service_data[1] = AdvertisingDataType::ServiceData as u8;
238
239 // 16-bit eddystone uuid
240 service_data[2] = 0xaa;
241 service_data[3] = 0xFE;
242
243 service_data[4] = 0x10; // URL frame type
244 service_data[5] = 22_i8 as u8; // calibrated TX power at 0m
245 service_data[6] = 0x03; // eddystone url prefix = https
246
247 service_data[7..(7 + url_len)].copy_from_slice(EDDYSTONE_URL);
248
249 service_data
75} 250}