mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Mon Nov 09 13:30:11 2015 +0000
Revision:
18:da299f395b9e
Synchronized with git revision f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3

Full URL: https://github.com/mbedmicro/mbed/commit/f605825f66bb2e462ff7dbc5fb4ed2dbe979d1c3/

Added support for SAML21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 18:da299f395b9e 1 /**
mbed_official 18:da299f395b9e 2 * \file
mbed_official 18:da299f395b9e 3 *
mbed_official 18:da299f395b9e 4 * \brief SAM L21 Clock Driver
mbed_official 18:da299f395b9e 5 *
mbed_official 18:da299f395b9e 6 * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
mbed_official 18:da299f395b9e 7 *
mbed_official 18:da299f395b9e 8 * \asf_license_start
mbed_official 18:da299f395b9e 9 *
mbed_official 18:da299f395b9e 10 * \page License
mbed_official 18:da299f395b9e 11 *
mbed_official 18:da299f395b9e 12 * Redistribution and use in source and binary forms, with or without
mbed_official 18:da299f395b9e 13 * modification, are permitted provided that the following conditions are met:
mbed_official 18:da299f395b9e 14 *
mbed_official 18:da299f395b9e 15 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 18:da299f395b9e 16 * this list of conditions and the following disclaimer.
mbed_official 18:da299f395b9e 17 *
mbed_official 18:da299f395b9e 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 18:da299f395b9e 19 * this list of conditions and the following disclaimer in the documentation
mbed_official 18:da299f395b9e 20 * and/or other materials provided with the distribution.
mbed_official 18:da299f395b9e 21 *
mbed_official 18:da299f395b9e 22 * 3. The name of Atmel may not be used to endorse or promote products derived
mbed_official 18:da299f395b9e 23 * from this software without specific prior written permission.
mbed_official 18:da299f395b9e 24 *
mbed_official 18:da299f395b9e 25 * 4. This software may only be redistributed and used in connection with an
mbed_official 18:da299f395b9e 26 * Atmel microcontroller product.
mbed_official 18:da299f395b9e 27 *
mbed_official 18:da299f395b9e 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
mbed_official 18:da299f395b9e 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 18:da299f395b9e 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
mbed_official 18:da299f395b9e 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
mbed_official 18:da299f395b9e 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
mbed_official 18:da299f395b9e 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
mbed_official 18:da299f395b9e 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
mbed_official 18:da299f395b9e 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
mbed_official 18:da299f395b9e 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
mbed_official 18:da299f395b9e 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 18:da299f395b9e 38 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 18:da299f395b9e 39 *
mbed_official 18:da299f395b9e 40 * \asf_license_stop
mbed_official 18:da299f395b9e 41 *
mbed_official 18:da299f395b9e 42 */
mbed_official 18:da299f395b9e 43 /*
mbed_official 18:da299f395b9e 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
mbed_official 18:da299f395b9e 45 */
mbed_official 18:da299f395b9e 46 #include <clock.h>
mbed_official 18:da299f395b9e 47 #include <conf_clocks.h>
mbed_official 18:da299f395b9e 48 #include <system.h>
mbed_official 18:da299f395b9e 49
mbed_official 18:da299f395b9e 50
mbed_official 18:da299f395b9e 51 /**
mbed_official 18:da299f395b9e 52 * \internal
mbed_official 18:da299f395b9e 53 * \brief DFLL-specific data container.
mbed_official 18:da299f395b9e 54 */
mbed_official 18:da299f395b9e 55 struct _system_clock_dfll_config {
mbed_official 18:da299f395b9e 56 uint32_t control;
mbed_official 18:da299f395b9e 57 uint32_t val;
mbed_official 18:da299f395b9e 58 uint32_t mul;
mbed_official 18:da299f395b9e 59 };
mbed_official 18:da299f395b9e 60
mbed_official 18:da299f395b9e 61 /**
mbed_official 18:da299f395b9e 62 * \internal
mbed_official 18:da299f395b9e 63 * \brief DPLL-specific data container.
mbed_official 18:da299f395b9e 64 */
mbed_official 18:da299f395b9e 65 struct _system_clock_dpll_config {
mbed_official 18:da299f395b9e 66 uint32_t frequency;
mbed_official 18:da299f395b9e 67 };
mbed_official 18:da299f395b9e 68
mbed_official 18:da299f395b9e 69
mbed_official 18:da299f395b9e 70 /**
mbed_official 18:da299f395b9e 71 * \internal
mbed_official 18:da299f395b9e 72 * \brief XOSC-specific data container.
mbed_official 18:da299f395b9e 73 */
mbed_official 18:da299f395b9e 74 struct _system_clock_xosc_config {
mbed_official 18:da299f395b9e 75 uint32_t frequency;
mbed_official 18:da299f395b9e 76 };
mbed_official 18:da299f395b9e 77
mbed_official 18:da299f395b9e 78 /**
mbed_official 18:da299f395b9e 79 * \internal
mbed_official 18:da299f395b9e 80 * \brief System clock module data container.
mbed_official 18:da299f395b9e 81 */
mbed_official 18:da299f395b9e 82 struct _system_clock_module {
mbed_official 18:da299f395b9e 83 volatile struct _system_clock_dfll_config dfll;
mbed_official 18:da299f395b9e 84 volatile struct _system_clock_dpll_config dpll;
mbed_official 18:da299f395b9e 85
mbed_official 18:da299f395b9e 86 volatile struct _system_clock_xosc_config xosc;
mbed_official 18:da299f395b9e 87 volatile struct _system_clock_xosc_config xosc32k;
mbed_official 18:da299f395b9e 88 };
mbed_official 18:da299f395b9e 89
mbed_official 18:da299f395b9e 90 /**
mbed_official 18:da299f395b9e 91 * \internal
mbed_official 18:da299f395b9e 92 * \brief Internal module instance to cache configuration values.
mbed_official 18:da299f395b9e 93 */
mbed_official 18:da299f395b9e 94 static struct _system_clock_module _system_clock_inst = {
mbed_official 18:da299f395b9e 95 .dfll = {
mbed_official 18:da299f395b9e 96 .control = 0,
mbed_official 18:da299f395b9e 97 .val = 0,
mbed_official 18:da299f395b9e 98 .mul = 0,
mbed_official 18:da299f395b9e 99 },
mbed_official 18:da299f395b9e 100 .dpll = {
mbed_official 18:da299f395b9e 101 .frequency = 0,
mbed_official 18:da299f395b9e 102 },
mbed_official 18:da299f395b9e 103 .xosc = {
mbed_official 18:da299f395b9e 104 .frequency = 0,
mbed_official 18:da299f395b9e 105 },
mbed_official 18:da299f395b9e 106 .xosc32k = {
mbed_official 18:da299f395b9e 107 .frequency = 0,
mbed_official 18:da299f395b9e 108 },
mbed_official 18:da299f395b9e 109 };
mbed_official 18:da299f395b9e 110
mbed_official 18:da299f395b9e 111 /**
mbed_official 18:da299f395b9e 112 * \internal
mbed_official 18:da299f395b9e 113 * \brief Wait for sync to the DFLL control registers.
mbed_official 18:da299f395b9e 114 */
mbed_official 18:da299f395b9e 115 static inline void _system_dfll_wait_for_sync(void)
mbed_official 18:da299f395b9e 116 {
mbed_official 18:da299f395b9e 117 while (!(OSCCTRL->STATUS.reg & OSCCTRL_STATUS_DFLLRDY)) {
mbed_official 18:da299f395b9e 118 /* Wait for DFLL sync */
mbed_official 18:da299f395b9e 119 }
mbed_official 18:da299f395b9e 120 }
mbed_official 18:da299f395b9e 121
mbed_official 18:da299f395b9e 122 /**
mbed_official 18:da299f395b9e 123 * \internal
mbed_official 18:da299f395b9e 124 * \brief Wait for sync to the OSC32K control registers.
mbed_official 18:da299f395b9e 125 */
mbed_official 18:da299f395b9e 126 static inline void _system_osc32k_wait_for_sync(void)
mbed_official 18:da299f395b9e 127 {
mbed_official 18:da299f395b9e 128 while (!(OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_OSC32KRDY)) {
mbed_official 18:da299f395b9e 129 /* Wait for OSC32K sync */
mbed_official 18:da299f395b9e 130 }
mbed_official 18:da299f395b9e 131 }
mbed_official 18:da299f395b9e 132
mbed_official 18:da299f395b9e 133 /**
mbed_official 18:da299f395b9e 134 * \internal
mbed_official 18:da299f395b9e 135 * \brief OSC16M frequency selection.
mbed_official 18:da299f395b9e 136 * Frequency selection can be done only when OSC16M is disabled,thus,
mbed_official 18:da299f395b9e 137 * OSCULP32K is temporarily used as a new clocksource for mainclock .
mbed_official 18:da299f395b9e 138 *
mbed_official 18:da299f395b9e 139 */
mbed_official 18:da299f395b9e 140 static inline void _system_clock_source_osc16m_freq_sel(void)
mbed_official 18:da299f395b9e 141 {
mbed_official 18:da299f395b9e 142 struct system_gclk_gen_config gclk_conf;
mbed_official 18:da299f395b9e 143 struct system_clock_source_osc16m_config osc16m_conf;
mbed_official 18:da299f395b9e 144
mbed_official 18:da299f395b9e 145 /* Select OSCULP32K as new clock source for mainclock temporarily */
mbed_official 18:da299f395b9e 146 system_gclk_gen_get_config_defaults(&gclk_conf);
mbed_official 18:da299f395b9e 147 gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_ULP32K;
mbed_official 18:da299f395b9e 148 system_gclk_gen_set_config(GCLK_GENERATOR_0, &gclk_conf);
mbed_official 18:da299f395b9e 149
mbed_official 18:da299f395b9e 150 /* GCLK0 is enabled after POR */
mbed_official 18:da299f395b9e 151
mbed_official 18:da299f395b9e 152 /* Disable OSC16M clock*/
mbed_official 18:da299f395b9e 153 system_clock_source_disable(SYSTEM_CLOCK_SOURCE_OSC16M);
mbed_official 18:da299f395b9e 154
mbed_official 18:da299f395b9e 155 /* Switch to new frequency selection and enable OSC16M */
mbed_official 18:da299f395b9e 156 system_clock_source_osc16m_get_config_defaults(&osc16m_conf);
mbed_official 18:da299f395b9e 157 osc16m_conf.fsel = CONF_CLOCK_OSC16M_FREQ_SEL;
mbed_official 18:da299f395b9e 158 osc16m_conf.on_demand = 0;
mbed_official 18:da299f395b9e 159 osc16m_conf.run_in_standby = CONF_CLOCK_OSC16M_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 160 system_clock_source_osc16m_set_config(&osc16m_conf);
mbed_official 18:da299f395b9e 161 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC16M);
mbed_official 18:da299f395b9e 162 while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_OSC16M));
mbed_official 18:da299f395b9e 163
mbed_official 18:da299f395b9e 164 /* Select OSC16M for mainclock again */
mbed_official 18:da299f395b9e 165 system_gclk_gen_get_config_defaults(&gclk_conf);
mbed_official 18:da299f395b9e 166 gclk_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC16M;
mbed_official 18:da299f395b9e 167 system_gclk_gen_set_config(GCLK_GENERATOR_0, &gclk_conf);
mbed_official 18:da299f395b9e 168 if (CONF_CLOCK_OSC16M_ON_DEMAND) {
mbed_official 18:da299f395b9e 169 OSCCTRL->OSC16MCTRL.reg |= OSCCTRL_OSC16MCTRL_ONDEMAND;
mbed_official 18:da299f395b9e 170 }
mbed_official 18:da299f395b9e 171 }
mbed_official 18:da299f395b9e 172
mbed_official 18:da299f395b9e 173 static inline void _system_clock_source_dfll_set_config_errata_9905(void)
mbed_official 18:da299f395b9e 174 {
mbed_official 18:da299f395b9e 175
mbed_official 18:da299f395b9e 176 /* Disable ONDEMAND mode while writing configurations */
mbed_official 18:da299f395b9e 177 OSCCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control & ~OSCCTRL_DFLLCTRL_ONDEMAND;
mbed_official 18:da299f395b9e 178 _system_dfll_wait_for_sync();
mbed_official 18:da299f395b9e 179
mbed_official 18:da299f395b9e 180 OSCCTRL->DFLLMUL.reg = _system_clock_inst.dfll.mul;
mbed_official 18:da299f395b9e 181 OSCCTRL->DFLLVAL.reg = _system_clock_inst.dfll.val;
mbed_official 18:da299f395b9e 182
mbed_official 18:da299f395b9e 183 /* Write full configuration to DFLL control register */
mbed_official 18:da299f395b9e 184 OSCCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control;
mbed_official 18:da299f395b9e 185 }
mbed_official 18:da299f395b9e 186
mbed_official 18:da299f395b9e 187 /**
mbed_official 18:da299f395b9e 188 * \brief Retrieve the frequency of a clock source.
mbed_official 18:da299f395b9e 189 *
mbed_official 18:da299f395b9e 190 * Determines the current operating frequency of a given clock source.
mbed_official 18:da299f395b9e 191 *
mbed_official 18:da299f395b9e 192 * \param[in] clock_source Clock source to get the frequency of
mbed_official 18:da299f395b9e 193 *
mbed_official 18:da299f395b9e 194 * \returns Frequency of the given clock source, in Hz.
mbed_official 18:da299f395b9e 195 */
mbed_official 18:da299f395b9e 196 uint32_t system_clock_source_get_hz(
mbed_official 18:da299f395b9e 197 const enum system_clock_source clock_source)
mbed_official 18:da299f395b9e 198 {
mbed_official 18:da299f395b9e 199 switch (clock_source) {
mbed_official 18:da299f395b9e 200 case SYSTEM_CLOCK_SOURCE_XOSC:
mbed_official 18:da299f395b9e 201 return _system_clock_inst.xosc.frequency;
mbed_official 18:da299f395b9e 202
mbed_official 18:da299f395b9e 203 case SYSTEM_CLOCK_SOURCE_OSC16M:
mbed_official 18:da299f395b9e 204 return (OSCCTRL->OSC16MCTRL.bit.FSEL+1)*4000000UL;
mbed_official 18:da299f395b9e 205
mbed_official 18:da299f395b9e 206 case SYSTEM_CLOCK_SOURCE_OSC32K:
mbed_official 18:da299f395b9e 207 return 32768UL;
mbed_official 18:da299f395b9e 208
mbed_official 18:da299f395b9e 209 case SYSTEM_CLOCK_SOURCE_ULP32K:
mbed_official 18:da299f395b9e 210 return 32768UL;
mbed_official 18:da299f395b9e 211
mbed_official 18:da299f395b9e 212 case SYSTEM_CLOCK_SOURCE_XOSC32K:
mbed_official 18:da299f395b9e 213 return _system_clock_inst.xosc32k.frequency;
mbed_official 18:da299f395b9e 214
mbed_official 18:da299f395b9e 215 case SYSTEM_CLOCK_SOURCE_DFLL:
mbed_official 18:da299f395b9e 216
mbed_official 18:da299f395b9e 217 /* Check if the DFLL has been configured */
mbed_official 18:da299f395b9e 218 if (!(_system_clock_inst.dfll.control & OSCCTRL_DFLLCTRL_ENABLE))
mbed_official 18:da299f395b9e 219 return 0;
mbed_official 18:da299f395b9e 220
mbed_official 18:da299f395b9e 221 /* Make sure that the DFLL module is ready */
mbed_official 18:da299f395b9e 222 _system_dfll_wait_for_sync();
mbed_official 18:da299f395b9e 223
mbed_official 18:da299f395b9e 224 /* Check if operating in closed loop mode */
mbed_official 18:da299f395b9e 225 if (_system_clock_inst.dfll.control & OSCCTRL_DFLLCTRL_MODE) {
mbed_official 18:da299f395b9e 226 return system_gclk_chan_get_hz(OSCCTRL_GCLK_ID_DFLL48) *
mbed_official 18:da299f395b9e 227 (_system_clock_inst.dfll.mul & 0xffff);
mbed_official 18:da299f395b9e 228 }
mbed_official 18:da299f395b9e 229
mbed_official 18:da299f395b9e 230 return 48000000UL;
mbed_official 18:da299f395b9e 231
mbed_official 18:da299f395b9e 232 case SYSTEM_CLOCK_SOURCE_DPLL:
mbed_official 18:da299f395b9e 233 if (!(OSCCTRL->DPLLCTRLA.reg & OSCCTRL_DPLLCTRLA_ENABLE)) {
mbed_official 18:da299f395b9e 234 return 0;
mbed_official 18:da299f395b9e 235 }
mbed_official 18:da299f395b9e 236
mbed_official 18:da299f395b9e 237 return _system_clock_inst.dpll.frequency;
mbed_official 18:da299f395b9e 238
mbed_official 18:da299f395b9e 239 default:
mbed_official 18:da299f395b9e 240 return 0;
mbed_official 18:da299f395b9e 241 }
mbed_official 18:da299f395b9e 242 }
mbed_official 18:da299f395b9e 243
mbed_official 18:da299f395b9e 244 /**
mbed_official 18:da299f395b9e 245 * \brief Configure the internal OSC16M oscillator clock source.
mbed_official 18:da299f395b9e 246 *
mbed_official 18:da299f395b9e 247 * Configures the 16MHz (nominal) internal RC oscillator with the given
mbed_official 18:da299f395b9e 248 * configuration settings.
mbed_official 18:da299f395b9e 249 *
mbed_official 18:da299f395b9e 250 * \note Frequency selection can be done only when OSC16M is disabled.
mbed_official 18:da299f395b9e 251 *
mbed_official 18:da299f395b9e 252 * \param[in] config OSC16M configuration structure containing the new config
mbed_official 18:da299f395b9e 253 */
mbed_official 18:da299f395b9e 254 void system_clock_source_osc16m_set_config(
mbed_official 18:da299f395b9e 255 struct system_clock_source_osc16m_config *const config)
mbed_official 18:da299f395b9e 256 {
mbed_official 18:da299f395b9e 257 OSCCTRL_OSC16MCTRL_Type temp = OSCCTRL->OSC16MCTRL;
mbed_official 18:da299f395b9e 258
mbed_official 18:da299f395b9e 259 /* Use temporary struct to reduce register access */
mbed_official 18:da299f395b9e 260 temp.bit.FSEL = config->fsel;
mbed_official 18:da299f395b9e 261 temp.bit.ONDEMAND = config->on_demand;
mbed_official 18:da299f395b9e 262 temp.bit.RUNSTDBY = config->run_in_standby;
mbed_official 18:da299f395b9e 263
mbed_official 18:da299f395b9e 264 OSCCTRL->OSC16MCTRL = temp;
mbed_official 18:da299f395b9e 265 }
mbed_official 18:da299f395b9e 266
mbed_official 18:da299f395b9e 267 /**
mbed_official 18:da299f395b9e 268 * \brief Configure the internal OSC32K oscillator clock source.
mbed_official 18:da299f395b9e 269 *
mbed_official 18:da299f395b9e 270 * Configures the 32KHz (nominal) internal RC oscillator with the given
mbed_official 18:da299f395b9e 271 * configuration settings.
mbed_official 18:da299f395b9e 272 *
mbed_official 18:da299f395b9e 273 * \param[in] config OSC32K configuration structure containing the new config
mbed_official 18:da299f395b9e 274 */
mbed_official 18:da299f395b9e 275 void system_clock_source_osc32k_set_config(
mbed_official 18:da299f395b9e 276 struct system_clock_source_osc32k_config *const config)
mbed_official 18:da299f395b9e 277 {
mbed_official 18:da299f395b9e 278 OSC32KCTRL_OSC32K_Type temp = OSC32KCTRL->OSC32K;
mbed_official 18:da299f395b9e 279
mbed_official 18:da299f395b9e 280
mbed_official 18:da299f395b9e 281 /* Update settings via a temporary struct to reduce register access */
mbed_official 18:da299f395b9e 282 temp.bit.EN1K = config->enable_1khz_output;
mbed_official 18:da299f395b9e 283 temp.bit.EN32K = config->enable_32khz_output;
mbed_official 18:da299f395b9e 284 temp.bit.STARTUP = config->startup_time;
mbed_official 18:da299f395b9e 285 temp.bit.ONDEMAND = config->on_demand;
mbed_official 18:da299f395b9e 286 temp.bit.RUNSTDBY = config->run_in_standby;
mbed_official 18:da299f395b9e 287 temp.bit.WRTLOCK = config->write_once;
mbed_official 18:da299f395b9e 288
mbed_official 18:da299f395b9e 289 OSC32KCTRL->OSC32K = temp;
mbed_official 18:da299f395b9e 290 }
mbed_official 18:da299f395b9e 291
mbed_official 18:da299f395b9e 292 /**
mbed_official 18:da299f395b9e 293 * \brief Configure the internal OSCULP32K oscillator clock source.
mbed_official 18:da299f395b9e 294 *
mbed_official 18:da299f395b9e 295 * Configures the Ultra Low Power 32KHz internal RC oscillator with the given
mbed_official 18:da299f395b9e 296 * configuration settings.
mbed_official 18:da299f395b9e 297 *
mbed_official 18:da299f395b9e 298 * \note The OSCULP32K is enabled by default after a Power On Reset (POR) and
mbed_official 18:da299f395b9e 299 * will always run except during POR.
mbed_official 18:da299f395b9e 300 *
mbed_official 18:da299f395b9e 301 * \param[in] config OSCULP32K configuration structure containing the new config
mbed_official 18:da299f395b9e 302 */
mbed_official 18:da299f395b9e 303 void system_clock_source_osculp32k_set_config(
mbed_official 18:da299f395b9e 304 struct system_clock_source_osculp32k_config *const config)
mbed_official 18:da299f395b9e 305 {
mbed_official 18:da299f395b9e 306 OSC32KCTRL_OSCULP32K_Type temp = OSC32KCTRL->OSCULP32K;
mbed_official 18:da299f395b9e 307 /* Update settings via a temporary struct to reduce register access */
mbed_official 18:da299f395b9e 308 temp.bit.WRTLOCK = config->write_once;
mbed_official 18:da299f395b9e 309 OSC32KCTRL->OSCULP32K = temp;
mbed_official 18:da299f395b9e 310 }
mbed_official 18:da299f395b9e 311
mbed_official 18:da299f395b9e 312 /**
mbed_official 18:da299f395b9e 313 * \brief Configure the external oscillator clock source.
mbed_official 18:da299f395b9e 314 *
mbed_official 18:da299f395b9e 315 * Configures the external oscillator clock source with the given configuration
mbed_official 18:da299f395b9e 316 * settings.
mbed_official 18:da299f395b9e 317 *
mbed_official 18:da299f395b9e 318 * \param[in] config External oscillator configuration structure containing
mbed_official 18:da299f395b9e 319 * the new config
mbed_official 18:da299f395b9e 320 */
mbed_official 18:da299f395b9e 321 void system_clock_source_xosc_set_config(
mbed_official 18:da299f395b9e 322 struct system_clock_source_xosc_config *const config)
mbed_official 18:da299f395b9e 323 {
mbed_official 18:da299f395b9e 324 OSCCTRL_XOSCCTRL_Type temp = OSCCTRL->XOSCCTRL;
mbed_official 18:da299f395b9e 325
mbed_official 18:da299f395b9e 326 temp.bit.STARTUP = config->startup_time;
mbed_official 18:da299f395b9e 327
mbed_official 18:da299f395b9e 328 if (config->external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) {
mbed_official 18:da299f395b9e 329 temp.bit.XTALEN = 1;
mbed_official 18:da299f395b9e 330 } else {
mbed_official 18:da299f395b9e 331 temp.bit.XTALEN = 0;
mbed_official 18:da299f395b9e 332 }
mbed_official 18:da299f395b9e 333
mbed_official 18:da299f395b9e 334 temp.bit.AMPGC = config->auto_gain_control;
mbed_official 18:da299f395b9e 335
mbed_official 18:da299f395b9e 336 /* Set gain if automatic gain control is not selected */
mbed_official 18:da299f395b9e 337 if (!config->auto_gain_control) {
mbed_official 18:da299f395b9e 338 if (config->frequency <= 2000000) {
mbed_official 18:da299f395b9e 339 temp.bit.GAIN = 0;
mbed_official 18:da299f395b9e 340 } else if (config->frequency <= 4000000) {
mbed_official 18:da299f395b9e 341 temp.bit.GAIN = 1;
mbed_official 18:da299f395b9e 342 } else if (config->frequency <= 8000000) {
mbed_official 18:da299f395b9e 343 temp.bit.GAIN = 2;
mbed_official 18:da299f395b9e 344 } else if (config->frequency <= 16000000) {
mbed_official 18:da299f395b9e 345 temp.bit.GAIN = 3;
mbed_official 18:da299f395b9e 346 } else if (config->frequency <= 30000000) {
mbed_official 18:da299f395b9e 347 temp.bit.GAIN = 4;
mbed_official 18:da299f395b9e 348 }
mbed_official 18:da299f395b9e 349
mbed_official 18:da299f395b9e 350 }
mbed_official 18:da299f395b9e 351
mbed_official 18:da299f395b9e 352 temp.bit.ONDEMAND = config->on_demand;
mbed_official 18:da299f395b9e 353 temp.bit.RUNSTDBY = config->run_in_standby;
mbed_official 18:da299f395b9e 354
mbed_official 18:da299f395b9e 355 /* Store XOSC frequency for internal use */
mbed_official 18:da299f395b9e 356 _system_clock_inst.xosc.frequency = config->frequency;
mbed_official 18:da299f395b9e 357
mbed_official 18:da299f395b9e 358 OSCCTRL->XOSCCTRL = temp;
mbed_official 18:da299f395b9e 359 }
mbed_official 18:da299f395b9e 360
mbed_official 18:da299f395b9e 361 /**
mbed_official 18:da299f395b9e 362 * \brief Configure the XOSC32K external 32KHz oscillator clock source.
mbed_official 18:da299f395b9e 363 *
mbed_official 18:da299f395b9e 364 * Configures the external 32KHz oscillator clock source with the given
mbed_official 18:da299f395b9e 365 * configuration settings.
mbed_official 18:da299f395b9e 366 *
mbed_official 18:da299f395b9e 367 * \param[in] config XOSC32K configuration structure containing the new config
mbed_official 18:da299f395b9e 368 */
mbed_official 18:da299f395b9e 369 void system_clock_source_xosc32k_set_config(
mbed_official 18:da299f395b9e 370 struct system_clock_source_xosc32k_config *const config)
mbed_official 18:da299f395b9e 371 {
mbed_official 18:da299f395b9e 372 OSC32KCTRL_XOSC32K_Type temp = OSC32KCTRL->XOSC32K;
mbed_official 18:da299f395b9e 373
mbed_official 18:da299f395b9e 374 temp.bit.STARTUP = config->startup_time;
mbed_official 18:da299f395b9e 375
mbed_official 18:da299f395b9e 376 if (config->external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) {
mbed_official 18:da299f395b9e 377 temp.bit.XTALEN = 1;
mbed_official 18:da299f395b9e 378 } else {
mbed_official 18:da299f395b9e 379 temp.bit.XTALEN = 0;
mbed_official 18:da299f395b9e 380 }
mbed_official 18:da299f395b9e 381
mbed_official 18:da299f395b9e 382 temp.bit.EN1K = config->enable_1khz_output;
mbed_official 18:da299f395b9e 383 temp.bit.EN32K = config->enable_32khz_output;
mbed_official 18:da299f395b9e 384
mbed_official 18:da299f395b9e 385 temp.bit.ONDEMAND = config->on_demand;
mbed_official 18:da299f395b9e 386 temp.bit.RUNSTDBY = config->run_in_standby;
mbed_official 18:da299f395b9e 387 temp.bit.WRTLOCK = config->write_once;
mbed_official 18:da299f395b9e 388
mbed_official 18:da299f395b9e 389 /* Cache the new frequency in case the user needs to check the current
mbed_official 18:da299f395b9e 390 * operating frequency later */
mbed_official 18:da299f395b9e 391 _system_clock_inst.xosc32k.frequency = config->frequency;
mbed_official 18:da299f395b9e 392
mbed_official 18:da299f395b9e 393 OSC32KCTRL->XOSC32K = temp;
mbed_official 18:da299f395b9e 394 }
mbed_official 18:da299f395b9e 395
mbed_official 18:da299f395b9e 396 /**
mbed_official 18:da299f395b9e 397 * \brief Configure the DFLL clock source.
mbed_official 18:da299f395b9e 398 *
mbed_official 18:da299f395b9e 399 * Configures the Digital Frequency Locked Loop clock source with the given
mbed_official 18:da299f395b9e 400 * configuration settings.
mbed_official 18:da299f395b9e 401 *
mbed_official 18:da299f395b9e 402 * \note The DFLL will be running when this function returns, as the DFLL module
mbed_official 18:da299f395b9e 403 * needs to be enabled in order to perform the module configuration.
mbed_official 18:da299f395b9e 404 *
mbed_official 18:da299f395b9e 405 * \param[in] config DFLL configuration structure containing the new config
mbed_official 18:da299f395b9e 406 */
mbed_official 18:da299f395b9e 407 void system_clock_source_dfll_set_config(
mbed_official 18:da299f395b9e 408 struct system_clock_source_dfll_config *const config)
mbed_official 18:da299f395b9e 409 {
mbed_official 18:da299f395b9e 410 _system_clock_inst.dfll.val =
mbed_official 18:da299f395b9e 411 OSCCTRL_DFLLVAL_COARSE(config->coarse_value) |
mbed_official 18:da299f395b9e 412 OSCCTRL_DFLLVAL_FINE(config->fine_value);
mbed_official 18:da299f395b9e 413
mbed_official 18:da299f395b9e 414 _system_clock_inst.dfll.control =
mbed_official 18:da299f395b9e 415 (uint32_t)config->wakeup_lock |
mbed_official 18:da299f395b9e 416 (uint32_t)config->stable_tracking |
mbed_official 18:da299f395b9e 417 (uint32_t)config->quick_lock |
mbed_official 18:da299f395b9e 418 (uint32_t)config->chill_cycle |
mbed_official 18:da299f395b9e 419 ((uint32_t)config->on_demand << OSCCTRL_DFLLCTRL_ONDEMAND_Pos) |
mbed_official 18:da299f395b9e 420 ((uint32_t)config->run_in_stanby << OSCCTRL_DFLLCTRL_RUNSTDBY_Pos);
mbed_official 18:da299f395b9e 421
mbed_official 18:da299f395b9e 422 if (config->loop_mode == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
mbed_official 18:da299f395b9e 423
mbed_official 18:da299f395b9e 424 _system_clock_inst.dfll.mul =
mbed_official 18:da299f395b9e 425 OSCCTRL_DFLLMUL_CSTEP(config->coarse_max_step) |
mbed_official 18:da299f395b9e 426 OSCCTRL_DFLLMUL_FSTEP(config->fine_max_step) |
mbed_official 18:da299f395b9e 427 OSCCTRL_DFLLMUL_MUL(config->multiply_factor);
mbed_official 18:da299f395b9e 428
mbed_official 18:da299f395b9e 429 /* Enable the closed loop mode */
mbed_official 18:da299f395b9e 430 _system_clock_inst.dfll.control |= config->loop_mode;
mbed_official 18:da299f395b9e 431 }
mbed_official 18:da299f395b9e 432 if (config->loop_mode == SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY) {
mbed_official 18:da299f395b9e 433
mbed_official 18:da299f395b9e 434 _system_clock_inst.dfll.mul =
mbed_official 18:da299f395b9e 435 OSCCTRL_DFLLMUL_MUL(config->multiply_factor);
mbed_official 18:da299f395b9e 436
mbed_official 18:da299f395b9e 437 /* Enable the USB recovery mode */
mbed_official 18:da299f395b9e 438 _system_clock_inst.dfll.control |= config->loop_mode |
mbed_official 18:da299f395b9e 439 OSCCTRL_DFLLCTRL_BPLCKC;
mbed_official 18:da299f395b9e 440 }
mbed_official 18:da299f395b9e 441 }
mbed_official 18:da299f395b9e 442
mbed_official 18:da299f395b9e 443 /**
mbed_official 18:da299f395b9e 444 * \brief Configure the DPLL clock source.
mbed_official 18:da299f395b9e 445 *
mbed_official 18:da299f395b9e 446 * Configures the Digital Phase-Locked Loop clock source with the given
mbed_official 18:da299f395b9e 447 * configuration settings.
mbed_official 18:da299f395b9e 448 *
mbed_official 18:da299f395b9e 449 * \note The DPLL will be running when this function returns, as the DPLL module
mbed_official 18:da299f395b9e 450 * needs to be enabled in order to perform the module configuration.
mbed_official 18:da299f395b9e 451 *
mbed_official 18:da299f395b9e 452 * \param[in] config DPLL configuration structure containing the new config
mbed_official 18:da299f395b9e 453 */
mbed_official 18:da299f395b9e 454 void system_clock_source_dpll_set_config(
mbed_official 18:da299f395b9e 455 struct system_clock_source_dpll_config *const config)
mbed_official 18:da299f395b9e 456 {
mbed_official 18:da299f395b9e 457
mbed_official 18:da299f395b9e 458 uint32_t tmpldr;
mbed_official 18:da299f395b9e 459 uint8_t tmpldrfrac;
mbed_official 18:da299f395b9e 460 uint32_t refclk;
mbed_official 18:da299f395b9e 461
mbed_official 18:da299f395b9e 462 refclk = config->reference_frequency;
mbed_official 18:da299f395b9e 463
mbed_official 18:da299f395b9e 464 /* Only reference clock REF1 can be divided */
mbed_official 18:da299f395b9e 465 if (config->reference_clock == SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC) {
mbed_official 18:da299f395b9e 466 refclk = refclk / (2 * (config->reference_divider + 1));
mbed_official 18:da299f395b9e 467 }
mbed_official 18:da299f395b9e 468
mbed_official 18:da299f395b9e 469 /* Calculate LDRFRAC and LDR */
mbed_official 18:da299f395b9e 470 tmpldr = (config->output_frequency << 4) / refclk;
mbed_official 18:da299f395b9e 471 tmpldrfrac = tmpldr & 0x0f;
mbed_official 18:da299f395b9e 472 tmpldr = (tmpldr >> 4) - 1;
mbed_official 18:da299f395b9e 473
mbed_official 18:da299f395b9e 474 OSCCTRL->DPLLCTRLA.reg =
mbed_official 18:da299f395b9e 475 ((uint32_t)config->on_demand << OSCCTRL_DPLLCTRLA_ONDEMAND_Pos) |
mbed_official 18:da299f395b9e 476 ((uint32_t)config->run_in_standby << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos);
mbed_official 18:da299f395b9e 477
mbed_official 18:da299f395b9e 478 OSCCTRL->DPLLRATIO.reg =
mbed_official 18:da299f395b9e 479 OSCCTRL_DPLLRATIO_LDRFRAC(tmpldrfrac) |
mbed_official 18:da299f395b9e 480 OSCCTRL_DPLLRATIO_LDR(tmpldr);
mbed_official 18:da299f395b9e 481
mbed_official 18:da299f395b9e 482 while(OSCCTRL->DPLLSYNCBUSY.reg & OSCCTRL_DPLLSYNCBUSY_DPLLRATIO) {
mbed_official 18:da299f395b9e 483 }
mbed_official 18:da299f395b9e 484
mbed_official 18:da299f395b9e 485 OSCCTRL->DPLLCTRLB.reg =
mbed_official 18:da299f395b9e 486 OSCCTRL_DPLLCTRLB_DIV(config->reference_divider) |
mbed_official 18:da299f395b9e 487 ((uint32_t)config->lock_bypass << OSCCTRL_DPLLCTRLB_LBYPASS_Pos) |
mbed_official 18:da299f395b9e 488 OSCCTRL_DPLLCTRLB_LTIME(config->lock_time) |
mbed_official 18:da299f395b9e 489 OSCCTRL_DPLLCTRLB_REFCLK(config->reference_clock) |
mbed_official 18:da299f395b9e 490 ((uint32_t)config->wake_up_fast << OSCCTRL_DPLLCTRLB_WUF_Pos) |
mbed_official 18:da299f395b9e 491 ((uint32_t)config->low_power_enable << OSCCTRL_DPLLCTRLB_LPEN_Pos) |
mbed_official 18:da299f395b9e 492 OSCCTRL_DPLLCTRLB_FILTER(config->filter);
mbed_official 18:da299f395b9e 493
mbed_official 18:da299f395b9e 494 OSCCTRL->DPLLPRESC.reg = OSCCTRL_DPLLPRESC_PRESC(config->prescaler);
mbed_official 18:da299f395b9e 495 while(OSCCTRL->DPLLSYNCBUSY.reg & OSCCTRL_DPLLSYNCBUSY_DPLLPRESC) {
mbed_official 18:da299f395b9e 496 }
mbed_official 18:da299f395b9e 497 /*
mbed_official 18:da299f395b9e 498 * Fck = Fckrx * (LDR + 1 + LDRFRAC / 16)
mbed_official 18:da299f395b9e 499 */
mbed_official 18:da299f395b9e 500 _system_clock_inst.dpll.frequency =
mbed_official 18:da299f395b9e 501 (refclk * (((tmpldr + 1) << 4) + tmpldrfrac)) >> 4;
mbed_official 18:da299f395b9e 502 }
mbed_official 18:da299f395b9e 503
mbed_official 18:da299f395b9e 504 /**
mbed_official 18:da299f395b9e 505 * \brief Writes the calibration values for a given oscillator clock source.
mbed_official 18:da299f395b9e 506 *
mbed_official 18:da299f395b9e 507 * Writes an oscillator calibration value to the given oscillator control
mbed_official 18:da299f395b9e 508 * registers. The acceptable ranges are:
mbed_official 18:da299f395b9e 509 *
mbed_official 18:da299f395b9e 510 * For OSC32K:
mbed_official 18:da299f395b9e 511 * - 7 bits (max value 128)
mbed_official 18:da299f395b9e 512 * For OSC16MHZ:
mbed_official 18:da299f395b9e 513 * - 8 bits (Max value 255)
mbed_official 18:da299f395b9e 514 * For OSCULP:
mbed_official 18:da299f395b9e 515 * - 5 bits (Max value 32)
mbed_official 18:da299f395b9e 516 *
mbed_official 18:da299f395b9e 517 * \note The frequency range parameter applies only when configuring the 8MHz
mbed_official 18:da299f395b9e 518 * oscillator and will be ignored for the other oscillators.
mbed_official 18:da299f395b9e 519 *
mbed_official 18:da299f395b9e 520 * \param[in] clock_source Clock source to calibrate
mbed_official 18:da299f395b9e 521 * \param[in] calibration_value Calibration value to write
mbed_official 18:da299f395b9e 522 * \param[in] freq_range Frequency range (8MHz oscillator only)
mbed_official 18:da299f395b9e 523 *
mbed_official 18:da299f395b9e 524 * \retval STATUS_OK The calibration value was written
mbed_official 18:da299f395b9e 525 * successfully.
mbed_official 18:da299f395b9e 526 * \retval STATUS_ERR_INVALID_ARG The setting is not valid for selected clock
mbed_official 18:da299f395b9e 527 * source.
mbed_official 18:da299f395b9e 528 */
mbed_official 18:da299f395b9e 529 enum status_code system_clock_source_write_calibration(
mbed_official 18:da299f395b9e 530 const enum system_clock_source clock_source,
mbed_official 18:da299f395b9e 531 const uint16_t calibration_value,
mbed_official 18:da299f395b9e 532 const uint8_t freq_select)
mbed_official 18:da299f395b9e 533 {
mbed_official 18:da299f395b9e 534 switch (clock_source) {
mbed_official 18:da299f395b9e 535 case SYSTEM_CLOCK_SOURCE_OSC16M:
mbed_official 18:da299f395b9e 536 //to enable DSU test mode and add calibration value
mbed_official 18:da299f395b9e 537 return STATUS_OK;
mbed_official 18:da299f395b9e 538
mbed_official 18:da299f395b9e 539 case SYSTEM_CLOCK_SOURCE_OSC32K:
mbed_official 18:da299f395b9e 540
mbed_official 18:da299f395b9e 541 if (calibration_value > 128) {
mbed_official 18:da299f395b9e 542 return STATUS_ERR_INVALID_ARG;
mbed_official 18:da299f395b9e 543 }
mbed_official 18:da299f395b9e 544
mbed_official 18:da299f395b9e 545 _system_osc32k_wait_for_sync();
mbed_official 18:da299f395b9e 546 OSC32KCTRL->OSC32K.bit.CALIB = calibration_value;
mbed_official 18:da299f395b9e 547 break;
mbed_official 18:da299f395b9e 548
mbed_official 18:da299f395b9e 549 case SYSTEM_CLOCK_SOURCE_ULP32K:
mbed_official 18:da299f395b9e 550
mbed_official 18:da299f395b9e 551 if (calibration_value > 32) {
mbed_official 18:da299f395b9e 552 return STATUS_ERR_INVALID_ARG;
mbed_official 18:da299f395b9e 553 }
mbed_official 18:da299f395b9e 554
mbed_official 18:da299f395b9e 555 OSC32KCTRL->OSCULP32K.bit.CALIB = calibration_value;
mbed_official 18:da299f395b9e 556 break;
mbed_official 18:da299f395b9e 557
mbed_official 18:da299f395b9e 558 default:
mbed_official 18:da299f395b9e 559 Assert(false);
mbed_official 18:da299f395b9e 560 return STATUS_ERR_INVALID_ARG;
mbed_official 18:da299f395b9e 561 break;
mbed_official 18:da299f395b9e 562 }
mbed_official 18:da299f395b9e 563
mbed_official 18:da299f395b9e 564 return STATUS_OK;
mbed_official 18:da299f395b9e 565 }
mbed_official 18:da299f395b9e 566
mbed_official 18:da299f395b9e 567 /**
mbed_official 18:da299f395b9e 568 * \brief Enables a clock source.
mbed_official 18:da299f395b9e 569 *
mbed_official 18:da299f395b9e 570 * Enables a clock source which has been previously configured.
mbed_official 18:da299f395b9e 571 *
mbed_official 18:da299f395b9e 572 * \param[in] clock_source Clock source to enable
mbed_official 18:da299f395b9e 573 *
mbed_official 18:da299f395b9e 574 * \retval STATUS_OK Clock source was enabled successfully and
mbed_official 18:da299f395b9e 575 * is ready
mbed_official 18:da299f395b9e 576 * \retval STATUS_ERR_INVALID_ARG The clock source is not available on this
mbed_official 18:da299f395b9e 577 * device
mbed_official 18:da299f395b9e 578 */
mbed_official 18:da299f395b9e 579 enum status_code system_clock_source_enable(
mbed_official 18:da299f395b9e 580 const enum system_clock_source clock_source)
mbed_official 18:da299f395b9e 581 {
mbed_official 18:da299f395b9e 582 switch (clock_source) {
mbed_official 18:da299f395b9e 583 case SYSTEM_CLOCK_SOURCE_OSC16M:
mbed_official 18:da299f395b9e 584 OSCCTRL->OSC16MCTRL.reg |= OSCCTRL_OSC16MCTRL_ENABLE;
mbed_official 18:da299f395b9e 585 return STATUS_OK;
mbed_official 18:da299f395b9e 586
mbed_official 18:da299f395b9e 587 case SYSTEM_CLOCK_SOURCE_OSC32K:
mbed_official 18:da299f395b9e 588 OSC32KCTRL->OSC32K.reg |= OSC32KCTRL_OSC32K_ENABLE;
mbed_official 18:da299f395b9e 589 break;
mbed_official 18:da299f395b9e 590
mbed_official 18:da299f395b9e 591 case SYSTEM_CLOCK_SOURCE_XOSC:
mbed_official 18:da299f395b9e 592 OSCCTRL->XOSCCTRL.reg |= OSCCTRL_XOSCCTRL_ENABLE;
mbed_official 18:da299f395b9e 593 break;
mbed_official 18:da299f395b9e 594
mbed_official 18:da299f395b9e 595 case SYSTEM_CLOCK_SOURCE_XOSC32K:
mbed_official 18:da299f395b9e 596 OSC32KCTRL->XOSC32K.reg |= OSC32KCTRL_XOSC32K_ENABLE;
mbed_official 18:da299f395b9e 597 break;
mbed_official 18:da299f395b9e 598
mbed_official 18:da299f395b9e 599 case SYSTEM_CLOCK_SOURCE_DFLL:
mbed_official 18:da299f395b9e 600 _system_clock_inst.dfll.control |= OSCCTRL_DFLLCTRL_ENABLE;
mbed_official 18:da299f395b9e 601 _system_clock_source_dfll_set_config_errata_9905();
mbed_official 18:da299f395b9e 602 break;
mbed_official 18:da299f395b9e 603
mbed_official 18:da299f395b9e 604 case SYSTEM_CLOCK_SOURCE_DPLL:
mbed_official 18:da299f395b9e 605 OSCCTRL->DPLLCTRLA.reg |= OSCCTRL_DPLLCTRLA_ENABLE;
mbed_official 18:da299f395b9e 606 while(OSCCTRL->DPLLSYNCBUSY.reg & OSCCTRL_DPLLSYNCBUSY_ENABLE) {
mbed_official 18:da299f395b9e 607 }
mbed_official 18:da299f395b9e 608 break;
mbed_official 18:da299f395b9e 609
mbed_official 18:da299f395b9e 610 case SYSTEM_CLOCK_SOURCE_ULP32K:
mbed_official 18:da299f395b9e 611 /* Always enabled */
mbed_official 18:da299f395b9e 612 return STATUS_OK;
mbed_official 18:da299f395b9e 613
mbed_official 18:da299f395b9e 614 default:
mbed_official 18:da299f395b9e 615 Assert(false);
mbed_official 18:da299f395b9e 616 return STATUS_ERR_INVALID_ARG;
mbed_official 18:da299f395b9e 617 }
mbed_official 18:da299f395b9e 618
mbed_official 18:da299f395b9e 619 return STATUS_OK;
mbed_official 18:da299f395b9e 620 }
mbed_official 18:da299f395b9e 621
mbed_official 18:da299f395b9e 622 /**
mbed_official 18:da299f395b9e 623 * \brief Disables a clock source.
mbed_official 18:da299f395b9e 624 *
mbed_official 18:da299f395b9e 625 * Disables a clock source that was previously enabled.
mbed_official 18:da299f395b9e 626 *
mbed_official 18:da299f395b9e 627 * \param[in] clock_source Clock source to disable
mbed_official 18:da299f395b9e 628 *
mbed_official 18:da299f395b9e 629 * \retval STATUS_OK Clock source was disabled successfully
mbed_official 18:da299f395b9e 630 * \retval STATUS_ERR_INVALID_ARG An invalid or unavailable clock source was
mbed_official 18:da299f395b9e 631 * given
mbed_official 18:da299f395b9e 632 */
mbed_official 18:da299f395b9e 633 enum status_code system_clock_source_disable(
mbed_official 18:da299f395b9e 634 const enum system_clock_source clock_source)
mbed_official 18:da299f395b9e 635 {
mbed_official 18:da299f395b9e 636 switch (clock_source) {
mbed_official 18:da299f395b9e 637 case SYSTEM_CLOCK_SOURCE_OSC16M:
mbed_official 18:da299f395b9e 638 OSCCTRL->OSC16MCTRL.reg &= ~OSCCTRL_OSC16MCTRL_ENABLE;
mbed_official 18:da299f395b9e 639 break;
mbed_official 18:da299f395b9e 640
mbed_official 18:da299f395b9e 641 case SYSTEM_CLOCK_SOURCE_OSC32K:
mbed_official 18:da299f395b9e 642 OSC32KCTRL->OSC32K.reg &= ~OSC32KCTRL_OSC32K_ENABLE;
mbed_official 18:da299f395b9e 643 break;
mbed_official 18:da299f395b9e 644
mbed_official 18:da299f395b9e 645 case SYSTEM_CLOCK_SOURCE_XOSC:
mbed_official 18:da299f395b9e 646 OSCCTRL->XOSCCTRL.reg &= ~OSCCTRL_XOSCCTRL_ENABLE;
mbed_official 18:da299f395b9e 647 break;
mbed_official 18:da299f395b9e 648
mbed_official 18:da299f395b9e 649 case SYSTEM_CLOCK_SOURCE_XOSC32K:
mbed_official 18:da299f395b9e 650 OSC32KCTRL->XOSC32K.reg &= ~OSC32KCTRL_XOSC32K_ENABLE;
mbed_official 18:da299f395b9e 651 break;
mbed_official 18:da299f395b9e 652
mbed_official 18:da299f395b9e 653 case SYSTEM_CLOCK_SOURCE_DFLL:
mbed_official 18:da299f395b9e 654 _system_clock_inst.dfll.control &= ~OSCCTRL_DFLLCTRL_ENABLE;
mbed_official 18:da299f395b9e 655 OSCCTRL->DFLLCTRL.reg = _system_clock_inst.dfll.control;
mbed_official 18:da299f395b9e 656 break;
mbed_official 18:da299f395b9e 657 case SYSTEM_CLOCK_SOURCE_DPLL:
mbed_official 18:da299f395b9e 658 OSCCTRL->DPLLCTRLA.reg &= ~OSCCTRL_DPLLCTRLA_ENABLE;
mbed_official 18:da299f395b9e 659 break;
mbed_official 18:da299f395b9e 660 case SYSTEM_CLOCK_SOURCE_ULP32K:
mbed_official 18:da299f395b9e 661 /* Not possible to disable */
mbed_official 18:da299f395b9e 662
mbed_official 18:da299f395b9e 663 default:
mbed_official 18:da299f395b9e 664 Assert(false);
mbed_official 18:da299f395b9e 665 return STATUS_ERR_INVALID_ARG;
mbed_official 18:da299f395b9e 666
mbed_official 18:da299f395b9e 667 }
mbed_official 18:da299f395b9e 668
mbed_official 18:da299f395b9e 669 return STATUS_OK;
mbed_official 18:da299f395b9e 670 }
mbed_official 18:da299f395b9e 671
mbed_official 18:da299f395b9e 672 /**
mbed_official 18:da299f395b9e 673 * \brief Checks if a clock source is ready.
mbed_official 18:da299f395b9e 674 *
mbed_official 18:da299f395b9e 675 * Checks if a given clock source is ready to be used.
mbed_official 18:da299f395b9e 676 *
mbed_official 18:da299f395b9e 677 * \param[in] clock_source Clock source to check if ready
mbed_official 18:da299f395b9e 678 *
mbed_official 18:da299f395b9e 679 * \returns Ready state of the given clock source.
mbed_official 18:da299f395b9e 680 *
mbed_official 18:da299f395b9e 681 * \retval true Clock source is enabled and ready
mbed_official 18:da299f395b9e 682 * \retval false Clock source is disabled or not yet ready
mbed_official 18:da299f395b9e 683 */
mbed_official 18:da299f395b9e 684 bool system_clock_source_is_ready(
mbed_official 18:da299f395b9e 685 const enum system_clock_source clock_source)
mbed_official 18:da299f395b9e 686 {
mbed_official 18:da299f395b9e 687 uint32_t mask = 0;
mbed_official 18:da299f395b9e 688
mbed_official 18:da299f395b9e 689 switch (clock_source) {
mbed_official 18:da299f395b9e 690 case SYSTEM_CLOCK_SOURCE_OSC16M:
mbed_official 18:da299f395b9e 691 mask = OSCCTRL_STATUS_OSC16MRDY;
mbed_official 18:da299f395b9e 692 return ((OSCCTRL->STATUS.reg & mask) == mask);
mbed_official 18:da299f395b9e 693
mbed_official 18:da299f395b9e 694 case SYSTEM_CLOCK_SOURCE_OSC32K:
mbed_official 18:da299f395b9e 695 mask = OSC32KCTRL_STATUS_OSC32KRDY;
mbed_official 18:da299f395b9e 696 return ((OSC32KCTRL->STATUS.reg & mask) == mask);
mbed_official 18:da299f395b9e 697
mbed_official 18:da299f395b9e 698 case SYSTEM_CLOCK_SOURCE_XOSC:
mbed_official 18:da299f395b9e 699 mask = OSCCTRL_STATUS_XOSCRDY;
mbed_official 18:da299f395b9e 700 return ((OSCCTRL->STATUS.reg & mask) == mask);
mbed_official 18:da299f395b9e 701
mbed_official 18:da299f395b9e 702 case SYSTEM_CLOCK_SOURCE_XOSC32K:
mbed_official 18:da299f395b9e 703 mask = OSC32KCTRL_STATUS_XOSC32KRDY;
mbed_official 18:da299f395b9e 704 return ((OSC32KCTRL->STATUS.reg & mask) == mask);
mbed_official 18:da299f395b9e 705
mbed_official 18:da299f395b9e 706 case SYSTEM_CLOCK_SOURCE_DFLL:
mbed_official 18:da299f395b9e 707 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
mbed_official 18:da299f395b9e 708 mask = (OSCCTRL_STATUS_DFLLRDY |
mbed_official 18:da299f395b9e 709 OSCCTRL_STATUS_DFLLLCKF | OSCCTRL_STATUS_DFLLLCKC);
mbed_official 18:da299f395b9e 710 } else {
mbed_official 18:da299f395b9e 711 mask = OSCCTRL_STATUS_DFLLRDY;
mbed_official 18:da299f395b9e 712 }
mbed_official 18:da299f395b9e 713 return ((OSCCTRL->STATUS.reg & mask) == mask);
mbed_official 18:da299f395b9e 714
mbed_official 18:da299f395b9e 715 case SYSTEM_CLOCK_SOURCE_DPLL:
mbed_official 18:da299f395b9e 716 return ((OSCCTRL->DPLLSTATUS.reg &
mbed_official 18:da299f395b9e 717 (OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK)) ==
mbed_official 18:da299f395b9e 718 (OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK));
mbed_official 18:da299f395b9e 719 case SYSTEM_CLOCK_SOURCE_ULP32K:
mbed_official 18:da299f395b9e 720 /* Not possible to disable */
mbed_official 18:da299f395b9e 721 return true;
mbed_official 18:da299f395b9e 722
mbed_official 18:da299f395b9e 723 default:
mbed_official 18:da299f395b9e 724 return false;
mbed_official 18:da299f395b9e 725 }
mbed_official 18:da299f395b9e 726 }
mbed_official 18:da299f395b9e 727
mbed_official 18:da299f395b9e 728 /* Include some checks for conf_clocks.h validation */
mbed_official 18:da299f395b9e 729 #include "clock_config_check.h"
mbed_official 18:da299f395b9e 730
mbed_official 18:da299f395b9e 731 #if !defined(__DOXYGEN__)
mbed_official 18:da299f395b9e 732 /** \internal
mbed_official 18:da299f395b9e 733 *
mbed_official 18:da299f395b9e 734 * Configures a Generic Clock Generator with the configuration from \c conf_clocks.h.
mbed_official 18:da299f395b9e 735 */
mbed_official 18:da299f395b9e 736 # define _CONF_CLOCK_GCLK_CONFIG(n, unused) \
mbed_official 18:da299f395b9e 737 if (CONF_CLOCK_GCLK_##n##_ENABLE == true) { \
mbed_official 18:da299f395b9e 738 struct system_gclk_gen_config gclk_conf; \
mbed_official 18:da299f395b9e 739 system_gclk_gen_get_config_defaults(&gclk_conf); \
mbed_official 18:da299f395b9e 740 gclk_conf.source_clock = CONF_CLOCK_GCLK_##n##_CLOCK_SOURCE; \
mbed_official 18:da299f395b9e 741 gclk_conf.division_factor = CONF_CLOCK_GCLK_##n##_PRESCALER; \
mbed_official 18:da299f395b9e 742 gclk_conf.run_in_standby = CONF_CLOCK_GCLK_##n##_RUN_IN_STANDBY; \
mbed_official 18:da299f395b9e 743 gclk_conf.output_enable = CONF_CLOCK_GCLK_##n##_OUTPUT_ENABLE; \
mbed_official 18:da299f395b9e 744 system_gclk_gen_set_config(GCLK_GENERATOR_##n, &gclk_conf); \
mbed_official 18:da299f395b9e 745 system_gclk_gen_enable(GCLK_GENERATOR_##n); \
mbed_official 18:da299f395b9e 746 }
mbed_official 18:da299f395b9e 747
mbed_official 18:da299f395b9e 748 /** \internal
mbed_official 18:da299f395b9e 749 *
mbed_official 18:da299f395b9e 750 * Configures a Generic Clock Generator with the configuration from \c conf_clocks.h,
mbed_official 18:da299f395b9e 751 * provided that it is not the main Generic Clock Generator channel.
mbed_official 18:da299f395b9e 752 */
mbed_official 18:da299f395b9e 753 # define _CONF_CLOCK_GCLK_CONFIG_NONMAIN(n, unused) \
mbed_official 18:da299f395b9e 754 if (n > 0) { _CONF_CLOCK_GCLK_CONFIG(n, unused); }
mbed_official 18:da299f395b9e 755 #endif
mbed_official 18:da299f395b9e 756
mbed_official 18:da299f395b9e 757 /**
mbed_official 18:da299f395b9e 758 * \brief Initialize clock system based on the configuration in conf_clocks.h.
mbed_official 18:da299f395b9e 759 *
mbed_official 18:da299f395b9e 760 * This function will apply the settings in conf_clocks.h when run from the user
mbed_official 18:da299f395b9e 761 * application. All clock sources and GCLK generators are running when this function
mbed_official 18:da299f395b9e 762 * returns.
mbed_official 18:da299f395b9e 763 *
mbed_official 18:da299f395b9e 764 * \note OSC16M is always enabled and if user selects other clocks for GCLK generators,
mbed_official 18:da299f395b9e 765 * the OSC16M default enable can be disabled after system_clock_init. Make sure the
mbed_official 18:da299f395b9e 766 * clock switches successfully before disabling OSC8M.
mbed_official 18:da299f395b9e 767 */
mbed_official 18:da299f395b9e 768 void system_clock_init(void)
mbed_official 18:da299f395b9e 769 {
mbed_official 18:da299f395b9e 770 /* Various bits in the INTFLAG register can be set to one at startup.
mbed_official 18:da299f395b9e 771 This will ensure that these bits are cleared */
mbed_official 18:da299f395b9e 772 OSCCTRL->INTFLAG.reg = OSCCTRL_INTFLAG_DFLLRDY;
mbed_official 18:da299f395b9e 773 SUPC->INTFLAG.reg = SUPC_INTFLAG_BOD33RDY | SUPC_INTFLAG_BOD33DET;
mbed_official 18:da299f395b9e 774
mbed_official 18:da299f395b9e 775 system_flash_set_waitstates(CONF_CLOCK_FLASH_WAIT_STATES);
mbed_official 18:da299f395b9e 776
mbed_official 18:da299f395b9e 777 /* Switch to PL2 to be sure configuration of GCLK0 is safe */
mbed_official 18:da299f395b9e 778 system_switch_performance_level(SYSTEM_PERFORMANCE_LEVEL_2);
mbed_official 18:da299f395b9e 779
mbed_official 18:da299f395b9e 780 /* XOSC */
mbed_official 18:da299f395b9e 781 #if CONF_CLOCK_XOSC_ENABLE == true
mbed_official 18:da299f395b9e 782 struct system_clock_source_xosc_config xosc_conf;
mbed_official 18:da299f395b9e 783 system_clock_source_xosc_get_config_defaults(&xosc_conf);
mbed_official 18:da299f395b9e 784
mbed_official 18:da299f395b9e 785 xosc_conf.external_clock = CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL;
mbed_official 18:da299f395b9e 786 xosc_conf.startup_time = CONF_CLOCK_XOSC_STARTUP_TIME;
mbed_official 18:da299f395b9e 787 xosc_conf.auto_gain_control = CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL;
mbed_official 18:da299f395b9e 788 xosc_conf.frequency = CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY;
mbed_official 18:da299f395b9e 789 xosc_conf.on_demand = CONF_CLOCK_XOSC_ON_DEMAND;
mbed_official 18:da299f395b9e 790 xosc_conf.run_in_standby = CONF_CLOCK_XOSC_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 791
mbed_official 18:da299f395b9e 792 system_clock_source_xosc_set_config(&xosc_conf);
mbed_official 18:da299f395b9e 793 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC);
mbed_official 18:da299f395b9e 794 #endif
mbed_official 18:da299f395b9e 795
mbed_official 18:da299f395b9e 796 /* XOSC32K */
mbed_official 18:da299f395b9e 797 #if CONF_CLOCK_XOSC32K_ENABLE == true
mbed_official 18:da299f395b9e 798 struct system_clock_source_xosc32k_config xosc32k_conf;
mbed_official 18:da299f395b9e 799 system_clock_source_xosc32k_get_config_defaults(&xosc32k_conf);
mbed_official 18:da299f395b9e 800
mbed_official 18:da299f395b9e 801 xosc32k_conf.frequency = 32768UL;
mbed_official 18:da299f395b9e 802 xosc32k_conf.external_clock = CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL;
mbed_official 18:da299f395b9e 803 xosc32k_conf.startup_time = CONF_CLOCK_XOSC32K_STARTUP_TIME;
mbed_official 18:da299f395b9e 804 xosc32k_conf.enable_1khz_output = CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT;
mbed_official 18:da299f395b9e 805 xosc32k_conf.enable_32khz_output = CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT;
mbed_official 18:da299f395b9e 806 xosc32k_conf.on_demand = false;
mbed_official 18:da299f395b9e 807 xosc32k_conf.run_in_standby = CONF_CLOCK_XOSC32K_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 808
mbed_official 18:da299f395b9e 809 system_clock_source_xosc32k_set_config(&xosc32k_conf);
mbed_official 18:da299f395b9e 810 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
mbed_official 18:da299f395b9e 811 while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC32K));
mbed_official 18:da299f395b9e 812 if (CONF_CLOCK_XOSC32K_ON_DEMAND) {
mbed_official 18:da299f395b9e 813 OSC32KCTRL->XOSC32K.bit.ONDEMAND = 1;
mbed_official 18:da299f395b9e 814 }
mbed_official 18:da299f395b9e 815 #endif
mbed_official 18:da299f395b9e 816
mbed_official 18:da299f395b9e 817 /* OSCK32K */
mbed_official 18:da299f395b9e 818 #if CONF_CLOCK_OSC32K_ENABLE == true
mbed_official 18:da299f395b9e 819
mbed_official 18:da299f395b9e 820 struct system_clock_source_osc32k_config osc32k_conf;
mbed_official 18:da299f395b9e 821 system_clock_source_osc32k_get_config_defaults(&osc32k_conf);
mbed_official 18:da299f395b9e 822
mbed_official 18:da299f395b9e 823 osc32k_conf.startup_time = CONF_CLOCK_OSC32K_STARTUP_TIME;
mbed_official 18:da299f395b9e 824 osc32k_conf.enable_1khz_output = CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT;
mbed_official 18:da299f395b9e 825 osc32k_conf.enable_32khz_output = CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT;
mbed_official 18:da299f395b9e 826 osc32k_conf.on_demand = CONF_CLOCK_OSC32K_ON_DEMAND;
mbed_official 18:da299f395b9e 827 osc32k_conf.run_in_standby = CONF_CLOCK_OSC32K_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 828
mbed_official 18:da299f395b9e 829 system_clock_source_osc32k_set_config(&osc32k_conf);
mbed_official 18:da299f395b9e 830 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC32K);
mbed_official 18:da299f395b9e 831 #endif
mbed_official 18:da299f395b9e 832
mbed_official 18:da299f395b9e 833 /* OSC16M */
mbed_official 18:da299f395b9e 834 if (CONF_CLOCK_OSC16M_FREQ_SEL == SYSTEM_OSC16M_4M) {
mbed_official 18:da299f395b9e 835 OSCCTRL->OSC16MCTRL.bit.ONDEMAND = CONF_CLOCK_OSC16M_ON_DEMAND ;
mbed_official 18:da299f395b9e 836 OSCCTRL->OSC16MCTRL.bit.RUNSTDBY = CONF_CLOCK_OSC16M_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 837 } else {
mbed_official 18:da299f395b9e 838 _system_clock_source_osc16m_freq_sel();
mbed_official 18:da299f395b9e 839 }
mbed_official 18:da299f395b9e 840
mbed_official 18:da299f395b9e 841 /* DFLL Config (Open and Closed Loop) */
mbed_official 18:da299f395b9e 842 #if CONF_CLOCK_DFLL_ENABLE == true
mbed_official 18:da299f395b9e 843 struct system_clock_source_dfll_config dfll_conf;
mbed_official 18:da299f395b9e 844 system_clock_source_dfll_get_config_defaults(&dfll_conf);
mbed_official 18:da299f395b9e 845
mbed_official 18:da299f395b9e 846 dfll_conf.loop_mode = CONF_CLOCK_DFLL_LOOP_MODE;
mbed_official 18:da299f395b9e 847 dfll_conf.on_demand = false;
mbed_official 18:da299f395b9e 848 dfll_conf.run_in_stanby = CONF_CLOCK_DFLL_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 849
mbed_official 18:da299f395b9e 850 /* Using DFLL48M COARSE CAL value from NVM Software Calibration Area Mapping
mbed_official 18:da299f395b9e 851 in DFLL.COARSE helps to output a frequency close to 48 MHz.*/
mbed_official 18:da299f395b9e 852 #define NVM_DFLL_COARSE_POS 26 /* DFLL48M Coarse calibration value bit position.*/
mbed_official 18:da299f395b9e 853 #define NVM_DFLL_COARSE_SIZE 6 /* DFLL48M Coarse calibration value bit size.*/
mbed_official 18:da299f395b9e 854
mbed_official 18:da299f395b9e 855 uint32_t coarse =( *((uint32_t *)(NVMCTRL_OTP5)
mbed_official 18:da299f395b9e 856 + (NVM_DFLL_COARSE_POS / 32))
mbed_official 18:da299f395b9e 857 >> (NVM_DFLL_COARSE_POS % 32))
mbed_official 18:da299f395b9e 858 & ((1 << NVM_DFLL_COARSE_SIZE) - 1);
mbed_official 18:da299f395b9e 859 /* In some revision chip, the Calibration value is not correct */
mbed_official 18:da299f395b9e 860 if (coarse == 0x3f) {
mbed_official 18:da299f395b9e 861 coarse = 0x1f;
mbed_official 18:da299f395b9e 862 }
mbed_official 18:da299f395b9e 863
mbed_official 18:da299f395b9e 864 dfll_conf.coarse_value = coarse;
mbed_official 18:da299f395b9e 865
mbed_official 18:da299f395b9e 866 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN) {
mbed_official 18:da299f395b9e 867 dfll_conf.fine_value = CONF_CLOCK_DFLL_FINE_VALUE;
mbed_official 18:da299f395b9e 868 }
mbed_official 18:da299f395b9e 869
mbed_official 18:da299f395b9e 870 # if CONF_CLOCK_DFLL_QUICK_LOCK == true
mbed_official 18:da299f395b9e 871 dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE;
mbed_official 18:da299f395b9e 872 # else
mbed_official 18:da299f395b9e 873 dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_DISABLE;
mbed_official 18:da299f395b9e 874 # endif
mbed_official 18:da299f395b9e 875
mbed_official 18:da299f395b9e 876 # if CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK == true
mbed_official 18:da299f395b9e 877 dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK;
mbed_official 18:da299f395b9e 878 # else
mbed_official 18:da299f395b9e 879 dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_FIX_AFTER_LOCK;
mbed_official 18:da299f395b9e 880 # endif
mbed_official 18:da299f395b9e 881
mbed_official 18:da299f395b9e 882 # if CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP == true
mbed_official 18:da299f395b9e 883 dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP;
mbed_official 18:da299f395b9e 884 # else
mbed_official 18:da299f395b9e 885 dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_LOSE;
mbed_official 18:da299f395b9e 886 # endif
mbed_official 18:da299f395b9e 887
mbed_official 18:da299f395b9e 888 # if CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE == true
mbed_official 18:da299f395b9e 889 dfll_conf.chill_cycle = SYSTEM_CLOCK_DFLL_CHILL_CYCLE_ENABLE;
mbed_official 18:da299f395b9e 890 # else
mbed_official 18:da299f395b9e 891 dfll_conf.chill_cycle = SYSTEM_CLOCK_DFLL_CHILL_CYCLE_DISABLE;
mbed_official 18:da299f395b9e 892 # endif
mbed_official 18:da299f395b9e 893
mbed_official 18:da299f395b9e 894 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
mbed_official 18:da299f395b9e 895 dfll_conf.multiply_factor = CONF_CLOCK_DFLL_MULTIPLY_FACTOR;
mbed_official 18:da299f395b9e 896 }
mbed_official 18:da299f395b9e 897
mbed_official 18:da299f395b9e 898 dfll_conf.coarse_max_step = CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE;
mbed_official 18:da299f395b9e 899 dfll_conf.fine_max_step = CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE;
mbed_official 18:da299f395b9e 900
mbed_official 18:da299f395b9e 901 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY) {
mbed_official 18:da299f395b9e 902 dfll_conf.fine_value = 0x1ff;
mbed_official 18:da299f395b9e 903 dfll_conf.quick_lock = SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE;
mbed_official 18:da299f395b9e 904 dfll_conf.stable_tracking = SYSTEM_CLOCK_DFLL_STABLE_TRACKING_FIX_AFTER_LOCK;
mbed_official 18:da299f395b9e 905 dfll_conf.wakeup_lock = SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP;
mbed_official 18:da299f395b9e 906 dfll_conf.chill_cycle = SYSTEM_CLOCK_DFLL_CHILL_CYCLE_DISABLE;
mbed_official 18:da299f395b9e 907
mbed_official 18:da299f395b9e 908 dfll_conf.multiply_factor = 48000;
mbed_official 18:da299f395b9e 909 }
mbed_official 18:da299f395b9e 910
mbed_official 18:da299f395b9e 911 system_clock_source_dfll_set_config(&dfll_conf);
mbed_official 18:da299f395b9e 912 #endif
mbed_official 18:da299f395b9e 913
mbed_official 18:da299f395b9e 914 /* GCLK */
mbed_official 18:da299f395b9e 915 #if CONF_CLOCK_CONFIGURE_GCLK == true
mbed_official 18:da299f395b9e 916 system_gclk_init();
mbed_official 18:da299f395b9e 917
mbed_official 18:da299f395b9e 918 /* Configure all GCLK generators except for the main generator, which
mbed_official 18:da299f395b9e 919 * is configured later after all other clock systems are set up */
mbed_official 18:da299f395b9e 920 MREPEAT(GCLK_GEN_NUM, _CONF_CLOCK_GCLK_CONFIG_NONMAIN, ~);
mbed_official 18:da299f395b9e 921 # if CONF_CLOCK_DFLL_ENABLE == true
mbed_official 18:da299f395b9e 922 /* Enable DFLL reference clock if in closed loop mode */
mbed_official 18:da299f395b9e 923 if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) {
mbed_official 18:da299f395b9e 924 struct system_gclk_chan_config dfll_gclk_chan_conf;
mbed_official 18:da299f395b9e 925
mbed_official 18:da299f395b9e 926 system_gclk_chan_get_config_defaults(&dfll_gclk_chan_conf);
mbed_official 18:da299f395b9e 927 dfll_gclk_chan_conf.source_generator = CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR;
mbed_official 18:da299f395b9e 928 system_gclk_chan_set_config(OSCCTRL_GCLK_ID_DFLL48, &dfll_gclk_chan_conf);
mbed_official 18:da299f395b9e 929 system_gclk_chan_enable(OSCCTRL_GCLK_ID_DFLL48);
mbed_official 18:da299f395b9e 930 }
mbed_official 18:da299f395b9e 931 # endif
mbed_official 18:da299f395b9e 932
mbed_official 18:da299f395b9e 933 # if CONF_CLOCK_DPLL_ENABLE == true
mbed_official 18:da299f395b9e 934 /* Enable DPLL internal lock timer and reference clock */
mbed_official 18:da299f395b9e 935 struct system_gclk_chan_config dpll_gclk_chan_conf;
mbed_official 18:da299f395b9e 936 system_gclk_chan_get_config_defaults(&dpll_gclk_chan_conf);
mbed_official 18:da299f395b9e 937 if (CONF_CLOCK_DPLL_LOCK_TIME != SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT) {
mbed_official 18:da299f395b9e 938 dpll_gclk_chan_conf.source_generator = CONF_CLOCK_DPLL_LOCK_GCLK_GENERATOR;
mbed_official 18:da299f395b9e 939 system_gclk_chan_set_config(OSCCTRL_GCLK_ID_FDPLL32K, &dpll_gclk_chan_conf);
mbed_official 18:da299f395b9e 940 system_gclk_chan_enable(OSCCTRL_GCLK_ID_FDPLL32K);
mbed_official 18:da299f395b9e 941 }
mbed_official 18:da299f395b9e 942
mbed_official 18:da299f395b9e 943 if (CONF_CLOCK_DPLL_REFERENCE_CLOCK == SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_GCLK) {
mbed_official 18:da299f395b9e 944 dpll_gclk_chan_conf.source_generator = CONF_CLOCK_DPLL_REFERENCE_GCLK_GENERATOR;
mbed_official 18:da299f395b9e 945 system_gclk_chan_set_config(OSCCTRL_GCLK_ID_FDPLL, &dpll_gclk_chan_conf);
mbed_official 18:da299f395b9e 946 system_gclk_chan_enable(OSCCTRL_GCLK_ID_FDPLL);
mbed_official 18:da299f395b9e 947 }
mbed_official 18:da299f395b9e 948 # endif
mbed_official 18:da299f395b9e 949 #endif
mbed_official 18:da299f395b9e 950
mbed_official 18:da299f395b9e 951 /* DFLL Enable (Open and Closed Loop) */
mbed_official 18:da299f395b9e 952 #if CONF_CLOCK_DFLL_ENABLE == true
mbed_official 18:da299f395b9e 953 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL);
mbed_official 18:da299f395b9e 954 while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL));
mbed_official 18:da299f395b9e 955 if (CONF_CLOCK_DFLL_ON_DEMAND) {
mbed_official 18:da299f395b9e 956 OSCCTRL->DFLLCTRL.bit.ONDEMAND = 1;
mbed_official 18:da299f395b9e 957 }
mbed_official 18:da299f395b9e 958 #endif
mbed_official 18:da299f395b9e 959
mbed_official 18:da299f395b9e 960 /* DPLL */
mbed_official 18:da299f395b9e 961 # if (CONF_CLOCK_DPLL_ENABLE == true)
mbed_official 18:da299f395b9e 962
mbed_official 18:da299f395b9e 963 /* Enable DPLL reference clock */
mbed_official 18:da299f395b9e 964 if (CONF_CLOCK_DPLL_REFERENCE_CLOCK == SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC32K) {
mbed_official 18:da299f395b9e 965 /* XOSC32K should have been enabled for GCLK_XOSC32 */
mbed_official 18:da299f395b9e 966 Assert(CONF_CLOCK_XOSC32K_ENABLE);
mbed_official 18:da299f395b9e 967 } else if (CONF_CLOCK_DPLL_REFERENCE_CLOCK == SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_XOSC) {
mbed_official 18:da299f395b9e 968 /* XOSC should have been enabled for GCLK_XOSC */
mbed_official 18:da299f395b9e 969 Assert(CONF_CLOCK_XOSC_ENABLE);
mbed_official 18:da299f395b9e 970 } else if (CONF_CLOCK_DPLL_REFERENCE_CLOCK == SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_GCLK) {
mbed_official 18:da299f395b9e 971 /* GCLK should have been enabled */
mbed_official 18:da299f395b9e 972 Assert(CONF_CLOCK_CONFIGURE_GCLK);
mbed_official 18:da299f395b9e 973 } else {
mbed_official 18:da299f395b9e 974 Assert(false);
mbed_official 18:da299f395b9e 975 }
mbed_official 18:da299f395b9e 976
mbed_official 18:da299f395b9e 977 struct system_clock_source_dpll_config dpll_config;
mbed_official 18:da299f395b9e 978 system_clock_source_dpll_get_config_defaults(&dpll_config);
mbed_official 18:da299f395b9e 979
mbed_official 18:da299f395b9e 980 dpll_config.on_demand = false;
mbed_official 18:da299f395b9e 981 dpll_config.run_in_standby = CONF_CLOCK_DPLL_RUN_IN_STANDBY;
mbed_official 18:da299f395b9e 982 dpll_config.lock_bypass = CONF_CLOCK_DPLL_LOCK_BYPASS;
mbed_official 18:da299f395b9e 983 dpll_config.wake_up_fast = CONF_CLOCK_DPLL_WAKE_UP_FAST;
mbed_official 18:da299f395b9e 984 dpll_config.low_power_enable = CONF_CLOCK_DPLL_LOW_POWER_ENABLE;
mbed_official 18:da299f395b9e 985
mbed_official 18:da299f395b9e 986 dpll_config.filter = CONF_CLOCK_DPLL_FILTER;
mbed_official 18:da299f395b9e 987 dpll_config.lock_time = CONF_CLOCK_DPLL_LOCK_TIME;
mbed_official 18:da299f395b9e 988
mbed_official 18:da299f395b9e 989 dpll_config.reference_clock = CONF_CLOCK_DPLL_REFERENCE_CLOCK;
mbed_official 18:da299f395b9e 990 dpll_config.reference_frequency = CONF_CLOCK_DPLL_REFERENCE_FREQUENCY;
mbed_official 18:da299f395b9e 991 dpll_config.reference_divider = CONF_CLOCK_DPLL_REFERENCE_DIVIDER;
mbed_official 18:da299f395b9e 992 dpll_config.output_frequency = CONF_CLOCK_DPLL_OUTPUT_FREQUENCY;
mbed_official 18:da299f395b9e 993 dpll_config.prescaler = CONF_CLOCK_DPLL_PRESCALER;
mbed_official 18:da299f395b9e 994
mbed_official 18:da299f395b9e 995 system_clock_source_dpll_set_config(&dpll_config);
mbed_official 18:da299f395b9e 996 system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DPLL);
mbed_official 18:da299f395b9e 997 while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DPLL));
mbed_official 18:da299f395b9e 998 if (CONF_CLOCK_DPLL_ON_DEMAND) {
mbed_official 18:da299f395b9e 999 OSCCTRL->DPLLCTRLA.bit.ONDEMAND = 1;
mbed_official 18:da299f395b9e 1000 }
mbed_official 18:da299f395b9e 1001
mbed_official 18:da299f395b9e 1002 # endif
mbed_official 18:da299f395b9e 1003
mbed_official 18:da299f395b9e 1004 /* CPU and BUS clocks */
mbed_official 18:da299f395b9e 1005 system_cpu_clock_set_divider(CONF_CLOCK_CPU_DIVIDER);
mbed_official 18:da299f395b9e 1006 system_main_clock_set_failure_detect(CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT);
mbed_official 18:da299f395b9e 1007 system_low_power_clock_set_divider(CONF_CLOCK_LOW_POWER_DIVIDER);
mbed_official 18:da299f395b9e 1008 system_backup_clock_set_divider(CONF_CLOCK_BACKUP_DIVIDER);
mbed_official 18:da299f395b9e 1009
mbed_official 18:da299f395b9e 1010 /* GCLK 0 */
mbed_official 18:da299f395b9e 1011 #if CONF_CLOCK_CONFIGURE_GCLK == true
mbed_official 18:da299f395b9e 1012 /* Configure the main GCLK last as it might depend on other generators */
mbed_official 18:da299f395b9e 1013 _CONF_CLOCK_GCLK_CONFIG(0, ~);
mbed_official 18:da299f395b9e 1014 #endif
mbed_official 18:da299f395b9e 1015
mbed_official 18:da299f395b9e 1016 /* If CPU frequency is less than 12MHz, scale down performance level to PL0 */
mbed_official 18:da299f395b9e 1017 uint32_t cpu_freq = system_cpu_clock_get_hz();
mbed_official 18:da299f395b9e 1018 if (cpu_freq <= 12000000) {
mbed_official 18:da299f395b9e 1019 system_switch_performance_level(SYSTEM_PERFORMANCE_LEVEL_0);
mbed_official 18:da299f395b9e 1020 }
mbed_official 18:da299f395b9e 1021 }