cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring LAN8742 possible bug issues using CubeMx tool for stm32f207

genisuvi
Associate III

I'm testing and debugging a server application running on a custom board based on LAN8742 and stm32f207zg devices. Server has an UDP version and a TCP one. 

Firmware is built using LwIP stack (2.0.3 version), Raw api, non RTOS and HAL drivers (1.9.4 version.). 

As you know CubeMx generate a project folder structure and generates an ethernetif.c file used for "linking" MAC hardware to LwIP stack services. It also ad lwip settings, frame ethernet settings, PHY mask registers and PHY registers addresses definitions, etc..

Clients are python implemented running on windows 11.

Sometimes when server is running link is detected as down. So we were debugging and checking MAC registers where PHY is putting their register values using the mdio interface (for status and control communications). 

Observations:

1.- Autonegotiation result and MAC configuration:

When link up is detected and autonegotiation occurres it seems that PHY is detecting that mode is half-duplex, despite ethernet_init is forcing full-duplex mode. But register has on this bit the value of a half-duplex autonegotiation result. So, here we thought that -for some reason- LAN was only able to talk with the remote host by this mode. Despite this, system communications seems very quick. So we want to be sure and we asked Windows 11 for speed and mode ethernet cards connections. This was the answer:

image.png

  • Does this mean that LAN device is wrongly detecting "half-duplex" and LAN is configuring MAC driver for working in half duplex because of LAN register wrong value but ethernet communication between 2 hosts are actually full-duplex? 

2.- Linkdown detection and loopback mode

When TCP server starts the MX_LWIP_Process() detects link_down event after some time working. Net connection is lost. After this event we are unable to revert this situation. We even tried doing initializing the MAC, where a reset command to LAN device is sent before re-configuring the communications. But it stills unable to receive anymore data. Reading dma descriptors status, MACMIIAR and MACMIIDR values seems that MAC is ok. It doesn't show any error bit. It seems that LAN device is not putting bytes on the bus (I can't confirm this because I have not done osciloscope measures). Once here, we read the above registers values after the first link up and after the link down detection. PHY register accessed by the MAC was BCR register and I can there see that its 14th bit is set. When it is set datasheet says that loop-back mode (for testing purposes) is enabled instead of normal mode. 

Usually peripheral loopback mode is a connection way in which  data sent by TX lines is being received by RX line of the same port. Usefull for testing and checking RX and TX port lines, appropriate configuration parameters, etc. 

  • So I don't know how the communications between server and client (host PC and microcontroller-based PCB could be working correctly (with loopback mode) before to lose the link connection. 

Are LAN device updating badly its owns registers? is it the HAL accesses to this register using wrong ways for reading the actual value? How can the observations be possible? Please let me know. 

I'm very impressed by the fact that ST and Microchip would be able to offering market product lines with this kind of error taxes (high probably of behavior errors). 

 

Thanks in advance.

2 ACCEPTED SOLUTIONS

Accepted Solutions
LCE
Principal

About the half-duplex problem:

If you are using ETH HAL, maybe there is still the bug that HAL ethernet init is reading the wrong register from the LAN8742 to evaluate the negotiated settings. That was the case for me with an F7.
And if one side is setup wrong (PHY and host are working full duplex, but STM's MAC thinks it's half-duplex) strange things start to happen...

Here's my old comment:
/* PHY should be set up now, just check status of auto negotiation */
/* CORRECT register: PHY_REG_SSR = 31d - wrong in (old) HAL driver */

View solution in original post

@LCE yes it does, but I had to add more corrections. This register was wrong mapped, but duplex and speed bits mapping are wrong too. MACCR register now is "showing" full duplex. I did it and it was finally solved:

 

 

/* Section 4: Extended PHY Registers */

#define PHY_SR                          ((uint16_t)0x1F)    /*!< PHY status register Offset */ 

#define PHY_SPEED_STATUS                ((uint16_t)0x0002)  /*!< PHY Speed mask */                          
#define PHY_DUPLEX_STATUS               ((uint16_t)0x0010)  /*!< PHY Duplex mask*/

#define PHY_ISFR                        ((uint16_t)0x001D)    /*!< PHY Interrupt Source Flag register Offset   */
#define PHY_ISFR_INT4                   ((uint16_t)0x000B)  /*!< PHY Link down inturrupt       */

 

I'm now trying to fix the loopback mode bit enabling found on BCR register read. I don't know who is writing there, because soft reset is clearing it, but some statement is writing '1'.

 

Thanks for your attention and suggestions! I appreciate them 🙂

 

View solution in original post

5 REPLIES 5
LCE
Principal

About the half-duplex problem:

If you are using ETH HAL, maybe there is still the bug that HAL ethernet init is reading the wrong register from the LAN8742 to evaluate the negotiated settings. That was the case for me with an F7.
And if one side is setup wrong (PHY and host are working full duplex, but STM's MAC thinks it's half-duplex) strange things start to happen...

Here's my old comment:
/* PHY should be set up now, just check status of auto negotiation */
/* CORRECT register: PHY_REG_SSR = 31d - wrong in (old) HAL driver */

