EFM32 Pearl Gecko Software Documentation  efm32pg1-doc-4.2.1
system_efm32pg1b.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 EFM_nFXO_FREQ */
52 /* values according to board design. By defining the EFM_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_HFRCO_MAX_FREQ
57 #define EFM32_HFRCO_MAX_FREQ (38000000UL)
58 #endif
59 
60 #ifndef EFM32_HFXO_FREQ
61 #define EFM32_HFXO_FREQ (40000000UL)
62 #endif
63 
64 #ifndef EFM32_HFRCO_STARTUP_FREQ
65 #define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
66 #endif
67 
68 
69 /* Do not define variable if HF crystal oscillator not present */
70 #if (EFM32_HFXO_FREQ > 0UL)
71 
73 static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
75 #endif
76 
77 #ifndef EFM32_LFXO_FREQ
78 #define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
79 #endif
80 /* Do not define variable if LF crystal oscillator not present */
81 #if (EFM32_LFXO_FREQ > 0UL)
82 
84 static uint32_t SystemLFXOClock = 32768UL;
86 #endif
87 
88 
89 /*******************************************************************************
90  ************************** GLOBAL VARIABLES *******************************
91  ******************************************************************************/
92 
101 
102 
113 uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
114 
115 
116 /*******************************************************************************
117  ************************** GLOBAL FUNCTIONS *******************************
118  ******************************************************************************/
119 
120 /***************************************************************************/
137 uint32_t SystemCoreClockGet(void)
138 {
139  uint32_t ret;
140  uint32_t presc;
141 
142  ret = SystemHFClockGet();
143  presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
145  ret /= (presc + 1);
146 
147  /* Keep CMSIS system clock variable up-to-date */
148  SystemCoreClock = ret;
149 
150  return ret;
151 }
152 
153 
154 /***************************************************************************/
164 uint32_t SystemMaxCoreClockGet(void)
165 {
166  return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
167  EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
168 }
169 
170 
171 /***************************************************************************/
181 uint32_t SystemHFClockGet(void)
182 {
183  uint32_t ret;
184 
185  switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
186  {
188 #if (EFM32_LFXO_FREQ > 0)
189  ret = SystemLFXOClock;
190 #else
191  /* We should not get here, since core should not be clocked. May */
192  /* be caused by a misconfiguration though. */
193  ret = 0;
194 #endif
195  break;
196 
198  ret = EFM32_LFRCO_FREQ;
199  break;
200 
202 #if (EFM32_HFXO_FREQ > 0)
203  ret = SystemHFXOClock;
204 #else
205  /* We should not get here, since core should not be clocked. May */
206  /* be caused by a misconfiguration though. */
207  ret = 0;
208 #endif
209  break;
210 
211  default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
212  ret = SystemHfrcoFreq;
213  break;
214  }
215 
216  return ret;
217 }
218 
219 
220 /**************************************************************************/
230 uint32_t SystemHFXOClockGet(void)
231 {
232  /* External crystal oscillator present? */
233 #if (EFM32_HFXO_FREQ > 0)
234  return SystemHFXOClock;
235 #else
236  return 0;
237 #endif
238 }
239 
240 
241 /**************************************************************************/
256 void SystemHFXOClockSet(uint32_t freq)
257 {
258  /* External crystal oscillator present? */
259 #if (EFM32_HFXO_FREQ > 0)
260  SystemHFXOClock = freq;
261 
262  /* Update core clock frequency if HFXO is used to clock core */
264  {
265  /* The function will update the global variable */
267  }
268 #else
269  (void)freq; /* Unused parameter */
270 #endif
271 }
272 
273 
274 /**************************************************************************/
286 void SystemInit(void)
287 {
288 #if (__FPU_PRESENT == 1)
289  /* Set floating point coprosessor access mode. */
290  SCB->CPACR |= ((3UL << 10 * 2) | /* set CP10 Full Access */
291  (3UL << 11 * 2)); /* set CP11 Full Access */
292 #endif
293 }
294 
295 
296 /**************************************************************************/
306 uint32_t SystemLFRCOClockGet(void)
307 {
308  /* Currently we assume that this frequency is properly tuned during */
309  /* manufacturing and is not changed after reset. If future requirements */
310  /* for re-tuning by user, we can add support for that. */
311  return EFM32_LFRCO_FREQ;
312 }
313 
314 
315 /**************************************************************************/
325 uint32_t SystemULFRCOClockGet(void)
326 {
327  /* The ULFRCO frequency is not tuned, and can be very inaccurate */
328  return EFM32_ULFRCO_FREQ;
329 }
330 
331 
332 /**************************************************************************/
342 uint32_t SystemLFXOClockGet(void)
343 {
344  /* External crystal oscillator present? */
345 #if (EFM32_LFXO_FREQ > 0)
346  return SystemLFXOClock;
347 #else
348  return 0;
349 #endif
350 }
351 
352 
353 /**************************************************************************/
368 void SystemLFXOClockSet(uint32_t freq)
369 {
370  /* External crystal oscillator present? */
371 #if (EFM32_LFXO_FREQ > 0)
372  SystemLFXOClock = freq;
373 
374  /* Update core clock frequency if LFXO is used to clock core */
376  {
377  /* The function will update the global variable */
379  }
380 #else
381  (void)freq; /* Unused parameter */
382 #endif
383 }
#define _CMU_HFCOREPRESC_PRESC_MASK
void SystemLFXOClockSet(uint32_t freq)
Set low frequency crystal oscillator clock frequency for target system.
#define _CMU_HFCOREPRESC_PRESC_SHIFT
void SystemInit(void)
Initialize the system.
uint32_t SystemMaxCoreClockGet(void)
Get the maximum core clock frequency.
uint32_t SystemHfrcoFreq
System HFRCO frequency.
void SystemHFXOClockSet(uint32_t freq)
Set high frequency crystal oscillator clock frequency for target system.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
uint32_t SystemHFXOClockGet(void)
Get high frequency crystal oscillator clock frequency for target system.
#define EFM32_LFRCO_FREQ
#define CMU_HFCLKSTATUS_SELECTED_LFRCO
#define CMU_HFCLKSTATUS_SELECTED_HFXO
uint32_t SystemULFRCOClockGet(void)
Get ultra low frequency RC oscillator clock frequency for target system.
uint32_t SystemCoreClock
System System Clock Frequency (Core Clock).
#define CMU_HFCLKSTATUS_SELECTED_LFXO
#define CMU
uint32_t SystemLFXOClockGet(void)
Get low frequency crystal oscillator clock frequency for target system.
uint32_t SystemHFClockGet(void)
Get the current HFCLK frequency.
#define _CMU_HFCLKSTATUS_SELECTED_MASK
uint32_t SystemCoreClockGet(void)
Get the current core clock frequency.
uint32_t SystemLFRCOClockGet(void)
Get low frequency RC oscillator clock frequency for target system.