From 1c19c9647b07386cb09f488fc44f8122f47606cb Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Thu, 14 Jul 2022 21:59:10 +0100 Subject: [PATCH] make enable unsafe. Add note about preallocated interrupts in vectored mode. --- esp-hal-common/src/interrupt/xtensa.rs | 40 ++++++++++++++--------- esp32-hal/examples/serial_interrupts.rs | 12 ++++--- esp32-hal/examples/timer_interrupt.rs | 24 +++++++------- esp32-hal/src/lib.rs | 2 +- esp32s2-hal/examples/serial_interrupts.rs | 12 ++++--- esp32s2-hal/examples/systimer.rs | 36 ++++++++++---------- esp32s2-hal/examples/timer_interrupt.rs | 23 +++++++------ esp32s2-hal/src/lib.rs | 2 +- esp32s3-hal/examples/serial_interrupts.rs | 12 ++++--- esp32s3-hal/examples/systimer.rs | 36 ++++++++++---------- esp32s3-hal/examples/timer_interrupt.rs | 23 +++++++------ esp32s3-hal/src/lib.rs | 2 +- 12 files changed, 124 insertions(+), 100 deletions(-) diff --git a/esp-hal-common/src/interrupt/xtensa.rs b/esp-hal-common/src/interrupt/xtensa.rs index 6cd5747abb9..76ab71fca48 100644 --- a/esp-hal-common/src/interrupt/xtensa.rs +++ b/esp-hal-common/src/interrupt/xtensa.rs @@ -47,21 +47,31 @@ pub enum CpuInterrupt { } /// Enable and assign a peripheral interrupt to an CPU interrupt. -pub fn enable(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) { - unsafe { - let interrupt_number = interrupt as isize; - let cpu_interrupt_number = which as isize; - let intr_map_base = match core { - Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), - #[cfg(feature = "multicore")] - Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(), - #[cfg(feature = "unicore")] - Cpu::AppCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), - }; - intr_map_base - .offset(interrupt_number) - .write_volatile(cpu_interrupt_number as u32); - } +/// +/// Great care **must** be taken when using with function with interrupt +/// vectoring (enabled by default). Avoid the following CPU interrupts: +/// - Interrupt1LevelPriority1 +/// - Interrupt19LevelPriority2 +/// - Interrupt23LevelPriority3 +/// - Interrupt10EdgePriority1 +/// - Interrupt22EdgePriority3 +/// As they are preallocated for interrupt vectoring. +/// +/// Note: this only maps the interrupt to the CPU interrupt. The CPU interrupt +/// still needs to be enabled afterwards +pub unsafe fn enable(core: Cpu, interrupt: Interrupt, which: CpuInterrupt) { + let interrupt_number = interrupt as isize; + let cpu_interrupt_number = which as isize; + let intr_map_base = match core { + Cpu::ProCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), + #[cfg(feature = "multicore")] + Cpu::AppCpu => (*core1_interrupt_peripheral()).app_mac_intr_map.as_ptr(), + #[cfg(feature = "unicore")] + Cpu::AppCpu => (*core0_interrupt_peripheral()).pro_mac_intr_map.as_ptr(), + }; + intr_map_base + .offset(interrupt_number) + .write_volatile(cpu_interrupt_number as u32); } /// Disable the given peripheral interrupt. diff --git a/esp32-hal/examples/serial_interrupts.rs b/esp32-hal/examples/serial_interrupts.rs index e37f5738c47..33b8023ecba 100644 --- a/esp32-hal/examples/serial_interrupts.rs +++ b/esp32-hal/examples/serial_interrupts.rs @@ -48,11 +48,13 @@ fn main() -> ! { serial0.listen_at_cmd(); serial0.listen_rx_fifo_full(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::UART0, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::UART0, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + } timer0.start(1u64.secs()); diff --git a/esp32-hal/examples/timer_interrupt.rs b/esp32-hal/examples/timer_interrupt.rs index b51adf18e93..e030f0904e1 100644 --- a/esp32-hal/examples/timer_interrupt.rs +++ b/esp32-hal/examples/timer_interrupt.rs @@ -41,19 +41,21 @@ fn main() -> ! { timer1.disable(); rtc_cntl.set_wdt_global_enable(false); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG0_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + } timer0.start(500u64.millis()); timer0.listen(); - - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG1_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt23LevelPriority3, - ); timer1.start(1u64.secs()); timer1.listen(); diff --git a/esp32-hal/src/lib.rs b/esp32-hal/src/lib.rs index 0f897400ca0..702d2bce906 100644 --- a/esp32-hal/src/lib.rs +++ b/esp32-hal/src/lib.rs @@ -12,8 +12,8 @@ pub use esp_hal_common::{ pac, prelude, pulse_control, - spi, serial, + spi, utils, Cpu, Delay, diff --git a/esp32s2-hal/examples/serial_interrupts.rs b/esp32s2-hal/examples/serial_interrupts.rs index 2241d79fa62..e77ad11b1cf 100644 --- a/esp32s2-hal/examples/serial_interrupts.rs +++ b/esp32s2-hal/examples/serial_interrupts.rs @@ -48,11 +48,13 @@ fn main() -> ! { serial0.listen_at_cmd(); serial0.listen_rx_fifo_full(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::UART0, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::UART0, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + } timer0.start(1u64.secs()); diff --git a/esp32s2-hal/examples/systimer.rs b/esp32s2-hal/examples/systimer.rs index 797068efde5..de42f186e13 100644 --- a/esp32s2-hal/examples/systimer.rs +++ b/esp32s2-hal/examples/systimer.rs @@ -65,25 +65,25 @@ fn main() -> ! { (&ALARM0).lock(|data| (*data).replace(Some(alarm0))); (&ALARM1).lock(|data| (*data).replace(Some(alarm1))); (&ALARM2).lock(|data| (*data).replace(Some(alarm2))); - } - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET0, - interrupt::CpuInterrupt::Interrupt0LevelPriority1, - ); - - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET1, - interrupt::CpuInterrupt::Interrupt19LevelPriority2, - ); - - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET2, - interrupt::CpuInterrupt::Interrupt23LevelPriority3, - ); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET0, + interrupt::CpuInterrupt::Interrupt0LevelPriority1, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET1, + interrupt::CpuInterrupt::Interrupt19LevelPriority2, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET2, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + } // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. diff --git a/esp32s2-hal/examples/timer_interrupt.rs b/esp32s2-hal/examples/timer_interrupt.rs index 5364ac3330c..9de55376b08 100644 --- a/esp32s2-hal/examples/timer_interrupt.rs +++ b/esp32s2-hal/examples/timer_interrupt.rs @@ -41,19 +41,22 @@ fn main() -> ! { timer1.disable(); rtc_cntl.set_wdt_global_enable(false); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG0_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + } timer0.start(500u64.millis()); timer0.listen(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG1_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt23LevelPriority3, - ); timer1.start(1u64.secs()); timer1.listen(); diff --git a/esp32s2-hal/src/lib.rs b/esp32s2-hal/src/lib.rs index fbd193e42f4..0ee7c1197bc 100644 --- a/esp32s2-hal/src/lib.rs +++ b/esp32s2-hal/src/lib.rs @@ -11,8 +11,8 @@ pub use esp_hal_common::{ pac, prelude, pulse_control, - spi, serial, + spi, systimer, utils, Cpu, diff --git a/esp32s3-hal/examples/serial_interrupts.rs b/esp32s3-hal/examples/serial_interrupts.rs index 1822b1bbc17..bff349c7e67 100644 --- a/esp32s3-hal/examples/serial_interrupts.rs +++ b/esp32s3-hal/examples/serial_interrupts.rs @@ -48,11 +48,13 @@ fn main() -> ! { serial0.listen_at_cmd(); serial0.listen_rx_fifo_full(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::UART0, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::UART0, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + } timer0.start(1u64.secs()); diff --git a/esp32s3-hal/examples/systimer.rs b/esp32s3-hal/examples/systimer.rs index 9eaf000da53..39e229d0a94 100644 --- a/esp32s3-hal/examples/systimer.rs +++ b/esp32s3-hal/examples/systimer.rs @@ -61,25 +61,25 @@ fn main() -> ! { (&ALARM0).lock(|data| (*data).replace(Some(alarm0))); (&ALARM1).lock(|data| (*data).replace(Some(alarm1))); (&ALARM2).lock(|data| (*data).replace(Some(alarm2))); - } - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET0, - interrupt::CpuInterrupt::Interrupt0LevelPriority1, - ); - - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET1, - interrupt::CpuInterrupt::Interrupt19LevelPriority2, - ); - - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::SYSTIMER_TARGET2, - interrupt::CpuInterrupt::Interrupt23LevelPriority3, - ); + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET0, + interrupt::CpuInterrupt::Interrupt0LevelPriority1, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET1, + interrupt::CpuInterrupt::Interrupt19LevelPriority2, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::SYSTIMER_TARGET2, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + } // Initialize the Delay peripheral, and use it to toggle the LED state in a // loop. diff --git a/esp32s3-hal/examples/timer_interrupt.rs b/esp32s3-hal/examples/timer_interrupt.rs index a7db2d3c57e..f8a1fc82c17 100644 --- a/esp32s3-hal/examples/timer_interrupt.rs +++ b/esp32s3-hal/examples/timer_interrupt.rs @@ -41,19 +41,22 @@ fn main() -> ! { timer1.disable(); rtc_cntl.set_wdt_global_enable(false); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG0_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt20LevelPriority2, - ); + unsafe { + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG0_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt20LevelPriority2, + ); + + interrupt::enable( + Cpu::ProCpu, + pac::Interrupt::TG1_T0_LEVEL, + interrupt::CpuInterrupt::Interrupt23LevelPriority3, + ); + } timer0.start(500u64.millis()); timer0.listen(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG1_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt23LevelPriority3, - ); timer1.start(1u64.secs()); timer1.listen(); diff --git a/esp32s3-hal/src/lib.rs b/esp32s3-hal/src/lib.rs index 7c21ea0252a..1776b93f4eb 100644 --- a/esp32s3-hal/src/lib.rs +++ b/esp32s3-hal/src/lib.rs @@ -12,8 +12,8 @@ pub use esp_hal_common::{ pac, prelude, pulse_control, - spi, serial, + spi, systimer, usb_serial_jtag, utils,