fw: refactor timer stuff into its own module
This commit is contained in:
parent
a132f2e1f1
commit
034160b301
@ -7,7 +7,6 @@ extern crate panic_halt;
|
|||||||
|
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use core::{
|
use core::{
|
||||||
arch::asm,
|
|
||||||
ptr::{read_volatile, write_volatile},
|
ptr::{read_volatile, write_volatile},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,11 +32,12 @@ mod mcp4726;
|
|||||||
mod proto;
|
mod proto;
|
||||||
mod uart;
|
mod uart;
|
||||||
mod sampler;
|
mod sampler;
|
||||||
|
mod timer;
|
||||||
|
|
||||||
|
use timer::millis;
|
||||||
|
|
||||||
const MAC: [u8; 6] = [0xA0, 0xBB, 0xCC, 0xDD, 0xEE, 0xF0];
|
const MAC: [u8; 6] = [0xA0, 0xBB, 0xCC, 0xDD, 0xEE, 0xF0];
|
||||||
|
|
||||||
static mut SECONDS: u32 = 0;
|
|
||||||
|
|
||||||
// use `main` as the entry point of this application
|
// use `main` as the entry point of this application
|
||||||
// `main` is not allowed to return
|
// `main` is not allowed to return
|
||||||
#[entry]
|
#[entry]
|
||||||
@ -111,13 +111,7 @@ fn main() -> ! {
|
|||||||
//defmt::info!("Done setup");
|
//defmt::info!("Done setup");
|
||||||
|
|
||||||
// Set up timer for polling events
|
// Set up timer for polling events
|
||||||
unsafe {
|
timer::init();
|
||||||
// Timer stuff
|
|
||||||
write_reg(0xf000_3808, 0u32); // Disable timer
|
|
||||||
write_reg(0xf000_3800, 0u32); // Set LOAD value
|
|
||||||
write_reg(0xf000_3804, 60_000_000u32); // Set RELOAD value
|
|
||||||
write_reg(0xf000_3808, 1u32); // Enable timer
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cmd = command_interface::CommandInterface::new();
|
let mut cmd = command_interface::CommandInterface::new();
|
||||||
|
|
||||||
@ -156,33 +150,11 @@ fn main() -> ! {
|
|||||||
|
|
||||||
// TODO I think the timer might actually stop until the event is cleared? this may pose
|
// TODO I think the timer might actually stop until the event is cleared? this may pose
|
||||||
// problems, might explain why moving this above the smoltcp stuff "broke" things
|
// problems, might explain why moving this above the smoltcp stuff "broke" things
|
||||||
handle_timer_event();
|
timer::poll();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_timer_event() {
|
|
||||||
unsafe {
|
|
||||||
if read_reg::<u32>(0xf000_3818) == 0 {
|
|
||||||
// No event yet, continue
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear TIMER0 event status, and update time
|
|
||||||
write_reg(0xf000_3818, 1u32);
|
|
||||||
SECONDS += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn busy_wait(ms: u32) {
|
|
||||||
let start = millis();
|
|
||||||
while millis() - start < ms {
|
|
||||||
unsafe {
|
|
||||||
asm!("nop");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_led(val: u32) {
|
fn write_led(val: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
write_reg(0xf000_2000, val);
|
write_reg(0xf000_2000, val);
|
||||||
@ -196,16 +168,3 @@ unsafe fn write_reg<T>(addr: u32, value: T) {
|
|||||||
unsafe fn read_reg<T>(addr: u32) -> T {
|
unsafe fn read_reg<T>(addr: u32) -> T {
|
||||||
return read_volatile(addr as *mut T);
|
return read_volatile(addr as *mut T);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn millis() -> u32 {
|
|
||||||
riscv::interrupt::free(|| {
|
|
||||||
unsafe {
|
|
||||||
// Latch timer value
|
|
||||||
write_reg(0xf000_380c, 1u32);
|
|
||||||
// Read timer value
|
|
||||||
let val: u32 = read_reg(0xf000_3810);
|
|
||||||
let val = 60_000_000 - val;
|
|
||||||
(SECONDS * 1000) + val / 60_000
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
79
firmware/src/timer.rs
Normal file
79
firmware/src/timer.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//! Simple module to use LiteX TIMER0 for simple timekeeping
|
||||||
|
|
||||||
|
use crate::{read_reg, write_reg};
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
/// Initializes the timer to use for polling events as a wall clock.
|
||||||
|
///
|
||||||
|
/// Timer is running at system frequency (60MHz)
|
||||||
|
pub fn init() {
|
||||||
|
unsafe {
|
||||||
|
write_reg(0xf000_3808, 0u32); // Disable timer
|
||||||
|
write_reg(0xf000_3800, 0u32); // Set LOAD value
|
||||||
|
write_reg(0xf000_3804, 60_000_000u32); // Set RELOAD value
|
||||||
|
write_reg(0xf000_3808, 1u32); // Enable timer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage for overflow time
|
||||||
|
static mut SECONDS: u32 = 0;
|
||||||
|
|
||||||
|
/// Processes potential timer events. Must be polled regularly
|
||||||
|
pub fn poll() {
|
||||||
|
unsafe {
|
||||||
|
if read_reg::<u32>(0xf000_3818) == 0 {
|
||||||
|
// No event yet, continue
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear TIMER0 event status, and update time
|
||||||
|
write_reg(0xf000_3818, 1u32);
|
||||||
|
SECONDS += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets system time in milliseconds
|
||||||
|
pub fn millis() -> u32 {
|
||||||
|
riscv::interrupt::free(|| {
|
||||||
|
unsafe {
|
||||||
|
// Latch timer value
|
||||||
|
write_reg(0xf000_380c, 1u32);
|
||||||
|
// Read timer value
|
||||||
|
let val: u32 = read_reg(0xf000_3810);
|
||||||
|
let val = 60_000_000 - val;
|
||||||
|
(SECONDS * 1000) + val / 60_000
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets system time in microseconds
|
||||||
|
pub fn micros() -> u64 {
|
||||||
|
riscv::interrupt::free(|| {
|
||||||
|
unsafe {
|
||||||
|
// Latch timer value
|
||||||
|
write_reg(0xf000_380c, 1u32);
|
||||||
|
// Read timer value
|
||||||
|
let val: u32 = read_reg(0xf000_3810);
|
||||||
|
let val = 60_000_000 - val;
|
||||||
|
(SECONDS as u64 * 1_000_000) + (val as u64 / 60)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn busy_wait_ms(ms: u32) {
|
||||||
|
let start = millis();
|
||||||
|
while millis() - start < ms {
|
||||||
|
unsafe {
|
||||||
|
asm!("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn busy_wait_us(us: u64) {
|
||||||
|
let start = micros();
|
||||||
|
while micros() - start < us {
|
||||||
|
unsafe {
|
||||||
|
asm!("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user