7#ifndef _HARDWARE_CLOCKS_H
8#define _HARDWARE_CLOCKS_H
11#include "hardware/structs/clocks.h"
168#ifndef PLL_COMMON_REFDIV
170#define PLL_COMMON_REFDIV 1
174#ifndef PLL_SYS_REFDIV
176#ifdef PLL_COMMON_REFDIV
177#define PLL_SYS_REFDIV PLL_COMMON_REFDIV
179#define PLL_SYS_REFDIV 1
183#ifndef PLL_SYS_VCO_FREQ_HZ
185#ifdef PLL_SYS_VCO_FREQ_KHZ
186#define PLL_SYS_VCO_FREQ_HZ (PLL_SYS_VCO_FREQ_KHZ * KHZ)
190#if (SYS_CLK_HZ == 125 * MHZ || SYS_CLK_HZ == 150 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
193#ifndef PLL_SYS_VCO_FREQ_HZ
194#define PLL_SYS_VCO_FREQ_HZ (1500 * MHZ)
197#ifndef PLL_SYS_POSTDIV1
198#if SYS_CLK_HZ == 125 * MHZ
199#define PLL_SYS_POSTDIV1 6
201#define PLL_SYS_POSTDIV1 5
205#ifndef PLL_SYS_POSTDIV2
206#define PLL_SYS_POSTDIV2 2
210#if PICO_RP2040 && (SYS_CLK_HZ == 200 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_SYS_REFDIV == 1)
212#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
213#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 1
216#if SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST && !defined(SYS_CLK_VREG_VOLTAGE_MIN)
217#define SYS_CLK_VREG_VOLTAGE_MIN VREG_VOLTAGE_1_15
220#ifndef PLL_SYS_VCO_FREQ_HZ
221#define PLL_SYS_VCO_FREQ_HZ (1200 * MHZ)
223#ifndef PLL_SYS_POSTDIV1
224#define PLL_SYS_POSTDIV1 6
226#ifndef PLL_SYS_POSTDIV2
227#define PLL_SYS_POSTDIV2 1
230#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST
231#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST 0
236#ifndef SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US
237#define SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US 1000
240#if !defined(PLL_SYS_VCO_FREQ_HZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
241#error PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
245#ifndef PLL_USB_REFDIV
247#ifdef PLL_COMMON_REFDIV
248#define PLL_USB_REFDIV PLL_COMMON_REFDIV
250#define PLL_USB_REFDIV 1
254#ifndef PLL_USB_VCO_FREQ_HZ
256#ifdef PLL_USB_VCO_FREQ_KHZ
257#define PLL_USB_VCO_FREQ_HZ (PLL_USB_VCO_FREQ_KHZ * KHZ)
261#if (USB_CLK_HZ == 48 * MHZ) && (XOSC_HZ == 12 * MHZ) && (PLL_USB_REFDIV == 1)
264#ifndef PLL_USB_VCO_FREQ_HZ
265#define PLL_USB_VCO_FREQ_HZ (1200 * MHZ)
268#ifndef PLL_USB_POSTDIV1
269#define PLL_USB_POSTDIV1 5
272#ifndef PLL_USB_POSTDIV2
273#define PLL_USB_POSTDIV2 5
276#if !defined(PLL_USB_VCO_FREQ_HZ) || !defined(PLL_USB_POSTDIV1) || !defined(PLL_USB_POSTDIV2)
277#error PLL_USB_VCO_FREQ_HZ, PLL_USB_POSTDIV1 and PLL_USB_POSTDIV2 must all be specified when using custom clock setup.
281#ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS
282#ifdef PARAM_ASSERTIONS_ENABLED_CLOCKS
283#define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS PARAM_ASSERTIONS_ENABLED_CLOCKS
285#define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS 0
290#ifndef PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
291#define PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
320bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq);
346bool clock_configure_mhz(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq_mhz, uint32_t freq_mhz);
485static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac8) {
509 uint div_int = (uint)div;
510 const int frac_bit_count = REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC);
511#if PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
512 div += 0.5f / (1 << frac_bit_count);
514#if REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 16
515 uint16_t frac = (uint16_t)((div - (
float)div_int) * (1u << frac_bit_count));
517#elif REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 8
518 uint8_t frac = (uint8_t)((div - (
float)div_int) * (1u << frac_bit_count));
521#error unsupported number of fractional bits
563bool check_sys_clock_hz(uint32_t freq_hz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
574bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
588 uint vco, postdiv1, postdiv2;
592 }
else if (required) {
593 panic(
"System clock of %u Hz cannot be exactly achieved", freq_hz);
610 uint vco, postdiv1, postdiv2;
614 }
else if (required) {
615 panic(
"System clock of %u kHz cannot be exactly achieved", freq_khz);
621#define clock_dest_bitset_none() fixed_bitset_with_fill(clock_dest_bitset_t, NUM_CLOCK_DESTINATIONS, 0)
622#define clock_dest_bitset_all() fixed_bitset_with_fill(clock_dest_bitset_t, NUM_CLOCK_DESTINATIONS, 1)
624static inline clock_dest_bitset_t *clock_dest_bitset_clear(clock_dest_bitset_t *dests) {
629static inline clock_dest_bitset_t *clock_dest_bitset_add_all(clock_dest_bitset_t *dests) {
634static inline clock_dest_bitset_t *clock_dest_bitset_add(clock_dest_bitset_t *dests,
clock_dest_num_t dest) {
639static inline clock_dest_bitset_t *clock_dest_bitset_remove(clock_dest_bitset_t *dests,
clock_dest_num_t dest) {
644void clock_get_sleep_en_gate(clock_dest_bitset_t *clocks);
645void clock_gate_sleep_en(
const clock_dest_bitset_t *clocks);
647#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle) \
648 ((gpio) == 21 ? clk_gpout0 : \
649 ((gpio) == 23 ? clk_gpout1 : \
650 ((gpio) == 24 ? clk_gpout2 : \
651 ((gpio) == 25 ? clk_gpout3 : \
652 (default_clk_handle)))))
654#define GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350(gpio, default_clk_handle) \
655 ((gpio) == 13 ? clk_gpout0 : \
656 ((gpio) == 15 ? clk_gpout1 : \
657 (GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040(gpio, default_clk_handle))))
667#ifndef GPIO_TO_GPOUT_CLOCK_HANDLE
669#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2040
671#define GPIO_TO_GPOUT_CLOCK_HANDLE GPIO_TO_GPOUT_CLOCK_HANDLE_RP2350
static fixed_bitset_t * fixed_bitset_clear(fixed_bitset_t *bitset, uint bit_index)
Clear a single bit in the bitset.
Definition fixed_bitset.h:202
static fixed_bitset_t * fixed_bitset_set(fixed_bitset_t *bitset, uint bit_index)
Set a single bit in the bitset.
Definition fixed_bitset.h:188
static fixed_bitset_t * fixed_bitset_clear_all(fixed_bitset_t *bitset)
Clear all bits in the bitset.
Definition fixed_bitset.h:151
#define fixed_bitset_type(N)
Macro used to define a fixed-size bitset of a given size.
Definition fixed_bitset.h:48
static fixed_bitset_t * fixed_bitset_set_all(fixed_bitset_t *bitset)
Set all bits in the bitset.
Definition fixed_bitset.h:162
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:150
static float frequency_count_mhz(uint src)
Measure a clock's frequency using the frequency counter.
Definition clocks.h:416
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:480
static bool set_sys_clock_hz(uint32_t freq_hz, bool required)
Attempt to set a system clock frequency in hz.
Definition clocks.h:587
enum clock_dest_num_rp2350 clock_dest_num_t
Clock destination numbers on RP2350 (used as typedef clock_dest_num_t).
void clock_stop(clock_handle_t clock)
Stop the specified clock.
Definition clocks.c:33
bool clock_configure_mhz(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq_mhz, uint32_t freq_mhz)
Configure the specified clock with 1MHz accuracy.
Definition clocks.c:126
void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2)
Initialise the system clock.
Definition clocks.c:391
#define GPIO_TO_GPOUT_CLOCK_HANDLE
Returns the GPOUT clock number associated with a particular GPIO if there is one, or default_clk_hand...
Definition clocks.h:671
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:99
void(* resus_callback_t)(void)
Resus callback function type.
Definition clocks.h:426
void clocks_enable_resus(resus_callback_t resus_callback)
Enable the resus function. Restarts clk_sys if it is accidentally stopped.
Definition clocks.c:245
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:154
static void clock_gpio_init(uint gpio, uint src, float div)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.h:507
enum clock_num_rp2350 clock_num_t
Clock numbers on RP2350 (used as typedef clock_num_t).
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:449
void set_sys_clock_48mhz(void)
Initialise the system clock to 48MHz.
Definition clocks.c:357
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:166
uint32_t clock_get_hz(clock_handle_t clock)
Get the current frequency of the specified clock.
Definition clocks.c:161
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:269
static bool set_sys_clock_khz(uint32_t freq_khz, bool required)
Attempt to set a system clock frequency in khz.
Definition clocks.h:609
static clock_handle_t gpio_to_gpout_clock_handle(uint gpio, clock_handle_t default_clk_handle)
return the associated GPOUT clock for a given GPIO if any
Definition clocks.h:680
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:324
uint32_t frequency_count_khz(uint src)
Measure a clock's frequency using the frequency counter.
Definition clocks.c:171
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:428