mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
<>
Date:
Tue Nov 08 17:45:16 2016 +0000
Revision:
150:02e0a0aed4ec
Parent:
149:156823d33999
Child:
161:2cc1468da177
This updates the lib to the mbed lib v129

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_emu.c
<> 144:ef7eb2e8f9f7 3 * @brief Energy Management Unit (EMU) Peripheral API
<> 150:02e0a0aed4ec 4 * @version 5.0.0
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
<> 144:ef7eb2e8f9f7 6 * @section License
<> 150:02e0a0aed4ec 7 * <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include <limits.h>
<> 144:ef7eb2e8f9f7 34
<> 144:ef7eb2e8f9f7 35 #include "em_emu.h"
<> 144:ef7eb2e8f9f7 36 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
<> 144:ef7eb2e8f9f7 37
<> 144:ef7eb2e8f9f7 38 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 39 #include "em_system.h"
<> 150:02e0a0aed4ec 40 #include "em_common.h"
<> 144:ef7eb2e8f9f7 41 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 42
<> 144:ef7eb2e8f9f7 43 /***************************************************************************//**
<> 150:02e0a0aed4ec 44 * @addtogroup emlib
<> 144:ef7eb2e8f9f7 45 * @{
<> 144:ef7eb2e8f9f7 46 ******************************************************************************/
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 49 * @addtogroup EMU
<> 144:ef7eb2e8f9f7 50 * @brief Energy Management Unit (EMU) Peripheral API
<> 150:02e0a0aed4ec 51 * @details
<> 150:02e0a0aed4ec 52 * This module contains functions to control the EMU peripheral of Silicon
<> 150:02e0a0aed4ec 53 * Labs 32-bit MCUs and SoCs. The EMU handles the different low energy modes
<> 150:02e0a0aed4ec 54 * in Silicon Labs microcontrollers.
<> 144:ef7eb2e8f9f7 55 * @{
<> 144:ef7eb2e8f9f7 56 ******************************************************************************/
<> 144:ef7eb2e8f9f7 57
<> 144:ef7eb2e8f9f7 58 /* Consistency check, since restoring assumes similar bitpositions in */
<> 144:ef7eb2e8f9f7 59 /* CMU OSCENCMD and STATUS regs */
<> 144:ef7eb2e8f9f7 60 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
<> 144:ef7eb2e8f9f7 61 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 62 #endif
<> 144:ef7eb2e8f9f7 63 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
<> 144:ef7eb2e8f9f7 64 #error Conflict in HFXOENS and HFXOEN bitpositions
<> 144:ef7eb2e8f9f7 65 #endif
<> 144:ef7eb2e8f9f7 66 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
<> 144:ef7eb2e8f9f7 67 #error Conflict in LFRCOENS and LFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 68 #endif
<> 144:ef7eb2e8f9f7 69 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
<> 144:ef7eb2e8f9f7 70 #error Conflict in LFXOENS and LFXOEN bitpositions
<> 144:ef7eb2e8f9f7 71 #endif
<> 144:ef7eb2e8f9f7 72
<> 144:ef7eb2e8f9f7 73
<> 144:ef7eb2e8f9f7 74 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 75 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
<> 144:ef7eb2e8f9f7 76 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 77 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 78 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
<> 144:ef7eb2e8f9f7 79 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 80
<> 144:ef7eb2e8f9f7 81 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 82 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 83 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
<> 144:ef7eb2e8f9f7 84 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 87 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 88 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 89 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 92 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 93 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 94 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 95
<> 144:ef7eb2e8f9f7 96 #else
<> 144:ef7eb2e8f9f7 97 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 98 #endif
<> 144:ef7eb2e8f9f7 99
<> 144:ef7eb2e8f9f7 100 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 101 #if defined( _EFM32_HAPPY_FAMILY )
<> 144:ef7eb2e8f9f7 102 #define ERRATA_FIX_EMU_E108_EN
<> 144:ef7eb2e8f9f7 103 #endif
<> 150:02e0a0aed4ec 104
<> 150:02e0a0aed4ec 105 /* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H */
<> 150:02e0a0aed4ec 106 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 150:02e0a0aed4ec 107 #define ERRATA_FIX_EMU_E208_EN
<> 150:02e0a0aed4ec 108 #endif
<> 150:02e0a0aed4ec 109
<> 150:02e0a0aed4ec 110 /* Enable FETCNT tuning errata fix */
<> 150:02e0a0aed4ec 111 #if defined( _EMU_DCDCCTRL_MASK ) && defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 150:02e0a0aed4ec 112 #define ERRATA_FIX_DCDC_FETCNT_SET_EN
<> 150:02e0a0aed4ec 113 #endif
<> 150:02e0a0aed4ec 114
<> 150:02e0a0aed4ec 115 /* Enable LN handshake errata fix */
<> 150:02e0a0aed4ec 116 #if defined( _EMU_DCDCCTRL_MASK ) && ( _SILICON_LABS_32B_PLATFORM_2_GEN < 3 )
<> 150:02e0a0aed4ec 117 #define ERRATA_FIX_DCDC_LNHS_BLOCK_EN
<> 150:02e0a0aed4ec 118 #endif
<> 150:02e0a0aed4ec 119
<> 150:02e0a0aed4ec 120 /* Enable bypass current limiter enable timing fix */
<> 150:02e0a0aed4ec 121 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_2 )
<> 150:02e0a0aed4ec 122 #define ERRATA_FIX_BYPLIMEN_TIMING_EN
<> 150:02e0a0aed4ec 123 #endif
<> 150:02e0a0aed4ec 124
<> 150:02e0a0aed4ec 125 #define EMU_DCDCCLIMCTRL (uint32_t *)(EMU_BASE + 0x054)
<> 150:02e0a0aed4ec 126 #if !defined(_EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT)
<> 150:02e0a0aed4ec 127 #define _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT 13
<> 150:02e0a0aed4ec 128 #endif
<> 150:02e0a0aed4ec 129 #if !defined(_EMU_PWRCTRL_DVDDBODDIS_SHIFT)
<> 150:02e0a0aed4ec 130 #define EMU_PWRCTRL_DVDDBODDIS (1 << 12)
<> 150:02e0a0aed4ec 131 #endif
<> 150:02e0a0aed4ec 132
<> 144:ef7eb2e8f9f7 133 /** @endcond */
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 137 /* DCDCTODVDD output range min/max */
<> 150:02e0a0aed4ec 138 #if !defined(PWRCFG_DCDCTODVDD_VMIN)
<> 150:02e0a0aed4ec 139 #define PWRCFG_DCDCTODVDD_VMIN 1800
<> 150:02e0a0aed4ec 140 #endif
<> 150:02e0a0aed4ec 141 #if !defined(PWRCFG_DCDCTODVDD_VMAX)
<> 144:ef7eb2e8f9f7 142 #define PWRCFG_DCDCTODVDD_VMAX 3000
<> 150:02e0a0aed4ec 143 #endif
<> 150:02e0a0aed4ec 144
<> 144:ef7eb2e8f9f7 145 typedef enum
<> 144:ef7eb2e8f9f7 146 {
<> 144:ef7eb2e8f9f7 147 errataFixDcdcHsInit,
<> 144:ef7eb2e8f9f7 148 errataFixDcdcHsTrimSet,
<> 150:02e0a0aed4ec 149 errataFixDcdcHsBypassLn,
<> 144:ef7eb2e8f9f7 150 errataFixDcdcHsLnWaitDone
<> 144:ef7eb2e8f9f7 151 } errataFixDcdcHs_TypeDef;
<> 144:ef7eb2e8f9f7 152 errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;
<> 144:ef7eb2e8f9f7 153 #endif
<> 144:ef7eb2e8f9f7 154
<> 144:ef7eb2e8f9f7 155 /*******************************************************************************
<> 144:ef7eb2e8f9f7 156 ************************** LOCAL VARIABLES ********************************
<> 144:ef7eb2e8f9f7 157 ******************************************************************************/
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 160 /**
<> 144:ef7eb2e8f9f7 161 * CMU configured oscillator selection and oscillator enable status. When a
<> 144:ef7eb2e8f9f7 162 * user configures oscillators, this varaiable shall shadow the configuration.
<> 144:ef7eb2e8f9f7 163 * It is used by the EMU module in order to be able to restore the oscillator
<> 144:ef7eb2e8f9f7 164 * config after having been in certain energy modes (since HW may automatically
<> 144:ef7eb2e8f9f7 165 * alter config when going into an energy mode). It is the responsibility of
<> 144:ef7eb2e8f9f7 166 * the CMU module to keep it up-to-date (or a user if not using the CMU API
<> 144:ef7eb2e8f9f7 167 * for oscillator control).
<> 144:ef7eb2e8f9f7 168 */
<> 144:ef7eb2e8f9f7 169 static uint32_t cmuStatus;
<> 144:ef7eb2e8f9f7 170 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 171 static uint16_t cmuHfclkStatus;
<> 144:ef7eb2e8f9f7 172 #endif
<> 144:ef7eb2e8f9f7 173 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 174 static uint16_t dcdcMaxCurrent_mA;
<> 150:02e0a0aed4ec 175 static uint16_t dcdcEm01LoadCurrent_mA;
<> 150:02e0a0aed4ec 176 static EMU_DcdcLnReverseCurrentControl_TypeDef dcdcReverseCurrentControl;
<> 144:ef7eb2e8f9f7 177 #endif
<> 144:ef7eb2e8f9f7 178
<> 144:ef7eb2e8f9f7 179 /** @endcond */
<> 144:ef7eb2e8f9f7 180
<> 144:ef7eb2e8f9f7 181
<> 144:ef7eb2e8f9f7 182 /*******************************************************************************
<> 144:ef7eb2e8f9f7 183 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 184 ******************************************************************************/
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 187
<> 144:ef7eb2e8f9f7 188 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 189 * @brief
<> 144:ef7eb2e8f9f7 190 * Restore oscillators and core clock after having been in EM2 or EM3.
<> 144:ef7eb2e8f9f7 191 ******************************************************************************/
<> 144:ef7eb2e8f9f7 192 static void emuRestore(void)
<> 144:ef7eb2e8f9f7 193 {
<> 144:ef7eb2e8f9f7 194 uint32_t oscEnCmd;
<> 144:ef7eb2e8f9f7 195 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 196
<> 144:ef7eb2e8f9f7 197 /* Although we could use the CMU API for most of the below handling, we */
<> 144:ef7eb2e8f9f7 198 /* would like this function to be as efficient as possible. */
<> 144:ef7eb2e8f9f7 199
<> 144:ef7eb2e8f9f7 200 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 201 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 202 CMU_Unlock();
<> 144:ef7eb2e8f9f7 203
<> 144:ef7eb2e8f9f7 204 /* AUXHFRCO are automatically disabled (except if using debugger). */
<> 144:ef7eb2e8f9f7 205 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
<> 144:ef7eb2e8f9f7 206 /* LFRCO/LFXO may be disabled by SW in EM3. */
<> 144:ef7eb2e8f9f7 207 /* Restore according to status prior to entering energy mode. */
<> 144:ef7eb2e8f9f7 208 oscEnCmd = 0;
<> 144:ef7eb2e8f9f7 209 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
<> 144:ef7eb2e8f9f7 210 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 211 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
<> 144:ef7eb2e8f9f7 212 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
<> 144:ef7eb2e8f9f7 213 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
<> 144:ef7eb2e8f9f7 214 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
<> 144:ef7eb2e8f9f7 215 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 216 #endif
<> 144:ef7eb2e8f9f7 217 CMU->OSCENCMD = oscEnCmd;
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219
<> 144:ef7eb2e8f9f7 220 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 221 /* Restore oscillator used for clocking core */
<> 144:ef7eb2e8f9f7 222 switch (cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 223 {
<> 144:ef7eb2e8f9f7 224 case CMU_HFCLKSTATUS_SELECTED_LFRCO:
<> 144:ef7eb2e8f9f7 225 /* HFRCO could only be selected if the autostart HFXO feature is not
<> 144:ef7eb2e8f9f7 226 * enabled, otherwise the HFXO would be started and selected automatically.
<> 144:ef7eb2e8f9f7 227 * Note: this error hook helps catching erroneous oscillator configurations,
<> 144:ef7eb2e8f9f7 228 * when the AUTOSTARTSELEM0EM1 is set in CMU_HFXOCTRL. */
<> 144:ef7eb2e8f9f7 229 if (!(CMU->HFXOCTRL & CMU_HFXOCTRL_AUTOSTARTSELEM0EM1))
<> 144:ef7eb2e8f9f7 230 {
<> 144:ef7eb2e8f9f7 231 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 232 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 233 ;
<> 144:ef7eb2e8f9f7 234 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFRCO;
<> 144:ef7eb2e8f9f7 235 }
<> 144:ef7eb2e8f9f7 236 else
<> 144:ef7eb2e8f9f7 237 {
<> 144:ef7eb2e8f9f7 238 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 239 }
<> 144:ef7eb2e8f9f7 240 break;
<> 144:ef7eb2e8f9f7 241
<> 144:ef7eb2e8f9f7 242 case CMU_HFCLKSTATUS_SELECTED_LFXO:
<> 144:ef7eb2e8f9f7 243 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 244 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 245 ;
<> 144:ef7eb2e8f9f7 246 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFXO;
<> 144:ef7eb2e8f9f7 247 break;
<> 144:ef7eb2e8f9f7 248
<> 144:ef7eb2e8f9f7 249 case CMU_HFCLKSTATUS_SELECTED_HFXO:
<> 144:ef7eb2e8f9f7 250 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 251 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 252 ;
<> 150:02e0a0aed4ec 253 #if defined( _CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_MASK )
<> 150:02e0a0aed4ec 254 if (BUS_RegMaskedRead(&CMU->HFXOCTRL,
<> 150:02e0a0aed4ec 255 _CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_MASK)
<> 150:02e0a0aed4ec 256 == CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_AUTOCMD)
<> 150:02e0a0aed4ec 257 {
<> 150:02e0a0aed4ec 258 while (BUS_RegMaskedRead(&CMU->STATUS,
<> 150:02e0a0aed4ec 259 _CMU_STATUS_HFXOSHUNTOPTRDY_MASK
<> 150:02e0a0aed4ec 260 | _CMU_STATUS_HFXOPEAKDETRDY_MASK)
<> 150:02e0a0aed4ec 261 != (CMU_STATUS_HFXOSHUNTOPTRDY | CMU_STATUS_HFXOPEAKDETRDY))
<> 150:02e0a0aed4ec 262 ;
<> 150:02e0a0aed4ec 263 }
<> 150:02e0a0aed4ec 264 #endif
<> 144:ef7eb2e8f9f7 265 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO;
<> 144:ef7eb2e8f9f7 266 break;
<> 144:ef7eb2e8f9f7 267
<> 144:ef7eb2e8f9f7 268 default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
<> 144:ef7eb2e8f9f7 269 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 270 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 271 break;
<> 144:ef7eb2e8f9f7 272 }
<> 144:ef7eb2e8f9f7 273 #else
<> 144:ef7eb2e8f9f7 274 switch (cmuStatus & (CMU_STATUS_HFRCOSEL
<> 144:ef7eb2e8f9f7 275 | CMU_STATUS_HFXOSEL
<> 144:ef7eb2e8f9f7 276 | CMU_STATUS_LFRCOSEL
<> 144:ef7eb2e8f9f7 277 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 278 | CMU_STATUS_USHFRCODIV2SEL
<> 144:ef7eb2e8f9f7 279 #endif
<> 144:ef7eb2e8f9f7 280 | CMU_STATUS_LFXOSEL))
<> 144:ef7eb2e8f9f7 281 {
<> 144:ef7eb2e8f9f7 282 case CMU_STATUS_LFRCOSEL:
<> 144:ef7eb2e8f9f7 283 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 284 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 285 ;
<> 144:ef7eb2e8f9f7 286 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
<> 144:ef7eb2e8f9f7 287 break;
<> 144:ef7eb2e8f9f7 288
<> 144:ef7eb2e8f9f7 289 case CMU_STATUS_LFXOSEL:
<> 144:ef7eb2e8f9f7 290 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 291 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 292 ;
<> 144:ef7eb2e8f9f7 293 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
<> 144:ef7eb2e8f9f7 294 break;
<> 144:ef7eb2e8f9f7 295
<> 144:ef7eb2e8f9f7 296 case CMU_STATUS_HFXOSEL:
<> 144:ef7eb2e8f9f7 297 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 298 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 299 ;
<> 144:ef7eb2e8f9f7 300 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
<> 144:ef7eb2e8f9f7 301 break;
<> 144:ef7eb2e8f9f7 302
<> 144:ef7eb2e8f9f7 303 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 304 case CMU_STATUS_USHFRCODIV2SEL:
<> 144:ef7eb2e8f9f7 305 /* Wait for USHFRCO to stabilize */
<> 144:ef7eb2e8f9f7 306 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
<> 144:ef7eb2e8f9f7 307 ;
<> 144:ef7eb2e8f9f7 308 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
<> 144:ef7eb2e8f9f7 309 break;
<> 144:ef7eb2e8f9f7 310 #endif
<> 144:ef7eb2e8f9f7 311
<> 144:ef7eb2e8f9f7 312 default: /* CMU_STATUS_HFRCOSEL */
<> 144:ef7eb2e8f9f7 313 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 314 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 315 break;
<> 144:ef7eb2e8f9f7 316 }
<> 144:ef7eb2e8f9f7 317
<> 144:ef7eb2e8f9f7 318 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
<> 144:ef7eb2e8f9f7 319 /* as it is automatically enabled by wake up */
<> 144:ef7eb2e8f9f7 320 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
<> 144:ef7eb2e8f9f7 321 {
<> 144:ef7eb2e8f9f7 322 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
<> 144:ef7eb2e8f9f7 323 }
<> 144:ef7eb2e8f9f7 324 #endif
<> 144:ef7eb2e8f9f7 325 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 326 if (cmuLocked)
<> 144:ef7eb2e8f9f7 327 {
<> 144:ef7eb2e8f9f7 328 CMU_Lock();
<> 144:ef7eb2e8f9f7 329 }
<> 144:ef7eb2e8f9f7 330 }
<> 144:ef7eb2e8f9f7 331
<> 144:ef7eb2e8f9f7 332
<> 144:ef7eb2e8f9f7 333 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 334 /* Get enable conditions for errata EMU_E107 fix. */
<> 150:02e0a0aed4ec 335 __STATIC_INLINE bool getErrataFixEmuE107En(void)
<> 144:ef7eb2e8f9f7 336 {
<> 144:ef7eb2e8f9f7 337 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a
<> 144:ef7eb2e8f9f7 338 * faster implementation in this case.
<> 144:ef7eb2e8f9f7 339 */
<> 144:ef7eb2e8f9f7 340 uint16_t majorMinorRev;
<> 144:ef7eb2e8f9f7 341
<> 144:ef7eb2e8f9f7 342 /* CHIP MAJOR bit [3:0] */
<> 144:ef7eb2e8f9f7 343 majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
<> 144:ef7eb2e8f9f7 344 >> _ROMTABLE_PID0_REVMAJOR_SHIFT)
<> 144:ef7eb2e8f9f7 345 << 8;
<> 144:ef7eb2e8f9f7 346 /* CHIP MINOR bit [7:4] */
<> 144:ef7eb2e8f9f7 347 majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
<> 144:ef7eb2e8f9f7 348 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT)
<> 144:ef7eb2e8f9f7 349 << 4;
<> 144:ef7eb2e8f9f7 350 /* CHIP MINOR bit [3:0] */
<> 144:ef7eb2e8f9f7 351 majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
<> 144:ef7eb2e8f9f7 352 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT;
<> 144:ef7eb2e8f9f7 353
<> 144:ef7eb2e8f9f7 354 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 355 return (majorMinorRev <= 0x0103);
<> 144:ef7eb2e8f9f7 356 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 357 return (majorMinorRev <= 0x0102);
<> 144:ef7eb2e8f9f7 358 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 359 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
<> 144:ef7eb2e8f9f7 360 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 361 return (majorMinorRev == 0x0100);
<> 144:ef7eb2e8f9f7 362 #else
<> 144:ef7eb2e8f9f7 363 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 364 return false;
<> 144:ef7eb2e8f9f7 365 #endif
<> 144:ef7eb2e8f9f7 366 }
<> 144:ef7eb2e8f9f7 367 #endif
<> 144:ef7eb2e8f9f7 368
<> 144:ef7eb2e8f9f7 369 /* LP prepare / LN restore P/NFET count */
<> 144:ef7eb2e8f9f7 370 #define DCDC_LP_PFET_CNT 7
<> 150:02e0a0aed4ec 371 #define DCDC_LP_NFET_CNT 7
<> 150:02e0a0aed4ec 372 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 150:02e0a0aed4ec 373 static void currentLimitersUpdate(void);
<> 150:02e0a0aed4ec 374 static void dcdcFetCntSet(bool lpModeSet)
<> 144:ef7eb2e8f9f7 375 {
<> 144:ef7eb2e8f9f7 376 uint32_t tmp;
<> 144:ef7eb2e8f9f7 377 static uint32_t emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 378
<> 144:ef7eb2e8f9f7 379 if (lpModeSet)
<> 144:ef7eb2e8f9f7 380 {
<> 144:ef7eb2e8f9f7 381 emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;
<> 144:ef7eb2e8f9f7 382 tmp = EMU->DCDCMISCCTRL
<> 144:ef7eb2e8f9f7 383 & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);
<> 144:ef7eb2e8f9f7 384 tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)
<> 144:ef7eb2e8f9f7 385 | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 386 EMU->DCDCMISCCTRL = tmp;
<> 150:02e0a0aed4ec 387 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 388 }
<> 144:ef7eb2e8f9f7 389 else
<> 144:ef7eb2e8f9f7 390 {
<> 144:ef7eb2e8f9f7 391 EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;
<> 150:02e0a0aed4ec 392 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 393 }
<> 144:ef7eb2e8f9f7 394 }
<> 150:02e0a0aed4ec 395 #endif
<> 144:ef7eb2e8f9f7 396
<> 150:02e0a0aed4ec 397 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 150:02e0a0aed4ec 398 static void dcdcHsFixLnBlock(void)
<> 144:ef7eb2e8f9f7 399 {
<> 144:ef7eb2e8f9f7 400 #define EMU_DCDCSTATUS (* (volatile uint32_t *)(EMU_BASE + 0x7C))
<> 150:02e0a0aed4ec 401 if ((errataFixDcdcHsState == errataFixDcdcHsTrimSet)
<> 150:02e0a0aed4ec 402 || (errataFixDcdcHsState == errataFixDcdcHsBypassLn))
<> 144:ef7eb2e8f9f7 403 {
<> 144:ef7eb2e8f9f7 404 /* Wait for LNRUNNING */
<> 150:02e0a0aed4ec 405 if ((EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
<> 144:ef7eb2e8f9f7 406 {
<> 144:ef7eb2e8f9f7 407 while (!(EMU_DCDCSTATUS & (0x1 << 16)));
<> 144:ef7eb2e8f9f7 408 }
<> 144:ef7eb2e8f9f7 409 errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;
<> 144:ef7eb2e8f9f7 410 }
<> 144:ef7eb2e8f9f7 411 }
<> 144:ef7eb2e8f9f7 412 #endif
<> 144:ef7eb2e8f9f7 413
<> 144:ef7eb2e8f9f7 414
<> 150:02e0a0aed4ec 415
<> 144:ef7eb2e8f9f7 416 /** @endcond */
<> 144:ef7eb2e8f9f7 417
<> 144:ef7eb2e8f9f7 418
<> 144:ef7eb2e8f9f7 419 /*******************************************************************************
<> 144:ef7eb2e8f9f7 420 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 421 ******************************************************************************/
<> 144:ef7eb2e8f9f7 422
<> 144:ef7eb2e8f9f7 423 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 424 * @brief
<> 144:ef7eb2e8f9f7 425 * Enter energy mode 2 (EM2).
<> 144:ef7eb2e8f9f7 426 *
<> 144:ef7eb2e8f9f7 427 * @details
<> 144:ef7eb2e8f9f7 428 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
<> 144:ef7eb2e8f9f7 429 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
<> 144:ef7eb2e8f9f7 430 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
<> 144:ef7eb2e8f9f7 431 * HFRCO band. This ensures a quick wakeup from EM2.
<> 144:ef7eb2e8f9f7 432 *
<> 144:ef7eb2e8f9f7 433 * However, prior to entering EM2, the core may have been using another
<> 144:ef7eb2e8f9f7 434 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 435 * to restore all HF oscillators according to state prior to entering EM2,
<> 144:ef7eb2e8f9f7 436 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 437 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 438 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 439 *
<> 144:ef7eb2e8f9f7 440 * @note
<> 144:ef7eb2e8f9f7 441 * If restoring core clock to use the HFXO oscillator, which has been
<> 144:ef7eb2e8f9f7 442 * disabled during EM2 mode, this function will stall until the oscillator
<> 144:ef7eb2e8f9f7 443 * has stabilized. Stalling time can be reduced by adding interrupt
<> 144:ef7eb2e8f9f7 444 * support detecting stable oscillator, and an asynchronous switch to the
<> 144:ef7eb2e8f9f7 445 * original oscillator. See CMU documentation. Such a feature is however
<> 144:ef7eb2e8f9f7 446 * outside the scope of the implementation in this function.
<> 144:ef7eb2e8f9f7 447 * @par
<> 144:ef7eb2e8f9f7 448 * If HFXO is re-enabled by this function, and NOT used to clock the core,
<> 144:ef7eb2e8f9f7 449 * this function will not wait for HFXO to stabilize. This must be considered
<> 144:ef7eb2e8f9f7 450 * by the application if trying to use features relying on that oscillator
<> 144:ef7eb2e8f9f7 451 * upon return.
<> 144:ef7eb2e8f9f7 452 * @par
<> 144:ef7eb2e8f9f7 453 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 454 * upon entering EM2. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 455 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 456 * @par
<> 144:ef7eb2e8f9f7 457 * If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
<> 144:ef7eb2e8f9f7 458 * the starting and selecting of the core clocks will be identical to the user
<> 144:ef7eb2e8f9f7 459 * independently of the value of the @p restore parameter when waking up on
<> 144:ef7eb2e8f9f7 460 * the wakeup sources corresponding to the autostart and select setting.
<> 144:ef7eb2e8f9f7 461 *
<> 144:ef7eb2e8f9f7 462 * @param[in] restore
<> 144:ef7eb2e8f9f7 463 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 464 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 465 * @par
<> 144:ef7eb2e8f9f7 466 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 467 * via the CMU API.
<> 144:ef7eb2e8f9f7 468 ******************************************************************************/
<> 144:ef7eb2e8f9f7 469 void EMU_EnterEM2(bool restore)
<> 144:ef7eb2e8f9f7 470 {
<> 144:ef7eb2e8f9f7 471 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 472 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 473 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 474 #endif
<> 144:ef7eb2e8f9f7 475
<> 144:ef7eb2e8f9f7 476 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 477 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 478 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 479 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 480 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 481 #endif
<> 144:ef7eb2e8f9f7 482
<> 144:ef7eb2e8f9f7 483 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 484 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 487 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 488 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 489 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 490 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 491 {
<> 144:ef7eb2e8f9f7 492 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 493 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 494 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 495 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 496 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 497 #endif
<> 144:ef7eb2e8f9f7 498 }
<> 144:ef7eb2e8f9f7 499 #endif
<> 144:ef7eb2e8f9f7 500
<> 150:02e0a0aed4ec 501 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 502 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 503 #endif
<> 150:02e0a0aed4ec 504 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 505 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 506 #endif
<> 150:02e0a0aed4ec 507 #if defined( ERRATA_FIX_BYPLIMEN_TIMING_EN )
<> 150:02e0a0aed4ec 508 BUS_RegBitWrite(EMU_DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, 0);
<> 150:02e0a0aed4ec 509 #endif
<> 144:ef7eb2e8f9f7 510
<> 144:ef7eb2e8f9f7 511 __WFI();
<> 144:ef7eb2e8f9f7 512
<> 150:02e0a0aed4ec 513 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 514 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 515 #endif
<> 144:ef7eb2e8f9f7 516
<> 144:ef7eb2e8f9f7 517 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 518 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 519 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 520 {
<> 144:ef7eb2e8f9f7 521 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 522 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 523 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 524 #endif
<> 144:ef7eb2e8f9f7 525 }
<> 144:ef7eb2e8f9f7 526 #endif
<> 144:ef7eb2e8f9f7 527
<> 144:ef7eb2e8f9f7 528 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 529 if (restore)
<> 144:ef7eb2e8f9f7 530 {
<> 144:ef7eb2e8f9f7 531 emuRestore();
<> 144:ef7eb2e8f9f7 532 }
<> 144:ef7eb2e8f9f7 533 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 534 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 535 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 536 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 537 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 538 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 539 #else
<> 144:ef7eb2e8f9f7 540 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 541 #endif
<> 144:ef7eb2e8f9f7 542 {
<> 144:ef7eb2e8f9f7 543 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 544 }
<> 144:ef7eb2e8f9f7 545 }
<> 144:ef7eb2e8f9f7 546
<> 144:ef7eb2e8f9f7 547
<> 144:ef7eb2e8f9f7 548 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 549 * @brief
<> 144:ef7eb2e8f9f7 550 * Enter energy mode 3 (EM3).
<> 144:ef7eb2e8f9f7 551 *
<> 144:ef7eb2e8f9f7 552 * @details
<> 144:ef7eb2e8f9f7 553 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
<> 144:ef7eb2e8f9f7 554 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
<> 144:ef7eb2e8f9f7 555 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
<> 144:ef7eb2e8f9f7 556 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
<> 144:ef7eb2e8f9f7 557 * configured HFRCO band. This ensures a quick wakeup from EM3.
<> 144:ef7eb2e8f9f7 558 *
<> 144:ef7eb2e8f9f7 559 * However, prior to entering EM3, the core may have been using another
<> 144:ef7eb2e8f9f7 560 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 561 * to restore all HF/LF oscillators according to state prior to entering EM3,
<> 144:ef7eb2e8f9f7 562 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 563 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 564 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 565 *
<> 144:ef7eb2e8f9f7 566 * @note
<> 144:ef7eb2e8f9f7 567 * If restoring core clock to use an oscillator other than HFRCO, this
<> 144:ef7eb2e8f9f7 568 * function will stall until the oscillator has stabilized. Stalling time
<> 144:ef7eb2e8f9f7 569 * can be reduced by adding interrupt support detecting stable oscillator,
<> 144:ef7eb2e8f9f7 570 * and an asynchronous switch to the original oscillator. See CMU
<> 144:ef7eb2e8f9f7 571 * documentation. Such a feature is however outside the scope of the
<> 144:ef7eb2e8f9f7 572 * implementation in this function.
<> 144:ef7eb2e8f9f7 573 * @par
<> 144:ef7eb2e8f9f7 574 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
<> 144:ef7eb2e8f9f7 575 * the core, this function will not wait for those oscillators to stabilize.
<> 144:ef7eb2e8f9f7 576 * This must be considered by the application if trying to use features
<> 144:ef7eb2e8f9f7 577 * relying on those oscillators upon return.
<> 144:ef7eb2e8f9f7 578 * @par
<> 144:ef7eb2e8f9f7 579 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 580 * upon entering EM3. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 581 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 582 *
<> 144:ef7eb2e8f9f7 583 * @param[in] restore
<> 144:ef7eb2e8f9f7 584 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 585 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 586 * @par
<> 144:ef7eb2e8f9f7 587 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 588 * via the CMU API.
<> 144:ef7eb2e8f9f7 589 ******************************************************************************/
<> 144:ef7eb2e8f9f7 590 void EMU_EnterEM3(bool restore)
<> 144:ef7eb2e8f9f7 591 {
<> 144:ef7eb2e8f9f7 592 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 593
<> 144:ef7eb2e8f9f7 594 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 595 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 596 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 597 #endif
<> 144:ef7eb2e8f9f7 598
<> 144:ef7eb2e8f9f7 599 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 600 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 601 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 602 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 603 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 604 #endif
<> 144:ef7eb2e8f9f7 605
<> 144:ef7eb2e8f9f7 606 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 607 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 608 CMU_Unlock();
<> 144:ef7eb2e8f9f7 609
<> 144:ef7eb2e8f9f7 610 /* Disable LF oscillators */
<> 144:ef7eb2e8f9f7 611 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
<> 144:ef7eb2e8f9f7 612
<> 144:ef7eb2e8f9f7 613 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 614 if (cmuLocked)
<> 144:ef7eb2e8f9f7 615 {
<> 144:ef7eb2e8f9f7 616 CMU_Lock();
<> 144:ef7eb2e8f9f7 617 }
<> 144:ef7eb2e8f9f7 618
<> 144:ef7eb2e8f9f7 619 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 620 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 621
<> 144:ef7eb2e8f9f7 622 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 623 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 624 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 625 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 626 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 627 {
<> 144:ef7eb2e8f9f7 628 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 629 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 630 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 631 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 632 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 633 #endif
<> 144:ef7eb2e8f9f7 634 }
<> 144:ef7eb2e8f9f7 635 #endif
<> 144:ef7eb2e8f9f7 636
<> 150:02e0a0aed4ec 637 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 638 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 639 #endif
<> 150:02e0a0aed4ec 640 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 641 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 642 #endif
<> 150:02e0a0aed4ec 643 #if defined( ERRATA_FIX_BYPLIMEN_TIMING_EN )
<> 150:02e0a0aed4ec 644 BUS_RegBitWrite(EMU_DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, 0);
<> 150:02e0a0aed4ec 645 #endif
<> 144:ef7eb2e8f9f7 646
<> 144:ef7eb2e8f9f7 647 __WFI();
<> 144:ef7eb2e8f9f7 648
<> 150:02e0a0aed4ec 649 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 650 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 651 #endif
<> 144:ef7eb2e8f9f7 652
<> 144:ef7eb2e8f9f7 653 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 654 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 655 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 656 {
<> 144:ef7eb2e8f9f7 657 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 658 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 659 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 660 #endif
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 #endif
<> 144:ef7eb2e8f9f7 663
<> 144:ef7eb2e8f9f7 664 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 665 if (restore)
<> 144:ef7eb2e8f9f7 666 {
<> 144:ef7eb2e8f9f7 667 emuRestore();
<> 144:ef7eb2e8f9f7 668 }
<> 144:ef7eb2e8f9f7 669 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 670 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 671 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 672 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 673 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 674 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 675 #else
<> 144:ef7eb2e8f9f7 676 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 677 #endif
<> 144:ef7eb2e8f9f7 678 {
<> 144:ef7eb2e8f9f7 679 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 680 }
<> 144:ef7eb2e8f9f7 681 }
<> 144:ef7eb2e8f9f7 682
<> 144:ef7eb2e8f9f7 683
<> 144:ef7eb2e8f9f7 684 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 685 * @brief
<> 144:ef7eb2e8f9f7 686 * Enter energy mode 4 (EM4).
<> 144:ef7eb2e8f9f7 687 *
<> 144:ef7eb2e8f9f7 688 * @note
<> 144:ef7eb2e8f9f7 689 * Only a power on reset or external reset pin can wake the device from EM4.
<> 144:ef7eb2e8f9f7 690 ******************************************************************************/
<> 144:ef7eb2e8f9f7 691 void EMU_EnterEM4(void)
<> 144:ef7eb2e8f9f7 692 {
<> 144:ef7eb2e8f9f7 693 int i;
<> 144:ef7eb2e8f9f7 694
<> 144:ef7eb2e8f9f7 695 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 696 uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 697 | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 698 uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 699 | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 700 #else
<> 144:ef7eb2e8f9f7 701 uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 702 | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 703 uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 704 | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 705 #endif
<> 144:ef7eb2e8f9f7 706
<> 144:ef7eb2e8f9f7 707 /* Make sure register write lock is disabled */
<> 144:ef7eb2e8f9f7 708 EMU_Unlock();
<> 144:ef7eb2e8f9f7 709
<> 150:02e0a0aed4ec 710 #if defined( _EMU_EM4CTRL_MASK )
<> 150:02e0a0aed4ec 711 if ((EMU->EM4CTRL & _EMU_EM4CTRL_EM4STATE_MASK) == EMU_EM4CTRL_EM4STATE_EM4S)
<> 150:02e0a0aed4ec 712 {
<> 150:02e0a0aed4ec 713 uint32_t dcdcMode = EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK;
<> 150:02e0a0aed4ec 714 if (dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWNOISE
<> 150:02e0a0aed4ec 715 || dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWPOWER)
<> 150:02e0a0aed4ec 716 {
<> 150:02e0a0aed4ec 717 /* DCDC is not supported in EM4S so we switch DCDC to bypass mode before
<> 150:02e0a0aed4ec 718 * entering EM4S */
<> 150:02e0a0aed4ec 719 EMU_DCDCModeSet(emuDcdcMode_Bypass);
<> 150:02e0a0aed4ec 720 }
<> 150:02e0a0aed4ec 721 }
<> 150:02e0a0aed4ec 722 #endif
<> 150:02e0a0aed4ec 723
<> 150:02e0a0aed4ec 724 #if defined( _EMU_EM4CTRL_MASK ) && defined( ERRATA_FIX_EMU_E208_EN )
<> 150:02e0a0aed4ec 725 if (EMU->EM4CTRL & EMU_EM4CTRL_EM4STATE_EM4H)
<> 150:02e0a0aed4ec 726 {
<> 150:02e0a0aed4ec 727 /* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H.
<> 150:02e0a0aed4ec 728 * Full description of errata fix can be found in the errata document. */
<> 150:02e0a0aed4ec 729 __disable_irq();
<> 150:02e0a0aed4ec 730 *(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0000ADE8UL;
<> 150:02e0a0aed4ec 731 *(volatile uint32_t *)(EMU_BASE + 0x198) |= (0x1UL << 7);
<> 150:02e0a0aed4ec 732 *(volatile uint32_t *)(EMU_BASE + 0x88) |= (0x1UL << 8);
<> 150:02e0a0aed4ec 733 }
<> 150:02e0a0aed4ec 734 #endif
<> 150:02e0a0aed4ec 735
<> 144:ef7eb2e8f9f7 736 #if defined( ERRATA_FIX_EMU_E108_EN )
<> 144:ef7eb2e8f9f7 737 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 738 __disable_irq();
<> 144:ef7eb2e8f9f7 739 *(volatile uint32_t *)0x400C80E4 = 0;
<> 144:ef7eb2e8f9f7 740 #endif
<> 144:ef7eb2e8f9f7 741
<> 150:02e0a0aed4ec 742 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 743 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 744 #endif
<> 150:02e0a0aed4ec 745 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 746 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 747 #endif
<> 150:02e0a0aed4ec 748 #if defined( ERRATA_FIX_BYPLIMEN_TIMING_EN )
<> 150:02e0a0aed4ec 749 BUS_RegBitWrite(EMU_DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, 0);
<> 150:02e0a0aed4ec 750 #endif
<> 144:ef7eb2e8f9f7 751
<> 144:ef7eb2e8f9f7 752 for (i = 0; i < 4; i++)
<> 144:ef7eb2e8f9f7 753 {
<> 144:ef7eb2e8f9f7 754 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 755 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 756 EMU->EM4CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 757 }
<> 144:ef7eb2e8f9f7 758 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 759 #else
<> 144:ef7eb2e8f9f7 760 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 761 EMU->CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 762 }
<> 144:ef7eb2e8f9f7 763 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 764 #endif
<> 144:ef7eb2e8f9f7 765 }
<> 144:ef7eb2e8f9f7 766
<> 150:02e0a0aed4ec 767 #if defined( _EMU_EM4CTRL_MASK )
<> 150:02e0a0aed4ec 768 /***************************************************************************//**
<> 150:02e0a0aed4ec 769 * @brief
<> 150:02e0a0aed4ec 770 * Enter energy mode 4 hibernate (EM4H).
<> 150:02e0a0aed4ec 771 *
<> 150:02e0a0aed4ec 772 * @note
<> 150:02e0a0aed4ec 773 * Retention of clocks and GPIO in EM4 can be configured using
<> 150:02e0a0aed4ec 774 * @ref EMU_EM4Init before calling this function.
<> 150:02e0a0aed4ec 775 ******************************************************************************/
<> 150:02e0a0aed4ec 776 void EMU_EnterEM4H(void)
<> 150:02e0a0aed4ec 777 {
<> 150:02e0a0aed4ec 778 BUS_RegBitWrite(&EMU->EM4CTRL, _EMU_EM4CTRL_EM4STATE_SHIFT, 1);
<> 150:02e0a0aed4ec 779 EMU_EnterEM4();
<> 150:02e0a0aed4ec 780 }
<> 150:02e0a0aed4ec 781
<> 150:02e0a0aed4ec 782 /***************************************************************************//**
<> 150:02e0a0aed4ec 783 * @brief
<> 150:02e0a0aed4ec 784 * Enter energy mode 4 shutoff (EM4S).
<> 150:02e0a0aed4ec 785 *
<> 150:02e0a0aed4ec 786 * @note
<> 150:02e0a0aed4ec 787 * Retention of clocks and GPIO in EM4 can be configured using
<> 150:02e0a0aed4ec 788 * @ref EMU_EM4Init before calling this function.
<> 150:02e0a0aed4ec 789 ******************************************************************************/
<> 150:02e0a0aed4ec 790 void EMU_EnterEM4S(void)
<> 150:02e0a0aed4ec 791 {
<> 150:02e0a0aed4ec 792 BUS_RegBitWrite(&EMU->EM4CTRL, _EMU_EM4CTRL_EM4STATE_SHIFT, 0);
<> 150:02e0a0aed4ec 793 EMU_EnterEM4();
<> 150:02e0a0aed4ec 794 }
<> 150:02e0a0aed4ec 795 #endif
<> 144:ef7eb2e8f9f7 796
<> 144:ef7eb2e8f9f7 797 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 798 * @brief
<> 144:ef7eb2e8f9f7 799 * Power down memory block.
<> 144:ef7eb2e8f9f7 800 *
<> 144:ef7eb2e8f9f7 801 * @param[in] blocks
<> 144:ef7eb2e8f9f7 802 * Specifies a logical OR of bits indicating memory blocks to power down.
<> 144:ef7eb2e8f9f7 803 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
<> 144:ef7eb2e8f9f7 804 * be disabled. Please refer to the reference manual for available
<> 144:ef7eb2e8f9f7 805 * memory blocks for a device.
<> 144:ef7eb2e8f9f7 806 *
<> 144:ef7eb2e8f9f7 807 * @note
<> 144:ef7eb2e8f9f7 808 * Only a reset can make the specified memory block(s) available for use
<> 144:ef7eb2e8f9f7 809 * after having been powered down. Function will be void for devices not
<> 144:ef7eb2e8f9f7 810 * supporting this feature.
<> 144:ef7eb2e8f9f7 811 ******************************************************************************/
<> 144:ef7eb2e8f9f7 812 void EMU_MemPwrDown(uint32_t blocks)
<> 144:ef7eb2e8f9f7 813 {
<> 144:ef7eb2e8f9f7 814 #if defined( _EMU_MEMCTRL_POWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 815 EFM_ASSERT(blocks <= (_EMU_MEMCTRL_POWERDOWN_MASK
<> 144:ef7eb2e8f9f7 816 >> _EMU_MEMCTRL_POWERDOWN_SHIFT));
<> 144:ef7eb2e8f9f7 817 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 818
<> 144:ef7eb2e8f9f7 819 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 820 && defined( _EMU_MEMCTRL_RAMHPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 821 && defined( _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 822 EFM_ASSERT((blocks & (_EMU_MEMCTRL_RAMPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 823 | _EMU_MEMCTRL_RAMHPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 824 | _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK))
<> 144:ef7eb2e8f9f7 825 == blocks);
<> 144:ef7eb2e8f9f7 826 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 827
<> 144:ef7eb2e8f9f7 828 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 829 EFM_ASSERT((blocks & _EMU_MEMCTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 830 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 831
<> 144:ef7eb2e8f9f7 832 #elif defined( _EMU_RAM0CTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 833 EFM_ASSERT((blocks & _EMU_RAM0CTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 834 EMU->RAM0CTRL = blocks;
<> 144:ef7eb2e8f9f7 835
<> 144:ef7eb2e8f9f7 836 #else
<> 144:ef7eb2e8f9f7 837 (void)blocks;
<> 144:ef7eb2e8f9f7 838 #endif
<> 144:ef7eb2e8f9f7 839 }
<> 144:ef7eb2e8f9f7 840
<> 144:ef7eb2e8f9f7 841
<> 144:ef7eb2e8f9f7 842 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 843 * @brief
<> 144:ef7eb2e8f9f7 844 * Update EMU module with CMU oscillator selection/enable status.
<> 144:ef7eb2e8f9f7 845 *
<> 144:ef7eb2e8f9f7 846 * @details
<> 144:ef7eb2e8f9f7 847 * When entering EM2 and EM3, the HW may change the core clock oscillator
<> 144:ef7eb2e8f9f7 848 * used, as well as disabling some oscillators. The user may optionally select
<> 144:ef7eb2e8f9f7 849 * to restore the oscillators after waking up from EM2 and EM3 through the
<> 144:ef7eb2e8f9f7 850 * SW API.
<> 144:ef7eb2e8f9f7 851 *
<> 144:ef7eb2e8f9f7 852 * However, in order to support this in a safe way, the EMU module must
<> 144:ef7eb2e8f9f7 853 * be kept up-to-date on the actual selected configuration. The CMU
<> 144:ef7eb2e8f9f7 854 * module must keep the EMU module up-to-date.
<> 144:ef7eb2e8f9f7 855 *
<> 144:ef7eb2e8f9f7 856 * This function is mainly intended for internal use by the CMU module,
<> 144:ef7eb2e8f9f7 857 * but if the applications changes oscillator configurations without
<> 144:ef7eb2e8f9f7 858 * using the CMU API, this function can be used to keep the EMU module
<> 144:ef7eb2e8f9f7 859 * up-to-date.
<> 144:ef7eb2e8f9f7 860 ******************************************************************************/
<> 144:ef7eb2e8f9f7 861 void EMU_UpdateOscConfig(void)
<> 144:ef7eb2e8f9f7 862 {
<> 144:ef7eb2e8f9f7 863 /* Fetch current configuration */
<> 144:ef7eb2e8f9f7 864 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 865 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 866 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 867 #endif
<> 144:ef7eb2e8f9f7 868 }
<> 144:ef7eb2e8f9f7 869
<> 144:ef7eb2e8f9f7 870
<> 144:ef7eb2e8f9f7 871 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 872 * @brief
<> 144:ef7eb2e8f9f7 873 * Update EMU module with Energy Mode 2 and 3 configuration
<> 144:ef7eb2e8f9f7 874 *
<> 144:ef7eb2e8f9f7 875 * @param[in] em23Init
<> 144:ef7eb2e8f9f7 876 * Energy Mode 2 and 3 configuration structure
<> 144:ef7eb2e8f9f7 877 ******************************************************************************/
<> 144:ef7eb2e8f9f7 878 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
<> 144:ef7eb2e8f9f7 879 {
<> 144:ef7eb2e8f9f7 880 #if defined( _EMU_CTRL_EMVREG_MASK )
<> 144:ef7eb2e8f9f7 881 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)
<> 144:ef7eb2e8f9f7 882 : (EMU->CTRL & ~EMU_CTRL_EMVREG);
<> 144:ef7eb2e8f9f7 883 #elif defined( _EMU_CTRL_EM23VREG_MASK )
<> 144:ef7eb2e8f9f7 884 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)
<> 144:ef7eb2e8f9f7 885 : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
<> 144:ef7eb2e8f9f7 886 #else
<> 144:ef7eb2e8f9f7 887 (void)em23Init;
<> 144:ef7eb2e8f9f7 888 #endif
<> 144:ef7eb2e8f9f7 889 }
<> 144:ef7eb2e8f9f7 890
<> 144:ef7eb2e8f9f7 891
<> 144:ef7eb2e8f9f7 892 #if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 893 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 894 * @brief
<> 144:ef7eb2e8f9f7 895 * Update EMU module with Energy Mode 4 configuration
<> 144:ef7eb2e8f9f7 896 *
<> 144:ef7eb2e8f9f7 897 * @param[in] em4Init
<> 144:ef7eb2e8f9f7 898 * Energy Mode 4 configuration structure
<> 144:ef7eb2e8f9f7 899 ******************************************************************************/
<> 144:ef7eb2e8f9f7 900 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
<> 144:ef7eb2e8f9f7 901 {
<> 144:ef7eb2e8f9f7 902 #if defined( _EMU_EM4CONF_MASK )
<> 144:ef7eb2e8f9f7 903 /* Init for platforms with EMU->EM4CONF register */
<> 144:ef7eb2e8f9f7 904 uint32_t em4conf = EMU->EM4CONF;
<> 144:ef7eb2e8f9f7 905
<> 144:ef7eb2e8f9f7 906 /* Clear fields that will be reconfigured */
<> 144:ef7eb2e8f9f7 907 em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK
<> 144:ef7eb2e8f9f7 908 | _EMU_EM4CONF_OSC_MASK
<> 144:ef7eb2e8f9f7 909 | _EMU_EM4CONF_BURTCWU_MASK
<> 144:ef7eb2e8f9f7 910 | _EMU_EM4CONF_VREGEN_MASK);
<> 144:ef7eb2e8f9f7 911
<> 144:ef7eb2e8f9f7 912 /* Configure new settings */
<> 144:ef7eb2e8f9f7 913 em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)
<> 144:ef7eb2e8f9f7 914 | (em4Init->osc)
<> 144:ef7eb2e8f9f7 915 | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)
<> 144:ef7eb2e8f9f7 916 | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);
<> 144:ef7eb2e8f9f7 917
<> 144:ef7eb2e8f9f7 918 /* Apply configuration. Note that lock can be set after this stage. */
<> 144:ef7eb2e8f9f7 919 EMU->EM4CONF = em4conf;
<> 144:ef7eb2e8f9f7 920
<> 144:ef7eb2e8f9f7 921 #elif defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 922 /* Init for platforms with EMU->EM4CTRL register */
<> 144:ef7eb2e8f9f7 923
<> 144:ef7eb2e8f9f7 924 uint32_t em4ctrl = EMU->EM4CTRL;
<> 144:ef7eb2e8f9f7 925
<> 144:ef7eb2e8f9f7 926 em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK
<> 144:ef7eb2e8f9f7 927 | _EMU_EM4CTRL_RETAINLFRCO_MASK
<> 144:ef7eb2e8f9f7 928 | _EMU_EM4CTRL_RETAINULFRCO_MASK
<> 144:ef7eb2e8f9f7 929 | _EMU_EM4CTRL_EM4STATE_MASK
<> 144:ef7eb2e8f9f7 930 | _EMU_EM4CTRL_EM4IORETMODE_MASK);
<> 144:ef7eb2e8f9f7 931
<> 150:02e0a0aed4ec 932 em4ctrl |= (em4Init->retainLfxo ? EMU_EM4CTRL_RETAINLFXO : 0)
<> 150:02e0a0aed4ec 933 | (em4Init->retainLfrco ? EMU_EM4CTRL_RETAINLFRCO : 0)
<> 150:02e0a0aed4ec 934 | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)
<> 150:02e0a0aed4ec 935 | (em4Init->em4State ? EMU_EM4CTRL_EM4STATE_EM4H : 0)
<> 150:02e0a0aed4ec 936 | (em4Init->pinRetentionMode);
<> 144:ef7eb2e8f9f7 937
<> 144:ef7eb2e8f9f7 938 EMU->EM4CTRL = em4ctrl;
<> 144:ef7eb2e8f9f7 939 #endif
<> 144:ef7eb2e8f9f7 940 }
<> 144:ef7eb2e8f9f7 941 #endif
<> 144:ef7eb2e8f9f7 942
<> 144:ef7eb2e8f9f7 943
<> 144:ef7eb2e8f9f7 944 #if defined( BU_PRESENT )
<> 144:ef7eb2e8f9f7 945 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 946 * @brief
<> 144:ef7eb2e8f9f7 947 * Configure Backup Power Domain settings
<> 144:ef7eb2e8f9f7 948 *
<> 144:ef7eb2e8f9f7 949 * @param[in] bupdInit
<> 144:ef7eb2e8f9f7 950 * Backup power domain initialization structure
<> 144:ef7eb2e8f9f7 951 ******************************************************************************/
<> 144:ef7eb2e8f9f7 952 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
<> 144:ef7eb2e8f9f7 953 {
<> 144:ef7eb2e8f9f7 954 uint32_t reg;
<> 144:ef7eb2e8f9f7 955
<> 144:ef7eb2e8f9f7 956 /* Set power connection configuration */
<> 144:ef7eb2e8f9f7 957 reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK
<> 144:ef7eb2e8f9f7 958 | _EMU_PWRCONF_VOUTSTRONG_MASK
<> 144:ef7eb2e8f9f7 959 | _EMU_PWRCONF_VOUTMED_MASK
<> 144:ef7eb2e8f9f7 960 | _EMU_PWRCONF_VOUTWEAK_MASK);
<> 144:ef7eb2e8f9f7 961
<> 144:ef7eb2e8f9f7 962 reg |= bupdInit->resistor
<> 144:ef7eb2e8f9f7 963 | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)
<> 144:ef7eb2e8f9f7 964 | (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)
<> 144:ef7eb2e8f9f7 965 | (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT);
<> 144:ef7eb2e8f9f7 966
<> 144:ef7eb2e8f9f7 967 EMU->PWRCONF = reg;
<> 144:ef7eb2e8f9f7 968
<> 144:ef7eb2e8f9f7 969 /* Set backup domain inactive mode configuration */
<> 144:ef7eb2e8f9f7 970 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 971 reg |= (bupdInit->inactivePower);
<> 144:ef7eb2e8f9f7 972 EMU->BUINACT = reg;
<> 144:ef7eb2e8f9f7 973
<> 144:ef7eb2e8f9f7 974 /* Set backup domain active mode configuration */
<> 144:ef7eb2e8f9f7 975 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 976 reg |= (bupdInit->activePower);
<> 144:ef7eb2e8f9f7 977 EMU->BUACT = reg;
<> 144:ef7eb2e8f9f7 978
<> 144:ef7eb2e8f9f7 979 /* Set power control configuration */
<> 144:ef7eb2e8f9f7 980 reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK
<> 144:ef7eb2e8f9f7 981 | _EMU_BUCTRL_BODCAL_MASK
<> 144:ef7eb2e8f9f7 982 | _EMU_BUCTRL_STATEN_MASK
<> 144:ef7eb2e8f9f7 983 | _EMU_BUCTRL_EN_MASK);
<> 144:ef7eb2e8f9f7 984
<> 144:ef7eb2e8f9f7 985 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
<> 144:ef7eb2e8f9f7 986 release reset */
<> 144:ef7eb2e8f9f7 987 reg |= bupdInit->probe
<> 144:ef7eb2e8f9f7 988 | (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)
<> 144:ef7eb2e8f9f7 989 | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)
<> 144:ef7eb2e8f9f7 990 | (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT);
<> 144:ef7eb2e8f9f7 991
<> 144:ef7eb2e8f9f7 992 /* Enable configuration */
<> 144:ef7eb2e8f9f7 993 EMU->BUCTRL = reg;
<> 144:ef7eb2e8f9f7 994
<> 144:ef7eb2e8f9f7 995 /* If enable is true, enable BU_VIN input power pin, if not disable it */
<> 144:ef7eb2e8f9f7 996 EMU_BUPinEnable(bupdInit->enable);
<> 144:ef7eb2e8f9f7 997
<> 144:ef7eb2e8f9f7 998 /* If enable is true, release BU reset, if not keep reset asserted */
<> 144:ef7eb2e8f9f7 999 BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
<> 144:ef7eb2e8f9f7 1000 }
<> 144:ef7eb2e8f9f7 1001
<> 144:ef7eb2e8f9f7 1002
<> 144:ef7eb2e8f9f7 1003 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1004 * @brief
<> 144:ef7eb2e8f9f7 1005 * Configure Backup Power Domain BOD Threshold value
<> 144:ef7eb2e8f9f7 1006 * @note
<> 144:ef7eb2e8f9f7 1007 * These values are precalibrated
<> 144:ef7eb2e8f9f7 1008 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 1009 * @param[in] value
<> 144:ef7eb2e8f9f7 1010 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1011 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 1012 {
<> 144:ef7eb2e8f9f7 1013 EFM_ASSERT(value<8);
<> 144:ef7eb2e8f9f7 1014 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
<> 144:ef7eb2e8f9f7 1015
<> 144:ef7eb2e8f9f7 1016 switch(mode)
<> 144:ef7eb2e8f9f7 1017 {
<> 144:ef7eb2e8f9f7 1018 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 1019 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)
<> 144:ef7eb2e8f9f7 1020 | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 1021 break;
<> 144:ef7eb2e8f9f7 1022 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 1023 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)
<> 144:ef7eb2e8f9f7 1024 | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 1025 break;
<> 144:ef7eb2e8f9f7 1026 }
<> 144:ef7eb2e8f9f7 1027 }
<> 144:ef7eb2e8f9f7 1028
<> 144:ef7eb2e8f9f7 1029
<> 144:ef7eb2e8f9f7 1030 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1031 * @brief
<> 144:ef7eb2e8f9f7 1032 * Configure Backup Power Domain BOD Threshold Range
<> 144:ef7eb2e8f9f7 1033 * @note
<> 144:ef7eb2e8f9f7 1034 * These values are precalibrated
<> 144:ef7eb2e8f9f7 1035 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 1036 * @param[in] value
<> 144:ef7eb2e8f9f7 1037 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1038 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 1039 {
<> 144:ef7eb2e8f9f7 1040 EFM_ASSERT(value < 4);
<> 144:ef7eb2e8f9f7 1041 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
<> 144:ef7eb2e8f9f7 1042
<> 144:ef7eb2e8f9f7 1043 switch(mode)
<> 144:ef7eb2e8f9f7 1044 {
<> 144:ef7eb2e8f9f7 1045 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 1046 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)
<> 144:ef7eb2e8f9f7 1047 | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 1048 break;
<> 144:ef7eb2e8f9f7 1049 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 1050 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)
<> 144:ef7eb2e8f9f7 1051 | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 1052 break;
<> 144:ef7eb2e8f9f7 1053 }
<> 144:ef7eb2e8f9f7 1054 }
<> 144:ef7eb2e8f9f7 1055 #endif
<> 144:ef7eb2e8f9f7 1056
<> 144:ef7eb2e8f9f7 1057
<> 144:ef7eb2e8f9f7 1058 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 1059
<> 150:02e0a0aed4ec 1060 /* Translate fields with different names across platform generations to common names. */
<> 150:02e0a0aed4ec 1061 #if defined( _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK )
<> 150:02e0a0aed4ec 1062 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK
<> 150:02e0a0aed4ec 1063 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT
<> 150:02e0a0aed4ec 1064 #elif defined( _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_MASK )
<> 150:02e0a0aed4ec 1065 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_MASK
<> 150:02e0a0aed4ec 1066 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT
<> 150:02e0a0aed4ec 1067 #endif
<> 150:02e0a0aed4ec 1068 #if defined( _EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK )
<> 150:02e0a0aed4ec 1069 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK _EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK
<> 150:02e0a0aed4ec 1070 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT
<> 150:02e0a0aed4ec 1071 #elif defined( _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK )
<> 150:02e0a0aed4ec 1072 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK
<> 150:02e0a0aed4ec 1073 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT
<> 150:02e0a0aed4ec 1074 #endif
<> 150:02e0a0aed4ec 1075
<> 144:ef7eb2e8f9f7 1076 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 1077
<> 144:ef7eb2e8f9f7 1078 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1079 * @brief
<> 144:ef7eb2e8f9f7 1080 * Load DCDC calibration constants from DI page. Const means calibration
<> 144:ef7eb2e8f9f7 1081 * data that does not change depending on other configuration parameters.
<> 144:ef7eb2e8f9f7 1082 *
<> 144:ef7eb2e8f9f7 1083 * @return
<> 144:ef7eb2e8f9f7 1084 * False if calibration registers are locked
<> 144:ef7eb2e8f9f7 1085 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1086 static bool ConstCalibrationLoad(void)
<> 144:ef7eb2e8f9f7 1087 {
<> 150:02e0a0aed4ec 1088 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 144:ef7eb2e8f9f7 1089 uint32_t val;
<> 144:ef7eb2e8f9f7 1090 volatile uint32_t *reg;
<> 144:ef7eb2e8f9f7 1091
<> 144:ef7eb2e8f9f7 1092 /* DI calib data in flash */
<> 144:ef7eb2e8f9f7 1093 volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL = (volatile uint32_t *)(0x0FE08038);
<> 144:ef7eb2e8f9f7 1094 volatile uint32_t* const diCal_EMU_DCDCLNVCTRL = (volatile uint32_t *)(0x0FE08040);
<> 144:ef7eb2e8f9f7 1095 volatile uint32_t* const diCal_EMU_DCDCLPCTRL = (volatile uint32_t *)(0x0FE08048);
<> 144:ef7eb2e8f9f7 1096 volatile uint32_t* const diCal_EMU_DCDCLPVCTRL = (volatile uint32_t *)(0x0FE08050);
<> 144:ef7eb2e8f9f7 1097 volatile uint32_t* const diCal_EMU_DCDCTRIM0 = (volatile uint32_t *)(0x0FE08058);
<> 144:ef7eb2e8f9f7 1098 volatile uint32_t* const diCal_EMU_DCDCTRIM1 = (volatile uint32_t *)(0x0FE08060);
<> 144:ef7eb2e8f9f7 1099
<> 144:ef7eb2e8f9f7 1100 if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)
<> 144:ef7eb2e8f9f7 1101 {
<> 144:ef7eb2e8f9f7 1102 val = *(diCal_EMU_DCDCLNFREQCTRL + 1);
<> 144:ef7eb2e8f9f7 1103 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;
<> 144:ef7eb2e8f9f7 1104 *reg = val;
<> 144:ef7eb2e8f9f7 1105
<> 144:ef7eb2e8f9f7 1106 val = *(diCal_EMU_DCDCLNVCTRL + 1);
<> 144:ef7eb2e8f9f7 1107 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;
<> 144:ef7eb2e8f9f7 1108 *reg = val;
<> 144:ef7eb2e8f9f7 1109
<> 144:ef7eb2e8f9f7 1110 val = *(diCal_EMU_DCDCLPCTRL + 1);
<> 144:ef7eb2e8f9f7 1111 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;
<> 144:ef7eb2e8f9f7 1112 *reg = val;
<> 144:ef7eb2e8f9f7 1113
<> 144:ef7eb2e8f9f7 1114 val = *(diCal_EMU_DCDCLPVCTRL + 1);
<> 144:ef7eb2e8f9f7 1115 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;
<> 144:ef7eb2e8f9f7 1116 *reg = val;
<> 144:ef7eb2e8f9f7 1117
<> 144:ef7eb2e8f9f7 1118 val = *(diCal_EMU_DCDCTRIM0 + 1);
<> 144:ef7eb2e8f9f7 1119 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;
<> 144:ef7eb2e8f9f7 1120 *reg = val;
<> 144:ef7eb2e8f9f7 1121
<> 144:ef7eb2e8f9f7 1122 val = *(diCal_EMU_DCDCTRIM1 + 1);
<> 144:ef7eb2e8f9f7 1123 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;
<> 144:ef7eb2e8f9f7 1124 *reg = val;
<> 144:ef7eb2e8f9f7 1125
<> 144:ef7eb2e8f9f7 1126 return true;
<> 144:ef7eb2e8f9f7 1127 }
<> 144:ef7eb2e8f9f7 1128 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1129 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1130 return false;
<> 150:02e0a0aed4ec 1131
<> 150:02e0a0aed4ec 1132 #elif defined( _SILICON_LABS_32B_PLATFORM_2_GEN_2 )
<> 150:02e0a0aed4ec 1133 return true;
<> 150:02e0a0aed4ec 1134 #else
<> 150:02e0a0aed4ec 1135 #error "Undefined platform 2 generation."
<> 150:02e0a0aed4ec 1136 return true;
<> 150:02e0a0aed4ec 1137 #endif
<> 144:ef7eb2e8f9f7 1138 }
<> 144:ef7eb2e8f9f7 1139
<> 144:ef7eb2e8f9f7 1140
<> 144:ef7eb2e8f9f7 1141 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1142 * @brief
<> 150:02e0a0aed4ec 1143 * Set recommended and validated current optimization and timing settings
<> 144:ef7eb2e8f9f7 1144 *
<> 144:ef7eb2e8f9f7 1145 ******************************************************************************/
<> 150:02e0a0aed4ec 1146 static void ValidatedConfigSet(void)
<> 144:ef7eb2e8f9f7 1147 {
<> 150:02e0a0aed4ec 1148 /* Disable LP mode hysterysis in the state machine control */
<> 150:02e0a0aed4ec 1149 #define EMU_DCDCMISCCTRL_LPCMPHYSDIS (0x1UL << 1)
<> 150:02e0a0aed4ec 1150 /* Comparator threshold on the high side */
<> 150:02e0a0aed4ec 1151 #define EMU_DCDCMISCCTRL_LPCMPHYSHI (0x1UL << 2)
<> 144:ef7eb2e8f9f7 1152 #define EMU_DCDCSMCTRL (* (volatile uint32_t *)(EMU_BASE + 0x44))
<> 144:ef7eb2e8f9f7 1153
<> 150:02e0a0aed4ec 1154 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 144:ef7eb2e8f9f7 1155 uint32_t dcdcTiming;
<> 144:ef7eb2e8f9f7 1156 SYSTEM_PartFamily_TypeDef family;
<> 144:ef7eb2e8f9f7 1157 SYSTEM_ChipRevision_TypeDef rev;
<> 150:02e0a0aed4ec 1158 #endif
<> 150:02e0a0aed4ec 1159
<> 150:02e0a0aed4ec 1160 uint32_t lnForceCcm = BUS_RegBitRead(&EMU->DCDCMISCCTRL, _EMU_DCDCMISCCTRL_LNFORCECCM_SHIFT);
<> 144:ef7eb2e8f9f7 1161
<> 144:ef7eb2e8f9f7 1162 /* Enable duty cycling of the bias */
<> 144:ef7eb2e8f9f7 1163 EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;
<> 144:ef7eb2e8f9f7 1164
<> 150:02e0a0aed4ec 1165 /* Set low-noise RCO for LNFORCECCM configuration
<> 150:02e0a0aed4ec 1166 * LNFORCECCM is default 1 for EFR32
<> 150:02e0a0aed4ec 1167 * LNFORCECCM is default 0 for EFM32
<> 150:02e0a0aed4ec 1168 */
<> 150:02e0a0aed4ec 1169 if (lnForceCcm)
<> 150:02e0a0aed4ec 1170 {
<> 150:02e0a0aed4ec 1171 /* 7MHz is recommended for LNFORCECCM = 1 */
<> 150:02e0a0aed4ec 1172 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_7MHz);
<> 150:02e0a0aed4ec 1173 }
<> 150:02e0a0aed4ec 1174 else
<> 150:02e0a0aed4ec 1175 {
<> 150:02e0a0aed4ec 1176 /* 3MHz is recommended for LNFORCECCM = 0 */
<> 150:02e0a0aed4ec 1177 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_3MHz);
<> 150:02e0a0aed4ec 1178 }
<> 144:ef7eb2e8f9f7 1179
<> 150:02e0a0aed4ec 1180 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 144:ef7eb2e8f9f7 1181 EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;
<> 150:02e0a0aed4ec 1182 EMU->DCDCMISCCTRL |= EMU_DCDCMISCCTRL_LPCMPHYSDIS
<> 150:02e0a0aed4ec 1183 | EMU_DCDCMISCCTRL_LPCMPHYSHI;
<> 144:ef7eb2e8f9f7 1184
<> 144:ef7eb2e8f9f7 1185 family = SYSTEM_GetFamily();
<> 144:ef7eb2e8f9f7 1186 SYSTEM_ChipRevisionGet(&rev);
<> 144:ef7eb2e8f9f7 1187 if ((((family >= systemPartFamilyMighty1P)
<> 144:ef7eb2e8f9f7 1188 && (family <= systemPartFamilyFlex1V))
<> 144:ef7eb2e8f9f7 1189 || (family == systemPartFamilyEfm32Pearl1B)
<> 144:ef7eb2e8f9f7 1190 || (family == systemPartFamilyEfm32Jade1B))
<> 144:ef7eb2e8f9f7 1191 && ((rev.major == 1) && (rev.minor < 3))
<> 144:ef7eb2e8f9f7 1192 && (errataFixDcdcHsState == errataFixDcdcHsInit))
<> 144:ef7eb2e8f9f7 1193 {
<> 144:ef7eb2e8f9f7 1194 /* LPCMPWAITDIS = 1 */
<> 144:ef7eb2e8f9f7 1195 EMU_DCDCSMCTRL |= 1;
<> 144:ef7eb2e8f9f7 1196
<> 144:ef7eb2e8f9f7 1197 dcdcTiming = EMU->DCDCTIMING;
<> 144:ef7eb2e8f9f7 1198 dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK
<> 144:ef7eb2e8f9f7 1199 |_EMU_DCDCTIMING_LNWAIT_MASK
<> 144:ef7eb2e8f9f7 1200 |_EMU_DCDCTIMING_BYPWAIT_MASK);
<> 144:ef7eb2e8f9f7 1201
<> 144:ef7eb2e8f9f7 1202 dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1203 | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1204 | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));
<> 144:ef7eb2e8f9f7 1205 EMU->DCDCTIMING = dcdcTiming;
<> 144:ef7eb2e8f9f7 1206
<> 144:ef7eb2e8f9f7 1207 errataFixDcdcHsState = errataFixDcdcHsTrimSet;
<> 144:ef7eb2e8f9f7 1208 }
<> 150:02e0a0aed4ec 1209 #endif
<> 144:ef7eb2e8f9f7 1210 }
<> 144:ef7eb2e8f9f7 1211
<> 144:ef7eb2e8f9f7 1212
<> 144:ef7eb2e8f9f7 1213 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1214 * @brief
<> 150:02e0a0aed4ec 1215 * Compute current limiters:
<> 150:02e0a0aed4ec 1216 * LNCLIMILIMSEL: LN current limiter threshold
<> 150:02e0a0aed4ec 1217 * LPCLIMILIMSEL: LP current limiter threshold
<> 150:02e0a0aed4ec 1218 * DCDCZDETCTRL: zero detector limiter threshold
<> 144:ef7eb2e8f9f7 1219 ******************************************************************************/
<> 150:02e0a0aed4ec 1220 static void currentLimitersUpdate(void)
<> 144:ef7eb2e8f9f7 1221 {
<> 150:02e0a0aed4ec 1222 uint32_t lncLimSel;
<> 150:02e0a0aed4ec 1223 uint32_t zdetLimSel;
<> 144:ef7eb2e8f9f7 1224 uint32_t pFetCnt;
<> 150:02e0a0aed4ec 1225 uint16_t maxReverseCurrent_mA;
<> 144:ef7eb2e8f9f7 1226
<> 150:02e0a0aed4ec 1227 /* 80mA as recommended peak in Application Note AN0948.
<> 150:02e0a0aed4ec 1228 The peak current is the average current plus 50% of the current ripple.
<> 150:02e0a0aed4ec 1229 Hence, a 14mA average current is recommended in LP mode. Since LP PFETCNT is also
<> 150:02e0a0aed4ec 1230 a constant, we get lpcLimImSel = 1. The following calculation is provided
<> 150:02e0a0aed4ec 1231 for documentation only. */
<> 150:02e0a0aed4ec 1232 const uint32_t lpcLim = (((14 + 40) + ((14 + 40) / 2))
<> 150:02e0a0aed4ec 1233 / (5 * (DCDC_LP_PFET_CNT + 1)))
<> 150:02e0a0aed4ec 1234 - 1;
<> 150:02e0a0aed4ec 1235 const uint32_t lpcLimSel = lpcLim << _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1236
<> 150:02e0a0aed4ec 1237 /* Get enabled PFETs */
<> 144:ef7eb2e8f9f7 1238 pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)
<> 144:ef7eb2e8f9f7 1239 >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;
<> 144:ef7eb2e8f9f7 1240
<> 150:02e0a0aed4ec 1241 /* Compute LN current limiter threshold from nominal user input current and
<> 150:02e0a0aed4ec 1242 LN PFETCNT as described in the register description for
<> 150:02e0a0aed4ec 1243 EMU_DCDCMISCCTRL_LNCLIMILIMSEL. */
<> 150:02e0a0aed4ec 1244 lncLimSel = (((dcdcMaxCurrent_mA + 40) + ((dcdcMaxCurrent_mA + 40) / 2))
<> 150:02e0a0aed4ec 1245 / (5 * (pFetCnt + 1)))
<> 150:02e0a0aed4ec 1246 - 1;
<> 144:ef7eb2e8f9f7 1247
<> 150:02e0a0aed4ec 1248 /* Saturate the register field value */
<> 150:02e0a0aed4ec 1249 lncLimSel = SL_MIN(lncLimSel,
<> 150:02e0a0aed4ec 1250 _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 150:02e0a0aed4ec 1251 >> _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT);
<> 150:02e0a0aed4ec 1252
<> 150:02e0a0aed4ec 1253 lncLimSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1254
<> 150:02e0a0aed4ec 1255 /* Check for overflow */
<> 150:02e0a0aed4ec 1256 EFM_ASSERT((lncLimSel & ~_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1257 EFM_ASSERT((lpcLimSel & ~_EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1258
<> 144:ef7eb2e8f9f7 1259 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 144:ef7eb2e8f9f7 1260 | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))
<> 150:02e0a0aed4ec 1261 | (lncLimSel | lpcLimSel);
<> 150:02e0a0aed4ec 1262
<> 150:02e0a0aed4ec 1263
<> 150:02e0a0aed4ec 1264 /* Compute reverse current limit threshold for the zero detector from user input
<> 150:02e0a0aed4ec 1265 maximum reverse current and LN PFETCNT as described in the register description
<> 150:02e0a0aed4ec 1266 for EMU_DCDCZDETCTRL_ZDETILIMSEL. */
<> 150:02e0a0aed4ec 1267 if (dcdcReverseCurrentControl >= 0)
<> 150:02e0a0aed4ec 1268 {
<> 150:02e0a0aed4ec 1269 /* If dcdcReverseCurrentControl < 0, then EMU_DCDCZDETCTRL_ZDETILIMSEL is "don't care" */
<> 150:02e0a0aed4ec 1270 maxReverseCurrent_mA = (uint16_t)dcdcReverseCurrentControl;
<> 150:02e0a0aed4ec 1271
<> 150:02e0a0aed4ec 1272 zdetLimSel = ( ((maxReverseCurrent_mA + 40) + ((maxReverseCurrent_mA + 40) / 2))
<> 150:02e0a0aed4ec 1273 / ((2 * (pFetCnt + 1)) + ((pFetCnt + 1) / 2)) );
<> 150:02e0a0aed4ec 1274 /* Saturate the register field value */
<> 150:02e0a0aed4ec 1275 zdetLimSel = SL_MIN(zdetLimSel,
<> 150:02e0a0aed4ec 1276 _EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK
<> 150:02e0a0aed4ec 1277 >> _EMU_DCDCZDETCTRL_ZDETILIMSEL_SHIFT);
<> 150:02e0a0aed4ec 1278
<> 150:02e0a0aed4ec 1279 zdetLimSel <<= _EMU_DCDCZDETCTRL_ZDETILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1280
<> 150:02e0a0aed4ec 1281 /* Check for overflow */
<> 150:02e0a0aed4ec 1282 EFM_ASSERT((zdetLimSel & ~_EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1283
<> 150:02e0a0aed4ec 1284 EMU->DCDCZDETCTRL = (EMU->DCDCZDETCTRL & ~_EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK)
<> 150:02e0a0aed4ec 1285 | zdetLimSel;
<> 150:02e0a0aed4ec 1286 }
<> 144:ef7eb2e8f9f7 1287 }
<> 144:ef7eb2e8f9f7 1288
<> 144:ef7eb2e8f9f7 1289
<> 144:ef7eb2e8f9f7 1290 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1291 * @brief
<> 150:02e0a0aed4ec 1292 * Set static variables that hold the user set maximum peak current
<> 150:02e0a0aed4ec 1293 * and reverse current. Update limiters.
<> 144:ef7eb2e8f9f7 1294 *
<> 150:02e0a0aed4ec 1295 * @param[in] maxCurrent_mA
<> 150:02e0a0aed4ec 1296 * Set the maximum peak current that the DCDC can draw from the power source.
<> 150:02e0a0aed4ec 1297 * @param[in] reverseCurrentControl
<> 150:02e0a0aed4ec 1298 * Reverse current control as defined by
<> 150:02e0a0aed4ec 1299 * @ref EMU_DcdcLnReverseCurrentControl_TypeDef. Positive values have unit mA.
<> 144:ef7eb2e8f9f7 1300 ******************************************************************************/
<> 150:02e0a0aed4ec 1301 static void userCurrentLimitsSet(uint32_t maxCurrent_mA,
<> 150:02e0a0aed4ec 1302 EMU_DcdcLnReverseCurrentControl_TypeDef reverseCurrentControl)
<> 144:ef7eb2e8f9f7 1303 {
<> 150:02e0a0aed4ec 1304 dcdcMaxCurrent_mA = maxCurrent_mA;
<> 150:02e0a0aed4ec 1305 dcdcReverseCurrentControl = reverseCurrentControl;
<> 144:ef7eb2e8f9f7 1306 }
<> 144:ef7eb2e8f9f7 1307
<> 144:ef7eb2e8f9f7 1308
<> 144:ef7eb2e8f9f7 1309 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1310 * @brief
<> 150:02e0a0aed4ec 1311 * Set DCDC low noise compensator control register
<> 150:02e0a0aed4ec 1312 *
<> 150:02e0a0aed4ec 1313 * @param[in] comp
<> 150:02e0a0aed4ec 1314 * Low-noise mode compensator trim setpoint
<> 150:02e0a0aed4ec 1315 ******************************************************************************/
<> 150:02e0a0aed4ec 1316 static void compCtrlSet(EMU_DcdcLnCompCtrl_TypeDef comp)
<> 150:02e0a0aed4ec 1317 {
<> 150:02e0a0aed4ec 1318 #define EMU_DCDCLNCOMPCTRL (*(volatile uint32_t *) (EMU_BASE + 0x58UL))
<> 150:02e0a0aed4ec 1319
<> 150:02e0a0aed4ec 1320 switch (comp)
<> 150:02e0a0aed4ec 1321 {
<> 150:02e0a0aed4ec 1322 case emuDcdcLnCompCtrl_1u0F:
<> 150:02e0a0aed4ec 1323 EMU_DCDCLNCOMPCTRL = 0x57204077UL;
<> 150:02e0a0aed4ec 1324 break;
<> 150:02e0a0aed4ec 1325
<> 150:02e0a0aed4ec 1326 case emuDcdcLnCompCtrl_4u7F:
<> 150:02e0a0aed4ec 1327 EMU_DCDCLNCOMPCTRL = 0xB7102137UL;
<> 150:02e0a0aed4ec 1328 break;
<> 150:02e0a0aed4ec 1329
<> 150:02e0a0aed4ec 1330 default:
<> 150:02e0a0aed4ec 1331 EFM_ASSERT(false);
<> 150:02e0a0aed4ec 1332 break;
<> 150:02e0a0aed4ec 1333 }
<> 150:02e0a0aed4ec 1334 }
<> 150:02e0a0aed4ec 1335
<> 150:02e0a0aed4ec 1336 /***************************************************************************//**
<> 150:02e0a0aed4ec 1337 * @brief
<> 144:ef7eb2e8f9f7 1338 * Load EMU_DCDCLPCTRL_LPCMPHYSSEL depending on LP bias, LP feedback
<> 144:ef7eb2e8f9f7 1339 * attenuation and DEVINFOREV.
<> 144:ef7eb2e8f9f7 1340 *
<> 144:ef7eb2e8f9f7 1341 * @param[in] attSet
<> 144:ef7eb2e8f9f7 1342 * LP feedback attenuation.
<> 144:ef7eb2e8f9f7 1343 * @param[in] lpCmpBias
<> 150:02e0a0aed4ec 1344 * lpCmpBias selection (unshifted)
<> 144:ef7eb2e8f9f7 1345 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1346 static bool LpCmpHystCalibrationLoad(bool lpAttenuation, uint32_t lpCmpBias)
<> 144:ef7eb2e8f9f7 1347 {
<> 144:ef7eb2e8f9f7 1348 uint8_t devinfoRev;
<> 144:ef7eb2e8f9f7 1349 uint32_t lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1350
<> 144:ef7eb2e8f9f7 1351 /* Get calib data revision */
<> 144:ef7eb2e8f9f7 1352 devinfoRev = SYSTEM_GetDevinfoRev();
<> 144:ef7eb2e8f9f7 1353
<> 144:ef7eb2e8f9f7 1354 /* Load LPATT indexed calibration data */
<> 144:ef7eb2e8f9f7 1355 if (devinfoRev < 4)
<> 144:ef7eb2e8f9f7 1356 {
<> 144:ef7eb2e8f9f7 1357 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;
<> 144:ef7eb2e8f9f7 1358
<> 144:ef7eb2e8f9f7 1359 if (lpAttenuation)
<> 144:ef7eb2e8f9f7 1360 {
<> 144:ef7eb2e8f9f7 1361 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)
<> 144:ef7eb2e8f9f7 1362 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1363 }
<> 144:ef7eb2e8f9f7 1364 else
<> 144:ef7eb2e8f9f7 1365 {
<> 144:ef7eb2e8f9f7 1366 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)
<> 144:ef7eb2e8f9f7 1367 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1368 }
<> 144:ef7eb2e8f9f7 1369 }
<> 144:ef7eb2e8f9f7 1370 else
<> 144:ef7eb2e8f9f7 1371 {
<> 150:02e0a0aed4ec 1372 /* devinfoRev >= 4: load LPCMPBIAS indexed calibration data */
<> 144:ef7eb2e8f9f7 1373 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;
<> 144:ef7eb2e8f9f7 1374 switch (lpCmpBias)
<> 144:ef7eb2e8f9f7 1375 {
<> 150:02e0a0aed4ec 1376 case 0:
<> 144:ef7eb2e8f9f7 1377 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1378 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1379 break;
<> 144:ef7eb2e8f9f7 1380
<> 150:02e0a0aed4ec 1381 case 1 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1382 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1383 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1384 break;
<> 144:ef7eb2e8f9f7 1385
<> 150:02e0a0aed4ec 1386 case 2 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1387 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1388 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1389 break;
<> 144:ef7eb2e8f9f7 1390
<> 150:02e0a0aed4ec 1391 case 3 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1392 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1393 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1394 break;
<> 144:ef7eb2e8f9f7 1395
<> 144:ef7eb2e8f9f7 1396 default:
<> 144:ef7eb2e8f9f7 1397 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1398 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1399 return false;
<> 144:ef7eb2e8f9f7 1400 }
<> 144:ef7eb2e8f9f7 1401 }
<> 144:ef7eb2e8f9f7 1402 /* Make sure the sel value is within the field range. */
<> 150:02e0a0aed4ec 1403 lpcmpHystSel <<= _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT;
<> 150:02e0a0aed4ec 1404 if (lpcmpHystSel & ~_GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK)
<> 144:ef7eb2e8f9f7 1405 {
<> 144:ef7eb2e8f9f7 1406 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1407 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1408 return false;
<> 144:ef7eb2e8f9f7 1409 }
<> 150:02e0a0aed4ec 1410 EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK) | lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1411
<> 144:ef7eb2e8f9f7 1412 return true;
<> 144:ef7eb2e8f9f7 1413 }
<> 144:ef7eb2e8f9f7 1414
<> 144:ef7eb2e8f9f7 1415 /** @endcond */
<> 144:ef7eb2e8f9f7 1416
<> 144:ef7eb2e8f9f7 1417 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1418 * @brief
<> 144:ef7eb2e8f9f7 1419 * Set DCDC regulator operating mode
<> 144:ef7eb2e8f9f7 1420 *
<> 144:ef7eb2e8f9f7 1421 * @param[in] dcdcMode
<> 144:ef7eb2e8f9f7 1422 * DCDC mode
<> 144:ef7eb2e8f9f7 1423 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1424 void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)
<> 144:ef7eb2e8f9f7 1425 {
<> 150:02e0a0aed4ec 1426 uint32_t currentDcdcMode = (EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK);
<> 150:02e0a0aed4ec 1427
<> 150:02e0a0aed4ec 1428 if ((EMU_DcdcMode_TypeDef)currentDcdcMode == dcdcMode)
<> 150:02e0a0aed4ec 1429 {
<> 150:02e0a0aed4ec 1430 /* Mode already set - do nothing */
<> 150:02e0a0aed4ec 1431 return;
<> 150:02e0a0aed4ec 1432 }
<> 150:02e0a0aed4ec 1433
<> 150:02e0a0aed4ec 1434 #if defined(_SILICON_LABS_32B_PLATFORM_2_GEN_1)
<> 150:02e0a0aed4ec 1435
<> 144:ef7eb2e8f9f7 1436 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 150:02e0a0aed4ec 1437 /* Configure bypass current limiter */
<> 150:02e0a0aed4ec 1438 BUS_RegBitWrite(EMU_DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);
<> 150:02e0a0aed4ec 1439
<> 150:02e0a0aed4ec 1440 /* Fix for errata DCDC_E203 */
<> 150:02e0a0aed4ec 1441 if (((EMU_DcdcMode_TypeDef)currentDcdcMode == emuDcdcMode_Bypass)
<> 150:02e0a0aed4ec 1442 && (dcdcMode == emuDcdcMode_LowNoise))
<> 150:02e0a0aed4ec 1443 {
<> 150:02e0a0aed4ec 1444 errataFixDcdcHsState = errataFixDcdcHsBypassLn;
<> 150:02e0a0aed4ec 1445 }
<> 150:02e0a0aed4ec 1446
<> 150:02e0a0aed4ec 1447 #elif defined(_SILICON_LABS_32B_PLATFORM_2_GEN_2)
<> 150:02e0a0aed4ec 1448
<> 150:02e0a0aed4ec 1449 if (((currentDcdcMode == EMU_DCDCCTRL_DCDCMODE_OFF) || (currentDcdcMode == EMU_DCDCCTRL_DCDCMODE_BYPASS))
<> 150:02e0a0aed4ec 1450 && ((dcdcMode == emuDcdcMode_LowPower) || (dcdcMode == emuDcdcMode_LowNoise)))
<> 150:02e0a0aed4ec 1451 {
<> 150:02e0a0aed4ec 1452 /* Always start in LOWNOISE mode and then switch to LOWPOWER mode once LOWNOISE startup is complete. */
<> 150:02e0a0aed4ec 1453 EMU_IntClear(EMU_IFC_DCDCLNRUNNING);
<> 150:02e0a0aed4ec 1454 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 150:02e0a0aed4ec 1455 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | EMU_DCDCCTRL_DCDCMODE_LOWNOISE;
<> 150:02e0a0aed4ec 1456 while(!(EMU_IntGet() & EMU_IF_DCDCLNRUNNING));
<> 150:02e0a0aed4ec 1457 }
<> 150:02e0a0aed4ec 1458 else if (dcdcMode == emuDcdcMode_Bypass)
<> 150:02e0a0aed4ec 1459 {
<> 150:02e0a0aed4ec 1460 /* Enable limiter to remove current peak. Disable again in EMU_EnterEM2/3/4 */
<> 150:02e0a0aed4ec 1461 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 150:02e0a0aed4ec 1462 BUS_RegBitWrite(EMU_DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, 1);
<> 150:02e0a0aed4ec 1463 }
<> 150:02e0a0aed4ec 1464 #else
<> 150:02e0a0aed4ec 1465 #error "DCDC mode handling is undefined for this family."
<> 150:02e0a0aed4ec 1466 #endif
<> 150:02e0a0aed4ec 1467
<> 150:02e0a0aed4ec 1468 /* Set user requested mode. */
<> 144:ef7eb2e8f9f7 1469 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;
<> 144:ef7eb2e8f9f7 1470 }
<> 144:ef7eb2e8f9f7 1471
<> 144:ef7eb2e8f9f7 1472
<> 144:ef7eb2e8f9f7 1473 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1474 * @brief
<> 144:ef7eb2e8f9f7 1475 * Configure DCDC regulator
<> 144:ef7eb2e8f9f7 1476 *
<> 144:ef7eb2e8f9f7 1477 * @note
<> 150:02e0a0aed4ec 1478 * If the power circuit is configured for NODCDC as described in Section
<> 150:02e0a0aed4ec 1479 * 11.3.4.3 of the Reference Manual, do not call this function. Instead call
<> 150:02e0a0aed4ec 1480 * EMU_DCDCPowerOff().
<> 144:ef7eb2e8f9f7 1481 *
<> 144:ef7eb2e8f9f7 1482 * @param[in] dcdcInit
<> 144:ef7eb2e8f9f7 1483 * DCDC initialization structure
<> 144:ef7eb2e8f9f7 1484 *
<> 144:ef7eb2e8f9f7 1485 * @return
<> 144:ef7eb2e8f9f7 1486 * True if initialization parameters are valid
<> 144:ef7eb2e8f9f7 1487 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1488 bool EMU_DCDCInit(EMU_DCDCInit_TypeDef *dcdcInit)
<> 144:ef7eb2e8f9f7 1489 {
<> 150:02e0a0aed4ec 1490 #if defined(_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 150:02e0a0aed4ec 1491 uint32_t lpCmpBiasSelEM01;
<> 150:02e0a0aed4ec 1492 #endif
<> 150:02e0a0aed4ec 1493 uint32_t lpCmpBiasSelEM234H;
<> 144:ef7eb2e8f9f7 1494
<> 144:ef7eb2e8f9f7 1495 /* Set external power configuration. This enables writing to the other
<> 144:ef7eb2e8f9f7 1496 DCDC registers. */
<> 144:ef7eb2e8f9f7 1497 EMU->PWRCFG = dcdcInit->powerConfig;
<> 144:ef7eb2e8f9f7 1498
<> 144:ef7eb2e8f9f7 1499 /* EMU->PWRCFG is write-once and POR reset only. Check that
<> 144:ef7eb2e8f9f7 1500 we could set the desired power configuration. */
<> 144:ef7eb2e8f9f7 1501 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != dcdcInit->powerConfig)
<> 144:ef7eb2e8f9f7 1502 {
<> 144:ef7eb2e8f9f7 1503 /* If this assert triggers unexpectedly, please power cycle the
<> 144:ef7eb2e8f9f7 1504 kit to reset the power configuration. */
<> 144:ef7eb2e8f9f7 1505 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1506 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1507 return false;
<> 144:ef7eb2e8f9f7 1508 }
<> 144:ef7eb2e8f9f7 1509
<> 144:ef7eb2e8f9f7 1510 /* Load DCDC calibration data from the DI page */
<> 144:ef7eb2e8f9f7 1511 ConstCalibrationLoad();
<> 144:ef7eb2e8f9f7 1512
<> 144:ef7eb2e8f9f7 1513 /* Check current parameters */
<> 144:ef7eb2e8f9f7 1514 EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1515 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);
<> 150:02e0a0aed4ec 1516 EFM_ASSERT(dcdcInit->reverseCurrentControl <= 200);
<> 144:ef7eb2e8f9f7 1517
<> 144:ef7eb2e8f9f7 1518 /* DCDC low-noise supports max 200mA */
<> 144:ef7eb2e8f9f7 1519 if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)
<> 144:ef7eb2e8f9f7 1520 {
<> 144:ef7eb2e8f9f7 1521 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1522 }
<> 150:02e0a0aed4ec 1523 #if (_SILICON_LABS_32B_PLATFORM_2_GEN > 1)
<> 150:02e0a0aed4ec 1524 else if (dcdcInit->dcdcMode == emuDcdcMode_LowPower)
<> 150:02e0a0aed4ec 1525 {
<> 150:02e0a0aed4ec 1526 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 10);
<> 150:02e0a0aed4ec 1527 }
<> 150:02e0a0aed4ec 1528 #endif
<> 144:ef7eb2e8f9f7 1529
<> 150:02e0a0aed4ec 1530 /* EM2/3/4 current above 10mA is not supported */
<> 150:02e0a0aed4ec 1531 EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 10000);
<> 144:ef7eb2e8f9f7 1532
<> 144:ef7eb2e8f9f7 1533 /* Decode LP comparator bias for EM0/1 and EM2/3 */
<> 150:02e0a0aed4ec 1534 #if defined(_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 150:02e0a0aed4ec 1535 lpCmpBiasSelEM01 = EMU_DCDCLPEM01CFG_LPCMPBIASEM01_BIAS3;
<> 150:02e0a0aed4ec 1536 if (dcdcInit->dcdcMode == emuDcdcMode_LowPower)
<> 150:02e0a0aed4ec 1537 {
<> 150:02e0a0aed4ec 1538 if (dcdcInit->em01LoadCurrent_mA <= 1)
<> 150:02e0a0aed4ec 1539 {
<> 150:02e0a0aed4ec 1540 lpCmpBiasSelEM01 = EMU_DCDCLPEM01CFG_LPCMPBIASEM01_BIAS1;
<> 150:02e0a0aed4ec 1541 }
<> 150:02e0a0aed4ec 1542 else if (dcdcInit->em01LoadCurrent_mA <= 3)
<> 150:02e0a0aed4ec 1543 {
<> 150:02e0a0aed4ec 1544 lpCmpBiasSelEM01 = EMU_DCDCLPEM01CFG_LPCMPBIASEM01_BIAS2;
<> 150:02e0a0aed4ec 1545 }
<> 150:02e0a0aed4ec 1546 }
<> 150:02e0a0aed4ec 1547 #endif
<> 150:02e0a0aed4ec 1548
<> 150:02e0a0aed4ec 1549 if (dcdcInit->em234LoadCurrent_uA < 75)
<> 144:ef7eb2e8f9f7 1550 {
<> 150:02e0a0aed4ec 1551 lpCmpBiasSelEM234H = 0;
<> 150:02e0a0aed4ec 1552 }
<> 150:02e0a0aed4ec 1553 else if (dcdcInit->em234LoadCurrent_uA < 500)
<> 150:02e0a0aed4ec 1554 {
<> 150:02e0a0aed4ec 1555 lpCmpBiasSelEM234H = 1 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 144:ef7eb2e8f9f7 1556 }
<> 150:02e0a0aed4ec 1557 else if (dcdcInit->em234LoadCurrent_uA < 2500)
<> 150:02e0a0aed4ec 1558 {
<> 150:02e0a0aed4ec 1559 lpCmpBiasSelEM234H = 2 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 150:02e0a0aed4ec 1560 }
<> 150:02e0a0aed4ec 1561 else
<> 150:02e0a0aed4ec 1562 {
<> 150:02e0a0aed4ec 1563 lpCmpBiasSelEM234H = 3 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 150:02e0a0aed4ec 1564 }
<> 150:02e0a0aed4ec 1565
<> 150:02e0a0aed4ec 1566 /* ==== THESE NEXT STEPS ARE STRONGLY ORDER DEPENDENT ==== */
<> 144:ef7eb2e8f9f7 1567
<> 144:ef7eb2e8f9f7 1568 /* Set DCDC low-power mode comparator bias selection */
<> 150:02e0a0aed4ec 1569
<> 150:02e0a0aed4ec 1570 /* 1. Set DCDC low-power mode comparator bias selection and forced CCM
<> 150:02e0a0aed4ec 1571 => Updates DCDCMISCCTRL_LNFORCECCM */
<> 150:02e0a0aed4ec 1572 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK
<> 144:ef7eb2e8f9f7 1573 | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))
<> 150:02e0a0aed4ec 1574 | ((uint32_t)lpCmpBiasSelEM234H
<> 150:02e0a0aed4ec 1575 | (dcdcInit->reverseCurrentControl >= 0 ?
<> 150:02e0a0aed4ec 1576 EMU_DCDCMISCCTRL_LNFORCECCM : 0));
<> 150:02e0a0aed4ec 1577 #if defined(_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 150:02e0a0aed4ec 1578 EMU->DCDCLPEM01CFG = (EMU->DCDCLPEM01CFG & ~_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 150:02e0a0aed4ec 1579 | lpCmpBiasSelEM01;
<> 150:02e0a0aed4ec 1580 #endif
<> 144:ef7eb2e8f9f7 1581
<> 150:02e0a0aed4ec 1582 /* 2. Set recommended and validated current optimization settings
<> 150:02e0a0aed4ec 1583 <= Depends on LNFORCECCM
<> 150:02e0a0aed4ec 1584 => Updates DCDCLNFREQCTRL_RCOBAND */
<> 144:ef7eb2e8f9f7 1585 ValidatedConfigSet();
<> 144:ef7eb2e8f9f7 1586
<> 150:02e0a0aed4ec 1587 /* 3. Updated static currents and limits user data.
<> 150:02e0a0aed4ec 1588 Limiters are updated in EMU_DCDCOptimizeSlice() */
<> 150:02e0a0aed4ec 1589 userCurrentLimitsSet(dcdcInit->maxCurrent_mA,
<> 150:02e0a0aed4ec 1590 dcdcInit->reverseCurrentControl);
<> 150:02e0a0aed4ec 1591 dcdcEm01LoadCurrent_mA = dcdcInit->em01LoadCurrent_mA;
<> 144:ef7eb2e8f9f7 1592
<> 150:02e0a0aed4ec 1593 /* 4. Optimize LN slice based on given user input load current
<> 150:02e0a0aed4ec 1594 <= Depends on DCDCMISCCTRL_LNFORCECCM and DCDCLNFREQCTRL_RCOBAND
<> 150:02e0a0aed4ec 1595 <= Depends on dcdcInit->maxCurrent_mA and dcdcInit->reverseCurrentControl
<> 150:02e0a0aed4ec 1596 => Updates DCDCMISCCTRL_P/NFETCNT
<> 150:02e0a0aed4ec 1597 => Updates DCDCMISCCTRL_LNCLIMILIMSEL and DCDCMISCCTRL_LPCLIMILIMSEL
<> 150:02e0a0aed4ec 1598 => Updates DCDCZDETCTRL_ZDETILIMSEL */
<> 144:ef7eb2e8f9f7 1599 EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 1600
<> 150:02e0a0aed4ec 1601 /* ======================================================= */
<> 150:02e0a0aed4ec 1602
<> 150:02e0a0aed4ec 1603 /* Set DCDC low noise mode compensator control register. */
<> 150:02e0a0aed4ec 1604 compCtrlSet(dcdcInit->dcdcLnCompCtrl);
<> 150:02e0a0aed4ec 1605
<> 144:ef7eb2e8f9f7 1606 /* Set DCDC output voltage */
<> 150:02e0a0aed4ec 1607 if (!EMU_DCDCOutputVoltageSet(dcdcInit->mVout, true, true))
<> 144:ef7eb2e8f9f7 1608 {
<> 144:ef7eb2e8f9f7 1609 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1610 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1611 return false;
<> 144:ef7eb2e8f9f7 1612 }
<> 144:ef7eb2e8f9f7 1613
<> 150:02e0a0aed4ec 1614 #if ( _SILICON_LABS_32B_PLATFORM_2_GEN == 1 )
<> 150:02e0a0aed4ec 1615 /* Select analog peripheral power supply. This must be done before
<> 150:02e0a0aed4ec 1616 DCDC mode is set for GEN_1. */
<> 150:02e0a0aed4ec 1617 BUS_RegBitWrite(&EMU->PWRCTRL,
<> 150:02e0a0aed4ec 1618 _EMU_PWRCTRL_ANASW_SHIFT,
<> 150:02e0a0aed4ec 1619 dcdcInit->anaPeripheralPower ? 1 : 0);
<> 150:02e0a0aed4ec 1620 #endif
<> 150:02e0a0aed4ec 1621
<> 150:02e0a0aed4ec 1622 /* Set EM0 DCDC operating mode. Output voltage set in
<> 150:02e0a0aed4ec 1623 EMU_DCDCOutputVoltageSet() above takes effect if mode
<> 150:02e0a0aed4ec 1624 is changed from bypass/off mode. */
<> 144:ef7eb2e8f9f7 1625 EMU_DCDCModeSet(dcdcInit->dcdcMode);
<> 144:ef7eb2e8f9f7 1626
<> 150:02e0a0aed4ec 1627 /* Select DVDD as input to the digital regulator */
<> 150:02e0a0aed4ec 1628 #if defined(_EMU_PWRCTRL_REGPWRSEL_MASK)
<> 150:02e0a0aed4ec 1629 EMU->PWRCTRL |= EMU_PWRCTRL_REGPWRSEL_DVDD;
<> 150:02e0a0aed4ec 1630 #endif
<> 150:02e0a0aed4ec 1631
<> 150:02e0a0aed4ec 1632 #if ( _SILICON_LABS_32B_PLATFORM_2_GEN > 1 )
<> 150:02e0a0aed4ec 1633 /* Select analog peripheral power supply. This must be done after
<> 150:02e0a0aed4ec 1634 DCDC mode is set for GEN > 1. */
<> 150:02e0a0aed4ec 1635 BUS_RegBitWrite(&EMU->PWRCTRL,
<> 150:02e0a0aed4ec 1636 _EMU_PWRCTRL_ANASW_SHIFT,
<> 150:02e0a0aed4ec 1637 dcdcInit->anaPeripheralPower ? 1 : 0);
<> 150:02e0a0aed4ec 1638 #endif
<> 144:ef7eb2e8f9f7 1639
<> 144:ef7eb2e8f9f7 1640 return true;
<> 144:ef7eb2e8f9f7 1641 }
<> 144:ef7eb2e8f9f7 1642
<> 144:ef7eb2e8f9f7 1643
<> 144:ef7eb2e8f9f7 1644 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1645 * @brief
<> 144:ef7eb2e8f9f7 1646 * Set DCDC output voltage
<> 144:ef7eb2e8f9f7 1647 *
<> 144:ef7eb2e8f9f7 1648 * @param[in] mV
<> 144:ef7eb2e8f9f7 1649 * Target DCDC output voltage in mV
<> 144:ef7eb2e8f9f7 1650 *
<> 144:ef7eb2e8f9f7 1651 * @return
<> 144:ef7eb2e8f9f7 1652 * True if the mV parameter is valid
<> 144:ef7eb2e8f9f7 1653 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1654 bool EMU_DCDCOutputVoltageSet(uint32_t mV,
<> 144:ef7eb2e8f9f7 1655 bool setLpVoltage,
<> 144:ef7eb2e8f9f7 1656 bool setLnVoltage)
<> 144:ef7eb2e8f9f7 1657 {
<> 144:ef7eb2e8f9f7 1658 #if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )
<> 144:ef7eb2e8f9f7 1659
<> 144:ef7eb2e8f9f7 1660 bool validOutVoltage;
<> 144:ef7eb2e8f9f7 1661 uint8_t lnMode;
<> 144:ef7eb2e8f9f7 1662 bool attSet;
<> 144:ef7eb2e8f9f7 1663 uint32_t attMask;
<> 144:ef7eb2e8f9f7 1664 uint32_t vrefLow = 0;
<> 144:ef7eb2e8f9f7 1665 uint32_t vrefHigh = 0;
<> 144:ef7eb2e8f9f7 1666 uint32_t vrefVal = 0;
<> 144:ef7eb2e8f9f7 1667 uint32_t mVlow = 0;
<> 144:ef7eb2e8f9f7 1668 uint32_t mVhigh = 0;
<> 144:ef7eb2e8f9f7 1669 uint32_t vrefShift;
<> 144:ef7eb2e8f9f7 1670 uint32_t lpcmpBias;
<> 144:ef7eb2e8f9f7 1671 volatile uint32_t* ctrlReg;
<> 144:ef7eb2e8f9f7 1672
<> 144:ef7eb2e8f9f7 1673 /* Check that the set voltage is within valid range.
<> 144:ef7eb2e8f9f7 1674 Voltages are obtained from the datasheet. */
<> 144:ef7eb2e8f9f7 1675 validOutVoltage = false;
<> 144:ef7eb2e8f9f7 1676 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD)
<> 144:ef7eb2e8f9f7 1677 {
<> 144:ef7eb2e8f9f7 1678 validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)
<> 144:ef7eb2e8f9f7 1679 && (mV <= PWRCFG_DCDCTODVDD_VMAX));
<> 144:ef7eb2e8f9f7 1680 }
<> 144:ef7eb2e8f9f7 1681
<> 144:ef7eb2e8f9f7 1682 if (!validOutVoltage)
<> 144:ef7eb2e8f9f7 1683 {
<> 144:ef7eb2e8f9f7 1684 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1685 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1686 return false;
<> 144:ef7eb2e8f9f7 1687 }
<> 144:ef7eb2e8f9f7 1688
<> 144:ef7eb2e8f9f7 1689 /* Populate both LP and LN registers, set control reg pointer and VREF shift. */
<> 144:ef7eb2e8f9f7 1690 for (lnMode = 0; lnMode <= 1; lnMode++)
<> 144:ef7eb2e8f9f7 1691 {
<> 144:ef7eb2e8f9f7 1692 if (((lnMode == 0) && !setLpVoltage)
<> 144:ef7eb2e8f9f7 1693 || ((lnMode == 1) && !setLnVoltage))
<> 144:ef7eb2e8f9f7 1694 {
<> 144:ef7eb2e8f9f7 1695 continue;
<> 144:ef7eb2e8f9f7 1696 }
<> 144:ef7eb2e8f9f7 1697
<> 144:ef7eb2e8f9f7 1698 ctrlReg = (lnMode ? &EMU->DCDCLNVCTRL : &EMU->DCDCLPVCTRL);
<> 144:ef7eb2e8f9f7 1699 vrefShift = (lnMode ? _EMU_DCDCLNVCTRL_LNVREF_SHIFT
<> 144:ef7eb2e8f9f7 1700 : _EMU_DCDCLPVCTRL_LPVREF_SHIFT);
<> 144:ef7eb2e8f9f7 1701
<> 144:ef7eb2e8f9f7 1702 /* Set attenuation to use */
<> 144:ef7eb2e8f9f7 1703 attSet = (mV > 1800);
<> 150:02e0a0aed4ec 1704 /* Always set mVlow different from mVhigh to avoid division by zero */
<> 150:02e0a0aed4ec 1705 /* further down. */
<> 144:ef7eb2e8f9f7 1706 if (attSet)
<> 144:ef7eb2e8f9f7 1707 {
<> 144:ef7eb2e8f9f7 1708 mVlow = 1800;
<> 144:ef7eb2e8f9f7 1709 mVhigh = 3000;
<> 144:ef7eb2e8f9f7 1710 attMask = (lnMode ? EMU_DCDCLNVCTRL_LNATT : EMU_DCDCLPVCTRL_LPATT);
<> 144:ef7eb2e8f9f7 1711 }
<> 144:ef7eb2e8f9f7 1712 else
<> 144:ef7eb2e8f9f7 1713 {
<> 144:ef7eb2e8f9f7 1714 mVlow = 1200;
<> 144:ef7eb2e8f9f7 1715 mVhigh = 1800;
<> 144:ef7eb2e8f9f7 1716 attMask = 0;
<> 144:ef7eb2e8f9f7 1717 }
<> 144:ef7eb2e8f9f7 1718
<> 144:ef7eb2e8f9f7 1719 /* Get 2-point calib data from DEVINFO, calculate trimming and set voltege */
<> 144:ef7eb2e8f9f7 1720 if (lnMode)
<> 144:ef7eb2e8f9f7 1721 {
<> 144:ef7eb2e8f9f7 1722 /* Set low-noise DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1723 if (attSet)
<> 144:ef7eb2e8f9f7 1724 {
<> 144:ef7eb2e8f9f7 1725 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1726 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1727 >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1728 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1729 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1730 }
<> 144:ef7eb2e8f9f7 1731 else
<> 144:ef7eb2e8f9f7 1732 {
<> 144:ef7eb2e8f9f7 1733 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1734 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1735 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1736 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1737 >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1738 }
<> 144:ef7eb2e8f9f7 1739 }
<> 144:ef7eb2e8f9f7 1740 else
<> 144:ef7eb2e8f9f7 1741 {
<> 144:ef7eb2e8f9f7 1742 /* Set low-power DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1743
<> 144:ef7eb2e8f9f7 1744 /* Get LPCMPBIAS and make sure masks are not overlayed */
<> 150:02e0a0aed4ec 1745 lpcmpBias = EMU->DCDCMISCCTRL & _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK;
<> 150:02e0a0aed4ec 1746 EFM_ASSERT(!(_GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK & attMask));
<> 144:ef7eb2e8f9f7 1747 switch (attMask | lpcmpBias)
<> 144:ef7eb2e8f9f7 1748 {
<> 150:02e0a0aed4ec 1749 case EMU_DCDCLPVCTRL_LPATT:
<> 144:ef7eb2e8f9f7 1750 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1751 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1752 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1753 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1754 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1755 break;
<> 144:ef7eb2e8f9f7 1756
<> 150:02e0a0aed4ec 1757 case EMU_DCDCLPVCTRL_LPATT | 1 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1758 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1759 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1760 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1761 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1762 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1763 break;
<> 144:ef7eb2e8f9f7 1764
<> 150:02e0a0aed4ec 1765 case EMU_DCDCLPVCTRL_LPATT | 2 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1766 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1767 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1768 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1769 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1770 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1771 break;
<> 144:ef7eb2e8f9f7 1772
<> 150:02e0a0aed4ec 1773 case EMU_DCDCLPVCTRL_LPATT | 3 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1774 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1775 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1776 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1777 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1778 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1779 break;
<> 144:ef7eb2e8f9f7 1780
<> 150:02e0a0aed4ec 1781 case 0:
<> 144:ef7eb2e8f9f7 1782 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1783 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1784 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1785 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1786 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1787 break;
<> 144:ef7eb2e8f9f7 1788
<> 150:02e0a0aed4ec 1789 case 1 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1790 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1791 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1792 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1793 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1794 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1795 break;
<> 144:ef7eb2e8f9f7 1796
<> 150:02e0a0aed4ec 1797 case 2 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1798 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1799 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1800 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1801 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1802 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1803 break;
<> 144:ef7eb2e8f9f7 1804
<> 150:02e0a0aed4ec 1805 case 3 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT:
<> 144:ef7eb2e8f9f7 1806 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1807 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1808 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1809 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1810 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1811 break;
<> 144:ef7eb2e8f9f7 1812
<> 144:ef7eb2e8f9f7 1813 default:
<> 144:ef7eb2e8f9f7 1814 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1815 break;
<> 144:ef7eb2e8f9f7 1816 }
<> 144:ef7eb2e8f9f7 1817
<> 144:ef7eb2e8f9f7 1818 /* Load LP comparator hysteresis calibration */
<> 150:02e0a0aed4ec 1819 if(!(LpCmpHystCalibrationLoad(attSet, lpcmpBias)))
<> 144:ef7eb2e8f9f7 1820 {
<> 144:ef7eb2e8f9f7 1821 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1822 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1823 return false;
<> 144:ef7eb2e8f9f7 1824 }
<> 144:ef7eb2e8f9f7 1825 } /* Low-nise / low-power mode */
<> 144:ef7eb2e8f9f7 1826
<> 144:ef7eb2e8f9f7 1827
<> 144:ef7eb2e8f9f7 1828 /* Check for valid 2-point trim values */
<> 150:02e0a0aed4ec 1829 if (mVlow >= mVhigh)
<> 144:ef7eb2e8f9f7 1830 {
<> 144:ef7eb2e8f9f7 1831 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1832 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1833 return false;
<> 144:ef7eb2e8f9f7 1834 }
<> 144:ef7eb2e8f9f7 1835
<> 144:ef7eb2e8f9f7 1836 /* Calculate and set voltage trim */
<> 144:ef7eb2e8f9f7 1837 vrefVal = ((mV - mVlow) * (vrefHigh - vrefLow)) / (mVhigh - mVlow);
<> 144:ef7eb2e8f9f7 1838 vrefVal += vrefLow;
<> 144:ef7eb2e8f9f7 1839
<> 144:ef7eb2e8f9f7 1840 /* Range check */
<> 144:ef7eb2e8f9f7 1841 if ((vrefVal > vrefHigh) || (vrefVal < vrefLow))
<> 144:ef7eb2e8f9f7 1842 {
<> 144:ef7eb2e8f9f7 1843 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1844 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1845 return false;
<> 144:ef7eb2e8f9f7 1846 }
<> 144:ef7eb2e8f9f7 1847
<> 144:ef7eb2e8f9f7 1848 /* Update DCDCLNVCTRL/DCDCLPVCTRL */
<> 144:ef7eb2e8f9f7 1849 *ctrlReg = (vrefVal << vrefShift) | attMask;
<> 144:ef7eb2e8f9f7 1850 }
<> 144:ef7eb2e8f9f7 1851 #endif
<> 144:ef7eb2e8f9f7 1852 return true;
<> 144:ef7eb2e8f9f7 1853 }
<> 144:ef7eb2e8f9f7 1854
<> 144:ef7eb2e8f9f7 1855
<> 144:ef7eb2e8f9f7 1856 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1857 * @brief
<> 144:ef7eb2e8f9f7 1858 * Optimize DCDC slice count based on the estimated average load current
<> 144:ef7eb2e8f9f7 1859 * in EM0
<> 144:ef7eb2e8f9f7 1860 *
<> 150:02e0a0aed4ec 1861 * @param[in] em0LoadCurrent_mA
<> 144:ef7eb2e8f9f7 1862 * Estimated average EM0 load current in mA.
<> 144:ef7eb2e8f9f7 1863 ******************************************************************************/
<> 150:02e0a0aed4ec 1864 void EMU_DCDCOptimizeSlice(uint32_t em0LoadCurrent_mA)
<> 144:ef7eb2e8f9f7 1865 {
<> 144:ef7eb2e8f9f7 1866 uint32_t sliceCount = 0;
<> 144:ef7eb2e8f9f7 1867 uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1868 >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;
<> 144:ef7eb2e8f9f7 1869
<> 144:ef7eb2e8f9f7 1870 /* Set recommended slice count */
<> 150:02e0a0aed4ec 1871 if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= emuDcdcLnRcoBand_5MHz))
<> 144:ef7eb2e8f9f7 1872 {
<> 150:02e0a0aed4ec 1873 if (em0LoadCurrent_mA < 20)
<> 144:ef7eb2e8f9f7 1874 {
<> 144:ef7eb2e8f9f7 1875 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1876 }
<> 150:02e0a0aed4ec 1877 else if ((em0LoadCurrent_mA >= 20) && (em0LoadCurrent_mA < 40))
<> 144:ef7eb2e8f9f7 1878 {
<> 144:ef7eb2e8f9f7 1879 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1880 }
<> 144:ef7eb2e8f9f7 1881 else
<> 144:ef7eb2e8f9f7 1882 {
<> 144:ef7eb2e8f9f7 1883 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1884 }
<> 144:ef7eb2e8f9f7 1885 }
<> 150:02e0a0aed4ec 1886 else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= emuDcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1887 {
<> 150:02e0a0aed4ec 1888 if (em0LoadCurrent_mA < 10)
<> 144:ef7eb2e8f9f7 1889 {
<> 144:ef7eb2e8f9f7 1890 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1891 }
<> 150:02e0a0aed4ec 1892 else if ((em0LoadCurrent_mA >= 10) && (em0LoadCurrent_mA < 20))
<> 144:ef7eb2e8f9f7 1893 {
<> 144:ef7eb2e8f9f7 1894 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1895 }
<> 144:ef7eb2e8f9f7 1896 else
<> 144:ef7eb2e8f9f7 1897 {
<> 144:ef7eb2e8f9f7 1898 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1899 }
<> 144:ef7eb2e8f9f7 1900 }
<> 150:02e0a0aed4ec 1901 else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= emuDcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1902 {
<> 150:02e0a0aed4ec 1903 if (em0LoadCurrent_mA < 40)
<> 144:ef7eb2e8f9f7 1904 {
<> 144:ef7eb2e8f9f7 1905 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1906 }
<> 144:ef7eb2e8f9f7 1907 else
<> 144:ef7eb2e8f9f7 1908 {
<> 144:ef7eb2e8f9f7 1909 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1910 }
<> 144:ef7eb2e8f9f7 1911 }
<> 144:ef7eb2e8f9f7 1912 else
<> 144:ef7eb2e8f9f7 1913 {
<> 144:ef7eb2e8f9f7 1914 /* This configuration is not recommended. EMU_DCDCInit() applies a recommended
<> 144:ef7eb2e8f9f7 1915 configuration. */
<> 144:ef7eb2e8f9f7 1916 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1917 }
<> 144:ef7eb2e8f9f7 1918
<> 150:02e0a0aed4ec 1919 /* The selected slices are PSLICESEL + 1 */
<> 144:ef7eb2e8f9f7 1920 sliceCount--;
<> 144:ef7eb2e8f9f7 1921
<> 144:ef7eb2e8f9f7 1922 /* Apply slice count to both N and P slice */
<> 144:ef7eb2e8f9f7 1923 sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT
<> 144:ef7eb2e8f9f7 1924 | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 1925 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK
<> 144:ef7eb2e8f9f7 1926 | _EMU_DCDCMISCCTRL_NFETCNT_MASK))
<> 144:ef7eb2e8f9f7 1927 | sliceCount;
<> 144:ef7eb2e8f9f7 1928
<> 150:02e0a0aed4ec 1929 /* Update current limiters */
<> 150:02e0a0aed4ec 1930 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 1931 }
<> 144:ef7eb2e8f9f7 1932
<> 144:ef7eb2e8f9f7 1933 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1934 * @brief
<> 144:ef7eb2e8f9f7 1935 * Set DCDC Low-noise RCO band.
<> 144:ef7eb2e8f9f7 1936 *
<> 144:ef7eb2e8f9f7 1937 * @param[in] band
<> 144:ef7eb2e8f9f7 1938 * RCO band to set.
<> 144:ef7eb2e8f9f7 1939 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1940 void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)
<> 144:ef7eb2e8f9f7 1941 {
<> 150:02e0a0aed4ec 1942 uint32_t forcedCcm;
<> 150:02e0a0aed4ec 1943 forcedCcm = BUS_RegBitRead(&EMU->DCDCMISCCTRL, _EMU_DCDCMISCCTRL_LNFORCECCM_SHIFT);
<> 150:02e0a0aed4ec 1944
<> 150:02e0a0aed4ec 1945 /* DCM mode supports up to 4MHz LN RCO. */
<> 150:02e0a0aed4ec 1946 EFM_ASSERT((!forcedCcm && band <= emuDcdcLnRcoBand_4MHz) || forcedCcm);
<> 150:02e0a0aed4ec 1947
<> 144:ef7eb2e8f9f7 1948 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1949 | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 150:02e0a0aed4ec 1950
<> 150:02e0a0aed4ec 1951 /* Update slice configuration as this depends on the RCO band. */
<> 150:02e0a0aed4ec 1952 EMU_DCDCOptimizeSlice(dcdcEm01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 1953 }
<> 144:ef7eb2e8f9f7 1954
<> 144:ef7eb2e8f9f7 1955 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1956 * @brief
<> 144:ef7eb2e8f9f7 1957 * Power off the DCDC regulator.
<> 144:ef7eb2e8f9f7 1958 *
<> 144:ef7eb2e8f9f7 1959 * @details
<> 144:ef7eb2e8f9f7 1960 * This function powers off the DCDC controller. This function should only be
<> 144:ef7eb2e8f9f7 1961 * used if the external power circuit is wired for no DCDC. If the external power
<> 144:ef7eb2e8f9f7 1962 * circuit is wired for DCDC usage, then use EMU_DCDCInit() and set the
<> 144:ef7eb2e8f9f7 1963 * DCDC in bypass mode to disable DCDC.
<> 144:ef7eb2e8f9f7 1964 *
<> 144:ef7eb2e8f9f7 1965 * @return
<> 144:ef7eb2e8f9f7 1966 * Return false if the DCDC could not be disabled.
<> 144:ef7eb2e8f9f7 1967 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1968 bool EMU_DCDCPowerOff(void)
<> 144:ef7eb2e8f9f7 1969 {
<> 150:02e0a0aed4ec 1970 bool dcdcModeSet;
<> 150:02e0a0aed4ec 1971
<> 150:02e0a0aed4ec 1972 /* Set DCDCTODVDD only to enable write access to EMU->DCDCCTRL */
<> 150:02e0a0aed4ec 1973 EMU->PWRCFG = EMU_PWRCFG_PWRCFG_DCDCTODVDD;
<> 150:02e0a0aed4ec 1974
<> 150:02e0a0aed4ec 1975 /* Select DVDD as input to the digital regulator */
<> 150:02e0a0aed4ec 1976 #if defined(_EMU_PWRCTRL_REGPWRSEL_MASK)
<> 150:02e0a0aed4ec 1977 EMU->PWRCTRL |= EMU_PWRCTRL_REGPWRSEL_DVDD;
<> 150:02e0a0aed4ec 1978 #endif
<> 144:ef7eb2e8f9f7 1979
<> 150:02e0a0aed4ec 1980 /* Set DCDC to OFF and disable LP in EM2/3/4. Verify that the required
<> 150:02e0a0aed4ec 1981 mode could be set. */
<> 150:02e0a0aed4ec 1982 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 144:ef7eb2e8f9f7 1983 EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;
<> 150:02e0a0aed4ec 1984
<> 150:02e0a0aed4ec 1985 dcdcModeSet = (EMU->DCDCCTRL == EMU_DCDCCTRL_DCDCMODE_OFF);
<> 150:02e0a0aed4ec 1986 EFM_ASSERT(dcdcModeSet);
<> 150:02e0a0aed4ec 1987
<> 150:02e0a0aed4ec 1988 return dcdcModeSet;
<> 144:ef7eb2e8f9f7 1989 }
<> 144:ef7eb2e8f9f7 1990 #endif
<> 144:ef7eb2e8f9f7 1991
<> 144:ef7eb2e8f9f7 1992
<> 144:ef7eb2e8f9f7 1993 #if defined( EMU_STATUS_VMONRDY )
<> 144:ef7eb2e8f9f7 1994 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 1995 __STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)
<> 144:ef7eb2e8f9f7 1996 {
<> 144:ef7eb2e8f9f7 1997 return (mV - 1200) / 200;
<> 144:ef7eb2e8f9f7 1998 }
<> 144:ef7eb2e8f9f7 1999
<> 144:ef7eb2e8f9f7 2000 __STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)
<> 144:ef7eb2e8f9f7 2001 {
<> 144:ef7eb2e8f9f7 2002 return (mV - 1200 - (coarseThreshold * 200)) / 20;
<> 144:ef7eb2e8f9f7 2003 }
<> 144:ef7eb2e8f9f7 2004 /** @endcond */
<> 144:ef7eb2e8f9f7 2005
<> 144:ef7eb2e8f9f7 2006 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2007 * @brief
<> 144:ef7eb2e8f9f7 2008 * Initialize VMON channel.
<> 144:ef7eb2e8f9f7 2009 *
<> 144:ef7eb2e8f9f7 2010 * @details
<> 144:ef7eb2e8f9f7 2011 * Initialize a VMON channel without hysteresis. If the channel supports
<> 144:ef7eb2e8f9f7 2012 * separate rise and fall triggers, both thresholds will be set to the same
<> 144:ef7eb2e8f9f7 2013 * value.
<> 144:ef7eb2e8f9f7 2014 *
<> 144:ef7eb2e8f9f7 2015 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 2016 * VMON initialization struct
<> 144:ef7eb2e8f9f7 2017 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2018 void EMU_VmonInit(EMU_VmonInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 2019 {
<> 144:ef7eb2e8f9f7 2020 uint32_t thresholdCoarse, thresholdFine;
<> 144:ef7eb2e8f9f7 2021 EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));
<> 144:ef7eb2e8f9f7 2022
<> 144:ef7eb2e8f9f7 2023 thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);
<> 144:ef7eb2e8f9f7 2024 thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);
<> 144:ef7eb2e8f9f7 2025
<> 144:ef7eb2e8f9f7 2026 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 2027 {
<> 144:ef7eb2e8f9f7 2028 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2029 EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2030 | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2031 | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2032 | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2033 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2034 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2035 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2036 break;
<> 144:ef7eb2e8f9f7 2037 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2038 EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2039 | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2040 | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2041 | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2042 | (vmonInit->enable ? EMU_VMONALTAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2043 break;
<> 144:ef7eb2e8f9f7 2044 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2045 EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2046 | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2047 | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2048 | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2049 | (vmonInit->enable ? EMU_VMONDVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2050 break;
<> 144:ef7eb2e8f9f7 2051 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2052 EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2053 | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2054 | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)
<> 144:ef7eb2e8f9f7 2055 | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2056 | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2057 | (vmonInit->enable ? EMU_VMONIO0CTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2058 break;
<> 144:ef7eb2e8f9f7 2059 default:
<> 144:ef7eb2e8f9f7 2060 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2061 return;
<> 144:ef7eb2e8f9f7 2062 }
<> 144:ef7eb2e8f9f7 2063 }
<> 144:ef7eb2e8f9f7 2064
<> 144:ef7eb2e8f9f7 2065 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2066 * @brief
<> 144:ef7eb2e8f9f7 2067 * Initialize VMON channel with hysteresis (separate rise and fall triggers).
<> 144:ef7eb2e8f9f7 2068 *
<> 144:ef7eb2e8f9f7 2069 * @details
<> 144:ef7eb2e8f9f7 2070 * Initialize a VMON channel which supports hysteresis. The AVDD channel is
<> 144:ef7eb2e8f9f7 2071 * the only channel to support separate rise and fall triggers.
<> 144:ef7eb2e8f9f7 2072 *
<> 144:ef7eb2e8f9f7 2073 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 2074 * VMON Hysteresis initialization struct
<> 144:ef7eb2e8f9f7 2075 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2076 void EMU_VmonHystInit(EMU_VmonHystInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 2077 {
<> 144:ef7eb2e8f9f7 2078 uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;
<> 144:ef7eb2e8f9f7 2079 /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */
<> 144:ef7eb2e8f9f7 2080 EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));
<> 144:ef7eb2e8f9f7 2081 EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));
<> 144:ef7eb2e8f9f7 2082 /* Fall threshold has to be lower than rise threshold */
<> 144:ef7eb2e8f9f7 2083 EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 2084
<> 144:ef7eb2e8f9f7 2085 riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 2086 riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);
<> 144:ef7eb2e8f9f7 2087 fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);
<> 144:ef7eb2e8f9f7 2088 fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);
<> 144:ef7eb2e8f9f7 2089
<> 144:ef7eb2e8f9f7 2090 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 2091 {
<> 144:ef7eb2e8f9f7 2092 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2093 EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2094 | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2095 | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2096 | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2097 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2098 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2099 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2100 break;
<> 144:ef7eb2e8f9f7 2101 default:
<> 144:ef7eb2e8f9f7 2102 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2103 return;
<> 144:ef7eb2e8f9f7 2104 }
<> 144:ef7eb2e8f9f7 2105 }
<> 144:ef7eb2e8f9f7 2106
<> 144:ef7eb2e8f9f7 2107 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2108 * @brief
<> 144:ef7eb2e8f9f7 2109 * Enable or disable a VMON channel
<> 144:ef7eb2e8f9f7 2110 *
<> 144:ef7eb2e8f9f7 2111 * @param[in] channel
<> 144:ef7eb2e8f9f7 2112 * VMON channel to enable/disable
<> 144:ef7eb2e8f9f7 2113 *
<> 144:ef7eb2e8f9f7 2114 * @param[in] enable
<> 144:ef7eb2e8f9f7 2115 * Whether to enable or disable
<> 144:ef7eb2e8f9f7 2116 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2117 void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)
<> 144:ef7eb2e8f9f7 2118 {
<> 144:ef7eb2e8f9f7 2119 uint32_t volatile * reg;
<> 144:ef7eb2e8f9f7 2120 uint32_t bit;
<> 144:ef7eb2e8f9f7 2121
<> 144:ef7eb2e8f9f7 2122 switch(channel)
<> 144:ef7eb2e8f9f7 2123 {
<> 144:ef7eb2e8f9f7 2124 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2125 reg = &(EMU->VMONAVDDCTRL);
<> 144:ef7eb2e8f9f7 2126 bit = _EMU_VMONAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2127 break;
<> 144:ef7eb2e8f9f7 2128 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2129 reg = &(EMU->VMONALTAVDDCTRL);
<> 144:ef7eb2e8f9f7 2130 bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2131 break;
<> 144:ef7eb2e8f9f7 2132 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2133 reg = &(EMU->VMONDVDDCTRL);
<> 144:ef7eb2e8f9f7 2134 bit = _EMU_VMONDVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2135 break;
<> 144:ef7eb2e8f9f7 2136 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2137 reg = &(EMU->VMONIO0CTRL);
<> 144:ef7eb2e8f9f7 2138 bit = _EMU_VMONIO0CTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2139 break;
<> 144:ef7eb2e8f9f7 2140 default:
<> 144:ef7eb2e8f9f7 2141 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2142 return;
<> 144:ef7eb2e8f9f7 2143 }
<> 144:ef7eb2e8f9f7 2144
<> 144:ef7eb2e8f9f7 2145 BUS_RegBitWrite(reg, bit, enable);
<> 144:ef7eb2e8f9f7 2146 }
<> 144:ef7eb2e8f9f7 2147
<> 144:ef7eb2e8f9f7 2148 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2149 * @brief
<> 144:ef7eb2e8f9f7 2150 * Get the status of a voltage monitor channel.
<> 144:ef7eb2e8f9f7 2151 *
<> 144:ef7eb2e8f9f7 2152 * @param[in] channel
<> 144:ef7eb2e8f9f7 2153 * VMON channel to get status for
<> 144:ef7eb2e8f9f7 2154 *
<> 144:ef7eb2e8f9f7 2155 * @return
<> 144:ef7eb2e8f9f7 2156 * Status of the selected VMON channel. True if channel is triggered.
<> 144:ef7eb2e8f9f7 2157 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2158 bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)
<> 144:ef7eb2e8f9f7 2159 {
<> 144:ef7eb2e8f9f7 2160 uint32_t bit;
<> 144:ef7eb2e8f9f7 2161 switch(channel)
<> 144:ef7eb2e8f9f7 2162 {
<> 144:ef7eb2e8f9f7 2163 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2164 bit = _EMU_STATUS_VMONAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2165 break;
<> 144:ef7eb2e8f9f7 2166 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2167 bit = _EMU_STATUS_VMONALTAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2168 break;
<> 144:ef7eb2e8f9f7 2169 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2170 bit = _EMU_STATUS_VMONDVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2171 break;
<> 144:ef7eb2e8f9f7 2172 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2173 bit = _EMU_STATUS_VMONIO0_SHIFT;
<> 144:ef7eb2e8f9f7 2174 break;
<> 144:ef7eb2e8f9f7 2175 default:
<> 144:ef7eb2e8f9f7 2176 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2177 bit = 0;
<> 144:ef7eb2e8f9f7 2178 }
<> 144:ef7eb2e8f9f7 2179
<> 144:ef7eb2e8f9f7 2180 return BUS_RegBitRead(&EMU->STATUS, bit);
<> 144:ef7eb2e8f9f7 2181 }
<> 144:ef7eb2e8f9f7 2182 #endif /* EMU_STATUS_VMONRDY */
<> 144:ef7eb2e8f9f7 2183
<> 150:02e0a0aed4ec 2184 #if defined( _SILICON_LABS_32B_PLATFORM_2_GEN_1 )
<> 150:02e0a0aed4ec 2185 /**
<> 150:02e0a0aed4ec 2186 * @brief
<> 150:02e0a0aed4ec 2187 * Adjust the bias refresh rate
<> 150:02e0a0aed4ec 2188 *
<> 150:02e0a0aed4ec 2189 * @details
<> 150:02e0a0aed4ec 2190 * This function is only meant to be used under high-temperature operation on
<> 150:02e0a0aed4ec 2191 * the first generation EFR32, Pearl and Jade. Adjusting the bias mode will
<> 150:02e0a0aed4ec 2192 * increase the typical current consumption. See application note 1027
<> 150:02e0a0aed4ec 2193 * and errata documents for further details.
<> 150:02e0a0aed4ec 2194 *
<> 150:02e0a0aed4ec 2195 * @param [in] mode
<> 150:02e0a0aed4ec 2196 * The new bias refresh rate
<> 150:02e0a0aed4ec 2197 */
<> 150:02e0a0aed4ec 2198 void EMU_SetBiasMode(EMU_BiasMode_TypeDef mode)
<> 150:02e0a0aed4ec 2199 {
<> 150:02e0a0aed4ec 2200 #define EMU_TESTLOCK (*(volatile uint32_t *) (EMU_BASE + 0x190))
<> 150:02e0a0aed4ec 2201 #define EMU_BIASCONF (*(volatile uint32_t *) (EMU_BASE + 0x164))
<> 150:02e0a0aed4ec 2202 #define EMU_BIASTESTCTRL (*(volatile uint32_t *) (EMU_BASE + 0x19C))
<> 150:02e0a0aed4ec 2203 #define CMU_ULFRCOCTRL (*(volatile uint32_t *) (CMU_BASE + 0x03C))
<> 150:02e0a0aed4ec 2204
<> 150:02e0a0aed4ec 2205 uint32_t freq = 0x2;
<> 150:02e0a0aed4ec 2206 bool emuTestLocked = false;
<> 150:02e0a0aed4ec 2207
<> 150:02e0a0aed4ec 2208 if (mode == emuBiasMode_1KHz)
<> 150:02e0a0aed4ec 2209 {
<> 150:02e0a0aed4ec 2210 freq = 0x0;
<> 150:02e0a0aed4ec 2211 }
<> 150:02e0a0aed4ec 2212
<> 150:02e0a0aed4ec 2213 if (EMU_TESTLOCK == 0x1)
<> 150:02e0a0aed4ec 2214 {
<> 150:02e0a0aed4ec 2215 emuTestLocked = true;
<> 150:02e0a0aed4ec 2216 EMU_TESTLOCK = 0xADE8;
<> 150:02e0a0aed4ec 2217 }
<> 150:02e0a0aed4ec 2218
<> 150:02e0a0aed4ec 2219 if (mode == emuBiasMode_Continuous)
<> 150:02e0a0aed4ec 2220 {
<> 150:02e0a0aed4ec 2221 EMU_BIASCONF &= ~0x74;
<> 150:02e0a0aed4ec 2222 }
<> 150:02e0a0aed4ec 2223 else
<> 150:02e0a0aed4ec 2224 {
<> 150:02e0a0aed4ec 2225 EMU_BIASCONF |= 0x74;
<> 150:02e0a0aed4ec 2226 }
<> 150:02e0a0aed4ec 2227
<> 150:02e0a0aed4ec 2228 EMU_BIASTESTCTRL |= 0x8;
<> 150:02e0a0aed4ec 2229 CMU_ULFRCOCTRL = (CMU_ULFRCOCTRL & ~0xC00)
<> 150:02e0a0aed4ec 2230 | ((freq & 0x3) << 10);
<> 150:02e0a0aed4ec 2231 EMU_BIASTESTCTRL &= ~0x8;
<> 150:02e0a0aed4ec 2232
<> 150:02e0a0aed4ec 2233 if (emuTestLocked)
<> 150:02e0a0aed4ec 2234 {
<> 150:02e0a0aed4ec 2235 EMU_TESTLOCK = 0;
<> 150:02e0a0aed4ec 2236 }
<> 150:02e0a0aed4ec 2237 }
<> 150:02e0a0aed4ec 2238 #endif
<> 150:02e0a0aed4ec 2239
<> 144:ef7eb2e8f9f7 2240 /** @} (end addtogroup EMU) */
<> 150:02e0a0aed4ec 2241 /** @} (end addtogroup emlib) */
<> 144:ef7eb2e8f9f7 2242 #endif /* __EM_EMU_H */