From cba331b93968437d694a2b6f5de42935109ac02b Mon Sep 17 00:00:00 2001 From: Hexa Dust Date: Fri, 18 Jul 2025 20:31:23 +0100 Subject: [PATCH] refactoring of timing constants --- src/main.rs | 13 +++++++------ src/timer.rs | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main.rs b/src/main.rs index 91e81e3..26982f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,11 +44,12 @@ pub const DISPLAY_SEGMENTS_EXP: usize = 2; pub const DISPLAY_SEGMENT_EXP_MINUS: usize = 6; // Timing -pub const IO_SEG_REFRESH_FREQ: u32 = 1000; // Segment timer freq; from 62 to 15779 for 8bit counter -pub const IO_SEG_ON_DIV: u32 = 4; // How long to hold segment LEDs on as part of time for segment timer +// Note: it takes ~224 μs to read keyboard after segment off +pub const IO_SEGMENT_RATE_US: u32 = 1000; // Time in μs between segment updates +pub const IO_SEGMENT_ON_US: u32 = 200; // How long in μs to hold segment LEDs on +// Calculator setup pub const STACK_DEPTH: usize = 7; - type Calc = StackCalc; // Interrupt driven I/O @@ -528,9 +529,9 @@ fn main() -> ! { ADC.borrow(cs).replace(Some(adc)); }); timer::segment_timer_init( - dp.TC0, // Timer0 (8bit) - IO_SEG_REFRESH_FREQ, // run segments at 100Hz - IO_SEG_ON_DIV, // 1/10th of 100Hz, 1ms segment on time + dp.TC0, // Timer0 (8bit) + IO_SEGMENT_RATE_US, + IO_SEGMENT_ON_US, ); unsafe { avr_device::interrupt::enable(); diff --git a/src/timer.rs b/src/timer.rs index 9e307f0..71b9eac 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -1,11 +1,13 @@ use arduino_hal::{clock::Clock, pac::TC0, DefaultClock}; -// Raises two interrupts: TIMER0_COMPA every period cycles/1024 -// and TIMER0_COMPB compb_cocunt cycles/1024 after TIMER0_COMPA -pub fn segment_timer_init(tc0: TC0, seg_freq: u32, on_div: u32) { - // 16_000_000 / 1024 / 100 => 156 (100Hz|10ms) - let ocra = DefaultClock::FREQ / 1024 / seg_freq; - let ocrb: u32 = ocra / on_div; +// 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()); @@ -16,8 +18,8 @@ pub fn segment_timer_init(tc0: TC0, seg_freq: u32, on_div: u32) { 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_1024()); - // Raise interrupt on counter TOP (reset) + 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());