cancel
Showing results for 
Search instead for 
Did you mean: 

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

Christian Wächter
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
Tilen MAJERLE
ST Employee

Function name is LL_USART_EnableDMAReq_TX.

Tilen

View solution in original post

6 REPLIES 6
Tilen MAJERLE
ST Employee

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

Christian Wächter
Associate III

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...

Tilen MAJERLE
ST Employee

Function name is LL_USART_EnableDMAReq_TX.

Tilen

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 */
}

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

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

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