Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DMA 5/N]: Clean up duplicate PDMA instance macro #2527

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions esp-hal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- I8080: Added `set_8bits_order()` to set the byte order in 8-bit mode (#2487)
- `I2c::{apply_config(), with_sda(), with_scl()}` (#2477)
- ESP32-S2: Added missing GPIO alternate functions (#2512)
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)

### Changed

Expand All @@ -65,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `I2c` SCL timeout is now defined in bus clock cycles. (#2477)
- Trying to send a single-shot RMT transmission will result in an error now, `RMT` deals with `u32` now, `PulseCode` is a convenience trait now (#2463)
- Removed `get_` prefixes from functions (#2528)
- The `I8080` driver's constructor now only accepts blocking-mode DMA channels. (#2519)

### Fixed

Expand Down Expand Up @@ -97,6 +99,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed the pin type parameters from `lcd_cam::cam::{RxEightBits, RxSixteenBits}` (#2388)
- Most of the async-specific constructors (`new_async`, `new_async_no_transceiver`) have been removed. (#2430)
- The `configure_for_async` DMA functions have been removed (#2430)
- The `configure` DMA channel functions has been removed (#2403)
- The `Uart::{change_baud, change_stop_bits}` functions have been removed (#2449)
- `gpio::{Input, Output, OutputOpenDrain, Flex, GpioPin}::{peripheral_input, into_peripheral_output}` have been removed. (#2418)
- The `GpioEtm` prefix has been removed from `gpio::etm` types (#2427)
Expand Down Expand Up @@ -180,6 +183,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- The DMA channel types have been removed from peripherals (#2261)
- `I2C` driver renamed to `I2c` (#2320)
- The GPIO pins are now accessible via `Peripherals` and are no longer part of the `Io` struct (#2508)
- `dma::{ChannelRx, ChannelTx}` now have a `Mode` type parameter (#2519)

### Fixed

Expand Down
72 changes: 70 additions & 2 deletions esp-hal/MIGRATING-0.21.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ For example:
}
```

## Circular DMA transfer's `available` returns `Result<usize, DmaError>` now
## DMA related changes

### Circular DMA transfer's `available` returns `Result<usize, DmaError>` now

In case of any error you should drop the transfer and restart it.

Expand All @@ -293,6 +295,28 @@ In case of any error you should drop the transfer and restart it.
+ };
```

### Channel, ChannelRx and ChannelTx types have changed

- `Channel`'s `Async`/`Blocking` mode has been moved before the channel instance parameter.
- `ChannelRx` and `ChannelTx` have gained a new `Async`/`Blocking` mode parameter.

```diff
-Channel<'d, DmaChannel0, Async>
+Channel<'d, Async, DmaChannel0>

-ChannelRx<'d, DmaChannel0>
+ChannelRx<'d, Async, DmaChannel0>

-ChannelTx<'d, DmaChannel0>
+ChannelTx<'d, Async, DmaChannel0>
```

## 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

## Removed `peripheral_input` and `into_peripheral_output` from GPIO pin types

Creating peripheral interconnect signals now consume the GPIO pin used for the connection.
Expand Down Expand Up @@ -357,7 +381,9 @@ refer to the `Config` struct as `uart::Config`.
+)
```

## I8080 driver split `set_byte_order()` into `set_8bits_order()` and `set_byte_order()`.
## I8080 changes

### I8080 driver split `set_byte_order()` into `set_8bits_order()` and `set_byte_order()`.

If you were using an 8-bit bus.

Expand All @@ -371,6 +397,48 @@ If you were using an 16-bit bus, you don't need to change anything, `set_byte_or
If you were sharing the bus between an 8-bit and 16-bit device, you will have to call the corresponding method when
you switch between devices. Be sure to read the documentation of the new methods.

### Mixed mode constructor

It is no longer possible to construct an `I8080` driver using a blocking-mode `Lcd` and an async-mode
DMA channel. Convert the DMA channel into blocking, or set up an async `LcdCam` first.

```diff
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
let channel = ctx
.dma
.channel0
- .configure(false, DmaPriority::Priority0)
- .into_async();
+ .configure(false, DmaPriority::Priority0);

let i8080 = I8080::new(
lcd_cam.lcd,
channel.tx,
pins,
20.MHz(),
Config::default(),
);
```

Or:

```diff
-let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
+let lcd_cam = LcdCam::new(peripherals.LCD_CAM).into_async();
let channel = ctx
.dma
.channel0
.into_async();

let i8080 = I8080::new(
lcd_cam.lcd,
channel.tx,
pins,
20.MHz(),
Config::default(),
);
```

## `rmt::Channel::transmit` now returns `Result`, `PulseCode` is now `u32`

When trying to send a one-shot transmission will fail if it doesn't end with an end-marker.
Expand Down
21 changes: 13 additions & 8 deletions esp-hal/src/aes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,18 @@ pub mod dma {
ChannelTx,
DescriptorChain,
DmaChannelConvert,
DmaChannelFor,
DmaDescriptor,
DmaEligible,
DmaPeripheral,
DmaTransferRxTx,
ReadBuffer,
Rx,
RxChannelFor,
Tx,
TxChannelFor,
WriteBuffer,
},
peripheral::Peripheral,
peripherals::AES,
Blocking,
};
Expand Down Expand Up @@ -276,25 +279,27 @@ pub mod dma {
/// The underlying [`Aes`](super::Aes) driver
pub aes: super::Aes<'d>,

channel: Channel<'d, <AES as DmaEligible>::Dma, Blocking>,
channel: Channel<'d, Blocking, DmaChannelFor<AES>>,
rx_chain: DescriptorChain,
tx_chain: DescriptorChain,
}

impl<'d> crate::aes::Aes<'d> {
/// Enable DMA for the current instance of the AES driver
pub fn with_dma<C>(
pub fn with_dma<CH>(
self,
channel: Channel<'d, C, Blocking>,
channel: impl Peripheral<P = CH> + 'd,
rx_descriptors: &'static mut [DmaDescriptor],
tx_descriptors: &'static mut [DmaDescriptor],
) -> AesDma<'d>
where
C: DmaChannelConvert<<AES as DmaEligible>::Dma>,
CH: DmaChannelConvert<DmaChannelFor<AES>>,
{
let channel = Channel::new(channel.map(|ch| ch.degrade()));
channel.runtime_ensure_compatible(&self.aes);
AesDma {
aes: self,
channel: channel.degrade(),
channel,
rx_chain: DescriptorChain::new(rx_descriptors),
tx_chain: DescriptorChain::new(tx_descriptors),
}
Expand Down Expand Up @@ -324,7 +329,7 @@ pub mod dma {
}

impl<'d> DmaSupportTx for AesDma<'d> {
type TX = ChannelTx<'d, <AES as DmaEligible>::Dma>;
type TX = ChannelTx<'d, Blocking, TxChannelFor<AES>>;

fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
Expand All @@ -336,7 +341,7 @@ pub mod dma {
}

impl<'d> DmaSupportRx for AesDma<'d> {
type RX = ChannelRx<'d, <AES as DmaEligible>::Dma>;
type RX = ChannelRx<'d, Blocking, RxChannelFor<AES>>;

fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
Expand Down
24 changes: 12 additions & 12 deletions esp-hal/src/dma/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ 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).
pub is_burstable: bool,
// TODO: currently unused, buffers should not hardcode their preference.
pub burst: bool,

/// Configures the "check owner" feature of the DMA channel.
///
Expand Down Expand Up @@ -330,7 +330,7 @@ unsafe impl DmaTxBuffer for DmaTxBuf {
start: self.descriptors.head(),
block_size: self.block_size,
// This is TX, the DMA channel is free to do a burst transfer.
is_burstable: true,
burst: true,
check_owner: None,
}
}
Expand Down Expand Up @@ -481,7 +481,7 @@ unsafe impl DmaRxBuffer for DmaRxBuf {
// DmaRxBuf doesn't currently enforce the alignment requirements required for bursting.
// In the future, it could either enforce the alignment or calculate if the alignment
// requirements happen to be met.
is_burstable: false,
burst: false,
check_owner: None,
}
}
Expand Down Expand Up @@ -609,7 +609,7 @@ unsafe impl DmaTxBuffer for DmaRxTxBuf {
block_size: None, // TODO: support block size!

// This is TX, the DMA channel is free to do a burst transfer.
is_burstable: true,
burst: true,
check_owner: None,
}
}
Expand Down Expand Up @@ -641,7 +641,7 @@ unsafe impl DmaRxBuffer for DmaRxTxBuf {

// DmaRxTxBuf doesn't currently enforce the alignment requirements required for
// bursting.
is_burstable: false,
burst: false,
check_owner: None,
}
}
Expand Down Expand Up @@ -782,7 +782,7 @@ unsafe impl DmaRxBuffer for DmaRxStreamBuf {

// DmaRxStreamBuf doesn't currently enforce the alignment requirements required for
// bursting.
is_burstable: false,
burst: false,

// Whilst we give ownership of the descriptors the DMA, the correctness of this buffer
// implementation doesn't rely on the DMA checking for descriptor ownership.
Expand Down Expand Up @@ -995,7 +995,7 @@ unsafe impl DmaTxBuffer for EmptyBuf {
block_size: None,

// This is TX, the DMA channel is free to do a burst transfer.
is_burstable: true,
burst: true,

// As we don't give ownership of the descriptor to the DMA, it's important that the DMA
// channel does *NOT* check for ownership, otherwise the channel will return an error.
Expand Down Expand Up @@ -1026,7 +1026,7 @@ unsafe impl DmaRxBuffer for EmptyBuf {
block_size: None,

// As much as bursting is meaningless here, the descriptor does meet the requirements.
is_burstable: true,
burst: true,

// As we don't give ownership of the descriptor to the DMA, it's important that the DMA
// channel does *NOT* check for ownership, otherwise the channel will return an error.
Expand Down
Loading
Loading