From 92c130c7be259c13bb1fd1a58b6c9f7b717323da Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 28 Feb 2025 23:05:27 +0100 Subject: [PATCH] machine: compute rp2 clock dividers from crystal and target frequency (#4747) Follow-up to #4728 which implemented the algorithm for finding the dividers. The calculation is computed at compile time by interp, as verified by building example/blinky1 for -target pico. --- src/machine/machine_rp2_clocks.go | 16 ++++++++++++++-- src/machine/machine_rp2_pll.go | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/machine/machine_rp2_clocks.go b/src/machine/machine_rp2_clocks.go index 9dd2774b9..520a8d333 100644 --- a/src/machine/machine_rp2_clocks.go +++ b/src/machine/machine_rp2_clocks.go @@ -137,7 +137,19 @@ func (clk *clock) configure(src, auxsrc, srcFreq, freq uint32) { } -const pllsysFB, pllsysPD1, pllsysPD2 uint32 = 125, 6, 2 // RP2040 running 125MHz with 1500MHz VCO. +var pllsysFB, pllsysPD1, pllsysPD2 uint32 + +// Compute clock dividers. +// +// Note that the entire init function is computed at compile time +// by interp. +func init() { + fb, _, pd1, pd2, err := pllSearch{LockRefDiv: 1}.CalcDivs(xoscFreq*MHz, uint64(CPUFrequency()), MHz) + if err != nil { + panic(err) + } + pllsysFB, pllsysPD1, pllsysPD2 = uint32(fb), uint32(pd1), uint32(pd2) +} // init initializes the clock hardware. // @@ -165,7 +177,7 @@ func (clks *clocksType) init() { // REF FBDIV VCO POSTDIV // pllSys: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz // pllUSB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz - pllSys.init(1, uint32(pllsysFB), uint32(pllsysPD1), uint32(pllsysPD2)) + pllSys.init(1, pllsysFB, pllsysPD1, pllsysPD2) pllUSB.init(1, 40, 5, 2) // Configure clocks diff --git a/src/machine/machine_rp2_pll.go b/src/machine/machine_rp2_pll.go index dcc654ab0..d5760842b 100644 --- a/src/machine/machine_rp2_pll.go +++ b/src/machine/machine_rp2_pll.go @@ -111,7 +111,7 @@ var errVCOOverflow = errors.New("VCO calculation overflow; use lower MHz") // // Example for 12MHz crystal and RP2350: // -// fbdiv, refdiv, pd1, pd2, _ := pllSearch{LockRefDiv:1}.CalcDivs(12*MHz, 133*MHz, MHz) +// fbdiv, refdiv, pd1, pd2, _ := pllSearch{LockRefDiv:1}.CalcDivs(12*MHz, 150*MHz, MHz) type pllSearch struct { LowerVCO bool LockRefDiv uint8