diff --git a/Cargo.toml b/Cargo.toml index 43e16e3..e673b71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,11 @@ version = "0.1" [features] rt = ["va108xx/rt"] +[dev-dependencies] +panic-rtt-target = { version = "0.1", features = ["cortex-m"] } +rtt-target = { version = "0.3", features = ["cortex-m"] } +panic-halt = "0.2" + [profile.dev] debug = true lto = false @@ -32,3 +37,7 @@ lto = false lto = true debug = true opt-level = "s" + +[[example]] +name = "timer-ticks" +required-features = ["rt"] diff --git a/examples/timer-ticks.rs b/examples/timer-ticks.rs new file mode 100644 index 0000000..5e20f0b --- /dev/null +++ b/examples/timer-ticks.rs @@ -0,0 +1,124 @@ +//! MS and Second counter implemented using the TIM0 and TIM1 peripheral +#![no_main] +#![no_std] + +use core::cell::Cell; +use cortex_m::interrupt::Mutex; +use cortex_m_rt::entry; +use panic_rtt_target as _; +use rtt_target::{rprintln, rtt_init_print}; +use va108xx_hal::{ + clock::{get_sys_clock, set_sys_clock}, + pac::{self, interrupt}, + prelude::*, + time::Hertz, + timer::{CountDownTimer, Event}, +}; + +#[allow(dead_code)] +enum LibType { + Pac, + Hal, +} + +static MS_COUNTER: Mutex> = Mutex::new(Cell::new(0)); +static SEC_COUNTER: Mutex> = Mutex::new(Cell::new(0)); + +#[entry] +fn main() -> ! { + rtt_init_print!(); + let mut dp = pac::Peripherals::take().unwrap(); + let mut last_ms = 0; + rprintln!("-- Vorago system ticks using timers --"); + set_sys_clock(50.mhz().into()); + let lib_type = LibType::Hal; + match lib_type { + LibType::Pac => { + unsafe { + dp.SYSCONFIG + .peripheral_clk_enable + .modify(|_, w| w.irqsel().set_bit()); + dp.SYSCONFIG + .tim_clk_enable + .modify(|r, w| w.bits(r.bits() | (1 << 0) | (1 << 1))); + dp.IRQSEL.tim[0].write(|w| w.bits(0x00)); + dp.IRQSEL.tim[1].write(|w| w.bits(0x01)); + } + + let sys_clk: Hertz = 50.mhz().into(); + let cnt_ms = sys_clk.0 / 1000 - 1; + let cnt_sec = sys_clk.0 - 1; + unsafe { + dp.TIM0.cnt_value.write(|w| w.bits(cnt_ms)); + dp.TIM0.rst_value.write(|w| w.bits(cnt_ms)); + dp.TIM0.ctrl.write(|w| { + w.enable().set_bit(); + w.irq_enb().set_bit() + }); + dp.TIM1.cnt_value.write(|w| w.bits(cnt_sec)); + dp.TIM1.rst_value.write(|w| w.bits(cnt_sec)); + dp.TIM1.ctrl.write(|w| { + w.enable().set_bit(); + w.irq_enb().set_bit() + }); + unmask_irqs(); + } + } + LibType::Hal => { + let mut ms_timer = + CountDownTimer::tim0(&mut dp.SYSCONFIG, get_sys_clock().unwrap(), dp.TIM0); + let mut second_timer = + CountDownTimer::tim1(&mut dp.SYSCONFIG, get_sys_clock().unwrap(), dp.TIM1); + ms_timer.listen( + Event::TimeOut, + &mut dp.SYSCONFIG, + &mut dp.IRQSEL, + interrupt::OC0, + ); + second_timer.listen( + Event::TimeOut, + &mut dp.SYSCONFIG, + &mut dp.IRQSEL, + interrupt::OC1, + ); + ms_timer.start(1000.hz()); + second_timer.start(1.hz()); + unmask_irqs(); + } + } + loop { + let current_ms = cortex_m::interrupt::free(|cs| MS_COUNTER.borrow(cs).get()); + if current_ms - last_ms >= 1000 { + last_ms = current_ms; + rprintln!("MS counter: {}", current_ms); + let second = cortex_m::interrupt::free(|cs| SEC_COUNTER.borrow(cs).get()); + rprintln!("Second counter: {}", second); + } + cortex_m::asm::delay(10000); + } +} + +fn unmask_irqs() { + unsafe { + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC0); + cortex_m::peripheral::NVIC::unmask(pac::Interrupt::OC1); + } +} + +#[interrupt] +fn OC0() { + cortex_m::interrupt::free(|cs| { + let mut ms = MS_COUNTER.borrow(cs).get(); + ms += 1; + MS_COUNTER.borrow(cs).set(ms); + }); +} + +#[interrupt] +fn OC1() { + cortex_m::interrupt::free(|cs| { + let mut sec = SEC_COUNTER.borrow(cs).get(); + sec += 1; + SEC_COUNTER.borrow(cs).set(sec); + }); +}