1 /***************************************************************************//**
\r
3 * @brief Clock management unit (CMU) Peripheral API
\r
5 *******************************************************************************
\r
7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
\r
8 *******************************************************************************
\r
10 * Permission is granted to anyone to use this software for any purpose,
\r
11 * including commercial applications, and to alter it and redistribute it
\r
12 * freely, subject to the following restrictions:
\r
14 * 1. The origin of this software must not be misrepresented; you must not
\r
15 * claim that you wrote the original software.
\r
16 * 2. Altered source versions must be plainly marked as such, and must not be
\r
17 * misrepresented as being the original software.
\r
18 * 3. This notice may not be removed or altered from any source distribution.
\r
20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
\r
21 * obligation to support this Software. Silicon Labs is providing the
\r
22 * Software "AS IS", with no express or implied warranties of any kind,
\r
23 * including, but not limited to, any implied warranties of merchantability
\r
24 * or fitness for any particular purpose or warranties against infringement
\r
25 * of any proprietary rights of a third party.
\r
27 * Silicon Labs will not be liable for any consequential, incidental, or
\r
28 * special damages, or any other relief, or for any claim by any third party,
\r
29 * arising from your use of this Software.
\r
31 ******************************************************************************/
\r
33 #if defined( CMU_PRESENT )
\r
37 #include "em_assert.h"
\r
40 #include "em_system.h"
\r
42 /***************************************************************************//**
\r
43 * @addtogroup EM_Library
\r
45 ******************************************************************************/
\r
47 /***************************************************************************//**
\r
49 * @brief Clock management unit (CMU) Peripheral API
\r
51 ******************************************************************************/
\r
53 /*******************************************************************************
\r
54 ****************************** DEFINES ************************************
\r
55 ******************************************************************************/
\r
57 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
59 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
60 /** Maximum allowed core frequency when using 0 wait-states on flash access. */
\r
61 #define CMU_MAX_FREQ_0WS 26000000
\r
62 /** Maximum allowed core frequency when using 1 wait-states on flash access */
\r
63 #define CMU_MAX_FREQ_1WS 40000000
\r
64 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
65 /** Maximum allowed core frequency when using 0 wait-states on flash access. */
\r
66 #define CMU_MAX_FREQ_0WS 16000000
\r
67 /** Maximum allowed core frequency when using 1 wait-states on flash access */
\r
68 #define CMU_MAX_FREQ_1WS 32000000
\r
70 #error "Unkown MCU platform."
\r
73 #if defined( CMU_CTRL_HFLE )
\r
74 /** Maximum frequency for HFLE needs to be enabled on Giant, Leopard and
\r
76 #if defined( _EFM32_WONDER_FAMILY ) \
\r
77 || defined( _EZR32_LEOPARD_FAMILY ) \
\r
78 || defined( _EZR32_WONDER_FAMILY )
\r
79 #define CMU_MAX_FREQ_HFLE() 24000000
\r
80 #elif defined ( _EFM32_GIANT_FAMILY )
\r
81 #define CMU_MAX_FREQ_HFLE() (maxFreqHfle())
\r
83 #error Invalid part/device.
\r
87 /*******************************************************************************
\r
88 ************************** LOCAL VARIABLES ********************************
\r
89 ******************************************************************************/
\r
91 #if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )
\r
92 static CMU_AUXHFRCOFreq_TypeDef auxHfrcoFreq = cmuAUXHFRCOFreq_19M0Hz;
\r
97 /*******************************************************************************
\r
98 ************************** LOCAL FUNCTIONS ********************************
\r
99 ******************************************************************************/
\r
101 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
103 /***************************************************************************//**
\r
105 * Get the AUX clock frequency. Used by MSC flash programming and LESENSE,
\r
106 * by default also as debug clock.
\r
109 * AUX Frequency in Hz
\r
110 ******************************************************************************/
\r
111 static uint32_t auxClkGet(void)
\r
115 #if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )
\r
116 ret = auxHfrcoFreq;
\r
118 #elif defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
\r
119 /* All Geckos from TG and newer */
\r
120 switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)
\r
122 case CMU_AUXHFRCOCTRL_BAND_1MHZ:
\r
126 case CMU_AUXHFRCOCTRL_BAND_7MHZ:
\r
130 case CMU_AUXHFRCOCTRL_BAND_11MHZ:
\r
134 case CMU_AUXHFRCOCTRL_BAND_14MHZ:
\r
138 case CMU_AUXHFRCOCTRL_BAND_21MHZ:
\r
142 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
\r
143 case CMU_AUXHFRCOCTRL_BAND_28MHZ:
\r
155 /* Gecko has a fixed 14Mhz AUXHFRCO clock */
\r
164 /***************************************************************************//**
\r
166 * Get the Debug Trace clock frequency
\r
169 * Debug Trace frequency in Hz
\r
170 ******************************************************************************/
\r
171 static uint32_t dbgClkGet(void)
\r
174 CMU_Select_TypeDef clk;
\r
176 /* Get selected clock source */
\r
177 clk = CMU_ClockSelectGet(cmuClock_DBG);
\r
181 case cmuSelect_HFCLK:
\r
182 ret = SystemHFClockGet();
\r
183 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
\r
184 /* Family with an additional divider. */
\r
185 ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)
\r
186 >> _CMU_CTRL_HFCLKDIV_SHIFT));
\r
190 case cmuSelect_AUXHFRCO:
\r
203 /***************************************************************************//**
\r
205 * Configure flash access wait states in order to support given core clock
\r
208 * @param[in] coreFreq
\r
209 * Core clock frequency to configure flash wait-states for
\r
210 ******************************************************************************/
\r
211 static void flashWaitStateControl(uint32_t coreFreq)
\r
215 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
\r
216 bool scbtpEn; /* Suppressed Conditional Branch Target Prefetch setting. */
\r
219 /* Make sure the MSC is unlocked */
\r
220 mscLocked = MSC->LOCK;
\r
221 MSC->LOCK = MSC_UNLOCK_CODE;
\r
223 /* Get mode and SCBTP enable */
\r
224 mode = MSC->READCTRL & _MSC_READCTRL_MODE_MASK;
\r
225 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
\r
228 case MSC_READCTRL_MODE_WS0:
\r
229 case MSC_READCTRL_MODE_WS1:
\r
230 #if defined( MSC_READCTRL_MODE_WS2 )
\r
231 case MSC_READCTRL_MODE_WS2:
\r
236 default: /* WSxSCBTP */
\r
243 /* Set mode based on the core clock frequency and SCBTP enable */
\r
244 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
\r
248 #if defined( MSC_READCTRL_MODE_WS2 )
\r
249 else if (coreFreq > CMU_MAX_FREQ_1WS)
\r
251 mode = (scbtpEn ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2);
\r
254 else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))
\r
256 mode = (scbtpEn ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1);
\r
260 mode = (scbtpEn ? MSC_READCTRL_MODE_WS0SCBTP : MSC_READCTRL_MODE_WS0);
\r
263 #else /* If MODE and SCBTP is in separate register fields */
\r
268 #if defined( MSC_READCTRL_MODE_WS2 )
\r
269 else if (coreFreq > CMU_MAX_FREQ_1WS)
\r
271 mode = MSC_READCTRL_MODE_WS2;
\r
274 else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))
\r
276 mode = MSC_READCTRL_MODE_WS1;
\r
280 mode = MSC_READCTRL_MODE_WS0;
\r
284 /* BUS_RegMaskedWrite cannot be used here as it would temporarely set the
\r
285 mode field to WS0 */
\r
286 MSC->READCTRL = (MSC->READCTRL &~_MSC_READCTRL_MODE_MASK) | mode;
\r
295 /***************************************************************************//**
\r
297 * Configure flash access wait states to most conservative setting for
\r
298 * this target. Retain SCBTP (Suppressed Conditional Branch Target Prefetch)
\r
300 ******************************************************************************/
\r
301 static void flashWaitStateMax(void)
\r
303 flashWaitStateControl(SystemMaxCoreClockGet());
\r
307 /***************************************************************************//**
\r
309 * Get the LFnCLK frequency based on current configuration.
\r
311 * @param[in] lfClkBranch
\r
312 * Selected LF branch
\r
315 * The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is
\r
317 ******************************************************************************/
\r
318 static uint32_t lfClkGet(CMU_Clock_TypeDef lfClkBranch)
\r
323 switch (lfClkBranch)
\r
327 #if defined( _CMU_LFCCLKEN0_MASK )
\r
330 #if defined( _CMU_LFECLKSEL_MASK )
\r
340 sel = CMU_ClockSelectGet(lfClkBranch);
\r
342 /* Get clock select field */
\r
343 switch (lfClkBranch)
\r
346 #if defined( _CMU_LFCLKSEL_MASK )
\r
347 sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK) >> _CMU_LFCLKSEL_LFA_SHIFT;
\r
348 #elif defined( _CMU_LFACLKSEL_MASK )
\r
349 sel = (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK) >> _CMU_LFACLKSEL_LFA_SHIFT;
\r
356 #if defined( _CMU_LFCLKSEL_MASK )
\r
357 sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK) >> _CMU_LFCLKSEL_LFB_SHIFT;
\r
358 #elif defined( _CMU_LFBCLKSEL_MASK )
\r
359 sel = (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK) >> _CMU_LFBCLKSEL_LFB_SHIFT;
\r
365 #if defined( _CMU_LFCCLKEN0_MASK )
\r
367 sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK) >> _CMU_LFCLKSEL_LFC_SHIFT;
\r
371 #if defined( _CMU_LFECLKSEL_MASK )
\r
373 sel = (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK) >> _CMU_LFECLKSEL_LFE_SHIFT;
\r
382 /* Get clock frequency */
\r
383 #if defined( _CMU_LFCLKSEL_MASK )
\r
386 case _CMU_LFCLKSEL_LFA_LFRCO:
\r
387 ret = SystemLFRCOClockGet();
\r
390 case _CMU_LFCLKSEL_LFA_LFXO:
\r
391 ret = SystemLFXOClockGet();
\r
394 #if defined( _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )
\r
395 case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
\r
396 #if defined( CMU_CTRL_HFLE )
\r
397 /* Family which can use an extra div 4 divider */
\r
398 /* (and must if >32MHz) or HFLE is set. */
\r
399 if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK)
\r
400 == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)
\r
401 || (CMU->CTRL & CMU_CTRL_HFLE))
\r
403 ret = SystemCoreClockGet() / 4U;
\r
407 ret = SystemCoreClockGet() / 2U;
\r
410 ret = SystemCoreClockGet() / 2U;
\r
415 case _CMU_LFCLKSEL_LFA_DISABLED:
\r
417 #if defined( CMU_LFCLKSEL_LFAE )
\r
418 /* Check LF Extended bit setting for LFA or LFB ULFRCO clock */
\r
419 if ((lfClkBranch == cmuClock_LFA) || (lfClkBranch == cmuClock_LFB))
\r
421 if (CMU->LFCLKSEL >> (lfClkBranch == cmuClock_LFA
\r
422 ? _CMU_LFCLKSEL_LFAE_SHIFT
\r
423 : _CMU_LFCLKSEL_LFBE_SHIFT))
\r
425 ret = SystemULFRCOClockGet();
\r
436 #endif /* _CMU_LFCLKSEL_MASK */
\r
438 #if defined( _CMU_LFACLKSEL_MASK )
\r
441 case _CMU_LFACLKSEL_LFA_LFRCO:
\r
442 ret = SystemLFRCOClockGet();
\r
445 case _CMU_LFACLKSEL_LFA_LFXO:
\r
446 ret = SystemLFXOClockGet();
\r
449 case _CMU_LFACLKSEL_LFA_ULFRCO:
\r
450 ret = SystemULFRCOClockGet();
\r
453 #if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )
\r
454 case _CMU_LFACLKSEL_LFA_HFCLKLE:
\r
455 ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)
\r
456 == CMU_HFPRESC_HFCLKLEPRESC_DIV4)
\r
457 ? SystemCoreClockGet() / 4U
\r
458 : SystemCoreClockGet() / 2U;
\r
460 #elif defined( _CMU_LFBCLKSEL_LFB_HFCLKLE )
\r
461 case _CMU_LFBCLKSEL_LFB_HFCLKLE:
\r
462 ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)
\r
463 == CMU_HFPRESC_HFCLKLEPRESC_DIV4)
\r
464 ? SystemCoreClockGet() / 4U
\r
465 : SystemCoreClockGet() / 2U;
\r
469 case _CMU_LFACLKSEL_LFA_DISABLED:
\r
479 #if defined( CMU_CTRL_HFLE ) \
\r
480 && !defined( _EFM32_WONDER_FAMILY ) \
\r
481 && !defined( _EZR32_LEOPARD_FAMILY ) \
\r
482 && !defined( _EZR32_WONDER_FAMILY )
\r
483 /***************************************************************************//**
\r
485 * Return max allowed frequency for low energy peripherals.
\r
486 ******************************************************************************/
\r
487 static uint32_t maxFreqHfle(void)
\r
489 uint16_t majorMinorRev;
\r
491 switch (SYSTEM_GetFamily())
\r
493 case systemPartFamilyEfm32Leopard:
\r
494 /* CHIP MAJOR bit [5:0] */
\r
495 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
\r
496 >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
\r
497 /* CHIP MINOR bit [7:4] */
\r
498 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
\r
499 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
\r
500 /* CHIP MINOR bit [3:0] */
\r
501 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
\r
502 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
\r
504 if (majorMinorRev >= 0x0204)
\r
509 case systemPartFamilyEfm32Giant:
\r
513 /* Invalid device family. */
\r
521 /***************************************************************************//**
\r
523 * Wait for ongoing sync of register(s) to low frequency domain to complete.
\r
526 * Bitmask corresponding to SYNCBUSY register defined bits, indicating
\r
527 * registers that must complete any ongoing synchronization.
\r
528 ******************************************************************************/
\r
529 __STATIC_INLINE void syncReg(uint32_t mask)
\r
531 /* Avoid deadlock if modifying the same register twice when freeze mode is */
\r
533 if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)
\r
536 /* Wait for any pending previous write operation to have been completed */
\r
537 /* in low frequency domain */
\r
538 while (CMU->SYNCBUSY & mask)
\r
544 #if defined(USB_PRESENT)
\r
545 /***************************************************************************//**
\r
547 * Get the USBC frequency
\r
550 * USBC frequency in Hz
\r
551 ******************************************************************************/
\r
552 static uint32_t usbCClkGet(void)
\r
555 CMU_Select_TypeDef clk;
\r
557 /* Get selected clock source */
\r
558 clk = CMU_ClockSelectGet(cmuClock_USBC);
\r
562 case cmuSelect_LFXO:
\r
563 ret = SystemLFXOClockGet();
\r
565 case cmuSelect_LFRCO:
\r
566 ret = SystemLFRCOClockGet();
\r
568 case cmuSelect_HFCLK:
\r
569 ret = SystemHFClockGet();
\r
572 /* Clock is not enabled */
\r
583 /*******************************************************************************
\r
584 ************************** GLOBAL FUNCTIONS *******************************
\r
585 ******************************************************************************/
\r
587 #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
\r
588 /***************************************************************************//**
\r
590 * Get AUXHFRCO band in use.
\r
593 * AUXHFRCO band in use.
\r
594 ******************************************************************************/
\r
595 CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)
\r
597 return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL
\r
598 & _CMU_AUXHFRCOCTRL_BAND_MASK)
\r
599 >> _CMU_AUXHFRCOCTRL_BAND_SHIFT);
\r
601 #endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */
\r
604 #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
\r
605 /***************************************************************************//**
\r
607 * Set AUXHFRCO band and the tuning value based on the value in the
\r
608 * calibration table made during production.
\r
611 * AUXHFRCO band to activate.
\r
612 ******************************************************************************/
\r
613 void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)
\r
617 /* Read tuning value from calibration table */
\r
620 case cmuAUXHFRCOBand_1MHz:
\r
621 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK)
\r
622 >> _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;
\r
625 case cmuAUXHFRCOBand_7MHz:
\r
626 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK)
\r
627 >> _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;
\r
630 case cmuAUXHFRCOBand_11MHz:
\r
631 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK)
\r
632 >> _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;
\r
635 case cmuAUXHFRCOBand_14MHz:
\r
636 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK)
\r
637 >> _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;
\r
640 case cmuAUXHFRCOBand_21MHz:
\r
641 tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK)
\r
642 >> _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;
\r
645 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
\r
646 case cmuAUXHFRCOBand_28MHz:
\r
647 tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK)
\r
648 >> _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;
\r
657 /* Set band/tuning */
\r
658 CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &
\r
659 ~(_CMU_AUXHFRCOCTRL_BAND_MASK
\r
660 | _CMU_AUXHFRCOCTRL_TUNING_MASK))
\r
661 | (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT)
\r
662 | (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
\r
665 #endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */
\r
668 #if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )
\r
669 /**************************************************************************//**
\r
671 * Get a pointer to the AUXHFRCO frequency calibration word in DEVINFO
\r
677 * AUXHFRCO calibration word for a given frequency
\r
678 *****************************************************************************/
\r
679 static uint32_t CMU_AUXHFRCODevinfoGet(CMU_AUXHFRCOFreq_TypeDef freq)
\r
683 /* 1, 2 and 4MHz share the same calibration word */
\r
684 case cmuAUXHFRCOFreq_1M0Hz:
\r
685 case cmuAUXHFRCOFreq_2M0Hz:
\r
686 case cmuAUXHFRCOFreq_4M0Hz:
\r
687 return DEVINFO->AUXHFRCOCAL0;
\r
689 case cmuAUXHFRCOFreq_7M0Hz:
\r
690 return DEVINFO->AUXHFRCOCAL3;
\r
692 case cmuAUXHFRCOFreq_13M0Hz:
\r
693 return DEVINFO->AUXHFRCOCAL6;
\r
695 case cmuAUXHFRCOFreq_16M0Hz:
\r
696 return DEVINFO->AUXHFRCOCAL7;
\r
698 case cmuAUXHFRCOFreq_19M0Hz:
\r
699 return DEVINFO->AUXHFRCOCAL8;
\r
701 case cmuAUXHFRCOFreq_26M0Hz:
\r
702 return DEVINFO->AUXHFRCOCAL10;
\r
704 case cmuAUXHFRCOFreq_32M0Hz:
\r
705 return DEVINFO->AUXHFRCOCAL11;
\r
707 case cmuAUXHFRCOFreq_38M0Hz:
\r
708 return DEVINFO->AUXHFRCOCAL12;
\r
710 default: /* cmuAUXHFRCOFreq_UserDefined */
\r
714 #endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */
\r
717 #if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )
\r
718 /***************************************************************************//**
\r
720 * Get AUXHFRCO frequency enumeration in use
\r
723 * AUXHFRCO frequency enumeration in use
\r
724 ******************************************************************************/
\r
725 CMU_AUXHFRCOFreq_TypeDef CMU_AUXHFRCOFreqGet(void)
\r
727 return auxHfrcoFreq;
\r
729 #endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */
\r
732 #if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )
\r
733 /***************************************************************************//**
\r
735 * Set AUXHFRCO calibration for the selected target frequency
\r
737 * @param[in] frequency
\r
738 * AUXHFRCO frequency to set
\r
739 ******************************************************************************/
\r
740 void CMU_AUXHFRCOFreqSet(CMU_AUXHFRCOFreq_TypeDef freq)
\r
744 /* Get DEVINFO index, set global auxHfrcoFreq */
\r
745 freqCal = CMU_AUXHFRCODevinfoGet(freq);
\r
746 EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));
\r
747 auxHfrcoFreq = freq;
\r
749 /* Wait for any previous sync to complete, and then set calibration data
\r
750 for the selected frequency. */
\r
751 while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT));
\r
753 /* Set divider in AUXHFRCOCTRL for 1, 2 and 4MHz */
\r
756 case cmuAUXHFRCOFreq_1M0Hz:
\r
757 freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)
\r
758 | CMU_AUXHFRCOCTRL_CLKDIV_DIV4;
\r
761 case cmuAUXHFRCOFreq_2M0Hz:
\r
762 freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)
\r
763 | CMU_AUXHFRCOCTRL_CLKDIV_DIV2;
\r
766 case cmuAUXHFRCOFreq_4M0Hz:
\r
767 freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)
\r
768 | CMU_AUXHFRCOCTRL_CLKDIV_DIV1;
\r
774 CMU->AUXHFRCOCTRL = freqCal;
\r
776 #endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */
\r
779 /***************************************************************************//**
\r
784 * Run a calibration for HFCLK against a selectable reference clock. Please
\r
785 * refer to the reference manual, CMU chapter, for further details.
\r
788 * This function will not return until calibration measurement is completed.
\r
790 * @param[in] HFCycles
\r
791 * The number of HFCLK cycles to run calibration. Increasing this number
\r
792 * increases precision, but the calibration will take more time.
\r
795 * The reference clock used to compare HFCLK with.
\r
798 * The number of ticks the reference clock after HFCycles ticks on the HF
\r
800 ******************************************************************************/
\r
801 uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
\r
803 EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
\r
805 /* Set reference clock source */
\r
809 CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;
\r
813 CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;
\r
817 CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;
\r
821 CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;
\r
824 case cmuOsc_AUXHFRCO:
\r
825 CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;
\r
833 /* Set top value */
\r
834 CMU->CALCNT = HFCycles;
\r
836 /* Start calibration */
\r
837 CMU->CMD = CMU_CMD_CALSTART;
\r
839 #if defined( CMU_STATUS_CALRDY )
\r
840 /* Wait until calibration completes */
\r
841 while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))
\r
845 /* Wait until calibration completes */
\r
846 while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))
\r
851 return CMU->CALCNT;
\r
855 #if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )
\r
856 /***************************************************************************//**
\r
858 * Configure clock calibration
\r
861 * Configure a calibration for a selectable clock source against another
\r
862 * selectable reference clock.
\r
863 * Refer to the reference manual, CMU chapter, for further details.
\r
866 * After configuration, a call to CMU_CalibrateStart() is required, and
\r
867 * the resulting calibration value can be read out with the
\r
868 * CMU_CalibrateCountGet() function call.
\r
870 * @param[in] downCycles
\r
871 * The number of downSel clock cycles to run calibration. Increasing this
\r
872 * number increases precision, but the calibration will take more time.
\r
874 * @param[in] downSel
\r
875 * The clock which will be counted down downCycles
\r
878 * The reference clock, the number of cycles generated by this clock will
\r
879 * be counted and added up, the result can be given with the
\r
880 * CMU_CalibrateCountGet() function call.
\r
881 ******************************************************************************/
\r
882 void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
\r
883 CMU_Osc_TypeDef upSel)
\r
885 /* Keep untouched configuration settings */
\r
886 uint32_t calCtrl = CMU->CALCTRL
\r
887 & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);
\r
889 /* 20 bits of precision to calibration count register */
\r
890 EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
\r
892 /* Set down counting clock source - down counter */
\r
896 calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;
\r
900 calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;
\r
904 calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;
\r
908 calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;
\r
911 case cmuOsc_AUXHFRCO:
\r
912 calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;
\r
920 /* Set top value to be counted down by the downSel clock */
\r
921 CMU->CALCNT = downCycles;
\r
923 /* Set reference clock source - up counter */
\r
927 calCtrl |= CMU_CALCTRL_UPSEL_LFXO;
\r
931 calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;
\r
935 calCtrl |= CMU_CALCTRL_UPSEL_HFXO;
\r
939 calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;
\r
942 case cmuOsc_AUXHFRCO:
\r
943 calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;
\r
951 CMU->CALCTRL = calCtrl;
\r
956 /***************************************************************************//**
\r
958 * Get calibration count register
\r
960 * If continuous calibrartion mode is active, calibration busy will almost
\r
961 * always be off, and we just need to read the value, where the normal case
\r
962 * would be that this function call has been triggered by the CALRDY
\r
965 * Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)
\r
966 * in the period of DOWNSEL oscillator clock cycles configured by a previous
\r
967 * write operation to CMU->CALCNT
\r
968 ******************************************************************************/
\r
969 uint32_t CMU_CalibrateCountGet(void)
\r
971 /* Wait until calibration completes, UNLESS continuous calibration mode is */
\r
973 #if defined( CMU_CALCTRL_CONT )
\r
974 if (!BUS_RegBitRead(&CMU->CALCTRL, _CMU_CALCTRL_CONT_SHIFT))
\r
976 #if defined( CMU_STATUS_CALRDY )
\r
977 /* Wait until calibration completes */
\r
978 while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))
\r
982 /* Wait until calibration completes */
\r
983 while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))
\r
989 while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))
\r
993 return CMU->CALCNT;
\r
997 /***************************************************************************//**
\r
999 * Get clock divisor/prescaler.
\r
1001 * @param[in] clock
\r
1002 * Clock point to get divisor/prescaler for. Notice that not all clock points
\r
1003 * have a divisor/prescaler. Please refer to CMU overview in reference manual.
\r
1006 * The current clock point divisor/prescaler. 1 is returned
\r
1007 * if @p clock specifies a clock point without a divisor/prescaler.
\r
1008 ******************************************************************************/
\r
1009 CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
\r
1011 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1012 return 1 + (uint32_t)CMU_ClockPrescGet(clock);
\r
1014 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1016 CMU_ClkDiv_TypeDef ret;
\r
1018 /* Get divisor reg id */
\r
1019 divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
\r
1023 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
\r
1024 case CMU_HFCLKDIV_REG:
\r
1025 ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)
\r
1026 >> _CMU_CTRL_HFCLKDIV_SHIFT);
\r
1030 case CMU_HFPERCLKDIV_REG:
\r
1031 ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV
\r
1032 & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)
\r
1033 >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
\r
1034 ret = CMU_Log2ToDiv(ret);
\r
1037 case CMU_HFCORECLKDIV_REG:
\r
1038 ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV
\r
1039 & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)
\r
1040 >> _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
\r
1041 ret = CMU_Log2ToDiv(ret);
\r
1044 case CMU_LFAPRESC0_REG:
\r
1047 case cmuClock_RTC:
\r
1048 ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)
\r
1049 >> _CMU_LFAPRESC0_RTC_SHIFT);
\r
1050 ret = CMU_Log2ToDiv(ret);
\r
1053 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
\r
1054 case cmuClock_LETIMER0:
\r
1055 ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)
\r
1056 >> _CMU_LFAPRESC0_LETIMER0_SHIFT);
\r
1057 ret = CMU_Log2ToDiv(ret);
\r
1061 #if defined(_CMU_LFAPRESC0_LCD_MASK)
\r
1062 case cmuClock_LCDpre:
\r
1063 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)
\r
1064 >> _CMU_LFAPRESC0_LCD_SHIFT)
\r
1065 + CMU_DivToLog2(cmuClkDiv_16));
\r
1066 ret = CMU_Log2ToDiv(ret);
\r
1070 #if defined(_CMU_LFAPRESC0_LESENSE_MASK)
\r
1071 case cmuClock_LESENSE:
\r
1072 ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)
\r
1073 >> _CMU_LFAPRESC0_LESENSE_SHIFT);
\r
1074 ret = CMU_Log2ToDiv(ret);
\r
1080 ret = cmuClkDiv_1;
\r
1085 case CMU_LFBPRESC0_REG:
\r
1088 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
\r
1089 case cmuClock_LEUART0:
\r
1090 ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)
\r
1091 >> _CMU_LFBPRESC0_LEUART0_SHIFT);
\r
1092 ret = CMU_Log2ToDiv(ret);
\r
1096 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
\r
1097 case cmuClock_LEUART1:
\r
1098 ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)
\r
1099 >> _CMU_LFBPRESC0_LEUART1_SHIFT);
\r
1100 ret = CMU_Log2ToDiv(ret);
\r
1106 ret = cmuClkDiv_1;
\r
1113 ret = cmuClkDiv_1;
\r
1122 /***************************************************************************//**
\r
1124 * Set clock divisor/prescaler.
\r
1127 * If setting a LF clock prescaler, synchronization into the low frequency
\r
1128 * domain is required. If the same register is modified before a previous
\r
1129 * update has completed, this function will stall until the previous
\r
1130 * synchronization has completed. Please refer to CMU_FreezeEnable() for
\r
1131 * a suggestion on how to reduce stalling time in some use cases.
\r
1133 * @param[in] clock
\r
1134 * Clock point to set divisor/prescaler for. Notice that not all clock points
\r
1135 * have a divisor/prescaler, please refer to CMU overview in the reference
\r
1139 * The clock divisor to use (<= cmuClkDiv_512).
\r
1140 ******************************************************************************/
\r
1141 void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
\r
1143 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1144 CMU_ClockPrescSet(clock, (CMU_ClkPresc_TypeDef)(div - 1));
\r
1146 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1150 /* Get divisor reg id */
\r
1151 divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
\r
1155 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
\r
1156 case CMU_HFCLKDIV_REG:
\r
1157 EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));
\r
1159 /* Configure worst case wait states for flash access before setting divisor */
\r
1160 flashWaitStateMax();
\r
1163 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK)
\r
1164 | ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);
\r
1166 /* Update CMSIS core clock variable */
\r
1167 /* (The function will update the global variable) */
\r
1168 freq = SystemCoreClockGet();
\r
1170 /* Optimize flash access wait state setting for current core clk */
\r
1171 flashWaitStateControl(freq);
\r
1175 case CMU_HFPERCLKDIV_REG:
\r
1176 EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));
\r
1177 /* Convert to correct scale */
\r
1178 div = CMU_DivToLog2(div);
\r
1179 CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)
\r
1180 | (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
\r
1183 case CMU_HFCORECLKDIV_REG:
\r
1184 EFM_ASSERT(div <= cmuClkDiv_512);
\r
1186 /* Configure worst case wait states for flash access before setting divisor */
\r
1187 flashWaitStateMax();
\r
1189 #if defined( CMU_CTRL_HFLE )
\r
1190 /* Clear HFLE and set DIV2 factor for peripheral clock
\r
1191 when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */
\r
1192 if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE())
\r
1194 /* Clear CMU HFLE */
\r
1195 BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 0);
\r
1197 /* Set DIV2 factor for peripheral clock */
\r
1198 BUS_RegBitWrite(&CMU->HFCORECLKDIV,
\r
1199 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);
\r
1203 /* Set CMU HFLE */
\r
1204 BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);
\r
1206 /* Set DIV4 factor for peripheral clock */
\r
1207 BUS_RegBitWrite(&CMU->HFCORECLKDIV,
\r
1208 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
\r
1212 /* Convert to correct scale */
\r
1213 div = CMU_DivToLog2(div);
\r
1215 CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV
\r
1216 & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)
\r
1217 | (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
\r
1219 /* Update CMSIS core clock variable */
\r
1220 /* (The function will update the global variable) */
\r
1221 freq = SystemCoreClockGet();
\r
1223 /* Optimize flash access wait state setting for current core clk */
\r
1224 flashWaitStateControl(freq);
\r
1227 case CMU_LFAPRESC0_REG:
\r
1230 case cmuClock_RTC:
\r
1231 EFM_ASSERT(div <= cmuClkDiv_32768);
\r
1233 /* LF register about to be modified require sync. busy check */
\r
1234 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1236 /* Convert to correct scale */
\r
1237 div = CMU_DivToLog2(div);
\r
1239 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)
\r
1240 | (div << _CMU_LFAPRESC0_RTC_SHIFT);
\r
1243 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
\r
1244 case cmuClock_LETIMER0:
\r
1245 EFM_ASSERT(div <= cmuClkDiv_32768);
\r
1247 /* LF register about to be modified require sync. busy check */
\r
1248 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1250 /* Convert to correct scale */
\r
1251 div = CMU_DivToLog2(div);
\r
1253 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)
\r
1254 | (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);
\r
1258 #if defined(LCD_PRESENT)
\r
1259 case cmuClock_LCDpre:
\r
1260 EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));
\r
1262 /* LF register about to be modified require sync. busy check */
\r
1263 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1265 /* Convert to correct scale */
\r
1266 div = CMU_DivToLog2(div);
\r
1268 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK)
\r
1269 | ((div - CMU_DivToLog2(cmuClkDiv_16))
\r
1270 << _CMU_LFAPRESC0_LCD_SHIFT);
\r
1272 #endif /* defined(LCD_PRESENT) */
\r
1274 #if defined(LESENSE_PRESENT)
\r
1275 case cmuClock_LESENSE:
\r
1276 EFM_ASSERT(div <= cmuClkDiv_8);
\r
1278 /* LF register about to be modified require sync. busy check */
\r
1279 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1281 /* Convert to correct scale */
\r
1282 div = CMU_DivToLog2(div);
\r
1284 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK)
\r
1285 | (div << _CMU_LFAPRESC0_LESENSE_SHIFT);
\r
1287 #endif /* defined(LESENSE_PRESENT) */
\r
1295 case CMU_LFBPRESC0_REG:
\r
1298 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
\r
1299 case cmuClock_LEUART0:
\r
1300 EFM_ASSERT(div <= cmuClkDiv_8);
\r
1302 /* LF register about to be modified require sync. busy check */
\r
1303 syncReg(CMU_SYNCBUSY_LFBPRESC0);
\r
1305 /* Convert to correct scale */
\r
1306 div = CMU_DivToLog2(div);
\r
1308 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)
\r
1309 | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);
\r
1313 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
\r
1314 case cmuClock_LEUART1:
\r
1315 EFM_ASSERT(div <= cmuClkDiv_8);
\r
1317 /* LF register about to be modified require sync. busy check */
\r
1318 syncReg(CMU_SYNCBUSY_LFBPRESC0);
\r
1320 /* Convert to correct scale */
\r
1321 div = CMU_DivToLog2(div);
\r
1323 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)
\r
1324 | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);
\r
1342 /***************************************************************************//**
\r
1344 * Enable/disable a clock.
\r
1347 * In general, module clocking is disabled after a reset. If a module
\r
1348 * clock is disabled, the registers of that module are not accessible and
\r
1349 * reading from such registers may return undefined values. Writing to
\r
1350 * registers of clock disabled modules have no effect. One should normally
\r
1351 * avoid accessing module registers of a module with a disabled clock.
\r
1354 * If enabling/disabling a LF clock, synchronization into the low frequency
\r
1355 * domain is required. If the same register is modified before a previous
\r
1356 * update has completed, this function will stall until the previous
\r
1357 * synchronization has completed. Please refer to CMU_FreezeEnable() for
\r
1358 * a suggestion on how to reduce stalling time in some use cases.
\r
1360 * @param[in] clock
\r
1361 * The clock to enable/disable. Notice that not all defined clock
\r
1362 * points have separate enable/disable control, please refer to CMU overview
\r
1363 * in reference manual.
\r
1365 * @param[in] enable
\r
1366 * @li true - enable specified clock.
\r
1367 * @li false - disable specified clock.
\r
1368 ******************************************************************************/
\r
1369 void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
\r
1371 volatile uint32_t *reg;
\r
1373 uint32_t sync = 0;
\r
1375 /* Identify enable register */
\r
1376 switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)
\r
1378 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1379 case CMU_CTRL_EN_REG:
\r
1384 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1385 case CMU_HFCORECLKEN0_EN_REG:
\r
1386 reg = &CMU->HFCORECLKEN0;
\r
1387 #if defined( CMU_CTRL_HFLE )
\r
1388 /* Set HFLE and DIV4 factor for peripheral clock when
\r
1389 running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */
\r
1390 if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE())
\r
1392 /* Enable CMU HFLE */
\r
1393 BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);
\r
1395 /* Set DIV4 factor for peripheral clock */
\r
1396 BUS_RegBitWrite(&CMU->HFCORECLKDIV,
\r
1397 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
\r
1403 #if defined( _CMU_HFBUSCLKEN0_MASK )
\r
1404 case CMU_HFBUSCLKEN0_EN_REG:
\r
1405 reg = &CMU->HFBUSCLKEN0;
\r
1409 #if defined( _CMU_HFRADIOCLKEN0_MASK )
\r
1410 case CMU_HFRADIOCLKEN0_EN_REG:
\r
1411 reg = &CMU->HFRADIOCLKEN0;
\r
1415 #if defined( _CMU_HFPERCLKDIV_MASK )
\r
1416 case CMU_HFPERCLKDIV_EN_REG:
\r
1417 reg = &CMU->HFPERCLKDIV;
\r
1421 case CMU_HFPERCLKEN0_EN_REG:
\r
1422 reg = &CMU->HFPERCLKEN0;
\r
1425 case CMU_LFACLKEN0_EN_REG:
\r
1426 reg = &CMU->LFACLKEN0;
\r
1427 sync = CMU_SYNCBUSY_LFACLKEN0;
\r
1430 case CMU_LFBCLKEN0_EN_REG:
\r
1431 reg = &CMU->LFBCLKEN0;
\r
1432 sync = CMU_SYNCBUSY_LFBCLKEN0;
\r
1435 #if defined( _CMU_LFCCLKEN0_MASK )
\r
1436 case CMU_LFCCLKEN0_EN_REG:
\r
1437 reg = &CMU->LFCCLKEN0;
\r
1438 sync = CMU_SYNCBUSY_LFCCLKEN0;
\r
1442 #if defined( _CMU_LFECLKEN0_MASK )
\r
1443 case CMU_LFECLKEN0_EN_REG:
\r
1444 reg = &CMU->LFECLKEN0;
\r
1445 sync = CMU_SYNCBUSY_LFECLKEN0;
\r
1449 case CMU_PCNT_EN_REG:
\r
1450 reg = &CMU->PCNTCTRL;
\r
1453 default: /* Cannot enable/disable clock point */
\r
1458 /* Get bit position used to enable/disable */
\r
1459 bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;
\r
1461 /* LF synchronization required? */
\r
1467 /* Set/clear bit as requested */
\r
1468 BUS_RegBitWrite(reg, bit, enable);
\r
1472 /***************************************************************************//**
\r
1474 * Get clock frequency for a clock point.
\r
1476 * @param[in] clock
\r
1477 * Clock point to fetch frequency for.
\r
1480 * The current frequency in Hz.
\r
1481 ******************************************************************************/
\r
1482 uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
\r
1486 switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))
\r
1488 case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1489 ret = SystemHFClockGet();
\r
1490 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
\r
1491 /* Family with an additional divider. */
\r
1492 ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)
\r
1493 >> _CMU_CTRL_HFCLKDIV_SHIFT));
\r
1495 #if defined( _CMU_HFPRESC_MASK )
\r
1496 ret = ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
\r
1497 >> _CMU_HFPRESC_PRESC_SHIFT));
\r
1501 case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1502 ret = SystemHFClockGet();
\r
1503 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1504 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
\r
1505 /* Family with an additional divider. */
\r
1506 ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)
\r
1507 >> _CMU_CTRL_HFCLKDIV_SHIFT));
\r
1509 ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)
\r
1510 >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;
\r
1511 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1512 ret /= 1U + ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)
\r
1513 >> _CMU_HFPERPRESC_PRESC_SHIFT);
\r
1517 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1518 #if defined( _CMU_HFRADIOPRESC_PRESC_MASK )
\r
1519 case (CMU_HFRADIO_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1520 ret = SystemHFClockGet();
\r
1521 ret /= 1U + ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)
\r
1522 >> _CMU_HFRADIOPRESC_PRESC_SHIFT);
\r
1526 #if defined( CRYPTO_PRESENT ) \
\r
1527 || defined( LDMA_PRESENT ) \
\r
1528 || defined( GPCRC_PRESENT ) \
\r
1529 || defined( PRS_PRESENT ) \
\r
1530 || defined( GPIO_PRESENT )
\r
1531 case (CMU_HFBUS_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1532 ret = SystemHFClockGet();
\r
1536 case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1537 ret = SystemHFClockGet();
\r
1538 ret /= 1U + ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)
\r
1539 >> _CMU_HFCOREPRESC_PRESC_SHIFT);
\r
1542 case (CMU_HFEXP_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1543 ret = SystemHFClockGet();
\r
1544 ret /= 1U + ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)
\r
1545 >> _CMU_HFEXPPRESC_PRESC_SHIFT);
\r
1549 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1550 #if defined(AES_PRESENT) \
\r
1551 || defined(DMA_PRESENT) \
\r
1552 || defined(EBI_PRESENT) \
\r
1553 || defined(USB_PRESENT)
\r
1554 case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1556 ret = SystemCoreClockGet();
\r
1561 case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1562 ret = lfClkGet(cmuClock_LFA);
\r
1565 #if defined( _CMU_LFACLKEN0_RTC_MASK )
\r
1566 case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1567 ret = lfClkGet(cmuClock_LFA);
\r
1568 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)
\r
1569 >> _CMU_LFAPRESC0_RTC_SHIFT;
\r
1573 #if defined( _CMU_LFECLKEN0_RTCC_MASK )
\r
1574 case (CMU_RTCC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1575 ret = lfClkGet(cmuClock_LFE);
\r
1579 #if defined( _CMU_LFACLKEN0_LETIMER0_MASK )
\r
1580 case (CMU_LETIMER0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1581 ret = lfClkGet(cmuClock_LFA);
\r
1582 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1583 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)
\r
1584 >> _CMU_LFAPRESC0_LETIMER0_SHIFT;
\r
1585 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1586 ret /= CMU_Log2ToDiv((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)
\r
1587 >> _CMU_LFAPRESC0_LETIMER0_SHIFT);
\r
1592 #if defined(_CMU_LFACLKEN0_LCD_MASK)
\r
1593 case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1594 ret = lfClkGet(cmuClock_LFA);
\r
1595 ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)
\r
1596 >> _CMU_LFAPRESC0_LCD_SHIFT)
\r
1597 + CMU_DivToLog2(cmuClkDiv_16);
\r
1600 case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1601 ret = lfClkGet(cmuClock_LFA);
\r
1602 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)
\r
1603 >> _CMU_LFAPRESC0_LCD_SHIFT;
\r
1604 ret /= 1U + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK)
\r
1605 >> _CMU_LCDCTRL_FDIV_SHIFT);
\r
1609 #if defined(_CMU_LFACLKEN0_LESENSE_MASK)
\r
1610 case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1611 ret = lfClkGet(cmuClock_LFA);
\r
1612 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)
\r
1613 >> _CMU_LFAPRESC0_LESENSE_SHIFT;
\r
1617 case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1618 ret = lfClkGet(cmuClock_LFB);
\r
1621 #if defined( _CMU_LFBCLKEN0_LEUART0_MASK )
\r
1622 case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1623 ret = lfClkGet(cmuClock_LFB);
\r
1624 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1625 ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)
\r
1626 >> _CMU_LFBPRESC0_LEUART0_SHIFT;
\r
1627 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1628 ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)
\r
1629 >> _CMU_LFBPRESC0_LEUART0_SHIFT);
\r
1634 #if defined( _CMU_LFBCLKEN0_LEUART1_MASK )
\r
1635 case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1636 ret = lfClkGet(cmuClock_LFB);
\r
1637 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
1638 ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)
\r
1639 >> _CMU_LFBPRESC0_LEUART1_SHIFT;
\r
1640 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1641 ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)
\r
1642 >> _CMU_LFBPRESC0_LEUART1_SHIFT);
\r
1647 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1648 case (CMU_LFE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1649 ret = lfClkGet(cmuClock_LFE);
\r
1653 case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1654 ret = dbgClkGet();
\r
1657 case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1658 ret = auxClkGet();
\r
1661 #if defined(USB_PRESENT)
\r
1662 case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
\r
1663 ret = usbCClkGet();
\r
1677 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1678 /***************************************************************************//**
\r
1680 * Get clock prescaler.
\r
1682 * @param[in] clock
\r
1683 * Clock point to get the prescaler for. Notice that not all clock points
\r
1684 * have a prescaler. Please refer to CMU overview in reference manual.
\r
1687 * The prescaler value of the current clock point. 0 is returned
\r
1688 * if @p clock specifies a clock point without a prescaler.
\r
1689 ******************************************************************************/
\r
1690 uint32_t CMU_ClockPrescGet(CMU_Clock_TypeDef clock)
\r
1692 uint32_t prescReg;
\r
1695 /* Get prescaler register id. */
\r
1696 prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;
\r
1700 case CMU_HFPRESC_REG:
\r
1701 ret = ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
\r
1702 >> _CMU_HFPRESC_PRESC_SHIFT);
\r
1705 case CMU_HFEXPPRESC_REG:
\r
1706 ret = ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)
\r
1707 >> _CMU_HFEXPPRESC_PRESC_SHIFT);
\r
1710 case CMU_HFCLKLEPRESC_REG:
\r
1711 ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)
\r
1712 >> _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);
\r
1715 case CMU_HFPERPRESC_REG:
\r
1716 ret = ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)
\r
1717 >> _CMU_HFPERPRESC_PRESC_SHIFT);
\r
1720 #if defined( _CMU_HFRADIOPRESC_PRESC_MASK )
\r
1721 case CMU_HFRADIOPRESC_REG:
\r
1722 ret = ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)
\r
1723 >> _CMU_HFRADIOPRESC_PRESC_SHIFT);
\r
1727 case CMU_HFCOREPRESC_REG:
\r
1728 ret = ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)
\r
1729 >> _CMU_HFCOREPRESC_PRESC_SHIFT);
\r
1732 case CMU_LFAPRESC0_REG:
\r
1735 #if defined( _CMU_LFAPRESC0_LETIMER0_MASK )
\r
1736 case cmuClock_LETIMER0:
\r
1737 ret = (((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)
\r
1738 >> _CMU_LFAPRESC0_LETIMER0_SHIFT));
\r
1739 /* Convert the exponent to prescaler value. */
\r
1740 ret = CMU_Log2ToDiv(ret) - 1U;
\r
1751 case CMU_LFBPRESC0_REG:
\r
1754 #if defined( _CMU_LFBPRESC0_LEUART0_MASK )
\r
1755 case cmuClock_LEUART0:
\r
1756 ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)
\r
1757 >> _CMU_LFBPRESC0_LEUART0_SHIFT));
\r
1758 /* Convert the exponent to prescaler value. */
\r
1759 ret = CMU_Log2ToDiv(ret) - 1U;
\r
1763 #if defined( _CMU_LFBPRESC0_LEUART1_MASK )
\r
1764 case cmuClock_LEUART1:
\r
1765 ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)
\r
1766 >> _CMU_LFBPRESC0_LEUART1_SHIFT));
\r
1767 /* Convert the exponent to prescaler value. */
\r
1768 ret = CMU_Log2ToDiv(ret) - 1U;
\r
1779 case CMU_LFEPRESC0_REG:
\r
1782 #if defined( RTCC_PRESENT )
\r
1783 case cmuClock_RTCC:
\r
1784 /* No need to compute with LFEPRESC0_RTCC - DIV1 is the only */
\r
1785 /* allowed value. Convert the exponent to prescaler value. */
\r
1786 ret = _CMU_LFEPRESC0_RTCC_DIV1;
\r
1808 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
1809 /***************************************************************************//**
\r
1811 * Set clock prescaler.
\r
1814 * If setting a LF clock prescaler, synchronization into the low frequency
\r
1815 * domain is required. If the same register is modified before a previous
\r
1816 * update has completed, this function will stall until the previous
\r
1817 * synchronization has completed. Please refer to CMU_FreezeEnable() for
\r
1818 * a suggestion on how to reduce stalling time in some use cases.
\r
1820 * @param[in] clock
\r
1821 * Clock point to set prescaler for. Notice that not all clock points
\r
1822 * have a prescaler, please refer to CMU overview in the reference manual.
\r
1824 * @param[in] presc
\r
1825 * The clock prescaler to use.
\r
1826 ******************************************************************************/
\r
1827 void CMU_ClockPrescSet(CMU_Clock_TypeDef clock, CMU_ClkPresc_TypeDef presc)
\r
1830 uint32_t prescReg;
\r
1832 /* Get divisor reg id */
\r
1833 prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;
\r
1837 case CMU_HFPRESC_REG:
\r
1838 EFM_ASSERT(presc < 32U);
\r
1840 CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_PRESC_MASK)
\r
1841 | (presc << _CMU_HFPRESC_PRESC_SHIFT);
\r
1844 case CMU_HFEXPPRESC_REG:
\r
1845 EFM_ASSERT(presc < 32U);
\r
1847 CMU->HFEXPPRESC = (CMU->HFEXPPRESC & ~_CMU_HFEXPPRESC_PRESC_MASK)
\r
1848 | (presc << _CMU_HFEXPPRESC_PRESC_SHIFT);
\r
1851 case CMU_HFCLKLEPRESC_REG:
\r
1852 EFM_ASSERT(presc < 2U);
\r
1854 /* Specifies the clock divider for HFCLKLE. When running at frequencies
\r
1855 * higher than 32 MHz, this must be set to DIV4. */
\r
1856 CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_HFCLKLEPRESC_MASK)
\r
1857 | (presc << _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);
\r
1860 case CMU_HFPERPRESC_REG:
\r
1861 EFM_ASSERT(presc < 512U);
\r
1863 CMU->HFPERPRESC = (CMU->HFPERPRESC & ~_CMU_HFPERPRESC_PRESC_MASK)
\r
1864 | (presc << _CMU_HFPERPRESC_PRESC_SHIFT);
\r
1867 #if defined( _CMU_HFRADIOPRESC_PRESC_MASK )
\r
1868 case CMU_HFRADIOPRESC_REG:
\r
1869 EFM_ASSERT(presc < 512U);
\r
1871 CMU->HFRADIOPRESC = (CMU->HFRADIOPRESC & ~_CMU_HFRADIOPRESC_PRESC_MASK)
\r
1872 | (presc << _CMU_HFRADIOPRESC_PRESC_SHIFT);
\r
1876 case CMU_HFCOREPRESC_REG:
\r
1877 EFM_ASSERT(presc < 512U);
\r
1879 /* Configure worst case wait states for flash access before setting
\r
1880 * the prescaler. */
\r
1881 flashWaitStateControl(CMU_MAX_FREQ_0WS + 1);
\r
1883 CMU->HFCOREPRESC = (CMU->HFCOREPRESC & ~_CMU_HFCOREPRESC_PRESC_MASK)
\r
1884 | (presc << _CMU_HFCOREPRESC_PRESC_SHIFT);
\r
1886 /* Update CMSIS core clock variable */
\r
1887 /* (The function will update the global variable) */
\r
1888 freq = SystemCoreClockGet();
\r
1890 /* Optimize flash access wait state setting for current core clk */
\r
1891 flashWaitStateControl(freq);
\r
1894 case CMU_LFAPRESC0_REG:
\r
1897 #if defined( RTC_PRESENT )
\r
1898 case cmuClock_RTC:
\r
1899 EFM_ASSERT(presc <= 32768U);
\r
1901 /* Convert prescaler value to DIV exponent scale. */
\r
1902 presc = CMU_PrescToLog2(presc);
\r
1904 /* LF register about to be modified require sync. Busy check. */
\r
1905 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1907 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)
\r
1908 | (presc << _CMU_LFAPRESC0_RTC_SHIFT);
\r
1912 #if defined( RTCC_PRESENT )
\r
1913 case cmuClock_RTCC:
\r
1914 #if defined( _CMU_LFEPRESC0_RTCC_MASK )
\r
1915 /* DIV1 is the only accepted value. */
\r
1916 EFM_ASSERT(presc <= 0U);
\r
1918 /* LF register about to be modified require sync. Busy check.. */
\r
1919 syncReg(CMU_SYNCBUSY_LFEPRESC0);
\r
1921 CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)
\r
1922 | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);
\r
1924 EFM_ASSERT(presc <= 32768U);
\r
1926 /* Convert prescaler value to DIV exponent scale. */
\r
1927 presc = CMU_PrescToLog2(presc);
\r
1929 /* LF register about to be modified require sync. Busy check. */
\r
1930 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1932 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTCC_MASK)
\r
1933 | (presc << _CMU_LFAPRESC0_RTCC_SHIFT);
\r
1938 #if defined( _CMU_LFAPRESC0_LETIMER0_MASK )
\r
1939 case cmuClock_LETIMER0:
\r
1940 EFM_ASSERT(presc <= 32768U);
\r
1942 /* Convert prescaler value to DIV exponent scale. */
\r
1943 presc = CMU_PrescToLog2(presc);
\r
1945 /* LF register about to be modified require sync. Busy check. */
\r
1946 syncReg(CMU_SYNCBUSY_LFAPRESC0);
\r
1948 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)
\r
1949 | (presc << _CMU_LFAPRESC0_LETIMER0_SHIFT);
\r
1959 case CMU_LFBPRESC0_REG:
\r
1962 #if defined( _CMU_LFBPRESC0_LEUART0_MASK )
\r
1963 case cmuClock_LEUART0:
\r
1964 EFM_ASSERT(presc <= 8U);
\r
1966 /* Convert prescaler value to DIV exponent scale. */
\r
1967 presc = CMU_PrescToLog2(presc);
\r
1969 /* LF register about to be modified require sync. Busy check. */
\r
1970 syncReg(CMU_SYNCBUSY_LFBPRESC0);
\r
1972 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)
\r
1973 | (presc << _CMU_LFBPRESC0_LEUART0_SHIFT);
\r
1977 #if defined( _CMU_LFBPRESC0_LEUART1_MASK )
\r
1978 case cmuClock_LEUART1:
\r
1979 EFM_ASSERT(presc <= 8U);
\r
1981 /* Convert prescaler value to DIV exponent scale. */
\r
1982 presc = CMU_PrescToLog2(presc);
\r
1984 /* LF register about to be modified require sync. Busy check. */
\r
1985 syncReg(CMU_SYNCBUSY_LFBPRESC0);
\r
1987 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)
\r
1988 | (presc << _CMU_LFBPRESC0_LEUART1_SHIFT);
\r
1998 case CMU_LFEPRESC0_REG:
\r
2001 #if defined( _CMU_LFEPRESC0_RTCC_MASK )
\r
2002 case cmuClock_RTCC:
\r
2003 EFM_ASSERT(presc <= 0U);
\r
2005 /* LF register about to be modified require sync. Busy check. */
\r
2006 syncReg(CMU_SYNCBUSY_LFEPRESC0);
\r
2008 CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)
\r
2009 | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);
\r
2027 /***************************************************************************//**
\r
2029 * Get currently selected reference clock used for a clock branch.
\r
2031 * @param[in] clock
\r
2032 * Clock branch to fetch selected ref. clock for. One of:
\r
2033 * @li #cmuClock_HF
\r
2034 * @li #cmuClock_LFA
\r
2035 * @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO
\r
2036 * @li #cmuClock_LFC
\r
2037 * @endif @if _SILICON_LABS_32B_PLATFORM_2
\r
2038 * @li #cmuClock_LFE
\r
2040 * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT
\r
2041 * @li #cmuClock_USBC
\r
2045 * Reference clock used for clocking selected branch, #cmuSelect_Error if
\r
2046 * invalid @p clock provided.
\r
2047 ******************************************************************************/
\r
2048 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
\r
2050 CMU_Select_TypeDef ret = cmuSelect_Disabled;
\r
2053 selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
\r
2057 case CMU_HFCLKSEL_REG:
\r
2058 #if defined( _CMU_HFCLKSEL_HF_MASK )
\r
2059 switch (CMU->HFCLKSEL & _CMU_HFCLKSEL_HF_MASK)
\r
2061 case CMU_HFCLKSEL_HF_LFXO:
\r
2062 ret = cmuSelect_LFXO;
\r
2065 case CMU_HFCLKSEL_HF_LFRCO:
\r
2066 ret = cmuSelect_LFRCO;
\r
2069 case CMU_HFCLKSEL_HF_HFXO:
\r
2070 ret = cmuSelect_HFXO;
\r
2074 ret = cmuSelect_HFRCO;
\r
2078 switch (CMU->STATUS
\r
2079 & (CMU_STATUS_HFRCOSEL
\r
2080 | CMU_STATUS_HFXOSEL
\r
2081 | CMU_STATUS_LFRCOSEL
\r
2082 #if defined( CMU_STATUS_USHFRCODIV2SEL )
\r
2083 | CMU_STATUS_USHFRCODIV2SEL
\r
2085 | CMU_STATUS_LFXOSEL))
\r
2087 case CMU_STATUS_LFXOSEL:
\r
2088 ret = cmuSelect_LFXO;
\r
2091 case CMU_STATUS_LFRCOSEL:
\r
2092 ret = cmuSelect_LFRCO;
\r
2095 case CMU_STATUS_HFXOSEL:
\r
2096 ret = cmuSelect_HFXO;
\r
2099 #if defined( CMU_STATUS_USHFRCODIV2SEL )
\r
2100 case CMU_STATUS_USHFRCODIV2SEL:
\r
2101 ret = cmuSelect_USHFRCODIV2;
\r
2106 ret = cmuSelect_HFRCO;
\r
2112 case CMU_LFACLKSEL_REG:
\r
2113 #if defined( _CMU_LFCLKSEL_MASK )
\r
2114 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)
\r
2116 case CMU_LFCLKSEL_LFA_LFRCO:
\r
2117 ret = cmuSelect_LFRCO;
\r
2120 case CMU_LFCLKSEL_LFA_LFXO:
\r
2121 ret = cmuSelect_LFXO;
\r
2124 #if defined( CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )
\r
2125 case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
\r
2126 ret = cmuSelect_CORELEDIV2;
\r
2131 #if defined( CMU_LFCLKSEL_LFAE )
\r
2132 if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)
\r
2134 ret = cmuSelect_ULFRCO;
\r
2138 ret = cmuSelect_Disabled;
\r
2142 #endif /* _CMU_LFCLKSEL_MASK */
\r
2144 #if defined( _CMU_LFACLKSEL_MASK )
\r
2145 switch (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK)
\r
2147 case CMU_LFACLKSEL_LFA_LFRCO:
\r
2148 ret = cmuSelect_LFRCO;
\r
2151 case CMU_LFACLKSEL_LFA_LFXO:
\r
2152 ret = cmuSelect_LFXO;
\r
2155 case CMU_LFACLKSEL_LFA_ULFRCO:
\r
2156 ret = cmuSelect_ULFRCO;
\r
2159 #if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )
\r
2160 case CMU_LFACLKSEL_LFA_HFCLKLE:
\r
2161 ret = cmuSelect_HFCLKLE;
\r
2166 ret = cmuSelect_Disabled;
\r
2172 case CMU_LFBCLKSEL_REG:
\r
2173 #if defined( _CMU_LFCLKSEL_MASK )
\r
2174 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)
\r
2176 case CMU_LFCLKSEL_LFB_LFRCO:
\r
2177 ret = cmuSelect_LFRCO;
\r
2180 case CMU_LFCLKSEL_LFB_LFXO:
\r
2181 ret = cmuSelect_LFXO;
\r
2184 #if defined( CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 )
\r
2185 case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
\r
2186 ret = cmuSelect_CORELEDIV2;
\r
2190 #if defined( CMU_LFCLKSEL_LFB_HFCLKLE )
\r
2191 case CMU_LFCLKSEL_LFB_HFCLKLE:
\r
2192 ret = cmuSelect_HFCLKLE;
\r
2197 #if defined( CMU_LFCLKSEL_LFBE )
\r
2198 if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)
\r
2200 ret = cmuSelect_ULFRCO;
\r
2204 ret = cmuSelect_Disabled;
\r
2208 #endif /* _CMU_LFCLKSEL_MASK */
\r
2210 #if defined( _CMU_LFBCLKSEL_MASK )
\r
2211 switch (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK)
\r
2213 case CMU_LFBCLKSEL_LFB_LFRCO:
\r
2214 ret = cmuSelect_LFRCO;
\r
2217 case CMU_LFBCLKSEL_LFB_LFXO:
\r
2218 ret = cmuSelect_LFXO;
\r
2221 case CMU_LFBCLKSEL_LFB_ULFRCO:
\r
2222 ret = cmuSelect_ULFRCO;
\r
2225 case CMU_LFBCLKSEL_LFB_HFCLKLE:
\r
2226 ret = cmuSelect_HFCLKLE;
\r
2230 ret = cmuSelect_Disabled;
\r
2236 #if defined( _CMU_LFCLKSEL_LFC_MASK )
\r
2237 case CMU_LFCCLKSEL_REG:
\r
2238 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)
\r
2240 case CMU_LFCLKSEL_LFC_LFRCO:
\r
2241 ret = cmuSelect_LFRCO;
\r
2244 case CMU_LFCLKSEL_LFC_LFXO:
\r
2245 ret = cmuSelect_LFXO;
\r
2249 ret = cmuSelect_Disabled;
\r
2255 #if defined( _CMU_LFECLKSEL_LFE_MASK )
\r
2256 case CMU_LFECLKSEL_REG:
\r
2257 switch (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK)
\r
2259 case CMU_LFECLKSEL_LFE_LFRCO:
\r
2260 ret = cmuSelect_LFRCO;
\r
2263 case CMU_LFECLKSEL_LFE_LFXO:
\r
2264 ret = cmuSelect_LFXO;
\r
2267 case CMU_LFECLKSEL_LFE_ULFRCO:
\r
2268 ret = cmuSelect_ULFRCO;
\r
2271 #if defined ( _CMU_LFECLKSEL_LFE_HFCLKLE )
\r
2272 case CMU_LFECLKSEL_LFE_HFCLKLE:
\r
2273 ret = cmuSelect_HFCLKLE;
\r
2278 ret = cmuSelect_Disabled;
\r
2282 #endif /* CMU_LFECLKSEL_REG */
\r
2284 case CMU_DBGCLKSEL_REG:
\r
2285 #if defined( _CMU_DBGCLKSEL_DBG_MASK )
\r
2286 switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)
\r
2288 case CMU_DBGCLKSEL_DBG_HFCLK:
\r
2289 ret = cmuSelect_HFCLK;
\r
2292 case CMU_DBGCLKSEL_DBG_AUXHFRCO:
\r
2293 ret = cmuSelect_AUXHFRCO;
\r
2297 ret = cmuSelect_AUXHFRCO;
\r
2298 #endif /* CMU_DBGCLKSEL_DBG */
\r
2300 #if defined( _CMU_CTRL_DBGCLK_MASK )
\r
2301 switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)
\r
2303 case CMU_CTRL_DBGCLK_AUXHFRCO:
\r
2304 ret = cmuSelect_AUXHFRCO;
\r
2307 case CMU_CTRL_DBGCLK_HFCLK:
\r
2308 ret = cmuSelect_HFCLK;
\r
2312 ret = cmuSelect_AUXHFRCO;
\r
2317 #if defined( USB_PRESENT )
\r
2318 case CMU_USBCCLKSEL_REG:
\r
2319 switch (CMU->STATUS
\r
2320 & (CMU_STATUS_USBCLFXOSEL
\r
2321 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
\r
2322 | CMU_STATUS_USBCHFCLKSEL
\r
2324 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
\r
2325 | CMU_STATUS_USBCUSHFRCOSEL
\r
2327 | CMU_STATUS_USBCLFRCOSEL))
\r
2329 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
\r
2330 case CMU_STATUS_USBCHFCLKSEL:
\r
2331 ret = cmuSelect_HFCLK;
\r
2335 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
\r
2336 case CMU_STATUS_USBCUSHFRCOSEL:
\r
2337 ret = cmuSelect_USHFRCO;
\r
2341 case CMU_STATUS_USBCLFXOSEL:
\r
2342 ret = cmuSelect_LFXO;
\r
2345 case CMU_STATUS_USBCLFRCOSEL:
\r
2346 ret = cmuSelect_LFRCO;
\r
2350 ret = cmuSelect_Disabled;
\r
2358 ret = cmuSelect_Error;
\r
2366 /***************************************************************************//**
\r
2368 * Select reference clock/oscillator used for a clock branch.
\r
2371 * Notice that if a selected reference is not enabled prior to selecting its
\r
2372 * use, it will be enabled, and this function will wait for the selected
\r
2373 * oscillator to be stable. It will however NOT be disabled if another
\r
2374 * reference clock is selected later.
\r
2376 * This feature is particularly important if selecting a new reference
\r
2377 * clock for the clock branch clocking the core, otherwise the system
\r
2380 * @param[in] clock
\r
2381 * Clock branch to select reference clock for. One of:
\r
2382 * @li #cmuClock_HF
\r
2383 * @li #cmuClock_LFA
\r
2384 * @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO
\r
2385 * @li #cmuClock_LFC
\r
2386 * @endif @if _SILICON_LABS_32B_PLATFORM_2
\r
2387 * @li #cmuClock_LFE
\r
2389 * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT
\r
2390 * @li #cmuClock_USBC
\r
2394 * Reference selected for clocking, please refer to reference manual for
\r
2395 * for details on which reference is available for a specific clock branch.
\r
2396 * @li #cmuSelect_HFRCO
\r
2397 * @li #cmuSelect_LFRCO
\r
2398 * @li #cmuSelect_HFXO
\r
2399 * @li #cmuSelect_LFXO
\r
2400 * @li #cmuSelect_CORELEDIV2
\r
2401 * @li #cmuSelect_AUXHFRCO
\r
2402 * @li #cmuSelect_HFCLK @ifnot DOXYDOC_EFM32_GECKO_FAMILY
\r
2403 * @li #cmuSelect_ULFRCO
\r
2405 ******************************************************************************/
\r
2406 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
\r
2408 uint32_t select = cmuOsc_HFRCO;
\r
2409 CMU_Osc_TypeDef osc = cmuOsc_HFRCO;
\r
2412 uint32_t selRegId;
\r
2413 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2414 volatile uint32_t *selReg = NULL;
\r
2416 #if defined( CMU_LFCLKSEL_LFAE_ULFRCO )
\r
2417 uint32_t lfExtended = 0;
\r
2420 selRegId = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
\r
2424 case CMU_HFCLKSEL_REG:
\r
2427 case cmuSelect_LFXO:
\r
2428 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2429 select = CMU_HFCLKSEL_HF_LFXO;
\r
2430 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2431 select = CMU_CMD_HFCLKSEL_LFXO;
\r
2433 osc = cmuOsc_LFXO;
\r
2436 case cmuSelect_LFRCO:
\r
2437 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2438 select = CMU_HFCLKSEL_HF_LFRCO;
\r
2439 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2440 select = CMU_CMD_HFCLKSEL_LFRCO;
\r
2442 osc = cmuOsc_LFRCO;
\r
2445 case cmuSelect_HFXO:
\r
2446 osc = cmuOsc_HFXO;
\r
2447 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2448 select = CMU_HFCLKSEL_HF_HFXO;
\r
2449 /* Adjust HFXO buffer current for high frequencies, */
\r
2450 /* enable WSHFLE for frequencies above 32MHz. */
\r
2451 if (SystemHFXOClockGet() > 32000000)
\r
2453 CMU->CTRL |= CMU_CTRL_WSHFLE;
\r
2455 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2456 select = CMU_CMD_HFCLKSEL_HFXO;
\r
2457 #if defined( CMU_CTRL_HFLE )
\r
2458 /* Adjust HFXO buffer current for high frequencies, */
\r
2459 /* enable HFLE for frequencies above CMU_MAX_FREQ_HFLE. */
\r
2460 if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE())
\r
2462 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)
\r
2463 | CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ
\r
2464 /* Must have HFLE enabled to access some LE peripherals >=32MHz */
\r
2467 /* Set HFLE and DIV4 factor for peripheral clock if HFCORE */
\r
2468 /* clock for LE is enabled. */
\r
2469 if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)
\r
2471 BUS_RegBitWrite(&CMU->HFCORECLKDIV,
\r
2472 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
\r
2477 /* This can happen if the user configures the EFM32_HFXO_FREQ to */
\r
2478 /* use another oscillator frequency */
\r
2479 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)
\r
2480 | CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;
\r
2486 case cmuSelect_HFRCO:
\r
2487 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2488 select = CMU_HFCLKSEL_HF_HFRCO;
\r
2489 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2490 select = CMU_CMD_HFCLKSEL_HFRCO;
\r
2492 osc = cmuOsc_HFRCO;
\r
2495 #if defined( CMU_CMD_HFCLKSEL_USHFRCODIV2 )
\r
2496 case cmuSelect_USHFRCODIV2:
\r
2497 select = CMU_CMD_HFCLKSEL_USHFRCODIV2;
\r
2498 osc = cmuOsc_USHFRCO;
\r
2502 #if defined( CMU_LFCLKSEL_LFAE_ULFRCO ) || defined( CMU_LFACLKSEL_LFA_ULFRCO )
\r
2503 case cmuSelect_ULFRCO:
\r
2504 /* ULFRCO cannot be used as HFCLK */
\r
2514 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2515 CMU_OscillatorEnable(osc, true, true);
\r
2517 /* Configure worst case wait states for flash access before selecting */
\r
2518 flashWaitStateMax();
\r
2520 /* Switch to selected oscillator */
\r
2521 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2522 CMU->HFCLKSEL = select;
\r
2523 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2524 CMU->CMD = select;
\r
2527 /* Keep EMU module informed */
\r
2528 EMU_UpdateOscConfig();
\r
2530 /* Update CMSIS core clock variable */
\r
2531 /* (The function will update the global variable) */
\r
2532 freq = SystemCoreClockGet();
\r
2534 /* Optimize flash access wait state setting for currently selected core clk */
\r
2535 flashWaitStateControl(freq);
\r
2538 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
2539 case CMU_LFACLKSEL_REG:
\r
2540 selReg = (selReg == NULL) ? &CMU->LFACLKSEL : selReg;
\r
2541 #if !defined( _CMU_LFACLKSEL_LFA_HFCLKLE )
\r
2542 /* HFCLKCLE can not be used as LFACLK */
\r
2543 EFM_ASSERT(ref != cmuSelect_HFCLKLE);
\r
2545 case CMU_LFECLKSEL_REG:
\r
2546 selReg = (selReg == NULL) ? &CMU->LFECLKSEL : selReg;
\r
2547 #if !defined( _CMU_LFECLKSEL_LFE_HFCLKLE )
\r
2548 /* HFCLKCLE can not be used as LFECLK */
\r
2549 EFM_ASSERT(ref != cmuSelect_HFCLKLE);
\r
2551 case CMU_LFBCLKSEL_REG:
\r
2552 selReg = (selReg == NULL) ? &CMU->LFBCLKSEL : selReg;
\r
2555 case cmuSelect_Disabled:
\r
2556 tmp = _CMU_LFACLKSEL_LFA_DISABLED;
\r
2559 case cmuSelect_LFXO:
\r
2560 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2561 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
\r
2562 tmp = _CMU_LFACLKSEL_LFA_LFXO;
\r
2565 case cmuSelect_LFRCO:
\r
2566 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2567 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
\r
2568 tmp = _CMU_LFACLKSEL_LFA_LFRCO;
\r
2571 case cmuSelect_HFCLKLE:
\r
2572 /* Ensure HFCORE to LE clocking is enabled */
\r
2573 BUS_RegBitWrite(&CMU->HFBUSCLKEN0, _CMU_HFBUSCLKEN0_LE_SHIFT, 1);
\r
2574 tmp = _CMU_LFBCLKSEL_LFB_HFCLKLE;
\r
2576 /* If core frequency is > 32MHz enable WSHFLE */
\r
2577 freq = SystemCoreClockGet();
\r
2578 if (freq > 32000000U)
\r
2580 /* Enable CMU HFLE */
\r
2581 BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_WSHFLE_SHIFT, 1);
\r
2583 /* Enable DIV4 factor for peripheral clock */
\r
2584 BUS_RegBitWrite(&CMU->HFPRESC, _CMU_HFPRESC_HFCLKLEPRESC_SHIFT, 1);
\r
2588 case cmuSelect_ULFRCO:
\r
2589 /* ULFRCO is always on, there is no need to enable it. */
\r
2590 tmp = _CMU_LFACLKSEL_LFA_ULFRCO;
\r
2600 #elif defined( _SILICON_LABS_32B_PLATFORM_1 )
\r
2601 case CMU_LFACLKSEL_REG:
\r
2602 case CMU_LFBCLKSEL_REG:
\r
2605 case cmuSelect_Disabled:
\r
2606 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
\r
2609 case cmuSelect_LFXO:
\r
2610 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2611 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
\r
2612 tmp = _CMU_LFCLKSEL_LFA_LFXO;
\r
2615 case cmuSelect_LFRCO:
\r
2616 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2617 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
\r
2618 tmp = _CMU_LFCLKSEL_LFA_LFRCO;
\r
2621 case cmuSelect_CORELEDIV2:
\r
2622 /* Ensure HFCORE to LE clocking is enabled */
\r
2623 BUS_RegBitWrite(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);
\r
2624 tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
\r
2625 #if defined( CMU_CTRL_HFLE )
\r
2626 /* If core frequency is higher than CMU_MAX_FREQ_HFLE on
\r
2627 Giant/Leopard/Wonder, enable HFLE and DIV4. */
\r
2628 freq = SystemCoreClockGet();
\r
2629 if(freq > CMU_MAX_FREQ_HFLE())
\r
2631 /* Enable CMU HFLE */
\r
2632 BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);
\r
2634 /* Enable DIV4 factor for peripheral clock */
\r
2635 BUS_RegBitWrite(&CMU->HFCORECLKDIV,
\r
2636 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
\r
2641 #if defined( CMU_LFCLKSEL_LFAE_ULFRCO )
\r
2642 case cmuSelect_ULFRCO:
\r
2643 /* ULFRCO is always enabled */
\r
2644 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
\r
2650 /* Illegal clock source for LFA/LFB selected */
\r
2655 /* Apply select */
\r
2656 if (selRegId == CMU_LFACLKSEL_REG)
\r
2658 #if defined( _CMU_LFCLKSEL_LFAE_MASK )
\r
2659 CMU->LFCLKSEL = (CMU->LFCLKSEL
\r
2660 & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK))
\r
2661 | (tmp << _CMU_LFCLKSEL_LFA_SHIFT)
\r
2662 | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);
\r
2664 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK)
\r
2665 | (tmp << _CMU_LFCLKSEL_LFA_SHIFT);
\r
2670 #if defined( _CMU_LFCLKSEL_LFBE_MASK )
\r
2671 CMU->LFCLKSEL = (CMU->LFCLKSEL
\r
2672 & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK))
\r
2673 | (tmp << _CMU_LFCLKSEL_LFB_SHIFT)
\r
2674 | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);
\r
2676 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK)
\r
2677 | (tmp << _CMU_LFCLKSEL_LFB_SHIFT);
\r
2682 #if defined( _CMU_LFCLKSEL_LFC_MASK )
\r
2683 case CMU_LFCCLKSEL_REG:
\r
2686 case cmuSelect_Disabled:
\r
2687 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
\r
2690 case cmuSelect_LFXO:
\r
2691 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2692 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
\r
2693 tmp = _CMU_LFCLKSEL_LFC_LFXO;
\r
2696 case cmuSelect_LFRCO:
\r
2697 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2698 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
\r
2699 tmp = _CMU_LFCLKSEL_LFC_LFRCO;
\r
2703 /* Illegal clock source for LFC selected */
\r
2708 /* Apply select */
\r
2709 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK)
\r
2710 | (tmp << _CMU_LFCLKSEL_LFC_SHIFT);
\r
2715 #if defined( CMU_DBGCLKSEL_DBG ) || defined( CMU_CTRL_DBGCLK )
\r
2716 case CMU_DBGCLKSEL_REG:
\r
2719 #if defined( CMU_DBGCLKSEL_DBG )
\r
2720 case cmuSelect_AUXHFRCO:
\r
2721 /* Select AUXHFRCO as debug clock */
\r
2722 CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_AUXHFRCO;
\r
2725 case cmuSelect_HFCLK:
\r
2726 /* Select divided HFCLK as debug clock */
\r
2727 CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_HFCLK;
\r
2731 #if defined( CMU_CTRL_DBGCLK )
\r
2732 case cmuSelect_AUXHFRCO:
\r
2733 /* Select AUXHFRCO as debug clock */
\r
2734 CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))
\r
2735 | CMU_CTRL_DBGCLK_AUXHFRCO;
\r
2738 case cmuSelect_HFCLK:
\r
2739 /* Select divided HFCLK as debug clock */
\r
2740 CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))
\r
2741 | CMU_CTRL_DBGCLK_HFCLK;
\r
2746 /* Illegal clock source for debug selected */
\r
2753 #if defined(USB_PRESENT)
\r
2754 case CMU_USBCCLKSEL_REG:
\r
2757 case cmuSelect_LFXO:
\r
2758 /* Select LFXO as clock source for USB, can only be used in sleep mode */
\r
2759 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2760 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
\r
2762 /* Switch oscillator */
\r
2763 CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
\r
2765 /* Wait until clock is activated */
\r
2766 while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0)
\r
2771 case cmuSelect_LFRCO:
\r
2772 /* Select LFRCO as clock source for USB, can only be used in sleep mode */
\r
2773 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2774 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
\r
2776 /* Switch oscillator */
\r
2777 CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
\r
2779 /* Wait until clock is activated */
\r
2780 while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0)
\r
2785 #if defined( CMU_STATUS_USBCHFCLKSEL )
\r
2786 case cmuSelect_HFCLK:
\r
2787 /* Select undivided HFCLK as clock source for USB */
\r
2788 /* Oscillator must already be enabled to avoid a core lockup */
\r
2789 CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
\r
2790 /* Wait until clock is activated */
\r
2791 while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0)
\r
2797 #if defined( CMU_CMD_USBCCLKSEL_USHFRCO )
\r
2798 case cmuSelect_USHFRCO:
\r
2799 /* Select USHFRCO as clock source for USB */
\r
2800 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
\r
2801 CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);
\r
2803 /* Switch oscillator */
\r
2804 CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
\r
2806 /* Wait until clock is activated */
\r
2807 while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0)
\r
2814 /* Illegal clock source for USB */
\r
2828 /**************************************************************************//**
\r
2830 * CMU low frequency register synchronization freeze control.
\r
2833 * Some CMU registers requires synchronization into the low frequency (LF)
\r
2834 * domain. The freeze feature allows for several such registers to be
\r
2835 * modified before passing them to the LF domain simultaneously (which
\r
2836 * takes place when the freeze mode is disabled).
\r
2838 * Another usage scenario of this feature, is when using an API (such
\r
2839 * as the CMU API) for modifying several bit fields consecutively in the
\r
2840 * same register. If freeze mode is enabled during this sequence, stalling
\r
2844 * When enabling freeze mode, this function will wait for all current
\r
2845 * ongoing CMU synchronization to LF domain to complete (Normally
\r
2846 * synchronization will not be in progress.) However for this reason, when
\r
2847 * using freeze mode, modifications of registers requiring LF synchronization
\r
2848 * should be done within one freeze enable/disable block to avoid unecessary
\r
2851 * @param[in] enable
\r
2852 * @li true - enable freeze, modified registers are not propagated to the
\r
2854 * @li false - disable freeze, modified registers are propagated to LF
\r
2856 *****************************************************************************/
\r
2857 void CMU_FreezeEnable(bool enable)
\r
2861 /* Wait for any ongoing LF synchronization to complete. This is just to */
\r
2862 /* protect against the rare case when a user */
\r
2863 /* - modifies a register requiring LF sync */
\r
2864 /* - then enables freeze before LF sync completed */
\r
2865 /* - then modifies the same register again */
\r
2866 /* since modifying a register while it is in sync progress should be */
\r
2868 while (CMU->SYNCBUSY)
\r
2872 CMU->FREEZE = CMU_FREEZE_REGFREEZE;
\r
2881 #if defined( _CMU_HFRCOCTRL_BAND_MASK )
\r
2882 /***************************************************************************//**
\r
2884 * Get HFRCO band in use.
\r
2887 * HFRCO band in use.
\r
2888 ******************************************************************************/
\r
2889 CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)
\r
2891 return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
\r
2892 >> _CMU_HFRCOCTRL_BAND_SHIFT);
\r
2894 #endif /* _CMU_HFRCOCTRL_BAND_MASK */
\r
2897 #if defined( _CMU_HFRCOCTRL_BAND_MASK )
\r
2898 /***************************************************************************//**
\r
2900 * Set HFRCO band and the tuning value based on the value in the calibration
\r
2901 * table made during production.
\r
2904 * HFRCO band to activate.
\r
2905 ******************************************************************************/
\r
2906 void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)
\r
2910 CMU_Select_TypeDef osc;
\r
2912 /* Read tuning value from calibration table */
\r
2915 case cmuHFRCOBand_1MHz:
\r
2916 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK)
\r
2917 >> _DEVINFO_HFRCOCAL0_BAND1_SHIFT;
\r
2920 case cmuHFRCOBand_7MHz:
\r
2921 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK)
\r
2922 >> _DEVINFO_HFRCOCAL0_BAND7_SHIFT;
\r
2925 case cmuHFRCOBand_11MHz:
\r
2926 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK)
\r
2927 >> _DEVINFO_HFRCOCAL0_BAND11_SHIFT;
\r
2930 case cmuHFRCOBand_14MHz:
\r
2931 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK)
\r
2932 >> _DEVINFO_HFRCOCAL0_BAND14_SHIFT;
\r
2935 case cmuHFRCOBand_21MHz:
\r
2936 tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK)
\r
2937 >> _DEVINFO_HFRCOCAL1_BAND21_SHIFT;
\r
2940 #if defined( _CMU_HFRCOCTRL_BAND_28MHZ )
\r
2941 case cmuHFRCOBand_28MHz:
\r
2942 tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK)
\r
2943 >> _DEVINFO_HFRCOCAL1_BAND28_SHIFT;
\r
2952 /* If HFRCO is used for core clock, we have to consider flash access WS. */
\r
2953 osc = CMU_ClockSelectGet(cmuClock_HF);
\r
2954 if (osc == cmuSelect_HFRCO)
\r
2956 /* Configure worst case wait states for flash access before setting divider */
\r
2957 flashWaitStateMax();
\r
2960 /* Set band/tuning */
\r
2961 CMU->HFRCOCTRL = (CMU->HFRCOCTRL &
\r
2962 ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK))
\r
2963 | (band << _CMU_HFRCOCTRL_BAND_SHIFT)
\r
2964 | (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);
\r
2966 /* If HFRCO is used for core clock, optimize flash WS */
\r
2967 if (osc == cmuSelect_HFRCO)
\r
2969 /* Update CMSIS core clock variable and get current core clock */
\r
2970 /* (The function will update the global variable) */
\r
2971 /* NOTE! We need at least 21 cycles before setting zero wait state to flash */
\r
2972 /* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */
\r
2973 freq = SystemCoreClockGet();
\r
2975 /* Optimize flash access wait state setting for current core clk */
\r
2976 flashWaitStateControl(freq);
\r
2979 #endif /* _CMU_HFRCOCTRL_BAND_MASK */
\r
2982 #if defined( _CMU_HFRCOCTRL_FREQRANGE_MASK )
\r
2983 /**************************************************************************//**
\r
2985 * Get a pointer to the HFRCO frequency calibration word in DEVINFO
\r
2991 * HFRCO calibration word for a given frequency
\r
2992 *****************************************************************************/
\r
2993 static uint32_t CMU_HFRCODevinfoGet(CMU_HFRCOFreq_TypeDef freq)
\r
2997 /* 1, 2 and 4MHz share the same calibration word */
\r
2998 case cmuHFRCOFreq_1M0Hz:
\r
2999 case cmuHFRCOFreq_2M0Hz:
\r
3000 case cmuHFRCOFreq_4M0Hz:
\r
3001 return DEVINFO->HFRCOCAL0;
\r
3003 case cmuHFRCOFreq_7M0Hz:
\r
3004 return DEVINFO->HFRCOCAL3;
\r
3006 case cmuHFRCOFreq_13M0Hz:
\r
3007 return DEVINFO->HFRCOCAL6;
\r
3009 case cmuHFRCOFreq_16M0Hz:
\r
3010 return DEVINFO->HFRCOCAL7;
\r
3012 case cmuHFRCOFreq_19M0Hz:
\r
3013 return DEVINFO->HFRCOCAL8;
\r
3015 case cmuHFRCOFreq_26M0Hz:
\r
3016 return DEVINFO->HFRCOCAL10;
\r
3018 case cmuHFRCOFreq_32M0Hz:
\r
3019 return DEVINFO->HFRCOCAL11;
\r
3021 case cmuHFRCOFreq_38M0Hz:
\r
3022 return DEVINFO->HFRCOCAL12;
\r
3024 default: /* cmuHFRCOFreq_UserDefined */
\r
3030 /***************************************************************************//**
\r
3032 * Get HFRCO frequency enumeration in use
\r
3035 * HFRCO frequency enumeration in use
\r
3036 ******************************************************************************/
\r
3037 CMU_HFRCOFreq_TypeDef CMU_HFRCOFreqGet(void)
\r
3039 return (CMU_HFRCOFreq_TypeDef)SystemHfrcoFreq;
\r
3043 /***************************************************************************//**
\r
3045 * Set HFRCO calibration for the selected target frequency
\r
3048 * HFRCO frequency band to set
\r
3049 ******************************************************************************/
\r
3050 void CMU_HFRCOFreqSet(CMU_HFRCOFreq_TypeDef freq)
\r
3054 /* Get DEVINFO index, set CMSIS frequency SystemHfrcoFreq */
\r
3055 freqCal = CMU_HFRCODevinfoGet(freq);
\r
3056 EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));
\r
3057 SystemHfrcoFreq = (uint32_t)freq;
\r
3059 /* Set max wait-states while changing core clock */
\r
3060 if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)
\r
3062 flashWaitStateMax();
\r
3065 /* Wait for any previous sync to complete, and then set calibration data
\r
3066 for the selected frequency. */
\r
3067 while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT));
\r
3069 /* Check for valid calibration data */
\r
3070 EFM_ASSERT(freqCal != UINT_MAX);
\r
3072 /* Set divider in HFRCOCTRL for 1, 2 and 4MHz */
\r
3075 case cmuHFRCOFreq_1M0Hz:
\r
3076 freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)
\r
3077 | CMU_HFRCOCTRL_CLKDIV_DIV4;
\r
3080 case cmuHFRCOFreq_2M0Hz:
\r
3081 freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)
\r
3082 | CMU_HFRCOCTRL_CLKDIV_DIV2;
\r
3085 case cmuHFRCOFreq_4M0Hz:
\r
3086 freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)
\r
3087 | CMU_HFRCOCTRL_CLKDIV_DIV1;
\r
3093 CMU->HFRCOCTRL = freqCal;
\r
3095 /* Optimize flash access wait-state configuration for this frequency, */
\r
3096 /* if HFRCO is reference for core clock. */
\r
3097 if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)
\r
3099 flashWaitStateControl((uint32_t)freq);
\r
3102 #endif /* _CMU_HFRCOCTRL_FREQRANGE_MASK */
\r
3104 #if defined( _CMU_HFRCOCTRL_SUDELAY_MASK )
\r
3105 /***************************************************************************//**
\r
3107 * Get the HFRCO startup delay.
\r
3110 * Please refer to the reference manual for further details.
\r
3113 * The startup delay in use.
\r
3114 ******************************************************************************/
\r
3115 uint32_t CMU_HFRCOStartupDelayGet(void)
\r
3117 return (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK)
\r
3118 >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;
\r
3122 /***************************************************************************//**
\r
3124 * Set the HFRCO startup delay.
\r
3127 * Please refer to the reference manual for further details.
\r
3129 * @param[in] delay
\r
3130 * The startup delay to set (<= 31).
\r
3131 ******************************************************************************/
\r
3132 void CMU_HFRCOStartupDelaySet(uint32_t delay)
\r
3134 EFM_ASSERT(delay <= 31);
\r
3136 delay &= _CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;
\r
3137 CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK))
\r
3138 | (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);
\r
3143 #if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )
\r
3144 /***************************************************************************//**
\r
3146 * Enable or disable HFXO autostart
\r
3148 * @param[in] enRACStartSel
\r
3149 * If true, HFXO is automatically started and selected upon RAC wakeup.
\r
3150 * If false, HFXO is not started or selected automatically upon RAC wakeup.
\r
3152 * @param[in] enEM0EM1Start
\r
3153 * If true, HFXO is automatically started upon entering EM0/EM1 entry from
\r
3154 * EM2/EM3. HFXO selection has to be handled by the user.
\r
3155 * If false, HFXO is not started automatically when entering EM0/EM1.
\r
3157 * @param[in] enEM0EM1StartSel
\r
3158 * If true, HFXO is automatically started and immediately selected upon
\r
3159 * entering EM0/EM1 entry from EM2/EM3. Note that this option stalls the use of
\r
3160 * HFSRCCLK until HFXO becomes ready.
\r
3161 * If false, HFXO is not started or selected automatically when entering
\r
3163 ******************************************************************************/
\r
3164 void CMU_HFXOAutostartEnable(bool enRACStartSel,
\r
3165 bool enEM0EM1Start,
\r
3166 bool enEM0EM1StartSel)
\r
3168 uint32_t hfxoCtrl;
\r
3169 hfxoCtrl = CMU->HFXOCTRL & ~(_CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK
\r
3170 | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK
\r
3171 | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK);
\r
3173 hfxoCtrl |= (enRACStartSel ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)
\r
3174 | (enEM0EM1Start ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)
\r
3175 | (enEM0EM1StartSel ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0);
\r
3177 CMU->HFXOCTRL = hfxoCtrl;
\r
3179 #endif /* _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK */
\r
3182 #if defined( _CMU_HFXOCTRL_MASK )
\r
3183 /**************************************************************************//**
\r
3185 * Set HFXO control registers
\r
3188 * HFXO configuration should be obtained from a configuration tool,
\r
3189 * app note or xtal datasheet. This function disables the HFXO to ensure
\r
3190 * a valid state before update.
\r
3192 * @param[in] hfxoInit
\r
3193 * HFXO setup parameters
\r
3194 *****************************************************************************/
\r
3195 void CMU_HFXOInit(CMU_HFXOInit_TypeDef *hfxoInit)
\r
3200 /* Do not disable HFXO if it is currently selected as HF/Core clock */
\r
3201 EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_HFXO);
\r
3203 /* HFXO must be disabled before reconfiguration */
\r
3204 CMU_OscillatorEnable(cmuOsc_HFXO, false, false);
\r
3206 /* Apply control settings */
\r
3207 BUS_RegMaskedWrite(&CMU->HFXOCTRL,
\r
3208 _CMU_HFXOCTRL_LOWPOWER_MASK
\r
3209 #if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )
\r
3210 | _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK
\r
3212 | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK
\r
3213 | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK,
\r
3214 (hfxoInit->lowPowerMode
\r
3215 ? CMU_HFXOCTRL_LOWPOWER : 0)
\r
3216 #if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )
\r
3217 | (hfxoInit->autoStartSelOnRacWakeup
\r
3218 ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)
\r
3220 | (hfxoInit->autoStartEm01
\r
3221 ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)
\r
3222 | (hfxoInit->autoSelEm01
\r
3223 ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0));
\r
3225 /* Set XTAL tuning parameters */
\r
3227 /* Set peak detection threshold in CMU_HFXOCTRL1_PEAKDETTHR[2:0] (hidden). */
\r
3228 BUS_RegMaskedWrite((volatile uint32_t *)0x400E4028, 0x7, hfxoInit->thresholdPeakDetect);
\r
3230 /* Set tuning for startup and steady state */
\r
3231 BUS_RegMaskedWrite(&CMU->HFXOSTARTUPCTRL,
\r
3232 _CMU_HFXOSTARTUPCTRL_CTUNE_MASK
\r
3233 | _CMU_HFXOSTARTUPCTRL_REGISHWARM_MASK
\r
3234 | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK
\r
3235 | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_MASK,
\r
3236 (hfxoInit->ctuneStartup
\r
3237 << _CMU_HFXOSTARTUPCTRL_CTUNE_SHIFT)
\r
3238 | (hfxoInit->regIshStartup
\r
3239 << _CMU_HFXOSTARTUPCTRL_REGISHWARM_SHIFT)
\r
3240 | (hfxoInit->xoCoreBiasTrimStartup
\r
3241 << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT)
\r
3242 | 0x4 /* Recommended tuning */
\r
3243 << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_SHIFT);
\r
3245 /* Adjust CMU_HFXOSTEADYSTATECTRL_REGISHUPPER according to regIshSteadyState.
\r
3246 Saturate at max value. Please see the reference manual page 433 and Section
\r
3247 12.5.10 CMU_HFXOSTEADYSTATECTRL for more details. */
\r
3248 ishReg = hfxoInit->regIshSteadyState + 3;
\r
3249 ishMax = _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK
\r
3250 >> _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;
\r
3251 ishReg = ishReg > ishMax ? ishMax : ishReg;
\r
3252 ishReg <<= _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;
\r
3254 BUS_RegMaskedWrite(&CMU->HFXOSTEADYSTATECTRL,
\r
3255 _CMU_HFXOSTEADYSTATECTRL_CTUNE_MASK
\r
3256 | _CMU_HFXOSTEADYSTATECTRL_REGISH_MASK
\r
3257 | _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_MASK
\r
3258 | _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK,
\r
3259 (hfxoInit->ctuneSteadyState
\r
3260 << _CMU_HFXOSTEADYSTATECTRL_CTUNE_SHIFT)
\r
3261 | (hfxoInit->regIshSteadyState
\r
3262 << _CMU_HFXOSTEADYSTATECTRL_REGISH_SHIFT)
\r
3263 | (hfxoInit->xoCoreBiasTrimSteadyState
\r
3264 << _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_SHIFT)
\r
3267 /* Set timeouts */
\r
3268 BUS_RegMaskedWrite(&CMU->HFXOTIMEOUTCTRL,
\r
3269 _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_MASK
\r
3270 | _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_MASK
\r
3271 | _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_MASK
\r
3272 | _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_MASK
\r
3273 | _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_MASK,
\r
3274 (hfxoInit->timeoutShuntOptimization
\r
3275 << _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_SHIFT)
\r
3276 | (hfxoInit->timeoutPeakDetect
\r
3277 << _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_SHIFT)
\r
3278 | (hfxoInit->timeoutWarmSteady
\r
3279 << _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_SHIFT)
\r
3280 | (hfxoInit->timeoutSteady
\r
3281 << _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_SHIFT)
\r
3282 | (hfxoInit->timeoutStartup
\r
3283 << _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_SHIFT));
\r
3288 /***************************************************************************//**
\r
3290 * Get the LCD framerate divisor (FDIV) setting.
\r
3293 * The LCD framerate divisor.
\r
3294 ******************************************************************************/
\r
3295 uint32_t CMU_LCDClkFDIVGet(void)
\r
3297 #if defined( LCD_PRESENT )
\r
3298 return (CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT;
\r
3301 #endif /* defined(LCD_PRESENT) */
\r
3305 /***************************************************************************//**
\r
3307 * Set the LCD framerate divisor (FDIV) setting.
\r
3310 * The FDIV field (CMU LCDCTRL register) should only be modified while the
\r
3311 * LCD module is clock disabled (CMU LFACLKEN0.LCD bit is 0). This function
\r
3312 * will NOT modify FDIV if the LCD module clock is enabled. Please refer to
\r
3313 * CMU_ClockEnable() for disabling/enabling LCD clock.
\r
3316 * The FDIV setting to use.
\r
3317 ******************************************************************************/
\r
3318 void CMU_LCDClkFDIVSet(uint32_t div)
\r
3320 #if defined( LCD_PRESENT )
\r
3321 EFM_ASSERT(div <= cmuClkDiv_128);
\r
3323 /* Do not allow modification if LCD clock enabled */
\r
3324 if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)
\r
3329 div <<= _CMU_LCDCTRL_FDIV_SHIFT;
\r
3330 div &= _CMU_LCDCTRL_FDIV_MASK;
\r
3331 CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;
\r
3333 (void)div; /* Unused parameter */
\r
3334 #endif /* defined(LCD_PRESENT) */
\r
3338 #if defined( _CMU_LFXOCTRL_MASK )
\r
3339 /**************************************************************************//**
\r
3341 * Set LFXO control registers
\r
3344 * LFXO configuration should be obtained from a configuration tool,
\r
3345 * app note or xtal datasheet. This function disables the LFXO to ensure
\r
3346 * a valid state before update.
\r
3348 * @param[in] lfxoInit
\r
3349 * LFXO setup parameters
\r
3350 *****************************************************************************/
\r
3351 void CMU_LFXOInit(CMU_LFXOInit_TypeDef *lfxoInit)
\r
3353 /* Do not disable LFXO if it is currently selected as HF/Core clock */
\r
3354 EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_LFXO);
\r
3356 /* LFXO must be disabled before reconfiguration */
\r
3357 CMU_OscillatorEnable(cmuOsc_LFXO, false, false);
\r
3359 BUS_RegMaskedWrite(&CMU->LFXOCTRL,
\r
3360 _CMU_LFXOCTRL_TUNING_MASK
\r
3361 | _CMU_LFXOCTRL_GAIN_MASK
\r
3362 | _CMU_LFXOCTRL_TIMEOUT_MASK,
\r
3363 (lfxoInit->ctune << _CMU_LFXOCTRL_TUNING_SHIFT)
\r
3364 | (lfxoInit->gain << _CMU_LFXOCTRL_GAIN_SHIFT)
\r
3365 | (lfxoInit->timeout << _CMU_LFXOCTRL_TIMEOUT_SHIFT));
\r
3370 /***************************************************************************//**
\r
3372 * Enable/disable oscillator.
\r
3375 * WARNING: When this function is called to disable either cmuOsc_LFXO or
\r
3376 * cmuOsc_HFXO the LFXOMODE or HFXOMODE fields of the CMU_CTRL register
\r
3377 * are reset to the reset value. I.e. if external clock sources are selected
\r
3378 * in either LFXOMODE or HFXOMODE fields, the configuration will be cleared
\r
3379 * and needs to be reconfigured if needed later.
\r
3382 * The oscillator to enable/disable.
\r
3384 * @param[in] enable
\r
3385 * @li true - enable specified oscillator.
\r
3386 * @li false - disable specified oscillator.
\r
3389 * Only used if @p enable is true.
\r
3390 * @li true - wait for oscillator start-up time to timeout before returning.
\r
3391 * @li false - do not wait for oscillator start-up time to timeout before
\r
3393 ******************************************************************************/
\r
3394 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
\r
3396 uint32_t rdyBitPos;
\r
3397 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3398 uint32_t ensBitPos;
\r
3405 case cmuOsc_HFRCO:
\r
3406 enBit = CMU_OSCENCMD_HFRCOEN;
\r
3407 disBit = CMU_OSCENCMD_HFRCODIS;
\r
3408 rdyBitPos = _CMU_STATUS_HFRCORDY_SHIFT;
\r
3409 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3410 ensBitPos = _CMU_STATUS_HFRCOENS_SHIFT;
\r
3415 enBit = CMU_OSCENCMD_HFXOEN;
\r
3416 disBit = CMU_OSCENCMD_HFXODIS;
\r
3417 rdyBitPos = _CMU_STATUS_HFXORDY_SHIFT;
\r
3418 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3419 ensBitPos = _CMU_STATUS_HFXOENS_SHIFT;
\r
3423 case cmuOsc_AUXHFRCO:
\r
3424 enBit = CMU_OSCENCMD_AUXHFRCOEN;
\r
3425 disBit = CMU_OSCENCMD_AUXHFRCODIS;
\r
3426 rdyBitPos = _CMU_STATUS_AUXHFRCORDY_SHIFT;
\r
3427 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3428 ensBitPos = _CMU_STATUS_AUXHFRCOENS_SHIFT;
\r
3432 case cmuOsc_LFRCO:
\r
3433 enBit = CMU_OSCENCMD_LFRCOEN;
\r
3434 disBit = CMU_OSCENCMD_LFRCODIS;
\r
3435 rdyBitPos = _CMU_STATUS_LFRCORDY_SHIFT;
\r
3436 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3437 ensBitPos = _CMU_STATUS_LFRCOENS_SHIFT;
\r
3442 enBit = CMU_OSCENCMD_LFXOEN;
\r
3443 disBit = CMU_OSCENCMD_LFXODIS;
\r
3444 rdyBitPos = _CMU_STATUS_LFXORDY_SHIFT;
\r
3445 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3446 ensBitPos = _CMU_STATUS_LFXOENS_SHIFT;
\r
3450 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
\r
3451 case cmuOsc_USHFRCO:
\r
3452 enBit = CMU_OSCENCMD_USHFRCOEN;
\r
3453 disBit = CMU_OSCENCMD_USHFRCODIS;
\r
3454 rdyBitPos = _CMU_STATUS_USHFRCORDY_SHIFT;
\r
3455 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3456 ensBitPos = _CMU_STATUS_USHFRCOENS_SHIFT;
\r
3461 #if defined( CMU_LFCLKSEL_LFAE_ULFRCO )
\r
3462 case cmuOsc_ULFRCO:
\r
3463 /* ULFRCO is always enabled, and cannot be turned off */
\r
3468 /* Undefined clock source */
\r
3475 CMU->OSCENCMD = enBit;
\r
3477 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3478 /* Always wait for ENS to go high */
\r
3479 while (!BUS_RegBitRead(&CMU->STATUS, ensBitPos))
\r
3484 /* Wait for clock to become ready after enable */
\r
3487 while (!BUS_RegBitRead(&CMU->STATUS, rdyBitPos));
\r
3488 #if defined( _CMU_STATUS_HFXOSHUNTOPTRDY_MASK )
\r
3489 /* Wait for shunt current optimization to complete */
\r
3490 if ((osc == cmuOsc_HFXO)
\r
3491 && (BUS_RegMaskedRead(&CMU->HFXOCTRL,
\r
3492 _CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_MASK)
\r
3493 == CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_AUTOCMD))
\r
3495 while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOSHUNTOPTRDY_SHIFT))
\r
3498 /* Assert on failed peak detection. Incorrect HFXO initialization parameters
\r
3499 caused startup to fail. Please review parameters. */
\r
3500 EFM_ASSERT(BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOPEAKDETRDY_SHIFT));
\r
3507 CMU->OSCENCMD = disBit;
\r
3509 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3510 /* Always wait for ENS to go low */
\r
3511 while (BUS_RegBitRead(&CMU->STATUS, ensBitPos))
\r
3517 /* Keep EMU module informed */
\r
3518 EMU_UpdateOscConfig();
\r
3522 /***************************************************************************//**
\r
3524 * Get oscillator frequency tuning setting.
\r
3527 * Oscillator to get tuning value for, one of:
\r
3528 * @li #cmuOsc_LFRCO
\r
3529 * @li #cmuOsc_HFRCO
\r
3530 * @li #cmuOsc_AUXHFRCO
\r
3533 * The oscillator frequency tuning setting in use.
\r
3534 ******************************************************************************/
\r
3535 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
\r
3541 case cmuOsc_LFRCO:
\r
3542 ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK)
\r
3543 >> _CMU_LFRCOCTRL_TUNING_SHIFT;
\r
3546 case cmuOsc_HFRCO:
\r
3547 ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK)
\r
3548 >> _CMU_HFRCOCTRL_TUNING_SHIFT;
\r
3551 case cmuOsc_AUXHFRCO:
\r
3552 ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK)
\r
3553 >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
\r
3566 /***************************************************************************//**
\r
3568 * Set the oscillator frequency tuning control.
\r
3571 * Oscillator tuning is done during production, and the tuning value is
\r
3572 * automatically loaded after a reset. Changing the tuning value from the
\r
3573 * calibrated value is for more advanced use.
\r
3576 * Oscillator to set tuning value for, one of:
\r
3577 * @li #cmuOsc_LFRCO
\r
3578 * @li #cmuOsc_HFRCO
\r
3579 * @li #cmuOsc_AUXHFRCO
\r
3582 * The oscillator frequency tuning setting to use.
\r
3583 ******************************************************************************/
\r
3584 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
\r
3588 case cmuOsc_LFRCO:
\r
3589 EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK
\r
3590 >> _CMU_LFRCOCTRL_TUNING_SHIFT));
\r
3591 val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);
\r
3592 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3593 while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_LFRCOBSY_SHIFT));
\r
3595 CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK))
\r
3596 | (val << _CMU_LFRCOCTRL_TUNING_SHIFT);
\r
3599 case cmuOsc_HFRCO:
\r
3600 EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK
\r
3601 >> _CMU_HFRCOCTRL_TUNING_SHIFT));
\r
3602 val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);
\r
3603 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3604 while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT))
\r
3608 CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK))
\r
3609 | (val << _CMU_HFRCOCTRL_TUNING_SHIFT);
\r
3612 case cmuOsc_AUXHFRCO:
\r
3613 EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK
\r
3614 >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));
\r
3615 val &= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
\r
3616 #if defined( _SILICON_LABS_32B_PLATFORM_2 )
\r
3617 while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT))
\r
3621 CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK))
\r
3622 | (val << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
\r
3632 /**************************************************************************//**
\r
3634 * Determine if currently selected PCNTn clock used is external or LFBCLK.
\r
3636 * @param[in] instance
\r
3637 * PCNT instance number to get currently selected clock source for.
\r
3640 * @li true - selected clock is external clock.
\r
3641 * @li false - selected clock is LFBCLK.
\r
3642 *****************************************************************************/
\r
3643 bool CMU_PCNTClockExternalGet(unsigned int instance)
\r
3649 #if defined( _CMU_PCNTCTRL_PCNT0CLKEN_MASK )
\r
3651 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;
\r
3654 #if defined( _CMU_PCNTCTRL_PCNT1CLKEN_MASK )
\r
3656 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;
\r
3659 #if defined( _CMU_PCNTCTRL_PCNT2CLKEN_MASK )
\r
3661 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;
\r
3671 return (setting ? true : false);
\r
3675 /**************************************************************************//**
\r
3677 * Select PCNTn clock.
\r
3679 * @param[in] instance
\r
3680 * PCNT instance number to set selected clock source for.
\r
3682 * @param[in] external
\r
3683 * Set to true to select external clock, false to select LFBCLK.
\r
3684 *****************************************************************************/
\r
3685 void CMU_PCNTClockExternalSet(unsigned int instance, bool external)
\r
3687 #if defined( PCNT_PRESENT )
\r
3688 uint32_t setting = 0;
\r
3690 EFM_ASSERT(instance < PCNT_COUNT);
\r
3697 BUS_RegBitWrite(&(CMU->PCNTCTRL), (instance * 2) + 1, setting);
\r
3700 (void)instance; /* Unused parameter */
\r
3701 (void)external; /* Unused parameter */
\r
3706 #if defined( _CMU_USHFRCOCONF_BAND_MASK )
\r
3707 /***************************************************************************//**
\r
3709 * Get USHFRCO band in use.
\r
3712 * USHFRCO band in use.
\r
3713 ******************************************************************************/
\r
3714 CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)
\r
3716 return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF
\r
3717 & _CMU_USHFRCOCONF_BAND_MASK)
\r
3718 >> _CMU_USHFRCOCONF_BAND_SHIFT);
\r
3722 #if defined( _CMU_USHFRCOCONF_BAND_MASK )
\r
3723 /***************************************************************************//**
\r
3725 * Set USHFRCO band to use.
\r
3728 * USHFRCO band to activate.
\r
3729 ******************************************************************************/
\r
3730 void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)
\r
3733 uint32_t fineTuning;
\r
3734 CMU_Select_TypeDef osc;
\r
3736 /* Cannot switch band if USHFRCO is already selected as HF clock. */
\r
3737 osc = CMU_ClockSelectGet(cmuClock_HF);
\r
3738 EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));
\r
3740 /* Read tuning value from calibration table */
\r
3743 case cmuUSHFRCOBand_24MHz:
\r
3744 tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK)
\r
3745 >> _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;
\r
3746 fineTuning = (DEVINFO->USHFRCOCAL0
\r
3747 & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK)
\r
3748 >> _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;
\r
3751 case cmuUSHFRCOBand_48MHz:
\r
3752 tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK)
\r
3753 >> _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;
\r
3754 fineTuning = (DEVINFO->USHFRCOCAL0
\r
3755 & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK)
\r
3756 >> _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;
\r
3757 /* Enable the clock divider before switching the band from 24 to 48MHz */
\r
3758 BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);
\r
3766 /* Set band and tuning */
\r
3767 CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK)
\r
3768 | (band << _CMU_USHFRCOCONF_BAND_SHIFT);
\r
3769 CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK)
\r
3770 | (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);
\r
3771 CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK)
\r
3772 | (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);
\r
3774 /* Disable the clock divider after switching the band from 48 to 24MHz */
\r
3775 if (band == cmuUSHFRCOBand_24MHz)
\r
3777 BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);
\r
3784 /** @} (end addtogroup CMU) */
\r
3785 /** @} (end addtogroup EM_Library) */
\r
3786 #endif /* __EM_CMU_H */
\r