cancel
Showing results for 
Search instead for 
Did you mean: 

How to wake up STM32G070 on EXTI from stop1 mode?

rickard2
Associate III

I set up EXTI so I get interupt on the correct pin GPIO B.6. But I cannot get it to wake up from stop1 mode. I call WFI and RTC wakes upp the processor regularly but EXTI will not.

Reading the reference manuel it says any interupt should wake the processor from stop1 mode.

In datasheet wakeup pins are mentioned, but I do not find how they are linked to GPIO.

I am not sure of GPIO clock B shall be enabled or not. Can it be disabled and still wakeup on EXTI? I tried both enable and disable but still the processor did not wakeup.

Here is the relevant code, have I missed setting up something? Maybe wakeup pins are needed but I am not sure how to set them.

void SetupEXTI()
{
	GPIO_InitTypeDef   GPIO_InitStructure;
 
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStructure.Pull = GPIO_NOPULL;
	GPIO_InitStructure.Pin = GPIO_PIN_6;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
 
	/* Enable and set line 4_15 Interrupt to the lowest priority */
	HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
	HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
 
void EXTI4_15_IRQHandler(void)
{
	printf("EXTI!!\n\r");
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
}
 
 
 /* Set STO1 0 mode when CPU enters deepsleep */
  LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);
 
  /* Set SLEEPDEEP bit of Cortex System Control Register */
  LL_LPM_EnableDeepSleep();
 
  /* Request Wait For Interrupt */
  __WFI();
 

7 REPLIES 7
TZARDI
Associate III

Hello Rickard2,

You can take as a reference this function:

/* User push-button (line 4_15) will be used to wakeup the system */

  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

/**
  * @brief  Configures Button GPIO and EXTI Line.
  * @param  Button: Specifies the Button to be configured.
  *   This parameter should be: BUTTON_USER
  * @param  ButtonMode: Specifies Button mode.
  *   This parameter can be one of following parameters:   
  *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
  *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
  *                            generation capability  
  * @retval None
  */
