diff --git a/LibraryPatches/Ethernet/src/Ethernet.cpp b/LibraryPatches/Ethernet/src/Ethernet.cpp new file mode 100644 index 00000000..3e5596dc --- /dev/null +++ b/LibraryPatches/Ethernet/src/Ethernet.cpp @@ -0,0 +1,319 @@ +/**************************************************************************************************************************** + Ethernet.cpp + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +#include +#include "Ethernet.h" +#include "utility/w5100.h" +#include "Dhcp.h" + +#define ETHERNET_DEBUG 1 + + +IPAddress EthernetClass::_dnsServerAddress; +DhcpClass* EthernetClass::_dhcp = NULL; + +// KH +void EthernetClass::setRstPin(uint8_t pinRST) +{ + _pinRST = pinRST; + pinMode(_pinRST, OUTPUT); + digitalWrite(_pinRST, HIGH); +} +void EthernetClass::setCsPin(uint8_t pinCS) +{ + _pinCS = pinCS; + +#if ( ETHERNET_DEBUG > 0 ) + Serial.print("Input pinCS = "); + Serial.println(pinCS); + Serial.print("_pinCS = "); + Serial.println(_pinCS); +#endif +} + +void EthernetClass::initMaxSockNum(uint8_t maxSockNum) +{ + _maxSockNum = maxSockNum; +} + +uint8_t EthernetClass::softreset() +{ + return W5100.softReset(); +} + +void EthernetClass::hardreset() +{ + if(_pinRST != 0) + { + digitalWrite(_pinRST, LOW); + delay(1); + digitalWrite(_pinRST, HIGH); + delay(150); + } +} + +int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +{ + DhcpClass s_dhcp; + _dhcp = &s_dhcp; + +#if ( ETHERNET_DEBUG > 0 ) + Serial.print("_pinCS = "); + Serial.print(_pinCS); +#endif + + // Initialise the basic info + // KH + if (W5100.init(MAX_SOCK_NUM, _pinCS) == 0) + return 0; + + + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac); + W5100.setIPAddress(IPAddress(0,0,0,0).raw_address()); + SPI.endTransaction(); + + // Now try to get our config info from a DHCP server + int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout); + if (ret == 1) + { + // We've successfully found a DHCP server and got our configuration + // info, so set things accordingly + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); + W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); + W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); + SPI.endTransaction(); + _dnsServerAddress = _dhcp->getDnsServerIp(); + socketPortRand(micros()); + } + return ret; +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip) +{ + // Assume the DNS server will be the machine on the same network as the local IP + // but with last octet being '1' + IPAddress dns = ip; + dns[3] = 1; + begin(mac, ip, dns); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns) +{ + // Assume the gateway will be the machine on the same network as the local IP + // but with last octet being '1' + IPAddress gateway = ip; + gateway[3] = 1; + begin(mac, ip, dns, gateway); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway) +{ + IPAddress subnet(255, 255, 255, 0); + begin(mac, ip, dns, gateway, subnet); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) +{ + if (W5100.init(MAX_SOCK_NUM, _pinCS) == 0) + return; + + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac); + +#if ( defined(ESP8266) || defined(ESP32) ) + W5100.setIPAddress(ip.raw_address()); + W5100.setGatewayIp(gateway.raw_address()); + W5100.setSubnetMask(subnet.raw_address()); +#elif (ARDUINO > 106 || TEENSYDUINO > 121) + W5100.setIPAddress(ip._address.bytes); + W5100.setGatewayIp(gateway._address.bytes); + W5100.setSubnetMask(subnet._address.bytes); +#else + W5100.setIPAddress(ip._address); + W5100.setGatewayIp(gateway._address); + W5100.setSubnetMask(subnet._address); +#endif + + SPI.endTransaction(); + _dnsServerAddress = dns; +} + +void EthernetClass::init(uint8_t sspin) +{ + W5100.setSS(sspin); +} + +EthernetLinkStatus EthernetClass::linkStatus() +{ + switch (W5100.getLinkStatus()) { + case UNKNOWN: return Unknown; + case LINK_ON: return LinkON; + case LINK_OFF: return LinkOFF; + default: return Unknown; + } +} + +EthernetHardwareStatus EthernetClass::hardwareStatus() +{ + switch (W5100.getChip()) { + case 51: return EthernetW5100; + case 52: return EthernetW5200; + case 55: return EthernetW5500; + default: return EthernetNoHardware; + } +} + +int EthernetClass::maintain() +{ + int rc = DHCP_CHECK_NONE; + if (_dhcp != NULL) { + // we have a pointer to dhcp, use it + rc = _dhcp->checkLease(); + switch (rc) + { + case DHCP_CHECK_NONE: + //nothing done + break; + case DHCP_CHECK_RENEW_OK: + case DHCP_CHECK_REBIND_OK: + //we might have got a new IP. + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); + W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); + W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); + SPI.endTransaction(); + _dnsServerAddress = _dhcp->getDnsServerIp(); + break; + default: + //this is actually an error, it will retry though + break; + } + } + return rc; +} + + +void EthernetClass::MACAddress(uint8_t *mac_address) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getMACAddress(mac_address); + SPI.endTransaction(); +} + +IPAddress EthernetClass::localIP() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getIPAddress(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +IPAddress EthernetClass::subnetMask() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getSubnetMask(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +IPAddress EthernetClass::gatewayIP() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getGatewayIp(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +void EthernetClass::setMACAddress(const uint8_t *mac_address) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac_address); + SPI.endTransaction(); +} + +void EthernetClass::setLocalIP(const IPAddress local_ip) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = local_ip; + W5100.setIPAddress(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setSubnetMask(const IPAddress subnet) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = subnet; + W5100.setSubnetMask(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setGatewayIP(const IPAddress gateway) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = gateway; + W5100.setGatewayIp(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setRetransmissionTimeout(uint16_t milliseconds) +{ + if (milliseconds > 6553) milliseconds = 6553; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setRetransmissionTime(milliseconds * 10); + SPI.endTransaction(); +} + +void EthernetClass::setRetransmissionCount(uint8_t num) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setRetransmissionCount(num); + SPI.endTransaction(); +} + +EthernetClass Ethernet; diff --git a/LibraryPatches/Ethernet/src/Ethernet.h b/LibraryPatches/Ethernet/src/Ethernet.h index 3e800b13..893131a1 100644 --- a/LibraryPatches/Ethernet/src/Ethernet.h +++ b/LibraryPatches/Ethernet/src/Ethernet.h @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.6 + Version: 1.0.8 Copyright 2018 Paul Stoffregen @@ -37,7 +37,9 @@ 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge - 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. *****************************************************************************************************************************/ #ifndef ethernet_h_ @@ -100,26 +102,45 @@ class EthernetClass { static IPAddress _dnsServerAddress; static DhcpClass* _dhcp; public: + // KH + uint8_t _maxSockNum; + uint8_t _pinCS; + uint8_t _pinRST; + + void setRstPin(uint8_t pinRST = 9); // for WIZ550io or USR-ES1, must set befor Ethernet.begin + void setCsPin(uint8_t pinCS = 10); // must set befor Ethernet.begin + + // Initialize with less sockets but more RX/TX Buffer + // maxSockNum = 1 Socket 0 -> RX/TX Buffer 16k + // maxSockNum = 2 Socket 0, 1 -> RX/TX Buffer 8k + // maxSockNum = 4 Socket 0...3 -> RX/TX Buffer 4k + // maxSockNum = 8 (Standard) all sockets -> RX/TX Buffer 2k + // be carefull of the MAX_SOCK_NUM, because in the moment it can't dynamicly changed + void initMaxSockNum(uint8_t maxSockNum = 8); + + uint8_t softreset(); // can set only after Ethernet.begin + void hardreset(); // You need to set the Rst pin + // Initialise the Ethernet shield to use the provided MAC address and // gain the rest of the configuration through DHCP. // Returns 0 if the DHCP configuration failed, and 1 if it succeeded - static int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); - static int maintain(); - static EthernetLinkStatus linkStatus(); - static EthernetHardwareStatus hardwareStatus(); - - // Manaul configuration - static void begin(uint8_t *mac, IPAddress ip); - static void begin(uint8_t *mac, IPAddress ip, IPAddress dns); - static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); - static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - static void init(uint8_t sspin = 10); - - static void MACAddress(uint8_t *mac_address); - static IPAddress localIP(); - static IPAddress subnetMask(); - static IPAddress gatewayIP(); - static IPAddress dnsServerIP() { return _dnsServerAddress; } + int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int maintain(); + EthernetLinkStatus linkStatus(); + EthernetHardwareStatus hardwareStatus(); + + // Manual configuration + void begin(uint8_t *mac, IPAddress ip); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); + void init(uint8_t sspin = 10); + + void MACAddress(uint8_t *mac_address); + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsServerIP() { return _dnsServerAddress; } void setMACAddress(const uint8_t *mac_address); void setLocalIP(const IPAddress local_ip); @@ -134,38 +155,38 @@ class EthernetClass { friend class EthernetUDP; private: // Opens a socket(TCP or UDP or IP_RAW mode) - static uint8_t socketBegin(uint8_t protocol, uint16_t port); - static uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port); - static uint8_t socketStatus(uint8_t s); + uint8_t socketBegin(uint8_t protocol, uint16_t port); + uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port); + uint8_t socketStatus(uint8_t s); // Close socket - static void socketClose(uint8_t s); + void socketClose(uint8_t s); // Establish TCP connection (Active connection) - static void socketConnect(uint8_t s, uint8_t * addr, uint16_t port); + void socketConnect(uint8_t s, uint8_t * addr, uint16_t port); // disconnect the connection - static void socketDisconnect(uint8_t s); + void socketDisconnect(uint8_t s); // Establish TCP connection (Passive connection) - static uint8_t socketListen(uint8_t s); + uint8_t socketListen(uint8_t s); // Send data (TCP) - static uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len); - static uint16_t socketSendAvailable(uint8_t s); + uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len); + uint16_t socketSendAvailable(uint8_t s); // Receive data (TCP) - static int socketRecv(uint8_t s, uint8_t * buf, int16_t len); - static uint16_t socketRecvAvailable(uint8_t s); - static uint8_t socketPeek(uint8_t s); + int socketRecv(uint8_t s, uint8_t * buf, int16_t len); + uint16_t socketRecvAvailable(uint8_t s); + uint8_t socketPeek(uint8_t s); // sets up a UDP datagram, the data for which will be provided by one // or more calls to bufferData and then finally sent with sendUDP. // return true if the datagram was successfully set up, or false if there was an error - static bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port); + bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port); // copy up to len bytes of data from buf into a UDP datagram to be // sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls. // return Number of bytes successfully buffered - static uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len); + uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len); // Send a UDP datagram built up from a sequence of startUDP followed by one or more // calls to bufferData. // return true if the datagram was successfully sent, or false if there was an error - static bool socketSendUDP(uint8_t s); + bool socketSendUDP(uint8_t s); // Initialize the "random" source port number - static void socketPortRand(uint16_t n); + void socketPortRand(uint16_t n); }; extern EthernetClass Ethernet; @@ -237,15 +258,17 @@ class EthernetUDP : public UDP { class EthernetClient : public Client { public: - EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { } - EthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { } + EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(5000) { } + EthernetClient(uint8_t s) : sockindex(s), _timeout(5000) { } + uint8_t status(); virtual int connect(IPAddress ip, uint16_t port); virtual int connect(const char *host, uint16_t port); virtual int availableForWrite(void); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); virtual int read(); virtual int read(uint8_t *buf, size_t size); @@ -339,8 +362,4 @@ class DhcpClass { int checkLease(); }; - - - - #endif diff --git a/LibraryPatches/Ethernet/src/EthernetServer.cpp b/LibraryPatches/Ethernet/src/EthernetServer.cpp index 010a6c4f..a7c5a7e2 100644 --- a/LibraryPatches/Ethernet/src/EthernetServer.cpp +++ b/LibraryPatches/Ethernet/src/EthernetServer.cpp @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.6 + Version: 1.0.8 Copyright 2018 Paul Stoffregen @@ -37,7 +37,9 @@ 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge - 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. *****************************************************************************************************************************/ #include @@ -50,10 +52,14 @@ uint16_t EthernetServer::server_port[MAX_SOCK_NUM]; void EthernetServer::begin() { uint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port); - if (sockindex < MAX_SOCK_NUM) { - if (Ethernet.socketListen(sockindex)) { + if (sockindex < MAX_SOCK_NUM) + { + if (Ethernet.socketListen(sockindex)) + { server_port[sockindex] = _port; - } else { + } + else + { Ethernet.socketDisconnect(sockindex); } } @@ -66,7 +72,9 @@ EthernetClient EthernetServer::available() uint8_t chip, maxindex=MAX_SOCK_NUM; chip = W5100.getChip(); - if (!chip) return EthernetClient(MAX_SOCK_NUM); + + if (!chip) + return EthernetClient(MAX_SOCK_NUM); //KH, set W5100 to max 2 sockets to increase buffer size if (chip == 51) @@ -125,7 +133,9 @@ EthernetClient EthernetServer::accept() uint8_t chip, maxindex=MAX_SOCK_NUM; chip = W5100.getChip(); - if (!chip) return EthernetClient(MAX_SOCK_NUM); + + if (!chip) + return EthernetClient(MAX_SOCK_NUM); //KH, set W5100 to max 2 sockets to increase buffer size if (chip == 51) @@ -137,24 +147,34 @@ EthernetClient EthernetServer::accept() #endif } - for (uint8_t i=0; i < maxindex; i++) { - if (server_port[i] == _port) { + for (uint8_t i=0; i < maxindex; i++) + { + if (server_port[i] == _port) + { uint8_t stat = Ethernet.socketStatus(i); - if (sockindex == MAX_SOCK_NUM && - (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) { + + if (sockindex == MAX_SOCK_NUM && (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) + { // Return the connected client even if no data received. // Some protocols like FTP expect the server to send the // first data. sockindex = i; server_port[i] = 0; // only return the client once - } else if (stat == SnSR::LISTEN) { + } + else if (stat == SnSR::LISTEN) + { listening = true; - } else if (stat == SnSR::CLOSED) { + } + else if (stat == SnSR::CLOSED) + { server_port[i] = 0; } } } - if (!listening) begin(); + + if (!listening) + begin(); + return EthernetClient(sockindex); } @@ -172,9 +192,12 @@ EthernetServer::operator bool() #endif } - for (uint8_t i=0; i < maxindex; i++) { - if (server_port[i] == _port) { - if (Ethernet.socketStatus(i) == SnSR::LISTEN) { + for (uint8_t i=0; i < maxindex; i++) + { + if (server_port[i] == _port) + { + if (Ethernet.socketStatus(i) == SnSR::LISTEN) + { return true; // server is listening for incoming clients } } @@ -182,39 +205,6 @@ EthernetServer::operator bool() return false; } -#if 0 -void EthernetServer::statusreport() -{ - Serial.printf("EthernetServer, port=%d\n", _port); - for (uint8_t i=0; i < MAX_SOCK_NUM; i++) { - uint16_t port = server_port[i]; - uint8_t stat = Ethernet.socketStatus(i); - const char *name; - switch (stat) { - case 0x00: name = "CLOSED"; break; - case 0x13: name = "INIT"; break; - case 0x14: name = "LISTEN"; break; - case 0x15: name = "SYNSENT"; break; - case 0x16: name = "SYNRECV"; break; - case 0x17: name = "ESTABLISHED"; break; - case 0x18: name = "FIN_WAIT"; break; - case 0x1A: name = "CLOSING"; break; - case 0x1B: name = "TIME_WAIT"; break; - case 0x1C: name = "CLOSE_WAIT"; break; - case 0x1D: name = "LAST_ACK"; break; - case 0x22: name = "UDP"; break; - case 0x32: name = "IPRAW"; break; - case 0x42: name = "MACRAW"; break; - case 0x5F: name = "PPPOE"; break; - default: name = "???"; - } - int avail = Ethernet.socketRecvAvailable(i); - Serial.printf(" %d: port=%d, status=%s (0x%02X), avail=%d\n", - i, port, name, stat, avail); - } -} -#endif - size_t EthernetServer::write(uint8_t b) { return write(&b, 1); @@ -238,9 +228,13 @@ size_t EthernetServer::write(const uint8_t *buffer, size_t size) } available(); - for (uint8_t i=0; i < maxindex; i++) { - if (server_port[i] == _port) { - if (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) { + + for (uint8_t i=0; i < maxindex; i++) + { + if (server_port[i] == _port) + { + if (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) + { Ethernet.socketSend(i, buffer, size); } } diff --git a/LibraryPatches/Ethernet/src/utility/w5100.cpp b/LibraryPatches/Ethernet/src/utility/w5100.cpp index a5109b20..46eb27b4 100644 --- a/LibraryPatches/Ethernet/src/utility/w5100.cpp +++ b/LibraryPatches/Ethernet/src/utility/w5100.cpp @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.6 + Version: 1.0.8 Copyright 2018 Paul Stoffregen Copyright (c) 2010 by Cristian Maglie @@ -26,13 +26,16 @@ 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge - 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. *****************************************************************************************************************************/ #include #include "Ethernet.h" #include "w5100.h" +#define W5100_DEBUG 1 /***************************************************/ /** Default SS pin setting **/ @@ -42,18 +45,15 @@ // default SS pin for ethernet, use it. #if defined(PIN_SPI_SS_ETHERNET_LIB) - #define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB - //KH #warning w5100.cpp Use PIN_SPI_SS_ETHERNET_LIB defined, change SS_PIN_DEFAULT to PIN_SPI_SS_ETHERNET_LIB - // MKR boards default to pin 5 for MKR ETH // Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10 #elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300) -#define SS_PIN_DEFAULT 5 +#define SS_PIN_DEFAULT 5 //KH #warning w5100.cpp Use MKR, change SS_PIN_DEFAULT to 5 @@ -62,8 +62,8 @@ // SS is pin 53) and Arduino Leonardo (where SS is pin 17) // to work by default with Arduino Ethernet Shield R2 & R3. #elif defined(__AVR__) -#define SS_PIN_DEFAULT 10 +#define SS_PIN_DEFAULT 10 //KH #warning w5100.cpp Use __AVR__, change SS_PIN_DEFAULT to 10 @@ -72,7 +72,7 @@ #elif defined(PIN_SPI_SS) #if defined(__SAMD21G18A__) -//10 - 4 all not OK for Nano 33 IoT !!! +//10 - 2 (6 conflict) all not OK for Nano 33 IoT !!! SPI corrupted??? #warning w5100.cpp Use __SAMD21G18A__, change SS_PIN_DEFAULT to 10 #define SS_PIN_DEFAULT 10 #else @@ -88,13 +88,6 @@ //KH #warning w5100.cpp Use CORE_SS0_PIN defined, change SS_PIN_DEFAULT to CORE_SS0_PIN -//KH for Nano33 IoT -#elif defined(__SAMD21G18A__) -//10, 9 not OK -#warning w5100.cpp Use __SAMD21G18A__, change SS_PIN_DEFAULT to 8 -#define SS_PIN_DEFAULT 8 -/////// - //KH for ESP32 #elif defined(ESP32) //pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc. @@ -157,10 +150,9 @@ W5100Class W5100; #warning w5100.cpp Use __SAMD21G18A__ #endif - -uint8_t W5100Class::init(void) +// KH +uint8_t W5100Class::init(uint8_t socketNumbers, uint8_t new_ss_pin) { - static bool initialized = false; uint8_t i; if (initialized) return 1; @@ -175,20 +167,32 @@ uint8_t W5100Class::init(void) // reset time, this can be edited or removed. delay(560); + W5100Class::ss_pin = new_ss_pin; + +#if ( W5100_DEBUG > 0 ) //KH - Serial.print("w5100 init, using SS_PIN_DEFAULT = "); - Serial.println(SS_PIN_DEFAULT); + Serial.print("\nW5100 init, using SS_PIN_DEFAULT = "); + Serial.print(SS_PIN_DEFAULT); + Serial.print(", new ss_pin = "); + Serial.print(new_ss_pin); + Serial.print(", W5100Class::ss_pin = "); + Serial.println(W5100Class::ss_pin); +#endif SPI.begin(); + initSS(); resetSS(); + + // From #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) SPI.beginTransaction(SPI_ETHERNET_SETTINGS); // Attempt W5200 detection first, because W5200 does not properly // reset its SPI state when CS goes high (inactive). Communication // from detecting the other chips can leave the W5200 in a state // where it won't recover, unless given a reset pulse. - if (isW5200()) { + if (isW5200()) + { CH_BASE_MSB = 0x40; #ifdef ETHERNET_LARGE_BUFFERS #if MAX_SOCK_NUM <= 1 @@ -202,22 +206,27 @@ uint8_t W5100Class::init(void) #endif SMASK = SSIZE - 1; #endif - for (i=0; i> 10); writeSnTX_SIZE(i, SSIZE >> 10); } - for (; i<8; i++) { + for (; i<8; i++) + { writeSnRX_SIZE(i, 0); writeSnTX_SIZE(i, 0); } - - //Serial.print("W5100::init: W5200, SSIZE ="); - //Serial.println(SSIZE); + +#if ( W5100_DEBUG > 0 ) + Serial.print("W5100::init: W5200, SSIZE ="); + Serial.println(SSIZE); +#endif // Try W5500 next. Wiznet finally seems to have implemented // SPI well with this chip. It appears to be very resilient, // so try it after the fragile W5200 - } else if (isW5500()) { + } else if (isW5500()) + { CH_BASE_MSB = 0x10; #ifdef ETHERNET_LARGE_BUFFERS #if MAX_SOCK_NUM <= 1 @@ -230,25 +239,30 @@ uint8_t W5100Class::init(void) SSIZE = 2048; #endif SMASK = SSIZE - 1; - for (i=0; i> 10); writeSnTX_SIZE(i, SSIZE >> 10); } - for (; i<8; i++) { + for (; i<8; i++) + { writeSnRX_SIZE(i, 0); writeSnTX_SIZE(i, 0); } #endif +#if ( W5100_DEBUG > 0 ) Serial.print("W5100::init: W5500, SSIZE ="); Serial.println(SSIZE); +#endif // Try W5100 last. This simple chip uses fixed 4 byte frames // for every 8 bit access. Terribly inefficient, but so simple // it recovers from "hearing" unsuccessful W5100 or W5200 // communication. W5100 is also the only chip without a VERSIONR // register for identification, so we check this last. - } else if (isW5100()) { + } else if (isW5100()) + { CH_BASE_MSB = 0x04; #ifdef ETHERNET_LARGE_BUFFERS @@ -270,18 +284,26 @@ uint8_t W5100Class::init(void) writeRMSR(0x55); #endif +#if ( W5100_DEBUG > 0 ) Serial.print("W5100::init: W5100, SSIZE ="); Serial.println(SSIZE); +#endif // No hardware seems to be present. Or it could be a W5200 // that's heard other SPI communication if its chip select // pin wasn't high when a SD card or other SPI chip was used. - } else { - //Serial.println("no chip :-("); + } + else + { +#if ( W5100_DEBUG > 0 ) + Serial.println("no chip :-("); +#endif + chip = 0; SPI.endTransaction(); return 0; // no known chip is responding :-( } + SPI.endTransaction(); initialized = true; return 1; // successful init @@ -292,15 +314,25 @@ uint8_t W5100Class::softReset(void) { uint16_t count=0; - //Serial.println("Wiznet soft reset"); +#if ( W5100_DEBUG > 0 ) + Serial.println("Wiznet soft reset"); +#endif + // write to reset bit writeMR(0x80); // then wait for soft reset to complete - do { + do + { uint8_t mr = readMR(); - //Serial.print("mr="); - //Serial.println(mr, HEX); - if (mr == 0) return 1; + +#if ( W5100_DEBUG > 2 ) + Serial.print("mr="); + Serial.println(mr, HEX); +#endif + + if (mr == 0) + return 1; + delay(1); } while (++count < 20); return 0; @@ -309,53 +341,110 @@ uint8_t W5100Class::softReset(void) uint8_t W5100Class::isW5100(void) { chip = 51; - //Serial.println("w5100.cpp: detect W5100 chip"); - if (!softReset()) return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5100 chip"); +#endif + + if (!softReset()) + return 0; + writeMR(0x10); - if (readMR() != 0x10) return 0; + if (readMR() != 0x10) + return 0; + writeMR(0x12); - if (readMR() != 0x12) return 0; + if (readMR() != 0x12) + return 0; + writeMR(0x00); - if (readMR() != 0x00) return 0; - //Serial.println("chip is W5100"); + if (readMR() != 0x00) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5100"); +#endif + return 1; } uint8_t W5100Class::isW5200(void) { chip = 52; - //Serial.println("w5100.cpp: detect W5200 chip"); - if (!softReset()) return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5200 chip"); +#endif + + if (!softReset()) + return 0; + writeMR(0x08); - if (readMR() != 0x08) return 0; + if (readMR() != 0x08) + return 0; + writeMR(0x10); - if (readMR() != 0x10) return 0; + if (readMR() != 0x10) + return 0; + writeMR(0x00); - if (readMR() != 0x00) return 0; + if (readMR() != 0x00) + return 0; + int ver = readVERSIONR_W5200(); - //Serial.print("version="); - //Serial.println(ver); - if (ver != 3) return 0; - //Serial.println("chip is W5200"); + +#if ( W5100_DEBUG > 1 ) + Serial.print("version="); + Serial.println(ver); +#endif + + if (ver != 3) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5200"); +#endif + return 1; } uint8_t W5100Class::isW5500(void) { chip = 55; - //Serial.println("w5100.cpp: detect W5500 chip"); - if (!softReset()) return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5500 chip"); +#endif + + if (!softReset()) + return 0; + writeMR(0x08); - if (readMR() != 0x08) return 0; + if (readMR() != 0x08) + return 0; + writeMR(0x10); - if (readMR() != 0x10) return 0; + if (readMR() != 0x10) + return 0; + writeMR(0x00); - if (readMR() != 0x00) return 0; + if (readMR() != 0x00) + return 0; + int ver = readVERSIONR_W5500(); - //Serial.print("version="); - //Serial.println(ver); - if (ver != 4) return 0; - //Serial.println("chip is W5500"); + +#if ( W5100_DEBUG > 1 ) + Serial.print("version="); + Serial.println(ver); +#endif + + if (ver != 4) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5500"); +#endif + return 1; } @@ -363,20 +452,29 @@ W5100Linkstatus W5100Class::getLinkStatus() { uint8_t phystatus; - if (!init()) return UNKNOWN; - switch (chip) { + // KH + if (!initialized) return UNKNOWN; + + switch (chip) + { case 52: SPI.beginTransaction(SPI_ETHERNET_SETTINGS); phystatus = readPSTATUS_W5200(); SPI.endTransaction(); - if (phystatus & 0x20) return LINK_ON; + if (phystatus & 0x20) + return LINK_ON; + return LINK_OFF; + case 55: SPI.beginTransaction(SPI_ETHERNET_SETTINGS); phystatus = readPHYCFGR_W5500(); SPI.endTransaction(); - if (phystatus & 0x01) return LINK_ON; + if (phystatus & 0x01) + return LINK_ON; + return LINK_OFF; + default: return UNKNOWN; } @@ -386,8 +484,10 @@ uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len) { uint8_t cmd[8]; - if (chip == 51) { - for (uint16_t i=0; i> 8); @@ -396,35 +496,47 @@ uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len) SPI.transfer(buf[i]); resetSS(); } - } else if (chip == 52) { + } + else if (chip == 52) + { setSS(); cmd[0] = addr >> 8; cmd[1] = addr & 0xFF; cmd[2] = ((len >> 8) & 0x7F) | 0x80; cmd[3] = len & 0xFF; SPI.transfer(cmd, 4); + #ifdef SPI_HAS_TRANSFER_BUF SPI.transfer(buf, NULL, len); #else // TODO: copy 8 bytes at a time to cmd[] and block transfer - for (uint16_t i=0; i < len; i++) { + for (uint16_t i=0; i < len; i++) + { SPI.transfer(buf[i]); } #endif resetSS(); - } else { // chip == 55 + } + else + { + // chip == 55 setSS(); - if (addr < 0x100) { + if (addr < 0x100) + { // common registers 00nn cmd[0] = 0; cmd[1] = addr & 0xFF; cmd[2] = 0x04; - } else if (addr < 0x8000) { + } + else if (addr < 0x8000) + { // socket registers 10nn, 11nn, 12nn, 13nn, etc cmd[0] = 0; cmd[1] = addr & 0xFF; cmd[2] = ((addr >> 3) & 0xE0) | 0x0C; - } else if (addr < 0xC000) { + } + else if (addr < 0xC000) + { // transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc // 10## #nnn nnnn nnnn cmd[0] = addr >> 8; @@ -438,7 +550,9 @@ uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len) #else cmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers #endif - } else { + } + else + { // receive buffers cmd[0] = addr >> 8; cmd[1] = addr & 0xFF; @@ -452,18 +566,25 @@ uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len) cmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers #endif } - if (len <= 5) { - for (uint8_t i=0; i < len; i++) { + + if (len <= 5) + { + for (uint8_t i=0; i < len; i++) + { cmd[i + 3] = buf[i]; } + SPI.transfer(cmd, len + 3); - } else { + } + else + { SPI.transfer(cmd, 3); #ifdef SPI_HAS_TRANSFER_BUF SPI.transfer(buf, NULL, len); #else // TODO: copy 8 bytes at a time to cmd[] and block transfer - for (uint16_t i=0; i < len; i++) { + for (uint16_t i=0; i < len; i++) + { SPI.transfer(buf[i]); } #endif @@ -477,8 +598,10 @@ uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len) { uint8_t cmd[4]; - if (chip == 51) { - for (uint16_t i=0; i < len; i++) { + if (chip == 51) + { + for (uint16_t i=0; i < len; i++) + { setSS(); #if 1 SPI.transfer(0x0F); @@ -497,7 +620,9 @@ uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len) #endif resetSS(); } - } else if (chip == 52) { + } + else if (chip == 52) + { setSS(); cmd[0] = addr >> 8; cmd[1] = addr & 0xFF; @@ -507,19 +632,28 @@ uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len) memset(buf, 0, len); SPI.transfer(buf, len); resetSS(); - } else { // chip == 55 + } + else + { + // chip == 55 setSS(); - if (addr < 0x100) { + + if (addr < 0x100) + { // common registers 00nn cmd[0] = 0; cmd[1] = addr & 0xFF; cmd[2] = 0x00; - } else if (addr < 0x8000) { + } + else if (addr < 0x8000) + { // socket registers 10nn, 11nn, 12nn, 13nn, etc cmd[0] = 0; cmd[1] = addr & 0xFF; cmd[2] = ((addr >> 3) & 0xE0) | 0x08; - } else if (addr < 0xC000) { + } + else if (addr < 0xC000) + { // transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc // 10## #nnn nnnn nnnn cmd[0] = addr >> 8; @@ -533,7 +667,8 @@ uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len) #else cmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers #endif - } else { + } else + { // receive buffers cmd[0] = addr >> 8; cmd[1] = addr & 0xFF; diff --git a/LibraryPatches/Ethernet/src/utility/w5100.h b/LibraryPatches/Ethernet/src/utility/w5100.h new file mode 100644 index 00000000..ff168509 --- /dev/null +++ b/LibraryPatches/Ethernet/src/utility/w5100.h @@ -0,0 +1,626 @@ +/**************************************************************************************************************************** + w5100.h - Driver for W5x00 + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + Copyright (c) 2010 by Cristian Maglie + + This file is free software; you can redistribute it and/or modify + it under the terms of either the GNU General Public License version 2 + or the GNU Lesser General Public License version 2.1, both as + published by the Free Software Foundation. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +// w5100.h contains private W5x00 hardware "driver" level definitions +// which are not meant to be exposed to other libraries or Arduino users + +#ifndef W5100_H_INCLUDED +#define W5100_H_INCLUDED + +#include +#include + +#ifndef USE_W5500 +#define USE_W5500 false +#else +#define USE_W5500 true +#endif + +#if USE_W5500 + +// Safe for W5200 and W5500, but too fast for W5100 +// Uncomment this if you know you'll never need W5100 support. +// Higher SPI clock only results in faster transfer to hosts on a LAN +// or with very low packet latency. With ordinary internet latency, +// the TCP window size & packet loss determine your overall speed. +#warning Use 30MHz clock for W5200/W5500. Not for W5100 +#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE0) + +#else + +// Safe for all chips +#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) +#warning Use 14MHz clock for W5100/W5200/W5500. Slow. + +#endif + +// Require Ethernet.h, because we need MAX_SOCK_NUM +#ifndef ethernet_h_ +#error "Ethernet.h must be included before w5100.h" +#endif + +// Arduino 101's SPI can not run faster than 8 MHz. +#if defined(ARDUINO_ARCH_ARC32) +#undef SPI_ETHERNET_SETTINGS +#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0) +#endif + +// Arduino Zero can't use W5100-based shields faster than 8 MHz +// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848 +// W5500 does seem to work at 12 MHz. Delete this if only using W5500 +#if defined(__SAMD21G18A__) +#undef SPI_ETHERNET_SETTINGS +//#warning Use SAMD21 architecture SPISettings(8000000, MSBFIRST, SPI_MODE3) => IP OK +#warning Use SAMD21 architecture SPISettings(30000000, MSBFIRST, SPI_MODE3) => IP OK +// Still not working !!! Original SPI_MODE0 not OK at all +//#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE3) +#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE3) +#endif + +typedef uint8_t SOCKET; + +class SnMR { +public: + static const uint8_t CLOSE = 0x00; + static const uint8_t TCP = 0x21; + static const uint8_t UDP = 0x02; + static const uint8_t IPRAW = 0x03; + static const uint8_t MACRAW = 0x04; + static const uint8_t PPPOE = 0x05; + static const uint8_t ND = 0x20; + static const uint8_t MULTI = 0x80; +}; + +enum SockCMD { + Sock_OPEN = 0x01, + Sock_LISTEN = 0x02, + Sock_CONNECT = 0x04, + Sock_DISCON = 0x08, + Sock_CLOSE = 0x10, + Sock_SEND = 0x20, + Sock_SEND_MAC = 0x21, + Sock_SEND_KEEP = 0x22, + Sock_RECV = 0x40 +}; + +class SnIR { +public: + static const uint8_t SEND_OK = 0x10; + static const uint8_t TIMEOUT = 0x08; + static const uint8_t RECV = 0x04; + static const uint8_t DISCON = 0x02; + static const uint8_t CON = 0x01; +}; + +class SnSR { +public: + static const uint8_t CLOSED = 0x00; + static const uint8_t INIT = 0x13; + static const uint8_t LISTEN = 0x14; + static const uint8_t SYNSENT = 0x15; + static const uint8_t SYNRECV = 0x16; + static const uint8_t ESTABLISHED = 0x17; + static const uint8_t FIN_WAIT = 0x18; + static const uint8_t CLOSING = 0x1A; + static const uint8_t TIME_WAIT = 0x1B; + static const uint8_t CLOSE_WAIT = 0x1C; + static const uint8_t LAST_ACK = 0x1D; + static const uint8_t UDP = 0x22; + static const uint8_t IPRAW = 0x32; + static const uint8_t MACRAW = 0x42; + static const uint8_t PPPOE = 0x5F; +}; + +class IPPROTO { +public: + static const uint8_t IP = 0; + static const uint8_t ICMP = 1; + static const uint8_t IGMP = 2; + static const uint8_t GGP = 3; + static const uint8_t TCP = 6; + static const uint8_t PUP = 12; + static const uint8_t UDP = 17; + static const uint8_t IDP = 22; + static const uint8_t ND = 77; + static const uint8_t RAW = 255; +}; + +enum W5100Linkstatus { + UNKNOWN, + LINK_ON, + LINK_OFF +}; + +class W5100Class { + +public: + // KH + uint8_t init(uint8_t socketNumbers = MAX_SOCK_NUM, uint8_t new_ss_pin = 10); + + inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); } + inline void getGatewayIp(uint8_t * addr) { readGAR(addr); } + + inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); } + inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); } + + inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); } + inline void getMACAddress(uint8_t * addr) { readSHAR(addr); } + + inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); } + inline void getIPAddress(uint8_t * addr) { readSIPR(addr); } + + inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); } + inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); } + + static void execCmdSn(SOCKET s, SockCMD _cmd); + + + // W5100 Registers + // --------------- +//private: +public: + static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len); + + static uint8_t write(uint16_t addr, uint8_t data) + { + return write(addr, &data, 1); + } + + static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len); + + static uint8_t read(uint16_t addr) + { + uint8_t data; + read(addr, &data, 1); + return data; + } + +#define __GP_REGISTER8(name, address) \ + static inline void write##name(uint8_t _data) { \ + write(address, _data); \ + } \ + static inline uint8_t read##name() { \ + return read(address); \ + } +#define __GP_REGISTER16(name, address) \ + static void write##name(uint16_t _data) { \ + uint8_t buf[2]; \ + buf[0] = _data >> 8; \ + buf[1] = _data & 0xFF; \ + write(address, buf, 2); \ + } \ + static uint16_t read##name() { \ + uint8_t buf[2]; \ + read(address, buf, 2); \ + return (buf[0] << 8) | buf[1]; \ + } +#define __GP_REGISTER_N(name, address, size) \ + static uint16_t write##name(const uint8_t *_buff) { \ + return write(address, _buff, size); \ + } \ + static uint16_t read##name(uint8_t *_buff) { \ + return read(address, _buff, size); \ + } + + W5100Linkstatus getLinkStatus(); + +public: + __GP_REGISTER8 (MR, 0x0000); // Mode + __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address + __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address + __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address + __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address + __GP_REGISTER8 (IR, 0x0015); // Interrupt + __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask + __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) + __GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only) + __GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only) + __GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status + __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx + + +#undef __GP_REGISTER8 +#undef __GP_REGISTER16 +#undef __GP_REGISTER_N + + // W5100 Socket registers + // ---------------------- +private: + static uint16_t CH_BASE(void) { + //if (chip == 55) return 0x1000; + //if (chip == 52) return 0x4000; + //return 0x0400; + return CH_BASE_MSB << 8; + } + static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR + static const uint16_t CH_SIZE = 0x0100; + + static inline uint8_t readSn(SOCKET s, uint16_t addr) + { + return read(CH_BASE() + s * CH_SIZE + addr); + } + static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data) + { + return write(CH_BASE() + s * CH_SIZE + addr, data); + } + static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) + { + return read(CH_BASE() + s * CH_SIZE + addr, buf, len); + } + static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) + { + return write(CH_BASE() + s * CH_SIZE + addr, buf, len); + } + +#define __SOCKET_REGISTER8(name, address) \ + static inline void write##name(SOCKET _s, uint8_t _data) { \ + writeSn(_s, address, _data); \ + } \ + static inline uint8_t read##name(SOCKET _s) { \ + return readSn(_s, address); \ + } +#define __SOCKET_REGISTER16(name, address) \ + static void write##name(SOCKET _s, uint16_t _data) { \ + uint8_t buf[2]; \ + buf[0] = _data >> 8; \ + buf[1] = _data & 0xFF; \ + writeSn(_s, address, buf, 2); \ + } \ + static uint16_t read##name(SOCKET _s) { \ + uint8_t buf[2]; \ + readSn(_s, address, buf, 2); \ + return (buf[0] << 8) | buf[1]; \ + } +#define __SOCKET_REGISTER_N(name, address, size) \ + static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \ + return writeSn(_s, address, _buff, size); \ + } \ + static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \ + return readSn(_s, address, _buff, size); \ + } + +public: + __SOCKET_REGISTER8(SnMR, 0x0000) // Mode + __SOCKET_REGISTER8(SnCR, 0x0001) // Command + __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt + __SOCKET_REGISTER8(SnSR, 0x0003) // Status + __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port + __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr + __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr + __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port + __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size + __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode + __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS + __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL + __SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only) + __SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only) + __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size + __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer + __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer + __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size + __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer + __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?) + +#undef __SOCKET_REGISTER8 +#undef __SOCKET_REGISTER16 +#undef __SOCKET_REGISTER_N + + +private: + // KH + bool initialized = false; + static uint8_t chip; + static uint8_t ss_pin; + + static uint8_t isW5100(void); + static uint8_t isW5200(void); + static uint8_t isW5500(void); + +public: + // KH + static uint8_t softReset(void); + static uint8_t getChip(void) { return chip; } +#ifdef ETHERNET_LARGE_BUFFERS + static uint16_t SSIZE; + static uint16_t SMASK; +#else + static const uint16_t SSIZE = 2048; + static const uint16_t SMASK = 0x07FF; +#endif + static uint16_t SBASE(uint8_t socknum) + { + if (chip == 51) + { + return socknum * SSIZE + 0x4000; + } + else + { + return socknum * SSIZE + 0x8000; + } + } + + static uint16_t RBASE(uint8_t socknum) + { + if (chip == 51) { + return socknum * SSIZE + 0x6000; + } + else + { + return socknum * SSIZE + 0xC000; + } + } + + static bool hasOffsetAddressMapping(void) + { + if (chip == 55) + return true; + + return false; + } + + static void setSS(uint8_t pin) { ss_pin = pin; } + +private: +#if defined(__AVR__) + +#warning Use AVR architecture + + static volatile uint8_t *ss_pin_reg; + static uint8_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg) &= ~ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg) |= ss_pin_mask; + } +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__) + +#warning Use MK architecture + + static volatile uint8_t *ss_pin_reg; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+256) = 1; + } + + inline static void resetSS() + { + *(ss_pin_reg+128) = 1; + } +#elif defined(__IMXRT1062__) + +#warning Use Teensy architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+34) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+33) = ss_pin_mask; + } +#elif defined(__MKL26Z64__) + static volatile uint8_t *ss_pin_reg; + static uint8_t ss_pin_mask; + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+8) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+4) = ss_pin_mask; + } +#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__) + +#warning Use SAM3 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+13) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+12) = ss_pin_mask; + } +#elif defined(__PIC32MX__) + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+8+1) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+8+2) = ss_pin_mask; + } + +#elif defined(ARDUINO_ARCH_ESP8266) + +#warning Use ARDUINO_ARCH_ESP8266 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = (volatile uint32_t*)GPO; + ss_pin_mask = 1 << ss_pin; + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + GPOC = ss_pin_mask; + } + + inline static void resetSS() + { + GPOS = ss_pin_mask; + } + +#elif defined(__SAMD21G18A__) + +#warning Use SAMD21 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+5) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+6) = ss_pin_mask; + } +#else + +#warning Use Default architecture + + inline static void initSS() + { + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + digitalWrite(ss_pin, LOW); + } + + inline static void resetSS() + { + digitalWrite(ss_pin, HIGH); + } +#endif +}; + +extern W5100Class W5100; + +#endif + +#ifndef UTIL_H +#define UTIL_H + +#ifndef htons +#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) ) +#endif + +#ifndef ntohs +#define ntohs(x) htons(x) +#endif + +#ifndef htonl +#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ + ((x)<< 8 & 0x00FF0000UL) | \ + ((x)>> 8 & 0x0000FF00UL) | \ + ((x)>>24 & 0x000000FFUL) ) +#endif + +#ifndef ntohl +#define ntohl(x) htonl(x) +#endif + +#endif //W5100_H_INCLUDED diff --git a/LibraryPatches/EthernetLarge/src/EthernetLarge.cpp b/LibraryPatches/EthernetLarge/src/EthernetLarge.cpp new file mode 100644 index 00000000..84014f6e --- /dev/null +++ b/LibraryPatches/EthernetLarge/src/EthernetLarge.cpp @@ -0,0 +1,304 @@ +/**************************************************************************************************************************** + EthernetLarge.cpp + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +#include +#include "EthernetLarge.h" +#include "utility/w5100.h" +#include "Dhcp.h" + +IPAddress EthernetClass::_dnsServerAddress; +DhcpClass* EthernetClass::_dhcp = NULL; + +// KH +void EthernetClass::setRstPin(uint8_t pinRST) +{ + _pinRST = pinRST; + pinMode(_pinRST, OUTPUT); + digitalWrite(_pinRST, HIGH); +} +void EthernetClass::setCsPin(uint8_t pinCS) +{ + _pinCS = pinCS; + Serial.print("Input pinCS = "); + Serial.println(pinCS); + Serial.print("_pinCS = "); + Serial.println(_pinCS); +} + +void EthernetClass::initMaxSockNum(uint8_t maxSockNum) +{ + _maxSockNum = maxSockNum; +} + +uint8_t EthernetClass::softreset() +{ + return W5100.softReset(); +} + +void EthernetClass::hardreset() +{ + if(_pinRST != 0) + { + digitalWrite(_pinRST, LOW); + delay(1); + digitalWrite(_pinRST, HIGH); + delay(150); + } +} + +int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +{ + static DhcpClass s_dhcp; + _dhcp = &s_dhcp; + + // Initialise the basic info + //if (W5100.init() == 0) return 0; + // KH + if (W5100.init(MAX_SOCK_NUM, _pinCS) == 0) + return 0; + + + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac); + W5100.setIPAddress(IPAddress(0,0,0,0).raw_address()); + SPI.endTransaction(); + + // Now try to get our config info from a DHCP server + int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout); + if (ret == 1) { + // We've successfully found a DHCP server and got our configuration + // info, so set things accordingly + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); + W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); + W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); + SPI.endTransaction(); + _dnsServerAddress = _dhcp->getDnsServerIp(); + socketPortRand(micros()); + } + return ret; +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip) +{ + // Assume the DNS server will be the machine on the same network as the local IP + // but with last octet being '1' + IPAddress dns = ip; + dns[3] = 1; + begin(mac, ip, dns); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns) +{ + // Assume the gateway will be the machine on the same network as the local IP + // but with last octet being '1' + IPAddress gateway = ip; + gateway[3] = 1; + begin(mac, ip, dns, gateway); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway) +{ + IPAddress subnet(255, 255, 255, 0); + begin(mac, ip, dns, gateway, subnet); +} + +void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) +{ + if (W5100.init() == 0) return; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac); +#ifdef ESP8266 + W5100.setIPAddress(&ip[0]); + W5100.setGatewayIp(&gateway[0]); + W5100.setSubnetMask(&subnet[0]); +#elif ARDUINO > 106 || TEENSYDUINO > 121 + W5100.setIPAddress(ip._address.bytes); + W5100.setGatewayIp(gateway._address.bytes); + W5100.setSubnetMask(subnet._address.bytes); +#else + W5100.setIPAddress(ip._address); + W5100.setGatewayIp(gateway._address); + W5100.setSubnetMask(subnet._address); +#endif + SPI.endTransaction(); + _dnsServerAddress = dns; +} + +void EthernetClass::init(uint8_t sspin) +{ + W5100.setSS(sspin); +} + +EthernetLinkStatus EthernetClass::linkStatus() +{ + switch (W5100.getLinkStatus()) { + case UNKNOWN: return Unknown; + case LINK_ON: return LinkON; + case LINK_OFF: return LinkOFF; + default: return Unknown; + } +} + +EthernetHardwareStatus EthernetClass::hardwareStatus() +{ + switch (W5100.getChip()) { + case 51: return EthernetW5100; + case 52: return EthernetW5200; + case 55: return EthernetW5500; + default: return EthernetNoHardware; + } +} + +int EthernetClass::maintain() +{ + int rc = DHCP_CHECK_NONE; + if (_dhcp != NULL) { + // we have a pointer to dhcp, use it + rc = _dhcp->checkLease(); + switch (rc) { + case DHCP_CHECK_NONE: + //nothing done + break; + case DHCP_CHECK_RENEW_OK: + case DHCP_CHECK_REBIND_OK: + //we might have got a new IP. + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); + W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); + W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); + SPI.endTransaction(); + _dnsServerAddress = _dhcp->getDnsServerIp(); + break; + default: + //this is actually an error, it will retry though + break; + } + } + return rc; +} + + +void EthernetClass::MACAddress(uint8_t *mac_address) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getMACAddress(mac_address); + SPI.endTransaction(); +} + +IPAddress EthernetClass::localIP() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getIPAddress(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +IPAddress EthernetClass::subnetMask() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getSubnetMask(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +IPAddress EthernetClass::gatewayIP() +{ + IPAddress ret; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.getGatewayIp(ret.raw_address()); + SPI.endTransaction(); + return ret; +} + +void EthernetClass::setMACAddress(const uint8_t *mac_address) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setMACAddress(mac_address); + SPI.endTransaction(); +} + +void EthernetClass::setLocalIP(const IPAddress local_ip) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = local_ip; + W5100.setIPAddress(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setSubnetMask(const IPAddress subnet) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = subnet; + W5100.setSubnetMask(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setGatewayIP(const IPAddress gateway) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + IPAddress ip = gateway; + W5100.setGatewayIp(ip.raw_address()); + SPI.endTransaction(); +} + +void EthernetClass::setRetransmissionTimeout(uint16_t milliseconds) +{ + if (milliseconds > 6553) milliseconds = 6553; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setRetransmissionTime(milliseconds * 10); + SPI.endTransaction(); +} + +void EthernetClass::setRetransmissionCount(uint8_t num) +{ + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + W5100.setRetransmissionCount(num); + SPI.endTransaction(); +} + + +EthernetClass Ethernet; diff --git a/LibraryPatches/EthernetLarge/src/EthernetLarge.h b/LibraryPatches/EthernetLarge/src/EthernetLarge.h new file mode 100644 index 00000000..5b875d25 --- /dev/null +++ b/LibraryPatches/EthernetLarge/src/EthernetLarge.h @@ -0,0 +1,361 @@ +/**************************************************************************************************************************** + EthernetLarge.h + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +#ifndef ethernet_h_ +#define ethernet_h_ + +// All symbols exposed to Arduino sketches are contained in this header file +// +// Older versions had much of this stuff in EthernetClient.h, EthernetServer.h, +// and socket.h. Including headers in different order could cause trouble, so +// these "friend" classes are now defined in the same header file. socket.h +// was removed to avoid possible conflict with the C library header files. + + +// Configure the maximum number of sockets to support. W5100 chips can have +// up to 4 sockets. W5200 & W5500 can have up to 8 sockets. Several bytes +// of RAM are used for each socket. Reducing the maximum can save RAM, but +// you are limited to fewer simultaneous connections. +#define MAX_SOCK_NUM 2 + +// By default, each socket uses 2K buffers inside the Wiznet chip. If +// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting +// this will use larger buffers within the Wiznet chip. Large buffers +// can really help with UDP protocols like Artnet. In theory larger +// buffers should allow faster TCP over high-latency links, but this +// does not always seem to work in practice (maybe Wiznet bugs?) +#define ETHERNET_LARGE_BUFFERS + + +#include +#include "Client.h" +#include "Server.h" +#include "Udp.h" + +enum EthernetLinkStatus { + Unknown, + LinkON, + LinkOFF +}; + +enum EthernetHardwareStatus { + EthernetNoHardware, + EthernetW5100, + EthernetW5200, + EthernetW5500 +}; + +class EthernetUDP; +class EthernetClient; +class EthernetServer; +class DhcpClass; + +class EthernetClass { +private: + static IPAddress _dnsServerAddress; + static DhcpClass* _dhcp; +public: + // KH + uint8_t _maxSockNum; + uint8_t _pinCS; + uint8_t _pinRST; + + void setRstPin(uint8_t pinRST = 9); // for WIZ550io or USR-ES1, must set befor Ethernet.begin + void setCsPin(uint8_t pinCS = 10); // must set befor Ethernet.begin + + // Initialize with less sockets but more RX/TX Buffer + // maxSockNum = 1 Socket 0 -> RX/TX Buffer 16k + // maxSockNum = 2 Socket 0, 1 -> RX/TX Buffer 8k + // maxSockNum = 4 Socket 0...3 -> RX/TX Buffer 4k + // maxSockNum = 8 (Standard) all sockets -> RX/TX Buffer 2k + // be carefull of the MAX_SOCK_NUM, because in the moment it can't dynamicly changed + void initMaxSockNum(uint8_t maxSockNum = 8); + + uint8_t softreset(); // can set only after Ethernet.begin + void hardreset(); // You need to set the Rst pin + + // Initialise the Ethernet shield to use the provided MAC address and + // gain the rest of the configuration through DHCP. + // Returns 0 if the DHCP configuration failed, and 1 if it succeeded + int begin(uint8_t *mac, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int maintain(); + EthernetLinkStatus linkStatus(); + EthernetHardwareStatus hardwareStatus(); + + // Manaul configuration + void begin(uint8_t *mac, IPAddress ip); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); + void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); + void init(uint8_t sspin = 10); + + void MACAddress(uint8_t *mac_address); + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsServerIP() { return _dnsServerAddress; } + + void setMACAddress(const uint8_t *mac_address); + void setLocalIP(const IPAddress local_ip); + void setSubnetMask(const IPAddress subnet); + void setGatewayIP(const IPAddress gateway); + void setDnsServerIP(const IPAddress dns_server) { _dnsServerAddress = dns_server; } + void setRetransmissionTimeout(uint16_t milliseconds); + void setRetransmissionCount(uint8_t num); + + friend class EthernetClient; + friend class EthernetServer; + friend class EthernetUDP; +private: + // Opens a socket(TCP or UDP or IP_RAW mode) + uint8_t socketBegin(uint8_t protocol, uint16_t port); + uint8_t socketBeginMulticast(uint8_t protocol, IPAddress ip,uint16_t port); + uint8_t socketStatus(uint8_t s); + // Close socket + void socketClose(uint8_t s); + // Establish TCP connection (Active connection) + void socketConnect(uint8_t s, uint8_t * addr, uint16_t port); + // disconnect the connection + void socketDisconnect(uint8_t s); + // Establish TCP connection (Passive connection) + uint8_t socketListen(uint8_t s); + // Send data (TCP) + uint16_t socketSend(uint8_t s, const uint8_t * buf, uint16_t len); + uint16_t socketSendAvailable(uint8_t s); + // Receive data (TCP) + int socketRecv(uint8_t s, uint8_t * buf, int16_t len); + uint16_t socketRecvAvailable(uint8_t s); + uint8_t socketPeek(uint8_t s); + // sets up a UDP datagram, the data for which will be provided by one + // or more calls to bufferData and then finally sent with sendUDP. + // return true if the datagram was successfully set up, or false if there was an error + bool socketStartUDP(uint8_t s, uint8_t* addr, uint16_t port); + // copy up to len bytes of data from buf into a UDP datagram to be + // sent later by sendUDP. Allows datagrams to be built up from a series of bufferData calls. + // return Number of bytes successfully buffered + uint16_t socketBufferData(uint8_t s, uint16_t offset, const uint8_t* buf, uint16_t len); + // Send a UDP datagram built up from a sequence of startUDP followed by one or more + // calls to bufferData. + // return true if the datagram was successfully sent, or false if there was an error + bool socketSendUDP(uint8_t s); + // Initialize the "random" source port number + void socketPortRand(uint16_t n); +}; + +extern EthernetClass Ethernet; + + +#define UDP_TX_PACKET_MAX_SIZE 24 + +class EthernetUDP : public UDP { +private: + uint16_t _port; // local port to listen on + IPAddress _remoteIP; // remote IP address for the incoming packet whilst it's being processed + uint16_t _remotePort; // remote port for the incoming packet whilst it's being processed + uint16_t _offset; // offset into the packet being sent + +protected: + uint8_t sockindex; + uint16_t _remaining; // remaining bytes of incoming packet yet to be processed + +public: + EthernetUDP() : sockindex(MAX_SOCK_NUM) {} // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port); + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port); + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket(); + // Write a single byte into the packet + virtual size_t write(uint8_t); + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size); + + using Print::write; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket(); + // Number of bytes remaining in the current packet + virtual int available(); + // Read a single byte from the current packet + virtual int read(); + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len); + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek(); + virtual void flush(); // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP() { return _remoteIP; }; + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort() { return _remotePort; }; + virtual uint16_t localPort() { return _port; } +}; + + + + +class EthernetClient : public Client { +public: + EthernetClient() : sockindex(MAX_SOCK_NUM), _timeout(1000) { } + EthernetClient(uint8_t s) : sockindex(s), _timeout(1000) { } + + uint8_t status(); + virtual int connect(IPAddress ip, uint16_t port); + virtual int connect(const char *host, uint16_t port); + virtual int availableForWrite(void); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual int available(); + virtual int read(); + virtual int read(uint8_t *buf, size_t size); + virtual int peek(); + virtual void flush(); + virtual void stop(); + virtual uint8_t connected(); + virtual operator bool() { return sockindex < MAX_SOCK_NUM; } + virtual bool operator==(const bool value) { return bool() == value; } + virtual bool operator!=(const bool value) { return bool() != value; } + virtual bool operator==(const EthernetClient&); + virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); } + uint8_t getSocketNumber() const { return sockindex; } + virtual uint16_t localPort(); + virtual IPAddress remoteIP(); + virtual uint16_t remotePort(); + virtual void setConnectionTimeout(uint16_t timeout) { _timeout = timeout; } + + friend class EthernetServer; + + using Print::write; + +private: + uint8_t sockindex; // MAX_SOCK_NUM means client not in use + uint16_t _timeout; +}; + + +class EthernetServer : public Server { +private: + uint16_t _port; +public: + EthernetServer(uint16_t port) : _port(port) { } + EthernetClient available(); + EthernetClient accept(); + virtual void begin(); + virtual size_t write(uint8_t); + virtual size_t write(const uint8_t *buf, size_t size); + virtual operator bool(); + using Print::write; + //void statusreport(); + + // TODO: make private when socket allocation moves to EthernetClass + static uint16_t server_port[MAX_SOCK_NUM]; +}; + + +class DhcpClass { +private: + uint32_t _dhcpInitialTransactionId; + uint32_t _dhcpTransactionId; + uint8_t _dhcpMacAddr[6]; +#ifdef __arm__ + uint8_t _dhcpLocalIp[4] __attribute__((aligned(4))); + uint8_t _dhcpSubnetMask[4] __attribute__((aligned(4))); + uint8_t _dhcpGatewayIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDhcpServerIp[4] __attribute__((aligned(4))); + uint8_t _dhcpDnsServerIp[4] __attribute__((aligned(4))); +#else + uint8_t _dhcpLocalIp[4]; + uint8_t _dhcpSubnetMask[4]; + uint8_t _dhcpGatewayIp[4]; + uint8_t _dhcpDhcpServerIp[4]; + uint8_t _dhcpDnsServerIp[4]; +#endif + uint32_t _dhcpLeaseTime; + uint32_t _dhcpT1, _dhcpT2; + uint32_t _renewInSec; + uint32_t _rebindInSec; + unsigned long _timeout; + unsigned long _responseTimeout; + unsigned long _lastCheckLeaseMillis; + uint8_t _dhcp_state; + EthernetUDP _dhcpUdpSocket; + + int request_DHCP_lease(); + void reset_DHCP_lease(); + void presend_DHCP(); + void send_DHCP_MESSAGE(uint8_t, uint16_t); + void printByte(char *, uint8_t); + + uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId); +public: + IPAddress getLocalIp(); + IPAddress getSubnetMask(); + IPAddress getGatewayIp(); + IPAddress getDhcpServerIp(); + IPAddress getDnsServerIp(); + + int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int checkLease(); +}; + + + + + +#endif diff --git a/LibraryPatches/EthernetLarge/src/EthernetServer.cpp b/LibraryPatches/EthernetLarge/src/EthernetServer.cpp new file mode 100644 index 00000000..63ad3e7f --- /dev/null +++ b/LibraryPatches/EthernetLarge/src/EthernetServer.cpp @@ -0,0 +1,203 @@ +/**************************************************************************************************************************** + EthernetServer.cpp + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + + Permission is hereby granted, free of charge, to any person obtaining a copy of this + software and associated documentation files (the "Software"), to deal in the Software + without restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +#include +#include "EthernetLarge.h" +#include "utility/w5100.h" + +uint16_t EthernetServer::server_port[MAX_SOCK_NUM]; + + +void EthernetServer::begin() +{ + uint8_t sockindex = Ethernet.socketBegin(SnMR::TCP, _port); + if (sockindex < MAX_SOCK_NUM) { + if (Ethernet.socketListen(sockindex)) { + server_port[sockindex] = _port; + } else { + Ethernet.socketDisconnect(sockindex); + } + } +} + +EthernetClient EthernetServer::available() +{ + bool listening = false; + uint8_t sockindex = MAX_SOCK_NUM; + uint8_t chip, maxindex=MAX_SOCK_NUM; + + chip = W5100.getChip(); + if (!chip) return EthernetClient(MAX_SOCK_NUM); +#if MAX_SOCK_NUM > 4 + if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets +#endif + for (uint8_t i=0; i < maxindex; i++) { + if (server_port[i] == _port) { + uint8_t stat = Ethernet.socketStatus(i); + if (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT) { + if (Ethernet.socketRecvAvailable(i) > 0) { + sockindex = i; + } else { + // remote host closed connection, our end still open + if (stat == SnSR::CLOSE_WAIT) { + Ethernet.socketDisconnect(i); + // status becomes LAST_ACK for short time + } + } + } else if (stat == SnSR::LISTEN) { + listening = true; + } else if (stat == SnSR::CLOSED) { + server_port[i] = 0; + } + } + } + if (!listening) begin(); + return EthernetClient(sockindex); +} + +EthernetClient EthernetServer::accept() +{ + bool listening = false; + uint8_t sockindex = MAX_SOCK_NUM; + uint8_t chip, maxindex=MAX_SOCK_NUM; + + chip = W5100.getChip(); + if (!chip) return EthernetClient(MAX_SOCK_NUM); +#if MAX_SOCK_NUM > 4 + if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets +#endif + for (uint8_t i=0; i < maxindex; i++) { + if (server_port[i] == _port) { + uint8_t stat = Ethernet.socketStatus(i); + if (sockindex == MAX_SOCK_NUM && + (stat == SnSR::ESTABLISHED || stat == SnSR::CLOSE_WAIT)) { + // Return the connected client even if no data received. + // Some protocols like FTP expect the server to send the + // first data. + sockindex = i; + server_port[i] = 0; // only return the client once + } else if (stat == SnSR::LISTEN) { + listening = true; + } else if (stat == SnSR::CLOSED) { + server_port[i] = 0; + } + } + } + if (!listening) begin(); + return EthernetClient(sockindex); +} + +EthernetServer::operator bool() +{ + uint8_t maxindex=MAX_SOCK_NUM; +#if MAX_SOCK_NUM > 4 + if (W5100.getChip() == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets +#endif + for (uint8_t i=0; i < maxindex; i++) { + if (server_port[i] == _port) { + if (Ethernet.socketStatus(i) == SnSR::LISTEN) { + return true; // server is listening for incoming clients + } + } + } + return false; +} + +#if 0 +void EthernetServer::statusreport() +{ + Serial.printf("EthernetServer, port=%d\n", _port); + for (uint8_t i=0; i < MAX_SOCK_NUM; i++) { + uint16_t port = server_port[i]; + uint8_t stat = Ethernet.socketStatus(i); + const char *name; + switch (stat) { + case 0x00: name = "CLOSED"; break; + case 0x13: name = "INIT"; break; + case 0x14: name = "LISTEN"; break; + case 0x15: name = "SYNSENT"; break; + case 0x16: name = "SYNRECV"; break; + case 0x17: name = "ESTABLISHED"; break; + case 0x18: name = "FIN_WAIT"; break; + case 0x1A: name = "CLOSING"; break; + case 0x1B: name = "TIME_WAIT"; break; + case 0x1C: name = "CLOSE_WAIT"; break; + case 0x1D: name = "LAST_ACK"; break; + case 0x22: name = "UDP"; break; + case 0x32: name = "IPRAW"; break; + case 0x42: name = "MACRAW"; break; + case 0x5F: name = "PPPOE"; break; + default: name = "???"; + } + int avail = Ethernet.socketRecvAvailable(i); + Serial.printf(" %d: port=%d, status=%s (0x%02X), avail=%d\n", + i, port, name, stat, avail); + } +} +#endif + +size_t EthernetServer::write(uint8_t b) +{ + return write(&b, 1); +} + +size_t EthernetServer::write(const uint8_t *buffer, size_t size) +{ + uint8_t chip, maxindex=MAX_SOCK_NUM; + + chip = W5100.getChip(); + if (!chip) return 0; +#if MAX_SOCK_NUM > 4 + if (chip == 51) maxindex = 4; // W5100 chip never supports more than 4 sockets +#endif + available(); + for (uint8_t i=0; i < maxindex; i++) { + if (server_port[i] == _port) { + if (Ethernet.socketStatus(i) == SnSR::ESTABLISHED) { + Ethernet.socketSend(i, buffer, size); + } + } + } + return size; +} diff --git a/LibraryPatches/EthernetLarge/src/utility/w5100.cpp b/LibraryPatches/EthernetLarge/src/utility/w5100.cpp new file mode 100644 index 00000000..f65565d2 --- /dev/null +++ b/LibraryPatches/EthernetLarge/src/utility/w5100.cpp @@ -0,0 +1,702 @@ +/**************************************************************************************************************************** + w5100.cpp - Driver for W5x00 + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + Copyright (c) 2010 by Cristian Maglie + + This file is free software; you can redistribute it and/or modify + it under the terms of either the GNU General Public License version 2 + or the GNU Lesser General Public License version 2.1, both as + published by the Free Software Foundation. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +#include +#include "EthernetLarge.h" +#include "w5100.h" + +#define W5100_DEBUG 1 + +/***************************************************/ +/** Default SS pin setting **/ +/***************************************************/ + +// If variant.h or other headers specifically define the +// default SS pin for ethernet, use it. +#if defined(PIN_SPI_SS_ETHERNET_LIB) + +#define SS_PIN_DEFAULT PIN_SPI_SS_ETHERNET_LIB +//KH +#warning w5100.cpp Use PIN_SPI_SS_ETHERNET_LIB defined, change SS_PIN_DEFAULT to PIN_SPI_SS_ETHERNET_LIB + +// MKR boards default to pin 5 for MKR ETH +// Pins 8-10 are MOSI/SCK/MISO on MRK, so don't use pin 10 +#elif defined(USE_ARDUINO_MKR_PIN_LAYOUT) || defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRWAN1300) + +#define SS_PIN_DEFAULT 5 +//KH +#warning w5100.cpp Use MKR, change SS_PIN_DEFAULT to 5 + +// For boards using AVR, assume shields with SS on pin 10 +// will be used. This allows for Arduino Mega (where +// SS is pin 53) and Arduino Leonardo (where SS is pin 17) +// to work by default with Arduino Ethernet Shield R2 & R3. +#elif defined(__AVR__) + +#define SS_PIN_DEFAULT 10 +//KH +#warning w5100.cpp Use __AVR__, change SS_PIN_DEFAULT to 10 + +// If variant.h or other headers define these names +// use them if none of the other cases match +#elif defined(PIN_SPI_SS) + +#if defined(__SAMD21G18A__) +//10 - 2 (6 conflict) all not OK for Nano 33 IoT !!! SPI corrupted??? +#warning w5100.cpp Use __SAMD21G18A__, change SS_PIN_DEFAULT to 10 +#define SS_PIN_DEFAULT 10 +#else +#define SS_PIN_DEFAULT PIN_SPI_SS + +//KH +#warning w5100.cpp Use PIN_SPI_SS defined, change SS_PIN_DEFAULT to PIN_SPI_SS +#endif + +#elif defined(CORE_SS0_PIN) +#define SS_PIN_DEFAULT CORE_SS0_PIN + +//KH +#warning w5100.cpp Use CORE_SS0_PIN defined, change SS_PIN_DEFAULT to CORE_SS0_PIN + +//KH for ESP32 +#elif defined(ESP32) +//pin SS already defined in ESP32 as pin 5, don't use this as conflict with SPIFFS, EEPROM, etc. +// Use in GPIO13 +#warning w5100.cpp Use ESP32, change SS_PIN_DEFAULT to GPIO13, MOSI(23), MISO(19), SCK(18) +#define SS_PIN_DEFAULT 13 //SS +/////// + +//KH for ESP8266 +#elif defined(ESP8266) +//pin SS already defined in ESP8266 as pin 15. Conflict => Move to pin 5 (D1) +#warning w5100.cpp Use ESP8266, change SS_PIN_DEFAULT to SS(5), MOSI(13), MISO(12), SCK(14) +#define SS_PIN_DEFAULT D1 // 5, SS + +/////// + +// As a final fallback, use pin 10 +#else +#define SS_PIN_DEFAULT 10 + +//KH +#warning w5100.cpp Use fallback, change SS_PIN_DEFAULT to 10 + +#endif + +// W5100 controller instance +uint8_t W5100Class::chip = 0; +uint8_t W5100Class::CH_BASE_MSB; +uint8_t W5100Class::ss_pin = SS_PIN_DEFAULT; +#ifdef ETHERNET_LARGE_BUFFERS +uint16_t W5100Class::SSIZE = 2048; +uint16_t W5100Class::SMASK = 0x07FF; +#endif +W5100Class W5100; + +// pointers and bitmasks for optimized SS pin +#if defined(__AVR__) + volatile uint8_t * W5100Class::ss_pin_reg; + uint8_t W5100Class::ss_pin_mask; +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__) + volatile uint8_t * W5100Class::ss_pin_reg; +#elif defined(__IMXRT1062__) + volatile uint32_t * W5100Class::ss_pin_reg; + uint32_t W5100Class::ss_pin_mask; +#elif defined(__MKL26Z64__) + volatile uint8_t * W5100Class::ss_pin_reg; + uint8_t W5100Class::ss_pin_mask; +#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__) + volatile uint32_t * W5100Class::ss_pin_reg; + uint32_t W5100Class::ss_pin_mask; +#elif defined(__PIC32MX__) + volatile uint32_t * W5100Class::ss_pin_reg; + uint32_t W5100Class::ss_pin_mask; +#elif defined(ARDUINO_ARCH_ESP8266) + volatile uint32_t * W5100Class::ss_pin_reg; + uint32_t W5100Class::ss_pin_mask; +#elif defined(__SAMD21G18A__) + volatile uint32_t * W5100Class::ss_pin_reg; + uint32_t W5100Class::ss_pin_mask; + #warning w5100.cpp Use __SAMD21G18A__ +#endif + +// KH +uint8_t W5100Class::init(uint8_t socketNumbers, uint8_t new_ss_pin) +{ + // KH + uint8_t i; + + if (initialized) return 1; + + // Many Ethernet shields have a CAT811 or similar reset chip + // connected to W5100 or W5200 chips. The W5200 will not work at + // all, and may even drive its MISO pin, until given an active low + // reset pulse! The CAT811 has a 240 ms typical pulse length, and + // a 400 ms worst case maximum pulse length. MAX811 has a worst + // case maximum 560 ms pulse length. This delay is meant to wait + // until the reset pulse is ended. If your hardware has a shorter + // reset time, this can be edited or removed. + delay(560); + + W5100Class::ss_pin = new_ss_pin; + +#if ( W5100_DEBUG > 0 ) + //KH + Serial.print("\nW5100 init, using SS_PIN_DEFAULT = "); + Serial.print(SS_PIN_DEFAULT); + Serial.print(", new ss_pin = "); + Serial.print(new_ss_pin); + Serial.print(", W5100Class::ss_pin = "); + Serial.println(W5100Class::ss_pin); +#endif + + SPI.begin(); + + initSS(); + resetSS(); + + // From #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + + // Attempt W5200 detection first, because W5200 does not properly + // reset its SPI state when CS goes high (inactive). Communication + // from detecting the other chips can leave the W5200 in a state + // where it won't recover, unless given a reset pulse. + if (isW5200()) + { + CH_BASE_MSB = 0x40; +#ifdef ETHERNET_LARGE_BUFFERS +#if MAX_SOCK_NUM <= 1 + SSIZE = 16384; +#elif MAX_SOCK_NUM <= 2 + SSIZE = 8192; +#elif MAX_SOCK_NUM <= 4 + SSIZE = 4096; +#else + SSIZE = 2048; +#endif + SMASK = SSIZE - 1; +#endif + for (i=0; i> 10); + writeSnTX_SIZE(i, SSIZE >> 10); + } + for (; i<8; i++) + { + writeSnRX_SIZE(i, 0); + writeSnTX_SIZE(i, 0); + } + +#if ( W5100_DEBUG > 0 ) + Serial.print("W5100::init: W5200, SSIZE ="); + Serial.println(SSIZE); +#endif + + // Try W5500 next. Wiznet finally seems to have implemented + // SPI well with this chip. It appears to be very resilient, + // so try it after the fragile W5200 + } + else if (isW5500()) + { + CH_BASE_MSB = 0x10; +#ifdef ETHERNET_LARGE_BUFFERS +#if MAX_SOCK_NUM <= 1 + SSIZE = 16384; +#elif MAX_SOCK_NUM <= 2 + SSIZE = 8192; +#elif MAX_SOCK_NUM <= 4 + SSIZE = 4096; +#else + SSIZE = 2048; +#endif + SMASK = SSIZE - 1; + for (i=0; i> 10); + writeSnTX_SIZE(i, SSIZE >> 10); + } + for (; i<8; i++) + { + writeSnRX_SIZE(i, 0); + writeSnTX_SIZE(i, 0); + } +#endif + +#if ( W5100_DEBUG > 0 ) + Serial.print("W5100::init: W5500, SSIZE ="); + Serial.println(SSIZE); +#endif + + + // Try W5100 last. This simple chip uses fixed 4 byte frames + // for every 8 bit access. Terribly inefficient, but so simple + // it recovers from "hearing" unsuccessful W5100 or W5200 + // communication. W5100 is also the only chip without a VERSIONR + // register for identification, so we check this last. + } else if (isW5100()) + { + CH_BASE_MSB = 0x04; +#ifdef ETHERNET_LARGE_BUFFERS +#if MAX_SOCK_NUM <= 1 + SSIZE = 8192; + writeTMSR(0x03); + writeRMSR(0x03); +#elif MAX_SOCK_NUM <= 2 + SSIZE = 4096; + writeTMSR(0x0A); + writeRMSR(0x0A); +#else + SSIZE = 2048; + writeTMSR(0x55); + writeRMSR(0x55); +#endif + SMASK = SSIZE - 1; +#else + writeTMSR(0x55); + writeRMSR(0x55); +#endif + +#if ( W5100_DEBUG > 0 ) + Serial.print("W5100::init: W5100, SSIZE ="); + Serial.println(SSIZE); +#endif + + // No hardware seems to be present. Or it could be a W5200 + // that's heard other SPI communication if its chip select + // pin wasn't high when a SD card or other SPI chip was used. + } + else + { +#if ( W5100_DEBUG > 0 ) + Serial.println("no chip :-("); +#endif + + chip = 0; + SPI.endTransaction(); + return 0; // no known chip is responding :-( + } + SPI.endTransaction(); + initialized = true; + return 1; // successful init +} + +// Soft reset the Wiznet chip, by writing to its MR register reset bit +uint8_t W5100Class::softReset(void) +{ + uint16_t count=0; + +#if ( W5100_DEBUG > 0 ) + Serial.println("Wiznet soft reset"); +#endif + + // write to reset bit + writeMR(0x80); + // then wait for soft reset to complete + do + { + uint8_t mr = readMR(); + +#if ( W5100_DEBUG > 2 ) + Serial.print("mr="); + Serial.println(mr, HEX); +#endif + + if (mr == 0) + return 1; + + delay(1); + } while (++count < 20); + return 0; +} + + +uint8_t W5100Class::isW5100(void) +{ + chip = 51; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5100 chip"); +#endif + + if (!softReset()) + return 0; + + writeMR(0x10); + if (readMR() != 0x10) + return 0; + + writeMR(0x12); + if (readMR() != 0x12) + return 0; + + writeMR(0x00); + if (readMR() != 0x00) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5100"); +#endif + + return 1; +} + +uint8_t W5100Class::isW5200(void) +{ + chip = 52; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5200 chip"); +#endif + + if (!softReset()) + return 0; + + writeMR(0x08); + if (readMR() != 0x08) + return 0; + + writeMR(0x10); + if (readMR() != 0x10) + return 0; + + writeMR(0x00); + if (readMR() != 0x00) + return 0; + + int ver = readVERSIONR_W5200(); + +#if ( W5100_DEBUG > 1 ) + Serial.print("version="); + Serial.println(ver); +#endif + + if (ver != 3) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5200"); +#endif + + return 1; +} + +uint8_t W5100Class::isW5500(void) +{ + chip = 55; + +#if ( W5100_DEBUG > 1 ) + Serial.println("W5100.cpp: detect W5500 chip"); +#endif + + if (!softReset()) + return 0; + + writeMR(0x08); + if (readMR() != 0x08) + return 0; + + writeMR(0x10); + if (readMR() != 0x10) + return 0; + + writeMR(0x00); + if (readMR() != 0x00) + return 0; + + int ver = readVERSIONR_W5500(); + +#if ( W5100_DEBUG > 1 ) + Serial.print("version="); + Serial.println(ver); +#endif + + if (ver != 4) + return 0; + +#if ( W5100_DEBUG > 1 ) + Serial.println("chip is W5500"); +#endif + + return 1; +} + +W5100Linkstatus W5100Class::getLinkStatus() +{ + uint8_t phystatus; + + // KH + if (!initialized) return UNKNOWN; + + switch (chip) + { + case 52: + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + phystatus = readPSTATUS_W5200(); + SPI.endTransaction(); + if (phystatus & 0x20) + return LINK_ON; + + return LINK_OFF; + + case 55: + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); + phystatus = readPHYCFGR_W5500(); + SPI.endTransaction(); + if (phystatus & 0x01) + return LINK_ON; + + return LINK_OFF; + + default: + return UNKNOWN; + } +} + +uint16_t W5100Class::write(uint16_t addr, const uint8_t *buf, uint16_t len) +{ + uint8_t cmd[8]; + + if (chip == 51) + { + for (uint16_t i=0; i> 8); + SPI.transfer(addr & 0xFF); + addr++; + SPI.transfer(buf[i]); + resetSS(); + } + } + else if (chip == 52) + { + setSS(); + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + cmd[2] = ((len >> 8) & 0x7F) | 0x80; + cmd[3] = len & 0xFF; + SPI.transfer(cmd, 4); + +#ifdef SPI_HAS_TRANSFER_BUF + SPI.transfer(buf, NULL, len); +#else + // TODO: copy 8 bytes at a time to cmd[] and block transfer + for (uint16_t i=0; i < len; i++) + { + SPI.transfer(buf[i]); + } +#endif + resetSS(); + } + else + { + // chip == 55 + setSS(); + if (addr < 0x100) + { + // common registers 00nn + cmd[0] = 0; + cmd[1] = addr & 0xFF; + cmd[2] = 0x04; + } + else if (addr < 0x8000) + { + // socket registers 10nn, 11nn, 12nn, 13nn, etc + cmd[0] = 0; + cmd[1] = addr & 0xFF; + cmd[2] = ((addr >> 3) & 0xE0) | 0x0C; + } + else if (addr < 0xC000) + { + // transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc + // 10## #nnn nnnn nnnn + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + #if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1 + cmd[2] = 0x14; // 16K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2 + cmd[2] = ((addr >> 8) & 0x20) | 0x14; // 8K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4 + cmd[2] = ((addr >> 7) & 0x60) | 0x14; // 4K buffers + #else + cmd[2] = ((addr >> 6) & 0xE0) | 0x14; // 2K buffers + #endif + } + else + { + // receive buffers + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + #if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1 + cmd[2] = 0x1C; // 16K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2 + cmd[2] = ((addr >> 8) & 0x20) | 0x1C; // 8K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4 + cmd[2] = ((addr >> 7) & 0x60) | 0x1C; // 4K buffers + #else + cmd[2] = ((addr >> 6) & 0xE0) | 0x1C; // 2K buffers + #endif + } + + if (len <= 5) + { + for (uint8_t i=0; i < len; i++) + { + cmd[i + 3] = buf[i]; + } + + SPI.transfer(cmd, len + 3); + } + else + { + SPI.transfer(cmd, 3); +#ifdef SPI_HAS_TRANSFER_BUF + SPI.transfer(buf, NULL, len); +#else + // TODO: copy 8 bytes at a time to cmd[] and block transfer + for (uint16_t i=0; i < len; i++) + { + SPI.transfer(buf[i]); + } +#endif + } + resetSS(); + } + return len; +} + +uint16_t W5100Class::read(uint16_t addr, uint8_t *buf, uint16_t len) +{ + uint8_t cmd[4]; + + if (chip == 51) + { + for (uint16_t i=0; i < len; i++) + { + setSS(); + #if 1 + SPI.transfer(0x0F); + SPI.transfer(addr >> 8); + SPI.transfer(addr & 0xFF); + addr++; + buf[i] = SPI.transfer(0); + #else + cmd[0] = 0x0F; + cmd[1] = addr >> 8; + cmd[2] = addr & 0xFF; + cmd[3] = 0; + SPI.transfer(cmd, 4); // TODO: why doesn't this work? + buf[i] = cmd[3]; + addr++; + #endif + resetSS(); + } + } + else if (chip == 52) + { + setSS(); + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + cmd[2] = (len >> 8) & 0x7F; + cmd[3] = len & 0xFF; + SPI.transfer(cmd, 4); + memset(buf, 0, len); + SPI.transfer(buf, len); + resetSS(); + } + else + { + // chip == 55 + setSS(); + + if (addr < 0x100) + { + // common registers 00nn + cmd[0] = 0; + cmd[1] = addr & 0xFF; + cmd[2] = 0x00; + } + else if (addr < 0x8000) + { + // socket registers 10nn, 11nn, 12nn, 13nn, etc + cmd[0] = 0; + cmd[1] = addr & 0xFF; + cmd[2] = ((addr >> 3) & 0xE0) | 0x08; + } + else if (addr < 0xC000) + { + // transmit buffers 8000-87FF, 8800-8FFF, 9000-97FF, etc + // 10## #nnn nnnn nnnn + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + #if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1 + cmd[2] = 0x10; // 16K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2 + cmd[2] = ((addr >> 8) & 0x20) | 0x10; // 8K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4 + cmd[2] = ((addr >> 7) & 0x60) | 0x10; // 4K buffers + #else + cmd[2] = ((addr >> 6) & 0xE0) | 0x10; // 2K buffers + #endif + } else + { + // receive buffers + cmd[0] = addr >> 8; + cmd[1] = addr & 0xFF; + #if defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 1 + cmd[2] = 0x18; // 16K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 2 + cmd[2] = ((addr >> 8) & 0x20) | 0x18; // 8K buffers + #elif defined(ETHERNET_LARGE_BUFFERS) && MAX_SOCK_NUM <= 4 + cmd[2] = ((addr >> 7) & 0x60) | 0x18; // 4K buffers + #else + cmd[2] = ((addr >> 6) & 0xE0) | 0x18; // 2K buffers + #endif + } + SPI.transfer(cmd, 3); + memset(buf, 0, len); + SPI.transfer(buf, len); + resetSS(); + } + return len; +} + +void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) +{ + // Send command to socket + writeSnCR(s, _cmd); + // Wait for command to complete + while (readSnCR(s)) ; +} diff --git a/LibraryPatches/EthernetLarge/src/utility/w5100.h b/LibraryPatches/EthernetLarge/src/utility/w5100.h new file mode 100644 index 00000000..8d5b709b --- /dev/null +++ b/LibraryPatches/EthernetLarge/src/utility/w5100.h @@ -0,0 +1,617 @@ +/**************************************************************************************************************************** + w5100.cpp - Driver for W5x00 + + EthernetWebServer is a library for the Ethernet shields to run WebServer + + Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases + Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer + Licensed under MIT license + Version: 1.0.8 + + Copyright 2018 Paul Stoffregen + Copyright (c) 2010 by Cristian Maglie + + This file is free software; you can redistribute it and/or modify + it under the terms of either the GNU General Public License version 2 + or the GNU Lesser General Public License version 2.1, both as + published by the Free Software Foundation. + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 13/02/2020 Initial coding for Arduino Mega, Teensy, etc to support Ethernetx libraries + 1.0.1 K Hoang 20/02/2020 Add support to lambda functions + 1.0.2 K Hoang 20/02/2020 Add support to UIPEthernet library for ENC28J60 + 1.0.3 K Hoang 23/02/2020 Add support to SAM DUE / SAMD21 boards + 1.0.4 K Hoang 16/04/2020 Add support to SAMD51 boards + 1.0.5 K Hoang 24/04/2020 Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, + Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. + More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge + 1.0.6 K Hoang 27/04/2020 Add support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. Sync with ESP8266 core 2.7.1. + *****************************************************************************************************************************/ + +// w5100.h contains private W5x00 hardware "driver" level definitions +// which are not meant to be exposed to other libraries or Arduino users + +#ifndef W5100_H_INCLUDED +#define W5100_H_INCLUDED + +#include +#include + +// Safe for all chips +#define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) + +// Safe for W5200 and W5500, but too fast for W5100 +// Uncomment this if you know you'll never need W5100 support. +// Higher SPI clock only results in faster transfer to hosts on a LAN +// or with very low packet latency. With ordinary internet latency, +// the TCP window size & packet loss determine your overall speed. +//#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE0) + + +// Require Ethernet.h, because we need MAX_SOCK_NUM +#ifndef ethernet_h_ +#error "EthernetLarge.h must be included before w5100.h" +#endif + + +// Arduino 101's SPI can not run faster than 8 MHz. +#if defined(ARDUINO_ARCH_ARC32) +#undef SPI_ETHERNET_SETTINGS +#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE0) +#endif + +// Arduino Zero can't use W5100-based shields faster than 8 MHz +// https://github.com/arduino-libraries/Ethernet/issues/37#issuecomment-408036848 +// W5500 does seem to work at 12 MHz. Delete this if only using W5500 +#if defined(__SAMD21G18A__) +#undef SPI_ETHERNET_SETTINGS +//#warning Use SAMD21 architecture SPISettings(8000000, MSBFIRST, SPI_MODE3) => IP OK +#warning Use SAMD21 architecture SPISettings(30000000, MSBFIRST, SPI_MODE3) => IP OK +// Still not working !!! Original SPI_MODE0 not OK at all +//#define SPI_ETHERNET_SETTINGS SPISettings(8000000, MSBFIRST, SPI_MODE3) +#define SPI_ETHERNET_SETTINGS SPISettings(30000000, MSBFIRST, SPI_MODE3) +#endif + + +typedef uint8_t SOCKET; + +class SnMR { +public: + static const uint8_t CLOSE = 0x00; + static const uint8_t TCP = 0x21; + static const uint8_t UDP = 0x02; + static const uint8_t IPRAW = 0x03; + static const uint8_t MACRAW = 0x04; + static const uint8_t PPPOE = 0x05; + static const uint8_t ND = 0x20; + static const uint8_t MULTI = 0x80; +}; + +enum SockCMD { + Sock_OPEN = 0x01, + Sock_LISTEN = 0x02, + Sock_CONNECT = 0x04, + Sock_DISCON = 0x08, + Sock_CLOSE = 0x10, + Sock_SEND = 0x20, + Sock_SEND_MAC = 0x21, + Sock_SEND_KEEP = 0x22, + Sock_RECV = 0x40 +}; + +class SnIR { +public: + static const uint8_t SEND_OK = 0x10; + static const uint8_t TIMEOUT = 0x08; + static const uint8_t RECV = 0x04; + static const uint8_t DISCON = 0x02; + static const uint8_t CON = 0x01; +}; + +class SnSR { +public: + static const uint8_t CLOSED = 0x00; + static const uint8_t INIT = 0x13; + static const uint8_t LISTEN = 0x14; + static const uint8_t SYNSENT = 0x15; + static const uint8_t SYNRECV = 0x16; + static const uint8_t ESTABLISHED = 0x17; + static const uint8_t FIN_WAIT = 0x18; + static const uint8_t CLOSING = 0x1A; + static const uint8_t TIME_WAIT = 0x1B; + static const uint8_t CLOSE_WAIT = 0x1C; + static const uint8_t LAST_ACK = 0x1D; + static const uint8_t UDP = 0x22; + static const uint8_t IPRAW = 0x32; + static const uint8_t MACRAW = 0x42; + static const uint8_t PPPOE = 0x5F; +}; + +class IPPROTO { +public: + static const uint8_t IP = 0; + static const uint8_t ICMP = 1; + static const uint8_t IGMP = 2; + static const uint8_t GGP = 3; + static const uint8_t TCP = 6; + static const uint8_t PUP = 12; + static const uint8_t UDP = 17; + static const uint8_t IDP = 22; + static const uint8_t ND = 77; + static const uint8_t RAW = 255; +}; + +enum W5100Linkstatus { + UNKNOWN, + LINK_ON, + LINK_OFF +}; + +class W5100Class { + +public: + // KH + uint8_t init(uint8_t socketNumbers = MAX_SOCK_NUM, uint8_t new_ss_pin = 10); + + inline void setGatewayIp(const uint8_t * addr) { writeGAR(addr); } + inline void getGatewayIp(uint8_t * addr) { readGAR(addr); } + + inline void setSubnetMask(const uint8_t * addr) { writeSUBR(addr); } + inline void getSubnetMask(uint8_t * addr) { readSUBR(addr); } + + inline void setMACAddress(const uint8_t * addr) { writeSHAR(addr); } + inline void getMACAddress(uint8_t * addr) { readSHAR(addr); } + + inline void setIPAddress(const uint8_t * addr) { writeSIPR(addr); } + inline void getIPAddress(uint8_t * addr) { readSIPR(addr); } + + inline void setRetransmissionTime(uint16_t timeout) { writeRTR(timeout); } + inline void setRetransmissionCount(uint8_t retry) { writeRCR(retry); } + + static void execCmdSn(SOCKET s, SockCMD _cmd); + + + // W5100 Registers + // --------------- +//private: +public: + static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len); + + static uint8_t write(uint16_t addr, uint8_t data) + { + return write(addr, &data, 1); + } + + static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len); + + static uint8_t read(uint16_t addr) + { + uint8_t data; + read(addr, &data, 1); + return data; + } + +#define __GP_REGISTER8(name, address) \ + static inline void write##name(uint8_t _data) { \ + write(address, _data); \ + } \ + static inline uint8_t read##name() { \ + return read(address); \ + } +#define __GP_REGISTER16(name, address) \ + static void write##name(uint16_t _data) { \ + uint8_t buf[2]; \ + buf[0] = _data >> 8; \ + buf[1] = _data & 0xFF; \ + write(address, buf, 2); \ + } \ + static uint16_t read##name() { \ + uint8_t buf[2]; \ + read(address, buf, 2); \ + return (buf[0] << 8) | buf[1]; \ + } +#define __GP_REGISTER_N(name, address, size) \ + static uint16_t write##name(const uint8_t *_buff) { \ + return write(address, _buff, size); \ + } \ + static uint16_t read##name(uint8_t *_buff) { \ + return read(address, _buff, size); \ + } + + // KH + W5100Linkstatus getLinkStatus(); + + +public: + __GP_REGISTER8 (MR, 0x0000); // Mode + __GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address + __GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address + __GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address + __GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address + __GP_REGISTER8 (IR, 0x0015); // Interrupt + __GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask + __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) + __GP_REGISTER8 (VERSIONR_W5200,0x001F); // Chip Version Register (W5200 only) + __GP_REGISTER8 (VERSIONR_W5500,0x0039); // Chip Version Register (W5500 only) + __GP_REGISTER8 (PSTATUS_W5200, 0x0035); // PHY Status + __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default: 10111xxx + + +#undef __GP_REGISTER8 +#undef __GP_REGISTER16 +#undef __GP_REGISTER_N + + // W5100 Socket registers + // ---------------------- +private: + static uint16_t CH_BASE(void) { + //if (chip == 55) return 0x1000; + //if (chip == 52) return 0x4000; + //return 0x0400; + return CH_BASE_MSB << 8; + } + static uint8_t CH_BASE_MSB; // 1 redundant byte, saves ~80 bytes code on AVR + static const uint16_t CH_SIZE = 0x0100; + + static inline uint8_t readSn(SOCKET s, uint16_t addr) + { + return read(CH_BASE() + s * CH_SIZE + addr); + } + static inline uint8_t writeSn(SOCKET s, uint16_t addr, uint8_t data) + { + return write(CH_BASE() + s * CH_SIZE + addr, data); + } + static inline uint16_t readSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) + { + return read(CH_BASE() + s * CH_SIZE + addr, buf, len); + } + static inline uint16_t writeSn(SOCKET s, uint16_t addr, uint8_t *buf, uint16_t len) + { + return write(CH_BASE() + s * CH_SIZE + addr, buf, len); + } + +#define __SOCKET_REGISTER8(name, address) \ + static inline void write##name(SOCKET _s, uint8_t _data) { \ + writeSn(_s, address, _data); \ + } \ + static inline uint8_t read##name(SOCKET _s) { \ + return readSn(_s, address); \ + } +#define __SOCKET_REGISTER16(name, address) \ + static void write##name(SOCKET _s, uint16_t _data) { \ + uint8_t buf[2]; \ + buf[0] = _data >> 8; \ + buf[1] = _data & 0xFF; \ + writeSn(_s, address, buf, 2); \ + } \ + static uint16_t read##name(SOCKET _s) { \ + uint8_t buf[2]; \ + readSn(_s, address, buf, 2); \ + return (buf[0] << 8) | buf[1]; \ + } +#define __SOCKET_REGISTER_N(name, address, size) \ + static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \ + return writeSn(_s, address, _buff, size); \ + } \ + static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \ + return readSn(_s, address, _buff, size); \ + } + +public: + __SOCKET_REGISTER8(SnMR, 0x0000) // Mode + __SOCKET_REGISTER8(SnCR, 0x0001) // Command + __SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt + __SOCKET_REGISTER8(SnSR, 0x0003) // Status + __SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port + __SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr + __SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr + __SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port + __SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size + __SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode + __SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS + __SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL + __SOCKET_REGISTER8(SnRX_SIZE, 0x001E) // RX Memory Size (W5200 only) + __SOCKET_REGISTER8(SnTX_SIZE, 0x001F) // RX Memory Size (W5200 only) + __SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size + __SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer + __SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer + __SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size + __SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer + __SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?) + +#undef __SOCKET_REGISTER8 +#undef __SOCKET_REGISTER16 +#undef __SOCKET_REGISTER_N + + +private: + // KH + bool initialized = false; + static uint8_t chip; + static uint8_t ss_pin; + + static uint8_t isW5100(void); + static uint8_t isW5200(void); + static uint8_t isW5500(void); + +public: + // KH + static uint8_t softReset(void); + static uint8_t getChip(void) { return chip; } +#ifdef ETHERNET_LARGE_BUFFERS + static uint16_t SSIZE; + static uint16_t SMASK; +#else + static const uint16_t SSIZE = 2048; + static const uint16_t SMASK = 0x07FF; +#endif + static uint16_t SBASE(uint8_t socknum) + { + if (chip == 51) + { + return socknum * SSIZE + 0x4000; + } + else + { + return socknum * SSIZE + 0x8000; + } + } + + static uint16_t RBASE(uint8_t socknum) + { + if (chip == 51) { + return socknum * SSIZE + 0x6000; + } + else + { + return socknum * SSIZE + 0xC000; + } + } + + static bool hasOffsetAddressMapping(void) + { + if (chip == 55) + return true; + + return false; + } + + static void setSS(uint8_t pin) { ss_pin = pin; } + +private: +#if defined(__AVR__) + +#warning Use AVR architecture + + static volatile uint8_t *ss_pin_reg; + static uint8_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg) &= ~ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg) |= ss_pin_mask; + } +#elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK66FX1M0__) || defined(__MK64FX512__) + +#warning Use MK architecture + + static volatile uint8_t *ss_pin_reg; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+256) = 1; + } + + inline static void resetSS() + { + *(ss_pin_reg+128) = 1; + } +#elif defined(__IMXRT1062__) + +#warning Use Teensy architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+34) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+33) = ss_pin_mask; + } +#elif defined(__MKL26Z64__) + static volatile uint8_t *ss_pin_reg; + static uint8_t ss_pin_mask; + inline static void initSS() + { + ss_pin_reg = portOutputRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+8) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+4) = ss_pin_mask; + } +#elif defined(__SAM3X8E__) || defined(__SAM3A8C__) || defined(__SAM3A4C__) + +#warning Use SAM3 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = &(digitalPinToPort(ss_pin)->PIO_PER); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+13) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+12) = ss_pin_mask; + } +#elif defined(__PIC32MX__) + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+8+1) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+8+2) = ss_pin_mask; + } + +#elif defined(ARDUINO_ARCH_ESP8266) + +#warning Use ARDUINO_ARCH_ESP8266 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = (volatile uint32_t*)GPO; + ss_pin_mask = 1 << ss_pin; + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + GPOC = ss_pin_mask; + } + + inline static void resetSS() + { + GPOS = ss_pin_mask; + } + +#elif defined(__SAMD21G18A__) + +#warning Use SAMD21 architecture + + static volatile uint32_t *ss_pin_reg; + static uint32_t ss_pin_mask; + + inline static void initSS() + { + ss_pin_reg = portModeRegister(digitalPinToPort(ss_pin)); + ss_pin_mask = digitalPinToBitMask(ss_pin); + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + *(ss_pin_reg+5) = ss_pin_mask; + } + + inline static void resetSS() + { + *(ss_pin_reg+6) = ss_pin_mask; + } +#else + +#warning Use Default architecture + + inline static void initSS() + { + pinMode(ss_pin, OUTPUT); + } + + inline static void setSS() + { + digitalWrite(ss_pin, LOW); + } + + inline static void resetSS() + { + digitalWrite(ss_pin, HIGH); + } +#endif +}; + +extern W5100Class W5100; + +#endif + +#ifndef UTIL_H +#define UTIL_H + +#ifndef htons +#define htons(x) ( (((x)<<8)&0xFF00) | (((x)>>8)&0xFF) ) +#endif + +#ifndef ntohs +#define ntohs(x) htons(x) +#endif + +#ifndef htonl +#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ + ((x)<< 8 & 0x00FF0000UL) | \ + ((x)>> 8 & 0x0000FF00UL) | \ + ((x)>>24 & 0x000000FFUL) ) +#endif + +#ifndef ntohl +#define ntohl(x) htonl(x) +#endif + +#endif //W5100_H_INCLUDED diff --git a/README.md b/README.md index 3b856bfe..a04379ab 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/EthernetWebServer.svg)](http://github.com/khoih-prog/EthernetWebServer/issues) +#### New in v1.0.8 + +1. Fix W5x00 support for ESP8266 boards. + #### New in v1.0.7 1. Add ENC28J60 support to ***ESP32 and ESP8266*** boards. @@ -42,7 +46,10 @@ The EthernetWebServer class found in `EthernetWebServer.h` header, is a simple w 1. [`Arduino IDE 1.8.11 or later` for Arduino](https://www.arduino.cc/en/Main/Software) 2. `Arduino AVR core 1.8.2 or later` for Arduino (Use Arduino Board Manager) 3. Depending on which Ethernet card you're using: - - [Ethernet library](https://www.arduino.cc/en/Reference/Ethernet) for W5100, W5200 and W5500 + - [Ethernet library](https://www.arduino.cc/en/Reference/Ethernet) for W5100, W5200 and W5500. + - [EthernetLarge library](https://github.com/OPEnSLab-OSU/EthernetLarge) for W5100, W5200 and W5500. + - [Ethernet2 library](https://github.com/khoih-prog/Ethernet2) for W5500. + - [Ethernet3 library](https://github.com/sstaub/Ethernet3) for W5500/WIZ550io/WIZ850io/USR-ES1 with Wiznet W5500 chip. - [UIPEthernet](https://github.com/UIPEthernet/UIPEthernet) for ENC28J60 4. [`Functional-VLPP library`](https://github.com/khoih-prog/functional-vlpp) to use lambda function @@ -61,21 +68,30 @@ Another way is to use `Arduino Library Manager` or [![arduino-library-badge](htt ### Important notes -1. If your application requires 2K+ HTML page, the current [`Ethernet library`](https://www.arduino.cc/en/Reference/Ethernet) must be modified if you are using W5200/W5500 Ethernet shields. W5100 is not supported for 2K+ buffer. +1. If your application requires 2K+ HTML page, the current [`Ethernet library`](https://www.arduino.cc/en/Reference/Ethernet) must be modified if you are using W5200/W5500 Ethernet shields. W5100 is not supported for 2K+ buffer. If you use boards requiring different CS/SS pin for W5x00 Ethernet shield, for example ESP32, ESP8266, nRF52, etc., you also have to modify the following libraries to be able to specify the CS/SS pin correctly. 2. To fix [`Ethernet library`](https://www.arduino.cc/en/Reference/Ethernet), just copy these following files into the [`Ethernet library`](https://www.arduino.cc/en/Reference/Ethernet) directory to overwrite the old files: - [Ethernet.h](LibraryPatches/Ethernet/src/Ethernet.h) +- [Ethernet.cpp](LibraryPatches/Ethernet/src/Ethernet.cpp) - [EthernetServer.cpp](LibraryPatches/Ethernet/src/EthernetServer.cpp) +- [w5100.h](LibraryPatches/Ethernet/src/utility/w5100.h) - [w5100.cpp](LibraryPatches/Ethernet/src/utility/w5100.cpp) -3. To fix [`UIPEthernet`](https://github.com/UIPEthernet/UIPEthernet), just copy these following files into the [`UIPEthernet`](https://github.com/UIPEthernet/UIPEthernet) directory to overwrite the old files: +2. To fix [`EthernetLarge library`](https://github.com/OPEnSLab-OSU/EthernetLarge), just copy these following files into the [`EthernetLarge library`](https://github.com/OPEnSLab-OSU/EthernetLarge) directory to overwrite the old files: +- [Ethernet.h](LibraryPatches/EthernetLarge/src/Ethernet.h) +- [Ethernet.cpp](LibraryPatches/EthernetLarge/src/Ethernet.cpp) +- [EthernetServer.cpp](LibraryPatches/EthernetLarge/src/EthernetServer.cpp) +- [w5100.h](LibraryPatches/EthernetLarge/src/utility/w5100.h) +- [w5100.cpp](LibraryPatches/EthernetLarge/src/utility/w5100.cpp) + +4. To fix [`UIPEthernet`](https://github.com/UIPEthernet/UIPEthernet), just copy these following files into the [`UIPEthernet`](https://github.com/UIPEthernet/UIPEthernet) directory to overwrite the old files: - [Enc28J60Network.h](LibraryPatches/UIPEthernet/utility/Enc28J60Network.h) - [Enc28J60Network.cpp](LibraryPatches/UIPEthernet/utility/Enc28J60Network.cpp) -4. To fix [`ESP32`](https://github.com/espressif/arduino-esp32), just copy the following file into the [`ESP32`](https://github.com/espressif/arduino-esp32) cores/esp32 directory (e.g. ./arduino-1.8.12/hardware/espressif/cores/esp32) to overwrite the old file: +5. To fix [`ESP32 compile error`](https://github.com/espressif/arduino-esp32), just copy the following file into the [`ESP32`](https://github.com/espressif/arduino-esp32) cores/esp32 directory (e.g. ./arduino-1.8.12/hardware/espressif/cores/esp32) to overwrite the old file: - [Server.h](LibraryPatches/esp32/cores/esp32/Server.h) -5. ***How to select which built-in Ethernet or shield to use*** +6. ***How to select which built-in Ethernet or shield to use*** - Standard Ethernet library is used by default, just check in the sketch these line are commented out @@ -128,6 +144,52 @@ For example, Ethernet_XYZ library uses ***Ethernet_XYZ.h*** - The ***Ethernet_Shield_W5200, EtherCard, EtherSia libraries are not supported***. Don't use unless you know how to modify those libraries. - Requests to support for any future custom Ethernet library will be ignored. ***Use at your own risk***. +7. ***How to select another CS/SS pin to use*** + +- For ***Ethernet, Ethernet3 and EthernetLarge*** libraries, use as follows + +``` +// Select a GPIO pin to use, for example GPIO13 for ESP32. Default is 10 if not called +Ethernet.setCsPin (13); +``` + +- For Ethernet2 library, use as follows + +``` +// Select a GPIO pin to use, for example GPIO13 for ESP32. Default is 10 if not called +Ethernet.init (13); +``` + +8. ***How to use W5x00 with ESP8266*** + +To avoid using the default not-working Ethernet library of ESP8266, rename the Ethernet.h/cpp to Ethernet_ESP8266.h/cpp to avoid library conflict if you're using the Ethernet library. The Ethernet2, Ethernet3, EthernetLarge library can be used without conflict. + +These pins are tested OK with ESP8266 and W5x00 + +``` +// For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +``` + +9. ***How to increase W5x00 TX/RX buffer*** + +- For ***Ethernet3*** library only, use as follows + +``` + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +``` #### Usage @@ -292,6 +354,12 @@ Also see examples: Please take a look at other examples as well. ```cpp +/* + The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno + and pins 50, 51, and 52 on the Mega. On both boards, pin 10 is used as SS. On the Mega, the hardware SS pin, 53, + is not used to select the Ethernet controller chip, but it must be kept as an output or the SPI interface won't work. +*/ + #if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \ || defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \ || defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \ @@ -310,13 +378,6 @@ Please take a look at other examples as well. #undef ETHERNET_USE_NRF528XX #endif #define ETHERNET_USE_NRF528XX true - -//This is workaround for NINA_B302_ublox -// Change the pin -#define ENC28J60_CONTROL_CS 10 -#define ENC28J60_USE_SPILIB true -#warning Use nRF52 with SPI pins defined - #endif #if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) ) @@ -411,12 +472,13 @@ Please take a look at other examples as well. #elif ( defined(ESP8266) ) // For ESP8266 #warning Use ESP8266 architecture +#include #define ETHERNET_USE_ESP8266 #define BOARD_TYPE "ESP8266" #elif ( defined(ESP32) ) // For ESP32 -#warning Use ESP32 architecture +#warning Use ESP32architecture #define ETHERNET_USE_ESP32 #define BOARD_TYPE "ESP32" @@ -432,40 +494,116 @@ Please take a look at other examples as well. // Use true for ENC28J60 and UIPEthernet library (https://github.com/UIPEthernet/UIPEthernet) // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) -#define USE_UIP_ETHERNET false //true +//#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false + +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif // Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network -IPAddress ip(192, 168, 2, 200); +IPAddress ip(192, 168, 2, 222); EthernetWebServer server(80); +int reqCount = 0; // number of requests received + const int led = 13; void handleRoot() { - String html = "Hello from EthernetWebServer running on " + String(BOARD_TYPE); - - server.send(200, "text/plain", html); + digitalWrite(led, 1); + char temp[400]; + int sec = millis() / 1000; + int min = sec / 60; + int hr = min / 60; + + snprintf(temp, 400, + "\ +\ +\ +ESP8266 Demo\ +\ + \ +\ +

