EFM32 Happy Gecko Software Documentation  efm32hg-doc-5.1.2
system_efm32hg.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include <stdint.h>
34 #include "em_device.h"
35 
36 /*******************************************************************************
37  ****************************** DEFINES ************************************
38  ******************************************************************************/
39 
41 #define EFM32_LFRCO_FREQ (32768UL)
42 #define EFM32_ULFRCO_FREQ (1000UL)
43 
44 /*******************************************************************************
45  ************************** LOCAL VARIABLES ********************************
46  ******************************************************************************/
47 
48 /* System oscillator frequencies. These frequencies are normally constant */
49 /* for a target, but they are made configurable in order to allow run-time */
50 /* handling of different boards. The crystal oscillator clocks can be set */
51 /* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
52 /* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
53 /* one indicates that the oscillator is not present, in order to save some */
54 /* SW footprint. */
55 
56 #ifndef EFM32_HFXO_FREQ
57 #define EFM32_HFXO_FREQ (24000000UL)
58 #endif
59 
60 #define EFM32_HFRCO_MAX_FREQ (21000000UL)
61 
62 /* Do not define variable if HF crystal oscillator not present */
63 #if (EFM32_HFXO_FREQ > 0)
64 
66 static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
68 #endif
69 
70 #ifndef EFM32_LFXO_FREQ
71 #define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
72 #endif
73 
74 /* Do not define variable if LF crystal oscillator not present */
75 #if (EFM32_LFXO_FREQ > 0)
76 
78 static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
80 #endif
81 
82 /*******************************************************************************
83  ************************** GLOBAL VARIABLES *******************************
84  ******************************************************************************/
85 
93 uint32_t SystemCoreClock;
94 
95 /*******************************************************************************
96  ************************** GLOBAL FUNCTIONS *******************************
97  ******************************************************************************/
98 
99 /***************************************************************************/
116 uint32_t SystemCoreClockGet(void)
117 {
118  uint32_t ret;
119 
120  ret = SystemHFClockGet();
121  ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
123 
124  /* Keep CMSIS variable up-to-date just in case */
125  SystemCoreClock = ret;
126 
127  return ret;
128 }
129 
130 
131 /***************************************************************************/
141 uint32_t SystemMaxCoreClockGet(void)
142 {
143  return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
144  EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
145 }
146 
147 
148 /***************************************************************************/
158 uint32_t SystemHFClockGet(void)
159 {
160  uint32_t ret;
161 
162  switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL
164 #if defined(CMU_STATUS_USHFRCODIV2SEL)
166 #endif
167  ))
168  {
169  case CMU_STATUS_LFXOSEL:
170 #if (EFM32_LFXO_FREQ > 0)
171  ret = SystemLFXOClock;
172 #else
173  /* We should not get here, since core should not be clocked. May */
174  /* be caused by a misconfiguration though. */
175  ret = 0;
176 #endif
177  break;
178 
179  case CMU_STATUS_LFRCOSEL:
180  ret = EFM32_LFRCO_FREQ;
181  break;
182 
183  case CMU_STATUS_HFXOSEL:
184 #if (EFM32_HFXO_FREQ > 0)
185  ret = SystemHFXOClock;
186 #else
187  /* We should not get here, since core should not be clocked. May */
188  /* be caused by a misconfiguration though. */
189  ret = 0;
190 #endif
191  break;
192 
193 #if defined(CMU_STATUS_USHFRCODIV2SEL)
195  ret = 24000000;
196  break;
197 #endif
198 
199  default: /* CMU_STATUS_HFRCOSEL */
200  switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
201  {
203  ret = 21000000;
204  break;
205 
207  ret = 14000000;
208  break;
209 
211  ret = 11000000;
212  break;
213 
215  ret = 6600000;
216  break;
217 
219  ret = 1200000;
220  break;
221 
222  default:
223  ret = 0;
224  break;
225  }
226  break;
227  }
228 
229  return ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)
231 }
232 
233 
234 /**************************************************************************/
244 uint32_t SystemHFXOClockGet(void)
245 {
246  /* External crystal oscillator present? */
247 #if (EFM32_HFXO_FREQ > 0)
248  return SystemHFXOClock;
249 #else
250  return 0;
251 #endif
252 }
253 
254 
255 /**************************************************************************/
270 void SystemHFXOClockSet(uint32_t freq)
271 {
272  /* External crystal oscillator present? */
273 #if (EFM32_HFXO_FREQ > 0)
274  SystemHFXOClock = freq;
275 
276  /* Update core clock frequency if HFXO is used to clock core */
277  if (CMU->STATUS & CMU_STATUS_HFXOSEL)
278  {
279  /* The function will update the global variable */
281  }
282 #else
283  (void)freq; /* Unused parameter */
284 #endif
285 }
286 
287 
288 /**************************************************************************/
300 void SystemInit(void)
301 {
302 }
303 
304 
305 /**************************************************************************/
315 uint32_t SystemLFRCOClockGet(void)
316 {
317  /* Currently we assume that this frequency is properly tuned during */
318  /* manufacturing and is not changed after reset. If future requirements */
319  /* for re-tuning by user, we can add support for that. */
320  return EFM32_LFRCO_FREQ;
321 }
322 
323 
324 /**************************************************************************/
334 uint32_t SystemULFRCOClockGet(void)
335 {
336  /* The ULFRCO frequency is not tuned, and can be very inaccurate */
337  return EFM32_ULFRCO_FREQ;
338 }
339 
340 
341 /**************************************************************************/
351 uint32_t SystemLFXOClockGet(void)
352 {
353  /* External crystal oscillator present? */
354 #if (EFM32_LFXO_FREQ > 0)
355  return SystemLFXOClock;
356 #else
357  return 0;
358 #endif
359 }
360 
361 
362 /**************************************************************************/
377 void SystemLFXOClockSet(uint32_t freq)
378 {
379  /* External crystal oscillator present? */
380 #if (EFM32_LFXO_FREQ > 0)
381  SystemLFXOClock = freq;
382 
383  /* Update core clock frequency if LFXO is used to clock core */
384  if (CMU->STATUS & CMU_STATUS_LFXOSEL)
385  {
386  /* The function will update the global variable */
388  }
389 #else
390  (void)freq; /* Unused parameter */
391 #endif
392 }
#define _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT
Definition: efm32hg_cmu.h:222
uint32_t SystemCoreClockGet(void)
Get the current core clock frequency.
void SystemLFXOClockSet(uint32_t freq)
Set low frequency crystal oscillator clock frequency for target system.
#define CMU_HFRCOCTRL_BAND_11MHZ
Definition: efm32hg_cmu.h:306
#define EFM32_LFXO_FREQ
#define CMU_HFRCOCTRL_BAND_1MHZ
Definition: efm32hg_cmu.h:304
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define CMU_STATUS_LFXOSEL
Definition: efm32hg_cmu.h:622
#define CMU_STATUS_USHFRCODIV2SEL
Definition: efm32hg_cmu.h:667
#define _CMU_CTRL_HFCLKDIV_SHIFT
Definition: efm32hg_cmu.h:155
#define _CMU_HFRCOCTRL_BAND_MASK
Definition: efm32hg_cmu.h:297
#define CMU_STATUS_HFXOSEL
Definition: efm32hg_cmu.h:612
#define CMU_HFRCOCTRL_BAND_7MHZ
Definition: efm32hg_cmu.h:305
uint32_t SystemLFXOClockGet(void)
Get low frequency crystal oscillator clock frequency for target system.
uint32_t SystemHFClockGet(void)
Get the current HFCLK frequency.
uint32_t SystemHFXOClockGet(void)
Get high frequency crystal oscillator clock frequency for target system.
#define _CMU_CTRL_HFCLKDIV_MASK
Definition: efm32hg_cmu.h:156
#define CMU_STATUS_LFRCOSEL
Definition: efm32hg_cmu.h:617
uint32_t SystemULFRCOClockGet(void)
Get ultra low frequency RC oscillator clock frequency for target system.
#define EFM32_LFRCO_FREQ
void SystemHFXOClockSet(uint32_t freq)
Set high frequency crystal oscillator clock frequency for target system.
uint32_t SystemMaxCoreClockGet(void)
Get the maximum core clock frequency.
uint32_t SystemLFRCOClockGet(void)
Get low frequency RC oscillator clock frequency for target system.
#define _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK
Definition: efm32hg_cmu.h:223
uint32_t SystemCoreClock
System System Clock Frequency (Core Clock).
#define CMU_HFRCOCTRL_BAND_21MHZ
Definition: efm32hg_cmu.h:309
void SystemInit(void)
Initialize the system.
#define CMU_STATUS_HFRCOSEL
Definition: efm32hg_cmu.h:607
#define CMU_HFRCOCTRL_BAND_14MHZ
Definition: efm32hg_cmu.h:308
#define CMU