2021-05-21 03:14 AM
Currently I am working on UART DMA and I encountered problems after transmitting data via DMA UART. After 1 successful data transmission, the state flag remains on BUSY. After a search, I ended up on this thread and this fixed the problem.
static
void
UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if
( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->TxXferCount = 0;
/* 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 */
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
huart->State=HAL_UART_STATE_READY;
//<--- i add this line to solve the //problem
}
/* DMA Circular mode */
else
{
HAL_UART_TxCpltCallback(huart);
}
}
Line 31 in code snippet
However, is this a good solution (and should this be implemented in the stm32f3 library) or am I missing something that causes this problem of only 1 successful transmission?
Solved! Go to Solution.
2021-05-21 05:08 AM
Hello @Ade J.2
Here is how UART DMA Tx transfers are expected to work :
In your case, could you check that UART IRQ is properly enabled, with corresponding IRQ handler ?
(that could be an explanation why state remains in BUSY and HAL_UART_TxCpltCallback() is not called).
FYI, requirement of checking TC status of last transmitted byte was required by some applications that enter low power modes just after an transmission. If HAL sets state to ready directly in UART_DMATransmitCplt(), and user disables UART clocks after state is back to ready, last data copied by DMA, is not transmitted. As I mentioned, at a given instant, transfer is completed from DMA point of view, but not from UART Tx line yet.
Hope this will help you.
Regards
Guenael
2021-05-21 05:08 AM
Hello @Ade J.2
Here is how UART DMA Tx transfers are expected to work :
In your case, could you check that UART IRQ is properly enabled, with corresponding IRQ handler ?
(that could be an explanation why state remains in BUSY and HAL_UART_TxCpltCallback() is not called).
FYI, requirement of checking TC status of last transmitted byte was required by some applications that enter low power modes just after an transmission. If HAL sets state to ready directly in UART_DMATransmitCplt(), and user disables UART clocks after state is back to ready, last data copied by DMA, is not transmitted. As I mentioned, at a given instant, transfer is completed from DMA point of view, but not from UART Tx line yet.
Hope this will help you.
Regards
Guenael
2021-05-31 12:48 AM
Sorry for the late response, was on vacation for a week.
Thanks for the clear explanation. When I indeed enable USARTx global interrupt, it works as it should.
Thanks for the solution.