aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2022-08-06 12:12:37 -0400
committerBrian Cully <bjc@kublai.com>2022-08-06 12:12:37 -0400
commit35248b205cd56633e52b9e634a942e7fd987db0b (patch)
tree37c9fd21e52e7cb0a7c547065a52d73d19d925b9
parent8f9bc49bb40e2972cf0c0bf1b61eb8127a9397df (diff)
downloadluchie-35248b205cd56633e52b9e634a942e7fd987db0b.tar.gz
luchie-35248b205cd56633e52b9e634a942e7fd987db0b.zip
Blinky on a hardware timer, with ‘wfi’ in between.
-rw-r--r--.cargo/config.toml8
-rw-r--r--Cargo.lock180
-rw-r--r--Cargo.toml3
-rw-r--r--build.rs18
-rw-r--r--memory.x13
-rw-r--r--src/led.rs10
-rwxr-xr-xsrc/main.rs93
7 files changed, 302 insertions, 23 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
index 2609695..d0fb511 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -7,5 +7,9 @@ target = "riscv32imac-unknown-none-elf"
[target.riscv32imac-unknown-none-elf]
runner = "riscv32-elf-gdb -x gdbinit"
-rustflags = ["-C", "link-arg=-Tdevice.lds", "-C", "link-arg=-nostdlib"]
-linker = "riscv32-elf-ld"
+#rustflags = ["-C", "link-arg=-Tdevice.lds", "-C", "link-arg=-nostdlib"]
+rustflags = [
+ "-C", "link-arg=-Tmemory.x",
+ "-C", "link-arg=-Tlink.x",
+]
+#linker = "riscv32-elf-ld"
diff --git a/Cargo.lock b/Cargo.lock
index f03a28c..282789f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,27 +17,77 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
dependencies = [
- "rustc_version",
+ "rustc_version 0.2.3",
]
[[package]]
+name = "bare-metal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
+
+[[package]]
name = "bit_field"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
+name = "cast"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+dependencies = [
+ "rustc_version 0.4.0",
+]
+
+[[package]]
+name = "embedded-dma"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46c8c02e4347a0267ca60813c952017f4c5948c232474c6010a381a337f1bda4"
+dependencies = [
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
+dependencies = [
+ "nb 0.1.3",
+ "void",
+]
+
+[[package]]
name = "gd32vf103-pac"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffd430737a49edbd1c0241b58cabe79a7ac7ebe208f67dc838c1c981eb60e83"
dependencies = [
- "bare-metal",
- "riscv",
+ "bare-metal 0.2.5",
+ "riscv 0.6.0",
"vcell",
]
[[package]]
+name = "gd32vf103xx-hal"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bdffb2f55a16c7916b5df9c02b1dab0dc1c8545237491821a7fd98c61378e4a"
+dependencies = [
+ "cast",
+ "embedded-dma",
+ "embedded-hal",
+ "gd32vf103-pac",
+ "nb 0.1.3",
+ "riscv 0.6.0",
+ "vcell",
+ "void",
+]
+
+[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -48,6 +98,9 @@ name = "luchie"
version = "0.1.0"
dependencies = [
"gd32vf103-pac",
+ "gd32vf103xx-hal",
+ "riscv 0.8.0",
+ "riscv-rt",
]
[[package]]
@@ -57,6 +110,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "nb"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
+dependencies = [
+ "nb 1.0.0",
+]
+
+[[package]]
+name = "nb"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r0"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211"
+
+[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -79,12 +171,46 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f0b705d428e9d0f78e2bb73093887ee58a83c9688de3faedbb4c0631c4618e"
dependencies = [
- "bare-metal",
+ "bare-metal 0.2.5",
"bit_field",
"riscv-target",
]
[[package]]
+name = "riscv"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e2856a701069e2d262b264750d382407d272d5527f7a51d3777d1805b4e2d3c"
+dependencies = [
+ "bare-metal 1.0.0",
+ "bit_field",
+ "embedded-hal",
+]
+
+[[package]]
+name = "riscv-rt"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527ddfacbbfeed89256163c2655b0392c4aa76dd95c0189dc05044bf2c47c3f8"
+dependencies = [
+ "r0",
+ "riscv 0.8.0",
+ "riscv-rt-macros",
+ "riscv-target",
+]
+
+[[package]]
+name = "riscv-rt-macros"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38509d7b17c2f604ceab3e5ff8ac97bb8cd2f544688c512be75c715edaf4daf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "riscv-target"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -100,7 +226,16 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
- "semver",
+ "semver 0.9.0",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver 1.0.13",
]
[[package]]
@@ -113,13 +248,48 @@ dependencies = [
]
[[package]]
+name = "semver"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
+
+[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "syn"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
+
+[[package]]
name = "vcell"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
diff --git a/Cargo.toml b/Cargo.toml
index 16741da..0d23eb7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,6 +18,9 @@ codegen-units = 1
[dependencies]
gd32vf103-pac = "0.4.0"
+gd32vf103xx-hal = "0.5.0"
+riscv = "0.8.0"
+riscv-rt = "0.9.0"
[[bin]]
name = "luchie"
diff --git a/build.rs b/build.rs
index ff3f6a1..5dd893a 100644
--- a/build.rs
+++ b/build.rs
@@ -1,3 +1,19 @@
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
fn main() {
- println!("cargo:rerun-if-changed=device.lds")
+ let out_dir = env::var("OUT_DIR").expect("No out dir");
+ let dest_path = Path::new(&out_dir);
+ let mut f = File::create(&dest_path.join("memory.x"))
+ .expect("Could not create file");
+
+ f.write_all(include_bytes!("memory.x"))
+ .expect("Could not write file");
+
+ println!("cargo:rustc-link-search={}", dest_path.display());
+
+ println!("cargo:rerun-if-changed=memory.x");
+ println!("cargo:rerun-if-changed=build.rs");
}
diff --git a/memory.x b/memory.x
new file mode 100644
index 0000000..6d8ae75
--- /dev/null
+++ b/memory.x
@@ -0,0 +1,13 @@
+MEMORY
+{
+ /* 0x0000_0000 is an alias for 0x08000_0000 */
+ FLASH(rwx) : ORIGIN = 0x00000000, LENGTH = 128K
+ RAM(rw) : ORIGIN = 0x20000000, LENGTH = 32K
+}
+
+REGION_ALIAS("REGION_TEXT", FLASH);
+REGION_ALIAS("REGION_RODATA", FLASH);
+REGION_ALIAS("REGION_DATA", RAM);
+REGION_ALIAS("REGION_BSS", RAM);
+REGION_ALIAS("REGION_HEAP", RAM);
+REGION_ALIAS("REGION_STACK", RAM);
diff --git a/src/led.rs b/src/led.rs
index d8d9912..951a32e 100644
--- a/src/led.rs
+++ b/src/led.rs
@@ -1,21 +1,23 @@
use gd32vf103_pac::Peripherals;
+#[derive(Clone, Copy)]
pub struct LED();
impl LED {
- pub fn new(peripherals: &Peripherals) -> Self {
- peripherals.RCU.apb2en.write(|w| {
+ pub fn new() -> Self {
+ let peripherals = unsafe { Peripherals::steal() };
+ peripherals.RCU.apb2en.modify(|_, w| {
w.paen().set_bit()
});
- peripherals.GPIOA.ctl0.write(|w| unsafe {
+ peripherals.GPIOA.ctl0.modify(|_, w| unsafe {
// output mode, push-pull
w.ctl7().bits(0b00);
// 50 mhz output rate
w.md7().bits(0b11);
w
});
- Self {}
+ Self()
}
pub fn is_on(&self) -> bool {
diff --git a/src/main.rs b/src/main.rs
index aee0767..2944500 100755
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,27 +3,98 @@
mod led;
-use core::arch::global_asm;
-use gd32vf103_pac::Peripherals;
+//use core::arch::global_asm;
+//use gd32vf103_pac::{self as pac, Interrupt, Peripherals};
+use gd32vf103xx_hal::{
+ eclic::{self, EclicExt},
+ pac::{self, Interrupt, Peripherals},
+ rcu::RcuExt,
+ time::Hertz,
+ timer,
+};
+use riscv::asm::wfi;
+use riscv_rt::entry;
+use gd32vf103xx_hal::prelude::_embedded_hal_timer_CountDown;
use led::LED;
-global_asm!(include_str!("boot.S"));
+// global_asm!(include_str!("boot.S"));
-#[no_mangle]
+enum State {
+ WaitForTime(timer::Timer<pac::TIMER6>, Hertz, LED),
+ ToggleLED(timer::Timer<pac::TIMER6>, Hertz, LED),
+}
+
+static mut DEBUG: usize = 1;
+
+impl State {
+ fn next(self) -> Self {
+ match self {
+ Self::WaitForTime(mut timer, duration, led) => {
+ match timer.wait() {
+ Ok(_) => {
+ unsafe {
+ DEBUG += 1
+ };
+
+ led.toggle();
+ timer.start(duration);
+ Self::WaitForTime(timer, duration, led)
+ },
+ Err(_) => Self::WaitForTime(timer, duration, led),
+ }
+ },
+
+ Self::ToggleLED(mut timer, duration, led) => {
+ unsafe {
+ DEBUG += 1
+ };
+ led.toggle();
+ timer.start(duration);
+ Self::WaitForTime(timer, duration, led)
+ },
+ }
+ }
+}
+
+#[entry]
fn main(_hartid: usize) -> ! {
- // let peripherals = Peripherals::take().unwrap();
- let peripherals = unsafe { Peripherals::steal() };
+ let p = unsafe { Peripherals::steal() };
+
+ pac::ECLIC::set_threshold_level(eclic::Level::L0);
+ pac::ECLIC::set_level_priority_bits(eclic::LevelPriorityBits::L3P1);
+
+ let t6 = p.TIMER6;
+ let mut rcu = p.RCU.configure().freeze();
+ let mut timer = timer::Timer::<pac::TIMER6>::timer6(t6, Hertz(10), &mut rcu);
+ pac::ECLIC::setup(Interrupt::TIMER6, eclic::TriggerType::RisingEdge, eclic::Level::L0, eclic::Priority::P3);
+ unsafe { pac::ECLIC::unmask(Interrupt::TIMER6); }
+ if !pac::ECLIC::is_enabled(Interrupt::TIMER6) {
+ panic!("timer6 interrupt not enabled");
+ }
+ timer.listen(timer::Event::Update);
- let led = LED::new(&peripherals);
+ let led = LED::new();
+ let mut state = State::ToggleLED(timer, Hertz(2), led);
loop {
- led.toggle();
- delay();
+ state = state.next();
+ unsafe { wfi() };
}
}
-fn delay() {
- for _ in 1..100_000 {}
+#[export_name="ExceptionHandler"]
+fn exception_handler(_frame: &riscv_rt::TrapFrame) -> ! {
+ loop { unsafe { wfi() } };
+}
+
+#[export_name="DefaultHandler"]
+fn default_handler() -> ! {
+ loop { unsafe { wfi() } };
+}
+
+#[export_name="MachineTimer"]
+fn machine_timer() {
+ loop { unsafe { wfi() } };
}
#[panic_handler]