Skip to content

Commit

Permalink
Example working in QEMU
Browse files Browse the repository at this point in the history
  • Loading branch information
romancardenas committed Nov 10, 2023
1 parent 0d63107 commit 955f070
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 84 deletions.
2 changes: 1 addition & 1 deletion hifive1-test/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[target.'cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), target_os = "none"))']
[target.'cfg(all(target_arch = "riscv32", target_os = "none"))']
runner = "riscv64-unknown-elf-gdb -q -x gdb_init"
# runner = "probe-run --chip fe310-g002 --verbose"
rustflags = [
Expand Down
5 changes: 4 additions & 1 deletion hifive1-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ edition = "2021"

[dependencies]
riscv-slic = {path = "../riscv-slic", features = ["clint-backend", "unsafe-assume-single-core"]}
e310x = { git = "https://github.com/greenlsi/e310x.git", branch = "master", features = ["v-extern"]}
e310x = { git = "https://github.com/greenlsi/e310x.git", rev = "f22b4dd"}
hifive1 = { git = "https://github.com/greenlsi/hifive1.git", branch = "rtc", features = ["board-redv"] }
bare-metal = "0.2"
# riscv-rt = "0.11.0"
riscv-rt = {git = "https://github.com/rust-embedded/riscv-rt.git", branch = "master"}
# riscv-rt = {path = "../../../github/riscv-rt", features = ["atomic-emulation-trap"]}
panic-halt = "0.2.0"

[features]
qemu = [] # feature for running on qemu (CLINT timer is 10MHz instead of 32KHz)
62 changes: 21 additions & 41 deletions hifive1-test/examples/rtc.rs → hifive1-test/examples/clint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@
#![no_main]

extern crate panic_halt;

use hifive1::hal::e310x::{Interrupt as ExtInterrupt, Priority, PLIC};
use e310x::CLINT;
use hifive1::hal::prelude::*;
use hifive1::hal::DeviceResources;
use hifive1::{pin, sprintln};

use riscv_rt::entry;
use riscv_slic;
extern crate riscv_slic;

#[cfg(feature = "qemu")]
const PERIOD: u64 = 10000000; // 10 MHz in QEMU
#[cfg(not(feature = "qemu"))]
const PERIOD: u64 = 32_768; // 32.768 kHz in HW

// generate SLIC code for this example
riscv_slic::codegen!(
pac = e310x,
swi = [SoftLow, SoftMedium, SoftHigh],
backend = [hart_id = HART0]
);

use slic::Interrupt as SoftInterrupt; // Re-export of automatically generated enum of interrupts in previous macro

/// HW handler for clearing RTC.
/// We must define a ClearX handler for every bypassed HW interrupt
/// HW handler for MachineTimer interrupts triggered by CLINT.
#[allow(non_snake_case)]
#[no_mangle]
unsafe fn RTC() {
// increase rtccmp to clear HW interrupt
let rtc = DeviceResources::steal().peripherals.RTC;
let rtccmp = rtc.rtccmp.read().bits();
sprintln!("--- clear RTC (rtccmp = {}) ---", rtccmp);
rtc.rtccmp.write(|w| w.bits(rtccmp + 65536));
fn MachineTimer() {
let mtimecmp = CLINT::mtimecmp0();
let val = mtimecmp.read();
sprintln!("--- update MTIMECMP (mtimecmp = {}) ---", val);
mtimecmp.write(val + PERIOD);
riscv_slic::pend(SoftInterrupt::SoftMedium);
}

Expand Down Expand Up @@ -76,35 +79,12 @@ fn main() -> ! {
clocks,
);

// Disable watchdog
let wdg = peripherals.WDOG;
wdg.wdogcfg.modify(|_, w| w.enalways().clear_bit());

sprintln!("Configuring PLIC!!!...");
sprintln!("Configuring CLINT...");
// First, we make sure that all PLIC the interrupts are disabled and set the interrupts priorities
PLIC::disable();
PLIC::priorities().reset::<ExtInterrupt>();
// Safety: interrupts are disabled
unsafe { PLIC::priorities().set_priority(ExtInterrupt::RTC, Priority::P7) };

// Next, we configure the PLIC context for our use case
let ctx = PLIC::ctx0();
ctx.enables().disable_all::<ExtInterrupt>();
// Safety: we are the only hart running and we have not enabled any interrupts yet
unsafe {
ctx.enables().enable(ExtInterrupt::RTC);
ctx.threshold().set_threshold(Priority::P1);
};
sprintln!("done!");

sprintln!("Configuring RTC...");
let mut rtc = peripherals.RTC.constrain();
rtc.disable();
rtc.set_scale(0);
rtc.set_rtc(0);
rtc.set_rtccmp(10000);
rtc.enable();
sprintln!("done!");
CLINT::disable();
let mtimer = CLINT::mtimer();
mtimer.mtimecmp0.write(PERIOD);
mtimer.mtime.write(0);

sprintln!("Configuring SLIC...");
// make sure that interrupts are off
Expand All @@ -116,15 +96,15 @@ fn main() -> ! {
riscv_slic::set_priority(SoftInterrupt::SoftMedium, 2); // medium priority
riscv_slic::set_priority(SoftInterrupt::SoftHigh, 3); // high priority
}

sprintln!("Done!");

sprintln!("Enabling interrupts...");
unsafe {
riscv_slic::set_interrupts();
PLIC::enable();
CLINT::mtimer_enable();
riscv_slic::enable();
}
//let mut delay = CLINT::delay();
loop {
sprintln!("Going to sleep!");
unsafe { riscv_slic::riscv::asm::wfi() };
Expand Down
62 changes: 21 additions & 41 deletions hifive1-test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,36 @@
#![no_main]

extern crate panic_halt;

use hifive1::hal::e310x::{Interrupt as ExtInterrupt, Priority, PLIC};
use e310x::CLINT;
use hifive1::hal::prelude::*;
use hifive1::hal::DeviceResources;
use hifive1::{pin, sprintln};

use riscv_rt::entry;
use riscv_slic;
extern crate riscv_slic;

#[cfg(feature = "qemu")]
const PERIOD: u64 = 10000000; // 10 MHz in QEMU
#[cfg(not(feature = "qemu"))]
const PERIOD: u64 = 32_768; // 32.768 kHz in HW

// generate SLIC code for this example
riscv_slic::codegen!(
pac = e310x,
swi = [SoftLow, SoftMedium, SoftHigh],
backend = [hart_id = HART0]
);

use slic::Interrupt as SoftInterrupt; // Re-export of automatically generated enum of interrupts in previous macro

/// HW handler for clearing RTC.
/// We must define a ClearX handler for every bypassed HW interrupt
/// HW handler for MachineTimer interrupts triggered by CLINT.
#[allow(non_snake_case)]
#[no_mangle]
unsafe fn RTC() {
// increase rtccmp to clear HW interrupt
let rtc = DeviceResources::steal().peripherals.RTC;
let rtccmp = rtc.rtccmp.read().bits();
sprintln!("--- clear RTC (rtccmp = {}) ---", rtccmp);
rtc.rtccmp.write(|w| w.bits(rtccmp + 65536));
fn MachineTimer() {
let mtimecmp = CLINT::mtimecmp0();
let val = mtimecmp.read();
sprintln!("--- update MTIMECMP (mtimecmp = {}) ---", val);
mtimecmp.write(val + PERIOD);
riscv_slic::pend(SoftInterrupt::SoftMedium);
}

Expand Down Expand Up @@ -76,35 +79,12 @@ fn main() -> ! {
clocks,
);

// Disable watchdog
let wdg = peripherals.WDOG;
wdg.wdogcfg.modify(|_, w| w.enalways().clear_bit());

sprintln!("Configuring PLIC!!...");
sprintln!("Configuring CLINT...");
// First, we make sure that all PLIC the interrupts are disabled and set the interrupts priorities
PLIC::disable();
PLIC::priorities().reset::<ExtInterrupt>();
// Safety: interrupts are disabled
unsafe { PLIC::priorities().set_priority(ExtInterrupt::RTC, Priority::P7) };

// Next, we configure the PLIC context for our use case
let ctx = PLIC::ctx0();
ctx.enables().disable_all::<ExtInterrupt>();
// Safety: we are the only hart running and we have not enabled any interrupts yet
unsafe {
ctx.enables().enable(ExtInterrupt::RTC);
ctx.threshold().set_threshold(Priority::P1);
};
sprintln!("done!");

sprintln!("Configuring RTC...");
let mut rtc = peripherals.RTC.constrain();
rtc.disable();
rtc.set_scale(0);
rtc.set_rtc(0);
rtc.set_rtccmp(10000);
rtc.enable();
sprintln!("done!");
CLINT::disable();
let mtimer = CLINT::mtimer();
mtimer.mtimecmp0.write(PERIOD);
mtimer.mtime.write(0);

sprintln!("Configuring SLIC...");
// make sure that interrupts are off
Expand All @@ -116,15 +96,15 @@ fn main() -> ! {
riscv_slic::set_priority(SoftInterrupt::SoftMedium, 2); // medium priority
riscv_slic::set_priority(SoftInterrupt::SoftHigh, 3); // high priority
}

sprintln!("Done!");

sprintln!("Enabling interrupts...");
unsafe {
riscv_slic::set_interrupts();
PLIC::enable();
CLINT::mtimer_enable();
riscv_slic::enable();
}
//let mut delay = CLINT::delay();
loop {
sprintln!("Going to sleep!");
unsafe { riscv_slic::riscv::asm::wfi() };
Expand Down

0 comments on commit 955f070

Please sign in to comment.