4 * \brief SAM D20 Clock Driver
\r
6 * Copyright (C) 2012-2013 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
44 #include <conf_clocks.h>
\r
48 * \brief DFLL-specific data container
\r
50 struct _system_clock_dfll_config {
\r
58 * \brief XOSC-specific data container
\r
60 struct _system_clock_xosc_config {
\r
66 * \brief System clock module data container
\r
68 struct _system_clock_module {
\r
69 volatile struct _system_clock_dfll_config dfll;
\r
70 volatile struct _system_clock_xosc_config xosc;
\r
71 volatile struct _system_clock_xosc_config xosc32k;
\r
76 * \brief Internal module instance to cache configuration values
\r
78 static struct _system_clock_module _system_clock_inst = {
\r
94 * \brief Wait for sync to the DFLL control registers
\r
96 static inline void _system_dfll_wait_for_sync(void)
\r
98 while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY)) {
\r
99 /* Wait for DFLL sync */
\r
105 * \brief Wait for sync to the OSC32K control registers
\r
107 static inline void _system_osc32k_wait_for_sync(void)
\r
109 while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY)) {
\r
110 /* Wait for OSC32K sync */
\r
114 static inline void _system_clock_source_dfll_set_config_errata_9905(void)
\r
117 /* Disable ONDEMAND mode while writing configurations */
\r
118 SYSCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control & ~SYSCTRL_DFLLCTRL_ONDEMAND;
\r
119 _system_dfll_wait_for_sync();
\r
121 SYSCTRL->DFLLMUL.reg = _system_clock_inst.dfll.mul;
\r
122 SYSCTRL->DFLLVAL.reg = _system_clock_inst.dfll.val;
\r
124 /* Write full configuration to DFLL control register */
\r
125 SYSCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control;
\r
129 * \brief Retrieve the frequency of a clock source
\r
131 * Determines the current operating frequency of a given clock source.
\r
133 * \param[in] clock_source Clock source to get the frequency of
\r
135 * \returns Frequency of the given clock source, in Hz
\r
137 uint32_t system_clock_source_get_hz(
\r
138 const enum system_clock_source clock_source)
\r
140 switch (clock_source) {
\r
141 case SYSTEM_CLOCK_SOURCE_XOSC:
\r
142 return _system_clock_inst.xosc.frequency;
\r
144 case SYSTEM_CLOCK_SOURCE_OSC8M:
\r
145 return 8000000UL >> SYSCTRL->OSC8M.bit.PRESC;
\r
147 case SYSTEM_CLOCK_SOURCE_OSC32K:
\r
150 case SYSTEM_CLOCK_SOURCE_ULP32K:
\r
153 case SYSTEM_CLOCK_SOURCE_XOSC32K:
\r
154 return _system_clock_inst.xosc32k.frequency;
\r
156 case SYSTEM_CLOCK_SOURCE_DFLL:
\r
158 /* Check if the DFLL has been configured */
\r
159 if (!(_system_clock_inst.dfll.control & SYSCTRL_DFLLCTRL_ENABLE))
\r
162 /* Make sure that the DFLL module is ready */
\r
163 _system_dfll_wait_for_sync();
\r
165 /* Check if operating in closed loop mode */
\r
166 if (_system_clock_inst.dfll.control & SYSCTRL_DFLLCTRL_MODE) {
\r
167 return system_gclk_chan_get_hz(SYSCTRL_GCLK_ID_DFLL48) *
\r
168 (_system_clock_inst.dfll.mul & 0xffff);
\r
179 * \brief Configure the internal OSC8M oscillator clock source
\r
181 * Configures the 8MHz (nominal) internal RC oscillator with the given
\r
182 * configuration settings.
\r
184 * \param[in] config OSC8M configuration structure containing the new config
\r
186 void system_clock_source_osc8m_set_config(
\r
187 struct system_clock_source_osc8m_config *const config)
\r
189 SYSCTRL_OSC8M_Type temp = SYSCTRL->OSC8M;
\r
191 /* Use temporary struct to reduce register access */
\r
192 temp.bit.PRESC = config->prescaler;
\r
193 temp.bit.ONDEMAND = config->on_demand;
\r
194 temp.bit.RUNSTDBY = config->run_in_standby;
\r
196 SYSCTRL->OSC8M = temp;
\r
200 * \brief Configure the internal OSC32K oscillator clock source
\r
202 * Configures the 32KHz (nominal) internal RC oscillator with the given
\r
203 * configuration settings.
\r
205 * \param[in] config OSC32K configuration structure containing the new config
\r
207 void system_clock_source_osc32k_set_config(
\r
208 struct system_clock_source_osc32k_config *const config)
\r
210 SYSCTRL_OSC32K_Type temp = SYSCTRL->OSC32K;
\r
212 /* Update settings via a temporary struct to reduce register access */
\r
213 temp.bit.EN1K = config->enable_1khz_output;
\r
214 temp.bit.EN32K = config->enable_32khz_output;
\r
215 temp.bit.STARTUP = config->startup_time;
\r
216 temp.bit.ONDEMAND = config->on_demand;
\r
217 temp.bit.RUNSTDBY = config->run_in_standby;
\r
219 SYSCTRL->OSC32K = temp;
\r
223 * \brief Configure the external oscillator clock source
\r
225 * Configures the external oscillator clock source with the given configuration
\r
228 * \param[in] config External oscillator configuration structure containing
\r
231 void system_clock_source_xosc_set_config(
\r
232 struct system_clock_source_xosc_config *const config)
\r
234 SYSCTRL_XOSC_Type temp = SYSCTRL->XOSC;
\r
236 temp.bit.STARTUP = config->startup_time;
\r
238 if (config->external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) {
\r
239 temp.bit.XTALEN = 1;
\r
241 temp.bit.XTALEN = 0;
\r
244 temp.bit.AMPGC = config->auto_gain_control;
\r
246 /* Set gain if automatic gain control is not selected */
\r
247 if (!config->auto_gain_control) {
\r
248 if (config->frequency <= 2000000) {
\r
250 } else if (config->frequency <= 4000000) {
\r
252 } else if (config->frequency <= 8000000) {
\r
254 } else if (config->frequency <= 16000000) {
\r
256 } else if (config->frequency <= 30000000) {
\r
262 temp.bit.ONDEMAND = config->on_demand;
\r
263 temp.bit.RUNSTDBY = config->run_in_standby;
\r
265 /* Store XOSC frequency for internal use */
\r
266 _system_clock_inst.xosc.frequency = config->frequency;
\r
268 SYSCTRL->XOSC = temp;
\r
272 * \brief Configure the XOSC32K external 32KHz oscillator clock source
\r
274 * Configures the external 32KHz oscillator clock source with the given
\r
275 * configuration settings.
\r
277 * \param[in] config XOSC32K configuration structure containing the new config
\r
279 void system_clock_source_xosc32k_set_config(
\r
280 struct system_clock_source_xosc32k_config *const config)
\r
282 SYSCTRL_XOSC32K_Type temp = SYSCTRL->XOSC32K;
\r
284 temp.bit.STARTUP = config->startup_time;
\r
286 if (config->external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) {
\r
287 temp.bit.XTALEN = 1;
\r
289 temp.bit.XTALEN = 0;
\r
292 temp.bit.AAMPEN = config->auto_gain_control;
\r
293 temp.bit.EN1K = config->enable_1khz_output;
\r
294 temp.bit.EN32K = config->enable_32khz_output;
\r
296 temp.bit.ONDEMAND = config->on_demand;
\r
297 temp.bit.RUNSTDBY = config->run_in_standby;
\r
299 /* Cache the new frequency in case the user needs to check the current
\r
300 * operating frequency later */
\r
301 _system_clock_inst.xosc32k.frequency = config->frequency;
\r
303 SYSCTRL->XOSC32K = temp;
\r
307 * \brief Configure the DFLL clock source
\r
309 * Configures the Digital Frequency Locked Loop clock source with the given
\r
310 * configuration settings.
\r
312 * \note The DFLL will be running when this function returns, as the DFLL module
\r
313 * needs to be enabled in order to perform the module configuration.
\r
315 * \param[in] config DFLL configuration structure containing the new config
\r
317 void system_clock_source_dfll_set_config(
\r
318 struct system_clock_source_dfll_config *const config)
\r
320 _system_clock_inst.dfll.val =
\r
321 SYSCTRL_DFLLVAL_COARSE(config->coarse_value) |
\r
322 SYSCTRL_DFLLVAL_FINE(config->fine_value);
\r
324 _system_clock_inst.dfll.control =
\r
325 (uint32_t)config->wakeup_lock |
\r
326 (uint32_t)config->stable_tracking |
\r
327 (uint32_t)config->quick_lock |
\r
328 (uint32_t)config->chill_cycle |
\r
329 (uint32_t)config->run_in_standby << SYSCTRL_DFLLCTRL_RUNSTDBY_Pos |
\r
330 (uint32_t)config->on_demand << SYSCTRL_DFLLCTRL_ONDEMAND_Pos;
\r
332 if (config->loop_mode == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
\r
333 _system_clock_inst.dfll.mul =
\r
334 SYSCTRL_DFLLMUL_CSTEP(config->coarse_max_step) |
\r
335 SYSCTRL_DFLLMUL_FSTEP(config->fine_max_step) |
\r
336 SYSCTRL_DFLLMUL_MUL(config->multiply_factor);
\r
338 /* Enable the closed loop mode */
\r
339 _system_clock_inst.dfll.control |= config->loop_mode;
\r
344 * \brief Writes the calibration values for a given oscillator clock source
\r
346 * Writes an oscillator calibration value to the given oscillator control
\r
347 * registers. The acceptable ranges are:
\r
350 * - 7 bits (max value 128)
\r
352 * - 8 bits (Max value 255)
\r
354 * - 5 bits (Max value 32)
\r
356 * \note The frequency range parameter applies only when configuring the 8MHz
\r
357 * oscillator and will be ignored for the other oscillators.
\r
359 * \param[in] clock_source Clock source to calibrate
\r
360 * \param[in] calibration_value Calibration value to write
\r
361 * \param[in] freq_range Frequency range (8MHz oscillator only)
\r
363 * \retval STATUS_ERR_INVALID_ARG The selected clock source is not available
\r
365 enum status_code system_clock_source_write_calibration(
\r
366 const enum system_clock_source clock_source,
\r
367 const uint16_t calibration_value,
\r
368 const uint8_t freq_range)
\r
370 switch (clock_source) {
\r
371 case SYSTEM_CLOCK_SOURCE_OSC8M:
\r
373 if (calibration_value > 0xfff || freq_range > 4) {
\r
374 return STATUS_ERR_INVALID_ARG;
\r
377 SYSCTRL->OSC8M.bit.CALIB = calibration_value;
\r
378 SYSCTRL->OSC8M.bit.FRANGE = freq_range;
\r
381 case SYSTEM_CLOCK_SOURCE_OSC32K:
\r
383 if (calibration_value > 128) {
\r
384 return STATUS_ERR_INVALID_ARG;
\r
387 _system_osc32k_wait_for_sync();
\r
388 SYSCTRL->OSC32K.bit.CALIB = calibration_value;
\r
391 case SYSTEM_CLOCK_SOURCE_ULP32K:
\r
393 if (calibration_value > 32) {
\r
394 return STATUS_ERR_INVALID_ARG;
\r
397 SYSCTRL->OSCULP32K.bit.CALIB = calibration_value;
\r
402 return STATUS_ERR_INVALID_ARG;
\r
410 * \brief Enables a clock source
\r
412 * Enables a clock source which has been previously configured.
\r
414 * \param[in] clock_source Clock source to enable
\r
416 * \retval STATUS_OK Clock source was enabled successfully and
\r
418 * \retval STATUS_ERR_INVALID_ARG The clock source is not available on this
\r
421 * \retval STATUS_ERR_NOT_INITIALIZED DFLL configuration is not initialized
\r
423 enum status_code system_clock_source_enable(
\r
424 const enum system_clock_source clock_source)
\r
426 switch (clock_source) {
\r
427 case SYSTEM_CLOCK_SOURCE_OSC8M:
\r
428 SYSCTRL->OSC8M.reg |= SYSCTRL_OSC8M_ENABLE;
\r
431 case SYSTEM_CLOCK_SOURCE_OSC32K:
\r
432 SYSCTRL->OSC32K.reg |= SYSCTRL_OSC32K_ENABLE;
\r
435 case SYSTEM_CLOCK_SOURCE_XOSC:
\r
436 SYSCTRL->XOSC.reg |= SYSCTRL_XOSC_ENABLE;
\r
439 case SYSTEM_CLOCK_SOURCE_XOSC32K:
\r
440 SYSCTRL->XOSC32K.reg |= SYSCTRL_XOSC32K_ENABLE;
\r
443 case SYSTEM_CLOCK_SOURCE_DFLL:
\r
444 _system_clock_inst.dfll.control |= SYSCTRL_DFLLCTRL_ENABLE;
\r
445 _system_clock_source_dfll_set_config_errata_9905();
\r
448 case SYSTEM_CLOCK_SOURCE_ULP32K:
\r
449 /* Always enabled */
\r
454 return STATUS_ERR_INVALID_ARG;
\r
461 * \brief Disables a clock source
\r
463 * Disables a clock source that was previously enabled.
\r
465 * \param[in] clock_source Clock source to disable
\r
467 * \retval STATUS_OK Clock source was disabled successfully
\r
468 * \retval STATUS_ERR_INVALID_ARG An invalid or unavailable clock source was
\r
471 enum status_code system_clock_source_disable(
\r
472 const enum system_clock_source clock_source)
\r
474 switch (clock_source) {
\r
475 case SYSTEM_CLOCK_SOURCE_OSC8M:
\r
476 SYSCTRL->OSC8M.reg &= ~SYSCTRL_OSC8M_ENABLE;
\r
479 case SYSTEM_CLOCK_SOURCE_OSC32K:
\r
480 SYSCTRL->OSC32K.reg &= ~SYSCTRL_OSC32K_ENABLE;
\r
483 case SYSTEM_CLOCK_SOURCE_XOSC:
\r
484 SYSCTRL->XOSC.reg &= ~SYSCTRL_XOSC_ENABLE;
\r
487 case SYSTEM_CLOCK_SOURCE_XOSC32K:
\r
488 SYSCTRL->XOSC32K.reg &= ~SYSCTRL_XOSC32K_ENABLE;
\r
491 case SYSTEM_CLOCK_SOURCE_DFLL:
\r
492 _system_clock_inst.dfll.control &= ~SYSCTRL_DFLLCTRL_ENABLE;
\r
493 SYSCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control;
\r
496 case SYSTEM_CLOCK_SOURCE_ULP32K:
\r
497 /* Not possible to disable */
\r
498 return STATUS_ERR_INVALID_ARG;
\r
501 return STATUS_ERR_INVALID_ARG;
\r
508 * \brief Checks if a clock source is ready
\r
510 * Checks if a given clock source is ready to be used.
\r
512 * \param[in] clock_source Clock source to check if ready
\r
514 * \returns Ready state of the given clock source.
\r
516 * \retval true Clock source is enabled and ready
\r
517 * \retval false Clock source is disabled or not yet ready
\r
519 bool system_clock_source_is_ready(
\r
520 const enum system_clock_source clock_source)
\r
524 switch (clock_source) {
\r
525 case SYSTEM_CLOCK_SOURCE_OSC8M:
\r
526 mask = SYSCTRL_PCLKSR_OSC8MRDY;
\r
529 case SYSTEM_CLOCK_SOURCE_OSC32K:
\r
530 mask = SYSCTRL_PCLKSR_OSC32KRDY;
\r
533 case SYSTEM_CLOCK_SOURCE_XOSC:
\r
534 mask = SYSCTRL_PCLKSR_XOSCRDY;
\r
537 case SYSTEM_CLOCK_SOURCE_XOSC32K:
\r
538 mask = SYSCTRL_PCLKSR_XOSC32KRDY;
\r
541 case SYSTEM_CLOCK_SOURCE_DFLL:
\r
542 mask = SYSCTRL_PCLKSR_DFLLRDY;
\r
545 case SYSTEM_CLOCK_SOURCE_ULP32K:
\r
546 /* Not possible to disable */
\r
553 return ((SYSCTRL->PCLKSR.reg & mask) != 0);
\r
556 /* Include some checks for conf_clocks.h validation */
\r
557 #include "clock_config_check.h"
\r
559 #if !defined(__DOXYGEN__)
\r
562 * Configures a Generic Clock Generator with the configuration from \c conf_clocks.h.
\r
564 # define _CONF_CLOCK_GCLK_CONFIG(n, unused) \
\r
565 if (CONF_CLOCK_GCLK_##n##_ENABLE == true) { \
\r
566 struct system_gclk_gen_config gclk_conf; \
\r
567 system_gclk_gen_get_config_defaults(&gclk_conf); \
\r
568 gclk_conf.source_clock = CONF_CLOCK_GCLK_##n##_CLOCK_SOURCE; \
\r
569 gclk_conf.division_factor = CONF_CLOCK_GCLK_##n##_PRESCALER; \
\r
570 gclk_conf.run_in_standby = CONF_CLOCK_GCLK_##n##_RUN_IN_STANDBY; \
\r
571 gclk_conf.output_enable = CONF_CLOCK_GCLK_##n##_OUTPUT_ENABLE; \
\r
572 system_gclk_gen_set_config(GCLK_GENERATOR_##n, &gclk_conf); \
\r
573 system_gclk_gen_enable(GCLK_GENERATOR_##n); \
\r
578 * Configures a Generic Clock Generator with the configuration from \c conf_clocks.h,
\r
579 * provided that it is not the main Generic Clock Generator channel.
\r
581 # define _CONF_CLOCK_GCLK_CONFIG_NONMAIN(n, unused) \
\r
582 if (n > 0) { _CONF_CLOCK_GCLK_CONFIG(n, unused); }
\r
586 * \brief Initialize clock system based on the configuration in conf_clocks.h
\r
588 * This function will apply the settings in conf_clocks.h when run from the user
\r
589 * application. All clock sources and GCLK generators are running when this function
\r
592 void system_clock_init(void)
\r
594 /* Workaround for errata 10558 */
\r
595 SYSCTRL->INTFLAG.reg = SYSCTRL_INTFLAG_BOD12RDY | SYSCTRL_INTFLAG_BOD33RDY |
\r
596 SYSCTRL_INTFLAG_BOD12DET | SYSCTRL_INTFLAG_BOD33DET |
\r
597 SYSCTRL_INTFLAG_DFLLRDY;
\r
599 system_flash_set_waitstates(CONF_CLOCK_FLASH_WAIT_STATES);
\r
602 #if CONF_CLOCK_XOSC_ENABLE == true
\r
603 struct system_clock_source_xosc_config xosc_conf;
\r
604 system_clock_source_xosc_get_config_defaults(&xosc_conf);
\r
606 xosc_conf.external_clock = CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL;
\r
607 xosc_conf.startup_time = CONF_CLOCK_XOSC_STARTUP_TIME;
\r
608 xosc_conf.auto_gain_control = CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL;
\r
609 xosc_conf.frequency = CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY;
\r
610 xosc_conf.on_demand = CONF_CLOCK_XOSC_ON_DEMAND;
\r
611 xosc_conf.run_in_standby = CONF_CLOCK_XOSC_RUN_IN_STANDBY;
\r
613 system_clock_source_xosc_set_config(&xosc_conf);
\r
614 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC);
\r
619 #if CONF_CLOCK_XOSC32K_ENABLE == true
\r
620 struct system_clock_source_xosc32k_config xosc32k_conf;
\r
621 system_clock_source_xosc32k_get_config_defaults(&xosc32k_conf);
\r
623 xosc32k_conf.frequency = 32768UL;
\r
624 xosc32k_conf.external_clock = CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL;
\r
625 xosc32k_conf.startup_time = CONF_CLOCK_XOSC32K_STARTUP_TIME;
\r
626 xosc32k_conf.auto_gain_control = CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL;
\r
627 xosc32k_conf.enable_1khz_output = CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT;
\r
628 xosc32k_conf.enable_32khz_output = CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT;
\r
629 xosc32k_conf.on_demand = CONF_CLOCK_XOSC32K_ON_DEMAND;
\r
630 xosc32k_conf.run_in_standby = CONF_CLOCK_XOSC32K_RUN_IN_STANDBY;
\r
632 system_clock_source_xosc32k_set_config(&xosc32k_conf);
\r
633 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
\r
638 #if CONF_CLOCK_OSC32K_ENABLE == true
\r
639 SYSCTRL->OSC32K.bit.CALIB =
\r
640 (*(uint32_t *)SYSCTRL_FUSES_OSC32KCAL_ADDR >> SYSCTRL_FUSES_OSC32KCAL_Pos);
\r
642 struct system_clock_source_osc32k_config osc32k_conf;
\r
643 system_clock_source_osc32k_get_config_defaults(&osc32k_conf);
\r
645 osc32k_conf.startup_time = CONF_CLOCK_OSC32K_STARTUP_TIME;
\r
646 osc32k_conf.enable_1khz_output = CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT;
\r
647 osc32k_conf.enable_32khz_output = CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT;
\r
648 osc32k_conf.on_demand = CONF_CLOCK_OSC32K_ON_DEMAND;
\r
649 osc32k_conf.run_in_standby = CONF_CLOCK_OSC32K_RUN_IN_STANDBY;
\r
651 system_clock_source_osc32k_set_config(&osc32k_conf);
\r
652 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC32K);
\r
656 /* DFLL (Open and Closed Loop) */
\r
657 #if CONF_CLOCK_DFLL_ENABLE == true
\r
658 struct system_clock_source_dfll_config dfll_conf;
\r
659 system_clock_source_dfll_get_config_defaults(&dfll_conf);
\r
661 dfll_conf.loop_mode = CONF_CLOCK_DFLL_LOOP_MODE;
\r
662 dfll_conf.on_demand = CONF_CLOCK_DFLL_ON_DEMAND;
\r
663 dfll_conf.run_in_standby = CONF_CLOCK_DFLL_RUN_IN_STANDBY;
\r
665 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN) {
\r
666 dfll_conf.coarse_value = CONF_CLOCK_DFLL_COARSE_VALUE;
\r
667 dfll_conf.fine_value = CONF_CLOCK_DFLL_FINE_VALUE;
\r
670 # if CONF_CLOCK_DFLL_QUICK_LOCK == true
\r
671 dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE;
\r
673 dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_DISABLE;
\r
676 # if CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK == true
\r
677 dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK;
\r
679 dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_FIX_AFTER_LOCK;
\r
682 # if CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP == true
\r
683 dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP;
\r
685 dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_LOSE;
\r
688 # if CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE == true
\r
689 dfll_conf.chill_cycle = SYSTEM_CLOCK_DFLL_CHILL_CYCLE_ENABLE;
\r
691 dfll_conf.chill_cycle = SYSTEM_CLOCK_DFLL_CHILL_CYCLE_DISABLE;
\r
694 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
\r
695 dfll_conf.multiply_factor = CONF_CLOCK_DFLL_MULTIPLY_FACTOR;
\r
698 dfll_conf.coarse_max_step = CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE;
\r
699 dfll_conf.fine_max_step = CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE;
\r
701 system_clock_source_dfll_set_config(&dfll_conf);
\r
702 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);
\r
707 struct system_clock_source_osc8m_config osc8m_conf;
\r
708 system_clock_source_osc8m_get_config_defaults(&osc8m_conf);
\r
710 osc8m_conf.prescaler = CONF_CLOCK_OSC8M_PRESCALER;
\r
711 osc8m_conf.on_demand = CONF_CLOCK_OSC8M_ON_DEMAND;
\r
712 osc8m_conf.run_in_standby = CONF_CLOCK_OSC8M_RUN_IN_STANDBY;
\r
714 system_clock_source_osc8m_set_config(&osc8m_conf);
\r
715 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC8M);
\r
719 #if CONF_CLOCK_CONFIGURE_GCLK == true
\r
720 system_gclk_init();
\r
722 /* Configure all GCLK generators except for the main generator, which
\r
723 * is configured later after all other clock systems are set up */
\r
724 MREPEAT(GCLK_GEN_NUM_MSB, _CONF_CLOCK_GCLK_CONFIG_NONMAIN, ~);
\r
726 # if (CONF_CLOCK_DFLL_ENABLE)
\r
727 /* Enable DFLL reference clock if in closed loop mode */
\r
728 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
\r
729 struct system_gclk_chan_config dfll_gclk_chan_conf;
\r
731 system_gclk_chan_get_config_defaults(&dfll_gclk_chan_conf);
\r
732 dfll_gclk_chan_conf.source_generator = CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR;
\r
733 system_gclk_chan_set_config(SYSCTRL_GCLK_ID_DFLL48, &dfll_gclk_chan_conf);
\r
734 system_gclk_chan_enable(SYSCTRL_GCLK_ID_DFLL48);
\r
738 /* Configure the main GCLK last as it might depend on other generators */
\r
739 _CONF_CLOCK_GCLK_CONFIG(0, ~);
\r
743 /* CPU and BUS clocks */
\r
744 system_cpu_clock_set_divider(CONF_CLOCK_CPU_DIVIDER);
\r
745 system_main_clock_set_failure_detect(CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT);
\r
746 system_apb_clock_set_divider(SYSTEM_CLOCK_APB_APBA, CONF_CLOCK_APBA_DIVIDER);
\r
747 system_apb_clock_set_divider(SYSTEM_CLOCK_APB_APBB, CONF_CLOCK_APBB_DIVIDER);
\r