2024-09-03 11:37 AM
Hi all,
We have an STM32H735VGH6 on a custom board with a LAN8742a PHY chip to allow ethernet communication. This custom board is minimally tested so it's possible that there's a hardware issue though I'm uncertain where the issue would be. I generated the MCU project using STM32CubeMX (ver 6.12.0) and have been running it with STM32CubeIDE (version 1.16.0). In all versions that I'm running, the MPU is setting all 4GB of space to be non-cacheable.
After a lot of playing around with it, I have been able to get communication to work (basic ARP announcement and ICMP responses) but only in two conditions:
1. If I regenerated the MX project but with the D-Cache enabled under "Cortex Interface Settings" (the MPU is still set up with cache disabled). Then running that build (which doesn't work). Then, without powering down, re-generating the build with D-Cache disabled. Running after that would allow the STM32 to respond to incoming packets. I can rebuild as much as I want and it will work so long as I don't shut off the power. If I do shut off the power, despite having flashed the board with that build, if I turn the power back on then it no longer responds to ARP communication. If I then attach the debugger, sometimes though not all the time, it will attempt to read an incoming packet and have a hard fault from attempting to invalidate D-Cache despite D-Cache not being enabled. The invalidate D-Cache function has a define it checks to ensure that D-Cache exists (which is set to 1 in both generated codebases) and if I force that to 0, it gets past the hard fault but it still doesn't respond to packets.
2. The other method to get it to work is to put the "SCB_EnableDCache()" call after the MPU_Config(), but to then add "SCB_DisableDCache()" after the MX_LWIP_Init() function is called (all while the MPU is still not allowing cache access). This will cause all future ethernet connections to work but if the ethernet is plugged in while programming this build or on boot up, the STM32 doesn't respond (until that ethernet is unplugged and replugged in). This makes me think that the Initialization isn't occurring fully successfully. I've tried moving the SCB_DisableDCache() before the MX_LWIP_Init() and it doesn't work. I did not yet try and see at exactly what point inside the MX_LWIP_Init() that the cache needs to be set for the communication to function on future connections.
What could be going on here to cause this issue? I have attached the generated .ioc file in case that helps.
2024-09-03 02:21 PM
It's interesting.
> attempting to invalidate D-Cache despite D-Cache not being enabled.
Do not invalidate D-Cache when it is not enabled (some people say it is a bug in old CMSIS version in ST libraries...) but I always do:
bool dc = !!(SCB->CCR & (uint32_t)SCB_CCR_DC_Msk);
if (dc) {
/* flush or invalidate D cache */
} /* else don't touch d-cache */
2024-09-04 05:58 AM
Yeah the attempt to invalidate the D-Cache seems like a bug in the auto-generated code. It's calling the invalidate line in HAL_ETH_RxLinkCallback with no check to see if D-Cache is enabled like the one you posted. Within the invalidate D-Cache function, it checks for "__DCACHE_PRESENT" being defined and equal to 1 before writing to the registers but the generated code has that value at 1 even when the D-Cache is set to disabled. The hard fault is just an interesting side note to this issue though because I can comment out that line (or set __DCACHE_PRESENT to a non-1 value) and I no longer get the hard fault though the board ends up still being unable to respond to ARP packets.
I'm taking sort of a wild guess here but I think it may be an issue with some registers during setup of the LAN8742a chip. I think that because it seems to be running successfully only if LwIP setup occurs while cache is enabled even if that setup happened in a previous build and run, like in my temp solution 1 in my first post, so long as power is not reset. That makes me think it can't be a bad state within the STM32 itself because it should reset itself on every new programming. I believe that the cache on this device defaults to write-back not write-through (for at least some of the addresses) so maybe it's possible some value is not truly being written to the LAN8742a that would put it in a bad state when setup with cache enabled. Then the actual running of the processes needs to be done with cache disabled so that writes can be truly passed on. I don't really know enough about that chip or the STM32 ETH module to know what specifically it could be. The MPU is also being set to non-cacheable across the entire 4GB address space so maybe this theory isn't sound (though clearly the cache does have to be enabled anyways for part of the time for this to work!).
2024-09-10 03:01 AM - edited 2024-09-10 03:02 AM
Hello,
This issue is being tracked internally (Internal ticket number: 190602). I'll get back to you as soon as possible.
With Regards,
2024-09-16 09:10 AM - edited 2024-09-16 10:42 AM
Hi. Your MPU configuration doesn't set all 4GB of space to be non-cacheable.
This overwrites the default settings to prevent speculative read to unavailable memories (range 0x60000000 to 0xE0000000, set as strong ordered, code execution disabled). See tutorials: https://community.st.com/t5/stm32-mcus/how-to-create-a-project-for-stm32h7-with-ethernet-and-lwip-stack/ta-p/49308 or on youtube