cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 stop mode problem (WFE)

arnold2
Associate II
Posted on January 30, 2013 at 15:17

Hi,

we have a problem with the STOP mode of the STM32F3. We have the feeling, that the F3 immediately returns from STOP mode, if ANY interrupt is enabled and has been activated before entering the STOP mode. The second entry into STOP mode is working (does not return without an event). We have a little demo for the STM32F3DISCOVERY board, that demonstrates this behaviour (the main.c is attached).

To provoke the error, do the following:

1. disable (''comment-out'') the second WFE in line 58

2. Build and run the project

3. Press and release the button. Nothing to be seen, but in fact the LED is switched on and off very fast (can be seen with an osci; the same signal is on PA3 for verfication).

With the following change the error could be ''worked around'' (at least in my tests):

1. Enable the 2nd WFE and all following NOPs

2. Build and run the project

3. Press and Release the button.  After releasing the button the blue LED is switched on, the MCU is in STOP mode now.

4. Press and release the button. The MCU wakes up, the LED is switched off.

Another problem occurs, if you remove the 4 NOPs after the 2nd WFE. Then the core goes into hardfault handler.

With an STM32F1 and L1 we don't have these problems! Can anyone else confirm this behaviour and/or has an explanation for it? Any general comments and hints related to the STOP mode especially with the STM32F3xx are appreciated. Has anyone the STOP mode of the STM32F3 working??

thanks in advance,

Ren�

#stm32f3-stop-mode-problem-wfe
16 REPLIES 16
arnold2
Associate II
Posted on February 06, 2013 at 16:13

Nobody using the STOP mode of the STM32F3????

Posted on February 06, 2013 at 20:29

Nobody using the STOP mode of the STM32F3????

To your rhetorical question, the forum says loudly that no one is indeed using it. Is anyone using the F3 participating?

I personally prefer WFI. The F4 has an errata related to WFE and Debug Mode and it's interaction with subsequent instructions.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
arnold2
Associate II
Posted on February 07, 2013 at 08:00

Thank for your hint related to the F4, but no that's not our problem. The behaviour described above is there with or without connected debugger. I have noticed some ''strange'' behaviour related to the instructions following immediately the WFE in te F3 too (that's why my sample code contains the NOPs after the WFE), but that's another (minor) problem.

We are using WFE instead of WFI to further decrease current while sleeping. WFI is used in our main loop to stop the core until the next interrupt occurs (timer, SPI, etc.). But with WFE we bring our device into a state, where it consumes minimum power and wakeup is only possible with a falling edge of 1 dedicated signal.

lowpowermcu
Associate II
Posted on February 07, 2013 at 10:32

Hi arnold.rene,

Did you look in ST examples within PWR folder?

arnold2
Associate II
Posted on February 08, 2013 at 07:42

Yes, I did. But all examples there are entering power down mode with WFI, but we are using WFE.

lowpowermcu
Associate II
Posted on February 13, 2013 at 10:16

Hi arnold,

Here is an example of using WFE with EXTI. Hope that helps you.

int main(void)

{

 /*!< At this stage the microcontroller clock setting is already configured,

       this is done through SystemInit() function which is called from startup

       file (startup_stm32f37x.s) before to branch to application main.

       To reconfigure the default setting of SystemInit() function, refer to

       system_stm32f37x.c file

     */

  /* Configure PA0 in interrupt mode */

  EXTI0_Config();

 

  /* Configure LEDs */

  STM_EVAL_LEDInit(LED1);

  STM_EVAL_LEDInit(LED2);

 STM_EVAL_LEDInit(LED4);

 

  /* SysTick interrupt each 10 ms */

  if (SysTick_Config(SystemCoreClock / 100))

  {

    /* Capture error */

    while (1);

  }

  /* LED1 On */

  STM_EVAL_LEDOn(LED1);

  /* Request to enter STOP mode with regulator in low power mode */

  PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);

 

  /* LED1 On */

  STM_EVAL_LEDOn(LED2);

 

  while(1)

  {

  }

}

/**

  * @brief  Configure PA0 in interrupt mode

  * @param  None

  * @retval None

  */

static void EXTI0_Config(void)

{

  EXTI_InitTypeDef   EXTI_InitStructure;

GPIO_InitTypeDef   GPIO_InitStructure;

  /* Enable GPIOA clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

 

  /* Configure PA0 pin as input floating */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Enable SYSCFG clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

 

  /* Connect EXTI0 Line to PA0 pin */

  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

  /* Configure EXTI0 line */

  EXTI_InitStructure.EXTI_Line = EXTI_Line0;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_Init(&EXTI_InitStructure);

}

      

arnold2
Associate II
Posted on February 13, 2013 at 12:14

Thank your for your response!

But with your code I get (nearly) exactly the behaviour I described above. My Environment is as follows: Crossworks 2.1, F3Discoveryboard (so I have modified your example a bit to run it on the DISCOVERY board (changed the LED code)).

If I enable the tick counter, both LEDs turn on immediately after reset. Only if I do NOT start the systick counter, the WFE command keeps the device in STOP mode until the button is pressed. If the systick counter is enabled (and generates interrupts), PWR_EnterSTOPMode() returns immediately (tested with disconnected debugger).

