---
title: "TCP Server with W5500"
url: "https://maker.wiznet.io/forum/12286"
markdown_url: "https://maker.wiznet.io/forum/12286/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "Shade"
created: "2017-05-14T04:46:23+09:00"
last_activity: "2019-03-24T05:14:54+09:00"
language: "en"
views: 13032
replies: 23
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# TCP Server with W5500

## Question

Asked by Shade on 2017-05-14 in Ethernet Chips.

Hi,

I’m new with W5500.
My project is to develop Ethernet-to-Serial Converter using W5500.
The Evaluation board with the chip, SPI interface and RJ45 connector is in its way and I’m currently getting familiar with the Datasheet of W5500.
My idea is to start with a very simple MCU application, which to initialize the chip as a TCP Server and establish connection with a TCP Client.
Investigating the registers of the chip, I think the following initialization and control sequence will be good enough to start with. I will appreciate if somebody who is experience tells if I’m missing anything:

1. Hardware Reset.

2. Common Register Block (0x00).
   2.1 Write MR = 0x80 (Software Reset).
   2.2 Write GAR (Gateway).
   2.3 Write SUBR (Subnet Mask).
   2.4 Write SHAR (Source Hardware Address).
   2.5 Write SIPR (Source IP Address).
   2.6 Write IMR = 0x01 (Enable Socket 0 Interrupts).

3. Socket 0 Register Block (0x01).
   3.1 Write S0_PORT (Port Number).
   3.2 Write S0_MR = 0x01 (Set TCP Protocol).
   3.3 Write S0_CR = 0x01 (OPEN).
   3.4 Write S0_CR = 0x02 (LISTEN).
   3.5 Wait for an Interrupt when a Connection is Established.
   3.6 Write to Common Block SIR to Clear the Interrupt.
   3.7 Wait for RECV Interrupt (Data Received).
   3.7.1 Read S0_RX_RSR to Get the RX Buffer Data Size.
   3.7.2 Read S0_RX_RD to Get RX Data Start Address.
   3.7.3 Read RX Data from S0_RX_BUF (Block 0x02).
   3.7.4 Write Data Size to S0_RX_RD to Update.
   3.7.5 Write S0_CR = 0x40 (RECV) to Notify W5500.
   3.8 When Data to Send is Available.
   3.8.1 Read S0_TX_WR to Get RX Data Start Address.
   3.8.2 Write TX Data from the Start Address of S0_TX_BUF (Block 0x01).
   3.8.3 Write Data Size to S0_TX_WR to the Increased Value.
   3.8.4 Write S0_CR = 0x20 (SEND) to Transmit the Data.

Thank you,
Ivan

## Replies

### Reply 1 by Eugeny, 2017-05-14

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> chip as a TCP Server and establish connection with a TCP Client

It is the client who establishes connection to the server, not other way around.

In general your flow is correct. If your application is not going to be multitasking, you may not need to use interrupts - just poll socket status register and see its status change to desired one.

### Reply 2 by Shade, 2017-05-14 (in reply to reply 1)

Thank you, Eugeny,

Yes, the server is listening for a client to establish connection.
Since the Status register provides all necessary information, probably my startup application doesn’t need interrupts.

The reason I started looking at W5500 is I have implemented Ethernet-to-Serial Converter for our project by using Microchip PIC18F67J60 MCU with an integrated 10BaseT Ethernet controller. It works well for short messages but provides 200 ms latency between data blocks when downloading data. I wasn’t able to decrease this latency. Probably the reason of it is the speed of 10Mbps.
A 100BaseT MOXA Nport provides 15 ms latency.
I tried an WIZ110SR board and was surprised: it provided 2 ms latency. But this board doesn’t support RFC2217 COM Port Telnet protocol.
Looks like W5500 has advantages for my implementation vs W5100 and I decided to use W5500.
A small Microchip MCU will initialize W5500 and support the Ethernet-to-Serial conversion.
I’ll be working on my firmware to give a try with W5500.

