libboard_zynq: find prescaler for GlobalTimer, rename new() to start()

pull/29/head
Astro 2020-04-25 02:59:48 +02:00
parent 22555017fe
commit fe6a058a6b
3 changed files with 18 additions and 6 deletions

View File

@ -72,7 +72,7 @@ pub fn main_core0() {
}
let mut flash = flash.stop();
let timer = libboard_zynq::timer::GlobalTimer::new();
let timer = libboard_zynq::timer::GlobalTimer::start();
let mut ddr = zynq::ddr::DdrRam::new();
#[cfg(not(feature = "target_zc706"))]

View File

@ -92,7 +92,7 @@ register!(value_register, ValueRegister, RW, u32);
register_bits!(value_register, value, u32, 0, 31);
register!(global_timer_control, GlobalTimerControl, RW, u32);
register_bits!(global_timer_control, prescaler, u16, 8, 15);
register_bits!(global_timer_control, prescaler, u8, 8, 15);
register_bit!(global_timer_control, auto_increment_mode, 3);
register_bit!(global_timer_control, irq_enable, 2);
register_bit!(global_timer_control, comp_enablea, 1);

View File

@ -13,7 +13,14 @@ pub struct GlobalTimer {
}
impl GlobalTimer {
pub fn new() -> GlobalTimer {
/// Get the potentially uninitialized timer
pub unsafe fn get() -> GlobalTimer {
let mut regs = mpcore::RegisterBlock::new();
GlobalTimer { regs }
}
/// Get the timer with a reset
pub fn start() -> GlobalTimer {
let mut regs = mpcore::RegisterBlock::new();
Self::reset(&mut regs);
GlobalTimer { regs }
@ -33,12 +40,17 @@ impl GlobalTimer {
mpcore::ValueRegister::zeroed()
);
// find a prescaler value that matches CPU speed / 2 to us
let clocks = Clocks::get();
let mut prescaler = clocks.cpu_3x2x() / 1_000_000;
while prescaler > 256 {
prescaler /= 2;
}
// Start
regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed()
// maximum prescaler is still enough for millisecond
// precision while overflowing after centuries.
.prescaler(255)
.prescaler((prescaler - 1) as u8)
.auto_increment_mode(true)
.timer_enable(true)
);