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