emlib/src/em_emu.c
void EMU_EnterEM2(bool restore)
{
#if defined(ERRATA_FIX_EMU_E107_EN)
  bool errataFixEmuE107En;
  uint32_t nonWicIntEn[2];
#endif

  /* Only save EMU and CMU state if restored on wake-up. */
  if (restore) {
    emState(emState_Save);
  }

#if defined(_EMU_CTRL_EM23VSCALE_MASK)
  vScaleDownEM23Setup();
#endif

  /* Enter Cortex deep sleep mode */
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

  /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
     Disable the enabled non-WIC interrupts. */
#if defined(ERRATA_FIX_EMU_E107_EN)
  errataFixEmuE107En = getErrataFixEmuE107En();
  if (errataFixEmuE107En) {
    nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
    NVIC->ICER[0] = nonWicIntEn[0];
#if (NON_WIC_INT_MASK_1 != (~(0x0U)))
    nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
    NVIC->ICER[1] = nonWicIntEn[1];
#endif
  }
#endif

#if defined(ERRATA_FIX_DCDC_FETCNT_SET_EN)
  dcdcFetCntSet(true);
#endif
#if defined(ERRATA_FIX_DCDC_LNHS_BLOCK_EN)
  dcdcHsFixLnBlock();
#endif

  __WFI();

#if defined(ERRATA_FIX_DCDC_FETCNT_SET_EN)
  dcdcFetCntSet(false);
#endif

  /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */
#if defined(ERRATA_FIX_EMU_E107_EN)
  if (errataFixEmuE107En) {
    NVIC->ISER[0] = nonWicIntEn[0];
#if (NON_WIC_INT_MASK_1 != (~(0x0U)))
    NVIC->ISER[1] = nonWicIntEn[1];
#endif
  }
#endif

  /* Restore oscillators/clocks and voltage scaling if supported. */
  if (restore) {
    emState(emState_Restore);
  } else {
    /* If not restoring, and original clock was not HFRCO, we have to */
    /* update CMSIS core clock variable since HF clock has changed */
    /* to HFRCO. */
    SystemCoreClockUpdate();
  }
}
/***************************************************************************/
/**
 * @brief
 *   Enter energy mode 2 (EM2).
 *
 * @details
 *   When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
 *   and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
 *   EM0, HFRCO is re-enabled and the core will be clocked by the configured
 *   HFRCO band. This ensures a quick wakeup from EM2.
 *
 *   However, prior to entering EM2, the core may have been using another
 *   oscillator than HFRCO. The @p restore parameter gives the user the option
 *   to restore all HF oscillators according to state prior to entering EM2,
 *   as well as the clock used to clock the core. This restore procedure is
 *   handled by SW. However, since handled by SW, it will not be restored
 *   before completing the interrupt function(s) waking up the core!
 *
 * @note
 *   If restoring core clock to use the HFXO oscillator, which has been
 *   disabled during EM2 mode, this function will stall until the oscillator
 *   has stabilized. Stalling time can be reduced by adding interrupt
 *   support detecting stable oscillator, and an asynchronous switch to the
 *   original oscillator. See CMU documentation. Such a feature is however
 *   outside the scope of the implementation in this function.
 * @par
 *   If HFXO is re-enabled by this function, and NOT used to clock the core,
 *   this function will not wait for HFXO to stabilize. This must be considered
 *   by the application if trying to use features relying on that oscillator
 *   upon return.
 * @par
 *   If a debugger is attached, the AUXHFRCO will not be disabled if enabled
 *   upon entering EM2. It will thus remain enabled when returning to EM0
 *   regardless of the @p restore parameter.
 * @par
 *   If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
 *   the starting and selecting of the core clocks will be identical to the user
 *   independently of the value of the @p restore parameter when waking up on
 *   the wakeup sources corresponding to the autostart and select setting.
 * @par
 *   If voltage scaling is supported, the restore parameter is true and the EM0
 *   voltage scaling level is set higher than the EM2 level, then the EM0 level is
 *   also restored.
 *
 * @param[in] restore
 *   @li true - save and restore oscillators, clocks and voltage scaling, see
 *   function details.
 *   @li false - do not save and restore oscillators and clocks, see function
 *   details.
 * @par
 *   The @p restore option should only be used if all clock control is done
 *   via the CMU API.
 ******************************************************************************/