void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
{
  GPIO_InitTypeDef gpioinitstruct;
 
  /* Enable the BUTTON Clock */
  BUTTONx_GPIO_CLK_ENABLE(Button);
 
  gpioinitstruct.Pin = BUTTON_PIN[Button];
  gpioinitstruct.Pull = GPIO_NOPULL;
  gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 
  if(ButtonMode == BUTTON_MODE_GPIO)
  {
    /* Configure Button pin as input */
    gpioinitstruct.Mode = GPIO_MODE_INPUT;
 
    HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
  }
 
  if(ButtonMode == BUTTON_MODE_EXTI)
  {
    /* Configure Button pin as input with External interrupt */
    gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
 
    HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
 
    /* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x03, 0x00);
    HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
  }
}

with

/**
  * @brief User push-button
  */
#define USER_BUTTON_PIN                         GPIO_PIN_13
#define USER_BUTTON_GPIO_PORT                   GPIOC
#define USER_BUTTON_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOC_CLK_ENABLE()   
#define USER_BUTTON_GPIO_CLK_DISABLE()        __HAL_RCC_GPIOC_CLK_DISABLE()  
#define USER_BUTTON_EXTI_LINE                   GPIO_PIN_13
#define USER_BUTTON_EXTI_IRQn                   EXTI4_15_IRQn

I recommend to check STM32Cube_FW_G0. You can find plenty of examples that you can take as a reference(for the wake up push button you can check the example available in: STM32Cube\Repository\STM32Cube_FW_G0_V1.4.0\Projects\NUCLEO-G070RB\Examples\PWR\PWR_SLEEP.)

I hope my response was helpful.

Best regards,

rickard2
Associate III

Sorry for late reply, been on vacation. Thanks for yout suggestion. I have checked your code and also stm32cube example code, but still I cannot wake up from stop using exti and I cannot find any example code with this behaviour.

I get both timer interupt and exti interupt in stop mode, but the they do not wakt up the processor,,...

TZARDI
Associate III

Hello,

You can find in STM32CubeG0_v1-5-0_v1.5.0 examples that wake up the CPU from LPRUN, LPSLEEP, SLEEP and STANDBY when pressing the User push-button.  

Path to the examples: en.STM32CubeG0_v1-5-0_v1.5.0\STM32Cube_FW_G0_V1.5.0\Projects\NUCLEO-G070RB\Examples\PWR

that can be downloaded from this link.

Best regards,

rickard2
Associate III

I followed the example in stm32 cube 1.5.0 PWR/sleep and then I get the EXTI to wakeup from sleep. I also modified to wake up from stop and it works.

BUT the problem appears when I combine EXTI with rtc wake up ( I want to wake up the processor periodically, even if no exti interupt). Then only EXTI works. In my previous implementetion RTC wakeup did work, but not EXTI, so for some reason I cannot get them to both work att same time.

Can you help me understand why it behaves like this?

void HW_RTC_Init(void)
{
	//LL_RTC_InitTypeDef RTC_InitStructure;
	LL_RTC_TimeTypeDef time;
	LL_RTC_DateTypeDef date;
    HAL_PWR_EnableBkUpAccess();
    __HAL_RCC_RTC_ENABLE();
    __HAL_RCC_RTCAPB_CLK_ENABLE();
 
	LL_RCC_LSI_Enable();
 
	while(LL_RCC_LSI_IsReady() == 0)
	{
 
	}
	LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);
	__HAL_RCC_RTC_ENABLE();
	LL_RTC_WaitForSynchro(RTC);
 
	//Set the default date to 2000-01-01 00:00:00:000
 
	date.Year = 0;
	date.Day = 1;
	date.Month = 1;
	date.WeekDay = 6;
	time.Hours = 0;
	time.Minutes = 0;
	time.Seconds = 0;
 
	//LL_RTC_Init(RTC, &RTC_InitStructure);
 
 
	/* Configure RTC */
	RTCHandle.Instance = RTC;
	/* Set the RTC time base to 1s */
	/* Configure RTC prescaler and RTC data registers as follow:
	- Hour Format = Format 24
	- Asynch Prediv = Value according to source clock
	- Synch Prediv = Value according to source clock
	- OutPut = Output Disable
	- OutPutPolarity = High Polarity
	- OutPutType = Open Drain */
	RTCHandle.Init.HourFormat = RTC_HOURFORMAT_24;
	RTCHandle.Init.AsynchPrediv = 127;
	RTCHandle.Init.SynchPrediv = 255;
	RTCHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
	RTCHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
	RTCHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
 
	HAL_RTC_Init(&RTCHandle);
 
	LL_RTC_TIME_SetFormat(RTC, LL_RTC_HOURFORMAT_24HOUR);
	LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BIN, &time);
	LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BIN, &date);
 
	rtcSet = false;
 
}
 
 
 
 
void SleepTest(unsigned int ms)
{
	HW_RTC_Init();
	if(ms > 0x7FFF)
	{
		return;
	}
 
	ms = ms *2;	// 1ms = 16/(32e3)*2
	ms++;
 
	/* Disable all used wakeup source */
	HAL_StatusTypeDef err = HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
	if(err != HAL_OK)
	{
		printf("fel %d\n\r", err);
		return;
	}
 
	__HAL_RCC_SYSCFG_CLK_ENABLE();
	__HAL_RCC_PWR_CLK_ENABLE();
 
	/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
	*/
	HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
 
	/* System interrupt init*/
	GPIO_InitTypeDef   GPIO_InitStructure;
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStructure.Pull = GPIO_NOPULL;
	GPIO_InitStructure.Pin = GPIO_PIN_6;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
 
	/* Enable and set line 4_15 Interrupt to the lowest priority */
	HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
	HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
	__HAL_RTC_TAMPER_EXTI_ENABLE_IT();
 
	err = HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, ms, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
	if(err != HAL_OK)
	{
		printf("fel %d\n\r", err);
		return;
	}
	printf("Stop...\n\r");
	/* Disable Prefetch Buffer */
	__HAL_FLASH_PREFETCH_BUFFER_DISABLE();
 
	RCC->IOPSMENR  = 0x00u;
	RCC->AHBSMENR  = 0x00u;
 
	RCC->APBSMENR1 = 0x00u;
	RCC->APBSMENR2 = 0x00u;
	HAL_SuspendTick();
 
	//HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
	HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
	HW_UART_Init(LOG, 115200);
	printf("Wakeup!!!!\n\r");
}

