I used CubeMX to setup a project for UART DMA transfers RX and TX. Apart from my protocol logic, I added two callbacks:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
and start transfers with calls to
HAL_UART_Receive_DMA(&huart2, (uint8_t *)buf, len);
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)x, len)
Both work fine in the sense that the data is transmitted, as I can see from logic analyzer and host side. But the problem is, that only the Rx Callback is called after transfer has finished.
I walked through the source code with debugger and found that the interrupt for TX complete is actually triggered, but the callback function is never called from HAL implementation. I checked the file "stm32l4xx_hal_uart.c" and found the following function, which is called after the UART DMA TX transfer has completed:
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
UART_HandleTypeDef* huart = (UART_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 resetting the DMAT bit
in the UART CR3 register */
/* Enable the UART Transmit Complete Interrupt */
/* DMA Circular mode */
Essentially, this tells me, that when in normal mode (not circular), the registered callback is never executed. Is this a bug in the HAL implementation?
After adding the callback in the code executed if normal mode is activated, everything works like a charm. I would prefer not to change the HAL library code, though.
Has anybody experienced this problem before? Am I using the driver correctly?
You can find the complete source code of my application in the attachment.