WIZnet Developer Forum

Problem with the TCP connection at 10Mbps

Hi!
We decided to upgrade our custom board with W5100 to W5200.

W5200 is installed on via typical connection from datasheet.
Software init was made also by typical code.

Problem is it wont establish TCP connection on 10Mb.
100 Mbit has no any problems with UDP or TCP.

10 Mbit was forced via pulldown on SPEED pin, or using 10Mb hub.
UDP packets are received and transmitted without problems on 10Mb.
When I try to connect to W5200 telnet server, it resets connection with cause “TCP acked unseen segment”
This situation repeats every time I try to connect.
Wireshark capture is shown on picture.

123.123.123.104 - PC
123.123.123.219 - W5200

Thanks in advance for any suggestion.
Alex


Hi,
as i think, your socket was closed, so RST packet is shown by the capture image.
Please check socket status on your firmware in debug mode.
AND, I think, if you should change W5100, you’d better to change W5500. it’s more cheaper and brand new.
you could find more sample code about W5500 in WIZnet Github site github.com/wiznet. Please consider it. :smiley:

Hi!
Firmware has no problems, because when we switch to 100Mb, all works as intended on short cable.
TCP is not working only on 10 Mbits.
Socket is closed by W5200 itself, not by firmware. Chip sees wrong TCP ack from PC, but Wireshark shows correct ACK
UPDATE: 100 Mbit is also cant work when using long cable more than 70-80 meters. Looks like hardware problem.
Schematics is default. Two different devices with same schematics but different tracing shows same result.
100 Mbit is all fine with short cable, but not working with long cable >70m (shows no link).
10 Mbit shows link OK on any cable, but cant properly accept TCP connection.
Alex

hi alecn50.

W5500 is an operation to the length of the cable 120m. If you want to send the W5500 can give samples. Try considered.
You say the firmware is not a problem, we want to try your review. Are you okay?
There is a possibility that there is a problem that you have not discovered. We’ll review.
And your circuit recommend trying one more check.
I will attach the circuit that we recommend.
Thank you.
W5200E01-M3 REV115_20140625.pdf (157 KB)

Hi!
Here is simple test for TCP connection.
We have 100Mbit switch, where PC (123.123.123.104), W5200 (123.123.123.219) and 10Mbit switch are connected. All cordes are short <1m.

We establish first Telnet connection via 100 Mbit switch, disconnect. All flows normal

Next, patch cord from W5200 is detached from 100 mbit switch and connected to 10 Mbit switch.


W5200 resets connection after it sends first data and receive ACK for it.
Previously, on 100 Mbit same connection completed without problem.
This error repeats always the same without any deviation.
And take attention - we dont see any hardware problems as IP protocol flows perfectly - all checksums are ok.
SYN received without error
SYN ACK send OK
ACK received without error
Telnet data sent correctly
ACK is OK marked Wireshark, but didnt received correctly by W5200.

PS As I mentioned, we have UDP packets exchange, which has no problems on 100 or 10 mbit, so I dont show it here.

Regards, Alex

Hi,
Could you show your code snippet? I couldn’t do any more as only my assumption.
And I suggest one more check point on your firmware. After writing command register, are you waiting for being zero value of that command register? if you don’t, then please you do insert that code and run again.
Thanks.

Hi ! Thanks for reply.
Sure, all chip commands are sent as recommended, because we are using default SOCKET.C functions, provided by Wiznet.
Exactly, to run telnet server, at least two functions must be used:
socket() - to reserve resources for new socket in W5200
listen() - to activate new socket to make it listen for connections

/*
*
@file		socket.c
@brief	setting chip register for socket
*		last update : July 30, 2013
*
*  -----------------------------------------------------------------------------------
*  History
*  -----------------------------------------------------------------------------------
*
*	- first release : Jan. 2008
*  - modified code July 30, 2013 @wiznet : fix the code to add condition "retry" in send().
*
*/

/**
@brief	This Socket function initialize the channel in perticular mode, and set the port and wait for W5200 done it.
@return 	1 for sucess else 0.
*/  
uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag)
{
	uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("socket()\r\n");
#endif
	if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
	{
		close(s);
		IINCHIP_WRITE(Sn_MR(s),protocol | flag);
		if (port != 0) {
			IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
			IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
		} else {
			local_port++; // if don't set the source port, set local_port number.
                        if(local_port==23) local_port++;
			IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
			IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
		}
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR

		/* wait to process the command... */
		while( IINCHIP_READ(Sn_CR(s)) ) 
			;
		/* ------- */
		ret = 1;
	}
	else
	{
		ret = 0;
	}
#ifdef __DEF_IINCHIP_DBG__
	printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
#endif
	return ret;
}

