From bb91c05e1e331fe83bf0c99d0c4b1e799faf2238 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Mon, 11 Nov 2024 19:27:49 +0100 Subject: [PATCH 1/2] DMA - Rename stream to channel --- examples/adc-continious-dma.rs | 6 +- examples/adc-one-shot-dma.rs | 8 +- examples/spi-dma.rs | 13 +- examples/uart-dma-rx.rs | 6 +- examples/uart-dma-tx.rs | 6 +- src/dma.rs | 6 +- src/dma/{stream.rs => channel.rs} | 188 ++++++++++--------------- src/dma/config.rs | 10 +- src/dma/traits.rs | 78 +++++------ src/dma/transfer.rs | 220 +++++++++++++++--------------- 10 files changed, 247 insertions(+), 294 deletions(-) rename src/dma/{stream.rs => channel.rs} (83%) diff --git a/examples/adc-continious-dma.rs b/examples/adc-continious-dma.rs index e7ceb824..78313778 100644 --- a/examples/adc-continious-dma.rs +++ b/examples/adc-continious-dma.rs @@ -10,7 +10,7 @@ use crate::hal::{ AdcClaim, ClockSource, Temperature, Vref, }, delay::SYSTDelayExt, - dma::{config::DmaConfig, stream::DMAExt, TransferExt}, + dma::{channel::DMAExt, config::DmaConfig, TransferExt}, gpio::GpioExt, pwr::PwrExt, rcc::{Config, RccExt}, @@ -36,7 +36,7 @@ fn main() -> ! { let pwr = dp.PWR.constrain().freeze(); let mut rcc = rcc.freeze(Config::hsi(), pwr); - let streams = dp.DMA1.split(&rcc); + let channels = dp.DMA1.split(&rcc); let config = DmaConfig::default() .transfer_complete_interrupt(false) .circular_buffer(true) @@ -62,7 +62,7 @@ fn main() -> ! { info!("Setup DMA"); let first_buffer = cortex_m::singleton!(: [u16; 15] = [0; 15]).unwrap(); - let mut transfer = streams.0.into_circ_peripheral_to_memory_transfer( + let mut transfer = channels.0.into_circ_peripheral_to_memory_transfer( adc.enable_dma(AdcDma::Continuous), &mut first_buffer[..], config, diff --git a/examples/adc-one-shot-dma.rs b/examples/adc-one-shot-dma.rs index 898e7f02..b2ff3374 100644 --- a/examples/adc-one-shot-dma.rs +++ b/examples/adc-one-shot-dma.rs @@ -9,7 +9,7 @@ use crate::hal::{ AdcClaim, ClockSource, Temperature, }, delay::SYSTDelayExt, - dma::{config::DmaConfig, stream::DMAExt, TransferExt}, + dma::{channel::DMAExt, config::DmaConfig, TransferExt}, gpio::GpioExt, pwr::PwrExt, rcc::{Config, RccExt}, @@ -37,7 +37,7 @@ fn main() -> ! { let pwr = dp.PWR.constrain().freeze(); let mut rcc = rcc.freeze(Config::hsi(), pwr); - let mut streams = dp.DMA1.split(&rcc); + let mut channels = dp.DMA1.split(&rcc); let config = DmaConfig::default() .transfer_complete_interrupt(false) .circular_buffer(false) @@ -61,7 +61,7 @@ fn main() -> ! { info!("Setup DMA"); let first_buffer = cortex_m::singleton!(: [u16; 2] = [0; 2]).unwrap(); - let mut transfer = streams.0.into_peripheral_to_memory_transfer( + let mut transfer = channels.0.into_peripheral_to_memory_transfer( adc.enable_dma(AdcDma::Single), &mut first_buffer[..], config, @@ -77,7 +77,7 @@ fn main() -> ! { let (s0, adc, first_buffer) = transfer.free(); let adc = adc.disable(); - streams.0 = s0; + channels.0 = s0; let millivolts = adc.sample_to_millivolts(first_buffer[0]); info!("pa3: {}mV", millivolts); diff --git a/examples/spi-dma.rs b/examples/spi-dma.rs index 04533e3f..f1624c2c 100644 --- a/examples/spi-dma.rs +++ b/examples/spi-dma.rs @@ -22,8 +22,8 @@ use crate::hal::{ use cortex_m_rt::entry; use stm32g4xx_hal as hal; +use stm32g4xx_hal::dma::channel::DMAExt; use stm32g4xx_hal::dma::config::DmaConfig; -use stm32g4xx_hal::dma::stream::DMAExt; use stm32g4xx_hal::dma::TransferExt; #[macro_use] @@ -50,7 +50,7 @@ fn main() -> ! { let spi = dp .SPI1 .spi((sclk, miso, mosi), spi::MODE_0, 400.kHz(), &mut rcc); - let streams = dp.DMA1.split(&rcc); + let channels = dp.DMA1.split(&rcc); let config = DmaConfig::default() .transfer_complete_interrupt(false) .circular_buffer(true) @@ -62,10 +62,11 @@ fn main() -> ! { *item = index as u8; } let dma_buf = cortex_m::singleton!(: [u8; BUFFER_SIZE] = buf).unwrap(); - let mut transfer_dma = - streams - .0 - .into_memory_to_peripheral_transfer(spi.enable_tx_dma(), &mut dma_buf[..], config); + let mut transfer_dma = channels.0.into_memory_to_peripheral_transfer( + spi.enable_tx_dma(), + &mut dma_buf[..], + config, + ); transfer_dma.start(|_spi| {}); loop { delay_tim2.delay_ms(1000_u16); diff --git a/examples/uart-dma-rx.rs b/examples/uart-dma-rx.rs index 5a1742fb..84ad40e3 100644 --- a/examples/uart-dma-rx.rs +++ b/examples/uart-dma-rx.rs @@ -5,7 +5,7 @@ extern crate cortex_m_rt as rt; -use hal::dma::{config::DmaConfig, stream::DMAExt, TransferExt}; +use hal::dma::{channel::DMAExt, config::DmaConfig, TransferExt}; use hal::prelude::*; use hal::pwr::PwrExt; use hal::serial::*; @@ -30,7 +30,7 @@ fn main() -> ! { let pwr = dp.PWR.constrain().freeze(); let mut rcc = rcc.freeze(rcc::Config::hsi(), pwr); - let streams = dp.DMA1.split(&rcc); + let channels = dp.DMA1.split(&rcc); let config = DmaConfig::default() .transfer_complete_interrupt(false) .circular_buffer(true) @@ -65,7 +65,7 @@ fn main() -> ! { let (_tx, rx) = usart.split(); - let mut transfer = streams.0.into_circ_peripheral_to_memory_transfer( + let mut transfer = channels.0.into_circ_peripheral_to_memory_transfer( rx.enable_dma(), &mut rx_buffer[..], config, diff --git a/examples/uart-dma-tx.rs b/examples/uart-dma-tx.rs index 78abeb4f..8a1a7fed 100644 --- a/examples/uart-dma-tx.rs +++ b/examples/uart-dma-tx.rs @@ -7,7 +7,7 @@ extern crate cortex_m_rt as rt; use core::fmt::Write; -use hal::dma::{config::DmaConfig, stream::DMAExt, TransferExt}; +use hal::dma::{channel::DMAExt, config::DmaConfig, TransferExt}; use hal::prelude::*; use hal::pwr::PwrExt; use hal::serial::*; @@ -32,7 +32,7 @@ fn main() -> ! { let pwr = dp.PWR.constrain().freeze(); let mut rcc = rcc.freeze(rcc::Config::hsi(), pwr); - let streams = dp.DMA1.split(&rcc); + let channels = dp.DMA1.split(&rcc); let config = DmaConfig::default() .transfer_complete_interrupt(false) .circular_buffer(false) @@ -65,7 +65,7 @@ fn main() -> ! { // Setup DMA for USART2 TX with dma channel 1. let mut transfer = - streams + channels .0 .into_memory_to_peripheral_transfer(tx.enable_dma(), &mut tx_buffer[..], config); diff --git a/src/dma.rs b/src/dma.rs index d05b6e00..2e7f12e8 100644 --- a/src/dma.rs +++ b/src/dma.rs @@ -1,7 +1,7 @@ //! Direct Memory Access. //! //! [Transfer::init](struct.Transfer.html#method.init) is only implemented for -//! valid combinations of peripheral-stream-channel-direction, providing compile +//! valid combinations of peripheral-channel-direction, providing compile //! time checking. //! //! This module implements Memory To Memory, Peripheral To Memory and Memory to @@ -17,13 +17,13 @@ use core::fmt::Debug; +pub mod channel; // DMA MUX // DMA1 and DMA2 pub mod config; pub(crate) mod mux; -pub mod stream; // DMA MUX // DMA1 and DMA2 pub mod traits; pub mod transfer; -use traits::{sealed::Bits, Direction, Stream, TargetAddress}; +use traits::{sealed::Bits, Channel, Direction, TargetAddress}; pub use transfer::{Transfer, TransferExt}; /// Errors. diff --git a/src/dma/stream.rs b/src/dma/channel.rs similarity index 83% rename from src/dma/stream.rs rename to src/dma/channel.rs index 76cf60c6..ee7be694 100644 --- a/src/dma/stream.rs +++ b/src/dma/channel.rs @@ -70,66 +70,24 @@ pub struct DmaInterrupts { half_transfer: bool, } -/// Stream 0 on DMA -pub struct Stream0 { - _dma: PhantomData, -} -/// Stream 1 on DMA -pub struct Stream1 { - _dma: PhantomData, -} -/// Stream 2 on DMA -pub struct Stream2 { - _dma: PhantomData, -} -/// Stream 3 on DMA -pub struct Stream3 { - _dma: PhantomData, -} -/// Stream 4 on DMA -pub struct Stream4 { - _dma: PhantomData, -} -/// Stream 5 on DMA -pub struct Stream5 { - _dma: PhantomData, -} -/// Stream 6 on DMA -pub struct Stream6 { - _dma: PhantomData, -} -/// Stream 7 on DMA -pub struct Stream7 { - _dma: PhantomData, -} - -impl Sealed for Stream0 {} -impl Sealed for Stream1 {} -impl Sealed for Stream2 {} -impl Sealed for Stream3 {} -impl Sealed for Stream4 {} -impl Sealed for Stream5 {} -impl Sealed for Stream6 {} -impl Sealed for Stream7 {} - -/// Alias for a tuple with all DMA streams. -pub struct StreamsTuple( - pub Stream0, - pub Stream1, - pub Stream2, - pub Stream3, - pub Stream4, - pub Stream5, - #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Stream6, - #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Stream7, +/// Alias for a tuple with all DMA channels. +pub struct ChannelsTuple( + pub Channel1, + pub Channel2, + pub Channel3, + pub Channel4, + pub Channel5, + pub Channel6, + #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Channel7, + #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Channel8, ); pub trait DMAExt { - fn split(self, rcc: &Rcc) -> StreamsTuple; + fn split(self, rcc: &Rcc) -> ChannelsTuple; } impl DMAExt for DMA1 { - fn split(self, rcc: &Rcc) -> StreamsTuple { + fn split(self, rcc: &Rcc) -> ChannelsTuple { // Enable DMAMux is not yet enabled if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral @@ -139,12 +97,12 @@ impl DMAExt for DMA1 { // Enable peripheral rcc.rb.ahb1enr().modify(|_, w| w.dma1en().set_bit()); - StreamsTuple::new(self) + ChannelsTuple::new(self) } } impl DMAExt for DMA2 { - fn split(self, rcc: &Rcc) -> StreamsTuple { + fn split(self, rcc: &Rcc) -> ChannelsTuple { // Enable DMAMux is not yet enabled if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral @@ -154,38 +112,45 @@ impl DMAExt for DMA2 { // Enable peripheral rcc.rb.ahb1enr().modify(|_, w| w.dma2en().set_bit()); - StreamsTuple::new(self) + ChannelsTuple::new(self) } } -impl StreamsTuple { - /// Splits the DMA peripheral into streams. +impl ChannelsTuple { + /// Splits the DMA peripheral into channels. pub(crate) fn new(_regs: I) -> Self { Self( - Stream0 { _dma: PhantomData }, - Stream1 { _dma: PhantomData }, - Stream2 { _dma: PhantomData }, - Stream3 { _dma: PhantomData }, - Stream4 { _dma: PhantomData }, - Stream5 { _dma: PhantomData }, + Channel1 { _dma: PhantomData }, + Channel2 { _dma: PhantomData }, + Channel3 { _dma: PhantomData }, + Channel4 { _dma: PhantomData }, + Channel5 { _dma: PhantomData }, + Channel6 { _dma: PhantomData }, #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] - Stream6 { _dma: PhantomData }, + Channel7 { _dma: PhantomData }, #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] - Stream7 { _dma: PhantomData }, + Channel8 { _dma: PhantomData }, ) } } -// Macro that creates a struct representing a stream on either DMA controller +// Macro that creates a struct representing a channel on either DMA controller // // The implementation does the heavy lifting of mapping to the right fields on -// the stream -macro_rules! dma_stream { - ($(($name:ident, $number:expr, $x:literal)),+$(,)*) => { +// the channel +macro_rules! dma_channel { + ($(($name:ident, $number:expr)),+$(,)*) => { $( - impl Stream for $name { + /// Channel $number on DMA + pub struct $name { + _dma: PhantomData, + } - const NUMBER: usize = $number; + impl Sealed for $name {} + + impl Channel for $name { + + const NUMBER: usize = $number - 1; type Config = DmaConfig; type Interrupts = DmaInterrupts; @@ -208,7 +173,7 @@ macro_rules! dma_stream { let num = Self::NUMBER as u8; //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX + // that belongs to the ChannelX let dma = unsafe { &*I::ptr() }; dma.ifcr().write(|w| w .ctcif(num).set_bit() //Clear transfer complete interrupt flag @@ -223,7 +188,7 @@ macro_rules! dma_stream { #[inline(always)] fn clear_transfer_complete_flag(&mut self) { //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX + // that belongs to the ChannelX let dma = unsafe { &*I::ptr() }; dma.ifcr().write(|w| w.ctcif(Self::NUMBER as u8).set_bit()); } @@ -240,7 +205,7 @@ macro_rules! dma_stream { #[inline(always)] fn clear_transfer_error_interrupt(&mut self) { //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX + // that belongs to the ChannelX let dma = unsafe { &*I::ptr() }; dma.ifcr().write(|w| w.ctcif(Self::NUMBER as u8).set_bit()); let _ = dma.isr().read(); @@ -263,7 +228,7 @@ macro_rules! dma_stream { #[inline(always)] unsafe fn enable(&mut self) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.en().set_bit()); } @@ -277,7 +242,7 @@ macro_rules! dma_stream { fn disable(&mut self) { if Self::is_enabled() { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); // Aborting an on-going transfer might cause interrupts to fire, disable @@ -295,7 +260,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_request_line(&mut self, request_line: u8) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmamux = unsafe { &*I::mux_ptr() }; unsafe { dmamux.ccr($number) @@ -305,14 +270,14 @@ macro_rules! dma_stream { #[inline(always)] fn set_priority(&mut self, priority: config::Priority) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| unsafe { w.pl().bits(priority.bits()) }); } #[inline(always)] fn disable_interrupts(&mut self) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w .tcie().clear_bit() @@ -324,7 +289,7 @@ macro_rules! dma_stream { #[inline(always)] fn enable_interrupts(&mut self, interrupt: Self::Interrupts) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = &unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w .tcie().bit(interrupt.transfer_complete) @@ -335,7 +300,7 @@ macro_rules! dma_stream { #[inline(always)] fn get_interrupts_enable() -> Self::Interrupts { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); let cr = dma_ch.cr().read(); @@ -349,7 +314,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_transfer_complete_interrupt_enable(&mut self, transfer_complete_interrupt: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.tcie().bit(transfer_complete_interrupt)); let _ = dmacr.read(); @@ -358,7 +323,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_transfer_error_interrupt_enable(&mut self, transfer_error_interrupt: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.teie().bit(transfer_error_interrupt)); let _ = dmacr.read(); @@ -367,7 +332,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt)); let _ = dmacr.read(); @@ -384,7 +349,7 @@ macro_rules! dma_stream { #[inline(always)] fn clear_half_transfer_interrupt(&mut self) { //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX + // that belongs to the ChannelX let dma = unsafe { &*I::ptr() }; dma.ifcr().write(|w| w.chtif(Self::NUMBER as u8).set_bit()); let _ = dma.isr().read(); @@ -393,69 +358,69 @@ macro_rules! dma_stream { #[inline(always)] unsafe fn set_peripheral_address(&mut self, value: u32) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.par().write(|w| w.pa().bits(value)); } #[inline(always)] unsafe fn set_memory_address(&mut self, value: u32) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.mar().write(|w| w.ma().bits(value) ); } #[inline(always)] fn get_memory_address(&self) -> u32 { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.mar().read().ma().bits() } #[inline(always)] fn set_number_of_transfers(&mut self, value: u16) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.ndtr().write(|w| unsafe {w.ndt().bits(value) }); } #[inline(always)] fn get_number_of_transfers() -> u16 { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.ndtr().read().ndt().bits() } #[inline(always)] unsafe fn set_memory_size(&mut self, size: u8) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.msize().bits(size)); } #[inline(always)] unsafe fn set_peripheral_size(&mut self, size: u8) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.psize().bits(size)); } #[inline(always)] fn set_memory_increment(&mut self, increment: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.minc().bit(increment)); } #[inline(always)] fn set_peripheral_increment(&mut self, increment: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.pinc().bit(increment)); } #[inline(always)] fn set_direction(&mut self, direction: DmaDirection) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| { match direction { @@ -471,7 +436,7 @@ macro_rules! dma_stream { #[inline(always)] fn set_circular_buffer(&mut self, circular_buffer: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dma_ch = unsafe { &*I::ptr() }.ch(Self::NUMBER); dma_ch.cr().modify(|_, w| w.circ().bit(circular_buffer)); } @@ -481,7 +446,7 @@ macro_rules! dma_stream { #[inline(always)] pub fn clear_half_transfer_interrupt(&mut self) { //NOTE(unsafe) Atomic write with no side-effects and we only access the bits - // that belongs to the StreamX + // that belongs to the ChannelX let dma = unsafe { &*I::ptr() }; dma.ifcr().write(|w| w.chtif(Self::NUMBER as u8).set_bit()); let _ = dma.isr().read(); @@ -497,7 +462,7 @@ macro_rules! dma_stream { #[inline(always)] pub fn set_half_transfer_interrupt_enable(&mut self, half_transfer_interrupt: bool) { - //NOTE(unsafe) We only access the registers that belongs to the StreamX + //NOTE(unsafe) We only access the registers that belongs to the ChannelX let dmacr = &unsafe { &*I::ptr() }.ch(Self::NUMBER).cr(); dmacr.modify(|_, w| w.htie().bit(half_transfer_interrupt)); let _ = dmacr.read(); @@ -508,15 +473,13 @@ macro_rules! dma_stream { }; } -dma_stream!( - // Note: the field names start from one, unlike the RM where they start from - // zero. May need updating if it gets fixed upstream. - (Stream0, 0, 1), - (Stream1, 1, 2), - (Stream2, 2, 3), - (Stream3, 3, 4), - (Stream4, 4, 5), - (Stream5, 5, 6), +dma_channel!( + (Channel1, 1), + (Channel2, 2), + (Channel3, 3), + (Channel4, 4), + (Channel5, 5), + (Channel6, 6), ); // Cat 3 and 4 devices @@ -529,9 +492,4 @@ dma_stream!( feature = "stm32g491", feature = "stm32g4a1", ))] -dma_stream!( - // Note: the field names start from one, unlike the RM where they start from - // zero. May need updating if it gets fixed upstream. - (Stream6, 6, 7), - (Stream7, 7, 8), -); +dma_channel!((Channel7, 7), (Channel8, 8),); diff --git a/src/dma/config.rs b/src/dma/config.rs index 21b3bd02..ebf790ff 100644 --- a/src/dma/config.rs +++ b/src/dma/config.rs @@ -1,9 +1,9 @@ use super::Bits; -/// Priority of the DMA stream, defaults to `Medium`. If two requests have -/// the same software priority level, the stream with the lower number takes -/// priority over the stream with the higher number. For example, Stream 2 -/// takes priority over Stream 4. +/// Priority of the DMA channel, defaults to `Medium`. If two requests have +/// the same software priority level, the channel with the lower number takes +/// priority over the channel with the higher number. For example, channel 2 +/// takes priority over channel 4. #[derive(Debug, Clone, Copy, Default)] pub enum Priority { /// Low priority. @@ -28,7 +28,7 @@ impl Bits for Priority { } } -/// Contains the complete set of configuration for a DMA stream. +/// Contains the complete set of configuration for a DMA channel. #[derive(Debug, Default, Clone, Copy)] pub struct DmaConfig { pub(crate) priority: Priority, diff --git a/src/dma/traits.rs b/src/dma/traits.rs index d33a965e..85031492 100644 --- a/src/dma/traits.rs +++ b/src/dma/traits.rs @@ -15,33 +15,33 @@ pub(crate) mod sealed { } use sealed::Sealed; -/// Minimal trait for DMA streams -pub trait Stream: Sealed { - /// Number of the stream register +/// Minimal trait for DMA channels +pub trait Channel: Sealed { + /// Number of the channel register const NUMBER: usize; - /// Configuration structure for this stream. + /// Configuration structure for this channel. type Config; /// Structure representing interrupts type Interrupts: Copy + Debug; - /// Apply the configation structure to this stream. + /// Apply the configation structure to this channel. fn apply_config(&mut self, config: Self::Config); - /// Clear all interrupts for the DMA stream. + /// Clear all interrupts for the DMA channel. fn clear_interrupts(&mut self); - /// Clear transfer complete interrupt flag (tcif) for the DMA stream + /// Clear transfer complete interrupt flag (tcif) for the DMA channel /// but do not insert artificial delays. fn clear_transfer_complete_flag(&mut self); - /// Clear transfer complete interrupt (tcif) for the DMA stream and delay + /// Clear transfer complete interrupt (tcif) for the DMA channel and delay /// to ensure the change has settled through the bridge, peripheral, and /// synchronizers. fn clear_transfer_complete_interrupt(&mut self); - /// Clear transfer error interrupt (teif) for the DMA stream. + /// Clear transfer error interrupt (teif) for the DMA channel. fn clear_transfer_error_interrupt(&mut self); /// Get transfer complete flag. @@ -50,84 +50,84 @@ pub trait Stream: Sealed { /// Get transfer error flag. fn get_transfer_error_flag() -> bool; - /// Enable the DMA stream. + /// Enable the DMA channel. /// /// # Safety /// /// The user must ensure that all registers are properly configured. unsafe fn enable(&mut self); - /// Returns the state of the DMA stream. + /// Returns the state of the DMA channel. fn is_enabled() -> bool; - /// Disable the DMA stream. + /// Disable the DMA channel. /// - /// Disabling the stream during an on-going transfer needs to be performed - /// in a certain way to prevent problems if the stream is to be re-enabled + /// Disabling the channel during an on-going transfer needs to be performed + /// in a certain way to prevent problems if the channel is to be re-enabled /// shortly after, because of that, this method will also clear all the - /// stream's interrupt flags if the stream is active. + /// channel's interrupt flags if the channel is active. fn disable(&mut self); - /// Sets the request or trigger line for this stream + /// Sets the request or trigger line for this channel fn set_request_line(&mut self, request_line: u8); - /// Set the priority the DMA stream. + /// Set the priority the DMA channel. fn set_priority(&mut self, priority: config::Priority); - /// Disable all interrupts for the DMA stream. + /// Disable all interrupts for the DMA channel. fn disable_interrupts(&mut self); - /// Configure interrupts for the DMA stream + /// Configure interrupts for the DMA channel fn enable_interrupts(&mut self, interrupts: Self::Interrupts); - /// Get the value of all the interrupts for this DMA stream + /// Get the value of all the interrupts for this DMA channel fn get_interrupts_enable() -> Self::Interrupts; - /// Enable/disable the transfer complete interrupt (tcie) of the DMA stream. + /// Enable/disable the transfer complete interrupt (tcie) of the DMA channel. fn set_transfer_complete_interrupt_enable(&mut self, transfer_complete_interrupt: bool); - /// Enable/disable the transfer error interrupt (teie) of the DMA stream. + /// Enable/disable the transfer error interrupt (teie) of the DMA channel. fn set_transfer_error_interrupt_enable(&mut self, transfer_error_interrupt: bool); - /// Set the peripheral address (par) for the DMA stream. + /// Set the peripheral address (par) for the DMA channel. /// /// # Safety /// /// Value should be a word aligned valid peripheral address unsafe fn set_peripheral_address(&mut self, value: u32); - /// Set the memory address (m0ar or m1ar) for the DMA stream. + /// Set the memory address (m0ar or m1ar) for the DMA channel. /// /// # Safety /// /// Value should be a word aligned valid memory address unsafe fn set_memory_address(&mut self, value: u32); - /// Enable/disable the half transfer interrupt (htie) of the DMA stream. + /// Enable/disable the half transfer interrupt (htie) of the DMA channel. fn set_half_transfer_interrupt_enable(&mut self, transfer_complete_interrupt: bool); - /// Clear half transfer interrupt (htif) for the DMA stream. + /// Clear half transfer interrupt (htif) for the DMA channel. fn clear_half_transfer_interrupt(&mut self); /// Get half transfer flag. fn get_half_transfer_flag() -> bool; - /// Get the memory address for the DMA stream. + /// Get the memory address for the DMA channel. fn get_memory_address(&self) -> u32; - /// Enable/disable memory increment (minc) for the DMA stream. + /// Enable/disable memory increment (minc) for the DMA channel. fn set_memory_increment(&mut self, increment: bool); - /// Enable/disable peripheral increment (pinc) for the DMA stream. + /// Enable/disable peripheral increment (pinc) for the DMA channel. fn set_peripheral_increment(&mut self, increment: bool); - /// Set the number of transfers (ndt) for the DMA stream. + /// Set the number of transfers (ndt) for the DMA channel. fn set_number_of_transfers(&mut self, value: u16); - /// Get the number of transfers (ndt) for the DMA stream. + /// Get the number of transfers (ndt) for the DMA channel. fn get_number_of_transfers() -> u16; - /// Set the memory size (msize) for the DMA stream. + /// Set the memory size (msize) for the DMA channel. /// /// # Safety /// @@ -140,7 +140,7 @@ pub trait Stream: Sealed { /// * 3 -> double word unsafe fn set_memory_size(&mut self, size: u8); - /// Set the peripheral memory size (psize) for the DMA stream. + /// Set the peripheral memory size (psize) for the DMA channel. /// /// # Safety /// @@ -153,19 +153,13 @@ pub trait Stream: Sealed { /// * 2 -> word unsafe fn set_peripheral_size(&mut self, size: u8); - /// Set the direction (dir) of the DMA stream. + /// Set the direction (dir) of the DMA channel. fn set_direction(&mut self, direction: DmaDirection); - /// Enable/disable circular buffering for the DMA stream. + /// Enable/disable circular buffering for the DMA channel. fn set_circular_buffer(&mut self, circular_buffer: bool); } -/// Trait for Master DMA streams -/// -/// TODO -#[allow(unused)] -pub trait MasterStream: Stream + Sealed {} - /// DMA direction. pub trait Direction { /// Returns the `DmaDirection` of the type. @@ -189,7 +183,7 @@ pub unsafe trait TargetAddress { /// Memory size of the target address type MemSize; - /// The address to be used by the DMA stream + /// The address to be used by the DMA channel fn address(&self) -> u32; /// An optional associated request line diff --git a/src/dma/transfer.rs b/src/dma/transfer.rs index 2c0d2f3d..16356cd2 100644 --- a/src/dma/transfer.rs +++ b/src/dma/transfer.rs @@ -1,6 +1,6 @@ use crate::dma::{ - traits, Direction, DmaDirection, MemoryToMemory, MemoryToPeripheral, PeripheralToMemory, - Stream, TargetAddress, + traits, Channel, Direction, DmaDirection, MemoryToMemory, MemoryToPeripheral, + PeripheralToMemory, TargetAddress, }; use core::{ marker::PhantomData, @@ -17,13 +17,13 @@ pub struct MutTransfer; pub struct ConstTransfer; /// DMA Transfer. -pub struct Transfer +pub struct Transfer where - STREAM: Stream, + CHANNEL: Channel, PERIPHERAL: TargetAddress, DIR: Direction, { - stream: STREAM, + channel: CHANNEL, peripheral: PERIPHERAL, _direction: PhantomData, _transfer_type: PhantomData, @@ -33,10 +33,10 @@ where macro_rules! transfer_def { ($Marker:ty, $init:ident, $Buffer:tt, $rw_buffer:ident $(, $mut:tt)*; $($constraint:stmt)*) => { - impl - Transfer + impl + Transfer where - STREAM: Stream, + CHANNEL: Channel, DIR: Direction, PERIPHERAL: TargetAddress, BUF: $Buffer>::MemSize>, @@ -49,12 +49,12 @@ macro_rules! transfer_def { /// /// * When the transfer length is greater than (2^16 - 1) pub(crate) fn $init( - mut stream: STREAM, + mut channel: CHANNEL, peripheral: PERIPHERAL, $($mut)* memory: BUF, config: CONFIG, ) -> Self { - stream.disable(); + channel.disable(); fence(Ordering::SeqCst); @@ -62,7 +62,7 @@ macro_rules! transfer_def { $($constraint)* // Set peripheral to memory mode - stream.set_direction(DIR::direction()); + channel.set_direction(DIR::direction()); // NOTE(unsafe) We now own this buffer and we won't call any &mut // methods on it until the end of the DMA transfer @@ -74,7 +74,7 @@ macro_rules! transfer_def { // // Must be a valid memory address unsafe { - stream.set_memory_address( + channel.set_memory_address( buf_ptr as u32, ); } @@ -85,7 +85,7 @@ macro_rules! transfer_def { // // Must be a valid peripheral address or source address unsafe { - stream.set_peripheral_address(peripheral.address()); + channel.set_peripheral_address(peripheral.address()); } assert!( @@ -93,15 +93,15 @@ macro_rules! transfer_def { "Hardware does not support more than 65535 transfers" ); let buf_len = buf_len as u16; - stream.set_number_of_transfers(buf_len); + channel.set_number_of_transfers(buf_len); // Set the DMAMUX request line if needed if let Some(request_line) = PERIPHERAL::REQUEST_LINE { - stream.set_request_line(request_line); + channel.set_request_line(request_line); } let mut transfer = Self { - stream, + channel, peripheral, _direction: PhantomData, _transfer_type: PhantomData, @@ -113,24 +113,24 @@ macro_rules! transfer_def { } /// Starts the transfer, the closure will be executed right after enabling - /// the stream. + /// the channel. #[inline(always)] pub fn restart(&mut self, f: F) where F: FnOnce(&mut PERIPHERAL), { - self.stream.disable(); + self.channel.disable(); fence(Ordering::SeqCst); let (_, buf_len) = unsafe { self.buf.$rw_buffer() }; - self.stream.set_number_of_transfers(buf_len as u16); + self.channel.set_number_of_transfers(buf_len as u16); f(&mut self.peripheral); // Preserve the instruction and bus ordering of preceding buffer access // to the subsequent access by the DMA peripheral due to enabling it. fence(Ordering::SeqCst); unsafe { - self.stream.enable(); + self.channel.enable(); } } } @@ -141,9 +141,9 @@ transfer_def!(MutTransfer, init, StaticWriteBuffer, write_buffer, mut;); transfer_def!(ConstTransfer, init_const, StaticReadBuffer, read_buffer; assert!(DIR::direction() != DmaDirection::PeripheralToMemory)); -impl Transfer +impl Transfer where - STREAM: Stream, + CHANNEL: Channel, DIR: Direction, PERIPHERAL: TargetAddress, { @@ -151,16 +151,16 @@ where fn apply_config(&mut self, config: CONFIG) { let msize = mem::size_of::<>::MemSize>() / 2; - self.stream.clear_interrupts(); + self.channel.clear_interrupts(); // NOTE(unsafe) These values are correct because of the // invariants of TargetAddress unsafe { - self.stream.set_memory_size(msize as u8); - self.stream.set_peripheral_size(msize as u8); + self.channel.set_memory_size(msize as u8); + self.channel.set_peripheral_size(msize as u8); } - self.stream.apply_config(config); + self.channel.apply_config(config); } pub fn peek_buffer(&mut self, func: F) -> T @@ -168,7 +168,7 @@ where F: FnOnce(&BUF, usize) -> T, { // Single buffer mode - self.stream.disable(); + self.channel.disable(); // Protect the instruction sequence of preceding DMA disable/inactivity // verification/poisoning and subsequent (old completed) buffer content @@ -178,7 +178,7 @@ where fence(Ordering::SeqCst); // Check how many data in the transfer are remaining. - let remaining_data = STREAM::get_number_of_transfers(); + let remaining_data = CHANNEL::get_number_of_transfers(); let result = func(&self.buf, remaining_data as usize); @@ -190,13 +190,13 @@ where fence(Ordering::SeqCst); unsafe { - self.stream.enable(); + self.channel.enable(); } result } /// Starts the transfer, the closure will be executed right after enabling - /// the stream. + /// the channel. pub fn start(&mut self, f: F) where F: FnOnce(&mut PERIPHERAL), @@ -206,90 +206,90 @@ where fence(Ordering::SeqCst); unsafe { - self.stream.enable(); + self.channel.enable(); } f(&mut self.peripheral); } - /// Pauses the dma stream, the closure will be executed right before - /// disabling the stream. + /// Pauses the dma channel, the closure will be executed right before + /// disabling the channel. pub fn pause(&mut self, f: F) where F: FnOnce(&mut PERIPHERAL), { f(&mut self.peripheral); fence(Ordering::SeqCst); - self.stream.disable(); + self.channel.disable(); fence(Ordering::SeqCst); } - /// Stops the stream and returns the underlying resources. - pub fn free(mut self) -> (STREAM, PERIPHERAL, BUF) { - self.stream.disable(); + /// Stops the channel and returns the underlying resources. + pub fn free(mut self) -> (CHANNEL, PERIPHERAL, BUF) { + self.channel.disable(); // Protect the instruction and bus sequence of the preceding disable and // the subsequent buffer access. fence(Ordering::SeqCst); - self.stream.clear_interrupts(); + self.channel.clear_interrupts(); unsafe { - let stream = ptr::read(&self.stream); + let channel = ptr::read(&self.channel); let peripheral = ptr::read(&self.peripheral); let buf = ptr::read(&self.buf); mem::forget(self); - (stream, peripheral, buf) + (channel, peripheral, buf) } } - /// Clear all interrupts for the DMA stream. + /// Clear all interrupts for the DMA channel. #[inline(always)] pub fn clear_interrupts(&mut self) { - self.stream.clear_interrupts(); + self.channel.clear_interrupts(); } - /// Clear transfer complete interrupt (tcif) for the DMA stream. + /// Clear transfer complete interrupt (tcif) for the DMA channel. #[inline(always)] pub fn clear_transfer_complete_interrupt(&mut self) { - self.stream.clear_transfer_complete_interrupt(); + self.channel.clear_transfer_complete_interrupt(); } - /// Clear transfer error interrupt (teif) for the DMA stream. + /// Clear transfer error interrupt (teif) for the DMA channel. #[inline(always)] pub fn clear_transfer_error_interrupt(&mut self) { - self.stream.clear_transfer_error_interrupt(); + self.channel.clear_transfer_error_interrupt(); } #[inline(always)] pub fn get_transfer_complete_flag(&self) -> bool { - STREAM::get_transfer_complete_flag() + CHANNEL::get_transfer_complete_flag() } #[inline(always)] pub fn get_transfer_error_flag(&self) -> bool { - STREAM::get_transfer_error_flag() + CHANNEL::get_transfer_error_flag() } - /// Clear half transfer interrupt (htif) for the DMA stream. + /// Clear half transfer interrupt (htif) for the DMA channel. #[inline(always)] pub fn clear_half_transfer_interrupt(&mut self) { - self.stream.clear_half_transfer_interrupt(); + self.channel.clear_half_transfer_interrupt(); } #[inline(always)] pub fn get_half_transfer_flag(&self) -> bool { - STREAM::get_half_transfer_flag() + CHANNEL::get_half_transfer_flag() } } -impl Drop for Transfer +impl Drop for Transfer where - STREAM: Stream, + CHANNEL: Channel, PERIPHERAL: TargetAddress, DIR: Direction, { fn drop(&mut self) { - self.stream.disable(); + self.channel.disable(); // Protect the instruction and bus sequence of the preceding disable and // the subsequent buffer access. @@ -298,18 +298,18 @@ where } /// Circular DMA Transfer. -pub struct CircTransfer +pub struct CircTransfer where - STREAM: Stream, + CHANNEL: Channel, PERIPHERAL: TargetAddress, { - transfer: Transfer, + transfer: Transfer, r_pos: usize, } -impl CircTransfer +impl CircTransfer where - STREAM: Stream, + CHANNEL: Channel, BUF: StaticWriteBuffer + Deref, ::Target: Index, Output = [>::MemSize]>, @@ -319,7 +319,7 @@ where /// Return the number of elements available to read pub fn elements_available(&mut self) -> usize { let blen = unsafe { self.transfer.buf.static_write_buffer().1 }; - let ndtr = STREAM::get_number_of_transfers() as usize; + let ndtr = CHANNEL::get_number_of_transfers() as usize; let pos_at = self.r_pos; // the position the DMA would write to next @@ -397,7 +397,7 @@ where } /// Starts the transfer, the closure will be executed right after enabling - /// the stream. + /// the channel. pub fn start(&mut self, f: F) where F: FnOnce(&mut PERIPHERAL), @@ -405,8 +405,8 @@ where self.transfer.start(f) } - /// Pauses the dma stream, the closure will be executed right before - /// disabling the stream. + /// Pauses the dma channel, the closure will be executed right before + /// disabling the channel. pub fn pause(&mut self, f: F) where F: FnOnce(&mut PERIPHERAL), @@ -414,24 +414,24 @@ where self.transfer.pause(f) } - /// Stops the stream and returns the underlying resources. - pub fn free(self) -> (STREAM, PERIPHERAL, BUF) { + /// Stops the channel and returns the underlying resources. + pub fn free(self) -> (CHANNEL, PERIPHERAL, BUF) { self.transfer.free() } - /// Clear all interrupts for the DMA stream. + /// Clear all interrupts for the DMA channel. #[inline(always)] pub fn clear_interrupts(&mut self) { self.transfer.clear_interrupts(); } - /// Clear transfer complete interrupt (tcif) for the DMA stream. + /// Clear transfer complete interrupt (tcif) for the DMA channel. #[inline(always)] pub fn clear_transfer_complete_interrupt(&mut self) { self.transfer.clear_transfer_complete_interrupt(); } - /// Clear transfer error interrupt (teif) for the DMA stream. + /// Clear transfer error interrupt (teif) for the DMA channel. #[inline(always)] pub fn clear_transfer_error_interrupt(&mut self) { self.transfer.clear_transfer_error_interrupt(); @@ -447,7 +447,7 @@ where self.transfer.get_transfer_error_flag() } - /// Clear half transfer interrupt (htif) for the DMA stream. + /// Clear half transfer interrupt (htif) for the DMA channel. #[inline(always)] pub fn clear_half_transfer_interrupt(&mut self) { self.transfer.clear_half_transfer_interrupt(); @@ -461,9 +461,9 @@ where macro_rules! impl_adc_overrun { ($($adc:ident, )*) => {$( - impl CircTransfer, BUF> + impl CircTransfer, BUF> where - STREAM: Stream, + CHANNEL: Channel, BUF: StaticWriteBuffer + Deref, ::Target: Index, Output = [u16]> { /// This is set when the AD finishes a conversion before the DMA has hade time to transfer the previous value @@ -512,9 +512,9 @@ impl_adc_overrun!(ADC4, ADC5,); macro_rules! impl_serial_timeout { ($($uart:ident, )*) => {$( - impl CircTransfer, BUF> + impl CircTransfer, BUF> where - STREAM: Stream, + CHANNEL: Channel, /*BUF: StaticWriteBuffer + Deref*/ { pub fn timeout_lapsed(&self) -> bool { self.transfer.peripheral.timeout_lapsed() @@ -531,16 +531,16 @@ impl_serial_timeout!(USART1, USART2, USART3, UART4,); #[cfg(not(any(feature = "stm32g431", feature = "stm32g441")))] impl_serial_timeout!(UART5,); -pub trait TransferExt +pub trait TransferExt where - STREAM: traits::Stream, + CHANNEL: traits::Channel, { fn into_memory_to_memory_transfer( self, per: PERIPHERAL, buf: BUF, - config: ::Config, - ) -> Transfer, BUF, MutTransfer> + config: ::Config, + ) -> Transfer, BUF, MutTransfer> where T: Into, PERIPHERAL: TargetAddress>, @@ -549,8 +549,8 @@ where self, per: PERIPHERAL, buf: BUF, - config: ::Config, - ) -> Transfer + config: ::Config, + ) -> Transfer where PERIPHERAL: TargetAddress, BUF: StaticWriteBuffer>::MemSize>; @@ -558,8 +558,8 @@ where self, per: PERIPHERAL, buf: BUF, - config: ::Config, - ) -> Transfer + config: ::Config, + ) -> Transfer where PERIPHERAL: TargetAddress, BUF: StaticReadBuffer>::MemSize>; @@ -567,8 +567,8 @@ where self, src: PSRC, dst: PDST, - config: ::Config, - ) -> Transfer + config: ::Config, + ) -> Transfer where PSRC: TargetAddress, PDST: TargetAddress, @@ -579,8 +579,8 @@ where self, per: PERIPHERAL, buf: BUF, - config: ::Config, - ) -> CircTransfer + config: ::Config, + ) -> CircTransfer where PERIPHERAL: TargetAddress, >::MemSize: Copy, @@ -593,18 +593,18 @@ where } macro_rules! transfer_constructor { - ($(($DMA:ident, $STREAM:ident),)+) => { + ($(($DMA:ident, $CHANNEL:ident),)+) => { $( - impl TransferExt for crate::dma::stream::$STREAM + impl TransferExt for crate::dma::channel::$CHANNEL where - crate::stm32::$DMA: crate::dma::stream::Instance, - Self: traits::Stream, + crate::stm32::$DMA: crate::dma::channel::Instance, + Self: traits::Channel, { fn into_memory_to_memory_transfer( self, per: PERIPHERAL, buf: BUF, - mut config: ::Config, + mut config: ::Config, ) -> Transfer, BUF, MutTransfer> where T: Into, @@ -620,7 +620,7 @@ macro_rules! transfer_constructor { self, per: PERIPHERAL, buf: BUF, - config: ::Config, + config: ::Config, ) -> Transfer where PERIPHERAL: TargetAddress, @@ -634,7 +634,7 @@ macro_rules! transfer_constructor { self, per: PERIPHERAL, buf: BUF, - config: ::Config, + config: ::Config, ) -> Transfer where PERIPHERAL: TargetAddress, @@ -648,7 +648,7 @@ macro_rules! transfer_constructor { self, src: PSRC, dst: PDST, - config: ::Config, + config: ::Config, ) -> Transfer where PSRC: TargetAddress, @@ -666,7 +666,7 @@ macro_rules! transfer_constructor { self, per: PERIPHERAL, buf: BUF, - config: ::Config, + config: ::Config, ) -> CircTransfer where PERIPHERAL: TargetAddress, >::MemSize: Copy, @@ -685,18 +685,18 @@ macro_rules! transfer_constructor { } transfer_constructor!( - (DMA1, Stream0), - (DMA1, Stream1), - (DMA1, Stream2), - (DMA1, Stream3), - (DMA1, Stream4), - (DMA1, Stream5), - (DMA2, Stream0), - (DMA2, Stream1), - (DMA2, Stream2), - (DMA2, Stream3), - (DMA2, Stream4), - (DMA2, Stream5), + (DMA1, Channel1), + (DMA1, Channel2), + (DMA1, Channel3), + (DMA1, Channel4), + (DMA1, Channel5), + (DMA1, Channel6), + (DMA2, Channel1), + (DMA2, Channel2), + (DMA2, Channel3), + (DMA2, Channel4), + (DMA2, Channel5), + (DMA2, Channel6), ); // Cat 3 and 4 devices @@ -710,8 +710,8 @@ transfer_constructor!( feature = "stm32g4a1", ))] transfer_constructor!( - (DMA1, Stream6), - (DMA1, Stream7), - (DMA2, Stream6), - (DMA2, Stream7), + (DMA1, Channel7), + (DMA1, Channel8), + (DMA2, Channel7), + (DMA2, Channel8), ); From 87f4be6cd9fdbc4907ae03fda8eeee3d9b7348c8 Mon Sep 17 00:00:00 2001 From: Albin Hedman Date: Mon, 11 Nov 2024 19:41:30 +0100 Subject: [PATCH 2/2] DMA - Make ChannelsTuple a struct --- examples/adc-continious-dma.rs | 2 +- examples/adc-one-shot-dma.rs | 6 ++-- examples/spi-dma.rs | 2 +- examples/uart-dma-rx.rs | 2 +- examples/uart-dma-tx.rs | 9 +++--- src/dma/channel.rs | 54 ++++++++++++++++++---------------- 6 files changed, 39 insertions(+), 36 deletions(-) diff --git a/examples/adc-continious-dma.rs b/examples/adc-continious-dma.rs index 78313778..15ab0ae5 100644 --- a/examples/adc-continious-dma.rs +++ b/examples/adc-continious-dma.rs @@ -62,7 +62,7 @@ fn main() -> ! { info!("Setup DMA"); let first_buffer = cortex_m::singleton!(: [u16; 15] = [0; 15]).unwrap(); - let mut transfer = channels.0.into_circ_peripheral_to_memory_transfer( + let mut transfer = channels.ch1.into_circ_peripheral_to_memory_transfer( adc.enable_dma(AdcDma::Continuous), &mut first_buffer[..], config, diff --git a/examples/adc-one-shot-dma.rs b/examples/adc-one-shot-dma.rs index b2ff3374..b8370d25 100644 --- a/examples/adc-one-shot-dma.rs +++ b/examples/adc-one-shot-dma.rs @@ -61,7 +61,7 @@ fn main() -> ! { info!("Setup DMA"); let first_buffer = cortex_m::singleton!(: [u16; 2] = [0; 2]).unwrap(); - let mut transfer = channels.0.into_peripheral_to_memory_transfer( + let mut transfer = channels.ch1.into_peripheral_to_memory_transfer( adc.enable_dma(AdcDma::Single), &mut first_buffer[..], config, @@ -74,10 +74,10 @@ fn main() -> ! { info!("Conversion Done"); transfer.pause(|adc| adc.cancel_conversion()); - let (s0, adc, first_buffer) = transfer.free(); + let (ch1, adc, first_buffer) = transfer.free(); let adc = adc.disable(); - channels.0 = s0; + channels.ch1 = ch1; let millivolts = adc.sample_to_millivolts(first_buffer[0]); info!("pa3: {}mV", millivolts); diff --git a/examples/spi-dma.rs b/examples/spi-dma.rs index f1624c2c..01cb8e0f 100644 --- a/examples/spi-dma.rs +++ b/examples/spi-dma.rs @@ -62,7 +62,7 @@ fn main() -> ! { *item = index as u8; } let dma_buf = cortex_m::singleton!(: [u8; BUFFER_SIZE] = buf).unwrap(); - let mut transfer_dma = channels.0.into_memory_to_peripheral_transfer( + let mut transfer_dma = channels.ch1.into_memory_to_peripheral_transfer( spi.enable_tx_dma(), &mut dma_buf[..], config, diff --git a/examples/uart-dma-rx.rs b/examples/uart-dma-rx.rs index 84ad40e3..4b26d3fc 100644 --- a/examples/uart-dma-rx.rs +++ b/examples/uart-dma-rx.rs @@ -65,7 +65,7 @@ fn main() -> ! { let (_tx, rx) = usart.split(); - let mut transfer = channels.0.into_circ_peripheral_to_memory_transfer( + let mut transfer = channels.ch1.into_circ_peripheral_to_memory_transfer( rx.enable_dma(), &mut rx_buffer[..], config, diff --git a/examples/uart-dma-tx.rs b/examples/uart-dma-tx.rs index 8a1a7fed..ad17d497 100644 --- a/examples/uart-dma-tx.rs +++ b/examples/uart-dma-tx.rs @@ -64,10 +64,11 @@ fn main() -> ! { let (tx, _rx) = usart.split(); // Setup DMA for USART2 TX with dma channel 1. - let mut transfer = - channels - .0 - .into_memory_to_peripheral_transfer(tx.enable_dma(), &mut tx_buffer[..], config); + let mut transfer = channels.ch1.into_memory_to_peripheral_transfer( + tx.enable_dma(), + &mut tx_buffer[..], + config, + ); transfer.start(|_tx| {}); loop { diff --git a/src/dma/channel.rs b/src/dma/channel.rs index ee7be694..58f30814 100644 --- a/src/dma/channel.rs +++ b/src/dma/channel.rs @@ -71,23 +71,25 @@ pub struct DmaInterrupts { } /// Alias for a tuple with all DMA channels. -pub struct ChannelsTuple( - pub Channel1, - pub Channel2, - pub Channel3, - pub Channel4, - pub Channel5, - pub Channel6, - #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Channel7, - #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] pub Channel8, -); +pub struct Channels { + pub ch1: Channel1, + pub ch2: Channel2, + pub ch3: Channel3, + pub ch4: Channel4, + pub ch5: Channel5, + pub ch6: Channel6, + #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] + pub ch7: Channel7, + #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] + pub ch8: Channel8, +} pub trait DMAExt { - fn split(self, rcc: &Rcc) -> ChannelsTuple; + fn split(self, rcc: &Rcc) -> Channels; } impl DMAExt for DMA1 { - fn split(self, rcc: &Rcc) -> ChannelsTuple { + fn split(self, rcc: &Rcc) -> Channels { // Enable DMAMux is not yet enabled if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral @@ -97,12 +99,12 @@ impl DMAExt for DMA1 { // Enable peripheral rcc.rb.ahb1enr().modify(|_, w| w.dma1en().set_bit()); - ChannelsTuple::new(self) + Channels::new(self) } } impl DMAExt for DMA2 { - fn split(self, rcc: &Rcc) -> ChannelsTuple { + fn split(self, rcc: &Rcc) -> Channels { // Enable DMAMux is not yet enabled if !rcc.rb.ahb1enr().read().dmamuxen().bit_is_set() { // Enable peripheral @@ -112,25 +114,25 @@ impl DMAExt for DMA2 { // Enable peripheral rcc.rb.ahb1enr().modify(|_, w| w.dma2en().set_bit()); - ChannelsTuple::new(self) + Channels::new(self) } } -impl ChannelsTuple { +impl Channels { /// Splits the DMA peripheral into channels. pub(crate) fn new(_regs: I) -> Self { - Self( - Channel1 { _dma: PhantomData }, - Channel2 { _dma: PhantomData }, - Channel3 { _dma: PhantomData }, - Channel4 { _dma: PhantomData }, - Channel5 { _dma: PhantomData }, - Channel6 { _dma: PhantomData }, + Self { + ch1: Channel1 { _dma: PhantomData }, + ch2: Channel2 { _dma: PhantomData }, + ch3: Channel3 { _dma: PhantomData }, + ch4: Channel4 { _dma: PhantomData }, + ch5: Channel5 { _dma: PhantomData }, + ch6: Channel6 { _dma: PhantomData }, #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] - Channel7 { _dma: PhantomData }, + ch7: Channel7 { _dma: PhantomData }, #[cfg(not(any(feature = "stm32g431", feature = "stm32g441",)))] - Channel8 { _dma: PhantomData }, - ) + ch8: Channel8 { _dma: PhantomData }, + } } }