/***************************************************************************//**\r
* @file em_cmu.c\r
* @brief Clock management unit (CMU) Peripheral API\r
- * @version 4.0.0\r
+ * @version 4.2.1\r
*******************************************************************************\r
* @section License\r
- * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
*******************************************************************************\r
*\r
* Permission is granted to anyone to use this software for any purpose,\r
* arising from your use of this Software.\r
*\r
******************************************************************************/\r
-\r
-\r
#include "em_cmu.h"\r
#if defined( CMU_PRESENT )\r
\r
+#include <stddef.h>\r
+#include <limits.h>\r
#include "em_assert.h"\r
-#include "em_bitband.h"\r
+#include "em_bus.h"\r
#include "em_emu.h"\r
+#include "em_system.h"\r
\r
/***************************************************************************//**\r
* @addtogroup EM_Library\r
\r
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
\r
-/** Maximum allowed core frequency when using 0 wait states on flash access. */\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/** Maximum allowed core frequency when using 0 wait-states on flash access. */\r
+#define CMU_MAX_FREQ_0WS 26000000\r
+/** Maximum allowed core frequency when using 1 wait-states on flash access */\r
+#define CMU_MAX_FREQ_1WS 40000000\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+/** Maximum allowed core frequency when using 0 wait-states on flash access. */\r
#define CMU_MAX_FREQ_0WS 16000000\r
-/** Maximum allowed core frequency when using 1 wait states on flash access */\r
+/** Maximum allowed core frequency when using 1 wait-states on flash access */\r
#define CMU_MAX_FREQ_1WS 32000000\r
+#else\r
+#error "Unkown MCU platform."\r
+#endif\r
\r
#if defined( CMU_CTRL_HFLE )\r
/** Maximum frequency for HFLE needs to be enabled on Giant, Leopard and\r
Wonder. */\r
-#if defined ( _EFM32_WONDER_FAMILY ) || \\r
- defined ( _EZR32_LEOPARD_FAMILY ) || \\r
- defined ( _EZR32_WONDER_FAMILY )\r
-#define CMU_MAX_FREQ_HFLE 24000000\r
+#if defined( _EFM32_WONDER_FAMILY ) \\r
+ || defined( _EZR32_LEOPARD_FAMILY ) \\r
+ || defined( _EZR32_WONDER_FAMILY )\r
+#define CMU_MAX_FREQ_HFLE() 24000000\r
#elif defined ( _EFM32_GIANT_FAMILY )\r
-#define CMU_MAX_FREQ_HFLE (CMU_MaxFreqHfle())\r
+#define CMU_MAX_FREQ_HFLE() (maxFreqHfle())\r
#else\r
#error Invalid part/device.\r
#endif\r
#endif\r
\r
-/** Low frequency A group identifier */\r
-#define CMU_LFA 0\r
+/*******************************************************************************\r
+ ************************** LOCAL VARIABLES ********************************\r
+ ******************************************************************************/\r
\r
-/** Low frequency B group identifier */\r
-#define CMU_LFB 1\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+static CMU_AUXHFRCOFreq_TypeDef auxHfrcoFreq = cmuAUXHFRCOFreq_19M0Hz;\r
+#endif\r
\r
/** @endcond */\r
\r
\r
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
\r
-#if defined( CMU_CTRL_HFLE ) && \\r
- !defined ( _EFM32_WONDER_FAMILY ) && \\r
- !defined ( _EZR32_LEOPARD_FAMILY ) && \\r
- !defined ( _EZR32_WONDER_FAMILY )\r
-\r
/***************************************************************************//**\r
* @brief\r
- * Return max allowed frequency for low energy peripherals.\r
+ * Get the AUX clock frequency. Used by MSC flash programming and LESENSE,\r
+ * by default also as debug clock.\r
+ *\r
+ * @return\r
+ * AUX Frequency in Hz\r
******************************************************************************/\r
-static uint32_t CMU_MaxFreqHfle(void)\r
+static uint32_t auxClkGet(void)\r
{\r
- /* SYSTEM_GetFamily and SYSTEM_ChipRevisionGet could have been used here\r
- but we want to minimize dependencies in em_cmu.c. */\r
- uint16_t majorMinorRev;\r
- uint8_t deviceFamily = ((DEVINFO->PART & _DEVINFO_PART_DEVICE_FAMILY_MASK)\r
- >> _DEVINFO_PART_DEVICE_FAMILY_SHIFT);\r
- switch (deviceFamily)\r
+ uint32_t ret;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+ ret = auxHfrcoFreq;\r
+\r
+#elif defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
+ /* All Geckos from TG and newer */\r
+ switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)\r
{\r
- case _DEVINFO_PART_DEVICE_FAMILY_LG:\r
- /* CHIP MAJOR bit [3:0] */\r
- majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)\r
- >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);\r
- /* CHIP MINOR bit [7:4] */\r
- majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)\r
- >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);\r
- /* CHIP MINOR bit [3:0] */\r
- majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)\r
- >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);\r
-\r
- if (majorMinorRev >= 0x0204)\r
- return 24000000;\r
- else\r
- return 32000000;\r
- case _DEVINFO_PART_DEVICE_FAMILY_GG:\r
- return 32000000;\r
- case _DEVINFO_PART_DEVICE_FAMILY_WG:\r
- return 24000000;\r
- default:\r
- /* Invalid device family. */\r
- EFM_ASSERT(false);\r
- return 0;\r
+ case CMU_AUXHFRCOCTRL_BAND_1MHZ:\r
+ ret = 1000000;\r
+ break;\r
+\r
+ case CMU_AUXHFRCOCTRL_BAND_7MHZ:\r
+ ret = 7000000;\r
+ break;\r
+\r
+ case CMU_AUXHFRCOCTRL_BAND_11MHZ:\r
+ ret = 11000000;\r
+ break;\r
+\r
+ case CMU_AUXHFRCOCTRL_BAND_14MHZ:\r
+ ret = 14000000;\r
+ break;\r
+\r
+ case CMU_AUXHFRCOCTRL_BAND_21MHZ:\r
+ ret = 21000000;\r
+ break;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
+ case CMU_AUXHFRCOCTRL_BAND_28MHZ:\r
+ ret = 28000000;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0;\r
+ break;\r
}\r
+\r
+#else\r
+ /* Gecko has a fixed 14Mhz AUXHFRCO clock */\r
+ ret = 14000000;\r
+\r
+#endif\r
+\r
+ return ret;\r
}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get the Debug Trace clock frequency\r
+ *\r
+ * @return\r
+ * Debug Trace frequency in Hz\r
+ ******************************************************************************/\r
+static uint32_t dbgClkGet(void)\r
+{\r
+ uint32_t ret;\r
+ CMU_Select_TypeDef clk;\r
+\r
+ /* Get selected clock source */\r
+ clk = CMU_ClockSelectGet(cmuClock_DBG);\r
+\r
+ switch(clk)\r
+ {\r
+ case cmuSelect_HFCLK:\r
+ ret = SystemHFClockGet();\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+ /* Family with an additional divider. */\r
+ ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+ >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
#endif\r
+ break;\r
+\r
+ case cmuSelect_AUXHFRCO:\r
+ ret = auxClkGet();\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0;\r
+ break;\r
+ }\r
+ return ret;\r
+}\r
\r
\r
/***************************************************************************//**\r
* Configure flash access wait states in order to support given core clock\r
* frequency.\r
*\r
- * @param[in] hfcoreclk\r
+ * @param[in] coreFreq\r
* Core clock frequency to configure flash wait-states for\r
******************************************************************************/\r
-static void CMU_FlashWaitStateControl(uint32_t hfcoreclk)\r
+static void flashWaitStateControl(uint32_t coreFreq)\r
{\r
uint32_t mode;\r
bool mscLocked;\r
#if defined( MSC_READCTRL_MODE_WS0SCBTP )\r
- bool scbtpEn;\r
+ bool scbtpEn; /* Suppressed Conditional Branch Target Prefetch setting. */\r
#endif\r
\r
/* Make sure the MSC is unlocked */\r
{\r
}\r
#if defined( MSC_READCTRL_MODE_WS2 )\r
- else if (hfcoreclk > CMU_MAX_FREQ_1WS)\r
+ else if (coreFreq > CMU_MAX_FREQ_1WS)\r
{\r
mode = (scbtpEn ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2);\r
}\r
#endif\r
- else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))\r
+ else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))\r
{\r
mode = (scbtpEn ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1);\r
}\r
{\r
}\r
#if defined( MSC_READCTRL_MODE_WS2 )\r
- else if (hfcoreclk > CMU_MAX_FREQ_1WS)\r
+ else if (coreFreq > CMU_MAX_FREQ_1WS)\r
{\r
mode = MSC_READCTRL_MODE_WS2;\r
}\r
#endif\r
- else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))\r
+ else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))\r
{\r
mode = MSC_READCTRL_MODE_WS1;\r
}\r
/***************************************************************************//**\r
* @brief\r
* Configure flash access wait states to most conservative setting for\r
- * this target. Retain SCBTP setting.\r
+ * this target. Retain SCBTP (Suppressed Conditional Branch Target Prefetch)\r
+ * setting.\r
+ ******************************************************************************/\r
+static void flashWaitStateMax(void)\r
+{\r
+ flashWaitStateControl(SystemMaxCoreClockGet());\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get the LFnCLK frequency based on current configuration.\r
+ *\r
+ * @param[in] lfClkBranch\r
+ * Selected LF branch\r
+ *\r
+ * @return\r
+ * The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is\r
+ * returned.\r
******************************************************************************/\r
-static void CMU_FlashWaitStateMax(void)\r
+static uint32_t lfClkGet(CMU_Clock_TypeDef lfClkBranch)\r
{\r
- uint32_t maxCoreClock;\r
-#if defined (_EFM32_GECKO_FAMILY)\r
- maxCoreClock = 32000000;\r
-#elif defined (_EFM32_GIANT_FAMILY)\r
- maxCoreClock = 48000000;\r
-#elif defined (_EFM32_TINY_FAMILY)\r
- maxCoreClock = 32000000;\r
-#elif defined (_EFM32_LEOPARD_FAMILY)\r
- maxCoreClock = 48000000;\r
-#elif defined (_EFM32_WONDER_FAMILY)\r
- maxCoreClock = 48000000;\r
-#elif defined (_EFM32_ZERO_FAMILY)\r
- maxCoreClock = 24000000;\r
-#elif defined (_EFM32_HAPPY_FAMILY)\r
- maxCoreClock = 25000000;\r
+ uint32_t sel;\r
+ uint32_t ret = 0;\r
+\r
+ switch (lfClkBranch)\r
+ {\r
+ case cmuClock_LFA:\r
+ case cmuClock_LFB:\r
+#if defined( _CMU_LFCCLKEN0_MASK )\r
+ case cmuClock_LFC:\r
+#endif\r
+#if defined( _CMU_LFECLKSEL_MASK )\r
+ case cmuClock_LFE:\r
+#endif\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+\r
+ sel = CMU_ClockSelectGet(lfClkBranch);\r
+\r
+ /* Get clock select field */\r
+ switch (lfClkBranch)\r
+ {\r
+ case cmuClock_LFA:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+ sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK) >> _CMU_LFCLKSEL_LFA_SHIFT;\r
+#elif defined( _CMU_LFACLKSEL_MASK )\r
+ sel = (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK) >> _CMU_LFACLKSEL_LFA_SHIFT;\r
+#else\r
+ EFM_ASSERT(0);\r
+#endif\r
+ break;\r
+\r
+ case cmuClock_LFB:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+ sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK) >> _CMU_LFCLKSEL_LFB_SHIFT;\r
+#elif defined( _CMU_LFBCLKSEL_MASK )\r
+ sel = (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK) >> _CMU_LFBCLKSEL_LFB_SHIFT;\r
+#else\r
+ EFM_ASSERT(0);\r
+#endif\r
+ break;\r
+\r
+#if defined( _CMU_LFCCLKEN0_MASK )\r
+ case cmuClock_LFC:\r
+ sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK) >> _CMU_LFCLKSEL_LFC_SHIFT;\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKSEL_MASK )\r
+ case cmuClock_LFE:\r
+ sel = (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK) >> _CMU_LFECLKSEL_LFE_SHIFT;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+\r
+ /* Get clock frequency */\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+ switch (sel)\r
+ {\r
+ case _CMU_LFCLKSEL_LFA_LFRCO:\r
+ ret = SystemLFRCOClockGet();\r
+ break;\r
+\r
+ case _CMU_LFCLKSEL_LFA_LFXO:\r
+ ret = SystemLFXOClockGet();\r
+ break;\r
+\r
+#if defined( _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )\r
+ case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
+#if defined( CMU_CTRL_HFLE )\r
+ /* Family which can use an extra div 4 divider */\r
+ /* (and must if >32MHz) or HFLE is set. */\r
+ if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK)\r
+ == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)\r
+ || (CMU->CTRL & CMU_CTRL_HFLE))\r
+ {\r
+ ret = SystemCoreClockGet() / 4U;\r
+ }\r
+ else\r
+ {\r
+ ret = SystemCoreClockGet() / 2U;\r
+ }\r
#else\r
-#error "Max core clock frequency is not defined for this family"\r
+ ret = SystemCoreClockGet() / 2U;\r
+#endif\r
+ break;\r
+#endif\r
+\r
+ case _CMU_LFCLKSEL_LFA_DISABLED:\r
+ ret = 0;\r
+#if defined( CMU_LFCLKSEL_LFAE )\r
+ /* Check LF Extended bit setting for LFA or LFB ULFRCO clock */\r
+ if ((lfClkBranch == cmuClock_LFA) || (lfClkBranch == cmuClock_LFB))\r
+ {\r
+ if (CMU->LFCLKSEL >> (lfClkBranch == cmuClock_LFA\r
+ ? _CMU_LFCLKSEL_LFAE_SHIFT\r
+ : _CMU_LFCLKSEL_LFBE_SHIFT))\r
+ {\r
+ ret = SystemULFRCOClockGet();\r
+ }\r
+ }\r
+#endif\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0U;\r
+ break;\r
+ }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFACLKSEL_MASK )\r
+ switch (sel)\r
+ {\r
+ case _CMU_LFACLKSEL_LFA_LFRCO:\r
+ ret = SystemLFRCOClockGet();\r
+ break;\r
+\r
+ case _CMU_LFACLKSEL_LFA_LFXO:\r
+ ret = SystemLFXOClockGet();\r
+ break;\r
+\r
+ case _CMU_LFACLKSEL_LFA_ULFRCO:\r
+ ret = SystemULFRCOClockGet();\r
+ break;\r
+\r
+#if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+ case _CMU_LFACLKSEL_LFA_HFCLKLE:\r
+ ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+ == CMU_HFPRESC_HFCLKLEPRESC_DIV4)\r
+ ? SystemCoreClockGet() / 4U\r
+ : SystemCoreClockGet() / 2U;\r
+ break;\r
+#elif defined( _CMU_LFBCLKSEL_LFB_HFCLKLE )\r
+ case _CMU_LFBCLKSEL_LFB_HFCLKLE:\r
+ ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+ == CMU_HFPRESC_HFCLKLEPRESC_DIV4)\r
+ ? SystemCoreClockGet() / 4U\r
+ : SystemCoreClockGet() / 2U;\r
+ break;\r
+#endif\r
+\r
+ case _CMU_LFACLKSEL_LFA_DISABLED:\r
+ ret = 0;\r
+ break;\r
+ }\r
#endif\r
\r
- /* Use SystemMaxCoreClockGet() when available in CMSIS */\r
- CMU_FlashWaitStateControl(maxCoreClock);\r
+ return ret;\r
}\r
\r
\r
+#if defined( CMU_CTRL_HFLE ) \\r
+ && !defined( _EFM32_WONDER_FAMILY ) \\r
+ && !defined( _EZR32_LEOPARD_FAMILY ) \\r
+ && !defined( _EZR32_WONDER_FAMILY )\r
/***************************************************************************//**\r
- * @brief Convert dividend to prescaler logarithmic value. Only works for even\r
- * numbers equal to 2^n\r
- * @param[in] div Unscaled dividend,\r
- * @return Base 2 logarithm of input, as used by fixed prescalers\r
+ * @brief\r
+ * Return max allowed frequency for low energy peripherals.\r
******************************************************************************/\r
-__STATIC_INLINE uint32_t CMU_DivToLog2(CMU_ClkDiv_TypeDef div)\r
+static uint32_t maxFreqHfle(void)\r
{\r
- uint32_t log2;\r
-\r
- /* Prescalers take argument of 32768 or less */\r
- EFM_ASSERT((div>0) && (div <= 32768));\r
+ uint16_t majorMinorRev;\r
\r
- /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */\r
- log2 = (31 - __CLZ(div));\r
+ switch (SYSTEM_GetFamily())\r
+ {\r
+ case systemPartFamilyEfm32Leopard:\r
+ /* CHIP MAJOR bit [5:0] */\r
+ majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)\r
+ >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);\r
+ /* CHIP MINOR bit [7:4] */\r
+ majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)\r
+ >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);\r
+ /* CHIP MINOR bit [3:0] */\r
+ majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)\r
+ >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);\r
+\r
+ if (majorMinorRev >= 0x0204)\r
+ return 24000000;\r
+ else\r
+ return 32000000;\r
+\r
+ case systemPartFamilyEfm32Giant:\r
+ return 32000000;\r
\r
- return log2;\r
+ default:\r
+ /* Invalid device family. */\r
+ EFM_ASSERT(false);\r
+ return 0;\r
+ }\r
}\r
+#endif\r
\r
\r
/***************************************************************************//**\r
- * @brief Convert logarithm of 2 prescaler to division factor\r
- * @param[in] log2\r
- * @return Dividend\r
+ * @brief\r
+ * Wait for ongoing sync of register(s) to low frequency domain to complete.\r
+ *\r
+ * @param[in] mask\r
+ * Bitmask corresponding to SYNCBUSY register defined bits, indicating\r
+ * registers that must complete any ongoing synchronization.\r
******************************************************************************/\r
-__STATIC_INLINE uint32_t CMU_Log2ToDiv(uint32_t log2)\r
+__STATIC_INLINE void syncReg(uint32_t mask)\r
{\r
- return 1<<log2;\r
+ /* Avoid deadlock if modifying the same register twice when freeze mode is */\r
+ /* activated. */\r
+ if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)\r
+ return;\r
+\r
+ /* Wait for any pending previous write operation to have been completed */\r
+ /* in low frequency domain */\r
+ while (CMU->SYNCBUSY & mask)\r
+ {\r
+ }\r
}\r
\r
\r
* @return\r
* USBC frequency in Hz\r
******************************************************************************/\r
-static uint32_t CMU_USBCClkGet(void)\r
+static uint32_t usbCClkGet(void)\r
{\r
uint32_t ret;\r
CMU_Select_TypeDef clk;\r
\r
switch(clk)\r
{\r
- case cmuSelect_LFXO:\r
- ret = SystemLFXOClockGet();\r
- break;\r
- case cmuSelect_LFRCO:\r
- ret = SystemLFRCOClockGet();\r
- break;\r
- case cmuSelect_HFCLK:\r
- ret = SystemHFClockGet();\r
- break;\r
- default:\r
- /* Clock is not enabled */\r
- ret = 0;\r
- break;\r
+ case cmuSelect_LFXO:\r
+ ret = SystemLFXOClockGet();\r
+ break;\r
+ case cmuSelect_LFRCO:\r
+ ret = SystemLFRCOClockGet();\r
+ break;\r
+ case cmuSelect_HFCLK:\r
+ ret = SystemHFClockGet();\r
+ break;\r
+ default:\r
+ /* Clock is not enabled */\r
+ ret = 0;\r
+ break;\r
}\r
return ret;\r
}\r
#endif\r
\r
\r
+/** @endcond */\r
+\r
+/*******************************************************************************\r
+ ************************** GLOBAL FUNCTIONS *******************************\r
+ ******************************************************************************/\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
/***************************************************************************//**\r
* @brief\r
- * Get the AUX clock frequency. Used by MSC flash programming and LESENSE,\r
- * by default also as debug clock.\r
+ * Get AUXHFRCO band in use.\r
*\r
* @return\r
- * AUX Frequency in Hz\r
+ * AUXHFRCO band in use.\r
******************************************************************************/\r
-static uint32_t CMU_AUXClkGet(void)\r
+CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)\r
{\r
- uint32_t ret;\r
-\r
-#if defined(_EFM32_GECKO_FAMILY)\r
- /* Gecko has a fixed 14Mhz AUXHFRCO clock */\r
- ret = 14000000;\r
-#else\r
- switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)\r
- {\r
- case CMU_AUXHFRCOCTRL_BAND_1MHZ:\r
- ret = 1000000;\r
- break;\r
- case CMU_AUXHFRCOCTRL_BAND_7MHZ:\r
- ret = 7000000;\r
- break;\r
- case CMU_AUXHFRCOCTRL_BAND_11MHZ:\r
- ret = 11000000;\r
- break;\r
- case CMU_AUXHFRCOCTRL_BAND_14MHZ:\r
- ret = 14000000;\r
- break;\r
- case CMU_AUXHFRCOCTRL_BAND_21MHZ:\r
- ret = 21000000;\r
- break;\r
-#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
- case CMU_AUXHFRCOCTRL_BAND_28MHZ:\r
- ret = 28000000;\r
- break;\r
-#endif\r
- default:\r
- ret = 0;\r
- break;\r
- }\r
-#endif\r
- return ret;\r
+ return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL\r
+ & _CMU_AUXHFRCOCTRL_BAND_MASK)\r
+ >> _CMU_AUXHFRCOCTRL_BAND_SHIFT);\r
}\r
+#endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */\r
\r
\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
/***************************************************************************//**\r
* @brief\r
- * Get the Debug Trace clock frequency\r
+ * Set AUXHFRCO band and the tuning value based on the value in the\r
+ * calibration table made during production.\r
*\r
- * @return\r
- * Debug Trace frequency in Hz\r
+ * @param[in] band\r
+ * AUXHFRCO band to activate.\r
******************************************************************************/\r
-static uint32_t CMU_DBGClkGet(void)\r
+void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)\r
{\r
- uint32_t ret;\r
- CMU_Select_TypeDef clk;\r
+ uint32_t tuning;\r
\r
- /* Get selected clock source */\r
- clk = CMU_ClockSelectGet(cmuClock_DBG);\r
-\r
- switch(clk)\r
+ /* Read tuning value from calibration table */\r
+ switch (band)\r
{\r
- case cmuSelect_HFCLK:\r
- ret = SystemHFClockGet();\r
-#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
- /* Giant Gecko has an additional divider, not used by USBC */\r
- ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>\r
- _CMU_CTRL_HFCLKDIV_SHIFT));\r
-#endif\r
- break;\r
+ case cmuAUXHFRCOBand_1MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;\r
+ break;\r
\r
- case cmuSelect_AUXHFRCO:\r
- ret = CMU_AUXClkGet();\r
- break;\r
+ case cmuAUXHFRCOBand_7MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- ret = 0;\r
- break;\r
+ case cmuAUXHFRCOBand_11MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;\r
+ break;\r
+\r
+ case cmuAUXHFRCOBand_14MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;\r
+ break;\r
+\r
+ case cmuAUXHFRCOBand_21MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;\r
+ break;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
+ case cmuAUXHFRCOBand_28MHz:\r
+ tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK)\r
+ >> _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return;\r
}\r
- return ret;\r
+\r
+ /* Set band/tuning */\r
+ CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &\r
+ ~(_CMU_AUXHFRCOCTRL_BAND_MASK\r
+ | _CMU_AUXHFRCOCTRL_TUNING_MASK))\r
+ | (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT)\r
+ | (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+\r
}\r
+#endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */\r
\r
\r
-/***************************************************************************//**\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+/**************************************************************************//**\r
* @brief\r
- * Get the LFnCLK frequency based on current configuration.\r
+ * Get a pointer to the AUXHFRCO frequency calibration word in DEVINFO\r
*\r
- * @param[in] lfClkBranch\r
- * LF branch, 0 = LFA, 1 = LFB, ...\r
+ * @param[in] freq\r
+ * Frequency in Hz\r
*\r
* @return\r
- * The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is\r
- * returned.\r
- ******************************************************************************/\r
-static uint32_t CMU_LFClkGet(unsigned int lfClkBranch)\r
+ * AUXHFRCO calibration word for a given frequency\r
+ *****************************************************************************/\r
+static uint32_t CMU_AUXHFRCODevinfoGet(CMU_AUXHFRCOFreq_TypeDef freq)\r
{\r
- uint32_t ret;\r
+ switch (freq)\r
+ {\r
+ /* 1, 2 and 4MHz share the same calibration word */\r
+ case cmuAUXHFRCOFreq_1M0Hz:\r
+ case cmuAUXHFRCOFreq_2M0Hz:\r
+ case cmuAUXHFRCOFreq_4M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL0;\r
\r
- EFM_ASSERT(lfClkBranch == CMU_LFA || lfClkBranch == CMU_LFB);\r
+ case cmuAUXHFRCOFreq_7M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL3;\r
\r
- switch ((CMU->LFCLKSEL >> (lfClkBranch * 2)) & 0x3)\r
- {\r
- case _CMU_LFCLKSEL_LFA_LFRCO:\r
- ret = SystemLFRCOClockGet();\r
- break;\r
+ case cmuAUXHFRCOFreq_13M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL6;\r
\r
- case _CMU_LFCLKSEL_LFA_LFXO:\r
- ret = SystemLFXOClockGet();\r
- break;\r
+ case cmuAUXHFRCOFreq_16M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL7;\r
\r
- case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
-#if defined( CMU_CTRL_HFLE )\r
- /* Giant Gecko can use a /4 divider (and must if >32MHz) or HFLE is set */\r
- if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK) == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)||\r
- (CMU->CTRL & CMU_CTRL_HFLE))\r
- {\r
- ret = SystemCoreClockGet() / 4;\r
- }\r
- else\r
- {\r
- ret = SystemCoreClockGet() / 2;\r
- }\r
-#else\r
- ret = SystemCoreClockGet() / 2;\r
-#endif\r
- break;\r
+ case cmuAUXHFRCOFreq_19M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL8;\r
\r
- case _CMU_LFCLKSEL_LFA_DISABLED:\r
-#if defined( CMU_LFCLKSEL_LFAE )\r
- /* Check LF Extended bit setting for ULFRCO clock */\r
- if(CMU->LFCLKSEL >> (_CMU_LFCLKSEL_LFAE_SHIFT + lfClkBranch * 4))\r
- {\r
- ret = SystemULFRCOClockGet();\r
- }\r
- else\r
- {\r
- ret = 0;\r
- }\r
-#else\r
- ret = 0;\r
-#endif\r
- break;\r
+ case cmuAUXHFRCOFreq_26M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL10;\r
\r
- default:\r
- ret = 0;\r
- break;\r
+ case cmuAUXHFRCOFreq_32M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL11;\r
+\r
+ case cmuAUXHFRCOFreq_38M0Hz:\r
+ return DEVINFO->AUXHFRCOCAL12;\r
+\r
+ default: /* cmuAUXHFRCOFreq_UserDefined */\r
+ return 0;\r
}\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
\r
- return ret;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get AUXHFRCO frequency enumeration in use\r
+ *\r
+ * @return\r
+ * AUXHFRCO frequency enumeration in use\r
+ ******************************************************************************/\r
+CMU_AUXHFRCOFreq_TypeDef CMU_AUXHFRCOFreqGet(void)\r
+{\r
+ return auxHfrcoFreq;\r
}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
\r
\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
/***************************************************************************//**\r
* @brief\r
- * Wait for ongoing sync of register(s) to low frequency domain to complete.\r
+ * Set AUXHFRCO calibration for the selected target frequency\r
*\r
- * @param[in] mask\r
- * Bitmask corresponding to SYNCBUSY register defined bits, indicating\r
- * registers that must complete any ongoing synchronization.\r
+ * @param[in] frequency\r
+ * AUXHFRCO frequency to set\r
******************************************************************************/\r
-__STATIC_INLINE void CMU_Sync(uint32_t mask)\r
+void CMU_AUXHFRCOFreqSet(CMU_AUXHFRCOFreq_TypeDef freq)\r
{\r
- /* Avoid deadlock if modifying the same register twice when freeze mode is */\r
- /* activated. */\r
- if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)\r
- return;\r
+ uint32_t freqCal;\r
\r
- /* Wait for any pending previous write operation to have been completed */\r
- /* in low frequency domain */\r
- while (CMU->SYNCBUSY & mask)\r
- ;\r
-}\r
+ /* Get DEVINFO index, set global auxHfrcoFreq */\r
+ freqCal = CMU_AUXHFRCODevinfoGet(freq);\r
+ EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));\r
+ auxHfrcoFreq = freq;\r
\r
+ /* Wait for any previous sync to complete, and then set calibration data\r
+ for the selected frequency. */\r
+ while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT));\r
\r
-/** @endcond */\r
+ /* Set divider in AUXHFRCOCTRL for 1, 2 and 4MHz */\r
+ switch(freq)\r
+ {\r
+ case cmuAUXHFRCOFreq_1M0Hz:\r
+ freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_AUXHFRCOCTRL_CLKDIV_DIV4;\r
+ break;\r
+\r
+ case cmuAUXHFRCOFreq_2M0Hz:\r
+ freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_AUXHFRCOCTRL_CLKDIV_DIV2;\r
+ break;\r
+\r
+ case cmuAUXHFRCOFreq_4M0Hz:\r
+ freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_AUXHFRCOCTRL_CLKDIV_DIV1;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ CMU->AUXHFRCOCTRL = freqCal;\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
\r
-/*******************************************************************************\r
- ************************** GLOBAL FUNCTIONS *******************************\r
- ******************************************************************************/\r
\r
/***************************************************************************//**\r
* @brief\r
*\r
* @details\r
* Run a calibration for HFCLK against a selectable reference clock. Please\r
- * refer to the EFM32 reference manual, CMU chapter, for further details.\r
+ * refer to the reference manual, CMU chapter, for further details.\r
*\r
* @note\r
* This function will not return until calibration measurement is completed.\r
/* Set reference clock source */\r
switch (ref)\r
{\r
- case cmuOsc_LFXO:\r
- CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;\r
- break;\r
+ case cmuOsc_LFXO:\r
+ CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;\r
+ break;\r
\r
- case cmuOsc_LFRCO:\r
- CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;\r
+ break;\r
\r
- case cmuOsc_HFXO:\r
- CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;\r
- break;\r
+ case cmuOsc_HFXO:\r
+ CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;\r
+ break;\r
\r
- case cmuOsc_HFRCO:\r
- CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;\r
- break;\r
+ case cmuOsc_HFRCO:\r
+ CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- return 0;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return 0;\r
}\r
\r
/* Set top value */\r
/* Start calibration */\r
CMU->CMD = CMU_CMD_CALSTART;\r
\r
+#if defined( CMU_STATUS_CALRDY )\r
/* Wait until calibration completes */\r
- while (CMU->STATUS & CMU_STATUS_CALBSY)\r
- ;\r
+ while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))\r
+ {\r
+ }\r
+#else\r
+ /* Wait until calibration completes */\r
+ while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+ {\r
+ }\r
+#endif\r
\r
return CMU->CALCNT;\r
}\r
* @details\r
* Configure a calibration for a selectable clock source against another\r
* selectable reference clock.\r
- * Refer to the EFM32 reference manual, CMU chapter, for further details.\r
+ * Refer to the reference manual, CMU chapter, for further details.\r
*\r
* @note\r
* After configuration, a call to CMU_CalibrateStart() is required, and\r
CMU_Osc_TypeDef upSel)\r
{\r
/* Keep untouched configuration settings */\r
- uint32_t calCtrl = CMU->CALCTRL & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);\r
+ uint32_t calCtrl = CMU->CALCTRL\r
+ & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);\r
\r
/* 20 bits of precision to calibration count register */\r
EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));\r
/* Set down counting clock source - down counter */\r
switch (downSel)\r
{\r
- case cmuOsc_LFXO:\r
- calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;\r
- break;\r
+ case cmuOsc_LFXO:\r
+ calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;\r
+ break;\r
\r
- case cmuOsc_LFRCO:\r
- calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;\r
+ break;\r
\r
- case cmuOsc_HFXO:\r
- calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;\r
- break;\r
+ case cmuOsc_HFXO:\r
+ calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;\r
+ break;\r
\r
- case cmuOsc_HFRCO:\r
- calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;\r
- break;\r
+ case cmuOsc_HFRCO:\r
+ calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- break;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
}\r
\r
/* Set top value to be counted down by the downSel clock */\r
/* Set reference clock source - up counter */\r
switch (upSel)\r
{\r
- case cmuOsc_LFXO:\r
- calCtrl |= CMU_CALCTRL_UPSEL_LFXO;\r
- break;\r
+ case cmuOsc_LFXO:\r
+ calCtrl |= CMU_CALCTRL_UPSEL_LFXO;\r
+ break;\r
\r
- case cmuOsc_LFRCO:\r
- calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;\r
+ break;\r
\r
- case cmuOsc_HFXO:\r
- calCtrl |= CMU_CALCTRL_UPSEL_HFXO;\r
- break;\r
+ case cmuOsc_HFXO:\r
+ calCtrl |= CMU_CALCTRL_UPSEL_HFXO;\r
+ break;\r
\r
- case cmuOsc_HFRCO:\r
- calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;\r
- break;\r
+ case cmuOsc_HFRCO:\r
+ calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- break;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
}\r
\r
CMU->CALCTRL = calCtrl;\r
#endif\r
\r
\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get calibration count register\r
+ * @note\r
+ * If continuous calibrartion mode is active, calibration busy will almost\r
+ * always be off, and we just need to read the value, where the normal case\r
+ * would be that this function call has been triggered by the CALRDY\r
+ * interrupt flag.\r
+ * @return\r
+ * Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)\r
+ * in the period of DOWNSEL oscillator clock cycles configured by a previous\r
+ * write operation to CMU->CALCNT\r
+ ******************************************************************************/\r
+uint32_t CMU_CalibrateCountGet(void)\r
+{\r
+ /* Wait until calibration completes, UNLESS continuous calibration mode is */\r
+ /* active */\r
+#if defined( CMU_CALCTRL_CONT )\r
+ if (!BUS_RegBitRead(&CMU->CALCTRL, _CMU_CALCTRL_CONT_SHIFT))\r
+ {\r
+#if defined( CMU_STATUS_CALRDY )\r
+ /* Wait until calibration completes */\r
+ while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))\r
+ {\r
+ }\r
+#else\r
+ /* Wait until calibration completes */\r
+ while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+ {\r
+ }\r
+#endif\r
+ }\r
+#else\r
+ while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+ {\r
+ }\r
+#endif\r
+ return CMU->CALCNT;\r
+}\r
+\r
+\r
/***************************************************************************//**\r
* @brief\r
* Get clock divisor/prescaler.\r
******************************************************************************/\r
CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)\r
{\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ return 1 + (uint32_t)CMU_ClockPrescGet(clock);\r
+\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
uint32_t divReg;\r
CMU_ClkDiv_TypeDef ret;\r
\r
switch (divReg)\r
{\r
#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
- case CMU_HFCLKDIV_REG:\r
- ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>\r
- _CMU_CTRL_HFCLKDIV_SHIFT);\r
- break;\r
+ case CMU_HFCLKDIV_REG:\r
+ ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+ >> _CMU_CTRL_HFCLKDIV_SHIFT);\r
+ break;\r
#endif\r
\r
- case CMU_HFPERCLKDIV_REG:\r
- ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV &\r
- _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>\r
- _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
-\r
- case CMU_HFCORECLKDIV_REG:\r
- ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV &\r
- _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>\r
- _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
-\r
- case CMU_LFAPRESC0_REG:\r
- switch (clock)\r
- {\r
- case cmuClock_RTC:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>\r
- _CMU_LFAPRESC0_RTC_SHIFT));\r
+ case CMU_HFPERCLKDIV_REG:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV\r
+ & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+ >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
ret = CMU_Log2ToDiv(ret);\r
break;\r
\r
-#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)\r
- case cmuClock_LETIMER0:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>\r
- _CMU_LFAPRESC0_LETIMER0_SHIFT));\r
+ case CMU_HFCORECLKDIV_REG:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV\r
+ & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)\r
+ >> _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
ret = CMU_Log2ToDiv(ret);\r
break;\r
+\r
+ case CMU_LFAPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+ case cmuClock_RTC:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)\r
+ >> _CMU_LFAPRESC0_RTC_SHIFT);\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
+\r
+#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)\r
+ case cmuClock_LETIMER0:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+ >> _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
#endif\r
\r
#if defined(_CMU_LFAPRESC0_LCD_MASK)\r
- case cmuClock_LCDpre:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>\r
- _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16));\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
+ case cmuClock_LCDpre:\r
+ ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+ >> _CMU_LFAPRESC0_LCD_SHIFT)\r
+ + CMU_DivToLog2(cmuClkDiv_16));\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
#endif\r
\r
#if defined(_CMU_LFAPRESC0_LESENSE_MASK)\r
- case cmuClock_LESENSE:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>\r
- _CMU_LFAPRESC0_LESENSE_SHIFT));\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
+ case cmuClock_LESENSE:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)\r
+ >> _CMU_LFAPRESC0_LESENSE_SHIFT);\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
#endif\r
\r
- default:\r
- EFM_ASSERT(0);\r
- ret = cmuClkDiv_1;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = cmuClkDiv_1;\r
+ break;\r
+ }\r
break;\r
- }\r
- break;\r
\r
- case CMU_LFBPRESC0_REG:\r
- switch (clock)\r
- {\r
+ case CMU_LFBPRESC0_REG:\r
+ switch (clock)\r
+ {\r
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)\r
- case cmuClock_LEUART0:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>\r
- _CMU_LFBPRESC0_LEUART0_SHIFT));\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
+ case cmuClock_LEUART0:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
#endif\r
\r
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)\r
- case cmuClock_LEUART1:\r
- ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>\r
- _CMU_LFBPRESC0_LEUART1_SHIFT));\r
- ret = CMU_Log2ToDiv(ret);\r
- break;\r
+ case cmuClock_LEUART1:\r
+ ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+ ret = CMU_Log2ToDiv(ret);\r
+ break;\r
#endif\r
\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = cmuClkDiv_1;\r
+ break;\r
+ }\r
+ break;\r
+\r
default:\r
EFM_ASSERT(0);\r
ret = cmuClkDiv_1;\r
break;\r
- }\r
- break;\r
-\r
- default:\r
- EFM_ASSERT(0);\r
- ret = cmuClkDiv_1;\r
- break;\r
}\r
\r
- return(ret);\r
+ return ret;\r
+#endif\r
}\r
\r
\r
******************************************************************************/\r
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)\r
{\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ CMU_ClockPrescSet(clock, (CMU_ClkPresc_TypeDef)(div - 1));\r
+\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
uint32_t freq;\r
uint32_t divReg;\r
\r
switch (divReg)\r
{\r
#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
- case CMU_HFCLKDIV_REG:\r
- EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));\r
+ case CMU_HFCLKDIV_REG:\r
+ EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));\r
\r
- /* Configure worst case wait states for flash access before setting divisor */\r
- CMU_FlashWaitStateMax();\r
+ /* Configure worst case wait states for flash access before setting divisor */\r
+ flashWaitStateMax();\r
\r
- /* Set divider */\r
- CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK) |\r
- ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);\r
+ /* Set divider */\r
+ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK)\r
+ | ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);\r
\r
- /* Update CMSIS core clock variable */\r
- /* (The function will update the global variable) */\r
- freq = SystemCoreClockGet();\r
+ /* Update CMSIS core clock variable */\r
+ /* (The function will update the global variable) */\r
+ freq = SystemCoreClockGet();\r
\r
- /* Optimize flash access wait state setting for current core clk */\r
- CMU_FlashWaitStateControl(freq);\r
- break;\r
+ /* Optimize flash access wait state setting for current core clk */\r
+ flashWaitStateControl(freq);\r
+ break;\r
#endif\r
\r
- case CMU_HFPERCLKDIV_REG:\r
- EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
- CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) |\r
- (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
- break;\r
+ case CMU_HFPERCLKDIV_REG:\r
+ EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
+ CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+ | (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
+ break;\r
\r
- case CMU_HFCORECLKDIV_REG:\r
- EFM_ASSERT(div <= cmuClkDiv_512);\r
+ case CMU_HFCORECLKDIV_REG:\r
+ EFM_ASSERT(div <= cmuClkDiv_512);\r
\r
- /* Configure worst case wait states for flash access before setting divisor */\r
- CMU_FlashWaitStateMax();\r
+ /* Configure worst case wait states for flash access before setting divisor */\r
+ flashWaitStateMax();\r
\r
#if defined( CMU_CTRL_HFLE )\r
- /* Clear HFLE and set DIV2 factor for peripheral clock\r
- when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */\r
- if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE)\r
- {\r
- /* Clear CMU HFLE */\r
- BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 0);\r
+ /* Clear HFLE and set DIV2 factor for peripheral clock\r
+ when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */\r
+ if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE())\r
+ {\r
+ /* Clear CMU HFLE */\r
+ BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 0);\r
\r
- /* Set DIV2 factor for peripheral clock */\r
- BITBAND_Peripheral(&(CMU->HFCORECLKDIV),\r
- _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);\r
- }\r
- else\r
- {\r
- /* Set CMU HFLE */\r
- BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);\r
+ /* Set DIV2 factor for peripheral clock */\r
+ BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+ _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);\r
+ }\r
+ else\r
+ {\r
+ /* Set CMU HFLE */\r
+ BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
\r
- /* Set DIV4 factor for peripheral clock */\r
- BITBAND_Peripheral(&(CMU->HFCORECLKDIV),\r
- _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
- }\r
+ /* Set DIV4 factor for peripheral clock */\r
+ BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+ _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+ }\r
#endif\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) |\r
- (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
+ CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV\r
+ & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)\r
+ | (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
\r
- /* Update CMSIS core clock variable */\r
- /* (The function will update the global variable) */\r
- freq = SystemCoreClockGet();\r
+ /* Update CMSIS core clock variable */\r
+ /* (The function will update the global variable) */\r
+ freq = SystemCoreClockGet();\r
\r
- /* Optimize flash access wait state setting for current core clk */\r
- CMU_FlashWaitStateControl(freq);\r
- break;\r
+ /* Optimize flash access wait state setting for current core clk */\r
+ flashWaitStateControl(freq);\r
+ break;\r
\r
- case CMU_LFAPRESC0_REG:\r
- switch (clock)\r
- {\r
- case cmuClock_RTC:\r
- EFM_ASSERT(div <= cmuClkDiv_32768);\r
+ case CMU_LFAPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+ case cmuClock_RTC:\r
+ EFM_ASSERT(div <= cmuClkDiv_32768);\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK) |\r
- (div << _CMU_LFAPRESC0_RTC_SHIFT);\r
- break;\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)\r
+ | (div << _CMU_LFAPRESC0_RTC_SHIFT);\r
+ break;\r
\r
#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)\r
- case cmuClock_LETIMER0:\r
- EFM_ASSERT(div <= cmuClkDiv_32768);\r
+ case cmuClock_LETIMER0:\r
+ EFM_ASSERT(div <= cmuClkDiv_32768);\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK) |\r
- (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
- break;\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)\r
+ | (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+ break;\r
#endif\r
\r
#if defined(LCD_PRESENT)\r
- case cmuClock_LCDpre:\r
- EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));\r
+ case cmuClock_LCDpre:\r
+ EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK) |\r
- ((div - CMU_DivToLog2(cmuClkDiv_16)) << _CMU_LFAPRESC0_LCD_SHIFT);\r
- break;\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK)\r
+ | ((div - CMU_DivToLog2(cmuClkDiv_16))\r
+ << _CMU_LFAPRESC0_LCD_SHIFT);\r
+ break;\r
#endif /* defined(LCD_PRESENT) */\r
\r
#if defined(LESENSE_PRESENT)\r
- case cmuClock_LESENSE:\r
- EFM_ASSERT(div <= cmuClkDiv_8);\r
+ case cmuClock_LESENSE:\r
+ EFM_ASSERT(div <= cmuClkDiv_8);\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK) |\r
- (div << _CMU_LFAPRESC0_LESENSE_SHIFT);\r
- break;\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK)\r
+ | (div << _CMU_LFAPRESC0_LESENSE_SHIFT);\r
+ break;\r
#endif /* defined(LESENSE_PRESENT) */\r
\r
- default:\r
- EFM_ASSERT(0);\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
break;\r
- }\r
- break;\r
\r
- case CMU_LFBPRESC0_REG:\r
- switch (clock)\r
- {\r
+ case CMU_LFBPRESC0_REG:\r
+ switch (clock)\r
+ {\r
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)\r
- case cmuClock_LEUART0:\r
- EFM_ASSERT(div <= cmuClkDiv_8);\r
+ case cmuClock_LEUART0:\r
+ EFM_ASSERT(div <= cmuClkDiv_8);\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK) |\r
- (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);\r
- break;\r
+ CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)\r
+ | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+ break;\r
#endif\r
\r
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)\r
- case cmuClock_LEUART1:\r
- EFM_ASSERT(div <= cmuClkDiv_8);\r
+ case cmuClock_LEUART1:\r
+ EFM_ASSERT(div <= cmuClkDiv_8);\r
\r
- /* LF register about to be modified require sync. busy check */\r
- CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);\r
+ /* LF register about to be modified require sync. busy check */\r
+ syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
\r
- /* Convert to correct scale */\r
- div = CMU_DivToLog2(div);\r
+ /* Convert to correct scale */\r
+ div = CMU_DivToLog2(div);\r
\r
- CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK) |\r
- (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);\r
- break;\r
+ CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)\r
+ | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+ break;\r
#endif\r
\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+ break;\r
+\r
default:\r
EFM_ASSERT(0);\r
break;\r
- }\r
- break;\r
-\r
- default:\r
- EFM_ASSERT(0);\r
- break;\r
}\r
+#endif\r
}\r
\r
\r
/* Identify enable register */\r
switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)\r
{\r
- case CMU_HFPERCLKDIV_EN_REG:\r
- reg = &(CMU->HFPERCLKDIV);\r
- break;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ case CMU_CTRL_EN_REG:\r
+ reg = &CMU->CTRL;\r
+ break;\r
+#endif\r
\r
- case CMU_HFPERCLKEN0_EN_REG:\r
- reg = &(CMU->HFPERCLKEN0);\r
- break;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ case CMU_HFCORECLKEN0_EN_REG:\r
+ reg = &CMU->HFCORECLKEN0;\r
+#if defined( CMU_CTRL_HFLE )\r
+ /* Set HFLE and DIV4 factor for peripheral clock when\r
+ running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */\r
+ if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE())\r
+ {\r
+ /* Enable CMU HFLE */\r
+ BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
\r
- case CMU_HFCORECLKEN0_EN_REG:\r
- reg = &(CMU->HFCORECLKEN0);\r
+ /* Set DIV4 factor for peripheral clock */\r
+ BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+ _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+ }\r
+#endif\r
+ break;\r
+#endif\r
\r
-#if defined( CMU_CTRL_HFLE )\r
- /* Set HFLE and DIV4 factor for peripheral clock when\r
- running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */\r
- if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE )\r
- {\r
- /* Enable CMU HFLE */\r
- BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);\r
+#if defined( _CMU_HFBUSCLKEN0_MASK )\r
+ case CMU_HFBUSCLKEN0_EN_REG:\r
+ reg = &CMU->HFBUSCLKEN0;\r
+ break;\r
+#endif\r
\r
- /* Set DIV4 factor for peripheral clock */\r
- BITBAND_Peripheral(&(CMU->HFCORECLKDIV),\r
- _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
- }\r
+#if defined( _CMU_HFRADIOCLKEN0_MASK )\r
+ case CMU_HFRADIOCLKEN0_EN_REG:\r
+ reg = &CMU->HFRADIOCLKEN0;\r
+ break;\r
#endif\r
- break;\r
\r
- case CMU_LFACLKEN0_EN_REG:\r
- reg = &(CMU->LFACLKEN0);\r
- sync = CMU_SYNCBUSY_LFACLKEN0;\r
- break;\r
+#if defined( _CMU_HFPERCLKDIV_MASK )\r
+ case CMU_HFPERCLKDIV_EN_REG:\r
+ reg = &CMU->HFPERCLKDIV;\r
+ break;\r
+#endif\r
\r
- case CMU_LFBCLKEN0_EN_REG:\r
- reg = &(CMU->LFBCLKEN0);\r
- sync = CMU_SYNCBUSY_LFBCLKEN0;\r
- break;\r
+ case CMU_HFPERCLKEN0_EN_REG:\r
+ reg = &CMU->HFPERCLKEN0;\r
+ break;\r
\r
- case CMU_PCNT_EN_REG:\r
- reg = &(CMU->PCNTCTRL);\r
- break;\r
+ case CMU_LFACLKEN0_EN_REG:\r
+ reg = &CMU->LFACLKEN0;\r
+ sync = CMU_SYNCBUSY_LFACLKEN0;\r
+ break;\r
+\r
+ case CMU_LFBCLKEN0_EN_REG:\r
+ reg = &CMU->LFBCLKEN0;\r
+ sync = CMU_SYNCBUSY_LFBCLKEN0;\r
+ break;\r
\r
#if defined( _CMU_LFCCLKEN0_MASK )\r
- case CMU_LFCCLKEN0_EN_REG:\r
- reg = &(CMU->LFCCLKEN0);\r
- sync = CMU_SYNCBUSY_LFCCLKEN0;\r
- break;\r
+ case CMU_LFCCLKEN0_EN_REG:\r
+ reg = &CMU->LFCCLKEN0;\r
+ sync = CMU_SYNCBUSY_LFCCLKEN0;\r
+ break;\r
#endif\r
\r
- default: /* Cannot enable/disable clock point */\r
- EFM_ASSERT(0);\r
- return;\r
+#if defined( _CMU_LFECLKEN0_MASK )\r
+ case CMU_LFECLKEN0_EN_REG:\r
+ reg = &CMU->LFECLKEN0;\r
+ sync = CMU_SYNCBUSY_LFECLKEN0;\r
+ break;\r
+#endif\r
+\r
+ case CMU_PCNT_EN_REG:\r
+ reg = &CMU->PCNTCTRL;\r
+ break;\r
+\r
+ default: /* Cannot enable/disable clock point */\r
+ EFM_ASSERT(0);\r
+ return;\r
}\r
\r
/* Get bit position used to enable/disable */\r
/* LF synchronization required? */\r
if (sync)\r
{\r
- CMU_Sync(sync);\r
+ syncReg(sync);\r
}\r
\r
/* Set/clear bit as requested */\r
- BITBAND_Peripheral(reg, bit, (unsigned int)enable);\r
+ BUS_RegBitWrite(reg, bit, enable);\r
}\r
\r
\r
switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))\r
{\r
case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
ret = SystemHFClockGet();\r
#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
- /* Giant Gecko has an additional divider, not used by USBC */\r
- ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>\r
- _CMU_CTRL_HFCLKDIV_SHIFT));\r
+ /* Family with an additional divider. */\r
+ ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+ >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
#endif\r
- } break;\r
+#if defined( _CMU_HFPRESC_MASK )\r
+ ret = ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)\r
+ >> _CMU_HFPRESC_PRESC_SHIFT));\r
+#endif\r
+ break;\r
\r
-#if defined(_CMU_HFPERCLKEN0_USART0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_USART1_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_USART2_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_UART0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_UART1_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_TIMER0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_TIMER1_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_TIMER2_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_TIMER3_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_ACMP0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_ACMP1_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_DAC0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_IDAC0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_ADC0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_I2C0_MASK) || \\r
- defined(_CMU_HFPERCLKEN0_I2C1_MASK) || \\r
- defined(PRS_PRESENT) || \\r
- defined(VCMP_PRESENT)|| \\r
- defined(GPIO_PRESENT)\r
case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = SystemHFClockGet();\r
+ ret = SystemHFClockGet();\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
- /* Leopard/Giant Gecko has an additional divider */\r
- ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>\r
- _CMU_CTRL_HFCLKDIV_SHIFT));\r
+ /* Family with an additional divider. */\r
+ ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+ >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
#endif\r
- ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>\r
- _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;\r
- } break;\r
+ ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+ >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ret /= 1U + ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)\r
+ >> _CMU_HFPERPRESC_PRESC_SHIFT);\r
+#endif\r
+ break;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+ case (CMU_HFRADIO_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = SystemHFClockGet();\r
+ ret /= 1U + ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)\r
+ >> _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
+ break;\r
+#endif\r
+\r
+#if defined( CRYPTO_PRESENT ) \\r
+ || defined( LDMA_PRESENT ) \\r
+ || defined( GPCRC_PRESENT ) \\r
+ || defined( PRS_PRESENT ) \\r
+ || defined( GPIO_PRESENT )\r
+ case (CMU_HFBUS_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = SystemHFClockGet();\r
+ break;\r
+#endif\r
+\r
+ case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = SystemHFClockGet();\r
+ ret /= 1U + ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)\r
+ >> _CMU_HFCOREPRESC_PRESC_SHIFT);\r
+ break;\r
+\r
+ case (CMU_HFEXP_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = SystemHFClockGet();\r
+ ret /= 1U + ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)\r
+ >> _CMU_HFEXPPRESC_PRESC_SHIFT);\r
+ break;\r
#endif\r
\r
-#if defined(AES_PRESENT) || \\r
- defined(DMA_PRESENT) || \\r
- defined(EBI_PRESENT) || \\r
- defined(USB_PRESENT)\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+#if defined(AES_PRESENT) \\r
+ || defined(DMA_PRESENT) \\r
+ || defined(EBI_PRESENT) \\r
+ || defined(USB_PRESENT)\r
case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
{\r
ret = SystemCoreClockGet();\r
} break;\r
+#endif\r
#endif\r
\r
case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- } break;\r
-#if defined(_CMU_LFACLKEN0_RTC_MASK)\r
+ ret = lfClkGet(cmuClock_LFA);\r
+ break;\r
+\r
+#if defined( _CMU_LFACLKEN0_RTC_MASK )\r
case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>\r
- _CMU_LFAPRESC0_RTC_SHIFT;\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFA);\r
+ ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)\r
+ >> _CMU_LFAPRESC0_RTC_SHIFT;\r
+ break;\r
#endif\r
-#if defined(_CMU_LFACLKEN0_LETIMER0_MASK)\r
- case (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>\r
- _CMU_LFAPRESC0_LETIMER0_SHIFT;\r
- } break;\r
+\r
+#if defined( _CMU_LFECLKEN0_RTCC_MASK )\r
+ case (CMU_RTCC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = lfClkGet(cmuClock_LFE);\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFACLKEN0_LETIMER0_MASK )\r
+ case (CMU_LETIMER0_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = lfClkGet(cmuClock_LFA);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+ >> _CMU_LFAPRESC0_LETIMER0_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ret /= CMU_Log2ToDiv((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+ >> _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
#endif\r
+ break;\r
+#endif\r
+\r
#if defined(_CMU_LFACLKEN0_LCD_MASK)\r
case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>\r
- _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16);\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFA);\r
+ ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+ >> _CMU_LFAPRESC0_LCD_SHIFT)\r
+ + CMU_DivToLog2(cmuClkDiv_16);\r
+ break;\r
\r
case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>\r
- _CMU_LFAPRESC0_LCD_SHIFT;\r
- ret /= (1 + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >>\r
- _CMU_LCDCTRL_FDIV_SHIFT));\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFA);\r
+ ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+ >> _CMU_LFAPRESC0_LCD_SHIFT;\r
+ ret /= 1U + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK)\r
+ >> _CMU_LCDCTRL_FDIV_SHIFT);\r
+ break;\r
#endif\r
+\r
#if defined(_CMU_LFACLKEN0_LESENSE_MASK)\r
case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFA);\r
- ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>\r
- _CMU_LFAPRESC0_LESENSE_SHIFT;\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFA);\r
+ ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)\r
+ >> _CMU_LFAPRESC0_LESENSE_SHIFT;\r
+ break;\r
#endif\r
+\r
case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFB);\r
- } break;\r
-#if defined(_CMU_LFBCLKEN0_LEUART0_MASK)\r
+ ret = lfClkGet(cmuClock_LFB);\r
+ break;\r
+\r
+#if defined( _CMU_LFBCLKEN0_LEUART0_MASK )\r
case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFB);\r
- ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>\r
- _CMU_LFBPRESC0_LEUART0_SHIFT;\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFB);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART0_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART0_SHIFT);\r
#endif\r
-#if defined(_CMU_LFBCLKEN0_LEUART1_MASK)\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBCLKEN0_LEUART1_MASK )\r
case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_LFClkGet(CMU_LFB);\r
- ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>\r
- _CMU_LFBPRESC0_LEUART1_SHIFT;\r
- } break;\r
+ ret = lfClkGet(cmuClock_LFB);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART1_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+#endif\r
+ break;\r
+#endif\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ case (CMU_LFE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+ ret = lfClkGet(cmuClock_LFE);\r
+ break;\r
#endif\r
\r
case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_DBGClkGet();\r
- } break;\r
+ ret = dbgClkGet();\r
+ break;\r
\r
case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_AUXClkGet();\r
- } break;\r
+ ret = auxClkGet();\r
+ break;\r
\r
#if defined(USB_PRESENT)\r
case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
- {\r
- ret = CMU_USBCClkGet();\r
- } break;\r
+ ret = usbCClkGet();\r
+ break;\r
#endif\r
+\r
default:\r
- {\r
EFM_ASSERT(0);\r
ret = 0;\r
- } break;\r
+ break;\r
}\r
+\r
return ret;\r
}\r
\r
\r
-/**************************************************************************//**\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/***************************************************************************//**\r
* @brief\r
- * Get currently selected reference clock used for a clock branch.\r
+ * Get clock prescaler.\r
*\r
* @param[in] clock\r
- * Clock branch to fetch selected ref. clock for. One of:\r
- * @li #cmuClock_HF\r
- * @li #cmuClock_LFA\r
- * @li #cmuClock_LFB\r
- * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT\r
- * @li #cmuClock_USBC\r
- * @endif\r
+ * Clock point to get the prescaler for. Notice that not all clock points\r
+ * have a prescaler. Please refer to CMU overview in reference manual.\r
*\r
* @return\r
- * Reference clock used for clocking selected branch, #cmuSelect_Error if\r
- * invalid @p clock provided.\r
- *****************************************************************************/\r
-CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)\r
+ * The prescaler value of the current clock point. 0 is returned\r
+ * if @p clock specifies a clock point without a prescaler.\r
+ ******************************************************************************/\r
+uint32_t CMU_ClockPrescGet(CMU_Clock_TypeDef clock)\r
{\r
- CMU_Select_TypeDef ret = cmuSelect_Disabled;\r
- uint32_t selReg;\r
- uint32_t statusClkSelMask;\r
-\r
- statusClkSelMask =\r
- (CMU_STATUS_HFRCOSEL |\r
- CMU_STATUS_HFXOSEL |\r
- CMU_STATUS_LFRCOSEL |\r
-#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
- CMU_STATUS_USHFRCODIV2SEL |\r
-#endif\r
- CMU_STATUS_LFXOSEL);\r
+ uint32_t prescReg;\r
+ uint32_t ret;\r
\r
- selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
+ /* Get prescaler register id. */\r
+ prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;\r
\r
- switch (selReg)\r
+ switch (prescReg)\r
{\r
- case CMU_HFCLKSEL_REG:\r
- switch (CMU->STATUS & statusClkSelMask)\r
- {\r
- case CMU_STATUS_LFXOSEL:\r
- ret = cmuSelect_LFXO;\r
+ case CMU_HFPRESC_REG:\r
+ ret = ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)\r
+ >> _CMU_HFPRESC_PRESC_SHIFT);\r
break;\r
\r
- case CMU_STATUS_LFRCOSEL:\r
- ret = cmuSelect_LFRCO;\r
+ case CMU_HFEXPPRESC_REG:\r
+ ret = ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)\r
+ >> _CMU_HFEXPPRESC_PRESC_SHIFT);\r
break;\r
\r
- case CMU_STATUS_HFXOSEL:\r
- ret = cmuSelect_HFXO;\r
+ case CMU_HFCLKLEPRESC_REG:\r
+ ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+ >> _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);\r
break;\r
\r
-#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
- case CMU_STATUS_USHFRCODIV2SEL:\r
- ret = cmuSelect_USHFRCODIV2;\r
+ case CMU_HFPERPRESC_REG:\r
+ ret = ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)\r
+ >> _CMU_HFPERPRESC_PRESC_SHIFT);\r
break;\r
-#endif\r
\r
- default:\r
- ret = cmuSelect_HFRCO;\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+ case CMU_HFRADIOPRESC_REG:\r
+ ret = ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)\r
+ >> _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
break;\r
- }\r
- break;\r
+#endif\r
\r
- case CMU_LFACLKSEL_REG:\r
- switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)\r
- {\r
- case CMU_LFCLKSEL_LFA_LFRCO:\r
- ret = cmuSelect_LFRCO;\r
+ case CMU_HFCOREPRESC_REG:\r
+ ret = ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)\r
+ >> _CMU_HFCOREPRESC_PRESC_SHIFT);\r
break;\r
\r
- case CMU_LFCLKSEL_LFA_LFXO:\r
- ret = cmuSelect_LFXO;\r
+ case CMU_LFAPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+#if defined( _CMU_LFAPRESC0_LETIMER0_MASK )\r
+ case cmuClock_LETIMER0:\r
+ ret = (((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+ >> _CMU_LFAPRESC0_LETIMER0_SHIFT));\r
+ /* Convert the exponent to prescaler value. */\r
+ ret = CMU_Log2ToDiv(ret) - 1U;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0U;\r
+ break;\r
+ }\r
break;\r
\r
- case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
- ret = cmuSelect_CORELEDIV2;\r
+ case CMU_LFBPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+#if defined( _CMU_LFBPRESC0_LEUART0_MASK )\r
+ case cmuClock_LEUART0:\r
+ ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART0_SHIFT));\r
+ /* Convert the exponent to prescaler value. */\r
+ ret = CMU_Log2ToDiv(ret) - 1U;\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBPRESC0_LEUART1_MASK )\r
+ case cmuClock_LEUART1:\r
+ ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+ >> _CMU_LFBPRESC0_LEUART1_SHIFT));\r
+ /* Convert the exponent to prescaler value. */\r
+ ret = CMU_Log2ToDiv(ret) - 1U;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0U;\r
+ break;\r
+ }\r
break;\r
\r
- default:\r
-#if defined( CMU_LFCLKSEL_LFAE )\r
- if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)\r
+ case CMU_LFEPRESC0_REG:\r
+ switch (clock)\r
{\r
- ret = cmuSelect_ULFRCO;\r
- break;\r
- }\r
-#else\r
- ret = cmuSelect_Disabled;\r
+#if defined( RTCC_PRESENT )\r
+ case cmuClock_RTCC:\r
+ /* No need to compute with LFEPRESC0_RTCC - DIV1 is the only */\r
+ /* allowed value. Convert the exponent to prescaler value. */\r
+ ret = _CMU_LFEPRESC0_RTCC_DIV1;\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0U;\r
+ break;\r
#endif\r
+ }\r
break;\r
- }\r
- break;\r
\r
- case CMU_LFBCLKSEL_REG:\r
- switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)\r
- {\r
- case CMU_LFCLKSEL_LFB_LFRCO:\r
- ret = cmuSelect_LFRCO;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0U;\r
break;\r
+ }\r
\r
- case CMU_LFCLKSEL_LFB_LFXO:\r
- ret = cmuSelect_LFXO;\r
- break;\r
+ return ret;\r
+}\r
+#endif\r
\r
- case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:\r
- ret = cmuSelect_CORELEDIV2;\r
- break;\r
\r
- default:\r
-#if defined( CMU_LFCLKSEL_LFBE )\r
- if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)\r
- {\r
- ret = cmuSelect_ULFRCO;\r
- break;\r
- }\r
-#else\r
- ret = cmuSelect_Disabled;\r
-#endif\r
- break;\r
- }\r
- break;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Set clock prescaler.\r
+ *\r
+ * @note\r
+ * If setting a LF clock prescaler, synchronization into the low frequency\r
+ * domain is required. If the same register is modified before a previous\r
+ * update has completed, this function will stall until the previous\r
+ * synchronization has completed. Please refer to CMU_FreezeEnable() for\r
+ * a suggestion on how to reduce stalling time in some use cases.\r
+ *\r
+ * @param[in] clock\r
+ * Clock point to set prescaler for. Notice that not all clock points\r
+ * have a prescaler, please refer to CMU overview in the reference manual.\r
+ *\r
+ * @param[in] presc\r
+ * The clock prescaler to use.\r
+ ******************************************************************************/\r
+void CMU_ClockPrescSet(CMU_Clock_TypeDef clock, CMU_ClkPresc_TypeDef presc)\r
+{\r
+ uint32_t freq;\r
+ uint32_t prescReg;\r
\r
-#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
- case CMU_LFCCLKSEL_REG:\r
- switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)\r
- {\r
- case CMU_LFCLKSEL_LFC_LFRCO:\r
- ret = cmuSelect_LFRCO;\r
- break;\r
+ /* Get divisor reg id */\r
+ prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;\r
\r
- case CMU_LFCLKSEL_LFC_LFXO:\r
- ret = cmuSelect_LFXO;\r
- break;\r
+ switch (prescReg)\r
+ {\r
+ case CMU_HFPRESC_REG:\r
+ EFM_ASSERT(presc < 32U);\r
\r
- default:\r
- ret = cmuSelect_Disabled;\r
+ CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_PRESC_MASK)\r
+ | (presc << _CMU_HFPRESC_PRESC_SHIFT);\r
break;\r
- }\r
- break;\r
-#endif\r
\r
- case CMU_DBGCLKSEL_REG:\r
+ case CMU_HFEXPPRESC_REG:\r
+ EFM_ASSERT(presc < 32U);\r
\r
-#if defined( _CMU_DBGCLKSEL_DBG_MASK )\r
- switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)\r
- {\r
- case CMU_DBGCLKSEL_DBG_HFCLK:\r
- ret = cmuSelect_HFCLK;\r
+ CMU->HFEXPPRESC = (CMU->HFEXPPRESC & ~_CMU_HFEXPPRESC_PRESC_MASK)\r
+ | (presc << _CMU_HFEXPPRESC_PRESC_SHIFT);\r
break;\r
\r
- case CMU_DBGCLKSEL_DBG_AUXHFRCO:\r
- ret = cmuSelect_AUXHFRCO;\r
+ case CMU_HFCLKLEPRESC_REG:\r
+ EFM_ASSERT(presc < 2U);\r
+\r
+ /* Specifies the clock divider for HFCLKLE. When running at frequencies\r
+ * higher than 32 MHz, this must be set to DIV4. */\r
+ CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+ | (presc << _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);\r
break;\r
- }\r
-#else\r
- ret = cmuSelect_AUXHFRCO;\r
-#endif /* CMU_DBGCLKSEL_DBG */\r
\r
-#if defined( _CMU_CTRL_DBGCLK_MASK )\r
- switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)\r
- {\r
- case CMU_CTRL_DBGCLK_AUXHFRCO:\r
- ret = cmuSelect_AUXHFRCO;\r
+ case CMU_HFPERPRESC_REG:\r
+ EFM_ASSERT(presc < 512U);\r
+\r
+ CMU->HFPERPRESC = (CMU->HFPERPRESC & ~_CMU_HFPERPRESC_PRESC_MASK)\r
+ | (presc << _CMU_HFPERPRESC_PRESC_SHIFT);\r
break;\r
\r
- case CMU_CTRL_DBGCLK_HFCLK:\r
- ret = cmuSelect_HFCLK;\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+ case CMU_HFRADIOPRESC_REG:\r
+ EFM_ASSERT(presc < 512U);\r
+\r
+ CMU->HFRADIOPRESC = (CMU->HFRADIOPRESC & ~_CMU_HFRADIOPRESC_PRESC_MASK)\r
+ | (presc << _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
break;\r
- }\r
-#else\r
- ret = cmuSelect_AUXHFRCO;\r
#endif\r
- break;\r
\r
+ case CMU_HFCOREPRESC_REG:\r
+ EFM_ASSERT(presc < 512U);\r
\r
-#if defined(USB_PRESENT)\r
+ /* Configure worst case wait states for flash access before setting\r
+ * the prescaler. */\r
+ flashWaitStateControl(CMU_MAX_FREQ_0WS + 1);\r
\r
- case CMU_USBCCLKSEL_REG:\r
- switch(CMU->STATUS &\r
- (CMU_STATUS_USBCLFXOSEL |\r
-#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
- CMU_STATUS_USBCHFCLKSEL |\r
-#endif\r
-#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
- CMU_STATUS_USBCUSHFRCOSEL |\r
-#endif\r
- CMU_STATUS_USBCLFRCOSEL))\r
- {\r
+ CMU->HFCOREPRESC = (CMU->HFCOREPRESC & ~_CMU_HFCOREPRESC_PRESC_MASK)\r
+ | (presc << _CMU_HFCOREPRESC_PRESC_SHIFT);\r
\r
- case CMU_STATUS_USBCLFXOSEL:\r
- ret = cmuSelect_LFXO;\r
- break;\r
+ /* Update CMSIS core clock variable */\r
+ /* (The function will update the global variable) */\r
+ freq = SystemCoreClockGet();\r
\r
- case CMU_STATUS_USBCLFRCOSEL:\r
- ret = cmuSelect_LFRCO;\r
+ /* Optimize flash access wait state setting for current core clk */\r
+ flashWaitStateControl(freq);\r
break;\r
\r
-#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
- case CMU_STATUS_USBCHFCLKSEL:\r
- ret = cmuSelect_HFCLK;\r
- break;\r
-#endif\r
+ case CMU_LFAPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+#if defined( RTC_PRESENT )\r
+ case cmuClock_RTC:\r
+ EFM_ASSERT(presc <= 32768U);\r
\r
-#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
- case CMU_STATUS_USBCUSHFRCOSEL:\r
- ret = cmuSelect_USHFRCO;\r
- break;\r
-#endif\r
+ /* Convert prescaler value to DIV exponent scale. */\r
+ presc = CMU_PrescToLog2(presc);\r
\r
- default:\r
- ret = cmuSelect_Disabled;\r
- break;\r
- }\r
- break;\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)\r
+ | (presc << _CMU_LFAPRESC0_RTC_SHIFT);\r
+ break;\r
#endif\r
\r
- default:\r
- EFM_ASSERT(0);\r
- ret = cmuSelect_Error;\r
- break;\r
- }\r
+#if defined( RTCC_PRESENT )\r
+ case cmuClock_RTCC:\r
+#if defined( _CMU_LFEPRESC0_RTCC_MASK )\r
+ /* DIV1 is the only accepted value. */\r
+ EFM_ASSERT(presc <= 0U);\r
\r
- return ret;\r
-}\r
+ /* LF register about to be modified require sync. Busy check.. */\r
+ syncReg(CMU_SYNCBUSY_LFEPRESC0);\r
\r
+ CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)\r
+ | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);\r
+#else\r
+ EFM_ASSERT(presc <= 32768U);\r
\r
-/**************************************************************************//**\r
- * @brief\r
+ /* Convert prescaler value to DIV exponent scale. */\r
+ presc = CMU_PrescToLog2(presc);\r
+\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTCC_MASK)\r
+ | (presc << _CMU_LFAPRESC0_RTCC_SHIFT);\r
+#endif\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFAPRESC0_LETIMER0_MASK )\r
+ case cmuClock_LETIMER0:\r
+ EFM_ASSERT(presc <= 32768U);\r
+\r
+ /* Convert prescaler value to DIV exponent scale. */\r
+ presc = CMU_PrescToLog2(presc);\r
+\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+ CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)\r
+ | (presc << _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+ break;\r
+\r
+ case CMU_LFBPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+#if defined( _CMU_LFBPRESC0_LEUART0_MASK )\r
+ case cmuClock_LEUART0:\r
+ EFM_ASSERT(presc <= 8U);\r
+\r
+ /* Convert prescaler value to DIV exponent scale. */\r
+ presc = CMU_PrescToLog2(presc);\r
+\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+ CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)\r
+ | (presc << _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBPRESC0_LEUART1_MASK )\r
+ case cmuClock_LEUART1:\r
+ EFM_ASSERT(presc <= 8U);\r
+\r
+ /* Convert prescaler value to DIV exponent scale. */\r
+ presc = CMU_PrescToLog2(presc);\r
+\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+ CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)\r
+ | (presc << _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+ break;\r
+\r
+ case CMU_LFEPRESC0_REG:\r
+ switch (clock)\r
+ {\r
+#if defined( _CMU_LFEPRESC0_RTCC_MASK )\r
+ case cmuClock_RTCC:\r
+ EFM_ASSERT(presc <= 0U);\r
+\r
+ /* LF register about to be modified require sync. Busy check. */\r
+ syncReg(CMU_SYNCBUSY_LFEPRESC0);\r
+\r
+ CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)\r
+ | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get currently selected reference clock used for a clock branch.\r
+ *\r
+ * @param[in] clock\r
+ * Clock branch to fetch selected ref. clock for. One of:\r
+ * @li #cmuClock_HF\r
+ * @li #cmuClock_LFA\r
+ * @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO\r
+ * @li #cmuClock_LFC\r
+ * @endif @if _SILICON_LABS_32B_PLATFORM_2\r
+ * @li #cmuClock_LFE\r
+ * @endif\r
+ * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT\r
+ * @li #cmuClock_USBC\r
+ * @endif\r
+ *\r
+ * @return\r
+ * Reference clock used for clocking selected branch, #cmuSelect_Error if\r
+ * invalid @p clock provided.\r
+ ******************************************************************************/\r
+CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)\r
+{\r
+ CMU_Select_TypeDef ret = cmuSelect_Disabled;\r
+ uint32_t selReg;\r
+\r
+ selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
+\r
+ switch (selReg)\r
+ {\r
+ case CMU_HFCLKSEL_REG:\r
+#if defined( _CMU_HFCLKSEL_HF_MASK )\r
+ switch (CMU->HFCLKSEL & _CMU_HFCLKSEL_HF_MASK)\r
+ {\r
+ case CMU_HFCLKSEL_HF_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_HFCLKSEL_HF_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_HFCLKSEL_HF_HFXO:\r
+ ret = cmuSelect_HFXO;\r
+ break;\r
+\r
+ default:\r
+ ret = cmuSelect_HFRCO;\r
+ break;\r
+ }\r
+#else\r
+ switch (CMU->STATUS\r
+ & (CMU_STATUS_HFRCOSEL\r
+ | CMU_STATUS_HFXOSEL\r
+ | CMU_STATUS_LFRCOSEL\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+ | CMU_STATUS_USHFRCODIV2SEL\r
+#endif\r
+ | CMU_STATUS_LFXOSEL))\r
+ {\r
+ case CMU_STATUS_LFXOSEL:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_STATUS_LFRCOSEL:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_STATUS_HFXOSEL:\r
+ ret = cmuSelect_HFXO;\r
+ break;\r
+\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+ case CMU_STATUS_USHFRCODIV2SEL:\r
+ ret = cmuSelect_USHFRCODIV2;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ ret = cmuSelect_HFRCO;\r
+ break;\r
+ }\r
+#endif\r
+ break;\r
+\r
+ case CMU_LFACLKSEL_REG:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+ switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)\r
+ {\r
+ case CMU_LFCLKSEL_LFA_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFCLKSEL_LFA_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )\r
+ case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
+ ret = cmuSelect_CORELEDIV2;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+#if defined( CMU_LFCLKSEL_LFAE )\r
+ if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)\r
+ {\r
+ ret = cmuSelect_ULFRCO;\r
+ break;\r
+ }\r
+#else\r
+ ret = cmuSelect_Disabled;\r
+#endif\r
+ break;\r
+ }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFACLKSEL_MASK )\r
+ switch (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK)\r
+ {\r
+ case CMU_LFACLKSEL_LFA_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFACLKSEL_LFA_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_LFACLKSEL_LFA_ULFRCO:\r
+ ret = cmuSelect_ULFRCO;\r
+ break;\r
+\r
+#if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+ case CMU_LFACLKSEL_LFA_HFCLKLE:\r
+ ret = cmuSelect_HFCLKLE;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ ret = cmuSelect_Disabled;\r
+ break;\r
+ }\r
+#endif\r
+ break;\r
+\r
+ case CMU_LFBCLKSEL_REG:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+ switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)\r
+ {\r
+ case CMU_LFCLKSEL_LFB_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFCLKSEL_LFB_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 )\r
+ case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:\r
+ ret = cmuSelect_CORELEDIV2;\r
+ break;\r
+#endif\r
+\r
+#if defined( CMU_LFCLKSEL_LFB_HFCLKLE )\r
+ case CMU_LFCLKSEL_LFB_HFCLKLE:\r
+ ret = cmuSelect_HFCLKLE;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+#if defined( CMU_LFCLKSEL_LFBE )\r
+ if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)\r
+ {\r
+ ret = cmuSelect_ULFRCO;\r
+ break;\r
+ }\r
+#else\r
+ ret = cmuSelect_Disabled;\r
+#endif\r
+ break;\r
+ }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFBCLKSEL_MASK )\r
+ switch (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK)\r
+ {\r
+ case CMU_LFBCLKSEL_LFB_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFBCLKSEL_LFB_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_LFBCLKSEL_LFB_ULFRCO:\r
+ ret = cmuSelect_ULFRCO;\r
+ break;\r
+\r
+ case CMU_LFBCLKSEL_LFB_HFCLKLE:\r
+ ret = cmuSelect_HFCLKLE;\r
+ break;\r
+\r
+ default:\r
+ ret = cmuSelect_Disabled;\r
+ break;\r
+ }\r
+#endif\r
+ break;\r
+\r
+#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
+ case CMU_LFCCLKSEL_REG:\r
+ switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)\r
+ {\r
+ case CMU_LFCLKSEL_LFC_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFCLKSEL_LFC_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ default:\r
+ ret = cmuSelect_Disabled;\r
+ break;\r
+ }\r
+ break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKSEL_LFE_MASK )\r
+ case CMU_LFECLKSEL_REG:\r
+ switch (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK)\r
+ {\r
+ case CMU_LFECLKSEL_LFE_LFRCO:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ case CMU_LFECLKSEL_LFE_LFXO:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_LFECLKSEL_LFE_ULFRCO:\r
+ ret = cmuSelect_ULFRCO;\r
+ break;\r
+\r
+#if defined ( _CMU_LFECLKSEL_LFE_HFCLKLE )\r
+ case CMU_LFECLKSEL_LFE_HFCLKLE:\r
+ ret = cmuSelect_HFCLKLE;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ ret = cmuSelect_Disabled;\r
+ break;\r
+ }\r
+ break;\r
+#endif /* CMU_LFECLKSEL_REG */\r
+\r
+ case CMU_DBGCLKSEL_REG:\r
+#if defined( _CMU_DBGCLKSEL_DBG_MASK )\r
+ switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)\r
+ {\r
+ case CMU_DBGCLKSEL_DBG_HFCLK:\r
+ ret = cmuSelect_HFCLK;\r
+ break;\r
+\r
+ case CMU_DBGCLKSEL_DBG_AUXHFRCO:\r
+ ret = cmuSelect_AUXHFRCO;\r
+ break;\r
+ }\r
+#else\r
+ ret = cmuSelect_AUXHFRCO;\r
+#endif /* CMU_DBGCLKSEL_DBG */\r
+\r
+#if defined( _CMU_CTRL_DBGCLK_MASK )\r
+ switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)\r
+ {\r
+ case CMU_CTRL_DBGCLK_AUXHFRCO:\r
+ ret = cmuSelect_AUXHFRCO;\r
+ break;\r
+\r
+ case CMU_CTRL_DBGCLK_HFCLK:\r
+ ret = cmuSelect_HFCLK;\r
+ break;\r
+ }\r
+#else\r
+ ret = cmuSelect_AUXHFRCO;\r
+#endif\r
+ break;\r
+\r
+\r
+#if defined( USB_PRESENT )\r
+ case CMU_USBCCLKSEL_REG:\r
+ switch (CMU->STATUS\r
+ & (CMU_STATUS_USBCLFXOSEL\r
+#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
+ | CMU_STATUS_USBCHFCLKSEL\r
+#endif\r
+#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
+ | CMU_STATUS_USBCUSHFRCOSEL\r
+#endif\r
+ | CMU_STATUS_USBCLFRCOSEL))\r
+ {\r
+#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
+ case CMU_STATUS_USBCHFCLKSEL:\r
+ ret = cmuSelect_HFCLK;\r
+ break;\r
+#endif\r
+\r
+#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
+ case CMU_STATUS_USBCUSHFRCOSEL:\r
+ ret = cmuSelect_USHFRCO;\r
+ break;\r
+#endif\r
+\r
+ case CMU_STATUS_USBCLFXOSEL:\r
+ ret = cmuSelect_LFXO;\r
+ break;\r
+\r
+ case CMU_STATUS_USBCLFRCOSEL:\r
+ ret = cmuSelect_LFRCO;\r
+ break;\r
+\r
+ default:\r
+ ret = cmuSelect_Disabled;\r
+ break;\r
+ }\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = cmuSelect_Error;\r
+ break;\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
* Select reference clock/oscillator used for a clock branch.\r
*\r
* @details\r
* Clock branch to select reference clock for. One of:\r
* @li #cmuClock_HF\r
* @li #cmuClock_LFA\r
- * @li #cmuClock_LFB\r
+ * @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO\r
+ * @li #cmuClock_LFC\r
+ * @endif @if _SILICON_LABS_32B_PLATFORM_2\r
+ * @li #cmuClock_LFE\r
+ * @endif\r
* @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT\r
* @li #cmuClock_USBC\r
* @endif\r
* @li #cmuSelect_HFCLK @ifnot DOXYDOC_EFM32_GECKO_FAMILY\r
* @li #cmuSelect_ULFRCO\r
* @endif\r
- *****************************************************************************/\r
+ ******************************************************************************/\r
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)\r
{\r
uint32_t select = cmuOsc_HFRCO;\r
CMU_Osc_TypeDef osc = cmuOsc_HFRCO;\r
uint32_t freq;\r
- uint32_t selReg;\r
-#if !defined(_EFM32_GECKO_FAMILY)\r
+ uint32_t tmp;\r
+ uint32_t selRegId;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ volatile uint32_t *selReg = NULL;\r
+#endif\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
uint32_t lfExtended = 0;\r
#endif\r
- uint32_t tmp;\r
\r
- selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
+ selRegId = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
\r
- switch (selReg)\r
+ switch (selRegId)\r
{\r
- case CMU_HFCLKSEL_REG:\r
- switch (ref)\r
- {\r
- case cmuSelect_LFXO:\r
- select = CMU_CMD_HFCLKSEL_LFXO;\r
- osc = cmuOsc_LFXO;\r
- break;\r
-\r
- case cmuSelect_LFRCO:\r
- select = CMU_CMD_HFCLKSEL_LFRCO;\r
- osc = cmuOsc_LFRCO;\r
- break;\r
-\r
- case cmuSelect_HFXO:\r
- select = CMU_CMD_HFCLKSEL_HFXO;\r
- osc = cmuOsc_HFXO;\r
-#if defined( CMU_CTRL_HFLE )\r
- /* Adjust HFXO buffer current for high frequencies, enable HFLE for */\r
- /* frequencies above CMU_MAX_FREQ_HFLE. */\r
- if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE)\r
+ case CMU_HFCLKSEL_REG:\r
+ switch (ref)\r
{\r
- CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |\r
- CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ |\r
- /* Must have HFLE enabled to access some LE peripherals >=32MHz */\r
- CMU_CTRL_HFLE;\r
-\r
- /* Set HFLE and DIV4 factor for peripheral clock if HFCORE clock for\r
- LE is enabled. */\r
- if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)\r
- {\r
- BITBAND_Peripheral(&(CMU->HFCORECLKDIV),\r
- _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
- }\r
- } else {\r
- /* This can happen if the user configures the EFM32_HFXO_FREQ to */\r
- /* use another oscillator frequency */\r
- CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |\r
- CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;\r
- }\r
-#endif\r
- break;\r
-\r
- case cmuSelect_HFRCO:\r
- select = CMU_CMD_HFCLKSEL_HFRCO;\r
- osc = cmuOsc_HFRCO;\r
- break;\r
+ case cmuSelect_LFXO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ select = CMU_HFCLKSEL_HF_LFXO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ select = CMU_CMD_HFCLKSEL_LFXO;\r
+#endif\r
+ osc = cmuOsc_LFXO;\r
+ break;\r
+\r
+ case cmuSelect_LFRCO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ select = CMU_HFCLKSEL_HF_LFRCO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ select = CMU_CMD_HFCLKSEL_LFRCO;\r
+#endif\r
+ osc = cmuOsc_LFRCO;\r
+ break;\r
+\r
+ case cmuSelect_HFXO:\r
+ osc = cmuOsc_HFXO;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ select = CMU_HFCLKSEL_HF_HFXO;\r
+ /* Adjust HFXO buffer current for high frequencies, */\r
+ /* enable WSHFLE for frequencies above 32MHz. */\r
+ if (SystemHFXOClockGet() > 32000000)\r
+ {\r
+ CMU->CTRL |= CMU_CTRL_WSHFLE;\r
+ }\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ select = CMU_CMD_HFCLKSEL_HFXO;\r
+#if defined( CMU_CTRL_HFLE )\r
+ /* Adjust HFXO buffer current for high frequencies, */\r
+ /* enable HFLE for frequencies above CMU_MAX_FREQ_HFLE. */\r
+ if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE())\r
+ {\r
+ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)\r
+ | CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ\r
+ /* Must have HFLE enabled to access some LE peripherals >=32MHz */\r
+ | CMU_CTRL_HFLE;\r
+\r
+ /* Set HFLE and DIV4 factor for peripheral clock if HFCORE */\r
+ /* clock for LE is enabled. */\r
+ if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)\r
+ {\r
+ BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+ _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* This can happen if the user configures the EFM32_HFXO_FREQ to */\r
+ /* use another oscillator frequency */\r
+ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)\r
+ | CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;\r
+ }\r
+#endif\r
+#endif\r
+ break;\r
+\r
+ case cmuSelect_HFRCO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ select = CMU_HFCLKSEL_HF_HFRCO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ select = CMU_CMD_HFCLKSEL_HFRCO;\r
+#endif\r
+ osc = cmuOsc_HFRCO;\r
+ break;\r
\r
#if defined( CMU_CMD_HFCLKSEL_USHFRCODIV2 )\r
- case cmuSelect_USHFRCODIV2:\r
- select = CMU_CMD_HFCLKSEL_USHFRCODIV2;\r
- osc = cmuOsc_USHFRCO;\r
- break;\r
+ case cmuSelect_USHFRCODIV2:\r
+ select = CMU_CMD_HFCLKSEL_USHFRCODIV2;\r
+ osc = cmuOsc_USHFRCO;\r
+ break;\r
#endif\r
\r
-#if !defined( _EFM32_GECKO_FAMILY )\r
- case cmuSelect_ULFRCO:\r
- /* ULFRCO cannot be used as HFCLK */\r
- EFM_ASSERT(0);\r
- break;\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO ) || defined( CMU_LFACLKSEL_LFA_ULFRCO )\r
+ case cmuSelect_ULFRCO:\r
+ /* ULFRCO cannot be used as HFCLK */\r
+ EFM_ASSERT(0);\r
+ return;\r
#endif\r
\r
- default:\r
- EFM_ASSERT(0);\r
- return;\r
- }\r
-\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(osc, true, true);\r
-\r
- /* Configure worst case wait states for flash access before selecting */\r
- CMU_FlashWaitStateMax();\r
-\r
- /* Switch to selected oscillator */\r
- CMU->CMD = select;\r
-\r
- /* Keep EMU module informed */\r
- EMU_UpdateOscConfig();\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
\r
- /* Update CMSIS core clock variable */\r
- /* (The function will update the global variable) */\r
- freq = SystemCoreClockGet();\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(osc, true, true);\r
\r
- /* Optimize flash access wait state setting for currently selected core clk */\r
- CMU_FlashWaitStateControl(freq);\r
- break;\r
+ /* Configure worst case wait states for flash access before selecting */\r
+ flashWaitStateMax();\r
\r
- case CMU_LFACLKSEL_REG:\r
- case CMU_LFBCLKSEL_REG:\r
+ /* Switch to selected oscillator */\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ CMU->HFCLKSEL = select;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ CMU->CMD = select;\r
+#endif\r
\r
- switch (ref)\r
- {\r
- case cmuSelect_Disabled:\r
- tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
- break;\r
+ /* Keep EMU module informed */\r
+ EMU_UpdateOscConfig();\r
\r
- case cmuSelect_LFXO:\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
- tmp = _CMU_LFCLKSEL_LFA_LFXO;\r
- break;\r
+ /* Update CMSIS core clock variable */\r
+ /* (The function will update the global variable) */\r
+ freq = SystemCoreClockGet();\r
\r
- case cmuSelect_LFRCO:\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
- tmp = _CMU_LFCLKSEL_LFA_LFRCO;\r
+ /* Optimize flash access wait state setting for currently selected core clk */\r
+ flashWaitStateControl(freq);\r
break;\r
\r
- case cmuSelect_CORELEDIV2:\r
- /* Ensure HFCORE to LE clocking is enabled */\r
- BITBAND_Peripheral(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);\r
- tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;\r
-#if defined( CMU_CTRL_HFLE )\r
- /* If core frequency is higher than CMU_MAX_FREQ_HFLE on\r
- Giant/Leopard/Wonder, enable HFLE and DIV4. */\r
- freq = SystemCoreClockGet();\r
- if(freq > CMU_MAX_FREQ_HFLE)\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ case CMU_LFACLKSEL_REG:\r
+ selReg = (selReg == NULL) ? &CMU->LFACLKSEL : selReg;\r
+#if !defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+ /* HFCLKCLE can not be used as LFACLK */\r
+ EFM_ASSERT(ref != cmuSelect_HFCLKLE);\r
+#endif\r
+ case CMU_LFECLKSEL_REG:\r
+ selReg = (selReg == NULL) ? &CMU->LFECLKSEL : selReg;\r
+#if !defined( _CMU_LFECLKSEL_LFE_HFCLKLE )\r
+ /* HFCLKCLE can not be used as LFECLK */\r
+ EFM_ASSERT(ref != cmuSelect_HFCLKLE);\r
+#endif\r
+ case CMU_LFBCLKSEL_REG:\r
+ selReg = (selReg == NULL) ? &CMU->LFBCLKSEL : selReg;\r
+ switch (ref)\r
{\r
- /* Enable CMU HFLE */\r
- BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);\r
-\r
- /* Enable DIV4 factor for peripheral clock */\r
- BITBAND_Peripheral(&(CMU->HFCORECLKDIV),\r
- _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+ case cmuSelect_Disabled:\r
+ tmp = _CMU_LFACLKSEL_LFA_DISABLED;\r
+ break;\r
+\r
+ case cmuSelect_LFXO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+ tmp = _CMU_LFACLKSEL_LFA_LFXO;\r
+ break;\r
+\r
+ case cmuSelect_LFRCO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+ tmp = _CMU_LFACLKSEL_LFA_LFRCO;\r
+ break;\r
+\r
+ case cmuSelect_HFCLKLE:\r
+ /* Ensure HFCORE to LE clocking is enabled */\r
+ BUS_RegBitWrite(&CMU->HFBUSCLKEN0, _CMU_HFBUSCLKEN0_LE_SHIFT, 1);\r
+ tmp = _CMU_LFBCLKSEL_LFB_HFCLKLE;\r
+\r
+ /* If core frequency is > 32MHz enable WSHFLE */\r
+ freq = SystemCoreClockGet();\r
+ if (freq > 32000000U)\r
+ {\r
+ /* Enable CMU HFLE */\r
+ BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_WSHFLE_SHIFT, 1);\r
+\r
+ /* Enable DIV4 factor for peripheral clock */\r
+ BUS_RegBitWrite(&CMU->HFPRESC, _CMU_HFPRESC_HFCLKLEPRESC_SHIFT, 1);\r
+ }\r
+ break;\r
+\r
+ case cmuSelect_ULFRCO:\r
+ /* ULFRCO is always on, there is no need to enable it. */\r
+ tmp = _CMU_LFACLKSEL_LFA_ULFRCO;\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return;\r
}\r
-#endif\r
+ *selReg = tmp;\r
break;\r
\r
-#if !defined(_EFM32_GECKO_FAMILY)\r
- case cmuSelect_ULFRCO:\r
- /* ULFRCO is always enabled */\r
- tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
- lfExtended = 1;\r
- break;\r
-#endif\r
-\r
- default:\r
- /* Illegal clock source for LFA/LFB selected */\r
- EFM_ASSERT(0);\r
- return;\r
- }\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+ case CMU_LFACLKSEL_REG:\r
+ case CMU_LFBCLKSEL_REG:\r
+ switch (ref)\r
+ {\r
+ case cmuSelect_Disabled:\r
+ tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+ break;\r
+\r
+ case cmuSelect_LFXO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+ tmp = _CMU_LFCLKSEL_LFA_LFXO;\r
+ break;\r
+\r
+ case cmuSelect_LFRCO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+ tmp = _CMU_LFCLKSEL_LFA_LFRCO;\r
+ break;\r
+\r
+ case cmuSelect_CORELEDIV2:\r
+ /* Ensure HFCORE to LE clocking is enabled */\r
+ BUS_RegBitWrite(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);\r
+ tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;\r
+#if defined( CMU_CTRL_HFLE )\r
+ /* If core frequency is higher than CMU_MAX_FREQ_HFLE on\r
+ Giant/Leopard/Wonder, enable HFLE and DIV4. */\r
+ freq = SystemCoreClockGet();\r
+ if(freq > CMU_MAX_FREQ_HFLE())\r
+ {\r
+ /* Enable CMU HFLE */\r
+ BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
+\r
+ /* Enable DIV4 factor for peripheral clock */\r
+ BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+ _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+ }\r
+#endif\r
+ break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
+ case cmuSelect_ULFRCO:\r
+ /* ULFRCO is always enabled */\r
+ tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+ lfExtended = 1;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ /* Illegal clock source for LFA/LFB selected */\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
\r
- /* Apply select */\r
- if (selReg == CMU_LFACLKSEL_REG)\r
- {\r
-#if !defined( _EFM32_GECKO_FAMILY )\r
- CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK) ) |\r
- (tmp << _CMU_LFCLKSEL_LFA_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);\r
+ /* Apply select */\r
+ if (selRegId == CMU_LFACLKSEL_REG)\r
+ {\r
+#if defined( _CMU_LFCLKSEL_LFAE_MASK )\r
+ CMU->LFCLKSEL = (CMU->LFCLKSEL\r
+ & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK))\r
+ | (tmp << _CMU_LFCLKSEL_LFA_SHIFT)\r
+ | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);\r
#else\r
- CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK) |\r
- (tmp << _CMU_LFCLKSEL_LFA_SHIFT);\r
+ CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK)\r
+ | (tmp << _CMU_LFCLKSEL_LFA_SHIFT);\r
#endif\r
- }\r
- else\r
- {\r
-#if !defined( _EFM32_GECKO_FAMILY )\r
- CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK) ) |\r
- (tmp << _CMU_LFCLKSEL_LFB_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);\r
+ }\r
+ else\r
+ {\r
+#if defined( _CMU_LFCLKSEL_LFBE_MASK )\r
+ CMU->LFCLKSEL = (CMU->LFCLKSEL\r
+ & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK))\r
+ | (tmp << _CMU_LFCLKSEL_LFB_SHIFT)\r
+ | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);\r
#else\r
- CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK) |\r
- (tmp << _CMU_LFCLKSEL_LFB_SHIFT);\r
+ CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK)\r
+ | (tmp << _CMU_LFCLKSEL_LFB_SHIFT);\r
#endif\r
- }\r
- break;\r
-\r
-#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
- case CMU_LFCCLKSEL_REG:\r
- switch(ref)\r
- {\r
- case cmuSelect_Disabled:\r
- tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+ }\r
break;\r
\r
- case cmuSelect_LFXO:\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
- tmp = _CMU_LFCLKSEL_LFC_LFXO;\r
- break;\r
+#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
+ case CMU_LFCCLKSEL_REG:\r
+ switch(ref)\r
+ {\r
+ case cmuSelect_Disabled:\r
+ tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+ break;\r
+\r
+ case cmuSelect_LFXO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+ tmp = _CMU_LFCLKSEL_LFC_LFXO;\r
+ break;\r
+\r
+ case cmuSelect_LFRCO:\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+ tmp = _CMU_LFCLKSEL_LFC_LFRCO;\r
+ break;\r
+\r
+ default:\r
+ /* Illegal clock source for LFC selected */\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
\r
- case cmuSelect_LFRCO:\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
- tmp = _CMU_LFCLKSEL_LFC_LFRCO;\r
+ /* Apply select */\r
+ CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK)\r
+ | (tmp << _CMU_LFCLKSEL_LFC_SHIFT);\r
break;\r
+#endif\r
+#endif\r
\r
- default:\r
- /* Illegal clock source for LFC selected */\r
- EFM_ASSERT(0);\r
- return;\r
- }\r
+#if defined( CMU_DBGCLKSEL_DBG ) || defined( CMU_CTRL_DBGCLK )\r
+ case CMU_DBGCLKSEL_REG:\r
+ switch(ref)\r
+ {\r
+#if defined( CMU_DBGCLKSEL_DBG )\r
+ case cmuSelect_AUXHFRCO:\r
+ /* Select AUXHFRCO as debug clock */\r
+ CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_AUXHFRCO;\r
+ break;\r
\r
- /* Apply select */\r
- CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK) |\r
- (tmp << _CMU_LFCLKSEL_LFC_SHIFT);\r
- break;\r
+ case cmuSelect_HFCLK:\r
+ /* Select divided HFCLK as debug clock */\r
+ CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_HFCLK;\r
+ break;\r
#endif\r
\r
#if defined( CMU_CTRL_DBGCLK )\r
- case CMU_DBGCLKSEL_REG:\r
- switch(ref)\r
- {\r
- case cmuSelect_AUXHFRCO:\r
- /* Select AUXHFRCO as debug clock */\r
- CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_AUXHFRCO;\r
- break;\r
-\r
- case cmuSelect_HFCLK:\r
- /* Select divided HFCLK as debug clock */\r
- CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_HFCLK;\r
+ case cmuSelect_AUXHFRCO:\r
+ /* Select AUXHFRCO as debug clock */\r
+ CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))\r
+ | CMU_CTRL_DBGCLK_AUXHFRCO;\r
+ break;\r
+\r
+ case cmuSelect_HFCLK:\r
+ /* Select divided HFCLK as debug clock */\r
+ CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))\r
+ | CMU_CTRL_DBGCLK_HFCLK;\r
+ break;\r
+#endif\r
+\r
+ default:\r
+ /* Illegal clock source for debug selected */\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
break;\r
-\r
- default:\r
- /* Illegal clock source for debug selected */\r
- EFM_ASSERT(0);\r
- return;\r
- }\r
- break;\r
#endif\r
\r
#if defined(USB_PRESENT)\r
- case CMU_USBCCLKSEL_REG:\r
- switch(ref)\r
- {\r
- case cmuSelect_LFXO:\r
- /* Select LFXO as clock source for USB, can only be used in sleep mode */\r
-\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
-\r
- /* Switch oscillator */\r
- CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;\r
-\r
- /* Wait until clock is activated */\r
- while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0);\r
- break;\r
-\r
- case cmuSelect_LFRCO:\r
- /* Select LFRCO as clock source for USB, can only be used in sleep mode */\r
-\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
-\r
- /* Switch oscillator */\r
- CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;\r
-\r
- /* Wait until clock is activated */\r
- while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0);\r
- break;\r
+ case CMU_USBCCLKSEL_REG:\r
+ switch(ref)\r
+ {\r
+ case cmuSelect_LFXO:\r
+ /* Select LFXO as clock source for USB, can only be used in sleep mode */\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+\r
+ /* Switch oscillator */\r
+ CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;\r
+\r
+ /* Wait until clock is activated */\r
+ while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0)\r
+ {\r
+ }\r
+ break;\r
+\r
+ case cmuSelect_LFRCO:\r
+ /* Select LFRCO as clock source for USB, can only be used in sleep mode */\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+\r
+ /* Switch oscillator */\r
+ CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;\r
+\r
+ /* Wait until clock is activated */\r
+ while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0)\r
+ {\r
+ }\r
+ break;\r
\r
#if defined( CMU_STATUS_USBCHFCLKSEL )\r
- case cmuSelect_HFCLK:\r
- /* Select undivided HFCLK as clock source for USB */\r
-\r
- /* Oscillator must already be enabled to avoid a core lockup */\r
- CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;\r
- /* Wait until clock is activated */\r
- while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0);\r
- break;\r
+ case cmuSelect_HFCLK:\r
+ /* Select undivided HFCLK as clock source for USB */\r
+ /* Oscillator must already be enabled to avoid a core lockup */\r
+ CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;\r
+ /* Wait until clock is activated */\r
+ while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0)\r
+ {\r
+ }\r
+ break;\r
#endif\r
\r
#if defined( CMU_CMD_USBCCLKSEL_USHFRCO )\r
- case cmuSelect_USHFRCO:\r
- /* Select USHFRCO as clock source for USB */\r
+ case cmuSelect_USHFRCO:\r
+ /* Select USHFRCO as clock source for USB */\r
+ /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+ CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);\r
\r
- /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
- CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);\r
+ /* Switch oscillator */\r
+ CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;\r
\r
- /* Switch oscillator */\r
- CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;\r
+ /* Wait until clock is activated */\r
+ while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0)\r
+ {\r
+ }\r
+ break;\r
+#endif\r
\r
- /* Wait until clock is activated */\r
- while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0);\r
+ default:\r
+ /* Illegal clock source for USB */\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
break;\r
#endif\r
\r
default:\r
- /* Illegal clock source for USB */\r
EFM_ASSERT(0);\r
- return;\r
- }\r
- /* Wait until clock has been activated */\r
- break;\r
-#endif\r
-\r
- default:\r
- EFM_ASSERT(0);\r
- break;\r
+ break;\r
}\r
}\r
\r
/* - then modifies the same register again */\r
/* since modifying a register while it is in sync progress should be */\r
/* avoided. */\r
- while (CMU->SYNCBUSY)\r
- ;\r
-\r
- CMU->FREEZE = CMU_FREEZE_REGFREEZE;\r
- }\r
- else\r
- {\r
- CMU->FREEZE = 0;\r
- }\r
-}\r
-\r
-\r
-#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
-/***************************************************************************//**\r
- * @brief\r
- * Get AUXHFRCO band in use.\r
- *\r
- * @return\r
- * AUXHFRCO band in use.\r
- ******************************************************************************/\r
-CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)\r
-{\r
- return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK) >>\r
- _CMU_AUXHFRCOCTRL_BAND_SHIFT);\r
-}\r
-\r
-/***************************************************************************//**\r
- * @brief\r
- * Set AUIXHFRCO band and the tuning value based on the value in the\r
- * calibration table made during production.\r
- *\r
- * @param[in] band\r
- * AUXHFRCO band to activate.\r
- ******************************************************************************/\r
-void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)\r
-{\r
- uint32_t tuning;\r
-\r
- /* Read tuning value from calibration table */\r
- switch (band)\r
- {\r
- case cmuAUXHFRCOBand_1MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;\r
- break;\r
-\r
- case cmuAUXHFRCOBand_7MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;\r
- break;\r
-\r
- case cmuAUXHFRCOBand_11MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;\r
- break;\r
-\r
- case cmuAUXHFRCOBand_14MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;\r
- break;\r
-\r
- case cmuAUXHFRCOBand_21MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;\r
- break;\r
-\r
-#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
- case cmuAUXHFRCOBand_28MHz:\r
- tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK) >>\r
- _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;\r
- break;\r
-#endif\r
-\r
- default:\r
- EFM_ASSERT(0);\r
- return;\r
- }\r
-\r
- /* Set band/tuning */\r
- CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &\r
- ~(_CMU_AUXHFRCOCTRL_BAND_MASK | _CMU_AUXHFRCOCTRL_TUNING_MASK)) |\r
- (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT) |\r
- (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
-\r
-}\r
-#endif\r
-\r
-\r
-#if defined( _CMU_USHFRCOCONF_BAND_MASK )\r
-/***************************************************************************//**\r
- * @brief\r
- * Get USHFRCO band in use.\r
- *\r
- * @return\r
- * USHFRCO band in use.\r
- ******************************************************************************/\r
-CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)\r
-{\r
- return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF & _CMU_USHFRCOCONF_BAND_MASK) >>\r
- _CMU_USHFRCOCONF_BAND_SHIFT);\r
-}\r
-\r
-void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)\r
-{\r
- uint32_t tuning;\r
- uint32_t fineTuning;\r
- CMU_Select_TypeDef osc;\r
-\r
- /* Cannot switch band if USHFRCO is already selected as HF clock. */\r
- osc = CMU_ClockSelectGet(cmuClock_HF);\r
- EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));\r
-\r
- /* Read tuning value from calibration table */\r
- switch (band)\r
- {\r
- case cmuUSHFRCOBand_24MHz:\r
- tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK) >>\r
- _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;\r
- fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK) >>\r
- _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;\r
- break;\r
-\r
- case cmuUSHFRCOBand_48MHz:\r
- tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK) >>\r
- _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;\r
- fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK) >>\r
- _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;\r
- /* Enable the clock divider before switching the band from 24 to 48MHz */\r
- BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);\r
- break;\r
+ while (CMU->SYNCBUSY)\r
+ {\r
+ }\r
\r
- default:\r
- EFM_ASSERT(0);\r
- return;\r
+ CMU->FREEZE = CMU_FREEZE_REGFREEZE;\r
}\r
-\r
- /* Set band and tuning */\r
- CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK) |\r
- (band << _CMU_USHFRCOCONF_BAND_SHIFT);\r
- CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK) |\r
- (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);\r
- CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK) |\r
- (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);\r
-\r
- /* Disable the clock divider after switching the band from 48 to 24MHz */\r
- if (band == cmuUSHFRCOBand_24MHz)\r
+ else\r
{\r
- BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);\r
+ CMU->FREEZE = 0;\r
}\r
}\r
-#endif\r
\r
\r
+#if defined( _CMU_HFRCOCTRL_BAND_MASK )\r
/***************************************************************************//**\r
* @brief\r
* Get HFRCO band in use.\r
******************************************************************************/\r
CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)\r
{\r
- return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) >>\r
- _CMU_HFRCOCTRL_BAND_SHIFT);\r
+ return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)\r
+ >> _CMU_HFRCOCTRL_BAND_SHIFT);\r
}\r
+#endif /* _CMU_HFRCOCTRL_BAND_MASK */\r
\r
\r
+#if defined( _CMU_HFRCOCTRL_BAND_MASK )\r
/***************************************************************************//**\r
* @brief\r
* Set HFRCO band and the tuning value based on the value in the calibration\r
/* Read tuning value from calibration table */\r
switch (band)\r
{\r
- case cmuHFRCOBand_1MHz:\r
- tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK) >>\r
- _DEVINFO_HFRCOCAL0_BAND1_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_1MHz:\r
+ tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK)\r
+ >> _DEVINFO_HFRCOCAL0_BAND1_SHIFT;\r
+ break;\r
\r
- case cmuHFRCOBand_7MHz:\r
- tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK) >>\r
- _DEVINFO_HFRCOCAL0_BAND7_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_7MHz:\r
+ tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK)\r
+ >> _DEVINFO_HFRCOCAL0_BAND7_SHIFT;\r
+ break;\r
\r
- case cmuHFRCOBand_11MHz:\r
- tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK) >>\r
- _DEVINFO_HFRCOCAL0_BAND11_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_11MHz:\r
+ tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK)\r
+ >> _DEVINFO_HFRCOCAL0_BAND11_SHIFT;\r
+ break;\r
\r
- case cmuHFRCOBand_14MHz:\r
- tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK) >>\r
- _DEVINFO_HFRCOCAL0_BAND14_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_14MHz:\r
+ tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK)\r
+ >> _DEVINFO_HFRCOCAL0_BAND14_SHIFT;\r
+ break;\r
\r
- case cmuHFRCOBand_21MHz:\r
- tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK) >>\r
- _DEVINFO_HFRCOCAL1_BAND21_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_21MHz:\r
+ tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK)\r
+ >> _DEVINFO_HFRCOCAL1_BAND21_SHIFT;\r
+ break;\r
\r
#if defined( _CMU_HFRCOCTRL_BAND_28MHZ )\r
- case cmuHFRCOBand_28MHz:\r
- tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK) >>\r
- _DEVINFO_HFRCOCAL1_BAND28_SHIFT;\r
- break;\r
+ case cmuHFRCOBand_28MHz:\r
+ tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK)\r
+ >> _DEVINFO_HFRCOCAL1_BAND28_SHIFT;\r
+ break;\r
#endif\r
\r
- default:\r
- EFM_ASSERT(0);\r
- return;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return;\r
}\r
\r
/* If HFRCO is used for core clock, we have to consider flash access WS. */\r
if (osc == cmuSelect_HFRCO)\r
{\r
/* Configure worst case wait states for flash access before setting divider */\r
- CMU_FlashWaitStateMax();\r
+ flashWaitStateMax();\r
}\r
\r
/* Set band/tuning */\r
CMU->HFRCOCTRL = (CMU->HFRCOCTRL &\r
- ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK)) |\r
- (band << _CMU_HFRCOCTRL_BAND_SHIFT) |\r
- (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+ ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK))\r
+ | (band << _CMU_HFRCOCTRL_BAND_SHIFT)\r
+ | (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
\r
/* If HFRCO is used for core clock, optimize flash WS */\r
if (osc == cmuSelect_HFRCO)\r
freq = SystemCoreClockGet();\r
\r
/* Optimize flash access wait state setting for current core clk */\r
- CMU_FlashWaitStateControl(freq);\r
+ flashWaitStateControl(freq);\r
+ }\r
+}\r
+#endif /* _CMU_HFRCOCTRL_BAND_MASK */\r
+\r
+\r
+#if defined( _CMU_HFRCOCTRL_FREQRANGE_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ * Get a pointer to the HFRCO frequency calibration word in DEVINFO\r
+ *\r
+ * @param[in] freq\r
+ * Frequency in Hz\r
+ *\r
+ * @return\r
+ * HFRCO calibration word for a given frequency\r
+ *****************************************************************************/\r
+static uint32_t CMU_HFRCODevinfoGet(CMU_HFRCOFreq_TypeDef freq)\r
+{\r
+ switch (freq)\r
+ {\r
+ /* 1, 2 and 4MHz share the same calibration word */\r
+ case cmuHFRCOFreq_1M0Hz:\r
+ case cmuHFRCOFreq_2M0Hz:\r
+ case cmuHFRCOFreq_4M0Hz:\r
+ return DEVINFO->HFRCOCAL0;\r
+\r
+ case cmuHFRCOFreq_7M0Hz:\r
+ return DEVINFO->HFRCOCAL3;\r
+\r
+ case cmuHFRCOFreq_13M0Hz:\r
+ return DEVINFO->HFRCOCAL6;\r
+\r
+ case cmuHFRCOFreq_16M0Hz:\r
+ return DEVINFO->HFRCOCAL7;\r
+\r
+ case cmuHFRCOFreq_19M0Hz:\r
+ return DEVINFO->HFRCOCAL8;\r
+\r
+ case cmuHFRCOFreq_26M0Hz:\r
+ return DEVINFO->HFRCOCAL10;\r
+\r
+ case cmuHFRCOFreq_32M0Hz:\r
+ return DEVINFO->HFRCOCAL11;\r
+\r
+ case cmuHFRCOFreq_38M0Hz:\r
+ return DEVINFO->HFRCOCAL12;\r
+\r
+ default: /* cmuHFRCOFreq_UserDefined */\r
+ return 0;\r
}\r
}\r
\r
\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get HFRCO frequency enumeration in use\r
+ *\r
+ * @return\r
+ * HFRCO frequency enumeration in use\r
+ ******************************************************************************/\r
+CMU_HFRCOFreq_TypeDef CMU_HFRCOFreqGet(void)\r
+{\r
+ return (CMU_HFRCOFreq_TypeDef)SystemHfrcoFreq;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Set HFRCO calibration for the selected target frequency\r
+ *\r
+ * @param[in] freq\r
+ * HFRCO frequency band to set\r
+ ******************************************************************************/\r
+void CMU_HFRCOFreqSet(CMU_HFRCOFreq_TypeDef freq)\r
+{\r
+ uint32_t freqCal;\r
+\r
+ /* Get DEVINFO index, set CMSIS frequency SystemHfrcoFreq */\r
+ freqCal = CMU_HFRCODevinfoGet(freq);\r
+ EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));\r
+ SystemHfrcoFreq = (uint32_t)freq;\r
+\r
+ /* Set max wait-states while changing core clock */\r
+ if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)\r
+ {\r
+ flashWaitStateMax();\r
+ }\r
+\r
+ /* Wait for any previous sync to complete, and then set calibration data\r
+ for the selected frequency. */\r
+ while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT));\r
+\r
+ /* Check for valid calibration data */\r
+ EFM_ASSERT(freqCal != UINT_MAX);\r
+\r
+ /* Set divider in HFRCOCTRL for 1, 2 and 4MHz */\r
+ switch(freq)\r
+ {\r
+ case cmuHFRCOFreq_1M0Hz:\r
+ freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_HFRCOCTRL_CLKDIV_DIV4;\r
+ break;\r
+\r
+ case cmuHFRCOFreq_2M0Hz:\r
+ freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_HFRCOCTRL_CLKDIV_DIV2;\r
+ break;\r
+\r
+ case cmuHFRCOFreq_4M0Hz:\r
+ freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+ | CMU_HFRCOCTRL_CLKDIV_DIV1;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ CMU->HFRCOCTRL = freqCal;\r
+\r
+ /* Optimize flash access wait-state configuration for this frequency, */\r
+ /* if HFRCO is reference for core clock. */\r
+ if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)\r
+ {\r
+ flashWaitStateControl((uint32_t)freq);\r
+ }\r
+}\r
+#endif /* _CMU_HFRCOCTRL_FREQRANGE_MASK */\r
+\r
+#if defined( _CMU_HFRCOCTRL_SUDELAY_MASK )\r
/***************************************************************************//**\r
* @brief\r
* Get the HFRCO startup delay.\r
******************************************************************************/\r
uint32_t CMU_HFRCOStartupDelayGet(void)\r
{\r
- return((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK) >>\r
- _CMU_HFRCOCTRL_SUDELAY_SHIFT);\r
+ return (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK)\r
+ >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;\r
}\r
\r
\r
{\r
EFM_ASSERT(delay <= 31);\r
\r
- delay &= (_CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT);\r
- CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK)) |\r
- (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);\r
+ delay &= _CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;\r
+ CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK))\r
+ | (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);\r
+}\r
+#endif\r
+\r
+\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Enable or disable HFXO autostart\r
+ *\r
+ * @param[in] enRACStartSel\r
+ * If true, HFXO is automatically started and selected upon RAC wakeup.\r
+ * If false, HFXO is not started or selected automatically upon RAC wakeup.\r
+ *\r
+ * @param[in] enEM0EM1Start\r
+ * If true, HFXO is automatically started upon entering EM0/EM1 entry from\r
+ * EM2/EM3. HFXO selection has to be handled by the user.\r
+ * If false, HFXO is not started automatically when entering EM0/EM1.\r
+ *\r
+ * @param[in] enEM0EM1StartSel\r
+ * If true, HFXO is automatically started and immediately selected upon\r
+ * entering EM0/EM1 entry from EM2/EM3. Note that this option stalls the use of\r
+ * HFSRCCLK until HFXO becomes ready.\r
+ * If false, HFXO is not started or selected automatically when entering\r
+ * EM0/EM1.\r
+ ******************************************************************************/\r
+void CMU_HFXOAutostartEnable(bool enRACStartSel,\r
+ bool enEM0EM1Start,\r
+ bool enEM0EM1StartSel)\r
+{\r
+ uint32_t hfxoCtrl;\r
+ hfxoCtrl = CMU->HFXOCTRL & ~(_CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK\r
+ | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK\r
+ | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK);\r
+\r
+ hfxoCtrl |= (enRACStartSel ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)\r
+ | (enEM0EM1Start ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)\r
+ | (enEM0EM1StartSel ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0);\r
+\r
+ CMU->HFXOCTRL = hfxoCtrl;\r
+}\r
+#endif /* _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK */\r
+\r
+\r
+#if defined( _CMU_HFXOCTRL_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ * Set HFXO control registers\r
+ *\r
+ * @note\r
+ * HFXO configuration should be obtained from a configuration tool,\r
+ * app note or xtal datasheet. This function disables the HFXO to ensure\r
+ * a valid state before update.\r
+ *\r
+ * @param[in] hfxoInit\r
+ * HFXO setup parameters\r
+ *****************************************************************************/\r
+void CMU_HFXOInit(CMU_HFXOInit_TypeDef *hfxoInit)\r
+{\r
+ uint32_t ishReg;\r
+ uint32_t ishMax;\r
+\r
+ /* Do not disable HFXO if it is currently selected as HF/Core clock */\r
+ EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_HFXO);\r
+\r
+ /* HFXO must be disabled before reconfiguration */\r
+ CMU_OscillatorEnable(cmuOsc_HFXO, false, false);\r
+\r
+ /* Apply control settings */\r
+ BUS_RegMaskedWrite(&CMU->HFXOCTRL,\r
+ _CMU_HFXOCTRL_LOWPOWER_MASK\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+ | _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK\r
+#endif\r
+ | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK\r
+ | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK,\r
+ (hfxoInit->lowPowerMode\r
+ ? CMU_HFXOCTRL_LOWPOWER : 0)\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+ | (hfxoInit->autoStartSelOnRacWakeup\r
+ ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)\r
+#endif\r
+ | (hfxoInit->autoStartEm01\r
+ ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)\r
+ | (hfxoInit->autoSelEm01\r
+ ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0));\r
+\r
+ /* Set XTAL tuning parameters */\r
+\r
+ /* Set peak detection threshold in CMU_HFXOCTRL1_PEAKDETTHR[2:0] (hidden). */\r
+ BUS_RegMaskedWrite((volatile uint32_t *)0x400E4028, 0x7, hfxoInit->thresholdPeakDetect);\r
+\r
+ /* Set tuning for startup and steady state */\r
+ BUS_RegMaskedWrite(&CMU->HFXOSTARTUPCTRL,\r
+ _CMU_HFXOSTARTUPCTRL_CTUNE_MASK\r
+ | _CMU_HFXOSTARTUPCTRL_REGISHWARM_MASK\r
+ | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK\r
+ | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_MASK,\r
+ (hfxoInit->ctuneStartup\r
+ << _CMU_HFXOSTARTUPCTRL_CTUNE_SHIFT)\r
+ | (hfxoInit->regIshStartup\r
+ << _CMU_HFXOSTARTUPCTRL_REGISHWARM_SHIFT)\r
+ | (hfxoInit->xoCoreBiasTrimStartup\r
+ << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT)\r
+ | 0x4 /* Recommended tuning */\r
+ << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_SHIFT);\r
+\r
+ /* Adjust CMU_HFXOSTEADYSTATECTRL_REGISHUPPER according to regIshSteadyState.\r
+ Saturate at max value. Please see the reference manual page 433 and Section\r
+ 12.5.10 CMU_HFXOSTEADYSTATECTRL for more details. */\r
+ ishReg = hfxoInit->regIshSteadyState + 3;\r
+ ishMax = _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK\r
+ >> _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;\r
+ ishReg = ishReg > ishMax ? ishMax : ishReg;\r
+ ishReg <<= _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;\r
+\r
+ BUS_RegMaskedWrite(&CMU->HFXOSTEADYSTATECTRL,\r
+ _CMU_HFXOSTEADYSTATECTRL_CTUNE_MASK\r
+ | _CMU_HFXOSTEADYSTATECTRL_REGISH_MASK\r
+ | _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_MASK\r
+ | _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK,\r
+ (hfxoInit->ctuneSteadyState\r
+ << _CMU_HFXOSTEADYSTATECTRL_CTUNE_SHIFT)\r
+ | (hfxoInit->regIshSteadyState\r
+ << _CMU_HFXOSTEADYSTATECTRL_REGISH_SHIFT)\r
+ | (hfxoInit->xoCoreBiasTrimSteadyState\r
+ << _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_SHIFT)\r
+ | ishReg);\r
+\r
+ /* Set timeouts */\r
+ BUS_RegMaskedWrite(&CMU->HFXOTIMEOUTCTRL,\r
+ _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_MASK\r
+ | _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_MASK\r
+ | _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_MASK\r
+ | _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_MASK\r
+ | _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_MASK,\r
+ (hfxoInit->timeoutShuntOptimization\r
+ << _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_SHIFT)\r
+ | (hfxoInit->timeoutPeakDetect\r
+ << _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_SHIFT)\r
+ | (hfxoInit->timeoutWarmSteady\r
+ << _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_SHIFT)\r
+ | (hfxoInit->timeoutSteady\r
+ << _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_SHIFT)\r
+ | (hfxoInit->timeoutStartup\r
+ << _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_SHIFT));\r
}\r
+#endif\r
\r
\r
/***************************************************************************//**\r
******************************************************************************/\r
uint32_t CMU_LCDClkFDIVGet(void)\r
{\r
-#if defined(LCD_PRESENT)\r
- return((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT);\r
+#if defined( LCD_PRESENT )\r
+ return (CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT;\r
#else\r
return 0;\r
#endif /* defined(LCD_PRESENT) */\r
******************************************************************************/\r
void CMU_LCDClkFDIVSet(uint32_t div)\r
{\r
-#if defined(LCD_PRESENT)\r
+#if defined( LCD_PRESENT )\r
EFM_ASSERT(div <= cmuClkDiv_128);\r
\r
/* Do not allow modification if LCD clock enabled */\r
}\r
\r
\r
+#if defined( _CMU_LFXOCTRL_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ * Set LFXO control registers\r
+ *\r
+ * @note\r
+ * LFXO configuration should be obtained from a configuration tool,\r
+ * app note or xtal datasheet. This function disables the LFXO to ensure\r
+ * a valid state before update.\r
+ *\r
+ * @param[in] lfxoInit\r
+ * LFXO setup parameters\r
+ *****************************************************************************/\r
+void CMU_LFXOInit(CMU_LFXOInit_TypeDef *lfxoInit)\r
+{\r
+ /* Do not disable LFXO if it is currently selected as HF/Core clock */\r
+ EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_LFXO);\r
+\r
+ /* LFXO must be disabled before reconfiguration */\r
+ CMU_OscillatorEnable(cmuOsc_LFXO, false, false);\r
+\r
+ BUS_RegMaskedWrite(&CMU->LFXOCTRL,\r
+ _CMU_LFXOCTRL_TUNING_MASK\r
+ | _CMU_LFXOCTRL_GAIN_MASK\r
+ | _CMU_LFXOCTRL_TIMEOUT_MASK,\r
+ (lfxoInit->ctune << _CMU_LFXOCTRL_TUNING_SHIFT)\r
+ | (lfxoInit->gain << _CMU_LFXOCTRL_GAIN_SHIFT)\r
+ | (lfxoInit->timeout << _CMU_LFXOCTRL_TIMEOUT_SHIFT));\r
+}\r
+#endif\r
+\r
+\r
/***************************************************************************//**\r
* @brief\r
* Enable/disable oscillator.\r
******************************************************************************/\r
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)\r
{\r
- uint32_t status;\r
+ uint32_t rdyBitPos;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ uint32_t ensBitPos;\r
+#endif\r
uint32_t enBit;\r
uint32_t disBit;\r
\r
switch (osc)\r
{\r
- case cmuOsc_HFRCO:\r
- enBit = CMU_OSCENCMD_HFRCOEN;\r
- disBit = CMU_OSCENCMD_HFRCODIS;\r
- status = CMU_STATUS_HFRCORDY;\r
- break;\r
+ case cmuOsc_HFRCO:\r
+ enBit = CMU_OSCENCMD_HFRCOEN;\r
+ disBit = CMU_OSCENCMD_HFRCODIS;\r
+ rdyBitPos = _CMU_STATUS_HFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_HFRCOENS_SHIFT;\r
+#endif\r
+ break;\r
\r
- case cmuOsc_HFXO:\r
- enBit = CMU_OSCENCMD_HFXOEN;\r
- disBit = CMU_OSCENCMD_HFXODIS;\r
- status = CMU_STATUS_HFXORDY;\r
- break;\r
+ case cmuOsc_HFXO:\r
+ enBit = CMU_OSCENCMD_HFXOEN;\r
+ disBit = CMU_OSCENCMD_HFXODIS;\r
+ rdyBitPos = _CMU_STATUS_HFXORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_HFXOENS_SHIFT;\r
+#endif\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- enBit = CMU_OSCENCMD_AUXHFRCOEN;\r
- disBit = CMU_OSCENCMD_AUXHFRCODIS;\r
- status = CMU_STATUS_AUXHFRCORDY;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ enBit = CMU_OSCENCMD_AUXHFRCOEN;\r
+ disBit = CMU_OSCENCMD_AUXHFRCODIS;\r
+ rdyBitPos = _CMU_STATUS_AUXHFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_AUXHFRCOENS_SHIFT;\r
+#endif\r
+ break;\r
\r
- case cmuOsc_LFRCO:\r
- enBit = CMU_OSCENCMD_LFRCOEN;\r
- disBit = CMU_OSCENCMD_LFRCODIS;\r
- status = CMU_STATUS_LFRCORDY;\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ enBit = CMU_OSCENCMD_LFRCOEN;\r
+ disBit = CMU_OSCENCMD_LFRCODIS;\r
+ rdyBitPos = _CMU_STATUS_LFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_LFRCOENS_SHIFT;\r
+#endif\r
+ break;\r
\r
- case cmuOsc_LFXO:\r
- enBit = CMU_OSCENCMD_LFXOEN;\r
- disBit = CMU_OSCENCMD_LFXODIS;\r
- status = CMU_STATUS_LFXORDY;\r
- break;\r
+ case cmuOsc_LFXO:\r
+ enBit = CMU_OSCENCMD_LFXOEN;\r
+ disBit = CMU_OSCENCMD_LFXODIS;\r
+ rdyBitPos = _CMU_STATUS_LFXORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_LFXOENS_SHIFT;\r
+#endif\r
+ break;\r
\r
#if defined( _CMU_STATUS_USHFRCOENS_MASK )\r
- case cmuOsc_USHFRCO:\r
- enBit = CMU_OSCENCMD_USHFRCOEN;\r
- disBit = CMU_OSCENCMD_USHFRCODIS;\r
- status = CMU_STATUS_USHFRCORDY;\r
- break;\r
+ case cmuOsc_USHFRCO:\r
+ enBit = CMU_OSCENCMD_USHFRCOEN;\r
+ disBit = CMU_OSCENCMD_USHFRCODIS;\r
+ rdyBitPos = _CMU_STATUS_USHFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ ensBitPos = _CMU_STATUS_USHFRCOENS_SHIFT;\r
+#endif\r
+ break;\r
#endif\r
\r
-#if defined( _CMU_LFCLKSEL_LFAE_ULFRCO )\r
- case cmuOsc_ULFRCO:\r
- /* ULFRCO is always enabled, and cannot be turned off */\r
- return;\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
+ case cmuOsc_ULFRCO:\r
+ /* ULFRCO is always enabled, and cannot be turned off */\r
+ return;\r
#endif\r
\r
- default:\r
- /* Undefined clock source */\r
- EFM_ASSERT(0);\r
- return;\r
+ default:\r
+ /* Undefined clock source */\r
+ EFM_ASSERT(0);\r
+ return;\r
}\r
\r
if (enable)\r
{\r
CMU->OSCENCMD = enBit;\r
\r
- /* Wait for clock to stabilize if requested */\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ /* Always wait for ENS to go high */\r
+ while (!BUS_RegBitRead(&CMU->STATUS, ensBitPos))\r
+ {\r
+ }\r
+#endif\r
+\r
+ /* Wait for clock to become ready after enable */\r
if (wait)\r
{\r
- while (!(CMU->STATUS & status))\r
- ;\r
+ while (!BUS_RegBitRead(&CMU->STATUS, rdyBitPos));\r
+#if defined( _CMU_STATUS_HFXOSHUNTOPTRDY_MASK )\r
+ /* Wait for shunt current optimization to complete */\r
+ if ((osc == cmuOsc_HFXO)\r
+ && (BUS_RegMaskedRead(&CMU->HFXOCTRL,\r
+ _CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_MASK)\r
+ == CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_AUTOCMD))\r
+ {\r
+ while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOSHUNTOPTRDY_SHIFT))\r
+ {\r
+ }\r
+ /* Assert on failed peak detection. Incorrect HFXO initialization parameters\r
+ caused startup to fail. Please review parameters. */\r
+ EFM_ASSERT(BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOPEAKDETRDY_SHIFT));\r
+ }\r
+#endif\r
}\r
}\r
else\r
{\r
CMU->OSCENCMD = disBit;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ /* Always wait for ENS to go low */\r
+ while (BUS_RegBitRead(&CMU->STATUS, ensBitPos))\r
+ {\r
+ }\r
+#endif\r
}\r
\r
/* Keep EMU module informed */\r
\r
switch (osc)\r
{\r
- case cmuOsc_LFRCO:\r
- ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK) >>\r
- _CMU_LFRCOCTRL_TUNING_SHIFT;\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK)\r
+ >> _CMU_LFRCOCTRL_TUNING_SHIFT;\r
+ break;\r
\r
- case cmuOsc_HFRCO:\r
- ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK) >>\r
- _CMU_HFRCOCTRL_TUNING_SHIFT;\r
- break;\r
+ case cmuOsc_HFRCO:\r
+ ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK)\r
+ >> _CMU_HFRCOCTRL_TUNING_SHIFT;\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK) >>\r
- _CMU_AUXHFRCOCTRL_TUNING_SHIFT;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK)\r
+ >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT;\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- ret = 0;\r
- break;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ ret = 0;\r
+ break;\r
}\r
\r
- return(ret);\r
+ return ret;\r
}\r
\r
\r
{\r
switch (osc)\r
{\r
- case cmuOsc_LFRCO:\r
- EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT));\r
-\r
- val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);\r
- CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK)) |\r
- (val << _CMU_LFRCOCTRL_TUNING_SHIFT);\r
- break;\r
-\r
- case cmuOsc_HFRCO:\r
- EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT));\r
-\r
- val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);\r
- CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK)) |\r
- (val << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
- break;\r
+ case cmuOsc_LFRCO:\r
+ EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK\r
+ >> _CMU_LFRCOCTRL_TUNING_SHIFT));\r
+ val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_LFRCOBSY_SHIFT));\r
+#endif\r
+ CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK))\r
+ | (val << _CMU_LFRCOCTRL_TUNING_SHIFT);\r
+ break;\r
\r
- case cmuOsc_AUXHFRCO:\r
- EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));\r
+ case cmuOsc_HFRCO:\r
+ EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK\r
+ >> _CMU_HFRCOCTRL_TUNING_SHIFT));\r
+ val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT))\r
+ {\r
+ }\r
+#endif\r
+ CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK))\r
+ | (val << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+ break;\r
\r
- val <<= _CMU_AUXHFRCOCTRL_TUNING_SHIFT;\r
- val &= _CMU_AUXHFRCOCTRL_TUNING_MASK;\r
- CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK)) | val;\r
- break;\r
+ case cmuOsc_AUXHFRCO:\r
+ EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK\r
+ >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));\r
+ val &= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+ while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT))\r
+ {\r
+ }\r
+#endif\r
+ CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK))\r
+ | (val << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+ break;\r
\r
- default:\r
- EFM_ASSERT(0);\r
- break;\r
+ default:\r
+ EFM_ASSERT(0);\r
+ break;\r
}\r
}\r
\r
* @brief\r
* Determine if currently selected PCNTn clock used is external or LFBCLK.\r
*\r
- * @param[in] inst\r
+ * @param[in] instance\r
* PCNT instance number to get currently selected clock source for.\r
*\r
* @return\r
* @li true - selected clock is external clock.\r
* @li false - selected clock is LFBCLK.\r
*****************************************************************************/\r
-bool CMU_PCNTClockExternalGet(unsigned int inst)\r
+bool CMU_PCNTClockExternalGet(unsigned int instance)\r
{\r
- bool ret;\r
uint32_t setting;\r
\r
- switch (inst)\r
+ switch (instance)\r
{\r
-#if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)\r
- case 0:\r
- setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;\r
- break;\r
+#if defined( _CMU_PCNTCTRL_PCNT0CLKEN_MASK )\r
+ case 0:\r
+ setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;\r
+ break;\r
\r
-#if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)\r
- case 1:\r
- setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;\r
- break;\r
+#if defined( _CMU_PCNTCTRL_PCNT1CLKEN_MASK )\r
+ case 1:\r
+ setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;\r
+ break;\r
\r
-#if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)\r
- case 2:\r
- setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;\r
- break;\r
+#if defined( _CMU_PCNTCTRL_PCNT2CLKEN_MASK )\r
+ case 2:\r
+ setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;\r
+ break;\r
#endif\r
#endif\r
#endif\r
\r
- default:\r
- setting = 0;\r
- break;\r
- }\r
-\r
- if (setting)\r
- {\r
- ret = true;\r
- }\r
- else\r
- {\r
- ret = false;\r
+ default:\r
+ setting = 0;\r
+ break;\r
}\r
- return ret;\r
+ return (setting ? true : false);\r
}\r
\r
\r
* @brief\r
* Select PCNTn clock.\r
*\r
- * @param[in] inst\r
+ * @param[in] instance\r
* PCNT instance number to set selected clock source for.\r
*\r
* @param[in] external\r
* Set to true to select external clock, false to select LFBCLK.\r
*****************************************************************************/\r
-void CMU_PCNTClockExternalSet(unsigned int inst, bool external)\r
+void CMU_PCNTClockExternalSet(unsigned int instance, bool external)\r
{\r
-#if defined(PCNT_PRESENT)\r
+#if defined( PCNT_PRESENT )\r
uint32_t setting = 0;\r
\r
- EFM_ASSERT(inst < PCNT_COUNT);\r
+ EFM_ASSERT(instance < PCNT_COUNT);\r
\r
if (external)\r
{\r
setting = 1;\r
}\r
\r
- BITBAND_Peripheral(&(CMU->PCNTCTRL), (inst * 2) + 1, setting);\r
+ BUS_RegBitWrite(&(CMU->PCNTCTRL), (instance * 2) + 1, setting);\r
\r
#else\r
- (void)inst; /* Unused parameter */\r
+ (void)instance; /* Unused parameter */\r
(void)external; /* Unused parameter */\r
#endif\r
}\r
\r
\r
+#if defined( _CMU_USHFRCOCONF_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Get USHFRCO band in use.\r
+ *\r
+ * @return\r
+ * USHFRCO band in use.\r
+ ******************************************************************************/\r
+CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)\r
+{\r
+ return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF\r
+ & _CMU_USHFRCOCONF_BAND_MASK)\r
+ >> _CMU_USHFRCOCONF_BAND_SHIFT);\r
+}\r
+#endif\r
+\r
+#if defined( _CMU_USHFRCOCONF_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ * Set USHFRCO band to use.\r
+ *\r
+ * @param[in] band\r
+ * USHFRCO band to activate.\r
+ ******************************************************************************/\r
+void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)\r
+{\r
+ uint32_t tuning;\r
+ uint32_t fineTuning;\r
+ CMU_Select_TypeDef osc;\r
+\r
+ /* Cannot switch band if USHFRCO is already selected as HF clock. */\r
+ osc = CMU_ClockSelectGet(cmuClock_HF);\r
+ EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));\r
+\r
+ /* Read tuning value from calibration table */\r
+ switch (band)\r
+ {\r
+ case cmuUSHFRCOBand_24MHz:\r
+ tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK)\r
+ >> _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;\r
+ fineTuning = (DEVINFO->USHFRCOCAL0\r
+ & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK)\r
+ >> _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;\r
+ break;\r
+\r
+ case cmuUSHFRCOBand_48MHz:\r
+ tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK)\r
+ >> _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;\r
+ fineTuning = (DEVINFO->USHFRCOCAL0\r
+ & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK)\r
+ >> _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;\r
+ /* Enable the clock divider before switching the band from 24 to 48MHz */\r
+ BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);\r
+ break;\r
+\r
+ default:\r
+ EFM_ASSERT(0);\r
+ return;\r
+ }\r
+\r
+ /* Set band and tuning */\r
+ CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK)\r
+ | (band << _CMU_USHFRCOCONF_BAND_SHIFT);\r
+ CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK)\r
+ | (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);\r
+ CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK)\r
+ | (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);\r
+\r
+ /* Disable the clock divider after switching the band from 48 to 24MHz */\r
+ if (band == cmuUSHFRCOBand_24MHz)\r
+ {\r
+ BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);\r
+ }\r
+}\r
+#endif\r
+\r
+\r
+\r
/** @} (end addtogroup CMU) */\r
/** @} (end addtogroup EM_Library) */\r
#endif /* __EM_CMU_H */\r