Regards,
Ivan

### Reply 3 by Eugeny, 2017-05-14

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> I tried an WIZ110SR board and was surprised: it provided 2 ms latency.

Yes, they are really quick.

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> Looks like W5500 has advantages for my implementation vs W5100 and I decided to use W5500.

The obvious advantage of W5100 that it has parallel interface, and reading 8-bit data is achievable within 40 ns. The obvious advantage of W5500 that it has more sockets.

### Reply 4 by Shade, 2017-05-14

I preferred W5500 because its footprint is smaller and it is less expensive. However, the parallel interface of W5100 is valuable functionality. When I have a functional W5500 based module, I will compare its speed against WIZ110SR.
How big are the differences in registers set and initialization between W5500 and W5100?

By the way I was wondering about the meaning of the ‘Socket n Keep Alive Time Register’, located at offset 0x2F. The datasheet says W5500 automatically transmits KA packet after the specified time-period in case this register contains value different than the default 0x00. How does this register need to be used?

### Reply 5 by Eugeny, 2017-05-14

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> How does this register need to be used?

Web servers, for example Apache, usually have keep alive settings in their configuration, which controls behavior of the server when there’s no activity through the connection throughout specific time period.

Thus if you need to keep devices connected this feature must be very useful as you do not need to care about manually sending packets to inform server you still need the connection.

If you will be using HTTP please note that keep alive HTTP header is having effect for HTTP version 1.1 and above only.

### Reply 6 by Shade, 2017-05-14

Eugeny,

How is the Socket Status Register of W5500 used to check for events like ‘Data Received’ and 'Data Sent"? This register only contains “SOCK_SYNRECV”, indicating ‘Socket n successfully received the connect request packet (SYN packet) from a peer’ and ‘SOCK_SYNSENT’ for ‘Socket n sent the connect-request packet (SYN packet) to a peer’.

### Reply 7 by Eugeny, 2017-05-14

Use Sn_SR to ensure you get connection (state 0x17), and regularly check this register to still be 0x17. While it is in this state, just read RX_RSR to see the size of the data received. If it is not zero, you have data of indicated size, you can get it from the chip.

There’s one trick - connecting may have already been closed (Sn_SR) is not 0x17 any more, or, let’s say. 0x1C, but W5500 may still have data in its buffer. Thus after devices got disconnected ensure to read RX_RSR once more to ensure there’s no more data pending in its buffer.

### Reply 8 by irina, 2017-05-15

Hi Shade,

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> How is the Socket Status Register of W5500 used to check for events like ‘Data Received’ and 'Data Send"?

The Socket Status Register (Sn_SR) is mainly used to handle the socket by checking the connection status of the socket. For example, these socket states. Socket closed(SOCK_CLOSED, 0x00), Socket listen (SOCK_LISTEN, 0x14), Socket close wait(SOCK_CLOSE_WAIT, 0x1c), Socket connection established(SOCK_ESTABLISHED, 0x17) and Etc.

