Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2016-12-17 19:58:27 +0300
committerDavid Crocker <dcrocker@eschertech.com>2016-12-17 19:58:27 +0300
commitda3d67403f756c749deb175f209a6d964720a4c7 (patch)
tree2c607f327c28e8b1d377f3077a43c397432a9519 /src
parentf7aa7304b8405196fee03b3782ecfa74111a5d25 (diff)
1.17RC1+2
Changes for Duet Ethernet Changes RADDS Pins.h to support 2 SD cards
Diffstat (limited to 'src')
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Client.h45
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp520
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h179
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp422
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Dns.h41
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp194
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h62
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp167
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h39
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp91
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h22
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp271
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h106
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/README.md54
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Server.h30
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp74
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Twitter.h35
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/Udp.h88
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp425
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h24
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp413
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h48
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/util.h42
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp153
-rw-r--r--src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h443
-rw-r--r--src/DuetNG/DuetEthernet/Network.cpp157
-rw-r--r--src/DuetNG/DuetEthernet/Network.h44
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.c267
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp165
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h929
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.c912
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.cpp726
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.c792
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.cpp455
-rw-r--r--src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.h279
-rw-r--r--src/DuetNG/DuetWiFi/Network.cpp1
-rw-r--r--src/DuetNG/DuetWiFi/Network.h5
-rw-r--r--src/GCodes/GCodes2.cpp4
-rw-r--r--src/Platform.cpp2
-rw-r--r--src/Platform.h4
-rw-r--r--src/RADDS/Pins_radds.h8
41 files changed, 6094 insertions, 2644 deletions
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Client.h b/src/DuetNG/DuetEthernet/Ethernet3/Client.h
new file mode 100644
index 00000000..b8e5d935
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Client.h
@@ -0,0 +1,45 @@
+/*
+ Client.h - Base class that provides Client
+ Copyright (c) 2011 Adrian McEwen. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef client_h
+#define client_h
+#include "Print.h"
+#include "Stream.h"
+#include "IPAddress.h"
+
+class Client : public Stream {
+
+public:
+ virtual int connect(IPAddress ip, uint16_t port) =0;
+ virtual int connect(const char *host, uint16_t port) =0;
+ virtual size_t write(uint8_t) =0;
+ virtual size_t write(const uint8_t *buf, size_t size) =0;
+ virtual int available() = 0;
+ virtual int read() = 0;
+ virtual int read(uint8_t *buf, size_t size) = 0;
+ virtual int peek() = 0;
+ virtual void flush() = 0;
+ virtual void stop() = 0;
+ virtual uint8_t connected() = 0;
+ virtual operator bool() = 0;
+protected:
+ uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp
new file mode 100644
index 00000000..8b4cc219
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.cpp
@@ -0,0 +1,520 @@
+// DHCP Library v0.3 - April 25, 2009
+// Author: Jordan Terrell - blog.jordanterrell.com
+
+#include "utility/w5500.h"
+
+#include <cstring>
+#include <cstdlib>
+#include "Dhcp.h"
+#include "Core.h"
+#include "utility/util.h"
+
+extern "C" void debugPrintf(const char *fmt, ...);
+
+int DhcpClass::beginWithDHCP(const uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
+{
+ _dhcpLeaseTime=0;
+ _dhcpT1=0;
+ _dhcpT2=0;
+ _lastCheck=0;
+ _timeout = timeout;
+ _responseTimeout = responseTimeout;
+
+ reset_DHCP_lease();
+ memcpy(_dhcpMacAddr, mac, sizeof(_dhcpMacAddr));
+ _dhcp_state = STATE_DHCP_START;
+ return request_DHCP_lease();
+}
+
+void DhcpClass::reset_DHCP_lease(){
+ // zero out _dhcpSubnetMask, _dhcpGatewayIp, _dhcpLocalIp, _dhcpDhcpServerIp, _dhcpDnsServerIp
+ memset(_dhcpLocalIp, 0, sizeof(_dhcpLocalIp));
+ memset(_dhcpSubnetMask, 0, sizeof(_dhcpSubnetMask));
+ memset(_dhcpGatewayIp, 0, sizeof(_dhcpGatewayIp));
+ memset(_dhcpDhcpServerIp, 0, sizeof(_dhcpDhcpServerIp));
+ memset(_dhcpDnsServerIp, 0, sizeof(_dhcpDnsServerIp));
+}
+
+//return:0 on error, 1 if request is sent and response is received
+int DhcpClass::request_DHCP_lease()
+{
+ // Pick an initial transaction ID
+ _dhcpTransactionId = random(1UL, 2000UL);
+ _dhcpInitialTransactionId = _dhcpTransactionId;
+
+ _dhcpUdpSocket.stop();
+ if (_dhcpUdpSocket.begin(DHCP_CLIENT_PORT) == 0)
+ {
+ return 0; // Couldn't get a socket
+ }
+
+ presend_DHCP();
+
+ const unsigned long startTime = millis();
+ bool hadError = false;
+ while(_dhcp_state != STATE_DHCP_LEASED && !hadError && (millis() - startTime) < _timeout)
+ {
+#if 1
+ {
+ uint8_t tmp = w5500.readPHYCFGR();
+ uint8_t version = w5500.readVERSIONR();
+ uint8_t macBuf[6];
+ w5500.readSHAR(macBuf);
+ debugPrintf("Phy %02x ver %02x Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
+ tmp, version, macBuf[0], macBuf[1], macBuf[2], macBuf[3], macBuf[4], macBuf[5]);
+ }
+#endif
+ switch (_dhcp_state)
+ {
+ case STATE_DHCP_START:
+ debugPrintf("DHCP_START\n");
+ _dhcpTransactionId++;
+ send_DHCP_MESSAGE(DHCP_DISCOVER, ((millis() - startTime) / 1000));
+ _dhcp_state = STATE_DHCP_DISCOVER;
+ break;
+
+ case STATE_DHCP_DISCOVER:
+ {
+ debugPrintf("DHCP_DISCOVER\n");
+ uint32_t respId;
+ const uint8_t messageType = parseDHCPResponse(_responseTimeout, respId);
+ if (messageType == DHCP_OFFER)
+ {
+ // We'll use the transaction ID that the offer came with, rather than the one we were up to
+ _dhcpTransactionId = respId;
+ send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime) / 1000));
+ _dhcp_state = STATE_DHCP_REQUEST;
+ }
+ else if (messageType == 255)
+ {
+ _dhcp_state = STATE_DHCP_START;
+// hadError = true;
+ }
+ }
+ break;
+
+ case STATE_DHCP_REQUEST:
+ {
+ debugPrintf("DHCP_REQUEST\n");
+ uint32_t respId;
+ const uint8_t messageType = parseDHCPResponse(_responseTimeout, respId);
+ if (messageType == DHCP_ACK)
+ {
+ _dhcp_state = STATE_DHCP_LEASED;
+ debugPrintf("DHCP_LEASED\n");
+ //use default lease time if we didn't get it
+ if (_dhcpLeaseTime == 0)
+ {
+ _dhcpLeaseTime = DEFAULT_LEASE;
+ }
+ //calculate T1 & T2 if we didn't get it
+ if (_dhcpT1 == 0)
+ {
+ //T1 should be 50% of _dhcpLeaseTime
+ _dhcpT1 = _dhcpLeaseTime >> 1;
+ }
+ if (_dhcpT2 == 0)
+ {
+ //T2 should be 87.5% (7/8ths) of _dhcpLeaseTime
+ _dhcpT2 = _dhcpT1 << 1;
+ }
+ _renewInSec = _dhcpT1;
+ _rebindInSec = _dhcpT2;
+ }
+ else if (messageType == DHCP_NAK)
+ {
+ _dhcp_state = STATE_DHCP_START;
+ }
+ else if (messageType == 255)
+ {
+ _dhcp_state = STATE_DHCP_START;
+// hadError = true;
+ }
+ }
+ break;
+
+ case STATE_DHCP_REREQUEST:
+ debugPrintf("DHCP_REREQUEST\n");
+ _dhcpTransactionId++;
+ send_DHCP_MESSAGE(DHCP_REQUEST, ((millis() - startTime)/1000));
+ _dhcp_state = STATE_DHCP_REQUEST;
+ break;
+
+ default:
+ debugPrintf("Bad DHCP state\n");
+ _dhcp_state = STATE_DHCP_START;
+ hadError = true;
+ }
+ }
+
+ // We're done with the socket now
+ _dhcpUdpSocket.stop();
+ _dhcpTransactionId++;
+
+ return (_dhcp_state == STATE_DHCP_LEASED) ? 1 : 0;
+}
+
+void DhcpClass::presend_DHCP()
+{
+}
+
+void DhcpClass::send_DHCP_MESSAGE(uint8_t messageType, uint16_t secondsElapsed)
+{
+ uint8_t buffer[32];
+ memset(buffer, 0, 32);
+ IPAddress dest_addr( 255, 255, 255, 255 ); // Broadcast address
+
+ if (-1 == _dhcpUdpSocket.beginPacket(dest_addr, DHCP_SERVER_PORT))
+ {
+ // FIXME Need to return errors
+ debugPrintf("Begin packet failed\n");
+ return;
+ }
+
+ buffer[0] = DHCP_BOOTREQUEST; // op
+ buffer[1] = DHCP_HTYPE10MB; // htype
+ buffer[2] = DHCP_HLENETHERNET; // hlen
+ buffer[3] = DHCP_HOPS; // hops
+
+ // xid
+ unsigned long xid = htonl(_dhcpTransactionId);
+ memcpy(buffer + 4, &(xid), 4);
+
+ // 8, 9 - seconds elapsed
+ buffer[8] = ((secondsElapsed & 0xff00) >> 8);
+ buffer[9] = (secondsElapsed & 0x00ff);
+
+ // flags
+ unsigned short flags = htons(DHCP_FLAGSBROADCAST);
+ memcpy(buffer + 10, &(flags), 2);
+
+ // ciaddr: already zeroed
+ // yiaddr: already zeroed
+ // siaddr: already zeroed
+ // giaddr: already zeroed
+
+ //put data in w5500 transmit buffer
+ _dhcpUdpSocket.write(buffer, 28);
+
+ memset(buffer, 0, 32); // clear local buffer
+
+ memcpy(buffer, _dhcpMacAddr, 6); // chaddr
+
+ //put data in w5500 transmit buffer
+ _dhcpUdpSocket.write(buffer, 16);
+
+ memset(buffer, 0, 32); // clear local buffer
+
+ // leave zeroed out for sname && file
+ // put in w5500 transmit buffer x 6 (192 bytes)
+
+ for (int i = 0; i < 6; i++)
+ {
+ _dhcpUdpSocket.write(buffer, 32);
+ }
+
+ // OPT - Magic Cookie
+ buffer[0] = (uint8_t)((MAGIC_COOKIE >> 24)& 0xFF);
+ buffer[1] = (uint8_t)((MAGIC_COOKIE >> 16)& 0xFF);
+ buffer[2] = (uint8_t)((MAGIC_COOKIE >> 8)& 0xFF);
+ buffer[3] = (uint8_t)(MAGIC_COOKIE& 0xFF);
+
+ // OPT - message type
+ buffer[4] = dhcpMessageType;
+ buffer[5] = 0x01;
+ buffer[6] = messageType; //DHCP_REQUEST;
+
+ // OPT - client identifier
+ buffer[7] = dhcpClientIdentifier;
+ buffer[8] = 0x07;
+ buffer[9] = 0x01;
+ memcpy(buffer + 10, _dhcpMacAddr, 6);
+
+ // OPT - host name
+ buffer[16] = hostName;
+ buffer[17] = strlen(HOST_NAME) + 6; // length of hostname + last 3 bytes of mac address
+ strcpy((char*)&(buffer[18]), HOST_NAME);
+
+ printByte((char*)&(buffer[24]), _dhcpMacAddr[3]);
+ printByte((char*)&(buffer[26]), _dhcpMacAddr[4]);
+ printByte((char*)&(buffer[28]), _dhcpMacAddr[5]);
+
+ //put data in w5500 transmit buffer
+ _dhcpUdpSocket.write(buffer, 30);
+
+ if(messageType == DHCP_REQUEST)
+ {
+ buffer[0] = dhcpRequestedIPaddr;
+ buffer[1] = 0x04;
+ buffer[2] = _dhcpLocalIp[0];
+ buffer[3] = _dhcpLocalIp[1];
+ buffer[4] = _dhcpLocalIp[2];
+ buffer[5] = _dhcpLocalIp[3];
+
+ buffer[6] = dhcpServerIdentifier;
+ buffer[7] = 0x04;
+ buffer[8] = _dhcpDhcpServerIp[0];
+ buffer[9] = _dhcpDhcpServerIp[1];
+ buffer[10] = _dhcpDhcpServerIp[2];
+ buffer[11] = _dhcpDhcpServerIp[3];
+
+ //put data in w5500 transmit buffer
+ _dhcpUdpSocket.write(buffer, 12);
+ }
+
+ buffer[0] = dhcpParamRequest;
+ buffer[1] = 0x06;
+ buffer[2] = subnetMask;
+ buffer[3] = routersOnSubnet;
+ buffer[4] = dns;
+ buffer[5] = domainName;
+ buffer[6] = dhcpT1value;
+ buffer[7] = dhcpT2value;
+ buffer[8] = endOption;
+
+ //put data in w5500 transmit buffer
+ _dhcpUdpSocket.write(buffer, 9);
+
+ _dhcpUdpSocket.endPacket();
+}
+
+uint8_t DhcpClass::parseDHCPResponse(unsigned long responseTimeout, uint32_t& transactionId)
+{
+ uint8_t type = 0;
+ uint8_t opt_len = 0;
+
+ const unsigned long startTime = millis();
+
+ while(_dhcpUdpSocket.parsePacket() <= 0)
+ {
+ if ((millis() - startTime) > responseTimeout)
+ {
+ debugPrintf("Response timed out\n");
+ return 255;
+ }
+ delay(50);
+ }
+
+ // start reading in the packet
+ RIP_MSG_FIXED fixedMsg;
+ _dhcpUdpSocket.read((uint8_t*)&fixedMsg, sizeof(RIP_MSG_FIXED));
+
+ if (fixedMsg.op == DHCP_BOOTREPLY && _dhcpUdpSocket.remotePort() == DHCP_SERVER_PORT)
+ {
+ transactionId = ntohl(fixedMsg.xid);
+ if(memcmp(fixedMsg.chaddr, _dhcpMacAddr, 6) != 0 || (transactionId < _dhcpInitialTransactionId) || (transactionId > _dhcpTransactionId))
+ {
+ // Need to read the rest of the packet here regardless
+ _dhcpUdpSocket.flush();
+ return 0;
+ }
+
+ memcpy(_dhcpLocalIp, 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
+ // on the stack (as we don't have lots of memory lying around)
+ for (int i =0; i < (240 - (int)sizeof(RIP_MSG_FIXED)); i++)
+ {
+ _dhcpUdpSocket.read(); // we don't care about the returned byte
+ }
+
+ while (_dhcpUdpSocket.available() > 0)
+ {
+ switch (_dhcpUdpSocket.read())
+ {
+ case endOption :
+
+ break;
+
+ case padOption :
+
+ break;
+
+ case dhcpMessageType :
+
+ opt_len = _dhcpUdpSocket.read();
+ type = _dhcpUdpSocket.read();
+ break;
+
+ case subnetMask :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read(_dhcpSubnetMask, 4);
+ break;
+
+ case routersOnSubnet :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read(_dhcpGatewayIp, 4);
+ for (int i = 0; i < opt_len-4; i++)
+ {
+ _dhcpUdpSocket.read();
+ }
+ break;
+
+ case dns :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read(_dhcpDnsServerIp, 4);
+ for (int i = 0; i < opt_len-4; i++)
+ {
+ _dhcpUdpSocket.read();
+ }
+ break;
+
+ case dhcpServerIdentifier :
+
+ opt_len = _dhcpUdpSocket.read();
+ if(((_dhcpDhcpServerIp[0] == 0) && (_dhcpDhcpServerIp[1] == 0) && (_dhcpDhcpServerIp[2] == 0) && (_dhcpDhcpServerIp[3] == 0)) || (IPAddress(_dhcpDhcpServerIp) == _dhcpUdpSocket.remoteIP()))
+ {
+ _dhcpUdpSocket.read(_dhcpDhcpServerIp, sizeof(_dhcpDhcpServerIp));
+ }
+ else
+ {
+ // Skip over the rest of this option
+ while (opt_len--)
+ {
+ _dhcpUdpSocket.read();
+ }
+ }
+ break;
+
+ case dhcpT1value :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT1, sizeof(_dhcpT1));
+ _dhcpT1 = ntohl(_dhcpT1);
+ break;
+
+ case dhcpT2value :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpT2, sizeof(_dhcpT2));
+ _dhcpT2 = ntohl(_dhcpT2);
+ break;
+
+ case dhcpIPaddrLeaseTime :
+
+ opt_len = _dhcpUdpSocket.read();
+ _dhcpUdpSocket.read((uint8_t*)&_dhcpLeaseTime, sizeof(_dhcpLeaseTime));
+ _dhcpLeaseTime = ntohl(_dhcpLeaseTime);
+ _renewInSec = _dhcpLeaseTime;
+ break;
+
+ default :
+
+ opt_len = _dhcpUdpSocket.read();
+ // Skip over the rest of this option
+ while (opt_len--)
+ {
+ _dhcpUdpSocket.read();
+ }
+ break;
+ }
+ }
+ }
+
+ // Need to skip to end of the packet regardless here
+ _dhcpUdpSocket.flush();
+
+ return type;
+}
+
+
+/*
+ returns:
+ 0/DHCP_CHECK_NONE: nothing happened
+ 1/DHCP_CHECK_RENEW_FAIL: renew failed
+ 2/DHCP_CHECK_RENEW_OK: renew success
+ 3/DHCP_CHECK_REBIND_FAIL: rebind fail
+ 4/DHCP_CHECK_REBIND_OK: rebind success
+*/
+int DhcpClass::checkLease(){
+ //this uses a signed / unsigned trick to deal with millis overflow
+ unsigned long now = millis();
+ signed long snow = (long)now;
+ int rc=DHCP_CHECK_NONE;
+ if (_lastCheck != 0){
+ signed long factor;
+ //calc how many ms past the timeout we are
+ factor = snow - (long)_secTimeout;
+ //if on or passed the timeout, reduce the counters
+ if ( factor >= 0 ){
+ //next timeout should be now plus 1000 ms minus parts of second in factor
+ _secTimeout = snow + 1000 - factor % 1000;
+ //how many seconds late are we, minimum 1
+ factor = factor / 1000 +1;
+
+ //reduce the counters by that mouch
+ //if we can assume that the cycle time (factor) is fairly constant
+ //and if the remainder is less than cycle time * 2
+ //do it early instead of late
+ if(_renewInSec < factor*2 )
+ _renewInSec = 0;
+ else
+ _renewInSec -= factor;
+
+ if(_rebindInSec < factor*2 )
+ _rebindInSec = 0;
+ else
+ _rebindInSec -= factor;
+ }
+
+ //if we have a lease but should renew, do it
+ if (_dhcp_state == STATE_DHCP_LEASED && _renewInSec <=0){
+ _dhcp_state = STATE_DHCP_REREQUEST;
+ rc = 1 + request_DHCP_lease();
+ }
+
+ //if we have a lease or is renewing but should bind, do it
+ if( (_dhcp_state == STATE_DHCP_LEASED || _dhcp_state == STATE_DHCP_START) && _rebindInSec <=0){
+ //this should basically restart completely
+ _dhcp_state = STATE_DHCP_START;
+ reset_DHCP_lease();
+ rc = 3 + request_DHCP_lease();
+ }
+ }
+ else{
+ _secTimeout = snow + 1000;
+ }
+
+ _lastCheck = now;
+ return rc;
+}
+
+IPAddress DhcpClass::getLocalIp()
+{
+ return IPAddress(_dhcpLocalIp);
+}
+
+IPAddress DhcpClass::getSubnetMask()
+{
+ return IPAddress(_dhcpSubnetMask);
+}
+
+IPAddress DhcpClass::getGatewayIp()
+{
+ return IPAddress(_dhcpGatewayIp);
+}
+
+IPAddress DhcpClass::getDhcpServerIp()
+{
+ return IPAddress(_dhcpDhcpServerIp);
+}
+
+IPAddress DhcpClass::getDnsServerIp()
+{
+ return IPAddress(_dhcpDnsServerIp);
+}
+
+void DhcpClass::printByte(char * buf, uint8_t n ) {
+ char *str = &buf[1];
+ buf[0]='0';
+ do {
+ unsigned long m = n;
+ n /= 16;
+ char c = m - 16 * n;
+ *str-- = c < 10 ? c + '0' : c + 'A' - 10;
+ } while(n);
+}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h
new file mode 100644
index 00000000..8deebdd8
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Dhcp.h
@@ -0,0 +1,179 @@
+// DHCP Library v0.3 - April 25, 2009
+// Author: Jordan Terrell - blog.jordanterrell.com
+
+#ifndef Dhcp_h
+#define Dhcp_h
+
+#include "EthernetUdp3.h"
+
+/* DHCP state machine. */
+#define STATE_DHCP_START 0
+#define STATE_DHCP_DISCOVER 1
+#define STATE_DHCP_REQUEST 2
+#define STATE_DHCP_LEASED 3
+#define STATE_DHCP_REREQUEST 4
+#define STATE_DHCP_RELEASE 5
+
+#define DHCP_FLAGSBROADCAST 0x8000
+
+/* UDP port numbers for DHCP */
+#define DHCP_SERVER_PORT 67 /* from server to client */
+#define DHCP_CLIENT_PORT 68 /* from client to server */
+
+/* DHCP message OP code */
+#define DHCP_BOOTREQUEST 1
+#define DHCP_BOOTREPLY 2
+
+/* DHCP message type */
+#define DHCP_DISCOVER 1
+#define DHCP_OFFER 2
+#define DHCP_REQUEST 3
+#define DHCP_DECLINE 4
+#define DHCP_ACK 5
+#define DHCP_NAK 6
+#define DHCP_RELEASE 7
+#define DHCP_INFORM 8
+
+#define DHCP_HTYPE10MB 1
+#define DHCP_HTYPE100MB 2
+
+#define DHCP_HLENETHERNET 6
+#define DHCP_HOPS 0
+#define DHCP_SECS 0
+
+#define MAGIC_COOKIE 0x63825363
+#define MAX_DHCP_OPT 16
+
+#define HOST_NAME "WIZnet"
+#define DEFAULT_LEASE (900) //default lease time in seconds
+
+#define DHCP_CHECK_NONE (0)
+#define DHCP_CHECK_RENEW_FAIL (1)
+#define DHCP_CHECK_RENEW_OK (2)
+#define DHCP_CHECK_REBIND_FAIL (3)
+#define DHCP_CHECK_REBIND_OK (4)
+
+enum
+{
+ padOption = 0,
+ subnetMask = 1,
+ timerOffset = 2,
+ routersOnSubnet = 3,
+ /* timeServer = 4,
+ nameServer = 5,*/
+ dns = 6,
+ /*logServer = 7,
+ cookieServer = 8,
+ lprServer = 9,
+ impressServer = 10,
+ resourceLocationServer = 11,*/
+ hostName = 12,
+ /*bootFileSize = 13,
+ meritDumpFile = 14,*/
+ domainName = 15,
+ /*swapServer = 16,
+ rootPath = 17,
+ extentionsPath = 18,
+ IPforwarding = 19,
+ nonLocalSourceRouting = 20,
+ policyFilter = 21,
+ maxDgramReasmSize = 22,
+ defaultIPTTL = 23,
+ pathMTUagingTimeout = 24,
+ pathMTUplateauTable = 25,
+ ifMTU = 26,
+ allSubnetsLocal = 27,
+ broadcastAddr = 28,
+ performMaskDiscovery = 29,
+ maskSupplier = 30,
+ performRouterDiscovery = 31,
+ routerSolicitationAddr = 32,
+ staticRoute = 33,
+ trailerEncapsulation = 34,
+ arpCacheTimeout = 35,
+ ethernetEncapsulation = 36,
+ tcpDefaultTTL = 37,
+ tcpKeepaliveInterval = 38,
+ tcpKeepaliveGarbage = 39,
+ nisDomainName = 40,
+ nisServers = 41,
+ ntpServers = 42,
+ vendorSpecificInfo = 43,
+ netBIOSnameServer = 44,
+ netBIOSdgramDistServer = 45,
+ netBIOSnodeType = 46,
+ netBIOSscope = 47,
+ xFontServer = 48,
+ xDisplayManager = 49,*/
+ dhcpRequestedIPaddr = 50,
+ dhcpIPaddrLeaseTime = 51,
+ /*dhcpOptionOverload = 52,*/
+ dhcpMessageType = 53,
+ dhcpServerIdentifier = 54,
+ dhcpParamRequest = 55,
+ /*dhcpMsg = 56,
+ dhcpMaxMsgSize = 57,*/
+ dhcpT1value = 58,
+ dhcpT2value = 59,
+ /*dhcpClassIdentifier = 60,*/
+ dhcpClientIdentifier = 61,
+ endOption = 255
+};
+
+typedef struct _RIP_MSG_FIXED
+{
+ uint8_t op;
+ uint8_t htype;
+ uint8_t hlen;
+ uint8_t hops;
+ uint32_t xid;
+ uint16_t secs;
+ uint16_t flags;
+ uint8_t ciaddr[4];
+ uint8_t yiaddr[4];
+ uint8_t siaddr[4];
+ uint8_t giaddr[4];
+ uint8_t chaddr[6];
+}RIP_MSG_FIXED;
+
+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];
+ 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;
+ 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(const uint8_t *macAddress, unsigned long timeout, unsigned long responseTimeout);
+ int checkLease();
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp
new file mode 100644
index 00000000..d55fad8b
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Dns.cpp
@@ -0,0 +1,422 @@
+// Arduino DNS client for WizNet5100-based Ethernet shield
+// (c) Copyright 2009-2010 MCQN Ltd.
+// Released under Apache License, version 2.0
+
+#include "utility/w5500.h"
+#include "EthernetUdp3.h"
+#include "utility/util.h"
+
+#include "Dns.h"
+#include <cstring>
+#include "Core.h"
+
+
+#define SOCKET_NONE 255
+// Various flags and header field values for a DNS message
+#define UDP_HEADER_SIZE 8
+#define DNS_HEADER_SIZE 12
+#define TTL_SIZE 4
+#define QUERY_FLAG (0)
+#define RESPONSE_FLAG (1<<15)
+#define QUERY_RESPONSE_MASK (1<<15)
+#define OPCODE_STANDARD_QUERY (0)
+#define OPCODE_INVERSE_QUERY (1<<11)
+#define OPCODE_STATUS_REQUEST (2<<11)
+#define OPCODE_MASK (15<<11)
+#define AUTHORITATIVE_FLAG (1<<10)
+#define TRUNCATION_FLAG (1<<9)
+#define RECURSION_DESIRED_FLAG (1<<8)
+#define RECURSION_AVAILABLE_FLAG (1<<7)
+#define RESP_NO_ERROR (0)
+#define RESP_FORMAT_ERROR (1)
+#define RESP_SERVER_FAILURE (2)
+#define RESP_NAME_ERROR (3)
+#define RESP_NOT_IMPLEMENTED (4)
+#define RESP_REFUSED (5)
+#define RESP_MASK (15)
+#define TYPE_A (0x0001)
+#define CLASS_IN (0x0001)
+#define LABEL_COMPRESSION_MASK (0xC0)
+// Port number that DNS servers listen on
+#define DNS_PORT 53
+
+// Possible return codes from ProcessResponse
+#define SUCCESS 1
+#define TIMED_OUT -1
+#define INVALID_SERVER -2
+#define TRUNCATED -3
+#define INVALID_RESPONSE -4
+
+void DNSClient::begin(const IPAddress& aDNSServer)
+{
+ iDNSServer = aDNSServer;
+ iRequestId = 0;
+}
+
+
+int DNSClient::inet_aton(const char* aIPAddrString, IPAddress& aResult)
+{
+ // See if we've been given a valid IP address
+ const char* p =aIPAddrString;
+ while (*p &&
+ ( (*p == '.') || (*p >= '0') || (*p <= '9') ))
+ {
+ p++;
+ }
+
+ if (*p == '\0')
+ {
+ // It's looking promising, we haven't found any invalid characters
+ p = aIPAddrString;
+ int segment =0;
+ int segmentValue =0;
+ while (*p && (segment < 4))
+ {
+ if (*p == '.')
+ {
+ // We've reached the end of a segment
+ if (segmentValue > 255)
+ {
+ // You can't have IP address segments that don't fit in a byte
+ return 0;
+ }
+ else
+ {
+ aResult[segment] = (byte)segmentValue;
+ segment++;
+ segmentValue = 0;
+ }
+ }
+ else
+ {
+ // Next digit
+ segmentValue = (segmentValue*10)+(*p - '0');
+ }
+ p++;
+ }
+ // We've reached the end of address, but there'll still be the last
+ // segment to deal with
+ if ((segmentValue > 255) || (segment > 3))
+ {
+ // You can't have IP address segments that don't fit in a byte,
+ // or more than four segments
+ return 0;
+ }
+ else
+ {
+ aResult[segment] = (byte)segmentValue;
+ return 1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int DNSClient::getHostByName(const char* aHostname, IPAddress& aResult)
+{
+ int ret =0;
+
+ // See if it's a numeric IP address
+ if (inet_aton(aHostname, aResult))
+ {
+ // It is, our work here is done
+ return 1;
+ }
+
+ // Check we've got a valid DNS server to use
+ if (iDNSServer == INADDR_NONE)
+ {
+ return INVALID_SERVER;
+ }
+
+ // Find a socket to use
+ if (iUdp.begin(1024+(millis() & 0xF)) == 1)
+ {
+ // Try up to three times
+ int retries = 0;
+// while ((retries < 3) && (ret <= 0))
+ {
+ // Send DNS request
+ ret = iUdp.beginPacket(iDNSServer, DNS_PORT);
+ if (ret != 0)
+ {
+ // Now output the request data
+ ret = BuildRequest(aHostname);
+ if (ret != 0)
+ {
+ // And finally send the request
+ ret = iUdp.endPacket();
+ if (ret != 0)
+ {
+ // Now wait for a response
+ int wait_retries = 0;
+ ret = TIMED_OUT;
+ while ((wait_retries < 3) && (ret == TIMED_OUT))
+ {
+ ret = ProcessResponse(5000, aResult);
+ wait_retries++;
+ }
+ }
+ }
+ }
+ retries++;
+ }
+
+ // We're done with the socket now
+ iUdp.stop();
+ }
+
+ return ret;
+}
+
+uint16_t DNSClient::BuildRequest(const char* aName)
+{
+ // Build header
+ // 1 1 1 1 1 1
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // | ID |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // | QDCOUNT |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // | ANCOUNT |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // | NSCOUNT |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // | ARCOUNT |
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // As we only support one request at a time at present, we can simplify
+ // some of this header
+ iRequestId = millis(); // generate a random ID
+ uint16_t twoByteBuffer;
+
+ // FIXME We should also check that there's enough space available to write to, rather
+ // FIXME than assume there's enough space (as the code does at present)
+ iUdp.write((uint8_t*)&iRequestId, sizeof(iRequestId));
+
+ twoByteBuffer = htons((uint16_t)(QUERY_FLAG | OPCODE_STANDARD_QUERY | RECURSION_DESIRED_FLAG));
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+
+ twoByteBuffer = htons(1); // One question record
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+
+ twoByteBuffer = 0; // Zero answer records
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+ // and zero additional records
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+
+ // Build question
+ const char* start =aName;
+ const char* end =start;
+ uint8_t len;
+ // Run through the name being requested
+ while (*end)
+ {
+ // Find out how long this section of the name is
+ end = start;
+ while (*end && (*end != '.') )
+ {
+ end++;
+ }
+
+ if (end-start > 0)
+ {
+ // Write out the size of this section
+ len = end-start;
+ iUdp.write(&len, sizeof(len));
+ // And then write out the section
+ iUdp.write((uint8_t*)start, end-start);
+ }
+ start = end+1;
+ }
+
+ // We've got to the end of the question name, so
+ // terminate it with a zero-length section
+ len = 0;
+ iUdp.write(&len, sizeof(len));
+ // Finally the type and class of question
+ twoByteBuffer = htons(TYPE_A);
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+
+ twoByteBuffer = htons(CLASS_IN); // Internet class of question
+ iUdp.write((uint8_t*)&twoByteBuffer, sizeof(twoByteBuffer));
+ // Success! Everything buffered okay
+ return 1;
+}
+
+
+uint16_t DNSClient::ProcessResponse(uint16_t aTimeout, IPAddress& aAddress)
+{
+ uint32_t startTime = millis();
+
+ // Wait for a response packet
+ while(iUdp.parsePacket() <= 0)
+ {
+ if((millis() - startTime) > aTimeout)
+ return TIMED_OUT;
+ delay(50);
+ }
+
+ // We've had a reply!
+ // Read the UDP header
+ uint8_t header[DNS_HEADER_SIZE]; // Enough space to reuse for the DNS header
+ // Check that it's a response from the right server and the right port
+ if ( (iDNSServer != iUdp.remoteIP()) ||
+ (iUdp.remotePort() != DNS_PORT) )
+ {
+ // It's not from who we expected
+ return INVALID_SERVER;
+ }
+
+ // Read through the rest of the response
+ if (iUdp.available() < DNS_HEADER_SIZE)
+ {
+ return TRUNCATED;
+ }
+ iUdp.read(header, DNS_HEADER_SIZE);
+
+ uint16_t header_flags = get16nb(&header[2]);
+ // Check that it's a response to this request
+ if ( ( iRequestId != get16(&header[0]) ) ||
+ ((header_flags & QUERY_RESPONSE_MASK) != (uint16_t)RESPONSE_FLAG) )
+ {
+ // Mark the entire packet as read
+ iUdp.flush();
+ return INVALID_RESPONSE;
+ }
+ // Check for any errors in the response (or in our request)
+ // although we don't do anything to get round these
+ if ( (header_flags & TRUNCATION_FLAG) || (header_flags & RESP_MASK) )
+ {
+ // Mark the entire packet as read
+ iUdp.flush();
+ return -5; //INVALID_RESPONSE;
+ }
+
+ // And make sure we've got (at least) one answer
+ uint16_t answerCount = get16nb(&header[6]);
+ if (answerCount == 0 )
+ {
+ // Mark the entire packet as read
+ iUdp.flush();
+ return -6; //INVALID_RESPONSE;
+ }
+
+ // Skip over any questions
+ for (uint16_t i = 0; i < get16nb(&header[4]); i++)
+ {
+ // Skip over the name
+ uint8_t len;
+ do
+ {
+ iUdp.read(&len, sizeof(len));
+ if (len > 0)
+ {
+ // Don't need to actually read the data out for the string, just
+ // advance ptr to beyond it
+ while(len--)
+ {
+ iUdp.read(); // we don't care about the returned byte
+ }
+ }
+ } while (len != 0);
+
+ // Now jump over the type and class
+ for (int i =0; i < 4; i++)
+ {
+ iUdp.read(); // we don't care about the returned byte
+ }
+ }
+
+ // Now we're up to the bit we're interested in, the answer
+ // There might be more than one answer (although we'll just use the first
+ // type A answer) and some authority and additional resource records but
+ // we're going to ignore all of them.
+
+ for (uint16_t i =0; i < answerCount; i++)
+ {
+ // Skip the name
+ uint8_t len;
+ do
+ {
+ iUdp.read(&len, sizeof(len));
+ if ((len & LABEL_COMPRESSION_MASK) == 0)
+ {
+ // It's just a normal label
+ if (len > 0)
+ {
+ // And it's got a length
+ // Don't need to actually read the data out for the string,
+ // just advance ptr to beyond it
+ while(len--)
+ {
+ iUdp.read(); // we don't care about the returned byte
+ }
+ }
+ }
+ else
+ {
+ // This is a pointer to a somewhere else in the message for the
+ // rest of the name. We don't care about the name, and RFC1035
+ // says that a name is either a sequence of labels ended with a
+ // 0 length octet or a pointer or a sequence of labels ending in
+ // a pointer. Either way, when we get here we're at the end of
+ // the name
+ // Skip over the pointer
+ iUdp.read(); // we don't care about the returned byte
+ // And set len so that we drop out of the name loop
+ len = 0;
+ }
+ } while (len != 0);
+
+ // Check the type and class
+ uint16_t answerType;
+ uint16_t answerClass;
+ iUdp.read((uint8_t*)&answerType, sizeof(answerType));
+ iUdp.read((uint8_t*)&answerClass, sizeof(answerClass));
+
+ // Ignore the Time-To-Live as we don't do any caching
+ for (int i =0; i < TTL_SIZE; i++)
+ {
+ iUdp.read(); // we don't care about the returned byte
+ }
+
+ // And read out the length of this answer
+ // Don't need header_flags anymore, so we can reuse it here
+ iUdp.read((uint8_t*)&header_flags, sizeof(header_flags));
+
+ if ( (htons(answerType) == TYPE_A) && (htons(answerClass) == CLASS_IN) )
+ {
+ if (htons(header_flags) != 4)
+ {
+ // It's a weird size
+ // Mark the entire packet as read
+ iUdp.flush();
+ return -9;//INVALID_RESPONSE;
+ }
+ iUdp.read(aAddress.raw_address(), 4);
+ return SUCCESS;
+ }
+ else
+ {
+ // This isn't an answer type we're after, move onto the next one
+ for (uint16_t i =0; i < htons(header_flags); i++)
+ {
+ iUdp.read(); // we don't care about the returned byte
+ }
+ }
+ }
+
+ // Mark the entire packet as read
+ iUdp.flush();
+
+ // If we get here then we haven't found an answer
+ return -10;//INVALID_RESPONSE;
+}
+
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Dns.h b/src/DuetNG/DuetEthernet/Ethernet3/Dns.h
new file mode 100644
index 00000000..481c5c40
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Dns.h
@@ -0,0 +1,41 @@
+// Arduino DNS client for WizNet5100-based Ethernet shield
+// (c) Copyright 2009-2010 MCQN Ltd.
+// Released under Apache License, version 2.0
+
+#ifndef DNSClient_h
+#define DNSClient_h
+
+#include <EthernetUdp3.h>
+
+class DNSClient
+{
+public:
+ // ctor
+ void begin(const IPAddress& aDNSServer);
+
+ /** Convert a numeric IP address string into a four-byte IP address.
+ @param aIPAddrString IP address to convert
+ @param aResult IPAddress structure to store the returned IP address
+ @result 1 if aIPAddrString was successfully converted to an IP address,
+ else error code
+ */
+ int inet_aton(const char *aIPAddrString, IPAddress& aResult);
+
+ /** Resolve the given hostname to an IP address.
+ @param aHostname Name to be resolved
+ @param aResult IPAddress structure to store the returned IP address
+ @result 1 if aIPAddrString was successfully converted to an IP address,
+ else error code
+ */
+ int getHostByName(const char* aHostname, IPAddress& aResult);
+
+protected:
+ uint16_t BuildRequest(const char* aName);
+ uint16_t ProcessResponse(uint16_t aTimeout, IPAddress& aAddress);
+
+ IPAddress iDNSServer;
+ uint16_t iRequestId;
+ EthernetUDP iUdp;
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp
new file mode 100644
index 00000000..d8a2b9c7
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.cpp
@@ -0,0 +1,194 @@
+/*
+ modified 12 Aug 2013
+ by Soohwan Kim (suhwan@wiznet.co.kr)
+
+- 10 Apr. 2015
+ Added support for Arduino Ethernet Shield 2
+ by Arduino.org team
+
+ */
+
+#include "Ethernet3.h"
+#include "Dhcp.h"
+
+#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
+
+// XXX: don't make assumptions about the value of MAX_SOCK_NUM.
+uint8_t EthernetClass::_state[MAX_SOCK_NUM] = { 0, };
+uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = { 0, };
+
+
+int EthernetClass::begin(const uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout)
+{
+ if (_dhcp == nullptr)
+ {
+ _dhcp = new DhcpClass();
+ }
+
+ // Initialise the basic info
+ w5500.init();
+ w5500.setMACAddress(mac_address);
+ w5500.setIPAddress(IPAddress(0,0,0,0).raw_address());
+
+ // Now try to get our config info from a DHCP server
+ const int ret = _dhcp->beginWithDHCP(mac_address, timeout, responseTimeout);
+ if (ret == 1)
+ {
+ // We've successfully found a DHCP server and got our configuration info, so set things accordingly
+ w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
+ w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
+ }
+
+ return ret;
+}
+
+void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip)
+{
+ IPAddress subnet(255, 255, 255, 0);
+ begin(mac_address, local_ip, subnet);
+}
+
+void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet)
+{
+ // Assume the gateway will be the machine on the same network as the local IP
+ // but with last octet being '1'
+ IPAddress gateway = local_ip;
+ gateway[3] = 1;
+ begin(mac_address, local_ip, subnet, gateway);
+}
+
+void EthernetClass::begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway)
+{
+ // Assume the DNS server will be the machine on the same network as the local IP
+ // but with last octet being '1'
+ IPAddress dns_server = local_ip;
+ dns_server[3] = 1;
+ begin(mac_address, local_ip, subnet, gateway, dns_server);
+}
+
+void EthernetClass::begin(const uint8_t *mac, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server)
+{
+ w5500.init();
+ w5500.setMACAddress(mac);
+ w5500.setIPAddress(local_ip.raw_address());
+ w5500.setGatewayIp(gateway.raw_address());
+ w5500.setSubnetMask(subnet.raw_address());
+ _dnsServerAddress = dns_server;
+}
+
+void EthernetClass::stop()
+{
+ w5500.stop();
+}
+
+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.
+ w5500.setIPAddress(_dhcp->getLocalIp().raw_address());
+ w5500.setGatewayIp(_dhcp->getGatewayIp().raw_address());
+ w5500.setSubnetMask(_dhcp->getSubnetMask().raw_address());
+ _dnsServerAddress = _dhcp->getDnsServerIp();
+ break;
+ default:
+ //this is actually a error, it will retry though
+ break;
+ }
+ }
+ return rc;
+}
+
+uint8_t EthernetClass::phyState() {
+ return w5500.getPHYCFGR();
+ }
+
+uint8_t EthernetClass::link() {
+ return bitRead(w5500.getPHYCFGR(), 0);
+ }
+
+const char* EthernetClass::linkReport() {
+ if(bitRead(w5500.getPHYCFGR(), 0) == 1) return "LINK";
+ else return "NO LINK";
+ }
+
+uint8_t EthernetClass::speed() {
+ if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
+ if(bitRead(w5500.getPHYCFGR(), 1) == 1) return 100;
+ if(bitRead(w5500.getPHYCFGR(), 1) == 0) return 10;
+ }
+ return 0;
+ }
+
+const char* EthernetClass::speedReport() {
+ if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
+ if(bitRead(w5500.getPHYCFGR(), 1) == 1) return "100 MB";
+ if(bitRead(w5500.getPHYCFGR(), 1) == 0) return "10 MB";
+ }
+ return "NO LINK";
+ }
+
+uint8_t EthernetClass::duplex() {
+ if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
+ if(bitRead(w5500.getPHYCFGR(), 2) == 1) return 2;
+ if(bitRead(w5500.getPHYCFGR(), 2) == 0) return 1;
+ }
+ return 0;
+ }
+
+const char* EthernetClass::duplexReport() {
+ if(bitRead(w5500.getPHYCFGR(), 0) == 1) {
+ if(bitRead(w5500.getPHYCFGR(), 2) == 1) return "FULL DUPLEX";
+ if(bitRead(w5500.getPHYCFGR(), 2) == 0) return "HALF DUPLEX";
+ }
+ return "NO LINK";
+ }
+
+void EthernetClass::macAddress(uint8_t mac[]) {
+ w5500.getMACAddress(mac);
+ }
+
+const char* EthernetClass::macAddressReport() {
+ uint8_t mac[6];
+ static char str[18];
+ w5500.getMACAddress(mac);
+ sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return str;
+ }
+
+IPAddress EthernetClass::localIP()
+{
+ IPAddress ret;
+ w5500.getIPAddress(ret.raw_address());
+ return ret;
+}
+
+IPAddress EthernetClass::subnetMask()
+{
+ IPAddress ret;
+ w5500.getSubnetMask(ret.raw_address());
+ return ret;
+}
+
+IPAddress EthernetClass::gatewayIP()
+{
+ IPAddress ret;
+ w5500.getGatewayIp(ret.raw_address());
+ return ret;
+}
+
+IPAddress EthernetClass::dnsServerIP()
+{
+ return _dnsServerAddress;
+}
+
+EthernetClass Ethernet;
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h
new file mode 100644
index 00000000..0e176c1b
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Ethernet3.h
@@ -0,0 +1,62 @@
+/*
+ modified 12 Aug 2013
+ by Soohwan Kim (suhwan@wiznet.co.kr)
+
+ - 10 Apr. 2015
+ Added support for Arduino Ethernet Shield 2
+ by Arduino.org team
+
+ */
+#ifndef ethernet3_h
+#define ethernet3_h
+
+#include <inttypes.h>
+#include "utility/w5500.h"
+#include "IPAddress.h"
+#include "EthernetClient.h"
+#include "EthernetServer.h"
+#include "Dhcp.h"
+
+
+class EthernetClass {
+private:
+ IPAddress _dnsServerAddress;
+ DhcpClass* _dhcp;
+public:
+ static uint8_t _state[MAX_SOCK_NUM];
+ static uint16_t _server_port[MAX_SOCK_NUM];
+
+ // Initialize 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(const uint8_t *mac_address, unsigned long timeout, unsigned long responseTimeout);
+ void begin(const uint8_t *mac_address, IPAddress local_ip);
+ void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet);
+ void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway);
+ void begin(const uint8_t *mac_address, IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server);
+
+ int maintain();
+
+ void stop();
+
+ uint8_t phyState(); // returns the PHYCFGR
+ uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
+ const char* linkReport(); // returns the linkstate as a string
+ uint8_t speed(); // returns speed in MB/s
+ const char* speedReport(); // returns speed as a string
+ uint8_t duplex(); // returns duplex mode 0 = no link, 1 = Half Duplex, 2 = Full Duplex
+ const char* duplexReport(); // returns duplex mode as a string
+
+ void macAddress(uint8_t mac[]); // get the MAC Address
+ const char* macAddressReport(); // returns the the MAC Address as a string
+ IPAddress localIP();
+ IPAddress subnetMask();
+ IPAddress gatewayIP();
+ IPAddress dnsServerIP();
+
+ friend class EthernetClient;
+ friend class EthernetServer;
+};
+
+extern EthernetClass Ethernet;
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp
new file mode 100644
index 00000000..2cb38e60
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.cpp
@@ -0,0 +1,167 @@
+#include "utility/w5500.h"
+#include "utility/socket.h"
+
+#include "cstring"
+
+
+#include "Core.h"
+
+#include "Ethernet3.h"
+#include "EthernetClient.h"
+#include "EthernetServer.h"
+#include "Dns.h"
+
+uint16_t EthernetClient::_srcport = 1024;
+
+EthernetClient::EthernetClient() : _sock(MAX_SOCK_NUM) {
+}
+
+EthernetClient::EthernetClient(uint8_t sock) : _sock(sock) {
+}
+
+int EthernetClient::connect(const char* host, uint16_t port) {
+ // Look up the host first
+ int ret = 0;
+ DNSClient dns;
+ IPAddress remote_addr;
+
+ dns.begin(Ethernet.dnsServerIP());
+ ret = dns.getHostByName(host, remote_addr);
+ if (ret == 1) {
+ return connect(remote_addr, port);
+ } else {
+ return ret;
+ }
+}
+
+int EthernetClient::connect(IPAddress ip, uint16_t port) {
+ if (_sock != MAX_SOCK_NUM)
+ return 0;
+
+ for (int i = 0; i < MAX_SOCK_NUM; i++) {
+ uint8_t s = w5500.readSnSR(i);
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
+ _sock = i;
+ break;
+ }
+ }
+
+ if (_sock == MAX_SOCK_NUM)
+ return 0;
+
+ _srcport++;
+ if (_srcport == 0) _srcport = 1024;
+ socket(_sock, SnMR::TCP, _srcport, 0);
+
+ if (!::connect(_sock, rawIPAddress(ip), port)) {
+ _sock = MAX_SOCK_NUM;
+ return 0;
+ }
+
+ while (status() != SnSR::ESTABLISHED) {
+ delay(1);
+ if (status() == SnSR::CLOSED) {
+ _sock = MAX_SOCK_NUM;
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+size_t EthernetClient::write(uint8_t b) {
+ return write(&b, 1);
+}
+
+size_t EthernetClient::write(const uint8_t *buf, size_t size) {
+ if (_sock == MAX_SOCK_NUM) {
+ setWriteError();
+ return 0;
+ }
+ if (!send(_sock, buf, size)) {
+ setWriteError();
+ return 0;
+ }
+ return size;
+}
+
+int EthernetClient::available() {
+ if (_sock != MAX_SOCK_NUM)
+ return w5500.getRXReceivedSize(_sock);
+ return 0;
+}
+
+int EthernetClient::read() {
+ uint8_t b;
+ if ( recv(_sock, &b, 1) > 0 )
+ {
+ // recv worked
+ return b;
+ }
+ else
+ {
+ // No data available
+ return -1;
+ }
+}
+
+int EthernetClient::read(uint8_t *buf, size_t size) {
+ return recv(_sock, buf, size);
+}
+
+int EthernetClient::peek() {
+ uint8_t b;
+ // Unlike recv, peek doesn't check to see if there's any data available, so we must
+ if (!available())
+ return -1;
+ ::peek(_sock, &b);
+ return b;
+}
+
+void EthernetClient::flush() {
+ ::flush(_sock);
+}
+
+void EthernetClient::stop() {
+ if (_sock == MAX_SOCK_NUM)
+ return;
+
+ // attempt to close the connection gracefully (send a FIN to other side)
+ disconnect(_sock);
+ unsigned long start = millis();
+
+ // wait a second for the connection to close
+ while (status() != SnSR::CLOSED && millis() - start < 1000)
+ delay(1);
+
+ // if it hasn't closed, close it forcefully
+ if (status() != SnSR::CLOSED)
+ close(_sock);
+
+ EthernetClass::_server_port[_sock] = 0;
+ _sock = MAX_SOCK_NUM;
+}
+
+uint8_t EthernetClient::connected() {
+ if (_sock == MAX_SOCK_NUM) return 0;
+
+ uint8_t s = status();
+ return !(s == SnSR::LISTEN || s == SnSR::CLOSED || s == SnSR::FIN_WAIT ||
+ (s == SnSR::CLOSE_WAIT && !available()));
+}
+
+uint8_t EthernetClient::status() {
+ if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
+ return w5500.readSnSR(_sock);
+}
+
+// the next function allows us to use the client returned by
+// EthernetServer::available() as the condition in an if-statement.
+
+EthernetClient::operator bool() {
+ return _sock != MAX_SOCK_NUM;
+}
+
+bool EthernetClient::operator==(const EthernetClient& rhs) {
+ return _sock == rhs._sock && _sock != MAX_SOCK_NUM && rhs._sock != MAX_SOCK_NUM;
+}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h
new file mode 100644
index 00000000..8612e5c1
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetClient.h
@@ -0,0 +1,39 @@
+#ifndef ethernetclient_h
+#define ethernetclient_h
+#include "Core.h"
+#include "Print.h"
+#include "Client.h"
+#include "IPAddress.h"
+
+class EthernetClient : public Client {
+
+public:
+ EthernetClient();
+ EthernetClient(uint8_t sock);
+
+ uint8_t status();
+ virtual int connect(IPAddress ip, uint16_t port);
+ virtual int connect(const char *host, uint16_t port);
+ 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();
+ virtual bool operator==(const EthernetClient&);
+ virtual bool operator!=(const EthernetClient& rhs) { return !this->operator==(rhs); };
+
+ friend class EthernetServer;
+
+ using Print::write;
+
+private:
+ static uint16_t _srcport;
+ uint8_t _sock;
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp
new file mode 100644
index 00000000..406f0b3f
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.cpp
@@ -0,0 +1,91 @@
+#include "utility/w5500.h"
+#include "utility/socket.h"
+extern "C" {
+#include "string.h"
+}
+
+#include "Ethernet3.h"
+#include "EthernetClient.h"
+#include "EthernetServer.h"
+
+EthernetServer::EthernetServer(uint16_t port)
+{
+ _port = port;
+}
+
+void EthernetServer::begin()
+{
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ EthernetClient client(sock);
+ if (client.status() == SnSR::CLOSED) {
+ socket(sock, SnMR::TCP, _port, 0);
+ listen(sock);
+ EthernetClass::_server_port[sock] = _port;
+ break;
+ }
+ }
+}
+
+void EthernetServer::accept()
+{
+ int listening = 0;
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ EthernetClient client(sock);
+
+ if (EthernetClass::_server_port[sock] == _port) {
+ if (client.status() == SnSR::LISTEN) {
+ listening = 1;
+ }
+ else if (client.status() == SnSR::CLOSE_WAIT && !client.available()) {
+ client.stop();
+ }
+ }
+ }
+
+ if (!listening) {
+ begin();
+ }
+}
+
+EthernetClient EthernetServer::available()
+{
+ accept();
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ EthernetClient client(sock);
+ if (EthernetClass::_server_port[sock] == _port &&
+ (client.status() == SnSR::ESTABLISHED ||
+ client.status() == SnSR::CLOSE_WAIT)) {
+ if (client.available()) {
+ // XXX: don't always pick the lowest numbered socket.
+ return client;
+ }
+ }
+ }
+
+ return EthernetClient(MAX_SOCK_NUM);
+}
+
+size_t EthernetServer::write(uint8_t b)
+{
+ return write(&b, 1);
+}
+
+size_t EthernetServer::write(const uint8_t *buffer, size_t size)
+{
+ size_t n = 0;
+
+ accept();
+
+ for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
+ EthernetClient client(sock);
+
+ if (EthernetClass::_server_port[sock] == _port &&
+ client.status() == SnSR::ESTABLISHED) {
+ n += client.write(buffer, size);
+ }
+ }
+
+ return n;
+}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h
new file mode 100644
index 00000000..86ccafe9
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetServer.h
@@ -0,0 +1,22 @@
+#ifndef ethernetserver_h
+#define ethernetserver_h
+
+#include "Server.h"
+
+class EthernetClient;
+
+class EthernetServer :
+public Server {
+private:
+ uint16_t _port;
+ void accept();
+public:
+ EthernetServer(uint16_t);
+ EthernetClient available();
+ virtual void begin();
+ virtual size_t write(uint8_t);
+ virtual size_t write(const uint8_t *buf, size_t size);
+ using Print::write;
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp
new file mode 100644
index 00000000..a8ad13ee
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.cpp
@@ -0,0 +1,271 @@
+/*
+ * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
+ * This version only offers minimal wrapping of socket.c/socket.h
+ * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
+ *
+ * MIT License:
+ * Copyright (c) 2008 Bjoern Hartmann
+ * 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.
+ *
+ * bjoern@cs.stanford.edu 12/30/2008
+ *
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ */
+
+#include "utility/w5500.h"
+#include "utility/socket.h"
+#include "Ethernet3.h"
+#include "Udp.h"
+#include "Dns.h"
+
+#undef UDP
+
+/* Constructor */
+EthernetUDP::EthernetUDP() : _sock(MAX_SOCK_NUM) {}
+
+/* Start EthernetUDP socket, listening at local port PORT */
+uint8_t EthernetUDP::begin(uint16_t port)
+{
+ if (_sock != MAX_SOCK_NUM)
+ {
+ return 0;
+ }
+
+ for (int i = 0; i < MAX_SOCK_NUM; i++)
+ {
+ uint8_t s = w5500.readSnSR(i);
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT)
+ {
+ _sock = i;
+ break;
+ }
+ }
+
+ if (_sock == MAX_SOCK_NUM)
+ {
+ return 0;
+ }
+
+ _port = port;
+ _remaining = 0;
+ socket(_sock, SnMR::UDP, _port, 0);
+
+ return 1;
+}
+
+/* return number of bytes available in the current packet,
+ will return zero if parsePacket hasn't been called yet */
+int EthernetUDP::available()
+{
+ return _remaining;
+}
+
+/* Release any resources being used by this EthernetUDP instance */
+void EthernetUDP::stop()
+{
+ if (_sock == MAX_SOCK_NUM)
+ {
+ return;
+ }
+
+ close(_sock);
+
+ EthernetClass::_server_port[_sock] = 0;
+ _sock = MAX_SOCK_NUM;
+}
+
+int EthernetUDP::beginPacket(const char *host, uint16_t port)
+{
+ // Look up the host first
+ DNSClient dns;
+ IPAddress remote_addr;
+
+ dns.begin(Ethernet.dnsServerIP());
+ const int ret = dns.getHostByName(host, remote_addr);
+ if (ret == 1)
+ {
+ return beginPacket(remote_addr, port);
+ }
+ else
+ {
+ return ret;
+ }
+}
+
+int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
+{
+ _offset = 0;
+ return startUDP(_sock, rawIPAddress(ip), port);
+}
+
+int EthernetUDP::endPacket()
+{
+ return sendUDP(_sock);
+}
+
+size_t EthernetUDP::write(uint8_t byte)
+{
+ return write(&byte, 1);
+}
+
+size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
+{
+ uint16_t bytes_written = bufferData(_sock, _offset, buffer, size);
+ _offset += bytes_written;
+ return bytes_written;
+}
+
+int EthernetUDP::parsePacket()
+{
+ // discard any remaining bytes in the last packet
+ flush();
+
+ if (w5500.getRXReceivedSize(_sock) > 0)
+ {
+ //HACK - hand-parse the UDP packet using TCP recv method
+ uint8_t tmpBuf[8];
+ //read 8 header bytes and get IP and port from it
+ int ret = recv(_sock, tmpBuf, 8);
+ if (ret > 0)
+ {
+ _remoteIP = tmpBuf;
+ _remotePort = tmpBuf[4];
+ _remotePort = (_remotePort << 8) + tmpBuf[5];
+ _remaining = tmpBuf[6];
+ _remaining = (_remaining << 8) + tmpBuf[7];
+
+ // When we get here, any remaining bytes are the data
+ ret = _remaining;
+ }
+ return ret;
+ }
+ // There aren't any packets available
+ return 0;
+}
+
+int EthernetUDP::read()
+{
+ uint8_t byte;
+
+ if ((_remaining > 0) && (recv(_sock, &byte, 1) > 0))
+ {
+ // We read things without any problems
+ _remaining--;
+ return byte;
+ }
+
+ // If we get here, there's no data available
+ return -1;
+}
+
+int EthernetUDP::read(unsigned char* buffer, size_t len)
+{
+ if (_remaining > 0)
+ {
+ int got;
+ if (_remaining <= len)
+ {
+ // data should fit in the buffer
+ got = recv(_sock, buffer, _remaining);
+ }
+ else
+ {
+ // too much data for the buffer,
+ // grab as much as will fit
+ got = recv(_sock, buffer, len);
+ }
+
+ if (got > 0)
+ {
+ _remaining -= got;
+ return got;
+ }
+ }
+
+ // If we get here, there's no data available or recv failed
+ return -1;
+}
+
+int EthernetUDP::peek()
+{
+ uint8_t b;
+ // Unlike recv, peek doesn't check to see if there's any data available, so we must.
+ // If the user hasn't called parsePacket yet then return nothing otherwise they
+ // may get the UDP header
+ if (!_remaining)
+ {
+ return -1;
+ }
+ ::peek(_sock, &b);
+ return b;
+}
+
+void EthernetUDP::flush()
+{
+ // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
+ // should only occur if recv fails after telling us the data is there, lets
+ // hope the w5500 always behaves :)
+ while (_remaining)
+ {
+ read();
+ }
+}
+
+/* Start EthernetUDP socket, listening at local port PORT */
+uint8_t EthernetUDP::beginMulticast(IPAddress ip, uint16_t port)
+{
+ if (_sock != MAX_SOCK_NUM)
+ {
+ return 0;
+ }
+
+ for (int i = 0; i < MAX_SOCK_NUM; i++)
+ {
+ const uint8_t s = w5500.readSnSR(i);
+ if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT)
+ {
+ _sock = i;
+ break;
+ }
+ }
+
+ if (_sock == MAX_SOCK_NUM)
+ {
+ return 0;
+ }
+
+ // Calculate MAC address from Multicast IP Address
+ byte mac[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0x00 };
+
+ mac[3] = ip[1] & 0x7F;
+ mac[4] = ip[2];
+ mac[5] = ip[3];
+
+ w5500.writeSnDIPR(_sock, rawIPAddress(ip)); //239.255.0.1
+ w5500.writeSnDPORT(_sock, port);
+ w5500.writeSnDHAR(_sock,mac);
+
+ _remaining = 0;
+ socket(_sock, SnMR::UDP, port, SnMR::MULTI);
+ return 1;
+}
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h
new file mode 100644
index 00000000..41676bb8
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/EthernetUdp3.h
@@ -0,0 +1,106 @@
+/*
+ * Udp.cpp: Library to send/receive UDP packets with the Arduino ethernet shield.
+ * This version only offers minimal wrapping of socket.c/socket.h
+ * Drop Udp.h/.cpp into the Ethernet library directory at hardware/libraries/Ethernet/
+ *
+ * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
+ * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
+ * might not happen often in practice, but in larger network topologies, a UDP
+ * packet can be received out of sequence.
+ * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
+ * aware of it. Again, this may not be a concern in practice on small local networks.
+ * For more information, see http://www.cafeaulait.org/course/week12/35.html
+ *
+ * MIT License:
+ * Copyright (c) 2008 Bjoern Hartmann
+ * 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.
+ *
+ * bjoern@cs.stanford.edu 12/30/2008
+ *
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ *
+ */
+
+
+#ifndef ethernetudp3_h
+#define ethernetudp3_h
+
+#include <Udp.h>
+
+#define UDP_TX_PACKET_MAX_SIZE 24
+
+class EthernetUDP : public UdpStream {
+private:
+ uint8_t _sock; // socket ID for Wiz5100
+ 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
+ uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
+
+public:
+ EthernetUDP(); // 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; };
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/README.md b/src/DuetNG/DuetEthernet/Ethernet3/README.md
new file mode 100644
index 00000000..37c06aa8
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/README.md
@@ -0,0 +1,54 @@
+# Ethernet3
+Ethernet library for Arduino and Ethernetshield2 / WIZ550io / WIZ850io with Wiznet W5500 chip
+based on the Ethernet2 library of arduino.org
+
+added some new functionalities
+
+you need to include
+
+ #include <Ethernet3.h> // instead Ethernet.h
+ #include <EthernetUdp3.h> // instead EthernetUdp.h for UDP functionality
+
+###- New init procedure **!!!**
+
+the init of the Ethernetinterface changed, the ordner is now:
+
+*mac, ip, subnet, gateway, dns* instead *mac, ip, dns, gateway, subnet*,
+which is more logical
+
+ Ethernet.begin(mac, ip, subnet, gateway, dns);
+
+###- Multicast support
+
+multicast for udp added
+
+ EthernetUdp udp
+ upd.beginMulticast(multicastIP, port);
+
+###- PHY support
+
+added some function to read the PHYCFGR in Ethernet3
+
+ uint8_t phyState(); // returns the PHYCFGR
+ uint8_t link(); // returns the linkstate, 1 = linked, 0 = no link
+ const char* linkReport(); // returns the linkstate as a string
+ uint8_t speed(); // returns speed in MB/s
+ const char* speedReport(); // returns speed as a string
+ uint8_t duplex(); // returns duplex mode 0 = no link, 1 = Half Duplex, 2 = Full Duplex
+ const char* duplexReport(); // returns duplex mode as a string
+
+example
+
+ Serial.println(Ethernet.linkReport());
+
+###- MAC address
+
+added some function to read the MAC address in Ethernet3, this is helpfull when you use Wiznet boards like WIZ550io with build in MAC address
+
+ void macAddress(uint8_t mac[]); // get the MAC Address
+ const char* macAddressReport(); // returns the the MAC Address as a string
+
+example
+
+ uint8_t mac[6]; // array for mac address
+ Ethernet.macAddress(mac);
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Server.h b/src/DuetNG/DuetEthernet/Ethernet3/Server.h
new file mode 100644
index 00000000..69e3e39f
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Server.h
@@ -0,0 +1,30 @@
+/*
+ Server.h - Base class that provides Server
+ Copyright (c) 2011 Adrian McEwen. All right reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef server_h
+#define server_h
+
+#include "Print.h"
+
+class Server : public Print {
+public:
+ virtual void begin() =0;
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp
new file mode 100644
index 00000000..7d1b9a9c
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.cpp
@@ -0,0 +1,74 @@
+/*
+ Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
+ Copyright (c) NeoCat 2010-2011. All right reserved.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+// ver1.2 - Use <string.h>
+// ver1.3 - Support IDE 1.0
+
+#include <cstring>
+#include "Twitter.h"
+
+#define LIB_DOMAIN "arduino-tweet.appspot.com"
+
+Twitter::Twitter(const char *token) : token(token)
+{
+}
+
+bool Twitter::doPost(const char *msg)
+{
+ parseStatus = 0;
+ statusCode = 0;
+ if (client.connect(LIB_DOMAIN, 80)) {
+ client.println("POST http://" LIB_DOMAIN "/update HTTP/1.0");
+ client.print("Content-Length: ");
+ client.println(strlen(msg)+strlen(token)+14);
+ client.println();
+ client.print("token=");
+ client.print(token);
+ client.print("&status=");
+ client.println(msg);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool Twitter::checkStatus(Print *debug)
+{
+ if (!client.connected()) {
+ if (debug)
+ while(client.available())
+ debug->print((char)client.read());
+ client.flush();
+ client.stop();
+ return false;
+ }
+ if (!client.available())
+ return true;
+ char c = client.read();
+ if (debug)
+ debug->print(c);
+ switch(parseStatus) {
+ case 0:
+ if (c == ' ') parseStatus++; break; // skip "HTTP/1.1 "
+ case 1:
+ if (c >= '0' && c <= '9') {
+ statusCode *= 10;
+ statusCode += c - '0';
+ } else {
+ parseStatus++;
+ }
+ }
+ return true;
+}
+
+int Twitter::wait(Print *debug)
+{
+ while (checkStatus(debug));
+ return statusCode;
+}
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h
new file mode 100644
index 00000000..80c5673b
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Twitter.h
@@ -0,0 +1,35 @@
+/*
+ Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
+ Copyright (c) NeoCat 2010-2011. All right reserved.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+// ver1.2 - Use <Udp.h> to support IDE 0019 or later
+// ver1.3 - Support IDE 1.0
+
+#ifndef TWITTER_H
+#define TWITTER_H
+
+#include <inttypes.h>
+#include <Ethernet3.h>
+
+class Twitter
+{
+private:
+ uint8_t parseStatus;
+ int statusCode;
+ const char *token;
+ EthernetClient client;
+public:
+ Twitter(const char *user_and_passwd);
+
+ bool doPost(const char *msg);
+ bool checkStatus(Print *debug = NULL);
+ int wait(Print *debug = NULL);
+ int status(void) { return statusCode; }
+};
+
+#endif //TWITTER_H
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/Udp.h b/src/DuetNG/DuetEthernet/Ethernet3/Udp.h
new file mode 100644
index 00000000..04207c71
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/Udp.h
@@ -0,0 +1,88 @@
+/*
+ * Udp.cpp: Library to send/receive UDP packets.
+ *
+ * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
+ * 1) UDP does not guarantee the order in which assembled UDP packets are received. This
+ * might not happen often in practice, but in larger network topologies, a UDP
+ * packet can be received out of sequence.
+ * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
+ * aware of it. Again, this may not be a concern in practice on small local networks.
+ * For more information, see http://www.cafeaulait.org/course/week12/35.html
+ *
+ * MIT License:
+ * Copyright (c) 2008 Bjoern Hartmann
+ * 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.
+ *
+ * bjoern@cs.stanford.edu 12/30/2008
+ */
+
+#ifndef udp_h
+#define udp_h
+
+#include <Stream.h>
+#include <IPAddress.h>
+
+class UdpStream : public Stream {
+
+public:
+ virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
+ virtual void stop() =0; // 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) =0;
+ // 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) =0;
+ // Finish off this packet and send it
+ // Returns 1 if the packet was sent successfully, 0 if there was an error
+ virtual int endPacket() =0;
+ // Write a single byte into the packet
+ virtual size_t write(uint8_t) =0;
+ // Write size bytes from buffer into the packet
+ virtual size_t write(const uint8_t *buffer, size_t size) =0;
+
+ // 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() =0;
+ // Number of bytes remaining in the current packet
+ virtual int available() =0;
+ // Read a single byte from the current packet
+ virtual int read() =0;
+ // 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) =0;
+ // 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) =0;
+ // Return the next byte from the current packet without moving on to the next byte
+ virtual int peek() =0;
+ virtual void flush() =0; // Finish reading the current packet
+
+ // Return the IP address of the host who sent the current incoming packet
+ virtual IPAddress remoteIP() =0;
+ // Return the port of the host who sent the current incoming packet
+ virtual uint16_t remotePort() =0;
+protected:
+ uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
+};
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp
new file mode 100644
index 00000000..076017f9
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.cpp
@@ -0,0 +1,425 @@
+/*
+ * WizSpi.cpp
+ *
+ * Created on: 16 Dec 2016
+ * Author: David
+ */
+
+#include "WizSpi.h"
+#include "variant.h"
+#include "Pins.h"
+
+// Define exactly one of the following as 1, the other as zero
+// The PDC seems to be too slow to work reliably without getting transmit underruns, so we use the DMAC now.
+#define USE_PDC 0 // use peripheral DMA controller
+#define USE_DMAC 0 // use general DMA controller
+
+#if USE_PDC
+#include "pdc.h"
+#endif
+
+#if USE_DMAC
+#include "dmac.h"
+#endif
+
+#include "matrix.h"
+
+// Functions called by the W5500 module to transfer data to/from the W5500 via SPI
+const uint32_t SpiClockFrequency = 10000000; // use 10MHz for now, increase it later
+const unsigned int SpiPeripheralChannelId = 0; // we use NPCS0 as the slave select signal
+
+#if USE_PDC
+static Pdc *spi_pdc;
+static inline void spi_rx_dma_enable()
+{
+ pdc_enable_transfer(spi_pdc, PERIPH_PTCR_RXTEN);
+}
+
+static inline void spi_tx_dma_enable()
+{
+ pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN);
+}
+
+static inline void spi_rx_dma_disable()
+{
+ pdc_disable_transfer(spi_pdc, PERIPH_PTCR_RXTDIS);
+}
+
+static inline void spi_tx_dma_disable()
+{
+ pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS);
+}
+
+static bool spi_dma_check_rx_complete()
+{
+ return true;
+}
+
+static void spi_tx_dma_setup(const TransactionBuffer *buf, uint32_t maxTransmitLength)
+{
+ pdc_packet_t pdc_spi_packet;
+ pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
+ pdc_spi_packet.ul_size = buf->PacketLength() * 4; // need length in bytes
+ pdc_tx_init(spi_pdc, &pdc_spi_packet, NULL);
+}
+
+static void spi_rx_dma_setup(const TransactionBuffer *buf)
+{
+ pdc_packet_t pdc_spi_packet;
+ pdc_spi_packet.ul_addr = reinterpret_cast<uint32_t>(buf);
+ pdc_spi_packet.ul_size = TransactionBuffer::MaxReceiveBytes;
+ pdc_rx_init(spi_pdc, &pdc_spi_packet, NULL);
+}
+
+#endif
+
+#if USE_DMAC
+
+// Our choice of DMA channels to use
+const uint32_t CONF_SPI_DMAC_TX_CH = 1;
+const uint32_t CONF_SPI_DMAC_RX_CH = 2;
+
+// Hardware IDs of the SPI transmit and receive DMA interfaces. See atsam datasheet.
+const uint32_t DMA_HW_ID_SPI_TX = 1;
+const uint32_t DMA_HW_ID_SPI_RX = 2;
+
+static inline void spi_rx_dma_enable()
+{
+ dmac_channel_enable(DMAC, CONF_SPI_DMAC_RX_CH);
+}
+
+static inline void spi_tx_dma_enable()
+{
+ dmac_channel_enable(DMAC, CONF_SPI_DMAC_TX_CH);
+}
+
+static inline void spi_rx_dma_disable()
+{
+ dmac_channel_disable(DMAC, CONF_SPI_DMAC_RX_CH);
+}
+
+static inline void spi_tx_dma_disable()
+{
+ dmac_channel_disable(DMAC, CONF_SPI_DMAC_TX_CH);
+}
+
+static bool spi_dma_check_rx_complete()
+{
+ uint32_t status = DMAC->DMAC_CHSR;
+ if ( ((status & (DMAC_CHSR_ENA0 << CONF_SPI_DMAC_RX_CH)) == 0) // controller is not enabled, perhaps because it finished a full buffer transfer
+ || ((status & (DMAC_CHSR_EMPT0 << CONF_SPI_DMAC_RX_CH)) != 0) // controller is enabled, probably suspended, and the FIFO is empty
+ )
+ {
+ // Disable the channel.
+ // We also need to set the resume bit, otherwise it remains suspended when we re-enable it.
+ DMAC->DMAC_CHDR = (DMAC_CHDR_DIS0 << CONF_SPI_DMAC_RX_CH) | (DMAC_CHDR_RES0 << CONF_SPI_DMAC_RX_CH);
+ return true;
+ }
+ return false;
+}
+
+static void spi_tx_dma_setup(const TransactionBuffer *buf, uint32_t maxTransmitLength)
+{
+ DMAC->DMAC_EBCISR; // clear any pending interrupts
+
+ dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast<uint32_t>(buf));
+ dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_TX_CH, reinterpret_cast<uint32_t>(& SPI->SPI_TDR));
+ dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_TX_CH, 0);
+ dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_TX_CH, maxTransmitLength | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_BYTE);
+ dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_TX_CH,
+ DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2PER_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_FIXED);
+}
+
+static void spi_rx_dma_setup(const TransactionBuffer *buf)
+{
+ DMAC->DMAC_EBCISR; // clear any pending interrupts
+
+ dmac_channel_set_source_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast<uint32_t>(& SPI->SPI_RDR));
+ dmac_channel_set_destination_addr(DMAC, CONF_SPI_DMAC_RX_CH, reinterpret_cast<uint32_t>(buf));
+ dmac_channel_set_descriptor_addr(DMAC, CONF_SPI_DMAC_RX_CH, 0);
+// dmac_channel_set_ctrlA(DMAC, CONF_SPI_DMAC_RX_CH, TransactionBuffer::MaxTransferBytes | DMAC_CTRLA_SRC_WIDTH_BYTE | DMAC_CTRLA_DST_WIDTH_WORD);
+ dmac_channel_set_ctrlB(DMAC, CONF_SPI_DMAC_RX_CH,
+ DMAC_CTRLB_SRC_DSCR | DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_PER2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING);
+}
+
+#endif
+
+#if USE_PDC || USE_DMAC
+
+static void spi_dma_disable()
+{
+ spi_tx_dma_disable();
+ spi_rx_dma_disable();
+}
+
+#if 0
+/**
+ * \brief Set SPI slave transfer.
+ */
+static void spi_slave_dma_setup(bool dataToSend, bool allowReceive)
+{
+#if USE_PDC
+ pdc_disable_transfer(spi_pdc, PERIPH_PTCR_TXTDIS | PERIPH_PTCR_RXTDIS);
+
+ TransactionBuffer *outBufPointer = (dataToSend) ? &outBuffer : reinterpret_cast<TransactionBuffer*>(&dummyOutBuffer);
+ spi_tx_dma_setup(outBufPointer);
+ if (allowReceive)
+ {
+ outBufPointer->SetDataTaken();
+ spi_rx_dma_setup(&inBuffer);
+ pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN | PERIPH_PTCR_RXTEN);
+ }
+ else
+ {
+ outBufPointer->ClearDataTaken();
+ pdc_enable_transfer(spi_pdc, PERIPH_PTCR_TXTEN);
+ }
+#endif
+
+#if USE_DMAC
+ spi_dma_disable();
+
+ TransactionBuffer *outBufPointer = (dataToSend) ? &outBuffer : reinterpret_cast<TransactionBuffer*>(&dummyOutBuffer);
+ if (allowReceive)
+ {
+ spi_rx_dma_setup(&inBuffer);
+ spi_rx_dma_enable();
+// outBufPointer->SetDataTaken();
+ }
+ else
+ {
+// outBufPointer->ClearDataTaken();
+ }
+
+// spi_tx_dma_setup(outBufPointer, (dataToSend) ? TransactionBuffer::MaxTransferBytes : 4 * TransactionBuffer::headerDwords);
+ spi_tx_dma_enable();
+#endif
+}
+#endif
+
+#endif
+
+namespace WizSpi
+{
+ // Initialise the SPI interface
+ void Init()
+ {
+ #if USE_PDC
+ spi_pdc = spi_get_pdc_base(SPI);
+ // The PDCs are masters 2 and 3 and the SRAM is slave 0. Give the PDCs the highest priority.
+ matrix_set_master_burst_type(0, MATRIX_ULBT_8_BEAT_BURST);
+ matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER);
+ matrix_set_slave_priority(0, (3 << MATRIX_PRAS0_M2PR_Pos) | (3 << MATRIX_PRAS0_M3PR_Pos));
+ matrix_set_slave_slot_cycle(0, 8);
+ #endif
+
+ #if USE_DMAC
+ pmc_enable_periph_clk(ID_DMAC);
+ dmac_init(DMAC);
+ dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN);
+ dmac_enable(DMAC);
+ // The DMAC is master 4 and the SRAM is slave 0. Give the DMAC the highest priority.
+ matrix_set_slave_default_master_type(0, MATRIX_DEFMSTR_LAST_DEFAULT_MASTER);
+ matrix_set_slave_priority(0, (3 << MATRIX_PRAS0_M4PR_Pos));
+ // Set the slave slot cycle limit.
+ // If we leave it at the default value of 511 clock cycles, we get transmit underruns due to the HSMCI using the bus for too long.
+ // A value of 8 seems to work. I haven't tried other values yet.
+ matrix_set_slave_slot_cycle(0, 8);
+ #endif
+
+ // Set up the SPI pins
+ ConfigurePin(g_APinDescription[APIN_SPI_SCK]);
+ ConfigurePin(g_APinDescription[APIN_SPI_MOSI]);
+ ConfigurePin(g_APinDescription[APIN_SPI_MISO]);
+#if 1
+ pinMode(APIN_SPI_SS0, OUTPUT_HIGH); // use manual SS control for now
+#else
+ ConfigurePin(g_APinDescription[APIN_SPI_SS0]);
+#endif
+
+ pmc_enable_periph_clk(ID_SPI);
+
+#if USE_PDC || USE_DMAC
+ spi_dma_disable();
+#endif
+
+ spi_reset(SPI); // this clears the transmit and receive registers and puts the SPI into slave mode
+ SPI->SPI_MR = SPI_MR_MSTR // master mode
+ | SPI_MR_MODFDIS // disable fault detection
+ | SPI_MR_PCS(SpiPeripheralChannelId); // fixed peripheral select
+
+ // Set SPI mode, clock frequency, CS active after transfer, delay between transfers
+ const uint16_t baud_div = (uint16_t)spi_calc_baudrate_div(SpiClockFrequency, SystemCoreClock);
+ const uint32_t csr = SPI_CSR_SCBR(baud_div) // Baud rate
+ | SPI_CSR_BITS_8_BIT // Transfer bit width
+ | SPI_CSR_DLYBCT(0) // Transfer delay
+ | SPI_CSR_CSAAT // Keep CS low after transfer in case we are slow in writing the next byte
+ | SPI_CSR_NCPHA; // Data is captured on the leading edge of the clock (SPI mode 0)
+ SPI->SPI_CSR[SpiPeripheralChannelId] = csr;
+ spi_enable(SPI);
+
+#if USE_DMAC
+ // Configure DMA RX channel
+ dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_RX_CH,
+ DMAC_CFG_SRC_PER(DMA_HW_ID_SPI_RX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG);
+
+ // Configure DMA TX channel
+ dmac_channel_set_configuration(DMAC, CONF_SPI_DMAC_TX_CH,
+ DMAC_CFG_DST_PER(DMA_HW_ID_SPI_TX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ASAP_CFG);
+#endif
+ }
+
+ void Stop()
+ {
+ NVIC_DisableIRQ(SPI_IRQn);
+ spi_disable(SPI);
+#if USE_PDC || USE_DMA
+ spi_dma_check_rx_complete();
+ spi_dma_disable();
+#endif
+ }
+
+ // Wait for transmitter ready returning true if timed out
+ static inline bool waitForTxReady()
+ {
+ uint32_t timeout = SPI_TIMEOUT;
+ while (!spi_is_tx_ready(SPI))
+ {
+ if (--timeout == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Wait for transmitter empty returning true if timed out
+ static inline bool waitForTxEmpty()
+ {
+ uint32_t timeout = SPI_TIMEOUT;
+ while (!spi_is_tx_empty(SPI))
+ {
+ if (!timeout--)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Wait for receive data available returning true if timed out
+ static inline bool waitForRxReady()
+ {
+ uint32_t timeout = SPI_TIMEOUT;
+ while (!spi_is_rx_ready(SPI))
+ {
+ if (--timeout == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Set the SS pin low to address the W5500
+ void AssertSS()
+ {
+ spi_set_peripheral_chip_select_value(SPI, spi_get_pcs(SpiPeripheralChannelId));
+ digitalWrite(SamCsPin, LOW);
+ }
+
+ // Set the SS pin high again
+ void ReleaseSS()
+ {
+ waitForTxEmpty();
+ digitalWrite(SamCsPin, HIGH);
+ }
+
+ //TODO return type, error returns
+ uint8_t ExchangeByte(uint8_t b, bool isLast)
+ {
+ if (waitForTxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Write to transmit register
+ uint32_t dOut = b;
+ if (isLast)
+ {
+ dOut |= SPI_TDR_LASTXFER;
+ }
+ SPI->SPI_TDR = dOut;
+
+ // Wait for receive register
+ if (waitForRxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Get data from receive register
+ return (uint8_t)SPI->SPI_RDR;
+ }
+
+ spi_status_t ReadBurst(uint8_t* rx_data, size_t len)
+ {
+ for (size_t i = 0; i < len; ++i)
+ {
+ uint32_t dOut = 0x000000FF;
+ if (waitForTxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Write to transmit register
+ if (i + 1 == len)
+ {
+ dOut |= SPI_TDR_LASTXFER;
+ }
+ SPI->SPI_TDR = dOut;
+
+ // Wait for receive register
+ if (waitForRxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Get data from receive register
+ *rx_data++ = (uint8_t)SPI->SPI_RDR;
+ }
+
+ return SPI_OK;
+ }
+
+ spi_status_t SendBurst(const uint8_t* tx_data, size_t len)
+ {
+ for (uint32_t i = 0; i < len; ++i)
+ {
+ uint32_t dOut = (uint32_t)*tx_data++;
+ if (waitForTxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Write to transmit register
+ if (i + 1 == len)
+ {
+ dOut |= SPI_TDR_LASTXFER;
+ }
+ SPI->SPI_TDR = dOut;
+ // Wait for receive register
+ if (waitForRxReady())
+ {
+ return SPI_ERROR_TIMEOUT;
+ }
+
+ // Get data from receive register
+ (void)SPI->SPI_RDR;
+ }
+
+ return SPI_OK;
+ }
+
+} // end namespace
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h
new file mode 100644
index 00000000..214c668f
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/WizSpi.h
@@ -0,0 +1,24 @@
+/*
+ * Spi.h
+ *
+ * Created on: 16 Dec 2016
+ * Author: David
+ */
+
+#ifndef SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_
+#define SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_
+
+#include "spi.h"
+
+namespace WizSpi
+{
+ void Init();
+ void Stop();
+ void AssertSS();
+ void ReleaseSS();
+ uint8_t ExchangeByte(uint8_t b, bool isLast);
+ spi_status_t ReadBurst(uint8_t* rx_data, size_t len);
+ spi_status_t SendBurst(const uint8_t* tx_data, size_t len);
+}
+
+#endif /* SRC_DUETNG_DUETETHERNET_ETHERNET3_UTILITY_WIZSPI_H_ */
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp
new file mode 100644
index 00000000..75f7a993
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.cpp
@@ -0,0 +1,413 @@
+ /*
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ */
+
+#include "utility/w5500.h"
+#include "utility/socket.h"
+
+static uint16_t local_port;
+
+/**
+ * @brief This Socket function initialize the channel in perticular mode, and set the port and wait for w5500 done it.
+ * @return 1 for success else 0.
+ */
+uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
+{
+ if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE))
+ {
+ close(s);
+ w5500.writeSnMR(s, protocol | flag);
+ if (port != 0) {
+ w5500.writeSnPORT(s, port);
+ }
+ else {
+ local_port++; // if don't set the source port, set local_port number.
+ w5500.writeSnPORT(s, local_port);
+ }
+
+ w5500.execCmdSn(s, Sock_OPEN);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/**
+ * @brief This function close the socket and parameter is "s" which represent the socket number
+ */
+void close(SOCKET s)
+{
+ w5500.execCmdSn(s, Sock_CLOSE);
+ w5500.writeSnIR(s, 0xFF);
+}
+
+
+/**
+ * @brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
+ * @return 1 for success else 0.
+ */
+uint8_t listen(SOCKET s)
+{
+ if (w5500.readSnSR(s) != SnSR::INIT)
+ return 0;
+ w5500.execCmdSn(s, Sock_LISTEN);
+ return 1;
+}
+
+
+/**
+ * @brief This function established the connection for the channel in Active (client) mode.
+ * This function waits for the untill the connection is established.
+ *
+ * @return 1 for success else 0.
+ */
+uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
+{
+ if
+ (
+ ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
+ ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
+ (port == 0x00)
+ )
+ return 0;
+
+ // set destination IP
+ w5500.writeSnDIPR(s, addr);
+ w5500.writeSnDPORT(s, port);
+ w5500.execCmdSn(s, Sock_CONNECT);
+
+ return 1;
+}
+
+
+
+/**
+ * @brief This function used for disconnect the socket and parameter is "s" which represent the socket number
+ * @return 1 for success else 0.
+ */
+void disconnect(SOCKET s)
+{
+ w5500.execCmdSn(s, Sock_DISCON);
+}
+
+
+/**
+ * @brief This function used to send the data in TCP mode
+ * @return 1 for success else 0.
+ */
+uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
+{
+ uint8_t status=0;
+ uint16_t ret=0;
+ uint16_t freesize=0;
+
+ if (len > w5500.SSIZE)
+ ret = w5500.SSIZE; // check size not to exceed MAX size.
+ else
+ ret = len;
+
+ // if freebuf is available, start.
+ do
+ {
+ freesize = w5500.getTXFreeSize(s);
+ status = w5500.readSnSR(s);
+ if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
+ {
+ ret = 0;
+ break;
+ }
+ }
+ while (freesize < ret);
+
+ // copy data
+ w5500.send_data_processing(s, (uint8_t *)buf, ret);
+ w5500.execCmdSn(s, Sock_SEND);
+
+ /* +2008.01 bj */
+ while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
+ {
+ /* m2008.01 [bj] : reduce code */
+ if ( w5500.readSnSR(s) == SnSR::CLOSED )
+ {
+ close(s);
+ return 0;
+ }
+ }
+ /* +2008.01 bj */
+ w5500.writeSnIR(s, SnIR::SEND_OK);
+ return ret;
+}
+
+
+/**
+ * @brief This function is an application I/F function which is used to receive the data in TCP mode.
+ * It continues to wait for data as much as the application wants to receive.
+ *
+ * @return received data size for success else -1.
+ */
+int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
+{
+ // Check how much data is available
+ int16_t ret = w5500.getRXReceivedSize(s);
+ if ( ret == 0 )
+ {
+ // No data available.
+ uint8_t status = w5500.readSnSR(s);
+ if ( status == SnSR::LISTEN || status == SnSR::CLOSED || status == SnSR::CLOSE_WAIT )
+ {
+ // The remote end has closed its side of the connection, so this is the eof state
+ ret = 0;
+ }
+ else
+ {
+ // The connection is still up, but there's no data waiting to be read
+ ret = -1;
+ }
+ }
+ else if (ret > len)
+ {
+ ret = len;
+ }
+
+ if ( ret > 0 )
+ {
+ w5500.recv_data_processing(s, buf, ret);
+ w5500.execCmdSn(s, Sock_RECV);
+ }
+ return ret;
+}
+
+
+/**
+ * @brief Returns the first byte in the receive queue (no checking)
+ *
+ * @return
+ */
+uint16_t peek(SOCKET s, uint8_t *buf)
+{
+ w5500.recv_data_processing(s, buf, 1, 1);
+
+ return 1;
+}
+
+
+/**
+ * @brief This function is an application I/F function which is used to send the data for other then TCP mode.
+ * Unlike TCP transmission, The peer's destination address and the port is needed.
+ *
+ * @return This function return send data size for success else -1.
+ */
+uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
+{
+ uint16_t ret=0;
+
+ if (len > w5500.SSIZE) ret = w5500.SSIZE; // check size not to exceed MAX size.
+ else ret = len;
+
+ if
+ (
+ ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
+ ((port == 0x00)) ||(ret == 0)
+ )
+ {
+ /* +2008.01 [bj] : added return value */
+ ret = 0;
+ }
+ else
+ {
+ w5500.writeSnDIPR(s, addr);
+ w5500.writeSnDPORT(s, port);
+
+ // copy data
+ w5500.send_data_processing(s, (uint8_t *)buf, ret);
+ w5500.execCmdSn(s, Sock_SEND);
+
+ /* +2008.01 bj */
+ while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
+ {
+ if (w5500.readSnIR(s) & SnIR::TIMEOUT)
+ {
+ /* +2008.01 [bj]: clear interrupt */
+ w5500.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
+ return 0;
+ }
+ }
+
+ /* +2008.01 bj */
+ w5500.writeSnIR(s, SnIR::SEND_OK);
+ }
+ return ret;
+}
+
+
+/**
+ * @brief This function is an application I/F function which is used to receive the data in other then
+ * TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
+ *
+ * @return This function return received data size for success else -1.
+ */
+uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t *port)
+{
+ uint8_t head[8];
+ uint16_t data_len=0;
+ uint16_t ptr=0;
+
+ if ( len > 0 )
+ {
+ ptr = w5500.readSnRX_RD(s);
+ switch (w5500.readSnMR(s) & 0x07)
+ {
+ case SnMR::UDP :
+ w5500.read_data(s, ptr, head, 0x08);
+ ptr += 8;
+ // read peer's IP address, port number.
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ *port = head[4];
+ *port = (*port << 8) + head[5];
+ data_len = head[6];
+ data_len = (data_len << 8) + head[7];
+
+ w5500.read_data(s, ptr, buf, data_len); // data copy.
+ ptr += data_len;
+
+ w5500.writeSnRX_RD(s, ptr);
+ break;
+
+ case SnMR::IPRAW :
+ w5500.read_data(s, ptr, head, 0x06);
+ ptr += 6;
+
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ data_len = head[4];
+ data_len = (data_len << 8) + head[5];
+
+ w5500.read_data(s, ptr, buf, data_len); // data copy.
+ ptr += data_len;
+
+ w5500.writeSnRX_RD(s, ptr);
+ break;
+
+ case SnMR::MACRAW:
+ w5500.read_data(s, ptr, head, 2);
+ ptr+=2;
+ data_len = head[0];
+ data_len = (data_len<<8) + head[1] - 2;
+
+ w5500.read_data(s, ptr, buf, data_len);
+ ptr += data_len;
+ w5500.writeSnRX_RD(s, ptr);
+ break;
+
+ default :
+ break;
+ }
+ w5500.execCmdSn(s, Sock_RECV);
+ }
+ return data_len;
+}
+
+/**
+ * @brief Wait for buffered transmission to complete.
+ */
+void flush(SOCKET s) {
+ // TODO
+}
+
+uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
+{
+ //uint8_t status=0;
+ uint16_t ret=0;
+
+ if (len > w5500.SSIZE)
+ ret = w5500.SSIZE; // check size not to exceed MAX size.
+ else
+ ret = len;
+
+ if (ret == 0)
+ return 0;
+
+ w5500.send_data_processing(s, (uint8_t *)buf, ret);
+ w5500.execCmdSn(s, Sock_SEND);
+
+ while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
+ {
+ //status = w5500.readSnSR(s);
+ (void)w5500.readSnSR(s);
+ if (w5500.readSnIR(s) & SnIR::TIMEOUT)
+ {
+ /* in case of igmp, if send fails, then socket closed */
+ /* if you want change, remove this code. */
+ close(s);
+ return 0;
+ }
+ }
+
+ w5500.writeSnIR(s, SnIR::SEND_OK);
+ return ret;
+}
+
+uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
+{
+ uint16_t ret =0;
+ if (len > w5500.getTXFreeSize(s))
+ {
+ ret = w5500.getTXFreeSize(s); // check size not to exceed MAX size.
+ }
+ else
+ {
+ ret = len;
+ }
+ w5500.send_data_processing_offset(s, offset, buf, ret);
+ return ret;
+}
+
+int startUDP(SOCKET s, uint8_t* addr, uint16_t port)
+{
+ if
+ (
+ ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
+ ((port == 0x00))
+ )
+ {
+ return 0;
+ }
+ else
+ {
+ w5500.writeSnDIPR(s, addr);
+ w5500.writeSnDPORT(s, port);
+ return 1;
+ }
+}
+
+int sendUDP(SOCKET s)
+{
+ w5500.execCmdSn(s, Sock_SEND);
+
+ /* +2008.01 bj */
+ while ( (w5500.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
+ {
+ if (w5500.readSnIR(s) & SnIR::TIMEOUT)
+ {
+ /* +2008.01 [bj]: clear interrupt */
+ w5500.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
+ return 0;
+ }
+ }
+
+ /* +2008.01 bj */
+ w5500.writeSnIR(s, SnIR::SEND_OK);
+
+ /* Sent ok */
+ return 1;
+}
+
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h
new file mode 100644
index 00000000..903280c0
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/socket.h
@@ -0,0 +1,48 @@
+ /*
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ */
+
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+#include "utility/w5500.h"
+
+extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode)
+extern void close(SOCKET s); // Close socket
+extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection)
+extern void disconnect(SOCKET s); // disconnect the connection
+extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection)
+extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP)
+extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP)
+extern uint16_t peek(SOCKET s, uint8_t *buf);
+extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW)
+extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW)
+extern void flush(SOCKET s); // Wait for transmission to complete
+
+extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);
+
+// Functions to allow buffered UDP send (i.e. where the UDP datagram is built up over a
+// number of calls before being sent
+/*
+ @brief This function 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 1 if the datagram was successfully set up, or 0 if there was an error
+*/
+extern int startUDP(SOCKET s, uint8_t* addr, uint16_t port);
+/*
+ @brief This function copies 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 bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len);
+/*
+ @brief Send a UDP datagram built up from a sequence of startUDP followed by one or more
+ calls to bufferData.
+ @return 1 if the datagram was successfully sent, or 0 if there was an error
+*/
+int sendUDP(SOCKET s);
+
+#endif
+/* _SOCKET_H_ */
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h
new file mode 100644
index 00000000..8a254408
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/util.h
@@ -0,0 +1,42 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+static inline uint16_t htons(uint16_t x)
+{
+ return (x << 8) | ((x >> 8) & 0xFF);
+}
+
+#define ntohs(x) htons(x)
+
+#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \
+ ((x)<< 8 & 0x00FF0000UL) | \
+ ((x)>> 8 & 0x0000FF00UL) | \
+ ((x)>>24 & 0x000000FFUL) )
+#define ntohl(x) htonl(x)
+
+// Get a 16 bit word in network byte order from a buffer
+static inline uint16_t get16nb(const uint8_t *buf)
+{
+ return ((uint16_t)buf[0] << 8) | buf[1];
+}
+
+// Get a 32 bit word in network byte order from a buffer
+static inline uint16_t get32nb(const uint8_t *buf)
+{
+ return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3];
+}
+
+// Get a 16 bit word in native byte order from a buffer
+static inline uint16_t get16(const uint8_t *buf)
+{
+ return ((uint16_t)buf[1] << 8) | buf[0];
+}
+
+// Put a 16-bit word in native byte order in a buffer
+static inline void put16(uint8_t *buf, uint16_t n)
+{
+ buf[0] = (uint8_t)n;
+ buf[1] = (uint8_t)(n >> 8);
+}
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp
new file mode 100644
index 00000000..553f9ee5
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2010 by WIZnet <support@wiznet.co.kr>
+ *
+ * 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.
+ *
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "Core.h"
+
+#include "utility/w5500.h"
+#include "utility/WizSpi.h"
+
+// W5500 controller instance
+W5500Class w5500;
+
+
+void W5500Class::init(void)
+{
+ WizSpi::Init();
+
+ for (int i=0; i<MAX_SOCK_NUM; i++)
+ {
+ const uint8_t cntl_byte = (0x0C + (i<<5));
+ write( 0x1E, cntl_byte, 2); //0x1E - Sn_RXBUF_SIZE
+ write( 0x1F, cntl_byte, 2); //0x1F - Sn_TXBUF_SIZE
+ }
+}
+
+void W5500Class::stop()
+{
+ WizSpi::Stop();
+}
+
+uint16_t W5500Class::getTXFreeSize(SOCKET s)
+{
+ uint16_t val=0, val1=0;
+ do {
+ val1 = readSnTX_FSR(s);
+ if (val1 != 0)
+ val = readSnTX_FSR(s);
+ }
+ while (val != val1);
+ return val;
+}
+
+uint16_t W5500Class::getRXReceivedSize(SOCKET s)
+{
+ uint16_t val=0,val1=0;
+ do {
+ val1 = readSnRX_RSR(s);
+ if (val1 != 0)
+ val = readSnRX_RSR(s);
+ }
+ while (val != val1);
+ return val;
+}
+
+void W5500Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len)
+{
+ // This is same as having no offset in a call to send_data_processing_offset
+ send_data_processing_offset(s, 0, data, len);
+}
+
+void W5500Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
+{
+ uint16_t ptr = readSnTX_WR(s);
+ uint8_t cntl_byte = (0x14+(s<<5));
+ ptr += data_offset;
+ write(ptr, cntl_byte, data, len);
+ ptr += len;
+ writeSnTX_WR(s, ptr);
+
+}
+
+void W5500Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
+{
+ uint16_t ptr = readSnRX_RD(s);
+
+ read_data(s, ptr, data, len);
+ if (!peek)
+ {
+ ptr += len;
+ writeSnRX_RD(s, ptr);
+ }
+}
+
+void W5500Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len)
+{
+ uint8_t cntl_byte = (0x18+(s<<5));
+ read((uint16_t)src , cntl_byte, (uint8_t *)dst, len);
+}
+
+uint8_t W5500Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data)
+{
+ WizSpi::AssertSS();
+ WizSpi::ExchangeByte(_addr >> 8, false);
+ WizSpi::ExchangeByte(_addr & 0xFF, false);
+ WizSpi::ExchangeByte(_cb, false);
+ WizSpi::ExchangeByte(_data, true);
+ WizSpi::ReleaseSS();
+ return 1;
+}
+
+uint16_t W5500Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len)
+{
+ WizSpi::AssertSS();
+ WizSpi::ExchangeByte(_addr >> 8, false);
+ WizSpi::ExchangeByte(_addr & 0xFF, false);
+ WizSpi::ExchangeByte(_cb, false);
+ WizSpi::SendBurst(_buf, _len);
+ WizSpi::ReleaseSS();
+ return _len;
+}
+
+uint8_t W5500Class::read(uint16_t _addr, uint8_t _cb)
+{
+ WizSpi::AssertSS();
+ WizSpi::ExchangeByte(_addr >> 8, false);
+ WizSpi::ExchangeByte(_addr & 0xFF, false);
+ WizSpi::ExchangeByte(_cb, false);
+ const uint8_t _data = WizSpi::ExchangeByte(0, true);
+ WizSpi::ReleaseSS();
+ return _data;
+}
+
+uint16_t W5500Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len)
+{
+ WizSpi::AssertSS();
+ WizSpi::ExchangeByte(_addr >> 8, false);
+ WizSpi::ExchangeByte(_addr & 0xFF, false);
+ WizSpi::ExchangeByte(_cb, false);
+ WizSpi::ReadBurst(_buf, _len);
+ WizSpi::ReleaseSS();
+ return _len;
+}
+
+void W5500Class::execCmdSn(SOCKET s, SockCMD _cmd) {
+ // Send command to socket
+ writeSnCR(s, _cmd);
+ // Wait for command to complete
+ while (readSnCR(s))
+ ;
+}
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h
new file mode 100644
index 00000000..418da9a8
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Ethernet3/utility/w5500.h
@@ -0,0 +1,443 @@
+/*
+* Copyright (c) 2010 by WIZnet <support@wiznet.co.kr>
+ *
+ * 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.
+ *
+ * - 10 Apr. 2015
+ * Added support for Arduino Ethernet Shield 2
+ * by Arduino.org team
+ */
+
+#ifndef W5500_H_INCLUDED
+#define W5500_H_INCLUDED
+
+#include <cstdint>
+
+// The SAM4E header files define UDP as a macro for accessing the USB Device Port, which clashes with UDP in this module. So un-define it.
+#undef UDP
+
+#define MAX_SOCK_NUM 8
+
+typedef uint8_t SOCKET;
+/*
+class MR {
+public:
+ static const uint8_t RST = 0x80;
+ static const uint8_t PB = 0x10;
+ static const uint8_t PPPOE = 0x08;
+ static const uint8_t LB = 0x04;
+ static const uint8_t AI = 0x02;
+ static const uint8_t IND = 0x01;
+};
+*/
+/*
+class IR {
+public:
+ static const uint8_t CONFLICT = 0x80;
+ static const uint8_t UNREACH = 0x40;
+ static const uint8_t PPPoE = 0x20;
+ static const uint8_t SOCK0 = 0x01;
+ static const uint8_t SOCK1 = 0x02;
+ static const uint8_t SOCK2 = 0x04;
+ static const uint8_t SOCK3 = 0x08;
+ static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
+};
+*/
+
+class SnMR {
+public:
+ static const uint8_t CLOSE = 0x00;
+ static const uint8_t TCP = 0x01;
+ 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 SnCmd {
+public:
+ static const uint8_t OPEN = 0x01;
+ static const uint8_t LISTEN = 0x02;
+ static const uint8_t CONNECT = 0x04;
+ static const uint8_t DISCON = 0x08;
+ static const uint8_t CLOSE = 0x10;
+ static const uint8_t SEND = 0x20;
+ static const uint8_t SEND_MAC = 0x21;
+ static const uint8_t SEND_KEEP = 0x22;
+ static const uint8_t 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;
+};
+
+class W5500Class {
+
+public:
+ void init();
+
+ void stop();
+
+ /**
+ * @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
+ *
+ * It calculate the actual physical address where one has to read
+ * the data from Receive buffer. Here also take care of the condition while it exceed
+ * the Rx memory uper-bound of socket.
+ */
+ void read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);
+
+ /**
+ * @brief This function is being called by send() and sendto() function also.
+ *
+ * This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
+ * register. User should read upper byte first and lower byte later to get proper value.
+ */
+ void send_data_processing(SOCKET s, const uint8_t *data, uint16_t len);
+ /**
+ * @brief A copy of send_data_processing that uses the provided ptr for the
+ * write offset. Only needed for the "streaming" UDP API, where
+ * a single UDP packet is built up over a number of calls to
+ * send_data_processing_ptr, because TX_WR doesn't seem to get updated
+ * correctly in those scenarios
+ * @param ptr value to use in place of TX_WR. If 0, then the value is read
+ * in from TX_WR
+ * @return New value for ptr, to be used in the next call
+ */
+ // FIXME Update documentation
+ void send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len);
+
+ /**
+ * @brief This function is being called by recv() also.
+ *
+ * This function read the Rx read pointer register
+ * and after copy the data from receive buffer update the Rx write pointer register.
+ * User should read upper byte first and lower byte later to get proper value.
+ */
+ void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek = 0);
+
+ inline void setGatewayIp(const uint8_t *_addr);
+ inline void getGatewayIp(uint8_t *_addr);
+
+ inline void setSubnetMask(const uint8_t *_addr);
+ inline void getSubnetMask(uint8_t *_addr);
+
+ inline void setMACAddress(const uint8_t * addr);
+ inline void getMACAddress(uint8_t * addr);
+
+ inline void setIPAddress(const uint8_t * addr);
+ inline void getIPAddress(uint8_t * addr);
+
+ inline void setRetransmissionTime(uint16_t timeout);
+ inline void setRetransmissionCount(uint8_t _retry);
+
+ inline void setPHYCFGR(uint8_t _val);
+ inline uint8_t getPHYCFGR();
+
+ void execCmdSn(SOCKET s, SockCMD _cmd);
+
+ uint16_t getTXFreeSize(SOCKET s);
+ uint16_t getRXReceivedSize(SOCKET s);
+
+
+ // W5500 Registers
+ // ---------------
+private:
+ static uint8_t write(uint16_t _addr, uint8_t _cb, uint8_t _data);
+ static uint16_t write(uint16_t _addr, uint8_t _cb, const uint8_t *buf, uint16_t len);
+ static uint8_t read(uint16_t _addr, uint8_t _cb );
+ static uint16_t read(uint16_t _addr, uint8_t _cb, uint8_t *buf, uint16_t len);
+
+#define __GP_REGISTER8(name, address) \
+ static inline void write##name(uint8_t _data) { \
+ write(address, 0x04, _data); \
+ } \
+ static inline uint8_t read##name() { \
+ return read(address, 0x00); \
+ }
+#define __GP_REGISTER16(name, address) \
+ static void write##name(uint16_t _data) { \
+ write(address, 0x04, _data >> 8); \
+ write(address+1, 0x04, _data & 0xFF); \
+ } \
+ static uint16_t read##name() { \
+ uint16_t res = read(address, 0x00); \
+ res = (res << 8) + read(address + 1, 0x00); \
+ return res; \
+ }
+#define __GP_REGISTER_N(name, address, size) \
+ static uint16_t write##name(const uint8_t *_buff) { \
+ return write(address, 0x04, _buff, size); \
+ } \
+ static uint16_t read##name(uint8_t *_buff) { \
+ return read(address, 0x00, _buff, size); \
+ }
+
+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, 0x0019); // Timeout address
+ __GP_REGISTER8 (RCR, 0x001B); // Retry count
+ __GP_REGISTER_N(UIPR, 0x0028, 4); // Unreachable IP address in UDP mode
+ __GP_REGISTER16(UPORT, 0x002C); // Unreachable Port address in UDP mode
+ __GP_REGISTER8 (PHYCFGR, 0x002E); // PHY Configuration register, default value: 0b 1011 1xxx
+ __GP_REGISTER8 (VERSIONR, 0x0039); // Version register, should return 0x04
+
+
+#undef __GP_REGISTER8
+#undef __GP_REGISTER16
+#undef __GP_REGISTER_N
+
+ // W5500 Socket registers
+ // ----------------------
+private:
+ static inline uint8_t readSn(SOCKET _s, uint16_t _addr);
+ static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data);
+ static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
+ static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
+
+ //static const uint16_t CH_BASE = 0x0000;
+ //static const uint16_t CH_SIZE = 0x0000;
+
+#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); \
+ }
+#if defined(REL_GR_KURUMI) || defined(REL_GR_KURUMI_PROTOTYPE)
+#define __SOCKET_REGISTER16(name, address) \
+ static void write##name(SOCKET _s, uint16_t _data) { \
+ writeSn(_s, address, _data >> 8); \
+ writeSn(_s, address+1, _data & 0xFF); \
+ } \
+ static uint16_t read##name(SOCKET _s) { \
+ uint16_t res = readSn(_s, address); \
+ uint16_t res2 = readSn(_s,address + 1); \
+ res = res << 8; \
+ res2 = res2 & 0xFF; \
+ res = res | res2; \
+ return res; \
+ }
+#else
+#define __SOCKET_REGISTER16(name, address) \
+ static void write##name(SOCKET _s, uint16_t _data) { \
+ writeSn(_s, address, _data >> 8); \
+ writeSn(_s, address+1, _data & 0xFF); \
+ } \
+ static uint16_t read##name(SOCKET _s) { \
+ uint16_t res = readSn(_s, address); \
+ res = (res << 8) + readSn(_s, address + 1); \
+ return res; \
+ }
+#endif
+#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_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:
+ static const uint8_t RST = 7; // Reset BIT
+ static const int SOCKETS = 8;
+
+public:
+ static const uint16_t SSIZE = 2048; // Max Tx buffer size
+private:
+ static const uint16_t RSIZE = 2048; // Max Rx buffer size
+
+private:
+#if defined(ARDUINO_ARCH_AVR)
+#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284P__)
+ inline static void initSS() { DDRB |= _BV(4); };
+ inline static void setSS() { PORTB &= ~_BV(4); };
+ inline static void resetSS() { PORTB |= _BV(4); };
+#elif defined(__AVR_ATmega32U4__)
+ inline static void initSS() { DDRB |= _BV(6); };
+ inline static void setSS() { PORTB &= ~_BV(6); };
+ inline static void resetSS() { PORTB |= _BV(6); };
+#elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
+ inline static void initSS() { DDRB |= _BV(0); };
+ inline static void setSS() { PORTB &= ~_BV(0); };
+ inline static void resetSS() { PORTB |= _BV(0); };
+#elif defined(REL_GR_KURUMI) || defined(REL_GR_KURUMI_PROTOTYPE)
+ inline static void initSS() { pinMode(SS, OUTPUT);
+ digitalWrite(SS, HIGH); };
+ inline static void setSS() { digitalWrite(SS, LOW); };
+ inline static void resetSS() { digitalWrite(SS, HIGH); };
+#else
+ inline static void initSS() { DDRB |= _BV(2); };
+ inline static void setSS() { PORTB &= ~_BV(2); };
+ inline static void resetSS() { PORTB |= _BV(2); };
+#endif
+#elif defined(ARDUINO_ARCH_SAMD)
+ inline static void initSS() { PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].reg&=~(uint8_t)(PORT_PINCFG_INEN) ;
+ PORT->Group[g_APinDescription[10].ulPort].DIRSET.reg = (uint32_t)(1<<g_APinDescription[10].ulPin) ;
+ PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].reg=(uint8_t)(PORT_PINCFG_PULLEN) ;
+ PORT->Group[g_APinDescription[10].ulPort].OUTSET.reg = (1ul << g_APinDescription[10].ulPin) ; };
+ inline static void setSS() { PORT->Group[g_APinDescription[10].ulPort].OUTCLR.reg = (1ul << g_APinDescription[10].ulPin) ; };
+ inline static void resetSS() { PORT->Group[g_APinDescription[10].ulPort].OUTSET.reg = (1ul << g_APinDescription[10].ulPin) ; };
+#endif // ARDUINO_ARCH_AVR
+};
+
+extern W5500Class w5500;
+
+uint8_t W5500Class::readSn(SOCKET _s, uint16_t _addr) {
+ uint8_t cntl_byte = (_s<<5)+0x08;
+ return read(_addr, cntl_byte);
+}
+
+uint8_t W5500Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) {
+ uint8_t cntl_byte = (_s<<5)+0x0C;
+ return write(_addr, cntl_byte, _data);
+}
+
+uint16_t W5500Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
+ uint8_t cntl_byte = (_s<<5)+0x08;
+ return read(_addr, cntl_byte, _buf, _len );
+}
+
+uint16_t W5500Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
+ uint8_t cntl_byte = (_s<<5)+0x0C;
+ return write(_addr, cntl_byte, _buf, _len);
+}
+
+void W5500Class::getGatewayIp(uint8_t *_addr) {
+ readGAR(_addr);
+}
+
+void W5500Class::setGatewayIp(const uint8_t *_addr) {
+ writeGAR(_addr);
+}
+
+void W5500Class::getSubnetMask(uint8_t *_addr) {
+ readSUBR(_addr);
+}
+
+void W5500Class::setSubnetMask(const uint8_t *_addr) {
+ writeSUBR(_addr);
+}
+
+void W5500Class::getMACAddress(uint8_t *_addr) {
+ readSHAR(_addr);
+}
+
+void W5500Class::setMACAddress(const uint8_t *_addr) {
+ writeSHAR(_addr);
+}
+
+void W5500Class::getIPAddress(uint8_t *_addr) {
+ readSIPR(_addr);
+}
+
+void W5500Class::setIPAddress(const uint8_t *_addr) {
+ writeSIPR(_addr);
+}
+
+void W5500Class::setRetransmissionTime(uint16_t _timeout) {
+ writeRTR(_timeout);
+}
+
+void W5500Class::setRetransmissionCount(uint8_t _retry) {
+ writeRCR(_retry);
+}
+
+void W5500Class::setPHYCFGR(uint8_t _val) {
+ writePHYCFGR(_val);
+}
+
+uint8_t W5500Class::getPHYCFGR() {
+// readPHYCFGR();
+ return read(0x002E, 0x00);
+}
+
+#endif
diff --git a/src/DuetNG/DuetEthernet/Network.cpp b/src/DuetNG/DuetEthernet/Network.cpp
index 73199aa9..094795d7 100644
--- a/src/DuetNG/DuetEthernet/Network.cpp
+++ b/src/DuetNG/DuetEthernet/Network.cpp
@@ -5,12 +5,11 @@
* Author: David
*/
-#include "Network.h"
+#include "RepRapFirmware.h"
+#include "compiler.h"
+#include "Pins.h"
+#include "Ethernet3/Ethernet3.h"
-const uint8_t *Network::IPAddress() const
-{
- return ipAddress;
-}
void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[])
{
@@ -19,30 +18,63 @@ void Network::SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[
memcpy(gateway, p_gateway, sizeof(gateway));
}
-Network::Network(Platform* p)
- : httpPort(DEFAULT_HTTP_PORT)
+Network::Network(Platform* p) : platform(p), responseCode(0), responseBody(nullptr), responseText(nullptr), responseFile(nullptr),
+ httpPort(DEFAULT_HTTP_PORT),
+ state(disabled), activated(false)
{
SetIPAddress(IP_ADDRESS, NET_MASK, GATE_WAY);
+ strcpy(hostname, HOSTNAME);
}
void Network::Init()
{
-
+ // Ensure that the chip is in the reset state
+ pinMode(EspResetPin, OUTPUT_LOW);
+ state = disabled;
}
+// This is called at the end of config.g processing.
+// Start the network if it was enabled
void Network::Activate()
{
-
+ activated = true;
+ if (state == enabled)
+ {
+ Start();
+ }
}
void Network::Exit()
{
-
+ Stop();
}
void Network::Spin()
{
-
+#if 1
+#if 0
+ if (state == starting)
+ {
+ const int rc = Ethernet.begin(platform->MACAddress(), 12000, 5000); // for now we always use DHCP
+ if (rc == 1)
+ {
+ state = running;
+ }
+ }
+ else if (state == running)
+#else
+ if (state == starting || state == running)
+#endif
+ {
+ // Check DHCP
+ const int rc = Ethernet.maintain();
+ if (state == starting && (rc == DHCP_CHECK_RENEW_OK || rc == DHCP_CHECK_REBIND_OK))
+ {
+ state = running;
+ }
+ }
+#endif
+ platform->ClassReport(longWait);
}
void Network::Diagnostics(MessageType mtype)
@@ -52,27 +84,96 @@ void Network::Diagnostics(MessageType mtype)
void Network::Start()
{
-
+ pinMode(EspResetPin, OUTPUT_LOW);
+ delayMicroseconds(550); // W550 reset pulse must be at least 500us long
+ Platform::WriteDigital(EspResetPin, HIGH); // raise /Reset pin
+ delay(55); // W5500 needs 50ms to start up
+ state = starting;
+#if 0
+ w5500.init();
+ w5500.setMACAddress(platform->MACAddress());
+#endif
+ const int rc = Ethernet.begin(platform->MACAddress(), 12000, 5000); // for now we always use DHCP
+ if (rc == 1)
+ {
+ state = running;
+ }
+ else
+ {
+#if 1
+ {
+ uint8_t tmp = w5500.readPHYCFGR();
+ uint8_t version = w5500.readVERSIONR();
+ uint8_t macBuf[6];
+ w5500.readSHAR(macBuf);
+ platform->MessageF(GENERIC_MESSAGE, "Phy %02x ver %02x Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
+ tmp, version, macBuf[0], macBuf[1], macBuf[2], macBuf[3], macBuf[4], macBuf[5]);
+ }
+#endif
+ platform->Message(GENERIC_MESSAGE, "Failed to start Ethernet interface\n");
+ Stop();
+ }
}
void Network::Stop()
{
-
+ if (state != disabled)
+ {
+ Ethernet.stop();
+ digitalWrite(EspResetPin, LOW); // put the ESP back into reset
+ state = disabled;
+ }
}
void Network::Enable()
{
-
+ if (state == disabled)
+ {
+ state = enabled;
+ if (activated)
+ {
+ Start();
+ }
+ }
+#if 1
+ else if (state == starting)
+ {
+ uint8_t tmp = w5500.readPHYCFGR();
+ uint8_t version = w5500.readVERSIONR();
+ uint8_t macBuf[6];
+ w5500.readSHAR(macBuf);
+ platform->MessageF(GENERIC_MESSAGE, "Phy %02x ver %02x Mac %02x:%02x:%02x:%02x:%02x:%02x\n",
+ tmp, version, macBuf[0], macBuf[1], macBuf[2], macBuf[3], macBuf[4], macBuf[5]);
+ }
+#endif
}
void Network::Disable()
{
-
+ if (activated && state != disabled)
+ {
+ Stop();
+ platform->Message(GENERIC_MESSAGE, "WiFi server stopped\n");
+ }
}
bool Network::IsEnabled() const
{
- return false;
+ return state != disabled;
+}
+
+const uint8_t *Network::GetIPAddress() const
+{
+ if (state == running)
+ {
+ static IPAddress ip;
+ ip = Ethernet.localIP();
+ return ip.GetRawAddress();
+ }
+ else
+ {
+ return ipAddress;
+ }
}
void Network::SetHttpPort(uint16_t port)
@@ -87,7 +188,29 @@ uint16_t Network::GetHttpPort() const
void Network::SetHostname(const char *name)
{
-
+ size_t i = 0;
+ while (*name && i < ARRAY_UPB(hostname))
+ {
+ char c = *name++;
+ if (c >= 'A' && c <= 'Z')
+ {
+ c += 'a' - 'A';
+ }
+
+ if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '-') || (c == '_'))
+ {
+ hostname[i++] = c;
+ }
+ }
+
+ if (i)
+ {
+ hostname[i] = 0;
+ }
+ else
+ {
+ strcpy(hostname, HOSTNAME);
+ }
}
// End
diff --git a/src/DuetNG/DuetEthernet/Network.h b/src/DuetNG/DuetEthernet/Network.h
index 1daa2db4..88edd5f0 100644
--- a/src/DuetNG/DuetEthernet/Network.h
+++ b/src/DuetNG/DuetEthernet/Network.h
@@ -21,10 +21,11 @@ const uint32_t rcNumber = 0x0000FFFF;
const uint32_t rcJson = 0x00010000;
const uint32_t rcKeepOpen = 0x00020000;
-static const uint8_t IP_ADDRESS[4] = { 192, 168, 1, 10 }; // Need some sort of default...
-static const uint8_t NET_MASK[4] = { 255, 255, 255, 0 };
-static const uint8_t GATE_WAY[4] = { 192, 168, 1, 1 };
-static const uint16_t DEFAULT_HTTP_PORT = 80;
+const uint8_t IP_ADDRESS[4] = { 192, 168, 1, 10 }; // Need some sort of default...
+const uint8_t NET_MASK[4] = { 255, 255, 255, 0 };
+const uint8_t GATE_WAY[4] = { 192, 168, 1, 1 };
+const uint8_t MAC_ADDRESS[6] = { 0xBE, 0xEF, 0xDE, 0xAD, 0xFE, 0xED }; // Need some sort of default...
+const uint16_t DEFAULT_HTTP_PORT = 80;
class TransactionBuffer;
class WifiFirmwareUploader;
@@ -33,8 +34,21 @@ class Platform;
// The main network class that drives the network.
class Network
{
+ enum NetworkState
+ {
+ disabled, // WiFi not active
+ enabled, // WiFi enabled but not started yet
+ starting, // starting up (waiting for initialisation)
+ running
+// idle, // nothing happening
+// receivePending, // we have asserted TransferReady and await completion of a receive-only transaction
+// sendReceivePending, // we have asserted TransferReady and await completion of a transmit/receive
+// transferDone, // transfer completed but receive DMA fifo may not have been flushed yet
+// processing, // a transaction has been completed but we haven't released the input buffer yet
+// sending // a transaction has been completed and we are sending the response
+ };
public:
- const uint8_t *IPAddress() const;
+ const uint8_t *GetIPAddress() const;
void SetIPAddress(const uint8_t p_ipAddress[], const uint8_t p_netmask[], const uint8_t p_gateway[]);
Network(Platform* p);
@@ -58,10 +72,28 @@ public:
void SetHostname(const char *name);
private:
- uint16_t httpPort;
+ void SetupSpi();
+
+ Platform *platform;
+
+// uint32_t responseIp;
+ uint32_t responseCode;
+// uint32_t responseFragment;
+ OutputBuffer *responseBody;
+ const char* responseText;
+ FileStore *responseFile;
+// uint32_t responseFileBytes;
+
+ float longWait;
+
+ uint16_t httpPort;
uint8_t ipAddress[4];
uint8_t netmask[4];
uint8_t gateway[4];
+ char hostname[16]; // Limit DHCP hostname to 15 characters + terminating 0
+
+ NetworkState state;
+ bool activated;
};
#endif
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.c b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.c
deleted file mode 100644
index 68d4cb8b..00000000
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.c
+++ /dev/null
@@ -1,267 +0,0 @@
-//*****************************************************************************
-//
-//! \file w5500.c
-//! \brief W5500 HAL Interface.
-//! \version 1.0.2
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.2
-//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
-//! Fixed the problem on porting into under 32bit MCU
-//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
-//! Thank for your interesting and serious advices.
-//! <2013/12/20> V1.0.1
-//! 1. Remove warning
-//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
-//! for loop optimized(removed). refer to M20131220
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-//#include <stdio.h>
-#include "w5500.h"
-
-#define _W5500_SPI_VDM_OP_ 0x00
-#define _W5500_SPI_FDM_OP_LEN1_ 0x01
-#define _W5500_SPI_FDM_OP_LEN2_ 0x02
-#define _W5500_SPI_FDM_OP_LEN4_ 0x03
-
-#if (_WIZCHIP_ == 5500)
-////////////////////////////////////////////////////
-
-uint8_t WIZCHIP_READ(uint32_t AddrSel)
-{
- uint8_t ret;
- uint8_t spi_data[3];
-
- WIZCHIP_CRITICAL_ENTER();
- WIZCHIP.CS._select();
-
- AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
-
- if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
- {
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
- }
- else // burst operation
- {
- spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
- spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
- spi_data[2] = (AddrSel & 0x000000FF) >> 0;
- WIZCHIP.IF.SPI._write_burst(spi_data, 3);
- }
- ret = WIZCHIP.IF.SPI._read_byte();
-
- WIZCHIP.CS._deselect();
- WIZCHIP_CRITICAL_EXIT();
- return ret;
-}
-
-void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
-{
- uint8_t spi_data[4];
-
- WIZCHIP_CRITICAL_ENTER();
- WIZCHIP.CS._select();
-
- AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
-
- //if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
- if(!WIZCHIP.IF.SPI._write_burst) // byte operation
- {
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
- WIZCHIP.IF.SPI._write_byte(wb);
- }
- else // burst operation
- {
- spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
- spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
- spi_data[2] = (AddrSel & 0x000000FF) >> 0;
- spi_data[3] = wb;
- WIZCHIP.IF.SPI._write_burst(spi_data, 4);
- }
-
- WIZCHIP.CS._deselect();
- WIZCHIP_CRITICAL_EXIT();
-}
-
-void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
-{
- uint8_t spi_data[3];
- uint16_t i;
-
- WIZCHIP_CRITICAL_ENTER();
- WIZCHIP.CS._select();
-
- AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
-
- if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
- {
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
- for(i = 0; i < len; i++)
- pBuf[i] = WIZCHIP.IF.SPI._read_byte();
- }
- else // burst operation
- {
- spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
- spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
- spi_data[2] = (AddrSel & 0x000000FF) >> 0;
- WIZCHIP.IF.SPI._write_burst(spi_data, 3);
- WIZCHIP.IF.SPI._read_burst(pBuf, len);
- }
-
- WIZCHIP.CS._deselect();
- WIZCHIP_CRITICAL_EXIT();
-}
-
-void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
-{
- uint8_t spi_data[3];
- uint16_t i;
-
- WIZCHIP_CRITICAL_ENTER();
- WIZCHIP.CS._select();
-
- AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);
-
- if(!WIZCHIP.IF.SPI._write_burst) // byte operation
- {
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
- WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
- for(i = 0; i < len; i++)
- WIZCHIP.IF.SPI._write_byte(pBuf[i]);
- }
- else // burst operation
- {
- spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
- spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
- spi_data[2] = (AddrSel & 0x000000FF) >> 0;
- WIZCHIP.IF.SPI._write_burst(spi_data, 3);
- WIZCHIP.IF.SPI._write_burst(pBuf, len);
- }
-
- WIZCHIP.CS._deselect();
- WIZCHIP_CRITICAL_EXIT();
-}
-
-
-uint16_t getSn_TX_FSR(uint8_t sn)
-{
- uint16_t val=0,val1=0;
-
- do
- {
- val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
- val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
- if (val1 != 0)
- {
- val = WIZCHIP_READ(Sn_TX_FSR(sn));
- val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
- }
- }while (val != val1);
- return val;
-}
-
-
-uint16_t getSn_RX_RSR(uint8_t sn)
-{
- uint16_t val=0,val1=0;
-
- do
- {
- val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
- val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
- if (val1 != 0)
- {
- val = WIZCHIP_READ(Sn_RX_RSR(sn));
- val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
- }
- }while (val != val1);
- return val;
-}
-
-void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
-{
- uint16_t ptr = 0;
- uint32_t addrsel = 0;
-
- if(len == 0) return;
- ptr = getSn_TX_WR(sn);
- //M20140501 : implict type casting -> explict type casting
- //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
- addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
- //
- WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
-
- ptr += len;
- setSn_TX_WR(sn,ptr);
-}
-
-void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
-{
- uint16_t ptr = 0;
- uint32_t addrsel = 0;
-
- if(len == 0) return;
- ptr = getSn_RX_RD(sn);
- //M20140501 : implict type casting -> explict type casting
- //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
- addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
- //
- WIZCHIP_READ_BUF(addrsel, wizdata, len);
- ptr += len;
-
- setSn_RX_RD(sn,ptr);
-}
-
-
-void wiz_recv_ignore(uint8_t sn, uint16_t len)
-{
- uint16_t ptr = 0;
-
- ptr = getSn_RX_RD(sn);
- ptr += len;
- setSn_RX_RD(sn,ptr);
-}
-
-#endif
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp
new file mode 100644
index 00000000..7447386b
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.cpp
@@ -0,0 +1,165 @@
+//*****************************************************************************
+//
+//! \file w5500.cpp
+//! \brief W5500 HAL Interface.
+//! \version 1.0.2
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.2
+//! 1. Implicit type casting -> Explicit type casting. Refer to M20140501
+//! Fixed the problem on porting into under 32bit MCU
+//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
+//! Thank for your interesting and serious advices.
+//! <2013/12/20> V1.0.1
+//! 1. Remove warning
+//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
+//! for loop optimized(removed). refer to M20131220
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+
+#include "w5500.h"
+
+#define _W5500_SPI_VDM_OP_ 0x00
+#define _W5500_SPI_FDM_OP_LEN1_ 0x01
+#define _W5500_SPI_FDM_OP_LEN2_ 0x02
+#define _W5500_SPI_FDM_OP_LEN4_ 0x03
+
+////////////////////////////////////////////////////
+
+uint8_t WIZCHIP_READ(uint32_t AddrSel)
+{
+ SpiAssertSS();
+ SpiSendAddress(AddrSel | (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_));
+ const uint8_t ret = SpiReadByte();
+ SpiReleaseSS();
+ return ret;
+}
+
+void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb )
+{
+ SpiAssertSS();
+ SpiSendAddress(AddrSel | (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_));
+ SpiSendByte(wb);
+ SpiReleaseSS();
+}
+
+void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
+{
+ SpiAssertSS();
+ SpiSendAddress(AddrSel | (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_));
+ SpiReadBurst(pBuf, len);
+ SpiReleaseSS();
+}
+
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, const uint8_t* pBuf, uint16_t len)
+{
+ SpiAssertSS();
+ SpiSendAddress(AddrSel | (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_));
+ SpiSendBurst(pBuf, len);
+ SpiReleaseSS();
+}
+
+
+uint16_t getSn_TX_FSR(uint8_t sn)
+{
+ uint16_t val = 0, val1 = 0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_TX_FSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1));
+ }
+ } while (val != val1);
+ return val;
+}
+
+
+uint16_t getSn_RX_RSR(uint8_t sn)
+{
+ uint16_t val = 0, val1 = 0;
+ do
+ {
+ val1 = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ if (val1 != 0)
+ {
+ val = WIZCHIP_READ(Sn_RX_RSR(sn));
+ val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1));
+ }
+ } while (val != val1);
+ return val;
+}
+
+void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ if (len != 0)
+ {
+ uint16_t ptr = getSn_TX_WR(sn);
+ uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
+ WIZCHIP_WRITE_BUF(addrsel,wizdata, len);
+
+ ptr += len;
+ setSn_TX_WR(sn,ptr);
+ }
+}
+
+void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len)
+{
+ if (len != 0)
+ {
+ uint16_t ptr = getSn_RX_RD(sn);
+ uint32_t addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
+ WIZCHIP_READ_BUF(addrsel, wizdata, len);
+ ptr += len;
+
+ setSn_RX_RD(sn,ptr);
+ }
+}
+
+
+void wiz_recv_ignore(uint8_t sn, uint16_t len)
+{
+ uint16_t ptr = getSn_RX_RD(sn);
+ ptr += len;
+ setSn_RX_RD(sn,ptr);
+}
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
index 051ef753..048c47eb 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/W5500/w5500.h
@@ -48,12 +48,20 @@
#ifndef _W5500_H_
#define _W5500_H_
-#include <stdint.h>
+#include <cstdint>
+#include <cstddef>
#include "../wizchip_conf.h"
+#include "spi.h"
+
+// The following functions are defined in Network.cpp and used by this module
+extern void SpiAssertSS();
+extern void SpiReleaseSS();
+extern void SpiSendAddress(uint32_t);
+extern uint8_t SpiReadByte();
+extern void SpiSendByte(uint8_t b);
+extern spi_status_t SpiReadBurst(uint8_t* pBuf, size_t len);
+extern spi_status_t SpiSendBurst(const uint8_t* pBuf, size_t len);
-/// @cond DOXY_APPLY_CODE
-#if (_WIZCHIP_ == 5500)
-/// @endcond
#define _W5500_IO_BASE_ 0x00000000
@@ -211,42 +219,42 @@
* - \ref MR_PPPOE : PPPoE mode
* - \ref MR_FARP : Force ARP mode
*/
-#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+const uint32_t MR = _W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief Gateway IP Register address(R/W)
* @details @ref GAR configures the default gateway address.
*/
-#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t GAR = _W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief Subnet mask Register address(R/W)
* @details @ref SUBR configures the subnet mask address.
*/
-#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t SUBR = _W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief Source MAC Register address(R/W)
* @details @ref SHAR configures the source hardware address.
*/
-#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t SHAR = _W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief Source IP Register address(R/W)
* @details @ref SIPR configures the source IP address.
*/
-#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t SIPR = _W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief Set Interrupt low level timer register address(R/W)
* @details @ref INTLEVEL configures the Interrupt Assert Time.
*/
-#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t INTLEVEL = _W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -263,7 +271,7 @@
* - \ref IR_PPPoE : PPPoE connection close
* - \ref IR_MP : Magic packet
*/
-#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t IR = _W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -281,9 +289,7 @@
* - \ref IM_IR5 : PPPoE Close Interrupt Mask
* - \ref IM_IR4 : Magic Packet Interrupt Mask
*/
-//M20150401 : Rename SYMBOE ( Re-define error in a compile)
-//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t _IMR_ = _W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -291,7 +297,7 @@
* @details @ref SIR indicates the interrupt status of Socket.\n
* Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n
* If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is asserted until @ref SIR is x00 */
-#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t SIR = _W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -300,7 +306,7 @@
* When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt will be issued.
* In other words, if a bit of @ref SIMR is an interrupt will be not issued even if the corresponding bit of @ref SIR is
*/
-#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t SIMR = _W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -310,9 +316,7 @@
* to the packet that is transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP command).
* If the peer does not respond within the @ref _RTR_ time, W5500 retransmits the packet or issues timeout.
*/
-//M20150401 : Rename SYMBOE ( Re-define error in a compile)
-//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
-#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t _RTR_ = _W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -320,44 +324,42 @@
* @details @ref _RCR_ configures the number of time of retransmission.
* When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued (@ref Sn_IR_TIMEOUT = '1').
*/
-//M20150401 : Rename SYMBOE ( Re-define error in a compile)
-//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
-#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t _RCR_ = _W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PPP LCP Request Timer register in PPPoE mode(R/W)
* @details @ref PTIMER configures the time for sending LCP echo request. The unit of time is 25ms.
*/
-#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PTIMER = _W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PPP LCP Magic number register in PPPoE mode(R/W)
* @details @ref PMAGIC configures the 4bytes magic number to be used in LCP negotiation.
*/
-#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PMAGIC = _W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PPP Destination MAC Register address(R/W)
* @details @ref PHAR configures the PPPoE server hardware address that is acquired during PPPoE connection process.
*/
-#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PHAR = _W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PPP Session Identification Register(R/W)
* @details @ref PSID configures the PPPoE sever session ID acquired during PPPoE connection process.
*/
-#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PSID = _W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PPP Maximum Segment Size(MSS) register(R/W)
* @details @ref PMRU configures the maximum receive unit of PPPoE.
*/
-#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PMRU = _W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -366,7 +368,7 @@
* which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates
* the destination IP address & port number respectively.
*/
-#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t UIPR = _W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
@@ -375,14 +377,14 @@
* which socket is not open and @ref IR_UNREACH bit of @ref IR becomes and @ref UIPR & @ref UPORTR
* indicates the destination IP address & port number respectively.
*/
-#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t UPORTR = _W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3);
/**
* @ingroup Common_register_group
* @brief PHY Status Register(R/W)
* @details @ref PHYCFGR configures PHY operation mode and resets PHY. In addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, Link.
*/
-#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t PHYCFGR = _W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3);
// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_CREG_BLOCK << 3))
// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_CREG_BLOCK << 3))
@@ -400,7 +402,7 @@
* @brief chip version register address(R)
* @details @ref VERSIONR always indicates the W5500 version as @b 0x04.
*/
-#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3))
+ const uint32_t VERSIONR = _W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3);
//----------------------------- W5500 Socket Registers IOMAP -----------------------------
@@ -434,7 +436,10 @@
* - @ref Sn_MR_CLOSE : Unused socket
* @note MACRAW mode should be only used in Socket 0.
*/
-#define Sn_MR(N) (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_MR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -453,7 +458,10 @@
* - @ref Sn_CR_SEND_KEEP : Send keep alive message.
* - @ref Sn_CR_RECV : Update RX buffer pointer and receive data.
*/
-#define Sn_CR(N) (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_CR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -471,7 +479,10 @@
* - \ref Sn_IR_DISCON : <b>DISCON Interrupt</b>
* - \ref Sn_IR_CON : <b>CON Interrupt</b>
*/
-#define Sn_IR(N) (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_IR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -494,7 +505,10 @@
* - @ref SOCK_TIME_WAIT : Closing state
* - @ref SOCK_LAST_ACK : Closing state
*/
-#define Sn_SR(N) (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_SR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -502,7 +516,10 @@
* @details @ref Sn_PORT configures the source port number of Socket n.
* It is valid when Socket n is used in TCP/UDP mode. It should be set before OPEN command is ordered.
*/
-#define Sn_PORT(N) (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_PORT(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -510,7 +527,10 @@
* @details @ref Sn_DHAR configures the destination hardware address of Socket n when using SEND_MAC command in UDP mode or
* it indicates that it is acquired in ARP-process by CONNECT/SEND command.
*/
-#define Sn_DHAR(N) (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_DHAR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -520,7 +540,10 @@
* In TCP server mode, it indicates an IP address of TCP clientafter successfully establishing connection.
* In UDP mode, it configures an IP address of peer to be received the UDP packet by SEND or SEND_MAC command.
*/
-#define Sn_DIPR(N) (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_DIPR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -530,14 +553,20 @@
* In TCP Servermode, it indicates the port number of TCP client after successfully establishing connection.
* In UDP mode, it configures the port number of peer to be transmitted the UDP packet by SEND/SEND_MAC command.
*/
-#define Sn_DPORT(N) (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_DPORT(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
* @brief Maximum Segment Size(Sn_MSSR0) register address(R/W)
* @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) of Socket n.
*/
-#define Sn_MSSR(N) (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_MSSR(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@@ -547,14 +576,22 @@
* @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) of Socket n.
* It is set before OPEN command.
*/
-#define Sn_TOS(N) (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TOS(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
+
/**
* @ingroup Socket_register_group
* @brief IP Time to live(TTL) Register(R/W)
* @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of Socket n.
* It is set before OPEN command.
*/
-#define Sn_TTL(N) (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TTL(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
+
// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
// Reserved (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
// Reserved (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@@ -573,7 +610,10 @@
* user can re-configure its size using @ref Sn_RXBUF_SIZE. The total sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes.
* When exceeded, the data reception error is occurred.
*/
-#define Sn_RXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_RXBUF_SIZE(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -584,7 +624,10 @@
* user can be re-configure its size using @ref Sn_TXBUF_SIZE. The total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes.
* When exceeded, the data transmission error is occurred.
*/
-#define Sn_TXBUF_SIZE(N) (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TXBUF_SIZE(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -595,7 +638,10 @@
* transmit the data with SEND/SEND_MAC command after saving the data in Socket n TX buffer. But, if data is bigger than its checked size,
* transmit the data after dividing into the checked size and saving in the Socket n TX buffer.
*/
-#define Sn_TX_FSR(N) (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TX_FSR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -607,7 +653,10 @@
* If its increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
* then the carry bit is ignored and will automatically update with the lower 16bits value.
*/
-#define Sn_TX_RD(N) (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TX_RD(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -621,16 +670,22 @@
* then the carry bit is ignored and will automatically update with the lower 16bits value.\n
* 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command
*/
-#define Sn_TX_WR(N) (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_TX_WR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
* @brief Received data size register(R)
* @details @ref Sn_RX_RSR indicates the data size received and saved in Socket n RX Buffer.
* @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as the difference between
- * �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket n RX Read Pointer (@ref Sn_RX_RD)
+ * Socket n RX Write Pointer (@ref Sn_RX_WR)and Socket n RX Read Pointer (@ref Sn_RX_RD)
*/
-#define Sn_RX_RSR(N) (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_RX_RSR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -643,7 +698,10 @@
* update with the lower 16bits value ignored the carry bit.\n
* 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500.
*/
-#define Sn_RX_RD(N) (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_RX_RD(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -652,7 +710,10 @@
* If the increased value exceeds the maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs),
* then the carry bit is ignored and will automatically update with the lower 16bits value.
*/
-#define Sn_RX_WR(N) (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_RX_WR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
@@ -662,14 +723,20 @@
* the corresponding bit of @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref Sn_IR are and the n-th bit of @ref IR is
* Host is interrupted by asserted INTn PIN to low.
*/
-#define Sn_IMR(N) (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_IMR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
/**
* @ingroup Socket_register_group
* @brief Fragment field value in IP header register(R/W)
* @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header).
*/
-#define Sn_FRAG(N) (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+ static inline uint32_t Sn_FRAG(uint8_t N)
+ {
+ return _W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+ }
/**
* @ingroup Socket_register_group
@@ -682,7 +749,10 @@
* and KA packet can be transmitted by SEND_KEEP command by the host (Manual-keep-alive-process).
* Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'.
*/
-#define Sn_KPALVTR(N) (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
+static inline uint32_t Sn_KPALVTR(uint8_t N)
+{
+ return _W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3);
+}
//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3))
@@ -694,7 +764,7 @@
* @brief Reset
* @details If this bit is All internal registers will be initialized. It will be automatically cleared as after S/W reset.
*/
-#define MR_RST 0x80
+const uint8_t MR_RST = 0x80;
/**
* @brief Wake on LAN
@@ -705,7 +775,7 @@
* @note The magic packet over UDP supported by W5500 consists of 6 bytes synchronization stream (xFFFFFFFFFFFF and
* 16 times Target MAC address stream in UDP payload. The options such like password are ignored. You can use any UDP source port number for WOL mode.
*/
-#define MR_WOL 0x20
+const uint8_t MR_WOL = 0x20;
/**
* @brief Ping block
@@ -713,7 +783,7 @@
* 1 : Enable Ping block\n
* If the bit is it blocks the response to a ping request.
*/
-#define MR_PB 0x10
+const uint8_t MR_PB = 0x10;
/**
* @brief Enable PPPoE
@@ -721,7 +791,7 @@
* 1 : EnablePPPoE mode\n
* If you use ADSL, this bit should be
*/
-#define MR_PPPOE 0x08
+const uint8_t MR_PPPOE = 0x08;
/**
* @brief Enable UDP_FORCE_ARP CHECHK
@@ -729,52 +799,52 @@
* 1 : Enable Force ARP mode\n
* In Force ARP mode, It forces on sending ARP Request whenever data is sent.
*/
-#define MR_FARP 0x02
+const uint8_t MR_FARP = 0x02;
/* IR register values */
/**
* @brief Check IP conflict.
* @details Bit is set as when own source IP address is same with the sender IP address in the received ARP request.
*/
-#define IR_CONFLICT 0x80
+const uint8_t IR_CONFLICT = 0x80;
/**
* @brief Get the destination unreachable message in UDP sending.
* @details When receiving the ICMP (Destination port unreachable) packet, this bit is set as
* When this bit is Destination Information such as IP address and Port number may be checked with the corresponding @ref UIPR & @ref UPORTR.
*/
-#define IR_UNREACH 0x40
+const uint8_t IR_UNREACH = 0x40;
/**
* @brief Get the PPPoE close message.
* @details When PPPoE is disconnected during PPPoE mode, this bit is set.
*/
-#define IR_PPPoE 0x20
+const uint8_t IR_PPPoE = 0x20;
/**
* @brief Get the magic packet interrupt.
* @details When WOL mode is enabled and receives the magic packet over UDP, this bit is set.
*/
-#define IR_MP 0x10
+const uint8_t IR_MP = 0x10;
/* PHYCFGR register value */
-#define PHYCFGR_RST ~(1<<7) //< For PHY reset, must operate AND mask.
-#define PHYCFGR_OPMD (1<<6) // Configre PHY with OPMDC value
-#define PHYCFGR_OPMDC_ALLA (7<<3)
-#define PHYCFGR_OPMDC_PDOWN (6<<3)
-#define PHYCFGR_OPMDC_NA (5<<3)
-#define PHYCFGR_OPMDC_100FA (4<<3)
-#define PHYCFGR_OPMDC_100F (3<<3)
-#define PHYCFGR_OPMDC_100H (2<<3)
-#define PHYCFGR_OPMDC_10F (1<<3)
-#define PHYCFGR_OPMDC_10H (0<<3)
-#define PHYCFGR_DPX_FULL (1<<2)
-#define PHYCFGR_DPX_HALF (0<<2)
-#define PHYCFGR_SPD_100 (1<<1)
-#define PHYCFGR_SPD_10 (0<<1)
-#define PHYCFGR_LNK_ON (1<<0)
-#define PHYCFGR_LNK_OFF (0<<0)
+const uint8_t PHYCFGR_RST = (uint8_t)~(1<<7); //< For PHY reset, must operate AND mask.
+const uint8_t PHYCFGR_OPMD = (1<<6); // Configre PHY with OPMDC value
+const uint8_t PHYCFGR_OPMDC_ALLA = (7<<3);
+const uint8_t PHYCFGR_OPMDC_PDOWN = (6<<3);
+const uint8_t PHYCFGR_OPMDC_NA = (5<<3);
+const uint8_t PHYCFGR_OPMDC_100FA = (4<<3);
+const uint8_t PHYCFGR_OPMDC_100F = (3<<3);
+const uint8_t PHYCFGR_OPMDC_100H = (2<<3);
+const uint8_t PHYCFGR_OPMDC_10F = (1<<3);
+const uint8_t PHYCFGR_OPMDC_10H = (0<<3);
+const uint8_t PHYCFGR_DPX_FULL = (1<<2);
+const uint8_t PHYCFGR_DPX_HALF = (0<<2);
+const uint8_t PHYCFGR_SPD_100 = (1<<1);
+const uint8_t PHYCFGR_SPD_10 = (0<<1);
+const uint8_t PHYCFGR_LNK_ON = (1<<0);
+const uint8_t PHYCFGR_LNK_OFF = (0<<0);
/* IMR register values */
/**
@@ -782,28 +852,28 @@
* @details 0: Disable IP Conflict Interrupt\n
* 1: Enable IP Conflict Interrupt
*/
-#define IM_IR7 0x80
+const uint8_t IM_IR7 = 0x80;
/**
* @brief Destination unreachable Interrupt Mask.
* @details 0: Disable Destination unreachable Interrupt\n
* 1: Enable Destination unreachable Interrupt
*/
-#define IM_IR6 0x40
+const uint8_t IM_IR6 = 0x40;
/**
* @brief PPPoE Close Interrupt Mask.
* @details 0: Disable PPPoE Close Interrupt\n
* 1: Enable PPPoE Close Interrupt
*/
-#define IM_IR5 0x20
+const uint8_t IM_IR5 = 0x20;
/**
* @brief Magic Packet Interrupt Mask.
* @details 0: Disable Magic Packet Interrupt\n
* 1: Enable Magic Packet Interrupt
*/
-#define IM_IR4 0x10
+const uint8_t IM_IR4 = 0x10;
/* Sn_MR Default values */
/**
@@ -814,7 +884,7 @@
* To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively configured with the multicast group IP address & port number
* before Socket n is opened by OPEN command of @ref Sn_CR.
*/
-#define Sn_MR_MULTI 0x80
+const uint8_t Sn_MR_MULTI = 0x80;
/**
* @brief Broadcast block in UDP Multicasting.
@@ -823,7 +893,7 @@
* This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = 010.\m
* In addition, This bit does when MACRAW mode(P[3:0] = 100
*/
-#define Sn_MR_BCASTB 0x40
+const uint8_t Sn_MR_BCASTB = 0x40;
/**
* @brief No Delayed Ack(TCP), Multicast flag
@@ -833,7 +903,7 @@
* When this bit is It sends the ACK packet without delay as soon as a Data packet is received from a peer.\n
* When this bit is It sends the ACK packet after waiting for the timeout time configured by @ref _RTR_.
*/
-#define Sn_MR_ND 0x20
+const uint8_t Sn_MR_ND = 0x20;
/**
* @brief Unicast Block in UDP Multicasting
@@ -841,14 +911,14 @@
* 1 : enable Unicast Blocking\n
* This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and MULTI =
*/
-#define Sn_MR_UCASTB 0x10
+const uint8_t Sn_MR_UCASTB = 0x10;
/**
* @brief MAC LAYER RAW SOCK
* @details This configures the protocol mode of Socket n.
* @note MACRAW mode should be only used in Socket 0.
*/
-#define Sn_MR_MACRAW 0x04
+const uint8_t Sn_MR_MACRAW = 0x04;
//#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
@@ -856,19 +926,19 @@
* @brief UDP
* @details This configures the protocol mode of Socket n.
*/
-#define Sn_MR_UDP 0x02
+const uint8_t Sn_MR_UDP = 0x02;
/**
* @brief TCP
* @details This configures the protocol mode of Socket n.
*/
-#define Sn_MR_TCP 0x01
+const uint8_t Sn_MR_TCP = 0x01;
/**
* @brief Unused socket
* @details This configures the protocol mode of Socket n.
*/
-#define Sn_MR_CLOSE 0x00
+const uint8_t Sn_MR_CLOSE = 0x00;
/* Sn_MR values used with Sn_MR_MACRAW */
/**
@@ -881,7 +951,7 @@
* If user wants to implement Hybrid TCP/IP stack,
* it is recommended that this bit is set as for reducing host overhead to process the all received packets.
*/
-#define Sn_MR_MFEN Sn_MR_MULTI
+const uint8_t Sn_MR_MFEN = Sn_MR_MULTI;
/**
* @brief Multicast Blocking in @ref Sn_MR_MACRAW mode
@@ -890,7 +960,7 @@
* This bit is applied only during UDP mode(P[3:0] = 010 and MULTI =
* It configures the version for IGMP messages (Join/Leave/Report).
*/
-#define Sn_MR_MMB Sn_MR_ND
+const uint8_t Sn_MR_MMB = Sn_MR_ND;
/**
* @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode
@@ -898,7 +968,7 @@
* 1 : enable IPv6 Blocking\n
* This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to receiving the IPv6 packet.
*/
-#define Sn_MR_MIP6B Sn_MR_UCASTB
+const uint8_t Sn_MR_MIP6B = Sn_MR_UCASTB;
/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */
/**
@@ -907,18 +977,18 @@
* 1 : enable Multicast Blocking\n
* This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive the packet with multicast MAC address.
*/
-#define Sn_MR_MC Sn_MR_ND
+const uint8_t Sn_MR_MC = Sn_MR_ND;
/* Sn_MR alternate values */
/**
* @brief For Berkeley Socket API
*/
-#define SOCK_STREAM Sn_MR_TCP
+const uint8_t SOCK_STREAM = Sn_MR_TCP;
/**
* @brief For Berkeley Socket API
*/
-#define SOCK_DGRAM Sn_MR_UDP
+const uint8_t SOCK_DGRAM = Sn_MR_UDP;
/* Sn_CR values */
@@ -934,7 +1004,7 @@
* <tr> <td>S0_MR_MACRAW (100)</td> <td>SOCK_MACRAW (0x02)</td> </tr>
* </table>
*/
-#define Sn_CR_OPEN 0x01
+const uint8_t Sn_CR_OPEN = 0x01;
/**
* @brief Wait connection request in TCP mode(Server mode)
@@ -945,7 +1015,7 @@
* the @ref Sn_SR changes from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes
* But when a TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status of @ref Sn_SR changes to SOCK_CLOSED.
*/
-#define Sn_CR_LISTEN 0x02
+const uint8_t Sn_CR_LISTEN = 0x02;
/**
* @brief Send connection request in TCP mode(Client mode)
@@ -957,7 +1027,7 @@
* 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these cases, @ref Sn_SR is changed to @ref SOCK_CLOSED.
* @note This is valid only in TCP mode and operates when Socket n acts as <b>TCP client</b>
*/
-#define Sn_CR_CONNECT 0x04
+const uint8_t Sn_CR_CONNECT = 0x04;
/**
* @brief Send closing request in TCP mode
@@ -970,13 +1040,13 @@
* Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to @ref SOCK_CLOSED.
* @note Valid only in TCP mode.
*/
-#define Sn_CR_DISCON 0x08
+const uint8_t Sn_CR_DISCON = 0x08;
/**
* @brief Close socket
* @details Sn_SR is changed to @ref SOCK_CLOSED.
*/
-#define Sn_CR_CLOSE 0x10
+const uint8_t Sn_CR_CLOSE = 0x10;
/**
* @brief Update TX buffer pointer and send data
@@ -984,7 +1054,7 @@
* For more details, please refer to Socket n TX Free Size Register (@ref Sn_TX_FSR), Socket n,
* TX Write Pointer Register(@ref Sn_TX_WR), and Socket n TX Read Pointer Register(@ref Sn_TX_RD).
*/
-#define Sn_CR_SEND 0x20
+const uint8_t Sn_CR_SEND = 0x20;
/**
* @brief Send data with MAC address, so without ARP process
@@ -994,7 +1064,7 @@
* In this case, the destination hardware address is acquired from @ref Sn_DHAR configured by host, instead of APR-process.
* @note Valid only in UDP mode.
*/
-#define Sn_CR_SEND_MAC 0x21
+const uint8_t Sn_CR_SEND_MAC = 0x21;
/**
* @brief Send keep alive message
@@ -1002,7 +1072,7 @@
* If the peer can not respond to the keep-alive packet during timeout time, the connection is terminated and the timeout interrupt will occur.
* @note Valid only in TCP mode.
*/
-#define Sn_CR_SEND_KEEP 0x22
+const uint8_t Sn_CR_SEND_KEEP = 0x22;
/**
* @brief Update RX buffer pointer and receive data
@@ -1010,38 +1080,38 @@
* For more details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket n RX Write Pointer Register (@ref Sn_RX_WR),
* and Socket n RX Read Pointer Register (@ref Sn_RX_RD).
*/
-#define Sn_CR_RECV 0x40
+const uint8_t Sn_CR_RECV = 0x40;
/* Sn_IR values */
/**
* @brief SEND_OK Interrupt
* @details This is issued when SEND command is completed.
*/
-#define Sn_IR_SENDOK 0x10
+const uint8_t Sn_IR_SENDOK = 0x10;
/**
* @brief TIMEOUT Interrupt
* @details This is issued when ARPTO or TCPTO occurs.
*/
-#define Sn_IR_TIMEOUT 0x08
+const uint8_t Sn_IR_TIMEOUT = 0x08;
/**
* @brief RECV Interrupt
* @details This is issued whenever data is received from a peer.
*/
-#define Sn_IR_RECV 0x04
+const uint8_t Sn_IR_RECV = 0x04;
/**
* @brief DISCON Interrupt
* @details This is issued when FIN or FIN/ACK packet is received from a peer.
*/
-#define Sn_IR_DISCON 0x02
+const uint8_t Sn_IR_DISCON = 0x02;
/**
* @brief CON Interrupt
* @details This is issued one time when the connection with peer is successful and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED.
*/
-#define Sn_IR_CON 0x01
+const uint8_t Sn_IR_CON = 0x01;
/* Sn_SR values */
/**
@@ -1049,7 +1119,7 @@
* @details This indicates that Socket n is released.\n
* When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed to @ref SOCK_CLOSED regardless of previous status.
*/
-#define SOCK_CLOSED 0x00
+const uint8_t SOCK_CLOSED = 0x00;
/**
* @brief Initiate state
@@ -1057,7 +1127,7 @@
* It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN command is ordered.\n
* After @ref SOCK_INIT, user can use LISTEN /CONNECT command.
*/
-#define SOCK_INIT 0x13
+const uint8_t SOCK_INIT = 0x13;
/**
* @brief Listen state
@@ -1065,7 +1135,7 @@
* It will change to @ref SOCK_ESTALBLISHED when the connection-request is successfully accepted.\n
* Otherwise it will change to @ref SOCK_CLOSED after TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred.
*/
-#define SOCK_LISTEN 0x14
+const uint8_t SOCK_LISTEN = 0x14;
/**
* @brief Connection state
@@ -1074,7 +1144,7 @@
* If connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it changes to @ref SOCK_ESTABLISHED.\n
* Otherwise, it changes to @ref SOCK_CLOSED after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/
-#define SOCK_SYNSENT 0x15
+const uint8_t SOCK_SYNSENT = 0x15;
/**
* @brief Connection state
@@ -1082,7 +1152,7 @@
* If socket n sends the response (SYN/ACK packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n
* If not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/
-#define SOCK_SYNRECV 0x16
+const uint8_t SOCK_SYNRECV = 0x16;
/**
* @brief Success to connect
@@ -1091,7 +1161,7 @@
* when the CONNECT command is successful.\n
* During @ref SOCK_ESTABLISHED, DATA packet can be transferred using SEND or RECV command.
*/
-#define SOCK_ESTABLISHED 0x17
+const uint8_t SOCK_ESTABLISHED = 0x17;
/**
* @brief Closing state
@@ -1099,7 +1169,7 @@
* These are shown in disconnect-process such as active-close and passive-close.\n
* When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
*/
-#define SOCK_FIN_WAIT 0x18
+const uint8_t SOCK_FIN_WAIT = 0x18;
/**
* @brief Closing state
@@ -1107,7 +1177,7 @@
* These are shown in disconnect-process such as active-close and passive-close.\n
* When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
*/
-#define SOCK_CLOSING 0x1A
+const uint8_t SOCK_CLOSING = 0x1A;
/**
* @brief Closing state
@@ -1115,7 +1185,7 @@
* These are shown in disconnect-process such as active-close and passive-close.\n
* When Disconnect-process is successfully completed, or when timeout occurs, these change to @ref SOCK_CLOSED.
*/
-#define SOCK_TIME_WAIT 0x1B
+const uint8_t SOCK_TIME_WAIT = 0x1B;
/**
* @brief Closing state
@@ -1123,14 +1193,14 @@
* This is half-closing status, and data can be transferred.\n
* For full-closing, DISCON command is used. But For just-closing, CLOSE command is used.
*/
-#define SOCK_CLOSE_WAIT 0x1C
+const uint8_t SOCK_CLOSE_WAIT = 0x1C;
/**
* @brief Closing state
* @details This indicates Socket n is waiting for the response (FIN/ACK packet) to the disconnect-request (FIN packet) by passive-close.\n
* It changes to @ref SOCK_CLOSED when Socket n received the response successfully, or when timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred.
*/
-#define SOCK_LAST_ACK 0x1D
+const uint8_t SOCK_LAST_ACK = 0x1D;
/**
* @brief UDP socket
@@ -1138,7 +1208,7 @@
* It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref Sn_CR_OPEN command is ordered.\n
* Unlike TCP mode, data can be transfered without the connection-process.
*/
-#define SOCK_UDP 0x22
+const uint8_t SOCK_UDP = 0x22;
//#define SOCK_IPRAW 0x32 /**< IP raw mode socket */
@@ -1148,7 +1218,7 @@
* It changes to SOCK_MACRAW when S0_MR(P[3:0] = 100and OPEN command is ordered.\n
* Like UDP mode socket, MACRAW mode Socket 0 can transfer a MAC packet (Ethernet frame) without the connection-process.
*/
-#define SOCK_MACRAW 0x42
+const uint8_t SOCK_MACRAW = 0x42;
//#define SOCK_PPPOE 0x5F
@@ -1176,11 +1246,7 @@
* \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
* \sa WIZCHIP_CRITICAL_EXIT()
*/
-#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter()
-
-#ifdef _exit
-#undef _exit
-#endif
+static inline void WIZCHIP_CRITICAL_ENTER() {}
/**
* @brief Exit a critical section
@@ -1193,7 +1259,7 @@
* @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF()
* @sa WIZCHIP_CRITICAL_ENTER()
*/
-#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit()
+static inline void WIZCHIP_CRITICAL_EXIT() { }
////////////////////////
@@ -1233,7 +1299,7 @@ void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param pBuf Pointer buffer to write data
* @param len Data length
*/
-void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
+void WIZCHIP_WRITE_BUF(uint32_t AddrSel, const uint8_t* pBuf, uint16_t len);
/////////////////////////////////
// Common Register I/O function //
@@ -1244,9 +1310,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)mr The value to be set.
* @sa getMR()
*/
-#define setMR(mr) \
- WIZCHIP_WRITE(MR,mr)
-
+static inline void setMR(uint8_t mr)
+{
+ WIZCHIP_WRITE(MR, mr);
+}
/**
* @ingroup Common_register_access_function
@@ -1254,8 +1321,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. The value of Mode register.
* @sa setMR()
*/
-#define getMR() \
- WIZCHIP_READ(MR)
+static inline uint8_t getMR()
+{
+ return WIZCHIP_READ(MR);
+}
+
/**
* @ingroup Common_register_access_function
@@ -1263,8 +1333,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be allocated 4 bytes.
* @sa getGAR()
*/
-#define setGAR(gar) \
- WIZCHIP_WRITE_BUF(GAR,gar,4)
+static inline void setGAR(const uint8_t *gar)
+{
+ WIZCHIP_WRITE_BUF(GAR, gar, 4);
+}
/**
* @ingroup Common_register_access_function
@@ -1272,8 +1344,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be allocated 4 bytes.
* @sa setGAR()
*/
-#define getGAR(gar) \
- WIZCHIP_READ_BUF(GAR,gar,4)
+static inline void getGAR(uint8_t *gar)
+{
+ WIZCHIP_READ_BUF(GAR, gar, 4);
+}
/**
* @ingroup Common_register_access_function
@@ -1281,8 +1355,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)subr Pointer variable to set subnet mask address. It should be allocated 4 bytes.
* @sa getSUBR()
*/
-#define setSUBR(subr) \
- WIZCHIP_WRITE_BUF(SUBR, subr,4)
+static inline void setSUBR(const uint8_t *subr)
+{
+ WIZCHIP_WRITE_BUF(SUBR, subr, 4);
+}
/**
@@ -1291,8 +1367,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)subr Pointer variable to get subnet mask address. It should be allocated 4 bytes.
* @sa setSUBR()
*/
-#define getSUBR(subr) \
- WIZCHIP_READ_BUF(SUBR, subr, 4)
+static inline void getSUBR(uint8_t* subr)
+{
+ WIZCHIP_READ_BUF(SUBR, subr, 4);
+}
/**
* @ingroup Common_register_access_function
@@ -1300,8 +1378,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)shar Pointer variable to set local MAC address. It should be allocated 6 bytes.
* @sa getSHAR()
*/
-#define setSHAR(shar) \
- WIZCHIP_WRITE_BUF(SHAR, shar, 6)
+static inline void setSHAR(const uint8_t *shar)
+{
+ WIZCHIP_WRITE_BUF(SHAR, shar, 6);
+}
/**
* @ingroup Common_register_access_function
@@ -1309,8 +1389,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)shar Pointer variable to get local MAC address. It should be allocated 6 bytes.
* @sa setSHAR()
*/
-#define getSHAR(shar) \
- WIZCHIP_READ_BUF(SHAR, shar, 6)
+static inline void getSHAR(uint8_t *shar)
+{
+ WIZCHIP_READ_BUF(SHAR, shar, 6);
+}
/**
* @ingroup Common_register_access_function
@@ -1318,8 +1400,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)sipr Pointer variable to set local IP address. It should be allocated 4 bytes.
* @sa getSIPR()
*/
-#define setSIPR(sipr) \
- WIZCHIP_WRITE_BUF(SIPR, sipr, 4)
+static inline void setSIPR(const uint8_t *sipr)
+{
+ WIZCHIP_WRITE_BUF(SIPR, sipr, 4);
+}
/**
* @ingroup Common_register_access_function
@@ -1327,8 +1411,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)sipr Pointer variable to get local IP address. It should be allocated 4 bytes.
* @sa setSIPR()
*/
-#define getSIPR(sipr) \
- WIZCHIP_READ_BUF(SIPR, sipr, 4)
+static inline void getSIPR(uint8_t *sipr)
+{
+ WIZCHIP_READ_BUF(SIPR, sipr, 4);
+}
/**
* @ingroup Common_register_access_function
@@ -1336,11 +1422,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)intlevel Value to set @ref INTLEVEL register.
* @sa getINTLEVEL()
*/
-#define setINTLEVEL(intlevel) {\
- WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel); \
- }
-
+static inline void setINTLEVEL(uint16_t intlevel)
+{
+ WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL,1), (uint8_t) intlevel);
+}
/**
* @ingroup Common_register_access_function
@@ -1348,13 +1434,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref INTLEVEL register.
* @sa setINTLEVEL()
*/
-//M20150401 : Type explict declaration
-/*
-#define getINTLEVEL() \
- ((WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
-*/
-#define getINTLEVEL() \
- (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1)))
+static inline uint16_t getINTLEVEL()
+{
+ const uint8_t msb = WIZCHIP_READ(INTLEVEL);
+ return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1));
+}
/**
* @ingroup Common_register_access_function
@@ -1362,8 +1446,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)ir Value to set @ref IR register.
* @sa getIR()
*/
-#define setIR(ir) \
- WIZCHIP_WRITE(IR, (ir & 0xF0))
+static inline void setIR(uint8_t ir)
+{
+ WIZCHIP_WRITE(IR, (ir & 0xF0));
+}
/**
* @ingroup Common_register_access_function
@@ -1371,16 +1457,21 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref IR register.
* @sa setIR()
*/
-#define getIR() \
- (WIZCHIP_READ(IR) & 0xF0)
+static inline uint8_t getIR()
+{
+ return WIZCHIP_READ(IR) & 0xF0;
+}
+
/**
* @ingroup Common_register_access_function
* @brief Set @ref _IMR_ register
* @param (uint8_t)imr Value to set @ref _IMR_ register.
* @sa getIMR()
*/
-#define setIMR(imr) \
- WIZCHIP_WRITE(_IMR_, imr)
+static inline void setIMR(uint8_t imr)
+{
+ WIZCHIP_WRITE(_IMR_, imr);
+}
/**
* @ingroup Common_register_access_function
@@ -1388,8 +1479,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref _IMR_ register.
* @sa setIMR()
*/
-#define getIMR() \
- WIZCHIP_READ(_IMR_)
+static inline uint8_t getIMR()
+{
+ return WIZCHIP_READ(_IMR_);
+}
/**
* @ingroup Common_register_access_function
@@ -1397,8 +1490,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)sir Value to set @ref SIR register.
* @sa getSIR()
*/
-#define setSIR(sir) \
- WIZCHIP_WRITE(SIR, sir)
+static inline void setSIR(uint8_t sir)
+{
+ WIZCHIP_WRITE(SIR, sir);
+}
/**
* @ingroup Common_register_access_function
@@ -1406,16 +1501,21 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref SIR register.
* @sa setSIR()
*/
-#define getSIR() \
- WIZCHIP_READ(SIR)
+static inline uint8_t getSIR()
+{
+ return WIZCHIP_READ(SIR);
+}
+
/**
* @ingroup Common_register_access_function
* @brief Set @ref SIMR register
* @param (uint8_t)simr Value to set @ref SIMR register.
* @sa getSIMR()
*/
-#define setSIMR(simr) \
- WIZCHIP_WRITE(SIMR, simr)
+static inline void setSIMR(uint8_t simr)
+{
+ WIZCHIP_WRITE(SIMR, simr);
+}
/**
* @ingroup Common_register_access_function
@@ -1423,8 +1523,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref SIMR register.
* @sa setSIMR()
*/
-#define getSIMR() \
- WIZCHIP_READ(SIMR)
+static inline uint8_t getSIMR()
+{
+ return WIZCHIP_READ(SIMR);
+}
/**
* @ingroup Common_register_access_function
@@ -1432,10 +1534,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)rtr Value to set @ref _RTR_ register.
* @sa getRTR()
*/
-#define setRTR(rtr) {\
- WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr); \
- }
+static inline void setRTR(uint16_t rtr)
+{
+ WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_,1), (uint8_t) rtr);
+}
/**
* @ingroup Common_register_access_function
@@ -1443,13 +1546,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref _RTR_ register.
* @sa setRTR()
*/
-//M20150401 : Type explict declaration
-/*
-#define getRTR() \
- ((WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
-*/
-#define getRTR() \
- (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1)))
+static inline uint16_t getRTR()
+{
+ const uint8_t msb = WIZCHIP_READ(_RTR_);
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1));
+}
/**
@@ -1458,8 +1559,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)rcr Value to set @ref _RCR_ register.
* @sa getRCR()
*/
-#define setRCR(rcr) \
- WIZCHIP_WRITE(_RCR_, rcr)
+static inline void setRCR(uint8_t rcr)
+{
+ WIZCHIP_WRITE(_RCR_, rcr);
+}
/**
* @ingroup Common_register_access_function
@@ -1467,8 +1570,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref _RCR_ register.
* @sa setRCR()
*/
-#define getRCR() \
- WIZCHIP_READ(_RCR_)
+static inline uint8_t getRCR()
+{
+ return WIZCHIP_READ(_RCR_);
+}
//================================================== test done ===========================================================
@@ -1478,8 +1583,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)ptimer Value to set @ref PTIMER register.
* @sa getPTIMER()
*/
-#define setPTIMER(ptimer) \
- WIZCHIP_WRITE(PTIMER, ptimer)
+static inline void setPTIMER(uint8_t ptimer)
+{
+ WIZCHIP_WRITE(PTIMER, ptimer);
+}
/**
* @ingroup Common_register_access_function
@@ -1487,8 +1594,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref PTIMER register.
* @sa setPTIMER()
*/
-#define getPTIMER() \
- WIZCHIP_READ(PTIMER)
+static inline uint8_t getPTIMER()
+{
+ return WIZCHIP_READ(PTIMER);
+}
/**
* @ingroup Common_register_access_function
@@ -1496,8 +1605,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)pmagic Value to set @ref PMAGIC register.
* @sa getPMAGIC()
*/
-#define setPMAGIC(pmagic) \
- WIZCHIP_WRITE(PMAGIC, pmagic)
+static inline void setPMAGIC(uint8_t pmagic)
+{
+ WIZCHIP_WRITE(PMAGIC, pmagic);
+}
/**
* @ingroup Common_register_access_function
@@ -1505,8 +1616,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref PMAGIC register.
* @sa setPMAGIC()
*/
-#define getPMAGIC() \
- WIZCHIP_READ(PMAGIC)
+static inline uint8_t getPMAGIC()
+{
+ return WIZCHIP_READ(PMAGIC);
+}
/**
* @ingroup Common_register_access_function
@@ -1514,8 +1627,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)phar Pointer variable to set PPP destination MAC register address. It should be allocated 6 bytes.
* @sa getPHAR()
*/
-#define setPHAR(phar) \
- WIZCHIP_WRITE_BUF(PHAR, phar, 6)
+static inline void setPHAR(const uint8_t *phar)
+{
+ WIZCHIP_WRITE_BUF(PHAR, phar, 6);
+}
/**
* @ingroup Common_register_access_function
@@ -1523,8 +1638,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)phar Pointer variable to PPP destination MAC register address. It should be allocated 6 bytes.
* @sa setPHAR()
*/
-#define getPHAR(phar) \
- WIZCHIP_READ_BUF(PHAR, phar, 6)
+static inline void getPHAR(uint8_t *phar)
+{
+ WIZCHIP_READ_BUF(PHAR, phar, 6);
+}
/**
* @ingroup Common_register_access_function
@@ -1532,10 +1649,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)psid Value to set @ref PSID register.
* @sa getPSID()
*/
-#define setPSID(psid) {\
- WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid); \
- }
+static inline void setPSID(uint16_t psid)
+{
+ WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID,1), (uint8_t) psid);
+}
/**
* @ingroup Common_register_access_function
@@ -1543,14 +1661,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref PSID register.
* @sa setPSID()
*/
-//uint16_t getPSID(void);
-//M20150401 : Type explict declaration
-/*
-#define getPSID() \
- ((WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
-*/
-#define getPSID() \
- (((uint16_t)WIZCHIP_READ(PSID) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1)))
+static inline uint16_t getPSID()
+{
+ const uint8_t msb = WIZCHIP_READ(PSID);
+ return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1));
+}
/**
* @ingroup Common_register_access_function
@@ -1558,10 +1673,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)pmru Value to set @ref PMRU register.
* @sa getPMRU()
*/
-#define setPMRU(pmru) { \
- WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru); \
- }
+static inline void setPMRU(uint16_t pmru)
+{
+ WIZCHIP_WRITE(PMRU, (uint8_t)(pmru>>8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU,1), (uint8_t) pmru);
+}
/**
* @ingroup Common_register_access_function
@@ -1569,39 +1685,32 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref PMRU register.
* @sa setPMRU()
*/
-//M20150401 : Type explict declaration
-/*
-#define getPMRU() \
- ((WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
-*/
-#define getPMRU() \
- (((uint16_t)WIZCHIP_READ(PMRU) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1)))
+static inline uint16_t getPMRU()
+{
+ const uint8_t msb = WIZCHIP_READ(PMRU);
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1));
+}
/**
* @ingroup Common_register_access_function
* @brief Get unreachable IP address
* @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It should be allocated 4 bytes.
*/
-//M20150401 : Size Error of UIPR (6 -> 4)
-/*
-#define getUIPR(uipr) \
- WIZCHIP_READ_BUF(UIPR,uipr,6)
-*/
-#define getUIPR(uipr) \
- WIZCHIP_READ_BUF(UIPR,uipr,4)
+static inline void getUIPR(uint8_t *uipr)
+{
+ WIZCHIP_READ_BUF(UIPR, uipr, 4);
+}
/**
* @ingroup Common_register_access_function
* @brief Get @ref UPORTR register
* @return uint16_t. Value of @ref UPORTR register.
*/
-//M20150401 : Type explict declaration
-/*
-#define getUPORTR() \
- ((WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
-*/
-#define getUPORTR() \
- (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1)))
+static inline uint16_t getUPORTR()
+{
+ const uint8_t msb = WIZCHIP_READ(UPORTR);
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1));
+}
/**
* @ingroup Common_register_access_function
@@ -1609,8 +1718,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)phycfgr Value to set @ref PHYCFGR register.
* @sa getPHYCFGR()
*/
-#define setPHYCFGR(phycfgr) \
- WIZCHIP_WRITE(PHYCFGR, phycfgr)
+static inline void setPHYCFGR(uint8_t phycfgr)
+{
+ WIZCHIP_WRITE(PHYCFGR, phycfgr);
+}
/**
* @ingroup Common_register_access_function
@@ -1618,16 +1729,20 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref PHYCFGR register.
* @sa setPHYCFGR()
*/
-#define getPHYCFGR() \
- WIZCHIP_READ(PHYCFGR)
+static inline uint8_t getPHYCFGR()
+{
+ return WIZCHIP_READ(PHYCFGR);
+}
/**
* @ingroup Common_register_access_function
* @brief Get @ref VERSIONR register
* @return uint8_t. Value of @ref VERSIONR register.
*/
-#define getVERSIONR() \
- WIZCHIP_READ(VERSIONR)
+static inline uint8_t getVERSIONR()
+{
+ return WIZCHIP_READ(VERSIONR);
+}
/////////////////////////////////////
@@ -1641,8 +1756,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)mr Value to set @ref Sn_MR
* @sa getSn_MR()
*/
-#define setSn_MR(sn, mr) \
- WIZCHIP_WRITE(Sn_MR(sn),mr)
+static inline void setSn_MR(uint8_t sn, uint8_t mr)
+{
+ WIZCHIP_WRITE(Sn_MR(sn), mr);
+}
/**
* @ingroup Socket_register_access_function
@@ -1651,8 +1768,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_MR.
* @sa setSn_MR()
*/
-#define getSn_MR(sn) \
- WIZCHIP_READ(Sn_MR(sn))
+static inline uint8_t getSn_MR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_MR(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1661,8 +1780,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)cr Value to set @ref Sn_CR
* @sa getSn_CR()
*/
-#define setSn_CR(sn, cr) \
- WIZCHIP_WRITE(Sn_CR(sn), cr)
+static inline void setSn_CR(uint8_t sn, uint8_t cr)
+{
+ WIZCHIP_WRITE(Sn_CR(sn), cr);
+}
/**
* @ingroup Socket_register_access_function
@@ -1671,8 +1792,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_CR.
* @sa setSn_CR()
*/
-#define getSn_CR(sn) \
- WIZCHIP_READ(Sn_CR(sn))
+static inline uint8_t getSn_CR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_CR(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1681,8 +1804,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)ir Value to set @ref Sn_IR
* @sa getSn_IR()
*/
-#define setSn_IR(sn, ir) \
- WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F))
+static inline void setSn_IR(uint8_t sn, uint8_t ir)
+{
+ WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F));
+}
/**
* @ingroup Socket_register_access_function
@@ -1691,8 +1816,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_IR.
* @sa setSn_IR()
*/
-#define getSn_IR(sn) \
- (WIZCHIP_READ(Sn_IR(sn)) & 0x1F)
+static inline uint8_t getSn_IR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_IR(sn)) & 0x1F;
+}
/**
* @ingroup Socket_register_access_function
@@ -1701,8 +1828,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)imr Value to set @ref Sn_IMR
* @sa getSn_IMR()
*/
-#define setSn_IMR(sn, imr) \
- WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F))
+static inline void setSn_IMR(uint8_t sn, uint8_t imr)
+{
+ WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F));
+}
/**
* @ingroup Socket_register_access_function
@@ -1711,8 +1840,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_IMR.
* @sa setSn_IMR()
*/
-#define getSn_IMR(sn) \
- (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F)
+static inline uint8_t getSn_IMR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_IMR(sn)) & 0x1F;
+}
/**
* @ingroup Socket_register_access_function
@@ -1720,8 +1851,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint8_t. Value of @ref Sn_SR.
*/
-#define getSn_SR(sn) \
- WIZCHIP_READ(Sn_SR(sn))
+static inline uint8_t getSn_SR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_SR(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1730,10 +1863,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)port Value to set @ref Sn_PORT.
* @sa getSn_PORT()
*/
-#define setSn_PORT(sn, port) { \
- WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1), (uint8_t) port); \
- }
+static inline void setSn_PORT(uint8_t sn, uint16_t port)
+{
+ WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t) port);
+}
/**
* @ingroup Socket_register_access_function
@@ -1742,13 +1876,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_PORT.
* @sa setSn_PORT()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_PORT(sn) \
- ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
-*/
-#define getSn_PORT(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1)))
+static inline uint16_t getSn_PORT(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_PORT(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1));
+}
/**
* @ingroup Socket_register_access_function
@@ -1757,8 +1889,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)dhar Pointer variable to set socket n destination hardware address. It should be allocated 6 bytes.
* @sa getSn_DHAR()
*/
-#define setSn_DHAR(sn, dhar) \
- WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6)
+static inline void setSn_DHAR(uint8_t sn, const uint8_t *dhar)
+{
+ WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6);
+}
/**
* @ingroup Socket_register_access_function
@@ -1767,8 +1901,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)dhar Pointer variable to get socket n destination hardware address. It should be allocated 6 bytes.
* @sa setSn_DHAR()
*/
-#define getSn_DHAR(sn, dhar) \
- WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6)
+static inline void getSn_DHAR(uint8_t sn, uint8_t *dhar)
+{
+ WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6);
+}
/**
* @ingroup Socket_register_access_function
@@ -1777,8 +1913,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)dipr Pointer variable to set socket n destination IP address. It should be allocated 4 bytes.
* @sa getSn_DIPR()
*/
-#define setSn_DIPR(sn, dipr) \
- WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4)
+static inline void setSn_DIPR(uint8_t sn, const uint8_t *dipr)
+{
+ WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4);
+}
/**
* @ingroup Socket_register_access_function
@@ -1787,8 +1925,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t*)dipr Pointer variable to get socket n destination IP address. It should be allocated 4 bytes.
* @sa setSn_DIPR()
*/
-#define getSn_DIPR(sn, dipr) \
- WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4)
+static inline void getSn_DIPR(uint8_t sn, uint8_t *dipr)
+{
+ WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4);
+}
/**
* @ingroup Socket_register_access_function
@@ -1797,10 +1937,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)dport Value to set @ref Sn_DPORT
* @sa getSn_DPORT()
*/
-#define setSn_DPORT(sn, dport) { \
- WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport>>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1), (uint8_t) dport); \
- }
+static inline void setSn_DPORT(uint8_t sn, uint16_t dport)
+{
+ WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t) (dport >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t) dport);
+}
/**
* @ingroup Socket_register_access_function
@@ -1809,13 +1950,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_DPORT.
* @sa setSn_DPORT()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_DPORT(sn) \
- ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
-*/
-#define getSn_DPORT(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1)))
+static inline uint16_t getSn_DPORT(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_DPORT(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1));
+}
/**
* @ingroup Socket_register_access_function
@@ -1824,10 +1963,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint16_t)mss Value to set @ref Sn_MSSR
* @sa setSn_MSSR()
*/
-#define setSn_MSSR(sn, mss) { \
- WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss>>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1), (uint8_t) mss); \
- }
+static inline void setSn_MSSR(uint8_t sn, uint16_t mss)
+{
+ WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t) mss);
+}
/**
* @ingroup Socket_register_access_function
@@ -1836,13 +1976,11 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint16_t. Value of @ref Sn_MSSR.
* @sa setSn_MSSR()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_MSSR(sn) \
- ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
-*/
-#define getSn_MSSR(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1)))
+static inline uint16_t getSn_MSSR(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_MSSR(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1));
+}
/**
* @ingroup Socket_register_access_function
@@ -1851,8 +1989,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)tos Value to set @ref Sn_TOS
* @sa getSn_TOS()
*/
-#define setSn_TOS(sn, tos) \
- WIZCHIP_WRITE(Sn_TOS(sn), tos)
+static inline void setSn_TOS(uint8_t sn, uint8_t tos)
+{
+ WIZCHIP_WRITE(Sn_TOS(sn), tos);
+}
/**
* @ingroup Socket_register_access_function
@@ -1861,8 +2001,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of Sn_TOS.
* @sa setSn_TOS()
*/
-#define getSn_TOS(sn) \
- WIZCHIP_READ(Sn_TOS(sn))
+static inline uint8_t getSn_TOS(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_TOS(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1871,8 +2013,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)ttl Value to set @ref Sn_TTL
* @sa getSn_TTL()
*/
-#define setSn_TTL(sn, ttl) \
- WIZCHIP_WRITE(Sn_TTL(sn), ttl)
+static inline void setSn_TTL(uint8_t sn, uint8_t ttl)
+{
+ WIZCHIP_WRITE(Sn_TTL(sn), ttl);
+}
/**
@@ -1882,8 +2026,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_TTL.
* @sa setSn_TTL()
*/
-#define getSn_TTL(sn) \
- WIZCHIP_READ(Sn_TTL(sn))
+static inline uint8_t getSn_TTL(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_TTL(sn));
+}
/**
@@ -1893,8 +2039,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE
* @sa getSn_RXBUF_SIZE()
*/
-#define setSn_RXBUF_SIZE(sn, rxbufsize) \
- WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize)
+static inline void setSn_RXBUF_SIZE(uint8_t sn, uint8_t rxbufsize)
+{
+ WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn),rxbufsize);
+}
/**
@@ -1904,8 +2052,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_RXBUF_SIZE.
* @sa setSn_RXBUF_SIZE()
*/
-#define getSn_RXBUF_SIZE(sn) \
- WIZCHIP_READ(Sn_RXBUF_SIZE(sn))
+static inline uint8_t getSn_RXBUF_SIZE(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_RXBUF_SIZE(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1914,8 +2064,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE
* @sa getSn_TXBUF_SIZE()
*/
-#define setSn_TXBUF_SIZE(sn, txbufsize) \
- WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize)
+static inline void setSn_TXBUF_SIZE(uint8_t sn, uint8_t txbufsize)
+{
+ WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize);
+}
/**
* @ingroup Socket_register_access_function
@@ -1924,8 +2076,10 @@ void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len);
* @return uint8_t. Value of @ref Sn_TXBUF_SIZE.
* @sa setSn_TXBUF_SIZE()
*/
-#define getSn_TXBUF_SIZE(sn) \
- WIZCHIP_READ(Sn_TXBUF_SIZE(sn))
+static inline uint8_t getSn_TXBUF_SIZE(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_TXBUF_SIZE(sn));
+}
/**
* @ingroup Socket_register_access_function
@@ -1941,13 +2095,11 @@ uint16_t getSn_TX_FSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of @ref Sn_TX_RD.
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_TX_RD(sn) \
- ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
-*/
-#define getSn_TX_RD(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1)))
+static inline uint16_t getSn_TX_RD(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_TX_RD(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1));
+}
/**
* @ingroup Socket_register_access_function
@@ -1956,10 +2108,11 @@ uint16_t getSn_TX_FSR(uint8_t sn);
* @param (uint16_t)txwr Value to set @ref Sn_TX_WR
* @sa GetSn_TX_WR()
*/
-#define setSn_TX_WR(sn, txwr) { \
- WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr>>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1), (uint8_t) txwr); \
- }
+static inline void setSn_TX_WR(uint8_t sn, uint16_t txwr)
+{
+ WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t) txwr);
+}
/**
* @ingroup Socket_register_access_function
@@ -1968,13 +2121,11 @@ uint16_t getSn_TX_FSR(uint8_t sn);
* @return uint16_t. Value of @ref Sn_TX_WR.
* @sa setSn_TX_WR()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_TX_WR(sn) \
- ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
-*/
-#define getSn_TX_WR(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1)))
+static inline uint16_t getSn_TX_WR(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_TX_WR(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1));
+}
/**
@@ -1993,10 +2144,11 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint16_t)rxrd Value to set @ref Sn_RX_RD
* @sa getSn_RX_RD()
*/
-#define setSn_RX_RD(sn, rxrd) { \
- WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd>>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd); \
- }
+static inline void setSn_RX_RD(uint8_t sn, uint16_t rxrd)
+{
+ WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1), (uint8_t) rxrd);
+}
/**
* @ingroup Socket_register_access_function
@@ -2005,13 +2157,11 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @return uint16_t. Value of @ref Sn_RX_RD.
* @sa setSn_RX_RD()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_RX_RD(sn) \
- ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
-*/
-#define getSn_RX_RD(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1)))
+static inline uint16_t getSn_RX_RD(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_RX_RD(sn));
+ return ((uint16_t)msb << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1));
+}
/**
* @ingroup Socket_register_access_function
@@ -2019,13 +2169,11 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of @ref Sn_RX_WR.
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_RX_WR(sn) \
- ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
-*/
-#define getSn_RX_WR(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1)))
+static inline uint16_t getSn_RX_WR(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_RX_WR(sn));
+ return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1));
+}
/**
* @ingroup Socket_register_access_function
@@ -2034,10 +2182,11 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint16_t)frag Value to set @ref Sn_FRAG
* @sa getSn_FRAD()
*/
-#define setSn_FRAG(sn, frag) { \
- WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >>8)); \
- WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag); \
- }
+static inline void setSn_FRAG(uint8_t sn, uint16_t frag)
+{
+ WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8));
+ WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1), (uint8_t) frag);
+}
/**
* @ingroup Socket_register_access_function
@@ -2046,13 +2195,11 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @return uint16_t. Value of @ref Sn_FRAG.
* @sa setSn_FRAG()
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_FRAG(sn) \
- ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
-*/
-#define getSn_FRAG(sn) \
- (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1)))
+static inline uint16_t getSn_FRAG(uint8_t sn)
+{
+ const uint8_t msb = WIZCHIP_READ(Sn_FRAG(sn));
+ return ((uint16_t)msb << 8) | WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1));
+}
/**
* @ingroup Socket_register_access_function
@@ -2061,8 +2208,10 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR
* @sa getSn_KPALVTR()
*/
-#define setSn_KPALVTR(sn, kpalvt) \
- WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt)
+static inline void setSn_KPALVTR(uint8_t sn, uint8_t kpalvt)
+{
+ WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt);
+}
/**
* @ingroup Socket_register_access_function
@@ -2071,8 +2220,10 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @return uint8_t. Value of @ref Sn_KPALVTR.
* @sa setSn_KPALVTR()
*/
-#define getSn_KPALVTR(sn) \
- WIZCHIP_READ(Sn_KPALVTR(sn))
+static inline uint8_t getSn_KPALVTR(uint8_t sn)
+{
+ return WIZCHIP_READ(Sn_KPALVTR(sn));
+}
//////////////////////////////////////
@@ -2085,13 +2236,10 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of Socket n RX max buffer size.
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_RxMAX(sn) \
- (getSn_RXBUF_SIZE(sn) << 10)
-*/
-#define getSn_RxMAX(sn) \
- (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10)
+static inline uint16_t getSn_RxMAX(uint8_t sn)
+{
+ return ((uint16_t)getSn_RXBUF_SIZE(sn)) << 10;
+}
/**
* @brief Socket_register_access_function
@@ -2099,13 +2247,10 @@ uint16_t getSn_RX_RSR(uint8_t sn);
* @param (uint8_t)sn Socket number. It should be <b>0 ~ 7</b>.
* @return uint16_t. Value of Socket n TX max buffer size.
*/
-//M20150401 : Type explict declaration
-/*
-#define getSn_TxMAX(sn) \
- (getSn_TXBUF_SIZE(sn) << 10)
-*/
-#define getSn_TxMAX(sn) \
- (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10)
+static inline uint16_t getSn_TxMAX(uint8_t sn)
+{
+ return ((uint16_t)getSn_TXBUF_SIZE(sn)) << 10;
+}
/**
* @ingroup Basic_IO_function
@@ -2148,8 +2293,4 @@ void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len);
*/
void wiz_recv_ignore(uint8_t sn, uint16_t len);
-/// @cond DOXY_APPLY_CODE
-#endif
-/// @endcond
-
#endif // _W5500_H_
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.c b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.c
deleted file mode 100644
index b289da46..00000000
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.c
+++ /dev/null
@@ -1,912 +0,0 @@
-//*****************************************************************************
-//
-//! \file socket.c
-//! \brief SOCKET APIs Implements file.
-//! \details SOCKET APIs like as Berkeley Socket APIs.
-//! \version 1.0.3
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.3. Refer to M20140501
-//! 1. Implicit type casting -> Explicit type casting.
-//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
-//! 3. Validation a destination ip in connect() & sendto():
-//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
-//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
-//! <2013/12/20> V1.0.2 Refer to M20131220
-//! Remove Warning.
-//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
-//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************
-#include "socket.h"
-
-//M20150401 : Typing Error
-//#define SOCK_ANY_PORT_NUM 0xC000;
-#define SOCK_ANY_PORT_NUM 0xC000
-
-static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
-static uint16_t sock_io_mode = 0;
-static uint16_t sock_is_sending = 0;
-
-static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
-
-//M20150601 : For extern decleation
-//static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
-uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
-//
-
-#if _WIZCHIP_ == 5200
- static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,};
-#endif
-
-//A20150601 : For integrating with W5300
-#if _WIZCHIP_ == 5300
- uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
-#endif
-
-
-#define CHECK_SOCKNUM() \
- do{ \
- if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \
- }while(0); \
-
-#define CHECK_SOCKMODE(mode) \
- do{ \
- if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
- }while(0); \
-
-#define CHECK_SOCKINIT() \
- do{ \
- if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
- }while(0); \
-
-#define CHECK_SOCKDATA() \
- do{ \
- if(len == 0) return SOCKERR_DATALEN; \
- }while(0); \
-
-
-
-int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
-{
- CHECK_SOCKNUM();
- switch(protocol)
- {
- case Sn_MR_TCP :
- {
- //M20150601 : Fixed the warning - taddr will never be NULL
- /*
- uint8_t taddr[4];
- getSIPR(taddr);
- */
- uint32_t taddr;
- getSIPR((uint8_t*)&taddr);
- if(taddr == 0) return SOCKERR_SOCKINIT;
- }
- case Sn_MR_UDP :
- case Sn_MR_MACRAW :
- break;
- #if ( _WIZCHIP_ < 5200 )
- case Sn_MR_IPRAW :
- case Sn_MR_PPPoE :
- break;
- #endif
- default :
- return SOCKERR_SOCKMODE;
- }
- //M20150601 : For SF_TCP_ALIGN & W5300
- //if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
- if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG;
-#if _WIZCHIP_ == 5200
- if(flag & 0x10) return SOCKERR_SOCKFLAG;
-#endif
-
- if(flag != 0)
- {
- switch(protocol)
- {
- case Sn_MR_TCP:
- //M20150601 : For SF_TCP_ALIGN & W5300
- #if _WIZCHIP_ == 5300
- if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG;
- #else
- if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG;
- #endif
-
- break;
- case Sn_MR_UDP:
- if(flag & SF_IGMP_VER2)
- {
- if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG;
- }
- #if _WIZCHIP_ == 5500
- if(flag & SF_UNI_BLOCK)
- {
- if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG;
- }
- #endif
- break;
- default:
- break;
- }
- }
- close(sn);
- //M20150601
- #if _WIZCHIP_ == 5300
- setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) );
- #else
- setSn_MR(sn, (protocol | (flag & 0xF0)));
- #endif
- if(!port)
- {
- port = sock_any_port++;
- if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM;
- }
- setSn_PORT(sn,port);
- setSn_CR(sn,Sn_CR_OPEN);
- while(getSn_CR(sn));
- //A20150401 : For release the previous sock_io_mode
- sock_io_mode &= ~(1 <<sn);
- //
- sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
- sock_is_sending &= ~(1<<sn);
- sock_remained_size[sn] = 0;
- //M20150601 : repalce 0 with PACK_COMPLETED
- //sock_pack_info[sn] = 0;
- sock_pack_info[sn] = PACK_COMPLETED;
- //
- while(getSn_SR(sn) == SOCK_CLOSED);
- return (int8_t)sn;
-}
-
-int8_t close(uint8_t sn)
-{
- CHECK_SOCKNUM();
-//A20160426 : Applied the erratum 1 of W5300
-#if (_WIZCHIP_ == 5300)
- //M20160503 : Wrong socket parameter. s -> sn
- //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
- if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
- {
- uint8 destip[4] = {0, 0, 0, 1};
- // TODO
- // You can wait for completing to sending data;
- // wait about 1 second;
- // if you have completed to send data, skip the code of erratum 1
- // ex> wait_1s();
- // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
- //
- //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
- //socket(s,Sn_MR_UDP,0x3000,0);
- //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
- setSn_MR(sn,Sn_MR_UDP);
- setSn_PORTR(sn, 0x3000);
- setSn_CR(sn,Sn_CR_OPEN);
- while(getSn_CR(sn) != 0);
- while(getSn_SR(sn) != SOCK_UDP);
- sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
- };
-#endif
- setSn_CR(sn,Sn_CR_CLOSE);
- /* wait to process the command... */
- while( getSn_CR(sn) );
- /* clear all interrupt of the socket. */
- setSn_IR(sn, 0xFF);
- //A20150401 : Release the sock_io_mode of socket n.
- sock_io_mode &= ~(1<<sn);
- //
- sock_is_sending &= ~(1<<sn);
- sock_remained_size[sn] = 0;
- sock_pack_info[sn] = 0;
- while(getSn_SR(sn) != SOCK_CLOSED);
- return SOCK_OK;
-}
-
-int8_t listen(uint8_t sn)
-{
- CHECK_SOCKNUM();
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKINIT();
- setSn_CR(sn,Sn_CR_LISTEN);
- while(getSn_CR(sn));
- while(getSn_SR(sn) != SOCK_LISTEN)
- {
- close(sn);
- return SOCKERR_SOCKCLOSED;
- }
- return SOCK_OK;
-}
-
-
-int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
-{
- CHECK_SOCKNUM();
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKINIT();
- //M20140501 : For avoiding fatal error on memory align mismatched
- //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
- {
- uint32_t taddr;
- taddr = ((uint32_t)addr[0] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
- if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID;
- }
- //
-
- if(port == 0) return SOCKERR_PORTZERO;
- setSn_DIPR(sn,addr);
- setSn_DPORT(sn,port);
- setSn_CR(sn,Sn_CR_CONNECT);
- while(getSn_CR(sn));
- if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
- while(getSn_SR(sn) != SOCK_ESTABLISHED)
- {
- if (getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- return SOCKERR_TIMEOUT;
- }
-
- if (getSn_SR(sn) == SOCK_CLOSED)
- {
- return SOCKERR_SOCKCLOSED;
- }
- }
-
- return SOCK_OK;
-}
-
-int8_t disconnect(uint8_t sn)
-{
- CHECK_SOCKNUM();
- CHECK_SOCKMODE(Sn_MR_TCP);
- setSn_CR(sn,Sn_CR_DISCON);
- /* wait to process the command... */
- while(getSn_CR(sn));
- sock_is_sending &= ~(1<<sn);
- if(sock_io_mode & (1<<sn)) return SOCK_BUSY;
- while(getSn_SR(sn) != SOCK_CLOSED)
- {
- if(getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- close(sn);
- return SOCKERR_TIMEOUT;
- }
- }
- return SOCK_OK;
-}
-
-int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
-{
- uint8_t tmp=0;
- uint16_t freesize=0;
-
- CHECK_SOCKNUM();
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKDATA();
- tmp = getSn_SR(sn);
- if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
- if( sock_is_sending & (1<<sn) )
- {
- tmp = getSn_IR(sn);
- if(tmp & Sn_IR_SENDOK)
- {
- setSn_IR(sn, Sn_IR_SENDOK);
- //M20150401 : Typing Error
- //#if _WZICHIP_ == 5200
- #if _WIZCHIP_ == 5200
- if(getSn_TX_RD(sn) != sock_next_rd[sn])
- {
- setSn_CR(sn,Sn_CR_SEND);
- while(getSn_CR(sn));
- return SOCK_BUSY;
- }
- #endif
- sock_is_sending &= ~(1<<sn);
- }
- else if(tmp & Sn_IR_TIMEOUT)
- {
- close(sn);
- return SOCKERR_TIMEOUT;
- }
- else return SOCK_BUSY;
- }
- freesize = getSn_TxMAX(sn);
- if (len > freesize) len = freesize; // check size not to exceed MAX size.
- while(1)
- {
- freesize = getSn_TX_FSR(sn);
- tmp = getSn_SR(sn);
- if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
- if(len <= freesize) break;
- }
- wiz_send_data(sn, buf, len);
- #if _WIZCHIP_ == 5200
- sock_next_rd[sn] = getSn_TX_RD(sn) + len;
- #endif
-
- #if _WIZCHIP_ == 5300
- setSn_TX_WRSR(sn,len);
- #endif
-
- setSn_CR(sn,Sn_CR_SEND);
- /* wait to process the command... */
- while(getSn_CR(sn));
- sock_is_sending |= (1 << sn);
- //M20150409 : Explicit Type Casting
- //return len;
- return (int32_t)len;
-}
-
-
-int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
-{
- uint8_t tmp = 0;
- uint16_t recvsize = 0;
-//A20150601 : For integarating with W5300
-#if _WIZCHIP_ == 5300
- uint8_t head[2];
- uint16_t mr;
-#endif
-//
- CHECK_SOCKNUM();
- CHECK_SOCKMODE(Sn_MR_TCP);
- CHECK_SOCKDATA();
-
- recvsize = getSn_RxMAX(sn);
- if(recvsize < len) len = recvsize;
-
-//A20150601 : For Integrating with W5300
-#if _WIZCHIP_ == 5300
- //sock_pack_info[sn] = PACK_COMPLETED; // for clear
- if(sock_remained_size[sn] == 0)
- {
-#endif
-//
- while(1)
- {
- recvsize = getSn_RX_RSR(sn);
- tmp = getSn_SR(sn);
- if (tmp != SOCK_ESTABLISHED)
- {
- if(tmp == SOCK_CLOSE_WAIT)
- {
- if(recvsize != 0) break;
- else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- }
- else
- {
- close(sn);
- return SOCKERR_SOCKSTATUS;
- }
- }
- if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY;
- if(recvsize != 0) break;
- };
-#if _WIZCHIP_ == 5300
- }
-#endif
-
-//A20150601 : For integrating with W5300
-#if _WIZCHIP_ == 5300
- if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN))
- {
- mr = getMR();
- if((getSn_MR(sn) & Sn_MR_ALIGN)==0)
- {
- wiz_recv_data(sn,head,2);
- if(mr & MR_FS)
- recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]);
- else
- recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]);
- sock_pack_info[sn] = PACK_FIRST;
- }
- sock_remained_size[sn] = recvsize;
- }
- if(len > sock_remained_size[sn]) len = sock_remained_size[sn];
- recvsize = len;
- if(sock_pack_info[sn] & PACK_FIFOBYTE)
- {
- *buf = sock_remained_byte[sn];
- buf++;
- sock_pack_info[sn] &= ~(PACK_FIFOBYTE);
- recvsize -= 1;
- sock_remained_size[sn] -= 1;
- }
- if(recvsize != 0)
- {
- wiz_recv_data(sn, buf, recvsize);
- setSn_CR(sn,Sn_CR_RECV);
- while(getSn_CR(sn));
- }
- sock_remained_size[sn] -= recvsize;
- if(sock_remained_size[sn] != 0)
- {
- sock_pack_info[sn] |= PACK_REMAINED;
- if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE;
- }
- else sock_pack_info[sn] = PACK_COMPLETED;
- if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0;
- //len = recvsize;
-#else
- if(recvsize < len) len = recvsize;
- wiz_recv_data(sn, buf, len);
- setSn_CR(sn,Sn_CR_RECV);
- while(getSn_CR(sn));
-#endif
-
- //M20150409 : Explicit Type Casting
- //return len;
- return (int32_t)len;
-}
-
-int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
-{
- uint8_t tmp = 0;
- uint16_t freesize = 0;
- uint32_t taddr;
-
- CHECK_SOCKNUM();
- switch(getSn_MR(sn) & 0x0F)
- {
- case Sn_MR_UDP:
- case Sn_MR_MACRAW:
- break;
- default:
- return SOCKERR_SOCKMODE;
- }
- CHECK_SOCKDATA();
- //M20140501 : For avoiding fatal error on memory align mismatched
- //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
- //{
- //uint32_t taddr;
- taddr = ((uint32_t)addr[0]) & 0x000000FF;
- taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
- taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
- //}
- //
- //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
- if(taddr == 0) return SOCKERR_IPINVALID;
- if(port == 0) return SOCKERR_PORTZERO;
- tmp = getSn_SR(sn);
- if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
-
- setSn_DIPR(sn,addr);
- setSn_DPORT(sn,port);
- freesize = getSn_TxMAX(sn);
- if (len > freesize) len = freesize; // check size not to exceed MAX size.
- while(1)
- {
- freesize = getSn_TX_FSR(sn);
- if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
- if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
- if(len <= freesize) break;
- };
- wiz_send_data(sn, buf, len);
-
- #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
- getSIPR((uint8_t*)&taddr);
- if(taddr == 0)
- {
- getSUBR((uint8_t*)&taddr);
- setSUBR((uint8_t*)"\x00\x00\x00\x00");
- }
- else taddr = 0;
- #endif
-
-//A20150601 : For W5300
-#if _WIZCHIP_ == 5300
- setSn_TX_WRSR(sn, len);
-#endif
-//
- setSn_CR(sn,Sn_CR_SEND);
- /* wait to process the command... */
- while(getSn_CR(sn));
- while(1)
- {
- tmp = getSn_IR(sn);
- if(tmp & Sn_IR_SENDOK)
- {
- setSn_IR(sn, Sn_IR_SENDOK);
- break;
- }
- //M:20131104
- //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
- else if(tmp & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- //M20150409 : Fixed the lost of sign bits by type casting.
- //len = (uint16_t)SOCKERR_TIMEOUT;
- //break;
- #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
- if(taddr) setSUBR((uint8_t*)&taddr);
- #endif
- return SOCKERR_TIMEOUT;
- }
- ////////////
- }
- #if _WIZCHIP_ < 5500 //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
- if(taddr) setSUBR((uint8_t*)&taddr);
- #endif
- //M20150409 : Explicit Type Casting
- //return len;
- return (int32_t)len;
-}
-
-
-
-int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
-{
-//M20150601 : For W5300
-#if _WIZCHIP_ == 5300
- uint16_t mr;
- uint16_t mr1;
-#else
- uint8_t mr;
-#endif
-//
- uint8_t head[8];
- uint16_t pack_len=0;
-
- CHECK_SOCKNUM();
- //CHECK_SOCKMODE(Sn_MR_UDP);
-//A20150601
-#if _WIZCHIP_ == 5300
- mr1 = getMR();
-#endif
-
- switch((mr=getSn_MR(sn)) & 0x0F)
- {
- case Sn_MR_UDP:
- case Sn_MR_MACRAW:
- break;
- #if ( _WIZCHIP_ < 5200 )
- case Sn_MR_IPRAW:
- case Sn_MR_PPPoE:
- break;
- #endif
- default:
- return SOCKERR_SOCKMODE;
- }
- CHECK_SOCKDATA();
- if(sock_remained_size[sn] == 0)
- {
- while(1)
- {
- pack_len = getSn_RX_RSR(sn);
- if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED;
- if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY;
- if(pack_len != 0) break;
- };
- }
-//D20150601 : Move it to bottom
-// sock_pack_info[sn] = PACK_COMPLETED;
- switch (mr & 0x07)
- {
- case Sn_MR_UDP :
- if(sock_remained_size[sn] == 0)
- {
- wiz_recv_data(sn, head, 8);
- setSn_CR(sn,Sn_CR_RECV);
- while(getSn_CR(sn));
- // read peer's IP address, port number & packet length
- //A20150601 : For W5300
- #if _WIZCHIP_ == 5300
- if(mr1 & MR_FS)
- {
- addr[0] = head[1];
- addr[1] = head[0];
- addr[2] = head[3];
- addr[3] = head[2];
- *port = head[5];
- *port = (*port << 8) + head[4];
- sock_remained_size[sn] = head[7];
- sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6];
- }
- else
- {
- #endif
- addr[0] = head[0];
- addr[1] = head[1];
- addr[2] = head[2];
- addr[3] = head[3];
- *port = head[4];
- *port = (*port << 8) + head[5];
- sock_remained_size[sn] = head[6];
- sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
- #if _WIZCHIP_ == 5300
- }
- #endif
- sock_pack_info[sn] = PACK_FIRST;
- }
- if(len < sock_remained_size[sn]) pack_len = len;
- else pack_len = sock_remained_size[sn];
- //A20150601 : For W5300
- len = pack_len;
- #if _WIZCHIP_ == 5300
- if(sock_pack_info[sn] & PACK_FIFOBYTE)
- {
- *buf++ = sock_remained_byte[sn];
- pack_len -= 1;
- sock_remained_size[sn] -= 1;
- sock_pack_info[sn] &= ~PACK_FIFOBYTE;
- }
- #endif
- //
- // Need to packet length check (default 1472)
- //
- wiz_recv_data(sn, buf, pack_len); // data copy.
- break;
- case Sn_MR_MACRAW :
- if(sock_remained_size[sn] == 0)
- {
- wiz_recv_data(sn, head, 2);
- setSn_CR(sn,Sn_CR_RECV);
- while(getSn_CR(sn));
- // read peer's IP address, port number & packet length
- sock_remained_size[sn] = head[0];
- sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
- if(sock_remained_size[sn] > 1514)
- {
- close(sn);
- return SOCKFATAL_PACKLEN;
- }
- sock_pack_info[sn] = PACK_FIRST;
- }
- if(len < sock_remained_size[sn]) pack_len = len;
- else pack_len = sock_remained_size[sn];
- wiz_recv_data(sn,buf,pack_len);
- break;
- #if ( _WIZCHIP_ < 5200 )
- case Sn_MR_IPRAW:
- if(sock_remained_size[sn] == 0)
- {
- wiz_recv_data(sn, head, 6);
- setSn_CR(sn,Sn_CR_RECV);
- while(getSn_CR(sn));
- addr[0] = head[0];
- addr[1] = head[1];
- addr[2] = head[2];
- addr[3] = head[3];
- sock_remained_size[sn] = head[4];
- //M20150401 : For Typing Error
- //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
- sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5];
- sock_pack_info[sn] = PACK_FIRST;
- }
- //
- // Need to packet length check
- //
- if(len < sock_remained_size[sn]) pack_len = len;
- else pack_len = sock_remained_size[sn];
- wiz_recv_data(sn, buf, pack_len); // data copy.
- break;
- #endif
- default:
- wiz_recv_ignore(sn, pack_len); // data copy.
- sock_remained_size[sn] = pack_len;
- break;
- }
- setSn_CR(sn,Sn_CR_RECV);
- /* wait to process the command... */
- while(getSn_CR(sn)) ;
- sock_remained_size[sn] -= pack_len;
- //M20150601 :
- //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
- if(sock_remained_size[sn] != 0)
- {
- sock_pack_info[sn] |= PACK_REMAINED;
- #if _WIZCHIP_ == 5300
- if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE;
- #endif
- }
- else sock_pack_info[sn] = PACK_COMPLETED;
-#if _WIZCHIP_ == 5300
- pack_len = len;
-#endif
- //
- //M20150409 : Explicit Type Casting
- //return pack_len;
- return (int32_t)pack_len;
-}
-
-
-int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
-{
- uint8_t tmp = 0;
- CHECK_SOCKNUM();
- switch(cstype)
- {
- case CS_SET_IOMODE:
- tmp = *((uint8_t*)arg);
- if(tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1<<sn);
- else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn);
- else return SOCKERR_ARG;
- break;
- case CS_GET_IOMODE:
- //M20140501 : implict type casting -> explict type casting
- //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
- *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
- //
- break;
- case CS_GET_MAXTXBUF:
- *((uint16_t*)arg) = getSn_TxMAX(sn);
- break;
- case CS_GET_MAXRXBUF:
- *((uint16_t*)arg) = getSn_RxMAX(sn);
- break;
- case CS_CLR_INTERRUPT:
- if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
- setSn_IR(sn,*(uint8_t*)arg);
- break;
- case CS_GET_INTERRUPT:
- *((uint8_t*)arg) = getSn_IR(sn);
- break;
- #if _WIZCHIP_ != 5100
- case CS_SET_INTMASK:
- if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG;
- setSn_IMR(sn,*(uint8_t*)arg);
- break;
- case CS_GET_INTMASK:
- *((uint8_t*)arg) = getSn_IMR(sn);
- break;
- #endif
- default:
- return SOCKERR_ARG;
- }
- return SOCK_OK;
-}
-
-int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
-{
- // M20131220 : Remove warning
- //uint8_t tmp;
- CHECK_SOCKNUM();
- switch(sotype)
- {
- case SO_TTL:
- setSn_TTL(sn,*(uint8_t*)arg);
- break;
- case SO_TOS:
- setSn_TOS(sn,*(uint8_t*)arg);
- break;
- case SO_MSS:
- setSn_MSSR(sn,*(uint16_t*)arg);
- break;
- case SO_DESTIP:
- setSn_DIPR(sn, (uint8_t*)arg);
- break;
- case SO_DESTPORT:
- setSn_DPORT(sn, *(uint16_t*)arg);
- break;
-#if _WIZCHIP_ != 5100
- case SO_KEEPALIVESEND:
- CHECK_SOCKMODE(Sn_MR_TCP);
- #if _WIZCHIP_ > 5200
- if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT;
- #endif
- setSn_CR(sn,Sn_CR_SEND_KEEP);
- while(getSn_CR(sn) != 0)
- {
- // M20131220
- //if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
- if (getSn_IR(sn) & Sn_IR_TIMEOUT)
- {
- setSn_IR(sn, Sn_IR_TIMEOUT);
- return SOCKERR_TIMEOUT;
- }
- }
- break;
- #if _WIZCHIP_ > 5200
- case SO_KEEPALIVEAUTO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- setSn_KPALVTR(sn,*(uint8_t*)arg);
- break;
- #endif
-#endif
- default:
- return SOCKERR_ARG;
- }
- return SOCK_OK;
-}
-
-int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
-{
- CHECK_SOCKNUM();
- switch(sotype)
- {
- case SO_FLAG:
- *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
- break;
- case SO_TTL:
- *(uint8_t*) arg = getSn_TTL(sn);
- break;
- case SO_TOS:
- *(uint8_t*) arg = getSn_TOS(sn);
- break;
- case SO_MSS:
- *(uint8_t*) arg = getSn_MSSR(sn);
- break;
- case SO_DESTIP:
- getSn_DIPR(sn, (uint8_t*)arg);
- break;
- case SO_DESTPORT:
- *(uint16_t*) arg = getSn_DPORT(sn);
- break;
- #if _WIZCHIP_ > 5200
- case SO_KEEPALIVEAUTO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- *(uint16_t*) arg = getSn_KPALVTR(sn);
- break;
- #endif
- case SO_SENDBUF:
- *(uint16_t*) arg = getSn_TX_FSR(sn);
- break;
- case SO_RECVBUF:
- *(uint16_t*) arg = getSn_RX_RSR(sn);
- break;
- case SO_STATUS:
- *(uint8_t*) arg = getSn_SR(sn);
- break;
- case SO_REMAINSIZE:
- if(getSn_MR(sn) == Sn_MR_TCP)
- *(uint16_t*)arg = getSn_RX_RSR(sn);
- else
- *(uint16_t*)arg = sock_remained_size[sn];
- break;
- case SO_PACKINFO:
- CHECK_SOCKMODE(Sn_MR_TCP);
- *(uint8_t*)arg = sock_pack_info[sn];
- break;
- default:
- return SOCKERR_SOCKOPT;
- }
- return SOCK_OK;
-}
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.cpp
new file mode 100644
index 00000000..5aeca9b8
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/socket.cpp
@@ -0,0 +1,726 @@
+//*****************************************************************************
+//
+//! \file socket.c
+//! \brief SOCKET APIs Implements file.
+//! \details SOCKET APIs like as Berkeley Socket APIs.
+//! \version 1.0.3
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.3. Refer to M20140501
+//! 1. Implicit type casting -> Explicit type casting.
+//! 2. replace 0x01 with PACK_REMAINED in recvfrom()
+//! 3. Validation a destination ip in connect() & sendto():
+//! It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
+//! Copy 4 byte addr value into temporary uint32 variable and then compares it.
+//! <2013/12/20> V1.0.2 Refer to M20131220
+//! Remove Warning.
+//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
+//! In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************
+#include "socket.h"
+
+#define SOCK_ANY_PORT_NUM 0xC000
+
+static uint16_t sock_any_port = SOCK_ANY_PORT_NUM;
+static uint16_t sock_io_mode = 0;
+static uint16_t sock_is_sending = 0;
+
+static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,};
+
+uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
+
+#define CHECK_SOCKMODE(mode) \
+ do{ \
+ if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \
+ }while(0); \
+
+#define CHECK_SOCKINIT() \
+ do{ \
+ if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \
+ }while(0); \
+
+#define CHECK_SOCKDATA() \
+ do{ \
+ if(len == 0) return SOCKERR_DATALEN; \
+ }while(0); \
+
+static void ExecCommand(uint8_t sn, uint8_t cmd)
+{
+ setSn_CR(sn, Sn_CR_OPEN);
+ while(getSn_CR(sn) != 0) { }
+}
+
+int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
+{
+ switch(protocol)
+ {
+ case Sn_MR_TCP:
+ {
+ uint32_t taddr;
+ getSIPR((uint8_t*)&taddr);
+ if (taddr == 0)
+ {
+ return SOCKERR_SOCKINIT;
+ }
+ }
+ break;
+
+ case Sn_MR_UDP:
+ case Sn_MR_MACRAW:
+ break;
+
+ default:
+ return SOCKERR_SOCKMODE;
+ }
+
+ if ((flag & 0x04) != 0)
+ {
+ return SOCKERR_SOCKFLAG;
+ }
+
+ if (flag != 0)
+ {
+ switch(protocol)
+ {
+ case Sn_MR_TCP:
+ if ((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK)) == 0)
+ {
+ return SOCKERR_SOCKFLAG;
+ }
+ break;
+ case Sn_MR_UDP:
+ if (flag & SF_IGMP_VER2)
+ {
+ if ((flag & SF_MULTI_ENABLE) == 0)
+ {
+ return SOCKERR_SOCKFLAG;
+ }
+ }
+ if (flag & SF_UNI_BLOCK)
+ {
+ if ((flag & SF_MULTI_ENABLE) == 0)
+ {
+ return SOCKERR_SOCKFLAG;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ close(sn);
+ setSn_MR(sn, (protocol | (flag & 0xF0)));
+ if (port == 0)
+ {
+ port = sock_any_port++;
+ if (sock_any_port == 0xFFF0)
+ {
+ sock_any_port = SOCK_ANY_PORT_NUM;
+ }
+ }
+ setSn_PORT(sn,port);
+ ExecCommand(sn, Sn_CR_OPEN);
+
+ // release the previous sock_io_mode
+ sock_io_mode &= ~(1 <<sn);
+ sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);
+ sock_is_sending &= ~(1<<sn);
+ sock_remained_size[sn] = 0;
+ sock_pack_info[sn] = PACK_COMPLETED;
+ while(getSn_SR(sn) == SOCK_CLOSED) { }
+ return (int8_t)sn;
+}
+
+int8_t close(uint8_t sn)
+{
+ ExecCommand(sn, Sn_CR_CLOSE);
+
+ // Clear all interrupt of the socket
+ setSn_IR(sn, 0xFF);
+ // Release the sock_io_mode of socket n.
+ sock_io_mode &= ~(1<<sn);
+ sock_is_sending &= ~(1<<sn);
+ sock_remained_size[sn] = 0;
+ sock_pack_info[sn] = 0;
+ while(getSn_SR(sn) != SOCK_CLOSED) { }
+ return SOCK_OK;
+}
+
+int8_t listen(uint8_t sn)
+{
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ CHECK_SOCKINIT();
+ ExecCommand(sn, Sn_CR_LISTEN);
+ while(getSn_SR(sn) != SOCK_LISTEN)
+ {
+ close(sn);
+ return SOCKERR_SOCKCLOSED;
+ }
+ return SOCK_OK;
+}
+
+
+int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
+{
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ CHECK_SOCKINIT();
+ {
+ uint32_t taddr = ((uint32_t)addr[0] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
+ if (taddr == 0xFFFFFFFF || taddr == 0)
+ {
+ return SOCKERR_IPINVALID;
+ }
+ }
+
+ if (port == 0)
+ {
+ return SOCKERR_PORTZERO;
+ }
+ setSn_DIPR(sn,addr);
+ setSn_DPORT(sn,port);
+ ExecCommand(sn, Sn_CR_CONNECT);
+ if (sock_io_mode & (1<<sn))
+ {
+ return SOCK_BUSY;
+ }
+ while(getSn_SR(sn) != SOCK_ESTABLISHED)
+ {
+ if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+ {
+ setSn_IR(sn, Sn_IR_TIMEOUT);
+ return SOCKERR_TIMEOUT;
+ }
+
+ if (getSn_SR(sn) == SOCK_CLOSED)
+ {
+ return SOCKERR_SOCKCLOSED;
+ }
+ }
+
+ return SOCK_OK;
+}
+
+int8_t disconnect(uint8_t sn)
+{
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ ExecCommand(sn, Sn_CR_DISCON);
+
+ sock_is_sending &= ~(1<<sn);
+ if (sock_io_mode & (1<<sn))
+ {
+ return SOCK_BUSY;
+ }
+ while(getSn_SR(sn) != SOCK_CLOSED)
+ {
+ if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+ {
+ close(sn);
+ return SOCKERR_TIMEOUT;
+ }
+ }
+ return SOCK_OK;
+}
+
+int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
+{
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ CHECK_SOCKDATA();
+ uint8_t tmp = getSn_SR(sn);
+ if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT)
+ {
+ return SOCKERR_SOCKSTATUS;
+ }
+ if ( sock_is_sending & (1<<sn) )
+ {
+ tmp = getSn_IR(sn);
+ if (tmp & Sn_IR_SENDOK)
+ {
+ setSn_IR(sn, Sn_IR_SENDOK);
+ sock_is_sending &= ~(1<<sn);
+ }
+ else if(tmp & Sn_IR_TIMEOUT)
+ {
+ close(sn);
+ return SOCKERR_TIMEOUT;
+ }
+ else
+ {
+ return SOCK_BUSY;
+ }
+ }
+ uint16_t freesize = getSn_TxMAX(sn);
+ if (len > freesize)
+ {
+ len = freesize; // check size not to exceed MAX size.
+ }
+ while(1)
+ {
+ freesize = getSn_TX_FSR(sn);
+ tmp = getSn_SR(sn);
+ if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ if ( (sock_io_mode & (1<<sn)) && (len > freesize) )
+ {
+ return SOCK_BUSY;
+ }
+ if (len <= freesize)
+ {
+ break;
+ }
+ }
+ wiz_send_data(sn, buf, len);
+
+ ExecCommand(sn, Sn_CR_SEND);
+ sock_is_sending |= (1 << sn);
+ return (int32_t)len;
+}
+
+
+int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
+{
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ CHECK_SOCKDATA();
+
+ uint16_t recvsize = getSn_RxMAX(sn);
+ if (recvsize < len)
+ {
+ len = recvsize;
+ }
+
+ while(1)
+ {
+ recvsize = getSn_RX_RSR(sn);
+ const uint8_t tmp = getSn_SR(sn);
+ if (tmp != SOCK_ESTABLISHED)
+ {
+ if (tmp == SOCK_CLOSE_WAIT)
+ {
+ if (recvsize != 0)
+ {
+ break;
+ }
+ else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn))
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ }
+ else
+ {
+ close(sn);
+ return SOCKERR_SOCKSTATUS;
+ }
+ }
+ if ((sock_io_mode & (1<<sn)) && (recvsize == 0))
+ {
+ return SOCK_BUSY;
+ }
+ if (recvsize != 0)
+ {
+ break;
+ }
+ };
+
+ if (recvsize < len)
+ {
+ len = recvsize;
+ }
+ wiz_recv_data(sn, buf, len);
+ ExecCommand(sn, Sn_CR_RECV);
+
+ return (int32_t)len;
+}
+
+int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port)
+{
+ switch(getSn_MR(sn) & 0x0F)
+ {
+ case Sn_MR_UDP:
+ case Sn_MR_MACRAW:
+ break;
+ default:
+ return SOCKERR_SOCKMODE;
+ }
+
+ CHECK_SOCKDATA();
+ uint32_t taddr = ((uint32_t)addr[0]) & 0x000000FF;
+ taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF);
+ taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF);
+ if (taddr == 0)
+ {
+ return SOCKERR_IPINVALID;
+ }
+ if (port == 0)
+ {
+ return SOCKERR_PORTZERO;
+ }
+ const uint8_t tmp = getSn_SR(sn);
+ if (tmp != SOCK_MACRAW && tmp != SOCK_UDP)
+ {
+ return SOCKERR_SOCKSTATUS;
+ }
+
+ setSn_DIPR(sn,addr);
+ setSn_DPORT(sn,port);
+ uint16_t freesize = getSn_TxMAX(sn);
+ if (len > freesize)
+ {
+ len = freesize; // check size not to exceed MAX size.
+ }
+
+ while(1)
+ {
+ freesize = getSn_TX_FSR(sn);
+ if (getSn_SR(sn) == SOCK_CLOSED)
+ {
+ return SOCKERR_SOCKCLOSED;
+ }
+ if ( (sock_io_mode & (1<<sn)) && (len > freesize) )
+ {
+ return SOCK_BUSY;
+ }
+ if (len <= freesize)
+ {
+ break;
+ }
+ };
+
+ wiz_send_data(sn, buf, len);
+
+ ExecCommand(sn, Sn_CR_SEND);
+
+ while(1)
+ {
+ const uint8_t tmp = getSn_IR(sn);
+ if (tmp & Sn_IR_SENDOK)
+ {
+ setSn_IR(sn, Sn_IR_SENDOK);
+ break;
+ }
+ else if(tmp & Sn_IR_TIMEOUT)
+ {
+ setSn_IR(sn, Sn_IR_TIMEOUT);
+ return SOCKERR_TIMEOUT;
+ }
+ }
+ return (int32_t)len;
+}
+
+
+int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port)
+{
+ const uint8_t mr = getSn_MR(sn);
+ switch(mr & 0x0F)
+ {
+ case Sn_MR_UDP:
+ case Sn_MR_MACRAW:
+ break;
+ default:
+ return SOCKERR_SOCKMODE;
+ }
+
+ CHECK_SOCKDATA();
+ uint16_t pack_len=0;
+ if (sock_remained_size[sn] == 0)
+ {
+ while(1)
+ {
+ pack_len = getSn_RX_RSR(sn);
+ if (getSn_SR(sn) == SOCK_CLOSED)
+ {
+ return SOCKERR_SOCKCLOSED;
+ }
+ if ( (sock_io_mode & (1<<sn)) && (pack_len == 0) )
+ {
+ return SOCK_BUSY;
+ }
+ if (pack_len != 0)
+ {
+ break;
+ }
+ }
+ }
+
+ switch (mr & 0x07)
+ {
+ case Sn_MR_UDP :
+ if (sock_remained_size[sn] == 0)
+ {
+ uint8_t head[8];
+ wiz_recv_data(sn, head, 8);
+ ExecCommand(sn, Sn_CR_RECV);
+
+ // Read peer's IP address, port number & packet length
+ addr[0] = head[0];
+ addr[1] = head[1];
+ addr[2] = head[2];
+ addr[3] = head[3];
+ *port = head[4];
+ *port = (*port << 8) + head[5];
+ sock_remained_size[sn] = head[6];
+ sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7];
+ sock_pack_info[sn] = PACK_FIRST;
+ }
+ if (len < sock_remained_size[sn])
+ {
+ pack_len = len;
+ }
+ else
+ {
+ pack_len = sock_remained_size[sn];
+ }
+ len = pack_len;
+ //
+ // Need to packet length check (default 1472)
+ //
+ wiz_recv_data(sn, buf, pack_len); // data copy.
+ break;
+
+ case Sn_MR_MACRAW :
+ if (sock_remained_size[sn] == 0)
+ {
+ uint8_t head[8];
+ wiz_recv_data(sn, head, 2);
+ ExecCommand(sn, Sn_CR_RECV);
+
+ // Read peer's IP address, port number & packet length
+ sock_remained_size[sn] = head[0];
+ sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1];
+ if (sock_remained_size[sn] > 1514)
+ {
+ close(sn);
+ return SOCKFATAL_PACKLEN;
+ }
+ sock_pack_info[sn] = PACK_FIRST;
+ }
+ if (len < sock_remained_size[sn])
+ {
+ pack_len = len;
+ }
+ else
+ {
+ pack_len = sock_remained_size[sn];
+ }
+ wiz_recv_data(sn,buf,pack_len);
+ break;
+
+ default:
+ wiz_recv_ignore(sn, pack_len); // data copy.
+ sock_remained_size[sn] = pack_len;
+ break;
+ }
+ ExecCommand(sn, Sn_CR_RECV);
+
+ sock_remained_size[sn] -= pack_len;
+ if (sock_remained_size[sn] != 0)
+ {
+ sock_pack_info[sn] |= PACK_REMAINED;
+ }
+ else
+ {
+ sock_pack_info[sn] = PACK_COMPLETED;
+ }
+ return (int32_t)pack_len;
+}
+
+
+int8_t ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg)
+{
+ switch(cstype)
+ {
+ case CS_SET_IOMODE:
+ {
+ const uint8_t tmp = *((uint8_t*)arg);
+ if (tmp == SOCK_IO_NONBLOCK)
+ {
+ sock_io_mode |= (1<<sn);
+ }
+ else if (tmp == SOCK_IO_BLOCK)
+ {
+ sock_io_mode &= ~(1<<sn);
+ }
+ else
+ {
+ return SOCKERR_ARG;
+ }
+ }
+ break;
+ case CS_GET_IOMODE:
+ *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
+ break;
+ case CS_GET_MAXTXBUF:
+ *((uint16_t*)arg) = getSn_TxMAX(sn);
+ break;
+ case CS_GET_MAXRXBUF:
+ *((uint16_t*)arg) = getSn_RxMAX(sn);
+ break;
+ case CS_CLR_INTERRUPT:
+ if ((*(uint8_t*)arg) > SIK_ALL)
+ {
+ return SOCKERR_ARG;
+ }
+ setSn_IR(sn, *(uint8_t*)arg);
+ break;
+ case CS_GET_INTERRUPT:
+ *((uint8_t*)arg) = getSn_IR(sn);
+ break;
+ case CS_SET_INTMASK:
+ if ((*(uint8_t*)arg) > SIK_ALL)
+ {
+ return SOCKERR_ARG;
+ }
+ setSn_IMR(sn, *(uint8_t*)arg);
+ break;
+ case CS_GET_INTMASK:
+ *((uint8_t*)arg) = getSn_IMR(sn);
+ break;
+ default:
+ return SOCKERR_ARG;
+ }
+ return SOCK_OK;
+}
+
+int8_t setsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+ switch(sotype)
+ {
+ case SO_TTL:
+ setSn_TTL(sn,*(uint8_t*)arg);
+ break;
+ case SO_TOS:
+ setSn_TOS(sn,*(uint8_t*)arg);
+ break;
+ case SO_MSS:
+ setSn_MSSR(sn,*(uint16_t*)arg);
+ break;
+ case SO_DESTIP:
+ setSn_DIPR(sn, (uint8_t*)arg);
+ break;
+ case SO_DESTPORT:
+ setSn_DPORT(sn, *(uint16_t*)arg);
+ break;
+ case SO_KEEPALIVESEND:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ if (getSn_KPALVTR(sn) != 0)
+ {
+ return SOCKERR_SOCKOPT;
+ }
+ setSn_CR(sn, Sn_CR_SEND_KEEP);
+ while(getSn_CR(sn) != 0)
+ {
+ if (getSn_IR(sn) & Sn_IR_TIMEOUT)
+ {
+ setSn_IR(sn, Sn_IR_TIMEOUT);
+ return SOCKERR_TIMEOUT;
+ }
+ }
+ break;
+ case SO_KEEPALIVEAUTO:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ setSn_KPALVTR(sn,*(uint8_t*)arg);
+ break;
+ default:
+ return SOCKERR_ARG;
+ }
+ return SOCK_OK;
+}
+
+int8_t getsockopt(uint8_t sn, sockopt_type sotype, void* arg)
+{
+ switch(sotype)
+ {
+ case SO_FLAG:
+ *(uint8_t*)arg = getSn_MR(sn) & 0xF0;
+ break;
+ case SO_TTL:
+ *(uint8_t*) arg = getSn_TTL(sn);
+ break;
+ case SO_TOS:
+ *(uint8_t*) arg = getSn_TOS(sn);
+ break;
+ case SO_MSS:
+ *(uint8_t*) arg = getSn_MSSR(sn);
+ break;
+ case SO_DESTIP:
+ getSn_DIPR(sn, (uint8_t*)arg);
+ break;
+ case SO_DESTPORT:
+ *(uint16_t*) arg = getSn_DPORT(sn);
+ break;
+ case SO_KEEPALIVEAUTO:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ *(uint16_t*) arg = getSn_KPALVTR(sn);
+ break;
+ case SO_SENDBUF:
+ *(uint16_t*) arg = getSn_TX_FSR(sn);
+ break;
+ case SO_RECVBUF:
+ *(uint16_t*) arg = getSn_RX_RSR(sn);
+ break;
+ case SO_STATUS:
+ *(uint8_t*) arg = getSn_SR(sn);
+ break;
+ case SO_REMAINSIZE:
+ if (getSn_MR(sn) == Sn_MR_TCP)
+ {
+ *(uint16_t*)arg = getSn_RX_RSR(sn);
+ }
+ else
+ {
+ *(uint16_t*)arg = sock_remained_size[sn];
+ }
+ break;
+ case SO_PACKINFO:
+ CHECK_SOCKMODE(Sn_MR_TCP);
+ *(uint8_t*)arg = sock_pack_info[sn];
+ break;
+ default:
+ return SOCKERR_SOCKOPT;
+ }
+ return SOCK_OK;
+}
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.c b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.c
deleted file mode 100644
index a1756913..00000000
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.c
+++ /dev/null
@@ -1,792 +0,0 @@
-//****************************************************************************/
-//!
-//! \file wizchip_conf.c
-//! \brief WIZCHIP Config Header File.
-//! \version 1.0.1
-//! \date 2013/10/21
-//! \par Revision history
-//! <2015/02/05> Notice
-//! The version history is not updated after this point.
-//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
-//! >> https://github.com/Wiznet/ioLibrary_Driver
-//! <2014/05/01> V1.0.1 Refer to M20140501
-//! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
-// Issued by Mathias ClauBen.
-//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
-//! For remove the warning when pointer type size is not 32bit.
-//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
-//! <2013/10/21> 1st Release
-//! \author MidnightCow
-//! \copyright
-//!
-//! Copyright (c) 2013, WIZnet Co., LTD.
-//! All rights reserved.
-//!
-//! Redistribution and use in source and binary forms, with or without
-//! modification, are permitted provided that the following conditions
-//! are met:
-//!
-//! * Redistributions of source code must retain the above copyright
-//! notice, this list of conditions and the following disclaimer.
-//! * Redistributions in binary form must reproduce the above copyright
-//! notice, this list of conditions and the following disclaimer in the
-//! documentation and/or other materials provided with the distribution.
-//! * Neither the name of the <ORGANIZATION> nor the names of its
-//! contributors may be used to endorse or promote products derived
-//! from this software without specific prior written permission.
-//!
-//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
-//! THE POSSIBILITY OF SUCH DAMAGE.
-//
-//*****************************************************************************/
-//A20140501 : for use the type - ptrdiff_t
-#include <stddef.h>
-//
-
-#include "wizchip_conf.h"
-
-/////////////
-//M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc.
-/////////////
-
-/**
- * @brief Default function to enable interrupt.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_cris_enter(void) {};
-void wizchip_cris_enter(void) {}
-
-/**
- * @brief Default function to disable interrupt.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_cris_exit(void) {};
-void wizchip_cris_exit(void) {}
-
-/**
- * @brief Default function to select chip.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_cs_select(void) {};
-void wizchip_cs_select(void) {}
-
-/**
- * @brief Default function to deselect chip.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_cs_deselect(void) {};
-void wizchip_cs_deselect(void) {}
-
-/**
- * @brief Default function to read in direct or indirect interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
- //M20150601 : Rename the function for integrating with W5300
-//uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }
-iodata_t wizchip_bus_readdata(uint32_t AddrSel) { return * ((volatile iodata_t *)((ptrdiff_t) AddrSel)); }
-
-/**
- * @brief Default function to write in direct or indirect interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//M20150601 : Rename the function for integrating with W5300
-//void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }
-void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; }
-
-/**
- * @brief Default function to read in SPI interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//uint8_t wizchip_spi_readbyte(void) {return 0;};
-uint8_t wizchip_spi_readbyte(void) {return 0;}
-
-/**
- * @brief Default function to write in SPI interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_spi_writebyte(uint8_t wb) {};
-void wizchip_spi_writebyte(uint8_t wb) {}
-
-/**
- * @brief Default function to burst read in SPI interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {};
-void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}
-
-/**
- * @brief Default function to burst write in SPI interface.
- * @note This function help not to access wrong address. If you do not describe this function or register any functions,
- * null function is called.
- */
-//void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {};
-void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}
-
-/**
- * @\ref _WIZCHIP instance
- */
-//
-//M20150401 : For a compiler didnot support a member of structure
-// Replace the assignment of struct members with the assingment of array
-//
-/*
-_WIZCHIP WIZCHIP =
- {
- .id = _WIZCHIP_ID_,
- .if_mode = _WIZCHIP_IO_MODE_,
- .CRIS._enter = wizchip_cris_enter,
- .CRIS._exit = wizchip_cris_exit,
- .CS._select = wizchip_cs_select,
- .CS._deselect = wizchip_cs_deselect,
- .IF.BUS._read_byte = wizchip_bus_readbyte,
- .IF.BUS._write_byte = wizchip_bus_writebyte
-// .IF.SPI._read_byte = wizchip_spi_readbyte,
-// .IF.SPI._write_byte = wizchip_spi_writebyte
- };
-*/
-_WIZCHIP WIZCHIP =
- {
- _WIZCHIP_IO_MODE_,
- _WIZCHIP_ID_ ,
- {
- wizchip_cris_enter,
- wizchip_cris_exit
- },
- {
- wizchip_cs_select,
- wizchip_cs_deselect
- },
- //M20150601 : Rename the function
- //wizchip_bus_readbyte,
- //wizchip_bus_writebyte
- {
- {
- wizchip_bus_readdata,
- wizchip_bus_writedata
- }
- },
-// wizchip_spi_readbyte,
-// wizchip_spi_writebyte
-};
-
-
-static uint8_t _DNS_[4]; // DNS server ip address
-static dhcp_mode _DHCP_; // DHCP mode
-
-void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void))
-{
- if(!cris_en || !cris_ex)
- {
- WIZCHIP.CRIS._enter = wizchip_cris_enter;
- WIZCHIP.CRIS._exit = wizchip_cris_exit;
- }
- else
- {
- WIZCHIP.CRIS._enter = cris_en;
- WIZCHIP.CRIS._exit = cris_ex;
- }
-}
-
-void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void))
-{
- if(!cs_sel || !cs_desel)
- {
- WIZCHIP.CS._select = wizchip_cs_select;
- WIZCHIP.CS._deselect = wizchip_cs_deselect;
- }
- else
- {
- WIZCHIP.CS._select = cs_sel;
- WIZCHIP.CS._deselect = cs_desel;
- }
-}
-
-//M20150515 : For integrating with W5300
-//void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
-void reg_wizchip_bus_cbfunc(iodata_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb))
-{
- while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_));
- //M20150601 : Rename call back function for integrating with W5300
- /*
- if(!bus_rb || !bus_wb)
- {
- WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte;
- WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte;
- }
- else
- {
- WIZCHIP.IF.BUS._read_byte = bus_rb;
- WIZCHIP.IF.BUS._write_byte = bus_wb;
- }
- */
- if(!bus_rb || !bus_wb)
- {
- WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata;
- WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata;
- }
- else
- {
- WIZCHIP.IF.BUS._read_data = bus_rb;
- WIZCHIP.IF.BUS._write_data = bus_wb;
- }
-}
-
-void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb))
-{
- while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
-
- if(!spi_rb || !spi_wb)
- {
- WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte;
- WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte;
- }
- else
- {
- WIZCHIP.IF.SPI._read_byte = spi_rb;
- WIZCHIP.IF.SPI._write_byte = spi_wb;
- }
-}
-
-// 20140626 Eric Added for SPI burst operations
-void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len))
-{
- while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_));
-
- if(!spi_rb || !spi_wb)
- {
- WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst;
- WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst;
- }
- else
- {
- WIZCHIP.IF.SPI._read_burst = spi_rb;
- WIZCHIP.IF.SPI._write_burst = spi_wb;
- }
-}
-
-int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
-{
-#if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
- uint8_t tmp = 0;
-#endif
- uint8_t* ptmp[2] = {0,0};
- switch(cwtype)
- {
- case CW_RESET_WIZCHIP:
- wizchip_sw_reset();
- break;
- case CW_INIT_WIZCHIP:
- if(arg != 0)
- {
- ptmp[0] = (uint8_t*)arg;
- ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
- }
- return wizchip_init(ptmp[0], ptmp[1]);
- case CW_CLR_INTERRUPT:
- wizchip_clrinterrupt(*((intr_kind*)arg));
- break;
- case CW_GET_INTERRUPT:
- *((intr_kind*)arg) = wizchip_getinterrupt();
- break;
- case CW_SET_INTRMASK:
- wizchip_setinterruptmask(*((intr_kind*)arg));
- break;
- case CW_GET_INTRMASK:
- *((intr_kind*)arg) = wizchip_getinterruptmask();
- break;
- //M20150601 : This can be supported by W5200, W5500
- //#if _WIZCHIP_ > 5100
- #if (_WIZCHIP_ == 5200 || _WIZCHIP_ == 5500)
- case CW_SET_INTRTIME:
- setINTLEVEL(*(uint16_t*)arg);
- break;
- case CW_GET_INTRTIME:
- *(uint16_t*)arg = getINTLEVEL();
- break;
- #endif
- case CW_GET_ID:
- ((uint8_t*)arg)[0] = WIZCHIP.id[0];
- ((uint8_t*)arg)[1] = WIZCHIP.id[1];
- ((uint8_t*)arg)[2] = WIZCHIP.id[2];
- ((uint8_t*)arg)[3] = WIZCHIP.id[3];
- ((uint8_t*)arg)[4] = WIZCHIP.id[4];
- ((uint8_t*)arg)[5] = 0;
- break;
- #if _WIZCHIP_ == 5500
- case CW_RESET_PHY:
- wizphy_reset();
- break;
- case CW_SET_PHYCONF:
- wizphy_setphyconf((wiz_PhyConf*)arg);
- break;
- case CW_GET_PHYCONF:
- wizphy_getphyconf((wiz_PhyConf*)arg);
- break;
- case CW_GET_PHYSTATUS:
- break;
- case CW_SET_PHYPOWMODE:
- return wizphy_setphypmode(*(uint8_t*)arg);
- #endif
- #if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
- case CW_GET_PHYPOWMODE:
- tmp = wizphy_getphypmode();
- if((int8_t)tmp == -1) return -1;
- *(uint8_t*)arg = tmp;
- break;
- case CW_GET_PHYLINK:
- tmp = wizphy_getphylink();
- if((int8_t)tmp == -1) return -1;
- *(uint8_t*)arg = tmp;
- break;
- #endif
- default:
- return -1;
- }
- return 0;
-}
-
-
-int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
-{
-
- switch(cntype)
- {
- case CN_SET_NETINFO:
- wizchip_setnetinfo((wiz_NetInfo*)arg);
- break;
- case CN_GET_NETINFO:
- wizchip_getnetinfo((wiz_NetInfo*)arg);
- break;
- case CN_SET_NETMODE:
- return wizchip_setnetmode(*(netmode_type*)arg);
- case CN_GET_NETMODE:
- *(netmode_type*)arg = wizchip_getnetmode();
- break;
- case CN_SET_TIMEOUT:
- wizchip_settimeout((wiz_NetTimeout*)arg);
- break;
- case CN_GET_TIMEOUT:
- wizchip_gettimeout((wiz_NetTimeout*)arg);
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-void wizchip_sw_reset(void)
-{
- uint8_t gw[4], sn[4], sip[4];
- uint8_t mac[6];
-//A20150601
-#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
- uint16_t mr = (uint16_t)getMR();
- setMR(mr | MR_IND);
-#endif
-//
- getSHAR(mac);
- getGAR(gw); getSUBR(sn); getSIPR(sip);
- setMR(MR_RST);
- getMR(); // for delay
-//A2015051 : For indirect bus mode
-#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_
- setMR(mr | MR_IND);
-#endif
-//
- setSHAR(mac);
- setGAR(gw);
- setSUBR(sn);
- setSIPR(sip);
-}
-
-int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
-{
- int8_t i;
- int8_t tmp = 0;
- wizchip_sw_reset();
- if(txsize)
- {
- tmp = 0;
- //M20150601 : For integrating with W5300
- #if _WIZCHIP_ == 5300
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- if(txsize[i] >= 64) return -1; //No use 64KB even if W5300 support max 64KB memory allocation
- tmp += txsize[i];
- if(tmp > 128) return -1;
- }
- if(tmp % 8) return -1;
- #else
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- tmp += txsize[i];
- if(tmp > 16) return -1;
- }
- #endif
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- setSn_TXBUF_SIZE(i, txsize[i]);
- }
- if(rxsize)
- {
- tmp = 0;
- #if _WIZCHIP_ == 5300
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- if(rxsize[i] >= 64) return -1; //No use 64KB even if W5300 support max 64KB memory allocation
- tmp += rxsize[i];
- if(tmp > 128) return -1;
- }
- if(tmp % 8) return -1;
- #else
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- {
- tmp += rxsize[i];
- if(tmp > 16) return -1;
- }
- #endif
-
- for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
- setSn_RXBUF_SIZE(i, rxsize[i]);
- }
- return 0;
-}
-
-void wizchip_clrinterrupt(intr_kind intr)
-{
- uint8_t ir = (uint8_t)intr;
- uint8_t sir = (uint8_t)((uint16_t)intr >> 8);
-#if _WIZCHIP_ < 5500
- ir |= (1<<4); // IK_WOL
-#endif
-#if _WIZCHIP_ == 5200
- ir |= (1 << 6);
-#endif
-
-#if _WIZCHIP_ < 5200
- sir &= 0x0F;
-#endif
-
-#if _WIZCHIP_ == 5100
- ir |= sir;
- setIR(ir);
-//A20150601 : For integrating with W5300
-#elif _WIZCHIP_ == 5300
- setIR( ((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF)) );
-#else
- setIR(ir);
- setSIR(sir);
-#endif
-}
-
-intr_kind wizchip_getinterrupt(void)
-{
- uint8_t ir = 0;
- uint8_t sir = 0;
- uint16_t ret = 0;
-#if _WIZCHIP_ == 5100
- ir = getIR();
- sir = ir & 0x0F;
-//A20150601 : For integrating with W5300
-#elif _WIZCHIP_ == 5300
- ret = getIR();
- ir = (uint8_t)(ret >> 8);
- sir = (uint8_t)ret;
-#else
- ir = getIR();
- sir = getSIR();
-#endif
-
-//M20150601 : For Integrating with W5300
-//#if _WIZCHIP_ < 5500
-#if _WIZCHIP_ < 5200
- ir &= ~(1<<4); // IK_WOL
-#endif
-#if _WIZCHIP_ == 5200
- ir &= ~(1 << 6);
-#endif
- ret = sir;
- ret = (ret << 8) + ir;
- return (intr_kind)ret;
-}
-
-void wizchip_setinterruptmask(intr_kind intr)
-{
- uint8_t imr = (uint8_t)intr;
- uint8_t simr = (uint8_t)((uint16_t)intr >> 8);
-#if _WIZCHIP_ < 5500
- imr &= ~(1<<4); // IK_WOL
-#endif
-#if _WIZCHIP_ == 5200
- imr &= ~(1 << 6);
-#endif
-
-#if _WIZCHIP_ == 5100
- simr &= 0x0F;
- imr |= simr;
- setIMR(imr);
-//A20150601 : For integrating with W5300
-#elif _WIZCHIP_ == 5300
- setIMR( ((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF)) );
-#else
- setIMR(imr);
- setSIMR(simr);
-#endif
-}
-
-intr_kind wizchip_getinterruptmask(void)
-{
- uint8_t imr = 0;
- uint8_t simr = 0;
- uint16_t ret = 0;
-#if _WIZCHIP_ == 5100
- imr = getIMR();
- simr = imr & 0x0F;
-//A20150601 : For integrating with W5300
-#elif _WIZCHIP_ == 5300
- ret = getIMR();
- imr = (uint8_t)(ret >> 8);
- simr = (uint8_t)ret;
-#else
- imr = getIMR();
- simr = getSIMR();
-#endif
-
-#if _WIZCHIP_ < 5500
- imr &= ~(1<<4); // IK_WOL
-#endif
-#if _WIZCHIP_ == 5200
- imr &= ~(1 << 6); // IK_DEST_UNREACH
-#endif
- ret = simr;
- ret = (ret << 8) + imr;
- return (intr_kind)ret;
-}
-
-int8_t wizphy_getphylink(void)
-{
- int8_t tmp;
-#if _WIZCHIP_ == 5200
- if(getPHYSTATUS() & PHYSTATUS_LINK)
- tmp = PHY_LINK_ON;
- else
- tmp = PHY_LINK_OFF;
-#elif _WIZCHIP_ == 5500
- if(getPHYCFGR() & PHYCFGR_LNK_ON)
- tmp = PHY_LINK_ON;
- else
- tmp = PHY_LINK_OFF;
-#else
- tmp = -1;
-#endif
- return tmp;
-}
-
-#if _WIZCHIP_ > 5100
-
-int8_t wizphy_getphypmode(void)
-{
- int8_t tmp = 0;
- #if _WIZCHIP_ == 5200
- if(getPHYSTATUS() & PHYSTATUS_POWERDOWN)
- tmp = PHY_POWER_DOWN;
- else
- tmp = PHY_POWER_NORM;
- #elif _WIZCHIP_ == 5500
- if(getPHYCFGR() & PHYCFGR_OPMDC_PDOWN)
- tmp = PHY_POWER_DOWN;
- else
- tmp = PHY_POWER_NORM;
- #else
- tmp = -1;
- #endif
- return tmp;
-}
-#endif
-
-#if _WIZCHIP_ == 5500
-void wizphy_reset(void)
-{
- uint8_t tmp = getPHYCFGR();
- tmp &= PHYCFGR_RST;
- setPHYCFGR(tmp);
- tmp = getPHYCFGR();
- tmp |= ~PHYCFGR_RST;
- setPHYCFGR(tmp);
-}
-
-void wizphy_setphyconf(wiz_PhyConf* phyconf)
-{
- uint8_t tmp = 0;
- if(phyconf->by == PHY_CONFBY_SW)
- tmp |= PHYCFGR_OPMD;
- else
- tmp &= ~PHYCFGR_OPMD;
- if(phyconf->mode == PHY_MODE_AUTONEGO)
- tmp |= PHYCFGR_OPMDC_ALLA;
- else
- {
- if(phyconf->duplex == PHY_DUPLEX_FULL)
- {
- if(phyconf->speed == PHY_SPEED_100)
- tmp |= PHYCFGR_OPMDC_100F;
- else
- tmp |= PHYCFGR_OPMDC_10F;
- }
- else
- {
- if(phyconf->speed == PHY_SPEED_100)
- tmp |= PHYCFGR_OPMDC_100H;
- else
- tmp |= PHYCFGR_OPMDC_10H;
- }
- }
- setPHYCFGR(tmp);
- wizphy_reset();
-}
-
-void wizphy_getphyconf(wiz_PhyConf* phyconf)
-{
- uint8_t tmp = 0;
- tmp = getPHYCFGR();
- phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_ALLA:
- case PHYCFGR_OPMDC_100FA:
- phyconf->mode = PHY_MODE_AUTONEGO;
- break;
- default:
- phyconf->mode = PHY_MODE_MANUAL;
- break;
- }
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_100FA:
- case PHYCFGR_OPMDC_100F:
- case PHYCFGR_OPMDC_100H:
- phyconf->speed = PHY_SPEED_100;
- break;
- default:
- phyconf->speed = PHY_SPEED_10;
- break;
- }
- switch(tmp & PHYCFGR_OPMDC_ALLA)
- {
- case PHYCFGR_OPMDC_100FA:
- case PHYCFGR_OPMDC_100F:
- case PHYCFGR_OPMDC_10F:
- phyconf->duplex = PHY_DUPLEX_FULL;
- break;
- default:
- phyconf->duplex = PHY_DUPLEX_HALF;
- break;
- }
-}
-
-void wizphy_getphystat(wiz_PhyConf* phyconf)
-{
- uint8_t tmp = getPHYCFGR();
- phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
- phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
-}
-
-int8_t wizphy_setphypmode(uint8_t pmode)
-{
- uint8_t tmp = 0;
- tmp = getPHYCFGR();
- if((tmp & PHYCFGR_OPMD)== 0) return -1;
- tmp &= ~PHYCFGR_OPMDC_ALLA;
- if( pmode == PHY_POWER_DOWN)
- tmp |= PHYCFGR_OPMDC_PDOWN;
- else
- tmp |= PHYCFGR_OPMDC_ALLA;
- setPHYCFGR(tmp);
- wizphy_reset();
- tmp = getPHYCFGR();
- if( pmode == PHY_POWER_DOWN)
- {
- if(tmp & PHYCFGR_OPMDC_PDOWN) return 0;
- }
- else
- {
- if(tmp & PHYCFGR_OPMDC_ALLA) return 0;
- }
- return -1;
-}
-#endif
-
-
-void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
-{
- setSHAR(pnetinfo->mac);
- setGAR(pnetinfo->gw);
- setSUBR(pnetinfo->sn);
- setSIPR(pnetinfo->ip);
- _DNS_[0] = pnetinfo->dns[0];
- _DNS_[1] = pnetinfo->dns[1];
- _DNS_[2] = pnetinfo->dns[2];
- _DNS_[3] = pnetinfo->dns[3];
- _DHCP_ = pnetinfo->dhcp;
-}
-
-void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
-{
- getSHAR(pnetinfo->mac);
- getGAR(pnetinfo->gw);
- getSUBR(pnetinfo->sn);
- getSIPR(pnetinfo->ip);
- pnetinfo->dns[0]= _DNS_[0];
- pnetinfo->dns[1]= _DNS_[1];
- pnetinfo->dns[2]= _DNS_[2];
- pnetinfo->dns[3]= _DNS_[3];
- pnetinfo->dhcp = _DHCP_;
-}
-
-int8_t wizchip_setnetmode(netmode_type netmode)
-{
- uint8_t tmp = 0;
-#if _WIZCHIP_ != 5500
- if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1;
-#else
- if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1;
-#endif
- tmp = getMR();
- tmp |= (uint8_t)netmode;
- setMR(tmp);
- return 0;
-}
-
-netmode_type wizchip_getnetmode(void)
-{
- return (netmode_type) getMR();
-}
-
-void wizchip_settimeout(wiz_NetTimeout* nettime)
-{
- setRCR(nettime->retry_cnt);
- setRTR(nettime->time_100us);
-}
-
-void wizchip_gettimeout(wiz_NetTimeout* nettime)
-{
- nettime->retry_cnt = getRCR();
- nettime->time_100us = getRTR();
-}
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.cpp b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.cpp
new file mode 100644
index 00000000..85d19e26
--- /dev/null
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.cpp
@@ -0,0 +1,455 @@
+//****************************************************************************/
+//!
+//! \file wizchip_conf.c
+//! \brief WIZCHIP Config Header File.
+//! \version 1.0.1
+//! \date 2013/10/21
+//! \par Revision history
+//! <2015/02/05> Notice
+//! The version history is not updated after this point.
+//! Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
+//! >> https://github.com/Wiznet/ioLibrary_Driver
+//! <2014/05/01> V1.0.1 Refer to M20140501
+//! 1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
+// Issued by Mathias ClauBen.
+//! uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
+//! For remove the warning when pointer type size is not 32bit.
+//! If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
+//! <2013/10/21> 1st Release
+//! \author MidnightCow
+//! \copyright
+//!
+//! Copyright (c) 2013, WIZnet Co., LTD.
+//! All rights reserved.
+//!
+//! Redistribution and use in source and binary forms, with or without
+//! modification, are permitted provided that the following conditions
+//! are met:
+//!
+//! * Redistributions of source code must retain the above copyright
+//! notice, this list of conditions and the following disclaimer.
+//! * Redistributions in binary form must reproduce the above copyright
+//! notice, this list of conditions and the following disclaimer in the
+//! documentation and/or other materials provided with the distribution.
+//! * Neither the name of the <ORGANIZATION> nor the names of its
+//! contributors may be used to endorse or promote products derived
+//! from this software without specific prior written permission.
+//!
+//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+//! THE POSSIBILITY OF SUCH DAMAGE.
+//
+//*****************************************************************************/
+//A20140501 : for use the type - ptrdiff_t
+
+#include <cstddef>
+#include <cstring>
+#include "wizchip_conf.h"
+
+/**
+ * @\ref WIZCHIP instance data
+ */
+
+static uint8_t _DNS_[4]; // DNS server ip address
+static dhcp_mode _DHCP_; // DHCP mode
+static const char WizchipId[6] = "w5500";
+
+int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg)
+{
+ switch(cwtype)
+ {
+ case CW_RESET_WIZCHIP:
+ wizchip_sw_reset();
+ break;
+ case CW_INIT_WIZCHIP:
+ {
+ uint8_t* ptmp[2] = {0,0};
+ if (arg != 0)
+ {
+ ptmp[0] = (uint8_t*)arg;
+ ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_;
+ }
+ return wizchip_init(ptmp[0], ptmp[1]);
+ }
+ case CW_CLR_INTERRUPT:
+ wizchip_clrinterrupt(*((intr_kind*)arg));
+ break;
+ case CW_GET_INTERRUPT:
+ *((intr_kind*)arg) = wizchip_getinterrupt();
+ break;
+ case CW_SET_INTRMASK:
+ wizchip_setinterruptmask(*((intr_kind*)arg));
+ break;
+ case CW_GET_INTRMASK:
+ *((intr_kind*)arg) = wizchip_getinterruptmask();
+ break;
+ case CW_SET_INTRTIME:
+ setINTLEVEL(*(uint16_t*)arg);
+ break;
+ case CW_GET_INTRTIME:
+ *(uint16_t*)arg = getINTLEVEL();
+ break;
+ case CW_GET_ID:
+ memcpy(arg, WizchipId, sizeof(WizchipId));
+ break;
+ case CW_RESET_PHY:
+ wizphy_reset();
+ break;
+ case CW_SET_PHYCONF:
+ wizphy_setphyconf((wiz_PhyConf*)arg);
+ break;
+ case CW_GET_PHYCONF:
+ wizphy_getphyconf((wiz_PhyConf*)arg);
+ break;
+ case CW_GET_PHYSTATUS:
+ break;
+ case CW_SET_PHYPOWMODE:
+ return wizphy_setphypmode(*(uint8_t*)arg);
+ case CW_GET_PHYPOWMODE:
+ {
+ uint8_t tmp = wizphy_getphypmode();
+ if ((int8_t)tmp == -1)
+ {
+ return -1;
+ }
+ *(uint8_t*)arg = tmp;
+ }
+ break;
+ case CW_GET_PHYLINK:
+ {
+ uint8_t tmp = wizphy_getphylink();
+ if ((int8_t)tmp == -1)
+ {
+ return -1;
+ }
+ *(uint8_t*)arg = tmp;
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+
+int8_t ctlnetwork(ctlnetwork_type cntype, void* arg)
+{
+ switch(cntype)
+ {
+ case CN_SET_NETINFO:
+ wizchip_setnetinfo((wiz_NetInfo*)arg);
+ break;
+ case CN_GET_NETINFO:
+ wizchip_getnetinfo((wiz_NetInfo*)arg);
+ break;
+ case CN_SET_NETMODE:
+ return wizchip_setnetmode(*(netmode_type*)arg);
+ case CN_GET_NETMODE:
+ *(netmode_type*)arg = wizchip_getnetmode();
+ break;
+ case CN_SET_TIMEOUT:
+ wizchip_settimeout((wiz_NetTimeout*)arg);
+ break;
+ case CN_GET_TIMEOUT:
+ wizchip_gettimeout((wiz_NetTimeout*)arg);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+void wizchip_sw_reset(void)
+{
+ uint8_t gw[4], sn[4], sip[4];
+ uint8_t mac[6];
+ getSHAR(mac);
+ getGAR(gw); getSUBR(sn); getSIPR(sip);
+ setMR(MR_RST);
+ getMR(); // for delay
+ setSHAR(mac);
+ setGAR(gw);
+ setSUBR(sn);
+ setSIPR(sip);
+}
+
+int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize)
+{
+ wizchip_sw_reset();
+ if (txsize != nullptr)
+ {
+ int8_t tmp = 0;
+ for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+ {
+ tmp += txsize[i];
+ if (tmp > 16)
+ {
+ return -1;
+ }
+ }
+ for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+ {
+ setSn_TXBUF_SIZE(i, txsize[i]);
+ }
+ }
+ if (rxsize != nullptr)
+ {
+ int8_t tmp = 0;
+ for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+ {
+ tmp += rxsize[i];
+ if (tmp > 16)
+ {
+ return -1;
+ }
+ }
+
+ for (uint8_t i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++)
+ {
+ setSn_RXBUF_SIZE(i, rxsize[i]);
+ }
+ }
+ return 0;
+}
+
+void wizchip_clrinterrupt(intr_kind intr)
+{
+ setIR((uint8_t)intr);
+ setSIR((uint8_t)((uint16_t)intr >> 8));
+}
+
+intr_kind wizchip_getinterrupt(void)
+{
+ const uint8_t ir = getIR();
+ const uint8_t sir = getSIR();
+ const uint16_t ret = ((uint16_t)sir << 8) | ir;
+ return (intr_kind)ret;
+}
+
+void wizchip_setinterruptmask(intr_kind intr)
+{
+ setIMR((uint8_t)intr);
+ setSIMR((uint8_t)((uint16_t)intr >> 8));
+}
+
+intr_kind wizchip_getinterruptmask(void)
+{
+ const uint8_t imr = getIMR();
+ const uint8_t simr = getSIMR();
+ const uint16_t ret = ((uint16_t)simr << 8) | imr;
+ return (intr_kind)ret;
+}
+
+int8_t wizphy_getphylink(void)
+{
+ return (getPHYCFGR() & PHYCFGR_LNK_ON) ? PHY_LINK_ON : PHY_LINK_OFF;
+}
+
+int8_t wizphy_getphypmode(void)
+{
+ return (getPHYCFGR() & PHYCFGR_OPMDC_PDOWN) ? PHY_POWER_DOWN : PHY_POWER_NORM;
+}
+
+void wizphy_reset(void)
+{
+ uint8_t tmp = getPHYCFGR();
+ tmp &= PHYCFGR_RST;
+ setPHYCFGR(tmp);
+ tmp = getPHYCFGR();
+ tmp |= ~PHYCFGR_RST;
+ setPHYCFGR(tmp);
+}
+
+void wizphy_setphyconf(wiz_PhyConf* phyconf)
+{
+ uint8_t tmp = 0;
+ if (phyconf->by == PHY_CONFBY_SW)
+ {
+ tmp |= PHYCFGR_OPMD;
+ }
+ else
+ {
+ tmp &= ~PHYCFGR_OPMD;
+ }
+ if (phyconf->mode == PHY_MODE_AUTONEGO)
+ {
+ tmp |= PHYCFGR_OPMDC_ALLA;
+ }
+ else
+ {
+ if (phyconf->duplex == PHY_DUPLEX_FULL)
+ {
+ if (phyconf->speed == PHY_SPEED_100)
+ {
+ tmp |= PHYCFGR_OPMDC_100F;
+ }
+ else
+ {
+ tmp |= PHYCFGR_OPMDC_10F;
+ }
+ }
+ else
+ {
+ if (phyconf->speed == PHY_SPEED_100)
+ {
+ tmp |= PHYCFGR_OPMDC_100H;
+ }
+ else
+ {
+ tmp |= PHYCFGR_OPMDC_10H;
+ }
+ }
+ }
+ setPHYCFGR(tmp);
+ wizphy_reset();
+}
+
+void wizphy_getphyconf(wiz_PhyConf* phyconf)
+{
+ const uint8_t tmp = getPHYCFGR();
+ phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW;
+ switch(tmp & PHYCFGR_OPMDC_ALLA)
+ {
+ case PHYCFGR_OPMDC_ALLA:
+ case PHYCFGR_OPMDC_100FA:
+ phyconf->mode = PHY_MODE_AUTONEGO;
+ break;
+ default:
+ phyconf->mode = PHY_MODE_MANUAL;
+ break;
+ }
+
+ switch(tmp & PHYCFGR_OPMDC_ALLA)
+ {
+ case PHYCFGR_OPMDC_100FA:
+ case PHYCFGR_OPMDC_100F:
+ case PHYCFGR_OPMDC_100H:
+ phyconf->speed = PHY_SPEED_100;
+ break;
+ default:
+ phyconf->speed = PHY_SPEED_10;
+ break;
+ }
+
+ switch(tmp & PHYCFGR_OPMDC_ALLA)
+ {
+ case PHYCFGR_OPMDC_100FA:
+ case PHYCFGR_OPMDC_100F:
+ case PHYCFGR_OPMDC_10F:
+ phyconf->duplex = PHY_DUPLEX_FULL;
+ break;
+ default:
+ phyconf->duplex = PHY_DUPLEX_HALF;
+ break;
+ }
+}
+
+void wizphy_getphystat(wiz_PhyConf* phyconf)
+{
+ const uint8_t tmp = getPHYCFGR();
+ phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF;
+ phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10;
+}
+
+int8_t wizphy_setphypmode(uint8_t pmode)
+{
+ uint8_t tmp = getPHYCFGR();
+ if ((tmp & PHYCFGR_OPMD)== 0)
+ {
+ return -1;
+ }
+ tmp &= ~PHYCFGR_OPMDC_ALLA;
+ if (pmode == PHY_POWER_DOWN)
+ {
+ tmp |= PHYCFGR_OPMDC_PDOWN;
+ }
+ else
+ {
+ tmp |= PHYCFGR_OPMDC_ALLA;
+ }
+ setPHYCFGR(tmp);
+ wizphy_reset();
+
+ tmp = getPHYCFGR();
+ if (pmode == PHY_POWER_DOWN)
+ {
+ if (tmp & PHYCFGR_OPMDC_PDOWN)
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (tmp & PHYCFGR_OPMDC_ALLA)
+ {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+
+void wizchip_setnetinfo(wiz_NetInfo* pnetinfo)
+{
+ setSHAR(pnetinfo->mac);
+ setGAR(pnetinfo->gw);
+ setSUBR(pnetinfo->sn);
+ setSIPR(pnetinfo->ip);
+ _DNS_[0] = pnetinfo->dns[0];
+ _DNS_[1] = pnetinfo->dns[1];
+ _DNS_[2] = pnetinfo->dns[2];
+ _DNS_[3] = pnetinfo->dns[3];
+ _DHCP_ = pnetinfo->dhcp;
+}
+
+void wizchip_getnetinfo(wiz_NetInfo* pnetinfo)
+{
+ getSHAR(pnetinfo->mac);
+ getGAR(pnetinfo->gw);
+ getSUBR(pnetinfo->sn);
+ getSIPR(pnetinfo->ip);
+ pnetinfo->dns[0]= _DNS_[0];
+ pnetinfo->dns[1]= _DNS_[1];
+ pnetinfo->dns[2]= _DNS_[2];
+ pnetinfo->dns[3]= _DNS_[3];
+ pnetinfo->dhcp = _DHCP_;
+}
+
+int8_t wizchip_setnetmode(netmode_type netmode)
+{
+ if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP))
+ {
+ return -1;
+ }
+ uint8_t tmp = getMR();
+ tmp |= (uint8_t)netmode;
+ setMR(tmp);
+ return 0;
+}
+
+netmode_type wizchip_getnetmode(void)
+{
+ return (netmode_type) getMR();
+}
+
+void wizchip_settimeout(wiz_NetTimeout* nettime)
+{
+ setRCR(nettime->retry_cnt);
+ setRTR(nettime->time_100us);
+}
+
+void wizchip_gettimeout(wiz_NetTimeout* nettime)
+{
+ nettime->retry_cnt = getRCR();
+ nettime->time_100us = getRTR();
+}
+
+// End
diff --git a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.h b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.h
index d6e47236..edb0f590 100644
--- a/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.h
+++ b/src/DuetNG/DuetEthernet/Wiznet/Ethernet/wizchip_conf.h
@@ -61,7 +61,7 @@
* ex> <code> #define \_WIZCHIP_ 5500 </code>
*/
#ifndef _WIZCHIP_
-#define _WIZCHIP_ 5500 // 5100, 5200, 5300, 5500
+# define _WIZCHIP_ 5500 // 5100, 5200, 5300, 5500
#endif
#define _WIZCHIP_IO_MODE_NONE_ 0x0000
@@ -69,8 +69,6 @@
#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */
//#define _WIZCHIP_IO_MODE_IIC_ 0x0400
//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800
-// Add to
-//
#define _WIZCHIP_IO_MODE_BUS_DIR_ (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */
#define _WIZCHIP_IO_MODE_BUS_INDIR_ (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */
@@ -79,36 +77,7 @@
#define _WIZCHIP_IO_MODE_SPI_FDM_ (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/
-#if (_WIZCHIP_ == 5100)
- #define _WIZCHIP_ID_ "W5100\0"
-/**
- * @brief Define interface mode.
- * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
- */
-// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
-// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
- #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
-
-//A20150601 : Define the unit of IO DATA.
- typedef uint8_t iodata_t;
-//A20150401 : Indclude W5100.h file
- #include "W5100/w5100.h"
-
-#elif (_WIZCHIP_ == 5200)
- #define _WIZCHIP_ID_ "W5200\0"
-/**
- * @brief Define interface mode.
- * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
- */
-#ifndef _WIZCHIP_IO_MODE_
-// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
- #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_
-#endif
-//A20150601 : Define the unit of IO DATA.
- typedef uint8_t iodata_t;
- #include "W5200/w5200.h"
-#elif (_WIZCHIP_ == 5500)
- #define _WIZCHIP_ID_ "W5500\0"
+#define _WIZCHIP_ID_ "W5500"
/**
* @brief Define interface mode. \n
@@ -127,40 +96,10 @@
//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_
#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_
#endif
-//A20150601 : Define the unit of IO DATA.
- typedef uint8_t iodata_t;
- #include "W5500/w5500.h"
-#elif ( _WIZCHIP_ == 5300)
- #define _WIZCHIP_ID_ "W5300\0"
-/**
- * @brief Define interface mode.
- * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_
- */
-#ifndef _WIZCHIP_IO_MODE_
-// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_
- #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_
-#endif
-//A20150601 : Define the unit and bus width of IO DATA.
- /**
- * @brief Select the data width 8 or 16 bits.
- * @todo you should select the bus width. Select one of 8 or 16.
- */
- #ifndef _WIZCHIP_IO_BUS_WIDTH_
- #define _WIZCHIP_IO_BUS_WIDTH_ 8 // 16
- #endif
- #if _WIZCHIP_IO_BUS_WIDTH_ == 8
- typedef uint8_t iodata_t;
- #elif _WIZCHIP_IO_BUS_WIDTH_ == 16
- typedef uint16_t iodata_t;
- #else
- #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16."
- #endif
-//
- #include "W5300/w5300.h"
-#else
- #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!"
-#endif
+typedef uint8_t iodata_t;
+
+#include "W5500/w5500.h"
#ifndef _WIZCHIP_IO_MODE_
#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!"
@@ -173,93 +112,27 @@
* ex> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/
#ifndef _WIZCHIP_IO_BASE_
-#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000
+# define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000
#endif
-//M20150401 : Typing Error
-//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS
#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_
#ifndef _WIZCHIP_IO_BASE_
#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map."
#endif
#endif
-#if _WIZCHIP_ > 5100
- #define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP
-#else
- #define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP
-#endif
+#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independent socket of @b WIZCHIP
/********************************************************
* WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC.
*********************************************************/
-/**
- * @ingroup DATA_TYPE
- * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200
- */
-typedef struct __WIZCHIP
-{
- uint16_t if_mode; ///< host interface mode
- uint8_t id[6]; ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on.
- /**
- * The set of critical section callback func.
- */
- struct _CRIS
- {
- void (*_enter) (void); ///< crtical section enter
- void (*_exit) (void); ///< critial section exit
- }CRIS;
- /**
- * The set of @ref \_WIZCHIP_ select control callback func.
- */
- struct _CS
- {
- void (*_select) (void); ///< @ref \_WIZCHIP_ selected
- void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected
- }CS;
- /**
- * The set of interface IO callback func.
- */
- union _IF
- {
- /**
- * For BUS interface IO
- */
- //M20156501 : Modify the function name for integrating with W5300
- //struct
- //{
- // uint8_t (*_read_byte) (uint32_t AddrSel);
- // void (*_write_byte) (uint32_t AddrSel, uint8_t wb);
- //}BUS;
- struct
- {
- iodata_t (*_read_data) (uint32_t AddrSel);
- void (*_write_data) (uint32_t AddrSel, iodata_t wb);
- }BUS;
-
- /**
- * For SPI interface IO
- */
- struct
- {
- uint8_t (*_read_byte) (void);
- void (*_write_byte) (uint8_t wb);
- void (*_read_burst) (uint8_t* pBuf, uint16_t len);
- void (*_write_burst) (uint8_t* pBuf, uint16_t len);
- }SPI;
- // To be added
- //
- }IF;
-}_WIZCHIP;
-
-extern _WIZCHIP WIZCHIP;
/**
* @ingroup DATA_TYPE
- * WIZCHIP control type enumration used in @ref ctlwizchip().
+ * WIZCHIP control type enumeration used in @ref ctlwizchip().
*/
-typedef enum
+enum ctlwizchip_type
{
CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly
CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
@@ -271,26 +144,20 @@ typedef enum
CW_GET_INTRTIME, ///< Set interval time between the current and next interrupt.
CW_GET_ID, ///< Gets WIZCHIP name.
-//D20150601 : For no modification your application code
-//#if _WIZCHIP_ == 5500
CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500
CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only W5500
CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500
CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500
-//#endif
-//D20150601 : For no modification your application code
-//#if _WIZCHIP_ == 5200 || _WIZCHIP_ == 5500
CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200
CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200
-//#endif
-}ctlwizchip_type;
+};
/**
* @ingroup DATA_TYPE
* Network control type enumration used in @ref ctlnetwork().
*/
-typedef enum
+enum ctlnetwork_type
{
CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo
CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo
@@ -298,7 +165,7 @@ typedef enum
CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
CN_SET_TIMEOUT, ///< Set network timeout as retry count and time.
CN_GET_TIMEOUT, ///< Get network timeout as retry count and time.
-}ctlnetwork_type;
+};
/**
* @ingroup DATA_TYPE
@@ -306,19 +173,13 @@ typedef enum
* and CW_GET_INTRMASK is used in @ref ctlnetwork().
* It can be used with OR operation.
*/
-typedef enum
+enum intr_kind
{
-#if _WIZCHIP_ == 5500
IK_WOL = (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500.
-#elif _WIZCHIP_ == 5300
- IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU)
-#endif
IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected
-#if _WIZCHIP_ != 5200
IK_DEST_UNREACH = (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200
-#endif
IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred
@@ -326,19 +187,13 @@ typedef enum
IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt
IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt
IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt
-#if _WIZCHIP_ > 5100
IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100
IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100
IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100
IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100
-#endif
-#if _WIZCHIP_ > 5100
IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt
-#else
- IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt
-#endif
-}intr_kind;
+};
#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin
#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register
@@ -354,39 +209,37 @@ typedef enum
#define PHY_POWER_DOWN 1 ///< PHY power down mode
-#if _WIZCHIP_ == 5500
/**
* @ingroup DATA_TYPE
* It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,
* and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n
* Valid only in W5500.
*/
-typedef struct wiz_PhyConf_t
+struct wiz_PhyConf
{
- uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
- uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
- uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
- uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
- //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
- //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
- }wiz_PhyConf;
-#endif
+ uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
+ uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
+ uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
+ uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL
+ //uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
+ //uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF
+};
/**
* @ingroup DATA_TYPE
* It used in setting dhcp_mode of @ref wiz_NetInfo.
*/
-typedef enum
+enum dhcp_mode
{
NETINFO_STATIC = 1, ///< Static IP configuration by manually.
NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever
-}dhcp_mode;
+};
/**
* @ingroup DATA_TYPE
* Network Information for WIZCHIP
*/
-typedef struct wiz_NetInfo_t
+struct wiz_NetInfo
{
uint8_t mac[6]; ///< Source Mac Address
uint8_t ip[4]; ///< Source IP Address
@@ -394,83 +247,30 @@ typedef struct wiz_NetInfo_t
uint8_t gw[4]; ///< Gateway IP Address
uint8_t dns[4]; ///< DNS server IP Address
dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP
-}wiz_NetInfo;
+};
/**
* @ingroup DATA_TYPE
* Network mode
*/
-typedef enum
+enum netmode_type
{
-#if _WIZCHIP_ == 5500
NM_FORCEARP = (1<<1), ///< Force to APP send whenever udp data is sent. Valid only in W5500
-#endif
NM_WAKEONLAN = (1<<5), ///< Wake On Lan
NM_PINGBLOCK = (1<<4), ///< Block ping-request
NM_PPPOE = (1<<3), ///< PPPoE mode
-}netmode_type;
+};
/**
* @ingroup DATA_TYPE
* Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation.
*/
-typedef struct wiz_NetTimeout_t
+struct wiz_NetTimeout
{
uint8_t retry_cnt; ///< retry count
uint16_t time_100us; ///< time unit 100us
-}wiz_NetTimeout;
-
-/**
- *@brief Registers call back function for critical section of I/O functions such as
- *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF.
- *@param cris_en : callback function for critical section enter.
- *@param cris_ex : callback function for critical section exit.
- *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions.
- *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called.
- */
-void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void));
-
-
-/**
- *@brief Registers call back function for WIZCHIP select & deselect.
- *@param cs_sel : callback function for WIZCHIP select
- *@param cs_desel : callback fucntion for WIZCHIP deselect
- *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions.
- *@note If you do not describe or register, null function is called.
- */
-void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void));
+};
-/**
- *@brief Registers call back function for bus interface.
- *@param bus_rb : callback function to read byte data using system bus
- *@param bus_wb : callback function to write byte data using system bus
- *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function
- *or register your functions.
- *@note If you do not describe or register, null function is called.
- */
-//M20150601 : For integrating with W5300
-//void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
-void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb));
-
-/**
- *@brief Registers call back function for SPI interface.
- *@param spi_rb : callback function to read byte using SPI
- *@param spi_wb : callback function to write byte using SPI
- *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
- *or register your functions.
- *@note If you do not describe or register, null function is called.
- */
-void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb));
-
-/**
- *@brief Registers call back function for SPI interface.
- *@param spi_rb : callback function to burst read using SPI
- *@param spi_wb : callback function to burst write using SPI
- *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function
- *or register your functions.
- *@note If you do not describe or register, null function is called.
- */
-void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len));
/**
* @ingroup extra_functions
@@ -545,38 +345,35 @@ void wizchip_setinterruptmask(intr_kind intr);
*/
intr_kind wizchip_getinterruptmask(void);
-#if _WIZCHIP_ > 5100
- int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100
- int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100
-#endif
+int8_t wizphy_getphylink(void); ///< get the link status of phy in WIZCHIP. No use in W5100
+int8_t wizphy_getphypmode(void); ///< get the power mode of PHY in WIZCHIP. No use in W5100
+
+void wizphy_reset(void); ///< Reset phy. Valid only in W5500
-#if _WIZCHIP_ == 5500
- void wizphy_reset(void); ///< Reset phy. Vailid only in W5500
/**
* @ingroup extra_functions
* @brief Set the phy information for WIZCHIP without power mode
* @param phyconf : @ref wiz_PhyConf
*/
- void wizphy_setphyconf(wiz_PhyConf* phyconf);
+void wizphy_setphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy configuration information.
* @param phyconf : @ref wiz_PhyConf
*/
- void wizphy_getphyconf(wiz_PhyConf* phyconf);
+void wizphy_getphyconf(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief Get phy status.
* @param phyconf : @ref wiz_PhyConf
*/
- void wizphy_getphystat(wiz_PhyConf* phyconf);
+void wizphy_getphystat(wiz_PhyConf* phyconf);
/**
* @ingroup extra_functions
* @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200
* @param pmode Settig value of power down mode.
*/
- int8_t wizphy_setphypmode(uint8_t pmode);
-#endif
+int8_t wizphy_setphypmode(uint8_t pmode);
/**
* @ingroup extra_functions
diff --git a/src/DuetNG/DuetWiFi/Network.cpp b/src/DuetNG/DuetWiFi/Network.cpp
index e8aa07aa..7920ed34 100644
--- a/src/DuetNG/DuetWiFi/Network.cpp
+++ b/src/DuetNG/DuetWiFi/Network.cpp
@@ -4,7 +4,6 @@
****************************************************************************************************/
-#include "WifiFirmwareUploader.h"
#include "RepRapFirmware.h"
#include "compiler.h"
#include "Pins.h"
diff --git a/src/DuetNG/DuetWiFi/Network.h b/src/DuetNG/DuetWiFi/Network.h
index 6fc3ed31..7f4e66f4 100644
--- a/src/DuetNG/DuetWiFi/Network.h
+++ b/src/DuetNG/DuetWiFi/Network.h
@@ -71,11 +71,6 @@ public:
void SetHostname(const char *name);
void EspRequestsTransfer();
-#if 0
- void AcquireBus();
- void ReleaseBus();
-#endif
-
const char *GetRequest(uint32_t& ip, size_t& length, uint32_t& fragment) const;
void SendReply(uint32_t ip, unsigned int code, OutputBuffer *body);
void SendReply(uint32_t ip, unsigned int code, const char *text);
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 4bdba272..9524110c 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -2173,8 +2173,8 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, StringRef& reply)
if (!seen)
{
- const byte *config_ip = platform->IPAddress();
- const byte *actual_ip = reprap.GetNetwork()->IPAddress();
+ const byte *config_ip = platform->GetIPAddress();
+ const byte *actual_ip = reprap.GetNetwork()->GetIPAddress();
reply.printf("Network is %s, configured IP address: %d.%d.%d.%d, actual IP address: %d.%d.%d.%d, HTTP port: %d",
reprap.GetNetwork()->IsEnabled() ? "enabled" : "disabled",
config_ip[0], config_ip[1], config_ip[2], config_ip[3], actual_ip[0], actual_ip[1], actual_ip[2], actual_ip[3],
diff --git a/src/Platform.cpp b/src/Platform.cpp
index 39b98c4d..e35a1be9 100644
--- a/src/Platform.cpp
+++ b/src/Platform.cpp
@@ -213,7 +213,7 @@ void Platform::Init()
ARRAY_INIT(netMask, NET_MASK);
ARRAY_INIT(gateWay, GATE_WAY);
-#ifdef DUET_NG
+#if defined(DUET_NG) && defined(DUET_WIFI)
memset(macAddress, 0xFF, sizeof(macAddress));
#else
ARRAY_INIT(macAddress, MAC_ADDRESS);
diff --git a/src/Platform.h b/src/Platform.h
index 5be96144..dfdc3e5b 100644
--- a/src/Platform.h
+++ b/src/Platform.h
@@ -385,7 +385,7 @@ public:
void SetAuxDetected() { auxDetected = true; }
void SetIPAddress(uint8_t ip[]);
- const uint8_t* IPAddress() const;
+ const uint8_t* GetIPAddress() const;
void SetNetMask(uint8_t nm[]);
const uint8_t* NetMask() const;
void SetGateWay(uint8_t gw[]);
@@ -1136,7 +1136,7 @@ inline bool Platform::IsRtdChannel(uint8_t heater) const
&& heaterTempChannels[heater] - FirstRtdChannel < MaxSpiTempSensors;
}
-inline const uint8_t* Platform::IPAddress() const
+inline const uint8_t* Platform::GetIPAddress() const
{
return ipAddress;
}
diff --git a/src/RADDS/Pins_radds.h b/src/RADDS/Pins_radds.h
index 956d7a63..3cb48c4d 100644
--- a/src/RADDS/Pins_radds.h
+++ b/src/RADDS/Pins_radds.h
@@ -123,10 +123,10 @@ const Pin COOLING_FAN_PINS[NUM_FANS] = { 9, 8 }; // Fan 0, Fan 1
const Pin COOLING_FAN_RPM_PIN = 25;
// SD cards
-const size_t NumSdCards = 1;
-const Pin SdCardDetectPins[NumSdCards] = { 14 };
-const Pin SdWriteProtectPins[NumSdCards] = { NoPin};
-const Pin SdSpiCSPins[1] = { 77 };
+const size_t NumSdCards = 2;
+const Pin SdCardDetectPins[NumSdCards] = { 14, 14 };
+const Pin SdWriteProtectPins[NumSdCards] = { NoPin, NoPin };
+const Pin SdSpiCSPins[2] = { 87, 77 };
// Definition of which pins we allow to be controlled using M42
// Spare pins on the Arduino Due are