cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746 Ethernet DMA Transmit problem

zoltan2
Associate II
Posted on August 11, 2016 at 11:57

Hi,

I am developing Ethernet driver on STM32F7-DISCO board.

I set buffer address, buffer size in Tx descriptor.

Then I set control bits in TDES0 of Tx descriptor and write DMATPDR register to send the frame.

However the frame is not sent out. If I try to transit a new frame both the previous one and the new one are sent together after each other.

If I do some delay between setting OWN bit in TDES0 and writing DMATPDR register the frame will be sent immediately.

I found similar behavior with the STM32 FW (STM32Cube_FW_F7_V1.4.0) delivered with STM32F7-DISCO board.

I changed Ethernet HAL driver so that I exchanged code lines with setting next descriptor address and setting OWN bit, and the frame is not transmitted.

I simply did this:

original code order in stm32f7xx_hal_eth.c fn: HAL_ETH_TransmitFrame():

  /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */

    heth->TxDesc->Status |= ETH_DMATXDESC_OWN;

  /* Point to next descriptor */

    heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);

after changing the code order:

  /* Point to next descriptor */

    heth->TxDesc= (ETH_DMADescTypeDef *)(heth->TxDesc->Buffer2NextDescAddr);

  /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */

    heth->TxDesc->Status |= ETH_DMATXDESC_OWN;

Can anyone help me to overcome this problem?

Thanks!

Zoli

#dma #ethernet #stm32f
18 REPLIES 18
dirk2
Associate
Posted on November 03, 2016 at 16:38

Hi,

I experience the same problems. Also when adding the delay the packets get transmitted. Have got any sort of solution for this?
Amel NASRI
ST Employee
Posted on December 26, 2016 at 11:36

Hello,

Please check the following:

  • is datacache enabled?
  • if yes, please check your MPU configuration
  • a cache clean is required if DMA source or destination buffers are located in cache-able regions of memory.

You may find some more hints in

http://www.st.com/content/ccc/resource/technical/document/application_note/group0/08/dd/25/9c/4d/83/43/12/DM00272913/files/DM00272913.pdf/jcr:content/translations/en.DM00272913.pdf

.

-Amel-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on January 21, 2017 at 11:50

Hi,

I've been debugging this for quite a few hours now, wish I had found this thread sooner... Being almost certain that I had done something wrong outside HAL, I've gone through quite a few iterations.

In any case, what I have conluded is that there is likely a race condition in the HAL HAL_ETH_TransmitFrame (stm32f7xx_hal_eth.c, version V1.1.2). I have two projects with the F746, one that 'works' and one that fails to transmit a frame every now and then. The project that works is generated by STM32CubeMX and uses lwIP and the ST supplied driver between lwIP and HAL. Second project which has issues is using FreeRTOS+TCP stack and a modified version of the driver supplied by FreeRTOS written for STM32F4.

In the project that fails I have the I-cache enabled and D-cache disabled on my F746 running at 192MHz, but the default setting in Cube project seems to be to have the ART-accelerator as well as both D and I-caches disabled which slows down things in general which appears to mask this issue.

What appears to be the issue though is that the store instructions the CPU is doing towards the 

T

xDesc resgisters, for example 

TxDesc->Status |= ETH_DMATXDESC_OWN are not actually seen by the DMA engine when the DMA transmission is resumed;

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;

}

Note that in the CubeMX project driver, this restart sequence is actually performed twice (one in the HAL driver, and once in the low_level_output() function in ethernetif.c , which also masks this issue.

My 'solution' was to add a synchronization barrier inside the HAL driver, after filling in the TxDesc and before restarting the DMA engine from the suspended state. That appears to solve the problem, but I'm hoping someone at ST can shed some more light on this topic.

//Daniel

Posted on February 11, 2017 at 19:56

Thank you, Daniel,  for your message here. I had facing same issue with sending eth frame with HAL ... and I was not able to fix it within few days of work ... But now You helped me and my project is running and sending data again !!!!

Can someone from ST confirm issue/solution officially ?

Adrian F
Associate
Posted on September 14, 2017 at 11:38

I have the same issue of dropped packets, but without using RTOS on an STM32F746. I only use the CubeMX provided HAL drivers and have dropped packets on fast transmissions.

This fails for me randomly:

      if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)

      {

        errval = ERR_USE;

        goto error;

      }

I have no caches enabled and it still happens. Do you have any suggestions?

Kind regards

Posted on September 28, 2017 at 22:14

Hi,

I guess you could be running into the same issue. It's been quite a while since I reported this, but I haven't seen any response from STs side. These issues are obviously quite hard to debug, and since the HAL code appears to mask them I guess ST testcases still works. Below is my patch to fix my issue, I haven't had a problem in this area since I applied this fix.

Regards

Daniel

diff --git a/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.c b/fw/controller/system/src/stm32f7-hal/stm32f7xx_hal_eth.c
index 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)
 {
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Posted on October 03, 2017 at 17:12

Thank's a lot. It solve my problem. When St corrects this problem in CubeMX?

Posted on October 03, 2017 at 18:45

You're welcome. Part of the motivation to post fixes here is of course to get it fixed in subsequent releases of HAL for F7, however I have no idea how to get in touch with anyone at ST working on this code. Since I posted the 'fix' here 8 months I haven't seen any action from ST what so ever. Note though that I just have a theory that the the CPU performs a store operation towards the DMA engine, this store is not completed before the CPU restarts the DMA transmission. If this really is what is happening is hard to tell, only ST has the information on how this is connected internally. The ST supplied examples work because they restart the DMA transmission twice. I think this is also an error, but I don't use that part of the ST example code so I haven't bothered fixing it. Once you try to use the HAL layer directly, as it was intended, you start seeing these issues.

Posted on November 28, 2017 at 20:33

This is great information!  Thanks for taking the time to post the fix.