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.

Revision:
613:bc40b8d2aec4
Parent:
612:fba1c7dc54c0
Child:
614:9d86c2ae5de0
--- a/targets/hal/TARGET_Atmel/TARGET_SAM21/drivers/system/clock/clock_samd21_r21/gclk.c	Tue Aug 18 15:00:09 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,476 +0,0 @@
-#include <gclk.h>
-#include <clock.h>
-#include <system_interrupt.h>
-
-/**
- * \brief Determines if the hardware module(s) are currently synchronizing to the bus.
- *
- * Checks to see if the underlying hardware peripheral module(s) are currently
- * synchronizing across multiple clock domains to the hardware bus, This
- * function can be used to delay further operations on a module until such time
- * that it is ready, to prevent blocking delays for synchronization in the
- * user application.
- *
- * \return Synchronization status of the underlying hardware module(s).
- *
- * \retval false if the module has completed synchronization
- * \retval true if the module synchronization is ongoing
- */
-static inline bool system_gclk_is_syncing(void)
-{
-    if (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {
-        return true;
-    }
-
-    return false;
-}
-
-/**
- * \brief Initializes the GCLK driver.
- *
- * Initializes the Generic Clock module, disabling and resetting all active
- * Generic Clock Generators and Channels to their power-on default values.
- */
-void system_gclk_init(void)
-{
-    /* Turn on the digital interface clock */
-    system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_GCLK);
-
-    /* Software reset the module to ensure it is re-initialized correctly */
-    GCLK->CTRL.reg = GCLK_CTRL_SWRST;
-    while (GCLK->CTRL.reg & GCLK_CTRL_SWRST) {
-        /* Wait for reset to complete */
-    }
-}
-
-/**
- * \brief Writes a Generic Clock Generator configuration to the hardware module.
- *
- * Writes out a given configuration of a Generic Clock Generator configuration
- * to the hardware module.
- *
- * \note Changing the clock source on the fly (on a running
- *       generator) can take additional time if the clock source is configured
- *       to only run on-demand (ONDEMAND bit is set) and it is not currently
- *       running (no peripheral is requesting the clock source). In this case
- *       the GCLK will request the new clock while still keeping a request to
- *       the old clock source until the new clock source is ready.
- *
- * \note This function will not start a generator that is not already running;
- *       to start the generator, call \ref system_gclk_gen_enable()
- *       after configuring a generator.
- *
- * \param[in] generator  Generic Clock Generator index to configure
- * \param[in] config     Configuration settings for the generator
- */
-void system_gclk_gen_set_config(
-    const uint8_t generator,
-    struct system_gclk_gen_config *const config)
-{
-    /* Sanity check arguments */
-    Assert(config);
-
-    /* Cache new register configurations to minimize sync requirements. */
-    uint32_t new_genctrl_config = (generator << GCLK_GENCTRL_ID_Pos);
-    uint32_t new_gendiv_config  = (generator << GCLK_GENDIV_ID_Pos);
-
-    /* Select the requested source clock for the generator */
-    new_genctrl_config |= config->source_clock << GCLK_GENCTRL_SRC_Pos;
-
-    /* Configure the clock to be either high or low when disabled */
-    if (config->high_when_disabled) {
-        new_genctrl_config |= GCLK_GENCTRL_OOV;
-    }
-
-    /* Configure if the clock output to I/O pin should be enabled. */
-    if (config->output_enable) {
-        new_genctrl_config |= GCLK_GENCTRL_OE;
-    }
-
-    /* Set division factor */
-    if (config->division_factor > 1) {
-        /* Check if division is a power of two */
-        if (((config->division_factor & (config->division_factor - 1)) == 0)) {
-            /* Determine the index of the highest bit set to get the
-             * division factor that must be loaded into the division
-             * register */
-
-            uint32_t div2_count = 0;
-
-            uint32_t mask;
-            for (mask = (1UL << 1); mask < config->division_factor;
-                    mask <<= 1) {
-                div2_count++;
-            }
-
-            /* Set binary divider power of 2 division factor */
-            new_gendiv_config  |= div2_count << GCLK_GENDIV_DIV_Pos;
-            new_genctrl_config |= GCLK_GENCTRL_DIVSEL;
-        } else {
-            /* Set integer division factor */
-
-            new_gendiv_config  |=
-                (config->division_factor) << GCLK_GENDIV_DIV_Pos;
-
-            /* Enable non-binary division with increased duty cycle accuracy */
-            new_genctrl_config |= GCLK_GENCTRL_IDC;
-        }
-
-    }
-
-    /* Enable or disable the clock in standby mode */
-    if (config->run_in_standby) {
-        new_genctrl_config |= GCLK_GENCTRL_RUNSTDBY;
-    }
-
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the correct generator */
-    *((uint8_t*)&GCLK->GENDIV.reg) = generator;
-
-    /* Write the new generator configuration */
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-    GCLK->GENDIV.reg  = new_gendiv_config;
-
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-    GCLK->GENCTRL.reg = new_genctrl_config | (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN);
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Enables a Generic Clock Generator that was previously configured.
- *
- * Starts the clock generation of a Generic Clock Generator that was previously
- * configured via a call to \ref system_gclk_gen_set_config().
- *
- * \param[in] generator  Generic Clock Generator index to enable
- */
-void system_gclk_gen_enable(
-    const uint8_t generator)
-{
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator */
-    *((uint8_t*)&GCLK->GENCTRL.reg) = generator;
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    /* Enable generator */
-    GCLK->GENCTRL.reg |= GCLK_GENCTRL_GENEN;
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Disables a Generic Clock Generator that was previously enabled.
- *
- * Stops the clock generation of a Generic Clock Generator that was previously
- * started via a call to \ref system_gclk_gen_enable().
- *
- * \param[in] generator  Generic Clock Generator index to disable
- */
-void system_gclk_gen_disable(
-    const uint8_t generator)
-{
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator */
-    *((uint8_t*)&GCLK->GENCTRL.reg) = generator;
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    /* Disable generator */
-    GCLK->GENCTRL.reg &= ~GCLK_GENCTRL_GENEN;
-    while (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN) {
-        /* Wait for clock to become disabled */
-    }
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Determins if the specified Generic Clock Generator is enabled.
- *
- * \param[in] generator  Generic Clock Generator index to check
- *
- * \return The enabled status.
- * \retval true The Generic Clock Generator is enabled
- * \retval false The Generic Clock Generator is disabled
- */
-bool system_gclk_gen_is_enabled(
-    const uint8_t generator)
-{
-    bool enabled;
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator */
-    *((uint8_t*)&GCLK->GENCTRL.reg) = generator;
-    /* Obtain the enabled status */
-    enabled = (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN);
-
-    system_interrupt_leave_critical_section();
-
-    return enabled;
-}
-
-/**
- * \brief Retrieves the clock frequency of a Generic Clock generator.
- *
- * Determines the clock frequency (in Hz) of a specified Generic Clock
- * generator, used as a source to a Generic Clock Channel module.
- *
- * \param[in] generator  Generic Clock Generator index
- *
- * \return The frequency of the generic clock generator, in Hz.
- */
-uint32_t system_gclk_gen_get_hz(
-    const uint8_t generator)
-{
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the appropriate generator */
-    *((uint8_t*)&GCLK->GENCTRL.reg) = generator;
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    /* Get the frequency of the source connected to the GCLK generator */
-    uint32_t gen_input_hz = system_clock_source_get_hz(
-                                (enum system_clock_source)GCLK->GENCTRL.bit.SRC);
-
-    *((uint8_t*)&GCLK->GENCTRL.reg) = generator;
-
-    uint8_t divsel = GCLK->GENCTRL.bit.DIVSEL;
-
-    /* Select the appropriate generator division register */
-    *((uint8_t*)&GCLK->GENDIV.reg) = generator;
-    while (system_gclk_is_syncing()) {
-        /* Wait for synchronization */
-    };
-
-    uint32_t divider = GCLK->GENDIV.bit.DIV;
-
-    system_interrupt_leave_critical_section();
-
-    /* Check if the generator is using fractional or binary division */
-    if (!divsel && divider > 1) {
-        gen_input_hz /= divider;
-    } else if (divsel) {
-        gen_input_hz >>= (divider+1);
-    }
-
-    return gen_input_hz;
-}
-
-/**
- * \brief Writes a Generic Clock configuration to the hardware module.
- *
- * Writes out a given configuration of a Generic Clock configuration to the
- * hardware module. If the clock is currently running, it will be stopped.
- *
- * \note Once called the clock will not be running; to start the clock,
- *       call \ref system_gclk_chan_enable() after configuring a clock channel.
- *
- * \param[in] channel   Generic Clock channel to configure
- * \param[in] config    Configuration settings for the clock
- *
- */
-void system_gclk_chan_set_config(
-    const uint8_t channel,
-    struct system_gclk_chan_config *const config)
-{
-    /* Sanity check arguments */
-    Assert(config);
-
-    /* Cache the new config to reduce sync requirements */
-    uint32_t new_clkctrl_config = (channel << GCLK_CLKCTRL_ID_Pos);
-
-    /* Select the desired generic clock generator */
-    new_clkctrl_config |= config->source_generator << GCLK_CLKCTRL_GEN_Pos;
-
-    /* Disable generic clock channel */
-    system_gclk_chan_disable(channel);
-
-    /* Write the new configuration */
-    GCLK->CLKCTRL.reg = new_clkctrl_config;
-}
-
-/**
- * \brief Enables a Generic Clock that was previously configured.
- *
- * Starts the clock generation of a Generic Clock that was previously
- * configured via a call to \ref system_gclk_chan_set_config().
- *
- * \param[in] channel   Generic Clock channel to enable
- */
-void system_gclk_chan_enable(
-    const uint8_t channel)
-{
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-
-    /* Enable the generic clock */
-    GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN;
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Disables a Generic Clock that was previously enabled.
- *
- * Stops the clock generation of a Generic Clock that was previously started
- * via a call to \ref system_gclk_chan_enable().
- *
- * \param[in] channel  Generic Clock channel to disable
- */
-void system_gclk_chan_disable(
-    const uint8_t channel)
-{
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-
-    /* Sanity check WRTLOCK */
-    Assert(!GCLK->CLKCTRL.bit.WRTLOCK);
-
-    /* Switch to known-working source so that the channel can be disabled */
-    uint32_t prev_gen_id = GCLK->CLKCTRL.bit.GEN;
-    GCLK->CLKCTRL.bit.GEN = 0;
-
-    /* Disable the generic clock */
-    GCLK->CLKCTRL.reg &= ~GCLK_CLKCTRL_CLKEN;
-    while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN) {
-        /* Wait for clock to become disabled */
-    }
-
-    /* Restore previous configured clock generator */
-    GCLK->CLKCTRL.bit.GEN = prev_gen_id;
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Determins if the specified Generic Clock channel is enabled.
- *
- * \param[in] channel  Generic Clock Channel index
- *
- * \return The enabled status.
- * \retval true The Generic Clock channel is enabled
- * \retval false The Generic Clock channel is disabled
- */
-bool system_gclk_chan_is_enabled(
-    const uint8_t channel)
-{
-    bool enabled;
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generic clock channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-    enabled = GCLK->CLKCTRL.bit.CLKEN;
-
-    system_interrupt_leave_critical_section();
-
-    return enabled;
-}
-
-/**
- * \brief Locks a Generic Clock channel from further configuration writes.
- *
- * Locks a generic clock channel from further configuration writes. It is only
- * possible to unlock the channel configuration through a power on reset.
- *
- * \param[in] channel   Generic Clock channel to enable
- */
-void system_gclk_chan_lock(
-    const uint8_t channel)
-{
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generator channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-
-    /* Lock the generic clock */
-    GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_WRTLOCK;
-
-    system_interrupt_leave_critical_section();
-}
-
-/**
- * \brief Determins if the specified Generic Clock channel is locked.
- *
- * \param[in] channel  Generic Clock Channel index
- *
- * \return The lock status.
- * \retval true The Generic Clock channel is locked
- * \retval false The Generic Clock channel is not locked
- */
-bool system_gclk_chan_is_locked(
-    const uint8_t channel)
-{
-    bool locked;
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generic clock channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-    locked = GCLK->CLKCTRL.bit.WRTLOCK;
-
-    system_interrupt_leave_critical_section();
-
-    return locked;
-}
-
-/**
- * \brief Retrieves the clock frequency of a Generic Clock channel.
- *
- * Determines the clock frequency (in Hz) of a specified Generic Clock
- * channel, used as a source to a device peripheral module.
- *
- * \param[in] channel  Generic Clock Channel index
- *
- * \return The frequency of the generic clock channel, in Hz.
- */
-uint32_t system_gclk_chan_get_hz(
-    const uint8_t channel)
-{
-    uint8_t gen_id;
-
-    system_interrupt_enter_critical_section();
-
-    /* Select the requested generic clock channel */
-    *((uint8_t*)&GCLK->CLKCTRL.reg) = channel;
-    gen_id = GCLK->CLKCTRL.bit.GEN;
-
-    system_interrupt_leave_critical_section();
-
-    /* Return the clock speed of the associated GCLK generator */
-    return system_gclk_gen_get_hz(gen_id);
-}