W5500 stuck on socket close

Hello, I have a W5500 chip which is stuck after writing Sn_CR_CLOSE to CR, reading back CR always returns 0x10 (=Sn_CR_CLOSE), it never returns 0 as the operation is never completed.
This happens on all the 8 sockets. The configuration of the W5500 is the default after a reset. The hardware seems all ok and this same board was working a week ago.
The test code is like this:

spi_init();
set_w5500_spi_functions();

uint8_t r = getVERSIONR();
assert(r == 0x04); // ok

for (uint8_t sn = 0; sn <=7; sn++)
{
    r = getSn_CR(sn);
    assert(r == 0); // ok
}
for (uint8_t sn = 0; sn <=7; sn++)
{
    setSn_CR(sn, Sn_CR_CLOSE);
    for (int32_t i = 0; i <= 1000; i++)
    {
        r = getSn_CR(sn);
        if (r == 0)
            break; // it never breaks
        r = getSn_SR(sn); // always returns 0 (=SOCK_CLOSED)
    }
}

I have 2 other boards which do not have this problem, after writing CR=0x10 they return CR=0 at the first reading.
What happened on this chip?

Never tried to close socket which is already in closed state. Second suspicion is you writing and reading register data from wrong location (e.g. problems in SPI communication).

Hello Eugeny, I don’t think so, because 2 others boards with the same hardware and test code work without problems: after writing 0x10 to CR, the first reading of CR returns 0, which is correct.

Do other registers read properly? Make a reg dump to see if all the values are correct default values.

Yes, I’ve checked most of the global and sockets registers (excluding ip addresses, ports and tx/rx pointers). They are at the default value: most of them are zero, but I can correctly read the ones which are not zero (RCR=08h, PHYCFGR=B8h, Sn_TTL=80h, Sn_RX/TXBUF_SIZE=2 …), the only difference is Sn_IMR which is 1Fh instead of FFh, but it is ok the missing bits are reserved.

Does link go up when you insert network cable connected at the other end?

The link status is indifferent for this problem: on the working boards it works with or without link, on the stuck board it never works.
But on the stuck board the link is never up with the cable connected, also the link led is always off. Hardware-wise everything else seems ok.

If I would not think there’s a difference, I would not ask.

Not ok. Even with unconfigured W5500 (e.g. just after power up) link must be up when live cable is connected. You must check if circuitry is properly powered at the PHY side, and if there’s any connection/PCB issue.

As I tried to explain in that line, with “indifferent” I meant that this problem doesn’t change with the link on or off, and since without link I have a chip working and one not, I can probably assume that the link detention not working is not a cause but another result of the faulty chip.
To recap, a week ago I had 3 boards working without problems, now one board is not working. Without link I can compare the boards pin to pin, the only differences are: EXRES1 pin is 0V instead of the correct 1.2V and on the TX couple I cannot see the “idle frames”, on the working one I can see them repeated every 20ms.
I’m quite sure that the problem is the W5500 chip.
I’m trying to understand what happened to this faulty chip, its situation is: CR doesn’t reset itself for any command, consumption is 20mA less than normal, but the SPI communication works correctly (and the registers read/written are correct).
It seems like the W5500’s SPI peripheral still works and can read/write the chip’s RAM, but the microprocessor in charge of everything else doesn’t work anymore.

Does anyone know in what case CR cannot reset itself? Fried microprocessor? Bad cloned chip?

Does it matter? If your goal is to solve the problem with non-working module, replace chip, but only after you ensure problem is not external to the chip.

It is not proven yet. EXTRES1 relates to analog circuit, 0V level may mean you have problem with 3V3A. Did you check it as I asked in my previous reply?

Given the price of the chip I do not think there will be clones or unauthorized copies.

Eugeny, I don’t know what you trying to do, but nevertheless thanks for trying to help, now it’s ok.

Is there anyone from @wizteam who knows in what case CR cannot reset itself? And possibly the cause of this situation, so I can try to avoid it.

Hi @gama

Thank you for the test with W5500.
It is so interesting ethernet function test.

Actually, In Sn_CR register, 0x10 means SOCK_CLOSED.
image

This is defined in ioLibrary, as
#define Sn_CR_CLOSE 0x10

It is so good way to use W5500 with own made driver. But if there is some problem, it could be helpful to refer the official ioLibrary:

Thank you :slight_smile:

Hello @lawrence,

thank you for your reply. Yes, I’m using the same file ‘w5500.h’.

This is my problem: I write the CR registry with Sn_CR_CLOSE = 0x10:

setSn_CR(sn, Sn_CR_CLOSE);

but when I read back the CR registry:

uint8_t r = getSn_CR(sn);

the value read is always 0x10 and never 0x00 (CR should reset itself to 0x00) no matter how much I wait.

I’m really sure that I have a faulty/damaged W5500, also: it consumes 20mA less than a working W5500, on the TX couple lines I cannot see the “presence/idle frames”, the EXRES1 pin is at 0V instead of the correct 1.2V (but VBG is at 1.2V). Other signals/powers/clocks of the W5500 chip are all correct.

In what situation the CR register cannot reset itself to 0x00 once written?
And possibly, do you know what situation could have damaged the chip?
Thank you.

