diff --git a/src/main.rs b/src/main.rs index bfc8cbf..94b4770 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,19 +5,23 @@ mod display; mod keyboard; mod panic; +mod timer; +use avr_device::interrupt::Mutex; use calc_math::{ calc::{StackCalc, StackCalcError}, Decimal, }; +use core::{cell::RefCell, ops::DerefMut}; use display::{DispalyState, SegmentPins, Show}; use keyboard::{Debounce, KeyPress, KeyReadout, Keyboard}; use arduino_hal::{ adc::channel::{ADC6, ADC7}, - hal::port::{PB3, PB4, PC1, PC2, PC3, PD2, PD3, PD4, PD7}, + clock::Clock, + hal::port::{PB3, PB4, PB5, PC1, PC2, PC3, PD2, PD3, PD4, PD7}, port::{mode::Output, Pin}, - Adc, + Adc, DefaultClock, }; use ufmt::derive::uDebug; @@ -48,11 +52,20 @@ type Calc = StackCalc; // * Set another timer to run for 1ms. // * On another timer interrupt expire disable display (LEDs off) and handle keyboard input. +static LED: Mutex>>> = Mutex::new(RefCell::new(None)); + #[avr_device::interrupt(atmega328p)] -fn TIMER1_OVF() { +unsafe fn TIMER0_COMPA() { //TODO: Handle timer interrupt to display next segment // file:///home/hxd/projects/avr-calc/target/avr-none/doc/avr_device/interrupt/index.html // ... + avr_device::interrupt::free( + |cs| match LED.borrow(cs).borrow_mut().deref_mut().as_mut() { + Some(led) => led.toggle(), + None => panic!(), + }, + ); + //..toggle()); } struct IOSelect<'p> { @@ -458,6 +471,11 @@ fn main() -> ! { }; // TODO: configure timer, enable it to interrupt: dp.TC1.tifr1 + // https://github.com/monoper/rust-atmega328p/blob/main/arduino-nano/key-tmr-input/src/main.rs + timer::segment_timer_init(dp.TC0, (DefaultClock::FREQ / 1024 / 100) as u8); // 16_000_000 / 1024 / 100 => 156 + avr_device::interrupt::free(|cs| { + LED.borrow(cs).replace(Some(pins.d13.into_output())); + }); unsafe { avr_device::interrupt::enable(); diff --git a/src/timer.rs b/src/timer.rs new file mode 100644 index 0000000..5dd76b6 --- /dev/null +++ b/src/timer.rs @@ -0,0 +1,12 @@ +use arduino_hal::pac::TC0; + +pub fn segment_timer_init(tc0: TC0, counts: u8) { + // Use CTC mode: reset counter when matches compare value + tc0.tccr0a.write(|w| w.wgm0().ctc()); + // Set the compare value + tc0.ocr0a.write(|w| w.bits(counts)); + // Slow down the timer (CLK / prescale) + tc0.tccr0b.write(|w| w.cs0().prescale_1024()); + // Raise interrupt on reset + tc0.timsk0.write(|w| w.ocie0a().set_bit()); +}