Xmega Application Note


PLL Management
[Clock Management]

Collaboration diagram for PLL Management:

Data Structures

struct  pll_config
 Hardware-specific representation of PLL configuration. More...

Defines

#define NR_PLLS   1
#define NR_PLLS   2
#define pll_config_defaults(cfg, pll_id)
#define pll_config_defaults(cfg, pll_id)
#define pll_get_default_rate(pll_id)
#define pll_get_default_rate(pll_id)
#define PLL_MAX_HZ   200000000UL
#define PLL_MAX_HZ   240000000
#define PLL_MIN_HZ   10000000UL
#define PLL_MIN_HZ   40000000
#define PLL_NR_OPTIONS   0
#define PLL_TIMEOUT_MS   div_ceil(1000 * (PLL_MAX_STARTUP_CYCLES * 2), OSC_SLOW_MIN_HZ)
 Number of milliseconds to wait for PLL lock.

Enumerations

enum  pll_source {
  PLL_SRC_OSC0 = 0, PLL_SRC_OSC1 = 1, PLL_NR_SOURCES, PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc,
  PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc
}
enum  pll_source {
  PLL_SRC_OSC0 = 0, PLL_SRC_OSC1 = 1, PLL_NR_SOURCES, PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc,
  PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc
}
 

PLL clock source.

More...

Functions

static uint32_t pll_get_default_rate_priv (enum pll_source src, unsigned int mul, unsigned int div)
 Return clock rate for specified PLL settings.

PLL configuration



static void pll_config_clear_option (struct pll_config *cfg, unsigned int option)
 Clear the PLL option bit option in the configuration cfg.
static void pll_config_init (struct pll_config *cfg, enum pll_source src, unsigned int div, unsigned int mul)
 Initialize PLL configuration from standard parameters.
static void pll_config_read (struct pll_config *cfg, unsigned int pll_id)
 Read the currently active configuration of pll_id.
static void pll_config_set_option (struct pll_config *cfg, unsigned int option)
 Set the PLL option bit option in the configuration cfg.
static void pll_config_write (const struct pll_config *cfg, unsigned int pll_id)
 Activate the configuration cfg on pll_id.

Interaction with the PLL hardware



static void pll_disable (unsigned int pll_id)
 Disable the PLL identified by pll_id.
static void pll_enable (const struct pll_config *cfg, unsigned int pll_id)
 Activate the configuration cfg and enable PLL pll_id.
static bool pll_is_locked (unsigned int pll_id)
 Determine whether the PLL is locked or not.
static int pll_wait_for_lock (unsigned int pll_id)
 Wait for PLL pll_id to become locked.

Chip-specific PLL characteristics



#define PLL_MAX_STARTUP_CYCLES   ((1 << AVR32_PM_PLL0_PLLCOUNT_SIZE) - 1)
 Maximum PLL startup time in number of slow clock cycles.

Chip-specific PLL options



#define PLL_NR_OPTIONS   AVR32_PM_PLL0_PLLOPT_SIZE
 Number of PLL options.
#define PLL_OPT_OUTPUT_DIV   1
 Divide output frequency by two.
#define PLL_OPT_VCO_RANGE_LOW   0
 VCO frequency range is 80-180 MHz (160-240 MHz if unset).
#define PLL_OPT_WBM_DISABLE   2
 Disable wide-bandwidth mode.
#define PLL_VCO_LOW_THRESHOLD   AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ
 The threshold under which to set the PLL_OPT_VCO_RANGE_LOW option.

Detailed Description

This group contains functions and definitions related to configuring and enabling/disabling on-chip PLLs. A PLL will take an input signal (the source), optionally divide the frequency by a configurable divider, and then multiply the frequency by a configurable multiplier.

Some devices don't support input dividers; specifying any other divisor than 1 on these devices will result in an assertion failure. Other devices may have various restrictions to the frequency range of the input and output signals.

Example: Setting up PLL0 with default parameters

The following example shows how to configure and enable PLL0 using the default parameters specified using the configuration symbols listed above, and with Wide Bandwidth Mode disabled (a UC3A3-specific PLL option.)

        struct pll_config pllcfg;

        pll_config_defaults(&pllcfg, 0);
        pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE);
        pll_enable(&pllcfg, 0);
        pll_wait_for_lock(0); 

When the last function call returns, PLL0 is ready to be used as the main system clock source.

Configuration Symbols

Each PLL has a set of default parameters determined by the following configuration symbols in the application's configuration file:

These configuration symbols determine the result of calling pll_config_defaults() and pll_get_default_rate().


