mbed library sources. Supersedes mbed-src.

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

Committer:
<>
Date:
Thu Mar 30 13:45:57 2017 +0100
Revision:
161:2cc1468da177
Parent:
150:02e0a0aed4ec
Child:
179:b0033dcd6934
This updates the lib to the mbed lib v139

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
<> 161:2cc1468da177 4 * @version 5.1.2
<> 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 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 161:2cc1468da177 74 #if defined( _SILICON_LABS_32B_SERIES_0 )
<> 161:2cc1468da177 75 /* Fix for errata EMU_E107 - non-WIC interrupt masks.
<> 161:2cc1468da177 76 * Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 77 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 78 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 79 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
<> 144:ef7eb2e8f9f7 80 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 81
<> 144:ef7eb2e8f9f7 82 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 83 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 84 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
<> 144:ef7eb2e8f9f7 85 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 86
<> 144:ef7eb2e8f9f7 87 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 88 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 89 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 90 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 91
<> 144:ef7eb2e8f9f7 92 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 93 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 94 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 95 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 96
<> 161:2cc1468da177 97 #endif
<> 144:ef7eb2e8f9f7 98 #endif
<> 144:ef7eb2e8f9f7 99
<> 144:ef7eb2e8f9f7 100 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 161:2cc1468da177 101 #if defined(_SILICON_LABS_32B_SERIES_0) && 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 */
<> 161:2cc1468da177 106 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 150:02e0a0aed4ec 107 #define ERRATA_FIX_EMU_E208_EN
<> 150:02e0a0aed4ec 108 #endif
<> 150:02e0a0aed4ec 109
<> 150:02e0a0aed4ec 110 /* Enable FETCNT tuning errata fix */
<> 161:2cc1468da177 111 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 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 */
<> 161:2cc1468da177 116 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 150:02e0a0aed4ec 117 #define ERRATA_FIX_DCDC_LNHS_BLOCK_EN
<> 161:2cc1468da177 118 typedef enum
<> 161:2cc1468da177 119 {
<> 161:2cc1468da177 120 errataFixDcdcHsInit,
<> 161:2cc1468da177 121 errataFixDcdcHsTrimSet,
<> 161:2cc1468da177 122 errataFixDcdcHsBypassLn,
<> 161:2cc1468da177 123 errataFixDcdcHsLnWaitDone
<> 161:2cc1468da177 124 } errataFixDcdcHs_TypeDef;
<> 161:2cc1468da177 125 static errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;
<> 150:02e0a0aed4ec 126 #endif
<> 150:02e0a0aed4ec 127
<> 161:2cc1468da177 128 /* Used to figure out if a memory address is inside or outside of a RAM block.
<> 161:2cc1468da177 129 * A memory address is inside a RAM block if the address is greater than the
<> 161:2cc1468da177 130 * RAM block address. */
<> 161:2cc1468da177 131 #define ADDRESS_NOT_IN_BLOCK(addr, block) ((addr) <= (block))
<> 161:2cc1468da177 132
<> 161:2cc1468da177 133 /* RAM Block layout for various device families. Note that some devices
<> 161:2cc1468da177 134 * have special layout in RAM0. */
<> 161:2cc1468da177 135 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84)
<> 161:2cc1468da177 136 #define RAM1_BLOCKS 2
<> 161:2cc1468da177 137 #define RAM1_BLOCK_SIZE 0x10000 // 64 kB blocks
<> 161:2cc1468da177 138 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
<> 161:2cc1468da177 139 #define RAM0_BLOCKS 2
<> 161:2cc1468da177 140 #define RAM0_BLOCK_SIZE 0x4000
<> 161:2cc1468da177 141 #define RAM1_BLOCKS 2
<> 161:2cc1468da177 142 #define RAM1_BLOCK_SIZE 0x4000 // 16 kB blocks
<> 161:2cc1468da177 143 #elif defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GIANT_FAMILY)
<> 161:2cc1468da177 144 #define RAM0_BLOCKS 4
<> 161:2cc1468da177 145 #define RAM0_BLOCK_SIZE 0x8000 // 32 kB blocks
<> 161:2cc1468da177 146 #elif defined(_SILICON_LABS_32B_SERIES_0) && defined(_EFM32_GECKO_FAMILY)
<> 161:2cc1468da177 147 #define RAM0_BLOCKS 4
<> 161:2cc1468da177 148 #define RAM0_BLOCK_SIZE 0x1000 // 4 kB blocks
<> 150:02e0a0aed4ec 149 #endif
<> 150:02e0a0aed4ec 150
<> 161:2cc1468da177 151 #if defined(_SILICON_LABS_32B_SERIES_0)
<> 161:2cc1468da177 152 /* RAM_MEM_END on Gecko devices have a value larger than the SRAM_SIZE */
<> 161:2cc1468da177 153 #define RAM0_END (SRAM_BASE + SRAM_SIZE - 1)
<> 161:2cc1468da177 154 #else
<> 161:2cc1468da177 155 #define RAM0_END RAM_MEM_END
<> 150:02e0a0aed4ec 156 #endif
<> 150:02e0a0aed4ec 157
<> 144:ef7eb2e8f9f7 158 /** @endcond */
<> 144:ef7eb2e8f9f7 159
<> 144:ef7eb2e8f9f7 160
<> 144:ef7eb2e8f9f7 161 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 162 /* DCDCTODVDD output range min/max */
<> 150:02e0a0aed4ec 163 #if !defined(PWRCFG_DCDCTODVDD_VMIN)
<> 150:02e0a0aed4ec 164 #define PWRCFG_DCDCTODVDD_VMIN 1800
<> 150:02e0a0aed4ec 165 #endif
<> 150:02e0a0aed4ec 166 #if !defined(PWRCFG_DCDCTODVDD_VMAX)
<> 144:ef7eb2e8f9f7 167 #define PWRCFG_DCDCTODVDD_VMAX 3000
<> 150:02e0a0aed4ec 168 #endif
<> 144:ef7eb2e8f9f7 169 #endif
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 /*******************************************************************************
<> 161:2cc1468da177 172 *************************** LOCAL VARIABLES ********************************
<> 144:ef7eb2e8f9f7 173 ******************************************************************************/
<> 144:ef7eb2e8f9f7 174
<> 144:ef7eb2e8f9f7 175 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 161:2cc1468da177 176
<> 161:2cc1468da177 177 /* Static user configuration */
<> 144:ef7eb2e8f9f7 178 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 179 static uint16_t dcdcMaxCurrent_mA;
<> 150:02e0a0aed4ec 180 static uint16_t dcdcEm01LoadCurrent_mA;
<> 150:02e0a0aed4ec 181 static EMU_DcdcLnReverseCurrentControl_TypeDef dcdcReverseCurrentControl;
<> 144:ef7eb2e8f9f7 182 #endif
<> 161:2cc1468da177 183 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 184 static EMU_EM01Init_TypeDef vScaleEM01Config = {false};
<> 161:2cc1468da177 185 #endif
<> 144:ef7eb2e8f9f7 186 /** @endcond */
<> 144:ef7eb2e8f9f7 187
<> 144:ef7eb2e8f9f7 188
<> 144:ef7eb2e8f9f7 189 /*******************************************************************************
<> 144:ef7eb2e8f9f7 190 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 191 ******************************************************************************/
<> 144:ef7eb2e8f9f7 192
<> 144:ef7eb2e8f9f7 193 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 194
<> 161:2cc1468da177 195 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 196 /* Convert from level to EM0 and 1 command bit */
<> 161:2cc1468da177 197 __STATIC_INLINE uint32_t vScaleEM01Cmd(EMU_VScaleEM01_TypeDef level)
<> 161:2cc1468da177 198 {
<> 161:2cc1468da177 199 return EMU_CMD_EM01VSCALE0 << (_EMU_STATUS_VSCALE_VSCALE0 - (uint32_t)level);
<> 161:2cc1468da177 200 }
<> 161:2cc1468da177 201 #endif
<> 161:2cc1468da177 202
<> 144:ef7eb2e8f9f7 203 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 204 * @brief
<> 161:2cc1468da177 205 * Save/restore/update oscillator, core clock and voltage scaling configuration on
<> 161:2cc1468da177 206 * EM2 or EM3 entry/exit.
<> 161:2cc1468da177 207 *
<> 161:2cc1468da177 208 * @details
<> 161:2cc1468da177 209 * Hardware may automatically change oscillator and voltage scaling configuration
<> 161:2cc1468da177 210 * when going into or out of an energy mode. Static data in this function keeps track of
<> 161:2cc1468da177 211 * such configuration bits and is used to restore state if needed.
<> 161:2cc1468da177 212 *
<> 144:ef7eb2e8f9f7 213 ******************************************************************************/
<> 161:2cc1468da177 214 typedef enum
<> 161:2cc1468da177 215 {
<> 161:2cc1468da177 216 emState_Save, /* Save EMU and CMU state */
<> 161:2cc1468da177 217 emState_Restore, /* Restore and unlock */
<> 161:2cc1468da177 218 } emState_TypeDef;
<> 161:2cc1468da177 219
<> 161:2cc1468da177 220 static void emState(emState_TypeDef action)
<> 144:ef7eb2e8f9f7 221 {
<> 144:ef7eb2e8f9f7 222 uint32_t oscEnCmd;
<> 144:ef7eb2e8f9f7 223 uint32_t cmuLocked;
<> 161:2cc1468da177 224 static uint32_t cmuStatus;
<> 161:2cc1468da177 225 static CMU_Select_TypeDef hfClock;
<> 161:2cc1468da177 226 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 227 static uint8_t vScaleStatus;
<> 144:ef7eb2e8f9f7 228 #endif
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230
<> 161:2cc1468da177 231 /* Save or update state */
<> 161:2cc1468da177 232 if (action == emState_Save)
<> 144:ef7eb2e8f9f7 233 {
<> 161:2cc1468da177 234 /* Save configuration. */
<> 161:2cc1468da177 235 cmuStatus = CMU->STATUS;
<> 161:2cc1468da177 236 hfClock = CMU_ClockSelectGet(cmuClock_HF);
<> 161:2cc1468da177 237 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 238 /* Save vscale */
<> 161:2cc1468da177 239 EMU_VScaleWait();
<> 161:2cc1468da177 240 vScaleStatus = (uint8_t)((EMU->STATUS & _EMU_STATUS_VSCALE_MASK)
<> 161:2cc1468da177 241 >> _EMU_STATUS_VSCALE_SHIFT);
<> 150:02e0a0aed4ec 242 #endif
<> 144:ef7eb2e8f9f7 243 }
<> 161:2cc1468da177 244 else if (action == emState_Restore) /* Restore state */
<> 144:ef7eb2e8f9f7 245 {
<> 161:2cc1468da177 246 /* Apply saved configuration. */
<> 161:2cc1468da177 247 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 248 /* Restore EM0 and 1 voltage scaling level. EMU_VScaleWait() is called later,
<> 161:2cc1468da177 249 just before HF clock select is set. */
<> 161:2cc1468da177 250 EMU->CMD = vScaleEM01Cmd((EMU_VScaleEM01_TypeDef)vScaleStatus);
<> 144:ef7eb2e8f9f7 251 #endif
<> 144:ef7eb2e8f9f7 252
<> 161:2cc1468da177 253 /* CMU registers may be locked */
<> 161:2cc1468da177 254 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 161:2cc1468da177 255 CMU_Unlock();
<> 161:2cc1468da177 256
<> 161:2cc1468da177 257 /* AUXHFRCO are automatically disabled (except if using debugger). */
<> 161:2cc1468da177 258 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
<> 161:2cc1468da177 259 /* LFRCO/LFXO may be disabled by SW in EM3. */
<> 161:2cc1468da177 260 /* Restore according to status prior to entering energy mode. */
<> 161:2cc1468da177 261 oscEnCmd = 0;
<> 161:2cc1468da177 262 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
<> 161:2cc1468da177 263 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
<> 161:2cc1468da177 264 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
<> 161:2cc1468da177 265 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
<> 161:2cc1468da177 266 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
<> 161:2cc1468da177 267 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
<> 161:2cc1468da177 268 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
<> 161:2cc1468da177 269 #endif
<> 161:2cc1468da177 270 CMU->OSCENCMD = oscEnCmd;
<> 144:ef7eb2e8f9f7 271
<> 161:2cc1468da177 272 #if defined( _EMU_STATUS_VSCALE_MASK )
<> 161:2cc1468da177 273 /* Wait for upscale to complete and then restore selected clock */
<> 161:2cc1468da177 274 EMU_VScaleWait();
<> 144:ef7eb2e8f9f7 275 #endif
<> 161:2cc1468da177 276
<> 161:2cc1468da177 277 if (hfClock != cmuSelect_HFRCO)
<> 161:2cc1468da177 278 {
<> 161:2cc1468da177 279 CMU_ClockSelectSet(cmuClock_HF, hfClock);
<> 161:2cc1468da177 280 }
<> 161:2cc1468da177 281
<> 161:2cc1468da177 282 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
<> 161:2cc1468da177 283 /* as it is automatically enabled by wake up */
<> 161:2cc1468da177 284 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
<> 161:2cc1468da177 285 {
<> 161:2cc1468da177 286 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
<> 161:2cc1468da177 287 }
<> 161:2cc1468da177 288
<> 161:2cc1468da177 289 /* Restore CMU register locking */
<> 161:2cc1468da177 290 if (cmuLocked)
<> 161:2cc1468da177 291 {
<> 161:2cc1468da177 292 CMU_Lock();
<> 161:2cc1468da177 293 }
<> 144:ef7eb2e8f9f7 294 }
<> 144:ef7eb2e8f9f7 295 }
<> 144:ef7eb2e8f9f7 296
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 299 /* Get enable conditions for errata EMU_E107 fix. */
<> 150:02e0a0aed4ec 300 __STATIC_INLINE bool getErrataFixEmuE107En(void)
<> 144:ef7eb2e8f9f7 301 {
<> 144:ef7eb2e8f9f7 302 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a
<> 144:ef7eb2e8f9f7 303 * faster implementation in this case.
<> 144:ef7eb2e8f9f7 304 */
<> 144:ef7eb2e8f9f7 305 uint16_t majorMinorRev;
<> 144:ef7eb2e8f9f7 306
<> 144:ef7eb2e8f9f7 307 /* CHIP MAJOR bit [3:0] */
<> 144:ef7eb2e8f9f7 308 majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
<> 144:ef7eb2e8f9f7 309 >> _ROMTABLE_PID0_REVMAJOR_SHIFT)
<> 144:ef7eb2e8f9f7 310 << 8;
<> 144:ef7eb2e8f9f7 311 /* CHIP MINOR bit [7:4] */
<> 144:ef7eb2e8f9f7 312 majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
<> 144:ef7eb2e8f9f7 313 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT)
<> 144:ef7eb2e8f9f7 314 << 4;
<> 144:ef7eb2e8f9f7 315 /* CHIP MINOR bit [3:0] */
<> 144:ef7eb2e8f9f7 316 majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
<> 144:ef7eb2e8f9f7 317 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT;
<> 144:ef7eb2e8f9f7 318
<> 144:ef7eb2e8f9f7 319 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 320 return (majorMinorRev <= 0x0103);
<> 144:ef7eb2e8f9f7 321 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 322 return (majorMinorRev <= 0x0102);
<> 144:ef7eb2e8f9f7 323 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 324 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
<> 144:ef7eb2e8f9f7 325 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 326 return (majorMinorRev == 0x0100);
<> 144:ef7eb2e8f9f7 327 #else
<> 144:ef7eb2e8f9f7 328 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 329 return false;
<> 144:ef7eb2e8f9f7 330 #endif
<> 144:ef7eb2e8f9f7 331 }
<> 144:ef7eb2e8f9f7 332 #endif
<> 144:ef7eb2e8f9f7 333
<> 144:ef7eb2e8f9f7 334 /* LP prepare / LN restore P/NFET count */
<> 144:ef7eb2e8f9f7 335 #define DCDC_LP_PFET_CNT 7
<> 150:02e0a0aed4ec 336 #define DCDC_LP_NFET_CNT 7
<> 150:02e0a0aed4ec 337 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 150:02e0a0aed4ec 338 static void currentLimitersUpdate(void);
<> 150:02e0a0aed4ec 339 static void dcdcFetCntSet(bool lpModeSet)
<> 144:ef7eb2e8f9f7 340 {
<> 144:ef7eb2e8f9f7 341 uint32_t tmp;
<> 144:ef7eb2e8f9f7 342 static uint32_t emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 343
<> 144:ef7eb2e8f9f7 344 if (lpModeSet)
<> 144:ef7eb2e8f9f7 345 {
<> 144:ef7eb2e8f9f7 346 emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;
<> 144:ef7eb2e8f9f7 347 tmp = EMU->DCDCMISCCTRL
<> 144:ef7eb2e8f9f7 348 & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);
<> 144:ef7eb2e8f9f7 349 tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)
<> 144:ef7eb2e8f9f7 350 | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 351 EMU->DCDCMISCCTRL = tmp;
<> 150:02e0a0aed4ec 352 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 353 }
<> 144:ef7eb2e8f9f7 354 else
<> 144:ef7eb2e8f9f7 355 {
<> 144:ef7eb2e8f9f7 356 EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;
<> 150:02e0a0aed4ec 357 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 358 }
<> 144:ef7eb2e8f9f7 359 }
<> 150:02e0a0aed4ec 360 #endif
<> 144:ef7eb2e8f9f7 361
<> 150:02e0a0aed4ec 362 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 150:02e0a0aed4ec 363 static void dcdcHsFixLnBlock(void)
<> 144:ef7eb2e8f9f7 364 {
<> 144:ef7eb2e8f9f7 365 #define EMU_DCDCSTATUS (* (volatile uint32_t *)(EMU_BASE + 0x7C))
<> 150:02e0a0aed4ec 366 if ((errataFixDcdcHsState == errataFixDcdcHsTrimSet)
<> 150:02e0a0aed4ec 367 || (errataFixDcdcHsState == errataFixDcdcHsBypassLn))
<> 144:ef7eb2e8f9f7 368 {
<> 144:ef7eb2e8f9f7 369 /* Wait for LNRUNNING */
<> 150:02e0a0aed4ec 370 if ((EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
<> 144:ef7eb2e8f9f7 371 {
<> 144:ef7eb2e8f9f7 372 while (!(EMU_DCDCSTATUS & (0x1 << 16)));
<> 144:ef7eb2e8f9f7 373 }
<> 144:ef7eb2e8f9f7 374 errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;
<> 144:ef7eb2e8f9f7 375 }
<> 144:ef7eb2e8f9f7 376 }
<> 144:ef7eb2e8f9f7 377 #endif
<> 144:ef7eb2e8f9f7 378
<> 144:ef7eb2e8f9f7 379
<> 161:2cc1468da177 380 #if defined( _EMU_CTRL_EM23VSCALE_MASK )
<> 161:2cc1468da177 381 /* Configure EMU and CMU for EM2 and 3 voltage downscale */
<> 161:2cc1468da177 382 static void vScaleDownEM23Setup(void)
<> 161:2cc1468da177 383 {
<> 161:2cc1468da177 384 uint32_t hfSrcClockFrequency;
<> 150:02e0a0aed4ec 385
<> 161:2cc1468da177 386 EMU_VScaleEM23_TypeDef scaleEM23Voltage =
<> 161:2cc1468da177 387 (EMU_VScaleEM23_TypeDef)((EMU->CTRL & _EMU_CTRL_EM23VSCALE_MASK)
<> 161:2cc1468da177 388 >> _EMU_CTRL_EM23VSCALE_SHIFT);
<> 161:2cc1468da177 389
<> 161:2cc1468da177 390 EMU_VScaleEM01_TypeDef currentEM01Voltage =
<> 161:2cc1468da177 391 (EMU_VScaleEM01_TypeDef)((EMU->STATUS & _EMU_STATUS_VSCALE_MASK)
<> 161:2cc1468da177 392 >> _EMU_STATUS_VSCALE_SHIFT);
<> 161:2cc1468da177 393
<> 161:2cc1468da177 394 /* Wait until previous scaling is done. */
<> 161:2cc1468da177 395 EMU_VScaleWait();
<> 161:2cc1468da177 396
<> 161:2cc1468da177 397 /* Inverse coding. */
<> 161:2cc1468da177 398 if ((uint32_t)scaleEM23Voltage > (uint32_t)currentEM01Voltage)
<> 161:2cc1468da177 399 {
<> 161:2cc1468da177 400 /* Set safe clock and wait-states. */
<> 161:2cc1468da177 401 if (scaleEM23Voltage == emuVScaleEM23_LowPower)
<> 161:2cc1468da177 402 {
<> 161:2cc1468da177 403 hfSrcClockFrequency = CMU_ClockDivGet(cmuClock_HF) * CMU_ClockFreqGet(cmuClock_HF);
<> 161:2cc1468da177 404 /* Set default low power voltage HFRCO band as HF clock. */
<> 161:2cc1468da177 405 if (hfSrcClockFrequency > CMU_VSCALEEM01_LOWPOWER_VOLTAGE_CLOCK_MAX)
<> 161:2cc1468da177 406 {
<> 161:2cc1468da177 407 CMU_HFRCOBandSet(cmuHFRCOFreq_19M0Hz);
<> 161:2cc1468da177 408 }
<> 161:2cc1468da177 409 CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
<> 161:2cc1468da177 410 }
<> 161:2cc1468da177 411 else
<> 161:2cc1468da177 412 {
<> 161:2cc1468da177 413 /* Other voltage scaling levels are not currently supported. */
<> 161:2cc1468da177 414 EFM_ASSERT(false);
<> 161:2cc1468da177 415 }
<> 161:2cc1468da177 416 }
<> 161:2cc1468da177 417 else
<> 161:2cc1468da177 418 {
<> 161:2cc1468da177 419 /* Same voltage or hardware will scale to min(EMU_CTRL_EM23VSCALE, EMU_STATUS_VSCALE) */
<> 161:2cc1468da177 420 }
<> 161:2cc1468da177 421 }
<> 161:2cc1468da177 422 #endif
<> 144:ef7eb2e8f9f7 423 /** @endcond */
<> 144:ef7eb2e8f9f7 424
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 /*******************************************************************************
<> 144:ef7eb2e8f9f7 427 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 428 ******************************************************************************/
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 431 * @brief
<> 144:ef7eb2e8f9f7 432 * Enter energy mode 2 (EM2).
<> 144:ef7eb2e8f9f7 433 *
<> 144:ef7eb2e8f9f7 434 * @details
<> 144:ef7eb2e8f9f7 435 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
<> 144:ef7eb2e8f9f7 436 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
<> 144:ef7eb2e8f9f7 437 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
<> 144:ef7eb2e8f9f7 438 * HFRCO band. This ensures a quick wakeup from EM2.
<> 144:ef7eb2e8f9f7 439 *
<> 144:ef7eb2e8f9f7 440 * However, prior to entering EM2, the core may have been using another
<> 144:ef7eb2e8f9f7 441 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 442 * to restore all HF oscillators according to state prior to entering EM2,
<> 144:ef7eb2e8f9f7 443 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 444 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 445 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 446 *
<> 144:ef7eb2e8f9f7 447 * @note
<> 144:ef7eb2e8f9f7 448 * If restoring core clock to use the HFXO oscillator, which has been
<> 144:ef7eb2e8f9f7 449 * disabled during EM2 mode, this function will stall until the oscillator
<> 144:ef7eb2e8f9f7 450 * has stabilized. Stalling time can be reduced by adding interrupt
<> 144:ef7eb2e8f9f7 451 * support detecting stable oscillator, and an asynchronous switch to the
<> 144:ef7eb2e8f9f7 452 * original oscillator. See CMU documentation. Such a feature is however
<> 144:ef7eb2e8f9f7 453 * outside the scope of the implementation in this function.
<> 144:ef7eb2e8f9f7 454 * @par
<> 144:ef7eb2e8f9f7 455 * If HFXO is re-enabled by this function, and NOT used to clock the core,
<> 144:ef7eb2e8f9f7 456 * this function will not wait for HFXO to stabilize. This must be considered
<> 144:ef7eb2e8f9f7 457 * by the application if trying to use features relying on that oscillator
<> 144:ef7eb2e8f9f7 458 * upon return.
<> 144:ef7eb2e8f9f7 459 * @par
<> 144:ef7eb2e8f9f7 460 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 461 * upon entering EM2. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 462 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 463 * @par
<> 144:ef7eb2e8f9f7 464 * If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
<> 144:ef7eb2e8f9f7 465 * the starting and selecting of the core clocks will be identical to the user
<> 144:ef7eb2e8f9f7 466 * independently of the value of the @p restore parameter when waking up on
<> 144:ef7eb2e8f9f7 467 * the wakeup sources corresponding to the autostart and select setting.
<> 161:2cc1468da177 468 * @par
<> 161:2cc1468da177 469 * If voltage scaling is supported, the restore parameter is true and the EM0
<> 161:2cc1468da177 470 * voltage scaling level is set higher than the EM2 level, then the EM0 level is
<> 161:2cc1468da177 471 * also restored.
<> 144:ef7eb2e8f9f7 472 *
<> 144:ef7eb2e8f9f7 473 * @param[in] restore
<> 161:2cc1468da177 474 * @li true - restore oscillators, clocks and voltage scaling, see function details.
<> 144:ef7eb2e8f9f7 475 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 476 * @par
<> 144:ef7eb2e8f9f7 477 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 478 * via the CMU API.
<> 144:ef7eb2e8f9f7 479 ******************************************************************************/
<> 144:ef7eb2e8f9f7 480 void EMU_EnterEM2(bool restore)
<> 144:ef7eb2e8f9f7 481 {
<> 144:ef7eb2e8f9f7 482 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 483 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 484 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 485 #endif
<> 144:ef7eb2e8f9f7 486
<> 161:2cc1468da177 487 /* Save EMU and CMU state requiring restore on EM2 exit. */
<> 161:2cc1468da177 488 emState(emState_Save);
<> 161:2cc1468da177 489
<> 161:2cc1468da177 490 #if defined( _EMU_CTRL_EM23VSCALE_MASK )
<> 161:2cc1468da177 491 vScaleDownEM23Setup();
<> 144:ef7eb2e8f9f7 492 #endif
<> 144:ef7eb2e8f9f7 493
<> 144:ef7eb2e8f9f7 494 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 495 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 496
<> 144:ef7eb2e8f9f7 497 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 498 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 499 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 500 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 501 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 502 {
<> 144:ef7eb2e8f9f7 503 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 504 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 505 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 506 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 507 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 508 #endif
<> 144:ef7eb2e8f9f7 509 }
<> 144:ef7eb2e8f9f7 510 #endif
<> 144:ef7eb2e8f9f7 511
<> 150:02e0a0aed4ec 512 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 513 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 514 #endif
<> 150:02e0a0aed4ec 515 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 516 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 517 #endif
<> 144:ef7eb2e8f9f7 518
<> 144:ef7eb2e8f9f7 519 __WFI();
<> 144:ef7eb2e8f9f7 520
<> 150:02e0a0aed4ec 521 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 522 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 523 #endif
<> 144:ef7eb2e8f9f7 524
<> 144:ef7eb2e8f9f7 525 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 526 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 527 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 528 {
<> 144:ef7eb2e8f9f7 529 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 530 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 531 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 532 #endif
<> 144:ef7eb2e8f9f7 533 }
<> 144:ef7eb2e8f9f7 534 #endif
<> 144:ef7eb2e8f9f7 535
<> 161:2cc1468da177 536 /* Restore oscillators/clocks and voltage scaling if supported. */
<> 144:ef7eb2e8f9f7 537 if (restore)
<> 144:ef7eb2e8f9f7 538 {
<> 161:2cc1468da177 539 emState(emState_Restore);
<> 144:ef7eb2e8f9f7 540 }
<> 161:2cc1468da177 541 else
<> 144:ef7eb2e8f9f7 542 {
<> 161:2cc1468da177 543 /* If not restoring, and original clock was not HFRCO, we have to */
<> 161:2cc1468da177 544 /* update CMSIS core clock variable since HF clock has changed */
<> 161:2cc1468da177 545 /* to HFRCO. */
<> 144:ef7eb2e8f9f7 546 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 547 }
<> 144:ef7eb2e8f9f7 548 }
<> 144:ef7eb2e8f9f7 549
<> 144:ef7eb2e8f9f7 550
<> 144:ef7eb2e8f9f7 551 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 552 * @brief
<> 144:ef7eb2e8f9f7 553 * Enter energy mode 3 (EM3).
<> 144:ef7eb2e8f9f7 554 *
<> 144:ef7eb2e8f9f7 555 * @details
<> 144:ef7eb2e8f9f7 556 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
<> 144:ef7eb2e8f9f7 557 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
<> 144:ef7eb2e8f9f7 558 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
<> 144:ef7eb2e8f9f7 559 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
<> 144:ef7eb2e8f9f7 560 * configured HFRCO band. This ensures a quick wakeup from EM3.
<> 144:ef7eb2e8f9f7 561 *
<> 144:ef7eb2e8f9f7 562 * However, prior to entering EM3, the core may have been using another
<> 144:ef7eb2e8f9f7 563 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 564 * to restore all HF/LF oscillators according to state prior to entering EM3,
<> 144:ef7eb2e8f9f7 565 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 566 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 567 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 568 *
<> 144:ef7eb2e8f9f7 569 * @note
<> 144:ef7eb2e8f9f7 570 * If restoring core clock to use an oscillator other than HFRCO, this
<> 144:ef7eb2e8f9f7 571 * function will stall until the oscillator has stabilized. Stalling time
<> 144:ef7eb2e8f9f7 572 * can be reduced by adding interrupt support detecting stable oscillator,
<> 144:ef7eb2e8f9f7 573 * and an asynchronous switch to the original oscillator. See CMU
<> 144:ef7eb2e8f9f7 574 * documentation. Such a feature is however outside the scope of the
<> 144:ef7eb2e8f9f7 575 * implementation in this function.
<> 144:ef7eb2e8f9f7 576 * @par
<> 144:ef7eb2e8f9f7 577 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
<> 144:ef7eb2e8f9f7 578 * the core, this function will not wait for those oscillators to stabilize.
<> 144:ef7eb2e8f9f7 579 * This must be considered by the application if trying to use features
<> 144:ef7eb2e8f9f7 580 * relying on those oscillators upon return.
<> 144:ef7eb2e8f9f7 581 * @par
<> 144:ef7eb2e8f9f7 582 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 583 * upon entering EM3. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 584 * regardless of the @p restore parameter.
<> 161:2cc1468da177 585 * @par
<> 161:2cc1468da177 586 * If voltage scaling is supported, the restore parameter is true and the EM0
<> 161:2cc1468da177 587 * voltage scaling level is set higher than the EM3 level, then the EM0 level is
<> 161:2cc1468da177 588 * also restored.
<> 144:ef7eb2e8f9f7 589 *
<> 144:ef7eb2e8f9f7 590 * @param[in] restore
<> 161:2cc1468da177 591 * @li true - restore oscillators, clocks and voltage scaling, see function details.
<> 144:ef7eb2e8f9f7 592 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 593 * @par
<> 144:ef7eb2e8f9f7 594 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 595 * via the CMU API.
<> 144:ef7eb2e8f9f7 596 ******************************************************************************/
<> 144:ef7eb2e8f9f7 597 void EMU_EnterEM3(bool restore)
<> 144:ef7eb2e8f9f7 598 {
<> 144:ef7eb2e8f9f7 599 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 600
<> 144:ef7eb2e8f9f7 601 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 602 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 603 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 604 #endif
<> 144:ef7eb2e8f9f7 605
<> 161:2cc1468da177 606 /* Save EMU and CMU state requiring restore on EM2 exit. */
<> 161:2cc1468da177 607 emState(emState_Save);
<> 161:2cc1468da177 608
<> 161:2cc1468da177 609 #if defined( _EMU_CTRL_EM23VSCALE_MASK )
<> 161:2cc1468da177 610 vScaleDownEM23Setup();
<> 144:ef7eb2e8f9f7 611 #endif
<> 144:ef7eb2e8f9f7 612
<> 144:ef7eb2e8f9f7 613 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 614 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 615 CMU_Unlock();
<> 144:ef7eb2e8f9f7 616
<> 144:ef7eb2e8f9f7 617 /* Disable LF oscillators */
<> 144:ef7eb2e8f9f7 618 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
<> 144:ef7eb2e8f9f7 619
<> 144:ef7eb2e8f9f7 620 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 621 if (cmuLocked)
<> 144:ef7eb2e8f9f7 622 {
<> 144:ef7eb2e8f9f7 623 CMU_Lock();
<> 144:ef7eb2e8f9f7 624 }
<> 144:ef7eb2e8f9f7 625
<> 144:ef7eb2e8f9f7 626 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 627 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 628
<> 144:ef7eb2e8f9f7 629 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 630 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 631 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 632 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 633 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 634 {
<> 144:ef7eb2e8f9f7 635 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 636 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 637 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 638 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 639 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 640 #endif
<> 144:ef7eb2e8f9f7 641 }
<> 144:ef7eb2e8f9f7 642 #endif
<> 144:ef7eb2e8f9f7 643
<> 150:02e0a0aed4ec 644 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 645 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 646 #endif
<> 150:02e0a0aed4ec 647 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 648 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 649 #endif
<> 144:ef7eb2e8f9f7 650
<> 144:ef7eb2e8f9f7 651 __WFI();
<> 144:ef7eb2e8f9f7 652
<> 150:02e0a0aed4ec 653 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 654 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 655 #endif
<> 144:ef7eb2e8f9f7 656
<> 144:ef7eb2e8f9f7 657 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 658 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 659 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 660 {
<> 144:ef7eb2e8f9f7 661 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 662 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 663 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 664 #endif
<> 144:ef7eb2e8f9f7 665 }
<> 144:ef7eb2e8f9f7 666 #endif
<> 144:ef7eb2e8f9f7 667
<> 161:2cc1468da177 668 /* Restore oscillators/clocks and voltage scaling if supported. */
<> 144:ef7eb2e8f9f7 669 if (restore)
<> 144:ef7eb2e8f9f7 670 {
<> 161:2cc1468da177 671 emState(emState_Restore);
<> 144:ef7eb2e8f9f7 672 }
<> 161:2cc1468da177 673 else
<> 144:ef7eb2e8f9f7 674 {
<> 161:2cc1468da177 675 /* If not restoring, and original clock was not HFRCO, we have to */
<> 161:2cc1468da177 676 /* update CMSIS core clock variable since HF clock has changed */
<> 161:2cc1468da177 677 /* to HFRCO. */
<> 144:ef7eb2e8f9f7 678 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 679 }
<> 144:ef7eb2e8f9f7 680 }
<> 144:ef7eb2e8f9f7 681
<> 144:ef7eb2e8f9f7 682
<> 144:ef7eb2e8f9f7 683 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 684 * @brief
<> 161:2cc1468da177 685 * Restore CMU HF clock select state, oscillator enable and voltage scaling
<> 161:2cc1468da177 686 * (if available) after @ref EMU_EnterEM2() or @ref EMU_EnterEM3() are called
<> 161:2cc1468da177 687 * with the restore parameter set to false. Calling this function is
<> 161:2cc1468da177 688 * equivalent to calling @ref EMU_EnterEM2() or @ref EMU_EnterEM3() with the
<> 161:2cc1468da177 689 * restore parameter set to true, but it allows the application to evaluate the
<> 161:2cc1468da177 690 * wakeup reason before restoring state.
<> 161:2cc1468da177 691 ******************************************************************************/
<> 161:2cc1468da177 692 void EMU_Restore(void)
<> 161:2cc1468da177 693 {
<> 161:2cc1468da177 694 emState(emState_Restore);
<> 161:2cc1468da177 695 }
<> 161:2cc1468da177 696
<> 161:2cc1468da177 697
<> 161:2cc1468da177 698 /***************************************************************************//**
<> 161:2cc1468da177 699 * @brief
<> 144:ef7eb2e8f9f7 700 * Enter energy mode 4 (EM4).
<> 144:ef7eb2e8f9f7 701 *
<> 144:ef7eb2e8f9f7 702 * @note
<> 144:ef7eb2e8f9f7 703 * Only a power on reset or external reset pin can wake the device from EM4.
<> 144:ef7eb2e8f9f7 704 ******************************************************************************/
<> 144:ef7eb2e8f9f7 705 void EMU_EnterEM4(void)
<> 144:ef7eb2e8f9f7 706 {
<> 144:ef7eb2e8f9f7 707 int i;
<> 144:ef7eb2e8f9f7 708
<> 144:ef7eb2e8f9f7 709 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 710 uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 711 | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 712 uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 713 | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 714 #else
<> 144:ef7eb2e8f9f7 715 uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 716 | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 717 uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 718 | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 719 #endif
<> 144:ef7eb2e8f9f7 720
<> 144:ef7eb2e8f9f7 721 /* Make sure register write lock is disabled */
<> 144:ef7eb2e8f9f7 722 EMU_Unlock();
<> 144:ef7eb2e8f9f7 723
<> 150:02e0a0aed4ec 724 #if defined( _EMU_EM4CTRL_MASK )
<> 150:02e0a0aed4ec 725 if ((EMU->EM4CTRL & _EMU_EM4CTRL_EM4STATE_MASK) == EMU_EM4CTRL_EM4STATE_EM4S)
<> 150:02e0a0aed4ec 726 {
<> 150:02e0a0aed4ec 727 uint32_t dcdcMode = EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK;
<> 150:02e0a0aed4ec 728 if (dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWNOISE
<> 150:02e0a0aed4ec 729 || dcdcMode == EMU_DCDCCTRL_DCDCMODE_LOWPOWER)
<> 150:02e0a0aed4ec 730 {
<> 150:02e0a0aed4ec 731 /* DCDC is not supported in EM4S so we switch DCDC to bypass mode before
<> 150:02e0a0aed4ec 732 * entering EM4S */
<> 150:02e0a0aed4ec 733 EMU_DCDCModeSet(emuDcdcMode_Bypass);
<> 150:02e0a0aed4ec 734 }
<> 150:02e0a0aed4ec 735 }
<> 150:02e0a0aed4ec 736 #endif
<> 150:02e0a0aed4ec 737
<> 150:02e0a0aed4ec 738 #if defined( _EMU_EM4CTRL_MASK ) && defined( ERRATA_FIX_EMU_E208_EN )
<> 150:02e0a0aed4ec 739 if (EMU->EM4CTRL & EMU_EM4CTRL_EM4STATE_EM4H)
<> 150:02e0a0aed4ec 740 {
<> 150:02e0a0aed4ec 741 /* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H.
<> 150:02e0a0aed4ec 742 * Full description of errata fix can be found in the errata document. */
<> 150:02e0a0aed4ec 743 __disable_irq();
<> 150:02e0a0aed4ec 744 *(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0000ADE8UL;
<> 150:02e0a0aed4ec 745 *(volatile uint32_t *)(EMU_BASE + 0x198) |= (0x1UL << 7);
<> 150:02e0a0aed4ec 746 *(volatile uint32_t *)(EMU_BASE + 0x88) |= (0x1UL << 8);
<> 150:02e0a0aed4ec 747 }
<> 150:02e0a0aed4ec 748 #endif
<> 150:02e0a0aed4ec 749
<> 144:ef7eb2e8f9f7 750 #if defined( ERRATA_FIX_EMU_E108_EN )
<> 144:ef7eb2e8f9f7 751 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 752 __disable_irq();
<> 144:ef7eb2e8f9f7 753 *(volatile uint32_t *)0x400C80E4 = 0;
<> 144:ef7eb2e8f9f7 754 #endif
<> 144:ef7eb2e8f9f7 755
<> 150:02e0a0aed4ec 756 #if defined( ERRATA_FIX_DCDC_FETCNT_SET_EN )
<> 144:ef7eb2e8f9f7 757 dcdcFetCntSet(true);
<> 150:02e0a0aed4ec 758 #endif
<> 150:02e0a0aed4ec 759 #if defined( ERRATA_FIX_DCDC_LNHS_BLOCK_EN )
<> 144:ef7eb2e8f9f7 760 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 761 #endif
<> 144:ef7eb2e8f9f7 762
<> 144:ef7eb2e8f9f7 763 for (i = 0; i < 4; i++)
<> 144:ef7eb2e8f9f7 764 {
<> 144:ef7eb2e8f9f7 765 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 766 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 767 EMU->EM4CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 768 }
<> 144:ef7eb2e8f9f7 769 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 770 #else
<> 144:ef7eb2e8f9f7 771 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 772 EMU->CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 773 }
<> 144:ef7eb2e8f9f7 774 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 775 #endif
<> 144:ef7eb2e8f9f7 776 }
<> 144:ef7eb2e8f9f7 777
<> 150:02e0a0aed4ec 778 #if defined( _EMU_EM4CTRL_MASK )
<> 150:02e0a0aed4ec 779 /***************************************************************************//**
<> 150:02e0a0aed4ec 780 * @brief
<> 150:02e0a0aed4ec 781 * Enter energy mode 4 hibernate (EM4H).
<> 150:02e0a0aed4ec 782 *
<> 150:02e0a0aed4ec 783 * @note
<> 150:02e0a0aed4ec 784 * Retention of clocks and GPIO in EM4 can be configured using
<> 150:02e0a0aed4ec 785 * @ref EMU_EM4Init before calling this function.
<> 150:02e0a0aed4ec 786 ******************************************************************************/
<> 150:02e0a0aed4ec 787 void EMU_EnterEM4H(void)
<> 150:02e0a0aed4ec 788 {
<> 150:02e0a0aed4ec 789 BUS_RegBitWrite(&EMU->EM4CTRL, _EMU_EM4CTRL_EM4STATE_SHIFT, 1);
<> 150:02e0a0aed4ec 790 EMU_EnterEM4();
<> 150:02e0a0aed4ec 791 }
<> 150:02e0a0aed4ec 792
<> 150:02e0a0aed4ec 793 /***************************************************************************//**
<> 150:02e0a0aed4ec 794 * @brief
<> 150:02e0a0aed4ec 795 * Enter energy mode 4 shutoff (EM4S).
<> 150:02e0a0aed4ec 796 *
<> 150:02e0a0aed4ec 797 * @note
<> 150:02e0a0aed4ec 798 * Retention of clocks and GPIO in EM4 can be configured using
<> 150:02e0a0aed4ec 799 * @ref EMU_EM4Init before calling this function.
<> 150:02e0a0aed4ec 800 ******************************************************************************/
<> 150:02e0a0aed4ec 801 void EMU_EnterEM4S(void)
<> 150:02e0a0aed4ec 802 {
<> 150:02e0a0aed4ec 803 BUS_RegBitWrite(&EMU->EM4CTRL, _EMU_EM4CTRL_EM4STATE_SHIFT, 0);
<> 150:02e0a0aed4ec 804 EMU_EnterEM4();
<> 150:02e0a0aed4ec 805 }
<> 150:02e0a0aed4ec 806 #endif
<> 144:ef7eb2e8f9f7 807
<> 144:ef7eb2e8f9f7 808 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 809 * @brief
<> 144:ef7eb2e8f9f7 810 * Power down memory block.
<> 144:ef7eb2e8f9f7 811 *
<> 144:ef7eb2e8f9f7 812 * @param[in] blocks
<> 144:ef7eb2e8f9f7 813 * Specifies a logical OR of bits indicating memory blocks to power down.
<> 144:ef7eb2e8f9f7 814 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
<> 144:ef7eb2e8f9f7 815 * be disabled. Please refer to the reference manual for available
<> 144:ef7eb2e8f9f7 816 * memory blocks for a device.
<> 144:ef7eb2e8f9f7 817 *
<> 144:ef7eb2e8f9f7 818 * @note
<> 161:2cc1468da177 819 * Only a POR reset can power up the specified memory block(s) after powerdown.
<> 161:2cc1468da177 820 *
<> 161:2cc1468da177 821 * @deprecated
<> 161:2cc1468da177 822 * This function is deprecated, use @ref EMU_RamPowerDown() instead which
<> 161:2cc1468da177 823 * maps a user provided memory range into RAM blocks to power down.
<> 144:ef7eb2e8f9f7 824 ******************************************************************************/
<> 144:ef7eb2e8f9f7 825 void EMU_MemPwrDown(uint32_t blocks)
<> 144:ef7eb2e8f9f7 826 {
<> 161:2cc1468da177 827 #if defined( _EMU_MEMCTRL_MASK )
<> 161:2cc1468da177 828 EMU->MEMCTRL = blocks & _EMU_MEMCTRL_MASK;
<> 161:2cc1468da177 829 #elif defined( _EMU_RAM0CTRL_MASK )
<> 161:2cc1468da177 830 EMU->RAM0CTRL = blocks & _EMU_RAM0CTRL_MASK;
<> 144:ef7eb2e8f9f7 831 #else
<> 144:ef7eb2e8f9f7 832 (void)blocks;
<> 144:ef7eb2e8f9f7 833 #endif
<> 144:ef7eb2e8f9f7 834 }
<> 144:ef7eb2e8f9f7 835
<> 161:2cc1468da177 836 /***************************************************************************//**
<> 161:2cc1468da177 837 * @brief
<> 161:2cc1468da177 838 * Power down RAM memory blocks.
<> 161:2cc1468da177 839 *
<> 161:2cc1468da177 840 * @details
<> 161:2cc1468da177 841 * This function will power down all the RAM blocks that are within a given
<> 161:2cc1468da177 842 * range. The RAM block layout is different between device families, so this
<> 161:2cc1468da177 843 * function can be used in a generic way to power down a RAM memory region
<> 161:2cc1468da177 844 * which is known to be unused.
<> 161:2cc1468da177 845 *
<> 161:2cc1468da177 846 * This function will only power down blocks which are completely enclosed
<> 161:2cc1468da177 847 * by the memory range given by [start, end).
<> 161:2cc1468da177 848 *
<> 161:2cc1468da177 849 * Here is an example of how to power down all RAM blocks except the first
<> 161:2cc1468da177 850 * one. The first RAM block is special in that it cannot be powered down
<> 161:2cc1468da177 851 * by the hardware. The size of this first RAM block is device specific
<> 161:2cc1468da177 852 * see the reference manual to find the RAM block sizes.
<> 161:2cc1468da177 853 *
<> 161:2cc1468da177 854 * @code
<> 161:2cc1468da177 855 * EMU_RamPowerDown(SRAM_BASE, SRAM_BASE + SRAM_SIZE);
<> 161:2cc1468da177 856 * @endcode
<> 161:2cc1468da177 857 *
<> 161:2cc1468da177 858 * @note
<> 161:2cc1468da177 859 * Only a POR reset can power up the specified memory block(s) after powerdown.
<> 161:2cc1468da177 860 *
<> 161:2cc1468da177 861 * @param[in] start
<> 161:2cc1468da177 862 * The start address of the RAM region to power down. This address is
<> 161:2cc1468da177 863 * inclusive.
<> 161:2cc1468da177 864 *
<> 161:2cc1468da177 865 * @param[in] end
<> 161:2cc1468da177 866 * The end address of the RAM region to power down. This address is
<> 161:2cc1468da177 867 * exclusive. If this parameter is 0, then all RAM blocks contained in the
<> 161:2cc1468da177 868 * region from start to the upper RAM address will be powered down.
<> 161:2cc1468da177 869 ******************************************************************************/
<> 161:2cc1468da177 870 void EMU_RamPowerDown(uint32_t start, uint32_t end)
<> 161:2cc1468da177 871 {
<> 161:2cc1468da177 872 uint32_t mask = 0;
<> 161:2cc1468da177 873
<> 161:2cc1468da177 874 if (end == 0)
<> 161:2cc1468da177 875 {
<> 161:2cc1468da177 876 end = SRAM_BASE + SRAM_SIZE;
<> 161:2cc1468da177 877 }
<> 161:2cc1468da177 878
<> 161:2cc1468da177 879 // Check to see if something in RAM0 can be powered down
<> 161:2cc1468da177 880 if (end > RAM0_END)
<> 161:2cc1468da177 881 {
<> 161:2cc1468da177 882 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_84) // EFM32xG12 and EFR32xG12
<> 161:2cc1468da177 883 // Block 0 is 16 kB and cannot be powered off
<> 161:2cc1468da177 884 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 0; // Block 1, 16 kB
<> 161:2cc1468da177 885 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20008000) << 1; // Block 2, 16 kB
<> 161:2cc1468da177 886 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x2000C000) << 2; // Block 3, 16 kB
<> 161:2cc1468da177 887 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20010000) << 3; // Block 4, 64 kB
<> 161:2cc1468da177 888 #elif defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) // EFM32xG1 and EFR32xG1
<> 161:2cc1468da177 889 // Block 0 is 4 kB and cannot be powered off
<> 161:2cc1468da177 890 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20001000) << 0; // Block 1, 4 kB
<> 161:2cc1468da177 891 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20002000) << 1; // Block 2, 8 kB
<> 161:2cc1468da177 892 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20004000) << 2; // Block 3, 8 kB
<> 161:2cc1468da177 893 mask |= ADDRESS_NOT_IN_BLOCK(start, 0x20006000) << 3; // Block 4, 7 kB
<> 161:2cc1468da177 894 #elif defined(RAM0_BLOCKS)
<> 161:2cc1468da177 895 // These platforms have equally sized RAM blocks
<> 161:2cc1468da177 896 for (int i = 1; i < RAM0_BLOCKS; i++)
<> 161:2cc1468da177 897 {
<> 161:2cc1468da177 898 mask |= ADDRESS_NOT_IN_BLOCK(start, RAM_MEM_BASE + (i * RAM0_BLOCK_SIZE)) << (i - 1);
<> 161:2cc1468da177 899 }
<> 161:2cc1468da177 900 #endif
<> 161:2cc1468da177 901 }
<> 161:2cc1468da177 902
<> 161:2cc1468da177 903 // Power down the selected blocks
<> 161:2cc1468da177 904 #if defined( _EMU_MEMCTRL_MASK )
<> 161:2cc1468da177 905 EMU->MEMCTRL = EMU->MEMCTRL | mask;
<> 161:2cc1468da177 906 #elif defined( _EMU_RAM0CTRL_MASK )
<> 161:2cc1468da177 907 EMU->RAM0CTRL = EMU->RAM0CTRL | mask;
<> 161:2cc1468da177 908 #else
<> 161:2cc1468da177 909 // These devices are unable to power down RAM blocks
<> 161:2cc1468da177 910 (void) mask;
<> 161:2cc1468da177 911 (void) start;
<> 161:2cc1468da177 912 #endif
<> 161:2cc1468da177 913
<> 161:2cc1468da177 914 #if defined(RAM1_MEM_END)
<> 161:2cc1468da177 915 mask = 0;
<> 161:2cc1468da177 916 if (end > RAM1_MEM_END)
<> 161:2cc1468da177 917 {
<> 161:2cc1468da177 918 for (int i = 0; i < RAM1_BLOCKS; i++)
<> 161:2cc1468da177 919 {
<> 161:2cc1468da177 920 mask |= ADDRESS_NOT_IN_BLOCK(start, RAM1_MEM_BASE + (i * RAM1_BLOCK_SIZE)) << i;
<> 161:2cc1468da177 921 }
<> 161:2cc1468da177 922 }
<> 161:2cc1468da177 923 EMU->RAM1CTRL |= mask;
<> 161:2cc1468da177 924 #endif
<> 161:2cc1468da177 925 }
<> 161:2cc1468da177 926
<> 161:2cc1468da177 927 #if defined(_EMU_EM23PERNORETAINCTRL_MASK)
<> 161:2cc1468da177 928 /***************************************************************************//**
<> 161:2cc1468da177 929 * @brief
<> 161:2cc1468da177 930 * Set EM2 3 peripheral retention control.
<> 161:2cc1468da177 931 *
<> 161:2cc1468da177 932 * @param[in] periMask
<> 161:2cc1468da177 933 * Peripheral select mask. Use | operator to select multiple peripheral, for example
<> 161:2cc1468da177 934 * @ref emuPeripheralRetention_LEUART0 | @ref emuPeripheralRetention_VDAC0.
<> 161:2cc1468da177 935 * @param[in] enable
<> 161:2cc1468da177 936 * Peripheral retention enable (true) or disable (false).
<> 161:2cc1468da177 937 *
<> 161:2cc1468da177 938 *
<> 161:2cc1468da177 939 * @note
<> 161:2cc1468da177 940 * Only peripheral retention disable is currently supported. Peripherals are
<> 161:2cc1468da177 941 * enabled by default, and can only be disabled.
<> 161:2cc1468da177 942 ******************************************************************************/
<> 161:2cc1468da177 943 void EMU_PeripheralRetention(EMU_PeripheralRetention_TypeDef periMask, bool enable)
<> 161:2cc1468da177 944 {
<> 161:2cc1468da177 945 EFM_ASSERT(!enable);
<> 161:2cc1468da177 946 EMU->EM23PERNORETAINCTRL = periMask & emuPeripheralRetention_ALL;
<> 161:2cc1468da177 947 }
<> 161:2cc1468da177 948 #endif
<> 161:2cc1468da177 949
<> 144:ef7eb2e8f9f7 950
<> 144:ef7eb2e8f9f7 951 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 952 * @brief
<> 144:ef7eb2e8f9f7 953 * Update EMU module with CMU oscillator selection/enable status.
<> 144:ef7eb2e8f9f7 954 *
<> 161:2cc1468da177 955 * @deprecated
<> 161:2cc1468da177 956 * Oscillator status is saved in @ref EMU_EnterEM2() and @ref EMU_EnterEM3().
<> 144:ef7eb2e8f9f7 957 ******************************************************************************/
<> 144:ef7eb2e8f9f7 958 void EMU_UpdateOscConfig(void)
<> 144:ef7eb2e8f9f7 959 {
<> 161:2cc1468da177 960 emState(emState_Save);
<> 161:2cc1468da177 961 }
<> 161:2cc1468da177 962
<> 161:2cc1468da177 963
<> 161:2cc1468da177 964 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 965 /***************************************************************************//**
<> 161:2cc1468da177 966 * @brief
<> 161:2cc1468da177 967 * Voltage scale in EM0 and 1 by clock frequency.
<> 161:2cc1468da177 968 *
<> 161:2cc1468da177 969 * @param[in] clockFrequency
<> 161:2cc1468da177 970 * Use CMSIS HF clock if 0, or override to custom clock. Providing a
<> 161:2cc1468da177 971 * custom clock frequency is required if using a non-standard HFXO
<> 161:2cc1468da177 972 * frequency.
<> 161:2cc1468da177 973 * @param[in] wait
<> 161:2cc1468da177 974 * Wait for scaling to complate.
<> 161:2cc1468da177 975 *
<> 161:2cc1468da177 976 * @note
<> 161:2cc1468da177 977 * This function is primarely needed by the @ref CMU module.
<> 161:2cc1468da177 978 ******************************************************************************/
<> 161:2cc1468da177 979 void EMU_VScaleEM01ByClock(uint32_t clockFrequency, bool wait)
<> 161:2cc1468da177 980 {
<> 161:2cc1468da177 981 uint32_t hfSrcClockFrequency;
<> 161:2cc1468da177 982 uint32_t hfPresc = 1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
<> 161:2cc1468da177 983 >> _CMU_HFPRESC_PRESC_SHIFT);
<> 161:2cc1468da177 984
<> 161:2cc1468da177 985 /* VSCALE frequency is HFSRCCLK */
<> 161:2cc1468da177 986 if (clockFrequency == 0)
<> 161:2cc1468da177 987 {
<> 161:2cc1468da177 988 hfSrcClockFrequency = SystemHFClockGet() * hfPresc;
<> 161:2cc1468da177 989 }
<> 161:2cc1468da177 990 else
<> 161:2cc1468da177 991 {
<> 161:2cc1468da177 992 hfSrcClockFrequency = clockFrequency;
<> 161:2cc1468da177 993 }
<> 161:2cc1468da177 994
<> 161:2cc1468da177 995 /* Apply EM0 and 1 voltage scaling command. */
<> 161:2cc1468da177 996 if (vScaleEM01Config.vScaleEM01LowPowerVoltageEnable
<> 161:2cc1468da177 997 && (hfSrcClockFrequency < CMU_VSCALEEM01_LOWPOWER_VOLTAGE_CLOCK_MAX))
<> 161:2cc1468da177 998 {
<> 161:2cc1468da177 999 EMU->CMD = vScaleEM01Cmd(emuVScaleEM01_LowPower);
<> 161:2cc1468da177 1000 }
<> 161:2cc1468da177 1001 else
<> 161:2cc1468da177 1002 {
<> 161:2cc1468da177 1003 EMU->CMD = vScaleEM01Cmd(emuVScaleEM01_HighPerformance);
<> 161:2cc1468da177 1004 }
<> 161:2cc1468da177 1005
<> 161:2cc1468da177 1006 if (wait)
<> 161:2cc1468da177 1007 {
<> 161:2cc1468da177 1008 EMU_VScaleWait();
<> 161:2cc1468da177 1009 }
<> 161:2cc1468da177 1010 }
<> 144:ef7eb2e8f9f7 1011 #endif
<> 161:2cc1468da177 1012
<> 161:2cc1468da177 1013
<> 161:2cc1468da177 1014 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 1015 /***************************************************************************//**
<> 161:2cc1468da177 1016 * @brief
<> 161:2cc1468da177 1017 * Force voltage scaling in EM0 and 1 to a specific voltage level.
<> 161:2cc1468da177 1018 *
<> 161:2cc1468da177 1019 * @param[in] voltage
<> 161:2cc1468da177 1020 * Target VSCALE voltage level.
<> 161:2cc1468da177 1021 * @param[in] wait
<> 161:2cc1468da177 1022 * Wait for scaling to complate.
<> 161:2cc1468da177 1023 *
<> 161:2cc1468da177 1024 * @note
<> 161:2cc1468da177 1025 * This function is useful for upscaling before programming Flash from @ref MSC,
<> 161:2cc1468da177 1026 * and downscaling after programming is done. Flash programming is only supported
<> 161:2cc1468da177 1027 * at @ref emuVScaleEM01_HighPerformance.
<> 161:2cc1468da177 1028 *
<> 161:2cc1468da177 1029 * @note
<> 161:2cc1468da177 1030 * This function ignores @ref vScaleEM01LowPowerVoltageEnable set from @ref
<> 161:2cc1468da177 1031 * EMU_EM01Init().
<> 161:2cc1468da177 1032 ******************************************************************************/
<> 161:2cc1468da177 1033 void EMU_VScaleEM01(EMU_VScaleEM01_TypeDef voltage, bool wait)
<> 161:2cc1468da177 1034 {
<> 161:2cc1468da177 1035 uint32_t hfSrcClockFrequency;
<> 161:2cc1468da177 1036 uint32_t hfPresc = 1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
<> 161:2cc1468da177 1037 >> _CMU_HFPRESC_PRESC_SHIFT);
<> 161:2cc1468da177 1038 hfSrcClockFrequency = SystemHFClockGet() * hfPresc;
<> 161:2cc1468da177 1039
<> 161:2cc1468da177 1040 if (voltage == emuVScaleEM01_LowPower)
<> 161:2cc1468da177 1041 {
<> 161:2cc1468da177 1042 EFM_ASSERT(hfSrcClockFrequency <= CMU_VSCALEEM01_LOWPOWER_VOLTAGE_CLOCK_MAX);
<> 161:2cc1468da177 1043 }
<> 161:2cc1468da177 1044
<> 161:2cc1468da177 1045 EMU->CMD = vScaleEM01Cmd(voltage);
<> 161:2cc1468da177 1046 if (wait)
<> 161:2cc1468da177 1047 {
<> 161:2cc1468da177 1048 EMU_VScaleWait();
<> 161:2cc1468da177 1049 }
<> 144:ef7eb2e8f9f7 1050 }
<> 161:2cc1468da177 1051 #endif
<> 161:2cc1468da177 1052
<> 161:2cc1468da177 1053
<> 161:2cc1468da177 1054 #if defined( _EMU_CMD_EM01VSCALE0_MASK )
<> 161:2cc1468da177 1055 /***************************************************************************//**
<> 161:2cc1468da177 1056 * @brief
<> 161:2cc1468da177 1057 * Update EMU module with Energy Mode 0 and 1 configuration
<> 161:2cc1468da177 1058 *
<> 161:2cc1468da177 1059 * @param[in] em01Init
<> 161:2cc1468da177 1060 * Energy Mode 0 and 1 configuration structure
<> 161:2cc1468da177 1061 ******************************************************************************/
<> 161:2cc1468da177 1062 void EMU_EM01Init(const EMU_EM01Init_TypeDef *em01Init)
<> 161:2cc1468da177 1063 {
<> 161:2cc1468da177 1064 vScaleEM01Config.vScaleEM01LowPowerVoltageEnable =
<> 161:2cc1468da177 1065 em01Init->vScaleEM01LowPowerVoltageEnable;
<> 161:2cc1468da177 1066 EMU_VScaleEM01ByClock(0, true);
<> 161:2cc1468da177 1067 }
<> 161:2cc1468da177 1068 #endif
<> 144:ef7eb2e8f9f7 1069
<> 144:ef7eb2e8f9f7 1070
<> 144:ef7eb2e8f9f7 1071 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1072 * @brief
<> 144:ef7eb2e8f9f7 1073 * Update EMU module with Energy Mode 2 and 3 configuration
<> 144:ef7eb2e8f9f7 1074 *
<> 144:ef7eb2e8f9f7 1075 * @param[in] em23Init
<> 144:ef7eb2e8f9f7 1076 * Energy Mode 2 and 3 configuration structure
<> 144:ef7eb2e8f9f7 1077 ******************************************************************************/
<> 161:2cc1468da177 1078 void EMU_EM23Init(const EMU_EM23Init_TypeDef *em23Init)
<> 144:ef7eb2e8f9f7 1079 {
<> 144:ef7eb2e8f9f7 1080 #if defined( _EMU_CTRL_EMVREG_MASK )
<> 144:ef7eb2e8f9f7 1081 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)
<> 144:ef7eb2e8f9f7 1082 : (EMU->CTRL & ~EMU_CTRL_EMVREG);
<> 144:ef7eb2e8f9f7 1083 #elif defined( _EMU_CTRL_EM23VREG_MASK )
<> 144:ef7eb2e8f9f7 1084 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)
<> 144:ef7eb2e8f9f7 1085 : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
<> 144:ef7eb2e8f9f7 1086 #else
<> 144:ef7eb2e8f9f7 1087 (void)em23Init;
<> 144:ef7eb2e8f9f7 1088 #endif
<> 161:2cc1468da177 1089
<> 161:2cc1468da177 1090 #if defined( _EMU_CTRL_EM23VSCALE_MASK )
<> 161:2cc1468da177 1091 EMU->CTRL = (EMU->CTRL & ~_EMU_CTRL_EM23VSCALE_MASK)
<> 161:2cc1468da177 1092 | (em23Init->vScaleEM23Voltage << _EMU_CTRL_EM23VSCALE_SHIFT);
<> 161:2cc1468da177 1093 #endif
<> 144:ef7eb2e8f9f7 1094 }
<> 144:ef7eb2e8f9f7 1095
<> 144:ef7eb2e8f9f7 1096
<> 144:ef7eb2e8f9f7 1097 #if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 1098 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1099 * @brief
<> 144:ef7eb2e8f9f7 1100 * Update EMU module with Energy Mode 4 configuration
<> 144:ef7eb2e8f9f7 1101 *
<> 144:ef7eb2e8f9f7 1102 * @param[in] em4Init
<> 144:ef7eb2e8f9f7 1103 * Energy Mode 4 configuration structure
<> 144:ef7eb2e8f9f7 1104 ******************************************************************************/
<> 161:2cc1468da177 1105 void EMU_EM4Init(const EMU_EM4Init_TypeDef *em4Init)
<> 144:ef7eb2e8f9f7 1106 {
<> 144:ef7eb2e8f9f7 1107 #if defined( _EMU_EM4CONF_MASK )
<> 144:ef7eb2e8f9f7 1108 /* Init for platforms with EMU->EM4CONF register */
<> 144:ef7eb2e8f9f7 1109 uint32_t em4conf = EMU->EM4CONF;
<> 144:ef7eb2e8f9f7 1110
<> 144:ef7eb2e8f9f7 1111 /* Clear fields that will be reconfigured */
<> 144:ef7eb2e8f9f7 1112 em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK
<> 144:ef7eb2e8f9f7 1113 | _EMU_EM4CONF_OSC_MASK
<> 144:ef7eb2e8f9f7 1114 | _EMU_EM4CONF_BURTCWU_MASK
<> 144:ef7eb2e8f9f7 1115 | _EMU_EM4CONF_VREGEN_MASK);
<> 144:ef7eb2e8f9f7 1116
<> 144:ef7eb2e8f9f7 1117 /* Configure new settings */
<> 144:ef7eb2e8f9f7 1118 em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)
<> 144:ef7eb2e8f9f7 1119 | (em4Init->osc)
<> 144:ef7eb2e8f9f7 1120 | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)
<> 144:ef7eb2e8f9f7 1121 | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);
<> 144:ef7eb2e8f9f7 1122
<> 144:ef7eb2e8f9f7 1123 /* Apply configuration. Note that lock can be set after this stage. */
<> 144:ef7eb2e8f9f7 1124 EMU->EM4CONF = em4conf;
<> 144:ef7eb2e8f9f7 1125
<> 144:ef7eb2e8f9f7 1126 #elif defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 1127 /* Init for platforms with EMU->EM4CTRL register */
<> 144:ef7eb2e8f9f7 1128
<> 144:ef7eb2e8f9f7 1129 uint32_t em4ctrl = EMU->EM4CTRL;
<> 144:ef7eb2e8f9f7 1130
<> 144:ef7eb2e8f9f7 1131 em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK
<> 144:ef7eb2e8f9f7 1132 | _EMU_EM4CTRL_RETAINLFRCO_MASK
<> 144:ef7eb2e8f9f7 1133 | _EMU_EM4CTRL_RETAINULFRCO_MASK
<> 144:ef7eb2e8f9f7 1134 | _EMU_EM4CTRL_EM4STATE_MASK
<> 144:ef7eb2e8f9f7 1135 | _EMU_EM4CTRL_EM4IORETMODE_MASK);
<> 144:ef7eb2e8f9f7 1136
<> 150:02e0a0aed4ec 1137 em4ctrl |= (em4Init->retainLfxo ? EMU_EM4CTRL_RETAINLFXO : 0)
<> 150:02e0a0aed4ec 1138 | (em4Init->retainLfrco ? EMU_EM4CTRL_RETAINLFRCO : 0)
<> 150:02e0a0aed4ec 1139 | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)
<> 150:02e0a0aed4ec 1140 | (em4Init->em4State ? EMU_EM4CTRL_EM4STATE_EM4H : 0)
<> 150:02e0a0aed4ec 1141 | (em4Init->pinRetentionMode);
<> 144:ef7eb2e8f9f7 1142
<> 144:ef7eb2e8f9f7 1143 EMU->EM4CTRL = em4ctrl;
<> 144:ef7eb2e8f9f7 1144 #endif
<> 161:2cc1468da177 1145
<> 161:2cc1468da177 1146 #if defined( _EMU_CTRL_EM4HVSCALE_MASK )
<> 161:2cc1468da177 1147 EMU->CTRL = (EMU->CTRL & ~_EMU_CTRL_EM4HVSCALE_MASK)
<> 161:2cc1468da177 1148 | (em4Init->vScaleEM4HVoltage << _EMU_CTRL_EM4HVSCALE_SHIFT);
<> 161:2cc1468da177 1149 #endif
<> 144:ef7eb2e8f9f7 1150 }
<> 144:ef7eb2e8f9f7 1151 #endif
<> 144:ef7eb2e8f9f7 1152
<> 144:ef7eb2e8f9f7 1153
<> 144:ef7eb2e8f9f7 1154 #if defined( BU_PRESENT )
<> 144:ef7eb2e8f9f7 1155 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1156 * @brief
<> 144:ef7eb2e8f9f7 1157 * Configure Backup Power Domain settings
<> 144:ef7eb2e8f9f7 1158 *
<> 144:ef7eb2e8f9f7 1159 * @param[in] bupdInit
<> 144:ef7eb2e8f9f7 1160 * Backup power domain initialization structure
<> 144:ef7eb2e8f9f7 1161 ******************************************************************************/
<> 161:2cc1468da177 1162 void EMU_BUPDInit(const EMU_BUPDInit_TypeDef *bupdInit)
<> 144:ef7eb2e8f9f7 1163 {
<> 144:ef7eb2e8f9f7 1164 uint32_t reg;
<> 144:ef7eb2e8f9f7 1165
<> 144:ef7eb2e8f9f7 1166 /* Set power connection configuration */
<> 144:ef7eb2e8f9f7 1167 reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK
<> 144:ef7eb2e8f9f7 1168 | _EMU_PWRCONF_VOUTSTRONG_MASK
<> 144:ef7eb2e8f9f7 1169 | _EMU_PWRCONF_VOUTMED_MASK
<> 144:ef7eb2e8f9f7 1170 | _EMU_PWRCONF_VOUTWEAK_MASK);
<> 144:ef7eb2e8f9f7 1171
<> 144:ef7eb2e8f9f7 1172 reg |= bupdInit->resistor
<> 144:ef7eb2e8f9f7 1173 | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)
<> 144:ef7eb2e8f9f7 1174 | (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)
<> 144:ef7eb2e8f9f7 1175 | (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT);
<> 144:ef7eb2e8f9f7 1176
<> 144:ef7eb2e8f9f7 1177 EMU->PWRCONF = reg;
<> 144:ef7eb2e8f9f7 1178
<> 144:ef7eb2e8f9f7 1179 /* Set backup domain inactive mode configuration */
<> 144:ef7eb2e8f9f7 1180 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 1181 reg |= (bupdInit->inactivePower);
<> 144:ef7eb2e8f9f7 1182 EMU->BUINACT = reg;
<> 144:ef7eb2e8f9f7 1183
<> 144:ef7eb2e8f9f7 1184 /* Set backup domain active mode configuration */
<> 144:ef7eb2e8f9f7 1185 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 1186 reg |= (bupdInit->activePower);
<> 144:ef7eb2e8f9f7 1187 EMU->BUACT = reg;
<> 144:ef7eb2e8f9f7 1188
<> 144:ef7eb2e8f9f7 1189 /* Set power control configuration */
<> 144:ef7eb2e8f9f7 1190 reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK
<> 144:ef7eb2e8f9f7 1191 | _EMU_BUCTRL_BODCAL_MASK
<> 144:ef7eb2e8f9f7 1192 | _EMU_BUCTRL_STATEN_MASK
<> 144:ef7eb2e8f9f7 1193 | _EMU_BUCTRL_EN_MASK);
<> 144:ef7eb2e8f9f7 1194
<> 144:ef7eb2e8f9f7 1195 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
<> 144:ef7eb2e8f9f7 1196 release reset */
<> 144:ef7eb2e8f9f7 1197 reg |= bupdInit->probe
<> 144:ef7eb2e8f9f7 1198 | (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)
<> 144:ef7eb2e8f9f7 1199 | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)
<> 144:ef7eb2e8f9f7 1200 | (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT);
<> 144:ef7eb2e8f9f7 1201
<> 144:ef7eb2e8f9f7 1202 /* Enable configuration */
<> 144:ef7eb2e8f9f7 1203 EMU->BUCTRL = reg;
<> 144:ef7eb2e8f9f7 1204
<> 144:ef7eb2e8f9f7 1205 /* If enable is true, enable BU_VIN input power pin, if not disable it */
<> 144:ef7eb2e8f9f7 1206 EMU_BUPinEnable(bupdInit->enable);
<> 144:ef7eb2e8f9f7 1207
<> 144:ef7eb2e8f9f7 1208 /* If enable is true, release BU reset, if not keep reset asserted */
<> 144:ef7eb2e8f9f7 1209 BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
<> 144:ef7eb2e8f9f7 1210 }
<> 144:ef7eb2e8f9f7 1211
<> 144:ef7eb2e8f9f7 1212
<> 144:ef7eb2e8f9f7 1213 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1214 * @brief
<> 144:ef7eb2e8f9f7 1215 * Configure Backup Power Domain BOD Threshold value
<> 144:ef7eb2e8f9f7 1216 * @note
<> 144:ef7eb2e8f9f7 1217 * These values are precalibrated
<> 144:ef7eb2e8f9f7 1218 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 1219 * @param[in] value
<> 144:ef7eb2e8f9f7 1220 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1221 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 1222 {
<> 144:ef7eb2e8f9f7 1223 EFM_ASSERT(value<8);
<> 144:ef7eb2e8f9f7 1224 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
<> 144:ef7eb2e8f9f7 1225
<> 144:ef7eb2e8f9f7 1226 switch(mode)
<> 144:ef7eb2e8f9f7 1227 {
<> 144:ef7eb2e8f9f7 1228 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 1229 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)
<> 144:ef7eb2e8f9f7 1230 | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 1231 break;
<> 144:ef7eb2e8f9f7 1232 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 1233 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)
<> 144:ef7eb2e8f9f7 1234 | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 1235 break;
<> 144:ef7eb2e8f9f7 1236 }
<> 144:ef7eb2e8f9f7 1237 }
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239
<> 144:ef7eb2e8f9f7 1240 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1241 * @brief
<> 144:ef7eb2e8f9f7 1242 * Configure Backup Power Domain BOD Threshold Range
<> 144:ef7eb2e8f9f7 1243 * @note
<> 144:ef7eb2e8f9f7 1244 * These values are precalibrated
<> 144:ef7eb2e8f9f7 1245 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 1246 * @param[in] value
<> 144:ef7eb2e8f9f7 1247 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1248 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 1249 {
<> 144:ef7eb2e8f9f7 1250 EFM_ASSERT(value < 4);
<> 144:ef7eb2e8f9f7 1251 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
<> 144:ef7eb2e8f9f7 1252
<> 144:ef7eb2e8f9f7 1253 switch(mode)
<> 144:ef7eb2e8f9f7 1254 {
<> 144:ef7eb2e8f9f7 1255 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 1256 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)
<> 144:ef7eb2e8f9f7 1257 | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 1258 break;
<> 144:ef7eb2e8f9f7 1259 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 1260 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)
<> 144:ef7eb2e8f9f7 1261 | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 1262 break;
<> 144:ef7eb2e8f9f7 1263 }
<> 144:ef7eb2e8f9f7 1264 }
<> 144:ef7eb2e8f9f7 1265 #endif
<> 144:ef7eb2e8f9f7 1266
<> 144:ef7eb2e8f9f7 1267
<> 161:2cc1468da177 1268 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 1269 #if defined( _EMU_DCDCCTRL_MASK )
<> 150:02e0a0aed4ec 1270 /* Translate fields with different names across platform generations to common names. */
<> 150:02e0a0aed4ec 1271 #if defined( _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK )
<> 150:02e0a0aed4ec 1272 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK
<> 150:02e0a0aed4ec 1273 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT
<> 150:02e0a0aed4ec 1274 #elif defined( _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_MASK )
<> 150:02e0a0aed4ec 1275 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_MASK
<> 150:02e0a0aed4ec 1276 #define _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT _EMU_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT
<> 150:02e0a0aed4ec 1277 #endif
<> 150:02e0a0aed4ec 1278 #if defined( _EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK )
<> 150:02e0a0aed4ec 1279 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK _EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK
<> 150:02e0a0aed4ec 1280 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT
<> 150:02e0a0aed4ec 1281 #elif defined( _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK )
<> 150:02e0a0aed4ec 1282 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK
<> 150:02e0a0aed4ec 1283 #define _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT _EMU_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT
<> 150:02e0a0aed4ec 1284 #endif
<> 150:02e0a0aed4ec 1285
<> 161:2cc1468da177 1286 /* Internal DCDC trim modes. */
<> 161:2cc1468da177 1287 typedef enum
<> 161:2cc1468da177 1288 {
<> 161:2cc1468da177 1289 dcdcTrimMode_EM234H_LP = 0,
<> 161:2cc1468da177 1290 #if defined( _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK )
<> 161:2cc1468da177 1291 dcdcTrimMode_EM01_LP,
<> 161:2cc1468da177 1292 #endif
<> 161:2cc1468da177 1293 dcdcTrimMode_LN,
<> 161:2cc1468da177 1294 } dcdcTrimMode_TypeDef;
<> 144:ef7eb2e8f9f7 1295
<> 144:ef7eb2e8f9f7 1296 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1297 * @brief
<> 144:ef7eb2e8f9f7 1298 * Load DCDC calibration constants from DI page. Const means calibration
<> 144:ef7eb2e8f9f7 1299 * data that does not change depending on other configuration parameters.
<> 144:ef7eb2e8f9f7 1300 *
<> 144:ef7eb2e8f9f7 1301 * @return
<> 144:ef7eb2e8f9f7 1302 * False if calibration registers are locked
<> 144:ef7eb2e8f9f7 1303 ******************************************************************************/
<> 161:2cc1468da177 1304 static bool dcdcConstCalibrationLoad(void)
<> 144:ef7eb2e8f9f7 1305 {
<> 161:2cc1468da177 1306 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 144:ef7eb2e8f9f7 1307 uint32_t val;
<> 144:ef7eb2e8f9f7 1308 volatile uint32_t *reg;
<> 144:ef7eb2e8f9f7 1309
<> 144:ef7eb2e8f9f7 1310 /* DI calib data in flash */
<> 144:ef7eb2e8f9f7 1311 volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL = (volatile uint32_t *)(0x0FE08038);
<> 144:ef7eb2e8f9f7 1312 volatile uint32_t* const diCal_EMU_DCDCLNVCTRL = (volatile uint32_t *)(0x0FE08040);
<> 144:ef7eb2e8f9f7 1313 volatile uint32_t* const diCal_EMU_DCDCLPCTRL = (volatile uint32_t *)(0x0FE08048);
<> 144:ef7eb2e8f9f7 1314 volatile uint32_t* const diCal_EMU_DCDCLPVCTRL = (volatile uint32_t *)(0x0FE08050);
<> 144:ef7eb2e8f9f7 1315 volatile uint32_t* const diCal_EMU_DCDCTRIM0 = (volatile uint32_t *)(0x0FE08058);
<> 144:ef7eb2e8f9f7 1316 volatile uint32_t* const diCal_EMU_DCDCTRIM1 = (volatile uint32_t *)(0x0FE08060);
<> 144:ef7eb2e8f9f7 1317
<> 144:ef7eb2e8f9f7 1318 if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)
<> 144:ef7eb2e8f9f7 1319 {
<> 144:ef7eb2e8f9f7 1320 val = *(diCal_EMU_DCDCLNFREQCTRL + 1);
<> 144:ef7eb2e8f9f7 1321 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;
<> 144:ef7eb2e8f9f7 1322 *reg = val;
<> 144:ef7eb2e8f9f7 1323
<> 144:ef7eb2e8f9f7 1324 val = *(diCal_EMU_DCDCLNVCTRL + 1);
<> 144:ef7eb2e8f9f7 1325 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;
<> 144:ef7eb2e8f9f7 1326 *reg = val;
<> 144:ef7eb2e8f9f7 1327
<> 144:ef7eb2e8f9f7 1328 val = *(diCal_EMU_DCDCLPCTRL + 1);
<> 144:ef7eb2e8f9f7 1329 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;
<> 144:ef7eb2e8f9f7 1330 *reg = val;
<> 144:ef7eb2e8f9f7 1331
<> 144:ef7eb2e8f9f7 1332 val = *(diCal_EMU_DCDCLPVCTRL + 1);
<> 144:ef7eb2e8f9f7 1333 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;
<> 144:ef7eb2e8f9f7 1334 *reg = val;
<> 144:ef7eb2e8f9f7 1335
<> 144:ef7eb2e8f9f7 1336 val = *(diCal_EMU_DCDCTRIM0 + 1);
<> 144:ef7eb2e8f9f7 1337 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;
<> 144:ef7eb2e8f9f7 1338 *reg = val;
<> 144:ef7eb2e8f9f7 1339
<> 144:ef7eb2e8f9f7 1340 val = *(diCal_EMU_DCDCTRIM1 + 1);
<> 144:ef7eb2e8f9f7 1341 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;
<> 144:ef7eb2e8f9f7 1342 *reg = val;
<> 144:ef7eb2e8f9f7 1343
<> 144:ef7eb2e8f9f7 1344 return true;
<> 144:ef7eb2e8f9f7 1345 }
<> 144:ef7eb2e8f9f7 1346 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1347 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1348 return false;
<> 150:02e0a0aed4ec 1349
<> 150:02e0a0aed4ec 1350 #else
<> 150:02e0a0aed4ec 1351 return true;
<> 150:02e0a0aed4ec 1352 #endif
<> 144:ef7eb2e8f9f7 1353 }
<> 144:ef7eb2e8f9f7 1354
<> 144:ef7eb2e8f9f7 1355
<> 144:ef7eb2e8f9f7 1356 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1357 * @brief
<> 150:02e0a0aed4ec 1358 * Set recommended and validated current optimization and timing settings
<> 144:ef7eb2e8f9f7 1359 *
<> 144:ef7eb2e8f9f7 1360 ******************************************************************************/
<> 161:2cc1468da177 1361 static void dcdcValidatedConfigSet(void)
<> 144:ef7eb2e8f9f7 1362 {
<> 150:02e0a0aed4ec 1363 /* Disable LP mode hysterysis in the state machine control */
<> 150:02e0a0aed4ec 1364 #define EMU_DCDCMISCCTRL_LPCMPHYSDIS (0x1UL << 1)
<> 150:02e0a0aed4ec 1365 /* Comparator threshold on the high side */
<> 150:02e0a0aed4ec 1366 #define EMU_DCDCMISCCTRL_LPCMPHYSHI (0x1UL << 2)
<> 144:ef7eb2e8f9f7 1367 #define EMU_DCDCSMCTRL (* (volatile uint32_t *)(EMU_BASE + 0x44))
<> 144:ef7eb2e8f9f7 1368
<> 161:2cc1468da177 1369 uint32_t lnForceCcm;
<> 161:2cc1468da177 1370
<> 161:2cc1468da177 1371 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 144:ef7eb2e8f9f7 1372 uint32_t dcdcTiming;
<> 144:ef7eb2e8f9f7 1373 SYSTEM_ChipRevision_TypeDef rev;
<> 150:02e0a0aed4ec 1374 #endif
<> 150:02e0a0aed4ec 1375
<> 144:ef7eb2e8f9f7 1376 /* Enable duty cycling of the bias */
<> 144:ef7eb2e8f9f7 1377 EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;
<> 144:ef7eb2e8f9f7 1378
<> 150:02e0a0aed4ec 1379 /* Set low-noise RCO for LNFORCECCM configuration
<> 150:02e0a0aed4ec 1380 * LNFORCECCM is default 1 for EFR32
<> 150:02e0a0aed4ec 1381 * LNFORCECCM is default 0 for EFM32
<> 150:02e0a0aed4ec 1382 */
<> 161:2cc1468da177 1383 lnForceCcm = BUS_RegBitRead(&EMU->DCDCMISCCTRL, _EMU_DCDCMISCCTRL_LNFORCECCM_SHIFT);
<> 150:02e0a0aed4ec 1384 if (lnForceCcm)
<> 150:02e0a0aed4ec 1385 {
<> 150:02e0a0aed4ec 1386 /* 7MHz is recommended for LNFORCECCM = 1 */
<> 150:02e0a0aed4ec 1387 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_7MHz);
<> 150:02e0a0aed4ec 1388 }
<> 150:02e0a0aed4ec 1389 else
<> 150:02e0a0aed4ec 1390 {
<> 150:02e0a0aed4ec 1391 /* 3MHz is recommended for LNFORCECCM = 0 */
<> 150:02e0a0aed4ec 1392 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_3MHz);
<> 150:02e0a0aed4ec 1393 }
<> 144:ef7eb2e8f9f7 1394
<> 161:2cc1468da177 1395 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 144:ef7eb2e8f9f7 1396 EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;
<> 150:02e0a0aed4ec 1397 EMU->DCDCMISCCTRL |= EMU_DCDCMISCCTRL_LPCMPHYSDIS
<> 150:02e0a0aed4ec 1398 | EMU_DCDCMISCCTRL_LPCMPHYSHI;
<> 144:ef7eb2e8f9f7 1399
<> 144:ef7eb2e8f9f7 1400 SYSTEM_ChipRevisionGet(&rev);
<> 161:2cc1468da177 1401 if ((rev.major == 1)
<> 161:2cc1468da177 1402 && (rev.minor < 3)
<> 144:ef7eb2e8f9f7 1403 && (errataFixDcdcHsState == errataFixDcdcHsInit))
<> 144:ef7eb2e8f9f7 1404 {
<> 144:ef7eb2e8f9f7 1405 /* LPCMPWAITDIS = 1 */
<> 144:ef7eb2e8f9f7 1406 EMU_DCDCSMCTRL |= 1;
<> 144:ef7eb2e8f9f7 1407
<> 144:ef7eb2e8f9f7 1408 dcdcTiming = EMU->DCDCTIMING;
<> 144:ef7eb2e8f9f7 1409 dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK
<> 144:ef7eb2e8f9f7 1410 |_EMU_DCDCTIMING_LNWAIT_MASK
<> 144:ef7eb2e8f9f7 1411 |_EMU_DCDCTIMING_BYPWAIT_MASK);
<> 144:ef7eb2e8f9f7 1412
<> 144:ef7eb2e8f9f7 1413 dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1414 | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1415 | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));
<> 144:ef7eb2e8f9f7 1416 EMU->DCDCTIMING = dcdcTiming;
<> 144:ef7eb2e8f9f7 1417
<> 144:ef7eb2e8f9f7 1418 errataFixDcdcHsState = errataFixDcdcHsTrimSet;
<> 144:ef7eb2e8f9f7 1419 }
<> 150:02e0a0aed4ec 1420 #endif
<> 144:ef7eb2e8f9f7 1421 }
<> 144:ef7eb2e8f9f7 1422
<> 144:ef7eb2e8f9f7 1423
<> 144:ef7eb2e8f9f7 1424 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1425 * @brief
<> 150:02e0a0aed4ec 1426 * Compute current limiters:
<> 150:02e0a0aed4ec 1427 * LNCLIMILIMSEL: LN current limiter threshold
<> 150:02e0a0aed4ec 1428 * LPCLIMILIMSEL: LP current limiter threshold
<> 150:02e0a0aed4ec 1429 * DCDCZDETCTRL: zero detector limiter threshold
<> 144:ef7eb2e8f9f7 1430 ******************************************************************************/
<> 150:02e0a0aed4ec 1431 static void currentLimitersUpdate(void)
<> 144:ef7eb2e8f9f7 1432 {
<> 150:02e0a0aed4ec 1433 uint32_t lncLimSel;
<> 150:02e0a0aed4ec 1434 uint32_t zdetLimSel;
<> 144:ef7eb2e8f9f7 1435 uint32_t pFetCnt;
<> 150:02e0a0aed4ec 1436 uint16_t maxReverseCurrent_mA;
<> 144:ef7eb2e8f9f7 1437
<> 150:02e0a0aed4ec 1438 /* 80mA as recommended peak in Application Note AN0948.
<> 150:02e0a0aed4ec 1439 The peak current is the average current plus 50% of the current ripple.
<> 150:02e0a0aed4ec 1440 Hence, a 14mA average current is recommended in LP mode. Since LP PFETCNT is also
<> 150:02e0a0aed4ec 1441 a constant, we get lpcLimImSel = 1. The following calculation is provided
<> 150:02e0a0aed4ec 1442 for documentation only. */
<> 150:02e0a0aed4ec 1443 const uint32_t lpcLim = (((14 + 40) + ((14 + 40) / 2))
<> 150:02e0a0aed4ec 1444 / (5 * (DCDC_LP_PFET_CNT + 1)))
<> 150:02e0a0aed4ec 1445 - 1;
<> 150:02e0a0aed4ec 1446 const uint32_t lpcLimSel = lpcLim << _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1447
<> 150:02e0a0aed4ec 1448 /* Get enabled PFETs */
<> 144:ef7eb2e8f9f7 1449 pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)
<> 144:ef7eb2e8f9f7 1450 >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;
<> 144:ef7eb2e8f9f7 1451
<> 150:02e0a0aed4ec 1452 /* Compute LN current limiter threshold from nominal user input current and
<> 150:02e0a0aed4ec 1453 LN PFETCNT as described in the register description for
<> 150:02e0a0aed4ec 1454 EMU_DCDCMISCCTRL_LNCLIMILIMSEL. */
<> 150:02e0a0aed4ec 1455 lncLimSel = (((dcdcMaxCurrent_mA + 40) + ((dcdcMaxCurrent_mA + 40) / 2))
<> 150:02e0a0aed4ec 1456 / (5 * (pFetCnt + 1)))
<> 150:02e0a0aed4ec 1457 - 1;
<> 144:ef7eb2e8f9f7 1458
<> 150:02e0a0aed4ec 1459 /* Saturate the register field value */
<> 150:02e0a0aed4ec 1460 lncLimSel = SL_MIN(lncLimSel,
<> 150:02e0a0aed4ec 1461 _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 150:02e0a0aed4ec 1462 >> _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT);
<> 150:02e0a0aed4ec 1463
<> 150:02e0a0aed4ec 1464 lncLimSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1465
<> 150:02e0a0aed4ec 1466 /* Check for overflow */
<> 150:02e0a0aed4ec 1467 EFM_ASSERT((lncLimSel & ~_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1468 EFM_ASSERT((lpcLimSel & ~_EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1469
<> 144:ef7eb2e8f9f7 1470 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 144:ef7eb2e8f9f7 1471 | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))
<> 150:02e0a0aed4ec 1472 | (lncLimSel | lpcLimSel);
<> 150:02e0a0aed4ec 1473
<> 150:02e0a0aed4ec 1474
<> 150:02e0a0aed4ec 1475 /* Compute reverse current limit threshold for the zero detector from user input
<> 150:02e0a0aed4ec 1476 maximum reverse current and LN PFETCNT as described in the register description
<> 150:02e0a0aed4ec 1477 for EMU_DCDCZDETCTRL_ZDETILIMSEL. */
<> 150:02e0a0aed4ec 1478 if (dcdcReverseCurrentControl >= 0)
<> 150:02e0a0aed4ec 1479 {
<> 150:02e0a0aed4ec 1480 /* If dcdcReverseCurrentControl < 0, then EMU_DCDCZDETCTRL_ZDETILIMSEL is "don't care" */
<> 150:02e0a0aed4ec 1481 maxReverseCurrent_mA = (uint16_t)dcdcReverseCurrentControl;
<> 150:02e0a0aed4ec 1482
<> 150:02e0a0aed4ec 1483 zdetLimSel = ( ((maxReverseCurrent_mA + 40) + ((maxReverseCurrent_mA + 40) / 2))
<> 150:02e0a0aed4ec 1484 / ((2 * (pFetCnt + 1)) + ((pFetCnt + 1) / 2)) );
<> 150:02e0a0aed4ec 1485 /* Saturate the register field value */
<> 150:02e0a0aed4ec 1486 zdetLimSel = SL_MIN(zdetLimSel,
<> 150:02e0a0aed4ec 1487 _EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK
<> 150:02e0a0aed4ec 1488 >> _EMU_DCDCZDETCTRL_ZDETILIMSEL_SHIFT);
<> 150:02e0a0aed4ec 1489
<> 150:02e0a0aed4ec 1490 zdetLimSel <<= _EMU_DCDCZDETCTRL_ZDETILIMSEL_SHIFT;
<> 150:02e0a0aed4ec 1491
<> 150:02e0a0aed4ec 1492 /* Check for overflow */
<> 150:02e0a0aed4ec 1493 EFM_ASSERT((zdetLimSel & ~_EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK) == 0x0);
<> 150:02e0a0aed4ec 1494
<> 150:02e0a0aed4ec 1495 EMU->DCDCZDETCTRL = (EMU->DCDCZDETCTRL & ~_EMU_DCDCZDETCTRL_ZDETILIMSEL_MASK)
<> 150:02e0a0aed4ec 1496 | zdetLimSel;
<> 150:02e0a0aed4ec 1497 }
<> 144:ef7eb2e8f9f7 1498 }
<> 144:ef7eb2e8f9f7 1499
<> 144:ef7eb2e8f9f7 1500
<> 144:ef7eb2e8f9f7 1501 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1502 * @brief
<> 150:02e0a0aed4ec 1503 * Set static variables that hold the user set maximum peak current
<> 150:02e0a0aed4ec 1504 * and reverse current. Update limiters.
<> 144:ef7eb2e8f9f7 1505 *
<> 150:02e0a0aed4ec 1506 * @param[in] maxCurrent_mA
<> 150:02e0a0aed4ec 1507 * Set the maximum peak current that the DCDC can draw from the power source.
<> 150:02e0a0aed4ec 1508 * @param[in] reverseCurrentControl
<> 150:02e0a0aed4ec 1509 * Reverse current control as defined by
<> 150:02e0a0aed4ec 1510 * @ref EMU_DcdcLnReverseCurrentControl_TypeDef. Positive values have unit mA.
<> 144:ef7eb2e8f9f7 1511 ******************************************************************************/
<> 150:02e0a0aed4ec 1512 static void userCurrentLimitsSet(uint32_t maxCurrent_mA,
<> 150:02e0a0aed4ec 1513 EMU_DcdcLnReverseCurrentControl_TypeDef reverseCurrentControl)
<> 144:ef7eb2e8f9f7 1514 {
<> 150:02e0a0aed4ec 1515 dcdcMaxCurrent_mA = maxCurrent_mA;
<> 150:02e0a0aed4ec 1516 dcdcReverseCurrentControl = reverseCurrentControl;
<> 144:ef7eb2e8f9f7 1517 }
<> 144:ef7eb2e8f9f7 1518
<> 144:ef7eb2e8f9f7 1519
<> 144:ef7eb2e8f9f7 1520 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1521 * @brief
<> 150:02e0a0aed4ec 1522 * Set DCDC low noise compensator control register
<> 150:02e0a0aed4ec 1523 *
<> 150:02e0a0aed4ec 1524 * @param[in] comp
<> 150:02e0a0aed4ec 1525 * Low-noise mode compensator trim setpoint
<> 150:02e0a0aed4ec 1526 ******************************************************************************/
<> 150:02e0a0aed4ec 1527 static void compCtrlSet(EMU_DcdcLnCompCtrl_TypeDef comp)
<> 150:02e0a0aed4ec 1528 {
<> 150:02e0a0aed4ec 1529 switch (comp)
<> 150:02e0a0aed4ec 1530 {
<> 150:02e0a0aed4ec 1531 case emuDcdcLnCompCtrl_1u0F:
<> 161:2cc1468da177 1532 EMU->DCDCLNCOMPCTRL = 0x57204077UL;
<> 150:02e0a0aed4ec 1533 break;
<> 150:02e0a0aed4ec 1534
<> 150:02e0a0aed4ec 1535 case emuDcdcLnCompCtrl_4u7F:
<> 161:2cc1468da177 1536 EMU->DCDCLNCOMPCTRL = 0xB7102137UL;
<> 150:02e0a0aed4ec 1537 break;
<> 150:02e0a0aed4ec 1538
<> 150:02e0a0aed4ec 1539 default:
<> 150:02e0a0aed4ec 1540 EFM_ASSERT(false);
<> 150:02e0a0aed4ec 1541 break;
<> 150:02e0a0aed4ec 1542 }
<> 150:02e0a0aed4ec 1543 }
<> 150:02e0a0aed4ec 1544
<> 150:02e0a0aed4ec 1545 /***************************************************************************//**
<> 150:02e0a0aed4ec 1546 * @brief
<> 144:ef7eb2e8f9f7 1547 * Load EMU_DCDCLPCTRL_LPCMPHYSSEL depending on LP bias, LP feedback
<> 144:ef7eb2e8f9f7 1548 * attenuation and DEVINFOREV.
<> 144:ef7eb2e8f9f7 1549 *
<> 161:2cc1468da177 1550 * @param[in] lpAttenuation
<> 144:ef7eb2e8f9f7 1551 * LP feedback attenuation.
<> 144:ef7eb2e8f9f7 1552 * @param[in] lpCmpBias
<> 161:2cc1468da177 1553 * lpCmpBias selection.
<> 161:2cc1468da177 1554 * @param[in] trimMode
<> 161:2cc1468da177 1555 * DCDC trim mode.
<> 144:ef7eb2e8f9f7 1556 ******************************************************************************/
<> 161:2cc1468da177 1557 static bool lpCmpHystCalibrationLoad(bool lpAttenuation,
<> 161:2cc1468da177 1558 uint8_t lpCmpBias,
<> 161:2cc1468da177 1559 dcdcTrimMode_TypeDef trimMode)
<> 144:ef7eb2e8f9f7 1560 {
<> 144:ef7eb2e8f9f7 1561 uint32_t lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1562
<> 144:ef7eb2e8f9f7 1563 /* Get calib data revision */
<> 161:2cc1468da177 1564 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
<> 161:2cc1468da177 1565 uint8_t devinfoRev = SYSTEM_GetDevinfoRev();
<> 144:ef7eb2e8f9f7 1566
<> 144:ef7eb2e8f9f7 1567 /* Load LPATT indexed calibration data */
<> 144:ef7eb2e8f9f7 1568 if (devinfoRev < 4)
<> 161:2cc1468da177 1569 #else
<> 161:2cc1468da177 1570 /* Format change not present of newer families. */
<> 161:2cc1468da177 1571 if (false)
<> 161:2cc1468da177 1572 #endif
<> 144:ef7eb2e8f9f7 1573 {
<> 144:ef7eb2e8f9f7 1574 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;
<> 144:ef7eb2e8f9f7 1575
<> 144:ef7eb2e8f9f7 1576 if (lpAttenuation)
<> 144:ef7eb2e8f9f7 1577 {
<> 144:ef7eb2e8f9f7 1578 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)
<> 144:ef7eb2e8f9f7 1579 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1580 }
<> 144:ef7eb2e8f9f7 1581 else
<> 144:ef7eb2e8f9f7 1582 {
<> 144:ef7eb2e8f9f7 1583 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)
<> 144:ef7eb2e8f9f7 1584 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1585 }
<> 144:ef7eb2e8f9f7 1586 }
<> 144:ef7eb2e8f9f7 1587 else
<> 144:ef7eb2e8f9f7 1588 {
<> 150:02e0a0aed4ec 1589 /* devinfoRev >= 4: load LPCMPBIAS indexed calibration data */
<> 144:ef7eb2e8f9f7 1590 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;
<> 144:ef7eb2e8f9f7 1591 switch (lpCmpBias)
<> 144:ef7eb2e8f9f7 1592 {
<> 150:02e0a0aed4ec 1593 case 0:
<> 144:ef7eb2e8f9f7 1594 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1595 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1596 break;
<> 144:ef7eb2e8f9f7 1597
<> 161:2cc1468da177 1598 case 1:
<> 144:ef7eb2e8f9f7 1599 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1600 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1601 break;
<> 144:ef7eb2e8f9f7 1602
<> 161:2cc1468da177 1603 case 2:
<> 144:ef7eb2e8f9f7 1604 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1605 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1606 break;
<> 144:ef7eb2e8f9f7 1607
<> 161:2cc1468da177 1608 case 3:
<> 144:ef7eb2e8f9f7 1609 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1610 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1611 break;
<> 144:ef7eb2e8f9f7 1612
<> 144:ef7eb2e8f9f7 1613 default:
<> 144:ef7eb2e8f9f7 1614 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1615 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1616 return false;
<> 144:ef7eb2e8f9f7 1617 }
<> 144:ef7eb2e8f9f7 1618 }
<> 161:2cc1468da177 1619
<> 161:2cc1468da177 1620 /* Set trims */
<> 161:2cc1468da177 1621 if (trimMode == dcdcTrimMode_EM234H_LP)
<> 144:ef7eb2e8f9f7 1622 {
<> 161:2cc1468da177 1623 /* Make sure the sel value is within the field range. */
<> 161:2cc1468da177 1624 lpcmpHystSel <<= _GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_SHIFT;
<> 161:2cc1468da177 1625 if (lpcmpHystSel & ~_GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK)
<> 161:2cc1468da177 1626 {
<> 161:2cc1468da177 1627 EFM_ASSERT(false);
<> 161:2cc1468da177 1628 /* Return when assertions are disabled */
<> 161:2cc1468da177 1629 return false;
<> 161:2cc1468da177 1630 }
<> 161:2cc1468da177 1631 EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_GENERIC_DCDCLPCTRL_LPCMPHYSSELEM234H_MASK) | lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1632 }
<> 161:2cc1468da177 1633
<> 161:2cc1468da177 1634 #if defined( _EMU_DCDCLPEM01CFG_LPCMPHYSSELEM01_MASK )
<> 161:2cc1468da177 1635 if (trimMode == dcdcTrimMode_EM01_LP)
<> 161:2cc1468da177 1636 {
<> 161:2cc1468da177 1637 /* Make sure the sel value is within the field range. */
<> 161:2cc1468da177 1638 lpcmpHystSel <<= _EMU_DCDCLPEM01CFG_LPCMPHYSSELEM01_SHIFT;
<> 161:2cc1468da177 1639 if (lpcmpHystSel & ~_EMU_DCDCLPEM01CFG_LPCMPHYSSELEM01_MASK)
<> 161:2cc1468da177 1640 {
<> 161:2cc1468da177 1641 EFM_ASSERT(false);
<> 161:2cc1468da177 1642 /* Return when assertions are disabled */
<> 161:2cc1468da177 1643 return false;
<> 161:2cc1468da177 1644 }
<> 161:2cc1468da177 1645 EMU->DCDCLPEM01CFG = (EMU->DCDCLPEM01CFG & ~_EMU_DCDCLPEM01CFG_LPCMPHYSSELEM01_MASK) | lpcmpHystSel;
<> 161:2cc1468da177 1646 }
<> 161:2cc1468da177 1647 #endif
<> 144:ef7eb2e8f9f7 1648
<> 144:ef7eb2e8f9f7 1649 return true;
<> 144:ef7eb2e8f9f7 1650 }
<> 144:ef7eb2e8f9f7 1651
<> 161:2cc1468da177 1652
<> 161:2cc1468da177 1653 /***************************************************************************//**
<> 161:2cc1468da177 1654 * @brief
<> 161:2cc1468da177 1655 * Load LPVREF low and high from DEVINFO.
<> 161:2cc1468da177 1656 *
<> 161:2cc1468da177 1657 * @param[out] vrefL
<> 161:2cc1468da177 1658 * LPVREF low from DEVINFO.
<> 161:2cc1468da177 1659 * @param[out] vrefH
<> 161:2cc1468da177 1660 * LPVREF high from DEVINFO.
<> 161:2cc1468da177 1661 * @param[in] lpAttenuation
<> 161:2cc1468da177 1662 * LP feedback attenuation.
<> 161:2cc1468da177 1663 * @param[in] lpcmpBias
<> 161:2cc1468da177 1664 * lpcmpBias to lookup in DEVINFO.
<> 161:2cc1468da177 1665 ******************************************************************************/
<> 161:2cc1468da177 1666 static void lpGetDevinfoVrefLowHigh(uint32_t *vrefL,
<> 161:2cc1468da177 1667 uint32_t *vrefH,
<> 161:2cc1468da177 1668 bool lpAttenuation,
<> 161:2cc1468da177 1669 uint8_t lpcmpBias)
<> 161:2cc1468da177 1670 {
<> 161:2cc1468da177 1671 uint32_t vrefLow = 0;
<> 161:2cc1468da177 1672 uint32_t vrefHigh = 0;
<> 161:2cc1468da177 1673
<> 161:2cc1468da177 1674 /* Find VREF high and low in DEVINFO indexed by LPCMPBIAS (lpcmpBias)
<> 161:2cc1468da177 1675 and LPATT (lpAttenuation) */
<> 161:2cc1468da177 1676 uint32_t switchVal = (lpcmpBias << 8) | (lpAttenuation ? 1 : 0);
<> 161:2cc1468da177 1677 switch (switchVal)
<> 161:2cc1468da177 1678 {
<> 161:2cc1468da177 1679 case ((0 << 8) | 1):
<> 161:2cc1468da177 1680 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 161:2cc1468da177 1681 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)
<> 161:2cc1468da177 1682 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;
<> 161:2cc1468da177 1683 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)
<> 161:2cc1468da177 1684 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;
<> 161:2cc1468da177 1685 break;
<> 161:2cc1468da177 1686
<> 161:2cc1468da177 1687 case ((1 << 8) | 1):
<> 161:2cc1468da177 1688 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 161:2cc1468da177 1689 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)
<> 161:2cc1468da177 1690 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;
<> 161:2cc1468da177 1691 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)
<> 161:2cc1468da177 1692 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;
<> 161:2cc1468da177 1693 break;
<> 161:2cc1468da177 1694
<> 161:2cc1468da177 1695 case ((2 << 8) | 1):
<> 161:2cc1468da177 1696 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 161:2cc1468da177 1697 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)
<> 161:2cc1468da177 1698 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;
<> 161:2cc1468da177 1699 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)
<> 161:2cc1468da177 1700 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;
<> 161:2cc1468da177 1701 break;
<> 161:2cc1468da177 1702
<> 161:2cc1468da177 1703 case ((3 << 8) | 1):
<> 161:2cc1468da177 1704 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 161:2cc1468da177 1705 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)
<> 161:2cc1468da177 1706 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;
<> 161:2cc1468da177 1707 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)
<> 161:2cc1468da177 1708 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;
<> 161:2cc1468da177 1709 break;
<> 161:2cc1468da177 1710
<> 161:2cc1468da177 1711 case ((0 << 8) | 0):
<> 161:2cc1468da177 1712 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 161:2cc1468da177 1713 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)
<> 161:2cc1468da177 1714 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;
<> 161:2cc1468da177 1715 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)
<> 161:2cc1468da177 1716 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;
<> 161:2cc1468da177 1717 break;
<> 161:2cc1468da177 1718
<> 161:2cc1468da177 1719 case ((1 << 8) | 0):
<> 161:2cc1468da177 1720 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 161:2cc1468da177 1721 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)
<> 161:2cc1468da177 1722 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;
<> 161:2cc1468da177 1723 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)
<> 161:2cc1468da177 1724 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;
<> 161:2cc1468da177 1725 break;
<> 161:2cc1468da177 1726
<> 161:2cc1468da177 1727 case ((2 << 8) | 0):
<> 161:2cc1468da177 1728 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 161:2cc1468da177 1729 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)
<> 161:2cc1468da177 1730 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;
<> 161:2cc1468da177 1731 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)
<> 161:2cc1468da177 1732 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;
<> 161:2cc1468da177 1733 break;
<> 161:2cc1468da177 1734
<> 161:2cc1468da177 1735 case ((3 << 8) | 0):
<> 161:2cc1468da177 1736 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 161:2cc1468da177 1737 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)
<> 161:2cc1468da177 1738 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;
<> 161:2cc1468da177 1739 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)
<> 161:2cc1468da177 1740 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;
<> 161:2cc1468da177 1741 break;
<> 161:2cc1468da177 1742
<> 161:2cc1468da177 1743 default:
<> 161:2cc1468da177 1744 EFM_ASSERT(false);
<> 161:2cc1468da177 1745 break;
<> 161:2cc1468da177 1746 }
<> 161:2cc1468da177 1747 *vrefL = vrefLow;
<> 161:2cc1468da177 1748 *vrefH = vrefHigh;
<> 161:2cc1468da177 1749 }
<> 161:2cc1468da177 1750
<> 144:ef7eb2e8f9f7 1751 /** @endcond */
<> 144:ef7eb2e8f9f7 1752
<> 144:ef7eb2e8f9f7 1753 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1754 * @brief
<> 144:ef7eb2e8f9f7 1755 * Set DCDC regulator operating mode
<> 144:ef7eb2e8f9f7 1756 *
<> 144:ef7eb2e8f9f7 1757 * @param[in] dcdcMode
<> 144:ef7eb2e8f9f7 1758 * DCDC mode
<> 144:ef7eb2e8f9f7 1759 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1760 void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)
<> 144:ef7eb2e8f9f7 1761 {
<> 150:02e0a0aed4ec 1762 uint32_t currentDcdcMode = (EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK);
<> 150:02e0a0aed4ec 1763
<> 150:02e0a0aed4ec 1764 if ((EMU_DcdcMode_TypeDef)currentDcdcMode == dcdcMode)
<> 150:02e0a0aed4ec 1765 {
<> 150:02e0a0aed4ec 1766 /* Mode already set - do nothing */
<> 150:02e0a0aed4ec 1767 return;
<> 150:02e0a0aed4ec 1768 }
<> 150:02e0a0aed4ec 1769
<> 161:2cc1468da177 1770 #if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80)
<> 150:02e0a0aed4ec 1771
<> 144:ef7eb2e8f9f7 1772 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 150:02e0a0aed4ec 1773 /* Configure bypass current limiter */
<> 161:2cc1468da177 1774 BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);
<> 150:02e0a0aed4ec 1775
<> 150:02e0a0aed4ec 1776 /* Fix for errata DCDC_E203 */
<> 150:02e0a0aed4ec 1777 if (((EMU_DcdcMode_TypeDef)currentDcdcMode == emuDcdcMode_Bypass)
<> 150:02e0a0aed4ec 1778 && (dcdcMode == emuDcdcMode_LowNoise))
<> 150:02e0a0aed4ec 1779 {
<> 150:02e0a0aed4ec 1780 errataFixDcdcHsState = errataFixDcdcHsBypassLn;
<> 150:02e0a0aed4ec 1781 }
<> 150:02e0a0aed4ec 1782
<> 161:2cc1468da177 1783 #else
<> 150:02e0a0aed4ec 1784
<> 161:2cc1468da177 1785 /* Fix for errata DCDC_E204 */
<> 150:02e0a0aed4ec 1786 if (((currentDcdcMode == EMU_DCDCCTRL_DCDCMODE_OFF) || (currentDcdcMode == EMU_DCDCCTRL_DCDCMODE_BYPASS))
<> 150:02e0a0aed4ec 1787 && ((dcdcMode == emuDcdcMode_LowPower) || (dcdcMode == emuDcdcMode_LowNoise)))
<> 150:02e0a0aed4ec 1788 {
<> 150:02e0a0aed4ec 1789 /* Always start in LOWNOISE mode and then switch to LOWPOWER mode once LOWNOISE startup is complete. */
<> 150:02e0a0aed4ec 1790 EMU_IntClear(EMU_IFC_DCDCLNRUNNING);
<> 150:02e0a0aed4ec 1791 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 150:02e0a0aed4ec 1792 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | EMU_DCDCCTRL_DCDCMODE_LOWNOISE;
<> 150:02e0a0aed4ec 1793 while(!(EMU_IntGet() & EMU_IF_DCDCLNRUNNING));
<> 150:02e0a0aed4ec 1794 }
<> 150:02e0a0aed4ec 1795 #endif
<> 150:02e0a0aed4ec 1796
<> 150:02e0a0aed4ec 1797 /* Set user requested mode. */
<> 161:2cc1468da177 1798 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 144:ef7eb2e8f9f7 1799 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;
<> 144:ef7eb2e8f9f7 1800 }
<> 144:ef7eb2e8f9f7 1801
<> 144:ef7eb2e8f9f7 1802
<> 144:ef7eb2e8f9f7 1803 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1804 * @brief
<> 161:2cc1468da177 1805 * Set DCDC LN regulator conduction mode
<> 161:2cc1468da177 1806 *
<> 161:2cc1468da177 1807 * @param[in] conductionMode
<> 161:2cc1468da177 1808 * DCDC LN conduction mode.
<> 161:2cc1468da177 1809 * @param[in] rcoDefaultSet
<> 161:2cc1468da177 1810 * The default DCDC RCO band for the conductionMode will be used if true.
<> 161:2cc1468da177 1811 * Otherwise the current RCO configuration is used.
<> 161:2cc1468da177 1812 ******************************************************************************/
<> 161:2cc1468da177 1813 void EMU_DCDCConductionModeSet(EMU_DcdcConductionMode_TypeDef conductionMode, bool rcoDefaultSet)
<> 161:2cc1468da177 1814 {
<> 161:2cc1468da177 1815 EMU_DcdcMode_TypeDef currentDcdcMode
<> 161:2cc1468da177 1816 = (EMU_DcdcMode_TypeDef)(EMU->DCDCCTRL & _EMU_DCDCCTRL_DCDCMODE_MASK);
<> 161:2cc1468da177 1817 EMU_DcdcLnRcoBand_TypeDef rcoBand
<> 161:2cc1468da177 1818 = (EMU_DcdcLnRcoBand_TypeDef)((EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 161:2cc1468da177 1819 >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 161:2cc1468da177 1820
<> 161:2cc1468da177 1821 /* Set bypass mode and wait for bypass mode to settle before
<> 161:2cc1468da177 1822 EMU_DCDCMISCCTRL_LNFORCECCM is set. Restore current DCDC mode. */
<> 161:2cc1468da177 1823 EMU_IntClear(EMU_IFC_DCDCINBYPASS);
<> 161:2cc1468da177 1824 EMU_DCDCModeSet(emuDcdcMode_Bypass);
<> 161:2cc1468da177 1825 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 161:2cc1468da177 1826 while(!(EMU_IntGet() & EMU_IF_DCDCINBYPASS));
<> 161:2cc1468da177 1827 if (conductionMode == emuDcdcConductionMode_DiscontinuousLN)
<> 161:2cc1468da177 1828 {
<> 161:2cc1468da177 1829 EMU->DCDCMISCCTRL &= ~ EMU_DCDCMISCCTRL_LNFORCECCM;
<> 161:2cc1468da177 1830 if (rcoDefaultSet)
<> 161:2cc1468da177 1831 {
<> 161:2cc1468da177 1832 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_3MHz);
<> 161:2cc1468da177 1833 }
<> 161:2cc1468da177 1834 else
<> 161:2cc1468da177 1835 {
<> 161:2cc1468da177 1836 /* emuDcdcConductionMode_DiscontinuousLN supports up to 4MHz LN RCO. */
<> 161:2cc1468da177 1837 EFM_ASSERT(rcoBand <= emuDcdcLnRcoBand_4MHz);
<> 161:2cc1468da177 1838 }
<> 161:2cc1468da177 1839 }
<> 161:2cc1468da177 1840 else
<> 161:2cc1468da177 1841 {
<> 161:2cc1468da177 1842 EMU->DCDCMISCCTRL |= EMU_DCDCMISCCTRL_LNFORCECCM;
<> 161:2cc1468da177 1843 if (rcoDefaultSet)
<> 161:2cc1468da177 1844 {
<> 161:2cc1468da177 1845 EMU_DCDCLnRcoBandSet(emuDcdcLnRcoBand_7MHz);
<> 161:2cc1468da177 1846 }
<> 161:2cc1468da177 1847 }
<> 161:2cc1468da177 1848 EMU_DCDCModeSet(currentDcdcMode);
<> 161:2cc1468da177 1849 /* Update slice configuration as it depends on conduction mode and RCO band. */
<> 161:2cc1468da177 1850 EMU_DCDCOptimizeSlice(dcdcEm01LoadCurrent_mA);
<> 161:2cc1468da177 1851 }
<> 161:2cc1468da177 1852
<> 161:2cc1468da177 1853
<> 161:2cc1468da177 1854 /***************************************************************************//**
<> 161:2cc1468da177 1855 * @brief
<> 144:ef7eb2e8f9f7 1856 * Configure DCDC regulator
<> 144:ef7eb2e8f9f7 1857 *
<> 144:ef7eb2e8f9f7 1858 * @note
<> 150:02e0a0aed4ec 1859 * If the power circuit is configured for NODCDC as described in Section
<> 150:02e0a0aed4ec 1860 * 11.3.4.3 of the Reference Manual, do not call this function. Instead call
<> 150:02e0a0aed4ec 1861 * EMU_DCDCPowerOff().
<> 144:ef7eb2e8f9f7 1862 *
<> 144:ef7eb2e8f9f7 1863 * @param[in] dcdcInit
<> 144:ef7eb2e8f9f7 1864 * DCDC initialization structure
<> 144:ef7eb2e8f9f7 1865 *
<> 144:ef7eb2e8f9f7 1866 * @return
<> 144:ef7eb2e8f9f7 1867 * True if initialization parameters are valid
<> 144:ef7eb2e8f9f7 1868 ******************************************************************************/
<> 161:2cc1468da177 1869 bool EMU_DCDCInit(const EMU_DCDCInit_TypeDef *dcdcInit)
<> 144:ef7eb2e8f9f7 1870 {
<> 150:02e0a0aed4ec 1871 uint32_t lpCmpBiasSelEM234H;
<> 144:ef7eb2e8f9f7 1872
<> 161:2cc1468da177 1873 #if defined(_EMU_PWRCFG_MASK)
<> 144:ef7eb2e8f9f7 1874 /* Set external power configuration. This enables writing to the other
<> 144:ef7eb2e8f9f7 1875 DCDC registers. */
<> 161:2cc1468da177 1876 EMU->PWRCFG = EMU_PWRCFG_PWRCFG_DCDCTODVDD;
<> 144:ef7eb2e8f9f7 1877
<> 144:ef7eb2e8f9f7 1878 /* EMU->PWRCFG is write-once and POR reset only. Check that
<> 144:ef7eb2e8f9f7 1879 we could set the desired power configuration. */
<> 161:2cc1468da177 1880 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != EMU_PWRCFG_PWRCFG_DCDCTODVDD)
<> 144:ef7eb2e8f9f7 1881 {
<> 144:ef7eb2e8f9f7 1882 /* If this assert triggers unexpectedly, please power cycle the
<> 144:ef7eb2e8f9f7 1883 kit to reset the power configuration. */
<> 144:ef7eb2e8f9f7 1884 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1885 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1886 return false;
<> 144:ef7eb2e8f9f7 1887 }
<> 161:2cc1468da177 1888 #endif
<> 144:ef7eb2e8f9f7 1889
<> 144:ef7eb2e8f9f7 1890 /* Load DCDC calibration data from the DI page */
<> 161:2cc1468da177 1891 dcdcConstCalibrationLoad();
<> 144:ef7eb2e8f9f7 1892
<> 144:ef7eb2e8f9f7 1893 /* Check current parameters */
<> 144:ef7eb2e8f9f7 1894 EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1895 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);
<> 150:02e0a0aed4ec 1896 EFM_ASSERT(dcdcInit->reverseCurrentControl <= 200);
<> 144:ef7eb2e8f9f7 1897
<> 144:ef7eb2e8f9f7 1898 if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)
<> 144:ef7eb2e8f9f7 1899 {
<> 161:2cc1468da177 1900 /* DCDC low-noise supports max 200mA */
<> 144:ef7eb2e8f9f7 1901 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1902 }
<> 161:2cc1468da177 1903 #if (_SILICON_LABS_GECKO_INTERNAL_SDID != 80)
<> 150:02e0a0aed4ec 1904 else if (dcdcInit->dcdcMode == emuDcdcMode_LowPower)
<> 150:02e0a0aed4ec 1905 {
<> 161:2cc1468da177 1906 /* Up to 10mA is supported for EM01-LP mode. */
<> 150:02e0a0aed4ec 1907 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 10);
<> 150:02e0a0aed4ec 1908 }
<> 150:02e0a0aed4ec 1909 #endif
<> 144:ef7eb2e8f9f7 1910
<> 150:02e0a0aed4ec 1911 /* EM2/3/4 current above 10mA is not supported */
<> 150:02e0a0aed4ec 1912 EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 10000);
<> 144:ef7eb2e8f9f7 1913
<> 150:02e0a0aed4ec 1914 if (dcdcInit->em234LoadCurrent_uA < 75)
<> 144:ef7eb2e8f9f7 1915 {
<> 150:02e0a0aed4ec 1916 lpCmpBiasSelEM234H = 0;
<> 150:02e0a0aed4ec 1917 }
<> 150:02e0a0aed4ec 1918 else if (dcdcInit->em234LoadCurrent_uA < 500)
<> 150:02e0a0aed4ec 1919 {
<> 150:02e0a0aed4ec 1920 lpCmpBiasSelEM234H = 1 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 144:ef7eb2e8f9f7 1921 }
<> 150:02e0a0aed4ec 1922 else if (dcdcInit->em234LoadCurrent_uA < 2500)
<> 150:02e0a0aed4ec 1923 {
<> 150:02e0a0aed4ec 1924 lpCmpBiasSelEM234H = 2 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 150:02e0a0aed4ec 1925 }
<> 150:02e0a0aed4ec 1926 else
<> 150:02e0a0aed4ec 1927 {
<> 150:02e0a0aed4ec 1928 lpCmpBiasSelEM234H = 3 << _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 150:02e0a0aed4ec 1929 }
<> 150:02e0a0aed4ec 1930
<> 150:02e0a0aed4ec 1931 /* ==== THESE NEXT STEPS ARE STRONGLY ORDER DEPENDENT ==== */
<> 144:ef7eb2e8f9f7 1932
<> 144:ef7eb2e8f9f7 1933 /* Set DCDC low-power mode comparator bias selection */
<> 150:02e0a0aed4ec 1934
<> 150:02e0a0aed4ec 1935 /* 1. Set DCDC low-power mode comparator bias selection and forced CCM
<> 150:02e0a0aed4ec 1936 => Updates DCDCMISCCTRL_LNFORCECCM */
<> 150:02e0a0aed4ec 1937 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK
<> 144:ef7eb2e8f9f7 1938 | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))
<> 150:02e0a0aed4ec 1939 | ((uint32_t)lpCmpBiasSelEM234H
<> 150:02e0a0aed4ec 1940 | (dcdcInit->reverseCurrentControl >= 0 ?
<> 150:02e0a0aed4ec 1941 EMU_DCDCMISCCTRL_LNFORCECCM : 0));
<> 150:02e0a0aed4ec 1942 #if defined(_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 161:2cc1468da177 1943 /* Only 10mA EM01-LP current is supported */
<> 150:02e0a0aed4ec 1944 EMU->DCDCLPEM01CFG = (EMU->DCDCLPEM01CFG & ~_EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 161:2cc1468da177 1945 | EMU_DCDCLPEM01CFG_LPCMPBIASEM01_BIAS3;
<> 150:02e0a0aed4ec 1946 #endif
<> 144:ef7eb2e8f9f7 1947
<> 150:02e0a0aed4ec 1948 /* 2. Set recommended and validated current optimization settings
<> 150:02e0a0aed4ec 1949 <= Depends on LNFORCECCM
<> 150:02e0a0aed4ec 1950 => Updates DCDCLNFREQCTRL_RCOBAND */
<> 161:2cc1468da177 1951 dcdcValidatedConfigSet();
<> 144:ef7eb2e8f9f7 1952
<> 150:02e0a0aed4ec 1953 /* 3. Updated static currents and limits user data.
<> 150:02e0a0aed4ec 1954 Limiters are updated in EMU_DCDCOptimizeSlice() */
<> 150:02e0a0aed4ec 1955 userCurrentLimitsSet(dcdcInit->maxCurrent_mA,
<> 150:02e0a0aed4ec 1956 dcdcInit->reverseCurrentControl);
<> 150:02e0a0aed4ec 1957 dcdcEm01LoadCurrent_mA = dcdcInit->em01LoadCurrent_mA;
<> 144:ef7eb2e8f9f7 1958
<> 150:02e0a0aed4ec 1959 /* 4. Optimize LN slice based on given user input load current
<> 150:02e0a0aed4ec 1960 <= Depends on DCDCMISCCTRL_LNFORCECCM and DCDCLNFREQCTRL_RCOBAND
<> 150:02e0a0aed4ec 1961 <= Depends on dcdcInit->maxCurrent_mA and dcdcInit->reverseCurrentControl
<> 150:02e0a0aed4ec 1962 => Updates DCDCMISCCTRL_P/NFETCNT
<> 150:02e0a0aed4ec 1963 => Updates DCDCMISCCTRL_LNCLIMILIMSEL and DCDCMISCCTRL_LPCLIMILIMSEL
<> 150:02e0a0aed4ec 1964 => Updates DCDCZDETCTRL_ZDETILIMSEL */
<> 144:ef7eb2e8f9f7 1965 EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 1966
<> 150:02e0a0aed4ec 1967 /* ======================================================= */
<> 150:02e0a0aed4ec 1968
<> 150:02e0a0aed4ec 1969 /* Set DCDC low noise mode compensator control register. */
<> 150:02e0a0aed4ec 1970 compCtrlSet(dcdcInit->dcdcLnCompCtrl);
<> 150:02e0a0aed4ec 1971
<> 144:ef7eb2e8f9f7 1972 /* Set DCDC output voltage */
<> 150:02e0a0aed4ec 1973 if (!EMU_DCDCOutputVoltageSet(dcdcInit->mVout, true, true))
<> 144:ef7eb2e8f9f7 1974 {
<> 144:ef7eb2e8f9f7 1975 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1976 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1977 return false;
<> 144:ef7eb2e8f9f7 1978 }
<> 144:ef7eb2e8f9f7 1979
<> 161:2cc1468da177 1980 #if ( _SILICON_LABS_GECKO_INTERNAL_SDID == 80 )
<> 150:02e0a0aed4ec 1981 /* Select analog peripheral power supply. This must be done before
<> 161:2cc1468da177 1982 DCDC mode is set for all EFM32xG1 and EFR32xG1 devices. */
<> 150:02e0a0aed4ec 1983 BUS_RegBitWrite(&EMU->PWRCTRL,
<> 150:02e0a0aed4ec 1984 _EMU_PWRCTRL_ANASW_SHIFT,
<> 150:02e0a0aed4ec 1985 dcdcInit->anaPeripheralPower ? 1 : 0);
<> 150:02e0a0aed4ec 1986 #endif
<> 150:02e0a0aed4ec 1987
<> 161:2cc1468da177 1988 #if defined(_EMU_PWRCTRL_REGPWRSEL_MASK)
<> 161:2cc1468da177 1989 /* Select DVDD as input to the digital regulator. The switch to DVDD will take
<> 161:2cc1468da177 1990 effect once the DCDC output is stable. */
<> 161:2cc1468da177 1991 EMU->PWRCTRL |= EMU_PWRCTRL_REGPWRSEL_DVDD;
<> 161:2cc1468da177 1992 #endif
<> 161:2cc1468da177 1993
<> 150:02e0a0aed4ec 1994 /* Set EM0 DCDC operating mode. Output voltage set in
<> 150:02e0a0aed4ec 1995 EMU_DCDCOutputVoltageSet() above takes effect if mode
<> 150:02e0a0aed4ec 1996 is changed from bypass/off mode. */
<> 144:ef7eb2e8f9f7 1997 EMU_DCDCModeSet(dcdcInit->dcdcMode);
<> 144:ef7eb2e8f9f7 1998
<> 161:2cc1468da177 1999 #if ( _SILICON_LABS_GECKO_INTERNAL_SDID != 80 )
<> 150:02e0a0aed4ec 2000 /* Select analog peripheral power supply. This must be done after
<> 161:2cc1468da177 2001 DCDC mode is set for all devices other than EFM32xG1 and EFR32xG1. */
<> 150:02e0a0aed4ec 2002 BUS_RegBitWrite(&EMU->PWRCTRL,
<> 150:02e0a0aed4ec 2003 _EMU_PWRCTRL_ANASW_SHIFT,
<> 150:02e0a0aed4ec 2004 dcdcInit->anaPeripheralPower ? 1 : 0);
<> 150:02e0a0aed4ec 2005 #endif
<> 144:ef7eb2e8f9f7 2006
<> 144:ef7eb2e8f9f7 2007 return true;
<> 144:ef7eb2e8f9f7 2008 }
<> 144:ef7eb2e8f9f7 2009
<> 144:ef7eb2e8f9f7 2010 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2011 * @brief
<> 144:ef7eb2e8f9f7 2012 * Set DCDC output voltage
<> 144:ef7eb2e8f9f7 2013 *
<> 144:ef7eb2e8f9f7 2014 * @param[in] mV
<> 144:ef7eb2e8f9f7 2015 * Target DCDC output voltage in mV
<> 144:ef7eb2e8f9f7 2016 *
<> 144:ef7eb2e8f9f7 2017 * @return
<> 144:ef7eb2e8f9f7 2018 * True if the mV parameter is valid
<> 144:ef7eb2e8f9f7 2019 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2020 bool EMU_DCDCOutputVoltageSet(uint32_t mV,
<> 144:ef7eb2e8f9f7 2021 bool setLpVoltage,
<> 144:ef7eb2e8f9f7 2022 bool setLnVoltage)
<> 144:ef7eb2e8f9f7 2023 {
<> 144:ef7eb2e8f9f7 2024 #if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )
<> 144:ef7eb2e8f9f7 2025
<> 161:2cc1468da177 2026 #define DCDC_TRIM_MODES ((uint8_t)dcdcTrimMode_LN + 1)
<> 144:ef7eb2e8f9f7 2027 bool validOutVoltage;
<> 161:2cc1468da177 2028 bool attenuationSet;
<> 144:ef7eb2e8f9f7 2029 uint32_t mVlow = 0;
<> 144:ef7eb2e8f9f7 2030 uint32_t mVhigh = 0;
<> 161:2cc1468da177 2031 uint32_t mVdiff;
<> 161:2cc1468da177 2032 uint32_t vrefVal[DCDC_TRIM_MODES] = {0};
<> 161:2cc1468da177 2033 uint32_t vrefLow[DCDC_TRIM_MODES] = {0};
<> 161:2cc1468da177 2034 uint32_t vrefHigh[DCDC_TRIM_MODES] = {0};
<> 161:2cc1468da177 2035 uint8_t lpcmpBias[DCDC_TRIM_MODES] = {0};
<> 144:ef7eb2e8f9f7 2036
<> 144:ef7eb2e8f9f7 2037 /* Check that the set voltage is within valid range.
<> 144:ef7eb2e8f9f7 2038 Voltages are obtained from the datasheet. */
<> 161:2cc1468da177 2039 validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)
<> 161:2cc1468da177 2040 && (mV <= PWRCFG_DCDCTODVDD_VMAX));
<> 144:ef7eb2e8f9f7 2041
<> 144:ef7eb2e8f9f7 2042 if (!validOutVoltage)
<> 144:ef7eb2e8f9f7 2043 {
<> 144:ef7eb2e8f9f7 2044 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2045 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 2046 return false;
<> 144:ef7eb2e8f9f7 2047 }
<> 144:ef7eb2e8f9f7 2048
<> 161:2cc1468da177 2049 /* Set attenuation to use and low/high range. */
<> 161:2cc1468da177 2050 attenuationSet = (mV > 1800);
<> 161:2cc1468da177 2051 if (attenuationSet)
<> 144:ef7eb2e8f9f7 2052 {
<> 161:2cc1468da177 2053 mVlow = 1800;
<> 161:2cc1468da177 2054 mVhigh = 3000;
<> 161:2cc1468da177 2055 mVdiff = mVhigh - mVlow;
<> 161:2cc1468da177 2056 }
<> 161:2cc1468da177 2057 else
<> 161:2cc1468da177 2058 {
<> 161:2cc1468da177 2059 mVlow = 1200;
<> 161:2cc1468da177 2060 mVhigh = 1800;
<> 161:2cc1468da177 2061 mVdiff = mVhigh - mVlow;
<> 161:2cc1468da177 2062 }
<> 144:ef7eb2e8f9f7 2063
<> 161:2cc1468da177 2064 /* Get 2-point calib data from DEVINFO */
<> 144:ef7eb2e8f9f7 2065
<> 161:2cc1468da177 2066 /* LN mode */
<> 161:2cc1468da177 2067 if (attenuationSet)
<> 144:ef7eb2e8f9f7 2068 {
<> 161:2cc1468da177 2069 vrefLow[dcdcTrimMode_LN] = DEVINFO->DCDCLNVCTRL0;
<> 161:2cc1468da177 2070 vrefHigh[dcdcTrimMode_LN] = (vrefLow[dcdcTrimMode_LN] & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)
<> 161:2cc1468da177 2071 >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;
<> 161:2cc1468da177 2072 vrefLow[dcdcTrimMode_LN] = (vrefLow[dcdcTrimMode_LN] & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)
<> 161:2cc1468da177 2073 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 2074 }
<> 144:ef7eb2e8f9f7 2075 else
<> 144:ef7eb2e8f9f7 2076 {
<> 161:2cc1468da177 2077 vrefLow[dcdcTrimMode_LN] = DEVINFO->DCDCLNVCTRL0;
<> 161:2cc1468da177 2078 vrefHigh[dcdcTrimMode_LN] = (vrefLow[dcdcTrimMode_LN] & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)
<> 161:2cc1468da177 2079 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;
<> 161:2cc1468da177 2080 vrefLow[dcdcTrimMode_LN] = (vrefLow[dcdcTrimMode_LN] & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)
<> 161:2cc1468da177 2081 >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;
<> 161:2cc1468da177 2082 }
<> 144:ef7eb2e8f9f7 2083
<> 144:ef7eb2e8f9f7 2084
<> 161:2cc1468da177 2085 /* LP EM234H mode */
<> 161:2cc1468da177 2086 lpcmpBias[dcdcTrimMode_EM234H_LP] = (EMU->DCDCMISCCTRL & _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_MASK)
<> 161:2cc1468da177 2087 >> _GENERIC_DCDCMISCCTRL_LPCMPBIASEM234H_SHIFT;
<> 161:2cc1468da177 2088 lpGetDevinfoVrefLowHigh(&vrefLow[dcdcTrimMode_EM234H_LP],
<> 161:2cc1468da177 2089 &vrefHigh[dcdcTrimMode_EM234H_LP],
<> 161:2cc1468da177 2090 attenuationSet,
<> 161:2cc1468da177 2091 lpcmpBias[dcdcTrimMode_EM234H_LP]);
<> 144:ef7eb2e8f9f7 2092
<> 161:2cc1468da177 2093 #if defined( _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK )
<> 161:2cc1468da177 2094 /* LP EM01 mode */
<> 161:2cc1468da177 2095 lpcmpBias[dcdcTrimMode_EM01_LP] = (EMU->DCDCLPEM01CFG & _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK)
<> 161:2cc1468da177 2096 >> _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_SHIFT;
<> 161:2cc1468da177 2097 lpGetDevinfoVrefLowHigh(&vrefLow[dcdcTrimMode_EM01_LP],
<> 161:2cc1468da177 2098 &vrefHigh[dcdcTrimMode_EM01_LP],
<> 161:2cc1468da177 2099 attenuationSet,
<> 161:2cc1468da177 2100 lpcmpBias[dcdcTrimMode_EM01_LP]);
<> 161:2cc1468da177 2101 #endif
<> 144:ef7eb2e8f9f7 2102
<> 144:ef7eb2e8f9f7 2103
<> 161:2cc1468da177 2104 /* Calculate output voltage trims */
<> 161:2cc1468da177 2105 vrefVal[dcdcTrimMode_LN] = ((mV - mVlow) * (vrefHigh[dcdcTrimMode_LN] - vrefLow[dcdcTrimMode_LN]))
<> 161:2cc1468da177 2106 / mVdiff;
<> 161:2cc1468da177 2107 vrefVal[dcdcTrimMode_LN] += vrefLow[dcdcTrimMode_LN];
<> 161:2cc1468da177 2108
<> 161:2cc1468da177 2109 vrefVal[dcdcTrimMode_EM234H_LP] = ((mV - mVlow) * (vrefHigh[dcdcTrimMode_EM234H_LP] - vrefLow[dcdcTrimMode_EM234H_LP]))
<> 161:2cc1468da177 2110 / mVdiff;
<> 161:2cc1468da177 2111 vrefVal[dcdcTrimMode_EM234H_LP] += vrefLow[dcdcTrimMode_EM234H_LP];
<> 161:2cc1468da177 2112
<> 161:2cc1468da177 2113 #if defined( _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK )
<> 161:2cc1468da177 2114 vrefVal[dcdcTrimMode_EM01_LP] = ((mV - mVlow) * (vrefHigh[dcdcTrimMode_EM01_LP] - vrefLow[dcdcTrimMode_EM01_LP]))
<> 161:2cc1468da177 2115 / mVdiff;
<> 161:2cc1468da177 2116 vrefVal[dcdcTrimMode_EM01_LP] += vrefLow[dcdcTrimMode_EM01_LP];
<> 161:2cc1468da177 2117 #endif
<> 161:2cc1468da177 2118
<> 161:2cc1468da177 2119 /* Range checks */
<> 161:2cc1468da177 2120 if ((vrefVal[dcdcTrimMode_LN] > vrefHigh[dcdcTrimMode_LN])
<> 161:2cc1468da177 2121 || (vrefVal[dcdcTrimMode_LN] < vrefLow[dcdcTrimMode_LN])
<> 161:2cc1468da177 2122 #if defined( _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK )
<> 161:2cc1468da177 2123 || (vrefVal[dcdcTrimMode_EM01_LP] > vrefHigh[dcdcTrimMode_EM01_LP])
<> 161:2cc1468da177 2124 || (vrefVal[dcdcTrimMode_EM01_LP] < vrefLow[dcdcTrimMode_EM01_LP])
<> 161:2cc1468da177 2125 #endif
<> 161:2cc1468da177 2126 || (vrefVal[dcdcTrimMode_EM234H_LP] > vrefHigh[dcdcTrimMode_EM234H_LP])
<> 161:2cc1468da177 2127 || (vrefVal[dcdcTrimMode_EM234H_LP] < vrefLow[dcdcTrimMode_EM234H_LP]))
<> 161:2cc1468da177 2128 {
<> 161:2cc1468da177 2129 EFM_ASSERT(false);
<> 161:2cc1468da177 2130 /* Return when assertions are disabled */
<> 161:2cc1468da177 2131 return false;
<> 161:2cc1468da177 2132 }
<> 161:2cc1468da177 2133
<> 161:2cc1468da177 2134 /* Update output voltage tuning for LN and LP modes. */
<> 161:2cc1468da177 2135 if (setLnVoltage)
<> 161:2cc1468da177 2136 {
<> 161:2cc1468da177 2137 EMU->DCDCLNVCTRL = (EMU->DCDCLNVCTRL & ~(_EMU_DCDCLNVCTRL_LNVREF_MASK | _EMU_DCDCLNVCTRL_LNATT_MASK))
<> 161:2cc1468da177 2138 | (vrefVal[dcdcTrimMode_LN] << _EMU_DCDCLNVCTRL_LNVREF_SHIFT)
<> 161:2cc1468da177 2139 | (attenuationSet ? EMU_DCDCLNVCTRL_LNATT : 0);
<> 161:2cc1468da177 2140 }
<> 161:2cc1468da177 2141
<> 161:2cc1468da177 2142 if (setLpVoltage)
<> 161:2cc1468da177 2143 {
<> 161:2cc1468da177 2144 /* Load LP EM234H comparator hysteresis calibration */
<> 161:2cc1468da177 2145 if(!(lpCmpHystCalibrationLoad(attenuationSet, lpcmpBias[dcdcTrimMode_EM234H_LP], dcdcTrimMode_EM234H_LP)))
<> 144:ef7eb2e8f9f7 2146 {
<> 144:ef7eb2e8f9f7 2147 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2148 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 2149 return false;
<> 144:ef7eb2e8f9f7 2150 }
<> 144:ef7eb2e8f9f7 2151
<> 161:2cc1468da177 2152 #if defined( _EMU_DCDCLPEM01CFG_LPCMPBIASEM01_MASK )
<> 161:2cc1468da177 2153 /* Load LP EM234H comparator hysteresis calibration */
<> 161:2cc1468da177 2154 if(!(lpCmpHystCalibrationLoad(attenuationSet, lpcmpBias[dcdcTrimMode_EM01_LP], dcdcTrimMode_EM01_LP)))
<> 144:ef7eb2e8f9f7 2155 {
<> 144:ef7eb2e8f9f7 2156 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2157 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 2158 return false;
<> 144:ef7eb2e8f9f7 2159 }
<> 144:ef7eb2e8f9f7 2160
<> 161:2cc1468da177 2161 /* LP VREF is that max of trims for EM01 and EM234H. */
<> 161:2cc1468da177 2162 vrefVal[dcdcTrimMode_EM234H_LP] = SL_MAX(vrefVal[dcdcTrimMode_EM234H_LP], vrefVal[dcdcTrimMode_EM01_LP]);
<> 161:2cc1468da177 2163 #endif
<> 161:2cc1468da177 2164
<> 161:2cc1468da177 2165 /* Don't exceed max available code as specified in the reference manual for EMU_DCDCLPVCTRL. */
<> 161:2cc1468da177 2166 vrefVal[dcdcTrimMode_EM234H_LP] = SL_MIN(vrefVal[dcdcTrimMode_EM234H_LP], 0xE7U);
<> 161:2cc1468da177 2167 EMU->DCDCLPVCTRL = (EMU->DCDCLPVCTRL & ~(_EMU_DCDCLPVCTRL_LPVREF_MASK | _EMU_DCDCLPVCTRL_LPATT_MASK))
<> 161:2cc1468da177 2168 | (vrefVal[dcdcTrimMode_EM234H_LP] << _EMU_DCDCLPVCTRL_LPVREF_SHIFT)
<> 161:2cc1468da177 2169 | (attenuationSet ? EMU_DCDCLPVCTRL_LPATT : 0);
<> 144:ef7eb2e8f9f7 2170 }
<> 144:ef7eb2e8f9f7 2171 #endif
<> 144:ef7eb2e8f9f7 2172 return true;
<> 144:ef7eb2e8f9f7 2173 }
<> 144:ef7eb2e8f9f7 2174
<> 144:ef7eb2e8f9f7 2175
<> 144:ef7eb2e8f9f7 2176 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2177 * @brief
<> 144:ef7eb2e8f9f7 2178 * Optimize DCDC slice count based on the estimated average load current
<> 144:ef7eb2e8f9f7 2179 * in EM0
<> 144:ef7eb2e8f9f7 2180 *
<> 150:02e0a0aed4ec 2181 * @param[in] em0LoadCurrent_mA
<> 144:ef7eb2e8f9f7 2182 * Estimated average EM0 load current in mA.
<> 144:ef7eb2e8f9f7 2183 ******************************************************************************/
<> 150:02e0a0aed4ec 2184 void EMU_DCDCOptimizeSlice(uint32_t em0LoadCurrent_mA)
<> 144:ef7eb2e8f9f7 2185 {
<> 144:ef7eb2e8f9f7 2186 uint32_t sliceCount = 0;
<> 144:ef7eb2e8f9f7 2187 uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 2188 >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;
<> 144:ef7eb2e8f9f7 2189
<> 144:ef7eb2e8f9f7 2190 /* Set recommended slice count */
<> 150:02e0a0aed4ec 2191 if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= emuDcdcLnRcoBand_5MHz))
<> 144:ef7eb2e8f9f7 2192 {
<> 150:02e0a0aed4ec 2193 if (em0LoadCurrent_mA < 20)
<> 144:ef7eb2e8f9f7 2194 {
<> 144:ef7eb2e8f9f7 2195 sliceCount = 4;
<> 144:ef7eb2e8f9f7 2196 }
<> 150:02e0a0aed4ec 2197 else if ((em0LoadCurrent_mA >= 20) && (em0LoadCurrent_mA < 40))
<> 144:ef7eb2e8f9f7 2198 {
<> 144:ef7eb2e8f9f7 2199 sliceCount = 8;
<> 144:ef7eb2e8f9f7 2200 }
<> 144:ef7eb2e8f9f7 2201 else
<> 144:ef7eb2e8f9f7 2202 {
<> 144:ef7eb2e8f9f7 2203 sliceCount = 16;
<> 144:ef7eb2e8f9f7 2204 }
<> 144:ef7eb2e8f9f7 2205 }
<> 150:02e0a0aed4ec 2206 else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= emuDcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 2207 {
<> 150:02e0a0aed4ec 2208 if (em0LoadCurrent_mA < 10)
<> 144:ef7eb2e8f9f7 2209 {
<> 144:ef7eb2e8f9f7 2210 sliceCount = 4;
<> 144:ef7eb2e8f9f7 2211 }
<> 150:02e0a0aed4ec 2212 else if ((em0LoadCurrent_mA >= 10) && (em0LoadCurrent_mA < 20))
<> 144:ef7eb2e8f9f7 2213 {
<> 144:ef7eb2e8f9f7 2214 sliceCount = 8;
<> 144:ef7eb2e8f9f7 2215 }
<> 144:ef7eb2e8f9f7 2216 else
<> 144:ef7eb2e8f9f7 2217 {
<> 144:ef7eb2e8f9f7 2218 sliceCount = 16;
<> 144:ef7eb2e8f9f7 2219 }
<> 144:ef7eb2e8f9f7 2220 }
<> 150:02e0a0aed4ec 2221 else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= emuDcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 2222 {
<> 150:02e0a0aed4ec 2223 if (em0LoadCurrent_mA < 40)
<> 144:ef7eb2e8f9f7 2224 {
<> 144:ef7eb2e8f9f7 2225 sliceCount = 8;
<> 144:ef7eb2e8f9f7 2226 }
<> 144:ef7eb2e8f9f7 2227 else
<> 144:ef7eb2e8f9f7 2228 {
<> 144:ef7eb2e8f9f7 2229 sliceCount = 16;
<> 144:ef7eb2e8f9f7 2230 }
<> 144:ef7eb2e8f9f7 2231 }
<> 144:ef7eb2e8f9f7 2232 else
<> 144:ef7eb2e8f9f7 2233 {
<> 144:ef7eb2e8f9f7 2234 /* This configuration is not recommended. EMU_DCDCInit() applies a recommended
<> 144:ef7eb2e8f9f7 2235 configuration. */
<> 144:ef7eb2e8f9f7 2236 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2237 }
<> 144:ef7eb2e8f9f7 2238
<> 150:02e0a0aed4ec 2239 /* The selected slices are PSLICESEL + 1 */
<> 144:ef7eb2e8f9f7 2240 sliceCount--;
<> 144:ef7eb2e8f9f7 2241
<> 144:ef7eb2e8f9f7 2242 /* Apply slice count to both N and P slice */
<> 144:ef7eb2e8f9f7 2243 sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT
<> 144:ef7eb2e8f9f7 2244 | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 2245 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK
<> 144:ef7eb2e8f9f7 2246 | _EMU_DCDCMISCCTRL_NFETCNT_MASK))
<> 144:ef7eb2e8f9f7 2247 | sliceCount;
<> 144:ef7eb2e8f9f7 2248
<> 150:02e0a0aed4ec 2249 /* Update current limiters */
<> 150:02e0a0aed4ec 2250 currentLimitersUpdate();
<> 144:ef7eb2e8f9f7 2251 }
<> 144:ef7eb2e8f9f7 2252
<> 144:ef7eb2e8f9f7 2253 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2254 * @brief
<> 144:ef7eb2e8f9f7 2255 * Set DCDC Low-noise RCO band.
<> 144:ef7eb2e8f9f7 2256 *
<> 144:ef7eb2e8f9f7 2257 * @param[in] band
<> 144:ef7eb2e8f9f7 2258 * RCO band to set.
<> 144:ef7eb2e8f9f7 2259 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2260 void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)
<> 144:ef7eb2e8f9f7 2261 {
<> 150:02e0a0aed4ec 2262 uint32_t forcedCcm;
<> 150:02e0a0aed4ec 2263 forcedCcm = BUS_RegBitRead(&EMU->DCDCMISCCTRL, _EMU_DCDCMISCCTRL_LNFORCECCM_SHIFT);
<> 150:02e0a0aed4ec 2264
<> 150:02e0a0aed4ec 2265 /* DCM mode supports up to 4MHz LN RCO. */
<> 150:02e0a0aed4ec 2266 EFM_ASSERT((!forcedCcm && band <= emuDcdcLnRcoBand_4MHz) || forcedCcm);
<> 150:02e0a0aed4ec 2267
<> 144:ef7eb2e8f9f7 2268 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 2269 | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 150:02e0a0aed4ec 2270
<> 150:02e0a0aed4ec 2271 /* Update slice configuration as this depends on the RCO band. */
<> 150:02e0a0aed4ec 2272 EMU_DCDCOptimizeSlice(dcdcEm01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 2273 }
<> 144:ef7eb2e8f9f7 2274
<> 144:ef7eb2e8f9f7 2275 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2276 * @brief
<> 144:ef7eb2e8f9f7 2277 * Power off the DCDC regulator.
<> 144:ef7eb2e8f9f7 2278 *
<> 144:ef7eb2e8f9f7 2279 * @details
<> 144:ef7eb2e8f9f7 2280 * This function powers off the DCDC controller. This function should only be
<> 144:ef7eb2e8f9f7 2281 * used if the external power circuit is wired for no DCDC. If the external power
<> 144:ef7eb2e8f9f7 2282 * circuit is wired for DCDC usage, then use EMU_DCDCInit() and set the
<> 144:ef7eb2e8f9f7 2283 * DCDC in bypass mode to disable DCDC.
<> 144:ef7eb2e8f9f7 2284 *
<> 144:ef7eb2e8f9f7 2285 * @return
<> 144:ef7eb2e8f9f7 2286 * Return false if the DCDC could not be disabled.
<> 144:ef7eb2e8f9f7 2287 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2288 bool EMU_DCDCPowerOff(void)
<> 144:ef7eb2e8f9f7 2289 {
<> 150:02e0a0aed4ec 2290 bool dcdcModeSet;
<> 150:02e0a0aed4ec 2291
<> 161:2cc1468da177 2292 #if defined(_EMU_PWRCFG_MASK)
<> 150:02e0a0aed4ec 2293 /* Set DCDCTODVDD only to enable write access to EMU->DCDCCTRL */
<> 150:02e0a0aed4ec 2294 EMU->PWRCFG = EMU_PWRCFG_PWRCFG_DCDCTODVDD;
<> 161:2cc1468da177 2295 #endif
<> 150:02e0a0aed4ec 2296
<> 150:02e0a0aed4ec 2297 /* Select DVDD as input to the digital regulator */
<> 161:2cc1468da177 2298 #if defined(EMU_PWRCTRL_IMMEDIATEPWRSWITCH)
<> 161:2cc1468da177 2299 EMU->PWRCTRL |= EMU_PWRCTRL_REGPWRSEL_DVDD | EMU_PWRCTRL_IMMEDIATEPWRSWITCH;
<> 161:2cc1468da177 2300 #elif defined(EMU_PWRCTRL_REGPWRSEL_DVDD)
<> 150:02e0a0aed4ec 2301 EMU->PWRCTRL |= EMU_PWRCTRL_REGPWRSEL_DVDD;
<> 150:02e0a0aed4ec 2302 #endif
<> 144:ef7eb2e8f9f7 2303
<> 150:02e0a0aed4ec 2304 /* Set DCDC to OFF and disable LP in EM2/3/4. Verify that the required
<> 150:02e0a0aed4ec 2305 mode could be set. */
<> 150:02e0a0aed4ec 2306 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 144:ef7eb2e8f9f7 2307 EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;
<> 150:02e0a0aed4ec 2308
<> 150:02e0a0aed4ec 2309 dcdcModeSet = (EMU->DCDCCTRL == EMU_DCDCCTRL_DCDCMODE_OFF);
<> 150:02e0a0aed4ec 2310 EFM_ASSERT(dcdcModeSet);
<> 150:02e0a0aed4ec 2311
<> 150:02e0a0aed4ec 2312 return dcdcModeSet;
<> 144:ef7eb2e8f9f7 2313 }
<> 144:ef7eb2e8f9f7 2314 #endif
<> 144:ef7eb2e8f9f7 2315
<> 144:ef7eb2e8f9f7 2316
<> 144:ef7eb2e8f9f7 2317 #if defined( EMU_STATUS_VMONRDY )
<> 144:ef7eb2e8f9f7 2318 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 2319 __STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)
<> 144:ef7eb2e8f9f7 2320 {
<> 144:ef7eb2e8f9f7 2321 return (mV - 1200) / 200;
<> 144:ef7eb2e8f9f7 2322 }
<> 144:ef7eb2e8f9f7 2323
<> 144:ef7eb2e8f9f7 2324 __STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)
<> 144:ef7eb2e8f9f7 2325 {
<> 144:ef7eb2e8f9f7 2326 return (mV - 1200 - (coarseThreshold * 200)) / 20;
<> 144:ef7eb2e8f9f7 2327 }
<> 144:ef7eb2e8f9f7 2328 /** @endcond */
<> 144:ef7eb2e8f9f7 2329
<> 144:ef7eb2e8f9f7 2330 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2331 * @brief
<> 144:ef7eb2e8f9f7 2332 * Initialize VMON channel.
<> 144:ef7eb2e8f9f7 2333 *
<> 144:ef7eb2e8f9f7 2334 * @details
<> 144:ef7eb2e8f9f7 2335 * Initialize a VMON channel without hysteresis. If the channel supports
<> 144:ef7eb2e8f9f7 2336 * separate rise and fall triggers, both thresholds will be set to the same
<> 144:ef7eb2e8f9f7 2337 * value.
<> 144:ef7eb2e8f9f7 2338 *
<> 144:ef7eb2e8f9f7 2339 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 2340 * VMON initialization struct
<> 144:ef7eb2e8f9f7 2341 ******************************************************************************/
<> 161:2cc1468da177 2342 void EMU_VmonInit(const EMU_VmonInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 2343 {
<> 144:ef7eb2e8f9f7 2344 uint32_t thresholdCoarse, thresholdFine;
<> 144:ef7eb2e8f9f7 2345 EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));
<> 144:ef7eb2e8f9f7 2346
<> 144:ef7eb2e8f9f7 2347 thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);
<> 144:ef7eb2e8f9f7 2348 thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);
<> 144:ef7eb2e8f9f7 2349
<> 144:ef7eb2e8f9f7 2350 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 2351 {
<> 144:ef7eb2e8f9f7 2352 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2353 EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2354 | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2355 | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2356 | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2357 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2358 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2359 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2360 break;
<> 144:ef7eb2e8f9f7 2361 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2362 EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2363 | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2364 | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2365 | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2366 | (vmonInit->enable ? EMU_VMONALTAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2367 break;
<> 144:ef7eb2e8f9f7 2368 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2369 EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2370 | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2371 | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2372 | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2373 | (vmonInit->enable ? EMU_VMONDVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2374 break;
<> 144:ef7eb2e8f9f7 2375 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2376 EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2377 | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2378 | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)
<> 144:ef7eb2e8f9f7 2379 | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2380 | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2381 | (vmonInit->enable ? EMU_VMONIO0CTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2382 break;
<> 144:ef7eb2e8f9f7 2383 default:
<> 144:ef7eb2e8f9f7 2384 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2385 return;
<> 144:ef7eb2e8f9f7 2386 }
<> 144:ef7eb2e8f9f7 2387 }
<> 144:ef7eb2e8f9f7 2388
<> 144:ef7eb2e8f9f7 2389 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2390 * @brief
<> 144:ef7eb2e8f9f7 2391 * Initialize VMON channel with hysteresis (separate rise and fall triggers).
<> 144:ef7eb2e8f9f7 2392 *
<> 144:ef7eb2e8f9f7 2393 * @details
<> 144:ef7eb2e8f9f7 2394 * Initialize a VMON channel which supports hysteresis. The AVDD channel is
<> 144:ef7eb2e8f9f7 2395 * the only channel to support separate rise and fall triggers.
<> 144:ef7eb2e8f9f7 2396 *
<> 144:ef7eb2e8f9f7 2397 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 2398 * VMON Hysteresis initialization struct
<> 144:ef7eb2e8f9f7 2399 ******************************************************************************/
<> 161:2cc1468da177 2400 void EMU_VmonHystInit(const EMU_VmonHystInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 2401 {
<> 144:ef7eb2e8f9f7 2402 uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;
<> 144:ef7eb2e8f9f7 2403 /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */
<> 144:ef7eb2e8f9f7 2404 EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));
<> 144:ef7eb2e8f9f7 2405 EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));
<> 144:ef7eb2e8f9f7 2406 /* Fall threshold has to be lower than rise threshold */
<> 144:ef7eb2e8f9f7 2407 EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 2408
<> 144:ef7eb2e8f9f7 2409 riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 2410 riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);
<> 144:ef7eb2e8f9f7 2411 fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);
<> 144:ef7eb2e8f9f7 2412 fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);
<> 144:ef7eb2e8f9f7 2413
<> 144:ef7eb2e8f9f7 2414 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 2415 {
<> 144:ef7eb2e8f9f7 2416 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2417 EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2418 | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2419 | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 2420 | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 2421 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 2422 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 2423 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 2424 break;
<> 144:ef7eb2e8f9f7 2425 default:
<> 144:ef7eb2e8f9f7 2426 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2427 return;
<> 144:ef7eb2e8f9f7 2428 }
<> 144:ef7eb2e8f9f7 2429 }
<> 144:ef7eb2e8f9f7 2430
<> 144:ef7eb2e8f9f7 2431 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2432 * @brief
<> 144:ef7eb2e8f9f7 2433 * Enable or disable a VMON channel
<> 144:ef7eb2e8f9f7 2434 *
<> 144:ef7eb2e8f9f7 2435 * @param[in] channel
<> 144:ef7eb2e8f9f7 2436 * VMON channel to enable/disable
<> 144:ef7eb2e8f9f7 2437 *
<> 144:ef7eb2e8f9f7 2438 * @param[in] enable
<> 144:ef7eb2e8f9f7 2439 * Whether to enable or disable
<> 144:ef7eb2e8f9f7 2440 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2441 void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)
<> 144:ef7eb2e8f9f7 2442 {
<> 144:ef7eb2e8f9f7 2443 uint32_t volatile * reg;
<> 144:ef7eb2e8f9f7 2444 uint32_t bit;
<> 144:ef7eb2e8f9f7 2445
<> 144:ef7eb2e8f9f7 2446 switch(channel)
<> 144:ef7eb2e8f9f7 2447 {
<> 144:ef7eb2e8f9f7 2448 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2449 reg = &(EMU->VMONAVDDCTRL);
<> 144:ef7eb2e8f9f7 2450 bit = _EMU_VMONAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2451 break;
<> 144:ef7eb2e8f9f7 2452 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2453 reg = &(EMU->VMONALTAVDDCTRL);
<> 144:ef7eb2e8f9f7 2454 bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2455 break;
<> 144:ef7eb2e8f9f7 2456 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2457 reg = &(EMU->VMONDVDDCTRL);
<> 144:ef7eb2e8f9f7 2458 bit = _EMU_VMONDVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2459 break;
<> 144:ef7eb2e8f9f7 2460 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2461 reg = &(EMU->VMONIO0CTRL);
<> 144:ef7eb2e8f9f7 2462 bit = _EMU_VMONIO0CTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 2463 break;
<> 144:ef7eb2e8f9f7 2464 default:
<> 144:ef7eb2e8f9f7 2465 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2466 return;
<> 144:ef7eb2e8f9f7 2467 }
<> 144:ef7eb2e8f9f7 2468
<> 144:ef7eb2e8f9f7 2469 BUS_RegBitWrite(reg, bit, enable);
<> 144:ef7eb2e8f9f7 2470 }
<> 144:ef7eb2e8f9f7 2471
<> 144:ef7eb2e8f9f7 2472 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2473 * @brief
<> 144:ef7eb2e8f9f7 2474 * Get the status of a voltage monitor channel.
<> 144:ef7eb2e8f9f7 2475 *
<> 144:ef7eb2e8f9f7 2476 * @param[in] channel
<> 144:ef7eb2e8f9f7 2477 * VMON channel to get status for
<> 144:ef7eb2e8f9f7 2478 *
<> 144:ef7eb2e8f9f7 2479 * @return
<> 144:ef7eb2e8f9f7 2480 * Status of the selected VMON channel. True if channel is triggered.
<> 144:ef7eb2e8f9f7 2481 ******************************************************************************/
<> 144:ef7eb2e8f9f7 2482 bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)
<> 144:ef7eb2e8f9f7 2483 {
<> 144:ef7eb2e8f9f7 2484 uint32_t bit;
<> 144:ef7eb2e8f9f7 2485 switch(channel)
<> 144:ef7eb2e8f9f7 2486 {
<> 144:ef7eb2e8f9f7 2487 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 2488 bit = _EMU_STATUS_VMONAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2489 break;
<> 144:ef7eb2e8f9f7 2490 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 2491 bit = _EMU_STATUS_VMONALTAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2492 break;
<> 144:ef7eb2e8f9f7 2493 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 2494 bit = _EMU_STATUS_VMONDVDD_SHIFT;
<> 144:ef7eb2e8f9f7 2495 break;
<> 144:ef7eb2e8f9f7 2496 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 2497 bit = _EMU_STATUS_VMONIO0_SHIFT;
<> 144:ef7eb2e8f9f7 2498 break;
<> 144:ef7eb2e8f9f7 2499 default:
<> 144:ef7eb2e8f9f7 2500 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 2501 bit = 0;
<> 144:ef7eb2e8f9f7 2502 }
<> 144:ef7eb2e8f9f7 2503
<> 144:ef7eb2e8f9f7 2504 return BUS_RegBitRead(&EMU->STATUS, bit);
<> 144:ef7eb2e8f9f7 2505 }
<> 144:ef7eb2e8f9f7 2506 #endif /* EMU_STATUS_VMONRDY */
<> 144:ef7eb2e8f9f7 2507
<> 161:2cc1468da177 2508 #if defined( _SILICON_LABS_GECKO_INTERNAL_SDID_80 )
<> 161:2cc1468da177 2509 /***************************************************************************//**
<> 150:02e0a0aed4ec 2510 * @brief
<> 150:02e0a0aed4ec 2511 * Adjust the bias refresh rate
<> 150:02e0a0aed4ec 2512 *
<> 150:02e0a0aed4ec 2513 * @details
<> 150:02e0a0aed4ec 2514 * This function is only meant to be used under high-temperature operation on
<> 161:2cc1468da177 2515 * EFR32xG1 and EFM32xG1 devices. Adjusting the bias mode will
<> 150:02e0a0aed4ec 2516 * increase the typical current consumption. See application note 1027
<> 150:02e0a0aed4ec 2517 * and errata documents for further details.
<> 150:02e0a0aed4ec 2518 *
<> 150:02e0a0aed4ec 2519 * @param [in] mode
<> 150:02e0a0aed4ec 2520 * The new bias refresh rate
<> 161:2cc1468da177 2521 ******************************************************************************/
<> 150:02e0a0aed4ec 2522 void EMU_SetBiasMode(EMU_BiasMode_TypeDef mode)
<> 150:02e0a0aed4ec 2523 {
<> 150:02e0a0aed4ec 2524 #define EMU_TESTLOCK (*(volatile uint32_t *) (EMU_BASE + 0x190))
<> 150:02e0a0aed4ec 2525 #define EMU_BIASCONF (*(volatile uint32_t *) (EMU_BASE + 0x164))
<> 150:02e0a0aed4ec 2526 #define EMU_BIASTESTCTRL (*(volatile uint32_t *) (EMU_BASE + 0x19C))
<> 150:02e0a0aed4ec 2527 #define CMU_ULFRCOCTRL (*(volatile uint32_t *) (CMU_BASE + 0x03C))
<> 150:02e0a0aed4ec 2528
<> 161:2cc1468da177 2529 uint32_t freq = 0x2u;
<> 150:02e0a0aed4ec 2530 bool emuTestLocked = false;
<> 150:02e0a0aed4ec 2531
<> 150:02e0a0aed4ec 2532 if (mode == emuBiasMode_1KHz)
<> 150:02e0a0aed4ec 2533 {
<> 161:2cc1468da177 2534 freq = 0x0u;
<> 150:02e0a0aed4ec 2535 }
<> 150:02e0a0aed4ec 2536
<> 161:2cc1468da177 2537 if (EMU_TESTLOCK == 0x1u)
<> 150:02e0a0aed4ec 2538 {
<> 150:02e0a0aed4ec 2539 emuTestLocked = true;
<> 161:2cc1468da177 2540 EMU_TESTLOCK = 0xADE8u;
<> 150:02e0a0aed4ec 2541 }
<> 150:02e0a0aed4ec 2542
<> 150:02e0a0aed4ec 2543 if (mode == emuBiasMode_Continuous)
<> 150:02e0a0aed4ec 2544 {
<> 161:2cc1468da177 2545 EMU_BIASCONF &= ~0x74u;
<> 150:02e0a0aed4ec 2546 }
<> 150:02e0a0aed4ec 2547 else
<> 150:02e0a0aed4ec 2548 {
<> 161:2cc1468da177 2549 EMU_BIASCONF |= 0x74u;
<> 150:02e0a0aed4ec 2550 }
<> 150:02e0a0aed4ec 2551
<> 161:2cc1468da177 2552 EMU_BIASTESTCTRL |= 0x8u;
<> 161:2cc1468da177 2553 CMU_ULFRCOCTRL = (CMU_ULFRCOCTRL & ~0xC00u)
<> 161:2cc1468da177 2554 | ((freq & 0x3u) << 10u);
<> 161:2cc1468da177 2555 EMU_BIASTESTCTRL &= ~0x8u;
<> 150:02e0a0aed4ec 2556
<> 150:02e0a0aed4ec 2557 if (emuTestLocked)
<> 150:02e0a0aed4ec 2558 {
<> 161:2cc1468da177 2559 EMU_TESTLOCK = 0u;
<> 150:02e0a0aed4ec 2560 }
<> 150:02e0a0aed4ec 2561 }
<> 150:02e0a0aed4ec 2562 #endif
<> 150:02e0a0aed4ec 2563
<> 144:ef7eb2e8f9f7 2564 /** @} (end addtogroup EMU) */
<> 150:02e0a0aed4ec 2565 /** @} (end addtogroup emlib) */
<> 144:ef7eb2e8f9f7 2566 #endif /* __EM_EMU_H */