Skip to content

Commit c7a52a5

Browse files
committed
opm refactoring
1 parent 9dd132d commit c7a52a5

File tree

2 files changed

+104
-84
lines changed

2 files changed

+104
-84
lines changed

examples/opm.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ use hal::prelude::*;
1515
use hal::rcc;
1616
use hal::stm32;
1717
use hal::timer::opm::Opm;
18-
use hal::timer::Channel1;
1918
use rtic::app;
2019

2120
#[app(device = hal::stm32, peripherals = true)]
2221
const APP: () = {
2322
struct Resources {
2423
exti: stm32::EXTI,
2524
led: PA5<Output<PushPull>>,
26-
opm: Opm<stm32::TIM14, Channel1>,
25+
opm: Opm<stm32::TIM3>,
2726
}
2827

2928
#[init]
@@ -32,13 +31,28 @@ const APP: () = {
3231
let mut exti = ctx.device.EXTI;
3332

3433
let gpioa = ctx.device.GPIOA.split(&mut rcc);
34+
let gpiob = ctx.device.GPIOB.split(&mut rcc);
3535
let gpioc = ctx.device.GPIOC.split(&mut rcc);
3636

3737
let led = gpioa.pa5.into_push_pull_output();
3838
gpioc.pc13.listen(SignalEdge::Falling, &mut exti);
3939

40-
let mut opm = ctx.device.TIM14.opm(gpioa.pa4, 5.ms(), &mut rcc);
41-
opm.enable();
40+
let opm = ctx.device.TIM3.opm(4.ms(), &mut rcc);
41+
42+
let mut opm_ch1 = opm.bind_pin(gpioa.pa6);
43+
opm_ch1.enable();
44+
45+
let mut opm_ch2 = opm.bind_pin(gpioa.pa7);
46+
opm_ch2.set_delay(1.ms());
47+
opm_ch2.enable();
48+
49+
let mut opm_ch3 = opm.bind_pin(gpiob.pb0);
50+
opm_ch3.set_delay(2.ms());
51+
opm_ch3.enable();
52+
53+
let mut opm_ch4 = opm.bind_pin(gpiob.pb1);
54+
opm_ch4.set_delay(3.ms());
55+
opm_ch4.enable();
4256

4357
init::LateResources { opm, exti, led }
4458
}

src/timer/opm.rs

Lines changed: 86 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,72 @@ use crate::timer::*;
88
use core::marker::PhantomData;
99

1010
pub trait OpmExt: Sized {
11-
fn opm<PIN>(self, _: PIN, pulse_width: MicroSecond, rcc: &mut Rcc) -> Opm<Self, PIN::Channel>
12-
where
13-
PIN: TimerPin<Self>;
11+
fn opm(self, period: MicroSecond, rcc: &mut Rcc) -> Opm<Self>;
1412
}
1513

16-
pub struct Opm<TIM, CHANNEL> {
17-
rb: TIM,
14+
pub struct OpmPin<TIM, CH> {
15+
tim: PhantomData<TIM>,
16+
channel: PhantomData<CH>,
1817
clk: Hertz,
19-
pulse_width: MicroSecond,
2018
delay: MicroSecond,
21-
_channel: PhantomData<CHANNEL>,
19+
}
20+
21+
pub struct Opm<TIM> {
22+
tim: PhantomData<TIM>,
23+
clk: Hertz,
24+
}
25+
26+
impl<TIM> Opm<TIM> {
27+
pub fn bind_pin<PIN>(&self, pin: PIN) -> OpmPin<TIM, PIN::Channel>
28+
where
29+
PIN: TimerPin<TIM>,
30+
{
31+
pin.setup();
32+
OpmPin {
33+
tim: PhantomData,
34+
channel: PhantomData,
35+
clk: self.clk,
36+
delay: 0.ms(),
37+
}
38+
}
2239
}
2340

2441
macro_rules! opm {
25-
($($TIMX:ident: ($apbXenr:ident, $apbXrstr:ident, $timX:ident, $timXen:ident, $timXrst:ident),)+) => {
42+
($($TIMX:ident: ($apbXenr:ident, $apbXrstr:ident, $timX:ident, $timXen:ident, $timXrst:ident, $arr:ident $(,$arr_h:ident)*),)+) => {
2643
$(
2744
impl OpmExt for $TIMX {
28-
fn opm<PIN>(self, pin: PIN, pulse_width: MicroSecond, rcc: &mut Rcc) -> Opm<Self, PIN::Channel>
29-
where
30-
PIN: TimerPin<Self>
31-
{
32-
$timX(self, pin, pulse_width, rcc)
45+
fn opm(self, period: MicroSecond, rcc: &mut Rcc) -> Opm<Self> {
46+
$timX(self, period, rcc)
3347
}
3448
}
3549

36-
fn $timX<PIN>(tim: $TIMX, pin: PIN, pulse_width: MicroSecond, rcc: &mut Rcc) -> Opm<$TIMX, PIN::Channel>
37-
where
38-
PIN: TimerPin<$TIMX>,
39-
{
50+
fn $timX(tim: $TIMX, period: MicroSecond, rcc: &mut Rcc) -> Opm<$TIMX> {
4051
rcc.rb.$apbXenr.modify(|_, w| w.$timXen().set_bit());
4152
rcc.rb.$apbXrstr.modify(|_, w| w.$timXrst().set_bit());
4253
rcc.rb.$apbXrstr.modify(|_, w| w.$timXrst().clear_bit());
43-
pin.setup();
54+
55+
let cycles_per_period = rcc.clocks.apb_tim_clk / period.into();
56+
let psc = (cycles_per_period - 1) / 0xffff;
57+
tim.psc.write(|w| unsafe { w.psc().bits(psc as u16) });
58+
59+
let freq = (rcc.clocks.apb_tim_clk.0 / (psc + 1)).hz();
60+
let reload = period.cycles(freq);
61+
unsafe {
62+
tim.arr.write(|w| w.$arr().bits(reload as u16));
63+
$(
64+
tim.arr.modify(|_, w| w.$arr_h().bits((reload >> 16) as u16));
65+
)*
66+
}
4467
Opm {
45-
rb: tim,
46-
clk: rcc.clocks.apb_tim_clk,
47-
pulse_width,
48-
delay: 0.us(),
49-
_channel: PhantomData,
68+
clk: freq,
69+
tim: PhantomData,
70+
}
71+
}
72+
73+
impl Opm<$TIMX> {
74+
pub fn generate(&mut self) {
75+
let tim = unsafe {&*$TIMX::ptr()};
76+
tim.cr1.write(|w| w.opm().set_bit().cen().set_bit());
5077
}
5178
}
5279
)+
@@ -55,60 +82,39 @@ macro_rules! opm {
5582

5683
macro_rules! opm_hal {
5784
($($TIMX:ident:
58-
($CH:ty, $ccxe:ident, $ccmrx_output:ident, $ocxm:ident, $ocxfe:ident, $ccrx:ident, $arr:ident $(,$arr_h:ident)*),)+
85+
($CH:ty, $ccxe:ident, $ccmrx_output:ident, $ocxm:ident, $ocxfe:ident, $ccrx:ident),)+
5986
) => {
6087
$(
61-
impl Opm<$TIMX, $CH> {
62-
pub fn enable (&mut self) {
63-
self.rb.ccer.modify(|_, w| w.$ccxe().set_bit());
88+
impl OpmPin<$TIMX, $CH> {
89+
pub fn enable(&mut self) {
90+
let tim = unsafe {&*$TIMX::ptr()};
91+
tim.ccer.modify(|_, w| w.$ccxe().set_bit());
6492
self.setup();
6593
}
6694

67-
pub fn disable (&mut self) {
68-
self.rb.ccer.modify(|_, w| w.$ccxe().clear_bit());
95+
pub fn disable(&mut self) {
96+
let tim = unsafe {&*$TIMX::ptr()};
97+
tim.ccer.modify(|_, w| w.$ccxe().clear_bit());
6998
}
7099

71-
pub fn generate(&mut self) {
72-
self.rb.cr1.write(|w| w.opm().set_bit().cen().set_bit());
73-
}
74-
75-
pub fn set_pulse_width<T> (&mut self, pulse_width: T)
76-
where
77-
T: Into<MicroSecond>
78-
{
79-
self.pulse_width = pulse_width.into();
80-
self.setup();
81-
}
82-
83-
pub fn set_delay<T> (&mut self, delay: T)
100+
pub fn set_delay<T>(&mut self, delay: T)
84101
where
85102
T: Into<MicroSecond>
86103
{
87104
self.delay = delay.into();
88105
self.setup();
89106
}
90107

91-
fn setup (&mut self) {
92-
let period = self.pulse_width + self.delay;
93-
94-
let cycles_per_period = self.clk / period.into();
95-
let psc = (cycles_per_period - 1) / 0xffff;
96-
97-
self.rb.psc.write(|w| unsafe { w.psc().bits(psc as u16) });
98-
let freq = (self.clk.0 / (psc + 1)).hz();
99-
let reload = cycles_per_period / (psc + 1);
108+
fn setup(&mut self) {
109+
let tim = unsafe {&*$TIMX::ptr()};
100110
let compare = if self.delay.0 > 0 {
101-
self.delay.cycles(freq)
111+
self.delay.cycles(self.clk)
102112
} else {
103113
1
104114
};
105115
unsafe {
106-
self.rb.arr.write(|w| w.$arr().bits(reload as u16));
107-
self.rb.$ccrx.write(|w| w.bits(compare));
108-
$(
109-
self.rb.arr.modify(|_, w| w.$arr_h().bits((reload >> 16) as u16));
110-
)*
111-
self.rb.$ccmrx_output().modify(|_, w| w.$ocxm().bits(7).$ocxfe().set_bit());
116+
tim.$ccrx.write(|w| w.bits(compare));
117+
tim.$ccmrx_output().modify(|_, w| w.$ocxm().bits(7).$ocxfe().set_bit());
112118
}
113119
}
114120
}
@@ -117,41 +123,41 @@ macro_rules! opm_hal {
117123
}
118124

119125
opm_hal! {
120-
TIM1: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr),
121-
TIM1: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr),
122-
TIM1: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr),
123-
TIM1: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr),
124-
TIM3: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr_l, arr_h),
125-
TIM3: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr_l, arr_h),
126-
TIM3: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr_l, arr_h),
127-
TIM3: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr_l, arr_h),
128-
TIM14: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr),
129-
TIM16: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr),
130-
TIM17: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr),
126+
TIM1: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
127+
TIM1: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2),
128+
TIM1: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3),
129+
TIM1: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4),
130+
TIM3: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
131+
TIM3: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2),
132+
TIM3: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3),
133+
TIM3: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4),
134+
TIM14: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
135+
TIM16: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
136+
TIM17: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
131137
}
132138

