Skip to main content
Associate II
Mar 16, 2025 1:54 PM UTC
Solved

DAC in DMA mode @ enabled cache

Hello!

 

A simple question. 

If I run DAC, using HAL_ADCEx_MultiModeStart_DMA(..., buffer, ...), when D-cache is disabled, I succeed to send what I filled in the buffer. 

If I do the same with enabled D-cache, I don't succeed. 

SCB_InvalidateDCache_by_Addr() function, which is useful in ADC callbacks, seems to be not helpful for DAC.

 

How to fix that?

 

This topic has been closed for replies.
ahsrabrifatBest answer
Senior III
Mar 16, 2025 2:16 PM UTC

Use SCB_CleanDCache_by_Addr() Before Enabling DMA

Before starting the DAC DMA transfer, call:

 

SCB_CleanDCache_by_Addr((uint32_t*)buffer, buffer_size);

 

where:

  • buffer is the pointer to your DAC buffer.
  • buffer_size is the number of bytes in the buffer.

3 replies

ahsrabrifatBest answer
Senior III
Mar 16, 2025 2:16 PM UTC

Use SCB_CleanDCache_by_Addr() Before Enabling DMA

Before starting the DAC DMA transfer, call:

 

SCB_CleanDCache_by_Addr((uint32_t*)buffer, buffer_size);

 

where:

  • buffer is the pointer to your DAC buffer.
  • buffer_size is the number of bytes in the buffer.
Tesla DeLorean
Guru
Mar 16, 2025 6:46 PM UTC

The command to FLUSH the pending memory for a DMA (memory-to-peripheral) is SCB_CleanDCache_by_Addr()

The SCB_InvalidateDCache_by_Addr() throws away the pending/dirty cache content, ie stuff you've created in the buffer. It's what you'd use when DMA (peripheral-to-memory) has changed the underlying content of the memory

 

Remember that the by_Addr() expects 32-byte alignment buffers and sizes. You need to add guard zones around the buffers if you can't do that, the Invalidate can do collateral damage.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
LeonidPAuthor
Associate II
Mar 17, 2025 12:15 PM UTC

Thanks. With SCB_CleanDCache_by_Addr() it works.