]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/asf/common/services/clock/sam4l/osc.h
Add SAM4L demo.
[freertos] / FreeRTOS / Demo / CORTEX_M4_ATSAM4L_Atmel_Studio / src / asf / common / services / clock / sam4l / osc.h
1 /**\r
2  * \file\r
3  *\r
4  * \brief Chip-specific oscillator management functions\r
5  *\r
6  * Copyright (c) 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 #ifndef CHIP_OSC_H_INCLUDED\r
44 #define CHIP_OSC_H_INCLUDED\r
45 \r
46 #include <board.h>\r
47 \r
48 #ifdef __cplusplus\r
49 extern "C" {\r
50 #endif\r
51 \r
52 \r
53 /**\r
54  * \weakgroup osc_group\r
55  * @{\r
56  */\r
57 \r
58 //! \name Oscillator identifiers\r
59 //@{\r
60 #define OSC_ID_OSC0             0       //!< External Oscillator 0\r
61 #define OSC_ID_OSC32            1       //!< External 32 kHz oscillator\r
62 #define OSC_ID_RC32K            2       //!< Internal 32 kHz RC oscillator\r
63 #define OSC_ID_RC80M            3       //!< Internal 80 MHz RC oscillator\r
64 #define OSC_ID_RCFAST           4       //!< Internal 4-8-12 MHz RCFAST oscillator\r
65 #define OSC_ID_RC1M             5       //!< Internal 1 MHz RC oscillator\r
66 #define OSC_ID_RCSYS            6       //!< Internal System RC oscillator\r
67 //@}\r
68 \r
69 //! \name OSC0 mode values\r
70 //@{\r
71 //! External clock connected to XIN\r
72 #define OSC_MODE_EXTERNAL       0\r
73 //! Crystal connected to XIN/XOUT\r
74 #define OSC_MODE_XTAL           SCIF_OSCCTRL0_MODE\r
75 //@}\r
76 \r
77 //! \name OSC32 mode values\r
78 //@{\r
79 //! External clock connected to XIN32\r
80 #define OSC32_MODE_EXTERNAL     BSCIF_OSCCTRL32_MODE(0)\r
81 //! Crystal connected to XIN32/XOUT32\r
82 #define OSC32_MODE_XTAL         BSCIF_OSCCTRL32_MODE(1)\r
83 //! Crystal connected to XIN32/XOUT32 in high current mode\r
84 #define OSC32_MODE_XTAL_HC      BSCIF_OSCCTRL32_MODE(4)\r
85 //@}\r
86 \r
87 //! \name OSC0 startup values\r
88 //@{\r
89 //! 0 cycles\r
90 #define OSC_STARTUP_0           SCIF_OSCCTRL0_STARTUP(0)\r
91 //! 64 cycles (560 us)\r
92 #define OSC_STARTUP_64          SCIF_OSCCTRL0_STARTUP(1)\r
93 //! 128 cycles (1.1 ms)\r
94 #define OSC_STARTUP_128         SCIF_OSCCTRL0_STARTUP(2)\r
95 //! 2048 cycles (18 ms)\r
96 #define OSC_STARTUP_2048        SCIF_OSCCTRL0_STARTUP(3)\r
97 //! 4096 cycles (36 ms)\r
98 #define OSC_STARTUP_4096        SCIF_OSCCTRL0_STARTUP(4)\r
99 //! 8192 cycles (71 ms)\r
100 #define OSC_STARTUP_8192        SCIF_OSCCTRL0_STARTUP(5)\r
101 //! 16384 cycles (143 ms)\r
102 #define OSC_STARTUP_16384       SCIF_OSCCTRL0_STARTUP(6)\r
103 //! 32768 cycles (285 ms)\r
104 #define OSC_STARTUP_32768       SCIF_OSCCTRL0_STARTUP(7)\r
105 //@}\r
106 \r
107 //! \name OSC32 startup values\r
108 //@{\r
109 //! 0 cycles\r
110 #define OSC32_STARTUP_0         BSCIF_OSCCTRL32_STARTUP(0)\r
111 //! 128 cycles (1.1 ms)\r
112 #define OSC32_STARTUP_128       BSCIF_OSCCTRL32_STARTUP(1)\r
113 //! 8192 cycles (72.3 ms)\r
114 #define OSC32_STARTUP_8192      BSCIF_OSCCTRL32_STARTUP(2)\r
115 //! 16384 cycles (143 ms)\r
116 #define OSC32_STARTUP_16384     BSCIF_OSCCTRL32_STARTUP(3)\r
117 //! 65536 cycles (570 ms)\r
118 #define OSC32_STARTUP_65536     BSCIF_OSCCTRL32_STARTUP(4)\r
119 //! 131072 cycles (1.1 s)\r
120 #define OSC32_STARTUP_131072    BSCIF_OSCCTRL32_STARTUP(5)\r
121 //! 262144 cycles (2.3 s)\r
122 #define OSC32_STARTUP_262144    BSCIF_OSCCTRL32_STARTUP(6)\r
123 //! 524288 cycles (4.6 s)\r
124 #define OSC32_STARTUP_524288    BSCIF_OSCCTRL32_STARTUP(7)\r
125 //@}\r
126 \r
127 /**\r
128  * \def OSC0_STARTUP_TIMEOUT\r
129  * \brief Number of slow clock cycles to wait for OSC0 to start\r
130  *\r
131  * This is the number of slow clock cycles corresponding to\r
132  * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the\r
133  * oscillator isn't running when this timeout has expired, it is assumed\r
134  * to have failed to start.\r
135  */\r
136 /**\r
137  * \def OSC0_MODE_VALUE\r
138  * \brief Board-dependent value written to the MODE bitfield of\r
139  * PM_OSCCTRL(0)\r
140  */\r
141 /**\r
142  * \def OSC0_STARTUP_VALUE\r
143  * \brief Board-dependent value written to the STARTUP bitfield of\r
144  * PM_OSCCTRL(0)\r
145  */\r
146 #if defined(BOARD_OSC0_STARTUP_US)\r
147 #   if BOARD_OSC0_STARTUP_US == 0\r
148 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_0\r
149 #      define OSC0_STARTUP_TIMEOUT  8\r
150 #   elif BOARD_OSC0_STARTUP_US <= 557\r
151 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_64\r
152 #      define OSC0_STARTUP_TIMEOUT  80\r
153 #   elif BOARD_OSC0_STARTUP_US <= 1100\r
154 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_128\r
155 #      define OSC0_STARTUP_TIMEOUT  160\r
156 #   elif BOARD_OSC0_STARTUP_US <= 18000\r
157 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_2048\r
158 #      define OSC0_STARTUP_TIMEOUT  2560\r
159 #   elif BOARD_OSC0_STARTUP_US <= 36000\r
160 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_4096\r
161 #      define OSC0_STARTUP_TIMEOUT  5120\r
162 #   elif BOARD_OSC0_STARTUP_US <= 71000\r
163 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_8192\r
164 #      define OSC0_STARTUP_TIMEOUT  10240\r
165 #   elif BOARD_OSC0_STARTUP_US <= 143000\r
166 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_16384\r
167 #      define OSC0_STARTUP_TIMEOUT  20480\r
168 #   elif BOARD_OSC0_STARTUP_US <= 285000\r
169 #      define OSC0_STARTUP_VALUE    OSC_STARTUP_32768\r
170 #      define OSC0_STARTUP_TIMEOUT  40960\r
171 #   else\r
172 #      error BOARD_OSC0_STARTUP_US is too high\r
173 #   endif\r
174 #   if BOARD_OSC0_IS_XTAL == true\r
175 #      define OSC0_MODE_VALUE       OSC_MODE_XTAL\r
176 #      if BOARD_OSC0_HZ < 2000000\r
177 #         define OSC0_GAIN_VALUE      SCIF_OSCCTRL0_GAIN(0)\r
178 #      elif BOARD_OSC0_HZ < 4000000\r
179 #         define OSC0_GAIN_VALUE      SCIF_OSCCTRL0_GAIN(1)\r
180 #      elif BOARD_OSC0_HZ < 8000000\r
181 #         define OSC0_GAIN_VALUE      SCIF_OSCCTRL0_GAIN(2)\r
182 #      elif BOARD_OSC0_HZ < 16000000\r
183 #         define OSC0_GAIN_VALUE      SCIF_OSCCTRL0_GAIN(3)\r
184 #      else\r
185 #         define OSC0_GAIN_VALUE      ((0x1u << 4) | SCIF_OSCCTRL0_GAIN(0))\r
186 #      endif\r
187 #   else\r
188 #      define OSC0_MODE_VALUE       OSC_MODE_EXTERNAL\r
189 #   endif\r
190 #else\r
191 #   if defined(BOARD_OSC0_HZ)\r
192 #      error BOARD_OSC0_STARTUP_US must be defined by the board code\r
193 #   endif\r
194 #   ifdef __DOXYGEN__\r
195 #      define OSC0_STARTUP_VALUE     UNDEFINED\r
196 #      define OSC0_STARTUP_TIMEOUT   UNDEFINED\r
197 #      define OSC0_MODE_VALUE        UNDEFINED\r
198 #   endif\r
199 #endif\r
200 \r
201 #if defined(BOARD_OSC32_STARTUP_US)\r
202 #   if BOARD_OSC32_STARTUP_US == 0\r
203 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_0\r
204 #   elif BOARD_OSC32_STARTUP_US   <= 1100\r
205 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_128\r
206 #   elif BOARD_OSC32_STARTUP_US   <= 72300\r
207 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_8192\r
208 #   elif BOARD_OSC32_STARTUP_US   <= 143000\r
209 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_16384\r
210 #   elif BOARD_OSC32_STARTUP_US   <= 570000\r
211 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_65536\r
212 #   elif BOARD_OSC32_STARTUP_US   <= 1100000\r
213 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_131072\r
214 #   elif BOARD_OSC32_STARTUP_US   <= 2300000\r
215 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_262144\r
216 #   elif BOARD_OSC32_STARTUP_US   <= 4600000\r
217 #      define OSC32_STARTUP_VALUE    OSC32_STARTUP_524288\r
218 #   else\r
219 #      error BOARD_OSC32_STARTUP_US is too high\r
220 #   endif\r
221 #   if BOARD_OSC32_IS_XTAL == true\r
222 #      define OSC32_MODE_VALUE       OSC32_MODE_XTAL\r
223 #   else\r
224 #      define OSC32_MODE_VALUE       OSC32_MODE_EXTERNAL\r
225 #   endif\r
226 #else\r
227 #   if defined(BOARD_OSC32_HZ)\r
228 #      error BOARD_OSC32_STARTUP_US must be defined by the board code\r
229 #   endif\r
230 #   ifdef __DOXYGEN__\r
231 #      define OSC32_STARTUP_VALUE     UNDEFINED\r
232 #      define OSC32_STARTUP_TIMEOUT   UNDEFINED\r
233 #      define OSC32_MODE_VALUE        UNDEFINED\r
234 #   endif\r
235 #endif\r
236 \r
237 // Use 4 MHz frequency range for RCFAST oscillator if config was empty.\r
238 #ifndef CONFIG_RCFAST_FRANGE\r
239 #define CONFIG_RCFAST_FRANGE    0\r
240 #endif\r
241 \r
242 /**\r
243  * \name Board-specific configuration parameters\r
244  * The following definitions must be provided by the board code for all\r
245  * working oscillators on the board.\r
246  */\r
247 //@{\r
248 /**\r
249  * \def BOARD_OSC0_HZ\r
250  * \brief Clock frequency of OSC0 in Hz\r
251  */\r
252 /**\r
253  * \def BOARD_OSC0_STARTUP_US\r
254  * \brief Startup time of OSC0 in microseconds\r
255  */\r
256 /**\r
257  * \def BOARD_OSC0_IS_XTAL\r
258  * \brief OSC0 uses a crystal, not an external clock\r
259  */\r
260 /**\r
261  * \def BOARD_OSC32_HZ\r
262  * \brief Clock frequency of OSC32 in Hz\r
263  */\r
264 /**\r
265  * \def BOARD_OSC32_STARTUP_US\r
266  * \brief Startup time of OSC32 in microseconds\r
267  */\r
268 /**\r
269  * \def BOARD_OSC32_IS_XTAL\r
270  * \brief OSC32 uses a crystal, not an external clock\r
271  */\r
272 /**\r
273  * \def BOARD_OSC32_SELCURR\r
274  * \brief Crystal current selection for OSC32\r
275  *\r
276  * If not defined, the recommended value (300nA) are used.\r
277  */\r
278 #ifndef BOARD_OSC32_SELCURR\r
279 #   define BOARD_OSC32_SELCURR     BSCIF_OSCCTRL32_SELCURR(10)\r
280 #endif\r
281 \r
282 /**\r
283  * \name RC oscillator frequency limits\r
284  * The frequency of the internal RC oscillators may drift a bit as a\r
285  * result of temperature changes. These definitions provide upper and\r
286  * lower limits which may be used to calculate upper and lower limits of\r
287  * timeouts, derived clock frequencies, etc.\r
288  */\r
289 //@{\r
290 //! Nominal frequency of RCSYS in Hz\r
291 #define OSC_RCSYS_NOMINAL_HZ    115000\r
292 //! Minimum frequency of RCSYS in Hz\r
293 #define OSC_RCSYS_MIN_HZ        100000\r
294 //! Maximum frequency of RCSYS in Hz\r
295 #define OSC_RCSYS_MAX_HZ        120000\r
296 \r
297 //! Nominal frequency of RC32K in Hz\r
298 #define OSC_RC32K_NOMINAL_HZ    32768\r
299 //! Minimum frequency of RC32K in Hz\r
300 #define OSC_RC32K_MIN_HZ        20000\r
301 //! Maximum frequency of RC32K in Hz\r
302 #define OSC_RC32K_MAX_HZ        44000\r
303 \r
304 //! Nominal frequency of RC80M in Hz\r
305 #define OSC_RC80M_NOMINAL_HZ    80000000\r
306 \r
307 //! Nominal frequency of RCFAST4M in Hz\r
308 #define OSC_RCFAST4M_NOMINAL_HZ 4000000\r
309 \r
310 //! Nominal frequency of RCFAST8M in Hz\r
311 #define OSC_RCFAST8M_NOMINAL_HZ 8000000\r
312 \r
313 //! Nominal frequency of RCFAST12M in Hz\r
314 #define OSC_RCFAST12M_NOMINAL_HZ 12000000\r
315 \r
316 //! Nominal frequency of RC1M in Hz\r
317 #define OSC_RC1M_NOMINAL_HZ     1000000\r
318 //@}\r
319 \r
320 #ifndef __ASSEMBLY__\r
321 \r
322 #include <compiler.h>\r
323 \r
324 extern void osc_priv_enable_osc0(void);\r
325 extern void osc_priv_disable_osc0(void);\r
326 extern void osc_priv_enable_osc32(void);\r
327 extern void osc_priv_disable_osc32(void);\r
328 extern void osc_priv_enable_rc32k(void);\r
329 extern void osc_priv_disable_rc32k(void);\r
330 extern void osc_priv_enable_rc80m(void);\r
331 extern void osc_priv_disable_rc80m(void);\r
332 extern void osc_priv_enable_rcfast(void);\r
333 extern void osc_priv_disable_rcfast(void);\r
334 extern void osc_priv_enable_rc1m(void);\r
335 extern void osc_priv_disable_rc1m(void);\r
336 \r
337 static inline void osc_enable(uint8_t id)\r
338 {\r
339         switch (id) {\r
340 #ifdef BOARD_OSC0_HZ\r
341         case OSC_ID_OSC0:\r
342                 osc_priv_enable_osc0();\r
343                 break;\r
344 #endif\r
345 \r
346 #ifdef BOARD_OSC32_HZ\r
347         case OSC_ID_OSC32:\r
348                 osc_priv_enable_osc32();\r
349                 break;\r
350 #endif\r
351 \r
352         case OSC_ID_RC32K:\r
353                 osc_priv_enable_rc32k();\r
354                 break;\r
355 \r
356         case OSC_ID_RC80M:\r
357                 osc_priv_enable_rc80m();\r
358                 break;\r
359 \r
360         case OSC_ID_RCFAST:\r
361                 osc_priv_enable_rcfast();\r
362                 break;\r
363 \r
364         case OSC_ID_RC1M:\r
365                 osc_priv_enable_rc1m();\r
366                 break;\r
367 \r
368         case OSC_ID_RCSYS:\r
369                 /* RCSYS is always running */\r
370                 break;\r
371 \r
372         default:\r
373                 /* unhandled_case(id); */\r
374                 break;\r
375         }\r
376 }\r
377 \r
378 static inline void osc_disable(uint8_t id)\r
379 {\r
380         switch (id) {\r
381 #ifdef BOARD_OSC0_HZ\r
382         case OSC_ID_OSC0:\r
383                 osc_priv_disable_osc0();\r
384                 break;\r
385 #endif\r
386 \r
387 #ifdef BOARD_OSC32_HZ\r
388         case OSC_ID_OSC32:\r
389                 osc_priv_disable_osc32();\r
390                 break;\r
391 #endif\r
392 \r
393         case OSC_ID_RC32K:\r
394                 osc_priv_disable_rc32k();\r
395                 break;\r
396 \r
397         case OSC_ID_RC80M:\r
398                 osc_priv_disable_rc80m();\r
399                 break;\r
400 \r
401         case OSC_ID_RCFAST:\r
402                 osc_priv_disable_rcfast();\r
403                 break;\r
404 \r
405         case OSC_ID_RC1M:\r
406                 osc_priv_disable_rc1m();\r
407                 break;\r
408 \r
409         case OSC_ID_RCSYS:\r
410                 /* RCSYS is always running */\r
411                 break;\r
412 \r
413         default:\r
414                 /* unhandled_case(id); */\r
415                 break;\r
416         }\r
417 }\r
418 \r
419 static inline bool osc_is_ready(uint8_t id)\r
420 {\r
421         switch (id) {\r
422 #ifdef BOARD_OSC0_HZ\r
423         case OSC_ID_OSC0:\r
424                 return !!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_OSC0RDY);\r
425 #endif\r
426 \r
427 #ifdef BOARD_OSC32_HZ\r
428         case OSC_ID_OSC32:\r
429                 return !!(BSCIF->BSCIF_PCLKSR & BSCIF_PCLKSR_OSC32RDY);\r
430 #endif\r
431 \r
432         case OSC_ID_RC32K:\r
433                 return !!(BSCIF->BSCIF_RC32KCR & (BSCIF_RC32KCR_EN));\r
434 \r
435         case OSC_ID_RC80M:\r
436                 return !!(SCIF->SCIF_RC80MCR & (SCIF_RC80MCR_EN));\r
437 \r
438         case OSC_ID_RCFAST:\r
439                 return !!(SCIF->SCIF_RCFASTCFG & (SCIF_RCFASTCFG_EN));\r
440 \r
441         case OSC_ID_RC1M:\r
442                 return !!(BSCIF->BSCIF_RC1MCR & (BSCIF_RC1MCR_CLKOE));\r
443 \r
444         case OSC_ID_RCSYS:\r
445                 /* RCSYS is always ready */\r
446                 return true;\r
447 \r
448         default:\r
449                 /* unhandled_case(id); */\r
450                 return false;\r
451         }\r
452 }\r
453 \r
454 static inline uint32_t osc_get_rate(uint8_t id)\r
455 {\r
456         switch (id) {\r
457 #ifdef BOARD_OSC0_HZ\r
458         case OSC_ID_OSC0:\r
459                 return BOARD_OSC0_HZ;\r
460 #endif\r
461 \r
462 #ifdef BOARD_OSC32_HZ\r
463         case OSC_ID_OSC32:\r
464                 return BOARD_OSC32_HZ;\r
465 #endif\r
466 \r
467         case OSC_ID_RC32K:\r
468                 return OSC_RC32K_NOMINAL_HZ;\r
469 \r
470         case OSC_ID_RC80M:\r
471                 return OSC_RC80M_NOMINAL_HZ;\r
472 \r
473         case OSC_ID_RCFAST:\r
474                 if (CONFIG_RCFAST_FRANGE == 2) {\r
475                         return OSC_RCFAST12M_NOMINAL_HZ;\r
476 \r
477                 } else if (CONFIG_RCFAST_FRANGE == 1) {\r
478                         return OSC_RCFAST8M_NOMINAL_HZ;\r
479 \r
480                 } else {\r
481                         return OSC_RCFAST4M_NOMINAL_HZ;\r
482                 }\r
483 \r
484         case OSC_ID_RC1M:\r
485                 return OSC_RC1M_NOMINAL_HZ;\r
486 \r
487         case OSC_ID_RCSYS:\r
488                 return OSC_RCSYS_NOMINAL_HZ;\r
489 \r
490         default:\r
491                 /* unhandled_case(id); */\r
492                 return 0;\r
493         }\r
494 }\r
495 \r
496 #endif /* !__ASSEMBLY__ */\r
497 \r
498 //! @}\r
499 \r
500 #ifdef __cplusplus\r
501 }\r
502 #endif\r
503 \r
504 #endif /* CHIP_OSC_H_INCLUDED */\r