Skip to content

Commit e3eb744

Browse files
bors[bot]burrbull
andauthored
Merge #382
382: timer::General trait r=therealprof a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents ff4dca2 + 74d18e1 commit e3eb744

File tree

10 files changed

+248
-291
lines changed

10 files changed

+248
-291
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Added
1111

12+
- `count_down` constructor for `Timer` -> `CountDownTimer` without start [#382]
1213
- Implementation of RTIC Monotonic for TIM2 & TIM5 under `rtic` feature [#380]
1314
- `IoPin` for `Output<OpenDrain>> <-> Input<Floating>>` [#374]
1415

16+
[#382]: https://github.com/stm32-rs/stm32f4xx-hal/pull/382
1517
[#380]: https://github.com/stm32-rs/stm32f4xx-hal/pull/380
1618
[#374]: https://github.com/stm32-rs/stm32f4xx-hal/pull/374
1719

1820
### Changed
1921

20-
- [breaking-change] Remove all deprecated
2122
- [breaking-change] Bump `stm32f4` to 0.14. Update RTIC based examples to use `rtic` 0.6 [#367]
2223
- [breaking-change] Bump `bxcan` to 0.6 [#371]
2324

examples/analog-stopwatch-with-spi-ssd1306.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ fn main() -> ! {
127127
disp.flush().unwrap();
128128

129129
// Create a 1ms periodic interrupt from TIM2
130-
let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.hz());
130+
let mut timer = Timer::new(dp.TIM2, &clocks).count_down();
131+
timer.start(1.hz());
131132
timer.listen(Event::TimeOut);
132133

133134
free(|cs| {

examples/blinky-timer-irq.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ fn main() -> ! {
7979
cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led));
8080

8181
// Set up a timer expiring after 1s
82-
let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.hz());
82+
let mut timer = Timer::new(dp.TIM2, &clocks).count_down();
83+
timer.start(1.hz());
8384

8485
// Generate an interrupt when the timer expires
8586
timer.listen(Event::TimeOut);

examples/stopwatch-with-ssd1306-and-interrupts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ fn main() -> ! {
9393
disp.flush().unwrap();
9494

9595
// Create a 1ms periodic interrupt from TIM2
96-
let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.hz());
96+
let mut timer = Timer::new(dp.TIM2, &clocks).count_down();
97+
timer.start(1.hz());
9798
timer.listen(Event::TimeOut);
9899

99100
free(|cs| {

examples/timer-periph.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ fn main() -> ! {
2929
let clocks = rcc.cfgr.sysclk(24.mhz()).freeze();
3030

3131
// Create a timer based on SysTick
32-
let mut timer = Timer::new(dp.TIM1, &clocks).start_count_down(1.hz());
32+
let mut timer = Timer::new(dp.TIM1, &clocks).count_down();
33+
timer.start(1.hz());
3334

3435
hprintln!("hello!").unwrap();
3536
// wait until timer expires

examples/timer-syst.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ fn main() -> ! {
3030
let clocks = rcc.cfgr.sysclk(24.mhz()).freeze();
3131

3232
// Create a timer based on SysTick
33-
let mut timer = Timer::syst(cp.SYST, &clocks).start_count_down(24.hz());
33+
let mut timer = Timer::syst(cp.SYST, &clocks).count_down();
34+
timer.start(24.hz());
3435

3536
hprintln!("hello!").unwrap();
3637
// wait until timer expires

src/delay/timer.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use core::cmp::max;
88
use cast::{u16, u32};
99
use embedded_hal::blocking::delay::{DelayMs, DelayUs};
1010

11-
use crate::{pac, rcc::Clocks, timer::Timer};
11+
use crate::{
12+
pac,
13+
rcc::Clocks,
14+
timer::{General, Timer},
15+
};
1216

1317
use super::Delay;
1418

@@ -17,25 +21,23 @@ macro_rules! hal {
1721
$(
1822
fn $waitfn(tim: &mut $TIM, prescaler: u16, auto_reload_register: u32) {
1923
// Write Prescaler (PSC)
20-
tim.psc.write(|w| w.psc().bits(prescaler));
24+
tim.set_prescaler(prescaler);
2125

2226
// Write Auto-Reload Register (ARR)
2327
// Note: Make it impossible to set the ARR value to 0, since this
2428
// would cause an infinite loop.
25-
tim.arr.write(|w| unsafe { w.bits(max(1, auto_reload_register)) });
29+
tim.set_auto_reload(max(1, auto_reload_register)).unwrap();
2630

2731
// Trigger update event (UEV) in the event generation register (EGR)
2832
// in order to immediately apply the config
29-
tim.cr1.modify(|_, w| w.urs().set_bit());
30-
tim.egr.write(|w| w.ug().set_bit());
31-
tim.cr1.modify(|_, w| w.urs().clear_bit());
33+
tim.trigger_update();
3234

3335
// Configure the counter in one-pulse mode (counter stops counting at
3436
// the next updateevent, clearing the CEN bit) and enable the counter.
3537
tim.cr1.write(|w| w.opm().set_bit().cen().set_bit());
3638

3739
// Wait for CEN bit to clear
38-
while tim.cr1.read().cen().is_enabled() { /* wait */ }
40+
while tim.is_counter_enabled() { /* wait */ }
3941
}
4042

4143
impl Timer<$TIM> {

src/pwm.rs

Lines changed: 26 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
use crate::{bb, hal as pwm, time::Hertz, timer::Timer};
2-
use cast::{u16, u32};
1+
use crate::{
2+
bb, hal as pwm,
3+
time::Hertz,
4+
timer::{General, Timer},
5+
};
6+
use cast::u16;
37
use core::{marker::PhantomData, mem::MaybeUninit};
48

59
pub trait Pins<TIM, P> {
@@ -112,19 +116,19 @@ macro_rules! pwm_pin {
112116
//NOTE(unsafe) atomic read with no side effects
113117
#[inline]
114118
pub fn get_duty(&self) -> u16 {
115-
unsafe { (*<$TIMX>::ptr()).$ccr.read().ccr().bits() as u16 }
119+
unsafe { (*<$TIMX>::ptr()).$ccr.read().bits() as u16 }
116120
}
117121

118122
//NOTE(unsafe) atomic read with no side effects
119123
#[inline]
120124
pub fn get_max_duty(&self) -> u16 {
121-
unsafe { (*<$TIMX>::ptr()).arr.read().arr().bits() as u16 }
125+
unsafe { (*<$TIMX>::ptr()).arr.read().bits() as u16 }
122126
}
123127

124128
//NOTE(unsafe) atomic write with no side effects
125129
#[inline]
126130
pub fn set_duty(&mut self, duty: u16) {
127-
unsafe { (*<$TIMX>::ptr()).$ccr.write(|w| w.ccr().bits(duty.into())) }
131+
unsafe { (*<$TIMX>::ptr()).$ccr.write(|w| w.bits(duty.into())) }
128132
}
129133
}
130134

@@ -153,7 +157,7 @@ macro_rules! pwm_all_channels {
153157
($($TIMX:ident,)+) => {
154158
$(
155159
impl Timer<crate::pac::$TIMX> {
156-
pub fn pwm<P, PINS, T>(self, _pins: PINS, freq: T) -> PINS::Channels
160+
pub fn pwm<P, PINS, T>(mut self, _pins: PINS, freq: T) -> PINS::Channels
157161
where
158162
PINS: Pins<crate::pac::$TIMX, P>,
159163
T: Into<Hertz>,
@@ -182,14 +186,12 @@ macro_rules! pwm_all_channels {
182186

183187
let ticks = self.clk.0 / freq.into().0;
184188
let psc = (ticks - 1) / (1 << 16);
185-
self.tim.psc.write(|w| w.psc().bits(u16(psc).unwrap()) );
186-
let arr = u16(ticks / (psc + 1)).unwrap();
187-
self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });
189+
self.tim.set_prescaler(u16(psc).unwrap());
190+
let arr = ticks / (psc + 1);
191+
self.tim.set_auto_reload(arr).unwrap();
188192

189193
// Trigger update event to load the registers
190-
self.tim.cr1.modify(|_, w| w.urs().set_bit());
191-
self.tim.egr.write(|w| w.ug().set_bit());
192-
self.tim.cr1.modify(|_, w| w.urs().clear_bit());
194+
self.tim.trigger_update();
193195

194196
let _tim = &self.tim;
195197
brk!($TIMX, _tim);
@@ -220,7 +222,7 @@ macro_rules! pwm_2_channels {
220222
($($TIMX:ident,)+) => {
221223
$(
222224
impl Timer<crate::pac::$TIMX> {
223-
pub fn pwm<P, PINS, T>(self, _pins: PINS, freq: T) -> PINS::Channels
225+
pub fn pwm<P, PINS, T>(mut self, _pins: PINS, freq: T) -> PINS::Channels
224226
where
225227
PINS: Pins<crate::pac::$TIMX, P>,
226228
T: Into<Hertz>,
@@ -245,14 +247,12 @@ macro_rules! pwm_2_channels {
245247

246248
let ticks = self.clk.0 / freq.into().0;
247249
let psc = (ticks - 1) / (1 << 16);
248-
self.tim.psc.write(|w| w.psc().bits(u16(psc).unwrap()) );
249-
let arr = u16(ticks / (psc + 1)).unwrap();
250-
self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });
250+
self.tim.set_prescaler(u16(psc).unwrap());
251+
let arr = ticks / (psc + 1);
252+
self.tim.set_auto_reload(arr).unwrap();
251253

252254
// Trigger update event to load the registers
253-
self.tim.cr1.modify(|_, w| w.urs().set_bit());
254-
self.tim.egr.write(|w| w.ug().set_bit());
255-
self.tim.cr1.modify(|_, w| w.urs().clear_bit());
255+
self.tim.trigger_update();
256256

257257
self.tim.cr1.write(|w|
258258
w.opm()
@@ -275,7 +275,7 @@ macro_rules! pwm_1_channel {
275275
($($TIMX:ident,)+) => {
276276
$(
277277
impl Timer<crate::pac::$TIMX> {
278-
pub fn pwm<P, PINS, T>(self, _pins: PINS, freq: T) -> PINS::Channels
278+
pub fn pwm<P, PINS, T>(mut self, _pins: PINS, freq: T) -> PINS::Channels
279279
where
280280
PINS: Pins<crate::pac::$TIMX, P>,
281281
T: Into<Hertz>,
@@ -295,14 +295,12 @@ macro_rules! pwm_1_channel {
295295

296296
let ticks = self.clk.0 / freq.into().0;
297297
let psc = (ticks - 1) / (1 << 16);
298-
self.tim.psc.write(|w| w.psc().bits(u16(psc).unwrap()) );
299-
let arr = u16(ticks / (psc + 1)).unwrap();
300-
self.tim.arr.write(|w| unsafe { w.bits(u32(arr)) });
298+
self.tim.set_prescaler(u16(psc).unwrap());
299+
let arr = ticks / (psc + 1);
300+
self.tim.set_auto_reload(arr).unwrap();
301301

302302
// Trigger update event to load the registers
303-
self.tim.cr1.modify(|_, w| w.urs().set_bit());
304-
self.tim.egr.write(|w| w.ug().set_bit());
305-
self.tim.cr1.modify(|_, w| w.urs().clear_bit());
303+
self.tim.trigger_update();
306304

307305
self.tim.cr1.write(|w|
308306
w.cen()
@@ -318,133 +316,7 @@ macro_rules! pwm_1_channel {
318316
};
319317
}
320318

321-
#[cfg(feature = "stm32f410")]
322-
macro_rules! pwm_pin_tim5 {
323-
($TIMX:ty, $C:ty, $ccr: ident, $bit:literal) => {
324-
impl PwmChannels<$TIMX, $C> {
325-
//NOTE(unsafe) atomic write with no side effects
326-
#[inline]
327-
pub fn disable(&mut self) {
328-
unsafe { bb::clear(&(*<$TIMX>::ptr()).ccer, 0) }
329-
}
330-
331-
//NOTE(unsafe) atomic write with no side effects
332-
#[inline]
333-
pub fn enable(&mut self) {
334-
unsafe { bb::set(&(*<$TIMX>::ptr()).ccer, 0) }
335-
}
336-
337-
//NOTE(unsafe) atomic read with no side effects
338-
#[inline]
339-
pub fn get_duty(&self) -> u16 {
340-
unsafe { (*<$TIMX>::ptr()).$ccr.read().ccr1_l().bits() as u16 }
341-
}
342-
343-
//NOTE(unsafe) atomic read with no side effects
344-
#[inline]
345-
pub fn get_max_duty(&self) -> u16 {
346-
unsafe { (*<$TIMX>::ptr()).arr.read().arr_l().bits() as u16 }
347-
}
348-
349-
//NOTE(unsafe) atomic write with no side effects
350-
#[inline]
351-
pub fn set_duty(&mut self, duty: u16) {
352-
unsafe {
353-
(*<$TIMX>::ptr())
354-
.$ccr
355-
.write(|w| w.ccr1_l().bits(duty.into()))
356-
}
357-
}
358-
}
359-
360-
impl pwm::PwmPin for PwmChannels<$TIMX, $C> {
361-
type Duty = u16;
362-
fn disable(&mut self) {
363-
self.disable()
364-
}
365-
fn enable(&mut self) {
366-
self.enable()
367-
}
368-
fn get_duty(&self) -> Self::Duty {
369-
self.get_duty()
370-
}
371-
fn get_max_duty(&self) -> Self::Duty {
372-
self.get_max_duty()
373-
}
374-
fn set_duty(&mut self, duty: Self::Duty) {
375-
self.set_duty(duty)
376-
}
377-
}
378-
};
379-
}
380-
381-
#[cfg(feature = "stm32f410")]
382-
macro_rules! pwm_tim5_f410 {
383-
($($TIMX:ident,)+) => {
384-
$(
385-
impl Timer<crate::pac::$TIMX> {
386-
pub fn pwm<P, PINS, T>(self, _pins: PINS, freq: T) -> PINS::Channels
387-
where
388-
PINS: Pins<crate::pac::$TIMX, P>,
389-
T: Into<Hertz>,
390-
{
391-
if PINS::C1 {
392-
self.tim.ccmr1_output()
393-
.modify(|_, w| w.oc1pe().set_bit().oc1m().pwm_mode1() );
394-
}
395-
if PINS::C2 {
396-
self.tim.ccmr1_output()
397-
.modify(|_, w| w.oc2pe().set_bit().oc2m().pwm_mode1() );
398-
}
399-
if PINS::C3 {
400-
self.tim.ccmr2_output()
401-
.modify(|_, w| w.oc3pe().set_bit().oc3m().pwm_mode1() );
402-
}
403-
if PINS::C4 {
404-
self.tim.ccmr2_output()
405-
.modify(|_, w| w.oc4pe().set_bit().oc4m().pwm_mode1() );
406-
}
407-
408-
// The reference manual is a bit ambiguous about when enabling this bit is really
409-
// necessary, but since we MUST enable the preload for the output channels then we
410-
// might as well enable for the auto-reload too
411-
self.tim.cr1.modify(|_, w| w.arpe().set_bit());
412-
413-
let ticks = self.clk.0 / freq.into().0;
414-
let psc = (ticks - 1) / (1 << 16);
415-
self.tim.psc.write(|w| w.psc().bits(u16(psc).unwrap()) );
416-
let arr = u16(ticks / (psc + 1)).unwrap();
417-
self.tim.arr.write(|w| unsafe { w.arr_l().bits(arr) });
418-
419-
// Trigger update event to load the registers
420-
self.tim.cr1.modify(|_, w| w.urs().set_bit());
421-
self.tim.egr.write(|w| w.ug().set_bit());
422-
self.tim.cr1.modify(|_, w| w.urs().clear_bit());
423-
424-
self.tim.cr1.write(|w|
425-
w.cms()
426-
.bits(0b00)
427-
.dir()
428-
.clear_bit()
429-
.opm()
430-
.clear_bit()
431-
.cen()
432-
.set_bit()
433-
);
434-
//NOTE(unsafe) `PINS::Channels` is a ZST
435-
unsafe { MaybeUninit::uninit().assume_init() }
436-
}
437-
}
438-
439-
pwm_pin_tim5!(crate::pac::$TIMX, C1, ccr1, 0);
440-
pwm_pin_tim5!(crate::pac::$TIMX, C2, ccr2, 4);
441-
pwm_pin_tim5!(crate::pac::$TIMX, C3, ccr3, 8);
442-
pwm_pin_tim5!(crate::pac::$TIMX, C4, ccr4, 12);
443-
)+
444-
};
445-
}
446-
447-
pwm_all_channels!(TIM1,);
319+
pwm_all_channels!(TIM1, TIM5,);
448320

449321
pwm_2_channels!(TIM9,);
450322

@@ -468,7 +340,7 @@ pwm_1_channel!(TIM11,);
468340
feature = "stm32f469",
469341
feature = "stm32f479"
470342
))]
471-
pwm_all_channels!(TIM2, TIM3, TIM4, TIM5,);
343+
pwm_all_channels!(TIM2, TIM3, TIM4,);
472344

473345
#[cfg(any(
474346
feature = "stm32f401",
@@ -543,6 +415,3 @@ pwm_2_channels!(TIM12,);
543415
feature = "stm32f479"
544416
))]
545417
pwm_1_channel!(TIM13, TIM14,);
546-
547-
#[cfg(feature = "stm32f410")]
548-
pwm_tim5_f410!(TIM5,);

0 commit comments

Comments
 (0)