Skip to content

Commit e6286a5

Browse files
committed
BusClock
1 parent 1cbe88d commit e6286a5

File tree

7 files changed

+187
-122
lines changed

7 files changed

+187
-122
lines changed

src/i2c.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use crate::hal::blocking::i2c::{Read, Write, WriteRead};
66
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2", feature = "stm32l4x6"))]
77
use crate::pac::I2C4;
88
use crate::pac::{i2c1, I2C1, I2C2, I2C3};
9-
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2", feature = "stm32l4x6"))]
10-
use crate::rcc::APB1R2;
119

1210
use crate::rcc::{Clocks, Enable, RccBus, Reset};
1311
use crate::time::Hertz;

src/prelude.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ pub use crate::dma::DmaExt as _stm32l4_hal_DmaExt;
99
pub use crate::flash::FlashExt as _stm32l4_hal_FlashExt;
1010
pub use crate::gpio::ExtiPin as _stm32l4_hal_ExtiPin;
1111
pub use crate::gpio::GpioExt as _stm32l4_hal_GpioExt;
12-
pub use crate::pwm::PwmExt1 as _stm32l4_hal_PwmExt1;
13-
pub use crate::pwm::PwmExt2 as _stm32l4_hal_PwmExt2;
12+
pub use crate::pwm::PwmExt as _stm32l4_hal_PwmExt;
1413
pub use crate::pwr::PwrExt as _stm32l4_hal_PwrExt;
1514
pub use crate::rcc::RccExt as _stm32l4_hal_RccExt;
1615
pub use crate::rng::RngExt as _stm32l4_hal_RngExt;

src/pwm.rs

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::stm32::{TIM1, TIM15, TIM2};
99
use crate::gpio::gpioa::{PA0, PA1, PA10, PA11, PA15, PA2, PA3, PA8, PA9};
1010
use crate::gpio::gpiob::{PB10, PB11, PB14, PB3};
1111
use crate::gpio::Alternate;
12-
use crate::rcc::{Clocks, Enable, Reset, APB1R1, APB2};
12+
use crate::rcc::{BusTimerClock, Clocks, Enable, RccBus, Reset};
1313
use crate::time::Hertz;
1414

1515
// NB: REMAP is not implemented!
@@ -103,28 +103,27 @@ pins_to_channels_mapping! {
103103
// TIM15: (PA2, PA3), (C1, C2), (14, 14);
104104
}
105105

