5
5
//!
6
6
//!
7
7
8
- use embedded_hal:: timer:: { CountDown , Periodic } ;
8
+ use embedded_hal:: timer:: { Cancel , CountDown , Periodic } ;
9
9
10
10
use crate :: clock_control:: ClockControlConfig ;
11
11
use crate :: prelude:: * ;
@@ -21,6 +21,7 @@ pub enum Error {
21
21
UnsupportedWatchdogConfig ,
22
22
/// Value out of range
23
23
OutOfRange ,
24
+ Disabled ,
24
25
}
25
26
26
27
/// Hardware timers
@@ -37,6 +38,8 @@ unsafe impl<TIMG: TimerGroup, INST: TimerInst> Send for Timer<TIMG, INST> {}
37
38
pub enum Event {
38
39
/// Timer timed out / count down ended
39
40
TimeOut ,
41
+ /// Timer timed out / count down ended (Edge Interrupt)
42
+ TimeOutEdge ,
40
43
}
41
44
42
45
#[ doc( hidden) ]
@@ -109,32 +112,39 @@ macro_rules! timer {
109
112
// Needs multi-threaded protection as timer0 and 1 use same register
110
113
pub fn listen( & mut self , event: Event ) {
111
114
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 ) ,
120
117
}
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
+ } ;
121
126
}
122
127
123
128
/// Stops listening for an `event`
124
129
// Needs multi-threaded protection as timer0 and 1 use same register
125
130
pub fn unlisten( & mut self , event: Event ) {
126
131
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 ) ,
135
134
}
136
135
}
137
136
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
138
148
pub fn set_value<T : Into <TicksU64 >>( & mut self , value: T ) {
139
149
unsafe {
140
150
let timg = & * ( self . timg) ;
@@ -145,6 +155,7 @@ macro_rules! timer {
145
155
}
146
156
}
147
157
158
+ /// Get timer value
148
159
pub fn get_value( & mut self ) -> TicksU64 {
149
160
unsafe {
150
161
let timg = & * ( self . timg) ;
@@ -155,6 +166,7 @@ macro_rules! timer {
155
166
}
156
167
}
157
168
169
+ /// Get alarm value
158
170
pub fn get_alarm( & mut self ) -> TicksU64 {
159
171
unsafe {
160
172
let timg = & * ( self . timg) ;
@@ -178,10 +190,23 @@ macro_rules! timer {
178
190
}
179
191
}
180
192
193
+ /// Enable or disables the timer
181
194
pub fn enable( & mut self , enable: bool ) {
182
195
unsafe { ( * ( self . timg) ) . $CONFIG. modify( |_, w| w. $EN( ) . bit( enable) ) }
183
196
}
184
197
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.
185
210
pub fn increasing( & mut self , enable: bool ) {
186
211
unsafe {
187
212
( * ( self . timg) )
@@ -190,6 +215,13 @@ macro_rules! timer {
190
215
}
191
216
}
192
217
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.
193
225
pub fn auto_reload( & mut self , enable: bool ) {
194
226
unsafe {
195
227
( * ( self . timg) )
@@ -198,54 +230,38 @@ macro_rules! timer {
198
230
}
199
231
}
200
232
201
- pub fn enable_edge_interrupt( & mut self , enable: bool ) {
233
+ fn enable_edge_interrupt( & mut self , enable: bool ) {
202
234
unsafe {
203
235
( * ( self . timg) )
204
236
. $CONFIG
205
237
. modify( |_, w| w. $EDGE_INT_EN( ) . bit( enable) )
206
238
}
207
239
}
208
240
209
- pub fn enable_level_interrupt( & mut self , enable: bool ) {
241
+ fn enable_level_interrupt( & mut self , enable: bool ) {
210
242
unsafe {
211
243
( * ( self . timg) )
212
244
. $CONFIG
213
245
. modify( |_, w| w. $LEVEL_INT_EN( ) . bit( enable) )
214
246
}
215
247
}
216
248
217
- pub fn enable_alarm( & mut self , enable: bool ) {
249
+ fn enable_alarm( & mut self , enable: bool ) {
218
250
unsafe {
219
251
( * ( self . timg) )
220
252
. $CONFIG
221
253
. modify( |_, w| w. $ALARM_EN( ) . bit( enable) )
222
254
}
223
255
}
224
256
225
- pub fn alarm_active( & mut self ) -> bool {
257
+ fn alarm_active( & mut self ) -> bool {
226
258
unsafe { ( * ( self . timg) ) . $CONFIG. read( ) . $ALARM_EN( ) . bit_is_set( ) }
227
259
}
228
260
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
-
245
261
/// Set clock divider.
246
262
///
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 > {
249
265
if divider <= 1 || divider > 65536 {
250
266
return Err ( Error :: OutOfRange ) ;
251
267
}
@@ -264,25 +280,46 @@ macro_rules! timer {
264
280
265
281
impl <TIMG : TimerGroup > CountDown for Timer <TIMG , $TIMX> {
266
282
type Time = NanoSecondsU64 ;
283
+
284
+ /// Start timer
267
285
fn start<T : Into <Self :: Time >>( & mut self , timeout: T ) {
268
286
self . enable( false ) ;
269
287
self . set_divider( 2 ) . unwrap( ) ; // minimum divider value is 2,
270
288
// this still allows >14000years with 64 bit values
271
289
290
+ self . auto_reload( true ) ;
272
291
self . set_value( 0 ) ;
273
292
self . set_alarm( self . clock_control_config. apb_frequency( ) / 2 * timeout. into( ) ) ;
293
+ self . enable_alarm( true ) ;
274
294
self . enable( true ) ;
275
295
}
276
296
297
+ /// Wait for timer to finish
298
+ ///
299
+ /// **Note: if the timeout is handled via an interrupt, this will never return.**
277
300
fn wait( & mut self ) -> nb:: Result <( ) , void:: Void > {
278
- if ! self . alarm_active( ) {
301
+ if self . alarm_active( ) {
279
302
Err ( nb:: Error :: WouldBlock )
280
303
} else {
281
- self . enable_alarm ( true ) ;
304
+ self . clear_interrupt ( ) ;
282
305
Ok ( ( ) )
283
306
}
284
307
}
285
308
}
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
+ }
286
323
} ;
287
324
}
288
325
0 commit comments