aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Hastings <eli@seagen.io>2025-02-26 11:39:09 +0000
committerHenrik Tjäder <henrik@tjaders.com>2025-04-07 21:11:21 +0000
commit93059637524f99cfe477042135badf842ada48a1 (patch)
treeaf9181448167085352b113f5b8e8ca9f1e674937
parentef09e4b65f3586df6302721de909f66d69e7ba80 (diff)
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.
-rw-r--r--rtic-monotonics/src/esp32c6.rs10
-rw-r--r--rtic/src/export/riscv_esp32c6.rs80
2 files changed, 56 insertions, 34 deletions
diff --git a/rtic-monotonics/src/esp32c6.rs b/rtic-monotonics/src/esp32c6.rs
index 60a8175..5cb872a 100644
--- a/rtic-monotonics/src/esp32c6.rs
+++ b/rtic-monotonics/src/esp32c6.rs
@@ -35,7 +35,7 @@ pub mod prelude {
pub use fugit::{self, ExtU64, ExtU64Ceil};
}
use crate::TimerQueueBackend;
-use esp32c6::{INTERRUPT_CORE0, INTPRI, SYSTIMER};
+use esp32c6::{INTERRUPT_CORE0, PLIC_MX, SYSTIMER};
use rtic_time::timer_queue::TimerQueue;
/// Timer implementing [`TimerQueueBackend`].
@@ -57,13 +57,13 @@ impl TimerBackend {
.write_volatile(cpu_interrupt_number as u32);
// Set the interrupt's priority:
- (*INTPRI::ptr())
- .cpu_int_pri(cpu_interrupt_number as usize)
+ (*PLIC_MX::ptr())
+ .mxint_pri(cpu_interrupt_number as usize)
.write(|w| w.bits(15 as u32));
// Finally, enable the CPU interrupt:
- (*INTPRI::ptr())
- .cpu_int_enable()
+ (*PLIC_MX::ptr())
+ .mxint_enable()
.modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits()));
}
diff --git a/rtic/src/export/riscv_esp32c6.rs b/rtic/src/export/riscv_esp32c6.rs
index b06bf5d..cf7ac3c 100644
--- a/rtic/src/export/riscv_esp32c6.rs
+++ b/rtic/src/export/riscv_esp32c6.rs
@@ -1,5 +1,5 @@
pub use esp32c6::{Interrupt, Peripherals};
-use esp32c6::{INTERRUPT_CORE0, INTPRI};
+use esp32c6::{INTERRUPT_CORE0, INTPRI, PLIC_MX};
pub use riscv::interrupt;
pub use riscv::register::mcause;
@@ -15,25 +15,25 @@ where
//if priority is 1, priority thresh should be 1
f();
unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
- .write(|w| w.cpu_int_thresh().bits(1));
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
+ .write(|w| w.cpu_mxint_thresh().bits(1));
}
} else {
//read current thresh
let initial = unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
.read()
- .cpu_int_thresh()
+ .cpu_mxint_thresh()
.bits()
};
f();
//write back old thresh
unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
- .write(|w| w.cpu_int_thresh().bits(initial));
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
+ .write(|w| w.cpu_mxint_thresh().bits(initial));
}
}
}
@@ -57,29 +57,33 @@ where
#[inline(always)]
pub unsafe fn lock<T, R>(ptr: *mut T, ceiling: u8, f: impl FnOnce(&mut T) -> R) -> R {
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));
r
} else {
let current = unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
.read()
- .cpu_int_thresh()
+ .cpu_mxint_thresh()
.bits()
};
+ // esp32c6 lets interrupts with prio equal to threshold through so we up it by one
unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
- .write(|w| w.cpu_int_thresh().bits(ceiling + 1));
- } //esp32c6 lets interrupts with prio equal to threshold through so we up it by one
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
+ .write(|w| w.cpu_mxint_thresh().bits(ceiling + 1));
+ }
+
let r = f(&mut *ptr);
+
unsafe {
- (*INTPRI::ptr())
- .cpu_int_thresh()
- .write(|w| w.cpu_int_thresh().bits(current));
+ (*PLIC_MX::ptr())
+ .mxint_thresh()
+ .write(|w| w.cpu_mxint_thresh().bits(current));
}
+
r
}
}
@@ -144,14 +148,32 @@ pub fn enable(int: Interrupt, prio: u8, cpu_int_id: u8) {
.offset(int as isize)
.write_volatile(cpu_int_id as u32);
- // Set the interrupt's priority:
- (*INTPRI::ptr())
- .cpu_int_pri(cpu_int_id as usize)
- .write(|w| w.bits(prio as u32));
+ match int {
+ Interrupt::FROM_CPU_INTR0
+ | Interrupt::FROM_CPU_INTR1
+ | 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:
+ (*INTPRI::ptr())
+ .cpu_int_enable()
+ .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:
- (*INTPRI::ptr())
- .cpu_int_enable()
- .modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
+ // Finally, enable the CPU interrupt:
+ (*PLIC_MX::ptr())
+ .mxint_enable()
+ .modify(|r, w| w.bits((1 << cpu_int_id) | r.bits()));
+ }
+ }
}
}