33#![ no_std]
44
55use cortex_m:: peripheral:: { syst:: SystClkSource , DCB , DWT , SYST } ;
6- use rtic_monotonic:: {
7- embedded_time:: { clock:: Error , fraction:: Fraction } ,
8- Clock , Instant , Monotonic ,
9- } ;
6+ pub use fugit:: { self , ExtU32 } ;
7+ use rtic_monotonic:: Monotonic ;
108
119/// DWT and Systick combination implementing `embedded_time::Clock` and `rtic_monotonic::Monotonic`
1210///
13- /// The frequency of the DWT and SysTick is encoded using the parameter `FREQ `.
14- pub struct DwtSystick < const FREQ : u32 > {
11+ /// The frequency of the DWT and SysTick is encoded using the parameter `TIMER_HZ `.
12+ pub struct DwtSystick < const TIMER_HZ : u32 > {
1513 dwt : DWT ,
1614 systick : SYST ,
1715}
1816
19- impl < const FREQ : u32 > DwtSystick < FREQ > {
17+ impl < const TIMER_HZ : u32 > DwtSystick < TIMER_HZ > {
2018 /// Enable the DWT and provide a new `Monotonic` based on DWT and SysTick.
2119 ///
2220 /// Note that the `sysclk` parameter should come from e.g. the HAL's clock generation function
2321 /// so the real speed and the declared speed can be compared.
22+ #[ inline( always) ]
2423 pub fn new ( dcb : & mut DCB , dwt : DWT , systick : SYST , sysclk : u32 ) -> Self {
25- assert ! ( FREQ == sysclk) ;
24+ assert ! ( TIMER_HZ == sysclk) ;
2625
2726 dcb. enable_trace ( ) ;
2827 DWT :: unlock ( ) ;
@@ -35,19 +34,16 @@ impl<const FREQ: u32> DwtSystick<FREQ> {
3534 }
3635}
3736
38- impl < const FREQ : u32 > Clock for DwtSystick < FREQ > {
39- type T = u32 ;
37+ impl < const TIMER_HZ : u32 > Monotonic for DwtSystick < TIMER_HZ > {
38+ const DISABLE_INTERRUPT_ON_EMPTY_QUEUE : bool = true ;
4039
41- const SCALING_FACTOR : Fraction = Fraction :: new ( 1 , FREQ ) ;
40+ type Instant = fugit:: TimerInstantU32 < TIMER_HZ > ;
41+ type Duration = fugit:: TimerDurationU32 < TIMER_HZ > ;
4242
43- fn try_now ( & self ) -> Result < Instant < Self > , Error > {
44- // The instant is always valid when the DWT is not reset
45- Ok ( Instant :: new ( self . dwt . cyccnt . read ( ) ) )
43+ # [ inline ( always ) ]
44+ fn now ( & mut self ) -> Self :: Instant {
45+ Self :: Instant :: from_ticks ( self . dwt . cyccnt . read ( ) )
4646 }
47- }
48-
49- impl < const FREQ : u32 > Monotonic for DwtSystick < FREQ > {
50- const DISABLE_INTERRUPT_ON_EMPTY_QUEUE : bool = true ;
5147
5248 unsafe fn reset ( & mut self ) {
5349 self . dwt . enable_cycle_counter ( ) ;
@@ -58,27 +54,33 @@ impl<const FREQ: u32> Monotonic for DwtSystick<FREQ> {
5854 self . dwt . cyccnt . write ( 0 ) ;
5955 }
6056
61- fn set_compare ( & mut self , val : & Instant < Self > ) {
57+ fn set_compare ( & mut self , val : Self :: Instant ) {
6258 // The input `val` is in the timer, but the SysTick is a down-counter.
6359 // We need to convert into its domain.
64- let now: Instant < Self > = Instant :: new ( self . dwt . cyccnt . read ( ) ) ;
60+ let now = self . now ( ) ;
6561
6662 let max = 0x00ff_ffff ;
6763
68- let dur = match val. checked_duration_since ( & now) {
64+ let dur = match val. checked_duration_since ( now) {
6965 None => 1 , // In the past
7066
7167 // ARM Architecture Reference Manual says:
7268 // "Setting SYST_RVR to zero has the effect of
7369 // disabling the SysTick counter independently
7470 // of the counter enable bit.", so the min is 1
75- Some ( x) => max. min ( x. integer ( ) ) . max ( 1 ) ,
71+ Some ( x) => max. min ( x. ticks ( ) ) . max ( 1 ) ,
7672 } ;
7773
7874 self . systick . set_reload ( dur) ;
7975 self . systick . clear_current ( ) ;
8076 }
8177
78+ #[ inline( always) ]
79+ fn zero ( ) -> Self :: Instant {
80+ Self :: Instant :: from_ticks ( 0 )
81+ }
82+
83+ #[ inline( always) ]
8284 fn clear_compare_flag ( & mut self ) {
8385 // NOOP with SysTick interrupt
8486 }
0 commit comments