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