2018-08-04 04:33 AM
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
2018-08-08 02:09 PM
Can't help you, bumping you off my feed
2018-08-10 10:16 PM
Hi Clive,
Sorry, whats wrong ?
2018-09-05 10:57 AM
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
2018-11-08 02:24 PM
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?
2018-11-08 10:55 PM
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