aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src
diff options
context:
space:
mode:
authorgoueslati <[email protected]>2023-06-22 15:21:14 +0100
committergoueslati <[email protected]>2023-06-22 15:21:14 +0100
commitcd4f8f13a2c533f4e752c2e446661a6d86b19fe6 (patch)
tree8bd29c956fa5a57a5ec6fbf7ade3799b9370b8f3 /embassy-stm32-wpan/src
parent1f2be2dac5eeed739d2866b9b63ca06fdd84c276 (diff)
wpan: add BLE HCI
Diffstat (limited to 'embassy-stm32-wpan/src')
-rw-r--r--embassy-stm32-wpan/src/ble.rs19
-rw-r--r--embassy-stm32-wpan/src/cmd.rs2
-rw-r--r--embassy-stm32-wpan/src/evt.rs23
-rw-r--r--embassy-stm32-wpan/src/lhci.rs111
-rw-r--r--embassy-stm32-wpan/src/lib.rs2
5 files changed, 154 insertions, 3 deletions
diff --git a/embassy-stm32-wpan/src/ble.rs b/embassy-stm32-wpan/src/ble.rs
index 60e0cbdf8..297ee4cdf 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,17 @@ impl Ble {
61 .await; 62 .await;
62 } 63 }
63} 64}
65
66pub extern crate bluetooth_hci_async 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(&self) -> &[u8] {
74 let evt_box = self.tl_read().await;
75
76 evt_box.serial()
77 }
78}
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..7a4738b7a 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
@@ -105,6 +106,14 @@ impl EvtBox {
105 Self { ptr } 106 Self { ptr }
106 } 107 }
107 108
109 pub fn evt<'a>(&self) -> &'a [u8] {
110 unsafe {
111 let evt_packet = &(*self.ptr);
112
113 core::slice::from_raw_parts(evt_packet as *const _ as *const u8, core::mem::size_of::<EvtPacket>())
114 }
115 }
116
108 /// Returns information about the event 117 /// Returns information about the event
109 pub fn stub(&self) -> EvtStub { 118 pub fn stub(&self) -> EvtStub {
110 unsafe { 119 unsafe {
@@ -124,6 +133,20 @@ impl EvtBox {
124 slice::from_raw_parts(p_payload, payload_len as usize) 133 slice::from_raw_parts(p_payload, payload_len as usize)
125 } 134 }
126 } 135 }
136
137 /// writes an underlying [`EvtPacket`] into the provided buffer.
138 /// Returns the number of bytes that were written.
139 /// Returns an error if event kind is unknown or if provided buffer size is not enough.
140 pub fn serial<'a>(&self) -> &'a [u8] {
141 unsafe {
142 let evt_serial: *const EvtSerial = &(*self.ptr).evt_serial;
143 let evt_serial_buf: *const u8 = evt_serial.cast();
144
145 let len = (*evt_serial).evt.payload_len as usize + TL_EVT_HEADER_SIZE;
146
147 slice::from_raw_parts(evt_serial_buf, len)
148 }
149 }
127} 150}
128 151
129impl Drop for EvtBox { 152impl 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;