stm32: Add fences to DMA code

This commit is contained in:
Thales Fragoso 2021-08-10 20:40:02 -03:00
parent 0be5e323bb
commit c7ae2d2a3a
2 changed files with 14 additions and 0 deletions

View File

@ -1,6 +1,7 @@
#![macro_use] #![macro_use]
use core::future::Future; use core::future::Future;
use core::sync::atomic::{fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy::interrupt::{Interrupt, InterruptExt}; 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. // Wait for the transfer to complete when it was ongoing.
while ch.cr().read().en() {} while ch.cr().read().en() {}
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
fence(Ordering::Acquire);
}); });
#[cfg(dmamux)] #[cfg(dmamux)]
@ -72,6 +76,9 @@ pub(crate) unsafe fn do_transfer(
.modify(|w| w.set_cs(channel_number as _, request)) .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.par().write_value(peri_addr as u32);
ch.mar().write_value(mem_addr as u32); ch.mar().write_value(mem_addr as u32);
ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); ch.ndtr().write(|w| w.set_ndt(mem_len as u16));

View File

@ -1,4 +1,5 @@
use core::future::Future; use core::future::Future;
use core::sync::atomic::{fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy::interrupt::{Interrupt, InterruptExt}; 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. // Wait for the transfer to complete when it was ongoing.
while ch.cr().read().en() {} while ch.cr().read().en() {}
// "Subsequent reads and writes cannot be moved ahead of preceding reads."
fence(Ordering::Acquire);
}); });
#[cfg(dmamux)] #[cfg(dmamux)]
super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request); super::dmamux::configure_dmamux(dmamux_regs, dmamux_ch_num, request);
// "Preceding reads and writes cannot be moved past subsequent writes."
fence(Ordering::Release);
unsafe { unsafe {
ch.par().write_value(peri_addr as u32); ch.par().write_value(peri_addr as u32);
ch.m0ar().write_value(mem_addr as u32); ch.m0ar().write_value(mem_addr as u32);