mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-01 14:20:44 +00:00
Slight general cleanup, enable dma-macros test, allow using virtual mem2mem channel on c2 (#2200)
* Cfg features, not devices * Remove InterruptBinder * Clean up allow(declare_interior_mutable_const) * Small embassy cleanup * Enable dma-macros for 32 and S2 * Use MEM2MEM1 on C2 * Remove esp32-specific code from test
This commit is contained in:
parent
3d0a1998fa
commit
d4e463b3ff
@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- MSRV bump to 1.79 (#2156)
|
||||
|
||||
### Fixed
|
||||
|
||||
### Removed
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "esp-hal-embassy"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
rust-version = "1.79.0"
|
||||
description = "Embassy support for esp-hal"
|
||||
repository = "https://github.com/esp-rs/esp-hal"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
@ -36,11 +36,8 @@ pub(super) struct EmbassyTimer {
|
||||
alarms: Mutex<[AlarmState; MAX_SUPPORTED_ALARM_COUNT]>,
|
||||
}
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const ALARM_STATE_NONE: AlarmState = AlarmState::new();
|
||||
|
||||
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
|
||||
alarms: Mutex::new([ALARM_STATE_NONE; MAX_SUPPORTED_ALARM_COUNT]),
|
||||
alarms: Mutex::new([const { AlarmState::new() }; MAX_SUPPORTED_ALARM_COUNT]),
|
||||
});
|
||||
|
||||
impl EmbassyTimer {
|
||||
@ -99,18 +96,13 @@ impl EmbassyTimer {
|
||||
fn on_interrupt(&self, id: usize) {
|
||||
let cb = critical_section::with(|cs| {
|
||||
let mut timers = TIMERS.borrow_ref_mut(cs);
|
||||
let timers = timers.as_mut().expect("Time driver not initialized");
|
||||
let timers = unwrap!(timers.as_mut(), "Time driver not initialized");
|
||||
let timer = &mut timers[id];
|
||||
|
||||
timer.clear_interrupt();
|
||||
|
||||
let alarm = &self.alarms.borrow(cs)[id];
|
||||
|
||||
if let Some((f, ctx)) = alarm.callback.get() {
|
||||
Some((f, ctx))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
alarm.callback.get()
|
||||
});
|
||||
|
||||
if let Some((f, ctx)) = cb {
|
||||
@ -123,7 +115,7 @@ impl EmbassyTimer {
|
||||
let ts = timestamp.micros();
|
||||
// if the TS is already in the past make the timer fire immediately
|
||||
let timeout = if ts > now { ts - now } else { 0.micros() };
|
||||
timer.schedule(timeout).unwrap();
|
||||
unwrap!(timer.schedule(timeout));
|
||||
timer.enable_interrupt(true);
|
||||
}
|
||||
}
|
||||
@ -171,7 +163,7 @@ impl Driver for EmbassyTimer {
|
||||
// soon as possible, but not synchronously.)
|
||||
critical_section::with(|cs| {
|
||||
let mut timers = TIMERS.borrow_ref_mut(cs);
|
||||
let timers = timers.as_mut().expect("Time driver not initialized");
|
||||
let timers = unwrap!(timers.as_mut(), "Time driver not initialized");
|
||||
let timer = &mut timers[alarm.id() as usize];
|
||||
|
||||
Self::arm(timer, timestamp);
|
||||
|
@ -12,10 +12,6 @@
|
||||
//! GDMA peripheral can be initializes using the `new` function, which requires
|
||||
//! a DMA peripheral instance and a clock control reference.
|
||||
//!
|
||||
//! ## Usage
|
||||
//! This module implements DMA channels, such as `channel0`, `channel1` and so
|
||||
//! on. Each channel struct implements the `ChannelTypes` trait, which provides
|
||||
//! associated types for peripheral configuration.
|
||||
//! <em>PS: Note that the number of DMA channels is chip-specific.</em>
|
||||
|
||||
use crate::{
|
||||
@ -29,12 +25,6 @@ pub struct Channel<const N: u8> {}
|
||||
|
||||
impl<const N: u8> crate::private::Sealed for Channel<N> {}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[non_exhaustive]
|
||||
pub struct ChannelInterruptBinder<const N: u8> {}
|
||||
|
||||
impl<const N: u8> crate::private::Sealed for ChannelInterruptBinder<N> {}
|
||||
|
||||
impl<const N: u8> Channel<N> {
|
||||
#[inline(always)]
|
||||
fn ch() -> &'static crate::peripherals::dma::ch::CH {
|
||||
@ -102,10 +92,8 @@ impl<const N: u8> RegisterAccess for Channel<N> {
|
||||
|
||||
fn set_out_burstmode(burst_mode: bool) {
|
||||
Self::ch().out_conf0().modify(|_, w| {
|
||||
w.out_data_burst_en()
|
||||
.bit(burst_mode)
|
||||
.outdscr_burst_en()
|
||||
.bit(burst_mode)
|
||||
w.out_data_burst_en().bit(burst_mode);
|
||||
w.outdscr_burst_en().bit(burst_mode)
|
||||
});
|
||||
}
|
||||
|
||||
@ -222,10 +210,8 @@ impl<const N: u8> RegisterAccess for Channel<N> {
|
||||
|
||||
fn set_in_burstmode(burst_mode: bool) {
|
||||
Self::ch().in_conf0().modify(|_, w| {
|
||||
w.in_data_burst_en()
|
||||
.bit(burst_mode)
|
||||
.indscr_burst_en()
|
||||
.bit(burst_mode)
|
||||
w.in_data_burst_en().bit(burst_mode);
|
||||
w.indscr_burst_en().bit(burst_mode)
|
||||
});
|
||||
}
|
||||
|
||||
@ -422,12 +408,8 @@ pub struct ChannelTxImpl<const N: u8> {}
|
||||
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const INIT: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
static TX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [INIT; CHANNEL_COUNT];
|
||||
|
||||
static RX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [INIT; CHANNEL_COUNT];
|
||||
static TX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
|
||||
static RX_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [const { AtomicWaker::new() }; CHANNEL_COUNT];
|
||||
|
||||
impl<const N: u8> crate::private::Sealed for ChannelTxImpl<N> {}
|
||||
|
||||
@ -461,10 +443,13 @@ impl<const N: u8> PeripheralMarker for SuitablePeripheral<N> {}
|
||||
// with GDMA every channel can be used for any peripheral
|
||||
impl<const N: u8> SpiPeripheral for SuitablePeripheral<N> {}
|
||||
impl<const N: u8> Spi2Peripheral for SuitablePeripheral<N> {}
|
||||
#[cfg(esp32s3)]
|
||||
#[cfg(spi3)]
|
||||
impl<const N: u8> Spi3Peripheral for SuitablePeripheral<N> {}
|
||||
#[cfg(any(i2s0, i2s1))]
|
||||
impl<const N: u8> I2sPeripheral for SuitablePeripheral<N> {}
|
||||
#[cfg(i2s0)]
|
||||
impl<const N: u8> I2s0Peripheral for SuitablePeripheral<N> {}
|
||||
#[cfg(i2s1)]
|
||||
impl<const N: u8> I2s1Peripheral for SuitablePeripheral<N> {}
|
||||
#[cfg(parl_io)]
|
||||
impl<const N: u8> ParlIoPeripheral for SuitablePeripheral<N> {}
|
||||
@ -476,22 +461,7 @@ impl<const N: u8> LcdCamPeripheral for SuitablePeripheral<N> {}
|
||||
macro_rules! impl_channel {
|
||||
($num: literal, $async_handler: path, $($interrupt: ident),* ) => {
|
||||
paste::paste! {
|
||||
#[doc(hidden)]
|
||||
pub type [<Channel $num>] = Channel<$num>;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub type [<Channel $num TxImpl>] = ChannelTxImpl<$num>;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub type [<Channel $num RxImpl>] = ChannelRxImpl<$num>;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub type [<ChannelCreator $num>] = ChannelCreator<$num>;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub type [<Channel $num InterruptBinder>] = ChannelInterruptBinder<$num>;
|
||||
|
||||
impl InterruptBinder for ChannelInterruptBinder<$num> {
|
||||
impl ChannelTypes for Channel<$num> {
|
||||
fn set_isr(handler: $crate::interrupt::InterruptHandler) {
|
||||
let mut dma = unsafe { crate::peripherals::DMA::steal() };
|
||||
$(
|
||||
@ -501,10 +471,6 @@ macro_rules! impl_channel {
|
||||
}
|
||||
}
|
||||
|
||||
impl ChannelTypes for Channel<$num> {
|
||||
type Binder = ChannelInterruptBinder<$num>;
|
||||
}
|
||||
|
||||
/// A description of a GDMA channel
|
||||
#[non_exhaustive]
|
||||
pub struct [<DmaChannel $num>] {}
|
||||
@ -556,7 +522,7 @@ macro_rules! impl_channel {
|
||||
let mut rx_impl = ChannelRxImpl {};
|
||||
rx_impl.init(burst_mode, priority);
|
||||
|
||||
<Channel<$num> as ChannelTypes>::Binder::set_isr($async_handler);
|
||||
<Channel<$num> as ChannelTypes>::set_isr($async_handler);
|
||||
|
||||
crate::dma::Channel {
|
||||
tx: ChannelTx::new(tx_impl, burst_mode),
|
||||
@ -590,7 +556,7 @@ cfg_if::cfg_if! {
|
||||
impl_channel!(2, super::asynch::interrupt::interrupt_handler_ch2, DMA_IN_CH2, DMA_OUT_CH2);
|
||||
impl_channel!(3, super::asynch::interrupt::interrupt_handler_ch3, DMA_IN_CH3, DMA_OUT_CH3);
|
||||
impl_channel!(4, super::asynch::interrupt::interrupt_handler_ch4, DMA_IN_CH4, DMA_OUT_CH4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GDMA Peripheral
|
||||
@ -725,7 +691,7 @@ mod m2m {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must insure that your not using DMA for the same peripheral and
|
||||
/// You must ensure that your not using DMA for the same peripheral and
|
||||
/// that your the only one using the DmaPeripheral.
|
||||
pub unsafe fn new_unsafe(
|
||||
mut channel: Channel<'d, C, MODE>,
|
||||
|
@ -641,7 +641,7 @@ pub enum DmaPeripheral {
|
||||
Spi2 = 0,
|
||||
#[cfg(any(pdma, esp32s3))]
|
||||
Spi3 = 1,
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
#[cfg(any(esp32c2, esp32c6, esp32h2))]
|
||||
Mem2Mem1 = 1,
|
||||
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
Uhci0 = 2,
|
||||
@ -1888,11 +1888,6 @@ pub trait RegisterAccess: crate::private::Sealed {
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait ChannelTypes: crate::private::Sealed {
|
||||
type Binder: InterruptBinder;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait InterruptBinder: crate::private::Sealed {
|
||||
fn set_isr(handler: InterruptHandler);
|
||||
}
|
||||
|
||||
@ -1918,7 +1913,7 @@ where
|
||||
///
|
||||
/// Interrupts are not enabled at the peripheral level here.
|
||||
pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) {
|
||||
<C::Channel as ChannelTypes>::Binder::set_isr(handler);
|
||||
<C::Channel as ChannelTypes>::set_isr(handler);
|
||||
}
|
||||
|
||||
/// Listen for the given interrupts
|
||||
@ -3213,65 +3208,39 @@ pub(crate) mod asynch {
|
||||
pub(crate) mod interrupt {
|
||||
use procmacros::handler;
|
||||
|
||||
use super::*;
|
||||
pub(crate) fn interrupt_handler_ch<const CH: u8>() {
|
||||
use crate::dma::gdma::{Channel, ChannelRxImpl, ChannelTxImpl};
|
||||
|
||||
super::handle_interrupt::<Channel<CH>, ChannelRxImpl<CH>, ChannelTxImpl<CH>>();
|
||||
}
|
||||
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_ch0() {
|
||||
use crate::dma::gdma::{
|
||||
Channel0 as Channel,
|
||||
Channel0RxImpl as ChannelRxImpl,
|
||||
Channel0TxImpl as ChannelTxImpl,
|
||||
};
|
||||
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
interrupt_handler_ch::<0>();
|
||||
}
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_ch1() {
|
||||
use crate::dma::gdma::{
|
||||
Channel1 as Channel,
|
||||
Channel1RxImpl as ChannelRxImpl,
|
||||
Channel1TxImpl as ChannelTxImpl,
|
||||
};
|
||||
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
interrupt_handler_ch::<1>();
|
||||
}
|
||||
|
||||
#[cfg(not(esp32c2))]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_ch2() {
|
||||
use crate::dma::gdma::{
|
||||
Channel2 as Channel,
|
||||
Channel2RxImpl as ChannelRxImpl,
|
||||
Channel2TxImpl as ChannelTxImpl,
|
||||
};
|
||||
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
interrupt_handler_ch::<2>();
|
||||
}
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_ch3() {
|
||||
use crate::dma::gdma::{
|
||||
Channel3 as Channel,
|
||||
Channel3RxImpl as ChannelRxImpl,
|
||||
Channel3TxImpl as ChannelTxImpl,
|
||||
};
|
||||
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
interrupt_handler_ch::<3>();
|
||||
}
|
||||
|
||||
#[cfg(esp32s3)]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_ch4() {
|
||||
use crate::dma::gdma::{
|
||||
Channel4 as Channel,
|
||||
Channel4RxImpl as ChannelRxImpl,
|
||||
Channel4TxImpl as ChannelTxImpl,
|
||||
};
|
||||
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
interrupt_handler_ch::<4>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3292,6 +3261,7 @@ pub(crate) mod asynch {
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
}
|
||||
|
||||
#[cfg(spi3)]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_spi3_dma() {
|
||||
use crate::dma::pdma::{
|
||||
@ -3303,6 +3273,7 @@ pub(crate) mod asynch {
|
||||
handle_interrupt::<Channel, ChannelRxImpl, ChannelTxImpl>();
|
||||
}
|
||||
|
||||
#[cfg(i2s0)]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
pub(crate) fn interrupt_handler_i2s0() {
|
||||
use crate::dma::pdma::{
|
||||
|
@ -20,20 +20,6 @@ use crate::{
|
||||
macro_rules! ImplSpiChannel {
|
||||
($num: literal) => {
|
||||
paste::paste! {
|
||||
#[non_exhaustive]
|
||||
#[doc(hidden)]
|
||||
pub struct [<Channel $num InterruptBinder>] {}
|
||||
|
||||
impl $crate::private::Sealed for [<Channel $num InterruptBinder>] {}
|
||||
|
||||
impl InterruptBinder for [<Channel $num InterruptBinder>] {
|
||||
fn set_isr(handler: $crate::interrupt::InterruptHandler) {
|
||||
let mut spi = unsafe { $crate::peripherals::[< SPI $num >]::steal() };
|
||||
spi.[< bind_spi $num _dma_interrupt>](handler.handler());
|
||||
$crate::interrupt::enable($crate::peripherals::Interrupt::[< SPI $num _DMA >], handler.priority()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = concat!("DMA channel suitable for SPI", $num)]
|
||||
#[non_exhaustive]
|
||||
pub struct [<Spi $num DmaChannel>] {}
|
||||
@ -48,7 +34,11 @@ macro_rules! ImplSpiChannel {
|
||||
impl $crate::private::Sealed for [<Spi $num DmaChannel>] {}
|
||||
|
||||
impl ChannelTypes for [<Spi $num DmaChannel>] {
|
||||
type Binder = [<Channel $num InterruptBinder>];
|
||||
fn set_isr(handler: $crate::interrupt::InterruptHandler) {
|
||||
let mut spi = unsafe { $crate::peripherals::[< SPI $num >]::steal() };
|
||||
spi.[< bind_spi $num _dma_interrupt>](handler.handler());
|
||||
$crate::interrupt::enable($crate::peripherals::Interrupt::[< SPI $num _DMA >], handler.priority()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterAccess for [<Spi $num DmaChannel>] {
|
||||
@ -57,20 +47,9 @@ macro_rules! ImplSpiChannel {
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
let dport = unsafe { &*crate::peripherals::DPORT::PTR };
|
||||
|
||||
match $num {
|
||||
2 => {
|
||||
dport
|
||||
.spi_dma_chan_sel()
|
||||
.modify(|_, w| unsafe { w.spi2_dma_chan_sel().bits(1) });
|
||||
},
|
||||
3 => {
|
||||
dport
|
||||
.spi_dma_chan_sel()
|
||||
.modify(|_, w| unsafe { w.spi3_dma_chan_sel().bits(2) });
|
||||
},
|
||||
_ => panic!("Only SPI2 and SPI3 supported"),
|
||||
}
|
||||
dport
|
||||
.spi_dma_chan_sel()
|
||||
.modify(|_, w| unsafe { w.[< spi $num _dma_chan_sel>]().bits($num - 1) });
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,14 +64,10 @@ macro_rules! ImplSpiChannel {
|
||||
fn clear_out_interrupts() {
|
||||
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
|
||||
spi.dma_int_clr().write(|w| {
|
||||
w.out_done()
|
||||
.clear_bit_by_one()
|
||||
.out_eof()
|
||||
.clear_bit_by_one()
|
||||
.out_total_eof()
|
||||
.clear_bit_by_one()
|
||||
.outlink_dscr_error()
|
||||
.clear_bit_by_one()
|
||||
w.out_done().clear_bit_by_one();
|
||||
w.out_eof().clear_bit_by_one();
|
||||
w.out_total_eof().clear_bit_by_one();
|
||||
w.outlink_dscr_error().clear_bit_by_one()
|
||||
});
|
||||
}
|
||||
|
||||
@ -165,8 +140,7 @@ macro_rules! ImplSpiChannel {
|
||||
fn reset_out_eof_interrupt() {
|
||||
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
|
||||
spi.dma_int_clr().write(|w| {
|
||||
w.out_eof()
|
||||
.clear_bit_by_one()
|
||||
w.out_eof().clear_bit_by_one()
|
||||
});
|
||||
}
|
||||
|
||||
@ -181,14 +155,10 @@ macro_rules! ImplSpiChannel {
|
||||
fn clear_in_interrupts() {
|
||||
let spi = unsafe { &*crate::peripherals::[<SPI $num>]::PTR };
|
||||
spi.dma_int_clr().write(|w| {
|
||||
w.in_done()
|
||||
.clear_bit_by_one()
|
||||
.in_err_eof()
|
||||
.clear_bit_by_one()
|
||||
.in_suc_eof()
|
||||
.clear_bit_by_one()
|
||||
.inlink_dscr_error()
|
||||
.clear_bit_by_one()
|
||||
w.in_done().clear_bit_by_one();
|
||||
w.in_err_eof().clear_bit_by_one();
|
||||
w.in_suc_eof().clear_bit_by_one();
|
||||
w.inlink_dscr_error().clear_bit_by_one()
|
||||
});
|
||||
}
|
||||
|
||||
@ -417,7 +387,7 @@ macro_rules! ImplSpiChannel {
|
||||
let mut rx_impl = [<Spi $num DmaChannelRxImpl>] {};
|
||||
rx_impl.init(burst_mode, priority);
|
||||
|
||||
<[<Spi $num DmaChannel>] as ChannelTypes>::Binder::set_isr(super::asynch::interrupt::[< interrupt_handler_spi $num _dma >]);
|
||||
<[<Spi $num DmaChannel>] as ChannelTypes>::set_isr(super::asynch::interrupt::[< interrupt_handler_spi $num _dma >]);
|
||||
|
||||
Channel {
|
||||
tx: ChannelTx::new(tx_impl, burst_mode),
|
||||
@ -433,20 +403,6 @@ macro_rules! ImplSpiChannel {
|
||||
macro_rules! ImplI2sChannel {
|
||||
($num: literal, $peripheral: literal) => {
|
||||
paste::paste! {
|
||||
#[non_exhaustive]
|
||||
#[doc(hidden)]
|
||||
pub struct [<Channel $num InterruptBinder>] {}
|
||||
|
||||
impl $crate::private::Sealed for [<Channel $num InterruptBinder>] {}
|
||||
|
||||
impl InterruptBinder for [<Channel $num InterruptBinder>] {
|
||||
fn set_isr(handler: $crate::interrupt::InterruptHandler) {
|
||||
let mut i2s = unsafe { $crate::peripherals::[< I2S $num >]::steal() };
|
||||
i2s.[< bind_i2s $num _interrupt>](handler.handler());
|
||||
$crate::interrupt::enable($crate::peripherals::Interrupt::[< I2S $num >], handler.priority()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = concat!("DMA channel suitable for I2S", $num)]
|
||||
pub struct [<I2s $num DmaChannel>] {}
|
||||
|
||||
@ -460,7 +416,11 @@ macro_rules! ImplI2sChannel {
|
||||
}
|
||||
|
||||
impl ChannelTypes for [<I2s $num DmaChannel>] {
|
||||
type Binder = [<Channel $num InterruptBinder>];
|
||||
fn set_isr(handler: $crate::interrupt::InterruptHandler) {
|
||||
let mut i2s = unsafe { $crate::peripherals::[< I2S $num >]::steal() };
|
||||
i2s.[< bind_i2s $num _interrupt>](handler.handler());
|
||||
$crate::interrupt::enable($crate::peripherals::Interrupt::[< I2S $num >], handler.priority()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterAccess for [<I2s $num DmaChannel>] {
|
||||
@ -808,7 +768,7 @@ macro_rules! ImplI2sChannel {
|
||||
let mut rx_impl = [<I2s $num DmaChannelRxImpl>] {};
|
||||
rx_impl.init(burst_mode, priority);
|
||||
|
||||
<[<I2s $num DmaChannel>] as ChannelTypes>::Binder::set_isr(super::asynch::interrupt::[< interrupt_handler_i2s $num >]);
|
||||
<[<I2s $num DmaChannel>] as ChannelTypes>::set_isr(super::asynch::interrupt::[< interrupt_handler_i2s $num >]);
|
||||
|
||||
Channel {
|
||||
tx: ChannelTx::new(tx_impl, burst_mode),
|
||||
@ -854,7 +814,7 @@ impl PeripheralMarker for I2s1DmaSuitablePeripheral {}
|
||||
impl I2sPeripheral for I2s1DmaSuitablePeripheral {}
|
||||
impl I2s1Peripheral for I2s1DmaSuitablePeripheral {}
|
||||
|
||||
#[cfg(esp32)]
|
||||
#[cfg(i2s1)]
|
||||
ImplI2sChannel!(1, "I2S1");
|
||||
|
||||
/// DMA Peripheral
|
||||
@ -885,7 +845,7 @@ impl<'d> Dma<'d> {
|
||||
spi2channel: Spi2DmaChannelCreator {},
|
||||
spi3channel: Spi3DmaChannelCreator {},
|
||||
i2s0channel: I2s0DmaChannelCreator {},
|
||||
#[cfg(esp32)]
|
||||
#[cfg(i2s1)]
|
||||
i2s1channel: I2s1DmaChannelCreator {},
|
||||
}
|
||||
}
|
||||
|
@ -91,12 +91,13 @@ pub mod rtc_io;
|
||||
|
||||
/// Convenience constant for `Option::None` pin
|
||||
|
||||
static USER_INTERRUPT_HANDLER: CFnPtr = CFnPtr::NULL;
|
||||
static USER_INTERRUPT_HANDLER: CFnPtr = CFnPtr::new();
|
||||
|
||||
struct CFnPtr(AtomicPtr<()>);
|
||||
impl CFnPtr {
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
pub const NULL: Self = Self(AtomicPtr::new(core::ptr::null_mut()));
|
||||
pub const fn new() -> Self {
|
||||
Self(AtomicPtr::new(core::ptr::null_mut()))
|
||||
}
|
||||
|
||||
pub fn store(&self, f: extern "C" fn()) {
|
||||
self.0.store(f as *mut (), Ordering::Relaxed);
|
||||
@ -2488,9 +2489,8 @@ mod asynch {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
pub(super) static PIN_WAKERS: [AtomicWaker; NUM_PINS] = [NEW_AW; NUM_PINS];
|
||||
pub(super) static PIN_WAKERS: [AtomicWaker; NUM_PINS] =
|
||||
[const { AtomicWaker::new() }; NUM_PINS];
|
||||
|
||||
impl<'d, P> Flex<'d, P>
|
||||
where
|
||||
|
@ -533,23 +533,14 @@ mod asynch {
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use embedded_hal::i2c::Operation;
|
||||
use procmacros::handler;
|
||||
|
||||
use super::*;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(all(i2c0, i2c1))] {
|
||||
const NUM_I2C: usize = 2;
|
||||
} else if #[cfg(i2c0)] {
|
||||
const NUM_I2C: usize = 1;
|
||||
}
|
||||
}
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const INIT: AtomicWaker = AtomicWaker::new();
|
||||
static WAKERS: [AtomicWaker; NUM_I2C] = [INIT; NUM_I2C];
|
||||
const NUM_I2C: usize = 1 + cfg!(i2c1) as usize;
|
||||
static WAKERS: [AtomicWaker; NUM_I2C] = [const { AtomicWaker::new() }; NUM_I2C];
|
||||
|
||||
#[cfg_attr(esp32, allow(dead_code))]
|
||||
pub(crate) enum Event {
|
||||
|
@ -84,7 +84,7 @@ use core::marker::PhantomData;
|
||||
use enumset::{EnumSet, EnumSetType};
|
||||
use private::*;
|
||||
|
||||
#[cfg(any(esp32, esp32s3))]
|
||||
#[cfg(i2s1)]
|
||||
use crate::dma::I2s1Peripheral;
|
||||
use crate::{
|
||||
dma::{
|
||||
@ -469,7 +469,7 @@ where
|
||||
/// Construct a new I2S peripheral driver instance for the second I2S
|
||||
/// peripheral
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[cfg(any(esp32s3, esp32))]
|
||||
#[cfg(i2s1)]
|
||||
pub fn new_i2s1(
|
||||
i2s: impl Peripheral<P = I> + 'd,
|
||||
standard: Standard,
|
||||
|
@ -188,11 +188,10 @@ mod peripheral_macros {
|
||||
$crate::create_peripheral!($(#[$cfg])? $name <= $from_pac);
|
||||
)*
|
||||
|
||||
|
||||
$crate::impl_dma_eligible!(SPI2,Spi2);
|
||||
#[cfg(any(pdma, esp32s3))]
|
||||
$crate::impl_dma_eligible!(SPI3,Spi3);
|
||||
#[cfg(any(esp32c6, esp32h2))]
|
||||
#[cfg(any(esp32c2, esp32c6, esp32h2))]
|
||||
$crate::impl_dma_eligible!(MEM2MEM1,Mem2Mem1);
|
||||
#[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
$crate::impl_dma_eligible!(UHCI0,Uhci0);
|
||||
|
@ -1124,9 +1124,7 @@ pub mod asynch {
|
||||
#[cfg(not(any(esp32, esp32s3)))]
|
||||
const NUM_CHANNELS: usize = 4;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const INIT: AtomicWaker = AtomicWaker::new();
|
||||
static WAKER: [AtomicWaker; NUM_CHANNELS] = [INIT; NUM_CHANNELS];
|
||||
static WAKER: [AtomicWaker; NUM_CHANNELS] = [const { AtomicWaker::new() }; NUM_CHANNELS];
|
||||
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub(crate) struct RmtTxFuture<T>
|
||||
|
@ -1025,9 +1025,7 @@ mod asynch {
|
||||
|
||||
const NUM_ALARMS: usize = 3;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const INIT: AtomicWaker = AtomicWaker::new();
|
||||
static WAKERS: [AtomicWaker; NUM_ALARMS] = [INIT; NUM_ALARMS];
|
||||
static WAKERS: [AtomicWaker; NUM_ALARMS] = [const { AtomicWaker::new() }; NUM_ALARMS];
|
||||
|
||||
#[must_use = "futures do nothing unless you `.await` or poll them"]
|
||||
pub(crate) struct AlarmFuture<'a, COMP: Comparator, UNIT: Unit> {
|
||||
|
@ -536,9 +536,8 @@ mod asynch {
|
||||
|
||||
const NUM_TOUCH_PINS: usize = 10;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
static TOUCH_WAKERS: [AtomicWaker; NUM_TOUCH_PINS] = [NEW_AW; NUM_TOUCH_PINS];
|
||||
static TOUCH_WAKERS: [AtomicWaker; NUM_TOUCH_PINS] =
|
||||
[const { AtomicWaker::new() }; NUM_TOUCH_PINS];
|
||||
|
||||
// Helper variable to store which pins need handling.
|
||||
static TOUCHED_PINS: AtomicU16 = AtomicU16::new(0);
|
||||
|
@ -1671,9 +1671,8 @@ mod asynch {
|
||||
}
|
||||
|
||||
const NUM_TWAI: usize = 1 + cfg!(twai1) as usize;
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const NEW_STATE: TwaiAsyncState = TwaiAsyncState::new();
|
||||
pub(crate) static TWAI_STATE: [TwaiAsyncState; NUM_TWAI] = [NEW_STATE; NUM_TWAI];
|
||||
pub(crate) static TWAI_STATE: [TwaiAsyncState; NUM_TWAI] =
|
||||
[const { TwaiAsyncState::new() }; NUM_TWAI];
|
||||
|
||||
impl<T> Twai<'_, T, crate::Async>
|
||||
where
|
||||
|
@ -1849,7 +1849,6 @@ where
|
||||
mod asynch {
|
||||
use core::task::Poll;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use enumset::{EnumSet, EnumSetType};
|
||||
use procmacros::handler;
|
||||
@ -1857,20 +1856,10 @@ mod asynch {
|
||||
use super::*;
|
||||
use crate::Async;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(all(uart0, uart1, uart2))] {
|
||||
const NUM_UART: usize = 3;
|
||||
} else if #[cfg(all(uart0, uart1))] {
|
||||
const NUM_UART: usize = 2;
|
||||
} else if #[cfg(uart0)] {
|
||||
const NUM_UART: usize = 1;
|
||||
}
|
||||
}
|
||||
const NUM_UART: usize = 1 + cfg!(uart1) as usize + cfg!(uart2) as usize;
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const INIT: AtomicWaker = AtomicWaker::new();
|
||||
static TX_WAKERS: [AtomicWaker; NUM_UART] = [INIT; NUM_UART];
|
||||
static RX_WAKERS: [AtomicWaker; NUM_UART] = [INIT; NUM_UART];
|
||||
static TX_WAKERS: [AtomicWaker; NUM_UART] = [const { AtomicWaker::new() }; NUM_UART];
|
||||
static RX_WAKERS: [AtomicWaker; NUM_UART] = [const { AtomicWaker::new() }; NUM_UART];
|
||||
|
||||
#[derive(EnumSetType, Debug)]
|
||||
pub(crate) enum TxEvent {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! DMA Mem2Mem Tests
|
||||
//! DMA macro tests
|
||||
|
||||
//% CHIPS: esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
||||
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
@ -1,12 +1,12 @@
|
||||
//! DMA Mem2Mem Tests
|
||||
|
||||
//% CHIPS: esp32s3 esp32c2 esp32c3 esp32c6 esp32h2
|
||||
//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2 esp32s3
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use esp_hal::{
|
||||
dma::{Channel, Dma, DmaChannel0, DmaError, DmaPriority, Mem2Mem},
|
||||
dma::{Channel, Dma, DmaError, DmaPriority, Mem2Mem},
|
||||
dma_buffers,
|
||||
dma_buffers_chunk_size,
|
||||
dma_descriptors,
|
||||
@ -17,13 +17,15 @@ use hil_test as _;
|
||||
const DATA_SIZE: usize = 1024 * 10;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))] {
|
||||
type DmaPeripheralType = esp_hal::peripherals::SPI2;
|
||||
} else {
|
||||
if #[cfg(any(esp32c2, esp32c6, esp32h2))] {
|
||||
type DmaPeripheralType = esp_hal::peripherals::MEM2MEM1;
|
||||
} else {
|
||||
type DmaPeripheralType = esp_hal::peripherals::SPI2;
|
||||
}
|
||||
}
|
||||
|
||||
use esp_hal::dma::DmaChannel0;
|
||||
|
||||
struct Context {
|
||||
channel: Channel<'static, DmaChannel0, Blocking>,
|
||||
dma_peripheral: DmaPeripheralType,
|
||||
@ -41,18 +43,18 @@ mod tests {
|
||||
let peripherals = esp_hal::init(esp_hal::Config::default());
|
||||
|
||||
let dma = Dma::new(peripherals.DMA);
|
||||
let channel = dma.channel0.configure(false, DmaPriority::Priority0);
|
||||
let dma_channel = dma.channel0;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(feature = "esp32c2", feature = "esp32c3", feature = "esp32s3"))] {
|
||||
let dma_peripheral = peripherals.SPI2;
|
||||
} else {
|
||||
if #[cfg(any(esp32c2, esp32c6, esp32h2))] {
|
||||
let dma_peripheral = peripherals.MEM2MEM1;
|
||||
} else {
|
||||
let dma_peripheral = peripherals.SPI2;
|
||||
}
|
||||
}
|
||||
|
||||
Context {
|
||||
channel,
|
||||
channel: dma_channel.configure(false, DmaPriority::Priority0),
|
||||
dma_peripheral,
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,7 @@ use esp_hal::{
|
||||
use hil_test as _;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(any(
|
||||
feature = "esp32",
|
||||
feature = "esp32s2",
|
||||
))] {
|
||||
if #[cfg(any(esp32, esp32s2))] {
|
||||
use esp_hal::dma::Spi2DmaChannel as DmaChannel0;
|
||||
} else {
|
||||
use esp_hal::dma::DmaChannel0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user