diff options
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/linked_list.rs | 22 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma/ringbuffered.rs | 7 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 5 |
3 files changed, 25 insertions, 9 deletions
diff --git a/embassy-stm32/src/dma/gpdma/linked_list.rs b/embassy-stm32/src/dma/gpdma/linked_list.rs index 627da0055..f7c1fbbed 100644 --- a/embassy-stm32/src/dma/gpdma/linked_list.rs +++ b/embassy-stm32/src/dma/gpdma/linked_list.rs | |||
| @@ -166,15 +166,27 @@ impl<const ITEM_COUNT: usize> Table<ITEM_COUNT> { | |||
| 166 | /// Create a ping-pong linked-list table. | 166 | /// Create a ping-pong linked-list table. |
| 167 | /// | 167 | /// |
| 168 | /// This uses two linked-list items, one for each half of the buffer. | 168 | /// This uses two linked-list items, one for each half of the buffer. |
| 169 | pub unsafe fn new_ping_pong<W: Word>(request: Request, peri_addr: *mut W, buffer: &mut [W]) -> Table<2> { | 169 | pub unsafe fn new_ping_pong<W: Word>( |
| 170 | request: Request, | ||
| 171 | peri_addr: *mut W, | ||
| 172 | buffer: &mut [W], | ||
| 173 | direction: Dir, | ||
| 174 | ) -> Table<2> { | ||
| 170 | // Buffer halves should be the same length. | 175 | // Buffer halves should be the same length. |
| 171 | let half_len = buffer.len() / 2; | 176 | let half_len = buffer.len() / 2; |
| 172 | assert_eq!(half_len * 2, buffer.len()); | 177 | assert_eq!(half_len * 2, buffer.len()); |
| 173 | 178 | ||
| 174 | let items = [ | 179 | let items = match direction { |
| 175 | LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), | 180 | Dir::MemoryToPeripheral => [ |
| 176 | LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), | 181 | LinearItem::new_write(request, &mut buffer[..half_len], peri_addr), |
| 177 | ]; | 182 | LinearItem::new_write(request, &mut buffer[half_len..], peri_addr), |
| 183 | ], | ||
| 184 | Dir::PeripheralToMemory => [ | ||
| 185 | LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), | ||
| 186 | LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), | ||
| 187 | ], | ||
| 188 | }; | ||
| 189 | |||
| 178 | Table::new(items) | 190 | Table::new(items) |
| 179 | } | 191 | } |
| 180 | 192 | ||
diff --git a/embassy-stm32/src/dma/gpdma/ringbuffered.rs b/embassy-stm32/src/dma/gpdma/ringbuffered.rs index 55486d5cc..9ee52193b 100644 --- a/embassy-stm32/src/dma/gpdma/ringbuffered.rs +++ b/embassy-stm32/src/dma/gpdma/ringbuffered.rs | |||
| @@ -12,7 +12,7 @@ use super::{AnyChannel, TransferOptions, STATE}; | |||
| 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, Request}; | 15 | use crate::dma::{Channel, Dir, Request}; |
| 16 | 16 | ||
| 17 | struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); | 17 | struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); |
| 18 | 18 | ||
| @@ -67,7 +67,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> { | |||
| 67 | options: TransferOptions, | 67 | options: TransferOptions, |
| 68 | ) -> Self { | 68 | ) -> Self { |
| 69 | let channel: Peri<'a, AnyChannel> = channel.into(); | 69 | let channel: Peri<'a, AnyChannel> = channel.into(); |
| 70 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer); | 70 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::PeripheralToMemory); |
| 71 | 71 | ||
| 72 | Self { | 72 | Self { |
| 73 | channel, | 73 | channel, |
| @@ -207,7 +207,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 207 | options: TransferOptions, | 207 | options: TransferOptions, |
| 208 | ) -> Self { | 208 | ) -> Self { |
| 209 | let channel: Peri<'a, AnyChannel> = channel.into(); | 209 | let channel: Peri<'a, AnyChannel> = channel.into(); |
| 210 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer); | 210 | let table = Table::<2>::new_ping_pong::<W>(request, peri_addr, buffer, Dir::MemoryToPeripheral); |
| 211 | 211 | ||
| 212 | Self { | 212 | Self { |
| 213 | channel, | 213 | channel, |
| @@ -222,6 +222,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { | |||
| 222 | // Apply the default configuration to the channel. | 222 | // Apply the default configuration to the channel. |
| 223 | unsafe { self.channel.configure_linked_list(&self.table, self.options) }; | 223 | unsafe { self.channel.configure_linked_list(&self.table, self.options) }; |
| 224 | self.table.link(RunMode::Circular); | 224 | self.table.link(RunMode::Circular); |
| 225 | |||
| 225 | self.channel.start(); | 226 | self.channel.start(); |
| 226 | } | 227 | } |
| 227 | 228 | ||
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index 030f906d2..5989bfd7c 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -28,10 +28,13 @@ use embassy_hal_internal::{impl_peripheral, PeripheralType}; | |||
| 28 | 28 | ||
| 29 | use crate::interrupt; | 29 | use crate::interrupt; |
| 30 | 30 | ||
| 31 | /// The direction of a DMA transfer. | ||
| 31 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] | 32 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
| 32 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 33 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 33 | enum Dir { | 34 | pub enum Dir { |
| 35 | /// Transfer from memory to a peripheral. | ||
| 34 | MemoryToPeripheral, | 36 | MemoryToPeripheral, |
| 37 | /// Transfer from a peripheral to memory. | ||
| 35 | PeripheralToMemory, | 38 | PeripheralToMemory, |
| 36 | } | 39 | } |
| 37 | 40 | ||
