/* Copyright 2018 Paul Stoffregen * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "Ethernet.h" #include "utility/w5100.h" #include "Dhcp.h" IPAddress EthernetClass::_dnsServerAddress; DhcpClass* EthernetClass::_dhcp = NULL; int EthernetClass::begin(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) { static DhcpClass s_dhcp; _dhcp = &s_dhcp; // Initialise the basic info if (W5100.init() == 0) return 0; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setMACAddress(mac); W5100.setIPAddress(IPAddress(0,0,0,0).raw_address()); SPI.endTransaction(); // Now try to get our config info from a DHCP server int ret = _dhcp->beginWithDHCP(mac, timeout, responseTimeout); if (ret == 1) { // We've successfully found a DHCP server and got our configuration // info, so set things accordingly SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); SPI.endTransaction(); _dnsServerAddress = _dhcp->getDnsServerIp(); socketPortRand(micros()); } return ret; } void EthernetClass::begin(uint8_t *mac, IPAddress ip) { // Assume the DNS server will be the machine on the same network as the local IP // but with last octet being '1' IPAddress dns = ip; dns[3] = 1; begin(mac, ip, dns); } void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns) { // Assume the gateway will be the machine on the same network as the local IP // but with last octet being '1' IPAddress gateway = ip; gateway[3] = 1; begin(mac, ip, dns, gateway); } void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway) { IPAddress subnet(255, 255, 255, 0); begin(mac, ip, dns, gateway, subnet); } void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet) { if (W5100.init() == 0) return; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setMACAddress(mac); #if ARDUINO > 106 || TEENSYDUINO > 121 W5100.setIPAddress(ip._address.bytes); W5100.setGatewayIp(gateway._address.bytes); W5100.setSubnetMask(subnet._address.bytes); #else W5100.setIPAddress(ip._address); W5100.setGatewayIp(gateway._address); W5100.setSubnetMask(subnet._address); #endif SPI.endTransaction(); _dnsServerAddress = dns; } void EthernetClass::init(uint8_t sspin) { W5100.setSS(sspin); } EthernetLinkStatus EthernetClass::linkStatus() { switch (W5100.getLinkStatus()) { case UNKNOWN: return Unknown; case LINK_ON: return LinkON; case LINK_OFF: return LinkOFF; default: return Unknown; } } EthernetHardwareStatus EthernetClass::hardwareStatus() { switch (W5100.getChip()) { case 51: return EthernetW5100; case 52: return EthernetW5200; case 55: return EthernetW5500; default: return EthernetNoHardware; } } int EthernetClass::maintain() { int rc = DHCP_CHECK_NONE; if (_dhcp != NULL) { // we have a pointer to dhcp, use it rc = _dhcp->checkLease(); switch (rc) { case DHCP_CHECK_NONE: //nothing done break; case DHCP_CHECK_RENEW_OK: case DHCP_CHECK_REBIND_OK: //we might have got a new IP. SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); SPI.endTransaction(); _dnsServerAddress = _dhcp->getDnsServerIp(); break; default: //this is actually an error, it will retry though break; } } return rc; } void EthernetClass::MACAddress(uint8_t *mac_address) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.getMACAddress(mac_address); SPI.endTransaction(); } IPAddress EthernetClass::localIP() { IPAddress ret; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.getIPAddress(ret.raw_address()); SPI.endTransaction(); return ret; } IPAddress EthernetClass::subnetMask() { IPAddress ret; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.getSubnetMask(ret.raw_address()); SPI.endTransaction(); return ret; } IPAddress EthernetClass::gatewayIP() { IPAddress ret; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.getGatewayIp(ret.raw_address()); SPI.endTransaction(); return ret; } void EthernetClass::setMACAddress(const uint8_t *mac_address) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setMACAddress(mac_address); SPI.endTransaction(); } void EthernetClass::setLocalIP(const IPAddress local_ip) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); IPAddress ip = local_ip; W5100.setIPAddress(ip.raw_address()); SPI.endTransaction(); } void EthernetClass::setSubnetMask(const IPAddress subnet) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); IPAddress ip = subnet; W5100.setSubnetMask(ip.raw_address()); SPI.endTransaction(); } void EthernetClass::setGatewayIP(const IPAddress gateway) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); IPAddress ip = gateway; W5100.setGatewayIp(ip.raw_address()); SPI.endTransaction(); } void EthernetClass::setRetransmissionTimeout(uint16_t milliseconds) { if (milliseconds > 6553) milliseconds = 6553; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setRetransmissionTime(milliseconds * 10); SPI.endTransaction(); } void EthernetClass::setRetransmissionCount(uint8_t num) { SPI.beginTransaction(SPI_ETHERNET_SETTINGS); W5100.setRetransmissionCount(num); SPI.endTransaction(); } EthernetClass Ethernet;