Skip to main content
RN_it
Associate III
August 4, 2018
Question

UART DMA TX complete callback issue

  • August 4, 2018
  • 5 replies
  • 2285 views

Hello,

In the uart driver code of STM32 CUBE layer i found this,

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 */

  CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

  /* Enable the UART Transmit Complete Interrupt */

  SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);

 }

 /* DMA Circular mode */

 else

 {

  HAL_UART_TxCpltCallback(huart);

 }

}

if DMA Is in normal mode , HAL_UART_TxCpltCallback() is not called ,

then , how to get UART DMA tx complete callabck in normal mode ??

also who makes huart->gState = HAL_UART_STATE_READY; ?

Please help

    This topic has been closed for replies.

    5 replies

    Tesla DeLorean
    Guru
    August 8, 2018

    Can't help you, bumping you off my feed

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    RN_it
    RN_itAuthor
    Associate III
    August 11, 2018

    Hi Clive,

    Sorry, whats wrong ?

    dcomer
    Associate
    September 5, 2018

    Hi RN, I don't have a complete answer, but if you refer to the document UM1725, "Description of STM32F4HAL and LL drivers", section 20, "HAL DMA Generic Driver", subsection 20.2 has the following:

    "At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can add his own function by customization of function pointer XferCpltCallback and XferErrorCallback (i.e a member of DMA handle structure)."

    Furthermore, in section 2.12.3.2 Interrupt mode, there is an example of how to use. That said, I don't have it quite working but expect to in the next day. Let me know if this is what you are looking for and, if so, I will post a response on how I get it working. If you beat me to, please reply with your solution.

    Dave

    HYu.5
    Associate
    November 8, 2018

    Just encountered the same problem here.

    Seems like it forget to reset it. I can only send it once and then always get serial port busy. I'm thinking about write own interrupt service.

    Do you find the solution?

    waclawek.jan
    Super User
    November 9, 2018

    Note, that in the non-circular leg of UART_DMATransmitCplt() the USART Tx interrupt is enabled by SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);

    So the idea here is, that this is a "go to complete end" transfer thus the transfer is deemed finished not when DMA moves the last byte to USART->DR, but later, when the last byte actually leaves the USART, ie. when USART->SR. TC is set. In other words, the HAL_UART_TxCpltCallback() is here called from USART_EndTransmit_IT() which you are supposed to have hooked on the USART interrupt servicing routine (and have that ISR enabled somewhere in the startup code of course).

    I don't Cube/HAL.

    JW