aboutsummaryrefslogtreecommitdiffstats
path: root/src
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 /src
parent8f9bc49bb40e2972cf0c0bf1b61eb8127a9397df (diff)
downloadluchie-35248b205cd56633e52b9e634a942e7fd987db0b.tar.gz
luchie-35248b205cd56633e52b9e634a942e7fd987db0b.zip
Blinky on a hardware timer, with ‘wfi’ in between.
Diffstat (limited to 'src')
-rw-r--r--src/led.rs10
-rwxr-xr-xsrc/main.rs93
2 files changed, 88 insertions, 15 deletions
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]