From b11d810d978f8ed2caea635dbbc07821d773963b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Mon, 30 Jun 2025 17:28:42 +0200 Subject: [PATCH] Tweak and make use of the old `bind_X_interrupt` functions (#3689) * Rename bind_interrupt functions * Generate enable/disable functions, remove redundant irq mapping from metadata * Clean up PARL_IO * Refactor SPI master, I2S, Uart * Update USB_DEVICE --- esp-hal/src/i2c/master/mod.rs | 52 +++++++++++++----------- esp-hal/src/i2s/master.rs | 46 +++++++-------------- esp-hal/src/parl_io.rs | 33 +++++---------- esp-hal/src/peripheral.rs | 46 +++++++++++++-------- esp-hal/src/soc/esp32/peripherals.rs | 18 ++++----- esp-hal/src/soc/esp32c2/peripherals.rs | 8 ++-- esp-hal/src/soc/esp32c3/peripherals.rs | 12 +++--- esp-hal/src/soc/esp32c6/peripherals.rs | 14 +++---- esp-hal/src/soc/esp32h2/peripherals.rs | 16 ++++---- esp-hal/src/soc/esp32s2/peripherals.rs | 14 +++---- esp-hal/src/soc/esp32s3/peripherals.rs | 20 ++++----- esp-hal/src/spi/master.rs | 54 +++++++++++++------------ esp-hal/src/uart.rs | 56 ++++++++++++++------------ esp-hal/src/usb_serial_jtag.rs | 17 +++----- esp-metadata/devices/esp32.toml | 4 +- esp-metadata/devices/esp32c2.toml | 2 +- esp-metadata/devices/esp32c3.toml | 2 +- esp-metadata/devices/esp32c6.toml | 2 +- esp-metadata/devices/esp32h2.toml | 4 +- esp-metadata/devices/esp32s2.toml | 4 +- esp-metadata/devices/esp32s3.toml | 4 +- esp-metadata/src/cfg/i2c_master.rs | 6 +-- 22 files changed, 212 insertions(+), 222 deletions(-) diff --git a/esp-hal/src/i2c/master/mod.rs b/esp-hal/src/i2c/master/mod.rs index 946e14c5e..194a0d07d 100644 --- a/esp-hal/src/i2c/master/mod.rs +++ b/esp-hal/src/i2c/master/mod.rs @@ -139,7 +139,6 @@ use crate::{ }, interrupt::InterruptHandler, pac::i2c0::{COMD, RegisterBlock}, - peripherals::Interrupt, private, system::PeripheralGuard, time::{Duration, Instant, Rate}, @@ -745,7 +744,7 @@ impl<'d> I2c<'d, Blocking> { /// `None`) #[instability::unstable] pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.i2c.info().set_interrupt_handler(handler); + self.i2c.set_interrupt_handler(handler); } /// Listen for the given interrupts @@ -778,7 +777,7 @@ impl private::Sealed for I2c<'_, Blocking> {} #[instability::unstable] impl crate::interrupt::InterruptConfigurable for I2c<'_, Blocking> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.i2c.info().set_interrupt_handler(handler); + self.i2c.set_interrupt_handler(handler); } } @@ -916,7 +915,7 @@ impl Drop for I2cFuture<'_> { impl<'d> I2c<'d, Async> { /// Configure the I2C peripheral to operate in blocking mode. pub fn into_blocking(self) -> I2c<'d, Blocking> { - self.i2c.info().disable_interrupts(); + self.i2c.disable_peri_interrupt(); I2c { i2c: self.i2c, @@ -1350,9 +1349,6 @@ pub struct Info { /// Interrupt handler for the asynchronous operations of this I2C instance. pub async_handler: InterruptHandler, - /// Interrupt for this I2C instance. - pub interrupt: Interrupt, - /// SCL output signal. pub scl_output: OutputSignal, @@ -1424,20 +1420,6 @@ impl Info { w }); } - - fn set_interrupt_handler(&self, handler: InterruptHandler) { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, self.interrupt); - } - self.enable_listen(EnumSet::all(), false); - self.clear_interrupts(EnumSet::all()); - unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) }; - unwrap!(crate::interrupt::enable(self.interrupt, handler.priority())); - } - - fn disable_interrupts(&self) { - crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt); - } } impl PartialEq for Info { @@ -3115,7 +3097,7 @@ fn estimate_ack_failed_reason(_register_block: &RegisterBlock) -> AcknowledgeChe } crate::peripherals::for_each_i2c_master!( - ($inst:ident, $peri:ident, $scl:ident, $sda:ident, $interrupt:ident) => { + ($inst:ident, $peri:ident, $scl:ident, $sda:ident) => { impl Instance for crate::peripherals::$inst<'_> { fn parts(&self) -> (&Info, &State) { #[crate::handler] @@ -3131,7 +3113,6 @@ crate::peripherals::for_each_i2c_master!( register_block: crate::peripherals::$inst::ptr(), peripheral: crate::system::Peripheral::$peri, async_handler: irq_handler, - interrupt: Interrupt::$interrupt, scl_output: OutputSignal::$scl, scl_input: InputSignal::$scl, sda_output: OutputSignal::$sda, @@ -3165,3 +3146,28 @@ impl Instance for AnyI2c<'_> { } } } + +impl AnyI2c<'_> { + delegate::delegate! { + to match &self.0 { + #[cfg(i2c_master_i2c0)] + AnyI2cInner::I2c0(i2c) => i2c, + #[cfg(i2c_master_i2c1)] + AnyI2cInner::I2c1(i2c) => i2c, + } { + fn bind_peri_interrupt(&self, handler: unsafe extern "C" fn() -> ()); + fn disable_peri_interrupt(&self); + fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority); + } + } + + fn set_interrupt_handler(&self, handler: InterruptHandler) { + self.disable_peri_interrupt(); + + self.info().enable_listen(EnumSet::all(), false); + self.info().clear_interrupts(EnumSet::all()); + + self.bind_peri_interrupt(handler.handler()); + self.enable_peri_interrupt(handler.priority()); + } +} diff --git a/esp-hal/src/i2s/master.rs b/esp-hal/src/i2s/master.rs index daa5ff8ff..7888a1ac9 100644 --- a/esp-hal/src/i2s/master.rs +++ b/esp-hal/src/i2s/master.rs @@ -693,7 +693,7 @@ mod private { }, i2s::AnyI2sInner, interrupt::InterruptHandler, - peripherals::{I2S0, Interrupt}, + peripherals::I2S0, }; // on ESP32-S3 I2S1 doesn't support all features - use that to avoid using those features // by accident @@ -832,8 +832,6 @@ mod private { #[cfg(any(esp32, esp32s2))] pub trait RegisterAccessPrivate: Signals + RegBlock { - fn set_interrupt_handler(&self, handler: InterruptHandler); - fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { for interrupt in interrupts { @@ -1065,8 +1063,6 @@ mod private { #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] pub trait RegisterAccessPrivate: Signals + RegBlock { - fn set_interrupt_handler(&self, handler: InterruptHandler); - fn enable_listen(&self, interrupts: EnumSet, enable: bool) { self.regs().int_ena().modify(|_, w| { for interrupt in interrupts { @@ -1512,18 +1508,7 @@ mod private { } } - impl RegisterAccessPrivate for I2S0<'_> { - fn set_interrupt_handler(&self, handler: InterruptHandler) { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, Interrupt::I2S0); - } - unsafe { crate::peripherals::I2S0::steal() }.bind_i2s0_interrupt(handler.handler()); - unwrap!(crate::interrupt::enable( - Interrupt::I2S0, - handler.priority() - )); - } - } + impl RegisterAccessPrivate for I2S0<'_> {} impl Signals for crate::peripherals::I2S0<'_> { fn mclk_signal(&self) -> OutputSignal { @@ -1621,18 +1606,7 @@ mod private { } #[cfg(soc_has_i2s1)] - impl RegisterAccessPrivate for I2S1<'_> { - fn set_interrupt_handler(&self, handler: InterruptHandler) { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, Interrupt::I2S1); - } - unsafe { crate::peripherals::I2S1::steal() }.bind_i2s1_interrupt(handler.handler()); - unwrap!(crate::interrupt::enable( - Interrupt::I2S1, - handler.priority() - )); - } - } + impl RegisterAccessPrivate for I2S1<'_> {} #[cfg(soc_has_i2s1)] impl Signals for crate::peripherals::I2S1<'_> { @@ -1705,7 +1679,9 @@ mod private { } } - impl RegisterAccessPrivate for super::AnyI2s<'_> { + impl RegisterAccessPrivate for super::AnyI2s<'_> {} + + impl super::AnyI2s<'_> { delegate::delegate! { to match &self.0 { #[cfg(soc_has_i2s0)] @@ -1713,9 +1689,17 @@ mod private { #[cfg(soc_has_i2s1)] AnyI2sInner::I2s1(i2s) => i2s, } { - fn set_interrupt_handler(&self, handler: InterruptHandler); + fn bind_peri_interrupt(&self, handler: unsafe extern "C" fn() -> ()); + fn disable_peri_interrupt(&self); + fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority); } } + + pub(super) fn set_interrupt_handler(&self, handler: InterruptHandler) { + self.disable_peri_interrupt(); + self.bind_peri_interrupt(handler.handler()); + self.enable_peri_interrupt(handler.priority()); + } } impl Signals for super::AnyI2s<'_> { diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index 24a11e8d4..d006a7aa4 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -987,40 +987,27 @@ where } fn internal_set_interrupt_handler(handler: InterruptHandler) { - let mut peri = unsafe { PARL_IO::steal() }; + let peri = unsafe { PARL_IO::steal() }; #[cfg(esp32c6)] { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, Interrupt::PARL_IO); - } + peri.disable_peri_interrupt(); internal_listen(EnumSet::all(), false); internal_clear_interrupts(EnumSet::all()); - peri.bind_parl_io_interrupt(handler.handler()); + peri.bind_peri_interrupt(handler.handler()); - unwrap!(crate::interrupt::enable( - Interrupt::PARL_IO, - handler.priority() - )); + peri.enable_peri_interrupt(handler.priority()); } #[cfg(esp32h2)] { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, Interrupt::PARL_IO_RX); - crate::interrupt::disable(core, Interrupt::PARL_IO_TX); - } + peri.disable_rx_interrupt(); + peri.disable_tx_interrupt(); internal_listen(EnumSet::all(), false); internal_clear_interrupts(EnumSet::all()); - peri.bind_parl_io_tx_interrupt(handler.handler()); - peri.bind_parl_io_rx_interrupt(handler.handler()); + peri.bind_rx_interrupt(handler.handler()); + peri.bind_tx_interrupt(handler.handler()); - unwrap!(crate::interrupt::enable( - Interrupt::PARL_IO_TX, - handler.priority(), - )); - unwrap!(crate::interrupt::enable( - Interrupt::PARL_IO_RX, - handler.priority(), - )); + peri.enable_rx_interrupt(handler.priority()); + peri.enable_tx_interrupt(handler.priority()); } } diff --git a/esp-hal/src/peripheral.rs b/esp-hal/src/peripheral.rs index bb8d6c7b9..5c3dab680 100644 --- a/esp-hal/src/peripheral.rs +++ b/esp-hal/src/peripheral.rs @@ -16,18 +16,44 @@ macro_rules! peripherals { ( peripherals: [ $( - $name:ident <= $from_pac:tt $(($($interrupt:ident),*))? + $name:ident <= $from_pac:tt $(($($interrupt_name:ident => $interrupt:ident),*))? ),* $(,)? ], unstable_peripherals: [ $( - $unstable_name:ident <= $unstable_from_pac:tt $(($($unstable_interrupt:ident),*))? + $unstable_name:ident <= $unstable_from_pac:tt $(($($unstable_interrupt_name:ident => $unstable_interrupt:ident),*))? ),* $(,)? ], pins: [ $( $pin:literal, )* ] ) => { + macro_rules! generate_interrupt_fns { + ($fn_name:ident, $int_name:ident) => { + paste::paste!{ + /// Binds an interrupt handler to the corresponding interrupt for this peripheral. + #[instability::unstable] + pub fn [](&self, handler: unsafe extern "C" fn() -> ()) { + unsafe { $crate::interrupt::bind_interrupt($crate::peripherals::Interrupt::$int_name, handler); } + } + + /// Disables the interrupt handler + #[instability::unstable] + pub fn [](&self) { + for core in $crate::system::Cpu::other() { + $crate::interrupt::disable(core, $crate::peripherals::Interrupt::$int_name); + } + } + + /// Enables the interrupt handler on the given core + #[instability::unstable] + pub fn [](&self, priority: $crate::interrupt::Priority) { + unwrap!($crate::interrupt::enable($crate::peripherals::Interrupt::$int_name, priority)); + } + } + }; + } + paste::paste! { $( $crate::create_peripheral!($name <= $from_pac); @@ -115,13 +141,7 @@ macro_rules! peripherals { $( impl $name<'_> { $( - paste::paste!{ - /// Binds an interrupt handler to the corresponding interrupt for this peripheral. - #[instability::unstable] - pub fn [](&mut self, handler: unsafe extern "C" fn() -> ()) { - unsafe { $crate::interrupt::bind_interrupt($crate::peripherals::Interrupt::$interrupt, handler); } - } - } + generate_interrupt_fns!($interrupt_name, $interrupt); )* } )* @@ -131,13 +151,7 @@ macro_rules! peripherals { $( impl $unstable_name<'_> { $( - paste::paste!{ - /// Binds an interrupt handler to the corresponding interrupt for this peripheral. - #[instability::unstable] - pub fn [](&mut self, handler: unsafe extern "C" fn() -> ()) { - unsafe { $crate::interrupt::bind_interrupt($crate::peripherals::Interrupt::$unstable_interrupt, handler); } - } - } + generate_interrupt_fns!($unstable_interrupt_name, $unstable_interrupt); )* } )* diff --git a/esp-hal/src/soc/esp32/peripherals.rs b/esp-hal/src/soc/esp32/peripherals.rs index 854cc4dd7..f43da5cc7 100644 --- a/esp-hal/src/soc/esp32/peripherals.rs +++ b/esp-hal/src/soc/esp32/peripherals.rs @@ -19,13 +19,13 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - I2C1 <= I2C1, - SPI2 <= SPI2 (SPI2_DMA, SPI2), - SPI3 <= SPI3 (SPI3_DMA, SPI3), - UART0 <= UART0, - UART1 <= UART1, - UART2 <= UART2, + I2C0 <= I2C0 (peri => I2C_EXT0), + I2C1 <= I2C1 (peri => I2C_EXT1), + SPI2 <= SPI2 (dma => SPI2_DMA, peri => SPI2), + SPI3 <= SPI3 (dma => SPI3_DMA, peri => SPI3), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), + UART2 <= UART2 (peri => UART2), ], unstable_peripherals: [ ADC1 <= virtual, @@ -44,8 +44,8 @@ crate::peripherals! { GPIO <= GPIO, GPIO_SD <= GPIO_SD, HINF <= HINF, - I2S0 <= I2S0 (I2S0), - I2S1 <= I2S1 (I2S1), + I2S0 <= I2S0 (peri => I2S0), + I2S1 <= I2S1 (peri => I2S1), IO_MUX <= IO_MUX, LEDC <= LEDC, LPWR <= RTC_CNTL, diff --git a/esp-hal/src/soc/esp32c2/peripherals.rs b/esp-hal/src/soc/esp32c2/peripherals.rs index 8509a13eb..0c8ba4c94 100644 --- a/esp-hal/src/soc/esp32c2/peripherals.rs +++ b/esp-hal/src/soc/esp32c2/peripherals.rs @@ -19,10 +19,10 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - SPI2 <= SPI2 (SPI2), - UART0 <= UART0, - UART1 <= UART1, + I2C0 <= I2C0 (peri => I2C_EXT0), + SPI2 <= SPI2 (peri => SPI2), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), ], unstable_peripherals: [ ADC1 <= virtual, diff --git a/esp-hal/src/soc/esp32c3/peripherals.rs b/esp-hal/src/soc/esp32c3/peripherals.rs index 261a8afe5..7f0972f34 100644 --- a/esp-hal/src/soc/esp32c3/peripherals.rs +++ b/esp-hal/src/soc/esp32c3/peripherals.rs @@ -19,10 +19,10 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - SPI2 <= SPI2 (SPI2), - UART0 <= UART0, - UART1 <= UART1, + I2C0 <= I2C0 (peri => I2C_EXT0), + SPI2 <= SPI2 (peri => SPI2), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), ], unstable_peripherals: [ ADC1 <= virtual, @@ -43,7 +43,7 @@ crate::peripherals! { GPIO_SD <= GPIO_SD, HMAC <= HMAC, I2C_ANA_MST <= I2C_ANA_MST, - I2S0 <= I2S0 (I2S0), + I2S0 <= I2S0 (peri => I2S0), INTERRUPT_CORE0 <= INTERRUPT_CORE0, IO_MUX <= IO_MUX, LEDC <= LEDC, @@ -66,7 +66,7 @@ crate::peripherals! { TWAI0 <= TWAI0, UHCI0 <= UHCI0, UHCI1 <= UHCI1, - USB_DEVICE <= USB_DEVICE, + USB_DEVICE <= USB_DEVICE (peri => USB_DEVICE), WIFI <= virtual, XTS_AES <= XTS_AES, diff --git a/esp-hal/src/soc/esp32c6/peripherals.rs b/esp-hal/src/soc/esp32c6/peripherals.rs index 3aae03cc5..05bd22d4f 100644 --- a/esp-hal/src/soc/esp32c6/peripherals.rs +++ b/esp-hal/src/soc/esp32c6/peripherals.rs @@ -19,10 +19,10 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - SPI2 <= SPI2 (SPI2), - UART0 <= UART0, - UART1 <= UART1, + I2C0 <= I2C0 (peri => I2C_EXT0), + SPI2 <= SPI2 (peri => SPI2), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), ], unstable_peripherals: [ ADC1 <= virtual, @@ -43,7 +43,7 @@ crate::peripherals! { HP_APM <= HP_APM, HP_SYS <= HP_SYS, I2C_ANA_MST <= I2C_ANA_MST, - I2S0 <= I2S0 (I2S0), + I2S0 <= I2S0 (peri => I2S0), IEEE802154 <= IEEE802154, INTERRUPT_CORE0 <= INTERRUPT_CORE0, INTPRI <= INTPRI, @@ -68,7 +68,7 @@ crate::peripherals! { MODEM_LPCON <= MODEM_LPCON, MODEM_SYSCON <= MODEM_SYSCON, OTP_DEBUG <= OTP_DEBUG, - PARL_IO <= PARL_IO (PARL_IO), + PARL_IO <= PARL_IO (peri => PARL_IO), PAU <= PAU, PCR <= PCR, PCNT <= PCNT, @@ -94,7 +94,7 @@ crate::peripherals! { TWAI0 <= TWAI0, TWAI1 <= TWAI1, UHCI0 <= UHCI0, - USB_DEVICE <= USB_DEVICE, + USB_DEVICE <= USB_DEVICE (peri => USB_DEVICE), WIFI <= virtual, MEM2MEM1 <= virtual, MEM2MEM4 <= virtual, diff --git a/esp-hal/src/soc/esp32h2/peripherals.rs b/esp-hal/src/soc/esp32h2/peripherals.rs index c9aa606b3..080170226 100644 --- a/esp-hal/src/soc/esp32h2/peripherals.rs +++ b/esp-hal/src/soc/esp32h2/peripherals.rs @@ -19,11 +19,11 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - I2C1 <= I2C1, - SPI2 <= SPI2 (SPI2), - UART0 <= UART0, - UART1 <= UART1, + I2C0 <= I2C0 (peri => I2C_EXT0), + I2C1 <= I2C1 (peri => I2C_EXT1), + SPI2 <= SPI2 (peri => SPI2), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), ], unstable_peripherals: [ ADC1 <= virtual, @@ -41,7 +41,7 @@ crate::peripherals! { HP_APM <= HP_APM, HP_SYS <= HP_SYS, I2C_ANA_MST <= I2C_ANA_MST, - I2S0 <= I2S0 (I2S0), + I2S0 <= I2S0 (peri => I2S0), IEEE802154 <= IEEE802154, INTERRUPT_CORE0 <= INTERRUPT_CORE0, INTPRI <= INTPRI, @@ -60,7 +60,7 @@ crate::peripherals! { MODEM_LPCON <= MODEM_LPCON, MODEM_SYSCON <= MODEM_SYSCON, OTP_DEBUG <= OTP_DEBUG, - PARL_IO <= PARL_IO (PARL_IO_TX, PARL_IO_RX), + PARL_IO <= PARL_IO (tx => PARL_IO_TX, rx => PARL_IO_RX), PAU <= PAU, PCNT <= PCNT, PCR <= PCR, @@ -83,7 +83,7 @@ crate::peripherals! { TRACE0 <= TRACE, TWAI0 <= TWAI0, UHCI0 <= UHCI0, - USB_DEVICE <= USB_DEVICE, + USB_DEVICE <= USB_DEVICE (peri => USB_DEVICE), MEM2MEM1 <= virtual, MEM2MEM4 <= virtual, MEM2MEM5 <= virtual, diff --git a/esp-hal/src/soc/esp32s2/peripherals.rs b/esp-hal/src/soc/esp32s2/peripherals.rs index e2ed42fe4..658bd9c73 100644 --- a/esp-hal/src/soc/esp32s2/peripherals.rs +++ b/esp-hal/src/soc/esp32s2/peripherals.rs @@ -19,12 +19,12 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - I2C1 <= I2C1, - SPI2 <= SPI2 (SPI2_DMA, SPI2), - SPI3 <= SPI3 (SPI3_DMA, SPI3), - UART0 <= UART0, - UART1 <= UART1, + I2C0 <= I2C0 (peri => I2C_EXT0), + I2C1 <= I2C1 (peri => I2C_EXT1), + SPI2 <= SPI2 (dma => SPI2_DMA, peri => SPI2), + SPI3 <= SPI3 (dma => SPI3_DMA, peri => SPI3), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), ], unstable_peripherals: [ ADC1 <= virtual, @@ -41,7 +41,7 @@ crate::peripherals! { GPIO_SD <= GPIO_SD, HMAC <= HMAC, I2C_ANA_MST <= I2C_ANA_MST, - I2S0 <= I2S0 (I2S0), + I2S0 <= I2S0 (peri => I2S0), INTERRUPT_CORE0 <= INTERRUPT_CORE0, IO_MUX <= IO_MUX, LEDC <= LEDC, diff --git a/esp-hal/src/soc/esp32s3/peripherals.rs b/esp-hal/src/soc/esp32s3/peripherals.rs index 0ef7a08cd..db60d832b 100644 --- a/esp-hal/src/soc/esp32s3/peripherals.rs +++ b/esp-hal/src/soc/esp32s3/peripherals.rs @@ -19,13 +19,13 @@ pub use pac::Interrupt; // creating "virtual peripherals" for them. crate::peripherals! { peripherals: [ - I2C0 <= I2C0, - I2C1 <= I2C1, - SPI2 <= SPI2 (SPI2), - SPI3 <= SPI3 (SPI3), - UART0 <= UART0, - UART1 <= UART1, - UART2 <= UART2, + I2C0 <= I2C0 (peri => I2C_EXT0), + I2C1 <= I2C1 (peri => I2C_EXT1), + SPI2 <= SPI2 (peri => SPI2), + SPI3 <= SPI3 (peri => SPI3), + UART0 <= UART0 (peri => UART0), + UART1 <= UART1 (peri => UART1), + UART2 <= UART2 (peri => UART2), ], unstable_peripherals: [ ADC1 <= virtual, @@ -43,8 +43,8 @@ crate::peripherals! { GPIO <= GPIO, GPIO_SD <= GPIO_SD, HMAC <= HMAC, - I2S0 <= I2S0 (I2S0), - I2S1 <= I2S1 (I2S1), + I2S0 <= I2S0 (peri => I2S0), + I2S1 <= I2S1 (peri => I2S1), INTERRUPT_CORE0 <= INTERRUPT_CORE0, INTERRUPT_CORE1 <= INTERRUPT_CORE1, IO_MUX <= IO_MUX, @@ -77,7 +77,7 @@ crate::peripherals! { UHCI1 <= UHCI1, ULP_RISCV_CORE <= virtual, USB0 <= USB0, - USB_DEVICE <= USB_DEVICE, + USB_DEVICE <= USB_DEVICE (peri => USB_DEVICE), USB_WRAP <= USB_WRAP, WCL <= WCL, WIFI <= virtual, diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 74b623a60..1d830ecd0 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -64,7 +64,7 @@ use crate::{ interrupt::InterruptHandler, pac::spi2::RegisterBlock, private::{self, OnDrop, Sealed}, - system::{Cpu, PeripheralGuard}, + system::PeripheralGuard, time::Rate, }; @@ -797,12 +797,7 @@ impl<'d> Spi<'d, Blocking> { /// `None`) #[instability::unstable] pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - let interrupt = self.driver().info.interrupt; - for core in Cpu::other() { - crate::interrupt::disable(core, interrupt); - } - unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) }; - unwrap!(crate::interrupt::enable(interrupt, handler.priority())); + self.spi.set_interrupt_handler(handler); } } @@ -812,14 +807,14 @@ impl crate::interrupt::InterruptConfigurable for Spi<'_, Blocking> { /// /// Interrupts are not enabled at the peripheral level here. fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - Spi::set_interrupt_handler(self, handler); + self.set_interrupt_handler(handler); } } impl<'d> Spi<'d, Async> { /// Converts the SPI instance into blocking mode. pub fn into_blocking(self) -> Spi<'d, Blocking> { - crate::interrupt::disable(Cpu::current(), self.driver().info.interrupt); + self.spi.disable_peri_interrupt(); Spi { spi: self.spi, _mode: PhantomData, @@ -1358,12 +1353,7 @@ mod dma { /// `None`) #[instability::unstable] pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - let interrupt = self.driver().info.interrupt; - for core in Cpu::other() { - crate::interrupt::disable(core, interrupt); - } - unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) }; - unwrap!(crate::interrupt::enable(interrupt, handler.priority())); + self.spi.set_interrupt_handler(handler); } } @@ -1371,7 +1361,7 @@ mod dma { /// Converts the SPI instance into async mode. #[instability::unstable] pub fn into_blocking(self) -> SpiDma<'d, Blocking> { - crate::interrupt::disable(Cpu::current(), self.driver().info.interrupt); + self.spi.disable_peri_interrupt(); SpiDma { spi: self.spi, channel: self.channel.into_blocking(), @@ -1453,12 +1443,7 @@ mod dma { /// /// Interrupts are not enabled at the peripheral level here. fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - let interrupt = self.driver().info.interrupt; - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, interrupt); - } - unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) }; - unwrap!(crate::interrupt::enable(interrupt, handler.priority())); + self.set_interrupt_handler(handler); } } @@ -2687,9 +2672,6 @@ pub struct Info { /// The system peripheral marker. pub peripheral: crate::system::Peripheral, - /// Interrupt for this SPI instance. - pub interrupt: crate::peripherals::Interrupt, - /// SCLK signal. pub sclk: OutputSignal, @@ -3721,7 +3703,6 @@ macro_rules! spi_instance { static INFO: Info = Info { register_block: crate::peripherals::[]::regs(), peripheral: crate::system::Peripheral::[], - interrupt: crate::peripherals::Interrupt::[], sclk: OutputSignal::$sclk, mosi: OutputSignal::$mosi, miso: InputSignal::$miso, @@ -3929,6 +3910,27 @@ impl Instance for AnySpi<'_> { } } +impl AnySpi<'_> { + delegate::delegate! { + to match &self.0 { + #[cfg(spi_master_spi2)] + AnySpiInner::Spi2(spi) => spi, + #[cfg(spi_master_spi3)] + AnySpiInner::Spi3(spi) => spi, + } { + fn bind_peri_interrupt(&self, handler: unsafe extern "C" fn() -> ()); + fn disable_peri_interrupt(&self); + fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority); + } + } + + fn set_interrupt_handler(&self, handler: InterruptHandler) { + self.disable_peri_interrupt(); + self.bind_peri_interrupt(handler.handler()); + self.enable_peri_interrupt(handler.priority()); + } +} + struct SpiFuture<'a> { driver: &'a Driver, } diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 6dc791488..33b002c47 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -65,7 +65,6 @@ use crate::{ }, interrupt::InterruptHandler, pac::uart0::RegisterBlock, - peripherals::Interrupt, private::OnDrop, system::{PeripheralClockControl, PeripheralGuard}, }; @@ -636,7 +635,6 @@ impl<'d> UartTx<'d, Blocking> { pub fn into_async(self) -> UartTx<'d, Async> { if !self.uart.state().is_rx_async.load(Ordering::Acquire) { self.uart - .info() .set_interrupt_handler(self.uart.info().async_handler); } self.uart.state().is_tx_async.store(true, Ordering::Release); @@ -660,7 +658,7 @@ impl<'d> UartTx<'d, Async> { .is_tx_async .store(false, Ordering::Release); if !self.uart.state().is_rx_async.load(Ordering::Acquire) { - self.uart.info().disable_interrupts(); + self.uart.disable_peri_interrupt(); } UartTx { @@ -931,7 +929,6 @@ impl<'d> UartRx<'d, Blocking> { pub fn into_async(self) -> UartRx<'d, Async> { if !self.uart.state().is_tx_async.load(Ordering::Acquire) { self.uart - .info() .set_interrupt_handler(self.uart.info().async_handler); } self.uart.state().is_rx_async.store(true, Ordering::Release); @@ -953,7 +950,7 @@ impl<'d> UartRx<'d, Async> { .is_rx_async .store(false, Ordering::Release); if !self.uart.state().is_tx_async.load(Ordering::Acquire) { - self.uart.info().disable_interrupts(); + self.uart.disable_peri_interrupt(); } UartRx { @@ -1277,7 +1274,7 @@ impl<'d> Uart<'d, Blocking> { #[instability::unstable] pub fn set_interrupt_handler(&mut self, handler: InterruptHandler) { // `self.tx.uart` and `self.rx.uart` are the same - self.tx.uart.info().set_interrupt_handler(handler); + self.tx.uart.set_interrupt_handler(handler); } /// Listen for the given interrupts @@ -1784,7 +1781,7 @@ impl crate::private::Sealed for Uart<'_, Blocking> {} impl crate::interrupt::InterruptConfigurable for Uart<'_, Blocking> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { // `self.tx.uart` and `self.rx.uart` are the same - self.tx.uart.info().set_interrupt_handler(handler); + self.tx.uart.set_interrupt_handler(handler); } } @@ -2459,9 +2456,6 @@ pub struct Info { /// Interrupt handler for the asynchronous operations of this UART instance. pub async_handler: InterruptHandler, - /// Interrupt for this UART instance. - pub interrupt: Interrupt, - /// TX pin pub tx_signal: OutputSignal, @@ -2559,20 +2553,6 @@ impl Info { }); } - fn set_interrupt_handler(&self, handler: InterruptHandler) { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, self.interrupt); - } - self.enable_listen(EnumSet::all(), false); - self.clear_interrupts(EnumSet::all()); - unsafe { crate::interrupt::bind_interrupt(self.interrupt, handler.handler()) }; - unwrap!(crate::interrupt::enable(self.interrupt, handler.priority())); - } - - fn disable_interrupts(&self) { - crate::interrupt::disable(crate::system::Cpu::current(), self.interrupt); - } - fn apply_config(&self, config: &Config) -> Result<(), ConfigError> { config.validate()?; self.change_baud(config)?; @@ -3245,7 +3225,6 @@ macro_rules! impl_instance { register_block: crate::peripherals::$inst::ptr(), peripheral: crate::system::Peripheral::$peri, async_handler: irq_handler, - interrupt: Interrupt::$inst, tx_signal: OutputSignal::$txd, rx_signal: InputSignal::$rxd, cts_signal: InputSignal::$cts, @@ -3289,3 +3268,30 @@ impl Instance for AnyUart<'_> { } } } + +impl AnyUart<'_> { + delegate::delegate! { + to match &self.0 { + #[cfg(soc_has_uart0)] + AnyUartInner::Uart0(uart) => uart, + #[cfg(soc_has_uart1)] + AnyUartInner::Uart1(uart) => uart, + #[cfg(soc_has_uart2)] + AnyUartInner::Uart2(uart) => uart, + } { + fn bind_peri_interrupt(&self, handler: unsafe extern "C" fn() -> ()); + fn disable_peri_interrupt(&self); + fn enable_peri_interrupt(&self, priority: crate::interrupt::Priority); + } + } + + fn set_interrupt_handler(&self, handler: InterruptHandler) { + self.disable_peri_interrupt(); + + self.info().enable_listen(EnumSet::all(), false); + self.info().clear_interrupts(EnumSet::all()); + + self.bind_peri_interrupt(handler.handler()); + self.enable_peri_interrupt(handler.priority()); + } +} diff --git a/esp-hal/src/usb_serial_jtag.rs b/esp-hal/src/usb_serial_jtag.rs index 8b8827c73..e4be78858 100644 --- a/esp-hal/src/usb_serial_jtag.rs +++ b/esp-hal/src/usb_serial_jtag.rs @@ -133,8 +133,8 @@ use crate::{ DriverMode, asynch::AtomicWaker, pac::usb_device::RegisterBlock, - peripherals::{Interrupt, USB_DEVICE}, - system::{Cpu, PeripheralClockControl}, + peripherals::USB_DEVICE, + system::PeripheralClockControl, }; /// Custom USB serial error type @@ -439,14 +439,9 @@ where /// handlers. #[instability::unstable] pub fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) { - for core in crate::system::Cpu::other() { - crate::interrupt::disable(core, Interrupt::USB_DEVICE); - } - unsafe { crate::interrupt::bind_interrupt(Interrupt::USB_DEVICE, handler.handler()) }; - unwrap!(crate::interrupt::enable( - Interrupt::USB_DEVICE, - handler.priority() - )); + self.rx.peripheral.disable_peri_interrupt(); + self.rx.peripheral.bind_peri_interrupt(handler.handler()); + self.rx.peripheral.enable_peri_interrupt(handler.priority()); } } @@ -718,7 +713,7 @@ impl<'d> UsbSerialJtag<'d, Async> { /// Reconfigure the USB Serial JTAG peripheral to operate in blocking /// mode. pub fn into_blocking(self) -> UsbSerialJtag<'d, Blocking> { - crate::interrupt::disable(Cpu::current(), Interrupt::USB_DEVICE); + self.rx.peripheral.disable_peri_interrupt(); UsbSerialJtag { rx: UsbSerialJtagRx { peripheral: self.rx.peripheral, diff --git a/esp-metadata/devices/esp32.toml b/esp-metadata/devices/esp32.toml index 45aa5aae9..c54d2fc76 100644 --- a/esp-metadata/devices/esp32.toml +++ b/esp-metadata/devices/esp32.toml @@ -552,8 +552,8 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, - { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA", interrupt = "I2C_EXT1" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, + { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA" }, ] ll_intr_mask = 0x3ffff fifo_size = 32 diff --git a/esp-metadata/devices/esp32c2.toml b/esp-metadata/devices/esp32c2.toml index d18ff7a83..e09ada99a 100644 --- a/esp-metadata/devices/esp32c2.toml +++ b/esp-metadata/devices/esp32c2.toml @@ -196,7 +196,7 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, ] has_fsm_timeouts = true has_hw_bus_clear = true diff --git a/esp-metadata/devices/esp32c3.toml b/esp-metadata/devices/esp32c3.toml index 2203e55db..c9733745f 100644 --- a/esp-metadata/devices/esp32c3.toml +++ b/esp-metadata/devices/esp32c3.toml @@ -245,7 +245,7 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, ] has_fsm_timeouts = true has_hw_bus_clear = true diff --git a/esp-metadata/devices/esp32c6.toml b/esp-metadata/devices/esp32c6.toml index 85e5f14e1..68498d6a8 100644 --- a/esp-metadata/devices/esp32c6.toml +++ b/esp-metadata/devices/esp32c6.toml @@ -368,7 +368,7 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, ] has_fsm_timeouts = true has_hw_bus_clear = true diff --git a/esp-metadata/devices/esp32h2.toml b/esp-metadata/devices/esp32h2.toml index e4a2da106..6b3010145 100644 --- a/esp-metadata/devices/esp32h2.toml +++ b/esp-metadata/devices/esp32h2.toml @@ -312,8 +312,8 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, - { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA", interrupt = "I2C_EXT1" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, + { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA" }, ] has_fsm_timeouts = true has_hw_bus_clear = true diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 64b100d9b..cbac00c9d 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -338,8 +338,8 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, - { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA", interrupt = "I2C_EXT1" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, + { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA" }, ] ll_intr_mask = 0x1ffff fifo_size = 32 diff --git a/esp-metadata/devices/esp32s3.toml b/esp-metadata/devices/esp32s3.toml index b1f79b114..db3ba1987 100644 --- a/esp-metadata/devices/esp32s3.toml +++ b/esp-metadata/devices/esp32s3.toml @@ -486,8 +486,8 @@ output_signals = [ [device.i2c_master] support_status = "supported" instances = [ - { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA", interrupt = "I2C_EXT0" }, - { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA", interrupt = "I2C_EXT1" }, + { name = "i2c0", sys_instance = "I2cExt0", scl = "I2CEXT0_SCL", sda = "I2CEXT0_SDA" }, + { name = "i2c1", sys_instance = "I2cExt1", scl = "I2CEXT1_SCL", sda = "I2CEXT1_SDA" }, ] has_fsm_timeouts = true has_hw_bus_clear = true diff --git a/esp-metadata/src/cfg/i2c_master.rs b/esp-metadata/src/cfg/i2c_master.rs index 254e59e16..81f1129fe 100644 --- a/esp-metadata/src/cfg/i2c_master.rs +++ b/esp-metadata/src/cfg/i2c_master.rs @@ -14,9 +14,6 @@ pub(crate) struct I2cMasterInstanceConfig { /// IOMUX signal name of the instane's SDA signal. pub sda: String, - - /// The name of the instance's interrupt handler. - pub interrupt: String, } /// Generates `for_each_i2c_master!` which can be used to implement the I2C @@ -34,12 +31,11 @@ pub(crate) fn generate_i2c_master_peripehrals(i2c: &I2cMasterProperties) -> Toke let sys = format_ident!("{}", instance_config.sys_instance); let sda = format_ident!("{}", instance_config.sda); let scl = format_ident!("{}", instance_config.scl); - let int = format_ident!("{}", instance_config.interrupt); // The order and meaning of these tokens must match their use in the // `for_each_i2c_master!` call. quote::quote! { - #instance, #sys, #scl, #sda, #int + #instance, #sys, #scl, #sda } }) .collect::>();