GlobalTimer: add timer start with interrupt

pull/108/head
morgan 2023-12-14 12:54:38 +08:00
parent 0c29a20d36
commit 535c162034
1 changed files with 48 additions and 8 deletions

View File

@ -24,6 +24,43 @@ impl GlobalTimer {
pub fn start() -> GlobalTimer {
let mut regs = mpcore::RegisterBlock::mpcore();
Self::reset(&mut regs);
// Start
regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed()
.prescaler((Self::get_prescalar() - 1) as u8)
.auto_increment_mode(true)
.timer_enable(true)
);
GlobalTimer { regs }
}
// Get the timer with a reset and interrupt
pub fn start_with_interrupt(interrupt_period_us: u64) -> GlobalTimer {
let mut regs = mpcore::RegisterBlock::mpcore();
Self::reset(&mut regs);
let prescaler = Self::get_prescalar() as u64;
let clocks = Clocks::get();
let increment_val:u32 = (interrupt_period_us * clocks.cpu_3x2x() as u64 / (1_000_000 * (prescaler + 1))) as u32;
// When auto-increment and comp enable bits are set, an IRQ is generated periodically
unsafe{
regs.auto_increment.write(increment_val);
}
// Clear event flag
Self::clear_isr();
// Start
regs.global_timer_control.write(
mpcore::GlobalTimerControl::zeroed()
.prescaler((prescaler - 1) as u8)
.auto_increment_mode(true)
.comp_enable(true)
.irq_enable(true)
.timer_enable(true)
);
GlobalTimer { regs }
}
@ -40,21 +77,24 @@ impl GlobalTimer {
regs.global_timer_counter1.write(
mpcore::ValueRegister::zeroed()
);
}
pub fn clear_isr(){
let regs = mpcore::RegisterBlock::mpcore();
regs.global_timer_interrupt_status.write(
mpcore::GlobalTimerInterruptStatusRegister::zeroed()
.event_flag(true)
);
}
fn get_prescalar() -> u32 {
// 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()
.prescaler((prescaler - 1) as u8)
.auto_increment_mode(true)
.timer_enable(true)
);
prescaler
}
/// read the raw counter value