Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cross PR with e310x-hal]: Example of the virq feature and helpful debug configs #27

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[target.'cfg(all(target_arch = "riscv32", target_os = "none"))']
runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -kernel"
# runner = "riscv64-unknown-elf-gdb -q -x gdb_init"
rustflags = [
"-C", "link-arg=-Thifive1-link.x",
]

[build]
target = "riscv32imac-unknown-none-elf"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Cargo.lock
target/
core
.gdb_history
.gdb_history
.vscode/.cortex-debug.peripherals.state.json
.vscode/.cortex-debug.registers.state.json
27 changes: 27 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Hifive1 (Debug)",
// Substitute with the board number
"device": "FE310",
"type": "cortex-debug",
"preLaunchTask": "example-virq",
// Defined in tasks.json
"request": "launch",
"servertype": "jlink",
// JLink server path
// "serverpath": "",
// GDB debug output
// "showDevDebugOutput": "raw",
"cwd": "${workspaceRoot}",
// Executable to launch
"executable": "${workspaceRoot}/target/riscv32imac-unknown-none-elf/debug/examples/virq",
"interface": "jtag",
"svdFile": "${workspaceRoot}/hifive.svd",
// Set this to point to sifive risc-v gdb path
"gdbPath": "${workspaceRoot}/../../Toolchains/sifive/bin/riscv64-unknown-elf-gdb",
"toolchainPrefix": "riscv64-unknown-elf",
},
]
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cortex-debug.variableUseNaturalFormat": true,
"rust-analyzer.cargo.features": ["board-redv"],
"rust-analyzer.check.allTargets": false,
}
21 changes: 21 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "example-virq",
"command": "cargo",
"args": [
"build",
"--features=board-redv,virq",
"--example=virq"
],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
]
}
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ categories = ["embedded", "hardware-support", "no-std"]
description = "Board support crate for HiFive1 and LoFive boards"
keywords = ["riscv", "register", "peripheral"]
license = "ISC"
edition = "2018"
edition = "2021"

[dependencies]
e310x-hal = "0.9.1"
e310x-hal = {git = "https://github.com/greenlsi/e310x-hal"}
embedded-hal = "0.2.5"
riscv = "0.6.0"
riscv = { git = "https://github.com/rust-embedded/riscv", branch = "riscv-pac-only", features = ["critical-section-single-hart"]} # TODO use crates.io
riscv-rt = { git = "https://github.com/rust-embedded/riscv", branch = "riscv-pac-only" } # TODO use crates.io
nb = "1.0.0"
panic-halt = "0.2.0"

[features]
board-hifive1 = []
board-hifive1-revb = ["e310x-hal/g002"]
board-redv = ["e310x-hal/g002"]
board-lofive = []
board-lofive-r1 = ["e310x-hal/g002"]
v-trap = ["e310x-hal/v-trap"]

[package.metadata.docs.rs]
features = ['board-hifive1-revb']
11 changes: 0 additions & 11 deletions assemble.sh

This file was deleted.

Binary file removed bin/flash.a
Binary file not shown.
6 changes: 0 additions & 6 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,4 @@ fn main() {

fs::copy("hifive1-link.x", out_dir.join("hifive1-link.x")).unwrap();
println!("cargo:rerun-if-changed=hifive1-link.x");

// Copy library with flash setup code
let name = env::var("CARGO_PKG_NAME").unwrap();
fs::copy("bin/flash.a", out_dir.join(format!("lib{}.a", name))).unwrap();
println!("cargo:rustc-link-lib=static={}", name);
println!("cargo:rerun-if-changed=bin/flash.a");
}
78 changes: 78 additions & 0 deletions examples/gpio4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//! Demonstration on how to configure the GPIO4 interrupt on HiFive boards.
//! You must connect a button to pin 12 (GPIO4) and ground to test this example.

#![no_main]
#![no_std]

extern crate panic_halt;

use hifive1::hal::e310x::PLIC;
use hifive1::{hal::prelude::*, hal::DeviceResources, pin, sprintln};

use riscv::register::mstatus;
use riscv_rt::entry;

/* Handler for the GPIO0 interrupt */
#[riscv_rt::external_interrupt(ExternalInterrupt::GPIO4)]
fn gpio4_handler() {
sprintln!("We reached the GPIO4 interrupt!");
/* Clear the GPIO pending interrupt */
let gpio_block = unsafe { hifive1::hal::e310x::Gpio0::steal() };
gpio_block.fall_ip().write(|w| w.pin4().set_bit());
}

