Skip to content

Commit 5ff1d05

Browse files
committed
WIP: Drafting deref based impl
Testsuite is NOT working :(
1 parent fce730d commit 5ff1d05

File tree

1 file changed

+58
-39
lines changed

1 file changed

+58
-39
lines changed

src/timer.rs

+58-39
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl Instant {
9090
#[derive(Debug)]
9191
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
9292
pub struct Timer<TIM> {
93-
tim: TIM,
93+
tim: BasicTimer<TIM>,
9494
clocks: Clocks,
9595
}
9696

@@ -110,21 +110,23 @@ pub enum Event {
110110

111111
impl<TIM> Timer<TIM>
112112
where
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

273276
impl<TIM> CountDown for Timer<TIM>
274277
where
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

333339
impl<TIM> Cancel for Timer<TIM>
334340
where
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

390396
macro_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 {
452469
macro_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 {
496513
macro_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>?
630649
pub trait BasicTimerInstance: Deref<Target = pac::tim6::RegisterBlock> {}

0 commit comments

Comments
 (0)