2025-07-30 3:06 AM - last edited on 2025-07-30 3:11 AM by Andrew Neil
Hello everyone,
We're working on UART interrupts and would like to wake up the MCU from STOP1 mode to begin UART communication. We're using USART1 as the LoRa peripheral for VCOM instead of the default USART2, in a LoRa End Node architecture. I'm working on Nucleo board STM32WL55JC.
At this point, we’ve successfully managed to wake up the MCU using a UART interrupt, but I'm having trouble identifying which callback is triggered when the system wakes up from STOP mode via UART.
Our goal is to stay in Low Power Sleep mode after processing the UART interrupt. In this state, we would like to be able send data over uart constantly (what we have been able to do via the sequencer).
Here are our Enter/Exit Stop mode:
void PWR_EnterStopMode(void)
{
/* USER CODE BEGIN EnterStopMode_1 */
// Save peripheral states and de-initialize before entering stop mode
// stop ADC conversions
HAL_ADC_Stop(&hadc);
// deinit SPI
HAL_SPI_DeInit(&hspi1);
// De-deinit I2C
HAL_I2C_DeInit(&hi2c2);
// disable peripheral clocks
__HAL_RCC_SPI1_CLK_DISABLE();
__HAL_RCC_I2C2_CLK_DISABLE();
// __HAL_RCC_USART1_CLK_DISABLE();
__HAL_RCC_ADC_CLK_DISABLE();
// disable GPIO clocks for unused pins
__HAL_RCC_GPIOA_CLK_DISABLE();
// __HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
UART_WakeUpTypeDef WakeUpSelection;
/*Set wakeUp event on start bit*/
WakeUpSelection.WakeUpEvent = UART_WAKEUP_ON_STARTBIT;
HAL_UARTEx_StopModeWakeUpSourceConfig(&huart1, WakeUpSelection);
/* Make sure that no UART transfer is on-going */
while (__HAL_UART_GET_FLAG(&huart1, USART_ISR_BUSY) == SET);
/* Make sure that UART is ready to receive) */
while (__HAL_UART_GET_FLAG(&huart1, USART_ISR_REACK) == RESET);
/* Enable USART interrupt */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_WUF);
/*Enable wakeup from stop mode*/
HAL_UARTEx_EnableStopMode(&huart1);
/* USER CODE END EnterStopMode_1 */
HAL_SuspendTick();
/* Clear Status Flag before entering STOP/STANDBY Mode */
LL_PWR_ClearFlag_C1STOP_C1STB();
/* USER CODE BEGIN EnterStopMode_2 */
APP_PRINTF("Entering STOP1 MODE\r\n");
HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
// /*
// /* USER CODE END EnterStopMode_2 */
// HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
// /* USER CODE BEGIN EnterStopMode_3 */
//
/* USER CODE END EnterStopMode_3 */
}
void PWR_ExitStopMode(void)
{
/* USER CODE BEGIN ExitStopMode_1 */
// reconfigure system clock
SystemClock_Config();
HAL_UARTEx_DisableStopMode(&huart1); // DKW but We need it
// enable GPIO clocks first
__HAL_RCC_GPIOA_CLK_ENABLE();
// __HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
// enable peripheral clocks
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
// __HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_ADC_CLK_ENABLE();
// initialize GPIO
MX_GPIO_Init();
// initialize peripherals
MX_SPI1_Init();
MX_I2C2_Init();
// MX_USART1_UART_Init();
MX_ADC_Init();
// Set nSLEEP pin state as in main.c
HAL_GPIO_WritePin(nSLEEP_GPIO_Port, nSLEEP_Pin, GPIO_PIN_RESET);
/* USER CODE END ExitStopMode_1 */
/* Resume sysTick : work around for debugger problem in dual core */
HAL_ResumeTick();
/*Not retained periph:
ADC interface
DAC interface USARTx, TIMx, i2Cx, SPIx
SRAM ctrls, DMAx, DMAMux, AES, RNG, HSEM */
/* Resume not retained USARTx and DMA */
vcom_Resume();
/* USER CODE BEGIN ExitStopMode_2 */
APP_PRINTF("Exiting STOP1 MODE\r\n");
/* USER CODE END ExitStopMode_2 */
}
I also tried implementing a custom wakeupcallback function:
void WakeupCallback(UART_HandleTypeDef *huart){
if (huart->Instance == USART1)
{
UTIL_LPM_SetStopMode((1 << CFG_LPM_UART_TX_Id), UTIL_LPM_DISABLE);
}
}
However, I’m a bit confused about the Low Power Manager and the use of the CFG_LPM_Id enum in utilities_def.h.
Specifically:
Any help or clarification would be greatly appreciated!
Thanks in advance!
Edited to apply source code formatting - please see How to insert source code for future reference.