/* Code adapted from https://github.com/riscv-rust/riscv-rust-quickstart/blob/interrupt-test/examples/interrupt.rs*/
#[entry]
fn main() -> ! {
/* Get the ownership of the device resources singleton */
let resources = DeviceResources::take().unwrap();
let peripherals = resources.peripherals;

/* Configure system clock */
let sysclock = hifive1::configure_clocks(peripherals.PRCI, peripherals.AONCLK, 64.mhz().into());
/* Get the board pins */
let gpio = resources.pins;

/* Configure stdout for debugging */
hifive1::stdout::configure(
peripherals.UART0,
pin!(gpio, uart0_tx),
pin!(gpio, uart0_rx),
115_200.bps(),
sysclock,
);

sprintln!("Configuring GPIO...");
/* Set GPIO4 (pin 12) as input */
// let gpio4 = pin!(gpio, dig12);
gpio.pin4.into_pull_up_input();
//let input = gpio4.into_pull_up_input();

sprintln!("Configuring priorities...");
/* Set interrupt source priority */
let priorities = PLIC::priorities();
unsafe { priorities.set_priority(ExternalInterrupt::GPIO4, Priority::P7) };

let gpio_block = unsafe { hifive1::hal::e310x::Gpio0::steal() };
unsafe {
/* Clear pending interrupts from previous states */
gpio_block.fall_ie().write(|w| w.bits(0x00000000));
gpio_block.rise_ie().write(|w| w.bits(0x00000000));
gpio_block.fall_ip().write(|w| w.bits(0xffffffff));
gpio_block.rise_ip().write(|w| w.bits(0xffffffff));
}
gpio_block.fall_ie().write(|w| w.pin4().set_bit());
gpio_block.rise_ie().write(|w| w.pin4().clear_bit());

/* Activate global interrupts (mie bit) */
let ctx = PLIC::ctx0();
unsafe {
ctx.threshold().set_threshold(Priority::P1);
ctx.enables().enable(ExternalInterrupt::GPIO4);
mstatus::set_mie();
PLIC::enable();
}
loop {
riscv::asm::wfi();
}
}
61 changes: 61 additions & 0 deletions examples/mtimer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//! This example demonstrates how to configure the CLINT to generate
//! periodic interrupts using the machine timer.

#![no_main]
#![no_std]

extern crate panic_halt;

use hifive1::{
configure_clocks,
hal::{e310x::CLINT, prelude::*, DeviceResources},
pin, sprintln,
};

const PERIOD_MS: u64 = 1000;
const FREQUENCY_HZ: u64 = 32768;
const CLINT_TICKS_PER_MS: u64 = PERIOD_MS * FREQUENCY_HZ / 1000;

/// Handler for the machine timer interrupt (handled by the CLINT)
#[riscv_rt::core_interrupt(CoreInterrupt::MachineTimer)]
fn mtimer_handler() {
sprintln!("MTIMER interrupt!");
CLINT::mtimecmp0().modify(|f| *f += CLINT_TICKS_PER_MS);
}

#[riscv_rt::entry]
fn main() -> ! {
/* Get the ownership of the device resources singleton */
let resources = DeviceResources::take().unwrap();
let peripherals = resources.peripherals;

/* Configure system clock */
let sysclock = configure_clocks(peripherals.PRCI, peripherals.AONCLK, 64.mhz().into());

/* Configure stdout for printing via UART */
let gpio = resources.pins;
hifive1::stdout::configure(
peripherals.UART0,
pin!(gpio, uart0_tx),
pin!(gpio, uart0_rx),
115_200.bps(),
sysclock,
);

sprintln!("Configuring CLINT...");
CLINT::mtimer_disable();
let mtimer = CLINT::mtimer();
let (mtimecmp, mtime) = (mtimer.mtimecmp0, mtimer.mtime);
mtime.write(0);
mtimecmp.write(CLINT_TICKS_PER_MS);

sprintln!("Enabling interrupts...");
unsafe {
riscv::interrupt::enable();
CLINT::mtimer_enable();
}
loop {
sprintln!("Sleeping...");
riscv::asm::wfi();
}
}
45 changes: 0 additions & 45 deletions flash.S

This file was deleted.

9 changes: 9 additions & 0 deletions gdb_init
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set history save on
set confirm off
set remotetimeout 240
target extended-remote :3333
set print asm-demangle on
monitor reset halt
load
continue
# quit
Loading