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
14 extern "C" {
15 #endif
16 
17 /** \file hardware/clocks.h
18  *  \defgroup hardware_clocks hardware_clocks
19  *
20  * \brief Clock Management API
21  *
22  * This API provides a high level interface to the clock functions.
23  *
24  * The clocks block provides independent clocks to on-chip and external components. It takes inputs from a variety of clock
25  * sources allowing the user to trade off performance against cost, board area and power consumption. From these sources
26  * it uses multiple clock generators to provide the required clocks. This architecture allows the user flexibility to start and
27  * stop clocks independently and to vary some clock frequencies whilst maintaining others at their optimum frequencies
28  *
29  * Please refer to the appropriate datasheet for more details on the RP-series clocks.
30  *
31  * The clock source depends on which clock you are attempting to configure. The first table below shows main clock sources. If
32  * you are not setting the Reference clock or the System clock, or you are specifying that one of those two will be using an auxiliary
33  * clock source, then you will need to use one of the entries from the subsequent tables.
34  *
35  * * \if rp2040_specific
36  * On RP2040 the clock sources are:
37  *
38  * **Main Clock Sources**
39  *
40  * Source | Reference Clock | System Clock
41  * -------|-----------------|---------
42  * ROSC      | CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH     |  |
43  * Auxiliary | CLOCKS_CLK_REF_CTRL_SRC_VALUE_CLKSRC_CLK_REF_AUX | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX
44  * XOSC      | CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC        |  |
45  * Reference |                                                  | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF
46  *
47  * **Auxiliary Clock Sources**
48  *
49  * The auxiliary clock sources available for use in the configure function depend on which clock is being configured. The following table
50  * describes the available values that can be used. Note that for clk_gpout[x], x can be 0-3.
51  *
52  *
53  * Aux Source | clk_gpout[x] | clk_ref | clk_sys
54  * -----------|------------|---------|--------
55  * System PLL | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS
56  * GPIO in 0  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0   | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0  | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0
57  * GPIO in 1  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1   | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1  | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1
58  * USB PLL    | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB| CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB
59  * ROSC       | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_ROSC_CLKSRC    |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC
60  * XOSC       | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_XOSC_CLKSRC    |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_XOSC_CLKSRC
61  * System clock | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_SYS      | | |
62  * USB Clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_USB        | | |
63  * ADC clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_ADC        | | |
64  * RTC Clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_RTC        | | |
65  * Ref clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_REF        | | |
66  *
67  * Aux Source |  clk_peri | clk_usb | clk_adc
68  * -----------|-----------|---------|--------
69  * System PLL | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS    | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS
70  * GPIO in 0  | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0      | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0   | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0
71  * GPIO in 1  | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1      | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1   | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1
72  * USB PLL    | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB    | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB
73  * ROSC       | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH    | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH
74  * XOSC       | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_XOSC_CLKSRC       | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_XOSC_CLKSRC    | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC
75  * System clock | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS         | | |
76  *
77  * Aux Source | clk_rtc
78  * -----------|----------
79  * System PLL |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS
80  * GPIO in 0  |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0
81  * GPIO in 1  |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1
82  * USB PLL    |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB
83  * ROSC       |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH
84  * XOSC       |  CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC
85  * \endif
86  *
87  * \if rp2350_specific
88  * On RP2350 the clock sources are:
89  * * **Main Clock Sources**
90  *
91  * Source | Reference Clock | System Clock
92  * -------|-----------------|---------
93  * ROSC      | CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH     |  |
94  * Auxiliary | CLOCKS_CLK_REF_CTRL_SRC_VALUE_CLKSRC_CLK_REF_AUX | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX
95  * XOSC      | CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC        |  |
96  * LPOSC     | CLOCKS_CLK_REF_CTRL_SRC_VALUE_LPOSC_CLKSRC | |
97  * Reference |                                                  | CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF
98  *
99  * **Auxiliary Clock Sources**
100  *
101  * The auxiliary clock sources available for use in the configure function depend on which clock is being configured. The following table
102  * describes the available values that can be used. Note that for clk_gpout[x], x can be 0-3.
103  *
104  *
105  * Aux Source | clk_gpout[x] | clk_ref | clk_sys
106  * -----------|------------|---------|--------
107  * System PLL | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS
108  * GPIO in 0  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0   | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0  | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0
109  * GPIO in 1  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1   | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1  | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1
110  * USB PLL    | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB | CLOCKS_CLK_REF_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB| CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB
111  * ROSC       | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_ROSC_CLKSRC    |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC
112  * XOSC       | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_XOSC_CLKSRC    |                                                | CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_XOSC_CLKSRC
113  * LPOSC      | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_LPOSC_CLKSRC   | | |
114  * System clock | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_SYS      | | |
115  * USB Clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_USB        | | |
116  * ADC clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_ADC        | | |
117  * REF clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_REF        | | |
118  * PERI clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_PERI      | | |
119  * HSTX clock  | CLOCKS_CLK_GPOUTx_CTRL_AUXSRC_VALUE_CLK_PERI      | | |
120 
121  *
122  * Aux Source |  clk_peri | clk_hstx | clk_usb | clk_adc
123  * -----------|-----------|----------|---------|--------
124  * System PLL | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS    | CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS
125  * GPIO in 0  | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0      |  | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0   | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN0
126  * GPIO in 1  | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1      |  | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1   | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_GPIN1
127  * USB PLL    | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB    | CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB
128  * ROSC       | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH    |  | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH
129  * XOSC       | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_XOSC_CLKSRC       |  | CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_XOSC_CLKSRC    | CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC
130  * System clock | CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS         | CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS | | |
131  * \endif
132 
133  *
134  * \section clock_example Example
135  * \addtogroup hardware_clocks
136  * \include hello_48MHz.c
137  */
138 
139 #define PICO_KHZ 1000
140 #define PICO_MHZ 1000000
141 
142 // \tag::pll_settings[]
143 // There are two PLLs in RP-series microcontrollers:
144 // 1. The 'SYS PLL' generates the system clock, the frequency is defined by `SYS_CLK_KHZ`.
145 // 2. The 'USB PLL' generates the USB clock, the frequency is defined by `USB_CLK_KHZ`.
146 //
147 // The two PLLs use the crystal oscillator output directly as their reference frequency input; the PLLs reference
148 // frequency cannot be reduced by the dividers present in the clocks block. The crystal frequency is defined by `XOSC_HZ` (or
149 // `XOSC_KHZ` or `XOSC_MHZ`).
150 //
151 // The system's default definitions are correct for the above frequencies with a 12MHz
152 // crystal frequency.  If different frequencies are required, these must be defined in
153 // the board configuration file together with the revised PLL settings
154 // Use `vcocalc.py` to check and calculate new PLL settings if you change any of these frequencies.
155 //
156 // Default PLL configuration RP2040:
157 //                   REF     FBDIV VCO            POSTDIV
158 // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz
159 // PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 =  48MHz
160 //
161 // Default PLL configuration RP2350:
162 //                   REF     FBDIV VCO            POSTDIV
163 // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 5 / 2 = 150MHz
164 // PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 =  48MHz
165 // \end::pll_settings[]
166 
167 #ifndef PLL_COMMON_REFDIV
168 // backwards compatibility, but now deprecated
169 #define PLL_COMMON_REFDIV 1
170 #endif
171 
172 // PICO_CONFIG: PLL_SYS_REFDIV, PLL reference divider setting for PLL_SYS, type=int, default=1, advanced=true, group=hardware_clocks
173 #ifndef PLL_SYS_REFDIV
174 // backwards compatibility with deprecated PLL_COMMON_REFDIV
175 #ifdef PLL_COMMON_REFDIV
176 #define PLL_SYS_REFDIV                   PLL_COMMON_REFDIV
177 #else
178 #define PLL_SYS_REFDIV                   1
179 #endif
180 #endif
181 
182 #ifndef PLL_SYS_VCO_FREQ_HZ
183 // For backwards compatibility define PLL_SYS_VCO_FREQ_HZ if PLL_SYS_VCO_FREQ_KHZ is defined
184 #ifdef PLL_SYS_VCO_FREQ_KHZ
185 #define PLL_SYS_VCO_FREQ_HZ                (PLL_SYS_VCO_FREQ_KHZ * PICO_KHZ)
186 #endif
187 #endif
188 
189 #if (SYS_CLK_HZ == 125 * PICO_MHZ || SYS_CLK_HZ == 150 * PICO_MHZ) && (XOSC_HZ == 12 * PICO_MHZ) && (PLL_SYS_REFDIV == 1)
190 // PLL settings for standard 125/150 MHz system clock.
191 // PICO_CONFIG: PLL_SYS_VCO_FREQ_HZ, System clock PLL frequency, type=int, default=(1500 * PICO_MHZ), advanced=true, group=hardware_clocks
192 #ifndef PLL_SYS_VCO_FREQ_HZ
193 #define PLL_SYS_VCO_FREQ_HZ                (1500 * PICO_MHZ)
194 #endif
195 // PICO_CONFIG: PLL_SYS_POSTDIV1, System clock PLL post divider 1 setting, type=int, default=6 on RP2040 or 5 on RP2350, advanced=true, group=hardware_clocks
196 #ifndef PLL_SYS_POSTDIV1
197 #if SYS_CLK_HZ == 125 * PICO_MHZ
198 #define PLL_SYS_POSTDIV1                    6
199 #else
200 #define PLL_SYS_POSTDIV1                    5
201 #endif
202 #endif
203 // PICO_CONFIG: PLL_SYS_POSTDIV2, System clock PLL post divider 2 setting, type=int, default=2, advanced=true, group=hardware_clocks
204 #ifndef PLL_SYS_POSTDIV2
205 #define PLL_SYS_POSTDIV2                    2
206 #endif
207 #endif // SYS_CLK_KHZ == 125000 && XOSC_KHZ == 12000 && PLL_COMMON_REFDIV == 1
208 
209 #if !defined(PLL_SYS_VCO_FREQ_HZ) || !defined(PLL_SYS_POSTDIV1) || !defined(PLL_SYS_POSTDIV2)
210 #error PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1 and PLL_SYS_POSTDIV2 must all be specified when using custom clock setup
211 #endif
212 
213 // PICO_CONFIG: PLL_USB_REFDIV, PLL reference divider setting for PLL_USB, type=int, default=1, advanced=true, group=hardware_clocks
214 #ifndef PLL_USB_REFDIV
215 // backwards compatibility with deprecated PLL_COMMON_REFDIV
216 #ifdef PLL_COMMON_REFDIV
217 #define PLL_USB_REFDIV                   PLL_COMMON_REFDIV
218 #else
219 #define PLL_USB_REFDIV                   1
220 #endif
221 #endif
222 
223 #ifndef PLL_USB_VCO_FREQ_HZ
224 // For backwards compatibility define PLL_USB_VCO_FREQ_HZ if PLL_USB_VCO_FREQ_KHZ is defined
225 #ifdef PLL_USB_VCO_FREQ_KHZ
226 #define PLL_USB_VCO_FREQ_HZ                 (PLL_USB_VCO_FREQ_KHZ * PICO_KHZ)
227 #endif
228 #endif
229 
230 #if (USB_CLK_HZ == 48 * PICO_MHZ) && (XOSC_HZ == 12 * PICO_MHZ) && (PLL_USB_REFDIV == 1)
231 // PLL settings for a USB clock of 48MHz.
232 // PICO_CONFIG: PLL_USB_VCO_FREQ_HZ, USB clock PLL frequency, type=int, default=(1200 * PICO_MHZ), advanced=true, group=hardware_clocks
233 #ifndef PLL_USB_VCO_FREQ_HZ
234 #define PLL_USB_VCO_FREQ_HZ                 (1200 * PICO_MHZ)
235 #endif
236 // PICO_CONFIG: PLL_USB_POSTDIV1, USB clock PLL post divider 1 setting, type=int, default=5, advanced=true, group=hardware_clocks
237 #ifndef PLL_USB_POSTDIV1
238 #define PLL_USB_POSTDIV1                    5
239 #endif
240 // PICO_CONFIG: PLL_USB_POSTDIV2, USB clock PLL post divider 2 setting, type=int, default=5, advanced=true, group=hardware_clocks
241 #ifndef PLL_USB_POSTDIV2
242 #define PLL_USB_POSTDIV2                    5
243 #endif
244 #endif // USB_CLK_HZ == 48000000 && XOSC_HZ == 12000000 && PLL_COMMON_REFDIV == 1
245 #if !defined(PLL_USB_VCO_FREQ_HZ) || !defined(PLL_USB_POSTDIV1) || !defined(PLL_USB_POSTDIV2)
246 #error PLL_USB_VCO_FREQ_HZ, PLL_USB_POSTDIV1 and PLL_USB_POSTDIV2 must all be specified when using custom clock setup.
247 #endif
248 
249 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS, Enable/disable assertions in the hardware_clocks module, type=bool, default=0, group=hardware_clocks
250 #ifndef PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS
251 #ifdef PARAM_ASSERTIONS_ENABLED_CLOCKS // backwards compatibility with SDK < 2.0.0
252 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS PARAM_ASSERTIONS_ENABLED_CLOCKS
253 #else
254 #define PARAM_ASSERTIONS_ENABLED_HARDWARE_CLOCKS 0
255 #endif
256 #endif
257 
258  // PICO_CONFIG: PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST, True if floating point GPIO clock divisors should be rounded to the nearest possible clock divisor rather than rounding down, type=bool, default=PICO_CLKDIV_ROUND_NEAREST, group=hardware_clocks
259 #ifndef PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
260 #define PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST PICO_CLKDIV_ROUND_NEAREST
261 #endif
262 
263 typedef clock_num_t clock_handle_t;
264 
265 /*! \brief Configure the specified clock
266  *  \ingroup hardware_clocks
267  *
268  * See the tables in the description for details on the possible values for clock sources.
269  *
270  * \param clock The clock to configure
271  * \param src The main clock source, can be 0.
272  * \param auxsrc The auxiliary clock source, which depends on which clock is being set. Can be 0
273  * \param src_freq Frequency of the input clock source
274  * \param freq Requested frequency
275  */
276 bool clock_configure(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq);
277 
278 /*! \brief Configure the specified clock to use the undividded input source
279  *  \ingroup hardware_clocks
280  *
281  * See the tables in the description for details on the possible values for clock sources.
282  *
283  * \param clock The clock to configure
284  * \param src The main clock source, can be 0.
285  * \param auxsrc The auxiliary clock source, which depends on which clock is being set. Can be 0
286  * \param src_freq Frequency of the input clock source
287  */
288 void clock_configure_undivided(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq);
289 
290 /*! \brief Configure the specified clock to use the undividded input source
291  *  \ingroup hardware_clocks
292  *
293  * See the tables in the description for details on the possible values for clock sources.
294  *
295  * \param clock The clock to configure
296  * \param src The main clock source, can be 0.
297  * \param auxsrc The auxiliary clock source, which depends on which clock is being set. Can be 0
298  * \param src_freq Frequency of the input clock source
299  * \param int_divider an integer divider
300  */
301 void clock_configure_int_divider(clock_handle_t clock, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t int_divider);
302 
303 /*! \brief Stop the specified clock
304  *  \ingroup hardware_clocks
305  *
306  * \param clock The clock to stop
307  */
308 void clock_stop(clock_handle_t clock);
309 
310 /*! \brief Get the current frequency of the specified clock
311  *  \ingroup hardware_clocks
312  *
313  * \param clock Clock
314  * \return Clock frequency in Hz
315  */
316 uint32_t clock_get_hz(clock_handle_t clock);
317 
318 /*! \brief Measure a clocks frequency using the Frequency counter.
319  *  \ingroup hardware_clocks
320  *
321  * Uses the inbuilt frequency counter to measure the specified clocks frequency.
322  * Currently, this function is accurate to +-1KHz. See the datasheet for more details.
323  */
324 uint32_t frequency_count_khz(uint src);
325 
326 /*! \brief Set the "current frequency" of the clock as reported by clock_get_hz without actually changing the clock
327  *  \ingroup hardware_clocks
328  *
329  * \see clock_get_hz()
330  */
331 void clock_set_reported_hz(clock_handle_t clock, uint hz);
332 
333 /// \tag::frequency_count_mhz[]
frequency_count_mhz(uint src)334 static inline float frequency_count_mhz(uint src) {
335     return ((float) (frequency_count_khz(src))) / PICO_KHZ;
336 }
337 /// \end::frequency_count_mhz[]
338 
339 /*! \brief Resus callback function type.
340  *  \ingroup hardware_clocks
341  *
342  * User provided callback for a resus event (when clk_sys is stopped by the programmer and is restarted for them).
343  */
344 typedef void (*resus_callback_t)(void);
345 
346 /*! \brief Enable the resus function. Restarts clk_sys if it is accidentally stopped.
347  *  \ingroup hardware_clocks
348  *
349  * The resuscitate function will restart the system clock if it falls below a certain speed (or stops). This
350  * could happen if the clock source the system clock is running from stops. For example if a PLL is stopped.
351  *
352  * \param resus_callback a function pointer provided by the user to call if a resus event happens.
353  */
354 void clocks_enable_resus(resus_callback_t resus_callback);
355 
356 /*! \brief Output an optionally divided clock to the specified gpio pin.
357  *  \ingroup hardware_clocks
358  *
359  * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.
360  * \param src  The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.
361  * \param div_int  The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040
362  *                 and 1..2^16-1 on RP2350
363  * \param div_frac16 The fractional part of the value to divide the source clock by. This is in range of 0..65535 (/65536).
364  */
365 void clock_gpio_init_int_frac16(uint gpio, uint src, uint32_t div_int, uint16_t div_frac16);
366 
367 /*! \brief Output an optionally divided clock to the specified gpio pin.
368  *  \ingroup hardware_clocks
369  *
370  * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.
371  * \param src  The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.
372  * \param div_int  The integer part of the value to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock. This is in range of 1..2^24-1 on RP2040
373  *                 and 1..2^16-1 on RP2350
374  * \param div_frac8 The fractional part of the value to divide the source clock by. This is in range of 0..255 (/256).
375  */
clock_gpio_init_int_frac8(uint gpio,uint src,uint32_t div_int,uint8_t div_frac8)376 static inline void clock_gpio_init_int_frac8(uint gpio, uint src, uint32_t div_int, uint8_t div_frac8) {
377     return clock_gpio_init_int_frac16(gpio, src, div_int, (uint16_t)(div_frac8 << 8u));
378 }
379 
380 // backwards compatibility
clock_gpio_init_int_frac(uint gpio,uint src,uint32_t div_int,uint8_t div_frac8)381 static inline void clock_gpio_init_int_frac(uint gpio, uint src, uint32_t div_int, uint8_t div_frac8) {
382     return clock_gpio_init_int_frac8(gpio, src, div_int, div_frac8);
383 }
384 
385 /*! \brief Output an optionally divided clock to the specified gpio pin.
386  *  \ingroup hardware_clocks
387  *
388  * \param gpio The GPIO pin to output the clock to. Valid GPIOs are: 21, 23, 24, 25. These GPIOs are connected to the GPOUT0-3 clock generators.
389  * \param src  The source clock. See the register field CLOCKS_CLK_GPOUT0_CTRL_AUXSRC for a full list. The list is the same for each GPOUT clock generator.
390  * \param div  The float amount to divide the source clock by. This is useful to not overwhelm the GPIO pin with a fast clock.
391  */
clock_gpio_init(uint gpio,uint src,float div)392 static inline void clock_gpio_init(uint gpio, uint src, float div)
393 {
394     uint div_int = (uint)div;
395     const int frac_bit_count = REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC);
396 #if PICO_CLOCK_GPIO_CLKDIV_ROUND_NEAREST
397     div += 0.5f / (1 << frac_bit_count); // round to the nearest fraction
398 #endif
399 #if REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 16
400     uint16_t frac = (uint16_t)((div - (float)div_int) * (1u << frac_bit_count));
401     clock_gpio_init_int_frac16(gpio, src, div_int, frac);
402 #elif REG_FIELD_WIDTH(CLOCKS_CLK_GPOUT0_DIV_FRAC) == 8
403     uint8_t frac = (uint8_t)((div - (float)div_int) * (1u << frac_bit_count));
404     clock_gpio_init_int_frac8(gpio, src, div_int, frac);
405 #else
406 #error unsupported number of fractional bits
407 #endif
408 }
409 
410 /*! \brief Configure a clock to come from a gpio input
411  *  \ingroup hardware_clocks
412  *
413  * \param clock The clock to configure
414  * \param gpio The GPIO pin to run the clock from. Valid GPIOs are: 20 and 22.
415  * \param src_freq Frequency of the input clock source
416  * \param freq Requested frequency
417  */
418 bool clock_configure_gpin(clock_handle_t clock, uint gpio, uint32_t src_freq, uint32_t freq);
419 
420 /*! \brief Initialise the system clock to 48MHz
421  *  \ingroup hardware_clocks
422  *
423  *  Set the system clock to 48MHz, and set the peripheral clock to match.
424  */
425 void set_sys_clock_48mhz(void);
426 
427 /*! \brief Initialise the system clock
428  *  \ingroup hardware_clocks
429  *
430  * \param vco_freq The voltage controller oscillator frequency to be used by the SYS PLL
431  * \param post_div1 The first post divider for the SYS PLL
432  * \param post_div2 The second post divider for the SYS PLL.
433  *
434  * See the PLL documentation in the datasheet for details of driving the PLLs.
435  */
436 void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2);
437 
438 /*! \brief Check if a given system clock frequency is valid/attainable
439  *  \ingroup hardware_clocks
440  *
441  * \param freq_hz Requested frequency
442  * \param vco_freq_out On success, the voltage controlled oscillator frequency to be used by the SYS PLL
443  * \param post_div1_out On success, The first post divider for the SYS PLL
444  * \param post_div2_out On success, The second post divider for the SYS PLL.
445  * @return true if the frequency is possible and the output parameters have been written.
446  */
447 bool check_sys_clock_hz(uint32_t freq_hz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
448 
449 /*! \brief Check if a given system clock frequency is valid/attainable
450  *  \ingroup hardware_clocks
451  *
452  * \param freq_khz Requested frequency
453  * \param vco_freq_out On success, the voltage controlled oscillator frequency to be used by the SYS PLL
454  * \param post_div1_out On success, The first post divider for the SYS PLL
455  * \param post_div2_out On success, The second post divider for the SYS PLL.
456  * @return true if the frequency is possible and the output parameters have been written.
457  */
458 bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
459 
460 /*! \brief Attempt to set a system clock frequency in hz
461  *  \ingroup hardware_clocks
462  *
463  * Note that not all clock frequencies are possible; it is preferred that you
464  * use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters
465  * for use with set_sys_clock_pll
466  *
467  * \param freq_hz Requested frequency
468  * \param required if true then this function will assert if the frequency is not attainable.
469  * \return true if the clock was configured
470  */
set_sys_clock_hz(uint32_t freq_hz,bool required)471 static inline bool set_sys_clock_hz(uint32_t freq_hz, bool required) {
472     uint vco, postdiv1, postdiv2;
473     if (check_sys_clock_hz(freq_hz, &vco, &postdiv1, &postdiv2)) {
474         set_sys_clock_pll(vco, postdiv1, postdiv2);
475         return true;
476     } else if (required) {
477         panic("System clock of %u Hz cannot be exactly achieved", freq_hz);
478     }
479     return false;
480 }
481 
482 /*! \brief Attempt to set a system clock frequency in khz
483  *  \ingroup hardware_clocks
484  *
485  * Note that not all clock frequencies are possible; it is preferred that you
486  * use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters
487  * for use with set_sys_clock_pll
488  *
489  * \param freq_khz Requested frequency
490  * \param required if true then this function will assert if the frequency is not attainable.
491  * \return true if the clock was configured
492  */
set_sys_clock_khz(uint32_t freq_khz,bool required)493 static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) {
494     uint vco, postdiv1, postdiv2;
495     if (check_sys_clock_khz(freq_khz, &vco, &postdiv1, &postdiv2)) {
496         set_sys_clock_pll(vco, postdiv1, postdiv2);
497         return true;
498     } else if (required) {
499         panic("System clock of %u kHz cannot be exactly achieved", freq_khz);
500     }
501     return false;
502 }
503 
504 #ifdef __cplusplus
505 }
506 #endif
507 
508 #endif
509