w5500-evb-pico using lwip ‘C’ library hangs on wizchip_initialise() when Ethernet cable is unplugged from board.

This occurs ONLY when the Ethernet cable is unplugged which means the link LED is Off. If the board is plugged into a switch but there are no other connections on the switch it does not hang, in this case the link LED is On and the program continues normally.
Plugging in the ethernet cable in the hung state (after many minutes) to the board when hung releases the hung state and the program continues to initialize.
Debugging I can see there is a loop which results from a call wizchip_read(), it gets here from:

Debugging from wizchip_initialize(); I can see the loop here at line 210 in w5x00_spi.c
/* Check PHY link status */
do
{
if (ctlwizchip(CW_GET_PHYLINK, (void *)&temp) == -1)
{
printf(" Unknown PHY link status\n");
return;
}
} while (temp == PHY_LINK_OFF);

Clearly its waiting for the Link to be established, I guess to by pass the network initaliztion I could call WIZCHIP_READ(uint32_t AddrSel) directly, and proceed without any network, but is there any other method to this problem? Thanks.

The call stack is as follows:
This calls int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) with cwtype as CW_GET_PHYLINK
This calls int8_t wizphy_getphylink() which returns ‘0’
This calls: int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
which at line 355 calls
case CW_GET_PHYLINK:
tmp = wizphy_getphylink() which returns ‘0’
This calls: if(getPHYCFGR() & PHYCFGR_LNK_ON)
which calls WIZCHIP_READ() with the retern value as 186

I asked for link to the sources in previous thread you commented in. Please provide link to the sources.
Looking to the ioLibrary_Driver I see case CW_GET_PHYLINK here then wizphy_getphylink() here and then getPHYCFGR() here and I see no while loops. Your code is literally waits for link up, and this is actually what you have found. Where did you find this code you used?

Hi Eugeny, All the code shown is in the WIZnet lwIP library, in the example loop.c code it calls wiznet_initialize() at line 95 (here: RP2040-HAT-LWIP-C/w5x00_loopback.c at main · Wiznet/RP2040-HAT-LWIP-C · GitHub) (sorry don’t know how to make a link out of this URL)
In wiznet_initialize() there is a ( do{ … } while (temp == PHY_LINK_OFF)) loop at line 211, it the loop there is a call to ctlwizchip(CW_GET_PHYLINK, (void *)&temp) == -1) at line 213, at line 219 (temp == PHY_LINK_OFF) is not True, so it loops here as the Ethernet cable is unplugged (or the switch is powered off) which continues until the cable is plugged in. see: RP2040-HAT-LWIP-C/w5x00_spi.c at main · Wiznet/RP2040-HAT-LWIP-C · GitHub

My question is simply, is there a simple way round to stop this blocking, if not I’ll implement a timer to check the link status before calling wiznet_initialize()
Thanks

The header file says:

/*! \brief Initialize WIZchip
 *  \ingroup w5x00_spi
 *
 *  Set callback function to read/write byte using SPI.
 *  Set callback function for WIZchip select/deselect.
 *  Set memory size of W5x00 chip and monitor PHY link status.
 *
 *  \param none
 */
void wizchip_initialize(void);

Repository does not explain why this takes place. It says this is collection of the examples. So the code/driver in this repository by default may not be universal and is provided for example. Log issue to the code on the github and ask for clarification why this code takes place.

Thanks, I have not been able to find where to report/ask this question on github, do you have a URL for it.
Many thanks

Issues link of the project.
Meanwhile I believe you can just remove the code in this loop unless there’s other code assuming link to be up.

Thanks again, I’ve removed the loop and returned a value to determine the LINK state, does not seem to cause any problems.

1 Like