Updated W5100.h definitions per Wiznet W5500 version 1.0.6 data sheet values (see page 30, Section 3.1 Common Register Block):
GP_REGISTER16(RTR, 0x0019); // Timeout address
__GP_REGISTER8 (RCR, 0x001B); // Retry count
GP_REGISTER8 (PTIMER, 0x001C); // PPP LCP Request Timer
GP_REGISTER8 (PMAGIC, 0x001D); // PPP LCP Magic Number
GP_REGISTER_N(PHAR, 0x001E, 6); // PPP Destination MAC address
GP_REGISTER16(PSID, 0x0024); // PPP Session ID
GP_REGISTER16(PMRU, 0x0026); // PPP Maximum Segment Size
GP_REGISTER_N(UIPR, 0x0028, 4); // Unreachable IP address in UDP mode (W5500 only)
GP_REGISTER16(UPORT, 0x002C); // Unreachable Port address in UDP mode (W5500 only)
__GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx
I discovered this while tweaking RTR values in the hope of resolving the client-mode TCP connection problems others have reported. Setting RTR to 4000 (400ms) seems to have eliminated the connection timeout I was seeing, but I still have the problem in which socketConnect reports SnSR::CLOSED while waiting for SnSR::ESTABLISHED.
Update: Further testing revealed that the device I'm connecting to, a Linksys WRTGS running DD-WRT, routinely takes over 202 - 237 ms to connect (though it sometimes connects in as little as 100 ms). This is longer than the W5500's default of 200ms (W5500 datasheet, page 39), which caused constant failures to connect.
Setting the W5500 timeout (RTR) with the current driver was fruitless because W5100.h contains the wrong address for this register. After I fixed that, I was able to set RTR to 3000 by adding W5100.setRetransmissionTime(3000); to EthernetClient::connect (see code below).
I made two other minor mods while investigating this. I changed execCmdSn so the Arduino isn't constantly hammering the W5500's I/O while waiting for the command register to be zeroed by commenting out "while (readSnCR(s)) ;" and adding a loop with a modest delay between reads. After resolving the connection timeout issue I restored the original code and got an occasional failure to connect, while I got none with the new code.
{
// Send command to socket
writeSnCR(s, _cmd);
// Wait for command to complete
//while (readSnCR(s)) ;
do {
delayMicroseconds(100);
} while (readSnCR(s));
}
The other minor mod was the increase of the delay in the loop in EthernetClient::connect that watches for the socket to enter ESTABLISHED status from 1 ms to 5 ms. I had persistent failures to connect with the 1 ms delay that vanished when I increased it to 5 ms. YMMV. Incidentally, my target platform is an Adafruit Metro M4 Express.
One last note; the W5500 datasheet (page 63, 5.5.4 SPI Timing) specifies a maximum guaranteed SPI bus clock rate of 33.3 MHz. I ran my tests with a SPI clock of 25 MHz. If your performance is flaky, consider reducing your SPI bus clock.
{
if (sockindex < MAX_SOCK_NUM) {
if (Ethernet.socketStatus(sockindex) != SnSR::CLOSED) {
Ethernet.socketDisconnect(sockindex); // TODO: should we call stop()?
}
sockindex = MAX_SOCK_NUM;
}
#if defined(ESP8266) || defined(ESP32)
if (ip == IPAddress((uint32_t)0) || ip == IPAddress(0xFFFFFFFFul)) return 0;
#else
if (ip == IPAddress(0ul) || ip == IPAddress(0xFFFFFFFFul)) return 0;
#endif
**W5100.setRetransmissionTime(3000);**
sockindex = Ethernet.socketBegin(SnMR::TCP, 0);
if (sockindex >= MAX_SOCK_NUM) return 0;
Ethernet.socketConnect(sockindex, rawIPAddress(ip), port);
uint32_t start = millis();
while (1) {
uint8_t stat = Ethernet.socketStatus(sockindex);
//iStats[i++] = stat;
if (stat == SnSR::ESTABLISHED) return 1;
if (stat == SnSR::CLOSE_WAIT) return 1;
if (stat == SnSR::CLOSED) {
return 0;
}
if ((uint16_t)(millis() - start) > _timeout) break;
**delay(5);**
}
Ethernet.socketClose(sockindex);
sockindex = MAX_SOCK_NUM;
return 0;
}
The W5500 data sheet (https://wizwiki.net/wiki/lib/exe/fetch.php?media=products:w5500:w5500_ds_v106e_141230.pdf) shows certain W5500 registers to be at different addresses than those used by the driver (W5100.h).
Current W5100.h values: GP_REGISTER16(RTR, 0x0017); // Timeout address __GP_REGISTER8 (RCR, 0x0019); // Retry count GP_REGISTER8 (RMSR, 0x001A); // Receive memory size (W5100 only) GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size (W5100 only) __GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer __GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode (W5100 only) GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode (W5100 only)
Updated W5100.h definitions per Wiznet W5500 version 1.0.6 data sheet values (see page 30, Section 3.1 Common Register Block): GP_REGISTER16(RTR, 0x0019); // Timeout address __GP_REGISTER8 (RCR, 0x001B); // Retry count GP_REGISTER8 (PTIMER, 0x001C); // PPP LCP Request Timer GP_REGISTER8 (PMAGIC, 0x001D); // PPP LCP Magic Number GP_REGISTER_N(PHAR, 0x001E, 6); // PPP Destination MAC address GP_REGISTER16(PSID, 0x0024); // PPP Session ID GP_REGISTER16(PMRU, 0x0026); // PPP Maximum Segment Size GP_REGISTER_N(UIPR, 0x0028, 4); // Unreachable IP address in UDP mode (W5500 only) GP_REGISTER16(UPORT, 0x002C); // Unreachable Port address in UDP mode (W5500 only) __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx
I discovered this while tweaking RTR values in the hope of resolving the client-mode TCP connection problems others have reported. Setting RTR to 4000 (400ms) seems to have eliminated the connection timeout I was seeing, but I still have the problem in which socketConnect reports SnSR::CLOSED while waiting for SnSR::ESTABLISHED.
Update: Further testing revealed that the device I'm connecting to, a Linksys WRTGS running DD-WRT, routinely takes over 202 - 237 ms to connect (though it sometimes connects in as little as 100 ms). This is longer than the W5500's default of 200ms (W5500 datasheet, page 39), which caused constant failures to connect.
Setting the W5500 timeout (RTR) with the current driver was fruitless because W5100.h contains the wrong address for this register. After I fixed that, I was able to set RTR to 3000 by adding W5100.setRetransmissionTime(3000); to EthernetClient::connect (see code below).
I made two other minor mods while investigating this. I changed execCmdSn so the Arduino isn't constantly hammering the W5500's I/O while waiting for the command register to be zeroed by commenting out "while (readSnCR(s)) ;" and adding a loop with a modest delay between reads. After resolving the connection timeout issue I restored the original code and got an occasional failure to connect, while I got none with the new code.
The other minor mod was the increase of the delay in the loop in EthernetClient::connect that watches for the socket to enter ESTABLISHED status from 1 ms to 5 ms. I had persistent failures to connect with the 1 ms delay that vanished when I increased it to 5 ms. YMMV. Incidentally, my target platform is an Adafruit Metro M4 Express.
One last note; the W5500 datasheet (page 63, 5.5.4 SPI Timing) specifies a maximum guaranteed SPI bus clock rate of 33.3 MHz. I ran my tests with a SPI clock of 25 MHz. If your performance is flaky, consider reducing your SPI bus clock.