diff options
Diffstat (limited to 'embassy-stm32-wpan/src/sub/ble.rs')
| -rw-r--r-- | embassy-stm32-wpan/src/sub/ble.rs | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/embassy-stm32-wpan/src/sub/ble.rs b/embassy-stm32-wpan/src/sub/ble.rs index cd69a0479..d5ed2ca28 100644 --- a/embassy-stm32-wpan/src/sub/ble.rs +++ b/embassy-stm32-wpan/src/sub/ble.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::ptr; | 1 | use core::ptr; |
| 2 | 2 | ||
| 3 | use embassy_stm32::ipcc::Ipcc; | 3 | use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel}; |
| 4 | use hci::Opcode; | 4 | use hci::Opcode; |
| 5 | 5 | ||
| 6 | use crate::cmd::CmdPacket; | 6 | use crate::cmd::CmdPacket; |
| @@ -9,7 +9,7 @@ use crate::evt::{EvtBox, EvtPacket, EvtStub}; | |||
| 9 | use crate::sub::mm; | 9 | use crate::sub::mm; |
| 10 | use crate::tables::{BLE_CMD_BUFFER, BleTable, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; | 10 | use crate::tables::{BLE_CMD_BUFFER, BleTable, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE}; |
| 11 | use crate::unsafe_linked_list::LinkedListNode; | 11 | use crate::unsafe_linked_list::LinkedListNode; |
| 12 | use crate::{channels, evt}; | 12 | use crate::evt; |
| 13 | 13 | ||
| 14 | /// A guard that, once constructed, may be used to send BLE commands to CPU2. | 14 | /// A guard that, once constructed, may be used to send BLE commands to CPU2. |
| 15 | /// | 15 | /// |
| @@ -36,15 +36,21 @@ use crate::{channels, evt}; | |||
| 36 | /// # mbox.ble_subsystem.reset().await; | 36 | /// # mbox.ble_subsystem.reset().await; |
| 37 | /// # let _reset_response = mbox.ble_subsystem.read().await; | 37 | /// # let _reset_response = mbox.ble_subsystem.read().await; |
| 38 | /// ``` | 38 | /// ``` |
| 39 | pub struct Ble { | 39 | pub struct Ble<'a> { |
| 40 | _private: (), | 40 | hw_ipcc_ble_cmd_channel: IpccTxChannel<'a>, |
| 41 | ipcc_ble_event_channel: IpccRxChannel<'a>, | ||
| 42 | ipcc_hci_acl_data_channel: IpccTxChannel<'a>, | ||
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | impl Ble { | 45 | impl<'a> Ble<'a> { |
| 44 | /// Constructs a guard that allows for BLE commands to be sent to CPU2. | 46 | /// Constructs a guard that allows for BLE commands to be sent to CPU2. |
| 45 | /// | 47 | /// |
| 46 | /// This takes the place of `TL_BLE_Init`, completing that step as laid out in AN5289, Fig 66. | 48 | /// This takes the place of `TL_BLE_Init`, completing that step as laid out in AN5289, Fig 66. |
| 47 | pub(crate) fn new() -> Self { | 49 | pub(crate) fn new( |
| 50 | hw_ipcc_ble_cmd_channel: IpccTxChannel<'a>, | ||
| 51 | ipcc_ble_event_channel: IpccRxChannel<'a>, | ||
| 52 | ipcc_hci_acl_data_channel: IpccTxChannel<'a>, | ||
| 53 | ) -> Self { | ||
| 48 | unsafe { | 54 | unsafe { |
| 49 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); | 55 | LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); |
| 50 | 56 | ||
| @@ -56,44 +62,51 @@ impl Ble { | |||
| 56 | }); | 62 | }); |
| 57 | } | 63 | } |
| 58 | 64 | ||
| 59 | Self { _private: () } | 65 | Self { |
| 66 | hw_ipcc_ble_cmd_channel, | ||
| 67 | ipcc_ble_event_channel, | ||
| 68 | ipcc_hci_acl_data_channel, | ||
| 69 | } | ||
| 60 | } | 70 | } |
| 61 | 71 | ||
| 62 | /// `HW_IPCC_BLE_EvtNot` | 72 | /// `HW_IPCC_BLE_EvtNot` |
| 63 | pub async fn tl_read(&self) -> EvtBox<Self> { | 73 | pub async fn tl_read(&mut self) -> EvtBox<Self> { |
| 64 | Ipcc::receive(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, || unsafe { | 74 | self.ipcc_ble_event_channel |
| 65 | if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { | 75 | .receive(|| unsafe { |
| 66 | Some(EvtBox::new(node_ptr.cast())) | 76 | if let Some(node_ptr) = LinkedListNode::remove_head(EVT_QUEUE.as_mut_ptr()) { |
| 67 | } else { | 77 | Some(EvtBox::new(node_ptr.cast())) |
| 68 | None | 78 | } else { |
| 69 | } | 79 | None |
| 70 | }) | 80 | } |
| 71 | .await | 81 | }) |
| 82 | .await | ||
| 72 | } | 83 | } |
| 73 | 84 | ||
| 74 | /// `TL_BLE_SendCmd` | 85 | /// `TL_BLE_SendCmd` |
| 75 | pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { | 86 | pub async fn tl_write(&mut self, opcode: u16, payload: &[u8]) { |
| 76 | Ipcc::send(channels::cpu1::IPCC_BLE_CMD_CHANNEL, || unsafe { | 87 | self.hw_ipcc_ble_cmd_channel |
| 77 | CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); | 88 | .send(|| unsafe { |
| 78 | }) | 89 | CmdPacket::write_into(BLE_CMD_BUFFER.as_mut_ptr(), TlPacketType::BleCmd, opcode, payload); |
| 79 | .await; | 90 | }) |
| 91 | .await; | ||
| 80 | } | 92 | } |
| 81 | 93 | ||
| 82 | /// `TL_BLE_SendAclData` | 94 | /// `TL_BLE_SendAclData` |
| 83 | pub async fn acl_write(&self, handle: u16, payload: &[u8]) { | 95 | pub async fn acl_write(&mut self, handle: u16, payload: &[u8]) { |
| 84 | Ipcc::send(channels::cpu1::IPCC_HCI_ACL_DATA_CHANNEL, || unsafe { | 96 | self.ipcc_hci_acl_data_channel |
| 85 | CmdPacket::write_into( | 97 | .send(|| unsafe { |
| 86 | HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, | 98 | CmdPacket::write_into( |
| 87 | TlPacketType::AclData, | 99 | HCI_ACL_DATA_BUFFER.as_mut_ptr() as *mut _, |
| 88 | handle, | 100 | TlPacketType::AclData, |
| 89 | payload, | 101 | handle, |
| 90 | ); | 102 | payload, |
| 91 | }) | 103 | ); |
| 92 | .await; | 104 | }) |
| 105 | .await; | ||
| 93 | } | 106 | } |
| 94 | } | 107 | } |
| 95 | 108 | ||
| 96 | impl evt::MemoryManager for Ble { | 109 | impl<'a> evt::MemoryManager for Ble<'a> { |
| 97 | /// SAFETY: passing a pointer to something other than a managed event packet is UB | 110 | /// SAFETY: passing a pointer to something other than a managed event packet is UB |
| 98 | unsafe fn drop_event_packet(evt: *mut EvtPacket) { | 111 | unsafe fn drop_event_packet(evt: *mut EvtPacket) { |
| 99 | let stub = unsafe { | 112 | let stub = unsafe { |
| @@ -110,13 +123,17 @@ impl evt::MemoryManager for Ble { | |||
| 110 | 123 | ||
| 111 | pub extern crate stm32wb_hci as hci; | 124 | pub extern crate stm32wb_hci as hci; |
| 112 | 125 | ||
| 113 | impl hci::Controller for Ble { | 126 | impl<'a> hci::Controller for Ble<'a> { |
| 114 | async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) { | 127 | async fn controller_write(&mut self, opcode: Opcode, payload: &[u8]) { |
| 115 | self.tl_write(opcode.0, payload).await; | 128 | self.tl_write(opcode.0, payload).await; |
| 116 | } | 129 | } |
| 117 | 130 | ||
| 131 | #[allow(invalid_reference_casting)] | ||
| 118 | async fn controller_read_into(&self, buf: &mut [u8]) { | 132 | async fn controller_read_into(&self, buf: &mut [u8]) { |
| 119 | let evt_box = self.tl_read().await; | 133 | // A complete hack since I cannot update the trait |
| 134 | let s = unsafe { &mut *(self as *const _ as *mut Ble) }; | ||
| 135 | |||
| 136 | let evt_box = s.tl_read().await; | ||
| 120 | let evt_serial = evt_box.serial(); | 137 | let evt_serial = evt_box.serial(); |
| 121 | 138 | ||
| 122 | buf[..evt_serial.len()].copy_from_slice(evt_serial); | 139 | buf[..evt_serial.len()].copy_from_slice(evt_serial); |
