]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_ATSAM3X_Atmel_Studio/src/asf/common/services/clock/sam3x/sysclk.c
Add SAM3X-EK demo.
[freertos] / FreeRTOS / Demo / CORTEX_ATSAM3X_Atmel_Studio / src / asf / common / services / clock / sam3x / sysclk.c
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 #include <sysclk.h>\r
45 \r
46 /// @cond 0\r
47 /**INDENT-OFF**/\r
48 #ifdef __cplusplus\r
49 extern "C" {\r
50 #endif\r
51 /**INDENT-ON**/\r
52 /// @endcond\r
53 \r
54 /**\r
55  * \weakgroup sysclk_group\r
56  * @{\r
57  */\r
58 \r
59 #if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)\r
60 /**\r
61  * \brief boolean signalling that the sysclk_init is done.\r
62  */\r
63 uint32_t sysclk_initialized = 0;\r
64 #endif\r
65 \r
66 /**\r
67  * \brief Set system clock prescaler configuration\r
68  *\r
69  * This function will change the system clock prescaler configuration to\r
70  * match the parameters.\r
71  *\r
72  * \note The parameters to this function are device-specific.\r
73  *\r
74  * \param cpu_shift The CPU clock will be divided by \f$2^{mck\_pres}\f$\r
75  */\r
76 void sysclk_set_prescalers(uint32_t ul_pres)\r
77 {\r
78         pmc_mck_set_prescaler(ul_pres);\r
79         SystemCoreClockUpdate();\r
80 }\r
81 \r
82 /**\r
83  * \brief Change the source of the main system clock.\r
84  *\r
85  * \param src The new system clock source. Must be one of the constants\r
86  * from the <em>System Clock Sources</em> section.\r
87  */\r
88 void sysclk_set_source(uint32_t ul_src)\r
89 {\r
90         switch (ul_src) {\r
91         case SYSCLK_SRC_SLCK_RC:\r
92         case SYSCLK_SRC_SLCK_XTAL:\r
93         case SYSCLK_SRC_SLCK_BYPASS:\r
94                 pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK);\r
95                 break;\r
96 \r
97         case SYSCLK_SRC_MAINCK_4M_RC:\r
98         case SYSCLK_SRC_MAINCK_8M_RC:\r
99         case SYSCLK_SRC_MAINCK_12M_RC:\r
100         case SYSCLK_SRC_MAINCK_XTAL:\r
101         case SYSCLK_SRC_MAINCK_BYPASS:\r
102                 pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK);\r
103                 break;\r
104 \r
105         case SYSCLK_SRC_PLLACK:\r
106                 pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK);\r
107                 break;\r
108 \r
109         case SYSCLK_SRC_UPLLCK:\r
110                 pmc_mck_set_source(PMC_MCKR_CSS_UPLL_CLK);\r
111                 break;\r
112         }\r
113 \r
114         SystemCoreClockUpdate();\r
115 }\r
116 \r
117 #if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__)\r
118 /**\r
119  * \brief Enable full speed USB clock.\r
120  *\r
121  * \note The SAM3X UDP hardware interprets div as div+1. For readability the hardware div+1\r
122  * is hidden in this implementation. Use div as div effective value.\r
123  *\r
124  * \param pll_id Source of the USB clock.\r
125  * \param div Actual clock divisor. Must be superior to 0.\r
126  */\r
127 void sysclk_enable_usb(void)\r
128 {\r
129         Assert(CONFIG_USBCLK_DIV > 0);\r
130 \r
131         switch (CONFIG_USBCLK_SOURCE) {\r
132 #ifdef CONFIG_PLL0_SOURCE\r
133         case USBCLK_SRC_PLL0: {\r
134                 struct pll_config pllcfg;\r
135 \r
136                 pll_enable_source(CONFIG_PLL0_SOURCE);\r
137                 pll_config_defaults(&pllcfg, 0);\r
138                 pll_enable(&pllcfg, 0);\r
139                 pll_wait_for_lock(0);\r
140                 pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1);\r
141                 pmc_enable_udpck();\r
142                 break;\r
143         }\r
144 #endif\r
145 \r
146         case USBCLK_SRC_UPLL: {\r
147 \r
148                 pmc_enable_upll_clock();\r
149                 pmc_switch_udpck_to_upllck(CONFIG_USBCLK_DIV - 1);\r
150                 pmc_enable_udpck();\r
151                 break;\r
152         }\r
153 \r
154         }\r
155 }\r
156 \r
157 /**\r
158  * \brief Disable full speed USB clock.\r
159  *\r
160  * \note This implementation does not switch off the PLL, it just turns off the USB clock.\r
161  */\r
162 void sysclk_disable_usb(void)\r
163 {\r
164         pll_disable(1);\r
165 }\r
166 #endif // CONFIG_USBCLK_SOURCE\r
167 \r
168 void sysclk_init(void)\r
169 {\r
170         struct pll_config pllcfg;\r
171 \r
172         /* Set a flash wait state depending on the new cpu frequency */\r
173         system_init_flash(sysclk_get_cpu_hz());\r
174 \r
175         /* Config system clock setting */\r
176         switch (CONFIG_SYSCLK_SOURCE) {\r
177         case SYSCLK_SRC_SLCK_RC:\r
178                 osc_enable(OSC_SLCK_32K_RC);\r
179                 osc_wait_ready(OSC_SLCK_32K_RC);\r
180                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
181                 break;\r
182 \r
183         case SYSCLK_SRC_SLCK_XTAL:\r
184                 osc_enable(OSC_SLCK_32K_XTAL);\r
185                 osc_wait_ready(OSC_SLCK_32K_XTAL);\r
186                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
187                 break;\r
188 \r
189         case SYSCLK_SRC_SLCK_BYPASS:\r
190                 osc_enable(OSC_SLCK_32K_BYPASS);\r
191                 osc_wait_ready(OSC_SLCK_32K_BYPASS);\r
192                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
193                 break;\r
194 \r
195         case SYSCLK_SRC_MAINCK_4M_RC:\r
196                 /* Already running from SYSCLK_SRC_MAINCK_4M_RC */\r
197                 break;\r
198 \r
199         case SYSCLK_SRC_MAINCK_8M_RC:\r
200                 osc_enable(OSC_MAINCK_8M_RC);\r
201                 osc_wait_ready(OSC_MAINCK_8M_RC);\r
202                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
203                 break;\r
204 \r
205         case SYSCLK_SRC_MAINCK_12M_RC:\r
206                 osc_enable(OSC_MAINCK_12M_RC);\r
207                 osc_wait_ready(OSC_MAINCK_12M_RC);\r
208                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
209                 break;\r
210 \r
211 \r
212         case SYSCLK_SRC_MAINCK_XTAL:\r
213                 osc_enable(OSC_MAINCK_XTAL);\r
214                 osc_wait_ready(OSC_MAINCK_XTAL);\r
215                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
216                 break;\r
217 \r
218         case SYSCLK_SRC_MAINCK_BYPASS:\r
219                 osc_enable(OSC_MAINCK_BYPASS);\r
220                 osc_wait_ready(OSC_MAINCK_BYPASS);\r
221                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
222                 break;\r
223 \r
224 #ifdef CONFIG_PLL0_SOURCE\r
225         case SYSCLK_SRC_PLLACK:\r
226                 pll_enable_source(CONFIG_PLL0_SOURCE);\r
227                 pll_config_defaults(&pllcfg, 0);\r
228                 pll_enable(&pllcfg, 0);\r
229                 pll_wait_for_lock(0);\r
230                 pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);\r
231                 break;\r
232 #endif\r
233 \r
234         case SYSCLK_SRC_UPLLCK:\r
235                 pll_enable_source(CONFIG_PLL1_SOURCE);\r
236                 pll_config_defaults(&pllcfg, 1);\r
237                 pll_enable(&pllcfg, 1);\r
238                 pll_wait_for_lock(1);\r
239                 pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES);\r
240                 break;\r
241         }\r
242 \r
243         /* Update the SystemFrequency variable */\r
244         SystemCoreClockUpdate();\r
245 \r
246 #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)\r
247         /* Signal that the internal frequencies are setup */\r
248         sysclk_initialized = 1;\r
249 #endif\r
250 }\r
251 \r
252 //! @}\r
253 \r
254 /// @cond 0\r
255 /**INDENT-OFF**/\r
256 #ifdef __cplusplus\r
257 }\r
258 #endif\r
259 /**INDENT-ON**/\r
260 /// @endcond\r