133139
#[cfg(feature = "stm32g0x1")]
134140
opm_hal! {
135-
TIM2: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr_l, arr_h),
136-
TIM2: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr_l, arr_h),
137-
TIM2: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr_l, arr_h),
138-
TIM2: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr_l, arr_h),
141+
TIM2: (Channel1, cc1e, ccmr1_output, oc1m, oc1fe, ccr1),
142+
TIM2: (Channel2, cc2e, ccmr1_output, oc2m, oc2fe, ccr2),
143+
TIM2: (Channel3, cc3e, ccmr2_output, oc3m, oc3fe, ccr3),
144+
TIM2: (Channel4, cc4e, ccmr2_output, oc4m, oc4fe, ccr4),
139145
}
140146

141147
opm! {
142-
TIM1: (apbenr2, apbrstr2, tim1, tim1en, tim1rst),
143-
TIM3: (apbenr1, apbrstr1, tim3, tim3en, tim3rst),
144-
TIM14: (apbenr2, apbrstr2, tim14, tim14en, tim14rst),
145-
TIM16: (apbenr2, apbrstr2, tim16, tim16en, tim16rst),
146-
TIM17: (apbenr2, apbrstr2, tim17, tim17en, tim17rst),
148+
TIM1: (apbenr2, apbrstr2, tim1, tim1en, tim1rst, arr),
149+
TIM3: (apbenr1, apbrstr1, tim3, tim3en, tim3rst, arr_l, arr_h),
150+
TIM14: (apbenr2, apbrstr2, tim14, tim14en, tim14rst, arr),
151+
TIM16: (apbenr2, apbrstr2, tim16, tim16en, tim16rst, arr),
152+
TIM17: (apbenr2, apbrstr2, tim17, tim17en, tim17rst, arr),
147153
}
148154

149155
#[cfg(feature = "stm32g0x1")]
150156
opm! {
151-
TIM2: (apbenr1, apbrstr1, tim2, tim2en, tim2rst),
157+
TIM2: (apbenr1, apbrstr1, tim2, tim2en, tim2rst, arr_l, arr_h),
152158
}
153159

154160
#[cfg(any(feature = "stm32g070", feature = "stm32g071", feature = "stm32g081"))]
155161
opm! {
156-
TIM15: (apbenr2, apbrstr2, tim15, tim15en, tim15rst),
162+
TIM15: (apbenr2, apbrstr2, tim15, tim15en, tim15rst, arr),
157163
}

0 commit comments

Comments
 (0)