Skip to content

Commit 26a531a

Browse files
authored
Merge pull request #302 from burrbull/frequency
BusClock
2 parents ae12718 + d3af40e commit 26a531a

File tree

5 files changed

+204
-289
lines changed

5 files changed

+204
-289
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616

1717
### Added
1818

19+
- `BusClock` and `BusTimerClock` traits ([#302])
20+
- `RccBus`, `Enable`, `Reset` traits and implementations for peripherals ([#299])
1921
- Support cortex-m-rt `v0.7.0` but still allow `v0.6.13` ([#283])
2022

2123
### Fixed
@@ -500,6 +502,8 @@ let clocks = rcc
500502
[defmt]: https://github.com/knurling-rs/defmt
501503
[filter]: https://defmt.ferrous-systems.com/filtering.html
502504

505+
[#302]: https://github.com/stm32-rs/stm32f3xx-hal/pull/302
506+
[#299]: https://github.com/stm32-rs/stm32f3xx-hal/pull/299
503507
[#291]: https://github.com/stm32-rs/stm32f3xx-hal/pull/291
504508
[#283]: https://github.com/stm32-rs/stm32f3xx-hal/pull/283
505509
[#282]: https://github.com/stm32-rs/stm32f3xx-hal/pull/282

src/rcc.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,67 @@ pub trait Reset: RccBus {
226226
unsafe fn reset_unchecked();
227227
}
228228

229+
/// Frequency on bus that peripheral is connected in
230+
pub trait BusClock {
231+
/// Calculates frequency depending on `Clock` state
232+
fn clock(clocks: &Clocks) -> Hertz;
233+
}
234+
235+
impl<T> BusClock for T
236+
where
237+
T: RccBus,
238+
T::Bus: BusClock,
239+
{
240+
fn clock(clocks: &Clocks) -> Hertz {
241+
T::Bus::clock(clocks)
242+
}
243+
}
244+
245+
impl BusClock for AHB {
246+
fn clock(clocks: &Clocks) -> Hertz {
247+
clocks.hclk
248+
}
249+
}
250+
impl BusClock for APB1 {
251+
fn clock(clocks: &Clocks) -> Hertz {
252+
clocks.pclk1
253+
}
254+
}
255+
impl BusClock for APB2 {
256+
fn clock(clocks: &Clocks) -> Hertz {
257+
clocks.pclk2
258+
}
259+
}
260+
261+
/// Frequency on bus that timer is connected in
262+
pub trait BusTimerClock {
263+
/// Calculates base frequency of timer depending on `Clock` state
264+
fn timer_clock(clocks: &Clocks) -> Hertz;
265+
}
266+
267+
impl<T> BusTimerClock for T
268+
where
269+
T: RccBus,
270+
T::Bus: BusTimerClock,
271+
{
272+
fn timer_clock(clocks: &Clocks) -> Hertz {
273+
T::Bus::timer_clock(clocks)
274+
}
275+
}
276+
277+
impl BusTimerClock for APB1 {
278+
fn timer_clock(clocks: &Clocks) -> Hertz {
279+
let pclk_mul = if clocks.ppre1 > 1 { 2 } else { 1 };
280+
Hertz(clocks.pclk1.0 * pclk_mul)
281+
}
282+
}
283+
impl BusTimerClock for APB2 {
284+
fn timer_clock(clocks: &Clocks) -> Hertz {
285+
let pclk_mul = if clocks.ppre2 > 1 { 2 } else { 1 };
286+
Hertz(clocks.pclk2.0 * pclk_mul)
287+
}
288+
}
289+
229290
/// Frequency of interal hardware RC oscillator (HSI OSC)
230291
pub const HSI: Hertz = Hertz(8_000_000);
231292
/// Frequency of external 32.768 kHz oscillator (LSE OSC)

src/serial.rs

Lines changed: 37 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,13 +1195,7 @@ pub trait Instance:
11951195
macro_rules! usart {
11961196
(
11971197
$(
1198-
$USARTX:ident: (
1199-
$usartXen:ident,
1200-
$INTERRUPT:path,
1201-
$pclkX:ident,
1202-
$usartXsw:ident,
1203-
$usartXclock:ident
1204-
),
1198+
$USARTX:ident: ($INTERRUPT:path),
12051199
)+
12061200
) => {
12071201
$(
@@ -1210,16 +1204,6 @@ macro_rules! usart {
12101204
const INTERRUPT: Interrupt = $INTERRUPT;
12111205
}
12121206

1213-
impl Instance for $USARTX {
1214-
fn clock(clocks: &Clocks) -> Hertz {
1215-
// Use the function created via another macro outside of this one,
1216-
// because the implementation is dependend on the type $USARTX.
1217-
// But macros can not differentiate between types.
1218-
$usartXclock(clocks)
1219-
}
1220-
}
1221-
1222-
12231207
impl<Tx, Rx> Serial<$USARTX, (Tx, Rx)>
12241208
where Tx: TxPin<$USARTX>, Rx: RxPin<$USARTX> {
12251209
/// Splits the [`Serial`] abstraction into a transmitter and a receiver half.
@@ -1275,17 +1259,11 @@ macro_rules! usart {
12751259
)+
12761260
};
12771261

1278-
([ $(($X:literal, $APB:literal, $INTERRUPT:path)),+ ]) => {
1262+
([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
12791263
paste::paste! {
12801264
usart!(
12811265
$(
1282-
[<USART $X>]: (
1283-
[<usart $X en>],
1284-
$INTERRUPT,
1285-
[<pclk $APB>],
1286-
[<usart $X sw>],
1287-
[<usart $X clock>]
1288-
),
1266+
[<USART $X>]: ($INTERRUPT),
12891267
)+
12901268
);
12911269
}
@@ -1296,19 +1274,19 @@ macro_rules! usart {
12961274
/// the only clock source can be the peripheral clock
12971275
#[allow(unused_macros)]
12981276
macro_rules! usart_static_clock {
1299-
($($usartXclock:ident, $pclkX:ident),+) => {
1277+
($($USARTX:ident),+) => {
13001278
$(
1301-
/// Return the currently set source frequency the UART peripheral
1302-
/// depending on the clock source.
1303-
fn $usartXclock(clocks: &Clocks) -> Hertz {
1304-
clocks.$pclkX()
1279+
impl Instance for $USARTX {
1280+
fn clock(clocks: &Clocks) -> Hertz {
1281+
<$USARTX as rcc::BusClock>::clock(clocks)
1282+
}
13051283
}
13061284
)+
13071285
};
1308-
([ $(($X:literal, $APB:literal)),+ ]) => {
1286+
($($X:literal),+) => {
13091287
paste::paste! {
13101288
usart_static_clock!(
1311-
$([<usart $X clock>], [<pclk $APB>]),+
1289+
$([<USART $X>]),+
13121290
);
13131291
}
13141292
};
@@ -1317,25 +1295,25 @@ macro_rules! usart_static_clock {
13171295
/// Generates a clock function for UART Peripherals, where
13181296
/// the clock source can vary.
13191297
macro_rules! usart_var_clock {
1320-
($($usartXclock:ident, $usartXsw:ident, $pclkX:ident),+) => {
1298+
($($USARTX:ident, $usartXsw:ident),+) => {
13211299
$(
1322-
/// Return the currently set source frequency for the UART peripheral
1323-
/// depending on the clock source.
1324-
fn $usartXclock(clocks: &Clocks) -> Hertz {
1325-
// NOTE(unsafe): atomic read with no side effects
1326-
match unsafe {(*RCC::ptr()).cfgr3.read().$usartXsw().variant()} {
1327-
USART1SW_A::PCLK => clocks.$pclkX(),
1328-
USART1SW_A::HSI => crate::rcc::HSI,
1329-
USART1SW_A::SYSCLK => clocks.sysclk(),
1330-
USART1SW_A::LSE => crate::rcc::LSE,
1300+
impl Instance for $USARTX {
1301+
fn clock(clocks: &Clocks) -> Hertz {
1302+
// NOTE(unsafe): atomic read with no side effects
1303+
match unsafe {(*RCC::ptr()).cfgr3.read().$usartXsw().variant()} {
1304+
USART1SW_A::PCLK => <$USARTX as rcc::BusClock>::clock(clocks),
1305+
USART1SW_A::HSI => crate::rcc::HSI,
1306+
USART1SW_A::SYSCLK => clocks.sysclk(),
1307+
USART1SW_A::LSE => crate::rcc::LSE,
1308+
}
13311309
}
13321310
}
13331311
)+
13341312
};
1335-
([ $(($X:literal, $APB:literal)),+ ]) => {
1313+
($($X:literal),+) => {
13361314
paste::paste! {
13371315
usart_var_clock!(
1338-
$([<usart $X clock>], [<usart $X sw>], [<pclk $APB>]),+
1316+
$([<USART $X>], [<usart $X sw>]),+
13391317
);
13401318
}
13411319
};
@@ -1357,62 +1335,56 @@ cfg_if::cfg_if! {
13571335
))] {
13581336
// USART1 is accessed through APB2,
13591337
// but USART1SW_A::PCLK will connect its phy to PCLK1.
1360-
usart_var_clock!([(1,1)]);
1338+
usart_var_clock!(1);
13611339
// These are uart peripherals, where the only clock source
13621340
// is the PCLK (peripheral clock).
1363-
usart_static_clock!([(2,1), (3,1)]);
1341+
usart_static_clock!(2, 3);
13641342
} else {
1365-
usart_var_clock!([(1, 2), (2, 1), (3, 1)]);
1343+
usart_var_clock!(1, 2, 3);
13661344
}
13671345
}
13681346

13691347
#[cfg(not(feature = "svd-f373"))]
13701348
usart!([
1371-
(1, 2, Interrupt::USART1_EXTI25),
1372-
(2, 1, Interrupt::USART2_EXTI26),
1373-
(3, 1, Interrupt::USART3_EXTI28)
1349+
(1, Interrupt::USART1_EXTI25),
1350+
(2, Interrupt::USART2_EXTI26),
1351+
(3, Interrupt::USART3_EXTI28)
13741352
]);
13751353
#[cfg(feature = "svd-f373")]
13761354
usart!([
1377-
(1, 2, Interrupt::USART1),
1378-
(2, 1, Interrupt::USART2),
1379-
(3, 1, Interrupt::USART3)
1355+
(1, Interrupt::USART1),
1356+
(2, Interrupt::USART2),
1357+
(3, Interrupt::USART3)
13801358
]);
13811359

13821360
cfg_if::cfg_if! {
13831361
// See table 29.4 RM0316
13841362
if #[cfg(any(feature = "gpio-f303", feature = "gpio-f303e"))] {
13851363

13861364
macro_rules! uart {
1387-
([ $(($X:literal, $APB:literal, $INTERRUPT:path)),+ ]) => {
1365+
([ $(($X:literal, $INTERRUPT:path)),+ ]) => {
13881366
paste::paste! {
13891367
usart!(
13901368
$(
1391-
[<UART $X>]: (
1392-
[<uart $X en>],
1393-
$INTERRUPT,
1394-
[<pclk $APB>],
1395-
[<uart $X sw>],
1396-
[<usart $X clock>]
1397-
),
1369+
[<UART $X>]: ($INTERRUPT),
13981370
)+
13991371
);
14001372
}
14011373
};
14021374
}
14031375

14041376
macro_rules! uart_var_clock {
1405-
([ $(($X:literal, $APB:literal)),+ ]) => {
1377+
($($X:literal),+) => {
14061378
paste::paste! {
14071379
usart_var_clock!(
1408-
$([<usart $X clock>], [<uart $X sw>], [<pclk $APB>]),+
1380+
$([<UART $X>], [<uart $X sw>]),+
14091381
);
14101382
}
14111383
};
14121384
}
14131385

1414-
uart_var_clock!([(4,1), (5,1)]);
1415-
uart!([(4,1, Interrupt::UART4_EXTI34), (5,1, Interrupt::UART5_EXTI35)]);
1386+
uart_var_clock!(4, 5);
1387+
uart!([(4, Interrupt::UART4_EXTI34), (5, Interrupt::UART5_EXTI35)]);
14161388

14171389
impl Dma for UART4 {}
14181390

src/spi.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::pac::{
2222
use crate::{
2323
gpio::{self, PushPull, AF5, AF6},
2424
rcc::{self, Clocks},
25-
time::rate::{self, Hertz},
25+
time::rate,
2626
};
2727

2828
/// SPI error
@@ -401,9 +401,8 @@ pub trait Instance:
401401
+ crate::private::Sealed
402402
+ rcc::Enable
403403
+ rcc::Reset
404+
+ rcc::BusClock
404405
{
405-
#[doc(hidden)]
406-
fn clock(clocks: &Clocks) -> Hertz;
407406
}
408407

409408
macro_rules! spi {
@@ -414,11 +413,7 @@ macro_rules! spi {
414413
const INTERRUPT: Self::Interrupt = interrupts::$SPIX;
415414
}
416415

417-
impl Instance for pac::$SPIX {
418-
fn clock(clocks: &Clocks) -> Hertz {
419-
clocks.$pclkX()
420-
}
421-
}
416+
impl Instance for pac::$SPIX { }
422417

423418
#[cfg(feature = "defmt")]
424419
impl<Pins> defmt::Format for Spi<pac::$SPIX, Pins> {

0 commit comments

Comments
 (0)