Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Slight general cleanup, enable dma-macros test, allow using virtual mem2mem channel on c2 #2200

Merged
merged 7 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions esp-hal-embassy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion esp-hal-embassy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
18 changes: 5 additions & 13 deletions esp-hal-embassy/src/time_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooo fancy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New toys with the 1.79 msrv :)

});

impl EmbassyTimer {
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -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);
Expand Down
62 changes: 14 additions & 48 deletions esp-hal/src/dma/gdma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
});
}

Expand Down Expand Up @@ -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)
});
}

Expand Down Expand Up @@ -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> {}

Expand Down Expand Up @@ -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> {}
Expand All @@ -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() };
$(
Expand All @@ -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>] {}
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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>,
Expand Down
57 changes: 14 additions & 43 deletions esp-hal/src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}

Expand All @@ -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
Expand Down Expand Up @@ -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>();
}
}

Expand All @@ -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::{
Expand All @@ -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::{
Expand Down
Loading