Hi from EthernetWebServer!

\ +

Uptime: %02d:%02d:%02d

\ +\ +\ +", + hr, min % 60, sec % 60); + + server.send(200, "text/html", temp); + digitalWrite(led, 0); } void handleNotFound() { + digitalWrite(led, 1); String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); @@ -474,26 +612,53 @@ void handleNotFound() message += "\nArguments: "; message += server.args(); message += "\n"; + for (uint8_t i = 0; i < server.args(); i++) { message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; } + server.send(404, "text/plain", message); digitalWrite(led, 0); } +void drawGraph() +{ + String out; + out.reserve(3000); + char temp[70]; + out += "\n"; + out += "\n"; + out += "\n"; + int y = rand() % 130; + + for (int x = 10; x < 300; x += 10) + { + int y2 = rand() % 130; + sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); + out += temp; + y = y2; + } + out += "\n\n"; + + server.send(200, "image/svg+xml", out); +} + void setup(void) { - // Open serial communications and wait for port to open: + pinMode(led, OUTPUT); + digitalWrite(led, 0); + Serial.begin(115200); while (!Serial); //delay(1000); - Serial.println("\nStarting HelloServer on " + String(BOARD_TYPE)); + + Serial.println("\nStarting AdvancedServer on " + String(BOARD_TYPE)); // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -504,20 +669,93 @@ void setup(void) Serial.println(SS); Serial.println("========================="); +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP - Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - //Ethernet.begin(mac); + //Ethernet.begin(mac, ip); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); - server.on("/", handleRoot); + Ethernet.begin(mac[index]); + + // Just info to know how to connect correctly + Serial.println("========================="); + Serial.println("Currently Used SPI pinout:"); + Serial.print("MOSI:"); + Serial.println(MOSI); + Serial.print("MISO:"); + Serial.println(MISO); + Serial.print("SCK:"); + Serial.println(SCK); + Serial.print("SS:"); + Serial.println(SS); +#if USE_ETHERNET3 + Serial.print("SPI_CS:"); + Serial.println(SPI_CS); +#endif + Serial.println("========================="); + + Serial.print("Using mac index = "); + Serial.println(index); - server.on("/inline", []() { + Serial.print("Connected! IP address: "); + Serial.println(Ethernet.localIP()); + + server.on("/", handleRoot); + server.on("/test.svg", drawGraph); + server.on("/inline", []() + { server.send(200, "text/plain", "This works as well"); }); server.onNotFound(handleNotFound); - server.begin(); Serial.print(F("HTTP EthernetWebServer is @ IP : ")); @@ -612,6 +850,9 @@ Conn2Blynk: server = account.duckdns.org, port = 8080 Token = token, IP = 192.168.2.103 BBBBBBBBBB BBBBBBBBBB BBBBBBBBBB ``` +#### New in v1.0.8 + +1. Fix W5x00 support for ESP8266 boards. #### New in v1.0.7 @@ -660,10 +901,10 @@ The library supports ### Contributions and thanks -1. Forked from [Ivan Grokhotkov's ESP8266WebServer](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer) +1. Based on and mdified from from [Ivan Grokhotkov's ESP8266WebServer](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer) 2. [jandrassy](https://github.com/jandrassy) for [UIPEthernet library](https://github.com/UIPEthernet/UIPEthernet) 3. Thanks to [Miguel Alexandre Wisintainer](https://github.com/tcpipchip) for initiating, inspriring, working with, developing, debugging and testing. Without that, support to nRF52, especially ***U-Box B302 running as nRF52840***, has never been started and finished. Also see [ESP32-based U-BLOX NINA W102 running ENC28J60](https://u-blox-ethernet-ninaw.blogspot.com/). -4. Thanks to [Vladimir](https://github.com/workpage2) to initiate the work on ESP32 in [Spiffs not work Issue #2](https://github.com/khoih-prog/EthernetWebServer/issues/2) +4. Thanks to [Vladimir](https://github.com/workpage2) to initiate the work on ESP32 and ESP8266 in [Spiffs not work Issue #2](https://github.com/khoih-prog/EthernetWebServer/issues/2) ## Contributing diff --git a/examples/AdvancedWebServer/AdvancedWebServer.ino b/examples/AdvancedWebServer/AdvancedWebServer.ino index 5f06e5da..baa75cb5 100644 --- a/examples/AdvancedWebServer/AdvancedWebServer.ino +++ b/examples/AdvancedWebServer/AdvancedWebServer.ino @@ -6,7 +6,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Copyright (c) 2015, Majenko Technologies All rights reserved. @@ -47,7 +47,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards. + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -167,6 +168,7 @@ #elif ( defined(ESP8266) ) // For ESP8266 #warning Use ESP8266 architecture +#include #define ETHERNET_USE_ESP8266 #define BOARD_TYPE "ESP8266" @@ -188,23 +190,73 @@ // Use true for ENC28J60 and UIPEthernet library (https://github.com/UIPEthernet/UIPEthernet) // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) -#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xCD +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network @@ -225,7 +277,7 @@ void handleRoot() int hr = min / 60; snprintf(temp, 400, -"\ + "\ \ \ ESP8266 Demo\ @@ -302,7 +354,7 @@ void setup(void) // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -313,11 +365,84 @@ void setup(void) Serial.println(SS); Serial.println("========================="); +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP //Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - Ethernet.begin(mac); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); + + // Just info to know how to connect correctly + Serial.println("========================="); + Serial.println("Currently Used SPI pinout:"); + Serial.print("MOSI:"); + Serial.println(MOSI); + Serial.print("MISO:"); + Serial.println(MISO); + Serial.print("SCK:"); + Serial.println(SCK); + Serial.print("SS:"); + Serial.println(SS); +#if USE_ETHERNET3 + Serial.print("SPI_CS:"); + Serial.println(SPI_CS); +#endif + Serial.println("========================="); + + Serial.print("Using mac index = "); + Serial.println(index); + + Serial.print("Connected! IP address: "); + Serial.println(Ethernet.localIP()); server.on("/", handleRoot); server.on("/test.svg", drawGraph); diff --git a/examples/HelloServer/HelloServer.ino b/examples/HelloServer/HelloServer.ino index 28761f9b..8cb44fd5 100644 --- a/examples/HelloServer/HelloServer.ino +++ b/examples/HelloServer/HelloServer.ino @@ -6,7 +6,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,6 +24,7 @@ More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -171,26 +172,79 @@ // Use true for ENC28J60 and UIPEthernet library (https://github.com/UIPEthernet/UIPEthernet) // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) -#define USE_UIP_ETHERNET false //true +//#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 false //true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network -IPAddress ip(192, 168, 2, 200); +IPAddress ip(192, 168, 2, 155); EthernetWebServer server(80); @@ -198,7 +252,7 @@ const int led = 13; void handleRoot() { - String html = "Hello from EthernetWebServer running on " + String(BOARD_TYPE); + String html = "Hello from HelloServer running on " + String(BOARD_TYPE); server.send(200, "text/plain", html); } @@ -232,7 +286,7 @@ void setup(void) // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -243,11 +297,61 @@ void setup(void) Serial.println(SS); Serial.println("========================="); +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP - Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - //Ethernet.begin(mac); + //Ethernet.begin(mac, ip); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); server.on("/", handleRoot); diff --git a/examples/HelloServer2/HelloServer2.ino b/examples/HelloServer2/HelloServer2.ino index 933bc701..d88e9e48 100644 --- a/examples/HelloServer2/HelloServer2.ino +++ b/examples/HelloServer2/HelloServer2.ino @@ -5,7 +5,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,6 +23,7 @@ More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -164,23 +165,77 @@ // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) //#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 false //true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; + // Select the IP address according to your local network IPAddress ip(192, 168, 2, 200); @@ -190,7 +245,7 @@ const int led = 13; void handleRoot() { - String html = "Hello from EthernetWebServer running on " + String(BOARD_TYPE); + String html = "Hello from HelloServer2 running on " + String(BOARD_TYPE); //digitalWrite(led, 1); server.send(200, "text/plain", html); //digitalWrite(led, 0); @@ -228,7 +283,7 @@ void setup(void) // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -238,12 +293,62 @@ void setup(void) Serial.print("SS:"); Serial.println(SS); Serial.println("========================="); + +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP //Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - Ethernet.begin(mac); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); server.on("/", handleRoot); @@ -287,7 +392,7 @@ void setup(void) server.begin(); - Serial.print(F("HTTP EthernetWebServer started @ IP : ")); + Serial.print(F("HTTP HelloServer2 started @ IP : ")); Serial.println(Ethernet.localIP()); } diff --git a/examples/HttpBasicAuth/HttpBasicAuth.ino b/examples/HttpBasicAuth/HttpBasicAuth.ino index dfe3b3f2..74cb4ea0 100644 --- a/examples/HttpBasicAuth/HttpBasicAuth.ino +++ b/examples/HttpBasicAuth/HttpBasicAuth.ino @@ -6,7 +6,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -163,21 +164,74 @@ // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) //#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 false //true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network @@ -196,8 +250,9 @@ void setup() //delay(1000); Serial.println("\nStarting HTTPBasicAuth on " + String(BOARD_TYPE)); -#if ( defined(ESP32) || defined(ESP8266) ) - Serial.println("Used/default ESP32/ESP8266 pinout:"); + // Just info to know how to connect correctly + Serial.println("========================="); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -206,15 +261,63 @@ void setup() Serial.println(SCK); Serial.print("SS:"); Serial.println(SS); + Serial.println("========================="); + +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); #endif - Serial.println("Starting ethernet"); +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP - Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - //Ethernet.begin(mac); + //Ethernet.begin(mac, ip); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); server.on("/", []() { @@ -227,7 +330,7 @@ void setup() server.begin(); - Serial.print(F("HTTP EthernetWebServer started @ IP : ")); + Serial.print(F("HTTP HTTPBasicAuth started @ IP : ")); Serial.println(Ethernet.localIP()); Serial.print(F("Open http://")); diff --git a/examples/PostServer/PostServer.ino b/examples/PostServer/PostServer.ino index b72398e1..0d3e6d3a 100644 --- a/examples/PostServer/PostServer.ino +++ b/examples/PostServer/PostServer.ino @@ -6,7 +6,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -162,21 +163,74 @@ // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) //#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 false //true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network @@ -283,7 +337,7 @@ void setup(void) // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -293,12 +347,62 @@ void setup(void) Serial.print("SS:"); Serial.println(SS); Serial.println("========================="); + +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP - Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - //Ethernet.begin(mac); + //Ethernet.begin(mac, ip); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); server.on("/", handleRoot); @@ -310,7 +414,7 @@ void setup(void) server.begin(); - Serial.print(F("HTTP EthernetWebServer started @ IP : ")); + Serial.print(F("HTTP POSTServer started @ IP : ")); Serial.println(Ethernet.localIP()); } diff --git a/examples/SimpleAuthentication/SimpleAuthentication.ino b/examples/SimpleAuthentication/SimpleAuthentication.ino index 72bf4978..f82bfd88 100644 --- a/examples/SimpleAuthentication/SimpleAuthentication.ino +++ b/examples/SimpleAuthentication/SimpleAuthentication.ino @@ -6,7 +6,7 @@ Forked and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ /* The Arduino board communicates with the shield using the SPI bus. This is on digital pins 11, 12, and 13 on the Uno @@ -163,21 +164,74 @@ // Use false for W5x00 and Ethernetx library (https://www.arduino.cc/en/Reference/Ethernet) //#define USE_UIP_ETHERNET true +//#define USE_UIP_ETHERNET false -// Ethernet_Shield_W5200, EtherCar, EtherSia not supported +// Note: To rename ESP628266 Ethernet lib files to Ethernet_ESP8266.h and Ethernet_ESP8266.cpp +#if ( !defined(USE_UIP_ETHERNET) || !USE_UIP_ETHERNET ) + +// Only one if the following to be true +#define USE_ETHERNET2 false +#define USE_ETHERNET3 false //true +#define USE_ETHERNET_LARGE false //true +#define USE_ETHERNET_ESP8266 false + +#if ( USE_ETHERNET2 || USE_ETHERNET3 || USE_ETHERNET_LARGE || USE_ETHERNET_ESP8266 ) +#define USE_CUSTOM_ETHERNET true +#endif + +#if USE_ETHERNET3 +#include "Ethernet3.h" +#warning Use Ethernet3 lib +#elif USE_ETHERNET2 +#include "Ethernet2.h" +#warning Use Ethernet2 lib +#elif USE_ETHERNET_LARGE +#include "EthernetLarge.h" +#warning Use EthernetLarge lib +#elif USE_ETHERNET_ESP8266 +#include "Ethernet_ESP8266.h" +#warning Use Ethernet_ESP8266 lib +#else +#define USE_ETHERNET true +#include "Ethernet.h" +#warning Use Ethernet lib +#endif + +// Ethernet_Shield_W5200, EtherCard, EtherSia not supported // Select just 1 of the following #include if uncomment #define USE_CUSTOM_ETHERNET // Otherwise, standard Ethernet library will be used for W5x00 -//#define USE_CUSTOM_ETHERNET true -//#include -//#include -//#include + +#endif //#if !USE_UIP_ETHERNET #include // Enter a MAC address and IP address for your controller below. -byte mac[] = { - 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED +// Enter a MAC address and IP address for your controller below. +#define NUMBER_OF_MAC 20 + +byte mac[][NUMBER_OF_MAC] = +{ + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x09 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x03 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x08 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0F }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x07 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0D }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0E }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x13 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0C }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x04 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x01 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x10 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x11 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x12 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x05 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x06 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x0B }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x02 }, + { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x14 }, }; // Select the IP address according to your local network @@ -306,7 +360,7 @@ void setup(void) // Just info to know how to connect correctly Serial.println("========================="); - Serial.println("Used/default SPI pinout:"); + Serial.println("Default SPI pinout:"); Serial.print("MOSI:"); Serial.println(MOSI); Serial.print("MISO:"); @@ -316,12 +370,62 @@ void setup(void) Serial.print("SS:"); Serial.println(SS); Serial.println("========================="); + +#if defined(ESP8266) +// For ESP8266, change for other boards if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // For ESP8266 + // Pin D0(GPIO16) D1(GPIO5) D2(GPIO4) D3(GPIO0) D4(GPIO2) D8 + // Ethernet 0 X X X X 0 + // Ethernet2 X X X X X 0 + // Ethernet3 X X X X X 0 + // EthernetLarge X X X X X 0 + // Ethernet_ESP8266 0 0 0 0 0 0 + // D1 is safe to used for Ethernet, Ethernet2, Ethernet3, EthernetLarge libs + // Must use library patch for Ethernet, EthernetLarge libraries + Ethernet.setCsPin (D1); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) + Ethernet.init (D1); +#endif + +#else +// For other boards, to change if necessary +#if ( USE_ETHERNET || USE_ETHERNET3 || USE_ETHERNET_LARGE ) + // Must use library patch for Ethernet, EthernetLarge libraries + // ESP32 => GPIO13 OK with Ethernet, EthernetLarge, not Ethernet3 + Ethernet.setCsPin (13); + +#if USE_ETHERNET3 + // Use MAX_SOCK_NUM = 4 for 4K, 2 for 8K, 1 for 16K RX/TX buffer + #define ETHERNET3_MAX_SOCK_NUM 4 + + Ethernet.init (ETHERNET3_MAX_SOCK_NUM); +#endif + +#elif ( USE_ETHERNET2 ) +// ESP32 => GPIO13 OK with Ethernet2 + Ethernet.init (13); +#endif + +#endif //defined(ESP8266) + // start the ethernet connection and the server: // Use Static IP - Ethernet.begin(mac, ip); - // Use DHCP dynamic IP - //Ethernet.begin(mac); + //Ethernet.begin(mac, ip); + // Use DHCP dynamic IP and random mac + srand(1); + uint16_t index = rand() % NUMBER_OF_MAC; + //uint16_t index = random(NUMBER_OF_MAC); + + Ethernet.begin(mac[index]); server.on("/", handleRoot); server.on("/login", handleLogin); @@ -341,7 +445,7 @@ void setup(void) server.collectHeaders(headerkeys, headerkeyssize); server.begin(); - Serial.print(F("HTTP EthernetWebServer is @ IP : ")); + Serial.print(F("HTTP SimpleAuthentication is @ IP : ")); Serial.println(Ethernet.localIP()); } diff --git a/library.json b/library.json index 907b7abf..00bedb3b 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "EthernetWebServer", - "version": "1.0.7", + "version": "1.0.8", "keywords": "WebServer, Ethernet, Arduino, Teensy, SAMD, SAM DUE, AVR, Mega, nRF52, ESP32, ESP8266, Ethernet shield", "description": "Simple EthernetWebServer library for AVR, Teensy, SAM DUE, SAMD, ESP, nRF52, ESP32, ESP8266 boards running Ethernet shields", "authors": diff --git a/library.properties b/library.properties index 1e827db2..534db7c3 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=EthernetWebServer -version=1.0.7 +version=1.0.8 author=Khoi Hoang license=MIT maintainer=Khoi Hoang diff --git a/src/EthernetWebServer-impl.h b/src/EthernetWebServer-impl.h index ca290ff7..c5e9808f 100644 --- a/src/EthernetWebServer-impl.h +++ b/src/EthernetWebServer-impl.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef EthernetWebServer_impl_h diff --git a/src/EthernetWebServer.h b/src/EthernetWebServer.h index f9c418db..10569077 100644 --- a/src/EthernetWebServer.h +++ b/src/EthernetWebServer.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef EthernetWebServer_h diff --git a/src/Parsing-impl.h b/src/Parsing-impl.h index 71fbde6f..a6d73055 100644 --- a/src/Parsing-impl.h +++ b/src/Parsing-impl.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef Parsing_impl_h #define Parsing_impl_h diff --git a/src/detail/Debug.h b/src/detail/Debug.h index 168347da..458d1456 100644 --- a/src/detail/Debug.h +++ b/src/detail/Debug.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef EthernetWebServer_Debug_H diff --git a/src/detail/RequestHandler.h b/src/detail/RequestHandler.h index 5c52c893..7a1c355b 100644 --- a/src/detail/RequestHandler.h +++ b/src/detail/RequestHandler.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef RequestHandler_h diff --git a/src/detail/RequestHandlersImpl.h b/src/detail/RequestHandlersImpl.h index bb39da65..d60f394b 100644 --- a/src/detail/RequestHandlersImpl.h +++ b/src/detail/RequestHandlersImpl.h @@ -7,7 +7,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -24,7 +24,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef RequestHandlerImpl_h diff --git a/src/libb64/cdecode.c b/src/libb64/cdecode.c index 75662670..0195b83e 100644 --- a/src/libb64/cdecode.c +++ b/src/libb64/cdecode.c @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #include "cdecode.h" diff --git a/src/libb64/cdecode.h b/src/libb64/cdecode.h index 0f2954c4..92ead30a 100644 --- a/src/libb64/cdecode.h +++ b/src/libb64/cdecode.h @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef BASE64_CDECODE_H diff --git a/src/libb64/cencode.c b/src/libb64/cencode.c index bd957fb5..4892fa49 100644 --- a/src/libb64/cencode.c +++ b/src/libb64/cencode.c @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #include "cencode.h" diff --git a/src/libb64/cencode.h b/src/libb64/cencode.h index 56660284..1f18d0c9 100644 --- a/src/libb64/cencode.h +++ b/src/libb64/cencode.h @@ -6,7 +6,7 @@ Based on and modified from ESP8266 https://github.com/esp8266/Arduino/releases Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer Licensed under MIT license - Version: 1.0.7 + Version: 1.0.8 Original author: @file Esp8266WebServer.h @@ -23,7 +23,8 @@ Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc. More Custom Ethernet libraries supported such as Ethernet2, Ethernet3, EthernetLarge 1.0.6 K Hoang 27/04/2020 Add W5x00 support to ESP32/ESP8266 boards - 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.7 K Hoang 30/04/2020 Add ENC28J60 support to ESP32/ESP8266 boards + 1.0.8 K Hoang 12/05/2020 Fix W5x00 support for ESP8266 boards. *****************************************************************************************************************************/ #ifndef BASE64_CENCODE_H