2024-12-22 05:57 AM - edited 2024-12-22 06:06 AM
Hello All,
I am using USART peripheral to transfer a block of bytes. I am trying to do it using DMA. Because I want all bytes of USART frame should be dispatched without any gaps between them and my system has few interrupts that could bring gaps between the byte if I transfer using polling mode.
So I have configured the DMA channel for this. But my problem is that DMA Transfer complete Callback is not getting invoked by HAL Driver. I am using Normal DMA mode and NOT the circular mode.
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
when I debugged the code I found that the HAL driver file stm32f0xx_hal_uart.c file line no 3533
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
is only invoking the HAL_UART_TxCpltCallback() when the DMA type is Circular (see the screenshot below) so is it a bug? Because HAL documentation doesn't state that the callback will be called only for CIRCULAR mode and NOT normal more. Nor does this code is making any sense.
When I removed the "else" keyword, my callback is getting called. I have also referred to a previous version of the HAL driver, there also the logic is same and also in STM32F4's HAL driver.
2024-12-22 06:26 AM
Yes, that does look unhelpful. Not sure it's by design.
2024-12-22 09:37 AM
Fairly sure this works.
At end of normal DMA, TCIE gets set, which eventually triggers the IRQ, which calls UART_EndTransmit_IT which calls HAL_UART_TxCpltCallback. TC gets set when no characters are being sent (i.e. transmission is actually complete).
So why does it do this? Because when the DMA TC flag gets set, the last character is still being sent out. TC only indicates that the DMA is done, not that the transmission is done. If it called HAL_UART_TxCpltCallback then, and you disabled the UART, it would cause issues.
2024-12-22 10:03 AM - edited 2024-12-22 10:03 AM
Test on a STM32F429 new CubeMX project. It does work as intended as described above. However, you need to enable the global UART IRQ interrupt, which is not enabled by default.