AnsweredAssumed Answered

Wake stm32l151 up from stop mode by way of USART

Question asked by David Rodenas on May 31, 2017
Latest reply on Jun 1, 2017 by Maxime TEISSIER

Hello everyone, 

 

I have looked up this issue but I am afraid I have been unable to find a solution. 

 

I am trying to wake a stm32l151CCT6 MCU up from stop mode by way of USART1 interrupt. I have the RXNE interrupt enabled (I am posting some of my code below) but I seem to never get an interrupt after entering stop mode. Separately, both the usart and enter to/wakeup from stop mode work. Is there something I am missing? If useful, I am using the stm32l1xx standard peripheral library 

 

Any help is much appreciated. 

 

My code below:

 

/* Enter stop mode */

void lpm_enter(void)

{

   /* Turn off LSE and HSE clocks */
   cpu_deinit();

   /* Disable the Power Voltage Detector */
   PWR_PVDCmd(DISABLE);

   /* Clear Wakeup flag */
   PWR->CR |= PWR_CR_CWUF;

   /* Set MCU in ULP (Ultra Low Power) */
   PWR_UltraLowPowerCmd(ENABLE);

   /* Enable the fast wake up from Ultra low power mode */
   PWR_FastWakeUpCmd(ENABLE);

   /* Enter STOP mode with regulator in low power mode */
   PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

}

/* Exit stop mode */

void lpm_exit(void)

{

extern void SetSysClock( void );

   /* Disable interrupts */
   dint(); 

   /* Reconfigure the system clocks */
   SetSysClock();

   /* RTC is used as system clock; Re-initialise */
   mcu_rtc_init();   

   /* Disable ULP (Ultra Low Power) */
   PWR_UltraLowPowerCmd(DISABLE); // add up to 3ms wakeup time

   /* Enable the Power Voltage Detector */
   PWR_PVDCmd(ENABLE);

   /* Set internal voltage regulator */
   PWR_VoltageScalingConfig( PWR_VoltageScaling_Range1 );

   /* Enable interrupts */

   eint();

}

/* USART1 configuration */

void
usart_init(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;

   

   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

 

   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);

 

   /* GPIO pin configuration */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure);

   

   /* Alternate function conf */
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
   GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

   

   /* USART conf */
   USART_InitStructure.USART_BaudRate = 115200;
   USART_InitStructure.USART_WordLength = USART_WordLength_8b;
   USART_InitStructure.USART_StopBits = USART_StopBits_1;
   USART_InitStructure.USART_Parity = USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
   USART_Init(USART1, &USART_InitStructure);

 

   /* Enable RXNE interrupt */
   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

   /* Enable USART1 global interrupt */
   NVIC_EnableIRQ(USART1_IRQn);

   

   USART_Cmd(USART1, ENABLE);
}

/* USARTx IRQHAndler */

void USART1_IRQHandler(void)
{
   if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
   {
      unsigned char x;

 

      /* Exit stop mode */

      lpm_exit();

     

      USART_ClearITPendingBit(USART1, USART_IT_RXNE);
      x = USART_ReceiveData(USART1);

 

      /* Loop until the end of reception */
      while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET);

      /* Handle input */

      if(usart_input_handler != NULL) usart_input_handler(x);
   }
}

 

Many thanks again

Outcomes