2025-01-09 01:52 AM
Hello everyone,
I want to try to wakeup my system from the the STOP2 mode with a button press. The button is also in use in the rest of the application and works just fine. But when going to STOP2 it does not wake up the system again.
I've tried it with the preconfigured interrupt, which also handles the button presses while the system is active, as well as a change to an event based trigger setup right before going to STOP2. Both do not wake up the system.
void setEXTIEvent(void)
{
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_6;
EXTI_InitStruct.Mode = LL_EXTI_MODE_EVENT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
}
void setEXTIInt(void)
{
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_6;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
NVIC_EnableIRQ(EXTI9_5_IRQn);
}
void EnterStop2Mode(void)
{
SaveParamConfig();
printf("Entering STOP2 mode...\n");
setEXTIEvent();
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_SuspendTick();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE);
HAL_ResumeTick();
setEXTIInt();
MX_SUBGHZ_Init();
printf("Woke up from STOP2\n");
}
I've included the code for the current event based implementation. The interrupt based implementation just doesn't call the two setEXTI functions and PWR_STOPENTRY_WFI ist used instead. The general pin configuration is done through the code generator.
As the tag is not available I'm working on a STM32WLE5 MCU.
2025-01-09 05:18 AM
Hello @RWalko, welcome to ST Community,
Following this wiki, you should be able to make it work: Getting started with EXTI - stm32mcu
Could you try that?
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-01-09 05:35 AM
Thanks for the welcome, and thanks for the resource.
As I have written, the EXTI Interrupt generally works, and the button is used to switch between modes in my application, which works just fine, so I am already beyond the example you have given me. I have checked in regardlessly but found no differences between my solution and the example. The only problem is that in the STOP2 low power mode the interrupt or the event does not wake up the MCU.
I noticed in the data sheet that EXTI is an 'optional' wakeup source for STOP2. But all the resources I've found said that if I have configured the interrupt or event, it should work as a wakeup. Is there maybe something else that warrants that 'optional' tag that I missed?
2025-01-09 05:43 AM
This is the table you should refer to, to know the wake up capabilities in every low power mode:
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-01-09 06:03 AM
Hi Rico
Please find below my code that runs on the Nucleo-WL55JC development board. I've achieved around 880 nA current consumption in STOP2 mode. By pressing user button 1 (PA0), the system wakes up (interrupt), toggles an LED (PB9) a few times, and then returns to STOP2 mode, reaching the same current consumption as before.
I've included everything in the main function so you can see all the necessary steps. I didn't have much time for code refactoring.
Remember to clear the corresponding EXTI flag in the ISR handler (file stm32wlxx_it.c).
Should the problem persists, feel free to contact me.
Hope this helps!
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
/* USER CODE BEGIN 2 */
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
/* GPIO Ports Clock Enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
/**/
LL_GPIO_ResetOutputPin(LED2_GPIO_Port, LED2_Pin);
/**/
GPIO_InitStruct.Pin = LED2_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
LL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
/* Configure PA0 (user button 1) as EXTI */
LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE0);
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_0;
EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_0, LL_GPIO_PULL_UP);
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_0, LL_GPIO_MODE_INPUT);
/* EXTI interrupt init*/
NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(EXTI0_IRQn);
/* Enter Stop 2 mode */
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
/* Set SLEEPDEEP bit of Cortex System Control Register */
LL_LPM_EnableDeepSleep();
/* Request Wait For Interrupt */
__WFI();
/* Here Device is in Stop 2 mode */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
LED_Blinking_5s();
__WFI();
}
/* USER CODE END 3 */
}
void LED_Blinking_5s(void)
{
uint32_t i = 0;
/* Toggle IO in during 5s (25*200ms) */
for(i = 0; i < 24; i++)
{
LL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
LL_mDelay(50);
}
}
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
/* USER CODE END EXTI0_IRQn 0 */
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
2025-01-09 06:09 AM
Thanks for the info, but it only shows me that it should work as I have explained it. But if there is something I overlooked, it's not there.
I have checked in the reference manual and have seen that any activated EXTI line is also activated as a wakeup source, no matter if it's event or interrupt based. So I'm still stumped.
2025-01-09 06:47 AM - edited 2025-01-09 06:56 AM
Thanks a lot for the example, I was able to cross check. I wrote a smaller example that just displays something on a LCD display that is connected via I2C, turns off after a time and goes to STOP2 and is supposed to be reactivated with a button press. The used Pin is PA6, which is not a wakeup pin, but it should not matter if I do not go in standby/shutdown.
Generally, the code generated by CubeMX is the same, except that I use HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
void EnterStop2Mode(void)
{
sl_segment_lcd_all_off();
sl_segment_lcd_disable();
HAL_SuspendTick();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
HAL_ResumeTick();
sl_segment_lcd_init(false);
}
int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t counter = 10;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
sl_segment_lcd_init(false);
/* USER CODE END 2 */
/* Infinite loop */
while (1)
{
sl_segment_lcd_number(counter);
HAL_Delay(10000);
EnterStop2Mode();
counter++;
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
/* GPIO Ports Clock Enable */
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
/**/
LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE6);
/**/
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_6;
EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
EXTI_InitStruct.LineCommand = ENABLE;
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
LL_EXTI_Init(&EXTI_InitStruct);
/**/
LL_GPIO_SetPinPull(TAMP_GPIO_Port, TAMP_Pin, LL_GPIO_PULL_UP);
/**/
LL_GPIO_SetPinMode(TAMP_GPIO_Port, TAMP_Pin, LL_GPIO_MODE_INPUT);
/* EXTI interrupt init*/
NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(EXTI9_5_IRQn);
}
And in the stm32wlxx_it.c (which I have not modified, as it does not need to do anything).
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
/* USER CODE END EXTI9_5_IRQn 0 */
if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_6) != RESET)
{
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_6);
/* USER CODE BEGIN LL_EXTI_LINE_6 */
/* USER CODE END LL_EXTI_LINE_6 */
}
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
2025-01-09 06:54 AM
Hi Rico,
great. Nice example!
Does this mean the issue has been resolved and you can now wake up from STOP2 mode by pressing the button or does the problem still persist?
Best regards
Jaroslav