Microchip® Advanced Software Framework

 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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.

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.

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.

struct dfll_config dfllcfg;
dfll_enable_source(CONFIG_DFLL0_SOURCE);
dfll_config_defaults(&dfllcfg, 0);
dfll_enable(&dfllcfg, 0);

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.

Data Structures

struct  dfll_config
 Hardware-specific representation of DFLL configuration. More...
 

Macros

#define DFLL_COARSE_MAX   (AVR32_SCIF_COARSE_MASK >> AVR32_SCIF_COARSE_OFFSET)
 
#define DFLL_FINE_HALF   (1UL << (AVR32_SCIF_FINE_SIZE - 1))
 
#define DFLL_FINE_MAX   (AVR32_SCIF_FINE_MASK >> AVR32_SCIF_FINE_OFFSET)
 
#define DFLL_MAX_KHZ   (DFLL_MAX_HZ / 1000)
 
#define DFLL_MIN_KHZ   (DFLL_MIN_HZ / 1000)
 

Typedefs

typedef enum genclk_source dfll_refclk_t
 Type used for identifying a reference clock source for the DFLL. More...
 

Functions

static void dfll_config_tune_for_target_hz (struct dfll_config *cfg, uint32_t target_hz)
 Tune the DFLL configuration for a specific target frequency. More...
 
void dfll_disable_closed_loop (unsigned int dfll_id)
 Disable the DFLL identified by dfll_id. More...
 
void dfll_disable_open_loop (unsigned int dfll_id)
 Disable the DFLL identified by dfll_id. More...
 
void dfll_enable_closed_loop (const struct dfll_config *cfg, unsigned int dfll_id)
 Activate the configuration cfg and enable DFLL dfll_id in closed-loop mode. More...
 
void dfll_enable_config_defaults (unsigned int dfll_id)
 Enable the dfll with the default configuration. More...
 
void dfll_enable_open_loop (const struct dfll_config *cfg, unsigned int dfll_id)
 Activate the configuration cfg and enable DFLL dfll_id in open-loop mode. More...
 
static uint32_t dfll_priv_get_source_hz (dfll_refclk_t src)
 

Chip-specific DFLL characteristics

#define NR_DFLLS   1
 Number of on-chip DFLLs. More...
 
#define DFLL_MIN_HZ   20000000UL
 Minimum frequency that the DFLL can generate. More...
 
#define DFLL_MAX_HZ   150000000UL
 Maximum frequency that the DFLL can generate. More...
 

DFLL Configuration

static void dfll_config_init_open_loop_mode (struct dfll_config *cfg)
 Configure the DFLL configuration cfg for open-loop mode. More...
 
static void dfll_config_init_closed_loop_mode (struct dfll_config *cfg, dfll_refclk_t refclk, uint16_t div, uint16_t mul)
 Configure the DFLL configuration cfg for closed-loop mode. More...
 
static void dfll_config_set_fractional_multiplier (struct dfll_config *cfg, uint16_t mul_i, uint16_t mul_f)
 Set a fractional multiplier. More...
 
static void dfll_config_enable_dithering (struct dfll_config *cfg)
 Enable dithering for more accurate frequency generation. More...
 
static void dfll_config_disable_dithering (struct dfll_config *cfg)
 Disable dithering. More...
 
static void dfll_config_set_initial_tuning (struct dfll_config *cfg, uint16_t coarse, uint16_t fine)
 Set initial VCO tuning. More...
 
static void dfll_config_set_max_step (struct dfll_config *cfg, uint16_t coarse, uint16_t fine)
 Set the maximum VCO tuning step size. More...
 
static void dfll_config_enable_ssg (struct dfll_config *cfg, uint16_t amplitude, uint16_t step_size)
 Enable Spread Spectrum Generator. More...
 
static void dfll_config_disable_ssg (struct dfll_config *cfg)
 Disable Spread Spectrum Generator. More...
 
#define dfll_config_defaults(cfg, dfll_id)
 Initialize DFLL configuration using default parameters. More...
 
#define dfll_get_default_rate(dfll_id)
 Return the default rate in Hz of dfll_id. More...
 

Interaction with the DFLL hardware

static bool dfll_is_coarse_locked (unsigned int dfll_id)
 Determine whether or not a DFLL has achieved coarse lock. More...
 
static bool dfll_is_fine_locked (unsigned int dfll_id)
 Determine whether or not a DFLL has achieved fine lock. More...
 
static bool dfll_is_accurate_locked (unsigned int dfll_id)
 Determine whether or not a DFLL has achieved accurate lock. More...
 
