diff options
Diffstat (limited to 'embassy-stm32/src/dma')
| -rw-r--r-- | embassy-stm32/src/dma/dma_bdma.rs | 19 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/mod.rs | 20 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/ringbuffered.rs | 13 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 34 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs | 2 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/util.rs | 58 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/word.rs | 4 |
7 files changed, 126 insertions, 24 deletions
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs index 73ecab070..adc084474 100644 --- a/embassy-stm32/src/dma/dma_bdma.rs +++ b/embassy-stm32/src/dma/dma_bdma.rs | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | use core::future::{poll_fn, Future}; | 1 | use core::future::{Future, poll_fn}; |
| 2 | use core::pin::Pin; | 2 | use core::pin::Pin; |
| 3 | use core::sync::atomic::{fence, AtomicUsize, Ordering}; | 3 | use core::sync::atomic::{AtomicUsize, Ordering, fence}; |
| 4 | use core::task::{Context, Poll, Waker}; | 4 | use core::task::{Context, Poll, Waker}; |
| 5 | 5 | ||
| 6 | use embassy_hal_internal::Peri; | 6 | use embassy_hal_internal::Peri; |
| @@ -10,6 +10,7 @@ use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBu | |||
| 10 | use super::word::{Word, WordSize}; | 10 | use super::word::{Word, WordSize}; |
| 11 | use super::{AnyChannel, Channel, Dir, Request, STATE}; | 11 | use super::{AnyChannel, Channel, Dir, Request, STATE}; |
| 12 | use crate::interrupt::typelevel::Interrupt; | 12 | use crate::interrupt::typelevel::Interrupt; |
| 13 | use crate::rcc::BusyPeripheral; | ||
| 13 | use crate::{interrupt, pac}; | 14 | use crate::{interrupt, pac}; |
| 14 | 15 | ||
| 15 | pub(crate) struct ChannelInfo { | 16 | pub(crate) struct ChannelInfo { |
| @@ -602,7 +603,7 @@ impl AnyChannel { | |||
| 602 | /// DMA transfer. | 603 | /// DMA transfer. |
| 603 | #[must_use = "futures do nothing unless you `.await` or poll them"] | 604 | #[must_use = "futures do nothing unless you `.await` or poll them"] |
| 604 | pub struct Transfer<'a> { | 605 | pub struct Transfer<'a> { |
| 605 | channel: Peri<'a, AnyChannel>, | 606 | channel: BusyPeripheral<Peri<'a, AnyChannel>>, |
| 606 | } | 607 | } |
| 607 | 608 | ||
| 608 | impl<'a> Transfer<'a> { | 609 | impl<'a> Transfer<'a> { |
| @@ -713,7 +714,9 @@ impl<'a> Transfer<'a> { | |||
| 713 | _request, dir, peri_addr, mem_addr, mem_len, incr_mem, mem_size, peri_size, options, | 714 | _request, dir, peri_addr, mem_addr, mem_len, incr_mem, mem_size, peri_size, options, |
| 714 | ); | 715 | ); |
| 715 | channel.start(); | 716 | channel.start(); |
| 716 | Self { channel } | 717 | Self { |
| 718 | channel: BusyPeripheral::new(channel), | ||
| 719 | } | ||
| 717 | } | 720 | } |
| 718 | 721 | ||
| 719 | /// Request the transfer to pause, keeping the existing configuration for this channel. | 722 | /// Request the transfer to pause, keeping the existing configuration for this channel. |
| @@ -816,7 +819,7 @@ impl<'a> DmaCtrl for DmaCtrlImpl<'a> { | |||
| 816 | 819 | ||
| 817 | /// Ringbuffer for receiving data using DMA circular mode. | 820 | /// Ringbuffer for receiving data using DMA circular mode. |
| 818 | pub struct ReadableRingBuffer<'a, W: Word> { | 821 | pub struct ReadableRingBuffer<'a, W: Word> { |
| 819 | channel: Peri<'a, AnyChannel>, | 822 | channel: BusyPeripheral<Peri<'a, AnyChannel>>, |
| 820 | ringbuf: ReadableDmaRingBuffer<'a, W>, | 823 | ringbuf: ReadableDmaRingBuffer<'a, W>, |
| 821 | } | 824 | } |
| 822 | 825 | ||
| @@ -853,7 +856,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> { | |||
| 853 | ); | 856 | ); |
| 854 | 857 | ||
| 855 | Self { | 858 | Self { |
| 856 | channel, | 859 | channel: BusyPeripheral::new(channel), |
| 857 | ringbuf: ReadableDmaRingBuffer::new(buffer), | 860 | ringbuf: ReadableDmaRingBuffer::new(buffer), |
| 858 | } | 861 | } |
| 859 | } | 862 | } |
| @@ -972,7 +975,7 @@ impl<'a, W: Word> Drop for ReadableRingBuffer<'a, W> { | |||
| 972 | 975 | ||
| 973 | /// Ringbuffer for writing data using DMA circular mode. | 976 | /// Ringbuffer for writing data using DMA circular mode. |
| 974 | pub struct WritableRingBuffer<'a, W: Word> { | 977 | pub struct WritableRingBuffer<'a, W: Word> { |
| 975 | channel: Peri<'a, AnyChannel>, | 978 | channel: BusyPeripheral<Peri<'a, AnyChannel>>, |
| 976 | ringbuf: WritableDmaRingBuffer<'a, W>, | 979 | ringbuf: WritableDmaRingBuffer<'a, W>, |
| 977 | } | 980 | } |
| 978 | 981 | ||
| @@ -1009,7 +1012,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 1009 | ); | 1012 | ); |
| 1010 | 1013 | ||
| 1011 | Self { | 1014 | Self { |
| 1012 | channel, | 1015 | channel: BusyPeripheral::new(channel), |
| 1013 | ringbuf: WritableDmaRingBuffer::new(buffer), | 1016 | ringbuf: WritableDmaRingBuffer::new(buffer), |
| 1014 | } | 1017 | } |
| 1015 | } | 1018 | } |
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, |
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 5989bfd7c..05d9c2e51 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #[cfg(any(bdma, dma))] | 4 | #[cfg(any(bdma, dma))] |
| 5 | mod dma_bdma; | 5 | mod dma_bdma; |
| 6 | |||
| 6 | #[cfg(any(bdma, dma))] | 7 | #[cfg(any(bdma, dma))] |
| 7 | pub use dma_bdma::*; | 8 | pub use dma_bdma::*; |
| 8 | 9 | ||
| @@ -24,9 +25,10 @@ pub(crate) use util::*; | |||
| 24 | pub(crate) mod ringbuffer; | 25 | pub(crate) mod ringbuffer; |
| 25 | pub mod word; | 26 | pub mod word; |
| 26 | 27 | ||
| 27 | use embassy_hal_internal::{impl_peripheral, PeripheralType}; | 28 | use embassy_hal_internal::{PeripheralType, impl_peripheral}; |
| 28 | 29 | ||
| 29 | use crate::interrupt; | 30 | use crate::interrupt; |
| 31 | use crate::rcc::StoppablePeripheral; | ||
| 30 | 32 | ||
| 31 | /// The direction of a DMA transfer. | 33 | /// The direction of a DMA transfer. |
| 32 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] | 34 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
| @@ -45,7 +47,7 @@ pub type Request = u8; | |||
| 45 | #[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] | 47 | #[cfg(not(any(dma_v2, bdma_v2, gpdma, dmamux)))] |
| 46 | pub type Request = (); | 48 | pub type Request = (); |
| 47 | 49 | ||
| 48 | pub(crate) trait SealedChannel { | 50 | pub(crate) trait SealedChannel: StoppablePeripheral { |
| 49 | fn id(&self) -> u8; | 51 | fn id(&self) -> u8; |
| 50 | } | 52 | } |
| 51 | 53 | ||
| @@ -59,15 +61,28 @@ pub(crate) trait ChannelInterrupt { | |||
| 59 | pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {} | 61 | pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {} |
| 60 | 62 | ||
| 61 | macro_rules! dma_channel_impl { | 63 | macro_rules! dma_channel_impl { |
| 62 | ($channel_peri:ident, $index:expr) => { | 64 | ($channel_peri:ident, $index:expr, $stop_mode:ident) => { |
| 65 | impl crate::rcc::StoppablePeripheral for crate::peripherals::$channel_peri { | ||
| 66 | #[cfg(feature = "low-power")] | ||
| 67 | fn stop_mode(&self) -> crate::rcc::StopMode { | ||
| 68 | crate::rcc::StopMode::$stop_mode | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 63 | impl crate::dma::SealedChannel for crate::peripherals::$channel_peri { | 72 | impl crate::dma::SealedChannel for crate::peripherals::$channel_peri { |
| 64 | fn id(&self) -> u8 { | 73 | fn id(&self) -> u8 { |
| 65 | $index | 74 | $index |
| 66 | } | 75 | } |
| 67 | } | 76 | } |
| 77 | |||
| 68 | impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri { | 78 | impl crate::dma::ChannelInterrupt for crate::peripherals::$channel_peri { |
| 69 | unsafe fn on_irq() { | 79 | unsafe fn on_irq() { |
| 70 | crate::dma::AnyChannel { id: $index }.on_irq(); | 80 | crate::dma::AnyChannel { |
| 81 | id: $index, | ||
| 82 | #[cfg(feature = "low-power")] | ||
| 83 | stop_mode: crate::rcc::StopMode::$stop_mode, | ||
| 84 | } | ||
| 85 | .on_irq(); | ||
| 71 | } | 86 | } |
| 72 | } | 87 | } |
| 73 | 88 | ||
| @@ -77,6 +92,8 @@ macro_rules! dma_channel_impl { | |||
| 77 | fn from(val: crate::peripherals::$channel_peri) -> Self { | 92 | fn from(val: crate::peripherals::$channel_peri) -> Self { |
| 78 | Self { | 93 | Self { |
| 79 | id: crate::dma::SealedChannel::id(&val), | 94 | id: crate::dma::SealedChannel::id(&val), |
| 95 | #[cfg(feature = "low-power")] | ||
| 96 | stop_mode: crate::rcc::StoppablePeripheral::stop_mode(&val), | ||
| 80 | } | 97 | } |
| 81 | } | 98 | } |
| 82 | } | 99 | } |
| @@ -86,6 +103,8 @@ macro_rules! dma_channel_impl { | |||
| 86 | /// Type-erased DMA channel. | 103 | /// Type-erased DMA channel. |
| 87 | pub struct AnyChannel { | 104 | pub struct AnyChannel { |
| 88 | pub(crate) id: u8, | 105 | pub(crate) id: u8, |
| 106 | #[cfg(feature = "low-power")] | ||
| 107 | pub(crate) stop_mode: crate::rcc::StopMode, | ||
| 89 | } | 108 | } |
| 90 | impl_peripheral!(AnyChannel); | 109 | impl_peripheral!(AnyChannel); |
| 91 | 110 | ||
| @@ -95,6 +114,13 @@ impl AnyChannel { | |||
| 95 | } | 114 | } |
| 96 | } | 115 | } |
| 97 | 116 | ||
| 117 | impl StoppablePeripheral for AnyChannel { | ||
| 118 | #[cfg(feature = "low-power")] | ||
| 119 | fn stop_mode(&self) -> crate::rcc::StopMode { | ||
| 120 | self.stop_mode | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 98 | impl SealedChannel for AnyChannel { | 124 | impl SealedChannel for AnyChannel { |
| 99 | fn id(&self) -> u8 { | 125 | fn id(&self) -> u8 { |
| 100 | self.id | 126 | self.id |
diff --git a/embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs b/embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs index 661fb1728..eff5b4058 100644 --- a/embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs +++ b/embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs | |||
| @@ -2,7 +2,7 @@ use std::task::Waker; | |||
| 2 | 2 | ||
| 3 | use proptest::prop_oneof; | 3 | use proptest::prop_oneof; |
| 4 | use proptest::strategy::{self, BoxedStrategy, Strategy as _}; | 4 | use proptest::strategy::{self, BoxedStrategy, Strategy as _}; |
| 5 | use proptest_state_machine::{prop_state_machine, ReferenceStateMachine, StateMachineTest}; | 5 | use proptest_state_machine::{ReferenceStateMachine, StateMachineTest, prop_state_machine}; |
| 6 | 6 | ||
| 7 | use super::*; | 7 | use super::*; |
| 8 | 8 | ||
diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs index 3245887c1..304268963 100644 --- a/embassy-stm32/src/dma/util.rs +++ b/embassy-stm32/src/dma/util.rs | |||
| @@ -20,6 +20,16 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 20 | Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) | 20 | Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | #[allow(dead_code)] | ||
| 24 | pub unsafe fn read_unchecked<'a, W: Word>( | ||
| 25 | &'a self, | ||
| 26 | peri_addr: *mut W, | ||
| 27 | buf: &'a mut [W], | ||
| 28 | options: TransferOptions, | ||
| 29 | ) -> Transfer<'a> { | ||
| 30 | Transfer::new_read(self.channel.clone_unchecked(), self.request, peri_addr, buf, options) | ||
| 31 | } | ||
| 32 | |||
| 23 | pub unsafe fn read_raw<'a, MW: Word, PW: Word>( | 33 | pub unsafe fn read_raw<'a, MW: Word, PW: Word>( |
| 24 | &'a mut self, | 34 | &'a mut self, |
| 25 | peri_addr: *mut PW, | 35 | peri_addr: *mut PW, |
| @@ -29,6 +39,16 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 29 | Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) | 39 | Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) |
| 30 | } | 40 | } |
| 31 | 41 | ||
| 42 | #[allow(dead_code)] | ||
| 43 | pub unsafe fn read_raw_unchecked<'a, MW: Word, PW: Word>( | ||
| 44 | &'a self, | ||
| 45 | peri_addr: *mut PW, | ||
| 46 | buf: *mut [MW], | ||
| 47 | options: TransferOptions, | ||
| 48 | ) -> Transfer<'a> { | ||
| 49 | Transfer::new_read_raw(self.channel.clone_unchecked(), self.request, peri_addr, buf, options) | ||
| 50 | } | ||
| 51 | |||
| 32 | pub unsafe fn write<'a, W: Word>( | 52 | pub unsafe fn write<'a, W: Word>( |
| 33 | &'a mut self, | 53 | &'a mut self, |
| 34 | buf: &'a [W], | 54 | buf: &'a [W], |
| @@ -38,6 +58,16 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 38 | Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options) | 58 | Transfer::new_write(self.channel.reborrow(), self.request, buf, peri_addr, options) |
| 39 | } | 59 | } |
| 40 | 60 | ||
| 61 | #[allow(dead_code)] | ||
| 62 | pub unsafe fn write_unchecked<'a, W: Word>( | ||
| 63 | &'a self, | ||
| 64 | buf: &'a [W], | ||
| 65 | peri_addr: *mut W, | ||
| 66 | options: TransferOptions, | ||
| 67 | ) -> Transfer<'a> { | ||
| 68 | Transfer::new_write(self.channel.clone_unchecked(), self.request, buf, peri_addr, options) | ||
| 69 | } | ||
| 70 | |||
| 41 | pub unsafe fn write_raw<'a, MW: Word, PW: Word>( | 71 | pub unsafe fn write_raw<'a, MW: Word, PW: Word>( |
| 42 | &'a mut self, | 72 | &'a mut self, |
| 43 | buf: *const [MW], | 73 | buf: *const [MW], |
| @@ -48,6 +78,16 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 48 | } | 78 | } |
| 49 | 79 | ||
| 50 | #[allow(dead_code)] | 80 | #[allow(dead_code)] |
| 81 | pub unsafe fn write_raw_unchecked<'a, MW: Word, PW: Word>( | ||
| 82 | &'a self, | ||
| 83 | buf: *const [MW], | ||
| 84 | peri_addr: *mut PW, | ||
| 85 | options: TransferOptions, | ||
| 86 | ) -> Transfer<'a> { | ||
| 87 | Transfer::new_write_raw(self.channel.clone_unchecked(), self.request, buf, peri_addr, options) | ||
| 88 | } | ||
| 89 | |||
| 90 | #[allow(dead_code)] | ||
| 51 | pub unsafe fn write_repeated<'a, W: Word>( | 91 | pub unsafe fn write_repeated<'a, W: Word>( |
| 52 | &'a mut self, | 92 | &'a mut self, |
| 53 | repeated: &'a W, | 93 | repeated: &'a W, |
| @@ -64,4 +104,22 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 64 | options, | 104 | options, |
| 65 | ) | 105 | ) |
| 66 | } | 106 | } |
| 107 | |||
| 108 | #[allow(dead_code)] | ||
| 109 | pub unsafe fn write_repeated_unchecked<'a, W: Word>( | ||
| 110 | &'a self, | ||
| 111 | repeated: &'a W, | ||
| 112 | count: usize, | ||
| 113 | peri_addr: *mut W, | ||
| 114 | options: TransferOptions, | ||
| 115 | ) -> Transfer<'a> { | ||
| 116 | Transfer::new_write_repeated( | ||
| 117 | self.channel.clone_unchecked(), | ||
| 118 | self.request, | ||
| 119 | repeated, | ||
| 120 | count, | ||
| 121 | peri_addr, | ||
| 122 | options, | ||
| 123 | ) | ||
| 124 | } | ||
| 67 | } | 125 | } |
diff --git a/embassy-stm32/src/dma/word.rs b/embassy-stm32/src/dma/word.rs index fb1bde860..5c3bb8f7f 100644 --- a/embassy-stm32/src/dma/word.rs +++ b/embassy-stm32/src/dma/word.rs | |||
| @@ -31,6 +31,10 @@ pub trait Word: SealedWord + Default + Copy + 'static { | |||
| 31 | fn size() -> WordSize; | 31 | fn size() -> WordSize; |
| 32 | /// Amount of bits of this word size. | 32 | /// Amount of bits of this word size. |
| 33 | fn bits() -> usize; | 33 | fn bits() -> usize; |
| 34 | /// Maximum value of this type. | ||
| 35 | fn max() -> usize { | ||
| 36 | (1 << Self::bits()) - 1 | ||
| 37 | } | ||
| 34 | } | 38 | } |
| 35 | 39 | ||
| 36 | macro_rules! impl_word { | 40 | macro_rules! impl_word { |
