Skip to main content
kaloyan
Associate II
December 28, 2016
Solved

STM32L152C6 Enter STOP Mode

  • December 28, 2016
  • 2 replies
  • 1017 views
Posted on December 28, 2016 at 10:22

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.
    Best answer by kaloyan
    Posted on January 02, 2017 at 11:02

    Happy New Year!

    I used the sample provided with the StdLib. However it may not be enough for successful operation in STOP mode.

    I followed the posts of Hamed A from this url:

    http://www.onarm.com/forum/60050/

     

    The problem was the initialization of the GPIO ports.

    Here is the test code I used:

    main.c

    #include 'stm32l1xx_conf.h'

    #include 'stm32l1xx.h'

    void RTC_Config(void);

    int main(void)

    {

     RTC_Config();

     while (1)

      {

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |

                            RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOH | RCC_AHBPeriph_GPIOE

                            /* RCC_AHBPeriph_GPIOF | RCC_AHBPeriph_GPIOG*/, ENABLE);

      GPIO_InitTypeDef GPIO_InitStructure;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_Init(GPIOB, &GPIO_InitStructure);

      GPIO_Init(GPIOC, &GPIO_InitStructure);

      GPIO_Init(GPIOD, &GPIO_InitStructure);

      GPIO_Init(GPIOE, &GPIO_InitStructure);

      //GPIO_Init(GPIOF, &GPIO_InitStructure);

      //GPIO_Init(GPIOG, &GPIO_InitStructure);

      GPIO_Init(GPIOH, &GPIO_InitStructure);

       RTC_WakeUpCmd(ENABLE);

       PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);

       RTC_WakeUpCmd(DISABLE);

       GPIO_DeInit( GPIOA );

       GPIO_DeInit( GPIOB );

       GPIO_DeInit( GPIOC );

       GPIO_DeInit( GPIOD );

       GPIO_DeInit( GPIOE );

       GPIO_DeInit( GPIOH );

       while(1){}

      }

    }

    void RTC_Config(void)

    {

      NVIC_InitTypeDef  NVIC_InitStructure;

      EXTI_InitTypeDef  EXTI_InitStructure;

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

     PWR_UltraLowPowerCmd(ENABLE); //in order to switch off Vrefint

     PWR_FastWakeUpCmd(ENABLE); //don't wait for Vrefint

      /*!< Allow access to RTC */

      PWR_RTCAccessCmd(ENABLE);

      /*!< Reset RTC Domain */

      RCC_RTCResetCmd(ENABLE);

      RCC_RTCResetCmd(DISABLE);

     

      RCC_LSICmd(ENABLE);

      while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {}

      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

     

      /*

      RCC_LSEConfig(RCC_LSE_ON);

      while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}

      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

      */

      RCC_RTCCLKCmd(ENABLE);

      /*!< Wait for RTC APB registers synchronisation */

      RTC_WaitForSynchro();

      /* EXTI configuration *******************************************************/

      EXTI_ClearITPendingBit(EXTI_Line20);

      EXTI_InitStructure.EXTI_Line = EXTI_Line20;

      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

      EXTI_InitStructure.EXTI_LineCmd = ENABLE;

      EXTI_Init(&EXTI_InitStructure);

     

      /* Enable the RTC Wakeup Interrupt */

      NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

      NVIC_Init(&NVIC_InitStructure);

     

      /* RTC Wakeup Interrupt Generation: Clock Source: RTCDiv_16, Wakeup Time Base: 4s */

      RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);

      RTC_SetWakeUpCounter(0xFFFF);

      /* Enable the Wakeup Interrupt */

      RTC_ITConfig(RTC_IT_WUT, ENABLE);  

    }

    The interrupt function:

    void RTC_WKUP_IRQHandler(void)

    {

      if(RTC_GetITStatus(RTC_IT_WUT) != RESET)

      {

        RTC_ClearITPendingBit(RTC_IT_WUT);

        EXTI_ClearITPendingBit(EXTI_Line20);

      }

    }

    Note how the GPIO ports are deinitialized. Note also that you can try to include all the ports (to cover the MCUs with more pins) and this wouldn't lead to compile error. This however leads to higher current consumption (in case these ports doesn't exist in your MCU). That is why GPIOF and GPIOG are commented out. The same apply if you forget to deinitialize all the ports.

    After the wakeup timer expires you should init all the required pins. The GPIO_DeInit() resets them to their default values. With this code my debugger (st-link 2) sucessfully connects to the targer after the MCU woke up and I can reach the breakpoint at the while(1) {} loop.

    Good luck everyone!

    2 replies

    Nesrine M_O
    Associate
    December 28, 2016
    Posted on December 28, 2016 at 10:52

    Hi

    Mihaylov.Kaloyan

    ‌,

    you can start fromthe PWR STOP mode example under the

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

    :

    STM32L1xx_StdPeriph_Lib_V1.3.1\Project\STM32L1xx_StdPeriph_Examples\PWR\STOP

    This example shows how to enters the system to STOP mode and wake-up from thismode using RTC Wakeup Timer Event connected to EXTI Line

    -Nesrine-

    kaloyan
    kaloyanAuthorBest answer
    Associate II
    January 2, 2017
    Posted on January 02, 2017 at 11:02

    Happy New Year!

    I used the sample provided with the StdLib. However it may not be enough for successful operation in STOP mode.

    I followed the posts of Hamed A from this url:

    http://www.onarm.com/forum/60050/

     

    The problem was the initialization of the GPIO ports.

    Here is the test code I used:

    main.c

    #include 'stm32l1xx_conf.h'

    #include 'stm32l1xx.h'

    void RTC_Config(void);

    int main(void)

    {

     RTC_Config();

     while (1)

      {

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |

                            RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOH | RCC_AHBPeriph_GPIOE

                            /* RCC_AHBPeriph_GPIOF | RCC_AHBPeriph_GPIOG*/, ENABLE);

      GPIO_InitTypeDef GPIO_InitStructure;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_Init(GPIOB, &GPIO_InitStructure);

      GPIO_Init(GPIOC, &GPIO_InitStructure);

      GPIO_Init(GPIOD, &GPIO_InitStructure);

      GPIO_Init(GPIOE, &GPIO_InitStructure);

      //GPIO_Init(GPIOF, &GPIO_InitStructure);

      //GPIO_Init(GPIOG, &GPIO_InitStructure);

      GPIO_Init(GPIOH, &GPIO_InitStructure);

       RTC_WakeUpCmd(ENABLE);

       PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFE);

       RTC_WakeUpCmd(DISABLE);

       GPIO_DeInit( GPIOA );

       GPIO_DeInit( GPIOB );

       GPIO_DeInit( GPIOC );

       GPIO_DeInit( GPIOD );

       GPIO_DeInit( GPIOE );

       GPIO_DeInit( GPIOH );

       while(1){}

      }

    }

    void RTC_Config(void)

    {

      NVIC_InitTypeDef  NVIC_InitStructure;

      EXTI_InitTypeDef  EXTI_InitStructure;

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

     PWR_UltraLowPowerCmd(ENABLE); //in order to switch off Vrefint

     PWR_FastWakeUpCmd(ENABLE); //don't wait for Vrefint

      /*!< Allow access to RTC */

      PWR_RTCAccessCmd(ENABLE);

      /*!< Reset RTC Domain */

      RCC_RTCResetCmd(ENABLE);

      RCC_RTCResetCmd(DISABLE);

     

      RCC_LSICmd(ENABLE);

      while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {}

      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

     

      /*

      RCC_LSEConfig(RCC_LSE_ON);

      while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}

      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

      */

      RCC_RTCCLKCmd(ENABLE);

      /*!< Wait for RTC APB registers synchronisation */

      RTC_WaitForSynchro();

      /* EXTI configuration *******************************************************/

      EXTI_ClearITPendingBit(EXTI_Line20);

      EXTI_InitStructure.EXTI_Line = EXTI_Line20;

      EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

      EXTI_InitStructure.EXTI_LineCmd = ENABLE;

      EXTI_Init(&EXTI_InitStructure);

     

      /* Enable the RTC Wakeup Interrupt */

      NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

      NVIC_Init(&NVIC_InitStructure);

     

      /* RTC Wakeup Interrupt Generation: Clock Source: RTCDiv_16, Wakeup Time Base: 4s */

      RTC_WakeUpClockConfig(RTC_WakeUpClock_RTCCLK_Div16);

      RTC_SetWakeUpCounter(0xFFFF);

      /* Enable the Wakeup Interrupt */

      RTC_ITConfig(RTC_IT_WUT, ENABLE);  

    }

    The interrupt function:

    void RTC_WKUP_IRQHandler(void)

    {

      if(RTC_GetITStatus(RTC_IT_WUT) != RESET)

      {

        RTC_ClearITPendingBit(RTC_IT_WUT);

        EXTI_ClearITPendingBit(EXTI_Line20);

      }

    }

    Note how the GPIO ports are deinitialized. Note also that you can try to include all the ports (to cover the MCUs with more pins) and this wouldn't lead to compile error. This however leads to higher current consumption (in case these ports doesn't exist in your MCU). That is why GPIOF and GPIOG are commented out. The same apply if you forget to deinitialize all the ports.

    After the wakeup timer expires you should init all the required pins. The GPIO_DeInit() resets them to their default values. With this code my debugger (st-link 2) sucessfully connects to the targer after the MCU woke up and I can reach the breakpoint at the while(1) {} loop.

    Good luck everyone!