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 }