@brief
Enter energy mode 2 (EM2).

@details
When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
EM0, HFRCO is re-enabled and the core will be clocked by the configured
HFRCO band. This ensures a quick wakeup from EM2.

However, prior to entering EM2, the core may have been using another
oscillator than HFRCO. The @p restore parameter gives the user the option
to restore all HF oscillators according to state prior to entering EM2,
as well as the clock used to clock the core. This restore procedure is
handled by SW. However, since handled by SW, it will not be restored
before completing the interrupt function(s) waking up the core!

@note
If restoring core clock to use the HFXO oscillator, which has been
disabled during EM2 mode, this function will stall until the oscillator
has stabilized. Stalling time can be reduced by adding interrupt
support detecting stable oscillator, and an asynchronous switch to the
original oscillator. See CMU documentation. Such a feature is however
outside the scope of the implementation in this function.
@par
If HFXO is re-enabled by this function, and NOT used to clock the core,
this function will not wait for HFXO to stabilize. This must be considered
by the application if trying to use features relying on that oscillator
upon return.
@par
If a debugger is attached, the AUXHFRCO will not be disabled if enabled
upon entering EM2. It will thus remain enabled when returning to EM0
regardless of the @p restore parameter.
@par
If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),
the starting and selecting of the core clocks will be identical to the user
independently of the value of the @p restore parameter when waking up on
the wakeup sources corresponding to the autostart and select setting.
@par
If voltage scaling is supported, the restore parameter is true and the EM0
voltage scaling level is set higher than the EM2 level, then the EM0 level is
also restored.

