diff options
author | Brian Cully <bjc@kublai.com> | 2022-08-06 12:12:37 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2022-08-06 12:12:37 -0400 |
commit | 35248b205cd56633e52b9e634a942e7fd987db0b (patch) | |
tree | 37c9fd21e52e7cb0a7c547065a52d73d19d925b9 /src | |
parent | 8f9bc49bb40e2972cf0c0bf1b61eb8127a9397df (diff) | |
download | luchie-35248b205cd56633e52b9e634a942e7fd987db0b.tar.gz luchie-35248b205cd56633e52b9e634a942e7fd987db0b.zip |
Blinky on a hardware timer, with ‘wfi’ in between.
Diffstat (limited to 'src')
-rw-r--r-- | src/led.rs | 10 | ||||
-rwxr-xr-x | src/main.rs | 93 |
2 files changed, 88 insertions, 15 deletions
@@ -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] |