aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 2944500d280c8a2db8886d21226880f14db598a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![no_std]
#![no_main]

mod led;

//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"));

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 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();
    let mut state = State::ToggleLED(timer, Hertz(2), led);
    loop {
        state = state.next();
        unsafe { wfi() };
    }
}

#[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]
fn panic(info: &core::panic::PanicInfo) -> ! {
    if let Some(loc) = info.location() {
        let _file = loc.file();
        let _line = loc.line();
        if let Some(_msg) = info.payload().downcast_ref::<&str>() {
            loop {}
        }
        loop {}
    }
    loop {}
}