Cache coherency issues when reading DMA buffer from ADC
Hello,
I face serveral data coherency issues on my dma buffer which is used to place the values of serveral ADC channels into it. This is executed on M7 context
Just as a reference, I have a dummy project without any MPU configuration and data cache is globally disabled. I start the DMA sampling via Software (On-Shot-Mode) several times. When I set different voltage levels on different ADC channels, I see the expected values inside the DMA buffer.
When I enable the data cache, then my buffer keeps freezing. I don't see any updates inside the dma buffer. I was following the example code form ST as well as the link "https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices"
According to this page, I created a seperate memory region for the DMA. The dma buffer is 32 byte aligned and placed into the SRAM3 region via linker attributes
ALIGN_32BYTES (__attribute__ ((section (".dma"))) static uint16_t Buff[I5]) = {0U};
.dma is a section of SRAM3 (0x38000000).
Starting address of the buffer is 0x38000000 as well.
After the complete initialization stuff on the M7, I call HAL_ADC_Start_DMA() to start the ADC sampling of all 5 channels in the background.
After that, I call SCB_InvalidateDCache_by_Addr(). This function seems to work only once because I see that the buffer changed to its expected values correctly. When I call HAL_ADC_Stop_DMA and call HAL_ADC_Start_DMA() again due to One-Shot mode procedure follewed by SCB_InvalidateDCache_by_Addr(), the values are not updated anymore. The previous value from the first SCB_InvalidateDCache_by_Addr() are still reflected in the dma buffer although I put a different set of voltages on a different channel. I can evaluate the ADC DR register with its latest value from the last channel (depending on rank config), I see that this value didn't make it into the dma buffer
I also tried to use SCB_InvalidateDCache() which is stucked in an endless loop till I manually leave the loop via ajump instruction with the debugger
I also tried SCB_CleanDCache_by_Addr() afterwards but it doesn't seem to work at all
What part I am missing here?
Whats a littble bit confusin is that the ST example use the SCB_InvalidateDCache_by_Addr after the data is available (actually inside the DMA complete interrupt) while the page mentioned above tells you to use it even before reading data from the DMA buffer.
Do I need adapt the MPU as well for SRAM3 region ? Any assistance?
The same project without Cache and MPU on M7 is running without any issue, but the loss of d-cache is not a option for me due to performance loss on other interfaces (FMC, etc.)
Why is it working ony once ?
