---
title: "W5100 stop working after 6 min"
url: "https://maker.wiznet.io/forum/10040"
markdown_url: "https://maker.wiznet.io/forum/10040/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "Kvy"
created: "2014-03-13T10:05:21+09:00"
last_activity: "2017-05-04T08:31:59+09:00"
language: "en"
views: 1599
replies: 2
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# W5100 stop working after 6 min

## Question

Asked by Kvy on 2014-03-13 in Ethernet Chips.

Hi all,

I am using the Ethernet Arduino board.
I am sending and receiving packets of 128 bits size every 11 ms. After approximately 6 minuets the W5100 stops sending packets, and don’t get out from the while loop:

int sendUDP(SOCKET s)
{
[color=#FF0000] W5100.execCmdSn(s, Sock_SEND);

/* +2008.01 bj */
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
{
if (W5100.readSnIR(s) & SnIR::TIMEOUT)
{
/* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
return 0;
}
}[/color]

/* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK);

/* Sent ok */
return 1;
}

I will be happy to receive some help debugging it.

Thanks
Yoav

## Replies

### Reply 1 by Kvy, 2014-03-14

Hi, I quote a part of code from the socket.cpp file of Arduino ethernet library. The entire code is: #include “w5100.h” #include “socket.h” static uint16_t local_port; /** @brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it. @return 1 for success else 0. */ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag) { if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE)) { close(s); W5100.writeSnMR(s, protocol | flag); if (port != 0) { W5100.writeSnPORT(s, port); } else { local_port++; // if don’t set the source port, set local_port number. W5100.writeSnPORT(s, local_port); } W5100.execCmdSn(s, Sock_OPEN); return 1; } return 0; } /** @brief This function close the socket and parameter is “s” which represent the socket number */ void close(SOCKET s) { W5100.execCmdSn(s, Sock_CLOSE); W5100.writeSnIR(s, 0xFF); } /** @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_t listen(SOCKET s) { if (W5100.readSnSR(s) != SnSR::INIT) return 0; W5100.execCmdSn(s, Sock_LISTEN); return 1; } /** @brief This function established the connection for the channel in Active (client) mode. This function waits for the untill the connection is established. @return 1 for success else 0. */ uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port) { if ( ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) || ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || (port == 0x00) ) return 0; // set destination IP W5100.writeSnDIPR(s, addr); W5100.writeSnDPORT(s, port); W5100.execCmdSn(s, Sock_CONNECT); return 1; } /** @brief This function used for disconnect the socket and parameter is “s” which represent the socket number @return 1 for success else 0. */ void disconnect(SOCKET s) { W5100.execCmdSn(s, Sock_DISCON); } /** @brief This function used to send the data in TCP mode @return 1 for success else 0. */ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len) { uint8_t status=0; uint16_t ret=0; uint16_t freesize=0; if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size. else ret = len; // if freebuf is available, start. do { freesize = W5100.getTXFreeSize(s); status = W5100.readSnSR(s); if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT)) { ret = 0; break; } } while (freesize &lt; ret); // copy data W5100.send_data_processing(s, (uint8_t *)buf, ret); W5100.execCmdSn(s, Sock_SEND); /* +2008.01 bj / while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { / m2008.01 [bj] : reduce code / if ( W5100.readSnSR(s) == SnSR::CLOSED ) { close(s); return 0; } } / +2008.01 bj */ W5100.writeSnIR(s, SnIR::SEND_OK); 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. */ int16_t recv(SOCKET s, uint8_t *buf, int16_t len) { // Check how much data is available int16_t ret = W5100.getRXReceivedSize(s); if ( ret == 0 ) { // No data available. uint8_t status = W5100.readSnSR(s); if ( status == SnSR::LISTEN || status == SnSR::CLOSED || status == SnSR::CLOSE_WAIT ) { // The remote end has closed its side of the connection, so this is the eof state ret = 0; } else { // The connection is still up, but there’s no data waiting to be read ret = -1; } } else if (ret > len) { ret = len; } if ( ret > 0 ) { W5100.recv_data_processing(s, buf, ret); W5100.execCmdSn(s, Sock_RECV); } return ret; } /** @brief Returns the first byte in the receive queue (no checking) @return */ uint16_t peek(SOCKET s, uint8_t *buf) { W5100.recv_data_processing(s, buf, 1, 1); return 1; } /** @brief This function is an application I/F function which is used to send the data for other then TCP mode. Unlike TCP transmission, The peer's destination address and the port is needed. @return This function return send data size for success else -1. */ uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port) { uint16_t ret=0; if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size. else ret = len; if ( ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) ||(ret == 0) ) { /* +2008.01 [bj] : added return value */ ret = 0; } else { W5100.writeSnDIPR(s, addr); W5100.writeSnDPORT(s, port); // copy data W5100.send_data_processing(s, (uint8_t *)buf, ret); W5100.execCmdSn(s, Sock_SEND); /* +2008.01 bj */ while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { if (W5100.readSnIR(s) & SnIR::TIMEOUT) { /* +2008.01 [bj]: clear interrupt */ W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */ return 0; } } /* +2008.01 bj */ W5100.writeSnIR(s, SnIR::SEND_OK); } return ret; } /** @brief This function is an application I/F function which is used to receive the data in other then TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well. @return This function return received data size for success else -1. */ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port) { uint8_t head[8]; uint16_t data_len=0; uint16_t ptr=0; if ( len > 0 ) { ptr = W5100.readSnRX_RD(s); switch (W5100.readSnMR(s) & 0x07) { case SnMR::UDP : W5100.read_data(s, (uint8_t *)ptr, head, 0x08); ptr += 8; // read peer’s IP address, port number. addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; *port = head[4]; *port = (*port &lt;&lt; 8) + head[5]; data_len = head[6]; data_len = (data_len &lt;&lt; 8) + head[7]; W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. ptr += data_len; W5100.writeSnRX_RD(s, ptr); break; case SnMR::IPRAW : W5100.read_data(s, (uint8_t *)ptr, head, 0x06); ptr += 6; addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; data_len = head[4]; data_len = (data_len &lt;&lt; 8) + head[5]; W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. ptr += data_len; W5100.writeSnRX_RD(s, ptr); break; case SnMR::MACRAW: W5100.read_data(s,(uint8_t*)ptr,head,2); ptr+=2; data_len = head[0]; data_len = (data_len&lt;&lt;8) + head[1] - 2; W5100.read_data(s,(uint8_t*) ptr,buf,data_len); ptr += data_len; W5100.writeSnRX_RD(s, ptr); break; default : break; } W5100.execCmdSn(s, Sock_RECV); } return data_len; } uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len) { uint8_t status=0; uint16_t ret=0; if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size. else ret = len; if (ret == 0) return 0; W5100.send_data_processing(s, (uint8_t *)buf, ret); W5100.execCmdSn(s, Sock_SEND); while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { status = W5100.readSnSR(s); if (W5100.readSnIR(s) & SnIR::TIMEOUT) { /* in case of igmp, if send fails, then socket closed / / if you want change, remove this code. */ close(s); return 0; } } W5100.writeSnIR(s, SnIR::SEND_OK); return ret; } uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len) { uint16_t ret =0; if (len > W5100.getTXFreeSize(s)) { ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size. } else { ret = len; } W5100.send_data_processing_offset(s, offset, buf, ret); return ret; } int startUDP(SOCKET s, uint8_t* addr, uint16_t port) { if ( ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) || ((port == 0x00)) ) { return 0; } else { W5100.writeSnDIPR(s, addr); W5100.writeSnDPORT(s, port); return 1; } } int sendUDP(SOCKET s) { W5100.execCmdSn(s, Sock_SEND); /* +2008.01 bj / while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { if (W5100.readSnIR(s) & SnIR::TIMEOUT) { / +2008.01 [bj]: clear interrupt */ W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT)); return 0; } } /* +2008.01 bj */ W5100.writeSnIR(s, SnIR::SEND_OK); /* Sent ok */ return 1; }

### Reply 2 by Kvy, 2014-03-16

Hi midnightcow,

Thanks for the replay.

I didn’t change the original Ethernet library. I don’t get SEND_OK, and it happens when the data rate is as I mention above, with slower data rate it works fine.

I also tried modifying the Ethernet library and my own time out, it also didn’t help (in the sendUDP):

while ((W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK) {

```
	if (W5100.readSnIR(s) & SnIR::TIMEOUT) {			
		/* +2008.01 [bj]: clear interrupt */
		W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT));
		return 0;
	}

	if (ii > 1000) {		
		W5100.writeSnIR(s, SnIR::SEND_OK | SnIR::TIMEOUT);
		return 0;
	}
	ii++;
```

}

Thnaks
Yoav

---

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