cancel
Showing results for 
Search instead for 
Did you mean: 

LPUART1 not working with interrupts via HAL_UART_Transmit_IT(...) function

Snowopolis
Associate II

I'm using STM32CubeIDE 1.3.1 w/ a Nucleo L4R5ZI board. I can transmit via the lpuart1 with the polled version - HAL_UART_Transmit(...). The interrupt is enabled in the NVIC. Changing to the HAL_UART_Transmit_IT(...) and board stuck repeatedly calling HAL_UART_IRQHandler().

/* this works fine and output appears in serial terminal */

result = HAL_UART_Transmit(&hlpuart1, (uint8_t*)"GO-1\r\n", 6, 100);

/* this never returns. nothing appears on serial terminal */

result = HAL_UART_Transmit_IT(&hlpuart1, (uint8_t*)"GO-2\r\n", 6);

It never returns because it's stuck infinitely calling the HAL_UART_IRQHandler(). I haven't made any changes to the HAL_UART_IRQHandler(...), just using the default generated code.

HAL_UART_IRQHandler() at stm32l4xx_hal_uart.c:2,509 0x8003408

LPUART1_IRQHandler() at stm32l4xx_it.c:209 0x8000a52

<signal handler called>() at 0xfffffff9

HAL_UART_Transmit_IT() at stm32l4xx_hal_uart.c:1,301 0x8003128

main() at main.c:105 0x800053c

As a sanity check on myself I tried with a Nucleo-F103RB (because I had one sitting here), and the above steps works fine.

It's like the library and/or generated code is missing something. Not sure if it's lpuart1 or L4R5 related. The data isn't transmitted and the interrupt isn't cleared/handled.

Has anyone else run into this? Any work around?

9 REPLIES 9
YS.K
Associate III

I'd like to ask if LPUART1 can send data.

The sentence above said yes, but the sentence below said no, so I am inquiring.

TDK
Guru

Examine the UART->SR register to see why the interrupt keeps getting called. Ensure the handler actually handles the flag appropriately.

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

lpuart1 can send data. Works fine with the polled transmit function (HAL_UART_Transmit). Does not work with interrupt transmit function (HAL_UART_Transmit_IT).

Has NVIC Setting checked the UARTx global interrupt ?

And I set the interrupt priority to 5 and tested it.

This should be the interrupt setting above.

Snowopolis
Associate II

Solved! - The problem is, as I suspected, with the generated code. I noticed that it was adding an "UART_HandleTypeDef huart1;" to main.c but uart1 wasn't enabled. Odd, but seemed benign. The root of the issue is that the generated LPUART1_IRQHandler(...) is:

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
 
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
 
  /* USER CODE END LPUART1_IRQn 1 */
}

BUT, it should be:

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
 
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
 
  /* USER CODE END LPUART1_IRQn 1 */
}

In the end, I made my handler

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
 
	  HAL_UART_IRQHandler(&hlpuart1);
	  return;
 
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
 
  /* USER CODE END LPUART1_IRQn 1 */

A little bit clunky, but make me immune to future regenerations of the code.

I also noticed that MX_LPUART1_UART_Init(void) references huart1 in the disabling of the fifo line. Fixed that too.

All is well now.

It amazes me how many times I stared at and walked through that code before I noticed it was passing the wrong uart! :beaming_face_with_smiling_eyes: :face_with_tears_of_joy: :sad_but_relieved_face:

mantisrobot
Associate III

Hi,

I'm getting this exact same issue using LPUART1 and interrupt transmits, the system gets stuck in an infinite loop within the ISR. I've looked at the generated LPUART1_IRQHandler code and it seems fine now so clearly fixed, but I have exactly the same issue. If I use any other USART port it works fine!

/**
  * @brief This function handles LPUART1 global interrupt.
  */
void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
 
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
 
  /* USER CODE END LPUART1_IRQn 1 */
}

I should point out I'm running RTOS, this is my call stack:

HAL_UART_IRQHandler() at stm32h7xx_hal_uart.c:2,231 0x8012690

LPUART1_IRQHandler() at stm32h7xx_it.c:332 0x8007fd2

<signal handler called>() at 0xfffffffd

prvPortStartFirstTask() at port.c:267 0x801be58

xPortStartScheduler() at port.c:379 0x801bf6c

The first time I call HAL_UART_Transmit_IT() I do get the 34 bytes of data out of the port, however, the second call to the function gets into the infinite IRQ loop at about the second fill of the FIFO buffer (Set at 14bytes)

As mentioned by the community member above, should review the hlpuart1->SR register to see which interrupt bit is set with JTAG.

Like the code below, the ISR infinite loop does not occur when generated bits in the interrupt routine clear before function return.

{

uint32_t isrflags = READ_REG(hlpuart1->ISR);

hlpuart1->ICR = (uint32_t)isrflags;

if ((isrflags & USART_ISR_RXNE)) {

}

if ((isrflags & USART_ISR_TXE)) {

}

}

Additionally check which interrupt enabled -> hlpuart1->CR1

​ - USART_CR1_TXEIE, USART_CR1_TCIE

I'm sorry I haven't experienced UART FIFO buffer.

If you use UART FIFO buffer, please check if there are FIFO interrupt bits.​