aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/dma/gpdma
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/dma/gpdma')
-rw-r--r--embassy-stm32/src/dma/gpdma/mod.rs20
-rw-r--r--embassy-stm32/src/dma/gpdma/ringbuffered.rs13
2 files changed, 22 insertions, 11 deletions
diff --git a/embassy-stm32/src/dma/gpdma/mod.rs b/embassy-stm32/src/dma/gpdma/mod.rs
index 4a14c2a8e..afb18ec1a 100644
--- a/embassy-stm32/src/dma/gpdma/mod.rs
+++ b/embassy-stm32/src/dma/gpdma/mod.rs
@@ -2,7 +2,7 @@
2 2
3use core::future::Future; 3use core::future::Future;
4use core::pin::Pin; 4use core::pin::Pin;
5use core::sync::atomic::{fence, AtomicUsize, Ordering}; 5use core::sync::atomic::{AtomicUsize, Ordering, fence};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use embassy_hal_internal::Peri; 8use embassy_hal_internal::Peri;
@@ -14,6 +14,7 @@ use super::{AnyChannel, Channel, Dir, Request, STATE};
14use crate::interrupt::typelevel::Interrupt; 14use crate::interrupt::typelevel::Interrupt;
15use crate::pac; 15use crate::pac;
16use crate::pac::gpdma::vals; 16use crate::pac::gpdma::vals;
17use crate::rcc::BusyPeripheral;
17 18
18pub mod linked_list; 19pub mod linked_list;
19pub mod ringbuffered; 20pub mod ringbuffered;
@@ -236,6 +237,11 @@ impl AnyChannel {
236 // "Preceding reads and writes cannot be moved past subsequent writes." 237 // "Preceding reads and writes cannot be moved past subsequent writes."
237 fence(Ordering::SeqCst); 238 fence(Ordering::SeqCst);
238 239
240 if ch.cr().read().en() {
241 ch.cr().modify(|w| w.set_susp(true));
242 while !ch.sr().read().suspf() {}
243 }
244
239 ch.cr().write(|w| w.set_reset(true)); 245 ch.cr().write(|w| w.set_reset(true));
240 ch.fcr().write(|w| { 246 ch.fcr().write(|w| {
241 // Clear all irqs 247 // Clear all irqs
@@ -407,7 +413,7 @@ impl AnyChannel {
407/// Linked-list DMA transfer. 413/// Linked-list DMA transfer.
408#[must_use = "futures do nothing unless you `.await` or poll them"] 414#[must_use = "futures do nothing unless you `.await` or poll them"]
409pub struct LinkedListTransfer<'a, const ITEM_COUNT: usize> { 415pub struct LinkedListTransfer<'a, const ITEM_COUNT: usize> {
410 channel: Peri<'a, AnyChannel>, 416 channel: BusyPeripheral<Peri<'a, AnyChannel>>,
411} 417}
412 418
413impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> { 419impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
@@ -428,7 +434,9 @@ impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> {
428 channel.configure_linked_list(&table, options); 434 channel.configure_linked_list(&table, options);
429 channel.start(); 435 channel.start();
430 436
431 Self { channel } 437 Self {
438 channel: BusyPeripheral::new(channel),
439 }
432 } 440 }
433 441
434 /// Request the transfer to pause, keeping the existing configuration for this channel. 442 /// Request the transfer to pause, keeping the existing configuration for this channel.
@@ -504,7 +512,7 @@ impl<'a, const ITEM_COUNT: usize> Future for LinkedListTransfer<'a, ITEM_COUNT>
504/// DMA transfer. 512/// DMA transfer.
505#[must_use = "futures do nothing unless you `.await` or poll them"] 513#[must_use = "futures do nothing unless you `.await` or poll them"]
506pub struct Transfer<'a> { 514pub struct Transfer<'a> {
507 channel: Peri<'a, AnyChannel>, 515 channel: BusyPeripheral<Peri<'a, AnyChannel>>,
508} 516}
509 517
510impl<'a> Transfer<'a> { 518impl<'a> Transfer<'a> {
@@ -624,7 +632,9 @@ impl<'a> Transfer<'a> {
624 ); 632 );
625 channel.start(); 633 channel.start();
626 634
627 Self { channel } 635 Self {
636 channel: BusyPeripheral::new(channel),
637 }
628 } 638 }
629 639
630 /// Request the transfer to pause, keeping the existing configuration for this channel. 640 /// Request the transfer to pause, keeping the existing configuration for this channel.
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
index 9ee52193b..c150d0b95 100644
--- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs
+++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
@@ -3,16 +3,17 @@
3//! FIXME: Add request_pause functionality? 3//! FIXME: Add request_pause functionality?
4//! FIXME: Stop the DMA, if a user does not queue new transfers (chain of linked-list items ends automatically). 4//! FIXME: Stop the DMA, if a user does not queue new transfers (chain of linked-list items ends automatically).
5use core::future::poll_fn; 5use core::future::poll_fn;
6use core::sync::atomic::{fence, Ordering}; 6use core::sync::atomic::{Ordering, fence};
7use core::task::Waker; 7use core::task::Waker;
8 8
9use embassy_hal_internal::Peri; 9use embassy_hal_internal::Peri;
10 10
11use super::{AnyChannel, TransferOptions, STATE}; 11use super::{AnyChannel, STATE, TransferOptions};
12use crate::dma::gpdma::linked_list::{RunMode, Table}; 12use crate::dma::gpdma::linked_list::{RunMode, Table};
13use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; 13use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer};
14use crate::dma::word::Word; 14use crate::dma::word::Word;
15use crate::dma::{Channel, Dir, Request}; 15use crate::dma::{Channel, Dir, Request};
16use crate::rcc::BusyPeripheral;
16 17
17struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); 18struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>);
18 19
@@ -49,7 +50,7 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> {
49 50
50/// Ringbuffer for receiving data using GPDMA linked-list mode. 51/// Ringbuffer for receiving data using GPDMA linked-list mode.
51pub struct ReadableRingBuffer<'a, W: Word> { 52pub struct ReadableRingBuffer<'a, W: Word> {
52 channel: Peri<'a, AnyChannel>, 53 channel: BusyPeripheral<Peri<'a, AnyChannel>>,
53 ringbuf: ReadableDmaRingBuffer<'a, W>, 54 ringbuf: ReadableDmaRingBuffer<'a, W>,
54 table: Table<2>, 55 table: Table<2>,
55 options: TransferOptions, 56 options: TransferOptions,
@@ -70,7 +71,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
70 let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::PeripheralToMemory); 71 let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::PeripheralToMemory);
71 72
72 Self { 73 Self {
73 channel, 74 channel: BusyPeripheral::new(channel),
74 ringbuf: ReadableDmaRingBuffer::new(buffer), 75 ringbuf: ReadableDmaRingBuffer::new(buffer),
75 table, 76 table,
76 options, 77 options,
@@ -189,7 +190,7 @@ impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> {
189 190
190/// Ringbuffer for writing data using GPDMA linked-list mode. 191/// Ringbuffer for writing data using GPDMA linked-list mode.
191pub struct WritableRingBuffer<'a, W: Word> { 192pub struct WritableRingBuffer<'a, W: Word> {
192 channel: Peri<'a, AnyChannel>, 193 channel: BusyPeripheral<Peri<'a, AnyChannel>>,
193 ringbuf: WritableDmaRingBuffer<'a, W>, 194 ringbuf: WritableDmaRingBuffer<'a, W>,
194 table: Table<2>, 195 table: Table<2>,
195 options: TransferOptions, 196 options: TransferOptions,
@@ -210,7 +211,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
210 let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::MemoryToPeripheral); 211 let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::MemoryToPeripheral);
211 212
212 Self { 213 Self {
213 channel, 214 channel: BusyPeripheral::new(channel),
214 ringbuf: WritableDmaRingBuffer::new(buffer), 215 ringbuf: WritableDmaRingBuffer::new(buffer),
215 table, 216 table,
216 options, 217 options,