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 October 15, 2017 at 11:45

Hello Ouseema.

This while () is never entered in my app (file stm32h7xx_hal_eth.c) :

uint8_t HAL_ETH_IsRxDataAvailable(ETH_HandleTypeDef *heth)

{

ETH_RxDescListTypeDef *dmarxdesclist = &heth->RxDescList;

uint32_t descidx = dmarxdesclist->CurRxDesc;

ETH_DMADescTypeDef *dmarxdesc = (ETH_DMADescTypeDef *)dmarxdesclist->RxDesc[descidx];

uint32_t descscancnt = 0;

uint32_t appdesccnt = 0, firstappdescidx = 0;

if(dmarxdesclist->AppDescNbr != 0)

{

/* data already received by not yet processed*/

return 0;

}

/* Check if descriptor is not owned by DMA */

while((READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_OWN) == (uint32_t)RESET) && (descscancnt < ETH_RX_DESC_CNT))

{

descscancnt++;

<<<---- never reached

/* Check if last descriptor */

if(READ_BIT(dmarxdesc->DESC3, ETH_DMARXNDESCWBF_LD) != (uint32_t)RESET)

{

/* Increment the number of descriptors to be passed to the application */

appdesccnt += 1U;

if(appdesccnt == 1)

{

WRITE_REG(firstappdescidx, descidx);

}

...

Do you have a working example using Ethernet for the NUCLEO-H734ZI board?

Thank you, Joerg

Joerg Wagner
Senior III
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 Employee
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 Accept as Solution on the reply which solved your issue or answered your question.

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

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.

Posted on December 05, 2017 at 15:42

Wagner.Joerg

‌,

Great catch on the PG11 and PG13 reserved pins, it worked!!! Very helpful, Thanks! Do you know how to change cubes generated code so it will reserve the correct pins without the need to edit the generated code?

Posted on December 05, 2017 at 16:03

Put it in the file ethernetif.c in function HAL_ETH_MspInit like this:

  /* USER CODE BEGIN ETH_MspInit 1 */

    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF11_ETH;

    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /* USER CODE END ETH_MspInit 1 */
Posted on December 06, 2017 at 05:03

Hello,

So, now my project includes Eth, lwip, dchp, and freeRTos. The DCHP server allocates dynamicly the IP address and my tcp server which I took from the tcp echo server example starts listening on port All good so far..

BUT when I start my tcp client on windows 7 (.NET), it tries to connect to the server based on the IP and port 80 with NO success. It worked fine when i was running the lwip + rtos example that came with H7 package.

This is the flow:

The tcp server calls

netconn_listen(conn) and then callsnetconn_accept(conn, &newconn);

netconn_accept calls

sys_arch_mbox_fetch and it hangs forever.

Line 414 in api_lib.c file:

if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT)

I can seethat theDMA and thelow_level_input in ethernerif.c file are executed properly so my guess is I

did not configure something the right wayfor freeRTos in the CubeMX.

Can someone help? Did anyone tried and succeededto use RTos with eth ?

Maybe someone can point me in the right direction?

DAHMEN.IMEN

Thanks,

Marina

Posted on December 06, 2017 at 16:20

Hello Marina. I do not have troubles using FreeRTOS.

Which IDE do you use? If SW4STM32, did you change the linker script?

I modified ethernetif.c like this:

ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section('.SRAM_D2')));

ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section('.SRAM_D2')));

uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE] __attribute__((section('.SRAM_D2')));
Posted on December 06, 2017 at 19:40

Hi Joerg,

I am working on SW4STM32, my buffers look like this: 

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

ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section('.TxDecripSection'))); /* Ethernet Tx DMA Descriptors */

uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE] __attribute__((section('.RxArraySection'))); /* Ethernet Receive Buffers */

my linker file looks like this:

/*

*****************************************************************************

**

** File : LinkerScript.ld

**

** Abstract : Linker script for STM32H743ZITx Device with

** 2048KByte FLASH, 1056KByte RAM

**

** Set heap size, stack size and stack location according

** to application requirements.

**

** Set memory bank area and size if external memory is used.

**

** Target : STMicroelectronics STM32

**

**

** Distribution: The file is distributed as is, without any warranty

** of any kind.

**

** (c)Copyright Ac6.

** You may use this file as-is or modify it according to the needs of your

** project. Distribution of this file (unmodified or modified) is not

** permitted. Ac6 permit registered System Workbench for MCU users the

** rights to distribute the assembled, compiled & linked contents of this

** file as part of an application binary file, provided that it is built

** using the System Workbench for MCU toolchain.

**

*****************************************************************************

*/