static void dfll_enable_source (dfll_refclk_t src)
 Enable the source of the dfll. More...
 
static int dfll_wait_for_coarse_lock (unsigned int dfll_id)
 Wait for the DFLL identified by dfll_id to achieve coarse lock. More...
 
static int dfll_wait_for_fine_lock (unsigned int dfll_id)
 Wait for the DFLL identified by dfll_id to achieve fine lock. More...
 
static int dfll_wait_for_accurate_lock (unsigned int dfll_id)
 Wait for the DFLL identified by dfll_id to achieve accurate lock. More...
 

#define DFLL_COARSE_MAX   (AVR32_SCIF_COARSE_MASK >> AVR32_SCIF_COARSE_OFFSET)
#define dfll_config_defaults (   cfg,
  dfll_id 
)
Value:
CONFIG_DFLL##dfll_id##_SOURCE, \
CONFIG_DFLL##dfll_id##_DIV, \
CONFIG_DFLL##dfll_id##_MUL)
static void dfll_config_init_closed_loop_mode(struct dfll_config *cfg, dfll_refclk_t refclk, uint16_t div, uint16_t mul)
Configure the DFLL configuration cfg for closed-loop mode.
Definition: uc3l/dfll.h:84

Initialize DFLL configuration using default parameters.

After this function returns, 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.

Parameters
cfgThe DFLL configuration to be initialized.
dfll_idUse defaults for this DFLL.

Referenced by run_pll_dfll_test().

