From fe6a058a6b17d573282a78ea03b328107be6ebba Mon Sep 17 00:00:00 2001 From: Astro Date: Sat, 25 Apr 2020 02:59:48 +0200 Subject: [PATCH] libboard_zynq: find prescaler for GlobalTimer, rename new() to start() --- experiments/src/main.rs | 2 +- libboard_zynq/src/mpcore.rs | 2 +- libboard_zynq/src/timer/global.rs | 20 ++++++++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 50a117d..65b7848 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -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"))] diff --git a/libboard_zynq/src/mpcore.rs b/libboard_zynq/src/mpcore.rs index 8bb791c..1b3a077 100644 --- a/libboard_zynq/src/mpcore.rs +++ b/libboard_zynq/src/mpcore.rs @@ -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); diff --git a/libboard_zynq/src/timer/global.rs b/libboard_zynq/src/timer/global.rs index 758e890..633a7eb 100644 --- a/libboard_zynq/src/timer/global.rs +++ b/libboard_zynq/src/timer/global.rs @@ -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) );