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