Microchip® Advanced Software Framework

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator 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_config_enable_dithering(&dfllcfg);
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_CALIB_VALUE   (0x0B)
 
#define DFLL_COARSE_MAX   (255)
 
#define DFLL_FINE_HALF   (255)
 
#define DFLL_FINE_MAX   (511)
 
#define DFLL_MAX_KHZ   (DFLL_MAX_HZ / 1000)
 
#define DFLL_MAX_RANGE1   (110000000)
 
#define DFLL_MAX_RANGE2   (55000000)
 
#define DFLL_MAX_RANGE3   (30000000)
 
#define DFLL_MIN_KHZ   (DFLL_MIN_HZ / 1000)
 
#define DFLL_RANGE0   (0)
 
#define DFLL_RANGE1   (1)
 
#define DFLL_RANGE2   (2)
 
#define DFLL_RANGE3   (3)
 

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 (uint32_t dfll_id)
 
void dfll_disable_open_loop (uint32_t dfll_id)
 
void dfll_enable_closed_loop (const struct dfll_config *cfg, uint32_t dfll_id)
 
void dfll_enable_config_defaults (uint32_t dfll_id)
 
void dfll_enable_open_loop (const struct dfll_config *cfg, uint32_t dfll_id)
 
static bool dfll_is_accurate_locked (uint32_t dfll_id)
 
static bool dfll_is_coarse_locked (uint32_t dfll_id)
 
static bool dfll_is_fine_locked (uint32_t dfll_id)
 
static uint32_t dfll_priv_get_source_hz (dfll_refclk_t src)
 
static void dfll_priv_set_frequency_range (struct dfll_config *cfg, uint32_t freq)
 

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_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_init_open_loop_mode (struct dfll_config *cfg)
 Configure the DFLL configuration cfg for open-loop mode. 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_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 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_CALIB_VALUE   (0x0B)
#define DFLL_COARSE_MAX   (255)
#define dfll_config_defaults (   cfg,
  dfll_id 
)
Value:
dfll_config_init_closed_loop_mode(cfg, \
CONFIG_DFLL##dfll_id##_SOURCE, \
CONFIG_DFLL##dfll_id##_DIV, \
CONFIG_DFLL##dfll_id##_MUL)

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   (255)
#define DFLL_FINE_MAX   (511)
#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: sam4l/dfll.h:164

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_MAX_RANGE1   (110000000)
#define DFLL_MAX_RANGE2   (55000000)
#define DFLL_MAX_RANGE3   (30000000)
#define DFLL_MIN_HZ   20000000UL

Minimum frequency that the DFLL can generate.

#define DFLL_MIN_KHZ   (DFLL_MIN_HZ / 1000)
#define DFLL_RANGE0   (0)
#define DFLL_RANGE1   (1)
#define DFLL_RANGE2   (2)
#define DFLL_RANGE3   (3)
#define NR_DFLLS   1

Number of on-chip DFLLs.

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

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_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_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, dfll_config::freq_range, genclk_config_defaults(), dfll_config::mul, dfll_config::ref_cfg, dfll_config::ssg, dfll_config::step, and dfll_config::val.

Referenced by main().

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::val.

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, DFLL_MIN_KHZ, and dfll_priv_set_frequency_range().

Referenced by main().

void dfll_disable_closed_loop ( uint32_t  dfll_id)

References dfll_write_reg, genclk_disable(), and UNUSED.

Referenced by cleanup_pll_dfll_test(), and main().

void dfll_disable_open_loop ( uint32_t  dfll_id)

References dfll_write_reg, genclk_disable(), and UNUSED.

Referenced by main().

void dfll_enable_config_defaults ( uint32_t  dfll_id)
void dfll_enable_open_loop ( const struct dfll_config cfg,
uint32_t  dfll_id 
)
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_RC32K, GENCLK_SRC_RC80M, GENCLK_SRC_RCSYS, osc_enable(), OSC_ID_OSC0, OSC_ID_OSC32, OSC_ID_RC32K, OSC_ID_RC80M, osc_is_ready(), and osc_wait_ready().

Referenced by dfll_enable_config_defaults().

static bool dfll_is_accurate_locked ( uint32_t  dfll_id)
inlinestatic
static bool dfll_is_coarse_locked ( uint32_t  dfll_id)
inlinestatic
static bool dfll_is_fine_locked ( uint32_t  dfll_id)
inlinestatic
static void dfll_priv_set_frequency_range ( struct dfll_config cfg,
uint32_t  freq 
)
inlinestatic
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().