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
This commit is contained in:
Dániel Buga 2025-06-30 17:28:42 +02:00 committed by GitHub
parent 03a3b6f5d6
commit b11d810d97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 212 additions and 222 deletions

View File

@ -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());
}
}

View File

@ -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<I2sInterrupt>, 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<I2sInterrupt>, 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<'_> {

View File

@ -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());
}
}

View File

@ -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 [<bind_ $fn_name _interrupt >](&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 [<disable_ $fn_name _interrupt >](&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 [<enable_ $fn_name _interrupt >](&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 [<bind_ $interrupt:lower _interrupt >](&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 [<bind_ $unstable_interrupt:lower _interrupt >](&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);
)*
}
)*

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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::[<SPI $num>]::regs(),
peripheral: crate::system::Peripheral::[<Spi $num>],
interrupt: crate::peripherals::Interrupt::[<SPI $num>],
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,
}

View File

@ -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());
}
}

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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::<Vec<_>>();