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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use core::marker::PhantomData;
use crate::memory_mapped::MemoryMapped;
const fn timer_data(timer: usize) -> MemoryMapped<u16> {
unsafe { MemoryMapped::new(0x0400_0100 + 4 * timer) }
}
const fn timer_control(timer: usize) -> MemoryMapped<u16> {
unsafe { MemoryMapped::new(0x0400_0102 + 4 * timer) }
}
#[derive(Clone, Copy)]
/// Divides the cycle precise timer down
///
/// A larger divider will mean the timer is slower. The frequency and cycle
/// durations are given.
pub enum Divider {
/// 16.78MHz or 59.59ns
Divider1,
/// 262.21kHz or 3.815us
Divider64,
/// 65.536kHz or 15.26us
Divider256,
/// 16.384kHz or 61.04us
Divider1024,
}
impl Divider {
fn as_bits(self) -> u16 {
use Divider::*;
match self {
Divider1 => 0,
Divider64 => 1,
Divider256 => 2,
Divider1024 => 3,
}
}
}
#[non_exhaustive]
/// A 16 bit hardware timer
pub struct Timer {
timer_number: u16,
}
#[non_exhaustive]
/// A currently hard to use distributor around hardware timers only exposing
/// those that you can freely use in agb.
pub struct Timers<'gba> {
/// A timer
pub timer2: Timer,
/// A timer
pub timer3: Timer,
phantom: PhantomData<&'gba ()>,
}
/// All timers including those used by system components
pub struct AllTimers<'gba> {
/// Timer0 - used by sound system and embassy-agb time driver
pub timer0: Timer,
/// Timer1 - used by sound system
pub timer1: Timer,
/// Timer2 - available for general use
pub timer2: Timer,
/// Timer3 - available for general use
pub timer3: Timer,
phantom: PhantomData<&'gba ()>,
}
impl Timers<'_> {
pub(crate) unsafe fn new() -> Self {
Self {
timer2: unsafe { Timer::new(2) },
timer3: unsafe { Timer::new(3) },
phantom: PhantomData,
}
}
}
impl AllTimers<'_> {
/// Create access to all timers
///
/// # Safety
/// This allows access to Timer0 and Timer1 which are used by system components.
/// Using these timers may interfere with sound or embassy-agb functionality.
#[must_use]
pub(crate) unsafe fn new() -> Self {
Self {
timer0: unsafe { Timer::new(0) },
timer1: unsafe { Timer::new(1) },
timer2: unsafe { Timer::new(2) },
timer3: unsafe { Timer::new(3) },
phantom: PhantomData,
}
}
}
impl Timer {
pub(crate) unsafe fn new(timer_number: u16) -> Self {
let new_timer = Self { timer_number };
new_timer.data_register().set(0);
new_timer.control_register().set(0);
new_timer
}
/// Causes the timer to overflow at the given value.
pub fn set_overflow_amount(&mut self, n: u16) -> &mut Self {
let count_up_value = 0u16.wrapping_sub(n);
self.data_register().set(count_up_value);
self
}
#[must_use]
/// The current value of the timer.
pub fn value(&self) -> u16 {
self.data_register().get()
}
/// Sets the divider of the timer which causes the timer to run at a faster
/// or slower rate.
pub fn set_divider(&mut self, divider: Divider) -> &mut Self {
self.control_register().set_bits(divider.as_bits(), 2, 0);
self
}
/// Sets whether the timer is frozen or enabled.
pub fn set_enabled(&mut self, enabled: bool) -> &mut Self {
let bit = u16::from(enabled);
self.control_register().set_bits(bit, 1, 7);
self
}
/// Causes the timer to step when the previous timer overflows. Can be used to create timers that are greater than 16 bit.
pub fn set_cascade(&mut self, cascade: bool) -> &mut Self {
let bit = u16::from(cascade);
self.control_register().set_bits(bit, 1, 2);
self
}
/// Sets whether the relevant interrupt will trigger when this timer overflows
pub fn set_interrupt(&mut self, interrupt: bool) -> &mut Self {
let bit = u16::from(interrupt);
self.control_register().set_bits(bit, 1, 6);
self
}
fn data_register(&self) -> MemoryMapped<u16> {
timer_data(self.timer_number())
}
fn control_register(&self) -> MemoryMapped<u16> {
timer_control(self.timer_number())
}
fn timer_number(&self) -> usize {
self.timer_number as usize
}
#[must_use]
/// Gets the relevant interrupt that can directly be used in [`add_interrupt_handler`][crate::interrupt::add_interrupt_handler].
pub fn interrupt(&self) -> crate::interrupt::Interrupt {
use crate::interrupt::Interrupt;
match self.timer_number {
0 => Interrupt::Timer0,
1 => Interrupt::Timer1,
2 => Interrupt::Timer2,
3 => Interrupt::Timer3,
_ => unreachable!(),
}
}
}
#[non_exhaustive]
/// A distributor of timers that binds the timers lifetime to that of the Gba
/// struct to try ensure unique access to timers.
pub struct TimerController {}
impl TimerController {
pub(crate) const fn new() -> Self {
Self {}
}
/// Gets the underlying timers.
pub fn timers(&mut self) -> Timers<'_> {
unsafe { Timers::new() }
}
/// Gets all timers including system ones (Timer0, Timer1)
///
/// # Safety
/// Timer0 and Timer1 are used by system components (sound, embassy-agb).
/// Using them may interfere with system functionality.
pub unsafe fn all_timers(&mut self) -> AllTimers<'_> {
unsafe { AllTimers::new() }
}
}