Skip to content

Commit

Permalink
Move DMA channels into Peripherals
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Nov 15, 2024
1 parent 2e30073 commit c4b8db8
Show file tree
Hide file tree
Showing 48 changed files with 267 additions and 336 deletions.
64 changes: 17 additions & 47 deletions esp-hal/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,51 +750,21 @@ crate::impl_dma_eligible! {
}
}

/// GDMA Peripheral
///
/// This offers the available DMA channels.
pub struct Dma<'d> {
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
/// Channel 0
pub channel0: DmaChannel0,
/// Channel 1
#[cfg(not(esp32c2))]
pub channel1: DmaChannel1,
/// Channel 2
#[cfg(not(esp32c2))]
pub channel2: DmaChannel2,
/// Channel 3
#[cfg(esp32s3)]
pub channel3: DmaChannel3,
/// Channel 4
#[cfg(esp32s3)]
pub channel4: DmaChannel4,
}

impl<'d> Dma<'d> {
/// Create a DMA instance.
pub fn new(dma: impl Peripheral<P = crate::peripherals::DMA> + 'd) -> Dma<'d> {
crate::into_ref!(dma);

PeripheralClockControl::enable(system::Peripheral::Gdma);
dma.misc_conf().modify(|_, w| w.ahbm_rst_inter().set_bit());
dma.misc_conf()
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
dma.misc_conf().modify(|_, w| w.clk_en().set_bit());

unsafe {
Dma {
_inner: dma,
channel0: DmaChannel0::steal(),
#[cfg(not(esp32c2))]
channel1: DmaChannel1::steal(),
#[cfg(not(esp32c2))]
channel2: DmaChannel2::steal(),
#[cfg(esp32s3)]
channel3: DmaChannel3::steal(),
#[cfg(esp32s3)]
channel4: DmaChannel4::steal(),
}
}
}
pub(super) fn init_dma() {
use portable_atomic::{AtomicBool, Ordering};
static INITED: AtomicBool = AtomicBool::new(false);

if INITED
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_err()
{
return;
}

PeripheralClockControl::enable(system::Peripheral::Gdma);
let dma = unsafe { crate::soc::peripherals::DMA::steal() };
dma.misc_conf().modify(|_, w| w.ahbm_rst_inter().set_bit());
dma.misc_conf()
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
dma.misc_conf().modify(|_, w| w.clk_en().set_bit());
}
27 changes: 16 additions & 11 deletions esp-hal/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::dma_buffers;
//! # use esp_hal::spi::{master::{Config, Spi}, SpiMode};
//! # use esp_hal::dma::Dma;
//! let dma = Dma::new(peripherals.DMA);
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.spi2channel;")]
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = peripherals.DMA_SPI2;")]
#![cfg_attr(
not(any(esp32, esp32s2)),
doc = "let dma_channel = peripherals.DMA_CH0;"
)]
//! let sclk = peripherals.GPIO0;
//! let miso = peripherals.GPIO2;
//! let mosi = peripherals.GPIO4;
Expand All @@ -40,7 +41,7 @@
//! .with_mosi(mosi)
//! .with_miso(miso)
//! .with_cs(cs)
//! .with_dma(dma_channel);
//! .with_dma(peripherals.DMA_SPI2);
//! # }
//! ```
//!
Expand Down Expand Up @@ -1639,7 +1640,7 @@ impl<DEG: DmaChannel> DmaChannelConvert<DEG> for DEG {
#[cfg_attr(pdma, doc = "")]
#[cfg_attr(
pdma,
doc = "Note that using mismatching channels (e.g. trying to use `spi2channel` with SPI3) may compile, but will panic in runtime."
doc = "Note that using mismatching channels (e.g. trying to use `DMA_SPI2` with SPI3) may compile, but will panic in runtime."
)]
#[cfg_attr(pdma, doc = "")]
/// ## Example
Expand All @@ -1652,14 +1653,12 @@ impl<DEG: DmaChannel> DmaChannelConvert<DEG> for DEG {
/// use esp_hal::spi::master::{Spi, Config, Instance as SpiInstance};
/// use esp_hal::dma::CompatibleWith;
/// use esp_hal::Blocking;
/// use esp_hal::dma::Dma;
///
/// fn takes_spi<S: SpiInstance>(spi: Spi<'_, Blocking, S>, channel: impl
/// CompatibleWith<S>) {}
///
/// let dma = Dma::new(peripherals.DMA);
#[cfg_attr(pdma, doc = "let dma_channel = dma.spi2channel;")]
#[cfg_attr(gdma, doc = "let dma_channel = dma.channel0;")]
#[doc = ""]
#[cfg_attr(pdma, doc = "let dma_channel = peripherals.DMA_SPI2;")]
#[cfg_attr(gdma, doc = "let dma_channel = peripherals.DMA_CH0;")]
#[doc = ""]
/// let spi = Spi::new_with_config(
/// peripherals.SPI2,
Expand Down Expand Up @@ -1773,6 +1772,9 @@ where
/// Creates a new RX channel half.
pub fn new(rx_impl: impl Peripheral<P = CH> + 'a) -> Self {
crate::into_ref!(rx_impl);

init_dma();

#[cfg(gdma)]
// clear the mem2mem mode to avoid failed DMA if this
// channel was previously used for a mem2mem transfer.
Expand Down Expand Up @@ -2067,6 +2069,9 @@ where
/// Creates a new TX channel half.
pub fn new(tx_impl: impl Peripheral<P = CH> + 'a) -> Self {
crate::into_ref!(tx_impl);

init_dma();

if let Some(interrupt) = tx_impl.peripheral_interrupt() {
for cpu in Cpu::all() {
crate::interrupt::disable(cpu, interrupt);
Expand Down
67 changes: 23 additions & 44 deletions esp-hal/src/dma/pdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,50 +915,29 @@ crate::impl_dma_eligible!([I2s0DmaChannel] I2S0 => I2s0);
#[cfg(i2s1)]
crate::impl_dma_eligible!([I2s1DmaChannel] I2S1 => I2s1);

/// DMA Peripheral
///
/// This offers the available DMA channels.
pub struct Dma<'d> {
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
/// DMA channel for SPI2
pub spi2channel: Spi2DmaChannel,
/// DMA channel for SPI3
pub spi3channel: Spi3DmaChannel,
/// DMA channel for I2S0
pub i2s0channel: I2s0DmaChannel,
/// DMA channel for I2S1
#[cfg(i2s1)]
pub i2s1channel: I2s1DmaChannel,
}

impl<'d> Dma<'d> {
/// Create a DMA instance.
pub fn new(dma: impl Peripheral<P = crate::peripherals::DMA> + 'd) -> Dma<'d> {
PeripheralClockControl::enable(system::Peripheral::Dma);

#[cfg(esp32)]
{
// (only) on ESP32 we need to configure DPORT for the SPI DMA channels
// This assignes the DMA channels to the SPI peripherals, which is more
// restrictive than necessary but we currently support the same
// number of SPI peripherals as SPI DMA channels so it's not a big
// deal.
let dport = unsafe { &*crate::peripherals::DPORT::PTR };
dport.spi_dma_chan_sel().modify(|_, w| unsafe {
w.spi2_dma_chan_sel().bits(1).spi3_dma_chan_sel().bits(2)
});
}

unsafe {
Dma {
_inner: dma.into_ref(),
spi2channel: Spi2DmaChannel::steal(),
spi3channel: Spi3DmaChannel::steal(),
i2s0channel: I2s0DmaChannel::steal(),
#[cfg(i2s1)]
i2s1channel: I2s1DmaChannel::steal(),
}
}
pub(super) fn init_dma() {
static INITED: AtomicBool = AtomicBool::new(false);

if INITED
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_err()
{
return;
}

PeripheralClockControl::enable(system::Peripheral::Dma);

#[cfg(esp32)]
{
// (only) on ESP32 we need to configure DPORT for the SPI DMA channels
// This assignes the DMA channels to the SPI peripherals, which is more
// restrictive than necessary but we currently support the same
// number of SPI peripherals as SPI DMA channels so it's not a big
// deal.
let dport = unsafe { crate::peripherals::DPORT::steal() };
dport
.spi_dma_chan_sel()
.modify(|_, w| unsafe { w.spi2_dma_chan_sel().bits(1).spi3_dma_chan_sel().bits(2) });
}
}

Expand Down
9 changes: 5 additions & 4 deletions esp-hal/src/i2s/master.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::i2s::master::{I2s, Standard, DataFormat};
//! # use esp_hal::dma_buffers;
//! # use esp_hal::dma::Dma;
//! let dma = Dma::new(peripherals.DMA);
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.i2s0channel;")]
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = peripherals.DMA_I2S0;")]
#![cfg_attr(
not(any(esp32, esp32s2)),
doc = "let dma_channel = peripherals.DMA_CH0;"
)]
//! let (mut rx_buffer, rx_descriptors, _, tx_descriptors) =
//! dma_buffers!(0, 4 * 4092);
//!
Expand Down
6 changes: 1 addition & 5 deletions esp-hal/src/lcd_cam/cam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@
//! # use esp_hal::lcd_cam::{cam::{Camera, RxEightBits}, LcdCam};
//! # use fugit::RateExtU32;
//! # use esp_hal::dma_rx_stream_buffer;
//! # use esp_hal::dma::Dma;
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//!
//! # let dma_buf = dma_rx_stream_buffer!(20 * 1000, 1000);
//!
Expand All @@ -44,7 +40,7 @@
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
//! let mut camera = Camera::new(
//! lcd_cam.cam,
//! channel,
//! peripherals.DMA_CH0,
//! data_pins,
//! 20u32.MHz(),
//! )
Expand Down
7 changes: 2 additions & 5 deletions esp-hal/src/lcd_cam/lcd/i8080.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::lcd_cam::{LcdCam, lcd::i8080::{Config, I8080, TxEightBits}};
//! # use esp_hal::dma_tx_buffer;
//! # use esp_hal::dma::{Dma, DmaTxBuf};
//!
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//! # use esp_hal::dma::DmaTxBuf;
//!
//! # let mut dma_buf = dma_tx_buffer!(32678).unwrap();
//!
Expand All @@ -38,7 +35,7 @@
//!
//! let mut i8080 = I8080::new(
//! lcd_cam.lcd,
//! channel,
//! peripherals.DMA_CH0,
//! tx_pins,
//! 20.MHz(),
//! Config::default(),
Expand Down
16 changes: 15 additions & 1 deletion esp-hal/src/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,15 @@ mod peripheral_macros {
peripherals: [
$(
$name:ident <= $from_pac:tt $(($($interrupt:ident),*))?
), *$(,)?
),* $(,)?
],
pins: [
$( ( $pin:literal, $($pin_tokens:tt)* ) )*
],
dma_channels: [
$(
$channel_name:ident : $channel_ty:path
),* $(,)?
]
) => {

Expand Down Expand Up @@ -280,6 +285,11 @@ mod peripheral_macros {
#[doc = concat!("GPIO", stringify!($pin))]
pub [<GPIO $pin>]: $crate::gpio::GpioPin<$pin>,
)*

$(
#[doc = concat!(stringify!($channel_name), " DMA channel.")]
pub $channel_name: $crate::dma::$channel_ty,
)*
}

impl Peripherals {
Expand Down Expand Up @@ -313,6 +323,10 @@ mod peripheral_macros {
$(
[<GPIO $pin>]: $crate::gpio::GpioPin::<$pin>::steal(),
)*

$(
$channel_name: $crate::dma::$channel_ty::steal(),
)*
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion esp-hal/src/soc/esp32/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ crate::peripherals! {
CPU_CTRL <= virtual,
DAC1 <= virtual,
DAC2 <= virtual,
DMA <= virtual,
EFUSE <= EFUSE,
FLASH_ENCRYPTION <= FLASH_ENCRYPTION,
FRC_TIMER <= FRC_TIMER,
Expand Down Expand Up @@ -112,5 +111,11 @@ crate::peripherals! {
(37, [Input, Analog, RtcIoInput])
(38, [Input, Analog, RtcIoInput])
(39, [Input, Analog, RtcIoInput])
],
dma_channels: [
DMA_SPI2: Spi2DmaChannel,
DMA_SPI3: Spi3DmaChannel,
DMA_I2S0: I2s0DmaChannel,
DMA_I2S1: I2s1DmaChannel,
]
}
4 changes: 3 additions & 1 deletion esp-hal/src/soc/esp32c2/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ crate::peripherals! {
APB_CTRL <= APB_CTRL,
ASSIST_DEBUG <= ASSIST_DEBUG,
BT <= virtual,
DMA <= DMA (DMA_CH0),
ECC <= ECC,
EFUSE <= EFUSE,
EXTMEM <= EXTMEM,
Expand Down Expand Up @@ -72,5 +71,8 @@ crate::peripherals! {
(18, [Input, Output])
(19, [Input, Output])
(20, [Input, Output] (0 => U0RXD) ())
],
dma_channels: [
DMA_CH0: DmaChannel0,
]
}
6 changes: 5 additions & 1 deletion esp-hal/src/soc/esp32c3/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ crate::peripherals! {
APB_CTRL <= APB_CTRL,
ASSIST_DEBUG <= ASSIST_DEBUG,
BT <= virtual,
DMA <= DMA (DMA_CH0,DMA_CH1,DMA_CH2),
DS <= DS,
EFUSE <= EFUSE,
EXTMEM <= EXTMEM,
Expand Down Expand Up @@ -85,5 +84,10 @@ crate::peripherals! {
(19, [Input, Output])
(20, [Input, Output] (0 => U0RXD) ())
(21, [Input, Output] () (0 => U0TXD))
],
dma_channels: [
DMA_CH0: DmaChannel0,
DMA_CH1: DmaChannel1,
DMA_CH2: DmaChannel2,
]
}
6 changes: 5 additions & 1 deletion esp-hal/src/soc/esp32c6/peripherals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ crate::peripherals! {
ASSIST_DEBUG <= ASSIST_DEBUG,
ATOMIC <= ATOMIC,
BT <= virtual,
DMA <= DMA (DMA_IN_CH0,DMA_IN_CH1,DMA_IN_CH2,DMA_OUT_CH0,DMA_OUT_CH1,DMA_OUT_CH2),
DS <= DS,
ECC <= ECC,
EFUSE <= EFUSE,
Expand Down Expand Up @@ -130,5 +129,10 @@ crate::peripherals! {
(28, [Input, Output] (0 => SPIHD) (0 => SPIHD))
(29, [Input, Output] () (0 => SPICLK_MUX))
(30, [Input, Output] (0 => SPID) (0 => SPID))
],
dma_channels: [
DMA_CH0: DmaChannel0,
DMA_CH1: DmaChannel1,
DMA_CH2: DmaChannel2,
]
}
Loading

0 comments on commit c4b8db8

Please sign in to comment.