Reply
<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> tj
Posts: 40
Registered: ‎07-04-2016
Accepted Solution

EFR32MG - EM4 wakeup pins ?

In reference manual there is "It is possible to trigger a wake-up from EM4 using any of the selectable EM4WU GPIO pins." 

In GPIO_EM4WUEN there is 16 bits [31:16] EM4WUEN  EM4 wake up enable without any link to pins.

In GPIO_EXTILEVELthere is only 6 bits to set EM4 Wake Up Level (EM4WU0, 1, 4, 8, 9, 12)

 

Which pins can be used as EM4 wakeup pins ? I have EFR32MG1P132F256GM32 

Is it possible to use PB12 pin at high level ?

How to set pinmask and  polaritymask for GPIO_EM4EnablePinWakeup function ?

Posts: 260
Registered: ‎09-18-2015

Re: EFR32MG - EM4 wakeup pins ?

Hi tj,

 

Which pins can be used as EM4 wakeup pins ? I have EFR32MG1P132F256GM32

 

Please see Table 6.7 in the Mighty Gecko datasheet and look at the GPIO_EM4WUx pins.

 

PB12 is not an option but these are...

 

Wake-Up Pin
GPIO_EM4WU0 PF2
GPIO_EM4WU1 PF7
GPIO_EM4WU4 PD14
GPIO_EM4WU8 PA3
GPIO_EM4WU9 PB13
GPIO_EM4WU12 PC10

 

So, if you wanted to use PB13 (closest one to PB12), you would set bit 25 in both GPIO_EM4WUEN and GPIO_IEN to enable wake-up on PB13.  If you want to wake-up on a high-level on PB13, you would set bit 25 of GPIO_EXTILEVEL; for wake-up on a low-level, you would make sure bit 25 of GPIO_EXTILEVEL is clear.

 

There's a little bit more involved.  You might want to check out a Knowledge Base article I did for this on Happy Gecko.  The sample code I provided won't work on Mighty Gecko as-is, but the steps involved are similar with the proviso that GPIO retention is a very different beast on Mighty Gecko vs. Happy Gecko.  In particular, there's the issue of the EMU_EM4Init_TypeDef structure and how you initialize it that would make things different.

 

At some point, I promise to take the Happy Gecko example and port it to parts like Mighty Gecko Smiley Happy

 

John

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> tj
Posts: 40
Registered: ‎07-04-2016

Re: EFR32MG - EM4 wakeup pins ?

Thank you for reply.

 

Could you check my code ? I have set bit 25 in GPIO_EM4WUEN, GPIO_IEN and GPIO_EXTILEVEL but I can't wake up from EM4H by pin PB13. I have checked by low and high level.

What I'm missing ?

 

void gpioSetWakeUp(void)
{
	CMU_ClockEnable(cmuClock_GPIO, true);

	//EM4WU9 - PB13
	GPIO_PinModeSet(gpioPortB, 13, gpioModeInputPullFilter, 0);

	GPIO->EM4WUEN = (1<<25);
	GPIO->IEN = (1<<25);
	GPIO->EXTILEVEL = (1<<25);
}

void em_EM4H_LfxoRTCC(void)
{
  // Make sure clocks are disabled.
  disableClocks();

  // Route the LFXO clock to RTCC.
  CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFXO);
  CMU_ClockEnable(cmuClock_RTCC, true);

  // Enable clock to the interface with low energy modules.
  CMU_ClockEnable(cmuClock_HFLE, true);

  // Setup RTC parameters.
  RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
  rtccInit.presc = rtccCntPresc_1;
  rtccInit.cntWrapOnCCV1 = true;
  rtccInit.debugRun = true;

  // Initialize RTCC. Configure RTCC with prescaler 1.
  RTCC_Init(&rtccInit);

  // Make sure unwanted oscillators are disabled specifically for EM4H and LFXO.
  CMU_OscillatorEnable(cmuOsc_LFRCO, false, true);

  // EM4H retains 128 byte RAM through RTCC by default.

  // Enter EM4H.
  EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
  em4Init.retainLfxo = 1;
  em4Init.em4State = emuEM4Hibernate;
  em4Init.retainLfxo = true;
  em4Init.pinRetentionMode = emuPinRetentionLatch;
  EMU_EM4Init(&em4Init);
  EMU_EnterEM4();
}

int main(void)
{
	int i;

	EMU_EM23Init_TypeDef em23Init = EMU_EM23INIT_DEFAULT;
	CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;

	/* Chip errata */
	CHIP_Init();

	BSP_TraceProfilerSetup();

	CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);

	ledInit();

	// get reset cause
	uint32_t resetCause = RMU_ResetCauseGet(); // RMU->RSTCAUSE;
	RMU_ResetCauseClear();

	//if system was in EM4 state
	if (resetCause & RMU_RSTCAUSE_EM4RST)
	{
		ledOn(LED1);
		delay_ms(3000);
	}


	gpioSetWakeUp();

	em_EM4H_LfxoRTCC();
}

 

Posts: 260
Registered: ‎09-18-2015

Re: EFR32MG - EM4 wakeup pins ?

[ Edited ]

Hi tj,

 

I suspect your code is not working because you are not handling the retention latch properly.

 

Specifically, if you use full GPIO retention as you are doing (em4Init.pinRetentionMode = emuPinRetentionLatch), then you must unlatch the GPIOs after you reconfigure them upon EM4 wake-up. Retention only holds the pin state and configuration through EM4 entry and wake-up. It does not prevent the associated register bits from being reset upon EM4 wake-up (see 28.3.3 EM4 Retention in the reference manual). Regardless of the source of EM4 wake-up, it is still seen by the system as a reset.

 

Consequently, your code must determine if the reset was caused by EM4 wake-up, and, if so, reconfigure the GPIOs as needed and release the GPIO retention latch. This can be done by calling by setting the EM4UNLATCH bit in EMU_CMD or by calling EMU_UnlatchPinRetention(), which does the same thing.

 

I wrote an example to demonstrate how EM4 pin-wake-up works. I tested this on the Pearl Gecko STK, and I believe it should run unmodified on the Mighty Gecko WSTK because the GPIOs connected to the LEDs and push buttons are the same.

 

/*
 * This code demonstrates GPIO wake from EM4.  Program flow is as follows:
 *
 * 1. Chip and DC-DC initialization.
 * 2. Determine and clear reset cause(s):
 *    a. If a primary source like POR, the reset pin, or system reset
 *       request (debugger), turn on LED1.
 *    b. If the reset is due to EM4 wake-up, turn off LED1.
 * 3. Setup EMU_EM4Init_TypeDef (not really necessary).
 * 4. Configure PF7 (button 1) and wait for rising edge.  Need to do this
 *    before entering EM4 to make sure button still isn't help low from
 *    the last wake-up.
 * 5. Enable EM4 wake-up from low level on PF7 (button 1 press).  LED1 is
 *    turned on and remains lit because retention is required for EM4 pin
 *    wake-up.
 * 6. Go back to step 1 upon EM4 wake-up.
 */

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_gpio.h"
#include "em_rmu.h"

int main(void)
{
  CHIP_Init();

    EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_DEFAULT;
    EMU_DCDCInit(&dcdcInit);

  // Enable GPIO clock
    CMU_ClockEnable(cmuClock_GPIO, true);

    // Get reset cause(s)
    uint32_t rflags = RMU_ResetCauseGet();

    /*
     * Did we get reset from power-on, external pin, or debugger (system
     * request)?  If so, configure PF5 as an output and turn LED1 on.
     * Otherwise turn LED1 off if we got EM4 wake.
     */
    if ((rflags & RMU_RSTCAUSE_PORST) ||
            (rflags & RMU_RSTCAUSE_EXTRST) ||
            (rflags & RMU_RSTCAUSE_SYSREQRST))
        GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 1);
    else if (rflags & RMU_RSTCAUSE_EM4RST)
        GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 0);

    // Clear reset causes so we know which reset matters next time around
    RMU_ResetCauseClear();

    /*
     * None of this is really necessary if only pin wake from EM4 is needed.
     * Code can use either EMU_EnterEM4H() or EMU_EnterEM4S() for hibernate
     * or shutdown entry, respectively.
     *
     * It's very important to note that GPIO_EM4EnablePinWakeup() sets
     * EM4CTRL[EM4IORETMODE] to EM4EXIT, which causes pin retention trough
     * exit.  This is mandatory for EM4 pin wake-up.
     */
  EMU_EM4Init_TypeDef em4init;
    em4init.em4State = emuEM4Shutoff;    // emuEM4Hibernate also works
    em4init.retainLfxo = false;
    em4init.retainLfrco = false;
    em4init.retainUlfrco = false;
    em4init.pinRetentionMode = emuPinRetentionEm4Exit;
    EMU_EM4Init(&em4init);

  // Setup PF7 as input with pull-up enabled EM4
  GPIO_PinModeSet(gpioPortF, 7, gpioModeInputPullFilter, 1);

  /*
   * Make sure PF7 still isn't low from the button push responsible for
   * wake-up from EM4, then enable GPIO_ODD interrupt on rising edge.
   */
  while (!GPIO_PinInGet(gpioPortF, 7));
  GPIO_IntClear(0x0080);
  NVIC_EnableIRQ(GPIO_ODD_IRQn);
  GPIO_IntConfig(gpioPortF, 7, true, false, true);

  // Wait for rising edge of PF7 (button 1)
  EMU_EnterEM3(false);

  // Turn on LED1 (stays lit in EM4)
  GPIO_PinOutSet(gpioPortF, 5);

  // Enable EM4 wake on PF7 low
  GPIO_EM4EnablePinWakeup(0x2 << _GPIO_EM4WUEN_EM4WUEN_SHIFT, 0);

  // Go into EM4 and wait for button 1 wake; LED(s) will be off
  EMU_EnterEM4();
}

