Skip to main content
NSAUG.1
Associate III
Nov 27, 2021 10:22 PM UTC
Question

On RX Framing error, UART_DMAAbortOnError can corrupts ongoing TX transfer resulting in 65536 bytes transfered. HAL bug ?

Hi,

I use STM32Cube_FW_WB_V1.12.1 on a STM32WB55, with generated init code and HAL functions.

I have setup a circular DMA for RX of UART1 and use HAL_UART_Transmit() when I need to send data.

I'm communicating with a device (GPS module) that can be configured at two different baud rates, so I have written code to try to talk to it alternatively at both baud rates until it responds something that the UART understands.

The problem is that upon raising a Frame Error on RX, HAL_UART_IRQHandler calls HAL_DMA_Abort_IT which in turn calls UART_DMAAbortOnError, which is implemented as below :

/**
 * @brief DMA UART communication abort callback, when initiated by HAL services on Error
 * (To be called at end of DMA Abort procedure following error occurrence).
 * @param hdma DMA handle.
 * @retval None
 */
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
{
 UART_HandleTypeDef *huart = (UART_HandleTypeDef *)(hdma->Parent);
 huart->RxXferCount = 0U;
 huart->TxXferCount = 0U;
 
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
 /*Call registered error callback*/
 huart->ErrorCallback(huart);
#else
 /*Call legacy weak error callback*/
 HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}

As you can see, TxXferCount is set to zero, evn though the original error only concerns RX...

And when this happens while HAL_UART_Transmit is ongoing, specifically in this snippet of that function :

while (huart->TxXferCount > 0U)
 {
 if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
 {
 return HAL_TIMEOUT;
 }
 if (pdata8bits == NULL)
 {
 huart->Instance->TDR = (uint16_t)(*pdata16bits & 0x01FFU);
 pdata16bits++;
 }
 else
 {
 huart->Instance->TDR = (uint8_t)(*pdata8bits & 0xFFU);
 pdata8bits++;
 }
 huart->TxXferCount--;
 }

the result is TxXferCount going to zero just before being decremented, so it wraps around to 65536 (TxXferCount is volatile).

This obviously leads to a very wrong result of having about 1/3rd of the RAM of my chip transmitted.

This bug looks like a HAL bug to me.

The behavior I would have though normal here would have been to only reset the RxXferCount when the error concerns only RX.

Best,

Nicolas

This topic has been closed for replies.