@web-font-path: "roboto-debian.css";
Loading...
Searching...
No Matches
clocks.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_CLOCKS_H
8#define _HARDWARE_CLOCKS_H
9
10#include "pico.h"
11#include "hardware/structs/clocks.h"
12
13#ifdef __cplusplus
14extern "C" {
15#endif
16
89#define KHZ 1000
90#define MHZ 1000000
91
93//
94// There are two PLLs in RP2040:
95// 1. The 'SYS PLL' generates the 125MHz system clock, the frequency is defined by `SYS_CLK_KHZ`.
96// 2. The 'USB PLL' generates the 48MHz USB clock, the frequency is defined by `USB_CLK_KHZ`.
97//
98// The two PLLs use the crystal oscillator output directly as their reference frequency input; the PLLs reference
99// frequency cannot be reduced by the dividers present in the clocks block. The crystal frequency is defined by `XOSC_KHZ` or
100// `XOSC_MHZ`.
101//
102// The system's default definitions are correct for the above frequencies with a 12MHz
103// crystal frequency. If different frequencies are required, these must be defined in
104// the board configuration file together with the revised PLL settings
105// Use `vcocalc.py` to check and calculate new PLL settings if you change any of these frequencies.
106//
107// Default PLL configuration:
108// REF FBDIV VCO POSTDIV
109// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz
110// PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz
112
113// PICO_CONFIG: PLL_COMMON_REFDIV, PLL reference divider setting - used for both PLLs, type=int, default=1, advanced=true, group=hardware_clocks
114#ifndef PLL_COMMON_REFDIV
115#define PLL_COMMON_REFDIV 1
116#endif
117
118#if (SYS_CLK_KHZ == 125000) && (XOSC_KHZ == 12000) && (PLL_COMMON_REFDIV == 1)
119// PLL settings for standard 125 MHz system clock.
120// PICO_CONFIG: PLL_SYS_VCO_FREQ_KHZ, System clock PLL frequency, type=int, default=1500 * KHZ, advanced=true, group=hardware_clocks
121#ifndef PLL_SYS_VCO_FREQ_KHZ
122#define PLL_SYS_VCO_FREQ_KHZ (1500 * KHZ)
123#endif
124// PICO_CONFIG: PLL_SYS_POSTDIV1, System clock PLL post divider 1 setting, type=int, default=6, advanced=true, group=hardware_clocks
125#ifndef PLL_SYS_POSTDIV1
126#define PLL_SYS_POSTDIV1 6
127#endif
128// PICO_CONFIG: PLL_SYS_POSTDIV2, System clock PLL post divider 2 setting, type=int, default=2, advanced=true, group=hardware_clocks
129#ifndef PLL_SYS_POSTDIV2
130#define PLL_SYS_POSTDIV2 2
131#endif
132#endif // SYS_CLK_KHZ == 125000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
133#if !defined(PLL_SYS_VCO_FREQ_KHZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
134#error PLL_SYS_VCO_FREQ_KHZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
135#endif
136
137#if (USB_CLK_KHZ == 48000) && (XOSC_KHZ == 12000) && (PLL_COMMON_REFDIV == 1)
138// PLL settings for a USB clock of 48MHz.
139// PICO_CONFIG: PLL_USB_VCO_FREQ_KHZ, USB clock PLL frequency, type=int, default=1200 * KHZ, advanced=true, group=hardware_clocks
140#ifndef PLL_USB_VCO_FREQ_KHZ
141#define PLL_USB_VCO_FREQ_KHZ (1200 * KHZ)
142#endif
143// PICO_CONFIG: PLL_USB_POSTDIV1, USB clock PLL post divider 1 setting, type=int, default=5, advanced=true, group=hardware_clocks
144#ifndef PLL_USB_POSTDIV1
145#define PLL_USB_POSTDIV1 5
146#endif
147// PICO_CONFIG: PLL_USB_POSTDIV2, USB clock PLL post divider 2 setting, type=int, default=5, advanced=true, group=hardware_clocks
148#ifndef PLL_USB_POSTDIV2
149#define PLL_USB_POSTDIV2 5
150#endif
151#endif // USB_CLK_KHZ == 48000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
152#if !defined(PLL_USB_VCO_FREQ_KHZ) || !defined(PLL_USB_POSTDIV1) || !defined(PLL_USB_POSTDIV2)
153#error PLL_USB_VCO_FREQ_KHZ, PLL_USB_POSTDIV1 and PLL_USB_POSTDIV2 must all be specified when using custom clock setup.
154#endif
155
156// PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_CLOCKS, Enable/disable assertions in the clocks module, type=bool, default=0, group=hardware_clocks
157#ifndef PARAM_ASSERTIONS_ENABLED_CLOCKS
158#define PARAM_ASSERTIONS_ENABLED_CLOCKS 0
159#endif
160
166void clocks_init(void);
167
179bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq);
180
186void clock_stop(enum clock_index clk_index);
187
194uint32_t clock_get_hz(enum clock_index clk_index);
195
202uint32_t frequency_count_khz(uint src);
203
209void clock_set_reported_hz(enum clock_index clk_index, uint hz);
210
212static inline float frequency_count_mhz(uint src) {
213 return ((float) (frequency_count_khz(src))) / KHZ;
214}
216
222typedef void (*resus_callback_t)(void);
223
232void clocks_enable_resus(resus_callback_t resus_callback);
233
242void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac);
243
251static inline void clock_gpio_init(uint gpio, uint src, float div)
252{
253 uint div_int = (uint)div;
254 uint8_t frac = (uint8_t)((div - (float)div_int) * (1u << CLOCKS_CLK_GPOUT0_DIV_INT_LSB));
255 clock_gpio_init_int_frac(gpio, src, div_int, frac);
256}
257
266bool clock_configure_gpin(enum clock_index clk_index, uint gpio, uint32_t src_freq, uint32_t freq);
267
268
269#ifdef __cplusplus
270}
271#endif
272
273#endif
void clock_stop(enum clock_index clk_index)
Stop the specified clock.
Definition clocks.c:41
void(* resus_callback_t)(void)
Resus callback function type.
Definition clocks.h:222
void clocks_enable_resus(resus_callback_t resus_callback)
Enable the resus function. Restarts clk_sys if it is accidentally stopped.
Definition clocks.c:286
static void clock_gpio_init(uint gpio, uint src, float div)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.h:251
clock_index
Enumeration identifying a hardware clock.
Definition clocks.h:27
bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq)
Configure the specified clock.
Definition clocks.c:48
bool clock_configure_gpin(enum clock_index clk_index, uint gpio, uint32_t src_freq, uint32_t freq)
Configure a clock to come from a gpio input.
Definition clocks.c:357
void clocks_init(void)
Initialise the clock hardware.
Definition clocks.c:121
uint32_t clock_get_hz(enum clock_index clk_index)
Get the current frequency of the specified clock.
Definition clocks.c:201
uint32_t frequency_count_khz(uint src)
Measure a clocks frequency using the Frequency counter.
Definition clocks.c:211
void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac)
Output an optionally divided clock to the specified gpio pin.
Definition clocks.c:310
void clock_set_reported_hz(enum clock_index clk_index, uint hz)
Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the cl...
Definition clocks.c:206