From f3b9c977630a0a91eb80e730643760db50d22189 Mon Sep 17 00:00:00 2001 From: Bob McWhirter Date: Wed, 30 Jun 2021 10:17:25 -0400 Subject: [PATCH] Change atomics and add a fence. --- embassy-stm32/src/dma/v2.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/embassy-stm32/src/dma/v2.rs b/embassy-stm32/src/dma/v2.rs index 4cce1adfc..93b3cb869 100644 --- a/embassy-stm32/src/dma/v2.rs +++ b/embassy-stm32/src/dma/v2.rs @@ -74,7 +74,7 @@ pub(crate) async unsafe fn transfer_p2m( let res = poll_fn(|cx| { STATE.ch_wakers[n].register(cx.waker()); - match STATE.ch_status[n].load(Ordering::Relaxed) { + match STATE.ch_status[n].load(Ordering::Acquire) { CH_STATUS_NONE => Poll::Pending, x => Poll::Ready(x), } @@ -105,6 +105,7 @@ pub(crate) async unsafe fn transfer_m2p( c.par().write_value(dst as _); c.m0ar().write_value(src.as_ptr() as _); c.ndtr().write_value(regs::Ndtr(src.len() as _)); + compiler_fence(Ordering::AcqRel); c.cr().write(|w| { w.set_dir(vals::Dir::MEMORYTOPERIPHERAL); w.set_msize(vals::Size::BITS8); @@ -120,7 +121,7 @@ pub(crate) async unsafe fn transfer_m2p( let res = poll_fn(|cx| { STATE.ch_wakers[n].register(cx.waker()); - match STATE.ch_status[n].load(Ordering::Relaxed) { + match STATE.ch_status[n].load(Ordering::Acquire) { CH_STATUS_NONE => { let left = c.ndtr().read().ndt(); Poll::Pending @@ -130,6 +131,8 @@ pub(crate) async unsafe fn transfer_m2p( }) .await; + compiler_fence(Ordering::AcqRel); + // TODO handle error assert!(res == CH_STATUS_COMPLETED); } @@ -145,10 +148,10 @@ unsafe fn on_irq() { for chn in 0..4 { let n = dman * 8 + isrn * 4 + chn; if isr.teif(chn) { - STATE.ch_status[n].store(CH_STATUS_ERROR, Ordering::Relaxed); + STATE.ch_status[n].store(CH_STATUS_ERROR, Ordering::Release); STATE.ch_wakers[n].wake(); } else if isr.tcif(chn) { - STATE.ch_status[n].store(CH_STATUS_COMPLETED, Ordering::Relaxed); + STATE.ch_status[n].store(CH_STATUS_COMPLETED, Ordering::Release); STATE.ch_wakers[n].wake(); } } @@ -298,6 +301,7 @@ pub struct M2P; #[cfg(usart)] use crate::usart; +use atomic_polyfill::compiler_fence; peripheral_dma_channels! { ($peri:ident, usart, $kind:ident, RX, $channel_peri:ident, $dma_peri:ident, $channel_num:expr, $event_num:expr) => { impl usart::RxDma for peripherals::$channel_peri { }