bug in HAL_UART_Transmit_DMA
I wrote an application configuring the USART for DMA transmission. The first call to HAL_UART_Transmit_DMA works correctly and the expected bytes are sent. However, every subsequent call fails with HAL_UART_STATE_BUSY.
It appears that the uart state is not set back to ready when the DMA transmission ends. I added a line in UART_DMATransmitCplt to set the state back to ready (below) and this appears to fix the problem but I wondered if there is a better solution than modifying the provided HAL code.
FWIW, UART_DMAReceiveCplt does set the state back to ready in the non-circular case. It seems like Transmit should do the same.
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
/* DMA Normal mode*/
if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
{
huart->TxXferCount = 0x00U;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
ATOMIC_SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
// TODO bug, transmission ends but UART remains in busy state preventing further transmissions
huart->gState = HAL_UART_STATE_READY;
}
/* DMA Circular mode */
else
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#else
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}