Skip to content

Commit 55ac63a

Browse files
kevswimsluctius
authored andcommitted
Allow setting apb 1 and 2 prescalers separately and fix timer clock calcs
1 parent 4e25b7c commit 55ac63a

File tree

2 files changed

+58
-27
lines changed

2 files changed

+58
-27
lines changed

src/rcc/config.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ pub struct Config {
330330
pub(crate) sys_mux: SysClockSrc,
331331
pub(crate) pll_cfg: PllConfig,
332332
pub(crate) ahb_psc: Prescaler,
333-
pub(crate) apb_psc: Prescaler,
333+
pub(crate) apb1_psc: Prescaler,
334+
pub(crate) apb2_psc: Prescaler,
334335
}
335336

336337
impl Config {
@@ -361,8 +362,13 @@ impl Config {
361362
self
362363
}
363364

364-
pub fn apb_psc(mut self, psc: Prescaler) -> Self {
365-
self.apb_psc = psc;
365+
pub fn apb1_psc(mut self, psc: Prescaler) -> Self {
366+
self.apb1_psc = psc;
367+
self
368+
}
369+
370+
pub fn apb2_psc(mut self, psc: Prescaler) -> Self {
371+
self.apb2_psc = psc;
366372
self
367373
}
368374
}
@@ -373,7 +379,8 @@ impl Default for Config {
373379
sys_mux: SysClockSrc::HSI,
374380
pll_cfg: PllConfig::default(),
375381
ahb_psc: Prescaler::NotDivided,
376-
apb_psc: Prescaler::NotDivided,
382+
apb1_psc: Prescaler::NotDivided,
383+
apb2_psc: Prescaler::NotDivided,
377384
}
378385
}
379386
}

