aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: 6cb41399935d98806f8ab0c6ab4444e3dd2a1b7b (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
#![no_std]
#![no_main]

mod blink;
mod led;
mod log;

use gd32vf103xx_hal::{
    afio::AfioExt,
    eclic::{self, EclicExt},
    gpio::GpioExt,
    pac::{self, Peripherals},
    rcu::RcuExt,
    serial::Serial,
    time::Hertz,
    timer::Timer,
};
use riscv::{
    asm::wfi,
    interrupt,
};
use riscv_rt::entry;

use led::LED;

// global_asm!(include_str!("boot.S"));

#[entry]
fn main(_hartid: usize) -> ! {
    let p = Peripherals::take().expect("couldn't take peripherals");

    pac::ECLIC::set_threshold_level(eclic::Level::L0);
    pac::ECLIC::set_level_priority_bits(eclic::LevelPriorityBits::L3P1);

    let mut rcu = p.RCU.configure().freeze();
    let mut afio = p.AFIO.constrain(&mut rcu);
    let gpioa = p.GPIOA.split(&mut rcu);

    // TODO: figure out how to use the usb serial on the start board.
    //
    // this version has to be wired up physically.
    let serial = Serial::new(
        p.USART1,
        (gpioa.pa2, gpioa.pa3),
        Default::default(),
        &mut afio,
        &mut rcu,
    );
    let (tx, _rx) = serial.split();
    log::init(tx);

    let timer = Timer::<pac::TIMER6>::timer6(p.TIMER6, Hertz(1), &mut rcu);
    let led = LED::new(gpioa.pa7);
    let mut blink = blink::Task::new(timer, Hertz(5), led);

    loop {
        let mut can_sleep = true;

        if let Ok(_) = blink.poll() {
            can_sleep = false;
        }
        log!("yo!");
        logln!(" mtv raps");

        if can_sleep {
            unsafe { wfi() };
        }
    }
}

#[export_name="ExceptionHandler"]
fn exception_handler(_frame: &riscv_rt::TrapFrame) -> ! {
    spin();
}

#[export_name="DefaultHandler"]
fn default_handler() -> ! {
    spin();
}

#[export_name="MachineTimer"]
fn machine_timer() {
    spin();
}

#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
    interrupt::free(|_cs| {
        log!("!!! panic ");
        if let Some(loc) = info.location() {
            log!("in {}:{} ", loc.file(), loc.line());
        }
        if let Some(msg) = info.payload().downcast_ref::<&str>() {
            log!("⇒ {} ", msg);
        }
        logln!("!!!");
    });
    spin();
}

fn spin() -> ! {
    loop { unsafe { wfi() } };
}