123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- /**
- * \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 */
|