From 2102dba83b3254b77c12a23fd17853cbf985233f Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 16 Dec 2025 11:27:20 -0800 Subject: [iMXRT] dma: define MAX_CHUNK_SIZE constant Instead of adding magic constants all over the place, let's just define DMA MAX_CHUNK_SIZE in a single constant that be referenced by the various users. --- embassy-imxrt/src/dma.rs | 2 ++ embassy-imxrt/src/flexcomm/uart.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/embassy-imxrt/src/dma.rs b/embassy-imxrt/src/dma.rs index e71a27e0e..76c9953c1 100644 --- a/embassy-imxrt/src/dma.rs +++ b/embassy-imxrt/src/dma.rs @@ -16,6 +16,8 @@ use crate::peripherals::DMA0; use crate::sealed::Sealed; use crate::{BitIter, interrupt, pac, peripherals}; +pub(crate) const MAX_CHUNK_SIZE: usize = 1024; + #[cfg(feature = "rt")] #[interrupt] fn DMA0() { diff --git a/embassy-imxrt/src/flexcomm/uart.rs b/embassy-imxrt/src/flexcomm/uart.rs index 2b759ba84..d13b32e93 100644 --- a/embassy-imxrt/src/flexcomm/uart.rs +++ b/embassy-imxrt/src/flexcomm/uart.rs @@ -598,7 +598,7 @@ impl<'a> UartTx<'a, Async> { regs.fifocfg().modify(|_, w| w.dmatx().disabled()); }); - for chunk in buf.chunks(1024) { + for chunk in buf.chunks(dma::MAX_CHUNK_SIZE) { regs.fifocfg().modify(|_, w| w.dmatx().enabled()); let ch = self.tx_dma.as_mut().unwrap().reborrow(); @@ -726,7 +726,7 @@ impl<'a> UartRx<'a, Async> { regs.fifocfg().modify(|_, w| w.dmarx().disabled()); }); - for chunk in buf.chunks_mut(1024) { + for chunk in buf.chunks_mut(dma::MAX_CHUNK_SIZE) { regs.fifocfg().modify(|_, w| w.dmarx().enabled()); let ch = self.rx_dma.as_mut().unwrap().reborrow(); -- cgit From 772c9f951b5ee292089670d9b489314d75f8a92a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 16 Dec 2025 11:28:31 -0800 Subject: [iMXRT] dma: fix transfer count computation count should be defined as the integer div_round_up of buffer length and word size, otherwise transferring small buffers will cause a panic due to underflow: if we let from = [0u32; 1]; then calling dma::write() will result in: let count = ((1 / 4 as usize) - 1) = 0 - 1 // underflow Rounding up results in 1 - 1 as expected. --- embassy-imxrt/src/dma.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/embassy-imxrt/src/dma.rs b/embassy-imxrt/src/dma.rs index 76c9953c1..eaa09870d 100644 --- a/embassy-imxrt/src/dma.rs +++ b/embassy-imxrt/src/dma.rs @@ -71,7 +71,7 @@ pub(crate) unsafe fn init() { /// /// SAFETY: Slice must point to a valid location reachable by DMA. pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: *mut [W]) -> Transfer<'a, C> { - let count = ((to.len() / W::size() as usize) - 1) as isize; + let count = (to.len().div_ceil(W::size() as usize) - 1) as isize; copy_inner( ch, @@ -89,7 +89,7 @@ pub unsafe fn read<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const W, to: /// /// SAFETY: Slice must point to a valid location reachable by DMA. pub unsafe fn write<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: *const [W], to: *mut W) -> Transfer<'a, C> { - let count = ((from.len() / W::size() as usize) - 1) as isize; + let count = (from.len().div_ceil(W::size() as usize) - 1) as isize; copy_inner( ch, @@ -111,7 +111,7 @@ pub unsafe fn copy<'a, C: Channel, W: Word>(ch: Peri<'a, C>, from: &[W], to: &mu let to_len = to.len(); assert_eq!(from_len, to_len); - let count = ((from_len / W::size() as usize) - 1) as isize; + let count = (from_len.div_ceil(W::size() as usize) - 1) as isize; copy_inner( ch, -- cgit