cancel
Showing results for 
Search instead for 
Did you mean: 

Issues waking up from Stop2 mode using interrupt on STM32WB55

JayDev
Senior II

Hello!

I'm trying to put my project into Stop2 mode (so it can only be woken up by 1 of 5 wakeup pins) on an STM32WB55 Nucleo board. I have an external signal that starts low and goes high to generate an interrupt. I've tried various approaches to code and I can't seem to get my code to wake it up after entering sleep mode (which I assume is happening based solely on LED outputs).

Based on all the variations I've tried, I assume it's because I'm not setting up the interrupt pin correctly.

Here's my *.ioc file showing that I have wakeup pin 2 (PC13) setup for my interrupt:

0693W00000AOymNQAT.jpg 

Below is the code I'm running in main:

Enter_Sleep_Mode();
Exit_Sleep_Mode();

Below is the code for the above functions (with various attempts commented out to show some of the things I've tried):

void Enter_Sleep_Mode(void)
{
	BSP_LED_On(LED_RED);
	//HAL_EnableDBGStopMode();
 
	/* Disable WKUP pin */
	HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN1 );
	HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN2 );
	HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN3 );
	HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN4 );
	HAL_PWR_DisableWakeUpPin( PWR_WAKEUP_PIN5 );
 
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
 
	/* Enable WKUP pin */
	//HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN2);
	//HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN3);
	//HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4);
	//HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN5);
 
	/* Clearing the bit as per the reference manual to enter into STOP2 mode*/
	//CLEAR_BIT(PWR->CR1, PWR_CR1_LPR);
 
	//__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
 
	 //osDelay(1000); /* Put delay before going to shut down */
	//HAL_Delay(1000); /* Put delay before going to shut down */
 
	//HAL_SuspendTick();
	//HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON,PWR_STOPENTRY_WFI);
	HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
	//SystemClock_Config();
	//HAL_ResumeTick();
}
 
void Exit_Sleep_Mode( void )
{
	BSP_LED_Init(LED_BLUE);
	BSP_LED_On(LED_BLUE);
 
	SYSCLK_Resume_After_STOP();
 
	BSP_LED_Init(LED_GREEN);
	BSP_LED_On(LED_GREEN);
}
 
/**
  * @brief  Configures system clock after wake-up from STOP: enable MSI, PLL
  *         and select MSI as system clock source.
  * @param  None
  * @retval None
  */
void SYSCLK_Resume_After_STOP(void)
{
	  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
	  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
	  uint32_t pFLatency = 0;
 
	  /* Get the Oscillators configuration according to the internal RCC registers */
	  HAL_RCC_GetOscConfig(&RCC_OscInitStruct);
 
	  /* After wake-up from STOP reconfigure the system clock: Enable MSI and PLL */
	  RCC_OscInitStruct.OscillatorType  = RCC_OSCILLATORTYPE_MSI;
	  RCC_OscInitStruct.MSIState        = RCC_MSI_ON;
	  RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
	  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	  {
	    Error_Handler();
	  }
 
	  /* Get the Clocks configuration according to the internal RCC registers */
	  HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &pFLatency);
 
	  /* Select MSI as system clock source */
	  RCC_ClkInitStruct.ClockType     = RCC_CLOCKTYPE_SYSCLK;
	  RCC_ClkInitStruct.SYSCLKSource  = RCC_SYSCLKSOURCE_MSI;
	  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, pFLatency) != HAL_OK)
	  {
	    Error_Handler();
	  }
}

I think I'm pretty close but I'm clearly missing something important (like maybe I'm calling a function with the wrong argument, I'm not setting up my interrupt correctly, need to set the polarity of my interrupt, etc).

Any ideas what I might be missing? Thanks!

2 REPLIES 2
Piranha
Chief II

Maybe your signal source is open-drain and needs a pull-up? Internal ones can be enabled in PWR_PUCRC.

Also PC13 can be "taken over" by RTC. Check for that.

Thanks for the direction! I tried tying +3.3V to the signal line (in case that was the issue) and that didn't resolve it, unfortunately. I did find that option for RTC to take over but, at present, I don't have an RTC running (not sure if that needs to be running, I'm not using it as I'm not trying to wake it with the RTC, I'm trying to wake it with the wake pin (PC13).

To try and reduce the number of variables, I started a new project and I eventually got it working (potentially) but I had to set the pin to be an interrupt (GPIO_EXTI13) rather than a wakeup pin (SYS_WAKEUP_2) in the *.ioc file. I don't have my multimeter with me right now so I can't verify it's going into STOP2 mode (though it appears to be going into some kind of sleep mode) but I'm a bit confused that it should even work as an interrupt rather than a wake pin.

The datasheet says the following about waking with GPIO pins in STOP2 mode (pg 38 of the datasheet):

 I/Os with wakeup from Standby/Shutdown capability: PA0, PC13, PC12, PA2, PC5

Bah, I'm an idiot, it WILL work with interrupts in Stop2 mode, I was originally looking at the wakeup as I was considering using Shutdown mode at one point. I'll have to take another look at that in case I do want to get it to work in shutdown mode down the road (I think it might create more problems than it's worth though as it force me to reinitialize a number of variables that I need, so it'll be a pretty slow startup.

The code I used is below (for anyone who might run into the same issues I did):

void Run_Stop_Mode()
{
   for (int i=0; i<20; i++)
   {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
    HAL_Delay (200);
   }
 
   char *str = "ABOUT TO GO INTO THE STOP MODE\r\n";
 
   HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen (str), HAL_MAX_DELAY);
 
   /****** Suspend the Ticks before entering the STOP mode or else this can wake the device up **********/
   HAL_SuspendTick();
 
   /* Enter Stop Mode */
   //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
   HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
 
   SystemClock_Config();
   HAL_ResumeTick();
 
   for (int i=0; i<5; i++)
   {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
    HAL_Delay(1000);
   }
 
   char *str2 = "WAKEUP FROM STOP MODE in the MAIN LOOP\r\n";
   HAL_UART_Transmit(&huart1, (uint8_t *)str2, strlen (str2), HAL_MAX_DELAY);
}

There's obviously a lot of extra stuff that isn't needed there (LEDs, UART, etc) but the basic functionality is really only about 4 lines of code, which is nice. It'll obviously be more if I decide to shut down additional unneeded peripherals.

I got a lot of help from the following video, if anyone needs some help setting it up. It was with a different chip initially so I had to make some mods but the *.ioc framework is so straight forward, it was easy to do.

https://www.youtube.com/watch?v=UtQhc4XV8k4&t=139s

Thanks, @Piranha​ !