@gama

Sorry for the late,

Could you share all register’s reset value in 2 cases?

one is after spi init and second is after socket open.

We can figure out damaged chip or not with the log.

I will also try to check some cases.

Thank you,

@gama

Could we know the init value of Sn_CR register before write any command?

If it is not 0x00 in init, as you said we consider any damaged case.

Lawrence, unfortunately I was forced to replace that W5500 chip with a new one, with the new one the board worked correclty. Now I’m trying to manually mount the problematic W5500 on a old board to give you a full register dump, please be patient.

However, I had already written down a partial dump of the registers of that W5500, it was done just after the reset and without the ethernet link:

Common registers:
getVERSIONR = 0x04
getPHYCFGR = 0xB8
getMR = 0
getIR = 0
getIMR = 0
getSIR = 0
getSIMR = 0
getRCR = 0x08
getPMAGIC = 0

Socket register (n = 0…7):
getSn_MR = 0
getSn_CR = 0
getSn_IR = 0
getSn_SR = 0
getSn_TOS = 0
getSn_TTL = 0x80
getSn_RXBUF_SIZE = 0x02
getSn_TXBUF_SIZE = 0x02
getSn_IMR = 0x1F
getSn_KPALVTR = 0

So to reply your question, getSn_CR was zero before writing any command.

After this, if I write CR:

 setSn_CR(sn, Sn_CR_CLOSE)

I get:

getSn_CR(sn) = 0x10
getSn_SR(sn) = 0

this is true for any socket (sn = 0…7).

Thank you for your help.

@lawrence, I mounted the W5500 on an a different board, this board was working with a different W5500.
Now the board doesn’t work anymore, the W5500 has the same behavior, it cannot reset CR.

This makes me think this W5500 is faulty. For at least 2 days before the problem, the chip was working, it was connected to the ethernet cable and it was powered at 3.3V. The 3.3V rail is from a step-down converter which is a bit noisy, it has a ripple of 200-300mV, but on the same 3.3V rail there is also the microprocessor, and after the problem the microprocessor still worked without problems.

Attached the full dump before and after writing CR to 0x10.

Seems I cannot upload files, here is the dump:

Before writing CR:

— Common registers —
getMR: 00
getGAR: 00 00 00 00
getSUBR: 00 00 00 00
getSHAR: 00 00 00 00 00 00
getSIPR: 00 00 00 00
getINTLEVEL: 00 00
getIR: 00
getIMR: 00
getSIR: 00
getSIMR: 00
getRTR: d0 07
getRCR: 08
getPTIMER: 28
getPMAGIC: 00
getPHAR: 00 00 00 00 00 00
getPSID: 00 00
getPMRU: ff ff
getUIPR: 00 00 00 00
getUPORTR: 00 00
getPHYCFGR: b8
getVERSIONR: 04
— Socket 0 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 1 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 2 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 3 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 4 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 5 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 6 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 7 registers —
getSn_MR: 00
getSn_CR: 00
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00

After writing CR:

— Common registers —
getMR: 00
getGAR: 00 00 00 00
getSUBR: 00 00 00 00
getSHAR: 00 00 00 00 00 00
getSIPR: 00 00 00 00
getINTLEVEL: 00 00
getIR: 00
getIMR: 00
getSIR: 00
getSIMR: 00
getRTR: d0 07
getRCR: 08
getPTIMER: 28
getPMAGIC: 00
getPHAR: 00 00 00 00 00 00
getPSID: 00 00
getPMRU: ff ff
getUIPR: 00 00 00 00
getUPORTR: 00 00
getPHYCFGR: b8
getVERSIONR: 04
— Socket 0 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 1 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 2 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 3 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 4 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 5 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 6 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00
— Socket 7 registers —
getSn_MR: 00
getSn_CR: 10
getSn_IR: 00
getSn_SR: 00
getSn_PORT: 00 00
getSn_DHAR: ff ff ff ff ff ff
getSn_DIPR: 00 00 00 00
getSn_DPORT: 00 00
getSn_MSSR: 00 00
getSn_TOS: 00
getSn_TTL: 80
getSn_RXBUF_SIZE: 02
getSn_TXBUF_SIZE: 02
getSn_TX_FSR: 00 00
getSn_TX_RD: 00 00
getSn_TX_WR: 00 00
getSn_RX_RSR: 00 00
getSn_RX_RD: 00 00
getSn_RX_WR: 00 00
getSn_IMR: 1f
getSn_FRAG: 00 40
getSn_KPALVTR: 00

Hi~ @gama
The clocks used to perform register write operations and register erase operations are different.
When w5500 operates register read/write, it uses the SPI clock connected to the master.
the w5500 uses the clock of phy to operate the register clear operation.

Therefore, if the PHY does not operate normally as @Eugeny said, the register clear operation is not performed.

2 Likes

Hello @irina_kim, thanks, finally I’ve an answer.
So the PHY is not working, can I measure something or do something to investigate the cause of this problem? I need to prevent this kind of problem, and of course, I can have inadvertently damaged the chip myself, but I’m trying to understand how. Sorry if I’m too persistent.