stm32F7 USART RX data not being stored in DMA buffer
Hello,
I am using an STM32F767 (nucleo board). I am trying to configure a DMA channel as a circular buffer for USART RX data. Unfortunately, the data never appear in the specified DMA buffer location. A few pieces of information:
- I am using the low-level (LL) drivers exclusively.
- I have successfully configured and used the USART2 and USART3 without DMA buffering, so I am confident in my pin configuration, and that the data I send to the USART is correct (I'm using a virtual comm port to send characters from a terminal program).
- I encounter the same problem using both USART2 and USART3 with DMA.
- I have confirmed that the DMAx_Streamy->NDTR counter is correctly decrementing with each byte that is received by the USART RX.
- I have confirmed that something (presumably the DMA) is clearing the USART RXNE flag upon receipt of each byte.
- I have directly read the contents of the USARTx->RDR register and confirmed that the correct data is present in the register - but this data never appears in the DMA buffer.
- I have directly read the contents pointed to by DMAx_Streamy->M0AR to confirm that it is pointing to the correct buffer location. The data is never updated despite sending bytes to the USART RX
- I have confirmed that the circular buffer is resetting DMAx_Streamy->NDTR upon roll-under and continues to decrement with each byte sent to the USART RX.
- I programmed an SMT32F4 part with an identical USART and DMA configuration, and did not have any problems.
Here is my DMA configuration function:
void Config_USART2_DMA(void)
{
LL_DMA_InitTypeDef DMA_InitStruct;
// u2_rx_buf[] is the DMA buffer, preloaded
u2_rx_buf[0]='a';
u2_rx_buf[1]='b';
u2_rx_buf[2]='c';
u2_rx_buf[3]='d';
//Enable the clock of DMA1
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
//USART2 RX DMA channel - DMA1, channel 4, stream 5 (RX)
LL_DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.Channel= LL_DMA_CHANNEL_4;
DMA_InitStruct.Direction= LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
DMA_InitStruct.FIFOMode= LL_DMA_FIFOMODE_DISABLE;
DMA_InitStruct.FIFOThreshold = LL_DMA_FIFOTHRESHOLD_FULL;
DMA_InitStruct.MemBurst= LL_DMA_MBURST_SINGLE;
DMA_InitStruct.MemoryOrM2MDstAddress = (uint32_t)u2_rx_buf;
DMA_InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
DMA_InitStruct.Mode= LL_DMA_MODE_CIRCULAR;
DMA_InitStruct.NbData= 4;
DMA_InitStruct.PeriphBurst = LL_DMA_PBURST_SINGLE;
DMA_InitStruct.PeriphOrM2MSrcAddress = (uint32_t)&USART2->RDR;
DMA_InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
DMA_InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
DMA_InitStruct.Priority = LL_DMA_PRIORITY_HIGH;
LL_DMA_Init(DMA1,LL_DMA_STREAM_5,&DMA_InitStruct);
// Clear all DMA flags
LL_DMA_ClearFlag_HT5(DMA1);
LL_DMA_ClearFlag_TC5(DMA1);
LL_DMA_ClearFlag_TE5(DMA1);
LL_DMA_ClearFlag_DME5(DMA1);
LL_DMA_ClearFlag_FE5(DMA1);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_STREAM_5);
// Enable the DMA
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
//Enable USART for DMA - tells USART to generate DMA request upon receiving data
LL_USART_EnableDMAReq_RX(USART2);
}
Anyone have any ideas, or run into similar problems? I also compared my code with a stm32cube example for configures the USART using DMA. I don't see any significant difference.
Lastly, I found a thread (FAQ: DMA is not working on STM32H7 devices) indicating that there is a memory/cache issue on the SMT32H parts... Any possibility this is an issue here as well?
I appreciate any helpful responses. Thank you!
