release/EM_CMSIS_P1_4.0.0/Device/SiliconLabs/EFM32HG/Source/system_efm32hg.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 #define EFM32_HFRCO_MAX_FREQ    (21000000UL)
00059 #endif
00060 /* Do not define variable if HF crystal oscillator not present */
00061 #if (EFM32_HFXO_FREQ > 0)
00062 
00064 static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
00066 #endif
00067 
00068 #ifndef EFM32_LFXO_FREQ
00069 #define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
00070 #endif
00071 /* Do not define variable if LF crystal oscillator not present */
00072 #if (EFM32_LFXO_FREQ > 0)
00073 
00075 static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
00077 #endif
00078 
00079 /*******************************************************************************
00080  **************************   GLOBAL VARIABLES   *******************************
00081  ******************************************************************************/
00082 
00090 uint32_t SystemCoreClock;
00091 
00092 /*******************************************************************************
00093  **************************   GLOBAL FUNCTIONS   *******************************
00094  ******************************************************************************/
00095 
00096 /***************************************************************************/
00113 uint32_t SystemCoreClockGet(void)
00114 {
00115   uint32_t ret;
00116 
00117   ret = SystemHFClockGet();
00118   ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
00119           _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
00120 
00121   /* Keep CMSIS variable up-to-date just in case */
00122   SystemCoreClock = ret;
00123 
00124   return ret;
00125 }
00126 
00127 
00128 /***************************************************************************/
00138 uint32_t SystemMaxCoreClockGet(void)
00139 {
00140   return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
00141           EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
00142 }
00143 
00144 
00145 /***************************************************************************/
00155 uint32_t SystemHFClockGet(void)
00156 {
00157   uint32_t ret;
00158 
00159   switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL
00160                          | CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL
00161 #if defined(CMU_STATUS_USHFRCODIV2SEL)
00162                          | CMU_STATUS_USHFRCODIV2SEL
00163 #endif
00164                         ))
00165   {
00166     case CMU_STATUS_LFXOSEL:
00167 #if (EFM32_LFXO_FREQ > 0)
00168       ret = SystemLFXOClock;
00169 #else
00170       /* We should not get here, since core should not be clocked. May */
00171       /* be caused by a misconfiguration though. */
00172       ret = 0;
00173 #endif
00174       break;
00175 
00176     case CMU_STATUS_LFRCOSEL:
00177       ret = EFM32_LFRCO_FREQ;
00178       break;
00179 
00180     case CMU_STATUS_HFXOSEL:
00181 #if (EFM32_HFXO_FREQ > 0)
00182       ret = SystemHFXOClock;
00183 #else
00184       /* We should not get here, since core should not be clocked. May */
00185       /* be caused by a misconfiguration though. */
00186       ret = 0;
00187 #endif
00188       break;
00189 
00190 #if defined(CMU_STATUS_USHFRCODIV2SEL)
00191     case CMU_STATUS_USHFRCODIV2SEL:
00192       ret = 24000000;
00193       break;
00194 #endif
00195 
00196     default: /* CMU_STATUS_HFRCOSEL */
00197       switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
00198       {
00199       case CMU_HFRCOCTRL_BAND_21MHZ:
00200         ret = 21000000;
00201         break;
00202 
00203       case CMU_HFRCOCTRL_BAND_14MHZ:
00204         ret = 14000000;
00205         break;
00206 
00207       case CMU_HFRCOCTRL_BAND_11MHZ:
00208         ret = 11000000;
00209         break;
00210 
00211       case CMU_HFRCOCTRL_BAND_7MHZ:
00212         ret = 6600000;
00213         break;
00214 
00215       case CMU_HFRCOCTRL_BAND_1MHZ:
00216         ret = 1200000;
00217         break;
00218 
00219       default:
00220         ret = 0;
00221         break;
00222       }
00223       break;
00224   }
00225 
00226   return ret;
00227 }
00228 
00229 
00230 /**************************************************************************/
00240 uint32_t SystemHFXOClockGet(void)
00241 {
00242   /* External crystal oscillator present? */
00243 #if (EFM32_HFXO_FREQ > 0)
00244   return SystemHFXOClock;
00245 #else
00246   return 0;
00247 #endif
00248 }
00249 
00250 
00251 /**************************************************************************/
00266 void SystemHFXOClockSet(uint32_t freq)
00267 {
00268   /* External crystal oscillator present? */
00269 #if (EFM32_HFXO_FREQ > 0)
00270   SystemHFXOClock = freq;
00271 
00272   /* Update core clock frequency if HFXO is used to clock core */
00273   if (CMU->STATUS & CMU_STATUS_HFXOSEL)
00274   {
00275     /* The function will update the global variable */
00276     SystemCoreClockGet();
00277   }
00278 #else
00279   (void)freq; /* Unused parameter */
00280 #endif
00281 }
00282 
00283 
00284 /**************************************************************************/
00296 void SystemInit(void)
00297 {
00298 }
00299 
00300 
00301 /**************************************************************************/
00311 uint32_t SystemLFRCOClockGet(void)
00312 {
00313   /* Currently we assume that this frequency is properly tuned during */
00314   /* manufacturing and is not changed after reset. If future requirements */
00315   /* for re-tuning by user, we can add support for that. */
00316   return EFM32_LFRCO_FREQ;
00317 }
00318 
00319 
00320 /**************************************************************************/
00330 uint32_t SystemULFRCOClockGet(void)
00331 {
00332   /* The ULFRCO frequency is not tuned, and can be very inaccurate */
00333   return EFM32_ULFRCO_FREQ;
00334 }
00335 
00336 
00337 /**************************************************************************/
00347 uint32_t SystemLFXOClockGet(void)
00348 {
00349   /* External crystal oscillator present? */
00350 #if (EFM32_LFXO_FREQ > 0)
00351   return SystemLFXOClock;
00352 #else
00353   return 0;
00354 #endif
00355 }
00356 
00357 
00358 /**************************************************************************/
00373 void SystemLFXOClockSet(uint32_t freq)
00374 {
00375   /* External crystal oscillator present? */
00376 #if (EFM32_LFXO_FREQ > 0)
00377   SystemLFXOClock = freq;
00378 
00379   /* Update core clock frequency if LFXO is used to clock core */
00380   if (CMU->STATUS & CMU_STATUS_LFXOSEL)
00381   {
00382     /* The function will update the global variable */
00383     SystemCoreClockGet();
00384   }
00385 #else
00386   (void)freq; /* Unused parameter */
00387 #endif
00388 }