106-
pub trait PwmExt1: Sized {
107-
fn pwm<PINS, T>(self, _: PINS, frequency: T, clocks: Clocks, apb: &mut APB2) -> PINS::Channels
108-
where
109-
PINS: Pins<Self>,
110-
T: Into<Hertz>;
111-
}
112-
113-
pub trait PwmExt2: Sized {
106+
pub trait PwmExt: Sized + RccBus {
114107
fn pwm<PINS, T>(
115108
self,
116109
_: PINS,
117110
frequency: T,
118111
clocks: Clocks,
119-
apb: &mut APB1R1,
112+
apb: &mut Self::Bus,
120113
) -> PINS::Channels
121114
where
122115
PINS: Pins<Self>,
123116
T: Into<Hertz>;
124117
}
125118

126-
impl PwmExt1 for TIM1 {
127-
fn pwm<PINS, T>(self, _pins: PINS, freq: T, clocks: Clocks, apb: &mut APB2) -> PINS::Channels
119+
impl PwmExt for TIM1 {
120+
fn pwm<PINS, T>(
121+
self,
122+
_pins: PINS,
123+
freq: T,
124+
clocks: Clocks,
125+
apb: &mut Self::Bus,
126+
) -> PINS::Channels
128127
where
129128
PINS: Pins<Self>,
130129
T: Into<Hertz>,
@@ -133,8 +132,14 @@ impl PwmExt1 for TIM1 {
133132
}
134133
}
135134

136-
impl PwmExt1 for TIM15 {
137-
fn pwm<PINS, T>(self, _pins: PINS, freq: T, clocks: Clocks, apb: &mut APB2) -> PINS::Channels
135+
impl PwmExt for TIM15 {
136+
fn pwm<PINS, T>(
137+
self,
138+
_pins: PINS,
139+
freq: T,
140+
clocks: Clocks,
141+
apb: &mut Self::Bus,
142+
) -> PINS::Channels
138143
where
139144
PINS: Pins<Self>,
140145
T: Into<Hertz>,
@@ -143,8 +148,14 @@ impl PwmExt1 for TIM15 {
143148
}
144149
}
145150

146-
impl PwmExt2 for TIM2 {
147-
fn pwm<PINS, T>(self, _pins: PINS, freq: T, clocks: Clocks, apb: &mut APB1R1) -> PINS::Channels
151+
impl PwmExt for TIM2 {
152+
fn pwm<PINS, T>(
153+
self,
154+
_pins: PINS,
155+
freq: T,
156+
clocks: Clocks,
157+
apb: &mut Self::Bus,
158+
) -> PINS::Channels
148159
where
149160
PINS: Pins<Self>,
150161
T: Into<Hertz>,
@@ -170,14 +181,14 @@ pub struct C3;
170181
pub struct C4;
171182

172183
macro_rules! advanced_timer {
173-
($($TIMX:ident: ($timX:ident, $apb:ident, $psc_width:ident, $arr_width:ident),)+) => {
184+
($($TIMX:ident: ($timX:ident, $psc_width:ident, $arr_width:ident),)+) => {
174185
$(
175186
fn $timX<PINS>(
176187
tim: $TIMX,
177188
_pins: PINS,
178189
freq: Hertz,
179190
clocks: Clocks,
180-
apb: &mut $apb,
191+
apb: &mut <$TIMX as RccBus>::Bus,
181192
) -> PINS::Channels
182193
where
183194
PINS: Pins<$TIMX>,
@@ -201,9 +212,8 @@ macro_rules! advanced_timer {
201212
tim.ccmr2_output().modify(|_, w| w.oc4pe().set_bit().oc4m().bits(6));
202213
}
203214

204-
let clk = clocks.pclk2().0;
205-
let freq = freq.0;
206-
let ticks = clk / freq;
215+
let clk = <$TIMX as BusTimerClock>::timer_clock(&clocks);
216+
let ticks = clk.0 / freq.0;
207217

208218
// maybe this is all u32? also, why no `- 1` vs `timer.rs`?
209219
let psc = ticks / (1 << 16);
@@ -239,14 +249,14 @@ macro_rules! advanced_timer {
239249
}
240250

241251
macro_rules! standard_timer {
242-
($($TIMX:ident: ($timX:ident, $apb:ident, $psc_width:ident, $arr_width:ident),)+) => {
252+
($($TIMX:ident: ($timX:ident, $psc_width:ident, $arr_width:ident),)+) => {
243253
$(
244254
fn $timX<PINS>(
245255
tim: $TIMX,
246256
_pins: PINS,
247257
freq: Hertz,
248258
clocks: Clocks,
249-
apb: &mut $apb,
259+
apb: &mut <$TIMX as RccBus>::Bus,
250260
) -> PINS::Channels
251261
where
252262
PINS: Pins<$TIMX>,
@@ -270,9 +280,8 @@ macro_rules! standard_timer {
270280
tim.ccmr2_output().modify(|_, w| w.oc4pe().set_bit().oc4m().bits(6));
271281
}
272282

273-
let clk = clocks.pclk1().0;
274-
let freq = freq.0;
275-
let ticks = clk / freq;
283+
let clk = <$TIMX as BusTimerClock>::timer_clock(&clocks);
284+
let ticks = clk.0 / freq.0;
276285

277286
// maybe this is all u32? also, why no `- 1` vs `timer.rs`?
278287
let psc = ticks / (1 << 16);
@@ -304,14 +313,14 @@ macro_rules! standard_timer {
304313
}
305314

306315
macro_rules! small_timer {
307-
($($TIMX:ident: ($timX:ident, $apb:ident, $psc_width:ident, $arr_width:ident),)+) => {
316+
($($TIMX:ident: ($timX:ident, $psc_width:ident, $arr_width:ident),)+) => {
308317
$(
309318
fn $timX<PINS>(
310319
tim: $TIMX,
311320
_pins: PINS,
312321
freq: Hertz,
313322
clocks: Clocks,
314-
apb: &mut $apb,
323+
apb: &mut <$TIMX as RccBus>::Bus,
315324
) -> PINS::Channels
316325
where
317326
PINS: Pins<$TIMX>,
@@ -328,9 +337,8 @@ macro_rules! small_timer {
328337
// tim.ccmr1_output().modify(|_, w| w.oc2pe().set_bit().oc2m().bits(6));
329338
// }
330339

331-
let clk = clocks.pclk1().0;
332-
let freq = freq.0;
333-
let ticks = clk / freq;
340+
let clk = <$TIMX as BusTimerClock>::timer_clock(&clocks);
341+
let ticks = clk.0 / freq.0;
334342

335343
// maybe this is all u32? also, why no `- 1` vs `timer.rs`?
336344
let psc = ticks / (1 << 16);
@@ -396,13 +404,13 @@ macro_rules! pwm_channels {
396404
}
397405

398406
advanced_timer! {
399-
TIM1: (tim1, APB2, u16, u16),
407+
TIM1: (tim1, u16, u16),
400408
}
401409

402410
standard_timer! {
403-
TIM2: (tim2, APB1R1, u16, u32),
411+
TIM2: (tim2, u16, u32),
404412
}
405413

406414
small_timer! {
407-
TIM15: (tim15, APB2, u16, u16),
415+
TIM15: (tim15, u16, u16),
408416
}

src/rcc.rs

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ impl BDCR {
184184
}
185185

186186
macro_rules! bus_struct {
187-
($($busX:ident => ($EN:ident, $en:ident, $SMEN:ident, $smen:ident, $RST:ident, $rst:ident, $doc:literal),)+) => {
187+
($($busX:ident => ($EN:ident, $en:ident, $SMEN:ident, $smen:ident, $RST:ident, $rst:ident, $clk:ident, $doc:literal),)+) => {
188188
$(
189189
#[doc = $doc]
190190
pub struct $busX {
@@ -214,17 +214,23 @@ macro_rules! bus_struct {
214214
unsafe { &(*RCC::ptr()).$rst }
215215
}
216216
}
217+
218+
impl BusClock for $busX {
219+
fn clock(clocks: &Clocks) -> Hertz {
220+
clocks.$clk
221+
}
222+
}
217223
)+
218224
};
219225
}
220226

221227
bus_struct! {
222-
AHB1 => (AHB1ENR, ahb1enr, AHB1SMENR, ahb1smenr, AHB1RSTR, ahb1rstr, "Advanced High-performance Bus 1 (AHB1) registers"),
223-
AHB2 => (AHB2ENR, ahb2enr, AHB2SMENR, ahb2smenr, AHB2RSTR, ahb2rstr, "Advanced High-performance Bus 2 (AHB2) registers"),
224-
AHB3 => (AHB3ENR, ahb3enr, AHB3SMENR, ahb3smenr, AHB3RSTR, ahb3rstr, "Advanced High-performance Bus 3 (AHB3) registers"),
225-
APB1R1 => (APB1ENR1, apb1enr1, APB1SMENR1, apb1smenr1, APB1RSTR1, apb1rstr1, "Advanced Peripheral Bus 1 (APB1) registers"),
226-
APB1R2 => (APB1ENR2, apb1enr2, APB1SMENR2, apb1smenr2, APB1RSTR2, apb1rstr2, "Advanced Peripheral Bus 1 (APB1) registers"),
227-
APB2 => (APB2ENR, apb2enr, APB2SMENR, apb2smenr, APB2RSTR, apb2rstr, "Advanced Peripheral Bus 2 (APB2) registers"),
228+
AHB1 => (AHB1ENR, ahb1enr, AHB1SMENR, ahb1smenr, AHB1RSTR, ahb1rstr, hclk, "Advanced High-performance Bus 1 (AHB1) registers"),
229+
AHB2 => (AHB2ENR, ahb2enr, AHB2SMENR, ahb2smenr, AHB2RSTR, ahb2rstr, hclk, "Advanced High-performance Bus 2 (AHB2) registers"),
230+
AHB3 => (AHB3ENR, ahb3enr, AHB3SMENR, ahb3smenr, AHB3RSTR, ahb3rstr, hclk, "Advanced High-performance Bus 3 (AHB3) registers"),
231+
APB1R1 => (APB1ENR1, apb1enr1, APB1SMENR1, apb1smenr1, APB1RSTR1, apb1rstr1, pclk1, "Advanced Peripheral Bus 1 (APB1) registers"),
232+
APB1R2 => (APB1ENR2, apb1enr2, APB1SMENR2, apb1smenr2, APB1RSTR2, apb1rstr2, pclk1, "Advanced Peripheral Bus 1 (APB1) registers"),
233+
APB2 => (APB2ENR, apb2enr, APB2SMENR, apb2smenr, APB2RSTR, apb2rstr, pclk2, "Advanced Peripheral Bus 2 (APB2) registers"),
228234
}
229235

230236
/// Bus associated to peripheral
@@ -294,6 +300,59 @@ pub trait Reset: RccBus {
294300
unsafe fn reset_unchecked();
295301
}
296302

303+
/// Frequency on bus that peripheral is connected in
304+
pub trait BusClock {
305+
/// Calculates frequency depending on `Clock` state
306+
fn clock(clocks: &Clocks) -> Hertz;
307+
}
308+
309+
impl<T> BusClock for T
310+
where
311+
T: RccBus,
312+
T::Bus: BusClock,
313+
{
314+
fn clock(clocks: &Clocks) -> Hertz {
315+
T::Bus::clock(clocks)
316+
}
317+
}
318+
319+
/// Frequency on bus that timer is connected in
320+
pub trait BusTimerClock {
321+
/// Calculates base frequency of timer depending on `Clock` state
322+
fn timer_clock(clocks: &Clocks) -> Hertz;
323+
}
324+
325+
impl<T> BusTimerClock for T
326+
where
327+
T: RccBus,
328+
T::Bus: BusTimerClock,
329+
{
330+
fn timer_clock(clocks: &Clocks) -> Hertz {
331+
T::Bus::timer_clock(clocks)
332+
}
333+
}
334+
335+
impl BusTimerClock for APB1R1 {
336+
fn timer_clock(clocks: &Clocks) -> Hertz {
337+
let pclk_mul = if clocks.ppre1 > 1 { 2 } else { 1 };
338+
Hertz(clocks.pclk1.0 * pclk_mul)
339+
}
340+
}
341+
342+
impl BusTimerClock for APB1R2 {
343+
fn timer_clock(clocks: &Clocks) -> Hertz {
344+
let pclk_mul = if clocks.ppre1 > 1 { 2 } else { 1 };
345+
Hertz(clocks.pclk1.0 * pclk_mul)
346+
}
347+
}
348+
349+
impl BusTimerClock for APB2 {
350+
fn timer_clock(clocks: &Clocks) -> Hertz {
351+
let pclk_mul = if clocks.ppre2 > 1 { 2 } else { 1 };
352+
Hertz(clocks.pclk2.0 * pclk_mul)
353+
}
354+
}
355+
297356
#[derive(Debug, PartialEq)]
298357
/// HSE Configuration
299358
struct HseConfig {

0 commit comments

Comments
 (0)