Skip to main content
Joerg Wagner
Senior III
October 8, 2017
Solved

NUCLEO-H743ZI (STM32H743ZI) no Ethernet DMA transfer

  • October 8, 2017
  • 14 replies
  • 8250 views
Posted on October 08, 2017 at 15:11

Hi all.

Does anyone have a working example for Ethernet?

I tried to build one wih CubeMX (HAL 1.1.0) with and without FreeRTOS.

I did it many times for F746, F767 (A and Z) and F769 (A) but Ethernet with STM32H743ZI (Ver. Y) will not work.

- IDE is OpenSTM32 (GNU C)

- RAM is AXI SRAM in Domain D1 or AHB SRAM1 in Domain D2

- no DTCM RAM is used (in linker script: i.e. RAM_D1 >AT FLASH, _estack is adapted)

- Instruction Cache enabled and Data Cache is disabled

- no MPU

- ethernetif.c line 421 is commented out: // SCB_CleanInvalidateDCache();

- ethernetif.c line 443 is commented out: // SCB_CleanInvalidateDCache();

Another options:

- using 0x30040000 and MPU for DMARxDscrTab[ETH_RX_DESC_CNT] and DMATxDscrTab[ETH_TX_DESC_CNT]

- DHCP or static IP

- Data cache enabled and using original SCB_CleanIvalidDCache();

The result:

stm32h7xx_hal_eth.c : HAL_ETH_Transmit(...) throws a timeout in line 708 and returns HAL_ERROR

which is not recognized by low_level_output() in ethernetif.c

Using a different timeout value (>0) in the HAL_ETH_Transmit( &heth, &TxConfig, myTimeOutVal) throws a timeout as well.

When I enable MPUETHADDR16_COPY(&ethhdr->src, src); in ethernet.c it will end in Infinite_Loop. (Edited: wrong MPU settings)

Using AHB SRAM2 in Domain D2, the software cannot be debugged. I hope not to forget something: payload is in domain D2, LAN8742 is activated in CubeMX (Platform settings), ...

In conclusion: The DMA transfer does not work.

I spent so many hours to find a solution and I'm thankful for any advice.

Note: this post was migrated and contained many threaded conversations, some content may be missing.
This topic has been closed for replies.
Best answer by Joerg Wagner
Posted on October 23, 2017 at 15:13

Using HAL only works.

The next CubeMX release should fix this. There are many differences in the produced code.

A good starting point to use HAL only and to get mature.

- Joerg -

14 replies

Oussema Hajjem_O
Visitor II
October 9, 2017
Posted on October 09, 2017 at 15:30

Hello Joerg,

When the HAL_ETH_Transmit(...) throws a timeout, it doesn't mean that the DMA transfer failed, it means that the Transmit function returned without waiting for the Tx status (Transmission is ongoing)

Please ensure that your DMA descriptors are configured by MPU as Device (not cacheable).

For more information, please refer to the HTTP server application in the STM32Cube H7 FW package: 

..\Projects\STM32H743ZI-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS\

Best regards,

Oussema

Joerg Wagner
Senior III
October 9, 2017
Posted on October 09, 2017 at 18:39

Hello Oussema.

I connected a scope to the signals RMII_TXD0 and RM_TXD1. There is no traffic anytime!

This is a note in the original hal driver:

@Note: This interface is implemented to operate in zero-copy mode only:

        - Rx buffers are allocated statically and passed directly to the LwIP stack

          they will return back to DMA after been processed by the stack.

        - Tx Buffers will be allocated from LwIP stack memory heap,

          then passed to ETH HAL driver.

Why are Tx Buffers allocated from heap? If your data is in DTCMRAM there is no interconnect to the DMA. Anyway, but I tried it also to put TxBuffer in 0x3400XXXX and somewhere else except DTCM, not cacheable.

Using SW4STM32, I prepared the linker script to have the ETH descriptors like in LwIP (0x34000000, 0x34000060) with this in MPU_Config():

  MPU_InitStruct.Enable = MPU_REGION_ENABLE;

  MPU_InitStruct.Number = MPU_REGION_NUMBER0;

  MPU_InitStruct.BaseAddress = 0x30040000;

  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;

  MPU_InitStruct.SubRegionDisable = 0x0;

  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;

  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;

  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;

  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

I visited a friend with the board to use KEIL and we adopted a sample MDK project from H743-EVAL to NUCLEO-H743, because the __attribute__ sections are already prepared. Same result: no traffic.