So if you get different (correct / expected) behaviour, the reasons could be the following:

1. Your startup code is different from mine and the systick counter has not yet generated an interrupt at the time the WFE is executed. Could you please check this by inserting code, that checks, if the systick interrupt has occured at least once before calling PWR_EnterSTOPMode()??

You would need the following additional code:

volatile unsigned long ticks = 0;

void SysTick_Handler(void)

{

    ticks++;

}

And before calling PWR_EnterSTOPMode():

/* wait until at least 1 systick interrupt occured */

while( ticks == 0 );

2. The startup code itself makes the MCU behave as described by me (for some yet unknown reason). Could you please tell me, what toolchain you are using??? And could you post your startup code here? (hope that's legal???)

René

lowpowermcu
Associate II
Posted on February 13, 2013 at 14:53

Hi René,

I am using EWARM as toolchain with nothing special in the start-up (the same

file delivered by ST).

Just two questions:

  1. Are you using DBGMCU_Config() in your code?

  2. Are you performing a power-off/power-on sequence with debugger probe disconned?

Thank your for your response!

But with your code I get (nearly) exactly the behaviour I described above. My Environment is as follows: Crossworks 2.1, F3Discoveryboard (so I have modified your example a bit to run it on the DISCOVERY board (changed the LED code)).

If I enable the tick counter, both LEDs turn on immediately after reset. Only if I do NOT start the systick counter, the WFE command keeps the device in STOP mode until the button is pressed. If the systick counter is enabled (and generates interrupts), PWR_EnterSTOPMode() returns immediately (tested with disconnected debugger).

So if you get different (correct / expected) behaviour, the reasons could be the following:

1. Your startup code is different from mine and the systick counter has not yet generated an interrupt at the time the WFE is executed. Could you please check this by inserting code, that checks, if the systick interrupt has occured at least once before calling PWR_EnterSTOPMode()??

You would need the following additional code:

volatile unsigned long ticks = 0;

void SysTick_Handler(void)

{

    ticks++;

}

And before calling PWR_EnterSTOPMode():

/* wait until at least 1 systick interrupt occured */

while( ticks == 0 );

2. The startup code itself makes the MCU behave as described by me (for some yet unknown reason). Could you please tell me, what toolchain you are using??? And could you post your startup code here? (hope that's legal???)

René

arnold2
Associate II
Posted on February 14, 2013 at 09:41

1. I am not using DBGMCU_Config()

2. Yes, I have power-cycled the target without debug probe connected.

I have tested your example with IAR and it works. BUT: it only works, because no interrupt has occured at the time PWR_EnterStop() is called. If I wait for the SysTick interrupt to occur before calling PWR_EnterStop(), PWR_EnterStop() returns immediately.

The main.c below is a modified version of the one you posted above. With this modification PWR_EnterStop() returns immediately. I have tested it without connected debug probe. Both LEDs are switched on immediately after reset.

main.c:

#include ''stm32373c_eval.h''

static void EXTI0_Config(void);

void SysTick_Handler(void);

volatile unsigned long ticks = 0;

unsigned long tick_counter_after_wakeup = 0xFFFFFFFF;

void SysTick_Handler(void)

{

    ticks++;

}

int main(void)

{

 /*!< At this stage the microcontroller clock setting is already configured,

       this is done through SystemInit() function which is called from startup

       file (startup_stm32f37x.s) before to branch to application main.

       To reconfigure the default setting of SystemInit() function, refer to

       system_stm32f37x.c file

     */

  /* Configure PA0 in interrupt mode */

  EXTI0_Config();

  /* Configure LEDs */

  STM_EVAL_LEDInit(LED1);

  STM_EVAL_LEDInit(LED2);

 STM_EVAL_LEDInit(LED4);

  /* SysTick interrupt each 10 ms */

  if (SysTick_Config(SystemCoreClock / 100))

  {

    /* Capture error */

    while (1);

  }

  /* LED1 On */

  STM_EVAL_LEDOn(LED1);

  /* wait until at least 1 systick interrupt occured */

  while( ticks == 0 );

  /* Request to enter STOP mode with regulator in low power mode */

  PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_STOPEntry_WFE );

  tick_counter_after_wakeup = ticks;

  /* LED1 On */

  STM_EVAL_LEDOn(LED2);

  while(1)

  {

  }

}

 

/**

  * @brief  Configure PA0 in interrupt mode

  * @param  None

  * @retval None

  */

static void EXTI0_Config(void)

{

    EXTI_InitTypeDef   EXTI_InitStructure;

    GPIO_InitTypeDef   GPIO_InitStructure;

    /* Enable GPIOA clock */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    /* Configure PA0 pin as input floating */

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Enable SYSCFG clock */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

    /* Connect EXTI0 Line to PA0 pin */

    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

    /* Configure EXTI0 line */

    EXTI_InitStructure.EXTI_Line = EXTI_Line0;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

}

Do you get the behaviour I described, with this modification (while( ticks == 0 )) in your environment too?

René