cancel
Showing results for 
Search instead for 
Did you mean: 

STM32CubeIDE generates bad GPIO initialization code for Ethernet peripheral

crazy88
Associate II
Post edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code

# STM32CubeIDE ETH Configuration Bug Report

 

## Issue Summary
STM32CubeIDE fails to generate proper GPIO initialization code for Ethernet peripheral, resulting in non-functional MDIO/MDC communication with PHY chips.

 

## Environment
- **STM32CubeIDE Version**: 1.19.0
- **MCU**: STM32F407ZGT6 (LQFP144 package)
- **PHY**: YT8512C
- **Interface**: RMII mode
- **Date**: September 28, 2025

 

## Problem Description

 

### Configuration in .ioc File (Correct)
The STM32CubeIDE project configuration file (`.ioc`) shows correct pin assignments:
```
PC1.Mode=RMII
PC1.Signal=ETH_MDC
PA2.Mode=RMII  
PA2.Signal=ETH_MDIO
ETH.MediaInterface=HAL_ETH_RMII_MODE
```

 

### Generated Code Issue (Incorrect)
However, STM32CubeIDE **fails to generate the required `HAL_ETH_MspInit()` function** in `stm32f4xx_hal_msp.c`. This results in:

 

1. **Missing GPIO configuration**: PC1 and PA2 pins are not configured as alternate function AF11
2. **Default GPIO state**: Pins remain in their default configuration (typically AF0)
3. **Non-functional MDIO interface**: PHY register reads always return 0x0000
4. **Network connectivity failure**: Cannot establish Ethernet communication

 

### Symptoms Observed
- PHY register reads via `HAL_ETH_ReadPHYRegister()` always return 0x0000
- PHY not responding to MDIO commands
- Network interface fails to initialize properly
- Cable insertion/removal has no effect on link status

 

### Root Cause Analysis
Investigation revealed that the GPIO registers showed incorrect configuration:
- PC1 (MDC): Mode=0x0, AF=0x0 (should be Mode=0x2, AF=0xB)  
- PA2 (MDIO): Mode=0x0, AF=0x0 (should be Mode=0x2, AF=0xB)

 

The missing `HAL_ETH_MspInit()` function should contain:
void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(heth->Instance==ETH)
  {
    /* Peripheral clock enable */
    __HAL_RCC_ETH_CLK_ENABLE();
    __HAL_RCC_ETHMAC_CLK_ENABLE();
    __HAL_RCC_ETHMACTX_CLK_ENABLE();
    __HAL_RCC_ETHMACRX_CLK_ENABLE();
   
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /* ... other GPIO clocks ... */
   
    /**ETH GPIO Configuration
    PC1     ------> ETH_MDC
    PA2     ------> ETH_MDIO
    /* ... other ETH pins ... */
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    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(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    /* ... */
  }
}

 

## Workaround Solution
Manual GPIO configuration in user code successfully resolves the issue:
 
// Enable GPIO clocks
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();


// Configure PA2 (MDIO) as AF11
GPIOA->MODER = (GPIOA->MODER & ~(0x3 << 4)) | (0x2 << 4);
GPIOA->AFR[0] = (GPIOA->AFR[0] & ~(0xF << 8)) | (0xB << 8);


// Configure PC1 (MDC) as AF11  
GPIOC->MODER = (GPIOC->MODER & ~(0x3 << 2)) | (0x2 << 2);
GPIOC->AFR[0] = (GPIOC->AFR[0] & ~(0xF << 4)) | (0xB << 4);

 

After applying this workaround, PHY communication is immediately restored and network functionality works correctly.

 

## Impact Assessment
- **Severity**: High - Ethernet functionality completely non-functional
- **Scope**: Affects all STM32F4 projects using ETH peripheral with STM32CubeIDE
- **Workaround Available**: Yes, but requires manual intervention

 

## Expected Behavior
STM32CubeIDE should automatically generate the complete `HAL_ETH_MspInit()` function in `stm32f4xx_hal_msp.c` when ETH peripheral is enabled in the .ioc configuration, including proper GPIO alternate function configuration for all assigned ETH pins.

 

## Reproduction Steps
1. Create new STM32F407ZGT6 project in STM32CubeIDE 1.19.0
2. Enable ETH peripheral in RMII mode
3. Assign pins PC1→ETH_MDC, PA2→ETH_MDIO
4. Generate code
5. Observe missing `HAL_ETH_MspInit()` function in generated `stm32f4xx_hal_msp.c`
6. Compile and run - PHY communication will fail

 

## Request for Fix
Please investigate and fix the STM32CubeIDE code generator to ensure proper `HAL_ETH_MspInit()` function generation for ETH peripheral configurations.

 

---
**Reported by**: XINYU SONG
**Project**: Dispenser Control System  
**Contact**: 1301621323@qq.com
5 REPLIES 5
Ghofrane GSOURI
ST Employee

Hello @crazy88 

Following your description of reproduction steps:

1. Create new STM32F407ZGT6 project in STM32CubeIDE 1.19.0
2. Enable ETH peripheral in RMII mode
3. Assign pins PC1→ETH_MDC, PA2→ETH_MDIO (This step will be automatically done  by MX )
4. Generate code

