Re-TX data on the W5500


#1

All,

I have been re-writeing the iolibrary_v100 for the processor I am using.
I was going through the TCPReSend function, in particular TCPReSendNB().
After some checks, it issues the SEND command in the sockets CR register.

Here is what I am wondering.
If the SEND command was already used to on the first transmit, TCPSend.
Then would not the TX_RD and TX_WR be the same value?
And if so, how does sending the SEND command again work, if the
TX_RD and TX_WR are the same value?

If one could decrease the TX_RD by the data length, then I could see
resending the SEND command work.
But the TX_RD is read only, correct?
So if it is read only, then how can data be re-transmitted without
loading the data back into the socket TX buffer first, and increasing
the TX_WR pointer?

Thanks,
Jim


#2

Hi,
ioLibrary_v100 are based on the previous W5200 driver in W7200. So, the W5200 code are remained still.
It was for supporting on old W7200 users. If you use W5500 first, We recommended ioLibraray_BSD instead of ioLirary_v100 because it is difficult to intensive technical support.

Anyway, We will fixed the code as soon as possible.

If you get a fast response, you can modify it as like the followings.

int32_t TCPSend(uint8_t s, const int8_t *buf, uint16_t len)
{
	int32_t ret;
	while(1) {
		ret = TCPSendNB(s, buf, len);
		if(ret == RET_OK) break;
		if(ret != SOCKERR_BUSY) return ret;
	}
	while(1) {
		ret = TCPSendCHK(s);
		if(ret >= 0 || ret != SOCKERR_BUSY) break;
	}
	return len;
}

int32_t TCPSendCHK(uint8_t s)
{
	uint16_t txrd;
	if(!(getSn_IR(s) & Sn_IR_SENDOK)) {
		if(getSn_SR(s) == SOCK_CLOSED) {
                  DBG("SOCK_CLOSED");                    
			TCPClose(s);
			return SOCKERR_CLOSED;
		}
		return SOCKERR_BUSY;
	} else setSn_IR(s, Sn_IR_SENDOK);
	return 0;
}

And remove TCPReSend() funciton in your code.

void loopback_tcps(uint8_t sock, uint16_t port)
{
	int32_t ret;
	int32_t SendLen, ReSendLen;

	ret = TCPRecv(sock, data_buf, TX_RX_MAX_BUF_SIZE);

	if(ret > 0){				// Received
		SendLen = TCPSend(sock, data_buf, ret);

                /* Remove TCPResend() funciton */
                /*
		if(SendLen < ret){
			while(SendLen != ret){
				ReSendLen = TCPReSend(sock);

				if(ReSendLen > 0){
					SendLen += ReSendLen;

				} else if(ReSendLen == SOCKERR_WINDOW_FULL){
					LOG("Window Full");
					TCPClose(sock);
					DBG("TCP Socket Close");
					while(1);

				} else{
					break;
				}
			}
		}

	} else  */
        if(ret == SOCKERR_NOT_TCP){	// Not TCP Socket, It's UDP Socket
		DBG("UDP Socket Close");
		UDPClose(sock);
	} else if(ret == SOCKERR_CLOSED){		// Socket Closed
          LOGA("TCPS Loop-Back Started - sock(%d):port(%d)",(uint16_t)sock,port);
		TCPServerOpen(sock, port);
	}

	if(GetTCPSocketStatus(sock) == SOCKSTAT_CLOSE_WAIT){	// Close waiting
		TCPClose(sock);
	}
}

Thank you.


#3

I think I figured it out.
The only thing in the W5500 datasheet says is
"SEND command transmits from the current Sn_TX_RD to the Sn_TX_WR".
Well looking at the datasheet for the W5200(page 50) it looks like there is an
exception to that. If the data is longer then what is set in the MSS register,
then it only sends that length of data. In that case the Sn_TX_RD would not be
increased all the way to Sn_TX_WR and the resend fiction TCPReSend would
be the thing to use to transmit the next chunk of data.

The whole section 5 of the W5200 data sheet is missing from the W5500 manual,
I hope this gets included in the W5500 datasheet for people like me that have not
used a previous wiz chip.

Thanks,
Jim


#4

Hi,
Thanks for your advice.
We will apply that after considering enough.

Thank you.