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();