void GPIO_ODD_IRQHandler(void)
{
  // Clear GPIO_ODD interrupt for PF7
  GPIO_IntClear(0x0080);
}

 

John

 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> tj
Posts: 40
Registered: ‎07-04-2016

Re: EFR32MG - EM4 wakeup pins ?

Hello JohnB

 

You code is working, my too with small modification. I can wake up from EM4H by external pin

There is problem with full reset after exiting from EM4H.

 

I have chcecked resetCause with 3 leds, LEDC has never been active.

 

 

 uint32_t resetCause = RMU_ResetCauseGet();
RMU_ResetCauseClear();

if ((resetCause & RMU_RSTCAUSE_PORST) || (resetCause & RMU_RSTCAUSE_EXTRST) || (resetCause & RMU_RSTCAUSE_SYSREQRST))
ledOn(LEDA);
if (resetCause & RMU_RSTCAUSE_AVDDBOD ) //|| resetCause & RMU_RSTCAUSE_DVDDBOD || resetCause & RMU_RSTCAUSE_DECBOD)
ledOn(LEDB);
if (resetCause & RMU_RSTCAUSE_EM4RST)
ledOn(LEDC);

 

After power on - LEDA works

after reset - LEDA and LEDB

after EM4H wakeup - LEDB

 

 

I have found EMU_E208 in EFR32MG1 errata: Occasional Full Reset After Exiting EM4H

 

The work around is to disable the BOD prior to EM4H entry by doing the following sequence:
// Unlock access to emu test registers
EMU->TESTLOCK = EMU_TESTLOCK_LOCKKEY_UNLOCK;
// Mask the BOD outputs to avoid resets
EMU->TESTCTRL |= EMU_TESTCTRL_BOD_MASK;

 

 

EMU don't have TESTLOCK and TESTCTRL registers. I have removed TEST word, EMU->LOCK and EMU-CTRL egists.
I can unlock EMU configuration, but EMU->CTRL don't have BOD bit for configuration.
How to disable EM4BOD protection ?

 

 

<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> tj
Posts: 40
Registered: ‎07-04-2016

Re: EFR32MG - EM4 wakeup pins ?

after EM4S wakeup - LEDC works correctly.

Posts: 260
Registered: ‎09-18-2015

Re: EFR32MG - EM4 wakeup pins ?

Hi tj,

 

Regarding EMU_E208, the workaround for this is already handled in the EMU_EnterEM4() function. Check the source below:

 

#if defined( _EMU_EM4CTRL_MASK ) && defined( ERRATA_FIX_EMU_E208_EN )
  if (EMU->EM4CTRL & EMU_EM4CTRL_EM4STATE_EM4H)
  {
    /* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H.
     * Full description of errata fix can be found in the errata document. */
    *(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0000ADE8UL;
    *(volatile uint32_t *)(EMU_BASE + 0x198) |= (0x1UL << 7);
  }
#endif

In general, errata requiring software workarounds are accounted for in emlib, to the best of my knowledge (haven't found one yet that isn't).

 

John

Highlighted
<a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Ninja</font></font> </a> tj
Posts: 40
Registered: ‎07-04-2016

Re: EFR32MG - EM4 wakeup pins ?

Hello JohnB

 

Thank you for reply.

Correct fix is here. Now my wake up from EM4H is working correctly. Robot wink

#if defined( _EMU_EM4CTRL_MASK ) && defined( ERRATA_FIX_EMU_E208_EN ) 
if (EMU->EM4CTRL & EMU_EM4CTRL_EM4STATE_EM4H) 
{ 
/* Fix for errata EMU_E208 - Occasional Full Reset After Exiting EM4H. 
* Full description of errata fix can be found in the errata document. */ 
__disable_irq(); 
*(volatile uint32_t *)(EMU_BASE + 0x190) = 0x0000ADE8UL; 
*(volatile uint32_t *)(EMU_BASE + 0x198) |= (0x1UL << 7); 
*(volatile uint32_t *)(EMU_BASE + 0x88) |= (0x1UL << 8); 
} 
#endif 

 

Posts: 2,736
Registered: ‎02-07-2002

Re: EFR32MG - EM4 wakeup pins ?

@JohnB,

 

If TJ is onto something here, it would be nice to have it confirmed by you (or some other SiLabs employee) here. It seems he claims a third fix is required.

Posts: 260
Registered: ‎09-18-2015

Re: EFR32MG - EM4 wakeup pins ?

@vanmierlo,

 

We appear to have added the third register write in emlib 5.0.0.0; it's not there in 4.4.1 and 4.4.0.

 

I'm not sure what it does, however, because my example code for pin wake-up on Jade, Pearl, Mighty, etc. runs fine using emlib 4.4.0 as does other code I've written to demonstrate EM4 and wake-up using the CRYOTIMER.

 

Looking at our internal documentation, that registers appears to have some test related functionality, but it's not clear to me what the bit being set does.

 

John