Handling UART errors in HAL
I am struggling to establish robust UART communication using HAL. It also seems I am not alone, there were many similar questions here, all closed without an answer. Here are some of them:
https://community.st.com/s/question/0D50X00009XkfAH/handling-uart-errors-with-hal
https://community.st.com/s/question/0D50X00009XkfFg/stm32-hal-uart-error-managment
https://community.st.com/s/question/0D50X00009XkgNBSAZ/hal-uarts-and-overrun-errors
https://community.st.com/s/question/0D50X00009Xkfom/stm32f407-uart-error-handling
In our system we have multiple UART channels between several MCUs. The data is passed in packets with variable length using standard DMA for transmission and circular DMA for reception. Since low latency is important for us, we also have RTO enabled to read partial buffers when there are pauses in reception.
Problem 1: Recently updated HAL treats RTO as an error and stops communication. We sort of solved this by adding user code to USARTx_IRQHandler() and clearing flag before default HAL processing. An ugly solution to artificially created problem.
Problem 2: It seems HAL uses same UART_DMAError function for hdmatx->XferErrorCallback and hdmarx->XferErrorCallback. This function stops BOTH Tx and Rx DMA transfers regardless of an error. As a result Rx error on device A terminates transmission as well, which causes Rx error on device B, which terminates its own DMA too.
At this point both devices trying to restart UART, and then simple timing decides outcome: if receiver is ready when transmission begins everything is OK. If Tx begins first then receiver seems to catch the middle of incoming frame and rise an error again.
Question 1: is there an example of correct HAL error handling? Every single piece of code I found on the web does something like calling Error_Handler() in main, which is not really "handling".
Question 2: Why RTO is treated as an error in HAL? And not just any error, but a "blocking" one, requiring stopping everything right away.
Question 3: Are there really any Tx errors? I went through all the register descriptions and all I could see are Rx-related interrupts, like parity, frame, overflow etc. Furthermore, in HAL_UART_IRQHandler() all the errors are processed in Rx half of the code, transmission half only checks for TC flag. On the other hand HAL_UART_ERROR_DMA looks like "all in one" for Rx and Tx, and there is no way to tell the difference in user callback function.
