mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-01 22:31:23 +00:00
Added software interrupt API, examples for all of the MCUs
This commit is contained in:
parent
9ff3837537
commit
3d3b71924b
@ -15,9 +15,18 @@ use crate::peripheral::PeripheralRef;
|
||||
type SystemPeripheral = crate::peripherals::DPORT;
|
||||
#[cfg(esp32c6)]
|
||||
type SystemPeripheral = crate::peripherals::PCR;
|
||||
#[cfg(esp32c6)]
|
||||
type IntPri = crate::peripherals::INTPRI;
|
||||
#[cfg(not(any(esp32, esp32c6)))]
|
||||
type SystemPeripheral = crate::peripherals::SYSTEM;
|
||||
|
||||
pub enum SoftwareInterrupt {
|
||||
SoftwareInterrupt0,
|
||||
SoftwareInterrupt1,
|
||||
SoftwareInterrupt2,
|
||||
SoftwareInterrupt3,
|
||||
}
|
||||
|
||||
/// Peripherals which can be enabled via [PeripheralClockControl]
|
||||
pub enum Peripheral {
|
||||
#[cfg(spi2)]
|
||||
@ -70,6 +79,67 @@ pub enum Peripheral {
|
||||
#[cfg(rsa)]
|
||||
Rsa,
|
||||
}
|
||||
pub struct SoftwareInterruptControl {
|
||||
_private: (),
|
||||
}
|
||||
impl SoftwareInterruptControl {
|
||||
pub fn raise(&mut self, interrupt: SoftwareInterrupt) {
|
||||
#[cfg(not(esp32c6))]
|
||||
let system = unsafe { &*SystemPeripheral::PTR };
|
||||
#[cfg(esp32c6)]
|
||||
let system = unsafe { &*IntPri::PTR };
|
||||
match interrupt {
|
||||
SoftwareInterrupt::SoftwareInterrupt0 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_0
|
||||
.write(|w| w.cpu_intr_from_cpu_0().bit(true));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt1 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_1
|
||||
.write(|w| w.cpu_intr_from_cpu_1().bit(true));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt2 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_2
|
||||
.write(|w| w.cpu_intr_from_cpu_2().bit(true));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt3 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_3
|
||||
.write(|w| w.cpu_intr_from_cpu_3().bit(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn reset(&mut self, interrupt: SoftwareInterrupt) {
|
||||
#[cfg(not(esp32c6))]
|
||||
let system = unsafe { &*SystemPeripheral::PTR };
|
||||
#[cfg(esp32c6)]
|
||||
let system = unsafe { &*IntPri::PTR };
|
||||
match interrupt {
|
||||
SoftwareInterrupt::SoftwareInterrupt0 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_0
|
||||
.write(|w| w.cpu_intr_from_cpu_0().bit(false));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt1 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_1
|
||||
.write(|w| w.cpu_intr_from_cpu_1().bit(false));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt2 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_2
|
||||
.write(|w| w.cpu_intr_from_cpu_2().bit(false));
|
||||
}
|
||||
SoftwareInterrupt::SoftwareInterrupt3 => {
|
||||
system
|
||||
.cpu_intr_from_cpu_3
|
||||
.write(|w| w.cpu_intr_from_cpu_3().bit(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Controls the enablement of peripheral clocks.
|
||||
pub struct PeripheralClockControl {
|
||||
@ -480,6 +550,7 @@ pub struct SystemParts<'d> {
|
||||
#[cfg(pdma)]
|
||||
pub dma: Dma,
|
||||
pub radio_clock_control: RadioClockControl,
|
||||
pub software_interrupt_control: SoftwareInterruptControl,
|
||||
}
|
||||
|
||||
/// Extension trait to split a SYSTEM/DPORT peripheral in independent logical
|
||||
@ -503,6 +574,7 @@ impl<'d, T: crate::peripheral::Peripheral<P = SystemPeripheral> + 'd> SystemExt<
|
||||
#[cfg(pdma)]
|
||||
dma: Dma { _private: () },
|
||||
radio_clock_control: RadioClockControl { _private: () },
|
||||
software_interrupt_control: SoftwareInterruptControl { _private: () },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
152
esp32-hal/examples/software_interrupts.rs
Normal file
152
esp32-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,152 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt::{self},
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
system::{SoftwareInterrupt, SoftwareInterruptControl},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
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.DPORT.split();
|
||||
let sw_int = system.software_interrupt_control;
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
156
esp32c2-hal/examples/software_interrupts.rs
Normal file
156
esp32c2-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,156 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32c2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt::{self},
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
riscv,
|
||||
system::{SoftwareInterrupt, SoftwareInterruptControl},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
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();
|
||||
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
|
||||
// Disable watchdog timers
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
unsafe { riscv::interrupt::enable() }
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
BIN
esp32c3-hal/app.bin
Normal file
BIN
esp32c3-hal/app.bin
Normal file
Binary file not shown.
2111
esp32c3-hal/app.hex
Executable file
2111
esp32c3-hal/app.hex
Executable file
File diff suppressed because it is too large
Load Diff
164
esp32c3-hal/examples/software_interrupts.rs
Normal file
164
esp32c3-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,164 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![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,
|
||||
Delay,
|
||||
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();
|
||||
|
||||
// Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT,
|
||||
// the RTC WDT, and the TIMG WDTs.
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
unsafe { riscv::interrupt::enable() }
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
BIN
esp32c3-hal/mcuboot-esp32c3.bin
Normal file
BIN
esp32c3-hal/mcuboot-esp32c3.bin
Normal file
Binary file not shown.
164
esp32c6-hal/examples/software_interrupts.rs
Normal file
164
esp32c6-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,164 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32c6_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt::{self},
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
riscv,
|
||||
system::{SoftwareInterrupt, SoftwareInterruptControl},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
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.PCR.split();
|
||||
let clockctrl = system.clock_control;
|
||||
let sw_int = system.software_interrupt_control;
|
||||
let clocks = ClockControl::boot_defaults(clockctrl).freeze();
|
||||
|
||||
// Disable the watchdog timers. For the ESP32-C3, this includes the Super WDT,
|
||||
// the RTC WDT, and the TIMG WDTs.
|
||||
let mut rtc = Rtc::new(peripherals.LP_CLKRST);
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt0 = timer_group0.wdt;
|
||||
let timer_group1 = TimerGroup::new(
|
||||
peripherals.TIMG1,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt1 = timer_group1.wdt;
|
||||
|
||||
rtc.swd.disable();
|
||||
rtc.rwdt.disable();
|
||||
wdt0.disable();
|
||||
wdt1.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
unsafe { riscv::interrupt::enable() }
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
152
esp32s2-hal/examples/software_interrupts.rs
Normal file
152
esp32s2-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,152 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s2_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt::{self},
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
system::{SoftwareInterrupt, SoftwareInterruptControl},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
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 sw_int = system.software_interrupt_control;
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
152
esp32s3-hal/examples/software_interrupts.rs
Normal file
152
esp32s3-hal/examples/software_interrupts.rs
Normal file
@ -0,0 +1,152 @@
|
||||
//! GPIO interrupt
|
||||
//!
|
||||
//! This prints "Interrupt" when the boot button is pressed.
|
||||
//! It also blinks an LED like the blinky example.
|
||||
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cell::RefCell;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use esp32s3_hal::{
|
||||
clock::ClockControl,
|
||||
interrupt::{self},
|
||||
peripherals::{self, Peripherals},
|
||||
prelude::*,
|
||||
system::{SoftwareInterrupt, SoftwareInterruptControl},
|
||||
timer::TimerGroup,
|
||||
Delay,
|
||||
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 sw_int = system.software_interrupt_control;
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timer_group0 = TimerGroup::new(
|
||||
peripherals.TIMG0,
|
||||
&clocks,
|
||||
&mut system.peripheral_clock_control,
|
||||
);
|
||||
let mut wdt = timer_group0.wdt;
|
||||
let mut rtc = Rtc::new(peripherals.RTC_CNTL);
|
||||
|
||||
// Disable MWDT and RWDT (Watchdog) flash boot protection
|
||||
wdt.disable();
|
||||
rtc.rwdt.disable();
|
||||
|
||||
critical_section::with(|cs| SWINT.borrow_ref_mut(cs).replace(sw_int));
|
||||
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR0,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR1,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR2,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::enable(
|
||||
peripherals::Interrupt::FROM_CPU_INTR3,
|
||||
interrupt::Priority::Priority3,
|
||||
)
|
||||
.unwrap();
|
||||
let mut delay = Delay::new(&clocks);
|
||||
let mut counter = 0;
|
||||
loop {
|
||||
delay.delay_ms(500u32);
|
||||
match counter {
|
||||
0 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt0);
|
||||
}),
|
||||
1 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
}),
|
||||
2 => critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt2);
|
||||
}),
|
||||
3 => {
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.raise(SoftwareInterrupt::SoftwareInterrupt3);
|
||||
});
|
||||
counter = -1
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[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");
|
||||
critical_section::with(|cs| {
|
||||
SWINT
|
||||
.borrow_ref_mut(cs)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.reset(SoftwareInterrupt::SoftwareInterrupt1);
|
||||
});
|
||||
}
|
||||
#[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);
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user