Skip to content

Commit

Permalink
WIP (interrupts)
Browse files Browse the repository at this point in the history
  • Loading branch information
playfulFence committed Nov 14, 2024
1 parent 819c175 commit 127f695
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 15 deletions.
133 changes: 123 additions & 10 deletions esp-hal/src/interrupt/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,99 @@ pub static RESERVED_INTERRUPTS: &[usize] = INTERRUPT_TO_PRIORITY;
#[link_section = ".trap.rust"]
#[export_name = "_start_trap_rust_hal"]
pub unsafe extern "C" fn start_trap_rust_hal(trap_frame: *mut TrapFrame) {
assert!(
mcause::read().is_exception(),
"Arrived into _start_trap_rust_hal but mcause is not an exception!"
);
extern "C" {
fn ExceptionHandler(tf: *mut TrapFrame);
// assert!(
// mcause::read().is_exception(),
// "Arrived into _start_trap_rust_hal but mcause is not an exception!"
// );

if riscv::register::mcause::read().is_exception() {
extern "C" {
fn ExceptionHandler(tf: *mut TrapFrame);
}
ExceptionHandler(trap_frame);
} else {
extern "C" {
fn interrupt1(frame: &mut TrapFrame);
fn interrupt2(frame: &mut TrapFrame);
fn interrupt3(frame: &mut TrapFrame);
fn interrupt4(frame: &mut TrapFrame);
fn interrupt5(frame: &mut TrapFrame);
fn interrupt6(frame: &mut TrapFrame);
fn interrupt7(frame: &mut TrapFrame);
fn interrupt8(frame: &mut TrapFrame);
fn interrupt9(frame: &mut TrapFrame);
fn interrupt10(frame: &mut TrapFrame);
fn interrupt11(frame: &mut TrapFrame);
fn interrupt12(frame: &mut TrapFrame);
fn interrupt13(frame: &mut TrapFrame);
fn interrupt14(frame: &mut TrapFrame);
fn interrupt15(frame: &mut TrapFrame);
fn interrupt16(frame: &mut TrapFrame);
fn interrupt17(frame: &mut TrapFrame);
fn interrupt18(frame: &mut TrapFrame);
fn interrupt19(frame: &mut TrapFrame);
fn interrupt20(frame: &mut TrapFrame);
fn interrupt21(frame: &mut TrapFrame);
fn interrupt22(frame: &mut TrapFrame);
fn interrupt23(frame: &mut TrapFrame);
fn interrupt24(frame: &mut TrapFrame);
fn interrupt25(frame: &mut TrapFrame);
fn interrupt26(frame: &mut TrapFrame);
fn interrupt27(frame: &mut TrapFrame);
fn interrupt28(frame: &mut TrapFrame);
fn interrupt29(frame: &mut TrapFrame);
fn interrupt30(frame: &mut TrapFrame);
fn interrupt31(frame: &mut TrapFrame);

// Defined in `esp-riscv-rt`
pub fn DefaultHandler();
}

let interrupt_priority = _handle_priority();

let code = riscv::register::mcause::read().code();

// #[cfg(clic)]
let code = (code & 0b1111_1111_1111) - 16 as usize;

match code {
1 => interrupt1(trap_frame.as_mut().unwrap()),
2 => interrupt2(trap_frame.as_mut().unwrap()),
3 => interrupt3(trap_frame.as_mut().unwrap()),
4 => interrupt4(trap_frame.as_mut().unwrap()),
5 => interrupt5(trap_frame.as_mut().unwrap()),
6 => interrupt6(trap_frame.as_mut().unwrap()),
7 => interrupt7(trap_frame.as_mut().unwrap()),
8 => interrupt8(trap_frame.as_mut().unwrap()),
9 => interrupt9(trap_frame.as_mut().unwrap()),
10 => interrupt10(trap_frame.as_mut().unwrap()),
11 => interrupt11(trap_frame.as_mut().unwrap()),
12 => interrupt12(trap_frame.as_mut().unwrap()),
13 => interrupt13(trap_frame.as_mut().unwrap()),
14 => interrupt14(trap_frame.as_mut().unwrap()),
15 => interrupt15(trap_frame.as_mut().unwrap()),
16 => interrupt16(trap_frame.as_mut().unwrap()),
17 => interrupt17(trap_frame.as_mut().unwrap()),
18 => interrupt18(trap_frame.as_mut().unwrap()),
19 => interrupt19(trap_frame.as_mut().unwrap()),
20 => interrupt20(trap_frame.as_mut().unwrap()),
21 => interrupt21(trap_frame.as_mut().unwrap()),
22 => interrupt22(trap_frame.as_mut().unwrap()),
23 => interrupt23(trap_frame.as_mut().unwrap()),
24 => interrupt24(trap_frame.as_mut().unwrap()),
25 => interrupt25(trap_frame.as_mut().unwrap()),
26 => interrupt26(trap_frame.as_mut().unwrap()),
27 => interrupt27(trap_frame.as_mut().unwrap()),
28 => interrupt28(trap_frame.as_mut().unwrap()),
29 => interrupt29(trap_frame.as_mut().unwrap()),
30 => interrupt30(trap_frame.as_mut().unwrap()),
31 => interrupt31(trap_frame.as_mut().unwrap()),
_ => DefaultHandler(),
};

_restore_priority(interrupt_priority);
}
ExceptionHandler(trap_frame);

}

#[doc(hidden)]
Expand Down Expand Up @@ -833,19 +918,47 @@ mod clic {
/// Get interrupt priority - called by assembly code
#[inline]
pub(super) unsafe extern "C" fn get_priority(cpu_interrupt: CpuInterrupt) -> Priority {
todo!()
let clic = &*crate::peripherals::CLIC::PTR;
let prio = clic
.int_ctrl(cpu_interrupt as usize)
.read()
.int_ctl()
.bits();

core::mem::transmute::<u8, Priority>(prio >> (8 - 3))
}

#[no_mangle]
#[link_section = ".trap"]
pub(super) unsafe extern "C" fn _handle_priority() -> u32 {
todo!()
use super::mcause;
let clic = &*crate::peripherals::CLIC::PTR;

let interrupt_id: usize = mcause::read().code(); // MSB is whether its exception or interrupt.
let interrupt_id = (interrupt_id & 0b1111_1111_1111) - EXTERNAL_INTERRUPT_OFFSET as usize;

let interrupt_priority = clic.int_ctrl(interrupt_id).read().int_ctl().bits();

let prev_interrupt_priority = clic.int_thresh().read().cpu_int_thresh().bits();
if interrupt_priority < 15 {
// leave interrupts disabled if interrupt is of max priority.
clic.int_thresh()
.write(|w| w.cpu_int_thresh().bits(interrupt_priority + 1));
unsafe {
riscv::interrupt::enable();
}
}

prev_interrupt_priority as u32
}

#[no_mangle]
#[link_section = ".trap"]
pub(super) unsafe extern "C" fn _restore_priority(stored_prio: u32) {
todo!()
riscv::interrupt::disable();
let clic = &*crate::peripherals::CLIC::PTR;
clic.int_thresh()
.write(|w| w.cpu_int_thresh().bits(stored_prio as u8));
}
}

Expand Down
4 changes: 2 additions & 2 deletions esp-hal/src/soc/esp32p4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ pub(crate) mod registers {

pub(crate) mod constants {
/// Start address of the system's DRAM (low range).
pub const SOC_DRAM_LOW: usize = 0x4000_0000;
pub const SOC_DRAM_LOW: usize = 0x4FF0_0000;
/// End address of the system's DRAM (high range).
pub const SOC_DRAM_HIGH: usize = 0x4C00_0000;
pub const SOC_DRAM_HIGH: usize = 0x4FFB_FFFF;
/// RC FAST Clock value (Hertz).
pub const RC_FAST_CLK: fugit::HertzU32 = fugit::HertzU32::kHz(17500);
}
2 changes: 1 addition & 1 deletion examples/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ esp32s2 = "run --release --features=esp32s2 --target=xtensa-esp32s2-none-elf"
esp32s3 = "run --release --features=esp32s3 --target=xtensa-esp32s3-none-elf"

[target.'cfg(target_arch = "riscv32")']
runner = "espflash flash --monitor --no-stub"
runner = "espflash flash --monitor"
rustflags = [
"-C", "link-arg=-Tlinkall.x",
"-C", "force-frame-pointers",
Expand Down
4 changes: 3 additions & 1 deletion examples/src/bin/gpio_interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! - LED => GPIO2
//! - BUTTON => GPIO0 (ESP32, ESP32-S2, ESP32-S3) / GPIO9
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32p4 esp32s2 esp32s3

#![no_std]
#![no_main]
Expand Down Expand Up @@ -37,6 +37,8 @@ fn main() -> ! {
cfg_if::cfg_if! {
if #[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))] {
let button = peripherals.GPIO0;
} else if #[cfg(feature = "esp32p4")] {
let button = peripherals.GPIO35;
} else {
let button = peripherals.GPIO9;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/src/bin/systimer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! It's an additional timer besides the TIMG peripherals.
//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3
//% CHIPS: esp32c2 esp32c3 esp32c6 esp32h2 esp32p4 esp32s2 esp32s3

#![no_std]
#![no_main]
Expand Down

0 comments on commit 127f695

Please sign in to comment.