From e98a24d32db36236a6f04b30801ecedaea51b9f6 Mon Sep 17 00:00:00 2001 From: Hexa Dust Date: Sat, 4 Oct 2025 14:14:10 +0100 Subject: [PATCH] timer debugging --- src/main.rs | 42 +++++++++++++++++++++++++++++++++++++++--- src/timer.rs | 12 ++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index f4a18a9..e936d01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,6 +51,7 @@ pub const IO_SEGMENT_ON_MIN_US: u32 = 80; // How long in μs to hold segment LED pub const IO_SEGMENT_ON_MAX_US: u32 = 700; // How long in μs to hold segment LEDs on (bright) //TODO: When inline it is much slower due to use of Brightness instead of const 0xFF?! +//TODO: Optimize this code, currently it does 2 add, 1 sub, 1 mul and 1 div all on 32bit numbers! #[inline(never)] fn scale_brightness(b: Brightness) -> u32 { assert_eq!((Brightness::full().unwrap() as u32), 0xFF); @@ -91,9 +92,12 @@ fn access_global<'cs, 'v: 'cs, T, O>( #[avr_device::interrupt(atmega328p)] unsafe fn TIMER0_COMPA() { avr_device::interrupt::free(|cs| { - let brightness = access_global(&IO_LOOP, cs, |io_loop| io_loop.display_on()); - access_global(&SEGMENT_TIMER, cs, |st| { - st.segment_on_time(scale_brightness(brightness)) + access_global(&IO_LOOP, cs, |io_loop| { + access_global(&SEGMENT_TIMER, cs, |st| { + let brightness = io_loop.display_on(); + let elapsed = st.segment_on_time(scale_brightness(brightness)); + io_loop.frame_data = Some((elapsed, brightness.unwrap())); + }); }); }); } @@ -115,24 +119,28 @@ unsafe fn TIMER0_COMPB() { pub struct IOLoop { index: usize, + frame: u16, io_pins: IOPins, segment_pins: SegmentPins, dispaly: DispalyState, keyboard: Keyboard, readount: Option, debounce: Debounce, + frame_data: Option<(u8, u8)>, } impl IOLoop { pub fn new(io_pins: IOPins, segment_pins: SegmentPins, keyboard: Keyboard) -> IOLoop { IOLoop { index: 0, + frame: 0, io_pins, segment_pins, dispaly: Default::default(), keyboard, readount: None, debounce: Default::default(), + frame_data: None, } } @@ -151,6 +159,8 @@ impl IOLoop { pub fn advance(&mut self) -> Option { self.index += 1; if self.index == self.io_pins.len() || self.index == self.dispaly.len() { + // Frame done + self.frame = self.frame.wrapping_add(1); // Start from first segment self.index = 0; @@ -181,6 +191,14 @@ impl IOLoop { } self.select_off(); } + + pub fn frame(&self) -> (u16, usize) { + (self.frame, self.index) + } + + pub fn frame_data(&self) -> Option<(u8, u8)> { + self.frame_data + } } #[derive(uDebug)] @@ -526,6 +544,7 @@ fn main() -> ! { let mut display = DispalyState::default(); number_input.show(&mut display); + let mut frame_data_index: usize = 0; let mut calc = Calc::default(); let mut state = State { transient: TransientState::Done, @@ -557,6 +576,12 @@ fn main() -> ! { state.calculator ) .ok(); + match key { + KeyPress::Num(n) => { + frame_data_index = n as usize; + } + _ => (), + } match state.calculator.on_key(key, &mut number_input, &mut calc) { Ok(new_state) => state.calculator = new_state, Err(err) => { @@ -616,6 +641,17 @@ fn main() -> ! { avr_device::interrupt::free(|cs| { access_global(&IO_LOOP, cs, |io_loop| { io_loop.update_display(&display); + let (frame, index) = io_loop.frame(); + if frame % 64 == 0 && index == frame_data_index { + ufmt::uwriteln!( + &mut serial, + "[{}, {}] {:?}", + frame, + index, + io_loop.frame_data() + ) + .ok(); + } }); }); } diff --git a/src/timer.rs b/src/timer.rs index 8885aa8..6fcba95 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -10,7 +10,9 @@ const fn us_to_ticks(us: u32) -> u32 { } // Timer 0 (8bit) -pub struct SegmentTimer(TC0); +pub struct SegmentTimer { + timer: TC0, +} impl SegmentTimer { // Sets up timer to rise interrupts: @@ -36,19 +38,21 @@ impl SegmentTimer { tc0.timsk0 .write(|w| w.ocie0a().set_bit().ocie0b().set_bit()); - SegmentTimer(tc0) + SegmentTimer { timer: tc0 } } // Set for how long the segment LEDs should be on in μs // Controls TIMER0_COMPB interrupt time after TIMER0_COMPA - pub fn segment_on_time(&mut self, segment_on_us: u32) { + pub fn segment_on_time(&mut self, segment_on_us: u32) -> u8 { let ocrb = us_to_ticks(segment_on_us); + let elapsed = self.timer.tcnt0.read().bits(); // Set the compare value for B match - self.0.ocr0b.write(|w| { + self.timer.ocr0b.write(|w| { w.bits( ocrb.try_into() .expect("timer init segment_on_us out of rage"), ) }); + return elapsed; } }