aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/wb55/sub/sys.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan/src/wb55/sub/sys.rs')
-rw-r--r--embassy-stm32-wpan/src/wb55/sub/sys.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/embassy-stm32-wpan/src/wb55/sub/sys.rs b/embassy-stm32-wpan/src/wb55/sub/sys.rs
index 2e625a677..3d774eeb7 100644
--- a/embassy-stm32-wpan/src/wb55/sub/sys.rs
+++ b/embassy-stm32-wpan/src/wb55/sub/sys.rs
@@ -1,3 +1,5 @@
1use core::slice;
2
1use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel}; 3use embassy_stm32::ipcc::{IpccRxChannel, IpccTxChannel};
2 4
3use crate::cmd::CmdPacket; 5use crate::cmd::CmdPacket;
@@ -5,12 +7,17 @@ use crate::consts::TlPacketType;
5use crate::evt::EvtBox; 7use crate::evt::EvtBox;
6#[cfg(feature = "wb55_ble")] 8#[cfg(feature = "wb55_ble")]
7use crate::shci::ShciBleInitCmdParam; 9use crate::shci::ShciBleInitCmdParam;
8use crate::shci::{SchiCommandStatus, ShciOpcode}; 10use crate::shci::{SchiCommandStatus, SchiFromPacket, SchiSysEventReady, ShciFusGetStateErrorCode, ShciOpcode};
9use crate::sub::mm; 11use crate::sub::mm;
10use crate::tables::{SysTable, WirelessFwInfoTable}; 12use crate::tables::{SysTable, WirelessFwInfoTable};
11use crate::unsafe_linked_list::LinkedListNode; 13use crate::unsafe_linked_list::LinkedListNode;
12use crate::wb55::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE}; 14use crate::wb55::{SYS_CMD_BUF, SYSTEM_EVT_QUEUE, TL_DEVICE_INFO_TABLE, TL_SYS_TABLE};
13 15
16const fn slice8_ref(x: &[u32]) -> &[u8] {
17 let len = x.len() * 4;
18 unsafe { slice::from_raw_parts(x.as_ptr() as *const u8, len) }
19}
20
14/// A guard that, once constructed, allows for sys commands to be sent to CPU2. 21/// A guard that, once constructed, allows for sys commands to be sent to CPU2.
15pub struct Sys<'a> { 22pub struct Sys<'a> {
16 ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>, 23 ipcc_system_cmd_rsp_channel: IpccTxChannel<'a>,
@@ -55,15 +62,15 @@ impl<'a> Sys<'a> {
55 } 62 }
56 63
57 /// `HW_IPCC_SYS_CmdEvtNot` 64 /// `HW_IPCC_SYS_CmdEvtNot`
58 pub async fn write_and_get_response( 65 pub async fn write_and_get_response<T: SchiFromPacket>(
59 &mut self, 66 &mut self,
60 opcode: ShciOpcode, 67 opcode: ShciOpcode,
61 payload: &[u8], 68 payload: &[u8],
62 ) -> Result<SchiCommandStatus, ()> { 69 ) -> Result<T, ()> {
63 self.write(opcode, payload).await; 70 self.write(opcode, payload).await;
64 self.ipcc_system_cmd_rsp_channel.flush().await; 71 self.ipcc_system_cmd_rsp_channel.flush().await;
65 72
66 unsafe { SchiCommandStatus::from_packet(SYS_CMD_BUF.as_ptr()) } 73 unsafe { T::from_packet(SYS_CMD_BUF.as_ptr()) }
67 } 74 }
68 75
69 #[cfg(feature = "wb55_mac")] 76 #[cfg(feature = "wb55_mac")]
@@ -82,6 +89,36 @@ impl<'a> Sys<'a> {
82 self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await 89 self.write_and_get_response(ShciOpcode::BleInit, param.payload()).await
83 } 90 }
84 91
92 pub async fn shci_c2_fus_getstate(&mut self) -> Result<ShciFusGetStateErrorCode, ()> {
93 self.write_and_get_response(ShciOpcode::FusStartWirelessStack, &[])
94 .await
95 }
96
97 /// Send a request to CPU2 to start the wireless stack
98 pub async fn shci_c2_fus_startws(&mut self) -> Result<SchiCommandStatus, ()> {
99 self.write_and_get_response(ShciOpcode::FusStartWirelessStack, &[])
100 .await
101 }
102
103 /// Send a request to CPU2 to upgrade the firmware
104 pub async fn shci_c2_fus_fwupgrade(&mut self, fw_src_add: u32, fw_dst_add: u32) -> Result<SchiCommandStatus, ()> {
105 let buf = [fw_src_add, fw_dst_add];
106 let len = if fw_dst_add != 0 {
107 2
108 } else if fw_src_add != 0 {
109 1
110 } else {
111 0
112 };
113
114 self.write_and_get_response(ShciOpcode::FusFirmwareUpgrade, slice8_ref(&buf[..len]))
115 .await
116 }
117
118 pub async fn read_ready(&mut self) -> Result<SchiSysEventReady, ()> {
119 self.read().await.payload()[0].try_into()
120 }
121
85 /// `HW_IPCC_SYS_EvtNot` 122 /// `HW_IPCC_SYS_EvtNot`
86 /// 123 ///
87 /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`, 124 /// This method takes the place of the `HW_IPCC_SYS_EvtNot`/`SysUserEvtRx`/`APPE_SysUserEvtRx`,