added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 0:9b334a45a8ff 1 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2 * @file em_cmu.c
bogdanm 0:9b334a45a8ff 3 * @brief Clock management unit (CMU) Peripheral API
bogdanm 0:9b334a45a8ff 4 * @version 3.20.12
bogdanm 0:9b334a45a8ff 5 *******************************************************************************
bogdanm 0:9b334a45a8ff 6 * @section License
bogdanm 0:9b334a45a8ff 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
bogdanm 0:9b334a45a8ff 8 *******************************************************************************
bogdanm 0:9b334a45a8ff 9 *
bogdanm 0:9b334a45a8ff 10 * Permission is granted to anyone to use this software for any purpose,
bogdanm 0:9b334a45a8ff 11 * including commercial applications, and to alter it and redistribute it
bogdanm 0:9b334a45a8ff 12 * freely, subject to the following restrictions:
bogdanm 0:9b334a45a8ff 13 *
bogdanm 0:9b334a45a8ff 14 * 1. The origin of this software must not be misrepresented; you must not
bogdanm 0:9b334a45a8ff 15 * claim that you wrote the original software.
bogdanm 0:9b334a45a8ff 16 * 2. Altered source versions must be plainly marked as such, and must not be
bogdanm 0:9b334a45a8ff 17 * misrepresented as being the original software.
bogdanm 0:9b334a45a8ff 18 * 3. This notice may not be removed or altered from any source distribution.
bogdanm 0:9b334a45a8ff 19 *
bogdanm 0:9b334a45a8ff 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
bogdanm 0:9b334a45a8ff 21 * obligation to support this Software. Silicon Labs is providing the
bogdanm 0:9b334a45a8ff 22 * Software "AS IS", with no express or implied warranties of any kind,
bogdanm 0:9b334a45a8ff 23 * including, but not limited to, any implied warranties of merchantability
bogdanm 0:9b334a45a8ff 24 * or fitness for any particular purpose or warranties against infringement
bogdanm 0:9b334a45a8ff 25 * of any proprietary rights of a third party.
bogdanm 0:9b334a45a8ff 26 *
bogdanm 0:9b334a45a8ff 27 * Silicon Labs will not be liable for any consequential, incidental, or
bogdanm 0:9b334a45a8ff 28 * special damages, or any other relief, or for any claim by any third party,
bogdanm 0:9b334a45a8ff 29 * arising from your use of this Software.
bogdanm 0:9b334a45a8ff 30 *
bogdanm 0:9b334a45a8ff 31 ******************************************************************************/
bogdanm 0:9b334a45a8ff 32
bogdanm 0:9b334a45a8ff 33
bogdanm 0:9b334a45a8ff 34 #include "em_cmu.h"
bogdanm 0:9b334a45a8ff 35 #if defined( CMU_PRESENT )
bogdanm 0:9b334a45a8ff 36
bogdanm 0:9b334a45a8ff 37 #include "em_assert.h"
bogdanm 0:9b334a45a8ff 38 #include "em_bitband.h"
bogdanm 0:9b334a45a8ff 39 #include "em_emu.h"
bogdanm 0:9b334a45a8ff 40
bogdanm 0:9b334a45a8ff 41 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 42 * @addtogroup EM_Library
bogdanm 0:9b334a45a8ff 43 * @{
bogdanm 0:9b334a45a8ff 44 ******************************************************************************/
bogdanm 0:9b334a45a8ff 45
bogdanm 0:9b334a45a8ff 46 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 47 * @addtogroup CMU
bogdanm 0:9b334a45a8ff 48 * @brief Clock management unit (CMU) Peripheral API
bogdanm 0:9b334a45a8ff 49 * @{
bogdanm 0:9b334a45a8ff 50 ******************************************************************************/
bogdanm 0:9b334a45a8ff 51
bogdanm 0:9b334a45a8ff 52 /*******************************************************************************
bogdanm 0:9b334a45a8ff 53 ****************************** DEFINES ************************************
bogdanm 0:9b334a45a8ff 54 ******************************************************************************/
bogdanm 0:9b334a45a8ff 55
bogdanm 0:9b334a45a8ff 56 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 57
bogdanm 0:9b334a45a8ff 58 /** Maximum allowed core frequency when using 0 wait states on flash access. */
bogdanm 0:9b334a45a8ff 59 #define CMU_MAX_FREQ_0WS 16000000
bogdanm 0:9b334a45a8ff 60 /** Maximum allowed core frequency when using 1 wait states on flash access */
bogdanm 0:9b334a45a8ff 61 #define CMU_MAX_FREQ_1WS 32000000
bogdanm 0:9b334a45a8ff 62
bogdanm 0:9b334a45a8ff 63 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 64 /** Maximum frequency for HFLE needs to be enabled on Giant, Leopard and
bogdanm 0:9b334a45a8ff 65 Wonder. */
bogdanm 0:9b334a45a8ff 66 #if defined ( _EFM32_WONDER_FAMILY ) || \
bogdanm 0:9b334a45a8ff 67 defined ( _EZR32_LEOPARD_FAMILY ) || \
bogdanm 0:9b334a45a8ff 68 defined ( _EZR32_WONDER_FAMILY )
bogdanm 0:9b334a45a8ff 69 #define CMU_MAX_FREQ_HFLE 24000000
bogdanm 0:9b334a45a8ff 70 #elif defined ( _EFM32_GIANT_FAMILY )
bogdanm 0:9b334a45a8ff 71 #define CMU_MAX_FREQ_HFLE (CMU_MaxFreqHfle())
bogdanm 0:9b334a45a8ff 72 #else
bogdanm 0:9b334a45a8ff 73 #error Invalid part/device.
bogdanm 0:9b334a45a8ff 74 #endif
bogdanm 0:9b334a45a8ff 75 #endif
bogdanm 0:9b334a45a8ff 76
bogdanm 0:9b334a45a8ff 77 /** Low frequency A group identifier */
bogdanm 0:9b334a45a8ff 78 #define CMU_LFA 0
bogdanm 0:9b334a45a8ff 79
bogdanm 0:9b334a45a8ff 80 /** Low frequency B group identifier */
bogdanm 0:9b334a45a8ff 81 #define CMU_LFB 1
bogdanm 0:9b334a45a8ff 82
bogdanm 0:9b334a45a8ff 83 /** @endcond */
bogdanm 0:9b334a45a8ff 84
bogdanm 0:9b334a45a8ff 85 /*******************************************************************************
bogdanm 0:9b334a45a8ff 86 ************************** LOCAL FUNCTIONS ********************************
bogdanm 0:9b334a45a8ff 87 ******************************************************************************/
bogdanm 0:9b334a45a8ff 88
bogdanm 0:9b334a45a8ff 89 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 90
bogdanm 0:9b334a45a8ff 91 #if defined( CMU_CTRL_HFLE ) && \
bogdanm 0:9b334a45a8ff 92 !defined ( _EFM32_WONDER_FAMILY ) && \
bogdanm 0:9b334a45a8ff 93 !defined ( _EZR32_LEOPARD_FAMILY ) && \
bogdanm 0:9b334a45a8ff 94 !defined ( _EZR32_WONDER_FAMILY )
bogdanm 0:9b334a45a8ff 95
bogdanm 0:9b334a45a8ff 96 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 97 * @brief
bogdanm 0:9b334a45a8ff 98 * Return max allowed frequency for low energy peripherals.
bogdanm 0:9b334a45a8ff 99 ******************************************************************************/
bogdanm 0:9b334a45a8ff 100 static uint32_t CMU_MaxFreqHfle(void)
bogdanm 0:9b334a45a8ff 101 {
bogdanm 0:9b334a45a8ff 102 /* SYSTEM_GetFamily and SYSTEM_ChipRevisionGet could have been used here
bogdanm 0:9b334a45a8ff 103 but we want to minimize dependencies in em_cmu.c. */
bogdanm 0:9b334a45a8ff 104 uint16_t majorMinorRev;
bogdanm 0:9b334a45a8ff 105 uint8_t deviceFamily = ((DEVINFO->PART & _DEVINFO_PART_DEVICE_FAMILY_MASK)
bogdanm 0:9b334a45a8ff 106 >> _DEVINFO_PART_DEVICE_FAMILY_SHIFT);
bogdanm 0:9b334a45a8ff 107 switch (deviceFamily)
bogdanm 0:9b334a45a8ff 108 {
bogdanm 0:9b334a45a8ff 109 case _DEVINFO_PART_DEVICE_FAMILY_LG:
bogdanm 0:9b334a45a8ff 110 /* CHIP MAJOR bit [3:0] */
bogdanm 0:9b334a45a8ff 111 majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
bogdanm 0:9b334a45a8ff 112 >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);
bogdanm 0:9b334a45a8ff 113 /* CHIP MINOR bit [7:4] */
bogdanm 0:9b334a45a8ff 114 majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
bogdanm 0:9b334a45a8ff 115 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
bogdanm 0:9b334a45a8ff 116 /* CHIP MINOR bit [3:0] */
bogdanm 0:9b334a45a8ff 117 majorMinorRev |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
bogdanm 0:9b334a45a8ff 118 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
bogdanm 0:9b334a45a8ff 119
bogdanm 0:9b334a45a8ff 120 if (majorMinorRev >= 0x0204)
bogdanm 0:9b334a45a8ff 121 return 24000000;
bogdanm 0:9b334a45a8ff 122 else
bogdanm 0:9b334a45a8ff 123 return 32000000;
bogdanm 0:9b334a45a8ff 124 case _DEVINFO_PART_DEVICE_FAMILY_GG:
bogdanm 0:9b334a45a8ff 125 return 32000000;
bogdanm 0:9b334a45a8ff 126 case _DEVINFO_PART_DEVICE_FAMILY_WG:
bogdanm 0:9b334a45a8ff 127 return 24000000;
bogdanm 0:9b334a45a8ff 128 default:
bogdanm 0:9b334a45a8ff 129 /* Invalid device family. */
bogdanm 0:9b334a45a8ff 130 EFM_ASSERT(false);
bogdanm 0:9b334a45a8ff 131 return 0;
bogdanm 0:9b334a45a8ff 132 }
bogdanm 0:9b334a45a8ff 133 }
bogdanm 0:9b334a45a8ff 134 #endif
bogdanm 0:9b334a45a8ff 135
bogdanm 0:9b334a45a8ff 136
bogdanm 0:9b334a45a8ff 137 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 138 * @brief
bogdanm 0:9b334a45a8ff 139 * Configure flash access wait states in order to support given core clock
bogdanm 0:9b334a45a8ff 140 * frequency.
bogdanm 0:9b334a45a8ff 141 *
bogdanm 0:9b334a45a8ff 142 * @param[in] hfcoreclk
bogdanm 0:9b334a45a8ff 143 * Core clock frequency to configure flash wait-states for
bogdanm 0:9b334a45a8ff 144 ******************************************************************************/
bogdanm 0:9b334a45a8ff 145 static void CMU_FlashWaitStateControl(uint32_t hfcoreclk)
bogdanm 0:9b334a45a8ff 146 {
bogdanm 0:9b334a45a8ff 147 uint32_t mode;
bogdanm 0:9b334a45a8ff 148 bool mscLocked;
bogdanm 0:9b334a45a8ff 149 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
bogdanm 0:9b334a45a8ff 150 bool scbtpEn;
bogdanm 0:9b334a45a8ff 151 #endif
bogdanm 0:9b334a45a8ff 152
bogdanm 0:9b334a45a8ff 153 /* Make sure the MSC is unlocked */
bogdanm 0:9b334a45a8ff 154 mscLocked = MSC->LOCK;
bogdanm 0:9b334a45a8ff 155 MSC->LOCK = MSC_UNLOCK_CODE;
bogdanm 0:9b334a45a8ff 156
bogdanm 0:9b334a45a8ff 157 /* Get mode and SCBTP enable */
bogdanm 0:9b334a45a8ff 158 mode = MSC->READCTRL & _MSC_READCTRL_MODE_MASK;
bogdanm 0:9b334a45a8ff 159 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
bogdanm 0:9b334a45a8ff 160 switch(mode)
bogdanm 0:9b334a45a8ff 161 {
bogdanm 0:9b334a45a8ff 162 case MSC_READCTRL_MODE_WS0:
bogdanm 0:9b334a45a8ff 163 case MSC_READCTRL_MODE_WS1:
bogdanm 0:9b334a45a8ff 164 #if defined( MSC_READCTRL_MODE_WS2 )
bogdanm 0:9b334a45a8ff 165 case MSC_READCTRL_MODE_WS2:
bogdanm 0:9b334a45a8ff 166 #endif
bogdanm 0:9b334a45a8ff 167 scbtpEn = false;
bogdanm 0:9b334a45a8ff 168 break;
bogdanm 0:9b334a45a8ff 169
bogdanm 0:9b334a45a8ff 170 default: /* WSxSCBTP */
bogdanm 0:9b334a45a8ff 171 scbtpEn = true;
bogdanm 0:9b334a45a8ff 172 break;
bogdanm 0:9b334a45a8ff 173 }
bogdanm 0:9b334a45a8ff 174 #endif
bogdanm 0:9b334a45a8ff 175
bogdanm 0:9b334a45a8ff 176
bogdanm 0:9b334a45a8ff 177 /* Set mode based on the core clock frequency and SCBTP enable */
bogdanm 0:9b334a45a8ff 178 #if defined( MSC_READCTRL_MODE_WS0SCBTP )
bogdanm 0:9b334a45a8ff 179 if (false)
bogdanm 0:9b334a45a8ff 180 {
bogdanm 0:9b334a45a8ff 181 }
bogdanm 0:9b334a45a8ff 182 #if defined( MSC_READCTRL_MODE_WS2 )
bogdanm 0:9b334a45a8ff 183 else if (hfcoreclk > CMU_MAX_FREQ_1WS)
bogdanm 0:9b334a45a8ff 184 {
bogdanm 0:9b334a45a8ff 185 mode = (scbtpEn ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2);
bogdanm 0:9b334a45a8ff 186 }
bogdanm 0:9b334a45a8ff 187 #endif
bogdanm 0:9b334a45a8ff 188 else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))
bogdanm 0:9b334a45a8ff 189 {
bogdanm 0:9b334a45a8ff 190 mode = (scbtpEn ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1);
bogdanm 0:9b334a45a8ff 191 }
bogdanm 0:9b334a45a8ff 192 else
bogdanm 0:9b334a45a8ff 193 {
bogdanm 0:9b334a45a8ff 194 mode = (scbtpEn ? MSC_READCTRL_MODE_WS0SCBTP : MSC_READCTRL_MODE_WS0);
bogdanm 0:9b334a45a8ff 195 }
bogdanm 0:9b334a45a8ff 196
bogdanm 0:9b334a45a8ff 197 #else /* If MODE and SCBTP is in separate register fields */
bogdanm 0:9b334a45a8ff 198
bogdanm 0:9b334a45a8ff 199 if (false)
bogdanm 0:9b334a45a8ff 200 {
bogdanm 0:9b334a45a8ff 201 }
bogdanm 0:9b334a45a8ff 202 #if defined( MSC_READCTRL_MODE_WS2 )
bogdanm 0:9b334a45a8ff 203 else if (hfcoreclk > CMU_MAX_FREQ_1WS)
bogdanm 0:9b334a45a8ff 204 {
bogdanm 0:9b334a45a8ff 205 mode = MSC_READCTRL_MODE_WS2;
bogdanm 0:9b334a45a8ff 206 }
bogdanm 0:9b334a45a8ff 207 #endif
bogdanm 0:9b334a45a8ff 208 else if ((hfcoreclk <= CMU_MAX_FREQ_1WS) && (hfcoreclk > CMU_MAX_FREQ_0WS))
bogdanm 0:9b334a45a8ff 209 {
bogdanm 0:9b334a45a8ff 210 mode = MSC_READCTRL_MODE_WS1;
bogdanm 0:9b334a45a8ff 211 }
bogdanm 0:9b334a45a8ff 212 else
bogdanm 0:9b334a45a8ff 213 {
bogdanm 0:9b334a45a8ff 214 mode = MSC_READCTRL_MODE_WS0;
bogdanm 0:9b334a45a8ff 215 }
bogdanm 0:9b334a45a8ff 216 #endif
bogdanm 0:9b334a45a8ff 217
bogdanm 0:9b334a45a8ff 218 /* BUS_RegMaskedWrite cannot be used here as it would temporarely set the
bogdanm 0:9b334a45a8ff 219 mode field to WS0 */
bogdanm 0:9b334a45a8ff 220 MSC->READCTRL = (MSC->READCTRL &~_MSC_READCTRL_MODE_MASK) | mode;
bogdanm 0:9b334a45a8ff 221
bogdanm 0:9b334a45a8ff 222 if (mscLocked)
bogdanm 0:9b334a45a8ff 223 {
bogdanm 0:9b334a45a8ff 224 MSC->LOCK = 0;
bogdanm 0:9b334a45a8ff 225 }
bogdanm 0:9b334a45a8ff 226 }
bogdanm 0:9b334a45a8ff 227
bogdanm 0:9b334a45a8ff 228
bogdanm 0:9b334a45a8ff 229 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 230 * @brief
bogdanm 0:9b334a45a8ff 231 * Configure flash access wait states to most conservative setting for
bogdanm 0:9b334a45a8ff 232 * this target. Retain SCBTP setting.
bogdanm 0:9b334a45a8ff 233 ******************************************************************************/
bogdanm 0:9b334a45a8ff 234 static void CMU_FlashWaitStateMax(void)
bogdanm 0:9b334a45a8ff 235 {
bogdanm 0:9b334a45a8ff 236 uint32_t maxCoreClock;
bogdanm 0:9b334a45a8ff 237 #if defined (_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 238 maxCoreClock = 32000000;
bogdanm 0:9b334a45a8ff 239 #elif defined (_EFM32_GIANT_FAMILY)
bogdanm 0:9b334a45a8ff 240 maxCoreClock = 48000000;
bogdanm 0:9b334a45a8ff 241 #elif defined (_EFM32_TINY_FAMILY)
bogdanm 0:9b334a45a8ff 242 maxCoreClock = 32000000;
bogdanm 0:9b334a45a8ff 243 #elif defined (_EFM32_LEOPARD_FAMILY)
bogdanm 0:9b334a45a8ff 244 maxCoreClock = 48000000;
bogdanm 0:9b334a45a8ff 245 #elif defined (_EFM32_WONDER_FAMILY)
bogdanm 0:9b334a45a8ff 246 maxCoreClock = 48000000;
bogdanm 0:9b334a45a8ff 247 #elif defined (_EFM32_ZERO_FAMILY)
bogdanm 0:9b334a45a8ff 248 maxCoreClock = 24000000;
bogdanm 0:9b334a45a8ff 249 #elif defined (_EFM32_HAPPY_FAMILY)
bogdanm 0:9b334a45a8ff 250 maxCoreClock = 25000000;
bogdanm 0:9b334a45a8ff 251 #else
bogdanm 0:9b334a45a8ff 252 #error "Max core clock frequency is not defined for this family"
bogdanm 0:9b334a45a8ff 253 #endif
bogdanm 0:9b334a45a8ff 254
bogdanm 0:9b334a45a8ff 255 /* Use SystemMaxCoreClockGet() when available in CMSIS */
bogdanm 0:9b334a45a8ff 256 CMU_FlashWaitStateControl(maxCoreClock);
bogdanm 0:9b334a45a8ff 257 }
bogdanm 0:9b334a45a8ff 258
bogdanm 0:9b334a45a8ff 259
bogdanm 0:9b334a45a8ff 260 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 261 * @brief Convert dividend to prescaler logarithmic value. Only works for even
bogdanm 0:9b334a45a8ff 262 * numbers equal to 2^n
bogdanm 0:9b334a45a8ff 263 * @param[in] div Unscaled dividend,
bogdanm 0:9b334a45a8ff 264 * @return Base 2 logarithm of input, as used by fixed prescalers
bogdanm 0:9b334a45a8ff 265 ******************************************************************************/
bogdanm 0:9b334a45a8ff 266 __STATIC_INLINE uint32_t CMU_DivToLog2(CMU_ClkDiv_TypeDef div)
bogdanm 0:9b334a45a8ff 267 {
bogdanm 0:9b334a45a8ff 268 uint32_t log2;
bogdanm 0:9b334a45a8ff 269
bogdanm 0:9b334a45a8ff 270 /* Prescalers take argument of 32768 or less */
bogdanm 0:9b334a45a8ff 271 EFM_ASSERT((div>0) && (div <= 32768));
bogdanm 0:9b334a45a8ff 272
bogdanm 0:9b334a45a8ff 273 /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
bogdanm 0:9b334a45a8ff 274 log2 = (31 - __CLZ(div));
bogdanm 0:9b334a45a8ff 275
bogdanm 0:9b334a45a8ff 276 return log2;
bogdanm 0:9b334a45a8ff 277 }
bogdanm 0:9b334a45a8ff 278
bogdanm 0:9b334a45a8ff 279
bogdanm 0:9b334a45a8ff 280 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 281 * @brief Convert logarithm of 2 prescaler to division factor
bogdanm 0:9b334a45a8ff 282 * @param[in] log2
bogdanm 0:9b334a45a8ff 283 * @return Dividend
bogdanm 0:9b334a45a8ff 284 ******************************************************************************/
bogdanm 0:9b334a45a8ff 285 __STATIC_INLINE uint32_t CMU_Log2ToDiv(uint32_t log2)
bogdanm 0:9b334a45a8ff 286 {
bogdanm 0:9b334a45a8ff 287 return 1<<log2;
bogdanm 0:9b334a45a8ff 288 }
bogdanm 0:9b334a45a8ff 289
bogdanm 0:9b334a45a8ff 290
bogdanm 0:9b334a45a8ff 291 #if defined(USB_PRESENT)
bogdanm 0:9b334a45a8ff 292 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 293 * @brief
bogdanm 0:9b334a45a8ff 294 * Get the USBC frequency
bogdanm 0:9b334a45a8ff 295 *
bogdanm 0:9b334a45a8ff 296 * @return
bogdanm 0:9b334a45a8ff 297 * USBC frequency in Hz
bogdanm 0:9b334a45a8ff 298 ******************************************************************************/
bogdanm 0:9b334a45a8ff 299 static uint32_t CMU_USBCClkGet(void)
bogdanm 0:9b334a45a8ff 300 {
bogdanm 0:9b334a45a8ff 301 uint32_t ret;
bogdanm 0:9b334a45a8ff 302 CMU_Select_TypeDef clk;
bogdanm 0:9b334a45a8ff 303
bogdanm 0:9b334a45a8ff 304 /* Get selected clock source */
bogdanm 0:9b334a45a8ff 305 clk = CMU_ClockSelectGet(cmuClock_USBC);
bogdanm 0:9b334a45a8ff 306
bogdanm 0:9b334a45a8ff 307 switch(clk)
bogdanm 0:9b334a45a8ff 308 {
bogdanm 0:9b334a45a8ff 309 case cmuSelect_LFXO:
bogdanm 0:9b334a45a8ff 310 ret = SystemLFXOClockGet();
bogdanm 0:9b334a45a8ff 311 break;
bogdanm 0:9b334a45a8ff 312 case cmuSelect_LFRCO:
bogdanm 0:9b334a45a8ff 313 ret = SystemLFRCOClockGet();
bogdanm 0:9b334a45a8ff 314 break;
bogdanm 0:9b334a45a8ff 315 case cmuSelect_HFCLK:
bogdanm 0:9b334a45a8ff 316 ret = SystemHFClockGet();
bogdanm 0:9b334a45a8ff 317 break;
bogdanm 0:9b334a45a8ff 318 default:
bogdanm 0:9b334a45a8ff 319 /* Clock is not enabled */
bogdanm 0:9b334a45a8ff 320 ret = 0;
bogdanm 0:9b334a45a8ff 321 break;
bogdanm 0:9b334a45a8ff 322 }
bogdanm 0:9b334a45a8ff 323 return ret;
bogdanm 0:9b334a45a8ff 324 }
bogdanm 0:9b334a45a8ff 325 #endif
bogdanm 0:9b334a45a8ff 326
bogdanm 0:9b334a45a8ff 327
bogdanm 0:9b334a45a8ff 328 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 329 * @brief
bogdanm 0:9b334a45a8ff 330 * Get the AUX clock frequency. Used by MSC flash programming and LESENSE,
bogdanm 0:9b334a45a8ff 331 * by default also as debug clock.
bogdanm 0:9b334a45a8ff 332 *
bogdanm 0:9b334a45a8ff 333 * @return
bogdanm 0:9b334a45a8ff 334 * AUX Frequency in Hz
bogdanm 0:9b334a45a8ff 335 ******************************************************************************/
bogdanm 0:9b334a45a8ff 336 static uint32_t CMU_AUXClkGet(void)
bogdanm 0:9b334a45a8ff 337 {
bogdanm 0:9b334a45a8ff 338 uint32_t ret;
bogdanm 0:9b334a45a8ff 339
bogdanm 0:9b334a45a8ff 340 #if defined(_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 341 /* Gecko has a fixed 14Mhz AUXHFRCO clock */
bogdanm 0:9b334a45a8ff 342 ret = 14000000;
bogdanm 0:9b334a45a8ff 343 #else
bogdanm 0:9b334a45a8ff 344 switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)
bogdanm 0:9b334a45a8ff 345 {
bogdanm 0:9b334a45a8ff 346 case CMU_AUXHFRCOCTRL_BAND_1MHZ:
bogdanm 0:9b334a45a8ff 347 ret = 1000000;
bogdanm 0:9b334a45a8ff 348 break;
bogdanm 0:9b334a45a8ff 349 case CMU_AUXHFRCOCTRL_BAND_7MHZ:
bogdanm 0:9b334a45a8ff 350 ret = 7000000;
bogdanm 0:9b334a45a8ff 351 break;
bogdanm 0:9b334a45a8ff 352 case CMU_AUXHFRCOCTRL_BAND_11MHZ:
bogdanm 0:9b334a45a8ff 353 ret = 11000000;
bogdanm 0:9b334a45a8ff 354 break;
bogdanm 0:9b334a45a8ff 355 case CMU_AUXHFRCOCTRL_BAND_14MHZ:
bogdanm 0:9b334a45a8ff 356 ret = 14000000;
bogdanm 0:9b334a45a8ff 357 break;
bogdanm 0:9b334a45a8ff 358 case CMU_AUXHFRCOCTRL_BAND_21MHZ:
bogdanm 0:9b334a45a8ff 359 ret = 21000000;
bogdanm 0:9b334a45a8ff 360 break;
bogdanm 0:9b334a45a8ff 361 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
bogdanm 0:9b334a45a8ff 362 case CMU_AUXHFRCOCTRL_BAND_28MHZ:
bogdanm 0:9b334a45a8ff 363 ret = 28000000;
bogdanm 0:9b334a45a8ff 364 break;
bogdanm 0:9b334a45a8ff 365 #endif
bogdanm 0:9b334a45a8ff 366 default:
bogdanm 0:9b334a45a8ff 367 ret = 0;
bogdanm 0:9b334a45a8ff 368 break;
bogdanm 0:9b334a45a8ff 369 }
bogdanm 0:9b334a45a8ff 370 #endif
bogdanm 0:9b334a45a8ff 371 return ret;
bogdanm 0:9b334a45a8ff 372 }
bogdanm 0:9b334a45a8ff 373
bogdanm 0:9b334a45a8ff 374
bogdanm 0:9b334a45a8ff 375 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 376 * @brief
bogdanm 0:9b334a45a8ff 377 * Get the Debug Trace clock frequency
bogdanm 0:9b334a45a8ff 378 *
bogdanm 0:9b334a45a8ff 379 * @return
bogdanm 0:9b334a45a8ff 380 * Debug Trace frequency in Hz
bogdanm 0:9b334a45a8ff 381 ******************************************************************************/
bogdanm 0:9b334a45a8ff 382 static uint32_t CMU_DBGClkGet(void)
bogdanm 0:9b334a45a8ff 383 {
bogdanm 0:9b334a45a8ff 384 uint32_t ret;
bogdanm 0:9b334a45a8ff 385 CMU_Select_TypeDef clk;
bogdanm 0:9b334a45a8ff 386
bogdanm 0:9b334a45a8ff 387 /* Get selected clock source */
bogdanm 0:9b334a45a8ff 388 clk = CMU_ClockSelectGet(cmuClock_DBG);
bogdanm 0:9b334a45a8ff 389
bogdanm 0:9b334a45a8ff 390 switch(clk)
bogdanm 0:9b334a45a8ff 391 {
bogdanm 0:9b334a45a8ff 392 case cmuSelect_HFCLK:
bogdanm 0:9b334a45a8ff 393 ret = SystemHFClockGet();
bogdanm 0:9b334a45a8ff 394 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
bogdanm 0:9b334a45a8ff 395 /* Giant Gecko has an additional divider, not used by USBC */
bogdanm 0:9b334a45a8ff 396 ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 397 _CMU_CTRL_HFCLKDIV_SHIFT));
bogdanm 0:9b334a45a8ff 398 #endif
bogdanm 0:9b334a45a8ff 399 break;
bogdanm 0:9b334a45a8ff 400
bogdanm 0:9b334a45a8ff 401 case cmuSelect_AUXHFRCO:
bogdanm 0:9b334a45a8ff 402 ret = CMU_AUXClkGet();
bogdanm 0:9b334a45a8ff 403 break;
bogdanm 0:9b334a45a8ff 404
bogdanm 0:9b334a45a8ff 405 default:
bogdanm 0:9b334a45a8ff 406 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 407 ret = 0;
bogdanm 0:9b334a45a8ff 408 break;
bogdanm 0:9b334a45a8ff 409 }
bogdanm 0:9b334a45a8ff 410 return ret;
bogdanm 0:9b334a45a8ff 411 }
bogdanm 0:9b334a45a8ff 412
bogdanm 0:9b334a45a8ff 413
bogdanm 0:9b334a45a8ff 414 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 415 * @brief
bogdanm 0:9b334a45a8ff 416 * Get the LFnCLK frequency based on current configuration.
bogdanm 0:9b334a45a8ff 417 *
bogdanm 0:9b334a45a8ff 418 * @param[in] lfClkBranch
bogdanm 0:9b334a45a8ff 419 * LF branch, 0 = LFA, 1 = LFB, ...
bogdanm 0:9b334a45a8ff 420 *
bogdanm 0:9b334a45a8ff 421 * @return
bogdanm 0:9b334a45a8ff 422 * The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is
bogdanm 0:9b334a45a8ff 423 * returned.
bogdanm 0:9b334a45a8ff 424 ******************************************************************************/
bogdanm 0:9b334a45a8ff 425 static uint32_t CMU_LFClkGet(unsigned int lfClkBranch)
bogdanm 0:9b334a45a8ff 426 {
bogdanm 0:9b334a45a8ff 427 uint32_t ret;
bogdanm 0:9b334a45a8ff 428
bogdanm 0:9b334a45a8ff 429 EFM_ASSERT(lfClkBranch == CMU_LFA || lfClkBranch == CMU_LFB);
bogdanm 0:9b334a45a8ff 430
bogdanm 0:9b334a45a8ff 431 switch ((CMU->LFCLKSEL >> (lfClkBranch * 2)) & 0x3)
bogdanm 0:9b334a45a8ff 432 {
bogdanm 0:9b334a45a8ff 433 case _CMU_LFCLKSEL_LFA_LFRCO:
bogdanm 0:9b334a45a8ff 434 ret = SystemLFRCOClockGet();
bogdanm 0:9b334a45a8ff 435 break;
bogdanm 0:9b334a45a8ff 436
bogdanm 0:9b334a45a8ff 437 case _CMU_LFCLKSEL_LFA_LFXO:
bogdanm 0:9b334a45a8ff 438 ret = SystemLFXOClockGet();
bogdanm 0:9b334a45a8ff 439 break;
bogdanm 0:9b334a45a8ff 440
bogdanm 0:9b334a45a8ff 441 case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
bogdanm 0:9b334a45a8ff 442 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 443 /* Giant Gecko can use a /4 divider (and must if >32MHz) or HFLE is set */
bogdanm 0:9b334a45a8ff 444 if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK) == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)||
bogdanm 0:9b334a45a8ff 445 (CMU->CTRL & CMU_CTRL_HFLE))
bogdanm 0:9b334a45a8ff 446 {
bogdanm 0:9b334a45a8ff 447 ret = SystemCoreClockGet() / 4;
bogdanm 0:9b334a45a8ff 448 }
bogdanm 0:9b334a45a8ff 449 else
bogdanm 0:9b334a45a8ff 450 {
bogdanm 0:9b334a45a8ff 451 ret = SystemCoreClockGet() / 2;
bogdanm 0:9b334a45a8ff 452 }
bogdanm 0:9b334a45a8ff 453 #else
bogdanm 0:9b334a45a8ff 454 ret = SystemCoreClockGet() / 2;
bogdanm 0:9b334a45a8ff 455 #endif
bogdanm 0:9b334a45a8ff 456 break;
bogdanm 0:9b334a45a8ff 457
bogdanm 0:9b334a45a8ff 458 case _CMU_LFCLKSEL_LFA_DISABLED:
bogdanm 0:9b334a45a8ff 459 #if defined( CMU_LFCLKSEL_LFAE )
bogdanm 0:9b334a45a8ff 460 /* Check LF Extended bit setting for ULFRCO clock */
bogdanm 0:9b334a45a8ff 461 if(CMU->LFCLKSEL >> (_CMU_LFCLKSEL_LFAE_SHIFT + lfClkBranch * 4))
bogdanm 0:9b334a45a8ff 462 {
bogdanm 0:9b334a45a8ff 463 ret = SystemULFRCOClockGet();
bogdanm 0:9b334a45a8ff 464 }
bogdanm 0:9b334a45a8ff 465 else
bogdanm 0:9b334a45a8ff 466 {
bogdanm 0:9b334a45a8ff 467 ret = 0;
bogdanm 0:9b334a45a8ff 468 }
bogdanm 0:9b334a45a8ff 469 #else
bogdanm 0:9b334a45a8ff 470 ret = 0;
bogdanm 0:9b334a45a8ff 471 #endif
bogdanm 0:9b334a45a8ff 472 break;
bogdanm 0:9b334a45a8ff 473
bogdanm 0:9b334a45a8ff 474 default:
bogdanm 0:9b334a45a8ff 475 ret = 0;
bogdanm 0:9b334a45a8ff 476 break;
bogdanm 0:9b334a45a8ff 477 }
bogdanm 0:9b334a45a8ff 478
bogdanm 0:9b334a45a8ff 479 return ret;
bogdanm 0:9b334a45a8ff 480 }
bogdanm 0:9b334a45a8ff 481
bogdanm 0:9b334a45a8ff 482
bogdanm 0:9b334a45a8ff 483 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 484 * @brief
bogdanm 0:9b334a45a8ff 485 * Wait for ongoing sync of register(s) to low frequency domain to complete.
bogdanm 0:9b334a45a8ff 486 *
bogdanm 0:9b334a45a8ff 487 * @param[in] mask
bogdanm 0:9b334a45a8ff 488 * Bitmask corresponding to SYNCBUSY register defined bits, indicating
bogdanm 0:9b334a45a8ff 489 * registers that must complete any ongoing synchronization.
bogdanm 0:9b334a45a8ff 490 ******************************************************************************/
bogdanm 0:9b334a45a8ff 491 __STATIC_INLINE void CMU_Sync(uint32_t mask)
bogdanm 0:9b334a45a8ff 492 {
bogdanm 0:9b334a45a8ff 493 /* Avoid deadlock if modifying the same register twice when freeze mode is */
bogdanm 0:9b334a45a8ff 494 /* activated. */
bogdanm 0:9b334a45a8ff 495 if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)
bogdanm 0:9b334a45a8ff 496 return;
bogdanm 0:9b334a45a8ff 497
bogdanm 0:9b334a45a8ff 498 /* Wait for any pending previous write operation to have been completed */
bogdanm 0:9b334a45a8ff 499 /* in low frequency domain */
bogdanm 0:9b334a45a8ff 500 while (CMU->SYNCBUSY & mask)
bogdanm 0:9b334a45a8ff 501 ;
bogdanm 0:9b334a45a8ff 502 }
bogdanm 0:9b334a45a8ff 503
bogdanm 0:9b334a45a8ff 504
bogdanm 0:9b334a45a8ff 505 /** @endcond */
bogdanm 0:9b334a45a8ff 506
bogdanm 0:9b334a45a8ff 507 /*******************************************************************************
bogdanm 0:9b334a45a8ff 508 ************************** GLOBAL FUNCTIONS *******************************
bogdanm 0:9b334a45a8ff 509 ******************************************************************************/
bogdanm 0:9b334a45a8ff 510
bogdanm 0:9b334a45a8ff 511 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 512 * @brief
bogdanm 0:9b334a45a8ff 513 * Calibrate clock.
bogdanm 0:9b334a45a8ff 514 *
bogdanm 0:9b334a45a8ff 515 * @details
bogdanm 0:9b334a45a8ff 516 * Run a calibration for HFCLK against a selectable reference clock. Please
bogdanm 0:9b334a45a8ff 517 * refer to the EFM32 reference manual, CMU chapter, for further details.
bogdanm 0:9b334a45a8ff 518 *
bogdanm 0:9b334a45a8ff 519 * @note
bogdanm 0:9b334a45a8ff 520 * This function will not return until calibration measurement is completed.
bogdanm 0:9b334a45a8ff 521 *
bogdanm 0:9b334a45a8ff 522 * @param[in] HFCycles
bogdanm 0:9b334a45a8ff 523 * The number of HFCLK cycles to run calibration. Increasing this number
bogdanm 0:9b334a45a8ff 524 * increases precision, but the calibration will take more time.
bogdanm 0:9b334a45a8ff 525 *
bogdanm 0:9b334a45a8ff 526 * @param[in] ref
bogdanm 0:9b334a45a8ff 527 * The reference clock used to compare HFCLK with.
bogdanm 0:9b334a45a8ff 528 *
bogdanm 0:9b334a45a8ff 529 * @return
bogdanm 0:9b334a45a8ff 530 * The number of ticks the reference clock after HFCycles ticks on the HF
bogdanm 0:9b334a45a8ff 531 * clock.
bogdanm 0:9b334a45a8ff 532 ******************************************************************************/
bogdanm 0:9b334a45a8ff 533 uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
bogdanm 0:9b334a45a8ff 534 {
bogdanm 0:9b334a45a8ff 535 EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
bogdanm 0:9b334a45a8ff 536
bogdanm 0:9b334a45a8ff 537 /* Set reference clock source */
bogdanm 0:9b334a45a8ff 538 switch (ref)
bogdanm 0:9b334a45a8ff 539 {
bogdanm 0:9b334a45a8ff 540 case cmuOsc_LFXO:
bogdanm 0:9b334a45a8ff 541 CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;
bogdanm 0:9b334a45a8ff 542 break;
bogdanm 0:9b334a45a8ff 543
bogdanm 0:9b334a45a8ff 544 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 545 CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;
bogdanm 0:9b334a45a8ff 546 break;
bogdanm 0:9b334a45a8ff 547
bogdanm 0:9b334a45a8ff 548 case cmuOsc_HFXO:
bogdanm 0:9b334a45a8ff 549 CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;
bogdanm 0:9b334a45a8ff 550 break;
bogdanm 0:9b334a45a8ff 551
bogdanm 0:9b334a45a8ff 552 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 553 CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;
bogdanm 0:9b334a45a8ff 554 break;
bogdanm 0:9b334a45a8ff 555
bogdanm 0:9b334a45a8ff 556 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 557 CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;
bogdanm 0:9b334a45a8ff 558 break;
bogdanm 0:9b334a45a8ff 559
bogdanm 0:9b334a45a8ff 560 default:
bogdanm 0:9b334a45a8ff 561 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 562 return 0;
bogdanm 0:9b334a45a8ff 563 }
bogdanm 0:9b334a45a8ff 564
bogdanm 0:9b334a45a8ff 565 /* Set top value */
bogdanm 0:9b334a45a8ff 566 CMU->CALCNT = HFCycles;
bogdanm 0:9b334a45a8ff 567
bogdanm 0:9b334a45a8ff 568 /* Start calibration */
bogdanm 0:9b334a45a8ff 569 CMU->CMD = CMU_CMD_CALSTART;
bogdanm 0:9b334a45a8ff 570
bogdanm 0:9b334a45a8ff 571 /* Wait until calibration completes */
bogdanm 0:9b334a45a8ff 572 while (CMU->STATUS & CMU_STATUS_CALBSY)
bogdanm 0:9b334a45a8ff 573 ;
bogdanm 0:9b334a45a8ff 574
bogdanm 0:9b334a45a8ff 575 return CMU->CALCNT;
bogdanm 0:9b334a45a8ff 576 }
bogdanm 0:9b334a45a8ff 577
bogdanm 0:9b334a45a8ff 578
bogdanm 0:9b334a45a8ff 579 #if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )
bogdanm 0:9b334a45a8ff 580 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 581 * @brief
bogdanm 0:9b334a45a8ff 582 * Configure clock calibration
bogdanm 0:9b334a45a8ff 583 *
bogdanm 0:9b334a45a8ff 584 * @details
bogdanm 0:9b334a45a8ff 585 * Configure a calibration for a selectable clock source against another
bogdanm 0:9b334a45a8ff 586 * selectable reference clock.
bogdanm 0:9b334a45a8ff 587 * Refer to the EFM32 reference manual, CMU chapter, for further details.
bogdanm 0:9b334a45a8ff 588 *
bogdanm 0:9b334a45a8ff 589 * @note
bogdanm 0:9b334a45a8ff 590 * After configuration, a call to CMU_CalibrateStart() is required, and
bogdanm 0:9b334a45a8ff 591 * the resulting calibration value can be read out with the
bogdanm 0:9b334a45a8ff 592 * CMU_CalibrateCountGet() function call.
bogdanm 0:9b334a45a8ff 593 *
bogdanm 0:9b334a45a8ff 594 * @param[in] downCycles
bogdanm 0:9b334a45a8ff 595 * The number of downSel clock cycles to run calibration. Increasing this
bogdanm 0:9b334a45a8ff 596 * number increases precision, but the calibration will take more time.
bogdanm 0:9b334a45a8ff 597 *
bogdanm 0:9b334a45a8ff 598 * @param[in] downSel
bogdanm 0:9b334a45a8ff 599 * The clock which will be counted down downCycles
bogdanm 0:9b334a45a8ff 600 *
bogdanm 0:9b334a45a8ff 601 * @param[in] upSel
bogdanm 0:9b334a45a8ff 602 * The reference clock, the number of cycles generated by this clock will
bogdanm 0:9b334a45a8ff 603 * be counted and added up, the result can be given with the
bogdanm 0:9b334a45a8ff 604 * CMU_CalibrateCountGet() function call.
bogdanm 0:9b334a45a8ff 605 ******************************************************************************/
bogdanm 0:9b334a45a8ff 606 void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
bogdanm 0:9b334a45a8ff 607 CMU_Osc_TypeDef upSel)
bogdanm 0:9b334a45a8ff 608 {
bogdanm 0:9b334a45a8ff 609 /* Keep untouched configuration settings */
bogdanm 0:9b334a45a8ff 610 uint32_t calCtrl = CMU->CALCTRL & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);
bogdanm 0:9b334a45a8ff 611
bogdanm 0:9b334a45a8ff 612 /* 20 bits of precision to calibration count register */
bogdanm 0:9b334a45a8ff 613 EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
bogdanm 0:9b334a45a8ff 614
bogdanm 0:9b334a45a8ff 615 /* Set down counting clock source - down counter */
bogdanm 0:9b334a45a8ff 616 switch (downSel)
bogdanm 0:9b334a45a8ff 617 {
bogdanm 0:9b334a45a8ff 618 case cmuOsc_LFXO:
bogdanm 0:9b334a45a8ff 619 calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;
bogdanm 0:9b334a45a8ff 620 break;
bogdanm 0:9b334a45a8ff 621
bogdanm 0:9b334a45a8ff 622 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 623 calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;
bogdanm 0:9b334a45a8ff 624 break;
bogdanm 0:9b334a45a8ff 625
bogdanm 0:9b334a45a8ff 626 case cmuOsc_HFXO:
bogdanm 0:9b334a45a8ff 627 calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;
bogdanm 0:9b334a45a8ff 628 break;
bogdanm 0:9b334a45a8ff 629
bogdanm 0:9b334a45a8ff 630 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 631 calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;
bogdanm 0:9b334a45a8ff 632 break;
bogdanm 0:9b334a45a8ff 633
bogdanm 0:9b334a45a8ff 634 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 635 calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;
bogdanm 0:9b334a45a8ff 636 break;
bogdanm 0:9b334a45a8ff 637
bogdanm 0:9b334a45a8ff 638 default:
bogdanm 0:9b334a45a8ff 639 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 640 break;
bogdanm 0:9b334a45a8ff 641 }
bogdanm 0:9b334a45a8ff 642
bogdanm 0:9b334a45a8ff 643 /* Set top value to be counted down by the downSel clock */
bogdanm 0:9b334a45a8ff 644 CMU->CALCNT = downCycles;
bogdanm 0:9b334a45a8ff 645
bogdanm 0:9b334a45a8ff 646 /* Set reference clock source - up counter */
bogdanm 0:9b334a45a8ff 647 switch (upSel)
bogdanm 0:9b334a45a8ff 648 {
bogdanm 0:9b334a45a8ff 649 case cmuOsc_LFXO:
bogdanm 0:9b334a45a8ff 650 calCtrl |= CMU_CALCTRL_UPSEL_LFXO;
bogdanm 0:9b334a45a8ff 651 break;
bogdanm 0:9b334a45a8ff 652
bogdanm 0:9b334a45a8ff 653 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 654 calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;
bogdanm 0:9b334a45a8ff 655 break;
bogdanm 0:9b334a45a8ff 656
bogdanm 0:9b334a45a8ff 657 case cmuOsc_HFXO:
bogdanm 0:9b334a45a8ff 658 calCtrl |= CMU_CALCTRL_UPSEL_HFXO;
bogdanm 0:9b334a45a8ff 659 break;
bogdanm 0:9b334a45a8ff 660
bogdanm 0:9b334a45a8ff 661 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 662 calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;
bogdanm 0:9b334a45a8ff 663 break;
bogdanm 0:9b334a45a8ff 664
bogdanm 0:9b334a45a8ff 665 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 666 calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;
bogdanm 0:9b334a45a8ff 667 break;
bogdanm 0:9b334a45a8ff 668
bogdanm 0:9b334a45a8ff 669 default:
bogdanm 0:9b334a45a8ff 670 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 671 break;
bogdanm 0:9b334a45a8ff 672 }
bogdanm 0:9b334a45a8ff 673
bogdanm 0:9b334a45a8ff 674 CMU->CALCTRL = calCtrl;
bogdanm 0:9b334a45a8ff 675 }
bogdanm 0:9b334a45a8ff 676 #endif
bogdanm 0:9b334a45a8ff 677
bogdanm 0:9b334a45a8ff 678
bogdanm 0:9b334a45a8ff 679 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 680 * @brief
bogdanm 0:9b334a45a8ff 681 * Get clock divisor/prescaler.
bogdanm 0:9b334a45a8ff 682 *
bogdanm 0:9b334a45a8ff 683 * @param[in] clock
bogdanm 0:9b334a45a8ff 684 * Clock point to get divisor/prescaler for. Notice that not all clock points
bogdanm 0:9b334a45a8ff 685 * have a divisor/prescaler. Please refer to CMU overview in reference manual.
bogdanm 0:9b334a45a8ff 686 *
bogdanm 0:9b334a45a8ff 687 * @return
bogdanm 0:9b334a45a8ff 688 * The current clock point divisor/prescaler. 1 is returned
bogdanm 0:9b334a45a8ff 689 * if @p clock specifies a clock point without a divisor/prescaler.
bogdanm 0:9b334a45a8ff 690 ******************************************************************************/
bogdanm 0:9b334a45a8ff 691 CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
bogdanm 0:9b334a45a8ff 692 {
bogdanm 0:9b334a45a8ff 693 uint32_t divReg;
bogdanm 0:9b334a45a8ff 694 CMU_ClkDiv_TypeDef ret;
bogdanm 0:9b334a45a8ff 695
bogdanm 0:9b334a45a8ff 696 /* Get divisor reg id */
bogdanm 0:9b334a45a8ff 697 divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
bogdanm 0:9b334a45a8ff 698
bogdanm 0:9b334a45a8ff 699 switch (divReg)
bogdanm 0:9b334a45a8ff 700 {
bogdanm 0:9b334a45a8ff 701 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
bogdanm 0:9b334a45a8ff 702 case CMU_HFCLKDIV_REG:
bogdanm 0:9b334a45a8ff 703 ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 704 _CMU_CTRL_HFCLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 705 break;
bogdanm 0:9b334a45a8ff 706 #endif
bogdanm 0:9b334a45a8ff 707
bogdanm 0:9b334a45a8ff 708 case CMU_HFPERCLKDIV_REG:
bogdanm 0:9b334a45a8ff 709 ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV &
bogdanm 0:9b334a45a8ff 710 _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 711 _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 712 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 713 break;
bogdanm 0:9b334a45a8ff 714
bogdanm 0:9b334a45a8ff 715 case CMU_HFCORECLKDIV_REG:
bogdanm 0:9b334a45a8ff 716 ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV &
bogdanm 0:9b334a45a8ff 717 _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 718 _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 719 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 720 break;
bogdanm 0:9b334a45a8ff 721
bogdanm 0:9b334a45a8ff 722 case CMU_LFAPRESC0_REG:
bogdanm 0:9b334a45a8ff 723 switch (clock)
bogdanm 0:9b334a45a8ff 724 {
bogdanm 0:9b334a45a8ff 725 case cmuClock_RTC:
bogdanm 0:9b334a45a8ff 726 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
bogdanm 0:9b334a45a8ff 727 _CMU_LFAPRESC0_RTC_SHIFT));
bogdanm 0:9b334a45a8ff 728 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 729 break;
bogdanm 0:9b334a45a8ff 730
bogdanm 0:9b334a45a8ff 731 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
bogdanm 0:9b334a45a8ff 732 case cmuClock_LETIMER0:
bogdanm 0:9b334a45a8ff 733 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
bogdanm 0:9b334a45a8ff 734 _CMU_LFAPRESC0_LETIMER0_SHIFT));
bogdanm 0:9b334a45a8ff 735 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 736 break;
bogdanm 0:9b334a45a8ff 737 #endif
bogdanm 0:9b334a45a8ff 738
bogdanm 0:9b334a45a8ff 739 #if defined(_CMU_LFAPRESC0_LCD_MASK)
bogdanm 0:9b334a45a8ff 740 case cmuClock_LCDpre:
bogdanm 0:9b334a45a8ff 741 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
bogdanm 0:9b334a45a8ff 742 _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16));
bogdanm 0:9b334a45a8ff 743 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 744 break;
bogdanm 0:9b334a45a8ff 745 #endif
bogdanm 0:9b334a45a8ff 746
bogdanm 0:9b334a45a8ff 747 #if defined(_CMU_LFAPRESC0_LESENSE_MASK)
bogdanm 0:9b334a45a8ff 748 case cmuClock_LESENSE:
bogdanm 0:9b334a45a8ff 749 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
bogdanm 0:9b334a45a8ff 750 _CMU_LFAPRESC0_LESENSE_SHIFT));
bogdanm 0:9b334a45a8ff 751 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 752 break;
bogdanm 0:9b334a45a8ff 753 #endif
bogdanm 0:9b334a45a8ff 754
bogdanm 0:9b334a45a8ff 755 default:
bogdanm 0:9b334a45a8ff 756 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 757 ret = cmuClkDiv_1;
bogdanm 0:9b334a45a8ff 758 break;
bogdanm 0:9b334a45a8ff 759 }
bogdanm 0:9b334a45a8ff 760 break;
bogdanm 0:9b334a45a8ff 761
bogdanm 0:9b334a45a8ff 762 case CMU_LFBPRESC0_REG:
bogdanm 0:9b334a45a8ff 763 switch (clock)
bogdanm 0:9b334a45a8ff 764 {
bogdanm 0:9b334a45a8ff 765 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
bogdanm 0:9b334a45a8ff 766 case cmuClock_LEUART0:
bogdanm 0:9b334a45a8ff 767 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
bogdanm 0:9b334a45a8ff 768 _CMU_LFBPRESC0_LEUART0_SHIFT));
bogdanm 0:9b334a45a8ff 769 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 770 break;
bogdanm 0:9b334a45a8ff 771 #endif
bogdanm 0:9b334a45a8ff 772
bogdanm 0:9b334a45a8ff 773 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
bogdanm 0:9b334a45a8ff 774 case cmuClock_LEUART1:
bogdanm 0:9b334a45a8ff 775 ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
bogdanm 0:9b334a45a8ff 776 _CMU_LFBPRESC0_LEUART1_SHIFT));
bogdanm 0:9b334a45a8ff 777 ret = CMU_Log2ToDiv(ret);
bogdanm 0:9b334a45a8ff 778 break;
bogdanm 0:9b334a45a8ff 779 #endif
bogdanm 0:9b334a45a8ff 780
bogdanm 0:9b334a45a8ff 781 default:
bogdanm 0:9b334a45a8ff 782 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 783 ret = cmuClkDiv_1;
bogdanm 0:9b334a45a8ff 784 break;
bogdanm 0:9b334a45a8ff 785 }
bogdanm 0:9b334a45a8ff 786 break;
bogdanm 0:9b334a45a8ff 787
bogdanm 0:9b334a45a8ff 788 default:
bogdanm 0:9b334a45a8ff 789 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 790 ret = cmuClkDiv_1;
bogdanm 0:9b334a45a8ff 791 break;
bogdanm 0:9b334a45a8ff 792 }
bogdanm 0:9b334a45a8ff 793
bogdanm 0:9b334a45a8ff 794 return(ret);
bogdanm 0:9b334a45a8ff 795 }
bogdanm 0:9b334a45a8ff 796
bogdanm 0:9b334a45a8ff 797
bogdanm 0:9b334a45a8ff 798 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 799 * @brief
bogdanm 0:9b334a45a8ff 800 * Set clock divisor/prescaler.
bogdanm 0:9b334a45a8ff 801 *
bogdanm 0:9b334a45a8ff 802 * @note
bogdanm 0:9b334a45a8ff 803 * If setting a LF clock prescaler, synchronization into the low frequency
bogdanm 0:9b334a45a8ff 804 * domain is required. If the same register is modified before a previous
bogdanm 0:9b334a45a8ff 805 * update has completed, this function will stall until the previous
bogdanm 0:9b334a45a8ff 806 * synchronization has completed. Please refer to CMU_FreezeEnable() for
bogdanm 0:9b334a45a8ff 807 * a suggestion on how to reduce stalling time in some use cases.
bogdanm 0:9b334a45a8ff 808 *
bogdanm 0:9b334a45a8ff 809 * @param[in] clock
bogdanm 0:9b334a45a8ff 810 * Clock point to set divisor/prescaler for. Notice that not all clock points
bogdanm 0:9b334a45a8ff 811 * have a divisor/prescaler, please refer to CMU overview in the reference
bogdanm 0:9b334a45a8ff 812 * manual.
bogdanm 0:9b334a45a8ff 813 *
bogdanm 0:9b334a45a8ff 814 * @param[in] div
bogdanm 0:9b334a45a8ff 815 * The clock divisor to use (<= cmuClkDiv_512).
bogdanm 0:9b334a45a8ff 816 ******************************************************************************/
bogdanm 0:9b334a45a8ff 817 void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
bogdanm 0:9b334a45a8ff 818 {
bogdanm 0:9b334a45a8ff 819 uint32_t freq;
bogdanm 0:9b334a45a8ff 820 uint32_t divReg;
bogdanm 0:9b334a45a8ff 821
bogdanm 0:9b334a45a8ff 822 /* Get divisor reg id */
bogdanm 0:9b334a45a8ff 823 divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
bogdanm 0:9b334a45a8ff 824
bogdanm 0:9b334a45a8ff 825 switch (divReg)
bogdanm 0:9b334a45a8ff 826 {
bogdanm 0:9b334a45a8ff 827 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
bogdanm 0:9b334a45a8ff 828 case CMU_HFCLKDIV_REG:
bogdanm 0:9b334a45a8ff 829 EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));
bogdanm 0:9b334a45a8ff 830
bogdanm 0:9b334a45a8ff 831 /* Configure worst case wait states for flash access before setting divisor */
bogdanm 0:9b334a45a8ff 832 CMU_FlashWaitStateMax();
bogdanm 0:9b334a45a8ff 833
bogdanm 0:9b334a45a8ff 834 /* Set divider */
bogdanm 0:9b334a45a8ff 835 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK) |
bogdanm 0:9b334a45a8ff 836 ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 837
bogdanm 0:9b334a45a8ff 838 /* Update CMSIS core clock variable */
bogdanm 0:9b334a45a8ff 839 /* (The function will update the global variable) */
bogdanm 0:9b334a45a8ff 840 freq = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 841
bogdanm 0:9b334a45a8ff 842 /* Optimize flash access wait state setting for current core clk */
bogdanm 0:9b334a45a8ff 843 CMU_FlashWaitStateControl(freq);
bogdanm 0:9b334a45a8ff 844 break;
bogdanm 0:9b334a45a8ff 845 #endif
bogdanm 0:9b334a45a8ff 846
bogdanm 0:9b334a45a8ff 847 case CMU_HFPERCLKDIV_REG:
bogdanm 0:9b334a45a8ff 848 EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));
bogdanm 0:9b334a45a8ff 849 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 850 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 851 CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) |
bogdanm 0:9b334a45a8ff 852 (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 853 break;
bogdanm 0:9b334a45a8ff 854
bogdanm 0:9b334a45a8ff 855 case CMU_HFCORECLKDIV_REG:
bogdanm 0:9b334a45a8ff 856 EFM_ASSERT(div <= cmuClkDiv_512);
bogdanm 0:9b334a45a8ff 857
bogdanm 0:9b334a45a8ff 858 /* Configure worst case wait states for flash access before setting divisor */
bogdanm 0:9b334a45a8ff 859 CMU_FlashWaitStateMax();
bogdanm 0:9b334a45a8ff 860
bogdanm 0:9b334a45a8ff 861 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 862 /* Clear HFLE and set DIV2 factor for peripheral clock
bogdanm 0:9b334a45a8ff 863 when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */
bogdanm 0:9b334a45a8ff 864 if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE)
bogdanm 0:9b334a45a8ff 865 {
bogdanm 0:9b334a45a8ff 866 /* Clear CMU HFLE */
bogdanm 0:9b334a45a8ff 867 BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 0);
bogdanm 0:9b334a45a8ff 868
bogdanm 0:9b334a45a8ff 869 /* Set DIV2 factor for peripheral clock */
bogdanm 0:9b334a45a8ff 870 BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
bogdanm 0:9b334a45a8ff 871 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);
bogdanm 0:9b334a45a8ff 872 }
bogdanm 0:9b334a45a8ff 873 else
bogdanm 0:9b334a45a8ff 874 {
bogdanm 0:9b334a45a8ff 875 /* Set CMU HFLE */
bogdanm 0:9b334a45a8ff 876 BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
bogdanm 0:9b334a45a8ff 877
bogdanm 0:9b334a45a8ff 878 /* Set DIV4 factor for peripheral clock */
bogdanm 0:9b334a45a8ff 879 BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
bogdanm 0:9b334a45a8ff 880 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
bogdanm 0:9b334a45a8ff 881 }
bogdanm 0:9b334a45a8ff 882 #endif
bogdanm 0:9b334a45a8ff 883
bogdanm 0:9b334a45a8ff 884 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 885 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 886
bogdanm 0:9b334a45a8ff 887 CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) |
bogdanm 0:9b334a45a8ff 888 (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
bogdanm 0:9b334a45a8ff 889
bogdanm 0:9b334a45a8ff 890 /* Update CMSIS core clock variable */
bogdanm 0:9b334a45a8ff 891 /* (The function will update the global variable) */
bogdanm 0:9b334a45a8ff 892 freq = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 893
bogdanm 0:9b334a45a8ff 894 /* Optimize flash access wait state setting for current core clk */
bogdanm 0:9b334a45a8ff 895 CMU_FlashWaitStateControl(freq);
bogdanm 0:9b334a45a8ff 896 break;
bogdanm 0:9b334a45a8ff 897
bogdanm 0:9b334a45a8ff 898 case CMU_LFAPRESC0_REG:
bogdanm 0:9b334a45a8ff 899 switch (clock)
bogdanm 0:9b334a45a8ff 900 {
bogdanm 0:9b334a45a8ff 901 case cmuClock_RTC:
bogdanm 0:9b334a45a8ff 902 EFM_ASSERT(div <= cmuClkDiv_32768);
bogdanm 0:9b334a45a8ff 903
bogdanm 0:9b334a45a8ff 904 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 905 CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
bogdanm 0:9b334a45a8ff 906
bogdanm 0:9b334a45a8ff 907 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 908 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 909
bogdanm 0:9b334a45a8ff 910 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK) |
bogdanm 0:9b334a45a8ff 911 (div << _CMU_LFAPRESC0_RTC_SHIFT);
bogdanm 0:9b334a45a8ff 912 break;
bogdanm 0:9b334a45a8ff 913
bogdanm 0:9b334a45a8ff 914 #if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
bogdanm 0:9b334a45a8ff 915 case cmuClock_LETIMER0:
bogdanm 0:9b334a45a8ff 916 EFM_ASSERT(div <= cmuClkDiv_32768);
bogdanm 0:9b334a45a8ff 917
bogdanm 0:9b334a45a8ff 918 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 919 CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
bogdanm 0:9b334a45a8ff 920
bogdanm 0:9b334a45a8ff 921 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 922 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 923
bogdanm 0:9b334a45a8ff 924 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK) |
bogdanm 0:9b334a45a8ff 925 (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);
bogdanm 0:9b334a45a8ff 926 break;
bogdanm 0:9b334a45a8ff 927 #endif
bogdanm 0:9b334a45a8ff 928
bogdanm 0:9b334a45a8ff 929 #if defined(LCD_PRESENT)
bogdanm 0:9b334a45a8ff 930 case cmuClock_LCDpre:
bogdanm 0:9b334a45a8ff 931 EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));
bogdanm 0:9b334a45a8ff 932
bogdanm 0:9b334a45a8ff 933 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 934 CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
bogdanm 0:9b334a45a8ff 935
bogdanm 0:9b334a45a8ff 936 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 937 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 938
bogdanm 0:9b334a45a8ff 939 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK) |
bogdanm 0:9b334a45a8ff 940 ((div - CMU_DivToLog2(cmuClkDiv_16)) << _CMU_LFAPRESC0_LCD_SHIFT);
bogdanm 0:9b334a45a8ff 941 break;
bogdanm 0:9b334a45a8ff 942 #endif /* defined(LCD_PRESENT) */
bogdanm 0:9b334a45a8ff 943
bogdanm 0:9b334a45a8ff 944 #if defined(LESENSE_PRESENT)
bogdanm 0:9b334a45a8ff 945 case cmuClock_LESENSE:
bogdanm 0:9b334a45a8ff 946 EFM_ASSERT(div <= cmuClkDiv_8);
bogdanm 0:9b334a45a8ff 947
bogdanm 0:9b334a45a8ff 948 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 949 CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
bogdanm 0:9b334a45a8ff 950
bogdanm 0:9b334a45a8ff 951 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 952 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 953
bogdanm 0:9b334a45a8ff 954 CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK) |
bogdanm 0:9b334a45a8ff 955 (div << _CMU_LFAPRESC0_LESENSE_SHIFT);
bogdanm 0:9b334a45a8ff 956 break;
bogdanm 0:9b334a45a8ff 957 #endif /* defined(LESENSE_PRESENT) */
bogdanm 0:9b334a45a8ff 958
bogdanm 0:9b334a45a8ff 959 default:
bogdanm 0:9b334a45a8ff 960 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 961 break;
bogdanm 0:9b334a45a8ff 962 }
bogdanm 0:9b334a45a8ff 963 break;
bogdanm 0:9b334a45a8ff 964
bogdanm 0:9b334a45a8ff 965 case CMU_LFBPRESC0_REG:
bogdanm 0:9b334a45a8ff 966 switch (clock)
bogdanm 0:9b334a45a8ff 967 {
bogdanm 0:9b334a45a8ff 968 #if defined(_CMU_LFBPRESC0_LEUART0_MASK)
bogdanm 0:9b334a45a8ff 969 case cmuClock_LEUART0:
bogdanm 0:9b334a45a8ff 970 EFM_ASSERT(div <= cmuClkDiv_8);
bogdanm 0:9b334a45a8ff 971
bogdanm 0:9b334a45a8ff 972 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 973 CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
bogdanm 0:9b334a45a8ff 974
bogdanm 0:9b334a45a8ff 975 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 976 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 977
bogdanm 0:9b334a45a8ff 978 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK) |
bogdanm 0:9b334a45a8ff 979 (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);
bogdanm 0:9b334a45a8ff 980 break;
bogdanm 0:9b334a45a8ff 981 #endif
bogdanm 0:9b334a45a8ff 982
bogdanm 0:9b334a45a8ff 983 #if defined(_CMU_LFBPRESC0_LEUART1_MASK)
bogdanm 0:9b334a45a8ff 984 case cmuClock_LEUART1:
bogdanm 0:9b334a45a8ff 985 EFM_ASSERT(div <= cmuClkDiv_8);
bogdanm 0:9b334a45a8ff 986
bogdanm 0:9b334a45a8ff 987 /* LF register about to be modified require sync. busy check */
bogdanm 0:9b334a45a8ff 988 CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
bogdanm 0:9b334a45a8ff 989
bogdanm 0:9b334a45a8ff 990 /* Convert to correct scale */
bogdanm 0:9b334a45a8ff 991 div = CMU_DivToLog2(div);
bogdanm 0:9b334a45a8ff 992
bogdanm 0:9b334a45a8ff 993 CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK) |
bogdanm 0:9b334a45a8ff 994 (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);
bogdanm 0:9b334a45a8ff 995 break;
bogdanm 0:9b334a45a8ff 996 #endif
bogdanm 0:9b334a45a8ff 997
bogdanm 0:9b334a45a8ff 998 default:
bogdanm 0:9b334a45a8ff 999 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1000 break;
bogdanm 0:9b334a45a8ff 1001 }
bogdanm 0:9b334a45a8ff 1002 break;
bogdanm 0:9b334a45a8ff 1003
bogdanm 0:9b334a45a8ff 1004 default:
bogdanm 0:9b334a45a8ff 1005 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1006 break;
bogdanm 0:9b334a45a8ff 1007 }
bogdanm 0:9b334a45a8ff 1008 }
bogdanm 0:9b334a45a8ff 1009
bogdanm 0:9b334a45a8ff 1010
bogdanm 0:9b334a45a8ff 1011 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1012 * @brief
bogdanm 0:9b334a45a8ff 1013 * Enable/disable a clock.
bogdanm 0:9b334a45a8ff 1014 *
bogdanm 0:9b334a45a8ff 1015 * @details
bogdanm 0:9b334a45a8ff 1016 * In general, module clocking is disabled after a reset. If a module
bogdanm 0:9b334a45a8ff 1017 * clock is disabled, the registers of that module are not accessible and
bogdanm 0:9b334a45a8ff 1018 * reading from such registers may return undefined values. Writing to
bogdanm 0:9b334a45a8ff 1019 * registers of clock disabled modules have no effect. One should normally
bogdanm 0:9b334a45a8ff 1020 * avoid accessing module registers of a module with a disabled clock.
bogdanm 0:9b334a45a8ff 1021 *
bogdanm 0:9b334a45a8ff 1022 * @note
bogdanm 0:9b334a45a8ff 1023 * If enabling/disabling a LF clock, synchronization into the low frequency
bogdanm 0:9b334a45a8ff 1024 * domain is required. If the same register is modified before a previous
bogdanm 0:9b334a45a8ff 1025 * update has completed, this function will stall until the previous
bogdanm 0:9b334a45a8ff 1026 * synchronization has completed. Please refer to CMU_FreezeEnable() for
bogdanm 0:9b334a45a8ff 1027 * a suggestion on how to reduce stalling time in some use cases.
bogdanm 0:9b334a45a8ff 1028 *
bogdanm 0:9b334a45a8ff 1029 * @param[in] clock
bogdanm 0:9b334a45a8ff 1030 * The clock to enable/disable. Notice that not all defined clock
bogdanm 0:9b334a45a8ff 1031 * points have separate enable/disable control, please refer to CMU overview
bogdanm 0:9b334a45a8ff 1032 * in reference manual.
bogdanm 0:9b334a45a8ff 1033 *
bogdanm 0:9b334a45a8ff 1034 * @param[in] enable
bogdanm 0:9b334a45a8ff 1035 * @li true - enable specified clock.
bogdanm 0:9b334a45a8ff 1036 * @li false - disable specified clock.
bogdanm 0:9b334a45a8ff 1037 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1038 void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
bogdanm 0:9b334a45a8ff 1039 {
bogdanm 0:9b334a45a8ff 1040 volatile uint32_t *reg;
bogdanm 0:9b334a45a8ff 1041 uint32_t bit;
bogdanm 0:9b334a45a8ff 1042 uint32_t sync = 0;
bogdanm 0:9b334a45a8ff 1043
bogdanm 0:9b334a45a8ff 1044 /* Identify enable register */
bogdanm 0:9b334a45a8ff 1045 switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)
bogdanm 0:9b334a45a8ff 1046 {
bogdanm 0:9b334a45a8ff 1047 case CMU_HFPERCLKDIV_EN_REG:
bogdanm 0:9b334a45a8ff 1048 reg = &(CMU->HFPERCLKDIV);
bogdanm 0:9b334a45a8ff 1049 break;
bogdanm 0:9b334a45a8ff 1050
bogdanm 0:9b334a45a8ff 1051 case CMU_HFPERCLKEN0_EN_REG:
bogdanm 0:9b334a45a8ff 1052 reg = &(CMU->HFPERCLKEN0);
bogdanm 0:9b334a45a8ff 1053 break;
bogdanm 0:9b334a45a8ff 1054
bogdanm 0:9b334a45a8ff 1055 case CMU_HFCORECLKEN0_EN_REG:
bogdanm 0:9b334a45a8ff 1056 reg = &(CMU->HFCORECLKEN0);
bogdanm 0:9b334a45a8ff 1057
bogdanm 0:9b334a45a8ff 1058 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 1059 /* Set HFLE and DIV4 factor for peripheral clock when
bogdanm 0:9b334a45a8ff 1060 running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */
bogdanm 0:9b334a45a8ff 1061 if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE )
bogdanm 0:9b334a45a8ff 1062 {
bogdanm 0:9b334a45a8ff 1063 /* Enable CMU HFLE */
bogdanm 0:9b334a45a8ff 1064 BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1065
bogdanm 0:9b334a45a8ff 1066 /* Set DIV4 factor for peripheral clock */
bogdanm 0:9b334a45a8ff 1067 BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
bogdanm 0:9b334a45a8ff 1068 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1069 }
bogdanm 0:9b334a45a8ff 1070 #endif
bogdanm 0:9b334a45a8ff 1071 break;
bogdanm 0:9b334a45a8ff 1072
bogdanm 0:9b334a45a8ff 1073 case CMU_LFACLKEN0_EN_REG:
bogdanm 0:9b334a45a8ff 1074 reg = &(CMU->LFACLKEN0);
bogdanm 0:9b334a45a8ff 1075 sync = CMU_SYNCBUSY_LFACLKEN0;
bogdanm 0:9b334a45a8ff 1076 break;
bogdanm 0:9b334a45a8ff 1077
bogdanm 0:9b334a45a8ff 1078 case CMU_LFBCLKEN0_EN_REG:
bogdanm 0:9b334a45a8ff 1079 reg = &(CMU->LFBCLKEN0);
bogdanm 0:9b334a45a8ff 1080 sync = CMU_SYNCBUSY_LFBCLKEN0;
bogdanm 0:9b334a45a8ff 1081 break;
bogdanm 0:9b334a45a8ff 1082
bogdanm 0:9b334a45a8ff 1083 case CMU_PCNT_EN_REG:
bogdanm 0:9b334a45a8ff 1084 reg = &(CMU->PCNTCTRL);
bogdanm 0:9b334a45a8ff 1085 break;
bogdanm 0:9b334a45a8ff 1086
bogdanm 0:9b334a45a8ff 1087 #if defined( _CMU_LFCCLKEN0_MASK )
bogdanm 0:9b334a45a8ff 1088 case CMU_LFCCLKEN0_EN_REG:
bogdanm 0:9b334a45a8ff 1089 reg = &(CMU->LFCCLKEN0);
bogdanm 0:9b334a45a8ff 1090 sync = CMU_SYNCBUSY_LFCCLKEN0;
bogdanm 0:9b334a45a8ff 1091 break;
bogdanm 0:9b334a45a8ff 1092 #endif
bogdanm 0:9b334a45a8ff 1093
bogdanm 0:9b334a45a8ff 1094 default: /* Cannot enable/disable clock point */
bogdanm 0:9b334a45a8ff 1095 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1096 return;
bogdanm 0:9b334a45a8ff 1097 }
bogdanm 0:9b334a45a8ff 1098
bogdanm 0:9b334a45a8ff 1099 /* Get bit position used to enable/disable */
bogdanm 0:9b334a45a8ff 1100 bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;
bogdanm 0:9b334a45a8ff 1101
bogdanm 0:9b334a45a8ff 1102 /* LF synchronization required? */
bogdanm 0:9b334a45a8ff 1103 if (sync)
bogdanm 0:9b334a45a8ff 1104 {
bogdanm 0:9b334a45a8ff 1105 CMU_Sync(sync);
bogdanm 0:9b334a45a8ff 1106 }
bogdanm 0:9b334a45a8ff 1107
bogdanm 0:9b334a45a8ff 1108 /* Set/clear bit as requested */
bogdanm 0:9b334a45a8ff 1109 BITBAND_Peripheral(reg, bit, (unsigned int)enable);
bogdanm 0:9b334a45a8ff 1110 }
bogdanm 0:9b334a45a8ff 1111
bogdanm 0:9b334a45a8ff 1112
bogdanm 0:9b334a45a8ff 1113 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1114 * @brief
bogdanm 0:9b334a45a8ff 1115 * Get clock frequency for a clock point.
bogdanm 0:9b334a45a8ff 1116 *
bogdanm 0:9b334a45a8ff 1117 * @param[in] clock
bogdanm 0:9b334a45a8ff 1118 * Clock point to fetch frequency for.
bogdanm 0:9b334a45a8ff 1119 *
bogdanm 0:9b334a45a8ff 1120 * @return
bogdanm 0:9b334a45a8ff 1121 * The current frequency in Hz.
bogdanm 0:9b334a45a8ff 1122 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1123 uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
bogdanm 0:9b334a45a8ff 1124 {
bogdanm 0:9b334a45a8ff 1125 uint32_t ret;
bogdanm 0:9b334a45a8ff 1126
bogdanm 0:9b334a45a8ff 1127 switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))
bogdanm 0:9b334a45a8ff 1128 {
bogdanm 0:9b334a45a8ff 1129 case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1130 {
bogdanm 0:9b334a45a8ff 1131 ret = SystemHFClockGet();
bogdanm 0:9b334a45a8ff 1132 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
bogdanm 0:9b334a45a8ff 1133 /* Giant Gecko has an additional divider, not used by USBC */
bogdanm 0:9b334a45a8ff 1134 ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 1135 _CMU_CTRL_HFCLKDIV_SHIFT));
bogdanm 0:9b334a45a8ff 1136 #endif
bogdanm 0:9b334a45a8ff 1137 } break;
bogdanm 0:9b334a45a8ff 1138
bogdanm 0:9b334a45a8ff 1139 #if defined(_CMU_HFPERCLKEN0_USART0_MASK) || \
bogdanm 0:9b334a45a8ff 1140 defined(_CMU_HFPERCLKEN0_USART1_MASK) || \
bogdanm 0:9b334a45a8ff 1141 defined(_CMU_HFPERCLKEN0_USART2_MASK) || \
bogdanm 0:9b334a45a8ff 1142 defined(_CMU_HFPERCLKEN0_UART0_MASK) || \
bogdanm 0:9b334a45a8ff 1143 defined(_CMU_HFPERCLKEN0_UART1_MASK) || \
bogdanm 0:9b334a45a8ff 1144 defined(_CMU_HFPERCLKEN0_TIMER0_MASK) || \
bogdanm 0:9b334a45a8ff 1145 defined(_CMU_HFPERCLKEN0_TIMER1_MASK) || \
bogdanm 0:9b334a45a8ff 1146 defined(_CMU_HFPERCLKEN0_TIMER2_MASK) || \
bogdanm 0:9b334a45a8ff 1147 defined(_CMU_HFPERCLKEN0_TIMER3_MASK) || \
bogdanm 0:9b334a45a8ff 1148 defined(_CMU_HFPERCLKEN0_ACMP0_MASK) || \
bogdanm 0:9b334a45a8ff 1149 defined(_CMU_HFPERCLKEN0_ACMP1_MASK) || \
bogdanm 0:9b334a45a8ff 1150 defined(_CMU_HFPERCLKEN0_DAC0_MASK) || \
bogdanm 0:9b334a45a8ff 1151 defined(_CMU_HFPERCLKEN0_IDAC0_MASK) || \
bogdanm 0:9b334a45a8ff 1152 defined(_CMU_HFPERCLKEN0_ADC0_MASK) || \
bogdanm 0:9b334a45a8ff 1153 defined(_CMU_HFPERCLKEN0_I2C0_MASK) || \
bogdanm 0:9b334a45a8ff 1154 defined(_CMU_HFPERCLKEN0_I2C1_MASK) || \
bogdanm 0:9b334a45a8ff 1155 defined(PRS_PRESENT) || \
bogdanm 0:9b334a45a8ff 1156 defined(VCMP_PRESENT)|| \
bogdanm 0:9b334a45a8ff 1157 defined(GPIO_PRESENT)
bogdanm 0:9b334a45a8ff 1158 case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1159 {
bogdanm 0:9b334a45a8ff 1160 ret = SystemHFClockGet();
bogdanm 0:9b334a45a8ff 1161 #if defined( _CMU_CTRL_HFCLKDIV_MASK )
bogdanm 0:9b334a45a8ff 1162 /* Leopard/Giant Gecko has an additional divider */
bogdanm 0:9b334a45a8ff 1163 ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 1164 _CMU_CTRL_HFCLKDIV_SHIFT));
bogdanm 0:9b334a45a8ff 1165 #endif
bogdanm 0:9b334a45a8ff 1166 ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
bogdanm 0:9b334a45a8ff 1167 _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;
bogdanm 0:9b334a45a8ff 1168 } break;
bogdanm 0:9b334a45a8ff 1169 #endif
bogdanm 0:9b334a45a8ff 1170
bogdanm 0:9b334a45a8ff 1171 #if defined(AES_PRESENT) || \
bogdanm 0:9b334a45a8ff 1172 defined(DMA_PRESENT) || \
bogdanm 0:9b334a45a8ff 1173 defined(EBI_PRESENT) || \
bogdanm 0:9b334a45a8ff 1174 defined(USB_PRESENT)
bogdanm 0:9b334a45a8ff 1175 case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1176 {
bogdanm 0:9b334a45a8ff 1177 ret = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 1178 } break;
bogdanm 0:9b334a45a8ff 1179 #endif
bogdanm 0:9b334a45a8ff 1180
bogdanm 0:9b334a45a8ff 1181 case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1182 {
bogdanm 0:9b334a45a8ff 1183 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1184 } break;
bogdanm 0:9b334a45a8ff 1185 #if defined(_CMU_LFACLKEN0_RTC_MASK)
bogdanm 0:9b334a45a8ff 1186 case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1187 {
bogdanm 0:9b334a45a8ff 1188 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1189 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
bogdanm 0:9b334a45a8ff 1190 _CMU_LFAPRESC0_RTC_SHIFT;
bogdanm 0:9b334a45a8ff 1191 } break;
bogdanm 0:9b334a45a8ff 1192 #endif
bogdanm 0:9b334a45a8ff 1193 #if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
bogdanm 0:9b334a45a8ff 1194 case (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1195 {
bogdanm 0:9b334a45a8ff 1196 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1197 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
bogdanm 0:9b334a45a8ff 1198 _CMU_LFAPRESC0_LETIMER0_SHIFT;
bogdanm 0:9b334a45a8ff 1199 } break;
bogdanm 0:9b334a45a8ff 1200 #endif
bogdanm 0:9b334a45a8ff 1201 #if defined(_CMU_LFACLKEN0_LCD_MASK)
bogdanm 0:9b334a45a8ff 1202 case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1203 {
bogdanm 0:9b334a45a8ff 1204 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1205 ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
bogdanm 0:9b334a45a8ff 1206 _CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16);
bogdanm 0:9b334a45a8ff 1207 } break;
bogdanm 0:9b334a45a8ff 1208
bogdanm 0:9b334a45a8ff 1209 case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1210 {
bogdanm 0:9b334a45a8ff 1211 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1212 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
bogdanm 0:9b334a45a8ff 1213 _CMU_LFAPRESC0_LCD_SHIFT;
bogdanm 0:9b334a45a8ff 1214 ret /= (1 + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >>
bogdanm 0:9b334a45a8ff 1215 _CMU_LCDCTRL_FDIV_SHIFT));
bogdanm 0:9b334a45a8ff 1216 } break;
bogdanm 0:9b334a45a8ff 1217 #endif
bogdanm 0:9b334a45a8ff 1218 #if defined(_CMU_LFACLKEN0_LESENSE_MASK)
bogdanm 0:9b334a45a8ff 1219 case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1220 {
bogdanm 0:9b334a45a8ff 1221 ret = CMU_LFClkGet(CMU_LFA);
bogdanm 0:9b334a45a8ff 1222 ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
bogdanm 0:9b334a45a8ff 1223 _CMU_LFAPRESC0_LESENSE_SHIFT;
bogdanm 0:9b334a45a8ff 1224 } break;
bogdanm 0:9b334a45a8ff 1225 #endif
bogdanm 0:9b334a45a8ff 1226 case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1227 {
bogdanm 0:9b334a45a8ff 1228 ret = CMU_LFClkGet(CMU_LFB);
bogdanm 0:9b334a45a8ff 1229 } break;
bogdanm 0:9b334a45a8ff 1230 #if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
bogdanm 0:9b334a45a8ff 1231 case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1232 {
bogdanm 0:9b334a45a8ff 1233 ret = CMU_LFClkGet(CMU_LFB);
bogdanm 0:9b334a45a8ff 1234 ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
bogdanm 0:9b334a45a8ff 1235 _CMU_LFBPRESC0_LEUART0_SHIFT;
bogdanm 0:9b334a45a8ff 1236 } break;
bogdanm 0:9b334a45a8ff 1237 #endif
bogdanm 0:9b334a45a8ff 1238 #if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
bogdanm 0:9b334a45a8ff 1239 case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1240 {
bogdanm 0:9b334a45a8ff 1241 ret = CMU_LFClkGet(CMU_LFB);
bogdanm 0:9b334a45a8ff 1242 ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
bogdanm 0:9b334a45a8ff 1243 _CMU_LFBPRESC0_LEUART1_SHIFT;
bogdanm 0:9b334a45a8ff 1244 } break;
bogdanm 0:9b334a45a8ff 1245 #endif
bogdanm 0:9b334a45a8ff 1246
bogdanm 0:9b334a45a8ff 1247 case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1248 {
bogdanm 0:9b334a45a8ff 1249 ret = CMU_DBGClkGet();
bogdanm 0:9b334a45a8ff 1250 } break;
bogdanm 0:9b334a45a8ff 1251
bogdanm 0:9b334a45a8ff 1252 case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1253 {
bogdanm 0:9b334a45a8ff 1254 ret = CMU_AUXClkGet();
bogdanm 0:9b334a45a8ff 1255 } break;
bogdanm 0:9b334a45a8ff 1256
bogdanm 0:9b334a45a8ff 1257 #if defined(USB_PRESENT)
bogdanm 0:9b334a45a8ff 1258 case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
bogdanm 0:9b334a45a8ff 1259 {
bogdanm 0:9b334a45a8ff 1260 ret = CMU_USBCClkGet();
bogdanm 0:9b334a45a8ff 1261 } break;
bogdanm 0:9b334a45a8ff 1262 #endif
bogdanm 0:9b334a45a8ff 1263 default:
bogdanm 0:9b334a45a8ff 1264 {
bogdanm 0:9b334a45a8ff 1265 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1266 ret = 0;
bogdanm 0:9b334a45a8ff 1267 } break;
bogdanm 0:9b334a45a8ff 1268 }
bogdanm 0:9b334a45a8ff 1269 return ret;
bogdanm 0:9b334a45a8ff 1270 }
bogdanm 0:9b334a45a8ff 1271
bogdanm 0:9b334a45a8ff 1272
bogdanm 0:9b334a45a8ff 1273 /**************************************************************************//**
bogdanm 0:9b334a45a8ff 1274 * @brief
bogdanm 0:9b334a45a8ff 1275 * Get currently selected reference clock used for a clock branch.
bogdanm 0:9b334a45a8ff 1276 *
bogdanm 0:9b334a45a8ff 1277 * @param[in] clock
bogdanm 0:9b334a45a8ff 1278 * Clock branch to fetch selected ref. clock for. One of:
bogdanm 0:9b334a45a8ff 1279 * @li #cmuClock_HF
bogdanm 0:9b334a45a8ff 1280 * @li #cmuClock_LFA
bogdanm 0:9b334a45a8ff 1281 * @li #cmuClock_LFB
bogdanm 0:9b334a45a8ff 1282 * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT
bogdanm 0:9b334a45a8ff 1283 * @li #cmuClock_USBC
bogdanm 0:9b334a45a8ff 1284 * @endif
bogdanm 0:9b334a45a8ff 1285 *
bogdanm 0:9b334a45a8ff 1286 * @return
bogdanm 0:9b334a45a8ff 1287 * Reference clock used for clocking selected branch, #cmuSelect_Error if
bogdanm 0:9b334a45a8ff 1288 * invalid @p clock provided.
bogdanm 0:9b334a45a8ff 1289 *****************************************************************************/
bogdanm 0:9b334a45a8ff 1290 CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
bogdanm 0:9b334a45a8ff 1291 {
bogdanm 0:9b334a45a8ff 1292 CMU_Select_TypeDef ret = cmuSelect_Disabled;
bogdanm 0:9b334a45a8ff 1293 uint32_t selReg;
bogdanm 0:9b334a45a8ff 1294 uint32_t statusClkSelMask;
bogdanm 0:9b334a45a8ff 1295
bogdanm 0:9b334a45a8ff 1296 statusClkSelMask =
bogdanm 0:9b334a45a8ff 1297 (CMU_STATUS_HFRCOSEL |
bogdanm 0:9b334a45a8ff 1298 CMU_STATUS_HFXOSEL |
bogdanm 0:9b334a45a8ff 1299 CMU_STATUS_LFRCOSEL |
bogdanm 0:9b334a45a8ff 1300 #if defined( CMU_STATUS_USHFRCODIV2SEL )
bogdanm 0:9b334a45a8ff 1301 CMU_STATUS_USHFRCODIV2SEL |
bogdanm 0:9b334a45a8ff 1302 #endif
bogdanm 0:9b334a45a8ff 1303 CMU_STATUS_LFXOSEL);
bogdanm 0:9b334a45a8ff 1304
bogdanm 0:9b334a45a8ff 1305 selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
bogdanm 0:9b334a45a8ff 1306
bogdanm 0:9b334a45a8ff 1307 switch (selReg)
bogdanm 0:9b334a45a8ff 1308 {
bogdanm 0:9b334a45a8ff 1309 case CMU_HFCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1310 switch (CMU->STATUS & statusClkSelMask)
bogdanm 0:9b334a45a8ff 1311 {
bogdanm 0:9b334a45a8ff 1312 case CMU_STATUS_LFXOSEL:
bogdanm 0:9b334a45a8ff 1313 ret = cmuSelect_LFXO;
bogdanm 0:9b334a45a8ff 1314 break;
bogdanm 0:9b334a45a8ff 1315
bogdanm 0:9b334a45a8ff 1316 case CMU_STATUS_LFRCOSEL:
bogdanm 0:9b334a45a8ff 1317 ret = cmuSelect_LFRCO;
bogdanm 0:9b334a45a8ff 1318 break;
bogdanm 0:9b334a45a8ff 1319
bogdanm 0:9b334a45a8ff 1320 case CMU_STATUS_HFXOSEL:
bogdanm 0:9b334a45a8ff 1321 ret = cmuSelect_HFXO;
bogdanm 0:9b334a45a8ff 1322 break;
bogdanm 0:9b334a45a8ff 1323
bogdanm 0:9b334a45a8ff 1324 #if defined( CMU_STATUS_USHFRCODIV2SEL )
bogdanm 0:9b334a45a8ff 1325 case CMU_STATUS_USHFRCODIV2SEL:
bogdanm 0:9b334a45a8ff 1326 ret = cmuSelect_USHFRCODIV2;
bogdanm 0:9b334a45a8ff 1327 break;
bogdanm 0:9b334a45a8ff 1328 #endif
bogdanm 0:9b334a45a8ff 1329
bogdanm 0:9b334a45a8ff 1330 default:
bogdanm 0:9b334a45a8ff 1331 ret = cmuSelect_HFRCO;
bogdanm 0:9b334a45a8ff 1332 break;
bogdanm 0:9b334a45a8ff 1333 }
bogdanm 0:9b334a45a8ff 1334 break;
bogdanm 0:9b334a45a8ff 1335
bogdanm 0:9b334a45a8ff 1336 case CMU_LFACLKSEL_REG:
bogdanm 0:9b334a45a8ff 1337 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)
bogdanm 0:9b334a45a8ff 1338 {
bogdanm 0:9b334a45a8ff 1339 case CMU_LFCLKSEL_LFA_LFRCO:
bogdanm 0:9b334a45a8ff 1340 ret = cmuSelect_LFRCO;
bogdanm 0:9b334a45a8ff 1341 break;
bogdanm 0:9b334a45a8ff 1342
bogdanm 0:9b334a45a8ff 1343 case CMU_LFCLKSEL_LFA_LFXO:
bogdanm 0:9b334a45a8ff 1344 ret = cmuSelect_LFXO;
bogdanm 0:9b334a45a8ff 1345 break;
bogdanm 0:9b334a45a8ff 1346
bogdanm 0:9b334a45a8ff 1347 case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
bogdanm 0:9b334a45a8ff 1348 ret = cmuSelect_CORELEDIV2;
bogdanm 0:9b334a45a8ff 1349 break;
bogdanm 0:9b334a45a8ff 1350
bogdanm 0:9b334a45a8ff 1351 default:
bogdanm 0:9b334a45a8ff 1352 #if defined( CMU_LFCLKSEL_LFAE )
bogdanm 0:9b334a45a8ff 1353 if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)
bogdanm 0:9b334a45a8ff 1354 {
bogdanm 0:9b334a45a8ff 1355 ret = cmuSelect_ULFRCO;
bogdanm 0:9b334a45a8ff 1356 break;
bogdanm 0:9b334a45a8ff 1357 }
bogdanm 0:9b334a45a8ff 1358 #else
bogdanm 0:9b334a45a8ff 1359 ret = cmuSelect_Disabled;
bogdanm 0:9b334a45a8ff 1360 #endif
bogdanm 0:9b334a45a8ff 1361 break;
bogdanm 0:9b334a45a8ff 1362 }
bogdanm 0:9b334a45a8ff 1363 break;
bogdanm 0:9b334a45a8ff 1364
bogdanm 0:9b334a45a8ff 1365 case CMU_LFBCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1366 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)
bogdanm 0:9b334a45a8ff 1367 {
bogdanm 0:9b334a45a8ff 1368 case CMU_LFCLKSEL_LFB_LFRCO:
bogdanm 0:9b334a45a8ff 1369 ret = cmuSelect_LFRCO;
bogdanm 0:9b334a45a8ff 1370 break;
bogdanm 0:9b334a45a8ff 1371
bogdanm 0:9b334a45a8ff 1372 case CMU_LFCLKSEL_LFB_LFXO:
bogdanm 0:9b334a45a8ff 1373 ret = cmuSelect_LFXO;
bogdanm 0:9b334a45a8ff 1374 break;
bogdanm 0:9b334a45a8ff 1375
bogdanm 0:9b334a45a8ff 1376 case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
bogdanm 0:9b334a45a8ff 1377 ret = cmuSelect_CORELEDIV2;
bogdanm 0:9b334a45a8ff 1378 break;
bogdanm 0:9b334a45a8ff 1379
bogdanm 0:9b334a45a8ff 1380 default:
bogdanm 0:9b334a45a8ff 1381 #if defined( CMU_LFCLKSEL_LFBE )
bogdanm 0:9b334a45a8ff 1382 if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)
bogdanm 0:9b334a45a8ff 1383 {
bogdanm 0:9b334a45a8ff 1384 ret = cmuSelect_ULFRCO;
bogdanm 0:9b334a45a8ff 1385 break;
bogdanm 0:9b334a45a8ff 1386 }
bogdanm 0:9b334a45a8ff 1387 #else
bogdanm 0:9b334a45a8ff 1388 ret = cmuSelect_Disabled;
bogdanm 0:9b334a45a8ff 1389 #endif
bogdanm 0:9b334a45a8ff 1390 break;
bogdanm 0:9b334a45a8ff 1391 }
bogdanm 0:9b334a45a8ff 1392 break;
bogdanm 0:9b334a45a8ff 1393
bogdanm 0:9b334a45a8ff 1394 #if defined( _CMU_LFCLKSEL_LFC_MASK )
bogdanm 0:9b334a45a8ff 1395 case CMU_LFCCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1396 switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)
bogdanm 0:9b334a45a8ff 1397 {
bogdanm 0:9b334a45a8ff 1398 case CMU_LFCLKSEL_LFC_LFRCO:
bogdanm 0:9b334a45a8ff 1399 ret = cmuSelect_LFRCO;
bogdanm 0:9b334a45a8ff 1400 break;
bogdanm 0:9b334a45a8ff 1401
bogdanm 0:9b334a45a8ff 1402 case CMU_LFCLKSEL_LFC_LFXO:
bogdanm 0:9b334a45a8ff 1403 ret = cmuSelect_LFXO;
bogdanm 0:9b334a45a8ff 1404 break;
bogdanm 0:9b334a45a8ff 1405
bogdanm 0:9b334a45a8ff 1406 default:
bogdanm 0:9b334a45a8ff 1407 ret = cmuSelect_Disabled;
bogdanm 0:9b334a45a8ff 1408 break;
bogdanm 0:9b334a45a8ff 1409 }
bogdanm 0:9b334a45a8ff 1410 break;
bogdanm 0:9b334a45a8ff 1411 #endif
bogdanm 0:9b334a45a8ff 1412
bogdanm 0:9b334a45a8ff 1413 case CMU_DBGCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1414
bogdanm 0:9b334a45a8ff 1415 #if defined( _CMU_DBGCLKSEL_DBG_MASK )
bogdanm 0:9b334a45a8ff 1416 switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)
bogdanm 0:9b334a45a8ff 1417 {
bogdanm 0:9b334a45a8ff 1418 case CMU_DBGCLKSEL_DBG_HFCLK:
bogdanm 0:9b334a45a8ff 1419 ret = cmuSelect_HFCLK;
bogdanm 0:9b334a45a8ff 1420 break;
bogdanm 0:9b334a45a8ff 1421
bogdanm 0:9b334a45a8ff 1422 case CMU_DBGCLKSEL_DBG_AUXHFRCO:
bogdanm 0:9b334a45a8ff 1423 ret = cmuSelect_AUXHFRCO;
bogdanm 0:9b334a45a8ff 1424 break;
bogdanm 0:9b334a45a8ff 1425 }
bogdanm 0:9b334a45a8ff 1426 #else
bogdanm 0:9b334a45a8ff 1427 ret = cmuSelect_AUXHFRCO;
bogdanm 0:9b334a45a8ff 1428 #endif /* CMU_DBGCLKSEL_DBG */
bogdanm 0:9b334a45a8ff 1429
bogdanm 0:9b334a45a8ff 1430 #if defined( _CMU_CTRL_DBGCLK_MASK )
bogdanm 0:9b334a45a8ff 1431 switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)
bogdanm 0:9b334a45a8ff 1432 {
bogdanm 0:9b334a45a8ff 1433 case CMU_CTRL_DBGCLK_AUXHFRCO:
bogdanm 0:9b334a45a8ff 1434 ret = cmuSelect_AUXHFRCO;
bogdanm 0:9b334a45a8ff 1435 break;
bogdanm 0:9b334a45a8ff 1436
bogdanm 0:9b334a45a8ff 1437 case CMU_CTRL_DBGCLK_HFCLK:
bogdanm 0:9b334a45a8ff 1438 ret = cmuSelect_HFCLK;
bogdanm 0:9b334a45a8ff 1439 break;
bogdanm 0:9b334a45a8ff 1440 }
bogdanm 0:9b334a45a8ff 1441 #else
bogdanm 0:9b334a45a8ff 1442 ret = cmuSelect_AUXHFRCO;
bogdanm 0:9b334a45a8ff 1443 #endif
bogdanm 0:9b334a45a8ff 1444 break;
bogdanm 0:9b334a45a8ff 1445
bogdanm 0:9b334a45a8ff 1446
bogdanm 0:9b334a45a8ff 1447 #if defined(USB_PRESENT)
bogdanm 0:9b334a45a8ff 1448
bogdanm 0:9b334a45a8ff 1449 case CMU_USBCCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1450 switch(CMU->STATUS &
bogdanm 0:9b334a45a8ff 1451 (CMU_STATUS_USBCLFXOSEL |
bogdanm 0:9b334a45a8ff 1452 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
bogdanm 0:9b334a45a8ff 1453 CMU_STATUS_USBCHFCLKSEL |
bogdanm 0:9b334a45a8ff 1454 #endif
bogdanm 0:9b334a45a8ff 1455 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
bogdanm 0:9b334a45a8ff 1456 CMU_STATUS_USBCUSHFRCOSEL |
bogdanm 0:9b334a45a8ff 1457 #endif
bogdanm 0:9b334a45a8ff 1458 CMU_STATUS_USBCLFRCOSEL))
bogdanm 0:9b334a45a8ff 1459 {
bogdanm 0:9b334a45a8ff 1460
bogdanm 0:9b334a45a8ff 1461 case CMU_STATUS_USBCLFXOSEL:
bogdanm 0:9b334a45a8ff 1462 ret = cmuSelect_LFXO;
bogdanm 0:9b334a45a8ff 1463 break;
bogdanm 0:9b334a45a8ff 1464
bogdanm 0:9b334a45a8ff 1465 case CMU_STATUS_USBCLFRCOSEL:
bogdanm 0:9b334a45a8ff 1466 ret = cmuSelect_LFRCO;
bogdanm 0:9b334a45a8ff 1467 break;
bogdanm 0:9b334a45a8ff 1468
bogdanm 0:9b334a45a8ff 1469 #if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)
bogdanm 0:9b334a45a8ff 1470 case CMU_STATUS_USBCHFCLKSEL:
bogdanm 0:9b334a45a8ff 1471 ret = cmuSelect_HFCLK;
bogdanm 0:9b334a45a8ff 1472 break;
bogdanm 0:9b334a45a8ff 1473 #endif
bogdanm 0:9b334a45a8ff 1474
bogdanm 0:9b334a45a8ff 1475 #if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)
bogdanm 0:9b334a45a8ff 1476 case CMU_STATUS_USBCUSHFRCOSEL:
bogdanm 0:9b334a45a8ff 1477 ret = cmuSelect_USHFRCO;
bogdanm 0:9b334a45a8ff 1478 break;
bogdanm 0:9b334a45a8ff 1479 #endif
bogdanm 0:9b334a45a8ff 1480
bogdanm 0:9b334a45a8ff 1481 default:
bogdanm 0:9b334a45a8ff 1482 ret = cmuSelect_Disabled;
bogdanm 0:9b334a45a8ff 1483 break;
bogdanm 0:9b334a45a8ff 1484 }
bogdanm 0:9b334a45a8ff 1485 break;
bogdanm 0:9b334a45a8ff 1486 #endif
bogdanm 0:9b334a45a8ff 1487
bogdanm 0:9b334a45a8ff 1488 default:
bogdanm 0:9b334a45a8ff 1489 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1490 ret = cmuSelect_Error;
bogdanm 0:9b334a45a8ff 1491 break;
bogdanm 0:9b334a45a8ff 1492 }
bogdanm 0:9b334a45a8ff 1493
bogdanm 0:9b334a45a8ff 1494 return ret;
bogdanm 0:9b334a45a8ff 1495 }
bogdanm 0:9b334a45a8ff 1496
bogdanm 0:9b334a45a8ff 1497
bogdanm 0:9b334a45a8ff 1498 /**************************************************************************//**
bogdanm 0:9b334a45a8ff 1499 * @brief
bogdanm 0:9b334a45a8ff 1500 * Select reference clock/oscillator used for a clock branch.
bogdanm 0:9b334a45a8ff 1501 *
bogdanm 0:9b334a45a8ff 1502 * @details
bogdanm 0:9b334a45a8ff 1503 * Notice that if a selected reference is not enabled prior to selecting its
bogdanm 0:9b334a45a8ff 1504 * use, it will be enabled, and this function will wait for the selected
bogdanm 0:9b334a45a8ff 1505 * oscillator to be stable. It will however NOT be disabled if another
bogdanm 0:9b334a45a8ff 1506 * reference clock is selected later.
bogdanm 0:9b334a45a8ff 1507 *
bogdanm 0:9b334a45a8ff 1508 * This feature is particularly important if selecting a new reference
bogdanm 0:9b334a45a8ff 1509 * clock for the clock branch clocking the core, otherwise the system
bogdanm 0:9b334a45a8ff 1510 * may halt.
bogdanm 0:9b334a45a8ff 1511 *
bogdanm 0:9b334a45a8ff 1512 * @param[in] clock
bogdanm 0:9b334a45a8ff 1513 * Clock branch to select reference clock for. One of:
bogdanm 0:9b334a45a8ff 1514 * @li #cmuClock_HF
bogdanm 0:9b334a45a8ff 1515 * @li #cmuClock_LFA
bogdanm 0:9b334a45a8ff 1516 * @li #cmuClock_LFB
bogdanm 0:9b334a45a8ff 1517 * @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT
bogdanm 0:9b334a45a8ff 1518 * @li #cmuClock_USBC
bogdanm 0:9b334a45a8ff 1519 * @endif
bogdanm 0:9b334a45a8ff 1520 *
bogdanm 0:9b334a45a8ff 1521 * @param[in] ref
bogdanm 0:9b334a45a8ff 1522 * Reference selected for clocking, please refer to reference manual for
bogdanm 0:9b334a45a8ff 1523 * for details on which reference is available for a specific clock branch.
bogdanm 0:9b334a45a8ff 1524 * @li #cmuSelect_HFRCO
bogdanm 0:9b334a45a8ff 1525 * @li #cmuSelect_LFRCO
bogdanm 0:9b334a45a8ff 1526 * @li #cmuSelect_HFXO
bogdanm 0:9b334a45a8ff 1527 * @li #cmuSelect_LFXO
bogdanm 0:9b334a45a8ff 1528 * @li #cmuSelect_CORELEDIV2
bogdanm 0:9b334a45a8ff 1529 * @li #cmuSelect_AUXHFRCO
bogdanm 0:9b334a45a8ff 1530 * @li #cmuSelect_HFCLK @ifnot DOXYDOC_EFM32_GECKO_FAMILY
bogdanm 0:9b334a45a8ff 1531 * @li #cmuSelect_ULFRCO
bogdanm 0:9b334a45a8ff 1532 * @endif
bogdanm 0:9b334a45a8ff 1533 *****************************************************************************/
bogdanm 0:9b334a45a8ff 1534 void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
bogdanm 0:9b334a45a8ff 1535 {
bogdanm 0:9b334a45a8ff 1536 uint32_t select = cmuOsc_HFRCO;
bogdanm 0:9b334a45a8ff 1537 CMU_Osc_TypeDef osc = cmuOsc_HFRCO;
bogdanm 0:9b334a45a8ff 1538 uint32_t freq;
bogdanm 0:9b334a45a8ff 1539 uint32_t selReg;
bogdanm 0:9b334a45a8ff 1540 #if !defined(_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 1541 uint32_t lfExtended = 0;
bogdanm 0:9b334a45a8ff 1542 #endif
bogdanm 0:9b334a45a8ff 1543 uint32_t tmp;
bogdanm 0:9b334a45a8ff 1544
bogdanm 0:9b334a45a8ff 1545 selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
bogdanm 0:9b334a45a8ff 1546
bogdanm 0:9b334a45a8ff 1547 switch (selReg)
bogdanm 0:9b334a45a8ff 1548 {
bogdanm 0:9b334a45a8ff 1549 case CMU_HFCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1550 switch (ref)
bogdanm 0:9b334a45a8ff 1551 {
bogdanm 0:9b334a45a8ff 1552 case cmuSelect_LFXO:
bogdanm 0:9b334a45a8ff 1553 select = CMU_CMD_HFCLKSEL_LFXO;
bogdanm 0:9b334a45a8ff 1554 osc = cmuOsc_LFXO;
bogdanm 0:9b334a45a8ff 1555 break;
bogdanm 0:9b334a45a8ff 1556
bogdanm 0:9b334a45a8ff 1557 case cmuSelect_LFRCO:
bogdanm 0:9b334a45a8ff 1558 select = CMU_CMD_HFCLKSEL_LFRCO;
bogdanm 0:9b334a45a8ff 1559 osc = cmuOsc_LFRCO;
bogdanm 0:9b334a45a8ff 1560 break;
bogdanm 0:9b334a45a8ff 1561
bogdanm 0:9b334a45a8ff 1562 case cmuSelect_HFXO:
bogdanm 0:9b334a45a8ff 1563 select = CMU_CMD_HFCLKSEL_HFXO;
bogdanm 0:9b334a45a8ff 1564 osc = cmuOsc_HFXO;
bogdanm 0:9b334a45a8ff 1565 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 1566 /* Adjust HFXO buffer current for high frequencies, enable HFLE for */
bogdanm 0:9b334a45a8ff 1567 /* frequencies above CMU_MAX_FREQ_HFLE. */
bogdanm 0:9b334a45a8ff 1568 if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE)
bogdanm 0:9b334a45a8ff 1569 {
bogdanm 0:9b334a45a8ff 1570 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
bogdanm 0:9b334a45a8ff 1571 CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ |
bogdanm 0:9b334a45a8ff 1572 /* Must have HFLE enabled to access some LE peripherals >=32MHz */
bogdanm 0:9b334a45a8ff 1573 CMU_CTRL_HFLE;
bogdanm 0:9b334a45a8ff 1574
bogdanm 0:9b334a45a8ff 1575 /* Set HFLE and DIV4 factor for peripheral clock if HFCORE clock for
bogdanm 0:9b334a45a8ff 1576 LE is enabled. */
bogdanm 0:9b334a45a8ff 1577 if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)
bogdanm 0:9b334a45a8ff 1578 {
bogdanm 0:9b334a45a8ff 1579 BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
bogdanm 0:9b334a45a8ff 1580 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1581 }
bogdanm 0:9b334a45a8ff 1582 } else {
bogdanm 0:9b334a45a8ff 1583 /* This can happen if the user configures the EFM32_HFXO_FREQ to */
bogdanm 0:9b334a45a8ff 1584 /* use another oscillator frequency */
bogdanm 0:9b334a45a8ff 1585 CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
bogdanm 0:9b334a45a8ff 1586 CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;
bogdanm 0:9b334a45a8ff 1587 }
bogdanm 0:9b334a45a8ff 1588 #endif
bogdanm 0:9b334a45a8ff 1589 break;
bogdanm 0:9b334a45a8ff 1590
bogdanm 0:9b334a45a8ff 1591 case cmuSelect_HFRCO:
bogdanm 0:9b334a45a8ff 1592 select = CMU_CMD_HFCLKSEL_HFRCO;
bogdanm 0:9b334a45a8ff 1593 osc = cmuOsc_HFRCO;
bogdanm 0:9b334a45a8ff 1594 break;
bogdanm 0:9b334a45a8ff 1595
bogdanm 0:9b334a45a8ff 1596 #if defined( CMU_CMD_HFCLKSEL_USHFRCODIV2 )
bogdanm 0:9b334a45a8ff 1597 case cmuSelect_USHFRCODIV2:
bogdanm 0:9b334a45a8ff 1598 select = CMU_CMD_HFCLKSEL_USHFRCODIV2;
bogdanm 0:9b334a45a8ff 1599 osc = cmuOsc_USHFRCO;
bogdanm 0:9b334a45a8ff 1600 break;
bogdanm 0:9b334a45a8ff 1601 #endif
bogdanm 0:9b334a45a8ff 1602
bogdanm 0:9b334a45a8ff 1603 #if !defined( _EFM32_GECKO_FAMILY )
bogdanm 0:9b334a45a8ff 1604 case cmuSelect_ULFRCO:
bogdanm 0:9b334a45a8ff 1605 /* ULFRCO cannot be used as HFCLK */
bogdanm 0:9b334a45a8ff 1606 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1607 break;
bogdanm 0:9b334a45a8ff 1608 #endif
bogdanm 0:9b334a45a8ff 1609
bogdanm 0:9b334a45a8ff 1610 default:
bogdanm 0:9b334a45a8ff 1611 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1612 return;
bogdanm 0:9b334a45a8ff 1613 }
bogdanm 0:9b334a45a8ff 1614
bogdanm 0:9b334a45a8ff 1615 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1616 CMU_OscillatorEnable(osc, true, true);
bogdanm 0:9b334a45a8ff 1617
bogdanm 0:9b334a45a8ff 1618 /* Configure worst case wait states for flash access before selecting */
bogdanm 0:9b334a45a8ff 1619 CMU_FlashWaitStateMax();
bogdanm 0:9b334a45a8ff 1620
bogdanm 0:9b334a45a8ff 1621 /* Switch to selected oscillator */
bogdanm 0:9b334a45a8ff 1622 CMU->CMD = select;
bogdanm 0:9b334a45a8ff 1623
bogdanm 0:9b334a45a8ff 1624 /* Keep EMU module informed */
bogdanm 0:9b334a45a8ff 1625 EMU_UpdateOscConfig();
bogdanm 0:9b334a45a8ff 1626
bogdanm 0:9b334a45a8ff 1627 /* Update CMSIS core clock variable */
bogdanm 0:9b334a45a8ff 1628 /* (The function will update the global variable) */
bogdanm 0:9b334a45a8ff 1629 freq = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 1630
bogdanm 0:9b334a45a8ff 1631 /* Optimize flash access wait state setting for currently selected core clk */
bogdanm 0:9b334a45a8ff 1632 CMU_FlashWaitStateControl(freq);
bogdanm 0:9b334a45a8ff 1633 break;
bogdanm 0:9b334a45a8ff 1634
bogdanm 0:9b334a45a8ff 1635 case CMU_LFACLKSEL_REG:
bogdanm 0:9b334a45a8ff 1636 case CMU_LFBCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1637
bogdanm 0:9b334a45a8ff 1638 switch (ref)
bogdanm 0:9b334a45a8ff 1639 {
bogdanm 0:9b334a45a8ff 1640 case cmuSelect_Disabled:
bogdanm 0:9b334a45a8ff 1641 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
bogdanm 0:9b334a45a8ff 1642 break;
bogdanm 0:9b334a45a8ff 1643
bogdanm 0:9b334a45a8ff 1644 case cmuSelect_LFXO:
bogdanm 0:9b334a45a8ff 1645 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1646 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
bogdanm 0:9b334a45a8ff 1647 tmp = _CMU_LFCLKSEL_LFA_LFXO;
bogdanm 0:9b334a45a8ff 1648 break;
bogdanm 0:9b334a45a8ff 1649
bogdanm 0:9b334a45a8ff 1650 case cmuSelect_LFRCO:
bogdanm 0:9b334a45a8ff 1651 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1652 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
bogdanm 0:9b334a45a8ff 1653 tmp = _CMU_LFCLKSEL_LFA_LFRCO;
bogdanm 0:9b334a45a8ff 1654 break;
bogdanm 0:9b334a45a8ff 1655
bogdanm 0:9b334a45a8ff 1656 case cmuSelect_CORELEDIV2:
bogdanm 0:9b334a45a8ff 1657 /* Ensure HFCORE to LE clocking is enabled */
bogdanm 0:9b334a45a8ff 1658 BITBAND_Peripheral(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1659 tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
bogdanm 0:9b334a45a8ff 1660 #if defined( CMU_CTRL_HFLE )
bogdanm 0:9b334a45a8ff 1661 /* If core frequency is higher than CMU_MAX_FREQ_HFLE on
bogdanm 0:9b334a45a8ff 1662 Giant/Leopard/Wonder, enable HFLE and DIV4. */
bogdanm 0:9b334a45a8ff 1663 freq = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 1664 if(freq > CMU_MAX_FREQ_HFLE)
bogdanm 0:9b334a45a8ff 1665 {
bogdanm 0:9b334a45a8ff 1666 /* Enable CMU HFLE */
bogdanm 0:9b334a45a8ff 1667 BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1668
bogdanm 0:9b334a45a8ff 1669 /* Enable DIV4 factor for peripheral clock */
bogdanm 0:9b334a45a8ff 1670 BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
bogdanm 0:9b334a45a8ff 1671 _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
bogdanm 0:9b334a45a8ff 1672 }
bogdanm 0:9b334a45a8ff 1673 #endif
bogdanm 0:9b334a45a8ff 1674 break;
bogdanm 0:9b334a45a8ff 1675
bogdanm 0:9b334a45a8ff 1676 #if !defined(_EFM32_GECKO_FAMILY)
bogdanm 0:9b334a45a8ff 1677 case cmuSelect_ULFRCO:
bogdanm 0:9b334a45a8ff 1678 /* ULFRCO is always enabled */
bogdanm 0:9b334a45a8ff 1679 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
bogdanm 0:9b334a45a8ff 1680 lfExtended = 1;
bogdanm 0:9b334a45a8ff 1681 break;
bogdanm 0:9b334a45a8ff 1682 #endif
bogdanm 0:9b334a45a8ff 1683
bogdanm 0:9b334a45a8ff 1684 default:
bogdanm 0:9b334a45a8ff 1685 /* Illegal clock source for LFA/LFB selected */
bogdanm 0:9b334a45a8ff 1686 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1687 return;
bogdanm 0:9b334a45a8ff 1688 }
bogdanm 0:9b334a45a8ff 1689
bogdanm 0:9b334a45a8ff 1690 /* Apply select */
bogdanm 0:9b334a45a8ff 1691 if (selReg == CMU_LFACLKSEL_REG)
bogdanm 0:9b334a45a8ff 1692 {
bogdanm 0:9b334a45a8ff 1693 #if !defined( _EFM32_GECKO_FAMILY )
bogdanm 0:9b334a45a8ff 1694 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK) ) |
bogdanm 0:9b334a45a8ff 1695 (tmp << _CMU_LFCLKSEL_LFA_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);
bogdanm 0:9b334a45a8ff 1696 #else
bogdanm 0:9b334a45a8ff 1697 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK) |
bogdanm 0:9b334a45a8ff 1698 (tmp << _CMU_LFCLKSEL_LFA_SHIFT);
bogdanm 0:9b334a45a8ff 1699 #endif
bogdanm 0:9b334a45a8ff 1700 }
bogdanm 0:9b334a45a8ff 1701 else
bogdanm 0:9b334a45a8ff 1702 {
bogdanm 0:9b334a45a8ff 1703 #if !defined( _EFM32_GECKO_FAMILY )
bogdanm 0:9b334a45a8ff 1704 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK) ) |
bogdanm 0:9b334a45a8ff 1705 (tmp << _CMU_LFCLKSEL_LFB_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);
bogdanm 0:9b334a45a8ff 1706 #else
bogdanm 0:9b334a45a8ff 1707 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK) |
bogdanm 0:9b334a45a8ff 1708 (tmp << _CMU_LFCLKSEL_LFB_SHIFT);
bogdanm 0:9b334a45a8ff 1709 #endif
bogdanm 0:9b334a45a8ff 1710 }
bogdanm 0:9b334a45a8ff 1711 break;
bogdanm 0:9b334a45a8ff 1712
bogdanm 0:9b334a45a8ff 1713 #if defined( _CMU_LFCLKSEL_LFC_MASK )
bogdanm 0:9b334a45a8ff 1714 case CMU_LFCCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1715 switch(ref)
bogdanm 0:9b334a45a8ff 1716 {
bogdanm 0:9b334a45a8ff 1717 case cmuSelect_Disabled:
bogdanm 0:9b334a45a8ff 1718 tmp = _CMU_LFCLKSEL_LFA_DISABLED;
bogdanm 0:9b334a45a8ff 1719 break;
bogdanm 0:9b334a45a8ff 1720
bogdanm 0:9b334a45a8ff 1721 case cmuSelect_LFXO:
bogdanm 0:9b334a45a8ff 1722 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1723 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
bogdanm 0:9b334a45a8ff 1724 tmp = _CMU_LFCLKSEL_LFC_LFXO;
bogdanm 0:9b334a45a8ff 1725 break;
bogdanm 0:9b334a45a8ff 1726
bogdanm 0:9b334a45a8ff 1727 case cmuSelect_LFRCO:
bogdanm 0:9b334a45a8ff 1728 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1729 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
bogdanm 0:9b334a45a8ff 1730 tmp = _CMU_LFCLKSEL_LFC_LFRCO;
bogdanm 0:9b334a45a8ff 1731 break;
bogdanm 0:9b334a45a8ff 1732
bogdanm 0:9b334a45a8ff 1733 default:
bogdanm 0:9b334a45a8ff 1734 /* Illegal clock source for LFC selected */
bogdanm 0:9b334a45a8ff 1735 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1736 return;
bogdanm 0:9b334a45a8ff 1737 }
bogdanm 0:9b334a45a8ff 1738
bogdanm 0:9b334a45a8ff 1739 /* Apply select */
bogdanm 0:9b334a45a8ff 1740 CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK) |
bogdanm 0:9b334a45a8ff 1741 (tmp << _CMU_LFCLKSEL_LFC_SHIFT);
bogdanm 0:9b334a45a8ff 1742 break;
bogdanm 0:9b334a45a8ff 1743 #endif
bogdanm 0:9b334a45a8ff 1744
bogdanm 0:9b334a45a8ff 1745 #if defined( CMU_CTRL_DBGCLK )
bogdanm 0:9b334a45a8ff 1746 case CMU_DBGCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1747 switch(ref)
bogdanm 0:9b334a45a8ff 1748 {
bogdanm 0:9b334a45a8ff 1749 case cmuSelect_AUXHFRCO:
bogdanm 0:9b334a45a8ff 1750 /* Select AUXHFRCO as debug clock */
bogdanm 0:9b334a45a8ff 1751 CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_AUXHFRCO;
bogdanm 0:9b334a45a8ff 1752 break;
bogdanm 0:9b334a45a8ff 1753
bogdanm 0:9b334a45a8ff 1754 case cmuSelect_HFCLK:
bogdanm 0:9b334a45a8ff 1755 /* Select divided HFCLK as debug clock */
bogdanm 0:9b334a45a8ff 1756 CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_HFCLK;
bogdanm 0:9b334a45a8ff 1757 break;
bogdanm 0:9b334a45a8ff 1758
bogdanm 0:9b334a45a8ff 1759 default:
bogdanm 0:9b334a45a8ff 1760 /* Illegal clock source for debug selected */
bogdanm 0:9b334a45a8ff 1761 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1762 return;
bogdanm 0:9b334a45a8ff 1763 }
bogdanm 0:9b334a45a8ff 1764 break;
bogdanm 0:9b334a45a8ff 1765 #endif
bogdanm 0:9b334a45a8ff 1766
bogdanm 0:9b334a45a8ff 1767 #if defined(USB_PRESENT)
bogdanm 0:9b334a45a8ff 1768 case CMU_USBCCLKSEL_REG:
bogdanm 0:9b334a45a8ff 1769 switch(ref)
bogdanm 0:9b334a45a8ff 1770 {
bogdanm 0:9b334a45a8ff 1771 case cmuSelect_LFXO:
bogdanm 0:9b334a45a8ff 1772 /* Select LFXO as clock source for USB, can only be used in sleep mode */
bogdanm 0:9b334a45a8ff 1773
bogdanm 0:9b334a45a8ff 1774 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1775 CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
bogdanm 0:9b334a45a8ff 1776
bogdanm 0:9b334a45a8ff 1777 /* Switch oscillator */
bogdanm 0:9b334a45a8ff 1778 CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
bogdanm 0:9b334a45a8ff 1779
bogdanm 0:9b334a45a8ff 1780 /* Wait until clock is activated */
bogdanm 0:9b334a45a8ff 1781 while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0);
bogdanm 0:9b334a45a8ff 1782 break;
bogdanm 0:9b334a45a8ff 1783
bogdanm 0:9b334a45a8ff 1784 case cmuSelect_LFRCO:
bogdanm 0:9b334a45a8ff 1785 /* Select LFRCO as clock source for USB, can only be used in sleep mode */
bogdanm 0:9b334a45a8ff 1786
bogdanm 0:9b334a45a8ff 1787 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1788 CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
bogdanm 0:9b334a45a8ff 1789
bogdanm 0:9b334a45a8ff 1790 /* Switch oscillator */
bogdanm 0:9b334a45a8ff 1791 CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
bogdanm 0:9b334a45a8ff 1792
bogdanm 0:9b334a45a8ff 1793 /* Wait until clock is activated */
bogdanm 0:9b334a45a8ff 1794 while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0);
bogdanm 0:9b334a45a8ff 1795 break;
bogdanm 0:9b334a45a8ff 1796
bogdanm 0:9b334a45a8ff 1797 #if defined( CMU_STATUS_USBCHFCLKSEL )
bogdanm 0:9b334a45a8ff 1798 case cmuSelect_HFCLK:
bogdanm 0:9b334a45a8ff 1799 /* Select undivided HFCLK as clock source for USB */
bogdanm 0:9b334a45a8ff 1800
bogdanm 0:9b334a45a8ff 1801 /* Oscillator must already be enabled to avoid a core lockup */
bogdanm 0:9b334a45a8ff 1802 CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
bogdanm 0:9b334a45a8ff 1803 /* Wait until clock is activated */
bogdanm 0:9b334a45a8ff 1804 while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0);
bogdanm 0:9b334a45a8ff 1805 break;
bogdanm 0:9b334a45a8ff 1806 #endif
bogdanm 0:9b334a45a8ff 1807
bogdanm 0:9b334a45a8ff 1808 #if defined( CMU_CMD_USBCCLKSEL_USHFRCO )
bogdanm 0:9b334a45a8ff 1809 case cmuSelect_USHFRCO:
bogdanm 0:9b334a45a8ff 1810 /* Select USHFRCO as clock source for USB */
bogdanm 0:9b334a45a8ff 1811
bogdanm 0:9b334a45a8ff 1812 /* Ensure selected oscillator is enabled, waiting for it to stabilize */
bogdanm 0:9b334a45a8ff 1813 CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);
bogdanm 0:9b334a45a8ff 1814
bogdanm 0:9b334a45a8ff 1815 /* Switch oscillator */
bogdanm 0:9b334a45a8ff 1816 CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
bogdanm 0:9b334a45a8ff 1817
bogdanm 0:9b334a45a8ff 1818 /* Wait until clock is activated */
bogdanm 0:9b334a45a8ff 1819 while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0);
bogdanm 0:9b334a45a8ff 1820 break;
bogdanm 0:9b334a45a8ff 1821 #endif
bogdanm 0:9b334a45a8ff 1822
bogdanm 0:9b334a45a8ff 1823 default:
bogdanm 0:9b334a45a8ff 1824 /* Illegal clock source for USB */
bogdanm 0:9b334a45a8ff 1825 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1826 return;
bogdanm 0:9b334a45a8ff 1827 }
bogdanm 0:9b334a45a8ff 1828 /* Wait until clock has been activated */
bogdanm 0:9b334a45a8ff 1829 break;
bogdanm 0:9b334a45a8ff 1830 #endif
bogdanm 0:9b334a45a8ff 1831
bogdanm 0:9b334a45a8ff 1832 default:
bogdanm 0:9b334a45a8ff 1833 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1834 break;
bogdanm 0:9b334a45a8ff 1835 }
bogdanm 0:9b334a45a8ff 1836 }
bogdanm 0:9b334a45a8ff 1837
bogdanm 0:9b334a45a8ff 1838
bogdanm 0:9b334a45a8ff 1839 /**************************************************************************//**
bogdanm 0:9b334a45a8ff 1840 * @brief
bogdanm 0:9b334a45a8ff 1841 * CMU low frequency register synchronization freeze control.
bogdanm 0:9b334a45a8ff 1842 *
bogdanm 0:9b334a45a8ff 1843 * @details
bogdanm 0:9b334a45a8ff 1844 * Some CMU registers requires synchronization into the low frequency (LF)
bogdanm 0:9b334a45a8ff 1845 * domain. The freeze feature allows for several such registers to be
bogdanm 0:9b334a45a8ff 1846 * modified before passing them to the LF domain simultaneously (which
bogdanm 0:9b334a45a8ff 1847 * takes place when the freeze mode is disabled).
bogdanm 0:9b334a45a8ff 1848 *
bogdanm 0:9b334a45a8ff 1849 * Another usage scenario of this feature, is when using an API (such
bogdanm 0:9b334a45a8ff 1850 * as the CMU API) for modifying several bit fields consecutively in the
bogdanm 0:9b334a45a8ff 1851 * same register. If freeze mode is enabled during this sequence, stalling
bogdanm 0:9b334a45a8ff 1852 * can be avoided.
bogdanm 0:9b334a45a8ff 1853 *
bogdanm 0:9b334a45a8ff 1854 * @note
bogdanm 0:9b334a45a8ff 1855 * When enabling freeze mode, this function will wait for all current
bogdanm 0:9b334a45a8ff 1856 * ongoing CMU synchronization to LF domain to complete (Normally
bogdanm 0:9b334a45a8ff 1857 * synchronization will not be in progress.) However for this reason, when
bogdanm 0:9b334a45a8ff 1858 * using freeze mode, modifications of registers requiring LF synchronization
bogdanm 0:9b334a45a8ff 1859 * should be done within one freeze enable/disable block to avoid unecessary
bogdanm 0:9b334a45a8ff 1860 * stalling.
bogdanm 0:9b334a45a8ff 1861 *
bogdanm 0:9b334a45a8ff 1862 * @param[in] enable
bogdanm 0:9b334a45a8ff 1863 * @li true - enable freeze, modified registers are not propagated to the
bogdanm 0:9b334a45a8ff 1864 * LF domain
bogdanm 0:9b334a45a8ff 1865 * @li false - disable freeze, modified registers are propagated to LF
bogdanm 0:9b334a45a8ff 1866 * domain
bogdanm 0:9b334a45a8ff 1867 *****************************************************************************/
bogdanm 0:9b334a45a8ff 1868 void CMU_FreezeEnable(bool enable)
bogdanm 0:9b334a45a8ff 1869 {
bogdanm 0:9b334a45a8ff 1870 if (enable)
bogdanm 0:9b334a45a8ff 1871 {
bogdanm 0:9b334a45a8ff 1872 /* Wait for any ongoing LF synchronization to complete. This is just to */
bogdanm 0:9b334a45a8ff 1873 /* protect against the rare case when a user */
bogdanm 0:9b334a45a8ff 1874 /* - modifies a register requiring LF sync */
bogdanm 0:9b334a45a8ff 1875 /* - then enables freeze before LF sync completed */
bogdanm 0:9b334a45a8ff 1876 /* - then modifies the same register again */
bogdanm 0:9b334a45a8ff 1877 /* since modifying a register while it is in sync progress should be */
bogdanm 0:9b334a45a8ff 1878 /* avoided. */
bogdanm 0:9b334a45a8ff 1879 while (CMU->SYNCBUSY)
bogdanm 0:9b334a45a8ff 1880 ;
bogdanm 0:9b334a45a8ff 1881
bogdanm 0:9b334a45a8ff 1882 CMU->FREEZE = CMU_FREEZE_REGFREEZE;
bogdanm 0:9b334a45a8ff 1883 }
bogdanm 0:9b334a45a8ff 1884 else
bogdanm 0:9b334a45a8ff 1885 {
bogdanm 0:9b334a45a8ff 1886 CMU->FREEZE = 0;
bogdanm 0:9b334a45a8ff 1887 }
bogdanm 0:9b334a45a8ff 1888 }
bogdanm 0:9b334a45a8ff 1889
bogdanm 0:9b334a45a8ff 1890
bogdanm 0:9b334a45a8ff 1891 #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
bogdanm 0:9b334a45a8ff 1892 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1893 * @brief
bogdanm 0:9b334a45a8ff 1894 * Get AUXHFRCO band in use.
bogdanm 0:9b334a45a8ff 1895 *
bogdanm 0:9b334a45a8ff 1896 * @return
bogdanm 0:9b334a45a8ff 1897 * AUXHFRCO band in use.
bogdanm 0:9b334a45a8ff 1898 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1899 CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)
bogdanm 0:9b334a45a8ff 1900 {
bogdanm 0:9b334a45a8ff 1901 return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK) >>
bogdanm 0:9b334a45a8ff 1902 _CMU_AUXHFRCOCTRL_BAND_SHIFT);
bogdanm 0:9b334a45a8ff 1903 }
bogdanm 0:9b334a45a8ff 1904
bogdanm 0:9b334a45a8ff 1905 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1906 * @brief
bogdanm 0:9b334a45a8ff 1907 * Set AUIXHFRCO band and the tuning value based on the value in the
bogdanm 0:9b334a45a8ff 1908 * calibration table made during production.
bogdanm 0:9b334a45a8ff 1909 *
bogdanm 0:9b334a45a8ff 1910 * @param[in] band
bogdanm 0:9b334a45a8ff 1911 * AUXHFRCO band to activate.
bogdanm 0:9b334a45a8ff 1912 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1913 void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)
bogdanm 0:9b334a45a8ff 1914 {
bogdanm 0:9b334a45a8ff 1915 uint32_t tuning;
bogdanm 0:9b334a45a8ff 1916
bogdanm 0:9b334a45a8ff 1917 /* Read tuning value from calibration table */
bogdanm 0:9b334a45a8ff 1918 switch (band)
bogdanm 0:9b334a45a8ff 1919 {
bogdanm 0:9b334a45a8ff 1920 case cmuAUXHFRCOBand_1MHz:
bogdanm 0:9b334a45a8ff 1921 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK) >>
bogdanm 0:9b334a45a8ff 1922 _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;
bogdanm 0:9b334a45a8ff 1923 break;
bogdanm 0:9b334a45a8ff 1924
bogdanm 0:9b334a45a8ff 1925 case cmuAUXHFRCOBand_7MHz:
bogdanm 0:9b334a45a8ff 1926 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK) >>
bogdanm 0:9b334a45a8ff 1927 _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;
bogdanm 0:9b334a45a8ff 1928 break;
bogdanm 0:9b334a45a8ff 1929
bogdanm 0:9b334a45a8ff 1930 case cmuAUXHFRCOBand_11MHz:
bogdanm 0:9b334a45a8ff 1931 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK) >>
bogdanm 0:9b334a45a8ff 1932 _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;
bogdanm 0:9b334a45a8ff 1933 break;
bogdanm 0:9b334a45a8ff 1934
bogdanm 0:9b334a45a8ff 1935 case cmuAUXHFRCOBand_14MHz:
bogdanm 0:9b334a45a8ff 1936 tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK) >>
bogdanm 0:9b334a45a8ff 1937 _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;
bogdanm 0:9b334a45a8ff 1938 break;
bogdanm 0:9b334a45a8ff 1939
bogdanm 0:9b334a45a8ff 1940 case cmuAUXHFRCOBand_21MHz:
bogdanm 0:9b334a45a8ff 1941 tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK) >>
bogdanm 0:9b334a45a8ff 1942 _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;
bogdanm 0:9b334a45a8ff 1943 break;
bogdanm 0:9b334a45a8ff 1944
bogdanm 0:9b334a45a8ff 1945 #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
bogdanm 0:9b334a45a8ff 1946 case cmuAUXHFRCOBand_28MHz:
bogdanm 0:9b334a45a8ff 1947 tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK) >>
bogdanm 0:9b334a45a8ff 1948 _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;
bogdanm 0:9b334a45a8ff 1949 break;
bogdanm 0:9b334a45a8ff 1950 #endif
bogdanm 0:9b334a45a8ff 1951
bogdanm 0:9b334a45a8ff 1952 default:
bogdanm 0:9b334a45a8ff 1953 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 1954 return;
bogdanm 0:9b334a45a8ff 1955 }
bogdanm 0:9b334a45a8ff 1956
bogdanm 0:9b334a45a8ff 1957 /* Set band/tuning */
bogdanm 0:9b334a45a8ff 1958 CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &
bogdanm 0:9b334a45a8ff 1959 ~(_CMU_AUXHFRCOCTRL_BAND_MASK | _CMU_AUXHFRCOCTRL_TUNING_MASK)) |
bogdanm 0:9b334a45a8ff 1960 (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT) |
bogdanm 0:9b334a45a8ff 1961 (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 1962
bogdanm 0:9b334a45a8ff 1963 }
bogdanm 0:9b334a45a8ff 1964 #endif
bogdanm 0:9b334a45a8ff 1965
bogdanm 0:9b334a45a8ff 1966
bogdanm 0:9b334a45a8ff 1967 #if defined( _CMU_USHFRCOCONF_BAND_MASK )
bogdanm 0:9b334a45a8ff 1968 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1969 * @brief
bogdanm 0:9b334a45a8ff 1970 * Get USHFRCO band in use.
bogdanm 0:9b334a45a8ff 1971 *
bogdanm 0:9b334a45a8ff 1972 * @return
bogdanm 0:9b334a45a8ff 1973 * USHFRCO band in use.
bogdanm 0:9b334a45a8ff 1974 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1975 CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)
bogdanm 0:9b334a45a8ff 1976 {
bogdanm 0:9b334a45a8ff 1977 return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF & _CMU_USHFRCOCONF_BAND_MASK) >>
bogdanm 0:9b334a45a8ff 1978 _CMU_USHFRCOCONF_BAND_SHIFT);
bogdanm 0:9b334a45a8ff 1979 }
bogdanm 0:9b334a45a8ff 1980
bogdanm 0:9b334a45a8ff 1981 void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)
bogdanm 0:9b334a45a8ff 1982 {
bogdanm 0:9b334a45a8ff 1983 uint32_t tuning;
bogdanm 0:9b334a45a8ff 1984 uint32_t fineTuning;
bogdanm 0:9b334a45a8ff 1985 CMU_Select_TypeDef osc;
bogdanm 0:9b334a45a8ff 1986
bogdanm 0:9b334a45a8ff 1987 /* Cannot switch band if USHFRCO is already selected as HF clock. */
bogdanm 0:9b334a45a8ff 1988 osc = CMU_ClockSelectGet(cmuClock_HF);
bogdanm 0:9b334a45a8ff 1989 EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));
bogdanm 0:9b334a45a8ff 1990
bogdanm 0:9b334a45a8ff 1991 /* Read tuning value from calibration table */
bogdanm 0:9b334a45a8ff 1992 switch (band)
bogdanm 0:9b334a45a8ff 1993 {
bogdanm 0:9b334a45a8ff 1994 case cmuUSHFRCOBand_24MHz:
bogdanm 0:9b334a45a8ff 1995 tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK) >>
bogdanm 0:9b334a45a8ff 1996 _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 1997 fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK) >>
bogdanm 0:9b334a45a8ff 1998 _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;
bogdanm 0:9b334a45a8ff 1999 break;
bogdanm 0:9b334a45a8ff 2000
bogdanm 0:9b334a45a8ff 2001 case cmuUSHFRCOBand_48MHz:
bogdanm 0:9b334a45a8ff 2002 tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK) >>
bogdanm 0:9b334a45a8ff 2003 _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2004 fineTuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK) >>
bogdanm 0:9b334a45a8ff 2005 _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2006 /* Enable the clock divider before switching the band from 48 to 24MHz */
bogdanm 0:9b334a45a8ff 2007 BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);
bogdanm 0:9b334a45a8ff 2008 break;
bogdanm 0:9b334a45a8ff 2009
bogdanm 0:9b334a45a8ff 2010 default:
bogdanm 0:9b334a45a8ff 2011 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 2012 return;
bogdanm 0:9b334a45a8ff 2013 }
bogdanm 0:9b334a45a8ff 2014
bogdanm 0:9b334a45a8ff 2015 /* Set band and tuning */
bogdanm 0:9b334a45a8ff 2016 CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK) |
bogdanm 0:9b334a45a8ff 2017 (band << _CMU_USHFRCOCONF_BAND_SHIFT);
bogdanm 0:9b334a45a8ff 2018 CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK) |
bogdanm 0:9b334a45a8ff 2019 (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2020 CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK) |
bogdanm 0:9b334a45a8ff 2021 (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2022
bogdanm 0:9b334a45a8ff 2023 /* Disable the clock divider after switching the band from 48 to 24MHz */
bogdanm 0:9b334a45a8ff 2024 if (band == cmuUSHFRCOBand_24MHz)
bogdanm 0:9b334a45a8ff 2025 {
bogdanm 0:9b334a45a8ff 2026 BITBAND_Peripheral(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);
bogdanm 0:9b334a45a8ff 2027 }
bogdanm 0:9b334a45a8ff 2028 }
bogdanm 0:9b334a45a8ff 2029 #endif
bogdanm 0:9b334a45a8ff 2030
bogdanm 0:9b334a45a8ff 2031
bogdanm 0:9b334a45a8ff 2032 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2033 * @brief
bogdanm 0:9b334a45a8ff 2034 * Get HFRCO band in use.
bogdanm 0:9b334a45a8ff 2035 *
bogdanm 0:9b334a45a8ff 2036 * @return
bogdanm 0:9b334a45a8ff 2037 * HFRCO band in use.
bogdanm 0:9b334a45a8ff 2038 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2039 CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)
bogdanm 0:9b334a45a8ff 2040 {
bogdanm 0:9b334a45a8ff 2041 return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) >>
bogdanm 0:9b334a45a8ff 2042 _CMU_HFRCOCTRL_BAND_SHIFT);
bogdanm 0:9b334a45a8ff 2043 }
bogdanm 0:9b334a45a8ff 2044
bogdanm 0:9b334a45a8ff 2045
bogdanm 0:9b334a45a8ff 2046 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2047 * @brief
bogdanm 0:9b334a45a8ff 2048 * Set HFRCO band and the tuning value based on the value in the calibration
bogdanm 0:9b334a45a8ff 2049 * table made during production.
bogdanm 0:9b334a45a8ff 2050 *
bogdanm 0:9b334a45a8ff 2051 * @param[in] band
bogdanm 0:9b334a45a8ff 2052 * HFRCO band to activate.
bogdanm 0:9b334a45a8ff 2053 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2054 void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)
bogdanm 0:9b334a45a8ff 2055 {
bogdanm 0:9b334a45a8ff 2056 uint32_t tuning;
bogdanm 0:9b334a45a8ff 2057 uint32_t freq;
bogdanm 0:9b334a45a8ff 2058 CMU_Select_TypeDef osc;
bogdanm 0:9b334a45a8ff 2059
bogdanm 0:9b334a45a8ff 2060 /* Read tuning value from calibration table */
bogdanm 0:9b334a45a8ff 2061 switch (band)
bogdanm 0:9b334a45a8ff 2062 {
bogdanm 0:9b334a45a8ff 2063 case cmuHFRCOBand_1MHz:
bogdanm 0:9b334a45a8ff 2064 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK) >>
bogdanm 0:9b334a45a8ff 2065 _DEVINFO_HFRCOCAL0_BAND1_SHIFT;
bogdanm 0:9b334a45a8ff 2066 break;
bogdanm 0:9b334a45a8ff 2067
bogdanm 0:9b334a45a8ff 2068 case cmuHFRCOBand_7MHz:
bogdanm 0:9b334a45a8ff 2069 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK) >>
bogdanm 0:9b334a45a8ff 2070 _DEVINFO_HFRCOCAL0_BAND7_SHIFT;
bogdanm 0:9b334a45a8ff 2071 break;
bogdanm 0:9b334a45a8ff 2072
bogdanm 0:9b334a45a8ff 2073 case cmuHFRCOBand_11MHz:
bogdanm 0:9b334a45a8ff 2074 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK) >>
bogdanm 0:9b334a45a8ff 2075 _DEVINFO_HFRCOCAL0_BAND11_SHIFT;
bogdanm 0:9b334a45a8ff 2076 break;
bogdanm 0:9b334a45a8ff 2077
bogdanm 0:9b334a45a8ff 2078 case cmuHFRCOBand_14MHz:
bogdanm 0:9b334a45a8ff 2079 tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK) >>
bogdanm 0:9b334a45a8ff 2080 _DEVINFO_HFRCOCAL0_BAND14_SHIFT;
bogdanm 0:9b334a45a8ff 2081 break;
bogdanm 0:9b334a45a8ff 2082
bogdanm 0:9b334a45a8ff 2083 case cmuHFRCOBand_21MHz:
bogdanm 0:9b334a45a8ff 2084 tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK) >>
bogdanm 0:9b334a45a8ff 2085 _DEVINFO_HFRCOCAL1_BAND21_SHIFT;
bogdanm 0:9b334a45a8ff 2086 break;
bogdanm 0:9b334a45a8ff 2087
bogdanm 0:9b334a45a8ff 2088 #if defined( _CMU_HFRCOCTRL_BAND_28MHZ )
bogdanm 0:9b334a45a8ff 2089 case cmuHFRCOBand_28MHz:
bogdanm 0:9b334a45a8ff 2090 tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK) >>
bogdanm 0:9b334a45a8ff 2091 _DEVINFO_HFRCOCAL1_BAND28_SHIFT;
bogdanm 0:9b334a45a8ff 2092 break;
bogdanm 0:9b334a45a8ff 2093 #endif
bogdanm 0:9b334a45a8ff 2094
bogdanm 0:9b334a45a8ff 2095 default:
bogdanm 0:9b334a45a8ff 2096 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 2097 return;
bogdanm 0:9b334a45a8ff 2098 }
bogdanm 0:9b334a45a8ff 2099
bogdanm 0:9b334a45a8ff 2100 /* If HFRCO is used for core clock, we have to consider flash access WS. */
bogdanm 0:9b334a45a8ff 2101 osc = CMU_ClockSelectGet(cmuClock_HF);
bogdanm 0:9b334a45a8ff 2102 if (osc == cmuSelect_HFRCO)
bogdanm 0:9b334a45a8ff 2103 {
bogdanm 0:9b334a45a8ff 2104 /* Configure worst case wait states for flash access before setting divider */
bogdanm 0:9b334a45a8ff 2105 CMU_FlashWaitStateMax();
bogdanm 0:9b334a45a8ff 2106 }
bogdanm 0:9b334a45a8ff 2107
bogdanm 0:9b334a45a8ff 2108 /* Set band/tuning */
bogdanm 0:9b334a45a8ff 2109 CMU->HFRCOCTRL = (CMU->HFRCOCTRL &
bogdanm 0:9b334a45a8ff 2110 ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK)) |
bogdanm 0:9b334a45a8ff 2111 (band << _CMU_HFRCOCTRL_BAND_SHIFT) |
bogdanm 0:9b334a45a8ff 2112 (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2113
bogdanm 0:9b334a45a8ff 2114 /* If HFRCO is used for core clock, optimize flash WS */
bogdanm 0:9b334a45a8ff 2115 if (osc == cmuSelect_HFRCO)
bogdanm 0:9b334a45a8ff 2116 {
bogdanm 0:9b334a45a8ff 2117 /* Update CMSIS core clock variable and get current core clock */
bogdanm 0:9b334a45a8ff 2118 /* (The function will update the global variable) */
bogdanm 0:9b334a45a8ff 2119 /* NOTE! We need at least 21 cycles before setting zero wait state to flash */
bogdanm 0:9b334a45a8ff 2120 /* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */
bogdanm 0:9b334a45a8ff 2121 freq = SystemCoreClockGet();
bogdanm 0:9b334a45a8ff 2122
bogdanm 0:9b334a45a8ff 2123 /* Optimize flash access wait state setting for current core clk */
bogdanm 0:9b334a45a8ff 2124 CMU_FlashWaitStateControl(freq);
bogdanm 0:9b334a45a8ff 2125 }
bogdanm 0:9b334a45a8ff 2126 }
bogdanm 0:9b334a45a8ff 2127
bogdanm 0:9b334a45a8ff 2128
bogdanm 0:9b334a45a8ff 2129 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2130 * @brief
bogdanm 0:9b334a45a8ff 2131 * Get the HFRCO startup delay.
bogdanm 0:9b334a45a8ff 2132 *
bogdanm 0:9b334a45a8ff 2133 * @details
bogdanm 0:9b334a45a8ff 2134 * Please refer to the reference manual for further details.
bogdanm 0:9b334a45a8ff 2135 *
bogdanm 0:9b334a45a8ff 2136 * @return
bogdanm 0:9b334a45a8ff 2137 * The startup delay in use.
bogdanm 0:9b334a45a8ff 2138 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2139 uint32_t CMU_HFRCOStartupDelayGet(void)
bogdanm 0:9b334a45a8ff 2140 {
bogdanm 0:9b334a45a8ff 2141 return((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK) >>
bogdanm 0:9b334a45a8ff 2142 _CMU_HFRCOCTRL_SUDELAY_SHIFT);
bogdanm 0:9b334a45a8ff 2143 }
bogdanm 0:9b334a45a8ff 2144
bogdanm 0:9b334a45a8ff 2145
bogdanm 0:9b334a45a8ff 2146 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2147 * @brief
bogdanm 0:9b334a45a8ff 2148 * Set the HFRCO startup delay.
bogdanm 0:9b334a45a8ff 2149 *
bogdanm 0:9b334a45a8ff 2150 * @details
bogdanm 0:9b334a45a8ff 2151 * Please refer to the reference manual for further details.
bogdanm 0:9b334a45a8ff 2152 *
bogdanm 0:9b334a45a8ff 2153 * @param[in] delay
bogdanm 0:9b334a45a8ff 2154 * The startup delay to set (<= 31).
bogdanm 0:9b334a45a8ff 2155 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2156 void CMU_HFRCOStartupDelaySet(uint32_t delay)
bogdanm 0:9b334a45a8ff 2157 {
bogdanm 0:9b334a45a8ff 2158 EFM_ASSERT(delay <= 31);
bogdanm 0:9b334a45a8ff 2159
bogdanm 0:9b334a45a8ff 2160 delay &= (_CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT);
bogdanm 0:9b334a45a8ff 2161 CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK)) |
bogdanm 0:9b334a45a8ff 2162 (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);
bogdanm 0:9b334a45a8ff 2163 }
bogdanm 0:9b334a45a8ff 2164
bogdanm 0:9b334a45a8ff 2165
bogdanm 0:9b334a45a8ff 2166 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2167 * @brief
bogdanm 0:9b334a45a8ff 2168 * Get the LCD framerate divisor (FDIV) setting.
bogdanm 0:9b334a45a8ff 2169 *
bogdanm 0:9b334a45a8ff 2170 * @return
bogdanm 0:9b334a45a8ff 2171 * The LCD framerate divisor.
bogdanm 0:9b334a45a8ff 2172 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2173 uint32_t CMU_LCDClkFDIVGet(void)
bogdanm 0:9b334a45a8ff 2174 {
bogdanm 0:9b334a45a8ff 2175 #if defined(LCD_PRESENT)
bogdanm 0:9b334a45a8ff 2176 return((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT);
bogdanm 0:9b334a45a8ff 2177 #else
bogdanm 0:9b334a45a8ff 2178 return 0;
bogdanm 0:9b334a45a8ff 2179 #endif /* defined(LCD_PRESENT) */
bogdanm 0:9b334a45a8ff 2180 }
bogdanm 0:9b334a45a8ff 2181
bogdanm 0:9b334a45a8ff 2182
bogdanm 0:9b334a45a8ff 2183 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2184 * @brief
bogdanm 0:9b334a45a8ff 2185 * Set the LCD framerate divisor (FDIV) setting.
bogdanm 0:9b334a45a8ff 2186 *
bogdanm 0:9b334a45a8ff 2187 * @note
bogdanm 0:9b334a45a8ff 2188 * The FDIV field (CMU LCDCTRL register) should only be modified while the
bogdanm 0:9b334a45a8ff 2189 * LCD module is clock disabled (CMU LFACLKEN0.LCD bit is 0). This function
bogdanm 0:9b334a45a8ff 2190 * will NOT modify FDIV if the LCD module clock is enabled. Please refer to
bogdanm 0:9b334a45a8ff 2191 * CMU_ClockEnable() for disabling/enabling LCD clock.
bogdanm 0:9b334a45a8ff 2192 *
bogdanm 0:9b334a45a8ff 2193 * @param[in] div
bogdanm 0:9b334a45a8ff 2194 * The FDIV setting to use.
bogdanm 0:9b334a45a8ff 2195 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2196 void CMU_LCDClkFDIVSet(uint32_t div)
bogdanm 0:9b334a45a8ff 2197 {
bogdanm 0:9b334a45a8ff 2198 #if defined(LCD_PRESENT)
bogdanm 0:9b334a45a8ff 2199 EFM_ASSERT(div <= cmuClkDiv_128);
bogdanm 0:9b334a45a8ff 2200
bogdanm 0:9b334a45a8ff 2201 /* Do not allow modification if LCD clock enabled */
bogdanm 0:9b334a45a8ff 2202 if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)
bogdanm 0:9b334a45a8ff 2203 {
bogdanm 0:9b334a45a8ff 2204 return;
bogdanm 0:9b334a45a8ff 2205 }
bogdanm 0:9b334a45a8ff 2206
bogdanm 0:9b334a45a8ff 2207 div <<= _CMU_LCDCTRL_FDIV_SHIFT;
bogdanm 0:9b334a45a8ff 2208 div &= _CMU_LCDCTRL_FDIV_MASK;
bogdanm 0:9b334a45a8ff 2209 CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;
bogdanm 0:9b334a45a8ff 2210 #else
bogdanm 0:9b334a45a8ff 2211 (void)div; /* Unused parameter */
bogdanm 0:9b334a45a8ff 2212 #endif /* defined(LCD_PRESENT) */
bogdanm 0:9b334a45a8ff 2213 }
bogdanm 0:9b334a45a8ff 2214
bogdanm 0:9b334a45a8ff 2215
bogdanm 0:9b334a45a8ff 2216 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2217 * @brief
bogdanm 0:9b334a45a8ff 2218 * Enable/disable oscillator.
bogdanm 0:9b334a45a8ff 2219 *
bogdanm 0:9b334a45a8ff 2220 * @note
bogdanm 0:9b334a45a8ff 2221 * WARNING: When this function is called to disable either cmuOsc_LFXO or
bogdanm 0:9b334a45a8ff 2222 * cmuOsc_HFXO the LFXOMODE or HFXOMODE fields of the CMU_CTRL register
bogdanm 0:9b334a45a8ff 2223 * are reset to the reset value. I.e. if external clock sources are selected
bogdanm 0:9b334a45a8ff 2224 * in either LFXOMODE or HFXOMODE fields, the configuration will be cleared
bogdanm 0:9b334a45a8ff 2225 * and needs to be reconfigured if needed later.
bogdanm 0:9b334a45a8ff 2226 *
bogdanm 0:9b334a45a8ff 2227 * @param[in] osc
bogdanm 0:9b334a45a8ff 2228 * The oscillator to enable/disable.
bogdanm 0:9b334a45a8ff 2229 *
bogdanm 0:9b334a45a8ff 2230 * @param[in] enable
bogdanm 0:9b334a45a8ff 2231 * @li true - enable specified oscillator.
bogdanm 0:9b334a45a8ff 2232 * @li false - disable specified oscillator.
bogdanm 0:9b334a45a8ff 2233 *
bogdanm 0:9b334a45a8ff 2234 * @param[in] wait
bogdanm 0:9b334a45a8ff 2235 * Only used if @p enable is true.
bogdanm 0:9b334a45a8ff 2236 * @li true - wait for oscillator start-up time to timeout before returning.
bogdanm 0:9b334a45a8ff 2237 * @li false - do not wait for oscillator start-up time to timeout before
bogdanm 0:9b334a45a8ff 2238 * returning.
bogdanm 0:9b334a45a8ff 2239 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2240 void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
bogdanm 0:9b334a45a8ff 2241 {
bogdanm 0:9b334a45a8ff 2242 uint32_t status;
bogdanm 0:9b334a45a8ff 2243 uint32_t enBit;
bogdanm 0:9b334a45a8ff 2244 uint32_t disBit;
bogdanm 0:9b334a45a8ff 2245
bogdanm 0:9b334a45a8ff 2246 switch (osc)
bogdanm 0:9b334a45a8ff 2247 {
bogdanm 0:9b334a45a8ff 2248 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 2249 enBit = CMU_OSCENCMD_HFRCOEN;
bogdanm 0:9b334a45a8ff 2250 disBit = CMU_OSCENCMD_HFRCODIS;
bogdanm 0:9b334a45a8ff 2251 status = CMU_STATUS_HFRCORDY;
bogdanm 0:9b334a45a8ff 2252 break;
bogdanm 0:9b334a45a8ff 2253
bogdanm 0:9b334a45a8ff 2254 case cmuOsc_HFXO:
bogdanm 0:9b334a45a8ff 2255 enBit = CMU_OSCENCMD_HFXOEN;
bogdanm 0:9b334a45a8ff 2256 disBit = CMU_OSCENCMD_HFXODIS;
bogdanm 0:9b334a45a8ff 2257 status = CMU_STATUS_HFXORDY;
bogdanm 0:9b334a45a8ff 2258 break;
bogdanm 0:9b334a45a8ff 2259
bogdanm 0:9b334a45a8ff 2260 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 2261 enBit = CMU_OSCENCMD_AUXHFRCOEN;
bogdanm 0:9b334a45a8ff 2262 disBit = CMU_OSCENCMD_AUXHFRCODIS;
bogdanm 0:9b334a45a8ff 2263 status = CMU_STATUS_AUXHFRCORDY;
bogdanm 0:9b334a45a8ff 2264 break;
bogdanm 0:9b334a45a8ff 2265
bogdanm 0:9b334a45a8ff 2266 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 2267 enBit = CMU_OSCENCMD_LFRCOEN;
bogdanm 0:9b334a45a8ff 2268 disBit = CMU_OSCENCMD_LFRCODIS;
bogdanm 0:9b334a45a8ff 2269 status = CMU_STATUS_LFRCORDY;
bogdanm 0:9b334a45a8ff 2270 break;
bogdanm 0:9b334a45a8ff 2271
bogdanm 0:9b334a45a8ff 2272 case cmuOsc_LFXO:
bogdanm 0:9b334a45a8ff 2273 enBit = CMU_OSCENCMD_LFXOEN;
bogdanm 0:9b334a45a8ff 2274 disBit = CMU_OSCENCMD_LFXODIS;
bogdanm 0:9b334a45a8ff 2275 status = CMU_STATUS_LFXORDY;
bogdanm 0:9b334a45a8ff 2276 break;
bogdanm 0:9b334a45a8ff 2277
bogdanm 0:9b334a45a8ff 2278 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
bogdanm 0:9b334a45a8ff 2279 case cmuOsc_USHFRCO:
bogdanm 0:9b334a45a8ff 2280 enBit = CMU_OSCENCMD_USHFRCOEN;
bogdanm 0:9b334a45a8ff 2281 disBit = CMU_OSCENCMD_USHFRCODIS;
bogdanm 0:9b334a45a8ff 2282 status = CMU_STATUS_USHFRCORDY;
bogdanm 0:9b334a45a8ff 2283 break;
bogdanm 0:9b334a45a8ff 2284 #endif
bogdanm 0:9b334a45a8ff 2285
bogdanm 0:9b334a45a8ff 2286 #if defined( _CMU_LFCLKSEL_LFAE_ULFRCO )
bogdanm 0:9b334a45a8ff 2287 case cmuOsc_ULFRCO:
bogdanm 0:9b334a45a8ff 2288 /* ULFRCO is always enabled, and cannot be turned off */
bogdanm 0:9b334a45a8ff 2289 return;
bogdanm 0:9b334a45a8ff 2290 #endif
bogdanm 0:9b334a45a8ff 2291
bogdanm 0:9b334a45a8ff 2292 default:
bogdanm 0:9b334a45a8ff 2293 /* Undefined clock source */
bogdanm 0:9b334a45a8ff 2294 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 2295 return;
bogdanm 0:9b334a45a8ff 2296 }
bogdanm 0:9b334a45a8ff 2297
bogdanm 0:9b334a45a8ff 2298 if (enable)
bogdanm 0:9b334a45a8ff 2299 {
bogdanm 0:9b334a45a8ff 2300 CMU->OSCENCMD = enBit;
bogdanm 0:9b334a45a8ff 2301
bogdanm 0:9b334a45a8ff 2302 /* Wait for clock to stabilize if requested */
bogdanm 0:9b334a45a8ff 2303 if (wait)
bogdanm 0:9b334a45a8ff 2304 {
bogdanm 0:9b334a45a8ff 2305 while (!(CMU->STATUS & status))
bogdanm 0:9b334a45a8ff 2306 ;
bogdanm 0:9b334a45a8ff 2307 }
bogdanm 0:9b334a45a8ff 2308 }
bogdanm 0:9b334a45a8ff 2309 else
bogdanm 0:9b334a45a8ff 2310 {
bogdanm 0:9b334a45a8ff 2311 CMU->OSCENCMD = disBit;
bogdanm 0:9b334a45a8ff 2312 }
bogdanm 0:9b334a45a8ff 2313
bogdanm 0:9b334a45a8ff 2314 /* Keep EMU module informed */
bogdanm 0:9b334a45a8ff 2315 EMU_UpdateOscConfig();
bogdanm 0:9b334a45a8ff 2316 }
bogdanm 0:9b334a45a8ff 2317
bogdanm 0:9b334a45a8ff 2318
bogdanm 0:9b334a45a8ff 2319 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2320 * @brief
bogdanm 0:9b334a45a8ff 2321 * Get oscillator frequency tuning setting.
bogdanm 0:9b334a45a8ff 2322 *
bogdanm 0:9b334a45a8ff 2323 * @param[in] osc
bogdanm 0:9b334a45a8ff 2324 * Oscillator to get tuning value for, one of:
bogdanm 0:9b334a45a8ff 2325 * @li #cmuOsc_LFRCO
bogdanm 0:9b334a45a8ff 2326 * @li #cmuOsc_HFRCO
bogdanm 0:9b334a45a8ff 2327 * @li #cmuOsc_AUXHFRCO
bogdanm 0:9b334a45a8ff 2328 *
bogdanm 0:9b334a45a8ff 2329 * @return
bogdanm 0:9b334a45a8ff 2330 * The oscillator frequency tuning setting in use.
bogdanm 0:9b334a45a8ff 2331 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2332 uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
bogdanm 0:9b334a45a8ff 2333 {
bogdanm 0:9b334a45a8ff 2334 uint32_t ret;
bogdanm 0:9b334a45a8ff 2335
bogdanm 0:9b334a45a8ff 2336 switch (osc)
bogdanm 0:9b334a45a8ff 2337 {
bogdanm 0:9b334a45a8ff 2338 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 2339 ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK) >>
bogdanm 0:9b334a45a8ff 2340 _CMU_LFRCOCTRL_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2341 break;
bogdanm 0:9b334a45a8ff 2342
bogdanm 0:9b334a45a8ff 2343 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 2344 ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK) >>
bogdanm 0:9b334a45a8ff 2345 _CMU_HFRCOCTRL_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2346 break;
bogdanm 0:9b334a45a8ff 2347
bogdanm 0:9b334a45a8ff 2348 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 2349 ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK) >>
bogdanm 0:9b334a45a8ff 2350 _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2351 break;
bogdanm 0:9b334a45a8ff 2352
bogdanm 0:9b334a45a8ff 2353 default:
bogdanm 0:9b334a45a8ff 2354 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 2355 ret = 0;
bogdanm 0:9b334a45a8ff 2356 break;
bogdanm 0:9b334a45a8ff 2357 }
bogdanm 0:9b334a45a8ff 2358
bogdanm 0:9b334a45a8ff 2359 return(ret);
bogdanm 0:9b334a45a8ff 2360 }
bogdanm 0:9b334a45a8ff 2361
bogdanm 0:9b334a45a8ff 2362
bogdanm 0:9b334a45a8ff 2363 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 2364 * @brief
bogdanm 0:9b334a45a8ff 2365 * Set the oscillator frequency tuning control.
bogdanm 0:9b334a45a8ff 2366 *
bogdanm 0:9b334a45a8ff 2367 * @note
bogdanm 0:9b334a45a8ff 2368 * Oscillator tuning is done during production, and the tuning value is
bogdanm 0:9b334a45a8ff 2369 * automatically loaded after a reset. Changing the tuning value from the
bogdanm 0:9b334a45a8ff 2370 * calibrated value is for more advanced use.
bogdanm 0:9b334a45a8ff 2371 *
bogdanm 0:9b334a45a8ff 2372 * @param[in] osc
bogdanm 0:9b334a45a8ff 2373 * Oscillator to set tuning value for, one of:
bogdanm 0:9b334a45a8ff 2374 * @li #cmuOsc_LFRCO
bogdanm 0:9b334a45a8ff 2375 * @li #cmuOsc_HFRCO
bogdanm 0:9b334a45a8ff 2376 * @li #cmuOsc_AUXHFRCO
bogdanm 0:9b334a45a8ff 2377 *
bogdanm 0:9b334a45a8ff 2378 * @param[in] val
bogdanm 0:9b334a45a8ff 2379 * The oscillator frequency tuning setting to use.
bogdanm 0:9b334a45a8ff 2380 ******************************************************************************/
bogdanm 0:9b334a45a8ff 2381 void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
bogdanm 0:9b334a45a8ff 2382 {
bogdanm 0:9b334a45a8ff 2383 switch (osc)
bogdanm 0:9b334a45a8ff 2384 {
bogdanm 0:9b334a45a8ff 2385 case cmuOsc_LFRCO:
bogdanm 0:9b334a45a8ff 2386 EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT));
bogdanm 0:9b334a45a8ff 2387
bogdanm 0:9b334a45a8ff 2388 val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2389 CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK)) |
bogdanm 0:9b334a45a8ff 2390 (val << _CMU_LFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2391 break;
bogdanm 0:9b334a45a8ff 2392
bogdanm 0:9b334a45a8ff 2393 case cmuOsc_HFRCO:
bogdanm 0:9b334a45a8ff 2394 EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT));
bogdanm 0:9b334a45a8ff 2395
bogdanm 0:9b334a45a8ff 2396 val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2397 CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK)) |
bogdanm 0:9b334a45a8ff 2398 (val << _CMU_HFRCOCTRL_TUNING_SHIFT);
bogdanm 0:9b334a45a8ff 2399 break;
bogdanm 0:9b334a45a8ff 2400
bogdanm 0:9b334a45a8ff 2401 case cmuOsc_AUXHFRCO:
bogdanm 0:9b334a45a8ff 2402 EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));
bogdanm 0:9b334a45a8ff 2403
bogdanm 0:9b334a45a8ff 2404 val <<= _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
bogdanm 0:9b334a45a8ff 2405 val &= _CMU_AUXHFRCOCTRL_TUNING_MASK;
bogdanm 0:9b334a45a8ff 2406 CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK)) | val;
bogdanm 0:9b334a45a8ff 2407 break;
bogdanm 0:9b334a45a8ff 2408
bogdanm 0:9b334a45a8ff 2409 default:
bogdanm 0:9b334a45a8ff 2410 EFM_ASSERT(0);
bogdanm 0:9b334a45a8ff 2411 break;
bogdanm 0:9b334a45a8ff 2412 }
bogdanm 0:9b334a45a8ff 2413 }
bogdanm 0:9b334a45a8ff 2414
bogdanm 0:9b334a45a8ff 2415
bogdanm 0:9b334a45a8ff 2416 /**************************************************************************//**
bogdanm 0:9b334a45a8ff 2417 * @brief
bogdanm 0:9b334a45a8ff 2418 * Determine if currently selected PCNTn clock used is external or LFBCLK.
bogdanm 0:9b334a45a8ff 2419 *
bogdanm 0:9b334a45a8ff 2420 * @param[in] inst
bogdanm 0:9b334a45a8ff 2421 * PCNT instance number to get currently selected clock source for.
bogdanm 0:9b334a45a8ff 2422 *
bogdanm 0:9b334a45a8ff 2423 * @return
bogdanm 0:9b334a45a8ff 2424 * @li true - selected clock is external clock.
bogdanm 0:9b334a45a8ff 2425 * @li false - selected clock is LFBCLK.
bogdanm 0:9b334a45a8ff 2426 *****************************************************************************/
bogdanm 0:9b334a45a8ff 2427 bool CMU_PCNTClockExternalGet(unsigned int inst)
bogdanm 0:9b334a45a8ff 2428 {
bogdanm 0:9b334a45a8ff 2429 bool ret;
bogdanm 0:9b334a45a8ff 2430 uint32_t setting;
bogdanm 0:9b334a45a8ff 2431
bogdanm 0:9b334a45a8ff 2432 switch (inst)
bogdanm 0:9b334a45a8ff 2433 {
bogdanm 0:9b334a45a8ff 2434 #if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
bogdanm 0:9b334a45a8ff 2435 case 0:
bogdanm 0:9b334a45a8ff 2436 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;
bogdanm 0:9b334a45a8ff 2437 break;
bogdanm 0:9b334a45a8ff 2438
bogdanm 0:9b334a45a8ff 2439 #if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
bogdanm 0:9b334a45a8ff 2440 case 1:
bogdanm 0:9b334a45a8ff 2441 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;
bogdanm 0:9b334a45a8ff 2442 break;
bogdanm 0:9b334a45a8ff 2443
bogdanm 0:9b334a45a8ff 2444 #if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
bogdanm 0:9b334a45a8ff 2445 case 2:
bogdanm 0:9b334a45a8ff 2446 setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;
bogdanm 0:9b334a45a8ff 2447 break;
bogdanm 0:9b334a45a8ff 2448 #endif
bogdanm 0:9b334a45a8ff 2449 #endif
bogdanm 0:9b334a45a8ff 2450 #endif
bogdanm 0:9b334a45a8ff 2451
bogdanm 0:9b334a45a8ff 2452 default:
bogdanm 0:9b334a45a8ff 2453 setting = 0;
bogdanm 0:9b334a45a8ff 2454 break;
bogdanm 0:9b334a45a8ff 2455 }
bogdanm 0:9b334a45a8ff 2456
bogdanm 0:9b334a45a8ff 2457 if (setting)
bogdanm 0:9b334a45a8ff 2458 {
bogdanm 0:9b334a45a8ff 2459 ret = true;
bogdanm 0:9b334a45a8ff 2460 }
bogdanm 0:9b334a45a8ff 2461 else
bogdanm 0:9b334a45a8ff 2462 {
bogdanm 0:9b334a45a8ff 2463 ret = false;
bogdanm 0:9b334a45a8ff 2464 }
bogdanm 0:9b334a45a8ff 2465 return ret;
bogdanm 0:9b334a45a8ff 2466 }
bogdanm 0:9b334a45a8ff 2467
bogdanm 0:9b334a45a8ff 2468
bogdanm 0:9b334a45a8ff 2469 /**************************************************************************//**
bogdanm 0:9b334a45a8ff 2470 * @brief
bogdanm 0:9b334a45a8ff 2471 * Select PCNTn clock.
bogdanm 0:9b334a45a8ff 2472 *
bogdanm 0:9b334a45a8ff 2473 * @param[in] inst
bogdanm 0:9b334a45a8ff 2474 * PCNT instance number to set selected clock source for.
bogdanm 0:9b334a45a8ff 2475 *
bogdanm 0:9b334a45a8ff 2476 * @param[in] external
bogdanm 0:9b334a45a8ff 2477 * Set to true to select external clock, false to select LFBCLK.
bogdanm 0:9b334a45a8ff 2478 *****************************************************************************/
bogdanm 0:9b334a45a8ff 2479 void CMU_PCNTClockExternalSet(unsigned int inst, bool external)
bogdanm 0:9b334a45a8ff 2480 {
bogdanm 0:9b334a45a8ff 2481 #if defined(PCNT_PRESENT)
bogdanm 0:9b334a45a8ff 2482 uint32_t setting = 0;
bogdanm 0:9b334a45a8ff 2483
bogdanm 0:9b334a45a8ff 2484 EFM_ASSERT(inst < PCNT_COUNT);
bogdanm 0:9b334a45a8ff 2485
bogdanm 0:9b334a45a8ff 2486 if (external)
bogdanm 0:9b334a45a8ff 2487 {
bogdanm 0:9b334a45a8ff 2488 setting = 1;
bogdanm 0:9b334a45a8ff 2489 }
bogdanm 0:9b334a45a8ff 2490
bogdanm 0:9b334a45a8ff 2491 BITBAND_Peripheral(&(CMU->PCNTCTRL), (inst * 2) + 1, setting);
bogdanm 0:9b334a45a8ff 2492
bogdanm 0:9b334a45a8ff 2493 #else
bogdanm 0:9b334a45a8ff 2494 (void)inst; /* Unused parameter */
bogdanm 0:9b334a45a8ff 2495 (void)external; /* Unused parameter */
bogdanm 0:9b334a45a8ff 2496 #endif
bogdanm 0:9b334a45a8ff 2497 }
bogdanm 0:9b334a45a8ff 2498
bogdanm 0:9b334a45a8ff 2499
bogdanm 0:9b334a45a8ff 2500 /** @} (end addtogroup CMU) */
bogdanm 0:9b334a45a8ff 2501 /** @} (end addtogroup EM_Library) */
bogdanm 0:9b334a45a8ff 2502 #endif /* __EM_CMU_H */