2017-06-29 07:39 PM
Hi,
I use CubeMX 4.21.0 to generate FreeRTOS+LWIP code on STM32F746GZ Nucleo board. The problem is when I ping the board, It will reply after pinging 2 times. See below capture:
Did anybody ever meet this problem?
2017-06-29 10:40 PM
Do they have same gateway?
2017-06-30 04:25 AM
Same Gateway.
I traced the code and foud the problem may be in function HAL_ETH_TransmitFrame() which called by low_level_output(). I could see the ICMP pack was copied to heth buffer in memory view. But the pack didn't be sent after running function
HAL_ETH_TransmitFrame(), and will be sent after call HAL_ETH_TransmitFrame() again by another pack.
I will check DMA part of 746GZ to see where's the reason.
2017-07-05 02:02 AM
I found the problem. It's in 'Resume DMA transmission' part code in function
HAL_ETH_TransmitFrame():
if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
{/* Clear TBUS ETHERNET DMA flag */ (heth->Instance)->DMASR = ETH_DMASR_TBUS; /* Resume DMA transmission*/ (heth->Instance)->DMATPDR = 0; dprintf('DMASR=0X%08X; TxDescriptor addr= 0X%08X; 0X%08X\r\n', (heth->Instance)->DMASR, (heth->Instance)->DMACHTDR, (uint32_t)heth->TxDesc); }Register
DMATPDR: ' Bits 31:0 TPD: Transmit poll demand
When these bits are written with any value, the DMA reads the current descriptor pointed toby the ETH_DMACHTDR register. If that descriptor is not available (owned by Host),transmission returns to the Suspend state and ETH_DMASR register bit 2 is asserted. If thedescriptor is available, transmission resumes.'The problem is ETH_DMACHTDR update on time(maybe not, cause printf also take time) by print it when ping delay over time occur. If It's update on time, then tx descriptor should be available(owned by DMA), But the result is it's unabailable . so the ping reply would delay untill next packet sent
DMASR=0X00360400; TxDescriptor addr= 0X20019E30; 0X20019E50
icmp_input: ping
DMASR=0X00360400; TxDescriptor addr= 0X20019E50; 0X20019E70
icmp_input: ping
DMASR=0X00360400; TxDescriptor addr= 0X20019E70; 0X20019E10
icmp_input: ping
DMASR=0X00660404; TxDescriptor addr= 0X20019E10; 0X20019E30
icmp_input: ping
DMASR=0X00360400; TxDescriptor addr= 0X20019E10; 0X20019E50
icmp_input: ping
DMASR=0X00360400; TxDescriptor addr= 0X20019E50; 0X20019E70
icmp_input: ping
DMASR=0X00360400; TxDescriptor addr= 0X20019E70; 0X20019E10
The conclude is there's confilict betweenDMASR=0X00660404 and DMACHTDR = 0X20019E10; My new question is when registerDMACHTDR is updated by DMA?
2017-11-20 06:59 PM
Did you find a solution to this problem? I have the same problem and don't want to waste too much time if you already know the answer. Thanks for sharing.
2017-11-28 12:11 PM
This solution worked for me. I found it on this forum:
https://community.st.com/0D50X00009XkgffSAB
Basically, just add '
__DSB();
' just before the check when Tx Buffer is unavailable. @ https://community.st.com/0D50X00009XkgffSAB#comment-168645
onhttps://community.st.com/0D50X00009XkgffSAB#comment-170221
diff --git a/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.c b/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.cindex 527ed.07eeba0 100644--- a/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.c+++ b/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.c@@ -752,7 +752,12 @@ HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameL heth->TxDesc = (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr); } }-++ /* DNIL: Sync here before moving on. Otherwise we seem to have intermittent issues with stores to+ * TxDesc->Status register not reaching the DMA engine.+ */+ __DSB();+ /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) {