aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-05-01 18:14:34 +0200
committerDario Nieuwenhuis <[email protected]>2023-05-01 22:42:36 +0200
commit14e0090cb1e60ce477ae4f080d0deb724dbc3b9e (patch)
treec59285e69338ee277bc44e99452fffb6ac0c86f9
parent45843034ec7c53f3f619bf1dcc6c145c428b0601 (diff)
stm32/dma: remove separate process_tcif.
-rw-r--r--embassy-stm32/src/dma/dma.rs46
1 files changed, 9 insertions, 37 deletions
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs
index 10ae20f5c..69a5ec4e4 100644
--- a/embassy-stm32/src/dma/dma.rs
+++ b/embassy-stm32/src/dma/dma.rs
@@ -8,14 +8,13 @@ use atomic_polyfill::AtomicUsize;
8use embassy_cortex_m::interrupt::Priority; 8use embassy_cortex_m::interrupt::Priority;
9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use pac::dma::regs;
12 11
13use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError}; 12use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
14use super::word::{Word, WordSize}; 13use super::word::{Word, WordSize};
15use super::Dir; 14use super::Dir;
16use crate::_generated::DMA_CHANNEL_COUNT; 15use crate::_generated::DMA_CHANNEL_COUNT;
17use crate::interrupt::{Interrupt, InterruptExt}; 16use crate::interrupt::{Interrupt, InterruptExt};
18use crate::pac::dma::vals; 17use crate::pac::dma::{regs, vals};
19use crate::{interrupt, pac}; 18use crate::{interrupt, pac};
20 19
21#[derive(Debug, Copy, Clone, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -196,35 +195,18 @@ pub(crate) unsafe fn on_irq_inner(dma: pac::dma::Dma, channel_num: usize, index:
196 wake = true; 195 wake = true;
197 } 196 }
198 197
199 wake |= process_tcif(dma, channel_num, index); 198 if isr.tcif(channel_num % 4) && cr.read().tcie() {
199 // Acknowledge transfer complete interrupt
200 dma.ifcr(channel_num / 4).write(|w| w.set_tcif(channel_num % 4, true));
201 STATE.complete_count[index].fetch_add(1, Ordering::Release);
202 wake = true;
203 }
200 204
201 if wake { 205 if wake {
202 STATE.ch_wakers[index].wake(); 206 STATE.ch_wakers[index].wake();
203 } 207 }
204} 208}
205 209
206unsafe fn process_tcif(dma: pac::dma::Dma, channel_num: usize, index: usize) -> bool {
207 let isr_reg = dma.isr(channel_num / 4);
208 let cr_reg = dma.st(channel_num).cr();
209
210 // First, figure out if tcif is set without a cs.
211 if isr_reg.read().tcif(channel_num % 4) && cr_reg.read().tcie() {
212 // Make tcif test again within a cs to avoid race when incrementing complete_count.
213 critical_section::with(|_| {
214 if isr_reg.read().tcif(channel_num % 4) && cr_reg.read().tcie() {
215 // Acknowledge transfer complete interrupt
216 dma.ifcr(channel_num / 4).write(|w| w.set_tcif(channel_num % 4, true));
217 STATE.complete_count[index].fetch_add(1, Ordering::Release);
218 true
219 } else {
220 false
221 }
222 })
223 } else {
224 false
225 }
226}
227
228#[cfg(any(dma_v2, dmamux))] 210#[cfg(any(dma_v2, dmamux))]
229pub type Request = u8; 211pub type Request = u8;
230#[cfg(not(any(dma_v2, dmamux)))] 212#[cfg(not(any(dma_v2, dmamux)))]
@@ -634,21 +616,11 @@ impl<C: Channel> DmaCtrl for C {
634 } 616 }
635 617
636 fn get_complete_count(&self) -> usize { 618 fn get_complete_count(&self) -> usize {
637 let dma = self.regs(); 619 STATE.complete_count[self.index()].load(Ordering::Acquire)
638 let channel_num = self.num();
639 let index = self.index();
640 // Manually process tcif in case transfer was completed and we are in a higher priority task.
641 unsafe { process_tcif(dma, channel_num, index) };
642 STATE.complete_count[index].load(Ordering::Acquire)
643 } 620 }
644 621
645 fn reset_complete_count(&mut self) -> usize { 622 fn reset_complete_count(&mut self) -> usize {
646 let dma = self.regs(); 623 STATE.complete_count[self.index()].swap(0, Ordering::AcqRel)
647 let channel_num = self.num();
648 let index = self.index();
649 // Manually process tcif in case transfer was completed and we are in a higher priority task.
650 unsafe { process_tcif(dma, channel_num, index) };
651 STATE.complete_count[index].swap(0, Ordering::AcqRel)
652 } 624 }
653} 625}
654 626