---
title: "W5500 UDP RX Socket Gives Weird Numbers"
url: "https://maker.wiznet.io/forum/15251"
markdown_url: "https://maker.wiznet.io/forum/15251/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "sugarcane41"
created: "2024-07-31T20:17:56+09:00"
last_activity: "2024-08-02T16:35:35+09:00"
language: "en"
views: 13
replies: 8
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# W5500 UDP RX Socket Gives Weird Numbers

## Question

Asked by sugarcane41 on 2024-07-31 in Ethernet Chips.

Hi everyone. I am trying to use STC89 connecting to W5500 and make a udp ethernet. I have encountered some problems now. There are only 2 devices in this local network: w5500 and my laptop (I write code on PC and connect W5500 to laptop). I did not use any existing library (except for 8051.h) since I prefer to know everything from scratch.

Firstly I set up SPI communication and set IP, MAC, Gateway and Subnet to W5500. Then I test it by ping command from laptop and it works well.

Then I successfully initialized an UDP socket, based on instructions from: [W5500 UDP Function | WIZnet Document System](https://docs.wiznet.io/Product/iEthernet/W5500/Application/udp#multicast)
I used a while loop to initialize the socket. The loop ends while value from Sn_CR is OPEN.
Outside the function, I checked my initialization by reading Sn_SR, port number from Sn_PORT0 and Sn_PORT1, and Sn_IR. Sn_SR is in SOCK_UDP and port number had been written into corresponding registers.

Then I wanted to start with the receiving UDP process. However, I found that values from Sn_RX_RSR are weird, which is something more than 10,000. Then I checked value from Sn_RX_RD and Sn_RX_WR, since Sn_RX_RSR should be the difference between them. But both of these registers give a number larger than 10,000 and their difference do not equal to Sn_RX_RSR.

Also I found that these weird number can be changed if I write them to 0. So I did that and try to step into a while loop to check if there is incoming packets. I follow the instructions from the website I post above. I tried to check the values from both Sn_RX_RSR and Sn_IR. They both give some responses to the incoming packets, but the value of Sn_RX_RSR is still wrong. It is still something over 10,000, which makes the receiveUDP function a mess.

There is another weird thing. Once I try to unplug some jumper wires on W5500 and run the code, the code stops at the while loop for socket initialization. After I plug them in, the initialization proceeds and finishes. Then I try to send packets to W5500 from laptop (using packet sender), and I found that it was delivered to my chip and there is an empty packet send back to the laptop. But this is the only time I succeeded. I cannot even make it happens again ![:frowning:](https://emoji.discourse-cdn.com/twitter/frowning.png?v=12)
I will really appreciate if anyone would like to help me with that. I use sdcc to compile the code and the frame is 8051. Also I add some UART function inside my code to help printing sth.
[W5500_UDPSocket.zip](https://maker.wiznet.io/forum/legacyFile.asp?path=iNdpVslsFSvl6sxYpaM35CidWpN.zip) (163.5 KB)

## Replies

### Reply 1 by Eugeny, 2024-08-01

sugarcane41:

> But both of these registers give a number larger than 10,000 and their difference do not equal to Sn_RX_RSR.

They may give any numbers but RSR must tell you how much data socket has received. What is their difference and value of RSR? May happen you have SPI access issue?

sugarcane41:

> but the value of Sn_RX_RSR is still wrong

If you read this value and it is larger than buffer, then your register value read is defective.
Refer to datasheet on how to read the 16-bit register properly.

sugarcane41:

> Also I found that these weird number can be changed if I write them to 0.

Some registers are not allowed to be written to. You **must** obey the algorithm.

sugarcane41:

> Once I try to unplug some jumper wires on W5500 and run the code, the code stops

Some are which? What W5500 board? Maybe these jumpers connect W5500 to power or to clock?

### Reply 2 by sugarcane41, 2024-08-01 (in reply to reply 1)

For now, I send packets from laptop to w5500.
Sn_RX_RSR has value of 39168.
Sn_RX_WR has value of 25977.
Sn_RX_RD has value of 872.
I read in a manner of:

> UART_SendLong((readRXBuffer(1, Sn_RX_RD0) &lt;&lt; 8) | readRXBuffer(1, Sn_RX_RD1));

In case this number might overflow, I took it as a unsigned long.
I also use the same manner to check my port number. It gives me 0 before initialization, and 5000 after that. Similarly, I read Sn_SR, which was 0 before initialization and 34 (decimal for SOCK_UDP) after that.

I also try to see if using RST would reset value for rx buffer, but it doesn’t work unless I manually write them to 0 in my code.

### Reply 3 by sugarcane41, 2024-08-01

Also I notice that when I send packets to w5500, I need to click send multiple times to send one with success.
Right now the way for checking incoming packet is:

> while (1){
> // Sn_RX_RSR0 stores the first 2 bytes and RSR1 store the next 2
> // e.g:0x0800 has 0x08 in RSR0, 0x00 in RSR1
> isReceive = (readRXBuffer(1, Sn_RX_RSR0) &lt;&lt; 8) | (readRXBuffer(1, Sn_RX_RSR1) );
> if (isReceive == 0) { continue; }
> UART_SendString(“Received a number from Sn_RX_RSR: “);
> // UART_SendLong(isReceive);
> UART_SendNumber(isReceive);
> UART_SendString(”\n------------------\n”);
> if (readSocketRegister(1, Sn_IR) != 0) {
> UART_SendString(“Received Something!”);
> printSn_IR();
> len = receiveUDP(1, buffer);
> sendUDP(1, len, buffer);
> }
> }

I tried with both method mentioned in wiznet website, which are checking Sn_IR and Sn_RX_RSR. However both of them would not response to the very first sending packets. After I tried several times to send, Sn_RX_RSR would change to a large 5-digit number and start receiving weird message. Should I use other methods rather than the while loop to check the incoming packets? Will using interrupt function be a better choice?

### Reply 4 by Eugeny, 2024-08-01

sugarcane41:

> Sn_RX_RSR has value of 39168.
> Sn_RX_WR has value of 25977.
> Sn_RX_RD has value of 872.

These values are wrong.

sugarcane41:

> UART_SendLong((readRXBuffer(1, Sn_RX_RD0) &lt;&lt; 8) | readRXBuffer(1, Sn_RX_RD1));

What are you reading here? Function `readRXBuffer()`, according to its name, is designed to read RX buffer, and not W5500 register area? And then where did you get this type of code? Do you have link? Are you sure that compiler will optimize to read RD0 first, and RD1 second, and not otherwise?

### Reply 5 by sugarcane41, 2024-08-01

> UART_SendLong((readRXBuffer(1, Sn_RX_RD0) &lt;&lt; 8) | readRXBuffer(1, Sn_RX_RD1));

This function read the RX Buffer of socket 0. From my understanding, Sn_RX_RD is the read pointer in RX buffer of Socket 0. I use an array to store bsb values, and the first parameter 1 mea ns choosing socket 0.
I also use this function to read the common registger area and it works. It reads the port number of 0 before initialization, and 5000 after that.

I write these code by myself, here is the detailed function:

> unsigned int readRXBuffer(unsigned int socket, unsigned int addr) {
> return read5500(bsbRX[socket-1], addr);
> }

> __xdata unsigned int bsbRX[8] = {0b00000011, 0b00000111, 0b00001011, 0b00001111,
> 0b00010011, 0b00010111, 0b00011011, 0b00011111};

> unsigned int read5500(unsigned int bsb, unsigned int addr){
> // SCSn should remain low till SPI Frame Transmit done
> SCS = 0;
> // Address Phase: 16 bits Offest Address
> SPIWrite((addr >>8) & 0xff); // bit 15-8
> SPIWrite(addr & 0xff); // bit 7-0
> // Control Phase: 5 bit for BSB, 1 bit for RW, 2 bits for OM
> SPIWrite(bsb &lt;&lt; 3); // bit 7-0
> // Data Phase:
> unsigned int data = SPIRead();
> SCS = 1;
> return data;
> }

In read5500 function, I take bsb&lt;&lt;3 for data phase since I am using VDM, and RW bit for writing is 0.

I really appreciate your help Mr.Eugeny. I searched my problems in this forum for a while and you always help everyone. Thanks again.

### Reply 6 by Eugeny, 2024-08-01

sugarcane41:

> 0b00000011

You access RX buffer, not the socket 0 register set. There’s no RSR/RD/WR registers in that location. There’s RX RAM in there. This is a reason why you get nonsense.

[![image](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/3/3b9dc3811a9f77c8028a2593348265367a8c5c8a.png) image724×246 18.4 KB](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/3/3b9dc3811a9f77c8028a2593348265367a8c5c8a.png)

### Reply 7 by sugarcane41, 2024-08-01

I have a question here. I am trying to read Sn_RX_RSR/Sn_RX_WR/Sn_RX_RD. Should we access to the socket directly, instead of selecting the rx buffer of this socket?

### Reply 8 by Eugeny, 2024-08-01

Read the W5100 datasheet, you will find some more information about chip architecture there.
RX buffer receives data. TX buffer is to send data. Register space contains socket registers. Common register space contains common registers.

---

Source: https://maker.wiznet.io/forum/15251
