forked from M-Labs/ionpak-thermostat
systick: implement nanosecond precision
This commit is contained in:
parent
4249addba2
commit
25dc3fb70c
|
@ -4,15 +4,22 @@ use cortex_m::peripheral::{SYST, syst::SystClkSource};
|
||||||
use cortex_m_rt::exception;
|
use cortex_m_rt::exception;
|
||||||
use bare_metal::CriticalSection;
|
use bare_metal::CriticalSection;
|
||||||
|
|
||||||
const SYSTICK_RATE: u32 = 250;
|
|
||||||
|
|
||||||
static mut TIME: Mutex<RefCell<u64>> = Mutex::new(RefCell::new(0));
|
static mut TIME: Mutex<RefCell<u64>> = Mutex::new(RefCell::new(0));
|
||||||
|
/// In HZ
|
||||||
|
const RATE: u32 = 10;
|
||||||
|
/// Period between to interrupts in ns
|
||||||
|
const INTERVAL: u64 = 1_000_000 / RATE as u64;
|
||||||
|
|
||||||
pub fn init(cs: &CriticalSection) {
|
fn syst() -> &'static mut SYST {
|
||||||
#[allow(mutable_transmutes)]
|
#[allow(mutable_transmutes)]
|
||||||
let syst: &mut SYST = unsafe { core::mem::transmute(&*SYST::ptr()) };
|
unsafe { core::mem::transmute(&*SYST::ptr()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(_cs: &CriticalSection) {
|
||||||
|
let syst = syst();
|
||||||
|
// syst.set_clock_source(SystClkSource::Core);
|
||||||
syst.set_clock_source(SystClkSource::External);
|
syst.set_clock_source(SystClkSource::External);
|
||||||
syst.set_reload(100 * SYST::get_ticks_per_10ms() / SYSTICK_RATE);
|
syst.set_reload(100 * SYST::get_ticks_per_10ms() / RATE);
|
||||||
syst.clear_current();
|
syst.clear_current();
|
||||||
syst.enable_interrupt();
|
syst.enable_interrupt();
|
||||||
syst.enable_counter();
|
syst.enable_counter();
|
||||||
|
@ -20,14 +27,17 @@ pub fn init(cs: &CriticalSection) {
|
||||||
|
|
||||||
#[exception]
|
#[exception]
|
||||||
unsafe fn SysTick() {
|
unsafe fn SysTick() {
|
||||||
let interval = u64::from(1000 / SYSTICK_RATE);
|
|
||||||
cortex_m::interrupt::free(|cs| {
|
cortex_m::interrupt::free(|cs| {
|
||||||
TIME.borrow(cs).replace_with(|time| *time + interval);
|
TIME.borrow(cs).replace_with(|time| *time + INTERVAL);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_time() -> u64 {
|
pub fn get_time() -> u64 {
|
||||||
cortex_m::interrupt::free(|cs| {
|
let base = cortex_m::interrupt::free(|cs| {
|
||||||
*unsafe { &mut TIME }.borrow(cs).borrow()
|
*unsafe { &mut TIME }.borrow(cs).borrow()
|
||||||
})
|
});
|
||||||
|
let syst_current = u64::from(SYST::get_current());
|
||||||
|
let syst_reload = u64::from(SYST::get_reload());
|
||||||
|
let precise = INTERVAL - (INTERVAL * syst_current / syst_reload);
|
||||||
|
base + u64::from(precise)
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,7 +181,7 @@ fn main() -> ! {
|
||||||
// if a socket has sent the latest data
|
// if a socket has sent the latest data
|
||||||
let mut socket_pending = [false; 8];
|
let mut socket_pending = [false; 8];
|
||||||
loop {
|
loop {
|
||||||
adc.data_ready()
|
let _ = adc.data_ready()
|
||||||
.and_then(|channel|
|
.and_then(|channel|
|
||||||
channel.map(|channel|
|
channel.map(|channel|
|
||||||
adc.read_data().map(|new_data| {
|
adc.read_data().map(|new_data| {
|
||||||
|
@ -199,7 +199,6 @@ fn main() -> ! {
|
||||||
for p in socket_pending.iter_mut() {
|
for p in socket_pending.iter_mut() {
|
||||||
*p = true;
|
*p = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
for (&tcp_handle, pending) in handles.iter().zip(socket_pending.iter_mut()) {
|
for (&tcp_handle, pending) in handles.iter().zip(socket_pending.iter_mut()) {
|
||||||
let socket = &mut *sockets.get::<TcpSocket>(tcp_handle);
|
let socket = &mut *sockets.get::<TcpSocket>(tcp_handle);
|
||||||
|
@ -223,7 +222,7 @@ fn main() -> ! {
|
||||||
*pending = false;
|
*pending = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match iface.poll(&mut sockets, Instant::from_millis(get_time() as i64)) {
|
match iface.poll(&mut sockets, Instant::from_millis((get_time() / 1000) as i64)) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => println!("poll error: {}", e)
|
Err(e) => println!("poll error: {}", e)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue