-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.rs
118 lines (93 loc) · 3.02 KB
/
main.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
111
112
113
114
115
116
117
118
#![feature(no_core)]
#![feature(asm)]
#![feature(abi_avr_interrupt)]
#![feature(lang_items)]
#![feature(core_intrinsics)]
#![no_core]
#![no_main]
extern crate core;
use core::prelude::v1::*;
use core::intrinsics::{volatile_load, volatile_store};
use core::marker::PhantomData;
#[lang = "eh_personality"]
extern fn eh_personality() {}
#[lang = "panic_fmt"]
extern fn panic_fmt() -> ! { loop {} }
pub mod avr {
pub const DDRB: *mut u8 = 0x24 as *mut u8;
pub const PORTB: *mut u8 = 0x25 as *mut u8;
pub const TCCR0A: *mut u8 = 0x44 as *mut u8;
pub const TCCR0B: *mut u8 = 0x45 as *mut u8;
pub const TCNT0: *mut u8 = 0x46 as *mut u8;
pub const OCR0A: *mut u8 = 0x47 as *mut u8;
pub const TIMSK0: *mut u8 = 0x6E as *mut u8;
pub const TCCR1A: *mut u8 = 0x80 as *mut u8;
pub const TCCR1B: *mut u8 = 0x81 as *mut u8;
pub const TCCR1L: *mut u8 = 0x84 as *mut u8;
pub const TCCR1H: *mut u8 = 0x85 as *mut u8;
pub const OCR1AL: *mut u8 = 0x88 as *mut u8;
pub const OCR1AH: *mut u8 = 0x89 as *mut u8;
pub const TCNT1L: *mut u8 = 0x84 as *mut u8;
pub const TCNT1H: *mut u8 = 0x85 as *mut u8;
pub const TIMSK1: *mut u8 = 0x6F as *mut u8;
// Should pins be represented in this way?
pub const PINB5: u8 = 0b0010_0000;
pub const WGM12: u8 = 0b0000_1000;
pub const CS12: u8 = 0b0000_0100;
pub const CS10: u8 = 0b0000_0001;
pub const OCIE1A: u8 = 0b0000_0010;
}
use avr::*;
#[no_mangle]
pub unsafe extern "avr-interrupt" fn _ivr_timer1_compare_a() {
let prev_value = volatile_load(PORTB);
volatile_store(PORTB, prev_value ^ PINB5);
}
struct DisableInterrupts(PhantomData<()>);
impl DisableInterrupts {
fn new() -> DisableInterrupts {
unsafe { asm!("CLI") }
DisableInterrupts(PhantomData)
}
}
impl Drop for DisableInterrupts {
fn drop(&mut self) {
unsafe { asm!("SEI") }
}
}
fn without_interrupts<F, T>(f: F) -> T
where F: FnOnce() -> T
{
let _disabled = DisableInterrupts::new();
f()
}
#[no_mangle]
pub extern fn main() {
unsafe {
without_interrupts(|| {
// Configure all Port B pins as outputs
volatile_store(DDRB, 0xFF);
// Turn on all Port B pins
volatile_store(PORTB, 0xFF);
// Initialize timer settings
volatile_store(TCCR1A, 0);
volatile_store(TCCR1B, 0);
// Initialize timer counter
volatile_store(TCNT1L, 0);
volatile_store(TCNT1H, 0);
// Set compare match register for 1hz increments (must be <65536)
// (16*10^6) / (1*1024) - 1 => 15624 => 0x3D08
volatile_store(OCR1AH, 0x3D);
volatile_store(OCR1AL, 0x08);
// Configure timer
let ctc_mode = WGM12;
let prescaler_1024x = CS12 | CS10;
volatile_store(TCCR1B, ctc_mode | prescaler_1024x);
// Enable timer compare interrupt
volatile_store(TIMSK1, OCIE1A);
});
loop {
// forever!
}
}
}