4 * \brief Chip-specific oscillator management functions
\r
6 * Copyright (c) 2012 Atmel Corporation. All rights reserved.
\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
15 * 1. Redistributions of source code must retain the above copyright notice,
\r
16 * this list of conditions and the following disclaimer.
\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
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
25 * 4. This software may only be redistributed and used in connection with an
\r
26 * Atmel microcontroller product.
\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
43 #ifndef CHIP_OSC_H_INCLUDED
\r
44 #define CHIP_OSC_H_INCLUDED
\r
54 * \weakgroup osc_group
\r
58 //! \name Oscillator identifiers
\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
69 //! \name OSC0 mode values
\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
77 //! \name OSC32 mode values
\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
87 //! \name OSC0 startup values
\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
107 //! \name OSC32 startup values
\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
128 * \def OSC0_STARTUP_TIMEOUT
\r
129 * \brief Number of slow clock cycles to wait for OSC0 to start
\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
137 * \def OSC0_MODE_VALUE
\r
138 * \brief Board-dependent value written to the MODE bitfield of
\r
142 * \def OSC0_STARTUP_VALUE
\r
143 * \brief Board-dependent value written to the STARTUP bitfield of
\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
172 # error BOARD_OSC0_STARTUP_US is too high
\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
185 # define OSC0_GAIN_VALUE ((0x1u << 4) | SCIF_OSCCTRL0_GAIN(0))
\r
188 # define OSC0_MODE_VALUE OSC_MODE_EXTERNAL
\r
191 # if defined(BOARD_OSC0_HZ)
\r
192 # error BOARD_OSC0_STARTUP_US must be defined by the board code
\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
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
219 # error BOARD_OSC32_STARTUP_US is too high
\r
221 # if BOARD_OSC32_IS_XTAL == true
\r
222 # define OSC32_MODE_VALUE OSC32_MODE_XTAL
\r
224 # define OSC32_MODE_VALUE OSC32_MODE_EXTERNAL
\r
227 # if defined(BOARD_OSC32_HZ)
\r
228 # error BOARD_OSC32_STARTUP_US must be defined by the board code
\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
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
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
249 * \def BOARD_OSC0_HZ
\r
250 * \brief Clock frequency of OSC0 in Hz
\r
253 * \def BOARD_OSC0_STARTUP_US
\r
254 * \brief Startup time of OSC0 in microseconds
\r
257 * \def BOARD_OSC0_IS_XTAL
\r
258 * \brief OSC0 uses a crystal, not an external clock
\r
261 * \def BOARD_OSC32_HZ
\r
262 * \brief Clock frequency of OSC32 in Hz
\r
265 * \def BOARD_OSC32_STARTUP_US
\r
266 * \brief Startup time of OSC32 in microseconds
\r
269 * \def BOARD_OSC32_IS_XTAL
\r
270 * \brief OSC32 uses a crystal, not an external clock
\r
273 * \def BOARD_OSC32_SELCURR
\r
274 * \brief Crystal current selection for OSC32
\r
276 * If not defined, the recommended value (300nA) are used.
\r
278 #ifndef BOARD_OSC32_SELCURR
\r
279 # define BOARD_OSC32_SELCURR BSCIF_OSCCTRL32_SELCURR(10)
\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
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
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
304 //! Nominal frequency of RC80M in Hz
\r
305 #define OSC_RC80M_NOMINAL_HZ 80000000
\r
307 //! Nominal frequency of RCFAST4M in Hz
\r
308 #define OSC_RCFAST4M_NOMINAL_HZ 4000000
\r
310 //! Nominal frequency of RCFAST8M in Hz
\r
311 #define OSC_RCFAST8M_NOMINAL_HZ 8000000
\r
313 //! Nominal frequency of RCFAST12M in Hz
\r
314 #define OSC_RCFAST12M_NOMINAL_HZ 12000000
\r
316 //! Nominal frequency of RC1M in Hz
\r
317 #define OSC_RC1M_NOMINAL_HZ 1000000
\r
320 #ifndef __ASSEMBLY__
\r
322 #include <compiler.h>
\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
337 static inline void osc_enable(uint8_t id)
\r
340 #ifdef BOARD_OSC0_HZ
\r
342 osc_priv_enable_osc0();
\r
346 #ifdef BOARD_OSC32_HZ
\r
348 osc_priv_enable_osc32();
\r
353 osc_priv_enable_rc32k();
\r
357 osc_priv_enable_rc80m();
\r
360 case OSC_ID_RCFAST:
\r
361 osc_priv_enable_rcfast();
\r
365 osc_priv_enable_rc1m();
\r
369 /* RCSYS is always running */
\r
373 /* unhandled_case(id); */
\r
378 static inline void osc_disable(uint8_t id)
\r
381 #ifdef BOARD_OSC0_HZ
\r
383 osc_priv_disable_osc0();
\r
387 #ifdef BOARD_OSC32_HZ
\r
389 osc_priv_disable_osc32();
\r
394 osc_priv_disable_rc32k();
\r
398 osc_priv_disable_rc80m();
\r
401 case OSC_ID_RCFAST:
\r
402 osc_priv_disable_rcfast();
\r
406 osc_priv_disable_rc1m();
\r
410 /* RCSYS is always running */
\r
414 /* unhandled_case(id); */
\r
419 static inline bool osc_is_ready(uint8_t id)
\r
422 #ifdef BOARD_OSC0_HZ
\r
424 return !!(SCIF->SCIF_PCLKSR & SCIF_PCLKSR_OSC0RDY);
\r
427 #ifdef BOARD_OSC32_HZ
\r
429 return !!(BSCIF->BSCIF_PCLKSR & BSCIF_PCLKSR_OSC32RDY);
\r
433 return !!(BSCIF->BSCIF_RC32KCR & (BSCIF_RC32KCR_EN));
\r
436 return !!(SCIF->SCIF_RC80MCR & (SCIF_RC80MCR_EN));
\r
438 case OSC_ID_RCFAST:
\r
439 return !!(SCIF->SCIF_RCFASTCFG & (SCIF_RCFASTCFG_EN));
\r
442 return !!(BSCIF->BSCIF_RC1MCR & (BSCIF_RC1MCR_CLKOE));
\r
445 /* RCSYS is always ready */
\r
449 /* unhandled_case(id); */
\r
454 static inline uint32_t osc_get_rate(uint8_t id)
\r
457 #ifdef BOARD_OSC0_HZ
\r
459 return BOARD_OSC0_HZ;
\r
462 #ifdef BOARD_OSC32_HZ
\r
464 return BOARD_OSC32_HZ;
\r
468 return OSC_RC32K_NOMINAL_HZ;
\r
471 return OSC_RC80M_NOMINAL_HZ;
\r
473 case OSC_ID_RCFAST:
\r
474 if (CONFIG_RCFAST_FRANGE == 2) {
\r
475 return OSC_RCFAST12M_NOMINAL_HZ;
\r
477 } else if (CONFIG_RCFAST_FRANGE == 1) {
\r
478 return OSC_RCFAST8M_NOMINAL_HZ;
\r
481 return OSC_RCFAST4M_NOMINAL_HZ;
\r
485 return OSC_RC1M_NOMINAL_HZ;
\r
488 return OSC_RCSYS_NOMINAL_HZ;
\r
491 /* unhandled_case(id); */
\r
496 #endif /* !__ASSEMBLY__ */
\r
504 #endif /* CHIP_OSC_H_INCLUDED */
\r