cancel
Showing results for 
Search instead for 
Did you mean: 

Exit STOP mode only works with WFE and not with WFI

Professional
Senior

Hello, i use RTC to exit STOP1 mode (tick disable) , the only way is to call HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFE);

HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI); doesn't work.

Have you any idea why ?

thanks

regards

8 REPLIES 8
turboscrew
Senior III

There's very little info in your post.

First: I assume that it doesn't wake up at all?

Which device do you have?

What should wake it up? The RTC wakeup timer? Have you configured it?

I recall that there was some setting to specially route WUT-interrupt to wakeup cirquits, but can't find it now...

Professional
Senior

Hello,

thank you for your reply

Yes it doesn't wake up at all, i use STM32L475RE, and i wake it with RTC ;

using PWR_STOPENTRY_WFI doesn't work; using PWR_STOPENTRY_WFE paremeter is OK (CPU wakes up after 10s as programmed).

Have you any clues ?

Here's the code :

   HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);

   HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 10000, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

   HAL_SuspendTick();

   EXTI->PR1 |= 0xFFFFFFFF; //(1<<i);

   EXTI->PR2 |= 0xFFFFFFFF; //(1<<i);

   /* Enter STOP 1 mode */

   HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFE);

   MA_SYSCLKConfig_STOP();

   HAL_ResumeTick();

Best regards

turboscrew
Senior III

This is how I did it with blue pill (F103) and without HAL. I think it works very much alike - at least it did with L476. I can't access that code anymore (I work for a different company now).

void go_standby(void)
{
	volatile uint32_t *rcc, *pwr, *bkp, *rtc, *scb, *syst, *nvic;
	// rcc = (uint32_t *) RCC_BASE;
	pwr = (uint32_t *) PWR_BASE;
	bkp = (uint32_t *) BKP_BASE;
	rtc = (uint32_t *) RTC_BASE;
	scb = (uint32_t *) SCB_BASE;
	syst = (uint32_t *) SYSTIC_BASE;
	nvic = (uint32_t *) NVIC_BASE;
 
	/* TODO: save data over standby */
	// bkp[BKP_DATA2] = ... // store data
 
	/* stop systick interrupts */
	syst[SYST_CSR] &= ~0x00000002;
 
	/* clear RSF, OWF, ALRF, SECF */
	rtc[RTC_CRL] &= 0xfffffff0;
	/* wait until RTC second event flag */
	while (rtc[RTC_CRL] & 0x00000001);
	/* clear RSF, OWF, ALRF, SECF */
	rtc[RTC_CRL] &= 0xfffffff0;
 
#ifdef RTC_WAKEUP
	/* wait for last write to finish (RTOFF) */
	while (!(rtc[RTC_CRL] & (uint32_t) 0x00000020));
	rtc[RTC_CRL] = 0x00000010; /* enter CNF */
	/* sleeptime */
	rtc[RTC_ALRH] = rtc[RTC_CNTH]; // high 16 bits
	rtc[RTC_ALRL] = rtc[RTC_CNTL] + 0x0000001e; // 30 sec, low 16 bits
	rtc[RTC_CRL] = 0x00000000; /* exit CNF */
 
	/* wait for synchronization (RSF) (can last a minute) */
    rtc[RTC_CRL] &= (uint32_t) 0xfffffff7; /* mark not synced */
	while (!(rtc[RTC_CRL] & (uint32_t) 0x00000008));
 
	/* wait for last write to finish (RTOFF) */
	while (!(rtc[RTC_CRL] & (uint32_t) 0x00000020));
 
	//rtc[RTC_CRH] |= 0x00000002; // enable alarm interrupt - must NOT do
#endif
 
#ifdef WKUP_WAKEUP
	/* enable wakeup by WKUP-pin */
	pwr[PWR_CSR] |= 0x00000100; // enable WKUP-pin
#endif
 
	/* clear all pending interrupts */
	nvic[NVIC_ICPR_0] = 0xffffffff;
	nvic[NVIC_ICPR_1] = 0xffffffff;
	nvic[NVIC_ICPR_2] = 0xffffffff;
 
	/* SEVONPEND = 0, SLEEPONEXIT = 0, DEEPSLEEP = 1 */
	scb[SCB_SCR] = 0x00000004;
	/* clear CSBF and CWUF, PDDS = standby */
	pwr[PWR_CR] = (pwr[PWR_CR] & 0xfffffff0) | 0x0000000e;
 
#if 1
	// dsb is probably a good idea before wfi
	asm volatile (
		"dsb\n\t"
		"wfi\n\t"
	);
#else
	// check that timer alarm works before trying actual sleep
	while (!(rtc[RTC_CRL] & 0x00000002)); // wait for RTC alarm
	/* start systick interrupts */
	syst[SYST_CSR] |= 0x00000002;
#endif
}

turboscrew
Senior III

Oh, and this example puts the blue pill in standby, but the L476 used the stop2 mode.

turboscrew
Senior III

I wonder if it was this:

//rtc[RTC_CRH] |= 0x00000002; // enable alarm interrupt - must NOT do

I wonder if this setting routed the WUT to NVIC instead of wakeup cirquit. I recall that there was such a setting...

[edit]

No, this applies to stdby-mode, when the EXTI is not powered.

turboscrew
Senior III

And, BTW, debug doesn't let the sleeping to take place, unless you specifically allow it (DBG_STOP). Also, a single pending event or interrupt makes the processor to execute wfi as nop.

Looks like you are using WUT, not alarm.

turboscrew
Senior III

Check the "5.3.11 Auto-wakeup from low-power mode" in the RM0351 (reference manual).

The wakeup from stop mode seems to be different in that the WUT needs to get to NVIC:

"To wakeup from Stop mode with an RTC wakeup event, it is necessary to:

• Configure the EXTI Line 20 to be sensitive to rising edge

• Configure the RTC to generate the RTC alarm"

I think it's the EXTI setting that defines whether event or interrupt is generated.

Looks like SEVONPEND has to be 0 and the interrupt needs to be enabled in NVIC (EXTI line 20).