diff --git a/libraries/WiFi/examples/ETH_LAN8720/ETH_LAN8720.ino b/libraries/WiFi/examples/ETH_LAN8720/ETH_LAN8720.ino new file mode 100644 index 00000000..af462b02 --- /dev/null +++ b/libraries/WiFi/examples/ETH_LAN8720/ETH_LAN8720.ino @@ -0,0 +1,81 @@ +/* + This sketch shows the Ethernet event usage + +*/ + +#include + +static bool eth_connected = false; + +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) +{ + Serial.print("\nconnecting to "); + Serial.println(host); + + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + Serial.write(client.read()); + } + + Serial.println("closing connection\n"); + client.stop(); +} + +void setup() +{ + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(); +} + + +void loop() +{ + if (eth_connected) { + testClient("google.com", 80); + } + delay(10000); +} diff --git a/libraries/WiFi/examples/ETH_TLK110/ETH_TLK110.ino b/libraries/WiFi/examples/ETH_TLK110/ETH_TLK110.ino new file mode 100644 index 00000000..093efb3e --- /dev/null +++ b/libraries/WiFi/examples/ETH_TLK110/ETH_TLK110.ino @@ -0,0 +1,87 @@ +/* + This sketch shows the Ethernet event usage + +*/ + +#include + +#define ETH_ADDR 31 +#define ETH_POWER_PIN 17 +#define ETH_MDC_PIN 23 +#define ETH_MDIO_PIN 18 +#define ETH_TYPE ETH_PHY_TLK110 + +static bool eth_connected = false; + +void WiFiEvent(WiFiEvent_t event) +{ + switch (event) { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + //set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +} + +void testClient(const char * host, uint16_t port) +{ + Serial.print("\nconnecting to "); + Serial.println(host); + + WiFiClient client; + if (!client.connect(host, port)) { + Serial.println("connection failed"); + return; + } + client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); + while (client.connected() && !client.available()); + while (client.available()) { + Serial.write(client.read()); + } + + Serial.println("closing connection\n"); + client.stop(); +} + +void setup() +{ + Serial.begin(115200); + WiFi.onEvent(WiFiEvent); + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE); +} + + +void loop() +{ + if (eth_connected) { + testClient("google.com", 80); + } + delay(10000); +} diff --git a/libraries/WiFi/src/ETH.cpp b/libraries/WiFi/src/ETH.cpp new file mode 100644 index 00000000..57bace89 --- /dev/null +++ b/libraries/WiFi/src/ETH.cpp @@ -0,0 +1,243 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. 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 + */ + +#include "ETH.h" +#include "eth_phy/phy.h" +#include "eth_phy/phy_tlk110.h" +#include "eth_phy/phy_lan8720.h" +#include "lwip/err.h" +#include "lwip/dns.h" + +extern void tcpipInit(); + +static int _eth_phy_mdc_pin = -1; +static int _eth_phy_mdio_pin = -1; +static int _eth_phy_power_pin = -1; +static eth_phy_power_enable_func _eth_phy_power_enable_orig = NULL; + +static void _eth_phy_config_gpio(void) +{ + if(_eth_phy_mdc_pin < 0 || _eth_phy_mdio_pin < 0){ + log_e("MDC and MDIO pins are not configured!"); + return; + } + phy_rmii_configure_data_interface_pins(); + phy_rmii_smi_configure_pins(_eth_phy_mdc_pin, _eth_phy_mdio_pin); +} + +static void _eth_phy_power_enable(bool enable) +{ + pinMode(_eth_phy_power_pin, OUTPUT); + digitalWrite(_eth_phy_power_pin, enable); + delay(1); +} + +ETHClass::ETHClass():initialized(false),started(false),staticIP(false) +{ +} + +ETHClass::~ETHClass() +{} + +bool ETHClass::begin(uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t type) +{ + esp_err_t err; + if(initialized){ + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + return false; + } + started = true; + return true; + } + _eth_phy_mdc_pin = mdc; + _eth_phy_mdio_pin = mdio; + _eth_phy_power_pin = power; + + if(type == ETH_PHY_LAN8720){ + eth_config_t config = phy_lan8720_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } else if(type == ETH_PHY_TLK110){ + eth_config_t config = phy_tlk110_default_ethernet_config; + memcpy(ð_config, &config, sizeof(eth_config_t)); + } else { + log_e("Bad ETH_PHY type: %u", (uint8_t)type); + return false; + } + + eth_config.phy_addr = (eth_phy_base_t)phy_addr; + eth_config.gpio_config = _eth_phy_config_gpio; + eth_config.tcpip_input = tcpip_adapter_eth_input; + if(_eth_phy_power_pin >= 0){ + _eth_phy_power_enable_orig = eth_config.phy_power_enable; + eth_config.phy_power_enable = _eth_phy_power_enable; + } + + tcpipInit(); + err = esp_eth_init(ð_config); + if(!err){ + initialized = true; + err = esp_eth_enable(); + if(err){ + log_e("esp_eth_enable error: %d", err); + } else { + started = true; + return true; + } + } else { + log_e("esp_eth_init error: %d", err); + } + return false; +} + +/* +bool ETHClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) +{ + if(!initialized){ + return false; + } + + tcpip_adapter_ip_info_t info; + info.ip.addr = static_cast(local_ip); + info.gw.addr = static_cast(gateway); + info.netmask.addr = static_cast(subnet); + + if(!staticIP){ + tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_ETH); + } + if(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_ETH, &info) == ESP_OK) { + staticIP = true; + } else { + return false; + } + ip_addr_t d; + + if(dns1 != (uint32_t)0x00000000) { + // Set DNS1-Server + d.u_addr.ip4.addr = static_cast(dns1); + dns_setserver(0, &d); + } + + if(dns2 != (uint32_t)0x00000000) { + // Set DNS2-Server + d.u_addr.ip4.addr = static_cast(dns2); + dns_setserver(1, &d); + } + + return true; +} +*/ + +IPAddress ETHClass::localIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.ip.addr); +} + +IPAddress ETHClass::subnetMask() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.netmask.addr); +} + +IPAddress ETHClass::gatewayIP() +{ + tcpip_adapter_ip_info_t ip; + if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){ + return IPAddress(); + } + return IPAddress(ip.gw.addr); +} + +IPAddress ETHClass::dnsIP(uint8_t dns_no) +{ + ip_addr_t dns_ip = dns_getserver(dns_no); + return IPAddress(dns_ip.u_addr.ip4.addr); +} + +const char * ETHClass::getHostname() +{ + const char * hostname; + if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_ETH, &hostname)){ + return NULL; + } + return hostname; +} + +bool ETHClass::setHostname(const char * hostname) +{ + return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_ETH, hostname) == 0; +} + +bool ETHClass::fullDuplex() +{ + return eth_config.phy_get_duplex_mode(); +} + +bool ETHClass::linkUp() +{ + return eth_config.phy_check_link(); +} + +uint8_t ETHClass::linkSpeed() +{ + return eth_config.phy_get_speed_mode()?100:10; +} + +bool ETHClass::enableIpV6() +{ + return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH) == 0; +} + +IPv6Address ETHClass::localIPv6() +{ + static ip6_addr_t addr; + if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_ETH, &addr)){ + return IPv6Address(); + } + return IPv6Address(addr.addr); +} + +uint8_t * macAddress(uint8_t* mac) +{ + if(!mac){ + return NULL; + } + esp_eth_get_mac(mac); + return mac; +} + +String ETHClass::macAddress(void) +{ + uint8_t mac[6]; + char macStr[18] = { 0 }; + esp_eth_get_mac(mac); + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return String(macStr); +} + +ETHClass ETH; diff --git a/libraries/WiFi/src/ETH.h b/libraries/WiFi/src/ETH.h new file mode 100644 index 00000000..95469f18 --- /dev/null +++ b/libraries/WiFi/src/ETH.h @@ -0,0 +1,88 @@ +/* + ETH.h - espre ETH PHY support. + Based on WiFi.h from Ardiono WiFi shield library. + Copyright (c) 2011-2014 Arduino. 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 _ETH_H_ +#define _ETH_H_ + +#include "WiFi.h" +#include "esp_eth.h" + +#ifndef ETH_PHY_ADDR +#define ETH_PHY_ADDR 0 +#endif + +#ifndef ETH_PHY_TYPE +#define ETH_PHY_TYPE ETH_PHY_LAN8720 +#endif + +#ifndef ETH_PHY_POWER +#define ETH_PHY_POWER -1 +#endif + +#ifndef ETH_PHY_MDC +#define ETH_PHY_MDC 23 +#endif + +#ifndef ETH_PHY_MDIO +#define ETH_PHY_MDIO 18 +#endif + +typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_MAX} eth_phy_type_t; + +class ETHClass { + private: + bool initialized; + bool started; + bool staticIP; + eth_config_t eth_config; + public: + ETHClass(); + ~ETHClass(); + + bool begin(uint8_t phy_addr=ETH_PHY_ADDR, int power=ETH_PHY_POWER, int mdc=ETH_PHY_MDC, int mdio=ETH_PHY_MDIO, eth_phy_type_t type=ETH_PHY_TYPE); + + // NOT WORKING YET! + //bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + + const char * getHostname(); + bool setHostname(const char * hostname); + + bool fullDuplex(); + bool linkUp(); + uint8_t linkSpeed(); + + bool enableIpV6(); + IPv6Address localIPv6(); + + IPAddress localIP(); + IPAddress subnetMask(); + IPAddress gatewayIP(); + IPAddress dnsIP(uint8_t dns_no = 0); + + uint8_t * macAddress(uint8_t* mac); + String macAddress(); + + friend class WiFiClient; + friend class WiFiServer; +}; + +extern ETHClass ETH; + +#endif /* _ETH_H_ */