cancel
Showing results for 
Search instead for 
Did you mean: 

UART and LPUART won't wake up on UART Data Receive Interrupt - STM32L072CZ, CMWX1ZZABZ-078

sid1
Associate II

Hello folks, we are working on an application where STM32L072CZ needs to wake up from STOP mode on a data received interrupt on UART and LPUART RX lines. We are aiming for STM32L072CZ to be in low power mode and needs to wake up when an external sensor sends serial data to STM32L072CZ every 5 minutes. We are using I-CUBE-LRWAN and the associated functions. 

We are able to put the STM32L072CZ to STOP Mode, however the MCU won't exit the low power mode on UART RX data receive interrupt. We tried this on both UART and LPUART lines and were not successful so far. We are using standard HAL functions. We are not sure if we are overseeing something, any suggestions would be appreciated.

 

SD

7 REPLIES 7
Sarra.S
ST Employee

Hello @sid1

Could you share UART config / its interrupt callback... so we can have better visibility on the issue 

 

 

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.

Hi Sarra, 

I am working on this issue with Sid. Here is the config we have at the moment after testing and trying to find what the issue might be.

//Register bit control - enabling wakeup and clock for UART, not sure if this is doing anything

RCC->CR |= 1<<1;
RCC->CR |= 1<<0;
RCC->APB2ENR |= 1<<14;
USART1->CR1 &= ~0x00000001;
USART1->CR3 |= 0x00700000;
USART1->CR1 |= 0x00000002;
USART1->CR1 |= 0x00000001;

//UART Initialization

huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}

 

if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */

/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA10 ------> USART1_RX
PA9 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

//Interrupt

void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* uint8_t test[] = "test\n";
HAL_UART_Transmit(&huart2, test, sizeof(test), 10);*/
/* USER CODE BEGIN USART2_IRQn 1 */
if(huart1.RxState == HAL_UART_STATE_READY){
Usart_Process_Msg();
}
//HAL_UART_Receive_IT(&huart2, &rx_char, 1);
    /* USER CODE END USART2_IRQn 1 */
}
Please let us know if you need any more information. I have tried using the built in UTIL_LPM functions to put the device in Off, Stop, and Sleep modes and the UART is not able to wake up in any mode. The register bits I found online were to attempt to keep the UART clock active even while in sleep mode as well as enabling the wakeup interrupt function.

@Sarra.S  Please see the info from my colleague @syed.naqvi 

Not sure the USART are going to be functional if the pins, peripherals and clocks are off.

Might be able to config pin as an EXTI, but expect to lose the first byte, unless the transmitting device can idle the data pin in a low state, and perhaps bring it back to a normally-high state for a byte time or two before sending data you want to receive.

The LPUART might have additional options, but check the plumbing and clocks required for that to work.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I used a similar approach using LPUART and was facing the same wakeup issues. The LPUART is not active so the interrupt routine is not called. We can't miss any data or change how the transmitting device can send data, so our options seem to be using LPUART. Below is the initialization I used for LPUART, I would appreciate it we could get some guidance for any setup or implementation tips to allow the LPUART to wakeup the device from low power.

//Init

hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_7B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
Error_Handler();
}

if(uartHandle->Instance==LPUART1)
{
/* USER CODE BEGIN LPUART1_MspInit 0 */

/* USER CODE END LPUART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_LPUART1_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();
/**LPUART1 GPIO Configuration
PA2 ------> LPUART1_TX
PA3 ------> LPUART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_LPUART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(RNG_LPUART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RNG_LPUART1_IRQn);

You'll have to review the Reference Manual, I'm not that invested. I'm not sure 115200 baud would work if clocking sourced from LSE. Check Peripheral clock source.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

As mentioned by @Tesla DeLorean  LPUART driven by LSE can be used to wake-up on incoming data. But the fastest that is supposed to work is 9600 baud.

Otherwise you can try wake-up by EXTI trigger on the start-bit edge. But the wakeup time is not consistent and, as well as lost characters, you might struggle to re-synchronise the UART peripheral with the serial data. I got around that by de-asserting RTS for longer than a byte period before re-asserting it.