W5500 TCP Server is refusing to connect

Hi,

I have made the socket 0 to listen. But while reading the register Sn_SR , value is toggling sometimes and at client i am getting the error “Connection Refused”.

Here is part of my code:

            socket_write(0x04, 0x13);
            socket_write(0x05, 0x88);
            socket_write(0x00, 0x01);
            socket_write(0x01, 0x01);
            socket_write(0x01, 0x02);

            while(1){
                     Delay_ms(1000);
                     val = socket_read(0x03);
                     UART1_Write(val);
            }

Insufficient information. What your socket_write calls are expected to do? Which values socket_read gives?

Hi dhanunjay,

When implementing a TCP server device based on the W5500 chip, please refer to the loopback_tcps() function of the next github link as a skeleton.

There is a caution. Please do not use delay() function when implementing networking applications. Network application devices (especially for a TCP server) must be able to receive client connection requests at any time. These delay routines in while loop can cause client connection failure and timeout.

My socket_write and socket_read just write and read the register of socket 0.

here is the code:

void socket_write(uint8_t reg_off, uint8_t val){
           CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(reg_off);
            SPI1_Write(0x0E);
            SPI1_Write(val);
            CB_ChipDeselect();
}

uint8_t socket_read(uint8_t reg_off){

        uint8_t val;
           CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(reg_off);
            SPI1_Write(0x08);
            val = SPI1_Read(0);
            CB_ChipDeselect();           
            return val;
}

Here is the packet capture from the wireshark 192.168.0.150 is my w5500 TCP Server ip and other my pc.

Here my total code

#include "Wizchip_Conf.h"
#include "W5500.h"
#include "Socket.h"

#define SOCK_ID_TCP       0
#define SOCK_ID_UDP       1
#define SOCK_WEBSERVER    0
#define PORT_TCP          5000
#define PORT_UDP          10001
#define PORT_WEBSERVER    80

#define DATA_BUF_SIZE     100

#define _W5500_SPI_VDM_OP_          0x00
#define _W5500_SPI_FDM_OP_LEN1_     0x01
#define _W5500_SPI_FDM_OP_LEN2_     0x02
#define _W5500_SPI_FDM_OP_LEN4_     0x03
uint8_t gDATABUF[DATA_BUF_SIZE];

sbit Wizchip_Rst at LATE1_bit;
sbit Wizchip_CS  at LATE0_bit;
sbit Wizchip_Rst_Direction at TRISE1_bit;
sbit Wizchip_CS_Direction  at TRISE0_bit;

int32_t ret;
uint16_t size = 100, sentsize=0, i=10000;

volatile wiz_NetInfo gWIZNETINFO =
{
  {0x00, 0x14, 0xA3, 0x72, 0x17, 0x3f},    // Source Mac Address
  {192, 168,  0, 150 },                      // Source IP Address
  {255, 255, 255, 0},                      // Subnet Mask
  {192, 168,  0, 1},                       // Gateway IP Address
  {8, 8,  8, 8},                      // DNS server IP Address
  NETINFO_STATIC
 };

 volatile wiz_PhyConf phyConf =
{
  PHY_CONFBY_HW,       // PHY_CONFBY_SW
  PHY_MODE_MANUAL,     // PHY_MODE_AUTONEGO
  PHY_SPEED_10,        // PHY_SPEED_100
  PHY_DUPLEX_FULL,     // PHY_DUPLEX_HALF
};

volatile wiz_NetInfo pnetinfo;


void CB_ChipSelect(void)
{
    Wizchip_CS = 0;
}

// brief Call back function for WIZCHIP deselect.
void CB_ChipDeselect(void)
{
    Wizchip_CS = 1;
}

// brief Callback function to read byte usig SPI.
uint8_t CB_SpiRead(void)
{
    return SPI1_Read(0);
}

// brief Callback function to write byte usig SPI.
void CB_SpiWrite(uint8_t wb)
{
    SPI1_Write(wb);
}

uint8_t val;
uint8_t mac[] = {0x00, 0x08, 0xDC, 0xAB, 0xCD, 0xEF};
uint8_t gw[] = {0xC0, 0xA8, 0x00, 0x01};
uint8_t sn[] = {0xFF, 0xFF, 0xFF, 0x00};
uint8_t sip[] = {0xC0, 0xA8, 0x00, 0x96};
uint8_t buffsize[8] = { 2, 2, 2, 2, 2, 2, 2, 2 } ;

void socket_write(uint8_t reg_off, uint8_t val){
           CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(reg_off);
            SPI1_Write(0x0E);
            SPI1_Write(val);
            CB_ChipDeselect();
}

uint8_t socket_read(uint8_t reg_off){

        uint8_t val;
           CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(reg_off);
            SPI1_Write(0x08);
            val = SPI1_Read(0);
            CB_ChipDeselect();
            return val;
}

void sendHeader(uint8_t sn){
    uint8_t dat[128]={0,};
    uint8_t dat_t[128]={0,};
    uint8_t *dat_temp;
    dat_temp = "HTTP/1.1 200 OK\r\n";                       strcat(dat, dat_temp);
    dat_temp = "Content-Type: text/html\r\n";                   strcat(dat, dat_temp);
    dat_temp = "Connection: close\r\n";                     strcat(dat, dat_temp);
    dat_temp = "\r\n\r\n";                              strcat(dat, dat_temp);
    send(sn, (uint8_t *)dat, strlen(dat));
}
uint8_t send_dat[1024]={0,};