genisuvi
Associate III

 Thanks @LCE , I'm worried about this situation. MAC is completely wrong and it is thinking it's in half duplex when not. Even DMA ethernet descriptor status "duplex-mode field" says that it is half-duplex. ST is a great company and has devices used in a lot of electronics industry products. It's a big big fail! big and basic issue: to know which speed and duplex mode the link has!

You are right, the PHY_REG_SR is 10 and should be 1F on my config.h HAL file. 

I have noticed another thing during MAC initialization, concretely when mcu talks with phy functions implementation:

HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue) implements the PHY register address value writing to the propper MAC register (MACMIIAR) and it also implements the data value to be written in the specified phy register (found in MACMIIAR corresponding field) by writing it to the MACMIIDR MAC register. 

 

 

/**
  * @brief  Writes to a PHY register.
  * @param  heth pointer to a ETH_HandleTypeDef structure that contains
  *         the configuration information for ETHERNET module
  * @param  PHYReg PHY register address, is the index of one of the 32 PHY register.
  *          This parameter can be one of the following values:
  *             PHY_BCR: Transceiver Control Register.
  *             More PHY register could be written depending on the used PHY
  * @param  RegValue the value to write
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
{
  uint32_t tmpreg1 = 0U;
  uint32_t tickstart = 0U;
  ...
  /* Give the value to the MII data register */
  heth->Instance->MACMIIDR = (uint16_t)RegValue;

  /* Write the result value into the MII Address register */
  heth->Instance->MACMIIAR = tmpreg1;
  ...
}

 

 

looking at instance:

 

 

  heth->Instance->MACMIIDR = (uint16_t)RegValue;

 

 

RevValue argument is a mask value with one bit set and the other ones are clear bits ('0') defined on stm32f2xx_hal_conf.h file. Doing that way, every time HAL writes a RevValue is writing a mask with only one bit = '1' for enabling or desabling a control option. This means that previous value will be totally erased because every time a mask is applied and written directly to the specified PHY register, so the other bits will be cleared.

I don't know if ST developers is having this in mind when they are writing PHY for settings, and erased bits doesn't matter after all. I have not followed the total setting writings sequence so I can not say it is. But knowing the fails they have done with mapping registers and other confirmed bugs I'm afraid that this suspects could be happening. 

Regarding second problem, from soft reset ececution (it clears and resets most of registers values) someone is writing '1' on the loop-back mode bit, since its default value after reset is '0'. But after initialization is modified by '1'.

Currently I don't find who is doing this.  

LCE
Principal

So, have you solved the half-duplex problem?
As soon as the STM's MAC gets the right answer from PHY and makes the right settings (full-duplex), it will probably work well.
I would not change the register's address, but rather add a new register for that address.
But beware: if you are using CubeMX and change stuff your own code in the HAL libs gets overwritten (I think).

About the PHY writing, what's your problem with that?
"RegValue" is the value which shall be written to the PHY register, and although it is declared and given to the function as a 32bit var, the register it is used for is 16 bit only, that's why it's cast.

The STM32 is actually some great hardware, but has have found out and will find, some HAL stuff is ... not that good.
That's why I didn't use the ETH HAL stuff. Too much overhead, and in the first version I started with was blocking.

@LCE yes it does, but I had to add more corrections. This register was wrong mapped, but duplex and speed bits mapping are wrong too. MACCR register now is "showing" full duplex. I did it and it was finally solved:

 

 

/* Section 4: Extended PHY Registers */

#define PHY_SR                          ((uint16_t)0x1F)    /*!< PHY status register Offset */ 

#define PHY_SPEED_STATUS                ((uint16_t)0x0002)  /*!< PHY Speed mask */                          
#define PHY_DUPLEX_STATUS               ((uint16_t)0x0010)  /*!< PHY Duplex mask*/

#define PHY_ISFR                        ((uint16_t)0x001D)    /*!< PHY Interrupt Source Flag register Offset   */
#define PHY_ISFR_INT4                   ((uint16_t)0x000B)  /*!< PHY Link down inturrupt       */

 

I'm now trying to fix the loopback mode bit enabling found on BCR register read. I don't know who is writing there, because soft reset is clearing it, but some statement is writing '1'.

 

Thanks for your attention and suggestions! I appreciate them 🙂

 

RhSilicon
Lead

Hi, I've already tried using LAN8720 with STM32F407VGT6, I managed to get some examples working, but it's been a while and I don't remember the details. It turns out that the Arduino platform also has an option to operate with Ethernet, perhaps it could be a way to obtain a parallel code for comparison, even if it is based on the HAL library as well.

I found this example repository:

https://github.com/nopnop2002/Arduino-STM32-Ethernet-LAN8720/issues/7

I saw a post about the USB hardware, where apparently the settings were not being set initially, if I remember correctly they put the memset function to solve it, there must be several gaps still in many of these HAL libraries

/* Initialize hid handler */
(void)USBH_memset(HID_Handle, 0, sizeof(HID_HandleTypeDef));