diff --git a/src/rp2040/hardware_regs/include/hardware/regs/pll.h b/src/rp2040/hardware_regs/include/hardware/regs/pll.h index a0f5ad0..9dba689 100644 --- a/src/rp2040/hardware_regs/include/hardware/regs/pll.h +++ b/src/rp2040/hardware_regs/include/hardware/regs/pll.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,7 +17,7 @@ // GENERAL CONSTRAINTS: // Reference clock frequency min=5MHz, max=800MHz // Feedback divider min=16, max=320 -// VCO frequency min=400MHz, max=1600MHz +// VCO frequency min=750MHz, max=1600MHz #define PLL_CS_OFFSET _u(0x00000000) #define PLL_CS_BITS _u(0x8000013f) #define PLL_CS_RESET _u(0x00000001) diff --git a/src/rp2040/hardware_regs/rp2040.svd b/src/rp2040/hardware_regs/rp2040.svd index 95e1990..3849776 100644 --- a/src/rp2040/hardware_regs/rp2040.svd +++ b/src/rp2040/hardware_regs/rp2040.svd @@ -22367,7 +22367,7 @@ GENERAL CONSTRAINTS:\n Reference clock frequency min=5MHz, max=800MHz\n Feedback divider min=16, max=320\n - VCO frequency min=400MHz, max=1600MHz + VCO frequency min=750MHz, max=1600MHz read-only diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index f51331a..9ba51f0 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -148,13 +148,13 @@ void clocks_init(void) { /// \tag::pll_settings[] // Configure PLLs // REF FBDIV VCO POSTDIV - // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz - // PLL USB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz + // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz + // PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz /// \end::pll_settings[] /// \tag::pll_init[] pll_init(pll_sys, 1, 1500 * MHZ, 6, 2); - pll_init(pll_usb, 1, 480 * MHZ, 5, 2); + pll_init(pll_usb, 1, 1200 * MHZ, 5, 5); /// \end::pll_init[] // Configure clocks diff --git a/src/rp2_common/hardware_clocks/scripts/vcocalc.py b/src/rp2_common/hardware_clocks/scripts/vcocalc.py index 4d90146..5d143b3 100755 --- a/src/rp2_common/hardware_clocks/scripts/vcocalc.py +++ b/src/rp2_common/hardware_clocks/scripts/vcocalc.py @@ -5,7 +5,7 @@ import argparse parser = argparse.ArgumentParser(description="PLL parameter calculator") parser.add_argument("--input", "-i", default=12, help="Input (reference) frequency. Default 12 MHz", type=float) parser.add_argument("--vco-max", default=1600, help="Override maximum VCO frequency. Default 1600 MHz", type=float) -parser.add_argument("--vco-min", default=400, help="Override minimum VCO frequency. Default 400 MHz", type=float) +parser.add_argument("--vco-min", default=750, help="Override minimum VCO frequency. Default 750 MHz", type=float) parser.add_argument("--low-vco", "-l", action="store_true", help="Use a lower VCO frequency when possible. This reduces power consumption, at the cost of increased jitter") parser.add_argument("output", help="Output frequency in MHz.", type=float) args = parser.parse_args() diff --git a/src/rp2_common/hardware_pll/include/hardware/pll.h b/src/rp2_common/hardware_pll/include/hardware/pll.h index ee0c3ae..0466504 100644 --- a/src/rp2_common/hardware_pll/include/hardware/pll.h +++ b/src/rp2_common/hardware_pll/include/hardware/pll.h @@ -31,6 +31,14 @@ typedef pll_hw_t *PLL; #define pll_sys pll_sys_hw #define pll_usb pll_usb_hw +#ifndef PICO_PLL_VCO_MIN_FREQ_MHZ +#define PICO_PLL_VCO_MIN_FREQ_MHZ 750 +#endif + +#ifndef PICO_PLL_VCO_MAX_FREQ_MHZ +#define PICO_PLL_VCO_MAX_FREQ_MHZ 1600 +#endif + /*! \brief Initialise specified PLL. * \ingroup hardware_pll * \param pll pll_sys or pll_usb diff --git a/src/rp2_common/hardware_pll/pll.c b/src/rp2_common/hardware_pll/pll.c index f1a09d5..e152b84 100644 --- a/src/rp2_common/hardware_pll/pll.c +++ b/src/rp2_common/hardware_pll/pll.c @@ -13,6 +13,9 @@ void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) { uint32_t ref_mhz = XOSC_MHZ / refdiv; + // Check vco freq is in an acceptable range + assert(vco_freq >= (PICO_PLL_VCO_MIN_FREQ_MHZ * MHZ) && vco_freq <= (PICO_PLL_VCO_MAX_FREQ_MHZ * MHZ)); + // What are we multiplying the reference clock by to get the vco freq // (The regs are called div, because you divide the vco output and compare it to the refclk) uint32_t fbdiv = vco_freq / (ref_mhz * MHZ); diff --git a/src/rp2_common/pico_stdlib/stdlib.c b/src/rp2_common/pico_stdlib/stdlib.c index 7c9854e..159095c 100644 --- a/src/rp2_common/pico_stdlib/stdlib.c +++ b/src/rp2_common/pico_stdlib/stdlib.c @@ -73,7 +73,7 @@ bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_out, uint *postdiv1_out, u uint crystal_freq_khz = clock_get_hz(clk_ref) / 1000; for (uint fbdiv = 320; fbdiv >= 16; fbdiv--) { uint vco = fbdiv * crystal_freq_khz; - if (vco < 400000 || vco > 1600000) continue; + if (vco < PICO_PLL_VCO_MIN_FREQ_MHZ * 1000 || vco > PICO_PLL_VCO_MAX_FREQ_MHZ * 1000) continue; for (uint postdiv1 = 7; postdiv1 >= 1; postdiv1--) { for (uint postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) { uint out = vco / (postdiv1 * postdiv2);