]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_ATSAM3S-EK2_Atmel_Studio/src/asf/common/services/clock/sam3s/sysclk.c
Add demo for SAM3S-EK2.
[freertos] / FreeRTOS / Demo / CORTEX_ATSAM3S-EK2_Atmel_Studio / src / asf / common / services / clock / sam3s / 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_PLLBCK:\r
110                 pmc_mck_set_source(PMC_MCKR_CSS_PLLB_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 USB clock.\r
120  *\r
121  * \note The SAM3S 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 #ifdef CONFIG_PLL1_SOURCE\r
147         case USBCLK_SRC_PLL1: {\r
148                 struct pll_config pllcfg;\r
149 \r
150                 pll_enable_source(CONFIG_PLL1_SOURCE);\r
151                 pll_config_defaults(&pllcfg, 1);\r
152                 pll_enable(&pllcfg, 1);\r
153                 pll_wait_for_lock(1);\r
154                 pmc_switch_udpck_to_pllbck(CONFIG_USBCLK_DIV - 1);\r
155                 pmc_enable_udpck();\r
156                 break;\r
157         }\r
158 #endif\r
159         }\r
160 }\r
161 \r
162 /**\r
163  * \brief Disable the USB clock.\r
164  *\r
165  * \note This implementation does not switch off the PLL, it just turns off the USB clock.\r
166  */\r
167 void sysclk_disable_usb(void)\r
168 {\r
169         pmc_disable_udpck();\r
170 }\r
171 #endif // CONFIG_USBCLK_SOURCE\r
172 \r
173 void sysclk_init(void)\r
174 {\r
175         struct pll_config pllcfg;\r
176 \r
177         /* Set a flash wait state depending on the new cpu frequency */\r
178         system_init_flash(sysclk_get_cpu_hz());\r
179 \r
180         /* Config system clock setting */\r
181         switch (CONFIG_SYSCLK_SOURCE) {\r
182         case SYSCLK_SRC_SLCK_RC:\r
183                 osc_enable(OSC_SLCK_32K_RC);\r
184                 osc_wait_ready(OSC_SLCK_32K_RC);                \r
185                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
186                 break;\r
187         \r
188         case SYSCLK_SRC_SLCK_XTAL:\r
189                 osc_enable(OSC_SLCK_32K_XTAL);\r
190                 osc_wait_ready(OSC_SLCK_32K_XTAL);              \r
191                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
192                 break;\r
193                 \r
194         case SYSCLK_SRC_SLCK_BYPASS:\r
195                 osc_enable(OSC_SLCK_32K_BYPASS);\r
196                 osc_wait_ready(OSC_SLCK_32K_BYPASS);            \r
197                 pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);\r
198                 break;\r
199         \r
200     case SYSCLK_SRC_MAINCK_4M_RC:\r
201                 /* Already running from SYSCLK_SRC_MAINCK_4M_RC */\r
202                 break;\r
203 \r
204     case SYSCLK_SRC_MAINCK_8M_RC:\r
205                 osc_enable(OSC_MAINCK_8M_RC);\r
206                 osc_wait_ready(OSC_MAINCK_8M_RC);               \r
207                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
208                 break;\r
209 \r
210     case SYSCLK_SRC_MAINCK_12M_RC:\r
211                 osc_enable(OSC_MAINCK_12M_RC);\r
212                 osc_wait_ready(OSC_MAINCK_12M_RC);              \r
213                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
214                 break;\r
215 \r
216 \r
217     case SYSCLK_SRC_MAINCK_XTAL:\r
218                 osc_enable(OSC_MAINCK_XTAL);\r
219                 osc_wait_ready(OSC_MAINCK_XTAL);                \r
220                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
221                 break;\r
222 \r
223     case SYSCLK_SRC_MAINCK_BYPASS:\r
224                 osc_enable(OSC_MAINCK_BYPASS);\r
225                 osc_wait_ready(OSC_MAINCK_BYPASS);              \r
226                 pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);\r
227                 break;\r
228 \r
229 #ifdef CONFIG_PLL0_SOURCE\r
230         case SYSCLK_SRC_PLLACK:\r
231                 pll_enable_source(CONFIG_PLL0_SOURCE);\r
232                 pll_config_defaults(&pllcfg, 0);\r
233                 pll_enable(&pllcfg, 0);\r
234                 pll_wait_for_lock(0);\r
235                 pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);\r
236                 break;  \r
237 #endif          \r
238 \r
239 #ifdef CONFIG_PLL1_SOURCE\r
240         case SYSCLK_SRC_PLLBCK:\r
241                 pll_enable_source(CONFIG_PLL1_SOURCE);\r
242                 pll_config_defaults(&pllcfg, 1);\r
243                 pll_enable(&pllcfg, 1);\r
244                 pll_wait_for_lock(1);\r
245                 pmc_switch_mck_to_pllbck(CONFIG_SYSCLK_PRES);\r
246                 break;\r
247 #endif  \r
248         }\r
249 \r
250         /* Update the SystemFrequency variable */\r
251         SystemCoreClockUpdate();\r
252         \r
253 #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)\r
254         /* Signal that the internal frequencies are setup */\r
255         sysclk_initialized = 1;\r
256 #endif\r
257 }\r
258 \r
259 //! @}\r
260 \r
261 /// @cond 0\r
262 /**INDENT-OFF**/\r
263 #ifdef __cplusplus\r
264 }\r
265 #endif\r
266 /**INDENT-ON**/\r
267 /// @endcond\r