[ETH] Implement SPI support, multiple interfaces and more (#8712)

This commit is contained in:
Me No Dev 2023-10-06 13:47:54 +03:00 committed by GitHub
parent 93a45019a8
commit e2487b128d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1172 additions and 529 deletions

View File

@ -3,11 +3,20 @@
*/
// Important to be defined BEFORE including ETH.h for ETH.begin() to work.
// Example RMII LAN8720 (Olimex, etc.)
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#define ETH_PHY_ADDR 0
#define ETH_PHY_MDC 23
#define ETH_PHY_MDIO 18
#define ETH_PHY_POWER -1
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
#include <ETH.h>
static bool eth_connected = false;
void WiFiEvent(WiFiEvent_t event)
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
{
switch (event) {
case ARDUINO_EVENT_ETH_START:
@ -19,18 +28,14 @@ void WiFiEvent(WiFiEvent_t event)
Serial.println("ETH Connected");
break;
case ARDUINO_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");
Serial.println("ETH Got IP");
ETH.printInfo(Serial);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
@ -67,7 +72,7 @@ void testClient(const char * host, uint16_t port)
void setup()
{
Serial.begin(115200);
WiFi.onEvent(WiFiEvent);
WiFi.onEvent(onEvent);
ETH.begin();
}

View File

@ -5,15 +5,16 @@
#include <ETH.h>
#define ETH_TYPE ETH_PHY_TLK110
#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
#define ETH_POWER_PIN 17
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
static bool eth_connected = false;
void WiFiEvent(WiFiEvent_t event)
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
{
switch (event) {
case ARDUINO_EVENT_ETH_START:
@ -25,18 +26,14 @@ void WiFiEvent(WiFiEvent_t event)
Serial.println("ETH Connected");
break;
case ARDUINO_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");
Serial.println("ETH Got IP");
ETH.printInfo(Serial);
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
@ -73,8 +70,8 @@ void testClient(const char * host, uint16_t port)
void setup()
{
Serial.begin(115200);
WiFi.onEvent(WiFiEvent);
ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE);
WiFi.onEvent(onEvent);
ETH.begin(ETH_TYPE, ETH_ADDR, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_POWER_PIN, ETH_CLK_MODE);
}

View File

@ -0,0 +1,110 @@
/*
This sketch shows the Ethernet event usage
*/
#include <ETH.h>
#include <SPI.h>
// Set this to 1 to enable dual Ethernet support
#define USE_TWO_ETH_PORTS 0
#define ETH_TYPE ETH_PHY_W5500
#define ETH_ADDR 1
#define ETH_CS 15
#define ETH_IRQ 4
#define ETH_RST 5
// SPI pins
#define ETH_SPI_SCK 14
#define ETH_SPI_MISO 12
#define ETH_SPI_MOSI 13
#if USE_TWO_ETH_PORTS
// Second port on shared SPI bus
#define ETH1_TYPE ETH_PHY_W5500
#define ETH1_ADDR 1
#define ETH1_CS 32
#define ETH1_IRQ 33
#define ETH1_RST 18
ETHClass ETH1(1);
#endif
static bool eth_connected = false;
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
{
switch (event) {
case ARDUINO_EVENT_ETH_START:
Serial.println("ETH Started");
//set eth hostname here
ETH.setHostname("esp32-eth0");
break;
case ARDUINO_EVENT_ETH_CONNECTED:
Serial.println("ETH Connected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif));
ETH.printInfo(Serial);
#if USE_TWO_ETH_PORTS
ETH1.printInfo(Serial);
#endif
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
break;
case ARDUINO_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(onEvent);
SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
ETH.begin(ETH_TYPE, ETH_ADDR, ETH_CS, ETH_IRQ, ETH_RST, SPI);
#if USE_TWO_ETH_PORTS
ETH1.begin(ETH1_TYPE, ETH1_ADDR, ETH1_CS, ETH1_IRQ, ETH1_RST, SPI);
#endif
}
void loop()
{
if (eth_connected) {
testClient("google.com", 80);
}
delay(10000);
}

View File

@ -0,0 +1,107 @@
/*
This sketch shows the Ethernet event usage
*/
#include <ETH.h>
// Set this to 1 to enable dual Ethernet support
#define USE_TWO_ETH_PORTS 0
#define ETH_TYPE ETH_PHY_W5500
#define ETH_ADDR 1
#define ETH_CS 15
#define ETH_IRQ 4
#define ETH_RST 5
#define ETH_SPI_HOST SPI2_HOST
#define ETH_SPI_SCK 14
#define ETH_SPI_MISO 12
#define ETH_SPI_MOSI 13
#if USE_TWO_ETH_PORTS
// Second port on shared SPI bus
#define ETH1_TYPE ETH_PHY_W5500
#define ETH1_ADDR 1
#define ETH1_CS 32
#define ETH1_IRQ 33
#define ETH1_RST 18
ETHClass ETH1(1);
#endif
static bool eth_connected = false;
void onEvent(arduino_event_id_t event, arduino_event_info_t info)
{
switch (event) {
case ARDUINO_EVENT_ETH_START:
Serial.println("ETH Started");
//set eth hostname here
ETH.setHostname("esp32-eth0");
break;
case ARDUINO_EVENT_ETH_CONNECTED:
Serial.println("ETH Connected");
break;
case ARDUINO_EVENT_ETH_GOT_IP:
Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif));
ETH.printInfo(Serial);
#if USE_TWO_ETH_PORTS
ETH1.printInfo(Serial);
#endif
eth_connected = true;
break;
case ARDUINO_EVENT_ETH_LOST_IP:
Serial.println("ETH Lost IP");
eth_connected = false;
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
Serial.println("ETH Disconnected");
eth_connected = false;
break;
case ARDUINO_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(onEvent);
ETH.begin(ETH_TYPE, ETH_ADDR, ETH_CS, ETH_IRQ, ETH_RST, ETH_SPI_HOST, ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
#if USE_TWO_ETH_PORTS
// Since SPI bus is shared, we should skip the SPI pins when calling ETH1.begin()
ETH1.begin(ETH1_TYPE, ETH1_ADDR, ETH1_CS, ETH1_IRQ, ETH1_RST, ETH_SPI_HOST);
#endif
}
void loop()
{
if (eth_connected) {
testClient("google.com", 80);
}
delay(10000);
}

File diff suppressed because it is too large Load Diff

View File

@ -21,11 +21,59 @@
#ifndef _ETH_H_
#define _ETH_H_
//
// Example configurations for pins_arduino.h to allow starting with ETH.begin();
//
// // Example RMII LAN8720 (Olimex, etc.)
// #define ETH_PHY_TYPE ETH_PHY_LAN8720
// #define ETH_PHY_ADDR 0
// #define ETH_PHY_MDC 23
// #define ETH_PHY_MDIO 18
// #define ETH_PHY_POWER -1
// #define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
// // Example RMII ESP32_Ethernet_V4
// #define ETH_PHY_TYPE ETH_PHY_TLK110
// #define ETH_PHY_ADDR 1
// #define ETH_PHY_MDC 23
// #define ETH_PHY_MDIO 18
// #define ETH_PHY_POWER -1
// #define ETH_CLK_MODE ETH_CLOCK_GPIO0_OUT
// // Example SPI using ESP-IDF's driver
// #define ETH_PHY_TYPE ETH_PHY_W5500
// #define ETH_PHY_ADDR 1
// #define ETH_PHY_CS 15
// #define ETH_PHY_IRQ 4
// #define ETH_PHY_RST 5
// #define ETH_PHY_SPI_HOST SPI2_HOST
// #define ETH_PHY_SPI_SCK 14
// #define ETH_PHY_SPI_MISO 12
// #define ETH_PHY_SPI_MOSI 13
// // Example SPI using Arduino's driver
// #define ETH_PHY_TYPE ETH_PHY_W5500
// #define ETH_PHY_ADDR 1
// #define ETH_PHY_CS 15
// #define ETH_PHY_IRQ 4
// #define ETH_PHY_RST 5
// #define ETH_PHY_SPI SPI
// This will be uncommented once custom SPI support is available in ESP-IDF
#define ETH_SPI_SUPPORTS_CUSTOM 1
#include "WiFi.h"
#if ETH_SPI_SUPPORTS_CUSTOM
#include "SPI.h"
#endif
#include "esp_system.h"
#include "esp_eth.h"
#include "esp_netif.h"
#if CONFIG_ETH_USE_ESP32_EMAC
#define ETH_PHY_IP101 ETH_PHY_TLK110
typedef enum { ETH_CLOCK_GPIO0_IN, ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT } eth_clock_mode_t;
//Dedicated GPIOs for RMII
#define ETH_RMII_TX_EN 21
#define ETH_RMII_TX0 19
@ -33,94 +81,137 @@
#define ETH_RMII_RX0 25
#define ETH_RMII_RX1_EN 26
#define ETH_RMII_CRS_DV 27
#endif /* CONFIG_ETH_USE_ESP32_EMAC */
#ifndef ETH_PHY_ADDR
#define ETH_PHY_ADDR 0
#ifndef ETH_PHY_SPI_FREQ_MHZ
#define ETH_PHY_SPI_FREQ_MHZ 20
#endif /* ETH_PHY_SPI_FREQ_MHZ */
typedef enum {
#if CONFIG_ETH_USE_ESP32_EMAC
ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_RTL8201, ETH_PHY_DP83848, ETH_PHY_KSZ8041, ETH_PHY_KSZ8081,
#endif /* CONFIG_ETH_USE_ESP32_EMAC */
#if CONFIG_ETH_SPI_ETHERNET_DM9051
ETH_PHY_DM9051,
#endif
#ifndef ETH_PHY_TYPE
#define ETH_PHY_TYPE ETH_PHY_LAN8720
#if CONFIG_ETH_SPI_ETHERNET_W5500
ETH_PHY_W5500,
#endif
#ifndef ETH_PHY_POWER
#define ETH_PHY_POWER -1
#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL
ETH_PHY_KSZ8851,
#endif
#ifndef ETH_PHY_MDC
#define ETH_PHY_MDC 23
#endif
#ifndef ETH_PHY_MDIO
#define ETH_PHY_MDIO 18
#endif
#ifndef ETH_CLK_MODE
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN
#endif
#if ESP_IDF_VERSION_MAJOR > 3
typedef enum { ETH_CLOCK_GPIO0_IN, ETH_CLOCK_GPIO0_OUT, ETH_CLOCK_GPIO16_OUT, ETH_CLOCK_GPIO17_OUT } eth_clock_mode_t;
#endif
typedef enum { ETH_PHY_LAN8720, ETH_PHY_TLK110, ETH_PHY_RTL8201, ETH_PHY_DP83848, ETH_PHY_DM9051, ETH_PHY_KSZ8041, ETH_PHY_KSZ8081, ETH_PHY_MAX } eth_phy_type_t;
#define ETH_PHY_IP101 ETH_PHY_TLK110
ETH_PHY_MAX
} eth_phy_type_t;
class ETHClass {
private:
bool initialized;
bool staticIP;
#if ESP_IDF_VERSION_MAJOR > 3
esp_eth_handle_t eth_handle;
esp_netif_t *esp_netif;
protected:
bool _started;
int8_t _pin_mcd = -1;
int8_t _pin_mdio = -1;
int8_t _pin_power = -1;
int8_t _pin_rmii_clock = -1;
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
#else
bool _started;
eth_config_t eth_config;
#endif
public:
ETHClass();
ETHClass(uint8_t eth_index=0);
~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, eth_clock_mode_t clk_mode=ETH_CLK_MODE, bool use_mac_from_efuse=false);
#if CONFIG_ETH_USE_ESP32_EMAC
bool begin(eth_phy_type_t type, uint8_t phy_addr, int mdc, int mdio, int power, eth_clock_mode_t clk_mode);
#endif /* CONFIG_ETH_USE_ESP32_EMAC */
#if ETH_SPI_SUPPORTS_CUSTOM
bool begin(eth_phy_type_t type, uint8_t phy_addr, int cs, int irq, int rst, SPIClass &spi, uint8_t spi_freq_mhz=ETH_PHY_SPI_FREQ_MHZ);
#endif
bool begin(eth_phy_type_t type, uint8_t phy_addr, int cs, int irq, int rst, spi_host_device_t spi_host, int sck=-1, int miso=-1, int mosi=-1, uint8_t spi_freq_mhz=ETH_PHY_SPI_FREQ_MHZ);
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
bool begin(){
#if defined(ETH_PHY_TYPE) && defined(ETH_PHY_ADDR)
#if defined(CONFIG_ETH_USE_ESP32_EMAC) && defined(ETH_PHY_POWER) && defined(ETH_PHY_MDC) && defined(ETH_PHY_MDIO) && defined(ETH_CLK_MODE)
return begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_POWER, ETH_CLK_MODE);
#elif defined(ETH_PHY_CS) && defined(ETH_PHY_IRQ) && defined(ETH_PHY_RST)
#if ETH_SPI_SUPPORTS_CUSTOM && defined(ETH_PHY_SPI)
return begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, ETH_PHY_SPI, ETH_PHY_SPI_FREQ_MHZ);
#elif defined(ETH_PHY_SPI_HOST) && defined(ETH_PHY_SPI_SCK) && defined(ETH_PHY_SPI_MISO) && defined(ETH_PHY_SPI_MOSI)
return begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, ETH_PHY_SPI_HOST, ETH_PHY_SPI_SCK, ETH_PHY_SPI_MISO, ETH_PHY_SPI_MOSI, ETH_PHY_SPI_FREQ_MHZ);
#endif
#endif
#endif
return false;
}
void end();
// Netif APIs
esp_netif_t * netif(void){ return _esp_netif; }
bool config(IPAddress local_ip = (uint32_t)0x00000000, IPAddress gateway = (uint32_t)0x00000000, IPAddress subnet = (uint32_t)0x00000000, 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);
IPAddress broadcastIP();
IPAddress networkID();
uint8_t subnetCIDR();
bool enableIpV6();
IPv6Address localIPv6();
const char * ifkey(void);
const char * desc(void);
String impl_name(void);
// Event based getters
bool connected();
bool hasIP();
// ETH Handle APIs
uint8_t * macAddress(uint8_t* mac);
String macAddress();
bool fullDuplex();
bool linkUp();
uint8_t linkSpeed();
bool autoNegotiation();
uint32_t phyAddr();
void end();
// Info APIs
void printInfo(Print & out);
friend class WiFiClient;
friend class WiFiServer;
#if ETH_SPI_SUPPORTS_CUSTOM
static esp_err_t _eth_spi_read(void *ctx, uint32_t cmd, uint32_t addr, void *data, uint32_t data_len);
static esp_err_t _eth_spi_write(void *ctx, uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len);
#endif
protected:
#if ETH_SPI_SUPPORTS_CUSTOM
esp_err_t eth_spi_read(uint32_t cmd, uint32_t addr, void *data, uint32_t data_len);
esp_err_t eth_spi_write(uint32_t cmd, uint32_t addr, const void *data, uint32_t data_len);
#endif
static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
private:
bool _eth_started;
esp_eth_handle_t _eth_handle;
esp_netif_t *_esp_netif;
uint8_t _eth_index;
eth_phy_type_t _phy_type;
#if ETH_SPI_SUPPORTS_CUSTOM
SPIClass * _spi;
#endif
uint8_t _spi_freq_mhz;
int8_t _pin_cs;
int8_t _pin_irq;
int8_t _pin_rst;
int8_t _pin_sck;
int8_t _pin_miso;
int8_t _pin_mosi;
#if CONFIG_ETH_USE_ESP32_EMAC
int8_t _pin_mcd;
int8_t _pin_mdio;
int8_t _pin_power;
int8_t _pin_rmii_clock;
#endif /* CONFIG_ETH_USE_ESP32_EMAC */
static bool ethDetachBus(void * bus_pointer);
bool beginSPI(eth_phy_type_t type, uint8_t phy_addr, int cs, int irq, int rst,
#if ETH_SPI_SUPPORTS_CUSTOM
SPIClass * spi,
#endif
int sck, int miso, int mosi, spi_host_device_t spi_host, uint8_t spi_freq_mhz);
};
extern ETHClass ETH;

View File

@ -444,10 +444,13 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev
} else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
log_v("Ethernet got %sip:" IPSTR, event->ip_changed?"new":"", IP2STR(&event->ip_info.ip));
log_v("Ethernet got %sip:" IPSTR, event->ip_changed?"new ":"", IP2STR(&event->ip_info.ip));
#endif
arduino_event.event_id = ARDUINO_EVENT_ETH_GOT_IP;
memcpy(&arduino_event.event_info.got_ip, event_data, sizeof(ip_event_got_ip_t));
} else if (event_base == ETH_EVENT && event_id == IP_EVENT_ETH_LOST_IP) {
log_v("Ethernet Lost IP");
arduino_event.event_id = ARDUINO_EVENT_ETH_LOST_IP;
/*
* IPv6
@ -870,6 +873,7 @@ const char * WiFiGenericClass::eventName(arduino_event_id_t id) {
case ARDUINO_EVENT_ETH_CONNECTED: return "ETH_CONNECTED";
case ARDUINO_EVENT_ETH_DISCONNECTED: return "ETH_DISCONNECTED";
case ARDUINO_EVENT_ETH_GOT_IP: return "ETH_GOT_IP";
case ARDUINO_EVENT_ETH_LOST_IP: return "ETH_LOST_IP";
case ARDUINO_EVENT_ETH_GOT_IP6: return "ETH_GOT_IP6";
case ARDUINO_EVENT_WPS_ER_SUCCESS: return "WPS_ER_SUCCESS";
case ARDUINO_EVENT_WPS_ER_FAILED: return "WPS_ER_FAILED";
@ -1137,6 +1141,8 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event)
gw[0], gw[1], gw[2], gw[3]);
#endif
setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT);
} else if(event->event_id == ARDUINO_EVENT_ETH_LOST_IP) {
clearStatusBits(ETH_HAS_IP_BIT);
} else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP6) {
setStatusBits(STA_CONNECTED_BIT | STA_HAS_IP6_BIT);

View File

@ -59,6 +59,7 @@ typedef enum {
ARDUINO_EVENT_ETH_CONNECTED,
ARDUINO_EVENT_ETH_DISCONNECTED,
ARDUINO_EVENT_ETH_GOT_IP,
ARDUINO_EVENT_ETH_LOST_IP,
ARDUINO_EVENT_ETH_GOT_IP6,
ARDUINO_EVENT_WPS_ER_SUCCESS,
ARDUINO_EVENT_WPS_ER_FAILED,