How to wake MCU from sleep by USART event
I'm learning STM32 by a NUCLEO-L053R8 board.
I want to put device to sleep (not LP Sleep, Stop or Standby) and wake it by either an interrupt or an event.
int main()
{
// Clock and peripherals init
// UART init (baud rate, GPIO, etc. are initialized before)
EXTI->IMR &= ~EXTI_IMR_IM26;
EXTI->EMR |= EXTI_EMR_EM26;
USART2->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE | USART_CR1_UE;
RCC->IOPENR |= RCC_IOPENR_GPIOCEN;
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
GPIOC->PUPDR = (GPIOC->PUPDR & GPIO_PUPDR_PUPD13_Msk) | GPIO_PUPDR_PUPD13_0; // PC13 - user button
GPIOC->MODER &= ~GPIO_MODER_MODE13;
SYSCFG->EXTICR[3] = (SYSCFG->EXTICR[3] & SYSCFG_EXTICR4_EXTI13_Msk) | SYSCFG_EXTICR4_EXTI13_PC;
EXTI->EMR |= EXTI_EMR_EM13;
EXTI->FTSR |= EXTI_FTSR_FT13;
EXTI->RTSR &= ~EXTI_RTSR_RT13;
while (1)
{
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
__SEV();
__WFE();
__WFE();
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
while ((GPIOC->IDR & GPIO_IDR_ID13) == 0)
{
// Process GPIO
}
if (UART2_NewDataAvailable())
{
// Process UART
}
}
}When I press button, device wakes up and processes GPIO and UART once, then goes to sleep. There is no need to clear any flag as the channel is configured as event (EM13).
However, sending a character to UART doesn't wake CPU.
If I set SEVONPEND bit, clear both IM26 and EM26, and leave NVIC as default (no priority or IRQ enable), sending a character to UART wakes device once and no more; because NVIC channel pending bit is set and should be cleared manually.
Why UART doesn't wake the CPU when configured as event?