1 /*This file has been prepared for Doxygen automatic documentation generation.*/
\r
2 /*! \file *********************************************************************
\r
4 * \brief Power Manager driver.
\r
7 * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
\r
8 * - Supported devices: All AVR32 devices.
\r
11 * \author Atmel Corporation: http://www.atmel.com \n
\r
12 * Support and FAQ: http://support.atmel.no/
\r
14 *****************************************************************************/
\r
16 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
\r
18 * Redistribution and use in source and binary forms, with or without
\r
19 * modification, are permitted provided that the following conditions are met:
\r
21 * 1. Redistributions of source code must retain the above copyright notice,
\r
22 * this list of conditions and the following disclaimer.
\r
24 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
25 * this list of conditions and the following disclaimer in the documentation
\r
26 * and/or other materials provided with the distribution.
\r
28 * 3. The name of ATMEL may not be used to endorse or promote products derived
\r
29 * from this software without specific prior written permission.
\r
31 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
\r
32 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
33 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
\r
34 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
\r
35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
\r
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
47 /*! \name PM Writable Bit-Field Registers
\r
53 unsigned long mcctrl;
\r
54 avr32_pm_mcctrl_t MCCTRL;
\r
55 } u_avr32_pm_mcctrl_t;
\r
59 unsigned long cksel;
\r
60 avr32_pm_cksel_t CKSEL;
\r
61 } u_avr32_pm_cksel_t;
\r
71 unsigned long oscctrl0;
\r
72 avr32_pm_oscctrl0_t OSCCTRL0;
\r
73 } u_avr32_pm_oscctrl0_t;
\r
77 unsigned long oscctrl1;
\r
78 avr32_pm_oscctrl1_t OSCCTRL1;
\r
79 } u_avr32_pm_oscctrl1_t;
\r
83 unsigned long oscctrl32;
\r
84 avr32_pm_oscctrl32_t OSCCTRL32;
\r
85 } u_avr32_pm_oscctrl32_t;
\r
102 avr32_pm_icr_t ICR;
\r
103 } u_avr32_pm_icr_t;
\r
107 unsigned long gcctrl;
\r
108 avr32_pm_gcctrl_t GCCTRL;
\r
109 } u_avr32_pm_gcctrl_t;
\r
113 unsigned long rccr;
\r
114 avr32_pm_rccr_t RCCR;
\r
115 } u_avr32_pm_rccr_t;
\r
119 unsigned long bgcr;
\r
120 avr32_pm_bgcr_t BGCR;
\r
121 } u_avr32_pm_bgcr_t;
\r
125 unsigned long vregcr;
\r
126 avr32_pm_vregcr_t VREGCR;
\r
127 } u_avr32_pm_vregcr_t;
\r
132 avr32_pm_bod_t BOD;
\r
133 } u_avr32_pm_bod_t;
\r
138 /*! \brief Sets the mode of the oscillator 0.
\r
140 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
\r
141 * \param mode Oscillator 0 mode (i.e. AVR32_PM_OSCCTRL0_MODE_x).
\r
143 static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode)
\r
146 u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
\r
148 u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode;
\r
150 pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
\r
154 void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)
\r
156 pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK);
\r
160 void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)
\r
162 pm_set_osc0_mode(pm, (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :
\r
163 AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3);
\r
167 void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)
\r
169 pm_enable_clk0_no_wait(pm, startup);
\r
170 pm_wait_for_clk0_ready(pm);
\r
174 void pm_disable_clk0(volatile avr32_pm_t *pm)
\r
176 pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK;
\r
180 void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
\r
183 u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
\r
185 u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup;
\r
187 pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
\r
189 pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK;
\r
193 void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)
\r
195 while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK));
\r
199 /*! \brief Sets the mode of the oscillator 1.
\r
201 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
\r
202 * \param mode Oscillator 1 mode (i.e. AVR32_PM_OSCCTRL1_MODE_x).
\r
204 static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode)
\r
207 u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
\r
209 u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode;
\r
211 pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
\r
215 void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)
\r
217 pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK);
\r
221 void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)
\r
223 pm_set_osc1_mode(pm, (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :
\r
224 AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3);
\r
228 void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)
\r
230 pm_enable_clk1_no_wait(pm, startup);
\r
231 pm_wait_for_clk1_ready(pm);
\r
235 void pm_disable_clk1(volatile avr32_pm_t *pm)
\r
237 pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK;
\r
241 void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
\r
244 u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
\r
246 u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup;
\r
248 pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
\r
250 pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK;
\r
254 void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)
\r
256 while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK));
\r
260 /*! \brief Sets the mode of the 32-kHz oscillator.
\r
262 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
\r
263 * \param mode 32-kHz oscillator mode (i.e. AVR32_PM_OSCCTRL32_MODE_x).
\r
265 static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode)
\r
268 u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
\r
270 u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode;
\r
272 pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
\r
276 void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)
\r
278 pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK);
\r
282 void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)
\r
284 pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL);
\r
288 void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)
\r
290 pm_enable_clk32_no_wait(pm, startup);
\r
291 pm_wait_for_clk32_ready(pm);
\r
295 void pm_disable_clk32(volatile avr32_pm_t *pm)
\r
297 pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK;
\r
301 void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
\r
304 u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
\r
306 u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1;
\r
307 u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup;
\r
309 pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
\r
313 void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)
\r
315 while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK));
\r
319 void pm_cksel(volatile avr32_pm_t *pm,
\r
320 unsigned int pbadiv,
\r
321 unsigned int pbasel,
\r
322 unsigned int pbbdiv,
\r
323 unsigned int pbbsel,
\r
324 unsigned int hsbdiv,
\r
325 unsigned int hsbsel)
\r
327 u_avr32_pm_cksel_t u_avr32_pm_cksel = {0};
\r
329 u_avr32_pm_cksel.CKSEL.cpusel = hsbsel;
\r
330 u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv;
\r
331 u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel;
\r
332 u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv;
\r
333 u_avr32_pm_cksel.CKSEL.pbasel = pbasel;
\r
334 u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv;
\r
335 u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel;
\r
336 u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv;
\r
338 pm->cksel = u_avr32_pm_cksel.cksel;
\r
340 // Wait for ckrdy bit and then clear it
\r
341 while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK));
\r
345 void pm_gc_setup(volatile avr32_pm_t *pm,
\r
347 unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)
\r
348 unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1
\r
349 unsigned int diven,
\r
352 u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0};
\r
354 u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc;
\r
355 u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll;
\r
356 u_avr32_pm_gcctrl.GCCTRL.diven = diven;
\r
357 u_avr32_pm_gcctrl.GCCTRL.div = div;
\r
359 pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl;
\r
363 void pm_gc_enable(volatile avr32_pm_t *pm,
\r
366 pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK;
\r
370 void pm_gc_disable(volatile avr32_pm_t *pm,
\r
373 pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK;
\r
377 void pm_pll_setup(volatile avr32_pm_t *pm,
\r
382 unsigned int lockcount)
\r
384 u_avr32_pm_pll_t u_avr32_pm_pll = {0};
\r
386 u_avr32_pm_pll.PLL.pllosc = osc;
\r
387 u_avr32_pm_pll.PLL.plldiv = div;
\r
388 u_avr32_pm_pll.PLL.pllmul = mul;
\r
389 u_avr32_pm_pll.PLL.pllcount = lockcount;
\r
391 pm->pll[pll] = u_avr32_pm_pll.pll;
\r
395 void pm_pll_set_option(volatile avr32_pm_t *pm,
\r
397 unsigned int pll_freq,
\r
398 unsigned int pll_div2,
\r
399 unsigned int pll_wbwdisable)
\r
401 u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]};
\r
402 u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2);
\r
403 pm->pll[pll] = u_avr32_pm_pll.pll;
\r
407 unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,
\r
410 return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET;
\r
414 void pm_pll_enable(volatile avr32_pm_t *pm,
\r
417 pm->pll[pll] |= AVR32_PM_PLLEN_MASK;
\r
421 void pm_pll_disable(volatile avr32_pm_t *pm,
\r
424 pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK;
\r
428 void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)
\r
430 while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK));
\r
432 // Bypass the lock signal of the PLL
\r
433 pm->pll[0] |= AVR32_PM_PLL0_PLLBPL_MASK;
\r
437 void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)
\r
439 while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK));
\r
441 // Bypass the lock signal of the PLL
\r
442 pm->pll[1] |= AVR32_PM_PLL1_PLLBPL_MASK;
\r
446 void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)
\r
449 u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl};
\r
451 u_avr32_pm_mcctrl.MCCTRL.mcsel = clock;
\r
453 pm->mcctrl = u_avr32_pm_mcctrl.mcctrl;
\r
457 void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)
\r
459 pm_enable_osc0_crystal(pm, fosc0); // Enable the Osc0 in crystal mode
\r
460 pm_enable_clk0(pm, startup); // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal
\r
461 pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0); // Then switch main clock to Osc0
\r
465 void pm_bod_enable_irq(volatile avr32_pm_t *pm)
\r
467 pm->ier = AVR32_PM_IER_BODDET_MASK;
\r
471 void pm_bod_disable_irq(volatile avr32_pm_t *pm)
\r
473 pm->idr = AVR32_PM_IDR_BODDET_MASK;
\r
477 void pm_bod_clear_irq(volatile avr32_pm_t *pm)
\r
479 pm->icr = AVR32_PM_ICR_BODDET_MASK;
\r
483 unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm)
\r
485 return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0);
\r
489 unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm)
\r
491 return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0);
\r
495 unsigned long pm_bod_get_level(volatile avr32_pm_t *pm)
\r
497 return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET;
\r
501 void pm_write_gplp(volatile avr32_pm_t *pm,unsigned long gplp, unsigned long value)
\r
503 pm->gplp[gplp] = value;
\r
507 unsigned long pm_read_gplp(volatile avr32_pm_t *pm,unsigned long gplp)
\r
509 return pm->gplp[gplp];
\r