Xmega Application Note


pll.h

Go to the documentation of this file.
00001 
00038 #ifndef XMEGA_PLL_H_INCLUDED
00039 #define XMEGA_PLL_H_INCLUDED
00040 
00041 #include <compiler.h>
00042 
00048 #define NR_PLLS         1
00049 #define PLL_MIN_HZ      10000000UL
00050 #define PLL_MAX_HZ      200000000UL
00051 #define PLL_NR_OPTIONS  0
00052 
00053 enum pll_source {
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 };
00061 
00062 #define pll_get_default_rate(pll_id)                              \
00063         pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE,    \
00064                         CONFIG_PLL##pll_id##_MUL,                 \
00065                         CONFIG_PLL##pll_id##_DIV)
00066 
00081 static inline uint32_t pll_get_default_rate_priv(enum pll_source src,
00082                 unsigned int mul, unsigned int div)
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 }
00115 
00116 struct pll_config {
00117         uint8_t ctrl;
00118 };
00119 
00126 static inline void pll_config_init(struct pll_config *cfg, enum pll_source src,
00127                 unsigned int div, unsigned int mul)
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 }
00140 
00141 #define pll_config_defaults(cfg, pll_id)                                \
00142         pll_config_init(cfg,                                            \
00143                         CONFIG_PLL##pll_id##_SOURCE,                    \
00144                         CONFIG_PLL##pll_id##_DIV,                       \
00145                         CONFIG_PLL##pll_id##_MUL)
00146 
00147 static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id)
00148 {
00149         Assert(pll_id < NR_PLLS);
00150 
00151         cfg->ctrl = OSC.PLLCTRL;
00152 }
00153 
00154 static inline void pll_config_write(const struct pll_config *cfg,
00155                 unsigned int pll_id)
00156 {
00157         Assert(pll_id < NR_PLLS);
00158 
00159         OSC.PLLCTRL = cfg->ctrl;
00160 }
00161 
00167 static inline void pll_enable(const struct pll_config *cfg,
00168                 unsigned int pll_id)
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 }
00179 
00183 static inline void pll_disable(unsigned int pll_id)
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 }
00193 
00194 static inline bool pll_is_locked(unsigned int pll_id)
00195 {
00196         Assert(pll_id < NR_PLLS);
00197 
00198         return OSC.STATUS & OSC_PLLRDY_bm;
00199 }
00200 
00202 
00203 #endif /* XMEGA_PLL_H_INCLUDED */
@DOC_TITLE@
Generated on Fri Oct 22 12:15:25 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3