mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-03-14 04:18:33 +00:00
* Allow pre-processor overrides for Clock/PLL setup * Use `_KHZ` rather than `_MHZ` for `XOSC_` `SYS_CLOCK_` etc definitions (`_MHZ` versions are provided for compatibility when `_KHZ` is a multiple of 1000) Co-authored-by: graham sanderson <graham.sanderson@raspberrypi.com>
This commit is contained in:
parent
cb0ac5bd1a
commit
a42564b4b4
@ -105,7 +105,7 @@ void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2);
|
||||
* \ingroup pico_stdlib
|
||||
*
|
||||
* \param freq_khz Requested frequency
|
||||
* \param vco_freq_out On success, the voltage controller oscillator frequeucny to be used by the SYS PLL
|
||||
* \param vco_freq_out On success, the voltage controlled oscillator frequency to be used by the SYS PLL
|
||||
* \param post_div1_out On success, The first post divider for the SYS PLL
|
||||
* \param post_div2_out On success, The second post divider for the SYS PLL.
|
||||
* @return true if the frequency is possible and the output parameters have been written.
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#define NUM_SPIN_LOCKS 32u
|
||||
|
||||
#define XOSC_MHZ 12
|
||||
#define XOSC_KHZ 12000u
|
||||
|
||||
#define NUM_SPIN_LOCKS 32u
|
||||
|
||||
|
@ -37,9 +37,38 @@
|
||||
|
||||
#define PIO_INSTRUCTION_COUNT _u(32)
|
||||
|
||||
// PICO_CONFIG: XOSC_MHZ, The crystal oscillator frequency in Mhz, type=int, default=12, advanced=true, group=hardware_base
|
||||
#ifndef XOSC_MHZ
|
||||
#define XOSC_MHZ _u(12)
|
||||
// PICO_CONFIG: XOSC_KHZ, The crystal oscillator frequency in kHz, type=int, default=12000, advanced=true, group=hardware_base
|
||||
// NOTE: The system and USB clocks are generated from the frequency using two PLLs.
|
||||
// If you override this define, or SYS_CLK_KHZ/USB_CLK_KHZ below, you will *also* need to add your own adjusted PLL set-up defines to
|
||||
// override the defaults which live in src/rp2_common/hardware_clocks/include/hardware/clocks.h
|
||||
// Please see the comments there about calculating the new PLL setting values.
|
||||
#ifndef XOSC_KHZ
|
||||
#define XOSC_KHZ _u(12000)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: SYS_CLK_KHZ, The system operating frequency in kHz, type=int, default=125000, advanced=true, group=hardware_base
|
||||
#ifndef SYS_CLK_KHZ
|
||||
#define SYS_CLK_KHZ _u(125000)
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: USB_CLK_KHZ, USB clock frequency. Must be 48MHz for the USB interface to operate correctly, type=int, default=48000, advanced=true, group=hardware_base
|
||||
#ifndef USB_CLK_KHZ
|
||||
#define USB_CLK_KHZ _u(48000)
|
||||
#endif
|
||||
|
||||
// For backwards compatibility define XOSC_MHZ if the frequency is indeed an integer number of Mhz.
|
||||
#if defined(XOSC_KHZ) && !defined(XOSC_MHZ) && (XOSC_KHZ % 1000 == 0)
|
||||
#define XOSC_MHZ (XOSC_KHZ / 1000)
|
||||
#endif
|
||||
|
||||
// For backwards compatibility define SYS_CLK_MHZ if the frequency is indeed an integer number of Mhz.
|
||||
#if defined(SYS_CLK_KHZ) && !defined(SYS_CLK_MHZ) && (SYS_CLK_KHZ % 1000 == 0)
|
||||
#define SYS_CLK_MHZ (SYS_CLK_KHZ / 1000)
|
||||
#endif
|
||||
|
||||
// For backwards compatibility define USB_CLK_MHZ if the frequency is indeed an integer number of Mhz.
|
||||
#if defined(USB_CLK_KHZ) && !defined(USB_CLK_MHZ) && (USB_CLK_KHZ % 1000 == 0)
|
||||
#define USB_CLK_MHZ (USB_CLK_KHZ / 1000)
|
||||
#endif
|
||||
|
||||
#define FIRST_USER_IRQ (NUM_IRQS - NUM_USER_IRQS)
|
||||
|
@ -14,6 +14,12 @@
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/gpio.h"
|
||||
|
||||
// The RTC clock frequency is 48MHz divided by power of 2 (to ensure an integer
|
||||
// division ratio will be used in the clocks block). A divisor of 1024 generates
|
||||
// an RTC clock tick of 46875Hz. This frequency is relatively close to the
|
||||
// customary 32 or 32.768kHz 'slow clock' crystals and provides good timing resolution.
|
||||
#define RTC_CLOCK_FREQ_HZ (USB_CLK_KHZ * KHZ / 1024)
|
||||
|
||||
check_hw_layout(clocks_hw_t, clk[clk_adc].selected, CLOCKS_CLK_ADC_SELECTED_OFFSET);
|
||||
check_hw_layout(clocks_hw_t, fc0.result, CLOCKS_FC0_RESULT_OFFSET);
|
||||
check_hw_layout(clocks_hw_t, ints, CLOCKS_INTS_OFFSET);
|
||||
@ -113,15 +119,15 @@ bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc,
|
||||
/// \end::clock_configure[]
|
||||
|
||||
void clocks_init(void) {
|
||||
// Start tick in watchdog
|
||||
watchdog_start_tick(XOSC_MHZ);
|
||||
// Start tick in watchdog, the argument is in 'cycles per microsecond' i.e. MHz
|
||||
watchdog_start_tick(XOSC_KHZ / KHZ);
|
||||
|
||||
// Everything is 48MHz on FPGA apart from RTC. Otherwise set to 0 and will be set in clock configure
|
||||
if (running_on_fpga()) {
|
||||
for (uint i = 0; i < CLK_COUNT; i++) {
|
||||
configured_freq[i] = 48 * MHZ;
|
||||
}
|
||||
configured_freq[clk_rtc] = 46875;
|
||||
configured_freq[clk_rtc] = RTC_CLOCK_FREQ_HZ;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -139,63 +145,56 @@ void clocks_init(void) {
|
||||
while (clocks_hw->clk[clk_ref].selected != 0x1)
|
||||
tight_loop_contents();
|
||||
|
||||
/// \tag::pll_settings[]
|
||||
// Configure PLLs
|
||||
// REF FBDIV VCO POSTDIV
|
||||
// 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, 1200 * MHZ, 5, 5);
|
||||
pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
|
||||
pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_KHZ * KHZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
|
||||
/// \end::pll_init[]
|
||||
|
||||
// Configure clocks
|
||||
// CLK_REF = XOSC (12MHz) / 1 = 12MHz
|
||||
// CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
|
||||
clock_configure(clk_ref,
|
||||
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
|
||||
0, // No aux mux
|
||||
12 * MHZ,
|
||||
12 * MHZ);
|
||||
XOSC_KHZ * KHZ,
|
||||
XOSC_KHZ * KHZ);
|
||||
|
||||
/// \tag::configure_clk_sys[]
|
||||
// CLK SYS = PLL SYS (125MHz) / 1 = 125MHz
|
||||
// CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz
|
||||
clock_configure(clk_sys,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
|
||||
125 * MHZ,
|
||||
125 * MHZ);
|
||||
SYS_CLK_KHZ * KHZ,
|
||||
SYS_CLK_KHZ * KHZ);
|
||||
/// \end::configure_clk_sys[]
|
||||
|
||||
// CLK USB = PLL USB (48MHz) / 1 = 48MHz
|
||||
// CLK USB = PLL USB 48MHz / 1 = 48MHz
|
||||
clock_configure(clk_usb,
|
||||
0, // No GLMUX
|
||||
CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
|
||||
// CLK ADC = PLL USB (48MHZ) / 1 = 48MHz
|
||||
// CLK ADC = PLL USB 48MHZ / 1 = 48MHz
|
||||
clock_configure(clk_adc,
|
||||
0, // No GLMUX
|
||||
CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
|
||||
// CLK RTC = PLL USB (48MHz) / 1024 = 46875Hz
|
||||
// CLK RTC = PLL USB 48MHz / 1024 = 46875Hz
|
||||
clock_configure(clk_rtc,
|
||||
0, // No GLMUX
|
||||
CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
46875);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
RTC_CLOCK_FREQ_HZ);
|
||||
|
||||
// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
|
||||
// Normally choose clk_sys or clk_usb
|
||||
clock_configure(clk_peri,
|
||||
0,
|
||||
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
|
||||
125 * MHZ,
|
||||
125 * MHZ);
|
||||
SYS_CLK_KHZ * KHZ,
|
||||
SYS_CLK_KHZ * KHZ);
|
||||
}
|
||||
|
||||
/// \tag::clock_get_hz[]
|
||||
|
@ -89,6 +89,70 @@ extern "C" {
|
||||
#define KHZ 1000
|
||||
#define MHZ 1000000
|
||||
|
||||
/// \tag::pll_settings[]
|
||||
//
|
||||
// There are two PLLs in RP2040:
|
||||
// 1. The 'SYS PLL' generates the 125MHz system clock, the frequency is defined by `SYS_CLK_KHZ`.
|
||||
// 2. The 'USB PLL' generates the 48MHz USB clock, the frequency is defined by `USB_CLK_KHZ`.
|
||||
//
|
||||
// The two PLLs use the crystal oscillator output directly as their reference frequency input; the PLLs reference
|
||||
// frequency cannot be reduced by the dividers present in the clocks block. The crystal frequency is defined by `XOSC_KHZ` or
|
||||
// `XOSC_MHZ`.
|
||||
//
|
||||
// The system's default definitions are correct for the above frequencies with a 12MHz
|
||||
// crystal frequency. If different frequencies are required, these must be defined in
|
||||
// the board configuration file together with the revised PLL settings
|
||||
// Use `vcocalc.py` to check and calculate new PLL settings if you change any of these frequencies.
|
||||
//
|
||||
// Default PLL configuration:
|
||||
// REF FBDIV VCO POSTDIV
|
||||
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz
|
||||
// PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz
|
||||
/// \end::pll_settings[]
|
||||
|
||||
// PICO_CONFIG: PLL_COMMON_REFDIV, PLL reference divider setting - used for both PLLs, type=int, default=1, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_COMMON_REFDIV
|
||||
#define PLL_COMMON_REFDIV 1
|
||||
#endif
|
||||
|
||||
#if (SYS_CLK_KHZ == 125000) && (XOSC_KHZ == 12000) && (PLL_COMMON_REFDIV == 1)
|
||||
// PLL settings for standard 125 MHz system clock.
|
||||
// PICO_CONFIG: PLL_SYS_VCO_FREQ_KHZ, System clock PLL frequency, type=int, default=1500 * KHZ, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_SYS_VCO_FREQ_KHZ
|
||||
#define PLL_SYS_VCO_FREQ_KHZ (1500 * KHZ)
|
||||
#endif
|
||||
// PICO_CONFIG: PLL_SYS_POSTDIV1, System clock PLL post divider 1 setting, type=int, default=6, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_SYS_POSTDIV1
|
||||
#define PLL_SYS_POSTDIV1 6
|
||||
#endif
|
||||
// PICO_CONFIG: PLL_SYS_POSTDIV2, System clock PLL post divider 2 setting, type=int, default=2, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_SYS_POSTDIV2
|
||||
#define PLL_SYS_POSTDIV2 2
|
||||
#endif
|
||||
#endif // SYS_CLK_KHZ == 125000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
|
||||
#if !defined(PLL_SYS_VCO_FREQ_KHZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
|
||||
#error PLL_SYS_VCO_FREQ_KHZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
|
||||
#endif
|
||||
|
||||
#if (USB_CLK_KHZ == 48000) && (XOSC_KHZ == 12000) && (PLL_COMMON_REFDIV == 1)
|
||||
// PLL settings for a USB clock of 48MHz.
|
||||
// PICO_CONFIG: PLL_USB_VCO_FREQ_KHZ, USB clock PLL frequency, type=int, default=1200 * KHZ, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_USB_VCO_FREQ_KHZ
|
||||
#define PLL_USB_VCO_FREQ_KHZ (1200 * KHZ)
|
||||
#endif
|
||||
// PICO_CONFIG: PLL_USB_POSTDIV1, USB clock PLL post divider 1 setting, type=int, default=5, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_USB_POSTDIV1
|
||||
#define PLL_USB_POSTDIV1 5
|
||||
#endif
|
||||
// PICO_CONFIG: PLL_USB_POSTDIV2, USB clock PLL post divider 2 setting, type=int, default=5, advanced=true, group=hardware_clocks
|
||||
#ifndef PLL_USB_POSTDIV2
|
||||
#define PLL_USB_POSTDIV2 5
|
||||
#endif
|
||||
#endif // USB_CLK_KHZ == 48000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
|
||||
#if !defined(PLL_USB_VCO_FREQ_KHZ) || !defined(PLL_USB_POSTDIV1) || !defined(PLL_USB_POSTDIV2)
|
||||
#error PLL_USB_VCO_FREQ_KHZ, PLL_USB_POSTDIV1 and PLL_USB_POSTDIV2 must all be specified when using custom clock setup.
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_CLOCKS, Enable/disable assertions in the clocks module, type=bool, default=0, group=hardware_clocks
|
||||
#ifndef PARAM_ASSERTIONS_ENABLED_CLOCKS
|
||||
#define PARAM_ASSERTIONS_ENABLED_CLOCKS 0
|
||||
|
@ -31,12 +31,20 @@ typedef pll_hw_t *PLL;
|
||||
#define pll_sys pll_sys_hw
|
||||
#define pll_usb pll_usb_hw
|
||||
|
||||
#ifndef PICO_PLL_VCO_MIN_FREQ_KHZ
|
||||
#ifndef PICO_PLL_VCO_MIN_FREQ_MHZ
|
||||
#define PICO_PLL_VCO_MIN_FREQ_MHZ 750
|
||||
#define PICO_PLL_VCO_MIN_FREQ_KHZ (750 * KHZ)
|
||||
#else
|
||||
#define PICO_PLL_VCO_MIN_FREQ_KHZ (PICO_PLL_VCO_MIN_FREQ_MHZ * KHZ)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PICO_PLL_VCO_MAX_FREQ_KHZ
|
||||
#ifndef PICO_PLL_VCO_MAX_FREQ_MHZ
|
||||
#define PICO_PLL_VCO_MAX_FREQ_MHZ 1600
|
||||
#define PICO_PLL_VCO_MAX_FREQ_KHZ (1600 * KHZ)
|
||||
#else
|
||||
#define PICO_PLL_VCO_MAX_FREQ_KHZ (PICO_PLL_VCO_MAX_FREQ_MHZ * KHZ)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*! \brief Initialise specified PLL.
|
||||
|
@ -4,21 +4,21 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// For MHZ definitions etc
|
||||
// For frequency and PLL definitions etc.
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/pll.h"
|
||||
#include "hardware/resets.h"
|
||||
|
||||
/// \tag::pll_init_calculations[]
|
||||
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) {
|
||||
uint32_t ref_mhz = XOSC_MHZ / refdiv;
|
||||
uint32_t ref_freq = XOSC_KHZ * KHZ / 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));
|
||||
assert(vco_freq >= (PICO_PLL_VCO_MIN_FREQ_KHZ * KHZ) && vco_freq <= (PICO_PLL_VCO_MAX_FREQ_KHZ * KHZ));
|
||||
|
||||
// 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);
|
||||
uint32_t fbdiv = vco_freq / ref_freq;
|
||||
/// \end::pll_init_calculations[]
|
||||
|
||||
// fbdiv
|
||||
@ -32,7 +32,7 @@ void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div
|
||||
// postdiv1 is designed to operate with a higher input frequency than postdiv2
|
||||
|
||||
// Check that reference frequency is no greater than vco / 16
|
||||
assert(ref_mhz <= (vco_freq / 16));
|
||||
assert(ref_freq <= (vco_freq / 16));
|
||||
|
||||
// div1 feeds into div2 so if div1 is 5 and div2 is 2 then you get a divide by 10
|
||||
uint32_t pdiv = (post_div1 << PLL_PRIM_POSTDIV1_LSB) |
|
||||
|
@ -6,18 +6,20 @@
|
||||
|
||||
#include "pico.h"
|
||||
|
||||
// For MHZ definitions etc
|
||||
// For frequency related definitions etc
|
||||
#include "hardware/clocks.h"
|
||||
|
||||
#include "hardware/platform_defs.h"
|
||||
#include "hardware/regs/xosc.h"
|
||||
#include "hardware/xosc.h"
|
||||
|
||||
#if XOSC_MHZ < 1 || XOSC_MHZ > 50
|
||||
#error XOSC_MHZ must be in the range 1-50
|
||||
#if XOSC_KHZ < (1 * KHZ) || XOSC_KHZ > (50 * KHZ)
|
||||
// Note: Although an external clock can be supplied up to 50 MHz, the maximum frequency the
|
||||
// XOSC cell is specified to work with a crystal is less, please see the RP2040 Datasheet.
|
||||
#error XOSC_KHZ must be in the range 1,000-50,000KHz i.e. 1-50MHz XOSC frequency
|
||||
#endif
|
||||
|
||||
#define STARTUP_DELAY (((((XOSC_MHZ * MHZ) / 1000) + 128) / 256) * PICO_XOSC_STARTUP_DELAY_MULTIPLIER)
|
||||
#define STARTUP_DELAY (((XOSC_KHZ + 128) / 256) * PICO_XOSC_STARTUP_DELAY_MULTIPLIER)
|
||||
|
||||
// The DELAY field in xosc_hw->startup is 14 bits wide.
|
||||
#if STARTUP_DELAY >= (1 << 13)
|
||||
|
@ -21,8 +21,8 @@ void set_sys_clock_48mhz() {
|
||||
clock_configure(clk_sys,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
|
||||
// Turn off PLL sys for good measure
|
||||
pll_deinit(pll_sys);
|
||||
@ -31,8 +31,8 @@ void set_sys_clock_48mhz() {
|
||||
clock_configure(clk_peri,
|
||||
0,
|
||||
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,21 +41,21 @@ void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2) {
|
||||
clock_configure(clk_sys,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
|
||||
pll_init(pll_sys, 1, vco_freq, post_div1, post_div2);
|
||||
pll_init(pll_sys, PLL_COMMON_REFDIV, vco_freq, post_div1, post_div2);
|
||||
uint32_t freq = vco_freq / (post_div1 * post_div2);
|
||||
|
||||
// Configure clocks
|
||||
// CLK_REF = XOSC (12MHz) / 1 = 12MHz
|
||||
// CLK_REF is the XOSC source
|
||||
clock_configure(clk_ref,
|
||||
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
|
||||
0, // No aux mux
|
||||
12 * MHZ,
|
||||
12 * MHZ);
|
||||
XOSC_KHZ * KHZ,
|
||||
XOSC_KHZ * KHZ);
|
||||
|
||||
// CLK SYS = PLL SYS (125MHz) / 1 = 125MHz
|
||||
// CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz
|
||||
clock_configure(clk_sys,
|
||||
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
|
||||
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
|
||||
@ -64,23 +64,23 @@ void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2) {
|
||||
clock_configure(clk_peri,
|
||||
0, // Only AUX mux on ADC
|
||||
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
|
||||
48 * MHZ,
|
||||
48 * MHZ);
|
||||
USB_CLK_KHZ * KHZ,
|
||||
USB_CLK_KHZ * KHZ);
|
||||
}
|
||||
}
|
||||
|
||||
bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_out, uint *postdiv1_out, uint *postdiv_out) {
|
||||
uint crystal_freq_khz = clock_get_hz(clk_ref) / 1000;
|
||||
bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_out, uint *postdiv1_out, uint *postdiv2_out) {
|
||||
uint reference_freq_khz = XOSC_KHZ / PLL_COMMON_REFDIV;
|
||||
for (uint fbdiv = 320; fbdiv >= 16; fbdiv--) {
|
||||
uint vco = fbdiv * crystal_freq_khz;
|
||||
if (vco < PICO_PLL_VCO_MIN_FREQ_MHZ * 1000 || vco > PICO_PLL_VCO_MAX_FREQ_MHZ * 1000) continue;
|
||||
uint vco_khz = fbdiv * reference_freq_khz;
|
||||
if (vco_khz < PICO_PLL_VCO_MIN_FREQ_KHZ || vco_khz > PICO_PLL_VCO_MAX_FREQ_KHZ) continue;
|
||||
for (uint postdiv1 = 7; postdiv1 >= 1; postdiv1--) {
|
||||
for (uint postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) {
|
||||
uint out = vco / (postdiv1 * postdiv2);
|
||||
if (out == freq_khz && !(vco % (postdiv1 * postdiv2))) {
|
||||
*vco_out = vco * 1000;
|
||||
uint out = vco_khz / (postdiv1 * postdiv2);
|
||||
if (out == freq_khz && !(vco_khz % (postdiv1 * postdiv2))) {
|
||||
*vco_out = vco_khz * KHZ;
|
||||
*postdiv1_out = postdiv1;
|
||||
*postdiv_out = postdiv2;
|
||||
*postdiv2_out = postdiv2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user