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