/* Entry Point */

ENTRY(Reset_Handler)

/* Highest address of the user mode stack */

_estack = 0x24080000; /* end of RAM */

/* Generate a link error if heap and stack don't fit into RAM */

_Min_Heap_Size = 0x200; /* required amount of heap */

_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */

MEMORY

{

DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K

RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K

RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K

RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K

ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K

FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K

DMARxDscr_Memory (xrw) : ORIGIN = 0x30040000, LENGTH = 0x60

DMATxDscr_Memory (xrw) : ORIGIN = 0x30040060, LENGTH = 0x19F

Rx_Buff_Memory (xrw) : ORIGIN = 0x30040200, LENGTH = 0x2000

}

/* Define output sections */

SECTIONS

{

/* The startup code goes first into FLASH */

.isr_vector :

{

. = ALIGN(4);

KEEP(*(.isr_vector)) /* Startup code */

. = ALIGN(4);

} >FLASH

/* The program code and other data goes into FLASH */

.text :

{

. = ALIGN(4);

*(.text) /* .text sections (code) */

*(.text*) /* .text* sections (code) */

*(.glue_7) /* glue arm to thumb code */

*(.glue_7t) /* glue thumb to arm code */

*(.eh_frame)

KEEP (*(.init))

KEEP (*(.fini))

. = ALIGN(4);

_etext = .; /* define a global symbols at end of code */

} >FLASH

/* Constant data goes into FLASH */

.rodata :

{

. = ALIGN(4);

*(.rodata) /* .rodata sections (constants, strings, etc.) */

*(.rodata*) /* .rodata* sections (constants, strings, etc.) */

. = ALIGN(4);

} >FLASH

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH

.ARM : {

__exidx_start = .;

*(.ARM.exidx*)

__exidx_end = .;

} >FLASH

.preinit_array :

{

PROVIDE_HIDDEN (__preinit_array_start = .);

KEEP (*(.preinit_array*))

PROVIDE_HIDDEN (__preinit_array_end = .);

} >FLASH

.init_array :

{

PROVIDE_HIDDEN (__init_array_start = .);

KEEP (*(SORT(.init_array.*)))

KEEP (*(.init_array*))

PROVIDE_HIDDEN (__init_array_end = .);

} >FLASH

.fini_array :

{

PROVIDE_HIDDEN (__fini_array_start = .);

KEEP (*(SORT(.fini_array.*)))

KEEP (*(.fini_array*))

PROVIDE_HIDDEN (__fini_array_end = .);

} >FLASH

/* used by the startup to initialize data */

_sidata = LOADADDR(.data);

/* Initialized data sections goes into RAM, load LMA copy after code */

.data :

{

. = ALIGN(4);

_sdata = .; /* create a global symbol at data start */

*(.data) /* .data sections */

*(.data*) /* .data* sections */

. = ALIGN(4);

_edata = .; /* define a global symbol at data end */

} >RAM_D1 AT> FLASH

/* Uninitialized data section */

. = ALIGN(4);

.bss :

{

/* This is used by the startup in order to initialize the .bss secion */

_sbss = .; /* define a global symbol at bss start */

__bss_start__ = _sbss;

*(.bss)

*(.bss*)

*(COMMON)

. = ALIGN(4);

_ebss = .; /* define a global symbol at bss end */

__bss_end__ = _ebss;

} >RAM_D1

/* User_heap_stack section, used to check that there is enough RAM left */

._user_heap_stack :

{

. = ALIGN(8);

PROVIDE ( end = . );

PROVIDE ( _end = . );

. = . + _Min_Heap_Size;

. = . + _Min_Stack_Size;

. = ALIGN(8);

} >RAM_D1

/* Remove information from the standard libraries */

/DISCARD/ :

{

libc.a ( * )

libm.a ( * )

libgcc.a ( * )

}

.ARM.attributes 0 : { *(.ARM.attributes) }

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

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

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

}

I copied the linker from the demo application, how does your linker file look like?