mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
179:b0033dcd6934
mbed library release version 165

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