diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md
index 0348757aaf5..b058fffe6a4 100644
--- a/esp-hal/CHANGELOG.md
+++ b/esp-hal/CHANGELOG.md
@@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- ESP32-S3: Added SDMMC signals (#2556)
- Added `set_priority` to the `DmaChannel` trait on GDMA devices (#2403, #2526)
- Added `into_async` and `into_blocking` functions for `ParlIoTxOnly`, `ParlIoRxOnly` (#2526)
-- ESP32-C6, H2, S3: Added `split` function to the `DmaChannel` trait. (#2526)
+- ESP32-C6, H2, S3: Added `split` function to the `DmaChannel` trait. (#2526, #2532)
+- DMA: `PeripheralDmaChannel` type aliasses and `DmaChannelFor` traits to improve usability. (#2532)
### Changed
diff --git a/esp-hal/MIGRATING-0.22.md b/esp-hal/MIGRATING-0.22.md
index 92e53418c13..1e930faaee2 100644
--- a/esp-hal/MIGRATING-0.22.md
+++ b/esp-hal/MIGRATING-0.22.md
@@ -1,6 +1,8 @@
# Migration Guide from 0.22.x to v1.0.0-beta.0
-## DMA configuration changes
+## DMA changes
+
+### Configuration changes
- `configure_for_async` and `configure` have been removed
- PDMA devices (ESP32, ESP32-S2) provide no configurability
@@ -27,6 +29,76 @@
+.with_dma(dma_channel);
```
+### Usability changes affecting applications
+
+Individual channels are no longer wrapped in `Channel`, but they implement the `DmaChannel` trait.
+This means that if you want to split them into an `rx` and a `tx` half (which is only supported on
+the H2, C6 and S3 currently), you can't move out of the channel but instead you need to call
+the `split` method.
+
+```diff
+-let tx = channel.tx;
++use esp_hal::dma::DmaChannel;
++let (rx, tx) = channel.split();
+```
+
+The `Channel` types remain available for use in peripheral drivers.
+
+It is now simpler to work with DMA channels in generic contexts. esp-hal now provides convenience
+traits and type aliasses to specify peripheral compatibility. The `ChannelCreator` types have been
+removed, further simplifying use.
+
+For example, previously you may have needed to write something like this to accept a DMA channel
+in a generic function:
+
+```rust
+fn new_foo<'d, T>(
+ dma_channel: ChannelCreator<2>, // It wasn't possible to accept a generic ChannelCreator.
+ peripheral: impl Peripheral
+ 'd,
+)
+where
+ T: SomePeripheralInstance,
+ ChannelCreator<2>: DmaChannelConvert<::Dma>,
+{
+ let dma_channel = dma_channel.configure_for_async(false, DmaPriority::Priority0);
+
+ let driver = PeripheralDriver::new(peripheral, config).with_dma(dma_channel);
+
+ // ...
+}
+```
+
+From now on a similar, but more flexible implementation may look like:
+
+```rust
+fn new_foo<'d, T, CH>(
+ dma_channel: impl Peripheral + 'd,
+ peripheral: impl Peripheral
+ 'd,
+)
+where
+ T: SomePeripheralInstance,
+ CH: DmaChannelFor,
+{
+ // Optionally: dma_channel.set_priority(DmaPriority::Priority2);
+
+ let driver = PeripheralDriver::new(peripheral, config).with_dma(dma_channel);
+
+ // ...
+}
+```
+
+### Usability changes affecting third party peripheral drivers
+
+If you are writing a driver and need to store a channel in a structure, you can use one of the
+`ChannelFor` type aliasses.
+
+```diff
+ struct Aes<'d> {
+- channel: ChannelTx<'d, Blocking, ::Dma>,
++ channel: ChannelTx<'d, Blocking, PeripheralTxChannel>,
+ }
+```
+
## Timer changes
The low level timers, `SystemTimer` and `TimerGroup` are now "dumb". They contain no logic for operating modes or trait implementations (except the low level `Timer` trait).
diff --git a/esp-hal/src/aes/mod.rs b/esp-hal/src/aes/mod.rs
index f2a32f245c2..e80f0d96a34 100644
--- a/esp-hal/src/aes/mod.rs
+++ b/esp-hal/src/aes/mod.rs
@@ -241,16 +241,16 @@ pub mod dma {
ChannelRx,
ChannelTx,
DescriptorChain,
- DmaChannelConvert,
DmaChannelFor,
DmaDescriptor,
DmaPeripheral,
DmaTransferRxTx,
+ PeripheralDmaChannel,
+ PeripheralRxChannel,
+ PeripheralTxChannel,
ReadBuffer,
Rx,
- RxChannelFor,
Tx,
- TxChannelFor,
WriteBuffer,
},
peripheral::Peripheral,
@@ -281,7 +281,7 @@ pub mod dma {
/// The underlying [`Aes`](super::Aes) driver
pub aes: super::Aes<'d>,
- channel: Channel<'d, Blocking, DmaChannelFor>,
+ channel: Channel<'d, Blocking, PeripheralDmaChannel>,
rx_chain: DescriptorChain,
tx_chain: DescriptorChain,
}
@@ -295,7 +295,7 @@ pub mod dma {
tx_descriptors: &'static mut [DmaDescriptor],
) -> AesDma<'d>
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
let channel = Channel::new(channel.map(|ch| ch.degrade()));
channel.runtime_ensure_compatible(&self.aes);
@@ -331,7 +331,7 @@ pub mod dma {
}
impl<'d> DmaSupportTx for AesDma<'d> {
- type TX = ChannelTx<'d, Blocking, TxChannelFor>;
+ type TX = ChannelTx<'d, Blocking, PeripheralTxChannel>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
@@ -343,7 +343,7 @@ pub mod dma {
}
impl<'d> DmaSupportRx for AesDma<'d> {
- type RX = ChannelRx<'d, Blocking, RxChannelFor>;
+ type RX = ChannelRx<'d, Blocking, PeripheralRxChannel>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs
index 3d7fd7fa395..3d762572558 100644
--- a/esp-hal/src/dma/gdma.rs
+++ b/esp-hal/src/dma/gdma.rs
@@ -60,6 +60,12 @@ impl Peripheral for AnyGdmaRxChannel {
}
}
+impl DmaChannelConvert for AnyGdmaRxChannel {
+ fn degrade(self) -> AnyGdmaRxChannel {
+ self
+ }
+}
+
/// An arbitrary GDMA TX channel
pub struct AnyGdmaTxChannel(u8);
@@ -71,6 +77,12 @@ impl Peripheral for AnyGdmaTxChannel {
}
}
+impl DmaChannelConvert for AnyGdmaTxChannel {
+ fn degrade(self) -> AnyGdmaTxChannel {
+ self
+ }
+}
+
use embassy_sync::waitqueue::AtomicWaker;
static TX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs
index cbe9a281317..bdcfb8a63e5 100644
--- a/esp-hal/src/dma/mod.rs
+++ b/esp-hal/src/dma/mod.rs
@@ -944,38 +944,6 @@ pub trait DmaEligible {
fn dma_peripheral(&self) -> DmaPeripheral;
}
-/// Helper type to get the DMA (Rx and Tx) channel for a peripheral.
-pub type DmaChannelFor = ::Dma;
-/// Helper type to get the DMA Rx channel for a peripheral.
-pub type RxChannelFor = as DmaChannel>::Rx;
-/// Helper type to get the DMA Tx channel for a peripheral.
-pub type TxChannelFor = as DmaChannel>::Tx;
-
-#[doc(hidden)]
-#[macro_export]
-macro_rules! impl_dma_eligible {
- ([$dma_ch:ident] $name:ident => $dma:ident) => {
- impl $crate::dma::DmaEligible for $crate::peripherals::$name {
- type Dma = $dma_ch;
-
- fn dma_peripheral(&self) -> $crate::dma::DmaPeripheral {
- $crate::dma::DmaPeripheral::$dma
- }
- }
- };
-
- (
- $dma_ch:ident {
- $($(#[$cfg:meta])? $name:ident => $dma:ident,)*
- }
- ) => {
- $(
- $(#[$cfg])?
- $crate::impl_dma_eligible!([$dma_ch] $name => $dma);
- )*
- };
-}
-
#[doc(hidden)]
#[derive(Debug)]
pub struct DescriptorChain {
@@ -1593,6 +1561,38 @@ impl RxCircularState {
}
}
+#[doc(hidden)]
+#[macro_export]
+macro_rules! impl_dma_eligible {
+ ([$dma_ch:ident] $name:ident => $dma:ident) => {
+ impl $crate::dma::DmaEligible for $crate::peripherals::$name {
+ type Dma = $dma_ch;
+
+ fn dma_peripheral(&self) -> $crate::dma::DmaPeripheral {
+ $crate::dma::DmaPeripheral::$dma
+ }
+ }
+ };
+
+ (
+ $dma_ch:ident {
+ $($(#[$cfg:meta])? $name:ident => $dma:ident,)*
+ }
+ ) => {
+ $(
+ $(#[$cfg])?
+ $crate::impl_dma_eligible!([$dma_ch] $name => $dma);
+ )*
+ };
+}
+
+/// Helper type to get the DMA (Rx and Tx) channel for a peripheral.
+pub type PeripheralDmaChannel = ::Dma;
+/// Helper type to get the DMA Rx channel for a peripheral.
+pub type PeripheralRxChannel = as DmaChannel>::Rx;
+/// Helper type to get the DMA Tx channel for a peripheral.
+pub type PeripheralTxChannel = as DmaChannel>::Tx;
+
#[doc(hidden)]
pub trait DmaRxChannel:
RxRegisterAccess + InterruptAccess + Peripheral
@@ -1647,7 +1647,7 @@ pub trait DmaChannelExt: DmaChannel {
note = "Not all channels are useable with all peripherals"
)]
#[doc(hidden)]
-pub trait DmaChannelConvert: DmaChannel {
+pub trait DmaChannelConvert {
fn degrade(self) -> DEG;
}
@@ -1657,6 +1657,94 @@ impl DmaChannelConvert for DEG {
}
}
+/// Trait implemented for DMA channels that are compatible with a particular
+/// peripheral.
+///
+/// You can use this in places where a peripheral driver would expect a
+/// `DmaChannel` implementation.
+#[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."
+)]
+#[cfg_attr(pdma, doc = "")]
+/// ## Example
+///
+/// The following example demonstrates how this trait can be used to only accept
+/// types compatible with a specific peripheral.
+///
+/// ```rust,no_run
+#[doc = crate::before_snippet!()]
+/// use esp_hal::spi::master::{Spi, SpiDma, Config, Instance as SpiInstance};
+/// use esp_hal::dma::DmaChannelFor;
+/// use esp_hal::peripheral::Peripheral;
+/// use esp_hal::Blocking;
+/// use esp_hal::dma::Dma;
+///
+/// fn configures_spi_dma<'d, S, CH>(
+/// spi: Spi<'d, Blocking, S>,
+/// channel: impl Peripheral + 'd,
+/// ) -> SpiDma<'d, Blocking, S>
+/// where
+/// S: SpiInstance,
+/// CH: DmaChannelFor + 'd,
+/// {
+/// spi.with_dma(channel)
+/// }
+///
+/// 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 = ""]
+/// let spi = Spi::new_with_config(
+/// peripherals.SPI2,
+/// Config::default(),
+/// );
+///
+/// let spi_dma = configures_spi_dma(spi, dma_channel);
+/// # }
+/// ```
+pub trait DmaChannelFor:
+ DmaChannel + DmaChannelConvert>
+{
+}
+impl DmaChannelFor
for CH
+where
+ P: DmaEligible,
+ CH: DmaChannel + DmaChannelConvert>,
+{
+}
+
+/// Trait implemented for the RX half of split DMA channels that are compatible
+/// with a particular peripheral. Accepts complete DMA channels or split halves.
+///
+/// This trait is similar in use to [`DmaChannelFor`].
+///
+/// You can use this in places where a peripheral driver would expect a
+/// `DmaRxChannel` implementation.
+pub trait RxChannelFor: DmaChannelConvert> {}
+impl RxChannelFor
for RX
+where
+ P: DmaEligible,
+ RX: DmaChannelConvert>,
+{
+}
+
+/// Trait implemented for the TX half of split DMA channels that are compatible
+/// with a particular peripheral. Accepts complete DMA channels or split halves.
+///
+/// This trait is similar in use to [`DmaChannelFor`].
+///
+/// You can use this in places where a peripheral driver would expect a
+/// `DmaTxChannel` implementation.
+pub trait TxChannelFor: DmaChannelConvert> {}
+impl TxChannelFor
for TX
+where
+ P: DmaEligible,
+ TX: DmaChannelConvert>,
+{
+}
+
/// The functions here are not meant to be used outside the HAL
#[doc(hidden)]
pub trait Rx: crate::private::Sealed {
diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs
index cdaaaee27e1..7fb77f84879 100644
--- a/esp-hal/src/i2s/master.rs
+++ b/esp-hal/src/i2s/master.rs
@@ -81,7 +81,6 @@ use crate::{
ChannelRx,
ChannelTx,
DescriptorChain,
- DmaChannelConvert,
DmaChannelFor,
DmaDescriptor,
DmaEligible,
@@ -90,11 +89,12 @@ use crate::{
DmaTransferRxCircular,
DmaTransferTx,
DmaTransferTxCircular,
+ PeripheralDmaChannel,
+ PeripheralRxChannel,
+ PeripheralTxChannel,
ReadBuffer,
Rx,
- RxChannelFor,
Tx,
- TxChannelFor,
WriteBuffer,
},
gpio::interconnect::PeripheralOutput,
@@ -271,7 +271,7 @@ where
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into,
- channel: PeripheralRef<'d, DmaChannelFor>,
+ channel: PeripheralRef<'d, PeripheralDmaChannel>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
@@ -377,7 +377,7 @@ impl<'d> I2s<'d, Blocking> {
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
Self::new_typed(
i2s.map_into(),
@@ -408,7 +408,7 @@ where
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
crate::into_ref!(i2s);
Self::new_internal(
@@ -463,7 +463,7 @@ where
DmaMode: Mode,
{
i2s: PeripheralRef<'d, T>,
- tx_channel: ChannelTx<'d, DmaMode, TxChannelFor>,
+ tx_channel: ChannelTx<'d, DmaMode, PeripheralTxChannel>,
tx_chain: DescriptorChain,
_guard: PeripheralGuard,
}
@@ -497,7 +497,7 @@ where
T: RegisterAccess,
DmaMode: Mode,
{
- type TX = ChannelTx<'d, DmaMode, TxChannelFor>;
+ type TX = ChannelTx<'d, DmaMode, PeripheralTxChannel>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
@@ -596,7 +596,7 @@ where
DmaMode: Mode,
{
i2s: PeripheralRef<'d, T>,
- rx_channel: ChannelRx<'d, DmaMode, RxChannelFor>,
+ rx_channel: ChannelRx<'d, DmaMode, PeripheralRxChannel>,
rx_chain: DescriptorChain,
_guard: PeripheralGuard,
}
@@ -630,7 +630,7 @@ where
T: RegisterAccess,
DmaMode: Mode,
{
- type RX = ChannelRx<'d, DmaMode, RxChannelFor>;
+ type RX = ChannelRx<'d, DmaMode, PeripheralRxChannel>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
@@ -766,7 +766,7 @@ mod private {
M: Mode,
{
pub i2s: PeripheralRef<'d, T>,
- pub tx_channel: ChannelTx<'d, M, TxChannelFor>,
+ pub tx_channel: ChannelTx<'d, M, PeripheralTxChannel>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) guard: PeripheralGuard,
}
@@ -826,7 +826,7 @@ mod private {
M: Mode,
{
pub i2s: PeripheralRef<'d, T>,
- pub rx_channel: ChannelRx<'d, M, RxChannelFor>,
+ pub rx_channel: ChannelRx<'d, M, PeripheralRxChannel>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) guard: PeripheralGuard,
}
diff --git a/esp-hal/src/i2s/parallel.rs b/esp-hal/src/i2s/parallel.rs
index e46f49bc8c5..d05a945c9aa 100644
--- a/esp-hal/src/i2s/parallel.rs
+++ b/esp-hal/src/i2s/parallel.rs
@@ -46,14 +46,13 @@ use crate::{
asynch::DmaTxFuture,
Channel,
ChannelTx,
- DmaChannelConvert,
DmaChannelFor,
DmaEligible,
DmaError,
DmaPeripheral,
DmaTxBuffer,
+ PeripheralTxChannel,
Tx,
- TxChannelFor,
},
gpio::{
interconnect::{OutputConnection, PeripheralOutput},
@@ -179,7 +178,7 @@ where
I: Instance,
{
instance: PeripheralRef<'d, I>,
- tx_channel: ChannelTx<'d, DM, TxChannelFor>,
+ tx_channel: ChannelTx<'d, DM, PeripheralTxChannel>,
_guard: PeripheralGuard,
}
@@ -193,7 +192,7 @@ impl<'d> I2sParallel<'d, Blocking> {
clock_pin: impl Peripheral + 'd,
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
Self::new_typed(i2s.map_into(), channel, frequency, pins, clock_pin)
}
@@ -212,7 +211,7 @@ where
clock_pin: impl Peripheral + 'd,
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
crate::into_ref!(i2s);
crate::into_mapped_ref!(clock_pin);
diff --git a/esp-hal/src/lcd_cam/cam.rs b/esp-hal/src/lcd_cam/cam.rs
index 7748259d461..e5998faef0a 100644
--- a/esp-hal/src/lcd_cam/cam.rs
+++ b/esp-hal/src/lcd_cam/cam.rs
@@ -67,7 +67,7 @@ use fugit::HertzU32;
use crate::{
clock::Clocks,
- dma::{ChannelRx, DmaChannelConvert, DmaError, DmaPeripheral, DmaRxBuffer, Rx, RxChannelFor},
+ dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, Rx, RxChannelFor},
gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal,
@@ -123,7 +123,7 @@ pub struct Cam<'d> {
/// Represents the camera interface with DMA support.
pub struct Camera<'d> {
lcd_cam: PeripheralRef<'d, LCD_CAM>,
- rx_channel: ChannelRx<'d, Blocking, RxChannelFor>,
+ rx_channel: ChannelRx<'d, Blocking, PeripheralRxChannel>,
_guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
}
@@ -136,7 +136,7 @@ impl<'d> Camera<'d> {
frequency: HertzU32,
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: RxChannelFor,
P: RxPins,
{
let rx_channel = ChannelRx::new(channel.map(|ch| ch.degrade()));
diff --git a/esp-hal/src/lcd_cam/lcd/dpi.rs b/esp-hal/src/lcd_cam/lcd/dpi.rs
index 77b30012b2b..42cef5ed496 100644
--- a/esp-hal/src/lcd_cam/lcd/dpi.rs
+++ b/esp-hal/src/lcd_cam/lcd/dpi.rs
@@ -106,7 +106,7 @@ use fugit::HertzU32;
use crate::{
clock::Clocks,
- dma::{ChannelTx, DmaChannelConvert, DmaError, DmaPeripheral, DmaTxBuffer, Tx, TxChannelFor},
+ dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, Tx, TxChannelFor},
gpio::{interconnect::PeripheralOutput, Level, OutputSignal},
lcd_cam::{
calculate_clkm,
@@ -123,7 +123,7 @@ use crate::{
/// Represents the RGB LCD interface.
pub struct Dpi<'d, DM: Mode> {
lcd_cam: PeripheralRef<'d, LCD_CAM>,
- tx_channel: ChannelTx<'d, Blocking, TxChannelFor>,
+ tx_channel: ChannelTx<'d, Blocking, PeripheralTxChannel>,
_mode: PhantomData,
}
@@ -139,7 +139,7 @@ where
config: Config,
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: TxChannelFor,
{
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
let lcd_cam = lcd.lcd_cam;
diff --git a/esp-hal/src/lcd_cam/lcd/i8080.rs b/esp-hal/src/lcd_cam/lcd/i8080.rs
index 12d9e5856b6..0255c9e6527 100644
--- a/esp-hal/src/lcd_cam/lcd/i8080.rs
+++ b/esp-hal/src/lcd_cam/lcd/i8080.rs
@@ -62,7 +62,7 @@ use fugit::HertzU32;
use crate::{
clock::Clocks,
- dma::{ChannelTx, DmaChannelConvert, DmaError, DmaPeripheral, DmaTxBuffer, Tx, TxChannelFor},
+ dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, Tx, TxChannelFor},
gpio::{
interconnect::{OutputConnection, PeripheralOutput},
OutputSignal,
@@ -85,7 +85,7 @@ use crate::{
/// Represents the I8080 LCD interface.
pub struct I8080<'d, DM: Mode> {
lcd_cam: PeripheralRef<'d, LCD_CAM>,
- tx_channel: ChannelTx<'d, Blocking, TxChannelFor>,
+ tx_channel: ChannelTx<'d, Blocking, PeripheralTxChannel>,
_mode: PhantomData,
}
@@ -102,7 +102,7 @@ where
config: Config,
) -> Self
where
- CH: DmaChannelConvert>,
+ CH: TxChannelFor,
P: TxPins,
{
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs
index d356f8ffa4b..14b7d0bf9fc 100644
--- a/esp-hal/src/parl_io.rs
+++ b/esp-hal/src/parl_io.rs
@@ -35,13 +35,14 @@ use crate::{
ChannelRx,
ChannelTx,
DescriptorChain,
- DmaChannelConvert,
DmaChannelFor,
DmaDescriptor,
DmaError,
DmaPeripheral,
DmaTransferRx,
DmaTransferTx,
+ PeripheralRxChannel,
+ PeripheralTxChannel,
ReadBuffer,
Rx,
RxChannelFor,
@@ -811,7 +812,7 @@ pub struct ParlIoTx<'d, DM>
where
DM: Mode,
{
- tx_channel: ChannelTx<'d, DM, TxChannelFor>,
+ tx_channel: ChannelTx<'d, DM, PeripheralTxChannel>,
tx_chain: DescriptorChain,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
}
@@ -892,7 +893,7 @@ pub struct ParlIoRx<'d, DM>
where
DM: Mode,
{
- rx_channel: ChannelRx<'d, DM, RxChannelFor>,
+ rx_channel: ChannelRx<'d, DM, PeripheralRxChannel>,
rx_chain: DescriptorChain,
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
}
@@ -1013,7 +1014,7 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> {
frequency: HertzU32,
) -> Result
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
let tx_guard = GenericPeripheralGuard::new();
let rx_guard = GenericPeripheralGuard::new();
@@ -1135,7 +1136,7 @@ impl<'d> ParlIoTxOnly<'d, Blocking> {
frequency: HertzU32,
) -> Result
where
- CH: DmaChannelConvert>,
+ CH: TxChannelFor,
{
let guard = GenericPeripheralGuard::new();
let tx_channel = ChannelTx::new(dma_channel.map(|ch| ch.degrade()));
@@ -1241,7 +1242,7 @@ impl<'d> ParlIoRxOnly<'d, Blocking> {
frequency: HertzU32,
) -> Result
where
- CH: DmaChannelConvert>,
+ CH: RxChannelFor,
{
let guard = GenericPeripheralGuard::new();
let rx_channel = ChannelRx::new(dma_channel.map(|ch| ch.degrade()));
@@ -1433,7 +1434,7 @@ impl<'d, DM> DmaSupportTx for ParlIoTx<'d, DM>
where
DM: Mode,
{
- type TX = ChannelTx<'d, DM, TxChannelFor>;
+ type TX = ChannelTx<'d, DM, PeripheralTxChannel>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
@@ -1475,7 +1476,7 @@ where
}
fn start_receive_bytes_dma(
- rx_channel: &mut ChannelRx<'d, DM, RxChannelFor>,
+ rx_channel: &mut ChannelRx<'d, DM, PeripheralRxChannel>,
rx_chain: &mut DescriptorChain,
ptr: *mut u8,
len: usize,
@@ -1529,7 +1530,7 @@ impl<'d, DM> DmaSupportRx for ParlIoRx<'d, DM>
where
DM: Mode,
{
- type RX = ChannelRx<'d, DM, RxChannelFor>;
+ type RX = ChannelRx<'d, DM, PeripheralRxChannel>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
@@ -1545,7 +1546,7 @@ pub struct TxCreator<'d, DM>
where
DM: Mode,
{
- tx_channel: ChannelTx<'d, DM, TxChannelFor>,
+ tx_channel: ChannelTx<'d, DM, PeripheralTxChannel>,
descriptors: &'static mut [DmaDescriptor],
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
}
@@ -1555,7 +1556,7 @@ pub struct RxCreator<'d, DM>
where
DM: Mode,
{
- rx_channel: ChannelRx<'d, DM, RxChannelFor>,
+ rx_channel: ChannelRx<'d, DM, PeripheralRxChannel>,
descriptors: &'static mut [DmaDescriptor],
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
}
@@ -1565,7 +1566,7 @@ pub struct TxCreatorFullDuplex<'d, DM>
where
DM: Mode,
{
- tx_channel: ChannelTx<'d, DM, TxChannelFor>,
+ tx_channel: ChannelTx<'d, DM, PeripheralTxChannel>,
descriptors: &'static mut [DmaDescriptor],
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
}
@@ -1575,7 +1576,7 @@ pub struct RxCreatorFullDuplex<'d, DM>
where
DM: Mode,
{
- rx_channel: ChannelRx<'d, DM, RxChannelFor>,
+ rx_channel: ChannelRx<'d, DM, PeripheralRxChannel>,
descriptors: &'static mut [DmaDescriptor],
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
}
diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs
index a07fac57355..50446ba6bca 100644
--- a/esp-hal/src/spi/master.rs
+++ b/esp-hal/src/spi/master.rs
@@ -78,7 +78,7 @@ use procmacros::ram;
use super::{DmaError, Error, SpiBitOrder, SpiDataMode, SpiMode};
use crate::{
clock::Clocks,
- dma::{DmaChannelConvert, DmaChannelFor, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
+ dma::{DmaChannelFor, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
gpio::{interconnect::PeripheralOutput, InputSignal, NoPin, OutputSignal},
interrupt::InterruptHandler,
peripheral::{Peripheral, PeripheralRef},
@@ -540,7 +540,7 @@ where
/// operations.
pub fn with_dma(self, channel: impl Peripheral + 'd) -> SpiDma<'d, Blocking, T>
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
SpiDma::new(self.spi, channel.map(|ch| ch.degrade()).into_ref())
}
@@ -856,12 +856,12 @@ mod dma {
dma::{
asynch::{DmaRxFuture, DmaTxFuture},
Channel,
- DmaChannelFor,
DmaRxBuf,
DmaRxBuffer,
DmaTxBuf,
DmaTxBuffer,
EmptyBuf,
+ PeripheralDmaChannel,
Rx,
Tx,
},
@@ -883,7 +883,7 @@ mod dma {
M: Mode,
{
pub(crate) spi: PeripheralRef<'d, T>,
- pub(crate) channel: Channel<'d, M, DmaChannelFor>,
+ pub(crate) channel: Channel<'d, M, PeripheralDmaChannel>,
tx_transfer_in_progress: bool,
rx_transfer_in_progress: bool,
#[cfg(all(esp32, spi_address_workaround))]
@@ -997,7 +997,7 @@ mod dma {
{
pub(super) fn new(
spi: PeripheralRef<'d, T>,
- channel: PeripheralRef<'d, DmaChannelFor>,
+ channel: PeripheralRef<'d, PeripheralDmaChannel>,
) -> Self {
let channel = Channel::new(channel);
channel.runtime_ensure_compatible(&spi);
diff --git a/esp-hal/src/spi/slave.rs b/esp-hal/src/spi/slave.rs
index cf48c07fe9b..4bfe0bc4572 100644
--- a/esp-hal/src/spi/slave.rs
+++ b/esp-hal/src/spi/slave.rs
@@ -73,7 +73,7 @@ use core::marker::PhantomData;
use super::{Error, SpiMode};
use crate::{
- dma::{DmaChannelConvert, DmaEligible},
+ dma::DmaEligible,
gpio::{
interconnect::{PeripheralInput, PeripheralOutput},
InputSignal,
@@ -182,11 +182,12 @@ pub mod dma {
DmaTransferRx,
DmaTransferRxTx,
DmaTransferTx,
+ PeripheralDmaChannel,
+ PeripheralRxChannel,
+ PeripheralTxChannel,
ReadBuffer,
Rx,
- RxChannelFor,
Tx,
- TxChannelFor,
WriteBuffer,
},
Mode,
@@ -206,7 +207,7 @@ pub mod dma {
tx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, Blocking, T>
where
- CH: DmaChannelConvert>,
+ CH: DmaChannelFor,
{
self.spi.info().set_data_mode(self.data_mode, true);
SpiDma::new(
@@ -225,7 +226,7 @@ pub mod dma {
M: Mode,
{
pub(crate) spi: PeripheralRef<'d, T>,
- pub(crate) channel: Channel<'d, M, DmaChannelFor>,
+ pub(crate) channel: Channel<'d, M, PeripheralDmaChannel>,
rx_chain: DescriptorChain,
tx_chain: DescriptorChain,
_guard: PeripheralGuard,
@@ -265,7 +266,7 @@ pub mod dma {
T: InstanceDma,
DmaMode: Mode,
{
- type TX = ChannelTx<'d, DmaMode, TxChannelFor>;
+ type TX = ChannelTx<'d, DmaMode, PeripheralTxChannel>;
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
@@ -281,7 +282,7 @@ pub mod dma {
T: InstanceDma,
DmaMode: Mode,
{
- type RX = ChannelRx<'d, DmaMode, RxChannelFor>;
+ type RX = ChannelRx<'d, DmaMode, PeripheralRxChannel>;
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
@@ -298,7 +299,7 @@ pub mod dma {
{
fn new(
spi: PeripheralRef<'d, T>,
- channel: PeripheralRef<'d, DmaChannelFor>,
+ channel: PeripheralRef<'d, PeripheralDmaChannel>,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> Self {
diff --git a/hil-test/tests/lcd_cam.rs b/hil-test/tests/lcd_cam.rs
index 1dcae2c785a..c1002e7fbe0 100644
--- a/hil-test/tests/lcd_cam.rs
+++ b/hil-test/tests/lcd_cam.rs
@@ -6,7 +6,7 @@
#![no_main]
use esp_hal::{
- dma::{Dma, DmaRxBuf, DmaTxBuf},
+ dma::{Dma, DmaChannel, DmaRxBuf, DmaTxBuf},
dma_buffers,
gpio::Level,
lcd_cam::{
@@ -58,9 +58,7 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
- // TODO: use split channels once supported
- let tx_channel = dma.channel2;
- let rx_channel = dma.channel3;
+ let (rx_channel, tx_channel) = dma.channel2.split();
let (vsync_in, vsync_out) = peripherals.GPIO6.split();
let (hsync_in, hsync_out) = peripherals.GPIO7.split();