cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152 Exit from Stop Mode

s0071904
Associate II
Posted on July 01, 2016 at 16:55

Hello,

I'm having issues getting my device to wake from stop mode using the RTC wake interrupt. I'm using the tickless idle function of FreeRTOS v9.0.0 to place the MCU into low power mode and I'm using the RTC wake interrupt to generate a periodic interrupt to wake from low power mode.

  /***** My function to enter low power mode, called from FreeRTOS *****/

  void BSP_Power_EnterLowPowerMode( void )

  {

    /* Switch on file-scope variable to choose sleep mode */

    switch(BSP_LowPowerMode)

    {

    case LOW_POWER_SLEEP:

      PWR_EnterSleepMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );

      break;

    

    case STOP_MODE:

      PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_STOPEntry_WFI ) ;

    

    default:

      BSP_ASSERT(false);

      break;

    }

  }

  /**********/

Inside the RTC wake ISR, I wake a suspended FreeRTOS task. This task resets the internal watchdog timer and then places itself in suspended state. This allows my application to periodically wake and reload the internal watchdog to avoid a watchdog timeout and device reset.

  /***** My ISR *****/

  void RTC_WKUP_IRQHandler(void)

  {

    if(RTC_GetITStatus(RTC_IT_WUT) != RESET)

    {

      /* Clear RTC and EXTI interrupt flags */

      RTC_ClearITPendingBit(RTC_IT_WUT);

      EXTI_ClearITPendingBit(EXTI_Line20);

      

      /* Code to wake suspended task goes here*/

    } 

  }

  

  /**********/

  /***** My Task *****/

  

  void SLP_Task( void *pvParameters )

  {

    while(1)

    {

      /* Reload the IWDG timeout */

      BSP_WDG_Checkin();

      /* Do Stuff */

      /* Send this task to suspended state */

      vTaskSuspend(TaskHandle);

    }

  }

If I use Low Power Sleep mode everything works fine, my interrupt occurs periodically and the MCU exits sleep mode and resets the IWDG.

If, however, I use Stop Mode my interrupt either doesn't occur or doesn't successfully bring the MCU out of stop mode. My device sits idle until the internal watchdog eventually times out causing a reset.

Can anyone give any advice as to what might be going wrong? Do I need to perform additional configuration of the interrupt, or on exit from stop mode, to get the device to wake which doesn't need to be performed for low power sleep?

Thanks
2 REPLIES 2
Walid FTITI_O
Senior II
Posted on July 04, 2016 at 13:53

Hi JoeEmerson,

Check if you have enabled both wakeup counter and wakeup interrupt, before entering stop mode, like the following:

/* Enable Wakeup Counter */ 
RTC_WakeUpCmd(ENABLE); 
/* Enable the Wakeup Interrupt */ 
RTC_ITConfig(RTC_IT_WUT, ENABLE);

Otherwise, I recommned you to check the ''STOP'' example in the

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32-standard-peripheral-libraries/stsw-stm32html

, and compare with your code and configuration. example is at this path : STM32L1xx_StdPeriph_Lib_V1.3.1\Project\STM32L1xx_StdPeriph_Examples\PWR\STOP -Hannibal-
s0071904
Associate II
Posted on July 05, 2016 at 18:19

Hi Hannibal,

Thanks for your advice. After looking at the peripheral library examples I've seen that I wasn't re-configuring my system clock following wake from stop mode (according to ST documentation the system clock defaults to MSI on wake from stop mode).

I have changed my code for entry to/exit from stop mode as follows:

  /***** Entry to stop mode *****/

  PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_STOPEntry_WFI ) ;

  /* Function generated by ST clock configuration tool to setup clocks */

  SystemInit();

After making this change I am able to observe the RTC wakeup interrupt bringing the MCU out of sleep mode. However, this only happens once rather than periodically. The only way I have been able to achieve a periodic wakeup has been to reset and reconfigure the RTC on each wake from stop mode ( using RCC_RTCResetCmd() and then re-configuring the RTC clock and interrupt ) which doesn't seem to be an ideal solution.

Thanks again for your help, if I manage to find a better solution I'll add an update.