diff options
Diffstat (limited to 'embassy-stm32/src/dma/gpdma')
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/mod.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/ringbuffered.rs | 13 |
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 | ||
| 3 | use core::future::Future; | 3 | use core::future::Future; |
| 4 | use core::pin::Pin; | 4 | use core::pin::Pin; |
| 5 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; | 5 | use core::sync::atomic::{AtomicUsize, Ordering, fence}; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use embassy_hal_internal::Peri; | 8 | use embassy_hal_internal::Peri; |
| @@ -14,6 +14,7 @@ use super::{AnyChannel, Channel, Dir, Request, STATE}; | |||
| 14 | use crate::interrupt::typelevel::Interrupt; | 14 | use crate::interrupt::typelevel::Interrupt; |
| 15 | use crate::pac; | 15 | use crate::pac; |
| 16 | use crate::pac::gpdma::vals; | 16 | use crate::pac::gpdma::vals; |
| 17 | use crate::rcc::BusyPeripheral; | ||
| 17 | 18 | ||
| 18 | pub mod linked_list; | 19 | pub mod linked_list; |
| 19 | pub mod ringbuffered; | 20 | pub 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"] |
| 409 | pub struct LinkedListTransfer<'a, const ITEM_COUNT: usize> { | 415 | pub struct LinkedListTransfer<'a, const ITEM_COUNT: usize> { |
| 410 | channel: Peri<'a, AnyChannel>, | 416 | channel: BusyPeripheral<Peri<'a, AnyChannel>>, |
| 411 | } | 417 | } |
| 412 | 418 | ||
| 413 | impl<'a, const ITEM_COUNT: usize> LinkedListTransfer<'a, ITEM_COUNT> { | 419 | impl<'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"] |
| 506 | pub struct Transfer<'a> { | 514 | pub struct Transfer<'a> { |
| 507 | channel: Peri<'a, AnyChannel>, | 515 | channel: BusyPeripheral<Peri<'a, AnyChannel>>, |
| 508 | } | 516 | } |
| 509 | 517 | ||
| 510 | impl<'a> Transfer<'a> { | 518 | impl<'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). |
| 5 | use core::future::poll_fn; | 5 | use core::future::poll_fn; |
| 6 | use core::sync::atomic::{fence, Ordering}; | 6 | use core::sync::atomic::{Ordering, fence}; |
| 7 | use core::task::Waker; | 7 | use core::task::Waker; |
| 8 | 8 | ||
| 9 | use embassy_hal_internal::Peri; | 9 | use embassy_hal_internal::Peri; |
| 10 | 10 | ||
| 11 | use super::{AnyChannel, TransferOptions, STATE}; | 11 | use super::{AnyChannel, STATE, TransferOptions}; |
| 12 | use crate::dma::gpdma::linked_list::{RunMode, Table}; | 12 | use crate::dma::gpdma::linked_list::{RunMode, Table}; |
| 13 | use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; | 13 | use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; |
| 14 | use crate::dma::word::Word; | 14 | use crate::dma::word::Word; |
| 15 | use crate::dma::{Channel, Dir, Request}; | 15 | use crate::dma::{Channel, Dir, Request}; |
| 16 | use crate::rcc::BusyPeripheral; | ||
| 16 | 17 | ||
| 17 | struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); | 18 | struct 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. |
| 51 | pub struct ReadableRingBuffer<'a, W: Word> { | 52 | pub 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. |
| 191 | pub struct WritableRingBuffer<'a, W: Word> { | 192 | pub 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, |
