UIPEthernet library for Arduino IDE, Eclipse with arduino plugin and MBED/SMeshStudio (AVR,STM32F,ESP8266,Intel ARC32,Nordic nRF51,Teensy boards,Realtek Ameba(RTL8195A,RTL8710)), ENC28j60 network chip. Compatible with Wiznet W5100 Ethernet library API. Compiled and tested on Nucleo-F302R8. Master repository is: https://github.com/UIPEthernet/UIPEthernet/
Revision 38:645b253e6b50, committed 2017-03-27
- Comitter:
- cassyarduino
- Date:
- Mon Mar 27 22:31:01 2017 +0200
- Parent:
- 37:a848e40373ac
- Child:
- 39:deeb00b81cc9
- Commit message:
- Release: 2.0.4
Changed in this revision
--- a/Dhcp.cpp Wed Feb 22 13:40:36 2017 +0000 +++ b/Dhcp.cpp Mon Mar 27 22:31:01 2017 +0200 @@ -17,17 +17,15 @@ #include "utility/logging.h" #include "utility/uip.h" -int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) +int DhcpClass::beginWithDHCP(uint8_t *mac) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::beginWithDHCP(uint8_t *mac) DEBUG_V1:Function started")); #endif _dhcpLeaseTime=0; _dhcpT1=0; _dhcpT2=0; _lastCheck=0; - _timeout = timeout; - _responseTimeout = responseTimeout; // zero out _dhcpMacAddr memset(_dhcpMacAddr, 0, 6); @@ -40,16 +38,16 @@ void DhcpClass::reset_DHCP_lease(void){ #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::reset_DHCP_lease(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::reset_DHCP_lease(void) DEBUG_V1:Function started")); #endif - // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp - memset(_dhcpLocalIp, 0, 20); + // zero out _dhcpipv4struct.SubnetMask, _dhcpipv4struct.GatewayIp, _dhcpipv4struct.LocalIp, _dhcpipv4struct.DhcpServerIp, _dhcpipv4struct.DnsServerIp + memset(&_dhcpipv4struct, 0, sizeof(_dhcpipv4struct)); } //return:0 on error, 1 if request is sent and response is received int DhcpClass::request_DHCP_lease(void){ #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:Function started")); #endif uint8_t messageType = 0; @@ -83,7 +81,7 @@ if(_dhcp_state == STATE_DHCP_START) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_START -> send_DHCP_MESSAGE DHCP_DISCOVER")); + LogObject.uart_send_strln(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_START -> send_DHCP_MESSAGE DHCP_DISCOVER")); #endif _dhcpTransactionId++; @@ -92,7 +90,7 @@ } else if(_dhcp_state == STATE_DHCP_REREQUEST){ #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_REREQUEST -> send_DHCP_MESSAGE DHCP_REQUEST")); + LogObject.uart_send_strln(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_REREQUEST -> send_DHCP_MESSAGE DHCP_REQUEST")); #endif _dhcpTransactionId++; send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000)); @@ -101,11 +99,11 @@ else if(_dhcp_state == STATE_DHCP_DISCOVER) { uint32_t respId; - messageType = parseDHCPResponse(_responseTimeout, respId); + messageType = parseDHCPResponse(respId); if(messageType == DHCP_OFFER) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_DISCOVER,messageType=DHCP_OFFER -> send_DHCP_MESSAGE DHCP_REQUEST")); + LogObject.uart_send_strln(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_DISCOVER,messageType=DHCP_OFFER -> send_DHCP_MESSAGE DHCP_REQUEST")); #endif // We'll use the transaction ID that the offer came with, // rather than the one we were up to @@ -117,11 +115,11 @@ else if(_dhcp_state == STATE_DHCP_REQUEST) { uint32_t respId; - messageType = parseDHCPResponse(_responseTimeout, respId); + messageType = parseDHCPResponse(respId); if(messageType == DHCP_ACK) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_REQUEST,messageType=DHCP_ACK")); + LogObject.uart_send_strln(F("DhcpClass::request_DHCP_lease(void) DEBUG_V1:dhcp_state=STATE_DHCP_REQUEST,messageType=DHCP_ACK")); #endif _dhcp_state = STATE_DHCP_LEASED; result = 1; @@ -151,8 +149,11 @@ _dhcp_state = STATE_DHCP_START; } - if(result != 1 && ((millis() - startTime) > _timeout)) + if(result != 1 && ((millis() - startTime) > DHCP_TIMEOUT)) break; + #if defined(ESP8266) + wdt_reset(); + #endif } // We're done with the socket now @@ -165,14 +166,14 @@ void DhcpClass::presend_DHCP(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::presend_DHCP(void) DEBUG_V1:Function started (Empty function)")); + LogObject.uart_send_strln(F("DhcpClass::presend_DHCP(void) DEBUG_V1:Function started (Empty function)")); #endif } void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed) DEBUG_V1:Function started")); #endif uint8_t buffer[32]; memset(buffer, 0, 32); @@ -258,17 +259,17 @@ { buffer[0] = dhcpRequestedIPaddr; buffer[1] = 0x04; - buffer[2] = _dhcpLocalIp[0]; - buffer[3] = _dhcpLocalIp[1]; - buffer[4] = _dhcpLocalIp[2]; - buffer[5] = _dhcpLocalIp[3]; + buffer[2] = _dhcpipv4struct.LocalIp[0]; + buffer[3] = _dhcpipv4struct.LocalIp[1]; + buffer[4] = _dhcpipv4struct.LocalIp[2]; + buffer[5] = _dhcpipv4struct.LocalIp[3]; buffer[6] = dhcpServerIdentifier; buffer[7] = 0x04; - buffer[8] = _dhcpDhcpServerIp[0]; - buffer[9] = _dhcpDhcpServerIp[1]; - buffer[10] = _dhcpDhcpServerIp[2]; - buffer[11] = _dhcpDhcpServerIp[3]; + buffer[8] = _dhcpipv4struct.DhcpServerIp[0]; + buffer[9] = _dhcpipv4struct.DhcpServerIp[1]; + buffer[10] = _dhcpipv4struct.DhcpServerIp[2]; + buffer[11] = _dhcpipv4struct.DhcpServerIp[3]; //put data in W5100 transmit buffer _dhcpUdpSocket.write(buffer, 12); @@ -290,10 +291,10 @@ _dhcpUdpSocket.endPacket(); } -uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) +uint8_t DhcpClass::parseDHCPResponse(uint32_t& transactionId) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::parseDHCPResponse(uint32_t& transactionId) DEBUG_V1:Function started")); #endif uint8_t type = 0; uint8_t opt_len = 0; @@ -302,7 +303,7 @@ while(_dhcpUdpSocket.parsePacket() <= 0) { - if((millis() - startTime) > responseTimeout) + if((millis() - startTime) > DHCP_RESPONSE_TIMEOUT) { return 255; } @@ -322,7 +323,7 @@ return 0; } - memcpy(_dhcpLocalIp, fixedMsg.yiaddr, 4); + memcpy(_dhcpipv4struct.LocalIp, fixedMsg.yiaddr, 4); // Skip to the option part // Doing this a byte at a time so we don't have to put a big buffer @@ -349,12 +350,12 @@ case subnetMask : opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((char*)_dhcpSubnetMask, 4); + _dhcpUdpSocket.read((char*)_dhcpipv4struct.SubnetMask, 4); break; case routersOnSubnet : opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((char*)_dhcpGatewayIp, 4); + _dhcpUdpSocket.read((char*)_dhcpipv4struct.GatewayIp, 4); for (int i = 0; i < opt_len-4; i++) { _dhcpUdpSocket.read(); @@ -363,7 +364,7 @@ case dns : opt_len = _dhcpUdpSocket.read(); - _dhcpUdpSocket.read((char*)_dhcpDnsServerIp, 4); + _dhcpUdpSocket.read((char*)_dhcpipv4struct.DnsServerIp, 4); for (int i = 0; i < opt_len-4; i++) { _dhcpUdpSocket.read(); @@ -372,10 +373,10 @@ case dhcpServerIdentifier : opt_len = _dhcpUdpSocket.read(); - if( IPAddress(_dhcpDhcpServerIp) == IPAddress(0,0,0,0) || - IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP() ) + if( IPAddress(_dhcpipv4struct.DhcpServerIp) == IPAddress(0,0,0,0) || + IPAddress(_dhcpipv4struct.DhcpServerIp) == _dhcpUdpSocket.remoteIP() ) { - _dhcpUdpSocket.read((char*)_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp)); + _dhcpUdpSocket.read((char*)_dhcpipv4struct.DhcpServerIp, sizeof(_dhcpipv4struct.DhcpServerIp)); } else { @@ -435,7 +436,7 @@ */ int DhcpClass::checkLease(void){ #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::checkLease(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::checkLease(void) DEBUG_V1:Function started")); #endif //this uses a signed / unsigned trick to deal with millis overflow @@ -493,46 +494,46 @@ IPAddress DhcpClass::getLocalIp(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::getLocalIp(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::getLocalIp(void) DEBUG_V1:Function started")); #endif - return IPAddress(_dhcpLocalIp); + return IPAddress(_dhcpipv4struct.LocalIp); } IPAddress DhcpClass::getSubnetMask(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::getSubnetMask(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::getSubnetMask(void) DEBUG_V1:Function started")); #endif - return IPAddress(_dhcpSubnetMask); + return IPAddress(_dhcpipv4struct.SubnetMask); } IPAddress DhcpClass::getGatewayIp(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::getGatewayIp(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::getGatewayIp(void) DEBUG_V1:Function started")); #endif - return IPAddress(_dhcpGatewayIp); + return IPAddress(_dhcpipv4struct.GatewayIp); } IPAddress DhcpClass::getDhcpServerIp(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::getDhcpServerIp(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::getDhcpServerIp(void) DEBUG_V1:Function started")); #endif - return IPAddress(_dhcpDhcpServerIp); + return IPAddress(_dhcpipv4struct.DhcpServerIp); } IPAddress DhcpClass::getDnsServerIp(void) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::getDnsServerIp(void) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::getDnsServerIp(void) DEBUG_V1:Function started")); #endif - return IPAddress(_dhcpDnsServerIp); + return IPAddress(_dhcpipv4struct.DnsServerIp); } void DhcpClass::printByte(char * buf, uint8_t n ) { #if ACTLOGLEVEL>=LOG_DEBUG_V1 - LogObject.uart_send_str(F("DhcpClass::printByte(char * buf, uint8_t n ) DEBUG_V1:Function started")); + LogObject.uart_send_strln(F("DhcpClass::printByte(char * buf, uint8_t n ) DEBUG_V1:Function started")); #endif char *str = &buf[1]; buf[0]='0';
--- a/Dhcp.h Wed Feb 22 13:40:36 2017 +0000 +++ b/Dhcp.h Mon Mar 27 22:31:01 2017 +0200 @@ -46,6 +46,8 @@ #define HOST_NAME "ENC28J" #define DEFAULT_LEASE (900) //default lease time in seconds +#define DHCP_TIMEOUT 60000 +#define DHCP_RESPONSE_TIMEOUT 4000 #define DHCP_CHECK_NONE (0) #define DHCP_CHECK_RENEW_FAIL (1) @@ -139,23 +141,26 @@ uint8_t chaddr[6]; }RIP_MSG_FIXED; +typedef struct +{ + uint8_t LocalIp[4]; + uint8_t SubnetMask[4]; + uint8_t GatewayIp[4]; + uint8_t DhcpServerIp[4]; + uint8_t DnsServerIp[4]; +} TIPV4Struct; + class DhcpClass { private: uint32_t _dhcpInitialTransactionId; uint32_t _dhcpTransactionId; uint8_t _dhcpMacAddr[6]; - uint8_t _dhcpLocalIp[4]; - uint8_t _dhcpSubnetMask[4]; - uint8_t _dhcpGatewayIp[4]; - uint8_t _dhcpDhcpServerIp[4]; - uint8_t _dhcpDnsServerIp[4]; + TIPV4Struct _dhcpipv4struct; uint32_t _dhcpLeaseTime; uint32_t _dhcpT1, _dhcpT2; signed long _renewInSec; signed long _rebindInSec; signed long _lastCheck; - unsigned long _timeout; - unsigned long _responseTimeout; unsigned long _secTimeout; uint8_t _dhcp_state; UIPUDP _dhcpUdpSocket; @@ -166,7 +171,7 @@ void send_DHCP_MESSAGE(uint8_t, uint16_t); void printByte(char *, uint8_t); - uint8_t parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId); + uint8_t parseDHCPResponse(uint32_t& transactionId); public: IPAddress getLocalIp(void); IPAddress getSubnetMask(void); @@ -174,7 +179,7 @@ IPAddress getDhcpServerIp(void); IPAddress getDnsServerIp(void); - int beginWithDHCP(uint8_t *, unsigned long timeout = 60000, unsigned long responseTimeout = 4000); + int beginWithDHCP(uint8_t *); int checkLease(void); }; #endif
--- a/README.md Wed Feb 22 13:40:36 2017 +0000 +++ b/README.md Mon Mar 27 22:31:01 2017 +0200 @@ -1,40 +1,43 @@ -# UIPEthernet -UIPEthernet library for Arduinos (Atmel AVR-s,Atmel SAM3X8E ARM Cortex-M3,STM32F series,ESP8266,Intel ARC32(Genuino101),Nordic nRF51(RFduino),Teensy boards,Realtek Ameba(RTL8195A,RTL8710)), ENC28j60 network chip compatible with Wiznet W5100 API - -Original UIPEthernet writed by Norbert Truchsess. - -You can find wiring diagram for more board in the hardware directory. - -Modifications: -- Replaced import to include, because gcc say 'import is deprecated'. -- Added support for STM32F, and ESP8266 MCU-s. -- Merged martinayotte's modification (Correct s_dhcp ~40K more memory usage with STM32F MCU-s.) -- Moved htons,ntohs,htonl,ntohl definitions to uip.h. -- Corrected infinite loops. -- Set the version to 2.0.3 -- Corrected ESP8266 exception(28). -- Added watchdog reset calls in functions for stable running on ESP8266. -- Added geterevid function to get ENC28j60 chip erevid (revision information). -- Changed linkStatus to static for outside call. -- Added functions bypass, if can't communicate with ethernet device. -- Changed debuging/logging. Remove individual debuging. Add global and scalable debuging feature. -You can setup debuging/logging level in utility/logging.h -You can use this header file in Your scetch too. -Add "LogObject" define for serial logging/debuging with board specific default setting. -- Added support to MBED/SMeshStudio IDE. (Compiled and tested on Nucleo-F302R8. (STM32F302R8)) - -- Added Abstract Print class to MBED for full compatibility (Can use print, println with uip objects.) -- Errata#12 corrected (by seydamir). -- Created v2.0.2 release. - -If You use NodeMCU please check wiring first: -https://github.com/UIPEthernet/UIPEthernet/blob/master/hardware/NodeMCU_enc28j60_wiring.PNG - -- You can save 5K flash if you disable UDP support. -- Correction code of Errata#12 modified. -- Added support for Intel ARC32(Genuino101), Nordic nRF51(RFduino), Teensy boards -- Issue#4 corrected -- Added support for Realtek Ameba(RTL8195A,RTL8710) -- Added support Eclipse with arduino plugin -- Added direct broadcast support - +# UIPEthernet +UIPEthernet library for Arduinos (Atmel AVR-s,Atmel SAM3X8E ARM Cortex-M3,STM32F series,ESP8266,Intel ARC32(Genuino101),Nordic nRF51(RFduino),Teensy boards,Realtek Ameba(RTL8195A,RTL8710)), ENC28j60 network chip compatible with Wiznet W5100 API + +Original UIPEthernet writed by Norbert Truchsess. + +You can find wiring diagram for more board in the hardware directory. + +Modifications: +- Replaced import to include, because gcc say 'import is deprecated'. +- Added support for STM32F, and ESP8266 MCU-s. +- Merged martinayotte's modification (Correct s_dhcp ~40K more memory usage with STM32F MCU-s.) +- Moved htons,ntohs,htonl,ntohl definitions to uip.h. +- Corrected infinite loops. +- Set the version to 2.0.3 +- Corrected ESP8266 exception(28). +- Added watchdog reset calls in functions for stable running on ESP8266. +- Added geterevid function to get ENC28j60 chip erevid (revision information). +- Changed linkStatus to static for outside call. +- Added functions bypass, if can't communicate with ethernet device. +- Changed debuging/logging. Remove individual debuging. Add global and scalable debuging feature. +You can setup debuging/logging level in utility/logging.h +You can use this header file in Your scetch too. +Add "LogObject" define for serial logging/debuging with board specific default setting. +- Added support to MBED/SMeshStudio IDE. (Compiled and tested on Nucleo-F302R8. (STM32F302R8)) + +- Added Abstract Print class to MBED for full compatibility (Can use print, println with uip objects.) +- Errata#12 corrected (by seydamir). +- Created v2.0.2 release. + +If You use NodeMCU please check wiring first: +https://github.com/UIPEthernet/UIPEthernet/blob/master/hardware/NodeMCU_enc28j60_wiring.PNG + +- You can save 5K flash if you disable UDP support. +- Correction code of Errata#12 modified. +- Added support for Intel ARC32(Genuino101), Nordic nRF51(RFduino), Teensy boards +- Issue#4 corrected +- Added support for Realtek Ameba(RTL8195A,RTL8710) +- Added direct broadcast support +- Issue#5 corrected: You can save 5K flash memory with disable UDP support. +- Issue#6 corrected: Added support Eclipse with arduino plugin +- Issue#8, and Issue#9 corrected: Modified DHCP code: Moved timeouts define to dhcp.h +- Issue#11 corrected: Changed ENC28J60_CONTROL_CS pin to 10 on Arduino Due +- New release:2.0.4
--- a/library.json Wed Feb 22 13:40:36 2017 +0000 +++ b/library.json Mon Mar 27 22:31:01 2017 +0200 @@ -16,9 +16,9 @@ "maintainer": true } ], - "version": "2.0.3", + "version": "2.0.4", "frameworks": "arduino, mbed", - "platforms": "atmelavr, atmelsam, espressif8266", + "platforms": "atmelavr, atmelsam, espressif8266, intel_arc32, nordicnrf51, nxplpc, ststm32, teensy", "export": { "exclude": [
--- a/library.properties Wed Feb 22 13:40:36 2017 +0000 +++ b/library.properties Mon Mar 27 22:31:01 2017 +0200 @@ -6,7 +6,7 @@ paragraph=implements the same API as stock Ethernet-lib. Just replace the include of Ethernet.h with UIPEthernet.h url=https://github.com/UIPEthernet/UIPEthernet category=Communication -version=2.0.3 +version=2.0.4 dependencies= core-dependencies=arduino (>=1.5.0) includes=UIPEthernet.h,utility/logging.h
--- a/utility/Enc28J60Network.h Wed Feb 22 13:40:36 2017 +0000 +++ b/utility/Enc28J60Network.h Mon Mar 27 22:31:01 2017 +0200 @@ -80,7 +80,8 @@ #define ENC28J60_CONTROL_CS SS //PC_0 A5 10 #elif defined(ARDUINO_ARCH_SAM) // Arduino Due (ARDUINO_ARCH_SAM) BOARD_SPI_DEFAULT_SS (SS3) defined to pin 78 - #define ENC28J60_CONTROL_CS BOARD_SPI_DEFAULT_SS + //#define ENC28J60_CONTROL_CS BOARD_SPI_DEFAULT_SS + #define ENC28J60_CONTROL_CS BOARD_SPI_SS0 #elif defined(__ARDUINO_ARC__) //Intel ARC32 Genuino 101 #define ENC28J60_CONTROL_CS SS #elif defined(__RFduino__) //RFduino