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:
18:da299f395b9e
Added targets.json file for the supported targets in the release

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 Generic 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
mbed_official 18:da299f395b9e 47 #include <gclk.h>
mbed_official 18:da299f395b9e 48 #include <clock.h>
mbed_official 18:da299f395b9e 49 #include <system_interrupt.h>
mbed_official 18:da299f395b9e 50
mbed_official 18:da299f395b9e 51
mbed_official 18:da299f395b9e 52 /**
mbed_official 18:da299f395b9e 53 * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
mbed_official 18:da299f395b9e 54 *
mbed_official 18:da299f395b9e 55 * Checks to see if the underlying hardware peripheral module(s) are currently
mbed_official 18:da299f395b9e 56 * synchronizing across multiple clock domains to the hardware bus, This
mbed_official 18:da299f395b9e 57 * function can be used to delay further operations on a module until such time
mbed_official 18:da299f395b9e 58 * that it is ready, to prevent blocking delays for synchronization in the
mbed_official 18:da299f395b9e 59 * user application.
mbed_official 18:da299f395b9e 60 * \param[in] generator Generic Clock Generator index to sync
mbed_official 18:da299f395b9e 61 *
mbed_official 18:da299f395b9e 62 * \return Synchronization status of the underlying hardware module(s).
mbed_official 18:da299f395b9e 63 *
mbed_official 18:da299f395b9e 64 * \retval false if the module has completed synchronization
mbed_official 18:da299f395b9e 65 * \retval true if the module synchronization is ongoing
mbed_official 18:da299f395b9e 66 */
mbed_official 18:da299f395b9e 67 static inline bool system_gclk_is_syncing(const uint8_t generator)
mbed_official 18:da299f395b9e 68 {
mbed_official 18:da299f395b9e 69
mbed_official 18:da299f395b9e 70 if (GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL(1 << generator )) {
mbed_official 18:da299f395b9e 71 return true;
mbed_official 18:da299f395b9e 72 }
mbed_official 18:da299f395b9e 73
mbed_official 18:da299f395b9e 74 return false;
mbed_official 18:da299f395b9e 75 }
mbed_official 18:da299f395b9e 76
mbed_official 18:da299f395b9e 77
mbed_official 18:da299f395b9e 78 /**
mbed_official 18:da299f395b9e 79 * \brief Initializes the GCLK driver.
mbed_official 18:da299f395b9e 80 *
mbed_official 18:da299f395b9e 81 * Initializes the Generic Clock module, disabling and resetting all active
mbed_official 18:da299f395b9e 82 * Generic Clock Generators and Channels to their power-on default values.
mbed_official 18:da299f395b9e 83 */
mbed_official 18:da299f395b9e 84 void system_gclk_init(void)
mbed_official 18:da299f395b9e 85 {
mbed_official 18:da299f395b9e 86 /* Turn on the digital interface clock */
mbed_official 18:da299f395b9e 87 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, MCLK_APBAMASK_GCLK);
mbed_official 18:da299f395b9e 88
mbed_official 18:da299f395b9e 89 /* Software reset the module to ensure it is re-initialized correctly */
mbed_official 18:da299f395b9e 90 GCLK->CTRLA.reg = GCLK_CTRLA_SWRST;
mbed_official 18:da299f395b9e 91 while (GCLK->CTRLA.reg & GCLK_CTRLA_SWRST) {
mbed_official 18:da299f395b9e 92 /* Wait for reset to complete */
mbed_official 18:da299f395b9e 93 }
mbed_official 18:da299f395b9e 94 }
mbed_official 18:da299f395b9e 95
mbed_official 18:da299f395b9e 96 /**
mbed_official 18:da299f395b9e 97 * \brief Writes a Generic Clock Generator configuration to the hardware module.
mbed_official 18:da299f395b9e 98 *
mbed_official 18:da299f395b9e 99 * Writes out a given configuration of a Generic Clock Generator configuration
mbed_official 18:da299f395b9e 100 * to the hardware module.
mbed_official 18:da299f395b9e 101 *
mbed_official 18:da299f395b9e 102 * \note Changing the clock source on the fly (on a running
mbed_official 18:da299f395b9e 103 * generator) can take additional time if the clock source is configured
mbed_official 18:da299f395b9e 104 * to only run on-demand (ONDEMAND bit is set) and it is not currently
mbed_official 18:da299f395b9e 105 * running (no peripheral is requesting the clock source). In this case
mbed_official 18:da299f395b9e 106 * the GCLK will request the new clock while still keeping a request to
mbed_official 18:da299f395b9e 107 * the old clock source until the new clock source is ready.
mbed_official 18:da299f395b9e 108 *
mbed_official 18:da299f395b9e 109 * \note This function will not start a generator that is not already running;
mbed_official 18:da299f395b9e 110 * to start the generator, call \ref system_gclk_gen_enable()
mbed_official 18:da299f395b9e 111 * after configuring a generator.
mbed_official 18:da299f395b9e 112 *
mbed_official 18:da299f395b9e 113 * \param[in] generator Generic Clock Generator index to configure
mbed_official 18:da299f395b9e 114 * \param[in] config Configuration settings for the generator
mbed_official 18:da299f395b9e 115 */
mbed_official 18:da299f395b9e 116 void system_gclk_gen_set_config(
mbed_official 18:da299f395b9e 117 const uint8_t generator,
mbed_official 18:da299f395b9e 118 struct system_gclk_gen_config *const config)
mbed_official 18:da299f395b9e 119 {
mbed_official 18:da299f395b9e 120 /* Sanity check arguments */
mbed_official 18:da299f395b9e 121 Assert(config);
mbed_official 18:da299f395b9e 122
mbed_official 18:da299f395b9e 123 /* Cache new register configurations to minimize sync requirements. */
mbed_official 18:da299f395b9e 124 uint32_t new_genctrl_config ;
mbed_official 18:da299f395b9e 125
mbed_official 18:da299f395b9e 126
mbed_official 18:da299f395b9e 127 /* Select the requested source clock for the generator */
mbed_official 18:da299f395b9e 128 new_genctrl_config = config->source_clock << GCLK_GENCTRL_SRC_Pos;
mbed_official 18:da299f395b9e 129
mbed_official 18:da299f395b9e 130 /* Configure the clock to be either high or low when disabled */
mbed_official 18:da299f395b9e 131 if (config->high_when_disabled) {
mbed_official 18:da299f395b9e 132 new_genctrl_config |= GCLK_GENCTRL_OOV;
mbed_official 18:da299f395b9e 133 }
mbed_official 18:da299f395b9e 134
mbed_official 18:da299f395b9e 135 /* Configure if the clock output to I/O pin should be enabled. */
mbed_official 18:da299f395b9e 136 if (config->output_enable) {
mbed_official 18:da299f395b9e 137 new_genctrl_config |= GCLK_GENCTRL_OE;
mbed_official 18:da299f395b9e 138 }
mbed_official 18:da299f395b9e 139
mbed_official 18:da299f395b9e 140 /* Set division factor */
mbed_official 18:da299f395b9e 141 if (config->division_factor > 1) {
mbed_official 18:da299f395b9e 142 /* Check if division is a power of two */
mbed_official 18:da299f395b9e 143 if (((config->division_factor & (config->division_factor - 1)) == 0)) {
mbed_official 18:da299f395b9e 144 /* Determine the index of the highest bit set to get the
mbed_official 18:da299f395b9e 145 * division factor that must be loaded into the division
mbed_official 18:da299f395b9e 146 * register */
mbed_official 18:da299f395b9e 147
mbed_official 18:da299f395b9e 148 uint32_t div2_count = 0;
mbed_official 18:da299f395b9e 149
mbed_official 18:da299f395b9e 150 uint32_t mask;
mbed_official 18:da299f395b9e 151 for (mask = (1UL << 1); mask < config->division_factor;
mbed_official 18:da299f395b9e 152 mask <<= 1) {
mbed_official 18:da299f395b9e 153 div2_count++;
mbed_official 18:da299f395b9e 154 }
mbed_official 18:da299f395b9e 155
mbed_official 18:da299f395b9e 156 /* Set binary divider power of 2 division factor */
mbed_official 18:da299f395b9e 157 new_genctrl_config |= div2_count << GCLK_GENCTRL_DIV_Pos;
mbed_official 18:da299f395b9e 158 new_genctrl_config |= GCLK_GENCTRL_DIVSEL;
mbed_official 18:da299f395b9e 159 } else {
mbed_official 18:da299f395b9e 160 /* Set integer division factor */
mbed_official 18:da299f395b9e 161
mbed_official 18:da299f395b9e 162 new_genctrl_config |=
mbed_official 18:da299f395b9e 163 (config->division_factor) << GCLK_GENCTRL_DIV_Pos;
mbed_official 18:da299f395b9e 164
mbed_official 18:da299f395b9e 165 /* Enable non-binary division with increased duty cycle accuracy */
mbed_official 18:da299f395b9e 166 new_genctrl_config |= GCLK_GENCTRL_IDC;
mbed_official 18:da299f395b9e 167 }
mbed_official 18:da299f395b9e 168
mbed_official 18:da299f395b9e 169 }
mbed_official 18:da299f395b9e 170
mbed_official 18:da299f395b9e 171 /* Enable or disable the clock in standby mode */
mbed_official 18:da299f395b9e 172 if (config->run_in_standby) {
mbed_official 18:da299f395b9e 173 new_genctrl_config |= GCLK_GENCTRL_RUNSTDBY;
mbed_official 18:da299f395b9e 174 }
mbed_official 18:da299f395b9e 175
mbed_official 18:da299f395b9e 176 while (system_gclk_is_syncing(generator)) {
mbed_official 18:da299f395b9e 177 /* Wait for synchronization */
mbed_official 18:da299f395b9e 178 };
mbed_official 18:da299f395b9e 179
mbed_official 18:da299f395b9e 180 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 181
mbed_official 18:da299f395b9e 182 GCLK->GENCTRL[generator].reg = new_genctrl_config | (GCLK->GENCTRL[generator].reg & GCLK_GENCTRL_GENEN);
mbed_official 18:da299f395b9e 183
mbed_official 18:da299f395b9e 184 while (system_gclk_is_syncing(generator)) {
mbed_official 18:da299f395b9e 185 /* Wait for synchronization */
mbed_official 18:da299f395b9e 186 };
mbed_official 18:da299f395b9e 187
mbed_official 18:da299f395b9e 188 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 189 }
mbed_official 18:da299f395b9e 190
mbed_official 18:da299f395b9e 191 /**
mbed_official 18:da299f395b9e 192 * \brief Enables a Generic Clock Generator that was previously configured.
mbed_official 18:da299f395b9e 193 *
mbed_official 18:da299f395b9e 194 * Starts the clock generation of a Generic Clock Generator that was previously
mbed_official 18:da299f395b9e 195 * configured via a call to \ref system_gclk_gen_set_config().
mbed_official 18:da299f395b9e 196 *
mbed_official 18:da299f395b9e 197 * \param[in] generator Generic Clock Generator index to enable
mbed_official 18:da299f395b9e 198 */
mbed_official 18:da299f395b9e 199 void system_gclk_gen_enable(
mbed_official 18:da299f395b9e 200 const uint8_t generator)
mbed_official 18:da299f395b9e 201 {
mbed_official 18:da299f395b9e 202 while (system_gclk_is_syncing(generator)) {
mbed_official 18:da299f395b9e 203 /* Wait for synchronization */
mbed_official 18:da299f395b9e 204 };
mbed_official 18:da299f395b9e 205
mbed_official 18:da299f395b9e 206 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 207
mbed_official 18:da299f395b9e 208 /* Enable generator */
mbed_official 18:da299f395b9e 209 GCLK->GENCTRL[generator].reg |= GCLK_GENCTRL_GENEN;
mbed_official 18:da299f395b9e 210
mbed_official 18:da299f395b9e 211 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 212 }
mbed_official 18:da299f395b9e 213
mbed_official 18:da299f395b9e 214 /**
mbed_official 18:da299f395b9e 215 * \brief Disables a Generic Clock Generator that was previously enabled.
mbed_official 18:da299f395b9e 216 *
mbed_official 18:da299f395b9e 217 * Stops the clock generation of a Generic Clock Generator that was previously
mbed_official 18:da299f395b9e 218 * started via a call to \ref system_gclk_gen_enable().
mbed_official 18:da299f395b9e 219 *
mbed_official 18:da299f395b9e 220 * \param[in] generator Generic Clock Generator index to disable
mbed_official 18:da299f395b9e 221 */
mbed_official 18:da299f395b9e 222 void system_gclk_gen_disable(
mbed_official 18:da299f395b9e 223 const uint8_t generator)
mbed_official 18:da299f395b9e 224 {
mbed_official 18:da299f395b9e 225 while (system_gclk_is_syncing(generator)) {
mbed_official 18:da299f395b9e 226 /* Wait for synchronization */
mbed_official 18:da299f395b9e 227 };
mbed_official 18:da299f395b9e 228
mbed_official 18:da299f395b9e 229 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 230
mbed_official 18:da299f395b9e 231 /* Disable generator */
mbed_official 18:da299f395b9e 232 GCLK->GENCTRL[generator].reg &= ~GCLK_GENCTRL_GENEN;
mbed_official 18:da299f395b9e 233 while (GCLK->GENCTRL[generator].reg & GCLK_GENCTRL_GENEN) {
mbed_official 18:da299f395b9e 234 /* Wait for clock to become disabled */
mbed_official 18:da299f395b9e 235 }
mbed_official 18:da299f395b9e 236
mbed_official 18:da299f395b9e 237 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 238 }
mbed_official 18:da299f395b9e 239
mbed_official 18:da299f395b9e 240 /**
mbed_official 18:da299f395b9e 241 * \brief Determins if the specified Generic Clock Generator is enabled.
mbed_official 18:da299f395b9e 242 *
mbed_official 18:da299f395b9e 243 * \param[in] generator Generic Clock Generator index to check
mbed_official 18:da299f395b9e 244 *
mbed_official 18:da299f395b9e 245 * \return The enabled status.
mbed_official 18:da299f395b9e 246 * \retval true The Generic Clock Generator is enabled
mbed_official 18:da299f395b9e 247 * \retval false The Generic Clock Generator is disabled
mbed_official 18:da299f395b9e 248 */
mbed_official 18:da299f395b9e 249 bool system_gclk_gen_is_enabled(
mbed_official 18:da299f395b9e 250 const uint8_t generator)
mbed_official 18:da299f395b9e 251 {
mbed_official 18:da299f395b9e 252 bool enabled;
mbed_official 18:da299f395b9e 253
mbed_official 18:da299f395b9e 254 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 255
mbed_official 18:da299f395b9e 256 /* Obtain the enabled status */
mbed_official 18:da299f395b9e 257 enabled = (GCLK->GENCTRL[generator].reg & GCLK_GENCTRL_GENEN);
mbed_official 18:da299f395b9e 258
mbed_official 18:da299f395b9e 259 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 260
mbed_official 18:da299f395b9e 261 return enabled;
mbed_official 18:da299f395b9e 262 }
mbed_official 18:da299f395b9e 263
mbed_official 18:da299f395b9e 264 /**
mbed_official 18:da299f395b9e 265 * \brief Retrieves the clock frequency of a Generic Clock generator.
mbed_official 18:da299f395b9e 266 *
mbed_official 18:da299f395b9e 267 * Determines the clock frequency (in Hz) of a specified Generic Clock
mbed_official 18:da299f395b9e 268 * generator, used as a source to a Generic Clock Channel module.
mbed_official 18:da299f395b9e 269 *
mbed_official 18:da299f395b9e 270 * \param[in] generator Generic Clock Generator index
mbed_official 18:da299f395b9e 271 *
mbed_official 18:da299f395b9e 272 * \return The frequency of the generic clock generator, in Hz.
mbed_official 18:da299f395b9e 273 */
mbed_official 18:da299f395b9e 274 uint32_t system_gclk_gen_get_hz(
mbed_official 18:da299f395b9e 275 const uint8_t generator)
mbed_official 18:da299f395b9e 276 {
mbed_official 18:da299f395b9e 277 while (system_gclk_is_syncing(generator)) {
mbed_official 18:da299f395b9e 278 /* Wait for synchronization */
mbed_official 18:da299f395b9e 279 };
mbed_official 18:da299f395b9e 280
mbed_official 18:da299f395b9e 281 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 282
mbed_official 18:da299f395b9e 283 /* Get the frequency of the source connected to the GCLK generator */
mbed_official 18:da299f395b9e 284 uint32_t gen_input_hz = system_clock_source_get_hz(
mbed_official 18:da299f395b9e 285 (enum system_clock_source)GCLK->GENCTRL[generator].bit.SRC);
mbed_official 18:da299f395b9e 286
mbed_official 18:da299f395b9e 287 uint8_t divsel = GCLK->GENCTRL[generator].bit.DIVSEL;
mbed_official 18:da299f395b9e 288 uint32_t divider = GCLK->GENCTRL[generator].bit.DIV;
mbed_official 18:da299f395b9e 289
mbed_official 18:da299f395b9e 290 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 291
mbed_official 18:da299f395b9e 292 /* Check if the generator is using fractional or binary division */
mbed_official 18:da299f395b9e 293 if (!divsel && divider > 1) {
mbed_official 18:da299f395b9e 294 gen_input_hz /= divider;
mbed_official 18:da299f395b9e 295 } else if (divsel) {
mbed_official 18:da299f395b9e 296 gen_input_hz >>= (divider+1);
mbed_official 18:da299f395b9e 297 }
mbed_official 18:da299f395b9e 298
mbed_official 18:da299f395b9e 299 return gen_input_hz;
mbed_official 18:da299f395b9e 300 }
mbed_official 18:da299f395b9e 301
mbed_official 18:da299f395b9e 302 /**
mbed_official 18:da299f395b9e 303 * \brief Writes a Generic Clock configuration to the hardware module.
mbed_official 18:da299f395b9e 304 *
mbed_official 18:da299f395b9e 305 * Writes out a given configuration of a Generic Clock configuration to the
mbed_official 18:da299f395b9e 306 * hardware module. If the clock is currently running, it will be stopped.
mbed_official 18:da299f395b9e 307 *
mbed_official 18:da299f395b9e 308 * \note Once called the clock will not be running; to start the clock,
mbed_official 18:da299f395b9e 309 * call \ref system_gclk_chan_enable() after configuring a clock channel.
mbed_official 18:da299f395b9e 310 *
mbed_official 18:da299f395b9e 311 * \param[in] channel Generic Clock channel to configure
mbed_official 18:da299f395b9e 312 * \param[in] config Configuration settings for the clock
mbed_official 18:da299f395b9e 313 *
mbed_official 18:da299f395b9e 314 */
mbed_official 18:da299f395b9e 315 void system_gclk_chan_set_config(
mbed_official 18:da299f395b9e 316 const uint8_t channel,
mbed_official 18:da299f395b9e 317 struct system_gclk_chan_config *const config)
mbed_official 18:da299f395b9e 318 {
mbed_official 18:da299f395b9e 319 /* Sanity check arguments */
mbed_official 18:da299f395b9e 320 Assert(config);
mbed_official 18:da299f395b9e 321
mbed_official 18:da299f395b9e 322 /* Disable generic clock channel */
mbed_official 18:da299f395b9e 323 system_gclk_chan_disable(channel);
mbed_official 18:da299f395b9e 324
mbed_official 18:da299f395b9e 325 /* Configure the peripheral channel */
mbed_official 18:da299f395b9e 326 GCLK->PCHCTRL[channel].reg = GCLK_PCHCTRL_GEN(config->source_generator);
mbed_official 18:da299f395b9e 327
mbed_official 18:da299f395b9e 328
mbed_official 18:da299f395b9e 329 }
mbed_official 18:da299f395b9e 330
mbed_official 18:da299f395b9e 331 /**
mbed_official 18:da299f395b9e 332 * \brief Enables a Generic Clock that was previously configured.
mbed_official 18:da299f395b9e 333 *
mbed_official 18:da299f395b9e 334 * Starts the clock generation of a Generic Clock that was previously
mbed_official 18:da299f395b9e 335 * configured via a call to \ref system_gclk_chan_set_config().
mbed_official 18:da299f395b9e 336 *
mbed_official 18:da299f395b9e 337 * \param[in] channel Generic Clock channel to enable
mbed_official 18:da299f395b9e 338 */
mbed_official 18:da299f395b9e 339 void system_gclk_chan_enable(
mbed_official 18:da299f395b9e 340 const uint8_t channel)
mbed_official 18:da299f395b9e 341 {
mbed_official 18:da299f395b9e 342 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 343
mbed_official 18:da299f395b9e 344 /* Enable the peripheral channel */
mbed_official 18:da299f395b9e 345 GCLK->PCHCTRL[channel].reg |= GCLK_PCHCTRL_CHEN;
mbed_official 18:da299f395b9e 346
mbed_official 18:da299f395b9e 347 while (!(GCLK->PCHCTRL[channel].reg & GCLK_PCHCTRL_CHEN)) {
mbed_official 18:da299f395b9e 348 /* Wait for clock synchronization */
mbed_official 18:da299f395b9e 349 }
mbed_official 18:da299f395b9e 350
mbed_official 18:da299f395b9e 351 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 352 }
mbed_official 18:da299f395b9e 353
mbed_official 18:da299f395b9e 354 /**
mbed_official 18:da299f395b9e 355 * \brief Disables a Generic Clock that was previously enabled.
mbed_official 18:da299f395b9e 356 *
mbed_official 18:da299f395b9e 357 * Stops the clock generation of a Generic Clock that was previously started
mbed_official 18:da299f395b9e 358 * via a call to \ref system_gclk_chan_enable().
mbed_official 18:da299f395b9e 359 *
mbed_official 18:da299f395b9e 360 * \param[in] channel Generic Clock channel to disable
mbed_official 18:da299f395b9e 361 */
mbed_official 18:da299f395b9e 362 void system_gclk_chan_disable(
mbed_official 18:da299f395b9e 363 const uint8_t channel)
mbed_official 18:da299f395b9e 364 {
mbed_official 18:da299f395b9e 365 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 366
mbed_official 18:da299f395b9e 367 /* Sanity check WRTLOCK */
mbed_official 18:da299f395b9e 368 Assert(!GCLK->PCHCTRL[channel].bit.WRTLOCK);
mbed_official 18:da299f395b9e 369
mbed_official 18:da299f395b9e 370 /* Disable the peripheral channel */
mbed_official 18:da299f395b9e 371 GCLK->PCHCTRL[channel].reg &= ~GCLK_PCHCTRL_CHEN;
mbed_official 18:da299f395b9e 372
mbed_official 18:da299f395b9e 373 while (GCLK->PCHCTRL[channel].reg & GCLK_PCHCTRL_CHEN) {
mbed_official 18:da299f395b9e 374 /* Wait for clock synchronization */
mbed_official 18:da299f395b9e 375 }
mbed_official 18:da299f395b9e 376
mbed_official 18:da299f395b9e 377 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 378 }
mbed_official 18:da299f395b9e 379
mbed_official 18:da299f395b9e 380 /**
mbed_official 18:da299f395b9e 381 * \brief Determins if the specified Generic Clock channel is enabled.
mbed_official 18:da299f395b9e 382 *
mbed_official 18:da299f395b9e 383 * \param[in] channel Generic Clock Channel index
mbed_official 18:da299f395b9e 384 *
mbed_official 18:da299f395b9e 385 * \return The enabled status.
mbed_official 18:da299f395b9e 386 * \retval true The Generic Clock channel is enabled
mbed_official 18:da299f395b9e 387 * \retval false The Generic Clock channel is disabled
mbed_official 18:da299f395b9e 388 */
mbed_official 18:da299f395b9e 389 bool system_gclk_chan_is_enabled(
mbed_official 18:da299f395b9e 390 const uint8_t channel)
mbed_official 18:da299f395b9e 391 {
mbed_official 18:da299f395b9e 392 bool enabled;
mbed_official 18:da299f395b9e 393
mbed_official 18:da299f395b9e 394 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 395
mbed_official 18:da299f395b9e 396 /* Select the requested generic clock channel */
mbed_official 18:da299f395b9e 397 enabled = GCLK->PCHCTRL[channel].bit.CHEN;
mbed_official 18:da299f395b9e 398
mbed_official 18:da299f395b9e 399 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 400
mbed_official 18:da299f395b9e 401 return enabled;
mbed_official 18:da299f395b9e 402 }
mbed_official 18:da299f395b9e 403
mbed_official 18:da299f395b9e 404 /**
mbed_official 18:da299f395b9e 405 * \brief Locks a Generic Clock channel from further configuration writes.
mbed_official 18:da299f395b9e 406 *
mbed_official 18:da299f395b9e 407 * Locks a generic clock channel from further configuration writes. It is only
mbed_official 18:da299f395b9e 408 * possible to unlock the channel configuration through a power on reset.
mbed_official 18:da299f395b9e 409 *
mbed_official 18:da299f395b9e 410 * \param[in] channel Generic Clock channel to enable
mbed_official 18:da299f395b9e 411 */
mbed_official 18:da299f395b9e 412 void system_gclk_chan_lock(
mbed_official 18:da299f395b9e 413 const uint8_t channel)
mbed_official 18:da299f395b9e 414 {
mbed_official 18:da299f395b9e 415 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 416
mbed_official 18:da299f395b9e 417 GCLK->PCHCTRL[channel].reg |= GCLK_PCHCTRL_WRTLOCK;
mbed_official 18:da299f395b9e 418 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 419 }
mbed_official 18:da299f395b9e 420
mbed_official 18:da299f395b9e 421 /**
mbed_official 18:da299f395b9e 422 * \brief Determins if the specified Generic Clock channel is locked.
mbed_official 18:da299f395b9e 423 *
mbed_official 18:da299f395b9e 424 * \param[in] channel Generic Clock Channel index
mbed_official 18:da299f395b9e 425 *
mbed_official 18:da299f395b9e 426 * \return The lock status.
mbed_official 18:da299f395b9e 427 * \retval true The Generic Clock channel is locked
mbed_official 18:da299f395b9e 428 * \retval false The Generic Clock channel is not locked
mbed_official 18:da299f395b9e 429 */
mbed_official 18:da299f395b9e 430 bool system_gclk_chan_is_locked(
mbed_official 18:da299f395b9e 431 const uint8_t channel)
mbed_official 18:da299f395b9e 432 {
mbed_official 18:da299f395b9e 433 bool locked;
mbed_official 18:da299f395b9e 434
mbed_official 18:da299f395b9e 435 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 436 locked = GCLK->PCHCTRL[channel].bit.WRTLOCK;
mbed_official 18:da299f395b9e 437 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 438
mbed_official 18:da299f395b9e 439 return locked;
mbed_official 18:da299f395b9e 440 }
mbed_official 18:da299f395b9e 441
mbed_official 18:da299f395b9e 442 /**
mbed_official 18:da299f395b9e 443 * \brief Retrieves the clock frequency of a Generic Clock channel.
mbed_official 18:da299f395b9e 444 *
mbed_official 18:da299f395b9e 445 * Determines the clock frequency (in Hz) of a specified Generic Clock
mbed_official 18:da299f395b9e 446 * channel, used as a source to a device peripheral module.
mbed_official 18:da299f395b9e 447 *
mbed_official 18:da299f395b9e 448 * \param[in] channel Generic Clock Channel index
mbed_official 18:da299f395b9e 449 *
mbed_official 18:da299f395b9e 450 * \return The frequency of the generic clock channel, in Hz.
mbed_official 18:da299f395b9e 451 */
mbed_official 18:da299f395b9e 452 uint32_t system_gclk_chan_get_hz(
mbed_official 18:da299f395b9e 453 const uint8_t channel)
mbed_official 18:da299f395b9e 454 {
mbed_official 18:da299f395b9e 455 uint8_t gen_id;
mbed_official 18:da299f395b9e 456
mbed_official 18:da299f395b9e 457 system_interrupt_enter_critical_section();
mbed_official 18:da299f395b9e 458 /* Select the requested generic clock channel */
mbed_official 18:da299f395b9e 459 gen_id = GCLK->PCHCTRL[channel].bit.GEN;
mbed_official 18:da299f395b9e 460 system_interrupt_leave_critical_section();
mbed_official 18:da299f395b9e 461
mbed_official 18:da299f395b9e 462 /* Return the clock speed of the associated GCLK generator */
mbed_official 18:da299f395b9e 463 return system_gclk_gen_get_hz(gen_id);
mbed_official 18:da299f395b9e 464 }