2026-06-01 4:45 AM - last edited on 2026-06-01 4:55 AM by mƎALLEm
Dear ST experts,
I have configured UART (both RX and TX) in Normal DMA mode. I want to send a small data packet every 500 ms with using HAL_UART_Transmit_DMA (&huart, buffer, 10). But I noticed that only one shot is triggered. What is the problem? Should I do something in HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) callback?
Best,
Davood.
Solved! Go to Solution.
2026-06-01 7:26 AM
Yes, you need to enable the UART global interrupt in STM32CubeMX. Go to your UART :
NVIC Settings → USARTx global interrupt → Enable
In Normal DMA mode, the HAL uses the UART TC (Transmission Complete) interrupt to reset the UART state to READY after each transfer. Without it, the state stays BUSY and every next HAL_UART_Transmit_DMA() call silently fails with HAL_BUSY.
In Circular mode this interrupt isn't needed because the DMA never stops.
You need both enabled: DMA stream interrupt & UART global interrupt
Br
2026-06-01 7:00 AM
Hello @Davood_Kesha ,
In DMA Normal mode, the DMA performs exactly one transfer and stops this is by design, not a bug. The HAL marks the UART state as READY and waits. It will not automatically re-trigger.
Yes, you must re-call HAL_UART_Transmit_DMA() to send again. The correct place is from HAL_UART_TxCpltCallback, combined with a timing mechanism:
volatile uint8_t txDone = 1; // start ready
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
txDone = 1; // transfer finished, ready for next
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_DMA_Init();
MX_USART1_UART_Init();
while (1)
{
if (txDone)
{
txDone = 0;
HAL_UART_Transmit_DMA(&huart1, buffer, 10);
}
HAL_Delay(500);
}
}Br
2026-06-01 7:13 AM
Hello,
I am recalling HAL_UART_Transmit_DMA (&huart, buffer, 10) every 500 ms. But it does not work.
Should I activate the global interrupt of uart in stm32cubemx? In circular mode global interrupt is not needed.
2026-06-01 7:26 AM
Yes, you need to enable the UART global interrupt in STM32CubeMX. Go to your UART :
NVIC Settings → USARTx global interrupt → Enable
In Normal DMA mode, the HAL uses the UART TC (Transmission Complete) interrupt to reset the UART state to READY after each transfer. Without it, the state stays BUSY and every next HAL_UART_Transmit_DMA() call silently fails with HAL_BUSY.
In Circular mode this interrupt isn't needed because the DMA never stops.
You need both enabled: DMA stream interrupt & UART global interrupt
Br
2026-06-01 7:41 AM
@MOBEJ wrote:HAL_UART_Transmit_DMA() call silently (sic) fails with HAL_BUSY.
If it gives an error code, then it's not a silent failure.
We’re moving the ST Community to a new platform to give you a better and more reliable community experience.