aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/gpdma/linked_list.rs20
-rw-r--r--embassy-stm32/src/dma/gpdma/mod.rs22
-rw-r--r--embassy-stm32/src/dma/gpdma/ringbuffered.rs16
-rw-r--r--embassy-stm32/src/sai/mod.rs5
-rw-r--r--embassy-stm32/src/usart/ringbuffered.rs3
5 files changed, 56 insertions, 10 deletions
diff --git a/embassy-stm32/src/dma/gpdma/linked_list.rs b/embassy-stm32/src/dma/gpdma/linked_list.rs
index a95e5590e..76381def3 100644
--- a/embassy-stm32/src/dma/gpdma/linked_list.rs
+++ b/embassy-stm32/src/dma/gpdma/linked_list.rs
@@ -4,6 +4,7 @@
4use stm32_metapac::gpdma::regs; 4use stm32_metapac::gpdma::regs;
5use stm32_metapac::gpdma::vals::Dreq; 5use stm32_metapac::gpdma::vals::Dreq;
6 6
7use super::RegisterUpdaters;
7use crate::dma::word::{Word, WordSize}; 8use crate::dma::word::{Word, WordSize};
8use crate::dma::{Dir, Request}; 9use crate::dma::{Dir, Request};
9 10
@@ -41,7 +42,12 @@ pub struct LinearItem {
41 42
42impl LinearItem { 43impl LinearItem {
43 /// Create a new read DMA transfer (peripheral to memory). 44 /// Create a new read DMA transfer (peripheral to memory).
44 pub unsafe fn new_read<'d, W: Word>(request: Request, peri_addr: *mut W, buf: &'d mut [W]) -> Self { 45 pub unsafe fn new_read<'d, W: Word>(
46 request: Request,
47 peri_addr: *mut W,
48 buf: &'d mut [W],
49 register_updaters: &RegisterUpdaters,
50 ) -> Self {
45 Self::new_inner( 51 Self::new_inner(
46 request, 52 request,
47 Dir::PeripheralToMemory, 53 Dir::PeripheralToMemory,
@@ -51,11 +57,17 @@ impl LinearItem {
51 true, 57 true,
52 W::size(), 58 W::size(),
53 W::size(), 59 W::size(),
60 register_updaters,
54 ) 61 )
55 } 62 }
56 63
57 /// Create a new write DMA transfer (memory to peripheral). 64 /// Create a new write DMA transfer (memory to peripheral).
58 pub unsafe fn new_write<'d, MW: Word, PW: Word>(request: Request, buf: &'d [MW], peri_addr: *mut PW) -> Self { 65 pub unsafe fn new_write<'d, MW: Word, PW: Word>(
66 request: Request,
67 buf: &'d [MW],
68 peri_addr: *mut PW,
69 register_updaters: &RegisterUpdaters,
70 ) -> Self {
59 Self::new_inner( 71 Self::new_inner(
60 request, 72 request,
61 Dir::MemoryToPeripheral, 73 Dir::MemoryToPeripheral,
@@ -65,6 +77,7 @@ impl LinearItem {
65 true, 77 true,
66 MW::size(), 78 MW::size(),
67 PW::size(), 79 PW::size(),
80 register_updaters,
68 ) 81 )
69 } 82 }
70 83
@@ -77,6 +90,7 @@ impl LinearItem {
77 incr_mem: bool, 90 incr_mem: bool,
78 data_size: WordSize, 91 data_size: WordSize,
79 dst_size: WordSize, 92 dst_size: WordSize,
93 register_updaters: &RegisterUpdaters,
80 ) -> Self { 94 ) -> Self {
81 // BNDT is specified as bytes, not as number of transfers. 95 // BNDT is specified as bytes, not as number of transfers.
82 let Ok(bndt) = (mem_len * data_size.bytes()).try_into() else { 96 let Ok(bndt) = (mem_len * data_size.bytes()).try_into() else {
@@ -91,6 +105,7 @@ impl LinearItem {
91 tr1.set_ddw(dst_size.into()); 105 tr1.set_ddw(dst_size.into());
92 tr1.set_sinc(dir == Dir::MemoryToPeripheral && incr_mem); 106 tr1.set_sinc(dir == Dir::MemoryToPeripheral && incr_mem);
93 tr1.set_dinc(dir == Dir::PeripheralToMemory && incr_mem); 107 tr1.set_dinc(dir == Dir::PeripheralToMemory && incr_mem);
108 (register_updaters.tr1)(&mut tr1);
94 109
95 let mut tr2 = regs::ChTr2(0); 110 let mut tr2 = regs::ChTr2(0);
96 tr2.set_dreq(match dir { 111 tr2.set_dreq(match dir {
@@ -98,6 +113,7 @@ impl LinearItem {
98 Dir::PeripheralToMemory => Dreq::SOURCE_PERIPHERAL, 113 Dir::PeripheralToMemory => Dreq::SOURCE_PERIPHERAL,
99 }); 114 });
100 tr2.set_reqsel(request); 115 tr2.set_reqsel(request);
116 (register_updaters.tr2)(&mut tr2);
101 117
102 let (sar, dar) = match dir { 118 let (sar, dar) = match dir {
103 Dir::MemoryToPeripheral => (mem_addr as _, peri_addr as _), 119 Dir::MemoryToPeripheral => (mem_addr as _, peri_addr as _),
diff --git a/embassy-stm32/src/dma/gpdma/mod.rs b/embassy-stm32/src/dma/gpdma/mod.rs
index 604db2852..58f93ffb0 100644
--- a/embassy-stm32/src/dma/gpdma/mod.rs
+++ b/embassy-stm32/src/dma/gpdma/mod.rs
@@ -73,6 +73,28 @@ impl Default for TransferOptions {
73 } 73 }
74} 74}
75 75
76/// GPDMA linked-list item register updater functions.
77#[derive(Debug, Copy, Clone)]
78#[cfg_attr(feature = "defmt", derive(defmt::Format))]
79pub struct RegisterUpdaters {
80 /// Function used to overwrite transfer register 1.
81 pub tr1: fn(&mut pac::gpdma::regs::ChTr1),
82 /// Function used to overwrite transfer register 2.
83 pub tr2: fn(&mut pac::gpdma::regs::ChTr2),
84 /// Function used to overwrite transfer register 3.
85 pub tr3: fn(&mut pac::gpdma::regs::ChTr3),
86}
87
88impl Default for RegisterUpdaters {
89 fn default() -> Self {
90 Self {
91 tr1: |_| {},
92 tr2: |_| {},
93 tr3: |_| {},
94 }
95 }
96}
97
76impl From<WordSize> for vals::Dw { 98impl From<WordSize> for vals::Dw {
77 fn from(raw: WordSize) -> Self { 99 fn from(raw: WordSize) -> Self {
78 match raw { 100 match raw {
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
index c74c7bd2b..dfc031627 100644
--- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs
+++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs
@@ -8,7 +8,7 @@ use 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, RegisterUpdaters, TransferOptions, STATE};
12use crate::dma::gpdma::linked_list::{LinearItem, RunMode, Table}; 12use crate::dma::gpdma::linked_list::{LinearItem, 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;
@@ -52,6 +52,7 @@ pub struct ReadableRingBuffer<'a, W: Word> {
52 channel: Peri<'a, AnyChannel>, 52 channel: Peri<'a, AnyChannel>,
53 ringbuf: ReadableDmaRingBuffer<'a, W>, 53 ringbuf: ReadableDmaRingBuffer<'a, W>,
54 table: Table<2>, 54 table: Table<2>,
55 options: TransferOptions,
55} 56}
56 57
57impl<'a, W: Word> ReadableRingBuffer<'a, W> { 58impl<'a, W: Word> ReadableRingBuffer<'a, W> {
@@ -64,6 +65,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
64 peri_addr: *mut W, 65 peri_addr: *mut W,
65 buffer: &'a mut [W], 66 buffer: &'a mut [W],
66 options: TransferOptions, 67 options: TransferOptions,
68 register_updaters: RegisterUpdaters,
67 ) -> Self { 69 ) -> Self {
68 let channel: Peri<'a, AnyChannel> = channel.into(); 70 let channel: Peri<'a, AnyChannel> = channel.into();
69 71
@@ -72,8 +74,8 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
72 assert_eq!(half_len * 2, buffer.len()); 74 assert_eq!(half_len * 2, buffer.len());
73 75
74 let items = [ 76 let items = [
75 LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), 77 LinearItem::new_read(request, peri_addr, &mut buffer[..half_len], &register_updaters),
76 LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), 78 LinearItem::new_read(request, peri_addr, &mut buffer[half_len..], &register_updaters),
77 ]; 79 ];
78 let table = Table::new(items); 80 let table = Table::new(items);
79 81
@@ -84,6 +86,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> {
84 channel, 86 channel,
85 ringbuf: ReadableDmaRingBuffer::new(buffer), 87 ringbuf: ReadableDmaRingBuffer::new(buffer),
86 table, 88 table,
89 options,
87 } 90 }
88 } 91 }
89 92
@@ -211,6 +214,7 @@ pub struct WritableRingBuffer<'a, W: Word> {
211 channel: Peri<'a, AnyChannel>, 214 channel: Peri<'a, AnyChannel>,
212 ringbuf: WritableDmaRingBuffer<'a, W>, 215 ringbuf: WritableDmaRingBuffer<'a, W>,
213 table: Table<2>, 216 table: Table<2>,
217 options: TransferOptions,
214} 218}
215 219
216impl<'a, W: Word> WritableRingBuffer<'a, W> { 220impl<'a, W: Word> WritableRingBuffer<'a, W> {
@@ -221,6 +225,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
221 peri_addr: *mut W, 225 peri_addr: *mut W,
222 buffer: &'a mut [W], 226 buffer: &'a mut [W],
223 options: TransferOptions, 227 options: TransferOptions,
228 register_updaters: RegisterUpdaters,
224 ) -> Self { 229 ) -> Self {
225 let channel: Peri<'a, AnyChannel> = channel.into(); 230 let channel: Peri<'a, AnyChannel> = channel.into();
226 231
@@ -229,8 +234,8 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
229 assert_eq!(half_len * 2, buffer.len()); 234 assert_eq!(half_len * 2, buffer.len());
230 235
231 let items = [ 236 let items = [
232 LinearItem::new_write(request, &mut buffer[..half_len], peri_addr), 237 LinearItem::new_write(request, &mut buffer[..half_len], peri_addr, &register_updaters),
233 LinearItem::new_write(request, &mut buffer[half_len..], peri_addr), 238 LinearItem::new_write(request, &mut buffer[half_len..], peri_addr, &register_updaters),
234 ]; 239 ];
235 let table = Table::new(items); 240 let table = Table::new(items);
236 241
@@ -241,6 +246,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> {
241 channel, 246 channel,
242 ringbuf: WritableDmaRingBuffer::new(buffer), 247 ringbuf: WritableDmaRingBuffer::new(buffer),
243 table, 248 table,
249 options,
244 }; 250 };
245 251
246 this 252 this
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs
index 88cc225dd..ac1ab2505 100644
--- a/embassy-stm32/src/sai/mod.rs
+++ b/embassy-stm32/src/sai/mod.rs
@@ -687,12 +687,13 @@ fn get_ring_buffer<'d, T: Instance, W: word::Word>(
687 //the new_write() and new_read() always use circular mode 687 //the new_write() and new_read() always use circular mode
688 ..Default::default() 688 ..Default::default()
689 }; 689 };
690 let updaters = Default::default();
690 match tx_rx { 691 match tx_rx {
691 TxRx::Transmitter => RingBuffer::Writable(unsafe { 692 TxRx::Transmitter => RingBuffer::Writable(unsafe {
692 WritableRingBuffer::new(dma, request, dr(T::REGS, sub_block), dma_buf, opts) 693 WritableRingBuffer::new(dma, request, dr(T::REGS, sub_block), dma_buf, opts, updaters)
693 }), 694 }),
694 TxRx::Receiver => RingBuffer::Readable(unsafe { 695 TxRx::Receiver => RingBuffer::Readable(unsafe {
695 ReadableRingBuffer::new(dma, request, dr(T::REGS, sub_block), dma_buf, opts) 696 ReadableRingBuffer::new(dma, request, dr(T::REGS, sub_block), dma_buf, opts, updaters)
696 }), 697 }),
697 } 698 }
698} 699}
diff --git a/embassy-stm32/src/usart/ringbuffered.rs b/embassy-stm32/src/usart/ringbuffered.rs
index bea56c991..78bf4b72f 100644
--- a/embassy-stm32/src/usart/ringbuffered.rs
+++ b/embassy-stm32/src/usart/ringbuffered.rs
@@ -103,6 +103,7 @@ impl<'d> UartRx<'d, Async> {
103 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF); 103 assert!(!dma_buf.is_empty() && dma_buf.len() <= 0xFFFF);
104 104
105 let opts = Default::default(); 105 let opts = Default::default();
106 let updaters = Default::default();
106 107
107 // Safety: we forget the struct before this function returns. 108 // Safety: we forget the struct before this function returns.
108 let rx_dma = self.rx_dma.as_mut().unwrap(); 109 let rx_dma = self.rx_dma.as_mut().unwrap();
@@ -112,7 +113,7 @@ impl<'d> UartRx<'d, Async> {
112 let info = self.info; 113 let info = self.info;
113 let state = self.state; 114 let state = self.state;
114 let kernel_clock = self.kernel_clock; 115 let kernel_clock = self.kernel_clock;
115 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts) }; 116 let ring_buf = unsafe { ReadableRingBuffer::new(rx_dma, request, rdr(info.regs), dma_buf, opts, updaters) };
116 let rx = unsafe { self.rx.as_ref().map(|x| x.clone_unchecked()) }; 117 let rx = unsafe { self.rx.as_ref().map(|x| x.clone_unchecked()) };
117 let rts = unsafe { self.rts.as_ref().map(|x| x.clone_unchecked()) }; 118 let rts = unsafe { self.rts.as_ref().map(|x| x.clone_unchecked()) };
118 119