Nut/OS  4.10.3
API Reference
pm.c
Go to the documentation of this file.
00001 
00037 /* This source file is part of the ATMEL AVR-UC3-SoftwareFramework-1.7.0 Release */
00038 
00039 /*This file has been prepared for Doxygen automatic documentation generation.*/
00054 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
00055  *
00056  * Redistribution and use in source and binary forms, with or without
00057  * modification, are permitted provided that the following conditions are met:
00058  *
00059  * 1. Redistributions of source code must retain the above copyright notice, this
00060  * list of conditions and the following disclaimer.
00061  *
00062  * 2. Redistributions in binary form must reproduce the above copyright notice,
00063  * this list of conditions and the following disclaimer in the documentation
00064  * and/or other materials provided with the distribution.
00065  *
00066  * 3. The name of Atmel may not be used to endorse or promote products derived
00067  * from this software without specific prior written permission.
00068  *
00069  * 4. This software may only be redistributed and used in connection with an Atmel
00070  * AVR product.
00071  *
00072  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
00073  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00074  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00075  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
00076  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00077  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00078  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00079  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00080  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00081  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00082  *
00083  */
00084 
00085 #include <avr32/io.h>
00086 #include <arch/avr32/pm.h>
00087 
00088 #define PASS   0
00089 
00090 
00093 
00094 
00095 typedef union
00096 {
00097   unsigned long                 mcctrl;
00098   avr32_pm_mcctrl_t             MCCTRL;
00099 } u_avr32_pm_mcctrl_t;
00100 
00101 typedef union
00102 {
00103   unsigned long                 cksel;
00104   avr32_pm_cksel_t              CKSEL;
00105 } u_avr32_pm_cksel_t;
00106 
00107 typedef union
00108 {
00109   unsigned long                 pll;
00110   avr32_pm_pll_t                PLL;
00111 } u_avr32_pm_pll_t;
00112 
00113 typedef union
00114 {
00115   unsigned long                 oscctrl0;
00116   avr32_pm_oscctrl0_t           OSCCTRL0;
00117 } u_avr32_pm_oscctrl0_t;
00118 
00119 typedef union
00120 {
00121   unsigned long                 oscctrl1;
00122   avr32_pm_oscctrl1_t           OSCCTRL1;
00123 } u_avr32_pm_oscctrl1_t;
00124 
00125 typedef union
00126 {
00127   unsigned long                 oscctrl32;
00128   avr32_pm_oscctrl32_t          OSCCTRL32;
00129 } u_avr32_pm_oscctrl32_t;
00130 
00131 typedef union
00132 {
00133   unsigned long                 ier;
00134   avr32_pm_ier_t                IER;
00135 } u_avr32_pm_ier_t;
00136 
00137 typedef union
00138 {
00139   unsigned long                 idr;
00140   avr32_pm_idr_t                IDR;
00141 } u_avr32_pm_idr_t;
00142 
00143 typedef union
00144 {
00145   unsigned long                 icr;
00146   avr32_pm_icr_t                ICR;
00147 } u_avr32_pm_icr_t;
00148 
00149 typedef union
00150 {
00151   unsigned long                 gcctrl;
00152   avr32_pm_gcctrl_t             GCCTRL;
00153 } u_avr32_pm_gcctrl_t;
00154 
00155 typedef union
00156 {
00157   unsigned long                 rccr;
00158   avr32_pm_rccr_t               RCCR;
00159 } u_avr32_pm_rccr_t;
00160 
00161 typedef union
00162 {
00163   unsigned long                 bgcr;
00164   avr32_pm_bgcr_t               BGCR;
00165 } u_avr32_pm_bgcr_t;
00166 
00167 typedef union
00168 {
00169   unsigned long                 vregcr;
00170   avr32_pm_vregcr_t             VREGCR;
00171 } u_avr32_pm_vregcr_t;
00172 
00173 typedef union
00174 {
00175   unsigned long                 bod;
00176   avr32_pm_bod_t                BOD;
00177 } u_avr32_pm_bod_t;
00178 
00180 
00181 
00187 static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode)
00188 {
00189   // Read
00190   u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
00191   // Modify
00192   u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode;
00193   // Write
00194   pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
00195 }
00196 
00197 
00198 void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm)
00199 {
00200   pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK);
00201 }
00202 
00203 
00204 void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0)
00205 {
00206   pm_set_osc0_mode(pm, (fosc0 <  900000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0 :
00207                        (fosc0 < 3000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1 :
00208                        (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 :
00209                                            AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3);
00210 }
00211 
00212 
00213 void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup)
00214 {
00215   pm_enable_clk0_no_wait(pm, startup);
00216   pm_wait_for_clk0_ready(pm);
00217 }
00218 
00219 
00220 void pm_disable_clk0(volatile avr32_pm_t *pm)
00221 {
00222   pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK;
00223 }
00224 
00225 
00226 void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
00227 {
00228   // Read register
00229   u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0};
00230   // Modify
00231   u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup;
00232   // Write back
00233   pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0;
00234 
00235   pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK;
00236 }
00237 
00238 
00239 void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm)
00240 {
00241   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK));
00242 }
00243 
00244 
00250 static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode)
00251 {
00252   // Read
00253   u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
00254   // Modify
00255   u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode;
00256   // Write
00257   pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
00258 }
00259 
00260 
00261 void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm)
00262 {
00263   pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK);
00264 }
00265 
00266 
00267 void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1)
00268 {
00269   pm_set_osc1_mode(pm, (fosc1 <  900000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G0 :
00270                        (fosc1 < 3000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G1 :
00271                        (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 :
00272                                            AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3);
00273 }
00274 
00275 
00276 void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup)
00277 {
00278   pm_enable_clk1_no_wait(pm, startup);
00279   pm_wait_for_clk1_ready(pm);
00280 }
00281 
00282 
00283 void pm_disable_clk1(volatile avr32_pm_t *pm)
00284 {
00285   pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK;
00286 }
00287 
00288 
00289 void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
00290 {
00291   // Read register
00292   u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1};
00293   // Modify
00294   u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup;
00295   // Write back
00296   pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1;
00297 
00298   pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK;
00299 }
00300 
00301 
00302 void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm)
00303 {
00304   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK));
00305 }
00306 
00307 
00313 static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode)
00314 {
00315   // Read
00316   u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
00317   // Modify
00318   u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode;
00319   // Write
00320   pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
00321 }
00322 
00323 
00324 void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm)
00325 {
00326   pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK);
00327 }
00328 
00329 
00330 void pm_enable_osc32_crystal(volatile avr32_pm_t *pm)
00331 {
00332   pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL);
00333 }
00334 
00335 
00336 void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup)
00337 {
00338   pm_enable_clk32_no_wait(pm, startup);
00339   pm_wait_for_clk32_ready(pm);
00340 }
00341 
00342 
00343 void pm_disable_clk32(volatile avr32_pm_t *pm)
00344 {
00345   pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK;
00346 }
00347 
00348 
00349 void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup)
00350 {
00351   // Read register
00352   u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32};
00353   // Modify
00354   u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1;
00355   u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup;
00356   // Write back
00357   pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32;
00358 }
00359 
00360 
00361 void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm)
00362 {
00363   while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK));
00364 }
00365 
00366 
00367 void pm_cksel(volatile avr32_pm_t *pm,
00368               unsigned int pbadiv,
00369               unsigned int pbasel,
00370               unsigned int pbbdiv,
00371               unsigned int pbbsel,
00372               unsigned int hsbdiv,
00373               unsigned int hsbsel)
00374 {
00375   u_avr32_pm_cksel_t u_avr32_pm_cksel = {0};
00376 
00377   u_avr32_pm_cksel.CKSEL.cpusel = hsbsel;
00378   u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv;
00379   u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel;
00380   u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv;
00381   u_avr32_pm_cksel.CKSEL.pbasel = pbasel;
00382   u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv;
00383   u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel;
00384   u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv;
00385 
00386   pm->cksel = u_avr32_pm_cksel.cksel;
00387 
00388   // Wait for ckrdy bit and then clear it
00389   while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK));
00390 }
00391 
00392 
00393 void pm_gc_setup(volatile avr32_pm_t *pm,
00394                   unsigned int gc,
00395                   unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1)
00396                   unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1
00397                   unsigned int diven,
00398                   unsigned int div)
00399 {
00400   u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0};
00401 
00402   u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc;
00403   u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll;
00404   u_avr32_pm_gcctrl.GCCTRL.diven  = diven;
00405   u_avr32_pm_gcctrl.GCCTRL.div    = div;
00406 
00407   pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl;
00408 }
00409 
00410 
00411 void pm_gc_enable(volatile avr32_pm_t *pm,
00412                   unsigned int gc)
00413 {
00414   pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK;
00415 }
00416 
00417 
00418 void pm_gc_disable(volatile avr32_pm_t *pm,
00419                    unsigned int gc)
00420 {
00421   pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK;
00422 }
00423 
00424 
00425 void pm_pll_setup(volatile avr32_pm_t *pm,
00426                   unsigned int pll,
00427                   unsigned int mul,
00428                   unsigned int div,
00429                   unsigned int osc,
00430                   unsigned int lockcount)
00431 {
00432   u_avr32_pm_pll_t u_avr32_pm_pll = {0};
00433 
00434   u_avr32_pm_pll.PLL.pllosc   = osc;
00435   u_avr32_pm_pll.PLL.plldiv   = div;
00436   u_avr32_pm_pll.PLL.pllmul   = mul;
00437   u_avr32_pm_pll.PLL.pllcount = lockcount;
00438 
00439   pm->pll[pll] = u_avr32_pm_pll.pll;
00440 }
00441 
00442 
00443 void pm_pll_set_option(volatile avr32_pm_t *pm,
00444                        unsigned int pll,
00445                        unsigned int pll_freq,
00446                        unsigned int pll_div2,
00447                        unsigned int pll_wbwdisable)
00448 {
00449   u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]};
00450   u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2);
00451   pm->pll[pll] = u_avr32_pm_pll.pll;
00452 }
00453 
00454 
00455 unsigned int pm_pll_get_option(volatile avr32_pm_t *pm,
00456                                unsigned int pll)
00457 {
00458   return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET;
00459 }
00460 
00461 
00462 void pm_pll_enable(volatile avr32_pm_t *pm,
00463                   unsigned int pll)
00464 {
00465   pm->pll[pll] |= AVR32_PM_PLLEN_MASK;
00466 }
00467 
00468 
00469 void pm_pll_disable(volatile avr32_pm_t *pm,
00470                   unsigned int pll)
00471 {
00472   pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK;
00473 }
00474 
00475 
00476 void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm)
00477 {
00478   while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK));
00479 }
00480 
00481 
00482 void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm)
00483 {
00484   while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK));
00485 }
00486 
00487 
00488 void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock)
00489 {
00490   // Read
00491   u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl};
00492   // Modify
00493   u_avr32_pm_mcctrl.MCCTRL.mcsel = clock;
00494   // Write back
00495   pm->mcctrl = u_avr32_pm_mcctrl.mcctrl;
00496 }
00497 
00498 
00499 void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup)
00500 {
00501   pm_enable_osc0_crystal(pm, fosc0);            // Enable the Osc0 in crystal mode
00502   pm_enable_clk0(pm, startup);                  // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal
00503   pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0);  // Then switch main clock to Osc0
00504 }
00505 
00506 
00507 void pm_bod_enable_irq(volatile avr32_pm_t *pm)
00508 {
00509   pm->ier = AVR32_PM_IER_BODDET_MASK;
00510 }
00511 
00512 void pm_bod_disable_irq(volatile avr32_pm_t *pm)
00513 {
00514   unsigned char global_interrupt_enabled = Is_global_interrupt_enabled();
00515 
00516   if (global_interrupt_enabled) Disable_global_interrupt();
00517   pm->idr = AVR32_PM_IDR_BODDET_MASK;
00518   pm->isr;
00519   if (global_interrupt_enabled) Enable_global_interrupt();
00520 }
00521 
00522 
00523 void pm_bod_clear_irq(volatile avr32_pm_t *pm)
00524 {
00525   pm->icr = AVR32_PM_ICR_BODDET_MASK;
00526 }
00527 
00528 
00529 unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm)
00530 {
00531   return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0);
00532 }
00533 
00534 
00535 unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm)
00536 {
00537   return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0);
00538 }
00539 
00540 
00541 unsigned long pm_bod_get_level(volatile avr32_pm_t *pm)
00542 {
00543   return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET;
00544 }
00545 
00546 
00547 unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp)
00548 {
00549   return pm->gplp[gplp];
00550 }
00551 
00552 
00553 void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value)
00554 {
00555   pm->gplp[gplp] = value;
00556 }
00557 
00558 
00559 long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module)
00560 {
00561   unsigned long domain = module>>5;
00562   unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
00563 
00564   // Implementation-specific shortcut: the ckMASK registers are contiguous and
00565   // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
00566 
00567   *regptr |= (1<<(module%32));
00568 
00569   return PASS;
00570 }
00571 
00572 long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module)
00573 {
00574   unsigned long domain = module>>5;
00575   unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain);
00576 
00577   // Implementation-specific shortcut: the ckMASK registers are contiguous and
00578   // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK.
00579 
00580   *regptr &= ~(1<<(module%32));
00581 
00582   return PASS;
00583 }