stm32/gpdma: fix race condition when resetting channel when done.

This commit is contained in:
Dario Nieuwenhuis 2023-04-10 15:11:07 +02:00
parent dee8c71a2d
commit 44b7fe45e2

View File

@ -190,6 +190,10 @@ mod low_level_api {
fence(Ordering::SeqCst); fence(Ordering::SeqCst);
let ch = dma.ch(channel_number as _); let ch = dma.ch(channel_number as _);
// Reset ch
ch.cr().write(|w| w.set_reset(true));
ch.llr().write(|_| {}); // no linked list ch.llr().write(|_| {}); // no linked list
ch.tr1().write(|w| { ch.tr1().write(|w| {
w.set_sdw(data_size.into()); w.set_sdw(data_size.into());
@ -252,7 +256,7 @@ mod low_level_api {
/// Gets the running status of the channel /// Gets the running status of the channel
pub unsafe fn is_running(dma: Gpdma, ch: u8) -> bool { pub unsafe fn is_running(dma: Gpdma, ch: u8) -> bool {
let ch = dma.ch(ch as _); let ch = dma.ch(ch as _);
!ch.sr().read().idlef() !ch.sr().read().tcf()
} }
/// Gets the total remaining transfers for the channel /// Gets the total remaining transfers for the channel
@ -291,7 +295,10 @@ mod low_level_api {
} }
if sr.suspf() || sr.tcf() { if sr.suspf() || sr.tcf() {
ch.cr().write(|w| w.set_reset(true)); // disable all xxIEs to prevent the irq from firing again.
ch.cr().write(|_| {});
// Wake the future. It'll look at tcf and see it's set.
STATE.channels[state_index].waker.wake(); STATE.channels[state_index].waker.wake();
} }
} }