105 lines
2.6 KiB
Rust
105 lines
2.6 KiB
Rust
|
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<RefCell<Time>> = Mutex::new(RefCell::new(Time {
|
||
|
hours: 0,
|
||
|
minutes: 0,
|
||
|
seconds: 0.0,
|
||
|
}));
|
||
|
|
||
|
static TIMER_TIM2: Mutex<RefCell<Option<CountDownTimer<TIM2>>>> = 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;
|
||
|
}
|