release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32ZG/Source/system_efm32zg.c

Go to the documentation of this file.
00001 /***************************************************************************/
00033 #include <stdint.h>
00034 #include "em_device.h"
00035 
00036 /*******************************************************************************
00037  ******************************   DEFINES   ************************************
00038  ******************************************************************************/
00039 
00041 #define EFM32_LFRCO_FREQ  (32768UL)
00042 #define EFM32_ULFRCO_FREQ (1000UL)
00043 
00044 /*******************************************************************************
00045  **************************   LOCAL VARIABLES   ********************************
00046  ******************************************************************************/
00047 
00048 /* System oscillator frequencies. These frequencies are normally constant */
00049 /* for a target, but they are made configurable in order to allow run-time */
00050 /* handling of different boards. The crystal oscillator clocks can be set */
00051 /* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
00052 /* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
00053 /* one indicates that the oscillator is not present, in order to save some */
00054 /* SW footprint. */
00055 
00056 #ifndef EFM32_HFXO_FREQ
00057 #define EFM32_HFXO_FREQ (24000000UL)
00058 #endif
00059 /* Do not define variable if HF crystal oscillator not present */
00060 #if (EFM32_HFXO_FREQ > 0)
00061 
00063 static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
00065 #endif
00066 
00067 #ifndef EFM32_LFXO_FREQ
00068 #define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
00069 #endif
00070 /* Do not define variable if LF crystal oscillator not present */
00071 #if (EFM32_LFXO_FREQ > 0)
00072 
00074 static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
00076 #endif
00077 
00078 /*******************************************************************************
00079  **************************   GLOBAL VARIABLES   *******************************
00080  ******************************************************************************/
00081 
00089 uint32_t SystemCoreClock;
00090 
00091 /*******************************************************************************
00092  **************************   GLOBAL FUNCTIONS   *******************************
00093  ******************************************************************************/
00094 
00095 /***************************************************************************/
00112 uint32_t SystemCoreClockGet(void)
00113 {
00114   uint32_t ret;
00115   
00116   ret = SystemHFClockGet();
00117   ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
00118           _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
00119 
00120   /* Keep CMSIS variable up-to-date just in case */
00121   SystemCoreClock = ret;
00122 
00123   return ret;
00124 }
00125 
00126 
00127 /***************************************************************************/
00137 uint32_t SystemHFClockGet(void)
00138 {
00139   uint32_t ret;
00140   
00141   switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
00142                          CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
00143   {
00144     case CMU_STATUS_LFXOSEL:
00145 #if (EFM32_LFXO_FREQ > 0)
00146       ret = SystemLFXOClock;
00147 #else
00148       /* We should not get here, since core should not be clocked. May */
00149       /* be caused by a misconfiguration though. */
00150       ret = 0;
00151 #endif
00152       break;
00153       
00154     case CMU_STATUS_LFRCOSEL:
00155       ret = EFM32_LFRCO_FREQ;
00156       break;
00157       
00158     case CMU_STATUS_HFXOSEL:
00159 #if (EFM32_HFXO_FREQ > 0)
00160       ret = SystemHFXOClock;
00161 #else
00162       /* We should not get here, since core should not be clocked. May */
00163       /* be caused by a misconfiguration though. */
00164       ret = 0;
00165 #endif
00166       break;
00167       
00168     default: /* CMU_STATUS_HFRCOSEL */
00169       switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
00170       {
00171       case CMU_HFRCOCTRL_BAND_21MHZ:
00172         ret = 21000000;
00173         break;
00174 
00175       case CMU_HFRCOCTRL_BAND_14MHZ:
00176         ret = 14000000;
00177         break;
00178 
00179       case CMU_HFRCOCTRL_BAND_11MHZ:
00180         ret = 11000000;
00181         break;
00182 
00183       case CMU_HFRCOCTRL_BAND_7MHZ:
00184         ret = 6600000;
00185         break;
00186 
00187       case CMU_HFRCOCTRL_BAND_1MHZ:
00188         ret = 1200000;
00189         break;
00190 
00191       default:
00192         ret = 0;
00193         break;
00194       }
00195       break;
00196   }
00197 
00198   return ret;
00199 }
00200 
00201 
00202 /**************************************************************************/
00212 uint32_t SystemHFXOClockGet(void)
00213 {
00214   /* External crystal oscillator present? */
00215 #if (EFM32_HFXO_FREQ > 0)
00216   return SystemHFXOClock;
00217 #else
00218   return 0;
00219 #endif
00220 }
00221 
00222 
00223 /**************************************************************************/
00238 void SystemHFXOClockSet(uint32_t freq)
00239 {
00240   /* External crystal oscillator present? */
00241 #if (EFM32_HFXO_FREQ > 0)
00242   SystemHFXOClock = freq;
00243 
00244   /* Update core clock frequency if HFXO is used to clock core */
00245   if (CMU->STATUS & CMU_STATUS_HFXOSEL)
00246   {
00247     /* The function will update the global variable */
00248     SystemCoreClockGet();
00249   }
00250 #else
00251   (void)freq; /* Unused parameter */
00252 #endif
00253 }
00254 
00255 
00256 /**************************************************************************/
00268 void SystemInit(void)
00269 {
00270 }
00271 
00272 
00273 /**************************************************************************/
00283 uint32_t SystemLFRCOClockGet(void)
00284 {
00285   /* Currently we assume that this frequency is properly tuned during */
00286   /* manufacturing and is not changed after reset. If future requirements */
00287   /* for re-tuning by user, we can add support for that. */
00288   return EFM32_LFRCO_FREQ;
00289 }
00290 
00291 
00292 /**************************************************************************/
00302 uint32_t SystemULFRCOClockGet(void)
00303 {
00304   /* The ULFRCO frequency is not tuned, and can be very inaccurate */
00305   return EFM32_ULFRCO_FREQ;
00306 }
00307 
00308 
00309 /**************************************************************************/
00319 uint32_t SystemLFXOClockGet(void)
00320 {
00321   /* External crystal oscillator present? */
00322 #if (EFM32_LFXO_FREQ > 0)
00323   return SystemLFXOClock;
00324 #else
00325   return 0;
00326 #endif
00327 }
00328 
00329 
00330 /**************************************************************************/
00345 void SystemLFXOClockSet(uint32_t freq)
00346 {
00347   /* External crystal oscillator present? */
00348 #if (EFM32_LFXO_FREQ > 0)
00349   SystemLFXOClock = freq;
00350 
00351   /* Update core clock frequency if LFXO is used to clock core */
00352   if (CMU->STATUS & CMU_STATUS_LFXOSEL)
00353   {
00354     /* The function will update the global variable */
00355     SystemCoreClockGet();
00356   }
00357 #else
00358   (void)freq; /* Unused parameter */
00359 #endif
00360 }