[DMA 3/8] Remove ChannelCreator types, temporarily disable burst mode (#2403)
* Remove ChannelCreator types and burst mode * Fix up I2sParallel * Always enable burst transfering descriptors * Configure burst transfer with a non-bool for future chip support * Reuse buffer preparation code * Update LoopBuf as well * Update lcd_cam tests * Rename config, fix changelog
This commit is contained in:
parent
f9203dc523
commit
973671c3cb
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
- ESP32-S3: Added SDMMC signals (#2556)
|
- ESP32-S3: Added SDMMC signals (#2556)
|
||||||
|
- `dma::{Channel, ChannelRx, ChannelTx}::set_priority` for GDMA devices (#2403)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -17,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
- The `configure` and `configure_for_async` DMA channel functions has been removed (#2403)
|
||||||
|
|
||||||
## [0.22.0] - 2024-11-20
|
## [0.22.0] - 2024-11-20
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -1 +1,17 @@
|
|||||||
# 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
|
||||||
|
|
||||||
|
- `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,25 +8,65 @@ use crate::soc::is_slice_in_dram;
|
|||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
use crate::soc::is_slice_in_psram;
|
use crate::soc::is_slice_in_psram;
|
||||||
|
|
||||||
|
/// Burst transfer configuration.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub enum BurstConfig {
|
||||||
|
/// Burst mode is disabled.
|
||||||
|
Disabled,
|
||||||
|
|
||||||
|
/// Burst mode is enabled.
|
||||||
|
Enabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BurstConfig {
|
||||||
|
pub(super) fn is_burst_enabled(self) -> bool {
|
||||||
|
!matches!(self, Self::Disabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The direction of the DMA transfer.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub enum TransferDirection {
|
||||||
|
/// DMA transfer from peripheral or external memory to memory.
|
||||||
|
In,
|
||||||
|
/// DMA transfer from memory to peripheral or external memory.
|
||||||
|
Out,
|
||||||
|
}
|
||||||
|
|
||||||
/// Holds all the information needed to configure a DMA channel for a transfer.
|
/// Holds all the information needed to configure a DMA channel for a transfer.
|
||||||
pub struct Preparation {
|
pub struct Preparation {
|
||||||
/// The descriptor the DMA will start from.
|
/// The descriptor the DMA will start from.
|
||||||
pub start: *mut DmaDescriptor,
|
pub start: *mut DmaDescriptor,
|
||||||
|
|
||||||
/// Block size for PSRAM transfers
|
/// The direction of the DMA transfer.
|
||||||
#[cfg_attr(not(esp32s3), allow(dead_code))]
|
pub direction: TransferDirection,
|
||||||
pub block_size: Option<DmaBufBlkSize>,
|
|
||||||
|
|
||||||
/// Specifies whether descriptor linked list specified in `start` conforms
|
/// Block size for PSRAM transfers.
|
||||||
/// to the alignment requirements required to enable burst transfers.
|
|
||||||
///
|
///
|
||||||
/// Note: This only applies to burst transfer of the buffer data, not the
|
/// If the buffer is in PSRAM, the implementation must ensure the following:
|
||||||
/// descriptors themselves.
|
|
||||||
///
|
///
|
||||||
/// There are no additional alignment requirements for TX burst transfers,
|
/// - The implementation of the buffer must provide a non-`None` block size.
|
||||||
/// but RX transfers require all descriptors to have buffer pointers and
|
/// - For [`TransferDirection::In`] transfers, the implementation of the
|
||||||
/// sizes that are a multiple of 4 (word aligned).
|
/// buffer must invalidate the cache that contains the buffer before the
|
||||||
pub is_burstable: bool,
|
/// DMA starts.
|
||||||
|
/// - For [`TransferDirection::Out`] transfers, the implementation of the
|
||||||
|
/// buffer must write back the cache that contains the buffer before the
|
||||||
|
/// DMA starts.
|
||||||
|
#[cfg(esp32s3)]
|
||||||
|
pub external_memory_block_size: Option<DmaBufBlkSize>,
|
||||||
|
|
||||||
|
/// Configures the DMA to transfer data in bursts.
|
||||||
|
///
|
||||||
|
/// 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
|
||||||
|
/// [`TransferDirection::Out`] burst transfers, but
|
||||||
|
/// [`TransferDirection::In`] transfers require all descriptors to have
|
||||||
|
/// buffer pointers and sizes that are a multiple of 4 (word aligned).
|
||||||
|
pub burst_transfer: BurstConfig,
|
||||||
|
|
||||||
/// Configures the "check owner" feature of the DMA channel.
|
/// Configures the "check owner" feature of the DMA channel.
|
||||||
///
|
///
|
||||||
@ -331,9 +371,11 @@ unsafe impl DmaTxBuffer for DmaTxBuf {
|
|||||||
|
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.descriptors.head(),
|
start: self.descriptors.head(),
|
||||||
block_size: self.block_size,
|
direction: TransferDirection::Out,
|
||||||
// This is TX, the DMA channel is free to do a burst transfer.
|
#[cfg(esp32s3)]
|
||||||
is_burstable: true,
|
external_memory_block_size: self.block_size,
|
||||||
|
// TODO: support burst transfers.
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
check_owner: None,
|
check_owner: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,11 +522,16 @@ unsafe impl DmaRxBuffer for DmaRxBuf {
|
|||||||
|
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.descriptors.head(),
|
start: self.descriptors.head(),
|
||||||
block_size: None,
|
direction: TransferDirection::In,
|
||||||
// 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
|
// TODO: support external memory access.
|
||||||
// requirements happen to be met.
|
#[cfg(esp32s3)]
|
||||||
is_burstable: false,
|
external_memory_block_size: None,
|
||||||
|
|
||||||
|
// TODO: 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.
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
check_owner: None,
|
check_owner: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,10 +656,14 @@ unsafe impl DmaTxBuffer for DmaRxTxBuf {
|
|||||||
|
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.tx_descriptors.head(),
|
start: self.tx_descriptors.head(),
|
||||||
block_size: None, // TODO: support block size!
|
direction: TransferDirection::Out,
|
||||||
|
|
||||||
// This is TX, the DMA channel is free to do a burst transfer.
|
// TODO: support external memory access.
|
||||||
is_burstable: true,
|
#[cfg(esp32s3)]
|
||||||
|
external_memory_block_size: None,
|
||||||
|
|
||||||
|
// TODO: This is TX, the DMA channel is free to do a burst transfer.
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
check_owner: None,
|
check_owner: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,11 +691,15 @@ unsafe impl DmaRxBuffer for DmaRxTxBuf {
|
|||||||
|
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.rx_descriptors.head(),
|
start: self.rx_descriptors.head(),
|
||||||
block_size: None, // TODO: support block size!
|
direction: TransferDirection::In,
|
||||||
|
|
||||||
// DmaRxTxBuf doesn't currently enforce the alignment requirements required for
|
// TODO: support external memory access.
|
||||||
|
#[cfg(esp32s3)]
|
||||||
|
external_memory_block_size: None,
|
||||||
|
|
||||||
|
// TODO: DmaRxTxBuf doesn't currently enforce the alignment requirements required for
|
||||||
// bursting.
|
// bursting.
|
||||||
is_burstable: false,
|
burst_transfer: BurstConfig::Disabled,
|
||||||
check_owner: None,
|
check_owner: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,11 +836,15 @@ unsafe impl DmaRxBuffer for DmaRxStreamBuf {
|
|||||||
}
|
}
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.descriptors.as_mut_ptr(),
|
start: self.descriptors.as_mut_ptr(),
|
||||||
block_size: None,
|
direction: TransferDirection::In,
|
||||||
|
|
||||||
// DmaRxStreamBuf doesn't currently enforce the alignment requirements required for
|
// TODO: support external memory access.
|
||||||
// bursting.
|
#[cfg(esp32s3)]
|
||||||
is_burstable: false,
|
external_memory_block_size: None,
|
||||||
|
|
||||||
|
// TODO: DmaRxStreamBuf doesn't currently enforce the alignment requirements required
|
||||||
|
// for bursting.
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
|
|
||||||
// Whilst we give ownership of the descriptors the DMA, the correctness of this buffer
|
// 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.
|
// implementation doesn't rely on the DMA checking for descriptor ownership.
|
||||||
@ -995,10 +1054,10 @@ unsafe impl DmaTxBuffer for EmptyBuf {
|
|||||||
#[allow(unused_unsafe)] // stable requires unsafe, nightly complains about it
|
#[allow(unused_unsafe)] // stable requires unsafe, nightly complains about it
|
||||||
Preparation {
|
Preparation {
|
||||||
start: unsafe { core::ptr::addr_of_mut!(EMPTY).cast() },
|
start: unsafe { core::ptr::addr_of_mut!(EMPTY).cast() },
|
||||||
block_size: None,
|
direction: TransferDirection::Out,
|
||||||
|
#[cfg(esp32s3)]
|
||||||
// This is TX, the DMA channel is free to do a burst transfer.
|
external_memory_block_size: None,
|
||||||
is_burstable: true,
|
burst_transfer: BurstConfig::Disabled,
|
||||||
|
|
||||||
// As we don't give ownership of the descriptor to the DMA, it's important that the DMA
|
// 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.
|
// channel does *NOT* check for ownership, otherwise the channel will return an error.
|
||||||
@ -1026,10 +1085,10 @@ unsafe impl DmaRxBuffer for EmptyBuf {
|
|||||||
#[allow(unused_unsafe)] // stable requires unsafe, nightly complains about it
|
#[allow(unused_unsafe)] // stable requires unsafe, nightly complains about it
|
||||||
Preparation {
|
Preparation {
|
||||||
start: unsafe { core::ptr::addr_of_mut!(EMPTY).cast() },
|
start: unsafe { core::ptr::addr_of_mut!(EMPTY).cast() },
|
||||||
block_size: None,
|
direction: TransferDirection::In,
|
||||||
|
#[cfg(esp32s3)]
|
||||||
// As much as bursting is meaningless here, the descriptor does meet the requirements.
|
external_memory_block_size: None,
|
||||||
is_burstable: true,
|
burst_transfer: BurstConfig::Disabled,
|
||||||
|
|
||||||
// As we don't give ownership of the descriptor to the DMA, it's important that the DMA
|
// 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.
|
// channel does *NOT* check for ownership, otherwise the channel will return an error.
|
||||||
@ -1104,8 +1163,11 @@ unsafe impl DmaTxBuffer for DmaLoopBuf {
|
|||||||
fn prepare(&mut self) -> Preparation {
|
fn prepare(&mut self) -> Preparation {
|
||||||
Preparation {
|
Preparation {
|
||||||
start: self.descriptor,
|
start: self.descriptor,
|
||||||
block_size: None,
|
direction: TransferDirection::Out,
|
||||||
is_burstable: true,
|
// TODO: support external memory access.
|
||||||
|
#[cfg(esp32s3)]
|
||||||
|
external_memory_block_size: None,
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
// The DMA must not check the owner bit, as it is never set.
|
// The DMA must not check the owner bit, as it is never set.
|
||||||
check_owner: Some(false),
|
check_owner: Some(false),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,11 +169,16 @@ impl<C: GdmaChannel> RegisterAccess for ChannelTxImpl<C> {
|
|||||||
conf0.modify(|_, w| w.out_rst().clear_bit());
|
conf0.modify(|_, w| w.out_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
fn set_burst_mode(&self, burst_mode: BurstConfig) {
|
||||||
self.ch().out_conf0().modify(|_, w| {
|
self.ch()
|
||||||
w.out_data_burst_en().bit(burst_mode);
|
.out_conf0()
|
||||||
w.outdscr_burst_en().bit(burst_mode)
|
.modify(|_, w| w.out_data_burst_en().bit(burst_mode.is_burst_enabled()));
|
||||||
});
|
}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
|
self.ch()
|
||||||
|
.out_conf0()
|
||||||
|
.modify(|_, w| w.outdscr_burst_en().bit(burst_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_priority(&self, priority: DmaPriority) {
|
fn set_priority(&self, priority: DmaPriority) {
|
||||||
@ -388,11 +393,16 @@ impl<C: GdmaChannel> RegisterAccess for ChannelRxImpl<C> {
|
|||||||
conf0.modify(|_, w| w.in_rst().clear_bit());
|
conf0.modify(|_, w| w.in_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
fn set_burst_mode(&self, burst_mode: BurstConfig) {
|
||||||
self.ch().in_conf0().modify(|_, w| {
|
self.ch()
|
||||||
w.in_data_burst_en().bit(burst_mode);
|
.in_conf0()
|
||||||
w.indscr_burst_en().bit(burst_mode)
|
.modify(|_, w| w.in_data_burst_en().bit(burst_mode.is_burst_enabled()));
|
||||||
});
|
}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
|
self.ch()
|
||||||
|
.in_conf0()
|
||||||
|
.modify(|_, w| w.indscr_burst_en().bit(burst_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_priority(&self, priority: DmaPriority) {
|
fn set_priority(&self, priority: DmaPriority) {
|
||||||
@ -559,10 +569,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> {
|
impl<CH: DmaChannel, M: Mode> Channel<'_, M, CH> {
|
||||||
/// Asserts that the channel is compatible with the given peripheral.
|
/// Asserts that the channel is compatible with the given peripheral.
|
||||||
pub fn runtime_ensure_compatible<P: DmaEligible>(&self, _peripheral: &PeripheralRef<'_, P>) {
|
pub fn runtime_ensure_compatible<P: DmaEligible>(&self, _peripheral: &PeripheralRef<'_, P>) {
|
||||||
@ -621,19 +627,19 @@ macro_rules! impl_channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChannelCreator<$num> {
|
impl [<DmaChannel $num>] {
|
||||||
/// Configure the channel for use with blocking APIs
|
/// Unsafely constructs a new DMA channel.
|
||||||
pub fn configure<'a>(
|
///
|
||||||
self,
|
/// # Safety
|
||||||
burst_mode: bool,
|
///
|
||||||
priority: DmaPriority,
|
/// The caller must ensure that only a single instance is used.
|
||||||
) -> Channel<'a, Blocking, [<DmaChannel $num>]> {
|
pub unsafe fn steal<'a>() -> Channel<'a, Blocking, Self> {
|
||||||
let mut this = Channel {
|
let mut this = Channel {
|
||||||
tx: ChannelTx::new(ChannelTxImpl(SpecificGdmaChannel::<$num> {})),
|
tx: ChannelTx::new(ChannelTxImpl(SpecificGdmaChannel::<$num> {})),
|
||||||
rx: ChannelRx::new(ChannelRxImpl(SpecificGdmaChannel::<$num> {})),
|
rx: ChannelRx::new(ChannelRxImpl(SpecificGdmaChannel::<$num> {})),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.configure(burst_mode, priority);
|
this.set_priority(DmaPriority::Priority0);
|
||||||
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
@ -731,19 +737,19 @@ crate::impl_dma_eligible! {
|
|||||||
pub struct Dma<'d> {
|
pub struct Dma<'d> {
|
||||||
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
|
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
|
||||||
/// Channel 0
|
/// Channel 0
|
||||||
pub channel0: ChannelCreator<0>,
|
pub channel0: Channel<'d, Blocking, DmaChannel0>,
|
||||||
/// Channel 1
|
/// Channel 1
|
||||||
#[cfg(not(esp32c2))]
|
#[cfg(not(esp32c2))]
|
||||||
pub channel1: ChannelCreator<1>,
|
pub channel1: Channel<'d, Blocking, DmaChannel1>,
|
||||||
/// Channel 2
|
/// Channel 2
|
||||||
#[cfg(not(esp32c2))]
|
#[cfg(not(esp32c2))]
|
||||||
pub channel2: ChannelCreator<2>,
|
pub channel2: Channel<'d, Blocking, DmaChannel2>,
|
||||||
/// Channel 3
|
/// Channel 3
|
||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
pub channel3: ChannelCreator<3>,
|
pub channel3: Channel<'d, Blocking, DmaChannel3>,
|
||||||
/// Channel 4
|
/// Channel 4
|
||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
pub channel4: ChannelCreator<4>,
|
pub channel4: Channel<'d, Blocking, DmaChannel4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Dma<'d> {
|
impl<'d> Dma<'d> {
|
||||||
@ -761,17 +767,19 @@ impl<'d> Dma<'d> {
|
|||||||
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
|
.modify(|_, w| w.ahbm_rst_inter().clear_bit());
|
||||||
dma.misc_conf().modify(|_, w| w.clk_en().set_bit());
|
dma.misc_conf().modify(|_, w| w.clk_en().set_bit());
|
||||||
|
|
||||||
Dma {
|
unsafe {
|
||||||
_inner: dma,
|
Dma {
|
||||||
channel0: ChannelCreator {},
|
_inner: dma,
|
||||||
#[cfg(not(esp32c2))]
|
channel0: DmaChannel0::steal(),
|
||||||
channel1: ChannelCreator {},
|
#[cfg(not(esp32c2))]
|
||||||
#[cfg(not(esp32c2))]
|
channel1: DmaChannel1::steal(),
|
||||||
channel2: ChannelCreator {},
|
#[cfg(not(esp32c2))]
|
||||||
#[cfg(esp32s3)]
|
channel2: DmaChannel2::steal(),
|
||||||
channel3: ChannelCreator {},
|
#[cfg(esp32s3)]
|
||||||
#[cfg(esp32s3)]
|
channel3: DmaChannel3::steal(),
|
||||||
channel4: ChannelCreator {},
|
#[cfg(esp32s3)]
|
||||||
|
channel4: DmaChannel4::steal(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::dma_buffers;
|
//! # use esp_hal::dma_buffers;
|
||||||
//! # use esp_hal::spi::{master::{Config, Spi}, SpiMode};
|
//! # 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);
|
//! let dma = Dma::new(peripherals.DMA);
|
||||||
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.spi2channel;")]
|
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.spi2channel;")]
|
||||||
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
|
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
|
||||||
@ -40,10 +40,7 @@
|
|||||||
//! .with_mosi(mosi)
|
//! .with_mosi(mosi)
|
||||||
//! .with_miso(miso)
|
//! .with_miso(miso)
|
||||||
//! .with_cs(cs)
|
//! .with_cs(cs)
|
||||||
//! .with_dma(dma_channel.configure(
|
//! .with_dma(dma_channel);
|
||||||
//! false,
|
|
||||||
//! DmaPriority::Priority0,
|
|
||||||
//! ));
|
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -1688,7 +1685,6 @@ pub struct ChannelRx<'a, M, CH>
|
|||||||
where
|
where
|
||||||
CH: DmaChannel,
|
CH: DmaChannel,
|
||||||
{
|
{
|
||||||
pub(crate) burst_mode: bool,
|
|
||||||
pub(crate) rx_impl: CH::Rx,
|
pub(crate) rx_impl: CH::Rx,
|
||||||
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
|
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
|
||||||
}
|
}
|
||||||
@ -1711,7 +1707,6 @@ where
|
|||||||
rx_impl.set_async(false);
|
rx_impl.set_async(false);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
burst_mode: false,
|
|
||||||
rx_impl,
|
rx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -1724,7 +1719,6 @@ where
|
|||||||
}
|
}
|
||||||
self.rx_impl.set_async(true);
|
self.rx_impl.set_async(true);
|
||||||
ChannelRx {
|
ChannelRx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
rx_impl: self.rx_impl,
|
rx_impl: self.rx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -1758,7 +1752,6 @@ where
|
|||||||
}
|
}
|
||||||
self.rx_impl.set_async(false);
|
self.rx_impl.set_async(false);
|
||||||
ChannelRx {
|
ChannelRx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
rx_impl: self.rx_impl,
|
rx_impl: self.rx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -1777,16 +1770,36 @@ where
|
|||||||
CH: DmaChannelConvert<DEG>,
|
CH: DmaChannelConvert<DEG>,
|
||||||
{
|
{
|
||||||
ChannelRx {
|
ChannelRx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
rx_impl: CH::degrade_rx(self.rx_impl),
|
rx_impl: CH::degrade_rx(self.rx_impl),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure the channel.
|
/// Configure the channel.
|
||||||
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
|
#[cfg(gdma)]
|
||||||
self.burst_mode = burst_mode;
|
pub fn set_priority(&mut self, priority: DmaPriority) {
|
||||||
self.rx_impl.configure(burst_mode, priority);
|
self.rx_impl.set_priority(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_prepare(
|
||||||
|
&mut self,
|
||||||
|
preparation: Preparation,
|
||||||
|
peri: DmaPeripheral,
|
||||||
|
) -> Result<(), DmaError> {
|
||||||
|
debug_assert_eq!(preparation.direction, TransferDirection::In);
|
||||||
|
|
||||||
|
self.rx_impl.set_burst_mode(preparation.burst_transfer);
|
||||||
|
self.rx_impl.set_descr_burst_mode(true);
|
||||||
|
self.rx_impl.set_check_owner(preparation.check_owner);
|
||||||
|
|
||||||
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
|
self.rx_impl.clear_all();
|
||||||
|
self.rx_impl.reset();
|
||||||
|
self.rx_impl.set_link_addr(preparation.start as u32);
|
||||||
|
self.rx_impl.set_peripheral(peri as u8);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1802,24 +1815,18 @@ where
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
CH: DmaChannel,
|
CH: DmaChannel,
|
||||||
{
|
{
|
||||||
|
// TODO: used by I2S, which should be rewritten to use the Preparation-based
|
||||||
|
// API.
|
||||||
unsafe fn prepare_transfer_without_start(
|
unsafe fn prepare_transfer_without_start(
|
||||||
&mut self,
|
&mut self,
|
||||||
peri: DmaPeripheral,
|
peri: DmaPeripheral,
|
||||||
chain: &DescriptorChain,
|
chain: &DescriptorChain,
|
||||||
) -> Result<(), DmaError> {
|
) -> Result<(), DmaError> {
|
||||||
if self.burst_mode
|
// For ESP32-S3 we check each descriptor buffer that points to PSRAM for
|
||||||
&& chain
|
// alignment and invalidate the cache for that buffer.
|
||||||
.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
|
|
||||||
// NOTE: for RX the `buffer` and `size` need to be aligned but the `len` does
|
// NOTE: for RX the `buffer` and `size` need to be aligned but the `len` does
|
||||||
// not. TRM section 3.4.9
|
// not. TRM section 3.4.9
|
||||||
|
// Note that DmaBuffer implementations are required to do this for us.
|
||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
for des in chain.descriptors.iter() {
|
for des in chain.descriptors.iter() {
|
||||||
// we are forcing the DMA alignment to the cache line size
|
// we are forcing the DMA alignment to the cache line size
|
||||||
@ -1834,14 +1841,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
self.do_prepare(
|
||||||
|
Preparation {
|
||||||
self.rx_impl.clear_all();
|
start: chain.first().cast_mut(),
|
||||||
self.rx_impl.reset();
|
#[cfg(esp32s3)]
|
||||||
self.rx_impl.set_link_addr(chain.first() as u32);
|
external_memory_block_size: None,
|
||||||
self.rx_impl.set_peripheral(peri as u8);
|
direction: TransferDirection::In,
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
Ok(())
|
check_owner: Some(false),
|
||||||
|
},
|
||||||
|
peri,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn prepare_transfer<BUF: DmaRxBuffer>(
|
unsafe fn prepare_transfer<BUF: DmaRxBuffer>(
|
||||||
@ -1851,19 +1861,7 @@ where
|
|||||||
) -> Result<(), DmaError> {
|
) -> Result<(), DmaError> {
|
||||||
let preparation = buffer.prepare();
|
let preparation = buffer.prepare();
|
||||||
|
|
||||||
self.rx_impl
|
self.do_prepare(preparation, peri)
|
||||||
.set_burst_mode(self.burst_mode && preparation.is_burstable);
|
|
||||||
|
|
||||||
self.rx_impl.set_check_owner(preparation.check_owner);
|
|
||||||
|
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
|
||||||
|
|
||||||
self.rx_impl.clear_all();
|
|
||||||
self.rx_impl.reset();
|
|
||||||
self.rx_impl.set_link_addr(preparation.start as u32);
|
|
||||||
self.rx_impl.set_peripheral(peri as u8);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_transfer(&mut self) -> Result<(), DmaError> {
|
fn start_transfer(&mut self) -> Result<(), DmaError> {
|
||||||
@ -1982,8 +1980,6 @@ pub struct ChannelTx<'a, M, CH>
|
|||||||
where
|
where
|
||||||
CH: DmaChannel,
|
CH: DmaChannel,
|
||||||
{
|
{
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) burst_mode: bool,
|
|
||||||
pub(crate) tx_impl: CH::Tx,
|
pub(crate) tx_impl: CH::Tx,
|
||||||
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
|
pub(crate) _phantom: PhantomData<(&'a (), CH, M)>,
|
||||||
}
|
}
|
||||||
@ -2001,7 +1997,6 @@ where
|
|||||||
tx_impl.set_async(false);
|
tx_impl.set_async(false);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
burst_mode: false,
|
|
||||||
tx_impl,
|
tx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -2014,7 +2009,6 @@ where
|
|||||||
}
|
}
|
||||||
self.tx_impl.set_async(true);
|
self.tx_impl.set_async(true);
|
||||||
ChannelTx {
|
ChannelTx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
tx_impl: self.tx_impl,
|
tx_impl: self.tx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -2048,7 +2042,6 @@ where
|
|||||||
}
|
}
|
||||||
self.tx_impl.set_async(false);
|
self.tx_impl.set_async(false);
|
||||||
ChannelTx {
|
ChannelTx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
tx_impl: self.tx_impl,
|
tx_impl: self.tx_impl,
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@ -2067,16 +2060,41 @@ where
|
|||||||
CH: DmaChannelConvert<DEG>,
|
CH: DmaChannelConvert<DEG>,
|
||||||
{
|
{
|
||||||
ChannelTx {
|
ChannelTx {
|
||||||
burst_mode: self.burst_mode,
|
|
||||||
tx_impl: CH::degrade_tx(self.tx_impl),
|
tx_impl: CH::degrade_tx(self.tx_impl),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure the channel.
|
/// Configure the channel priority.
|
||||||
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
|
#[cfg(gdma)]
|
||||||
self.burst_mode = burst_mode;
|
pub fn set_priority(&mut self, priority: DmaPriority) {
|
||||||
self.tx_impl.configure(burst_mode, priority);
|
self.tx_impl.set_priority(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_prepare(
|
||||||
|
&mut self,
|
||||||
|
preparation: Preparation,
|
||||||
|
peri: DmaPeripheral,
|
||||||
|
) -> Result<(), DmaError> {
|
||||||
|
debug_assert_eq!(preparation.direction, TransferDirection::Out);
|
||||||
|
|
||||||
|
#[cfg(esp32s3)]
|
||||||
|
if let Some(block_size) = preparation.external_memory_block_size {
|
||||||
|
self.set_ext_mem_block_size(block_size.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tx_impl.set_burst_mode(preparation.burst_transfer);
|
||||||
|
self.tx_impl.set_descr_burst_mode(true);
|
||||||
|
self.tx_impl.set_check_owner(preparation.check_owner);
|
||||||
|
|
||||||
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
|
self.tx_impl.clear_all();
|
||||||
|
self.tx_impl.reset();
|
||||||
|
self.tx_impl.set_link_addr(preparation.start as u32);
|
||||||
|
self.tx_impl.set_peripheral(peri as u8);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2092,14 +2110,18 @@ where
|
|||||||
M: Mode,
|
M: Mode,
|
||||||
CH: DmaChannel,
|
CH: DmaChannel,
|
||||||
{
|
{
|
||||||
|
// TODO: used by I2S, which should be rewritten to use the Preparation-based
|
||||||
|
// API.
|
||||||
unsafe fn prepare_transfer_without_start(
|
unsafe fn prepare_transfer_without_start(
|
||||||
&mut self,
|
&mut self,
|
||||||
peri: DmaPeripheral,
|
peri: DmaPeripheral,
|
||||||
chain: &DescriptorChain,
|
chain: &DescriptorChain,
|
||||||
) -> Result<(), DmaError> {
|
) -> Result<(), DmaError> {
|
||||||
// TODO: based on the ESP32-S3 TRM the alignment check is not needed for TX!
|
// Based on the ESP32-S3 TRM the alignment check is not needed for TX
|
||||||
// for esp32s3 we check each descriptor buffer that points to psram for
|
|
||||||
// alignment and writeback the cache for that buffer
|
// For esp32s3 we check each descriptor buffer that points to PSRAM for
|
||||||
|
// alignment and writeback the cache for that buffer.
|
||||||
|
// Note that DmaBuffer implementations are required to do this for us.
|
||||||
#[cfg(esp32s3)]
|
#[cfg(esp32s3)]
|
||||||
for des in chain.descriptors.iter() {
|
for des in chain.descriptors.iter() {
|
||||||
// we are forcing the DMA alignment to the cache line size
|
// we are forcing the DMA alignment to the cache line size
|
||||||
@ -2114,12 +2136,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
self.do_prepare(
|
||||||
|
Preparation {
|
||||||
self.tx_impl.clear_all();
|
start: chain.first().cast_mut(),
|
||||||
self.tx_impl.reset();
|
#[cfg(esp32s3)]
|
||||||
self.tx_impl.set_link_addr(chain.first() as u32);
|
external_memory_block_size: None,
|
||||||
self.tx_impl.set_peripheral(peri as u8);
|
direction: TransferDirection::Out,
|
||||||
|
burst_transfer: BurstConfig::Disabled,
|
||||||
|
check_owner: Some(false),
|
||||||
|
},
|
||||||
|
peri,
|
||||||
|
)?;
|
||||||
|
|
||||||
// enable descriptor write back in circular mode
|
// enable descriptor write back in circular mode
|
||||||
self.tx_impl
|
self.tx_impl
|
||||||
@ -2134,32 +2161,8 @@ where
|
|||||||
buffer: &mut BUF,
|
buffer: &mut BUF,
|
||||||
) -> Result<(), DmaError> {
|
) -> Result<(), DmaError> {
|
||||||
let preparation = buffer.prepare();
|
let preparation = buffer.prepare();
|
||||||
cfg_if::cfg_if!(
|
|
||||||
if #[cfg(esp32s3)] {
|
|
||||||
if let Some(block_size) = preparation.block_size {
|
|
||||||
self.set_ext_mem_block_size(block_size.into());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// we ensure that block_size is some only for PSRAM addresses
|
|
||||||
if preparation.block_size.is_some() {
|
|
||||||
return Err(DmaError::UnsupportedMemoryRegion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
self.tx_impl
|
self.do_prepare(preparation, peri)
|
||||||
.set_burst_mode(self.burst_mode && preparation.is_burstable);
|
|
||||||
|
|
||||||
self.tx_impl.set_check_owner(preparation.check_owner);
|
|
||||||
|
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
|
||||||
|
|
||||||
self.tx_impl.clear_all();
|
|
||||||
self.tx_impl.reset();
|
|
||||||
self.tx_impl.set_link_addr(preparation.start as u32);
|
|
||||||
self.tx_impl.set_peripheral(peri as u8);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_transfer(&mut self) -> Result<(), DmaError> {
|
fn start_transfer(&mut self) -> Result<(), DmaError> {
|
||||||
@ -2223,11 +2226,16 @@ pub trait RegisterAccess: crate::private::Sealed {
|
|||||||
fn reset(&self);
|
fn reset(&self);
|
||||||
|
|
||||||
/// Enable/Disable INCR burst transfer for channel reading
|
/// Enable/Disable INCR burst transfer for channel reading
|
||||||
/// descriptor and accessing data in internal RAM.
|
/// accessing data in internal RAM.
|
||||||
fn set_burst_mode(&self, burst_mode: bool);
|
fn set_burst_mode(&self, burst_mode: BurstConfig);
|
||||||
|
|
||||||
|
/// Enable/Disable burst transfer for channel reading
|
||||||
|
/// descriptors in internal RAM.
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool);
|
||||||
|
|
||||||
/// The priority of the channel. The larger the value, the higher the
|
/// The priority of the channel. The larger the value, the higher the
|
||||||
/// priority.
|
/// priority.
|
||||||
|
#[cfg(gdma)]
|
||||||
fn set_priority(&self, priority: DmaPriority);
|
fn set_priority(&self, priority: DmaPriority);
|
||||||
|
|
||||||
/// Select a peripheral for the channel.
|
/// Select a peripheral for the channel.
|
||||||
@ -2254,12 +2262,6 @@ pub trait RegisterAccess: crate::private::Sealed {
|
|||||||
|
|
||||||
#[cfg(pdma)]
|
#[cfg(pdma)]
|
||||||
fn is_compatible_with(&self, peripheral: DmaPeripheral) -> bool;
|
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)]
|
#[doc(hidden)]
|
||||||
@ -2375,10 +2377,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configure the channel.
|
/// Configure the channel priorities.
|
||||||
pub fn configure(&mut self, burst_mode: bool, priority: DmaPriority) {
|
#[cfg(gdma)]
|
||||||
self.rx.configure(burst_mode, priority);
|
pub fn set_priority(&mut self, priority: DmaPriority) {
|
||||||
self.tx.configure(burst_mode, priority);
|
self.tx.set_priority(priority);
|
||||||
|
self.rx.set_priority(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a blocking channel to an async channel.
|
/// Converts a blocking channel to an async channel.
|
||||||
|
|||||||
@ -57,14 +57,18 @@ impl<C: PdmaChannel<RegisterBlock = SpiRegisterBlock>> RegisterAccess for SpiDma
|
|||||||
spi.dma_conf().modify(|_, w| w.out_rst().clear_bit());
|
spi.dma_conf().modify(|_, w| w.out_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
fn set_burst_mode(&self, burst_mode: BurstConfig) {
|
||||||
|
let spi = self.0.register_block();
|
||||||
|
spi.dma_conf()
|
||||||
|
.modify(|_, w| w.out_data_burst_en().bit(burst_mode.is_burst_enabled()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
let spi = self.0.register_block();
|
let spi = self.0.register_block();
|
||||||
spi.dma_conf()
|
spi.dma_conf()
|
||||||
.modify(|_, w| w.outdscr_burst_en().bit(burst_mode));
|
.modify(|_, w| w.outdscr_burst_en().bit(burst_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_priority(&self, _priority: DmaPriority) {}
|
|
||||||
|
|
||||||
fn set_peripheral(&self, _peripheral: u8) {
|
fn set_peripheral(&self, _peripheral: u8) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
@ -218,14 +222,14 @@ impl<C: PdmaChannel<RegisterBlock = SpiRegisterBlock>> RegisterAccess for SpiDma
|
|||||||
spi.dma_conf().modify(|_, w| w.in_rst().clear_bit());
|
spi.dma_conf().modify(|_, w| w.in_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
fn set_burst_mode(&self, _burst_mode: BurstConfig) {}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
let spi = self.0.register_block();
|
let spi = self.0.register_block();
|
||||||
spi.dma_conf()
|
spi.dma_conf()
|
||||||
.modify(|_, w| w.indscr_burst_en().bit(burst_mode));
|
.modify(|_, w| w.indscr_burst_en().bit(burst_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_priority(&self, _priority: DmaPriority) {}
|
|
||||||
|
|
||||||
fn set_peripheral(&self, _peripheral: u8) {
|
fn set_peripheral(&self, _peripheral: u8) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
@ -442,25 +446,17 @@ macro_rules! ImplSpiChannel {
|
|||||||
|
|
||||||
impl $crate::private::Sealed for [<Spi $num DmaChannel>] {}
|
impl $crate::private::Sealed for [<Spi $num DmaChannel>] {}
|
||||||
|
|
||||||
#[doc = concat!("Creates a channel for SPI", $num)]
|
impl [<Spi $num DmaChannel>] {
|
||||||
#[non_exhaustive]
|
/// Unsafely constructs a new DMA channel.
|
||||||
pub struct [<Spi $num DmaChannelCreator>] {}
|
///
|
||||||
|
/// # Safety
|
||||||
impl [<Spi $num DmaChannelCreator>] {
|
///
|
||||||
/// Configure the channel for use with blocking APIs
|
/// The caller must ensure that only a single instance is used.
|
||||||
pub fn configure<'a>(
|
pub unsafe fn steal<'a>() -> Channel<'a, Blocking, Self> {
|
||||||
self,
|
Channel {
|
||||||
burst_mode: bool,
|
|
||||||
priority: DmaPriority,
|
|
||||||
) -> Channel<'a, Blocking, [<Spi $num DmaChannel>]> {
|
|
||||||
let mut this = Channel {
|
|
||||||
tx: ChannelTx::new(SpiDmaTxChannelImpl([<Spi $num DmaChannel>] {})),
|
tx: ChannelTx::new(SpiDmaTxChannelImpl([<Spi $num DmaChannel>] {})),
|
||||||
rx: ChannelRx::new(SpiDmaRxChannelImpl([<Spi $num DmaChannel>] {})),
|
rx: ChannelRx::new(SpiDmaRxChannelImpl([<Spi $num DmaChannel>] {})),
|
||||||
};
|
}
|
||||||
|
|
||||||
this.configure(burst_mode, priority);
|
|
||||||
|
|
||||||
this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -478,21 +474,26 @@ pub struct I2sDmaTxChannelImpl<C>(C);
|
|||||||
impl<C> crate::private::Sealed for I2sDmaTxChannelImpl<C> {}
|
impl<C> crate::private::Sealed for I2sDmaTxChannelImpl<C> {}
|
||||||
|
|
||||||
impl<C: PdmaChannel<RegisterBlock = I2sRegisterBlock>> RegisterAccess for I2sDmaTxChannelImpl<C> {
|
impl<C: PdmaChannel<RegisterBlock = I2sRegisterBlock>> RegisterAccess for I2sDmaTxChannelImpl<C> {
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
|
||||||
let reg_block = self.0.register_block();
|
|
||||||
reg_block
|
|
||||||
.lc_conf()
|
|
||||||
.modify(|_, w| w.outdscr_burst_en().bit(burst_mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_priority(&self, _priority: DmaPriority) {}
|
|
||||||
|
|
||||||
fn reset(&self) {
|
fn reset(&self) {
|
||||||
let reg_block = self.0.register_block();
|
let reg_block = self.0.register_block();
|
||||||
reg_block.lc_conf().modify(|_, w| w.out_rst().set_bit());
|
reg_block.lc_conf().modify(|_, w| w.out_rst().set_bit());
|
||||||
reg_block.lc_conf().modify(|_, w| w.out_rst().clear_bit());
|
reg_block.lc_conf().modify(|_, w| w.out_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_burst_mode(&self, burst_mode: BurstConfig) {
|
||||||
|
let reg_block = self.0.register_block();
|
||||||
|
reg_block
|
||||||
|
.lc_conf()
|
||||||
|
.modify(|_, w| w.out_data_burst_en().bit(burst_mode.is_burst_enabled()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
|
let reg_block = self.0.register_block();
|
||||||
|
reg_block
|
||||||
|
.lc_conf()
|
||||||
|
.modify(|_, w| w.outdscr_burst_en().bit(burst_mode));
|
||||||
|
}
|
||||||
|
|
||||||
fn set_link_addr(&self, address: u32) {
|
fn set_link_addr(&self, address: u32) {
|
||||||
let reg_block = self.0.register_block();
|
let reg_block = self.0.register_block();
|
||||||
reg_block
|
reg_block
|
||||||
@ -652,21 +653,21 @@ impl<C: PdmaChannel<RegisterBlock = I2sRegisterBlock>> InterruptAccess<DmaTxInte
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<C: PdmaChannel<RegisterBlock = I2sRegisterBlock>> RegisterAccess for I2sDmaRxChannelImpl<C> {
|
impl<C: PdmaChannel<RegisterBlock = I2sRegisterBlock>> RegisterAccess for I2sDmaRxChannelImpl<C> {
|
||||||
fn set_burst_mode(&self, burst_mode: bool) {
|
|
||||||
let reg_block = self.0.register_block();
|
|
||||||
reg_block
|
|
||||||
.lc_conf()
|
|
||||||
.modify(|_, w| w.indscr_burst_en().bit(burst_mode));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_priority(&self, _priority: DmaPriority) {}
|
|
||||||
|
|
||||||
fn reset(&self) {
|
fn reset(&self) {
|
||||||
let reg_block = self.0.register_block();
|
let reg_block = self.0.register_block();
|
||||||
reg_block.lc_conf().modify(|_, w| w.in_rst().set_bit());
|
reg_block.lc_conf().modify(|_, w| w.in_rst().set_bit());
|
||||||
reg_block.lc_conf().modify(|_, w| w.in_rst().clear_bit());
|
reg_block.lc_conf().modify(|_, w| w.in_rst().clear_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_burst_mode(&self, _burst_mode: BurstConfig) {}
|
||||||
|
|
||||||
|
fn set_descr_burst_mode(&self, burst_mode: bool) {
|
||||||
|
let reg_block = self.0.register_block();
|
||||||
|
reg_block
|
||||||
|
.lc_conf()
|
||||||
|
.modify(|_, w| w.indscr_burst_en().bit(burst_mode));
|
||||||
|
}
|
||||||
|
|
||||||
fn set_link_addr(&self, address: u32) {
|
fn set_link_addr(&self, address: u32) {
|
||||||
let reg_block = self.0.register_block();
|
let reg_block = self.0.register_block();
|
||||||
reg_block
|
reg_block
|
||||||
@ -881,24 +882,17 @@ macro_rules! ImplI2sChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = concat!("Creates a channel for I2S", $num)]
|
impl [<I2s $num DmaChannel>] {
|
||||||
pub struct [<I2s $num DmaChannelCreator>] {}
|
/// Unsafely constructs a new DMA channel.
|
||||||
|
///
|
||||||
impl [<I2s $num DmaChannelCreator>] {
|
/// # Safety
|
||||||
/// Configure the channel for use with blocking APIs
|
///
|
||||||
pub fn configure<'a>(
|
/// The caller must ensure that only a single instance is used.
|
||||||
self,
|
pub unsafe fn steal<'a>() -> Channel<'a, Blocking, Self> {
|
||||||
burst_mode: bool,
|
Channel {
|
||||||
priority: DmaPriority,
|
|
||||||
) -> Channel<'a, Blocking, [<I2s $num DmaChannel>]> {
|
|
||||||
let mut this = Channel {
|
|
||||||
tx: ChannelTx::new(I2sDmaTxChannelImpl([<I2s $num DmaChannel>] {})),
|
tx: ChannelTx::new(I2sDmaTxChannelImpl([<I2s $num DmaChannel>] {})),
|
||||||
rx: ChannelRx::new(I2sDmaRxChannelImpl([<I2s $num DmaChannel>] {})),
|
rx: ChannelRx::new(I2sDmaRxChannelImpl([<I2s $num DmaChannel>] {})),
|
||||||
};
|
}
|
||||||
|
|
||||||
this.configure(burst_mode, priority);
|
|
||||||
|
|
||||||
this
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -927,14 +921,14 @@ crate::impl_dma_eligible!([I2s1DmaChannel] I2S1 => I2s1);
|
|||||||
pub struct Dma<'d> {
|
pub struct Dma<'d> {
|
||||||
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
|
_inner: PeripheralRef<'d, crate::peripherals::DMA>,
|
||||||
/// DMA channel for SPI2
|
/// DMA channel for SPI2
|
||||||
pub spi2channel: Spi2DmaChannelCreator,
|
pub spi2channel: Channel<'d, Blocking, Spi2DmaChannel>,
|
||||||
/// DMA channel for SPI3
|
/// DMA channel for SPI3
|
||||||
pub spi3channel: Spi3DmaChannelCreator,
|
pub spi3channel: Channel<'d, Blocking, Spi3DmaChannel>,
|
||||||
/// DMA channel for I2S0
|
/// DMA channel for I2S0
|
||||||
pub i2s0channel: I2s0DmaChannelCreator,
|
pub i2s0channel: Channel<'d, Blocking, I2s0DmaChannel>,
|
||||||
/// DMA channel for I2S1
|
/// DMA channel for I2S1
|
||||||
#[cfg(i2s1)]
|
#[cfg(i2s1)]
|
||||||
pub i2s1channel: I2s1DmaChannelCreator,
|
pub i2s1channel: Channel<'d, Blocking, I2s1DmaChannel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d> Dma<'d> {
|
impl<'d> Dma<'d> {
|
||||||
@ -959,13 +953,15 @@ impl<'d> Dma<'d> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Dma {
|
unsafe {
|
||||||
_inner: dma.into_ref(),
|
Dma {
|
||||||
spi2channel: Spi2DmaChannelCreator {},
|
_inner: dma.into_ref(),
|
||||||
spi3channel: Spi3DmaChannelCreator {},
|
spi2channel: Spi2DmaChannel::steal(),
|
||||||
i2s0channel: I2s0DmaChannelCreator {},
|
spi3channel: Spi3DmaChannel::steal(),
|
||||||
#[cfg(i2s1)]
|
i2s0channel: I2s0DmaChannel::steal(),
|
||||||
i2s1channel: I2s1DmaChannelCreator {},
|
#[cfg(i2s1)]
|
||||||
|
i2s1channel: I2s1DmaChannel::steal(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::i2s::master::{I2s, Standard, DataFormat};
|
//! # use esp_hal::i2s::master::{I2s, Standard, DataFormat};
|
||||||
//! # use esp_hal::dma_buffers;
|
//! # use esp_hal::dma_buffers;
|
||||||
//! # use esp_hal::dma::{Dma, DmaPriority};
|
//! # use esp_hal::dma::Dma;
|
||||||
//! let dma = Dma::new(peripherals.DMA);
|
//! let dma = Dma::new(peripherals.DMA);
|
||||||
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.i2s0channel;")]
|
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.i2s0channel;")]
|
||||||
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
|
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
|
||||||
@ -43,10 +43,7 @@
|
|||||||
//! Standard::Philips,
|
//! Standard::Philips,
|
||||||
//! DataFormat::Data16Channel16,
|
//! DataFormat::Data16Channel16,
|
||||||
//! 44100.Hz(),
|
//! 44100.Hz(),
|
||||||
//! dma_channel.configure(
|
//! dma_channel,
|
||||||
//! false,
|
|
||||||
//! DmaPriority::Priority0,
|
|
||||||
//! ),
|
|
||||||
//! rx_descriptors,
|
//! rx_descriptors,
|
||||||
//! tx_descriptors,
|
//! tx_descriptors,
|
||||||
//! );
|
//! );
|
||||||
@ -430,7 +427,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the SPI instance into async mode.
|
/// Converts the I2S instance into async mode.
|
||||||
pub fn into_async(self) -> I2s<'d, Async, T> {
|
pub fn into_async(self) -> I2s<'d, Async, T> {
|
||||||
I2s {
|
I2s {
|
||||||
i2s_rx: RxCreator {
|
i2s_rx: RxCreator {
|
||||||
|
|||||||
@ -62,6 +62,7 @@ use crate::{
|
|||||||
private::Internal,
|
private::Internal,
|
||||||
system::PeripheralGuard,
|
system::PeripheralGuard,
|
||||||
Async,
|
Async,
|
||||||
|
Blocking,
|
||||||
Mode,
|
Mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -180,14 +181,11 @@ where
|
|||||||
_guard: PeripheralGuard,
|
_guard: PeripheralGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, DM> I2sParallel<'d, DM>
|
impl<'d> I2sParallel<'d, Blocking> {
|
||||||
where
|
|
||||||
DM: Mode,
|
|
||||||
{
|
|
||||||
/// Create a new I2S Parallel Interface
|
/// Create a new I2S Parallel Interface
|
||||||
pub fn new<CH>(
|
pub fn new<CH>(
|
||||||
i2s: impl Peripheral<P = impl Instance> + 'd,
|
i2s: impl Peripheral<P = impl Instance> + 'd,
|
||||||
channel: Channel<'d, DM, CH>,
|
channel: Channel<'d, Blocking, CH>,
|
||||||
frequency: impl Into<fugit::HertzU32>,
|
frequency: impl Into<fugit::HertzU32>,
|
||||||
pins: impl TxPins<'d>,
|
pins: impl TxPins<'d>,
|
||||||
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
@ -199,15 +197,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, I, DM> I2sParallel<'d, DM, I>
|
impl<'d, I> I2sParallel<'d, Blocking, I>
|
||||||
where
|
where
|
||||||
I: Instance,
|
I: Instance,
|
||||||
DM: Mode,
|
|
||||||
{
|
{
|
||||||
/// Create a new I2S Parallel Interface
|
/// Create a new I2S Parallel Interface
|
||||||
pub fn new_typed<CH>(
|
pub fn new_typed<CH>(
|
||||||
i2s: impl Peripheral<P = I> + 'd,
|
i2s: impl Peripheral<P = I> + 'd,
|
||||||
channel: Channel<'d, DM, CH>,
|
channel: Channel<'d, Blocking, CH>,
|
||||||
frequency: impl Into<fugit::HertzU32>,
|
frequency: impl Into<fugit::HertzU32>,
|
||||||
mut pins: impl TxPins<'d>,
|
mut pins: impl TxPins<'d>,
|
||||||
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
clock_pin: impl Peripheral<P = impl PeripheralOutput> + 'd,
|
||||||
@ -237,6 +234,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts the I2S instance into async mode.
|
||||||
|
pub fn into_async(self) -> I2sParallel<'d, Async, I> {
|
||||||
|
I2sParallel {
|
||||||
|
instance: self.instance,
|
||||||
|
tx_channel: self.tx_channel.into_async(),
|
||||||
|
_guard: self._guard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, I> I2sParallel<'d, Async, I>
|
||||||
|
where
|
||||||
|
I: Instance,
|
||||||
|
{
|
||||||
|
/// Converts the I2S instance into async mode.
|
||||||
|
pub fn into_blocking(self) -> I2sParallel<'d, Blocking, I> {
|
||||||
|
I2sParallel {
|
||||||
|
instance: self.instance,
|
||||||
|
tx_channel: self.tx_channel.into_blocking(),
|
||||||
|
_guard: self._guard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'d, I, DM> I2sParallel<'d, DM, I>
|
||||||
|
where
|
||||||
|
I: Instance,
|
||||||
|
DM: Mode,
|
||||||
|
{
|
||||||
/// Write data to the I2S peripheral
|
/// Write data to the I2S peripheral
|
||||||
pub fn send<BUF: DmaTxBuffer>(
|
pub fn send<BUF: DmaTxBuffer>(
|
||||||
mut self,
|
mut self,
|
||||||
|
|||||||
@ -19,18 +19,13 @@
|
|||||||
//! # use esp_hal::lcd_cam::{cam::{Camera, RxEightBits}, LcdCam};
|
//! # use esp_hal::lcd_cam::{cam::{Camera, RxEightBits}, LcdCam};
|
||||||
//! # use fugit::RateExtU32;
|
//! # use fugit::RateExtU32;
|
||||||
//! # use esp_hal::dma_rx_stream_buffer;
|
//! # use esp_hal::dma_rx_stream_buffer;
|
||||||
//! # use esp_hal::dma::{Dma, DmaPriority};
|
//! # use esp_hal::dma::Dma;
|
||||||
//!
|
//!
|
||||||
//! # let dma = Dma::new(peripherals.DMA);
|
//! # let dma = Dma::new(peripherals.DMA);
|
||||||
//! # let channel = dma.channel0;
|
//! # let channel = dma.channel0;
|
||||||
//!
|
//!
|
||||||
//! # let dma_buf = dma_rx_stream_buffer!(20 * 1000, 1000);
|
//! # let dma_buf = dma_rx_stream_buffer!(20 * 1000, 1000);
|
||||||
//!
|
//!
|
||||||
//! # let channel = channel.configure(
|
|
||||||
//! # false,
|
|
||||||
//! # DmaPriority::Priority0,
|
|
||||||
//! # );
|
|
||||||
//!
|
|
||||||
//! let mclk_pin = peripherals.GPIO15;
|
//! let mclk_pin = peripherals.GPIO15;
|
||||||
//! let vsync_pin = peripherals.GPIO6;
|
//! let vsync_pin = peripherals.GPIO6;
|
||||||
//! let href_pin = peripherals.GPIO7;
|
//! let href_pin = peripherals.GPIO7;
|
||||||
|
|||||||
@ -31,11 +31,6 @@
|
|||||||
//!
|
//!
|
||||||
//! # let mut dma_buf = dma_loop_buffer!(32);
|
//! # let mut dma_buf = dma_loop_buffer!(32);
|
||||||
//!
|
//!
|
||||||
//! # let channel = channel.configure(
|
|
||||||
//! # false,
|
|
||||||
//! # DmaPriority::Priority0,
|
|
||||||
//! # );
|
|
||||||
//!
|
|
||||||
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
//!
|
//!
|
||||||
//! let mut config = dpi::Config::default();
|
//! let mut config = dpi::Config::default();
|
||||||
|
|||||||
@ -17,18 +17,13 @@
|
|||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::lcd_cam::{LcdCam, lcd::i8080::{Config, I8080, TxEightBits}};
|
//! # use esp_hal::lcd_cam::{LcdCam, lcd::i8080::{Config, I8080, TxEightBits}};
|
||||||
//! # use esp_hal::dma_tx_buffer;
|
//! # use esp_hal::dma_tx_buffer;
|
||||||
//! # use esp_hal::dma::{Dma, DmaPriority, DmaTxBuf};
|
//! # use esp_hal::dma::{Dma, DmaTxBuf};
|
||||||
//!
|
//!
|
||||||
//! # let dma = Dma::new(peripherals.DMA);
|
//! # let dma = Dma::new(peripherals.DMA);
|
||||||
//! # let channel = dma.channel0;
|
//! # let channel = dma.channel0;
|
||||||
//!
|
//!
|
||||||
//! # let mut dma_buf = dma_tx_buffer!(32678).unwrap();
|
//! # let mut dma_buf = dma_tx_buffer!(32678).unwrap();
|
||||||
//!
|
//!
|
||||||
//! # let channel = channel.configure(
|
|
||||||
//! # false,
|
|
||||||
//! # DmaPriority::Priority0,
|
|
||||||
//! # );
|
|
||||||
//!
|
|
||||||
//! let tx_pins = TxEightBits::new(
|
//! let tx_pins = TxEightBits::new(
|
||||||
//! peripherals.GPIO9,
|
//! peripherals.GPIO9,
|
||||||
//! peripherals.GPIO46,
|
//! peripherals.GPIO46,
|
||||||
|
|||||||
@ -867,6 +867,8 @@ mod dma {
|
|||||||
Rx,
|
Rx,
|
||||||
Tx,
|
Tx,
|
||||||
},
|
},
|
||||||
|
Async,
|
||||||
|
Blocking,
|
||||||
InterruptConfigurable,
|
InterruptConfigurable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
//!
|
//!
|
||||||
//! ```rust, no_run
|
//! ```rust, no_run
|
||||||
#![doc = crate::before_snippet!()]
|
#![doc = crate::before_snippet!()]
|
||||||
//! # use esp_hal::dma::DmaPriority;
|
|
||||||
//! # use esp_hal::dma_buffers;
|
//! # use esp_hal::dma_buffers;
|
||||||
//! # use esp_hal::spi::SpiMode;
|
//! # use esp_hal::spi::SpiMode;
|
||||||
//! # use esp_hal::spi::slave::Spi;
|
//! # use esp_hal::spi::slave::Spi;
|
||||||
@ -39,10 +38,7 @@
|
|||||||
//! .with_miso(miso)
|
//! .with_miso(miso)
|
||||||
//! .with_cs(cs)
|
//! .with_cs(cs)
|
||||||
//! .with_dma(
|
//! .with_dma(
|
||||||
//! dma_channel.configure(
|
//! dma_channel,
|
||||||
//! false,
|
|
||||||
//! DmaPriority::Priority0,
|
|
||||||
//! ),
|
|
||||||
//! rx_descriptors,
|
//! rx_descriptors,
|
||||||
//! tx_descriptors,
|
//! tx_descriptors,
|
||||||
//! );
|
//! );
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use esp_alloc as _;
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, Mem2Mem},
|
dma::{Dma, Mem2Mem},
|
||||||
dma_descriptors_chunk_size,
|
dma_descriptors_chunk_size,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
@ -68,11 +68,10 @@ fn main() -> ! {
|
|||||||
let (rx_descriptors, tx_descriptors) = dma_descriptors_chunk_size!(DATA_SIZE, CHUNK_SIZE);
|
let (rx_descriptors, tx_descriptors) = dma_descriptors_chunk_size!(DATA_SIZE, CHUNK_SIZE);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
|
|
||||||
let dma_peripheral = peripherals.SPI2;
|
let dma_peripheral = peripherals.SPI2;
|
||||||
|
|
||||||
let mut mem2mem = Mem2Mem::new_with_chunk_size(
|
let mut mem2mem = Mem2Mem::new_with_chunk_size(
|
||||||
channel,
|
dma.channel0,
|
||||||
dma_peripheral,
|
dma_peripheral,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, Mem2Mem},
|
dma::{Dma, Mem2Mem},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
@ -28,14 +28,13 @@ fn main() -> ! {
|
|||||||
let (mut rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(DATA_SIZE);
|
let (mut rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(DATA_SIZE);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
|
|
||||||
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
|
#[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))]
|
||||||
let dma_peripheral = peripherals.SPI2;
|
let dma_peripheral = peripherals.SPI2;
|
||||||
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
|
#[cfg(not(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3")))]
|
||||||
let dma_peripheral = peripherals.MEM2MEM1;
|
let dma_peripheral = peripherals.MEM2MEM1;
|
||||||
|
|
||||||
let mut mem2mem =
|
let mut mem2mem =
|
||||||
Mem2Mem::new(channel, dma_peripheral, rx_descriptors, tx_descriptors).unwrap();
|
Mem2Mem::new(dma.channel0, dma_peripheral, rx_descriptors, tx_descriptors).unwrap();
|
||||||
|
|
||||||
for i in 0..core::mem::size_of_val(tx_buffer) {
|
for i in 0..core::mem::size_of_val(tx_buffer) {
|
||||||
tx_buffer[i] = (i % 256) as u8;
|
tx_buffer[i] = (i % 256) as u8;
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use embassy_executor::Spawner;
|
|||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::parallel::{I2sParallel, TxEightBits},
|
i2s::parallel::{I2sParallel, TxEightBits},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -56,15 +56,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, BUFFER_SIZE);
|
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, BUFFER_SIZE);
|
||||||
let mut parallel = I2sParallel::new(
|
let mut parallel = I2sParallel::new(i2s, dma_channel, 1.MHz(), pins, clock).into_async();
|
||||||
i2s,
|
|
||||||
dma_channel
|
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.into_async(),
|
|
||||||
1.MHz(),
|
|
||||||
pins,
|
|
||||||
clock,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (i, data) in tx_buffer.chunks_mut(4).enumerate() {
|
for (i, data) in tx_buffer.chunks_mut(4).enumerate() {
|
||||||
let offset = i * 4;
|
let offset = i * 4;
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::master::{DataFormat, I2s, Standard},
|
i2s::master::{DataFormat, I2s, Standard},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -49,7 +49,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
44100u32.Hz(),
|
44100u32.Hz(),
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -14,7 +14,7 @@ use embassy_executor::Spawner;
|
|||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::NoPin,
|
gpio::NoPin,
|
||||||
parl_io::{BitPackOrder, ParlIoRxOnly, RxFourBits},
|
parl_io::{BitPackOrder, ParlIoRxOnly, RxFourBits},
|
||||||
@ -34,7 +34,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
let (rx_buffer, rx_descriptors, _, _) = dma_buffers!(32000, 0);
|
let (rx_buffer, rx_descriptors, _, _) = dma_buffers!(32000, 0);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let mut rx_pins = RxFourBits::new(
|
let mut rx_pins = RxFourBits::new(
|
||||||
peripherals.GPIO1,
|
peripherals.GPIO1,
|
||||||
@ -46,9 +45,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let parl_io = ParlIoRxOnly::new(
|
let parl_io = ParlIoRxOnly::new(
|
||||||
peripherals.PARL_IO,
|
peripherals.PARL_IO,
|
||||||
dma_channel
|
dma.channel0.into_async(),
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.into_async(),
|
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
1.MHz(),
|
1.MHz(),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -18,7 +18,7 @@ use embassy_executor::Spawner;
|
|||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
parl_io::{
|
parl_io::{
|
||||||
BitPackOrder,
|
BitPackOrder,
|
||||||
@ -44,7 +44,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32000);
|
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, 32000);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let dma_channel = dma.channel0;
|
|
||||||
|
|
||||||
let tx_pins = TxFourBits::new(
|
let tx_pins = TxFourBits::new(
|
||||||
peripherals.GPIO1,
|
peripherals.GPIO1,
|
||||||
@ -57,9 +56,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let parl_io = ParlIoTxOnly::new(
|
let parl_io = ParlIoTxOnly::new(
|
||||||
peripherals.PARL_IO,
|
peripherals.PARL_IO,
|
||||||
dma_channel
|
dma.channel0.into_async(),
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.into_async(),
|
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
1.MHz(),
|
1.MHz(),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -71,7 +71,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_miso(miso)
|
.with_miso(miso)
|
||||||
.with_cs(cs)
|
.with_cs(cs)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0))
|
.with_dma(dma_channel)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf)
|
.with_buffers(dma_rx_buf, dma_tx_buf)
|
||||||
.into_async();
|
.into_async();
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::parallel::{I2sParallel, TxEightBits},
|
i2s::parallel::{I2sParallel, TxEightBits},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -50,13 +50,7 @@ fn main() -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, BUFFER_SIZE);
|
let (_, _, tx_buffer, tx_descriptors) = dma_buffers!(0, BUFFER_SIZE);
|
||||||
let mut parallel = I2sParallel::new(
|
let mut parallel = I2sParallel::new(i2s, dma_channel, 1.MHz(), pins, clock);
|
||||||
i2s,
|
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
1.MHz(),
|
|
||||||
pins,
|
|
||||||
clock,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (i, data) in tx_buffer.chunks_mut(4).enumerate() {
|
for (i, data) in tx_buffer.chunks_mut(4).enumerate() {
|
||||||
let offset = i * 4;
|
let offset = i * 4;
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::master::{DataFormat, I2s, Standard},
|
i2s::master::{DataFormat, I2s, Standard},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -46,7 +46,7 @@ fn main() -> ! {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
44100.Hz(),
|
44100.Hz(),
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ use core::iter::{empty, once};
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_loop_buffer,
|
dma_loop_buffer,
|
||||||
gpio::{Level, Output},
|
gpio::{Level, Output},
|
||||||
i2c,
|
i2c,
|
||||||
@ -71,7 +71,7 @@ fn main() -> ! {
|
|||||||
.with_scl(peripherals.GPIO48);
|
.with_scl(peripherals.GPIO48);
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let channel = dma.channel2.configure(true, DmaPriority::Priority0);
|
let channel = dma.channel2;
|
||||||
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
|
|
||||||
let mut expander = Tca9554::new(i2c);
|
let mut expander = Tca9554::new(i2c);
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::NoPin,
|
gpio::NoPin,
|
||||||
parl_io::{BitPackOrder, ParlIoRxOnly, RxFourBits},
|
parl_io::{BitPackOrder, ParlIoRxOnly, RxFourBits},
|
||||||
@ -37,13 +37,8 @@ fn main() -> ! {
|
|||||||
);
|
);
|
||||||
let mut rx_clk_pin = NoPin;
|
let mut rx_clk_pin = NoPin;
|
||||||
|
|
||||||
let parl_io = ParlIoRxOnly::new(
|
let parl_io =
|
||||||
peripherals.PARL_IO,
|
ParlIoRxOnly::new(peripherals.PARL_IO, dma_channel, rx_descriptors, 1.MHz()).unwrap();
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
rx_descriptors,
|
|
||||||
1.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut parl_io_rx = parl_io
|
let mut parl_io_rx = parl_io
|
||||||
.rx
|
.rx
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
parl_io::{
|
parl_io::{
|
||||||
BitPackOrder,
|
BitPackOrder,
|
||||||
@ -48,13 +48,8 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let mut pin_conf = TxPinConfigWithValidPin::new(tx_pins, peripherals.GPIO5);
|
let mut pin_conf = TxPinConfigWithValidPin::new(tx_pins, peripherals.GPIO5);
|
||||||
|
|
||||||
let parl_io = ParlIoTxOnly::new(
|
let parl_io =
|
||||||
peripherals.PARL_IO,
|
ParlIoTxOnly::new(peripherals.PARL_IO, dma_channel, tx_descriptors, 1.MHz()).unwrap();
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
tx_descriptors,
|
|
||||||
1.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut clock_pin = ClkOutPin::new(peripherals.GPIO6);
|
let mut clock_pin = ClkOutPin::new(peripherals.GPIO6);
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
@ -66,7 +66,7 @@ fn main() -> ! {
|
|||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_miso(miso)
|
.with_miso(miso)
|
||||||
.with_cs(cs)
|
.with_cs(cs)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaBufBlkSize, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaBufBlkSize, DmaRxBuf, DmaTxBuf},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
@ -103,7 +103,7 @@ fn main() -> ! {
|
|||||||
.with_miso(miso)
|
.with_miso(miso)
|
||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_cs(cs)
|
.with_cs(cs)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
delay.delay_millis(100); // delay to let the above messages display
|
delay.delay_millis(100); // delay to let the above messages display
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Input, Level, Output, Pull},
|
gpio::{Input, Level, Output, Pull},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -70,11 +70,7 @@ fn main() -> ! {
|
|||||||
.with_mosi(slave_mosi)
|
.with_mosi(slave_mosi)
|
||||||
.with_miso(slave_miso)
|
.with_miso(slave_miso)
|
||||||
.with_cs(slave_cs)
|
.with_cs(slave_cs)
|
||||||
.with_dma(
|
.with_dma(dma_channel, rx_descriptors, tx_descriptors);
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
rx_descriptors,
|
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
aes::{dma::CipherMode, Aes, Mode},
|
aes::{dma::CipherMode, Aes, Mode},
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
};
|
};
|
||||||
@ -32,11 +32,8 @@ mod tests {
|
|||||||
|
|
||||||
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
let mut aes = Aes::new(peripherals.AES).with_dma(
|
let mut aes =
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
Aes::new(peripherals.AES).with_dma(dma_channel, rx_descriptors, tx_descriptors);
|
||||||
rx_descriptors,
|
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let keytext = b"SUp4SeCp@sSw0rd";
|
let keytext = b"SUp4SeCp@sSw0rd";
|
||||||
let mut keybuf = [0_u8; 16];
|
let mut keybuf = [0_u8; 16];
|
||||||
@ -74,11 +71,8 @@ mod tests {
|
|||||||
|
|
||||||
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
let mut aes = Aes::new(peripherals.AES).with_dma(
|
let mut aes =
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
Aes::new(peripherals.AES).with_dma(dma_channel, rx_descriptors, tx_descriptors);
|
||||||
rx_descriptors,
|
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let keytext = b"SUp4SeCp@sSw0rd";
|
let keytext = b"SUp4SeCp@sSw0rd";
|
||||||
let mut keybuf = [0_u8; 16];
|
let mut keybuf = [0_u8; 16];
|
||||||
@ -115,11 +109,8 @@ mod tests {
|
|||||||
|
|
||||||
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
let mut aes = Aes::new(peripherals.AES).with_dma(
|
let mut aes =
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
Aes::new(peripherals.AES).with_dma(dma_channel, rx_descriptors, tx_descriptors);
|
||||||
rx_descriptors,
|
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let keytext = b"SUp4SeCp@sSw0rd";
|
let keytext = b"SUp4SeCp@sSw0rd";
|
||||||
let mut keybuf = [0_u8; 16];
|
let mut keybuf = [0_u8; 16];
|
||||||
@ -157,11 +148,8 @@ mod tests {
|
|||||||
|
|
||||||
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
let (mut output, rx_descriptors, input, tx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
let mut aes = Aes::new(peripherals.AES).with_dma(
|
let mut aes =
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
Aes::new(peripherals.AES).with_dma(dma_channel, rx_descriptors, tx_descriptors);
|
||||||
rx_descriptors,
|
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let keytext = b"SUp4SeCp@sSw0rd";
|
let keytext = b"SUp4SeCp@sSw0rd";
|
||||||
let mut keybuf = [0_u8; 16];
|
let mut keybuf = [0_u8; 16];
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{AnyGdmaChannel, Channel, Dma, DmaError, DmaPriority, Mem2Mem},
|
dma::{AnyGdmaChannel, Channel, Dma, DmaError, Mem2Mem},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
dma_buffers_chunk_size,
|
dma_buffers_chunk_size,
|
||||||
dma_descriptors,
|
dma_descriptors,
|
||||||
@ -50,9 +50,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
channel: dma_channel
|
channel: dma_channel.degrade(),
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.degrade(),
|
|
||||||
dma_peripheral,
|
dma_peripheral,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use embassy_time::{Duration, Instant, Ticker};
|
use embassy_time::{Duration, Instant, Ticker};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
interrupt::{software::SoftwareInterruptControl, Priority},
|
interrupt::{software::SoftwareInterruptControl, Priority},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
@ -129,7 +129,7 @@ mod test {
|
|||||||
)
|
)
|
||||||
.with_miso(unsafe { mosi.clone_unchecked() })
|
.with_miso(unsafe { mosi.clone_unchecked() })
|
||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_dma(dma_channel1.configure(false, DmaPriority::Priority0))
|
.with_dma(dma_channel1)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf)
|
.with_buffers(dma_rx_buf, dma_tx_buf)
|
||||||
.into_async();
|
.into_async();
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ mod test {
|
|||||||
..Config::default()
|
..Config::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_dma(dma_channel2.configure(false, DmaPriority::Priority0))
|
.with_dma(dma_channel2)
|
||||||
.into_async();
|
.into_async();
|
||||||
|
|
||||||
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
|
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
|
||||||
@ -154,7 +154,7 @@ mod test {
|
|||||||
esp_hal::i2s::master::Standard::Philips,
|
esp_hal::i2s::master::Standard::Philips,
|
||||||
esp_hal::i2s::master::DataFormat::Data8Channel8,
|
esp_hal::i2s::master::DataFormat::Data8Channel8,
|
||||||
8u32.kHz(),
|
8u32.kHz(),
|
||||||
dma_channel2.configure(false, DmaPriority::Priority0),
|
dma_channel2,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
)
|
)
|
||||||
@ -205,14 +205,14 @@ mod test {
|
|||||||
#[timeout(3)]
|
#[timeout(3)]
|
||||||
async fn dma_does_not_lock_up_on_core_1() {
|
async fn dma_does_not_lock_up_on_core_1() {
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use esp_hal::peripherals::SPI2;
|
use esp_hal::{dma::Channel, peripherals::SPI2, Blocking};
|
||||||
use portable_atomic::{AtomicU32, Ordering};
|
use portable_atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(pdma)] {
|
if #[cfg(pdma)] {
|
||||||
use esp_hal::dma::Spi2DmaChannelCreator as DmaChannelCreator;
|
use esp_hal::dma::Spi2DmaChannel as DmaChannel;
|
||||||
} else {
|
} else {
|
||||||
type DmaChannelCreator = esp_hal::dma::ChannelCreator<0>;
|
type DmaChannel = esp_hal::dma::DmaChannel0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ mod test {
|
|||||||
|
|
||||||
pub struct SpiPeripherals {
|
pub struct SpiPeripherals {
|
||||||
pub spi: SPI2,
|
pub spi: SPI2,
|
||||||
pub dma_channel: DmaChannelCreator,
|
pub dma_channel: Channel<'static, Blocking, DmaChannel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
@ -238,11 +238,7 @@ mod test {
|
|||||||
..Config::default()
|
..Config::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.with_dma(
|
.with_dma(peripherals.dma_channel)
|
||||||
peripherals
|
|
||||||
.dma_channel
|
|
||||||
.configure(false, DmaPriority::Priority0),
|
|
||||||
)
|
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf)
|
.with_buffers(dma_rx_buf, dma_tx_buf)
|
||||||
.into_async();
|
.into_async();
|
||||||
|
|
||||||
|
|||||||
@ -12,21 +12,22 @@
|
|||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Channel, Dma},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{AnyPin, NoPin, Pin},
|
gpio::{AnyPin, NoPin, Pin},
|
||||||
i2s::master::{DataFormat, I2s, I2sTx, Standard},
|
i2s::master::{DataFormat, I2s, I2sTx, Standard},
|
||||||
peripherals::I2S0,
|
peripherals::I2S0,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
Async,
|
Async,
|
||||||
|
Blocking,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(esp32, esp32s2))] {
|
if #[cfg(any(esp32, esp32s2))] {
|
||||||
type DmaChannel0Creator = esp_hal::dma::I2s0DmaChannelCreator;
|
type DmaChannel0 = esp_hal::dma::I2s0DmaChannel;
|
||||||
} else {
|
} else {
|
||||||
type DmaChannel0Creator = esp_hal::dma::ChannelCreator<0>;
|
type DmaChannel0 = esp_hal::dma::DmaChannel0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +105,7 @@ mod tests {
|
|||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
dout: AnyPin,
|
dout: AnyPin,
|
||||||
dma_channel: DmaChannel0Creator,
|
dma_channel: Channel<'static, Blocking, DmaChannel0>,
|
||||||
i2s: I2S0,
|
i2s: I2S0,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ mod tests {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
16000.Hz(),
|
16000.Hz(),
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
ctx.dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
)
|
)
|
||||||
@ -196,7 +197,7 @@ mod tests {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
16000.Hz(),
|
16000.Hz(),
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
ctx.dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
);
|
);
|
||||||
@ -305,7 +306,7 @@ mod tests {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
16000.Hz(),
|
16000.Hz(),
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
ctx.dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
);
|
);
|
||||||
@ -335,7 +336,7 @@ mod tests {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
16000.Hz(),
|
16000.Hz(),
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
ctx.dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
//! LCD_CAM Camera and DPI tests
|
//! LCD_CAM Camera and DPI tests
|
||||||
|
|
||||||
//% CHIPS: esp32s3
|
//% CHIPS: esp32s3
|
||||||
//% FEATURES: defmt
|
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
@ -59,7 +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);
|
||||||
|
|
||||||
let channel = dma.channel2.configure(false, DmaPriority::Priority0);
|
let channel = dma.channel2;
|
||||||
|
|
||||||
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();
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{GpioPin, NoPin},
|
gpio::{GpioPin, NoPin},
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
@ -74,13 +74,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i8080_8bit(ctx: Context<'static>) {
|
fn test_i8080_8bit(ctx: Context<'static>) {
|
||||||
let channel = ctx.dma.channel0.configure(false, DmaPriority::Priority0);
|
|
||||||
|
|
||||||
let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin);
|
let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin);
|
||||||
|
|
||||||
let i8080 = I8080::new(
|
let i8080 = I8080::new(
|
||||||
ctx.lcd_cam.lcd,
|
ctx.lcd_cam.lcd,
|
||||||
channel.tx,
|
ctx.dma.channel0.tx,
|
||||||
pins,
|
pins,
|
||||||
20.MHz(),
|
20.MHz(),
|
||||||
Config::default(),
|
Config::default(),
|
||||||
@ -130,7 +128,6 @@ mod tests {
|
|||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
let channel = ctx.dma.channel0.configure(false, DmaPriority::Priority0);
|
|
||||||
let pins = TxEightBits::new(
|
let pins = TxEightBits::new(
|
||||||
unit0_signal,
|
unit0_signal,
|
||||||
unit1_signal,
|
unit1_signal,
|
||||||
@ -144,7 +141,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut i8080 = I8080::new(
|
let mut i8080 = I8080::new(
|
||||||
ctx.lcd_cam.lcd,
|
ctx.lcd_cam.lcd,
|
||||||
channel.tx,
|
ctx.dma.channel0.tx,
|
||||||
pins,
|
pins,
|
||||||
20.MHz(),
|
20.MHz(),
|
||||||
Config::default(),
|
Config::default(),
|
||||||
@ -241,7 +238,7 @@ mod tests {
|
|||||||
.channel0
|
.channel0
|
||||||
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
.set_input_mode(EdgeMode::Hold, EdgeMode::Increment);
|
||||||
|
|
||||||
let channel = ctx.dma.channel0.configure(false, DmaPriority::Priority0);
|
let channel = ctx.dma.channel0;
|
||||||
let pins = TxSixteenBits::new(
|
let pins = TxSixteenBits::new(
|
||||||
NoPin,
|
NoPin,
|
||||||
NoPin,
|
NoPin,
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::NoPin,
|
gpio::NoPin,
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
@ -50,12 +50,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_i8080_8bit(ctx: Context<'static>) {
|
async fn test_i8080_8bit(ctx: Context<'static>) {
|
||||||
let channel = ctx.dma.channel0.configure(false, DmaPriority::Priority0);
|
|
||||||
let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin);
|
let pins = TxEightBits::new(NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin, NoPin);
|
||||||
|
|
||||||
let i8080 = I8080::new(
|
let i8080 = I8080::new(
|
||||||
ctx.lcd_cam.lcd,
|
ctx.lcd_cam.lcd,
|
||||||
channel.tx,
|
ctx.dma.channel0.tx,
|
||||||
pins,
|
pins,
|
||||||
20.MHz(),
|
20.MHz(),
|
||||||
Config::default(),
|
Config::default(),
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#[cfg(esp32c6)]
|
#[cfg(esp32c6)]
|
||||||
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{ChannelCreator, Dma, DmaPriority},
|
dma::{Channel, Dma, DmaChannel0},
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{InputSignal, OutputSignal},
|
interconnect::{InputSignal, OutputSignal},
|
||||||
NoPin,
|
NoPin,
|
||||||
@ -27,12 +27,13 @@ use esp_hal::{
|
|||||||
},
|
},
|
||||||
peripherals::PARL_IO,
|
peripherals::PARL_IO,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
Blocking,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
parl_io: PARL_IO,
|
parl_io: PARL_IO,
|
||||||
dma_channel: ChannelCreator<0>,
|
dma_channel: Channel<'static, Blocking, DmaChannel0>,
|
||||||
clock: OutputSignal,
|
clock: OutputSignal,
|
||||||
valid: OutputSignal,
|
valid: OutputSignal,
|
||||||
clock_loopback: InputSignal,
|
clock_loopback: InputSignal,
|
||||||
@ -88,13 +89,8 @@ mod tests {
|
|||||||
let mut pins = TxPinConfigIncludingValidPin::new(pins);
|
let mut pins = TxPinConfigIncludingValidPin::new(pins);
|
||||||
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
||||||
|
|
||||||
let pio = ParlIoTxOnly::new(
|
let pio =
|
||||||
ctx.parl_io,
|
ParlIoTxOnly::new(ctx.parl_io, ctx.dma_channel, tx_descriptors, 10.MHz()).unwrap();
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
tx_descriptors,
|
|
||||||
10.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut pio = pio
|
let mut pio = pio
|
||||||
.tx
|
.tx
|
||||||
@ -155,13 +151,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
||||||
|
|
||||||
let pio = ParlIoTxOnly::new(
|
let pio =
|
||||||
ctx.parl_io,
|
ParlIoTxOnly::new(ctx.parl_io, ctx.dma_channel, tx_descriptors, 10.MHz()).unwrap();
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
|
||||||
tx_descriptors,
|
|
||||||
10.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut pio = pio
|
let mut pio = pio
|
||||||
.tx
|
.tx
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#[cfg(esp32c6)]
|
#[cfg(esp32c6)]
|
||||||
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
use esp_hal::parl_io::{TxPinConfigWithValidPin, TxSixteenBits};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{ChannelCreator, Dma, DmaPriority},
|
dma::{Channel, Dma, DmaChannel0},
|
||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{InputSignal, OutputSignal},
|
interconnect::{InputSignal, OutputSignal},
|
||||||
NoPin,
|
NoPin,
|
||||||
@ -29,12 +29,13 @@ use esp_hal::{
|
|||||||
},
|
},
|
||||||
peripherals::PARL_IO,
|
peripherals::PARL_IO,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
Async,
|
||||||
};
|
};
|
||||||
use hil_test as _;
|
use hil_test as _;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
parl_io: PARL_IO,
|
parl_io: PARL_IO,
|
||||||
dma_channel: ChannelCreator<0>,
|
dma_channel: Channel<'static, Async, DmaChannel0>,
|
||||||
clock: OutputSignal,
|
clock: OutputSignal,
|
||||||
valid: OutputSignal,
|
valid: OutputSignal,
|
||||||
clock_loopback: InputSignal,
|
clock_loopback: InputSignal,
|
||||||
@ -60,7 +61,7 @@ mod tests {
|
|||||||
let pcnt = Pcnt::new(peripherals.PCNT);
|
let pcnt = Pcnt::new(peripherals.PCNT);
|
||||||
let pcnt_unit = pcnt.unit0;
|
let pcnt_unit = pcnt.unit0;
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let dma_channel = dma.channel0;
|
let dma_channel = dma.channel0.into_async();
|
||||||
|
|
||||||
let parl_io = peripherals.PARL_IO;
|
let parl_io = peripherals.PARL_IO;
|
||||||
|
|
||||||
@ -90,15 +91,8 @@ mod tests {
|
|||||||
let mut pins = TxPinConfigIncludingValidPin::new(pins);
|
let mut pins = TxPinConfigIncludingValidPin::new(pins);
|
||||||
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
||||||
|
|
||||||
let pio = ParlIoTxOnly::new(
|
let pio =
|
||||||
ctx.parl_io,
|
ParlIoTxOnly::new(ctx.parl_io, ctx.dma_channel, tx_descriptors, 10.MHz()).unwrap();
|
||||||
ctx.dma_channel
|
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.into_async(),
|
|
||||||
tx_descriptors,
|
|
||||||
10.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut pio = pio
|
let mut pio = pio
|
||||||
.tx
|
.tx
|
||||||
@ -158,15 +152,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
let mut clock_pin = ClkOutPin::new(ctx.clock);
|
||||||
|
|
||||||
let pio = ParlIoTxOnly::new(
|
let pio =
|
||||||
ctx.parl_io,
|
ParlIoTxOnly::new(ctx.parl_io, ctx.dma_channel, tx_descriptors, 10.MHz()).unwrap();
|
||||||
ctx.dma_channel
|
|
||||||
.configure(false, DmaPriority::Priority0)
|
|
||||||
.into_async(),
|
|
||||||
tx_descriptors,
|
|
||||||
10.MHz(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut pio = pio
|
let mut pio = pio
|
||||||
.tx
|
.tx
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
#[cfg(pcnt)]
|
#[cfg(pcnt)]
|
||||||
use esp_hal::pcnt::{channel::EdgeMode, unit::Unit, Pcnt};
|
use esp_hal::pcnt::{channel::EdgeMode, unit::Unit, Pcnt};
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Channel, Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Channel, Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{AnyPin, Input, Level, Output, Pull},
|
gpio::{AnyPin, Input, Level, Output, Pull},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -202,7 +202,6 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dma_channel = dma_channel.configure(false, DmaPriority::Priority0);
|
|
||||||
let spi = Spi::new_with_config(
|
let spi = Spi::new_with_config(
|
||||||
peripherals.SPI2,
|
peripherals.SPI2,
|
||||||
Config {
|
Config {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ use embedded_hal::spi::SpiBus;
|
|||||||
#[cfg(pcnt)]
|
#[cfg(pcnt)]
|
||||||
use embedded_hal_async::spi::SpiBus as SpiBusAsync;
|
use embedded_hal_async::spi::SpiBus as SpiBusAsync;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaDescriptor, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Channel, Dma, DmaDescriptor, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Level, NoPin},
|
gpio::{Level, NoPin},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
@ -29,15 +29,15 @@ use hil_test as _;
|
|||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(esp32, esp32s2))] {
|
if #[cfg(any(esp32, esp32s2))] {
|
||||||
type DmaChannelCreator = esp_hal::dma::Spi2DmaChannelCreator;
|
type DmaChannel = esp_hal::dma::Spi2DmaChannel;
|
||||||
} else {
|
} else {
|
||||||
type DmaChannelCreator = esp_hal::dma::ChannelCreator<0>;
|
type DmaChannel = esp_hal::dma::DmaChannel0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: Spi<'static, Blocking>,
|
spi: Spi<'static, Blocking>,
|
||||||
dma_channel: DmaChannelCreator,
|
dma_channel: Channel<'static, Blocking, DmaChannel>,
|
||||||
// Reuse the really large buffer so we don't run out of DRAM with many tests
|
// Reuse the really large buffer so we don't run out of DRAM with many tests
|
||||||
rx_buffer: &'static mut [u8],
|
rx_buffer: &'static mut [u8],
|
||||||
rx_descriptors: &'static mut [DmaDescriptor],
|
rx_descriptors: &'static mut [DmaDescriptor],
|
||||||
@ -204,9 +204,7 @@ mod tests {
|
|||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
|
|
||||||
let unit = ctx.pcnt_unit;
|
let unit = ctx.pcnt_unit;
|
||||||
let mut spi = ctx
|
let mut spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||||
unit.channel0
|
unit.channel0
|
||||||
@ -237,9 +235,7 @@ mod tests {
|
|||||||
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let mut dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
|
|
||||||
let unit = ctx.pcnt_unit;
|
let unit = ctx.pcnt_unit;
|
||||||
let mut spi = ctx
|
let mut spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||||
unit.channel0
|
unit.channel0
|
||||||
@ -274,9 +270,7 @@ mod tests {
|
|||||||
*v = (i % 255) as u8;
|
*v = (i % 255) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut spi = ctx
|
let mut spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
dma_tx_buf.as_mut_slice()[0] = i as u8;
|
dma_tx_buf.as_mut_slice()[0] = i as u8;
|
||||||
@ -304,9 +298,7 @@ mod tests {
|
|||||||
|
|
||||||
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
dma_tx_buf.fill(&[0xde, 0xad, 0xbe, 0xef]);
|
||||||
|
|
||||||
let spi = ctx
|
let spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
let transfer = spi
|
let transfer = spi
|
||||||
.transfer(dma_rx_buf, dma_tx_buf)
|
.transfer(dma_rx_buf, dma_tx_buf)
|
||||||
.map_err(|e| e.0)
|
.map_err(|e| e.0)
|
||||||
@ -335,7 +327,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut spi = ctx
|
let mut spi = ctx
|
||||||
.spi
|
.spi
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
.with_dma(ctx.dma_channel)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf);
|
.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||||
|
|
||||||
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
||||||
@ -355,7 +347,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut spi = ctx
|
let mut spi = ctx
|
||||||
.spi
|
.spi
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
.with_dma(ctx.dma_channel)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf);
|
.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||||
|
|
||||||
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
let tx_buf = [0xde, 0xad, 0xbe, 0xef];
|
||||||
@ -377,7 +369,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut spi = ctx
|
let mut spi = ctx
|
||||||
.spi
|
.spi
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
.with_dma(ctx.dma_channel)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf);
|
.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||||
|
|
||||||
let tx_buf = core::array::from_fn(|i| i as _);
|
let tx_buf = core::array::from_fn(|i| i as _);
|
||||||
@ -398,7 +390,7 @@ mod tests {
|
|||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let mut spi = ctx
|
let mut spi = ctx
|
||||||
.spi
|
.spi
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
.with_dma(ctx.dma_channel)
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf)
|
.with_buffers(dma_rx_buf, dma_tx_buf)
|
||||||
.into_async();
|
.into_async();
|
||||||
|
|
||||||
@ -432,9 +424,9 @@ mod tests {
|
|||||||
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
|
||||||
let mut spi = ctx
|
let mut spi = ctx
|
||||||
.spi
|
.spi
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
.into_async()
|
||||||
.with_buffers(dma_rx_buf, dma_tx_buf)
|
.with_dma(ctx.dma_channel)
|
||||||
.into_async();
|
.with_buffers(dma_rx_buf, dma_tx_buf);
|
||||||
|
|
||||||
ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source);
|
ctx.pcnt_unit.channel0.set_edge_signal(ctx.pcnt_source);
|
||||||
ctx.pcnt_unit
|
ctx.pcnt_unit
|
||||||
@ -465,7 +457,7 @@ mod tests {
|
|||||||
.spi
|
.spi
|
||||||
.with_mosi(NoPin)
|
.with_mosi(NoPin)
|
||||||
.with_miso(Level::High)
|
.with_miso(Level::High)
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(ctx.dma_channel);
|
||||||
|
|
||||||
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4);
|
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4);
|
||||||
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
let mut dma_rx_buf = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
|
||||||
@ -507,9 +499,7 @@ mod tests {
|
|||||||
let dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
||||||
let dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
||||||
|
|
||||||
let spi = ctx
|
let spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
let mut transfer = spi
|
let mut transfer = spi
|
||||||
.transfer(dma_rx_buf, dma_tx_buf)
|
.transfer(dma_rx_buf, dma_tx_buf)
|
||||||
@ -535,9 +525,7 @@ mod tests {
|
|||||||
let mut dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
let mut dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
||||||
let mut dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
let mut dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
||||||
|
|
||||||
let mut spi = ctx
|
let mut spi = ctx.spi.with_dma(ctx.dma_channel);
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0));
|
|
||||||
|
|
||||||
let mut transfer = spi
|
let mut transfer = spi
|
||||||
.transfer(dma_rx_buf, dma_tx_buf)
|
.transfer(dma_rx_buf, dma_tx_buf)
|
||||||
@ -573,10 +561,7 @@ mod tests {
|
|||||||
let dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
let dma_rx_buf = DmaRxBuf::new(ctx.rx_descriptors, ctx.rx_buffer).unwrap();
|
||||||
let dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
let dma_tx_buf = DmaTxBuf::new(ctx.tx_descriptors, ctx.tx_buffer).unwrap();
|
||||||
|
|
||||||
let spi = ctx
|
let spi = ctx.spi.with_dma(ctx.dma_channel).into_async();
|
||||||
.spi
|
|
||||||
.with_dma(ctx.dma_channel.configure(false, DmaPriority::Priority0))
|
|
||||||
.into_async();
|
|
||||||
|
|
||||||
let mut transfer = spi
|
let mut transfer = spi
|
||||||
.transfer(dma_rx_buf, dma_tx_buf)
|
.transfer(dma_rx_buf, dma_tx_buf)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Level, Output},
|
gpio::{Level, Output},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -58,7 +58,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_miso(miso)
|
.with_miso(miso)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
Context { spi, miso_mirror }
|
Context { spi, miso_mirror }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::interconnect::InputSignal,
|
gpio::interconnect::InputSignal,
|
||||||
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
pcnt::{channel::EdgeMode, unit::Unit, Pcnt},
|
||||||
@ -61,7 +61,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
spi,
|
spi,
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
use defmt::error;
|
use defmt::error;
|
||||||
use esp_alloc as _;
|
use esp_alloc as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaBufBlkSize, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaBufBlkSize, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
dma_descriptors_chunk_size,
|
dma_descriptors_chunk_size,
|
||||||
gpio::interconnect::InputSignal,
|
gpio::interconnect::InputSignal,
|
||||||
@ -73,7 +73,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.with_sck(sclk)
|
.with_sck(sclk)
|
||||||
.with_mosi(mosi)
|
.with_mosi(mosi)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
spi,
|
spi,
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::{Channel, Dma},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
gpio::{Input, Level, Output, Pull},
|
gpio::{Input, Level, Output, Pull},
|
||||||
peripheral::Peripheral,
|
peripheral::Peripheral,
|
||||||
@ -20,15 +20,15 @@ use hil_test as _;
|
|||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(esp32, esp32s2))] {
|
if #[cfg(any(esp32, esp32s2))] {
|
||||||
type DmaChannelCreator = esp_hal::dma::Spi2DmaChannelCreator;
|
type DmaChannel = esp_hal::dma::Spi2DmaChannel;
|
||||||
} else {
|
} else {
|
||||||
type DmaChannelCreator = esp_hal::dma::ChannelCreator<0>;
|
type DmaChannel = esp_hal::dma::DmaChannel0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
spi: Spi<'static, Blocking>,
|
spi: Spi<'static, Blocking>,
|
||||||
dma_channel: DmaChannelCreator,
|
dma_channel: Channel<'static, Blocking, DmaChannel>,
|
||||||
bitbang_spi: BitbangSpi,
|
bitbang_spi: BitbangSpi,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,11 +143,9 @@ mod tests {
|
|||||||
fn test_basic(mut ctx: Context) {
|
fn test_basic(mut ctx: Context) {
|
||||||
const DMA_SIZE: usize = 32;
|
const DMA_SIZE: usize = 32;
|
||||||
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(DMA_SIZE);
|
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(DMA_SIZE);
|
||||||
let mut spi = ctx.spi.with_dma(
|
let mut spi = ctx
|
||||||
ctx.dma_channel.configure(false, DmaPriority::Priority0),
|
.spi
|
||||||
rx_descriptors,
|
.with_dma(ctx.dma_channel, rx_descriptors, tx_descriptors);
|
||||||
tx_descriptors,
|
|
||||||
);
|
|
||||||
let slave_send = tx_buffer;
|
let slave_send = tx_buffer;
|
||||||
let slave_receive = rx_buffer;
|
let slave_receive = rx_buffer;
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::master::{DataFormat, I2s, Standard},
|
i2s::master::{DataFormat, I2s, Standard},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -71,7 +71,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
44100u32.Hz(),
|
44100u32.Hz(),
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
i2s::master::{DataFormat, I2s, Standard},
|
i2s::master::{DataFormat, I2s, Standard},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -63,7 +63,7 @@ fn main() -> ! {
|
|||||||
Standard::Philips,
|
Standard::Philips,
|
||||||
DataFormat::Data16Channel16,
|
DataFormat::Data16Channel16,
|
||||||
44100.Hz(),
|
44100.Hz(),
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
dma_channel,
|
||||||
rx_descriptors,
|
rx_descriptors,
|
||||||
tx_descriptors,
|
tx_descriptors,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority},
|
dma::Dma,
|
||||||
dma_rx_stream_buffer,
|
dma_rx_stream_buffer,
|
||||||
i2c::{
|
i2c::{
|
||||||
self,
|
self,
|
||||||
@ -48,12 +48,9 @@ fn main() -> ! {
|
|||||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let channel = dma.channel0;
|
|
||||||
|
|
||||||
let dma_rx_buf = dma_rx_stream_buffer!(20 * 1000, 1000);
|
let dma_rx_buf = dma_rx_stream_buffer!(20 * 1000, 1000);
|
||||||
|
|
||||||
let channel = channel.configure(false, DmaPriority::Priority0);
|
|
||||||
|
|
||||||
let cam_siod = peripherals.GPIO4;
|
let cam_siod = peripherals.GPIO4;
|
||||||
let cam_sioc = peripherals.GPIO5;
|
let cam_sioc = peripherals.GPIO5;
|
||||||
let cam_xclk = peripherals.GPIO15;
|
let cam_xclk = peripherals.GPIO15;
|
||||||
@ -72,7 +69,7 @@ fn main() -> ! {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
let camera = Camera::new(lcd_cam.cam, channel.rx, cam_data_pins, 20u32.MHz())
|
let camera = Camera::new(lcd_cam.cam, dma.channel0.rx, cam_data_pins, 20u32.MHz())
|
||||||
.with_master_clock(cam_xclk)
|
.with_master_clock(cam_xclk)
|
||||||
.with_pixel_clock(cam_pclk)
|
.with_pixel_clock(cam_pclk)
|
||||||
.with_ctrl_pins(cam_vsync, cam_href);
|
.with_ctrl_pins(cam_vsync, cam_href);
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, DmaTxBuf},
|
dma::{Dma, DmaTxBuf},
|
||||||
dma_tx_buffer,
|
dma_tx_buffer,
|
||||||
gpio::{Input, Level, Output, Pull},
|
gpio::{Input, Level, Output, Pull},
|
||||||
lcd_cam::{
|
lcd_cam::{
|
||||||
@ -48,12 +48,9 @@ fn main() -> ! {
|
|||||||
let lcd_te = peripherals.GPIO48; // Frame sync
|
let lcd_te = peripherals.GPIO48; // Frame sync
|
||||||
|
|
||||||
let dma = Dma::new(peripherals.DMA);
|
let dma = Dma::new(peripherals.DMA);
|
||||||
let channel = dma.channel0;
|
|
||||||
|
|
||||||
let dma_tx_buf = dma_tx_buffer!(4000).unwrap();
|
let dma_tx_buf = dma_tx_buffer!(4000).unwrap();
|
||||||
|
|
||||||
let channel = channel.configure(false, DmaPriority::Priority0);
|
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
let mut backlight = Output::new(lcd_backlight, Level::Low);
|
let mut backlight = Output::new(lcd_backlight, Level::Low);
|
||||||
@ -74,7 +71,7 @@ fn main() -> ! {
|
|||||||
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
|
||||||
let i8080 = I8080::new(
|
let i8080 = I8080::new(
|
||||||
lcd_cam.lcd,
|
lcd_cam.lcd,
|
||||||
channel.tx,
|
dma.channel0.tx,
|
||||||
tx_pins,
|
tx_pins,
|
||||||
20.MHz(),
|
20.MHz(),
|
||||||
Config::default(),
|
Config::default(),
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
use esp_backtrace as _;
|
use esp_backtrace as _;
|
||||||
use esp_hal::{
|
use esp_hal::{
|
||||||
delay::Delay,
|
delay::Delay,
|
||||||
dma::{Dma, DmaPriority, DmaRxBuf, DmaTxBuf},
|
dma::{Dma, DmaRxBuf, DmaTxBuf},
|
||||||
dma_buffers,
|
dma_buffers,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
spi::{
|
spi::{
|
||||||
@ -91,7 +91,7 @@ fn main() -> ! {
|
|||||||
.with_sio2(sio2)
|
.with_sio2(sio2)
|
||||||
.with_sio3(sio3)
|
.with_sio3(sio3)
|
||||||
.with_cs(cs)
|
.with_cs(cs)
|
||||||
.with_dma(dma_channel.configure(false, DmaPriority::Priority0));
|
.with_dma(dma_channel);
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user