3
3
//! See product specification, chapter 24.
4
4
5
5
#[ cfg( feature = "9160" ) ]
6
- use crate :: pac:: { Interrupt , TIMER0_NS as TIMER0 , TIMER1_NS as TIMER1 , TIMER2_NS as TIMER2 } ;
6
+ use crate :: pac:: {
7
+ timer0_ns:: RegisterBlock as RegBlock0 , Interrupt , TIMER0_NS as TIMER0 , TIMER1_NS as TIMER1 ,
8
+ TIMER2_NS as TIMER2 ,
9
+ } ;
7
10
8
11
#[ cfg( not( feature = "9160" ) ) ]
9
- use crate :: pac:: { Interrupt , TIMER0 , TIMER1 , TIMER2 } ;
12
+ use crate :: pac:: { timer0 :: RegisterBlock as RegBlock0 , Interrupt , TIMER0 , TIMER1 , TIMER2 } ;
10
13
11
14
use cast:: u32;
12
15
use embedded_hal:: {
@@ -20,6 +23,15 @@ use void::{unreachable, Void};
20
23
#[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
21
24
use crate :: pac:: { TIMER3 , TIMER4 } ;
22
25
26
+ // The 832 and 840 expose TIMER3 and TIMER for as timer3::RegisterBlock...
27
+ #[ cfg( any( feature = "52832" , feature = "52840" ) ) ]
28
+ use crate :: pac:: timer3:: RegisterBlock as RegBlock3 ;
29
+
30
+ // ...but the 833 exposes them as timer0::RegisterBlock. This might be a bug
31
+ // in the PAC, and could be fixed later. For now, it is equivalent anyway.
32
+ #[ cfg( feature = "52833" ) ]
33
+ use crate :: pac:: timer0:: RegisterBlock as RegBlock3 ;
34
+
23
35
use core:: marker:: PhantomData ;
24
36
25
37
pub struct OneShot ;
@@ -231,135 +243,172 @@ where
231
243
}
232
244
}
233
245
234
- /// Implemented by all `timer0:: TIMER` instances.
235
- pub trait Instance {
246
+ /// Implemented by all TIMER* instances.
247
+ pub trait Instance : sealed :: Sealed {
236
248
/// This interrupt associated with this RTC instance.
237
249
const INTERRUPT : Interrupt ;
238
250
251
+ fn as_timer0 ( & self ) -> & RegBlock0 ;
252
+
239
253
fn timer_start < Time > ( & self , cycles : Time )
240
254
where
241
- Time : Into < u32 > ;
255
+ Time : Into < u32 > ,
256
+ {
257
+ // If the following sequence of events occurs, the COMPARE event will be
258
+ // set here:
259
+ // 1. `start` is called.
260
+ // 2. The timer runs out but `wait` is _not_ called.
261
+ // 3. `start` is called again
262
+ //
263
+ // If that happens, then we need to reset the event here explicitly, as
264
+ // nothing else this method does will reset the event, and if it's still
265
+ // active after this method exits, then the next call to `wait` will
266
+ // return immediately, no matter how much time has actually passed.
267
+ self . as_timer0 ( ) . events_compare [ 0 ] . reset ( ) ;
268
+
269
+ // Configure timer to trigger EVENTS_COMPARE when given number of cycles
270
+ // is reached.
271
+ #[ cfg( not( feature = "51" ) ) ]
272
+ self . as_timer0 ( ) . cc [ 0 ] . write ( |w|
273
+ // The timer mode was set to 32 bits above, so all possible values
274
+ // of `cycles` are valid.
275
+ unsafe { w. cc ( ) . bits ( cycles. into ( ) ) } ) ;
276
+
277
+ #[ cfg( feature = "51" ) ]
278
+ self . as_timer0 ( ) . cc [ 0 ] . write ( |w| unsafe { w. bits ( cycles. into ( ) ) } ) ;
279
+
280
+ // Clear the counter value.
281
+ self . as_timer0 ( ) . tasks_clear . write ( |w| unsafe { w. bits ( 1 ) } ) ;
282
+
283
+ // Start the timer.
284
+ self . as_timer0 ( ) . tasks_start . write ( |w| unsafe { w. bits ( 1 ) } ) ;
285
+ }
242
286
243
- fn timer_reset_event ( & self ) ;
287
+ fn timer_reset_event ( & self ) {
288
+ self . as_timer0 ( ) . events_compare [ 0 ] . write ( |w| w) ;
289
+ }
244
290
245
- fn timer_cancel ( & self ) ;
291
+ fn timer_cancel ( & self ) {
292
+ self . as_timer0 ( ) . tasks_stop . write ( |w| unsafe { w. bits ( 1 ) } ) ;
293
+ self . timer_reset_event ( ) ;
294
+ }
246
295
247
- fn timer_running ( & self ) -> bool ;
296
+ fn timer_running ( & self ) -> bool {
297
+ self . as_timer0 ( ) . events_compare [ 0 ] . read ( ) . bits ( ) == 0
298
+ }
299
+
300
+ fn read_counter ( & self ) -> u32 {
301
+ self . as_timer0 ( ) . tasks_capture [ 1 ] . write ( |w| unsafe { w. bits ( 1 ) } ) ;
302
+ self . as_timer0 ( ) . cc [ 1 ] . read ( ) . bits ( )
303
+ }
304
+
305
+ fn disable_interrupt ( & self ) {
306
+ self . as_timer0 ( )
307
+ . intenclr
308
+ . modify ( |_, w| w. compare0 ( ) . clear ( ) ) ;
309
+ }
310
+
311
+ fn enable_interrupt ( & self ) {
312
+ self . as_timer0 ( ) . intenset . modify ( |_, w| w. compare0 ( ) . set ( ) ) ;
313
+ }
314
+
315
+ fn set_shorts_periodic ( & self ) {
316
+ self . as_timer0 ( )
317
+ . shorts
318
+ . write ( |w| w. compare0_clear ( ) . enabled ( ) . compare0_stop ( ) . disabled ( ) ) ;
319
+ }
248
320
249
- fn read_counter ( & self ) -> u32 ;
321
+ fn set_shorts_oneshot ( & self ) {
322
+ self . as_timer0 ( )
323
+ . shorts
324
+ . write ( |w| w. compare0_clear ( ) . enabled ( ) . compare0_stop ( ) . enabled ( ) ) ;
325
+ }
250
326
251
- fn disable_interrupt ( & self ) ;
327
+ fn set_periodic ( & self ) {
328
+ self . set_shorts_periodic ( ) ;
329
+ self . as_timer0 ( ) . prescaler . write (
330
+ |w| unsafe { w. prescaler ( ) . bits ( 4 ) } , // 1 MHz
331
+ ) ;
332
+ self . as_timer0 ( ) . bitmode . write ( |w| w. bitmode ( ) . _32bit ( ) ) ;
333
+ }
252
334
253
- fn enable_interrupt ( & self ) ;
335
+ fn set_oneshot ( & self ) {
336
+ self . set_shorts_oneshot ( ) ;
337
+ self . as_timer0 ( ) . prescaler . write (
338
+ |w| unsafe { w. prescaler ( ) . bits ( 4 ) } , // 1 MHz
339
+ ) ;
340
+ self . as_timer0 ( ) . bitmode . write ( |w| w. bitmode ( ) . _32bit ( ) ) ;
341
+ }
342
+ }
254
343
255
- fn set_shorts_periodic ( & self ) ;
344
+ impl Instance for TIMER0 {
345
+ const INTERRUPT : Interrupt = Interrupt :: TIMER0 ;
256
346
257
- fn set_shorts_oneshot ( & self ) ;
347
+ #[ inline( always) ]
348
+ fn as_timer0 ( & self ) -> & RegBlock0 {
349
+ self
350
+ }
351
+ }
258
352
259
- fn set_periodic ( & self ) ;
353
+ impl Instance for TIMER1 {
354
+ const INTERRUPT : Interrupt = Interrupt :: TIMER1 ;
260
355
261
- fn set_oneshot ( & self ) ;
356
+ #[ inline( always) ]
357
+ fn as_timer0 ( & self ) -> & RegBlock0 {
358
+ self
359
+ }
262
360
}
263
361
264
- macro_rules! impl_instance {
265
- ( $( $name: ident, ) * ) => {
266
- $(
267
- impl Instance for $name {
268
- const INTERRUPT : Interrupt = Interrupt :: $name;
269
-
270
- fn timer_start<Time >( & self , cycles: Time )
271
- where
272
- Time : Into <u32 >,
273
- {
274
- // If the following sequence of events occurs, the COMPARE event will be
275
- // set here:
276
- // 1. `start` is called.
277
- // 2. The timer runs out but `wait` is _not_ called.
278
- // 3. `start` is called again
279
- //
280
- // If that happens, then we need to reset the event here explicitly, as
281
- // nothing else this method does will reset the event, and if it's still
282
- // active after this method exits, then the next call to `wait` will
283
- // return immediately, no matter how much time has actually passed.
284
- self . events_compare[ 0 ] . reset( ) ;
285
-
286
- // Configure timer to trigger EVENTS_COMPARE when given number of cycles
287
- // is reached.
288
- #[ cfg( not( feature = "51" ) ) ]
289
- self . cc[ 0 ] . write( |w|
290
- // The timer mode was set to 32 bits above, so all possible values
291
- // of `cycles` are valid.
292
- unsafe { w. cc( ) . bits( cycles. into( ) ) } ) ;
293
-
294
- #[ cfg( feature = "51" ) ]
295
- self . cc[ 0 ] . write( |w| unsafe { w. bits( cycles. into( ) ) } ) ;
296
-
297
- // Clear the counter value.
298
- self . tasks_clear. write( |w| unsafe { w. bits( 1 ) } ) ;
299
-
300
- // Start the timer.
301
- self . tasks_start. write( |w| unsafe { w. bits( 1 ) } ) ;
302
- }
303
-
304
- fn timer_reset_event( & self ) {
305
- self . events_compare[ 0 ] . write( |w| w) ;
306
- }
307
-
308
- fn timer_cancel( & self ) {
309
- self . tasks_stop. write( |w| unsafe { w. bits( 1 ) } ) ;
310
- self . timer_reset_event( ) ;
311
- }
312
-
313
- fn timer_running( & self ) -> bool {
314
- self . events_compare[ 0 ] . read( ) . bits( ) == 0
315
- }
316
-
317
- fn read_counter( & self ) -> u32 {
318
- self . tasks_capture[ 1 ] . write( |w| unsafe { w. bits( 1 ) } ) ;
319
- self . cc[ 1 ] . read( ) . bits( )
320
- }
321
-
322
- fn disable_interrupt( & self ) {
323
- self . intenclr. modify( |_, w| w. compare0( ) . clear( ) ) ;
324
- }
325
-
326
- fn enable_interrupt( & self ) {
327
- self . intenset. modify( |_, w| w. compare0( ) . set( ) ) ;
328
- }
329
-
330
- fn set_shorts_periodic( & self ) {
331
- self
332
- . shorts
333
- . write( |w| w. compare0_clear( ) . enabled( ) . compare0_stop( ) . disabled( ) ) ;
334
- }
335
-
336
- fn set_shorts_oneshot( & self ) {
337
- self
338
- . shorts
339
- . write( |w| w. compare0_clear( ) . enabled( ) . compare0_stop( ) . enabled( ) ) ;
340
- }
341
-
342
- fn set_periodic( & self ) {
343
- self . set_shorts_periodic( ) ;
344
- self . prescaler. write(
345
- |w| unsafe { w. prescaler( ) . bits( 4 ) } , // 1 MHz
346
- ) ;
347
- self . bitmode. write( |w| w. bitmode( ) . _32bit( ) ) ;
348
- }
349
-
350
- fn set_oneshot( & self ) {
351
- self . set_shorts_oneshot( ) ;
352
- self . prescaler. write(
353
- |w| unsafe { w. prescaler( ) . bits( 4 ) } , // 1 MHz
354
- ) ;
355
- self . bitmode. write( |w| w. bitmode( ) . _32bit( ) ) ;
356
- }
357
- }
358
- ) *
362
+ impl Instance for TIMER2 {
363
+ const INTERRUPT : Interrupt = Interrupt :: TIMER2 ;
364
+
365
+ #[ inline( always) ]
366
+ fn as_timer0 ( & self ) -> & RegBlock0 {
367
+ self
359
368
}
360
369
}
361
370
362
- impl_instance ! ( TIMER0 , TIMER1 , TIMER2 , ) ;
371
+ #[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
372
+ impl Instance for TIMER3 {
373
+ const INTERRUPT : Interrupt = Interrupt :: TIMER3 ;
374
+
375
+ #[ inline( always) ]
376
+ fn as_timer0 ( & self ) -> & RegBlock0 {
377
+ let rb: & RegBlock3 = self ;
378
+ let rb_ptr: * const RegBlock3 = rb;
379
+
380
+ // SAFETY: TIMER0 and TIMER3 register layouts are identical, except
381
+ // that TIMER3 has 6 CC registers, while TIMER0 has 4. There is
382
+ // appropriate padding to allow other operations to work correctly
383
+ unsafe { & * rb_ptr. cast ( ) }
384
+ }
385
+ }
363
386
364
387
#[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
365
- impl_instance ! ( TIMER3 , TIMER4 , ) ;
388
+ impl Instance for TIMER4 {
389
+ const INTERRUPT : Interrupt = Interrupt :: TIMER4 ;
390
+
391
+ #[ inline( always) ]
392
+ fn as_timer0 ( & self ) -> & RegBlock0 {
393
+ let rb: & RegBlock3 = self ;
394
+ let rb_ptr: * const RegBlock3 = rb;
395
+
396
+ // SAFETY: TIMER0 and TIMER3 register layouts are identical, except
397
+ // that TIMER3 has 6 CC registers, while TIMER0 has 4. There is
398
+ // appropriate padding to allow other operations to work correctly
399
+ unsafe { & * rb_ptr. cast ( ) }
400
+ }
401
+ }
402
+
403
+ mod sealed {
404
+ pub trait Sealed { }
405
+ impl Sealed for super :: TIMER0 { }
406
+ impl Sealed for super :: TIMER1 { }
407
+ impl Sealed for super :: TIMER2 { }
408
+
409
+ #[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
410
+ impl Sealed for super :: TIMER3 { }
411
+
412
+ #[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
413
+ impl Sealed for super :: TIMER4 { }
414
+ }
0 commit comments