cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART acts strange with StopMode - STM32L081KZT6

HRaup.1
Associate II

Hello,

I am using a STM32L081KZT6. My code sends a Message via LPUART every second and receives an input over the same LPUART from the user. The RTC is used for the timing with LSE. To save power, I go into sleep mode between sending and receiving. The sleep function is called like this:

void schlafen_wenn_nichts_zu_tun(void)
{
	if (!TESTBIT(1, m1_rs232_aktiv)) {
		HAL_SuspendTick();
		HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
	}
}

The sending is done with Interupt and works fine:

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart == &hlpuart1)
	{
		idlemode_tx = IDLE_NACHLAUF_TX;
		if(TESTBIT(1, m1_rs232_aktiv))
		{
			if (rs232_outbuf_index < rs232_outbuf[0])
			{
				rs232_outbuf_index++;
				HAL_UART_Transmit_IT(&hlpuart1,&rs232_outbuf[rs232_outbuf_index], 1);	
			}
			else
			{
				HAL_UART_AbortTransmit_IT(&hlpuart1);	
				CLRBIT(1, m1_rs232_aktiv);
				memset(&rs232_outbuf, 0, sizeof(rs232_outbuf));	
			}
		}
	}
}

The receive also works fine:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	unsigned char zeichen;
	if (huart == &hlpuart1)
	{
		 if(!TESTBIT(1, m1_rs232_aktiv))
		 {
			SETBIT(1, m1_rs232_aktiv);
		 }
		if ((rs232_inbuf_index < RS232_INBUF_LEN))
		{
			 if(!TESTBIT(1, m1_rs232_aktiv))
			 {
				SETBIT(1, m1_rs232_aktiv);
			 }
			zeichen = rs232_inbuf[rs232_inbuf_index];
	}
			if(zeichen != LF){
				HAL_UART_Receive_IT(&hlpuart1, &rs232_inbuf[rs232_inbuf_index+1], 1);
				rs232_inbuf_index++;
 
			}
			else{
			  CLRBIT(1, m1_rs232_aktiv);
			}
}

The Problem starts when I use STOPMode (HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI)) instead of SLEEPMode. The transmit still works as its supposed to, but the Receive function doesn't. I lose the first 1-2 bytes of the message and the next 3-4 bytes are flawed. For example, I send the message "44 45 56 3F 5F 58 32 45 44 34 0D 0A" and the receive reads "5A 36 7A 61 32 45 44 34 0D 0A".

Can anyone tell me why the STOPMode flaws my HAL_UART_Receive_IT ?

Thanks for help

1 ACCEPTED SOLUTION

Accepted Solutions
HRaup.1
Associate II

I just found the solution to my problem:

According to RM0367 Reference manual and Application Note 4991 (https://www.st.com/resource/en/application_note/an4991-how-to-wake-up-an-stm32xx-series-microcontroller-from-lowpower-mode-with-the-usart-or-the-lpuart-stmicroelectronics.pdf), the LPUART clock is not active in stop mode, unless the UCESM bit is set in the LPUART1->CR3 register. This can be achieved by calling SET_BIT(LPUART1->CR3, 0x800000);

View solution in original post

4 REPLIES 4
TDK
Guru

Looks like you are starting the reception mid-stream. Ensure the LPUART is ready to receive at the time data come in. If you want it to wakeup from STOP mode, ensure that it is set up to do so.

If you feel a post has answered your question, please click "Accept as Solution".
HRaup.1
Associate II

Hello and thanks again for your help.

Yes, it looks like the reception starts too late and it is because of the STOPMode. The same code works fine with SLEEPMode.

LPUART does not seem to be ready to receive. When I wait for the LPUART to be ready with

while (HAL_UART_GetState(&hlpuart1) != HAL_UART_STATE_READY)
		    {}

It will get stuck there. I have the while part in a callback function for receive. The LPUART seems to never get ready again. What can cause this? Is there a way to wake up from STOPMode in code, except for Interrupts?

         

TDK
Guru

Not sure. Wakeup times from STOP mode are in the datasheet. They are understandably longer than in SLEEP mode.

LPUART is listed as being active in STOP mode, so I imagine there is a way to do this correctly.

If you feel a post has answered your question, please click "Accept as Solution".
HRaup.1
Associate II

I just found the solution to my problem:

According to RM0367 Reference manual and Application Note 4991 (https://www.st.com/resource/en/application_note/an4991-how-to-wake-up-an-stm32xx-series-microcontroller-from-lowpower-mode-with-the-usart-or-the-lpuart-stmicroelectronics.pdf), the LPUART clock is not active in stop mode, unless the UCESM bit is set in the LPUART1->CR3 register. This can be achieved by calling SET_BIT(LPUART1->CR3, 0x800000);