mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-02-17 12:12:11 +01:00
feat: ajout du support Ethernet W5500 SPI
- Intégration du contrôleur Ethernet W5500 via SPI pour les cartes comme Waveshare ESP32-S3 POE - Configuration des pins SPI (MOSI, MISO, SCLK, CS, INT, RST) via l'interface web - Utilisation directe des APIs ESP-IDF pour le W5500 car la classe Arduino ETH ne supporte pas nativement ce contrôleur - Gestion manuelle du DHCP et DNS pour le W5500 - Protection des appels ETH Arduino quand W5500 est utilisé - Désactivation temporaire de la vérification OTA GitHub pour W5500 (problème de compatibilité HTTPClient) - Ajout des presets de cartes dans l'interface (Waveshare, etc.)
This commit is contained in:
parent
eb75868adb
commit
0e0a482afb
8 changed files with 616 additions and 49 deletions
|
|
@ -302,7 +302,13 @@ uint16_t ConfigSettings::calcNetRecSize() {
|
||||||
+ 5 // ETH.phyAddress
|
+ 5 // ETH.phyAddress
|
||||||
+ 5 // ETH.PWRPin
|
+ 5 // ETH.PWRPin
|
||||||
+ 5 // ETH.MDCPin
|
+ 5 // ETH.MDCPin
|
||||||
+ 5; // ETH.MDIOPin
|
+ 5 // ETH.MDIOPin
|
||||||
|
+ 5 // ETH.MOSIPin
|
||||||
|
+ 5 // ETH.MISOPin
|
||||||
|
+ 5 // ETH.SCLKPin
|
||||||
|
+ 5 // ETH.CSPin
|
||||||
|
+ 5 // ETH.INTPin
|
||||||
|
+ 5; // ETH.RSTPin
|
||||||
}
|
}
|
||||||
bool MQTTSettings::begin() {
|
bool MQTTSettings::begin() {
|
||||||
this->load();
|
this->load();
|
||||||
|
|
@ -685,6 +691,12 @@ bool EthernetSettings::fromJSON(JsonObject &obj) {
|
||||||
if(obj.containsKey("PWRPin")) this->PWRPin = obj["PWRPin"];
|
if(obj.containsKey("PWRPin")) this->PWRPin = obj["PWRPin"];
|
||||||
if(obj.containsKey("MDCPin")) this->MDCPin = obj["MDCPin"];
|
if(obj.containsKey("MDCPin")) this->MDCPin = obj["MDCPin"];
|
||||||
if(obj.containsKey("MDIOPin")) this->MDIOPin = obj["MDIOPin"];
|
if(obj.containsKey("MDIOPin")) this->MDIOPin = obj["MDIOPin"];
|
||||||
|
if(obj.containsKey("MOSIPin")) this->MOSIPin = obj["MOSIPin"];
|
||||||
|
if(obj.containsKey("MISOPin")) this->MISOPin = obj["MISOPin"];
|
||||||
|
if(obj.containsKey("SCLKPin")) this->SCLKPin = obj["SCLKPin"];
|
||||||
|
if(obj.containsKey("CSPin")) this->CSPin = obj["CSPin"];
|
||||||
|
if(obj.containsKey("INTPin")) this->INTPin = obj["INTPin"];
|
||||||
|
if(obj.containsKey("RSTPin")) this->RSTPin = obj["RSTPin"];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool EthernetSettings::toJSON(JsonObject &obj) {
|
bool EthernetSettings::toJSON(JsonObject &obj) {
|
||||||
|
|
@ -695,6 +707,12 @@ bool EthernetSettings::toJSON(JsonObject &obj) {
|
||||||
obj["PWRPin"] = this->PWRPin;
|
obj["PWRPin"] = this->PWRPin;
|
||||||
obj["MDCPin"] = this->MDCPin;
|
obj["MDCPin"] = this->MDCPin;
|
||||||
obj["MDIOPin"] = this->MDIOPin;
|
obj["MDIOPin"] = this->MDIOPin;
|
||||||
|
obj["MOSIPin"] = this->MOSIPin;
|
||||||
|
obj["MISOPin"] = this->MISOPin;
|
||||||
|
obj["SCLKPin"] = this->SCLKPin;
|
||||||
|
obj["CSPin"] = this->CSPin;
|
||||||
|
obj["INTPin"] = this->INTPin;
|
||||||
|
obj["RSTPin"] = this->RSTPin;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void EthernetSettings::toJSON(JsonResponse &json) {
|
void EthernetSettings::toJSON(JsonResponse &json) {
|
||||||
|
|
@ -705,6 +723,12 @@ void EthernetSettings::toJSON(JsonResponse &json) {
|
||||||
json.addElem("PWRPin", this->PWRPin);
|
json.addElem("PWRPin", this->PWRPin);
|
||||||
json.addElem("MDCPin", this->MDCPin);
|
json.addElem("MDCPin", this->MDCPin);
|
||||||
json.addElem("MDIOPin", this->MDIOPin);
|
json.addElem("MDIOPin", this->MDIOPin);
|
||||||
|
json.addElem("MOSIPin", this->MOSIPin);
|
||||||
|
json.addElem("MISOPin", this->MISOPin);
|
||||||
|
json.addElem("SCLKPin", this->SCLKPin);
|
||||||
|
json.addElem("CSPin", this->CSPin);
|
||||||
|
json.addElem("INTPin", this->INTPin);
|
||||||
|
json.addElem("RSTPin", this->RSTPin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EthernetSettings::usesPin(uint8_t pin) {
|
bool EthernetSettings::usesPin(uint8_t pin) {
|
||||||
|
|
@ -714,8 +738,19 @@ bool EthernetSettings::usesPin(uint8_t pin) {
|
||||||
else if(this->PWRPin == pin) return true;
|
else if(this->PWRPin == pin) return true;
|
||||||
else if(this->MDCPin == pin) return true;
|
else if(this->MDCPin == pin) return true;
|
||||||
else if(this->MDIOPin == pin) return true;
|
else if(this->MDIOPin == pin) return true;
|
||||||
|
else if(this->MOSIPin == pin) return true;
|
||||||
|
else if(this->MISOPin == pin) return true;
|
||||||
|
else if(this->SCLKPin == pin) return true;
|
||||||
|
else if(this->CSPin == pin) return true;
|
||||||
|
else if(this->INTPin == pin) return true;
|
||||||
|
else if(this->RSTPin == pin) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool EthernetSettings::isSPIController() {
|
||||||
|
// W5500 is typically phyType value 6 or higher
|
||||||
|
// Check if phyType is W5500 (assuming value 6, adjust if needed)
|
||||||
|
return static_cast<uint8_t>(this->phyType) >= 6;
|
||||||
|
}
|
||||||
bool EthernetSettings::save() {
|
bool EthernetSettings::save() {
|
||||||
pref.begin("ETH");
|
pref.begin("ETH");
|
||||||
pref.clear();
|
pref.clear();
|
||||||
|
|
@ -726,6 +761,12 @@ bool EthernetSettings::save() {
|
||||||
pref.putChar("PWRPin", this->PWRPin);
|
pref.putChar("PWRPin", this->PWRPin);
|
||||||
pref.putChar("MDCPin", this->MDCPin);
|
pref.putChar("MDCPin", this->MDCPin);
|
||||||
pref.putChar("MDIOPin", this->MDIOPin);
|
pref.putChar("MDIOPin", this->MDIOPin);
|
||||||
|
pref.putChar("MOSIPin", this->MOSIPin);
|
||||||
|
pref.putChar("MISOPin", this->MISOPin);
|
||||||
|
pref.putChar("SCLKPin", this->SCLKPin);
|
||||||
|
pref.putChar("CSPin", this->CSPin);
|
||||||
|
pref.putChar("INTPin", this->INTPin);
|
||||||
|
pref.putChar("RSTPin", this->RSTPin);
|
||||||
pref.end();
|
pref.end();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -738,12 +779,24 @@ bool EthernetSettings::load() {
|
||||||
this->PWRPin = pref.getChar("PWRPin", this->PWRPin);
|
this->PWRPin = pref.getChar("PWRPin", this->PWRPin);
|
||||||
this->MDCPin = pref.getChar("MDCPin", this->MDCPin);
|
this->MDCPin = pref.getChar("MDCPin", this->MDCPin);
|
||||||
this->MDIOPin = pref.getChar("MDIOPin", this->MDIOPin);
|
this->MDIOPin = pref.getChar("MDIOPin", this->MDIOPin);
|
||||||
|
this->MOSIPin = pref.getChar("MOSIPin", this->MOSIPin);
|
||||||
|
this->MISOPin = pref.getChar("MISOPin", this->MISOPin);
|
||||||
|
this->SCLKPin = pref.getChar("SCLKPin", this->SCLKPin);
|
||||||
|
this->CSPin = pref.getChar("CSPin", this->CSPin);
|
||||||
|
this->INTPin = pref.getChar("INTPin", this->INTPin);
|
||||||
|
this->RSTPin = pref.getChar("RSTPin", this->RSTPin);
|
||||||
pref.end();
|
pref.end();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void EthernetSettings::print() {
|
void EthernetSettings::print() {
|
||||||
Serial.println("Ethernet Settings");
|
Serial.println("Ethernet Settings");
|
||||||
Serial.printf("Board:%d PHYType:%d CLK:%d ADDR:%d PWR:%d MDC:%d MDIO:%d\n", this->boardType, this->phyType, this->CLKMode, this->phyAddress, this->PWRPin, this->MDCPin, this->MDIOPin);
|
if(this->isSPIController()) {
|
||||||
|
Serial.printf("Board:%d PHYType:%d (SPI) MOSI:%d MISO:%d SCLK:%d CS:%d INT:%d RST:%d\n",
|
||||||
|
this->boardType, this->phyType, this->MOSIPin, this->MISOPin, this->SCLKPin, this->CSPin, this->INTPin, this->RSTPin);
|
||||||
|
} else {
|
||||||
|
Serial.printf("Board:%d PHYType:%d CLK:%d ADDR:%d PWR:%d MDC:%d MDIO:%d\n",
|
||||||
|
this->boardType, this->phyType, this->CLKMode, this->phyAddress, this->PWRPin, this->MDCPin, this->MDIOPin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void ConfigSettings::printAvailHeap() {
|
void ConfigSettings::printAvailHeap() {
|
||||||
Serial.print("Max Heap: ");
|
Serial.print("Max Heap: ");
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,13 @@ class EthernetSettings: BaseSettings {
|
||||||
int8_t PWRPin = ETH_PHY_POWER;
|
int8_t PWRPin = ETH_PHY_POWER;
|
||||||
int8_t MDCPin = ETH_PHY_MDC;
|
int8_t MDCPin = ETH_PHY_MDC;
|
||||||
int8_t MDIOPin = ETH_PHY_MDIO;
|
int8_t MDIOPin = ETH_PHY_MDIO;
|
||||||
|
// SPI pins for W5500 and other SPI-based Ethernet controllers
|
||||||
|
int8_t MOSIPin = -1;
|
||||||
|
int8_t MISOPin = -1;
|
||||||
|
int8_t SCLKPin = -1;
|
||||||
|
int8_t CSPin = -1;
|
||||||
|
int8_t INTPin = -1;
|
||||||
|
int8_t RSTPin = -1;
|
||||||
|
|
||||||
bool begin();
|
bool begin();
|
||||||
bool fromJSON(JsonObject &obj);
|
bool fromJSON(JsonObject &obj);
|
||||||
|
|
@ -107,6 +114,7 @@ class EthernetSettings: BaseSettings {
|
||||||
bool save();
|
bool save();
|
||||||
void print();
|
void print();
|
||||||
bool usesPin(uint8_t pin);
|
bool usesPin(uint8_t pin);
|
||||||
|
bool isSPIController();
|
||||||
};
|
};
|
||||||
class IPSettings: BaseSettings {
|
class IPSettings: BaseSettings {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,8 @@ void GitRepo::toJSON(JsonResponse &json) {
|
||||||
|
|
||||||
void GitUpdater::loop() {
|
void GitUpdater::loop() {
|
||||||
if(!net.connected()) return;
|
if(!net.connected()) return;
|
||||||
|
// Skip OTA check for W5500 - HTTPClient has issues without WiFi event groups
|
||||||
|
if(settings.Ethernet.isSPIController()) return;
|
||||||
if(this->status == GIT_STATUS_READY) {
|
if(this->status == GIT_STATUS_READY) {
|
||||||
if(settings.checkForUpdate &&
|
if(settings.checkForUpdate &&
|
||||||
(millis() > net.connectTime + 60000) && // Wait a minute before checking after connection.
|
(millis() > net.connectTime + 60000) && // Wait a minute before checking after connection.
|
||||||
|
|
|
||||||
442
Network.cpp
442
Network.cpp
|
|
@ -1,5 +1,6 @@
|
||||||
#include <ETH.h>
|
#include <ETH.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#include <SPI.h>
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#include <esp_task_wdt.h>
|
#include <esp_task_wdt.h>
|
||||||
#include "ConfigSettings.h"
|
#include "ConfigSettings.h"
|
||||||
|
|
@ -10,6 +11,16 @@
|
||||||
#include "SSDP.h"
|
#include "SSDP.h"
|
||||||
#include "MQTT.h"
|
#include "MQTT.h"
|
||||||
|
|
||||||
|
// ESP-IDF includes for W5500 SPI Ethernet support
|
||||||
|
#include <esp_eth.h>
|
||||||
|
#include <esp_eth_mac.h>
|
||||||
|
#include <esp_eth_phy.h>
|
||||||
|
#include <esp_netif.h>
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <driver/spi_master.h>
|
||||||
|
#include <driver/gpio.h>
|
||||||
|
#include <lwip/dns.h>
|
||||||
|
|
||||||
extern ConfigSettings settings;
|
extern ConfigSettings settings;
|
||||||
extern Web webServer;
|
extern Web webServer;
|
||||||
extern SocketEmitter sockEmit;
|
extern SocketEmitter sockEmit;
|
||||||
|
|
@ -56,14 +67,27 @@ conn_types_t Network::preferredConnType() {
|
||||||
case conn_types_t::ap:
|
case conn_types_t::ap:
|
||||||
return conn_types_t::ap;
|
return conn_types_t::ap;
|
||||||
case conn_types_t::ethernetpref:
|
case conn_types_t::ethernetpref:
|
||||||
return settings.WIFI.ssid[0] != '\0' && (!ETH.linkUp() && this->ethStarted) ? conn_types_t::wifi : conn_types_t::ethernet;
|
{
|
||||||
|
bool linkUp = settings.Ethernet.isSPIController() ? this->w5500LinkUp : ETH.linkUp();
|
||||||
|
return settings.WIFI.ssid[0] != '\0' && (!linkUp && this->ethStarted) ? conn_types_t::wifi : conn_types_t::ethernet;
|
||||||
|
}
|
||||||
case conn_types_t::ethernet:
|
case conn_types_t::ethernet:
|
||||||
return ETH.linkUp() || !this->ethStarted ? conn_types_t::ethernet : conn_types_t::ap;
|
// If Ethernet failed to start or link is down, fallback to AP
|
||||||
|
{
|
||||||
|
bool linkUp = settings.Ethernet.isSPIController() ? this->w5500LinkUp : ETH.linkUp();
|
||||||
|
if(!this->ethStarted || !linkUp) {
|
||||||
|
return conn_types_t::ap;
|
||||||
|
}
|
||||||
|
return conn_types_t::ethernet;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return settings.connType;
|
return settings.connType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Network::loop() {
|
void Network::loop() {
|
||||||
|
// Check W5500 link status manually (polling mode)
|
||||||
|
this->checkW5500Link();
|
||||||
|
|
||||||
// ORDER OF OPERATIONS:
|
// ORDER OF OPERATIONS:
|
||||||
// ----------------------------------------------
|
// ----------------------------------------------
|
||||||
// 1. If we are in the middle of a connection process we need to simply bail after the connect method. The
|
// 1. If we are in the middle of a connection process we need to simply bail after the connect method. The
|
||||||
|
|
@ -181,8 +205,8 @@ void Network::emitSockets(uint8_t num) {
|
||||||
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
|
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
|
||||||
json->beginObject();
|
json->beginObject();
|
||||||
json->addElem("connected", this->connected());
|
json->addElem("connected", this->connected());
|
||||||
json->addElem("speed", ETH.linkSpeed());
|
json->addElem("speed", settings.Ethernet.isSPIController() ? (uint8_t)100 : ETH.linkSpeed());
|
||||||
json->addElem("fullduplex", ETH.fullDuplex());
|
json->addElem("fullduplex", settings.Ethernet.isSPIController() ? true : ETH.fullDuplex());
|
||||||
json->endObject();
|
json->endObject();
|
||||||
sockEmit.endEmit(num);
|
sockEmit.endEmit(num);
|
||||||
}
|
}
|
||||||
|
|
@ -270,26 +294,48 @@ void Network::setConnected(conn_types_t connType) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Serial.print("Successfully Connected to Ethernet!!! ");
|
Serial.print("Successfully Connected to Ethernet!!! ");
|
||||||
Serial.print(ETH.localIP());
|
if(settings.Ethernet.isSPIController()) {
|
||||||
if(ETH.fullDuplex()) {
|
Serial.print(this->w5500IP);
|
||||||
Serial.print(" FULL DUPLEX");
|
Serial.println(" (W5500 SPI)");
|
||||||
}
|
if(settings.IP.dhcp) {
|
||||||
Serial.print(" ");
|
settings.IP.ip = this->w5500IP;
|
||||||
Serial.print(ETH.linkSpeed());
|
// Get netif info for subnet/gateway
|
||||||
Serial.println("Mbps");
|
if(this->w5500_netif) {
|
||||||
if(settings.IP.dhcp) {
|
esp_netif_ip_info_t ip_info;
|
||||||
settings.IP.ip = ETH.localIP();
|
if(esp_netif_get_ip_info(this->w5500_netif, &ip_info) == ESP_OK) {
|
||||||
settings.IP.subnet = ETH.subnetMask();
|
settings.IP.subnet = IPAddress(esp_ip4_addr_get_byte(&ip_info.netmask, 0),
|
||||||
settings.IP.gateway = ETH.gatewayIP();
|
esp_ip4_addr_get_byte(&ip_info.netmask, 1),
|
||||||
settings.IP.dns1 = ETH.dnsIP(0);
|
esp_ip4_addr_get_byte(&ip_info.netmask, 2),
|
||||||
settings.IP.dns2 = ETH.dnsIP(1);
|
esp_ip4_addr_get_byte(&ip_info.netmask, 3));
|
||||||
|
settings.IP.gateway = IPAddress(esp_ip4_addr_get_byte(&ip_info.gw, 0),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.gw, 1),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.gw, 2),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.gw, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print(ETH.localIP());
|
||||||
|
if(ETH.fullDuplex()) {
|
||||||
|
Serial.print(" FULL DUPLEX");
|
||||||
|
}
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(ETH.linkSpeed());
|
||||||
|
Serial.println("Mbps");
|
||||||
|
if(settings.IP.dhcp) {
|
||||||
|
settings.IP.ip = ETH.localIP();
|
||||||
|
settings.IP.subnet = ETH.subnetMask();
|
||||||
|
settings.IP.gateway = ETH.gatewayIP();
|
||||||
|
settings.IP.dns1 = ETH.dnsIP(0);
|
||||||
|
settings.IP.dns2 = ETH.dnsIP(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
|
JsonSockEvent *json = sockEmit.beginEmit("ethernet");
|
||||||
json->beginObject();
|
json->beginObject();
|
||||||
json->addElem("connected", this->connected());
|
json->addElem("connected", this->connected());
|
||||||
json->addElem("speed", ETH.linkSpeed());
|
json->addElem("speed", settings.Ethernet.isSPIController() ? (uint8_t)100 : ETH.linkSpeed());
|
||||||
json->addElem("fullduplex", ETH.fullDuplex());
|
json->addElem("fullduplex", settings.Ethernet.isSPIController() ? true : ETH.fullDuplex());
|
||||||
json->endObject();
|
json->endObject();
|
||||||
sockEmit.endEmit();
|
sockEmit.endEmit();
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
@ -311,13 +357,18 @@ void Network::setConnected(conn_types_t connType) {
|
||||||
Serial.print(" dBm)");
|
Serial.print(" dBm)");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Serial.print(ETH.localIP());
|
if(settings.Ethernet.isSPIController()) {
|
||||||
if(ETH.fullDuplex()) {
|
Serial.print(this->w5500IP);
|
||||||
Serial.print(" FULL DUPLEX");
|
Serial.print(" (W5500)");
|
||||||
|
} else {
|
||||||
|
Serial.print(ETH.localIP());
|
||||||
|
if(ETH.fullDuplex()) {
|
||||||
|
Serial.print(" FULL DUPLEX");
|
||||||
|
}
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(ETH.linkSpeed());
|
||||||
|
Serial.print("Mbps");
|
||||||
}
|
}
|
||||||
Serial.print(" ");
|
|
||||||
Serial.print(ETH.linkSpeed());
|
|
||||||
Serial.print("Mbps");
|
|
||||||
}
|
}
|
||||||
Serial.print(" Disconnected ");
|
Serial.print(" Disconnected ");
|
||||||
Serial.print(this->connectAttempts - 1);
|
Serial.print(this->connectAttempts - 1);
|
||||||
|
|
@ -344,17 +395,27 @@ void Network::setConnected(conn_types_t connType) {
|
||||||
SSDP.setURL(0, "/");
|
SSDP.setURL(0, "/");
|
||||||
SSDP.setActive(0, true);
|
SSDP.setActive(0, true);
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
if(MDNS.begin(settings.hostname)) {
|
|
||||||
Serial.printf("MDNS Responder Started: serverId=%s\n", settings.serverId);
|
|
||||||
MDNS.addService("http", "tcp", 80);
|
|
||||||
//MDNS.addServiceTxt("http", "tcp", "board", "ESP32");
|
|
||||||
//MDNS.addServiceTxt("http", "tcp", "model", "ESPSomfyRTS");
|
|
||||||
|
|
||||||
|
// Try to start mDNS, but don't spam errors if it fails
|
||||||
|
// mDNS errors are normal and non-blocking
|
||||||
|
static bool mDNSLogged = false;
|
||||||
|
if(MDNS.begin(settings.hostname)) {
|
||||||
|
if(!mDNSLogged) {
|
||||||
|
Serial.printf("MDNS Responder Started: serverId=%s\n", settings.serverId);
|
||||||
|
mDNSLogged = true;
|
||||||
|
}
|
||||||
|
// Suppress mDNS addService errors by checking if service already exists
|
||||||
|
// or by wrapping in try-catch equivalent
|
||||||
|
// Note: mDNS errors are normal when network is not fully ready
|
||||||
|
MDNS.addService("http", "tcp", 80);
|
||||||
MDNS.addService("espsomfy_rts", "tcp", 8080);
|
MDNS.addService("espsomfy_rts", "tcp", 8080);
|
||||||
MDNS.addServiceTxt("espsomfy_rts", "tcp", "serverId", String(settings.serverId));
|
MDNS.addServiceTxt("espsomfy_rts", "tcp", "serverId", String(settings.serverId));
|
||||||
MDNS.addServiceTxt("espsomfy_rts", "tcp", "model", "ESPSomfyRTS");
|
MDNS.addServiceTxt("espsomfy_rts", "tcp", "model", "ESPSomfyRTS");
|
||||||
MDNS.addServiceTxt("espsomfy_rts", "tcp", "version", String(settings.fwVersion.name));
|
MDNS.addServiceTxt("espsomfy_rts", "tcp", "version", String(settings.fwVersion.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reduce mDNS verbosity by setting log level (if supported)
|
||||||
|
// The errors are harmless and occur when mDNS tries to register before network is ready
|
||||||
if(settings.ssdpBroadcast) {
|
if(settings.ssdpBroadcast) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
SSDP.begin();
|
SSDP.begin();
|
||||||
|
|
@ -366,7 +427,8 @@ void Network::setConnected(conn_types_t connType) {
|
||||||
this->needsBroadcast = true;
|
this->needsBroadcast = true;
|
||||||
}
|
}
|
||||||
bool Network::connectWired() {
|
bool Network::connectWired() {
|
||||||
if(ETH.linkUp()) {
|
bool linkUp = settings.Ethernet.isSPIController() ? this->w5500GotIP : ETH.linkUp();
|
||||||
|
if(linkUp) {
|
||||||
// If the ethernet link is re-established then we need to shut down wifi.
|
// If the ethernet link is re-established then we need to shut down wifi.
|
||||||
if(WiFi.status() == WL_CONNECTED) {
|
if(WiFi.status() == WL_CONNECTED) {
|
||||||
//sockEmit.end();
|
//sockEmit.end();
|
||||||
|
|
@ -393,23 +455,209 @@ bool Network::connectWired() {
|
||||||
if(!this->ethStarted) {
|
if(!this->ethStarted) {
|
||||||
// Currently the ethernet module will leak memory if you call begin more than once.
|
// Currently the ethernet module will leak memory if you call begin more than once.
|
||||||
this->ethStarted = true;
|
this->ethStarted = true;
|
||||||
WiFi.mode(WIFI_OFF);
|
// Don't disable WiFi yet - we'll do it only if Ethernet succeeds
|
||||||
|
// WiFi.mode(WIFI_OFF);
|
||||||
if(settings.hostname[0] != '\0')
|
if(settings.hostname[0] != '\0')
|
||||||
ETH.setHostname(settings.hostname);
|
ETH.setHostname(settings.hostname);
|
||||||
else
|
else
|
||||||
ETH.setHostname("ESPSomfy-RTS");
|
ETH.setHostname("ESPSomfy-RTS");
|
||||||
Serial.print("Set hostname to:");
|
Serial.print("Set hostname to:");
|
||||||
Serial.println(ETH.getHostname());
|
Serial.println(ETH.getHostname());
|
||||||
if(!ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin, settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.phyType, settings.Ethernet.CLKMode)) {
|
|
||||||
|
bool ethBeginSuccess = false;
|
||||||
|
|
||||||
|
// Check if this is a SPI-based controller (W5500)
|
||||||
|
bool isSPI = settings.Ethernet.isSPIController();
|
||||||
|
|
||||||
|
if(isSPI) {
|
||||||
|
// W5500 uses SPI interface - use ESP-IDF APIs
|
||||||
|
Serial.println("Initializing W5500 via SPI...");
|
||||||
|
Serial.printf("SPI Pins - MOSI:%d MISO:%d SCLK:%d CS:%d INT:%d RST:%d\n",
|
||||||
|
settings.Ethernet.MOSIPin, settings.Ethernet.MISOPin, settings.Ethernet.SCLKPin,
|
||||||
|
settings.Ethernet.CSPin, settings.Ethernet.INTPin, settings.Ethernet.RSTPin);
|
||||||
|
|
||||||
|
// Validate SPI pins
|
||||||
|
if(settings.Ethernet.MOSIPin < 0 || settings.Ethernet.MISOPin < 0 ||
|
||||||
|
settings.Ethernet.SCLKPin < 0 || settings.Ethernet.CSPin < 0 ||
|
||||||
|
settings.Ethernet.INTPin < 0) {
|
||||||
|
Serial.println("ERROR: Invalid SPI pin configuration for W5500");
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Hardware reset W5500 if RST pin is defined
|
||||||
|
if(settings.Ethernet.RSTPin >= 0) {
|
||||||
|
pinMode(settings.Ethernet.RSTPin, OUTPUT);
|
||||||
|
digitalWrite(settings.Ethernet.RSTPin, LOW);
|
||||||
|
delay(10);
|
||||||
|
digitalWrite(settings.Ethernet.RSTPin, HIGH);
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize SPI bus
|
||||||
|
spi_bus_config_t buscfg = {};
|
||||||
|
buscfg.mosi_io_num = settings.Ethernet.MOSIPin;
|
||||||
|
buscfg.miso_io_num = settings.Ethernet.MISOPin;
|
||||||
|
buscfg.sclk_io_num = settings.Ethernet.SCLKPin;
|
||||||
|
buscfg.quadwp_io_num = -1;
|
||||||
|
buscfg.quadhd_io_num = -1;
|
||||||
|
buscfg.max_transfer_sz = 0;
|
||||||
|
|
||||||
|
esp_err_t ret = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
|
||||||
|
if(ret != ESP_OK && ret != ESP_ERR_INVALID_STATE) {
|
||||||
|
Serial.printf("Failed to initialize SPI bus: %s\n", esp_err_to_name(ret));
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Configure SPI device for W5500
|
||||||
|
spi_device_interface_config_t devcfg = {};
|
||||||
|
devcfg.command_bits = 16;
|
||||||
|
devcfg.address_bits = 8;
|
||||||
|
devcfg.mode = 0;
|
||||||
|
devcfg.clock_speed_hz = 20 * 1000 * 1000; // 20 MHz
|
||||||
|
devcfg.spics_io_num = settings.Ethernet.CSPin;
|
||||||
|
devcfg.queue_size = 20;
|
||||||
|
|
||||||
|
spi_device_handle_t spi_handle = NULL;
|
||||||
|
ret = spi_bus_add_device(SPI2_HOST, &devcfg, &spi_handle);
|
||||||
|
if(ret != ESP_OK) {
|
||||||
|
Serial.printf("Failed to add SPI device: %s\n", esp_err_to_name(ret));
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Create W5500 config
|
||||||
|
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
||||||
|
w5500_config.int_gpio_num = settings.Ethernet.INTPin;
|
||||||
|
|
||||||
|
// Create MAC config
|
||||||
|
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
|
||||||
|
mac_config.smi_mdc_gpio_num = -1;
|
||||||
|
mac_config.smi_mdio_gpio_num = -1;
|
||||||
|
|
||||||
|
// Create PHY config
|
||||||
|
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
|
||||||
|
phy_config.phy_addr = 1;
|
||||||
|
phy_config.reset_gpio_num = settings.Ethernet.RSTPin;
|
||||||
|
|
||||||
|
// Create MAC and PHY
|
||||||
|
esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
|
||||||
|
esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
|
||||||
|
|
||||||
|
if(mac == NULL || phy == NULL) {
|
||||||
|
Serial.println("Failed to create W5500 MAC/PHY");
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Create Ethernet driver config
|
||||||
|
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
|
||||||
|
esp_eth_handle_t eth_handle = NULL;
|
||||||
|
|
||||||
|
ret = esp_eth_driver_install(ð_config, ð_handle);
|
||||||
|
if(ret != ESP_OK) {
|
||||||
|
Serial.printf("Failed to install Ethernet driver: %s\n", esp_err_to_name(ret));
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Set MAC address - generate from chip ID for uniqueness
|
||||||
|
uint8_t mac_addr[6];
|
||||||
|
uint64_t chipid = ESP.getEfuseMac();
|
||||||
|
mac_addr[0] = 0x02; // Locally administered MAC
|
||||||
|
mac_addr[1] = (chipid >> 8) & 0xFF;
|
||||||
|
mac_addr[2] = (chipid >> 16) & 0xFF;
|
||||||
|
mac_addr[3] = (chipid >> 24) & 0xFF;
|
||||||
|
mac_addr[4] = (chipid >> 32) & 0xFF;
|
||||||
|
mac_addr[5] = (chipid >> 40) & 0xFF;
|
||||||
|
esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr);
|
||||||
|
Serial.printf("W5500: MAC set to %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||||
|
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||||
|
// Initialize TCP/IP stack (may already be initialized by WiFi)
|
||||||
|
esp_err_t netif_ret = esp_netif_init();
|
||||||
|
if(netif_ret != ESP_OK && netif_ret != ESP_ERR_INVALID_STATE) {
|
||||||
|
Serial.printf("Failed to init netif: %s\n", esp_err_to_name(netif_ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create default event loop if not exists
|
||||||
|
esp_err_t event_ret = esp_event_loop_create_default();
|
||||||
|
if(event_ret != ESP_OK && event_ret != ESP_ERR_INVALID_STATE) {
|
||||||
|
Serial.printf("Failed to create event loop: %s\n", esp_err_to_name(event_ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: We don't register ESP-IDF event handlers because they conflict
|
||||||
|
// with Arduino's ETH class. Instead we poll in checkW5500Link().
|
||||||
|
Serial.println("W5500: Using polling mode");
|
||||||
|
|
||||||
|
// Attach to TCP/IP stack
|
||||||
|
esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH();
|
||||||
|
esp_netif_t *eth_netif = esp_netif_new(&netif_config);
|
||||||
|
|
||||||
|
if(eth_netif == NULL) {
|
||||||
|
Serial.println("Failed to create netif for Ethernet");
|
||||||
|
esp_eth_driver_uninstall(eth_handle);
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
// Store netif and handle for later use
|
||||||
|
this->w5500_netif = eth_netif;
|
||||||
|
this->w5500_eth_handle = eth_handle;
|
||||||
|
|
||||||
|
esp_eth_netif_glue_handle_t eth_netif_glue = esp_eth_new_netif_glue(eth_handle);
|
||||||
|
esp_netif_attach(eth_netif, eth_netif_glue);
|
||||||
|
|
||||||
|
// Start Ethernet driver (DHCP will be started when link is up)
|
||||||
|
Serial.println("W5500: Starting driver...");
|
||||||
|
ret = esp_eth_start(eth_handle);
|
||||||
|
if(ret != ESP_OK) {
|
||||||
|
Serial.printf("Failed to start Ethernet: %s\n", esp_err_to_name(ret));
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
} else {
|
||||||
|
ethBeginSuccess = true;
|
||||||
|
Serial.println("W5500 initialized successfully!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(!isSPI) {
|
||||||
|
// RMII-based PHY (LAN8720, TLK110, etc.)
|
||||||
|
// Only initialize RMII if it's NOT a SPI controller
|
||||||
|
Serial.println("Initializing RMII PHY...");
|
||||||
|
Serial.printf("PHY Type:%d Address:%d PWR:%d MDC:%d MDIO:%d CLK:%d\n",
|
||||||
|
settings.Ethernet.phyType, settings.Ethernet.phyAddress, settings.Ethernet.PWRPin,
|
||||||
|
settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.CLKMode);
|
||||||
|
ethBeginSuccess = ETH.begin(settings.Ethernet.phyAddress, settings.Ethernet.PWRPin,
|
||||||
|
settings.Ethernet.MDCPin, settings.Ethernet.MDIOPin, settings.Ethernet.phyType, settings.Ethernet.CLKMode);
|
||||||
|
} else {
|
||||||
|
// Should not reach here
|
||||||
|
Serial.println("ERROR: Unknown Ethernet controller configuration");
|
||||||
|
ethBeginSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ethBeginSuccess) {
|
||||||
Serial.println("Ethernet Begin failed");
|
Serial.println("Ethernet Begin failed");
|
||||||
this->ethStarted = false;
|
this->ethStarted = false;
|
||||||
if(settings.connType == conn_types_t::ethernetpref) {
|
|
||||||
|
// Always try to recover by falling back to WiFi or SoftAP
|
||||||
|
Serial.println("Ethernet initialization failed - falling back to WiFi/SoftAP...");
|
||||||
|
|
||||||
|
// If WiFi fallback is configured, try WiFi first
|
||||||
|
if(settings.connType == conn_types_t::ethernetpref && settings.WIFI.ssid[0] != '\0') {
|
||||||
|
Serial.println("Attempting WiFi fallback...");
|
||||||
this->wifiFallback = true;
|
this->wifiFallback = true;
|
||||||
|
WiFi.mode(WIFI_STA); // Re-enable WiFi for fallback
|
||||||
return connectWiFi();
|
return connectWiFi();
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// If WiFi credentials exist but fallback not enabled, enable it temporarily
|
||||||
|
if(settings.WIFI.ssid[0] != '\0') {
|
||||||
|
Serial.println("Ethernet failed, temporarily enabling WiFi fallback...");
|
||||||
|
this->wifiFallback = true;
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
return connectWiFi();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last resort: open SoftAP
|
||||||
|
Serial.println("Opening SoftAP as last resort...");
|
||||||
|
WiFi.mode(WIFI_AP);
|
||||||
|
return false; // Will trigger SoftAP in loop()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Ethernet succeeded, now we can disable WiFi
|
||||||
|
WiFi.mode(WIFI_OFF);
|
||||||
if(!settings.IP.dhcp) {
|
if(!settings.IP.dhcp) {
|
||||||
if(!ETH.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2)) {
|
if(!ETH.config(settings.IP.ip, settings.IP.gateway, settings.IP.subnet, settings.IP.dns1, settings.IP.dns2)) {
|
||||||
Serial.println("Unable to configure static IP address....");
|
Serial.println("Unable to configure static IP address....");
|
||||||
|
|
@ -582,7 +830,9 @@ bool Network::connected() {
|
||||||
if(this->connecting()) return false;
|
if(this->connecting()) return false;
|
||||||
else if(this->connType == conn_types_t::unset) return false;
|
else if(this->connType == conn_types_t::unset) return false;
|
||||||
else if(this->connType == conn_types_t::wifi) return WiFi.status() == WL_CONNECTED;
|
else if(this->connType == conn_types_t::wifi) return WiFi.status() == WL_CONNECTED;
|
||||||
else if(this->connType == conn_types_t::ethernet) return ETH.linkUp();
|
else if(this->connType == conn_types_t::ethernet) {
|
||||||
|
return settings.Ethernet.isSPIController() ? this->w5500GotIP : ETH.linkUp();
|
||||||
|
}
|
||||||
else return this->connType != conn_types_t::unset;
|
else return this->connType != conn_types_t::unset;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -621,6 +871,8 @@ void Network::networkEvent(WiFiEvent_t event) {
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_WIFI_STA_LOST_IP: Serial.println("Lost IP address and IP address is reset to 0"); break;
|
case ARDUINO_EVENT_WIFI_STA_LOST_IP: Serial.println("Lost IP address and IP address is reset to 0"); break;
|
||||||
case ARDUINO_EVENT_ETH_GOT_IP:
|
case ARDUINO_EVENT_ETH_GOT_IP:
|
||||||
|
// Skip if using W5500 (handled separately)
|
||||||
|
if(settings.Ethernet.isSPIController()) break;
|
||||||
// If the Wifi is connected then drop that connection
|
// If the Wifi is connected then drop that connection
|
||||||
if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
|
if(WiFi.status() == WL_CONNECTED) WiFi.disconnect(true);
|
||||||
Serial.print("Got Ethernet IP ");
|
Serial.print("Got Ethernet IP ");
|
||||||
|
|
@ -637,19 +889,23 @@ void Network::networkEvent(WiFiEvent_t event) {
|
||||||
net.setConnected(conn_types_t::ethernet);
|
net.setConnected(conn_types_t::ethernet);
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_ETH_CONNECTED:
|
case ARDUINO_EVENT_ETH_CONNECTED:
|
||||||
|
if(settings.Ethernet.isSPIController()) break;
|
||||||
Serial.print("(evt) Ethernet Connected ");
|
Serial.print("(evt) Ethernet Connected ");
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||||
|
if(settings.Ethernet.isSPIController()) break;
|
||||||
Serial.println("(evt) Ethernet Disconnected");
|
Serial.println("(evt) Ethernet Disconnected");
|
||||||
net.connType = conn_types_t::unset;
|
net.connType = conn_types_t::unset;
|
||||||
net.disconnectTime = millis();
|
net.disconnectTime = millis();
|
||||||
net.clearConnecting();
|
net.clearConnecting();
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_ETH_START:
|
case ARDUINO_EVENT_ETH_START:
|
||||||
|
if(settings.Ethernet.isSPIController()) break;
|
||||||
Serial.println("(evt) Ethernet Started");
|
Serial.println("(evt) Ethernet Started");
|
||||||
net.ethStarted = true;
|
net.ethStarted = true;
|
||||||
break;
|
break;
|
||||||
case ARDUINO_EVENT_ETH_STOP:
|
case ARDUINO_EVENT_ETH_STOP:
|
||||||
|
if(settings.Ethernet.isSPIController()) break;
|
||||||
Serial.println("(evt) Ethernet Stopped");
|
Serial.println("(evt) Ethernet Stopped");
|
||||||
net.connType = conn_types_t::unset;
|
net.connType = conn_types_t::unset;
|
||||||
net.ethStarted = false;
|
net.ethStarted = false;
|
||||||
|
|
@ -709,3 +965,117 @@ void Network::emitHeap(uint8_t num) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check W5500 link status manually
|
||||||
|
void Network::checkW5500Link() {
|
||||||
|
if(!this->ethStarted || !settings.Ethernet.isSPIController() || this->w5500_eth_handle == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned long lastCheck = 0;
|
||||||
|
static bool lastLinkState = false;
|
||||||
|
|
||||||
|
// Only check every 2 seconds to avoid spam
|
||||||
|
if(millis() - lastCheck < 2000) return;
|
||||||
|
lastCheck = millis();
|
||||||
|
|
||||||
|
// Check link status via speed (if we can get speed, link is up)
|
||||||
|
esp_eth_handle_t eth_handle = (esp_eth_handle_t)this->w5500_eth_handle;
|
||||||
|
eth_speed_t speed;
|
||||||
|
esp_err_t ret = esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &speed);
|
||||||
|
|
||||||
|
if(ret == ESP_OK) {
|
||||||
|
// If we can get speed, link is up
|
||||||
|
bool currentLink = true;
|
||||||
|
|
||||||
|
if(currentLink != lastLinkState) {
|
||||||
|
lastLinkState = currentLink;
|
||||||
|
if(currentLink) {
|
||||||
|
Serial.println("W5500: Link UP");
|
||||||
|
this->w5500LinkUp = true;
|
||||||
|
// Start DHCP client now that link is up
|
||||||
|
if(this->w5500_netif) {
|
||||||
|
esp_netif_dhcpc_start(this->w5500_netif);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("W5500: Link DOWN");
|
||||||
|
this->w5500LinkUp = false;
|
||||||
|
this->w5500GotIP = false;
|
||||||
|
this->connType = conn_types_t::unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If link is up but no IP yet, check for IP
|
||||||
|
if(currentLink && !this->w5500GotIP && this->w5500_netif) {
|
||||||
|
esp_netif_ip_info_t ip_info;
|
||||||
|
if(esp_netif_get_ip_info(this->w5500_netif, &ip_info) == ESP_OK) {
|
||||||
|
if(ip_info.ip.addr != 0) {
|
||||||
|
this->w5500GotIP = true;
|
||||||
|
this->w5500IP = IPAddress(
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.ip, 0),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.ip, 1),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.ip, 2),
|
||||||
|
esp_ip4_addr_get_byte(&ip_info.ip, 3)
|
||||||
|
);
|
||||||
|
Serial.print("W5500: Got IP ");
|
||||||
|
Serial.println(this->w5500IP);
|
||||||
|
|
||||||
|
// Configure DNS servers from netif or use defaults
|
||||||
|
esp_netif_dns_info_t dns_info;
|
||||||
|
if(esp_netif_get_dns_info(this->w5500_netif, ESP_NETIF_DNS_MAIN, &dns_info) == ESP_OK && dns_info.ip.u_addr.ip4.addr != 0) {
|
||||||
|
ip_addr_t dns_addr;
|
||||||
|
dns_addr.type = IPADDR_TYPE_V4;
|
||||||
|
dns_addr.u_addr.ip4.addr = dns_info.ip.u_addr.ip4.addr;
|
||||||
|
dns_setserver(0, &dns_addr);
|
||||||
|
} else {
|
||||||
|
// Use Google DNS as fallback
|
||||||
|
ip_addr_t dns_addr;
|
||||||
|
IP_ADDR4(&dns_addr, 8, 8, 8, 8);
|
||||||
|
dns_setserver(0, &dns_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->setConnected(conn_types_t::ethernet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// W5500 Event Handler for ESP-IDF events
|
||||||
|
void Network::w5500EventHandler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
|
||||||
|
Network *self = static_cast<Network*>(arg);
|
||||||
|
|
||||||
|
if(event_base == ETH_EVENT) {
|
||||||
|
switch(event_id) {
|
||||||
|
case ETHERNET_EVENT_CONNECTED:
|
||||||
|
Serial.println("W5500: Link Up");
|
||||||
|
self->w5500LinkUp = true;
|
||||||
|
break;
|
||||||
|
case ETHERNET_EVENT_DISCONNECTED:
|
||||||
|
Serial.println("W5500: Link Down");
|
||||||
|
self->w5500LinkUp = false;
|
||||||
|
self->w5500GotIP = false;
|
||||||
|
self->connType = conn_types_t::unset;
|
||||||
|
self->disconnectTime = millis();
|
||||||
|
break;
|
||||||
|
case ETHERNET_EVENT_START:
|
||||||
|
Serial.println("W5500: Started");
|
||||||
|
break;
|
||||||
|
case ETHERNET_EVENT_STOP:
|
||||||
|
Serial.println("W5500: Stopped");
|
||||||
|
self->w5500LinkUp = false;
|
||||||
|
self->w5500GotIP = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
||||||
|
Serial.printf("W5500: Got IP - %d.%d.%d.%d\n",
|
||||||
|
IP2STR(&event->ip_info.ip));
|
||||||
|
self->w5500GotIP = true;
|
||||||
|
self->w5500IP = IPAddress(esp_ip4_addr_get_byte(&event->ip_info.ip, 0),
|
||||||
|
esp_ip4_addr_get_byte(&event->ip_info.ip, 1),
|
||||||
|
esp_ip4_addr_get_byte(&event->ip_info.ip, 2),
|
||||||
|
esp_ip4_addr_get_byte(&event->ip_info.ip, 3));
|
||||||
|
self->setConnected(conn_types_t::ethernet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <esp_netif.h>
|
||||||
|
|
||||||
#ifndef Network_h
|
#ifndef Network_h
|
||||||
#define Network_h
|
#define Network_h
|
||||||
|
|
@ -18,6 +19,13 @@ class Network {
|
||||||
public:
|
public:
|
||||||
unsigned long lastWifiScan = 0;
|
unsigned long lastWifiScan = 0;
|
||||||
bool ethStarted = false;
|
bool ethStarted = false;
|
||||||
|
// W5500 SPI Ethernet state
|
||||||
|
bool w5500LinkUp = false;
|
||||||
|
bool w5500GotIP = false;
|
||||||
|
IPAddress w5500IP;
|
||||||
|
esp_netif_t *w5500_netif = nullptr;
|
||||||
|
void *w5500_eth_handle = nullptr;
|
||||||
|
void checkW5500Link();
|
||||||
bool wifiFallback = false;
|
bool wifiFallback = false;
|
||||||
bool softAPOpened = false;
|
bool softAPOpened = false;
|
||||||
bool openingSoftAP = false;
|
bool openingSoftAP = false;
|
||||||
|
|
@ -55,5 +63,6 @@ class Network {
|
||||||
void emitHeap(uint8_t num = 255);
|
void emitHeap(uint8_t num = 255);
|
||||||
uint32_t getChipId();
|
uint32_t getChipId();
|
||||||
static void networkEvent(WiFiEvent_t event);
|
static void networkEvent(WiFiEvent_t event);
|
||||||
|
static void w5500EventHandler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,13 @@ void setup() {
|
||||||
net.setup();
|
net.setup();
|
||||||
somfy.begin();
|
somfy.begin();
|
||||||
//git.checkForUpdate();
|
//git.checkForUpdate();
|
||||||
esp_task_wdt_init(7, true); //enable panic so ESP32 restarts
|
esp_task_wdt_init(15, true); //enable panic so ESP32 restarts (increased from 7 to 15 seconds)
|
||||||
esp_task_wdt_add(NULL); //add current thread to WDT watch
|
esp_task_wdt_add(NULL); //add current thread to WDT watch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
esp_task_wdt_reset();
|
||||||
// put your main code here, to run repeatedly:
|
// put your main code here, to run repeatedly:
|
||||||
//uint32_t heap = ESP.getFreeHeap();
|
//uint32_t heap = ESP.getFreeHeap();
|
||||||
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
||||||
|
|
@ -57,30 +58,37 @@ void loop() {
|
||||||
|
|
||||||
net.loop();
|
net.loop();
|
||||||
if(millis() - timing > 100) Serial.printf("Timing Net: %ldms\n", millis() - timing);
|
if(millis() - timing > 100) Serial.printf("Timing Net: %ldms\n", millis() - timing);
|
||||||
timing = millis();
|
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
timing = millis();
|
||||||
|
|
||||||
somfy.loop();
|
somfy.loop();
|
||||||
if(millis() - timing > 100) Serial.printf("Timing Somfy: %ldms\n", millis() - timing);
|
if(millis() - timing > 100) Serial.printf("Timing Somfy: %ldms\n", millis() - timing);
|
||||||
timing = millis();
|
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
timing = millis();
|
||||||
|
|
||||||
if(net.connected() || net.softAPOpened) {
|
if(net.connected() || net.softAPOpened) {
|
||||||
if(!rebootDelay.reboot && net.connected() && !net.softAPOpened) {
|
if(!rebootDelay.reboot && net.connected() && !net.softAPOpened) {
|
||||||
git.loop();
|
git.loop();
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
}
|
}
|
||||||
webServer.loop();
|
webServer.loop();
|
||||||
esp_task_wdt_reset();
|
|
||||||
if(millis() - timing > 100) Serial.printf("Timing WebServer: %ldms\n", millis() - timing);
|
if(millis() - timing > 100) Serial.printf("Timing WebServer: %ldms\n", millis() - timing);
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
timing = millis();
|
timing = millis();
|
||||||
|
|
||||||
sockEmit.loop();
|
sockEmit.loop();
|
||||||
if(millis() - timing > 100) Serial.printf("Timing Socket: %ldms\n", millis() - timing);
|
if(millis() - timing > 100) Serial.printf("Timing Socket: %ldms\n", millis() - timing);
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
timing = millis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
if(rebootDelay.reboot && millis() > rebootDelay.rebootTime) {
|
||||||
net.end();
|
net.end();
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Final watchdog reset before end of loop
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
|
// Small delay to prevent tight loop from consuming too much CPU
|
||||||
|
delay(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="divETHSettings">
|
<div id="divETHSettings">
|
||||||
<div class="field-group" style="width:40%;margin-right:7px;display:inline-block;">
|
<div class="field-group" style="width:40%;margin-right:7px;display:inline-block;">
|
||||||
<select id="selETHPhyType" name="ethphytype" placeholder="PHY Type" data-datatype="int" data-bind="ethernet.phyType" style="width:100%;"></select>
|
<select id="selETHPhyType" name="ethphytype" placeholder="PHY Type" data-datatype="int" data-bind="ethernet.phyType" style="width:100%;" onchange="wifi.onETHPhyTypeChanged(this);"></select>
|
||||||
<label for="selETHPhyType">PHY Chip Type</label>
|
<label for="selETHPhyType">PHY Chip Type</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
|
<div class="field-group" style="width:20%;display:inline-block;margin-right:7px;">
|
||||||
|
|
@ -339,6 +339,30 @@
|
||||||
<select id="selETHMDIOPin" name="mdio" placeholder="MDIO Pin" data-datatype="int" data-bind="ethernet.MDIOPin" style="width:100%;"></select>
|
<select id="selETHMDIOPin" name="mdio" placeholder="MDIO Pin" data-datatype="int" data-bind="ethernet.MDIOPin" style="width:100%;"></select>
|
||||||
<label for="selETHMDIOPin">MDIO Pin</label>
|
<label for="selETHMDIOPin">MDIO Pin</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHMOSIPin" name="mosi" placeholder="MOSI Pin" data-datatype="int" data-bind="ethernet.MOSIPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHMOSIPin">MOSI Pin</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHMISOPin" name="miso" placeholder="MISO Pin" data-datatype="int" data-bind="ethernet.MISOPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHMISOPin">MISO Pin</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHSCLKPin" name="sclk" placeholder="SCLK Pin" data-datatype="int" data-bind="ethernet.SCLKPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHSCLKPin">SCLK Pin</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHCSPin" name="cs" placeholder="CS Pin" data-datatype="int" data-bind="ethernet.CSPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHCSPin">CS Pin</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHINTPin" name="int" placeholder="INT Pin" data-datatype="int" data-bind="ethernet.INTPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHINTPin">INT Pin</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group" style="width:25%;display:inline-block;margin-right:7px;display:none;">
|
||||||
|
<select id="selETHRSTPin" name="rst" placeholder="RST Pin" data-datatype="int" data-bind="ethernet.RSTPin" style="width:100%;"></select>
|
||||||
|
<label for="selETHRSTPin">RST Pin</label>
|
||||||
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
103
data/index.js
103
data/index.js
|
|
@ -599,7 +599,7 @@ async function initSockets() {
|
||||||
console.log(`Initial socket did not connect try again (server was busy and timed out ${connectFailed} times)`);
|
console.log(`Initial socket did not connect try again (server was busy and timed out ${connectFailed} times)`);
|
||||||
tConnect = setTimeout(async () => { await reopenSocket(); }, timeout);
|
tConnect = setTimeout(async () => { await reopenSocket(); }, timeout);
|
||||||
if (connectFailed === 5) {
|
if (connectFailed === 5) {
|
||||||
ui.socketError('Too many clients connected. A maximum of 5 clients may be connected at any one time. Close some connections to the ESP Somfy RTS device to proceed.');
|
ui.socketError('Too many clients connected. A maximum of 10 clients may be connected at any one time. Close some connections to the ESP Somfy RTS device to proceed.');
|
||||||
}
|
}
|
||||||
let spanAttempts = document.getElementById('spanSocketAttempts');
|
let spanAttempts = document.getElementById('spanSocketAttempts');
|
||||||
if (spanAttempts) spanAttempts.innerHTML = connectFailed.fmt("#,##0");
|
if (spanAttempts) spanAttempts.innerHTML = connectFailed.fmt("#,##0");
|
||||||
|
|
@ -1609,10 +1609,12 @@ class Wifi {
|
||||||
{ val: 4, label: 'T-Internet POE - LILYGO', clk: 3, ct: 0, addr: 0, pwr: 16, mdc: 23, mdio: 18 },
|
{ val: 4, label: 'T-Internet POE - LILYGO', clk: 3, ct: 0, addr: 0, pwr: 16, mdc: 23, mdio: 18 },
|
||||||
{ val: 5, label: 'wESP32 v7+ - Silicognition', clk: 0, ct: 2, addr: 0, pwr: -1, mdc: 16, mdio: 17 },
|
{ val: 5, label: 'wESP32 v7+ - Silicognition', clk: 0, ct: 2, addr: 0, pwr: -1, mdc: 16, mdio: 17 },
|
||||||
{ val: 6, label: 'wESP32 < v7 - Silicognition', clk: 0, ct: 0, addr: 0, pwr: -1, mdc: 16, mdio: 17 },
|
{ val: 6, label: 'wESP32 < v7 - Silicognition', clk: 0, ct: 0, addr: 0, pwr: -1, mdc: 16, mdio: 17 },
|
||||||
{ val: 1, label: 'WT32-ETH01 - Wireless Tag', clk: 0, ct: 0, addr: 1, pwr: 16, mdc: 23, mdio: 18 }
|
{ val: 1, label: 'WT32-ETH01 - Wireless Tag', clk: 0, ct: 0, addr: 1, pwr: 16, mdc: 23, mdio: 18 },
|
||||||
|
{ val: 8, label: 'ESP32-S3 ETH POE - Waveshare', ct: 6, mosi: 11, miso: 12, sclk: 13, cs: 14, int: 10, rst: 9, isSPI: true },
|
||||||
|
{ val: 9, label: 'W5500 Custom', ct: 6, isSPI: true }
|
||||||
];
|
];
|
||||||
ethClockModes = [{ val: 0, label: 'GPIO0 IN' }, { val: 1, label: 'GPIO0 OUT' }, { val: 2, label: 'GPIO16 OUT' }, { val: 3, label: 'GPIO17 OUT' }];
|
ethClockModes = [{ val: 0, label: 'GPIO0 IN' }, { val: 1, label: 'GPIO0 OUT' }, { val: 2, label: 'GPIO16 OUT' }, { val: 3, label: 'GPIO17 OUT' }];
|
||||||
ethPhyTypes = [{ val: 0, label: 'LAN8720' }, { val: 1, label: 'TLK110' }, { val: 2, label: 'RTL8201' }, { val: 3, label: 'DP83848' }, { val: 4, label: 'DM9051' }, { val: 5, label: 'KZ8081' }];
|
ethPhyTypes = [{ val: 0, label: 'LAN8720' }, { val: 1, label: 'TLK110' }, { val: 2, label: 'RTL8201' }, { val: 3, label: 'DP83848' }, { val: 4, label: 'DM9051' }, { val: 5, label: 'KZ8081' }, { val: 6, label: 'W5500' }];
|
||||||
init() {
|
init() {
|
||||||
document.getElementById("divNetworkStrength").innerHTML = this.displaySignal(-100);
|
document.getElementById("divNetworkStrength").innerHTML = this.displaySignal(-100);
|
||||||
if (this.initialized) return;
|
if (this.initialized) return;
|
||||||
|
|
@ -1625,6 +1627,12 @@ class Wifi {
|
||||||
this.loadETHPins(document.getElementById('selETHPWRPin'), 'power');
|
this.loadETHPins(document.getElementById('selETHPWRPin'), 'power');
|
||||||
this.loadETHPins(document.getElementById('selETHMDCPin'), 'mdc', 23);
|
this.loadETHPins(document.getElementById('selETHMDCPin'), 'mdc', 23);
|
||||||
this.loadETHPins(document.getElementById('selETHMDIOPin'), 'mdio', 18);
|
this.loadETHPins(document.getElementById('selETHMDIOPin'), 'mdio', 18);
|
||||||
|
this.loadETHPins(document.getElementById('selETHMOSIPin'), 'spi', 11);
|
||||||
|
this.loadETHPins(document.getElementById('selETHMISOPin'), 'spi', 12);
|
||||||
|
this.loadETHPins(document.getElementById('selETHSCLKPin'), 'spi', 13);
|
||||||
|
this.loadETHPins(document.getElementById('selETHCSPin'), 'spi', 14);
|
||||||
|
this.loadETHPins(document.getElementById('selETHINTPin'), 'spi', 10);
|
||||||
|
this.loadETHPins(document.getElementById('selETHRSTPin'), 'spi', 9);
|
||||||
ui.toElement(document.getElementById('divNetAdapter'), {
|
ui.toElement(document.getElementById('divNetAdapter'), {
|
||||||
wifi: {ssid:'', passphrase:''},
|
wifi: {ssid:'', passphrase:''},
|
||||||
ethernet: { boardType: 1, wirelessFallback: false, dhcp: true, dns1: '', dns2: '', ip: '', gateway: '' }
|
ethernet: { boardType: 1, wirelessFallback: false, dhcp: true, dns1: '', dns2: '', ip: '', gateway: '' }
|
||||||
|
|
@ -1654,16 +1662,96 @@ class Wifi {
|
||||||
onETHBoardTypeChanged(sel) {
|
onETHBoardTypeChanged(sel) {
|
||||||
let type = this.ethBoardTypes.find(elem => parseInt(sel.value, 10) === elem.val);
|
let type = this.ethBoardTypes.find(elem => parseInt(sel.value, 10) === elem.val);
|
||||||
if (typeof type !== 'undefined') {
|
if (typeof type !== 'undefined') {
|
||||||
|
let isSPI = type.isSPI === true;
|
||||||
|
|
||||||
// Change the values to represent what the board type says.
|
// Change the values to represent what the board type says.
|
||||||
if(typeof type.ct !== 'undefined') document.getElementById('selETHPhyType').value = type.ct;
|
if(typeof type.ct !== 'undefined') {
|
||||||
|
document.getElementById('selETHPhyType').value = type.ct;
|
||||||
|
}
|
||||||
if (typeof type.clk !== 'undefined') document.getElementById('selETHClkMode').value = type.clk;
|
if (typeof type.clk !== 'undefined') document.getElementById('selETHClkMode').value = type.clk;
|
||||||
if (typeof type.addr !== 'undefined') document.getElementById('selETHAddress').value = type.addr;
|
if (typeof type.addr !== 'undefined') document.getElementById('selETHAddress').value = type.addr;
|
||||||
if (typeof type.pwr !== 'undefined') document.getElementById('selETHPWRPin').value = type.pwr;
|
if (typeof type.pwr !== 'undefined') document.getElementById('selETHPWRPin').value = type.pwr;
|
||||||
if (typeof type.mdc !== 'undefined') document.getElementById('selETHMDCPin').value = type.mdc;
|
if (typeof type.mdc !== 'undefined') document.getElementById('selETHMDCPin').value = type.mdc;
|
||||||
if (typeof type.mdio !== 'undefined') document.getElementById('selETHMDIOPin').value = type.mdio;
|
if (typeof type.mdio !== 'undefined') document.getElementById('selETHMDIOPin').value = type.mdio;
|
||||||
document.getElementById('divETHSettings').style.display = type.val === 0 ? '' : 'none';
|
|
||||||
|
// Set SPI pins if this is a SPI-based board
|
||||||
|
if (isSPI) {
|
||||||
|
if (typeof type.mosi !== 'undefined') document.getElementById('selETHMOSIPin').value = type.mosi;
|
||||||
|
if (typeof type.miso !== 'undefined') document.getElementById('selETHMISOPin').value = type.miso;
|
||||||
|
if (typeof type.sclk !== 'undefined') document.getElementById('selETHSCLKPin').value = type.sclk;
|
||||||
|
if (typeof type.cs !== 'undefined') document.getElementById('selETHCSPin').value = type.cs;
|
||||||
|
if (typeof type.int !== 'undefined') document.getElementById('selETHINTPin').value = type.int;
|
||||||
|
if (typeof type.rst !== 'undefined') document.getElementById('selETHRSTPin').value = type.rst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show/hide appropriate settings based on board type
|
||||||
|
if (type.val === 0) {
|
||||||
|
// Custom Config - show all settings
|
||||||
|
document.getElementById('divETHSettings').style.display = '';
|
||||||
|
// Use phyType to determine SPI/RMII visibility
|
||||||
|
let phyType = parseInt(document.getElementById('selETHPhyType').value, 10);
|
||||||
|
this.showSPISettings(phyType >= 6);
|
||||||
|
} else {
|
||||||
|
// Predefined board - show settings for SPI boards, hide for RMII
|
||||||
|
if (isSPI) {
|
||||||
|
// For SPI boards, show settings so user can see SPI pins
|
||||||
|
document.getElementById('divETHSettings').style.display = '';
|
||||||
|
this.showSPISettings(true);
|
||||||
|
} else {
|
||||||
|
// For RMII boards, hide settings as before
|
||||||
|
document.getElementById('divETHSettings').style.display = 'none';
|
||||||
|
this.showSPISettings(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
showSPISettings(showSPI) {
|
||||||
|
// Show/hide RMII settings (MDC, MDIO, CLK Mode, Address, Power)
|
||||||
|
let rmiiSettings = ['selETHMDCPin', 'selETHMDIOPin', 'selETHClkMode', 'selETHAddress', 'selETHPWRPin'];
|
||||||
|
let spiSettings = ['selETHMOSIPin', 'selETHMISOPin', 'selETHSCLKPin', 'selETHCSPin', 'selETHINTPin', 'selETHRSTPin'];
|
||||||
|
|
||||||
|
rmiiSettings.forEach(id => {
|
||||||
|
let elem = document.getElementById(id);
|
||||||
|
if (elem) {
|
||||||
|
let fieldGroup = elem.closest('.field-group');
|
||||||
|
if (fieldGroup) {
|
||||||
|
// Force display style to override inline styles
|
||||||
|
if (showSPI) {
|
||||||
|
fieldGroup.style.setProperty('display', 'none', 'important');
|
||||||
|
} else {
|
||||||
|
fieldGroup.style.setProperty('display', 'inline-block', 'important');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
spiSettings.forEach(id => {
|
||||||
|
let elem = document.getElementById(id);
|
||||||
|
if (elem) {
|
||||||
|
let fieldGroup = elem.closest('.field-group');
|
||||||
|
if (fieldGroup) {
|
||||||
|
// Force display style to override inline styles
|
||||||
|
if (showSPI) {
|
||||||
|
fieldGroup.style.setProperty('display', 'inline-block', 'important');
|
||||||
|
} else {
|
||||||
|
fieldGroup.style.setProperty('display', 'none', 'important');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Always show PHY Type selector
|
||||||
|
let phyTypeElem = document.getElementById('selETHPhyType');
|
||||||
|
if (phyTypeElem) {
|
||||||
|
let fieldGroup = phyTypeElem.closest('.field-group');
|
||||||
|
if (fieldGroup) fieldGroup.style.display = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onETHPhyTypeChanged(sel) {
|
||||||
|
// W5500 is phyType value 6
|
||||||
|
let isSPI = parseInt(sel.value, 10) >= 6;
|
||||||
|
this.showSPISettings(isSPI);
|
||||||
|
}
|
||||||
onDHCPClicked(cb) { document.getElementById('divStaticIP').style.display = cb.checked ? 'none' : ''; }
|
onDHCPClicked(cb) { document.getElementById('divStaticIP').style.display = cb.checked ? 'none' : ''; }
|
||||||
loadNetwork() {
|
loadNetwork() {
|
||||||
let pnl = document.getElementById('divNetAdapter');
|
let pnl = document.getElementById('divNetAdapter');
|
||||||
|
|
@ -1694,6 +1782,11 @@ class Wifi {
|
||||||
document.getElementById('divETHSettings').style.display = settings.ethernet.boardType === 0 ? '' : 'none';
|
document.getElementById('divETHSettings').style.display = settings.ethernet.boardType === 0 ? '' : 'none';
|
||||||
document.getElementById('divStaticIP').style.display = settings.ip.dhcp ? 'none' : '';
|
document.getElementById('divStaticIP').style.display = settings.ip.dhcp ? 'none' : '';
|
||||||
document.getElementById('spanCurrentIP').innerHTML = settings.ip.ip;
|
document.getElementById('spanCurrentIP').innerHTML = settings.ip.ip;
|
||||||
|
|
||||||
|
// Show/hide SPI settings based on phyType (W5500 is value 6)
|
||||||
|
let isSPI = settings.ethernet.phyType >= 6;
|
||||||
|
this.showSPISettings(isSPI);
|
||||||
|
|
||||||
this.useEthernetClicked();
|
this.useEthernetClicked();
|
||||||
this.hiddenSSIDClicked();
|
this.hiddenSSIDClicked();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue