mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Jul 17 09:15:10 2015 +0100
Revision:
592:a274ee790e56
Parent:
579:53297373a894
Synchronized with git revision e7144f83a8d75df80c4877936b6ffe552b0be9e6

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

More API implementation for SAMR21

Who changed what in which revision?

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