/**
@brief	This function established  the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return	1 for success else 0.
*/ 
uint8 listen(SOCKET s)
{
	uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
	printf("listen()\r\n");
#endif
	if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
	{
		IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
		/* wait to process the command... */
		while( IINCHIP_READ(Sn_CR(s)) ) 
			;
		/* ------- */
		ret = 1;
	}
	else
	{
		ret = 0;
#ifdef __DEF_IINCHIP_DBG__
	printf("Fail[invalid ip,port]\r\n");
#endif
	}
	return ret;
}

As we can see, all commands for W5200 are followed by waiting for clear register to make sure command was executed:
while( IINCHIP_READ(Sn_CR(s)) );

Send() and Recv() functions are also respect this rule:
Any write to command register is followed by waiting to command complete.

[code]
/**
@brief This function used to send the data in TCP mode
@return 1 for success else 0.
*/
uint16 send(SOCKET s, const uint8 * buf, uint16 len, bool retry)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
uint16 txrd, txrd_before_send;

#ifdef DEF_IINCHIP_DBG
printf(“send()\r\n”);
#endif
if(retry) ;
else {
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;

	// if freebuf is available, start.
	do 
	{
		freesize = getSn_TX_FSR(s);
		status = IINCHIP_READ(Sn_SR(s));
		if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
		{
			ret = 0; 
			break;
		}

#ifdef DEF_IINCHIP_DBG
printf(“socket %d freesize(%d) empty or error\r\n”, s, freesize);
#endif
} while (freesize < ret);

	// copy data
	send_data_processing(s, (uint8 *)buf, ret);
}

// if(ret != 0) // error code
// 2013-07-30 wiznet fix the code to add condition "retry"
if(retry || ret != 0)
{
txrd_before_send = IINCHIP_READ(Sn_TX_RD0(s));
txrd_before_send = (txrd_before_send << 8) + IINCHIP_READ(Sn_TX_RD0(s) + 1);

	IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);

	/* wait to process the command... */
	while( IINCHIP_READ(Sn_CR(s)) );

	while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
            {
		if(IINCHIP_READ(Sn_IR(s)) == SOCK_CLOSED)
		{

#ifdef DEF_IINCHIP_DBG
printf(“SOCK_CLOSED.\r\n”);
#endif
close(s);
return 0;
}
}
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);

	txrd = IINCHIP_READ(Sn_TX_RD0(s));
	txrd = (txrd << 8) + IINCHIP_READ(Sn_TX_RD0(s) + 1);

	if(txrd > txrd_before_send) {
		ret = txrd - txrd_before_send;
	} else {
		ret = (0xffff - txrd_before_send) + txrd + 1;
	}
}
            
return ret;

}

/**
@brief This function is an application I/F function which is used to receive the data in TCP mode.
It continues to wait for data as much as the application wants to receive.

@return received data size for success else -1.
*/
uint16 recv(SOCKET s, uint8 * buf, uint16 len)
{
uint16 ret=0;
#ifdef DEF_IINCHIP_DBG
printf(“recv()\r\n”);
#endif

if ( len > 0 )
{
	recv_data_processing(s, buf, len);
	IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);

	/* wait to process the command... */
	while( IINCHIP_READ(Sn_CR(s)));
	/* ------- */

	ret = len;
}
return ret;

}[/code]
Regards, Alex

ok. actually I don’t know why this happens. :frowning:
so, for my reference please show the main code that calls wiznet api.
If you can’t all of code, then please open part of the code related to network.

Hi!

So, seems problem will not be resolved, so I write some resume.

Problem is that dozens of our custom devices, based on W5200, already sold.
Our developing and final testing was made only on short cable and 100 Mbit.
All devices passed.
We didnt complete full testing for W5200, as it was made for W5100 and we suggest W5200 repeats W5100 in physical parameters.
So, once upon a time, one of our clients decided to make long Ethernet connection and connected 100 meters cable to device.
And TCP connection failed. We started to investigate this and tried to downgrade chip to 10 Mbit. It also failed.
All possbile Schematics correction was made, its updated considered last Wiznet data (condensers on 3,3 line increased, ferrits removed)

INFO UPDATE:
We are using 4 TCP sockets as clients in W5200. When in fail condition (10 Mbit or 100Mbit/long cable), 3 clients cant connect to external servers, but 1 connected well. Thats impossible to understand.

All points to chip fail
Last our decision is to move to W5500 .

Regards, Alex

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.