2023-08-11 07:07 AM
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
2023-08-11 07:22 AM - edited 2023-08-11 07:23 AM
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.
2023-08-11 07:51 AM
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
2023-08-11 09:10 AM
@Sarra.S Please see the info from my colleague @syed.naqvi
2023-08-11 09:16 AM - edited 2023-08-11 01:11 PM
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.
2023-08-11 09:48 AM
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);
2023-08-11 09:55 AM - edited 2023-08-11 09:56 AM
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.
2023-08-11 12:56 PM
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.