7#ifndef _HARDWARE_CLOCKS_H
8#define _HARDWARE_CLOCKS_H
11#include "hardware/structs/clocks.h"
167#ifndef PLL_COMMON_REFDIV
169#define PLL_COMMON_REFDIV 1
173#ifndef PLL_SYS_REFDIV
175#ifdef PLL_COMMON_REFDIV
176#define PLL_SYS_REFDIV PLL_COMMON_REFDIV
178#define PLL_SYS_REFDIV 1
182#ifndef PLL_SYS_VCO_FREQ_HZ
184#ifdef PLL_SYS_VCO_FREQ_KHZ
185#define PLL_SYS_VCO_FREQ_HZ (PLL_SYS_VCO_FREQ_KHZ * KHZ)
189#if (SYS_CLK_HZ == 125 * MHZ || SYS_CLK_HZ == 150 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
192#ifndef PLL_SYS_VCO_FREQ_HZ
193#define PLL_SYS_VCO_FREQ_HZ (1500 * MHZ)
196#ifndef PLL_SYS_POSTDIV1
197#if SYS_CLK_HZ == 125 * MHZ
198#define PLL_SYS_POSTDIV1 6
200#define PLL_SYS_POSTDIV1 5
204#ifndef PLL_SYS_POSTDIV2
205#define PLL_SYS_POSTDIV2 2
209#if PICO_RP2040 && (SYS_CLK_HZ == 200 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
211#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
212#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 1
215#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && !defined(SYS_CLK_VREG_VOLTAGE_MIN)
216#define SYS_CLK_VREG_VOLTAGE_MIN VREG_VOLTAGE_1_15
219#ifndef PLL_SYS_VCO_FREQ_HZ
220#define PLL_SYS_VCO_FREQ_HZ (1200 * MHZ)
222#ifndef PLL_SYS_POSTDIV1
223#define PLL_SYS_POSTDIV1 6
225#ifndef PLL_SYS_POSTDIV2
226#define PLL_SYS_POSTDIV2 1
229#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
230#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 0
235#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US
236#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US 1000
239#if !defined(PLL_SYS_VCO_FREQ_HZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
240#error PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
244#ifndef PLL_USB_REFDIV
246#ifdef PLL_COMMON_REFDIV
247#define PLL_USB_REFDIV PLL_COMMON_REFDIV
249#define PLL_USB_REFDIV 1
253#ifndef PLL_USB_VCO_FREQ_HZ
255#ifdef PLL_USB_VCO_FREQ_KHZ
256#define PLL_USB_VCO_FREQ_HZ (PLL_USB_VCO_FREQ_KHZ * KHZ)
260#if (USB_CLK_HZ == 48 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_USB_REFDIV == 1)
263#ifndef PLL_USB_VCO_FREQ_HZ
264#define PLL_USB_VCO_FREQ_HZ (1200 * MHZ)
267#ifndef PLL_USB_POSTDIV1
268#define PLL_USB_POSTDIV1 5
271#ifndef PLL_USB_POSTDIV2
272#define PLL_USB_POSTDIV2 5
275#if !defined(PLL_USB_VCO_FREQ_HZ) || !defined(PLL_USB_POSTDIV1) || !defined(PLL_USB_POSTDIV2)
276#error PLL_USB_VCO_FREQ_HZ, PLL_USB_POSTDIV1 and PLL_USB_POSTDIV2 must all be specified when using custom clock setup.
280#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS
281#ifdef PARAM_ASSERTIONS_ENABLED_CLOCKS
282#define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS PARAM_ASSERTIONS_ENABLED_CLOCKS
284#define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS 0
289#ifndef PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
290#define PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
319bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq);
377static inline float frequency_count_mhz(uint src) {
424static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac8) {
437 uint div_int = (uint)div;
438 const int frac_bit_count = REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC);
439#if PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
440 div += 0.5f / (1 << frac_bit_count);
442#if REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 16
443 uint16_t frac = (uint16_t)((div - (
float)div_int) * (1u << frac_bit_count));
445#elif REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 8
446 uint8_t frac = (uint8_t)((div - (
float)div_int) * (1u << frac_bit_count));
449#error unsupported number of fractional bits
490bool check_sys_clock_hz(uint32_t freq_hz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
501bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
515 uint vco, postdiv1, postdiv2;
519 }
else if (required) {
520 panic(
"System clock of %u Hz cannot be exactly achieved", freq_hz);
537 uint vco, postdiv1, postdiv2;
541 }
else if (required) {
542 panic(
"System clock of %u kHz cannot be exactly achieved", freq_khz);
void clock_configure_int_divider(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider)
Configure the specified clock to use the undivided input source.
Definition clocks.c:126
static void clock_gpio_init_int_frac8(uint gpio, uint src, uint32_t div_int, uint8_t div_frac8)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.h:419
static bool set_sys_clock_hz(uint32_t freq_hz, bool required)
Attempt to set a system clock frequency in hz.
Definition clocks.h:514
void clock_stop(clock_handle_t clock)
Stop the specified clock.
Definition clocks.c:33
void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2)
Initialise the system clock.
Definition clocks.c:380
bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq)
Configure the specified clock with automatic clock divisor setup.
Definition clocks.c:98
void(* resus_callback_t)(void)
Resus callback function type.
Definition clocks.h:387
void clocks_enable_resus(resus_callback_t resus_callback)
Enable the resus function. Restarts clk_sys if it is accidentally stopped.
Definition clocks.c:221
void clock_configure_undivided(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq)
Configure the specified clock to use the undivided input source.
Definition clocks.c:130
static void clock_gpio_init(uint gpio, uint src, float div)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.h:435
bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out)
Check if a given system clock frequency is valid/attainable.
Definition clocks.c:438
void set_sys_clock_48mhz(void)
Initialise the system clock to 48MHz.
Definition clocks.c:346
void clock_set_reported_hz(clock_handle_t clock, uint hz)
Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the cl...
Definition clocks.c:142
uint32_t clock_get_hz(clock_handle_t clock)
Get the current frequency of the specified clock.
Definition clocks.c:137
void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t div_frac16)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.c:245
static bool set_sys_clock_khz(uint32_t freq_khz, bool required)
Attempt to set a system clock frequency in khz.
Definition clocks.h:536
bool clock_configure_gpin(clock_handle_t clock, uint gpio, uint32_t src_freq, uint32_t freq)
Configure a clock to come from a gpio input.
Definition clocks.c:313
enum clock_num_rp2040 clock_num_t
Clock numbers on RP2040 (used as typedef clock_num_t)
uint32_t frequency_count_khz(uint src)
Measure a clocks frequency using the Frequency counter.
Definition clocks.c:147
bool check_sys_clock_hz(uint32_t freq_hz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out)
Check if a given system clock frequency is valid/attainable.
Definition clocks.c:417