rickard2
Associate III

I some more testing, only using RTC (removed GPIO EXTI) and I cannot get the RTC interupt to wake up processor from stop. If remove the stop, I do get the interupt from RTC wakeup every 2 second (as expected).

void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
  /* USER CODE END RTC_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_RTC_ENABLE();
    __HAL_RCC_RTCAPB_CLK_ENABLE();
    /* RTC interrupt Init */
    HAL_NVIC_SetPriority(RTC_TAMP_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(RTC_TAMP_IRQn);
  /* USER CODE BEGIN RTC_MspInit 1 */
 
  /* USER CODE END RTC_MspInit 1 */
 
 
}
 
#define WAKEUP_TIMER_ENABLE 0x32F2
void SleepTest(unsigned int ms)
{
	__HAL_RCC_SYSCFG_CLK_ENABLE();
	__HAL_RCC_PWR_CLK_ENABLE();
 
	//HW_RTC_Init();
 
	HAL_RTC_MspInit(&RTCHandle);
	if(ms > 0x7FFF)
	{
		return;
	}
 
	ms = ms *2;	// 1ms = 16/(32e3)*2
	ms++;
 
 
	/* Disable all used wakeup source */
	HAL_StatusTypeDef err = HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);
	if(err != HAL_OK)
	{
		printf("fel %d\n\r", err);
		return;
	}
 
	  /*## Clear all related wakeup flags ########################################*/
	/* Clear PWR wake up Flag */
	__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WUF);
 
	/* Clear RTC Wake Up timer Flag */
	__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RTCHandle, RTC_FLAG_WUTF);
 
	/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
	*/
	HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
 
	/* System interrupt init*/
	GPIO_InitTypeDef   GPIO_InitStructure;
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
	GPIO_InitStructure.Pull = GPIO_NOPULL;
	GPIO_InitStructure.Pin = GPIO_PIN_6;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
 
	/* Enable and set line 4_15 Interrupt to the lowest priority */
	//HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
	//HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
	//__HAL_RTC_TAMPER_EXTI_ENABLE_IT();
 
	 HAL_NVIC_SetPriority(RTC_TAMP_IRQn, 0, 0);
	 HAL_NVIC_EnableIRQ(RTC_TAMP_IRQn);
 
	err = HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, ms, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
	if(err != HAL_OK)
	{
		printf("fel %d\n\r", err);
		return;
	}
	/* Write 'wakeup timer enabled' tag in RTC Backup data Register 1 */
	//HAL_RTCEx_BKUPWrite(&RTCHandle, RTC_BKP_DR1, WAKEUP_TIMER_ENABLE);
 
	printf("Stop...\n\r");
	/* Disable Prefetch Buffer */
	/*__HAL_FLASH_PREFETCH_BUFFER_DISABLE();
 
	RCC->IOPSMENR  = 0x00u;
	RCC->AHBSMENR  = 0x00u;
 
	RCC->APBSMENR1 = 0x00u;
	RCC->APBSMENR2 = 0x00u;
	HAL_SuspendTick();
 
	//HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
	HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
	//HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
	HW_UART_Init(LOG, 115200);*/
	printf("Wakeup!!!!\n\r");
}

rickard2
Associate III

I found the problem now:

RCC->APBSMENR1 = 0x00u;

causes the RTC interupt from waking up processor

Hi rickard2

I have the same problem as you. I couldn't come to any conclusion. I reviewed your code and made edits, but it didn't work. Do you have sample code or working code? thanks.