cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 LPUART Stays at RX Interrupt Constantly

FarukSozuer
Associate III

Hello everyone;

I'm working LUPART with STM32H747. I have a problem like this;

- LPUART 1000000 baudRate has been installed. LSE clock is not used.

There is no problem when the LPUART's RX-TX line is physically connected to the module. But when I physically remove the module, the processor does not execute the code at runtime. Constantly getting stuck in LPUART1_IRQHandler function. The problem disappears when I drop the BaudRate for example 9600. Below is the interrupt routine I wrote for LPUART. It works smoothly on all other UART / USARTs.

static void DS_LPUSART1_InterruptCallback(UART_HandleTypeDef *huart)
{
	uint32_t isrflags   		 	 = READ_REG(huart->Instance->ISR);
	uint32_t cr1its     			 = READ_REG(huart->Instance->CR1);
	uint32_t cr3its     			 = READ_REG(huart->Instance->CR3);
	uint8_t  received_data 			 = 0;
 
	bool	 is_transmit_in_progress = false;
 
    if ( ( (isrflags & USART_ISR_RXNE_RXFNE) != 0U)     &&
    	 ( ( (cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U) ||
    	   ( (cr3its & USART_CR3_RXFTIE) != 0U)
		 )
	   )
    {
    	received_data = (uint8_t) READ_REG(huart->Instance->RDR);
    	lpuart1.receiveByte(received_data);
    }
 
 
    if ( ( (isrflags & USART_ISR_TXE_TXFNF) != 0U)     &&
    	 ( ( (cr1its & USART_CR1_TXEIE_TXFNFIE) != 0U) ||
    	   ( (cr3its & USART_CR3_TXFTIE) != 0U)
		 )
	   )
	{
    	is_transmit_in_progress = lpuart1.transmit();
    	if(is_transmit_in_progress == false)
    	{
  	      CLEAR_BIT(huart->Instance->CR1, USART_CR1_TXEIE_TXFNFIE);  	     
    	}
	}
}
 
void initialize(void)
{
	static uint8_t dummy = 0;
 
	uart_handle->pRxBuffPtr  = &dummy;
	uart_handle->RxXferSize  = 1;
	uart_handle->RxXferCount = 1;
	uart_handle->ErrorCode   = HAL_UART_ERROR_NONE;
 
	SET_BIT(uart_handle->Instance->CR3, USART_CR3_EIE);
	SET_BIT(uart_handle->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE);
	CLEAR_BIT(uart_handle->Instance->ISR,USART_ISR_NE);
 
switch(uart_number)
{
	case uart_module_type::H747_LPUART1 :
	uart_handle->RxISR = DS_LPUSART1_InterruptCallback;	///< While interrupt routines are init, they are handled to ISR registers.
	uart_handle->TxISR = DS_LPUSART1_InterruptCallback; ///< While interrupt routines are init, they are handled to ISR registers.
	break;
 
	default :
		//Error
	break;
}
}

Below is the initialize funciton I wrote for LPUART.

void MX_LPUART1_UART_Init(void)
{
 
  hlpuart1.Instance = LPUART1;
  hlpuart1.Init.BaudRate = 100000;
  hlpuart1.Init.WordLength = UART_WORDLENGTH_9B;
  hlpuart1.Init.StopBits = UART_STOPBITS_2;
  hlpuart1.Init.Parity = UART_PARITY_EVEN;
  hlpuart1.Init.Mode = UART_MODE_TX_RX;
  hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_TXINVERT_INIT|UART_ADVFEATURE_RXINVERT_INIT;
  hlpuart1.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE;
  hlpuart1.AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE;
  hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
 
}

In addition, I constantly check error conditions.

bool H747_UART::errorCheck(void)
{
	uart_isr_bit.all = uart_handle->Instance->ISR;
 
	if(uart_isr_bit.bits.PE || uart_isr_bit.bits.NE || uart_isr_bit.bits.ORE)
	{
		return false;
	}
 
	return true;
}

I could not find the root cause of the problem. I would be glad if you could help.

Sincelery

1 ACCEPTED SOLUTION

Accepted Solutions
FarukSozuer
Associate III

Hi Tesla;

This problem is solved. I overlooked the status of the Frame Error (FE) bit in the ISR error flags. If the serial port line is physically empty, the FE bit is set to 1. I corrected this error situation by setting the FECF bit in the ICR register to 1.

Thanks

View solution in original post

2 REPLIES 2

So what statuses continue to flag?

Show register dump in these situations.

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

Hi Tesla;

This problem is solved. I overlooked the status of the Frame Error (FE) bit in the ISR error flags. If the serial port line is physically empty, the FE bit is set to 1. I corrected this error situation by setting the FECF bit in the ICR register to 1.

Thanks