mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

Committer:
screamer
Date:
Tue Aug 02 14:07:36 2016 +0000
Revision:
144:423e1876dc07
Parent:
64:41a834223ea3
Added targets.json file for the supported targets in the release

Who changed what in which revision?

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