cancel
Showing results for 
Search instead for 
Did you mean: 

When is the UART Receive/Transmit interrupt produced?

MCasas
Associate II

Hello to everyone,

First of all, excuse me if this post isn't posted in the correct group, but I didn't know in which one it should be posted.

About my doubt:

I'm using the functions HAL_UART_Receive_IT and HAL_UART_Transmit_IT to do a UART communication.

The thing is that I introduce a breakpoint in the Transmit interrupt and another one in the Receive interrupt but, the Transmit interrupt is executed 2 times before entering to the receive interrupt, and then, after finishing it, the T-interrupt is executed again.

Could you explain me when these interrupts are executed?

That's how I call the functions:

HAL_UART_Receive_IT(&huart1, &receptor, 1);
  HAL_UART_Transmit_IT(&huart2, &transmisor, 1);

Thank you!

Edit: I'm using the Devolopment board NUCLEO-G070RB that has the STM32G070RB uC

2 REPLIES 2

The STM32 (you don't mention which you're using) has a singular IRQ for each U(S)ART, the interrupt is triggered in the NVIC from a gated version of the status register and interrupt enable register in the USART. There are multiple status that can trigger the interrupt, together or alone.

With HAL, you have some additional stupidity, where you call into the HAL from the IRQ Handler, it qualifies the source and then at some decimated rate, based on buffer size, calls your callback routine(s).

The TXE interrupt may be enabled in a way that after the current byte enters the shifting buffer, it generates an IRQ, and the routine sees if any data was queued in the meantime, and if the queue is empty, it then disables the TXE interrupt to prevent an interrupt storm because you aren't servicing it with data, ie it continues to pend.

The CM3/CM4/CM7 also have a hazard with the pipeline, write-buffers and NVIC vs Tail Chaining, that can cause IRQ reentry if the clearing/disabling write hasn't propagated within the decision window.

Note that most STM32 generate an interrupt for each byte received/transmitted, if both RX/TX are pending, the IRQ Handler should really service BOTH in a single visit.

Some STM32 use the same IRQ for multiple U(S)ART, the IRQ Handler is expected to check all devices under its purview.

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

Thank you for your answer @Community member​ ,

I edited the post writing the Devolopment board that I'm using.

Now I was reading the transmit_IT HAL Function and seems to activate the TDR interrupt and the transmit complete, but, anyways, I still can not understand why the transmission interrupt is called 1 time after the receive interrupt has been called, when the communication should be done.

What I did is the next:

void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
int n = 0;
	if ((USART2->ISR & USART_ISR_TC) == USART_ISR_TC)
	{
		n++;
	}
	if ((USART2->ISR & USART_ISR_TXE_TXFNF) == USART_ISR_TXE_TXFNF)
	{
		n++;
	}
 
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
 
  /* USER CODE END USART2_IRQn 1 */
}

I put a breakpoint on both n++;. The first time the interrupt is called, both if are true. The second call, only the second if is true and, for the last one, after the receive interrupt, both if are true again.

Also, it's possible to modify the HAL_Transmit_IT to just enable the TC interrupt? or every time I generate the code the modification will be deleted?

Thanks!