Regarding the before/after, the article is right - invalidation must be done before starting the reception. Read my post in this topic:
https://community.st.com/s/question/0D53W000009j3IKSAY/stm32h7-sai-dma-cache-enabled-nothing-works-as-before
AN4839 page 4:
- If all the lines are allocated, the cache controller runs the line eviction process, where a line is selected (depending on replacement algorithm) cleaned/invalidated, and reallocated. The data cache and Instruction cache implement a pseudo-random replacement algorithm.
Detailed discussion:
https://community.st.com/s/question/0D50X0000C9hGoz/weird-cache-writeback-behavior-for-stm32f7508
But the article is wrong on other issues:
#define RX_LENGTH (16)
uint8_t rx_buffer[RX_LENGTH];
/* Make sure the address is 32-byte aligned and add 32-bytes to length, in case it overlaps cacheline */
SCB_InvalidateDCache_by_Addr((uint32_t*)(((uint32_t)rx_buffer) & ~(uint32_t)0x1F), RX_LENGTH+32);
- The math of the size (second) parameter is completely wrong. It doesn't do even what was intended and damages data.
- The intended "expand to the nearest cache line boundaries" logic is already done internally in SCB_*() functions and those manual calculations are useless.
- The address and size expansion logic doesn't cancel the requirement of a buffer address and size to be aligned to cache line size. Not doing that still damages other variables placed before and after that buffer.
- The points 1 and 2 are true also for a transmission part of the example.