mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-02 14:44:42 +00:00
[DMA 6/8] More helper types & working split
(#2532)
* Add helper traits to simplify DMA channel trait bounds * Document changes * Update doc example * Remove clutter from MG * Move DmaEligible down to place helper types closer * Rename * Include split in the MG
This commit is contained in:
parent
c1f0c134c3
commit
e98674e8fa
@ -12,7 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- ESP32-S3: Added SDMMC signals (#2556)
|
- ESP32-S3: Added SDMMC signals (#2556)
|
||||||
- Added `set_priority` to the `DmaChannel` trait on GDMA devices (#2403, #2526)
|
- Added `set_priority` to the `DmaChannel` trait on GDMA devices (#2403, #2526)
|
||||||
- Added `into_async` and `into_blocking` functions for `ParlIoTxOnly`, `ParlIoRxOnly` (#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
|
### Changed
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
# Migration Guide from 0.22.x to v1.0.0-beta.0
|
# 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
|
- `configure_for_async` and `configure` have been removed
|
||||||
- PDMA devices (ESP32, ESP32-S2) provide no configurability
|
- PDMA devices (ESP32, ESP32-S2) provide no configurability
|
||||||
@ -27,6 +29,76 @@
|
|||||||
+.with_dma(dma_channel);
|
+.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<P = T> + 'd,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: SomePeripheralInstance,
|
||||||
|
ChannelCreator<2>: DmaChannelConvert<<T as DmaEligible>::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<P = CH> + 'd,
|
||||||
|
peripheral: impl Peripheral<P = T> + 'd,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: SomePeripheralInstance,
|
||||||
|
CH: DmaChannelFor<T>,
|
||||||
|
{
|
||||||
|
// 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, <AES as DmaEligible>::Dma>,
|
||||||
|
+ channel: ChannelTx<'d, Blocking, PeripheralTxChannel<AES>>,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Timer changes
|
## 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).
|
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).
|
||||||
|
@ -241,16 +241,16 @@ pub mod dma {
|
|||||||
ChannelRx,
|
ChannelRx,
|
||||||
ChannelTx,
|
ChannelTx,
|
||||||
DescriptorChain,
|
DescriptorChain,
|
||||||
DmaChannelConvert,
|
|
||||||
DmaChannelFor,
|
DmaChannelFor,
|
||||||
DmaDescriptor,
|
DmaDescriptor,
|
||||||
DmaPeripheral,
|
DmaPeripheral,
|
||||||
DmaTransferRxTx,
|
DmaTransferRxTx,
|
||||||
|
PeripheralDmaChannel,
|
||||||
|
PeripheralRxChannel,
|
||||||
|
PeripheralTxChannel,
|
||||||
ReadBuffer,
|
ReadBuffer,
|
||||||
Rx,
|
Rx,
|
||||||
RxChannelFor,
|
|
||||||
Tx,
|
Tx,
|
||||||
TxChannelFor,
|
|
||||||
WriteBuffer,
|
WriteBuffer,
|
||||||
},
|
},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
@ -281,7 +281,7 @@ pub mod dma {
|
|||||||
/// The underlying [`Aes`](super::Aes) driver
|
/// The underlying [`Aes`](super::Aes) driver
|
||||||
pub aes: super::Aes<'d>,
|
pub aes: super::Aes<'d>,
|
||||||
|
|
||||||
channel: Channel<'d, Blocking, DmaChannelFor<AES>>,
|
channel: Channel<'d, Blocking, PeripheralDmaChannel<AES>>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
}
|
}
|
||||||
@ -295,7 +295,7 @@ pub mod dma {
|
|||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> AesDma<'d>
|
) -> AesDma<'d>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<AES>>,
|
CH: DmaChannelFor<AES>,
|
||||||
{
|
{
|
||||||
let channel = Channel::new(channel.map(|ch| ch.degrade()));
|
let channel = Channel::new(channel.map(|ch| ch.degrade()));
|
||||||
channel.runtime_ensure_compatible(&self.aes);
|
channel.runtime_ensure_compatible(&self.aes);
|
||||||
@ -331,7 +331,7 @@ pub mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> DmaSupportTx for AesDma<'d> {
|
impl<'d> DmaSupportTx for AesDma<'d> {
|
||||||
type TX = ChannelTx<'d, Blocking, TxChannelFor<AES>>;
|
type TX = ChannelTx<'d, Blocking, PeripheralTxChannel<AES>>;
|
||||||
|
|
||||||
fn tx(&mut self) -> &mut Self::TX {
|
fn tx(&mut self) -> &mut Self::TX {
|
||||||
&mut self.channel.tx
|
&mut self.channel.tx
|
||||||
@ -343,7 +343,7 @@ pub mod dma {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> DmaSupportRx for AesDma<'d> {
|
impl<'d> DmaSupportRx for AesDma<'d> {
|
||||||
type RX = ChannelRx<'d, Blocking, RxChannelFor<AES>>;
|
type RX = ChannelRx<'d, Blocking, PeripheralRxChannel<AES>>;
|
||||||
|
|
||||||
fn rx(&mut self) -> &mut Self::RX {
|
fn rx(&mut self) -> &mut Self::RX {
|
||||||
&mut self.channel.rx
|
&mut self.channel.rx
|
||||||
|
@ -60,6 +60,12 @@ impl Peripheral for AnyGdmaRxChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DmaChannelConvert<AnyGdmaRxChannel> for AnyGdmaRxChannel {
|
||||||
|
fn degrade(self) -> AnyGdmaRxChannel {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An arbitrary GDMA TX channel
|
/// An arbitrary GDMA TX channel
|
||||||
pub struct AnyGdmaTxChannel(u8);
|
pub struct AnyGdmaTxChannel(u8);
|
||||||
|
|
||||||
@ -71,6 +77,12 @@ impl Peripheral for AnyGdmaTxChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DmaChannelConvert<AnyGdmaTxChannel> for AnyGdmaTxChannel {
|
||||||
|
fn degrade(self) -> AnyGdmaTxChannel {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
|
|
||||||
static TX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
|
static TX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
|
||||||
|
@ -944,38 +944,6 @@ pub trait DmaEligible {
|
|||||||
fn dma_peripheral(&self) -> DmaPeripheral;
|
fn dma_peripheral(&self) -> DmaPeripheral;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper type to get the DMA (Rx and Tx) channel for a peripheral.
|
|
||||||
pub type DmaChannelFor<T> = <T as DmaEligible>::Dma;
|
|
||||||
/// Helper type to get the DMA Rx channel for a peripheral.
|
|
||||||
pub type RxChannelFor<T> = <DmaChannelFor<T> as DmaChannel>::Rx;
|
|
||||||
/// Helper type to get the DMA Tx channel for a peripheral.
|
|
||||||
pub type TxChannelFor<T> = <DmaChannelFor<T> 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)]
|
#[doc(hidden)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DescriptorChain {
|
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<T> = <T as DmaEligible>::Dma;
|
||||||
|
/// Helper type to get the DMA Rx channel for a peripheral.
|
||||||
|
pub type PeripheralRxChannel<T> = <PeripheralDmaChannel<T> as DmaChannel>::Rx;
|
||||||
|
/// Helper type to get the DMA Tx channel for a peripheral.
|
||||||
|
pub type PeripheralTxChannel<T> = <PeripheralDmaChannel<T> as DmaChannel>::Tx;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait DmaRxChannel:
|
pub trait DmaRxChannel:
|
||||||
RxRegisterAccess + InterruptAccess<DmaRxInterrupt> + Peripheral<P = Self>
|
RxRegisterAccess + InterruptAccess<DmaRxInterrupt> + Peripheral<P = Self>
|
||||||
@ -1647,7 +1647,7 @@ pub trait DmaChannelExt: DmaChannel {
|
|||||||
note = "Not all channels are useable with all peripherals"
|
note = "Not all channels are useable with all peripherals"
|
||||||
)]
|
)]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait DmaChannelConvert<DEG>: DmaChannel {
|
pub trait DmaChannelConvert<DEG> {
|
||||||
fn degrade(self) -> DEG;
|
fn degrade(self) -> DEG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1657,6 +1657,94 @@ impl<DEG: DmaChannel> DmaChannelConvert<DEG> 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<P = CH> + 'd,
|
||||||
|
/// ) -> SpiDma<'d, Blocking, S>
|
||||||
|
/// where
|
||||||
|
/// S: SpiInstance,
|
||||||
|
/// CH: DmaChannelFor<S> + '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<P: DmaEligible>:
|
||||||
|
DmaChannel + DmaChannelConvert<PeripheralDmaChannel<P>>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<P, CH> DmaChannelFor<P> for CH
|
||||||
|
where
|
||||||
|
P: DmaEligible,
|
||||||
|
CH: DmaChannel + DmaChannelConvert<PeripheralDmaChannel<P>>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<P: DmaEligible>: DmaChannelConvert<PeripheralRxChannel<P>> {}
|
||||||
|
impl<P, RX> RxChannelFor<P> for RX
|
||||||
|
where
|
||||||
|
P: DmaEligible,
|
||||||
|
RX: DmaChannelConvert<PeripheralRxChannel<P>>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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<PER: DmaEligible>: DmaChannelConvert<PeripheralTxChannel<PER>> {}
|
||||||
|
impl<P, TX> TxChannelFor<P> for TX
|
||||||
|
where
|
||||||
|
P: DmaEligible,
|
||||||
|
TX: DmaChannelConvert<PeripheralTxChannel<P>>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// The functions here are not meant to be used outside the HAL
|
/// The functions here are not meant to be used outside the HAL
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub trait Rx: crate::private::Sealed {
|
pub trait Rx: crate::private::Sealed {
|
||||||
|
@ -81,7 +81,6 @@ use crate::{
|
|||||||
ChannelRx,
|
ChannelRx,
|
||||||
ChannelTx,
|
ChannelTx,
|
||||||
DescriptorChain,
|
DescriptorChain,
|
||||||
DmaChannelConvert,
|
|
||||||
DmaChannelFor,
|
DmaChannelFor,
|
||||||
DmaDescriptor,
|
DmaDescriptor,
|
||||||
DmaEligible,
|
DmaEligible,
|
||||||
@ -90,11 +89,12 @@ use crate::{
|
|||||||
DmaTransferRxCircular,
|
DmaTransferRxCircular,
|
||||||
DmaTransferTx,
|
DmaTransferTx,
|
||||||
DmaTransferTxCircular,
|
DmaTransferTxCircular,
|
||||||
|
PeripheralDmaChannel,
|
||||||
|
PeripheralRxChannel,
|
||||||
|
PeripheralTxChannel,
|
||||||
ReadBuffer,
|
ReadBuffer,
|
||||||
Rx,
|
Rx,
|
||||||
RxChannelFor,
|
|
||||||
Tx,
|
Tx,
|
||||||
TxChannelFor,
|
|
||||||
WriteBuffer,
|
WriteBuffer,
|
||||||
},
|
},
|
||||||
gpio::interconnect::PeripheralOutput,
|
gpio::interconnect::PeripheralOutput,
|
||||||
@ -271,7 +271,7 @@ where
|
|||||||
standard: Standard,
|
standard: Standard,
|
||||||
data_format: DataFormat,
|
data_format: DataFormat,
|
||||||
sample_rate: impl Into<fugit::HertzU32>,
|
sample_rate: impl Into<fugit::HertzU32>,
|
||||||
channel: PeripheralRef<'d, DmaChannelFor<T>>,
|
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
|
||||||
rx_descriptors: &'static mut [DmaDescriptor],
|
rx_descriptors: &'static mut [DmaDescriptor],
|
||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -377,7 +377,7 @@ impl<'d> I2s<'d, Blocking> {
|
|||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<AnyI2s>>,
|
CH: DmaChannelFor<AnyI2s>,
|
||||||
{
|
{
|
||||||
Self::new_typed(
|
Self::new_typed(
|
||||||
i2s.map_into(),
|
i2s.map_into(),
|
||||||
@ -408,7 +408,7 @@ where
|
|||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<T>>,
|
CH: DmaChannelFor<T>,
|
||||||
{
|
{
|
||||||
crate::into_ref!(i2s);
|
crate::into_ref!(i2s);
|
||||||
Self::new_internal(
|
Self::new_internal(
|
||||||
@ -463,7 +463,7 @@ where
|
|||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
i2s: PeripheralRef<'d, T>,
|
i2s: PeripheralRef<'d, T>,
|
||||||
tx_channel: ChannelTx<'d, DmaMode, TxChannelFor<T>>,
|
tx_channel: ChannelTx<'d, DmaMode, PeripheralTxChannel<T>>,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
_guard: PeripheralGuard,
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
@ -497,7 +497,7 @@ where
|
|||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
type TX = ChannelTx<'d, DmaMode, TxChannelFor<T>>;
|
type TX = ChannelTx<'d, DmaMode, PeripheralTxChannel<T>>;
|
||||||
|
|
||||||
fn tx(&mut self) -> &mut Self::TX {
|
fn tx(&mut self) -> &mut Self::TX {
|
||||||
&mut self.tx_channel
|
&mut self.tx_channel
|
||||||
@ -596,7 +596,7 @@ where
|
|||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
i2s: PeripheralRef<'d, T>,
|
i2s: PeripheralRef<'d, T>,
|
||||||
rx_channel: ChannelRx<'d, DmaMode, RxChannelFor<T>>,
|
rx_channel: ChannelRx<'d, DmaMode, PeripheralRxChannel<T>>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
_guard: PeripheralGuard,
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
@ -630,7 +630,7 @@ where
|
|||||||
T: RegisterAccess,
|
T: RegisterAccess,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
type RX = ChannelRx<'d, DmaMode, RxChannelFor<T>>;
|
type RX = ChannelRx<'d, DmaMode, PeripheralRxChannel<T>>;
|
||||||
|
|
||||||
fn rx(&mut self) -> &mut Self::RX {
|
fn rx(&mut self) -> &mut Self::RX {
|
||||||
&mut self.rx_channel
|
&mut self.rx_channel
|
||||||
@ -766,7 +766,7 @@ mod private {
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
pub i2s: PeripheralRef<'d, T>,
|
pub i2s: PeripheralRef<'d, T>,
|
||||||
pub tx_channel: ChannelTx<'d, M, TxChannelFor<T>>,
|
pub tx_channel: ChannelTx<'d, M, PeripheralTxChannel<T>>,
|
||||||
pub descriptors: &'static mut [DmaDescriptor],
|
pub descriptors: &'static mut [DmaDescriptor],
|
||||||
pub(crate) guard: PeripheralGuard,
|
pub(crate) guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
@ -826,7 +826,7 @@ mod private {
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
pub i2s: PeripheralRef<'d, T>,
|
pub i2s: PeripheralRef<'d, T>,
|
||||||
pub rx_channel: ChannelRx<'d, M, RxChannelFor<T>>,
|
pub rx_channel: ChannelRx<'d, M, PeripheralRxChannel<T>>,
|
||||||
pub descriptors: &'static mut [DmaDescriptor],
|
pub descriptors: &'static mut [DmaDescriptor],
|
||||||
pub(crate) guard: PeripheralGuard,
|
pub(crate) guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
@ -46,14 +46,13 @@ use crate::{
|
|||||||
asynch::DmaTxFuture,
|
asynch::DmaTxFuture,
|
||||||
Channel,
|
Channel,
|
||||||
ChannelTx,
|
ChannelTx,
|
||||||
DmaChannelConvert,
|
|
||||||
DmaChannelFor,
|
DmaChannelFor,
|
||||||
DmaEligible,
|
DmaEligible,
|
||||||
DmaError,
|
DmaError,
|
||||||
DmaPeripheral,
|
DmaPeripheral,
|
||||||
DmaTxBuffer,
|
DmaTxBuffer,
|
||||||
|
PeripheralTxChannel,
|
||||||
Tx,
|
Tx,
|
||||||
TxChannelFor,
|
|
||||||
},
|
},
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{OutputConnection, PeripheralOutput},
|
interconnect::{OutputConnection, PeripheralOutput},
|
||||||
@ -179,7 +178,7 @@ where
|
|||||||
I: Instance,
|
I: Instance,
|
||||||
{
|
{
|
||||||
instance: PeripheralRef<'d, I>,
|
instance: PeripheralRef<'d, I>,
|
||||||
tx_channel: ChannelTx<'d, DM, TxChannelFor<I>>,
|
tx_channel: ChannelTx<'d, DM, PeripheralTxChannel<I>>,
|
||||||
_guard: PeripheralGuard,
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ impl<'d> I2sParallel<'d, Blocking> {
|
|||||||
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<AnyI2s>>,
|
CH: DmaChannelFor<AnyI2s>,
|
||||||
{
|
{
|
||||||
Self::new_typed(i2s.map_into(), channel, frequency, pins, clock_pin)
|
Self::new_typed(i2s.map_into(), channel, frequency, pins, clock_pin)
|
||||||
}
|
}
|
||||||
@ -212,7 +211,7 @@ where
|
|||||||
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<I>>,
|
CH: DmaChannelFor<I>,
|
||||||
{
|
{
|
||||||
crate::into_ref!(i2s);
|
crate::into_ref!(i2s);
|
||||||
crate::into_mapped_ref!(clock_pin);
|
crate::into_mapped_ref!(clock_pin);
|
||||||
|
@ -67,7 +67,7 @@ use fugit::HertzU32;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
dma::{ChannelRx, DmaChannelConvert, DmaError, DmaPeripheral, DmaRxBuffer, Rx, RxChannelFor},
|
dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, Rx, RxChannelFor},
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{PeripheralInput, PeripheralOutput},
|
interconnect::{PeripheralInput, PeripheralOutput},
|
||||||
InputSignal,
|
InputSignal,
|
||||||
@ -123,7 +123,7 @@ pub struct Cam<'d> {
|
|||||||
/// Represents the camera interface with DMA support.
|
/// Represents the camera interface with DMA support.
|
||||||
pub struct Camera<'d> {
|
pub struct Camera<'d> {
|
||||||
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
||||||
rx_channel: ChannelRx<'d, Blocking, RxChannelFor<LCD_CAM>>,
|
rx_channel: ChannelRx<'d, Blocking, PeripheralRxChannel<LCD_CAM>>,
|
||||||
_guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
|
_guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ impl<'d> Camera<'d> {
|
|||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<RxChannelFor<LCD_CAM>>,
|
CH: RxChannelFor<LCD_CAM>,
|
||||||
P: RxPins,
|
P: RxPins,
|
||||||
{
|
{
|
||||||
let rx_channel = ChannelRx::new(channel.map(|ch| ch.degrade()));
|
let rx_channel = ChannelRx::new(channel.map(|ch| ch.degrade()));
|
||||||
|
@ -106,7 +106,7 @@ use fugit::HertzU32;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
dma::{ChannelTx, DmaChannelConvert, DmaError, DmaPeripheral, DmaTxBuffer, Tx, TxChannelFor},
|
dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, Tx, TxChannelFor},
|
||||||
gpio::{interconnect::PeripheralOutput, Level, OutputSignal},
|
gpio::{interconnect::PeripheralOutput, Level, OutputSignal},
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
calculate_clkm,
|
calculate_clkm,
|
||||||
@ -123,7 +123,7 @@ use crate::{
|
|||||||
/// Represents the RGB LCD interface.
|
/// Represents the RGB LCD interface.
|
||||||
pub struct Dpi<'d, DM: Mode> {
|
pub struct Dpi<'d, DM: Mode> {
|
||||||
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
||||||
tx_channel: ChannelTx<'d, Blocking, TxChannelFor<LCD_CAM>>,
|
tx_channel: ChannelTx<'d, Blocking, PeripheralTxChannel<LCD_CAM>>,
|
||||||
_mode: PhantomData<DM>,
|
_mode: PhantomData<DM>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ where
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<TxChannelFor<LCD_CAM>>,
|
CH: TxChannelFor<LCD_CAM>,
|
||||||
{
|
{
|
||||||
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
|
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
|
||||||
let lcd_cam = lcd.lcd_cam;
|
let lcd_cam = lcd.lcd_cam;
|
||||||
|
@ -62,7 +62,7 @@ use fugit::HertzU32;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
dma::{ChannelTx, DmaChannelConvert, DmaError, DmaPeripheral, DmaTxBuffer, Tx, TxChannelFor},
|
dma::{ChannelTx, DmaError, DmaPeripheral, DmaTxBuffer, PeripheralTxChannel, Tx, TxChannelFor},
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{OutputConnection, PeripheralOutput},
|
interconnect::{OutputConnection, PeripheralOutput},
|
||||||
OutputSignal,
|
OutputSignal,
|
||||||
@ -85,7 +85,7 @@ use crate::{
|
|||||||
/// Represents the I8080 LCD interface.
|
/// Represents the I8080 LCD interface.
|
||||||
pub struct I8080<'d, DM: Mode> {
|
pub struct I8080<'d, DM: Mode> {
|
||||||
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
lcd_cam: PeripheralRef<'d, LCD_CAM>,
|
||||||
tx_channel: ChannelTx<'d, Blocking, TxChannelFor<LCD_CAM>>,
|
tx_channel: ChannelTx<'d, Blocking, PeripheralTxChannel<LCD_CAM>>,
|
||||||
_mode: PhantomData<DM>,
|
_mode: PhantomData<DM>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ where
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<TxChannelFor<LCD_CAM>>,
|
CH: TxChannelFor<LCD_CAM>,
|
||||||
P: TxPins,
|
P: TxPins,
|
||||||
{
|
{
|
||||||
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
|
let tx_channel = ChannelTx::new(channel.map(|ch| ch.degrade()));
|
||||||
|
@ -35,13 +35,14 @@ use crate::{
|
|||||||
ChannelRx,
|
ChannelRx,
|
||||||
ChannelTx,
|
ChannelTx,
|
||||||
DescriptorChain,
|
DescriptorChain,
|
||||||
DmaChannelConvert,
|
|
||||||
DmaChannelFor,
|
DmaChannelFor,
|
||||||
DmaDescriptor,
|
DmaDescriptor,
|
||||||
DmaError,
|
DmaError,
|
||||||
DmaPeripheral,
|
DmaPeripheral,
|
||||||
DmaTransferRx,
|
DmaTransferRx,
|
||||||
DmaTransferTx,
|
DmaTransferTx,
|
||||||
|
PeripheralRxChannel,
|
||||||
|
PeripheralTxChannel,
|
||||||
ReadBuffer,
|
ReadBuffer,
|
||||||
Rx,
|
Rx,
|
||||||
RxChannelFor,
|
RxChannelFor,
|
||||||
@ -811,7 +812,7 @@ pub struct ParlIoTx<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, TxChannelFor<PARL_IO>>,
|
tx_channel: ChannelTx<'d, DM, PeripheralTxChannel<PARL_IO>>,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
@ -892,7 +893,7 @@ pub struct ParlIoRx<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, RxChannelFor<PARL_IO>>,
|
rx_channel: ChannelRx<'d, DM, PeripheralRxChannel<PARL_IO>>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ crate::system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
@ -1013,7 +1014,7 @@ impl<'d> ParlIoFullDuplex<'d, Blocking> {
|
|||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<PARL_IO>>,
|
CH: DmaChannelFor<PARL_IO>,
|
||||||
{
|
{
|
||||||
let tx_guard = GenericPeripheralGuard::new();
|
let tx_guard = GenericPeripheralGuard::new();
|
||||||
let rx_guard = GenericPeripheralGuard::new();
|
let rx_guard = GenericPeripheralGuard::new();
|
||||||
@ -1135,7 +1136,7 @@ impl<'d> ParlIoTxOnly<'d, Blocking> {
|
|||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<TxChannelFor<PARL_IO>>,
|
CH: TxChannelFor<PARL_IO>,
|
||||||
{
|
{
|
||||||
let guard = GenericPeripheralGuard::new();
|
let guard = GenericPeripheralGuard::new();
|
||||||
let tx_channel = ChannelTx::new(dma_channel.map(|ch| ch.degrade()));
|
let tx_channel = ChannelTx::new(dma_channel.map(|ch| ch.degrade()));
|
||||||
@ -1241,7 +1242,7 @@ impl<'d> ParlIoRxOnly<'d, Blocking> {
|
|||||||
frequency: HertzU32,
|
frequency: HertzU32,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<RxChannelFor<PARL_IO>>,
|
CH: RxChannelFor<PARL_IO>,
|
||||||
{
|
{
|
||||||
let guard = GenericPeripheralGuard::new();
|
let guard = GenericPeripheralGuard::new();
|
||||||
let rx_channel = ChannelRx::new(dma_channel.map(|ch| ch.degrade()));
|
let rx_channel = ChannelRx::new(dma_channel.map(|ch| ch.degrade()));
|
||||||
@ -1433,7 +1434,7 @@ impl<'d, DM> DmaSupportTx for ParlIoTx<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
type TX = ChannelTx<'d, DM, TxChannelFor<PARL_IO>>;
|
type TX = ChannelTx<'d, DM, PeripheralTxChannel<PARL_IO>>;
|
||||||
|
|
||||||
fn tx(&mut self) -> &mut Self::TX {
|
fn tx(&mut self) -> &mut Self::TX {
|
||||||
&mut self.tx_channel
|
&mut self.tx_channel
|
||||||
@ -1475,7 +1476,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn start_receive_bytes_dma(
|
fn start_receive_bytes_dma(
|
||||||
rx_channel: &mut ChannelRx<'d, DM, RxChannelFor<PARL_IO>>,
|
rx_channel: &mut ChannelRx<'d, DM, PeripheralRxChannel<PARL_IO>>,
|
||||||
rx_chain: &mut DescriptorChain,
|
rx_chain: &mut DescriptorChain,
|
||||||
ptr: *mut u8,
|
ptr: *mut u8,
|
||||||
len: usize,
|
len: usize,
|
||||||
@ -1529,7 +1530,7 @@ impl<'d, DM> DmaSupportRx for ParlIoRx<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
type RX = ChannelRx<'d, DM, RxChannelFor<PARL_IO>>;
|
type RX = ChannelRx<'d, DM, PeripheralRxChannel<PARL_IO>>;
|
||||||
|
|
||||||
fn rx(&mut self) -> &mut Self::RX {
|
fn rx(&mut self) -> &mut Self::RX {
|
||||||
&mut self.rx_channel
|
&mut self.rx_channel
|
||||||
@ -1545,7 +1546,7 @@ pub struct TxCreator<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, TxChannelFor<PARL_IO>>,
|
tx_channel: ChannelTx<'d, DM, PeripheralTxChannel<PARL_IO>>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
@ -1555,7 +1556,7 @@ pub struct RxCreator<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, RxChannelFor<PARL_IO>>,
|
rx_channel: ChannelRx<'d, DM, PeripheralRxChannel<PARL_IO>>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
@ -1565,7 +1566,7 @@ pub struct TxCreatorFullDuplex<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
tx_channel: ChannelTx<'d, DM, TxChannelFor<PARL_IO>>,
|
tx_channel: ChannelTx<'d, DM, PeripheralTxChannel<PARL_IO>>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
@ -1575,7 +1576,7 @@ pub struct RxCreatorFullDuplex<'d, DM>
|
|||||||
where
|
where
|
||||||
DM: Mode,
|
DM: Mode,
|
||||||
{
|
{
|
||||||
rx_channel: ChannelRx<'d, DM, RxChannelFor<PARL_IO>>,
|
rx_channel: ChannelRx<'d, DM, PeripheralRxChannel<PARL_IO>>,
|
||||||
descriptors: &'static mut [DmaDescriptor],
|
descriptors: &'static mut [DmaDescriptor],
|
||||||
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
_guard: GenericPeripheralGuard<{ system::Peripheral::ParlIo as u8 }>,
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ use procmacros::ram;
|
|||||||
use super::{DmaError, Error, SpiBitOrder, SpiDataMode, SpiMode};
|
use super::{DmaError, Error, SpiBitOrder, SpiDataMode, SpiMode};
|
||||||
use crate::{
|
use crate::{
|
||||||
clock::Clocks,
|
clock::Clocks,
|
||||||
dma::{DmaChannelConvert, DmaChannelFor, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
|
dma::{DmaChannelFor, DmaEligible, DmaRxBuffer, DmaTxBuffer, Rx, Tx},
|
||||||
gpio::{interconnect::PeripheralOutput, InputSignal, NoPin, OutputSignal},
|
gpio::{interconnect::PeripheralOutput, InputSignal, NoPin, OutputSignal},
|
||||||
interrupt::InterruptHandler,
|
interrupt::InterruptHandler,
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
@ -540,7 +540,7 @@ where
|
|||||||
/// operations.
|
/// operations.
|
||||||
pub fn with_dma<CH>(self, channel: impl Peripheral<P = CH> + 'd) -> SpiDma<'d, Blocking, T>
|
pub fn with_dma<CH>(self, channel: impl Peripheral<P = CH> + 'd) -> SpiDma<'d, Blocking, T>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<T>>,
|
CH: DmaChannelFor<T>,
|
||||||
{
|
{
|
||||||
SpiDma::new(self.spi, channel.map(|ch| ch.degrade()).into_ref())
|
SpiDma::new(self.spi, channel.map(|ch| ch.degrade()).into_ref())
|
||||||
}
|
}
|
||||||
@ -856,12 +856,12 @@ mod dma {
|
|||||||
dma::{
|
dma::{
|
||||||
asynch::{DmaRxFuture, DmaTxFuture},
|
asynch::{DmaRxFuture, DmaTxFuture},
|
||||||
Channel,
|
Channel,
|
||||||
DmaChannelFor,
|
|
||||||
DmaRxBuf,
|
DmaRxBuf,
|
||||||
DmaRxBuffer,
|
DmaRxBuffer,
|
||||||
DmaTxBuf,
|
DmaTxBuf,
|
||||||
DmaTxBuffer,
|
DmaTxBuffer,
|
||||||
EmptyBuf,
|
EmptyBuf,
|
||||||
|
PeripheralDmaChannel,
|
||||||
Rx,
|
Rx,
|
||||||
Tx,
|
Tx,
|
||||||
},
|
},
|
||||||
@ -883,7 +883,7 @@ mod dma {
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
pub(crate) spi: PeripheralRef<'d, T>,
|
pub(crate) spi: PeripheralRef<'d, T>,
|
||||||
pub(crate) channel: Channel<'d, M, DmaChannelFor<T>>,
|
pub(crate) channel: Channel<'d, M, PeripheralDmaChannel<T>>,
|
||||||
tx_transfer_in_progress: bool,
|
tx_transfer_in_progress: bool,
|
||||||
rx_transfer_in_progress: bool,
|
rx_transfer_in_progress: bool,
|
||||||
#[cfg(all(esp32, spi_address_workaround))]
|
#[cfg(all(esp32, spi_address_workaround))]
|
||||||
@ -997,7 +997,7 @@ mod dma {
|
|||||||
{
|
{
|
||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
spi: PeripheralRef<'d, T>,
|
spi: PeripheralRef<'d, T>,
|
||||||
channel: PeripheralRef<'d, DmaChannelFor<T>>,
|
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let channel = Channel::new(channel);
|
let channel = Channel::new(channel);
|
||||||
channel.runtime_ensure_compatible(&spi);
|
channel.runtime_ensure_compatible(&spi);
|
||||||
|
@ -73,7 +73,7 @@ use core::marker::PhantomData;
|
|||||||
|
|
||||||
use super::{Error, SpiMode};
|
use super::{Error, SpiMode};
|
||||||
use crate::{
|
use crate::{
|
||||||
dma::{DmaChannelConvert, DmaEligible},
|
dma::DmaEligible,
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{PeripheralInput, PeripheralOutput},
|
interconnect::{PeripheralInput, PeripheralOutput},
|
||||||
InputSignal,
|
InputSignal,
|
||||||
@ -182,11 +182,12 @@ pub mod dma {
|
|||||||
DmaTransferRx,
|
DmaTransferRx,
|
||||||
DmaTransferRxTx,
|
DmaTransferRxTx,
|
||||||
DmaTransferTx,
|
DmaTransferTx,
|
||||||
|
PeripheralDmaChannel,
|
||||||
|
PeripheralRxChannel,
|
||||||
|
PeripheralTxChannel,
|
||||||
ReadBuffer,
|
ReadBuffer,
|
||||||
Rx,
|
Rx,
|
||||||
RxChannelFor,
|
|
||||||
Tx,
|
Tx,
|
||||||
TxChannelFor,
|
|
||||||
WriteBuffer,
|
WriteBuffer,
|
||||||
},
|
},
|
||||||
Mode,
|
Mode,
|
||||||
@ -206,7 +207,7 @@ pub mod dma {
|
|||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> SpiDma<'d, Blocking, T>
|
) -> SpiDma<'d, Blocking, T>
|
||||||
where
|
where
|
||||||
CH: DmaChannelConvert<DmaChannelFor<T>>,
|
CH: DmaChannelFor<T>,
|
||||||
{
|
{
|
||||||
self.spi.info().set_data_mode(self.data_mode, true);
|
self.spi.info().set_data_mode(self.data_mode, true);
|
||||||
SpiDma::new(
|
SpiDma::new(
|
||||||
@ -225,7 +226,7 @@ pub mod dma {
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
{
|
{
|
||||||
pub(crate) spi: PeripheralRef<'d, T>,
|
pub(crate) spi: PeripheralRef<'d, T>,
|
||||||
pub(crate) channel: Channel<'d, M, DmaChannelFor<T>>,
|
pub(crate) channel: Channel<'d, M, PeripheralDmaChannel<T>>,
|
||||||
rx_chain: DescriptorChain,
|
rx_chain: DescriptorChain,
|
||||||
tx_chain: DescriptorChain,
|
tx_chain: DescriptorChain,
|
||||||
_guard: PeripheralGuard,
|
_guard: PeripheralGuard,
|
||||||
@ -265,7 +266,7 @@ pub mod dma {
|
|||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
type TX = ChannelTx<'d, DmaMode, TxChannelFor<T>>;
|
type TX = ChannelTx<'d, DmaMode, PeripheralTxChannel<T>>;
|
||||||
|
|
||||||
fn tx(&mut self) -> &mut Self::TX {
|
fn tx(&mut self) -> &mut Self::TX {
|
||||||
&mut self.channel.tx
|
&mut self.channel.tx
|
||||||
@ -281,7 +282,7 @@ pub mod dma {
|
|||||||
T: InstanceDma,
|
T: InstanceDma,
|
||||||
DmaMode: Mode,
|
DmaMode: Mode,
|
||||||
{
|
{
|
||||||
type RX = ChannelRx<'d, DmaMode, RxChannelFor<T>>;
|
type RX = ChannelRx<'d, DmaMode, PeripheralRxChannel<T>>;
|
||||||
|
|
||||||
fn rx(&mut self) -> &mut Self::RX {
|
fn rx(&mut self) -> &mut Self::RX {
|
||||||
&mut self.channel.rx
|
&mut self.channel.rx
|
||||||
@ -298,7 +299,7 @@ pub mod dma {
|
|||||||
{
|
{
|
||||||
fn new(
|
fn new(
|
||||||
spi: PeripheralRef<'d, T>,
|
spi: PeripheralRef<'d, T>,
|
||||||
channel: PeripheralRef<'d, DmaChannelFor<T>>,
|
channel: PeripheralRef<'d, PeripheralDmaChannel<T>>,
|
||||||
rx_descriptors: &'static mut [DmaDescriptor],
|
rx_descriptors: &'static mut [DmaDescriptor],
|
||||||
tx_descriptors: &'static mut [DmaDescriptor],
|
tx_descriptors: &'static mut [DmaDescriptor],
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaChannel, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::Level,
|
gpio::Level,
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
@ -58,9 +58,7 @@ mod tests {
|
|||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
|
|
||||||
// TODO: use split channels once supported
|
let (rx_channel, tx_channel) = dma.channel2.split();
|
||||||
let tx_channel = dma.channel2;
|
|
||||||
let rx_channel = dma.channel3;
|
|
||||||
|
|
||||||
let (vsync_in, vsync_out) = peripherals.GPIO6.split();
|
let (vsync_in, vsync_out) = peripherals.GPIO6.split();
|
||||||
let (hsync_in, hsync_out) = peripherals.GPIO7.split();
|
let (hsync_in, hsync_out) = peripherals.GPIO7.split();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user