33//! See product specification, chapter 24.
44
55#[ 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+ } ;
710
811#[ cfg( not( feature = "9160" ) ) ]
9- use crate :: pac:: { Interrupt , TIMER0 , TIMER1 , TIMER2 } ;
12+ use crate :: pac:: { timer0 :: RegisterBlock as RegBlock0 , Interrupt , TIMER0 , TIMER1 , TIMER2 } ;
1013
1114use cast:: u32;
1215use embedded_hal:: {
@@ -20,6 +23,15 @@ use void::{unreachable, Void};
2023#[ cfg( any( feature = "52832" , feature = "52833" , feature = "52840" ) ) ]
2124use crate :: pac:: { TIMER3 , TIMER4 } ;
2225
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+
2335use core:: marker:: PhantomData ;
2436
2537pub struct OneShot ;
@@ -231,135 +243,172 @@ where
231243 }
232244}
233245
234- /// Implemented by all `timer0:: TIMER` instances.
235- pub trait Instance {
246+ /// Implemented by all TIMER* instances.
247+ pub trait Instance : sealed :: Sealed {
236248 /// This interrupt associated with this RTC instance.
237249 const INTERRUPT : Interrupt ;
238250
251+ fn as_timer0 ( & self ) -> & RegBlock0 ;
252+
239253 fn timer_start < Time > ( & self , cycles : Time )
240254 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+ }
242286
243- fn timer_reset_event ( & self ) ;
287+ fn timer_reset_event ( & self ) {
288+ self . as_timer0 ( ) . events_compare [ 0 ] . write ( |w| w) ;
289+ }
244290
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+ }
246295
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+ }
248320
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+ }
250326
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+ }
252334
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+ }
254343
255- fn set_shorts_periodic ( & self ) ;
344+ impl Instance for TIMER0 {
345+ const INTERRUPT : Interrupt = Interrupt :: TIMER0 ;
256346
257- fn set_shorts_oneshot ( & self ) ;
347+ #[ inline( always) ]
348+ fn as_timer0 ( & self ) -> & RegBlock0 {
349+ self
350+ }
351+ }
258352
259- fn set_periodic ( & self ) ;
353+ impl Instance for TIMER1 {
354+ const INTERRUPT : Interrupt = Interrupt :: TIMER1 ;
260355
261- fn set_oneshot ( & self ) ;
356+ #[ inline( always) ]
357+ fn as_timer0 ( & self ) -> & RegBlock0 {
358+ self
359+ }
262360}
263361
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
359368 }
360369}
361370
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+ }
363386
364387#[ 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