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 #ifdef _EFM32_GIANT_FAMILY 00058 #define EFM32_HFXO_FREQ (48000000UL) 00059 #else 00060 #define EFM32_HFXO_FREQ (32000000UL) 00061 #endif 00062 #endif 00063 /* Do not define variable if HF crystal oscillator not present */ 00064 #if (EFM32_HFXO_FREQ > 0) 00065 00067 static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ; 00069 #endif 00070 00071 #ifndef EFM32_LFXO_FREQ 00072 #define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ) 00073 #endif 00074 /* Do not define variable if LF crystal oscillator not present */ 00075 #if (EFM32_LFXO_FREQ > 0) 00076 00078 static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ; 00080 #endif 00081 00082 /* Inline function to get the chip's Production Revision. */ 00083 __STATIC_INLINE uint8_t GetProdRev(void) 00084 { 00085 return ((DEVINFO->PART & _DEVINFO_PART_PROD_REV_MASK) 00086 >> _DEVINFO_PART_PROD_REV_SHIFT); 00087 } 00088 00089 /******************************************************************************* 00090 ************************** GLOBAL VARIABLES ******************************* 00091 ******************************************************************************/ 00092 00100 uint32_t SystemCoreClock; 00101 00102 /******************************************************************************* 00103 ************************** GLOBAL FUNCTIONS ******************************* 00104 ******************************************************************************/ 00105 00106 /***************************************************************************/ 00123 uint32_t SystemCoreClockGet(void) 00124 { 00125 uint32_t ret; 00126 00127 ret = SystemHFClockGet(); 00128 #if defined (_EFM32_GIANT_FAMILY) 00129 /* Leopard/Giant Gecko has an additional divider */ 00130 ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)>>_CMU_CTRL_HFCLKDIV_SHIFT)); 00131 #endif 00132 ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >> 00133 _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT; 00134 00135 /* Keep CMSIS variable up-to-date just in case */ 00136 SystemCoreClock = ret; 00137 00138 return ret; 00139 } 00140 00141 00142 /***************************************************************************/ 00152 uint32_t SystemHFClockGet(void) 00153 { 00154 uint32_t ret; 00155 00156 switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL | 00157 CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL)) 00158 { 00159 case CMU_STATUS_LFXOSEL: 00160 #if (EFM32_LFXO_FREQ > 0) 00161 ret = SystemLFXOClock; 00162 #else 00163 /* We should not get here, since core should not be clocked. May */ 00164 /* be caused by a misconfiguration though. */ 00165 ret = 0; 00166 #endif 00167 break; 00168 00169 case CMU_STATUS_LFRCOSEL: 00170 ret = EFM32_LFRCO_FREQ; 00171 break; 00172 00173 case CMU_STATUS_HFXOSEL: 00174 #if (EFM32_HFXO_FREQ > 0) 00175 ret = SystemHFXOClock; 00176 #else 00177 /* We should not get here, since core should not be clocked. May */ 00178 /* be caused by a misconfiguration though. */ 00179 ret = 0; 00180 #endif 00181 break; 00182 00183 default: /* CMU_STATUS_HFRCOSEL */ 00184 switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) 00185 { 00186 case CMU_HFRCOCTRL_BAND_28MHZ: 00187 ret = 28000000; 00188 break; 00189 00190 case CMU_HFRCOCTRL_BAND_21MHZ: 00191 ret = 21000000; 00192 break; 00193 00194 case CMU_HFRCOCTRL_BAND_14MHZ: 00195 ret = 14000000; 00196 break; 00197 00198 case CMU_HFRCOCTRL_BAND_11MHZ: 00199 ret = 11000000; 00200 break; 00201 00202 case CMU_HFRCOCTRL_BAND_7MHZ: 00203 if ( GetProdRev() >= 19 ) 00204 ret = 6600000; 00205 else 00206 ret = 7000000; 00207 break; 00208 00209 case CMU_HFRCOCTRL_BAND_1MHZ: 00210 if ( GetProdRev() >= 19 ) 00211 ret = 1200000; 00212 else 00213 ret = 1000000; 00214 break; 00215 00216 default: 00217 ret = 0; 00218 break; 00219 } 00220 break; 00221 } 00222 00223 return ret; 00224 } 00225 00226 00227 /**************************************************************************/ 00237 uint32_t SystemHFXOClockGet(void) 00238 { 00239 /* External crystal oscillator present? */ 00240 #if (EFM32_HFXO_FREQ > 0) 00241 return SystemHFXOClock; 00242 #else 00243 return 0; 00244 #endif 00245 } 00246 00247 00248 /**************************************************************************/ 00263 void SystemHFXOClockSet(uint32_t freq) 00264 { 00265 /* External crystal oscillator present? */ 00266 #if (EFM32_HFXO_FREQ > 0) 00267 SystemHFXOClock = freq; 00268 00269 /* Update core clock frequency if HFXO is used to clock core */ 00270 if (CMU->STATUS & CMU_STATUS_HFXOSEL) 00271 { 00272 /* The function will update the global variable */ 00273 SystemCoreClockGet(); 00274 } 00275 #else 00276 (void)freq; /* Unused parameter */ 00277 #endif 00278 } 00279 00280 00281 /**************************************************************************/ 00293 void SystemInit(void) 00294 { 00295 } 00296 00297 00298 /**************************************************************************/ 00308 uint32_t SystemLFRCOClockGet(void) 00309 { 00310 /* Currently we assume that this frequency is properly tuned during */ 00311 /* manufacturing and is not changed after reset. If future requirements */ 00312 /* for re-tuning by user, we can add support for that. */ 00313 return EFM32_LFRCO_FREQ; 00314 } 00315 00316 00317 /**************************************************************************/ 00327 uint32_t SystemULFRCOClockGet(void) 00328 { 00329 /* The ULFRCO frequency is not tuned, and can be very inaccurate */ 00330 return EFM32_ULFRCO_FREQ; 00331 } 00332 00333 00334 /**************************************************************************/ 00344 uint32_t SystemLFXOClockGet(void) 00345 { 00346 /* External crystal oscillator present? */ 00347 #if (EFM32_LFXO_FREQ > 0) 00348 return SystemLFXOClock; 00349 #else 00350 return 0; 00351 #endif 00352 } 00353 00354 00355 /**************************************************************************/ 00370 void SystemLFXOClockSet(uint32_t freq) 00371 { 00372 /* External crystal oscillator present? */ 00373 #if (EFM32_LFXO_FREQ > 0) 00374 SystemLFXOClock = freq; 00375 00376 /* Update core clock frequency if LFXO is used to clock core */ 00377 if (CMU->STATUS & CMU_STATUS_LFXOSEL) 00378 { 00379 /* The function will update the global variable */ 00380 SystemCoreClockGet(); 00381 } 00382 #else 00383 (void)freq; /* Unused parameter */ 00384 #endif 00385 }