2018-08-07 07:59 AM
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:
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!
2018-08-07 09:09 AM
Sounds like caching issue. Use a non-cached portion of RAM.
JW
2018-08-07 09:21 AM
Hi Jan,
Thanks for the quick reply! I am not familiar with how to control where in memory a particular variable resides. Is that something that you can describe briefly? If not, can you point me to a resource for how to control whether or not a variable is in cached RAM? Thanks for your help!
2018-08-07 10:15 AM
The linker typically controls where data is placed via a scatter file, linker script, or via GUI configurations. At the compiler level direction can be made via attribute or #pragma directives.
It could be a cache coherency or write-through issue. Grep through the example sources for DCache and MPU_Config reference to see how ST addresses/solves these issues. Familiarize yourself with the CM7 caching, buffering, sharing architecture.
2018-08-07 10:19 AM
Hi Clive,
Thanks for the suggestions, I'll check it out!
2018-10-12 11:09 AM
Hi Nickname16298,
Did you find a solution to your problem? I have seen similar problem on my board; The problem did not go away when I disabled data cache.
2018-10-12 01:24 PM
Let's better define "similar problem", because if it is different, the causes might also be different.
Pay attention to what memory you're using. On the F7 the DTCM RAM will work a lot more favourably with DMA as the CPU will be looking at the same memory.
2018-10-12 04:23 PM
Clive Two.Zero,
Actually, my problem was exactly same as Nickname16298's.
BTW, can you please point me to any documentation that mentions how different SRAM blocks behave differently with respect to DMA? Especially if some SRAM is no no for DMA.
2018-10-12 06:54 PM
The Reference Manual shows the plumbing, caches and write buffers can cause coherency issues when you're not paying attention. You just have to become more self-aware, and make sure that when the processor-memory-DMA interact. You have to flush (clean) or invalidate the cache side copy.
Green square is tightly coupled memory, it is not cached (see south side of processor) because it is already fast, and you want to apply the cache resources to slower memory. The Dark Orange is the path the DMA data takes to the core, and the Light Orange is the path back to the memory.
You can use the SRAM, you just have to manage it. Review the code here
STM32Cube_FW_F7_V1.12.0\Middlewares\Third_Party\FatFs\src\drivers\sd_diskio_dma_template.c
See ENABLE_SD_DMA_CACHE_MAINTENANCE code sections
The DTCMRAM is a finite resource, I'm suggesting it as a diagnostic test here to see if it addresses your symptoms, as it's simpler to understand compared to the clean/invalidate methods.