src/rcc/mod.rs

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ pub struct Clocks {
2222
pub core_clk: Hertz,
2323
/// AHB frequency
2424
pub ahb_clk: Hertz,
25-
/// APB frequency
26-
pub apb_clk: Hertz,
27-
/// APB timers frequency
28-
pub apb_tim_clk: Hertz,
25+
/// APB 1 frequency
26+
pub apb1_clk: Hertz,
27+
/// APB 1 timers frequency (Timers 2-7)
28+
pub apb1_tim_clk: Hertz,
29+
/// APB 2 frequency
30+
pub apb2_clk: Hertz,
31+
/// APB 2 timers frequency (Timers 1, 8, 20, 15, 16, 17 and HRTIM1)
32+
pub apb2_tim_clk: Hertz,
2933
/// PLL frequency
3034
pub pll_clk: PLLClocks,
3135
}
@@ -48,8 +52,10 @@ impl Default for Clocks {
4852
sys_clk: freq,
4953
ahb_clk: freq,
5054
core_clk: freq,
51-
apb_clk: freq,
52-
apb_tim_clk: freq,
55+
apb1_clk: freq,
56+
apb1_tim_clk: freq,
57+
apb2_clk: freq,
58+
apb2_tim_clk: freq,
5359
pll_clk: PLLClocks {
5460
r: None,
5561
q: None,
@@ -101,7 +107,14 @@ impl Rcc {
101107
Prescaler::Div512 => (sys_freq / 512, 0b1111),
102108
_ => (sys_clk.0, 0b0000),
103109
};
104-
let (apb_freq, apb_psc_bits) = match rcc_cfg.apb_psc {
110+
let (apb1_freq, apb1_psc_bits) = match rcc_cfg.apb1_psc {
111+
Prescaler::Div2 => (sys_clk.0 / 2, 0b100),
112+
Prescaler::Div4 => (sys_clk.0 / 4, 0b101),
113+
Prescaler::Div8 => (sys_clk.0 / 8, 0b110),
114+
Prescaler::Div16 => (sys_clk.0 / 16, 0b111),
115+
_ => (sys_clk.0, 0b000),
116+
};
117+
let (apb2_freq, apb2_psc_bits) = match rcc_cfg.apb2_psc {
105118
Prescaler::Div2 => (sys_clk.0 / 2, 0b100),
106119
Prescaler::Div4 => (sys_clk.0 / 4, 0b101),
107120
Prescaler::Div8 => (sys_clk.0 / 8, 0b110),
@@ -127,24 +140,41 @@ impl Rcc {
127140
w.hpre()
128141
.bits(ahb_psc_bits)
129142
.ppre1()
130-
.bits(apb_psc_bits)
143+
.bits(apb1_psc_bits)
131144
.ppre2()
132-
.bits(apb_psc_bits)
145+
.bits(apb2_psc_bits)
133146
.sw()
134147
.bits(sw_bits)
135148
});
136149

137150
while self.rb.cfgr.read().sws().bits() != sw_bits {}
138151

152+
// From RM:
153+
// The timer clock frequencies are automatically defined by hardware. There are two cases:
154+
// 1. If the APB prescaler equals 1, the timer clock frequencies are set to the same
155+
// frequency as that of the APB domain.
156+
// 2. Otherwise, they are set to twice (×2) the frequency of the APB domain.
157+
let apb1_tim_clk = match rcc_cfg.apb1_psc {
158+
Prescaler::NotDivided => apb1_freq,
159+
_ => apb1_freq * 2,
160+
};
161+
162+
let apb2_tim_clk = match rcc_cfg.apb2_psc {
163+
Prescaler::NotDivided => apb2_freq,
164+
_ => apb2_freq * 2,
165+
};
166+
139167
Rcc {
140168
rb: self.rb,
141169
clocks: Clocks {
142170
pll_clk,
143171
sys_clk,
144172
core_clk: ahb_freq.hz(),
145173
ahb_clk: ahb_freq.hz(),
146-
apb_clk: apb_freq.hz(),
147-
apb_tim_clk: apb_freq.hz(),
174+
apb1_clk: apb1_freq.hz(),
175+
apb1_tim_clk: apb1_tim_clk.hz(),
176+
apb2_clk: apb2_freq.hz(),
177+
apb2_tim_clk: apb2_tim_clk.hz(),
148178
},
149179
}
150180
}
@@ -451,33 +481,27 @@ impl GetBusFreq for AHB3 {
451481

452482
impl GetBusFreq for APB1_1 {
453483
fn get_frequency(clocks: &Clocks) -> Hertz {
454-
clocks.apb_clk
484+
clocks.apb1_clk
455485
}
456486
fn get_timer_frequency(clocks: &Clocks) -> Hertz {
457-
// let pclk_mul = if clocks.ppre1 == 1 { 1 } else { 2 };
458-
// Hertz(clocks.pclk1.0 * pclk_mul)
459-
clocks.apb_tim_clk
487+
clocks.apb1_tim_clk
460488
}
461489
}
462490

463491
impl GetBusFreq for APB1_2 {
464492
fn get_frequency(clocks: &Clocks) -> Hertz {
465-
clocks.apb_clk
493+
clocks.apb1_clk
466494
}
467495
fn get_timer_frequency(clocks: &Clocks) -> Hertz {
468-
// let pclk_mul = if clocks.ppre1 == 1 { 1 } else { 2 };
469-
// Hertz(clocks.pclk1.0 * pclk_mul)
470-
clocks.apb_tim_clk
496+
clocks.apb1_tim_clk
471497
}
472498
}
473499

474500
impl GetBusFreq for APB2 {
475501
fn get_frequency(clocks: &Clocks) -> Hertz {
476-
clocks.apb_clk
502+
clocks.apb2_clk
477503
}
478504
fn get_timer_frequency(clocks: &Clocks) -> Hertz {
479-
// let pclk_mul = if clocks.ppre2 == 1 { 1 } else { 2 };
480-
// Hertz(clocks.pclk2.0 * pclk_mul)
481-
clocks.apb_tim_clk
505+
clocks.apb2_tim_clk
482506
}
483507
}

0 commit comments

Comments
 (0)