Skip to main content
IKayk.1
Associate
August 4, 2021
Question

STM32H7 HAL_UARTEx_ReceiveToIdle_DMA fails if there are already transmissions on the UART

  • August 4, 2021
  • 4 replies
  • 2743 views

I have this code that initiates my UART channels with DMA at startup:

if( HAL_OK == HAL_UART_RegisterRxEventCallback( m_configuration.huart, callbackRx )) {
 
		if( HAL_OK == HAL_UART_RegisterCallback( m_configuration.huart, HAL_UART_TX_COMPLETE_CB_ID, callbackTx )) {
 
			if( HAL_OK == HAL_UARTEx_ReceiveToIdle_DMA( m_configuration.huart, m_configuration.pRxBuffer, m_configuration.rxBufferSize )) {
 
				rc = true ;
			}
		}
	}

And it works fine if the STM32 is not physically connected to that UART and no one is sending anything on that channel during the startup, connecting after the startup allows the UART to work properly. However, if for some reason I need to reset the STM32 (which is a very possible scenario in our application), while the external device connected to this UART keeps transmitting, this code fails.

I did a little debugging:

Inside HAL_UARTEx_ReceiveToIdle_DMA when the code calls UART_Start_Receive_DMA, specifically the DMAR bit is set on CR3 register, the huart->ReceptionType is no longer HAL_UART_RECEPTION_TOIDLE but turns to HAL_UART_RECEPTION_STANDARD.

Just for the sake of it, I tried resetting huart->ReceptionType with HAL_UART_RECEPTION_TOIDLE HAL_UARTEx_ReceiveToIdle_DMA failed and the UART began to work correctly again.

My question are:

  1. Why, when the UART receives messages, the reception type changes to standard? Does it happen in an interrupt somewhere? I could not stop with a watchpoint or breakpoint where it happens...
  2. Why is reception type tested after calling UART_Start_Receive_DMA ? I assume I can't just ignore it.
  3. Is there a way to make the UART ignore incoming transmissions until after the DMA is setup properly?

Thanks!

This topic has been closed for replies.

4 replies

TDK
August 4, 2021

One option would be to de-initialize the pin during setup and re-initialize it afterwards.

"If you feel a post has answered your question, please click ""Accept as Solution""."
MBC
Associate III
February 4, 2022

@IKayk.1​ 

Did you ever find an acceptable solution to this?

Pavel A.
February 5, 2022

If the UART supports RTO, that is almost always what you want, rather than "receive to idle". See the examples by Tilen Majerle here.

Or, use continuous receive with circular buffer example

The HAL driver unfortunately is too complicated to work reliably.

Piranha
Principal III
July 21, 2022

IDLE and RTO events both are OK and do the same thing. IDLE just has a constant time - one byte, which is the minimum possible one.