Skip to main content
Visitor II
October 21, 2019
Solved

How to transmit USART data with DMA and low level (LL) functions?

  • October 21, 2019
  • 4 replies
  • 8107 views

Hello,

I'm trying to send some data via UART and DMA on a STM32F072, but with the low level functions. This works perfectly when using the HAL-function HAL_UART_Transmit_DMA(), but I'm missing some information for the low level functions. I configured everything with CubeMX and have this example "code" running:

// Disable DMA to load new length to be tranmitted
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_4);
 
// set length to be tranmitted
volatile uint8_t uart60_tx_buffer[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_4, sizeof(uart60_tx_buffer) );
 
// configure address to be transmitted by DMA
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_4, (uint32_t)uart60_tx_buffer, (uint32_t)LL_USART_DMA_GetRegAddr(USART2, LL_USART_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_4));
 
// Enable DMA again
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_4);
// how to start sending with DMA?!
 
// this works, but is not with DMA support
LL_USART_TransmitData8( USART2, 'A');

I'm just missing the command of function, with which the transmission of the data in the array uart60_tx_buffer[10] is acctually been send. Is this even possible with the low level functions?

Thanks in advance

    This topic has been closed for replies.
    Best answer by Tilen MAJERLE

    Function name is LL_USART_EnableDMAReq_TX.

    Tilen

    4 replies

    ST Employee
    October 21, 2019

    Steps to be considered (in order):

    • Use configuration from CubeMX
    • Configure DMA memory & peripheral addresses for UART and your buffer
    • Configure DMA length (number of bytes to transmit in your case)
    • Enable UART DMA TX request (not done in your example)
    • Enable UART TX mode
    • Enable UART itself
    • Enable DMA channel
    • Transmission will start

    Best regards,

    Tilen

    Visitor II
    October 21, 2019

    Hello, thank you for your replay. Can you please clarify the step "Enable UART DMA TX request" in a bit more detail? This ist my basic question, what is the function call for this, I was not able to find it by my own...

    ST Employee
    October 21, 2019

    Function name is LL_USART_EnableDMAReq_TX.

    Tilen

    Explorer
    August 1, 2023

    Hi Tilen,

    I have a problem with getting data on RX with DMA, Am i doing it correct?

    	LL_USART_EnableIT_RXNE(USART2);
    	LL_USART_IsEnabledIT_IDLE(USART2);
    
    	LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_1, (uint32_t)usart_rx_dma_buffer, (uint32_t)LL_USART_DMA_GetRegAddr(USART2, LL_USART_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1));
    	LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, sizeof(usart_rx_dma_buffer) );
    	LL_USART_EnableDMAReq_RX(USART2);
    	LL_USART_EnableDirectionRx(USART2);
    	LL_USART_Enable(USART2);
    	LL_DMA_EnableChannel(DMA1, 1);
    
    
    
    void DMA1_Channel1_IRQHandler(void) {
     /* Check half-transfer complete interrupt */
     if (LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_1) && LL_DMA_IsActiveFlag_HT1(DMA1)) {
     LL_DMA_ClearFlag_HT1(DMA1); /* Clear half-transfer complete flag */
     usart_rx_check(); /* Check for data to process */
     }
    
     /* Check transfer-complete interrupt */
     if (LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1) && LL_DMA_IsActiveFlag_TC1(DMA1)) {
     LL_DMA_ClearFlag_TC1(DMA1); /* Clear transfer complete flag */
     usart_rx_check(); /* Check for data to process */
     }
    
     /* Implement other events when needed */
    }
    
    /**
     * \brief USART3 global interrupt handler
     */
    void USART2_IRQHandler(void) {
     /* Check for IDLE line interrupt */
     if (LL_USART_IsEnabledIT_IDLE(USART2) && LL_USART_IsActiveFlag_IDLE(USART2)) {
     LL_USART_ClearFlag_IDLE(USART2); /* Clear IDLE line flag */
     usart_rx_check(); /* Check for data to process */
     }
    
     /* Implement other events when needed */
    }
    Graduate II
    August 7, 2023

    The second line of your code doesn't enable the IDLE interrupt.

    https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

    Explorer
    August 21, 2023

    Thank you for your replay, i am not using the LL anymore but het HAL instead