27 lines
1.1 KiB
Rust
27 lines
1.1 KiB
Rust
use arduino_hal::{clock::Clock, pac::TC0, DefaultClock};
|
|
|
|
// Sets up timer to rise two interrupts:
|
|
// 1. TIMER0_COMPA - every segment_rate_us μs
|
|
// 2. TIMER0_COMPB - segment_on_us μs after TIMER0_COMPA
|
|
pub fn segment_timer_init(tc0: TC0, segment_rate_us: u32, segment_on_us: u32) {
|
|
// 16_000_000 / 64 * 1000 / 1_000_000 => 250
|
|
let ocra = DefaultClock::FREQ / 64 * segment_rate_us / 1_000_000;
|
|
let ocrb = DefaultClock::FREQ / 64 * segment_on_us / 1_000_000;
|
|
assert!(ocra > ocrb);
|
|
|
|
// Use CTC mode: reset counter when matches compare value
|
|
tc0.tccr0a.write(|w| w.wgm0().ctc());
|
|
// Set the compare value for TOP (reset)
|
|
tc0.ocr0a
|
|
.write(|w| w.bits(ocra.try_into().expect("timer init seg_freq out of rage")));
|
|
// Set the compare value for B match
|
|
tc0.ocr0b
|
|
.write(|w| w.bits(ocrb.try_into().expect("timer init on_div out of rage")));
|
|
// Slow down the timer (CLK / prescale)
|
|
tc0.tccr0b.write(|w| w.cs0().prescale_64());
|
|
// Raise interrupt on TOP (reset)
|
|
// Raise interrupt on B match
|
|
tc0.timsk0
|
|
.write(|w| w.ocie0a().set_bit().ocie0b().set_bit());
|
|
}
|