uint16_t calcu_len(void){
    uint8_t *dat_temp;

    dat_temp = "<!DOCTYPE html>\r\n";                                              strcat(send_dat, dat_temp);
    dat_temp = "<html>\r\n";                                                  strcat(send_dat, dat_temp);
    dat_temp = "<body>\r\n";                                                      strcat(send_dat, dat_temp);
    dat_temp = "<h1>\r\n";                                                  strcat(send_dat, dat_temp);
    dat_temp = "First Html\r\n";                  strcat(send_dat, dat_temp);
    dat_temp = "W5500 WebServer Test!!\r\n";                                    strcat(send_dat, dat_temp);
    dat_temp = "</h1>\r\n";                              strcat(send_dat, dat_temp);
    dat_temp = "<p>My first paragraph.</p>\r\n";                                                  strcat(send_dat, dat_temp);
    dat_temp = "</body>\r\n";                                                      strcat(send_dat, dat_temp);
    dat_temp = "</html>\r\n";              strcat(send_dat, dat_temp);
    return strlen(send_dat);
}

void sendData(uint8_t sn){
    uint16_t i;
    send(sn, (uint8_t *)send_dat, strlen(send_dat));
    for(i=0;i<1024;i++){
        send_dat[i]=0;
    }
}

char proc_http(uint8_t sn, char * buf)
{
    if((buf[0]=='G')&&(buf[1]=='E')&&(buf[2]=='T')&&(buf[3]==' ')){ // GET_Request

            sendHeader(sn);
            sendData(sn);
    }

    return 1;
}

int32_t WebServer(uint8_t sn, uint8_t* buf, uint16_t port)
{


   switch(getSn_SR(sn))
   {
      case SOCK_ESTABLISHED :
         UART1_Write_Text("goole");
         if(getSn_IR(sn) & Sn_IR_CON)
         {
            setSn_IR(sn,Sn_IR_CON);
         }
         while(i){
             i--;
         }
         if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
         {
            if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
            ret = recv(sn, buf, size);

            if(ret <= 0) {

            return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
            }
            sentsize = 0;
            UART1_Write(buf[0]);
            UART1_Write(buf[1]);
            UART1_Write(buf[2]);
            UART1_Write(buf[3]);
            proc_http(sn, (char *)buf);

         }
         break;
      case SOCK_CLOSE_WAIT :
         if((ret = disconnect(sn)) != SOCK_OK) return ret;
         break;
      case SOCK_INIT :
         if( (ret = listen(sn)) != SOCK_OK) return ret;
         break;
      case SOCK_CLOSED:
         if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
         break;
      default:
         break;
   }
   return 1;
}




void main()
{
     UART1_Init(9600);
     Wizchip_Rst_Direction = 0;                           // Set Rst pin to be output
     Wizchip_CS_Direction = 0;                         // Set CS pin to be output

    CB_ChipDeselect();                                                          // Deselect module

//     Reset module
    Wizchip_Rst = 0;
    Delay_ms(1);
    Wizchip_Rst = 1;
    Delay_ms(1);


            SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

            reg_wizchip_cs_cbfunc( CB_ChipSelect, CB_ChipDeselect);
            WIZCHIP.IF.SPI._read_byte   = CB_SpiRead;
            WIZCHIP.IF.SPI._write_byte  = CB_SpiWrite;

            CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(0x00);
            SPI1_Write(0x06);
            SPI1_Write(0x80);
            CB_ChipDeselect();
            WIZCHIP_WRITE_BUF(REG_SHAR, mac, 4);
            CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(0x0D);
            SPI1_Write(0x06);
            SPI1_Write(mac[4]);
            SPI1_Write(mac[5]);
            CB_ChipDeselect();
            WIZCHIP_WRITE_BUF(REG_GAR, gw, 4);
            WIZCHIP_WRITE_BUF(REG_SUBR, sn, 4);
            WIZCHIP_WRITE_BUF(REG_SIPR, sip, 4);
            
            
            CB_ChipSelect();
            SPI1_Write(0x00);
            SPI1_Write(0x18);
            SPI1_Write(0x06);
            SPI1_Write(0x01);
            CB_ChipDeselect();

            socket_write(0x04, 0x00);
            socket_write(0x05, 0x50);
            socket_write(0x00, 0x01);
            socket_write(0x01, 0x01);
            socket_write(0x01, 0x02);

            while(1){
                     WebServer(SOCK_WEBSERVER, gDATABUF, PORT_WEBSERVER);
                     }
}

So your PC sends SYN packet to establish new connection, but W5500 responds with RST/ACK packet. I can not understand algorithm from your code, but probably you confused server-side W5500 implementation and client-side implementation.

When your PC connects to the W5500, W5500 sends required data to the PC, and at the end of this data stream W5500 must perform disconnect, and only then close commands. Disconnect command is being performed while W5500, as a server, is in “established” state, thus your code

case SOCK_CLOSE_WAIT :
     if((ret = disconnect(sn)) != SOCK_OK) return ret;
     break;

may simply never execute when server needs to terminate the connection, and W5500 does not perform disconnect (internally to itself, and informing PC that it has finished with data).

Please revise your algorithm, and see which case statements are being executed, and when.