Skip to content

Commit

Permalink
DmaEligible trait providing dma peripheral value & safe constructor f…
Browse files Browse the repository at this point in the history
…or Mem2Mem dma.
  • Loading branch information
liebman committed Jul 2, 2024
1 parent 02a2534 commit 81b5266
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 21 deletions.
22 changes: 20 additions & 2 deletions esp-hal/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,12 +619,13 @@ pub use m2m::*;
mod m2m {
use embedded_dma::{ReadBuffer, WriteBuffer};

use super::dma_private::{DmaSupport, DmaSupportRx};
use crate::dma::{
dma_private::{DmaSupport, DmaSupportRx},
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaEligible,
DmaError,
DmaPeripheral,
DmaTransferRx,
Expand Down Expand Up @@ -653,13 +654,30 @@ mod m2m {
C: ChannelTypes,
MODE: crate::Mode,
{
/// Create a new Mem2Mem instance.
pub fn new(
mut channel: Channel<'d, C, MODE>,
peripheral: impl DmaEligible,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
channel.tx.init_channel();
channel.rx.init_channel();
Mem2Mem {
channel,
peripheral: peripheral.dma_peripheral(),
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
}
}

/// Create a new Mem2Mem instance.
///
/// # Safety
///
/// You must insure that your not using DMA for the same peripheral and
/// that your the only one using the DmaPeripheral.
pub unsafe fn new(
pub unsafe fn new_unsafe(
mut channel: Channel<'d, C, MODE>,
peripheral: DmaPeripheral,
tx_descriptors: &'static mut [DmaDescriptor],
Expand Down
24 changes: 13 additions & 11 deletions esp-hal/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,34 +384,26 @@ pub enum DmaPeripheral {
Spi2 = 0,
#[cfg(any(pdma, esp32s3))]
Spi3 = 1,
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
#[cfg(any(esp32c6, esp32h2))]
Mem2Mem1 = 1,
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
Uhci0 = 2,
#[cfg(esp32c2)]
Mem2Mem2 = 2,
#[cfg(any(esp32, esp32s2, esp32c3, esp32c6, esp32h2, esp32s3))]
I2s0 = 3,
#[cfg(esp32c2)]
Mem2Mem3 = 3,
#[cfg(any(esp32, esp32s3))]
I2s1 = 4,
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
#[cfg(any(esp32c6, esp32h2))]
Mem2Mem4 = 4,
#[cfg(esp32s3)]
LcdCam = 5,
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
#[cfg(any(esp32c6, esp32h2))]
Mem2Mem5 = 5,
#[cfg(not(esp32c2))]
Aes = 6,
#[cfg(esp32c2)]
Mem2Mem6 = 6,
#[cfg(gdma)]
Sha = 7,
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
Adc = 8,
#[cfg(esp32c2)]
Mem2Mem8 = 8,
#[cfg(esp32s3)]
Rmt = 9,
#[cfg(parl_io)]
Expand Down Expand Up @@ -445,6 +437,16 @@ impl From<u32> for Owner {
}
}

/// Marks channels as useable for SPI
#[doc(hidden)]
pub trait DmaEligible {
/// The DMA peripheral
const DMA_PERIPHERAL: DmaPeripheral;
fn dma_peripheral(&self) -> DmaPeripheral {
Self::DMA_PERIPHERAL
}
}

/// Marks channels as useable for SPI
#[doc(hidden)]
pub trait SpiPeripheral: PeripheralMarker {}
Expand Down
53 changes: 53 additions & 0 deletions esp-hal/src/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ where
impl<T> crate::private::Sealed for &mut T where T: crate::private::Sealed {}

mod peripheral_macros {
#[doc(hidden)]
#[macro_export]
macro_rules! impl_dma_eligible {
($name:ident,$dma:ident) => {
impl $crate::dma::DmaEligible for $name {
const DMA_PERIPHERAL: $crate::dma::DmaPeripheral = $crate::dma::DmaPeripheral::$dma;
}
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! peripherals {
Expand All @@ -215,6 +225,49 @@ mod peripheral_macros {
$(
$crate::create_peripheral!($(#[$cfg])? $name <= $from_pac);
)*


$crate::impl_dma_eligible!(SPI2,Spi2);
#[cfg(any(pdma, esp32s3))]
$crate::impl_dma_eligible!(SPI3,Spi3);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM1,Mem2Mem1);
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
$crate::impl_dma_eligible!(UHCI0,Uhci0);
#[cfg(any(esp32, esp32s2, esp32c3, esp32c6, esp32h2, esp32s3))]
$crate::impl_dma_eligible!(I2S0,I2s0);
#[cfg(any(esp32, esp32s3))]
$crate::impl_dma_eligible!(I2S1,I2s1);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM4,Mem2Mem4);
#[cfg(esp32s3)]
$crate::impl_dma_eligible!(LCD_CAM,LcdCam);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM5,Mem2Mem5);
#[cfg(not(esp32c2))]
$crate::impl_dma_eligible!(AES,Aes);
#[cfg(gdma)]
$crate::impl_dma_eligible!(SHA,Sha);
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
$crate::impl_dma_eligible!(ADC1,Adc);
#[cfg(any(esp32c3, esp32s3))]
$crate::impl_dma_eligible!(ADC2,Adc);
#[cfg(esp32s3)]
$crate::impl_dma_eligible!(RMT,Rmt);
#[cfg(parl_io)]
$crate::impl_dma_eligible!(PARL_IO,ParlIo);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM10,Mem2Mem10);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM11,Mem2Mem11);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM12,Mem2Mem12);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM13,Mem2Mem13);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM14,Mem2Mem14);
#[cfg(any(esp32c6, esp32h2))]
$crate::impl_dma_eligible!(MEM2MEM15,Mem2Mem15);
}

#[allow(non_snake_case)]
Expand Down
7 changes: 7 additions & 0 deletions esp-hal/src/soc/esp32c2/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,11 @@ crate::peripherals! {
UART1 <= UART1,
WIFI <= virtual,
XTS_AES <= XTS_AES,
MEM2MEM1 <= virtual,
MEM2MEM2 <= virtual,
MEM2MEM3 <= virtual,
MEM2MEM4 <= virtual,
MEM2MEM5 <= virtual,
MEM2MEM6 <= virtual,
MEM2MEM8 <= virtual,
}
9 changes: 9 additions & 0 deletions esp-hal/src/soc/esp32c6/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,13 @@ crate::peripherals! {
UHCI0 <= UHCI0,
USB_DEVICE <= USB_DEVICE,
WIFI <= virtual,
MEM2MEM1 <= virtual,
MEM2MEM4 <= virtual,
MEM2MEM5 <= virtual,
MEM2MEM10 <= virtual,
MEM2MEM11 <= virtual,
MEM2MEM12 <= virtual,
MEM2MEM13 <= virtual,
MEM2MEM14 <= virtual,
MEM2MEM15 <= virtual,
}
9 changes: 9 additions & 0 deletions esp-hal/src/soc/esp32h2/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,13 @@ crate::peripherals! {
UART1 <= UART1,
UHCI0 <= UHCI0,
USB_DEVICE <= USB_DEVICE,
MEM2MEM1 <= virtual,
MEM2MEM4 <= virtual,
MEM2MEM5 <= virtual,
MEM2MEM10 <= virtual,
MEM2MEM11 <= virtual,
MEM2MEM12 <= virtual,
MEM2MEM13 <= virtual,
MEM2MEM14 <= virtual,
MEM2MEM15 <= virtual,
}
14 changes: 6 additions & 8 deletions examples/src/bin/dma_mem2mem.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Uses DMA to copy memory to memory.
//!
//% FEATURES: esp-hal/log
//% CHIPS: esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
Expand All @@ -11,7 +10,7 @@ use esp_backtrace as _;
use esp_hal::{
clock::ClockControl,
delay::Delay,
dma::{Dma, DmaPeripheral, DmaPriority, Mem2Mem},
dma::{Dma, DmaPriority, Mem2Mem},
dma_buffers,
peripherals::Peripherals,
prelude::*,
Expand All @@ -20,10 +19,6 @@ use esp_hal::{
use log::{error, info};

const DATA_SIZE: usize = 1024 * 10;
#[cfg(feature = "esp32s3")]
const DMA_PERIPHERAL: DmaPeripheral = DmaPeripheral::Adc;
#[cfg(not(feature = "esp32s3"))]
const DMA_PERIPHERAL: DmaPeripheral = DmaPeripheral::Mem2Mem1;

#[entry]
fn main() -> ! {
Expand All @@ -38,9 +33,12 @@ fn main() -> ! {

let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
let dma_peripheral = peripherals.SPI2;
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
let dma_peripheral = peripherals.MEM2MEM1;

let mut mem2mem =
unsafe { Mem2Mem::new(channel, DMA_PERIPHERAL, tx_descriptors, rx_descriptors) };
let mut mem2mem = Mem2Mem::new(channel, dma_peripheral, tx_descriptors, rx_descriptors);

for i in 0..core::mem::size_of_val(tx_buffer) {
tx_buffer[i] = (i % 256) as u8;
Expand Down

0 comments on commit 81b5266

Please sign in to comment.