diff options
Diffstat (limited to 'src')
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 |