AnsweredAssumed Answered

HAL: Without USART interrupt, HAL_UART_Transmit_DMA() will work only once

Question asked by johanson.arne on Apr 19, 2016
Latest reply on Apr 25, 2016 by Nesrine M
Hi,

I use CubeMX+HAL with a Nucleo-64 with an STM32F411 (FW package v. 1.11.0). I configured USART2 in DMA mode to send data to a PC connected to the ST-Link. I disabled the USART interrupt for performance reasons (whats the point in using the interrupt if you have DMA?).

I noticed that I receive data on the PC after the first call to HAL_UART_Transmit_DMA but on subsequent calls to the function, no data is received on the PC (having waited long enough to ensure that the previous transmit is complete).

A quick debug session shows that in subsequent calls to HAL_UART_Transmit_DMA, the functions immediately returns HAL_BUSY because huart->gState != HAL_UART_STATE_READY. This is the case because UART_DMATransmitCplt relies on the USART interrupt to be enabled to reset huart->gState to HAL_UART_STATE_READY. I would appreciate it if you could change the behavior of UART_DMATransmitCplt so that DMA transmits work without the USART interrupt. In my case, changing the definition of UART_DMATransmitCplt to the following code solved my problem:

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 = 0U;
 
    /* Disable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    huart->Instance->CR3 &= (uint32_t)~((uint32_t)USART_CR3_DMAT);
 
    /* Enable the UART Transmit Complete Interrupt */
    // EDITED BY USER:
    // I do not want to use the usart interrupt!
    //__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
    huart->gState = HAL_UART_STATE_READY;
 
  }
  /* DMA Circular mode */
  else
  {
    HAL_UART_TxCpltCallback(huart);
  }
}

Thanks and all the best
Arne

Outcomes