Skip to content
This repository was archived by the owner on Aug 9, 2022. It is now read-only.

Commit 6f0a1ce

Browse files
committed
Implement Cancel trait and corrected wait
1 parent bedcab2 commit 6f0a1ce

File tree

2 files changed

+106
-84
lines changed

2 files changed

+106
-84
lines changed

examples/timer.rs

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use esp32_hal::prelude::*;
99

1010
use core::cell::RefCell;
1111
use core::ops::DerefMut;
12+
use embedded_hal::timer::{Cancel, CountDown};
1213
use esp32_hal::clock_control::sleep;
1314
use esp32_hal::dport::Split;
1415
use esp32_hal::dprintln;
@@ -55,7 +56,7 @@ fn main() -> ! {
5556
action2: WatchdogAction::RESETSYSTEM,
5657
action3: WatchdogAction::DISABLE,
5758
action4: WatchdogAction::DISABLE,
58-
period1: 2.s().into(),
59+
period1: 5.s().into(),
5960
period2: 10.s().into(),
6061
period3: 0.us().into(),
6162
period4: 0.us().into(),
@@ -65,10 +66,8 @@ fn main() -> ! {
6566
};
6667

6768
watchdog1.set_config(&wdconfig).unwrap();
68-
//watchdog1.start(3.s());
6969

70-
timer0.enable(true);
71-
timer1.enable(true);
70+
*WATCHDOG1.lock().borrow_mut() = Some(watchdog1);
7271

7372
let config = Config {
7473
baudrate: Hertz(115_200),
@@ -82,79 +81,65 @@ fn main() -> ! {
8281

8382
writeln!(tx, "\n\nESP32 Started\n\n").unwrap();
8483

85-
timer0.set_alarm(70_000_000.into());
86-
timer0.enable_alarm(true);
87-
timer0.auto_reload(true);
88-
timer0.enable_level_interrupt(true);
89-
timer0.enable_edge_interrupt(true);
84+
timer0.start(900.ms());
85+
timer1.start(4.s());
86+
87+
writeln!(tx, "Waiting for timer0").unwrap();
88+
nb::block!(timer0.wait()).unwrap();
89+
90+
writeln!(tx, "Finished waiting for timer0").unwrap();
9091

9192
timer0.listen(esp32_hal::timer::Event::TimeOut);
93+
timer0.listen(esp32_hal::timer::Event::TimeOutEdge);
94+
9295
interrupt::enable_with_priority(PRO, Interrupt::TG0_T0_LEVEL_INTR, InterruptLevel(1)).unwrap();
9396
interrupt::enable_with_priority(PRO, Interrupt::TG0_T0_EDGE_INTR, InterruptLevel(1)).unwrap();
9497

9598
interrupt::enable_with_priority(PRO, Interrupt::TG1_WDT_LEVEL_INTR, InterruptLevel(1)).unwrap();
9699
interrupt::enable_with_priority(PRO, Interrupt::TG1_WDT_EDGE_INTR, InterruptLevel(3)).unwrap();
97100

98101
*TIMER.lock().borrow_mut() = Some(timer0);
99-
*WATCHDOG1.lock().borrow_mut() = Some(watchdog1);
100102

101103
loop {
102-
interrupt::free(|cs| {
104+
interrupt::free(|_| {
103105
if let Some(ref mut timer0) = TIMER.lock().borrow_mut().deref_mut() {
104-
writeln!(
105-
tx,
106-
"Timers: {} {} {} {} {:x} {:x} {}",
107-
timer0.get_value(),
108-
timer0.alarm_active(),
109-
timer0.interrupt_active_raw(),
110-
timer0.interrupt_active(),
111-
interrupt::get_interrupt_status(PRO),
112-
xtensa_lx6_rt::interrupt::get(),
113-
timer1.get_value()
114-
)
115-
.unwrap();
106+
writeln!(tx, "Timers: {} {}", timer0.get_value(), timer1.get_value()).unwrap();
107+
if let Ok(_) = timer1.wait() {
108+
writeln!(tx, "CANCELLING Timers").unwrap();
109+
timer0.cancel().unwrap();
110+
timer1.cancel().unwrap();
111+
}
116112
}
117113
});
118114

119115
sleep((Hertz(1_000_000) / BLINK_HZ).us());
120-
sleep((Hertz(1_000_000) / BLINK_HZ).us());
121116
}
122117
}
123118

124119
#[interrupt]
125120
fn TG0_T0_LEVEL_INTR() {
126-
interrupt::free(|cs| {
121+
esp32_hal::dprintln!(" TG0_T0_LEVEL_INTR");
122+
interrupt::free(|_| {
127123
if let Some(ref mut timer0) = TIMER.lock().borrow_mut().deref_mut() {
128124
timer0.clear_interrupt();
129-
timer0.enable_alarm(true);
130125
}
131126
});
132-
esp32_hal::dprintln!(" TG0_T0_LEVEL_INTR");
133127
}
134128

135129
#[interrupt]
136130
fn TG0_T0_EDGE_INTR() {
137-
interrupt::free(|cs| {
138-
if let Some(ref mut timer0) = TIMER.lock().borrow_mut().deref_mut() {
139-
esp32_hal::dprintln!(" TG0_T0_EDGE_INTR");
140-
141-
dprintln!(
142-
" Timers: {} {} {} {} {:x} {:x}",
143-
timer0.get_value(),
144-
timer0.alarm_active(),
145-
timer0.interrupt_active_raw(),
146-
timer0.interrupt_active(),
147-
interrupt::get_interrupt_status(PRO),
148-
xtensa_lx6_rt::interrupt::get(),
149-
);
150-
timer0.enable_alarm(true);
151-
}
131+
esp32_hal::dprintln!(" TG0_T0_EDGE_INTR");
132+
interrupt::free(|_| {
133+
// edge interrupt is fired before level. If cleared here level interrupt is not fired
134+
// if let Some(ref mut timer0) = TIMER.lock().borrow_mut().deref_mut() {
135+
// timer0.clear_interrupt();
136+
// }
152137
});
153138
}
154139

155140
#[interrupt]
156141
fn TG1_WDT_LEVEL_INTR() {
157-
interrupt::free(|cs| {
142+
interrupt::free(|_| {
158143
if let Some(ref mut watchdog1) = WATCHDOG1.lock().borrow_mut().deref_mut() {
159144
watchdog1.clear_interrupt();
160145
}

src/timer/mod.rs

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//!
66
//!
77
8-
use embedded_hal::timer::{CountDown, Periodic};
8+
use embedded_hal::timer::{Cancel, CountDown, Periodic};
99

1010
use crate::clock_control::ClockControlConfig;
1111
use crate::prelude::*;
@@ -21,6 +21,7 @@ pub enum Error {
2121
UnsupportedWatchdogConfig,
2222
/// Value out of range
2323
OutOfRange,
24+
Disabled,
2425
}
2526

2627
/// Hardware timers
@@ -37,6 +38,8 @@ unsafe impl<TIMG: TimerGroup, INST: TimerInst> Send for Timer<TIMG, INST> {}
3738
pub enum Event {
3839
/// Timer timed out / count down ended
3940
TimeOut,
41+
/// Timer timed out / count down ended (Edge Interrupt)
42+
TimeOutEdge,
4043
}
4144

4245
#[doc(hidden)]
@@ -109,32 +112,39 @@ macro_rules! timer {
109112
// Needs multi-threaded protection as timer0 and 1 use same register
110113
pub fn listen(&mut self, event: Event) {
111114
match event {
112-
Event::TimeOut => unsafe {
113-
interrupt::free(|_| {
114-
TIMER_MUTEX.lock();
115-
(*(self.timg))
116-
.int_ena_timers
117-
.modify(|_, w| w.$INT_ENA().set_bit());
118-
});
119-
},
115+
Event::TimeOut => self.enable_level_interrupt(true),
116+
Event::TimeOutEdge => self.enable_edge_interrupt(true),
120117
}
118+
unsafe {
119+
interrupt::free(|_| {
120+
TIMER_MUTEX.lock();
121+
(*(self.timg))
122+
.int_ena_timers
123+
.modify(|_, w| w.$INT_ENA().set_bit());
124+
})
125+
};
121126
}
122127

123128
/// Stops listening for an `event`
124129
// Needs multi-threaded protection as timer0 and 1 use same register
125130
pub fn unlisten(&mut self, event: Event) {
126131
match event {
127-
Event::TimeOut => unsafe {
128-
interrupt::free(|_| {
129-
TIMER_MUTEX.lock();
130-
(*(self.timg))
131-
.int_ena_timers
132-
.modify(|_, w| w.$INT_ENA().clear_bit())
133-
});
134-
},
132+
Event::TimeOut => self.enable_level_interrupt(false),
133+
Event::TimeOutEdge => self.enable_edge_interrupt(false),
135134
}
136135
}
137136

137+
/// Clear interrupt once fired
138+
pub fn clear_interrupt(&mut self) {
139+
self.enable_alarm(true);
140+
unsafe {
141+
(*(self.timg))
142+
.int_clr_timers
143+
.write(|w| w.$INT_CLR().set_bit())
144+
}
145+
}
146+
147+
/// Set timer value
138148
pub fn set_value<T: Into<TicksU64>>(&mut self, value: T) {
139149
unsafe {
140150
let timg = &*(self.timg);
@@ -145,6 +155,7 @@ macro_rules! timer {
145155
}
146156
}
147157

158+
/// Get timer value
148159
pub fn get_value(&mut self) -> TicksU64 {
149160
unsafe {
150161
let timg = &*(self.timg);
@@ -155,6 +166,7 @@ macro_rules! timer {
155166
}
156167
}
157168

169+
/// Get alarm value
158170
pub fn get_alarm(&mut self) -> TicksU64 {
159171
unsafe {
160172
let timg = &*(self.timg);
@@ -178,10 +190,23 @@ macro_rules! timer {
178190
}
179191
}
180192

193+
/// Enable or disables the timer
181194
pub fn enable(&mut self, enable: bool) {
182195
unsafe { (*(self.timg)).$CONFIG.modify(|_, w| w.$EN().bit(enable)) }
183196
}
184197

198+
/// Enable or disables the timer
199+
pub fn is_enabled(&mut self) -> bool {
200+
unsafe { (*(self.timg)).$CONFIG.read().$EN().bit_is_set() }
201+
}
202+
203+
/// Stop the timer
204+
pub fn stop(&mut self) {
205+
self.enable(false);
206+
}
207+
208+
/// Set to true to increase the timer value on each tick, set to false to decrease
209+
/// the timer value on each tick.
185210
pub fn increasing(&mut self, enable: bool) {
186211
unsafe {
187212
(*(self.timg))
@@ -190,6 +215,13 @@ macro_rules! timer {
190215
}
191216
}
192217

218+
/// Returns true if teh timer is increasing, otherwise decreasing
219+
pub fn is_increasing(&mut self) -> bool {
220+
unsafe { (*(self.timg)).$CONFIG.read().$INCREASE().bit_is_set() }
221+
}
222+
223+
/// Set to true if the timer needs to be reloaded to initial value once the alarm
224+
/// is reached.
193225
pub fn auto_reload(&mut self, enable: bool) {
194226
unsafe {
195227
(*(self.timg))
@@ -198,54 +230,38 @@ macro_rules! timer {
198230
}
199231
}
200232

201-
pub fn enable_edge_interrupt(&mut self, enable: bool) {
233+
fn enable_edge_interrupt(&mut self, enable: bool) {
202234
unsafe {
203235
(*(self.timg))
204236
.$CONFIG
205237
.modify(|_, w| w.$EDGE_INT_EN().bit(enable))
206238
}
207239
}
208240

209-
pub fn enable_level_interrupt(&mut self, enable: bool) {
241+
fn enable_level_interrupt(&mut self, enable: bool) {
210242
unsafe {
211243
(*(self.timg))
212244
.$CONFIG
213245
.modify(|_, w| w.$LEVEL_INT_EN().bit(enable))
214246
}
215247
}
216248

217-
pub fn enable_alarm(&mut self, enable: bool) {
249+
fn enable_alarm(&mut self, enable: bool) {
218250
unsafe {
219251
(*(self.timg))
220252
.$CONFIG
221253
.modify(|_, w| w.$ALARM_EN().bit(enable))
222254
}
223255
}
224256

225-
pub fn alarm_active(&mut self) -> bool {
257+
fn alarm_active(&mut self) -> bool {
226258
unsafe { (*(self.timg)).$CONFIG.read().$ALARM_EN().bit_is_set() }
227259
}
228260

229-
pub fn interrupt_active_raw(&mut self) -> bool {
230-
unsafe { (*(self.timg)).int_raw_timers.read().$INT_RAW().bit_is_set() }
231-
}
232-
233-
pub fn interrupt_active(&mut self) -> bool {
234-
unsafe { (*(self.timg)).int_st_timers.read().$INT_ST().bit_is_set() }
235-
}
236-
237-
pub fn clear_interrupt(&mut self) {
238-
unsafe {
239-
(*(self.timg))
240-
.int_clr_timers
241-
.write(|w| w.$INT_CLR().set_bit())
242-
}
243-
}
244-
245261
/// Set clock divider.
246262
///
247-
/// 1 divides by
248-
pub fn set_divider(&mut self, divider: u32) -> Result<(), Error> {
263+
/// Value must be between 2 and 65536 inclusive.
264+
fn set_divider(&mut self, divider: u32) -> Result<(), Error> {
249265
if divider <= 1 || divider > 65536 {
250266
return Err(Error::OutOfRange);
251267
}
@@ -264,25 +280,46 @@ macro_rules! timer {
264280

265281
impl<TIMG: TimerGroup> CountDown for Timer<TIMG, $TIMX> {
266282
type Time = NanoSecondsU64;
283+
284+
/// Start timer
267285
fn start<T: Into<Self::Time>>(&mut self, timeout: T) {
268286
self.enable(false);
269287
self.set_divider(2).unwrap(); // minimum divider value is 2,
270288
// this still allows >14000years with 64 bit values
271289

290+
self.auto_reload(true);
272291
self.set_value(0);
273292
self.set_alarm(self.clock_control_config.apb_frequency() / 2 * timeout.into());
293+
self.enable_alarm(true);
274294
self.enable(true);
275295
}
276296

297+
/// Wait for timer to finish
298+
///
299+
/// **Note: if the timeout is handled via an interrupt, this will never return.**
277300
fn wait(&mut self) -> nb::Result<(), void::Void> {
278-
if !self.alarm_active() {
301+
if self.alarm_active() {
279302
Err(nb::Error::WouldBlock)
280303
} else {
281-
self.enable_alarm(true);
304+
self.clear_interrupt();
282305
Ok(())
283306
}
284307
}
285308
}
309+
310+
impl<TIMG: TimerGroup> Cancel for Timer<TIMG, $TIMX> {
311+
type Error = Error;
312+
/// Cancel running timer.
313+
///
314+
/// This will stop the timer if running and returns error when not running.
315+
fn cancel(&mut self) -> Result<(), Self::Error> {
316+
if !self.is_enabled() {
317+
return Err(Self::Error::Disabled);
318+
}
319+
self.stop();
320+
Ok(())
321+
}
322+
}
286323
};
287324
}
288325

0 commit comments

Comments
 (0)