Thanks [@Eugeny](https://maker.wiznet.io/u/eugeny). your advice is appropriate.

It is recommended to check the Sn_RX_RSR (SOCKET n Received Size Register) periodically when receiving the data in Socket established state.

Completion of the data send is to be checked by the SEND_OK interrupt at the next Send function(TCP, driver level, ‘Next’ means: To prevent delay of SEND_OK check). For more information, see the Socket.c / h file in ioLibrary driver.

![](https://github.githubassets.com/favicons/favicon.svg) [GitHub](https://github.com/Wiznet/ioLibrary_Driver)

![](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/d/db09115139c508e638bbd6b7ccad470b78777415.png)

### [GitHub - Wiznet/ioLibrary_Driver: ioLibrary_Driver can be used for the...](https://github.com/Wiznet/ioLibrary_Driver)

ioLibrary_Driver can be used for the application design of WIZnet TCP/IP chips as W5500, W5300, W5200, W5100 W5100S. - GitHub - Wiznet/ioLibrary_Driver: ioLibrary_Driver can be used for the applica...

Regards,
Eric

### Reply 9 by Shade, 2017-05-15 (in reply to reply 8)

Thank you, Eric,

Is it possible to check for data sent when the interrupts are disabled from ‘Sn_IMR’? Just by polling the ‘Sn_IR’ register? Are the interrupt bits set in this case?
If yes, does the firmware need to clear the set interrupt bit by writing ‘1’ on it?
Does ‘Sn_IMR’ bit of the Common Block IMR (offset 0x18) need to be set in this case?

### Reply 10 by Kei, 2017-05-15

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> Is it possible to check for data sent when the interrupts are disabled from ‘Sn_IMR’? Just by polling the ‘Sn_IR’ register?

If Sn_IMR is disabled (‘0’), the bits of Sn_IR are not set to ‘1’.
Please refer to the [W5500 datasheet](http://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:w5500_ds_v107e_160224.pdf).

If you want to check the received data polling without using Interrupt, please refer to the **Sn_RX_RSR** register.

### Reply 11 by Shade, 2017-05-15 (in reply to reply 10)

Kei,

I understand that the ‘Sn_IMR’ bits must be set in order the ‘Sn_IR’ bits to be set when polling for ‘data sent’.
Two questions:

1. When an interrupt bit is set in ‘Sn_IR’, how this bit gets cleared afterwords? Is it necessary to write ‘1’ to ‘Sn_IR’ to clear the bit?

2. Is it necessary to set the Common Block ‘IMR’ bits to enable the ‘Sn_IR’ interrupt? Or these interrupts are independent?
   These things are not clearly explained in W5500 datasheet.

### Reply 12 by Kei, 2017-05-15

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> When an interrupt bit is set in ‘Sn_IR’, how this bit gets cleared afterwords? Is it necessary to write ‘1’ to ‘Sn_IR’ to clear the bit?

Yes, you must set ‘1’ in the register bit (Sn_IR).
Below is a description from the datasheet.

> In order to clear the Sn_IR bit, the host should write the bit to ‘1’.

for example,

```
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
     setSn_IR(sn, Sn_IR_SENDOK);
}
```

---

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> Is it necessary to set the Common Block ‘IMR’ bits to enable the ‘Sn_IR’ interrupt? Or these interrupts are independent?

For SIMR (offset 0x0018), this is the mask for socket’s interrupt(SIR) itself.
If you disable interrupts for a socket in SIMR, the socket’s an interrupt will be not issued even if the corresponding bit of SIR is ‘1’.

That is, enable bit in SIMR for use a socket’s interrupts, and mask the more detailed interrupts(CON, DISCON, etc… ) in Sn_IMR.

### Reply 13 by Shade, 2017-05-19

Hi, guys,

Just to share some impressions.
Based on the suggestions I got in this forum, I implemented a test application for Ethernet-to-Serial with W5500 and an existing microcontroller board. This is a full feature application, which even supports the RFC2217 Telnet COM Port option.
The network communication using W5500 appeared to be extremely fast! The latency between the data blocks when downloading a file was 1 msec.
As I mentioned before a USB-to-Serial provides latency of 2 msec, the latency with a MOXA Nport Ethernet-toSerial is 15 msec, and my old 10BaseT Ethernet-to-Serial has 200 msec latency.

I had a small issue with W5500 stopping to respond after keeping the RJ45 cable disconnected for some time, but I succeeded to fix this by initializing the ‘Keep Alive Timer register’ (Common Block, offset 0x002F) to a value different than zero.

Soon this design is going to be a part of a bigger project. If I have difficulties with it, will let you know.

Thanks everyone who helped me with advices!
Ivan

### Reply 14 by Kei, 2017-05-19 (in reply to reply 13)

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> The network communication using W5500 appeared to be extremely fast!

Thanks for good news! ![:slight_smile:](https://emoji.discourse-cdn.com/twitter/slight_smile.png?v=12)

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> Soon this design is going to be a part of a bigger project. If I have difficulties with it, will let you know.

Ok, please contact us if you have difficulty.
And when your project is completed or progressed, it would be appreciated if you let us know ![:slight_smile:](https://emoji.discourse-cdn.com/twitter/slight_smile.png?v=12)

I hope your project will succeed.
Thanks!

### Reply 15 by irina, 2017-05-20 (in reply to reply 13)

![](https://avatars.discourse-cdn.com/v4/letter/s/2bfe46/48.png) Shade:

> The network communication using W5500 appeared to be extremely fast! The latency between the data blocks when downloading a file was 1 msec.

Great! ![:+1:](https://emoji.discourse-cdn.com/twitter/+1.png?v=12)

### Reply 16 by Shade, 2017-12-22

Hi, Leza,
Do you have any question for me?
Ivan

### Reply 17 by Shubham Dubey, 2018-01-22

THIS IS CORRECT SEQUENCE FOR TCP/IP

### Reply 18 by Shubham Dubey, 2018-01-22 (in reply to reply 17)

? OR NOT

### Reply 19 by Shade, 2018-01-22

The sequence seems to be correct. Our system with the Ethernet-to-UART module using W5500 as a part of, is in production.

### Reply 20 by NewUser, 2018-01-23 (in reply to reply 1)

3.7.4 Write Data Size to S0_RX_RD to Update.
3.7.5 Write S0_CR = 0x40 (RECV) to Notify W5500.

Hello Eugeny. Based on Shade flow . May I know from "3.7.4 Write Data Size to S0_RX_RD to Update " . Do we write back the value of data size from " 3.7.1 Read S0_RX_RSR to Get the RX Buffer Data Size " to S0_RX_RD to Update ? Update means what for w5500 ?

And why we nee to to "3.7.5 Write S0_CR = 0x40 (RECV) to Notify W5500 " ? Isnt the S0_CR (RECV) interrupted when interrupted cause by established connection ?

Hope u could help to explain ? New to wiznet w5500 also.

### Reply 21 by Shubham Dubey, 2018-03-05 (in reply to reply 19)

hello give sample code for same.thanx

### Reply 22 by Eugeny, 2018-03-05

![](https://avatars.discourse-cdn.com/v4/letter/n/3e96dc/48.png) NewUser:

> Do we write back the value of data size from " 3.7.1 Read S0_RX_RSR to Get the RX Buffer Data Size " to S0_RX_RD to Update ? Update means what for w5500 ?

No. Read [W5100 datasheet](http://www.wiznet.io/product-item/w5100/) chapter 5. You update RX_RD register value with its value you previously read plus number of bytes you read from the buffer. It tells W5500 that this space you shifted pointer through is now free to be filled with further network data.

![](https://avatars.discourse-cdn.com/v4/letter/n/3e96dc/48.png) NewUser:

> And why we nee to to "3.7.5 Write S0_CR = 0x40 (RECV) to Notify W5500 " ? Isnt the S0_CR (RECV) interrupted when interrupted cause by established connection ?

Application must explicitly tell W5500 when it finished operations with its RX buffer, and that W5500 can proceed getting data from the network into freed space.

### Reply 23 by Mxyxixptlick, 2019-03-24

You may find it helpful to look at a LGPL W5500 driver that is known to work and use whatever parts of it you find useful. I just posted my update to the Arduino Ethernet 2.0 library on github.

![](https://github.githubassets.com/favicons/favicon.svg) [GitHub](https://github.com/SapientHetero/Ethernet)

![](https://maker.wiznet.io/forum_uploads/wiznet/original/2X/f/feb34e9e9a4899fe862c7138a8087dc2b3d6e637.png)

### [GitHub - SapientHetero/Ethernet: Ethernet Library for Arduino](https://github.com/SapientHetero/Ethernet)

Ethernet Library for Arduino. Contribute to SapientHetero/Ethernet development by creating an account on GitHub.

---

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