Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
Diff: targets/hal/TARGET_Atmel/TARGET_SAM_CortexM4/services/clock/dfll.h
- Revision:
- 107:414e9c822e99
diff -r c405d2eb506d -r 414e9c822e99 targets/hal/TARGET_Atmel/TARGET_SAM_CortexM4/services/clock/dfll.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/targets/hal/TARGET_Atmel/TARGET_SAM_CortexM4/services/clock/dfll.h Tue Apr 05 18:15:12 2016 +0100
@@ -0,0 +1,402 @@
+/**
+ * \file
+ *
+ * \brief DFLL management
+ *
+ * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+/*
+ * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
+ */
+#ifndef CLK_DFLL_H_INCLUDED
+#define CLK_DFLL_H_INCLUDED
+
+#include <parts.h>
+#include "conf_clock.h"
+
+#if UC3L
+# include "uc3l/dfll.h"
+#elif SAM4L
+# include "sam4l/dfll.h"
+#else
+# error Unsupported chip type
+#endif
+
+/**
+ * \ingroup clk_group
+ * \defgroup dfll_group DFLL Management
+ *
+ * A Digital Frequency Locked Loop can be used to generate a highly
+ * accurate frequency from a slower-running reference clock, in much the
+ * same way as a PLL. DFLLs typically have shorter startup times and
+ * less jitter. They can also be used in open-loop mode to generate a
+ * less accurate frequency without the use of a reference clock.
+ *
+ * There may be significant variations between platforms in the support
+ * for certain features.
+ *
+ * \par Example: Setting up DFLL0 with default parameters and dithering enabled
+ *
+ * The following example shows how to configure and enable DFLL0 in
+ * closed-loop mode using the default parameters specified through
+ * configuration symbols.
+ * \code
+ dfll_enable_config_defaults(0); \endcode
+ *
+ * To configure and enable DFLL0 in closed-loop mode using the default
+ * parameters and to enable specific feature like dithering for better accuracy,
+ * you can use this initialization process.
+ * \code
+ struct dfll_config dfllcfg;
+
+ dfll_enable_source(CONFIG_DFLL0_SOURCE);
+ dfll_config_defaults(&dfllcfg, 0);
+ dfll_config_enable_dithering(&dfllcfg);
+ dfll_enable(&dfllcfg, 0);
+ dfll_wait_for_accurate_lock(0); \endcode
+ *
+ * When the last function call returns, DFLL0 is running at a frequency
+ * which matches the default configuration as accurately as possible.
+ * Any additional alterations to the default configuration can be added
+ * at the same place as the call to dfll_config_enable_dithering(), but
+ * note that the DFLL will never achieve "accurate" lock if dithering is
+ * disabled.
+ *
+ * @{
+ */
+
+//! \name Chip-specific DFLL characteristics
+//@{
+/**
+ * \def NR_DFLLS
+ * \brief Number of on-chip DFLLs.
+ */
+/**
+ * \def DFLL_MIN_HZ
+ * \brief Minimum frequency that the DFLL can generate.
+ */
+/**
+ * \def DFLL_MAX_HZ
+ * \brief Maximum frequency that the DFLL can generate.
+ */
+//@}
+
+/**
+ * \typedef dfll_refclk_t
+ * \brief Type used for identifying a reference clock source for the DFLL.
+ */
+
+//! \name DFLL Configuration
+//@{
+
+/**
+ * \struct dfll_config
+ * \brief Hardware-specific representation of DFLL configuration.
+ *
+ * This structure contains one or more device-specific values
+ * representing the current DFLL configuration. The contents of this
+ * structure is typically different from platform to platform, and the
+ * user should not access any fields except through the DFLL
+ * configuration API.
+ */
+
+/**
+ * \fn void dfll_config_init_open_loop_mode(struct dfll_config *cfg)
+ * \brief Configure the DFLL configuration \a cfg for open-loop mode.
+ *
+ * \param cfg The DFLL configuration to be initialized.
+ */
+/**
+ * \fn void dfll_config_init_closed_loop_mode(struct dfll_config *cfg,
+ * dfll_refclk_t refclk, uint16_t div, uint16_t mul)
+ * \brief Configure the DFLL configuration \a cfg for closed-loop mode.
+ *
+ * \param cfg The DFLL configuration to be initialized.
+ * \param refclk The reference clock source.
+ * \param div Reference clock divider.
+ * \param mul Multiplier (integer part only).
+ */
+/**
+ * \def dfll_config_defaults(cfg, dfll_id)
+ * \brief Initialize DFLL configuration using default parameters.
+ *
+ * After this function returns, \a cfg will contain a configuration
+ * which will make the DFLL run at (CONFIG_DFLLx_MUL / CONFIG_DFLLx_DIV)
+ * times the frequency of CONFIG_DFLLx_SOURCE. The default configuration
+ * will always use closed-loop mode with no fractional multiplier.
+ *
+ * \param cfg The DFLL configuration to be initialized.
+ * \param dfll_id Use defaults for this DFLL.
+ */
+/**
+ * \def dfll_get_default_rate(dfll_id)
+ * \brief Return the default rate in Hz of \a dfll_id.
+ */
+
+/**
+ * \fn void dfll_config_set_fractional_multiplier(struct dfll_config *cfg,
+ * uint16_t mul_i, uint16_t mul_f)
+ * \brief Set a fractional multiplier.
+ *
+ * This function has no effect in open-loop mode, and is only available
+ * on devices which support fractional multipliers.
+ *
+ * The fractional part of the multiplier is assumed to be 16 bits. The
+ * low-level driver will make sure to shift this value to match the
+ * hardware if necessary.
+ *
+ * \param cfg The DFLL configuration to be modified.
+ * \param mul_i Integer part of multiplier.
+ * \param mul_f Fractional part of multiplier.
+ */
+/**
+ * \fn void dfll_config_enable_dithering(struct dfll_config *cfg)
+ * \brief Enable dithering for more accurate frequency generation.
+ *
+ * The fine LSB input to the VCO is dithered to achieve fractional
+ * approximation to the correct multiplication ratio.
+ *
+ * \param cfg The DFLL configuration to be modified.
+ */
+/**
+ * \fn void dfll_config_disable_dithering(struct dfll_config *cfg)
+ * \brief Disable dithering.
+ *
+ * \see dfll_config_enable_dithering()
+ *
+ * \param cfg The DFLL configuration to be modified.
+ */
+/**
+ * \fn void dfll_config_set_initial_tuning(struct dfll_config *cfg,
+ * uint16_t coarse, uint16_t fine)
+ * \brief Set initial VCO tuning.
+ *
+ * In open loop mode, this will determine the frequency of the output.
+ *
+ * In closed loop mode, this will provide an initial estimate of the VCO
+ * tuning. While the DFLL will automatically adjust these values to
+ * match the desired output frequency, careful selection of initial
+ * values might reduce the time to achieve coarse and fine lock.
+ *
+ * \param cfg The DFLL configuration to be modified.
+ * \param coarse Coarse tuning of the frequency generator.
+ * \param fine Fine tuning of the frequency generator.
+ */
+/**
+ * \fn void dfll_config_set_max_step(struct dfll_config *cfg,
+ * uint16_t coarse, uint16_t fine)
+ * \brief Set the maximum VCO tuning step size.
+ *
+ * This function has no effect in open-loop mode.
+ *
+ * By default, both of these values are set to 50% of their respective
+ * maximums. It is not recommended to set the values any higher than
+ * this, but setting them lower might reduce the frequency overshoot at
+ * the expense of longer time to achieve coarse and/or fine lock.
+ *
+ * \param cfg The DFLL configuration to be modified
+ * \param coarse The maximum step size of the coarse VCO tuning.
+ * \param fine The maximum step size of the fine VCO tuning.
+ */
+/**
+ * \fn void dfll_config_enable_ssg(struct dfll_config *cfg,
+ * uint16_t amplitude, uint16_t step_size)
+ * \brief Enable Spread Spectrum Generator.
+ *
+ * \param cfg The DFLL configuration to be modified.
+ * \param amplitude The amplitude of the spread spectrum.
+ * \param step_size The step size of the spread spectrum.
+ */
+/**
+ * \fn void dfll_config_disable_ssg(struct dfll_config *cfg)
+ * \brief Disable Spread Spectrum Generator.
+ *
+ * \param cfg The DFLL configuration to be modified.
+ */
+//@}
+
+//! \name Interaction with the DFLL hardware
+//@{
+/**
+ * \fn void dfll_enable_open_loop(const struct dfll_config *cfg,
+ * unsigned int dfll_id)
+ * \brief Activate the configuration \a cfg and enable DFLL \a dfll_id
+ * in open-loop mode.
+ *
+ * \pre The configuration in \a cfg must represent an open-loop
+ * configuration.
+ *
+ * \param cfg The configuration to be activated.
+ * \param dfll_id The ID of the DFLL to be enabled.
+ */
+/**
+ * \fn void dfll_enable_closed_loop(const struct dfll_config *cfg,
+ * unsigned int dfll_id)
+ * \brief Activate the configuration \a cfg and enable DFLL \a dfll_id
+ * in closed-loop mode.
+ *
+ * \pre The configuration in \a cfg must represent a closed-loop
+ * configuration.
+ *
+ * \param cfg The configuration to be activated.
+ * \param dfll_id The ID of the DFLL to be enabled.
+ */
+/**
+ * \fn void dfll_disable_open_loop(unsigned int dfll_id)
+ * \brief Disable the DFLL identified by \a dfll_id.
+ *
+ * \pre The DFLL must have been enabled in open loop mode.
+ *
+ * \param dfll_id The ID of the DFLL to be disabled.
+ */
+/**
+ * \fn void dfll_disable_closed_loop(unsigned int dfll_id)
+ * \brief Disable the DFLL identified by \a dfll_id.
+ *
+ * \pre The DFLL must have been enabled in closed loop mode.
+ *
+ * \param dfll_id The ID of the DFLL to be disabled.
+ */
+/**
+ * \fn bool dfll_is_coarse_locked(unsigned int dfll_id)
+ * \brief Determine whether or not a DFLL has achieved coarse lock.
+ *
+ * \param dfll_id The ID of the DFLL to check.
+ *
+ * \retval true The DFLL has determined the final value of the coarse
+ * VCO tuning value.
+ * \retval false The DFLL has not yet determined the coarse VCO tuning
+ * value, or has not been enabled.
+ */
+/**
+ * \fn bool dfll_is_fine_locked(unsigned int dfll_id)
+ * \brief Determine whether or not a DFLL has achieved fine lock.
+ *
+ * \param dfll_id The ID of the DFLL to check.
+ *
+ * \retval true The DFLL has determined the final value of the fine VCO
+ * tuning value.
+ * \retval false The DFLL has not yet determined the fine VCO tuning
+ * value, or has not been enabled.
+ */
+/**
+ * \fn bool dfll_is_accurate_locked(unsigned int dfll_id)
+ * \brief Determine whether or not a DFLL has achieved accurate lock.
+ *
+ * \param dfll_id The ID of the DFLL to check.
+ *
+ * \retval true The DFLL has determined the final dithering duty cycle.
+ * \retval false The DFLL has not yet determined the dithering duty
+ * cycle, or has not been enabled with dithering enabled.
+ */
+/**
+ * \fn void dfll_enable_source(enum dfll_refclk_t src)
+ * \brief Enable the source of the dfll.
+ * The source is enabled, if the source is not already running.
+ *
+ * \param dfll_source src The ID of the DFLL source to enable.
+ */
+/**
+ * \fn void dfll_enable_config_defaults(unsigned int dfll_id)
+ * \brief Enable the dfll with the default configuration.
+ * DFLL is enabled, if the DFLL is not already locked.
+ *
+ * \param dfll_id The ID of the DFLL to enable.
+ */
+
+/**
+ * \brief Wait for the DFLL identified by \a dfll_id to achieve coarse
+ * lock.
+ *
+ * \param dfll_id The ID of the DFLL to wait for.
+ *
+ * \retval STATUS_OK The DFLL has achieved coarse lock.
+ * \retval ERR_TIMEOUT Timed out waiting for lock.
+ */
+static inline int dfll_wait_for_coarse_lock(unsigned int dfll_id)
+{
+ /* TODO: Add timeout mechanism */
+ while (!dfll_is_coarse_locked(dfll_id)) {
+ /* Do nothing */
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Wait for the DFLL identified by \a dfll_id to achieve fine
+ * lock.
+ *
+ * \param dfll_id The ID of the DFLL to wait for.
+ *
+ * \retval STATUS_OK The DFLL has achieved fine lock.
+ * \retval ERR_TIMEOUT Timed out waiting for lock.
+ */
+static inline int dfll_wait_for_fine_lock(unsigned int dfll_id)
+{
+ /* TODO: Add timeout mechanism */
+ while (!dfll_is_fine_locked(dfll_id)) {
+ /* Do nothing */
+ }
+
+ return 0;
+}
+
+/**
+ * \brief Wait for the DFLL identified by \a dfll_id to achieve accurate
+ * lock.
+ *
+ * \param dfll_id The ID of the DFLL to wait for.
+ *
+ * \retval STATUS_OK The DFLL has achieved accurate lock.
+ * \retval ERR_TIMEOUT Timed out waiting for lock.
+ */
+static inline int dfll_wait_for_accurate_lock(unsigned int dfll_id)
+{
+ /* TODO: Add timeout mechanism */
+ while (!dfll_is_accurate_locked(dfll_id)) {
+ /* Do nothing */
+ }
+
+ return 0;
+}
+
+//@}
+//! @}
+
+#endif /* CLK_DFLL_H_INCLUDED */
