rp/clocks: provide fbdiv, not vco_freq
solvers usually output fbdiv directly, using vco_freq to get back to fbdiv is not all that necessary or useful. both vco_freq and fbdiv have hidden constraints, but vco_freq is a lot less accurate because the fbdiv value resulting from the division may be off by almost a full ref_freq's worth of frequency. also fixes the usb pll config, which ran the pll vco way out of (below) spec.
This commit is contained in:
parent
d3494a4bdf
commit
5bbed31513
@ -37,15 +37,15 @@ impl ClockConfig {
|
|||||||
clock_type: ExternalClock::Crystal,
|
clock_type: ExternalClock::Crystal,
|
||||||
sys_pll: Some(PllConfig {
|
sys_pll: Some(PllConfig {
|
||||||
refdiv: 1,
|
refdiv: 1,
|
||||||
vco_freq: 1500_000_000,
|
fbdiv: 125,
|
||||||
post_div1: 6,
|
post_div1: 6,
|
||||||
post_div2: 2,
|
post_div2: 2,
|
||||||
}),
|
}),
|
||||||
usb_pll: Some(PllConfig {
|
usb_pll: Some(PllConfig {
|
||||||
refdiv: 1,
|
refdiv: 1,
|
||||||
vco_freq: 480_000_000,
|
fbdiv: 120,
|
||||||
post_div1: 5,
|
post_div1: 6,
|
||||||
post_div2: 2,
|
post_div2: 5,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
ref_clk: RefClkConfig {
|
ref_clk: RefClkConfig {
|
||||||
@ -126,7 +126,7 @@ pub struct XoscConfig {
|
|||||||
|
|
||||||
pub struct PllConfig {
|
pub struct PllConfig {
|
||||||
pub refdiv: u32,
|
pub refdiv: u32,
|
||||||
pub vco_freq: u32,
|
pub fbdiv: u16,
|
||||||
pub post_div1: u8,
|
pub post_div1: u8,
|
||||||
pub post_div2: u8,
|
pub post_div2: u8,
|
||||||
}
|
}
|
||||||
@ -587,16 +587,15 @@ unsafe fn start_xosc(crystal_hz: u32) {
|
|||||||
unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) {
|
unsafe fn configure_pll(p: pac::pll::Pll, input_freq: u32, config: PllConfig) {
|
||||||
let ref_freq = input_freq / config.refdiv;
|
let ref_freq = input_freq / config.refdiv;
|
||||||
|
|
||||||
let fbdiv = config.vco_freq / ref_freq;
|
assert!(config.fbdiv >= 16 && config.fbdiv <= 320);
|
||||||
assert!(fbdiv >= 16 && fbdiv <= 320);
|
|
||||||
assert!(config.post_div1 >= 1 && config.post_div1 <= 7);
|
assert!(config.post_div1 >= 1 && config.post_div1 <= 7);
|
||||||
assert!(config.post_div2 >= 1 && config.post_div2 <= 7);
|
assert!(config.post_div2 >= 1 && config.post_div2 <= 7);
|
||||||
assert!(config.post_div2 <= config.post_div1);
|
assert!(config.post_div2 <= config.post_div1);
|
||||||
assert!(ref_freq <= (config.vco_freq / 16));
|
assert!(ref_freq >= 5_000_000 && ref_freq <= 800_000_000);
|
||||||
|
|
||||||
// Load VCO-related dividers before starting VCO
|
// Load VCO-related dividers before starting VCO
|
||||||
p.cs().write(|w| w.set_refdiv(config.refdiv as _));
|
p.cs().write(|w| w.set_refdiv(config.refdiv as _));
|
||||||
p.fbdiv_int().write(|w| w.set_fbdiv_int(fbdiv as _));
|
p.fbdiv_int().write(|w| w.set_fbdiv_int(config.fbdiv));
|
||||||
|
|
||||||
// Turn on PLL
|
// Turn on PLL
|
||||||
p.pwr().modify(|w| {
|
p.pwr().modify(|w| {
|
||||||
|
Loading…
Reference in New Issue
Block a user