Define Documentation

#define NR_PLLS   1

Definition at line 48 of file pll.h.

#define NR_PLLS   2
#define pll_config_defaults ( cfg,
pll_id   ) 
Value:
pll_config_init(cfg,                                            \
                        CONFIG_PLL##pll_id##_SOURCE,                    \
                        CONFIG_PLL##pll_id##_DIV,                       \
                        CONFIG_PLL##pll_id##_MUL)

Definition at line 141 of file pll.h.

#define pll_config_defaults ( cfg,
pll_id   ) 
Value:
pll_config_init(cfg,                                                   \
                        CONFIG_PLL##pll_id##_SOURCE,                           \
                        CONFIG_PLL##pll_id##_DIV,                              \
                        CONFIG_PLL##pll_id##_MUL)

Definition at line 153 of file pll.h.

#define pll_get_default_rate ( pll_id   ) 
Value:
pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE,    \
                        CONFIG_PLL##pll_id##_MUL,                 \
                        CONFIG_PLL##pll_id##_DIV)

Definition at line 62 of file pll.h.

#define pll_get_default_rate ( pll_id   ) 
Value:
((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE)                            \
                        * CONFIG_PLL##pll_id##_MUL)                            \
                        / CONFIG_PLL##pll_id##_DIV)

Definition at line 93 of file pll.h.

Referenced by sysclk_get_main_hz().

#define PLL_MAX_HZ   200000000UL

Definition at line 50 of file pll.h.

#define PLL_MAX_HZ   240000000

Definition at line 60 of file pll.h.

Referenced by pll_get_default_rate_priv().

#define PLL_MAX_STARTUP_CYCLES   ((1 << AVR32_PM_PLL0_PLLCOUNT_SIZE) - 1)

Maximum PLL startup time in number of slow clock cycles.

Definition at line 46 of file pll.h.

#define PLL_MIN_HZ   10000000UL

Definition at line 49 of file pll.h.

#define PLL_MIN_HZ   40000000
Note:
The PLL must run at twice this frequency internally, but the output frequency may be divided by two by setting the PLLOPT[1] bit.

Definition at line 59 of file pll.h.

Referenced by pll_get_default_rate_priv().

#define PLL_NR_OPTIONS   0

Definition at line 51 of file pll.h.

#define PLL_NR_OPTIONS   AVR32_PM_PLL0_PLLOPT_SIZE

Number of PLL options.

Definition at line 71 of file pll.h.

Referenced by pll_config_clear_option(), and pll_config_set_option().

#define PLL_OPT_OUTPUT_DIV   1

Divide output frequency by two.

Definition at line 67 of file pll.h.

#define PLL_OPT_VCO_RANGE_LOW   0

VCO frequency range is 80-180 MHz (160-240 MHz if unset).

Definition at line 65 of file pll.h.

#define PLL_OPT_WBM_DISABLE   2

Disable wide-bandwidth mode.

Definition at line 69 of file pll.h.

#define PLL_TIMEOUT_MS   div_ceil(1000 * (PLL_MAX_STARTUP_CYCLES * 2), OSC_SLOW_MIN_HZ)

Number of milliseconds to wait for PLL lock.

Definition at line 52 of file pll.h.

#define PLL_VCO_LOW_THRESHOLD   AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ

The threshold under which to set the PLL_OPT_VCO_RANGE_LOW option.

Definition at line 73 of file pll.h.


Enumeration Type Documentation

enum pll_source
Enumerator:
PLL_SRC_OSC0 

Oscillator 0.

PLL_SRC_OSC1 

Oscillator 1.

PLL_NR_SOURCES 

Number of PLL sources.

PLL_SRC_RC2MHZ 

2 MHz Internal RC Oscillator

PLL_SRC_RC32MHZ 

32 MHz Internal RC Oscillator

PLL_SRC_XOSC 

External Clock Source.

Definition at line 53 of file pll.h.

00053                 {
00055         PLL_SRC_RC2MHZ     = OSC_PLLSRC_RC2M_gc,
00057         PLL_SRC_RC32MHZ    = OSC_PLLSRC_RC32M_gc,
00059         PLL_SRC_XOSC       = OSC_PLLSRC_XOSC_gc,
00060 };

enum pll_source

PLL clock source.

Enumerator:
PLL_SRC_OSC0 

Oscillator 0.

PLL_SRC_OSC1 

Oscillator 1.

PLL_NR_SOURCES 

Number of PLL sources.

PLL_SRC_RC2MHZ 

2 MHz Internal RC Oscillator

PLL_SRC_RC32MHZ 

32 MHz Internal RC Oscillator

PLL_SRC_XOSC 

External Clock Source.

Definition at line 83 of file pll.h.

00083                 {
00084         PLL_SRC_OSC0            = 0,    
00085         PLL_SRC_OSC1            = 1,    
00086         PLL_NR_SOURCES,                 
00087 };


Function Documentation

void pll_config_clear_option ( struct pll_config cfg,
unsigned int  option 
) [inline, static]

Clear the PLL option bit option in the configuration cfg.

Parameters:
cfg The PLL configuration to be changed.
option The PLL option bit to be cleared.

Definition at line 106 of file pll.h.

References Assert, pll_config::ctrl, and PLL_NR_OPTIONS.

00108 {
00109         Assert(option < PLL_NR_OPTIONS);
00110 
00111         cfg->ctrl &= ~(1U << (AVR32_PM_PLL0_PLLOPT + option));
00112 }

static void pll_config_init ( struct pll_config cfg,
enum pll_source  src,
unsigned int  div,
unsigned int  mul 
) [inline, static]

Initialize PLL configuration from standard parameters.

The PLL options PLL_OPT_VCO_RANGE_LOW and PLL_OPT_OUTPUT_DIV will be set automatically based on the calculated target frequency.

Note:
The XMEGA PLL hardware uses hard-wired input dividers, so the user must ensure that div is set as follows:
  • If src is PLL_SRC_32MHZ, div must be set to 4.
  • Otherwise, div must be set to 1.
This function may be defined inline because it is assumed to be called very few times, and usually with constant parameters. Inlining it will in such cases reduce the code size significantly.
Parameters:
cfg The PLL configuration to be initialized.
src The oscillator to be used as input to the PLL.
div PLL input divider.
mul PLL loop divider (i.e. multiplier).
Returns:
A configuration which will make the PLL run at (mul / div) times the frequency of src

Definition at line 126 of file pll.h.

References Assert, pll_config::ctrl, and PLL_SRC_RC32MHZ.

00128 {
00129         Assert(mul >= 1 && mul <= 31);
00130 
00131         if (src == PLL_SRC_RC32MHZ) {
00132                 Assert(div == 4);
00133         } else {
00134                 Assert(div == 1);
00135         }
00136 
00137         /* Initialize the configuration */
00138         cfg->ctrl = src | (mul << OSC_PLLFAC_gp);
00139 }

static void pll_config_read ( struct pll_config cfg,
unsigned int  pll_id 
) [inline, static]

Read the currently active configuration of pll_id.

Parameters:
cfg The configuration object into which to store the currently active configuration.
pll_id The ID of the PLL to be accessed.

Definition at line 147 of file pll.h.

References Assert, pll_config::ctrl, and NR_PLLS.

00148 {
00149         Assert(pll_id < NR_PLLS);
00150 
00151         cfg->ctrl = OSC.PLLCTRL;
00152 }

void pll_config_set_option ( struct pll_config cfg,
unsigned int  option 
) [inline, static]

Set the PLL option bit option in the configuration cfg.

Parameters:
cfg The PLL configuration to be changed.
option The PLL option bit to be set.

Definition at line 98 of file pll.h.

References Assert, pll_config::ctrl, and PLL_NR_OPTIONS.

00100 {
00101         Assert(option < PLL_NR_OPTIONS);
00102 
00103         cfg->ctrl |= 1U << (AVR32_PM_PLL0_PLLOPT + option);
00104 }

static void pll_config_write ( const struct pll_config cfg,
unsigned int  pll_id 
) [inline, static]

Activate the configuration cfg on pll_id.

Parameters:
cfg The configuration object representing the PLL configuration to be activated.
pll_id The ID of the PLL to be updated.

Definition at line 154 of file pll.h.

References Assert, pll_config::ctrl, and NR_PLLS.

Referenced by pll_enable().

00156 {
00157         Assert(pll_id < NR_PLLS);
00158 
00159         OSC.PLLCTRL = cfg->ctrl;
00160 }

static void pll_disable ( unsigned int  pll_id  )  [inline, static]

Disable the PLL identified by pll_id.

Note:
This will not automatically disable the reference oscillator that is configured for the PLL.

After this function is called, the PLL identified by pll_id will be disabled. The PLL configuration stored in hardware may be affected by this, so if the caller needs to restore the same configuration later, it should either do a pll_config_read() before disabling the PLL, or remember the last configuration written to the PLL.

Parameters:
pll_id The ID of the PLL to be disabled.

Definition at line 183 of file pll.h.

References Assert, cpu_irq_restore(), cpu_irq_save(), and NR_PLLS.

00184 {
00185         irqflags_t flags;
00186 
00187         Assert(pll_id < NR_PLLS);
00188 
00189         flags = cpu_irq_save();
00190         OSC.CTRL &= ~OSC_PLLEN_bm;
00191         cpu_irq_restore(flags);
00192 }

Here is the call graph for this function:

static void pll_enable ( const struct pll_config cfg,
unsigned int  pll_id 
) [inline, static]

Activate the configuration cfg and enable PLL pll_id.

Note:
If a different PLL reference oscillator than those enabled by sysclk_init() is used, the user must ensure that the desired reference is enabled prior to calling this function.
Parameters:
cfg The PLL configuration to be activated.
pll_id The ID of the PLL to be enabled.

Definition at line 167 of file pll.h.

References Assert, cpu_irq_restore(), cpu_irq_save(), NR_PLLS, and pll_config_write().

00169 {
00170         irqflags_t flags;
00171 
00172         Assert(pll_id < NR_PLLS);
00173 
00174         flags = cpu_irq_save();
00175         pll_config_write(cfg, pll_id);
00176         OSC.CTRL |= OSC_PLLEN_bm;
00177         cpu_irq_restore(flags);
00178 }

Here is the call graph for this function:

static uint32_t pll_get_default_rate_priv ( enum pll_source  src,
unsigned int  mul,
unsigned int  div 
) [inline, static]

Return clock rate for specified PLL settings.

For internal use only.

Note:
Due to the hardware implementation of the PLL, div must be 4 if the 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must be above 440 kHz, and the output between 10 and 200 MHz.
Parameters:
src ID of the PLL's reference source oscillator.
mul Multiplier for the PLL.
div Divisor for the PLL.
Return values:
Output clock rate from PLL.

Definition at line 81 of file pll.h.

References Assert, osc_get_rate(), OSC_ID_XOSC, PLL_MAX_HZ, PLL_MIN_HZ, PLL_SRC_RC2MHZ, PLL_SRC_RC32MHZ, and PLL_SRC_XOSC.

00083 {
00084         uint32_t rate;
00085 
00086         switch (src) {
00087         case PLL_SRC_RC2MHZ:
00088                 rate = 2000000UL;
00089                 Assert(div == 1);
00090                 break;
00091 
00092         case PLL_SRC_RC32MHZ:
00093                 rate = 8000000UL;
00094                 Assert(div == 4);
00095                 break;
00096 
00097         case PLL_SRC_XOSC:
00098                 rate = osc_get_rate(OSC_ID_XOSC);
00099                 Assert(div == 1);
00100                 break;
00101 
00102         default:
00103                 break;
00104         }
00105 
00106         Assert(rate >= 440000UL);
00107 
00108         rate *= mul;
00109 
00110         Assert(rate >= PLL_MIN_HZ);
00111         Assert(rate <= PLL_MAX_HZ);
00112 
00113         return rate;
00114 }

Here is the call graph for this function:

static bool pll_is_locked ( unsigned int  pll_id  )  [inline, static]

Determine whether the PLL is locked or not.

Parameters:
pll_id The ID of the PLL to check.
Return values:
true The PLL is locked and ready to use as a clock source
false The PLL is not yet locked, or has not been enabled.

Definition at line 194 of file pll.h.

References Assert, and NR_PLLS.

Referenced by pll_wait_for_lock().

00195 {
00196         Assert(pll_id < NR_PLLS);
00197 
00198         return OSC.STATUS & OSC_PLLRDY_bm;
00199 }

static int pll_wait_for_lock ( unsigned int  pll_id  )  [inline, static]

Wait for PLL pll_id to become locked.

Todo:
Use a timeout to avoid waiting forever and hanging the system
Parameters:
pll_id The ID of the PLL to wait for.
Return values:
STATUS_OK The PLL is now locked.
ERR_TIMEOUT Timed out waiting for PLL to become locked.

Definition at line 261 of file pll.h.

References Assert, NR_PLLS, and pll_is_locked().

00262 {
00263         Assert(pll_id < NR_PLLS);
00264 
00265         while (!pll_is_locked(pll_id)) {
00266                 /* Do nothing */
00267         }
00268 
00269         return 0;
00270 }

Here is the call graph for this function:

@DOC_TITLE@
Generated on Fri Oct 22 12:15:26 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3