From 35248b205cd56633e52b9e634a942e7fd987db0b Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Sat, 6 Aug 2022 12:12:37 -0400 Subject: =?UTF-8?q?Blinky=20on=20a=20hardware=20timer,=20with=20=E2=80=98w?= =?UTF-8?q?fi=E2=80=99=20in=20between.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cargo/config.toml | 8 ++- Cargo.lock | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 3 + build.rs | 18 +++++- memory.x | 13 ++++ src/led.rs | 10 +-- src/main.rs | 93 +++++++++++++++++++++++---- 7 files changed, 302 insertions(+), 23 deletions(-) create mode 100644 memory.x 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,26 +17,76 @@ 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" @@ -48,6 +98,9 @@ name = "luchie" version = "0.1.0" dependencies = [ "gd32vf103-pac", + "gd32vf103xx-hal", + "riscv 0.8.0", + "riscv-rt", ] [[package]] @@ -56,6 +109,45 @@ version = "2.5.0" 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" @@ -79,11 +171,45 @@ 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" @@ -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]] @@ -112,14 +247,49 @@ dependencies = [ "semver-parser", ] +[[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, Hertz, LED), + ToggleLED(timer::Timer, 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::::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] -- cgit v1.2.3