cancel
Showing results for 
Search instead for 
Did you mean: 

Overrun problem with USART2 in STM32H723 MCU

FCamp.1
Associate III

Hello,

I'm facing a bizarre issue with USART2 in STM32H7 chip.

My H7 is connected to 8 F072 chips via UART. Communication with each chip uses a dedicated UART from 1 to 8.

All the data exchanges in both RX and TX work fine during normal operativity of my product even exchanging lots of data. I dont use any RTOS, I set priority in the NVIC table to manage concurrency.

-----

The problem starts when from the H7 I manage to transmit to the F0s a new version of their software to be installed by a bootloader. Once again during the data transmission and even the copy by the boot everything is fine. At the end of the installation process inside the F0s, when the main application is launched by the boot, that sends 3 bytes of "welcome" to the H7 to confirm the process has completed successfully.

For UART 1 and from 3 to 8 the welcome bytes are sent and received correctly. for UART2 I see an overrun error on the RX of the peripheral. Please keep in made that the whole process is repeated 8 times sequentially and the implementation is exactly the same, both inside the F0 and the H7.

Checking the registers of USART2 I see that in the RDR there is the first byte of the welcome message but the RXNE bit is in fact set. The ORE bit is also set. So according to my understanding the second byte of the welcome message arrives in the shift register before the first is red from the RDR. I really can't understand why only UART2 and only in this specific transfer is suffering this communication issue.

Some more implementation info:

1) the UARTs in both F0 and H7 are all set and receiving in async

2) all the UART configs are absolutely the same! (or at least this is what it looks like form CubeMX view)

3) this is the code in the callback on the H7

 

 

//rb_USART_CHxx_rx is a cyrcular FIFO buffer

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

	if(huart->Instance == USART1)
	{
		HAL_UART_Receive_IT(&huart1, &uart1_data, 1);
		bufferWrite2(&rb_USART_CH1_rx, uart1_data);
		isUartCh1Rx = true;
	}
	else if(huart->Instance == USART2)
	{
		HAL_UART_Receive_IT(&huart2, &uart2_data, 1);
		bufferWrite2(&rb_USART_CH2_rx, uart2_data);
		isUartCh2Rx = true;
	}
	else if(huart->Instance == USART3)
	{
		HAL_UART_Receive_IT(&huart3, &uart3_data, 1);
		bufferWrite2(&rb_USART_CH3_rx, uart3_data);
		isUartCh3Rx = true;
	}
	else if(huart->Instance == UART5)
	{
		HAL_UART_Receive_IT(&huart5, &uart4_data, 1);
		bufferWrite2(&rb_USART_CH4_rx, uart4_data);
		isUartCh4Rx = true;
	}
	else if(huart->Instance == USART6)
	{
		HAL_UART_Receive_IT(&huart6, &uart5_data, 1);
		bufferWrite2(&rb_USART_CH5_rx, uart5_data);
		isUartCh5Rx = true;
	}
	else if(huart->Instance == UART7)
	{
		HAL_UART_Receive_IT(&huart7, &uart6_data, 1);
		bufferWrite2(&rb_USART_CH6_rx, uart6_data);
		isUartCh6Rx = true;
	}
	else if(huart->Instance == UART9)
	{
		HAL_UART_Receive_IT(&huart9, &uart7_data, 1);
		bufferWrite2(&rb_USART_CH7_rx, uart7_data);
		isUartCh7Rx = true;
	}
	else if(huart->Instance == UART8)
	{
		HAL_UART_Receive_IT(&huart8, &uart8_data, 1);
		bufferWrite2(&rb_USART_CH8_rx, uart8_data);
		isUartCh8Rx = true;
	}
	else if(huart->Instance == UART4)
	{
		HAL_UART_Receive_IT(&huart4, &uartMST_data, 1);
		bufferWrite2(&rb_USART_MST_rx, uartMST_data);
		isUartMSTRx = true;
	}
}

 

 

 4) i have tried to switch the communication of different F0s from USART1 (working) to USART2 (not working) and viceversa and the result is the same.

What it seems to me is that for some reason on USART2 the call back is not running in this situation or the reading function is not working HAL_UART_Receive_IT(&huart2, &uart2_data, 1);

Any idea to point me in some direction? Here I'm getting crazy. 

Thanks,

Filo

 

1 REPLY 1
TDK
Guru

If RXNE and ORE are set, the interrupt wasn't handled fast enough, as you said.

There are a limited number of reasons an interrupt isn't running, so check each of them:

  • Interrupts must be globally enabled (i.e. no __disable_irq(), show PRIMASK value)
  • The interrupt must be enabled in NVIC. Check it, show screenshot (show NVIC register for USART1_IRQn)
  • The interrupt must be enabled in the UART peripheral (show USART->SR register values)
  • The interrupt flag must be set (show USART->SR register values)
  • Execution must not be in a higher or same priority interrupt (show stack trace, if in main thread you're good, if in IRQ maybe not)

If all those check out, perhaps the interrupt is ran but due to some other bug (e.g. out of bounds write) the uart handle is corrupted and the HAL handler doesn't behave as expected.

 

It sure sounds like the interrupt just wasn't handled quickly enough. I'd look at other parts of your code, particularly interrupt handlers, which may be taking longer than allowed. You can shuffle priorities to ensure USART2 is handled first as a debug measure.

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