diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index d262caeb6..fbd753a71 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs @@ -1,6 +1,7 @@ #![macro_use] use core::future::Future; +use core::sync::atomic::{fence, Ordering}; use core::task::Poll; use embassy::interrupt::{Interrupt, InterruptExt}; @@ -61,6 +62,9 @@ pub(crate) unsafe fn do_transfer( // Wait for the transfer to complete when it was ongoing. while ch.cr().read().en() {} + + // "Subsequent reads and writes cannot be moved ahead of preceding reads." + fence(Ordering::Acquire); }); #[cfg(dmamux)] @@ -72,6 +76,9 @@ pub(crate) unsafe fn do_transfer( .modify(|w| w.set_cs(channel_number as _, request)) }); + // "Preceding reads and writes cannot be moved past subsequent writes." + fence(Ordering::Release); + ch.par().write_value(peri_addr as u32); ch.mar().write_value(mem_addr as u32); ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index 9bf083de4..bce9656d1 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs @@ -1,4 +1,5 @@ use core::future::Future; +use core::sync::atomic::{fence, Ordering}; use core::task::Poll; use embassy::interrupt::{Interrupt, InterruptExt}; @@ -64,11 +65,17 @@ pub(crate) unsafe fn do_transfer( // Wait for the transfer to complete when it was ongoing. while ch.cr().read().en() {} + + // "Subsequent reads and writes cannot be moved ahead of preceding reads." + fence(Ordering::Acquire); }); #[cfg(dmamux)] super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request); + // "Preceding reads and writes cannot be moved past subsequent writes." + fence(Ordering::Release); + unsafe { ch.par().write_value(peri_addr as u32); ch.m0ar().write_value(mem_addr as u32);