use B compare match register to trigger interrupt
This commit is contained in:
31
src/main.rs
31
src/main.rs
@@ -18,10 +18,9 @@ use keyboard::{Debounce, KeyPress, KeyReadout, Keyboard};
|
|||||||
|
|
||||||
use arduino_hal::{
|
use arduino_hal::{
|
||||||
adc::channel::{ADC6, ADC7},
|
adc::channel::{ADC6, ADC7},
|
||||||
clock::Clock,
|
|
||||||
hal::port::{PB3, PB4, PB5, PC1, PC2, PC3, PD2, PD3, PD4, PD7},
|
hal::port::{PB3, PB4, PB5, PC1, PC2, PC3, PD2, PD3, PD4, PD7},
|
||||||
port::{mode::Output, Pin},
|
port::{mode::Output, Pin},
|
||||||
Adc, DefaultClock,
|
Adc,
|
||||||
};
|
};
|
||||||
use ufmt::derive::uDebug;
|
use ufmt::derive::uDebug;
|
||||||
|
|
||||||
@@ -41,6 +40,10 @@ pub const DISPLAY_SEGMENT_SIG_MINUS: usize = 0;
|
|||||||
pub const DISPLAY_SEGMENTS_EXP: usize = 2;
|
pub const DISPLAY_SEGMENTS_EXP: usize = 2;
|
||||||
pub const DISPLAY_SEGMENT_EXP_MINUS: usize = 6;
|
pub const DISPLAY_SEGMENT_EXP_MINUS: usize = 6;
|
||||||
|
|
||||||
|
// Timing
|
||||||
|
pub const IO_SEG_REFRESH_FREQ: u32 = 100; // Segment timer freq; from 62 to 15779 for 8bit counter
|
||||||
|
pub const IO_SEG_ON_DIV: u32 = 10; // How long to hold segment LEDs on as part of time for segment timer
|
||||||
|
|
||||||
pub const STACK_DEPTH: usize = 7;
|
pub const STACK_DEPTH: usize = 7;
|
||||||
|
|
||||||
type Calc = StackCalc<f32, STACK_DEPTH, 5, u8>;
|
type Calc = StackCalc<f32, STACK_DEPTH, 5, u8>;
|
||||||
@@ -61,11 +64,22 @@ unsafe fn TIMER0_COMPA() {
|
|||||||
// ...
|
// ...
|
||||||
avr_device::interrupt::free(
|
avr_device::interrupt::free(
|
||||||
|cs| match LED.borrow(cs).borrow_mut().deref_mut().as_mut() {
|
|cs| match LED.borrow(cs).borrow_mut().deref_mut().as_mut() {
|
||||||
Some(led) => led.toggle(),
|
// Some(led) => led.toggle(),
|
||||||
|
Some(led) => led.set_high(),
|
||||||
|
None => panic!(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[avr_device::interrupt(atmega328p)]
|
||||||
|
unsafe fn TIMER0_COMPB() {
|
||||||
|
//TODO: Disable display segment and handle keyboard input for current segment
|
||||||
|
avr_device::interrupt::free(
|
||||||
|
|cs| match LED.borrow(cs).borrow_mut().deref_mut().as_mut() {
|
||||||
|
Some(led) => led.set_low(),
|
||||||
None => panic!(),
|
None => panic!(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
//..toggle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IOSelect<'p> {
|
struct IOSelect<'p> {
|
||||||
@@ -470,13 +484,14 @@ fn main() -> ! {
|
|||||||
calculator: CalcluclatorState::EnterSignificant,
|
calculator: CalcluclatorState::EnterSignificant,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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| {
|
avr_device::interrupt::free(|cs| {
|
||||||
LED.borrow(cs).replace(Some(pins.d13.into_output()));
|
LED.borrow(cs).replace(Some(pins.d13.into_output()));
|
||||||
});
|
});
|
||||||
|
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
|
||||||
|
);
|
||||||
unsafe {
|
unsafe {
|
||||||
avr_device::interrupt::enable();
|
avr_device::interrupt::enable();
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/timer.rs
24
src/timer.rs
@@ -1,12 +1,24 @@
|
|||||||
use arduino_hal::pac::TC0;
|
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;
|
||||||
|
|
||||||
pub fn segment_timer_init(tc0: TC0, counts: u8) {
|
|
||||||
// Use CTC mode: reset counter when matches compare value
|
// Use CTC mode: reset counter when matches compare value
|
||||||
tc0.tccr0a.write(|w| w.wgm0().ctc());
|
tc0.tccr0a.write(|w| w.wgm0().ctc());
|
||||||
// Set the compare value
|
// Set the compare value for TOP (reset)
|
||||||
tc0.ocr0a.write(|w| w.bits(counts));
|
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)
|
// Slow down the timer (CLK / prescale)
|
||||||
tc0.tccr0b.write(|w| w.cs0().prescale_1024());
|
tc0.tccr0b.write(|w| w.cs0().prescale_1024());
|
||||||
// Raise interrupt on reset
|
// Raise interrupt on counter TOP (reset)
|
||||||
tc0.timsk0.write(|w| w.ocie0a().set_bit());
|
// Raise interrupt on B match
|
||||||
|
tc0.timsk0
|
||||||
|
.write(|w| w.ocie0a().set_bit().ocie0b().set_bit());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user