2020-06-15 17:27:04 +01:00
|
|
|
/*
|
2021-01-27 09:38:45 +00:00
|
|
|
xdrv_82_esp32_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota
|
2020-06-15 17:27:04 +01:00
|
|
|
|
2021-01-01 12:44:04 +00:00
|
|
|
Copyright (C) 2021 Theo Arends
|
2020-06-15 17:27:04 +01:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef ESP32
|
2024-02-14 15:19:51 +00:00
|
|
|
//#if CONFIG_IDF_TARGET_ESP32
|
2020-06-15 17:27:04 +01:00
|
|
|
#ifdef USE_ETHERNET
|
|
|
|
/*********************************************************************************************\
|
|
|
|
* Ethernet support for ESP32
|
2020-06-16 17:36:49 +01:00
|
|
|
*
|
2024-02-14 15:19:51 +00:00
|
|
|
* Dedicated fixed Phy pins (EMAC)
|
2020-06-16 17:36:49 +01:00
|
|
|
* GPIO17 - EMAC_CLK_OUT_180
|
|
|
|
* GPIO19 - EMAC_TXD0(RMII)
|
|
|
|
* GPIO21 - EMAC_TX_EN(RMII)
|
|
|
|
* GPIO22 - EMAC_TXD1(RMII)
|
|
|
|
* GPIO25 - EMAC_RXD0(RMII)
|
|
|
|
* GPIO26 - EMAC_RXD1(RMII)
|
|
|
|
* GPIO27 - EMAC_RX_CRS_DV
|
|
|
|
*
|
2020-06-18 11:55:10 +01:00
|
|
|
* {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
2020-10-23 14:18:58 +01:00
|
|
|
* GPIO12 = ETH POWER
|
|
|
|
* GPIO18 = ETH MDIO
|
|
|
|
* GPIO23 = ETH MDC
|
|
|
|
* #define ETH_TYPE ETH_PHY_LAN8720
|
|
|
|
* #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT
|
2021-02-02 17:02:24 +00:00
|
|
|
* #define ETH_ADDRESS 0
|
2020-10-23 14:18:58 +01:00
|
|
|
*
|
2020-06-20 11:00:40 +01:00
|
|
|
* {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1}
|
2020-10-23 14:18:58 +01:00
|
|
|
* GPIO16 = ETH MDC
|
|
|
|
* GPIO17 = ETH MDIO
|
|
|
|
* #define ETH_TYPE ETH_PHY_LAN8720
|
|
|
|
* #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN
|
2021-02-02 17:02:24 +00:00
|
|
|
* #define ETH_ADDRESS 0
|
2020-10-23 14:18:58 +01:00
|
|
|
*
|
|
|
|
* {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1}
|
|
|
|
* GPIO16 = Force Hi
|
|
|
|
* GPIO18 = ETH MDIO
|
|
|
|
* GPIO23 = ETH MDC
|
|
|
|
* #define ETH_TYPE ETH_PHY_LAN8720
|
|
|
|
* #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN
|
2021-02-02 17:02:24 +00:00
|
|
|
* #define ETH_ADDRESS 1
|
2020-10-23 14:18:58 +01:00
|
|
|
*
|
2024-02-14 15:19:51 +00:00
|
|
|
* Used SPI
|
|
|
|
* SPI_MOSI
|
|
|
|
* SPI_MISO
|
|
|
|
* SPI_CLK
|
|
|
|
* SPI_RST = Tasmota ETH_POWER
|
|
|
|
* SPI_IRQ = Tasmota ETH_MDIO
|
|
|
|
* SPI_CS = Tasmota ETH_MDC
|
2020-06-15 17:27:04 +01:00
|
|
|
\*********************************************************************************************/
|
|
|
|
|
|
|
|
#define XDRV_82 82
|
|
|
|
|
2020-06-16 17:36:49 +01:00
|
|
|
/*
|
2020-06-15 17:27:04 +01:00
|
|
|
// Olimex ESP32-PoE
|
2020-06-16 17:36:49 +01:00
|
|
|
#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT
|
|
|
|
#define ETH_POWER_PIN 12
|
|
|
|
|
|
|
|
//********************************************************************************************
|
|
|
|
|
2021-02-02 17:02:24 +00:00
|
|
|
#ifndef ETH_ADDRESS
|
2021-07-04 13:53:58 +01:00
|
|
|
#define ETH_ADDRESS 0 // ETH.h uint8_t: 0 = PHY0 .. 31 = PHY31
|
2020-06-16 17:36:49 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef ETH_TYPE
|
2024-02-08 15:45:28 +00:00
|
|
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
|
|
|
#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110/ETH_PHY_IP101, 2 = ETH_PHY_RTL8201, 3 = ETH_PHY_JL1101, 4 = ETH_PHY_DP83848, 5 = ETH_PHY_KSZ8041, 6 = ETH_PHY_KSZ8081, 7 = ETH_PHY_DM9051, 8 = ETH_PHY_W5500, 9 = ETH_PHY_KSZ8851
|
|
|
|
#else
|
|
|
|
#define ETH_TYPE ETH_PHY_LAN8720 // ETH.h eth_phy_type_t: 0 = ETH_PHY_LAN8720, 1 = ETH_PHY_TLK110/ETH_PHY_IP101, 2 = ETH_PHY_RTL8201, 3 = ETH_PHY_DP83848, 4 = ETH_PHY_DM9051, 5 = ETH_PHY_KSZ8041, 6 = ETH_PHY_KSZ8081, 7 = ETH_PHY_JL1101
|
|
|
|
#endif
|
2020-06-16 17:36:49 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef ETH_CLKMODE
|
2021-07-04 13:53:58 +01:00
|
|
|
#define ETH_CLKMODE ETH_CLOCK_GPIO0_IN // ETH.h eth_clock_mode_t: 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT
|
2020-06-16 17:36:49 +01:00
|
|
|
#endif
|
|
|
|
*/
|
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
#include <ETH.h>
|
|
|
|
|
2020-10-30 11:29:48 +00:00
|
|
|
char eth_hostname[sizeof(TasmotaGlobal.hostname)];
|
2022-01-12 16:32:21 +00:00
|
|
|
uint8_t eth_config_change;
|
2020-06-15 17:27:04 +01:00
|
|
|
|
2024-01-15 20:05:40 +00:00
|
|
|
extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
|
|
|
|
|
2022-12-08 18:42:04 +00:00
|
|
|
void EthernetEvent(arduino_event_t *event);
|
2022-12-08 18:06:51 +00:00
|
|
|
void EthernetEvent(arduino_event_t *event) {
|
|
|
|
switch (event->event_id) {
|
2021-11-21 12:30:05 +00:00
|
|
|
case ARDUINO_EVENT_ETH_START:
|
2022-12-08 18:06:51 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH D_ATTEMPTING_CONNECTION));
|
2020-06-18 16:47:29 +01:00
|
|
|
ETH.setHostname(eth_hostname);
|
2020-06-15 17:27:04 +01:00
|
|
|
break;
|
2022-12-08 18:06:51 +00:00
|
|
|
|
2021-11-21 12:30:05 +00:00
|
|
|
case ARDUINO_EVENT_ETH_CONNECTED:
|
2022-12-10 12:44:16 +00:00
|
|
|
#ifdef USE_IPV6
|
2024-01-15 20:05:40 +00:00
|
|
|
ETH.enableIPv6(); // enable Link-Local
|
|
|
|
// workaround for the race condition in LWIP, see https://github.com/espressif/arduino-esp32/pull/9016#discussion_r1451774885
|
|
|
|
{
|
|
|
|
uint32_t i = 5; // try 5 times only
|
|
|
|
while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)) != ESP_OK) {
|
|
|
|
delay(1);
|
|
|
|
if (i-- == 0) {
|
2024-02-08 15:45:28 +00:00
|
|
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH ">>>> HELP"));
|
2024-01-15 20:05:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-02-08 15:45:28 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "ESP_IF_ETH i=%i"), i);
|
2024-01-15 20:05:40 +00:00
|
|
|
}
|
2022-12-10 12:44:16 +00:00
|
|
|
#endif // USE_IPV6
|
2024-01-15 20:05:40 +00:00
|
|
|
|
2022-12-08 18:06:51 +00:00
|
|
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"),
|
|
|
|
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "",
|
|
|
|
ETH.macAddress().c_str(), eth_hostname
|
|
|
|
);
|
|
|
|
|
2024-01-15 20:05:40 +00:00
|
|
|
// AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIPV6() -> %i", ETH.enableIPV6());
|
2020-06-15 17:27:04 +01:00
|
|
|
break;
|
2022-12-08 18:06:51 +00:00
|
|
|
|
2021-11-21 12:30:05 +00:00
|
|
|
case ARDUINO_EVENT_ETH_GOT_IP:
|
2022-12-08 18:06:51 +00:00
|
|
|
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Mac %s, IPAddress %_I, Hostname %s"),
|
|
|
|
// ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname);
|
2022-01-12 16:32:21 +00:00
|
|
|
Settings->eth_ipv4_address[1] = (uint32_t)ETH.gatewayIP();
|
|
|
|
Settings->eth_ipv4_address[2] = (uint32_t)ETH.subnetMask();
|
2022-02-01 21:15:27 +00:00
|
|
|
if (0 == Settings->eth_ipv4_address[0]) { // At this point ETH.dnsIP() are NOT correct unless DHCP
|
|
|
|
Settings->eth_ipv4_address[3] = (uint32_t)ETH.dnsIP();
|
|
|
|
Settings->eth_ipv4_address[4] = (uint32_t)ETH.dnsIP(1);
|
|
|
|
}
|
2022-01-12 16:32:21 +00:00
|
|
|
TasmotaGlobal.rules_flag.eth_connected = 1;
|
2020-10-30 11:29:48 +00:00
|
|
|
TasmotaGlobal.global_state.eth_down = 0;
|
2022-12-27 20:59:34 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: IPv4 %_I, mask %_I, gateway %_I"),
|
|
|
|
event->event_info.got_ip.ip_info.ip.addr,
|
|
|
|
event->event_info.got_ip.ip_info.netmask.addr,
|
|
|
|
event->event_info.got_ip.ip_info.gw.addr);
|
|
|
|
WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use
|
2020-06-15 17:27:04 +01:00
|
|
|
break;
|
2022-12-08 18:06:51 +00:00
|
|
|
|
2022-12-27 20:59:34 +00:00
|
|
|
#ifdef USE_IPV6
|
|
|
|
case ARDUINO_EVENT_ETH_GOT_IP6:
|
|
|
|
{
|
|
|
|
ip_addr_t ip_addr6;
|
|
|
|
ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip);
|
2024-01-15 20:05:40 +00:00
|
|
|
IPAddress addr(&ip_addr6);
|
2022-12-27 20:59:34 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"),
|
|
|
|
event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF",
|
2024-01-15 20:05:40 +00:00
|
|
|
IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str());
|
|
|
|
if (!IPv6isLocal(addr)) { // declare network up on IPv6
|
2022-12-27 20:59:34 +00:00
|
|
|
TasmotaGlobal.rules_flag.eth_connected = 1;
|
|
|
|
TasmotaGlobal.global_state.eth_down = 0;
|
|
|
|
}
|
|
|
|
WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif // USE_IPV6
|
|
|
|
|
2021-11-21 12:30:05 +00:00
|
|
|
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
2022-12-08 18:06:51 +00:00
|
|
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH "Disconnected"));
|
2022-01-12 16:32:21 +00:00
|
|
|
TasmotaGlobal.rules_flag.eth_disconnected = 1;
|
2020-10-30 11:29:48 +00:00
|
|
|
TasmotaGlobal.global_state.eth_down = 1;
|
2020-06-15 17:27:04 +01:00
|
|
|
break;
|
2022-12-08 18:06:51 +00:00
|
|
|
|
2021-11-21 12:30:05 +00:00
|
|
|
case ARDUINO_EVENT_ETH_STOP:
|
2022-12-08 18:06:51 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Stopped"));
|
2020-10-30 11:29:48 +00:00
|
|
|
TasmotaGlobal.global_state.eth_down = 1;
|
2020-06-15 17:27:04 +01:00
|
|
|
break;
|
2022-12-08 18:06:51 +00:00
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void EthernetSetIp(void) {
|
2022-02-24 15:28:45 +00:00
|
|
|
// Set static IP
|
|
|
|
ETH.config(Settings->eth_ipv4_address[0], // IPAddress local_ip
|
|
|
|
Settings->eth_ipv4_address[1], // IPAddress gateway
|
|
|
|
Settings->eth_ipv4_address[2], // IPAddress subnet
|
|
|
|
Settings->eth_ipv4_address[3], // IPAddress dns1
|
|
|
|
Settings->eth_ipv4_address[4]); // IPAddress dns2
|
2022-01-12 16:32:21 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
void EthernetInit(void) {
|
2021-06-11 17:14:12 +01:00
|
|
|
if (!Settings->flag4.network_ethernet) { return; }
|
2022-01-12 16:32:21 +00:00
|
|
|
|
2024-02-14 15:19:51 +00:00
|
|
|
int eth_type = Settings->eth_type;
|
|
|
|
#if CONFIG_ETH_USE_ESP32_EMAC
|
2021-01-27 13:27:05 +00:00
|
|
|
if (WT32_ETH01 == TasmotaGlobal.module_type) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->eth_address = 1; // EthAddress
|
|
|
|
Settings->eth_type = ETH_PHY_LAN8720; // EthType
|
|
|
|
Settings->eth_clk_mode = ETH_CLOCK_GPIO0_IN; // EthClockMode
|
2021-01-27 13:27:05 +00:00
|
|
|
}
|
2024-02-14 15:19:51 +00:00
|
|
|
#else // No CONFIG_ETH_USE_ESP32_EMAC
|
|
|
|
if (Settings->eth_type < 7) {
|
|
|
|
Settings->eth_type = 8; // Select W5500 (SPI) for non-EMAC hardware
|
|
|
|
}
|
|
|
|
eth_type = Settings->eth_type -7; // As No EMAC support substract EMAC enums (According ETH.cpp debug info)
|
|
|
|
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
2021-01-27 13:27:05 +00:00
|
|
|
|
2024-02-14 16:01:31 +00:00
|
|
|
if (Settings->eth_type < 7) {
|
|
|
|
// CONFIG_ETH_USE_ESP32_EMAC
|
|
|
|
if (!PinUsed(GPIO_ETH_PHY_MDC) && !PinUsed(GPIO_ETH_PHY_MDIO)) { // && should be || but keep for backward compatibility
|
2024-02-08 15:45:28 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "No ETH MDC and ETH MDIO GPIO defined"));
|
2024-02-14 16:01:31 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// ETH_SPI_SUPPORTS_CUSTOM
|
|
|
|
if (!PinUsed(GPIO_ETH_PHY_MDC) || !PinUsed(GPIO_ETH_PHY_MDIO) || !PinUsed(GPIO_ETH_PHY_POWER)) {
|
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "No ETH MDC (SPI CS), ETH MDIO (SPI IRQ) and ETH POWER (SPI RST) GPIO defined"));
|
|
|
|
return;
|
2024-02-08 15:45:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
eth_config_change = 0;
|
|
|
|
|
2021-11-21 12:30:05 +00:00
|
|
|
strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "-eth"
|
|
|
|
strcat(eth_hostname, "-eth");
|
2020-06-18 16:47:29 +01:00
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
WiFi.onEvent(EthernetEvent);
|
2020-06-16 17:36:49 +01:00
|
|
|
|
2024-02-08 15:45:28 +00:00
|
|
|
int eth_mdc = Pin(GPIO_ETH_PHY_MDC); // Ethernet SPI CS (chip select)
|
|
|
|
int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); // Ethernet SPI IRQ
|
|
|
|
int eth_power = Pin(GPIO_ETH_PHY_POWER); // Ethernet SPI RST
|
|
|
|
|
|
|
|
bool init_ok = false;
|
2023-08-30 13:17:21 +01:00
|
|
|
#if ESP_IDF_VERSION_MAJOR >= 5
|
2024-02-08 15:45:28 +00:00
|
|
|
if (Settings->eth_type < 7) {
|
2024-02-14 15:19:51 +00:00
|
|
|
#if CONFIG_ETH_USE_ESP32_EMAC
|
|
|
|
init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, (eth_clock_mode_t)Settings->eth_clk_mode));
|
|
|
|
#endif // CONFIG_ETH_USE_ESP32_EMAC
|
2024-02-08 15:45:28 +00:00
|
|
|
} else {
|
2024-02-14 15:19:51 +00:00
|
|
|
// ETH_SPI_SUPPORTS_CUSTOM
|
|
|
|
// SPISettings(ETH_PHY_SPI_FREQ_MHZ * 1000 * 1000, MSBFIRST, SPI_MODE0); // 20MHz
|
|
|
|
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
|
|
|
|
init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI, ETH_PHY_SPI_FREQ_MHZ));
|
2024-02-08 15:45:28 +00:00
|
|
|
}
|
2023-08-30 13:17:21 +01:00
|
|
|
#else
|
2024-02-08 15:45:28 +00:00
|
|
|
init_ok = (ETH.begin(Settings->eth_address, eth_power, eth_mdc, eth_mdio, (eth_phy_type_t)Settings->eth_type, (eth_clock_mode_t)Settings->eth_clk_mode));
|
2024-02-14 15:19:51 +00:00
|
|
|
#endif // ESP_IDF_VERSION_MAJOR >= 5
|
2024-02-08 15:45:28 +00:00
|
|
|
if (!init_ok) {
|
2024-02-14 16:01:31 +00:00
|
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Bad EthType or init error"));
|
2022-01-12 16:32:21 +00:00
|
|
|
return;
|
2020-06-16 17:36:49 +01:00
|
|
|
};
|
2022-01-12 16:32:21 +00:00
|
|
|
|
|
|
|
if (Settings->eth_ipv4_address[0]) {
|
|
|
|
EthernetSetIp(); // Set static IP
|
|
|
|
}
|
2020-06-15 17:27:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
IPAddress EthernetLocalIP(void) {
|
|
|
|
return ETH.localIP();
|
|
|
|
}
|
|
|
|
|
2022-12-27 20:59:34 +00:00
|
|
|
// Check to see if we have any routable IP address
|
|
|
|
// IPv4 has always priority
|
|
|
|
// Copy the value of the IP if pointer provided (optional)
|
|
|
|
bool EthernetGetIP(IPAddress *ip) {
|
|
|
|
#ifdef USE_IPV6
|
|
|
|
if ((uint32_t)ETH.localIP() != 0) {
|
|
|
|
if (ip != nullptr) { *ip = ETH.localIP(); }
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
IPAddress lip;
|
|
|
|
if (EthernetGetIPv6(&lip)) {
|
|
|
|
if (ip != nullptr) { *ip = lip; }
|
|
|
|
return true;
|
|
|
|
}
|
2023-01-03 08:33:31 +00:00
|
|
|
if (ip != nullptr) { *ip = IPAddress(); }
|
2022-12-27 20:59:34 +00:00
|
|
|
return false;
|
|
|
|
#else
|
|
|
|
// IPv4 only
|
|
|
|
if (ip != nullptr) { *ip = ETH.localIP(); }
|
|
|
|
return (uint32_t)ETH.localIP() != 0;
|
|
|
|
#endif // USE_IPV6
|
|
|
|
}
|
|
|
|
bool EthernetHasIP(void) {
|
|
|
|
return EthernetGetIP(nullptr);
|
|
|
|
}
|
|
|
|
String EthernetGetIPStr(void) {
|
|
|
|
IPAddress ip;
|
|
|
|
if (EthernetGetIP(&ip)) {
|
|
|
|
return ip.toString();
|
|
|
|
} else {
|
|
|
|
return String();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
char* EthernetHostname(void) {
|
2020-06-18 16:47:29 +01:00
|
|
|
return eth_hostname;
|
2020-06-15 17:27:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
String EthernetMacAddress(void) {
|
|
|
|
return ETH.macAddress();
|
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void EthernetConfigChange(void) {
|
|
|
|
if (eth_config_change) {
|
|
|
|
eth_config_change--;
|
|
|
|
if (!eth_config_change) {
|
|
|
|
EthernetSetIp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
/*********************************************************************************************\
|
|
|
|
* Commands
|
|
|
|
\*********************************************************************************************/
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
#define D_CMND_ETHADDRESS "Address"
|
|
|
|
#define D_CMND_ETHTYPE "Type"
|
|
|
|
#define D_CMND_ETHCLOCKMODE "ClockMode"
|
|
|
|
#define D_CMND_ETHIPADDRESS D_CMND_IPADDRESS
|
|
|
|
#define D_CMND_ETHGATEWAY D_JSON_GATEWAY
|
|
|
|
#define D_CMND_ETHNETMASK D_JSON_SUBNETMASK
|
|
|
|
#define D_CMND_ETHDNS D_JSON_DNSSERVER
|
2020-06-16 17:36:49 +01:00
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
const char kEthernetCommands[] PROGMEM = "Eth|" // Prefix
|
|
|
|
"ernet|" D_CMND_ETHADDRESS "|" D_CMND_ETHTYPE "|" D_CMND_ETHCLOCKMODE "|"
|
2022-01-13 14:27:24 +00:00
|
|
|
D_CMND_ETHIPADDRESS "|" D_CMND_ETHGATEWAY "|" D_CMND_ETHNETMASK "|" D_CMND_ETHDNS ;
|
2020-06-15 17:27:04 +01:00
|
|
|
|
|
|
|
void (* const EthernetCommand[])(void) PROGMEM = {
|
2022-01-12 16:32:21 +00:00
|
|
|
&CmndEthernet, &CmndEthAddress, &CmndEthType, &CmndEthClockMode,
|
2022-01-13 14:27:24 +00:00
|
|
|
&CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig };
|
2020-06-15 17:27:04 +01:00
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
#define ETH_PARAM_OFFSET 4 // Offset of command index in above table of first CmndEthIpConfig
|
|
|
|
|
|
|
|
void CmndEthernet(void) {
|
2020-06-15 17:27:04 +01:00
|
|
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->flag4.network_ethernet = XdrvMailbox.payload;
|
2020-10-29 11:21:24 +00:00
|
|
|
TasmotaGlobal.restart_flag = 2;
|
2020-06-15 17:27:04 +01:00
|
|
|
}
|
2021-06-11 17:14:12 +01:00
|
|
|
ResponseCmndStateText(Settings->flag4.network_ethernet);
|
2020-06-15 17:27:04 +01:00
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void CmndEthAddress(void) {
|
2020-06-16 17:36:49 +01:00
|
|
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 31)) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->eth_address = XdrvMailbox.payload;
|
2020-10-29 11:21:24 +00:00
|
|
|
TasmotaGlobal.restart_flag = 2;
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
2021-06-11 17:14:12 +01:00
|
|
|
ResponseCmndNumber(Settings->eth_address);
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void CmndEthType(void) {
|
2023-01-05 12:04:06 +00:00
|
|
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 8)) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->eth_type = XdrvMailbox.payload;
|
2020-10-29 11:21:24 +00:00
|
|
|
TasmotaGlobal.restart_flag = 2;
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
2021-06-11 17:14:12 +01:00
|
|
|
ResponseCmndNumber(Settings->eth_type);
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void CmndEthClockMode(void) {
|
2020-06-16 17:36:49 +01:00
|
|
|
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) {
|
2021-06-11 17:14:12 +01:00
|
|
|
Settings->eth_clk_mode = XdrvMailbox.payload;
|
2020-10-29 11:21:24 +00:00
|
|
|
TasmotaGlobal.restart_flag = 2;
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
2021-06-11 17:14:12 +01:00
|
|
|
ResponseCmndNumber(Settings->eth_clk_mode);
|
2020-06-16 17:36:49 +01:00
|
|
|
}
|
|
|
|
|
2022-01-12 16:32:21 +00:00
|
|
|
void CmndEthSetIpConfig(void) {
|
|
|
|
uint32_t param_id = XdrvMailbox.command_code -ETH_PARAM_OFFSET;
|
|
|
|
|
|
|
|
char cmnd_idx[2] = { 0 };
|
|
|
|
if (3 == param_id) { // EthDnsServer
|
|
|
|
if ((XdrvMailbox.index < 1) || (XdrvMailbox.index > 2)) {
|
|
|
|
XdrvMailbox.index = 1;
|
|
|
|
}
|
|
|
|
cmnd_idx[0] = '0' + XdrvMailbox.index;
|
|
|
|
param_id += XdrvMailbox.index -1; // EthDnsServer2
|
|
|
|
}
|
|
|
|
|
|
|
|
if (XdrvMailbox.data_len) {
|
|
|
|
uint32_t ipv4_address;
|
|
|
|
if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) {
|
|
|
|
Settings->eth_ipv4_address[param_id] = ipv4_address;
|
|
|
|
eth_config_change = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char network_address[22] = { 0 };
|
|
|
|
if (0 == param_id) {
|
|
|
|
if (!Settings->eth_ipv4_address[0]) {
|
|
|
|
ext_snprintf_P(network_address, sizeof(network_address), PSTR(" (%_I)"), (uint32_t)ETH.localIP());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Response_P(PSTR("{\"%s%s\":\"%_I%s\"}"), XdrvMailbox.command, cmnd_idx, Settings->eth_ipv4_address[param_id], network_address);
|
|
|
|
}
|
|
|
|
|
2020-06-15 17:27:04 +01:00
|
|
|
/*********************************************************************************************\
|
|
|
|
* Interface
|
|
|
|
\*********************************************************************************************/
|
|
|
|
|
2022-11-11 09:44:56 +00:00
|
|
|
bool Xdrv82(uint32_t function) {
|
2020-06-15 17:27:04 +01:00
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
switch (function) {
|
2022-01-12 16:32:21 +00:00
|
|
|
case FUNC_EVERY_SECOND:
|
|
|
|
EthernetConfigChange();
|
|
|
|
break;
|
2020-06-15 17:27:04 +01:00
|
|
|
case FUNC_COMMAND:
|
|
|
|
result = DecodeCommand(kEthernetCommands, EthernetCommand);
|
|
|
|
break;
|
|
|
|
case FUNC_INIT:
|
|
|
|
EthernetInit();
|
|
|
|
break;
|
2023-12-27 21:03:56 +00:00
|
|
|
case FUNC_ACTIVE:
|
|
|
|
result = true;
|
|
|
|
break;
|
2020-06-15 17:27:04 +01:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // USE_ETHERNET
|
2024-02-14 15:19:51 +00:00
|
|
|
//#endif // CONFIG_IDF_TARGET_ESP32
|
2020-06-15 17:27:04 +01:00
|
|
|
#endif // ESP32
|