added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

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
<> 144:ef7eb2e8f9f7 4 * @version 4.2.1
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
<> 144:ef7eb2e8f9f7 6 * @section License
<> 144:ef7eb2e8f9f7 7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include <limits.h>
<> 144:ef7eb2e8f9f7 34
<> 144:ef7eb2e8f9f7 35 #include "em_emu.h"
<> 144:ef7eb2e8f9f7 36 #if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )
<> 144:ef7eb2e8f9f7 37
<> 144:ef7eb2e8f9f7 38 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 39 #include "em_system.h"
<> 144:ef7eb2e8f9f7 40 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 43 * @addtogroup EM_Library
<> 144:ef7eb2e8f9f7 44 * @{
<> 144:ef7eb2e8f9f7 45 ******************************************************************************/
<> 144:ef7eb2e8f9f7 46
<> 144:ef7eb2e8f9f7 47 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 48 * @addtogroup EMU
<> 144:ef7eb2e8f9f7 49 * @brief Energy Management Unit (EMU) Peripheral API
<> 144:ef7eb2e8f9f7 50 * @{
<> 144:ef7eb2e8f9f7 51 ******************************************************************************/
<> 144:ef7eb2e8f9f7 52
<> 144:ef7eb2e8f9f7 53 /* Consistency check, since restoring assumes similar bitpositions in */
<> 144:ef7eb2e8f9f7 54 /* CMU OSCENCMD and STATUS regs */
<> 144:ef7eb2e8f9f7 55 #if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
<> 144:ef7eb2e8f9f7 56 #error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 57 #endif
<> 144:ef7eb2e8f9f7 58 #if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
<> 144:ef7eb2e8f9f7 59 #error Conflict in HFXOENS and HFXOEN bitpositions
<> 144:ef7eb2e8f9f7 60 #endif
<> 144:ef7eb2e8f9f7 61 #if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
<> 144:ef7eb2e8f9f7 62 #error Conflict in LFRCOENS and LFRCOEN bitpositions
<> 144:ef7eb2e8f9f7 63 #endif
<> 144:ef7eb2e8f9f7 64 #if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
<> 144:ef7eb2e8f9f7 65 #error Conflict in LFXOENS and LFXOEN bitpositions
<> 144:ef7eb2e8f9f7 66 #endif
<> 144:ef7eb2e8f9f7 67
<> 144:ef7eb2e8f9f7 68
<> 144:ef7eb2e8f9f7 69 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 70 /* Fix for errata EMU_E107 - non-WIC interrupt masks. */
<> 144:ef7eb2e8f9f7 71 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 72 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 73 #define NON_WIC_INT_MASK_0 (~(0x0dfc0323U))
<> 144:ef7eb2e8f9f7 74 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 77 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 78 #define NON_WIC_INT_MASK_0 (~(0x001be323U))
<> 144:ef7eb2e8f9f7 79 #define NON_WIC_INT_MASK_1 (~(0x0U))
<> 144:ef7eb2e8f9f7 80
<> 144:ef7eb2e8f9f7 81 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 82 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 83 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 84 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 87 #define ERRATA_FIX_EMU_E107_EN
<> 144:ef7eb2e8f9f7 88 #define NON_WIC_INT_MASK_0 (~(0xff020e63U))
<> 144:ef7eb2e8f9f7 89 #define NON_WIC_INT_MASK_1 (~(0x00000046U))
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 #else
<> 144:ef7eb2e8f9f7 92 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 93 #endif
<> 144:ef7eb2e8f9f7 94
<> 144:ef7eb2e8f9f7 95 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 96 #if defined( _EFM32_HAPPY_FAMILY )
<> 144:ef7eb2e8f9f7 97 #define ERRATA_FIX_EMU_E108_EN
<> 144:ef7eb2e8f9f7 98 #endif
<> 144:ef7eb2e8f9f7 99 /** @endcond */
<> 144:ef7eb2e8f9f7 100
<> 144:ef7eb2e8f9f7 101
<> 144:ef7eb2e8f9f7 102 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 103 /* DCDCTODVDD output range min/max */
<> 144:ef7eb2e8f9f7 104 #define PWRCFG_DCDCTODVDD_VMIN 1200
<> 144:ef7eb2e8f9f7 105 #define PWRCFG_DCDCTODVDD_VMAX 3000
<> 144:ef7eb2e8f9f7 106 typedef enum
<> 144:ef7eb2e8f9f7 107 {
<> 144:ef7eb2e8f9f7 108 errataFixDcdcHsInit,
<> 144:ef7eb2e8f9f7 109 errataFixDcdcHsTrimSet,
<> 144:ef7eb2e8f9f7 110 errataFixDcdcHsLnWaitDone
<> 144:ef7eb2e8f9f7 111 } errataFixDcdcHs_TypeDef;
<> 144:ef7eb2e8f9f7 112 errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;
<> 144:ef7eb2e8f9f7 113 #endif
<> 144:ef7eb2e8f9f7 114
<> 144:ef7eb2e8f9f7 115 /*******************************************************************************
<> 144:ef7eb2e8f9f7 116 ************************** LOCAL VARIABLES ********************************
<> 144:ef7eb2e8f9f7 117 ******************************************************************************/
<> 144:ef7eb2e8f9f7 118
<> 144:ef7eb2e8f9f7 119 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 120 /**
<> 144:ef7eb2e8f9f7 121 * CMU configured oscillator selection and oscillator enable status. When a
<> 144:ef7eb2e8f9f7 122 * user configures oscillators, this varaiable shall shadow the configuration.
<> 144:ef7eb2e8f9f7 123 * It is used by the EMU module in order to be able to restore the oscillator
<> 144:ef7eb2e8f9f7 124 * config after having been in certain energy modes (since HW may automatically
<> 144:ef7eb2e8f9f7 125 * alter config when going into an energy mode). It is the responsibility of
<> 144:ef7eb2e8f9f7 126 * the CMU module to keep it up-to-date (or a user if not using the CMU API
<> 144:ef7eb2e8f9f7 127 * for oscillator control).
<> 144:ef7eb2e8f9f7 128 */
<> 144:ef7eb2e8f9f7 129 static uint32_t cmuStatus;
<> 144:ef7eb2e8f9f7 130 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 131 static uint16_t cmuHfclkStatus;
<> 144:ef7eb2e8f9f7 132 #endif
<> 144:ef7eb2e8f9f7 133 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 134 static uint16_t dcdcMaxCurrent_mA;
<> 144:ef7eb2e8f9f7 135 static uint16_t dcdcOutput_mVout;
<> 144:ef7eb2e8f9f7 136 #endif
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 /** @endcond */
<> 144:ef7eb2e8f9f7 139
<> 144:ef7eb2e8f9f7 140
<> 144:ef7eb2e8f9f7 141 /*******************************************************************************
<> 144:ef7eb2e8f9f7 142 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 143 ******************************************************************************/
<> 144:ef7eb2e8f9f7 144
<> 144:ef7eb2e8f9f7 145 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 146
<> 144:ef7eb2e8f9f7 147 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 148 * @brief
<> 144:ef7eb2e8f9f7 149 * Restore oscillators and core clock after having been in EM2 or EM3.
<> 144:ef7eb2e8f9f7 150 ******************************************************************************/
<> 144:ef7eb2e8f9f7 151 static void emuRestore(void)
<> 144:ef7eb2e8f9f7 152 {
<> 144:ef7eb2e8f9f7 153 uint32_t oscEnCmd;
<> 144:ef7eb2e8f9f7 154 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 155
<> 144:ef7eb2e8f9f7 156 /* Although we could use the CMU API for most of the below handling, we */
<> 144:ef7eb2e8f9f7 157 /* would like this function to be as efficient as possible. */
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 160 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 161 CMU_Unlock();
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 /* AUXHFRCO are automatically disabled (except if using debugger). */
<> 144:ef7eb2e8f9f7 164 /* HFRCO, USHFRCO and HFXO are automatically disabled. */
<> 144:ef7eb2e8f9f7 165 /* LFRCO/LFXO may be disabled by SW in EM3. */
<> 144:ef7eb2e8f9f7 166 /* Restore according to status prior to entering energy mode. */
<> 144:ef7eb2e8f9f7 167 oscEnCmd = 0;
<> 144:ef7eb2e8f9f7 168 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS) ? CMU_OSCENCMD_HFRCOEN : 0);
<> 144:ef7eb2e8f9f7 169 oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 170 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS) ? CMU_OSCENCMD_LFRCOEN : 0);
<> 144:ef7eb2e8f9f7 171 oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS) ? CMU_OSCENCMD_HFXOEN : 0);
<> 144:ef7eb2e8f9f7 172 oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS) ? CMU_OSCENCMD_LFXOEN : 0);
<> 144:ef7eb2e8f9f7 173 #if defined( _CMU_STATUS_USHFRCOENS_MASK )
<> 144:ef7eb2e8f9f7 174 oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS) ? CMU_OSCENCMD_USHFRCOEN : 0);
<> 144:ef7eb2e8f9f7 175 #endif
<> 144:ef7eb2e8f9f7 176 CMU->OSCENCMD = oscEnCmd;
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178
<> 144:ef7eb2e8f9f7 179 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 180 /* Restore oscillator used for clocking core */
<> 144:ef7eb2e8f9f7 181 switch (cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 182 {
<> 144:ef7eb2e8f9f7 183 case CMU_HFCLKSTATUS_SELECTED_LFRCO:
<> 144:ef7eb2e8f9f7 184 /* HFRCO could only be selected if the autostart HFXO feature is not
<> 144:ef7eb2e8f9f7 185 * enabled, otherwise the HFXO would be started and selected automatically.
<> 144:ef7eb2e8f9f7 186 * Note: this error hook helps catching erroneous oscillator configurations,
<> 144:ef7eb2e8f9f7 187 * when the AUTOSTARTSELEM0EM1 is set in CMU_HFXOCTRL. */
<> 144:ef7eb2e8f9f7 188 if (!(CMU->HFXOCTRL & CMU_HFXOCTRL_AUTOSTARTSELEM0EM1))
<> 144:ef7eb2e8f9f7 189 {
<> 144:ef7eb2e8f9f7 190 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 191 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 192 ;
<> 144:ef7eb2e8f9f7 193 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFRCO;
<> 144:ef7eb2e8f9f7 194 }
<> 144:ef7eb2e8f9f7 195 else
<> 144:ef7eb2e8f9f7 196 {
<> 144:ef7eb2e8f9f7 197 EFM_ASSERT(0);
<> 144:ef7eb2e8f9f7 198 }
<> 144:ef7eb2e8f9f7 199 break;
<> 144:ef7eb2e8f9f7 200
<> 144:ef7eb2e8f9f7 201 case CMU_HFCLKSTATUS_SELECTED_LFXO:
<> 144:ef7eb2e8f9f7 202 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 203 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 204 ;
<> 144:ef7eb2e8f9f7 205 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFXO;
<> 144:ef7eb2e8f9f7 206 break;
<> 144:ef7eb2e8f9f7 207
<> 144:ef7eb2e8f9f7 208 case CMU_HFCLKSTATUS_SELECTED_HFXO:
<> 144:ef7eb2e8f9f7 209 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 210 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 211 ;
<> 144:ef7eb2e8f9f7 212 CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO;
<> 144:ef7eb2e8f9f7 213 break;
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
<> 144:ef7eb2e8f9f7 216 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 217 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 218 break;
<> 144:ef7eb2e8f9f7 219 }
<> 144:ef7eb2e8f9f7 220 #else
<> 144:ef7eb2e8f9f7 221 switch (cmuStatus & (CMU_STATUS_HFRCOSEL
<> 144:ef7eb2e8f9f7 222 | CMU_STATUS_HFXOSEL
<> 144:ef7eb2e8f9f7 223 | CMU_STATUS_LFRCOSEL
<> 144:ef7eb2e8f9f7 224 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 225 | CMU_STATUS_USHFRCODIV2SEL
<> 144:ef7eb2e8f9f7 226 #endif
<> 144:ef7eb2e8f9f7 227 | CMU_STATUS_LFXOSEL))
<> 144:ef7eb2e8f9f7 228 {
<> 144:ef7eb2e8f9f7 229 case CMU_STATUS_LFRCOSEL:
<> 144:ef7eb2e8f9f7 230 /* Wait for LFRCO to stabilize */
<> 144:ef7eb2e8f9f7 231 while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
<> 144:ef7eb2e8f9f7 232 ;
<> 144:ef7eb2e8f9f7 233 CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
<> 144:ef7eb2e8f9f7 234 break;
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 case CMU_STATUS_LFXOSEL:
<> 144:ef7eb2e8f9f7 237 /* Wait for LFXO to stabilize */
<> 144:ef7eb2e8f9f7 238 while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
<> 144:ef7eb2e8f9f7 239 ;
<> 144:ef7eb2e8f9f7 240 CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
<> 144:ef7eb2e8f9f7 241 break;
<> 144:ef7eb2e8f9f7 242
<> 144:ef7eb2e8f9f7 243 case CMU_STATUS_HFXOSEL:
<> 144:ef7eb2e8f9f7 244 /* Wait for HFXO to stabilize */
<> 144:ef7eb2e8f9f7 245 while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
<> 144:ef7eb2e8f9f7 246 ;
<> 144:ef7eb2e8f9f7 247 CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
<> 144:ef7eb2e8f9f7 248 break;
<> 144:ef7eb2e8f9f7 249
<> 144:ef7eb2e8f9f7 250 #if defined( CMU_STATUS_USHFRCODIV2SEL )
<> 144:ef7eb2e8f9f7 251 case CMU_STATUS_USHFRCODIV2SEL:
<> 144:ef7eb2e8f9f7 252 /* Wait for USHFRCO to stabilize */
<> 144:ef7eb2e8f9f7 253 while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))
<> 144:ef7eb2e8f9f7 254 ;
<> 144:ef7eb2e8f9f7 255 CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;
<> 144:ef7eb2e8f9f7 256 break;
<> 144:ef7eb2e8f9f7 257 #endif
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 default: /* CMU_STATUS_HFRCOSEL */
<> 144:ef7eb2e8f9f7 260 /* If core clock was HFRCO core clock, it is automatically restored to */
<> 144:ef7eb2e8f9f7 261 /* state prior to entering energy mode. No need for further action. */
<> 144:ef7eb2e8f9f7 262 break;
<> 144:ef7eb2e8f9f7 263 }
<> 144:ef7eb2e8f9f7 264
<> 144:ef7eb2e8f9f7 265 /* If HFRCO was disabled before entering Energy Mode, turn it off again */
<> 144:ef7eb2e8f9f7 266 /* as it is automatically enabled by wake up */
<> 144:ef7eb2e8f9f7 267 if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
<> 144:ef7eb2e8f9f7 268 {
<> 144:ef7eb2e8f9f7 269 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
<> 144:ef7eb2e8f9f7 270 }
<> 144:ef7eb2e8f9f7 271 #endif
<> 144:ef7eb2e8f9f7 272 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 273 if (cmuLocked)
<> 144:ef7eb2e8f9f7 274 {
<> 144:ef7eb2e8f9f7 275 CMU_Lock();
<> 144:ef7eb2e8f9f7 276 }
<> 144:ef7eb2e8f9f7 277 }
<> 144:ef7eb2e8f9f7 278
<> 144:ef7eb2e8f9f7 279
<> 144:ef7eb2e8f9f7 280 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 281 /* Get enable conditions for errata EMU_E107 fix. */
<> 144:ef7eb2e8f9f7 282 static __INLINE bool getErrataFixEmuE107En(void)
<> 144:ef7eb2e8f9f7 283 {
<> 144:ef7eb2e8f9f7 284 /* SYSTEM_ChipRevisionGet could have been used here, but we would like a
<> 144:ef7eb2e8f9f7 285 * faster implementation in this case.
<> 144:ef7eb2e8f9f7 286 */
<> 144:ef7eb2e8f9f7 287 uint16_t majorMinorRev;
<> 144:ef7eb2e8f9f7 288
<> 144:ef7eb2e8f9f7 289 /* CHIP MAJOR bit [3:0] */
<> 144:ef7eb2e8f9f7 290 majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)
<> 144:ef7eb2e8f9f7 291 >> _ROMTABLE_PID0_REVMAJOR_SHIFT)
<> 144:ef7eb2e8f9f7 292 << 8;
<> 144:ef7eb2e8f9f7 293 /* CHIP MINOR bit [7:4] */
<> 144:ef7eb2e8f9f7 294 majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)
<> 144:ef7eb2e8f9f7 295 >> _ROMTABLE_PID2_REVMINORMSB_SHIFT)
<> 144:ef7eb2e8f9f7 296 << 4;
<> 144:ef7eb2e8f9f7 297 /* CHIP MINOR bit [3:0] */
<> 144:ef7eb2e8f9f7 298 majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)
<> 144:ef7eb2e8f9f7 299 >> _ROMTABLE_PID3_REVMINORLSB_SHIFT;
<> 144:ef7eb2e8f9f7 300
<> 144:ef7eb2e8f9f7 301 #if defined( _EFM32_GECKO_FAMILY )
<> 144:ef7eb2e8f9f7 302 return (majorMinorRev <= 0x0103);
<> 144:ef7eb2e8f9f7 303 #elif defined( _EFM32_TINY_FAMILY )
<> 144:ef7eb2e8f9f7 304 return (majorMinorRev <= 0x0102);
<> 144:ef7eb2e8f9f7 305 #elif defined( _EFM32_GIANT_FAMILY )
<> 144:ef7eb2e8f9f7 306 return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);
<> 144:ef7eb2e8f9f7 307 #elif defined( _EFM32_WONDER_FAMILY )
<> 144:ef7eb2e8f9f7 308 return (majorMinorRev == 0x0100);
<> 144:ef7eb2e8f9f7 309 #else
<> 144:ef7eb2e8f9f7 310 /* Zero Gecko and future families are not affected by errata EMU_E107 */
<> 144:ef7eb2e8f9f7 311 return false;
<> 144:ef7eb2e8f9f7 312 #endif
<> 144:ef7eb2e8f9f7 313 }
<> 144:ef7eb2e8f9f7 314 #endif
<> 144:ef7eb2e8f9f7 315
<> 144:ef7eb2e8f9f7 316
<> 144:ef7eb2e8f9f7 317 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 318 /* LP prepare / LN restore P/NFET count */
<> 144:ef7eb2e8f9f7 319 static void maxCurrentUpdate(void);
<> 144:ef7eb2e8f9f7 320 #define DCDC_LP_PFET_CNT 7
<> 144:ef7eb2e8f9f7 321 #define DCDC_LP_NFET_CNT 15
<> 144:ef7eb2e8f9f7 322 void dcdcFetCntSet(bool lpModeSet)
<> 144:ef7eb2e8f9f7 323 {
<> 144:ef7eb2e8f9f7 324 uint32_t tmp;
<> 144:ef7eb2e8f9f7 325 static uint32_t emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 if (lpModeSet)
<> 144:ef7eb2e8f9f7 328 {
<> 144:ef7eb2e8f9f7 329 emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;
<> 144:ef7eb2e8f9f7 330 tmp = EMU->DCDCMISCCTRL
<> 144:ef7eb2e8f9f7 331 & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);
<> 144:ef7eb2e8f9f7 332 tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)
<> 144:ef7eb2e8f9f7 333 | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 334 EMU->DCDCMISCCTRL = tmp;
<> 144:ef7eb2e8f9f7 335 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337 else
<> 144:ef7eb2e8f9f7 338 {
<> 144:ef7eb2e8f9f7 339 EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;
<> 144:ef7eb2e8f9f7 340 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 341 }
<> 144:ef7eb2e8f9f7 342 }
<> 144:ef7eb2e8f9f7 343
<> 144:ef7eb2e8f9f7 344 void dcdcHsFixLnBlock(void)
<> 144:ef7eb2e8f9f7 345 {
<> 144:ef7eb2e8f9f7 346 #define EMU_DCDCSTATUS (* (volatile uint32_t *)(EMU_BASE + 0x7C))
<> 144:ef7eb2e8f9f7 347 if (errataFixDcdcHsState == errataFixDcdcHsTrimSet)
<> 144:ef7eb2e8f9f7 348 {
<> 144:ef7eb2e8f9f7 349 /* Wait for LNRUNNING */
<> 144:ef7eb2e8f9f7 350 if ((EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)
<> 144:ef7eb2e8f9f7 351 {
<> 144:ef7eb2e8f9f7 352 while (!(EMU_DCDCSTATUS & (0x1 << 16)));
<> 144:ef7eb2e8f9f7 353 }
<> 144:ef7eb2e8f9f7 354 errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;
<> 144:ef7eb2e8f9f7 355 }
<> 144:ef7eb2e8f9f7 356 }
<> 144:ef7eb2e8f9f7 357 #endif
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359
<> 144:ef7eb2e8f9f7 360 /** @endcond */
<> 144:ef7eb2e8f9f7 361
<> 144:ef7eb2e8f9f7 362
<> 144:ef7eb2e8f9f7 363 /*******************************************************************************
<> 144:ef7eb2e8f9f7 364 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 365 ******************************************************************************/
<> 144:ef7eb2e8f9f7 366
<> 144:ef7eb2e8f9f7 367 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 368 * @brief
<> 144:ef7eb2e8f9f7 369 * Enter energy mode 2 (EM2).
<> 144:ef7eb2e8f9f7 370 *
<> 144:ef7eb2e8f9f7 371 * @details
<> 144:ef7eb2e8f9f7 372 * When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
<> 144:ef7eb2e8f9f7 373 * and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
<> 144:ef7eb2e8f9f7 374 * EM0, HFRCO is re-enabled and the core will be clocked by the configured
<> 144:ef7eb2e8f9f7 375 * HFRCO band. This ensures a quick wakeup from EM2.
<> 144:ef7eb2e8f9f7 376 *
<> 144:ef7eb2e8f9f7 377 * However, prior to entering EM2, the core may have been using another
<> 144:ef7eb2e8f9f7 378 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 379 * to restore all HF oscillators according to state prior to entering EM2,
<> 144:ef7eb2e8f9f7 380 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 381 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 382 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 383 *
<> 144:ef7eb2e8f9f7 384 * @note
<> 144:ef7eb2e8f9f7 385 * If restoring core clock to use the HFXO oscillator, which has been
<> 144:ef7eb2e8f9f7 386 * disabled during EM2 mode, this function will stall until the oscillator
<> 144:ef7eb2e8f9f7 387 * has stabilized. Stalling time can be reduced by adding interrupt
<> 144:ef7eb2e8f9f7 388 * support detecting stable oscillator, and an asynchronous switch to the
<> 144:ef7eb2e8f9f7 389 * original oscillator. See CMU documentation. Such a feature is however
<> 144:ef7eb2e8f9f7 390 * outside the scope of the implementation in this function.
<> 144:ef7eb2e8f9f7 391 * @par
<> 144:ef7eb2e8f9f7 392 * If HFXO is re-enabled by this function, and NOT used to clock the core,
<> 144:ef7eb2e8f9f7 393 * this function will not wait for HFXO to stabilize. This must be considered
<> 144:ef7eb2e8f9f7 394 * by the application if trying to use features relying on that oscillator
<> 144:ef7eb2e8f9f7 395 * upon return.
<> 144:ef7eb2e8f9f7 396 * @par
<> 144:ef7eb2e8f9f7 397 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 398 * upon entering EM2. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 399 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 400 * @par
<> 144:ef7eb2e8f9f7 401 * If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
<> 144:ef7eb2e8f9f7 402 * the starting and selecting of the core clocks will be identical to the user
<> 144:ef7eb2e8f9f7 403 * independently of the value of the @p restore parameter when waking up on
<> 144:ef7eb2e8f9f7 404 * the wakeup sources corresponding to the autostart and select setting.
<> 144:ef7eb2e8f9f7 405 *
<> 144:ef7eb2e8f9f7 406 * @param[in] restore
<> 144:ef7eb2e8f9f7 407 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 408 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 409 * @par
<> 144:ef7eb2e8f9f7 410 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 411 * via the CMU API.
<> 144:ef7eb2e8f9f7 412 ******************************************************************************/
<> 144:ef7eb2e8f9f7 413 void EMU_EnterEM2(bool restore)
<> 144:ef7eb2e8f9f7 414 {
<> 144:ef7eb2e8f9f7 415 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 416 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 417 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 418 #endif
<> 144:ef7eb2e8f9f7 419
<> 144:ef7eb2e8f9f7 420 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 421 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 422 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 423 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 424 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 425 #endif
<> 144:ef7eb2e8f9f7 426
<> 144:ef7eb2e8f9f7 427 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 428 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 429
<> 144:ef7eb2e8f9f7 430 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 431 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 432 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 433 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 434 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 435 {
<> 144:ef7eb2e8f9f7 436 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 437 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 438 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 439 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 440 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 441 #endif
<> 144:ef7eb2e8f9f7 442 }
<> 144:ef7eb2e8f9f7 443 #endif
<> 144:ef7eb2e8f9f7 444
<> 144:ef7eb2e8f9f7 445 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 446 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 447 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 448 #endif
<> 144:ef7eb2e8f9f7 449
<> 144:ef7eb2e8f9f7 450 __WFI();
<> 144:ef7eb2e8f9f7 451
<> 144:ef7eb2e8f9f7 452 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 453 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 454 #endif
<> 144:ef7eb2e8f9f7 455
<> 144:ef7eb2e8f9f7 456 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 457 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 458 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 459 {
<> 144:ef7eb2e8f9f7 460 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 461 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 462 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 463 #endif
<> 144:ef7eb2e8f9f7 464 }
<> 144:ef7eb2e8f9f7 465 #endif
<> 144:ef7eb2e8f9f7 466
<> 144:ef7eb2e8f9f7 467 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 468 if (restore)
<> 144:ef7eb2e8f9f7 469 {
<> 144:ef7eb2e8f9f7 470 emuRestore();
<> 144:ef7eb2e8f9f7 471 }
<> 144:ef7eb2e8f9f7 472 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 473 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 474 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 475 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 476 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 477 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 478 #else
<> 144:ef7eb2e8f9f7 479 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 480 #endif
<> 144:ef7eb2e8f9f7 481 {
<> 144:ef7eb2e8f9f7 482 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 483 }
<> 144:ef7eb2e8f9f7 484 }
<> 144:ef7eb2e8f9f7 485
<> 144:ef7eb2e8f9f7 486
<> 144:ef7eb2e8f9f7 487 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 488 * @brief
<> 144:ef7eb2e8f9f7 489 * Enter energy mode 3 (EM3).
<> 144:ef7eb2e8f9f7 490 *
<> 144:ef7eb2e8f9f7 491 * @details
<> 144:ef7eb2e8f9f7 492 * When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
<> 144:ef7eb2e8f9f7 493 * HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
<> 144:ef7eb2e8f9f7 494 * the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
<> 144:ef7eb2e8f9f7 495 * re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
<> 144:ef7eb2e8f9f7 496 * configured HFRCO band. This ensures a quick wakeup from EM3.
<> 144:ef7eb2e8f9f7 497 *
<> 144:ef7eb2e8f9f7 498 * However, prior to entering EM3, the core may have been using another
<> 144:ef7eb2e8f9f7 499 * oscillator than HFRCO. The @p restore parameter gives the user the option
<> 144:ef7eb2e8f9f7 500 * to restore all HF/LF oscillators according to state prior to entering EM3,
<> 144:ef7eb2e8f9f7 501 * as well as the clock used to clock the core. This restore procedure is
<> 144:ef7eb2e8f9f7 502 * handled by SW. However, since handled by SW, it will not be restored
<> 144:ef7eb2e8f9f7 503 * before completing the interrupt function(s) waking up the core!
<> 144:ef7eb2e8f9f7 504 *
<> 144:ef7eb2e8f9f7 505 * @note
<> 144:ef7eb2e8f9f7 506 * If restoring core clock to use an oscillator other than HFRCO, this
<> 144:ef7eb2e8f9f7 507 * function will stall until the oscillator has stabilized. Stalling time
<> 144:ef7eb2e8f9f7 508 * can be reduced by adding interrupt support detecting stable oscillator,
<> 144:ef7eb2e8f9f7 509 * and an asynchronous switch to the original oscillator. See CMU
<> 144:ef7eb2e8f9f7 510 * documentation. Such a feature is however outside the scope of the
<> 144:ef7eb2e8f9f7 511 * implementation in this function.
<> 144:ef7eb2e8f9f7 512 * @par
<> 144:ef7eb2e8f9f7 513 * If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
<> 144:ef7eb2e8f9f7 514 * the core, this function will not wait for those oscillators to stabilize.
<> 144:ef7eb2e8f9f7 515 * This must be considered by the application if trying to use features
<> 144:ef7eb2e8f9f7 516 * relying on those oscillators upon return.
<> 144:ef7eb2e8f9f7 517 * @par
<> 144:ef7eb2e8f9f7 518 * If a debugger is attached, the AUXHFRCO will not be disabled if enabled
<> 144:ef7eb2e8f9f7 519 * upon entering EM3. It will thus remain enabled when returning to EM0
<> 144:ef7eb2e8f9f7 520 * regardless of the @p restore parameter.
<> 144:ef7eb2e8f9f7 521 *
<> 144:ef7eb2e8f9f7 522 * @param[in] restore
<> 144:ef7eb2e8f9f7 523 * @li true - restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 524 * @li false - do not restore oscillators and clocks, see function details.
<> 144:ef7eb2e8f9f7 525 * @par
<> 144:ef7eb2e8f9f7 526 * The @p restore option should only be used if all clock control is done
<> 144:ef7eb2e8f9f7 527 * via the CMU API.
<> 144:ef7eb2e8f9f7 528 ******************************************************************************/
<> 144:ef7eb2e8f9f7 529 void EMU_EnterEM3(bool restore)
<> 144:ef7eb2e8f9f7 530 {
<> 144:ef7eb2e8f9f7 531 uint32_t cmuLocked;
<> 144:ef7eb2e8f9f7 532
<> 144:ef7eb2e8f9f7 533 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 534 bool errataFixEmuE107En;
<> 144:ef7eb2e8f9f7 535 uint32_t nonWicIntEn[2];
<> 144:ef7eb2e8f9f7 536 #endif
<> 144:ef7eb2e8f9f7 537
<> 144:ef7eb2e8f9f7 538 /* Auto-update CMU status just in case before entering energy mode. */
<> 144:ef7eb2e8f9f7 539 /* This variable is normally kept up-to-date by the CMU API. */
<> 144:ef7eb2e8f9f7 540 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 541 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 542 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 543 #endif
<> 144:ef7eb2e8f9f7 544
<> 144:ef7eb2e8f9f7 545 /* CMU registers may be locked */
<> 144:ef7eb2e8f9f7 546 cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
<> 144:ef7eb2e8f9f7 547 CMU_Unlock();
<> 144:ef7eb2e8f9f7 548
<> 144:ef7eb2e8f9f7 549 /* Disable LF oscillators */
<> 144:ef7eb2e8f9f7 550 CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
<> 144:ef7eb2e8f9f7 551
<> 144:ef7eb2e8f9f7 552 /* Restore CMU register locking */
<> 144:ef7eb2e8f9f7 553 if (cmuLocked)
<> 144:ef7eb2e8f9f7 554 {
<> 144:ef7eb2e8f9f7 555 CMU_Lock();
<> 144:ef7eb2e8f9f7 556 }
<> 144:ef7eb2e8f9f7 557
<> 144:ef7eb2e8f9f7 558 /* Enter Cortex deep sleep mode */
<> 144:ef7eb2e8f9f7 559 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
<> 144:ef7eb2e8f9f7 560
<> 144:ef7eb2e8f9f7 561 /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
<> 144:ef7eb2e8f9f7 562 Disable the enabled non-WIC interrupts. */
<> 144:ef7eb2e8f9f7 563 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 564 errataFixEmuE107En = getErrataFixEmuE107En();
<> 144:ef7eb2e8f9f7 565 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 566 {
<> 144:ef7eb2e8f9f7 567 nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
<> 144:ef7eb2e8f9f7 568 NVIC->ICER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 569 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 570 nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
<> 144:ef7eb2e8f9f7 571 NVIC->ICER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 572 #endif
<> 144:ef7eb2e8f9f7 573
<> 144:ef7eb2e8f9f7 574 }
<> 144:ef7eb2e8f9f7 575 #endif
<> 144:ef7eb2e8f9f7 576
<> 144:ef7eb2e8f9f7 577 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 578 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 579 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 580 #endif
<> 144:ef7eb2e8f9f7 581
<> 144:ef7eb2e8f9f7 582 __WFI();
<> 144:ef7eb2e8f9f7 583
<> 144:ef7eb2e8f9f7 584 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 585 dcdcFetCntSet(false);
<> 144:ef7eb2e8f9f7 586 #endif
<> 144:ef7eb2e8f9f7 587
<> 144:ef7eb2e8f9f7 588 /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
<> 144:ef7eb2e8f9f7 589 #if defined( ERRATA_FIX_EMU_E107_EN )
<> 144:ef7eb2e8f9f7 590 if (errataFixEmuE107En)
<> 144:ef7eb2e8f9f7 591 {
<> 144:ef7eb2e8f9f7 592 NVIC->ISER[0] = nonWicIntEn[0];
<> 144:ef7eb2e8f9f7 593 #if (NON_WIC_INT_MASK_1 != (~(0x0U)))
<> 144:ef7eb2e8f9f7 594 NVIC->ISER[1] = nonWicIntEn[1];
<> 144:ef7eb2e8f9f7 595 #endif
<> 144:ef7eb2e8f9f7 596 }
<> 144:ef7eb2e8f9f7 597 #endif
<> 144:ef7eb2e8f9f7 598
<> 144:ef7eb2e8f9f7 599 /* Restore oscillators/clocks if specified */
<> 144:ef7eb2e8f9f7 600 if (restore)
<> 144:ef7eb2e8f9f7 601 {
<> 144:ef7eb2e8f9f7 602 emuRestore();
<> 144:ef7eb2e8f9f7 603 }
<> 144:ef7eb2e8f9f7 604 /* If not restoring, and original clock was not HFRCO, we have to */
<> 144:ef7eb2e8f9f7 605 /* update CMSIS core clock variable since core clock has changed */
<> 144:ef7eb2e8f9f7 606 /* to using HFRCO. */
<> 144:ef7eb2e8f9f7 607 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 608 else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)
<> 144:ef7eb2e8f9f7 609 != CMU_HFCLKSTATUS_SELECTED_HFRCO)
<> 144:ef7eb2e8f9f7 610 #else
<> 144:ef7eb2e8f9f7 611 else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
<> 144:ef7eb2e8f9f7 612 #endif
<> 144:ef7eb2e8f9f7 613 {
<> 144:ef7eb2e8f9f7 614 SystemCoreClockUpdate();
<> 144:ef7eb2e8f9f7 615 }
<> 144:ef7eb2e8f9f7 616 }
<> 144:ef7eb2e8f9f7 617
<> 144:ef7eb2e8f9f7 618
<> 144:ef7eb2e8f9f7 619 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 620 * @brief
<> 144:ef7eb2e8f9f7 621 * Enter energy mode 4 (EM4).
<> 144:ef7eb2e8f9f7 622 *
<> 144:ef7eb2e8f9f7 623 * @note
<> 144:ef7eb2e8f9f7 624 * Only a power on reset or external reset pin can wake the device from EM4.
<> 144:ef7eb2e8f9f7 625 ******************************************************************************/
<> 144:ef7eb2e8f9f7 626 void EMU_EnterEM4(void)
<> 144:ef7eb2e8f9f7 627 {
<> 144:ef7eb2e8f9f7 628 int i;
<> 144:ef7eb2e8f9f7 629
<> 144:ef7eb2e8f9f7 630 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 631 uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 632 | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 633 uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)
<> 144:ef7eb2e8f9f7 634 | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);
<> 144:ef7eb2e8f9f7 635 #else
<> 144:ef7eb2e8f9f7 636 uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 637 | (2 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 638 uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)
<> 144:ef7eb2e8f9f7 639 | (3 << _EMU_CTRL_EM4CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 640 #endif
<> 144:ef7eb2e8f9f7 641
<> 144:ef7eb2e8f9f7 642 /* Make sure register write lock is disabled */
<> 144:ef7eb2e8f9f7 643 EMU_Unlock();
<> 144:ef7eb2e8f9f7 644
<> 144:ef7eb2e8f9f7 645 #if defined( ERRATA_FIX_EMU_E108_EN )
<> 144:ef7eb2e8f9f7 646 /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */
<> 144:ef7eb2e8f9f7 647 __disable_irq();
<> 144:ef7eb2e8f9f7 648 *(volatile uint32_t *)0x400C80E4 = 0;
<> 144:ef7eb2e8f9f7 649 #endif
<> 144:ef7eb2e8f9f7 650
<> 144:ef7eb2e8f9f7 651 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 652 dcdcFetCntSet(true);
<> 144:ef7eb2e8f9f7 653 dcdcHsFixLnBlock();
<> 144:ef7eb2e8f9f7 654 #endif
<> 144:ef7eb2e8f9f7 655
<> 144:ef7eb2e8f9f7 656 for (i = 0; i < 4; i++)
<> 144:ef7eb2e8f9f7 657 {
<> 144:ef7eb2e8f9f7 658 #if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )
<> 144:ef7eb2e8f9f7 659 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 660 EMU->EM4CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 EMU->EM4CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 663 #else
<> 144:ef7eb2e8f9f7 664 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 665 EMU->CTRL = em4seq3;
<> 144:ef7eb2e8f9f7 666 }
<> 144:ef7eb2e8f9f7 667 EMU->CTRL = em4seq2;
<> 144:ef7eb2e8f9f7 668 #endif
<> 144:ef7eb2e8f9f7 669 }
<> 144:ef7eb2e8f9f7 670
<> 144:ef7eb2e8f9f7 671
<> 144:ef7eb2e8f9f7 672 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 673 * @brief
<> 144:ef7eb2e8f9f7 674 * Power down memory block.
<> 144:ef7eb2e8f9f7 675 *
<> 144:ef7eb2e8f9f7 676 * @param[in] blocks
<> 144:ef7eb2e8f9f7 677 * Specifies a logical OR of bits indicating memory blocks to power down.
<> 144:ef7eb2e8f9f7 678 * Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
<> 144:ef7eb2e8f9f7 679 * be disabled. Please refer to the reference manual for available
<> 144:ef7eb2e8f9f7 680 * memory blocks for a device.
<> 144:ef7eb2e8f9f7 681 *
<> 144:ef7eb2e8f9f7 682 * @note
<> 144:ef7eb2e8f9f7 683 * Only a reset can make the specified memory block(s) available for use
<> 144:ef7eb2e8f9f7 684 * after having been powered down. Function will be void for devices not
<> 144:ef7eb2e8f9f7 685 * supporting this feature.
<> 144:ef7eb2e8f9f7 686 ******************************************************************************/
<> 144:ef7eb2e8f9f7 687 void EMU_MemPwrDown(uint32_t blocks)
<> 144:ef7eb2e8f9f7 688 {
<> 144:ef7eb2e8f9f7 689 #if defined( _EMU_MEMCTRL_POWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 690 EFM_ASSERT(blocks <= (_EMU_MEMCTRL_POWERDOWN_MASK
<> 144:ef7eb2e8f9f7 691 >> _EMU_MEMCTRL_POWERDOWN_SHIFT));
<> 144:ef7eb2e8f9f7 692 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 693
<> 144:ef7eb2e8f9f7 694 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 695 && defined( _EMU_MEMCTRL_RAMHPOWERDOWN_MASK ) \
<> 144:ef7eb2e8f9f7 696 && defined( _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 697 EFM_ASSERT((blocks & (_EMU_MEMCTRL_RAMPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 698 | _EMU_MEMCTRL_RAMHPOWERDOWN_MASK
<> 144:ef7eb2e8f9f7 699 | _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK))
<> 144:ef7eb2e8f9f7 700 == blocks);
<> 144:ef7eb2e8f9f7 701 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 702
<> 144:ef7eb2e8f9f7 703 #elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 704 EFM_ASSERT((blocks & _EMU_MEMCTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 705 EMU->MEMCTRL = blocks;
<> 144:ef7eb2e8f9f7 706
<> 144:ef7eb2e8f9f7 707 #elif defined( _EMU_RAM0CTRL_RAMPOWERDOWN_MASK )
<> 144:ef7eb2e8f9f7 708 EFM_ASSERT((blocks & _EMU_RAM0CTRL_RAMPOWERDOWN_MASK) == blocks);
<> 144:ef7eb2e8f9f7 709 EMU->RAM0CTRL = blocks;
<> 144:ef7eb2e8f9f7 710
<> 144:ef7eb2e8f9f7 711 #else
<> 144:ef7eb2e8f9f7 712 (void)blocks;
<> 144:ef7eb2e8f9f7 713 #endif
<> 144:ef7eb2e8f9f7 714 }
<> 144:ef7eb2e8f9f7 715
<> 144:ef7eb2e8f9f7 716
<> 144:ef7eb2e8f9f7 717 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 718 * @brief
<> 144:ef7eb2e8f9f7 719 * Update EMU module with CMU oscillator selection/enable status.
<> 144:ef7eb2e8f9f7 720 *
<> 144:ef7eb2e8f9f7 721 * @details
<> 144:ef7eb2e8f9f7 722 * When entering EM2 and EM3, the HW may change the core clock oscillator
<> 144:ef7eb2e8f9f7 723 * used, as well as disabling some oscillators. The user may optionally select
<> 144:ef7eb2e8f9f7 724 * to restore the oscillators after waking up from EM2 and EM3 through the
<> 144:ef7eb2e8f9f7 725 * SW API.
<> 144:ef7eb2e8f9f7 726 *
<> 144:ef7eb2e8f9f7 727 * However, in order to support this in a safe way, the EMU module must
<> 144:ef7eb2e8f9f7 728 * be kept up-to-date on the actual selected configuration. The CMU
<> 144:ef7eb2e8f9f7 729 * module must keep the EMU module up-to-date.
<> 144:ef7eb2e8f9f7 730 *
<> 144:ef7eb2e8f9f7 731 * This function is mainly intended for internal use by the CMU module,
<> 144:ef7eb2e8f9f7 732 * but if the applications changes oscillator configurations without
<> 144:ef7eb2e8f9f7 733 * using the CMU API, this function can be used to keep the EMU module
<> 144:ef7eb2e8f9f7 734 * up-to-date.
<> 144:ef7eb2e8f9f7 735 ******************************************************************************/
<> 144:ef7eb2e8f9f7 736 void EMU_UpdateOscConfig(void)
<> 144:ef7eb2e8f9f7 737 {
<> 144:ef7eb2e8f9f7 738 /* Fetch current configuration */
<> 144:ef7eb2e8f9f7 739 cmuStatus = CMU->STATUS;
<> 144:ef7eb2e8f9f7 740 #if defined( _CMU_HFCLKSTATUS_RESETVALUE )
<> 144:ef7eb2e8f9f7 741 cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);
<> 144:ef7eb2e8f9f7 742 #endif
<> 144:ef7eb2e8f9f7 743 }
<> 144:ef7eb2e8f9f7 744
<> 144:ef7eb2e8f9f7 745
<> 144:ef7eb2e8f9f7 746 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 747 * @brief
<> 144:ef7eb2e8f9f7 748 * Update EMU module with Energy Mode 2 and 3 configuration
<> 144:ef7eb2e8f9f7 749 *
<> 144:ef7eb2e8f9f7 750 * @param[in] em23Init
<> 144:ef7eb2e8f9f7 751 * Energy Mode 2 and 3 configuration structure
<> 144:ef7eb2e8f9f7 752 ******************************************************************************/
<> 144:ef7eb2e8f9f7 753 void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)
<> 144:ef7eb2e8f9f7 754 {
<> 144:ef7eb2e8f9f7 755 #if defined( _EMU_CTRL_EMVREG_MASK )
<> 144:ef7eb2e8f9f7 756 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)
<> 144:ef7eb2e8f9f7 757 : (EMU->CTRL & ~EMU_CTRL_EMVREG);
<> 144:ef7eb2e8f9f7 758 #elif defined( _EMU_CTRL_EM23VREG_MASK )
<> 144:ef7eb2e8f9f7 759 EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)
<> 144:ef7eb2e8f9f7 760 : (EMU->CTRL & ~EMU_CTRL_EM23VREG);
<> 144:ef7eb2e8f9f7 761 #else
<> 144:ef7eb2e8f9f7 762 (void)em23Init;
<> 144:ef7eb2e8f9f7 763 #endif
<> 144:ef7eb2e8f9f7 764 }
<> 144:ef7eb2e8f9f7 765
<> 144:ef7eb2e8f9f7 766
<> 144:ef7eb2e8f9f7 767 #if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 768 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 769 * @brief
<> 144:ef7eb2e8f9f7 770 * Update EMU module with Energy Mode 4 configuration
<> 144:ef7eb2e8f9f7 771 *
<> 144:ef7eb2e8f9f7 772 * @param[in] em4Init
<> 144:ef7eb2e8f9f7 773 * Energy Mode 4 configuration structure
<> 144:ef7eb2e8f9f7 774 ******************************************************************************/
<> 144:ef7eb2e8f9f7 775 void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)
<> 144:ef7eb2e8f9f7 776 {
<> 144:ef7eb2e8f9f7 777 #if defined( _EMU_EM4CONF_MASK )
<> 144:ef7eb2e8f9f7 778 /* Init for platforms with EMU->EM4CONF register */
<> 144:ef7eb2e8f9f7 779 uint32_t em4conf = EMU->EM4CONF;
<> 144:ef7eb2e8f9f7 780
<> 144:ef7eb2e8f9f7 781 /* Clear fields that will be reconfigured */
<> 144:ef7eb2e8f9f7 782 em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK
<> 144:ef7eb2e8f9f7 783 | _EMU_EM4CONF_OSC_MASK
<> 144:ef7eb2e8f9f7 784 | _EMU_EM4CONF_BURTCWU_MASK
<> 144:ef7eb2e8f9f7 785 | _EMU_EM4CONF_VREGEN_MASK);
<> 144:ef7eb2e8f9f7 786
<> 144:ef7eb2e8f9f7 787 /* Configure new settings */
<> 144:ef7eb2e8f9f7 788 em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)
<> 144:ef7eb2e8f9f7 789 | (em4Init->osc)
<> 144:ef7eb2e8f9f7 790 | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)
<> 144:ef7eb2e8f9f7 791 | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);
<> 144:ef7eb2e8f9f7 792
<> 144:ef7eb2e8f9f7 793 /* Apply configuration. Note that lock can be set after this stage. */
<> 144:ef7eb2e8f9f7 794 EMU->EM4CONF = em4conf;
<> 144:ef7eb2e8f9f7 795
<> 144:ef7eb2e8f9f7 796 #elif defined( _EMU_EM4CTRL_MASK )
<> 144:ef7eb2e8f9f7 797 /* Init for platforms with EMU->EM4CTRL register */
<> 144:ef7eb2e8f9f7 798
<> 144:ef7eb2e8f9f7 799 uint32_t em4ctrl = EMU->EM4CTRL;
<> 144:ef7eb2e8f9f7 800
<> 144:ef7eb2e8f9f7 801 em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK
<> 144:ef7eb2e8f9f7 802 | _EMU_EM4CTRL_RETAINLFRCO_MASK
<> 144:ef7eb2e8f9f7 803 | _EMU_EM4CTRL_RETAINULFRCO_MASK
<> 144:ef7eb2e8f9f7 804 | _EMU_EM4CTRL_EM4STATE_MASK
<> 144:ef7eb2e8f9f7 805 | _EMU_EM4CTRL_EM4IORETMODE_MASK);
<> 144:ef7eb2e8f9f7 806
<> 144:ef7eb2e8f9f7 807 em4ctrl |= (em4Init->retainLfxo ? EMU_EM4CTRL_RETAINLFXO : 0)
<> 144:ef7eb2e8f9f7 808 | (em4Init->retainLfrco ? EMU_EM4CTRL_RETAINLFRCO : 0)
<> 144:ef7eb2e8f9f7 809 | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)
<> 144:ef7eb2e8f9f7 810 | (em4Init->em4State ? EMU_EM4CTRL_EM4STATE_EM4H : 0)
<> 144:ef7eb2e8f9f7 811 | (em4Init->pinRetentionMode);
<> 144:ef7eb2e8f9f7 812
<> 144:ef7eb2e8f9f7 813 EMU->EM4CTRL = em4ctrl;
<> 144:ef7eb2e8f9f7 814 #endif
<> 144:ef7eb2e8f9f7 815 }
<> 144:ef7eb2e8f9f7 816 #endif
<> 144:ef7eb2e8f9f7 817
<> 144:ef7eb2e8f9f7 818
<> 144:ef7eb2e8f9f7 819 #if defined( BU_PRESENT )
<> 144:ef7eb2e8f9f7 820 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 821 * @brief
<> 144:ef7eb2e8f9f7 822 * Configure Backup Power Domain settings
<> 144:ef7eb2e8f9f7 823 *
<> 144:ef7eb2e8f9f7 824 * @param[in] bupdInit
<> 144:ef7eb2e8f9f7 825 * Backup power domain initialization structure
<> 144:ef7eb2e8f9f7 826 ******************************************************************************/
<> 144:ef7eb2e8f9f7 827 void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
<> 144:ef7eb2e8f9f7 828 {
<> 144:ef7eb2e8f9f7 829 uint32_t reg;
<> 144:ef7eb2e8f9f7 830
<> 144:ef7eb2e8f9f7 831 /* Set power connection configuration */
<> 144:ef7eb2e8f9f7 832 reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK
<> 144:ef7eb2e8f9f7 833 | _EMU_PWRCONF_VOUTSTRONG_MASK
<> 144:ef7eb2e8f9f7 834 | _EMU_PWRCONF_VOUTMED_MASK
<> 144:ef7eb2e8f9f7 835 | _EMU_PWRCONF_VOUTWEAK_MASK);
<> 144:ef7eb2e8f9f7 836
<> 144:ef7eb2e8f9f7 837 reg |= bupdInit->resistor
<> 144:ef7eb2e8f9f7 838 | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)
<> 144:ef7eb2e8f9f7 839 | (bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)
<> 144:ef7eb2e8f9f7 840 | (bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT);
<> 144:ef7eb2e8f9f7 841
<> 144:ef7eb2e8f9f7 842 EMU->PWRCONF = reg;
<> 144:ef7eb2e8f9f7 843
<> 144:ef7eb2e8f9f7 844 /* Set backup domain inactive mode configuration */
<> 144:ef7eb2e8f9f7 845 reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 846 reg |= (bupdInit->inactivePower);
<> 144:ef7eb2e8f9f7 847 EMU->BUINACT = reg;
<> 144:ef7eb2e8f9f7 848
<> 144:ef7eb2e8f9f7 849 /* Set backup domain active mode configuration */
<> 144:ef7eb2e8f9f7 850 reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
<> 144:ef7eb2e8f9f7 851 reg |= (bupdInit->activePower);
<> 144:ef7eb2e8f9f7 852 EMU->BUACT = reg;
<> 144:ef7eb2e8f9f7 853
<> 144:ef7eb2e8f9f7 854 /* Set power control configuration */
<> 144:ef7eb2e8f9f7 855 reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK
<> 144:ef7eb2e8f9f7 856 | _EMU_BUCTRL_BODCAL_MASK
<> 144:ef7eb2e8f9f7 857 | _EMU_BUCTRL_STATEN_MASK
<> 144:ef7eb2e8f9f7 858 | _EMU_BUCTRL_EN_MASK);
<> 144:ef7eb2e8f9f7 859
<> 144:ef7eb2e8f9f7 860 /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
<> 144:ef7eb2e8f9f7 861 release reset */
<> 144:ef7eb2e8f9f7 862 reg |= bupdInit->probe
<> 144:ef7eb2e8f9f7 863 | (bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)
<> 144:ef7eb2e8f9f7 864 | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)
<> 144:ef7eb2e8f9f7 865 | (bupdInit->enable << _EMU_BUCTRL_EN_SHIFT);
<> 144:ef7eb2e8f9f7 866
<> 144:ef7eb2e8f9f7 867 /* Enable configuration */
<> 144:ef7eb2e8f9f7 868 EMU->BUCTRL = reg;
<> 144:ef7eb2e8f9f7 869
<> 144:ef7eb2e8f9f7 870 /* If enable is true, enable BU_VIN input power pin, if not disable it */
<> 144:ef7eb2e8f9f7 871 EMU_BUPinEnable(bupdInit->enable);
<> 144:ef7eb2e8f9f7 872
<> 144:ef7eb2e8f9f7 873 /* If enable is true, release BU reset, if not keep reset asserted */
<> 144:ef7eb2e8f9f7 874 BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
<> 144:ef7eb2e8f9f7 875 }
<> 144:ef7eb2e8f9f7 876
<> 144:ef7eb2e8f9f7 877
<> 144:ef7eb2e8f9f7 878 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 879 * @brief
<> 144:ef7eb2e8f9f7 880 * Configure Backup Power Domain BOD Threshold value
<> 144:ef7eb2e8f9f7 881 * @note
<> 144:ef7eb2e8f9f7 882 * These values are precalibrated
<> 144:ef7eb2e8f9f7 883 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 884 * @param[in] value
<> 144:ef7eb2e8f9f7 885 ******************************************************************************/
<> 144:ef7eb2e8f9f7 886 void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 887 {
<> 144:ef7eb2e8f9f7 888 EFM_ASSERT(value<8);
<> 144:ef7eb2e8f9f7 889 EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
<> 144:ef7eb2e8f9f7 890
<> 144:ef7eb2e8f9f7 891 switch(mode)
<> 144:ef7eb2e8f9f7 892 {
<> 144:ef7eb2e8f9f7 893 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 894 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)
<> 144:ef7eb2e8f9f7 895 | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 896 break;
<> 144:ef7eb2e8f9f7 897 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 898 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)
<> 144:ef7eb2e8f9f7 899 | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);
<> 144:ef7eb2e8f9f7 900 break;
<> 144:ef7eb2e8f9f7 901 }
<> 144:ef7eb2e8f9f7 902 }
<> 144:ef7eb2e8f9f7 903
<> 144:ef7eb2e8f9f7 904
<> 144:ef7eb2e8f9f7 905 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 906 * @brief
<> 144:ef7eb2e8f9f7 907 * Configure Backup Power Domain BOD Threshold Range
<> 144:ef7eb2e8f9f7 908 * @note
<> 144:ef7eb2e8f9f7 909 * These values are precalibrated
<> 144:ef7eb2e8f9f7 910 * @param[in] mode Active or Inactive mode
<> 144:ef7eb2e8f9f7 911 * @param[in] value
<> 144:ef7eb2e8f9f7 912 ******************************************************************************/
<> 144:ef7eb2e8f9f7 913 void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
<> 144:ef7eb2e8f9f7 914 {
<> 144:ef7eb2e8f9f7 915 EFM_ASSERT(value < 4);
<> 144:ef7eb2e8f9f7 916 EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
<> 144:ef7eb2e8f9f7 917
<> 144:ef7eb2e8f9f7 918 switch(mode)
<> 144:ef7eb2e8f9f7 919 {
<> 144:ef7eb2e8f9f7 920 case emuBODMode_Active:
<> 144:ef7eb2e8f9f7 921 EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)
<> 144:ef7eb2e8f9f7 922 | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 923 break;
<> 144:ef7eb2e8f9f7 924 case emuBODMode_Inactive:
<> 144:ef7eb2e8f9f7 925 EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)
<> 144:ef7eb2e8f9f7 926 | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);
<> 144:ef7eb2e8f9f7 927 break;
<> 144:ef7eb2e8f9f7 928 }
<> 144:ef7eb2e8f9f7 929 }
<> 144:ef7eb2e8f9f7 930 #endif
<> 144:ef7eb2e8f9f7 931
<> 144:ef7eb2e8f9f7 932
<> 144:ef7eb2e8f9f7 933 #if defined( _EMU_DCDCCTRL_MASK )
<> 144:ef7eb2e8f9f7 934
<> 144:ef7eb2e8f9f7 935 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 936
<> 144:ef7eb2e8f9f7 937 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 938 * @brief
<> 144:ef7eb2e8f9f7 939 * Load DCDC calibration constants from DI page. Const means calibration
<> 144:ef7eb2e8f9f7 940 * data that does not change depending on other configuration parameters.
<> 144:ef7eb2e8f9f7 941 *
<> 144:ef7eb2e8f9f7 942 * @return
<> 144:ef7eb2e8f9f7 943 * False if calibration registers are locked
<> 144:ef7eb2e8f9f7 944 ******************************************************************************/
<> 144:ef7eb2e8f9f7 945 static bool ConstCalibrationLoad(void)
<> 144:ef7eb2e8f9f7 946 {
<> 144:ef7eb2e8f9f7 947 uint32_t val;
<> 144:ef7eb2e8f9f7 948 volatile uint32_t *reg;
<> 144:ef7eb2e8f9f7 949
<> 144:ef7eb2e8f9f7 950 /* DI calib data in flash */
<> 144:ef7eb2e8f9f7 951 volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL = (volatile uint32_t *)(0x0FE08038);
<> 144:ef7eb2e8f9f7 952 volatile uint32_t* const diCal_EMU_DCDCLNVCTRL = (volatile uint32_t *)(0x0FE08040);
<> 144:ef7eb2e8f9f7 953 volatile uint32_t* const diCal_EMU_DCDCLPCTRL = (volatile uint32_t *)(0x0FE08048);
<> 144:ef7eb2e8f9f7 954 volatile uint32_t* const diCal_EMU_DCDCLPVCTRL = (volatile uint32_t *)(0x0FE08050);
<> 144:ef7eb2e8f9f7 955 volatile uint32_t* const diCal_EMU_DCDCTRIM0 = (volatile uint32_t *)(0x0FE08058);
<> 144:ef7eb2e8f9f7 956 volatile uint32_t* const diCal_EMU_DCDCTRIM1 = (volatile uint32_t *)(0x0FE08060);
<> 144:ef7eb2e8f9f7 957
<> 144:ef7eb2e8f9f7 958 if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)
<> 144:ef7eb2e8f9f7 959 {
<> 144:ef7eb2e8f9f7 960 val = *(diCal_EMU_DCDCLNFREQCTRL + 1);
<> 144:ef7eb2e8f9f7 961 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;
<> 144:ef7eb2e8f9f7 962 *reg = val;
<> 144:ef7eb2e8f9f7 963
<> 144:ef7eb2e8f9f7 964 val = *(diCal_EMU_DCDCLNVCTRL + 1);
<> 144:ef7eb2e8f9f7 965 reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;
<> 144:ef7eb2e8f9f7 966 *reg = val;
<> 144:ef7eb2e8f9f7 967
<> 144:ef7eb2e8f9f7 968 val = *(diCal_EMU_DCDCLPCTRL + 1);
<> 144:ef7eb2e8f9f7 969 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;
<> 144:ef7eb2e8f9f7 970 *reg = val;
<> 144:ef7eb2e8f9f7 971
<> 144:ef7eb2e8f9f7 972 val = *(diCal_EMU_DCDCLPVCTRL + 1);
<> 144:ef7eb2e8f9f7 973 reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;
<> 144:ef7eb2e8f9f7 974 *reg = val;
<> 144:ef7eb2e8f9f7 975
<> 144:ef7eb2e8f9f7 976 val = *(diCal_EMU_DCDCTRIM0 + 1);
<> 144:ef7eb2e8f9f7 977 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;
<> 144:ef7eb2e8f9f7 978 *reg = val;
<> 144:ef7eb2e8f9f7 979
<> 144:ef7eb2e8f9f7 980 val = *(diCal_EMU_DCDCTRIM1 + 1);
<> 144:ef7eb2e8f9f7 981 reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;
<> 144:ef7eb2e8f9f7 982 *reg = val;
<> 144:ef7eb2e8f9f7 983
<> 144:ef7eb2e8f9f7 984 return true;
<> 144:ef7eb2e8f9f7 985 }
<> 144:ef7eb2e8f9f7 986 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 987 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 988 return false;
<> 144:ef7eb2e8f9f7 989 }
<> 144:ef7eb2e8f9f7 990
<> 144:ef7eb2e8f9f7 991
<> 144:ef7eb2e8f9f7 992 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 993 * @brief
<> 144:ef7eb2e8f9f7 994 * Set recommended and validated current optimization settings
<> 144:ef7eb2e8f9f7 995 *
<> 144:ef7eb2e8f9f7 996 ******************************************************************************/
<> 144:ef7eb2e8f9f7 997 void ValidatedConfigSet(void)
<> 144:ef7eb2e8f9f7 998 {
<> 144:ef7eb2e8f9f7 999 #define EMU_DCDCSMCTRL (* (volatile uint32_t *)(EMU_BASE + 0x44))
<> 144:ef7eb2e8f9f7 1000
<> 144:ef7eb2e8f9f7 1001 uint32_t dcdcTiming;
<> 144:ef7eb2e8f9f7 1002 SYSTEM_PartFamily_TypeDef family;
<> 144:ef7eb2e8f9f7 1003 SYSTEM_ChipRevision_TypeDef rev;
<> 144:ef7eb2e8f9f7 1004
<> 144:ef7eb2e8f9f7 1005 /* Enable duty cycling of the bias */
<> 144:ef7eb2e8f9f7 1006 EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;
<> 144:ef7eb2e8f9f7 1007
<> 144:ef7eb2e8f9f7 1008 /* Set low-noise RCO for EFM32 and EFR32 */
<> 144:ef7eb2e8f9f7 1009 #if defined( _EFR_DEVICE )
<> 144:ef7eb2e8f9f7 1010 /* 7MHz is recommended for all EFR32 parts with DCDC */
<> 144:ef7eb2e8f9f7 1011 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1012 | (EMU_DcdcLnRcoBand_7MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1013 #else
<> 144:ef7eb2e8f9f7 1014 /* 3MHz is recommended for all EFM32 parts with DCDC */
<> 144:ef7eb2e8f9f7 1015 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1016 | (EMU_DcdcLnRcoBand_3MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1017 #endif
<> 144:ef7eb2e8f9f7 1018
<> 144:ef7eb2e8f9f7 1019 EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;
<> 144:ef7eb2e8f9f7 1020
<> 144:ef7eb2e8f9f7 1021 family = SYSTEM_GetFamily();
<> 144:ef7eb2e8f9f7 1022 SYSTEM_ChipRevisionGet(&rev);
<> 144:ef7eb2e8f9f7 1023 if ((((family >= systemPartFamilyMighty1P)
<> 144:ef7eb2e8f9f7 1024 && (family <= systemPartFamilyFlex1V))
<> 144:ef7eb2e8f9f7 1025 || (family == systemPartFamilyEfm32Pearl1B)
<> 144:ef7eb2e8f9f7 1026 || (family == systemPartFamilyEfm32Jade1B))
<> 144:ef7eb2e8f9f7 1027 && ((rev.major == 1) && (rev.minor < 3))
<> 144:ef7eb2e8f9f7 1028 && (errataFixDcdcHsState == errataFixDcdcHsInit))
<> 144:ef7eb2e8f9f7 1029 {
<> 144:ef7eb2e8f9f7 1030 /* LPCMPWAITDIS = 1 */
<> 144:ef7eb2e8f9f7 1031 EMU_DCDCSMCTRL |= 1;
<> 144:ef7eb2e8f9f7 1032
<> 144:ef7eb2e8f9f7 1033 dcdcTiming = EMU->DCDCTIMING;
<> 144:ef7eb2e8f9f7 1034 dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK
<> 144:ef7eb2e8f9f7 1035 |_EMU_DCDCTIMING_LNWAIT_MASK
<> 144:ef7eb2e8f9f7 1036 |_EMU_DCDCTIMING_BYPWAIT_MASK);
<> 144:ef7eb2e8f9f7 1037
<> 144:ef7eb2e8f9f7 1038 dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1039 | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)
<> 144:ef7eb2e8f9f7 1040 | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));
<> 144:ef7eb2e8f9f7 1041 EMU->DCDCTIMING = dcdcTiming;
<> 144:ef7eb2e8f9f7 1042
<> 144:ef7eb2e8f9f7 1043 errataFixDcdcHsState = errataFixDcdcHsTrimSet;
<> 144:ef7eb2e8f9f7 1044 }
<> 144:ef7eb2e8f9f7 1045 }
<> 144:ef7eb2e8f9f7 1046
<> 144:ef7eb2e8f9f7 1047
<> 144:ef7eb2e8f9f7 1048 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1049 * @brief
<> 144:ef7eb2e8f9f7 1050 * Calculate and update EMU->DCDCMISCCTRL for maximum DCDC current based
<> 144:ef7eb2e8f9f7 1051 * on the slice configuration and user set maximum.
<> 144:ef7eb2e8f9f7 1052 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1053 static void maxCurrentUpdate(void)
<> 144:ef7eb2e8f9f7 1054 {
<> 144:ef7eb2e8f9f7 1055 uint32_t lncLimImSel;
<> 144:ef7eb2e8f9f7 1056 uint32_t lpcLimImSel;
<> 144:ef7eb2e8f9f7 1057 uint32_t pFetCnt;
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)
<> 144:ef7eb2e8f9f7 1060 >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;
<> 144:ef7eb2e8f9f7 1061
<> 144:ef7eb2e8f9f7 1062 /* Equation from Reference Manual section 11.5.20, in the register
<> 144:ef7eb2e8f9f7 1063 field description for LNCLIMILIMSEL and LPCLIMILIMSEL. */
<> 144:ef7eb2e8f9f7 1064 lncLimImSel = (dcdcMaxCurrent_mA / (5 * (pFetCnt + 1))) - 1;
<> 144:ef7eb2e8f9f7 1065 /* 80mA as recommended in Application Note AN0948 */
<> 144:ef7eb2e8f9f7 1066 lpcLimImSel = (80 / (5 * (pFetCnt + 1))) - 1;
<> 144:ef7eb2e8f9f7 1067
<> 144:ef7eb2e8f9f7 1068 lncLimImSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1069 lpcLimImSel <<= _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1070 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK
<> 144:ef7eb2e8f9f7 1071 | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))
<> 144:ef7eb2e8f9f7 1072 | (lncLimImSel | lpcLimImSel);
<> 144:ef7eb2e8f9f7 1073 }
<> 144:ef7eb2e8f9f7 1074
<> 144:ef7eb2e8f9f7 1075
<> 144:ef7eb2e8f9f7 1076 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1077 * @brief
<> 144:ef7eb2e8f9f7 1078 * Set static variable that holds the user set maximum current. Update
<> 144:ef7eb2e8f9f7 1079 * DCDC configuration.
<> 144:ef7eb2e8f9f7 1080 *
<> 144:ef7eb2e8f9f7 1081 * @param[in] mAmaxCurrent
<> 144:ef7eb2e8f9f7 1082 * Maximum allowed current drawn by the DCDC from VREGVDD in mA.
<> 144:ef7eb2e8f9f7 1083 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1084 static void maxCurrentSet(uint32_t mAmaxCurrent)
<> 144:ef7eb2e8f9f7 1085 {
<> 144:ef7eb2e8f9f7 1086 dcdcMaxCurrent_mA = mAmaxCurrent;
<> 144:ef7eb2e8f9f7 1087 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 1088 }
<> 144:ef7eb2e8f9f7 1089
<> 144:ef7eb2e8f9f7 1090
<> 144:ef7eb2e8f9f7 1091 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1092 * @brief
<> 144:ef7eb2e8f9f7 1093 * Load EMU_DCDCLPCTRL_LPCMPHYSSEL depending on LP bias, LP feedback
<> 144:ef7eb2e8f9f7 1094 * attenuation and DEVINFOREV.
<> 144:ef7eb2e8f9f7 1095 *
<> 144:ef7eb2e8f9f7 1096 * @param[in] attSet
<> 144:ef7eb2e8f9f7 1097 * LP feedback attenuation.
<> 144:ef7eb2e8f9f7 1098 * @param[in] lpCmpBias
<> 144:ef7eb2e8f9f7 1099 * lpCmpBias selection
<> 144:ef7eb2e8f9f7 1100 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1101 static bool LpCmpHystCalibrationLoad(bool lpAttenuation, uint32_t lpCmpBias)
<> 144:ef7eb2e8f9f7 1102 {
<> 144:ef7eb2e8f9f7 1103 uint8_t devinfoRev;
<> 144:ef7eb2e8f9f7 1104 uint32_t lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1105
<> 144:ef7eb2e8f9f7 1106 /* Get calib data revision */
<> 144:ef7eb2e8f9f7 1107 devinfoRev = SYSTEM_GetDevinfoRev();
<> 144:ef7eb2e8f9f7 1108
<> 144:ef7eb2e8f9f7 1109 /* Load LPATT indexed calibration data */
<> 144:ef7eb2e8f9f7 1110 if (devinfoRev < 4)
<> 144:ef7eb2e8f9f7 1111 {
<> 144:ef7eb2e8f9f7 1112 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;
<> 144:ef7eb2e8f9f7 1113
<> 144:ef7eb2e8f9f7 1114 if (lpAttenuation)
<> 144:ef7eb2e8f9f7 1115 {
<> 144:ef7eb2e8f9f7 1116 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)
<> 144:ef7eb2e8f9f7 1117 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1118 }
<> 144:ef7eb2e8f9f7 1119 else
<> 144:ef7eb2e8f9f7 1120 {
<> 144:ef7eb2e8f9f7 1121 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)
<> 144:ef7eb2e8f9f7 1122 >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1123 }
<> 144:ef7eb2e8f9f7 1124 }
<> 144:ef7eb2e8f9f7 1125 /* devinfoRev >= 4
<> 144:ef7eb2e8f9f7 1126 Load LPCMPBIAS indexed calibration data */
<> 144:ef7eb2e8f9f7 1127 else
<> 144:ef7eb2e8f9f7 1128 {
<> 144:ef7eb2e8f9f7 1129 lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;
<> 144:ef7eb2e8f9f7 1130 switch (lpCmpBias)
<> 144:ef7eb2e8f9f7 1131 {
<> 144:ef7eb2e8f9f7 1132 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1133 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1134 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1135 break;
<> 144:ef7eb2e8f9f7 1136
<> 144:ef7eb2e8f9f7 1137 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1138 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1139 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1140 break;
<> 144:ef7eb2e8f9f7 1141
<> 144:ef7eb2e8f9f7 1142 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1143 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1144 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1145 break;
<> 144:ef7eb2e8f9f7 1146
<> 144:ef7eb2e8f9f7 1147 case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1148 lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1149 >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1150 break;
<> 144:ef7eb2e8f9f7 1151
<> 144:ef7eb2e8f9f7 1152 default:
<> 144:ef7eb2e8f9f7 1153 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1154 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1155 return false;
<> 144:ef7eb2e8f9f7 1156 }
<> 144:ef7eb2e8f9f7 1157 }
<> 144:ef7eb2e8f9f7 1158
<> 144:ef7eb2e8f9f7 1159 /* Make sure the sel value is within the field range. */
<> 144:ef7eb2e8f9f7 1160 lpcmpHystSel <<= _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT;
<> 144:ef7eb2e8f9f7 1161 if (lpcmpHystSel & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK)
<> 144:ef7eb2e8f9f7 1162 {
<> 144:ef7eb2e8f9f7 1163 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1164 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1165 return false;
<> 144:ef7eb2e8f9f7 1166 }
<> 144:ef7eb2e8f9f7 1167 EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK) | lpcmpHystSel;
<> 144:ef7eb2e8f9f7 1168
<> 144:ef7eb2e8f9f7 1169 return true;
<> 144:ef7eb2e8f9f7 1170 }
<> 144:ef7eb2e8f9f7 1171
<> 144:ef7eb2e8f9f7 1172
<> 144:ef7eb2e8f9f7 1173 /** @endcond */
<> 144:ef7eb2e8f9f7 1174
<> 144:ef7eb2e8f9f7 1175 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1176 * @brief
<> 144:ef7eb2e8f9f7 1177 * Set DCDC regulator operating mode
<> 144:ef7eb2e8f9f7 1178 *
<> 144:ef7eb2e8f9f7 1179 * @param[in] dcdcMode
<> 144:ef7eb2e8f9f7 1180 * DCDC mode
<> 144:ef7eb2e8f9f7 1181 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1182 void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)
<> 144:ef7eb2e8f9f7 1183 {
<> 144:ef7eb2e8f9f7 1184 while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);
<> 144:ef7eb2e8f9f7 1185 BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);
<> 144:ef7eb2e8f9f7 1186 EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;
<> 144:ef7eb2e8f9f7 1187 }
<> 144:ef7eb2e8f9f7 1188
<> 144:ef7eb2e8f9f7 1189
<> 144:ef7eb2e8f9f7 1190 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1191 * @brief
<> 144:ef7eb2e8f9f7 1192 * Configure DCDC regulator
<> 144:ef7eb2e8f9f7 1193 *
<> 144:ef7eb2e8f9f7 1194 * @note
<> 144:ef7eb2e8f9f7 1195 * Use the function EMU_DCDCPowerDown() to if the power circuit is configured
<> 144:ef7eb2e8f9f7 1196 * for NODCDC as decribed in Section 11.3.4.3 in the Reference Manual.
<> 144:ef7eb2e8f9f7 1197 *
<> 144:ef7eb2e8f9f7 1198 * @param[in] dcdcInit
<> 144:ef7eb2e8f9f7 1199 * DCDC initialization structure
<> 144:ef7eb2e8f9f7 1200 *
<> 144:ef7eb2e8f9f7 1201 * @return
<> 144:ef7eb2e8f9f7 1202 * True if initialization parameters are valid
<> 144:ef7eb2e8f9f7 1203 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1204 bool EMU_DCDCInit(EMU_DCDCInit_TypeDef *dcdcInit)
<> 144:ef7eb2e8f9f7 1205 {
<> 144:ef7eb2e8f9f7 1206 uint32_t lpCmpBiasSel;
<> 144:ef7eb2e8f9f7 1207
<> 144:ef7eb2e8f9f7 1208 /* Set external power configuration. This enables writing to the other
<> 144:ef7eb2e8f9f7 1209 DCDC registers. */
<> 144:ef7eb2e8f9f7 1210 EMU->PWRCFG = dcdcInit->powerConfig;
<> 144:ef7eb2e8f9f7 1211
<> 144:ef7eb2e8f9f7 1212 /* EMU->PWRCFG is write-once and POR reset only. Check that
<> 144:ef7eb2e8f9f7 1213 we could set the desired power configuration. */
<> 144:ef7eb2e8f9f7 1214 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != dcdcInit->powerConfig)
<> 144:ef7eb2e8f9f7 1215 {
<> 144:ef7eb2e8f9f7 1216 /* If this assert triggers unexpectedly, please power cycle the
<> 144:ef7eb2e8f9f7 1217 kit to reset the power configuration. */
<> 144:ef7eb2e8f9f7 1218 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1219 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1220 return false;
<> 144:ef7eb2e8f9f7 1221 }
<> 144:ef7eb2e8f9f7 1222
<> 144:ef7eb2e8f9f7 1223 /* Load DCDC calibration data from the DI page */
<> 144:ef7eb2e8f9f7 1224 ConstCalibrationLoad();
<> 144:ef7eb2e8f9f7 1225
<> 144:ef7eb2e8f9f7 1226 /* Check current parameters */
<> 144:ef7eb2e8f9f7 1227 EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1228 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);
<> 144:ef7eb2e8f9f7 1229
<> 144:ef7eb2e8f9f7 1230 /* DCDC low-noise supports max 200mA */
<> 144:ef7eb2e8f9f7 1231 if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)
<> 144:ef7eb2e8f9f7 1232 {
<> 144:ef7eb2e8f9f7 1233 EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);
<> 144:ef7eb2e8f9f7 1234 }
<> 144:ef7eb2e8f9f7 1235
<> 144:ef7eb2e8f9f7 1236 /* EM2, 3 and 4 current above 100uA is not supported */
<> 144:ef7eb2e8f9f7 1237 EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 100);
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239 /* Decode LP comparator bias for EM0/1 and EM2/3 */
<> 144:ef7eb2e8f9f7 1240 lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1;
<> 144:ef7eb2e8f9f7 1241 if (dcdcInit->em234LoadCurrent_uA <= 10)
<> 144:ef7eb2e8f9f7 1242 {
<> 144:ef7eb2e8f9f7 1243 lpCmpBiasSel = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0;
<> 144:ef7eb2e8f9f7 1244 }
<> 144:ef7eb2e8f9f7 1245
<> 144:ef7eb2e8f9f7 1246 /* Set DCDC low-power mode comparator bias selection */
<> 144:ef7eb2e8f9f7 1247 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK
<> 144:ef7eb2e8f9f7 1248 | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))
<> 144:ef7eb2e8f9f7 1249 | ((uint32_t)lpCmpBiasSel
<> 144:ef7eb2e8f9f7 1250 | (uint32_t)dcdcInit->lnTransientMode);
<> 144:ef7eb2e8f9f7 1251
<> 144:ef7eb2e8f9f7 1252 /* Set recommended and validated current optimization settings */
<> 144:ef7eb2e8f9f7 1253 ValidatedConfigSet();
<> 144:ef7eb2e8f9f7 1254
<> 144:ef7eb2e8f9f7 1255 /* Set the maximum current that the DCDC can draw from the power source */
<> 144:ef7eb2e8f9f7 1256 maxCurrentSet(dcdcInit->maxCurrent_mA);
<> 144:ef7eb2e8f9f7 1257
<> 144:ef7eb2e8f9f7 1258 /* Optimize LN slice based on given load current estimate */
<> 144:ef7eb2e8f9f7 1259 EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);
<> 144:ef7eb2e8f9f7 1260
<> 144:ef7eb2e8f9f7 1261 /* Set DCDC output voltage */
<> 144:ef7eb2e8f9f7 1262 dcdcOutput_mVout = dcdcInit->mVout;
<> 144:ef7eb2e8f9f7 1263 if (!EMU_DCDCOutputVoltageSet(dcdcOutput_mVout, true, true))
<> 144:ef7eb2e8f9f7 1264 {
<> 144:ef7eb2e8f9f7 1265 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1266 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1267 return false;
<> 144:ef7eb2e8f9f7 1268 }
<> 144:ef7eb2e8f9f7 1269
<> 144:ef7eb2e8f9f7 1270 /* Set EM0 DCDC operating mode. Output voltage set in EMU_DCDCOutputVoltageSet()
<> 144:ef7eb2e8f9f7 1271 above takes effect if mode is changed from bypass here. */
<> 144:ef7eb2e8f9f7 1272 EMU_DCDCModeSet(dcdcInit->dcdcMode);
<> 144:ef7eb2e8f9f7 1273
<> 144:ef7eb2e8f9f7 1274 /* Select analog peripheral power supply */
<> 144:ef7eb2e8f9f7 1275 BUS_RegBitWrite(&EMU->PWRCTRL, _EMU_PWRCTRL_ANASW_SHIFT, dcdcInit->anaPeripheralPower ? 1 : 0);
<> 144:ef7eb2e8f9f7 1276
<> 144:ef7eb2e8f9f7 1277 return true;
<> 144:ef7eb2e8f9f7 1278 }
<> 144:ef7eb2e8f9f7 1279
<> 144:ef7eb2e8f9f7 1280
<> 144:ef7eb2e8f9f7 1281 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1282 * @brief
<> 144:ef7eb2e8f9f7 1283 * Set DCDC output voltage
<> 144:ef7eb2e8f9f7 1284 *
<> 144:ef7eb2e8f9f7 1285 * @param[in] mV
<> 144:ef7eb2e8f9f7 1286 * Target DCDC output voltage in mV
<> 144:ef7eb2e8f9f7 1287 *
<> 144:ef7eb2e8f9f7 1288 * @return
<> 144:ef7eb2e8f9f7 1289 * True if the mV parameter is valid
<> 144:ef7eb2e8f9f7 1290 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1291 bool EMU_DCDCOutputVoltageSet(uint32_t mV,
<> 144:ef7eb2e8f9f7 1292 bool setLpVoltage,
<> 144:ef7eb2e8f9f7 1293 bool setLnVoltage)
<> 144:ef7eb2e8f9f7 1294 {
<> 144:ef7eb2e8f9f7 1295 #if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )
<> 144:ef7eb2e8f9f7 1296
<> 144:ef7eb2e8f9f7 1297 bool validOutVoltage;
<> 144:ef7eb2e8f9f7 1298 uint8_t lnMode;
<> 144:ef7eb2e8f9f7 1299 bool attSet;
<> 144:ef7eb2e8f9f7 1300 uint32_t attMask;
<> 144:ef7eb2e8f9f7 1301 uint32_t vrefLow = 0;
<> 144:ef7eb2e8f9f7 1302 uint32_t vrefHigh = 0;
<> 144:ef7eb2e8f9f7 1303 uint32_t vrefVal = 0;
<> 144:ef7eb2e8f9f7 1304 uint32_t mVlow = 0;
<> 144:ef7eb2e8f9f7 1305 uint32_t mVhigh = 0;
<> 144:ef7eb2e8f9f7 1306 uint32_t vrefShift;
<> 144:ef7eb2e8f9f7 1307 uint32_t lpcmpBias;
<> 144:ef7eb2e8f9f7 1308 volatile uint32_t* ctrlReg;
<> 144:ef7eb2e8f9f7 1309
<> 144:ef7eb2e8f9f7 1310 /* Check that the set voltage is within valid range.
<> 144:ef7eb2e8f9f7 1311 Voltages are obtained from the datasheet. */
<> 144:ef7eb2e8f9f7 1312 validOutVoltage = false;
<> 144:ef7eb2e8f9f7 1313 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD)
<> 144:ef7eb2e8f9f7 1314 {
<> 144:ef7eb2e8f9f7 1315 validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)
<> 144:ef7eb2e8f9f7 1316 && (mV <= PWRCFG_DCDCTODVDD_VMAX));
<> 144:ef7eb2e8f9f7 1317 }
<> 144:ef7eb2e8f9f7 1318
<> 144:ef7eb2e8f9f7 1319 if (!validOutVoltage)
<> 144:ef7eb2e8f9f7 1320 {
<> 144:ef7eb2e8f9f7 1321 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1322 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1323 return false;
<> 144:ef7eb2e8f9f7 1324 }
<> 144:ef7eb2e8f9f7 1325
<> 144:ef7eb2e8f9f7 1326 /* Populate both LP and LN registers, set control reg pointer and VREF shift. */
<> 144:ef7eb2e8f9f7 1327 for (lnMode = 0; lnMode <= 1; lnMode++)
<> 144:ef7eb2e8f9f7 1328 {
<> 144:ef7eb2e8f9f7 1329 if (((lnMode == 0) && !setLpVoltage)
<> 144:ef7eb2e8f9f7 1330 || ((lnMode == 1) && !setLnVoltage))
<> 144:ef7eb2e8f9f7 1331 {
<> 144:ef7eb2e8f9f7 1332 continue;
<> 144:ef7eb2e8f9f7 1333 }
<> 144:ef7eb2e8f9f7 1334
<> 144:ef7eb2e8f9f7 1335 ctrlReg = (lnMode ? &EMU->DCDCLNVCTRL : &EMU->DCDCLPVCTRL);
<> 144:ef7eb2e8f9f7 1336 vrefShift = (lnMode ? _EMU_DCDCLNVCTRL_LNVREF_SHIFT
<> 144:ef7eb2e8f9f7 1337 : _EMU_DCDCLPVCTRL_LPVREF_SHIFT);
<> 144:ef7eb2e8f9f7 1338
<> 144:ef7eb2e8f9f7 1339 /* Set attenuation to use */
<> 144:ef7eb2e8f9f7 1340 attSet = (mV > 1800);
<> 144:ef7eb2e8f9f7 1341 if (attSet)
<> 144:ef7eb2e8f9f7 1342 {
<> 144:ef7eb2e8f9f7 1343 mVlow = 1800;
<> 144:ef7eb2e8f9f7 1344 mVhigh = 3000;
<> 144:ef7eb2e8f9f7 1345 attMask = (lnMode ? EMU_DCDCLNVCTRL_LNATT : EMU_DCDCLPVCTRL_LPATT);
<> 144:ef7eb2e8f9f7 1346 }
<> 144:ef7eb2e8f9f7 1347 else
<> 144:ef7eb2e8f9f7 1348 {
<> 144:ef7eb2e8f9f7 1349 mVlow = 1200;
<> 144:ef7eb2e8f9f7 1350 mVhigh = 1800;
<> 144:ef7eb2e8f9f7 1351 attMask = 0;
<> 144:ef7eb2e8f9f7 1352 }
<> 144:ef7eb2e8f9f7 1353
<> 144:ef7eb2e8f9f7 1354 /* Get 2-point calib data from DEVINFO, calculate trimming and set voltege */
<> 144:ef7eb2e8f9f7 1355 if (lnMode)
<> 144:ef7eb2e8f9f7 1356 {
<> 144:ef7eb2e8f9f7 1357 /* Set low-noise DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1358 if (attSet)
<> 144:ef7eb2e8f9f7 1359 {
<> 144:ef7eb2e8f9f7 1360 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1361 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1362 >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1363 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)
<> 144:ef7eb2e8f9f7 1364 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;
<> 144:ef7eb2e8f9f7 1365 }
<> 144:ef7eb2e8f9f7 1366 else
<> 144:ef7eb2e8f9f7 1367 {
<> 144:ef7eb2e8f9f7 1368 vrefLow = DEVINFO->DCDCLNVCTRL0;
<> 144:ef7eb2e8f9f7 1369 vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1370 >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1371 vrefLow = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)
<> 144:ef7eb2e8f9f7 1372 >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;
<> 144:ef7eb2e8f9f7 1373 }
<> 144:ef7eb2e8f9f7 1374 }
<> 144:ef7eb2e8f9f7 1375 else
<> 144:ef7eb2e8f9f7 1376 {
<> 144:ef7eb2e8f9f7 1377 /* Set low-power DCDC output voltage tuning */
<> 144:ef7eb2e8f9f7 1378
<> 144:ef7eb2e8f9f7 1379 /* Get LPCMPBIAS and make sure masks are not overlayed */
<> 144:ef7eb2e8f9f7 1380 lpcmpBias = EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK;
<> 144:ef7eb2e8f9f7 1381 EFM_ASSERT(!(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK & attMask));
<> 144:ef7eb2e8f9f7 1382 switch (attMask | lpcmpBias)
<> 144:ef7eb2e8f9f7 1383 {
<> 144:ef7eb2e8f9f7 1384 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1385 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1386 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1387 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1388 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1389 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1390 break;
<> 144:ef7eb2e8f9f7 1391
<> 144:ef7eb2e8f9f7 1392 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1393 vrefLow = DEVINFO->DCDCLPVCTRL2;
<> 144:ef7eb2e8f9f7 1394 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1395 >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1396 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1397 >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1398 break;
<> 144:ef7eb2e8f9f7 1399
<> 144:ef7eb2e8f9f7 1400 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1401 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1402 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1403 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1404 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1405 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1406 break;
<> 144:ef7eb2e8f9f7 1407
<> 144:ef7eb2e8f9f7 1408 case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1409 vrefLow = DEVINFO->DCDCLPVCTRL3;
<> 144:ef7eb2e8f9f7 1410 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1411 >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1412 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1413 >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1414 break;
<> 144:ef7eb2e8f9f7 1415
<> 144:ef7eb2e8f9f7 1416 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:
<> 144:ef7eb2e8f9f7 1417 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1418 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1419 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1420 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)
<> 144:ef7eb2e8f9f7 1421 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;
<> 144:ef7eb2e8f9f7 1422 break;
<> 144:ef7eb2e8f9f7 1423
<> 144:ef7eb2e8f9f7 1424 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:
<> 144:ef7eb2e8f9f7 1425 vrefLow = DEVINFO->DCDCLPVCTRL0;
<> 144:ef7eb2e8f9f7 1426 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1427 >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1428 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)
<> 144:ef7eb2e8f9f7 1429 >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;
<> 144:ef7eb2e8f9f7 1430 break;
<> 144:ef7eb2e8f9f7 1431
<> 144:ef7eb2e8f9f7 1432 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:
<> 144:ef7eb2e8f9f7 1433 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1434 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1435 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1436 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)
<> 144:ef7eb2e8f9f7 1437 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;
<> 144:ef7eb2e8f9f7 1438 break;
<> 144:ef7eb2e8f9f7 1439
<> 144:ef7eb2e8f9f7 1440 case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:
<> 144:ef7eb2e8f9f7 1441 vrefLow = DEVINFO->DCDCLPVCTRL1;
<> 144:ef7eb2e8f9f7 1442 vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1443 >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1444 vrefLow = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)
<> 144:ef7eb2e8f9f7 1445 >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;
<> 144:ef7eb2e8f9f7 1446 break;
<> 144:ef7eb2e8f9f7 1447
<> 144:ef7eb2e8f9f7 1448 default:
<> 144:ef7eb2e8f9f7 1449 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1450 break;
<> 144:ef7eb2e8f9f7 1451 }
<> 144:ef7eb2e8f9f7 1452
<> 144:ef7eb2e8f9f7 1453 /* Load LP comparator hysteresis calibration */
<> 144:ef7eb2e8f9f7 1454 if(!(LpCmpHystCalibrationLoad(attSet, lpcmpBias >> _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT)))
<> 144:ef7eb2e8f9f7 1455 {
<> 144:ef7eb2e8f9f7 1456 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1457 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1458 return false;
<> 144:ef7eb2e8f9f7 1459 }
<> 144:ef7eb2e8f9f7 1460 } /* Low-nise / low-power mode */
<> 144:ef7eb2e8f9f7 1461
<> 144:ef7eb2e8f9f7 1462
<> 144:ef7eb2e8f9f7 1463 /* Check for valid 2-point trim values */
<> 144:ef7eb2e8f9f7 1464 if ((vrefLow == 0xFF) && (vrefHigh == 0xFF))
<> 144:ef7eb2e8f9f7 1465 {
<> 144:ef7eb2e8f9f7 1466 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1467 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1468 return false;
<> 144:ef7eb2e8f9f7 1469 }
<> 144:ef7eb2e8f9f7 1470
<> 144:ef7eb2e8f9f7 1471 /* Calculate and set voltage trim */
<> 144:ef7eb2e8f9f7 1472 vrefVal = ((mV - mVlow) * (vrefHigh - vrefLow)) / (mVhigh - mVlow);
<> 144:ef7eb2e8f9f7 1473 vrefVal += vrefLow;
<> 144:ef7eb2e8f9f7 1474
<> 144:ef7eb2e8f9f7 1475 /* Range check */
<> 144:ef7eb2e8f9f7 1476 if ((vrefVal > vrefHigh) || (vrefVal < vrefLow))
<> 144:ef7eb2e8f9f7 1477 {
<> 144:ef7eb2e8f9f7 1478 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1479 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1480 return false;
<> 144:ef7eb2e8f9f7 1481 }
<> 144:ef7eb2e8f9f7 1482
<> 144:ef7eb2e8f9f7 1483 /* Update DCDCLNVCTRL/DCDCLPVCTRL */
<> 144:ef7eb2e8f9f7 1484 *ctrlReg = (vrefVal << vrefShift) | attMask;
<> 144:ef7eb2e8f9f7 1485 }
<> 144:ef7eb2e8f9f7 1486 #endif
<> 144:ef7eb2e8f9f7 1487 return true;
<> 144:ef7eb2e8f9f7 1488 }
<> 144:ef7eb2e8f9f7 1489
<> 144:ef7eb2e8f9f7 1490
<> 144:ef7eb2e8f9f7 1491 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1492 * @brief
<> 144:ef7eb2e8f9f7 1493 * Optimize DCDC slice count based on the estimated average load current
<> 144:ef7eb2e8f9f7 1494 * in EM0
<> 144:ef7eb2e8f9f7 1495 *
<> 144:ef7eb2e8f9f7 1496 * @param[in] mAEm0LoadCurrent
<> 144:ef7eb2e8f9f7 1497 * Estimated average EM0 load current in mA.
<> 144:ef7eb2e8f9f7 1498 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1499 void EMU_DCDCOptimizeSlice(uint32_t mAEm0LoadCurrent)
<> 144:ef7eb2e8f9f7 1500 {
<> 144:ef7eb2e8f9f7 1501 uint32_t sliceCount = 0;
<> 144:ef7eb2e8f9f7 1502 uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1503 >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;
<> 144:ef7eb2e8f9f7 1504
<> 144:ef7eb2e8f9f7 1505 /* Set recommended slice count */
<> 144:ef7eb2e8f9f7 1506 if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= EMU_DcdcLnRcoBand_5MHz))
<> 144:ef7eb2e8f9f7 1507 {
<> 144:ef7eb2e8f9f7 1508 if (mAEm0LoadCurrent < 20)
<> 144:ef7eb2e8f9f7 1509 {
<> 144:ef7eb2e8f9f7 1510 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1511 }
<> 144:ef7eb2e8f9f7 1512 else if ((mAEm0LoadCurrent >= 20) && (mAEm0LoadCurrent < 40))
<> 144:ef7eb2e8f9f7 1513 {
<> 144:ef7eb2e8f9f7 1514 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1515 }
<> 144:ef7eb2e8f9f7 1516 else
<> 144:ef7eb2e8f9f7 1517 {
<> 144:ef7eb2e8f9f7 1518 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1519 }
<> 144:ef7eb2e8f9f7 1520 }
<> 144:ef7eb2e8f9f7 1521 else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1522 {
<> 144:ef7eb2e8f9f7 1523 if (mAEm0LoadCurrent < 10)
<> 144:ef7eb2e8f9f7 1524 {
<> 144:ef7eb2e8f9f7 1525 sliceCount = 4;
<> 144:ef7eb2e8f9f7 1526 }
<> 144:ef7eb2e8f9f7 1527 else if ((mAEm0LoadCurrent >= 10) && (mAEm0LoadCurrent < 20))
<> 144:ef7eb2e8f9f7 1528 {
<> 144:ef7eb2e8f9f7 1529 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1530 }
<> 144:ef7eb2e8f9f7 1531 else
<> 144:ef7eb2e8f9f7 1532 {
<> 144:ef7eb2e8f9f7 1533 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1534 }
<> 144:ef7eb2e8f9f7 1535 }
<> 144:ef7eb2e8f9f7 1536 else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))
<> 144:ef7eb2e8f9f7 1537 {
<> 144:ef7eb2e8f9f7 1538 if (mAEm0LoadCurrent < 40)
<> 144:ef7eb2e8f9f7 1539 {
<> 144:ef7eb2e8f9f7 1540 sliceCount = 8;
<> 144:ef7eb2e8f9f7 1541 }
<> 144:ef7eb2e8f9f7 1542 else
<> 144:ef7eb2e8f9f7 1543 {
<> 144:ef7eb2e8f9f7 1544 sliceCount = 16;
<> 144:ef7eb2e8f9f7 1545 }
<> 144:ef7eb2e8f9f7 1546 }
<> 144:ef7eb2e8f9f7 1547 else
<> 144:ef7eb2e8f9f7 1548 {
<> 144:ef7eb2e8f9f7 1549 /* This configuration is not recommended. EMU_DCDCInit() applies a recommended
<> 144:ef7eb2e8f9f7 1550 configuration. */
<> 144:ef7eb2e8f9f7 1551 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1552 }
<> 144:ef7eb2e8f9f7 1553
<> 144:ef7eb2e8f9f7 1554 /* The selected silices are PSLICESEL + 1 */
<> 144:ef7eb2e8f9f7 1555 sliceCount--;
<> 144:ef7eb2e8f9f7 1556
<> 144:ef7eb2e8f9f7 1557 /* Apply slice count to both N and P slice */
<> 144:ef7eb2e8f9f7 1558 sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT
<> 144:ef7eb2e8f9f7 1559 | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);
<> 144:ef7eb2e8f9f7 1560 EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK
<> 144:ef7eb2e8f9f7 1561 | _EMU_DCDCMISCCTRL_NFETCNT_MASK))
<> 144:ef7eb2e8f9f7 1562 | sliceCount;
<> 144:ef7eb2e8f9f7 1563
<> 144:ef7eb2e8f9f7 1564 /* Update current limit configuration as it depends on the slice configuration. */
<> 144:ef7eb2e8f9f7 1565 maxCurrentUpdate();
<> 144:ef7eb2e8f9f7 1566 }
<> 144:ef7eb2e8f9f7 1567
<> 144:ef7eb2e8f9f7 1568 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1569 * @brief
<> 144:ef7eb2e8f9f7 1570 * Set DCDC Low-noise RCO band.
<> 144:ef7eb2e8f9f7 1571 *
<> 144:ef7eb2e8f9f7 1572 * @param[in] band
<> 144:ef7eb2e8f9f7 1573 * RCO band to set.
<> 144:ef7eb2e8f9f7 1574 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1575 void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)
<> 144:ef7eb2e8f9f7 1576 {
<> 144:ef7eb2e8f9f7 1577 EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)
<> 144:ef7eb2e8f9f7 1578 | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);
<> 144:ef7eb2e8f9f7 1579 }
<> 144:ef7eb2e8f9f7 1580
<> 144:ef7eb2e8f9f7 1581 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1582 * @brief
<> 144:ef7eb2e8f9f7 1583 * Power off the DCDC regulator.
<> 144:ef7eb2e8f9f7 1584 *
<> 144:ef7eb2e8f9f7 1585 * @details
<> 144:ef7eb2e8f9f7 1586 * This function powers off the DCDC controller. This function should only be
<> 144:ef7eb2e8f9f7 1587 * used if the external power circuit is wired for no DCDC. If the external power
<> 144:ef7eb2e8f9f7 1588 * circuit is wired for DCDC usage, then use EMU_DCDCInit() and set the
<> 144:ef7eb2e8f9f7 1589 * DCDC in bypass mode to disable DCDC.
<> 144:ef7eb2e8f9f7 1590 *
<> 144:ef7eb2e8f9f7 1591 * @return
<> 144:ef7eb2e8f9f7 1592 * Return false if the DCDC could not be disabled.
<> 144:ef7eb2e8f9f7 1593 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1594 bool EMU_DCDCPowerOff(void)
<> 144:ef7eb2e8f9f7 1595 {
<> 144:ef7eb2e8f9f7 1596 /* Set power configuration to hard bypass */
<> 144:ef7eb2e8f9f7 1597 EMU->PWRCFG = 0xF;
<> 144:ef7eb2e8f9f7 1598 if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != 0xF)
<> 144:ef7eb2e8f9f7 1599 {
<> 144:ef7eb2e8f9f7 1600 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1601 /* Return when assertions are disabled */
<> 144:ef7eb2e8f9f7 1602 return false;
<> 144:ef7eb2e8f9f7 1603 }
<> 144:ef7eb2e8f9f7 1604
<> 144:ef7eb2e8f9f7 1605 /* Set DCDC to OFF and disable LP in EM2/3/4 */
<> 144:ef7eb2e8f9f7 1606 EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;
<> 144:ef7eb2e8f9f7 1607 return true;
<> 144:ef7eb2e8f9f7 1608 }
<> 144:ef7eb2e8f9f7 1609 #endif
<> 144:ef7eb2e8f9f7 1610
<> 144:ef7eb2e8f9f7 1611
<> 144:ef7eb2e8f9f7 1612 #if defined( EMU_STATUS_VMONRDY )
<> 144:ef7eb2e8f9f7 1613 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 1614 __STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)
<> 144:ef7eb2e8f9f7 1615 {
<> 144:ef7eb2e8f9f7 1616 return (mV - 1200) / 200;
<> 144:ef7eb2e8f9f7 1617 }
<> 144:ef7eb2e8f9f7 1618
<> 144:ef7eb2e8f9f7 1619 __STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)
<> 144:ef7eb2e8f9f7 1620 {
<> 144:ef7eb2e8f9f7 1621 return (mV - 1200 - (coarseThreshold * 200)) / 20;
<> 144:ef7eb2e8f9f7 1622 }
<> 144:ef7eb2e8f9f7 1623 /** @endcond */
<> 144:ef7eb2e8f9f7 1624
<> 144:ef7eb2e8f9f7 1625 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1626 * @brief
<> 144:ef7eb2e8f9f7 1627 * Initialize VMON channel.
<> 144:ef7eb2e8f9f7 1628 *
<> 144:ef7eb2e8f9f7 1629 * @details
<> 144:ef7eb2e8f9f7 1630 * Initialize a VMON channel without hysteresis. If the channel supports
<> 144:ef7eb2e8f9f7 1631 * separate rise and fall triggers, both thresholds will be set to the same
<> 144:ef7eb2e8f9f7 1632 * value.
<> 144:ef7eb2e8f9f7 1633 *
<> 144:ef7eb2e8f9f7 1634 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 1635 * VMON initialization struct
<> 144:ef7eb2e8f9f7 1636 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1637 void EMU_VmonInit(EMU_VmonInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 1638 {
<> 144:ef7eb2e8f9f7 1639 uint32_t thresholdCoarse, thresholdFine;
<> 144:ef7eb2e8f9f7 1640 EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));
<> 144:ef7eb2e8f9f7 1641
<> 144:ef7eb2e8f9f7 1642 thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);
<> 144:ef7eb2e8f9f7 1643 thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);
<> 144:ef7eb2e8f9f7 1644
<> 144:ef7eb2e8f9f7 1645 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 1646 {
<> 144:ef7eb2e8f9f7 1647 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1648 EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1649 | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1650 | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1651 | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1652 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1653 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1654 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1655 break;
<> 144:ef7eb2e8f9f7 1656 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1657 EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1658 | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1659 | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1660 | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1661 | (vmonInit->enable ? EMU_VMONALTAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1662 break;
<> 144:ef7eb2e8f9f7 1663 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1664 EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1665 | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1666 | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1667 | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1668 | (vmonInit->enable ? EMU_VMONDVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1669 break;
<> 144:ef7eb2e8f9f7 1670 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1671 EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1672 | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1673 | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)
<> 144:ef7eb2e8f9f7 1674 | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1675 | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1676 | (vmonInit->enable ? EMU_VMONIO0CTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1677 break;
<> 144:ef7eb2e8f9f7 1678 default:
<> 144:ef7eb2e8f9f7 1679 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1680 return;
<> 144:ef7eb2e8f9f7 1681 }
<> 144:ef7eb2e8f9f7 1682 }
<> 144:ef7eb2e8f9f7 1683
<> 144:ef7eb2e8f9f7 1684 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1685 * @brief
<> 144:ef7eb2e8f9f7 1686 * Initialize VMON channel with hysteresis (separate rise and fall triggers).
<> 144:ef7eb2e8f9f7 1687 *
<> 144:ef7eb2e8f9f7 1688 * @details
<> 144:ef7eb2e8f9f7 1689 * Initialize a VMON channel which supports hysteresis. The AVDD channel is
<> 144:ef7eb2e8f9f7 1690 * the only channel to support separate rise and fall triggers.
<> 144:ef7eb2e8f9f7 1691 *
<> 144:ef7eb2e8f9f7 1692 * @param[in] vmonInit
<> 144:ef7eb2e8f9f7 1693 * VMON Hysteresis initialization struct
<> 144:ef7eb2e8f9f7 1694 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1695 void EMU_VmonHystInit(EMU_VmonHystInit_TypeDef *vmonInit)
<> 144:ef7eb2e8f9f7 1696 {
<> 144:ef7eb2e8f9f7 1697 uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;
<> 144:ef7eb2e8f9f7 1698 /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */
<> 144:ef7eb2e8f9f7 1699 EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));
<> 144:ef7eb2e8f9f7 1700 EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));
<> 144:ef7eb2e8f9f7 1701 /* Fall threshold has to be lower than rise threshold */
<> 144:ef7eb2e8f9f7 1702 EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 1703
<> 144:ef7eb2e8f9f7 1704 riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);
<> 144:ef7eb2e8f9f7 1705 riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);
<> 144:ef7eb2e8f9f7 1706 fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);
<> 144:ef7eb2e8f9f7 1707 fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);
<> 144:ef7eb2e8f9f7 1708
<> 144:ef7eb2e8f9f7 1709 switch(vmonInit->channel)
<> 144:ef7eb2e8f9f7 1710 {
<> 144:ef7eb2e8f9f7 1711 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1712 EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1713 | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1714 | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)
<> 144:ef7eb2e8f9f7 1715 | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)
<> 144:ef7eb2e8f9f7 1716 | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)
<> 144:ef7eb2e8f9f7 1717 | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)
<> 144:ef7eb2e8f9f7 1718 | (vmonInit->enable ? EMU_VMONAVDDCTRL_EN : 0);
<> 144:ef7eb2e8f9f7 1719 break;
<> 144:ef7eb2e8f9f7 1720 default:
<> 144:ef7eb2e8f9f7 1721 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1722 return;
<> 144:ef7eb2e8f9f7 1723 }
<> 144:ef7eb2e8f9f7 1724 }
<> 144:ef7eb2e8f9f7 1725
<> 144:ef7eb2e8f9f7 1726 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1727 * @brief
<> 144:ef7eb2e8f9f7 1728 * Enable or disable a VMON channel
<> 144:ef7eb2e8f9f7 1729 *
<> 144:ef7eb2e8f9f7 1730 * @param[in] channel
<> 144:ef7eb2e8f9f7 1731 * VMON channel to enable/disable
<> 144:ef7eb2e8f9f7 1732 *
<> 144:ef7eb2e8f9f7 1733 * @param[in] enable
<> 144:ef7eb2e8f9f7 1734 * Whether to enable or disable
<> 144:ef7eb2e8f9f7 1735 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1736 void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)
<> 144:ef7eb2e8f9f7 1737 {
<> 144:ef7eb2e8f9f7 1738 uint32_t volatile * reg;
<> 144:ef7eb2e8f9f7 1739 uint32_t bit;
<> 144:ef7eb2e8f9f7 1740
<> 144:ef7eb2e8f9f7 1741 switch(channel)
<> 144:ef7eb2e8f9f7 1742 {
<> 144:ef7eb2e8f9f7 1743 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1744 reg = &(EMU->VMONAVDDCTRL);
<> 144:ef7eb2e8f9f7 1745 bit = _EMU_VMONAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1746 break;
<> 144:ef7eb2e8f9f7 1747 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1748 reg = &(EMU->VMONALTAVDDCTRL);
<> 144:ef7eb2e8f9f7 1749 bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1750 break;
<> 144:ef7eb2e8f9f7 1751 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1752 reg = &(EMU->VMONDVDDCTRL);
<> 144:ef7eb2e8f9f7 1753 bit = _EMU_VMONDVDDCTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1754 break;
<> 144:ef7eb2e8f9f7 1755 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1756 reg = &(EMU->VMONIO0CTRL);
<> 144:ef7eb2e8f9f7 1757 bit = _EMU_VMONIO0CTRL_EN_SHIFT;
<> 144:ef7eb2e8f9f7 1758 break;
<> 144:ef7eb2e8f9f7 1759 default:
<> 144:ef7eb2e8f9f7 1760 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1761 return;
<> 144:ef7eb2e8f9f7 1762 }
<> 144:ef7eb2e8f9f7 1763
<> 144:ef7eb2e8f9f7 1764 BUS_RegBitWrite(reg, bit, enable);
<> 144:ef7eb2e8f9f7 1765 }
<> 144:ef7eb2e8f9f7 1766
<> 144:ef7eb2e8f9f7 1767 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1768 * @brief
<> 144:ef7eb2e8f9f7 1769 * Get the status of a voltage monitor channel.
<> 144:ef7eb2e8f9f7 1770 *
<> 144:ef7eb2e8f9f7 1771 * @param[in] channel
<> 144:ef7eb2e8f9f7 1772 * VMON channel to get status for
<> 144:ef7eb2e8f9f7 1773 *
<> 144:ef7eb2e8f9f7 1774 * @return
<> 144:ef7eb2e8f9f7 1775 * Status of the selected VMON channel. True if channel is triggered.
<> 144:ef7eb2e8f9f7 1776 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1777 bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)
<> 144:ef7eb2e8f9f7 1778 {
<> 144:ef7eb2e8f9f7 1779 uint32_t bit;
<> 144:ef7eb2e8f9f7 1780 switch(channel)
<> 144:ef7eb2e8f9f7 1781 {
<> 144:ef7eb2e8f9f7 1782 case emuVmonChannel_AVDD:
<> 144:ef7eb2e8f9f7 1783 bit = _EMU_STATUS_VMONAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1784 break;
<> 144:ef7eb2e8f9f7 1785 case emuVmonChannel_ALTAVDD:
<> 144:ef7eb2e8f9f7 1786 bit = _EMU_STATUS_VMONALTAVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1787 break;
<> 144:ef7eb2e8f9f7 1788 case emuVmonChannel_DVDD:
<> 144:ef7eb2e8f9f7 1789 bit = _EMU_STATUS_VMONDVDD_SHIFT;
<> 144:ef7eb2e8f9f7 1790 break;
<> 144:ef7eb2e8f9f7 1791 case emuVmonChannel_IOVDD0:
<> 144:ef7eb2e8f9f7 1792 bit = _EMU_STATUS_VMONIO0_SHIFT;
<> 144:ef7eb2e8f9f7 1793 break;
<> 144:ef7eb2e8f9f7 1794 default:
<> 144:ef7eb2e8f9f7 1795 EFM_ASSERT(false);
<> 144:ef7eb2e8f9f7 1796 bit = 0;
<> 144:ef7eb2e8f9f7 1797 }
<> 144:ef7eb2e8f9f7 1798
<> 144:ef7eb2e8f9f7 1799 return BUS_RegBitRead(&EMU->STATUS, bit);
<> 144:ef7eb2e8f9f7 1800 }
<> 144:ef7eb2e8f9f7 1801 #endif /* EMU_STATUS_VMONRDY */
<> 144:ef7eb2e8f9f7 1802
<> 144:ef7eb2e8f9f7 1803 /** @} (end addtogroup EMU) */
<> 144:ef7eb2e8f9f7 1804 /** @} (end addtogroup EM_Library) */
<> 144:ef7eb2e8f9f7 1805 #endif /* __EM_EMU_H */