mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-16 21:05:35 +01:00
Use PLIC_MX instead of INTPRI to set interrupt priorities
This doesn't fix the GPIO interrupt triggering during a higher priority CPU task, but does fix rtic-monotonics. I am unsure how to fix the former as PLIC_MX doesn't have a function like `cpu_intr_from_cpu_x` to pend/unpend CPU interrupts, and if the CPU interrupts are enabled with PLIC_MX instead of INTPRI then the MCU just hangs when there is a CPU interrupt.
This commit is contained in:
parent
ef09e4b65f
commit
9305963752
2 changed files with 58 additions and 36 deletions
|
|
@ -35,7 +35,7 @@ pub mod prelude {
|
||||||
pub use fugit::{self, ExtU64, ExtU64Ceil};
|
pub use fugit::{self, ExtU64, ExtU64Ceil};
|
||||||
}
|
}
|
||||||
use crate::TimerQueueBackend;
|
use crate::TimerQueueBackend;
|
||||||
use esp32c6::{INTERRUPT_CORE0, INTPRI, SYSTIMER};
|
use esp32c6::{INTERRUPT_CORE0, PLIC_MX, SYSTIMER};
|
||||||
use rtic_time::timer_queue::TimerQueue;
|
use rtic_time::timer_queue::TimerQueue;
|
||||||
|
|
||||||
/// Timer implementing [`TimerQueueBackend`].
|
/// Timer implementing [`TimerQueueBackend`].
|
||||||
|
|
@ -57,13 +57,13 @@ impl TimerBackend {
|
||||||
.write_volatile(cpu_interrupt_number as u32);
|
.write_volatile(cpu_interrupt_number as u32);
|
||||||
|
|
||||||
// Set the interrupt's priority:
|
// Set the interrupt's priority:
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_pri(cpu_interrupt_number as usize)
|
.mxint_pri(cpu_interrupt_number as usize)
|
||||||
.write(|w| w.bits(15 as u32));
|
.write(|w| w.bits(15 as u32));
|
||||||
|
|
||||||
// Finally, enable the CPU interrupt:
|
// Finally, enable the CPU interrupt:
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_enable()
|
.mxint_enable()
|
||||||
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits()));
|
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
pub use esp32c6::{Interrupt, Peripherals};
|
pub use esp32c6::{Interrupt, Peripherals};
|
||||||
use esp32c6::{INTERRUPT_CORE0, INTPRI};
|
use esp32c6::{INTERRUPT_CORE0, INTPRI, PLIC_MX};
|
||||||
pub use riscv::interrupt;
|
pub use riscv::interrupt;
|
||||||
pub use riscv::register::mcause;
|
pub use riscv::register::mcause;
|
||||||
|
|
||||||
|
|
@ -15,25 +15,25 @@ where
|
||||||
//if priority is 1, priority thresh should be 1
|
//if priority is 1, priority thresh should be 1
|
||||||
f();
|
f();
|
||||||
unsafe {
|
unsafe {
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_thresh()
|
.mxint_thresh()
|
||||||
.write(|w| w.cpu_int_thresh().bits(1));
|
.write(|w| w.cpu_mxint_thresh().bits(1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//read current thresh
|
//read current thresh
|
||||||
let initial = unsafe {
|
let initial = unsafe {
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_thresh()
|
.mxint_thresh()
|
||||||
.read()
|
.read()
|
||||||
.cpu_int_thresh()
|
.cpu_mxint_thresh()
|
||||||
.bits()
|
.bits()
|
||||||
};
|
};
|
||||||
f();
|
f();
|
||||||
//write back old thresh
|
//write back old thresh
|
||||||
unsafe {
|
unsafe {
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_thresh()
|
.mxint_thresh()
|
||||||
.write(|w| w.cpu_int_thresh().bits(initial));
|
.write(|w| w.cpu_mxint_thresh().bits(initial));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,29 +57,33 @@ where
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub unsafe fn lock<T, R>(ptr: *mut T, ceiling: u8, f: impl FnOnce(&mut T) -> R) -> R {
|
pub unsafe fn lock<T, R>(ptr: *mut T, ceiling: u8, f: impl FnOnce(&mut T) -> R) -> R {
|
||||||
if ceiling == (15) {
|
if ceiling == (15) {
|
||||||
//turn off interrupts completely, were at max prio
|
// Turn off interrupts completely, we're at max prio
|
||||||
let r = critical_section::with(|_| f(&mut *ptr));
|
let r = critical_section::with(|_| f(&mut *ptr));
|
||||||
r
|
r
|
||||||
} else {
|
} else {
|
||||||
let current = unsafe {
|
let current = unsafe {
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_thresh()
|
.mxint_thresh()
|
||||||
.read()
|
.read()
|
||||||
.cpu_int_thresh()
|
.cpu_mxint_thresh()
|
||||||
.bits()
|
.bits()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// esp32c6 lets interrupts with prio equal to threshold through so we up it by one
|
||||||
unsafe {
|
unsafe {
|
||||||
(*INTPRI::ptr())
|
(*PLIC_MX::ptr())
|
||||||
.cpu_int_thresh()
|
.mxint_thresh()
|
||||||
.write(|w| w.cpu_int_thresh().bits(ceiling + 1));
|
.write(|w| w.cpu_mxint_thresh().bits(ceiling + 1));
|
||||||
} //esp32c6 lets interrupts with prio equal to threshold through so we up it by one
|
|
||||||
let r = f(&mut *ptr);
|
|
||||||
unsafe {
|
|
||||||
(*INTPRI::ptr())
|
|
||||||
.cpu_int_thresh()
|
|
||||||
.write(|w| w.cpu_int_thresh().bits(current));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let r = f(&mut *ptr);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(*PLIC_MX::ptr())
|
||||||
|
.mxint_thresh()
|
||||||
|
.write(|w| w.cpu_mxint_thresh().bits(current));
|
||||||
|
}
|
||||||
|
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -144,14 +148,32 @@ pub fn enable(int: Interrupt, prio: u8, cpu_int_id: u8) {
|
||||||
.offset(int as isize)
|
.offset(int as isize)
|
||||||
.write_volatile(cpu_int_id as u32);
|
.write_volatile(cpu_int_id as u32);
|
||||||
|
|
||||||
// Set the interrupt's priority:
|
match int {
|
||||||
(*INTPRI::ptr())
|
Interrupt::FROM_CPU_INTR0
|
||||||
.cpu_int_pri(cpu_int_id as usize)
|
| Interrupt::FROM_CPU_INTR1
|
||||||
.write(|w| w.bits(prio as u32));
|
| Interrupt::FROM_CPU_INTR2
|
||||||
|
| Interrupt::FROM_CPU_INTR3 => {
|
||||||
|
// Set the interrupt's priority:
|
||||||
|
(*INTPRI::ptr())
|
||||||
|
.cpu_int_pri(cpu_int_id as usize)
|
||||||
|
.write(|w| w.bits(prio as u32));
|
||||||
|
|
||||||
// Finally, enable the CPU interrupt:
|
// Finally, enable the CPU interrupt:
|
||||||
(*INTPRI::ptr())
|
(*INTPRI::ptr())
|
||||||
.cpu_int_enable()
|
.cpu_int_enable()
|
||||||
.modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
|
.modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// Set the interrupt's priority:
|
||||||
|
(*PLIC_MX::ptr())
|
||||||
|
.mxint_pri(cpu_int_id as usize)
|
||||||
|
.write(|w| w.bits(prio as u32));
|
||||||
|
|
||||||
|
// Finally, enable the CPU interrupt:
|
||||||
|
(*PLIC_MX::ptr())
|
||||||
|
.mxint_enable()
|
||||||
|
.modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue