em_cmu.c

Go to the documentation of this file.
00001 /***************************************************************************/
00034 #include "em_cmu.h"
00035 #if defined( CMU_PRESENT )
00036 
00037 #include "em_assert.h"
00038 #include "em_bitband.h"
00039 #include "em_emu.h"
00040 
00041 /***************************************************************************/
00046 /***************************************************************************/
00052 /*******************************************************************************
00053  ******************************   DEFINES   ************************************
00054  ******************************************************************************/
00055 
00059 #define CMU_MAX_FREQ_0WS    16000000
00060 
00061 #define CMU_MAX_FREQ_1WS    32000000
00062 
00063 #if defined( CMU_CTRL_HFLE )
00064 
00066 #if defined ( _EFM32_WONDER_FAMILY ) ||  \
00067     defined ( _EZR32_LEOPARD_FAMILY ) || \
00068     defined ( _EZR32_WONDER_FAMILY )
00069 #define CMU_MAX_FREQ_HFLE   24000000
00070 #elif defined ( _EFM32_GIANT_FAMILY )
00071 #define CMU_MAX_FREQ_HFLE   (CMU_MaxFreqHfle())
00072 #else
00073 #error Invalid part/device.
00074 #endif
00075 #endif
00076 
00078 #define CMU_LFA             0
00079 
00081 #define CMU_LFB             1
00082 
00085 /*******************************************************************************
00086  **************************   LOCAL FUNCTIONS   ********************************
00087  ******************************************************************************/
00088 
00091 #if defined( CMU_CTRL_HFLE ) &&         \
00092   !defined ( _EFM32_WONDER_FAMILY ) &&  \
00093   !defined ( _EZR32_LEOPARD_FAMILY ) && \
00094   !defined ( _EZR32_WONDER_FAMILY )
00095 
00096 /***************************************************************************/
00100 static uint32_t CMU_MaxFreqHfle(void)
00101 {
00102   /* SYSTEM_GetFamily and SYSTEM_ChipRevisionGet could have been used here
00103      but we want to minimize dependencies in em_cmu.c. */
00104   uint16_t majorMinorRev;
00105   uint8_t  deviceFamily = ((DEVINFO->PART & _DEVINFO_PART_DEVICE_FAMILY_MASK)
00106                            >> _DEVINFO_PART_DEVICE_FAMILY_SHIFT);
00107   switch (deviceFamily)
00108   {
00109   case _DEVINFO_PART_DEVICE_FAMILY_LG:
00110     /* CHIP MAJOR bit [3:0] */
00111     majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
00112                       >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
00113     /* CHIP MINOR bit [7:4] */
00114     majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
00115                        >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
00116     /* CHIP MINOR bit [3:0] */
00117     majorMinorRev |=  ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
00118                        >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
00119 
00120     if (majorMinorRev >= 0x0204)
00121       return 24000000;
00122     else
00123       return 32000000;
00124   case _DEVINFO_PART_DEVICE_FAMILY_GG:
00125     return 32000000;
00126   case _DEVINFO_PART_DEVICE_FAMILY_WG:
00127     return 24000000;
00128   default:
00129     /* Invalid device family. */
00130     EFM_ASSERT(false);
00131     return 0;
00132   }
00133 }
00134 #endif
00135 
00136 
00137 /***************************************************************************/
00145 static void CMU_FlashWaitStateControl(uint32_t hfcoreclk)
00146 {
00147   uint32_t mode;
00148   bool mscLocked;
00149 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
00150   bool scbtpEn;
00151 #endif
00152 
00153   /* Make sure the MSC is unlocked */
00154   mscLocked = MSC->LOCK;
00155   MSC->LOCK = MSC_UNLOCK_CODE;
00156 
00157   /* Get mode and SCBTP enable */
00158   mode = MSC->READCTRL & _MSC_READCTRL_MODE_MASK;
00159 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
00160   switch(mode)
00161   {
00162     case MSC_READCTRL_MODE_WS0:
00163     case MSC_READCTRL_MODE_WS1:
00164 #if defined( MSC_READCTRL_MODE_WS2 )
00165     case MSC_READCTRL_MODE_WS2:
00166 #endif
00167       scbtpEn = false;
00168       break;
00169 
00170     default: /* WSxSCBTP */
00171       scbtpEn = true;
00172     break;
00173   }
00174 #endif
00175 
00176 
00177   /* Set mode based on the core clock frequency and SCBTP enable */
00178 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
00179   if (false)
00180   {
00181   }
00182 #if defined( MSC_READCTRL_MODE_WS2 )
00183   else if (hfcoreclk > CMU_MAX_FREQ_1WS)
00184   {
00185     mode = (scbtpEn ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2);
00186   }
00187 #endif
00188   else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))
00189   {
00190     mode = (scbtpEn ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1);
00191   }
00192   else
00193   {
00194     mode = (scbtpEn ? MSC_READCTRL_MODE_WS0SCBTP : MSC_READCTRL_MODE_WS0);
00195   }
00196 
00197 #else /* If MODE and SCBTP is in separate register fields */
00198 
00199   if (false)
00200   {
00201   }
00202 #if defined( MSC_READCTRL_MODE_WS2 )
00203   else if (hfcoreclk > CMU_MAX_FREQ_1WS)
00204   {
00205     mode = MSC_READCTRL_MODE_WS2;
00206   }
00207 #endif
00208   else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))
00209   {
00210     mode = MSC_READCTRL_MODE_WS1;
00211   }
00212   else
00213   {
00214     mode = MSC_READCTRL_MODE_WS0;
00215   }
00216 #endif
00217 
00218   /* BUS_RegMaskedWrite cannot be used here as it would temporarely set the
00219      mode field to WS0 */
00220   MSC->READCTRL = (MSC->READCTRL &~_MSC_READCTRL_MODE_MASK) | mode;
00221 
00222   if (mscLocked)
00223   {
00224     MSC->LOCK = 0;
00225   }
00226 }
00227 
00228 
00229 /***************************************************************************/
00234 static void CMU_FlashWaitStateMax(void)
00235 {
00236   uint32_t maxCoreClock;
00237 #if defined   (_EFM32_GECKO_FAMILY)
00238   maxCoreClock = 32000000;
00239 #elif defined (_EFM32_GIANT_FAMILY)
00240   maxCoreClock = 48000000;
00241 #elif defined (_EFM32_TINY_FAMILY)
00242   maxCoreClock = 32000000;
00243 #elif defined (_EFM32_LEOPARD_FAMILY)
00244   maxCoreClock = 48000000;
00245 #elif defined (_EFM32_WONDER_FAMILY)
00246   maxCoreClock = 48000000;
00247 #elif defined (_EFM32_ZERO_FAMILY)
00248   maxCoreClock = 24000000;
00249 #elif defined (_EFM32_HAPPY_FAMILY)
00250   maxCoreClock = 25000000;
00251 #else
00252 #error "Max core clock frequency is not defined for this family"
00253 #endif
00254 
00255   /* Use SystemMaxCoreClockGet() when available in CMSIS */
00256   CMU_FlashWaitStateControl(maxCoreClock);
00257 }
00258 
00259 
00260 /***************************************************************************/
00266 __STATIC_INLINE uint32_t CMU_DivToLog2(CMU_ClkDiv_TypeDef div)
00267 {
00268   uint32_t log2;
00269 
00270   /* Prescalers take argument of 32768 or less */
00271   EFM_ASSERT((div>0) && (div <= 32768));
00272 
00273   /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
00274   log2 = (31 - __CLZ(div));
00275 
00276   return log2;
00277 }
00278 
00279 
00280 /***************************************************************************/
00285 __STATIC_INLINE uint32_t CMU_Log2ToDiv(uint32_t log2)
00286 {
00287   return 1<<log2;
00288 }
00289 
00290 
00291 #if defined(USB_PRESENT)
00292 /***************************************************************************/
00299 static uint32_t CMU_USBCClkGet(void)
00300 {
00301   uint32_t ret;
00302   CMU_Select_TypeDef clk;
00303 
00304   /* Get selected clock source */
00305   clk = CMU_ClockSelectGet(cmuClock_USBC);
00306 
00307   switch(clk)
00308   {
00309   case cmuSelect_LFXO:
00310     ret = SystemLFXOClockGet();
00311     break;
00312   case cmuSelect_LFRCO:
00313     ret = SystemLFRCOClockGet();
00314     break;
00315   case cmuSelect_HFCLK:
00316     ret = SystemHFClockGet();
00317     break;
00318   default:
00319     /* Clock is not enabled */
00320     ret = 0;
00321     break;
00322   }
00323   return ret;
00324 }
00325 #endif
00326 
00327 
00328 /***************************************************************************/
00336 static uint32_t CMU_AUXClkGet(void)
00337 {
00338   uint32_t ret;
00339 
00340 #if defined(_EFM32_GECKO_FAMILY)
00341   /* Gecko has a fixed 14Mhz AUXHFRCO clock */
00342   ret = 14000000;
00343 #else
00344   switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)
00345   {
00346   case CMU_AUXHFRCOCTRL_BAND_1MHZ:
00347     ret = 1000000;
00348     break;
00349   case CMU_AUXHFRCOCTRL_BAND_7MHZ:
00350     ret = 7000000;
00351     break;
00352   case CMU_AUXHFRCOCTRL_BAND_11MHZ:
00353     ret = 11000000;
00354     break;
00355   case CMU_AUXHFRCOCTRL_BAND_14MHZ:
00356     ret = 14000000;
00357     break;
00358   case CMU_AUXHFRCOCTRL_BAND_21MHZ:
00359     ret = 21000000;
00360     break;
00361 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
00362   case CMU_AUXHFRCOCTRL_BAND_28MHZ:
00363     ret = 28000000;
00364     break;
00365 #endif
00366   default:
00367     ret = 0;
00368     break;
00369   }
00370 #endif
00371   return ret;
00372 }
00373 
00374 
00375 /***************************************************************************/
00382 static uint32_t CMU_DBGClkGet(void)
00383 {
00384   uint32_t ret;
00385   CMU_Select_TypeDef clk;
00386 
00387   /* Get selected clock source */
00388   clk = CMU_ClockSelectGet(cmuClock_DBG);
00389 
00390   switch(clk)
00391   {
00392   case cmuSelect_HFCLK:
00393     ret = SystemHFClockGet();
00394 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
00395     /* Giant Gecko has an additional divider, not used by USBC */
00396     ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
00397                       _CMU_CTRL_HFCLKDIV_SHIFT));
00398 #endif
00399     break;
00400 
00401   case cmuSelect_AUXHFRCO:
00402     ret = CMU_AUXClkGet();
00403     break;
00404 
00405   default:
00406     EFM_ASSERT(0);
00407     ret = 0;
00408     break;
00409   }
00410   return ret;
00411 }
00412 
00413 
00414 /***************************************************************************/
00425 static uint32_t CMU_LFClkGet(unsigned int lfClkBranch)
00426 {
00427   uint32_t ret;
00428 
00429   EFM_ASSERT(lfClkBranch == CMU_LFA || lfClkBranch == CMU_LFB);
00430 
00431   switch ((CMU->LFCLKSEL >> (lfClkBranch * 2)) & 0x3)
00432   {
00433   case _CMU_LFCLKSEL_LFA_LFRCO:
00434     ret = SystemLFRCOClockGet();
00435     break;
00436 
00437   case _CMU_LFCLKSEL_LFA_LFXO:
00438     ret = SystemLFXOClockGet();
00439     break;
00440 
00441   case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
00442 #if defined( CMU_CTRL_HFLE )
00443     /* Giant Gecko can use a /4 divider (and must if >32MHz) or HFLE is set */
00444     if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK) == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)||
00445        (CMU->CTRL & CMU_CTRL_HFLE))
00446     {
00447       ret = SystemCoreClockGet() / 4;
00448     }
00449     else
00450     {
00451       ret = SystemCoreClockGet() / 2;
00452     }
00453 #else
00454     ret = SystemCoreClockGet() / 2;
00455 #endif
00456     break;
00457 
00458   case _CMU_LFCLKSEL_LFA_DISABLED:
00459 #if defined( CMU_LFCLKSEL_LFAE )
00460     /* Check LF Extended bit setting for ULFRCO clock */
00461     if(CMU->LFCLKSEL >> (_CMU_LFCLKSEL_LFAE_SHIFT + lfClkBranch * 4))
00462     {
00463       ret = SystemULFRCOClockGet();
00464     }
00465     else
00466     {
00467       ret = 0;
00468     }
00469 #else
00470     ret = 0;
00471 #endif
00472     break;
00473 
00474   default:
00475     ret = 0;
00476     break;
00477   }
00478 
00479   return ret;
00480 }
00481 
00482 
00483 /***************************************************************************/
00491 __STATIC_INLINE void CMU_Sync(uint32_t mask)
00492 {
00493   /* Avoid deadlock if modifying the same register twice when freeze mode is */
00494   /* activated. */
00495   if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)
00496     return;
00497 
00498   /* Wait for any pending previous write operation to have been completed */
00499   /* in low frequency domain */
00500   while (CMU->SYNCBUSY & mask)
00501     ;
00502 }
00503 
00504 
00507 /*******************************************************************************
00508  **************************   GLOBAL FUNCTIONS   *******************************
00509  ******************************************************************************/
00510 
00511 /***************************************************************************/
00533 uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
00534 {
00535   EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
00536 
00537   /* Set reference clock source */
00538   switch (ref)
00539   {
00540   case cmuOsc_LFXO:
00541     CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;
00542     break;
00543 
00544   case cmuOsc_LFRCO:
00545     CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;
00546     break;
00547 
00548   case cmuOsc_HFXO:
00549     CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;
00550     break;
00551 
00552   case cmuOsc_HFRCO:
00553     CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;
00554     break;
00555 
00556   case cmuOsc_AUXHFRCO:
00557     CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;
00558     break;
00559 
00560   default:
00561     EFM_ASSERT(0);
00562     return 0;
00563   }
00564 
00565   /* Set top value */
00566   CMU->CALCNT = HFCycles;
00567 
00568   /* Start calibration */
00569   CMU->CMD = CMU_CMD_CALSTART;
00570 
00571   /* Wait until calibration completes */
00572   while (CMU->STATUS & CMU_STATUS_CALBSY)
00573     ;
00574 
00575   return CMU->CALCNT;
00576 }
00577 
00578 
00579 #if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )
00580 /***************************************************************************/
00606 void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
00607                          CMU_Osc_TypeDef upSel)
00608 {
00609   /* Keep untouched configuration settings */
00610   uint32_t calCtrl = CMU->CALCTRL & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);
00611 
00612   /* 20 bits of precision to calibration count register */
00613   EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
00614 
00615   /* Set down counting clock source - down counter */
00616   switch (downSel)
00617   {
00618   case cmuOsc_LFXO:
00619     calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;
00620     break;
00621 
00622   case cmuOsc_LFRCO:
00623     calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;
00624     break;
00625 
00626   case cmuOsc_HFXO:
00627     calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;
00628     break;
00629 
00630   case cmuOsc_HFRCO:
00631     calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;
00632     break;
00633 
00634   case cmuOsc_AUXHFRCO:
00635     calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;
00636     break;
00637 
00638   default:
00639     EFM_ASSERT(0);
00640     break;
00641   }
00642 
00643   /* Set top value to be counted down by the downSel clock */
00644   CMU->CALCNT = downCycles;
00645 
00646   /* Set reference clock source - up counter */
00647   switch (upSel)
00648   {
00649   case cmuOsc_LFXO:
00650     calCtrl |= CMU_CALCTRL_UPSEL_LFXO;
00651     break;
00652 
00653   case cmuOsc_LFRCO:
00654     calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;
00655     break;
00656 
00657   case cmuOsc_HFXO:
00658     calCtrl |= CMU_CALCTRL_UPSEL_HFXO;
00659     break;
00660 
00661   case cmuOsc_HFRCO:
00662     calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;
00663     break;
00664 
00665   case cmuOsc_AUXHFRCO:
00666     calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;
00667     break;
00668 
00669   default:
00670     EFM_ASSERT(0);
00671     break;
00672   }
00673 
00674   CMU->CALCTRL = calCtrl;
00675 }
00676 #endif
00677 
00678 
00679 /***************************************************************************/
00691 CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
00692 {
00693   uint32_t           divReg;
00694   CMU_ClkDiv_TypeDef ret;
00695 
00696   /* Get divisor reg id */
00697   divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
00698 
00699   switch (divReg)
00700   {
00701 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
00702   case CMU_HFCLKDIV_REG:
00703     ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
00704                _CMU_CTRL_HFCLKDIV_SHIFT);
00705     break;
00706 #endif
00707 
00708   case CMU_HFPERCLKDIV_REG:
00709     ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV &
00710                                 _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
00711                                _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
00712     ret = CMU_Log2ToDiv(ret);
00713     break;
00714 
00715   case CMU_HFCORECLKDIV_REG:
00716     ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV &
00717                                 _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
00718                                _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
00719     ret = CMU_Log2ToDiv(ret);
00720     break;
00721 
00722   case CMU_LFAPRESC0_REG:
00723     switch (clock)
00724     {
00725     case cmuClock_RTC:
00726       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
00727                                   _CMU_LFAPRESC0_RTC_SHIFT));
00728       ret = CMU_Log2ToDiv(ret);
00729       break;
00730 
00731 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
00732     case cmuClock_LETIMER0:
00733       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
00734                                   _CMU_LFAPRESC0_LETIMER0_SHIFT));
00735       ret = CMU_Log2ToDiv(ret);
00736       break;
00737 #endif
00738 
00739 #if defined(_CMU_LFAPRESC0_LCD_MASK)
00740     case cmuClock_LCDpre:
00741       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
00742                                   _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16));
00743       ret = CMU_Log2ToDiv(ret);
00744       break;
00745 #endif
00746 
00747 #if defined(_CMU_LFAPRESC0_LESENSE_MASK)
00748     case cmuClock_LESENSE:
00749       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
00750                                   _CMU_LFAPRESC0_LESENSE_SHIFT));
00751       ret = CMU_Log2ToDiv(ret);
00752       break;
00753 #endif
00754 
00755     default:
00756       EFM_ASSERT(0);
00757       ret = cmuClkDiv_1;
00758       break;
00759     }
00760     break;
00761 
00762   case CMU_LFBPRESC0_REG:
00763     switch (clock)
00764     {
00765 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
00766     case cmuClock_LEUART0:
00767       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
00768                                   _CMU_LFBPRESC0_LEUART0_SHIFT));
00769       ret = CMU_Log2ToDiv(ret);
00770       break;
00771 #endif
00772 
00773 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
00774     case cmuClock_LEUART1:
00775       ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
00776                                   _CMU_LFBPRESC0_LEUART1_SHIFT));
00777       ret = CMU_Log2ToDiv(ret);
00778       break;
00779 #endif
00780 
00781     default:
00782       EFM_ASSERT(0);
00783       ret = cmuClkDiv_1;
00784       break;
00785     }
00786     break;
00787 
00788   default:
00789     EFM_ASSERT(0);
00790     ret = cmuClkDiv_1;
00791     break;
00792   }
00793 
00794   return(ret);
00795 }
00796 
00797 
00798 /***************************************************************************/
00817 void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
00818 {
00819   uint32_t freq;
00820   uint32_t divReg;
00821 
00822   /* Get divisor reg id */
00823   divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
00824 
00825   switch (divReg)
00826   {
00827 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
00828   case CMU_HFCLKDIV_REG:
00829     EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));
00830 
00831     /* Configure worst case wait states for flash access before setting divisor */
00832     CMU_FlashWaitStateMax();
00833 
00834     /* Set divider */
00835     CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK) |
00836       ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);
00837 
00838     /* Update CMSIS core clock variable */
00839     /* (The function will update the global variable) */
00840     freq = SystemCoreClockGet();
00841 
00842     /* Optimize flash access wait state setting for current core clk */
00843     CMU_FlashWaitStateControl(freq);
00844     break;
00845 #endif
00846 
00847   case CMU_HFPERCLKDIV_REG:
00848     EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));
00849     /* Convert to correct scale */
00850     div = CMU_DivToLog2(div);
00851     CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) |
00852                        (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
00853     break;
00854 
00855   case CMU_HFCORECLKDIV_REG:
00856     EFM_ASSERT(div <= cmuClkDiv_512);
00857 
00858     /* Configure worst case wait states for flash access before setting divisor */
00859     CMU_FlashWaitStateMax();
00860 
00861 #if defined( CMU_CTRL_HFLE )
00862     /* Clear HFLE and set DIV2 factor for peripheral clock
00863        when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */
00864     if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE)
00865     {
00866       /* Clear CMU HFLE */
00867       BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 0);
00868 
00869       /* Set DIV2 factor for peripheral clock */
00870       BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
00871                          _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);
00872     }
00873     else
00874     {
00875       /* Set CMU HFLE */
00876       BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
00877 
00878       /* Set DIV4 factor for peripheral clock */
00879       BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
00880                          _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
00881     }
00882 #endif
00883 
00884     /* Convert to correct scale */
00885     div = CMU_DivToLog2(div);
00886 
00887     CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) |
00888                         (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
00889 
00890     /* Update CMSIS core clock variable */
00891     /* (The function will update the global variable) */
00892     freq = SystemCoreClockGet();
00893 
00894     /* Optimize flash access wait state setting for current core clk */
00895     CMU_FlashWaitStateControl(freq);
00896     break;
00897 
00898   case CMU_LFAPRESC0_REG:
00899     switch (clock)
00900     {
00901     case cmuClock_RTC:
00902       EFM_ASSERT(div <= cmuClkDiv_32768);
00903 
00904       /* LF register about to be modified require sync. busy check */
00905       CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
00906 
00907       /* Convert to correct scale */
00908       div = CMU_DivToLog2(div);
00909 
00910       CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK) |
00911                        (div << _CMU_LFAPRESC0_RTC_SHIFT);
00912       break;
00913 
00914 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
00915     case cmuClock_LETIMER0:
00916       EFM_ASSERT(div <= cmuClkDiv_32768);
00917 
00918       /* LF register about to be modified require sync. busy check */
00919       CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
00920 
00921       /* Convert to correct scale */
00922       div = CMU_DivToLog2(div);
00923 
00924       CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK) |
00925                        (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);
00926       break;
00927 #endif
00928 
00929 #if defined(LCD_PRESENT)
00930     case cmuClock_LCDpre:
00931       EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));
00932 
00933       /* LF register about to be modified require sync. busy check */
00934       CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
00935 
00936       /* Convert to correct scale */
00937       div = CMU_DivToLog2(div);
00938 
00939       CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK) |
00940                        ((div - CMU_DivToLog2(cmuClkDiv_16)) << _CMU_LFAPRESC0_LCD_SHIFT);
00941       break;
00942 #endif /* defined(LCD_PRESENT) */
00943 
00944 #if defined(LESENSE_PRESENT)
00945     case cmuClock_LESENSE:
00946       EFM_ASSERT(div <= cmuClkDiv_8);
00947 
00948       /* LF register about to be modified require sync. busy check */
00949       CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
00950 
00951       /* Convert to correct scale */
00952       div = CMU_DivToLog2(div);
00953 
00954       CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK) |
00955                        (div << _CMU_LFAPRESC0_LESENSE_SHIFT);
00956       break;
00957 #endif /* defined(LESENSE_PRESENT) */
00958 
00959     default:
00960       EFM_ASSERT(0);
00961       break;
00962     }
00963     break;
00964 
00965   case CMU_LFBPRESC0_REG:
00966     switch (clock)
00967     {
00968 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
00969     case cmuClock_LEUART0:
00970       EFM_ASSERT(div <= cmuClkDiv_8);
00971 
00972       /* LF register about to be modified require sync. busy check */
00973       CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
00974 
00975       /* Convert to correct scale */
00976       div = CMU_DivToLog2(div);
00977 
00978       CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK) |
00979                        (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);
00980       break;
00981 #endif
00982 
00983 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
00984     case cmuClock_LEUART1:
00985       EFM_ASSERT(div <= cmuClkDiv_8);
00986 
00987       /* LF register about to be modified require sync. busy check */
00988       CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
00989 
00990       /* Convert to correct scale */
00991       div = CMU_DivToLog2(div);
00992 
00993       CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK) |
00994                        (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);
00995       break;
00996 #endif
00997 
00998     default:
00999       EFM_ASSERT(0);
01000       break;
01001     }
01002     break;
01003 
01004   default:
01005     EFM_ASSERT(0);
01006     break;
01007   }
01008 }
01009 
01010 
01011 /***************************************************************************/
01038 void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
01039 {
01040   volatile uint32_t *reg;
01041   uint32_t          bit;
01042   uint32_t          sync = 0;
01043 
01044   /* Identify enable register */
01045   switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)
01046   {
01047   case CMU_HFPERCLKDIV_EN_REG:
01048     reg = &(CMU->HFPERCLKDIV);
01049     break;
01050 
01051   case CMU_HFPERCLKEN0_EN_REG:
01052     reg = &(CMU->HFPERCLKEN0);
01053     break;
01054 
01055   case CMU_HFCORECLKEN0_EN_REG:
01056     reg = &(CMU->HFCORECLKEN0);
01057 
01058 #if defined( CMU_CTRL_HFLE )
01059     /* Set HFLE and DIV4 factor for peripheral clock when
01060        running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */
01061     if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE )
01062     {
01063       /* Enable CMU HFLE */
01064       BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
01065 
01066       /* Set DIV4 factor for peripheral clock */
01067       BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
01068                          _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
01069     }
01070 #endif
01071     break;
01072 
01073   case CMU_LFACLKEN0_EN_REG:
01074     reg  = &(CMU->LFACLKEN0);
01075     sync = CMU_SYNCBUSY_LFACLKEN0;
01076     break;
01077 
01078   case CMU_LFBCLKEN0_EN_REG:
01079     reg  = &(CMU->LFBCLKEN0);
01080     sync = CMU_SYNCBUSY_LFBCLKEN0;
01081     break;
01082 
01083   case CMU_PCNT_EN_REG:
01084     reg = &(CMU->PCNTCTRL);
01085     break;
01086 
01087 #if defined( _CMU_LFCCLKEN0_MASK )
01088   case CMU_LFCCLKEN0_EN_REG:
01089     reg = &(CMU->LFCCLKEN0);
01090     sync = CMU_SYNCBUSY_LFCCLKEN0;
01091     break;
01092 #endif
01093 
01094   default: /* Cannot enable/disable clock point */
01095     EFM_ASSERT(0);
01096     return;
01097   }
01098 
01099   /* Get bit position used to enable/disable */
01100   bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;
01101 
01102   /* LF synchronization required? */
01103   if (sync)
01104   {
01105     CMU_Sync(sync);
01106   }
01107 
01108   /* Set/clear bit as requested */
01109   BITBAND_Peripheral(reg, bit, (unsigned int)enable);
01110 }
01111 
01112 
01113 /***************************************************************************/
01123 uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
01124 {
01125   uint32_t ret;
01126 
01127   switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))
01128   {
01129     case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01130     {
01131       ret = SystemHFClockGet();
01132 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
01133       /* Giant Gecko has an additional divider, not used by USBC */
01134       ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
01135                    _CMU_CTRL_HFCLKDIV_SHIFT));
01136 #endif
01137     } break;
01138 
01139 #if defined(_CMU_HFPERCLKEN0_USART0_MASK) || \
01140     defined(_CMU_HFPERCLKEN0_USART1_MASK) || \
01141     defined(_CMU_HFPERCLKEN0_USART2_MASK) || \
01142     defined(_CMU_HFPERCLKEN0_UART0_MASK) || \
01143     defined(_CMU_HFPERCLKEN0_UART1_MASK) || \
01144     defined(_CMU_HFPERCLKEN0_TIMER0_MASK) || \
01145     defined(_CMU_HFPERCLKEN0_TIMER1_MASK) || \
01146     defined(_CMU_HFPERCLKEN0_TIMER2_MASK) || \
01147     defined(_CMU_HFPERCLKEN0_TIMER3_MASK) || \
01148     defined(_CMU_HFPERCLKEN0_ACMP0_MASK) || \
01149     defined(_CMU_HFPERCLKEN0_ACMP1_MASK) || \
01150     defined(_CMU_HFPERCLKEN0_DAC0_MASK) || \
01151     defined(_CMU_HFPERCLKEN0_IDAC0_MASK) || \
01152     defined(_CMU_HFPERCLKEN0_ADC0_MASK) || \
01153     defined(_CMU_HFPERCLKEN0_I2C0_MASK) || \
01154     defined(_CMU_HFPERCLKEN0_I2C1_MASK) || \
01155     defined(PRS_PRESENT) || \
01156     defined(VCMP_PRESENT)|| \
01157     defined(GPIO_PRESENT)
01158     case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01159     {
01160       ret   = SystemHFClockGet();
01161 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
01162       /* Leopard/Giant Gecko has an additional divider */
01163       ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
01164                         _CMU_CTRL_HFCLKDIV_SHIFT));
01165 #endif
01166       ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
01167               _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;
01168     } break;
01169 #endif
01170 
01171 #if defined(AES_PRESENT) || \
01172     defined(DMA_PRESENT) || \
01173     defined(EBI_PRESENT) || \
01174     defined(USB_PRESENT)
01175     case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01176     {
01177       ret = SystemCoreClockGet();
01178     } break;
01179 #endif
01180 
01181     case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01182     {
01183       ret = CMU_LFClkGet(CMU_LFA);
01184     } break;
01185 #if defined(_CMU_LFACLKEN0_RTC_MASK)
01186     case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01187     {
01188       ret   = CMU_LFClkGet(CMU_LFA);
01189       ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
01190               _CMU_LFAPRESC0_RTC_SHIFT;
01191     } break;
01192 #endif
01193 #if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
01194     case (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01195     {
01196       ret   = CMU_LFClkGet(CMU_LFA);
01197       ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
01198               _CMU_LFAPRESC0_LETIMER0_SHIFT;
01199     } break;
01200 #endif
01201 #if defined(_CMU_LFACLKEN0_LCD_MASK)
01202     case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01203     {
01204       ret   = CMU_LFClkGet(CMU_LFA);
01205       ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
01206               _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16);
01207     } break;
01208 
01209     case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01210     {
01211       ret   = CMU_LFClkGet(CMU_LFA);
01212       ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
01213               _CMU_LFAPRESC0_LCD_SHIFT;
01214       ret /= (1 + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >>
01215                    _CMU_LCDCTRL_FDIV_SHIFT));
01216     } break;
01217 #endif
01218 #if defined(_CMU_LFACLKEN0_LESENSE_MASK)
01219     case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01220     {
01221       ret   = CMU_LFClkGet(CMU_LFA);
01222       ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
01223               _CMU_LFAPRESC0_LESENSE_SHIFT;
01224     } break;
01225 #endif
01226     case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01227     {
01228       ret = CMU_LFClkGet(CMU_LFB);
01229     } break;
01230 #if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
01231     case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01232     {
01233       ret   = CMU_LFClkGet(CMU_LFB);
01234       ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
01235               _CMU_LFBPRESC0_LEUART0_SHIFT;
01236     } break;
01237 #endif
01238 #if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
01239     case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01240     {
01241       ret   = CMU_LFClkGet(CMU_LFB);
01242       ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
01243         _CMU_LFBPRESC0_LEUART1_SHIFT;
01244     } break;
01245 #endif
01246 
01247     case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01248     {
01249       ret  = CMU_DBGClkGet();
01250     } break;
01251 
01252     case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01253     {
01254       ret  = CMU_AUXClkGet();
01255     } break;
01256 
01257 #if defined(USB_PRESENT)
01258     case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
01259     {
01260       ret = CMU_USBCClkGet();
01261     } break;
01262 #endif
01263     default:
01264     {
01265       EFM_ASSERT(0);
01266       ret = 0;
01267     } break;
01268   }
01269   return ret;
01270 }
01271 
01272 
01273 /**************************************************************************/
01290 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
01291 {
01292   CMU_Select_TypeDef ret = cmuSelect_Disabled;
01293   uint32_t           selReg;
01294   uint32_t           statusClkSelMask;
01295 
01296   statusClkSelMask =
01297     (CMU_STATUS_HFRCOSEL |
01298      CMU_STATUS_HFXOSEL |
01299      CMU_STATUS_LFRCOSEL |
01300 #if defined( CMU_STATUS_USHFRCODIV2SEL )
01301      CMU_STATUS_USHFRCODIV2SEL |
01302 #endif
01303      CMU_STATUS_LFXOSEL);
01304 
01305   selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
01306 
01307   switch (selReg)
01308   {
01309   case CMU_HFCLKSEL_REG:
01310     switch (CMU->STATUS & statusClkSelMask)
01311     {
01312     case CMU_STATUS_LFXOSEL:
01313       ret = cmuSelect_LFXO;
01314       break;
01315 
01316     case CMU_STATUS_LFRCOSEL:
01317       ret = cmuSelect_LFRCO;
01318       break;
01319 
01320     case CMU_STATUS_HFXOSEL:
01321       ret = cmuSelect_HFXO;
01322       break;
01323 
01324 #if defined( CMU_STATUS_USHFRCODIV2SEL )
01325     case CMU_STATUS_USHFRCODIV2SEL:
01326       ret = cmuSelect_USHFRCODIV2;
01327       break;
01328 #endif
01329 
01330     default:
01331       ret = cmuSelect_HFRCO;
01332       break;
01333     }
01334     break;
01335 
01336   case CMU_LFACLKSEL_REG:
01337     switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)
01338     {
01339     case CMU_LFCLKSEL_LFA_LFRCO:
01340       ret = cmuSelect_LFRCO;
01341       break;
01342 
01343     case CMU_LFCLKSEL_LFA_LFXO:
01344       ret = cmuSelect_LFXO;
01345       break;
01346 
01347     case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
01348       ret = cmuSelect_CORELEDIV2;
01349       break;
01350 
01351     default:
01352 #if defined( CMU_LFCLKSEL_LFAE )
01353       if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)
01354       {
01355         ret = cmuSelect_ULFRCO;
01356         break;
01357       }
01358 #else
01359       ret = cmuSelect_Disabled;
01360 #endif
01361       break;
01362     }
01363     break;
01364 
01365   case CMU_LFBCLKSEL_REG:
01366     switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)
01367     {
01368     case CMU_LFCLKSEL_LFB_LFRCO:
01369       ret = cmuSelect_LFRCO;
01370       break;
01371 
01372     case CMU_LFCLKSEL_LFB_LFXO:
01373       ret = cmuSelect_LFXO;
01374       break;
01375 
01376     case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
01377       ret = cmuSelect_CORELEDIV2;
01378       break;
01379 
01380     default:
01381 #if defined( CMU_LFCLKSEL_LFBE )
01382       if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)
01383       {
01384         ret = cmuSelect_ULFRCO;
01385         break;
01386       }
01387 #else
01388       ret = cmuSelect_Disabled;
01389 #endif
01390       break;
01391     }
01392     break;
01393 
01394 #if defined( _CMU_LFCLKSEL_LFC_MASK )
01395   case CMU_LFCCLKSEL_REG:
01396     switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)
01397     {
01398     case CMU_LFCLKSEL_LFC_LFRCO:
01399       ret = cmuSelect_LFRCO;
01400       break;
01401 
01402     case CMU_LFCLKSEL_LFC_LFXO:
01403       ret = cmuSelect_LFXO;
01404       break;
01405 
01406     default:
01407       ret = cmuSelect_Disabled;
01408       break;
01409     }
01410     break;
01411 #endif
01412 
01413   case CMU_DBGCLKSEL_REG:
01414 
01415 #if defined( _CMU_DBGCLKSEL_DBG_MASK )
01416     switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)
01417     {
01418     case CMU_DBGCLKSEL_DBG_HFCLK:
01419       ret = cmuSelect_HFCLK;
01420       break;
01421 
01422     case CMU_DBGCLKSEL_DBG_AUXHFRCO:
01423       ret = cmuSelect_AUXHFRCO;
01424       break;
01425     }
01426 #else
01427     ret = cmuSelect_AUXHFRCO;
01428 #endif /* CMU_DBGCLKSEL_DBG */
01429 
01430 #if defined( _CMU_CTRL_DBGCLK_MASK )
01431     switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)
01432     {
01433     case CMU_CTRL_DBGCLK_AUXHFRCO:
01434       ret = cmuSelect_AUXHFRCO;
01435       break;
01436 
01437     case CMU_CTRL_DBGCLK_HFCLK:
01438       ret = cmuSelect_HFCLK;
01439       break;
01440     }
01441 #else
01442     ret = cmuSelect_AUXHFRCO;
01443 #endif
01444     break;
01445 
01446 
01447 #if defined(USB_PRESENT)
01448 
01449   case CMU_USBCCLKSEL_REG:
01450     switch(CMU->STATUS &
01451            (CMU_STATUS_USBCLFXOSEL |
01452 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
01453             CMU_STATUS_USBCHFCLKSEL |
01454 #endif
01455 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
01456             CMU_STATUS_USBCUSHFRCOSEL |
01457 #endif
01458             CMU_STATUS_USBCLFRCOSEL))
01459     {
01460 
01461     case CMU_STATUS_USBCLFXOSEL:
01462       ret = cmuSelect_LFXO;
01463       break;
01464 
01465     case CMU_STATUS_USBCLFRCOSEL:
01466       ret = cmuSelect_LFRCO;
01467       break;
01468 
01469 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
01470     case CMU_STATUS_USBCHFCLKSEL:
01471       ret = cmuSelect_HFCLK;
01472       break;
01473 #endif
01474 
01475 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
01476     case CMU_STATUS_USBCUSHFRCOSEL:
01477       ret = cmuSelect_USHFRCO;
01478       break;
01479 #endif
01480 
01481     default:
01482       ret = cmuSelect_Disabled;
01483       break;
01484     }
01485     break;
01486 #endif
01487 
01488   default:
01489     EFM_ASSERT(0);
01490     ret = cmuSelect_Error;
01491     break;
01492   }
01493 
01494   return ret;
01495 }
01496 
01497 
01498 /**************************************************************************/
01534 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
01535 {
01536   uint32_t        select = cmuOsc_HFRCO;
01537   CMU_Osc_TypeDef osc    = cmuOsc_HFRCO;
01538   uint32_t        freq;
01539   uint32_t        selReg;
01540 #if !defined(_EFM32_GECKO_FAMILY)
01541   uint32_t        lfExtended = 0;
01542 #endif
01543   uint32_t        tmp;
01544 
01545   selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
01546 
01547   switch (selReg)
01548   {
01549   case CMU_HFCLKSEL_REG:
01550     switch (ref)
01551     {
01552     case cmuSelect_LFXO:
01553       select = CMU_CMD_HFCLKSEL_LFXO;
01554       osc    = cmuOsc_LFXO;
01555       break;
01556 
01557     case cmuSelect_LFRCO:
01558       select = CMU_CMD_HFCLKSEL_LFRCO;
01559       osc    = cmuOsc_LFRCO;
01560       break;
01561 
01562     case cmuSelect_HFXO:
01563       select = CMU_CMD_HFCLKSEL_HFXO;
01564       osc    = cmuOsc_HFXO;
01565 #if defined( CMU_CTRL_HFLE )
01566       /* Adjust HFXO buffer current for high frequencies, enable HFLE for */
01567       /* frequencies above CMU_MAX_FREQ_HFLE. */
01568       if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE)
01569       {
01570         CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
01571           CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ |
01572           /* Must have HFLE enabled to access some LE peripherals >=32MHz */
01573           CMU_CTRL_HFLE;
01574 
01575         /* Set HFLE and DIV4 factor for peripheral clock if HFCORE clock for
01576            LE is enabled. */
01577         if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)
01578         {
01579           BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
01580                              _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
01581         }
01582       } else {
01583         /* This can happen if the user configures the EFM32_HFXO_FREQ to */
01584         /* use another oscillator frequency */
01585         CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
01586           CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;
01587       }
01588 #endif
01589       break;
01590 
01591     case cmuSelect_HFRCO:
01592       select = CMU_CMD_HFCLKSEL_HFRCO;
01593       osc    = cmuOsc_HFRCO;
01594       break;
01595 
01596 #if defined( CMU_CMD_HFCLKSEL_USHFRCODIV2 )
01597     case cmuSelect_USHFRCODIV2:
01598       select = CMU_CMD_HFCLKSEL_USHFRCODIV2;
01599       osc    = cmuOsc_USHFRCO;
01600       break;
01601 #endif
01602 
01603 #if !defined( _EFM32_GECKO_FAMILY )
01604     case cmuSelect_ULFRCO:
01605       /* ULFRCO cannot be used as HFCLK  */
01606       EFM_ASSERT(0);
01607       break;
01608 #endif
01609 
01610     default:
01611       EFM_ASSERT(0);
01612       return;
01613     }
01614 
01615     /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01616     CMU_OscillatorEnable(osc, true, true);
01617 
01618     /* Configure worst case wait states for flash access before selecting */
01619     CMU_FlashWaitStateMax();
01620 
01621     /* Switch to selected oscillator */
01622     CMU->CMD = select;
01623 
01624     /* Keep EMU module informed */
01625     EMU_UpdateOscConfig();
01626 
01627     /* Update CMSIS core clock variable */
01628     /* (The function will update the global variable) */
01629     freq = SystemCoreClockGet();
01630 
01631     /* Optimize flash access wait state setting for currently selected core clk */
01632     CMU_FlashWaitStateControl(freq);
01633     break;
01634 
01635   case CMU_LFACLKSEL_REG:
01636   case CMU_LFBCLKSEL_REG:
01637 
01638     switch (ref)
01639     {
01640     case cmuSelect_Disabled:
01641       tmp = _CMU_LFCLKSEL_LFA_DISABLED;
01642       break;
01643 
01644     case cmuSelect_LFXO:
01645       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01646       CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
01647       tmp = _CMU_LFCLKSEL_LFA_LFXO;
01648       break;
01649 
01650     case cmuSelect_LFRCO:
01651       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01652       CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
01653       tmp = _CMU_LFCLKSEL_LFA_LFRCO;
01654       break;
01655 
01656     case cmuSelect_CORELEDIV2:
01657       /* Ensure HFCORE to LE clocking is enabled */
01658       BITBAND_Peripheral(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);
01659       tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
01660 #if defined( CMU_CTRL_HFLE )
01661       /* If core frequency is higher than CMU_MAX_FREQ_HFLE on
01662          Giant/Leopard/Wonder, enable HFLE and DIV4. */
01663       freq = SystemCoreClockGet();
01664       if(freq > CMU_MAX_FREQ_HFLE)
01665       {
01666         /* Enable CMU HFLE */
01667         BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
01668 
01669         /* Enable DIV4 factor for peripheral clock */
01670         BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
01671                            _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
01672       }
01673 #endif
01674       break;
01675 
01676 #if !defined(_EFM32_GECKO_FAMILY)
01677     case cmuSelect_ULFRCO:
01678       /* ULFRCO is always enabled */
01679       tmp        = _CMU_LFCLKSEL_LFA_DISABLED;
01680       lfExtended = 1;
01681       break;
01682 #endif
01683 
01684     default:
01685       /* Illegal clock source for LFA/LFB selected */
01686       EFM_ASSERT(0);
01687       return;
01688     }
01689 
01690     /* Apply select */
01691     if (selReg == CMU_LFACLKSEL_REG)
01692     {
01693 #if !defined( _EFM32_GECKO_FAMILY )
01694       CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK) ) |
01695                     (tmp << _CMU_LFCLKSEL_LFA_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);
01696 #else
01697       CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK) |
01698                     (tmp << _CMU_LFCLKSEL_LFA_SHIFT);
01699 #endif
01700     }
01701     else
01702     {
01703 #if !defined( _EFM32_GECKO_FAMILY )
01704       CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK) ) |
01705                     (tmp << _CMU_LFCLKSEL_LFB_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);
01706 #else
01707       CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK) |
01708                     (tmp << _CMU_LFCLKSEL_LFB_SHIFT);
01709 #endif
01710     }
01711     break;
01712 
01713 #if defined( _CMU_LFCLKSEL_LFC_MASK )
01714   case CMU_LFCCLKSEL_REG:
01715     switch(ref)
01716     {
01717     case cmuSelect_Disabled:
01718       tmp = _CMU_LFCLKSEL_LFA_DISABLED;
01719       break;
01720 
01721     case cmuSelect_LFXO:
01722       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01723       CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
01724       tmp = _CMU_LFCLKSEL_LFC_LFXO;
01725       break;
01726 
01727     case cmuSelect_LFRCO:
01728       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01729       CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
01730       tmp = _CMU_LFCLKSEL_LFC_LFRCO;
01731       break;
01732 
01733     default:
01734       /* Illegal clock source for LFC selected */
01735       EFM_ASSERT(0);
01736       return;
01737     }
01738 
01739     /* Apply select */
01740     CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK) |
01741                     (tmp << _CMU_LFCLKSEL_LFC_SHIFT);
01742     break;
01743 #endif
01744 
01745 #if defined( CMU_CTRL_DBGCLK )
01746   case CMU_DBGCLKSEL_REG:
01747     switch(ref)
01748     {
01749     case cmuSelect_AUXHFRCO:
01750       /* Select AUXHFRCO as debug clock */
01751       CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_AUXHFRCO;
01752       break;
01753 
01754     case cmuSelect_HFCLK:
01755       /* Select divided HFCLK as debug clock */
01756       CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_HFCLK;
01757       break;
01758 
01759     default:
01760       /* Illegal clock source for debug selected */
01761       EFM_ASSERT(0);
01762       return;
01763     }
01764     break;
01765 #endif
01766 
01767 #if defined(USB_PRESENT)
01768   case CMU_USBCCLKSEL_REG:
01769     switch(ref)
01770     {
01771     case cmuSelect_LFXO:
01772       /* Select LFXO as clock source for USB, can only be used in sleep mode */
01773 
01774       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01775       CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
01776 
01777       /* Switch oscillator */
01778       CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
01779 
01780       /* Wait until clock is activated */
01781       while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0);
01782       break;
01783 
01784     case cmuSelect_LFRCO:
01785       /* Select LFRCO as clock source for USB, can only be used in sleep mode */
01786 
01787       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01788       CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
01789 
01790       /* Switch oscillator */
01791       CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
01792 
01793       /* Wait until clock is activated */
01794       while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0);
01795       break;
01796 
01797 #if defined( CMU_STATUS_USBCHFCLKSEL )
01798     case cmuSelect_HFCLK:
01799       /* Select undivided HFCLK as clock source for USB */
01800 
01801       /* Oscillator must already be enabled to avoid a core lockup */
01802       CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
01803       /* Wait until clock is activated */
01804       while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0);
01805       break;
01806 #endif
01807 
01808 #if defined( CMU_CMD_USBCCLKSEL_USHFRCO )
01809     case cmuSelect_USHFRCO:
01810       /* Select USHFRCO as clock source for USB */
01811 
01812       /* Ensure selected oscillator is enabled, waiting for it to stabilize */
01813       CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);
01814 
01815       /* Switch oscillator */
01816       CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
01817 
01818       /* Wait until clock is activated */
01819       while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0);
01820       break;
01821 #endif
01822 
01823     default:
01824       /* Illegal clock source for USB */
01825       EFM_ASSERT(0);
01826       return;
01827     }
01828     /* Wait until clock has been activated */
01829     break;
01830 #endif
01831 
01832   default:
01833     EFM_ASSERT(0);
01834     break;
01835   }
01836 }
01837 
01838 
01839 /**************************************************************************/
01868 void CMU_FreezeEnable(bool enable)
01869 {
01870   if (enable)
01871   {
01872     /* Wait for any ongoing LF synchronization to complete. This is just to */
01873     /* protect against the rare case when a user                            */
01874     /* - modifies a register requiring LF sync                              */
01875     /* - then enables freeze before LF sync completed                       */
01876     /* - then modifies the same register again                              */
01877     /* since modifying a register while it is in sync progress should be    */
01878     /* avoided.                                                             */
01879     while (CMU->SYNCBUSY)
01880       ;
01881 
01882     CMU->FREEZE = CMU_FREEZE_REGFREEZE;
01883   }
01884   else
01885   {
01886     CMU->FREEZE = 0;
01887   }
01888 }
01889 
01890 
01891 #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
01892 /***************************************************************************/
01899 CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)
01900 {
01901   return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK) >>
01902                                  _CMU_AUXHFRCOCTRL_BAND_SHIFT);
01903 }
01904 
01905 /***************************************************************************/
01913 void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)
01914 {
01915   uint32_t tuning;
01916 
01917   /* Read tuning value from calibration table */
01918   switch (band)
01919   {
01920   case cmuAUXHFRCOBand_1MHz:
01921     tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK) >>
01922              _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;
01923     break;
01924 
01925   case cmuAUXHFRCOBand_7MHz:
01926     tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK) >>
01927              _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;
01928     break;
01929 
01930   case cmuAUXHFRCOBand_11MHz:
01931     tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK) >>
01932              _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;
01933     break;
01934 
01935   case cmuAUXHFRCOBand_14MHz:
01936     tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK) >>
01937              _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;
01938     break;
01939 
01940   case cmuAUXHFRCOBand_21MHz:
01941     tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK) >>
01942              _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;
01943     break;
01944 
01945 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
01946   case cmuAUXHFRCOBand_28MHz:
01947     tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK) >>
01948              _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;
01949     break;
01950 #endif
01951 
01952   default:
01953     EFM_ASSERT(0);
01954     return;
01955   }
01956 
01957   /* Set band/tuning */
01958   CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &
01959                     ~(_CMU_AUXHFRCOCTRL_BAND_MASK | _CMU_AUXHFRCOCTRL_TUNING_MASK)) |
01960                    (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT) |
01961                    (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
01962 
01963 }
01964 #endif
01965 
01966 
01967 #if defined( _CMU_USHFRCOCONF_BAND_MASK )
01968 /***************************************************************************/
01975 CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)
01976 {
01977   return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF & _CMU_USHFRCOCONF_BAND_MASK) >>
01978                                      _CMU_USHFRCOCONF_BAND_SHIFT);
01979 }
01980 
01981 void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)
01982 {
01983   uint32_t           tuning;
01984   uint32_t           fineTuning;
01985   CMU_Select_TypeDef osc;
01986 
01987   /* Cannot switch band if USHFRCO is already selected as HF clock. */
01988   osc = CMU_ClockSelectGet(cmuClock_HF);
01989   EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));
01990 
01991   /* Read tuning value from calibration table */
01992   switch (band)
01993   {
01994   case cmuUSHFRCOBand_24MHz:
01995     tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK) >>
01996          _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;
01997     fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK) >>
01998          _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;
01999     break;
02000 
02001   case cmuUSHFRCOBand_48MHz:
02002     tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK) >>
02003          _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;
02004     fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK) >>
02005          _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;
02006     /* Enable the clock divider before switching the band from 48 to 24MHz */
02007     BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);
02008     break;
02009 
02010   default:
02011     EFM_ASSERT(0);
02012     return;
02013   }
02014 
02015   /* Set band and tuning */
02016   CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK) |
02017                      (band << _CMU_USHFRCOCONF_BAND_SHIFT);
02018   CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK) |
02019                      (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);
02020   CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK) |
02021                      (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);
02022 
02023   /* Disable the clock divider after switching the band from 48 to 24MHz */
02024   if (band == cmuUSHFRCOBand_24MHz)
02025   {
02026     BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);
02027   }
02028 }
02029 #endif
02030 
02031 
02032 /***************************************************************************/
02039 CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)
02040 {
02041   return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) >>
02042                                  _CMU_HFRCOCTRL_BAND_SHIFT);
02043 }
02044 
02045 
02046 /***************************************************************************/
02054 void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)
02055 {
02056   uint32_t           tuning;
02057   uint32_t           freq;
02058   CMU_Select_TypeDef osc;
02059 
02060   /* Read tuning value from calibration table */
02061   switch (band)
02062   {
02063   case cmuHFRCOBand_1MHz:
02064     tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK) >>
02065              _DEVINFO_HFRCOCAL0_BAND1_SHIFT;
02066     break;
02067 
02068   case cmuHFRCOBand_7MHz:
02069     tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK) >>
02070              _DEVINFO_HFRCOCAL0_BAND7_SHIFT;
02071     break;
02072 
02073   case cmuHFRCOBand_11MHz:
02074     tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK) >>
02075              _DEVINFO_HFRCOCAL0_BAND11_SHIFT;
02076     break;
02077 
02078   case cmuHFRCOBand_14MHz:
02079     tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK) >>
02080              _DEVINFO_HFRCOCAL0_BAND14_SHIFT;
02081     break;
02082 
02083   case cmuHFRCOBand_21MHz:
02084     tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK) >>
02085              _DEVINFO_HFRCOCAL1_BAND21_SHIFT;
02086     break;
02087 
02088 #if defined( _CMU_HFRCOCTRL_BAND_28MHZ )
02089   case cmuHFRCOBand_28MHz:
02090     tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK) >>
02091              _DEVINFO_HFRCOCAL1_BAND28_SHIFT;
02092     break;
02093 #endif
02094 
02095   default:
02096     EFM_ASSERT(0);
02097     return;
02098   }
02099 
02100   /* If HFRCO is used for core clock, we have to consider flash access WS. */
02101   osc = CMU_ClockSelectGet(cmuClock_HF);
02102   if (osc == cmuSelect_HFRCO)
02103   {
02104     /* Configure worst case wait states for flash access before setting divider */
02105     CMU_FlashWaitStateMax();
02106   }
02107 
02108   /* Set band/tuning */
02109   CMU->HFRCOCTRL = (CMU->HFRCOCTRL &
02110                     ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK)) |
02111                    (band << _CMU_HFRCOCTRL_BAND_SHIFT) |
02112                    (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);
02113 
02114   /* If HFRCO is used for core clock, optimize flash WS */
02115   if (osc == cmuSelect_HFRCO)
02116   {
02117     /* Update CMSIS core clock variable and get current core clock */
02118     /* (The function will update the global variable) */
02119     /* NOTE! We need at least 21 cycles before setting zero wait state to flash */
02120     /* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */
02121     freq = SystemCoreClockGet();
02122 
02123     /* Optimize flash access wait state setting for current core clk */
02124     CMU_FlashWaitStateControl(freq);
02125   }
02126 }
02127 
02128 
02129 /***************************************************************************/
02139 uint32_t CMU_HFRCOStartupDelayGet(void)
02140 {
02141   return((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK) >>
02142          _CMU_HFRCOCTRL_SUDELAY_SHIFT);
02143 }
02144 
02145 
02146 /***************************************************************************/
02156 void CMU_HFRCOStartupDelaySet(uint32_t delay)
02157 {
02158   EFM_ASSERT(delay <= 31);
02159 
02160   delay         &= (_CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT);
02161   CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK)) |
02162                    (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);
02163 }
02164 
02165 
02166 /***************************************************************************/
02173 uint32_t CMU_LCDClkFDIVGet(void)
02174 {
02175 #if defined(LCD_PRESENT)
02176   return((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT);
02177 #else
02178   return 0;
02179 #endif /* defined(LCD_PRESENT) */
02180 }
02181 
02182 
02183 /***************************************************************************/
02196 void CMU_LCDClkFDIVSet(uint32_t div)
02197 {
02198 #if defined(LCD_PRESENT)
02199   EFM_ASSERT(div <= cmuClkDiv_128);
02200 
02201   /* Do not allow modification if LCD clock enabled */
02202   if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)
02203   {
02204     return;
02205   }
02206 
02207   div        <<= _CMU_LCDCTRL_FDIV_SHIFT;
02208   div         &= _CMU_LCDCTRL_FDIV_MASK;
02209   CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;
02210 #else
02211   (void)div;  /* Unused parameter */
02212 #endif /* defined(LCD_PRESENT) */
02213 }
02214 
02215 
02216 /***************************************************************************/
02240 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
02241 {
02242   uint32_t status;
02243   uint32_t enBit;
02244   uint32_t disBit;
02245 
02246   switch (osc)
02247   {
02248   case cmuOsc_HFRCO:
02249     enBit  = CMU_OSCENCMD_HFRCOEN;
02250     disBit = CMU_OSCENCMD_HFRCODIS;
02251     status = CMU_STATUS_HFRCORDY;
02252     break;
02253 
02254   case cmuOsc_HFXO:
02255     enBit  = CMU_OSCENCMD_HFXOEN;
02256     disBit = CMU_OSCENCMD_HFXODIS;
02257     status = CMU_STATUS_HFXORDY;
02258     break;
02259 
02260   case cmuOsc_AUXHFRCO:
02261     enBit  = CMU_OSCENCMD_AUXHFRCOEN;
02262     disBit = CMU_OSCENCMD_AUXHFRCODIS;
02263     status = CMU_STATUS_AUXHFRCORDY;
02264     break;
02265 
02266   case cmuOsc_LFRCO:
02267     enBit  = CMU_OSCENCMD_LFRCOEN;
02268     disBit = CMU_OSCENCMD_LFRCODIS;
02269     status = CMU_STATUS_LFRCORDY;
02270     break;
02271 
02272   case cmuOsc_LFXO:
02273     enBit  = CMU_OSCENCMD_LFXOEN;
02274     disBit = CMU_OSCENCMD_LFXODIS;
02275     status = CMU_STATUS_LFXORDY;
02276     break;
02277 
02278 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
02279   case cmuOsc_USHFRCO:
02280     enBit  = CMU_OSCENCMD_USHFRCOEN;
02281     disBit = CMU_OSCENCMD_USHFRCODIS;
02282     status = CMU_STATUS_USHFRCORDY;
02283     break;
02284 #endif
02285 
02286 #if defined( _CMU_LFCLKSEL_LFAE_ULFRCO )
02287   case cmuOsc_ULFRCO:
02288     /* ULFRCO is always enabled, and cannot be turned off */
02289     return;
02290 #endif
02291 
02292   default:
02293     /* Undefined clock source */
02294     EFM_ASSERT(0);
02295     return;
02296   }
02297 
02298   if (enable)
02299   {
02300     CMU->OSCENCMD = enBit;
02301 
02302     /* Wait for clock to stabilize if requested */
02303     if (wait)
02304     {
02305       while (!(CMU->STATUS & status))
02306         ;
02307     }
02308   }
02309   else
02310   {
02311     CMU->OSCENCMD = disBit;
02312   }
02313 
02314   /* Keep EMU module informed */
02315   EMU_UpdateOscConfig();
02316 }
02317 
02318 
02319 /***************************************************************************/
02332 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
02333 {
02334   uint32_t ret;
02335 
02336   switch (osc)
02337   {
02338   case cmuOsc_LFRCO:
02339     ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK) >>
02340           _CMU_LFRCOCTRL_TUNING_SHIFT;
02341     break;
02342 
02343   case cmuOsc_HFRCO:
02344     ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK) >>
02345           _CMU_HFRCOCTRL_TUNING_SHIFT;
02346     break;
02347 
02348   case cmuOsc_AUXHFRCO:
02349     ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK) >>
02350           _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
02351     break;
02352 
02353   default:
02354     EFM_ASSERT(0);
02355     ret = 0;
02356     break;
02357   }
02358 
02359   return(ret);
02360 }
02361 
02362 
02363 /***************************************************************************/
02381 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
02382 {
02383   switch (osc)
02384   {
02385   case cmuOsc_LFRCO:
02386     EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT));
02387 
02388     val           &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);
02389     CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK)) |
02390                      (val << _CMU_LFRCOCTRL_TUNING_SHIFT);
02391     break;
02392 
02393   case cmuOsc_HFRCO:
02394     EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT));
02395 
02396     val           &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);
02397     CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK)) |
02398                      (val << _CMU_HFRCOCTRL_TUNING_SHIFT);
02399     break;
02400 
02401   case cmuOsc_AUXHFRCO:
02402     EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));
02403 
02404     val             <<= _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
02405     val              &= _CMU_AUXHFRCOCTRL_TUNING_MASK;
02406     CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK)) | val;
02407     break;
02408 
02409   default:
02410     EFM_ASSERT(0);
02411     break;
02412   }
02413 }
02414 
02415 
02416 /**************************************************************************/
02427 bool CMU_PCNTClockExternalGet(unsigned int inst)
02428 {
02429   bool     ret;
02430   uint32_t setting;
02431 
02432   switch (inst)
02433   {
02434 #if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
02435   case 0:
02436     setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;
02437     break;
02438 
02439 #if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
02440   case 1:
02441     setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;
02442     break;
02443 
02444 #if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
02445   case 2:
02446     setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;
02447     break;
02448 #endif
02449 #endif
02450 #endif
02451 
02452   default:
02453     setting = 0;
02454     break;
02455   }
02456 
02457   if (setting)
02458   {
02459     ret = true;
02460   }
02461   else
02462   {
02463     ret = false;
02464   }
02465   return ret;
02466 }
02467 
02468 
02469 /**************************************************************************/
02479 void CMU_PCNTClockExternalSet(unsigned int inst, bool external)
02480 {
02481 #if defined(PCNT_PRESENT)
02482   uint32_t setting = 0;
02483 
02484   EFM_ASSERT(inst < PCNT_COUNT);
02485 
02486   if (external)
02487   {
02488     setting = 1;
02489   }
02490 
02491   BITBAND_Peripheral(&(CMU->PCNTCTRL), (inst * 2) + 1, setting);
02492 
02493 #else
02494   (void)inst;      /* Unused parameter */
02495   (void)external;  /* Unused parameter */
02496 #endif
02497 }
02498 
02499 
02502 #endif /* __EM_CMU_H */