diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f7586734f6f..00000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "editor.formatOnSave": true, - "rust-analyzer.cargo.buildScripts.enable": true, - "rust-analyzer.cargo.noDefaultFeatures": true, - "rust-analyzer.checkOnSave.allTargets": false, - "rust-analyzer.imports.granularity.enforce": true, - "rust-analyzer.imports.granularity.group": "crate", - "rust-analyzer.procMacro.attributes.enable": false, - "rust-analyzer.procMacro.enable": true, - // ----------------------------------------------------------------------- - // Since we have to handle multiple toolchains AND multiple targets, we - // we need to give Rust Analyzer some directions. - // - // Enable ONE target and linked project based on which chip you are - // developing for. This will propagate to the `esp-hal-common` crate too, - // as it is a dependency. Changing target/project requires reloading - // Rust Analyzer. - "rust-analyzer.cargo.target": "xtensa-esp32-none-elf", - // "rust-analyzer.cargo.target": "riscv32imc-unknown-none-elf", - // "rust-analyzer.cargo.target": "xtensa-esp32s2-none-elf", - // "rust-analyzer.cargo.target": "xtensa-esp32s3-none-elf", - "rust-analyzer.linkedProjects": [ - "esp32-hal/Cargo.toml", - // "esp32c3-hal/Cargo.toml", - // "esp32s2-hal/Cargo.toml", - // "esp32s3-hal/Cargo.toml", - ], -} \ No newline at end of file diff --git a/esp-hal-common/src/interrupt/riscv.rs b/esp-hal-common/src/interrupt/riscv.rs index 158b9afbbce..805a556eca4 100644 --- a/esp-hal-common/src/interrupt/riscv.rs +++ b/esp-hal-common/src/interrupt/riscv.rs @@ -1,6 +1,21 @@ +//! Interrupt handling - RISCV +//! +//! When the `vectored` feature is enabled, CPU interrupts 1 through 15 are +//! reserved for each of the possible interrupt priorities. +//! +//! ```rust +//! interrupt1() => Priority::Priority1 +//! interrupt2() => Priority::Priority2 +//! ... +//! interrupt15() => Priority::Priority15 +//! ``` + use riscv::register::mcause; -use crate::{pac::Interrupt, Cpu}; +use crate::{ + pac::{self, Interrupt}, + Cpu, +}; // User code shouldn't usually take the mutable TrapFrame or the TrapFrame in // general. However this makes things like preemtive multitasking easier in @@ -50,6 +65,8 @@ pub enum InterruptKind { /// Enumeration of available CPU interrupts. /// It is possible to create a handler for each of the interrupts. (e.g. /// `interrupt3`) +#[repr(u32)] +#[derive(Debug, Copy, Clone)] pub enum CpuInterrupt { Interrupt1 = 1, Interrupt2, @@ -85,6 +102,7 @@ pub enum CpuInterrupt { } /// Interrupt priority levels. +#[repr(u8)] pub enum Priority { None, Priority1, @@ -104,21 +122,26 @@ pub enum Priority { Priority15, } -/// 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 = &*crate::pac::INTERRUPT_CORE0::PTR; - let intr_map_base = intr.mac_intr_map.as_ptr(); - intr_map_base - .offset(interrupt_number) - .write_volatile(cpu_interrupt_number as u32); +/// Assign a peripheral interrupt to an CPU interrupt. +/// +/// Great care must be taken when using the `vectored` feature (enabled by +/// default). Avoid interrupts 1 - 15 when interrupt vectoring is enabled. +pub unsafe fn map(_core: Cpu, interrupt: Interrupt, which: CpuInterrupt) { + let interrupt_number = interrupt as isize; + let cpu_interrupt_number = which as isize; + let intr = &*crate::pac::INTERRUPT_CORE0::PTR; + let intr_map_base = intr.mac_intr_map.as_ptr(); + intr_map_base + .offset(interrupt_number) + .write_volatile(cpu_interrupt_number as u32); +} - // enable interrupt - intr.cpu_int_enable - .modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); - } +/// Enable a CPU interrupt +pub unsafe fn enable_cpu_interrupt(which: CpuInterrupt) { + let cpu_interrupt_number = which as isize; + let intr = &*crate::pac::INTERRUPT_CORE0::PTR; + intr.cpu_int_enable + .modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); } /// Disable the given peripheral interrupt. @@ -132,6 +155,9 @@ pub fn disable(_core: Cpu, interrupt: Interrupt) { } /// Set the interrupt kind (i.e. level or edge) of an CPU interrupt +/// +/// This is safe to call when the `vectored` feature is enabled. The vectored +/// interrupt handler will take care of clearing edge interrupt bits. pub fn set_kind(_core: Cpu, which: CpuInterrupt, kind: InterruptKind) { unsafe { let intr = &*crate::pac::INTERRUPT_CORE0::PTR; @@ -150,19 +176,22 @@ pub fn set_kind(_core: Cpu, which: CpuInterrupt, kind: InterruptKind) { } /// Set the priority level of an CPU interrupt -pub fn set_priority(_core: Cpu, which: CpuInterrupt, priority: Priority) { - unsafe { - let intr = &*crate::pac::INTERRUPT_CORE0::PTR; - let cpu_interrupt_number = which as isize; - let intr_prio_base = intr.cpu_int_pri_0.as_ptr(); +/// +/// Great care must be taken when using the `vectored` feature (enabled by +/// default). Avoid changing the priority of interrupts 1 - 15 when interrupt +/// vectoring is enabled. +pub unsafe fn set_priority(_core: Cpu, which: CpuInterrupt, priority: Priority) { + let intr = &*crate::pac::INTERRUPT_CORE0::PTR; + let cpu_interrupt_number = which as isize; + let intr_prio_base = intr.cpu_int_pri_0.as_ptr(); - intr_prio_base - .offset(cpu_interrupt_number as isize) - .write_volatile(priority as u32); - } + intr_prio_base + .offset(cpu_interrupt_number as isize) + .write_volatile(priority as u32); } /// Clear a CPU interrupt +#[inline] pub fn clear(_core: Cpu, which: CpuInterrupt) { unsafe { let cpu_interrupt_number = which as isize; @@ -173,6 +202,7 @@ pub fn clear(_core: Cpu, which: CpuInterrupt) { } /// Get status of peripheral interrupts +#[inline] pub fn get_status(_core: Cpu) -> u128 { unsafe { ((*crate::pac::INTERRUPT_CORE0::PTR) @@ -187,6 +217,204 @@ pub fn get_status(_core: Cpu) -> u128 { } } +#[cfg(feature = "vectored")] +pub use vectored::*; + +#[cfg(feature = "vectored")] +mod vectored { + use procmacros::ram; + + use super::*; + + // Setup interrupts 1-15 ready for vectoring + #[doc(hidden)] + pub(crate) unsafe fn init_vectoring() { + for i in 1..=15 { + set_kind( + crate::get_core(), + core::mem::transmute(i), + InterruptKind::Level, + ); + set_priority( + crate::get_core(), + core::mem::transmute(i), + core::mem::transmute(i as u8), + ); + enable_cpu_interrupt(core::mem::transmute(i)); + } + } + + /// Get the interrupts configured for the core + #[inline] + fn get_configured_interrupts(_core: Cpu) -> [u128; 15] { + unsafe { + let intr = &*crate::pac::INTERRUPT_CORE0::PTR; + let intr_map_base = intr.mac_intr_map.as_ptr(); + let intr_prio_base = intr.cpu_int_pri_0.as_ptr(); + + let mut prios = [0u128; 15]; + + for i in 0..get_interrupt_count() { + let i = i as isize; + let cpu_interrupt = intr_map_base.offset(i).read_volatile(); + // safety: cast is safe because of repr(u32) + let cpu_interrupt: CpuInterrupt = core::mem::transmute(cpu_interrupt); + let prio = intr_prio_base + .offset(cpu_interrupt as isize) + .read_volatile(); + + prios[prio as usize] |= 1 << i; + } + + prios + } + } + + #[inline] + fn get_interrupt_count() -> usize { + cfg_if::cfg_if! { + if #[cfg(feature = "esp32c3")] { + 62 + } + } + } + + /// Interrupt Error + #[derive(Copy, Clone, Debug, PartialEq, Eq)] + pub enum Error { + InvalidInterruptPriority, + } + + /// Enables a interrupt at a given priority + /// + /// Note that interrupts still need to be enabled globally for interrupts + /// to be serviced. + pub fn enable(interrupt: Interrupt, level: Priority) -> Result<(), Error> { + if matches!(level, Priority::None) { + return Err(Error::InvalidInterruptPriority); + } + unsafe { + let cpu_interrupt = core::mem::transmute(level as u8 as u32); + map(crate::get_core(), interrupt, cpu_interrupt); + enable_cpu_interrupt(cpu_interrupt); + } + Ok(()) + } + + #[ram] + unsafe fn handle_interrupts(cpu_intr: CpuInterrupt, context: &mut TrapFrame) { + let status = get_status(crate::get_core()); + + // this has no effect on level interrupts, but the interrupt may be an edge one + // so we clear it anyway + clear(crate::get_core(), cpu_intr); + + let configured_interrupts = get_configured_interrupts(crate::get_core()); + let mut interrupt_mask = status & configured_interrupts[cpu_intr as usize]; + while interrupt_mask != 0 { + let interrupt_nr = interrupt_mask.trailing_zeros(); + // Interrupt::try_from can fail if interrupt already de-asserted: + // silently ignore + if let Ok(interrupt) = pac::Interrupt::try_from(interrupt_nr as u8) { + handle_interrupt(interrupt, context) + } + interrupt_mask &= !(1u128 << interrupt_nr); + } + } + + #[ram] + unsafe fn handle_interrupt(interrupt: Interrupt, save_frame: &mut TrapFrame) { + extern "C" { + // defined in each hal + fn EspDefaultHandler(interrupt: Interrupt); + } + let handler = pac::__EXTERNAL_INTERRUPTS[interrupt as usize]._handler; + if handler as *const _ == EspDefaultHandler as *const unsafe extern "C" fn() { + EspDefaultHandler(interrupt); + } else { + let handler: fn(&mut TrapFrame) = core::mem::transmute(handler); + handler(save_frame); + } + } + + #[no_mangle] + #[ram] + pub unsafe fn interrupt1(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt1, context) + } + + #[no_mangle] + #[ram] + pub unsafe fn interrupt2(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt2, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt3(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt3, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt4(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt4, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt5(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt5, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt6(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt6, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt7(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt7, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt8(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt8, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt9(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt9, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt10(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt10, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt11(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt11, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt12(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt12, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt13(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt13, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt14(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt14, context) + } + #[no_mangle] + #[ram] + pub unsafe fn interrupt15(context: &mut TrapFrame) { + handle_interrupts(CpuInterrupt::Interrupt15, context) + } +} + /// Registers saved in trap handler #[doc(hidden)] #[allow(missing_docs)] @@ -234,6 +462,7 @@ pub struct TrapFrame { #[export_name = "_start_trap_rust_hal"] pub unsafe extern "C" fn start_trap_rust_hal(trap_frame: *mut TrapFrame) { extern "C" { + // defined in riscv-rt pub fn DefaultHandler(); } @@ -385,5 +614,8 @@ pub fn _setup_interrupts() { unsafe { let vec_table = &_vector_table_hal as *const _ as usize; riscv::register::mtvec::write(vec_table, riscv::register::mtvec::TrapMode::Vectored); + + #[cfg(feature = "vectored")] + crate::interrupt::init_vectoring(); }; } diff --git a/esp-hal-common/src/interrupt/xtensa.rs b/esp-hal-common/src/interrupt/xtensa.rs index 5e7bb38afc6..5826db7d280 100644 --- a/esp-hal-common/src/interrupt/xtensa.rs +++ b/esp-hal-common/src/interrupt/xtensa.rs @@ -184,7 +184,7 @@ unsafe fn core1_interrupt_peripheral() -> *const crate::pac::interrupt_core1::Re pub use vectored::*; #[cfg(feature = "vectored")] -pub mod vectored { +mod vectored { use procmacros::ram; use super::*; @@ -429,12 +429,12 @@ pub mod vectored { unsafe fn handle_interrupt(level: u32, interrupt: Interrupt, save_frame: &mut Context) { extern "C" { // defined in each hal - fn DefaultHandler(level: u32, interrupt: Interrupt); + fn EspDefaultHandler(level: u32, interrupt: Interrupt); } let handler = pac::__INTERRUPTS[interrupt.number() as usize]._handler; - if handler as *const _ == DefaultHandler as *const unsafe extern "C" fn() { - DefaultHandler(level, interrupt); + if handler as *const _ == EspDefaultHandler as *const unsafe extern "C" fn() { + EspDefaultHandler(level, interrupt); } else { let handler: fn(&mut Context) = core::mem::transmute(handler); handler(save_frame); diff --git a/esp32-hal/examples/gpio_interrupt.rs b/esp32-hal/examples/gpio_interrupt.rs index b8ee22de53b..ca8cb31b906 100644 --- a/esp32-hal/examples/gpio_interrupt.rs +++ b/esp32-hal/examples/gpio_interrupt.rs @@ -54,7 +54,7 @@ fn main() -> ! { interrupt::enable( pac::Interrupt::GPIO, - interrupt::vectored::Priority::Priority2, + interrupt::Priority::Priority2, ) .unwrap(); diff --git a/esp32-hal/src/lib.rs b/esp32-hal/src/lib.rs index 86641cc49a0..c8101b90941 100644 --- a/esp32-hal/src/lib.rs +++ b/esp32-hal/src/lib.rs @@ -36,7 +36,10 @@ pub mod analog { } #[no_mangle] -extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} +extern "C" fn EspDefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} + +#[no_mangle] +extern "C" fn DefaultHandler() {} /// Function initializes ESP32 specific memories (RTC slow and fast) and /// then calls original Reset function diff --git a/esp32c3-hal/.vscode/settings.json b/esp32c3-hal/.vscode/settings.json deleted file mode 100644 index e0839ba9dec..00000000000 --- a/esp32c3-hal/.vscode/settings.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "rust-analyzer.cargo.features": [], - "rust-analyzer.cargo.allFeatures": false, - "editor.formatOnSave": true, - "rust-analyzer.checkOnSave.allTargets": false, - "rust-analyzer.checkOnSave.allFeatures": false, - "rust-analyzer.checkOnSave.overrideCommand": [ - "cargo", - "check", - "--message-format=json", - "-Z", - "build-std=core", - "--examples" - ], - "rust-analyzer.cargo.buildScripts.enable": false -} \ No newline at end of file diff --git a/esp32c3-hal/Cargo.toml b/esp32c3-hal/Cargo.toml index 0eb5000de79..6f4053bea17 100644 --- a/esp32c3-hal/Cargo.toml +++ b/esp32c3-hal/Cargo.toml @@ -43,12 +43,13 @@ smart-leds = "0.3" esp-println = { version = "0.2.0", features = ["esp32c3"] } [features] -default = ["rt"] +default = ["rt", "vectored"] direct-boot = [] eh1 = ["esp-hal-common/eh1"] rt = ["riscv-rt"] smartled = ["esp-hal-common/smartled"] ufmt = ["esp-hal-common/ufmt"] +vectored = ["esp-hal-common/vectored"] [[example]] name = "hello_rgb" diff --git a/esp32c3-hal/examples/gpio_interrupt.rs b/esp32c3-hal/examples/gpio_interrupt.rs index ae7f0a6d6af..67980438c13 100644 --- a/esp32c3-hal/examples/gpio_interrupt.rs +++ b/esp32c3-hal/examples/gpio_interrupt.rs @@ -6,7 +6,7 @@ #![no_std] #![no_main] -use core::{cell::RefCell, fmt::Write}; +use core::cell::RefCell; use bare_metal::Mutex; use esp32c3_hal::{ @@ -14,18 +14,15 @@ use esp32c3_hal::{ gpio::{Gpio9, IO}, gpio_types::{Event, Input, Pin, PullDown}, interrupt, - pac::{self, Peripherals, UART0}, + pac::{self, Peripherals}, prelude::*, timer::TimerGroup, - Cpu, Delay, RtcCntl, - Serial, }; use panic_halt as _; use riscv_rt::entry; -static mut SERIAL: Mutex>>> = Mutex::new(RefCell::new(None)); static mut BUTTON: Mutex>>>> = Mutex::new(RefCell::new(None)); #[entry] @@ -41,7 +38,6 @@ fn main() -> ! { let mut wdt0 = timer_group0.wdt; let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); let mut wdt1 = timer_group1.wdt; - let serial0 = Serial::new(peripherals.UART0); rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); @@ -57,25 +53,10 @@ fn main() -> ! { button.listen(Event::FallingEdge); riscv::interrupt::free(|_cs| unsafe { - SERIAL.get_mut().replace(Some(serial0)); BUTTON.get_mut().replace(Some(button)); }); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::GPIO, - interrupt::CpuInterrupt::Interrupt3, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, - interrupt::InterruptKind::Level, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, - interrupt::Priority::Priority1, - ); + interrupt::enable(pac::Interrupt::GPIO, interrupt::Priority::Priority3).unwrap(); unsafe { riscv::interrupt::enable(); @@ -88,17 +69,12 @@ fn main() -> ! { } } -#[no_mangle] -pub fn interrupt3() { +#[interrupt] +fn GPIO() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); let mut button = BUTTON.borrow(*cs).borrow_mut(); let button = button.as_mut().unwrap(); - - writeln!(serial, "Interrupt").ok(); - - interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt3); + esp_println::println!("GPIO interrupt"); button.clear_interrupt(); }); } diff --git a/esp32c3-hal/examples/serial_interrupts.rs b/esp32c3-hal/examples/serial_interrupts.rs index 6d7214ff46b..fd5821465bb 100644 --- a/esp32c3-hal/examples/serial_interrupts.rs +++ b/esp32c3-hal/examples/serial_interrupts.rs @@ -56,21 +56,12 @@ fn main() -> ! { SERIAL.get_mut().replace(Some(serial0)); }); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::UART0, - interrupt::CpuInterrupt::Interrupt3, - ); + interrupt::enable(pac::Interrupt::UART0, interrupt::Priority::Priority1).unwrap(); interrupt::set_kind( Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, + interrupt::CpuInterrupt::Interrupt1, // Interrupt 1 handles priority one interrupts interrupt::InterruptKind::Edge, ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, - interrupt::Priority::Priority1, - ); unsafe { riscv::interrupt::enable(); @@ -88,8 +79,8 @@ fn main() -> ! { } } -#[no_mangle] -pub fn interrupt3() { +#[interrupt] +fn UART0() { riscv::interrupt::free(|cs| unsafe { let mut serial = SERIAL.borrow(*cs).borrow_mut(); let serial = serial.as_mut().unwrap(); @@ -110,6 +101,5 @@ pub fn interrupt3() { serial.reset_at_cmd_interrupt(); serial.reset_rx_fifo_full_interrupt(); - interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt3); }); } diff --git a/esp32c3-hal/examples/systimer.rs b/esp32c3-hal/examples/systimer.rs index dfd60cca1a2..172d7e82873 100644 --- a/esp32c3-hal/examples/systimer.rs +++ b/esp32c3-hal/examples/systimer.rs @@ -4,24 +4,22 @@ #![no_std] #![no_main] -use core::{cell::RefCell, fmt::Write}; +use core::cell::RefCell; use bare_metal::Mutex; use esp32c3_hal::{ clock::ClockControl, interrupt, - pac::{self, Peripherals, UART0}, + pac::{self, Peripherals}, prelude::*, systimer::{Alarm, SystemTimer, Target}, timer::TimerGroup, Cpu, RtcCntl, - Serial, }; use panic_halt as _; use riscv_rt::entry; -static mut SERIAL: Mutex>>> = Mutex::new(RefCell::new(None)); static mut ALARM0: Mutex>>> = Mutex::new(RefCell::new(None)); static mut ALARM1: Mutex>>> = Mutex::new(RefCell::new(None)); static mut ALARM2: Mutex>>> = Mutex::new(RefCell::new(None)); @@ -40,18 +38,14 @@ fn main() -> ! { let timer_group1 = TimerGroup::new(peripherals.TIMG1, &clocks); let mut wdt1 = timer_group1.wdt; - let mut serial0 = Serial::new(peripherals.UART0); - rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); wdt0.disable(); wdt1.disable(); - writeln!(serial0, "SYSTIMER Demo start!").ok(); - let syst = SystemTimer::new(peripherals.SYSTIMER); - writeln!(serial0, "SYSTIMER Current value = {}", SystemTimer::now()).ok(); + esp_println::println!("SYSTIMER Current value = {}", SystemTimer::now()); let alarm0 = syst.alarm0; alarm0.set_target(40_000_000); @@ -66,53 +60,22 @@ fn main() -> ! { alarm2.enable_interrupt(); interrupt::enable( - Cpu::ProCpu, pac::Interrupt::SYSTIMER_TARGET0, - interrupt::CpuInterrupt::Interrupt1, - ); + interrupt::Priority::Priority1, + ) + .unwrap(); interrupt::enable( - Cpu::ProCpu, pac::Interrupt::SYSTIMER_TARGET1, - interrupt::CpuInterrupt::Interrupt2, - ); + interrupt::Priority::Priority1, + ) + .unwrap(); interrupt::enable( - Cpu::ProCpu, pac::Interrupt::SYSTIMER_TARGET2, - interrupt::CpuInterrupt::Interrupt3, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt1, - interrupt::InterruptKind::Level, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt2, - interrupt::InterruptKind::Level, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, - interrupt::InterruptKind::Level, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt1, - interrupt::Priority::Priority1, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt2, - interrupt::Priority::Priority1, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt3, interrupt::Priority::Priority1, - ); + ) + .unwrap(); riscv::interrupt::free(|_cs| unsafe { - SERIAL.get_mut().replace(Some(serial0)); ALARM0.get_mut().replace(Some(alarm0)); ALARM1.get_mut().replace(Some(alarm1)); ALARM2.get_mut().replace(Some(alarm2)); @@ -125,12 +88,10 @@ fn main() -> ! { loop {} } -#[no_mangle] -pub fn interrupt1() { +#[interrupt] +fn SYSTIMER_TARGET0() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt 1 = {}", SystemTimer::now()).ok(); + esp_println::println!("Interrupt 1 = {}", SystemTimer::now()); let mut alarm = ALARM0.borrow(*cs).borrow_mut(); let alarm = alarm.as_mut().unwrap(); @@ -140,12 +101,10 @@ pub fn interrupt1() { }); } -#[no_mangle] -pub fn interrupt2() { +#[interrupt] +fn SYSTIMER_TARGET1() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt 2 = {}", SystemTimer::now()).ok(); + esp_println::println!("Interrupt 2 = {}", SystemTimer::now()); let mut alarm = ALARM1.borrow(*cs).borrow_mut(); let alarm = alarm.as_mut().unwrap(); @@ -155,12 +114,10 @@ pub fn interrupt2() { }); } -#[no_mangle] -pub fn interrupt3() { +#[interrupt] +fn SYSTIMER_TARGET2() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt 3 = {}", SystemTimer::now()).ok(); + esp_println::println!("Interrupt 3 = {}", SystemTimer::now()); let mut alarm = ALARM2.borrow(*cs).borrow_mut(); let alarm = alarm.as_mut().unwrap(); diff --git a/esp32c3-hal/examples/timer_interrupt.rs b/esp32c3-hal/examples/timer_interrupt.rs index 81f398b5429..8253d61641f 100644 --- a/esp32c3-hal/examples/timer_interrupt.rs +++ b/esp32c3-hal/examples/timer_interrupt.rs @@ -5,24 +5,21 @@ #![no_std] #![no_main] -use core::{cell::RefCell, fmt::Write}; +use core::cell::RefCell; use bare_metal::Mutex; use esp32c3_hal::{ clock::ClockControl, interrupt, - pac::{self, Peripherals, TIMG0, TIMG1, UART0}, + pac::{self, Peripherals, TIMG0, TIMG1}, prelude::*, timer::{Timer0, TimerGroup}, - Cpu, RtcCntl, - Serial, }; use esp_hal_common::Timer; use panic_halt as _; use riscv_rt::entry; -static mut SERIAL: Mutex>>> = Mutex::new(RefCell::new(None)); static mut TIMER0: Mutex>>>> = Mutex::new(RefCell::new(None)); static mut TIMER1: Mutex>>>> = Mutex::new(RefCell::new(None)); @@ -42,53 +39,20 @@ fn main() -> ! { let mut timer1 = timer_group1.timer0; let mut wdt1 = timer_group1.wdt; - let serial0 = Serial::new(peripherals.UART0); - rtc_cntl.set_super_wdt_enable(false); rtc_cntl.set_wdt_enable(false); wdt0.disable(); wdt1.disable(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG0_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt1, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt1, - interrupt::InterruptKind::Level, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt1, - interrupt::Priority::Priority1, - ); - + interrupt::enable(pac::Interrupt::TG0_T0_LEVEL, interrupt::Priority::Priority1).unwrap(); timer0.start(500u64.millis()); timer0.listen(); - interrupt::enable( - Cpu::ProCpu, - pac::Interrupt::TG1_T0_LEVEL, - interrupt::CpuInterrupt::Interrupt11, - ); - interrupt::set_kind( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt11, - interrupt::InterruptKind::Level, - ); - interrupt::set_priority( - Cpu::ProCpu, - interrupt::CpuInterrupt::Interrupt11, - interrupt::Priority::Priority1, - ); - + interrupt::enable(pac::Interrupt::TG1_T0_LEVEL, interrupt::Priority::Priority1).unwrap(); timer1.start(1u64.secs()); timer1.listen(); riscv::interrupt::free(|_cs| unsafe { - SERIAL.get_mut().replace(Some(serial0)); TIMER0.get_mut().replace(Some(timer0)); TIMER1.get_mut().replace(Some(timer1)); }); @@ -100,36 +64,28 @@ fn main() -> ! { loop {} } -#[no_mangle] -pub fn interrupt1() { +#[interrupt] +fn TG0_T0_LEVEL() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt 1").ok(); + esp_println::println!("Interrupt 1"); let mut timer0 = TIMER0.borrow(*cs).borrow_mut(); let timer0 = timer0.as_mut().unwrap(); - interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt1); timer0.clear_interrupt(); - timer0.start(500u64.millis()); }); } -#[no_mangle] -pub fn interrupt11() { +#[interrupt] +fn TG1_T0_LEVEL() { riscv::interrupt::free(|cs| unsafe { - let mut serial = SERIAL.borrow(*cs).borrow_mut(); - let serial = serial.as_mut().unwrap(); - writeln!(serial, "Interrupt 11").ok(); + esp_println::println!("Interrupt 11"); let mut timer1 = TIMER1.borrow(*cs).borrow_mut(); let timer1 = timer1.as_mut().unwrap(); - interrupt::clear(Cpu::ProCpu, interrupt::CpuInterrupt::Interrupt11); timer1.clear_interrupt(); - timer1.start(1u64.secs()); }); } diff --git a/esp32c3-hal/ld/hal-defaults.x b/esp32c3-hal/ld/hal-defaults.x index 469d127923f..a7bbdbb0bb7 100644 --- a/esp32c3-hal/ld/hal-defaults.x +++ b/esp32c3-hal/ld/hal-defaults.x @@ -29,3 +29,5 @@ PROVIDE(interrupt28 = DefaultHandler); PROVIDE(interrupt29 = DefaultHandler); PROVIDE(interrupt30 = DefaultHandler); PROVIDE(interrupt31 = DefaultHandler); + +INCLUDE "device.x" diff --git a/esp32c3-hal/src/lib.rs b/esp32c3-hal/src/lib.rs index 9abecd22fe4..475076ee9b3 100644 --- a/esp32c3-hal/src/lib.rs +++ b/esp32c3-hal/src/lib.rs @@ -310,3 +310,6 @@ pub fn mp_hook() -> bool { fn gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8 { int_enable as u8 | ((nmi_enable as u8) << 1) } + +#[no_mangle] +extern "C" fn EspDefaultHandler(_interrupt: pac::Interrupt) {} diff --git a/esp32s2-hal/examples/gpio_interrupt.rs b/esp32s2-hal/examples/gpio_interrupt.rs index 4d6018f46d1..51616cf73da 100644 --- a/esp32s2-hal/examples/gpio_interrupt.rs +++ b/esp32s2-hal/examples/gpio_interrupt.rs @@ -54,7 +54,7 @@ fn main() -> ! { interrupt::enable( pac::Interrupt::GPIO, - interrupt::vectored::Priority::Priority2, + interrupt::Priority::Priority2, ) .unwrap(); diff --git a/esp32s2-hal/src/lib.rs b/esp32s2-hal/src/lib.rs index 55314dc976a..b9218fb4d94 100644 --- a/esp32s2-hal/src/lib.rs +++ b/esp32s2-hal/src/lib.rs @@ -36,7 +36,10 @@ pub mod analog { } #[no_mangle] -extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} +extern "C" fn EspDefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} + +#[no_mangle] +extern "C" fn DefaultHandler() {} /// Function initializes ESP32 specific memories (RTC slow and fast) and /// then calls original Reset function diff --git a/esp32s3-hal/examples/gpio_interrupt.rs b/esp32s3-hal/examples/gpio_interrupt.rs index a98138b1622..f26cbbcc5aa 100644 --- a/esp32s3-hal/examples/gpio_interrupt.rs +++ b/esp32s3-hal/examples/gpio_interrupt.rs @@ -54,7 +54,7 @@ fn main() -> ! { interrupt::enable( pac::Interrupt::GPIO, - interrupt::vectored::Priority::Priority2, + interrupt::Priority::Priority2, ) .unwrap(); diff --git a/esp32s3-hal/src/lib.rs b/esp32s3-hal/src/lib.rs index 4c7f3beaae8..eb1af2c02bb 100644 --- a/esp32s3-hal/src/lib.rs +++ b/esp32s3-hal/src/lib.rs @@ -34,7 +34,10 @@ pub use self::gpio::IO; pub mod gpio; #[no_mangle] -extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} +extern "C" fn EspDefaultHandler(_level: u32, _interrupt: pac::Interrupt) {} + +#[no_mangle] +extern "C" fn DefaultHandler() {} #[cfg(all(feature = "rt", feature = "direct-boot"))] #[doc(hidden)]