diff --git a/esp-hal/src/assist_debug.rs b/esp-hal/src/assist_debug.rs index 4e5fe1e8c90..f8e8997e760 100644 --- a/esp-hal/src/assist_debug.rs +++ b/esp-hal/src/assist_debug.rs @@ -26,7 +26,7 @@ use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, - peripherals::ASSIST_DEBUG, + peripherals::{Interrupt, ASSIST_DEBUG}, InterruptConfigurable, }; @@ -51,17 +51,14 @@ impl<'d> crate::private::Sealed for DebugAssist<'d> {} impl<'d> InterruptConfigurable for DebugAssist<'d> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - unsafe { - crate::interrupt::bind_interrupt( - crate::peripherals::Interrupt::ASSIST_DEBUG, - handler.handler(), - ); - crate::interrupt::enable( - crate::peripherals::Interrupt::ASSIST_DEBUG, - handler.priority(), - ) - .unwrap(); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::ASSIST_DEBUG); } + unsafe { crate::interrupt::bind_interrupt(Interrupt::ASSIST_DEBUG, handler.handler()) }; + unwrap!(crate::interrupt::enable( + Interrupt::ASSIST_DEBUG, + handler.priority() + )); } } diff --git a/esp-hal/src/ecc.rs b/esp-hal/src/ecc.rs index 10d0a17fac5..6817f375b6f 100644 --- a/esp-hal/src/ecc.rs +++ b/esp-hal/src/ecc.rs @@ -30,7 +30,7 @@ use core::marker::PhantomData; use crate::{ interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, - peripherals::ECC, + peripherals::{Interrupt, ECC}, reg_access::{AlignmentHelper, SocDependentEndianess}, system::{Peripheral as PeripheralEnable, PeripheralClockControl}, InterruptConfigurable, @@ -117,11 +117,11 @@ impl<'d> crate::private::Sealed for Ecc<'d, crate::Blocking> {} impl<'d> InterruptConfigurable for Ecc<'d, crate::Blocking> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - unsafe { - crate::interrupt::bind_interrupt(crate::peripherals::Interrupt::ECC, handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::ECC, handler.priority()) - .unwrap(); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::ECC); } + unsafe { crate::interrupt::bind_interrupt(Interrupt::ECC, handler.handler()) }; + unwrap!(crate::interrupt::enable(Interrupt::ECC, handler.priority())); } } diff --git a/esp-hal/src/i2s.rs b/esp-hal/src/i2s.rs index 4db31771c43..fdd8ff70df2 100644 --- a/esp-hal/src/i2s.rs +++ b/esp-hal/src/i2s.rs @@ -790,7 +790,7 @@ mod private { }, interrupt::InterruptHandler, peripheral::{Peripheral, PeripheralRef}, - peripherals::I2S0, + peripherals::{Interrupt, I2S0}, private, Mode, }; @@ -1623,9 +1623,14 @@ mod private { impl RegisterAccessPrivate for I2S0 { fn set_interrupt_handler(&self, handler: InterruptHandler) { + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::I2S0); + } unsafe { crate::peripherals::I2S0::steal() }.bind_i2s0_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::I2S0, handler.priority()) - .unwrap(); + unwrap!(crate::interrupt::enable( + Interrupt::I2S0, + handler.priority() + )); } } @@ -1723,9 +1728,14 @@ mod private { #[cfg(i2s1)] impl RegisterAccessPrivate for I2S1 { fn set_interrupt_handler(&self, handler: InterruptHandler) { + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::I2S1); + } unsafe { crate::peripherals::I2S1::steal() }.bind_i2s1_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::I2S1, handler.priority()) - .unwrap(); + unwrap!(crate::interrupt::enable( + Interrupt::I2S1, + handler.priority() + )); } } diff --git a/esp-hal/src/interrupt/software.rs b/esp-hal/src/interrupt/software.rs index 64156a68d91..8b4284f7b33 100644 --- a/esp-hal/src/interrupt/software.rs +++ b/esp-hal/src/interrupt/software.rs @@ -62,10 +62,11 @@ impl SoftwareInterrupt { _ => unreachable!(), }; - unsafe { - crate::interrupt::bind_interrupt(interrupt, handler.handler()); - crate::interrupt::enable(interrupt, handler.priority()).unwrap(); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, interrupt); } + unsafe { crate::interrupt::bind_interrupt(interrupt, handler.handler()) }; + unwrap!(crate::interrupt::enable(interrupt, handler.priority())); } /// Trigger this software-interrupt diff --git a/esp-hal/src/parl_io.rs b/esp-hal/src/parl_io.rs index d9bd95577d1..b441f955410 100644 --- a/esp-hal/src/parl_io.rs +++ b/esp-hal/src/parl_io.rs @@ -52,7 +52,7 @@ use crate::{ gpio::interconnect::{InputConnection, OutputConnection, PeripheralInput, PeripheralOutput}, interrupt::InterruptHandler, peripheral::{self, Peripheral}, - peripherals::{self, PARL_IO}, + peripherals::{self, Interrupt, PARL_IO}, system::PeripheralClockControl, Blocking, InterruptConfigurable, @@ -923,42 +923,52 @@ where fn internal_set_interrupt_handler(handler: InterruptHandler) { #[cfg(esp32c6)] { + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::PARL_IO); + } + internal_listen(EnumSet::all(), false); + internal_clear_interrupts(EnumSet::all()); unsafe { PARL_IO::steal() }.bind_parl_io_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::PARL_IO, handler.priority()) - .unwrap(); + unwrap!(crate::interrupt::enable( + Interrupt::PARL_IO, + handler.priority() + )); } #[cfg(esp32h2)] { + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::PARL_IO_RX); + crate::interrupt::disable(core, Interrupt::PARL_IO_TX); + } + internal_listen(EnumSet::all(), false); + internal_clear_interrupts(EnumSet::all()); unsafe { PARL_IO::steal() }.bind_parl_io_tx_interrupt(handler.handler()); unsafe { PARL_IO::steal() }.bind_parl_io_rx_interrupt(handler.handler()); - crate::interrupt::enable( - crate::peripherals::Interrupt::PARL_IO_TX, + unwrap!(crate::interrupt::enable( + Interrupt::PARL_IO_TX, handler.priority(), - ) - .unwrap(); - crate::interrupt::enable( - crate::peripherals::Interrupt::PARL_IO_RX, + )); + unwrap!(crate::interrupt::enable( + Interrupt::PARL_IO_RX, handler.priority(), - ) - .unwrap(); + )); } } fn internal_listen(interrupts: EnumSet, enable: bool) { let parl_io = unsafe { PARL_IO::steal() }; - for interrupt in interrupts { - match interrupt { - ParlIoInterrupt::TxFifoReEmpty => parl_io - .int_ena() - .modify(|_, w| w.tx_fifo_rempty().bit(enable)), - ParlIoInterrupt::RxFifoWOvf => parl_io - .int_ena() - .modify(|_, w| w.rx_fifo_wovf().bit(enable)), - ParlIoInterrupt::TxEof => parl_io.int_ena().write(|w| w.tx_eof().bit(enable)), + parl_io.int_ena().write(|w| { + for interrupt in interrupts { + match interrupt { + ParlIoInterrupt::TxFifoReEmpty => w.tx_fifo_rempty().bit(enable), + ParlIoInterrupt::RxFifoWOvf => w.rx_fifo_wovf().bit(enable), + ParlIoInterrupt::TxEof => w.tx_eof().bit(enable), + } } - } + w + }); } fn internal_interrupts() -> EnumSet { @@ -980,17 +990,16 @@ fn internal_interrupts() -> EnumSet { fn internal_clear_interrupts(interrupts: EnumSet) { let parl_io = unsafe { PARL_IO::steal() }; - for interrupt in interrupts { - match interrupt { - ParlIoInterrupt::TxFifoReEmpty => parl_io - .int_clr() - .write(|w| w.tx_fifo_rempty().clear_bit_by_one()), - ParlIoInterrupt::RxFifoWOvf => parl_io - .int_clr() - .write(|w| w.rx_fifo_wovf().clear_bit_by_one()), - ParlIoInterrupt::TxEof => parl_io.int_clr().write(|w| w.tx_eof().clear_bit_by_one()), - } - } + parl_io.int_clr().write(|w| { + for interrupt in interrupts { + match interrupt { + ParlIoInterrupt::TxFifoReEmpty => w.tx_fifo_rempty().clear_bit_by_one(), + ParlIoInterrupt::RxFifoWOvf => w.rx_fifo_wovf().clear_bit_by_one(), + ParlIoInterrupt::TxEof => w.tx_eof().clear_bit_by_one(), + }; + } + w + }); } /// Parallel IO in full duplex mode diff --git a/esp-hal/src/pcnt/mod.rs b/esp-hal/src/pcnt/mod.rs index 4c4817c46cf..ad953ecf989 100644 --- a/esp-hal/src/pcnt/mod.rs +++ b/esp-hal/src/pcnt/mod.rs @@ -113,9 +113,10 @@ impl<'d> crate::private::Sealed for Pcnt<'d> {} impl<'d> InterruptConfigurable for Pcnt<'d> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - unsafe { - interrupt::bind_interrupt(Interrupt::PCNT, handler.handler()); - interrupt::enable(Interrupt::PCNT, handler.priority()).unwrap(); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::PCNT); } + unsafe { interrupt::bind_interrupt(Interrupt::PCNT, handler.handler()) }; + unwrap!(interrupt::enable(Interrupt::PCNT, handler.priority())); } } diff --git a/esp-hal/src/rtc_cntl/mod.rs b/esp-hal/src/rtc_cntl/mod.rs index c63c7538fa8..42abd507511 100644 --- a/esp-hal/src/rtc_cntl/mod.rs +++ b/esp-hal/src/rtc_cntl/mod.rs @@ -434,23 +434,18 @@ impl<'d> crate::private::Sealed for Rtc<'d> {} impl<'d> InterruptConfigurable for Rtc<'d> { fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - unsafe { - interrupt::bind_interrupt( - #[cfg(any(esp32c6, esp32h2))] - Interrupt::LP_WDT, - #[cfg(not(any(esp32c6, esp32h2)))] - Interrupt::RTC_CORE, - handler.handler(), - ); - interrupt::enable( - #[cfg(any(esp32c6, esp32h2))] - Interrupt::LP_WDT, - #[cfg(not(any(esp32c6, esp32h2)))] - Interrupt::RTC_CORE, - handler.priority(), - ) - .unwrap(); + cfg_if::cfg_if! { + if #[cfg(any(esp32c6, esp32h2))] { + let interrupt = Interrupt::LP_WDT; + } else { + let interrupt = Interrupt::RTC_CORE; + } + } + for core in crate::Cpu::other() { + crate::interrupt::disable(core, interrupt); } + unsafe { interrupt::bind_interrup(interrupt, handler.handler()) }; + unwrap!(interrupt::enable(interrupt, handler.priority())); } } diff --git a/esp-hal/src/sha.rs b/esp-hal/src/sha.rs index 6758ea2ec48..8c7601260de 100644 --- a/esp-hal/src/sha.rs +++ b/esp-hal/src/sha.rs @@ -64,7 +64,7 @@ pub use digest::Digest; use crate::{ peripheral::{Peripheral, PeripheralRef}, - peripherals::SHA, + peripherals::{Interrupt, SHA}, reg_access::{AlignmentHelper, SocDependentEndianess}, system::PeripheralClockControl, }; @@ -103,11 +103,11 @@ impl<'d> crate::private::Sealed for Sha<'d> {} #[cfg(not(esp32))] impl<'d> crate::InterruptConfigurable for Sha<'d> { fn set_interrupt_handler(&mut self, handler: crate::interrupt::InterruptHandler) { - unsafe { - crate::interrupt::bind_interrupt(crate::peripherals::Interrupt::SHA, handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::SHA, handler.priority()) - .unwrap(); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, Interrupt::SHA); } + unsafe { crate::interrupt::bind_interrupt(Interrupt::SHA, handler.handler()) }; + unwrap!(crate::interrupt::enable(Interrupt::SHA, handler.priority())); } } diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 3aa3792bd35..3fa38a0f84a 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -2980,6 +2980,9 @@ macro_rules! spi_instance { #[inline(always)] fn set_interrupt_handler(&mut self, handler: InterruptHandler) { + for core in crate::Cpu::other() { + crate::interrupt::disable(core, crate::peripherals::Interrupt::[]); + } self.[](handler.handler()); crate::interrupt::enable(crate::peripherals::Interrupt::[], handler.priority()).unwrap(); } diff --git a/esp-hal/src/timer/systimer.rs b/esp-hal/src/timer/systimer.rs index 7ecbd9f5ec2..69870866246 100644 --- a/esp-hal/src/timer/systimer.rs +++ b/esp-hal/src/timer/systimer.rs @@ -549,6 +549,10 @@ pub trait Comparator { _ => unreachable!(), }; + for core in crate::Cpu::other() { + crate::interrupt::disable(core, interrupt); + } + #[cfg(not(esp32s2))] unsafe { interrupt::bind_interrupt(interrupt, handler.handler()); diff --git a/esp-hal/src/timer/timg.rs b/esp-hal/src/timer/timg.rs index 27818ed8f14..7e9bf191fa8 100644 --- a/esp-hal/src/timer/timg.rs +++ b/esp-hal/src/timer/timg.rs @@ -553,10 +553,11 @@ where _ => unreachable!(), }; - unsafe { - interrupt::bind_interrupt(interrupt, handler.handler()); + for core in crate::Cpu::other() { + crate::interrupt::disable(core, interrupt); } - interrupt::enable(interrupt, handler.priority()).unwrap(); + unsafe { interrupt::bind_interrupt(interrupt, handler.handler()) }; + unwrap!(interrupt::enable(interrupt, handler.priority())); } fn is_interrupt_set(&self) -> bool { diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index a6260c18981..bc6b6f657bb 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -1207,66 +1207,24 @@ where self.rx.at_cmd_config = Some(config); } - /// Listen for the given interrupts - fn enable_listen(&mut self, interrupts: EnumSet, enable: bool) { - let reg_block = self.register_block(); - - reg_block.int_ena().modify(|_, w| { - for interrupt in interrupts { - match interrupt { - UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable), - UartInterrupt::TxDone => w.tx_done().bit(enable), - UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable), - }; - } - w - }); - } - /// Listen for the given interrupts pub fn listen(&mut self, interrupts: impl Into>) { - self.enable_listen(interrupts.into(), true); + self.tx.uart.info().enable_listen(interrupts.into(), true) } /// Unlisten the given interrupts pub fn unlisten(&mut self, interrupts: impl Into>) { - self.enable_listen(interrupts.into(), false); + self.tx.uart.info().enable_listen(interrupts.into(), false) } /// Gets asserted interrupts pub fn interrupts(&mut self) -> EnumSet { - let mut res = EnumSet::new(); - let reg_block = self.register_block(); - - let ints = reg_block.int_raw().read(); - - if ints.at_cmd_char_det().bit_is_set() { - res.insert(UartInterrupt::AtCmd); - } - if ints.tx_done().bit_is_set() { - res.insert(UartInterrupt::TxDone); - } - if ints.rxfifo_full().bit_is_set() { - res.insert(UartInterrupt::RxFifoFull); - } - - res + self.tx.uart.info().interrupts() } /// Resets asserted interrupts pub fn clear_interrupts(&mut self, interrupts: EnumSet) { - let reg_block = self.register_block(); - - reg_block.int_clr().write(|w| { - for interrupt in interrupts { - match interrupt { - UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(), - UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(), - UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(), - }; - } - w - }); + self.tx.uart.info().clear_interrupts(interrupts) } /// Write a byte out over the UART @@ -2438,6 +2396,8 @@ impl Info { for core in crate::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())); } @@ -2511,6 +2471,56 @@ impl Info { pub fn register_block(&self) -> &RegisterBlock { unsafe { &*self.register_block } } + + /// Listen for the given interrupts + fn enable_listen(&self, interrupts: EnumSet, enable: bool) { + let reg_block = self.register_block(); + + reg_block.int_ena().modify(|_, w| { + for interrupt in interrupts { + match interrupt { + UartInterrupt::AtCmd => w.at_cmd_char_det().bit(enable), + UartInterrupt::TxDone => w.tx_done().bit(enable), + UartInterrupt::RxFifoFull => w.rxfifo_full().bit(enable), + }; + } + w + }); + } + + fn interrupts(&self) -> EnumSet { + let mut res = EnumSet::new(); + let reg_block = self.register_block(); + + let ints = reg_block.int_raw().read(); + + if ints.at_cmd_char_det().bit_is_set() { + res.insert(UartInterrupt::AtCmd); + } + if ints.tx_done().bit_is_set() { + res.insert(UartInterrupt::TxDone); + } + if ints.rxfifo_full().bit_is_set() { + res.insert(UartInterrupt::RxFifoFull); + } + + res + } + + fn clear_interrupts(&self, interrupts: EnumSet) { + let reg_block = self.register_block(); + + reg_block.int_clr().write(|w| { + for interrupt in interrupts { + match interrupt { + UartInterrupt::AtCmd => w.at_cmd_char_det().clear_bit_by_one(), + UartInterrupt::TxDone => w.tx_done().clear_bit_by_one(), + UartInterrupt::RxFifoFull => w.rxfifo_full().clear_bit_by_one(), + }; + } + w + }); + } } impl PartialEq for Info {