Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Remove ChannelCreator types and burst mode
  • Loading branch information
bugadani committed Nov 21, 2024
commit 21cd0014d21beb0c8fbc6d816ed746b631b45563
3 changes: 3 additions & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- ESP32-S3: Added SDMMC signals (#2556)
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)

### Changed

### Fixed

### Removed

- The `configure` DMA channel functions has been removed (#2403)

## [0.22.0] - 2024-11-20

### Added
Expand Down
16 changes: 16 additions & 0 deletions esp-hal/MIGRATING-0.22.md
Original file line number Diff line number Diff line change
@@ -1 +1,17 @@
# Migration Guide from 0.22.x to v1.0.0-beta.0

## DMA configuration changes

- `configure_for_async` and `configure` have been removed
- PDMA devices (ESP32, ESP32-S2) provide no configurability
- GDMA devices provide `set_priority` to change DMA in/out channel priority

```diff
let mut spi = Spi::new_with_config(
peripherals.SPI2,
Config::default(),
)
// other setup
-.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
+.with_dma(dma_channel);
```
8 changes: 4 additions & 4 deletions esp-hal/src/dma/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ pub struct Preparation {
#[cfg_attr(not(esp32s3), allow(dead_code))]
pub block_size: Option<DmaBufBlkSize>,

/// Specifies whether descriptor linked list specified in `start` conforms
/// to the alignment requirements required to enable burst transfers.
/// Specifies whether the data should be transferred in burst mode.
///
/// Note: This only applies to burst transfer of the buffer data, not the
/// descriptors themselves.
/// The implementation of the buffer must ensure that burst mode is only
/// enabled when alignment requirements are met.
///
/// There are no additional alignment requirements for TX burst transfers,
/// but RX transfers require all descriptors to have buffer pointers and
/// sizes that are a multiple of 4 (word aligned).
// TODO: currently unused, buffers should not hardcode their preference.
pub is_burstable: bool,

/// Configures the "check owner" feature of the DMA channel.
Expand Down
54 changes: 26 additions & 28 deletions esp-hal/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,6 @@ impl<C: GdmaChannel> InterruptAccess<DmaRxInterrupt> for ChannelRxImpl<C> {
}
}

/// A Channel can be created from this
#[non_exhaustive]
pub struct ChannelCreator<const N: u8> {}

impl<CH: DmaChannel, M: Mode> Channel<'_, M, CH> {
/// Asserts that the channel is compatible with the given peripheral.
pub fn runtime_ensure_compatible<P: DmaEligible>(&self, _peripheral: &PeripheralRef<'_, P>) {
Expand Down Expand Up @@ -621,19 +617,19 @@ macro_rules! impl_channel {
}
}

impl ChannelCreator<$num> {
/// Configure the channel for use with blocking APIs
pub fn configure<'a>(
self,
burst_mode: bool,
priority: DmaPriority,
) -> Channel<'a, Blocking, [<DmaChannel $num>]> {
impl [<DmaChannel $num>] {
/// Unsafely constructs a new DMA channel.
///
/// # Safety
///
/// The caller must ensure that only a single instance is used.
pub unsafe fn steal<'a>() -> Channel<'a, Blocking, Self> {
let mut this = Channel {
tx: ChannelTx::new(ChannelTxImpl(SpecificGdmaChannel::<$num> {})),
rx: ChannelRx::new(ChannelRxImpl(SpecificGdmaChannel::<$num> {})),
};

this.configure(burst_mode, priority);
this.set_priority(DmaPriority::Priority0);

this
}
Expand Down Expand Up @@ -731,19 +727,19 @@ crate::impl_dma_eligible! {
pub struct Dma<'d> {
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
/// Channel 0
pub channel0: ChannelCreator<0>,
pub channel0: Channel<'d, Blocking, DmaChannel0>,
/// Channel 1
#[cfg(not(esp32c2))]
pub channel1: ChannelCreator<1>,
pub channel1: Channel<'d, Blocking, DmaChannel1>,
/// Channel 2
#[cfg(not(esp32c2))]
pub channel2: ChannelCreator<2>,
pub channel2: Channel<'d, Blocking, DmaChannel2>,
/// Channel 3
#[cfg(esp32s3)]
pub channel3: ChannelCreator<3>,
pub channel3: Channel<'d, Blocking, DmaChannel3>,
/// Channel 4
#[cfg(esp32s3)]
pub channel4: ChannelCreator<4>,
pub channel4: Channel<'d, Blocking, DmaChannel4>,
}

impl<'d> Dma<'d> {
Expand All @@ -761,17 +757,19 @@ impl<'d> Dma<'d> {
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
dma.misc_conf().modify(|_, w| w.clk_en().set_bit());

Dma {
_inner: dma,
channel0: ChannelCreator {},
#[cfg(not(esp32c2))]
channel1: ChannelCreator {},
#[cfg(not(esp32c2))]
channel2: ChannelCreator {},
#[cfg(esp32s3)]
channel3: ChannelCreator {},
#[cfg(esp32s3)]
channel4: ChannelCreator {},
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(),
}
}
}
}
72 changes: 25 additions & 47 deletions esp-hal/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![doc = crate::before_snippet!()]
//! # use esp_hal::dma_buffers;
//! # use esp_hal::spi::{master::{Config, Spi}, SpiMode};
//! # use esp_hal::dma::{Dma, DmaPriority};
//! # 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;")]
Expand All @@ -40,10 +40,7 @@
//! .with_mosi(mosi)
//! .with_miso(miso)
//! .with_cs(cs)
//! .with_dma(dma_channel.configure(
//! false,
//! DmaPriority::Priority0,
//! ));
//! .with_dma(dma_channel);
//! # }
//! ```
//!
Expand Down Expand Up @@ -1688,7 +1685,6 @@ pub struct ChannelRx<'a, M, CH>
where
CH: DmaChannel,
{
pub(crate) burst_mode: bool,
pub(crate) rx_impl: CH::Rx,
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
}
Expand All @@ -1711,7 +1707,6 @@ where
rx_impl.set_async(false);

Self {
burst_mode: false,
rx_impl,
_phantom: PhantomData,
}
Expand All @@ -1724,7 +1719,6 @@ where
}
self.rx_impl.set_async(true);
ChannelRx {
burst_mode: self.burst_mode,
rx_impl: self.rx_impl,
_phantom: PhantomData,
}
Expand Down Expand Up @@ -1758,7 +1752,6 @@ where
}
self.rx_impl.set_async(false);
ChannelRx {
burst_mode: self.burst_mode,
rx_impl: self.rx_impl,
_phantom: PhantomData,
}
Expand All @@ -1777,16 +1770,15 @@ where
CH: DmaChannelConvert<DEG>,
{
ChannelRx {
burst_mode: self.burst_mode,
rx_impl: CH::degrade_rx(self.rx_impl),
_phantom: PhantomData,
}
}

