1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald * \file
3*1b2596b5SMatthias Ringwald *
4*1b2596b5SMatthias Ringwald * \brief Chip-specific system clock management functions.
5*1b2596b5SMatthias Ringwald *
6*1b2596b5SMatthias Ringwald * Copyright (c) 2015 Atmel Corporation. All rights reserved.
7*1b2596b5SMatthias Ringwald *
8*1b2596b5SMatthias Ringwald * \asf_license_start
9*1b2596b5SMatthias Ringwald *
10*1b2596b5SMatthias Ringwald * \page License
11*1b2596b5SMatthias Ringwald *
12*1b2596b5SMatthias Ringwald * Redistribution and use in source and binary forms, with or without
13*1b2596b5SMatthias Ringwald * modification, are permitted provided that the following conditions are met:
14*1b2596b5SMatthias Ringwald *
15*1b2596b5SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright notice,
16*1b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer.
17*1b2596b5SMatthias Ringwald *
18*1b2596b5SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright notice,
19*1b2596b5SMatthias Ringwald * this list of conditions and the following disclaimer in the documentation
20*1b2596b5SMatthias Ringwald * and/or other materials provided with the distribution.
21*1b2596b5SMatthias Ringwald *
22*1b2596b5SMatthias Ringwald * 3. The name of Atmel may not be used to endorse or promote products derived
23*1b2596b5SMatthias Ringwald * from this software without specific prior written permission.
24*1b2596b5SMatthias Ringwald *
25*1b2596b5SMatthias Ringwald * 4. This software may only be redistributed and used in connection with an
26*1b2596b5SMatthias Ringwald * Atmel microcontroller product.
27*1b2596b5SMatthias Ringwald *
28*1b2596b5SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29*1b2596b5SMatthias Ringwald * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30*1b2596b5SMatthias Ringwald * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31*1b2596b5SMatthias Ringwald * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32*1b2596b5SMatthias Ringwald * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*1b2596b5SMatthias Ringwald * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*1b2596b5SMatthias Ringwald * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*1b2596b5SMatthias Ringwald * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36*1b2596b5SMatthias Ringwald * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37*1b2596b5SMatthias Ringwald * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*1b2596b5SMatthias Ringwald * POSSIBILITY OF SUCH DAMAGE.
39*1b2596b5SMatthias Ringwald *
40*1b2596b5SMatthias Ringwald * \asf_license_stop
41*1b2596b5SMatthias Ringwald *
42*1b2596b5SMatthias Ringwald */
43*1b2596b5SMatthias Ringwald /*
44*1b2596b5SMatthias Ringwald * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45*1b2596b5SMatthias Ringwald */
46*1b2596b5SMatthias Ringwald
47*1b2596b5SMatthias Ringwald #ifndef CHIP_SYSCLK_H_INCLUDED
48*1b2596b5SMatthias Ringwald #define CHIP_SYSCLK_H_INCLUDED
49*1b2596b5SMatthias Ringwald
50*1b2596b5SMatthias Ringwald #include <osc.h>
51*1b2596b5SMatthias Ringwald #include <pll.h>
52*1b2596b5SMatthias Ringwald
53*1b2596b5SMatthias Ringwald /**
54*1b2596b5SMatthias Ringwald * \page sysclk_quickstart Quick Start Guide for the System Clock Management
55*1b2596b5SMatthias Ringwald * service (SAMV71)
56*1b2596b5SMatthias Ringwald *
57*1b2596b5SMatthias Ringwald * This is the quick start guide for the \ref sysclk_group "System Clock
58*1b2596b5SMatthias Ringwald * Management" service, with step-by-step instructions on how to configure and
59*1b2596b5SMatthias Ringwald * use the service for specific use cases.
60*1b2596b5SMatthias Ringwald *
61*1b2596b5SMatthias Ringwald * \section sysclk_quickstart_usecases System Clock Management use cases
62*1b2596b5SMatthias Ringwald * - \ref sysclk_quickstart_basic
63*1b2596b5SMatthias Ringwald * - \ref sysclk_quickstart_use_case_2
64*1b2596b5SMatthias Ringwald *
65*1b2596b5SMatthias Ringwald * \section sysclk_quickstart_basic Basic usage of the System Clock Management
66*1b2596b5SMatthias Ringwald * service
67*1b2596b5SMatthias Ringwald * This section will present a basic use case for the System Clock Management
68*1b2596b5SMatthias Ringwald * service. This use case will configure the main system clock to 120MHz,
69*1b2596b5SMatthias Ringwald * using an internal PLL module to multiply the frequency of a crystal attached
70*1b2596b5SMatthias Ringwald * to the microcontroller.
71*1b2596b5SMatthias Ringwald *
72*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites
73*1b2596b5SMatthias Ringwald * - None
74*1b2596b5SMatthias Ringwald *
75*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code
76*1b2596b5SMatthias Ringwald * Add to the application initialization code:
77*1b2596b5SMatthias Ringwald * \code
78*1b2596b5SMatthias Ringwald sysclk_init();
79*1b2596b5SMatthias Ringwald \endcode
80*1b2596b5SMatthias Ringwald *
81*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow
82*1b2596b5SMatthias Ringwald * -# Configure the system clocks according to the settings in conf_clock.h:
83*1b2596b5SMatthias Ringwald * \code sysclk_init(); \endcode
84*1b2596b5SMatthias Ringwald *
85*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_1_example_code Example code
86*1b2596b5SMatthias Ringwald * Add or uncomment the following in your conf_clock.h header file,
87*1b2596b5SMatthias Ringwald * commenting out all other definitions of the same symbol(s):
88*1b2596b5SMatthias Ringwald * \code
89*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
90*1b2596b5SMatthias Ringwald
91*1b2596b5SMatthias Ringwald // Fpll0 = (Fclk * PLL_mul) / PLL_div
92*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
93*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
94*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_DIV 1
95*1b2596b5SMatthias Ringwald
96*1b2596b5SMatthias Ringwald // Fbus = Fsys / BUS_div
97*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
98*1b2596b5SMatthias Ringwald \endcode
99*1b2596b5SMatthias Ringwald *
100*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow
101*1b2596b5SMatthias Ringwald * -# Configure the main system clock to use the output of the PLL module as
102*1b2596b5SMatthias Ringwald * its source:
103*1b2596b5SMatthias Ringwald * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
104*1b2596b5SMatthias Ringwald * -# Configure the PLL module to use the fast external fast crystal
105*1b2596b5SMatthias Ringwald * oscillator as its source:
106*1b2596b5SMatthias Ringwald * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
107*1b2596b5SMatthias Ringwald * -# Configure the PLL module to multiply the external fast crystal
108*1b2596b5SMatthias Ringwald * oscillator frequency up to 120MHz:
109*1b2596b5SMatthias Ringwald * \code
110*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
111*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_DIV 1
112*1b2596b5SMatthias Ringwald \endcode
113*1b2596b5SMatthias Ringwald * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
114*1b2596b5SMatthias Ringwald * board \c conf_board.h configuration
115*1b2596b5SMatthias Ringwald * file as the frequency of the fast crystal attached to the microcontroller.
116*1b2596b5SMatthias Ringwald * -# Configure the main clock to run at the full 120MHz, disable scaling of
117*1b2596b5SMatthias Ringwald * the main system clock speed:
118*1b2596b5SMatthias Ringwald * \code
119*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
120*1b2596b5SMatthias Ringwald \endcode
121*1b2596b5SMatthias Ringwald * \note Some dividers are powers of two, while others are integer division
122*1b2596b5SMatthias Ringwald * factors. Refer to the formulas in the conf_clock.h template commented
123*1b2596b5SMatthias Ringwald * above each division define.
124*1b2596b5SMatthias Ringwald */
125*1b2596b5SMatthias Ringwald
126*1b2596b5SMatthias Ringwald /**
127*1b2596b5SMatthias Ringwald * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock
128*1b2596b5SMatthias Ringwald * Management (SAMV71)
129*1b2596b5SMatthias Ringwald *
130*1b2596b5SMatthias Ringwald * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus
131*1b2596b5SMatthias Ringwald * Clock Management
132*1b2596b5SMatthias Ringwald * This section will present a more advanced use case for the System Clock
133*1b2596b5SMatthias Ringwald * Management service. This use case will configure the main system clock to
134*1b2596b5SMatthias Ringwald * 96MHz, using an internal PLL module to multiply the frequency of a crystal
135*1b2596b5SMatthias Ringwald * attached to the microcontroller. The USB clock will be configured via the
136*1b2596b5SMatthias Ringwald * same PLL module.
137*1b2596b5SMatthias Ringwald *
138*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites
139*1b2596b5SMatthias Ringwald * - None
140*1b2596b5SMatthias Ringwald *
141*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code
142*1b2596b5SMatthias Ringwald * Add to the application initialization code:
143*1b2596b5SMatthias Ringwald * \code
144*1b2596b5SMatthias Ringwald sysclk_init();
145*1b2596b5SMatthias Ringwald \endcode
146*1b2596b5SMatthias Ringwald *
147*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow
148*1b2596b5SMatthias Ringwald * -# Configure the system clocks according to the settings in conf_clock.h:
149*1b2596b5SMatthias Ringwald * \code sysclk_init(); \endcode
150*1b2596b5SMatthias Ringwald *
151*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_2_example_code Example code
152*1b2596b5SMatthias Ringwald * Add or uncomment the following in your conf_clock.h header file,
153*1b2596b5SMatthias Ringwald * commenting out all other definitions of the same symbol(s):
154*1b2596b5SMatthias Ringwald * \code
155*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
156*1b2596b5SMatthias Ringwald
157*1b2596b5SMatthias Ringwald // Fpll0 = (Fclk * PLL_mul) / PLL_div
158*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
159*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL)
160*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_DIV 1
161*1b2596b5SMatthias Ringwald
162*1b2596b5SMatthias Ringwald // Fbus = Fsys / BUS_div
163*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
164*1b2596b5SMatthias Ringwald
165*1b2596b5SMatthias Ringwald // Fusb = Fsys / USB_div
166*1b2596b5SMatthias Ringwald #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0
167*1b2596b5SMatthias Ringwald #define CONFIG_USBCLK_DIV 2
168*1b2596b5SMatthias Ringwald \endcode
169*1b2596b5SMatthias Ringwald *
170*1b2596b5SMatthias Ringwald * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow
171*1b2596b5SMatthias Ringwald * -# Configure the main system clock to use the output of the PLL0 module as
172*1b2596b5SMatthias Ringwald * its source:
173*1b2596b5SMatthias Ringwald * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
174*1b2596b5SMatthias Ringwald * -# Configure the PLL0 module to use the fast external fast crystal
175*1b2596b5SMatthias Ringwald * oscillator as its source:
176*1b2596b5SMatthias Ringwald * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
177*1b2596b5SMatthias Ringwald * -# Configure the PLL0 module to multiply the external fast crystal
178*1b2596b5SMatthias Ringwald * oscillator frequency up to 96MHz:
179*1b2596b5SMatthias Ringwald * \code
180*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL)
181*1b2596b5SMatthias Ringwald #define CONFIG_PLL0_DIV 1
182*1b2596b5SMatthias Ringwald \endcode
183*1b2596b5SMatthias Ringwald * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
184*1b2596b5SMatthias Ringwald * board \c conf_board.h configuration file as the frequency of the fast
185*1b2596b5SMatthias Ringwald * crystal attached to the microcontroller.
186*1b2596b5SMatthias Ringwald * -# Configure the main clock to run at the full 96MHz, disable scaling of
187*1b2596b5SMatthias Ringwald * the main system clock speed:
188*1b2596b5SMatthias Ringwald * \code
189*1b2596b5SMatthias Ringwald #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
190*1b2596b5SMatthias Ringwald \endcode
191*1b2596b5SMatthias Ringwald * \note Some dividers are powers of two, while others are integer division
192*1b2596b5SMatthias Ringwald * factors. Refer to the formulas in the conf_clock.h template commented
193*1b2596b5SMatthias Ringwald * above each division define.
194*1b2596b5SMatthias Ringwald * -# Configure the USB module clock to use the output of the PLL0 module as
195*1b2596b5SMatthias Ringwald * its source with division 2:
196*1b2596b5SMatthias Ringwald * \code
197*1b2596b5SMatthias Ringwald #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0
198*1b2596b5SMatthias Ringwald #define CONFIG_USBCLK_DIV 2
199*1b2596b5SMatthias Ringwald \endcode
200*1b2596b5SMatthias Ringwald */
201*1b2596b5SMatthias Ringwald
202*1b2596b5SMatthias Ringwald /// @cond 0
203*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
204*1b2596b5SMatthias Ringwald #ifdef __cplusplus
205*1b2596b5SMatthias Ringwald extern "C" {
206*1b2596b5SMatthias Ringwald #endif
207*1b2596b5SMatthias Ringwald /**INDENT-ON**/
208*1b2596b5SMatthias Ringwald /// @endcond
209*1b2596b5SMatthias Ringwald
210*1b2596b5SMatthias Ringwald /**
211*1b2596b5SMatthias Ringwald * \weakgroup sysclk_group
212*1b2596b5SMatthias Ringwald * @{
213*1b2596b5SMatthias Ringwald */
214*1b2596b5SMatthias Ringwald
215*1b2596b5SMatthias Ringwald //! \name Configuration Symbols
216*1b2596b5SMatthias Ringwald //@{
217*1b2596b5SMatthias Ringwald /**
218*1b2596b5SMatthias Ringwald * \def CONFIG_SYSCLK_SOURCE
219*1b2596b5SMatthias Ringwald * \brief Initial/static main system clock source
220*1b2596b5SMatthias Ringwald *
221*1b2596b5SMatthias Ringwald * The main system clock will be configured to use this clock during
222*1b2596b5SMatthias Ringwald * initialization.
223*1b2596b5SMatthias Ringwald */
224*1b2596b5SMatthias Ringwald #ifndef CONFIG_SYSCLK_SOURCE
225*1b2596b5SMatthias Ringwald # define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC
226*1b2596b5SMatthias Ringwald #endif
227*1b2596b5SMatthias Ringwald /**
228*1b2596b5SMatthias Ringwald * \def CONFIG_SYSCLK_PRES
229*1b2596b5SMatthias Ringwald * \brief Initial CPU clock divider (mck)
230*1b2596b5SMatthias Ringwald *
231*1b2596b5SMatthias Ringwald * The MCK will run at
232*1b2596b5SMatthias Ringwald * \f[
233*1b2596b5SMatthias Ringwald * f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz}
234*1b2596b5SMatthias Ringwald * \f]
235*1b2596b5SMatthias Ringwald * after initialization.
236*1b2596b5SMatthias Ringwald */
237*1b2596b5SMatthias Ringwald #ifndef CONFIG_SYSCLK_PRES
238*1b2596b5SMatthias Ringwald # define CONFIG_SYSCLK_PRES 0
239*1b2596b5SMatthias Ringwald #endif
240*1b2596b5SMatthias Ringwald
241*1b2596b5SMatthias Ringwald //@}
242*1b2596b5SMatthias Ringwald
243*1b2596b5SMatthias Ringwald //! \name Master Clock Sources (MCK)
244*1b2596b5SMatthias Ringwald //@{
245*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock
246*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock
247*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock
248*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock
249*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock
250*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock
251*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock
252*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock
253*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock
254*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_UPLLCK 9 //!< Use UPLLCK as master source clock
255*1b2596b5SMatthias Ringwald //@}
256*1b2596b5SMatthias Ringwald
257*1b2596b5SMatthias Ringwald //! \name Master Clock Prescalers (MCK)
258*1b2596b5SMatthias Ringwald //@{
259*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1
260*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2
261*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4
262*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8
263*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16
264*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32
265*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64
266*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3
267*1b2596b5SMatthias Ringwald //@}
268*1b2596b5SMatthias Ringwald
269*1b2596b5SMatthias Ringwald //! \name Master Clock Division (MCK)
270*1b2596b5SMatthias Ringwald //@{
271*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_1 PMC_MCKR_MDIV_EQ_PCK //!< Set master clock division to 1
272*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_2 PMC_MCKR_MDIV_PCK_DIV2 //!< Set master clock division to 2
273*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_4 PMC_MCKR_MDIV_PCK_DIV4 //!< Set master clock division to 4
274*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_3 PMC_MCKR_MDIV_PCK_DIV3 //!< Set master clock division to 3
275*1b2596b5SMatthias Ringwald //@}
276*1b2596b5SMatthias Ringwald
277*1b2596b5SMatthias Ringwald //! \name USB Clock Sources
278*1b2596b5SMatthias Ringwald //@{
279*1b2596b5SMatthias Ringwald #define USBCLK_SRC_PLL0 0 //!< Use PLLA
280*1b2596b5SMatthias Ringwald #define USBCLK_SRC_UPLL 1 //!< Use UPLL
281*1b2596b5SMatthias Ringwald //@}
282*1b2596b5SMatthias Ringwald
283*1b2596b5SMatthias Ringwald /**
284*1b2596b5SMatthias Ringwald * \def CONFIG_USBCLK_SOURCE
285*1b2596b5SMatthias Ringwald * \brief Configuration symbol for the USB generic clock source
286*1b2596b5SMatthias Ringwald *
287*1b2596b5SMatthias Ringwald * Sets the clock source to use for the USB. The source must also be properly
288*1b2596b5SMatthias Ringwald * configured.
289*1b2596b5SMatthias Ringwald *
290*1b2596b5SMatthias Ringwald * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if
291*1b2596b5SMatthias Ringwald * USB is not required.
292*1b2596b5SMatthias Ringwald */
293*1b2596b5SMatthias Ringwald #ifdef __DOXYGEN__
294*1b2596b5SMatthias Ringwald # define CONFIG_USBCLK_SOURCE
295*1b2596b5SMatthias Ringwald #endif
296*1b2596b5SMatthias Ringwald
297*1b2596b5SMatthias Ringwald /**
298*1b2596b5SMatthias Ringwald * \def CONFIG_USBCLK_DIV
299*1b2596b5SMatthias Ringwald * \brief Configuration symbol for the USB generic clock divider setting
300*1b2596b5SMatthias Ringwald *
301*1b2596b5SMatthias Ringwald * Sets the clock division for the USB generic clock. If a USB clock source is
302*1b2596b5SMatthias Ringwald * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be
303*1b2596b5SMatthias Ringwald * defined.
304*1b2596b5SMatthias Ringwald */
305*1b2596b5SMatthias Ringwald #ifdef __DOXYGEN__
306*1b2596b5SMatthias Ringwald # define CONFIG_USBCLK_DIV
307*1b2596b5SMatthias Ringwald #endif
308*1b2596b5SMatthias Ringwald
309*1b2596b5SMatthias Ringwald /**
310*1b2596b5SMatthias Ringwald * \name Querying the system clock
311*1b2596b5SMatthias Ringwald *
312*1b2596b5SMatthias Ringwald * The following functions may be used to query the current frequency of
313*1b2596b5SMatthias Ringwald * the system clock and the CPU and bus clocks derived from it.
314*1b2596b5SMatthias Ringwald * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be
315*1b2596b5SMatthias Ringwald * available on all platforms, although some platforms may define
316*1b2596b5SMatthias Ringwald * additional accessors for various chip-internal bus clocks. These are
317*1b2596b5SMatthias Ringwald * usually not intended to be queried directly by generic code.
318*1b2596b5SMatthias Ringwald */
319*1b2596b5SMatthias Ringwald //@{
320*1b2596b5SMatthias Ringwald
321*1b2596b5SMatthias Ringwald /**
322*1b2596b5SMatthias Ringwald * \brief Return the current rate in Hz of the main system clock
323*1b2596b5SMatthias Ringwald *
324*1b2596b5SMatthias Ringwald * \todo This function assumes that the main clock source never changes
325*1b2596b5SMatthias Ringwald * once it's been set up, and that PLL0 always runs at the compile-time
326*1b2596b5SMatthias Ringwald * configured default rate. While this is probably the most common
327*1b2596b5SMatthias Ringwald * configuration, which we want to support as a special case for
328*1b2596b5SMatthias Ringwald * performance reasons, we will at some point need to support more
329*1b2596b5SMatthias Ringwald * dynamic setups as well.
330*1b2596b5SMatthias Ringwald */
331*1b2596b5SMatthias Ringwald #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
332*1b2596b5SMatthias Ringwald extern uint32_t sysclk_initialized;
333*1b2596b5SMatthias Ringwald #endif
sysclk_get_main_hz(void)334*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_main_hz(void)
335*1b2596b5SMatthias Ringwald {
336*1b2596b5SMatthias Ringwald #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
337*1b2596b5SMatthias Ringwald if (!sysclk_initialized ) {
338*1b2596b5SMatthias Ringwald return OSC_MAINCK_4M_RC_HZ;
339*1b2596b5SMatthias Ringwald }
340*1b2596b5SMatthias Ringwald #endif
341*1b2596b5SMatthias Ringwald
342*1b2596b5SMatthias Ringwald /* Config system clock setting */
343*1b2596b5SMatthias Ringwald if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) {
344*1b2596b5SMatthias Ringwald return OSC_SLCK_32K_RC_HZ;
345*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
346*1b2596b5SMatthias Ringwald return OSC_SLCK_32K_XTAL_HZ;
347*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) {
348*1b2596b5SMatthias Ringwald return OSC_SLCK_32K_BYPASS_HZ;
349*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) {
350*1b2596b5SMatthias Ringwald return OSC_MAINCK_4M_RC_HZ;
351*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) {
352*1b2596b5SMatthias Ringwald return OSC_MAINCK_8M_RC_HZ;
353*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) {
354*1b2596b5SMatthias Ringwald return OSC_MAINCK_12M_RC_HZ;
355*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) {
356*1b2596b5SMatthias Ringwald return OSC_MAINCK_XTAL_HZ;
357*1b2596b5SMatthias Ringwald } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) {
358*1b2596b5SMatthias Ringwald return OSC_MAINCK_BYPASS_HZ;
359*1b2596b5SMatthias Ringwald }
360*1b2596b5SMatthias Ringwald #ifdef CONFIG_PLL0_SOURCE
361*1b2596b5SMatthias Ringwald else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) {
362*1b2596b5SMatthias Ringwald return pll_get_default_rate(0);
363*1b2596b5SMatthias Ringwald }
364*1b2596b5SMatthias Ringwald #endif
365*1b2596b5SMatthias Ringwald
366*1b2596b5SMatthias Ringwald #ifdef CONFIG_PLL1_SOURCE
367*1b2596b5SMatthias Ringwald else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) {
368*1b2596b5SMatthias Ringwald return PLL_UPLL_HZ;
369*1b2596b5SMatthias Ringwald }
370*1b2596b5SMatthias Ringwald #endif
371*1b2596b5SMatthias Ringwald else {
372*1b2596b5SMatthias Ringwald /* unhandled_case(CONFIG_SYSCLK_SOURCE); */
373*1b2596b5SMatthias Ringwald return 0;
374*1b2596b5SMatthias Ringwald }
375*1b2596b5SMatthias Ringwald }
376*1b2596b5SMatthias Ringwald
377*1b2596b5SMatthias Ringwald /**
378*1b2596b5SMatthias Ringwald * \brief Return the current rate in Hz of the CPU clock
379*1b2596b5SMatthias Ringwald *
380*1b2596b5SMatthias Ringwald * \todo This function assumes that the CPU always runs at the system
381*1b2596b5SMatthias Ringwald * clock frequency. We want to support at least two more scenarios:
382*1b2596b5SMatthias Ringwald * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus
383*1b2596b5SMatthias Ringwald * clock dividers (which may change at run time). Ditto for all the bus
384*1b2596b5SMatthias Ringwald * clocks.
385*1b2596b5SMatthias Ringwald *
386*1b2596b5SMatthias Ringwald * \return Frequency of the CPU clock, in Hz.
387*1b2596b5SMatthias Ringwald */
sysclk_get_cpu_hz(void)388*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_cpu_hz(void)
389*1b2596b5SMatthias Ringwald {
390*1b2596b5SMatthias Ringwald /* CONFIG_SYSCLK_PRES is the register value for setting the expected */
391*1b2596b5SMatthias Ringwald /* prescaler, not an immediate value. */
392*1b2596b5SMatthias Ringwald return sysclk_get_main_hz() /
393*1b2596b5SMatthias Ringwald ((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 :
394*1b2596b5SMatthias Ringwald (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos)));
395*1b2596b5SMatthias Ringwald }
396*1b2596b5SMatthias Ringwald
397*1b2596b5SMatthias Ringwald /**
398*1b2596b5SMatthias Ringwald * \brief Retrieves the current rate in Hz of the peripheral clocks.
399*1b2596b5SMatthias Ringwald *
400*1b2596b5SMatthias Ringwald * \return Frequency of the peripheral clocks, in Hz.
401*1b2596b5SMatthias Ringwald */
sysclk_get_peripheral_hz(void)402*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_peripheral_hz(void)
403*1b2596b5SMatthias Ringwald {
404*1b2596b5SMatthias Ringwald /* CONFIG_SYSCLK_PRES is the register value for setting the expected */
405*1b2596b5SMatthias Ringwald /* prescaler, not an immediate value. */
406*1b2596b5SMatthias Ringwald return sysclk_get_main_hz() /
407*1b2596b5SMatthias Ringwald (((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))) * CONFIG_SYSCLK_DIV);
408*1b2596b5SMatthias Ringwald }
409*1b2596b5SMatthias Ringwald
410*1b2596b5SMatthias Ringwald /**
411*1b2596b5SMatthias Ringwald * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached
412*1b2596b5SMatthias Ringwald * to the specified peripheral.
413*1b2596b5SMatthias Ringwald *
414*1b2596b5SMatthias Ringwald * \param module Pointer to the module's base address.
415*1b2596b5SMatthias Ringwald *
416*1b2596b5SMatthias Ringwald * \return Frequency of the bus attached to the specified peripheral, in Hz.
417*1b2596b5SMatthias Ringwald */
sysclk_get_peripheral_bus_hz(const volatile void * module)418*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module)
419*1b2596b5SMatthias Ringwald {
420*1b2596b5SMatthias Ringwald UNUSED(module);
421*1b2596b5SMatthias Ringwald return sysclk_get_peripheral_hz();
422*1b2596b5SMatthias Ringwald }
423*1b2596b5SMatthias Ringwald //@}
424*1b2596b5SMatthias Ringwald
425*1b2596b5SMatthias Ringwald //! \name Enabling and disabling synchronous clocks
426*1b2596b5SMatthias Ringwald //@{
427*1b2596b5SMatthias Ringwald
428*1b2596b5SMatthias Ringwald /**
429*1b2596b5SMatthias Ringwald * \brief Enable a peripheral's clock.
430*1b2596b5SMatthias Ringwald *
431*1b2596b5SMatthias Ringwald * \param ul_id Id (number) of the peripheral clock.
432*1b2596b5SMatthias Ringwald */
sysclk_enable_peripheral_clock(uint32_t ul_id)433*1b2596b5SMatthias Ringwald static inline void sysclk_enable_peripheral_clock(uint32_t ul_id)
434*1b2596b5SMatthias Ringwald {
435*1b2596b5SMatthias Ringwald pmc_enable_periph_clk(ul_id);
436*1b2596b5SMatthias Ringwald }
437*1b2596b5SMatthias Ringwald
438*1b2596b5SMatthias Ringwald /**
439*1b2596b5SMatthias Ringwald * \brief Disable a peripheral's clock.
440*1b2596b5SMatthias Ringwald *
441*1b2596b5SMatthias Ringwald * \param ul_id Id (number) of the peripheral clock.
442*1b2596b5SMatthias Ringwald */
sysclk_disable_peripheral_clock(uint32_t ul_id)443*1b2596b5SMatthias Ringwald static inline void sysclk_disable_peripheral_clock(uint32_t ul_id)
444*1b2596b5SMatthias Ringwald {
445*1b2596b5SMatthias Ringwald pmc_disable_periph_clk(ul_id);
446*1b2596b5SMatthias Ringwald }
447*1b2596b5SMatthias Ringwald
448*1b2596b5SMatthias Ringwald //@}
449*1b2596b5SMatthias Ringwald
450*1b2596b5SMatthias Ringwald //! \name System Clock Source and Prescaler configuration
451*1b2596b5SMatthias Ringwald //@{
452*1b2596b5SMatthias Ringwald
453*1b2596b5SMatthias Ringwald extern void sysclk_set_prescalers(uint32_t ul_pres);
454*1b2596b5SMatthias Ringwald extern void sysclk_set_source(uint32_t ul_src);
455*1b2596b5SMatthias Ringwald
456*1b2596b5SMatthias Ringwald //@}
457*1b2596b5SMatthias Ringwald
458*1b2596b5SMatthias Ringwald extern void sysclk_enable_usb(void);
459*1b2596b5SMatthias Ringwald extern void sysclk_disable_usb(void);
460*1b2596b5SMatthias Ringwald
461*1b2596b5SMatthias Ringwald extern void sysclk_init(void);
462*1b2596b5SMatthias Ringwald
463*1b2596b5SMatthias Ringwald //! @}
464*1b2596b5SMatthias Ringwald
465*1b2596b5SMatthias Ringwald /// @cond 0
466*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
467*1b2596b5SMatthias Ringwald #ifdef __cplusplus
468*1b2596b5SMatthias Ringwald }
469*1b2596b5SMatthias Ringwald #endif
470*1b2596b5SMatthias Ringwald /**INDENT-ON**/
471*1b2596b5SMatthias Ringwald /// @endcond
472*1b2596b5SMatthias Ringwald
473*1b2596b5SMatthias Ringwald #endif /* CHIP_SYSCLK_H_INCLUDED */
474