Skip to content

Commit e514a37

Browse files
authored
Merge pull request #925 from McBandaska/feature/4_alarms_for_both_timers
both timers support up to 4 alarms
2 parents 0aaf8de + 775e958 commit e514a37

File tree

1 file changed

+23
-17
lines changed

1 file changed

+23
-17
lines changed

rp235x-hal/src/timer.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,16 @@ use crate::{
2222
/// Instant type used by the Timer & Alarm methods.
2323
pub type Instant = TimerInstantU64<1_000_000>;
2424

25-
static ALARMS: AtomicU8 = AtomicU8::new(0x0F);
26-
fn take_alarm(mask: u8) -> bool {
27-
critical_section::with(|_| {
28-
let alarms = ALARMS.load(Ordering::Relaxed);
29-
ALARMS.store(alarms & !mask, Ordering::Relaxed);
30-
(alarms & mask) != 0
31-
})
25+
static ALARMS_TIMER0: AtomicU8 = AtomicU8::new(0x00);
26+
static ALARMS_TIMER1: AtomicU8 = AtomicU8::new(0x00);
27+
28+
fn take_alarm(mask: u8, alarms: &'static AtomicU8) -> bool {
29+
let current_alarms = alarms.fetch_or(mask, Ordering::Relaxed);
30+
(current_alarms & mask) == 0
3231
}
33-
fn release_alarm(mask: u8) {
34-
critical_section::with(|_| {
35-
let alarms = ALARMS.load(Ordering::Relaxed);
36-
ALARMS.store(alarms | mask, Ordering::Relaxed);
37-
});
32+
33+
fn release_alarm(mask: u8, alarms: &'static AtomicU8) {
34+
alarms.fetch_and(!mask, Ordering::Relaxed);
3835
}
3936

4037
/// Represents Timer0
@@ -66,6 +63,15 @@ pub trait TimerDevice: Sealed + Clone + Copy + 'static {
6663
unsafe { &*pac::TIMER1::ptr() }
6764
}
6865
}
66+
67+
/// Get the static AtomicU8 for managing alarms.
68+
fn get_alarms_tracker() -> &'static AtomicU8 {
69+
if Self::ID == 0 {
70+
&ALARMS_TIMER0
71+
} else {
72+
&ALARMS_TIMER1
73+
}
74+
}
6975
}
7076

7177
impl TimerDevice for CopyableTimer0 {
@@ -168,22 +174,22 @@ where
168174
}
169175
/// Retrieve a reference to alarm 0. Will only return a value the first time this is called
170176
pub fn alarm_0(&mut self) -> Option<Alarm0<D>> {
171-
take_alarm(1 << 0).then_some(Alarm0(*self))
177+
take_alarm(1 << 0, <D>::get_alarms_tracker()).then_some(Alarm0(*self))
172178
}
173179

174180
/// Retrieve a reference to alarm 1. Will only return a value the first time this is called
175181
pub fn alarm_1(&mut self) -> Option<Alarm1<D>> {
176-
take_alarm(1 << 1).then_some(Alarm1(*self))
182+
take_alarm(1 << 1, <D>::get_alarms_tracker()).then_some(Alarm1(*self))
177183
}
178184

179185
/// Retrieve a reference to alarm 2. Will only return a value the first time this is called
180186
pub fn alarm_2(&mut self) -> Option<Alarm2<D>> {
181-
take_alarm(1 << 2).then_some(Alarm2(*self))
187+
take_alarm(1 << 2, <D>::get_alarms_tracker()).then_some(Alarm2(*self))
182188
}
183189

184190
/// Retrieve a reference to alarm 3. Will only return a value the first time this is called
185191
pub fn alarm_3(&mut self) -> Option<Alarm3<D>> {
186-
take_alarm(1 << 3).then_some(Alarm3(*self))
192+
take_alarm(1 << 3, <D>::get_alarms_tracker()).then_some(Alarm3(*self))
187193
}
188194

189195
/// Pauses execution for at minimum `us` microseconds.
@@ -549,7 +555,7 @@ macro_rules! impl_alarm {
549555
{
550556
fn drop(&mut self) {
551557
self.disable_interrupt();
552-
release_alarm($armed_bit_mask)
558+
release_alarm($armed_bit_mask, D::get_alarms_tracker());
553559
}
554560
}
555561
};

0 commit comments

Comments
 (0)