cancel
Showing results for 
Search instead for 
Did you mean: 

UART DMA TX complete callback issue

RN
Senior

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 discussion is locked. Please start a new topic to ask your question.
5 REPLIES 5

Can't help you, bumping you off my feed

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
RN
Senior

Hi Clive,

Sorry, whats wrong ?

dcomer
Associate II

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 II

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

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