Skip to content

Commit 38bb75b

Browse files
committed
rcc: configure PLL3 for the rest of the H5 family
1 parent aa1959a commit 38bb75b

File tree

4 files changed

+145
-57
lines changed

4 files changed

+145
-57
lines changed

examples/fractional-pll.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ fn main() -> ! {
4545
info!("sys_ck = {} Hz", ccdr.clocks.sys_ck().raw());
4646
assert_eq!(ccdr.clocks.sys_ck().raw(), 250_000_000);
4747

48-
info!("pll2_p_ck = {}", ccdr.clocks.pll2_p_ck().unwrap());
49-
info!("pll2_q_ck = {}", ccdr.clocks.pll2_q_ck().unwrap());
50-
info!("pll2_r_ck = {}", ccdr.clocks.pll2_r_ck().unwrap());
48+
info!("pll2_p_ck = {}", ccdr.clocks.pll2().p_ck().unwrap());
49+
info!("pll2_q_ck = {}", ccdr.clocks.pll2().q_ck().unwrap());
50+
info!("pll2_r_ck = {}", ccdr.clocks.pll2().r_ck().unwrap());
5151

5252
let _mco2_ck = ccdr.clocks.mco2_ck().unwrap().raw();
5353

src/rcc.rs

+91-28
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,16 @@
133133

134134
use crate::pwr::PowerConfiguration;
135135
use crate::pwr::VoltageScale as Voltage;
136+
#[cfg(feature = "rm0481")]
137+
use crate::stm32::rcc::pll3cfgr::PLL3SRC;
136138
use crate::stm32::rcc::{
137139
ccipr5::CKPERSEL, cfgr1::SW, cfgr1::TIMPRE, cfgr2::HPRE,
138140
cfgr2::PPRE1 as PPRE, pll1cfgr::PLL1SRC, pll2cfgr::PLL2SRC,
139141
};
140142
use crate::stm32::{RCC, SBS};
141143
use crate::time::Hertz;
142144

145+
use core_clocks::PllClocks;
143146
#[cfg(feature = "log")]
144147
use log::debug;
145148

@@ -168,8 +171,6 @@ pub struct Config {
168171
rcc_pclk1: Option<u32>,
169172
rcc_pclk2: Option<u32>,
170173
rcc_pclk3: Option<u32>,
171-
#[cfg(feature = "rm0481")]
172-
rcc_pclk4: Option<u32>,
173174
mco1: MCO1Config,
174175
mco2: MCO2Config,
175176
pll1: PllConfig,
@@ -199,8 +200,6 @@ impl RccExt for RCC {
199200
rcc_pclk1: None,
200201
rcc_pclk2: None,
201202
rcc_pclk3: None,
202-
#[cfg(feature = "rm0481")]
203-
rcc_pclk4: None,
204203
mco1: MCO1Config::default(),
205204
mco2: MCO2Config::default(),
206205
pll1: PllConfig::default(),
@@ -376,11 +375,6 @@ impl Rcc {
376375
pclk3: rcc_pclk3,
377376
}
378377

379-
#[cfg(feature = "rm0481")]
380-
pclk_setter! {
381-
pclk4: rcc_pclk4,
382-
}
383-
384378
pll_setter! {
385379
pll1: [
386380
pll1_p_ck: p_ck,
@@ -394,10 +388,24 @@ impl Rcc {
394388
],
395389
}
396390

391+
#[cfg(feature = "rm0481")]
392+
pll_setter! {
393+
pll3: [
394+
pll3_p_ck: p_ck,
395+
pll3_q_ck: q_ck,
396+
pll3_r_ck: r_ck,
397+
],
398+
}
399+
397400
pll_strategy_setter! {
398401
pll1: pll1_strategy,
399402
pll2: pll2_strategy,
400403
}
404+
405+
#[cfg(feature = "rm0481")]
406+
pll_strategy_setter! {
407+
pll3: pll3_strategy,
408+
}
401409
}
402410

403411
/// Divider calculator for pclk 1 - 4
@@ -574,6 +582,10 @@ impl Rcc {
574582
let (pll2_p_ck, pll2_q_ck, pll2_r_ck) =
575583
self.pll2_setup(rcc, &self.config.pll2);
576584

585+
#[cfg(feature = "rm0481")]
586+
let (pll3_p_ck, pll3_q_ck, pll3_r_ck) =
587+
self.pll3_setup(rcc, &self.config.pll3);
588+
577589
let sys_ck = if sys_use_pll1_p {
578590
pll1_p_ck.unwrap() // Must have been set by sys_ck_setup
579591
} else {
@@ -718,6 +730,15 @@ impl Rcc {
718730
};
719731
rcc.pll1cfgr().modify(|_, w| w.pll1src().variant(pll1src));
720732
rcc.pll2cfgr().modify(|_, w| w.pll2src().variant(pll2src));
733+
#[cfg(feature = "rm0481")]
734+
{
735+
let pll3src = if self.config.hse.is_some() {
736+
PLL3SRC::Hse
737+
} else {
738+
PLL3SRC::Hsi
739+
};
740+
rcc.pll3cfgr().modify(|_, w| w.pll3src().variant(pll3src));
741+
}
721742

722743
// PLL1
723744
if pll1_p_ck.is_some() {
@@ -733,6 +754,14 @@ impl Rcc {
733754
while rcc.cr().read().pll2rdy().is_not_ready() {}
734755
}
735756

757+
// PLL3
758+
#[cfg(feature = "rm0481")]
759+
if pll3_p_ck.is_some() {
760+
// Enable PLL and wait for it to stabilise
761+
rcc.cr().modify(|_, w| w.pll3on().on());
762+
while rcc.cr().read().pll3rdy().is_not_ready() {}
763+
}
764+
736765
// Core Prescaler / AHB Prescaler / APBx Prescalers
737766
rcc.cfgr2().modify(|_, w| {
738767
w.hpre()
@@ -824,19 +853,6 @@ impl Rcc {
824853
pll1cfgr.pll1ren().variant(),
825854
);
826855

827-
let pll2cfgr = rcc.pll2cfgr().read();
828-
debug!(
829-
"PLL2CFGR register: PLL2SRC={:?} PLL2RGE={:?} PLL2FRACEN={:?} PLL2VCOSEL={:?} PLL2M={:#x} PLL2PEN={:?} PLL2QEN={:?} PLL2REN={:?}",
830-
pll2cfgr.pll2src().variant(),
831-
pll2cfgr.pll2rge().variant(),
832-
pll2cfgr.pll2fracen().variant(),
833-
pll2cfgr.pll2vcosel().variant(),
834-
pll2cfgr.pll2m().bits(),
835-
pll2cfgr.pll2pen().variant(),
836-
pll2cfgr.pll2qen().variant(),
837-
pll2cfgr.pll2ren().variant(),
838-
);
839-
840856
let pll1divr = rcc.pll1divr().read();
841857
debug!(
842858
"PLL1DIVR register: PLL1N={:#x} PLL1P={:#x} PLL1Q={:#x} PLL1R={:#x}",
@@ -852,6 +868,19 @@ impl Rcc {
852868
pll1fracr.pll1fracn().bits(),
853869
);
854870

871+
let pll2cfgr = rcc.pll2cfgr().read();
872+
debug!(
873+
"PLL2CFGR register: PLL2SRC={:?} PLL2RGE={:?} PLL2FRACEN={:?} PLL2VCOSEL={:?} PLL2M={:#x} PLL2PEN={:?} PLL2QEN={:?} PLL2REN={:?}",
874+
pll2cfgr.pll2src().variant(),
875+
pll2cfgr.pll2rge().variant(),
876+
pll2cfgr.pll2fracen().variant(),
877+
pll2cfgr.pll2vcosel().variant(),
878+
pll2cfgr.pll2m().bits(),
879+
pll2cfgr.pll2pen().variant(),
880+
pll2cfgr.pll2qen().variant(),
881+
pll2cfgr.pll2ren().variant(),
882+
);
883+
855884
let pll2divr = rcc.pll2divr().read();
856885
debug!(
857886
"PLL2DIVR register: PLL2N={:#x} PLL2P={:#x} PLL2Q={:#x} PLL2R={:#x}",
@@ -866,8 +895,44 @@ impl Rcc {
866895
"PLL2FRACR register: FRACN2={:#x}",
867896
pll2fracr.pll2fracn().bits(),
868897
);
898+
899+
#[cfg(feature = "rm0481")]
900+
{
901+
let pll3cfgr = rcc.pll3cfgr().read();
902+
debug!(
903+
"PLL3CFGR register: PLL3SRC={:?} PLL3RGE={:?} PLL3FRACEN={:?} PLL3VCOSEL={:?} PLL3M={:#x} PLL3PEN={:?} PLL3QEN={:?} PLL3REN={:?}",
904+
pll3cfgr.pll3src().variant(),
905+
pll3cfgr.pll3rge().variant(),
906+
pll3cfgr.pll3fracen().variant(),
907+
pll3cfgr.pll3vcosel().variant(),
908+
pll3cfgr.pll3m().bits(),
909+
pll3cfgr.pll3pen().variant(),
910+
pll3cfgr.pll3qen().variant(),
911+
pll3cfgr.pll3ren().variant(),
912+
);
913+
914+
let pll3divr = rcc.pll3divr().read();
915+
debug!(
916+
"PLL3DIVR register: PLL3N={:#x} PLL3P={:#x} PLL3Q={:#x} PLL3R={:#x}",
917+
pll3divr.pll3n().bits(),
918+
pll3divr.pll3p().bits(),
919+
pll3divr.pll3q().bits(),
920+
pll3divr.pll3r().bits(),
921+
);
922+
923+
let pll3fracr = rcc.pll3fracr().read();
924+
debug!(
925+
"PLL3FRACR register: FRACN2={:#x}",
926+
pll3fracr.pll3fracn().bits(),
927+
);
928+
}
869929
}
870930

931+
let pll1 = PllClocks::new(pll1_p_ck, pll1_q_ck, pll1_r_ck);
932+
let pll2 = PllClocks::new(pll2_p_ck, pll2_q_ck, pll2_r_ck);
933+
#[cfg(feature = "rm0481")]
934+
let pll3 = PllClocks::new(pll3_p_ck, pll3_q_ck, pll3_r_ck);
935+
871936
// Return frozen clock configuration
872937
Ccdr {
873938
clocks: CoreClocks {
@@ -888,12 +953,10 @@ impl Rcc {
888953
audio_ck,
889954
mco1_ck,
890955
mco2_ck,
891-
pll1_p_ck,
892-
pll1_q_ck,
893-
pll1_r_ck,
894-
pll2_p_ck,
895-
pll2_q_ck,
896-
pll2_r_ck,
956+
pll1,
957+
pll2,
958+
#[cfg(feature = "rm0481")]
959+
pll3,
897960
timx_ker_ck: Hertz::from_raw(rcc_timx_ker_ck),
898961
timy_ker_ck: Hertz::from_raw(rcc_timy_ker_ck),
899962
sys_ck,

src/rcc/core_clocks.rs

+49-26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,37 @@
22
33
use crate::time::Hertz;
44

5+
#[derive(Clone, Copy)]
6+
pub struct PllClocks {
7+
p_ck: Option<Hertz>,
8+
q_ck: Option<Hertz>,
9+
r_ck: Option<Hertz>,
10+
}
11+
12+
impl PllClocks {
13+
pub fn new(
14+
p_ck: Option<Hertz>,
15+
q_ck: Option<Hertz>,
16+
r_ck: Option<Hertz>,
17+
) -> Self {
18+
Self { p_ck, q_ck, r_ck }
19+
}
20+
}
21+
22+
impl PllClocks {
23+
pub fn p_ck(&self) -> Option<Hertz> {
24+
self.p_ck
25+
}
26+
27+
pub fn q_ck(&self) -> Option<Hertz> {
28+
self.q_ck
29+
}
30+
31+
pub fn r_ck(&self) -> Option<Hertz> {
32+
self.r_ck
33+
}
34+
}
35+
536
/// Frozen core clock frequencies
637
///
738
/// The existence of this value indicates that the core clock
@@ -25,12 +56,10 @@ pub struct CoreClocks {
2556
pub(super) audio_ck: Option<Hertz>,
2657
pub(super) mco1_ck: Option<Hertz>,
2758
pub(super) mco2_ck: Option<Hertz>,
28-
pub(super) pll1_p_ck: Option<Hertz>,
29-
pub(super) pll1_q_ck: Option<Hertz>,
30-
pub(super) pll1_r_ck: Option<Hertz>,
31-
pub(super) pll2_p_ck: Option<Hertz>,
32-
pub(super) pll2_q_ck: Option<Hertz>,
33-
pub(super) pll2_r_ck: Option<Hertz>,
59+
pub(super) pll1: PllClocks,
60+
pub(super) pll2: PllClocks,
61+
#[cfg(feature = "rm0481")]
62+
pub(super) pll3: PllClocks,
3463
pub(super) timx_ker_ck: Hertz,
3564
pub(super) timy_ker_ck: Hertz,
3665
pub(super) sys_ck: Hertz,
@@ -66,19 +95,6 @@ macro_rules! optional_ck_getter {
6695
};
6796
}
6897

69-
/// Getters for pll clocks
70-
macro_rules! pll_getter {
71-
($($pll_ck:ident,)+) => {
72-
$(
73-
/// Returns `Some(frequency)` if the PLLx output is running,
74-
/// otherwise `None`
75-
pub fn $pll_ck(&self) -> Option<Hertz> {
76-
self.$pll_ck
77-
}
78-
)+
79-
};
80-
}
81-
8298
impl CoreClocks {
8399
/// Returns the frequency of AHB1,2,3 busses
84100
pub fn hclk(&self) -> Hertz {
@@ -114,13 +130,20 @@ impl CoreClocks {
114130
self.mco2_ck
115131
}
116132

117-
pll_getter! {
118-
pll1_p_ck,
119-
pll1_q_ck,
120-
pll1_r_ck,
121-
pll2_p_ck,
122-
pll2_q_ck,
123-
pll2_r_ck,
133+
/// Returns the configuration for PLL1
134+
pub fn pll1(&self) -> PllClocks {
135+
self.pll1
136+
}
137+
138+
/// Returns the configuration for PLL2
139+
pub fn pll2(&self) -> PllClocks {
140+
self.pll2
141+
}
142+
143+
#[cfg(feature = "rm0481")]
144+
/// Returns the configuration for PLL3
145+
pub fn pll3(&self) -> PllClocks {
146+
self.pll3
124147
}
125148

126149
/// Returns the input frequency to the SCGU

src/rcc/pll.rs

+2
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ fn calc_vco_ck(ref_ck: u32, pll_n: u32, pll_fracn: u16) -> u32 {
328328
impl Rcc {
329329
pll_setup! {pll1, false}
330330
pll_setup! {pll2, true}
331+
#[cfg(feature = "rm0481")]
332+
pll_setup! {pll3, true}
331333
}
332334

333335
#[cfg(test)]

0 commit comments

Comments
 (0)