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.
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.
|
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...
|
|
#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
-
cfg | The DFLL configuration to be initialized. |
dfll_id | Use defaults for this DFLL. |
#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:
* 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_MIN_HZ 20000000UL |
Minimum frequency that the DFLL can generate.
Type used for identifying a reference clock source for the DFLL.
void dfll_config_disable_dithering |
( |
struct dfll_config * |
cfg | ) |
|
|
inlinestatic |
void dfll_config_disable_ssg |
( |
struct dfll_config * |
cfg | ) |
|
|
inlinestatic |
Disable Spread Spectrum Generator.
- Parameters
-
cfg | The 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
-
cfg | The 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
-
cfg | The DFLL configuration to be modified. |
amplitude | The amplitude of the spread spectrum. |
step_size | The step size of the spread spectrum. |
References dfll_config::ssg.
void dfll_config_init_open_loop_mode |
( |
struct dfll_config * |
cfg | ) |
|
|
inlinestatic |
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
-
cfg | The DFLL configuration to be modified. |
mul_i | Integer part of multiplier. |
mul_f | Fractional 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
-
cfg | The DFLL configuration to be modified. |
coarse | Coarse tuning of the frequency generator. |
fine | Fine 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
-
cfg | The DFLL configuration to be modified |
coarse | The maximum step size of the coarse VCO tuning. |
fine | The 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
-
cfg | The DFLL configuration to be tuned. |
target_hz | Target 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.
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_id | The ID of the DFLL to be disabled. |
References dfll_write_reg, and genclk_disable().
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_id | The ID of the DFLL to be disabled. |
References dfll_write_reg.
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
-
cfg | The configuration to be activated. |
dfll_id | The ID of the DFLL to be enabled. |
References dfll_config::conf, cpu_irq_restore(), cpu_irq_save(), dfll_write_reg, genclk_enable(), dfll_config::mul, dfll_config::ref_cfg, dfll_config::ssg, dfll_config::step, UC3L0128, UC3L0256, and UC3L3_L4.
Referenced by dfll_enable_config_defaults().
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_id | The ID of the DFLL to enable. |
void dfll_enable_open_loop |
( |
const struct dfll_config * |
cfg, |
|
|
unsigned int |
dfll_id |
|
) |
| |
Enable the source of the dfll.
The source is enabled, if the source is not already running.
- Parameters
-
dfll_source | src 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_id | The ID of the DFLL to check. |
- Return values
-
true | The DFLL has determined the final dithering duty cycle. |
false | The 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_id | The ID of the DFLL to check. |
- Return values
-
true | The DFLL has determined the final value of the coarse VCO tuning value. |
false | The 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_id | The ID of the DFLL to check. |
- Return values
-
true | The DFLL has determined the final value of the fine VCO tuning value. |
false | The DFLL has not yet determined the fine VCO tuning value, or has not been enabled. |
Referenced by dfll_enable_config_defaults(), and dfll_wait_for_fine_lock().
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_id | The ID of the DFLL to wait for. |
- Return values
-
STATUS_OK | The DFLL has achieved accurate lock. |
ERR_TIMEOUT | Timed 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_id | The ID of the DFLL to wait for. |
- Return values
-
STATUS_OK | The DFLL has achieved coarse lock. |
ERR_TIMEOUT | Timed 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_id | The ID of the DFLL to wait for. |
- Return values
-
STATUS_OK | The DFLL has achieved fine lock. |
ERR_TIMEOUT | Timed out waiting for lock. |
References dfll_is_fine_locked().