cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L496 Determine EXTI wake-source when processor has been put in STOP mode

Elliott99
Associate II

My project uses multiple different GPIO's configured as EXTI interrupt sources, and there is a point where, after calling the API:

HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE)

Some different instructions should be executed depending on which EXTI rising/falling edge interrupt woke up the processor. The issue is, when debugging, if I check the EXTI's Pending Register(s) none of the possible bits that would encode wake-up sources for the utilitzed EXTI lines are asserted so I cannot tell which interrupt triggered the wake-up. Likewise, I have check the NVIC's ISPR registers to see if any of the EXTI interrupts are set there, and none of the relevant bits are set here either.

Is there any way to know exactly which event woke up the processor from STOP2 mode if all wake-up sources are EXTI interrupts?

3 REPLIES 3
Karl Yamashita
Lead III

You haven't show any code so no telling how you've set anything up?

 

Using a Nucelo-L432KC, I get interrupts on PA9 or PA10 just fine and breaks on the appropriate Nop depending which pin I ground.

#define USER_Button1_Pin GPIO_PIN_9
#define USER_Button1_GPIO_Port GPIOA
#define USER_Button1_EXTI_IRQn EXTI9_5_IRQn
#define USER_Button2_Pin GPIO_PIN_10
#define USER_Button2_GPIO_Port GPIOA
#define USER_Button2_EXTI_IRQn EXTI15_10_IRQn


void Sleep(void)
{
	HAL_SuspendTick();
	HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE);
	HAL_ResumeTick();

	SystemClock_Config();
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == USER_Button1_Pin)
	{
		Nop();
	}
	if(GPIO_Pin == USER_Button2_Pin)
	{
		Nop();
	}
}

 

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.

Hey Karl, I think I understand my issue, but some guidance on how to get around it would be appreciated.

The EXTI lines that can wake up the processor are configured in event mode. I found this in section 14.3.2, "Wakeup event management", of the rm0351 reference manual:

"The STM32L47x/L48x/L49x/L4Ax is able to handle external or internal events in order to
wake up the core (WFE). The wakeup event can be generated either by:

• enabling an interrupt in the peripheral control register but not in the NVIC, and enabling
the SEVONPEND bit in the CortexTM-M4 System Control register. When the MCU
resumes from WFE, the EXTI peripheral interrupt pending bit and the peripheral NVIC
IRQ channel pending bit (in the NVIC interrupt clear pending register) have to be
cleared
or by configuring an EXTI line in event mode. When the CPU resumes from WFE, it is
not necessary to clear the peripheral interrupt pending bit or the NVIC IRQ channel
pending bit as the pending bit corresponding to the event line is not set"

I assume this would be why I am unable to see any bits set in the EXTI_PR register or the NVIC_ICPR registers for the EXTI lines I believe could have woken the processor, no? And if I want to be able to check the ICPR or PR register to verify *which* wake-up line caused the wake-up, I'd have to configure the EXTI lines as described in bullet one of section 14.3.2?

Could you explain why, for bullet one, we should enable the interrupt in the EXTI peripheral control register but not in the NVIC if I am reading that correctly?


Again, without seeing any code, not sure at what point you're checking EXTI_PR register?

 

In the HAL_GPIO_EXTI_IRQHandler interrupt, the flag in EXTI_PR gets cleared before it calls HAL_GPIO_EXTI_Callback but still passes which pin(s) caused the interrupt. So the question is, do you check before or after the HAL driver clears the flag?

/**
  * @brief  Handle EXTI interrupt request.
  * @PAram  GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
  * @retval None
  */
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

 

If smoke escapes your device, put the smoke back in. It'll still work as a conversation piece. If you find my answers useful, click the Accept as Solution button so that way others can see the solution.