diff options
Diffstat (limited to 'embassy-stm32-wpan/src/sub')
| -rw-r--r-- | embassy-stm32-wpan/src/sub/ble.rs | 10 | ||||
| -rw-r--r-- | embassy-stm32-wpan/src/sub/sys.rs | 10 |
2 files changed, 20 insertions, 0 deletions
diff --git a/embassy-stm32-wpan/src/sub/ble.rs b/embassy-stm32-wpan/src/sub/ble.rs index c5f2334f4..a47c6a699 100644 --- a/embassy-stm32-wpan/src/sub/ble.rs +++ b/embassy-stm32-wpan/src/sub/ble.rs | |||
| @@ -11,11 +11,20 @@ use crate::tables::{BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA | |||
| 11 | use crate::unsafe_linked_list::LinkedListNode; | 11 | use crate::unsafe_linked_list::LinkedListNode; |
| 12 | use crate::{channels, evt}; | 12 | use crate::{channels, evt}; |
| 13 | 13 | ||
| 14 | /// A guard that, once constructed, may be used to send BLE commands to CPU2. | ||
| 15 | /// | ||
| 16 | /// It is the responsibility of the caller to ensure that they have awaited an event via | ||
| 17 | /// [crate::sub::Sys::read] before sending any of these commands, and to call | ||
| 18 | /// [crate::sub::Sys::shci_c2_ble_init] and await the HCI_COMMAND_COMPLETE_EVENT before sending any | ||
| 19 | /// other commands. | ||
| 14 | pub struct Ble { | 20 | pub struct Ble { |
| 15 | _private: (), | 21 | _private: (), |
| 16 | } | 22 | } |
| 17 | 23 | ||
| 18 | impl Ble { | 24 | impl Ble { |
| 25 | /// Constructs a guard that allows for BLE commands to be sent to CPU2. | ||
| 26 | /// | ||
| 27 | /// This takes the place of `TL_BLE_Init`, completing that step as laid out in AN5289, Fig 66. | ||
| 19 | pub(crate) fn new() -> Self { | 28 | pub(crate) fn new() -> Self { |
| 20 | unsafe { | 29 | unsafe { |
| 21 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | 30 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |
| @@ -30,6 +39,7 @@ impl Ble { | |||
| 30 | 39 | ||
| 31 | Self { _private: () } | 40 | Self { _private: () } |
| 32 | } | 41 | } |
| 42 | |||
| 33 | /// `HW_IPCC_BLE_EvtNot` | 43 | /// `HW_IPCC_BLE_EvtNot` |
| 34 | pub async fn tl_read(&self) -> EvtBox<Self> { | 44 | pub async fn tl_read(&self) -> EvtBox<Self> { |
| 35 | Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { | 45 | Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { |
diff --git a/embassy-stm32-wpan/src/sub/sys.rs b/embassy-stm32-wpan/src/sub/sys.rs index bd2ea3f74..fcc2c651e 100644 --- a/embassy-stm32-wpan/src/sub/sys.rs +++ b/embassy-stm32-wpan/src/sub/sys.rs | |||
| @@ -10,6 +10,7 @@ use crate::tables::{SysTable, WirelessFwInfoTable}; | |||
| 10 | use crate::unsafe_linked_list::LinkedListNode; | 10 | use crate::unsafe_linked_list::LinkedListNode; |
| 11 | use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; | 11 | use crate::{channels, Ipcc, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; |
| 12 | 12 | ||
| 13 | /// A guard that, once constructed, allows for sys commands to be sent to CPU2. | ||
| 13 | pub struct Sys { | 14 | pub struct Sys { |
| 14 | _private: (), | 15 | _private: (), |
| 15 | } | 16 | } |
| @@ -86,12 +87,21 @@ impl Sys { | |||
| 86 | self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await | 87 | self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await |
| 87 | } | 88 | } |
| 88 | 89 | ||
| 90 | /// Send a request to CPU2 to initialise the BLE stack. | ||
| 91 | /// | ||
| 92 | /// This must be called before any BLE commands are sent via the BLE channel (according to | ||
| 93 | /// AN5289, Figures 65 and 66). It should only be called after CPU2 sends a system event, via | ||
| 94 | /// `HW_IPCC_SYS_EvtNot`, aka `IoBusCallBackUserEvt` (as detailed in Figure 65), aka [read]. | ||
| 89 | #[cfg(feature = "ble")] | 95 | #[cfg(feature = "ble")] |
| 90 | pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> { | 96 | pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> { |
| 91 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await | 97 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await |
| 92 | } | 98 | } |
| 93 | 99 | ||
| 94 | /// `HW_IPCC_SYS_EvtNot` | 100 | /// `HW_IPCC_SYS_EvtNot` |
| 101 | /// | ||
| 102 | /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, | ||
| 103 | /// as the embassy implementation avoids the need to call C public bindings, and instead | ||
| 104 | /// handles the event channels directly. | ||
| 95 | pub async fn read(&self) -> EvtBox<mm::MemoryManager> { | 105 | pub async fn read(&self) -> EvtBox<mm::MemoryManager> { |
| 96 | Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { | 106 | Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { |
| 97 | if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { | 107 | if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { |
