cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152C6 Enter STOP Mode

kaloyan
Associate III
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.
1 ACCEPTED SOLUTION

Accepted Solutions
kaloyan
Associate III
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!

View solution in original post

2 REPLIES 2
Nesrine M_O
Lead II
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
Associate III
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!