cancel
Showing results for 
Search instead for 
Did you mean: 

Can the STM32L4 transmit and receive USART over DMA?

ABicc.1
Associate

Hello, I am inquiring about USART communication using DMA. I am following github.com/MaJerle/stm32-usart-uart-dma-rx-tx tutorial using the low level drivers for a STM32L432. I have reception working with no troubles and I believe my interrupts are being hit okay. However, I am having trouble with transmission, simplifying the code from the tutorial I can't seem to get the USART to actually start transmitting the data. When I check the size of the DMA buffer it says it is full of 32 bytes, then when I start channel it never empties. Apologies if this is simple, but I've tried numerous combinations with no success. Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions

USART1_TX is DMA1 CH4, not DMA2

0693W00000Uo6pKQAR.jpg

void USART1_DMA2_Start_Transmit(void)
{
    LL_DMA_DisableChannel(DMA2, LL_DMA_CHANNEL_4);
    LL_USART_ClearFlag_TC(USART1);
    LL_DMA_ClearFlag_TC4(DMA2);
    // set length to be tranmitted
    LL_DMA_SetDataLength(DMA2, LL_DMA_CHANNEL_4, ARRAY_LEN(RS485_TxData));
    
    // configure address to be transmitted by DMA
    LL_DMA_ConfigAddresses(DMA2, LL_DMA_CHANNEL_4, (uint32_t)RS485_TxData, (uint32_t)LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA2, LL_DMA_CHANNEL_4));
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_CHANNEL_4, (uint32_t)RS485_TxData);
 
    // Enable DMA again
    LL_USART_EnableDirectionTx(USART1);
    LL_USART_EnableDMAReq_TX(USART1);
 
    LL_DMA_EnableChannel(DMA2, LL_DMA_CHANNEL_4);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

1 REPLY 1

USART1_TX is DMA1 CH4, not DMA2

0693W00000Uo6pKQAR.jpg

void USART1_DMA2_Start_Transmit(void)
{
    LL_DMA_DisableChannel(DMA2, LL_DMA_CHANNEL_4);
    LL_USART_ClearFlag_TC(USART1);
    LL_DMA_ClearFlag_TC4(DMA2);
    // set length to be tranmitted
    LL_DMA_SetDataLength(DMA2, LL_DMA_CHANNEL_4, ARRAY_LEN(RS485_TxData));
    
    // configure address to be transmitted by DMA
    LL_DMA_ConfigAddresses(DMA2, LL_DMA_CHANNEL_4, (uint32_t)RS485_TxData, (uint32_t)LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA2, LL_DMA_CHANNEL_4));
    LL_DMA_SetMemoryAddress(DMA2, LL_DMA_CHANNEL_4, (uint32_t)RS485_TxData);
 
    // Enable DMA again
    LL_USART_EnableDirectionTx(USART1);
    LL_USART_EnableDMAReq_TX(USART1);
 
    LL_DMA_EnableChannel(DMA2, LL_DMA_CHANNEL_4);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..