From 2e2562d8dc38844b9907e282f6c098e6ac2fd096 Mon Sep 17 00:00:00 2001 From: Adrian Figueroa Date: Tue, 26 Aug 2025 23:11:18 +0200 Subject: fix: ping-pong helper DMA direction --- embassy-stm32/src/dma/gpdma/linked_list.rs | 22 +++++++++++++++++----- embassy-stm32/src/dma/gpdma/ringbuffered.rs | 7 ++++--- 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 Table { /// Create a ping-pong linked-list table. /// /// This uses two linked-list items, one for each half of the buffer. - pub unsafe fn new_ping_pong(request: Request, peri_addr: *mut W, buffer: &mut [W]) -> Table<2> { + pub unsafe fn new_ping_pong( + request: Request, + peri_addr: *mut W, + buffer: &mut [W], + direction: Dir, + ) -> Table<2> { // Buffer halves should be the same length. let half_len = buffer.len() / 2; assert_eq!(half_len * 2, buffer.len()); - let items = [ - LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), - LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), - ]; + let items = match direction { + Dir::MemoryToPeripheral => [ + LinearItem::new_write(request, &mut buffer[..half_len], peri_addr), + LinearItem::new_write(request, &mut buffer[half_len..], peri_addr), + ], + Dir::PeripheralToMemory => [ + LinearItem::new_read(request, peri_addr, &mut buffer[..half_len]), + LinearItem::new_read(request, peri_addr, &mut buffer[half_len..]), + ], + }; + Table::new(items) } 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}; use crate::dma::gpdma::linked_list::{RunMode, Table}; use crate::dma::ringbuffer::{DmaCtrl, Error, ReadableDmaRingBuffer, WritableDmaRingBuffer}; use crate::dma::word::Word; -use crate::dma::{Channel, Request}; +use crate::dma::{Channel, Dir, Request}; struct DmaCtrlImpl<'a>(Peri<'a, AnyChannel>); @@ -67,7 +67,7 @@ impl<'a, W: Word> ReadableRingBuffer<'a, W> { options: TransferOptions, ) -> Self { let channel: Peri<'a, AnyChannel> = channel.into(); - let table = Table::<2>::new_ping_pong::(request, peri_addr, buffer); + let table = Table::<2>::new_ping_pong::(request, peri_addr, buffer, Dir::PeripheralToMemory); Self { channel, @@ -207,7 +207,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { options: TransferOptions, ) -> Self { let channel: Peri<'a, AnyChannel> = channel.into(); - let table = Table::<2>::new_ping_pong::(request, peri_addr, buffer); + let table = Table::<2>::new_ping_pong::(request, peri_addr, buffer, Dir::MemoryToPeripheral); Self { channel, @@ -222,6 +222,7 @@ impl<'a, W: Word> WritableRingBuffer<'a, W> { // Apply the default configuration to the channel. unsafe { self.channel.configure_linked_list(&self.table, self.options) }; self.table.link(RunMode::Circular); + self.channel.start(); } 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}; use crate::interrupt; +/// The direction of a DMA transfer. #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -enum Dir { +pub enum Dir { + /// Transfer from memory to a peripheral. MemoryToPeripheral, + /// Transfer from a peripheral to memory. PeripheralToMemory, } -- cgit