@param[in] restore
@li true - save and restore oscillators, clocks and voltage scaling, see
function details.
@li false - do not save and restore oscillators and clocks, see function
details.
@par
The @p restore option should only be used if all clock control is done
via the CMU API.
@brief Enter energy mode 2 ( EM2 ) . @details When entering EM2 the high frequency clocks are disabled ie HFXO HFRCO and AUXHFRCO ( for AUXHFRCO see exception note below ) . When re - entering EM0 HFRCO is re - enabled and the core will be clocked by the configured HFRCO band . This ensures a quick wakeup from EM2 . However prior to entering EM2 the core may have been using another oscillator than HFRCO . The @p restore parameter gives the user the option to restore all HF oscillators according to state prior to entering EM2 as well as the clock used to clock the core . This restore procedure is handled by SW . However since handled by SW it will not be restored before completing the interrupt function ( s ) waking up the core! @note If restoring core clock to use the HFXO oscillator which has been disabled during EM2 mode this function will stall until the oscillator has stabilized . Stalling time can be reduced by adding interrupt support detecting stable oscillator and an asynchronous switch to the original oscillator . See CMU documentation . Such a feature is however outside the scope of the implementation in this function . @par If HFXO is re - enabled by this function and NOT used to clock the core this function will not wait for HFXO to stabilize . This must be considered by the application if trying to use features relying on that oscillator upon return . @par If a debugger is attached the AUXHFRCO will not be disabled if enabled upon entering EM2 . It will thus remain enabled when returning to EM0 regardless of the @p restore parameter . @par If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable () the starting and selecting of the core clocks will be identical to the user independently of the value of the @p restore parameter when waking up on the wakeup sources corresponding to the autostart and select setting . @par If voltage scaling is supported the restore parameter is true and the EM0 voltage scaling level is set higher than the EM2 level then the EM0 level is also restored . @param [ in ] restore @li true - save and restore oscillators clocks and voltage scaling see function details . @li false - do not save and restore oscillators and clocks see function details . @par The @p restore option should only be used if all clock control is done via the CMU API .
void EMU_EnterEM2(bool restore)
{
#if defined(ERRATA_FIX_EMU_E107_EN)
  bool errataFixEmuE107En;
  uint32_t nonWicIntEn[2];
#endif
  if (restore) {
    emState(emState_Save);
  }
#if defined(_EMU_CTRL_EM23VSCALE_MASK)
  vScaleDownEM23Setup();
#endif
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
#if defined(ERRATA_FIX_EMU_E107_EN)
  errataFixEmuE107En = getErrataFixEmuE107En();
  if (errataFixEmuE107En) {
    nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;
    NVIC->ICER[0] = nonWicIntEn[0];
#if (NON_WIC_INT_MASK_1 != (~(0x0U)))
    nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;
    NVIC->ICER[1] = nonWicIntEn[1];
#endif
  }
#endif
#if defined(ERRATA_FIX_DCDC_FETCNT_SET_EN)
  dcdcFetCntSet(true);
#endif
#if defined(ERRATA_FIX_DCDC_LNHS_BLOCK_EN)
  dcdcHsFixLnBlock();
#endif
  __WFI();
#if defined(ERRATA_FIX_DCDC_FETCNT_SET_EN)
  dcdcFetCntSet(false);
#endif
#if defined(ERRATA_FIX_EMU_E107_EN)
  if (errataFixEmuE107En) {
    NVIC->ISER[0] = nonWicIntEn[0];
#if (NON_WIC_INT_MASK_1 != (~(0x0U)))
    NVIC->ISER[1] = nonWicIntEn[1];
#endif
  }
#endif
  if (restore) {
    emState(emState_Restore);
  } else {
    SystemCoreClockUpdate();
  }
}
void EMU_EnterEM2 ( bool restore ) { #if defined ( ERRATA_FIX_EMU_E107_EN ) bool errataFixEmuE107En ; uint32_t nonWicIntEn [ 2 ] ; #endif if ( restore ) { emState ( emState_Save ) ; } #if defined ( _EMU_CTRL_EM23VSCALE_MASK ) vScaleDownEM23Setup ( ) ; #endif SCB -> SCR |= SCB_SCR_SLEEPDEEP_Msk ; #if defined ( ERRATA_FIX_EMU_E107_EN ) errataFixEmuE107En = getErrataFixEmuE107En ( ) ; if ( errataFixEmuE107En ) { nonWicIntEn [ 0 ] = NVIC -> ISER [ 0 ] & NON_WIC_INT_MASK_0 ; NVIC -> ICER [ 0 ] = nonWicIntEn [ 0 ] ; #if ( NON_WIC_INT_MASK_1 != ( ~ ( 0x0U ) ) ) nonWicIntEn [ 1 ] = NVIC -> ISER [ 1 ] & NON_WIC_INT_MASK_1 ; NVIC -> ICER [ 1 ] = nonWicIntEn [ 1 ] ; #endif } #endif #if defined ( ERRATA_FIX_DCDC_FETCNT_SET_EN ) dcdcFetCntSet ( true ) ; #endif #if defined ( ERRATA_FIX_DCDC_LNHS_BLOCK_EN ) dcdcHsFixLnBlock ( ) ; #endif __WFI ( ) ; #if defined ( ERRATA_FIX_DCDC_FETCNT_SET_EN ) dcdcFetCntSet ( false ) ; #endif #if defined ( ERRATA_FIX_EMU_E107_EN ) if ( errataFixEmuE107En ) { NVIC -> ISER [ 0 ] = nonWicIntEn [ 0 ] ; #if ( NON_WIC_INT_MASK_1 != ( ~ ( 0x0U ) ) ) NVIC -> ISER [ 1 ] = nonWicIntEn [ 1 ] ; #endif } #endif if ( restore ) { emState ( emState_Restore ) ; } else { SystemCoreClockUpdate ( ) ; } }
@brief
   Enter energy mode 2 (EM2).
@brief Enter energy mode 2 ( EM2 ) .
/* Only save EMU and CMU state if restored on wake-up. */ /* Enter Cortex deep sleep mode */ /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.
     Disable the enabled non-WIC interrupts. */ /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */ /* Restore oscillators/clocks and voltage scaling if supported. */ /* If not restoring, and original clock was not HFRCO, we have to */ /* update CMSIS core clock variable since HF clock has changed */ /* to HFRCO. */