mirror of
				https://github.com/esp-rs/esp-hal.git
				synced 2025-11-04 06:43:55 +00:00 
			
		
		
		
	* Update `esp32-hal` examples * Update `esp32c2-hal` examples * Update `esp32c3-hal` examples * Update `esp32c6-hal` examples * Update `esp32h2-hal` examples * Update `esp32s2-hal` examples * Update `esp32s3-hal` examples * Fix the `ram.rs` examples
		
			
				
	
	
		
			135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
//! Interrupt Preemption
 | 
						|
//!
 | 
						|
//! An example of how an interrupt can be preempted by another with higher
 | 
						|
//! priority. Should show higher-numbered software interrupts happening during
 | 
						|
//! the handling of lower-numbered ones.
 | 
						|
 | 
						|
#![no_std]
 | 
						|
#![no_main]
 | 
						|
 | 
						|
use core::cell::RefCell;
 | 
						|
 | 
						|
use critical_section::Mutex;
 | 
						|
use esp32c3_hal::{
 | 
						|
    clock::ClockControl,
 | 
						|
    interrupt::{self},
 | 
						|
    peripherals::{self, Peripherals},
 | 
						|
    prelude::*,
 | 
						|
    riscv,
 | 
						|
    system::{SoftwareInterrupt, SoftwareInterruptControl},
 | 
						|
    timer::TimerGroup,
 | 
						|
    Rtc,
 | 
						|
};
 | 
						|
use esp_backtrace as _;
 | 
						|
 | 
						|
static SWINT: Mutex<RefCell<Option<SoftwareInterruptControl>>> = Mutex::new(RefCell::new(None));
 | 
						|
 | 
						|
#[entry]
 | 
						|
fn main() -> ! {
 | 
						|
    let peripherals = Peripherals::take();
 | 
						|
    let mut system = peripherals.SYSTEM.split();
 | 
						|
    let clockctrl = system.clock_control;
 | 
						|
    let sw_int = system.software_interrupt_control;
 | 
						|
    let clocks = ClockControl::boot_defaults(clockctrl).freeze();
 | 
						|
 | 
						|
    critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
 | 
						|
 | 
						|
    interrupt::enable(
 | 
						|
        peripherals::Interrupt::FROM_CPU_INTR0,
 | 
						|
        interrupt::Priority::Priority1,
 | 
						|
    )
 | 
						|
    .unwrap();
 | 
						|
    interrupt::enable(
 | 
						|
        peripherals::Interrupt::FROM_CPU_INTR1,
 | 
						|
        interrupt::Priority::Priority2,
 | 
						|
    )
 | 
						|
    .unwrap();
 | 
						|
    interrupt::enable(
 | 
						|
        peripherals::Interrupt::FROM_CPU_INTR2,
 | 
						|
        interrupt::Priority::Priority2,
 | 
						|
    )
 | 
						|
    .unwrap();
 | 
						|
    interrupt::enable(
 | 
						|
        peripherals::Interrupt::FROM_CPU_INTR3,
 | 
						|
        interrupt::Priority::Priority15,
 | 
						|
    )
 | 
						|
    .unwrap();
 | 
						|
    unsafe { riscv::interrupt::enable() }
 | 
						|
 | 
						|
    // raise mid priority interrupt.
 | 
						|
    // The handler raises one interrupt at lower priority, one at same and one at
 | 
						|
    // higher. We expect to see the higher priority served immeiately before
 | 
						|
    // exiting the handler Once the handler is exited we expect to see same
 | 
						|
    // priority and low priority interrupts served in that order
 | 
						|
    critical_section::with(|cs| {
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .raise(SoftwareInterrupt::SoftwareInterrupt1);
 | 
						|
    });
 | 
						|
    loop {}
 | 
						|
}
 | 
						|
 | 
						|
#[interrupt]
 | 
						|
fn FROM_CPU_INTR0() {
 | 
						|
    esp_println::println!("SW interrupt0");
 | 
						|
    critical_section::with(|cs| {
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .reset(SoftwareInterrupt::SoftwareInterrupt0);
 | 
						|
    });
 | 
						|
}
 | 
						|
#[interrupt]
 | 
						|
fn FROM_CPU_INTR1() {
 | 
						|
    esp_println::println!("SW interrupt1 entry");
 | 
						|
    critical_section::with(|cs| {
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .reset(SoftwareInterrupt::SoftwareInterrupt1);
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .raise(SoftwareInterrupt::SoftwareInterrupt2); // raise interrupt at same priority
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .raise(SoftwareInterrupt::SoftwareInterrupt3); // raise interrupt at higher priority
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .raise(SoftwareInterrupt::SoftwareInterrupt0); // raise interrupt at
 | 
						|
                                                           // lower priority
 | 
						|
    });
 | 
						|
    esp_println::println!("SW interrupt1 exit");
 | 
						|
}
 | 
						|
#[interrupt]
 | 
						|
fn FROM_CPU_INTR2() {
 | 
						|
    esp_println::println!("SW interrupt2");
 | 
						|
    critical_section::with(|cs| {
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .reset(SoftwareInterrupt::SoftwareInterrupt2);
 | 
						|
    });
 | 
						|
}
 | 
						|
#[interrupt]
 | 
						|
fn FROM_CPU_INTR3() {
 | 
						|
    esp_println::println!("SW interrupt3");
 | 
						|
    critical_section::with(|cs| {
 | 
						|
        SWINT
 | 
						|
            .borrow_ref_mut(cs)
 | 
						|
            .as_mut()
 | 
						|
            .unwrap()
 | 
						|
            .reset(SoftwareInterrupt::SoftwareInterrupt3);
 | 
						|
    });
 | 
						|
}
 |