@@ -90,7 +90,7 @@ impl Instant {
90
90
#[ derive( Debug ) ]
91
91
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
92
92
pub struct Timer < TIM > {
93
- tim : TIM ,
93
+ tim : BasicTimer < TIM > ,
94
94
clocks : Clocks ,
95
95
}
96
96
@@ -110,21 +110,23 @@ pub enum Event {
110
110
111
111
impl < TIM > Timer < TIM >
112
112
where
113
- TIM : Instance ,
113
+ TIM : Instance < TIM > ,
114
114
{
115
115
/// Configures a TIM peripheral as a periodic count down timer
116
116
// TODO: CHange clocks to be a global variable
117
117
pub fn new ( tim : TIM , clocks : Clocks , apb : & mut <TIM as rcc:: RccBus >:: Bus ) -> Self {
118
118
TIM :: enable ( apb) ;
119
119
TIM :: reset ( apb) ;
120
120
121
+ let tim: BasicTimer < _ > = tim. into ( ) ;
122
+
121
123
Timer { clocks, tim }
122
124
}
123
125
124
126
/// Stops the timer
125
127
#[ inline]
126
128
pub fn stop ( & mut self ) {
127
- self . tim . set_cr1_cen ( false ) ;
129
+ self . tim . cr1 . modify ( |_ , w| w . cen ( ) . disabled ( ) ) ;
128
130
}
129
131
130
132
/// Enable or disable the interrupt for the specified [`Event`].
@@ -166,7 +168,7 @@ where
166
168
#[ inline]
167
169
pub fn configure_interrupt ( & mut self , event : Event , enable : bool ) {
168
170
match event {
169
- Event :: Update => self . tim . set_dier_uie ( enable) ,
171
+ Event :: Update => self . tim . dier . modify ( |_ , w| w . uie ( ) . bit ( enable) ) ,
170
172
}
171
173
}
172
174
@@ -190,7 +192,7 @@ where
190
192
#[ inline]
191
193
pub fn is_interrupt_configured ( & self , event : Event ) -> bool {
192
194
match event {
193
- Event :: Update => self . tim . is_dier_uie_set ( ) ,
195
+ Event :: Update => self . tim . dier . read ( ) . uie ( ) . bit ( ) ,
194
196
}
195
197
}
196
198
@@ -214,7 +216,7 @@ where
214
216
/// Check if an interrupt event happened.
215
217
pub fn is_event_triggered ( & self , event : Event ) -> bool {
216
218
match event {
217
- Event :: Update => self . tim . is_sr_uief_set ( ) ,
219
+ Event :: Update => self . tim . sr . read ( ) . uif ( ) . is_update_pending ( ) ,
218
220
}
219
221
}
220
222
@@ -237,14 +239,15 @@ where
237
239
#[ inline]
238
240
pub fn clear_event ( & mut self , event : Event ) {
239
241
match event {
240
- Event :: Update => self . tim . clear_sr_uief ( ) ,
242
+ Event :: Update => self . tim . sr . modify ( |_ , w| w . uif ( ) . clear ( ) ) ,
241
243
}
242
244
}
243
245
244
246
/// Clear **all** interrupt events.
245
247
#[ inline]
246
248
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 ) } ) ;
248
251
}
249
252
250
253
/// Get access to the underlying register block.
@@ -257,22 +260,22 @@ where
257
260
/// Changing specific options can lead to un-expected behavior and nothing
258
261
/// is guaranteed.
259
262
pub unsafe fn peripheral ( & mut self ) -> & mut TIM {
260
- & mut self . tim
263
+ & mut self . tim . real_timer
261
264
}
262
265
263
266
/// Releases the TIM peripheral
264
267
#[ inline]
265
268
pub fn free ( mut self ) -> TIM {
266
269
self . stop ( ) ;
267
- self . tim
270
+ self . tim . real_timer
268
271
}
269
272
}
270
273
271
- impl < TIM > Periodic for Timer < TIM > where TIM : Instance { }
274
+ impl < TIM > Periodic for Timer < TIM > where TIM : Instance < TIM > { }
272
275
273
276
impl < TIM > CountDown for Timer < TIM >
274
277
where
275
- TIM : Instance ,
278
+ TIM : Instance < TIM > ,
276
279
{
277
280
type Time = duration:: Generic < u32 > ;
278
281
@@ -288,10 +291,13 @@ where
288
291
let ticks = clock. integer ( ) * * timeout. scaling_factor ( ) * timeout. integer ( ) ;
289
292
290
293
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) ) ;
292
296
293
297
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) ) } ) ;
295
301
296
302
// Ensure that the below procedure does not create an unexpected interrupt.
297
303
let is_update_interrupt_active = self . is_interrupt_configured ( Event :: Update ) ;
@@ -301,7 +307,7 @@ where
301
307
302
308
// Trigger an update event to load the prescaler value to the clock The above line raises
303
309
// 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 ( ) ) ;
305
311
// Since this is not the case, it should be cleared.
306
312
self . clear_event ( Event :: Update ) ;
307
313
@@ -310,13 +316,13 @@ where
310
316
}
311
317
312
318
// start counter
313
- self . tim . set_cr1_cen ( true ) ;
319
+ self . tim . cr1 . modify ( |_ , w| w . cen ( ) . bit ( true ) ) ;
314
320
}
315
321
316
322
/// Wait until [`Event::Update`] / the timer has elapsed
317
323
/// and than clear the event.
318
324
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 ( ) {
320
326
Err ( nb:: Error :: WouldBlock )
321
327
} else {
322
328
self . clear_event ( Event :: Update ) ;
@@ -332,12 +338,12 @@ pub struct AlreadyCancled;
332
338
333
339
impl < TIM > Cancel for Timer < TIM >
334
340
where
335
- TIM : Instance ,
341
+ TIM : Instance < TIM > ,
336
342
{
337
343
type Error = AlreadyCancled ;
338
344
fn cancel ( & mut self ) -> Result < ( ) , Self :: Error > {
339
345
// If timer is already stopped.
340
- if !self . tim . is_cr1_cen_set ( ) {
346
+ if !self . tim . cr1 . read ( ) . cen ( ) . bit ( ) {
341
347
return Err ( AlreadyCancled ) ;
342
348
}
343
349
self . stop ( ) ;
@@ -376,8 +382,8 @@ pub trait CommonRegisterBlock: crate::private::Sealed {
376
382
}
377
383
378
384
/// Associated clocks with timers
379
- pub trait Instance :
380
- CommonRegisterBlock
385
+ pub trait Instance < T > :
386
+ Into < BasicTimer < T > >
381
387
+ crate :: interrupts:: InterruptNumber
382
388
+ crate :: private:: Sealed
383
389
+ rcc:: Enable
@@ -389,6 +395,17 @@ pub trait Instance:
389
395
390
396
macro_rules! timer {
391
397
( $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
+
392
409
impl CommonRegisterBlock for crate :: pac:: $TIMX {
393
410
#[ inline]
394
411
fn set_cr1_cen( & mut self , enable: bool ) {
@@ -452,7 +469,7 @@ macro_rules! timer {
452
469
macro_rules! timer_var_clock {
453
470
( $( $TIMX: ident, $timXsw: ident) ,+) => {
454
471
$(
455
- impl Instance for crate :: pac:: $TIMX {
472
+ impl Instance < crate :: pac :: $TIMX> for crate :: pac:: $TIMX {
456
473
#[ inline]
457
474
fn clock( clocks: & Clocks ) -> Hertz {
458
475
// SAFETY: Atomic read with no side-effects.
@@ -496,7 +513,7 @@ macro_rules! timer_var_clock {
496
513
macro_rules! timer_static_clock {
497
514
( $( $TIMX: ident) ,+) => {
498
515
$(
499
- impl Instance for crate :: pac:: $TIMX {
516
+ impl Instance < crate :: pac :: $TIMX> for crate :: pac:: $TIMX {
500
517
#[ inline]
501
518
fn clock( clocks: & Clocks ) -> Hertz {
502
519
<pac:: $TIMX as rcc:: BusTimerClock >:: timer_clock( clocks)
@@ -597,7 +614,9 @@ fn test(tim: pac::TIM16) {
597
614
598
615
// TODO: Rename BasicTimer to BasicTimerPeripheral or similar to not be confusing
599
616
// 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 > {
601
620
_ptr : usize ,
602
621
real_timer : T ,
603
622
}
@@ -610,21 +629,21 @@ impl<T> Deref for BasicTimer<T> {
610
629
unsafe { & * ( self . _ptr as * const Self :: Target ) }
611
630
}
612
631
}
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
+ // }
628
647
629
648
// TODO: Is that trait needed, when we already have Into<BasicTimer>?
630
649
pub trait BasicTimerInstance : Deref < Target = pac:: tim6:: RegisterBlock > { }
0 commit comments