@@ -90,7 +90,7 @@ impl Instant {
9090#[ derive( Debug ) ]
9191#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
9292pub struct Timer < TIM > {
93- tim : TIM ,
93+ tim : BasicTimer < TIM > ,
9494 clocks : Clocks ,
9595}
9696
@@ -110,21 +110,23 @@ pub enum Event {
110110
111111impl < TIM > Timer < TIM >
112112where
113- TIM : Instance ,
113+ TIM : Instance < TIM > ,
114114{
115115 /// Configures a TIM peripheral as a periodic count down timer
116116 // TODO: CHange clocks to be a global variable
117117 pub fn new ( tim : TIM , clocks : Clocks , apb : & mut <TIM as rcc:: RccBus >:: Bus ) -> Self {
118118 TIM :: enable ( apb) ;
119119 TIM :: reset ( apb) ;
120120
121+ let tim: BasicTimer < _ > = tim. into ( ) ;
122+
121123 Timer { clocks, tim }
122124 }
123125
124126 /// Stops the timer
125127 #[ inline]
126128 pub fn stop ( & mut self ) {
127- self . tim . set_cr1_cen ( false ) ;
129+ self . tim . cr1 . modify ( |_ , w| w . cen ( ) . disabled ( ) ) ;
128130 }
129131
130132 /// Enable or disable the interrupt for the specified [`Event`].
@@ -166,7 +168,7 @@ where
166168 #[ inline]
167169 pub fn configure_interrupt ( & mut self , event : Event , enable : bool ) {
168170 match event {
169- Event :: Update => self . tim . set_dier_uie ( enable) ,
171+ Event :: Update => self . tim . dier . modify ( |_ , w| w . uie ( ) . bit ( enable) ) ,
170172 }
171173 }
172174
@@ -190,7 +192,7 @@ where
190192 #[ inline]
191193 pub fn is_interrupt_configured ( & self , event : Event ) -> bool {
192194 match event {
193- Event :: Update => self . tim . is_dier_uie_set ( ) ,
195+ Event :: Update => self . tim . dier . read ( ) . uie ( ) . bit ( ) ,
194196 }
195197 }
196198
@@ -214,7 +216,7 @@ where
214216 /// Check if an interrupt event happened.
215217 pub fn is_event_triggered ( & self , event : Event ) -> bool {
216218 match event {
217- Event :: Update => self . tim . is_sr_uief_set ( ) ,
219+ Event :: Update => self . tim . sr . read ( ) . uif ( ) . is_update_pending ( ) ,
218220 }
219221 }
220222
@@ -237,14 +239,15 @@ where
237239 #[ inline]
238240 pub fn clear_event ( & mut self , event : Event ) {
239241 match event {
240- Event :: Update => self . tim . clear_sr_uief ( ) ,
242+ Event :: Update => self . tim . sr . modify ( |_ , w| w . uif ( ) . clear ( ) ) ,
241243 }
242244 }
243245
244246 /// Clear **all** interrupt events.
245247 #[ inline]
246248 pub fn clear_events ( & mut self ) {
247- self . tim . clear_sr ( ) ;
249+ // SAFETY: This atomic write clears all flags and ignores the reserverd bit fields.
250+ self . tim . sr . write ( |w| unsafe { w. bits ( 0 ) } ) ;
248251 }
249252
250253 /// Get access to the underlying register block.
@@ -257,22 +260,22 @@ where
257260 /// Changing specific options can lead to un-expected behavior and nothing
258261 /// is guaranteed.
259262 pub unsafe fn peripheral ( & mut self ) -> & mut TIM {
260- & mut self . tim
263+ & mut self . tim . real_timer
261264 }
262265
263266 /// Releases the TIM peripheral
264267 #[ inline]
265268 pub fn free ( mut self ) -> TIM {
266269 self . stop ( ) ;
267- self . tim
270+ self . tim . real_timer
268271 }
269272}
270273
271- impl < TIM > Periodic for Timer < TIM > where TIM : Instance { }
274+ impl < TIM > Periodic for Timer < TIM > where TIM : Instance < TIM > { }
272275
273276impl < TIM > CountDown for Timer < TIM >
274277where
275- TIM : Instance ,
278+ TIM : Instance < TIM > ,
276279{
277280 type Time = duration:: Generic < u32 > ;
278281
@@ -288,10 +291,13 @@ where
288291 let ticks = clock. integer ( ) * * timeout. scaling_factor ( ) * timeout. integer ( ) ;
289292
290293 let psc = crate :: unwrap!( u16 :: try_from( ( ticks - 1 ) / ( 1 << 16 ) ) . ok( ) ) ;
291- self . tim . set_psc ( psc) ;
294+ // NOTE(write): uses all bits in this register.
295+ self . tim . psc . write ( |w| w. psc ( ) . bits ( psc) ) ;
292296
293297 let arr = crate :: unwrap!( u16 :: try_from( ticks / u32 :: from( psc + 1 ) ) . ok( ) ) ;
294- self . tim . set_arr ( arr) ;
298+ // TODO(Sh3Rm4n):
299+ // self.tim.arr.write(|w| { w.arr().bits(arr) });
300+ self . tim . arr . write ( |w| unsafe { w. bits ( u32:: from ( arr) ) } ) ;
295301
296302 // Ensure that the below procedure does not create an unexpected interrupt.
297303 let is_update_interrupt_active = self . is_interrupt_configured ( Event :: Update ) ;
@@ -301,7 +307,7 @@ where
301307
302308 // Trigger an update event to load the prescaler value to the clock The above line raises
303309 // an update event which will indicate that the timer is already finished.
304- self . tim . set_egr_ug ( ) ;
310+ self . tim . egr . write ( |w| w . ug ( ) . update ( ) ) ;
305311 // Since this is not the case, it should be cleared.
306312 self . clear_event ( Event :: Update ) ;
307313
@@ -310,13 +316,13 @@ where
310316 }
311317
312318 // start counter
313- self . tim . set_cr1_cen ( true ) ;
319+ self . tim . cr1 . modify ( |_ , w| w . cen ( ) . bit ( true ) ) ;
314320 }
315321
316322 /// Wait until [`Event::Update`] / the timer has elapsed
317323 /// and than clear the event.
318324 fn wait ( & mut self ) -> nb:: Result < ( ) , Void > {
319- if !self . tim . is_sr_uief_set ( ) {
325+ if !self . tim . sr . read ( ) . uif ( ) . is_update_pending ( ) {
320326 Err ( nb:: Error :: WouldBlock )
321327 } else {
322328 self . clear_event ( Event :: Update ) ;
@@ -332,12 +338,12 @@ pub struct AlreadyCancled;
332338
333339impl < TIM > Cancel for Timer < TIM >
334340where
335- TIM : Instance ,
341+ TIM : Instance < TIM > ,
336342{
337343 type Error = AlreadyCancled ;
338344 fn cancel ( & mut self ) -> Result < ( ) , Self :: Error > {
339345 // If timer is already stopped.
340- if !self . tim . is_cr1_cen_set ( ) {
346+ if !self . tim . cr1 . read ( ) . cen ( ) . bit ( ) {
341347 return Err ( AlreadyCancled ) ;
342348 }
343349 self . stop ( ) ;
@@ -376,8 +382,8 @@ pub trait CommonRegisterBlock: crate::private::Sealed {
376382}
377383
378384/// Associated clocks with timers
379- pub trait Instance :
380- CommonRegisterBlock
385+ pub trait Instance < T > :
386+ Into < BasicTimer < T > >
381387 + crate :: interrupts:: InterruptNumber
382388 + crate :: private:: Sealed
383389 + rcc:: Enable
@@ -389,6 +395,17 @@ pub trait Instance:
389395
390396macro_rules! timer {
391397 ( $TIMX: ident) => {
398+ // TODO: This must be associated, so that Into trait works?
399+ impl From <crate :: pac:: $TIMX> for BasicTimer <crate :: pac:: $TIMX> {
400+ fn from( tim: crate :: pac:: $TIMX) -> Self {
401+ Self {
402+ // TODO: Check if TIM6 is really common ground for all timer.
403+ _ptr: unsafe { pac:: TIM6 :: ptr( ) as _ } ,
404+ real_timer: tim,
405+ }
406+ }
407+ }
408+
392409 impl CommonRegisterBlock for crate :: pac:: $TIMX {
393410 #[ inline]
394411 fn set_cr1_cen( & mut self , enable: bool ) {
@@ -452,7 +469,7 @@ macro_rules! timer {
452469macro_rules! timer_var_clock {
453470 ( $( $TIMX: ident, $timXsw: ident) ,+) => {
454471 $(
455- impl Instance for crate :: pac:: $TIMX {
472+ impl Instance < crate :: pac :: $TIMX> for crate :: pac:: $TIMX {
456473 #[ inline]
457474 fn clock( clocks: & Clocks ) -> Hertz {
458475 // SAFETY: Atomic read with no side-effects.
@@ -496,7 +513,7 @@ macro_rules! timer_var_clock {
496513macro_rules! timer_static_clock {
497514 ( $( $TIMX: ident) ,+) => {
498515 $(
499- impl Instance for crate :: pac:: $TIMX {
516+ impl Instance < crate :: pac :: $TIMX> for crate :: pac:: $TIMX {
500517 #[ inline]
501518 fn clock( clocks: & Clocks ) -> Hertz {
502519 <pac:: $TIMX as rcc:: BusTimerClock >:: timer_clock( clocks)
@@ -597,7 +614,9 @@ fn test(tim: pac::TIM16) {
597614
598615// TODO: Rename BasicTimer to BasicTimerPeripheral or similar to not be confusing
599616// by the actual Timer??? or in general, this could replace the Timer implementation?
600- struct BasicTimer < T > {
617+ #[ derive( Debug ) ]
618+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
619+ pub struct BasicTimer < T > {
601620 _ptr : usize ,
602621 real_timer : T ,
603622}
@@ -610,21 +629,21 @@ impl<T> Deref for BasicTimer<T> {
610629 unsafe { & * ( self . _ptr as * const Self :: Target ) }
611630 }
612631}
613-
614- impl From < pac:: TIM6 > for BasicTimer < pac:: TIM6 > {
615- fn from ( tim : pac:: TIM6 ) -> Self {
616- Self {
617- _ptr : unsafe { pac:: TIM6 :: ptr ( ) as _ } ,
618- real_timer : tim,
619- }
620- }
621- }
622-
623- impl < T > BasicTimer < T > {
624- pub fn free ( self ) -> T {
625- self . real_timer
626- }
627- }
632+ //
633+ // impl From<pac::TIM6> for BasicTimer<pac::TIM6> {
634+ // fn from(tim: pac::TIM6) -> Self {
635+ // Self {
636+ // _ptr: unsafe { pac::TIM6::ptr() as _ },
637+ // real_timer: tim,
638+ // }
639+ // }
640+ // }
641+
642+ // impl<T> BasicTimer<T> {
643+ // pub fn free(self) -> T {
644+ // self.real_timer
645+ // }
646+ // }
628647
629648// TODO: Is that trait needed, when we already have Into<BasicTimer>?
630649pub trait BasicTimerInstance : Deref < Target = pac:: tim6:: RegisterBlock > { }
0 commit comments