use core::cell::RefCell; use core::ops::Deref; use cortex_m::interrupt::Mutex; use cortex_m::peripheral::syst::SystClkSource; use cortex_m_rt::exception; use stm32f4xx_hal::{ rcc::Clocks, pac::SYST, }; /// Rate in Hz const TIMER_RATE: u32 = 1000; /// Interval duration in milliseconds const TIMER_DELTA: u32 = 1000 / TIMER_RATE; /// Elapsed time in milliseconds static TIMER_MS: Mutex> = Mutex::new(RefCell::new(0)); /// Setup SysTick exception pub fn setup(mut syst: SYST, clocks: Clocks) { syst.set_clock_source(SystClkSource::Core); syst.set_reload(clocks.hclk().to_Hz() / TIMER_RATE - 1); syst.enable_counter(); syst.enable_interrupt(); } /// SysTick exception (Timer) #[exception] fn SysTick() { cortex_m::interrupt::free(|cs| { *TIMER_MS.borrow(cs) .borrow_mut() += TIMER_DELTA; }); } /// Obtain current time in milliseconds pub fn now() -> u32 { cortex_m::interrupt::free(|cs| { *TIMER_MS.borrow(cs) .borrow() .deref() }) } /// block for `amount` milliseconds pub fn sleep(amount: u32) { if amount == 0 { return; } let start = now(); while now() - start <= amount - 1 {} }