diff options
| author | Raul Alimbekov <[email protected]> | 2025-12-16 09:05:22 +0300 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-16 09:05:22 +0300 |
| commit | c9a04b4b732b7a3b696eb8223664c1a7942b1875 (patch) | |
| tree | 6dbe5c02e66eed8d8762f13f95afd24f8db2b38c /embassy-stm32-wpan/src/sub/mac.rs | |
| parent | cde24a3ef1117653ba5ed4184102b33f745782fb (diff) | |
| parent | 5ae6e060ec1c90561719aabdc29d5b6e7b8b0a82 (diff) | |
Merge branch 'main' into main
Diffstat (limited to 'embassy-stm32-wpan/src/sub/mac.rs')
| -rw-r--r-- | embassy-stm32-wpan/src/sub/mac.rs | 124 |
1 files changed, 0 insertions, 124 deletions
diff --git a/embassy-stm32-wpan/src/sub/mac.rs b/embassy-stm32-wpan/src/sub/mac.rs deleted file mode 100644 index baf4da979..000000000 --- a/embassy-stm32-wpan/src/sub/mac.rs +++ /dev/null | |||
| @@ -1,124 +0,0 @@ | |||
| 1 | use core::future::poll_fn; | ||
| 2 | use core::ptr; | ||
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 4 | use core::task::Poll; | ||
| 5 | |||
| 6 | use embassy_futures::poll_once; | ||
| 7 | use embassy_stm32::ipcc::Ipcc; | ||
| 8 | use embassy_sync::waitqueue::AtomicWaker; | ||
| 9 | |||
| 10 | use crate::cmd::CmdPacket; | ||
| 11 | use crate::consts::TlPacketType; | ||
| 12 | use crate::evt::{EvtBox, EvtPacket}; | ||
| 13 | use crate::mac::commands::MacCommand; | ||
| 14 | use crate::mac::event::MacEvent; | ||
| 15 | use crate::mac::typedefs::MacError; | ||
| 16 | use crate::tables::{MAC_802_15_4_CMD_BUFFER, MAC_802_15_4_NOTIF_RSP_EVT_BUFFER}; | ||
| 17 | use crate::{channels, evt}; | ||
| 18 | |||
| 19 | static MAC_WAKER: AtomicWaker = AtomicWaker::new(); | ||
| 20 | static MAC_EVT_OUT: AtomicBool = AtomicBool::new(false); | ||
| 21 | |||
| 22 | pub struct Mac { | ||
| 23 | _private: (), | ||
| 24 | } | ||
| 25 | |||
| 26 | impl Mac { | ||
| 27 | pub(crate) fn new() -> Self { | ||
| 28 | Self { _private: () } | ||
| 29 | } | ||
| 30 | |||
| 31 | /// `HW_IPCC_MAC_802_15_4_EvtNot` | ||
| 32 | /// | ||
| 33 | /// This function will stall if the previous `EvtBox` has not been dropped | ||
| 34 | pub async fn tl_read(&self) -> EvtBox<Self> { | ||
| 35 | // Wait for the last event box to be dropped | ||
| 36 | poll_fn(|cx| { | ||
| 37 | MAC_WAKER.register(cx.waker()); | ||
| 38 | if MAC_EVT_OUT.load(Ordering::SeqCst) { | ||
| 39 | Poll::Pending | ||
| 40 | } else { | ||
| 41 | Poll::Ready(()) | ||
| 42 | } | ||
| 43 | }) | ||
| 44 | .await; | ||
| 45 | |||
| 46 | // Return a new event box | ||
| 47 | Ipcc::receive(channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, || unsafe { | ||
| 48 | // The closure is not async, therefore the closure must execute to completion (cannot be dropped) | ||
| 49 | // Therefore, the event box is guaranteed to be cleaned up if it's not leaked | ||
| 50 | MAC_EVT_OUT.store(true, Ordering::SeqCst); | ||
| 51 | |||
| 52 | Some(EvtBox::new(MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _)) | ||
| 53 | }) | ||
| 54 | .await | ||
| 55 | } | ||
| 56 | |||
| 57 | /// `HW_IPCC_MAC_802_15_4_CmdEvtNot` | ||
| 58 | pub async fn tl_write_and_get_response(&self, opcode: u16, payload: &[u8]) -> u8 { | ||
| 59 | self.tl_write(opcode, payload).await; | ||
| 60 | Ipcc::flush(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL).await; | ||
| 61 | |||
| 62 | unsafe { | ||
| 63 | let p_event_packet = MAC_802_15_4_CMD_BUFFER.as_ptr() as *const EvtPacket; | ||
| 64 | let p_mac_rsp_evt = &((*p_event_packet).evt_serial.evt.payload) as *const u8; | ||
| 65 | |||
| 66 | ptr::read_volatile(p_mac_rsp_evt) | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /// `TL_MAC_802_15_4_SendCmd` | ||
| 71 | pub async fn tl_write(&self, opcode: u16, payload: &[u8]) { | ||
| 72 | Ipcc::send(channels::cpu1::IPCC_MAC_802_15_4_CMD_RSP_CHANNEL, || unsafe { | ||
| 73 | CmdPacket::write_into( | ||
| 74 | MAC_802_15_4_CMD_BUFFER.as_mut_ptr(), | ||
| 75 | TlPacketType::MacCmd, | ||
| 76 | opcode, | ||
| 77 | payload, | ||
| 78 | ); | ||
| 79 | }) | ||
| 80 | .await; | ||
| 81 | } | ||
| 82 | |||
| 83 | pub async fn send_command<T>(&self, cmd: &T) -> Result<(), MacError> | ||
| 84 | where | ||
| 85 | T: MacCommand, | ||
| 86 | { | ||
| 87 | let response = self.tl_write_and_get_response(T::OPCODE as u16, cmd.payload()).await; | ||
| 88 | |||
| 89 | if response == 0x00 { | ||
| 90 | Ok(()) | ||
| 91 | } else { | ||
| 92 | Err(MacError::from(response)) | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | pub async fn read(&self) -> Result<MacEvent<'_>, ()> { | ||
| 97 | MacEvent::new(self.tl_read().await) | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | impl evt::MemoryManager for Mac { | ||
| 102 | /// SAFETY: passing a pointer to something other than a managed event packet is UB | ||
| 103 | unsafe fn drop_event_packet(_: *mut EvtPacket) { | ||
| 104 | trace!("mac drop event"); | ||
| 105 | |||
| 106 | // Write the ack | ||
| 107 | CmdPacket::write_into( | ||
| 108 | MAC_802_15_4_NOTIF_RSP_EVT_BUFFER.as_mut_ptr() as *mut _, | ||
| 109 | TlPacketType::OtAck, | ||
| 110 | 0, | ||
| 111 | &[], | ||
| 112 | ); | ||
| 113 | |||
| 114 | // Clear the rx flag | ||
| 115 | let _ = poll_once(Ipcc::receive::<()>( | ||
| 116 | channels::cpu2::IPCC_MAC_802_15_4_NOTIFICATION_ACK_CHANNEL, | ||
| 117 | || None, | ||
| 118 | )); | ||
| 119 | |||
| 120 | // Allow a new read call | ||
| 121 | MAC_EVT_OUT.store(false, Ordering::SeqCst); | ||
| 122 | MAC_WAKER.wake(); | ||
| 123 | } | ||
| 124 | } | ||
