Skip to main content
Visitor II
December 17, 2019
Question

HAL_UART_Transmit_DMA does not check if DMA is actually ready?

  • December 17, 2019
  • 2 replies
  • 1401 views

Hi,

I am using STM32Cube_FW_F4_V1.24.2. I noticed that HAL_UART_Transmit_DMA internally only checks the UART state (line 17) but completely ignores the return value of HAL_DMA_Start_IT (line 48). So what will happen if HAL_DMA_Start_IT returns HAL_BUSY for instance? In this case HAL_UART_Transmit_DMA would return HAL_OK although the start of the DMA transfer actually failed? In this case the data would never be sent. Or is this scenario impossible (by design)?

/**
 * @brief Sends an amount of data in DMA mode.
 * @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
 * the sent data is handled as a set of u16. In this case, Size must indicate the number
 * of u16 provided through pData.
 * @param huart Pointer to a UART_HandleTypeDef structure that contains
 * the configuration information for the specified UART module.
 * @param pData Pointer to data buffer (u8 or u16 data elements).
 * @param Size Amount of data elements (u8 or u16) to be sent
 * @retval HAL status
 */
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
 uint32_t *tmp;
 
 /* Check that a Tx process is not already ongoing */
 if (huart->gState == HAL_UART_STATE_READY)
 {
 if ((pData == NULL) || (Size == 0U))
 {
 return HAL_ERROR;
 }
 
 /* Process Locked */
 __HAL_LOCK(huart);
 
 huart->pTxBuffPtr = pData;
 huart->TxXferSize = Size;
 huart->TxXferCount = Size;
 
 huart->ErrorCode = HAL_UART_ERROR_NONE;
 huart->gState = HAL_UART_STATE_BUSY_TX;
 
 /* Set the UART DMA transfer complete callback */
 huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
 
 /* Set the UART DMA Half transfer complete callback */
 huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
 
 /* Set the DMA error callback */
 huart->hdmatx->XferErrorCallback = UART_DMAError;
 
 /* Set the DMA abort callback */
 huart->hdmatx->XferAbortCallback = NULL;
 
 /* Enable the UART transmit DMA stream */
 tmp = (uint32_t *)&pData;
 HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
 
 /* Clear the TC flag in the SR register by writing 0 to it */
 __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
 
 /* Process Unlocked */
 __HAL_UNLOCK(huart);
 
 /* Enable the DMA transfer for transmit request by setting the DMAT bit
 in the UART CR3 register */
 SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
 
 return HAL_OK;
 }
 else
 {
 return HAL_BUSY;
 }
}

Thanks in advance!

Kind regards,

Matthias

    This topic has been closed for replies.

    2 replies

    Super User
    December 18, 2019

    Please note that this is a primarily user-driven forum with casual ST presence. We haven't seen much feedback from the Cube/HAL developers here, either. And most users who provide answers here apparently don't use Cube/HAL.

    So, if you have doubts about it, you may be better off not using Cube/HAL.

    JW

    Graduate II
    December 22, 2019
    1. Of course the same is true also for USART driver. Actually UART driver should be eliminated as it's a subset of USART anyway.
    2. HAL's "busy" concept and many other things must also be eliminated or replaced.
    3. The same goes for HAL developer team and management...