#define DFLL_FINE_HALF   (1UL << (AVR32_SCIF_FINE_SIZE - 1))
#define DFLL_FINE_MAX   (AVR32_SCIF_FINE_MASK >> AVR32_SCIF_FINE_OFFSET)
#define dfll_get_default_rate (   dfll_id)
Value:
((dfll_priv_get_source_hz(CONFIG_DFLL##dfll_id##_SOURCE) \
* CONFIG_DFLL##dfll_id##_MUL) \
/ CONFIG_DFLL##dfll_id##_DIV)
static uint32_t dfll_priv_get_source_hz(dfll_refclk_t src)
Definition: uc3l/dfll.h:106

Return the default rate in Hz of dfll_id.

Referenced by sysclk_get_main_hz().

#define DFLL_MAX_HZ   150000000UL

Maximum frequency that the DFLL can generate.

#define DFLL_MAX_KHZ   (DFLL_MAX_HZ / 1000)
#define DFLL_MIN_HZ   20000000UL

Minimum frequency that the DFLL can generate.

#define DFLL_MIN_KHZ   (DFLL_MIN_HZ / 1000)
#define NR_DFLLS   1

Number of on-chip DFLLs.

Type used for identifying a reference clock source for the DFLL.

void dfll_config_disable_dithering ( struct dfll_config cfg)
inlinestatic

Disable dithering.

See Also
dfll_config_enable_dithering()
Parameters
cfgThe DFLL configuration to be modified.

References dfll_config::conf.

void dfll_config_disable_ssg ( struct dfll_config cfg)
inlinestatic

Disable Spread Spectrum Generator.

Parameters
cfgThe DFLL configuration to be modified.

References dfll_config::ssg.

void dfll_config_enable_dithering ( struct dfll_config cfg)
inlinestatic

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.

Parameters
cfgThe DFLL configuration to be modified.

References dfll_config::conf.

void dfll_config_enable_ssg ( struct dfll_config cfg,
uint16_t  amplitude,
uint16_t  step_size 
)
inlinestatic

Enable Spread Spectrum Generator.

Parameters
cfgThe DFLL configuration to be modified.
amplitudeThe amplitude of the spread spectrum.
step_sizeThe step size of the spread spectrum.

References dfll_config::ssg.

void dfll_config_init_closed_loop_mode ( struct dfll_config cfg,
dfll_refclk_t  refclk,
uint16_t  div,
uint16_t  mul 
)
inlinestatic

Configure the DFLL configuration cfg for closed-loop mode.

Parameters
cfgThe DFLL configuration to be initialized.
refclkThe reference clock source.
divReference clock divider.
mulMultiplier (integer part only).

References dfll_config::conf, genclk_config_defaults(), genclk_config_set_divider(), genclk_config_set_source(), dfll_config::mul, dfll_config::ref_cfg, dfll_config::ssg, and dfll_config::step.

Referenced by dfll_enable_config_defaults(), and main().

void dfll_config_init_open_loop_mode ( struct dfll_config cfg)
inlinestatic

Configure the DFLL configuration cfg for open-loop mode.

Parameters
cfgThe DFLL configuration to be initialized.

References dfll_config::conf, genclk_config_defaults(), dfll_config::mul, dfll_config::ref_cfg, dfll_config::ssg, and dfll_config::step.

Referenced by main().

void dfll_config_set_fractional_multiplier ( struct dfll_config cfg,
uint16_t  mul_i,
uint16_t  mul_f 
)
inlinestatic

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.

Parameters
cfgThe DFLL configuration to be modified.
mul_iInteger part of multiplier.
mul_fFractional part of multiplier.

References dfll_config::mul.

void dfll_config_set_initial_tuning ( struct dfll_config cfg,
uint16_t  coarse,
uint16_t  fine 
)
inlinestatic

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.

Parameters
cfgThe DFLL configuration to be modified.
coarseCoarse tuning of the frequency generator.
fineFine tuning of the frequency generator.

References dfll_config::conf.

Referenced by dfll_config_tune_for_target_hz().

void dfll_config_set_max_step ( struct dfll_config cfg,
uint16_t  coarse,
uint16_t  fine 
)
inlinestatic

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.

Parameters
cfgThe DFLL configuration to be modified
coarseThe maximum step size of the coarse VCO tuning.
fineThe maximum step size of the fine VCO tuning.

References dfll_config::step.

static void dfll_config_tune_for_target_hz ( struct dfll_config cfg,
uint32_t  target_hz 
)
inlinestatic

Tune the DFLL configuration for a specific target frequency.

This will set the initial coarse and fine DFLL tuning to match the given target frequency. In open loop mode, this will cause the DFLL to run close to the specified frequency, though it may not match exactly. In closed loop mode, the DFLL will automatically tune itself to the target frequency regardless of the initial tuning, but this function may be used to set a starting point close to the desired frequency in order to reduce the startup time.

Calculating the DFLL frequency

\begin{eqnarray*} f_{DFLL} &=& \left[f_{min} + \left(f_{max} - f_{min}\right) \frac{\mathrm{COARSE}}{\mathrm{COARSE}_{max}}\right] \left(1 + x \frac{\mathrm{FINE} - \mathrm{FINE}_{half}}{\mathrm{FINE}_{max}}\right) = f_{coarse} \left(1 + x \frac{\mathrm{FINE} - \mathrm{FINE}_{half}}{\mathrm{FINE}_{max}}\right) \\ \mathrm{COARSE} &=& \frac{\left(f_{DFLL} - f_{min}\right)} {f_{max} - f_{min}} \mathrm{COARSE}_{max} \\ f_{coarse} &=& f_{min} + \left(f_{max} - f_{min}\right) \frac{\mathrm{COARSE}}{\mathrm{COARSE}_{max}} \\ \mathrm{FINE} &=& \left(10 \frac{f_{DFLL} - f_{coarse}} {f_{coarse}} + \mathrm{FINE}_{half}\right) / 4 \end{eqnarray*}

Parameters
cfgThe DFLL configuration to be tuned.
target_hzTarget frequency in Hz.

References DFLL_COARSE_MAX, dfll_config_set_initial_tuning(), DFLL_FINE_HALF, DFLL_FINE_MAX, DFLL_MAX_KHZ, and DFLL_MIN_KHZ.

Referenced by main().

void dfll_disable_closed_loop ( unsigned int  dfll_id)

Disable the DFLL identified by dfll_id.

Precondition
The DFLL must have been enabled in closed loop mode.
Parameters
dfll_idThe ID of the DFLL to be disabled.

References dfll_write_reg, and genclk_disable().

Referenced by cleanup_pll_dfll_test(), and main().

void dfll_disable_open_loop ( unsigned int  dfll_id)

Disable the DFLL identified by dfll_id.

Precondition
The DFLL must have been enabled in open loop mode.
Parameters
dfll_idThe ID of the DFLL to be disabled.

References dfll_write_reg.

Referenced by main().

void dfll_enable_closed_loop ( const struct dfll_config cfg,
unsigned int  dfll_id 
)

Activate the configuration cfg and enable DFLL dfll_id in closed-loop mode.

Precondition
The configuration in cfg must represent a closed-loop configuration.
Parameters
cfgThe configuration to be activated.
dfll_idThe ID of the DFLL to be enabled.

References dfll_config::conf, cpu_irq_restore(), cpu_irq_save(), dfll_write_reg, genclk_enable(), if(), dfll_config::mul, dfll_config::ref_cfg, dfll_config::ssg, dfll_config::step, UC3L0128, UC3L0256, and UC3L3_L4.

Referenced by dfll_enable_config_defaults(), main(), and run_pll_dfll_test().

void dfll_enable_config_defaults ( unsigned int  dfll_id)

Enable the dfll with the default configuration.

DFLL is enabled, if the DFLL is not already locked.

Parameters
dfll_idThe ID of the DFLL to enable.

References Assert, dfll_config_init_closed_loop_mode(), dfll_enable_closed_loop(), dfll_enable_source(), and dfll_is_fine_locked().

Referenced by genclk_enable_source(), and sysclk_init().

void dfll_enable_open_loop ( const struct dfll_config cfg,
unsigned int  dfll_id 
)

Activate the configuration cfg and enable DFLL dfll_id in open-loop mode.

Precondition
The configuration in cfg must represent an open-loop configuration.
Parameters
cfgThe configuration to be activated.
dfll_idThe ID of the DFLL to be enabled.

References dfll_config::conf, cpu_irq_restore(), cpu_irq_save(), dfll_write_reg, if(), dfll_config::ssg, UC3L0128, UC3L0256, and UC3L3_L4.

Referenced by main().

void dfll_enable_source ( dfll_refclk_t  src)
inlinestatic

Enable the source of the dfll.

The source is enabled, if the source is not already running.

Parameters
dfll_sourcesrc The ID of the DFLL source to enable.

References Assert, GENCLK_SRC_OSC0, GENCLK_SRC_OSC32K, GENCLK_SRC_RC120M, GENCLK_SRC_RC32K, GENCLK_SRC_RCSYS, osc_enable(), OSC_ID_OSC0, OSC_ID_OSC32, OSC_ID_RC120M, OSC_ID_RC32K, osc_is_ready(), and osc_wait_ready().

Referenced by dfll_enable_config_defaults().

bool dfll_is_accurate_locked ( unsigned int  dfll_id)
inlinestatic

Determine whether or not a DFLL has achieved accurate lock.

Parameters
dfll_idThe ID of the DFLL to check.
Return values
trueThe DFLL has determined the final dithering duty cycle.
falseThe DFLL has not yet determined the dithering duty cycle, or has not been enabled with dithering enabled.

Referenced by dfll_wait_for_accurate_lock().

bool dfll_is_coarse_locked ( unsigned int  dfll_id)
inlinestatic

Determine whether or not a DFLL has achieved coarse lock.

Parameters
dfll_idThe ID of the DFLL to check.
Return values
trueThe DFLL has determined the final value of the coarse VCO tuning value.
falseThe DFLL has not yet determined the coarse VCO tuning value, or has not been enabled.

Referenced by dfll_wait_for_coarse_lock().

bool dfll_is_fine_locked ( unsigned int  dfll_id)
inlinestatic

Determine whether or not a DFLL has achieved fine lock.

Parameters
dfll_idThe ID of the DFLL to check.
Return values
trueThe DFLL has determined the final value of the fine VCO tuning value.
falseThe DFLL has not yet determined the fine VCO tuning value, or has not been enabled.

Referenced by dfll_enable_config_defaults(), dfll_wait_for_fine_lock(), and run_pll_dfll_test().

static int dfll_wait_for_accurate_lock ( unsigned int  dfll_id)
inlinestatic

Wait for the DFLL identified by dfll_id to achieve accurate lock.

Parameters
dfll_idThe ID of the DFLL to wait for.
Return values
STATUS_OKThe DFLL has achieved accurate lock.
ERR_TIMEOUTTimed out waiting for lock.

References dfll_is_accurate_locked().

static int dfll_wait_for_coarse_lock ( unsigned int  dfll_id)
inlinestatic

Wait for the DFLL identified by dfll_id to achieve coarse lock.

Parameters
dfll_idThe ID of the DFLL to wait for.
Return values
STATUS_OKThe DFLL has achieved coarse lock.
ERR_TIMEOUTTimed out waiting for lock.

References dfll_is_coarse_locked().

static int dfll_wait_for_fine_lock ( unsigned int  dfll_id)
inlinestatic

Wait for the DFLL identified by dfll_id to achieve fine lock.

Parameters
dfll_idThe ID of the DFLL to wait for.
Return values
STATUS_OKThe DFLL has achieved fine lock.
ERR_TIMEOUTTimed out waiting for lock.

References dfll_is_fine_locked().

Referenced by main().