cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401 Stop Mode entry

jesper2
Associate II
Posted on April 11, 2016 at 13:32

Hello,

I'm currently working on an application in which I need to put the MCU into the STOP mode, being able to wake it up by means of an EXTI. However, I'm having difficulties putting the MCU to STOP using __WFI(). It works properly when calling __WFE(); __WFE(); (twice).

According to Table 19 in the reference manual the following needs to be performed before trying to enter into Stop, otherwise the instruction will be ignored:

Note: To enter stop mode, all EXTI line pending bits in EXTI_PR, all peripheral interrupts pending bits, the RTC alarms (A and B), RTC Wakeup, RTC Tamper, and RTC TimeStamp flags, must be reset. Otherwise, the Stop mode entry procedure is ignored and program execution continues.

As far as I can understand, I perform these steps, but the device still ignores the __WFI() instruction.

Has anyone had similar problems with this or can understand where I'm missing the point?

/* STOP mode entry procedure from RM Table 19.

 * ==========================================================

 * Note: To enter stop mode, all EXTI line pending bits in

 * EXTI_PR, all peripheral interrupts pending bits, the RTC

 * alarms (A and B), RTC Wakeup, RTC Tamper, and RTC TimeStamp

 * flags, must be reset. Otherwise, the Stop mode entry

 * procedure is ignored and program execution continues. */

/* Disable the SysTick */

SysTick->CTRL  = 0;

/* Clear any pending EXTI */

EXTI->PR = 0xFFFFFFFF;

/* Clear any pending peripheral interrupts */

for (i = 0; i < 8; i++) {

    NVIC->ICPR[i] = 0xFFFFFFFF;

}

/* Clear the RTC pending flags */

RTC->ISR &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF | RTC_ISR_WUTF | RTC_ISR_TSF | RTC_ISR_TAMP1F);

/* 1. Set the SLEEPDEEP bit in FPU System Control register.

 * From PM:

 * 1: Deep sleep. */

SCB->SCR |= (1 << SCB_SCR_SLEEPDEEP_Pos);

/* 2. Clear PDDS bit in power control register

 * From RM:

 * 0: Enter stop mode when CPU enters deepsleep.

 * The regulator status depends on the LPDS bit */

PWR->CR &= ~(PWR_CR_PDDS);

/* 3. Select the voltage regulator mode by configuring LPDS bit in PWR_CR.

 * From RM:

 * 1: Low-power voltage regulator on during stop mode */

PWR->CR |= PWR_CR_LPDS;

/* Perform a wait-for-interrupt */

__WFI();

Sincerely,

Jesper

#low-power #stm32f401
6 REPLIES 6
Nesrine M_O
Lead II
Posted on April 11, 2016 at 14:33

Hi Jesper,

I suggest you to have a look to the PWR_STOP example: STM32F4xx_DSP_StdPeriph_Lib_V1.6.1\Project\STM32F4xx_StdPeriph_Examples\PWR\PWR_STOP

The example shows how to enter the system to STOP mode and wake-up from this mode using RTC Wakeup Timer Event.

-Syrine-

jesper2
Associate II
Posted on April 11, 2016 at 15:09

Thank you Syrine.

Unfortunately there is no difference between the example you linked and my own implementation. Do you have any other idea as to what might hinder the stop mode entry?

Sincerely,

Jesper

Posted on April 11, 2016 at 17:55

How are you testing this, in the debugger, or non-intrusively?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jesper2
Associate II
Posted on April 12, 2016 at 09:49

I've tried to test it both ways. When stepping through with the debugger it simply continues. I suspected that it was interfering somehow so I set up the controller to raise a pin when having booted up, then attempting to enter stop mode, and after that a softreset (after a couple of __NOP()). Then I could see that the controller continuously reset, indicating that the stop mode entry didn't have any effect.

wojciech239955
Associate II
Posted on April 19, 2017 at 12:22

I have the same problem but I use STM32F410RBT.

This problem occurs after the first interrupt from systick is called.

Up to this point, the program enters to STOP mode properly.

After the interrupt call (even blank interrupt without meaningful code), it does not enter to STOP, even I completely disable Systick timer.

wojciech239955
Associate II
Posted on April 20, 2017 at 15:53

I found solution. Enter to STOP in Cortex M4 required puts double WFE like in newest cube library STM32Cube_FW_F4_V1.15.0

    /* Request Wait For Event */

      __SEV();

      __WFE();

      __WFE();

But it is not described in any errata .