By checking stm32f4xx_hal_msp.c , the following code will be generated successfully using CubeMX 6.15.0 and IDE 1.19.0 

void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(heth->Instance==ETH)
  {
    /* USER CODE BEGIN ETH_MspInit 0 */

    /* USER CODE END ETH_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ETH_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**ETH GPIO Configuration
    PC1     ------> ETH_MDC
    PA1     ------> ETH_REF_CLK
    PA2     ------> ETH_MDIO
    PA7     ------> ETH_CRS_DV
    PC4     ------> ETH_RXD0
    PC5     ------> ETH_RXD1
    PB11     ------> ETH_TX_EN
    PB12     ------> ETH_TXD0
    PB13     ------> ETH_TXD1
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
    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(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
    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(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|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(GPIOB, &GPIO_InitStruct);

    /* USER CODE BEGIN ETH_MspInit 1 */

    /* USER CODE END ETH_MspInit 1 */

  }

}

 

But since you have mentioned that you are using **PHY**: YT8512C , not  using LAN8742 or DP83848 ( in those cases the GPIO code will be placed  in ethernetif.c).

Could you please provide your project?

THX

Ghofrane

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.

Dear @Ghofrane,

Thank you for your prompt response and verification! The earlier issues with pin multiplexing initialization and the uninitialized PD3 REST pin only occurred during the first code generation and were resolved after reconfiguration.

The current main problem is that the ICMP test keeps failing. I’m using a third-party development board, and the hardware has been proven functional through official examples. However, after using STM32CubeIDE with FreeRTOS + LWIP, the ICMP test has never passed, and even the ETH interrupt has not been triggered. I’ve been troubleshooting for nearly half a month and am unable to resolve it. Could you please help me identify the issue?

Thank you! I'll post my code tomorrow after my last try,lol

Best regards, crazy88

I finally worked  out, but i have encountered bigger problem.

i post my project on github : https://github.com/ABEGINNER-poor/dispenserBeneth.git

The reason why i can not successfully receive data ,is that the isr priority not be setted.

void HAL_ETH_MspInit(ETH_HandleTypeDef* heth)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(heth->Instance==ETH)
  {
    /* USER CODE BEGIN ETH_MspInit 0 */

    /* USER CODE END ETH_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ETH_CLK_ENABLE();
    __HAL_RCC_ETHMAC_CLK_ENABLE();
    __HAL_RCC_ETHMACTX_CLK_ENABLE();
    __HAL_RCC_ETHMACRX_CLK_ENABLE();
   
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();

    /**ETH GPIO Configuration    
    PC1     ------> ETH_MDC
    PA1     ------> ETH_REF_CLK
    PA2     ------> ETH_MDIO
    PA7     ------> ETH_CRS_DV
    PC4     ------> ETH_RXD0
    PC5     ------> ETH_RXD1
    PG11     ------> ETH_TX_EN
    PG13     ------> ETH_TXD0
    PG14     ------> ETH_TXD1
    PD3      ------> ETH_RESET
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    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(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
    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(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
    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(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13|GPIO_PIN_14;
    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);

    /* Configure ETH_RESET Pin (PD3) */
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
   
    /* Reset PHY */

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_RESET);
    HAL_Delay(10);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_SET);

    HAL_Delay(100);

    /* USER CODE BEGIN ETH_MspInit 1 */
    /* Configure ETH interrupt */
    HAL_NVIC_SetPriority(ETH_IRQn, 6, 0);
    HAL_NVIC_EnableIRQ(ETH_IRQn);
    /* USER CODE END ETH_MspInit 1 */
  }
}
but as you can see , the generator did not give me the right code ,and i have to set in
the user area on my own .but something even more strange things happend, these configruation
can still affect the running job ,when i configure the eht isr to 6,
below configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ,it dose worked.but when i check out
the HAL_ETH_MspInit ,the code still be HAL_NVIC_SetPriority(ETH_IRQn, 5, 0); then i delete
this line and reupload ,the eth interrupt was not working, so i deeply confussed.
crazy88_0-1759345768478.png

 

 

Hello @crazy88 

I have reviewed your IOC file and noticed that you enabled both ETH and LWIP without selecting a PHY driver

GhofraneGSOURI_0-1760364284475.png

In this scenario, since the configuration is incomplete (specifically, the Platform Settings under LWIP), CubeMX will not generate the necessary GPIO initialization code for Ethernet, which is the expected behavior.

As a workaround, you copied the initialization code that CubeMX generated when only ETH was enabled. I assume that, in this configuration, the Ethernet interrupt priority was set to 5  then you  placed this code in the user section 0 of stm32f4xx_hal_msp.c.

GhofraneGSOURI_1-1760364450843.png

Is that how you proceeded?

THX

Ghofrane

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.

i'am sorry to reply so late,i' ve been busy these days. and,yes,that's exactly what i did.I put these code in the user section of stm32f4xx_hal_msp.c. I want to know which function of whinch file for the generator generate HAL_NVIC_SetPriority ,thx;