aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32/src/dma
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32/src/dma')
-rw-r--r--embassy-stm32/src/dma/dma_bdma.rs19
-rw-r--r--embassy-stm32/src/dma/gpdma/mod.rs20
-rw-r--r--embassy-stm32/src/dma/gpdma/ringbuffered.rs13
-rw-r--r--embassy-stm32/src/dma/mod.rs34
-rw-r--r--embassy-stm32/src/dma/ringbuffer/tests/prop_test/mod.rs2
-rw-r--r--embassy-stm32/src/dma/util.rs58
-rw-r--r--embassy-stm32/src/dma/word.rs4
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 @@
1use core::future::{poll_fn, Future}; 1use core::future::{Future, poll_fn};
2use core::pin::Pin; 2use core::pin::Pin;
3use core::sync::atomic::{fence, AtomicUsize, Ordering}; 3use core::sync::atomic::{AtomicUsize, Ordering, fence};
4use core::task::{Context, Poll, Waker}; 4use core::task::{Context, Poll, Waker};
5 5
6use embassy_hal_internal::Peri; 6use embassy_hal_internal::Peri;
@@ -10,6 +10,7 @@ use super::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBu
10use super::word::{Word, WordSize}; 10use super::word::{Word, WordSize};
11use super::{AnyChannel, Channel, Dir, Request, STATE}; 11use super::{AnyChannel, Channel, Dir, Request, STATE};
12use crate::interrupt::typelevel::Interrupt; 12use crate::interrupt::typelevel::Interrupt;
13use crate::rcc::BusyPeripheral;
13use crate::{interrupt, pac}; 14use crate::{interrupt, pac};
14 15
15pub(crate) struct ChannelInfo { 16pub(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"]
604pub struct Transfer<'a> { 605pub struct Transfer<'a> {
605 channel: Peri<'a, AnyChannel>, 606 channel: BusyPeripheral<Peri<'a, AnyChannel>>,
606} 607}
607 608
608impl<'a> Transfer<'a> { 609impl<'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.
818pub struct ReadableRingBuffer<'a, W: Word> { 821pub 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.
974pub struct WritableRingBuffer<'a, W: Word> { 977pub 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
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,
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))]
5mod dma_bdma; 5mod dma_bdma;
6
6#[cfg(any(bdma, dma))] 7#[cfg(any(bdma, dma))]
7pub use dma_bdma::*; 8pub use dma_bdma::*;
8 9
@@ -24,9 +25,10 @@ pub(crate) use util::*;
24pub(crate) mod ringbuffer; 25pub(crate) mod ringbuffer;
25pub mod word; 26pub mod word;
26 27
27use embassy_hal_internal::{impl_peripheral, PeripheralType}; 28use embassy_hal_internal::{PeripheralType, impl_peripheral};
28 29
29use crate::interrupt; 30use crate::interrupt;
31use 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)))]
46pub type Request = (); 48pub type Request = ();
47 49
48pub(crate) trait SealedChannel { 50pub(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 {
59pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {} 61pub trait Channel: SealedChannel + PeripheralType + Into<AnyChannel> + 'static {}
60 62
61macro_rules! dma_channel_impl { 63macro_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.
87pub struct AnyChannel { 104pub 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}
90impl_peripheral!(AnyChannel); 109impl_peripheral!(AnyChannel);
91 110
@@ -95,6 +114,13 @@ impl AnyChannel {
95 } 114 }
96} 115}
97 116
117impl StoppablePeripheral for AnyChannel {
118 #[cfg(feature = "low-power")]
119 fn stop_mode(&self) -> crate::rcc::StopMode {
120 self.stop_mode
121 }
122}
123
98impl SealedChannel for AnyChannel { 124impl 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
3use proptest::prop_oneof; 3use proptest::prop_oneof;
4use proptest::strategy::{self, BoxedStrategy, Strategy as _}; 4use proptest::strategy::{self, BoxedStrategy, Strategy as _};
5use proptest_state_machine::{prop_state_machine, ReferenceStateMachine, StateMachineTest}; 5use proptest_state_machine::{ReferenceStateMachine, StateMachineTest, prop_state_machine};
6 6
7use super::*; 7use 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
36macro_rules! impl_word { 40macro_rules! impl_word {