cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H743ZI (STM32H743ZI) no Ethernet DMA transfer

Joerg Wagner
Senior III
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.
36 REPLIES 36
Posted on December 06, 2017 at 19:52

You have i.e.

ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section('.RxDecripSection'))); /* Ethernet Rx DMA Descriptors */

but in your linker script is the name Dest0Section used, and this is not referenced.

.RxDecripSection : {*(.Dest0Section)} >DMARxDscr_Memory

You can check this in Debug/output.map

Search for DMARxDscrTab, for example. This will not be at the right place in the memory.

Solution:

Take the same names in the linker sections:

.RxDecripSection : {*(.RxDecripSection)} >DMARxDscr_Memory

.TxDecripSection : {*(.TxDecripSection)} >DMATxDscr_Memory

.RxArraySection : {*(.RxArraySection)} >Rx_Buff_Memory

Now the output.map entries have to be set to the appropiate origins, like 0x30040000,....

Posted on December 06, 2017 at 22:59

this is my ouput.map entries related to DMA:

.RxDecripSection

0x30040000 0x60

*(.Dest0Section)

.RxDecripSection

0x30040000 0x60 Src/ethernetif.o

0x30040000 DMARxDscrTab

.TxDecripSection

0x30040060 0x60

*(.Dest0Section)

.TxDecripSection

0x30040060 0x60 Src/ethernetif.o

0x30040060 DMATxDscrTab

.RxArraySection

0x30040200 0x17e0

*(.Dest0Section)

.RxArraySection

0x30040200 0x17e0 Src/ethernetif.o

0x30040200 Rx_Buff

It looks like the linker knows how to map from

.RxDecripSection : {*(.Dest0Section)} >DMARxDscr_Memory

.TxDecripSection : {*(.Dest0Section)} >DMATxDscr_Memory

.RxArraySection : {*(.Dest0Section)} >Rx_Buff_Memory

to the correct addresses.

Butyour reference helped meunderstand the nature of my problem..

in case it will interest someone, I had a race condition between 2 tasks (tcpServer task, dhcp task):

Since the DHCP server managed to allocate the dynamic IP, the tcp server was suppose to work, but it didn't.

The problem was thattcpServer task executed before the dhcp task manages tofinish all the initialization.

I moved the tcpServer init task code to the dhcp thread so it will be executed after

dhcp_supplied_address returns true.

Like that, just to try if it help, and it solved the whole issue!

case DHCP_WAIT_ADDRESS:

{

if (dhcp_supplied_address(netif))

{

DHCP_state = DHCP_ADDRESS_ASSIGNED;

tcpServer_init();

}

Thank you Joerg very much for you help and support, I really appreciate it , since this is my first board/processor tryout.

JReim
Associate II

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

Joerg Wagner
Senior III

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

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
Associate II

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

Joerg Wagner
Senior III

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

JReim
Associate II

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

edwin8
Associate II

I am also having problems with LwIP on the NUCLEO-H743ZI . I have these problems when I run the LWIP example from STM32Cube_FW_H7_V1.3.0\Projects\STM32H743ZI-Nucleo\Applications\LwIP\LwIP_HTTP_Server_Netconn_RTOS:

  1. In DHCP mode, the board gets an IP address, but I only get ping responses from it only 1 out of every 30 to 50 request. I don't see any ARP responses except for one gratuitous ARP on reset. Strange thing is, the HTTP webpage is very responsive.
  2. In Static IP mode, I don't get any ARP responses, and so no ping nor HTTP response.

Any suggestions on what I can do to make ARPs/pings work better in DHCP mode and make static IP mode work? Thanks for your help.

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.