cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 MAC-to-MAC possible? With HAL?

OFAUR.1763
Associate II

The STM32F7 supports Ethernet with MAC (and DMA), according to doc en.DM00224583.pdf.

I try to connect it to a KSZ9896 (ethernet switch) that provides a direct MAC interface in RMII.

The KSZ provides configuration bits similar to the STM32 ETH_MACxxx.

I wonder if the connection between the 2 RMIIs needs any PHY.

STM32 MAC <--> KSZ MAC
OR
STM32 MAC <--> PHY <--> KSZ MAC
OR
STM32 MAC <--> PHY1 <--> PHY2 <--> KSZ MAC
  • Theoretically, does a MAC-to-MAC connection requires any PHY? 0, 1 or 2? (my guess: 0)
  • Does the STM32F7 specifically requires any PHY with its MAC layer?
  • Is it possible to customize the HAL to bypass the PHY related code, and use only the MAC related code?

Thanks in advance for your comments and answers!

1 ACCEPTED SOLUTION

Accepted Solutions
OFAUR.1763
Associate II

I've a better answer !

In the code generated by the cube, there is a

ETH_HandleTypeDef heth;

In the code, you need to set the adress of the PHY :

heth.Init.PhyAddress = 0; // or 1, or...

There is a default values for DP83848, for example, but you need to use the one corresponding to your PHY.

LAZY TIP: if you're lazy, try 0 and 1, there are usually the good guess 😂

BUT there is more for the KSZ9896C !

You don't have one PHY but... 5 !

According to the doc, with PhyAddress=0, you configure general settings.

If you want to configure all the PHY, you need to set the correct PhyAddress before using HAL_ETH_(Read|Write)Register()

Here an example of code for setting all the PHY to 100Mb/s full-duplex :

  for(unsigned int i=1; i<=5; i++) // for all ports
  {
	  // Needed, as this the base for PHY access in HAL_ETH_Read/Write
	  heth.Init.PhyAddress = (uint16_t)i;
 
          // all zeroes, except for 13 (100Mb/s) and 8 (full duplex)
	  HAL_ETH_WritePHYRegister(&heth, 0x0100, 0x2100);
}

With this setup, perhaps you can get the LINKED_STATUS and AUTONEGO_COMPLETE for the PHY you need.

Hope this helps !

View solution in original post

8 REPLIES 8
OFAUR.1763
Associate II

Auto-answer, resolved !

MAC-to-MAC is possible without PHY on a STM32F7.

You need to customize the HAL to bypass the status bits that can block the startup.

Usually it's code like this one :

    do
    {
      HAL_ETH_ReadPHYRegister(heth, PHY_BSR, &phyreg);
      phyreg |= PHY_LINKED_STATUS; // I ADDED THIS LINE TO BY PASS THE CHECK
      
      /* SOME CODE */
    } while (((phyreg & PHY_LINKED_STATUS) != PHY_LINKED_STATUS));

As you can, I forced the bit to be set.

You need to do this for the PHY_LINKED_STATUS, and for the PHY_AUTONEGO_COMPLETE.

Depending on your setup, you might need to "disable" HAL_ETH_(Read|Write)PHYRegister().

Hope this will help someone!

Thanks for sharing! I have almost exactly the same problem. Using an KSZ9893 and F767ZI. It is really a relief to see that you managed to connect without any extra phys. I tried to bypass the autonegotiation but my CPU doesn't write a single bit on the ETH_TXDx anyways. The ETH_RXDx is showing on the oscilloscope and I have a 50MHz clock from the switch. Did you do any other things to get it started? Thanks!

Thank you my friend!

Used KSZ8463RL and STM32F427VIT7, communication appeared, ping successful!

No, I only modified the 2 parts for the LINKED_STATUS and the AUTONEGO_COMPLETE.

There is also this : "you might need to "disable" HAL_ETH_(Read|Write)PHYRegister()."

Hi, thank you for sharing your experince!

I have the same problem. I am using KSZ8794 and STM32F7 for direct MAC connection through RMII. 3 ports of the switch can communicate with each other. Port 4 (MAC) is connected to STM32. However I cannot reach to STM32 from any of the other 3 ports.

I bypassed HAL-related PHY initialization but there is no communication. Could you please share your circuit configuration? For example, how did you connect to MAC's? SWITCH_RX -> STM_RX or SWITCH_RX -> STM_TX?

I am also using SPI configuration channel. Did you use SPI or MDIO interface for configuration?

I just checked, we are "SWITCH_RX -> STM_RX".

We struggle a bit to get it to work properly, and in fact the HAL driver is not really suitable for our case.

Don't get me wrong, the HAL_ETH is perfectly fine for most cases, but it needs some tweaking to correctly use the KSZ9896C, and for accessing the configuration of all ports.

Perhaps STM should provide an updated HAL, or microchip or the community might maintain a modified HAL_ETH (if someone starts it, please get in touch!).

Here, we used the HAL to perform the initialization to be sure all is done the right way for the STM32.

We use the MDIO interface.

BUT beware that the HAL_ETH_(Read|Write)Register() uses the provided heth.Init.PhyAddress as the target for your command.

What worked so far:

  • initializing the KSZ9896C with the HAL, while disabling HAL_ETH_(Read|Write)PHYRegister() (see my first answer), or setting heth.Init.PhyAddress to an unused PHY port (so that the HAL doesn't write on something else)
  • then, after initialization, modify temporarily heth.Init.PhyAddress to other ports to configure them using HAL_ETH_(Read|Write)PHYRegister(), and then switch back the original unused PhyAddress

I need to update my first answer in the light of the my current investigation, but time is lacking for now.

OFAUR.1763
Associate II

I've a better answer !

In the code generated by the cube, there is a

ETH_HandleTypeDef heth;

In the code, you need to set the adress of the PHY :

heth.Init.PhyAddress = 0; // or 1, or...

There is a default values for DP83848, for example, but you need to use the one corresponding to your PHY.

LAZY TIP: if you're lazy, try 0 and 1, there are usually the good guess 😂

BUT there is more for the KSZ9896C !

You don't have one PHY but... 5 !

According to the doc, with PhyAddress=0, you configure general settings.

If you want to configure all the PHY, you need to set the correct PhyAddress before using HAL_ETH_(Read|Write)Register()

Here an example of code for setting all the PHY to 100Mb/s full-duplex :

  for(unsigned int i=1; i<=5; i++) // for all ports
  {
	  // Needed, as this the base for PHY access in HAL_ETH_Read/Write
	  heth.Init.PhyAddress = (uint16_t)i;
 
          // all zeroes, except for 13 (100Mb/s) and 8 (full duplex)
	  HAL_ETH_WritePHYRegister(&heth, 0x0100, 0x2100);
}

With this setup, perhaps you can get the LINKED_STATUS and AUTONEGO_COMPLETE for the PHY you need.

Hope this helps !