use core::cell::RefCell; use core::ops::DerefMut; use cortex_m::interrupt::{free, Mutex}; use stm32f1xx_hal::{ delay::Delay, pac::interrupt, pac::{Interrupt, TIM2}, prelude::*, rcc::{Clocks, APB1}, serial::{Config, Serial}, stm32, timer::{CountDownTimer, Event, Timer}, }; use nmea0183::datetime::Time; static TIME: Mutex> = Mutex::new(RefCell::new(Time { hours: 0, minutes: 0, seconds: 0.0, })); static TIMER_TIM2: Mutex>>> = Mutex::new(RefCell::new(None)); pub fn setup(tim2: TIM2, clocks: &Clocks, apb1: &mut APB1) { let mut timer = Timer::tim2(tim2, clocks, apb1).start_count_down(1.khz()); // Generate an interrupt when the timer expires timer.listen(Event::Update); // Move the timer into our global storage cortex_m::interrupt::free(|cs| *TIMER_TIM2.borrow(cs).borrow_mut() = Some(timer)); unsafe { cortex_m::peripheral::NVIC::unmask(Interrupt::TIM2); } } #[interrupt] fn TIM2() { free(|cs| { if let Some(ref mut tim2) = TIMER_TIM2.borrow(cs).borrow_mut().deref_mut() { tim2.clear_update_interrupt_flag(); } let mut time = TIME.borrow(cs).borrow_mut(); time.seconds += 0.001; if time.seconds >= 60.0 { time.seconds -= 60.0; time.minutes += 1; } if time.minutes == 60 { time.minutes = 0; time.hours += 1; } if time.hours == 24 { time.hours = 0; } }); } pub fn get() -> Time { let mut res = Time { hours: 0, minutes: 0, seconds: 0.0, }; free(|cs| { let time = TIME.borrow(cs).borrow(); res.seconds = time.seconds; res.minutes = time.minutes; res.hours = time.hours; }); return res; } pub fn set(new_time: &Time) -> () { free(|cs| { let mut time = TIME.borrow(cs).borrow_mut(); let sec_delta = time.seconds - new_time.seconds; if time.hours != new_time.hours || time.minutes != new_time.minutes || sec_delta > 0.05 || sec_delta < -0.05 { time.seconds = new_time.seconds; time.minutes = new_time.minutes; time.hours = new_time.hours; } }); } pub fn get_timestamp() -> u32 { let mut res = 0; free(|cs| { let time = TIME.borrow(cs).borrow(); res = (time.seconds * 1000.0) as u32; res += (time.minutes as u32) * 60 * 1000; res += (time.hours as u32) * 60 * 60 * 1000; }); return res; }