aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/dma.rs43
1 files changed, 26 insertions, 17 deletions
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs
index 23cd8532f..820ce0051 100644
--- a/embassy-rp/src/dma.rs
+++ b/embassy-rp/src/dma.rs
@@ -25,30 +25,39 @@ unsafe fn DMA_IRQ_0() {
25 }); 25 });
26} 26}
27 27
28pub(crate) fn read<'a, C: Channel, W: Word>( 28pub fn read<'a, C: Channel, W: Word>(ch: impl Peripheral<P = C> + 'a, from: *const W, to: &mut [W]) -> Transfer<'a, C> {
29 ch: impl Peripheral<P = C> + 'a,
30 from: *const W,
31 to: *mut [W],
32) -> Transfer<'a, C> {
33 let (ptr, len) = crate::dma::slice_ptr_parts_mut(to); 29 let (ptr, len) = crate::dma::slice_ptr_parts_mut(to);
34 copy(ch, from as *const u32, ptr as *mut u32, len, W::size()) 30 copy_inner(ch, from as *const u32, ptr as *mut u32, len, W::size(), false, true)
35} 31}
36 32
37pub(crate) fn write<'a, C: Channel, W: Word>( 33pub fn write<'a, C: Channel, W: Word>(ch: impl Peripheral<P = C> + 'a, from: &[W], to: *mut W) -> Transfer<'a, C> {
38 ch: impl Peripheral<P = C> + 'a,
39 from: *const [W],
40 to: *mut W,
41) -> Transfer<'a, C> {
42 let (from_ptr, len) = crate::dma::slice_ptr_parts(from); 34 let (from_ptr, len) = crate::dma::slice_ptr_parts(from);
43 copy(ch, from_ptr as *const u32, to as *mut u32, len, W::size()) 35 copy_inner(ch, from_ptr as *const u32, to as *mut u32, len, W::size(), true, false)
36}
37
38pub fn copy<'a, C: Channel, W: Word>(ch: impl Peripheral<P = C> + 'a, from: &[W], to: &mut [W]) -> Transfer<'a, C> {
39 let (from_ptr, from_len) = crate::dma::slice_ptr_parts(from);
40 let (to_ptr, to_len) = crate::dma::slice_ptr_parts_mut(to);
41 assert_eq!(from_len, to_len);
42 copy_inner(
43 ch,
44 from_ptr as *const u32,
45 to_ptr as *mut u32,
46 from_len,
47 W::size(),
48 true,
49 true,
50 )
44} 51}
45 52
46fn copy<'a, C: Channel>( 53fn copy_inner<'a, C: Channel>(
47 ch: impl Peripheral<P = C> + 'a, 54 ch: impl Peripheral<P = C> + 'a,
48 from: *const u32, 55 from: *const u32,
49 to: *mut u32, 56 to: *mut u32,
50 len: usize, 57 len: usize,
51 data_size: DataSize, 58 data_size: DataSize,
59 incr_read: bool,
60 incr_write: bool,
52) -> Transfer<'a, C> { 61) -> Transfer<'a, C> {
53 into_ref!(ch); 62 into_ref!(ch);
54 63
@@ -63,8 +72,8 @@ fn copy<'a, C: Channel>(
63 72
64 p.ctrl_trig().write(|w| { 73 p.ctrl_trig().write(|w| {
65 w.set_data_size(data_size); 74 w.set_data_size(data_size);
66 w.set_incr_read(false); 75 w.set_incr_read(incr_read);
67 w.set_incr_write(true); 76 w.set_incr_write(incr_write);
68 w.set_chain_to(ch.number()); 77 w.set_chain_to(ch.number());
69 w.set_en(true); 78 w.set_en(true);
70 }); 79 });
@@ -74,7 +83,7 @@ fn copy<'a, C: Channel>(
74 Transfer::new(ch) 83 Transfer::new(ch)
75} 84}
76 85
77pub(crate) struct Transfer<'a, C: Channel> { 86pub struct Transfer<'a, C: Channel> {
78 channel: PeripheralRef<'a, C>, 87 channel: PeripheralRef<'a, C>,
79} 88}
80 89
@@ -114,7 +123,7 @@ impl<'a, C: Channel> Future for Transfer<'a, C> {
114 // calls to wake will deregister the waker. 123 // calls to wake will deregister the waker.
115 CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker()); 124 CHANNEL_WAKERS[self.channel.number() as usize].register(cx.waker());
116 125
117 if unsafe { self.channel.regs().ctrl_trig().read().en() } { 126 if unsafe { self.channel.regs().ctrl_trig().read().busy() } {
118 Poll::Pending 127 Poll::Pending
119 } else { 128 } else {
120 Poll::Ready(()) 129 Poll::Ready(())