/// Configure the channel.
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
self.burst_mode = burst_mode;
self.rx_impl.configure(burst_mode, priority);
#[cfg(gdma)]
pub fn set_priority(&mut self, priority: DmaPriority) {
self.rx_impl.set_priority(priority);
}
}

Expand All @@ -1807,14 +1799,14 @@ where
peri: DmaPeripheral,
chain: &DescriptorChain,
) -> Result<(), DmaError> {
if self.burst_mode
&& chain
.descriptors
.iter()
.any(|d| d.len() % 4 != 0 || d.buffer as u32 % 4 != 0)
{
return Err(DmaError::InvalidAlignment);
}
// if self.burst_mode
// && chain
// .descriptors
// .iter()
// .any(|d| d.len() % 4 != 0 || d.buffer as u32 % 4 != 0)
//{
// return Err(DmaError::InvalidAlignment);
//}

// for esp32s3 we check each descriptor buffer that points to psram for
// alignment and invalidate the cache for that buffer
Expand Down Expand Up @@ -1851,9 +1843,7 @@ where
) -> Result<(), DmaError> {
let preparation = buffer.prepare();

self.rx_impl
.set_burst_mode(self.burst_mode && preparation.is_burstable);

self.rx_impl.set_burst_mode(false);
self.rx_impl.set_check_owner(preparation.check_owner);

compiler_fence(core::sync::atomic::Ordering::SeqCst);
Expand Down Expand Up @@ -1982,8 +1972,6 @@ pub struct ChannelTx<'a, M, CH>
where
CH: DmaChannel,
{
#[allow(unused)]
pub(crate) burst_mode: bool,
pub(crate) tx_impl: CH::Tx,
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
}
Expand All @@ -2001,7 +1989,6 @@ where
tx_impl.set_async(false);

Self {
burst_mode: false,
tx_impl,
_phantom: PhantomData,
}
Expand All @@ -2014,7 +2001,6 @@ where
}
self.tx_impl.set_async(true);
ChannelTx {
burst_mode: self.burst_mode,
tx_impl: self.tx_impl,
_phantom: PhantomData,
}
Expand Down Expand Up @@ -2048,7 +2034,6 @@ where
}
self.tx_impl.set_async(false);
ChannelTx {
burst_mode: self.burst_mode,
tx_impl: self.tx_impl,
_phantom: PhantomData,
}
Expand All @@ -2067,16 +2052,15 @@ where
CH: DmaChannelConvert<DEG>,
{
ChannelTx {
burst_mode: self.burst_mode,
tx_impl: CH::degrade_tx(self.tx_impl),
_phantom: PhantomData,
}
}

/// Configure the channel.
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
self.burst_mode = burst_mode;
self.tx_impl.configure(burst_mode, priority);
/// Configure the channel priority.
#[cfg(gdma)]
pub fn set_priority(&mut self, priority: DmaPriority) {
self.tx_impl.set_priority(priority);
}
}

Expand Down Expand Up @@ -2147,9 +2131,7 @@ where
}
);

self.tx_impl
.set_burst_mode(self.burst_mode && preparation.is_burstable);

self.tx_impl.set_burst_mode(false);
self.tx_impl.set_check_owner(preparation.check_owner);

compiler_fence(core::sync::atomic::Ordering::SeqCst);
Expand Down Expand Up @@ -2228,6 +2210,7 @@ pub trait RegisterAccess: crate::private::Sealed {

/// The priority of the channel. The larger the value, the higher the
/// priority.
#[cfg(gdma)]
fn set_priority(&self, priority: DmaPriority);

/// Select a peripheral for the channel.
Expand All @@ -2254,12 +2237,6 @@ pub trait RegisterAccess: crate::private::Sealed {

#[cfg(pdma)]
fn is_compatible_with(&self, peripheral: DmaPeripheral) -> bool;

/// Configure the channel.
fn configure(&self, burst_mode: bool, priority: DmaPriority) {
self.set_burst_mode(burst_mode);
self.set_priority(priority);
}
}

#[doc(hidden)]
Expand Down Expand Up @@ -2375,10 +2352,11 @@ where
}
}

/// Configure the channel.
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
self.rx.configure(burst_mode, priority);
self.tx.configure(burst_mode, priority);
/// Configure the channel priorities.
#[cfg(gdma)]
pub fn set_priority(&mut self, priority: DmaPriority) {
self.tx.set_priority(priority);
self.rx.set_priority(priority);
}

/// Converts a blocking channel to an async channel.
Expand Down
Loading