-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimer_compare.rs
110 lines (90 loc) · 3.02 KB
/
timer_compare.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#![no_std]
#![no_main]
#![feature(abi_avr_interrupt)]
extern crate panic_halt;
use m48_robo_rust::{delay_ms, hal::port::*, prelude::*};
static mut LEDS: Option<[Pin<mode::Output>; 7]> = None;
static mut NUM: u8 = 0;
const SEG_A: u8 = 1u8 << 0;
const SEG_B: u8 = 1u8 << 1;
const SEG_C: u8 = 1u8 << 2;
const SEG_D: u8 = 1u8 << 3;
const SEG_E: u8 = 1u8 << 4;
const SEG_F: u8 = 1u8 << 5;
const SEG_G: u8 = 1u8 << 6;
const NUMS: [u8; 10] = [
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, // 0
SEG_B | SEG_C, // 1
SEG_A | SEG_B | SEG_G | SEG_E | SEG_D, // 2
SEG_A | SEG_B | SEG_G | SEG_C | SEG_D, // 3
SEG_F | SEG_G | SEG_B | SEG_C, // 4
SEG_A | SEG_F | SEG_G | SEG_C | SEG_D, // 5
SEG_F | SEG_G | SEG_C | SEG_D | SEG_E, // 6
SEG_A | SEG_B | SEG_C, // 7
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G, // 8
SEG_F | SEG_A | SEG_B | SEG_G | SEG_C, // 9
];
#[m48_robo_rust::entry]
fn main() -> ! {
let dp = m48_robo_rust::Peripherals::take().unwrap();
let mut portd = dp.PORTD.split();
let mut portc = dp.PORTC.split();
let pc0 = portc.pc0.into_output(&mut portc.ddr);
let pc1 = portc.pc1.into_output(&mut portc.ddr);
let pc2 = portc.pc2.into_output(&mut portc.ddr);
let pc3 = portc.pc3.into_output(&mut portc.ddr);
let pc4 = portc.pc4.into_output(&mut portc.ddr);
let pd3 = portd.pd3.into_output(&mut portd.ddr);
let pd4 = portd.pd4.into_output(&mut portd.ddr);
let mut dp_seg = portd.pd2.into_output(&mut portd.ddr);
unsafe {
LEDS = Some([
pc0.downgrade(),
pc1.downgrade(),
pc2.downgrade(),
pc3.downgrade(),
pc4.downgrade(),
pd3.downgrade(),
pd4.downgrade(),
]);
let leds = LEDS.as_mut().unwrap();
for i in 0..leds.len() {
leds[i].set_high().void_unwrap();
leds[if i < 1 { leds.len() - 1 } else { i - 1 }]
.set_low()
.void_unwrap();
delay_ms(250);
}
leds[leds.len() - 1].set_low().void_unwrap();
}
let tc1 = dp.TC1;
tc1.ocr1a.write(|w| unsafe { w.bits(15625) });
tc1.timsk1.write(|w| w.ocie1a().set_bit());
tc1.tccr1b.write(|w| w.wgm1().bits(0b1u8));
tc1.tccr1b.modify(|_, w| w.cs1().prescale_64());
unsafe {
// Enable interrupts
avr_device::interrupt::enable();
}
loop {
dp_seg.toggle().void_unwrap();
delay_ms(250);
}
}
#[avr_device::interrupt(atmega48p)]
unsafe fn TIMER1_COMPA() {
let num_repr = NUMS[NUM as usize];
NUM = if NUM < 9 { NUM + 1 } else { 0 };
apply_segments(num_repr);
}
#[inline(always)]
fn apply_segments(segments: u8) {
let leds = unsafe { LEDS.as_mut().unwrap() };
for i in 0..leds.len() {
if segments & (1u8 << i) != 0 {
leds[i].set_high().void_unwrap();
} else {
leds[i].set_low().void_unwrap();
}
}
}