1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _HARDWARE_PLL_H
8 #define _HARDWARE_PLL_H
9 
10 #include "pico.h"
11 #include "hardware/structs/pll.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /** \file hardware/pll.h
18  *  \defgroup hardware_pll hardware_pll
19  *
20  * \brief Phase Locked Loop control APIs
21  *
22  * There are two PLLs in RP2040. They are:
23  *   - pll_sys - Used to generate up to a 133MHz system clock
24  *   - pll_usb - Used to generate a 48MHz USB reference clock
25  *
26  * For details on how the PLLs are calculated, please refer to the RP2040 datasheet.
27  */
28 
29 typedef pll_hw_t *PLL;
30 
31 #define pll_sys pll_sys_hw
32 #define pll_usb pll_usb_hw
33 
34 #ifndef PICO_PLL_VCO_MIN_FREQ_HZ
35 #ifdef PICO_PLL_VCO_MIN_FREQ_MHZ
36 #define PICO_PLL_VCO_MIN_FREQ_HZ (PICO_PLL_VCO_MIN_FREQ_MHZ * PICO_MHZ)
37 #elif defined(PICO_PLL_VCO_MIN_FREQ_KHZ)
38 #define PICO_PLL_VCO_MIN_FREQ_HZ (PICO_PLL_VCO_MIN_FREQ_KHZ * PICO_KHZ)
39 #else
40 #define PICO_PLL_VCO_MIN_FREQ_HZ (750 * PICO_MHZ)
41 #endif
42 #endif
43 
44 #ifndef PICO_PLL_VCO_MAX_FREQ_HZ
45 #ifdef PICO_PLL_VCO_MAX_FREQ_MHZ
46 #define PICO_PLL_VCO_MAX_FREQ_HZ (PICO_PLL_VCO_MAX_FREQ_MHZ * PICO_MHZ)
47 #elif defined(PICO_PLL_VCO_MAX_FREQ_KHZ)
48 #define PICO_PLL_VCO_MAX_FREQ_HZ (PICO_PLL_VCO_MAX_FREQ_KHZ * PICO_KHZ)
49 #else
50 #define PICO_PLL_VCO_MAX_FREQ_HZ (1600 * PICO_MHZ)
51 #endif
52 #endif
53 
54 /*! \brief Initialise specified PLL.
55  *  \ingroup hardware_pll
56  * \param pll pll_sys or pll_usb
57  * \param ref_div Input clock divider.
58  * \param vco_freq  Requested output from the VCO (voltage controlled oscillator)
59  * \param post_div1 Post Divider 1 - range 1-7. Must be >= post_div2
60  * \param post_div2 Post Divider 2 - range 1-7
61  */
62 void pll_init(PLL pll, uint ref_div, uint vco_freq, uint post_div1, uint post_div2);
63 
64 /*! \brief Release/uninitialise specified PLL.
65  *  \ingroup hardware_pll
66  *
67  * This will turn off the power to the specified PLL. Note this function does not currently check if
68  * the PLL is in use before powering it off so should be used with care.
69  *
70  * \param pll pll_sys or pll_usb
71  */
72 void pll_deinit(PLL pll);
73 
74 /**
75  * \def PLL_RESET_NUM(pll)
76  * \ingroup hardware_pll
77  * \hideinitializer
78  * \brief Returns the \ref reset_num_t used to reset a given PLL instance
79  *
80  * Note this macro is intended to resolve at compile time, and does no parameter checking
81  */
82 #ifndef PLL_RESET_NUM
83 #define PLL_RESET_NUM(pll) ((pll_usb_hw == (pll)) ? RESET_PLL_USB : RESET_PLL_SYS)
84 #endif
85 
86 #ifdef __cplusplus
87 }
88 #endif
89 
90 #endif
91