diff options
Diffstat (limited to 'embassy-stm32-wpan/src/sub/sys.rs')
| -rw-r--r-- | embassy-stm32-wpan/src/sub/sys.rs | 82 |
1 files changed, 39 insertions, 43 deletions
diff --git a/embassy-stm32-wpan/src/sub/sys.rs b/embassy-stm32-wpan/src/sub/sys.rs index 8a3382f86..dffe9942c 100644 --- a/embassy-stm32-wpan/src/sub/sys.rs +++ b/embassy-stm32-wpan/src/sub/sys.rs | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | use core::ptr; | 1 | use core::ptr; |
| 2 | 2 | ||
| 3 | use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel}; | ||
| 4 | |||
| 3 | use crate::cmd::CmdPacket; | 5 | use crate::cmd::CmdPacket; |
| 4 | use crate::consts::TlPacketType; | 6 | use crate::consts::TlPacketType; |
| 5 | use crate::evt::{CcEvt, EvtBox, EvtPacket}; | 7 | use crate::evt::{CcEvt, EvtBox, EvtPacket}; |
| @@ -8,16 +10,20 @@ use crate::shci::{SchiCommandStatus, ShciBleInitCmdParam, ShciOpcode}; | |||
| 8 | use crate::sub::mm; | 10 | use crate::sub::mm; |
| 9 | use crate::tables::{SysTable, WirelessFwInfoTable}; | 11 | use crate::tables::{SysTable, WirelessFwInfoTable}; |
| 10 | use crate::unsafe_linked_list::LinkedListNode; | 12 | use crate::unsafe_linked_list::LinkedListNode; |
| 11 | use crate::{Ipcc, SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE, channels}; | 13 | use crate::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; |
| 12 | 14 | ||
| 13 | /// A guard that, once constructed, allows for sys commands to be sent to CPU2. | 15 | /// A guard that, once constructed, allows for sys commands to be sent to CPU2. |
| 14 | pub struct Sys { | 16 | pub struct Sys<'a> { |
| 15 | _private: (), | 17 | ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>, |
| 18 | ipcc_system_event_channel: IpccRxChannel<'a>, | ||
| 16 | } | 19 | } |
| 17 | 20 | ||
| 18 | impl Sys { | 21 | impl<'a> Sys<'a> { |
| 19 | /// TL_Sys_Init | 22 | /// TL_Sys_Init |
| 20 | pub(crate) fn new() -> Self { | 23 | pub(crate) fn new( |
| 24 | ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>, | ||
| 25 | ipcc_system_event_channel: IpccRxChannel<'a>, | ||
| 26 | ) -> Self { | ||
| 21 | unsafe { | 27 | unsafe { |
| 22 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); | 28 | LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); |
| 23 | 29 | ||
| @@ -27,7 +33,10 @@ impl Sys { | |||
| 27 | }); | 33 | }); |
| 28 | } | 34 | } |
| 29 | 35 | ||
| 30 | Self { _private: () } | 36 | Self { |
| 37 | ipcc_system_cmd_rsp_channel, | ||
| 38 | ipcc_system_event_channel, | ||
| 39 | } | ||
| 31 | } | 40 | } |
| 32 | 41 | ||
| 33 | /// Returns CPU2 wireless firmware information (if present). | 42 | /// Returns CPU2 wireless firmware information (if present). |
| @@ -38,17 +47,22 @@ impl Sys { | |||
| 38 | if info.version != 0 { Some(info) } else { None } | 47 | if info.version != 0 { Some(info) } else { None } |
| 39 | } | 48 | } |
| 40 | 49 | ||
| 41 | pub async fn write(&self, opcode: ShciOpcode, payload: &[u8]) { | 50 | pub async fn write(&mut self, opcode: ShciOpcode, payload: &[u8]) { |
| 42 | Ipcc::send(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, || unsafe { | 51 | self.ipcc_system_cmd_rsp_channel |
| 43 | CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); | 52 | .send(|| unsafe { |
| 44 | }) | 53 | CmdPacket::write_into(SYS_CMD_BUF.as_mut_ptr(), TlPacketType::SysCmd, opcode as u16, payload); |
| 45 | .await; | 54 | }) |
| 55 | .await; | ||
| 46 | } | 56 | } |
| 47 | 57 | ||
| 48 | /// `HW_IPCC_SYS_CmdEvtNot` | 58 | /// `HW_IPCC_SYS_CmdEvtNot` |
| 49 | pub async fn write_and_get_response(&self, opcode: ShciOpcode, payload: &[u8]) -> Result<SchiCommandStatus, ()> { | 59 | pub async fn write_and_get_response( |
| 60 | &mut self, | ||
| 61 | opcode: ShciOpcode, | ||
| 62 | payload: &[u8], | ||
| 63 | ) -> Result<SchiCommandStatus, ()> { | ||
| 50 | self.write(opcode, payload).await; | 64 | self.write(opcode, payload).await; |
| 51 | Ipcc::flush(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL).await; | 65 | self.ipcc_system_cmd_rsp_channel.flush().await; |
| 52 | 66 | ||
| 53 | unsafe { | 67 | unsafe { |
| 54 | let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; | 68 | let p_event_packet = SYS_CMD_BUF.as_ptr() as *const EvtPacket; |
| @@ -60,26 +74,7 @@ impl Sys { | |||
| 60 | } | 74 | } |
| 61 | 75 | ||
| 62 | #[cfg(feature = "mac")] | 76 | #[cfg(feature = "mac")] |
| 63 | pub async fn shci_c2_mac_802_15_4_init(&self) -> Result<SchiCommandStatus, ()> { | 77 | pub async fn shci_c2_mac_802_15_4_init(&mut self) -> Result<SchiCommandStatus, ()> { |
| 64 | use crate::tables::{ | ||
| 65 | MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER, Mac802_15_4Table, TL_MAC_802_15_4_TABLE, | ||
| 66 | TL_TRACES_TABLE, TRACES_EVT_QUEUE, TracesTable, | ||
| 67 | }; | ||
| 68 | |||
| 69 | unsafe { | ||
| 70 | LinkedListNode::init_head(TRACES_EVT_QUEUE.as_mut_ptr() as *mut _); | ||
| 71 | |||
| 72 | TL_TRACES_TABLE.as_mut_ptr().write_volatile(TracesTable { | ||
| 73 | traces_queue: TRACES_EVT_QUEUE.as_ptr() as *const _, | ||
| 74 | }); | ||
| 75 | |||
| 76 | TL_MAC_802_15_4_TABLE.as_mut_ptr().write_volatile(Mac802_15_4Table { | ||
| 77 | p_cmdrsp_buffer: MAC_802_15_4_CMD_BUFFER.as_mut_ptr().cast(), | ||
| 78 | p_notack_buffer: MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr().cast(), | ||
| 79 | evt_queue: core::ptr::null_mut(), | ||
| 80 | }); | ||
| 81 | }; | ||
| 82 | |||
| 83 | self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await | 78 | self.write_and_get_response(ShciOpcode::Mac802_15_4Init, &[]).await |
| 84 | } | 79 | } |
| 85 | 80 | ||
| @@ -90,7 +85,7 @@ impl Sys { | |||
| 90 | /// `HW_IPCC_SYS_EvtNot`, aka `IoBusCallBackUserEvt` (as detailed in Figure 65), aka | 85 | /// `HW_IPCC_SYS_EvtNot`, aka `IoBusCallBackUserEvt` (as detailed in Figure 65), aka |
| 91 | /// [crate::sub::ble::hci::host::uart::UartHci::read]. | 86 | /// [crate::sub::ble::hci::host::uart::UartHci::read]. |
| 92 | #[cfg(feature = "ble")] | 87 | #[cfg(feature = "ble")] |
| 93 | pub async fn shci_c2_ble_init(&self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> { | 88 | pub async fn shci_c2_ble_init(&mut self, param: ShciBleInitCmdParam) -> Result<SchiCommandStatus, ()> { |
| 94 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await | 89 | self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await |
| 95 | } | 90 | } |
| 96 | 91 | ||
| @@ -99,14 +94,15 @@ impl Sys { | |||
| 99 | /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, | 94 | /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, |
| 100 | /// as the embassy implementation avoids the need to call C public bindings, and instead | 95 | /// as the embassy implementation avoids the need to call C public bindings, and instead |
| 101 | /// handles the event channels directly. | 96 | /// handles the event channels directly. |
| 102 | pub async fn read(&self) -> EvtBox<mm::MemoryManager> { | 97 | pub async fn read<'b>(&mut self) -> EvtBox<mm::MemoryManager<'b>> { |
| 103 | Ipcc::receive(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, || unsafe { | 98 | self.ipcc_system_event_channel |
| 104 | if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { | 99 | .receive(|| unsafe { |
| 105 | Some(EvtBox::new(node_ptr.cast())) | 100 | if let Some(node_ptr) = LinkedListNode::remove_head(SYSTEM_EVT_QUEUE.as_mut_ptr()) { |
| 106 | } else { | 101 | Some(EvtBox::new(node_ptr.cast())) |
| 107 | None | 102 | } else { |
| 108 | } | 103 | None |
| 109 | }) | 104 | } |
| 110 | .await | 105 | }) |
| 106 | .await | ||
| 111 | } | 107 | } |
| 112 | } | 108 | } |
