Skip to main content
developer2
Senior
March 11, 2018
Question

issue with DCache on STM32F746ZG

Posted on March 11, 2018 at 16:54

Hello,

i'm having issue on STM32F746ZG, connected with ETH PHY through RGMII, and i'm having also enabled USB HS using ULPI,

when i not enable DCache at start everything works perfectly ...

but when i enable SCB_EnableDCache(), USART DMA TX is sending wrong data, ethernet does not work both ways (RX+TX),

i'm sure that DMATxDscrTab is at 0x20010280 , DMARxDscrTab is at 0x20010200, Rx_Buff is at 0x2004c000, Tx_Buff is at 0x2004d7d0,

i tried :

- before executing SCB_EnableDCache() i executed: MPU config region 1K starting at 0x20010000, with mode NotBufferable,

- before executing SCB_EnableDCache() i executed: MPU config region 1K starting at 0x20010000, with mode NotCacheable,

... no success at all,

... MPU_Config taken from ST's examples in HAL,

- without DCache everything works on 100% ...

please could you help me to find out what to do to get DCache usable ?

Thanks for all replies ...

Kind regards,

    This topic has been closed for replies.

    4 replies

    Tesla DeLorean
    Guru
    March 11, 2018
    Posted on March 11, 2018 at 18:24

    Use DTCM memory for the buffers, flush or invalidate the cache/buffers based on usage, or disable the cache and sharing on 0x20040000 region. 

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    developer2
    Senior
    March 11, 2018
    Posted on March 11, 2018 at 19:17

    Hi Clive,

    please could you write a little bit more details ?

    DTCM memory for buffers ? which buffers ? ethernet DMA descriptors or data buffers ? because based on Reference manual: 'The AHB masters support concurrent SRAM accesses (from the Ethernet or the USB OTG

    HS): for instance, the Ethernet MAC can read/write from/to SRAM2 while the CPU is

    reading/writing from/to SRAM1' ... so i targeted data buffers into SRAM2 at base address 0x2004c000,

    flush or invalidate buffers you mean for example sequence:

    SCB_CleanInvalidateDCache();

    HAL_UART_Transmit_DMA();

     ? ... this i tried but data still wrong on the opposite side and ethernet still not working ...

    disable cache and sharing on 0x20040000 ? you mean something like this:

      MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

      MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

      MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;

    why 0x20040000 ? it's nearly to the end of SRAM1 ... did you mean setup on full SRAM1 ? or SRAM2 ? what amount do you propose ?

    Tesla DeLorean
    Guru
    March 11, 2018
    Posted on March 11, 2018 at 23:38

    Put any structures where coherency would be an issue in DTCM, not cached, single cycle. Have different pools of memory, and allocate based on usage expectations.

    How much memory, and how out of control the memory usage is, will dictate the complexity of your task. I'd suggest containing it as much as possible, in the cleanest way possible. What you want to try an avoid is having to copy stuff from unsafe areas to safe ones, or using blanket methods for all memory instead of targeted methods.

    In SDMMC buffering, the invalidation is done on the buffer before/after depending on write/read. You can flag a region based on 32-byte alignment boundaries. Watch that you don't break your own data structures by throwing away pending write-backs. Here ST's code has a little more scope than I'd like, and I've seen one complaint about it breaking things. I've seen unscoped invalidation break regular code.

    ♯ if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

                      uint32_t alignedAddr;

              /*

                 the SCB_InvalidateDCache_by_Addr() requires a 32-Bit aligned address,

                 adjust the address and the D-Cache size to invalidate accordingly.

              */

              alignedAddr = (uint32_t)buff & ~3;

              SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

    ♯ endif

    https://community.st.com/message/93947

     

    You mentioned the address range, you could configure the MPU with suitable address/granularity. At 0x20040000 I'd presume up to 256KB would align suitably.

    I was thinking of 0x24000000 range in H7

    https://community.st.com/message/186230-re-stm32h743zi-nucleo-uart-dma-experiment-for-help?commentID=186230 ♯ comment-186230

     
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..