In the reference manual RM0433 on page 2679 cont'd is an explanation of the DMA flow. This means in my case the Own bit is set but not resetted by the controller.

Thank you, Joerg

Oussema Hajjem_O
Visitor II
October 9, 2017
Posted on October 09, 2017 at 19:28

Hello Joerg,

To ensure zero-copy, the ETH driver needs to send buffers allocated by the LwIP stack and not copy them in any other shadow buffers.

If you are using 

DTCMRAM, it is obvious that Tx buffers will be allocated in this memory, so you have to relocate the LWIP heap to D1 or D2 SRAM by defining LWIP_RAM_HEAP_POINTER in the lwipopts.h file.

Could you please check the Fatal Bus Error bit of the DMACSR register, after trying to send data, if it's SET, so it's clear that the Tx buffers are in DTCMRAM.

also please try to run the application with RAM starting from 0x24000000 (don't use theDTCMRAM)

Hope this will help you,

Best regards,

Oussema.

Joerg Wagner
Senior III
October 14, 2017
Posted on October 14, 2017 at 21:22

I prepared an application (simple) with RTOS and static IP: 192.168.99.85/24, destination 192.168.99.99/24

ARP request is sent:

'Who has 192.168.99.99? Tell 192.168.99.85'

The oscilloscope shows the answer on PC4/PC5 (RMII_RXD0 / RMII_RXD1):

'192.168.99.99 is at ...'

But then another broadcast ARP packet is sent:

'Who has 192.168.42.0? Tell 192.168.99.85' [ETHERNET FRAME CHECK SEQUENCE INCORRECT]

This confuses me, the netmask is set to 255.255.255.0.

The request will loop forever, because ARP cannot be resolved, UDP and TCP are not useable.

LWIP_DEBUG shows:

etharp_request: sending ARP request.

etharp_raw: sending raw ARP packet.

ethernet_output: sending packet 0x30000008

etharp_timer

...

Joerg

Joerg Wagner
Joerg WagnerAuthorBest answer
Senior III
October 23, 2017
Posted on October 23, 2017 at 15:13

Using HAL only works.

The next CubeMX release should fix this. There are many differences in the produced code.

A good starting point to use HAL only and to get mature.

- Joerg -

Amel NASRI
ST Technical Moderator
October 23, 2017
Posted on October 23, 2017 at 16:48

Hi

Wagner.Joerg

‌,

The CubeMX related issues are reported internally for farther checks to be fixed in coming releases.

Thanks for sharing your findings.

-Amel

To give better visibility on the answered topics, please click on "Best Answer" on the reply which solved your issue or answered your question.
Marina Brener
Associate III
December 4, 2017
Posted on December 04, 2017 at 22:06

Hello

DAHMEN.IMEN

and

Wagner.Joerg

,

I have been having the same problem, I am trying to create viaCubeMX eth+lwip+dma+dhcp project, no luck.

Tried with rtos and without it, tried setting the sections in the linker for the DMA.

Any update on the reported issues?

Thanks,

Marina

Joerg Wagner
Senior III
December 4, 2017
Posted on December 04, 2017 at 22:31

Hello

marina.brener

.

I opened already another topic with advices. Do the modifications and you can use Ethernet:

https://community.st.com/0D50X00009XkYPnSAN

Please use a memory section for Ethernet DMA which is not located in DTCMRAM.

JReim
Visitor II
October 29, 2018

Hi, would you be so kind to provide a working example, I can not get it to work properly.

Joerg Wagner
Senior III
October 29, 2018

You will find a working example of ST in the Cube Repository.

For example for H743ZI:

STM32Cube/Repository/STM32Cube_FW_H7_V1.3.0/Projects//STM32H743ZI-Nucleo/Applications/LwIP

Joerg Wagner
Senior III
October 29, 2018

You will find a working example of ST in the Cube Repository.

For example for H743ZI:

STM32Cube/Repository/STM32Cube_FW_H7_V1.3.0/Projects//STM32H743ZI-Nucleo/Applications/LwIP

JReim
Visitor II
October 29, 2018

This only contains a RTOS example which is extremely stuffed with junk :)

Joerg Wagner
Senior III
October 29, 2018

RTOS should be preferred instead of polling. Take the advantage of interrupts.

Piranha
Principal III
December 20, 2018

Not using RTOS doesn't imply use of polling. One can use interrupts and event flags without RTOS perfectly fine. For example, with some simple cooperative scheduler.

JReim
Visitor II
October 29, 2018

We can not use such a framework, we are using highly optimized code for our application.