From 36c466c38c0317c26874af5fdb47927bad1503b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Wed, 13 Nov 2024 11:39:45 +0100 Subject: [PATCH 1/4] Deduplicate PDMA channel impl macro --- esp-hal/src/dma/pdma.rs | 175 ++++++++-------------------------------- 1 file changed, 34 insertions(+), 141 deletions(-) diff --git a/esp-hal/src/dma/pdma.rs b/esp-hal/src/dma/pdma.rs index 0847eea7b72..7c0f5e3820a 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -384,114 +384,6 @@ impl InterruptAccess for AnySpiDmaRxChannel { } } -#[doc(hidden)] -pub struct SpiDmaChannel(PhantomData); - -impl crate::private::Sealed for SpiDmaChannel {} - -macro_rules! ImplSpiChannel { - ($num: literal) => { - paste::paste! { - #[doc = concat!("DMA channel suitable for SPI", $num)] - #[non_exhaustive] - pub struct [] {} - - impl $crate::private::Sealed for [] {} - - impl Peripheral for [] { - type P = Self; - - unsafe fn clone_unchecked(&self) -> Self::P { - Self::steal() - } - } - - impl [] { - /// Unsafely constructs a new DMA channel. - /// - /// # Safety - /// - /// The caller must ensure that only a single instance is used. - pub unsafe fn steal() -> Self { - Self {} - } - } - - impl DmaChannel for [] { - type Rx = AnySpiDmaRxChannel; - type Tx = AnySpiDmaTxChannel; - - unsafe fn split_internal(self, _: $crate::private::Internal) -> (Self::Rx, Self::Tx) { - (AnySpiDmaRxChannel(Self {}.into()), AnySpiDmaTxChannel(Self {}.into())) - } - } - - impl DmaChannelExt for [] { - fn rx_interrupts() -> impl InterruptAccess { - AnySpiDmaRxChannel(Self {}.into()) - } - fn tx_interrupts() -> impl InterruptAccess { - AnySpiDmaTxChannel(Self {}.into()) - } - } - - impl PdmaChannel for [] { - type RegisterBlock = SpiRegisterBlock; - - fn register_block(&self) -> &SpiRegisterBlock { - unsafe { &*$crate::peripherals::[]::PTR } - } - fn tx_waker(&self) -> &'static AtomicWaker { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - fn rx_waker(&self) -> &'static AtomicWaker { - static WAKER: AtomicWaker = AtomicWaker::new(); - &WAKER - } - - fn is_compatible_with(&self, peripheral: DmaPeripheral) -> bool { - peripheral == DmaPeripheral::[] - } - - fn peripheral_interrupt(&self) -> Interrupt { - Interrupt::[< SPI $num _DMA >] - } - - fn async_handler(&self) -> InterruptHandler { - super::asynch::interrupt::[< interrupt_handler_spi $num _dma >] - } - fn rx_async_flag(&self) -> &'static AtomicBool { - static FLAG: AtomicBool = AtomicBool::new(false); - &FLAG - } - fn tx_async_flag(&self) -> &'static AtomicBool { - static FLAG: AtomicBool = AtomicBool::new(false); - &FLAG - } - } - - impl DmaChannelConvert for [] { - fn degrade(self) -> AnySpiDmaChannel { - self.into() - } - } - - impl DmaChannelConvert for [] { - fn degrade(self) -> AnySpiDmaRxChannel { - AnySpiDmaRxChannel(Self {}.into()) - } - } - - impl DmaChannelConvert for [] { - fn degrade(self) -> AnySpiDmaTxChannel { - AnySpiDmaTxChannel(Self {}.into()) - } - } - } - }; -} - /// The RX half of an arbitrary I2S DMA channel. pub struct AnyI2sDmaRxChannel(AnyI2sDmaChannel); @@ -857,15 +749,16 @@ impl InterruptAccess for AnyI2sDmaRxChannel { } } -macro_rules! ImplI2sChannel { - ($num: literal) => { +macro_rules! ImplPdmaChannel { + ($peri:ident, $num:literal, $int:ident) => { paste::paste! { - #[doc = concat!("DMA channel suitable for I2S", $num)] - pub struct [] {} + #[doc = concat!("DMA channel suitable for ", stringify!([< $peri:upper >]), $num)] + #[non_exhaustive] + pub struct [<$peri $num DmaChannel>] {} - impl $crate::private::Sealed for [] {} + impl $crate::private::Sealed for [<$peri $num DmaChannel>] {} - impl Peripheral for [] { + impl Peripheral for [<$peri $num DmaChannel>] { type P = Self; unsafe fn clone_unchecked(&self) -> Self::P { @@ -873,7 +766,7 @@ macro_rules! ImplI2sChannel { } } - impl [] { + impl [<$peri $num DmaChannel>] { /// Unsafely constructs a new DMA channel. /// /// # Safety @@ -884,29 +777,29 @@ macro_rules! ImplI2sChannel { } } - impl DmaChannel for [] { - type Rx = AnyI2sDmaRxChannel; - type Tx = AnyI2sDmaTxChannel; + impl DmaChannel for [<$peri $num DmaChannel>] { + type Rx = []; + type Tx = []; unsafe fn split_internal(self, _: $crate::private::Internal) -> (Self::Rx, Self::Tx) { - (AnyI2sDmaRxChannel(Self {}.into()), AnyI2sDmaTxChannel(Self {}.into())) + ([](Self {}.into()), [](Self {}.into())) } } - impl DmaChannelExt for [] { + impl DmaChannelExt for [<$peri $num DmaChannel>] { fn rx_interrupts() -> impl InterruptAccess { - AnyI2sDmaRxChannel(Self {}.into()) + [](Self {}.into()) } fn tx_interrupts() -> impl InterruptAccess { - AnyI2sDmaTxChannel(Self {}.into()) + [](Self {}.into()) } } - impl PdmaChannel for [] { - type RegisterBlock = I2sRegisterBlock; + impl PdmaChannel for [<$peri $num DmaChannel>] { + type RegisterBlock = [<$peri RegisterBlock>]; - fn register_block(&self) -> &I2sRegisterBlock { - unsafe { &*crate::peripherals::[< I2S $num >]::PTR } + fn register_block(&self) -> &Self::RegisterBlock { + unsafe { &*crate::peripherals::[< $peri:upper $num >]::PTR } } fn tx_waker(&self) -> &'static AtomicWaker { static WAKER: AtomicWaker = AtomicWaker::new(); @@ -917,15 +810,15 @@ macro_rules! ImplI2sChannel { &WAKER } fn is_compatible_with(&self, peripheral: DmaPeripheral) -> bool { - peripheral == DmaPeripheral::[] + peripheral == DmaPeripheral::[<$peri $num>] } fn peripheral_interrupt(&self) -> Interrupt { - Interrupt::[< I2S $num >] + Interrupt::$int } fn async_handler(&self) -> InterruptHandler { - super::asynch::interrupt::[< interrupt_handler_i2s $num _dma >] + super::asynch::interrupt::[< interrupt_handler_ $peri:lower $num _dma >] } fn rx_async_flag(&self) -> &'static AtomicBool { static FLAG: AtomicBool = AtomicBool::new(false); @@ -937,33 +830,33 @@ macro_rules! ImplI2sChannel { } } - impl DmaChannelConvert for [] { - fn degrade(self) -> AnyI2sDmaChannel { + impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { + fn degrade(self) -> [] { self.into() } } - impl DmaChannelConvert for [] { - fn degrade(self) -> AnyI2sDmaRxChannel { - AnyI2sDmaRxChannel(Self {}.into()) + impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { + fn degrade(self) -> [] { + [](self.into()) } } - impl DmaChannelConvert for [] { - fn degrade(self) -> AnyI2sDmaTxChannel { - AnyI2sDmaTxChannel(Self {}.into()) + impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { + fn degrade(self) -> [] { + [](self.into()) } } } }; } -ImplSpiChannel!(2); -ImplSpiChannel!(3); +ImplPdmaChannel!(Spi, 2, SPI2_DMA); +ImplPdmaChannel!(Spi, 3, SPI3_DMA); -ImplI2sChannel!(0); +ImplPdmaChannel!(I2s, 0, I2S0); #[cfg(i2s1)] -ImplI2sChannel!(1); +ImplPdmaChannel!(I2s, 1, I2S1); // Specific peripherals use specific channels. Note that this may be overly // restrictive (ESP32 allows configuring 2 SPI DMA channels between 3 different From 7d4d33962da3148fa580c525092526eac89530cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 19 Nov 2024 09:16:07 +0100 Subject: [PATCH 2/4] Explicitly provide AnyDma prefix, regblock and compatible peripherals --- esp-hal/src/dma/pdma.rs | 59 +++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/esp-hal/src/dma/pdma.rs b/esp-hal/src/dma/pdma.rs index 7c0f5e3820a..069c8a7940d 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -750,15 +750,15 @@ impl InterruptAccess for AnyI2sDmaRxChannel { } macro_rules! ImplPdmaChannel { - ($peri:ident, $num:literal, $int:ident) => { + ($peri:ident, $register_block:ident, $instance:ident, $int:ident, [$($compatible:ident),*]) => { paste::paste! { - #[doc = concat!("DMA channel suitable for ", stringify!([< $peri:upper >]), $num)] + #[doc = concat!("DMA channel suitable for ", stringify!([< $instance:upper >]))] #[non_exhaustive] - pub struct [<$peri $num DmaChannel>] {} + pub struct [<$instance DmaChannel>] {} - impl $crate::private::Sealed for [<$peri $num DmaChannel>] {} + impl $crate::private::Sealed for [<$instance DmaChannel>] {} - impl Peripheral for [<$peri $num DmaChannel>] { + impl Peripheral for [<$instance DmaChannel>] { type P = Self; unsafe fn clone_unchecked(&self) -> Self::P { @@ -766,7 +766,7 @@ macro_rules! ImplPdmaChannel { } } - impl [<$peri $num DmaChannel>] { + impl [<$instance DmaChannel>] { /// Unsafely constructs a new DMA channel. /// /// # Safety @@ -777,29 +777,29 @@ macro_rules! ImplPdmaChannel { } } - impl DmaChannel for [<$peri $num DmaChannel>] { - type Rx = []; - type Tx = []; + impl DmaChannel for [<$instance DmaChannel>] { + type Rx = [<$peri DmaRxChannel>]; + type Tx = [<$peri DmaTxChannel>]; unsafe fn split_internal(self, _: $crate::private::Internal) -> (Self::Rx, Self::Tx) { - ([](Self {}.into()), [](Self {}.into())) + ([<$peri DmaRxChannel>](Self {}.into()), [<$peri DmaTxChannel>](Self {}.into())) } } - impl DmaChannelExt for [<$peri $num DmaChannel>] { + impl DmaChannelExt for [<$instance DmaChannel>] { fn rx_interrupts() -> impl InterruptAccess { - [](Self {}.into()) + [<$peri DmaRxChannel>](Self {}.into()) } fn tx_interrupts() -> impl InterruptAccess { - [](Self {}.into()) + [<$peri DmaTxChannel>](Self {}.into()) } } - impl PdmaChannel for [<$peri $num DmaChannel>] { - type RegisterBlock = [<$peri RegisterBlock>]; + impl PdmaChannel for [<$instance DmaChannel>] { + type RegisterBlock = $register_block; fn register_block(&self) -> &Self::RegisterBlock { - unsafe { &*crate::peripherals::[< $peri:upper $num >]::PTR } + unsafe { &*crate::peripherals::[< $instance:upper >]::PTR } } fn tx_waker(&self) -> &'static AtomicWaker { static WAKER: AtomicWaker = AtomicWaker::new(); @@ -810,7 +810,8 @@ macro_rules! ImplPdmaChannel { &WAKER } fn is_compatible_with(&self, peripheral: DmaPeripheral) -> bool { - peripheral == DmaPeripheral::[<$peri $num>] + let compatible_peripherals = [$(DmaPeripheral::$compatible),*]; + compatible_peripherals.contains(&peripheral) } fn peripheral_interrupt(&self) -> Interrupt { @@ -830,33 +831,33 @@ macro_rules! ImplPdmaChannel { } } - impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { - fn degrade(self) -> [] { + impl DmaChannelConvert<[<$peri DmaChannel>]> for [<$instance DmaChannel>] { + fn degrade(self) -> [<$peri DmaChannel>] { self.into() } } - impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { - fn degrade(self) -> [] { - [](self.into()) + impl DmaChannelConvert<[<$peri DmaRxChannel>]> for [<$instance DmaChannel>] { + fn degrade(self) -> [<$peri DmaRxChannel>] { + [<$peri DmaRxChannel>](self.into()) } } - impl DmaChannelConvert<[]> for [<$peri $num DmaChannel>] { - fn degrade(self) -> [] { - [](self.into()) + impl DmaChannelConvert<[<$peri DmaTxChannel>]> for [<$instance DmaChannel>] { + fn degrade(self) -> [<$peri DmaTxChannel>] { + [<$peri DmaTxChannel>](self.into()) } } } }; } -ImplPdmaChannel!(Spi, 2, SPI2_DMA); -ImplPdmaChannel!(Spi, 3, SPI3_DMA); +ImplPdmaChannel!(AnySpi, SpiRegisterBlock, Spi2, SPI2_DMA, [Spi2]); +ImplPdmaChannel!(AnySpi, SpiRegisterBlock, Spi3, SPI3_DMA, [Spi3]); -ImplPdmaChannel!(I2s, 0, I2S0); +ImplPdmaChannel!(AnyI2s, I2sRegisterBlock, I2s0, I2S0, [I2s0]); #[cfg(i2s1)] -ImplPdmaChannel!(I2s, 1, I2S1); +ImplPdmaChannel!(AnyI2s, I2sRegisterBlock, I2s1, I2S1, [I2s1]); // Specific peripherals use specific channels. Note that this may be overly // restrictive (ESP32 allows configuring 2 SPI DMA channels between 3 different From 95241b0bb351419c99b097e2c9a619e9a9986b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 19 Nov 2024 09:29:28 +0100 Subject: [PATCH 3/4] Clean up defining interrupt handlers --- esp-hal/src/dma/gdma.rs | 62 +++++++++++++++++++++++--------- esp-hal/src/dma/mod.rs | 79 ++--------------------------------------- esp-hal/src/dma/pdma.rs | 10 +++++- esp-hal/src/macros.rs | 10 ++++++ 4 files changed, 66 insertions(+), 95 deletions(-) diff --git a/esp-hal/src/dma/gdma.rs b/esp-hal/src/dma/gdma.rs index c271cc17fad..3d7fd7fa395 100644 --- a/esp-hal/src/dma/gdma.rs +++ b/esp-hal/src/dma/gdma.rs @@ -16,6 +16,8 @@ use crate::{ dma::*, + interrupt::Priority, + macros::handler, peripheral::{Peripheral, PeripheralRef}, peripherals::Interrupt, system::{self, PeripheralClockControl}, @@ -564,7 +566,7 @@ impl Channel<'_, M, CH> { } macro_rules! impl_channel { - ($num:literal, $interrupt_in:ident, $async_handler:path $(, $interrupt_out:ident , $async_handler_out:path)? ) => { + ($num:literal, $interrupt_in:ident $(, $interrupt_out:ident)? ) => { paste::paste! { /// A description of a specific GDMA channel #[non_exhaustive] @@ -593,7 +595,25 @@ macro_rules! impl_channel { impl [] { fn handler_in() -> Option { - Some($async_handler) + $crate::if_set! { + $({ + // $interrupt_out is present, meaning we have split handlers + #[handler(priority = Priority::max())] + fn interrupt_handler_in() { + $crate::ignore!($interrupt_out); + super::asynch::handle_in_interrupt::<[< DmaChannel $num >]>(); + } + Some(interrupt_handler_in) + })?, + { + #[handler(priority = Priority::max())] + fn interrupt_handler() { + super::asynch::handle_in_interrupt::<[< DmaChannel $num >]>(); + super::asynch::handle_out_interrupt::<[< DmaChannel $num >]>(); + } + Some(interrupt_handler) + } + } } fn isr_in() -> Option { @@ -601,7 +621,17 @@ macro_rules! impl_channel { } fn handler_out() -> Option { - $crate::if_set! { $(Some($async_handler_out))?, None } + $crate::if_set! { + $({ + #[handler(priority = Priority::max())] + fn interrupt_handler_out() { + $crate::ignore!($interrupt_out); + super::asynch::handle_out_interrupt::<[< DmaChannel $num >]>(); + } + Some(interrupt_handler_out) + })?, + None + } } fn isr_out() -> Option { @@ -653,29 +683,27 @@ macro_rules! impl_channel { }; } -use super::asynch::interrupt as asynch_handler; - cfg_if::cfg_if! { if #[cfg(esp32c2)] { const CHANNEL_COUNT: usize = 1; - impl_channel!(0, DMA_CH0, asynch_handler::interrupt_handler_ch0); + impl_channel!(0, DMA_CH0); } else if #[cfg(esp32c3)] { const CHANNEL_COUNT: usize = 3; - impl_channel!(0, DMA_CH0, asynch_handler::interrupt_handler_ch0); - impl_channel!(1, DMA_CH1, asynch_handler::interrupt_handler_ch1); - impl_channel!(2, DMA_CH2, asynch_handler::interrupt_handler_ch2); + impl_channel!(0, DMA_CH0); + impl_channel!(1, DMA_CH1); + impl_channel!(2, DMA_CH2); } else if #[cfg(any(esp32c6, esp32h2))] { const CHANNEL_COUNT: usize = 3; - impl_channel!(0, DMA_IN_CH0, asynch_handler::interrupt_handler_in_ch0, DMA_OUT_CH0, asynch_handler::interrupt_handler_out_ch0); - impl_channel!(1, DMA_IN_CH1, asynch_handler::interrupt_handler_in_ch1, DMA_OUT_CH1, asynch_handler::interrupt_handler_out_ch1); - impl_channel!(2, DMA_IN_CH2, asynch_handler::interrupt_handler_in_ch2, DMA_OUT_CH2, asynch_handler::interrupt_handler_out_ch2); + impl_channel!(0, DMA_IN_CH0, DMA_OUT_CH0); + impl_channel!(1, DMA_IN_CH1, DMA_OUT_CH1); + impl_channel!(2, DMA_IN_CH2, DMA_OUT_CH2); } else if #[cfg(esp32s3)] { const CHANNEL_COUNT: usize = 5; - impl_channel!(0, DMA_IN_CH0, asynch_handler::interrupt_handler_in_ch0, DMA_OUT_CH0, asynch_handler::interrupt_handler_out_ch0); - impl_channel!(1, DMA_IN_CH1, asynch_handler::interrupt_handler_in_ch1, DMA_OUT_CH1, asynch_handler::interrupt_handler_out_ch1); - impl_channel!(2, DMA_IN_CH2, asynch_handler::interrupt_handler_in_ch2, DMA_OUT_CH2, asynch_handler::interrupt_handler_out_ch2); - impl_channel!(3, DMA_IN_CH3, asynch_handler::interrupt_handler_in_ch3, DMA_OUT_CH3, asynch_handler::interrupt_handler_out_ch3); - impl_channel!(4, DMA_IN_CH4, asynch_handler::interrupt_handler_in_ch4, DMA_OUT_CH4, asynch_handler::interrupt_handler_out_ch4); + impl_channel!(0, DMA_IN_CH0, DMA_OUT_CH0); + impl_channel!(1, DMA_IN_CH1, DMA_OUT_CH1); + impl_channel!(2, DMA_IN_CH2, DMA_OUT_CH2); + impl_channel!(3, DMA_IN_CH3, DMA_OUT_CH3); + impl_channel!(4, DMA_IN_CH4, DMA_OUT_CH4); } } diff --git a/esp-hal/src/dma/mod.rs b/esp-hal/src/dma/mod.rs index b73ffb99a95..cbe9a281317 100644 --- a/esp-hal/src/dma/mod.rs +++ b/esp-hal/src/dma/mod.rs @@ -3032,7 +3032,7 @@ pub(crate) mod asynch { } } - fn handle_in_interrupt() { + pub(super) fn handle_in_interrupt() { let rx = CH::rx_interrupts(); if !rx.is_async() { @@ -3068,7 +3068,7 @@ pub(crate) mod asynch { } } - fn handle_out_interrupt() { + pub(super) fn handle_out_interrupt() { let tx = CH::tx_interrupts(); if !tx.is_async() { @@ -3097,79 +3097,4 @@ pub(crate) mod asynch { tx.waker().wake() } } - - #[cfg(gdma)] - pub(crate) mod interrupt { - use super::*; - use crate::{interrupt::Priority, macros::handler}; - - // Single interrupt handler for IN and OUT - #[cfg(any(esp32c2, esp32c3))] - macro_rules! interrupt_handler { - ($ch:literal) => { - paste::paste! { - #[handler(priority = Priority::max())] - pub(crate) fn []() { - handle_in_interrupt::<[< DmaChannel $ch >]>(); - handle_out_interrupt::<[< DmaChannel $ch >]>(); - } - } - }; - } - - #[cfg(not(any(esp32c2, esp32c3)))] - macro_rules! interrupt_handler { - ($ch:literal) => { - paste::paste! { - #[handler(priority = Priority::max())] - pub(crate) fn []() { - handle_in_interrupt::<[< DmaChannel $ch >]>(); - } - - #[handler(priority = Priority::max())] - pub(crate) fn []() { - handle_out_interrupt::<[< DmaChannel $ch >]>(); - } - } - }; - } - - interrupt_handler!(0); - #[cfg(not(esp32c2))] - interrupt_handler!(1); - #[cfg(not(esp32c2))] - interrupt_handler!(2); - #[cfg(esp32s3)] - interrupt_handler!(3); - #[cfg(esp32s3)] - interrupt_handler!(4); - } - - #[cfg(pdma)] - pub(crate) mod interrupt { - use super::*; - use crate::{interrupt::Priority, macros::handler}; - - // Single interrupt handler for IN and OUT - macro_rules! interrupt_handler { - ($ch:ident) => { - paste::paste! { - #[handler(priority = Priority::max())] - pub(crate) fn []() { - handle_in_interrupt::<[< $ch DmaChannel >]>(); - handle_out_interrupt::<[< $ch DmaChannel >]>(); - } - } - }; - } - - interrupt_handler!(Spi2); - #[cfg(spi3)] - interrupt_handler!(Spi3); - - #[cfg(i2s0)] - interrupt_handler!(I2s0); - #[cfg(i2s1)] - interrupt_handler!(I2s1); - } } diff --git a/esp-hal/src/dma/pdma.rs b/esp-hal/src/dma/pdma.rs index 069c8a7940d..8f763028215 100644 --- a/esp-hal/src/dma/pdma.rs +++ b/esp-hal/src/dma/pdma.rs @@ -16,6 +16,8 @@ use portable_atomic::{AtomicBool, Ordering}; use crate::{ dma::*, + interrupt::Priority, + macros::handler, peripheral::{Peripheral, PeripheralRef}, peripherals::Interrupt, system::{self, PeripheralClockControl}, @@ -819,7 +821,13 @@ macro_rules! ImplPdmaChannel { } fn async_handler(&self) -> InterruptHandler { - super::asynch::interrupt::[< interrupt_handler_ $peri:lower $num _dma >] + #[handler(priority = Priority::max())] + pub(crate) fn interrupt_handler() { + super::asynch::handle_in_interrupt::<[< $instance DmaChannel >]>(); + super::asynch::handle_out_interrupt::<[< $instance DmaChannel >]>(); + } + + interrupt_handler } fn rx_async_flag(&self) -> &'static AtomicBool { static FLAG: AtomicBool = AtomicBool::new(false); diff --git a/esp-hal/src/macros.rs b/esp-hal/src/macros.rs index 777cf0f6a20..b6abd50cfc5 100644 --- a/esp-hal/src/macros.rs +++ b/esp-hal/src/macros.rs @@ -134,3 +134,13 @@ macro_rules! if_set { $set }; } + +/// Macro to ignore tokens. +/// +/// This is useful when we need existence of a metavariable (to expand a +/// repetition), but we don't need to use it. +#[macro_export] +#[doc(hidden)] +macro_rules! ignore { + ($($item:tt)*) => {}; +} From 03f9982bd2e2c7659f3f6445eaf2b8717837fbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Tue, 19 Nov 2024 09:30:36 +0100 Subject: [PATCH 4/4] Clean up ad-hoc ignore macro branches --- esp-hal/src/soc/esp32/gpio.rs | 6 ++---- esp-hal/src/soc/esp32s2/gpio.rs | 2 -- esp-hal/src/soc/esp32s3/gpio.rs | 2 -- esp-hal/src/spi/master.rs | 4 +--- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/esp-hal/src/soc/esp32/gpio.rs b/esp-hal/src/soc/esp32/gpio.rs index 21e85a6f423..78156ff5cb8 100644 --- a/esp-hal/src/soc/esp32/gpio.rs +++ b/esp-hal/src/soc/esp32/gpio.rs @@ -531,8 +531,6 @@ pub enum OutputSignal { } macro_rules! rtcio_analog { - ( @ignore $rue:literal ) => {}; - ( $pin_num:expr, $rtc_pin:expr, $pin_reg:expr, $prefix:pat, $hold:ident $(, $rue:literal)? ) => { @@ -564,7 +562,7 @@ macro_rules! rtcio_analog { $( // FIXME: replace with $(ignore($rue)) once stable - rtcio_analog!(@ignore $rue); + $crate::ignore!($rue); impl $crate::gpio::RtcPinWithResistors for $crate::gpio::GpioPin<$pin_num> { fn rtcio_pullup(&mut self, enable: bool) { paste::paste! { @@ -610,7 +608,7 @@ macro_rules! rtcio_analog { // Disable pull-up and pull-down resistors on the pin, if it has them $( // FIXME: replace with $(ignore($rue)) once stable - rtcio_analog!( @ignore $rue ); + $crate::ignore!($rue); w.[<$prefix rue>]().bit(false); w.[<$prefix rde>]().bit(false); )? diff --git a/esp-hal/src/soc/esp32s2/gpio.rs b/esp-hal/src/soc/esp32s2/gpio.rs index 52c3deee7e9..d4026f8d5b2 100644 --- a/esp-hal/src/soc/esp32s2/gpio.rs +++ b/esp-hal/src/soc/esp32s2/gpio.rs @@ -318,8 +318,6 @@ pub enum OutputSignal { } macro_rules! rtcio_analog { - ( @ignore $rue:literal ) => {}; - ( $pin_num:expr, $pin_reg:expr, $prefix:pat, $hold:ident ) => { diff --git a/esp-hal/src/soc/esp32s3/gpio.rs b/esp-hal/src/soc/esp32s3/gpio.rs index 9ebbc43903d..b3c642fffee 100644 --- a/esp-hal/src/soc/esp32s3/gpio.rs +++ b/esp-hal/src/soc/esp32s3/gpio.rs @@ -395,8 +395,6 @@ pub enum OutputSignal { } macro_rules! rtcio_analog { - ( @ignore $rue:literal ) => {}; - ( $pin_num:expr, $pin_reg:expr, $prefix:pat, $hold:ident ) => { diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 5c4dc8e10a7..a07fac57355 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -3001,8 +3001,6 @@ impl PartialEq for Info { unsafe impl Sync for Info {} macro_rules! spi_instance { - (@ignore $sio2:ident) => {}; - ($num:literal, $sclk:ident, $mosi:ident, $miso:ident, $cs:ident $(, $sio2:ident, $sio3:ident)?) => { paste::paste! { impl Instance for crate::peripherals::[] { @@ -3030,7 +3028,7 @@ macro_rules! spi_instance { $( // If the extra pins are set, implement QspiInstance - spi_instance!(@ignore $sio2); + $crate::ignore!($sio2); impl QspiInstance for crate::peripherals::[] {} )? }