source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/firmwares/wifishield/wifi_dnld/src/SOFTWARE_FRAMEWORK/DRIVERS/PM/pm.c @ 4837

Last change on this file since 4837 was 4837, checked in by daduve, 2 years ago

Adding new version

File size: 14.0 KB
Line 
1/* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
2
3/*This file has been prepared for Doxygen automatic documentation generation.*/
4/*! \file *********************************************************************
5 *
6 * \brief Power Manager driver.
7 *
8 *
9 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
10 * - Supported devices:  All AVR32 devices.
11 * - AppNote:
12 *
13 * \author               Atmel Corporation: http://www.atmel.com \n
14 *                       Support and FAQ: http://support.atmel.no/
15 *
16 *****************************************************************************/
17
18/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 *
23 * 1. Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
25 *
26 * 2. Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials provided with the distribution.
29 *
30 * 3. The name of Atmel may not be used to endorse or promote products derived
31 * from this software without specific prior written permission.
32 *
33 * 4. This software may only be redistributed and used in connection with an Atmel
34 * AVR product.
35 *
36 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
38 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
39 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
40 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
46 *
47 */
48
49#include "compiler.h"
50#include "pm.h"
51
52
53/*! \name PM Writable Bit-Field Registers
54 */
55//! @{
56
57typedef union
58{
59  unsigned long                 mcctrl;
60  avr32_pm_mcctrl_t             MCCTRL;
61} u_avr32_pm_mcctrl_t;
62
63typedef union
64{
65  unsigned long                 cksel;
66  avr32_pm_cksel_t              CKSEL;
67} u_avr32_pm_cksel_t;
68
69typedef union
70{
71  unsigned long                 pll;
72  avr32_pm_pll_t                PLL;
73} u_avr32_pm_pll_t;
74
75typedef union
76{
77  unsigned long                 oscctrl0;
78  avr32_pm_oscctrl0_t           OSCCTRL0;
79} u_avr32_pm_oscctrl0_t;
80
81typedef union
82{
83  unsigned long                 oscctrl1;
84  avr32_pm_oscctrl1_t           OSCCTRL1;
85} u_avr32_pm_oscctrl1_t;
86
87typedef union
88{
89  unsigned long                 oscctrl32;
90  avr32_pm_oscctrl32_t          OSCCTRL32;
91} u_avr32_pm_oscctrl32_t;
92
93typedef union
94{
95  unsigned long                 ier;
96  avr32_pm_ier_t                IER;
97} u_avr32_pm_ier_t;
98
99typedef union
100{
101  unsigned long                 idr;
102  avr32_pm_idr_t                IDR;
103} u_avr32_pm_idr_t;
104
105typedef union
106{
107  unsigned long                 icr;
108  avr32_pm_icr_t                ICR;
109} u_avr32_pm_icr_t;
110
111typedef union
112{
113  unsigned long                 gcctrl;
114  avr32_pm_gcctrl_t             GCCTRL;
115} u_avr32_pm_gcctrl_t;
116
117typedef union
118{
119  unsigned long                 rccr;
120  avr32_pm_rccr_t               RCCR;
121} u_avr32_pm_rccr_t;
122
123typedef union
124{
125  unsigned long                 bgcr;
126  avr32_pm_bgcr_t               BGCR;
127} u_avr32_pm_bgcr_t;
128
129typedef union
130{
131  unsigned long                 vregcr;
132  avr32_pm_vregcr_t             VREGCR;
133} u_avr32_pm_vregcr_t;
134
135typedef union
136{
137  unsigned long                 bod;
138  avr32_pm_bod_t                BOD;
139} u_avr32_pm_bod_t;
140
141//! @}
142
143
144/*! \brief Sets the mode of the oscillator 0.
145 *
146 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
147 * \param mode Oscillator 0 mode (i.e. AVR32_PM_OSCCTRL0_MODE_x).
148 */
149static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode)
150{
151  // Read
152  u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
153  // Modify
154  u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode;
155  // Write
156  pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
157}
158
159
160void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)
161{
162  pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK);
163}
164
165
166void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)
167{
168  pm_set_osc0_mode(pm, (fosc0 <  900000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0 :
169                       (fosc0 < 3000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1 :
170                       (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :
171                                           AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3);
172}
173
174
175void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)
176{
177  pm_enable_clk0_no_wait(pm, startup);
178  pm_wait_for_clk0_ready(pm);
179}
180
181
182void pm_disable_clk0(volatile avr32_pm_t *pm)
183{
184  pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK;
185}
186
187
188void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
189{
190  // Read register
191  u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
192  // Modify
193  u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup;
194  // Write back
195  pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
196
197  pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK;
198}
199
200
201void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)
202{
203  while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK));
204}
205
206
207/*! \brief Sets the mode of the oscillator 1.
208 *
209 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
210 * \param mode Oscillator 1 mode (i.e. AVR32_PM_OSCCTRL1_MODE_x).
211 */
212static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode)
213{
214  // Read
215  u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
216  // Modify
217  u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode;
218  // Write
219  pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
220}
221
222
223void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)
224{
225  pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK);
226}
227
228
229void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)
230{
231  pm_set_osc1_mode(pm, (fosc1 <  900000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G0 :
232                       (fosc1 < 3000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G1 :
233                       (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :
234                                           AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3);
235}
236
237
238void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)
239{
240  pm_enable_clk1_no_wait(pm, startup);
241  pm_wait_for_clk1_ready(pm);
242}
243
244
245void pm_disable_clk1(volatile avr32_pm_t *pm)
246{
247  pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK;
248}
249
250
251void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
252{
253  // Read register
254  u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
255  // Modify
256  u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup;
257  // Write back
258  pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
259
260  pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK;
261}
262
263
264void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)
265{
266  while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK));
267}
268
269
270/*! \brief Sets the mode of the 32-kHz oscillator.
271 *
272 * \param pm Base address of the Power Manager (i.e. &AVR32_PM).
273 * \param mode 32-kHz oscillator mode (i.e. AVR32_PM_OSCCTRL32_MODE_x).
274 */
275static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode)
276{
277  // Read
278  u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
279  // Modify
280  u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode;
281  // Write
282  pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
283}
284
285
286void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)
287{
288  pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK);
289}
290
291
292void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)
293{
294  pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL);
295}
296
297
298void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)
299{
300  pm_enable_clk32_no_wait(pm, startup);
301  pm_wait_for_clk32_ready(pm);
302}
303
304
305void pm_disable_clk32(volatile avr32_pm_t *pm)
306{
307  pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK;
308}
309
310
311void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
312{
313  // Read register
314  u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
315  // Modify
316  u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1;
317  u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup;
318  // Write back
319  pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
320}
321
322
323void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)
324{
325  while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK));
326}
327
328
329void pm_cksel(volatile avr32_pm_t *pm,
330              unsigned int pbadiv,
331              unsigned int pbasel,
332              unsigned int pbbdiv,
333              unsigned int pbbsel,
334              unsigned int hsbdiv,
335              unsigned int hsbsel)
336{
337  u_avr32_pm_cksel_t u_avr32_pm_cksel = {0};
338
339  u_avr32_pm_cksel.CKSEL.cpusel = hsbsel;
340  u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv;
341  u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel;
342  u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv;
343  u_avr32_pm_cksel.CKSEL.pbasel = pbasel;
344  u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv;
345  u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel;
346  u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv;
347
348  pm->cksel = u_avr32_pm_cksel.cksel;
349
350  // Wait for ckrdy bit and then clear it
351  while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK));
352}
353
354
355void pm_gc_setup(volatile avr32_pm_t *pm,
356                  unsigned int gc,
357                  unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)
358                  unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1
359                  unsigned int diven,
360                  unsigned int div)
361{
362  u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0};
363
364  u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc;
365  u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll;
366  u_avr32_pm_gcctrl.GCCTRL.diven  = diven;
367  u_avr32_pm_gcctrl.GCCTRL.div    = div;
368
369  pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl;
370}
371
372
373void pm_gc_enable(volatile avr32_pm_t *pm,
374                  unsigned int gc)
375{
376  pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK;
377}
378
379
380void pm_gc_disable(volatile avr32_pm_t *pm,
381                   unsigned int gc)
382{
383  pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK;
384}
385
386
387void pm_pll_setup(volatile avr32_pm_t *pm,
388                  unsigned int pll,
389                  unsigned int mul,
390                  unsigned int div,
391                  unsigned int osc,
392                  unsigned int lockcount)
393{
394  u_avr32_pm_pll_t u_avr32_pm_pll = {0};
395
396  u_avr32_pm_pll.PLL.pllosc   = osc;
397  u_avr32_pm_pll.PLL.plldiv   = div;
398  u_avr32_pm_pll.PLL.pllmul   = mul;
399  u_avr32_pm_pll.PLL.pllcount = lockcount;
400
401  pm->pll[pll] = u_avr32_pm_pll.pll;
402}
403
404
405void pm_pll_set_option(volatile avr32_pm_t *pm,
406                       unsigned int pll,
407                       unsigned int pll_freq,
408                       unsigned int pll_div2,
409                       unsigned int pll_wbwdisable)
410{
411  u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]};
412  u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2);
413  pm->pll[pll] = u_avr32_pm_pll.pll;
414}
415
416
417unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,
418                               unsigned int pll)
419{
420  return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET;
421}
422
423
424void pm_pll_enable(volatile avr32_pm_t *pm,
425                  unsigned int pll)
426{
427  pm->pll[pll] |= AVR32_PM_PLLEN_MASK;
428}
429
430
431void pm_pll_disable(volatile avr32_pm_t *pm,
432                  unsigned int pll)
433{
434  pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK;
435}
436
437
438void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)
439{
440  while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK));
441}
442
443
444void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)
445{
446  while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK));
447}
448
449
450void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)
451{
452  // Read
453  u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl};
454  // Modify
455  u_avr32_pm_mcctrl.MCCTRL.mcsel = clock;
456  // Write back
457  pm->mcctrl = u_avr32_pm_mcctrl.mcctrl;
458}
459
460
461void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)
462{
463  pm_enable_osc0_crystal(pm, fosc0);            // Enable the Osc0 in crystal mode
464  pm_enable_clk0(pm, startup);                  // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal
465  pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0);  // Then switch main clock to Osc0
466}
467
468
469void pm_bod_enable_irq(volatile avr32_pm_t *pm)
470{
471  pm->ier = AVR32_PM_IER_BODDET_MASK;
472}
473
474
475void pm_bod_disable_irq(volatile avr32_pm_t *pm)
476{
477  Bool global_interrupt_enabled = Is_global_interrupt_enabled();
478
479  if (global_interrupt_enabled) Disable_global_interrupt();
480  pm->idr = AVR32_PM_IDR_BODDET_MASK;
481  pm->isr;
482  if (global_interrupt_enabled) Enable_global_interrupt();
483}
484
485
486void pm_bod_clear_irq(volatile avr32_pm_t *pm)
487{
488  pm->icr = AVR32_PM_ICR_BODDET_MASK;
489}
490
491
492unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm)
493{
494  return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0);
495}
496
497
498unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm)
499{
500  return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0);
501}
502
503
504unsigned long pm_bod_get_level(volatile avr32_pm_t *pm)
505{
506  return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET;
507}
508
509
510unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp)
511{
512  return pm->gplp[gplp];
513}
514
515
516void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value)
517{
518  pm->gplp[gplp] = value;
519}
520
521
522long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module)
523{
524  unsigned long domain = module>>5;
525  unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
526
527  // Implementation-specific shortcut: the ckMASK registers are contiguous and
528  // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
529
530  *regptr |= (1<<(module%32));
531
532  return PASS;
533}
534
535long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module)
536{
537  unsigned long domain = module>>5;
538  unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
539
540  // Implementation-specific shortcut: the ckMASK registers are contiguous and
541  // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
542
543  *regptr &= ~(1<<(module%32));
544
545  return PASS;
546}
Note: See TracBrowser for help on using the repository browser.