2021-08-04 01:34 AM
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:
Thanks!
2021-08-04 07:01 AM
One option would be to de-initialize the pin during setup and re-initialize it afterwards.
2022-02-04 09:55 AM
@IKayk.1
Did you ever find an acceptable solution to this?
2022-02-04 04:37 PM
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.
2022-07-21 02:06 PM
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.